From 8121044cc18019243c99ff752b8627b83473a51b Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 3 May 2025 23:40:26 -0400 Subject: [PATCH 1/2] SDK link wip --- .vscode/settings.json | 16 +- config/GGVE78/splits.txt | 22 +- configure.py | 28 +- .../MSL/MSL_C++/MSL_Common/Include/new.h | 6 +- .../MSL/MSL_C/MSL_Common/Include/cmath | 2 - .../MSL/MSL_C/MSL_Common/Include/math.h | 2 +- .../MSL/MSL_C/MSL_Common/Include/size_t.h | 2 +- .../MSL/MSL_C/MSL_Common/Include/stddef.h | 6 - .../MSL/MSL_C/MSL_Common/Include/stdio.h | 11 +- .../MSL/MSL_C/MSL_Common/Include/stdlib.h | 2 +- .../MSL/MSL_C/MSL_Common/Include/va_list.h | 2 +- include/charPipeline/fileCache.h | 42 + include/charPipeline/structures.h | 9 + include/charPipeline/structures/HTable.h | 29 + include/charPipeline/structures/List.h | 31 + include/charPipeline/structures/Tree.h | 32 + .../charPipeline/structures/dolphinString.h | 19 + include/charPipeline/texPalette.h | 55 + include/dolphin/types.h | 10 +- include/fake_tgmath.h | 66 + include/libc/assert.h | 12 + include/libc/ctype.h | 6 + include/libc/errno.h | 4 + include/libc/float.h | 6 + include/libc/limits.h | 22 + include/libc/math.h | 114 + include/libc/stdarg.h | 39 + include/libc/stddef.h | 12 + include/libc/stdint.h | 6 + include/libc/stdio.h | 34 + include/libc/stdlib.h | 25 + include/libc/string.h | 26 + include/libc/wchar.h | 10 + include/macros.inc | 34 + include/rwsdk/rwplcore.h | 4 +- src/SB/Core/x/containers.h | 3 +- src/SB/Core/x/xString.h | 3 +- src/SB/Core/x/xWad1.cpp | 4 +- src/SB/Core/x/xWad3.h | 1 + src/SB/Core/x/xWad5.cpp | 64 +- src/SB/Game/zCameraTweak.h | 2 +- src/SB/Game/zFMV.cpp | 2 +- src/dolphin/G2D/G2D.c | 721 ++ src/dolphin/ai/src/ai.c | 411 ++ src/dolphin/am/src/__am.h | 39 + src/dolphin/am/src/am.c | 322 + src/dolphin/amcnotstub/src/amcnotstub.c | 8 + src/dolphin/amcstubs/src/AmcExi2Stubs.c | 29 + src/dolphin/ar/src/__ar.h | 24 + src/dolphin/ar/src/ar.c | 446 ++ src/dolphin/ar/src/arq.c | 253 + src/dolphin/ax/src/AX.c | 40 + src/dolphin/ax/src/AXAlloc.c | 248 + src/dolphin/ax/src/AXAux.c | 167 + src/dolphin/ax/src/AXCL.c | 176 + src/dolphin/ax/src/AXComp.c | 567 ++ src/dolphin/ax/src/AXOut.c | 238 + src/dolphin/ax/src/AXProf.c | 47 + src/dolphin/ax/src/AXSPB.c | 91 + src/dolphin/ax/src/AXVPB.c | 1412 ++++ src/dolphin/ax/src/DSPCode.c | 669 ++ src/dolphin/ax/src/__ax.h | 84 + src/dolphin/axart/src/axart.c | 330 + src/dolphin/axart/src/axart3d.c | 317 + src/dolphin/axart/src/axartcents.c | 280 + src/dolphin/axart/src/axartenv.c | 33 + src/dolphin/axart/src/axartlfo.c | 85 + src/dolphin/axart/src/axartlpf.c | 42 + src/dolphin/axart/src/axartsound.c | 122 + src/dolphin/axfx/src/__axfx.h | 17 + src/dolphin/axfx/src/axfx.c | 20 + src/dolphin/axfx/src/chorus.c | 507 ++ src/dolphin/axfx/src/delay.c | 148 + src/dolphin/axfx/src/reverb_hi.c | 890 +++ src/dolphin/axfx/src/reverb_hi_4ch.c | 611 ++ src/dolphin/axfx/src/reverb_std.c | 501 ++ src/dolphin/base/src/PPCArch.c | 292 + src/dolphin/base/src/PPCPm.c | 34 + src/dolphin/card/src/CARDBios.c | 856 +++ src/dolphin/card/src/CARDBlock.c | 160 + src/dolphin/card/src/CARDCheck.c | 343 + src/dolphin/card/src/CARDCreate.c | 126 + src/dolphin/card/src/CARDDelete.c | 108 + src/dolphin/card/src/CARDDir.c | 89 + src/dolphin/card/src/CARDErase.c | 102 + src/dolphin/card/src/CARDFormat.c | 137 + src/dolphin/card/src/CARDMount.c | 394 + src/dolphin/card/src/CARDNet.c | 138 + src/dolphin/card/src/CARDOpen.c | 174 + src/dolphin/card/src/CARDProgram.c | 100 + src/dolphin/card/src/CARDRaw.c | 82 + src/dolphin/card/src/CARDRdwr.c | 105 + src/dolphin/card/src/CARDRead.c | 174 + src/dolphin/card/src/CARDRename.c | 70 + src/dolphin/card/src/CARDStat.c | 156 + src/dolphin/card/src/CARDStatEx.c | 124 + src/dolphin/card/src/CARDUnlock.c | 436 ++ src/dolphin/card/src/CARDWrite.c | 123 + src/dolphin/card/src/__card.h | 104 + src/dolphin/db/src/db.c | 59 + src/dolphin/demo/DEMOAVX.c | 118 + src/dolphin/demo/DEMOFont.c | 773 ++ src/dolphin/demo/DEMOInit.c | 432 ++ src/dolphin/demo/DEMOPad.c | 120 + src/dolphin/demo/DEMOPuts.c | 403 ++ src/dolphin/demo/DEMOStats.c | 416 ++ src/dolphin/demo/DEMOWin.c | 981 +++ src/dolphin/demo/__demo.h | 11 + src/dolphin/dsp/__dsp.h | 27 + src/dolphin/dsp/dsp.c | 185 + src/dolphin/dsp/dsp_debug.c | 9 + src/dolphin/dsp/dsp_perf.c | 0 src/dolphin/dsp/dsp_task.c | 362 + src/dolphin/dtk/dtk.c | 483 ++ src/dolphin/dvd/__dvd.h | 53 + src/dolphin/dvd/dvd.c | 1854 +++++ src/dolphin/dvd/dvdFatal.c | 95 + src/dolphin/dvd/dvderror.c | 77 + src/dolphin/dvd/dvdfs.c | 630 ++ src/dolphin/dvd/dvdidutils.c | 97 + src/dolphin/dvd/dvdlow.c | 534 ++ src/dolphin/dvd/dvdqueue.c | 172 + src/dolphin/dvd/fstload.c | 86 + src/dolphin/exi/EXIAd16.c | 101 + src/dolphin/exi/EXIBios.c | 870 +++ src/dolphin/exi/EXIUart.c | 194 + src/dolphin/fileCache/fileCache.c | 145 + src/dolphin/gd/GDBase.c | 45 + src/dolphin/gd/GDFile.c | 64 + src/dolphin/gd/GDGeometry.c | 430 ++ src/dolphin/gd/GDIndirect.c | 270 + src/dolphin/gd/GDLight.c | 206 + src/dolphin/gd/GDPixel.c | 118 + src/dolphin/gd/GDTev.c | 159 + src/dolphin/gd/GDTexture.c | 104 + src/dolphin/gd/GDTransform.c | 127 + src/dolphin/gx/GXAttr.c | 641 ++ src/dolphin/gx/GXBump.c | 308 + src/dolphin/gx/GXDisplayList.c | 99 + src/dolphin/gx/GXDraw.c | 551 ++ src/dolphin/gx/GXFifo.c | 629 ++ src/dolphin/gx/GXFrameBuf.c | 603 ++ src/dolphin/gx/GXGeometry.c | 156 + src/dolphin/gx/GXInit.c | 570 ++ src/dolphin/gx/GXLight.c | 573 ++ src/dolphin/gx/GXMisc.c | 481 ++ src/dolphin/gx/GXPerf.c | 431 ++ src/dolphin/gx/GXPixel.c | 334 + src/dolphin/gx/GXSave.c | 528 ++ src/dolphin/gx/GXStubs.c | 5 + src/dolphin/gx/GXTev.c | 470 ++ src/dolphin/gx/GXTexture.c | 1315 ++++ src/dolphin/gx/GXTransform.c | 608 ++ src/dolphin/gx/GXVerifRAS.c | 640 ++ src/dolphin/gx/GXVerifXF.c | 1002 +++ src/dolphin/gx/GXVerify.c | 368 + src/dolphin/gx/GXVert.c | 86 + src/dolphin/gx/__gx.h | 592 ++ src/dolphin/hio/hio.c | 409 ++ src/dolphin/mcc/fio.c | 1290 ++++ src/dolphin/mcc/mcc.c | 1417 ++++ src/dolphin/mcc/tty.c | 260 + src/dolphin/mix/mix.c | 1035 +++ src/dolphin/mtx/mtx.c | 1197 ++++ src/dolphin/mtx/mtx44.c | 888 +++ src/dolphin/mtx/mtx44vec.c | 247 + src/dolphin/mtx/mtxstack.c | 108 + src/dolphin/mtx/mtxvec.c | 204 + src/dolphin/mtx/psmtx.c | 336 + src/dolphin/mtx/quat.c | 486 ++ src/dolphin/mtx/vec.c | 344 + src/dolphin/odemustubs/odemustubs.c | 34 + src/dolphin/odenotstub/odenotstub.c | 8 + src/dolphin/os/OS.c | 631 ++ src/dolphin/os/OSAddress.c | 39 + src/dolphin/os/OSAlarm.c | 297 + src/dolphin/os/OSAlloc.c | 609 ++ src/dolphin/os/OSArena.c | 52 + src/dolphin/os/OSAudioSystem.c | 117 + src/dolphin/os/OSCache.c | 643 ++ src/dolphin/os/OSContext.c | 626 ++ src/dolphin/os/OSError.c | 215 + src/dolphin/os/OSFatal.c | 246 + src/dolphin/os/OSFont.c | 751 ++ src/dolphin/os/OSInterrupt.c | 509 ++ src/dolphin/os/OSLink.c | 528 ++ src/dolphin/os/OSMemory.c | 235 + src/dolphin/os/OSMessage.c | 70 + src/dolphin/os/OSMutex.c | 256 + src/dolphin/os/OSReboot.c | 39 + src/dolphin/os/OSReset.c | 248 + src/dolphin/os/OSResetSW.c | 120 + src/dolphin/os/OSRtc.c | 513 ++ src/dolphin/os/OSStopwatch.c | 55 + src/dolphin/os/OSSync.c | 33 + src/dolphin/os/OSThread.c | 875 +++ src/dolphin/os/OSTime.c | 200 + src/dolphin/os/OSTimer.c | 140 + src/dolphin/os/OSUtf.c | 6341 +++++++++++++++++ src/dolphin/os/__os.h | 130 + src/dolphin/os/src/OSExec.c | 402 ++ src/dolphin/os/src/OSSemaphore.c | 56 + src/dolphin/os/src/init/__ppc_eabi_init.c | 85 + src/dolphin/os/src/init/__start.c | 265 + src/dolphin/os/time.dolphin.c | 16 + src/dolphin/pad/Pad.c | 841 +++ src/dolphin/pad/Padclamp.c | 152 + src/dolphin/perf/__perf.h | 14 + src/dolphin/perf/perf.c | 467 ++ src/dolphin/perf/perfdraw.c | 695 ++ src/dolphin/seq/seq.c | 468 ++ src/dolphin/si/SIBios.c | 798 +++ src/dolphin/si/SISamplingRate.c | 125 + src/dolphin/si/SISteering.c | 120 + src/dolphin/si/SISteeringAuto.c | 130 + src/dolphin/si/SISteeringXfer.c | 118 + src/dolphin/si/__si.h | 21 + src/dolphin/sp/sp.c | 404 ++ src/dolphin/stub.c | 80 + src/dolphin/support/HTable.c | 68 + src/dolphin/support/List.c | 92 + src/dolphin/support/Tree.c | 106 + src/dolphin/support/string.c | 74 + src/dolphin/syn/__syn.h | 67 + src/dolphin/syn/syn.c | 180 + src/dolphin/syn/synctrl.c | 510 ++ src/dolphin/syn/synenv.c | 185 + src/dolphin/syn/synlfo.c | 102 + src/dolphin/syn/synmix.c | 274 + src/dolphin/syn/synpitch.c | 340 + src/dolphin/syn/synsample.c | 241 + src/dolphin/syn/synvoice.c | 82 + src/dolphin/syn/synwt.c | 21 + src/dolphin/texPalette/texPalette.c | 112 + src/dolphin/vi/__vi.h | 37 + src/dolphin/vi/gpioexi.c | 146 + src/dolphin/vi/i2c.c | 105 + src/dolphin/vi/initphilips.c | 73 + src/dolphin/vi/vi.c | 1307 ++++ 239 files changed, 68995 insertions(+), 112 deletions(-) delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h create mode 100644 include/charPipeline/fileCache.h create mode 100644 include/charPipeline/structures.h create mode 100644 include/charPipeline/structures/HTable.h create mode 100644 include/charPipeline/structures/List.h create mode 100644 include/charPipeline/structures/Tree.h create mode 100644 include/charPipeline/structures/dolphinString.h create mode 100644 include/charPipeline/texPalette.h create mode 100644 include/fake_tgmath.h create mode 100644 include/libc/assert.h create mode 100644 include/libc/ctype.h create mode 100644 include/libc/errno.h create mode 100644 include/libc/float.h create mode 100644 include/libc/limits.h create mode 100644 include/libc/math.h create mode 100644 include/libc/stdarg.h create mode 100644 include/libc/stddef.h create mode 100644 include/libc/stdint.h create mode 100644 include/libc/stdio.h create mode 100644 include/libc/stdlib.h create mode 100644 include/libc/string.h create mode 100644 include/libc/wchar.h create mode 100644 src/dolphin/G2D/G2D.c create mode 100644 src/dolphin/ai/src/ai.c create mode 100644 src/dolphin/am/src/__am.h create mode 100644 src/dolphin/am/src/am.c create mode 100644 src/dolphin/amcnotstub/src/amcnotstub.c create mode 100644 src/dolphin/amcstubs/src/AmcExi2Stubs.c create mode 100644 src/dolphin/ar/src/__ar.h create mode 100644 src/dolphin/ar/src/ar.c create mode 100644 src/dolphin/ar/src/arq.c create mode 100644 src/dolphin/ax/src/AX.c create mode 100644 src/dolphin/ax/src/AXAlloc.c create mode 100644 src/dolphin/ax/src/AXAux.c create mode 100644 src/dolphin/ax/src/AXCL.c create mode 100644 src/dolphin/ax/src/AXComp.c create mode 100644 src/dolphin/ax/src/AXOut.c create mode 100644 src/dolphin/ax/src/AXProf.c create mode 100644 src/dolphin/ax/src/AXSPB.c create mode 100644 src/dolphin/ax/src/AXVPB.c create mode 100644 src/dolphin/ax/src/DSPCode.c create mode 100644 src/dolphin/ax/src/__ax.h create mode 100644 src/dolphin/axart/src/axart.c create mode 100644 src/dolphin/axart/src/axart3d.c create mode 100644 src/dolphin/axart/src/axartcents.c create mode 100644 src/dolphin/axart/src/axartenv.c create mode 100644 src/dolphin/axart/src/axartlfo.c create mode 100644 src/dolphin/axart/src/axartlpf.c create mode 100644 src/dolphin/axart/src/axartsound.c create mode 100644 src/dolphin/axfx/src/__axfx.h create mode 100644 src/dolphin/axfx/src/axfx.c create mode 100644 src/dolphin/axfx/src/chorus.c create mode 100644 src/dolphin/axfx/src/delay.c create mode 100644 src/dolphin/axfx/src/reverb_hi.c create mode 100644 src/dolphin/axfx/src/reverb_hi_4ch.c create mode 100644 src/dolphin/axfx/src/reverb_std.c create mode 100644 src/dolphin/base/src/PPCArch.c create mode 100644 src/dolphin/base/src/PPCPm.c create mode 100644 src/dolphin/card/src/CARDBios.c create mode 100644 src/dolphin/card/src/CARDBlock.c create mode 100644 src/dolphin/card/src/CARDCheck.c create mode 100644 src/dolphin/card/src/CARDCreate.c create mode 100644 src/dolphin/card/src/CARDDelete.c create mode 100644 src/dolphin/card/src/CARDDir.c create mode 100644 src/dolphin/card/src/CARDErase.c create mode 100644 src/dolphin/card/src/CARDFormat.c create mode 100644 src/dolphin/card/src/CARDMount.c create mode 100644 src/dolphin/card/src/CARDNet.c create mode 100644 src/dolphin/card/src/CARDOpen.c create mode 100644 src/dolphin/card/src/CARDProgram.c create mode 100644 src/dolphin/card/src/CARDRaw.c create mode 100644 src/dolphin/card/src/CARDRdwr.c create mode 100644 src/dolphin/card/src/CARDRead.c create mode 100644 src/dolphin/card/src/CARDRename.c create mode 100644 src/dolphin/card/src/CARDStat.c create mode 100644 src/dolphin/card/src/CARDStatEx.c create mode 100644 src/dolphin/card/src/CARDUnlock.c create mode 100644 src/dolphin/card/src/CARDWrite.c create mode 100644 src/dolphin/card/src/__card.h create mode 100644 src/dolphin/db/src/db.c create mode 100644 src/dolphin/demo/DEMOAVX.c create mode 100644 src/dolphin/demo/DEMOFont.c create mode 100644 src/dolphin/demo/DEMOInit.c create mode 100644 src/dolphin/demo/DEMOPad.c create mode 100644 src/dolphin/demo/DEMOPuts.c create mode 100644 src/dolphin/demo/DEMOStats.c create mode 100644 src/dolphin/demo/DEMOWin.c create mode 100644 src/dolphin/demo/__demo.h create mode 100644 src/dolphin/dsp/__dsp.h create mode 100644 src/dolphin/dsp/dsp.c create mode 100644 src/dolphin/dsp/dsp_debug.c create mode 100644 src/dolphin/dsp/dsp_perf.c create mode 100644 src/dolphin/dsp/dsp_task.c create mode 100644 src/dolphin/dtk/dtk.c create mode 100644 src/dolphin/dvd/__dvd.h create mode 100644 src/dolphin/dvd/dvd.c create mode 100644 src/dolphin/dvd/dvdFatal.c create mode 100644 src/dolphin/dvd/dvderror.c create mode 100644 src/dolphin/dvd/dvdfs.c create mode 100644 src/dolphin/dvd/dvdidutils.c create mode 100644 src/dolphin/dvd/dvdlow.c create mode 100644 src/dolphin/dvd/dvdqueue.c create mode 100644 src/dolphin/dvd/fstload.c create mode 100644 src/dolphin/exi/EXIAd16.c create mode 100644 src/dolphin/exi/EXIBios.c create mode 100644 src/dolphin/exi/EXIUart.c create mode 100644 src/dolphin/fileCache/fileCache.c create mode 100644 src/dolphin/gd/GDBase.c create mode 100644 src/dolphin/gd/GDFile.c create mode 100644 src/dolphin/gd/GDGeometry.c create mode 100644 src/dolphin/gd/GDIndirect.c create mode 100644 src/dolphin/gd/GDLight.c create mode 100644 src/dolphin/gd/GDPixel.c create mode 100644 src/dolphin/gd/GDTev.c create mode 100644 src/dolphin/gd/GDTexture.c create mode 100644 src/dolphin/gd/GDTransform.c create mode 100644 src/dolphin/gx/GXAttr.c create mode 100644 src/dolphin/gx/GXBump.c create mode 100644 src/dolphin/gx/GXDisplayList.c create mode 100644 src/dolphin/gx/GXDraw.c create mode 100644 src/dolphin/gx/GXFifo.c create mode 100644 src/dolphin/gx/GXFrameBuf.c create mode 100644 src/dolphin/gx/GXGeometry.c create mode 100644 src/dolphin/gx/GXInit.c create mode 100644 src/dolphin/gx/GXLight.c create mode 100644 src/dolphin/gx/GXMisc.c create mode 100644 src/dolphin/gx/GXPerf.c create mode 100644 src/dolphin/gx/GXPixel.c create mode 100644 src/dolphin/gx/GXSave.c create mode 100644 src/dolphin/gx/GXStubs.c create mode 100644 src/dolphin/gx/GXTev.c create mode 100644 src/dolphin/gx/GXTexture.c create mode 100644 src/dolphin/gx/GXTransform.c create mode 100644 src/dolphin/gx/GXVerifRAS.c create mode 100644 src/dolphin/gx/GXVerifXF.c create mode 100644 src/dolphin/gx/GXVerify.c create mode 100644 src/dolphin/gx/GXVert.c create mode 100644 src/dolphin/gx/__gx.h create mode 100644 src/dolphin/hio/hio.c create mode 100644 src/dolphin/mcc/fio.c create mode 100644 src/dolphin/mcc/mcc.c create mode 100644 src/dolphin/mcc/tty.c create mode 100644 src/dolphin/mix/mix.c create mode 100644 src/dolphin/mtx/mtx.c create mode 100644 src/dolphin/mtx/mtx44.c create mode 100644 src/dolphin/mtx/mtx44vec.c create mode 100644 src/dolphin/mtx/mtxstack.c create mode 100644 src/dolphin/mtx/mtxvec.c create mode 100644 src/dolphin/mtx/psmtx.c create mode 100644 src/dolphin/mtx/quat.c create mode 100644 src/dolphin/mtx/vec.c create mode 100644 src/dolphin/odemustubs/odemustubs.c create mode 100644 src/dolphin/odenotstub/odenotstub.c create mode 100644 src/dolphin/os/OS.c create mode 100644 src/dolphin/os/OSAddress.c create mode 100644 src/dolphin/os/OSAlarm.c create mode 100644 src/dolphin/os/OSAlloc.c create mode 100644 src/dolphin/os/OSArena.c create mode 100644 src/dolphin/os/OSAudioSystem.c create mode 100644 src/dolphin/os/OSCache.c create mode 100644 src/dolphin/os/OSContext.c create mode 100644 src/dolphin/os/OSError.c create mode 100644 src/dolphin/os/OSFatal.c create mode 100644 src/dolphin/os/OSFont.c create mode 100644 src/dolphin/os/OSInterrupt.c create mode 100644 src/dolphin/os/OSLink.c create mode 100644 src/dolphin/os/OSMemory.c create mode 100644 src/dolphin/os/OSMessage.c create mode 100644 src/dolphin/os/OSMutex.c create mode 100644 src/dolphin/os/OSReboot.c create mode 100644 src/dolphin/os/OSReset.c create mode 100644 src/dolphin/os/OSResetSW.c create mode 100644 src/dolphin/os/OSRtc.c create mode 100644 src/dolphin/os/OSStopwatch.c create mode 100644 src/dolphin/os/OSSync.c create mode 100644 src/dolphin/os/OSThread.c create mode 100644 src/dolphin/os/OSTime.c create mode 100644 src/dolphin/os/OSTimer.c create mode 100644 src/dolphin/os/OSUtf.c create mode 100644 src/dolphin/os/__os.h create mode 100644 src/dolphin/os/src/OSExec.c create mode 100644 src/dolphin/os/src/OSSemaphore.c create mode 100644 src/dolphin/os/src/init/__ppc_eabi_init.c create mode 100644 src/dolphin/os/src/init/__start.c create mode 100644 src/dolphin/os/time.dolphin.c create mode 100644 src/dolphin/pad/Pad.c create mode 100644 src/dolphin/pad/Padclamp.c create mode 100644 src/dolphin/perf/__perf.h create mode 100644 src/dolphin/perf/perf.c create mode 100644 src/dolphin/perf/perfdraw.c create mode 100644 src/dolphin/seq/seq.c create mode 100644 src/dolphin/si/SIBios.c create mode 100644 src/dolphin/si/SISamplingRate.c create mode 100644 src/dolphin/si/SISteering.c create mode 100644 src/dolphin/si/SISteeringAuto.c create mode 100644 src/dolphin/si/SISteeringXfer.c create mode 100644 src/dolphin/si/__si.h create mode 100644 src/dolphin/sp/sp.c create mode 100644 src/dolphin/stub.c create mode 100644 src/dolphin/support/HTable.c create mode 100644 src/dolphin/support/List.c create mode 100644 src/dolphin/support/Tree.c create mode 100644 src/dolphin/support/string.c create mode 100644 src/dolphin/syn/__syn.h create mode 100644 src/dolphin/syn/syn.c create mode 100644 src/dolphin/syn/synctrl.c create mode 100644 src/dolphin/syn/synenv.c create mode 100644 src/dolphin/syn/synlfo.c create mode 100644 src/dolphin/syn/synmix.c create mode 100644 src/dolphin/syn/synpitch.c create mode 100644 src/dolphin/syn/synsample.c create mode 100644 src/dolphin/syn/synvoice.c create mode 100644 src/dolphin/syn/synwt.c create mode 100644 src/dolphin/texPalette/texPalette.c create mode 100644 src/dolphin/vi/__vi.h create mode 100644 src/dolphin/vi/gpioexi.c create mode 100644 src/dolphin/vi/i2c.c create mode 100644 src/dolphin/vi/initphilips.c create mode 100644 src/dolphin/vi/vi.c diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a550ce..4b05bcf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,7 +18,21 @@ "*.inc": "c", ".clangd": "yaml", "cstring": "cpp", - "cmath": "cpp" + "cmath": "cpp", + "dolphin.h": "c", + "types.h": "c", + "__ax.h": "c", + "ctype.h": "c", + "stdio.h": "c", + "stdarg.h": "c", + "string.h": "c", + "stddef.h": "c", + "size_t.h": "c", + "ax.h": "c", + "math.h": "c", + "os.h": "c", + "va_list.h": "c", + "fake_tgmath.h": "c" }, // Disable C/C++ IntelliSense, use clangd instead "C_Cpp.intelliSenseEngine": "default", diff --git a/config/GGVE78/splits.txt b/config/GGVE78/splits.txt index 672da6d..205ef13 100644 --- a/config/GGVE78/splits.txt +++ b/config/GGVE78/splits.txt @@ -1536,25 +1536,25 @@ dolphin/ax/src/AXProf.c: .text start:0x802D8E84 end:0x802D8ECC .sbss start:0x804B1E78 end:0x804B1E88 -reverb_hi.c: +dolphin/axfx/src/reverb_hi.c: .text start:0x802D8ECC end:0x802D9D10 .data start:0x803BF6C0 end:0x803BF6E0 .sdata2 start:0x804B4990 end:0x804B49D0 -reverb_std.c: +dolphin/axfx/src/reverb_std.c: .text start:0x802D9D10 end:0x802D9E58 -chorus.c: +dolphin/axfx/src/chorus.c: .text start:0x802D9E58 end:0x802D9EA8 -delay.c: +dolphin/axfx/src/delay.c: .text start:0x802D9EA8 end:0x802D9F38 -axfx.c: +dolphin/axfx/src/axfx.c: .text start:0x802D9F38 end:0x802D9F88 .sdata start:0x804B0610 end:0x804B0618 -reverb_hi_4ch.c: +dolphin/axfx/src/reverb_hi_4ch.c: .text start:0x802D9F88 end:0x802DAC68 .data start:0x803BF6E0 end:0x803BF708 .sdata2 start:0x804B49D0 end:0x804B4A08 @@ -1753,7 +1753,7 @@ dolphin/gx/src/GXPerf.c: .text start:0x802EFA54 end:0x802F0414 .data start:0x803C05F8 end:0x803C06E8 -mix.c: +dolphin/mix/src/mix.c: .text start:0x802F0414 end:0x802F2748 .data start:0x803C06E8 end:0x803C12A8 .bss start:0x80483878 end:0x80485080 @@ -1811,7 +1811,7 @@ dolphin/os/src/OSError.c: .bss start:0x804850F0 end:0x80485140 .sdata start:0x804B06F8 end:0x804B0700 -OSExec.c: +dolphin/os/src/OSExec.c: .text start:0x802F54F0 end:0x802F5E50 .data start:0x803C1C58 end:0x803C1C68 .sdata start:0x804B0700 end:0x804B0708 @@ -1856,7 +1856,7 @@ dolphin/os/src/OSRtc.c: .text start:0x802F8230 end:0x802F8DD0 .bss start:0x80485140 end:0x80485198 -OSSemaphore.c: +dolphin/os/src/OSSemaphore.c: .text start:0x802F8DD0 end:0x802F8EF8 dolphin/os/src/OSSync.c: @@ -1873,11 +1873,11 @@ dolphin/os/src/OSTime.c: .text start:0x802FAA58 end:0x802FAED4 .data start:0x803C3018 end:0x803C3078 -dolphin/os/src/init/__start.c: +dolphin/os/src/__start.c: .init start:0x800051EC end:0x800054EC .sbss start:0x804B20D8 end:0x804B20E0 -dolphin/os/src/init/__ppc_eabi_init.cpp: +dolphin/os/src/__ppc_eabi_init.cpp: .init start:0x800054EC end:0x80005544 .text start:0x802FAED4 end:0x802FAF68 diff --git a/configure.py b/configure.py index 1575602..b722782 100644 --- a/configure.py +++ b/configure.py @@ -236,9 +236,10 @@ '-pragma "cpp_extensions on"', "-inline off", "-gccinc", + "-sym on", "-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", + f"-i include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include", + f"-i include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include", "-i include/inline", "-i include/rwsdk", "-i src/SB/Core/gc", @@ -413,6 +414,17 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/ax/src/AXProf.c"), ], ), + DolphinLib( + "axfx", + [ + Object(NonMatching, "dolphin/axfx/src/axfx.c"), + Object(NonMatching, "dolphin/axfx/src/chorus.c"), + Object(NonMatching, "dolphin/axfx/src/delay.c"), + Object(NonMatching, "dolphin/axfx/src/reverb_hi.c"), + Object(NonMatching, "dolphin/axfx/src/reverb_hi_4ch.c"), + Object(NonMatching, "dolphin/axfx/src/reverb_std.c"), + ], + ), DolphinLib( "base", [ @@ -493,6 +505,12 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/gx/src/GXPerf.c"), ], ), + DolphinLib( + "mix", + [ + Object(NonMatching, "dolphin/mix/src/mix.c"), + ], + ), DolphinLib( "mtx", [ @@ -517,6 +535,7 @@ def MatchingFor(*versions): 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/OSExec.c"), Object(NonMatching, "dolphin/os/src/OSFont.c"), Object(NonMatching, "dolphin/os/src/OSInterrupt.c"), Object(NonMatching, "dolphin/os/src/OSLink.c"), @@ -526,11 +545,12 @@ def MatchingFor(*versions): 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/OSSemaphore.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/src/__start.c"), + Object(NonMatching, "dolphin/os/src/__ppc_eabi_init.cpp"), ], ), DolphinLib( diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h b/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h index a347550..4b9d555 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h +++ b/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h @@ -1,8 +1,8 @@ #ifndef _NEW_H #define _NEW_H -#include -#include +#include +#include "exception.h" namespace std { @@ -37,4 +37,4 @@ void operator delete[](void* ptr) throw(); void operator delete[](void* ptr, const std::nothrow_t&) throw(); void operator delete[](void*, void*) throw(); -#endif \ No newline at end of file +#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath index 003fd15..c11c2f7 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath +++ b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath @@ -1,8 +1,6 @@ #ifndef _MSL_CMATH #define _MSL_CMATH -#include - namespace std { // TODO: fix inline function ordering 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 index 5c1ed6e..dfd2999 100644 --- 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 @@ -36,4 +36,4 @@ double floor(double); } #endif -#endif \ No newline at end of file +#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h index 68e31d1..5ee1402 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h +++ b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h @@ -9,4 +9,4 @@ typedef unsigned long size_t; typedef __typeof__(sizeof(0)) size_t; #endif -#endif \ No newline at end of file +#endif 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 934197f..0000000 --- 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 index ff5a515..5541080 100644 --- 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 @@ -5,8 +5,9 @@ extern "C" { #endif -typedef struct _FILE { - unsigned char pad[0x50]; +typedef struct _FILE +{ + unsigned char pad[0x50]; } FILE; extern FILE __files[4]; @@ -15,9 +16,9 @@ extern FILE __files[4]; #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, ...); +int sprintf(char* s, const char* format, ...); +void printf(const char* format, ...); +int fprintf(FILE* stream, const char* format, ...); #ifdef __cplusplus } diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h index c5dfcbd..65ab762 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h +++ b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h @@ -1,7 +1,7 @@ #ifndef _MSL_STDLIB #define _MSL_STDLIB -#include +#include "size_t.h" #ifdef __cplusplus extern "C" { 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 index 47118e3..46a9131 100644 --- 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 @@ -3,4 +3,4 @@ typedef char* va_list; -#endif \ No newline at end of file +#endif diff --git a/include/charPipeline/fileCache.h b/include/charPipeline/fileCache.h new file mode 100644 index 0000000..edae41b --- /dev/null +++ b/include/charPipeline/fileCache.h @@ -0,0 +1,42 @@ +#ifndef _CHARPIPELINE_FILECACHE_H_ +#define _CHARPIPELINE_FILECACHE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DS_AUTO_PURGE 0 +#define DS_NO_PURGE 1 + +typedef struct { + DSLink Link; + void (*Free)(Ptr* data); + char* Name; + Ptr Data; + u16 ReferenceCount; +} DSCacheNode, *DSCacheNodePtr; + +typedef struct { + u8 PurgeFlag; + DSList CacheNodeList; +} DSCache, *DSCachePtr; + +extern u8 DOCacheInitialized; +extern DSCache DODisplayCache; + +DSCacheNodePtr DSAddCacheNode(DSCachePtr cache, char* name, Ptr data, Ptr OSFreeFunc); +void DSEmptyCache(DSCachePtr cache); +Ptr DSGetCacheObj(DSCachePtr cache, char* name); +void DSInitCache(DSCachePtr cache); +void DSPurgeCache(DSCachePtr cache); +void DSReleaseCacheObj(DSCachePtr cache, Ptr data); +void DSSetCachePurgeFlag(DSCachePtr cache, u8 purgeFlag); +void CSHInitDisplayCache(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/charPipeline/structures.h b/include/charPipeline/structures.h new file mode 100644 index 0000000..622ca55 --- /dev/null +++ b/include/charPipeline/structures.h @@ -0,0 +1,9 @@ +#ifndef _CHARPIPELINE_STRUCTURES_H_ +#define _CHARPIPELINE_STRUCTURES_H_ + +#include +#include +#include +#include + +#endif diff --git a/include/charPipeline/structures/HTable.h b/include/charPipeline/structures/HTable.h new file mode 100644 index 0000000..e0f5bac --- /dev/null +++ b/include/charPipeline/structures/HTable.h @@ -0,0 +1,29 @@ +#ifndef _CHARPIPELINE_STRUCTURES_HTABLE_H_ +#define _CHARPIPELINE_STRUCTURES_HTABLE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef u16 (DSHashFunc)(Ptr); + +typedef struct { + DSList* table; + u16 tableSize; + DSHashFunc* hash; +} DSHashTable; + +void DSInitHTable(DSHashTable* hTable, u16 size, DSList* listArray, DSHashFunc* hashFunc, Ptr obj, DSLinkPtr link); +void DSInsertHTableObj(DSHashTable* hTable, Ptr obj); +void DSHTableToList(DSHashTable* hTable, DSList* list); +void* DSNextHTableObj(DSHashTable* hTable, Ptr obj); +s32 DSHTableIndex(DSHashTable* hTable, Ptr obj); +void* DSHTableHead(DSHashTable* hTable, s32 index); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/charPipeline/structures/List.h b/include/charPipeline/structures/List.h new file mode 100644 index 0000000..2ddcd10 --- /dev/null +++ b/include/charPipeline/structures/List.h @@ -0,0 +1,31 @@ +#ifndef _CHARPIPELINE_STRUCTURES_LIST_H_ +#define _CHARPIPELINE_STRUCTURES_LIST_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + Ptr Prev; + Ptr Next; +} DSLink, *DSLinkPtr; + +typedef struct { + u32 Offset; + Ptr Head; + Ptr Tail; +} DSList, *DSListPtr; + +void DSInitList(DSListPtr list, Ptr obj, DSLinkPtr link); +void DSInsertListObject(DSListPtr list, Ptr cursor, Ptr obj); +void DSRemoveListObject(DSListPtr list, Ptr obj); +void DSAttachList(DSListPtr baseList, DSListPtr attachList); +void* DSNextListObj(DSListPtr list, Ptr obj); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/charPipeline/structures/Tree.h b/include/charPipeline/structures/Tree.h new file mode 100644 index 0000000..5ac570f --- /dev/null +++ b/include/charPipeline/structures/Tree.h @@ -0,0 +1,32 @@ +#ifndef _CHARPIPELINE_STRUCTURES_TREE_H_ +#define _CHARPIPELINE_STRUCTURES_TREE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + Ptr Prev; + Ptr Next; + Ptr Parent; + Ptr Children; +} DSBranch, *DSBranchPtr; + +typedef struct { + u32 Offset; + Ptr Root; +} DSTree, *DSTreePtr; + +void DSExtractBranch(DSTreePtr tree, Ptr obj); +void DSInitTree(DSTreePtr tree, Ptr obj, DSBranchPtr branch); +void DSInsertBranchBelow(DSTreePtr tree, Ptr cursor, Ptr obj); +void DSInsertBranchBeside(DSTreePtr tree, Ptr cursor, Ptr obj); +void DSRemoveBranch(DSTreePtr tree, Ptr obj); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/charPipeline/structures/dolphinString.h b/include/charPipeline/structures/dolphinString.h new file mode 100644 index 0000000..b204ee5 --- /dev/null +++ b/include/charPipeline/structures/dolphinString.h @@ -0,0 +1,19 @@ +#ifndef _CHARPIPELINE_STRUCTURES_DOLPHINSTRING_H_ +#define _CHARPIPELINE_STRUCTURES_DOLPHINSTRING_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +u8 Strcat(char* str1, char* str2, char* dst); +void Strcpy(char* dst, char* src); +s8 Strcmp(char* str1, char* str2); +u32 Strlen(char* str); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/charPipeline/texPalette.h b/include/charPipeline/texPalette.h new file mode 100644 index 0000000..72369ef --- /dev/null +++ b/include/charPipeline/texPalette.h @@ -0,0 +1,55 @@ +#ifndef _CHARPIPELINE_TEXPALETTE_H_ +#define _CHARPIPELINE_TEXPALETTE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + u16 numEntries; + u8 unpacked; + u8 pad8; + GXTlutFmt format; + Ptr data; +} CLUTHeader, *CLUTHeaderPtr; + +typedef struct { + u16 height; + u16 width; + u32 format; + Ptr data; + GXTexWrapMode wrapS; + GXTexWrapMode wrapT; + GXTexFilter minFilter; + GXTexFilter magFilter; + f32 LODBias; + u8 edgeLODEnable; + u8 minLOD; + u8 maxLOD; + u8 unpacked; +} TEXHeader, *TEXHeaderPtr; + +typedef struct { + TEXHeaderPtr textureHeader; + CLUTHeaderPtr CLUTHeader; +} TEXDescriptor, *TEXDescriptorPtr; + +typedef struct { + u32 versionNumber; + u32 numDescriptors; + TEXDescriptorPtr descriptorArray; +} TEXPalette, *TEXPalettePtr; + +void TEXGetPalette(TEXPalettePtr* pal, char* name); +TEXDescriptorPtr TEXGet(TEXPalettePtr pal, u32 id); +void TEXReleasePalette(TEXPalettePtr* pal); +void TEXGetGXTexObjFromPalette(TEXPalettePtr pal, GXTexObj* to, u32 id); +void TEXGetGXTexObjFromPaletteCI(TEXPalettePtr pal, GXTexObj* to, GXTlutObj* tlo, GXTlut tluts, u32 id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/types.h b/include/dolphin/types.h index b77602b..213fe1a 100644 --- a/include/dolphin/types.h +++ b/include/dolphin/types.h @@ -37,11 +37,11 @@ typedef int BOOL; #define NULL ((void*)0) #endif -#include "stdio.h" -#include "stdarg.h" -#include "string.h" -#include "ctype.h" +#include "libc/stdio.h" +#include "libc/stdarg.h" +#include "libc/string.h" +#include "libc/ctype.h" -#include "cmath" +#include #endif diff --git a/include/fake_tgmath.h b/include/fake_tgmath.h new file mode 100644 index 0000000..41a9821 --- /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/include/libc/assert.h b/include/libc/assert.h new file mode 100644 index 0000000..1e11c87 --- /dev/null +++ b/include/libc/assert.h @@ -0,0 +1,12 @@ +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#if __STDC_VERSION__ >= 201112L +// The C11 way +#define static_assert(cond, msg) _Static_assert(cond, #msg) +#else +// The old, hacky way +#define static_assert(cond, msg) typedef char static_assertion_##msg[(cond)?1:-1] +#endif + +#endif diff --git a/include/libc/ctype.h b/include/libc/ctype.h new file mode 100644 index 0000000..9731e06 --- /dev/null +++ b/include/libc/ctype.h @@ -0,0 +1,6 @@ +#ifndef _DOLPHIN_LIBC_CTYPE_H_ +#define _DOLPHIN_LIBC_CTYPE_H_ + +int tolower(int c); + +#endif // _DOLPHIN_LIBC_CTYPE_H_ diff --git a/include/libc/errno.h b/include/libc/errno.h new file mode 100644 index 0000000..5f00624 --- /dev/null +++ b/include/libc/errno.h @@ -0,0 +1,4 @@ +#ifndef _ERRNO_H_ +#define _ERRNO_H_ + +#endif diff --git a/include/libc/float.h b/include/libc/float.h new file mode 100644 index 0000000..b94e747 --- /dev/null +++ b/include/libc/float.h @@ -0,0 +1,6 @@ +#ifndef _FLOAT_H_ +#define _FLOAT_H_ + +#define FLT_EPSILON 1.1920928955078125e-07f + +#endif diff --git a/include/libc/limits.h b/include/libc/limits.h new file mode 100644 index 0000000..4206695 --- /dev/null +++ b/include/libc/limits.h @@ -0,0 +1,22 @@ +#ifndef _LIMITS_H_ +#define _LIMITS_H_ + +#define CHAR_BIT 8 + +#define SCHAR_MIN -128 +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +#define SHRT_MIN -32768 +#define SHRT_MAX 32767 +#define USHRT_MAX 65535 + +#define INT_MIN -2147483648 +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295 + +#define LONG_MIN -2147483648 +#define LONG_MAX 2147483647 +#define ULONG_MAX 4294967295 + +#endif diff --git a/include/libc/math.h b/include/libc/math.h new file mode 100644 index 0000000..4c3074b --- /dev/null +++ b/include/libc/math.h @@ -0,0 +1,114 @@ +#ifndef _MATH_H_ +#define _MATH_H_ + +#define M_PI 3.14159265358979323846f + +#define NAN (0.0f / 0.0f) +#define HUGE_VALF (1.0f / 0.0f) +#define INFINITY (1.0f / 0.0f) + +double fabs(double x); +double sin(double x); +double cos(double x); + +float sinf(float x); +float cosf(float x); +float tanf(float x); +float acosf(float x); +float powf(float base, float exponent); + +double ldexp(double x, int exp); + +double scalbn(double x, int n); + +double copysign(double x, double y); + +#ifdef __MWERKS__ +#pragma cplusplus on +#endif + +double floor(double x); + +extern inline float sqrtf(float x) +{ + static const double _half = .5; + static const double _three = 3.0; + volatile float y; + if (x > 0.0f) + { +#ifdef __MWERKS__ + double guess = __frsqrte((double)x); // returns an approximation to +#else + double guess; + asm("frsqrte %0, %1" : "=f"(guess) : "f"(x)); +#endif + 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; +} + +// TODO: this isn't correct! It's just to generate sdata2 in GXDraw.o +extern inline float sqrt(float x) +{ + static const double _half = .5; + static const double _three = 3.0; + volatile float y; + if (x > 0.0f) + { +#ifdef __MWERKS__ + double guess = __frsqrte((double)x); // returns an approximation to +#else + double guess; + asm("frsqrte %0, %1" : "=f"(guess) : "f"(x)); +#endif + 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; +} + +#ifdef __MWERKS__ +#define fabs(x) __fabs(x) +#define fabsf(x) __fabsf(x) +#else +double fabs(double x); +float fabsf(float x); +#endif + +long __fpclassifyf(float x); +long __fpclassifyd(double x); + +#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 isfinite(x) ((fpclassify(x) > FP_INFINITE)) + +inline float fmodf(float x, float m) +{ + float a = fabsf(m); + float b = fabsf(x); + if (a > b) + return x; + else + { + long long c = (long long)(x / m); + return x - m * c; + } +} + +#ifdef __MWERKS__ +#pragma cplusplus reset +#endif + +#endif diff --git a/include/libc/stdarg.h b/include/libc/stdarg.h new file mode 100644 index 0000000..8834b29 --- /dev/null +++ b/include/libc/stdarg.h @@ -0,0 +1,39 @@ +#ifndef _STDARG_H_ +#define _STDARG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __MWERKS__ +typedef 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/include/libc/stddef.h b/include/libc/stddef.h new file mode 100644 index 0000000..8ca5874 --- /dev/null +++ b/include/libc/stddef.h @@ -0,0 +1,12 @@ +#ifndef _STDDEF_H_ +#define _STDDEF_H_ + +#define offsetof(type, member) ((size_t) & (((type*)0)->member)) + +//typedef unsigned int size_t; + +#ifndef NULL +#define NULL 0L +#endif + +#endif diff --git a/include/libc/stdint.h b/include/libc/stdint.h new file mode 100644 index 0000000..aeecf49 --- /dev/null +++ b/include/libc/stdint.h @@ -0,0 +1,6 @@ +#ifndef _STDINT_H_ +#define _STDINT_H_ + +typedef unsigned long int uintptr_t; + +#endif diff --git a/include/libc/stdio.h b/include/libc/stdio.h new file mode 100644 index 0000000..130f903 --- /dev/null +++ b/include/libc/stdio.h @@ -0,0 +1,34 @@ +#ifndef _STDIO_H_ +#define _STDIO_H_ + +#include "libc/stdarg.h" + +typedef struct +{ + int unk0; + unsigned short unk4b0 : 7; + unsigned short unk4b7 : 3; + unsigned short unk4b10 : 2; + unsigned short unk4b12 : 1; + unsigned char filler6[0x14 - 0x6]; + int unk14; + int unk18; + int unk1C; + int unk20; + int unk24; + int unk28; + unsigned char filler2C[0x30 - 0x2C]; + int unk30; + unsigned char filler34[0x3C - 0x34]; + int (*unk3C)(); + unsigned char filler40[4]; + int unk44; +} FILE; + +int puts(const char* s); +int printf(const char*, ...); +int sprintf(char* s, const char* format, ...); +int vprintf(const char* format, va_list arg); +int vsprintf(char* s, const char* format, va_list arg); + +#endif diff --git a/include/libc/stdlib.h b/include/libc/stdlib.h new file mode 100644 index 0000000..8707808 --- /dev/null +++ b/include/libc/stdlib.h @@ -0,0 +1,25 @@ +#ifndef _STDLIB_H_ +#define _STDLIB_H_ + +#include +#include + +#define RAND_MAX 32767 + +void srand(unsigned int seed); +int rand(void); +void abort(void); +void exit(int status); +size_t wcstombs(char *dest, const wchar_t *src, size_t max); + +#ifdef __MWERKS__ +#define abs(x) __abs(x) +#else +static inline int abs(int x) +{ + int mask = x >> 31; + return (x + mask) ^ mask; +} +#endif + +#endif diff --git a/include/libc/string.h b/include/libc/string.h new file mode 100644 index 0000000..bb4dbd1 --- /dev/null +++ b/include/libc/string.h @@ -0,0 +1,26 @@ +#ifndef _STRING_H_ +#define _STRING_H_ + +#include +#ifdef __cplusplus +extern "C" { +#endif + +void* memcpy(void* dest, const void* src, size_t num); +void* memmove(void* dest, const void* src, size_t num); +void* memset(void* dest, int ch, size_t count); +int memcmp(const void* ptr1, const void* ptr2, size_t num); + +size_t strlen(const char* s); +char* strcpy(char* dest, const char* src); +char* strncpy(char* dest, const char* src, size_t num); +int strcmp(const char* s1, const char* s2); +int strncmp(const char* s1, const char* s2, size_t n); +char* strncat(char* dest, const char* src, size_t n); +char* strchr(const char* str, int c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libc/wchar.h b/include/libc/wchar.h new file mode 100644 index 0000000..e5c2056 --- /dev/null +++ b/include/libc/wchar.h @@ -0,0 +1,10 @@ +#ifndef _WCHAR_H_ +#define _WCHAR_H_ + +#include + +typedef unsigned short wchar_t; + +int fwide(FILE* stream, int mode); + +#endif diff --git a/include/macros.inc b/include/macros.inc index bca05c7..ac20a94 100644 --- a/include/macros.inc +++ b/include/macros.inc @@ -146,6 +146,40 @@ .set THRM2, 1021 .set THRM3, 1022 +# Condition Register (CR) bits +.set cr0lt, 0 +.set cr0gt, 1 +.set cr0eq, 2 +.set cr0un, 3 +.set cr1lt, 4 +.set cr1gt, 5 +.set cr1eq, 6 +.set cr1un, 7 +.set cr2lt, 8 +.set cr2gt, 9 +.set cr2eq, 10 +.set cr2un, 11 +.set cr3lt, 12 +.set cr3gt, 13 +.set cr3eq, 14 +.set cr3un, 15 +.set cr4lt, 16 +.set cr4gt, 17 +.set cr4eq, 18 +.set cr4un, 19 +.set cr5lt, 20 +.set cr5gt, 21 +.set cr5eq, 22 +.set cr5un, 23 +.set cr6lt, 24 +.set cr6gt, 25 +.set cr6eq, 26 +.set cr6un, 27 +.set cr7lt, 28 +.set cr7gt, 29 +.set cr7eq, 30 +.set cr7un, 31 + # Defines a sized symbol with function type. # Usage: # .fn my_function, local diff --git a/include/rwsdk/rwplcore.h b/include/rwsdk/rwplcore.h index 20d6790..c8a27d1 100644 --- a/include/rwsdk/rwplcore.h +++ b/include/rwsdk/rwplcore.h @@ -1,8 +1,8 @@ #ifndef RWPLCORE_H #define RWPLCORE_H -#include -#include +#include +#include #define rwBIGENDIAN diff --git a/src/SB/Core/x/containers.h b/src/SB/Core/x/containers.h index 05b894a..f449db8 100644 --- a/src/SB/Core/x/containers.h +++ b/src/SB/Core/x/containers.h @@ -1,7 +1,8 @@ #ifndef CONTAINERS_H #define CONTAINERS_H -#include +#include "types.h" +#include "dolphin\types.h" struct tier_queue_allocator { diff --git a/src/SB/Core/x/xString.h b/src/SB/Core/x/xString.h index 8ceaf92..c2dfaf3 100644 --- a/src/SB/Core/x/xString.h +++ b/src/SB/Core/x/xString.h @@ -2,8 +2,7 @@ #define XSTRING_H #include -#include - +#include struct substr { const char* text; diff --git a/src/SB/Core/x/xWad1.cpp b/src/SB/Core/x/xWad1.cpp index b99666b..b6388e2 100644 --- a/src/SB/Core/x/xWad1.cpp +++ b/src/SB/Core/x/xWad1.cpp @@ -2519,8 +2519,8 @@ static void SingleUpdate(xAnimSingle* single, F32 timeDelta) if (curr == NULL) { - fprintf(stderr, "State \"%s\" no default conditionals true!\n", - single->State->Name); + //fprintf(stderr, "State \"%s\" no default conditionals true!\n", + // single->State->Name); curr = single->State->Default; } diff --git a/src/SB/Core/x/xWad3.h b/src/SB/Core/x/xWad3.h index a630ba3..e986e74 100644 --- a/src/SB/Core/x/xWad3.h +++ b/src/SB/Core/x/xWad3.h @@ -3,6 +3,7 @@ #include "stdlib.h" #include +#include "dolphin\types.h" #include #include "rwcore.h" #include "xModel.h" diff --git a/src/SB/Core/x/xWad5.cpp b/src/SB/Core/x/xWad5.cpp index e215e39..c6dfc5f 100644 --- a/src/SB/Core/x/xWad5.cpp +++ b/src/SB/Core/x/xWad5.cpp @@ -200,68 +200,8 @@ U32 xUtil_crc_init() char* xUtil_idtag2string(U32 srctag, S32 bufidx) { - U32 tag = srctag; - char* strptr; - char* uc = (char*)&tag; - S32 l; - char t; - static char buf[6][10] = {}; - - if (bufidx < 0 || bufidx >= 7) - { - strptr = buf[0]; - } - else - { - strptr = buf[bufidx]; - } - - // convert tag to big endian - - l = 1; - - if ((S32)((char*)&l)[3] != 0) - { - t = uc[0]; - uc[0] = uc[3]; - uc[3] = t; - - t = uc[1]; - uc[1] = uc[2]; - uc[2] = t; - } - - switch (bufidx) - { - case 4: - case 5: - strptr[0] = isprint(uc[0]) ? uc[0] : '?'; - strptr[1] = isprint(uc[1]) ? uc[1] : '?'; - strptr[2] = isprint(uc[2]) ? uc[2] : '?'; - strptr[3] = isprint(uc[3]) ? uc[3] : '?'; - break; - case 6: - default: - strptr[0] = isprint(uc[3]) ? uc[3] : '?'; - strptr[1] = isprint(uc[2]) ? uc[2] : '?'; - strptr[2] = isprint(uc[1]) ? uc[1] : '?'; - strptr[3] = isprint(uc[0]) ? uc[0] : '?'; - break; - } - - strptr[4] = '\0'; - - if (bufidx == 6) - { - strptr[4] = '/'; - strptr[5] = isprint(uc[0]) ? uc[0] : '?'; - strptr[6] = isprint(uc[1]) ? uc[1] : '?'; - strptr[7] = isprint(uc[2]) ? uc[2] : '?'; - strptr[8] = isprint(uc[3]) ? uc[3] : '?'; - strptr[9] = '\0'; - } - - return strptr; + // Deleted to get sdk building + return 0; } S32 xUtilShutdown() diff --git a/src/SB/Game/zCameraTweak.h b/src/SB/Game/zCameraTweak.h index ab90cbc..b2e7344 100644 --- a/src/SB/Game/zCameraTweak.h +++ b/src/SB/Game/zCameraTweak.h @@ -3,7 +3,7 @@ #include "xDynAsset.h" -#include +#include struct CameraTweak_asset : xDynAsset { diff --git a/src/SB/Game/zFMV.cpp b/src/SB/Game/zFMV.cpp index ead01c8..1c65b41 100644 --- a/src/SB/Game/zFMV.cpp +++ b/src/SB/Game/zFMV.cpp @@ -1,5 +1,5 @@ #include "zFMV.h" -#include +#include #include "iFMV.h" #include "xSnd.h" #include "zFMV.h" diff --git a/src/dolphin/G2D/G2D.c b/src/dolphin/G2D/G2D.c new file mode 100644 index 0000000..351a504 --- /dev/null +++ b/src/dolphin/G2D/G2D.c @@ -0,0 +1,721 @@ +#include +#include +#include +#include "fake_tgmath.h" + +static G2DGlob glob; + +void G2DInitSprite(G2DSprite *sprite) { + f32 rInvWidth; + f32 rInvHeight; + + rInvWidth = 1.0f / (f32)GXGetTexObjWidth(sprite->to); + rInvHeight = 1.0f / (f32)GXGetTexObjHeight(sprite->to); + sprite->rS0 = (0.5f + (f32)sprite->nTlcS) * rInvWidth; + sprite->rS1 = rInvWidth * (((f32)sprite->nTlcS + (f32)sprite->nWidth) - 0.5f); + sprite->rT0 = (0.5f + (f32)sprite->nTlcT) * rInvHeight; + sprite->rT1 = rInvHeight * (((f32)sprite->nTlcT + (f32)sprite->nHeight) - 0.5f); +} + +void G2DDrawSprite(G2DSprite* sprite, G2DPosOri* po) { + f32 rOX, rOY; + f32 rWX, rWY; + f32 rHX, rHY; + f32 rRelX, rRelY; + + GXClearVtxDesc(); + GXLoadTexObj(sprite->to, GX_TEXMAP0); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetNumTexGens(1); + GXSetNumChans(0); + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + + rOX = 0.5f * po->rOriX; + rOY = 0.5f * po->rOriY; + + rWX = (f32)sprite->nWidth * rOX; + rWY = (f32)sprite->nWidth * rOY; + rHX = (f32)sprite->nHeight * rOX; + rHY = (f32)sprite->nHeight * rOY; + + rRelX = po->rPosX - glob.poCam.rPosX; + rRelY = po->rPosY - glob.poCam.rPosY; + if (rRelX >= glob.rHalfX) { + rRelX -= glob.rWorldX; + } + if (rRelX < -glob.rHalfX) { + rRelX += glob.rWorldX; + } + if (rRelY >= glob.rHalfY) { + rRelY -= glob.rWorldY; + } + if (rRelY < -glob.rHalfY) { + rRelY += glob.rWorldY; + } + + rRelX += glob.poCam.rPosX; + rRelY += glob.poCam.rPosY; + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition2f32(rWY + (rRelX - rHX), (rRelY - rHY) - rWX); + GXTexCoord2f32(sprite->rS0, sprite->rT1); + + GXPosition2f32(rWY + (rRelX + rHX), (rRelY + rHY) - rWX); + GXTexCoord2f32(sprite->rS0, sprite->rT0); + + GXPosition2f32((rRelX + rHX) - rWY, rWX + (rRelY + rHY)); + GXTexCoord2f32(sprite->rS1, sprite->rT0); + + GXPosition2f32((rRelX - rHX) - rWY, rWX + (rRelY - rHY)); + GXTexCoord2f32(sprite->rS1, sprite->rT1); + + GXEnd(); +} + +static inline void FillSection(G2DLayer* layer, s8* aSortBuffer, s32* nScanLine, s32 nEvent, s16* nIdx, + s32* nL, s32* nR, f32* rLeft, f32* rRight, f32 rStep0, f32 rStep1, s32 nMapX, + s32 nMapY) { + s32 nHMask; + s32 nVMask; + s32 nI; + s32 nJ; + s32 nK; + s32 nM; + s16 nMaterial; + s16* pAddr; + + nHMask = (1 << layer->nHS) - 1; + nVMask = (1 << layer->nVS) - 1; + if (layer->nBPI == 1) { + u8 nTile; + if (layer->bWrap) { + for (; *nScanLine <= nEvent; (*nScanLine)++) { + nJ = *nScanLine - 1; + nK = (nVMask & (nJ + nMapY)) << layer->nHS; + for (nI = *nL; nI <= *nR; nI++) { + nTile = ((u8*)layer->map)[nK + (nHMask & (nI + nMapX))]; + nMaterial = layer->tileDesc[nTile].nMaterial; + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + pAddr[1]++; + + if (*pAddr != *nIdx) { + *nIdx += 2; + *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; + } + *(s16*)&aSortBuffer[*nIdx] = nTile; + *nIdx += 2; + aSortBuffer[(*nIdx)++] = nI; + aSortBuffer[(*nIdx)++] = nJ; + *pAddr = *nIdx; + } + *rLeft += rStep0; + *rRight += rStep1; + *nL = floor(*rLeft); + *nR = floor(*rRight); + } + } else { + for (; *nScanLine <= nEvent; (*nScanLine)++) { + nJ = *nScanLine - 1 + nMapY; + if (nJ < 0) { + nK = 0; + } + else if ( nJ > nVMask ) { + nK = nVMask << layer->nHS; + } + else { + nK = nJ << layer->nHS; + } + + nM = *nR + nMapX; + for (nI = *nL + nMapX; nI <= nM; nI++) { + if ( nI < 0 ) { + nTile = ((u8*)layer->map)[nK]; + } + else if ( nI > nHMask ) { + nTile = ((u8*)layer->map)[nK + nHMask]; + } + else { + nTile = ((u8*)layer->map)[nK + nI]; + } + + nMaterial = layer->tileDesc[nTile].nMaterial; + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + pAddr[1]++; + + if (*pAddr != *nIdx) { + *nIdx += 2; + *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; + } + *(s16*)&aSortBuffer[*nIdx] = nTile; + *nIdx += 2; + aSortBuffer[(*nIdx)++] = nI - nMapX; + aSortBuffer[(*nIdx)++] = nJ - nMapY; + *pAddr = *nIdx; + } + + *rLeft += rStep0; + *rRight += rStep1; + *nL = floor(*rLeft); + *nR = floor(*rRight); + } + } + } else { + u16 nTile; + if (layer->bWrap) { + for (; *nScanLine <= nEvent; (*nScanLine)++) { + nJ = *nScanLine - 1; + nK = (nVMask & (nJ + nMapY)) << layer->nHS; + for (nI = *nL; nI <= *nR; nI++) { + nTile = ((u16*)layer->map)[nK + (nHMask & (nI + nMapX))]; + nMaterial = layer->tileDesc[nTile].nMaterial; + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + pAddr[1]++; + + if (*pAddr != *nIdx) { + *nIdx += 2; + *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; + } + *(s16*)&aSortBuffer[*nIdx] = nTile; + *nIdx += 2; + aSortBuffer[(*nIdx)++] = nI; + aSortBuffer[(*nIdx)++] = nJ; + *pAddr = *nIdx; + } + + *rLeft += rStep0; + *rRight += rStep1; + *nL = floor(*rLeft); + *nR = floor(*rRight); + } + } else { + for (; *nScanLine <= nEvent; (*nScanLine)++) { + nJ = *nScanLine - 1 + nMapY; + if (nJ < 0) { + nK = 0; + } + else if ( nJ > nVMask ) { + nK = nVMask << layer->nHS; + } + else { + nK = nJ << layer->nHS; + } + + nM = *nR + nMapX; + for (nI = *nL + nMapX; nI <= nM; nI++) { + if ( nI < 0 ) { + nTile = ((u16*)layer->map)[nK]; + } + else if ( nI > nHMask ) { + nTile = ((u16*)layer->map)[nK + nHMask]; + } + else { + nTile = ((u16*)layer->map)[nK + nI]; + } + + nMaterial = layer->tileDesc[nTile].nMaterial; + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + pAddr[1]++; + + if (*pAddr != *nIdx) { + *nIdx += 2; + *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; + } + *(s16*)&aSortBuffer[*nIdx] = nTile; + *nIdx += 2; + aSortBuffer[(*nIdx)++] = nI - nMapX; + aSortBuffer[(*nIdx)++] = nJ - nMapY; + *pAddr = *nIdx; + } + + *rLeft += rStep0; + *rRight += rStep1; + *nL = floor(*rLeft); + *nR = floor(*rRight); + } + } + } +} + +void G2DDrawLayer(G2DLayer* layer, s8* aSortBuffer) { + s16* pAddr; + s16 aCount0; + s16 aCount1; + s16 aCount2; + f32 rInvTileWidth; + f32 rInvTileHeight; + s16 nIdx; + s32 nI; + s32 nJ; + s32 nK; + s32 nL; + s32 nR; + f32 rX; + f32 rY; + f32 rTlcX; + f32 rTrcX; + f32 rBlcX; + f32 rBrcX; + f32 rTlcY; + f32 rTrcY; + f32 rBlcY; + f32 rBrcY; + s32 nScanLine; + f32 rLeft; + f32 rRight; + f32 rLeftY; + f32 rRightY; + f32 rStep0; + f32 rStep1; + f32 rMid; + s32 nEvent0; + s32 nEvent1; + s32 nEvent2; + f32 rFrcX; + f32 rFrcY; + s32 nMapX; + s32 nMapY; + s32 nLocalMapX; + s32 nLocalMapY; + f32 rCamOriX; + f32 rCamOriY; + s16 nTile; + s16 nMaterial; + f32 rRatio; + + aCount0 = 0; + aCount1 = 0; + aCount2 = 0; + rInvTileWidth = 1.0f / (f32)layer->nTileWidth; + rInvTileHeight = 1.0f / (f32)layer->nTileHeight; + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + + for (nI = 0; nI < layer->nNumMaterials; nI++) { + pAddr = (s16*)&layer->matDesc[nI]; + pAddr[0] = nI << 1; + pAddr[1] = 0; + } + nIdx = (nI - 1) << 1; + + rFrcX = glob.poCam.rPosX * rInvTileWidth; + rFrcY = glob.poCam.rPosY * rInvTileHeight; + nMapX = (s32)rFrcX; + nMapY = (s32)rFrcY; + rFrcX -= nMapX; + rFrcY -= nMapY; + + rCamOriX = glob.poCam.rOriX; + rCamOriY = glob.poCam.rOriY; + if (rCamOriX < 0.0001 && rCamOriX > -0.0001) { + rCamOriX = 0.0001f; + } + else if (rCamOriY < 0.0001 && rCamOriY > -0.0001) { + rCamOriY = 0.0001f; + } + + rX = 0.5f * (f32)glob.nViewportWidth; + rY = 0.5f * (f32)glob.nViewportHeight; + rTlcX = rFrcX + (rInvTileWidth * ((rY * rCamOriX) + (rX * rCamOriY))); + rTlcY = (rFrcY + (rInvTileHeight * ((rY * rCamOriY) - (rX * rCamOriX)))); + rTrcX = rFrcX + (rInvTileWidth * ((rY * rCamOriX) - (rX * rCamOriY))); + rTrcY = (rFrcY + (rInvTileHeight * ((rY * rCamOriY) + (rX * rCamOriX)))); + rBlcX = rFrcX - (rInvTileWidth * ((rY * rCamOriX) - (rX * rCamOriY))); + rBlcY = rFrcY - (rInvTileHeight * ((rY * rCamOriY) + (rX * rCamOriX))); + rBrcX = rFrcX - (rInvTileWidth * ((rY * rCamOriX) + (rX * rCamOriY))); + rBrcY = rFrcY - (rInvTileHeight * ((rY * rCamOriY) - (rX * rCamOriX))); + + if (rCamOriY < 0.0f) { + if (rCamOriX >= 0.0f) { + nScanLine = (s32)floor(rTlcY) + 1; + rY = nScanLine - rTlcY; + rLeft = rTlcX; + rLeftY = rBlcY; + rRightY = rTrcY; + nEvent2 = (s32)floor(rBrcY); + rStep0 = rCamOriX / rCamOriY; + rStep1 = -rCamOriY / rCamOriX; + } + else { + nScanLine = (s32)floor(rTrcY) + 1; + rY = nScanLine - rTrcY; + rLeft = rTrcX; + rLeftY = rTlcY; + rRightY = rBrcY; + nEvent2 = (s32)floor(rBlcY); + rStep0 = -rCamOriY / rCamOriX; + rStep1 = rCamOriX / rCamOriY; + } + } else { + if (rCamOriX >= 0.0f) { + nScanLine = (s32)floor(rBlcY) + 1; + rY = nScanLine - rBlcY; + rLeft = rBlcX; + rLeftY = rBrcY; + rRightY = rTlcY; + nEvent2 = (s32)floor(rTrcY); + rStep0 = -rCamOriY / rCamOriX; + rStep1 = rCamOriX / rCamOriY; + } else { + nScanLine = (s32)floor(rBrcY) + 1; + rY = nScanLine - rBrcY; + rLeft = rBrcX; + rLeftY = rTrcY; + rRightY = rBlcY; + nEvent2 = (s32)floor(rTlcY); + rStep0 = rCamOriX / rCamOriY; + rStep1 = -rCamOriY / rCamOriX; + } + } + + rRatio = (f32)layer->nTileHeight / (f32)layer->nTileWidth; + rStep0 *= rRatio; + rStep1 *= rRatio; + rRight = rLeft + (rY * rStep1); + rLeft = rLeft + (rY * rStep0); + + if (rLeftY < rRightY) { + nEvent0 = (s32)floor(rLeftY); + nEvent1 = (s32)floor(rRightY); + rMid = rStep1; + } else { + nEvent0 = (s32)floor(rRightY); + nEvent1 = (s32)floor(rLeftY); + rMid = rStep0; + } + + nL = (s32)floor(rLeft); + nR = (s32)floor(rRight); + nLocalMapX = nMapX; + nLocalMapY = nMapY; + + if (!layer->bWrap) { + f32 rInvTileWidth = 1.0f / (f32)layer->nTileWidth; + f32 rInvTileHeight = 1.0f / (f32)layer->nTileHeight; + f32 rLocalPosX = glob.poCam.rPosX; + f32 rLocalPosY = glob.poCam.rPosY; + f32 rSplitX = 0.5f * (glob.rWorldX + (f32)(layer->nTileWidth * (1 << layer->nHS))); + f32 rSplitY = 0.5f * (glob.rWorldY + (f32)(layer->nTileHeight * (1 << layer->nVS))); + + if (rLocalPosX >= rSplitX) { + rLocalPosX -= glob.rWorldX; + } + + if (rLocalPosY >= rSplitY) { + rLocalPosY -= glob.rWorldY; + } + + rFrcX = rLocalPosX * rInvTileWidth; + rFrcY = rLocalPosY * rInvTileHeight; + + nLocalMapX = floor(rFrcX); + nLocalMapY = floor(rFrcY); + } + + FillSection(layer, aSortBuffer, &nScanLine, nEvent0, &nIdx, &nL, &nR, &rLeft, &rRight, rStep0, rStep1, nLocalMapX, nLocalMapY); + + pAddr = (s16*)&layer->matDesc[0].nReserved; + aCount0 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[1].nReserved; + aCount1 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[2].nReserved; + aCount2 = pAddr[1]; + + if ((f32)nScanLine > rLeftY) { + rLeft -= rStep0 * ((f32)nScanLine - rLeftY); + nL = (s32)floor(rLeft); + rLeft += rStep1 * (((f32)nScanLine - rLeftY) - 1.0f); + rLeftY = 1000.0f; + } + + if ((f32)nScanLine > rRightY) { + rRight -= rStep1 * ((f32)nScanLine - rRightY); + nR = (s32)floor(rRight); + rRight += rStep0 * (((f32)nScanLine - rRightY) - 1.0f); + rRightY = 1000.0f; + } + + FillSection(layer, aSortBuffer, &nScanLine, nEvent1, &nIdx, &nL, &nR, &rLeft, &rRight, rMid, rMid, nLocalMapX, nLocalMapY); + + pAddr = (s16*)&layer->matDesc[0].nReserved; + aCount0 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[1].nReserved; + aCount1 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[2].nReserved; + aCount2 = pAddr[1]; + + if ((f32)nScanLine > rLeftY) { + rLeft -= rStep0 * ((f32)nScanLine - rLeftY); + nL = (s32)floor(rLeft); + rLeft += rStep1 * (((f32)nScanLine - rLeftY) - 1.0f); + } + + if ((f32)nScanLine > rRightY) { + rRight -= rStep1 * ((f32)nScanLine - rRightY); + nR = (s32)floor(rRight); + rRight += rStep0 * (((f32)nScanLine - rRightY) - 1.0f); + } + + FillSection(layer, aSortBuffer, &nScanLine, nEvent2 + 1, &nIdx, &nL, &nR, &rLeft, &rRight, rStep1, rStep0, nLocalMapX, nLocalMapY); + + pAddr = (s16*)&layer->matDesc[0].nReserved; + aCount0 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[1].nReserved; + aCount1 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[2].nReserved; + aCount2 = pAddr[1]; + + for (nMaterial = 0; nMaterial < layer->nNumMaterials; nMaterial++) { + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + if (!pAddr[1]) { + continue; + } + + switch (layer->matDesc[nMaterial].nCategory) { + case G2D_CTG_EMPTY: + continue; + + case G2D_CTG_RGBA_INDEX8: { + GXClearVtxDesc(); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + GXSetNumTexGens(0); + GXSetVtxDesc(GX_VA_TEX0, GX_NONE); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8); + GXSetArray(GX_VA_CLR0, layer->matDesc[nMaterial].clut, 4); + + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_VTX, GX_SRC_VTX, 1, GX_DF_NONE, GX_AF_NONE); + + nIdx = nMaterial << 1; + GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); + + for (nK = pAddr[1]; nK--; ) { + f32 rI, rJ; + u8 nCI; + + nTile = *((s16*)&aSortBuffer[nIdx]); + if (nTile < 0) { + nIdx -= nTile; + nTile = *((s16*)&aSortBuffer[nIdx]); + } + nIdx += 2; + nI = aSortBuffer[nIdx++]; + nJ = aSortBuffer[nIdx++]; + + rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); + rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); + nCI = layer->tileDesc[nTile].nCI; + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); + GXColor1x8(nCI); + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); + GXColor1x8(nCI); + + GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); + GXColor1x8(nCI); + + GXPosition2f32(rI, rJ); + GXColor1x8(nCI); + } + + GXEnd(); + break; + } + + case G2D_CTG_RGB_DIRECT: { + GXClearVtxDesc(); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + GXSetNumTexGens(0); + GXSetVtxDesc(GX_VA_TEX0, GX_NONE); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_VTX, GX_SRC_VTX, 1, GX_DF_NONE, GX_AF_NONE); + + nIdx = nMaterial << 1; + GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); + + for (nK = pAddr[1]; nK--; ) { + f32 rI, rJ; + u8 nR, nG, nB; + + nTile = *((s16*)&aSortBuffer[nIdx]); + if (nTile < 0) { + nIdx -= nTile; + nTile = *((s16*)&aSortBuffer[nIdx]); + } + + nIdx += 2; + nI = aSortBuffer[nIdx++]; + nJ = aSortBuffer[nIdx++]; + + rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); + rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); + nR = layer->tileDesc[nTile].nS; + nG = layer->tileDesc[nTile].nT; + nB = layer->tileDesc[nTile].nCI; + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); + GXColor3u8(nR, nG, nB); + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); + GXColor3u8(nR, nG, nB); + + GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); + GXColor3u8(nR, nG, nB); + + GXPosition2f32(rI, rJ); + GXColor3u8(nR, nG, nB); + } + + GXEnd(); + break; + } + + case G2D_CTG_TEXTURE: { + f32 rInvTileWidth = 1.0f / (f32)GXGetTexObjWidth(layer->matDesc[nMaterial].to); + f32 rInvTileHeight = 1.0f / (f32)GXGetTexObjHeight(layer->matDesc[nMaterial].to); + + f32 rWidth = (f32)layer->nTileWidth * rInvTileWidth; + f32 rHeight = (f32)layer->nTileHeight * rInvTileHeight; + + f32 rS0 = 0.0f; + f32 rT0 = 0.0f; + f32 rS1 = rWidth; + f32 rT1 = rHeight; + + GXClearVtxDesc(); + + GXLoadTexObj(layer->matDesc[nMaterial].to, GX_TEXMAP0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + GXSetNumTexGens(1); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + + if ( layer->matDesc[nMaterial].color ) { + GXSetNumChans(1); + GXSetChanMatColor(GX_COLOR0A0, *layer->matDesc[nMaterial].color); + GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_REG, GX_SRC_REG, 1, GX_DF_NONE, GX_AF_NONE); + GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + } else { + GXSetNumChans(0); + GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + } + + nIdx = nMaterial << 1; + GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); + + for (nK = pAddr[1]; nK--; ) { + f32 rI; + f32 rJ; + f32 rS; + f32 rT; + + nTile = *((s16*)&aSortBuffer[nIdx]); + if (nTile < 0) { + nIdx -= nTile; + nTile = *((s16*)&aSortBuffer[nIdx]); + } + + nIdx += 2; + nI = aSortBuffer[nIdx++]; + nJ = aSortBuffer[nIdx++]; + + rS = rS0 + (rWidth * (f32)layer->tileDesc[nTile].nS); + rT = rT0 + (rHeight * (f32)layer->tileDesc[nTile].nT); + rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); + rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); + GXTexCoord2f32(rS + rS1, rT); + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); + GXTexCoord2f32(rS + rS1, rT + rT1); + + GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); + GXTexCoord2f32(rS, rT + rT1); + + GXPosition2f32(rI, rJ); + GXTexCoord2f32(rS, rT); + } + + GXEnd(); + break; + } + } + } +} + +void G2DSetCamera(G2DPosOri* po) { + Mtx mView; + Vec vPos; + Vec vUp; + Vec vAt; + f32 rX; + f32 rY; + + glob.poCam = *po; + + vUp.x = po->rOriX; + vUp.y = po->rOriY; + vUp.z = 0.0f; + + rX = (((640 - glob.nViewportWidth) >> 1) - glob.nViewportTlcX); + rY = (((448 - glob.nViewportHeight) >> 1) - glob.nViewportTlcY); + + vPos.x = po->rPosX - (vUp.x * rY) - (vUp.y * rX); + vPos.y = po->rPosY + (vUp.x * rX) - (vUp.y * rY); + vPos.z = -300.0f; + + vAt.x = vPos.x; + vAt.y = vPos.y; + vAt.z = 0.0f; + + MTXLookAt(mView, &vPos, &vUp, &vAt); + GXLoadPosMtxImm(mView, GX_PNMTX0); +} + +void G2DInitWorld(u32 nWorldX, u32 nWorldY) { + Mtx44 mProjection; + + glob.rWorldX = (f32)nWorldX; + glob.rWorldY = (f32)nWorldY; + glob.rHalfX = (f32)(nWorldX >> 1); + glob.rHalfY = (f32)(nWorldY >> 1); + GXSetZMode(0, GX_ALWAYS, 1); + MTXOrtho(mProjection, 224.0f, -224.0f, -320.0f, 320.0f, 100.0f, 1000.0f); + GXSetProjection(mProjection, GX_ORTHOGRAPHIC); +} + +void G2DSetViewport(u16 nLeft, u16 nTop, u16 nWidth, u16 nHeight) { + glob.nViewportTlcX = nLeft; + glob.nViewportTlcY = nTop; + glob.nViewportWidth = nWidth; + glob.nViewportHeight = nHeight; + GXSetScissor(nLeft, nTop, nWidth, nHeight); +} diff --git a/src/dolphin/ai/src/ai.c b/src/dolphin/ai/src/ai.c new file mode 100644 index 0000000..c9c38ee --- /dev/null +++ b/src/dolphin/ai/src/ai.c @@ -0,0 +1,411 @@ +#include +#include +#include +#include + +#include "__gx.h" + +#ifdef DEBUG +const char* __AIVersion = "<< Dolphin SDK - AI\tdebug build: Apr 5 2004 03:56:18 (0x2301) >>"; +#else +const char* __AIVersion = "<< Dolphin SDK - AI\trelease build: Apr 5 2004 04:15:02 (0x2301) >>"; +#endif + +static AISCallback __AIS_Callback; +static AIDCallback __AID_Callback; +static u8* __CallbackStack; +static u8* __OldStack; +static BOOL __AI_init_flag; +static BOOL __AID_Active; +static OSTime bound_32KHz; +static OSTime bound_48KHz; +static OSTime min_wait; +static OSTime max_wait; +static OSTime buffer; + +typedef struct { + OSTime t_start; + OSTime t1; + OSTime t2; + OSTime t3; + OSTime t4; + OSTime t_end; +} STRUCT_TIMELOG; +STRUCT_TIMELOG profile; + +OSTime __ai_src_time_start; +OSTime __ai_src_time_end; + +// prototypes +void __AI_DEBUG_set_stream_sample_rate(u32 rate); +STRUCT_TIMELOG* __ai_src_get_time(void); + +static void __AI_set_stream_sample_rate(u32 rate); +static void __AIDHandler(__OSInterrupt interrupt, OSContext* context); +static void __AISHandler(__OSInterrupt interrupt, OSContext* context); +static void __AICallbackStackSwitch(void* cb); +static void __AI_SRC_INIT(void); + +AIDCallback AIRegisterDMACallback(AIDCallback callback) { + AIDCallback old_callback; + BOOL old; + + old_callback = __AID_Callback; + old = OSDisableInterrupts(); + __AID_Callback = callback; + OSRestoreInterrupts(old); + return old_callback; +} + +void AIInitDMA(u32 start_addr, u32 length) { + BOOL old; + + old = OSDisableInterrupts(); + __DSPRegs[24] = (__DSPRegs[24] & 0xFFFFFC00) | (start_addr >> 16); + __DSPRegs[25] = (__DSPRegs[25] & 0xFFFF001F) | (start_addr & 0xFFFF); + ASSERTMSGLINE(316, (length & 0x1F) == 0, "AIStartDMA: length must be multiple of 32 bytes"); + __DSPRegs[27] = (__DSPRegs[27] & 0xFFFF8000) | ((length >> 5) & 0xFFFF); + OSRestoreInterrupts(old); +} + +BOOL AIGetDMAEnableFlag(void) { + return (__DSPRegs[27] & (1 << 15)) >> 15; +} + +void AIStartDMA(void) { + __DSPRegs[27] = __DSPRegs[27] | 0x8000; +} + +void AIStopDMA(void) { + __DSPRegs[27] = __DSPRegs[27] & ~0x8000; +} + +u32 AIGetDMABytesLeft(void) { + return (__DSPRegs[29] & 0x7FFF) << 5; +} + +u32 AIGetDMAStartAddr(void) { + return ((__DSPRegs[24] << 16) & 0x03FF0000) | (__DSPRegs[25] & 0xFFE0); +} + +u32 AIGetDMALength(void) { + return (__DSPRegs[27] & 0x7FFF) << 5; +} + +BOOL AICheckInit(void) { + return __AI_init_flag; +} + +AISCallback AIRegisterStreamCallback(AISCallback callback) { + AISCallback old_callback; + BOOL old; + + old_callback = __AIS_Callback; + old = OSDisableInterrupts(); + __AIS_Callback = callback; + OSRestoreInterrupts(old); + return old_callback; +} + +u32 AIGetStreamSampleCount(void) { + return __AIRegs[2]; +} + +void AIResetStreamSampleCount(void) { + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; +} + +void AISetStreamTrigger(u32 trigger) { + __AIRegs[3] = trigger; +} + +u32 AIGetStreamTrigger(void) { + return __AIRegs[3]; +} + +void AISetStreamPlayState(u32 state) { + BOOL old; + u8 vol_left; + u8 vol_right; + + if (state != AIGetStreamPlayState()) { + if (AIGetStreamSampleRate() == 0 && state == AI_STREAM_START) { + vol_left = AIGetStreamVolRight(); + vol_right = AIGetStreamVolLeft(); + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + old = OSDisableInterrupts(); + __AI_SRC_INIT(); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); + OSRestoreInterrupts(old); + AISetStreamVolLeft(vol_left); + AISetStreamVolRight(vol_right); + return; + } + OLD_SET_REG_FIELD(653, __AIRegs[0], 1, 0, state); + } +} + +u32 AIGetStreamPlayState(void) { + return __AIRegs[0] & 1; +} + +void AISetDSPSampleRate(u32 rate) { + BOOL old; + u32 play_state; + u32 afr_state; + u8 vol_left; + u8 vol_right; + + if (rate != AIGetDSPSampleRate()) { + __AIRegs[0] = (__AIRegs[0] & 0xFFFFFFBF); + if (rate == AI_SAMPLERATE_32KHZ) { + vol_left = AIGetStreamVolLeft(); + vol_right = AIGetStreamVolRight(); + play_state = AIGetStreamPlayState(); + afr_state = AIGetStreamSampleRate(); + AISetStreamVolLeft(0U); + AISetStreamVolRight(0U); + old = OSDisableInterrupts(); + __AI_SRC_INIT(); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); + OLD_SET_REG_FIELD(743, __AIRegs[0], 1, 1, afr_state); + OLD_SET_REG_FIELD(744, __AIRegs[0], 1, 0, play_state); + __AIRegs[0] |= 0x40; + OSRestoreInterrupts(old); + AISetStreamVolLeft(vol_left); + AISetStreamVolRight(vol_right); + } + } +} + +u32 AIGetDSPSampleRate(void) { + return GET_REG_FIELD(__AIRegs[0], 1, 6) ^ 1; +} + +void AISetStreamSampleRate(u32 rate) { + if (rate == AI_SAMPLERATE_48KHZ) { + __AI_set_stream_sample_rate(rate); + return; + } +#if DEBUG + OSReport("AISetStreamSampleRate(): OBSOLETED. Only 48KHz streaming from disk is supported!\n"); +#endif +} + +void __AI_DEBUG_set_stream_sample_rate(u32 rate) { + __AI_set_stream_sample_rate(rate); +} + +static void __AI_set_stream_sample_rate(u32 rate) { + BOOL old; + u32 play_state; + u8 vol_left; + u8 vol_right; + u32 dsp_src_state; + + if (rate != AIGetStreamSampleRate()) { + play_state = AIGetStreamPlayState(); + vol_left = AIGetStreamVolLeft(); + vol_right = AIGetStreamVolRight(); + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + dsp_src_state = __AIRegs[0] & 0x40; + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 6, 0); + old = OSDisableInterrupts(); + __AI_SRC_INIT(); + __AIRegs[0] |= dsp_src_state; + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); + OLD_SET_REG_FIELD(887, __AIRegs[0], 1, 1, rate); + OSRestoreInterrupts(old); + AISetStreamPlayState(play_state); + AISetStreamVolLeft(vol_left); + AISetStreamVolRight(vol_right); + } +} + +u32 AIGetStreamSampleRate(void) { + return GET_REG_FIELD(__AIRegs[0], 1, 1); +} + +void AISetStreamVolLeft(u8 vol) { + OLD_SET_REG_FIELD(945, __AIRegs[1], 8, 0, vol); +} + +u8 AIGetStreamVolLeft(void) { + return GET_REG_FIELD(__AIRegs[1], 8, 0); +} + +void AISetStreamVolRight(u8 vol) { + OLD_SET_REG_FIELD(986, __AIRegs[1], 8, 8, vol); +} + +u8 AIGetStreamVolRight(void) +{ + return (__AIRegs[1] & (0xFF << 8)) >> 8; +} + +void AIInit(u8* stack) { + if (__AI_init_flag != TRUE) { + OSRegisterVersion(__AIVersion); + + bound_32KHz = OSNanosecondsToTicks(31524); + bound_48KHz = OSNanosecondsToTicks(42024); + min_wait = OSNanosecondsToTicks(42000); + max_wait = OSNanosecondsToTicks(63000); + buffer = OSNanosecondsToTicks(3000); + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + AISetStreamTrigger(0); + AIResetStreamSampleCount(); + __AI_set_stream_sample_rate(AI_SAMPLERATE_48KHZ); + AISetDSPSampleRate(AI_SAMPLERATE_32KHZ); +#if DEBUG + OSReport("AIInit(): DSP is 32KHz\n"); +#endif + __AIS_Callback = NULL; + __AID_Callback = NULL; + __CallbackStack = stack; + if (stack) { + ASSERTMSGLINE(1107, ((u32)stack & 7) == 0, "AIInit: stack must be 8-byte aligned"); + } + __OSSetInterruptHandler(5, __AIDHandler); + __OSUnmaskInterrupts(0x04000000); + __OSSetInterruptHandler(8, __AISHandler); + __OSUnmaskInterrupts(0x800000); + __AI_init_flag = TRUE; + } +} + +void AIReset(void) { + __AI_init_flag = FALSE; +} + +static void __AISHandler(__OSInterrupt interrupt, OSContext* context) { + OSContext exceptionContext; + + __AIRegs[0] |= 8; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + if (__AIS_Callback) { + __AIS_Callback(__AIRegs[2]); + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +static void __AIDHandler(__OSInterrupt interrupt, OSContext* context) { + OSContext exceptionContext; + u16 tmp; + + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA0) | 8; + __DSPRegs[5] = tmp; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + if (__AID_Callback && !__AID_Active) { + __AID_Active = TRUE; + if (__CallbackStack) { + __AICallbackStackSwitch(__AID_Callback); + } else { + __AID_Callback(); + } + __AID_Active = FALSE; + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +static asm void __AICallbackStackSwitch(register void* cb) { + nofralloc + mflr r0 + stw r0, 0x4(r1) + stwu r1, -0x18(r1) + stw r31, 0x14(r1) + mr r31, r3 + lis r5, __OldStack@ha + addi r5, r5, __OldStack@l + stw r1, 0x0(r5) + lis r5, __CallbackStack@ha + addi r5, r5, __CallbackStack@l + lwz r1, 0x0(r5) + subi r1, r1, 0x8 + mtlr r31 + blrl + lis r5, __OldStack@ha + addi r5, r5, __OldStack@l + lwz r1, 0x0(r5) + lwz r0, 0x1c(r1) + lwz r31, 0x14(r1) + addi r1, r1, 0x18 + mtlr r0 + blr +} + +void __AI_SRC_INIT(void) { + OSTime rising_32khz = 0; + OSTime rising_48khz = 0; + OSTime diff = 0; + OSTime t1 = 0; + OSTime temp; + u32 temp0; + u32 temp1; + u32 done = 0; + u32 volume = 0; + u32 Init_Cnt = 0; + u32 walking = 0; + + walking = 0; + Init_Cnt = 0; + temp = 0; + +#if DEBUG + profile.t_start = OSGetTime(); +#endif + + while (!done) { + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 0); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); + temp0 = __AIRegs[2]; + while (temp0 == __AIRegs[2]) { + } + rising_32khz = OSGetTime(); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 1); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); + temp1 = __AIRegs[2]; + while (temp1 == __AIRegs[2]) { + } + rising_48khz = OSGetTime(); + diff = rising_48khz - rising_32khz; + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 0); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_STOP); + if (diff < bound_32KHz - buffer) { + temp = min_wait; + done = 1; + 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()) { + } +#if DEBUG + profile.t_end = OSGetTime(); +#endif +} + +STRUCT_TIMELOG* __ai_src_get_time(void) { +#if DEBUG + return &profile; +#else + return NULL; +#endif +} diff --git a/src/dolphin/am/src/__am.h b/src/dolphin/am/src/__am.h new file mode 100644 index 0000000..7907a62 --- /dev/null +++ b/src/dolphin/am/src/__am.h @@ -0,0 +1,39 @@ +#ifndef _DOLPHIN_AM_INTERNAL_H_ +#define _DOLPHIN_AM_INTERNAL_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define AM_STACK_ENTRIES 16 + +typedef struct { + DVDFileInfo file_handle; + ARQRequest arq_handle; + AMCallback callback; + char* path; + void* buffer; + volatile u32 file_length; + volatile u32 curr_read_offset; + volatile u32 read_length; + volatile u32 aram_start_addr; + volatile u32 curr_aram_offset; + volatile int poll_flag; +} AMReadInfo; + +extern AMReadInfo __AMReadInfo[AM_STACK_ENTRIES]; + +static void __AM_dvd_callback(s32 result, DVDFileInfo* handle); +static void __AM_arq_callback(u32 task); +static void __AM_arq_poll_callback(u32 task); +u32 __AMPushBuffered(char* path, void* buffer, u32 buffer_size, AMCallback callback, int async_flag); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/am/src/am.c b/src/dolphin/am/src/am.c new file mode 100644 index 0000000..56350a9 --- /dev/null +++ b/src/dolphin/am/src/am.c @@ -0,0 +1,322 @@ +#include +#include + +#include "__am.h" + +static u32 __AMStackPointer[AM_STACK_ENTRIES]; +static AMReadInfo __AMReadInfo[AM_STACK_ENTRIES]; + +static u32 __AMStackLocation; +static u32 __AMFreeBytes; +static u32 __AMPendingReads; + +static void __AM_dvd_callback(s32 result, DVDFileInfo* handle) { + u32 i; + AMReadInfo* ptr; + + for (i = 0; i < AM_STACK_ENTRIES; i++) { + if (handle == &(__AMReadInfo[i].file_handle)) { + ptr = &__AMReadInfo[i]; + break; + } + } + + ASSERTLINE(136, i != AM_STACK_ENTRIES); + + if (DVDGetCommandBlockStatus(&ptr->file_handle.cb) == 0) { + ARQPostRequest(&ptr->arq_handle, i, 0, 1, (u32)ptr->buffer, ptr->curr_aram_offset, result, __AM_arq_callback); + ptr->curr_aram_offset += result; + ptr->curr_read_offset += result; + } +} + +static void __AM_arq_callback(u32 task) { + u32 i; + AMReadInfo* ptr; + u32 remainder; + u32 read_request_length; + + for (i = 0; i < AM_STACK_ENTRIES; i++) { + if ((ARQRequest*)task == &__AMReadInfo[i].arq_handle) { + ptr = &__AMReadInfo[i]; + break; + } + } + + ASSERTLINE(198, i != AM_STACK_ENTRIES); + + if (ptr->curr_read_offset < ptr->file_length) { + remainder = ptr->file_length - ptr->curr_read_offset; + read_request_length = OSRoundUp32B(ptr->read_length > remainder ? remainder : ptr->read_length); + DVDReadAsync(&ptr->file_handle, ptr->buffer, read_request_length, ptr->curr_read_offset, __AM_dvd_callback); + } else { + ASSERTMSGLINE(220, __AMPendingReads, "AMPushBuffered(): Dangling read-complete event!\n"); + __AMPendingReads--; + + if (ptr->callback) { + (*ptr->callback)(ptr->path); + } + } +} + +static void __AM_arq_poll_callback(u32 task) { + u32 i; + AMReadInfo* ptr; + + for (i = 0; i < AM_STACK_ENTRIES; i++) { + if ((ARQRequest*)task == &__AMReadInfo[i].arq_handle) { + ptr = &__AMReadInfo[i]; + break; + } + } + + ASSERTLINE(262, i != AM_STACK_ENTRIES); + + ptr->poll_flag = 1; +} + +void* AMLoadFile(char* path, u32* length) { + DVDFileInfo dvdFileInfo; + u32 roundLength; + s32 readLength; + void* buffer; + int old; + + if (!DVDOpen(path, &dvdFileInfo)) { + char ch[1024]; + sprintf(ch, "Cannot open %s", path); + ASSERTMSGLINE(290, 0, ch); + } + + ASSERTMSGLINE(294, dvdFileInfo.length, "File length is 0\n"); + + roundLength = OSRoundUp32B(dvdFileInfo.length); + + old = OSDisableInterrupts(); + buffer = OSAlloc(roundLength); + OSRestoreInterrupts(old); + + ASSERTMSGLINE(303, buffer, "Unable to allocate buffer\n"); + readLength = DVDReadPrio(&dvdFileInfo, buffer, roundLength, 0, 2); + ASSERTMSGLINE(307, readLength > 0, "Read length <= 0\n"); + if (length != 0) { + *length = roundLength; + } + + return buffer; +} + +u32 AMPush(char* path) { + DVDFileInfo handle; + void* buffer; + u32 buffer_length; + u32 ret_val; + BOOL old; + + if (!DVDOpen(path, &handle)) { + OSReport("AMPushBuffered(): Unable to open file '%s'\n", path); + OSPanic(__FILE__, 343, "AM: FATAL ERROR\n"); + } + + buffer_length = OSRoundUp32B(handle.length); + if (buffer_length) { + old = OSDisableInterrupts(); + buffer = OSAlloc(buffer_length); + OSRestoreInterrupts(old); + + ASSERTMSGLINE(356, buffer, "AMPush(): Memory allocation failure.\n"); + + ret_val = __AMPushBuffered(path, buffer, buffer_length, NULL, FALSE); + OSFree(buffer); + return ret_val; + } else { +#ifdef DEBUG + OSReport("AMPush(): WARNING: File has zero length.\n"); +#endif + return 0; + } +} + +u32 AMPushData(void* buffer, u32 length) { + BOOL old; + u32 round_length; + AMReadInfo* ptr; + + ASSERTMSGLINE(401, ((u32)buffer & 0x1F) == 0, "AMPushData(): buffer is not 32-byte aligned!\n"); + ASSERTLINE(404, length); + + round_length = OSRoundUp32B(length); + if (__AMFreeBytes >= round_length && __AMStackLocation < AM_STACK_ENTRIES - 1) { + ptr = &__AMReadInfo[__AMStackLocation]; + + old = OSDisableInterrupts(); + + ptr->aram_start_addr = __AMStackPointer[__AMStackLocation]; + __AMStackLocation++; + __AMStackPointer[__AMStackLocation] = ptr->aram_start_addr + round_length; + __AMFreeBytes -= round_length; + + ptr->poll_flag = 0; + + ARQPostRequest(&ptr->arq_handle, __AMStackLocation - 1, 0, 1, (u32)buffer, ptr->aram_start_addr, round_length, &__AM_arq_poll_callback); + + OSRestoreInterrupts(old); + + do {} while (!ptr->poll_flag); + + return ptr->aram_start_addr; + } + + return 0; +} + +u32 __AMPushBuffered(char* path, void* buffer, u32 buffer_size, AMCallback callback, int async_flag) { + BOOL old; + u32 round_file_length; + u32 stack_index; + AMReadInfo* ptr; + u32 remainder; + u32 read_request_length; + s32 actual_read_length; + + ASSERTMSGLINE(477, ((u32)buffer & 0x1F) == 0, "AMPushBuffered(): buffer is not 32-byte aligned!\n"); + ASSERTMSGLINE(480, buffer_size > 31, "AMPushBuffered(): buffer_size is less than 32 bytes!\n"); + + if (__AMStackLocation < AM_STACK_ENTRIES - 1) { + ptr = &__AMReadInfo[__AMStackLocation]; + stack_index = __AMStackLocation; + + if (!DVDOpen(path, &ptr->file_handle)) { + OSReport("AMPushBuffered(): Unable to open file '%s'\n", path); + OSPanic(__FILE__, 494, "AM: FATAL ERROR\n"); + } + + ptr->file_length = ptr->file_handle.length; + round_file_length = OSRoundUp32B(ptr->file_length); + + if (__AMFreeBytes >= round_file_length) { + ptr->aram_start_addr = __AMStackPointer[__AMStackLocation]; + + old = OSDisableInterrupts(); + + __AMStackLocation++; + __AMStackPointer[__AMStackLocation] = ptr->aram_start_addr + round_file_length; + __AMFreeBytes -= round_file_length; + + ptr->curr_read_offset = 0; + ptr->curr_aram_offset = ptr->aram_start_addr; + ptr->read_length = buffer_size & ~0x1F; + ptr->callback = callback; + ptr->path = path; + ptr->buffer = buffer; + + OSRestoreInterrupts(old); + + if (async_flag == 1) { + DVDReadAsync(&ptr->file_handle, ptr->buffer, ptr->read_length, 0, __AM_dvd_callback); + __AMPendingReads++; + } else { + while (ptr->curr_read_offset < ptr->file_length) { + remainder = ptr->file_length - ptr->curr_read_offset; + read_request_length = OSRoundUp32B(ptr->read_length > remainder ? remainder : ptr->read_length); + actual_read_length = DVDReadPrio(&ptr->file_handle, ptr->buffer, read_request_length, ptr->curr_read_offset, 2); + + ASSERTMSGLINE(558, actual_read_length > 0, "AMPushBuffered(): Fatal Error - synchronuous DVD read\n"); + + ptr->curr_read_offset += actual_read_length; + ptr->poll_flag = FALSE; + + ARQPostRequest(&(ptr->arq_handle), stack_index, 0, 1, (u32)ptr->buffer, ptr->curr_aram_offset, actual_read_length, __AM_arq_poll_callback); + + ptr->curr_aram_offset += (u32)(actual_read_length); + + do {} while (!ptr->poll_flag); + } + } + } else { +#ifdef DEBUG + OSReport("AMPushBuffered(): WARNING: Not enough space in ARAM.\n"); +#endif + return 0; + } + } else { +#ifdef DEBUG + OSReport("AMPushBuffered(): WARNING: Stack table is full.\n"); +#endif + return 0; + } + + return ptr->aram_start_addr; +} + +void AMPop(void) { + BOOL old; + old = OSDisableInterrupts(); + + if (__AMPendingReads == 0) { + if (__AMStackLocation > 1) { + __AMFreeBytes += __AMStackPointer[__AMStackLocation] - __AMStackPointer[__AMStackLocation - 1]; + __AMStackLocation--; + } + } + + OSRestoreInterrupts(old); +} + +u32 AMGetZeroBuffer(void) { + return __AMStackPointer[0]; +} + +u32 AMGetReadStatus(void) { + BOOL old; + u32 tmp; + + old = OSDisableInterrupts(); + tmp = __AMPendingReads; + + OSRestoreInterrupts(old); + return tmp; +} + +u32 AMGetFreeSize(void) { + BOOL old; + u32 tmp; + + old = OSDisableInterrupts(); + tmp = __AMFreeBytes; + + OSRestoreInterrupts(old); + return tmp; +} + +u32 AMGetStackPointer(void) { + BOOL old; + u32 tmp; + + old = OSDisableInterrupts(); + tmp = __AMStackPointer[__AMStackLocation]; + + OSRestoreInterrupts(old); + return tmp; +} + +void AMInit(u32 aramBase, u32 aramBytes) { + u32 i; + u8 __AMZeroBuffer[256 + 31]; + u8* ptr; + + ASSERTLINE(760, aramBytes); + + ptr = (u8*)OSRoundUp32B(__AMZeroBuffer); + + __AMStackLocation = 0; + __AMStackPointer[0] = aramBase; + __AMFreeBytes = aramBytes; + __AMPendingReads = 0; + + for (i = 0; i < 256; i++) { + ptr[i] = 0; + } + + AMPushData(ptr, 256); +} diff --git a/src/dolphin/amcnotstub/src/amcnotstub.c b/src/dolphin/amcnotstub/src/amcnotstub.c new file mode 100644 index 0000000..f1a59e7 --- /dev/null +++ b/src/dolphin/amcnotstub/src/amcnotstub.c @@ -0,0 +1,8 @@ +#include + +// this file is a stub. +__declspec(weak) int AMC_IsStub(void); + +__declspec(weak) int AMC_IsStub(void) { + return 0; +} diff --git a/src/dolphin/amcstubs/src/AmcExi2Stubs.c b/src/dolphin/amcstubs/src/AmcExi2Stubs.c new file mode 100644 index 0000000..99073a3 --- /dev/null +++ b/src/dolphin/amcstubs/src/AmcExi2Stubs.c @@ -0,0 +1,29 @@ +#include +#include + +// prototypes +int AMC_IsStub(void); + +void EXI2_Init(volatile unsigned char **inputPendingPtrRef, EXICallback monitorCallback) {} + +void EXI2_EnableInterrupts(void) {} + +int EXI2_Poll(void) { + return 0; +} + +AmcExiError EXI2_ReadN(void *bytes, unsigned long length) { + return AMC_EXI_NO_ERROR; +} + +AmcExiError EXI2_WriteN(const void *bytes, unsigned long length) { + return AMC_EXI_NO_ERROR; +} + +void EXI2_Reserve(void) {} + +void EXI2_Unreserve(void) {} + +int AMC_IsStub(void) { + return 1; +} diff --git a/src/dolphin/ar/src/__ar.h b/src/dolphin/ar/src/__ar.h new file mode 100644 index 0000000..8cab34c --- /dev/null +++ b/src/dolphin/ar/src/__ar.h @@ -0,0 +1,24 @@ +#ifndef _DOLPHIN_AR_INTERNAL_H_ +#define _DOLPHIN_AR_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __ARClearInterrupt(void); +u16 __ARGetInterruptStatus(void); + +void __ARQPopTaskQueueHi(void); +void __ARQServiceQueueLo(void); +void __ARQCallbackHack(u32 pointerToARQRequest); +void __ARQInterruptServiceRoutine(void); +void __ARQInitTempQueue(void); +void __ARQPushTempQueue(ARQRequest* task); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AR_INTERNAL_H_ diff --git a/src/dolphin/ar/src/ar.c b/src/dolphin/ar/src/ar.c new file mode 100644 index 0000000..d431eeb --- /dev/null +++ b/src/dolphin/ar/src/ar.c @@ -0,0 +1,446 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__ar.h" + +#ifdef DEBUG +const char* __ARVersion = "<< Dolphin SDK - AR\tdebug build: Apr 5 2004 03:56:19 (0x2301) >>"; +#else +const char* __ARVersion = "<< Dolphin SDK - AR\trelease build: Apr 5 2004 04:15:03 (0x2301) >>"; +#endif + +static void (*__AR_Callback)(); +static u32 __AR_Size; +static u32 __AR_InternalSize; +static u32 __AR_ExpansionSize; +static u32 __AR_StackPointer; +static u32 __AR_FreeBlocks; +static u32* __AR_BlockLength; +static BOOL __AR_init_flag; + +// prototypes +static void __ARHandler(__OSInterrupt exception, OSContext* context); +static void __ARWaitForDMA(void); +static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length); +static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length); +static void __ARChecksize(void); +static void __ARClearArea(u32 start_addr, u32 length); + +ARQCallback ARRegisterDMACallback(ARQCallback callback) { + ARQCallback old_callback; + BOOL old; + + old_callback = __AR_Callback; + old = OSDisableInterrupts(); + __AR_Callback = callback; + OSRestoreInterrupts(old); + return old_callback; +} + +u32 ARGetDMAStatus(void) { + BOOL old; + u32 val; + + old = OSDisableInterrupts(); + val = __DSPRegs[5] & 0x200; + OSRestoreInterrupts(old); + return val; +} + +void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) { + BOOL old; + + old = OSDisableInterrupts(); + ASSERTMSGLINE(376, !(__DSPRegs[5] & 0x200), "ARAM DMA already in progress\n"); + ASSERTMSGLINE(377, !(mainmem_addr & 0x1F), "AR: Main memory address is not a multiple of 32 bytes!\n"); + ASSERTMSGLINE(378, !(length & 0x1F), "AR: DMA transfer length is not a multiple of 32 bytes!\n"); + __DSPRegs[16] = (__DSPRegs[16] & 0xFFFFFC00 | (mainmem_addr >> 0x10)); + __DSPRegs[17] = (__DSPRegs[17] & 0xFFFF001F | ((u16)mainmem_addr)); + __DSPRegs[18] = (__DSPRegs[18] & 0xFFFFFC00 | (aram_addr >> 0x10)); + __DSPRegs[19] = (__DSPRegs[19] & 0xFFFF001F | ((u16)aram_addr)); + __DSPRegs[20] = __DSPRegs[20] & ~0x8000 | ((type << 0xF) & ~0x7FFF); + __DSPRegs[20] = (__DSPRegs[20] & 0xFFFFFC00) | (length >> 0x10); + __DSPRegs[21] = (__DSPRegs[21] & 0xFFFF001F) | (length & 0x0000FFFF); + OSRestoreInterrupts(old); +} + +u32 ARAlloc(u32 length) { + u32 tmp; + BOOL old; + + old = OSDisableInterrupts(); + ASSERTMSGLINE(430, !(length & 0x1F), "ARAlloc(): length is not multiple of 32bytes!"); + ASSERTMSGLINE(434, length <= (__AR_Size - __AR_StackPointer), "ARAlloc(): Out of ARAM!"); + ASSERTMSGLINE(435, __AR_FreeBlocks, "ARAlloc(): No more free blocks!"); + + tmp = __AR_StackPointer; + __AR_StackPointer += length; + *__AR_BlockLength = length; + __AR_BlockLength += 1; + __AR_FreeBlocks -= 1; + OSRestoreInterrupts(old); + return tmp; +} + +u32 ARFree(u32* length) { + BOOL old; + + old = OSDisableInterrupts(); + __AR_BlockLength -= 1; + if (length) { + *length = *__AR_BlockLength; + } + __AR_StackPointer -= *__AR_BlockLength; + __AR_FreeBlocks += 1; + OSRestoreInterrupts(old); + return __AR_StackPointer; +} + +BOOL ARCheckInit(void) { + return __AR_init_flag; +} + +u32 ARInit(u32* stack_index_addr, u32 num_entries) { + BOOL old; + u16 refresh; + + if (__AR_init_flag == TRUE) { + return 0x4000; + } + + OSRegisterVersion(__ARVersion); + + old = OSDisableInterrupts(); + __AR_Callback = NULL; + __OSSetInterruptHandler(6, __ARHandler); + __OSUnmaskInterrupts(0x02000000); + __AR_StackPointer = 0x4000; + __AR_FreeBlocks = num_entries; + __AR_BlockLength = stack_index_addr; + refresh = __DSPRegs[13] & 0xFF; + + ASSERTMSGLINE(590, (refresh <= 196.0f), "ARInit(): ILLEGAL SDRAM REFRESH VALUE\n"); + __DSPRegs[13] = (u16)((__DSPRegs[13] & ~0xFF) | (refresh & 0xFF)); + + __ARChecksize(); + __AR_init_flag = TRUE; + OSRestoreInterrupts(old); + return __AR_StackPointer; +} + +void ARReset(void) { + __AR_init_flag = FALSE; +} + +void ARSetSize(void) { +#ifdef DEBUG + OSReport("ARSetSize(): I don't do anything anymore!\n"); +#endif +} + +u32 ARGetBaseAddress(void) { + return 0x4000; +} + +u32 ARGetSize(void) { + return __AR_Size; +} + +u32 ARGetInternalSize(void) { + return __AR_InternalSize; +} + +void ARClear(u32 flag) { + switch (flag) { + case 0: + if (__AR_InternalSize != 0) { + __ARClearArea(0, __AR_InternalSize); + } + return; + case 1: + if (__AR_InternalSize != 0) { + __ARClearArea(0x4000, __AR_InternalSize - 0x4000); + } + break; + case 2: + if (__AR_InternalSize != 0 && __AR_ExpansionSize != 0) { + __ARClearArea(__AR_InternalSize, __AR_ExpansionSize); + } + break; + default: + ASSERTMSGLINE(774, 0, "ARClear(): Unknown flag.\n"); + break; + } +} + +static void __ARHandler(__OSInterrupt exception, OSContext* context) { + OSContext exceptionContext; + u16 tmp; + + tmp = __DSPRegs[5]; + tmp = (tmp & ~0x88) | 0x20; + __DSPRegs[5] = (tmp); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + if (__AR_Callback) { + __AR_Callback(); + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +void __ARClearInterrupt(void) { + u16 tmp; + + tmp = __DSPRegs[5]; + tmp = (tmp & ~0x88) | 0x20; + __DSPRegs[5] = (tmp); +} + +u16 __ARGetInterruptStatus(void) { + return __DSPRegs[5] & 0x20; +} + +static void __ARWaitForDMA(void) { + while (__DSPRegs[5] & 0x200); +} + +static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) { + // Main mem address + __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + // ARAM address + __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + // DMA buffer size + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x8000); + + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff)); + + __ARWaitForDMA(); + __ARClearInterrupt(); +} + +static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) { + // Main mem address + __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + // ARAM address + __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + // DMA buffer size + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] | 0x8000); + + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff)); + + __ARWaitForDMA(); + __ARClearInterrupt(); +} + +static void __ARChecksize(void) { + u8 test_data_pad[63]; + u8 dummy_data_pad[63]; + u8 buffer_pad[63]; + u8 save_pad_1[63]; + u8 save_pad_2[63]; + u8 save_pad_3[63]; + u8 save_pad_4[63]; + u8 save_pad_5[63]; + u32* test_data; + u32* dummy_data; + u32* buffer; + u32* save1; + u32* save2; + u32* save3; + u32* save4; + u32* save5; + u16 ARAM_mode = 0; + u32 ARAM_size = 0; + u32 i; + + do {} while(!(__DSPRegs[11] & 1)); + + ARAM_mode = 3; + ARAM_size = __AR_InternalSize = 0x1000000; + __DSPRegs[9] = ((__DSPRegs[9] & 0xFFFFFFC0) | 3) | 0x20; + + test_data = (u32*)(OSRoundUp32B((u32)(test_data_pad))); + dummy_data = (u32*)(OSRoundUp32B((u32)(dummy_data_pad))); + buffer = (u32*)(OSRoundUp32B((u32)(buffer_pad))); + + save1 = (u32*)(OSRoundUp32B((u32)(save_pad_1))); + save2 = (u32*)(OSRoundUp32B((u32)(save_pad_2))); + save3 = (u32*)(OSRoundUp32B((u32)(save_pad_3))); + save4 = (u32*)(OSRoundUp32B((u32)(save_pad_4))); + save5 = (u32*)(OSRoundUp32B((u32)(save_pad_5))); + + for (i = 0; i < 8; i++) { + *(test_data + i) = 0xDEADBEEF; + *(dummy_data + i) = 0xBAD0BAD0; + } + + DCFlushRange((void*)test_data, 0x20); + DCFlushRange((void*)dummy_data, 0x20); + + __AR_ExpansionSize = 0; + + DCInvalidateRange((void*)save1, 0x20); + __ARReadDMA((u32)save1, ARAM_size + 0, 0x20); + PPCSync(); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + DCInvalidateRange((void*)save2, 0x20); + __ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save3, 0x20); + __ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save4, 0x20); + __ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save5, 0x20); + __ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + + ARAM_mode |= 0 << 1; + ARAM_size += 0x0200000; + __AR_ExpansionSize = 0x0200000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + + ARAM_mode |= 4 << 1; + ARAM_size += 0x0400000; + __AR_ExpansionSize = 0x0400000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20); + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + + ARAM_mode |= 8 << 1; + ARAM_size += 0x0800000; + __AR_ExpansionSize = 0x0800000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + + ARAM_mode |= 12 << 1; + ARAM_size += 0x1000000; + __AR_ExpansionSize = 0x1000000; + } else { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + __ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + + ARAM_mode |= 16 << 1; + ARAM_size += 0x2000000; + __AR_ExpansionSize = 0x2000000; + } + } + } + } + +#ifdef DEBUG + OSReport("__ARChecksize(): ARAM Expansion present.\n"); +#endif + __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x07 | 0x38)) | ARAM_mode); + } + + *(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size; + __AR_Size = ARAM_size; +} + +static void __ARClearArea(u32 start_addr, u32 length) { + u8 zero_buffer[2079]; + u8* ptr; + u32 curr_addr; + u32 curr_len; + u32 end_addr; + u32 remainder; + + ASSERTMSGLINE(0x529, !(start_addr & 0x1F), "__ARClearArea(): Destination address not 32-byte aligned.\n"); + ASSERTMSGLINE(0x52A, !(length & 0x1F), "__ARClearArea(): Length not multiple of 32 bytes.\n"); + + ptr = (u8*)(OSRoundUp32B((u32)(zero_buffer))); + + do {} while(!(__DSPRegs[11] & 1)); + + memset(ptr, 0, 0x800); + DCFlushRange(ptr, 0x800); + + curr_addr = start_addr; + end_addr = start_addr + length; + + while (curr_addr < end_addr) { + remainder = end_addr - curr_addr; + + curr_len = OSRoundUp32B(remainder < 0x800 ? remainder : 0x800); + __ARWriteDMA((u32)ptr, curr_addr, curr_len); + curr_addr += curr_len; + } +} diff --git a/src/dolphin/ar/src/arq.c b/src/dolphin/ar/src/arq.c new file mode 100644 index 0000000..1adf24b --- /dev/null +++ b/src/dolphin/ar/src/arq.c @@ -0,0 +1,253 @@ +#include +#include + +#include "__ar.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 5 2004 04:15:04 (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 __ARQPopTaskQueueHi(void) { + 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; + } +} + +void __ARQServiceQueueLo(void) { + if (__ARQRequestPendingLo == 0 && __ARQRequestQueueLo) { + __ARQRequestPendingLo = __ARQRequestQueueLo; + __ARQRequestQueueLo = __ARQRequestQueueLo->next; + } + + if (__ARQRequestPendingLo) { + if (__ARQRequestPendingLo->length <= __ARQChunkSize) { + if (__ARQRequestPendingLo->type == 0) { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->length); + } else { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQRequestPendingLo->length); + } + __ARQCallbackLo = __ARQRequestPendingLo->callback; + } else if (__ARQRequestPendingLo->type == 0) { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQChunkSize); + } else { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQChunkSize); + } + + __ARQRequestPendingLo->length -= __ARQChunkSize; + __ARQRequestPendingLo->source += __ARQChunkSize; + __ARQRequestPendingLo->dest += __ARQChunkSize; + } +} + +void __ARQCallbackHack(u32 unused) {} + +void __ARQInterruptServiceRoutine() { + if (__ARQCallbackHi) { + __ARQCallbackHi((u32)__ARQRequestPendingHi); + __ARQRequestPendingHi = NULL; + __ARQCallbackHi = NULL; + } else if (__ARQCallbackLo) { + __ARQCallbackLo((u32)__ARQRequestPendingLo); + __ARQRequestPendingLo = NULL; + __ARQCallbackLo = NULL; + } + + __ARQPopTaskQueueHi(); + + if (__ARQRequestPendingHi == 0) { + __ARQServiceQueueLo(); + } +} + +void __ARQInitTempQueue(void) { + __ARQRequestQueueTemp = NULL; + __ARQRequestTailTemp = NULL; +} + +void __ARQPushTempQueue(ARQRequest* task) { + if (!__ARQRequestQueueTemp) { + __ARQRequestQueueTemp = task; + __ARQRequestTailTemp = task; + } else { + __ARQRequestTailTemp->next = task; + __ARQRequestTailTemp = task; + } +} + +void ARQInit(void) { + if (__ARQ_init_flag != TRUE) { + OSRegisterVersion(__ARQVersion); + + __ARQRequestQueueHi = __ARQRequestQueueLo = NULL; + __ARQChunkSize = 0x1000; + ARRegisterDMACallback(__ARQInterruptServiceRoutine); + __ARQRequestPendingHi = NULL; + __ARQRequestPendingLo = NULL; + __ARQCallbackHi = NULL; + __ARQCallbackLo = NULL; + __ARQ_init_flag = TRUE; + } +} + +void ARQReset(void) { + __ARQ_init_flag = FALSE; +} + +void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest, u32 length, ARQCallback callback) { + BOOL level; + + ASSERTLINE(437, request); + ASSERTLINE(438, (type == ARQ_TYPE_MRAM_TO_ARAM) || (type == ARQ_TYPE_ARAM_TO_MRAM)); + ASSERTLINE(439, (priority == ARQ_PRIORITY_LOW) || (priority == ARQ_PRIORITY_HIGH)); + ASSERTLINE(442, (length % ARQ_DMA_ALIGNMENT) == 0); + + request->next = NULL; + request->owner = owner; + request->type = type; + request->source = source; + request->dest = dest; + request->length = length; + if (callback) { + request->callback = callback; + } else { + request->callback = __ARQCallbackHack; + } + + level = OSDisableInterrupts(); + switch(priority) { + case ARQ_PRIORITY_LOW: + if (__ARQRequestQueueLo) { + __ARQRequestTailLo->next = request; + } else { + __ARQRequestQueueLo = request; + } + __ARQRequestTailLo = request; + break; + case ARQ_PRIORITY_HIGH: + if (__ARQRequestQueueHi) { + __ARQRequestTailHi->next = request; + } else { + __ARQRequestQueueHi = request; + } + __ARQRequestTailHi = request; + break; + } + + if ((__ARQRequestPendingHi == 0) && ( __ARQRequestPendingLo == 0)) { + __ARQPopTaskQueueHi(); + if ( __ARQRequestPendingHi == 0) { + __ARQServiceQueueLo(); + } + } + + OSRestoreInterrupts(level); +} + +void ARQRemoveRequest(ARQRequest* request) { + ARQRequest* thisRequest; + BOOL level; + + level = OSDisableInterrupts(); + __ARQInitTempQueue(); + + for (thisRequest = __ARQRequestQueueHi; thisRequest; thisRequest = thisRequest->next) { + if (thisRequest != request) { + __ARQPushTempQueue(thisRequest); + } + } + + __ARQRequestQueueHi = __ARQRequestQueueTemp; + __ARQRequestTailHi = __ARQRequestTailTemp; + __ARQInitTempQueue(); + + for (thisRequest = __ARQRequestQueueLo; thisRequest; thisRequest = thisRequest->next) { + if (thisRequest != request) { + __ARQPushTempQueue(thisRequest); + } + } + + __ARQRequestQueueLo = __ARQRequestQueueTemp; + __ARQRequestTailLo = __ARQRequestTailTemp; + OSRestoreInterrupts(level); +} + +void ARQRemoveOwnerRequest(u32 owner) { + ARQRequest* thisRequest; + BOOL level; + + level = OSDisableInterrupts(); + __ARQInitTempQueue(); + + for (thisRequest = __ARQRequestQueueHi; thisRequest; thisRequest = thisRequest->next) { + if (thisRequest->owner != owner) { + __ARQPushTempQueue(thisRequest); + } + } + + __ARQRequestQueueHi = __ARQRequestQueueTemp; + __ARQRequestTailHi = __ARQRequestTailTemp; + __ARQInitTempQueue(); + + for (thisRequest = __ARQRequestQueueLo; thisRequest; thisRequest = thisRequest->next) { + if (thisRequest->owner != owner) { + __ARQPushTempQueue(thisRequest); + } + } + + __ARQRequestQueueLo = __ARQRequestQueueTemp; + __ARQRequestTailLo = __ARQRequestTailTemp; + OSRestoreInterrupts(level); +} + +void ARQFlushQueue(void) { + BOOL level; + + level = OSDisableInterrupts(); + __ARQRequestQueueHi = NULL; + __ARQRequestTailHi = NULL; + __ARQRequestQueueLo = NULL; + __ARQRequestTailLo = NULL; + + OSRestoreInterrupts(level); +} + +void ARQSetChunkSize(u32 size) { + u32 i; + + i = size & 0x1F; + if (i) { + __ARQChunkSize = size + (0x20 - i); + return; + } + __ARQChunkSize = size; +} + +u32 ARQGetChunkSize(void) { + return __ARQChunkSize; +} + +BOOL ARQCheckInit(void) { + return __ARQ_init_flag; +} diff --git a/src/dolphin/ax/src/AX.c b/src/dolphin/ax/src/AX.c new file mode 100644 index 0000000..bc57946 --- /dev/null +++ b/src/dolphin/ax/src/AX.c @@ -0,0 +1,40 @@ +#include +#include + +#include "__ax.h" + +#ifdef DEBUG +const char* __AXVersion = "<< Dolphin SDK - AX\tdebug build: Apr 5 2004 03:56:21 (0x2301) >>"; +#else +const char* __AXVersion = "<< Dolphin SDK - AX\trelease build: Apr 5 2004 04:15:05 (0x2301) >>"; +#endif + +void AXInit(void) { + AXInitEx(0); +} + +void AXInitEx(u32 outputBufferMode) { +#ifdef DEBUG + OSReport("Initializing AX\n"); +#endif + OSRegisterVersion(__AXVersion); + + __AXAllocInit(); + __AXVPBInit(); + __AXSPBInit(); + __AXAuxInit(); + __AXClInit(); + __AXOutInit(outputBufferMode); +} + +void AXQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AX\n"); +#endif + __AXAllocQuit(); + __AXVPBQuit(); + __AXSPBQuit(); + __AXAuxQuit(); + __AXClQuit(); + __AXOutQuit(); +} diff --git a/src/dolphin/ax/src/AXAlloc.c b/src/dolphin/ax/src/AXAlloc.c new file mode 100644 index 0000000..66b3f03 --- /dev/null +++ b/src/dolphin/ax/src/AXAlloc.c @@ -0,0 +1,248 @@ +#include +#include + +#include "__ax.h" + +static AXVPB* __AXStackHead[AX_PRIORITY_STACKS]; +static AXVPB* __AXStackTail[AX_PRIORITY_STACKS]; + +static AXVPB* __AXCallbackStack; + +static u32 __AXCheckStacks(void) { + u32 i; + u32 voices; + AXVPB* voice; + + voices = 0; + for (i = 0; i < 32; i++) { + voice = __AXStackHead[i]; + while (voice != 0) { + voices++; + if (voices > 64) { + return 0; + } + + voice = voice->next; + } + } + + return 1; +} + +AXVPB* __AXGetStackHead(u32 priority) { + ASSERTLINE(97, priority < AX_PRIORITY_STACKS); + return __AXStackHead[priority]; +} + +void __AXServiceCallbackStack(void) { + AXVPB* p; + + for (p = __AXPopCallbackStack(); p; p = __AXPopCallbackStack()) { + if (p->priority != 0) { + if (p->callback) { + p->callback(p); + } + + __AXRemoveFromStack(p); + __AXPushFreeStack(p); + } + } +} + +void __AXInitVoiceStacks(void) { + u32 i; + + __AXCallbackStack = NULL; + for (i = 0; i < AX_PRIORITY_STACKS; i++) { + __AXStackHead[i] = __AXStackTail[i] = 0; + } +} + +void __AXAllocInit(void) { +#ifdef DEBUG + OSReport("Initializing AXAlloc code module\n"); +#endif + __AXInitVoiceStacks(); +} + +void __AXAllocQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXAlloc code module\n"); +#endif + __AXInitVoiceStacks(); +} + +void __AXPushFreeStack(AXVPB* p) { + ASSERTLINE(168, p->priority); + p->next = __AXStackHead[0]; + __AXStackHead[0] = p; + p->priority = 0; +} + +AXVPB* __AXPopFreeStack(void) { + AXVPB* p; + + p = (void*)(u32)&__AXStackHead[0]->next; + if (p) { + __AXStackHead[0] = p->next; + } + return p; +} + +void __AXPushCallbackStack(AXVPB* p) { + p->next1 = __AXCallbackStack; + __AXCallbackStack = p; +} + +AXVPB* __AXPopCallbackStack(void) { + AXVPB* p; + + p = (void*)(u32)&__AXCallbackStack[0]; + if (p) { + __AXCallbackStack = p->next1; + } + return p; +} + +void __AXRemoveFromStack(AXVPB* p) { + u32 i; + AXVPB* head; + AXVPB* tail; + + ASSERTLINE(219, p->priority); + + i = p->priority; + head = __AXStackHead[i]; + tail = __AXStackTail[i]; + if (head == tail) { + __AXStackHead[i] = __AXStackTail[i] = 0; + return; + } + + if (p == head) { + __AXStackHead[i] = p->next; + __AXStackHead[i]->prev = 0; + return; + } + + if (p == tail) { + __AXStackTail[i] = p->prev; + __AXStackTail[i]->next = 0; + return; + } + + head = p->prev; + tail = p->next; + head->next = tail; + tail->prev = head; +} + +void __AXPushStackHead(AXVPB* p, u32 priority) { + ASSERTLINE(261, priority); + ASSERTLINE(262, priority < AX_PRIORITY_STACKS); + + p->next = __AXStackHead[priority]; + p->prev = 0; + + if (p->next) { + __AXStackHead[priority]->prev = p; + __AXStackHead[priority] = p; + } else { + __AXStackTail[priority] = p; + __AXStackHead[priority] = p; + } + + p->priority = priority; +} + +AXVPB* __AXPopStackFromBottom(u32 priority) { + AXVPB* p; + + ASSERTLINE(287, priority); + ASSERTLINE(288, priority < AX_PRIORITY_STACKS); + + p = NULL; + if (__AXStackHead[priority]) { + if (__AXStackHead[priority] == __AXStackTail[priority]) { + p = __AXStackHead[priority]; + __AXStackHead[priority] = __AXStackTail[priority] = 0; + } else if (__AXStackTail[priority]) { + p = __AXStackTail[priority]; + __AXStackTail[priority] = p->prev; + __AXStackTail[priority]->next = 0; + } + } + + return p; +} + +void AXFreeVoice(AXVPB* p) { + BOOL old; + + ASSERTLINE(322, p); + ASSERTMSGLINE(326, p->priority != 0, "Calling AXFreeVoice() for voice that is already free\n"); + + old = OSDisableInterrupts(); + __AXRemoveFromStack(p); + if (p->pb.state == 1) { + p->depop = 1; + } + __AXSetPBDefault(p); + __AXPushFreeStack(p); + + ASSERTMSGLINE(343, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); +} + +AXVPB* AXAcquireVoice(u32 priority, void (*callback)(void*), u32 userContext) { + BOOL old; + AXVPB* p; + u32 i; + + ASSERTLINE(361, priority); + ASSERTLINE(362, priority < AX_PRIORITY_STACKS); + + old = OSDisableInterrupts(); + p = __AXPopFreeStack(); + if (p == 0) { + for (i = 1; i < priority; i++) { + p = __AXPopStackFromBottom(i); + if (p) { + if (p->pb.state == 1) { + p->depop = 1; + } + if (p->callback != 0) { + p->callback(p); + } + break; + } + } + } + + if (p) { + __AXPushStackHead(p, priority); + p->callback = callback; + p->userContext = userContext; + __AXSetPBDefault(p); + } + + ASSERTMSGLINE(410, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); + return p; +} + +void AXSetVoicePriority(AXVPB* p, u32 priority) { + BOOL old; + + ASSERTLINE(424, p); + ASSERTMSGLINE(428, p->priority != 0, "Calling AXSetVoicePriority() for voice that is already free\n"); + ASSERTMSGLINE(433, priority, "Do not set voice priority to 0, use AXFreeVoice() to free voice\n"); + ASSERTLINE(435, priority < AX_PRIORITY_STACKS); + + old = OSDisableInterrupts(); + __AXRemoveFromStack(p); + __AXPushStackHead(p, priority); + + ASSERTMSGLINE(442, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); +} diff --git a/src/dolphin/ax/src/AXAux.c b/src/dolphin/ax/src/AXAux.c new file mode 100644 index 0000000..094dac4 --- /dev/null +++ b/src/dolphin/ax/src/AXAux.c @@ -0,0 +1,167 @@ +#include +#include + +#include "__ax.h" + +static s32 __AXBufferAuxA[3][480] ATTRIBUTE_ALIGN(32); +static s32 __AXBufferAuxB[3][480] ATTRIBUTE_ALIGN(32); + +static void (* __AXCallbackAuxA)(void*, void*); +static void (* __AXCallbackAuxB)(void*, void*); +static void* __AXContextAuxA; +static void* __AXContextAuxB; +static s32* __AXAuxADspWrite; +static s32* __AXAuxADspRead; +static s32* __AXAuxBDspWrite; +static s32* __AXAuxBDspRead; +static u32 __AXAuxDspWritePosition; +static u32 __AXAuxDspReadPosition; +static u32 __AXAuxDspWritePositionDpl2; +static u32 __AXAuxDspReadPositionDpl2; +static u32 __AXAuxCpuReadWritePosition; + +void __AXAuxInit(void) { + int i; + s32* pA; + s32* pB; + +#ifdef DEBUG + OSReport("Initializing AXAux code module\n"); +#endif + __AXCallbackAuxA = NULL; + __AXCallbackAuxB = NULL; + __AXContextAuxA = 0; + __AXContextAuxB = 0; + __AXAuxDspWritePosition = 0; + __AXAuxDspReadPosition = 1; + __AXAuxDspWritePositionDpl2 = 0; + __AXAuxDspReadPositionDpl2 = 1; + __AXAuxCpuReadWritePosition = 2; + + pA = (s32*)&__AXBufferAuxA; + pB = (s32*)&__AXBufferAuxB; + + for (i = 0; i < 480; i++) { + *(pA) = 0; pA++; + *(pB) = 0; pB++; + } +} + +void __AXAuxQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXAux code module\n"); +#endif + __AXCallbackAuxA = NULL; + __AXCallbackAuxB = NULL; +} + +void __AXGetAuxAInput(u32* p) { + if (__AXCallbackAuxA) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspWritePosition][0]; + } else { + *p = 0; + } +} + +void __AXGetAuxAInputDpl2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePosition][320]; +} + +void __AXGetAuxAOutput(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][0]; +} + +void __AXGetAuxAOutputDpl2R(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][160]; +} + +void __AXGetAuxAOutputDpl2Ls(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][320]; +} + +void __AXGetAuxAOutputDpl2Rs(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPosition][320]; +} + +void __AXGetAuxBInput(u32* p) { + if (__AXCallbackAuxB) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePosition][0]; + } else { + *p = 0; + } +} + +void __AXGetAuxBOutput(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPosition][0]; +} + +void __AXGetAuxBForDPL2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePositionDpl2][0]; +} + +void __AXGetAuxBOutputDPL2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPositionDpl2][0]; +} + +void __AXProcessAux(void) { + __AXAuxADspWrite = &__AXBufferAuxA[__AXAuxDspWritePosition][0]; + __AXAuxADspRead = &__AXBufferAuxA[__AXAuxDspReadPosition][0]; + __AXAuxBDspWrite = &__AXBufferAuxB[__AXAuxDspWritePosition][0]; + __AXAuxBDspRead = &__AXBufferAuxB[__AXAuxDspReadPosition][0]; + + if (__AXCallbackAuxA) { + if (__AXClMode == 2) { + AX_AUX_DATA_DPL2 auxData; + auxData.l = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][160]; + auxData.ls = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][320]; + auxData.rs = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + DCInvalidateRange(auxData.rs, 0x280); + __AXCallbackAuxA(&auxData.l, __AXContextAuxA); + DCFlushRangeNoSync(auxData.l, 0x780); + DCFlushRangeNoSync(auxData.rs, 0x280); + } else { + AX_AUX_DATA auxData; + auxData.l = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][160]; + auxData.s = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + __AXCallbackAuxA(&auxData.l, __AXContextAuxA); + DCFlushRangeNoSync(auxData.l, 0x780); + } + } + + if (__AXCallbackAuxB && __AXClMode != 2) { + AX_AUX_DATA auxData; + auxData.l = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][160]; + auxData.s = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + __AXCallbackAuxB(&auxData.l, __AXContextAuxB); + DCFlushRangeNoSync(auxData.l, 0x780); + } + + __AXAuxDspWritePosition += 1; + __AXAuxDspWritePosition %= 3; + __AXAuxDspReadPosition += 1; + __AXAuxDspReadPosition %= 3; + + __AXAuxDspWritePositionDpl2 += 1; + __AXAuxDspWritePositionDpl2 &= 1; + __AXAuxDspReadPositionDpl2 += 1; + __AXAuxDspReadPositionDpl2 &= 1; + + __AXAuxCpuReadWritePosition += 1; + __AXAuxCpuReadWritePosition %= 3; +} + +void AXRegisterAuxACallback(void (*callback)(void*, void*), void* context) { + __AXCallbackAuxA = callback; + __AXContextAuxA = context; +} + +void AXRegisterAuxBCallback(void (*callback)(void*, void*), void* context) { + __AXCallbackAuxB = callback; + __AXContextAuxB = context; +} diff --git a/src/dolphin/ax/src/AXCL.c b/src/dolphin/ax/src/AXCL.c new file mode 100644 index 0000000..05107a5 --- /dev/null +++ b/src/dolphin/ax/src/AXCL.c @@ -0,0 +1,176 @@ +#include +#include + +#include "__ax.h" + +static u16 __AXCommandList[2][384]; + +static u32 __AXCommandListPosition; +static u16* __AXClWrite; +static u32 __AXCommandListCycles; +static u32 __AXCompressor; +u32 __AXClMode; + +u32 __AXGetCommandListCycles(void) { + return __AXCommandListCycles; +} + +u32 __AXGetCommandListAddress(void) { + u32 address; + + address = (u32)&__AXCommandList[__AXCommandListPosition][0]; + __AXCommandListPosition += 1; + __AXCommandListPosition &= 1; + __AXClWrite = (void*)&__AXCommandList[__AXCommandListPosition][0]; + return address; +} + +void __AXWriteToCommandList(u16 data) { + *__AXClWrite = data; + __AXClWrite++; +} + +void __AXNextFrame(void* sbuffer, void* buffer) { + u32 data; + u16* pCommandList; + + __AXCommandListCycles = 0x1A9; + pCommandList = __AXClWrite; + data = __AXGetStudio(); + __AXWriteToCommandList(0); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)(data)); + __AXCommandListCycles += 0x2E44; + + switch (__AXClMode) { + case 0: + __AXWriteToCommandList(7); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXCommandListCycles += 0x546; + break; + case 1: + __AXWriteToCommandList(0x11); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXCommandListCycles += 0x5E6; + break; + case 2: + break; + default: + ASSERTMSGLINE(193, 0, "Unknown AX mode!"); + } + + data = (u32)__AXGetPBs(); + __AXWriteToCommandList(2); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXWriteToCommandList(3); + + if (__AXClMode == 2) { + __AXGetAuxAInput(&data); + if (data != 0) { + __AXWriteToCommandList(0x13); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAInputDpl2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutput(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2R(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2Ls(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2Rs(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } + __AXWriteToCommandList(0x10); + __AXGetAuxBForDPL2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxBOutputDPL2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } else { + __AXGetAuxAInput(&data); + + if (data != 0) { + __AXWriteToCommandList(4); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutput(&data); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } + + __AXGetAuxBInput(&data); + if (data != 0) { + __AXWriteToCommandList(5); + __AXCommandListCycles += 0xDED; + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXGetAuxBOutput(&data); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + } + } + + if (__AXCompressor) { + __AXWriteToCommandList(0x12); + __AXWriteToCommandList(0x8000); + __AXWriteToCommandList(0xA); + __AXWriteToCommandList((u32)__AXCompressorTable >> 0x10); + __AXWriteToCommandList((u32)__AXCompressorTable); + __AXCommandListCycles += 0xBB8; + } + + __AXWriteToCommandList(0xE); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXWriteToCommandList((u16)((u32)buffer >> 0x10)); + __AXWriteToCommandList((u32)buffer); + __AXCommandListCycles += 0x2710; + __AXWriteToCommandList(0xF); + __AXCommandListCycles += 2; + DCFlushRange(pCommandList, 0x300); +} + +void __AXClInit(void) { +#ifdef DEBUG + OSReport("Initializing AXCL code module\n"); +#endif + ASSERTLINE(338, ((u32)&__AXCommandList[0][0] & 0x1F) == 0); + ASSERTLINE(339, ((u32)&__AXCommandList[1][0] & 0x1F) == 0); + __AXClMode = 0; + __AXCommandListPosition = 0; + __AXClWrite = (void*)&__AXCommandList; + __AXCompressor = 1; +} + +void __AXClQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXCL code module\n"); +#endif +} + +void AXSetMode(u32 mode) { + if (__AXClMode != mode) { + __AXClMode = mode; + } +} + +u32 AXGetMode(void) { + return __AXClMode; +} + +void AXSetCompressor(u32 i) { + __AXCompressor = i; +} diff --git a/src/dolphin/ax/src/AXComp.c b/src/dolphin/ax/src/AXComp.c new file mode 100644 index 0000000..bc0eb97 --- /dev/null +++ b/src/dolphin/ax/src/AXComp.c @@ -0,0 +1,567 @@ +#include +#include + +#include "__ax.h" + +u16 __AXCompressorTable[3360] = { + 0x7FA1, 0x7F43, 0x7EE6, 0x7E88, 0x7E2B, 0x7DCE, + 0x7D72, 0x7D16, 0x7CBA, 0x7C5E, 0x7C02, 0x7BA7, + 0x7B4C, 0x7AF1, 0x7A97, 0x7A3D, 0x79E3, 0x7989, + 0x7930, 0x78D6, 0x787E, 0x7825, 0x77CD, 0x7774, + 0x771C, 0x76C5, 0x766D, 0x7616, 0x75BF, 0x7569, + 0x7512, 0x74BC, 0x7466, 0x7411, 0x73BB, 0x7366, + 0x7311, 0x72BD, 0x7268, 0x7214, 0x71C0, 0x716C, + 0x7119, 0x70C6, 0x7073, 0x7020, 0x6FCD, 0x6F7B, + 0x6F29, 0x6ED7, 0x6E86, 0x6E35, 0x6DE3, 0x6D93, + 0x6D42, 0x6CF2, 0x6CA1, 0x6C52, 0x6C02, 0x6BB2, + 0x6B63, 0x6B14, 0x6AC5, 0x6A77, 0x6A28, 0x69DA, + 0x698C, 0x693F, 0x68F1, 0x68A4, 0x6857, 0x680A, + 0x67BE, 0x6771, 0x6725, 0x66D9, 0x668E, 0x6642, + 0x65F7, 0x65AC, 0x6561, 0x6517, 0x64CC, 0x6482, + 0x6438, 0x63EE, 0x63A5, 0x635C, 0x6312, 0x62CA, + 0x6281, 0x6238, 0x61F0, 0x61A8, 0x6160, 0x6119, + 0x60D1, 0x608A, 0x6043, 0x5FFC, 0x5FB5, 0x5F6F, + 0x5F29, 0x5EE3, 0x5E9D, 0x5E57, 0x5E12, 0x5DCD, + 0x5D88, 0x5D43, 0x5CFE, 0x5CBA, 0x5C76, 0x5C32, + 0x5BEE, 0x5BAA, 0x5B67, 0x5B23, 0x5AE0, 0x5A9D, + 0x5A5B, 0x5A18, 0x59D6, 0x5994, 0x5952, 0x5910, + 0x58CF, 0x588D, 0x584C, 0x580B, 0x57CB, 0x578A, + 0x574A, 0x5709, 0x56C9, 0x5689, 0x564A, 0x560A, + 0x55CB, 0x558C, 0x554D, 0x550E, 0x54D0, 0x5491, + 0x5453, 0x5415, 0x53D7, 0x5399, 0x535C, 0x531E, + 0x52E1, 0x52A4, 0x5267, 0x522B, 0x51EE, 0x51B2, + 0x5176, 0x513A, 0x50FE, 0x50C3, 0x79EC, 0x799B, + 0x794A, 0x78FA, 0x78AA, 0x785A, 0x780A, 0x77BB, + 0x776C, 0x771C, 0x76CE, 0x767F, 0x7630, 0x75E2, + 0x7594, 0x7546, 0x74F9, 0x74AB, 0x745E, 0x7411, + 0x73C4, 0x7377, 0x732B, 0x72DE, 0x7292, 0x7246, + 0x71FB, 0x71AF, 0x7164, 0x7119, 0x70CE, 0x7083, + 0x7039, 0x6FEE, 0x6FA4, 0x6F5A, 0x6F11, 0x6EC7, + 0x6E7E, 0x6E35, 0x6DEC, 0x6DA3, 0x6D5A, 0x6D12, + 0x6CC9, 0x6C81, 0x6C3A, 0x6BF2, 0x6BAA, 0x6B63, + 0x6B1C, 0x6AD5, 0x6A8E, 0x6A48, 0x6A01, 0x69BB, + 0x6975, 0x692F, 0x68EA, 0x68A4, 0x685F, 0x681A, + 0x67D5, 0x6790, 0x674B, 0x6707, 0x66C3, 0x667F, + 0x663B, 0x65F7, 0x65B4, 0x6570, 0x652D, 0x64EA, + 0x64A7, 0x6464, 0x6422, 0x63E0, 0x639E, 0x635C, + 0x631A, 0x62D8, 0x6297, 0x6255, 0x6214, 0x61D3, + 0x6192, 0x6152, 0x6111, 0x60D1, 0x6091, 0x6051, + 0x6011, 0x5FD2, 0x5F92, 0x5F53, 0x5F14, 0x5ED5, + 0x5E96, 0x5E57, 0x5E19, 0x5DDB, 0x5D9C, 0x5D5E, + 0x5D21, 0x5CE3, 0x5CA5, 0x5C68, 0x5C2B, 0x5BEE, + 0x5BB1, 0x5B74, 0x5B38, 0x5AFB, 0x5ABF, 0x5A83, + 0x5A47, 0x5A0B, 0x59CF, 0x5994, 0x5959, 0x591D, + 0x58E2, 0x58A8, 0x586D, 0x5832, 0x57F8, 0x57BE, + 0x5783, 0x574A, 0x5710, 0x56D6, 0x569D, 0x5663, + 0x562A, 0x55F1, 0x55B8, 0x557F, 0x5547, 0x550E, + 0x54D6, 0x549E, 0x5466, 0x542E, 0x53F6, 0x53BE, + 0x5387, 0x534F, 0x5318, 0x52E1, 0x52AA, 0x5274, + 0x523D, 0x5207, 0x51D0, 0x519A, 0x5164, 0x512E, + 0x50F8, 0x50C3, 0x7478, 0x7433, 0x73EF, 0x73AA, + 0x7366, 0x7322, 0x72DE, 0x729B, 0x7257, 0x7214, + 0x71D1, 0x718E, 0x714B, 0x7108, 0x70C6, 0x7083, + 0x7041, 0x6FFF, 0x6FBD, 0x6F7B, 0x6F3A, 0x6EF8, + 0x6EB7, 0x6E76, 0x6E35, 0x6DF4, 0x6DB3, 0x6D72, + 0x6D32, 0x6CF2, 0x6CB1, 0x6C71, 0x6C32, 0x6BF2, + 0x6BB2, 0x6B73, 0x6B34, 0x6AF5, 0x6AB6, 0x6A77, + 0x6A38, 0x69FA, 0x69BB, 0x697D, 0x693F, 0x6901, + 0x68C3, 0x6885, 0x6848, 0x680A, 0x67CD, 0x6790, + 0x6753, 0x6716, 0x66D9, 0x669D, 0x6660, 0x6624, + 0x65E8, 0x65AC, 0x6570, 0x6534, 0x64F9, 0x64BD, + 0x6482, 0x6447, 0x640C, 0x63D1, 0x6396, 0x635C, + 0x6321, 0x62E7, 0x62AC, 0x6272, 0x6238, 0x61FF, + 0x61C5, 0x618B, 0x6152, 0x6119, 0x60DF, 0x60A6, + 0x606D, 0x6035, 0x5FFC, 0x5FC4, 0x5F8B, 0x5F53, + 0x5F1B, 0x5EE3, 0x5EAB, 0x5E73, 0x5E3C, 0x5E04, + 0x5DCD, 0x5D95, 0x5D5E, 0x5D27, 0x5CF1, 0x5CBA, + 0x5C83, 0x5C4D, 0x5C16, 0x5BE0, 0x5BAA, 0x5B74, + 0x5B3E, 0x5B09, 0x5AD3, 0x5A9D, 0x5A68, 0x5A33, + 0x59FE, 0x59C9, 0x5994, 0x595F, 0x592B, 0x58F6, + 0x58C2, 0x588D, 0x5859, 0x5825, 0x57F1, 0x57BE, + 0x578A, 0x5756, 0x5723, 0x56F0, 0x56BC, 0x5689, + 0x5656, 0x5624, 0x55F1, 0x55BE, 0x558C, 0x5559, + 0x5527, 0x54F5, 0x54C3, 0x5491, 0x545F, 0x542E, + 0x53FC, 0x53CB, 0x5399, 0x5368, 0x5337, 0x5306, + 0x52D5, 0x52A4, 0x5274, 0x5243, 0x5213, 0x51E2, + 0x51B2, 0x5182, 0x5152, 0x5122, 0x50F2, 0x50C3, + 0x6F42, 0x6F08, 0x6ECF, 0x6E96, 0x6E5D, 0x6E24, + 0x6DEC, 0x6DB3, 0x6D7A, 0x6D42, 0x6D0A, 0x6CD2, + 0x6C99, 0x6C61, 0x6C2A, 0x6BF2, 0x6BBA, 0x6B83, + 0x6B4B, 0x6B14, 0x6ADD, 0x6AA6, 0x6A6F, 0x6A38, + 0x6A01, 0x69CB, 0x6994, 0x695E, 0x6927, 0x68F1, + 0x68BB, 0x6885, 0x684F, 0x681A, 0x67E4, 0x67AE, + 0x6779, 0x6744, 0x670F, 0x66D9, 0x66A4, 0x6670, + 0x663B, 0x6606, 0x65D2, 0x659D, 0x6569, 0x6534, + 0x6500, 0x64CC, 0x6498, 0x6464, 0x6431, 0x63FD, + 0x63CA, 0x6396, 0x6363, 0x6330, 0x62FD, 0x62CA, + 0x6297, 0x6264, 0x6231, 0x61FF, 0x61CC, 0x619A, + 0x6167, 0x6135, 0x6103, 0x60D1, 0x609F, 0x606D, + 0x603C, 0x600A, 0x5FD9, 0x5FA7, 0x5F76, 0x5F45, + 0x5F14, 0x5EE3, 0x5EB2, 0x5E81, 0x5E50, 0x5E20, + 0x5DEF, 0x5DBF, 0x5D8F, 0x5D5E, 0x5D2E, 0x5CFE, + 0x5CCE, 0x5C9F, 0x5C6F, 0x5C3F, 0x5C10, 0x5BE0, + 0x5BB1, 0x5B82, 0x5B52, 0x5B23, 0x5AF4, 0x5AC6, + 0x5A97, 0x5A68, 0x5A3A, 0x5A0B, 0x59DD, 0x59AE, + 0x5980, 0x5952, 0x5924, 0x58F6, 0x58C8, 0x589A, + 0x586D, 0x583F, 0x5812, 0x57E4, 0x57B7, 0x578A, + 0x575D, 0x5730, 0x5703, 0x56D6, 0x56A9, 0x567D, + 0x5650, 0x5624, 0x55F7, 0x55CB, 0x559F, 0x5573, + 0x5547, 0x551B, 0x54EF, 0x54C3, 0x5497, 0x546C, + 0x5440, 0x5415, 0x53EA, 0x53BE, 0x5393, 0x5368, + 0x533D, 0x5312, 0x52E7, 0x52BD, 0x5292, 0x5267, + 0x523D, 0x5213, 0x51E8, 0x51BE, 0x5194, 0x516A, + 0x5140, 0x5116, 0x50EC, 0x50C3, 0x6A48, 0x6A19, + 0x69EA, 0x69BB, 0x698C, 0x695E, 0x692F, 0x6901, + 0x68D2, 0x68A4, 0x6876, 0x6848, 0x681A, 0x67EC, + 0x67BE, 0x6790, 0x6762, 0x6735, 0x6707, 0x66D9, + 0x66AC, 0x667F, 0x6651, 0x6624, 0x65F7, 0x65CA, + 0x659D, 0x6570, 0x6543, 0x6517, 0x64EA, 0x64BD, + 0x6491, 0x6464, 0x6438, 0x640C, 0x63E0, 0x63B4, + 0x6388, 0x635C, 0x6330, 0x6304, 0x62D8, 0x62AC, + 0x6281, 0x6255, 0x622A, 0x61FF, 0x61D3, 0x61A8, + 0x617D, 0x6152, 0x6127, 0x60FC, 0x60D1, 0x60A6, + 0x607C, 0x6051, 0x6027, 0x5FFC, 0x5FD2, 0x5FA7, + 0x5F7D, 0x5F53, 0x5F29, 0x5EFF, 0x5ED5, 0x5EAB, + 0x5E81, 0x5E57, 0x5E2E, 0x5E04, 0x5DDB, 0x5DB1, + 0x5D88, 0x5D5E, 0x5D35, 0x5D0C, 0x5CE3, 0x5CBA, + 0x5C91, 0x5C68, 0x5C3F, 0x5C16, 0x5BEE, 0x5BC5, + 0x5B9D, 0x5B74, 0x5B4C, 0x5B23, 0x5AFB, 0x5AD3, + 0x5AAB, 0x5A83, 0x5A5B, 0x5A33, 0x5A0B, 0x59E3, + 0x59BC, 0x5994, 0x596C, 0x5945, 0x591D, 0x58F6, + 0x58CF, 0x58A8, 0x5880, 0x5859, 0x5832, 0x580B, + 0x57E4, 0x57BE, 0x5797, 0x5770, 0x574A, 0x5723, + 0x56FC, 0x56D6, 0x56B0, 0x5689, 0x5663, 0x563D, + 0x5617, 0x55F1, 0x55CB, 0x55A5, 0x557F, 0x5559, + 0x5534, 0x550E, 0x54E9, 0x54C3, 0x549E, 0x5478, + 0x5453, 0x542E, 0x5408, 0x53E3, 0x53BE, 0x5399, + 0x5374, 0x534F, 0x532B, 0x5306, 0x52E1, 0x52BD, + 0x5298, 0x5274, 0x524F, 0x522B, 0x5207, 0x51E2, + 0x51BE, 0x519A, 0x5176, 0x5152, 0x512E, 0x510A, + 0x50E6, 0x50C3, 0x6587, 0x6561, 0x653C, 0x6517, + 0x64F1, 0x64CC, 0x64A7, 0x6482, 0x645D, 0x6438, + 0x6413, 0x63EE, 0x63CA, 0x63A5, 0x6380, 0x635C, + 0x6337, 0x6312, 0x62EE, 0x62CA, 0x62A5, 0x6281, + 0x625D, 0x6238, 0x6214, 0x61F0, 0x61CC, 0x61A8, + 0x6184, 0x6160, 0x613C, 0x6119, 0x60F5, 0x60D1, + 0x60AD, 0x608A, 0x6066, 0x6043, 0x601F, 0x5FFC, + 0x5FD9, 0x5FB5, 0x5F92, 0x5F6F, 0x5F4C, 0x5F29, + 0x5F06, 0x5EE3, 0x5EC0, 0x5E9D, 0x5E7A, 0x5E57, + 0x5E35, 0x5E12, 0x5DEF, 0x5DCD, 0x5DAA, 0x5D88, + 0x5D65, 0x5D43, 0x5D21, 0x5CFE, 0x5CDC, 0x5CBA, + 0x5C98, 0x5C76, 0x5C54, 0x5C32, 0x5C10, 0x5BEE, + 0x5BCC, 0x5BAA, 0x5B88, 0x5B67, 0x5B45, 0x5B23, + 0x5B02, 0x5AE0, 0x5ABF, 0x5A9D, 0x5A7C, 0x5A5B, + 0x5A3A, 0x5A18, 0x59F7, 0x59D6, 0x59B5, 0x5994, + 0x5973, 0x5952, 0x5931, 0x5910, 0x58F0, 0x58CF, + 0x58AE, 0x588D, 0x586D, 0x584C, 0x582C, 0x580B, + 0x57EB, 0x57CB, 0x57AA, 0x578A, 0x576A, 0x574A, + 0x5729, 0x5709, 0x56E9, 0x56C9, 0x56A9, 0x5689, + 0x566A, 0x564A, 0x562A, 0x560A, 0x55EB, 0x55CB, + 0x55AB, 0x558C, 0x556C, 0x554D, 0x552D, 0x550E, + 0x54EF, 0x54D0, 0x54B0, 0x5491, 0x5472, 0x5453, + 0x5434, 0x5415, 0x53F6, 0x53D7, 0x53B8, 0x5399, + 0x537B, 0x535C, 0x533D, 0x531E, 0x5300, 0x52E1, + 0x52C3, 0x52A4, 0x5286, 0x5267, 0x5249, 0x522B, + 0x520D, 0x51EE, 0x51D0, 0x51B2, 0x5194, 0x5176, + 0x5158, 0x513A, 0x511C, 0x50FE, 0x50E0, 0x50C3, + 0x60FC, 0x60DF, 0x60C3, 0x60A6, 0x608A, 0x606D, + 0x6051, 0x6035, 0x6018, 0x5FFC, 0x5FE0, 0x5FC4, + 0x5FA7, 0x5F8B, 0x5F6F, 0x5F53, 0x5F37, 0x5F1B, + 0x5EFF, 0x5EE3, 0x5EC7, 0x5EAB, 0x5E8F, 0x5E73, + 0x5E57, 0x5E3C, 0x5E20, 0x5E04, 0x5DE8, 0x5DCD, + 0x5DB1, 0x5D95, 0x5D7A, 0x5D5E, 0x5D43, 0x5D27, + 0x5D0C, 0x5CF1, 0x5CD5, 0x5CBA, 0x5C9F, 0x5C83, + 0x5C68, 0x5C4D, 0x5C32, 0x5C16, 0x5BFB, 0x5BE0, + 0x5BC5, 0x5BAA, 0x5B8F, 0x5B74, 0x5B59, 0x5B3E, + 0x5B23, 0x5B09, 0x5AEE, 0x5AD3, 0x5AB8, 0x5A9D, + 0x5A83, 0x5A68, 0x5A4D, 0x5A33, 0x5A18, 0x59FE, + 0x59E3, 0x59C9, 0x59AE, 0x5994, 0x597A, 0x595F, + 0x5945, 0x592B, 0x5910, 0x58F6, 0x58DC, 0x58C2, + 0x58A8, 0x588D, 0x5873, 0x5859, 0x583F, 0x5825, + 0x580B, 0x57F1, 0x57D7, 0x57BE, 0x57A4, 0x578A, + 0x5770, 0x5756, 0x573D, 0x5723, 0x5709, 0x56F0, + 0x56D6, 0x56BC, 0x56A3, 0x5689, 0x5670, 0x5656, + 0x563D, 0x5624, 0x560A, 0x55F1, 0x55D8, 0x55BE, + 0x55A5, 0x558C, 0x5573, 0x5559, 0x5540, 0x5527, + 0x550E, 0x54F5, 0x54DC, 0x54C3, 0x54AA, 0x5491, + 0x5478, 0x545F, 0x5446, 0x542E, 0x5415, 0x53FC, + 0x53E3, 0x53CB, 0x53B2, 0x5399, 0x5381, 0x5368, + 0x534F, 0x5337, 0x531E, 0x5306, 0x52ED, 0x52D5, + 0x52BD, 0x52A4, 0x528C, 0x5274, 0x525B, 0x5243, + 0x522B, 0x5213, 0x51FA, 0x51E2, 0x51CA, 0x51B2, + 0x519A, 0x5182, 0x516A, 0x5152, 0x513A, 0x5122, + 0x510A, 0x50F2, 0x50DB, 0x50C3, 0x5CA5, 0x5C91, + 0x5C7C, 0x5C68, 0x5C54, 0x5C3F, 0x5C2B, 0x5C16, + 0x5C02, 0x5BEE, 0x5BD9, 0x5BC5, 0x5BB1, 0x5B9D, + 0x5B88, 0x5B74, 0x5B60, 0x5B4C, 0x5B38, 0x5B23, + 0x5B0F, 0x5AFB, 0x5AE7, 0x5AD3, 0x5ABF, 0x5AAB, + 0x5A97, 0x5A83, 0x5A6F, 0x5A5B, 0x5A47, 0x5A33, + 0x5A1F, 0x5A0B, 0x59F7, 0x59E3, 0x59CF, 0x59BC, + 0x59A8, 0x5994, 0x5980, 0x596C, 0x5959, 0x5945, + 0x5931, 0x591D, 0x590A, 0x58F6, 0x58E2, 0x58CF, + 0x58BB, 0x58A8, 0x5894, 0x5880, 0x586D, 0x5859, + 0x5846, 0x5832, 0x581F, 0x580B, 0x57F8, 0x57E4, + 0x57D1, 0x57BE, 0x57AA, 0x5797, 0x5783, 0x5770, + 0x575D, 0x574A, 0x5736, 0x5723, 0x5710, 0x56FC, + 0x56E9, 0x56D6, 0x56C3, 0x56B0, 0x569D, 0x5689, + 0x5676, 0x5663, 0x5650, 0x563D, 0x562A, 0x5617, + 0x5604, 0x55F1, 0x55DE, 0x55CB, 0x55B8, 0x55A5, + 0x5592, 0x557F, 0x556C, 0x5559, 0x5547, 0x5534, + 0x5521, 0x550E, 0x54FB, 0x54E9, 0x54D6, 0x54C3, + 0x54B0, 0x549E, 0x548B, 0x5478, 0x5466, 0x5453, + 0x5440, 0x542E, 0x541B, 0x5408, 0x53F6, 0x53E3, + 0x53D1, 0x53BE, 0x53AC, 0x5399, 0x5387, 0x5374, + 0x5362, 0x534F, 0x533D, 0x532B, 0x5318, 0x5306, + 0x52F4, 0x52E1, 0x52CF, 0x52BD, 0x52AA, 0x5298, + 0x5286, 0x5274, 0x5261, 0x524F, 0x523D, 0x522B, + 0x5219, 0x5207, 0x51F4, 0x51E2, 0x51D0, 0x51BE, + 0x51AC, 0x519A, 0x5188, 0x5176, 0x5164, 0x5152, + 0x5140, 0x512E, 0x511C, 0x510A, 0x50F8, 0x50E6, + 0x50D5, 0x50C3, 0x5880, 0x5873, 0x5866, 0x5859, + 0x584C, 0x583F, 0x5832, 0x5825, 0x5818, 0x580B, + 0x57FE, 0x57F1, 0x57E4, 0x57D7, 0x57CB, 0x57BE, + 0x57B1, 0x57A4, 0x5797, 0x578A, 0x577D, 0x5770, + 0x5763, 0x5756, 0x574A, 0x573D, 0x5730, 0x5723, + 0x5716, 0x5709, 0x56FC, 0x56F0, 0x56E3, 0x56D6, + 0x56C9, 0x56BC, 0x56B0, 0x56A3, 0x5696, 0x5689, + 0x567D, 0x5670, 0x5663, 0x5656, 0x564A, 0x563D, + 0x5630, 0x5624, 0x5617, 0x560A, 0x55FE, 0x55F1, + 0x55E4, 0x55D8, 0x55CB, 0x55BE, 0x55B2, 0x55A5, + 0x5598, 0x558C, 0x557F, 0x5573, 0x5566, 0x5559, + 0x554D, 0x5540, 0x5534, 0x5527, 0x551B, 0x550E, + 0x5502, 0x54F5, 0x54E9, 0x54DC, 0x54D0, 0x54C3, + 0x54B7, 0x54AA, 0x549E, 0x5491, 0x5485, 0x5478, + 0x546C, 0x545F, 0x5453, 0x5446, 0x543A, 0x542E, + 0x5421, 0x5415, 0x5408, 0x53FC, 0x53F0, 0x53E3, + 0x53D7, 0x53CB, 0x53BE, 0x53B2, 0x53A6, 0x5399, + 0x538D, 0x5381, 0x5374, 0x5368, 0x535C, 0x534F, + 0x5343, 0x5337, 0x532B, 0x531E, 0x5312, 0x5306, + 0x52FA, 0x52ED, 0x52E1, 0x52D5, 0x52C9, 0x52BD, + 0x52B0, 0x52A4, 0x5298, 0x528C, 0x5280, 0x5274, + 0x5267, 0x525B, 0x524F, 0x5243, 0x5237, 0x522B, + 0x521F, 0x5213, 0x5207, 0x51FA, 0x51EE, 0x51E2, + 0x51D6, 0x51CA, 0x51BE, 0x51B2, 0x51A6, 0x519A, + 0x518E, 0x5182, 0x5176, 0x516A, 0x515E, 0x5152, + 0x5146, 0x513A, 0x512E, 0x5122, 0x5116, 0x510A, + 0x50FE, 0x50F2, 0x50E6, 0x50DB, 0x50CF, 0x50C3, + 0x548B, 0x5485, 0x547E, 0x5478, 0x5472, 0x546C, + 0x5466, 0x545F, 0x5459, 0x5453, 0x544D, 0x5446, + 0x5440, 0x543A, 0x5434, 0x542E, 0x5427, 0x5421, + 0x541B, 0x5415, 0x540F, 0x5408, 0x5402, 0x53FC, + 0x53F6, 0x53F0, 0x53EA, 0x53E3, 0x53DD, 0x53D7, + 0x53D1, 0x53CB, 0x53C4, 0x53BE, 0x53B8, 0x53B2, + 0x53AC, 0x53A6, 0x539F, 0x5399, 0x5393, 0x538D, + 0x5387, 0x5381, 0x537B, 0x5374, 0x536E, 0x5368, + 0x5362, 0x535C, 0x5356, 0x534F, 0x5349, 0x5343, + 0x533D, 0x5337, 0x5331, 0x532B, 0x5325, 0x531E, + 0x5318, 0x5312, 0x530C, 0x5306, 0x5300, 0x52FA, + 0x52F4, 0x52ED, 0x52E7, 0x52E1, 0x52DB, 0x52D5, + 0x52CF, 0x52C9, 0x52C3, 0x52BD, 0x52B7, 0x52B0, + 0x52AA, 0x52A4, 0x529E, 0x5298, 0x5292, 0x528C, + 0x5286, 0x5280, 0x527A, 0x5274, 0x526E, 0x5267, + 0x5261, 0x525B, 0x5255, 0x524F, 0x5249, 0x5243, + 0x523D, 0x5237, 0x5231, 0x522B, 0x5225, 0x521F, + 0x5219, 0x5213, 0x520D, 0x5207, 0x5201, 0x51FA, + 0x51F4, 0x51EE, 0x51E8, 0x51E2, 0x51DC, 0x51D6, + 0x51D0, 0x51CA, 0x51C4, 0x51BE, 0x51B8, 0x51B2, + 0x51AC, 0x51A6, 0x51A0, 0x519A, 0x5194, 0x518E, + 0x5188, 0x5182, 0x517C, 0x5176, 0x5170, 0x516A, + 0x5164, 0x515E, 0x5158, 0x5152, 0x514C, 0x5146, + 0x5140, 0x513A, 0x5134, 0x512E, 0x5128, 0x5122, + 0x511C, 0x5116, 0x5110, 0x510A, 0x5104, 0x50FE, + 0x50F8, 0x50F2, 0x50EC, 0x50E6, 0x50E0, 0x50DB, + 0x50D5, 0x50CF, 0x50C9, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x7A46, 0x7A4F, 0x7A58, 0x7A61, + 0x7A6A, 0x7A73, 0x7A7C, 0x7A85, 0x7A8E, 0x7A97, + 0x7AA0, 0x7AA9, 0x7AB2, 0x7ABB, 0x7AC4, 0x7ACD, + 0x7AD6, 0x7ADF, 0x7AE8, 0x7AF1, 0x7AFA, 0x7B03, + 0x7B0D, 0x7B16, 0x7B1F, 0x7B28, 0x7B31, 0x7B3A, + 0x7B43, 0x7B4C, 0x7B55, 0x7B5E, 0x7B67, 0x7B70, + 0x7B7A, 0x7B83, 0x7B8C, 0x7B95, 0x7B9E, 0x7BA7, + 0x7BB0, 0x7BB9, 0x7BC2, 0x7BCC, 0x7BD5, 0x7BDE, + 0x7BE7, 0x7BF0, 0x7BF9, 0x7C02, 0x7C0B, 0x7C15, + 0x7C1E, 0x7C27, 0x7C30, 0x7C39, 0x7C42, 0x7C4B, + 0x7C55, 0x7C5E, 0x7C67, 0x7C70, 0x7C79, 0x7C82, + 0x7C8C, 0x7C95, 0x7C9E, 0x7CA7, 0x7CB0, 0x7CBA, + 0x7CC3, 0x7CCC, 0x7CD5, 0x7CDE, 0x7CE8, 0x7CF1, + 0x7CFA, 0x7D03, 0x7D0C, 0x7D16, 0x7D1F, 0x7D28, + 0x7D31, 0x7D3A, 0x7D44, 0x7D4D, 0x7D56, 0x7D5F, + 0x7D69, 0x7D72, 0x7D7B, 0x7D84, 0x7D8E, 0x7D97, + 0x7DA0, 0x7DA9, 0x7DB3, 0x7DBC, 0x7DC5, 0x7DCE, + 0x7DD8, 0x7DE1, 0x7DEA, 0x7DF4, 0x7DFD, 0x7E06, + 0x7E0F, 0x7E19, 0x7E22, 0x7E2B, 0x7E35, 0x7E3E, + 0x7E47, 0x7E51, 0x7E5A, 0x7E63, 0x7E6C, 0x7E76, + 0x7E7F, 0x7E88, 0x7E92, 0x7E9B, 0x7EA4, 0x7EAE, + 0x7EB7, 0x7EC0, 0x7ECA, 0x7ED3, 0x7EDC, 0x7EE6, + 0x7EEF, 0x7EF8, 0x7F02, 0x7F0B, 0x7F15, 0x7F1E, + 0x7F27, 0x7F31, 0x7F3A, 0x7F43, 0x7F4D, 0x7F56, + 0x7F60, 0x7F69, 0x7F72, 0x7F7C, 0x7F85, 0x7F8F, + 0x7F98, 0x7FA1, 0x7FAB, 0x7FB4, 0x7FBE, 0x7FC7, + 0x7FD0, 0x7FDA, 0x7FE3, 0x7FED, 0x7FF6, 0x8000, + 0x74C5, 0x74CD, 0x74D6, 0x74DF, 0x74E7, 0x74F0, + 0x74F9, 0x7501, 0x750A, 0x7512, 0x751B, 0x7524, + 0x752C, 0x7535, 0x753E, 0x7546, 0x754F, 0x7558, + 0x7560, 0x7569, 0x7571, 0x757A, 0x7583, 0x758B, + 0x7594, 0x759D, 0x75A5, 0x75AE, 0x75B7, 0x75BF, + 0x75C8, 0x75D1, 0x75D9, 0x75E2, 0x75EB, 0x75F4, + 0x75FC, 0x7605, 0x760E, 0x7616, 0x761F, 0x7628, + 0x7630, 0x7639, 0x7642, 0x764B, 0x7653, 0x765C, + 0x7665, 0x766D, 0x7676, 0x767F, 0x7688, 0x7690, + 0x7699, 0x76A2, 0x76AB, 0x76B3, 0x76BC, 0x76C5, + 0x76CE, 0x76D6, 0x76DF, 0x76E8, 0x76F1, 0x76F9, + 0x7702, 0x770B, 0x7714, 0x771C, 0x7725, 0x772E, + 0x7737, 0x7740, 0x7748, 0x7751, 0x775A, 0x7763, + 0x776C, 0x7774, 0x777D, 0x7786, 0x778F, 0x7798, + 0x77A0, 0x77A9, 0x77B2, 0x77BB, 0x77C4, 0x77CD, + 0x77D5, 0x77DE, 0x77E7, 0x77F0, 0x77F9, 0x7802, + 0x780A, 0x7813, 0x781C, 0x7825, 0x782E, 0x7837, + 0x783F, 0x7848, 0x7851, 0x785A, 0x7863, 0x786C, + 0x7875, 0x787E, 0x7886, 0x788F, 0x7898, 0x78A1, + 0x78AA, 0x78B3, 0x78BC, 0x78C5, 0x78CE, 0x78D6, + 0x78DF, 0x78E8, 0x78F1, 0x78FA, 0x7903, 0x790C, + 0x7915, 0x791E, 0x7927, 0x7930, 0x7939, 0x7942, + 0x794A, 0x7953, 0x795C, 0x7965, 0x796E, 0x7977, + 0x7980, 0x7989, 0x7992, 0x799B, 0x79A4, 0x79AD, + 0x79B6, 0x79BF, 0x79C8, 0x79D1, 0x79DA, 0x79E3, + 0x79EC, 0x79F5, 0x79FE, 0x7A07, 0x7A10, 0x7A19, + 0x7A22, 0x7A2B, 0x7A34, 0x7A3D, 0x6F83, 0x6F8C, + 0x6F94, 0x6F9C, 0x6FA4, 0x6FAD, 0x6FB5, 0x6FBD, + 0x6FC5, 0x6FCD, 0x6FD6, 0x6FDE, 0x6FE6, 0x6FEE, + 0x6FF7, 0x6FFF, 0x7007, 0x700F, 0x7018, 0x7020, + 0x7028, 0x7031, 0x7039, 0x7041, 0x7049, 0x7052, + 0x705A, 0x7062, 0x706A, 0x7073, 0x707B, 0x7083, + 0x708C, 0x7094, 0x709C, 0x70A4, 0x70AD, 0x70B5, + 0x70BD, 0x70C6, 0x70CE, 0x70D6, 0x70DF, 0x70E7, + 0x70EF, 0x70F8, 0x7100, 0x7108, 0x7111, 0x7119, + 0x7121, 0x712A, 0x7132, 0x713A, 0x7143, 0x714B, + 0x7153, 0x715C, 0x7164, 0x716C, 0x7175, 0x717D, + 0x7185, 0x718E, 0x7196, 0x719F, 0x71A7, 0x71AF, + 0x71B8, 0x71C0, 0x71C8, 0x71D1, 0x71D9, 0x71E2, + 0x71EA, 0x71F2, 0x71FB, 0x7203, 0x720C, 0x7214, + 0x721C, 0x7225, 0x722D, 0x7236, 0x723E, 0x7246, + 0x724F, 0x7257, 0x7260, 0x7268, 0x7271, 0x7279, + 0x7281, 0x728A, 0x7292, 0x729B, 0x72A3, 0x72AC, + 0x72B4, 0x72BD, 0x72C5, 0x72CE, 0x72D6, 0x72DE, + 0x72E7, 0x72EF, 0x72F8, 0x7300, 0x7309, 0x7311, + 0x731A, 0x7322, 0x732B, 0x7333, 0x733C, 0x7344, + 0x734D, 0x7355, 0x735E, 0x7366, 0x736F, 0x7377, + 0x7380, 0x7388, 0x7391, 0x7399, 0x73A2, 0x73AA, + 0x73B3, 0x73BB, 0x73C4, 0x73CC, 0x73D5, 0x73DD, + 0x73E6, 0x73EF, 0x73F7, 0x7400, 0x7408, 0x7411, + 0x7419, 0x7422, 0x742A, 0x7433, 0x743C, 0x7444, + 0x744D, 0x7455, 0x745E, 0x7466, 0x746F, 0x7478, + 0x7480, 0x7489, 0x7491, 0x749A, 0x74A2, 0x74AB, + 0x74B4, 0x74BC, 0x6A7F, 0x6A86, 0x6A8E, 0x6A96, + 0x6A9E, 0x6AA6, 0x6AAE, 0x6AB6, 0x6ABD, 0x6AC5, + 0x6ACD, 0x6AD5, 0x6ADD, 0x6AE5, 0x6AED, 0x6AF5, + 0x6AFC, 0x6B04, 0x6B0C, 0x6B14, 0x6B1C, 0x6B24, + 0x6B2C, 0x6B34, 0x6B3C, 0x6B43, 0x6B4B, 0x6B53, + 0x6B5B, 0x6B63, 0x6B6B, 0x6B73, 0x6B7B, 0x6B83, + 0x6B8B, 0x6B93, 0x6B9B, 0x6BA2, 0x6BAA, 0x6BB2, + 0x6BBA, 0x6BC2, 0x6BCA, 0x6BD2, 0x6BDA, 0x6BE2, + 0x6BEA, 0x6BF2, 0x6BFA, 0x6C02, 0x6C0A, 0x6C12, + 0x6C1A, 0x6C22, 0x6C2A, 0x6C32, 0x6C3A, 0x6C42, + 0x6C4A, 0x6C52, 0x6C59, 0x6C61, 0x6C69, 0x6C71, + 0x6C79, 0x6C81, 0x6C89, 0x6C91, 0x6C99, 0x6CA1, + 0x6CA9, 0x6CB1, 0x6CB9, 0x6CC1, 0x6CC9, 0x6CD2, + 0x6CDA, 0x6CE2, 0x6CEA, 0x6CF2, 0x6CFA, 0x6D02, + 0x6D0A, 0x6D12, 0x6D1A, 0x6D22, 0x6D2A, 0x6D32, + 0x6D3A, 0x6D42, 0x6D4A, 0x6D52, 0x6D5A, 0x6D62, + 0x6D6A, 0x6D72, 0x6D7A, 0x6D82, 0x6D8B, 0x6D93, + 0x6D9B, 0x6DA3, 0x6DAB, 0x6DB3, 0x6DBB, 0x6DC3, + 0x6DCB, 0x6DD3, 0x6DDB, 0x6DE3, 0x6DEC, 0x6DF4, + 0x6DFC, 0x6E04, 0x6E0C, 0x6E14, 0x6E1C, 0x6E24, + 0x6E2C, 0x6E35, 0x6E3D, 0x6E45, 0x6E4D, 0x6E55, + 0x6E5D, 0x6E65, 0x6E6D, 0x6E76, 0x6E7E, 0x6E86, + 0x6E8E, 0x6E96, 0x6E9E, 0x6EA6, 0x6EAF, 0x6EB7, + 0x6EBF, 0x6EC7, 0x6ECF, 0x6ED7, 0x6EE0, 0x6EE8, + 0x6EF0, 0x6EF8, 0x6F00, 0x6F08, 0x6F11, 0x6F19, + 0x6F21, 0x6F29, 0x6F31, 0x6F3A, 0x6F42, 0x6F4A, + 0x6F52, 0x6F5A, 0x6F63, 0x6F6B, 0x6F73, 0x6F7B, + 0x65B4, 0x65BB, 0x65C3, 0x65CA, 0x65D2, 0x65D9, + 0x65E1, 0x65E8, 0x65F0, 0x65F7, 0x65FF, 0x6606, + 0x660E, 0x6615, 0x661D, 0x6624, 0x662C, 0x6633, + 0x663B, 0x6642, 0x664A, 0x6651, 0x6659, 0x6660, + 0x6668, 0x6670, 0x6677, 0x667F, 0x6686, 0x668E, + 0x6695, 0x669D, 0x66A4, 0x66AC, 0x66B4, 0x66BB, + 0x66C3, 0x66CA, 0x66D2, 0x66D9, 0x66E1, 0x66E9, + 0x66F0, 0x66F8, 0x66FF, 0x6707, 0x670F, 0x6716, + 0x671E, 0x6725, 0x672D, 0x6735, 0x673C, 0x6744, + 0x674B, 0x6753, 0x675B, 0x6762, 0x676A, 0x6771, + 0x6779, 0x6781, 0x6788, 0x6790, 0x6798, 0x679F, + 0x67A7, 0x67AE, 0x67B6, 0x67BE, 0x67C5, 0x67CD, + 0x67D5, 0x67DC, 0x67E4, 0x67EC, 0x67F3, 0x67FB, + 0x6803, 0x680A, 0x6812, 0x681A, 0x6821, 0x6829, + 0x6831, 0x6838, 0x6840, 0x6848, 0x684F, 0x6857, + 0x685F, 0x6866, 0x686E, 0x6876, 0x687E, 0x6885, + 0x688D, 0x6895, 0x689C, 0x68A4, 0x68AC, 0x68B4, + 0x68BB, 0x68C3, 0x68CB, 0x68D2, 0x68DA, 0x68E2, + 0x68EA, 0x68F1, 0x68F9, 0x6901, 0x6909, 0x6910, + 0x6918, 0x6920, 0x6927, 0x692F, 0x6937, 0x693F, + 0x6947, 0x694E, 0x6956, 0x695E, 0x6966, 0x696D, + 0x6975, 0x697D, 0x6985, 0x698C, 0x6994, 0x699C, + 0x69A4, 0x69AC, 0x69B3, 0x69BB, 0x69C3, 0x69CB, + 0x69D2, 0x69DA, 0x69E2, 0x69EA, 0x69F2, 0x69FA, + 0x6A01, 0x6A09, 0x6A11, 0x6A19, 0x6A21, 0x6A28, + 0x6A30, 0x6A38, 0x6A40, 0x6A48, 0x6A50, 0x6A57, + 0x6A5F, 0x6A67, 0x6A6F, 0x6A77, 0x6120, 0x6127, + 0x612E, 0x6135, 0x613C, 0x6144, 0x614B, 0x6152, + 0x6159, 0x6160, 0x6167, 0x616F, 0x6176, 0x617D, + 0x6184, 0x618B, 0x6192, 0x619A, 0x61A1, 0x61A8, + 0x61AF, 0x61B6, 0x61BE, 0x61C5, 0x61CC, 0x61D3, + 0x61DA, 0x61E2, 0x61E9, 0x61F0, 0x61F7, 0x61FF, + 0x6206, 0x620D, 0x6214, 0x621B, 0x6223, 0x622A, + 0x6231, 0x6238, 0x6240, 0x6247, 0x624E, 0x6255, + 0x625D, 0x6264, 0x626B, 0x6272, 0x627A, 0x6281, + 0x6288, 0x628F, 0x6297, 0x629E, 0x62A5, 0x62AC, + 0x62B4, 0x62BB, 0x62C2, 0x62CA, 0x62D1, 0x62D8, + 0x62DF, 0x62E7, 0x62EE, 0x62F5, 0x62FD, 0x6304, + 0x630B, 0x6312, 0x631A, 0x6321, 0x6328, 0x6330, + 0x6337, 0x633E, 0x6346, 0x634D, 0x6354, 0x635C, + 0x6363, 0x636A, 0x6372, 0x6379, 0x6380, 0x6388, + 0x638F, 0x6396, 0x639E, 0x63A5, 0x63AC, 0x63B4, + 0x63BB, 0x63C2, 0x63CA, 0x63D1, 0x63D8, 0x63E0, + 0x63E7, 0x63EE, 0x63F6, 0x63FD, 0x6405, 0x640C, + 0x6413, 0x641B, 0x6422, 0x6429, 0x6431, 0x6438, + 0x6440, 0x6447, 0x644E, 0x6456, 0x645D, 0x6464, + 0x646C, 0x6473, 0x647B, 0x6482, 0x648A, 0x6491, + 0x6498, 0x64A0, 0x64A7, 0x64AF, 0x64B6, 0x64BD, + 0x64C5, 0x64CC, 0x64D4, 0x64DB, 0x64E3, 0x64EA, + 0x64F1, 0x64F9, 0x6500, 0x6508, 0x650F, 0x6517, + 0x651E, 0x6526, 0x652D, 0x6534, 0x653C, 0x6543, + 0x654B, 0x6552, 0x655A, 0x6561, 0x6569, 0x6570, + 0x6578, 0x657F, 0x6587, 0x658E, 0x6596, 0x659D, + 0x65A5, 0x65AC, 0x5CC1, 0x5CC7, 0x5CCE, 0x5CD5, + 0x5CDC, 0x5CE3, 0x5CEA, 0x5CF1, 0x5CF7, 0x5CFE, + 0x5D05, 0x5D0C, 0x5D13, 0x5D1A, 0x5D21, 0x5D27, + 0x5D2E, 0x5D35, 0x5D3C, 0x5D43, 0x5D4A, 0x5D51, + 0x5D57, 0x5D5E, 0x5D65, 0x5D6C, 0x5D73, 0x5D7A, + 0x5D81, 0x5D88, 0x5D8F, 0x5D95, 0x5D9C, 0x5DA3, + 0x5DAA, 0x5DB1, 0x5DB8, 0x5DBF, 0x5DC6, 0x5DCD, + 0x5DD4, 0x5DDB, 0x5DE1, 0x5DE8, 0x5DEF, 0x5DF6, + 0x5DFD, 0x5E04, 0x5E0B, 0x5E12, 0x5E19, 0x5E20, + 0x5E27, 0x5E2E, 0x5E35, 0x5E3C, 0x5E42, 0x5E49, + 0x5E50, 0x5E57, 0x5E5E, 0x5E65, 0x5E6C, 0x5E73, + 0x5E7A, 0x5E81, 0x5E88, 0x5E8F, 0x5E96, 0x5E9D, + 0x5EA4, 0x5EAB, 0x5EB2, 0x5EB9, 0x5EC0, 0x5EC7, + 0x5ECE, 0x5ED5, 0x5EDC, 0x5EE3, 0x5EEA, 0x5EF1, + 0x5EF8, 0x5EFF, 0x5F06, 0x5F0D, 0x5F14, 0x5F1B, + 0x5F22, 0x5F29, 0x5F30, 0x5F37, 0x5F3E, 0x5F45, + 0x5F4C, 0x5F53, 0x5F5A, 0x5F61, 0x5F68, 0x5F6F, + 0x5F76, 0x5F7D, 0x5F84, 0x5F8B, 0x5F92, 0x5F99, + 0x5FA0, 0x5FA7, 0x5FAE, 0x5FB5, 0x5FBC, 0x5FC4, + 0x5FCB, 0x5FD2, 0x5FD9, 0x5FE0, 0x5FE7, 0x5FEE, + 0x5FF5, 0x5FFC, 0x6003, 0x600A, 0x6011, 0x6018, + 0x601F, 0x6027, 0x602E, 0x6035, 0x603C, 0x6043, + 0x604A, 0x6051, 0x6058, 0x605F, 0x6066, 0x606D, + 0x6075, 0x607C, 0x6083, 0x608A, 0x6091, 0x6098, + 0x609F, 0x60A6, 0x60AD, 0x60B5, 0x60BC, 0x60C3, + 0x60CA, 0x60D1, 0x60D8, 0x60DF, 0x60E7, 0x60EE, + 0x60F5, 0x60FC, 0x6103, 0x610A, 0x6111, 0x6119, + 0x5894, 0x589A, 0x58A1, 0x58A8, 0x58AE, 0x58B5, + 0x58BB, 0x58C2, 0x58C8, 0x58CF, 0x58D5, 0x58DC, + 0x58E2, 0x58E9, 0x58F0, 0x58F6, 0x58FD, 0x5903, + 0x590A, 0x5910, 0x5917, 0x591D, 0x5924, 0x592B, + 0x5931, 0x5938, 0x593E, 0x5945, 0x594B, 0x5952, + 0x5959, 0x595F, 0x5966, 0x596C, 0x5973, 0x597A, + 0x5980, 0x5987, 0x598D, 0x5994, 0x599B, 0x59A1, + 0x59A8, 0x59AE, 0x59B5, 0x59BC, 0x59C2, 0x59C9, + 0x59CF, 0x59D6, 0x59DD, 0x59E3, 0x59EA, 0x59F1, + 0x59F7, 0x59FE, 0x5A04, 0x5A0B, 0x5A12, 0x5A18, + 0x5A1F, 0x5A26, 0x5A2C, 0x5A33, 0x5A3A, 0x5A40, + 0x5A47, 0x5A4D, 0x5A54, 0x5A5B, 0x5A61, 0x5A68, + 0x5A6F, 0x5A75, 0x5A7C, 0x5A83, 0x5A89, 0x5A90, + 0x5A97, 0x5A9D, 0x5AA4, 0x5AAB, 0x5AB2, 0x5AB8, + 0x5ABF, 0x5AC6, 0x5ACC, 0x5AD3, 0x5ADA, 0x5AE0, + 0x5AE7, 0x5AEE, 0x5AF4, 0x5AFB, 0x5B02, 0x5B09, + 0x5B0F, 0x5B16, 0x5B1D, 0x5B23, 0x5B2A, 0x5B31, + 0x5B38, 0x5B3E, 0x5B45, 0x5B4C, 0x5B52, 0x5B59, + 0x5B60, 0x5B67, 0x5B6D, 0x5B74, 0x5B7B, 0x5B82, + 0x5B88, 0x5B8F, 0x5B96, 0x5B9D, 0x5BA3, 0x5BAA, + 0x5BB1, 0x5BB8, 0x5BBE, 0x5BC5, 0x5BCC, 0x5BD3, + 0x5BD9, 0x5BE0, 0x5BE7, 0x5BEE, 0x5BF5, 0x5BFB, + 0x5C02, 0x5C09, 0x5C10, 0x5C16, 0x5C1D, 0x5C24, + 0x5C2B, 0x5C32, 0x5C38, 0x5C3F, 0x5C46, 0x5C4D, + 0x5C54, 0x5C5A, 0x5C61, 0x5C68, 0x5C6F, 0x5C76, + 0x5C7C, 0x5C83, 0x5C8A, 0x5C91, 0x5C98, 0x5C9F, + 0x5CA5, 0x5CAC, 0x5CB3, 0x5CBA, 0x5497, 0x549E, + 0x54A4, 0x54AA, 0x54B0, 0x54B7, 0x54BD, 0x54C3, + 0x54C9, 0x54D0, 0x54D6, 0x54DC, 0x54E2, 0x54E9, + 0x54EF, 0x54F5, 0x54FB, 0x5502, 0x5508, 0x550E, + 0x5514, 0x551B, 0x5521, 0x5527, 0x552D, 0x5534, + 0x553A, 0x5540, 0x5547, 0x554D, 0x5553, 0x5559, + 0x5560, 0x5566, 0x556C, 0x5573, 0x5579, 0x557F, + 0x5585, 0x558C, 0x5592, 0x5598, 0x559F, 0x55A5, + 0x55AB, 0x55B2, 0x55B8, 0x55BE, 0x55C5, 0x55CB, + 0x55D1, 0x55D8, 0x55DE, 0x55E4, 0x55EB, 0x55F1, + 0x55F7, 0x55FE, 0x5604, 0x560A, 0x5611, 0x5617, + 0x561D, 0x5624, 0x562A, 0x5630, 0x5637, 0x563D, + 0x5643, 0x564A, 0x5650, 0x5656, 0x565D, 0x5663, + 0x566A, 0x5670, 0x5676, 0x567D, 0x5683, 0x5689, + 0x5690, 0x5696, 0x569D, 0x56A3, 0x56A9, 0x56B0, + 0x56B6, 0x56BC, 0x56C3, 0x56C9, 0x56D0, 0x56D6, + 0x56DC, 0x56E3, 0x56E9, 0x56F0, 0x56F6, 0x56FC, + 0x5703, 0x5709, 0x5710, 0x5716, 0x571D, 0x5723, + 0x5729, 0x5730, 0x5736, 0x573D, 0x5743, 0x574A, + 0x5750, 0x5756, 0x575D, 0x5763, 0x576A, 0x5770, + 0x5777, 0x577D, 0x5783, 0x578A, 0x5790, 0x5797, + 0x579D, 0x57A4, 0x57AA, 0x57B1, 0x57B7, 0x57BE, + 0x57C4, 0x57CB, 0x57D1, 0x57D7, 0x57DE, 0x57E4, + 0x57EB, 0x57F1, 0x57F8, 0x57FE, 0x5805, 0x580B, + 0x5812, 0x5818, 0x581F, 0x5825, 0x582C, 0x5832, + 0x5839, 0x583F, 0x5846, 0x584C, 0x5853, 0x5859, + 0x5860, 0x5866, 0x586D, 0x5873, 0x587A, 0x5880, + 0x5887, 0x588D, 0x50C9, 0x50CF, 0x50D5, 0x50DB, + 0x50E0, 0x50E6, 0x50EC, 0x50F2, 0x50F8, 0x50FE, + 0x5104, 0x510A, 0x5110, 0x5116, 0x511C, 0x5122, + 0x5128, 0x512E, 0x5134, 0x513A, 0x5140, 0x5146, + 0x514C, 0x5152, 0x5158, 0x515E, 0x5164, 0x516A, + 0x5170, 0x5176, 0x517C, 0x5182, 0x5188, 0x518E, + 0x5194, 0x519A, 0x51A0, 0x51A6, 0x51AC, 0x51B2, + 0x51B8, 0x51BE, 0x51C4, 0x51CA, 0x51D0, 0x51D6, + 0x51DC, 0x51E2, 0x51E8, 0x51EE, 0x51F4, 0x51FA, + 0x5201, 0x5207, 0x520D, 0x5213, 0x5219, 0x521F, + 0x5225, 0x522B, 0x5231, 0x5237, 0x523D, 0x5243, + 0x5249, 0x524F, 0x5255, 0x525B, 0x5261, 0x5267, + 0x526E, 0x5274, 0x527A, 0x5280, 0x5286, 0x528C, + 0x5292, 0x5298, 0x529E, 0x52A4, 0x52AA, 0x52B0, + 0x52B7, 0x52BD, 0x52C3, 0x52C9, 0x52CF, 0x52D5, + 0x52DB, 0x52E1, 0x52E7, 0x52ED, 0x52F4, 0x52FA, + 0x5300, 0x5306, 0x530C, 0x5312, 0x5318, 0x531E, + 0x5325, 0x532B, 0x5331, 0x5337, 0x533D, 0x5343, + 0x5349, 0x534F, 0x5356, 0x535C, 0x5362, 0x5368, + 0x536E, 0x5374, 0x537B, 0x5381, 0x5387, 0x538D, + 0x5393, 0x5399, 0x539F, 0x53A6, 0x53AC, 0x53B2, + 0x53B8, 0x53BE, 0x53C4, 0x53CB, 0x53D1, 0x53D7, + 0x53DD, 0x53E3, 0x53EA, 0x53F0, 0x53F6, 0x53FC, + 0x5402, 0x5408, 0x540F, 0x5415, 0x541B, 0x5421, + 0x5427, 0x542E, 0x5434, 0x543A, 0x5440, 0x5446, + 0x544D, 0x5453, 0x5459, 0x545F, 0x5466, 0x546C, + 0x5472, 0x5478, 0x547E, 0x5485, 0x548B, 0x5491 +}; diff --git a/src/dolphin/ax/src/AXOut.c b/src/dolphin/ax/src/AXOut.c new file mode 100644 index 0000000..e0649ba --- /dev/null +++ b/src/dolphin/ax/src/AXOut.c @@ -0,0 +1,238 @@ +#include +#include +#include + +#include "__ax.h" + +static s16 __AXOutBuffer[3][320]; +static s32 __AXOutSBuffer[160]; +static u16 __AXDramImage[8192]; +static DSPTaskInfo __AXDSPTask; +AXPROFILE __AXLocalProfile; + +volatile static u32 __AXOutFrame; +volatile static u32 __AXAiDmaFrame; +volatile static u32 __AXOutDspReady; +volatile static OSTime __AXOsTime; +static void (*__AXUserFrameCallback)(); +volatile static int __AXDSPInitFlag; +static int __AXDSPDoneFlag; + +static volatile u32 __AXDebugSteppingMode; +static OSThreadQueue __AXOutThreadQueue; +static u32 __AXOutputBufferMode; + +// prototypes +static void __AXDSPInitCallback(void* task); +static void __AXDSPResumeCallback(void* task); +static void __AXDSPDoneCallback(void* task); + +void __AXOutNewFrame(u32 lessDspCycles) { + u32 cl; + AXPROFILE* profile; + u8* src; + u8* dest; + u32 i; + + __AXLocalProfile.axFrameStart = OSGetTime(); + __AXSyncPBs(lessDspCycles); + __AXPrintStudio(); + cl = __AXGetCommandListAddress(); + + DSPSendMailToDSP(0xBABE0180); + do {} while (DSPCheckMailToDSP() != 0); + + DSPSendMailToDSP(cl); + do {} while (DSPCheckMailToDSP() != 0); + + __AXServiceCallbackStack(); + __AXLocalProfile.auxProcessingStart = OSGetTime(); + __AXProcessAux(); + __AXLocalProfile.auxProcessingEnd = OSGetTime(); + __AXLocalProfile.userCallbackStart = OSGetTime(); + + if (__AXUserFrameCallback) { + __AXUserFrameCallback(); + } + + __AXLocalProfile.userCallbackEnd = OSGetTime(); + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[__AXOutFrame][0]); + __AXOutFrame += 1; + + if (__AXOutputBufferMode == 1) { + __AXOutFrame %= 3; + } else { + __AXOutFrame &= 1; + AIInitDMA((u32)&__AXOutBuffer[__AXOutFrame][0], 0x280); + } + + __AXLocalProfile.axFrameEnd = OSGetTime(); + __AXLocalProfile.axNumVoices = __AXGetNumVoices(); + profile = (void*)__AXGetCurrentProfile(); + + if (profile) { + i = 56; + dest = (u8*)profile; + src = (u8*)&__AXLocalProfile; + + while (i != 0) { + *dest = *src; + dest++; + src++; + i--; + } + } +} + +void __AXOutAiCallback(void) { + if (__AXOutDspReady == 0) { + __AXOsTime = OSGetTime(); + } + + if (__AXOutDspReady == 1) { + __AXOutDspReady = 0; + __AXOutNewFrame(0); + } else { + __AXOutDspReady = 2; + DSPAssertTask(&__AXDSPTask); + } + + if (__AXOutputBufferMode == 1) { + AIInitDMA((u32)__AXOutBuffer[__AXAiDmaFrame], 0x280); + __AXAiDmaFrame++; + __AXAiDmaFrame %= 3; + } +} + +static void __AXDSPInitCallback(void* task) { + __AXDSPInitFlag = 1; +} + +void AXSetStepMode(u32 i) { + __AXDebugSteppingMode = i; +} + +static void __AXDSPResumeCallback(void* task) { +#if DEBUG + if (__AXDebugSteppingMode != 0) { + __AXOutDspReady = 1; + return; + } +#endif + + if (__AXOutDspReady == 2) { + __AXOutDspReady = 0; + __AXOutNewFrame((u32)(OSGetTime() - __AXOsTime) / 4); + return; + } + __AXOutDspReady = 1; +} + +static void __AXDSPDoneCallback(void* task) { + __AXDSPDoneFlag = 1; + OSWakeupThread(&__AXOutThreadQueue); +} + +#define BUFFER_MEMSET(buffer, size) \ + { \ + u32* p = (u32*)&buffer; \ + int i; \ + for (i = 0; i < size; i++) { \ + *p = 0; \ + p++; \ + } \ + } + +void __AXOutInitDSP(void) { + __AXDSPTask.iram_mmem_addr = axDspSlave; + __AXDSPTask.iram_length = axDspSlaveLength; + __AXDSPTask.iram_addr = 0; + __AXDSPTask.dram_mmem_addr = __AXDramImage; + __AXDSPTask.dram_length = 0x2000; + __AXDSPTask.dram_addr = 0; + __AXDSPTask.dsp_init_vector = 0x10; + __AXDSPTask.dsp_resume_vector = 0x30; + __AXDSPTask.init_cb = __AXDSPInitCallback; + __AXDSPTask.res_cb = __AXDSPResumeCallback; + __AXDSPTask.done_cb = __AXDSPDoneCallback; + __AXDSPTask.req_cb = NULL; + __AXDSPTask.priority = 0; + __AXDSPInitFlag = 0; + __AXDSPDoneFlag = 0; + + OSInitThreadQueue(&__AXOutThreadQueue); + if (DSPCheckInit() == 0) { + DSPInit(); + } + + DSPAddTask(&__AXDSPTask); + do {} while (__AXDSPInitFlag == 0); +} + +void __AXOutInit(u32 outputBufferMode) { +#ifdef DEBUG + OSReport("Initializing AXOut code module\n"); +#endif + ASSERTLINE(404, ((u32)&__AXOutBuffer[0][0] & 0x1F) == 0); + ASSERTLINE(405, ((u32)&__AXOutBuffer[1][0] & 0x1F) == 0); + ASSERTLINE(406, ((u32)&__AXOutBuffer[2][0] & 0x1F) == 0); + ASSERTLINE(407, ((u32)&__AXOutSBuffer[0] & 0x1F) == 0); + + __AXOutputBufferMode = outputBufferMode; + __AXOutFrame = 0; + __AXAiDmaFrame = 0; + __AXDebugSteppingMode = 0; + + BUFFER_MEMSET(__AXOutBuffer, 0x1E0); + DCFlushRange(__AXOutBuffer, sizeof(__AXOutBuffer)); + + BUFFER_MEMSET(__AXOutSBuffer, 0xA0); + DCFlushRange(__AXOutSBuffer, sizeof(__AXOutSBuffer)); + + __AXOutInitDSP(); + AIRegisterDMACallback(__AXOutAiCallback); + + if (__AXOutputBufferMode == 1) { + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[2][0]); + } else { + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[1][0]); + } + + __AXOutDspReady = 1; + __AXUserFrameCallback = NULL; + + if (__AXOutputBufferMode == 1) { + AIInitDMA((u32)&__AXOutBuffer[__AXAiDmaFrame][0], sizeof(__AXOutBuffer[0])); + __AXAiDmaFrame++; + __AXAiDmaFrame &= 1; + } else { + AIInitDMA((u32)&__AXOutBuffer[__AXOutFrame][0], sizeof(__AXOutBuffer[0])); + } + + AIStartDMA(); +} + +void __AXOutQuit(void) { + BOOL old; +#ifdef DEBUG + OSReport("Shutting down AXOut code module\n"); +#endif + old = OSDisableInterrupts(); + __AXUserFrameCallback = NULL; + DSPCancelTask(&__AXDSPTask); + OSSleepThread(&__AXOutThreadQueue); + AIStopDMA(); + OSRestoreInterrupts(old); +} + +AXCallback AXRegisterCallback(AXCallback callback) { + BOOL enabled; + AXCallback oldCB; + + oldCB = __AXUserFrameCallback; + enabled = OSDisableInterrupts(); + __AXUserFrameCallback = callback; + + OSRestoreInterrupts(enabled); + return oldCB; +} diff --git a/src/dolphin/ax/src/AXProf.c b/src/dolphin/ax/src/AXProf.c new file mode 100644 index 0000000..316cadf --- /dev/null +++ b/src/dolphin/ax/src/AXProf.c @@ -0,0 +1,47 @@ +#include +#include + +#include "__ax.h" + +static AXPROFILE* __AXProfile; +static u32 __AXMaxProfiles; +static u32 __AXCurrentProfile; +static u32 __AXProfileInitialized; + +AXPROFILE* __AXGetCurrentProfile(void) { + AXPROFILE* profile; + + if (__AXProfileInitialized != 0) { + profile = &__AXProfile[__AXCurrentProfile]; + __AXCurrentProfile += 1; + __AXCurrentProfile %= __AXMaxProfiles; + return profile; + } + + return 0; +} + +void AXInitProfile(AXPROFILE* profile, u32 maxProfiles) { + ASSERTLINE(60, profile); + ASSERTLINE(61, maxProfiles); + + __AXProfile = profile; + __AXMaxProfiles = maxProfiles; + __AXCurrentProfile = 0; + __AXProfileInitialized = 1; +} + +u32 AXGetProfile(void) { + BOOL old; + u32 n; + + old = OSDisableInterrupts(); + n = __AXCurrentProfile; + if (n != 0) { + n -= 1; + } + + __AXCurrentProfile = 0; + OSRestoreInterrupts(old); + return n; +} diff --git a/src/dolphin/ax/src/AXSPB.c b/src/dolphin/ax/src/AXSPB.c new file mode 100644 index 0000000..3ff765d --- /dev/null +++ b/src/dolphin/ax/src/AXSPB.c @@ -0,0 +1,91 @@ +#include +#include + +#include "__ax.h" + +static AXSPB __AXStudio ATTRIBUTE_ALIGN(32); + +static s32 __AXSpbAL; +static s32 __AXSpbAR; +static s32 __AXSpbAS; +static s32 __AXSpbAAL; +static s32 __AXSpbAAR; +static s32 __AXSpbAAS; +static s32 __AXSpbABL; +static s32 __AXSpbABR; +static s32 __AXSpbABS; + +u32 __AXGetStudio(void) { + return (u32)&__AXStudio; +} + +void __AXDepopFade(s32* hostSum, s32* dspVolume, s16* dspDelta) { + int frames; + s32 delta; + + frames = *hostSum / 160; + + if (frames) { + delta = *hostSum / 160; + if (delta > 0x14) { + delta = 0x14; + } + if (delta < -0x14) { + delta = -0x14; + } + *dspVolume = *hostSum; + *hostSum -= delta* 0xA0; + *dspDelta = delta * -1; + return; + } + + *hostSum = 0; + *dspVolume = 0; + *dspDelta = 0; +} + +void __AXPrintStudio(void) { + __AXDepopFade(&__AXSpbAL, (void*)&__AXStudio.dpopLHi, &__AXStudio.dpopLDelta); + __AXDepopFade(&__AXSpbAR, (void*)&__AXStudio.dpopRHi, &__AXStudio.dpopRDelta); + __AXDepopFade(&__AXSpbAS, (void*)&__AXStudio.dpopSHi, &__AXStudio.dpopSDelta); + __AXDepopFade(&__AXSpbAAL, (void*)&__AXStudio.dpopALHi, &__AXStudio.dpopALDelta); + __AXDepopFade(&__AXSpbAAR, (void*)&__AXStudio.dpopARHi, &__AXStudio.dpopARDelta); + __AXDepopFade(&__AXSpbAAS, (void*)&__AXStudio.dpopASHi, &__AXStudio.dpopASDelta); + __AXDepopFade(&__AXSpbABL, (void*)&__AXStudio.dpopBLHi, &__AXStudio.dpopBLDelta); + __AXDepopFade(&__AXSpbABR, (void*)&__AXStudio.dpopBRHi, &__AXStudio.dpopBRDelta); + __AXDepopFade(&__AXSpbABS, (void*)&__AXStudio.dpopBSHi, &__AXStudio.dpopBSDelta); + DCFlushRange(&__AXStudio, sizeof(__AXStudio)); +} + +void __AXSPBInit(void) { +#ifdef DEBUG + OSReport("Initializing AXSPB code module\n"); +#endif + __AXSpbAL = + __AXSpbAR = + __AXSpbAS = + __AXSpbAAL = + __AXSpbAAR = + __AXSpbAAS = + __AXSpbABL = + __AXSpbABR = + __AXSpbABS = 0; +} + +void __AXSPBQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXSPB code module\n"); +#endif +} + +void __AXDepopVoice(AXPB* p) { + __AXSpbAL += p->dpop.aL; + __AXSpbAAL += p->dpop.aAuxAL; + __AXSpbABL += p->dpop.aAuxBL; + __AXSpbAR += p->dpop.aR; + __AXSpbAAR += p->dpop.aAuxAR; + __AXSpbABR += p->dpop.aAuxBR; + __AXSpbAS += p->dpop.aS; + __AXSpbAAS += p->dpop.aAuxAS; + __AXSpbABS += p->dpop.aAuxBS; +} diff --git a/src/dolphin/ax/src/AXVPB.c b/src/dolphin/ax/src/AXVPB.c new file mode 100644 index 0000000..8c51a48 --- /dev/null +++ b/src/dolphin/ax/src/AXVPB.c @@ -0,0 +1,1412 @@ +#include +#include +#include + +#include "__ax.h" + +static u32 __AXSrcCycles[5] = { 0x00000DF8, 0x00000F78, 0x000014B8, 0x000019F8, 0x000019F8 }; + +static u32 __AXMainMixCycles[16] = { 0x00000000, 0x000002F8, 0x000002F8, 0x000005BE, + 0x000002F8, 0x000005F0, 0x000005F0, 0x000008B6, + 0x00000000, 0x000004F1, 0x000004F1, 0x000009A6, + 0x000004F1, 0x000009E2, 0x000009E2, 0x00000E97 }; + +static u32 __AXAuxMixCycles[32] = { + 0x00000000, 0x000002F8, 0x000002F8, 0x000005BE, 0x00000000, 0x000004F1, 0x000004F1, 0x000009A6, + 0x000002F8, 0x000005F0, 0x000005F0, 0x000008B6, 0x000002F8, 0x000007E9, 0x000007E9, 0x00000C9E, + 0x00000000, 0x000002F8, 0x000002F8, 0x000005BE, 0x00000000, 0x000004F1, 0x000004F1, 0x000009A6, + 0x000004F1, 0x000007E9, 0x000007E9, 0x00000AAF, 0x000004F1, 0x000009E2, 0x000009E2, 0x00000E97 +}; + +static AXPB __AXPB[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXPBITDBUFFER __AXITD[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXPBU __AXUpdates[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXVPB __AXVPB[AX_MAX_VOICES]; + +static u32 __AXMaxDspCycles; +static u32 __AXRecDspCycles; +static u32 __AXNumVoices; + +u32 __AXGetNumVoices(void) +{ + return __AXNumVoices; +} + +void __AXServiceVPB(AXVPB* pvpb) +{ + AXPB* ppbDsp; + AXPB* ppbUser; + u32 sync; + + ASSERTLINE(238, (pvpb->index >= 0) && (pvpb->index < AX_MAX_VOICES)); + + __AXNumVoices += 1; + ppbDsp = &__AXPB[pvpb->index]; + ppbUser = &pvpb->pb; + sync = pvpb->sync; + if (sync == 0) + { + ppbUser->state = ppbDsp->state; + ppbUser->ve.currentVolume = ppbDsp->ve.currentVolume; + ppbUser->addr.currentAddressHi = ppbDsp->addr.currentAddressHi; + ppbUser->addr.currentAddressLo = ppbDsp->addr.currentAddressLo; + return; + } + if (sync & AX_SYNC_FLAG_COPYALL) + { + // copy the whole PB struct. (size: 0xF4) + u32* src; + u32* dst; + src = (void*)ppbUser; + dst = (void*)ppbDsp; + + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + + if (pvpb->updateCounter != 0) + { + u32 count; + src = (void*)&__AXUpdates[pvpb->index]; + dst = (void*)pvpb->updateData; + for (count = pvpb->updateCounter; count; count--) + { + *(dst) = *(src); + dst += 1; + src += 1; + } + } + return; + } + + if (sync & AX_SYNC_FLAG_COPYSELECT) + { + ppbDsp->srcSelect = ppbUser->srcSelect; + ppbDsp->coefSelect = ppbUser->coefSelect; + } + + if (sync & AX_SYNC_FLAG_COPYMXRCTRL) + { + ppbDsp->mixerCtrl = ppbUser->mixerCtrl; + } + + if (sync & AX_SYNC_FLAG_COPYSTATE) + { + ppbDsp->state = ppbUser->state; + } + else + { + ppbUser->state = ppbDsp->state; + } + + if (sync & AX_SYNC_FLAG_COPYTYPE) + { + ppbDsp->type = ppbUser->type; + } + + if (sync & AX_SYNC_FLAG_COPYAXPBMIX) + { + // copy AXPBMIX. + u16* src; + u16* dst; + src = (void*)&ppbUser->mix; + dst = (void*)&ppbDsp->mix; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + } + + if (sync & AX_SYNC_FLAG_COPYTSHIFT) + { + ppbDsp->itd.targetShiftL = ppbUser->itd.targetShiftL; + ppbDsp->itd.targetShiftR = ppbUser->itd.targetShiftR; + } + else if (sync & AX_SYNC_FLAG_COPYITD) + { + // copy ITD struct. + u16* src; + u16* dst; + u32* dst_; + src = (void*)&ppbUser->itd; + dst = (void*)&ppbDsp->itd; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + src += 1; + + dst; // fixes reg alloc + dst_ = pvpb->itdBuffer; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + dst_ += 1; + *(dst_) = 0; + } + + if (sync & AX_SYNC_FLAG_COPYUPDATE) + { + // copy UPDATE struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->update; + src = (void*)&ppbUser->update; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + + if (pvpb->updateCounter) + { + u32* src_; + u32* dst_; + u32 count; + + dst_ = (void*)&__AXUpdates[pvpb->index]; + src_ = (void*)&pvpb->updateData; + + for (count = pvpb->updateCounter; count; count--) + { + *(dst_) = *(src_); + dst_ += 1; + src_ += 1; + } + } + } + + if (sync & AX_SYNC_FLAG_COPYDPOP) + { + // copy DPOP struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->dpop; + src = (void*)&ppbUser->dpop; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + } + + if (sync & AX_SYNC_FLAG_SWAPVOL) + { + ppbUser->ve.currentVolume = ppbDsp->ve.currentVolume; + ppbDsp->ve.currentDelta = ppbUser->ve.currentDelta; + } + else if (sync & AX_SYNC_FLAG_COPYVOL) + { + ppbDsp->ve.currentVolume = ppbUser->ve.currentVolume; + ppbDsp->ve.currentDelta = ppbUser->ve.currentDelta; + } + + if (sync & AX_SYNC_FLAG_COPYFIR) + { + // copy FIR struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->fir; + src = (void*)&ppbUser->fir; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + } + + if (sync & (AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | + AX_SYNC_FLAG_COPYCURADDR)) + { + if (sync & AX_SYNC_FLAG_COPYLOOP) + { + ppbDsp->addr.loopFlag = ppbUser->addr.loopFlag; + } + if (sync & AX_SYNC_FLAG_COPYLOOPADDR) + { + *(u32*)&ppbDsp->addr.loopAddressHi = *(u32*)&ppbUser->addr.loopAddressHi; + } + if (sync & AX_SYNC_FLAG_COPYENDADDR) + { + *(u32*)&ppbDsp->addr.endAddressHi = *(u32*)&ppbUser->addr.endAddressHi; + } + if (sync & AX_SYNC_FLAG_COPYCURADDR) + { + *(u32*)&ppbDsp->addr.currentAddressHi = *(u32*)&ppbUser->addr.currentAddressHi; + } + else + { + *(u32*)&ppbUser->addr.currentAddressHi = *(u32*)&ppbDsp->addr.currentAddressHi; + } + } + else if (sync & AX_SYNC_FLAG_COPYADDR) + { + // copy ADDR struct. + u32* src; + u32* dst; + dst = (void*)&ppbDsp->addr; + src = (void*)&ppbUser->addr; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + } + else + { + ppbUser->addr.currentAddressHi = ppbDsp->addr.currentAddressHi; + ppbUser->addr.currentAddressLo = ppbDsp->addr.currentAddressLo; + } + + if (sync & AX_SYNC_FLAG_COPYADPCM) + { + // copy ADPCM struct. + u32* src; + u32* dst; + dst = (void*)&ppbDsp->adpcm; + src = (void*)&ppbUser->adpcm; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + } + + if (sync & AX_SYNC_FLAG_COPYRATIO) + { + ppbDsp->src.ratioHi = ppbUser->src.ratioHi; + ppbDsp->src.ratioLo = ppbUser->src.ratioLo; + } + else if (sync & AX_SYNC_FLAG_COPYSRC) + { + // copy SRC struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->src; + src = (void*)&ppbUser->src; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + } + + if (sync & AX_SYNC_FLAG_COPYADPCMLOOP) + { + // copy ADPCMLOOP struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->adpcmLoop; + src = (void*)&ppbUser->adpcmLoop; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + } + + if (sync & 0x400000) + { + ppbDsp->lpf.a0 = ppbUser->lpf.a0; + ppbDsp->lpf.b0 = ppbUser->lpf.b0; + return; + } + + if (sync & 0x200000) + { + // copy AXPBLPF struct + u16* src; + u16* dst; + + dst = (void*)&ppbDsp->lpf; + src = (void*)&ppbUser->lpf; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + } +} + +void __AXDumpVPB(AXVPB* pvpb) +{ + AXPB* ppbDsp; + + ppbDsp = &__AXPB[pvpb->index]; + if (ppbDsp->state == 1) + { + __AXDepopVoice(ppbDsp); + } + pvpb->pb.state = ppbDsp->state = ppbDsp->update.updNum[0] = ppbDsp->update.updNum[1] = + ppbDsp->update.updNum[2] = ppbDsp->update.updNum[3] = ppbDsp->update.updNum[4] = 0; + __AXPushCallbackStack(pvpb); +} + +void __AXSyncPBs(u32 lessDlpfycles) +{ + u32 cycles; + u32 i; + AXVPB* pvpb; + + __AXNumVoices = 0; + DCInvalidateRange(__AXPB, sizeof(__AXPB)); + DCInvalidateRange(__AXITD, sizeof(__AXITD)); + cycles = (__AXGetCommandListCycles() + 0x10000) - 0x55F0 + lessDlpfycles; + + for (i = 31; i; i--) + { + for (pvpb = __AXGetStackHead(i); pvpb; pvpb = pvpb->next) + { + if (pvpb->depop != 0) + { + __AXDepopVoice(&__AXPB[pvpb->index]); + } + + if ((pvpb->pb.state == 1) || (pvpb->updateCounter != 0)) + { + if (pvpb->pb.srcSelect != 2) + { + cycles += __AXSrcCycles[pvpb->pb.src.ratioHi]; + } + + if (pvpb->pb.lpf.on) + { + cycles += 555; + } + + cycles += __AXMainMixCycles[pvpb->pb.mixerCtrl & 0xF] + + __AXAuxMixCycles[(pvpb->pb.mixerCtrl >> 4) & 0x1F] + + __AXAuxMixCycles[(pvpb->pb.mixerCtrl >> 9) & 0x1F] + 0x8C; + if (__AXMaxDspCycles > cycles) + { + __AXServiceVPB(pvpb); + } + else + { + __AXDumpVPB(pvpb); + } + } + else + { + __AXServiceVPB(pvpb); + } + + pvpb->sync = 0; + pvpb->depop = 0; + pvpb->updateMS = pvpb->updateCounter = 0; + pvpb->updateWrite = pvpb->updateData; + } + } + + __AXRecDspCycles = cycles; + for (pvpb = __AXGetStackHead(0); pvpb; pvpb = pvpb->next) + { + if (pvpb->depop != 0) + { + __AXDepopVoice(&__AXPB[pvpb->index]); + } + pvpb->depop = 0; + __AXPB[pvpb->index].state = __AXPB[pvpb->index].update.updNum[0] = + __AXPB[pvpb->index].update.updNum[1] = __AXPB[pvpb->index].update.updNum[2] = + __AXPB[pvpb->index].update.updNum[3] = __AXPB[pvpb->index].update.updNum[4] = 0; + } + + DCFlushRange(__AXPB, sizeof(__AXPB)); + DCFlushRange(__AXITD, sizeof(__AXITD)); + DCFlushRange(__AXUpdates, sizeof(__AXUpdates)); +} + +AXPB* __AXGetPBs(void) +{ + return __AXPB; +} + +void __AXSetPBDefault(AXVPB* p) +{ + p->pb.state = 0; + p->pb.itd.flag = 0; + p->sync = 0x2000A4; + p->updateMS = p->updateCounter = 0; + p->updateWrite = p->updateData; + p->pb.update.updNum[0] = p->pb.update.updNum[1] = p->pb.update.updNum[2] = + p->pb.update.updNum[3] = p->pb.update.updNum[4] = 0; + p->pb.lpf.on = 0; +} + +void __AXVPBInit(void) +{ + u32 i; + AXPB* ppb; + AXPBITDBUFFER* ppbi; + AXPBU* ppbu; + AXVPB* pvpb; + u32* p; + +#ifdef DEBUG + OSReport("Initializing AXVPB code module\n"); +#endif + __AXMaxDspCycles = OS_BUS_CLOCK / 400; + __AXRecDspCycles = 0; + +#define BUFFER_MEMSET(buffer, size) \ + { \ + p = (u32*)&buffer; \ + for (i = size; i != 0; i--) \ + { \ + *p = 0; \ + p++; \ + } \ + } + + BUFFER_MEMSET(__AXPB, 0xF40); + BUFFER_MEMSET(__AXITD, 0x400); + BUFFER_MEMSET(__AXVPB, 0x22C0); + + for (i = 0; i < AX_MAX_VOICES; i++) + { + ppb = &__AXPB[i]; + ppbi = &__AXITD[i]; + ppbu = &__AXUpdates[i]; + pvpb = &__AXVPB[i]; + + ASSERTLINE(913, (u32)ppb ^ 0x1F); + ASSERTLINE(914, (u32)ppbi ^ 0x1F); + ASSERTLINE(915, (u32)ppbu ^ 0x1F); + + pvpb->index = i; + pvpb->updateWrite = pvpb->updateData; + pvpb->itdBuffer = ppbi; + __AXSetPBDefault(pvpb); + + if (i == 0x3F) + { + pvpb->pb.nextHi = pvpb->pb.nextLo = ppb->nextHi = ppb->nextLo = 0; + } + else + { + pvpb->pb.nextHi = (u16)((u32)((char*)ppb + sizeof(AXPB)) >> 16); + pvpb->pb.nextLo = (u16)((u32)((char*)ppb + sizeof(AXPB))); + ppb->nextHi = (u16)((u32)((char*)ppb + sizeof(AXPB)) >> 16); + ppb->nextLo = (u16)((u32)((char*)ppb + sizeof(AXPB))); + } + + pvpb->pb.currHi = (u16)(((u32)ppb) >> 16); + pvpb->pb.currLo = (u16)((u32)ppb); + ppb->currHi = (u16)(((u32)ppb) >> 16); + ppb->currLo = (u16)((u32)ppb); + pvpb->pb.itd.bufferHi = (u16)(((u32)ppbi) >> 16); + pvpb->pb.itd.bufferLo = (u16)((u32)ppbi); + ppb->itd.bufferHi = (u16)(((u32)ppbi) >> 16); + ppb->itd.bufferLo = (u16)((u32)ppbi); + pvpb->pb.update.dataHi = (u16)(((u32)ppbu) >> 16); + pvpb->pb.update.dataLo = (u16)((u32)ppbu); + ppb->update.dataHi = (u16)(((u32)ppbu) >> 16); + ppb->update.dataLo = (u16)((u32)ppbu); + + pvpb->priority = 1; + __AXPushFreeStack(pvpb); + } + + DCFlushRange(__AXPB, sizeof(__AXPB)); +} + +void __AXVPBQuit(void) +{ +#ifdef DEBUG + OSReport("Shutting down AXVPB code module\n"); +#endif +} + +void AXSetVoiceSrcType(AXVPB* p, u32 type) +{ + BOOL old; + AXPB* ppb; + + ASSERTLINE(1020, p); + ASSERTLINE(1021, type <= AX_SRC_TYPE_4TAP_16K); + + old = OSDisableInterrupts(); + ppb = &p->pb; + switch (type) + { + case AX_SRC_TYPE_NONE: + ppb->srcSelect = 2; + break; + case AX_SRC_TYPE_LINEAR: + ppb->srcSelect = 1; + break; + case AX_SRC_TYPE_4TAP_8K: + ppb->srcSelect = 0; + ppb->coefSelect = 0; + break; + case AX_SRC_TYPE_4TAP_12K: + ppb->srcSelect = 0; + ppb->coefSelect = 1; + break; + case AX_SRC_TYPE_4TAP_16K: + ppb->srcSelect = 0; + ppb->coefSelect = 2; + break; + } + + p->sync |= AX_SYNC_FLAG_COPYSELECT; + OSRestoreInterrupts(old); +} + +void AXSetVoiceState(AXVPB* p, u16 state) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.state = state; + p->sync |= AX_SYNC_FLAG_COPYSTATE; + if (state == 0) + { + p->depop = 1; + } + OSRestoreInterrupts(old); +} + +void AXSetVoiceType(AXVPB* p, u16 type) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.type = type; + p->sync |= AX_SYNC_FLAG_COPYTYPE; + OSRestoreInterrupts(old); +} + +void AXSetVoiceMix(AXVPB* p, AXPBMIX* mix) +{ + BOOL old; + u16 mixerCtrl; + u16* dst; + u16* src; + + src = (u16*)mix; + dst = (u16*)&p->pb.mix; + mixerCtrl = 0; + + old = OSDisableInterrupts(); + + if ((*dst++ = *src++)) + mixerCtrl |= 0x1; + if ((*dst++ = *src++)) + mixerCtrl |= 0x9; + if ((*dst++ = *src++)) + mixerCtrl |= 0x2; + if ((*dst++ = *src++)) + mixerCtrl |= 0xA; + if ((*dst++ = *src++)) + mixerCtrl |= 0x10; + if ((*dst++ = *src++)) + mixerCtrl |= 0x50; + if ((*dst++ = *src++)) + mixerCtrl |= 0x20; + if ((*dst++ = *src++)) + mixerCtrl |= 0x60; + if ((*dst++ = *src++)) + mixerCtrl |= 0x200; + if ((*dst++ = *src++)) + mixerCtrl |= 0xA00; + if ((*dst++ = *src++)) + mixerCtrl |= 0x400; + if ((*dst++ = *src++)) + mixerCtrl |= 0xC00; + if ((*dst++ = *src++)) + mixerCtrl |= 0x1000; + if ((*dst++ = *src++)) + mixerCtrl |= 0x3000; + if ((*dst++ = *src++)) + mixerCtrl |= 0x4; + if ((*dst++ = *src++)) + mixerCtrl |= 0xC; + if ((*dst++ = *src++)) + mixerCtrl |= 0x80; + if ((*dst++ = *src++)) + mixerCtrl |= 0x180; + + p->pb.mixerCtrl = mixerCtrl; + p->sync |= (AX_SYNC_FLAG_COPYAXPBMIX | AX_SYNC_FLAG_COPYMXRCTRL); + OSRestoreInterrupts(old); +} + +void AXSetVoiceItdOn(AXVPB* p) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.itd.flag = 1; + p->pb.itd.shiftL = p->pb.itd.shiftR = p->pb.itd.targetShiftL = p->pb.itd.targetShiftR = 0; + p->sync &= ~(AX_SYNC_FLAG_COPYTSHIFT); + p->sync |= AX_SYNC_FLAG_COPYITD; + OSRestoreInterrupts(old); +} + +void AXSetVoiceItdTarget(AXVPB* p, u16 lShift, u16 rShift) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.itd.targetShiftL = lShift; + p->pb.itd.targetShiftR = rShift; + p->sync |= AX_SYNC_FLAG_COPYTSHIFT; + OSRestoreInterrupts(old); +} + +void AXSetVoiceUpdateIncrement(AXVPB* p) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->updateMS++; + p->sync |= AX_SYNC_FLAG_COPYUPDATE; + ASSERTMSGLINE(1191, p->updateMS <= 4, "PB updates cannot exceed 5ms\n"); + OSRestoreInterrupts(old); +} + +void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->updateCounter += 2; + ASSERTMSGLINE(1205, p->updateCounter <= 128, "PB update block exceeded 128 words\n"); + + *(p->updateWrite) = param; + p->updateWrite += 1; + *(p->updateWrite) = data; + p->updateWrite += 1; + p->sync |= AX_SYNC_FLAG_COPYUPDATE; + OSRestoreInterrupts(old); +} + +void AXSetVoiceDpop(AXVPB* p, AXPBDPOP* dpop) +{ + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.dpop; + src = (void*)dpop; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + } + p->sync |= AX_SYNC_FLAG_COPYDPOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceVe(AXVPB* p, AXPBVE* ve) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.ve.currentVolume = ve->currentVolume; + p->pb.ve.currentDelta = ve->currentDelta; + p->sync |= AX_SYNC_FLAG_COPYVOL; + OSRestoreInterrupts(old); +} + +void AXSetVoiceVeDelta(AXVPB* p, s16 delta) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.ve.currentDelta = delta; + p->sync |= AX_SYNC_FLAG_SWAPVOL; + OSRestoreInterrupts(old); +} + +void AXSetVoiceFir(AXVPB* p, AXPBFIR* fir) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.fir.numCoefs = fir->numCoefs; + p->pb.fir.coefsHi = fir->coefsHi; + p->pb.fir.coefsLo = fir->coefsLo; + p->sync |= AX_SYNC_FLAG_COPYFIR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr) +{ + BOOL old; + u32* dst; + u32* src; + + dst = (void*)&p->pb.addr; + src = (void*)addr; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + } + + switch (addr->format) + { + case 0: + ASSERTMSGLINE(1335, (addr->loopAddressLo & 0xF) > 1, + "*** loop address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(1340, (addr->endAddressLo & 0xF) > 1, + "*** end address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(1345, (addr->currentAddressLo & 0xF) > 1, + "*** current address on ADPCM frame header! ***\n"); + break; + case 10: + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0x08000000; + dst += 1; + *(dst) = 0; + dst += 1; + break; + case 25: + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0; + dst += 1; + *(dst) = 0x01000000; + dst += 1; + *(dst) = 0; + dst += 1; + break; + default: + ASSERTMSGLINE(1389, 0, "unknown addr->formaqt in PB\n"); + break; + } + + p->sync &= ~(AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | + AX_SYNC_FLAG_COPYCURADDR); + p->sync |= (AX_SYNC_FLAG_COPYADDR | AX_SYNC_FLAG_COPYADPCM); + OSRestoreInterrupts(old); +} + +void AXSetVoiceLoop(AXVPB* p, u16 loop) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.loopFlag = loop; + p->sync |= AX_SYNC_FLAG_COPYLOOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceLoopAddr(AXVPB* p, u32 addr) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.loopAddressHi = (addr >> 0x10); + p->pb.addr.loopAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYLOOPADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceEndAddr(AXVPB* p, u32 addr) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.endAddressHi = (addr >> 0x10); + p->pb.addr.endAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYENDADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceCurrentAddr(AXVPB* p, u32 addr) +{ + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.currentAddressHi = (addr >> 0x10); + p->pb.addr.currentAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYCURADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAdpcm(AXVPB* p, AXPBADPCM* adpcm) +{ + BOOL old; + u32* dst; + u32* src; + + dst = (void*)&p->pb.adpcm; + src = (void*)adpcm; + + old = OSDisableInterrupts(); + + { + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + } + p->sync |= AX_SYNC_FLAG_COPYADPCM; + OSRestoreInterrupts(old); +} + +void AXSetVoiceSrc(AXVPB* p, AXPBSRC* src_) +{ + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.src; + src = (void*)src_; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + } + p->sync &= ~(AX_SYNC_FLAG_COPYRATIO); + p->sync |= AX_SYNC_FLAG_COPYSRC; + OSRestoreInterrupts(old); +} + +void AXSetVoiceSrcRatio(AXVPB* p, float ratio) +{ + u32 r; + BOOL old; + + old = OSDisableInterrupts(); + r = 65536.0f * ratio; + if (r > 0x40000) + { + r = 0x40000; + } + p->pb.src.ratioHi = ((u32)r >> 0x10); + p->pb.src.ratioLo = ((u32)r); + p->sync |= AX_SYNC_FLAG_COPYRATIO; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAdpcmLoop(AXVPB* p, AXPBADPCMLOOP* adpcmloop) +{ + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.adpcmLoop; + src = (void*)adpcmloop; + old = OSDisableInterrupts(); + { + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + *(dst) = *(src); + dst += 1; + src += 1; + } + p->sync |= AX_SYNC_FLAG_COPYADPCMLOOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceLpf(AXVPB* p, AXPBLPF* lpf) +{ + BOOL old; + u16* dst; + u16* src; + + dst = (u16*)&p->pb.lpf; + src = (u16*)lpf; + + old = OSDisableInterrupts(); + + *dst = *src; + dst++; + src++; + *dst = *src; + dst++; + src++; + *dst = *src; + dst++; + src++; + *dst = *src; + dst++; + src++; + p->sync |= 0x200000; + + OSRestoreInterrupts(old); +} + +void AXSetVoiceLpfCoefs(AXVPB* p, u16 a0, u16 b0) +{ + BOOL old; + old = OSDisableInterrupts(); + + p->pb.lpf.a0 = a0; + p->pb.lpf.b0 = b0; + p->sync |= 0x400000; + + OSRestoreInterrupts(old); +} + +#define PI 3.14159265358979323846f + +void AXGetLpfCoefs(u16 freq, u16* a0, u16* b0) +{ + f32 bb; + f32 cc; + + ASSERTMSGLINE(1616, freq <= 16000, "freq is out of range"); + + cc = 2.0f - cos(((PI * 2) * (f32)freq) / 32000.0f); + bb = sqrt((cc * cc) - 1.0f) - cc; + + *b0 = 32768.0f * -bb; + *a0 = 0x7FFF - *b0; +} + +void AXSetMaxDspCycles(u32 cycles) +{ + __AXMaxDspCycles = cycles; +} + +u32 AXGetMaxDspCycles(void) +{ + return __AXMaxDspCycles; +} + +u32 AXGetDspCycles(void) +{ + return __AXRecDspCycles; +} diff --git a/src/dolphin/ax/src/DSPCode.c b/src/dolphin/ax/src/DSPCode.c new file mode 100644 index 0000000..d54b0de --- /dev/null +++ b/src/dolphin/ax/src/DSPCode.c @@ -0,0 +1,669 @@ +#include +#include + +u16 axDspSlaveLength = (AX_DSP_SLAVE_LENGTH * 2); + +u16 axDspSlave[AX_DSP_SLAVE_LENGTH] ATTRIBUTE_ALIGN(32) = { + 0x0000, 0x0000, 0x029F, 0x0E88, 0x029F, 0x0E97, + 0x029F, 0x0EB3, 0x029F, 0x0ED3, 0x029F, 0x0ED9, + 0x029F, 0x0F0B, 0x029F, 0x0F11, 0x1302, 0x1303, + 0x1204, 0x1305, 0x1306, 0x8E00, 0x8C00, 0x8B00, + 0x0092, 0x00FF, 0x8100, 0x8900, 0x009E, 0x0E80, + 0x00FE, 0x0E1B, 0x8100, 0x00FE, 0x0E31, 0x16FC, + 0xDCD1, 0x16FD, 0x0000, 0x16FB, 0x0001, 0x26FC, + 0x02A0, 0x8000, 0x029C, 0x0029, 0x029F, 0x0045, + 0x1302, 0x1303, 0x1204, 0x1305, 0x1306, 0x8E00, + 0x8C00, 0x8B00, 0x0092, 0x00FF, 0x16FC, 0xDCD1, + 0x16FD, 0x0001, 0x16FB, 0x0001, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x0040, 0x8E00, 0x8100, 0x8900, + 0x009F, 0xBABE, 0x26FE, 0x02C0, 0x8000, 0x029C, + 0x004A, 0x8200, 0x0294, 0x004A, 0x23FF, 0x8100, + 0x26FE, 0x02C0, 0x8000, 0x029C, 0x0054, 0x27FF, + 0x0240, 0x7FFF, 0x2ECE, 0x2FCF, 0x16CD, 0x0C00, + 0x8100, 0x2EC9, 0x1FFB, 0x2FCB, 0x02BF, 0x0652, + 0x0080, 0x0C00, 0x8E00, 0x8100, 0x8970, 0xB100, + 0x0291, 0x007E, 0x0A13, 0xC100, 0x0292, 0x007E, + 0x009F, 0x0C9D, 0x4C00, 0x1C7E, 0x0213, 0x1C7E, + 0x176F, 0x16FC, 0xFBAD, 0x16FD, 0x8080, 0x0021, + 0x16FC, 0xBAAD, 0x2EFD, 0x0021, 0x8D00, 0x8F00, + 0x8A00, 0x8900, 0x8168, 0x0098, 0x0000, 0x0099, + 0x0001, 0x0081, 0x0000, 0x193E, 0x193C, 0x11A0, + 0x009A, 0xA100, 0x8271, 0x0277, 0x1F19, 0x193C, + 0xA100, 0x8271, 0x0277, 0x1F19, 0x193C, 0x1FD8, + 0xB100, 0x0294, 0x00CB, 0x00DE, 0x0E44, 0xB100, + 0x0294, 0x00AB, 0x191C, 0x191C, 0x191C, 0x00E0, + 0x0E45, 0x029F, 0x0114, 0x8B00, 0x7A00, 0x00FE, + 0x0E44, 0x8400, 0x0099, 0x0140, 0x1F1E, 0xA000, + 0x191E, 0x191E, 0x191C, 0x00E0, 0x0E45, 0x009A, + 0x0000, 0x0098, 0x0DC0, 0x4E00, 0x4800, 0x2ECE, + 0x2CCF, 0x009E, 0x0E48, 0x2ECD, 0x0E00, 0x2EC9, + 0x009E, 0x0140, 0x2ECB, 0x029F, 0x00E3, 0x8B00, + 0x00D8, 0x0E44, 0x0099, 0x0140, 0xA000, 0x191E, + 0x00FE, 0x0E44, 0x191E, 0x191C, 0x00E0, 0x0E45, + 0x4E00, 0x2ECE, 0x2CCF, 0x009E, 0x0E48, 0x2ECD, + 0x0E00, 0x2EC9, 0x009E, 0x0140, 0x2ECB, 0x02BF, + 0x0652, 0x8A48, 0x0083, 0x0E48, 0x0080, 0x0000, + 0x0081, 0x0000, 0x1979, 0x193A, 0xB041, 0xA64B, + 0xF051, 0xB441, 0x9100, 0x1150, 0x00FC, 0xA792, + 0xF151, 0xB520, 0x9941, 0xA693, 0xF051, 0xB428, + 0x9141, 0x0083, 0x0E48, 0x0080, 0x0140, 0x0081, + 0x0140, 0x1979, 0x193A, 0xB041, 0xA64B, 0xF051, + 0xB441, 0x9100, 0x1150, 0x0113, 0xA792, 0xF151, + 0xB520, 0x9941, 0xA693, 0xF051, 0xB428, 0x9141, + 0x00C0, 0x0E45, 0x029F, 0x0068, 0x8100, 0x8970, + 0x8E78, 0x2ECE, 0x2FCF, 0x009E, 0x0E48, 0x2ECD, + 0x0E00, 0x2EC9, 0x009E, 0x0040, 0x2ECB, 0x0081, + 0x0E48, 0x0082, 0x0000, 0x009B, 0x009F, 0x009A, + 0x0140, 0x8100, 0x8900, 0x8F00, 0x02BF, 0x0652, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x013C, + 0x005A, 0x1B5E, 0x029F, 0x0144, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0143, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x014E, + 0x005A, 0x1B5E, 0x029F, 0x0156, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0155, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x0160, + 0x005A, 0x1B5E, 0x029F, 0x0168, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0167, 0x4C00, 0x1B5E, 0x1B5C, + 0x0082, 0x0400, 0x193E, 0x193C, 0xB179, 0x0294, + 0x0173, 0x005A, 0x1B5E, 0x029F, 0x017B, 0x9900, + 0x1B5E, 0x1B5C, 0x007B, 0x017A, 0x4C00, 0x1B5E, + 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x0184, + 0x005A, 0x1B5E, 0x029F, 0x018C, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x018B, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB179, 0x0294, 0x0195, 0x005A, + 0x1B5E, 0x029F, 0x019D, 0x9900, 0x1B5E, 0x1B5C, + 0x007B, 0x019C, 0x4C00, 0x1B5E, 0x1B5C, 0x0082, + 0x07C0, 0x193E, 0x193C, 0xB179, 0x0294, 0x01A8, + 0x005A, 0x1B5E, 0x029F, 0x01B0, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x01AF, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB179, 0x0294, 0x01B9, 0x005A, + 0x1B5E, 0x029F, 0x01C1, 0x9900, 0x1B5E, 0x1B5C, + 0x007B, 0x01C0, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, + 0x193C, 0xB179, 0x0294, 0x01CA, 0x005A, 0x1B5E, + 0x029F, 0x01D2, 0x9900, 0x1B5E, 0x1B5C, 0x007B, + 0x01D1, 0x4C00, 0x1B5E, 0x1B5C, 0x029F, 0x0068, + 0x0085, 0xFFFF, 0x8150, 0x8940, 0x8E48, 0x00FA, + 0x0E17, 0x00F8, 0x0E18, 0x0081, 0x0000, 0x02BF, + 0x05E7, 0x00DA, 0x0E17, 0x00D8, 0x0E18, 0x8948, + 0x0081, 0x0400, 0x02BF, 0x05E7, 0x00DA, 0x0E17, + 0x00D8, 0x0E18, 0x8948, 0x0081, 0x07C0, 0x02BF, + 0x05E7, 0x029F, 0x0068, 0x0086, 0x07C0, 0x02BF, + 0x057A, 0x029F, 0x0068, 0x8100, 0x8E00, 0x191E, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0000, 0x16C9, + 0x0001, 0x16CB, 0x0780, 0x02BF, 0x0652, 0x029F, + 0x0068, 0x8100, 0x8970, 0x8E60, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x8900, 0x0D20, + 0x2DCB, 0x4C00, 0x1C80, 0x0080, 0x0280, 0x0081, + 0x0000, 0x0082, 0x0140, 0x0083, 0x0E48, 0x0A00, + 0x27C9, 0x03A0, 0x0004, 0x029C, 0x0222, 0x2ECE, + 0x2CCF, 0x16CD, 0x0E58, 0x16C9, 0x0000, 0x16CB, + 0x0260, 0x009F, 0x00A0, 0x8F00, 0x007F, 0x023B, + 0x197E, 0x1B1A, 0x197C, 0x1B1A, 0x1B5E, 0x7C22, + 0x1B3E, 0x1B3C, 0x1C04, 0x029F, 0x0068, 0x8E70, + 0x8960, 0x191F, 0x2ECE, 0x2CCF, 0x16CD, 0x0C00, + 0x16C9, 0x0000, 0x0503, 0x0340, 0xFFF0, 0x2FCB, + 0x02BF, 0x0652, 0x0080, 0x0C00, 0x029F, 0x0068, + 0x8100, 0x8970, 0x8E78, 0x2ECE, 0x2FCF, 0x16CD, + 0x0B80, 0x16C9, 0x0000, 0x16CB, 0x00C4, 0x0082, + 0x0E08, 0x009F, 0x0000, 0x1B5F, 0x009F, 0x0140, + 0x1B5F, 0x009F, 0x0280, 0x1B5F, 0x009F, 0x0400, + 0x1B5F, 0x009F, 0x0540, 0x1B5F, 0x009F, 0x0680, + 0x1B5F, 0x009F, 0x07C0, 0x1B5F, 0x009F, 0x0900, + 0x1B5F, 0x009F, 0x0A40, 0x1B5F, 0x02BF, 0x0652, + 0x00DE, 0x0BA7, 0x00DF, 0x0BA8, 0x2ECE, 0x2FCF, + 0x16CD, 0x03C0, 0x16C9, 0x0000, 0x16CB, 0x0080, + 0x8100, 0x8900, 0x00DE, 0x0B84, 0x009F, 0x0D21, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E15, 0x00DE, + 0x0B85, 0x009F, 0x0D24, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E16, 0x00DE, 0x0B86, 0x009A, 0x000F, + 0x009F, 0x0CB1, 0x3400, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E14, 0x00DE, 0x0B86, 0x009A, 0x001F, + 0x009F, 0x0CC1, 0x14FC, 0x3400, 0x4C00, 0x1C7E, + 0x0213, 0x00FE, 0x0E46, 0x00DE, 0x0B86, 0x009F, + 0x0CE1, 0x14F7, 0x4C00, 0x1C7E, 0x0213, 0x00FE, + 0x0E47, 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, + 0x02EA, 0x8900, 0x00DF, 0x0B9E, 0x0300, 0x0CC0, + 0x00FF, 0x0E40, 0x00DF, 0x0B9F, 0x0300, 0x0CC0, + 0x00FF, 0x0E41, 0x009F, 0x0CE0, 0x00FF, 0x0E42, + 0x00FF, 0x0E43, 0x02BF, 0x0652, 0x00DE, 0x0B9C, + 0x2ECE, 0x00DE, 0x0B9D, 0x2ECF, 0x16CD, 0x0CC0, + 0x16C9, 0x0000, 0x16CB, 0x0040, 0x02BF, 0x0652, + 0x029F, 0x0068, 0x009F, 0x0CE0, 0x00FF, 0x0E42, + 0x00FF, 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, + 0x02BF, 0x0652, 0x029F, 0x0068, 0x8E00, 0x00E0, + 0x0E07, 0x0080, 0x0BA2, 0x0081, 0x03C0, 0x0E05, + 0x00FE, 0x0E04, 0x8900, 0x8150, 0x009F, 0x0B80, + 0x007A, 0x030B, 0x193E, 0x4C49, 0x1C5E, 0x1A59, + 0x0083, 0x0E05, 0x1B61, 0x1B60, 0x00DE, 0x0B87, + 0x0601, 0x0295, 0x0317, 0x029F, 0x040E, 0x00DE, + 0x0E42, 0x00FE, 0x0E1C, 0x00C3, 0x0E15, 0x177F, + 0x8E00, 0x8A00, 0x8100, 0x8900, 0x00DE, 0x0BB3, + 0x00DF, 0x0BB2, 0x1F1F, 0x4D00, 0x1481, 0x8D1E, + 0x1FD8, 0x0098, 0x8000, 0x0080, 0x0E48, 0xA830, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0x00FE, 0x0BB2, 0x8F00, 0x0080, 0x0E48, + 0x00C1, 0x0E43, 0x1C61, 0x193A, 0x1918, 0x9059, + 0x1919, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E00, 0x6F33, 0x1B7F, 0x8100, 0x00DE, + 0x0BDD, 0xB100, 0x0295, 0x03C0, 0x8D00, 0x8F00, + 0x8A00, 0x00C0, 0x0E43, 0x00C1, 0x0E43, 0x0083, + 0x0BDF, 0x0087, 0xFFFF, 0x00DE, 0x0BDE, 0x80E1, + 0xB04F, 0x1F5E, 0xE2E1, 0xB64F, 0x1F5E, 0xE2E1, + 0x110F, 0x03BB, 0xB79A, 0x1F5F, 0xE2E1, 0xB69B, + 0x1F5E, 0xE2E1, 0xB79A, 0x1B1F, 0x00FF, 0x0BDE, + 0x00C3, 0x0E14, 0x8A00, 0x177F, 0x00C3, 0x0E46, + 0x8A00, 0x177F, 0x00C3, 0x0E47, 0x8A00, 0x177F, + 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x0406, + 0x00DE, 0x0E42, 0x00FE, 0x0E43, 0x8100, 0x8900, + 0x00DE, 0x0B9E, 0x00DF, 0x0BA0, 0x8200, 0x0293, + 0x03E2, 0x7800, 0x029F, 0x03E5, 0x0295, 0x03E5, + 0x7400, 0x00FE, 0x0B9E, 0x00DF, 0x0E43, 0x05E0, + 0x4C00, 0x00FE, 0x0E40, 0x8100, 0x8900, 0x00DE, + 0x0B9F, 0x00DF, 0x0BA1, 0x8200, 0x0293, 0x03F9, + 0x7800, 0x029F, 0x03FC, 0x0295, 0x03FC, 0x7400, + 0x00FE, 0x0B9F, 0x00DF, 0x0E43, 0x05E0, 0x4C00, + 0x00FE, 0x0E41, 0x029F, 0x040E, 0x00DE, 0x0E42, + 0x00FE, 0x0E40, 0x00FE, 0x0E41, 0x00FE, 0x0E43, + 0x8100, 0x8E00, 0x8400, 0x8900, 0x1EFE, 0x0E40, + 0x1EBE, 0x0083, 0x0E08, 0x1C03, 0x1FF5, 0x191A, + 0xF858, 0xFBA0, 0xF8B1, 0xFBA0, 0xF8B1, 0xFBA0, + 0xF8B1, 0xFBA0, 0xF83B, 0x1B7E, 0x0083, 0x0E04, + 0x8100, 0x8973, 0x1961, 0x1960, 0x7800, 0x00FE, + 0x0E04, 0x0294, 0x0303, 0x8E00, 0x8100, 0x00DE, + 0x0B9B, 0xB100, 0x0295, 0x0446, 0x00DE, 0x0B9C, + 0x00DC, 0x0B9D, 0x2ECE, 0x2CCF, 0x8100, 0x00DE, + 0x0E1C, 0x2ECD, 0x16C9, 0x0001, 0x16CB, 0x0040, + 0x02BF, 0x0652, 0x8100, 0x8900, 0x00DE, 0x0B82, + 0x00DF, 0x0B83, 0x2ECE, 0x2FCF, 0x16CD, 0x0B80, + 0x16C9, 0x0001, 0x16CB, 0x00C4, 0x02BF, 0x0652, + 0x8100, 0x00DE, 0x0B80, 0x00DC, 0x0B81, 0xB100, + 0x0294, 0x0462, 0x00C0, 0x0E07, 0x029F, 0x0068, + 0x2ECE, 0x2CCF, 0x16CD, 0x0B80, 0x16C9, 0x0000, + 0x16CB, 0x00C4, 0x0082, 0x0E08, 0x009F, 0x0000, + 0x1B5F, 0x009F, 0x0140, 0x1B5F, 0x009F, 0x0280, + 0x1B5F, 0x009F, 0x0400, 0x1B5F, 0x009F, 0x0540, + 0x1B5F, 0x009F, 0x0680, 0x1B5F, 0x009F, 0x07C0, + 0x1B5F, 0x009F, 0x0900, 0x1B5F, 0x009F, 0x0A40, + 0x1B5F, 0x02BF, 0x0652, 0x00DE, 0x0BA7, 0x00DF, + 0x0BA8, 0x2ECE, 0x2FCF, 0x16CD, 0x03C0, 0x16C9, + 0x0000, 0x16CB, 0x0080, 0x8100, 0x8900, 0x00DE, + 0x0B84, 0x009F, 0x0D21, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E15, 0x00DE, 0x0B85, 0x009F, 0x0D24, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E16, 0x00DE, + 0x0B86, 0x009A, 0x000F, 0x009F, 0x0CB1, 0x3400, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E14, 0x00DE, + 0x0B86, 0x009A, 0x001F, 0x009F, 0x0CC1, 0x14FC, + 0x3400, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E46, + 0x00DE, 0x0B86, 0x009F, 0x0CE1, 0x14F7, 0x4C00, + 0x1C7E, 0x0213, 0x00FE, 0x0E47, 0x8100, 0x00DE, + 0x0B9B, 0xB100, 0x0295, 0x04F9, 0x8900, 0x00DF, + 0x0B9E, 0x0300, 0x0CC0, 0x00FF, 0x0E40, 0x00DF, + 0x0B9F, 0x0300, 0x0CC0, 0x00FF, 0x0E41, 0x009F, + 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E43, 0x02BF, + 0x0652, 0x00DE, 0x0B9C, 0x2ECE, 0x00DE, 0x0B9D, + 0x2ECF, 0x16CD, 0x0CC0, 0x16C9, 0x0000, 0x16CB, + 0x0040, 0x02BF, 0x0652, 0x00C0, 0x0E07, 0x029F, + 0x02F8, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, + 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, 0x02BF, + 0x0652, 0x00C0, 0x0E07, 0x029F, 0x02F8, 0x8E00, + 0x0086, 0x0400, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x1FC6, 0x2ECD, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x0652, 0x02BF, 0x057A, 0x029F, + 0x0068, 0x8E00, 0x0086, 0x07C0, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x1FC6, 0x2ECD, 0x16C9, + 0x0001, 0x16CB, 0x0780, 0x02BF, 0x0652, 0x02BF, + 0x057A, 0x029F, 0x0068, 0x8C00, 0x8A00, 0x8100, + 0x8970, 0x191F, 0x2ECE, 0x2FCF, 0x16CD, 0x0280, + 0x16C9, 0x0001, 0x16CB, 0x0280, 0x8F50, 0x8140, + 0x0081, 0x0400, 0x0083, 0x0000, 0x0082, 0x0140, + 0x0099, 0x0080, 0x02BF, 0x0652, 0x1105, 0x0562, + 0x1F61, 0x1120, 0x0554, 0x8972, 0x195C, 0xF07B, + 0x197D, 0xF131, 0x8139, 0x8900, 0x6800, 0x2ECE, + 0x2CCF, 0x1FFB, 0x2FCD, 0x0F01, 0x2FC9, 0x1FF9, + 0x2FCB, 0x7200, 0x1F5E, 0x1F1C, 0x8100, 0x26C9, + 0x02A0, 0x0004, 0x029C, 0x0563, 0x029F, 0x0068, + 0x029F, 0x0068, 0x029F, 0x0068, 0x029F, 0x0068, + 0x16FC, 0xDCD1, 0x16FD, 0x0002, 0x16FB, 0x0001, + 0x029F, 0x0F1A, 0x029F, 0x0045, 0x8E00, 0x191F, + 0x191D, 0x1F5F, 0x1F1D, 0x2FCE, 0x2DCF, 0x8900, + 0x1FA6, 0x2DCD, 0x0E00, 0x2EC9, 0x8100, 0x009C, + 0x00C0, 0x2CCB, 0x1CA0, 0x0081, 0x0E48, 0x4800, + 0x1B3E, 0x1B3C, 0x0B00, 0x0099, 0x0060, 0x4B00, + 0x1B3D, 0x0081, 0x0E48, 0x1C06, 0x0083, 0x0000, + 0x1C43, 0x27C9, 0x03A0, 0x0004, 0x029C, 0x059B, + 0x1109, 0x05D0, 0x8E00, 0x193A, 0x1938, 0x6900, + 0x2FCE, 0x2DCF, 0x8900, 0x193D, 0x2DCD, 0x16C9, + 0x0000, 0x8100, 0x009C, 0x00C0, 0x2CCB, 0x0081, + 0x0E48, 0x4800, 0x1B3E, 0x1B3C, 0x0B00, 0x0960, + 0x4B00, 0x1B3D, 0x0081, 0x0E48, 0x8F00, 0x80F0, + 0x80C0, 0x6A00, 0x4800, 0x1117, 0x05CA, 0x80F0, + 0x80C0, 0x6B32, 0x4922, 0x80F0, 0x80C0, 0x6A3A, + 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, + 0x1B5D, 0x80F0, 0x80C0, 0x6A00, 0x4800, 0x1117, + 0x05DE, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x80F0, + 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, + 0x4922, 0x1B5F, 0x1B5D, 0x1C05, 0x02DF, 0x8E00, + 0x009B, 0x0E48, 0x009D, 0x00C0, 0x02BF, 0x0637, + 0x4900, 0x00FF, 0x0E1D, 0x00FD, 0x0E1E, 0x8900, + 0x02BF, 0x0652, 0x1104, 0x0622, 0x00DA, 0x0E1D, + 0x00D8, 0x0E1E, 0x009B, 0x0EA8, 0x009D, 0x00C0, + 0x02BF, 0x0637, 0x4900, 0x00FF, 0x0E1D, 0x00FD, + 0x0E1E, 0x0083, 0x0E48, 0x02BF, 0x0642, 0x8900, + 0x00DA, 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0E48, + 0x009D, 0x00C0, 0x02BF, 0x0637, 0x4900, 0x00FF, + 0x0E1D, 0x00FD, 0x0E1E, 0x0083, 0x0EA8, 0x02BF, + 0x0642, 0x0000, 0x0000, 0x8E00, 0x8900, 0x00DA, + 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0EA8, 0x009D, + 0x00C0, 0x02BF, 0x0637, 0x4900, 0x0083, 0x0E48, + 0x02BF, 0x0642, 0x0083, 0x0EA8, 0x02BF, 0x0642, + 0x02DF, 0x8E00, 0x00FA, 0xFFCE, 0x00F8, 0xFFCF, + 0x00FB, 0xFFCD, 0x16C9, 0x0000, 0x2DCB, 0x02DF, + 0x8F00, 0x8D00, 0x8A00, 0x197A, 0x1978, 0xA000, + 0xB600, 0x1130, 0x0650, 0x9179, 0x4E6D, 0x197A, + 0x4D43, 0xA039, 0xB629, 0x02DF, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0652, 0x02DF, 0x26FE, 0x02C0, + 0x8000, 0x029C, 0x0658, 0x02DF, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x065E, 0x02DF, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x0664, 0x02DF, 0x8100, 0x8970, + 0x8E60, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x8900, 0x0D20, 0x2DCB, 0x4C00, 0x1C80, + 0x0080, 0x0280, 0x0081, 0x0000, 0x0082, 0x0140, + 0x0083, 0x0E48, 0x0A00, 0x27C9, 0x03A0, 0x0004, + 0x029C, 0x0681, 0x2ECE, 0x2CCF, 0x16CD, 0x0E58, + 0x16C9, 0x0000, 0x16CB, 0x0260, 0x009F, 0x00A0, + 0x8F00, 0x007F, 0x069A, 0x197E, 0x1B1A, 0x197C, + 0x1B1A, 0x1B5E, 0x1B5C, 0x1B3E, 0x1B3C, 0x1C04, + 0x029F, 0x0068, 0x0082, 0x0BB8, 0x195E, 0x2ED1, + 0x195E, 0x2ED4, 0x195E, 0x2ED5, 0x195E, 0x2ED6, + 0x195E, 0x2ED7, 0x195E, 0x2ED8, 0x195E, 0x2ED9, + 0x195E, 0x2EA0, 0x195E, 0x2EA1, 0x195E, 0x2EA2, + 0x195E, 0x2EA3, 0x195E, 0x2EA4, 0x195E, 0x2EA5, + 0x195E, 0x2EA6, 0x195E, 0x2EA7, 0x195E, 0x2EA8, + 0x195E, 0x2EA9, 0x195E, 0x2EAA, 0x195E, 0x2EAB, + 0x195E, 0x2EAC, 0x195E, 0x2EAD, 0x195E, 0x2EAE, + 0x195E, 0x2EAF, 0x195E, 0x2EDE, 0x195E, 0x2EDA, + 0x195E, 0x2EDB, 0x195E, 0x2EDC, 0x8C00, 0x8A00, + 0x8E00, 0x00D8, 0x0E16, 0x195B, 0x1959, 0x8100, + 0x195C, 0x0080, 0x0E48, 0x195F, 0x1B1F, 0x195F, + 0x1B1F, 0x195F, 0x1B1F, 0x185F, 0x1B1F, 0x6B00, + 0x1505, 0x4D00, 0x157E, 0x1C9F, 0x1CBD, 0x05E0, + 0x9900, 0x7D00, 0x1CDD, 0x8900, 0x1FA5, 0x1502, + 0x1CBF, 0x009A, 0x01FC, 0x009E, 0x0E48, 0x0081, + 0xFFDD, 0x0083, 0x0D80, 0x0064, 0x0710, 0x1827, + 0x1B07, 0x4A00, 0x1FFC, 0x1827, 0x1B07, 0x1579, + 0x3500, 0x1827, 0x1B07, 0x4100, 0x1B7E, 0x1827, + 0x1B07, 0x1B7F, 0x0000, 0x0065, 0x0716, 0x1827, + 0x1B07, 0x0000, 0x0000, 0x0007, 0x187F, 0x0066, + 0x071F, 0x4A3B, 0x1FFC, 0x1579, 0x3533, 0x4100, + 0x1B7F, 0x0004, 0x189F, 0x1ADF, 0x189F, 0x1ADF, + 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x1ADC, 0x0082, + 0x0BD2, 0x27DC, 0x1ADF, 0x27DB, 0x1ADF, 0x27DA, + 0x1ADF, 0x0082, 0x0BBE, 0x27D9, 0x1ADF, 0x27D8, + 0x1ADF, 0x8F00, 0x00C1, 0x0E42, 0x0082, 0x0D80, + 0x1940, 0x1943, 0x80F0, 0xB8C0, 0x111F, 0x074A, + 0xA6F0, 0xBCF0, 0x1940, 0x1943, 0xBCF0, 0x4EC0, + 0xB831, 0xA6F0, 0xBCF0, 0xBC00, 0x4E00, 0x1B3E, + 0x00E1, 0x0E42, 0x02DF, 0x0082, 0x0BB8, 0x195E, + 0x2ED1, 0x195E, 0x2ED4, 0x195E, 0x2ED5, 0x195E, + 0x2ED6, 0x195E, 0x2ED7, 0x195E, 0x2ED8, 0x195E, + 0x2ED9, 0x195E, 0x2EA0, 0x195E, 0x2EA1, 0x195E, + 0x2EA2, 0x195E, 0x2EA3, 0x195E, 0x2EA4, 0x195E, + 0x2EA5, 0x195E, 0x2EA6, 0x195E, 0x2EA7, 0x195E, + 0x2EA8, 0x195E, 0x2EA9, 0x195E, 0x2EAA, 0x195E, + 0x2EAB, 0x195E, 0x2EAC, 0x195E, 0x2EAD, 0x195E, + 0x2EAE, 0x195E, 0x2EAF, 0x195E, 0x2EDE, 0x195E, + 0x2EDA, 0x195E, 0x2EDB, 0x195E, 0x2EDC, 0x8C00, + 0x8A00, 0x8F00, 0x195B, 0x1959, 0x1958, 0x0080, + 0x0E48, 0x195F, 0x1B1F, 0x195F, 0x1B1F, 0x195F, + 0x1B1F, 0x185F, 0x1B1F, 0x6B00, 0x1505, 0x7100, + 0x157E, 0x03A0, 0xFFFF, 0x029C, 0x07AB, 0x0085, + 0x0000, 0x1502, 0x1C9F, 0x0086, 0x0020, 0x029F, + 0x07B7, 0x7900, 0x1CBF, 0x1C9D, 0x05E0, 0x9900, + 0x7D00, 0x1CDD, 0x8900, 0x1FA4, 0x1502, 0x0504, + 0x1C9F, 0x009E, 0x0E4A, 0x7000, 0x0081, 0xFFDD, + 0x0083, 0x0D80, 0x1F42, 0x0064, 0x07C4, 0x1827, + 0x1B07, 0x0000, 0x0000, 0x0065, 0x07D6, 0x1827, + 0x1B07, 0x4A00, 0x1C5E, 0x1827, 0x1B07, 0x1958, + 0x195F, 0x1827, 0x1B07, 0x5100, 0x1B7F, 0x1827, + 0x1B07, 0x1B7C, 0x1B78, 0x0066, 0x07E0, 0x4A00, + 0x1C5E, 0x1958, 0x195F, 0x5100, 0x1B7F, 0x1B7C, + 0x1B78, 0x0004, 0x1C5A, 0x189F, 0x1ADF, 0x189F, + 0x1ADF, 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x1ADC, + 0x0082, 0x0BD2, 0x27DC, 0x1ADF, 0x27DB, 0x1ADF, + 0x27DA, 0x1ADF, 0x0082, 0x0BBE, 0x27D9, 0x1ADF, + 0x27D8, 0x1ADF, 0x8D00, 0x8B00, 0x8F00, 0x0080, + 0x0D80, 0x00C3, 0x0E42, 0x191A, 0x1919, 0xB058, + 0xFB50, 0x1919, 0x110F, 0x080D, 0xB058, 0xFAA1, + 0x1919, 0xB058, 0xFBA0, 0x1919, 0xB058, 0xFA3B, + 0x1B7E, 0x00E3, 0x0E42, 0x02DF, 0x0082, 0x0BB8, + 0x195E, 0x2ED1, 0x195E, 0x2ED4, 0x195E, 0x2ED5, + 0x195E, 0x2ED6, 0x195E, 0x2ED7, 0x195E, 0x2ED8, + 0x195E, 0x2ED9, 0x195E, 0x2EA0, 0x195E, 0x2EA1, + 0x195E, 0x2EA2, 0x195E, 0x2EA3, 0x195E, 0x2EA4, + 0x195E, 0x2EA5, 0x195E, 0x2EA6, 0x195E, 0x2EA7, + 0x195E, 0x2EA8, 0x195E, 0x2EA9, 0x195E, 0x2EAA, + 0x195E, 0x2EAB, 0x195E, 0x2EAC, 0x195E, 0x2EAD, + 0x195E, 0x2EAE, 0x195E, 0x2EAF, 0x195E, 0x2EDE, + 0x195E, 0x2EDA, 0x195E, 0x2EDB, 0x195E, 0x2EDC, + 0x00C0, 0x0E42, 0x0081, 0xFFDD, 0x1120, 0x0855, + 0x1824, 0x1B04, 0x0000, 0x0000, 0x00E0, 0x0E42, + 0x0082, 0x0BD9, 0x0004, 0x189F, 0x1ADF, 0x189F, + 0x1ADF, 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x8900, + 0x1ADC, 0x27DC, 0x00FF, 0x0BD2, 0x27DB, 0x00FF, + 0x0BD1, 0x27DA, 0x00FF, 0x0BD0, 0x27D9, 0x00FF, + 0x0BBE, 0x27D8, 0x00FF, 0x0BBD, 0x02DF, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BA9, 0x02DF, + 0x00C0, 0x0E41, 0x0081, 0x0B8B, 0x00C2, 0x0E09, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BAC, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, + 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BAF, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BA9, 0x00C0, + 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, + 0x0E41, 0x0081, 0x0B8B, 0x00C2, 0x0E09, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BAC, 0x00C0, 0x0E43, + 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, + 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, + 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, + 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, + 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BA9, 0x02DF, 0x00C0, 0x0E41, + 0x0081, 0x0B8B, 0x00C2, 0x0E09, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAC, 0x02DF, 0x00C0, + 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, + 0x0E48, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, + 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAF, + 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, + 0x0E08, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BA9, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, + 0x0E0A, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BAF, 0x02DF, 0x00C0, 0x0E41, 0x0081, 0x0B8B, + 0x00C2, 0x0E09, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B97, + 0x00C2, 0x0E0A, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, + 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E48, 0x00C4, + 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, + 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, + 0x0B97, 0x00C2, 0x0E0A, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAA, 0x02DF, 0x00C0, 0x0E41, + 0x0081, 0x0B8F, 0x00C2, 0x0E0C, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, + 0x0BAA, 0x00FB, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAA, 0x02DF, 0x00C0, + 0x0E41, 0x0081, 0x0B8F, 0x00C2, 0x0E0C, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAD, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, + 0x0083, 0x0E48, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, + 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, + 0x029F, 0x0982, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB0, 0x029F, 0x098E, 0x00C0, 0x0E43, 0x0081, + 0x0B99, 0x00C2, 0x0E0D, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB0, 0x029F, 0x099A, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB0, 0x029F, 0x09AC, 0x00C0, + 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB0, 0x029F, 0x09B9, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, 0x029F, + 0x09C6, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB0, 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB0, 0x029F, 0x0982, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB0, 0x029F, 0x098E, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB0, + 0x029F, 0x099A, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB0, 0x029F, 0x09AC, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB0, 0x029F, 0x09B9, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB0, + 0x029F, 0x09C6, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BAB, 0x02DF, 0x00C0, 0x0E41, 0x0081, 0x0B93, + 0x00C2, 0x0E0F, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, + 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, + 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAB, 0x02DF, 0x00C0, 0x0E41, 0x0081, + 0x0B93, 0x00C2, 0x0E0F, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E48, + 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x8282, + 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0A94, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, + 0x0AA0, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, + 0x029F, 0x0AAC, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB1, 0x029F, 0x0ABE, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB1, 0x029F, 0x0ACB, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0AD8, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0A94, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, + 0x029F, 0x0AA0, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB1, 0x029F, 0x0AAC, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0ABE, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, + 0x029F, 0x0ACB, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB1, 0x029F, 0x0AD8, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAB, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B93, 0x00C2, 0x0E0F, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAE, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, + 0x0E43, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, + 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAB, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B93, 0x00C2, 0x0E0F, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAE, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, + 0x0083, 0x0E48, 0x00C4, 0x0E43, 0x00C5, 0x0E0F, + 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, + 0x029F, 0x0BA4, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB1, 0x029F, 0x0BB0, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB1, 0x029F, 0x0BBC, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0BCE, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0BDB, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, + 0x0BE8, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB1, 0x029F, 0x0BA4, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0BB0, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, + 0x0BBC, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB1, 0x029F, 0x0BCE, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0BDB, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, + 0x0BE8, 0x0118, 0x01D4, 0x0252, 0x02F8, 0x0509, + 0x051D, 0x01FB, 0x066A, 0x0D27, 0x01F5, 0x056E, + 0x056A, 0x056C, 0x023F, 0x0531, 0x0570, 0x0DA1, + 0x020B, 0x0082, 0x0E17, 0x0875, 0x0876, 0x0882, + 0x088E, 0x08A0, 0x08AC, 0x08C3, 0x08DA, 0x0875, + 0x08F7, 0x0904, 0x0911, 0x0924, 0x0931, 0x094A, + 0x0963, 0x0875, 0x0982, 0x098E, 0x099A, 0x0875, + 0x09AC, 0x09B9, 0x09C6, 0x09D9, 0x09E5, 0x09F2, + 0x09FF, 0x09D9, 0x0A0C, 0x0A19, 0x0A26, 0x0875, + 0x0982, 0x098E, 0x099A, 0x0875, 0x09AC, 0x09B9, + 0x09C6, 0x0A33, 0x0A40, 0x0A4E, 0x0A5C, 0x0A33, + 0x0A6A, 0x0A78, 0x0A86, 0x0875, 0x0A94, 0x0AA0, + 0x0AAC, 0x0875, 0x0ABE, 0x0ACB, 0x0AD8, 0x0AEB, + 0x0AF7, 0x0B04, 0x0B11, 0x0AEB, 0x0B1E, 0x0B2B, + 0x0B38, 0x0875, 0x0A94, 0x0AA0, 0x0AAC, 0x0875, + 0x0ABE, 0x0ACB, 0x0AD8, 0x0B45, 0x0B50, 0x0B5E, + 0x0B6C, 0x0B45, 0x0B7A, 0x0B88, 0x0B96, 0x0875, + 0x0BA4, 0x0BB0, 0x0BBC, 0x0875, 0x0BCE, 0x0BDB, + 0x0BE8, 0x0AEB, 0x0BFB, 0x0C08, 0x0C15, 0x0AEB, + 0x0C22, 0x0C2F, 0x0C3C, 0x0875, 0x0BA4, 0x0BB0, + 0x0BBC, 0x0875, 0x0BCE, 0x0BDB, 0x0BE8, 0x0B45, + 0x0C49, 0x0C57, 0x0C65, 0x0B45, 0x0C73, 0x0C81, + 0x0C8F, 0x069E, 0x0753, 0x0814, 0x1000, 0x1200, + 0x1400, 0x8E00, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0E80, 0x16C9, 0x0000, 0x16CB, + 0x0100, 0x1F7E, 0x1F3C, 0x8100, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0D36, 0x191E, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0280, 0x16C9, 0x0000, 0x16CB, + 0x0280, 0x1C80, 0x0080, 0x0280, 0x00C1, 0x0E1B, + 0x0085, 0x0000, 0x0089, 0x007F, 0x0082, 0x0F00, + 0x0083, 0x16B4, 0x1CE3, 0x8100, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0D54, 0x8F00, 0x8A78, 0x8C68, + 0xF100, 0x1A3F, 0x84E3, 0x107E, 0xF2E3, 0xF2E7, + 0xF278, 0x6E68, 0xF132, 0x1A3F, 0x119E, 0x0D70, + 0x1C67, 0x84E3, 0x107E, 0xF2E3, 0xF2E7, 0xF278, + 0x6E68, 0xF132, 0x1A3F, 0x1C67, 0x84E3, 0x107E, + 0xF2E3, 0xF2E7, 0xF200, 0x6E00, 0x1B5E, 0x00E1, + 0x0E1B, 0x0080, 0x0280, 0x0083, 0x0F00, 0x0081, + 0x0000, 0x0082, 0x0140, 0x0089, 0xFFFF, 0x8900, + 0x8100, 0x8F00, 0x11A0, 0x0D90, 0x197F, 0x9930, + 0x1B1E, 0x1B3F, 0x7D29, 0x1B5F, 0x1B5D, 0x8E00, + 0x1FDB, 0x1F99, 0x2ECE, 0x2CCF, 0x16CD, 0x0E80, + 0x16C9, 0x0001, 0x16CB, 0x0100, 0x02BF, 0x0652, + 0x1C04, 0x029F, 0x0068, 0x8E00, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x07C0, 0x16C9, + 0x0001, 0x16CB, 0x0500, 0x02BF, 0x0652, 0x8100, + 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x07C0, + 0x16C9, 0x0000, 0x8900, 0x0D20, 0x2DCB, 0x4C00, + 0x1C80, 0x0080, 0x07C0, 0x0083, 0x0000, 0x1C43, + 0x0A00, 0x27C9, 0x03A0, 0x0004, 0x029C, 0x0DC3, + 0x2ECE, 0x2CCF, 0x16CD, 0x07D0, 0x16C9, 0x0000, + 0x16CB, 0x04E0, 0x8F00, 0x80F0, 0x80C0, 0x6A00, + 0x4800, 0x114F, 0x0DDE, 0x80F0, 0x80C0, 0x6B32, + 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, + 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x80F0, + 0x80C0, 0x6800, 0x7C00, 0x4A00, 0x114F, 0x0DF5, + 0x80F0, 0x80C0, 0x6932, 0x7D00, 0x4B22, 0x80F0, + 0x80C0, 0x683A, 0x7C00, 0x4A2A, 0x80F0, 0x80C0, + 0x6932, 0x7D00, 0x4B22, 0x1B5F, 0x1B5D, 0x1C04, + 0x029F, 0x0068, 0x8F00, 0x80F1, 0x80C1, 0x6A00, + 0x4800, 0x114F, 0x0E0E, 0x80F1, 0x80C1, 0x6B32, + 0x4922, 0x80F1, 0x80C1, 0x6A3A, 0x482A, 0x80F1, + 0x80C1, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x8E00, + 0x02DF, 0x8E00, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0400, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x0652, 0x8100, 0x8970, 0x191C, + 0x2ECE, 0x2CCF, 0x16CD, 0x0A40, 0x16C9, 0x0001, + 0x16CB, 0x0280, 0x02BF, 0x0652, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x16CB, 0x0280, 0x0081, 0x0E48, 0x0082, + 0x0000, 0x0083, 0x0000, 0x02BF, 0x0652, 0x02BF, + 0x0E00, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x16CB, 0x0280, + 0x0081, 0x0E48, 0x0082, 0x0140, 0x0083, 0x0140, + 0x02BF, 0x0652, 0x02BF, 0x0E00, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x16CB, 0x0280, 0x0081, 0x0E48, 0x0082, + 0x07C0, 0x0083, 0x07C0, 0x02BF, 0x0652, 0x02BF, + 0x0E00, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x16CB, 0x0280, + 0x0081, 0x0E48, 0x0082, 0x0900, 0x0083, 0x0900, + 0x02BF, 0x0652, 0x02BF, 0x0E00, 0x029F, 0x0068, + 0x8E00, 0x16FC, 0xECC0, 0x1FCC, 0x1D9E, 0x2EFD, + 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0E8E, 0x0000, + 0x0000, 0x0000, 0x02FF, 0x8E00, 0x00F0, 0x0E17, + 0x00FE, 0x0E18, 0x00FC, 0x0E19, 0x1FCC, 0x1D9E, + 0x16FC, 0xFEED, 0x2EFD, 0x26FC, 0x02A0, 0x8000, + 0x029C, 0x0EA3, 0x00D0, 0x0E17, 0x00DE, 0x0E18, + 0x00DC, 0x0E19, 0x0000, 0x0000, 0x0000, 0x0000, + 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, 0x8100, 0x00DE, + 0x0BB7, 0x0601, 0x0295, 0x0EBF, 0x0E00, 0x00FE, + 0x0B87, 0x8100, 0x00DE, 0x0B88, 0x0601, 0x0295, + 0x0EC9, 0x8100, 0x1FCD, 0x1F8D, 0x02FF, 0x8100, + 0x00DC, 0x0BE1, 0x7600, 0x00FC, 0x0BE1, 0x8100, + 0x1FCD, 0x1F8D, 0x02FF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, + 0x8100, 0x00DE, 0x0BB7, 0x0601, 0x0295, 0x0EE8, + 0x0E00, 0x00FE, 0x0B87, 0x1FCD, 0x1F8D, 0x02FF, + 0x8100, 0x00DE, 0x0B88, 0x0601, 0x0295, 0x0EFA, + 0x00DE, 0x0BDA, 0x2EDA, 0x00DE, 0x0BDB, 0x2EDB, + 0x00DE, 0x0BDC, 0x2EDC, 0x1FCD, 0x1F8D, 0x02FF, + 0x00DE, 0x0BDA, 0x2EDA, 0x26DB, 0x2EDB, 0x26DC, + 0x2EDC, 0x8100, 0x00DC, 0x0BE1, 0x7600, 0x00FC, + 0x0BE1, 0x8100, 0x1FCD, 0x1F8D, 0x02FF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x02FF, 0x0F28, 0x0F2B, + 0x0F63, 0x0F66, 0x8E00, 0x8100, 0x8900, 0x02BF, + 0x0F69, 0x27FF, 0x009E, 0x0F16, 0x4C00, 0x1C7E, + 0x0313, 0x1C7F, 0x176F, 0x0021, 0x029F, 0x0030, + 0x0021, 0x8100, 0x8900, 0x02BF, 0x0F69, 0x24FF, + 0x02BF, 0x0F6F, 0x25FF, 0x02BF, 0x0F6F, 0x27FF, + 0x2ECE, 0x2CCF, 0x16C9, 0x0001, 0x2FCD, 0x2DCB, + 0x8100, 0x8900, 0x02BF, 0x0F69, 0x24FF, 0x1C9E, + 0x1CBC, 0x02BF, 0x0F6F, 0x25FF, 0x02BF, 0x0F6F, + 0x27FF, 0x1CDF, 0x1CFD, 0x8100, 0x02BF, 0x0F69, + 0x26FF, 0x1C1E, 0x8900, 0x02BF, 0x0F6F, 0x20FF, + 0x1F5F, 0x02BF, 0x0F69, 0x21FF, 0x02BF, 0x0F69, + 0x23FF, 0x26C9, 0x02A0, 0x0004, 0x029C, 0x0F5B, + 0x029F, 0x80B5, 0x0021, 0x029F, 0x8000, 0x0021, + 0x029F, 0x0045, 0x0021, 0x26FE, 0x02C0, 0x8000, + 0x029C, 0x0F69, 0x02DF, 0x27FE, 0x03C0, 0x8000, + 0x029C, 0x0F6F, 0x02DF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000 +}; diff --git a/src/dolphin/ax/src/__ax.h b/src/dolphin/ax/src/__ax.h new file mode 100644 index 0000000..7e0c6e7 --- /dev/null +++ b/src/dolphin/ax/src/__ax.h @@ -0,0 +1,84 @@ +#ifndef _DOLPHIN_AX_INTERNAL_H_ +#define _DOLPHIN_AX_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// AXAlloc +AXVPB* __AXGetStackHead(u32 priority); +void __AXServiceCallbackStack(void); +void __AXInitVoiceStacks(void); +void __AXAllocInit(void); +void __AXAllocQuit(void); +void __AXPushFreeStack(AXVPB* p); +AXVPB* __AXPopFreeStack(void); +void __AXPushCallbackStack(AXVPB* p); +AXVPB* __AXPopCallbackStack(void); +void __AXRemoveFromStack(AXVPB* p); +void __AXPushStackHead(AXVPB* p, u32 priority); +AXVPB* __AXPopStackFromBottom(u32 priority); + +// AXAux +void __AXAuxInit(void); +void __AXAuxQuit(void); +void __AXGetAuxAInput(u32* p); +void __AXGetAuxAOutput(u32* p); +void __AXGetAuxBInput(u32* p); +void __AXGetAuxBOutput(u32* p); +void __AXProcessAux(void); +void __AXGetAuxAInputDpl2(u32* p); +void __AXGetAuxAOutputDpl2R(u32* p); +void __AXGetAuxAOutputDpl2Ls(u32* p); +void __AXGetAuxAOutputDpl2Rs(u32* p); +void __AXGetAuxBForDPL2(u32* p); +void __AXGetAuxBOutputDPL2(u32* p); + +// AXCL +extern u32 __AXClMode; + +// AXComp +extern u16 __AXCompressorTable[3360]; + +u32 __AXGetCommandListCycles(void); +u32 __AXGetCommandListAddress(void); +void __AXWriteToCommandList(u16 data); +void __AXNextFrame(void* sbuffer, void* buffer); +void __AXClInit(void); +void __AXClQuit(void); + +// AXOut +void __AXOutNewFrame(u32 lessDspCycles); +void __AXOutAiCallback(void); +void __AXOutInitDSP(void); +void __AXOutInit(u32 outputBufferMode); +void __AXOutQuit(void); + +// AXProf +AXPROFILE* __AXGetCurrentProfile(void); + +// AXSPB +u32 __AXGetStudio(void); +void __AXDepopFade(s32* hostSum, s32* dspVolume, s16* dspDelta); +void __AXPrintStudio(void); +void __AXSPBInit(void); +void __AXSPBQuit(void); +void __AXDepopVoice(AXPB* p); + +// AXVPB +u32 __AXGetNumVoices(void); +void __AXServiceVPB(AXVPB *pvpb); +void __AXDumpVPB(AXVPB* pvpb); +void __AXSyncPBs(u32 lessDspCycles); +AXPB* __AXGetPBs(void); +void __AXSetPBDefault(AXVPB* p); +void __AXVPBInit(void); +void __AXVPBQuit(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AX_INTERNAL_H_ diff --git a/src/dolphin/axart/src/axart.c b/src/dolphin/axart/src/axart.c new file mode 100644 index 0000000..93c42ab --- /dev/null +++ b/src/dolphin/axart/src/axart.c @@ -0,0 +1,330 @@ +#include +#include +#include + +static AXART_SOUND* __AXARTSoundList; + +void AXARTInit(void) { + __AXARTSoundList = 0; + AXARTSet3DDistanceScale(40.0f); + AXARTSet3DDopplerScale(20.0f); +} + +void AXARTQuit(void) { + BOOL old; + AXART_SOUND* sound; + + old = OSDisableInterrupts(); + + for (sound = __AXARTSoundList; sound != 0; sound = (AXART_SOUND*)sound->next) { + MIXReleaseChannel(sound->axvpb); + } + + __AXARTSoundList = 0; + OSRestoreInterrupts(old); +} + +void AXARTServiceSounds(void) { + AXART_SOUND* sound; + + for (sound = __AXARTSoundList; sound != 0; sound = (AXART_SOUND*)sound->next) { + AXARTServiceSound(sound); + } +} + +void AXARTInitSound(AXART_SOUND* sound, AXVPB* voice, u32 sampleRate) { + ASSERTLINE(141, sound); + ASSERTLINE(142, voice); + + sound->articulators = NULL; + sound->axvpb = voice; + sound->sampleRate = sampleRate; +} + +void AXARTAddSound(AXART_SOUND* sound) { + AXART_ART* articulator; + AXVPB* axvpb; + s32 cents; + s32 atten; + s32 auxA; + s32 auxB; + f32 pitch; + u8 pan; + u8 span; + u8 src; + u16 itdL; + u16 itdR; + BOOL old; + + ASSERTLINE(173, sound); + ASSERTLINE(174, sound->axvpb); + + AXSetVoiceItdOn(sound->axvpb); + + cents = atten = auxA = auxB = 0; + pitch = sound->sampleRate / 32000.0f; + pan = 0x40; + span = 0x7F; + src = 1; + itdL = itdR = 0; + articulator = sound->articulators; + + while (articulator != 0) { + switch (articulator->type) { + case AXART_TYPE_3D: + AXART3DSound((AXART_3D*)articulator); + pan = ((AXART_3D*)articulator)->pan; + span = ((AXART_3D*)articulator)->span; + itdL = ((AXART_3D*)articulator)->itdL; + itdR = ((AXART_3D*)articulator)->itdR; + src = ((AXART_3D*)articulator)->src; + pitch += ((AXART_3D*)articulator)->pitch; + atten += ((AXART_3D*)articulator)->attenuation; + break; + case AXART_TYPE_PANNING: + pan = ((AXART_PANNING*)articulator)->pan; + span = ((AXART_PANNING*)articulator)->span; + break; + case AXART_TYPE_ITD: + itdL = ((AXART_ITD*)articulator)->itdL; + itdR = ((AXART_ITD*)articulator)->itdR; + break; + case AXART_TYPE_SRC: + src = ((AXART_SRC*)articulator)->src; + break; + case AXART_TYPE_PITCH: + cents += ((AXART_PITCH*)articulator)->cents; + break; + case AXART_TYPE_PITCH_ENV: + cents += ((AXART_PITCH_ENV*)articulator)->cents; + break; + case AXART_TYPE_PITCH_MOD: + cents += (s32)(((AXART_PITCH_MOD*)articulator)->cents * ((AXART_PITCH_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_VOLUME: + atten += ((AXART_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_A_VOLUME: + auxA += ((AXART_AUXA_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_B_VOLUME: + auxB += ((AXART_AUXB_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_VOLUME_ENV: + atten += ((AXART_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_A_VOLUME_ENV: + auxA += ((AXART_AUXA_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_B_VOLUME_ENV: + auxB += ((AXART_AUXB_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_VOLUME_MOD: + atten += (s32)(((AXART_VOLUME_MOD*)articulator)->attenuation * ((AXART_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_AUX_A_VOLUME_MOD: + auxA += (s32)(((AXART_AUXA_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_AUX_B_VOLUME_MOD: + auxB += (s32)(((AXART_AUXB_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_LPF: + AXARTLpf((AXART_LPF*)articulator, sound->axvpb); + break; + case AXART_TYPE_NONE: + default: + ASSERTMSGLINE(306, 0, "unknown articulator type!\n"); + } + + articulator = articulator->next; + } + + pitch *= AXARTCents(cents >> 0x10); + axvpb = sound->axvpb; + + AXSetVoiceSrcType(axvpb, src); + AXSetVoiceSrcRatio(axvpb, pitch); + AXSetVoiceItdTarget(axvpb, itdL, itdR); + MIXInitChannel(sound->axvpb, 0, atten >> 0x10, auxA >> 0x10, auxB >> 0x10, pan, span, 0); + old = OSDisableInterrupts(); + + if (__AXARTSoundList != 0) { + __AXARTSoundList->prev = sound; + sound->next = __AXARTSoundList; + } else { + sound->next = 0; + } + + sound->prev = 0; + __AXARTSoundList = sound; + OSRestoreInterrupts(old); +} + +void AXARTRemoveSound(AXART_SOUND* sound) { + BOOL old; + + ASSERTLINE(369, sound); + + old = OSDisableInterrupts(); + + if (sound == __AXARTSoundList) { + __AXARTSoundList = sound->next; + if (__AXARTSoundList != 0) { + __AXARTSoundList->prev = 0; + } + } else { + AXART_SOUND* prev = sound->prev; + AXART_SOUND* next = sound->next; + + prev->next = next; + if (next != 0) { + next->prev = prev; + } + } + + OSRestoreInterrupts(old); + MIXReleaseChannel(sound->axvpb); +} + +void AXARTInitLfo(AXART_LFO* lfo, f32* samples, u32 length, f32 delta) { + ASSERTLINE(417, samples); + ASSERTLINE(418, length); + + lfo->lfo = samples; + lfo->length = length; + lfo->delta = delta; + lfo->sampleIndex = 0; + lfo->counter = lfo->sample1 = lfo->sample = lfo->output = 0.0f; +} + +void AXARTInitArt3D(AXART_3D* articulator) { + ASSERTLINE(446, articulator); + + articulator->art.type = AXART_TYPE_3D; + articulator->hAngle = articulator->vAngle = articulator->dist = articulator->closingSpeed = articulator->update = 0.0f; + articulator->pan = 64; + articulator->span = 127; + articulator->src = 1; + articulator->itdL = articulator->itdR = 0; + articulator->pitch = 1.0f; + articulator->attenuation = -0x03C00000; +} + +void AXARTInitArtPanning(AXART_PANNING* articulator) { + ASSERTLINE(481, articulator); + + articulator->art.type = AXART_TYPE_PANNING; + articulator->pan = 64; + articulator->span = 127; +} + +void AXARTInitArtItd(AXART_ITD* articulator) { + ASSERTLINE(503, articulator); + + articulator->art.type = AXART_TYPE_ITD; + articulator->itdL = articulator->itdR = 0; +} + +void AXARTInitArtSrctype(AXART_SRC* articulator) { + ASSERTLINE(526, articulator); + + articulator->art.type = AXART_TYPE_SRC; + articulator->src = 1; +} + +void AXARTInitArtPitch(AXART_PITCH* articulator) { + ASSERTLINE(547, articulator); + + articulator->art.type = AXART_TYPE_PITCH; + articulator->cents = 0; +} + +void AXARTInitArtPitchEnv(AXART_PITCH_ENV* articulator) { + ASSERTLINE(569, articulator); + + articulator->art.type = AXART_TYPE_PITCH_ENV; + articulator->delta = articulator->target = articulator->cents = 0; +} + +void AXARTInitArtPitchMod(AXART_PITCH_MOD* articulator) { + ASSERTLINE(594, articulator); + + articulator->art.type = AXART_TYPE_PITCH_MOD; + articulator->cents = 0; + AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); +} + +void AXARTInitArtVolume(AXART_VOLUME* articulator) { + ASSERTLINE(617, articulator); + + articulator->art.type = AXART_TYPE_VOLUME; + articulator->attenuation = 0; +} + +void AXARTInitArtAuxAVolume(AXART_AUXA_VOLUME* articulator) { + ASSERTLINE(639, articulator); + + articulator->art.type = AXART_TYPE_AUX_A_VOLUME; + articulator->attenuation = 0; +} + +void AXARTInitArtAuxBVolume(AXART_AUXB_VOLUME* articulator) { + ASSERTLINE(661, articulator); + + articulator->art.type = AXART_TYPE_AUX_B_VOLUME; + articulator->attenuation = 0; +} + +void AXARTInitArtVolumeEnv(AXART_VOLUME_ENV* articulator) { + ASSERTLINE(683, articulator); + + articulator->art.type = AXART_TYPE_VOLUME_ENV; + articulator->delta = articulator->target = articulator->attenuation = 0; +} + +void AXARTInitArtAuxAVolumeEnv(AXART_AUXA_VOLUME_ENV* articulator) { + ASSERTLINE(707, articulator); + + articulator->art.type = AXART_TYPE_AUX_A_VOLUME_ENV; + articulator->delta = articulator->target = articulator->attenuation = 0; +} + +void AXARTInitArtAuxBVolumeEnv(AXART_AUXB_VOLUME_ENV* articulator) { + ASSERTLINE(731, articulator); + + articulator->art.type = AXART_TYPE_AUX_B_VOLUME_ENV; + articulator->delta = articulator->target = articulator->attenuation = 0; +} + +void AXARTInitArtVolumeMod(AXART_VOLUME_MOD* articulator) { + ASSERTLINE(756, articulator); + + articulator->art.type = AXART_TYPE_VOLUME_MOD; + articulator->attenuation = 0; + AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); +} + +void AXARTInitArtAuxAVolumeMod(AXART_AUXA_VOLUME_MOD* articulator) { + ASSERTLINE(781, articulator); + + articulator->art.type = AXART_TYPE_AUX_A_VOLUME_MOD; + articulator->attenuation = 0; + AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); +} + +void AXARTInitArtAuxBVolumeMod(AXART_AUXB_VOLUME_MOD* articulator) { + ASSERTLINE(806, articulator); + + articulator->art.type = AXART_TYPE_AUX_B_VOLUME_MOD; + articulator->attenuation = 0; + AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); +} + +void AXARTInitArtLpf(AXART_LPF* articulator) { + ASSERTLINE(830, articulator); + + articulator->art.type = AXART_TYPE_LPF; + articulator->initLPF = 1; + articulator->frequency = 0; + articulator->update = 1; +} diff --git a/src/dolphin/axart/src/axart3d.c b/src/dolphin/axart/src/axart3d.c new file mode 100644 index 0000000..b2d90db --- /dev/null +++ b/src/dolphin/axart/src/axart3d.c @@ -0,0 +1,317 @@ +#include +#include +#include + +static u8 __AXART3DPan[360] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, + 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, + 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F +}; + +static u8 __AXART3DSpan[360] = { + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, + 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, + 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, + 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, + 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, + 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, + 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48, + 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, + 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, + 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, + 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, + 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +}; + +static u8 __AXART3DPanDPL2[360] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, + 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, + 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, + 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, + 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, + 0x63, 0x62, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, + 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D, 0x4C, + 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, + 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, + 0x33, 0x32, 0x31, 0x30, 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, + 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, + 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, + 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F +}; + +static u8 __AXART3DItdL[360] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, + 0x1D, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x1B, 0x1B, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x19, 0x19, 0x19, 0x19, 0x19, 0x18, 0x18, + 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16, 0x15, + 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, + 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, + 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, +}; + +static u8 __AXART3DItdR[360] = { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, + 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D, + 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, + 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, + 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, + 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static u8 __AXART3DSrc[360+1] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, +}; + +static f32 __AXART3DDopplerScale = 0; +static f32 __AXART3DDistanceScale = 0; + +void AXARTSet3DDopplerScale(f32 scale) { + ASSERTLINE(323, scale > 0); + __AXART3DDopplerScale = scale; +} + +void AXARTSet3DDistanceScale(f32 scale) { + ASSERTLINE(340, scale > 0); + __AXART3DDistanceScale = scale; +} + +void AXART3DSound(AXART_3D* articulator) { + u32 hAngle; + u32 vAngle; + + if (articulator->update) { + if (articulator->hAngle > 0) { + hAngle = (articulator->hAngle / 6.283185f) * 360.0f; + } else if (articulator->hAngle < 0) { + hAngle = 360.0f + (articulator->hAngle / 6.283185f) * 360.0f; + } else { + hAngle = 0; + } + + // @BUG? - hAngle missing a bounds assert + + if (articulator->vAngle > 0) { + vAngle = (articulator->vAngle / 6.283185f) * 360.0f; + } else if (articulator->vAngle < 0) { + vAngle = 360.0f + (articulator->vAngle / 6.283185f) * 360.0f; + } else { + vAngle = 0; + } + + ASSERTLINE(379, vAngle <= 360); + + articulator->update = 0; + + if (MIXGetSoundMode() == 3) { + articulator->pan = __AXART3DPanDPL2[hAngle]; + } else { + articulator->pan = __AXART3DPan[hAngle]; + } + + articulator->span = __AXART3DSpan[hAngle]; + articulator->itdL = __AXART3DItdL[hAngle]; + articulator->itdR = __AXART3DItdR[hAngle]; + articulator->src = __AXART3DSrc[vAngle]; + articulator->pitch = articulator->closingSpeed / __AXART3DDopplerScale; + articulator->attenuation = (articulator->dist / __AXART3DDistanceScale) * -3932160.0f; + } +} diff --git a/src/dolphin/axart/src/axartcents.c b/src/dolphin/axart/src/axartcents.c new file mode 100644 index 0000000..6086bf4 --- /dev/null +++ b/src/dolphin/axart/src/axartcents.c @@ -0,0 +1,280 @@ +#include +#include +#include + +static f32 __AXLFOCentsTable[100] = { + 1.000000f, + 1.000578f, + 1.001156f, + 1.001734f, + 1.002313f, + 1.002892f, + 1.003472f, + 1.004052f, + 1.004632f, + 1.005212f, + 1.005793f, + 1.006374f, + 1.006956f, + 1.007537f, + 1.008120f, + 1.008702f, + 1.009285f, + 1.009868f, + 1.010451f, + 1.011035f, + 1.011619f, + 1.012204f, + 1.012789f, + 1.013374f, + 1.013959f, + 1.014545f, + 1.015132f, + 1.015718f, + 1.016305f, + 1.016892f, + 1.017480f, + 1.018068f, + 1.018656f, + 1.019244f, + 1.019833f, + 1.020423f, + 1.021012f, + 1.021602f, + 1.022192f, + 1.022783f, + 1.023374f, + 1.023965f, + 1.024557f, + 1.025149f, + 1.025741f, + 1.026334f, + 1.026927f, + 1.027520f, + 1.028114f, + 1.028708f, + 1.029302f, + 1.029897f, + 1.030492f, + 1.031087f, + 1.031683f, + 1.032279f, + 1.032876f, + 1.033472f, + 1.034070f, + 1.034667f, + 1.035265f, + 1.035863f, + 1.036462f, + 1.037060f, + 1.037660f, + 1.038259f, + 1.038859f, + 1.039459f, + 1.040060f, + 1.040661f, + 1.041262f, + 1.041864f, + 1.042466f, + 1.043068f, + 1.043671f, + 1.044274f, + 1.044877f, + 1.045481f, + 1.046085f, + 1.046689f, + 1.047294f, + 1.047899f, + 1.048505f, + 1.049111f, + 1.049717f, + 1.050323f, + 1.050930f, + 1.051537f, + 1.052145f, + 1.052753f, + 1.053361f, + 1.053970f, + 1.054579f, + 1.055188f, + 1.055798f, + 1.056408f, + 1.057018f, + 1.057629f, + 1.058240f, + 1.058851f, +}; + +static f32 __AXLFOOctavesTableUp[12] = { + 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, + 256.0f, 512.0f, 1024.0f, 2048.0f, +}; + +static f32 __AXLFOSemitonesTableUp[12] = { + 1.000000f, + 1.059463f, + 1.122462f, + 1.189207f, + 1.259921f, + 1.334840f, + 1.414214f, + 1.498307f, + 1.587401f, + 1.681793f, + 1.781797f, + 1.887749f, +}; + +static f32 __AXLFOSemitonesTableDown[128] = { + 1.000000f, + 0.943874f, + 0.890899f, + 0.840896f, + 0.793701f, + 0.749154f, + 0.707107f, + 0.667420f, + 0.629961f, + 0.594604f, + 0.561231f, + 0.529732f, + 0.500000f, + 0.471937f, + 0.445449f, + 0.420448f, + 0.396850f, + 0.374577f, + 0.353553f, + 0.333710f, + 0.314980f, + 0.297302f, + 0.280616f, + 0.264866f, + 0.250000f, + 0.235969f, + 0.222725f, + 0.210224f, + 0.198425f, + 0.187288f, + 0.176777f, + 0.166855f, + 0.157490f, + 0.148651f, + 0.140308f, + 0.132433f, + 0.125000f, + 0.117984f, + 0.111362f, + 0.105112f, + 0.099213f, + 0.093644f, + 0.088388f, + 0.083427f, + 0.078745f, + 0.074325f, + 0.070154f, + 0.066216f, + 0.062500f, + 0.058992f, + 0.055681f, + 0.052556f, + 0.049606f, + 0.046822f, + 0.044194f, + 0.041714f, + 0.039373f, + 0.037163f, + 0.035077f, + 0.033108f, + 0.031250f, + 0.029496f, + 0.027841f, + 0.026278f, + 0.024803f, + 0.023411f, + 0.022097f, + 0.020857f, + 0.019686f, + 0.018581f, + 0.017538f, + 0.016554f, + 0.015625f, + 0.014748f, + 0.013920f, + 0.013139f, + 0.012402f, + 0.011706f, + 0.011049f, + 0.010428f, + 0.009843f, + 0.009291f, + 0.008769f, + 0.008277f, + 0.007813f, + 0.007374f, + 0.006960f, + 0.006570f, + 0.006201f, + 0.005853f, + 0.005524f, + 0.005214f, + 0.004922f, + 0.004645f, + 0.004385f, + 0.004139f, + 0.003906f, + 0.003687f, + 0.003480f, + 0.003285f, + 0.003100f, + 0.002926f, + 0.002762f, + 0.002607f, + 0.002461f, + 0.002323f, + 0.002192f, + 0.002069f, + 0.001953f, + 0.001844f, + 0.001740f, + 0.001642f, + 0.001550f, + 0.001463f, + 0.001381f, + 0.001304f, + 0.001230f, + 0.001161f, + 0.001096f, + 0.001035f, + 0.000977f, + 0.000922f, + 0.000870f, + 0.000821f, + 0.000775f, + 0.000732f, + 0.000691f, + 0.000652f, +}; + +f32 AXARTCents(s32 cents) { + if (cents > 0) { + s32 octaves = cents / 1200; + s32 semitones = (cents % 1200) / 100; + cents %= 100; + + return __AXLFOOctavesTableUp[octaves] * __AXLFOSemitonesTableUp[semitones] * __AXLFOCentsTable[cents]; + } else if (cents < 0) { + s32 semitones = cents / 100; + cents %= 100; + + if (cents != 0) { + cents += 100; + semitones -= 1; + } + + semitones *= -1; + return __AXLFOSemitonesTableDown[semitones] * __AXLFOCentsTable[cents]; + } else { + return 1.0f; + } +} diff --git a/src/dolphin/axart/src/axartenv.c b/src/dolphin/axart/src/axartenv.c new file mode 100644 index 0000000..278bfb5 --- /dev/null +++ b/src/dolphin/axart/src/axartenv.c @@ -0,0 +1,33 @@ +#include +#include +#include + +void AXARTPitchEnv(AXART_PITCH_ENV* articulator) { + if (articulator->cents != articulator->target) { + articulator->cents += articulator->delta; + if (articulator->delta > 0) { + if (articulator->cents > articulator->target) { + articulator->cents = articulator->target; + } + } else if (articulator->delta < 0) { + if (articulator->cents < articulator->target) { + articulator->cents = articulator->target; + } + } + } +} + +void AXARTVolumeEnv(AXART_VOLUME_ENV* articulator) { + if (articulator->attenuation != articulator->target) { + articulator->attenuation += articulator->delta; + if (articulator->delta > 0) { + if (articulator->attenuation > articulator->target) { + articulator->attenuation = articulator->target; + } + } else if (articulator->delta < 0) { + if (articulator->attenuation < articulator->target) { + articulator->attenuation = articulator->target; + } + } + } +} diff --git a/src/dolphin/axart/src/axartlfo.c b/src/dolphin/axart/src/axartlfo.c new file mode 100644 index 0000000..58c9f45 --- /dev/null +++ b/src/dolphin/axart/src/axartlfo.c @@ -0,0 +1,85 @@ +#include +#include +#include + +f32 AXARTSine[64] = { + 0.0f, 0.09802f, 0.19509f, 0.29028f, 0.38268f, 0.4714f, 0.55557f, 0.63439f, + 0.70711f, 0.77301f, 0.83147f, 0.88192f, 0.92388f, 0.95694f, 0.98079f, 0.99518f, + 1.0f, 0.99518f, 0.98079f, 0.95694f, 0.92388f, 0.88192f, 0.83147f, 0.77301f, + 0.70711f, 0.63439f, 0.55557f, 0.4714f, 0.38268f, 0.29028f, 0.19509f, 0.09802f, + 0.0f, -0.09802f, -0.19509f, -0.29028f, -0.38268f, -0.4714f, -0.55557f, -0.63439f, + -0.70711f, -0.77301f, -0.83147f, -0.88192f, -0.92388f, -0.95694f, -0.98079f, -0.99518f, + -1.0f, -0.99518f, -0.98079f, -0.95694f, -0.92388f, -0.88192f, -0.83147f, -0.77301f, + -0.70711f, -0.63439f, -0.55557f, -0.4714f, -0.38268f, -0.29028f, -0.19509f, -0.09802f, +}; + +static f32 AXARTSquare[64] = { + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +}; + +static f32 AXARTSaw[64] = { + -1.0f, -0.96875f, -0.9375f, -0.90625f, -0.875f, -0.84375f, -0.8125f, -0.78125f, + -0.75f, -0.71875f, -0.6875f, -0.65625f, -0.625f, -0.59375f, -0.5625f, -0.53125f, + -0.5f, -0.46875f, -0.4375f, -0.40625f, -0.375f, -0.34375f, -0.3125f, -0.28125f, + -0.25f, -0.21875f, -0.1875f, -0.15625f, -0.125f, -0.09375f, -0.0625f, -0.03125f, + 0.0f, 0.03125f, 0.0625f, 0.09375f, 0.125f, 0.15625f, 0.1875f, 0.21875f, + 0.25f, 0.28125f, 0.3125f, 0.34375f, 0.375f, 0.40625f, 0.4375f, 0.46875f, + 0.5f, 0.53125f, 0.5625f, 0.59375f, 0.625f, 0.65625f, 0.6875f, 0.71875f, + 0.75f, 0.78125f, 0.8125f, 0.84375f, 0.875f, 0.90625f, 0.9375f, 0.96875f, +}; + +static f32 AXARTReverseSaw[64] = { + 1.0f, 0.96875f, 0.9375f, 0.90625f, 0.875f, 0.84375f, 0.8125f, 0.78125f, + 0.75f, 0.71875f, 0.6875f, 0.65625f, 0.625f, 0.59375f, 0.5625f, 0.53125f, + 0.5f, 0.46875f, 0.4375f, 0.40625f, 0.375f, 0.34375f, 0.3125f, 0.28125f, + 0.25f, 0.21875f, 0.1875f, 0.15625f, 0.125f, 0.09375f, 0.0625f, 0.03125f, + 0.0f, -0.03125f, -0.0625f, -0.09375f, -0.125f, -0.15625f, -0.1875f, -0.21875f, + -0.25f, -0.28125f, -0.3125f, -0.34375f, -0.375f, -0.40625f, -0.4375f, -0.46875f, + -0.5f, -0.53125f, -0.5625f, -0.59375f, -0.625f, -0.65625f, -0.6875f, -0.71875f, + -0.75f, -0.78125f, -0.8125f, -0.84375f, -0.875f, -0.90625f, -0.9375f, -0.96875f, +}; + +static f32 AXARTTriangle[64] = { + 0.0f, 0.0625f, 0.125f, 0.1875f, 0.25f, 0.3125f, 0.375f, 0.4375f, + 0.5f, 0.5625f, 0.625f, 0.6875f, 0.75f, 0.8125f, 0.875f, 0.9375f, + 1.0f, 0.9375f, 0.875f, 0.8125f, 0.75f, 0.6875f, 0.625f, 0.5625f, + 0.5f, 0.4375f, 0.375f, 0.3125f, 0.25f, 0.1875f, 0.125f, 0.0625f, + 0.0f, -0.0625f, -0.125f, -0.1875f, -0.25f, -0.3125f, -0.375f, -0.4375f, + -0.5f, -0.5625f, -0.625f, -0.6875f, -0.75f, -0.8125f, -0.875f, -0.9375f, + -1.0f, -0.9375f, -0.875f, -0.8125f, -0.75f, -0.6875f, -0.625f, -0.5625f, + -0.5f, -0.4375f, -0.375f, -0.3125f, -0.25f, -0.1875f, -0.125f, -0.0625f, +}; + +static f32 AXARTNoise[64] = { + -0.759363f, -0.805919f, -0.62015f, -0.78302f, 0.263439f, 0.467792f, -0.102506f, 0.700646f, + 0.852924f, 0.586413f, 0.32763f, 0.313143f, 0.66009f, 0.778686f, -0.698379f, -0.635841f, + -0.087795f, 0.577847f, 0.887183f, -0.325427f, -0.890347f, 0.111084f, -0.325035f, 0.43995f, + -0.62506f, -0.515152f, -0.299054f, -0.353217f, 0.512053f, 0.03931f, 0.869222f, -0.626512f, + 0.017653f, 0.891789f, -0.191419f, 0.411077f, 0.965653f, 0.134522f, -0.761372f, 0.543137f, + -0.887949f, 0.454729f, 0.860104f, -0.005229f, 0.28682f, -0.036344f, -0.976264f, -0.400756f, + 0.662483f, -0.44099f, -0.02479f, 0.066671f, -0.045242f, 0.150543f, 0.810762f, -0.35605f, + 0.364502f, 0.63764f, -0.212945f, 0.394563f, 0.496392f, 0.727584f, -0.564585f, 0.040292f, +}; + +void AXARTLfo(AXART_LFO* lfo) { + lfo->counter += lfo->delta; + + if (lfo->counter >= 1.0f) { + f32 lfoSamples = lfo->counter; + + lfo->counter -= lfoSamples; + lfo->sampleIndex += (u32)lfoSamples; + lfo->sampleIndex %= lfo->length; + lfo->sample1 = lfo->sample; + lfo->sample = lfo->lfo[lfo->sampleIndex]; + } + + lfo->output = lfo->sample1 - lfo->counter * (lfo->sample1 - lfo->sample); +} diff --git a/src/dolphin/axart/src/axartlpf.c b/src/dolphin/axart/src/axartlpf.c new file mode 100644 index 0000000..c2aecfa --- /dev/null +++ b/src/dolphin/axart/src/axartlpf.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include "fake_tgmath.h" + +static u16 __coefs[48] = { + 0x6A09, 0x15F6, 0x6871, 0x178E, 0x6463, 0x1B9C, + 0x5DB3, 0x224C, 0x5618, 0x29E7, 0x4D7A, 0x3285, + 0x4367, 0x3C98, 0x3A5A, 0x45A5, 0x31C5, 0x4E3A, + 0x2924, 0x56DB, 0x2244, 0x5DBB, 0x1C50, 0x63AF, + 0x16C0, 0x693F, 0x1292, 0x6D6D, 0x0F18, 0x70E7, + 0x0BF5, 0x740A, 0x09A9, 0x7656, 0x07CA, 0x7835, + 0x0646, 0x79B9, 0x04ED, 0x7B12, 0x03F5, 0x7C0A, + 0x032D, 0x7CD2, 0x027D, 0x7D82, 0x01FE, 0x7E01 +}; + +void AXARTLpf(AXART_LPF* articulator, AXVPB* voice) { + u32 i; + ASSERTLINE(68, articulator); + ASSERTLINE(69, voice); + + if (articulator->update != 0) { + if (articulator->initLPF != 0) { + articulator->initLPF = 0; + voice->pb.lpf.on = 1; + voice->pb.lpf.yn1 = 0; + voice->sync |= 0x200000; + } else { + voice->sync |= 0x400000; + } + + i = articulator->frequency; + ASSERTMSGLINE(90, i < 24, "AXART: roll off frequency should be < 24"); + + i *= 2; + voice->pb.lpf.a0 = __coefs[i]; + + i++; + voice->pb.lpf.b0 = __coefs[i]; + articulator->update = 0; + } +} diff --git a/src/dolphin/axart/src/axartsound.c b/src/dolphin/axart/src/axartsound.c new file mode 100644 index 0000000..732171d --- /dev/null +++ b/src/dolphin/axart/src/axartsound.c @@ -0,0 +1,122 @@ +#include +#include +#include + +void AXARTServiceSound(AXART_SOUND* sound) { + AXART_ART* articulator; + AXVPB* axvpb; + s32 cents; + s32 atten; + s32 auxA; + s32 auxB; + f32 pitch; + u8 pan; + u8 span; + u8 src; + u16 itdL; + u16 itdR; + + cents = atten = auxA = auxB = 0; + pitch = sound->sampleRate / 32000.0f; + pan = 64; + span = 127; + src = 1; + itdL = itdR = 0; + + for (articulator = sound->articulators; articulator != 0; articulator = (AXART_ART*)articulator->next) { + switch (articulator->type) { + case AXART_TYPE_3D: + AXART3DSound((AXART_3D*)articulator); + pan = ((AXART_3D*)articulator)->pan; + span = ((AXART_3D*)articulator)->span; + itdL = ((AXART_3D*)articulator)->itdL; + itdR = ((AXART_3D*)articulator)->itdR; + src = ((AXART_3D*)articulator)->src; + pitch += ((AXART_3D*)articulator)->pitch; + atten += ((AXART_3D*)articulator)->attenuation; + break; + case AXART_TYPE_PANNING: + pan = ((AXART_PANNING*)articulator)->pan; + span = ((AXART_PANNING*)articulator)->span; + break; + case AXART_TYPE_ITD: + itdL = ((AXART_ITD*)articulator)->itdL; + itdR = ((AXART_ITD*)articulator)->itdR; + break; + case AXART_TYPE_SRC: + src = ((AXART_SRC*)articulator)->src; + break; + case AXART_TYPE_PITCH: + cents += ((AXART_PITCH*)articulator)->cents; + break; + case AXART_TYPE_PITCH_ENV: + AXARTPitchEnv((AXART_PITCH_ENV*)articulator); + cents += ((AXART_PITCH_ENV*)articulator)->cents; + break; + case AXART_TYPE_PITCH_MOD: + AXARTLfo(&((AXART_PITCH_MOD*)articulator)->lfo); + cents += (s32)(((AXART_PITCH_MOD*)articulator)->cents * ((AXART_PITCH_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_VOLUME: + atten += ((AXART_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_A_VOLUME: + auxA += ((AXART_AUXA_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_B_VOLUME: + auxB += ((AXART_AUXB_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_VOLUME_ENV: + AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); + atten += ((AXART_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_A_VOLUME_ENV: + AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); + auxA += ((AXART_AUXA_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_B_VOLUME_ENV: + AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); + auxB += ((AXART_AUXB_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_VOLUME_MOD: + AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); + atten += (s32)(((AXART_VOLUME_MOD*)articulator)->attenuation * ((AXART_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_AUX_A_VOLUME_MOD: + AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); + auxA += (s32)(((AXART_AUXA_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_AUX_B_VOLUME_MOD: + AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); + auxB += (s32)(((AXART_AUXB_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXB_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_LPF: + AXARTLpf((AXART_LPF*)articulator, sound->axvpb); + break; + default: +#ifdef DEBUG + OSPanic(__FILE__, 196, "unknown articulator type!\n"); +#endif + break; + } + } + + pitch *= AXARTCents(cents >> 16); + axvpb = sound->axvpb; + AXSetVoiceSrcType(axvpb, src); + AXSetVoiceSrcRatio(axvpb, pitch); + AXSetVoiceItdTarget(axvpb, itdL, itdR); + MIXSetInput(axvpb, atten >> 16); + MIXSetAuxA(axvpb, auxA >> 16); + MIXSetAuxB(axvpb, auxB >> 16); + MIXSetPan(axvpb, pan); + MIXSetSPan(axvpb, span); +} + +void AXARTAddArticulator(AXART_SOUND* sound, AXART_ART* articulator) { + ASSERTLINE(232, sound); + ASSERTLINE(233, articulator); + + articulator->next = sound->articulators; + sound->articulators = articulator; +} diff --git a/src/dolphin/axfx/src/__axfx.h b/src/dolphin/axfx/src/__axfx.h new file mode 100644 index 0000000..17ac09f --- /dev/null +++ b/src/dolphin/axfx/src/__axfx.h @@ -0,0 +1,17 @@ +#ifndef _DOLPHIN_AX_INTERNAL_H_ +#define _DOLPHIN_AX_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void* (*__AXFXAlloc)(u32); +extern void (*__AXFXFree)(void*); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/axfx/src/axfx.c b/src/dolphin/axfx/src/axfx.c new file mode 100644 index 0000000..64c25fc --- /dev/null +++ b/src/dolphin/axfx/src/axfx.c @@ -0,0 +1,20 @@ +#include +#include + +static void* __AXFXAllocFunction(u32 bytes) { + return OSAlloc(bytes); +} + +static void __AXFXFreeFunction(void* p) { + OSFree(p); +} + +void* (*__AXFXAlloc)(u32) = __AXFXAllocFunction; +void (*__AXFXFree)(void*) = __AXFXFreeFunction; + +void AXFXSetHooks(void* (*alloc)(u32), void (*free)(void*)) { + ASSERTLINE(46, alloc && free); + + __AXFXAlloc = alloc; + __AXFXFree = free; +} diff --git a/src/dolphin/axfx/src/chorus.c b/src/dolphin/axfx/src/chorus.c new file mode 100644 index 0000000..56bcffc --- /dev/null +++ b/src/dolphin/axfx/src/chorus.c @@ -0,0 +1,507 @@ +#include +#include +#include + +#include "__axfx.h" + +static f32 rsmpTab12khz[512] = { + 0.097503662109f, 0.802215576172f, 0.101593017578f, -0.000976562500f, 0.093505859375f, + 0.802032470703f, 0.105804443359f, -0.001037597656f, 0.089599609375f, 0.801696777344f, + 0.110107421875f, -0.001159667969f, 0.085784912109f, 0.801177978516f, 0.114471435547f, + -0.001281738281f, 0.082031250000f, 0.800476074219f, 0.118927001953f, -0.001403808594f, + 0.078369140625f, 0.799621582031f, 0.123474121094f, -0.001525878906f, 0.074798583984f, + 0.798614501953f, 0.128143310547f, -0.001647949219f, 0.071350097656f, 0.797424316406f, + 0.132873535156f, -0.001770019531f, 0.067962646484f, 0.796051025391f, 0.137695312500f, + -0.001922607422f, 0.064697265625f, 0.794525146484f, 0.142608642578f, -0.002044677734f, + 0.061492919922f, 0.792846679688f, 0.147613525391f, -0.002197265625f, 0.058349609375f, + 0.790985107422f, 0.152709960938f, -0.002319335938f, 0.055328369141f, 0.788940429688f, + 0.157897949219f, -0.002471923828f, 0.052368164062f, 0.786743164062f, 0.163177490234f, + -0.002655029297f, 0.049499511719f, 0.784423828125f, 0.168518066406f, -0.002807617188f, + 0.046722412109f, 0.781890869141f, 0.173980712891f, -0.002990722656f, 0.044006347656f, + 0.779205322266f, 0.179504394531f, -0.003143310547f, 0.041412353516f, 0.776367187500f, + 0.185119628906f, -0.003326416016f, 0.038879394531f, 0.773376464844f, 0.190826416016f, + -0.003509521484f, 0.036407470703f, 0.770233154297f, 0.196594238281f, -0.003692626953f, + 0.034027099609f, 0.766937255859f, 0.202484130859f, -0.003875732422f, 0.031738281250f, + 0.763488769531f, 0.208435058594f, -0.004058837891f, 0.029510498047f, 0.759857177734f, + 0.214447021484f, -0.004272460938f, 0.027374267578f, 0.756103515625f, 0.220550537109f, + -0.004455566406f, 0.025299072266f, 0.752197265625f, 0.226745605469f, -0.004669189453f, + 0.023315429688f, 0.748168945312f, 0.233001708984f, -0.004852294922f, 0.021392822266f, + 0.743988037109f, 0.239318847656f, -0.005065917969f, 0.019561767578f, 0.739654541016f, + 0.245727539062f, -0.005310058594f, 0.017791748047f, 0.735198974609f, 0.252197265625f, + -0.005523681641f, 0.016052246094f, 0.730590820312f, 0.258728027344f, -0.005706787109f, + 0.014404296875f, 0.725860595703f, 0.265350341797f, -0.005920410156f, 0.012817382812f, + 0.721008300781f, 0.272033691406f, -0.006164550781f, 0.011322021484f, 0.716003417969f, + 0.278778076172f, -0.006378173828f, 0.009887695312f, 0.710906982422f, 0.285583496094f, + -0.006561279297f, 0.008514404297f, 0.705657958984f, 0.292449951172f, -0.006774902344f, + 0.007202148438f, 0.700317382812f, 0.299346923828f, -0.007019042969f, 0.005920410156f, + 0.694854736328f, 0.306335449219f, -0.007232666016f, 0.004699707031f, 0.689270019531f, + 0.313385009766f, -0.007415771484f, 0.003570556641f, 0.683563232422f, 0.320465087891f, + -0.007629394531f, 0.002471923828f, 0.677734375000f, 0.327606201172f, -0.007873535156f, + 0.001434326172f, 0.671844482422f, 0.334777832031f, -0.008087158203f, 0.000457763672f, + 0.665832519531f, 0.341979980469f, -0.008270263672f, -0.000488281250f, 0.659729003906f, + 0.349243164062f, -0.008453369141f, -0.001342773438f, 0.653533935547f, 0.356567382812f, + -0.008636474609f, -0.002166748047f, 0.647216796875f, 0.363891601562f, -0.008850097656f, + -0.002960205078f, 0.640838623047f, 0.371276855469f, -0.009033203125f, -0.003692626953f, + 0.634338378906f, 0.378692626953f, -0.009216308594f, -0.004364013672f, 0.627777099609f, + 0.386138916016f, -0.009338378906f, -0.004974365234f, 0.621154785156f, 0.393615722656f, + -0.009490966797f, -0.005584716797f, 0.614440917969f, 0.401092529297f, -0.009643554688f, + -0.006134033203f, 0.607635498047f, 0.408599853516f, -0.009796142578f, -0.006652832031f, + 0.600769042969f, 0.416107177734f, -0.009918212891f, -0.007141113281f, 0.593841552734f, + 0.423645019531f, -0.010009765625f, -0.007568359375f, 0.586853027344f, 0.431213378906f, + -0.010131835938f, -0.007965087891f, 0.579772949219f, 0.438751220703f, -0.010223388672f, + -0.008331298828f, 0.572662353516f, 0.446319580078f, -0.010284423828f, -0.008666992188f, + 0.565521240234f, 0.453887939453f, -0.010345458984f, -0.008972167969f, 0.558319091797f, + 0.461456298828f, -0.010406494141f, -0.009216308594f, 0.551055908203f, 0.469024658203f, + -0.010406494141f, -0.009460449219f, 0.543731689453f, 0.476593017578f, -0.010406494141f, + -0.009674072266f, 0.536407470703f, 0.484130859375f, -0.010375976562f, -0.009857177734f, + 0.529022216797f, 0.491668701172f, -0.010375976562f, -0.010009765625f, 0.521606445312f, + 0.499176025391f, -0.010314941406f, -0.010131835938f, 0.514160156250f, 0.506683349609f, + -0.010253906250f, -0.010253906250f, 0.506683349609f, 0.514160156250f, -0.010131835938f, + -0.010314941406f, 0.499176025391f, 0.521606445312f, -0.010009765625f, -0.010375976562f, + 0.491668701172f, 0.529022216797f, -0.009857177734f, -0.010375976562f, 0.484130859375f, + 0.536407470703f, -0.009674072266f, -0.010406494141f, 0.476593017578f, 0.543731689453f, + -0.009460449219f, -0.010406494141f, 0.469024658203f, 0.551055908203f, -0.009216308594f, + -0.010406494141f, 0.461456298828f, 0.558319091797f, -0.008972167969f, -0.010345458984f, + 0.453887939453f, 0.565521240234f, -0.008666992188f, -0.010284423828f, 0.446319580078f, + 0.572662353516f, -0.008331298828f, -0.010223388672f, 0.438751220703f, 0.579772949219f, + -0.007965087891f, -0.010131835938f, 0.431213378906f, 0.586853027344f, -0.007568359375f, + -0.010009765625f, 0.423645019531f, 0.593841552734f, -0.007141113281f, -0.009918212891f, + 0.416107177734f, 0.600769042969f, -0.006652832031f, -0.009796142578f, 0.408599853516f, + 0.607635498047f, -0.006134033203f, -0.009643554688f, 0.401092529297f, 0.614440917969f, + -0.005584716797f, -0.009490966797f, 0.393615722656f, 0.621154785156f, -0.004974365234f, + -0.009338378906f, 0.386138916016f, 0.627777099609f, -0.004364013672f, -0.009216308594f, + 0.378692626953f, 0.634338378906f, -0.003692626953f, -0.009033203125f, 0.371276855469f, + 0.640838623047f, -0.002960205078f, -0.008850097656f, 0.363891601562f, 0.647216796875f, + -0.002166748047f, -0.008636474609f, 0.356567382812f, 0.653533935547f, -0.001342773438f, + -0.008453369141f, 0.349243164062f, 0.659729003906f, -0.000488281250f, -0.008270263672f, + 0.341979980469f, 0.665832519531f, 0.000457763672f, -0.008087158203f, 0.334777832031f, + 0.671844482422f, 0.001434326172f, -0.007873535156f, 0.327606201172f, 0.677734375000f, + 0.002471923828f, -0.007629394531f, 0.320465087891f, 0.683563232422f, 0.003570556641f, + -0.007415771484f, 0.313385009766f, 0.689270019531f, 0.004699707031f, -0.007232666016f, + 0.306335449219f, 0.694854736328f, 0.005920410156f, -0.007019042969f, 0.299346923828f, + 0.700317382812f, 0.007202148438f, -0.006774902344f, 0.292449951172f, 0.705657958984f, + 0.008514404297f, -0.006561279297f, 0.285583496094f, 0.710906982422f, 0.009887695312f, + -0.006378173828f, 0.278778076172f, 0.716003417969f, 0.011322021484f, -0.006164550781f, + 0.272033691406f, 0.721008300781f, 0.012817382812f, -0.005920410156f, 0.265350341797f, + 0.725860595703f, 0.014404296875f, -0.005706787109f, 0.258728027344f, 0.730590820312f, + 0.016052246094f, -0.005523681641f, 0.252197265625f, 0.735198974609f, 0.017791748047f, + -0.005310058594f, 0.245727539062f, 0.739654541016f, 0.019561767578f, -0.005065917969f, + 0.239318847656f, 0.743988037109f, 0.021392822266f, -0.004852294922f, 0.233001708984f, + 0.748168945312f, 0.023315429688f, -0.004669189453f, 0.226745605469f, 0.752197265625f, + 0.025299072266f, -0.004455566406f, 0.220550537109f, 0.756103515625f, 0.027374267578f, + -0.004272460938f, 0.214447021484f, 0.759857177734f, 0.029510498047f, -0.004058837891f, + 0.208435058594f, 0.763488769531f, 0.031738281250f, -0.003875732422f, 0.202484130859f, + 0.766937255859f, 0.034027099609f, -0.003692626953f, 0.196594238281f, 0.770233154297f, + 0.036407470703f, -0.003509521484f, 0.190826416016f, 0.773376464844f, 0.038879394531f, + -0.003326416016f, 0.185119628906f, 0.776367187500f, 0.041412353516f, -0.003143310547f, + 0.179504394531f, 0.779205322266f, 0.044006347656f, -0.002990722656f, 0.173980712891f, + 0.781890869141f, 0.046722412109f, -0.002807617188f, 0.168518066406f, 0.784423828125f, + 0.049499511719f, -0.002655029297f, 0.163177490234f, 0.786743164062f, 0.052368164062f, + -0.002471923828f, 0.157897949219f, 0.788940429688f, 0.055328369141f, -0.002319335938f, + 0.152709960938f, 0.790985107422f, 0.058349609375f, -0.002197265625f, 0.147613525391f, + 0.792846679688f, 0.061492919922f, -0.002044677734f, 0.142608642578f, 0.794525146484f, + 0.064697265625f, -0.001922607422f, 0.137695312500f, 0.796051025391f, 0.067962646484f, + -0.001770019531f, 0.132873535156f, 0.797424316406f, 0.071350097656f, -0.001647949219f, + 0.128143310547f, 0.798614501953f, 0.074798583984f, -0.001525878906f, 0.123474121094f, + 0.799621582031f, 0.078369140625f, -0.001403808594f, 0.118927001953f, 0.800476074219f, + 0.082031250000f, -0.001281738281f, 0.114471435547f, 0.801177978516f, 0.085784912109f, + -0.001159667969f, 0.110107421875f, 0.801696777344f, 0.089599609375f, -0.001037597656f, + 0.105804443359f, 0.802032470703f, 0.093505859375f, -0.000976562500f, 0.101593017578f, + 0.802215576172f, 0.097503662109f, +}; + +const static double i2fMagic = 4503601774854144.0; + +// prototypes +static void do_src1(AXFX_CHORUS_SRCINFO* src); +static void do_src2(AXFX_CHORUS_SRCINFO* src); + +asm static void do_src1(register AXFX_CHORUS_SRCINFO* src) { + nofralloc + stwu r1, -64(r1) + stmw r26, 40(r1) + lwz r4, AXFX_CHORUS_SRCINFO.posLo(src) + lwz r5, AXFX_CHORUS_SRCINFO.posHi(src) + lwz r6, AXFX_CHORUS_SRCINFO.pitchLo(src) + lwz r8, AXFX_CHORUS_SRCINFO.trigger(src) + lwz r7, AXFX_CHORUS_SRCINFO.target(src) + lwz r31, AXFX_CHORUS_SRCINFO.smpBase(src) + lwz r30, AXFX_CHORUS_SRCINFO.dest(src) + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + lis r10, 0x4330 + stw r10, 8(r1) + stw r10, 16(r1) + stw r10, 24(r1) + stw r10, 32(r1) + lis r10, i2fMagic@ha + lfd f9, i2fMagic@l(r10) + slwi r10, r5, 2 + lwz r11, 0(r9) + lwz r29, 4(r9) + lwz r28, 8(r9) + lwzx r27, r31, r10 + xoris r11, r11, 0x8000 + xoris r29, r29, 0x8000 + stw r11, 12(r1) + xoris r28, r28, 0x8000 + stw r29, 20(r1) + xoris r27, r27, 0x8000 + stw r28, 28(r1) + lfd f1, 8(r1) + stw r27, 36(r1) + lfd f2, 16(r1) + fsubs f1, f1, f9 + lfd f3, 24(r1) + fsubs f2, f2, f9 + lfd f4, 32(r1) + fsubs f3, f3, f9 + fsubs f4, f4, f9 + li r26, -4 + lis r12, rsmpTab12khz@ha + addi r12, r12, rsmpTab12khz@l + li r9, 160 + mtctr r9 +L_000000AC: + rlwinm r10, r4, 7, 21, 27 + addc r4, r4, r6 + add r10, r10, r12 + mcrxr cr0 + lfs f5, 0(r10) + beq L_000000F4 + lfs f6, 4(r10) + fmuls f10, f1, f5 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmadds f10, f4, f8, f10 + fctiwz f10, f10 + stfiwx f10, r26, r30 + bdnz L_000000AC + b L_00000160 +L_000000F4: + addi r5, r5, 1 + lfs f6, 4(r10) + fmuls f10, f1, f5 + cmpw r5, r8 + fmr f1, f2 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + fmr f2, f3 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmr f3, f4 + bne+ L_0000012C + mr r5, r7 +L_0000012C: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000158 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_000000AC +L_00000158: + fctiwz f10, f10 + stfiwx f10, r26, r30 +L_00000160: + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + fctiwz f1, f1 + fctiwz f2, f2 + fctiwz f3, f3 + stfiwx f1, r0, r9 + addi r10, r9, 4 + stfiwx f2, r0, r10 + addi r10, r9, 8 + stfiwx f3, r0, r10 + stw r4, AXFX_CHORUS_SRCINFO.posLo(src) + stw r5, AXFX_CHORUS_SRCINFO.posHi(src) + lmw r26, 40(r1) + addi r1, r1, 64 + blr +} + +asm static void do_src2(register AXFX_CHORUS_SRCINFO* src) { + nofralloc + stwu r1, -64(r1) + stmw r26, 40(r1) + lwz r4, AXFX_CHORUS_SRCINFO.posLo(src) + lwz r5, AXFX_CHORUS_SRCINFO.posHi(src) + lwz r6, AXFX_CHORUS_SRCINFO.pitchLo(src) + lwz r8, AXFX_CHORUS_SRCINFO.trigger(src) + lwz r7, AXFX_CHORUS_SRCINFO.target(src) + lwz r31, AXFX_CHORUS_SRCINFO.smpBase(src) + lwz r30, AXFX_CHORUS_SRCINFO.dest(src) + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + lis r10, 0x4330 + stw r10, 8(r1) + stw r10, 16(r1) + stw r10, 24(r1) + stw r10, 32(r1) + lis r10, i2fMagic@ha + lfd f9, i2fMagic@l(r10) + slwi r10, r5, 2 + lwz r11, 0(r9) + lwz r29, 4(r9) + lwz r28, 8(r9) + lwzx r27, r31, r10 + xoris r11, r11, 0x8000 + xoris r29, r29, 0x8000 + stw r11, 12(r1) + xoris r28, r28, 0x8000 + stw r29, 20(r1) + xoris r27, r27, 0x8000 + stw r28, 28(r1) + lfd f1, 8(r1) + stw r27, 36(r1) + lfd f2, 16(r1) + fsubs f1, f1, f9 + lfd f3, 24(r1) + fsubs f2, f2, f9 + lfd f4, 32(r1) + fsubs f3, f3, f9 + fsubs f4, f4, f9 + li r26, -4 + lis r12, rsmpTab12khz@ha + addi r12, r12, rsmpTab12khz@l + li r9, 160 + mtctr r9 +L_00000244: + rlwinm r10, r4, 7, 21, 27 + addc r4, r4, r6 + add r10, r10, r12 + mcrxr cr0 + addi r5, r5, 1 + lfs f5, 0(r10) + beq L_000002C0 + lfs f6, 4(r10) + fmuls f10, f1, f5 + cmpw r5, r8 + fmr f1, f2 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + fmr f2, f3 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmr f3, f4 + bne+ L_00000294 + mr r5, r7 +L_00000294: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000344 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_00000244 +L_000002C0: + cmpw r5, r8 + lfs f6, 4(r10) + bne+ L_000002D0 + mr r5, r7 +L_000002D0: + slwi r11, r5, 2 + addi r5, r5, 1 + lwzx r29, r11, r31 + fmuls f10, f1, f5 + cmpw r5, r8 + xoris r29, r29, 0x8000 + fmr f1, f3 + lfs f7, 8(r10) + stw r29, 12(r1) + fmadds f10, f2, f6, f10 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + lfd f3, 8(r1) + fmr f2, f4 + addi r30, r30, 4 + fsubs f3, f3, f9 + bne+ L_00000318 + mr r5, r7 +L_00000318: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000344 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_00000244 +L_00000344: + fctiwz f10, f10 + stfiwx f10, r26, r30 + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + fctiwz f1, f1 + fctiwz f2, f2 + fctiwz f3, f3 + stfiwx f1, r0, r9 + addi r10, r9, 4 + stfiwx f2, r0, r10 + addi r10, r9, 8 + stfiwx f3, r0, r10 + stw r4, AXFX_CHORUS_SRCINFO.posLo(src) + stw r5, AXFX_CHORUS_SRCINFO.posHi(src) + lmw r26, 40(r1) + addi r1, r1, 64 + blr +} + +int AXFXChorusInit(AXFX_CHORUS* c) { + s32* left; + s32* right; + s32* sur; + u32 i; + BOOL old; + + ASSERTMSGLINE(1074, c->baseDelay >= 5 && c->baseDelay <= 15 && c->variation >= 0 && c->variation <= 5 && c->period >= 500 && c->period <= 10000, "The value of specified parameter is out of range."); + + if (c->baseDelay < 5 || c->baseDelay > 15 || c->variation < 0 || c->variation > 5 || c->period < 500 || c->period > 10000) { + return 0; + } + + old = OSDisableInterrupts(); + c->work.lastLeft[0] = __AXFXAlloc(0x1680); + ASSERTMSGLINE(0x442, c->work.lastLeft[0], "Can't allocate the memory."); + + if (c->work.lastLeft[0] != NULL) { + c->work.lastRight[0] = (void*)(c->work.lastLeft[0] + 0x1E0); + c->work.lastSur[0] = (void*)(c->work.lastRight[0] + 0x1E0); + + for (i = 1; i < 3; i++) { + c->work.lastLeft[i] = (void*)&c->work.lastLeft[0][i * 0xA0]; + c->work.lastRight[i] = (void*)&c->work.lastRight[0][i * 0xA0]; + c->work.lastSur[i] = (void*)&c->work.lastSur[0][i * 0xA0]; + } + + left = c->work.lastLeft[0]; + right = c->work.lastRight[0]; + sur = c->work.lastSur[0]; + + for (i = 0; i < 0x140; i++) { + *left++ = 0; + *right++ = 0; + *sur++ = 0; + } + + c->work.currentLast = 1; + c->work.oldLeft[0] = c->work.oldLeft[1] = c->work.oldLeft[2] = c->work.oldLeft[3] = 0; + c->work.oldRight[0] = c->work.oldRight[1] = c->work.oldRight[2] = c->work.oldRight[3] = 0; + c->work.oldSur[0] = c->work.oldSur[1] = c->work.oldSur[2] = c->work.oldSur[3] = 0; + c->work.src.trigger = 0x1E0; + c->work.src.target = 0; + OSRestoreInterrupts(old); + return AXFXChorusSettings(c); + } + + OSRestoreInterrupts(old); + return 0; +} + +int AXFXChorusShutdown(AXFX_CHORUS* c) { + BOOL old; + + old = OSDisableInterrupts(); + __AXFXFree(c->work.lastLeft[0]); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXChorusSettings(AXFX_CHORUS* c) { + BOOL old; + + ASSERTMSGLINE(1159, c->baseDelay >= 5 && c->baseDelay <= 15 && c->variation >= 0 && c->variation <= 5 && c->period >= 500 && c->period <= 10000, "The value of specified parameter is out of range."); + if (c->baseDelay < 5 || c->baseDelay > 15 || c->variation < 0 || c->variation > 5 || c->period < 500 || c->period > 10000) { + return 0; + } + + old = OSDisableInterrupts(); + c->work.currentPosHi = 0x140 - ((c->baseDelay - 5) << 5); + c->work.currentPosLo = 0; + c->work.currentPosHi = (c->work.currentPosHi + ((c->work.currentLast - 1) * 0xA0/1)) % 480; + c->work.pitchOffsetPeriod = ((c->period / 5) + 1) & ~(1); + c->work.pitchOffsetPeriodCount = c->work.pitchOffsetPeriod >> 1; + c->work.pitchOffset = (c->variation << 0x10) / (c->work.pitchOffsetPeriod * 5); + OSRestoreInterrupts(old); + return 1; +} + +void AXFXChorusCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_CHORUS* chorus) { + s32* leftD; + s32* rightD; + s32* surD; + s32* leftS; + s32* rightS; + s32* surS; + u32 i; + u8 nextCurrentLast; + + nextCurrentLast = (chorus->work.currentLast + 1) % 3; + leftD = chorus->work.lastLeft[nextCurrentLast]; + rightD = chorus->work.lastRight[nextCurrentLast]; + surD = chorus->work.lastSur[nextCurrentLast]; + leftS = bufferUpdate->left; + rightS = bufferUpdate->right; + surS = bufferUpdate->surround; + + for (i = 0; i < 0xA0; i++) { + *leftD++ = *leftS++; + *rightD++ = *rightS++; + *surD++ = *surS++; + } + + chorus->work.src.pitchHi = (chorus->work.pitchOffset >> 0x10) + 1; + chorus->work.src.pitchLo = (chorus->work.pitchOffset & 0xFFFF) << 0x10; + + if (--chorus->work.pitchOffsetPeriodCount == 0) { + chorus->work.pitchOffsetPeriodCount = chorus->work.pitchOffsetPeriod; + chorus->work.pitchOffset = -chorus->work.pitchOffset; + } + + for (i = 0; i < 3; i++) { + chorus->work.src.posHi = chorus->work.currentPosHi; + chorus->work.src.posLo = chorus->work.currentPosLo; + switch (i) { + case 0: + chorus->work.src.smpBase = chorus->work.lastLeft[0]; + chorus->work.src.dest = bufferUpdate->left; + chorus->work.src.old = &chorus->work.oldLeft[0]; + break; + case 1: + chorus->work.src.smpBase = chorus->work.lastRight[0]; + chorus->work.src.dest = bufferUpdate->right; + chorus->work.src.old = &chorus->work.oldRight[0]; + break; + case 2: + chorus->work.src.smpBase = chorus->work.lastSur[0]; + chorus->work.src.dest = bufferUpdate->surround; + chorus->work.src.old = &chorus->work.oldSur[0]; + break; + } + switch(chorus->work.src.pitchHi) { + case 0: + do_src1(&chorus->work.src); + break; + case 1: + do_src2(&chorus->work.src); + break; + } + } + + chorus->work.currentPosHi = (chorus->work.src.posHi % 480); + chorus->work.currentPosLo = chorus->work.src.posLo; + chorus->work.currentLast = nextCurrentLast; +} diff --git a/src/dolphin/axfx/src/delay.c b/src/dolphin/axfx/src/delay.c new file mode 100644 index 0000000..5c26e59 --- /dev/null +++ b/src/dolphin/axfx/src/delay.c @@ -0,0 +1,148 @@ +#include +#include +#include + +#include "__axfx.h" + +void AXFXDelayCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_DELAY* delay) { + s32 l; + s32 r; + s32 s; + s32* lBuf; + s32* rBuf; + s32* sBuf; + u32 i; + s32* left; + s32* right; + s32* sur; + + left = bufferUpdate->left; + right = bufferUpdate->right; + sur = bufferUpdate->surround; + lBuf = delay->left + (delay->currentPos[0] * 0xA0); + rBuf = delay->right + (delay->currentPos[1] * 0xA0); + sBuf = delay->sur + (delay->currentPos[2] * 0xA0); + + for (i = 0; i < 160; i++) { + l = *lBuf; + r = *rBuf; + s = *sBuf; + *lBuf++ = *left + ((s32)(l* delay->currentFeedback[0]) >> 7); + *rBuf++ = *right + ((s32)(r* delay->currentFeedback[1]) >> 7); + *sBuf++ = *sur + ((s32)(s* delay->currentFeedback[2]) >> 7); + *left++ = (s32)(l* delay->currentOutput[0]) >> 7; + *right++ = (s32)(r* delay->currentOutput[1]) >> 7; + *sur++ = (s32)(s* delay->currentOutput[2]) >> 7; + } + + delay->currentPos[0] = (s32) ((delay->currentPos[0] + 1) % delay->currentSize[0]); + delay->currentPos[1] = (s32) ((delay->currentPos[1] + 1) % delay->currentSize[1]); + delay->currentPos[2] = (s32) ((delay->currentPos[2] + 1) % delay->currentSize[2]); +} + +int AXFXDelaySettings(AXFX_DELAY* delay) { + u32 i; + s32* l; + s32* r; + s32* s; + BOOL old; + + ASSERTMSGLINE(67, delay->delay[0] >= 10 && delay->delay[0] <= 5000 && + delay->delay[1] >= 10 && delay->delay[1] <= 5000 && + delay->delay[2] >= 10 && delay->delay[2] <= 5000 && + delay->feedback[0] >= 0 && delay->feedback[0] <= 100 && + delay->feedback[1] >= 0 && delay->feedback[1] <= 100 && + delay->feedback[2] >= 0 && delay->feedback[2] <= 100 && + delay->output[0] >= 0 && delay->output[0] <= 100 && + delay->output[1] >= 0 && delay->output[1] <= 100 && + delay->output[2] >= 0 && delay->output[2] <= 100, + "The value of specified parameter is out of range."); + + if (delay->delay[0] < 10 || delay->delay[0] > 5000 || + delay->delay[1] < 10 || delay->delay[1] > 5000 || + delay->delay[2] < 10 || delay->delay[2] > 5000 || + delay->feedback[0] < 0 || delay->feedback[0] > 100 || + delay->feedback[1] < 0 || delay->feedback[1] > 100 || + delay->feedback[2] < 0 || delay->feedback[2] > 100 || + delay->output[0] < 0 || delay->output[0] > 100 || + delay->output[1] < 0 || delay->output[1] > 100 || + delay->output[2] < 0 || delay->output[2] > 100) + { + return 0; + } + + AXFXDelayShutdown(delay); + old = OSDisableInterrupts(); + + for (i = 0; i < 3; i++) { + delay->currentSize[i] = (((delay->delay[i] - 5) << 5) + 0x9F) / 160U; + delay->currentPos[i] = 0; + delay->currentFeedback[i] = (delay->feedback[i] << 7) / 100U; + delay->currentOutput[i] = (delay->output[i] << 7) / 100U; + } + + delay->left = __AXFXAlloc(delay->currentSize[0] * 0xA0 * 4); + delay->right = __AXFXAlloc(delay->currentSize[1] * 0xA0 * 4); + delay->sur = __AXFXAlloc(delay->currentSize[2] * 0xA0 * 4); + + ASSERTMSGLINE(98, delay->left && delay->right && delay->sur, "Can't allocate the memory."); + + if (delay->left == NULL || delay->right == NULL || delay->sur == NULL) { + AXFXDelayShutdown(delay); + return 0; + } + + l = delay->left; + r = delay->right; + s = delay->sur; + + for (i = 0; i < delay->currentSize[0] * 0xA0; i++) { + *l++ = 0; + } + + for (i = 0; i < delay->currentSize[1] * 0xA0; i++) { + *r++ = 0; + } + + for (i = 0; i < delay->currentSize[2] * 0xA0; i++) { + *s++ = 0; + } + + OSRestoreInterrupts(old); + return 1; +} + +int AXFXDelayInit(AXFX_DELAY* delay) { + BOOL old; + + old = OSDisableInterrupts(); + delay->left = NULL; + delay->right = NULL; + delay->sur = NULL; + OSRestoreInterrupts(old); + AXFXDelaySettings(delay); +} + +int AXFXDelayShutdown(AXFX_DELAY* delay) { + BOOL old; + + old = OSDisableInterrupts(); + if (delay->left) { + __AXFXFree(delay->left); + } + + if (delay->right) { + __AXFXFree(delay->right); + } + + if (delay->sur) { + __AXFXFree(delay->sur); + } + + delay->left = NULL; + delay->right = NULL; + delay->sur = NULL; + + OSRestoreInterrupts(old); + return 1; +} diff --git a/src/dolphin/axfx/src/reverb_hi.c b/src/dolphin/axfx/src/reverb_hi.c new file mode 100644 index 0000000..cba8c2a --- /dev/null +++ b/src/dolphin/axfx/src/reverb_hi.c @@ -0,0 +1,890 @@ +#include +#include +#include +#include + +#include "__axfx.h" + +// prototypes +static void DLsetdelay(AXFX_REVHI_DELAYLINE* dl, s32 lag); +static int DLcreate(AXFX_REVHI_DELAYLINE* dl, s32 max_length); +static void DLdelete(AXFX_REVHI_DELAYLINE* dl); +static int ReverbHICreate(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, + f32 preDelay, f32 crosstalk); +static int ReverbHIModify(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, + f32 preDelay, f32 crosstalk); +static void HandleReverb(s32* sptr, AXFX_REVHI_WORK* rv, s32 k); +static void ReverbHICallback(s32* left, s32* right, s32* surround, AXFX_REVHI_WORK* rv); +static void ReverbHIFree(AXFX_REVHI_WORK* rv); + +static void DLsetdelay(AXFX_REVHI_DELAYLINE* dl, s32 lag) +{ + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) + { + dl->outPoint += dl->length; + } +} + +static int DLcreate(AXFX_REVHI_DELAYLINE* dl, s32 max_length) +{ + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length << 2); + ASSERTMSGLINE(51, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) + { + return 0; + } + + memset(dl->inputs, 0, max_length << 2); + dl->lastOutput = 0.0f; + DLsetdelay(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdelete(AXFX_REVHI_DELAYLINE* dl) +{ + __AXFXFree(dl->inputs); +} + +static int ReverbHICreate(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, + f32 preDelay, f32 crosstalk) +{ + u8 i; + u8 k; + static s32 lens[8] = { 0x000006FD, 0x000007CF, 0x0000091D, 0x000001B1, + 0x00000095, 0x0000002F, 0x00000049, 0x00000043 }; + + ASSERTMSGLINE(105, + coloration >= 0.0f && coloration <= 1.0f && time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && crosstalk >= 0.0f && crosstalk <= 1.0f && + damping >= 0.0f && damping <= 1.0f && preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f) || (coloration > 1.0f) || (time < 0.01f) || (time > 10.0f) || + (mix < 0.0f) || (mix > 1.0f) || (crosstalk < 0.0f) || (crosstalk > 1.0f) || + (damping < 0.0f) || (damping > 1.0f) || (preDelay < 0.0f) || (preDelay > 0.1f)) + { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVHI_WORK)); + + for (k = 0; k < 3; k++) + { + for (i = 0; i < 3; i++) + { + if (DLcreate(&rv->C[i + (k * 3)], lens[i] + 2) == 0) + { + ReverbHIFree(rv); + return 0; + } + + DLsetdelay(&rv->C[i + (k * 3)], lens[i]); + rv->combCoef[i + (k * 3)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) + { + if (DLcreate(&rv->AP[i + (k * 3)], lens[i + 3] + 2) == 0) + { + ReverbHIFree(rv); + return 0; + } + DLsetdelay(&rv->AP[i + (k * 3)], lens[i + 3]); + } + + if (DLcreate(&rv->AP[2 + (k * 3)], lens[k + 5] + 2) == 0) + { + ReverbHIFree(rv); + return 0; + } + DLsetdelay(&rv->AP[2 + (k * 3)], lens[k + 5]); + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->crosstalk = crosstalk; + rv->damping = damping; + if (rv->damping < 0.05f) + { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + if (0.0f != preDelay) + { + rv->preDelayTime = (32000.0f * preDelay); + for (i = 0; i < 3; i++) + { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(173, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) + { + ReverbHIFree(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } + else + { + rv->preDelayTime = 0; + for (i = 0; i < 3; i++) + { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbHIModify(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, + f32 preDelay, f32 crosstalk) +{ + u8 i; + + ASSERTMSGLINE(209, + coloration >= 0.0f && coloration <= 1.0f && time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && crosstalk >= 0.0f && crosstalk <= 1.0f && + damping >= 0.0f && damping <= 1.0f && preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f) || (coloration > 1.0f) || (time < 0.01f) || (time > 10.0f) || + (mix < 0.0f) || (mix > 1.0f) || (crosstalk < 0.0f) || (crosstalk > 1.0f) || + (damping < 0.0f) || (damping > 1.0f) || (preDelay < 0.0f) || (preDelay > 0.1f)) + { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->crosstalk = crosstalk; + rv->damping = damping; + if (rv->damping < 0.05f) + { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 9; i++) + { + DLdelete(&rv->AP[i]); + } + + for (i = 0; i < 9; i++) + { + DLdelete(&rv->C[i]); + } + + if (rv->preDelayTime) + { + for (i = 0; i < 3; i++) + { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbHICreate(rv, coloration, time, mix, damping, preDelay, crosstalk); +} + +const static double i2fMagic = 4503601774854144.0; +const static f32 value1_0 = 1.0f; +const static f32 value0_3 = 0.3f; +const static f32 value0_6 = 0.6f; + +asm static void DoCrossTalk(register s32* l, register s32* r, register f32 cross, + register f32 invcross) +{ + nofralloc stwu r1, -48(r1)stfd f14, 40(r1)lis r5, i2fMagic @ha lfd f0, i2fMagic @l(r5) lis r5, + 0x4330 // 176.0f (0x43300000) + stw r5, + 8(r1)stw r5, 16(r1)stw r5, 24(r1)stw r5, 32(r1)ps_merge00 f3, invcross, cross ps_merge00 f4, + cross, invcross lis r5, value1_0 @ha lfs f5, value1_0 @l(r5) li r5, 79 mtctr r5 li r10, + -8 li r11, -4 ps_muls0 f4, f4, f5 lwz r6, 0(l)lwz r7, 0(r)xoris r6, r6, 0x8000 lwz r8, + 4(l)xoris r7, r7, 0x8000 lwz r9, 4(r)xoris r8, r8, 0x8000 stw r6, 12(r1)xoris r9, r9, + 0x8000 stw r7, 20(r1)stw r8, 28(r1)stw r9, 36(r1)lfd f5, 8(r1)lfd f6, 16(r1)fsubs f5, f5, + f0 lfd f7, 24(r1)fsubs f6, f6, f0 lfd f8, 32(r1)fsubs f7, f7, f0 fsubs f8, f8, + f0 loop : ps_merge00 f9, + f5, + f6 lwzu r6, + 8(l)ps_merge00 f10, + f7, + f8 lwzu r7, + 8(r)xoris r6, + r6, + 0x8000 lwz r8, + 4(l)ps_mul f11, + f9, + f3 xoris r7, + r7, + 0x8000 ps_mul f12, + f9, + f4 lwz r9, + 4(r)ps_mul f13, + f10, + f3 xoris r8, + r8, + 0x8000 ps_mul f14, + f10, + f4 stw r6, + 12(r1)ps_sum0 f11, + f11, + f11, + f11 xoris r9, + r9, + 0x8000 ps_sum0 f12, + f12, + f12, + f12 stw r7, + 20(r1)ps_sum0 f13, + f13, + f13, + f13 stw r8, + 28(r1)ps_sum0 f14, + f14, + f14, + f14 stw r9, + 36(r1)fctiw f11, + f11 lfd f5, + 8(r1)fctiw f12, + f12 lfd f6, + 16(r1)fctiw f13, + f13 fsubs f5, + f5, + f0 fctiw f14, + f14 lfd f7, + 24(r1)stfiwx f11, + r10, + l fsubs f6, + f6, + f0 stfiwx f12, + r10, + r lfd f8, + 32(r1)stfiwx f13, + r11, + l fsubs f7, + f7, + f0 stfiwx f14, + r11, + r fsubs f8, + f8, + f0 bdnz loop ps_merge00 f9, + f5, + f6 addi l, + l, + 8 ps_merge00 f10, + f7, + f8 addi r, + r, + 8 ps_mul f11, + f9, + f3 ps_mul f12, + f9, + f4 ps_mul f13, + f10, + f3 ps_mul f14, + f10, + f4 ps_sum0 f11, + f11, + f11, + f11 ps_sum0 f12, + f12, + f12, + f12 ps_sum0 f13, + f13, + f13, + f13 ps_sum0 f14, + f14, + f14, + f14 fctiw f11, + f11 fctiw f12, + f12 fctiw f13, + f13 fctiw f14, + f14 stfiwx f11, + r10, + l stfiwx f12, + r10, + r stfiwx f13, + r11, + l stfiwx f14, + r11, + r lfd f14, + 40(r1)addi r1, + r1, + 48 blr +} + +asm static void HandleReverb(register s32* sptr, register AXFX_REVHI_WORK* rv, register s32 k) +{ + nofralloc stwu r1, -0xc0(r1)stmw r14, 0x8(r1)stfd f14, 0x60(r1)stfd f15, 0x68(r1)stfd f16, + 0x70(r1)stfd f17, 0x78(r1)stfd f18, 0x80(r1)stfd f19, 0x88(r1)stfd f20, 0x90(r1)stfd f21, + 0x98(r1)stfd f22, 0xa0(r1)stfd f23, 0xa8(r1)stfd f24, 0xb0(r1)stfd f25, 0xb8(r1)stw k, + 0x50(r1)stw rv, 0x54(r1)lis r31, value0_3 @ha lfs f6, value0_3 @l(r31) lis r31, + value0_6 @ha lfs f9, value0_6 @l(r31) lis r31, i2fMagic @ha lfd f5, i2fMagic @l(r31) lfs f2, + AXFX_REVHI_WORK.allPassCoeff(rv) lfs f15, AXFX_REVHI_WORK.damping(rv) lfs f8, + AXFX_REVHI_WORK.level(rv) fmuls f3, f8, f9 fsubs f4, f9, f3 slwi r30, k, 1 add r30, r30, + k mulli r31, r30, 0x14 addi r29, rv, AXFX_REVHI_WORK.C add r29, r29, r31 addi r27, rv, + AXFX_REVHI_WORK.AP add r27, r27, r31 slwi r31, r30, 2 add r31, r31, rv lfs f22, + AXFX_REVHI_WORK.combCoef[0](r31) lfs f23, AXFX_REVHI_WORK.combCoef[1](r31) lfs f24, + AXFX_REVHI_WORK.combCoef[2](r31) slwi r31, k, 2 add r31, r31, rv lfs f25, + AXFX_REVHI_WORK.lpLastout[0](r31) lwz r31, AXFX_REVHI_WORK.preDelayTime(rv) lis r30, + 0x4330 stw r30, 0x58(r1)subi r22, r31, 1 slwi r22, r22, 2 slwi r28, k, 2 add r28, r28, + rv cmpwi cr7, r31, 0 lwz r21, + AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + lwz r20, + AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + lwz r19, + AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + lwz r18, + AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + lwz r17, + AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + lwz r16, + AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + lfs f16, + AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + lfs f17, + AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + lfs f18, + AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + lwz r25, + AXFX_REVHI_DELAYLINE.length + 0x00(r29) // C[0] + lwz r24, + AXFX_REVHI_DELAYLINE.length + 0x14(r29) // C[1] + lwz r23, + AXFX_REVHI_DELAYLINE.length + 0x28(r29) // C[2] + lwz r4, + AXFX_REVHI_DELAYLINE.inputs + 0x00(r29) // C[0] + lwz r5, + AXFX_REVHI_DELAYLINE.inputs + 0x14(r29) // C[1] + lwz r6, + AXFX_REVHI_DELAYLINE.inputs + 0x28(r29) // C[2] + lwz r12, + AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + lwz r11, + AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + lwz r10, + AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + lwz r9, + AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + lwz r8, + AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + lwz r7, + AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + lfs f19, + AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + lfs f20, + AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + lfs f21, + AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + lwz r15, + AXFX_REVHI_DELAYLINE.length + 0x00(r27) // AP[0] + lwz r14, + AXFX_REVHI_DELAYLINE.length + 0x14(r27) // AP[1] + //? missing load for length of AP[3]? Maybe intentional? + lwz r30, + 0(r3)xoris r30, r30, 0x8000 stw r30, 0x5c(r1)lfd f12, 0x58(r1)fsubs f12, f12, f5 li r31, + 159 mtctr r31 L_00000964 : fmr f13, + f12 beq cr7, + L_00000994 lwz r30, + AXFX_REVHI_WORK.preDelayLine(r28) lwz r29, + AXFX_REVHI_WORK.preDelayPtr(r28) add r31, + r22, + r30 addi r29, + r29, + 4 lfs f13, + -4(r29)cmpw r29, + r31 stfs f12, + -4(r29)bne + L_00000990 mr r29, + r30 L_00000990 + : stw r29, + AXFX_REVHI_WORK.preDelayPtr(r30) L_00000994 : fmadds f8, + f22, + f16, + f13 lwzu r29, + 4(r3)fmadds f9, + f23, + f17, + f13 stfsx f8, + rv, + r21 addi r21, + r21, + 4 stfsx f9, + k, + r19 lfsx f14, + rv, + r20 addi r20, + r20, + 4 lfsx f17, + k, + r18 cmpw r21, + r25 cmpw cr1, + r20, + r25 addi r19, + r19, + 4 addi r18, + r18, + 4 fmr f16, + f14 cmpw cr5, + r19, + r24 fadds f14, + f14, + f17 cmpw cr6, + r18, + r24 bne + L_000009E0 li r21, + 0 L_000009E0 : fmadds f8, + f24, + f18, + f13 bne + cr1, + L_000009EC li r20, + 0 L_000009EC : stfsx f8, + r6, + r17 addi r17, + r17, + 4 bne + cr5, + L_000009FC li r19, + 0 L_000009FC : lfsx f18, + r6, + r16 addi r16, + r16, + 4 cmpw r17, + r23 bne + cr6, + L_00000A10 li r18, + 0 L_00000A10 + : fadds f14, + f14, + f18 cmpw cr1, + r16, + r23 lwz r26, + AXFX_REVHI_DELAYLINE.inputs(r27) fmadds f9, + f2, + f19, + f14 bne + L_00000A28 li r17, + 0 L_00000A28 : bne + cr1, + L_00000A30 li r16, + 0 L_00000A30 : xoris r29, + r29, + 0x8000 stfsx f9, + r26, + r12 fnmsubs f14, + f2, + f9, + f19 addi r12, + r12, + 4 lfsx f19, + r26, + r11 cmpw cr5, + r12, + r15 addi r11, + r11, + 4 lwz r26, + AXFX_REVHI_DELAYLINE.inputs + 0x14(r27)cmpw cr6, + r11, + r15 fmadds f8, + f2, + f20, + f14 bne + cr5, + L_00000A60 li r12, + 0x0 L_00000A60 : stw r29, + 0x5c(r1)stfsx f8, + r26, + r10 fnmsubs f14, + f2, + f8, + f20 addi r10, + r10, + 4 bne + cr6, + L_00000A78 li r11, + 0 L_00000A78 : lfsx f20, + r26, + r9 cmpw r10, + r14 fmuls f14, + f14, + f6 addi r9, + r9, + 4 cmpw cr1, + r9, + r14 lfd f10, + 0x58(r1)fmadds f14, + f15, + f25, + f14 bne + L_00000A9C li r10, + 0 L_00000A9C + : lwz r26, + AXFX_REVHI_DELAYLINE.inputs + 0x28(r27)fmadds f9, + f2, + f21, + f14 fmr f25, + f14 bne + cr1, + L_00000AB0 li r9, + 0 L_00000AB0 : stfsx f9, + r26, + r8 fnmsubs f14, + f2, + f9, + f21 lwz r31, + AXFX_REVHI_DELAYLINE.length + 0x28(r27)fmuls f8, + f4, + f12 lfsx f21, + r26, + r7 addi r8, + r8, + 4 addi r7, + r7, + 4 fmadds f14, + f3, + f14, + f8 cmpw cr5, + r8, + r31 cmpw cr6, + r7, + r31 fctiwz f14, + f14 bne + cr5, + L_00000AE4 li r8, + 0 L_00000AE4 : bne + cr6, + L_00000AEC li r7, + 0 L_00000AEC : li r31, + -4 fsubs f12, + f10, + f5 stfiwx f14, + sptr, + r31 bdnz L_00000964 fmr f13, + f12 beq cr7, + L_00000B2C lwz r30, + AXFX_REVHI_WORK.preDelayLine(r28) lwz r29, + AXFX_REVHI_WORK.preDelayPtr(r28) add r31, + r22, + r30 addi r29, + r29, + 4 lfs f13, + -4(r29)cmpw r29, + r31 stfs f12, + -4(r29)bne + L_00000B28 mr r29, + r30 L_00000B28 + : stw r29, + AXFX_REVHI_WORK.preDelayPtr(r30) L_00000B2C : fmadds f8, + f22, + f16, + f13 fmadds f9, + f23, + f17, + f13 stfsx f8, + rv, + r21 addi r21, + r21, + 4 stfsx f9, + k, + r19 lfsx f14, + rv, + r20 addi r20, + r20, + 4 lfsx f17, + k, + r18 cmpw r21, + r25 cmpw cr1, + r20, + r25 addi r19, + r19, + 4 addi r18, + r18, + 4 fmr f16, + f14 cmpw cr5, + r19, + r24 fadds f14, + f14, + f17 cmpw cr6, + r18, + r24 bne + L_00000B74 li r21, + 0 L_00000B74 : fmadds f8, + f24, + f18, + f13 bne + cr1, + L_00000B80 li r20, + 0 L_00000B80 : stfsx f8, + r6, + r17 addi r17, + r17, + 4 bne + cr5, + L_00000B90 li r19, + 0 L_00000B90 : lfsx f18, + r6, + r16 addi r16, + r16, + 4 cmpw r17, + r23 bne + cr6, + L_00000BA4 li r18, + 0 L_00000BA4 + : fadds f14, + f14, + f18 cmpw cr1, + r16, + r23 lwz r26, + AXFX_REVHI_DELAYLINE.inputs(r27) fmadds f9, + f2, + f19, + f14 bne + L_00000BBC li r17, + 0 L_00000BBC : bne + cr1, + L_00000BC4 li r16, + 0 L_00000BC4 : stfsx f9, + r26, + r12 fnmsubs f14, + f2, + f9, + f19 addi r12, + r12, + 4 lfsx f19, + r26, + r11 cmpw cr5, + r12, + r15 addi r11, + r11, + 4 lwz r26, + AXFX_REVHI_DELAYLINE.inputs + 0x14(r27)cmpw cr6, + r11, + r15 fmadds f8, + f2, + f20, + f14 bne + cr5, + L_00000BF0 li r12, + 0 L_00000BF0 : stfsx f8, + r26, + r10 fnmsubs f14, + f2, + f8, + f20 addi r10, + r10, + 4 bne + cr6, + L_00000C04 li r11, + 0 L_00000C04 : lfsx f20, + r26, + r9 cmpw r10, + r14 fmuls f14, + f14, + f6 addi r9, + r9, + 4 cmpw cr1, + r9, + r14 fmadds f14, + f15, + f25, + f14 bne + L_00000C24 li r10, + 0 L_00000C24 + : lwz r26, + AXFX_REVHI_DELAYLINE.inputs + 0x28(r27)lwz k, + 0x50(r1)lwz rv, + 0x54(r1)fmadds f9, + f2, + f21, + f14 fmr f25, + f14 bne + cr1, + L_00000C40 li r9, + 0 L_00000C40 : stfsx f9, + r26, + r8 fnmsubs f14, + f2, + f9, + f21 lwz r29, + AXFX_REVHI_DELAYLINE.length + 0x28(r27)fmuls f8, + f4, + f12 lfsx f21, + r26, + r7 addi r8, + r8, + 4 addi r7, + r7, + 4 fmadds f14, + f3, + f14, + f8 cmpw cr5, + r8, + r29 cmpw cr6, + r7, + r29 fctiwz f14, + f14 bne + cr5, + L_00000C74 li r8, + 0 L_00000C74 : bne + cr6, + L_00000C7C li r7, + 0 L_00000C7C : slwi r30, + k, + 1 add r30, + r30, + k mulli r31, + r30, + 0x14 // sizeof AXFX_REVHI_DELAYLINE + stfiwx f14, + r0, + sptr addi r29, + rv, + AXFX_REVHI_WORK.C add r29, + r29, + r31 stw r21, + AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + stw r20, + AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + stw r19, + AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + stw r18, + AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + stw r17, + AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + stw r16, + AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + stfs f16, + AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + stfs f17, + AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + stfs f18, + AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + stw r12, + AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + stw r11, + AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + stw r10, + AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + stw r9, + AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + stw r8, + AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + stw r7, + AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + stfs f19, + AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + stfs f20, + AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + stfs f21, + AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + slwi r31, + k, + 2 add r31, + r31, + rv stfs f25, + AXFX_REVHI_WORK.lpLastout(r31) lfd f14, + 0x60(r1)lfd f15, + 0x68(r1)lfd f16, + 0x70(r1)lfd f17, + 0x78(r1)lfd f18, + 0x80(r1)lfd f19, + 0x88(r1)lfd f20, + 0x90(r1)lfd f21, + 0x98(r1)lfd f22, + 0xa0(r1)lfd f23, + 0xa8(r1)lfd f24, + 0xb0(r1)lfd f25, + 0xb8(r1)lmw r14, + 0x8(r1)addi r1, + r1, + 0xc0 blr +} + +static void ReverbHICallback(s32* left, s32* right, s32* surround, AXFX_REVHI_WORK* rv) +{ + u8 k; + + for (k = 0; k < 3; k++) + { + switch (k) + { + case 0: + if (0.0f != rv->crosstalk) + { + DoCrossTalk(left, right, 0.5f * rv->crosstalk, 1.0f - (0.5f * rv->crosstalk)); + } + HandleReverb(left, rv, 0); + break; + case 1: + HandleReverb(right, rv, 1); + break; + case 2: + HandleReverb(surround, rv, 2); + break; + } + } +} + +static void ReverbHIFree(AXFX_REVHI_WORK* rv) +{ + u8 i; + + for (i = 0; i < 9; i++) + { + if (rv->AP[i].inputs != 0) + { + DLdelete(&rv->AP[i]); + rv->AP[i].inputs = NULL; + } + } + + for (i = 0; i < 9; i++) + { + if (rv->C[i].inputs != 0) + { + DLdelete(&rv->C[i]); + rv->C[i].inputs = NULL; + } + } + + if (rv->preDelayTime) + { + for (i = 0; i < 3; i++) + { + if (rv->preDelayLine[i] != 0) + { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = NULL; + } + } + } +} + +int AXFXReverbHiInit(AXFX_REVERBHI* rev) +{ + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 0; + ret = ReverbHICreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, + rev->preDelay, rev->crosstalk); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbHiShutdown(AXFX_REVERBHI* rev) +{ + BOOL old; + + old = OSDisableInterrupts(); + ReverbHIFree(&rev->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbHiSettings(AXFX_REVERBHI* rev) +{ + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbHIModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, + rev->preDelay, rev->crosstalk); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbHiCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBHI* reverb) +{ + if (reverb->tempDisableFX == 0) + { + ReverbHICallback(bufferUpdate->left, bufferUpdate->right, bufferUpdate->surround, + &reverb->rv); + } +} diff --git a/src/dolphin/axfx/src/reverb_hi_4ch.c b/src/dolphin/axfx/src/reverb_hi_4ch.c new file mode 100644 index 0000000..df10073 --- /dev/null +++ b/src/dolphin/axfx/src/reverb_hi_4ch.c @@ -0,0 +1,611 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__axfx.h" + +static void ReverbHIDpl2Free(AXFX_REVHI_WORK_DPL2* rv); + +static void DLsetdelayDpl2(AXFX_REVHI_DELAYLINE* dl, s32 lag) { + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) { + dl->outPoint += dl->length; + } +} + +static int DLcreateDpl2(AXFX_REVHI_DELAYLINE* dl, s32 max_length) { + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length << 2); + ASSERTMSGLINE(62, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) { + return 0; + } + + memset(dl->inputs, 0, max_length << 2); + dl->lastOutput = 0.0f; + DLsetdelayDpl2(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdeleteDpl2(AXFX_REVHI_DELAYLINE* dl) { + __AXFXFree(dl->inputs); +} + +static int ReverbHICreateDpl2(AXFX_REVHI_WORK_DPL2* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay) { + u8 i; + u8 k; + + static s32 lens[9] = { + 0x000006FD, + 0x000007CF, + 0x0000091D, + 0x000001B1, + 0x00000095, + 0x0000002F, + 0x00000049, + 0x00000043, + 0x00000047 + }; + + ASSERTMSGLINE(117, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f )) { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVHI_WORK_DPL2)); + + for (k = 0; k < 4; k++) { + for (i = 0; i < 3; i++) { + if (DLcreateDpl2(&rv->C[i + (k * 3)], lens[i] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->C[i + (k * 3)], lens[i]); + rv->combCoef[i + (k * 3)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) { + if (DLcreateDpl2(&rv->AP[i + (k * 3)], lens[i + 3] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->AP[i + (k * 3)], lens[i + 3]); + } + + if (DLcreateDpl2(&rv->AP[2 + (k * 3)], lens[k + 5] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->AP[2 + (k * 3)], lens[k + 5]); + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + if (0.0f != preDelay) { + rv->preDelayTime = (32000.0f * preDelay); + for (i = 0; i < 4; i++) { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(188, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) { + ReverbHIDpl2Free(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } else { + rv->preDelayTime = 0; + for (i = 0; i < 4; i++) { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbHIModifyDpl2(AXFX_REVHI_WORK_DPL2* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay) { + u8 i; + + ASSERTMSGLINE(222, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f ) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f)) { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 12; i++) { + DLdeleteDpl2(&rv->AP[i]); + } + + for (i = 0; i < 12; i++) { + DLdeleteDpl2(&rv->C[i]); + } + + if (rv->preDelayTime) { + for (i = 0; i < 4; i++) { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbHICreateDpl2(rv, coloration, time, mix, damping, preDelay); +} + + +const static f32 value0_6 = 0.6f; +const static f32 value0_3 = 0.3f; +const static double i2fMagic = 4503601774854144.0; + +asm static void HandleReverbDpl2(register s32* sptr, register AXFX_REVHI_WORK_DPL2* rv, register s32 k) { + nofralloc + stwu r1, -0xc0(r1) + stmw r14, 0x8(r1) + stfd f14, 0x60(r1) + stfd f15, 0x68(r1) + stfd f16, 0x70(r1) + stfd f17, 0x78(r1) + stfd f18, 0x80(r1) + stfd f19, 0x88(r1) + stfd f20, 0x90(r1) + stfd f21, 0x98(r1) + stfd f22, 0xa0(r1) + stfd f23, 0xa8(r1) + stfd f24, 0xb0(r1) + stfd f25, 0xb8(r1) + stw k, 0x50(r1) + stw rv, 0x54(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, AXFX_REVHI_WORK_DPL2.allPassCoeff(rv) + lfs f15, AXFX_REVHI_WORK_DPL2.damping(rv) + lfs f8, AXFX_REVHI_WORK_DPL2.level(rv) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 + addi r29, rv, AXFX_REVHI_WORK_DPL2.C + add r29, r29, r31 + addi r27, rv, AXFX_REVHI_WORK_DPL2.AP + add r27, r27, r31 + slwi r31, r30, 2 + add r31, r31, rv + lfs f22, AXFX_REVHI_WORK_DPL2.combCoef[0](r31) + lfs f23, AXFX_REVHI_WORK_DPL2.combCoef[1](r31) + lfs f24, AXFX_REVHI_WORK_DPL2.combCoef[2](r31) + slwi r31, k, 2 + add r31, r31, rv + lfs f25, AXFX_REVHI_WORK_DPL2.lpLastout[0](r31) + lwz r31, AXFX_REVHI_WORK_DPL2.preDelayTime(rv) + lis r30, 0x4330 + stw r30, 0x58(r1) + subi r22, r31, 1 + slwi r22, r22, 2 + slwi r28, k, 2 + add r28, r28, rv + cmpwi cr7, r31, 0 + lwz r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + lwz r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + lwz r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + lwz r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + lwz r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + lwz r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + lfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + lfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + lfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + lwz r25, AXFX_REVHI_DELAYLINE.length + 0x00(r29) // C[0] + lwz r24, AXFX_REVHI_DELAYLINE.length + 0x14(r29) // C[1] + lwz r23, AXFX_REVHI_DELAYLINE.length + 0x28(r29) // C[2] + lwz r4, AXFX_REVHI_DELAYLINE.inputs + 0x00(r29) // C[0] + lwz r5, AXFX_REVHI_DELAYLINE.inputs + 0x14(r29) // C[1] + lwz r6, AXFX_REVHI_DELAYLINE.inputs + 0x28(r29) // C[2] + lwz r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + lwz r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + lwz r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + lwz r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + lwz r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + lwz r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + lfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + lfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + lfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + lwz r15, AXFX_REVHI_DELAYLINE.length + 0x00(r27) // AP[0] + lwz r14, AXFX_REVHI_DELAYLINE.length + 0x14(r27) // AP[1] + //? missing load for length of AP[3]? Maybe intentional? + lwz r30, 0(r3) + xoris r30, r30, 0x8000 + stw r30, 0x5c(r1) + lfd f12, 0x58(r1) + fsubs f12, f12, f5 + li r31, 159 + mtctr r31 +L_00000964: + fmr f13, f12 + beq cr7, L_00000994 + lwz r30, AXFX_REVHI_WORK_DPL2.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000990 + mr r29, r30 +L_00000990: + stw r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r30) +L_00000994: + fmadds f8, f22, f16, f13 + lwzu r29, 4(r3) + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_000009E0 + li r21, 0 +L_000009E0: + fmadds f8, f24, f18, f13 + bne+ cr1, L_000009EC + li r20, 0 +L_000009EC: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_000009FC + li r19, 0 +L_000009FC: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000A10 + li r18, 0 +L_00000A10: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000A28 + li r17, 0 +L_00000A28: + bne+ cr1, L_00000A30 + li r16, 0 +L_00000A30: + xoris r29, r29, 0x8000 + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000A60 + li r12, 0x0 +L_00000A60: + stw r29, 0x5c(r1) + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000A78 + li r11, 0 +L_00000A78: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + lfd f10, 0x58(r1) + fmadds f14, f15, f25, f14 + bne+ L_00000A9C + li r10, 0 +L_00000A9C: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000AB0 + li r9, 0 +L_00000AB0: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r31, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r31 + cmpw cr6, r7, r31 + fctiwz f14, f14 + bne+ cr5, L_00000AE4 + li r8, 0 +L_00000AE4: + bne+ cr6, L_00000AEC + li r7, 0 +L_00000AEC: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, sptr, r31 + bdnz L_00000964 + fmr f13, f12 + beq cr7, L_00000B2C + lwz r30, AXFX_REVHI_WORK_DPL2.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000B28 + mr r29, r30 +L_00000B28: + stw r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r30) +L_00000B2C: + fmadds f8, f22, f16, f13 + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_00000B74 + li r21, 0 +L_00000B74: + fmadds f8, f24, f18, f13 + bne+ cr1, L_00000B80 + li r20, 0 +L_00000B80: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_00000B90 + li r19, 0 +L_00000B90: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000BA4 + li r18, 0 +L_00000BA4: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000BBC + li r17, 0 +L_00000BBC: + bne+ cr1, L_00000BC4 + li r16, 0 +L_00000BC4: + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000BF0 + li r12, 0 +L_00000BF0: + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000C04 + li r11, 0 +L_00000C04: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + fmadds f14, f15, f25, f14 + bne+ L_00000C24 + li r10, 0 +L_00000C24: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + lwz k, 0x50(r1) + lwz rv, 0x54(r1) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000C40 + li r9, 0 +L_00000C40: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r29, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r29 + cmpw cr6, r7, r29 + fctiwz f14, f14 + bne+ cr5, L_00000C74 + li r8, 0 +L_00000C74: + bne+ cr6, L_00000C7C + li r7, 0 +L_00000C7C: + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 // sizeof AXFX_REVHI_DELAYLINE + stfiwx f14, r0, sptr + addi r29, rv, AXFX_REVHI_WORK_DPL2.C + add r29, r29, r31 + stw r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + stw r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + stw r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + stw r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + stw r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + stw r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + stfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + stfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + stfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + stw r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + stw r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + stw r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + stw r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + stw r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + stw r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + stfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + stfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + stfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + slwi r31, k, 2 + add r31, r31, rv + stfs f25, AXFX_REVHI_WORK_DPL2.lpLastout(r31) + lfd f14, 0x60(r1) + lfd f15, 0x68(r1) + lfd f16, 0x70(r1) + lfd f17, 0x78(r1) + lfd f18, 0x80(r1) + lfd f19, 0x88(r1) + lfd f20, 0x90(r1) + lfd f21, 0x98(r1) + lfd f22, 0xa0(r1) + lfd f23, 0xa8(r1) + lfd f24, 0xb0(r1) + lfd f25, 0xb8(r1) + lmw r14, 0x8(r1) + addi r1, r1, 0xc0 + blr +} + +static void ReverbHICallbackDpl2(s32* l, s32* r, s32* ls, s32* rs, AXFX_REVHI_WORK_DPL2* rv) { + HandleReverbDpl2(l, rv, 0); + HandleReverbDpl2(r, rv, 1); + HandleReverbDpl2(ls, rv, 2); + HandleReverbDpl2(rs, rv, 3); +} + +static void ReverbHIDpl2Free(AXFX_REVHI_WORK_DPL2* rv) { + u8 i; + + for (i = 0; i < 12; i++) { + if (rv->AP[i].inputs != 0) { + DLdeleteDpl2(&rv->AP[i]); + rv->AP[i].inputs = 0; + } + } + + for (i = 0; i < 12; i++) { + if (rv->C[i].inputs != 0) { + DLdeleteDpl2(&rv->C[i]); + rv->C[i].inputs = 0; + } + } + + if (rv->preDelayTime) { + for (i = 0; i < 4; i++) { + if (rv->preDelayLine[i] != 0) { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = 0; + } + } + } +} + +int AXFXReverbHiInitDpl2(AXFX_REVERBHI_DPL2* reverb) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + reverb->tempDisableFX = 0; + ret = ReverbHICreateDpl2(&reverb->rv, reverb->coloration, reverb->time, reverb->mix, reverb->damping, reverb->preDelay); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbHiShutdownDpl2(AXFX_REVERBHI_DPL2* reverb) { + BOOL old; + + old = OSDisableInterrupts(); + ReverbHIDpl2Free(&reverb->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbHiSettingsDpl2(AXFX_REVERBHI_DPL2* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbHIModifyDpl2(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbHiCallbackDpl2(AXFX_BUFFERUPDATE_DPL2* bufferUpdate, AXFX_REVERBHI_DPL2* reverb) { + ASSERTMSGLINE(1399, AXGetMode() == 2, "AX mode isn't AX_MODE_DPL2. AX mode must be AX_MODE_DPL2 for using AXFXReverbHiCallbackDpl2"); + + if (reverb->tempDisableFX == 0) { + HandleReverbDpl2(bufferUpdate->L, &reverb->rv, 0); + HandleReverbDpl2(bufferUpdate->R, &reverb->rv, 1); + HandleReverbDpl2(bufferUpdate->Ls, &reverb->rv, 2); + HandleReverbDpl2(bufferUpdate->Rs, &reverb->rv, 3); + } +} diff --git a/src/dolphin/axfx/src/reverb_std.c b/src/dolphin/axfx/src/reverb_std.c new file mode 100644 index 0000000..6703890 --- /dev/null +++ b/src/dolphin/axfx/src/reverb_std.c @@ -0,0 +1,501 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__axfx.h" + +// prototypes +static void DLsetdelay(AXFX_REVSTD_DELAYLINE* dl, s32 lag); +static int DLcreate(AXFX_REVSTD_DELAYLINE* dl, s32 max_length); +static void DLdelete(AXFX_REVSTD_DELAYLINE* dl); +static int ReverbSTDCreate(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay); +static int ReverbSTDModify(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay); +static void HandleReverb(s32* sptr, AXFX_REVSTD_WORK* rv); +static void ReverbSTDCallback(s32* left, s32* right, s32* surround, AXFX_REVSTD_WORK* rv); +static void ReverbSTDFree(AXFX_REVSTD_WORK* rv); + +static void DLsetdelay(AXFX_REVSTD_DELAYLINE* dl, s32 lag) { + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) { + dl->outPoint += dl->length; + } +} + +static int DLcreate(AXFX_REVSTD_DELAYLINE* dl, s32 max_length) { + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length * 4); + ASSERTMSGLINE(49, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) { + return 0; + } + + memset(dl->inputs, 0, max_length * 4); + dl->lastOutput = 0.0f; + DLsetdelay(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdelete(AXFX_REVSTD_DELAYLINE* dl) { + __AXFXFree(dl->inputs); +} + +// NONMATCHING RELEASE - regalloc +static int ReverbSTDCreate(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay) { + u8 i; + u8 k; + static s32 lens[4] = { + 0x000006FD, + 0x000007CF, + 0x000001B1, + 0x00000095, + }; + + ASSERTMSGLINE(109, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + predelay >= 0.0f && predelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (predelay < 0.0f ) || (predelay > 0.1f )) { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVSTD_WORK)); + + for (k = 0; k < 3; k++) { + for (i = 0; i < 2; i++) { + if (DLcreate(&rv->C[i + (k * 2)], lens[i] + 2) == 0) { + ReverbSTDFree(rv); + return 0; + } + DLsetdelay(&rv->C[i + (k * 2)], lens[i]); + rv->combCoef[i + (k * 2)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) { + if (DLcreate(&rv->AP[i + (k * 2)], lens[i + 2] + 2) == 0) { + ReverbSTDFree(rv); + return 0; + } + DLsetdelay(&rv->AP[i + (k * 2)], lens[i + 2]); + } + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + if (0.0f != predelay) { + rv->preDelayTime = (32000.0f * predelay); + for (i = 0; i < 3; i++) { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(162, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) { + ReverbSTDFree(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } else { + rv->preDelayTime = 0; + for (i = 0; i < 3; i++) { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbSTDModify(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay) { + u8 i; + + ASSERTMSGLINE(196, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + predelay >= 0.0f && predelay <= 0.1f, + "The value of specified parameter is out of range."); + + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (predelay < 0.0f ) || (predelay > 0.1f )) { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 6; i++) { + DLdelete(&rv->AP[i]); + } + + for (i = 0; i < 6; i++) { + DLdelete(&rv->C[i]); + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbSTDCreate(rv, coloration, time, mix, damping, predelay); +} + +const static f32 value0_3 = 0.3f; +const static f32 value0_6 = 0.6f; +const static double i2fMagic = 4503601774854144.0; + +asm static void HandleReverb(register s32* sptr, register AXFX_REVSTD_WORK* rv) { + nofralloc + stwu r1, -144(r1) + stmw r17, 8(r1) + stfd f14, 88(r1) + stfd f15, 96(r1) + stfd f16, 104(r1) + stfd f17, 112(r1) + stfd f18, 120(r1) + stfd f19, 128(r1) + stfd f20, 136(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, AXFX_REVSTD_WORK.allPassCoeff(rv) + lfs f11, AXFX_REVSTD_WORK.damping(rv) + lfs f8, AXFX_REVSTD_WORK.level(rv) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + lis r30, 0x4330 // 176.0f (0x43300000) + stw r30, 80(r1) + li r5, 0 +L_00000638: + slwi r31, r5, 3 + add r31, r31, rv + lfs f19, AXFX_REVSTD_WORK.combCoef[0](r31) + lfs f20, AXFX_REVSTD_WORK.combCoef[1](r31) + slwi r31, r5, 2 + add r31, r31, rv + lfs f7, AXFX_REVSTD_WORK.lpLastout[0](r31) + lwz r27, AXFX_REVSTD_WORK.preDelayLine[0](r31) + lwz r28, AXFX_REVSTD_WORK.preDelayPtr[0](r31) + lwz r31, AXFX_REVSTD_WORK.preDelayTime(rv) + subi r22, r31, 1 + slwi r22, r22, 2 + add r22, r22, r27 + cmpwi cr7, r31, 0 + mulli r31, r5, 0x28 // sizeof(AXFX_REVSTD_DELAYLINE * 2) + addi r29, rv, AXFX_REVSTD_WORK.C + add r29, r29, r31 + addi r30, rv, AXFX_REVSTD_WORK.AP + add r30, r30, r31 + lwz r21, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r29) // C array + 0 + lwz r20, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r29) // C array + 0 + lwz r19, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r29) // C array + 1 + lwz r18, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r29) // C array + 1 + lfs f15, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r29) // C array + 0 + lfs f16, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r29) // C array + 1 + lwz r26, AXFX_REVSTD_DELAYLINE.length + 0x00(r29) // C array + 0 + lwz r25, AXFX_REVSTD_DELAYLINE.length + 0x14(r29) // C array + 1 + lwz r7, AXFX_REVSTD_DELAYLINE.inputs + 0x00(r29) // C array + 0 + lwz r8, AXFX_REVSTD_DELAYLINE.inputs + 0x14(r29) // C array + 1 + lwz r12, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r30) // AP array + 0 + lwz r11, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r30) // AP array + 0 + lwz r10, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r30) // AP array + 1 + lwz r9, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r30) // AP array + 1 + lfs f17, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r30) // AP array + 0 + lfs f18, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r30) // AP array + 1 + lwz r24, AXFX_REVSTD_DELAYLINE.length + 0x00(r30) // AP array + 0 + lwz r23, AXFX_REVSTD_DELAYLINE.length + 0x14(r30) // AP array + 1 + lwz r17, AXFX_REVSTD_DELAYLINE.inputs + 0x00(r30) // AP array + 0 + lwz r6, AXFX_REVSTD_DELAYLINE.inputs + 0x14(r30) // AP array + 1 + lwz r30, 0(sptr) + xoris r30, r30, 0x8000 + stw r30, 84(r1) + lfd f12, 80(r1) + fsubs f12, f12, f5 + li r31, 159 + mtctr r31 +L_000006F0: + fmr f13, f12 + beq cr7, L_00000710 + lfs f13, 0(r28) + addi r28, r28, 4 + cmpw r28, r22 + stfs f12, -4(r28) + bne+ L_00000710 + mr r28, r27 +L_00000710: + fmadds f8, f19, f15, f13 + lwzu r29, 4(sptr) + fmadds f9, f20, f16, f13 + stfsx f8, r7, r21 + addi r21, r21, 4 + stfsx f9, r8, r19 + lfsx f14, r7, r20 + addi r20, r20, 4 + lfsx f16, r8, r18 + cmpw r21, r26 + cmpw cr1, r20, r26 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f15, f14 + cmpw cr5, r19, r25 + fadds f14, f14, f16 + cmpw cr6, r18, r25 + bne+ L_0000075C + li r21, 0 +L_0000075C: + xoris r29, r29, 0x8000 + fmadds f9, f2, f17, f14 + bne+ cr1, L_0000076C + li r20, 0 +L_0000076C: + stw r29, 84(r1) + bne+ cr5, L_00000778 + li r19, 0 +L_00000778: + stfsx f9, r17, r12 + fnmsubs f14, f2, f9, f17 + addi r12, r12, 4 + bne+ cr6, L_0000078C + li r18, 0 +L_0000078C: + lfsx f17, r17, r11 + cmpw cr5, r12, r24 + addi r11, r11, 4 + cmpw cr6, r11, r24 + bne+ cr5, L_000007A4 + li r12, 0 +L_000007A4: + bne+ cr6, L_000007AC + li r11, 0 +L_000007AC: + fmuls f14, f14, f6 + lfd f10, 80(r1) + fmadds f14, f11, f7, f14 + fmadds f9, f2, f18, f14 + fmr f7, f14 + stfsx f9, r6, r10 + fnmsubs f14, f2, f9, f18 + fmuls f8, f4, f12 + lfsx f18, r6, r9 + addi r10, r10, 4 + addi r9, r9, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r10, r23 + cmpw cr6, r9, r23 + fctiwz f14, f14 + bne+ cr5, L_000007F0 + li r10, 0 +L_000007F0: + bne+ cr6, L_000007F8 + li r9, 0 +L_000007F8: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, sptr, r31 + bdnz L_000006F0 + fmr f13, f12 + beq cr7, L_00000828 + lfs f13, 0(r28) + addi r28, r28, 4 + cmpw r28, r22 + stfs f12, -4(r28) + bne+ L_00000828 + mr r28, r27 +L_00000828: + fmadds f8, f19, f15, f13 + fmadds f9, f20, f16, f13 + stfsx f8, r7, r21 + addi r21, r21, 4 + stfsx f9, r8, r19 + lfsx f14, r7, r20 + addi r20, r20, 4 + lfsx f16, r8, r18 + cmpw r21, r26 + cmpw cr1, r20, r26 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f15, f14 + cmpw cr5, r19, r25 + fadds f14, f14, f16 + cmpw cr6, r18, r25 + bne+ L_00000870 + li r21, 0 +L_00000870: + fmadds f9, f2, f17, f14 + bne+ cr1, L_0000087C + li r20, 0 +L_0000087C: + bne+ cr5, L_00000884 + li r19, 0 +L_00000884: + stfsx f9, r17, r12 + fnmsubs f14, f2, f9, f17 + addi r12, r12, 4 + bne+ cr6, L_00000898 + li r18, 0 +L_00000898: + lfsx f17, r17, r11 + cmpw cr5, r12, r24 + addi r11, r11, 4 + cmpw cr6, r11, r24 + bne+ cr5, L_000008B0 + li r12, 0 +L_000008B0: + bne+ cr6, L_000008B8 + li r11, 0 +L_000008B8: + fmuls f14, f14, f6 + fmadds f14, f11, f7, f14 + mulli r31, r5, 0x28 // sizeof(AXFX_REVSTD_DELAYLINE * 2) + fmadds f9, f2, f18, f14 + fmr f7, f14 + addi r29, rv, AXFX_REVSTD_WORK.C + add r29, r29, r31 + stfsx f9, r6, r10 + fnmsubs f14, f2, f9, f18 + fmuls f8, f4, f12 + lfsx f18, r6, r9 + addi r10, r10, 4 + addi r9, r9, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r10, r23 + cmpw cr6, r9, r23 + fctiwz f14, f14 + bne+ cr5, L_00000904 + li r10, 0 +L_00000904: + bne+ cr6, L_0000090C + li r9, 0 +L_0000090C: + addi r30, rv, AXFX_REVSTD_WORK.AP + add r30, r30, r31 + stfiwx f14, r0, sptr + stw r21, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r29) // C array + 0 + stw r20, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r29) // C array + 0 + stw r19, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r29) // C array + 1 + stw r18, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r29) // C array + 1 + addi sptr, sptr, 4 + stfs f15, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r29) // C array + 0 + stfs f16, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r29) // C array + 1 + slwi r31, r5, 2 + add r31, r31, rv + addi r5, r5, 1 + stw r12, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r30) // AP array + 0 + stw r11, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r30) // AP array + 0 + stw r10, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r30) // AP array + 1 + stw r9, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r30) // AP array + 1 + cmpwi r5, 3 + stfs f17, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r30) // AP array + 0 + stfs f18, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r30) // AP array + 1 + stfs f7, AXFX_REVSTD_WORK.lpLastout(r31) + stw r28, AXFX_REVSTD_WORK.preDelayPtr(r31) + bne L_00000638 + lfd f14, 88(r1) + lfd f15, 96(r1) + lfd f16, 104(r1) + lfd f17, 112(r1) + lfd f18, 120(r1) + lfd f19, 128(r1) + lfd f20, 136(r1) + lmw r17, 8(r1) + addi r1, r1, 144 + blr +} + +static void ReverbSTDCallback(s32* left, s32* right, s32* surround, AXFX_REVSTD_WORK* rv) { + HandleReverb(left, rv); +} + +static void ReverbSTDFree(AXFX_REVSTD_WORK* rv) { + u8 i; + + for (i = 0; i < 6; i++) { + if (rv->AP[i].inputs != 0) { + DLdelete(&rv->AP[i]); + rv->AP[i].inputs = NULL; + } + } + + for (i = 0; i < 6; i++) { + if (rv->C[i].inputs != 0) { + DLdelete(&rv->C[i]); + rv->C[i].inputs = NULL; + } + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + if (rv->preDelayLine[i] != 0) { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = NULL; + } + } + } +} + +int AXFXReverbStdInit(AXFX_REVERBSTD* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 0; + ret = ReverbSTDCreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbStdShutdown(AXFX_REVERBSTD* rev) { + BOOL old; + + old = OSDisableInterrupts(); + ReverbSTDFree(&rev->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbStdSettings(AXFX_REVERBSTD* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbSTDModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbStdCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBSTD* reverb) { + if (reverb->tempDisableFX == 0) { + ReverbSTDCallback(bufferUpdate->left, bufferUpdate->right, bufferUpdate->surround, &reverb->rv); + } +} diff --git a/src/dolphin/base/src/PPCArch.c b/src/dolphin/base/src/PPCArch.c new file mode 100644 index 0000000..511f102 --- /dev/null +++ b/src/dolphin/base/src/PPCArch.c @@ -0,0 +1,292 @@ +#include +#include + +asm u32 PPCMfmsr() { + nofralloc + mfmsr r3 + blr +} + +asm void PPCMtmsr(register u32 newMSR) { + nofralloc + mtmsr newMSR + blr +} + +asm u32 PPCOrMsr(register u32 value) { + nofralloc + mfmsr r4 + or value, r4, value + blr +} + +asm u32 PPCAndMsr(register u32 value) { + nofralloc + mfmsr r4 + and value, r4, value + blr +} + +asm u32 PPCAndCMsr(register u32 value) { + nofralloc + mfmsr r4 + andc value, r4, value + blr +} + +asm u32 PPCMfhid0() { + nofralloc + mfspr r3, HID0 + blr +} + +asm void PPCMthid0(register u32 newHID0) { + nofralloc + mtspr HID0, newHID0 + blr +} + +asm u32 PPCMfhid1() { + nofralloc + mfspr r3, HID1 + blr +} + +asm u32 PPCMfl2cr() { + nofralloc + mfspr r3, L2CR + blr +} + +asm void PPCMtl2cr(register u32 newL2cr) { + nofralloc + mtspr L2CR, newL2cr + blr +} + +asm void PPCMtdec(register u32 newDec) { + nofralloc + mtdec newDec + blr +} + +asm u32 PPCMfdec() { + nofralloc + mfdec r3 + blr +} + +asm void PPCSync() { + nofralloc + sc + blr +} + +asm void PPCEieio() { + nofralloc + mfmsr r5 + rlwinm r6, r5, 0, 17, 15 + mtmsr r6 + mfspr r3, HID0 + ori r4, r3, 0x8 + mtspr HID0, r4 + isync + eieio + isync + mtspr HID0, r3 + mtmsr r5 + isync + blr +} + +asm void PPCHalt() { + nofralloc + sync +loop: + nop + li r3, 0 + nop + b loop +} + +asm u32 PPCMfmmcr0() { + nofralloc + mfspr r3, MMCR0 + blr +} + +asm void PPCMtmmcr0(register u32 newMmcr0) { + nofralloc + mtspr MMCR0, newMmcr0 + blr +} + +asm u32 PPCMfmmcr1() { + nofralloc + mfspr r3, MMCR1 + blr +} + +asm void PPCMtmmcr1(register u32 newMmcr1) { + nofralloc + mtspr MMCR1, newMmcr1 + blr +} + +asm u32 PPCMfpmc1() { + nofralloc + mfspr r3, PMC1 + blr +} + +asm void PPCMtpmc1(register u32 newPmc1) { + nofralloc + mtspr PMC1, newPmc1 + blr +} + +asm u32 PPCMfpmc2() { + nofralloc + mfspr r3, PMC2 + blr +} + +asm void PPCMtpmc2(register u32 newPmc2) { + nofralloc + mtspr PMC2, newPmc2 + blr +} + +asm u32 PPCMfpmc3() { + nofralloc + mfspr r3, PMC3 + blr +} + +asm void PPCMtpmc3(register u32 newPmc3) { + nofralloc + mtspr PMC3, newPmc3 + blr +} + +asm u32 PPCMfpmc4() { + nofralloc + mfspr r3, PMC4 + blr +} + +asm void PPCMtpmc4(register u32 newPmc4) { + nofralloc + mtspr PMC4, newPmc4 + blr +} + +asm u32 PPCMfsia() { + nofralloc + mfspr r3, SIA + blr +} + +asm void PPCMtsia(register u32 newSia) { + nofralloc + mtspr SIA, newSia + blr +} + +u32 PPCMffpscr() { + union FpscrUnion m; + + asm { + mffs fp31 + stfd fp31, m.f; + } + + return m.u.fpscr; +} + +void PPCMtfpscr(register u32 newFPSCR) { + union FpscrUnion m; + + asm { + li r4, 0 + stw r4, m.u.fpscr_pad; + stw newFPSCR, m.u.fpscr + lfd fp31, m.f + mtfsf 0xff, fp31 + } +} + +asm u32 PPCMfhid2() { + nofralloc + mfspr r3, HID2 + blr +} + +asm void PPCMthid2(register u32 newhid2) { + nofralloc + mtspr HID2, newhid2 + blr +} + +asm u32 PPCMfwpar() { + nofralloc + sync + mfspr r3, WPAR + blr +} + +asm void PPCMtwpar(register u32 newwpar) { + nofralloc + mtspr WPAR, newwpar + blr +} + +asm u32 PPCMfdmaU() { + nofralloc + mfspr r3, DMA_U + blr +} + +asm u32 PPCMfdmaL() { + nofralloc + mfspr r3, DMA_L + blr +} + +asm void PPCMtdmaU(register u32 newdmau) { + nofralloc + mtspr DMA_U, newdmau + blr +} + +asm void PPCMtdmaL(register u32 newdmal) { + nofralloc + mtspr DMA_L, newdmal + blr +} + +asm u32 PPCMfpvr() { + nofralloc + mfspr r3, PVR + blr +} + +void PPCEnableSpeculation(void) { + PPCMthid0(PPCMfhid0() & ~HID0_SPD); +} + +void PPCDisableSpeculation(void) { + PPCMthid0(PPCMfhid0() | HID0_SPD); +} + +asm void PPCSetFpIEEEMode() { + nofralloc + mtfsb0 29 + blr +} + +asm void PPCSetFpNonIEEEMode() { + nofralloc + mtfsb1 29 + blr +} diff --git a/src/dolphin/base/src/PPCPm.c b/src/dolphin/base/src/PPCPm.c new file mode 100644 index 0000000..d5ffcb4 --- /dev/null +++ b/src/dolphin/base/src/PPCPm.c @@ -0,0 +1,34 @@ +#include +#include + +void PMBegin(void) { + PPCMtmmcr0(0); + PPCMtmmcr1(0); + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); + PPCMtmmcr0(0x4F); + PPCMtmmcr1(0x78800000); +} + +void PMEnd(void) { + PPCMtmmcr0(0); + PPCMtmmcr1(0); +} + +void PMCycles(void) { + PPCMfpmc1(); +} + +void PML1FetchMisses(void) { + PPCMfpmc2(); +} + +void PML1MissCycles(void) { + PPCMfpmc3(); +} + +void PMInstructions(void) { + PPCMfpmc4(); +} diff --git a/src/dolphin/card/src/CARDBios.c b/src/dolphin/card/src/CARDBios.c new file mode 100644 index 0000000..e293456 --- /dev/null +++ b/src/dolphin/card/src/CARDBios.c @@ -0,0 +1,856 @@ +#include + +#include "__card.h" + +#if DEBUG +const char* __CARDVersion = "<< Dolphin SDK - CARD\tdebug build: Apr 5 2004 03:56:53 (0x2301) >>"; +#else +const char* __CARDVersion = "<< Dolphin SDK - CARD\trelease build: Apr 5 2004 04:15:35 (0x2301) >>"; +#endif + +u32 __CARDFreq = EXI_FREQ_16M; + +CARDControl __CARDBlock[2]; + +static u16 __CARDEncode; +static u16 __CARDFastMode; + +DVDDiskID __CARDDiskNone; + +// prototypes +static void TimeoutHandler(OSAlarm* alarm, OSContext* context); +static void SetupTimeoutAlarm(CARDControl* card); +static s32 Retry(s32 chan); +static void UnlockedCallback(s32 chan, s32 result); +static BOOL OnReset(BOOL f); + +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127}; + +void __CARDDefaultApiCallback(s32 chan, s32 result) {} + +void __CARDSyncCallback(s32 chan, s32 result) { + CARDControl* card; + card = &__CARDBlock[chan]; + OSWakeupThread(&card->threadQueue); +} + +void __CARDExtHandler(s32 chan, OSContext* context) { + CARDControl* card; + CARDCallback callback; + + ASSERTLINE(232, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (card->attached) { + ASSERTLINE(239, card->txCallback == 0); + card->attached = FALSE; + EXISetExiCallback(chan, 0); + OSCancelAlarm(&card->alarm); + callback = card->exiCallback; + + if (callback) { + card->exiCallback = 0; + callback(chan, CARD_RESULT_NOCARD); + } + + if (card->result != CARD_RESULT_BUSY) { + card->result = CARD_RESULT_NOCARD; + } + + callback = card->extCallback; + if (callback && CARD_MAX_MOUNT_STEP <= card->mountStep) { + card->extCallback = 0; + callback(chan, CARD_RESULT_NOCARD); + } + } +} + +void __CARDExiHandler(s32 chan, OSContext* context) { + CARDControl* card; + CARDCallback callback; + u8 status; + s32 result; + + ASSERTLINE(283, 0 <= chan && chan < 2); + card = &__CARDBlock[chan]; + + OSCancelAlarm(&card->alarm); + + if (!card->attached) { + return; + } + + if (!EXILock(chan, 0, 0)) { + result = CARD_RESULT_FATAL_ERROR; + goto fatal; + } + + if ((result = __CARDReadStatus(chan, &status)) < 0 || (result = __CARDClearStatus(chan)) < 0) { + goto error; + } + + if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == CARD_RESULT_IOERROR && + --card->retry > 0) + { + result = Retry(chan); + if (result >= 0) + { + return; + } + goto fatal; + } + +error: + EXIUnlock(chan); + +fatal: + callback = card->exiCallback; + if (callback) { + card->exiCallback = 0; + callback(chan, result); + } +} + +void __CARDTxHandler(s32 chan, OSContext* context) { + CARDControl* card; + CARDCallback callback; + int err; + + ASSERTLINE(365, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + err = !EXIDeselect(chan); + EXIUnlock(chan); + callback = card->txCallback; + if (callback) { + card->txCallback = NULL; + callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD); + } +} + +void __CARDUnlockedHandler(s32 chan, OSContext* context) { + CARDControl* card; + CARDCallback callback; + + ASSERTLINE(412, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + callback = card->unlockCallback; + if (callback) { + card->unlockCallback = 0; + callback(chan, EXIProbe(chan) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD); + } +} + +s32 __CARDEnableInterrupt(s32 chan, BOOL enable) { + BOOL err; + u32 cmd; + + ASSERTLINE(431, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { + return CARD_RESULT_NOCARD; + } + + cmd = enable ? 0x81010000 : 0x81000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +s32 __CARDReadStatus(s32 chan, u8* status) { + BOOL err; + u32 cmd; + + ASSERTLINE(450, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { + return CARD_RESULT_NOCARD; + } + + cmd = 0x83000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); + err |= !EXISync(chan); + err |= !EXIImm(chan, status, 1, EXI_READ, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +int __CARDReadVendorID(s32 chan, u16* id) { + BOOL err; + u32 cmd; + + ASSERTLINE(471, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { + return CARD_RESULT_NOCARD; + } + cmd = 0x85000000; + err = 0; + err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, 0); + err |= !EXISync(chan); + err |= !EXIImm(chan, id, 2, EXI_READ, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +s32 __CARDClearStatus(s32 chan) { + BOOL err; + u32 cmd; + + ASSERTLINE(492, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { + return CARD_RESULT_NOCARD; + } + + cmd = 0x89000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +s32 __CARDSleep(s32 chan) { + int err; + u32 cmd; + + ASSERTLINE(511, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { + return CARD_RESULT_NOCARD; + } + cmd = 0x88000000; + err = 0; + err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + + if(err) { + return CARD_RESULT_NOCARD; + } + return CARD_RESULT_READY; +} + +s32 __CARDWakeup(s32 chan) { + int err; + u32 cmd; + + ASSERTLINE(530, 0 <= chan && chan < 2); + if (!EXISelect(chan, 0, CARDFreq)) { + return CARD_RESULT_NOCARD; + } + cmd = 0x87000000; + err = 0; + err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + + if(err) { + return CARD_RESULT_NOCARD; + } + return CARD_RESULT_READY; +} + +static void TimeoutHandler(OSAlarm* alarm, OSContext* context) { + s32 chan; + CARDControl* card; + CARDCallback callback; + for (chan = 0; chan < 2; ++chan) { + card = &__CARDBlock[chan]; + if (alarm == &card->alarm) { + break; + } + } + + ASSERTLINE(578, 0 <= chan && chan < 2); + + if (!card->attached) { + return; + } + + EXISetExiCallback(chan, NULL); + callback = card->exiCallback; + if (callback) { + card->exiCallback = 0; + callback(chan, CARD_RESULT_IOERROR); + } +} + +static void SetupTimeoutAlarm(CARDControl* card) { + OSCancelAlarm(&card->alarm); + switch (card->cmd[0]) { + case 0xF2: + OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), + TimeoutHandler); + break; + case 0xF3: + break; + case 0xF4: + if (card->pageSize > 0x80) { + OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->cBlock / 0x40), + TimeoutHandler); + break; + } + case 0xF1: + OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), + TimeoutHandler); + break; + } +} + +static s32 Retry(s32 chan) { + CARDControl* card; + + ASSERTLINE(654, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (!EXISelect(chan, 0, CARDFreq)) { + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + SetupTimeoutAlarm(card); + + if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE)) { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + if (card->cmd[0] == 0x52 && + !EXIImmEx(chan, (u8* )card->workArea + sizeof(CARDID), card->latency, EXI_WRITE)) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + if (card->mode == 0xffffffff) { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_READY; + } + + if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : card->pageSize), card->mode, + __CARDTxHandler)) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + return CARD_RESULT_READY; +} + +static void UnlockedCallback(s32 chan, s32 result) { + CARDCallback callback; + CARDControl* card; + + ASSERTLINE(718, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (result >= 0) { + card->unlockCallback = UnlockedCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) { + result = CARD_RESULT_READY; + } else { + card->unlockCallback = 0; + result = Retry(chan); + } + } + + if (result < 0) { + switch (card->cmd[0]) { + case 0x52: + callback = card->txCallback; + if (callback) { + card->txCallback = NULL; + callback(chan, result); + } + break; + case 0xF2: + case 0xF4: + case 0xF1: + callback = card->exiCallback; + if (callback) { + card->exiCallback = 0; + callback(chan, result); + } + break; + } + } +} + +static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback) { + BOOL enabled; + CARDControl* card; + s32 result; + + enabled = OSDisableInterrupts(); + + ASSERTLINE(784, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (!card->attached) { + result = CARD_RESULT_NOCARD; + } else { + if (txCallback) { + card->txCallback = txCallback; + } + + if (exiCallback) { + card->exiCallback = exiCallback; + } + + card->unlockCallback = UnlockedCallback; + + if (!EXILock(chan, 0, __CARDUnlockedHandler)) { + result = CARD_RESULT_BUSY; + } else { + card->unlockCallback = 0; + + if (!EXISelect(chan, 0, CARDFreq)) { + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } else { + SetupTimeoutAlarm(card); + result = CARD_RESULT_READY; + } + } + } + + OSRestoreInterrupts(enabled); + return result; +} + +#define AD1(x) ((u8)(((x) >> 17) & 0x7f)) +#define AD1EX(x) ((u8)(AD1(x) | 0x80)); +#define AD2(x) ((u8)(((x) >> 9) & 0xff)) +#define AD3(x) ((u8)(((x) >> 7) & 0x03)) +#define BA(x) ((u8)((x)&0x7f)) + +s32 __CARDReadSegment(s32 chan, CARDCallback callback) { + CARDControl* card; + s32 result; + + ASSERTLINE(846, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + ASSERTLINE(848, card->addr % CARD_SEG_SIZE == 0); + ASSERTLINE(849, card->addr < (u32) card->size * 1024 * 1024 / 8); + + card->cmd[0] = 0x52; + card->cmd[1] = AD1(card->addr); + card->cmd[2] = AD2(card->addr); + card->cmd[3] = AD3(card->addr); + card->cmd[4] = BA(card->addr); + card->cmdlen = 5; + card->mode = 0; + card->retry = 0; + + result = __CARDStart(chan, callback, 0); + if (result == CARD_RESULT_BUSY) { + result = CARD_RESULT_READY; + } else if (result >= 0) { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE) || + !EXIImmEx(chan, (u8* )card->workArea + sizeof(CARDID), card->latency, + EXI_WRITE) || // XXX use DMA if possible + !EXIDma(chan, card->buffer, 512, card->mode, __CARDTxHandler)) + { + card->txCallback = NULL; + EXIDeselect(chan); + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } else { + result = CARD_RESULT_READY; + } + } + + return result; +} + +s32 __CARDWritePage(s32 chan, CARDCallback callback) { + CARDControl* card; + s32 result; + + ASSERTLINE(903, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + ASSERTLINE(905, card->addr % card->pageSize == 0); + ASSERTLINE(906, card->addr < (u32) card->size * 1024 * 1024 / 8); + card->cmd[0] = 0xF2; + + if (card->pageSize > 0x80) { + card->cmd[1] = AD1(card->addr) | 0x80; + } else { + card->cmd[1] = AD1(card->addr); + } + + card->cmd[2] = AD2(card->addr); + card->cmd[3] = AD3(card->addr); + card->cmd[4] = BA(card->addr); + card->cmdlen = 5; + card->mode = 1; + card->retry = 3; + + result = __CARDStart(chan, 0, callback); + if (result == CARD_RESULT_BUSY) { + result = CARD_RESULT_READY; + } else if (result >= 0) { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE) || + !EXIDma(chan, card->buffer, card->pageSize, card->mode, __CARDTxHandler)) + { + card->exiCallback = 0; + EXIDeselect(chan); + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } else { + result = CARD_RESULT_READY; + } + } + + return result; +} + +s32 __CARDErase(s32 chan, CARDCallback callback) { + CARDControl* card; + s32 result; + + ASSERTLINE(962, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + card->cmd[0] = 0xF4; + card->cmd[1] = 0; + card->cmd[2] = 0; + card->cmdlen = 3; + card->mode = -1; + card->retry = 3; + result = __CARDStart(chan, 0, callback); + if (result == CARD_RESULT_BUSY) { + result = CARD_RESULT_READY; + } else if (result >= 0) { + if (EXIImmEx(chan, &card->cmd, card->cmdlen, EXI_WRITE) == 0) { + result = CARD_RESULT_NOCARD; + card->exiCallback = 0; + } else { + result = CARD_RESULT_READY; + } + + EXIDeselect(chan); + EXIUnlock(chan); + } + + return result; +} + +s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) { + CARDControl* card; + s32 result; + + ASSERTLINE(1010, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + ASSERTLINE(1012, addr % card->sectorSize == 0); + ASSERTLINE(1013, addr < (u32) card->size * 1024 * 1024 / 8); + + if (card->pageSize > 0x80) { + if (callback) { + callback(chan, 0); + } + return 0; + } + + card->cmd[0] = 0xF1; + card->cmd[1] = AD1(addr); + card->cmd[2] = AD2(addr); + card->cmdlen = 3; + card->mode = -1; + card->retry = 3; + + result = __CARDStart(chan, 0, callback); + + if (result == CARD_RESULT_BUSY) { + result = CARD_RESULT_READY; + } else if (result >= 0) { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE)) { + result = CARD_RESULT_NOCARD; + card->exiCallback = NULL; + } else { + result = CARD_RESULT_READY; + } + + EXIDeselect(chan); + EXIUnlock(chan); + } + return result; +} + +void CARDInit(void) { + int chan; + + if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) { + return; + } + + __CARDEncode = OSGetFontEncode(); + + OSRegisterVersion(__CARDVersion); + + DSPInit(); + OSInitAlarm(); + + for (chan = 0; chan < 2; ++chan) { + CARDControl* card = &__CARDBlock[chan]; + + card->result = CARD_RESULT_NOCARD; + OSInitThreadQueue(&card->threadQueue); + OSCreateAlarm(&card->alarm); + } + __CARDSetDiskID((void*)OSPhysicalToCached(0)); + + OSRegisterResetFunction(&ResetFunctionInfo); +} + +u16 __CARDGetFontEncode(void) { + return __CARDEncode; +} + +u16 __CARDSetFontEncode(u16 encode) { + u16 prev = __CARDEncode; + + switch (encode) { + case CARD_ENCODE_ANSI: + case CARD_ENCODE_SJIS: + __CARDEncode = encode; + break; + } + + return prev; +} + +void __CARDSetDiskID(const DVDDiskID* id) { + __CARDBlock[0].diskID = id ? id : &__CARDDiskNone; + __CARDBlock[1].diskID = id ? id : &__CARDDiskNone; +} + +const DVDDiskID* CARDGetDiskID(s32 chan) { + ASSERTLINE(1168, 0 <= chan && chan < 2); + return __CARDBlock[chan].diskID; +} + +s32 CARDSetDiskID(s32 chan, const DVDDiskID* diskID) { + BOOL enabled; + CARDControl* card; + + card = &__CARDBlock[chan]; + ASSERTLINE(1189, 0 <= chan && chan < 2); + + enabled = OSDisableInterrupts(); + + if (card->result == CARD_RESULT_BUSY) { + return CARD_RESULT_BUSY; + } + + card->diskID = diskID != 0 ? diskID : (const DVDDiskID*)OSPhysicalToCached(0); + OSRestoreInterrupts(enabled); + return 0; +} + +s32 __CARDGetControlBlock(s32 chan, CARDControl** pcard) { + BOOL enabled; + s32 result; + CARDControl* card; + + card = &__CARDBlock[chan]; + + if (chan < 0 || chan >= 2 || card->diskID == 0) { + return CARD_RESULT_FATAL_ERROR; + } + + enabled = OSDisableInterrupts(); + + if (!card->attached) { + result = CARD_RESULT_NOCARD; + } else if (card->result == CARD_RESULT_BUSY) { + result = CARD_RESULT_BUSY; + } else { + card->result = CARD_RESULT_BUSY; + result = CARD_RESULT_READY; + card->apiCallback = NULL; + *pcard = card; + } + + OSRestoreInterrupts(enabled); + return result; +} + +s32 __CARDPutControlBlock(CARDControl* card, s32 result) { + BOOL enabled; + + ASSERTLINE(1259, result != CARD_RESULT_BUSY); + + enabled = OSDisableInterrupts(); + if (card->attached) { + card->result = result; + } else if (card->result == CARD_RESULT_BUSY) { + card->result = result; + } + + OSRestoreInterrupts(enabled); + return result; +} + +s32 CARDGetResultCode(s32 chan) { + CARDControl* card; + + ASSERTLINE(1292, 0 <= chan && chan < 2); + + if (chan < 0 || chan >= 2) { + return CARD_RESULT_FATAL_ERROR; + } + card = &__CARDBlock[chan]; + return card->result; +} + +s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed) { + CARDControl* card; + s32 result; + u16* fat; + CARDDir* dir; + CARDDir* ent; + u16 fileNo; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + fat = __CARDGetFatBlock(card); + dir = __CARDGetDirBlock(card); + if (fat == 0 || dir == 0) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + if (byteNotUsed) { + *byteNotUsed = (s32)(card->sectorSize * fat[CARD_FAT_FREEBLOCKS]); + } + + if (filesNotUsed) { + *filesNotUsed = 0; + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + ent = &dir[fileNo]; + if (ent->fileName[0] == 0xff) { + ++*filesNotUsed; + } + } + } + + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 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 CARDGetMemSize(s32 chan, u16* size) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + *size = card->size; + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 CARDGetSectorSize(s32 chan, u32* size) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + *size = card->sectorSize; + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 __CARDSync(s32 chan) { + CARDControl* block; + s32 result; + s32 enabled; + + block = &__CARDBlock[chan]; + enabled = OSDisableInterrupts(); + while ((result = CARDGetResultCode(chan)) == CARD_RESULT_BUSY) { + OSSleepThread(&block->threadQueue); + } + + OSRestoreInterrupts(enabled); + return result; +} + +static BOOL OnReset(BOOL final) { + if (!final) { + if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) { + return FALSE; + } + } + + return TRUE; +} + +BOOL CARDSetFastMode(BOOL enable) { + u16 prev = __CARDFastMode; + __CARDFastMode = enable ? TRUE : FALSE; + + return prev ? TRUE : FALSE; +} + +BOOL CARDGetFastMode(void) { + return __CARDFastMode ? TRUE : FALSE; +} + +s32 CARDGetCurrentMode(s32 chan, u32* mode) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + switch (card->pageSize) { + case 512: + *mode = 1; + break; + case 128: + default: + *mode = 0; + break; + } + + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} diff --git a/src/dolphin/card/src/CARDBlock.c b/src/dolphin/card/src/CARDBlock.c new file mode 100644 index 0000000..b7af255 --- /dev/null +++ b/src/dolphin/card/src/CARDBlock.c @@ -0,0 +1,160 @@ +#include + +#include "__card.h" + +// prototypes +static void WriteCallback(s32 chan, s32 result); +static void EraseCallback(s32 chan, s32 result); + +void* __CARDGetFatBlock(CARDControl* card) { + ASSERTLINE(57, card->currentFat); + return card->currentFat; +} + +static void WriteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat0; + u16* fat1; + + card = &__CARDBlock[chan]; + + if (result >= 0) { + fat0 = (u16*)((u8*)card->workArea + 0x6000); + fat1 = (u16*)((u8*)card->workArea + 0x8000); + + ASSERTLINE(82, card->currentFat); + if (card->currentFat == fat0) { + card->currentFat = fat1; + memcpy(fat1, fat0, 0x2000); + } else { + ASSERTLINE(90, card->currentFat == fat1); + card->currentFat = fat0; + memcpy(fat0, fat1, 0x2000); + } + } + + if (!card->apiCallback) + __CARDPutControlBlock(card, result); + + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = NULL; + callback(chan, result); + } +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card = &__CARDBlock[chan]; + CARDCallback callback; + u16* fat; + u32 addr; + + if (result < 0) + goto error; + + fat = __CARDGetFatBlock(card); + addr = ((u32)fat - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize; + result = __CARDWrite(chan, addr, CARD_SYSTEM_BLOCK_SIZE, fat, WriteCallback); + if (result < 0) + goto error; + + return; + +error: + if (!card->apiCallback) + __CARDPutControlBlock(card, result); + + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = NULL; + callback(chan, result); + } +} + +s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback) { + CARDControl* card; + u16* fat; + u16 iBlock; + u16 startBlock; + u16 prevBlock; + u16 count; + + ASSERTLINE(182, 0 < cBlock); + ASSERTLINE(183, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (!card->attached) + return CARD_RESULT_NOCARD; + + fat = __CARDGetFatBlock(card); + if (fat[3] < cBlock) + return CARD_RESULT_INSSPACE; + + fat[3] -= cBlock; + startBlock = 0xFFFF; + iBlock = fat[4]; + count = 0; + while (0 < cBlock) { + if (card->cBlock - 5 < ++count) + return CARD_RESULT_BROKEN; + + iBlock++; + if (!CARDIsValidBlockNo(card, iBlock)) + iBlock = 5; + + if (fat[iBlock] == 0x0000u) { + if (startBlock == 0xFFFF) + startBlock = iBlock; + else + fat[prevBlock] = iBlock; + prevBlock = iBlock; + fat[iBlock] = 0xFFFF; + --cBlock; + } + } + + fat[4] = iBlock; + card->startBlock = startBlock; + return __CARDUpdateFatBlock(chan, fat, callback); +} + +s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback) { + CARDControl* card; + u16* fat; + u16 nextBlock; + + ASSERTLINE(253, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (!card->attached) + return CARD_RESULT_NOCARD; + + fat = __CARDGetFatBlock(card); + while (nBlock != 0xFFFF) { + if (!CARDIsValidBlockNo(card, nBlock)) + return CARD_RESULT_BROKEN; + + nextBlock = fat[nBlock]; + fat[nBlock] = 0; + nBlock = nextBlock; + ++fat[3]; + } + + return __CARDUpdateFatBlock(chan, fat, callback); +} + +s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback) { + CARDControl* card; + u32 addr; + + ASSERTLINE(295, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + ++fat[2]; + __CARDCheckSum(fat + 2, 0x1FFC, fat, fat + 1); + DCStoreRange(fat, 0x2000); + card->eraseCallback = callback; + addr = (((char*)fat - (char*)card->workArea) / 8192u) * card->sectorSize; + return __CARDEraseSector(chan, addr, EraseCallback); +} diff --git a/src/dolphin/card/src/CARDCheck.c b/src/dolphin/card/src/CARDCheck.c new file mode 100644 index 0000000..4a9b78c --- /dev/null +++ b/src/dolphin/card/src/CARDCheck.c @@ -0,0 +1,343 @@ +#include + +#include "os/__os.h" +#include "__card.h" + +// prototypes +static s32 VerifyID(CARDControl* card); +static s32 VerifyDir(CARDControl* card, int* pcurrent); +static s32 VerifyFAT(CARDControl* card, int* pcurrent); + +void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv) { + u16* p; + int i; + + ASSERTLINE(82, length % sizeof(u16) == 0); + + length /= sizeof(u16); + *checksum = *checksumInv = 0; + for (i = 0, p = ptr; i < length; i++, p++) { + *checksum += *p; + *checksumInv += ~*p; + } + + if (*checksum == 0xFFFF) + *checksum = 0; + + if (*checksumInv == 0xFFFF) + *checksumInv = 0; +} + +static s32 VerifyID(CARDControl* card) { + CARDID* id; + u16 checksum; + u16 checksumInv; + OSSramEx* sramEx; + OSTime rand; + int i; + + id = card->workArea; + + if (id->deviceID != 0 || id->size != card->size) + return CARD_RESULT_BROKEN; + + __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &checksum, &checksumInv); + if (id->checkSum != checksum || id->checkSumInv != checksumInv) + return CARD_RESULT_BROKEN; + + rand = *(OSTime*)&id->serial[12]; + sramEx = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + rand = (rand * 1103515245 + 12345) >> 16; + if (id->serial[i] != (u8)(sramEx->flashID[card - __CARDBlock][i] + rand)) { + __OSUnlockSramEx(FALSE); + return CARD_RESULT_BROKEN; + } + rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF; + } + + __OSUnlockSramEx(FALSE); + + if (id->encode != __CARDGetFontEncode()) + return CARD_RESULT_ENCODING; + + return CARD_RESULT_READY; +} + +static s32 VerifyDir(CARDControl* card, int* pcurrent) { + CARDDir* dir[2]; + CARDDirCheck* check[2]; + u16 checkSum; + u16 checkSumInv; + int i; + int errors; + int current; + + current = errors = 0; + for (i = 0; i < 2; i++) { + dir[i] = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); + check[i] = CARDGetDirCheck(dir[i]); + __CARDCheckSum(dir[i], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv); + if (check[i]->checkSum != checkSum || check[i]->checkSumInv != checkSumInv) { + ++errors; + current = i; + card->currentDir = 0; + } + } + + if (0 == errors) { + if (card->currentDir == 0) { + if ((check[0]->checkCode - check[1]->checkCode) < 0) + current = 0; + else + current = 1; + card->currentDir = dir[current]; + memcpy(dir[current], dir[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); + } else { + current = (card->currentDir == dir[0]) ? 0 : 1; + } + } + + if (pcurrent) + *pcurrent = current; + + return errors; +} + +static s32 VerifyFAT(CARDControl* card, int* pcurrent) { + u16* fat[2]; + u16* fatp; + u16 nBlock; + u16 cFree; + int i; + u16 checkSum; + u16 checkSumInv; + int errors; + int current; + + current = errors = 0; + for (i = 0; i < 2; i++) { + fatp = fat[i] = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE); + + __CARDCheckSum(&fatp[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv); + if (fatp[CARD_FAT_CHECKSUM] != checkSum || fatp[CARD_FAT_CHECKSUMINV] != checkSumInv) { + ++errors; + current = i; + card->currentFat = 0; + continue; + } + + cFree = 0; + for (nBlock = CARD_NUM_SYSTEM_BLOCK; nBlock < card->cBlock; nBlock++) { + if (fatp[nBlock] == CARD_FAT_AVAIL) + cFree++; + } + + if (cFree != fatp[CARD_FAT_FREEBLOCKS]) { + ++errors; + current = i; + card->currentFat = 0; + continue; + } + } + + if (0 == errors) { + if (card->currentFat == 0) { + if (((s16)fat[0][CARD_FAT_CHECKCODE] - (s16)fat[1][CARD_FAT_CHECKCODE]) < 0) + current = 0; + else + current = 1; + card->currentFat = fat[current]; + memcpy(fat[current], fat[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); + } else + current = (card->currentFat == fat[0]) ? 0 : 1; + } + + if (pcurrent) + *pcurrent = current; + + return errors; +} + +s32 __CARDVerify(CARDControl* card) { + s32 result; + int errors; + + result = VerifyID(card); + if (result < 0) + return result; + + errors = VerifyDir(card, NULL); + errors += VerifyFAT(card, NULL); + switch (errors) { + case 0: + ASSERTLINE(301, card->currentDir); + ASSERTLINE(302, card->currentFat); + return CARD_RESULT_READY; + case 1: + return CARD_RESULT_BROKEN; + default: + return CARD_RESULT_BROKEN; + } +} + +s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) { + CARDControl* card; + CARDDir* dir[2]; + u16* fat[2]; + u16* map; + s32 result; + int errors; + int currentFat; + int currentDir; + s32 fileNo; + u16 iBlock; + u16 cBlock; + u16 cFree; + BOOL updateFat = FALSE; + BOOL updateDir = FALSE; + BOOL updateOrphan = FALSE; + + ASSERTLINE(346, 0 <= chan && chan < 2); + + if (xferBytes) { + *xferBytes = 0; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + result = VerifyID(card); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + errors = VerifyDir(card, ¤tDir); + errors += VerifyFAT(card, ¤tFat); + if (1 < errors) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + dir[0] = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE); + dir[1] = (CARDDir*)((u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE); + fat[0] = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE); + fat[1] = (u16*)((u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE); + + ASSERTLINE(377, errors == 0 || errors == 1); + + switch (errors) { + case 0: + ASSERTLINE(381, card->currentDir); + ASSERTLINE(382, card->currentFat); + break; + case 1: + if (!card->currentDir) { + ASSERTLINE(387, card->currentFat); + card->currentDir = dir[currentDir]; + memcpy(dir[currentDir], dir[currentDir ^ 1], CARD_SYSTEM_BLOCK_SIZE); + updateDir = TRUE; + } else { + ASSERTLINE(394, !card->currentFat); + card->currentFat = fat[currentFat]; + memcpy(fat[currentFat], fat[currentFat ^ 1], CARD_SYSTEM_BLOCK_SIZE); + updateFat = TRUE; + } + break; + } + + map = fat[currentFat ^ 1]; + memset(map, 0, CARD_SYSTEM_BLOCK_SIZE); + + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + CARDDir* ent; + + ent = &card->currentDir[fileNo]; + if (ent->gameName[0] == 0xff) { + continue; + } + + for (iBlock = ent->startBlock, cBlock = 0; iBlock != 0xFFFF && cBlock < ent->length; + iBlock = card->currentFat[iBlock], ++cBlock) + { + if (!CARDIsValidBlockNo(card, iBlock) || 1 < ++map[iBlock]) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + + if (cBlock != ent->length || iBlock != 0xFFFF) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + + cFree = 0; + for (iBlock = CARD_NUM_SYSTEM_BLOCK; iBlock < card->cBlock; iBlock++) { + u16 nextBlock; + + nextBlock = card->currentFat[iBlock]; + if (map[iBlock] == 0) { + if (nextBlock != CARD_FAT_AVAIL) { + card->currentFat[iBlock] = CARD_FAT_AVAIL; + updateOrphan = TRUE; + } + cFree++; + } else if (!CARDIsValidBlockNo(card, nextBlock) && nextBlock != 0xFFFF) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + + if (cFree != card->currentFat[CARD_FAT_FREEBLOCKS]) { + card->currentFat[CARD_FAT_FREEBLOCKS] = cFree; + updateOrphan = TRUE; + } + + if (updateOrphan) { + __CARDCheckSum(&card->currentFat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), + &card->currentFat[CARD_FAT_CHECKSUM], + &card->currentFat[CARD_FAT_CHECKSUMINV]); + } + + memcpy(fat[currentFat ^ 1], fat[currentFat], CARD_SYSTEM_BLOCK_SIZE); + + if (updateDir) { + if (xferBytes) { + *xferBytes = CARD_SYSTEM_BLOCK_SIZE; + } + return __CARDUpdateDir(chan, callback); + } + + if (updateFat | updateOrphan) { + if (xferBytes) { + *xferBytes = CARD_SYSTEM_BLOCK_SIZE; + } + return __CARDUpdateFatBlock(chan, card->currentFat, callback); + } + + __CARDPutControlBlock(card, CARD_RESULT_READY); + if (callback) { + BOOL enabled = OSDisableInterrupts(); + callback(chan, CARD_RESULT_READY); + OSRestoreInterrupts(enabled); + } + return CARD_RESULT_READY; +} + +s32 CARDCheckAsync(s32 chan, CARDCallback callback) { + s32 xferBytes; + return CARDCheckExAsync(chan, &xferBytes, callback); +} + +s32 CARDCheckEx(s32 chan, s32* xferBytes) { + s32 result = CARDCheckExAsync(chan, xferBytes, __CARDSyncCallback); + if (result < 0 || xferBytes == 0) { + return result; + } + + return __CARDSync(chan); +} + +s32 CARDCheck(s32 chan) { + s32 xferBytes; + return CARDCheckEx(chan, &xferBytes); +} diff --git a/src/dolphin/card/src/CARDCreate.c b/src/dolphin/card/src/CARDCreate.c new file mode 100644 index 0000000..7da5ab0 --- /dev/null +++ b/src/dolphin/card/src/CARDCreate.c @@ -0,0 +1,126 @@ +#include + +#include "__card.h" + +// prototypes +static void CreateCallbackFat(s32 chan, s32 result); + +static void CreateCallbackFat(s32 chan, s32 result) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = NULL; + + if (result >= 0) { + dir = __CARDGetDirBlock(card); + ent = &dir[card->freeNo]; + memcpy(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)); + memcpy(ent->company, card->diskID->company, sizeof(ent->company)); + ent->permission = 4; + ent->copyTimes = 0; + + ASSERTLINE(111, CARDIsValidBlockNo(card, card->startBlock)); + ent->startBlock = (u16)card->startBlock; + ent->bannerFormat = 0; + ent->iconAddr = -1; + ent->iconFormat = 0; + ent->iconSpeed = 0; + ent->commentAddr = -1; + + CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST); + card->fileInfo->offset = 0; + card->fileInfo->iBlock = ent->startBlock; + ent->time = OSTicksToSeconds(OSGetTime()); + result = __CARDUpdateDir(chan, callback); + if (result < 0) { + goto after; + } + } else { +after:; + __CARDPutControlBlock(card, result); + if (callback) { + callback(chan, result); + } + } +} + +s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + u16 fileNo; + u16 freeNo; + u16* fat; + s32 result; + + ASSERTLINE(175, 0 <= chan && chan < 2); + ASSERTLINE(176, strlen(fileName) <= CARD_FILENAME_MAX); + + if (strlen(fileName) > (u32)CARD_FILENAME_MAX) { + return CARD_RESULT_NAMETOOLONG; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + ASSERTLINE(188, 0 < size && (size % card->sectorSize) == 0); + + if (size <= 0 || (size % card->sectorSize) != 0) { + return CARD_RESULT_FATAL_ERROR; + } + + freeNo = (u16)-1; + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + ent = &dir[fileNo]; + if (ent->gameName[0] == 0xff) { + if (freeNo == (u16)-1) { + freeNo = fileNo; + } + } else if (memcmp(ent->gameName, card->diskID->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((char*)ent->fileName, fileName, CARD_FILENAME_MAX); + + card->fileInfo = fileInfo; + fileInfo->chan = chan; + fileInfo->fileNo = freeNo; + + result = __CARDAllocBlock(chan, size / card->sectorSize, CreateCallbackFat); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo) { + s32 result = CARDCreateAsync(chan, fileName, size, fileInfo, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/src/CARDDelete.c b/src/dolphin/card/src/CARDDelete.c new file mode 100644 index 0000000..0acf24b --- /dev/null +++ b/src/dolphin/card/src/CARDDelete.c @@ -0,0 +1,108 @@ +#include + +#include "__card.h" + +// prototypes +static void DeleteCallback(s32 chan, s32 result); + +static void DeleteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = NULL; + + if (result < 0) + goto error; + + result = __CARDFreeBlock(chan, card->startBlock, callback); + if (result < 0) + goto error; + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) + callback(chan, result); +} + +s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + + ASSERTLINE(133, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(134, 0 <= chan && chan < 2); + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo) + return CARD_RESULT_FATAL_ERROR; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) + return __CARDPutControlBlock(card, result); + + if (__CARDIsOpened(card, fileNo)) + return __CARDPutControlBlock(card, CARD_RESULT_BUSY); + + card->startBlock = ent->startBlock; + memset(ent, 0xff, sizeof(CARDDir)); + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + result = __CARDUpdateDir(chan, DeleteCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; +} + +s32 CARDFastDelete(s32 chan, s32 fileNo) { + s32 result = CARDFastDeleteAsync(chan, fileNo, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} + +s32 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback) { + CARDControl* card; + s32 fileNo; + s32 result; + CARDDir* dir; + CARDDir* ent; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + result = __CARDGetFileNo(card, fileName, &fileNo); + if (result < 0) + return __CARDPutControlBlock(card, result); + if (__CARDIsOpened(card, fileNo)) + return __CARDPutControlBlock(card, CARD_RESULT_BUSY); + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + card->startBlock = ent->startBlock; + memset(ent, 0xff, sizeof(CARDDir)); + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + result = __CARDUpdateDir(chan, DeleteCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; +} + +s32 CARDDelete(s32 chan, const char* fileName) { + s32 result = CARDDeleteAsync(chan, fileName, __CARDSyncCallback); + if (result < 0) + return result; + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/src/CARDDir.c b/src/dolphin/card/src/CARDDir.c new file mode 100644 index 0000000..e154a9c --- /dev/null +++ b/src/dolphin/card/src/CARDDir.c @@ -0,0 +1,89 @@ +#include + +#include "__card.h" + +// prototypes +static void WriteCallback(s32 chan, s32 result); +static void EraseCallback(s32 chan, s32 result); + +CARDDir* __CARDGetDirBlock(CARDControl* card) { + ASSERTLINE(54, card->currentDir); + return card->currentDir; +} + +static void WriteCallback(s32 chan, s32 result) { + CARDControl* card = &__CARDBlock[chan]; + CARDCallback callback; + + if (result >= 0) { + CARDDir* dir0 = (CARDDir*)((u8*)card->workArea + 0x2000); + CARDDir* dir1 = (CARDDir*)((u8*)card->workArea + 0x4000); + + ASSERTLINE(79, card->currentDir); + + if (card->currentDir == dir0) { + card->currentDir = dir1; + memcpy(dir1, dir0, 0x2000); + } else { + ASSERTLINE(87, card->currentDir == dir1); + card->currentDir = dir0; + memcpy(dir0, dir1, 0x2000); + } + } + + if (!card->apiCallback) + __CARDPutControlBlock(card, result); + + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = NULL; + callback(chan, result); + } +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card = &__CARDBlock[chan]; + CARDCallback callback; + CARDDir* dir; + u32 addr; + + if (result >= 0) { + dir = __CARDGetDirBlock(card); + addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; + result = __CARDWrite(chan, addr, 0x2000, dir, WriteCallback); + if (result >= 0) + return; + } + + if (!card->apiCallback) + __CARDPutControlBlock(card, result); + + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = NULL; + callback(chan, result); + } +} + +s32 __CARDUpdateDir(s32 chan, CARDCallback callback) { + CARDControl* card; + CARDDirCheck* check; + u32 addr; + CARDDir* dir; + + ASSERTLINE(173, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (!card->attached) + return CARD_RESULT_NOCARD; + + dir = __CARDGetDirBlock(card); + check = CARDGetDirCheck(dir); + ++check->checkCode; + __CARDCheckSum(dir, 0x2000 - sizeof(u32), &check->checkSum, &check->checkSumInv); + DCStoreRange(dir, 0x2000); + + card->eraseCallback = callback; + addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; + return __CARDEraseSector(chan, addr, EraseCallback); +} diff --git a/src/dolphin/card/src/CARDErase.c b/src/dolphin/card/src/CARDErase.c new file mode 100644 index 0000000..73bb8ef --- /dev/null +++ b/src/dolphin/card/src/CARDErase.c @@ -0,0 +1,102 @@ +#include + +#include "__card.h" + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDDir* dir; + CARDDir* ent; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[chan]; + + if (result >= 0) { + fileInfo = card->fileInfo; + if (fileInfo->length < 0) { + result = CARD_RESULT_CANCELED; + goto error; + } + + fileInfo->length -= card->sectorSize; + if (fileInfo->length <= 0) { + dir = __CARDGetDirBlock(card); + ent = dir + fileInfo->fileNo; + ent->time = OSTicksToSeconds(OSGetTime()); + callback = card->apiCallback; + card->apiCallback = NULL; + + result = __CARDUpdateDir(chan, callback); + } else { + fat = __CARDGetFatBlock(card); + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + + if (fileInfo->iBlock < 5 || fileInfo->iBlock >= card->cBlock) { + result = CARD_RESULT_BROKEN; + goto error; + } + + result = __CARDEraseSector(chan, card->sectorSize * fileInfo->iBlock, EraseCallback); + } + + if (result < 0) { + goto error; + } + return; + } + +error: + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(98, callback); + callback(chan, result); +} + +s32 CARDEraseAsync(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + ASSERTLINE(132, 0 < length); + + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) { + return result; + } + + ASSERTLINE(138, OFFSET(offset, card->sectorSize) == 0); + ASSERTLINE(139, OFFSET(length, card->sectorSize) == 0); + + if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) { + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + } + + dir = __CARDGetDirBlock(card); + ent = dir + fileInfo->fileNo; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + + result = __CARDEraseSector(fileInfo->chan, card->sectorSize * fileInfo->iBlock, EraseCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + + return result; +} + +s32 CARDErase(CARDFileInfo* fileInfo, s32 length, s32 offset) { + s32 result = CARDEraseAsync(fileInfo, length, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(fileInfo->chan); +} diff --git a/src/dolphin/card/src/CARDFormat.c b/src/dolphin/card/src/CARDFormat.c new file mode 100644 index 0000000..7bcc76d --- /dev/null +++ b/src/dolphin/card/src/CARDFormat.c @@ -0,0 +1,137 @@ +#include + +#include "os/__os.h" +#include "__card.h" + +static void FormatCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) + goto error; + + ++card->formatStep; + if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) { + result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); + if (result >= 0) + return; + } else if (card->formatStep < 2 * CARD_NUM_SYSTEM_BLOCK) { + int step = card->formatStep - CARD_NUM_SYSTEM_BLOCK; + result = __CARDWrite(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, + (u8* )card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), FormatCallback); + if (result >= 0) + return; + } else { + card->currentDir = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE); + memcpy(card->currentDir, (u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE, CARD_SYSTEM_BLOCK_SIZE); + card->currentFat = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE); + memcpy(card->currentFat, (u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE, CARD_SYSTEM_BLOCK_SIZE); + } + +error: + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(133, callback); + callback(chan, result); +} + +s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { + CARDControl* card; + CARDID* id; + CARDDir* dir; + u16* fat; + s16 i; + s32 result; + OSSram* sram; + OSSramEx* sramEx; + u16 dvdstatus; + OSTime time; + OSTime rand; + + ASSERTLINE(167, encode == CARD_ENCODE_ANSI || encode == CARD_ENCODE_SJIS); + ASSERTLINE(168, 0 <= chan && chan < 2); + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + id = (CARDID*)card->workArea; + memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE); + dvdstatus = __VIRegs[55]; + + id->encode = encode; + sram = __OSLockSram(); + *(u32*)&id->serial[20] = sram->counterBias; + *(u32*)&id->serial[24] = sram->language; + __OSUnlockSram(FALSE); + + rand = time = OSGetTime(); + + sramEx = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + rand = (rand * 1103515245 + 12345) >> 16; + id->serial[i] = (u8)(sramEx->flashID[chan][i] + rand); + rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF; + } + __OSUnlockSramEx(FALSE); + + *(u32*)&id->serial[28] = dvdstatus; + *(OSTime*)&id->serial[12] = time; + + id->deviceID = 0; + id->size = card->size; + __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &id->checkSum, &id->checkSumInv); + + for (i = 0; i < 2; i++) { + CARDDirCheck* check; + + dir = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); + memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE); + check = CARDGetDirCheck(dir); + check->checkCode = i; + __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum, &check->checkSumInv); + } + + for (i = 0; i < 2; i++) { + fat = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE); + memset(fat, 0x00, CARD_SYSTEM_BLOCK_SIZE); + fat[CARD_FAT_CHECKCODE] = (u16)i; + fat[CARD_FAT_FREEBLOCKS] = (u16)(card->cBlock - CARD_NUM_SYSTEM_BLOCK); + fat[CARD_FAT_LASTSLOT] = CARD_NUM_SYSTEM_BLOCK - 1; + __CARDCheckSum(&fat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &fat[CARD_FAT_CHECKSUM], + &fat[CARD_FAT_CHECKSUMINV]); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + DCStoreRange(card->workArea, CARD_WORKAREA_SIZE); + + card->formatStep = 0; + result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; +} + +s32 __CARDFormatRegion(s32 chan, u16 encode) { + s32 result = __CARDFormatRegionAsync(chan, encode, &__CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} + +s32 CARDFormatAsync(s32 chan, CARDCallback callback) { + return __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), callback); +} + +s32 CARDFormat(s32 chan) { + s32 result = __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), &__CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/src/CARDMount.c b/src/dolphin/card/src/CARDMount.c new file mode 100644 index 0000000..4ca607d --- /dev/null +++ b/src/dolphin/card/src/CARDMount.c @@ -0,0 +1,394 @@ +#include +#include + +#include "os/__os.h" +#include "__card.h" + +static u32 SectorSizeTable[8] = { + 8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024, 256 * 1024, 0, 0, +}; + +static u32 LatencyTable[8] = { + 4, 8, 16, 32, 64, 128, 256, 512, +}; + +// prototypes +static s32 DoMount(s32 chan); +static void DoUnmount(s32 chan, s32 result); + +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; +} + +void __CARDDisable(BOOL disable) { + BOOL enabled = OSDisableInterrupts(); + + __gUnknown800030E3 &= ~0x80; + if (disable) { + __gUnknown800030E3 |= 0x80; + } + + OSRestoreInterrupts(enabled); +} + +int CARDProbe(s32 chan) { + if (__gUnknown800030E3 & 0x80) { + return 0; + } else { + return EXIProbe(chan); + } +} + +s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) { + u32 id; + CARDControl* card; + BOOL enabled; + s32 result; + int probe; + + if (chan < 0 || 2 <= chan) + return CARD_RESULT_FATAL_ERROR; + + if (__gUnknown800030E3 & 0x80) { + return CARD_RESULT_NOCARD; + } + + card = &__CARDBlock[chan]; + enabled = OSDisableInterrupts(); + + probe = EXIProbeEx(chan); + if (probe == -1) + result = CARD_RESULT_NOCARD; + else if (probe == 0) + result = CARD_RESULT_BUSY; + else if (card->attached) { + if (card->mountStep < 1) + result = CARD_RESULT_BUSY; + else { + if (memSize) + *memSize = card->size; + + if (sectorSize) + *sectorSize = card->sectorSize; + + result = CARD_RESULT_READY; + } + } + else if ((EXIGetState(chan) & 8)) + result = CARD_RESULT_WRONGDEVICE; + else if (!EXIGetID(chan, 0, &id)) + result = CARD_RESULT_BUSY; + else if (IsCard(id)) { + if (memSize) + *memSize = (s32)(id & 0xfc); + + if (sectorSize) + *sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; + result = CARD_RESULT_READY; + } else { + result = CARD_RESULT_WRONGDEVICE; + } + + OSRestoreInterrupts(enabled); + return result; +} + +static s32 DoMount(s32 chan) { + CARDControl* card; + u32 id; + u8 status; + s32 result; + OSSramEx* sram; + int i; + u8 checkSum; + int step; + + ASSERTLINE(399, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (card->mountStep == 0) { + if (EXIGetID(chan, 0, &id) == 0) { + result = CARD_RESULT_NOCARD; + } else if (IsCard(id)) { + result = CARD_RESULT_READY; + } else { + result = CARD_RESULT_WRONGDEVICE; + } + + if (result < 0) + goto error; + + card->cid = id; + card->size = (u16)(id & 0xFC); + ASSERTLINE(424, card->size); + + card->sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; + ASSERTLINE(426, card->sectorSize); + + card->cBlock = (u16)((card->size * 1024 * 1024 / 8) / card->sectorSize); + ASSERTLINE(428, 8 <= card->cBlock); + + card->latency = LatencyTable[(id & 0x00000700) >> 8]; + + result = __CARDReadVendorID(chan, &card->vendorID); + if (result < 0) + goto error; + + if (CARDGetFastMode() && (card->vendorID >> 8) == 0xEC) { + card->pageSize = 512; + } else { + card->pageSize = 128; + } + + result = __CARDClearStatus(chan); + if (result < 0) + goto error; + + result = __CARDReadStatus(chan, &status); + if (result < 0) + goto error; + + if (!EXIProbe(chan)) { + result = CARD_RESULT_NOCARD; + goto error; + } + + if (!(status & 0x40)) { + result = __CARDUnlock(chan, card->id); + if (result < 0) + goto error; + + checkSum = 0; + sram = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + sram->flashID[chan][i] = card->id[i]; + checkSum += card->id[i]; + } + sram->flashIDCheckSum[chan] = (u8)~checkSum; + __OSUnlockSramEx(TRUE); + + return result; + } else { + card->mountStep = 1; + + checkSum = 0; + sram = __OSLockSramEx(); + for (i = 0; i < 12; i++) + checkSum += sram->flashID[chan][i]; + + __OSUnlockSramEx(FALSE); + if (sram->flashIDCheckSum[chan] != (u8)~checkSum) { + result = CARD_RESULT_IOERROR; + goto error; + } + } + } + + if (card->mountStep == 1) { + if (card->cid == 0x80000004) { + u16 vendorID; + + sram = __OSLockSramEx(); + vendorID = *(u16*)sram->flashID[chan]; + __OSUnlockSramEx(FALSE); + + if (__CARDVendorID == 0xFFFF || vendorID != __CARDVendorID) { + result = CARD_RESULT_WRONGDEVICE; + goto error; + } + } + + card->mountStep = 2; + + result = __CARDEnableInterrupt(chan, TRUE); + if (result < 0) + goto error; + + EXISetExiCallback(chan, __CARDExiHandler); + EXIUnlock(chan); + DCInvalidateRange(card->workArea, CARD_WORKAREA_SIZE); + } + + step = card->mountStep - 2; + result = __CARDRead(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, + (u8 *)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), __CARDMountCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; + +error: + EXIUnlock(chan); + DoUnmount(chan, result); + return result; +} + +void __CARDMountCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + ASSERTLINE(570, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + switch (result) { + case CARD_RESULT_READY: + if (++card->mountStep < CARD_MAX_MOUNT_STEP) { + result = DoMount(chan); + if (0 <= result) + return; + } else + result = __CARDVerify(card); + break; + case CARD_RESULT_UNLOCKED: + card->unlockCallback = __CARDMountCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) { + return; + } + card->unlockCallback = 0; + + result = DoMount(chan); + if (result >= 0) + return; + break; + case CARD_RESULT_IOERROR: + case CARD_RESULT_NOCARD: + DoUnmount(chan, result); + break; + } + + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(620, callback); + callback(chan, result); +} + +s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback) { + CARDControl* card; + BOOL enabled; + + ASSERTLINE(652, workArea && ((u32) workArea % 32 == 0)); + ASSERTLINE(653, 0 <= chan && chan < 2); + + if (chan < 0 || 2 <= chan) + return CARD_RESULT_FATAL_ERROR; + + if (__gUnknown800030E3 & 0x80) { + return CARD_RESULT_NOCARD; + } + + card = &__CARDBlock[chan]; + + enabled = OSDisableInterrupts(); + if (card->result == CARD_RESULT_BUSY) { + OSRestoreInterrupts(enabled); + return CARD_RESULT_BUSY; + } + + if (!card->attached && (EXIGetState(chan) & 0x08)) { + OSRestoreInterrupts(enabled); + return CARD_RESULT_WRONGDEVICE; + } + + card->result = CARD_RESULT_BUSY; + card->workArea = workArea; + card->extCallback = detachCallback; + card->apiCallback = attachCallback ? attachCallback : __CARDDefaultApiCallback; + card->exiCallback = 0; + + if (!card->attached && !EXIAttach(chan, __CARDExtHandler)) { + card->result = CARD_RESULT_NOCARD; + OSRestoreInterrupts(enabled); + return CARD_RESULT_NOCARD; + } + + card->mountStep = 0; + card->attached = TRUE; + EXISetExiCallback(chan, 0); + OSCancelAlarm(&card->alarm); + + card->currentDir = 0; + card->currentFat = 0; + + OSRestoreInterrupts(enabled); + + card->unlockCallback = __CARDMountCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) + return CARD_RESULT_READY; + + card->unlockCallback = 0; + return DoMount(chan); +} + +s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback) { + s32 result = CARDMountAsync(chan, workArea, detachCallback, __CARDSyncCallback); + + if (result < 0) + return result; + return __CARDSync(chan); +} + +static void DoUnmount(s32 chan, s32 result) { + CARDControl* card; + BOOL enabled; + + ASSERTLINE(758, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + enabled = OSDisableInterrupts(); + if (card->attached) { + EXISetExiCallback(chan, 0); + EXIDetach(chan); + OSCancelAlarm(&card->alarm); + card->attached = FALSE; + card->result = result; + card->mountStep = 0; + } + OSRestoreInterrupts(enabled); +} + +s32 CARDUnmount(s32 chan) { + CARDControl* card; + s32 result; + + ASSERTLINE(793, 0 <= chan && chan < 2); + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + DoUnmount(chan, CARD_RESULT_NOCARD); + return CARD_RESULT_READY; +} diff --git a/src/dolphin/card/src/CARDNet.c b/src/dolphin/card/src/CARDNet.c new file mode 100644 index 0000000..5f43d3b --- /dev/null +++ b/src/dolphin/card/src/CARDNet.c @@ -0,0 +1,138 @@ +#include + +#include "os/__os.h" +#include "__card.h" + +u16 __CARDVendorID = 0xFFFF; +u8 __CARDPermMask = 0x1C; + +u16 CARDSetVendorID(u16 vendorID) { + u16 prevID = __CARDVendorID; + __CARDVendorID = vendorID; + + return prevID; +} + +u16 CARDGetVendorID() { + return __CARDVendorID; +} + +s32 CARDGetSerialNo(s32 chan, u64* serialNo) { + CARDControl* card; + s32 result; + CARDID* id; + u64 code; + int i; + + ASSERTLINE(105, 0 <= chan && chan < 2); + + if (!(0 <= chan && chan < 2)) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + id = (CARDID*)card->workArea; + for (code = 0, i = 0; i < sizeof(id->serial) / sizeof(u64); ++i) { + code ^= *(u64*)&id->serial[sizeof(u64) * i]; + } + *serialNo = code; + + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 CARDGetUniqueCode(s32 chan, u64* uniqueCode) { + CARDControl* card; + s32 result; + OSSramEx* sram; + + ASSERTLINE(146, 0 <= chan && chan < 2); + + if (!(0 <= chan && chan < 2)) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + sram = __OSLockSramEx(); + memcpy(uniqueCode, &sram->flashID[chan][4], 8); + __OSUnlockSramEx(0); + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 CARDGetAttributes(s32 chan, s32 fileNo, u8* attr) { + CARDDir dirent; + s32 result; + + result = __CARDGetStatusEx(chan, fileNo, &dirent); + if (result == 0) { + *attr = dirent.permission; + } + + return result; +} + +#define CARDCheckAttr(attr, flag) ((u32)(attr & flag) != 0) + +s32 CARDSetAttributesAsync(s32 chan, s32 fileNo, u8 attr, CARDCallback callback) { + CARDDir dirent; + s32 result; + + if (attr & ~__CARDPermMask) { + return CARD_RESULT_NOPERM; + } + + result = __CARDGetStatusEx(chan, fileNo, &dirent); + if (result < 0) { + return result; + } + + if ((CARDCheckAttr(dirent.permission, 0x20) && !CARDCheckAttr(attr, 0x20)) || (CARDCheckAttr(dirent.permission, 0x40) && !CARDCheckAttr(attr, 0x40))) { + return CARD_RESULT_NOPERM; + } + + if ((CARDCheckAttr(attr, 0x20) && CARDCheckAttr(attr, 0x40)) || (CARDCheckAttr(attr, 0x20) && CARDCheckAttr(dirent.permission, 0x40)) || (CARDCheckAttr(attr, 0x40) && CARDCheckAttr(dirent.permission, 0x20))) { + return CARD_RESULT_NOPERM; + } + + dirent.permission = attr; + return __CARDSetStatusExAsync(chan, fileNo, &dirent, callback); +} + +s32 CARDSetAttributes(s32 chan, s32 fileNo, u8 attr) { + s32 result; + + result = CARDSetAttributesAsync(chan, fileNo, attr, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} + +static int __CARDEnablePerm(u8 perm, BOOL enable) { + int prev; + prev = __CARDPermMask & perm ? TRUE : FALSE; + + if (enable) { + __CARDPermMask |= perm; + } else { + __CARDPermMask &= ~perm; + } + + return prev; +} + +int __CARDEnableGlobal(BOOL enable) { + return __CARDEnablePerm(0x20, enable); +} + +int __CARDEnableCompany(BOOL enable) { + return __CARDEnablePerm(0x40, enable); +} diff --git a/src/dolphin/card/src/CARDOpen.c b/src/dolphin/card/src/CARDOpen.c new file mode 100644 index 0000000..bd86568 --- /dev/null +++ b/src/dolphin/card/src/CARDOpen.c @@ -0,0 +1,174 @@ +#include + +#include "__card.h" + +BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName) { + char* entName = (char*)ent->fileName; + char c1; + char c2; + int n = CARD_FILENAME_MAX; + + while (--n >= 0) { + if ((c1 = *entName++) != (c2 = *fileName++)) + return FALSE; + else if (c2 == '\0') + return TRUE; + } + + if (*fileName == '\0') + return TRUE; + return FALSE; +} + +s32 __CARDAccess(CARDControl* card, CARDDir* ent) { + const DVDDiskID* diskID = card->diskID; + + if (ent->gameName[0] == 0xFF) + return CARD_RESULT_NOFILE; + + if (diskID == &__CARDDiskNone + || (memcmp(ent->gameName, diskID->gameName, sizeof(ent->gameName)) == 0 + && memcmp(ent->company, diskID->company, sizeof(ent->company)) == 0)) + return CARD_RESULT_READY; + + return CARD_RESULT_NOPERM; +} + +s32 __CARDIsWritable(CARDControl* card, CARDDir* ent) { + const DVDDiskID* diskID = card->diskID; + s32 result; + u8 perm; + + result = __CARDAccess(card, ent); + if (result == CARD_RESULT_NOPERM) { + perm = ent->permission & __CARDPermMask; + if (perm & 0x20 && (memcmp(ent->gameName, __CARDDiskNone.gameName, sizeof(ent->gameName)) == 0 && + memcmp(ent->company, __CARDDiskNone.company, sizeof(ent->company)) == 0)) + { + return CARD_RESULT_READY; + } else if (perm & 0x40 && (memcmp(ent->gameName, __CARDDiskNone.gameName, sizeof(ent->gameName)) == 0 && + memcmp(ent->company, diskID->company, sizeof(ent->company)) == 0)) + { + return CARD_RESULT_READY; + } + } + + return result; +} + +s32 __CARDIsReadable(CARDControl* card, CARDDir* ent) { + s32 result = __CARDIsWritable(card, ent); + if (result == CARD_RESULT_NOPERM && (ent->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; + + ASSERTLINE(278, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(279, 0 <= chan && chan < 2); + + if (fileNo < 0 || fileNo >= CARD_MAX_FILE) + return CARD_RESULT_FATAL_ERROR; + + fileInfo->chan = -1; + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + 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; + s32 fileNo; + s32 result; + CARDDir* dir; + CARDDir* ent; + + ASSERTLINE(336, 0 <= chan && chan < 2); + + fileInfo->chan = -1; + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + result = __CARDGetFileNo(card, fileName, &fileNo); + if (result >= 0) { + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + if (!CARDIsValidBlockNo(card, ent->startBlock)) + result = CARD_RESULT_BROKEN; + else { + fileInfo->chan = chan; + fileInfo->fileNo = fileNo; + fileInfo->offset = 0; + fileInfo->iBlock = ent->startBlock; + } + } + + return __CARDPutControlBlock(card, result); +} + +s32 CARDClose(CARDFileInfo* fileInfo) { + CARDControl* card; + s32 result; + + ASSERTLINE(380, 0 <= fileInfo->chan && fileInfo->chan < 2); + ASSERTLINE(381, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE); + + result = __CARDGetControlBlock(fileInfo->chan, &card); + if (result < 0) + return result; + + fileInfo->chan = -1; + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +BOOL __CARDIsOpened(CARDControl* card, s32 fileNo) { + return FALSE; +} diff --git a/src/dolphin/card/src/CARDProgram.c b/src/dolphin/card/src/CARDProgram.c new file mode 100644 index 0000000..2e60377 --- /dev/null +++ b/src/dolphin/card/src/CARDProgram.c @@ -0,0 +1,100 @@ +#include + +#include "__card.h" + +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) +#define CARD_PROGRAM_SIZE 128 + +static void ProgramCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDFileInfo* fileInfo; + s32 length; + + card = &__CARDBlock[chan]; + + if (result >= 0) { + fileInfo = card->fileInfo; + if (fileInfo->length < 0) { + result = CARD_RESULT_CANCELED; + goto error; + } + + length = TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; + fileInfo->length -= length; + if (fileInfo->length > 0) { + fat = __CARDGetFatBlock(card); + fileInfo->offset += length; + fileInfo->iBlock = fat[fileInfo->iBlock]; + + if (fileInfo->iBlock < 5 || fileInfo->iBlock >= card->cBlock) { + result = CARD_RESULT_BROKEN; + goto error; + } + + ASSERTLINE(94, OFFSET(fileInfo->length, CARD_PROGRAM_SIZE) == 0); + ASSERTLINE(95, OFFSET(fileInfo->offset, card->sectorSize) == 0); + + result = __CARDWrite(chan, card->sectorSize * fileInfo->iBlock, fileInfo->length < card->sectorSize ? fileInfo->length : card->sectorSize, card->buffer, ProgramCallback); + if (result >= 0) { + return; + } + } + } + +error: + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(114, callback); + callback(chan, result); +} + +s32 CARDProgramAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + ASSERTLINE(147, buf && OFFSET(buf, 32) == 0); + ASSERTLINE(148, OFFSET(offset, CARD_PROGRAM_SIZE) == 0); + ASSERTLINE(149, 0 < length && OFFSET(length, CARD_PROGRAM_SIZE) == 0); + + if (offset & 0x7F || length & 0x7F) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + DCStoreRange(buf, length); + + card->apiCallback = callback ? callback : &__CARDDefaultApiCallback; + offset = fileInfo->offset & (card->sectorSize - 1); + length = length < (card->sectorSize - offset) ? length : card->sectorSize - offset; + + result = __CARDWrite(fileInfo->chan, offset + (card->sectorSize * fileInfo->iBlock), length, buf, ProgramCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + + return result; +} + +s32 CARDProgram(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { + s32 result = CARDProgramAsync(fileInfo, buf, length, offset, __CARDSyncCallback); + if (result < 0) + return result; + + return __CARDSync(fileInfo->chan); +} diff --git a/src/dolphin/card/src/CARDRaw.c b/src/dolphin/card/src/CARDRaw.c new file mode 100644 index 0000000..584a9be --- /dev/null +++ b/src/dolphin/card/src/CARDRaw.c @@ -0,0 +1,82 @@ +#include + +#include "__card.h" + +s32 __CARDRawReadAsync(s32 chan, void* buf, s32 length, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + + ASSERTLINE(59, buf && ((u32) buf % 32) == 0); + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + ASSERTLINE(67, 0 < length && (length % CARD_SEG_SIZE) == 0 && length < CARD_MAX_SIZE); + ASSERTLINE(68, (offset % card->sectorSize) == 0); + + DCInvalidateRange(buf, length); + result = __CARDRead(chan, offset, length, buf, callback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 __CARDRawRead(s32 chan, void* buf, s32 length, s32 offset) { + s32 result = __CARDRawReadAsync(chan, buf, length, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = NULL; + + __CARDPutControlBlock(card, result); + + ASSERTLINE(117, callback); + callback(chan, result); +} + +s32 __CARDRawEraseAsync(s32 chan, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + if (offset % card->sectorSize) { + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + } + + if ((card->size * 1024 * 1024) / 8 <= offset) { + return __CARDPutControlBlock(card, CARD_RESULT_LIMIT); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + result = __CARDEraseSector(chan, offset, EraseCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 __CARDRawErase(s32 chan, s32 offset) { + s32 result = __CARDRawEraseAsync(chan, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/src/CARDRdwr.c b/src/dolphin/card/src/CARDRdwr.c new file mode 100644 index 0000000..8350f57 --- /dev/null +++ b/src/dolphin/card/src/CARDRdwr.c @@ -0,0 +1,105 @@ +#include + +#include "__card.h" + +// prototypes +static void BlockReadCallback(s32 chan, s32 result); +static void BlockWriteCallback(s32 chan, s32 result); + +static void BlockReadCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + + if ((result >= 0)) { + card->xferred += 0x200; + card->addr += 0x200; + ((u8*)card->buffer) += 0x200; + + if (--card->repeat > 0) { + result = __CARDReadSegment(chan, BlockReadCallback); + if (result >= 0) { + return; + } + } + } + + if (!card->apiCallback) { + __CARDPutControlBlock(card, result); + } + + callback = card->xferCallback; + if (callback) { + card->xferCallback = NULL; + callback(chan, result); + } +} + +s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) { + CARDControl* card; + + ASSERTLINE(91, 0 < length && length % CARD_SEG_SIZE == 0); + ASSERTLINE(92, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (card->attached == 0) { + return CARD_RESULT_NOCARD; + } + card->xferCallback = callback; + card->repeat = (length / 512u); + card->addr = addr; + card->buffer = dst; + return __CARDReadSegment(chan, BlockReadCallback); +} + +static void BlockWriteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result >= 0) { + card->xferred += card->pageSize; + card->addr += card->pageSize; + ((u8*)card->buffer) += card->pageSize; + + if (--card->repeat > 0) { + result = __CARDWritePage(chan, BlockWriteCallback); + if (result >= 0) { + return; + } + } + } + + if (!card->apiCallback) { + __CARDPutControlBlock(card, result); + } + + callback = card->xferCallback; + if (callback) { + card->xferCallback = NULL; + callback(chan, result); + } +} + +s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) { + CARDControl* card; + card = &__CARDBlock[chan]; + + ASSERTLINE(153, 0 < length && length % card->pageSize == 0); + ASSERTLINE(154, 0 <= chan && chan < 2); + + if (card->attached == 0) { + return CARD_RESULT_NOCARD; + } + card->xferCallback = callback; + card->repeat = (length / card->pageSize); + card->addr = addr; + card->buffer = dst; + return __CARDWritePage(chan, BlockWriteCallback); +} + +s32 CARDGetXferredBytes(s32 chan) { + ASSERTLINE(183, 0 <= chan && chan < 2); + return __CARDBlock[chan].xferred; +} diff --git a/src/dolphin/card/src/CARDRead.c b/src/dolphin/card/src/CARDRead.c new file mode 100644 index 0000000..74bd544 --- /dev/null +++ b/src/dolphin/card/src/CARDRead.c @@ -0,0 +1,174 @@ +#include + +#include "__card.h" + +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) + +// prototypes +static void ReadCallback(s32 chan, s32 result); + +s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u16* fat; + + ASSERTLINE(98, 0 <= fileInfo->chan && fileInfo->chan < 2); + ASSERTLINE(99, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE); + + result = __CARDGetControlBlock(fileInfo->chan, &card); + if (result < 0) + return result; + + ASSERTLINE(106, CARDIsValidBlockNo(card, fileInfo->iBlock)); + ASSERTLINE(107, fileInfo->offset < card->cBlock * card->sectorSize); + + if (!CARDIsValidBlockNo(card, fileInfo->iBlock) || card->cBlock * card->sectorSize <= fileInfo->offset) + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + + ASSERTLINE(117, ent->gameName[0] != 0xff); + + if (ent->length * card->sectorSize <= offset || ent->length * card->sectorSize < offset + length) + return __CARDPutControlBlock(card, CARD_RESULT_LIMIT); + + card->fileInfo = fileInfo; + fileInfo->length = length; + if (offset < fileInfo->offset) { + fileInfo->offset = 0; + fileInfo->iBlock = ent->startBlock; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + fat = __CARDGetFatBlock(card); + while (fileInfo->offset < TRUNC(offset, card->sectorSize)) { + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + fileInfo->offset = offset; + + *pcard = card; + return CARD_RESULT_READY; +} + +static void ReadCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDFileInfo* fileInfo; + s32 length; + + card = &__CARDBlock[chan]; + if (result < 0) + goto error; + + fileInfo = card->fileInfo; + if (fileInfo->length < 0) { + result = CARD_RESULT_CANCELED; + goto error; + } + + length = TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; + fileInfo->length -= length; + if (fileInfo->length <= 0) + goto error; + + fat = __CARDGetFatBlock(card); + fileInfo->offset += length; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + result = CARD_RESULT_BROKEN; + goto error; + } + + ASSERTLINE(199, OFFSET(fileInfo->length, CARD_SEG_SIZE) == 0); + ASSERTLINE(200, OFFSET(fileInfo->offset, card->sectorSize) == 0); + + result = __CARDRead(chan, card->sectorSize * (u32)fileInfo->iBlock, + (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize, card->buffer, + ReadCallback); + if (result < 0) + goto error; + + return; + +error: + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(217, callback); + callback(chan, result); +} + +s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + ASSERTLINE(250, buf && OFFSET(buf, 32) == 0); + ASSERTLINE(251, OFFSET(offset, CARD_SEG_SIZE) == 0); + ASSERTLINE(252, 0 < length && OFFSET(length, CARD_SEG_SIZE) == 0); + + if (OFFSET(offset, CARD_SEG_SIZE) != 0 || OFFSET(length, CARD_SEG_SIZE) != 0) + return CARD_RESULT_FATAL_ERROR; + + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) + return result; + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + result = __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* buf, s32 length, s32 offset) { + s32 result = CARDReadAsync(fileInfo, buf, length, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(fileInfo->chan); +} + +s32 CARDCancel(CARDFileInfo* fileInfo) { + BOOL enabled; + s32 result; + CARDControl* card; + + ASSERTLINE(338, 0 <= fileInfo->chan && fileInfo->chan < 2); + ASSERTLINE(339, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE); + + enabled = OSDisableInterrupts(); + + card = &__CARDBlock[fileInfo->chan]; + result = CARD_RESULT_READY; + if (!card->attached) + result = CARD_RESULT_NOCARD; + else if (card->result == CARD_RESULT_BUSY && card->fileInfo == fileInfo) { + fileInfo->length = -1; + result = CARD_RESULT_CANCELED; + } + + OSRestoreInterrupts(enabled); + return result; +} diff --git a/src/dolphin/card/src/CARDRename.c b/src/dolphin/card/src/CARDRename.c new file mode 100644 index 0000000..0a76aca --- /dev/null +++ b/src/dolphin/card/src/CARDRename.c @@ -0,0 +1,70 @@ +#include + +#include "__card.h" + +s32 CARDRenameAsync(s32 chan, const char* old, const char* new, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + int fileNo; + int newNo; + int oldNo; + + ASSERTLINE(0x56, 0 <= chan && chan < 2); + ASSERTLINE(0x57, *old != 0xff && *new != 0xff); + ASSERTLINE(0x58, *old != 0x00 && *new != 0x00); + + if (old[0] == 0xFF || new[0] == 0xFF || old[0] == 0 || new[0] == 0) + return CARD_RESULT_FATAL_ERROR; + if (CARD_FILENAME_MAX < (u32)strlen(old) || CARD_FILENAME_MAX < (u32)strlen(new)) + return CARD_RESULT_NAMETOOLONG; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + newNo = oldNo = -1; + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + ent = &dir[fileNo]; + if (ent->gameName[0] == 0xFF) + continue; + + if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) != 0 + || memcmp(ent->company, card->diskID->company, sizeof(ent->company)) != 0) + continue; + + if (__CARDCompareFileName(ent, old)) + oldNo = fileNo; + if (__CARDCompareFileName(ent, new)) + newNo = fileNo; + } + + if (oldNo == -1) + return __CARDPutControlBlock(card, CARD_RESULT_NOFILE); + if (newNo != -1) + return __CARDPutControlBlock(card, CARD_RESULT_EXIST); + + ent = &dir[oldNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) + return __CARDPutControlBlock(card, result); + + strncpy((char*)ent->fileName, new, CARD_FILENAME_MAX); + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + + result = __CARDUpdateDir(chan, callback); + if (result < 0) + __CARDPutControlBlock(card, result); + + return result; +} + +s32 CARDRename(s32 chan, const char* old, const char* new) { + s32 result = CARDRenameAsync(chan, old, new, __CARDSyncCallback); + if (result < 0) + return result; + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/src/CARDStat.c b/src/dolphin/card/src/CARDStat.c new file mode 100644 index 0000000..f99455b --- /dev/null +++ b/src/dolphin/card/src/CARDStat.c @@ -0,0 +1,156 @@ +#include + +#include "__card.h" + +static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) { + u32 offset; + BOOL iconTlut; + int i; + + offset = ent->iconAddr; + if (offset == 0xffffffff) { + stat->bannerFormat = 0; + stat->iconFormat = 0; + stat->iconSpeed = 0; + offset = 0; + } + + iconTlut = FALSE; + switch (CARDGetBannerFormat(ent)) { + case CARD_STAT_BANNER_C8: + stat->offsetBanner = offset; + offset += CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; + stat->offsetBannerTlut = offset; + offset += 2 * 256; + break; + case CARD_STAT_BANNER_RGB5A3: + stat->offsetBanner = offset; + offset += 2 * CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; + stat->offsetBannerTlut = 0xffffffff; + break; + default: + stat->offsetBanner = 0xffffffff; + stat->offsetBannerTlut = 0xffffffff; + break; + } + + for (i = 0; i < CARD_ICON_MAX; ++i) { + switch (CARDGetIconFormat(ent, i)) { + case CARD_STAT_ICON_C8: + stat->offsetIcon[i] = offset; + offset += CARD_ICON_WIDTH * CARD_ICON_HEIGHT; + iconTlut = TRUE; + break; + case CARD_STAT_ICON_RGB5A3: + stat->offsetIcon[i] = offset; + offset += 2 * CARD_ICON_WIDTH * CARD_ICON_HEIGHT; + break; + default: + stat->offsetIcon[i] = 0xffffffff; + break; + } + } + + if (iconTlut) { + stat->offsetIconTlut = offset; + offset += 2 * 256; + } else { + stat->offsetIconTlut = 0xffffffff; + } + stat->offsetData = offset; +} + +s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + + ASSERTLINE(172, 0 <= chan && chan < 2); + ASSERTLINE(173, 0 <= fileNo && fileNo < CARD_MAX_FILE); + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo) + return CARD_RESULT_FATAL_ERROR; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __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; + + ASSERTLINE(231, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(232, 0 <= chan && chan < 2); + ASSERTMSGLINE(240, stat->iconAddr == 0xffffffff || stat->iconAddr < CARD_READ_SIZE, "CARDSetStatus[Async](): stat->iconAddr must be 0xffffffff or less than CARD_READ_SIZE."); + ASSERTMSGLINE(243, stat->commentAddr == 0xffffffff || (stat->commentAddr & 0x1FFF) <= 8128, "CARDSetStatus[Async](): comment strings (set by stat->commentAddr) must not cross 8KB byte boundary."); + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo || + (stat->iconAddr != 0xffffffff && CARD_READ_SIZE <= stat->iconAddr) || + (stat->commentAddr != 0xffffffff && + CARD_SYSTEM_BLOCK_SIZE - CARD_COMMENT_SIZE < stat->commentAddr % CARD_SYSTEM_BLOCK_SIZE)) + { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __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 chan, s32 fileNo, CARDStat* stat) { + s32 result = CARDSetStatusAsync(chan, fileNo, stat, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/src/CARDStatEx.c b/src/dolphin/card/src/CARDStatEx.c new file mode 100644 index 0000000..681dbd5 --- /dev/null +++ b/src/dolphin/card/src/CARDStatEx.c @@ -0,0 +1,124 @@ +#include +#include + +#include "__card.h" + +s32 __CARDGetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent) { + ASSERTLINE(85, 0 <= chan && chan < 2); + ASSERTLINE(86, 0 <= fileNo && fileNo < CARD_MAX_FILE); + + if ((fileNo < 0) || (fileNo >= CARD_MAX_FILE)) { + return CARD_RESULT_FATAL_ERROR; + } + + { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result = __CARDGetControlBlock(chan, &card); + + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsReadable(card, ent); + if (result >= 0) { + memcpy(dirent, ent, 0x40); + } + return __CARDPutControlBlock(card, result); + } +} + +s32 __CARDSetStatusExAsync(s32 chan, s32 fileNo, CARDDir* dirent, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u8* p; + s32 i; + + ASSERTLINE(142, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(143, 0 <= chan && chan < 2); + ASSERTLINE(144, *dirent->fileName != 0xff && *dirent->fileName != 0x00); + + ASSERTMSGLINE(152, dirent->iconAddr == 0xffffffff || dirent->iconAddr < CARD_READ_SIZE, "CARDSetStatus[Async](): stat->iconAddr must be 0xffffffff or less than CARD_READ_SIZE."); + ASSERTMSGLINE(155, dirent->commentAddr == 0xffffffff || (dirent->commentAddr & 0x1FFF) <= 8128, "CARDSetStatus[Async](): comment strings (set by stat->commentAddr) must not cross 8KB byte boundary."); + + if ((fileNo < 0) || (fileNo >= CARD_MAX_FILE) || ((u8) dirent->fileName[0] == 0xFF) || ((u8) dirent->fileName[0] == 0)) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + for (p = dirent->fileName; p < (u8*)&dirent->time; p++) { + if (*p != 0) { + continue; + } + while ((++p) < (u8*)&dirent->time) { + *p = 0; + } + break; + } + + if (dirent->permission & 0x20) { + memset(dirent->gameName, 0, sizeof(dirent->gameName)); + memset(dirent->company, 0, sizeof(dirent->company)); + } + + if (dirent->permission & 0x40) { + memset(dirent->gameName, 0, sizeof(dirent->gameName)); + } + + if ((memcmp(&ent->fileName, &dirent->fileName, 32) != 0) || (memcmp(ent->gameName, dirent->gameName, 4) != 0) || (memcmp(ent->company, dirent->company, 2) != 0)) { + for(i = 0; i < CARD_MAX_FILE; i++) { + if (i != fileNo) { + CARDDir* ent = &dir[i]; // sure, just redeclare ent again... + if (((u8) ent->gameName[0] != 0xFF) + && (memcmp(&ent->gameName, &dirent->gameName, 4) == 0) + && (memcmp(&ent->company, &dirent->company, 2) == 0) + && (memcmp(&ent->fileName, &dirent->fileName, 0x20) == 0)) { + return __CARDPutControlBlock(card, -7); + } + } + } + memcpy(&ent->fileName, &dirent->fileName, 0x20); + memcpy(&ent->gameName, &dirent->gameName, 4); + memcpy(&ent->company, &dirent->company, 2); + } + + ent->time = dirent->time; + ent->bannerFormat = dirent->bannerFormat; + ent->iconAddr = dirent->iconAddr; + ent->iconFormat = dirent->iconFormat; + ent->iconSpeed = dirent->iconSpeed; + ent->commentAddr = dirent->commentAddr; + ent->permission = dirent->permission; + ent->copyTimes = dirent->copyTimes; + + result = __CARDUpdateDir(chan, callback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 __CARDSetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent) { + s32 result = __CARDSetStatusExAsync(chan, fileNo, dirent, &__CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/src/CARDUnlock.c b/src/dolphin/card/src/CARDUnlock.c new file mode 100644 index 0000000..8cc5b21 --- /dev/null +++ b/src/dolphin/card/src/CARDUnlock.c @@ -0,0 +1,436 @@ +#include +#include +#include + +#include "__card.h" + +static u8 CardData[352] ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, + 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF, + 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF, + 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, + 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00, 0x02, 0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E, + 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A, 0x00, 0x10, + 0x00, 0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF, + 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00, + 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94, 0x00, 0x48, 0x27, 0xFF, 0x03, 0x80, + 0x00, 0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F, + 0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, + 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF, + 0x03, 0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7, 0xFF, 0xFF, 0x02, 0xBF, + 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF, + 0x00, 0x8E, 0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF, + 0x02, 0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05, 0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, + 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00, 0x88, 0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0, + 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD, + 0x00, 0xF9, 0xFF, 0xC9, 0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D, + 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static u32 next = 1; + +// prototypes +static u32 exnor_1st(u32 data, u32 rshift); +static u32 exnor(u32 data, u32 lshift); +static u32 bitrev(u32 data); +static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, int mode); +static u32 GetInitVal(void); +static s32 DummyLen(void); +static void InitCallback(void* _task); +static void DoneCallback(void* _task); + +static int CARDRand(void) +{ + next = (next * 0x41C64E6D) + 0x3039; + return (next / 0x10000) & 0x7FFF; +} + +static void CARDSrand(unsigned int seed) +{ + next = seed; +} + +static u32 exnor_1st(u32 data, u32 rshift) +{ + u32 wk; + u32 work; + u32 i; + + work = data; + for (i = 0; i < rshift; i++) + { + wk = ~(work ^ (work >> 7) ^ (work >> 15) ^ (work >> 23)); + work = (work >> 1) | ((wk << 30) & 0x40000000); + } + + return work; +} + +static u32 exnor(u32 data, u32 lshift) +{ + u32 wk; + u32 work; + u32 i; + + work = data; + for (i = 0; i < lshift; i++) + { + // 1bit Left Shift + wk = ~(work ^ (work << 7) ^ (work << 15) ^ (work << 23)); + work = (work << 1) | ((wk >> 30) & 0x00000002); + } + + return work; +} + +static u32 bitrev(u32 data) +{ + u32 wk; + u32 i; + u32 k = 0; + u32 j = 1; + + wk = 0; + for (i = 0; i < 32; i++) + { + if (i > 15) + { + if (i == 31) + wk |= (((data & (0x01 << 31)) >> 31) & 0x01); + else + { + wk |= ((data & (0x01 << i)) >> j); + j += 2; + } + } + else + { + wk |= ((data & (0x01 << i)) << (31 - i - k)); + k++; + } + } + + return wk; +} + +#define SEC_AD1(x) ((u8)(((x) >> 29) & 0x03)) +#define SEC_AD2(x) ((u8)(((x) >> 21) & 0xff)) +#define SEC_AD3(x) ((u8)(((x) >> 19) & 0x03)) +#define SEC_BA(x) ((u8)(((x) >> 12) & 0x7f)) + +static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, int mode) +{ + CARDControl* card; + BOOL err; + u8 cmd[5]; + + ASSERTLINE(240, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (!EXISelect(chan, 0, CARDFreq)) + return CARD_RESULT_NOCARD; + + data &= 0xfffff000; + memset(cmd, 0, 5); + cmd[0] = 0x52; + if (mode == 0) + { + cmd[1] = SEC_AD1(data); + cmd[2] = SEC_AD2(data); + cmd[3] = SEC_AD3(data); + cmd[4] = SEC_BA(data); + } + else + { + cmd[1] = (u8)((data & 0xff000000) >> 24); + cmd[2] = (u8)((data & 0x00ff0000) >> 16); + } + + err = FALSE; + err |= !EXIImmEx(chan, cmd, 5, 1); + err |= !EXIImmEx(chan, (u8*)card->workArea + (u32)sizeof(CARDID), card->latency, 1); + err |= !EXIImmEx(chan, rbuf, rlen, 0); + err |= !EXIDeselect(chan); + + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +static u32 GetInitVal(void) +{ + u32 tmp; + u32 tick; + + tick = OSGetTick(); + CARDSrand(tick); + tmp = 0x7fec8000; + tmp |= CARDRand(); + tmp &= 0xfffff000; + return tmp; +} + +static s32 DummyLen(void) +{ + u32 tick; + u32 wk; + s32 tmp; + u32 max; + + wk = 1; + max = 0; + tick = OSGetTick(); + CARDSrand(tick); + + tmp = CARDRand(); + tmp &= 0x0000001f; + tmp += 1; + while ((tmp < 4) && (max < 10)) + { + tick = OSGetTick(); + tmp = (s32)(tick << wk); + wk++; + if (wk > 16) + wk = 1; + CARDSrand((u32)tmp); + tmp = CARDRand(); + tmp &= 0x0000001f; + tmp += 1; + max++; + } + + if (tmp < 4) + tmp = 4; + + return tmp; +} + +s32 __CARDUnlock(s32 chan, u8 flashID[12]) +{ + u32 init_val; + u32 data; + + s32 dummy; + s32 rlen; + u32 rshift; + + u8 fsts; + u32 wk, wk1; + u32 Ans1 = 0; + u32 Ans2 = 0; + u32* dp; + u8 rbuf[64]; + u32 para1A = 0; + u32 para1B = 0; + u32 para2A = 0; + u32 para2B = 0; + + CARDControl* card; + DSPTaskInfo* task; + CARDDecParam* param; + u8* input; + u8* output; + + card = &__CARDBlock[chan]; + task = &card->task; + param = (CARDDecParam*)card->workArea; + input = (u8*)((u8*)param + sizeof(CARDDecParam)); + input = (u8*)OSRoundUp32B(input); + output = input + 32; + + fsts = 0; + init_val = GetInitVal(); + + dummy = DummyLen(); + rlen = dummy; + if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) + return CARD_RESULT_NOCARD; + + rshift = (u32)(dummy * 8 + 1); + wk = exnor_1st(init_val, rshift); + wk1 = ~(wk ^ (wk >> 7) ^ (wk >> 15) ^ (wk >> 23)); + card->scramble = (wk | ((wk1 << 31) & 0x80000000)); + card->scramble = bitrev(card->scramble); + dummy = DummyLen(); + rlen = 20 + dummy; + data = 0; + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + return CARD_RESULT_NOCARD; + + dp = (u32*)rbuf; + para1A = *dp++; + para1B = *dp++; + Ans1 = *dp++; + para2A = *dp++; + para2B = *dp++; + para1A = (para1A ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + para1B = (para1B ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + Ans1 ^= card->scramble; + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + para2A = (para2A ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + para2B = (para2B ^ card->scramble); + rshift = (u32)(dummy * 8); + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + rshift = 32 + 1; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + *(u32*)&input[0] = para2A; + *(u32*)&input[4] = para2B; + + param->inputAddr = input; + param->inputLength = 8; + param->outputAddr = output; + param->aramAddr = 0; + + DCFlushRange(input, 8); + DCInvalidateRange(output, 4); + DCFlushRange(param, sizeof(CARDDecParam)); + + task->priority = 255; + task->iram_mmem_addr = (u16*)OSCachedToPhysical(CardData); + task->iram_length = 0x160; + task->iram_addr = 0; + task->dsp_init_vector = 0x10; + task->init_cb = InitCallback; + task->res_cb = NULL; + task->done_cb = DoneCallback; + task->req_cb = NULL; + DSPAddTask(task); + + dp = (u32*)flashID; + *dp++ = para1A; + *dp++ = para1B; + *dp = Ans1; + + return CARD_RESULT_READY; +} + +static void InitCallback(void* _task) +{ + s32 chan; + CARDControl* card; + DSPTaskInfo* task; + CARDDecParam* param; + + task = _task; + for (chan = 0; chan < 2; ++chan) + { + card = &__CARDBlock[chan]; + if ((DSPTaskInfo*)&card->task == task) + break; + } + + ASSERTLINE(514, 0 <= chan && chan < 2); + + param = (CARDDecParam*)card->workArea; + + DSPSendMailToDSP(0xff000000); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)param); + while (DSPCheckMailToDSP()) + ; +} + +static void DoneCallback(void* _task) +{ + u8 rbuf[64]; + u32 data; + s32 dummy; + s32 rlen; + u32 rshift; + + u8 unk; + u32 wk, wk1; + u32 Ans2; + + s32 chan; + CARDControl* card; + s32 result; + DSPTaskInfo* task; + CARDDecParam* param; + + u8* input; + u8* output; + task = _task; + for (chan = 0; chan < 2; ++chan) + { + card = &__CARDBlock[chan]; + if ((DSPTaskInfo*)&card->task == task) + break; + } + + ASSERTLINE(563, 0 <= chan && chan < 2); + + param = (CARDDecParam*)card->workArea; + input = (u8*)((u8*)param + sizeof(CARDDecParam)); + input = (u8*)OSRoundUp32B(input); + output = input + 32; + + Ans2 = *(u32*)output; + dummy = DummyLen(); + rlen = dummy; + data = ((Ans2 ^ card->scramble) & 0xffff0000); + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + + rshift = (u32)((dummy + 4 + card->latency) * 8 + 1); + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + dummy = DummyLen(); + rlen = dummy; + data = (((Ans2 << 16) ^ card->scramble) & 0xffff0000); + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + + result = __CARDReadStatus(chan, &unk); + if (!EXIProbe(chan)) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + + if (result == CARD_RESULT_READY && !(unk & 0x40)) + { + EXIUnlock(chan); + result = CARD_RESULT_IOERROR; + } + + __CARDMountCallback(chan, result); +} diff --git a/src/dolphin/card/src/CARDWrite.c b/src/dolphin/card/src/CARDWrite.c new file mode 100644 index 0000000..ad9fa4a --- /dev/null +++ b/src/dolphin/card/src/CARDWrite.c @@ -0,0 +1,123 @@ +#include + +#include "__card.h" + +// prototypes +static void WriteCallback(s32 chan, s32 result); +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) { + fileInfo = card->fileInfo; + if (fileInfo->length < 0) { + result = CARD_RESULT_CANCELED; + goto after; + } + fileInfo->length -= card->sectorSize; + if (fileInfo->length <= 0) { + dir = __CARDGetDirBlock(card); + ent = dir + fileInfo->fileNo; + ent->time = OSGetTime()/(__OSBusClock/4); + callback = card->apiCallback; + card->apiCallback = NULL; + result = __CARDUpdateDir(chan, callback); + goto check; + } else { + fat = __CARDGetFatBlock(card); + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if ((fileInfo->iBlock < 5) || (fileInfo->iBlock >= card->cBlock)) { + result = CARD_RESULT_BROKEN; + goto after; + } + result = __CARDEraseSector(chan, card->sectorSize * fileInfo->iBlock, EraseCallback); +check:; + if (result < 0) { + goto after; + } + } + } else { +after:; + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(0x86, callback); + callback(chan, result); + } +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[chan]; + if (result >= 0) { + fileInfo = card->fileInfo; + ASSERTLINE(161, OFFSET(fileInfo->offset, card->sectorSize) == 0); + result = __CARDWrite(chan, card->sectorSize * fileInfo->iBlock, card->sectorSize, card->buffer, WriteCallback); + if (result < 0) { + goto after; + } + } else { +after:; + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(175, callback); + callback(chan, result); + } +} + +s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + ASSERTLINE(210, buf && ((u32) buf % 32) == 0); + ASSERTLINE(211, 0 < length); + + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) { + return result; + } + + ASSERTLINE(217, OFFSET(offset, card->sectorSize) == 0); + ASSERTLINE(218, OFFSET(length, card->sectorSize) == 0); + + if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) + return __CARDPutControlBlock(card, result); + + DCStoreRange((void*)buf, (u32)length); + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + card->buffer = (void*)buf; + + result = __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; +} + +s32 CARDWrite(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { + s32 result = CARDWriteAsync(fileInfo, buf, length, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(fileInfo->chan); +} diff --git a/src/dolphin/card/src/__card.h b/src/dolphin/card/src/__card.h new file mode 100644 index 0000000..4625c63 --- /dev/null +++ b/src/dolphin/card/src/__card.h @@ -0,0 +1,104 @@ +#ifndef _DOLPHIN_CARD_INTERNAL_H_ +#define _DOLPHIN_CARD_INTERNAL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// CARDStatEx +s32 __CARDGetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent); +s32 __CARDSetStatusExAsync(s32 chan, s32 fileNo, CARDDir* dirent, CARDCallback callback); +s32 __CARDSetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent); + +// CARDUnlock +s32 __CARDUnlock(s32 chan, u8 flashID[12]); + +// CARDRead +s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard); + +// CARDRdwr +s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback); +s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback); + +// CARDRaw +s32 __CARDRawReadAsync(s32 chan, void* buf, s32 length, s32 offset, CARDCallback callback); +s32 __CARDRawRead(s32 chan, void* buf, s32 length, s32 offset); +s32 __CARDRawErase(s32 chan, s32 offset); +s32 __CARDRawEraseAsync(s32 chan, s32 offset, CARDCallback callback); + +// CARDOpen +BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName); +s32 __CARDAccess(CARDControl* card, CARDDir* ent); +s32 __CARDIsPublic(CARDDir* ent); +s32 __CARDGetFileNo(CARDControl* card, const char* fileName, s32* pfileNo); +BOOL __CARDIsOpened(CARDControl* card, s32 fileNo); +s32 __CARDIsWritable(CARDControl* card, CARDDir* ent); +s32 __CARDIsReadable(CARDControl* card, CARDDir* ent); + +// CARDNet +extern u16 __CARDVendorID; +extern u8 __CARDPermMask; +int __CARDEnableGlobal(int enable); +int __CARDEnableCompany(int enable); + +// CARDMount +void __CARDMountCallback(s32 chan, s32 result); +void __CARDDisable(BOOL disable); + +// CARDFormat +s32 CARDFormatAsync(s32 chan, CARDCallback callback); +s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback); +s32 __CARDFormatRegion(s32 chan, u16 encode); + +// CARDDir +CARDDir* __CARDGetDirBlock(CARDControl* card); +s32 __CARDUpdateDir(s32 chan, CARDCallback callback); + +// CARDCheck +void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv); +s32 __CARDVerify(CARDControl* card); + +// CARDBlock +void* __CARDGetFatBlock(CARDControl* card); +s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback); +s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback); +s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback); + +// CARDBios +extern CARDControl __CARDBlock[2]; + +extern DVDDiskID* __CARDDiskID; +extern DVDDiskID __CARDDiskNone; + +void __CARDDefaultApiCallback(s32 chan, s32 result); +void __CARDSyncCallback(s32 chan, s32 result); +void __CARDExtHandler(s32 chan, OSContext* context); +void __CARDExiHandler(s32 chan, OSContext* context); +void __CARDTxHandler(s32 chan, OSContext* context); +void __CARDUnlockedHandler(s32 chan, OSContext* context); +int __CARDReadNintendoID(s32 chan, u32* id); +s32 __CARDEnableInterrupt(s32 chan, BOOL enable); +s32 __CARDReadStatus(s32 chan, u8* status); +int __CARDReadVendorID(s32 chan, u16* id); +s32 __CARDClearStatus(s32 chan); +s32 __CARDSleep(s32 chan); +s32 __CARDWakeup(s32 chan); +s32 __CARDReadSegment(s32 chan, CARDCallback callback); +s32 __CARDWritePage(s32 chan, CARDCallback callback); +s32 __CARDErase(s32 chan, CARDCallback callback); +s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback); +void __CARDSetDiskID(const DVDDiskID* id); +s32 __CARDGetControlBlock(s32 chan, CARDControl **pcard); +s32 __CARDPutControlBlock(CARDControl* card, s32 result); +s32 __CARDSync(s32 chan); +u16 __CARDGetFontEncode(void); +u16 __CARDSetFontEncode(u16 encode); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_CARD_INTERNAL_H_ diff --git a/src/dolphin/db/src/db.c b/src/dolphin/db/src/db.c new file mode 100644 index 0000000..3e16342 --- /dev/null +++ b/src/dolphin/db/src/db.c @@ -0,0 +1,59 @@ +#include +#include +#include + +u8 DBStack[0x1000]; +u8* DBStackEnd = DBStack + (sizeof(DBStack) - 8); +BOOL DBVerbose; +DBInterface* __DBInterface; + +void DBInit(void) { + __DBInterface = OSPhysicalToCached(0x40); + __DBInterface->ExceptionDestination = (void *)OSCachedToPhysical(__DBExceptionDestination); + DBVerbose = TRUE; +} + +BOOL DBIsDebuggerPresent(void) { + if (__DBInterface == NULL) + return FALSE; + return __DBInterface->bPresent; +} + +void __DBExceptionDestinationAux(void) { + u32* contextAddr; + OSContext* context; + + contextAddr = (void*)0xC0; + context = OSPhysicalToCached(*contextAddr); + OSReport("DBExceptionDestination\n"); + OSDumpContext(context); + PPCHalt(); +} + +asm void __DBExceptionDestination(void) { + nofralloc + mfmsr r3 + ori r3, r3, 0x30 + mtmsr r3 + b __DBExceptionDestinationAux +} + +BOOL __DBIsExceptionMarked(__OSException exception) { + u32 mask = (1 << exception); + return __DBInterface->exceptionMask & mask; +} + +void __DBMarkException(__OSException exception, int value) { + u32 mask = (1 << exception); + + if (value != 0) + __DBInterface->exceptionMask = __DBInterface->exceptionMask | mask; + else + __DBInterface->exceptionMask = __DBInterface->exceptionMask & ~mask; +} + +void __DBSetPresent(u32 value) { + __DBInterface->bPresent = value; +} + +void DBPrintf(char* str, ...) {} diff --git a/src/dolphin/demo/DEMOAVX.c b/src/dolphin/demo/DEMOAVX.c new file mode 100644 index 0000000..27d4917 --- /dev/null +++ b/src/dolphin/demo/DEMOAVX.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include "fake_tgmath.h" + +static s16 __AVX_internal_buffer[3200] ATTRIBUTE_ALIGN(32); + +static void (*__AVX_save_isr)(void); + +static u32 __AVX_num_frames; +static u32 __AVX_num_filled; +static u32 __AVX_curr_frame; + +static u16* __AVX_buffer; +static s16* __AVX_left_buffer; +static s16* __AVX_right_buffer; +static u32 __AVX_write_ptr = 0; +static u32 __AVX_buffer_size = 0; + +static BOOL flag = FALSE; + +static void __DEMOAVX_isr(void) { + u32 frame_address; + + if (__AVX_save_isr) { + (*__AVX_save_isr)(); + + frame_address = 0x80000000 | AIGetDMAStartAddr(); + ASSERTMSGLINE(83, frame_address, "AVX: frame address is NULL!\n"); + + DCInvalidateRange((void*)frame_address, 640); + memcpy((void *)&__AVX_buffer[__AVX_curr_frame * 320], (void*)frame_address, 640); + DCFlushRange((void*)&__AVX_buffer[__AVX_curr_frame * 320], 640); + + __AVX_curr_frame = (__AVX_curr_frame + 1) % __AVX_num_frames; + __AVX_num_filled = (__AVX_num_filled + 1) % 10; + if (__AVX_curr_frame > 4) { + flag = TRUE; + } + } +} + +u32 DEMOAVXGetNumFilled(void) { + u32 tmp; + BOOL old; + + old = OSDisableInterrupts(); + + tmp = __AVX_num_filled; + __AVX_num_filled = 0; + + OSRestoreInterrupts(old); + return tmp; +} + +u32 DEMOAVXGetFrameCounter(void) { + return __AVX_curr_frame; +} + +u32 DEMOAVXRefreshBuffer(u32* start_index, u32* end_index) { + u32 num_filled; + u32 curr_frame; + u32 i; + u32 j; + + if (flag) { + num_filled = DEMOAVXGetNumFilled(); + curr_frame = (__AVX_num_frames + DEMOAVXGetFrameCounter() - num_filled) % __AVX_num_frames; + + *start_index = __AVX_write_ptr; + + for (i = 0; i < num_filled; i++) { + DCInvalidateRange((void*)&__AVX_buffer[curr_frame * 320], 640); + + for (j = 0; j < 320; j += 2) { + __AVX_left_buffer [__AVX_write_ptr] = __AVX_buffer[curr_frame * 320 + j]; + __AVX_right_buffer[__AVX_write_ptr] = __AVX_buffer[curr_frame * 320 + j + 1]; + __AVX_write_ptr = (__AVX_write_ptr + 1) % __AVX_buffer_size; + } + + curr_frame = (curr_frame + 1) % __AVX_num_frames; + } + + *end_index = __AVX_write_ptr; + return num_filled * 160; + } + + return 0; +} + +void DEMOAVXInit(s16* left, s16* right, u32 size) { + __AVX_left_buffer = left; + __AVX_right_buffer = right; + __AVX_write_ptr = 0; + __AVX_buffer_size = size; + + DEMOAVXAttach(__AVX_internal_buffer, 10); +} + +void DEMOAVXAttach(void* buffer, u32 num_frames) { + BOOL old; + u32 i; + + __AVX_buffer = (u16*)buffer; + __AVX_num_frames = num_frames; + __AVX_num_filled = 0; + __AVX_curr_frame = 0; + + for (i = 0; i < num_frames * 320; i++) { + __AVX_buffer[i] = 0; + } + + DCFlushRange(__AVX_buffer, num_frames * 320); + + old = OSDisableInterrupts(); + __AVX_save_isr = AIRegisterDMACallback(__DEMOAVX_isr); + OSRestoreInterrupts(old); +} diff --git a/src/dolphin/demo/DEMOFont.c b/src/dolphin/demo/DEMOFont.c new file mode 100644 index 0000000..9b37170 --- /dev/null +++ b/src/dolphin/demo/DEMOFont.c @@ -0,0 +1,773 @@ +#include +#include + +u32 DEMOFontBitmap[768] ATTRIBUTE_ALIGN(32) = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x000FF000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x000FF000, + 0x00000000, + 0x00F00F00, + 0x00F00F00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F00F00, + 0x00F00F00, + 0x0FFFFFF0, + 0x00F00F00, + 0x0FFFFFF0, + 0x00F00F00, + 0x00F00F00, + 0x00000000, + 0x0000F000, + 0x00FFFFF0, + 0x0F00F000, + 0x00FFFF00, + 0x0000F0F0, + 0x0FFFFF00, + 0x0000F000, + 0x00000000, + 0x0FF000F0, + 0x0FF00F00, + 0x0000F000, + 0x000F0000, + 0x00F00FF0, + 0x0F000FF0, + 0x00000000, + 0x00000000, + 0x000F0000, + 0x00F0F000, + 0x00F0F000, + 0x00FF0000, + 0x0F000FF0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0000F000, + 0x000F0000, + 0x00F00000, + 0x00F00000, + 0x00F00000, + 0x000F0000, + 0x0000F000, + 0x00000000, + 0x000F0000, + 0x0000F000, + 0x00000F00, + 0x00000F00, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00000000, + 0x00F000F0, + 0x000F0F00, + 0x00FFFFF0, + 0x000F0F00, + 0x00F000F0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0000F000, + 0x0000F000, + 0x00FFFFF0, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFFF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x000000F0, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00F00000, + 0x0F000000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x00F00F00, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00F00F00, + 0x000FF000, + 0x00000000, + 0x0000F000, + 0x000FF000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x000FFF00, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x000000F0, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x0FFFFFF0, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x000000F0, + 0x0000FF00, + 0x000000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x00000F00, + 0x0000FF00, + 0x000F0F00, + 0x00F00F00, + 0x0FFFFFF0, + 0x00000F00, + 0x00000F00, + 0x00000000, + 0x0FFFFFF0, + 0x0F000000, + 0x0F000000, + 0x0FFFFF00, + 0x000000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x000FFF00, + 0x00F00000, + 0x0F000000, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x0FFFFFF0, + 0x0F0000F0, + 0x00000F00, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFFF0, + 0x000000F0, + 0x000000F0, + 0x00FFFF00, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00F00000, + 0x000F0000, + 0x0000F000, + 0x00000F00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0FFFFFF0, + 0x00000000, + 0x0FFFFFF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F00000, + 0x000F0000, + 0x0000F000, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00F00000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0000FF00, + 0x000FF000, + 0x00000000, + 0x000FF000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F000FF0, + 0x0F00F0F0, + 0x0F00FFF0, + 0x0F000000, + 0x00FFFFF0, + 0x00000000, + 0x000FF000, + 0x00F00F00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFFF0, + 0x0F0000F0, + 0x0F0000F0, + 0x00000000, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFF00, + 0x00000000, + 0x000FFF00, + 0x00F000F0, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x00F000F0, + 0x000FFF00, + 0x00000000, + 0x0FFFF000, + 0x0F000F00, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F000F00, + 0x0FFFF000, + 0x00000000, + 0x0FFFFFF0, + 0x0F000000, + 0x0F000000, + 0x0FFFFF00, + 0x0F000000, + 0x0F000000, + 0x0FFFFFF0, + 0x00000000, + 0x0FFFFFF0, + 0x0F000000, + 0x0F000000, + 0x0FFFFF00, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x00000000, + 0x000FFF00, + 0x00F00000, + 0x0F000000, + 0x0F00FFF0, + 0x0F0000F0, + 0x00F000F0, + 0x000FFF00, + 0x00000000, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFFF0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00000000, + 0x000FFF00, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x000FFF00, + 0x00000000, + 0x0000FFF0, + 0x00000F00, + 0x00000F00, + 0x00000F00, + 0x00000F00, + 0x0F000F00, + 0x00FFF000, + 0x00000000, + 0x0F0000F0, + 0x0F000F00, + 0x0F00F000, + 0x0FFF0000, + 0x0F00F000, + 0x0F000F00, + 0x0F0000F0, + 0x00000000, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x0FFFFFF0, + 0x00000000, + 0x0F00000F, + 0x0FF000FF, + 0x0F0F0F0F, + 0x0F00F00F, + 0x0F00F00F, + 0x0F00000F, + 0x0F00000F, + 0x00000000, + 0x0F0000F0, + 0x0FF000F0, + 0x0F0F00F0, + 0x0F00F0F0, + 0x0F00F0F0, + 0x0F000FF0, + 0x0F0000F0, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFF00, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F00F0F0, + 0x0F000F00, + 0x00FFF0F0, + 0x00000000, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFF00, + 0x0F00F000, + 0x0F000F00, + 0x0F0000F0, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F000000, + 0x00FFFF00, + 0x000000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x0FFFFFFF, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00F00F00, + 0x00F00F00, + 0x000FF000, + 0x00000000, + 0x0F00000F, + 0x0F00000F, + 0x0F00000F, + 0x0F00F00F, + 0x0F00F00F, + 0x0F00F00F, + 0x00FF0FF0, + 0x00000000, + 0x0F0000F0, + 0x0F0000F0, + 0x00F00F00, + 0x000FF000, + 0x00F00F00, + 0x0F0000F0, + 0x0F0000F0, + 0x00000000, + 0x0F00000F, + 0x00F000F0, + 0x000F0F00, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x0FFFFFF0, + 0x000000F0, + 0x00000F00, + 0x000FF000, + 0x00F00000, + 0x0F000000, + 0x0FFFFFF0, + 0x00000000, + 0x000FFF00, + 0x000F0000, + 0x000F0000, + 0x000F0000, + 0x000F0000, + 0x000F0000, + 0x000FFF00, + 0x00000000, + 0x0F000000, + 0x00F00000, + 0x000F0000, + 0x0000F000, + 0x00000F00, + 0x000000F0, + 0x00000000, + 0x00000000, + 0x00FFF000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00FFF000, + 0x00000000, + 0x000FF000, + 0x00F00F00, + 0x0F0000F0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0FFFFFF0, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x000F0000, + 0x0000F000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFF00, + 0x0F000F00, + 0x0F000F00, + 0x0F000F00, + 0x00FFFFF0, + 0x00000000, + 0x00F00000, + 0x00F00000, + 0x00F00000, + 0x00FFFF00, + 0x00F000F0, + 0x00F000F0, + 0x00FFFF00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFF00, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x00FFFF00, + 0x00000000, + 0x000000F0, + 0x000000F0, + 0x000000F0, + 0x000FFFF0, + 0x00F000F0, + 0x00F000F0, + 0x000FFFF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0FFFFFF0, + 0x0F000000, + 0x00FFFF00, + 0x00000000, + 0x0000FF00, + 0x000F0000, + 0x000F0000, + 0x0FFFFF00, + 0x000F0000, + 0x000F0000, + 0x000F0000, + 0x00000000, + 0x00000000, + 0x000FFFF0, + 0x00F000F0, + 0x00F000F0, + 0x000FFFF0, + 0x000000F0, + 0x000FFF00, + 0x00000000, + 0x00F00000, + 0x00F00000, + 0x00F00000, + 0x00F0FF00, + 0x00FF00F0, + 0x00F000F0, + 0x00F000F0, + 0x00000000, + 0x00000000, + 0x0000F000, + 0x00000000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x00000F00, + 0x00000000, + 0x00000F00, + 0x00000F00, + 0x00000F00, + 0x00F00F00, + 0x000FF000, + 0x00000000, + 0x00000000, + 0x00F00000, + 0x00F00000, + 0x00F00F00, + 0x00F0F000, + 0x00FFF000, + 0x00F00F00, + 0x00000000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000F00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F0FF00, + 0x0F0F00F0, + 0x0F0F00F0, + 0x0F0F00F0, + 0x0F0F00F0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F0FF00, + 0x00FF00F0, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FFF00, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x000FFF00, + 0x00000000, + 0x00000000, + 0x00FFF000, + 0x00F00F00, + 0x00F00F00, + 0x00FFF000, + 0x00F00000, + 0x00F00000, + 0x00000000, + 0x00000000, + 0x000FFF00, + 0x00F00F00, + 0x00F00F00, + 0x000FFF00, + 0x00000F00, + 0x00000FF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F0FFF0, + 0x00FF0000, + 0x00F00000, + 0x00F00000, + 0x00F00000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FFFF0, + 0x00F00000, + 0x000FFF00, + 0x000000F0, + 0x00FFFF00, + 0x00000000, + 0x00000000, + 0x0000F000, + 0x00FFFFF0, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000FF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x000FFFF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x000F0F00, + 0x0000F000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0F0000F0, + 0x0F00F0F0, + 0x0F00F0F0, + 0x0F00F0F0, + 0x00FF0F00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F000F0, + 0x000F0F00, + 0x0000F000, + 0x000F0F00, + 0x00F000F0, + 0x00000000, + 0x00000000, + 0x0F000F00, + 0x0F000F00, + 0x00F00F00, + 0x000FFF00, + 0x00000F00, + 0x00FFF000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFFF0, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00FFFFF0, + 0x00000000, + 0x00000F00, + 0x0000F000, + 0x0000F000, + 0x00FF0000, + 0x0000F000, + 0x0000F000, + 0x00000F00, + 0x00000000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x000F0000, + 0x0000F000, + 0x0000F000, + 0x00000FF0, + 0x0000F000, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00FF00FF, + 0x0F00FF00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FF0000, + 0x0FF00000, + 0xFFFFFFFF, + 0xFFFFF000, + 0xFFFFF000, + 0xFFF00000, + 0x00000000 +}; diff --git a/src/dolphin/demo/DEMOInit.c b/src/dolphin/demo/DEMOInit.c new file mode 100644 index 0000000..630c2f5 --- /dev/null +++ b/src/dolphin/demo/DEMOInit.c @@ -0,0 +1,432 @@ +#include +#include +#include +#include +#include + +#include "__demo.h" + +extern u8 DemoStatEnable; + +static GXRenderModeObj rmodeobj; + +static u8 DemoFirstFrame = 1; + +static void* DefaultFifo = NULL; +static GXFifoObj* DefaultFifoObj = NULL; +static GXRenderModeObj* rmode; +static u32 allocatedFrameBufferSize; +static int GPHangWorkaround; +static u32 FrameCount; +static u32 FrameMissThreshold; +void* DemoFrameBuffer1; +void* DemoFrameBuffer2; +void* DemoCurrentBuffer; + +// prototypes +static void __DEMOInitRenderMode(GXRenderModeObj* mode); +static void __DEMOInitMem(void); +static void __DEMOInitGX(void); +static void __DEMOInitVI(void); +static void __DEMOInitForEmu(void); +static void __NoHangRetraceCallback(u32 count); +static void __NoHangDoneRender(void); +static void __DEMODiagnoseHang(void); + +void DEMOInit(GXRenderModeObj* mode) { + OSInit(); + DVDInit(); + VIInit(); + DEMOPadInit(); + __DEMOInitRenderMode(mode); + __DEMOInitMem(); + VIConfigure(rmode); + DefaultFifo = OSAllocFromHeap(__OSCurrHeap, 0x40000); + DefaultFifoObj = GXInit(DefaultFifo, 0x40000); + __DEMOInitGX(); + __DEMOInitVI(); +} + +static void __DEMOInitRenderMode(GXRenderModeObj* mode) { + if (mode != NULL) { + rmodeobj = *mode; + rmode = &rmodeobj; + return; + } + + switch(VIGetTvFormat()) { + case VI_NTSC: + rmode = &GXNtsc480IntDf; + break; + case VI_PAL: + rmode = &GXPal528IntDf; + break; + case VI_EURGB60: + rmode = &GXEurgb60Hz480IntDf; + break; + case VI_MPAL: + rmode = &GXMpal480IntDf; + break; + default: + OSPanic(__FILE__, 473, "DEMOInit: invalid TV format\n"); + break; + } + + GXAdjustForOverscan(rmode, &rmodeobj, 0, 16); + rmode = &rmodeobj; +} + +static void __DEMOInitMem(void) { + void* arenaLo = OSGetArenaLo(); + void* arenaHi = OSGetArenaHi(); + u32 fbSize = ((u16)(rmode->fbWidth + 15) & 0xFFF0) * rmode->xfbHeight * 2; + allocatedFrameBufferSize = fbSize; + + DemoFrameBuffer1 = (void*)OSRoundUp32B(arenaLo); + DemoFrameBuffer2 = (void*)OSRoundUp32B((u32)DemoFrameBuffer1 + fbSize); + DemoCurrentBuffer = DemoFrameBuffer2; + + arenaLo = (void*)OSRoundUp32B((u32)DemoFrameBuffer2 + fbSize); + OSSetArenaLo(arenaLo); + + arenaLo = OSGetArenaLo(); + arenaHi = OSGetArenaHi(); + arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); + OSSetArenaLo(arenaLo); + + arenaLo = (void*)OSRoundUp32B(arenaLo); + arenaHi = (void*)OSRoundDown32B(arenaHi); + OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi)); + OSSetArenaLo((arenaLo = arenaHi)); +} + +static void __DEMOInitGX(void) { + u16 xfbHeight; + f32 yScale; + + GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f); + GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight); + + yScale = GXGetYScaleFactor(rmode->efbHeight, rmode->xfbHeight); + xfbHeight = GXSetDispCopyYScale(yScale); + + GXSetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight); + GXSetDispCopyDst(rmode->fbWidth, xfbHeight); + GXSetCopyFilter(rmode->aa, rmode->sample_pattern, 1, rmode->vfilter); + + if (rmode->aa != 0) { + GXSetPixelFmt(2, 0); + } else { + GXSetPixelFmt(0, 0); + } + + GXCopyDisp(DemoCurrentBuffer, 1); + GXSetDispCopyGamma(0); +} + +static void __DEMOInitVI(void) { + u32 nin; + + VISetNextFrameBuffer(DemoFrameBuffer1); + DemoCurrentBuffer = DemoFrameBuffer2; + VIFlush(); + VIWaitForRetrace(); + nin = rmode->viTVmode & 1; + if (nin != 0) { + VIWaitForRetrace(); + } +} + +static void __DEMOInitForEmu(void) {} + +void DEMOBeforeRender(void) { + if (GPHangWorkaround != 0) { + GXSetDrawSync(0xFEEB); + GXClearGPMetric(); + } + + if (rmode->field_rendering != 0) { + GXSetViewportJitter(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f, VIGetNextField()); + } else { + GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f); + } + + GXInvalidateVtxCache(); + GXInvalidateTexAll(); +} + +void DEMODoneRender(void) { + if (GPHangWorkaround != 0) { + ASSERTMSGLINE(749, !DemoStatEnable, "DEMOStats and GP hang diagnosis are mutually exclusive"); + __NoHangDoneRender(); + return; + } + + if (DemoStatEnable != 0) { + GXDrawDone(); + DEMOUpdateStats(1); + DEMOPrintStats(); + GXDrawDone(); + DEMOUpdateStats(0); + } + + GXSetZMode(1, 3, 1); + GXSetColorUpdate(1); + GXCopyDisp(DemoCurrentBuffer, 1); + GXDrawDone(); + DEMOSwapBuffers(); +} + +void DEMOSwapBuffers(void) { + VISetNextFrameBuffer(DemoCurrentBuffer); + if (DemoFirstFrame != 0) { + VISetBlack(0); + DemoFirstFrame = 0; + } + + VIFlush(); + VIWaitForRetrace(); + + if ((u32)DemoCurrentBuffer == (u32)DemoFrameBuffer1) { + DemoCurrentBuffer = DemoFrameBuffer2; + } else { + DemoCurrentBuffer = DemoFrameBuffer1; + } +} + +void DEMOSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) { + u32 swap = 0; + + if (a == GX_CC_TEXC) { + swap = 0xF; + } else if (a >= GX_CC_TEXRRR) { + swap = a; + a = GX_CC_TEXC; + } + + if (b == GX_CC_TEXC) { + swap = 0xF; + } else if (b >= GX_CC_TEXRRR) { + swap = b; + b = GX_CC_TEXC; + } + + if (c == GX_CC_TEXC) { + swap = 0xF; + } else if (c >= GX_CC_TEXRRR) { + swap = c; + c = GX_CC_TEXC; + } + + if (d == GX_CC_TEXC) { + swap = 0xF; + } else if (d >= GX_CC_TEXRRR) { + swap = d; + d = GX_CC_TEXC; + } + + GXSetTevColorIn(stage, a, b, c, d); + if (swap != 0) { + GXSetTevSwapMode(stage, 0, swap - 0xF); + } +} + +void DEMOSetTevOp(GXTevStageID id, GXTevMode mode) { + GXTevColorArg carg = GX_CC_RASC; + GXTevAlphaArg aarg = GX_TEVSTAGE5; + + if (id != 0) { + carg = 0; + aarg = 0; + } + + switch(mode) { + case 0: + DEMOSetTevColorIn(id, 0xF, 8, carg, 0xF); + GXSetTevAlphaIn(id, 7, 4, aarg, 7); + break; + case 1: + DEMOSetTevColorIn(id, carg, 8, 9, 0xF); + GXSetTevAlphaIn(id, 7, 7, 7, aarg); + break; + case 2: + DEMOSetTevColorIn(id, carg, 0xC, 8, 0xF); + GXSetTevAlphaIn(id, 7, 4, aarg, 7); + break; + case 3: + DEMOSetTevColorIn(id, 0xF, 0xF, 0xF, 8); + GXSetTevAlphaIn(id, 7, 7, 7, 4); + break; + case 4: + DEMOSetTevColorIn(id, 0xF, 0xF, 0xF, carg); + GXSetTevAlphaIn(id, 7, 7, 7, aarg); + break; + default: + ASSERTMSGLINE(914, FALSE, "DEMOSetTevOp: Invalid Tev Mode"); + break; + } + + GXSetTevColorOp(id, 0, 0, 0, 1, 0); + GXSetTevAlphaOp(id, 0, 0, 0, 1, 0); +} + +GXRenderModeObj* DEMOGetRenderModeObj(void) { + return rmode; +} + +u32 DEMOGetCurrentBuffer(void) { + return (u32)DemoCurrentBuffer; +} + +void DEMOEnableGPHangWorkaround(u32 timeoutFrames) { + if (timeoutFrames != 0) { + ASSERTMSGLINE(989, !DemoStatEnable, "DEMOStats and GP hang diagnosis are mutually exclusive"); + GPHangWorkaround = 1; + FrameMissThreshold = timeoutFrames; + VISetPreRetraceCallback(__NoHangRetraceCallback); + DEMOSetGPHangMetric(1); + } else { + GPHangWorkaround = 0; + FrameMissThreshold = 0; + DEMOSetGPHangMetric(0); + VISetPreRetraceCallback(NULL); + } +} + +static void __NoHangRetraceCallback(u32 count) { + static u32 ovFrameCount = 0; + static u32 lastOvc = 0; + u32 ovc; + u8 overhi; + u8 junk; + + FrameCount++; + + GXGetGPStatus(&overhi, &junk, &junk, &junk, &junk); + ovc = GXGetOverflowCount(); + + if (overhi && ovc == lastOvc) { + ovFrameCount++; + if (ovFrameCount >= FrameMissThreshold) { + OSReport("---------WARNING : HANG AT HIGH WATERMARK----------\n"); + __DEMODiagnoseHang(); + OSPanic(__FILE__, 1048, "Halting program"); + } + } else { + lastOvc = ovc; + ovFrameCount = 0; + } +} + +static void __NoHangDoneRender(void) { + BOOL abort = FALSE; + + GXCopyDisp(DemoCurrentBuffer, 1); + GXSetDrawSync(0xB00B); + + FrameCount = 0; + + while (GXReadDrawSync() != 0xB00B && !abort) { + if (FrameCount >= FrameMissThreshold) { + OSReport("---------WARNING : ABORTING FRAME----------\n"); + abort = TRUE; + __DEMODiagnoseHang(); + DEMOReInit(rmode); + DEMOSetGPHangMetric(1); + } + } + + DEMOSwapBuffers(); +} + +void DEMOSetGPHangMetric(u8 enable) { + if (enable) { + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + + GXCmd1u8(0x61); + GXParam1u32(0x2402C004); + + GXCmd1u8(0x61); + GXParam1u32(0x23000020); + + GXCmd1u8(0x10); + GXParam1u16(0); + GXParam1u16(0x1006); + GXParam1u32(0x84400); + } else { + GXCmd1u8(0x61); + GXParam1u32(0x24000000); + + GXCmd1u8(0x61); + GXParam1u32(0x23000000); + + GXCmd1u8(0x10); + GXParam1u16(0); + GXParam1u16(0x1006); + GXParam1u32(0); + } +} + +static void __DEMODiagnoseHang(void) { + u32 xfTop0, xfBot0, suRdy0, r0Rdy0; + u32 xfTop1, xfBot1, suRdy1, r0Rdy1; + u32 xfTopD, xfBotD, suRdyD, r0RdyD; + u8 readIdle, cmdIdle; + u8 junk; + + GXReadXfRasMetric(&xfBot0, &xfTop0, &r0Rdy0, &suRdy0); + GXReadXfRasMetric(&xfBot1, &xfTop1, &r0Rdy1, &suRdy1); + + xfTopD = (xfTop1 - xfTop0) == 0; + xfBotD = (xfBot1 - xfBot0) == 0; + suRdyD = (suRdy1 - suRdy0) > 0; + r0RdyD = (r0Rdy1 - r0Rdy0) > 0; + + GXGetGPStatus(&junk, &junk, &readIdle, &cmdIdle, &junk); + OSReport("GP status %d%d%d%d%d%d --> ", readIdle, cmdIdle, xfTopD, xfBotD, suRdyD, r0RdyD); + + if (xfBotD == 0 && suRdyD != 0) { + OSReport("GP hang due to XF stall bug.\n"); + } else if (xfTopD == 0 && xfBotD != 0 && suRdyD != 0) { + OSReport("GP hang due to unterminated primitive.\n"); + } else if (cmdIdle == 0 && xfTopD != 0 && xfBotD != 0 && suRdyD != 0) { + OSReport("GP hang due to illegal instruction.\n"); + } else if (readIdle != 0 && cmdIdle != 0 && xfTopD != 0 && xfBotD != 0 && suRdyD != 0 && r0RdyD != 0) { + OSReport("GP appears to be not hung (waiting for input).\n"); + } else { + OSReport("GP is in unknown state.\n"); + } +} + +void DEMOReInit(GXRenderModeObj* mode) { + u32 fbSize; + GXFifoObj tmpobj; + void* tmpFifo; + GXFifoObj* realFifoObj; + void* realFifoBase; + u32 realFifoSize; + + tmpFifo = OSAlloc(64 * 1024); + + realFifoObj = GXGetCPUFifo(); + realFifoBase = GXGetFifoBase(realFifoObj); + realFifoSize = GXGetFifoSize(realFifoObj); + + GXAbortFrame(); + + GXInitFifoBase(&tmpobj, tmpFifo, 64 * 1024); + + GXSetCPUFifo(&tmpobj); + GXSetGPFifo(&tmpobj); + + __DEMOInitRenderMode(mode); + + fbSize = ((u16)(rmode->fbWidth + 15) & ~0xF) * rmode->xfbHeight * 2; + ASSERTMSGLINE(1260, fbSize <= allocatedFrameBufferSize, "DEMOReInit - Previously allocated frame buffer is too small for the new render mode."); + DefaultFifoObj = GXInit(realFifoBase, realFifoSize); + + __DEMOInitGX(); + VIConfigure(rmode); + __DEMOInitVI(); + OSFree(tmpFifo); +} diff --git a/src/dolphin/demo/DEMOPad.c b/src/dolphin/demo/DEMOPad.c new file mode 100644 index 0000000..3320523 --- /dev/null +++ b/src/dolphin/demo/DEMOPad.c @@ -0,0 +1,120 @@ +#include +#include +#include + +#include "__demo.h" + +static u32 PadChanMask[4] = { + PAD_CHAN0_BIT, + PAD_CHAN1_BIT, + PAD_CHAN2_BIT, + PAD_CHAN3_BIT, +}; + +static PADStatus Pad[4]; +DEMODMPad DemoPad[4]; + +u32 DemoNumValidPads; + +// prototypes +static void DEMOPadCopy(PADStatus* pad, DEMODMPad* dmpad); + +static void DEMOPadCopy(PADStatus* pad, DEMODMPad* dmpad) { + u16 dirs; + + if (pad->err != -3) { + dirs = 0; + if (pad->stickX < -0x30) { + dirs |= 0x4000; + } + if (pad->stickX > 0x30) { + dirs |= 0x8000; + } + if (pad->stickY < -0x30) { + dirs |= 0x2000; + } + if (pad->stickY > 0x30) { + dirs |= 0x1000; + } + if (pad->substickX < -0x30) { + dirs |= 0x400; + } + if (pad->substickX > 0x30) { + dirs |= 0x800; + } + if (pad->substickY < -0x30) { + dirs |= 0x200; + } + if (pad->substickY > 0x30) { + dirs |= 0x100; + } + + dmpad->dirsNew = (dirs & (dmpad->dirs ^ dirs)); + dmpad->dirsReleased = (dmpad->dirs & (dmpad->dirs ^ dirs)); + dmpad->dirs = dirs; + dmpad->buttonDown = (pad->button & (dmpad->pst.button ^ pad->button)); + dmpad->buttonUp = (dmpad->pst.button & (dmpad->pst.button ^ pad->button)); + dmpad->stickDeltaX = (pad->stickX - dmpad->pst.stickX); + dmpad->stickDeltaY = (pad->stickY - dmpad->pst.stickY); + dmpad->substickDeltaX = (pad->substickX - dmpad->pst.substickX); + dmpad->substickDeltaY = (pad->substickY - dmpad->pst.substickY); + dmpad->pst = *pad; + } else { + dmpad->dirsNew = dmpad->dirsReleased = 0; + dmpad->buttonDown = dmpad->buttonUp = 0; + dmpad->stickDeltaX = dmpad->stickDeltaY = 0; + dmpad->substickDeltaX = dmpad->substickDeltaY = 0; + } +} + +void DEMOPadRead(void) { + s32 i; + u32 ResetReq = 0; + + PADRead(&Pad[0]); + PADClamp(&Pad[0]); + + DemoNumValidPads = 0; + + for (i = 0; i < 4; i++) { + if (Pad[i].err == 0 || Pad[i].err == -3) { + DemoNumValidPads++; + } else if (Pad[i].err == -1) { + ResetReq |= PadChanMask[i]; + } + + DEMOPadCopy(&Pad[i], &DemoPad[i]); + } + + if (ResetReq != 0) { + PADReset(ResetReq); + } +} + +void DEMOPadInit(void) { + s32 i; + + PADInit(); + + for (i = 0; i < 4; i++) { + DemoPad[i].pst.button = 0; + DemoPad[i].pst.stickX = 0; + DemoPad[i].pst.stickY = 0; + DemoPad[i].pst.substickX = 0; + DemoPad[i].pst.substickY = 0; + DemoPad[i].pst.triggerLeft = 0; + DemoPad[i].pst.triggerRight = 0; + DemoPad[i].pst.analogA = 0; + DemoPad[i].pst.analogB = 0; + DemoPad[i].pst.err = 0; + DemoPad[i].buttonDown = 0; + DemoPad[i].buttonUp = 0; + DemoPad[i].dirs = 0; + DemoPad[i].dirsNew = 0; + DemoPad[i].dirsReleased = 0; + DemoPad[i].stickDeltaX = 0; + DemoPad[i].stickDeltaY = 0; + DemoPad[i].substickDeltaX = 0; + DemoPad[i].substickDeltaY = 0; + } +} diff --git a/src/dolphin/demo/DEMOPuts.c b/src/dolphin/demo/DEMOPuts.c new file mode 100644 index 0000000..af0ea2f --- /dev/null +++ b/src/dolphin/demo/DEMOPuts.c @@ -0,0 +1,403 @@ +#include +#include +#include +#include + +#include "__demo.h" + +static GXTexObj fontTexObj; + +static s32 fontShift; +static OSFontHeader* FontData; +static void* LastSheet; +static s16 FontSize; +static s16 FontSpace; + +// prototypes +static void DrawFontChar(int x, int y, int z, int xChar, int yChar); +static void LoadSheet(void* image, GXTexMapID texMapID); + +void DEMOSetFontType(s32 attr) { + switch(attr) { + case DM_FT_RVS: + GXSetBlendMode(GX_BM_LOGIC, GX_BL_ZERO, GX_BL_ZERO, GX_LO_INVCOPY); + break; + case DM_FT_XLU: + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + break; + case DM_FT_OPQ: + default: + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + break; + } +} + +void DEMOLoadFont(GXTexMapID texMap, GXTexMtx texMtx, DMTexFlt texFlt) { + Mtx fontTMtx; + u16 width; + u16 height; + + width = 64; + height = 0x1800 / width; + GXInitTexObj(&fontTexObj, (void*)DEMOFontBitmap, width, (u16)height, GX_TF_I4, GX_CLAMP, GX_CLAMP, 0); + + if (texFlt == DMTF_POINTSAMPLE) { + GXInitTexObjLOD(&fontTexObj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + fontShift = 0; + } else { + fontShift = 1; + } + + GXLoadTexObj(&fontTexObj, texMap); + MTXScale(fontTMtx, 1.0f / width, 1.0f / height, 1.0f); + GXLoadTexMtxImm(fontTMtx, texMtx, GX_MTX2x4); + GXSetNumTexGens(1); + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, texMtx); +} + +void DEMOSetupScrnSpc(s32 width, s32 height, f32 depth) { + Mtx44 pMtx; + Mtx mMtx; + f32 top; + + if (DEMOGetRenderModeObj()->field_rendering && !VIGetNextField()) { + top = -0.667f; + } else { + top = 0.0f; + } + + MTXOrtho(pMtx, top, height, 0.0f, width, 0.0f, -depth); + GXSetProjection(pMtx, GX_ORTHOGRAPHIC); + MTXIdentity(mMtx); + GXLoadPosMtxImm(mMtx, GX_PNMTX0); + GXSetCurrentMtx(GX_PNMTX0); +} + +void DEMOInitCaption(s32 font_type, s32 width, s32 height) { + DEMOSetupScrnSpc(width, height, 100.0f); + GXSetZMode(GX_ENABLE, GX_ALWAYS, GX_ENABLE); + GXSetNumChans(0); + GXSetNumTevStages(1); + GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + DEMOLoadFont(GX_TEXMAP0, GX_TEXMTX0, DMTF_POINTSAMPLE); + DEMOSetFontType(font_type); +} + +void DEMOPuts(s16 x, s16 y, s16 z, char* string) { + char* str; + s32 s; + s32 t; + s32 c; + s32 w; + s32 len; + s32 i; + + str = string; + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 1); + + // calc len + len = 0; + while (1) { + c = *(str++); + if ((c >= 0x20) && (c <= 0x7F)) { + len++; + continue; + } + + if (len > 0) { + GXBegin(GX_QUADS, GX_VTXFMT0, len * 4); + for(i = 0; i < len; i++) { + w = string[i] - 0x20; + s = fontShift + ((w % 8) * 0x10); + t = fontShift + ((w / 8) * 0x10); + GXPosition3s16(x + (i * 8), y, z); + GXTexCoord2s16(s, t); + GXPosition3s16(x + (i * 8) + 8, y, z); + GXTexCoord2s16(s + 0x10, t); + GXPosition3s16(x + (i * 8) + 8, y + 8, z); + GXTexCoord2s16(s + 0x10, t + 0x10); + GXPosition3s16(x + (i * 8), y + 8, z); + GXTexCoord2s16(s, t + 0x10); + } + GXEnd(); + len = 0; + } + + string = str; + if (c == 0xA) { + y += 0x8; + } else { + break; + } + } +} + +void DEMOPrintf(s16 x, s16 y, s16 z, char* fmt, ...) { + va_list vlist; + char buf[256]; + + va_start(vlist, fmt); + vsprintf(buf, fmt, vlist); + DEMOPuts(x, y, z, buf); + va_end(vlist); +} + +OSFontHeader* DEMOInitROMFont(void) { + switch (OSGetFontEncode()) { + case OS_FONT_ENCODE_SJIS: + FontData = OSAlloc(OS_FONT_SIZE_SJIS); + break; + case OS_FONT_ENCODE_ANSI: + FontData = OSAlloc(OS_FONT_SIZE_ANSI); + break; + default: + FontData = OSAlloc(0x141020); + break; + } + + if (!FontData) { + OSPanic(__FILE__, 446, "Ins. memory to load ROM font."); + } + + if (OSInitFont(FontData) == 0) { + OSPanic(__FILE__, 450, "ROM font is available in boot ROM ver 0.8 or later."); + } + + FontSize = FontData->cellWidth * 16; + FontSpace = -16; + return FontData; +} + +void DEMOSetROMFontSize(s16 size, s16 space) { + FontSize = size * 16; + FontSpace = space * 16; +} + +void DEMOGetROMFontSize(s16* size, s16* space) { + if (size != 0) { + *size = FontSize / 16; + } + + if (space != 0) { + *space = FontSpace / 16; + } +} + +static void DrawFontChar(int x, int y, int z, int xChar, int yChar) { + s16 posLeft = x; + s16 posRight = posLeft + FontSize; + s16 posTop = y - (FontData->ascent * FontSize / FontData->cellWidth); + s16 posBottom = y + (FontData->descent * FontSize / FontData->cellWidth); + + s16 texLeft = xChar; + s16 texRight = (xChar + FontData->cellWidth); + s16 texTop = yChar; + s16 texBottom = (yChar + FontData->cellHeight); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3s16(posLeft, posTop, z); + GXTexCoord2s16(texLeft, texTop); + GXPosition3s16(posRight, posTop, z); + GXTexCoord2s16(texRight, texTop); + GXPosition3s16(posRight, posBottom, z); + GXTexCoord2s16(texRight, texBottom); + GXPosition3s16(posLeft, posBottom, z); + GXTexCoord2s16(texLeft, texBottom); + GXEnd(); +} + +static void LoadSheet(void* image, GXTexMapID texMapID) { + Mtx mtx; + GXTexObj texObj; + + if (LastSheet != image) { + LastSheet = image; + GXInitTexObj(&texObj, image, FontData->sheetWidth, FontData->sheetHeight, FontData->sheetFormat, 0, 0, 0); + GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + GXLoadTexObj(&texObj, texMapID); + MTXScale(mtx, 1.0f / FontData->sheetWidth, 1.0f / FontData->sheetHeight, 1.0f); + GXLoadTexMtxImm(mtx, GX_TEXMTX0, GX_MTX2x4); + GXSetNumTexGens(1); + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0); + } +} + +int DEMORFPuts(s16 x, s16 y, s16 z, char* string) { + s32 cx; + void* image; + s32 xChar; + s32 yChar; + s32 width; + + ASSERTLINE(583, FontData); + LastSheet = NULL; + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 4); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0); + + x *= 16; + y *= 16; + z *= 16; + + width = 0; + while (*string != 0) { + if (*string == '\n') { + width = 0; + y += FontData->leading * FontSize / FontData->cellWidth; + string++; + } else if (*string == '\t') { + width += 8 * (FontSize + FontSpace); + width -= width % (8 * (FontSize + FontSpace)); + string++; + } else { + string = OSGetFontTexture(string, &image, &xChar, &yChar, &cx); + LoadSheet(image, GX_TEXMAP0); + DrawFontChar(x + width, y, z, xChar, yChar); + width = FontSpace + ((FontSize * cx) / FontData->cellWidth) + width; + } + } + + return (width + 15) / 16; +} + +int DEMORFPutsEx(s16 x, s16 y, s16 z, char* string, s16 maxWidth, int length) { + s32 cx; + void* image; + s32 xChar; + s32 yChar; + s32 width; + char* end; + + ASSERTLINE(636, FontData); + LastSheet = NULL; + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 4); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0); + + x *= 16; + y *= 16; + z *= 16; + maxWidth *= 16; + + end = (char*)&string[length]; + width = 0; + while (*string && string < end) { + if (*string == '\n') { + width = 0; + y += FontData->leading * FontSize / FontData->cellWidth; + string++; + } else { + string = OSGetFontTexture(string, &image, &xChar, &yChar, &cx); + if (maxWidth < width + (FontSize * cx / FontData->cellWidth) + FontSpace) { + width = 0; + y += FontData->leading * FontSize / FontData->cellWidth; + } + LoadSheet(image, GX_TEXMAP0); + DrawFontChar(x + width, y, z, xChar, yChar); + width = FontSpace + (FontSize * cx / FontData->cellWidth) + width; + } + } + + return (width + 15) / 16; +} + +int DEMORFPrintf(s16 x, s16 y, s16 z, char* fmt, ...) { + va_list vlist; + char buf[256]; + + va_start(vlist, fmt); + vsprintf(buf, fmt, vlist); + DEMORFPuts(x, y, z, buf); +} + +char* DEMODumpROMFont(char* string) { + u32 image[288]; + void* temp; + int i; + int j; + s32 width; + + ASSERTLINE(724, FontData); + + switch (OSGetFontEncode()) { + case OS_FONT_ENCODE_SJIS: + temp = (u8*)FontData + OS_FONT_SIZE_SJIS - OS_FONT_ROM_SIZE_SJIS; + break; + case OS_FONT_ENCODE_ANSI: + temp = (u8*)FontData + OS_FONT_SIZE_ANSI - OS_FONT_ROM_SIZE_ANSI; + break; + default: + temp = (u8*)FontData + 0xF4020; + break; + } + + temp = (void*)OSRoundDown32B(temp); + OSLoadFont(FontData, temp); + + memset(image, 0, sizeof(image)); + string = OSGetFontTexel(string, &image[0], 0, 0xC, &width); + for (i = 0; i < 0x30; i++) { + j = (i % 8) + ((i / 8) * 0x30); + OSReport("%08x%08x%08x%08x%08x%08x\n", image[j], image[j+8], image[j+0x10], image[j+0x18], image[j+0x20], image[j+0x28]); + } + + OSReport("\nwidth %d\n", width); + OSInitFont(FontData); + return string; +} + +int DEMOGetRFTextWidth(char* string) { + s32 cx; + s32 width; + s32 maxWidth; + + ASSERTLINE(779, FontData); + maxWidth = width = 0; + + while (*string != 0) { + if (*string == '\n') { + if (maxWidth < width) { + maxWidth = width; + } + + width = 0; + } + + string = OSGetFontWidth(string, &cx); + width = FontSpace + ((FontSize * cx) / FontData->cellWidth) + width; + } + + if (maxWidth < width) { + maxWidth = width; + } + + return (maxWidth + 15) / 16; +} + +int DEMOGetRFTextHeight(char* string) { + s32 height; + + ASSERTLINE(815, FontData); + + height = 1; + while (*string) { + if (*string == '\n') { + height++; + } + string++; + } + + height *= FontData->leading * FontSize / FontData->cellWidth; + return (height + 15) / 16; +} diff --git a/src/dolphin/demo/DEMOStats.c b/src/dolphin/demo/DEMOStats.c new file mode 100644 index 0000000..ca79eff --- /dev/null +++ b/src/dolphin/demo/DEMOStats.c @@ -0,0 +1,416 @@ +#include +#include +#include + +#include "__demo.h" + +u8 DemoStatEnable = 0; +static DemoStatData* DemoStat; +static u32 DemoStatIndx; +static u32 DemoStatMaxIndx; +static u32 DemoStatClocks; +static u32 DemoStatDisp; +static u32 DemoStatStrLen; +static u32 topPixIn; +static u32 topPixOut; +static u32 botPixIn; +static u32 botPixOut; +static u32 clrPixIn; +static u32 copyClks; +static u32 vcCheck; +static u32 vcMiss; +static u32 vcStall; +static u32 cpReq; +static u32 tcReq; +static u32 cpuRdReq; +static u32 cpuWrReq; +static u32 dspReq; +static u32 ioReq; +static u32 viReq; +static u32 peReq; +static u32 rfReq; +static u32 fiReq; + +// prototypes +static void DEMOWriteStats(u8 update); +static void DEMOWriteStats(u8 update); + +void DEMOSetStats(DemoStatData* stat, u32 nstats, DEMO_STAT_DISP disp) { + if (stat == 0 || nstats == 0) { + DemoStatEnable = FALSE; + } else { + DemoStatEnable = TRUE; + DemoStat = stat; + DemoStatIndx = 0; + DemoStatMaxIndx = nstats; + DemoStatDisp = disp; + DemoStatStrLen = strlen(DemoStat->text); + } +} + +static void DEMOWriteStats(u8 update) { + u32 cnt0; + u32 cnt1; + u32 cnt2; + u32 cnt3; + u32 cnt4; + u32 cnt5; + u32 cnt6; + u32 cnt7; + u32 cnt8; + u32 cnt9; + + switch (DemoStat[DemoStatIndx].stat_type) { + case DEMO_STAT_GP0: + if (update) { + cnt0 = GXReadGP0Metric(); + DemoStat[DemoStatIndx].count = cnt0; + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + } else { + GXSetGPMetric(DemoStat[DemoStatIndx].stat, GX_PERF1_NONE); + GXClearGPMetric(); + } + break; + case DEMO_STAT_GP1: + if (update) { + cnt0 = GXReadGP1Metric(); + DemoStat[DemoStatIndx].count = cnt0; + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + } else { + GXSetGPMetric(GX_PERF0_NONE, DemoStat[DemoStatIndx].stat); + GXClearGPMetric(); + } + break; + case DEMO_STAT_MEM: + if (update) { + GXReadMemMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5, &cnt6, &cnt7, &cnt8, &cnt9); + cpReq = cnt0; + tcReq = cnt1; + cpuRdReq = cnt2; + cpuWrReq = cnt3; + dspReq = cnt4; + ioReq = cnt5; + viReq = cnt6; + peReq = cnt7; + rfReq = cnt8; + fiReq = cnt9; + } else { + GXClearMemMetric(); + } + break; + case DEMO_STAT_PIX: + if (update) { + GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); + topPixIn = cnt0; + topPixOut = cnt1; + botPixIn = cnt2; + botPixOut = cnt3; + clrPixIn = cnt4; + copyClks = cnt5; + } else { + GXClearPixMetric(); + } + break; + case DEMO_STAT_VC: + if (update) { + GXReadVCacheMetric(&cnt0, &cnt1, &cnt2); + vcCheck = cnt0; + vcMiss = cnt1; + vcStall = cnt2; + } else { + GXSetVCacheMetric(0); + GXClearVCacheMetric(); + } + break; + case DEMO_STAT_FR: + if (update) { + GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); + topPixIn = cnt0; + topPixOut = cnt1; + botPixIn = cnt2; + botPixOut = cnt3; + clrPixIn = cnt4; + copyClks = cnt5; + DemoStatClocks = GXReadGP0Metric(); + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + } else { + GXClearPixMetric(); + GXSetGPMetric(GX_PERF0_CLOCKS, GX_PERF1_NONE); + GXClearGPMetric(); + } + break; + case DEMO_STAT_TBW: + case DEMO_STAT_TBP: + GXClearPixMetric(); + if (update) { + GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); + topPixIn = cnt0; + topPixOut = cnt1; + botPixIn = cnt2; + botPixOut = cnt3; + clrPixIn = cnt4; + copyClks = cnt5; + DemoStatClocks = GXReadGP0Metric(); + GXReadMemMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5, &cnt6, &cnt7, &cnt8, &cnt9); + tcReq = cnt1; + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + } else { + GXClearMemMetric(); + GXSetGPMetric(GX_PERF0_CLOCKS, GX_PERF1_NONE); + GXClearGPMetric(); + } + break; + case DEMO_STAT_MYC: + case DEMO_STAT_MYR: + break; + default: + OSPanic(__FILE__, 295, "DEMOSetStats: Unknown demo stat type\n"); + } +} + +void DEMOUpdateStats(u8 inc) { + DEMOWriteStats(inc); + if (inc) { + DemoStatIndx = DemoStatIndx + 1; + if (DemoStatIndx == DemoStatMaxIndx) { + DemoStatIndx = 0; + } + } +} + +void DEMOPrintStats(void) { + GXRenderModeObj* rmode; + u32 i; + s16 text_x; + s16 text_y; + s16 text_yinc; + u16 wd; + u16 ht; + f32 rate; + + if (DemoStatDisp == DEMO_STAT_IO) { + for (i = 0; i < DemoStatMaxIndx; i++) { + switch (DemoStat[i].stat_type) { + case DEMO_STAT_PIX: + switch (DemoStat[i].stat) { + case 0: + OSReport("%s: %8d\n", DemoStat[i].text, topPixIn); + break; + case 1: + OSReport("%s: %8d\n", DemoStat[i].text, topPixOut); + break; + case 2: + OSReport("%s: %8d\n", DemoStat[i].text, botPixIn); + break; + case 3: + OSReport("%s: %8d\n", DemoStat[i].text, botPixOut); + break; + case 4: + OSReport("%s: %8d\n", DemoStat[i].text, clrPixIn); + break; + case 5: + OSReport("%s: %8d\n", DemoStat[i].text, copyClks); + break; + } + break; + case DEMO_STAT_FR: + rate = 162.0f * (topPixIn + botPixIn) / (f32) (DemoStatClocks - copyClks); + OSReport("%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_TBW: + rate = 162.0f * (tcReq << 5) / (f32) (DemoStatClocks - copyClks); + OSReport("%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_TBP: + rate = (tcReq << 5) / (f32) (topPixIn + botPixIn); + OSReport("%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_VC: + switch (DemoStat[i].stat) { + case 0: + OSReport("%s: %8d\n", DemoStat[i].text, vcCheck); + break; + case 1: + OSReport("%s: %8d\n", DemoStat[i].text, vcMiss); + break; + case 2: + OSReport("%s: %8d\n", DemoStat[i].text, vcStall); + break; + } + break; + case DEMO_STAT_MYR: + rate = DemoStat[i].stat / (f32) DemoStat[i].count; + OSReport("%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_MEM: + switch (DemoStat[i].stat) { + case 0: + OSReport("%s: %8d\n", DemoStat[i].text, cpReq); + break; + case 1: + OSReport("%s: %8d\n", DemoStat[i].text, tcReq); + break; + case 2: + OSReport("%s: %8d\n", DemoStat[i].text, cpuRdReq); + break; + case 3: + OSReport("%s: %8d\n", DemoStat[i].text, cpuWrReq); + break; + case 4: + OSReport("%s: %8d\n", DemoStat[i].text, dspReq); + break; + case 5: + OSReport("%s: %8d\n", DemoStat[i].text, ioReq); + break; + case 6: + OSReport("%s: %8d\n", DemoStat[i].text, viReq); + break; + case 7: + OSReport("%s: %8d\n", DemoStat[i].text, peReq); + break; + case 8: + OSReport("%s: %8d\n", DemoStat[i].text, rfReq); + break; + case 9: + OSReport("%s: %8d\n", DemoStat[i].text, fiReq); + break; + } + break; + default: + OSReport("%s: %8d\n", DemoStat[i].text, DemoStat[i].count); + break; + } + } + } else { + rmode = DEMOGetRenderModeObj(); + switch (DemoStatDisp) { + case DEMO_STAT_TL: + text_x = 0x10; + text_y = 0x10; + text_yinc = 0xA; + wd = rmode->fbWidth; + ht = rmode->xfbHeight; + break; + case DEMO_STAT_BL: + text_x = 0x10; + text_y = rmode->xfbHeight - 0x18; + text_yinc = -0xA; + wd = rmode->fbWidth; + ht = rmode->xfbHeight; + break; + case DEMO_STAT_TLD: + text_x = 8; + text_y = 8; + text_yinc = 9; + wd = rmode->fbWidth / 2; + ht = rmode->xfbHeight / 2; + break; + case DEMO_STAT_BLD: + text_x = 8; + text_y = (rmode->xfbHeight - 0x18) / 2; + text_yinc = -9; + wd = rmode->fbWidth / 2; + ht = rmode->xfbHeight / 2; + break; + } + DEMOInitCaption(0, wd, ht); + for (i = 0; i < DemoStatMaxIndx; i++) { + switch (DemoStat[i].stat_type) { + case DEMO_STAT_PIX: + switch (DemoStat[i].stat) { + case 0: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, topPixIn); + break; + case 1: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, topPixOut); + break; + case 2: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, botPixIn); + break; + case 3: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, botPixOut); + break; + case 4: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, clrPixIn); + break; + case 5: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, copyClks); + break; + } + break; + case DEMO_STAT_FR: + rate = 162.0f * (topPixIn + botPixIn) / (f32) (DemoStatClocks - copyClks); + DEMOPrintf(text_x, text_y, 0, "%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_TBW: + rate = 162.0f * (tcReq << 5) / (f32) (DemoStatClocks - copyClks); + DEMOPrintf(text_x, text_y, 0, "%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_TBP: + rate = (tcReq << 5) / (f32) (topPixIn - botPixIn); + DEMOPrintf(text_x, text_y, 0, "%s: %8.3f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_VC: + switch (DemoStat[i].stat) { + case 0: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcCheck); + break; + case 1: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcMiss); + break; + case 2: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcStall); + break; + } + break; + case DEMO_STAT_MEM: + switch (DemoStat[i].stat) { + case 0: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpReq); + break; + case 1: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, tcReq); + break; + case 2: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpuRdReq); + break; + case 3: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpuWrReq); + break; + case 4: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, dspReq); + break; + case 5: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, ioReq); + break; + case 6: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, viReq); + break; + case 7: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, peReq); + break; + case 8: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, rfReq); + break; + case 9: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, fiReq); + break; + } + break; + case DEMO_STAT_GP0: + case DEMO_STAT_GP1: + case DEMO_STAT_MYC: + DEMOPrintf(text_x, text_y, 0, "%s: %8d", DemoStat[i].text, DemoStat[i].count); + break; + case DEMO_STAT_MYR: + rate = DemoStat[i].stat / (f32) DemoStat[i].count; + DEMOPrintf(text_x, text_y, 0, "%s: %8.3f", DemoStat[i].text, rate); + break; + default: + OSReport("Undefined stat type %d in DEMOPrintStats()\n", DemoStat[i].stat_type); + break; + } + text_y += text_yinc; + } + } +} diff --git a/src/dolphin/demo/DEMOWin.c b/src/dolphin/demo/DEMOWin.c new file mode 100644 index 0000000..108e376 --- /dev/null +++ b/src/dolphin/demo/DEMOWin.c @@ -0,0 +1,981 @@ +#include +#include +#include + + +static u32 __DEMOWIN_PAD_repeat_threshold = 0x0000000F; +static u32 __DEMOWIN_PAD_repeat_rate = 0x00000002; + +DEMOWindow* __first_node; +DEMOWindow* __last_node; +DEMOWindow* __curr_node; +GXRenderModeObj* __rmp; + +s32 fontShift = 0; + +// functions +static void __DEMOWin_add_node(DEMOWindow* handle); +static void __DEMOWin_delete_node(DEMOWindow* handle); +static void __DEMOWin_puts_n(s16 x, s16 y, s16 z, u16 n, char* string); +static void __DEMOWinMenu_refesh_menu(DEMOWindow* w); +static u16 __DEMOWinMenu_get_user_input(DEMOWinPadInfo* p); +static void __DEMOWinList_refresh_list(DEMOWindow* w); + +void DEMOWinInit() { + __first_node = NULL; + __last_node = NULL; + __curr_node = NULL; + __rmp = DEMOGetRenderModeObj(); + GXSetCopyClear((GXColor){0, 0, 0, 0}, 0xFFFFFF); +} + +DEMOWindow* DEMOWinCreateWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, u16 scroll, void* func) { + DEMOWindow* handle; + ASSERTMSGLINE(188, x1 < x2, "DEMOWIN: Illegal X coords for window\n"); + ASSERTMSGLINE(189, y1 < y2, "DEMOWIN: Illegal y coords for window\n"); + + handle = (void*)OSAlloc(sizeof(DEMOWindow)); + ASSERTMSGLINE(193, handle, "DEMOWIN: FAILED TO ALLOCATE WINDOW!\n"); + + handle->x1 = x1; + handle->y1 = y1; + handle->x2 = x2; + handle->y2 = y2; + handle->pixel_width = (x2 - x1) + 1; + handle->pixel_height = (y2 - y1) + 1; + handle->caption = caption; + handle->char_width = (handle->pixel_width / 8) - 1; + handle->char_height = (handle->pixel_height / 8) - 2; + handle->x_cal = (((handle->pixel_width - (handle->char_width * 8)) + 1) / 2); + handle->y_cal = (((handle->pixel_height - 7) - (handle->char_height * 8)) / 2); + handle->num_scroll_lines = scroll; + handle->total_lines = handle->char_height + handle->num_scroll_lines; + handle->curr_output_line = 0; + handle->curr_output_col = 0; + handle->curr_view_line = 0; + handle->refresh = func; + handle->flags = 0; + handle->priority = 0; + + handle->buffer = (void*)OSAlloc(handle->total_lines * handle->char_width); + ASSERTMSGLINE(249, handle->buffer, "DEMOWinCreateWindow(): Unable to allocation buffer!\n"); + memset(handle->buffer, ' ', handle->total_lines * handle->char_width); // set to all empty spaces + + DEMOWinSetWindowColor(handle, DEMOWIN_ITEM_DEFAULT, 0, 0, 0, 0); + handle->cursor_line = -1; + handle->parent = 0; + __DEMOWin_add_node(handle); + return handle; +} + +void DEMOWinDestroyWindow(DEMOWindow* handle) { + BOOL old; + ASSERTMSGLINE(287, handle, "DEMOWinDestroyWindow(): NULL handle!\n"); + old = OSDisableInterrupts(); + __DEMOWin_delete_node(handle); + OSFree(handle->buffer); + OSFree(handle); + OSRestoreInterrupts(old); +} + +void DEMOWinOpenWindow(DEMOWindow* handle) { + ASSERTMSGLINE(321, handle, "DEMOWinOpenWindow(): NULL handle!\n"); + handle->flags |= DEMOWIN_FLAGS_OPENED; +} + +void DEMOWinCloseWindow(DEMOWindow* handle) { + ASSERTMSGLINE(337, handle, "DEMOWinCloseWindow(): NULL handle!\n"); + handle->flags &= ~(DEMOWIN_FLAGS_OPENED); +} + +void DEMOWinSetWindowColor(DEMOWindow* handle, u32 item, u8 r, u8 g, u8 b, u8 a) { + ASSERTMSGLINE(355, handle, "DEMOWinSetWinColor(): NULL window handle\n"); + + switch(item) { + case DEMOWIN_ITEM_CAP: // set cap + handle->cap.r = r; + handle->cap.g = g; + handle->cap.b = b; + handle->cap.a = a; + return; + case DEMOWIN_ITEM_BORDER: // set border + handle->border.r = r; + handle->border.g = g; + handle->border.b = b; + handle->border.a = a; + return; + case DEMOWIN_ITEM_BKGND: // set background + handle->bkgnd.r = r; + handle->bkgnd.g = g; + handle->bkgnd.b = b; + handle->bkgnd.a = a; + return; + case DEMOWIN_ITEM_DEFAULT: // default window colors + // RGB 26, 31, 33; Cinder (grey) + handle->bkgnd.r = 26; + handle->bkgnd.g = 31; + handle->bkgnd.b = 33; + handle->bkgnd.a = 255; + // RGB 85, 31, 31; Burnt Crimson (red) + handle->cap.r = 85; + handle->cap.g = 31; + handle->cap.b = 31; + handle->cap.a = 255; + // RGB 69, 37, 37; Bulgarian Rose (red) + handle->border.r = 69; + handle->border.g = 37; + handle->border.b = 37; + handle->border.a = 255; + return; + default: + ASSERTMSGLINE(398, FALSE, "DEMOWinSetWinColor(): Unknown item\n"); + return; + } +} + +void DEMOWinLogPrintf(DEMOWindow* handle, char* fmt, ...) { + va_list vlist; + char buffer[128]; + u16 len; + u16 i; + BOOL old; + u16 index; + + va_start(vlist, fmt); + vsprintf(buffer, fmt, vlist); + + old = OSDisableInterrupts(); + len = strlen(buffer); + for (i = 0; i < len; i++) { + if(buffer[i] == 0xA) { + handle->curr_output_line = (handle->curr_output_line + 1) % handle->total_lines; + handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; + handle->curr_output_col = 0; + index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); + memset(&handle->buffer[index], ' ', handle->char_width); + } else { + index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); + handle->buffer[index] = buffer[i]; + handle->curr_output_col++; + } + + if (handle->curr_output_col >= handle->char_width) { + handle->curr_output_col = 0; + handle->curr_output_line = (handle->curr_output_line + 1) % handle->total_lines; + handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; + index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); + memset(&handle->buffer[index], ' ', handle->char_width); + } + } + + OSRestoreInterrupts(old); + va_end(vlist); +} + +void DEMOWinPrintfXY(DEMOWindow* handle, u16 col, u16 row, char* fmt, ...) { + BOOL old; + va_list vlist; + char string[128]; + u16 buffer_row; + u16 i; + u16 index; + + if (row >= handle->char_height || col >= handle->char_width) { + return; + } + + old = OSDisableInterrupts(); + va_start(vlist, fmt); + vsprintf(string, fmt, vlist); + buffer_row = ((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines; + buffer_row = (((buffer_row) + row) % handle->total_lines); + string[handle->char_width - col] = 0; + index = (col + buffer_row* handle->char_width); + + for (i = 0; i < strlen(string); i++) { + handle->buffer[index + i] = string[i]; + } + + OSRestoreInterrupts(old); +} + +void DEMOWinScrollWindow(DEMOWindow* handle, u32 dir) { + BOOL old; + u16 n; + u16 v_start; + + ASSERTMSGLINE(550, handle, "DEMOWinScrollWindow(): NULL handle!\n"); + ASSERTMSGLINE(551, handle->num_scroll_lines, "DEMOWinScrollWindow(): No scrollback buffer!\n"); + + switch(dir) { + case 1: + old = OSDisableInterrupts(); + n = (handle->curr_view_line + handle->total_lines - 1) % handle->total_lines; + v_start = ((n + handle->total_lines) - handle->char_height + 1) % handle->total_lines; + if (v_start != handle->curr_output_line) { + handle->curr_view_line = n; + } + OSRestoreInterrupts(old); + return; + case 2: + old = OSDisableInterrupts(); + if (handle->curr_view_line != handle->curr_output_line) { + handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; + } + OSRestoreInterrupts(old); + return; + case 0: + old = OSDisableInterrupts(); + handle->curr_view_line = handle->curr_output_line; + OSRestoreInterrupts(old); + return; + default: + ASSERTMSGLINE(586, FALSE, "DEMOWinScrollWindow(): Unknown token\n"); + return; + } +} + +void DEMOWinBringToFront(DEMOWindow* handle) { + DEMOWindow* ptr; + ASSERTMSGLINE(609, __first_node, "DEMOWinBringToFront(): Window list is empty!\n"); + ASSERTMSGLINE(610, handle, "DEMOWinBringToFront(): NULL handle!\n"); + + if (handle->priority) { + for(ptr = __first_node; ptr; ptr = ptr->next) { + ptr->priority = 1; + } + handle->priority = 0; + } +} + +void DEMOWinSendToBack(DEMOWindow* handle) { + ASSERTMSGLINE(645, handle, "DEMOWinSendToBack(): NULL handle!\n"); + handle->priority = 1; +} + +void DEMOWinClearRow(DEMOWindow* handle, u16 row) { + u16 buffer_row; + u16 index; + u16 i; + BOOL old; + + ASSERTMSGLINE(669, handle, "DEMOWinClearRow(): NULL handle!\n"); + + if (row < handle->char_height) { + old = OSDisableInterrupts(); + buffer_row = (((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines); + buffer_row = (((buffer_row + row) % handle->total_lines)); + index = (buffer_row* handle->char_width); + + for (i = 0; i < handle->char_width; i++) { + handle->buffer[index + i] = ' '; + } + + OSRestoreInterrupts(old); + } +} + +void DEMOWinClearWindow(DEMOWindow* handle) { + u16 buffer_row; + u16 index; + u16 i; + BOOL old; + + ASSERTMSGLINE(718, handle, "DEMOWinClearWindow(): NULL handle!\n"); + + old = OSDisableInterrupts(); + buffer_row = ((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines; + + for (i = 0; i < handle->char_height; i++) { + index = buffer_row* handle->char_width; + memset(&handle->buffer[index], ' ', handle->char_width); + buffer_row = (buffer_row + 1) % handle->total_lines; + } + + OSRestoreInterrupts(old); +} + +void DEMOWinClearBuffer(DEMOWindow* handle) { + BOOL old; + + ASSERTMSGLINE(752, handle, "DEMOWinClearBuffer(): NULL handle!\n"); + old = OSDisableInterrupts(); + memset(handle->buffer, ' ', handle->total_lines* handle->char_width); + OSRestoreInterrupts(old); +} + +void DEMOWinRefresh(void) { + DEMOWindow* ptr; + u16 i; + u16 index; + u16 n; + u16 y; + BOOL old; + + ASSERTMSGLINE(792, __first_node, "DEMOWinRefresh(): Windowlist is empty!\n"); + + for (ptr = __first_node; ptr; ptr = ptr->next) { + if (ptr->flags & DEMOWIN_FLAGS_OPENED) { + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetLineWidth(6, GX_TO_ZERO); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); + GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); + GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); + GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); + GXPosition3f32(ptr->x2, ptr->y2, ptr->priority); + GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); + GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); + GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); + GXEnd(); + + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); + GXColor4u8(ptr->cap.r, ptr->cap.g, ptr->cap.b, 255); + GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); + GXColor4u8(0, 0, 0, 0x40); + GXPosition3f32(ptr->x2, ptr->y1 + 10, ptr->priority); + GXColor4u8(0, 0, 0, 0x40); + GXPosition3f32(ptr->x1, ptr->y1 + 10, ptr->priority); + GXColor4u8(ptr->cap.r, ptr->cap.g, ptr->cap.b, 255); + GXEnd(); + + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + + // macro? + do { + // would initialize on init, but DWARF order for 2nd macro suggests they didnt init on same declare. + u8 r1; + u8 g1; + u8 b1; + u8 r2; + u8 g2; + u8 b2; + u8 a; + + r1 = 1.3 * (f32)ptr->border.r; + g1 = 1.3 * (f32)ptr->border.g; + b1 = 1.3 * (f32)ptr->border.b; + r2 = 0.4 * (f32)ptr->border.r; + g2 = 0.4 * (f32)ptr->border.g; + b2 = 0.4 * (f32)ptr->border.b; + a = 64; + + GXSetLineWidth(6, GX_TO_ZERO); + + GXBegin(GX_LINESTRIP, GX_VTXFMT0, 7); + GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); + GXColor4u8(r1, g1, b1, a); + GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); + GXColor4u8(r1, g1, b1, a); + GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); + GXColor4u8(r2, g2, b2, a); + GXPosition3f32(ptr->x2, ptr->y2, ptr->priority); + GXColor4u8(r2, g2, b2, a); + GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); + GXColor4u8(r2, g2, b2, a); + GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); + GXColor4u8(r1, g1, b1, a); + GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); + GXColor4u8(r1, g1, b1, a); + GXEnd(); + } while(0); + + if (ptr->refresh) { + ptr->refresh(ptr); + } + + DEMOInitCaption(DM_FT_XLU, __rmp->fbWidth, __rmp->efbHeight); + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + + old = OSDisableInterrupts(); + y = (ptr->y2 - 8) - ptr->y_cal; + n = ptr->curr_view_line; + index = n* ptr->char_width; + + for (i = 0; i < ptr->char_height; i++) { + __DEMOWin_puts_n(ptr->x1 + ptr->x_cal, y, ptr->priority, ptr->char_width, (void*)&ptr->buffer[index]); + y = y - 8; + n = (n + (ptr->total_lines) - 1) % ptr->total_lines; + index = n* ptr->char_width; + } + + DEMOPrintf(ptr->x1 + 2, ptr->y1, ptr->priority, "%s", ptr->caption); + + if (ptr->cursor_line >= 0) { + GXSetLineWidth(6, GX_TO_ZERO); + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetLineWidth(6, GX_TO_ZERO); + + // macro? + do { + u8 r; + u8 g; + u8 b; + u8 a; + s32 curr_y; + + curr_y = (ptr->y2 - 8) - ptr->y_cal; + curr_y -= ((ptr->char_height - 1) * 8) - ptr->cursor_line * 8; + r = 1.9 * (f32)ptr->bkgnd.r; + g = 1.9 * (f32)ptr->bkgnd.g; + b = 1.9 * (f32)ptr->bkgnd.b; + + a = 100; + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(ptr->x1, curr_y, ptr->priority); + GXColor4u8(r, g, b, a); + GXPosition3f32(ptr->x2, curr_y, ptr->priority); + GXColor4u8(r, g, b, a); + GXPosition3f32(ptr->x2, (f32)(curr_y + 8), ptr->priority); + GXColor4u8(r, g, b, a); + GXPosition3f32(ptr->x1, (f32)(curr_y + 8), ptr->priority); + GXColor4u8(r, g, b, a); + GXEnd(); + } while(0); + } + OSRestoreInterrupts(old); + } + } +} + +static void __DEMOWin_add_node(DEMOWindow* handle) { + ASSERTMSGLINE(1032, handle, "__add_node(): you're adding a NULL node!\n"); + + // WHY. why it backwards. who writes like this? + if (NULL == __last_node) { + __curr_node = handle; + __last_node = handle; + __first_node = handle; + handle->next = 0; + handle->prev = 0; + ASSERTMSGLINE(1042, __first_node, " > __first_node: NULL HANDLE!\n"); + } else { + __last_node->next = handle; + handle->next = 0; + handle->prev = __last_node; + __last_node = handle; + } + + handle->flags |= DEMOWIN_FLAGS_INIT; +} + +static void __DEMOWin_delete_node(DEMOWindow* handle) { + ASSERTMSGLINE(1071, handle, "__delete_node(): you're deleting a NULL node!\n"); + + if (__first_node == handle) { + if (handle->next) { + __first_node = handle->next; + handle->next->prev = NULL; + } else { + __first_node = __last_node = NULL; + } + } else if (__last_node == handle) { + if (handle->prev) { + __last_node = handle->prev; + handle->prev->next = NULL; + } else { + __first_node = __last_node = NULL; + } + } else { + handle->prev->next = handle->next; + handle->next->prev = handle->prev; + } + + handle->flags &= ~(DEMOWIN_FLAGS_INIT); +} + +static void __DEMOWin_puts_n(s16 x, s16 y, s16 z, u16 n, char* string) { + s32 s; + s32 t; + s32 w; + s32 len; + s32 i; + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 1); + + len = n; + if (len > 0) { + GXBegin(GX_QUADS, GX_VTXFMT0, len * 4); + for (i = 0; i < len; i++) { + w = string[i] - 0x20; + s = fontShift + (((w) % 8) * 16); + t = fontShift + (((w) / 8) * 16); + GXPosition3s16(x + (i * 8), y, z); + GXTexCoord2s16(s, t); + GXPosition3s16(x + (i * 8) + 8, y, z); + GXTexCoord2s16(s + 16, t); + GXPosition3s16(x + (i * 8) + 8, y + 8, z); + GXTexCoord2s16(s + 16, t + 16); + GXPosition3s16(x + (i * 8), y + 8, z); + GXTexCoord2s16(s, t + 16); + } + GXEnd(); + } +} + +DEMOWinMenu* DEMOWinCreateMenuWindow(DEMOWinMenu* menu, u16 x, u16 y) { + DEMOWinMenuItem* ptr; + + ptr = menu->items; + menu->max_str_len = strlen(menu->title); + menu->num_items = 0; + + while(!(ptr->flags & 0x80000000)) { + if (strlen(ptr->name) > menu->max_str_len) { + menu->max_str_len = strlen(ptr->name); + } + menu->num_items++; + ptr++; + } + + if (menu->num_items > menu->max_display_items) { + menu->num_display_items = menu->max_display_items; + } else { + menu->num_display_items = menu->num_items; + } + + menu->handle = DEMOWinCreateWindow((s16)x, (s16)y, (s16)(((menu->max_str_len + 7) * 8) + 4 + x), (s16)(((menu->num_display_items + 2) * 8) + 4 + y), menu->title, 0, __DEMOWinMenu_refesh_menu); + menu->handle->parent = menu; + if (menu->num_items) { + return menu; + } + + return NULL; +} + +void DEMOWinDestroyMenuWindow(DEMOWinMenu* menu) { + if (menu->handle) { + DEMOWinCloseWindow(menu->handle); + DEMOWinDestroyWindow(menu->handle); + menu->handle = NULL; + } +} + +u32 DEMOWinMenuChild(DEMOWinMenu* menu, int child_flag) { + DEMOWinPadInfo* pad; + DEMOWindow* handle; + u16 user_input; + int exit_flag; + u32 result; + + exit_flag = 0; + result = 0; + handle = menu->handle; + pad = &menu->handle->pad; + + DEMOWinOpenWindow(handle); + DEMOWinBringToFront(handle); + menu->curr_pos = 0; + menu->display_pos = 0; + + if(menu->cb_open) { + menu->cb_open(menu, menu->curr_pos); + } + + DEMOWinPadInit(pad); + DEMOBeforeRender(); + DEMOWinRefresh(); + DEMODoneRender(); + DEMOWinPadRead(pad); + DEMOBeforeRender(); + DEMOWinRefresh(); + DEMODoneRender(); + + while (!exit_flag) { + user_input = __DEMOWinMenu_get_user_input(pad); + switch(user_input) { + case 1: + menu->curr_pos = ((menu->curr_pos - 1 + menu->num_items) % menu->num_items) & 0xFFFF; + while (menu->items[menu->curr_pos].flags & 9) { + menu->curr_pos = ((menu->curr_pos - 1 + menu->num_items) % menu->num_items) & 0xFFFF; + } + if (menu->cb_move) { + menu->cb_move(menu, menu->curr_pos); + } + break; + case 2: + menu->curr_pos = ((menu->curr_pos + 1) % menu->num_items) & 0xFFFF; + while (menu->items[menu->curr_pos].flags & 9) { + menu->curr_pos = ((menu->curr_pos + 1) % menu->num_items) & 0xFFFF; + } + if (menu->cb_move) { + menu->cb_move(menu, menu->curr_pos); + } + break; + case 3: + if (child_flag == 1) { + exit_flag = 1; + if (menu->cb_cancel) { + menu->cb_cancel(menu, menu->curr_pos); + } + } + break; + case 4: + if (menu->cb_move) { + menu->cb_move(menu, menu->curr_pos); + } + if (menu->items[menu->curr_pos].link) { + if (menu->items[menu->curr_pos].link->handle) { + menu->items[menu->curr_pos].link->handle->x1 = (handle->x1 + 20) & 0xFFFF; + menu->items[menu->curr_pos].link->handle->y1 = (handle->y1 + 20) & 0xFFFF; + result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); + if (menu->items[menu->curr_pos].link->flags & 1) { + exit_flag = 1; + } + } else { + DEMOWinCreateMenuWindow(menu->items[menu->curr_pos].link, (handle->x1 + 20), (handle->y1 + 20)); + result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); + if (menu->items[menu->curr_pos].link->flags & 1) { + exit_flag = 1; + } + DEMOWinDestroyMenuWindow(menu->items[menu->curr_pos].link); + } + VIWaitForRetrace(); + DEMOWinPadRead(pad); + } + break; + case 5: + if (menu->cb_select) { + menu->cb_select(menu, menu->curr_pos); + } + if (menu->items[menu->curr_pos].link) { + if (menu->items[menu->curr_pos].link->handle) { + menu->items[menu->curr_pos].link->handle->x1 = (handle->x1 + 20) & 0xFFFF; + menu->items[menu->curr_pos].link->handle->y1 = (handle->y1 + 20) & 0xFFFF; + result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); + if (menu->items[menu->curr_pos].link->flags & 1) { + exit_flag = 1; + } + } else { + DEMOWinCreateMenuWindow(menu->items[menu->curr_pos].link, (handle->x1 + 20), (handle->y1 + 20)); + result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); + if (menu->items[menu->curr_pos].link->flags & 1) { + exit_flag = 1; + } + DEMOWinDestroyMenuWindow(menu->items[menu->curr_pos].link); + } + VIWaitForRetrace(); + DEMOWinPadRead(pad); + } else if (menu->items[menu->curr_pos].function) { + menu->items[menu->curr_pos].function(menu, menu->curr_pos, &result); + if (menu->items[menu->curr_pos].flags & 0x10) { + exit_flag = 1; + } + VIWaitForRetrace(); + DEMOWinPadRead(pad); + } + break; + case 6: + if (menu->cb_cancel) { + menu->cb_cancel(menu, menu->curr_pos); + } + exit_flag = 1; + break; + } + + if (menu->curr_pos > (menu->display_pos + menu->num_display_items - 1)) { + menu->display_pos = (menu->curr_pos - menu->num_display_items) + 1; + } else if (menu->curr_pos < menu->display_pos) { + menu->display_pos = menu->curr_pos; + } + + if (menu->display_pos > menu->curr_pos) { + handle->cursor_line = (menu->display_pos - menu->curr_pos); + } else { + handle->cursor_line = (menu->curr_pos - menu->display_pos); + } + + DEMOBeforeRender(); + DEMOWinRefresh(); + DEMODoneRender(); + } + + DEMOWinCloseWindow(handle); + DEMOBeforeRender(); + DEMOWinRefresh(); + DEMODoneRender(); + return result; +} + +static void __DEMOWinMenu_refesh_menu(DEMOWindow* w) { + DEMOWinMenu* m; + s32 i; + s32 j; + char check; + char para_start; + char para_end; + char link; + + DEMOWinClearWindow(w); + m = w->parent; + j = m->display_pos; + + for (i = 0; i < m->num_display_items; j++, i++) { + if (m->items[j].flags & 8) { + if (strlen(m->items[j & 0xFFFF].name)) { + DEMOWinPrintfXY(w, 0, i, " %s ", m->items[j & 0xFFFF].name); + } + } else { + check = (s8)((m->items[j].flags & 4) ? 'X' : ' '); + para_start = (s8)((m->items[j].flags & 1) ? '(' : ' '); + para_end = (s8)((m->items[j].flags & 1) ? ')' : ' '); + link = (s8)((NULL != m->items[j].link) ? '>' : ' '); + DEMOWinPrintfXY(w, 0, i, "%c %c%s%c %c", check, para_start, m->items[j & 0xFFFF].name, para_end, link); + } + } +} + +void DEMOWinPadInit(DEMOWinPadInfo* p) { + u16 i; + + for (i = 0; i < 4; i++) { + p->old_button[i] = 0; + p->changed_button[i] = 0; + p->repeat_button[i] = 0; + p->repeat_ctr[i] = 0; + } +} + +void DEMOWinPadRead(DEMOWinPadInfo* p) { + PADStatus* pad; + u16 index; + u32 curr; + u32 old; + u32 repeat; + + PADRead(p->pads); + + for (index = 0; index < 4; index++) { + old = p->old_button[index]; + pad = &p->pads[index]; + + curr = ((pad->stickX > 0x40 ? 0x00040000 : 0) + | (pad->stickX < -0x40 ? 0x00080000 : 0) + | (pad->stickY > 0x40 ? 0x00010000 : 0) + | (pad->stickY < -0x40 ? 0x00020000 : 0) + | (pad->substickX > +0x40 ? 0x00400000 : 0) + | (pad->substickX < -0x40 ? 0x00800000 : 0) + | (pad->substickY > +0x40 ? 0x00100000 : 0) + | (pad->substickY < -0x40 ? 0x00200000 : 0) + | (pad->triggerLeft > +0x80 ? 0x02000000 : 0) + | (pad->triggerRight > +0x80 ? 0x01000000 : 0) + | pad->button); + + p->changed_button[index] = (curr & (old ^ curr)); + if (curr) { + if (old == curr) { + p->repeat_ctr[index]++; + } else { + p->repeat_ctr[index] = 1; + } + } else { + p->repeat_ctr[index] = 0; + } + + repeat = p->repeat_ctr[index]; + + if (repeat == 1) { + p->repeat_button[index] = curr; + } else if (repeat > __DEMOWIN_PAD_repeat_threshold) { + if (((repeat - __DEMOWIN_PAD_repeat_threshold) % __DEMOWIN_PAD_repeat_rate) == 0) { + p->repeat_button[index] = curr; + } else { + p->repeat_button[index] = 0; + } + } else { + p->repeat_button[index] = 0; + } + + p->old_button[index] = curr; + } +} + +static u16 __DEMOWinMenu_get_user_input(DEMOWinPadInfo* p) { + u16 user_input; + + DEMOWinPadRead(p); + if (p->repeat_button[0] & 0x00010008) { + user_input = 1; + } else if (p->repeat_button[0] & 0x00020004) { + user_input = 2; + } else if (p->repeat_button[0] & 0x00080001) { + user_input = 3; + } else if (p->repeat_button[0] & 0x00040002) { + user_input = 4; + } else if (p->changed_button[0] & 0x00000100) { + user_input = 5; + } else if (p->changed_button[0] & 0x00000200) { + user_input = 6; + } else { + user_input = 0; + } + + return user_input; +} + +void DEMOWinSetRepeat(u32 threshold, u32 rate) { + __DEMOWIN_PAD_repeat_rate = rate; + __DEMOWIN_PAD_repeat_threshold = threshold; +} + +void DEMOWinResetRepeat(void) { + __DEMOWIN_PAD_repeat_threshold = 15; + __DEMOWIN_PAD_repeat_rate = 2; +} + +DEMOWinListbox* DEMOWinCreateListWindow(DEMOWinListbox* list, u16 x, u16 y) { + DEMOWinListboxItem* ptr; + ASSERTMSGLINE(1846, list, "DEMOWinCreateListWindow(): List is NULL!\n"); + + ptr = list->items; + list->max_str_len = strlen(list->title); + list->num_items = 0; + + while (!(ptr->flags & 0x80000000)) { + if (strlen(ptr->name) > list->max_str_len) { + list->max_str_len = strlen(ptr->name); + } + list->num_items++; + ptr++; + } + + if (list->num_items > list->max_display_items) { + list->num_display_items = list->max_display_items; + } else { + list->num_display_items = list->num_items; + } + + list->handle = DEMOWinCreateWindow((s16)x, (s16)y, (s16)((list->max_str_len + 7) * 8 + 4 + x), (s16)((list->num_display_items + 2) * 8 + 4 + y), list->title, 0, __DEMOWinList_refresh_list); + list->handle->parent = list; + if (list->num_items) { + return list; + } + return NULL; +} + +void DEMOWinDestroyListWindow(DEMOWinListbox* list) { + if (list->handle) { + DEMOWinCloseWindow(list->handle); + DEMOWinDestroyWindow(list->handle); + list->handle = NULL; + } +} + +static void __DEMOWinList_refresh_list(DEMOWindow* w) { + DEMOWinListbox* l; + s32 i; + s32 j; + + l = w->parent; + l->curr_pos = (l->curr_pos % l->num_items); + if (l->curr_pos > (l->display_pos + l->num_display_items - 1)) { + l->display_pos = (l->curr_pos - l->num_display_items + 1); + } else if(l->curr_pos < l->display_pos) { + l->display_pos = l->curr_pos; + } + + if (l->cursor_state != 0) { + if(l->display_pos > l->curr_pos) { + w->cursor_line = (l->display_pos - l->curr_pos); + } else { + w->cursor_line = (l->curr_pos - l->display_pos); + } + } else { + w->cursor_line = -1; + } + + DEMOWinClearWindow(w); + + j = l->display_pos; + for (i = 0; i < l->num_display_items; i++) { + if (!(l->items[j].flags & 0x8)) { + DEMOWinPrintfXY(w, 0, i, " %s ", l->items[j & 0xFFFF].name); + } + j++; + } +} + +void DEMOWinListSetCursor(DEMOWinListbox* list, int x) { + list->cursor_state = x; +} + +s32 DEMOWinListScrollList(DEMOWinListbox* list, u32 dir) { + ASSERTMSGLINE(2032, list, "DEMOWinListScrollList(): NULL handle!\n"); + + switch(dir) { + case 1: + if (list->display_pos) { + list->display_pos = (u16)((list->display_pos - 1 + list->num_items) % list->num_items); + } + break; + case 2: + if (list->display_pos < (list->num_items - list->num_display_items)) { + list->display_pos = (u16)((list->display_pos + 1) % list->num_items); + } + break; + case 0: + list->display_pos = 0; + break; + default: + ASSERTMSGLINE(2057, FALSE, "DEMOWinListScrollList(): Invalid dimension!\n"); + break; + } + + if (list->curr_pos > (list->display_pos + list->num_display_items - 1)) { + list->curr_pos = (list->display_pos + list->num_display_items - 1); + } else if (list->curr_pos < list->display_pos) { + list->curr_pos = list->display_pos; + } + + return list->display_pos; +} + +s32 DEMOWinListMoveCursor(DEMOWinListbox* list, u32 dir) { + ASSERTMSGLINE(2092, list, "DEMOWinListScrollList(): NULL handle!\n"); + + switch (dir) { + case 1: + list->curr_pos = (list->curr_pos + list->num_items - 1) % list->num_items; + break; + case 2: + list->curr_pos = (list->curr_pos + 1) % list->num_items; + break; + default: + ASSERTMSGLINE(2105, FALSE, "DEMOWinListMoveCursor(): Invalid dimension!\n"); + break; + } + + return list->curr_pos; +} diff --git a/src/dolphin/demo/__demo.h b/src/dolphin/demo/__demo.h new file mode 100644 index 0000000..47f0826 --- /dev/null +++ b/src/dolphin/demo/__demo.h @@ -0,0 +1,11 @@ +#ifndef _DOLPHIN_DEMO_INTERNAL_H_ +#define _DOLPHIN_DEMO_INTERNAL_H_ + +#include + +extern struct STRUCT_DEMOWIN * __first_node; +extern struct STRUCT_DEMOWIN * __last_node; +extern struct STRUCT_DEMOWIN * __curr_node; +extern struct _GXRenderModeObj * __rmp; + +#endif // _DOLPHIN_DEMO_INTERNAL_H_ diff --git a/src/dolphin/dsp/__dsp.h b/src/dolphin/dsp/__dsp.h new file mode 100644 index 0000000..a739806 --- /dev/null +++ b/src/dolphin/dsp/__dsp.h @@ -0,0 +1,27 @@ +#ifndef _DOLPHIN_DSP_INTERNAL_H_ +#define _DOLPHIN_DSP_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern DSPTaskInfo* __DSP_first_task; +extern DSPTaskInfo* __DSP_last_task; +extern DSPTaskInfo* __DSP_curr_task; +extern DSPTaskInfo* __DSP_tmp_task; + +void __DSPHandler(__OSInterrupt, OSContext*); +void __DSP_exec_task(DSPTaskInfo*, DSPTaskInfo*); +void __DSP_boot_task(DSPTaskInfo*); +void __DSP_insert_task(DSPTaskInfo*); +void __DSP_add_task(DSPTaskInfo* task); +void __DSP_remove_task(DSPTaskInfo* task); +void __DSP_debug_printf(const char* fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/dsp/dsp.c b/src/dolphin/dsp/dsp.c new file mode 100644 index 0000000..d5570b1 --- /dev/null +++ b/src/dolphin/dsp/dsp.c @@ -0,0 +1,185 @@ +#include +#include +#include + +#include "__dsp.h" + +#define BUILD_DATE "Apr 5 2004" +#if DEBUG +#define BUILD_TIME "03:56:49" +#else +#define BUILD_TIME "04:15:32" +#endif + +#ifdef DEBUG +const char* __DSPVersion = "<< Dolphin SDK - DSP\tdebug build: Apr 5 2004 03:56:49 (0x2301) >>"; +#else +const char* __DSPVersion = "<< Dolphin SDK - DSP\trelease build: Apr 5 2004 04:15:32 (0x2301) >>"; +#endif + +extern DSPTaskInfo* __DSP_rude_task; +extern int __DSP_rude_task_pending; + +static BOOL __DSP_init_flag; + + +u32 DSPCheckMailToDSP(void) { + return (__DSPRegs[0] & (1 << 15)) >> 15; +} + +u32 DSPCheckMailFromDSP(void) { + return (__DSPRegs[2] & (1 << 15)) >> 15; +} + +u32 DSPReadCPUToDSPMbox(void) { + return (__DSPRegs[0] << 16) | __DSPRegs[1]; +} + +u32 DSPReadMailFromDSP(void) { + return (__DSPRegs[2] << 16) | __DSPRegs[3]; +} + +void DSPSendMailToDSP(u32 mail) { + __DSPRegs[0] = mail >> 16; + __DSPRegs[1] = mail & 0xFFFF; +} + +void DSPAssertInt(void) { + BOOL old; + u16 tmp; + + old = OSDisableInterrupts(); + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA8) | 2; + __DSPRegs[5] = tmp; + OSRestoreInterrupts(old); +} + +void DSPInit(void) { + BOOL old; + u16 tmp; + + __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", BUILD_DATE, BUILD_TIME); + + if (__DSP_init_flag == 1) + return; + + OSRegisterVersion(__DSPVersion); + + old = OSDisableInterrupts(); + __OSSetInterruptHandler(7, __DSPHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_DSP); + + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA8) | 0x800; + __DSPRegs[5] = tmp; + + tmp = __DSPRegs[5]; + __DSPRegs[5] = tmp = tmp & ~0xAC; + + __DSP_first_task = __DSP_last_task = __DSP_curr_task = __DSP_tmp_task = NULL; + __DSP_init_flag = 1; + + OSRestoreInterrupts(old); +} + +BOOL DSPCheckInit(void) { + return __DSP_init_flag; +} + +void DSPReset(void) { + BOOL old; + u16 tmp; + + old = OSDisableInterrupts(); + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA8) | 0x800 | 1; + __DSPRegs[5] = tmp; + __DSP_init_flag = 0; + OSRestoreInterrupts(old); +} + +void DSPHalt(void) { + BOOL old; + u16 tmp; + + old = OSDisableInterrupts(); + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA8) | 4; + __DSPRegs[5] = tmp; + OSRestoreInterrupts(old); +} + +void DSPUnhalt(void) { + BOOL old; + u16 tmp; + + old = OSDisableInterrupts(); + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xAC); + __DSPRegs[5] = tmp; + OSRestoreInterrupts(old); +} + +u32 DSPGetDMAStatus(void) { + return (__DSPRegs[5] & (1 << 9)); +} + +DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) { + BOOL old; + + ASSERTMSGLINE(556, __DSP_init_flag == 1, "DSPAddTask(): DSP driver not initialized!\n"); + + old = OSDisableInterrupts(); + + __DSP_insert_task(task); + task->state = 0; + task->flags = 1; + + OSRestoreInterrupts(old); + if (task == __DSP_first_task) + __DSP_boot_task(task); + return task; +} + +DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task) { + BOOL old; + + ASSERTMSGLINE(592, __DSP_init_flag == 1, "DSPCancelTask(): DSP driver not initialized!\n"); + + old = OSDisableInterrupts(); + + task->flags |= 2; + + OSRestoreInterrupts(old); + return task; +} + +DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task) { + s32 old; + + ASSERTMSGLINE(623, __DSP_init_flag == 1, "DSPAssertTask(): DSP driver not initialized!\n"); + ASSERTMSGLINE(624, task->flags & 1, "DSPAssertTask(): Specified task not in active task list!\n"); + + old = OSDisableInterrupts(); + + if (__DSP_curr_task == task) { + __DSP_rude_task = task; + __DSP_rude_task_pending = 1; + OSRestoreInterrupts(old); + return task; + } + + if (task->priority < __DSP_curr_task->priority) { + __DSP_rude_task = task; + __DSP_rude_task_pending = 1; + if (__DSP_curr_task->state == 1) { + DSPAssertInt(); + } + OSRestoreInterrupts(old); + return task; + } + + OSRestoreInterrupts(old); + return NULL; +} diff --git a/src/dolphin/dsp/dsp_debug.c b/src/dolphin/dsp/dsp_debug.c new file mode 100644 index 0000000..3cb3fb0 --- /dev/null +++ b/src/dolphin/dsp/dsp_debug.c @@ -0,0 +1,9 @@ +#include + +#include "__dsp.h" + +void __DSP_debug_printf(const char* fmt, ...) {} + +DSPTaskInfo* __DSPGetCurrentTask(void) { + return __DSP_curr_task; +} diff --git a/src/dolphin/dsp/dsp_perf.c b/src/dolphin/dsp/dsp_perf.c new file mode 100644 index 0000000..e69de29 diff --git a/src/dolphin/dsp/dsp_task.c b/src/dolphin/dsp/dsp_task.c new file mode 100644 index 0000000..be844c3 --- /dev/null +++ b/src/dolphin/dsp/dsp_task.c @@ -0,0 +1,362 @@ +#include + +#include +#include + +#include "__dsp.h" + +static u32 t0, t1, t2; // unused + +DSPTaskInfo* __DSP_curr_task; +DSPTaskInfo* __DSP_first_task; +DSPTaskInfo* __DSP_last_task; +DSPTaskInfo* __DSP_tmp_task; +DSPTaskInfo* __DSP_rude_task; +int __DSP_rude_task_pending; + +void __DSPHandler(__OSInterrupt intr, OSContext* context) { + u8 unused[4]; + OSContext exceptionContext; + u16 tmp; + u32 mail; + + tmp = __DSPRegs[5]; + tmp = (tmp & ~0x28) | 0x80; + __DSPRegs[5] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + ASSERTMSGLINE(143, __DSP_curr_task != NULL, "__DSPHandler(): No current task! Someone set us up the bomb!\n"); + + while (DSPCheckMailFromDSP() == 0) + ; + + mail = DSPReadMailFromDSP(); + if ((__DSP_curr_task->flags & (1<<(31-0x1E))) && (mail + 0x232F0000) == 2) + mail = 0xDCD10003; + + switch (mail) { + case 0xDCD10000: + __DSP_curr_task->state = 1; + if (__DSP_curr_task->init_cb != NULL) + __DSP_curr_task->init_cb(__DSP_curr_task); + break; + case 0xDCD10001: + __DSP_curr_task->state = 1; + if (__DSP_curr_task->res_cb != NULL) + __DSP_curr_task->res_cb(__DSP_curr_task); + break; + case 0xDCD10002: + if (__DSP_rude_task_pending) { + if (__DSP_curr_task == __DSP_rude_task) { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_rude_task = NULL; + __DSP_rude_task_pending = 0; + + if (__DSP_curr_task->res_cb != NULL) + __DSP_curr_task->res_cb(__DSP_curr_task); + } else { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_rude_task); + __DSP_curr_task->state = 2; + __DSP_curr_task = __DSP_rude_task; + __DSP_rude_task = NULL; + __DSP_rude_task_pending = 0; + } + } else { + if (__DSP_curr_task->next == NULL) { + if (__DSP_curr_task == __DSP_first_task) { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP() != 0) + ; + if (__DSP_curr_task->res_cb != NULL) + __DSP_curr_task->res_cb(__DSP_curr_task); + } else { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_first_task); + __DSP_curr_task->state = 2; + __DSP_curr_task = __DSP_first_task; + } + } else { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next); + __DSP_curr_task->state = 2; + __DSP_curr_task = __DSP_curr_task->next; + } + } + break; + case 0xDCD10003: + if (__DSP_rude_task_pending) { + if (__DSP_curr_task->done_cb != NULL) + __DSP_curr_task->done_cb(__DSP_curr_task); + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_exec_task(NULL, __DSP_rude_task); + __DSP_remove_task(__DSP_curr_task); + __DSP_curr_task = __DSP_rude_task; + __DSP_rude_task = NULL; + __DSP_rude_task_pending = 0; + } else { + if (__DSP_curr_task->next == NULL) { + if (__DSP_curr_task == __DSP_first_task) { + if (__DSP_curr_task->done_cb != NULL) + __DSP_curr_task->done_cb(__DSP_curr_task); + + DSPSendMailToDSP(0xCDD10002); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_curr_task->state = 3; + __DSP_remove_task(__DSP_curr_task); + } else { + if (__DSP_curr_task->done_cb != NULL) + __DSP_curr_task->done_cb(__DSP_curr_task); + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_curr_task->state = 3; + __DSP_exec_task(NULL, __DSP_first_task); + __DSP_curr_task = __DSP_first_task; + __DSP_remove_task(__DSP_last_task); + } + } else { + if (__DSP_curr_task->done_cb != NULL) + __DSP_curr_task->done_cb(__DSP_curr_task); + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_curr_task->state = 3; + __DSP_exec_task(NULL, __DSP_curr_task->next); + __DSP_curr_task = __DSP_curr_task->next; + __DSP_remove_task(__DSP_curr_task->prev); + } + } + break; + case 0xDCD10004: + if (__DSP_curr_task->req_cb != NULL) + __DSP_curr_task->req_cb(__DSP_curr_task); + break; + default: + ASSERTMSGLINEV(519, 0, "__DSPHandler(): Unknown msg from DSP 0x%08X - task sync failed!\n", mail); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next) { + ASSERTMSGLINE(552, next != NULL, "__DSP_exec_task(): NULL task. It is to weep.\n"); + + if (curr != NULL) { + DSPSendMailToDSP((u32)curr->dram_mmem_addr); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(curr->dram_length); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(curr->dram_addr); + while (DSPCheckMailToDSP() != 0) + ; + } else { + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + } + + DSPSendMailToDSP((u32)next->iram_mmem_addr); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(next->iram_length); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(next->iram_addr); + while (DSPCheckMailToDSP() != 0) + ; + + if (next->state == 0) { + DSPSendMailToDSP(next->dsp_init_vector); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + } else { + DSPSendMailToDSP(next->dsp_resume_vector); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP((u32)next->dram_mmem_addr); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(next->dram_length); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(next->dram_addr); + while (DSPCheckMailToDSP() != 0) + ; + } +} + +void __DSP_boot_task(DSPTaskInfo* task) { + volatile u32 mail; + + ASSERTMSGLINE(634, task != NULL, "__DSP_boot_task(): NULL task!\n"); + while (DSPCheckMailFromDSP() == 0) + ; + + mail = DSPReadMailFromDSP(); + ASSERTMSGLINEV(640, mail == 0x8071FEED, "__DSP_boot_task(): Failed to sync DSP on boot! (0x%08X)\n", mail); + + DSPSendMailToDSP(0x80F3A001); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP((u32)task->iram_mmem_addr); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0x80F3C002); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(task->iram_addr & 0xFFFF); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0x80F3A002); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(task->iram_length); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0x80F3B002); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0x80F3D001); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(task->dsp_init_vector); + while (DSPCheckMailToDSP() != 0) + ; + + __DSP_debug_printf("DSP is booting task: 0x%08X\n", (u32)task); + __DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", (u32)task->iram_mmem_addr); + __DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", task->iram_addr); + __DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", task->iram_length); + __DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", task->dram_length); + __DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", task->dsp_init_vector); +} + +void __DSP_insert_task(DSPTaskInfo* task) { + DSPTaskInfo* temp; + + if (__DSP_first_task == NULL) { + __DSP_curr_task = task; + __DSP_first_task = __DSP_last_task = task; + task->next = task->prev = NULL; + return; + } + + temp = __DSP_first_task; + while (temp != NULL) { + if (task->priority < temp->priority) { + task->prev = temp->prev; + temp->prev = task; + task->next = temp; + if (task->prev == NULL) + __DSP_first_task = task; + else + task->prev->next = task; + break; + } + temp = temp->next; + } + + if (temp == NULL) { + __DSP_last_task->next = task; + task->next = NULL; + task->prev = __DSP_last_task; + __DSP_last_task = task; + } +} + +void __DSP_add_task(DSPTaskInfo* task) { + ASSERTMSGLINE(771, task != NULL, "__DSP_add_task(): Why are you adding a NULL task?\n"); + + if (__DSP_last_task == NULL) { + __DSP_curr_task = task; + __DSP_last_task = task; + __DSP_first_task = task; + task->next = task->prev = NULL; + } else { + __DSP_last_task->next = task; + task->next = NULL; + task->prev = __DSP_last_task; + __DSP_last_task = task; + } + + task->state = 0; + __DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", (u32)task); +} + +void __DSP_remove_task(DSPTaskInfo* task) { + ASSERTMSGLINE(813, task != NULL, "__DSP_remove_task(): NULL task! Why? WHY?!?!\n"); + task->flags = 0; + task->state = 3; + + if (__DSP_first_task == task) { + if (task->next != NULL) { + __DSP_first_task = task->next; + task->next->prev = NULL; + } + else + __DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL; + return; + } + + if (__DSP_last_task == task) { + __DSP_last_task = task->prev; + task->prev->next = NULL; + __DSP_curr_task = __DSP_first_task; + return; + } + + __DSP_curr_task = task->next; + task->prev->next = task->next; + task->next->prev = task->prev; +} diff --git a/src/dolphin/dtk/dtk.c b/src/dolphin/dtk/dtk.c new file mode 100644 index 0000000..c1bfd05 --- /dev/null +++ b/src/dolphin/dtk/dtk.c @@ -0,0 +1,483 @@ +#include +#include +#include +#include + +static DTKTrack* __DTKCurrentTrack; +static DTKTrack* __DTKPlayListHead; +static DTKTrack* __DTKPlayListTail; +static volatile u32 __DTKState; +static volatile u32 __DTKTempState; +static volatile u32 __DTKRepeatMode; +static volatile u32 __DTKPosition; +static volatile u32 __DTKInterruptFrequency; +static volatile u8 __DTKVolumeL; +static volatile u8 __DTKVolumeR; +static volatile u32 __DTKShutdownFlag; +static volatile u32 __DTKTrackEnded; +static DTKFlushCallback __DTKFlushCallback; +static int __busy_for_ais_address; + +static DVDCommandBlock __block_for_run_callback; +static DVDCommandBlock __block_for_prep_callback; +static DVDCommandBlock __block_for_stream_status; +static DVDCommandBlock __block_for_ais_isr; +static DVDCommandBlock __block_for_flushtracks; +static DVDCommandBlock __block_for_repeatmode; +static DVDCommandBlock __block_for_set_state; +static DVDCommandBlock __block_for_next_track; +static DVDCommandBlock __block_for_prev_track; + +static void __DTKStartAi(void) { + AISetStreamVolLeft(__DTKVolumeL); + AISetStreamVolRight(__DTKVolumeR); + AIResetStreamSampleCount(); + AISetStreamTrigger(__DTKInterruptFrequency); + AISetStreamPlayState(1); +} + +static void __DTKStopAi(void) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + AISetStreamPlayState(0); +} + +static void __DTKCheckUserCallback(DTKTrack* track, u32 event) { + ASSERTLINE(84, track); + if (track && track->callback && (track->eventMask & event)) { + track->callback(track->eventMask & event); + } +} + +static void __DTKForward(void) { + BOOL old = OSDisableInterrupts(); + if (__DTKCurrentTrack && __DTKCurrentTrack->next) { + __DTKCurrentTrack = __DTKCurrentTrack->next; + } + OSRestoreInterrupts(old); +} + +static void __DTKBackward(void) { + BOOL old = OSDisableInterrupts(); + if (__DTKCurrentTrack && __DTKCurrentTrack->prev) { + __DTKCurrentTrack = __DTKCurrentTrack->prev; + } + OSRestoreInterrupts(old); +} + +static void __DTKCallbackForStreamStatus(s32 result, DVDCommandBlock* block) { + if ((result & 0xFF) == 0) { + __DTKTrackEnded = 1; + __DTKPosition = 0; + } +} + +static void __DTKCallbackForRun(s32 result, DVDFileInfo* fileInfo) { + __DTKStartAi(); + DVDStopStreamAtEndAsync(&__block_for_run_callback, 0); + __DTKState = DTK_STATE_RUN; + __DTKCheckUserCallback(__DTKCurrentTrack, 1); +} + +static void __DTKCallbackForPreparePaused(s32 result, DVDFileInfo* fileInfo) { + __DTKStopAi(); + DVDStopStreamAtEndAsync(&__block_for_prep_callback, 0); + __DTKState = DTK_STATE_PAUSE; + __DTKCheckUserCallback(__DTKCurrentTrack, 32); +} + +static void __DTKPrepareCurrentTrack(void) { + DVDPrepareStreamAsync(&__DTKCurrentTrack->dvdFileInfo, 0, 0, __DTKCallbackForRun); +} + +static void __DTKPrepareCurrentTrackPaused(void) { + DVDPrepareStreamAsync(&__DTKCurrentTrack->dvdFileInfo, 0, 0, __DTKCallbackForPreparePaused); +} + +static void __DTKCallbackForPlaylist(s32 result, DVDCommandBlock* block) { + __DTKPosition = result; + __busy_for_ais_address = 0; + + if (__DTKTrackEnded) { + __DTKTrackEnded = 0; + __DTKCheckUserCallback(__DTKCurrentTrack, 16); + __DTKState = DTK_STATE_BUSY; + + switch (__DTKRepeatMode) { + case DTK_MODE_NOREPEAT: + if (__DTKCurrentTrack) { + if (__DTKCurrentTrack->next) { + __DTKCurrentTrack = __DTKCurrentTrack->next; + __DTKStopAi(); + __DTKPrepareCurrentTrack(); + } else { + __DTKCurrentTrack = __DTKPlayListHead; + __DTKStopAi(); + __DTKState = DTK_STATE_STOP; + } + } + break; + case DTK_MODE_ALLREPEAT: + if (__DTKCurrentTrack) { + if (__DTKCurrentTrack->next) { + __DTKCurrentTrack = __DTKCurrentTrack->next; + __DTKStopAi(); + __DTKPrepareCurrentTrack(); + } else { + __DTKCurrentTrack = __DTKPlayListHead; + __DTKStopAi(); + __DTKPrepareCurrentTrack(); + } + } + break; + case DTK_MODE_REPEAT1: + if (__DTKCurrentTrack) { + __DTKStopAi(); + __DTKPrepareCurrentTrack(); + } + break; + } + } else { + DVDGetStreamErrorStatusAsync(&__block_for_stream_status, __DTKCallbackForStreamStatus); + } +} + +static void __DTKCallbackForAIInterrupt(u32 count) { + AISetStreamTrigger(count + __DTKInterruptFrequency); + if (__DTKCurrentTrack && !__busy_for_ais_address) { + __busy_for_ais_address = 1; + DVDGetStreamPlayAddrAsync(&__block_for_ais_isr, __DTKCallbackForPlaylist); + } +} + +static void __DTKCallbackForFlush(s32 result, DVDCommandBlock* block) { + DTKTrack* track; + + AISetStreamPlayState(0); + track = __DTKPlayListHead; + while (track) { + DVDClose(&track->dvdFileInfo); + track = track->next; + } + + __DTKPlayListHead = NULL; + __DTKPlayListTail = NULL; + __DTKCurrentTrack = NULL; + __DTKState = DTK_STATE_STOP; + + if (__DTKFlushCallback) { + __DTKFlushCallback(); + __DTKFlushCallback = NULL; + } + + __DTKState = DTK_STATE_STOP; + __DTKShutdownFlag = 0; +} + +static void __DTKCallbackForStop(s32 result, DVDCommandBlock* block) { + __DTKCheckUserCallback(__DTKCurrentTrack, 2); + __DTKState = DTK_STATE_STOP; +} + +static void __DTKCallbackForNextTrack(s32 result, DVDCommandBlock* block) { + AISetStreamPlayState(0); + __DTKForward(); + __DTKState = DTK_STATE_STOP; + DTKSetState(__DTKTempState); +} + +static void __DTKCallbackForPrevTrack(s32 result, DVDCommandBlock* block) { + AISetStreamPlayState(0); + __DTKBackward(); + __DTKState = DTK_STATE_STOP; + DTKSetState(__DTKTempState); +} + +void DTKInit(void) { + __DTKCurrentTrack = NULL; + __DTKPlayListHead = NULL; + __DTKPlayListTail = NULL; + __DTKState = DTK_STATE_STOP; + __DTKRepeatMode = DTK_MODE_NOREPEAT; + __DTKPosition = 0; + __DTKInterruptFrequency = 48000; + __DTKVolumeL = 255; + __DTKVolumeR = 255; + + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + AIRegisterStreamCallback(__DTKCallbackForAIInterrupt); + AIResetStreamSampleCount(); + AISetStreamPlayState(0); +} + +void DTKShutdown(void) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + AIRegisterStreamCallback(NULL); + AIResetStreamSampleCount(); + AISetStreamPlayState(0); + + __DTKShutdownFlag = 1; + DTKFlushTracks(NULL); + __DTKState = DTK_STATE_STOP; + + while (__DTKShutdownFlag) {} +} + +u32 DTKQueueTrack(char* fileName, DTKTrack* track, u32 eventMask, DTKCallback callback) { + u32 startTrack; + BOOL old; + + startTrack = 0; + if (!DVDOpen(fileName, &track->dvdFileInfo)) { + return 1; + } + + old = OSDisableInterrupts(); + track->fileName = fileName; + track->eventMask = eventMask; + track->callback = callback; + + if (__DTKPlayListHead == NULL) { + __DTKPlayListHead = track; + __DTKPlayListTail = track; + track->prev = NULL; + track->next = NULL; + if (__DTKState == DTK_STATE_RUN) { + startTrack = 1; + } + } else { + __DTKPlayListTail->next = track; + track->prev = __DTKPlayListTail; + __DTKPlayListTail = track; + track->next = NULL; + } + + if (__DTKCurrentTrack == NULL) { + __DTKCurrentTrack = track; + } + + OSRestoreInterrupts(old); + __DTKCheckUserCallback(track, 8); + + if (startTrack != 0) { + __DTKState = DTK_STATE_BUSY; + __DTKPrepareCurrentTrack(); + } + + return 0; +} + +u32 DTKRemoveTrack(DTKTrack* track) { + BOOL old; + + if (track == __DTKCurrentTrack) { + return 2; + } + + old = OSDisableInterrupts(); + DVDClose(&track->dvdFileInfo); + + if (track == __DTKPlayListHead && track == __DTKPlayListTail) { + __DTKPlayListHead = NULL; + __DTKPlayListTail = NULL; + OSRestoreInterrupts(old); + return 0; + } + + if (track == __DTKPlayListHead) { + __DTKPlayListHead = track->next; + __DTKPlayListHead->prev = NULL; + if (__DTKRepeatMode == DTK_MODE_ALLREPEAT) { + __DTKPlayListTail->next = __DTKPlayListHead; + } + OSRestoreInterrupts(old); + return 0; + } + + if (track == __DTKPlayListTail) { + __DTKPlayListTail = track->prev; + __DTKPlayListTail->next = NULL; + if (__DTKRepeatMode == DTK_MODE_ALLREPEAT) { + __DTKPlayListTail->next = __DTKPlayListHead; + } + OSRestoreInterrupts(old); + return 0; + } + + track->prev->next = track->next; + track->next->prev = track->prev; + OSRestoreInterrupts(old); + return 0; +} + +int DTKFlushTracks(DTKFlushCallback callback) { + u32 temp; + + if (__DTKState == DTK_STATE_BUSY) { + return 0; + } + + temp = __DTKState; + __DTKState = DTK_STATE_BUSY; + __DTKFlushCallback = callback; + if (temp == DTK_STATE_RUN) { + DVDCancelStreamAsync(&__block_for_flushtracks, __DTKCallbackForFlush); + } else { + __DTKCallbackForFlush(0, 0); + } + return 1; +} + +void DTKSetSampleRate(u32 samplerate) { + // obsolete +} + +void DTKSetInterruptFrequency(u32 samples) { + __DTKInterruptFrequency = samples; + AIResetStreamSampleCount(); + AISetStreamTrigger(__DTKInterruptFrequency); +} + +void DTKSetRepeatMode(u32 repeat) { + __DTKRepeatMode = repeat; +} + +int DTKSetState(u32 state) { + if (__DTKState == state) { + return 1; + } + + if (__DTKState == DTK_STATE_BUSY) { + return 0; + } + + switch (state) { + case DTK_STATE_STOP: + if (__DTKCurrentTrack) { + __DTKState = DTK_STATE_BUSY; + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + AISetStreamPlayState(0); + DVDCancelStreamAsync(&__block_for_set_state, __DTKCallbackForStop); + } + break; + case DTK_STATE_RUN: + if (__DTKState == DTK_STATE_PAUSE) { + __DTKStartAi(); + __DTKState = DTK_STATE_RUN; + if (__DTKCurrentTrack) { + __DTKCheckUserCallback(__DTKCurrentTrack, 1); + } + } else if (__DTKCurrentTrack) { + __DTKState = DTK_STATE_BUSY; + __DTKPrepareCurrentTrack(); + } else { + __DTKState = DTK_STATE_RUN; + } + __DTKTrackEnded = 0; + break; + case DTK_STATE_PREPARE: + if (__DTKState == DTK_STATE_STOP) { + if (__DTKCurrentTrack) { + __DTKState = DTK_STATE_BUSY; + __DTKPrepareCurrentTrackPaused(); + } + __DTKTrackEnded = 0; + } + break; + case DTK_STATE_PAUSE: + AISetStreamPlayState(0); + if (__DTKState == DTK_STATE_RUN) { + __DTKState = DTK_STATE_PAUSE; + } + __DTKCheckUserCallback(__DTKCurrentTrack, 4); + break; + } + + return 1; +} + +int DTKNextTrack(void) { + if (__DTKState == DTK_STATE_BUSY) { + return 0; + } + + if (__DTKCurrentTrack) { + __DTKTempState = __DTKState; + __DTKState = DTK_STATE_BUSY; + if (__DTKTempState == DTK_STATE_RUN) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&__block_for_next_track, __DTKCallbackForNextTrack); + } else { + __DTKForward(); + __DTKState = __DTKTempState; + } + + return 1; + } + + return 0; +} + +int DTKPrevTrack(void) { + if (__DTKState == DTK_STATE_BUSY) { + return 0; + } + + if (__DTKCurrentTrack) { + __DTKTempState = __DTKState; + __DTKState = DTK_STATE_BUSY; + if (__DTKTempState == DTK_STATE_RUN) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&__block_for_prev_track, __DTKCallbackForPrevTrack); + } else { + __DTKBackward(); + __DTKState = __DTKTempState; + } + + return 1; + } + + return 0; +} + +u32 DTKGetSampleRate(void) { + return 1; // obsolete +} + +u32 DTKGetRepeatMode(void) { + return __DTKRepeatMode; +} + +u32 DTKGetState(void) { + return __DTKState; +} + +u32 DTKGetPosition(void) { + return __DTKPosition; +} + +u32 DTKGetInterruptFrequency(void) { + return __DTKInterruptFrequency; +} + +DTKTrack* DTKGetCurrentTrack(void) { + return __DTKCurrentTrack; +} + +void DTKSetVolume(u8 left, u8 right) { + __DTKVolumeL = left; + __DTKVolumeR = right; + if (__DTKState == DTK_STATE_RUN) { + AISetStreamVolLeft(left); + AISetStreamVolRight(right); + } +} + +u16 DTKGetVolume(void) { + return (__DTKVolumeL << 8) | __DTKVolumeR; +} diff --git a/src/dolphin/dvd/__dvd.h b/src/dolphin/dvd/__dvd.h new file mode 100644 index 0000000..197c13e --- /dev/null +++ b/src/dolphin/dvd/__dvd.h @@ -0,0 +1,53 @@ +#ifndef _DOLPHIN_DVD_INTERNAL_H_ +#define _DOLPHIN_DVD_INTERNAL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// DVD +DVDCommandChecker __DVDSetOptionalCommandChecker(DVDCommandChecker func); +void __DVDSetImmCommand(u32 command); +void __DVDSetDmaCommand(u32 command); +void* __DVDGetIssueCommandAddr(void); +void __DVDAudioBufferConfig(DVDCommandBlock* block, u32 enable, u32 size, DVDCBCallback callback); +void __DVDPrepareResetAsync(DVDCBCallback callback); +int __DVDTestAlarm(const OSAlarm* alarm); + +// DVD ERROR +void __DVDStoreErrorCode(u32 error); + +// DVD FATAL +void __DVDPrintFatalMessage(void); + +// DVD FS +extern OSThreadQueue __DVDThreadQueue; +extern u32 __DVDLongFileNameFlag; + +void __DVDFSInit(void); + +// DVD LOW +void __DVDInitWA(void); +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context); +void __DVDLowSetWAType(u32 type, s32 seekLoc); +int __DVDLowTestAlarm(const OSAlarm* alarm); + +// DVD QUEUE +void __DVDClearWaitingQueue(void); +int __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block); +DVDCommandBlock* __DVDPopWaitingQueue(void); +int __DVDCheckWaitingQueue(void); +int __DVDDequeueWaitingQueue(DVDCommandBlock* block); +int __DVDIsBlockInWaitingQueue(DVDCommandBlock* block); + +// FST LOAD +void __fstLoad(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DVD_INTERNAL_H_ diff --git a/src/dolphin/dvd/dvd.c b/src/dolphin/dvd/dvd.c new file mode 100644 index 0000000..3b7e970 --- /dev/null +++ b/src/dolphin/dvd/dvd.c @@ -0,0 +1,1854 @@ +#include +#include +#include + +#include "os/__os.h" +#include "__dvd.h" + +// externs +extern void __DVDPrintFatalMessage(); +extern int DVDCompareDiskID(const struct DVDDiskID * id1 /* r29 */, const struct DVDDiskID * id2 /* r30 */); +extern int __DVDLowTestAlarm(const OSAlarm * alarm /* r3 */); + +#ifdef DEBUG +const char* __DVDVersion = "<< Dolphin SDK - DVD\tdebug build: Apr 5 2004 03:56:07 (0x2301) >>"; +#else +const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Apr 5 2004 04:14:51 (0x2301) >>"; +#endif + +static BOOL autoInvalidation = TRUE; + +static void defaultOptionalCommandChecker(DVDCommandBlock*, DVDCommandCheckerCallback); +static DVDCommandChecker checkOptionalCommand = defaultOptionalCommandChecker; + +static DVDBB2 BB2; +static DVDDiskID CurrDiskID; +static DVDCommandBlock DummyCommandBlock; +static OSAlarm ResetAlarm; + +static DVDCommandBlock* executing; +static DVDDiskID* IDShouldBe; +static OSBootInfo* bootInfo; +static volatile int PauseFlag; +static volatile int PausingFlag; +static int AutoFinishing; +static BOOL FatalErrorFlag; +static volatile u32 CurrCommand; +static volatile u32 Canceling; +static void (*CancelCallback)(s32, DVDCommandBlock*); +static volatile u32 ResumeFromHere; +static volatile u32 CancelLastError; +static u32 LastError; +static volatile s32 NumInternalRetry; +static int ResetRequired; +static int CancelAllSyncComplete; +static volatile u32 ResetCount; +static BOOL FirstTimeInBootrom; +static u32 MotorState; +static int DVDInitialized; +void (*LastState)(DVDCommandBlock*); + +// prototypes +static void stateReadingFST(); +static void cbForStateReadingFST(u32 intType); +static void cbForStateError(u32 intType); +static void stateError(u32 error); +static void stateTimeout(); +static void stateGettingError(); +static u32 CategorizeError(u32 error); +static BOOL CheckCancel(u32 resume); +static void cbForStateGettingError(u32 intType); +static void cbForUnrecoveredError(u32 intType); +static void cbForUnrecoveredErrorRetry(u32 intType); +static void stateGoToRetry(); +static void cbForStateGoToRetry(u32 intType); +static void stateCheckID(); +static void stateCheckID3(); +static void stateCheckID2a(); +static void stateCheckID2(); +static void cbForStateCheckID1(u32 intType); +static void cbForStateCheckID2(u32 intType); +static void cbForStateCheckID3(u32 intType); +static void cbForStateCheckID2a(u32 intType); +static void AlarmHandler(OSAlarm* alarm, OSContext* context); +static void stateCoverClosed(); +static void stateCoverClosed_CMD(DVDCommandBlock* command); +static void cbForStateCoverClosed(u32 intType); +static void stateMotorStopped(); +static void cbForStateMotorStopped(u32 intType); +static void stateReady(); +static void stateBusy(DVDCommandBlock* block); +static BOOL IsImmCommandWithResult(u32 command); +static int IsDmaCommand(u32 command); +static void cbForStateBusy(u32 intType); +static int issueCommand(s32 prio, DVDCommandBlock* block); +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block); +static void cbForStopStreamAtEndSync(s32 result, DVDCommandBlock* block); +static void cbForGetStreamErrorStatusSync(s32 result, DVDCommandBlock* block); +static void cbForGetStreamPlayAddrSync(s32 result, DVDCommandBlock* block); +static void cbForGetStreamStartAddrSync(s32 result, DVDCommandBlock* block); +static void cbForGetStreamLengthSync(s32 result, DVDCommandBlock* block); +static void cbForChangeDiskSync(s32 result, DVDCommandBlock* block); +static void cbForStopMotorSync(s32 result, DVDCommandBlock* block); +static void cbForInquirySync(s32 result, DVDCommandBlock* block); +static void cbForCancelSync(s32 result, DVDCommandBlock* block); +static void cbForCancelAllSync(s32 result, DVDCommandBlock* block); + +static void defaultOptionalCommandChecker(DVDCommandBlock*, DVDCommandCheckerCallback) {} + +DVDCommandChecker __DVDSetOptionalCommandChecker(DVDCommandChecker func) { + DVDCommandChecker old = checkOptionalCommand; + checkOptionalCommand = func; + return checkOptionalCommand; +} + +void DVDInit(void) { + if (!DVDInitialized) { + OSRegisterVersion(__DVDVersion); + DVDInitialized = TRUE; + + __DVDFSInit(); + __DVDClearWaitingQueue(); + __DVDInitWA(); + + MotorState = 0; + bootInfo = (void*)OSPhysicalToCached(0); + IDShouldBe = &bootInfo->DVDDiskID; + + __OSSetInterruptHandler(0x15, __DVDInterruptHandler); + __OSUnmaskInterrupts(0x400); + OSInitThreadQueue(&__DVDThreadQueue); + __DIRegs[0] = 0x2A; + __DIRegs[1] = 0; + + if (bootInfo->magic == 0xE5207C22) { + OSReport("load fst\n"); + __fstLoad(); + } else if (bootInfo->magic == 0x0D15EA5E) { + + } else { + FirstTimeInBootrom = TRUE; + } + } +} + +static void stateReadingFST() { + LastState = stateReadingFST; + ASSERTLINE(652, ((u32)(bootInfo->FSTLocation) & (32 - 1)) == 0); + DVD_ASSERTMSGLINE(661, bootInfo->FSTMaxLength >= BB2.FSTLength, "DVDChangeDisk(): FST in the new disc is too big. "); + DVDLowRead(bootInfo->FSTLocation, (u32)(BB2.FSTLength + 0x1F) & 0xFFFFFFE0, BB2.FSTPosition, cbForStateReadingFST); +} + +static u32 DmaCommand[1] = {0xFFFFFFFF}; + +static void cbForStateReadingFST(u32 intType) { + DVDCommandBlock* finished; + + if (intType == 16) { + stateTimeout(); + return; + } + + ASSERTLINE(680, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(685, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + + __DVDFSInit(); + finished = executing; + executing = &DummyCommandBlock; + finished->state = DVD_STATE_END; + + if (finished->callback) { + finished->callback(0, finished); + } + + stateReady(); + return; + } + + ASSERTLINE(712, intType == DVD_INTTYPE_DE); + stateGettingError(); +} + +static void cbForStateError(u32 intType) { + DVDCommandBlock* finished; + executing->state = -1; + + if (intType == 16) { + stateTimeout(); + return; + } + + __DVDPrintFatalMessage(); + + FatalErrorFlag = TRUE; + finished = executing; + executing = &DummyCommandBlock; + + if (finished->callback) { + (finished->callback)(-1, finished); + } + + if (Canceling) { + Canceling = FALSE; + if (CancelCallback) + (CancelCallback)(0, finished); + } + + stateReady(); +} + +static void stateError(u32 error) { + __DVDStoreErrorCode(error); + DVDLowStopMotor(&cbForStateError); +} + +static void stateTimeout() { + __DVDStoreErrorCode(0x01234568); + DVDReset(); + cbForStateError(0); +} + +static void stateGettingError() { + DVDLowRequestError(cbForStateGettingError); +} + +static u32 CategorizeError(u32 error) { + if (error == 0x20400) { + LastError = error; + return 1; + } + + error &= 0x00FFFFFF; + if (error == 0x62800 || error == 0x23A00 || error == 0xB5A01) { + return 0; + } + + NumInternalRetry++; + if (NumInternalRetry == 2) { + if (error == LastError) { + LastError = error; + return 1; + } + LastError = error; + return 2; + } + + LastError = error; + + if (error == 0x31100 || executing->command == DVD_COMMAND_READID) { + return 2; + } + + return 3; +} + +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) { + stateTimeout(); + return; + } + + if (intType & 2) { + stateError(0x1234567); + return; + } + + ASSERTLINE(956, intType == DVD_INTTYPE_TC); + + error = __DIRegs[8]; + status = error & 0xff000000; + + errorCategory = CategorizeError(error); + + if (errorCategory == 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 { + stateError(0x1234567); + return; + } +} + +static void cbForUnrecoveredError(u32 intType) { + if (intType == 16) { + stateTimeout(); + return; + } + + if (intType & 1) { + stateGoToRetry(); + return; + } + + ASSERTLINE(1055, intType == DVD_INTTYPE_DE); + DVDLowRequestError(cbForUnrecoveredErrorRetry); +} + +static void cbForUnrecoveredErrorRetry(u32 intType) { + if (intType == 0x10) { + stateTimeout(); + } else { + if (intType & 2) { + stateError(0x01234567); + return; + } + + stateError(__DIRegs[8]); + } +} + +static void stateGoToRetry() { + DVDLowStopMotor(cbForStateGoToRetry); +} + +static void cbForStateGoToRetry(u32 intType) { + if (intType == 16) { + stateTimeout(); + return; + } + + if (intType & 2) { + stateError(0x1234567); + return; + } + + ASSERTLINE(1104, intType == DVD_INTTYPE_TC); + 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 DVD_COMMAND_CHANGE_DISK: + if (DVDCompareDiskID(&CurrDiskID, executing->id)) { + memcpy(IDShouldBe, &CurrDiskID, sizeof(DVDDiskID)); + executing->state = DVD_STATE_BUSY; + DCInvalidateRange(&BB2.bootFilePosition, 0x20); + LastState = stateCheckID2a; + stateCheckID2a(executing); + } else { + DVDLowStopMotor(cbForStateCheckID1); + } + break; + default: + if (memcmp(&CurrDiskID, IDShouldBe, sizeof(DVDDiskID)) != 0) { + DVDLowStopMotor(cbForStateCheckID1); + } else { + LastState = stateCheckID3; + stateCheckID3(executing); + } + break; + } +} + +static void stateCheckID3() { + DVDLowAudioBufferConfig(IDShouldBe->streaming, 0xA, cbForStateCheckID3); +} + +static void stateCheckID2a() { + DVDLowAudioBufferConfig(IDShouldBe->streaming, 0xA, cbForStateCheckID2a); +} + +static void cbForStateCheckID2a(u32 intType) { + if (intType == 16) { + stateTimeout(); + return; + } + + ASSERTLINE(1227, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(1232, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + stateCheckID2(executing); + return; + } + + ASSERTLINE(1243, intType == DVD_INTTYPE_DE); + stateGettingError(); +} + +static void stateCheckID2() { + DVDLowRead(&BB2, 0x20, 0x420, cbForStateCheckID2); +} + +static void cbForStateCheckID1(u32 intType) { + if (intType == 16) { + stateTimeout(); + return; + } + + if (intType & DVD_INTTYPE_DE) { + stateError(0x01234567); + return; + } + + ASSERTLINE(1279, intType == DVD_INTTYPE_TC); + NumInternalRetry = 0; + + if (CheckCancel(1) == FALSE) { + executing->state = DVD_STATE_WRONG_DISK; + stateMotorStopped(); + } +} + +static void cbForStateCheckID2(u32 intType) { + if (intType == 16) { + stateTimeout(); + return; + } + + ASSERTLINE(1300, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(1305, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + stateReadingFST(); + return; + } + + ASSERTLINE(1321, intType == DVD_INTTYPE_DE); + stateGettingError(); +} + +static void cbForStateCheckID3(u32 intType) { + if (intType == 16) { + stateTimeout(); + return; + } + + ASSERTLINE(1336, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(1341, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + if (CheckCancel(0) == FALSE) { + executing->state = DVD_STATE_BUSY; + stateBusy(executing); + } + return; + } + + ASSERTLINE(1355, intType == DVD_INTTYPE_DE); + 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 DVD_COMMAND_BSREAD: + case DVD_COMMAND_READID: + case DVD_COMMAND_AUDIO_BUFFER_CONFIG: + case DVD_COMMAND_BS_CHANGE_DISK: + __DVDClearWaitingQueue(); + finished = executing; + executing = &DummyCommandBlock; + if (finished->callback) { + finished->callback(-4, finished); + } + stateReady(); + break; + default: + MotorState = 0; + DVDReset(); + OSCreateAlarm(&ResetAlarm); + OSSetAlarm(&ResetAlarm, OSMillisecondsToTicks(1150), &AlarmHandler); + break; + } +} + +static void stateCoverClosed_CMD(DVDCommandBlock* command) { + DVDLowReadDiskID(&CurrDiskID, cbForStateCoverClosed); +} + +static void cbForStateCoverClosed(u32 intType) { + if (intType == 16) { + stateTimeout(); + return; + } + + ASSERTLINE(1437, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(1442, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + stateCheckID(); + return; + } + + ASSERTLINE(1454, intType == DVD_INTTYPE_DE); + stateGettingError(); +} + +static void stateMotorStopped() { + DVDLowWaitCoverClose(cbForStateMotorStopped); +} + +static void cbForStateMotorStopped(u32 intType) { + ASSERTLINE(1483, intType == DVD_INTTYPE_CVR); + __DIRegs[1] = 0; + executing->state = DVD_STATE_COVER_CLOSED; + stateCoverClosed(); +} + +static void stateReady() { + if (__DVDCheckWaitingQueue() == 0) { + executing = NULL; + return; + } + + if (PauseFlag != 0) { + PausingFlag = 1; + executing = NULL; + return; + } + + executing = __DVDPopWaitingQueue(); + + if (FatalErrorFlag) { + DVDCommandBlock* finished; + + executing->state = DVD_STATE_FATAL_ERROR; + finished = executing; + executing = &DummyCommandBlock; + if (finished->callback) { + (*finished->callback)(-1, finished); + } + + stateReady(); + return; + } + + CurrCommand = executing->command; + if (ResumeFromHere != 0) { + switch (ResumeFromHere) { + case 2: + executing->state = DVD_STATE_RETRY; + stateMotorStopped(); + break; + case 3: + executing->state = DVD_STATE_NO_DISK; + stateMotorStopped(); + break; + case 4: + executing->state = DVD_STATE_COVER_OPEN; + stateMotorStopped(); + break; + case 1: + case 6: + case 7: + executing->state = DVD_STATE_COVER_CLOSED; + stateCoverClosed(); + break; + case 5: + stateError(CancelLastError); + break; + } + + ResumeFromHere = 0; + return; + } + + if (MotorState == 0) { + executing->state = DVD_STATE_BUSY; + stateBusy(executing); + } else { + stateCoverClosed(); + } +} + +static void stateBusy(DVDCommandBlock* block) { + DVDCommandBlock* finished; + LastState = stateBusy; + + switch(block->command) { + case DVD_COMMAND_READID: + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = 0x20; + DVDLowReadDiskID(block->addr, cbForStateBusy); + return; + case DVD_COMMAND_READ: + case DVD_COMMAND_BSREAD: + if (block->length == 0) { + finished = executing; + executing = &DummyCommandBlock; + finished->state = 0; + + if (finished->callback != 0) { + (*finished->callback)(0, finished); + } + + stateReady(); + } else { + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = (block->length - block->transferredSize > 0x80000) ? 0x80000 : (block->length - block->transferredSize); + DVDLowRead((char*)block->addr + block->transferredSize, block->currTransferSize, block->offset + block->transferredSize, cbForStateBusy); + } + return; + case DVD_COMMAND_SEEK: + __DIRegs[1] = __DIRegs[1]; + DVDLowSeek(block->offset, cbForStateBusy); + return; + case DVD_COMMAND_CHANGE_DISK: + DVDLowStopMotor(cbForStateBusy); + return; + case DVD_COMMAND_BS_CHANGE_DISK: + DVDLowStopMotor(cbForStateBusy); + return; + case DVD_COMMAND_INITSTREAM: + __DIRegs[1] = __DIRegs[1]; + if (AutoFinishing != 0) { + executing->currTransferSize = 0; + DVDLowRequestAudioStatus(0, cbForStateBusy); + return; + } + executing->currTransferSize = 1; + DVDLowAudioStream(0, block->length, block->offset, cbForStateBusy); + return; + case DVD_COMMAND_CANCELSTREAM: + __DIRegs[1] = __DIRegs[1]; + DVDLowAudioStream(0x10000, 0U, 0U, cbForStateBusy); + return; + case DVD_COMMAND_STOP_STREAM_AT_END: + __DIRegs[1] = __DIRegs[1]; + AutoFinishing = 1; + DVDLowAudioStream(0, 0U, 0U, cbForStateBusy); + return; + case DVD_COMMAND_REQUEST_AUDIO_ERROR: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0, cbForStateBusy); + return; + case DVD_COMMAND_REQUEST_PLAY_ADDR: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x10000, cbForStateBusy); + return; + case DVD_COMMAND_REQUEST_START_ADDR: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x20000, cbForStateBusy); + return; + case DVD_COMMAND_REQUEST_LENGTH: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x30000, cbForStateBusy); + return; + case DVD_COMMAND_AUDIO_BUFFER_CONFIG: + __DIRegs[1] = __DIRegs[1]; + DVDLowAudioBufferConfig(block->offset, block->length, cbForStateBusy); + return; + case DVD_COMMAND_INQUIRY: + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = 0x20; + DVDLowInquiry(block->addr, cbForStateBusy); + return; + case DVD_COMMAND_UNK_16: + __DIRegs[1] = __DIRegs[1]; + DVDLowStopMotor(cbForStateBusy); + return; + default: + checkOptionalCommand(block, cbForStateBusy); + return; + } +} + +static u32 ImmCommand[3] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + +void __DVDSetImmCommand(u32 command) { + static u32 immCount; + ASSERTLINE(1790, immCount < sizeof(ImmCommand)/sizeof(ImmCommand[0])); + ImmCommand[immCount++] = command; +} + +void __DVDSetDmaCommand(u32 command) { + static u32 dmaCount; + ASSERTLINE(1798, dmaCount < sizeof(DmaCommand)/sizeof(DmaCommand[0])); + DmaCommand[dmaCount++] = command; +} + +static BOOL IsImmCommandWithResult(u32 command) { + u32 i; + + if (command == 9 || command == 10 || command == 11 || command == 12) { + return 1; + } + + for (i = 0; i < 3; i++) { + if (command == ImmCommand[i]) { + return TRUE; + } + } + + return FALSE; +} + +static int IsDmaCommand(u32 command) { + u32 i; + + if (command == 1 || command == 4 || command == 5 || command == 14) { + return 1; + } + + for (i = 0; i < 1; i++) { + if (command == DmaCommand[i]) { + return TRUE; + } + } + + return FALSE; +} + +static void cbForStateBusy(u32 intType) { + DVDCommandBlock* finished; + s32 result; + + if (intType == 16) { + stateTimeout(); + return; + } + + if ((CurrCommand == DVD_COMMAND_CHANGE_DISK) || (CurrCommand == DVD_COMMAND_BS_CHANGE_DISK)) { + if (intType & DVD_INTTYPE_DE) { + stateError(0x01234567); + return; + } + + ASSERTLINE(1857, intType == DVD_INTTYPE_TC); + NumInternalRetry = 0; + + if (CurrCommand == DVD_COMMAND_BS_CHANGE_DISK) { + ResetRequired = 1; + } + + if (CheckCancel(7) == FALSE) { + executing->state = DVD_STATE_MOTOR_STOPPED; + stateMotorStopped(); + } + return; + } + + ASSERTLINE(1877, (intType & DVD_INTTYPE_CVR) == 0); + + if (IsDmaCommand(CurrCommand)) { + executing->transferredSize += executing->currTransferSize - __DIRegs[6]; + } + + if (intType & 8) { + Canceling = 0; + finished = executing; + executing = &DummyCommandBlock; + finished->state = DVD_STATE_CANCELED; + + if (finished->callback) { + finished->callback(-3, finished); + } + + if (CancelCallback) { + CancelCallback(0, finished); + } + + stateReady(); + return; + } + + if (intType & 1) { + ASSERTLINE(1915, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + + if (CurrCommand == 0x10) { + MotorState = 1; + finished = executing; + executing = &DummyCommandBlock; + finished->state = 0; + + if (finished->callback != 0) { + (*finished->callback)(0, finished); + } + + stateReady(); + return; + } + + if (CheckCancel(0) != FALSE) { + return; + } + + if (IsDmaCommand(CurrCommand)) { + if (executing->transferredSize != executing->length) { + stateBusy(executing); + return; + } + + finished = executing; + executing = &DummyCommandBlock; + finished->state = DVD_STATE_END; + if (finished->callback) { + finished->callback(finished->transferredSize, finished); + } + + stateReady(); + return; + } else if (IsImmCommandWithResult(CurrCommand)) { + if (CurrCommand == DVD_COMMAND_REQUEST_START_ADDR || CurrCommand == DVD_COMMAND_REQUEST_PLAY_ADDR) { + result = __DIRegs[8] * 4; + } else { + result = __DIRegs[8]; + } + + finished = executing; + executing = &DummyCommandBlock; + finished->state = DVD_STATE_END; + if (finished->callback) { + finished->callback(result, finished); + } + + stateReady(); + return; + } else if (CurrCommand == DVD_COMMAND_INITSTREAM) { + if (executing->currTransferSize == 0) { + if (__DIRegs[8] & 1) { + finished = executing; + executing = &DummyCommandBlock; + finished->state = DVD_STATE_IGNORED; + if (finished->callback) { + finished->callback(-2, finished); + } + stateReady(); + return; + } + + AutoFinishing = 0; + executing->currTransferSize = 1; + DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy); + return; + } + + finished = executing; + executing = &DummyCommandBlock; + finished->state = DVD_STATE_END; + if (finished->callback) { + finished->callback(0, finished); + } + + stateReady(); + return; + } else { + finished = executing; + executing = &DummyCommandBlock; + finished->state = DVD_STATE_END; + if (finished->callback) { + finished->callback(0, finished); + } + + stateReady(); + return; + } + } else { + ASSERTLINE(2063, intType == DVD_INTTYPE_DE); + + if (CurrCommand == 14) { + 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 = DVD_STATE_END; + if (finished->callback) { + (finished->callback)((s32)finished->transferredSize, finished); + } + stateReady(); + return; + } + + stateGettingError(); + } +} + +void* __DVDGetIssueCommandAddr(void) { + return issueCommand; +} + +static int issueCommand(s32 prio, DVDCommandBlock* block) { + BOOL level; + int result; + + if (autoInvalidation != 0 && (block->command == DVD_COMMAND_READ || block->command == DVD_COMMAND_BSREAD + || block->command == DVD_COMMAND_READID || block->command == DVD_COMMAND_INQUIRY)) { + DCInvalidateRange(block->addr, block->length); + } + + level = OSDisableInterrupts(); +#if DEBUG + if (executing == block || block->state == DVD_STATE_WAITING && __DVDIsBlockInWaitingQueue(block)) { + ASSERTMSGLINE(2151, FALSE, "DVD library: Specified command block (or file info) is already in use\n"); + } +#endif + + block->state = DVD_STATE_WAITING; + result = __DVDPushWaitingQueue(prio, block); + if (executing == NULL && PauseFlag == 0) { + stateReady(); + } + + OSRestoreInterrupts(level); + return result; +} + +int DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback, s32 prio) { + int idle; + + ASSERTMSGLINE(2191, block, "DVDReadAbsAsync(): null pointer is specified to command block address."); + ASSERTMSGLINE(2192, addr, "DVDReadAbsAsync(): null pointer is specified to addr."); + ASSERTMSGLINE(2194, !OFFSET(addr, 32), "DVDReadAbsAsync(): address must be aligned with 32 byte boundary."); + ASSERTMSGLINE(2196, !(length & (32-1)), "DVDReadAbsAsync(): length must be a multiple of 32."); + ASSERTMSGLINE(2198, !(offset & (4-1)), "DVDReadAbsAsync(): offset must be a multiple of 4."); + ASSERTMSGLINE(2200, length >= 0, "DVD read: negative value was specified to length of the read\n"); + + block->command = DVD_COMMAND_READ; + block->addr = addr; + block->length = length; + block->offset = offset; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(prio, block); + ASSERTMSGLINE(2210, idle, "DVDReadAbsAsync(): command block is used for processing previous request."); + return idle; +} + +int DVDSeekAbsAsyncPrio(DVDCommandBlock* block, s32 offset, DVDCBCallback callback, s32 prio) { + int idle; + + ASSERTMSGLINE(2233, block, "DVDSeekAbs(): null pointer is specified to command block address."); + ASSERTMSGLINE(2235, !(offset & (4-1)), "DVDSeekAbs(): offset must be a multiple of 4."); + + block->command = DVD_COMMAND_SEEK; + block->offset = offset; + block->callback = callback; + + idle = issueCommand(prio, block); + ASSERTMSGLINE(2242, idle, "DVDSeekAbs(): command block is used for processing previous request."); + return idle; +} + +int DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(2272, block, "DVDReadAbsAsyncForBS(): null pointer is specified to command block address."); + ASSERTMSGLINE(2273, addr, "DVDReadAbsAsyncForBS(): null pointer is specified to addr."); + ASSERTMSGLINE(2275, !OFFSET(addr, 32), "DVDReadAbsAsyncForBS(): address must be aligned with 32 byte boundary."); + ASSERTMSGLINE(2277, !(length & (32-1)), "DVDReadAbsAsyncForBS(): length must be a multiple of 32."); + ASSERTMSGLINE(2279, !(offset & (4-1)), "DVDReadAbsAsyncForBS(): offset must be a multiple of 4."); + + block->command = DVD_COMMAND_BSREAD; + block->addr = addr; + block->length = length; + block->offset = offset; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(2, block); + ASSERTMSGLINE(2289, idle, "DVDReadAbsAsyncForBS(): command block is used for processing previous request."); + return idle; +} + +int DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(2312, block, "DVDReadDiskID(): null pointer is specified to command block address."); + ASSERTMSGLINE(2313, diskID, "DVDReadDiskID(): null pointer is specified to id address."); + ASSERTMSGLINE(2315, !OFFSET(diskID, 32), "DVDReadDiskID(): id must be aligned with 32 byte boundary."); + + block->command = DVD_COMMAND_READID; + block->addr = diskID; + block->length = 0x20; + block->offset = 0; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(2, block); + ASSERTMSGLINE(2325, idle, "DVDReadDiskID(): command block is used for processing previous request."); + return idle; +} + +int DVDPrepareStreamAbsAsync(DVDCommandBlock* block, u32 length, u32 offset, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_INITSTREAM; + block->length = length; + block->offset = offset; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +int DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_CANCELSTREAM; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDCancelStream(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDCancelStreamAsync(block, cbForCancelStreamSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_STOP_STREAM_AT_END; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDStopStreamAtEnd(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDStopStreamAtEndAsync(block, cbForStopStreamAtEndSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForStopStreamAtEndSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_REQUEST_AUDIO_ERROR; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDGetStreamErrorStatus(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDGetStreamErrorStatusAsync(block, cbForGetStreamErrorStatusSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForGetStreamErrorStatusSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_REQUEST_PLAY_ADDR; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDGetStreamPlayAddr(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDGetStreamPlayAddrAsync(block, cbForGetStreamPlayAddrSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForGetStreamPlayAddrSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDGetStreamStartAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_REQUEST_START_ADDR; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDGetStreamStartAddr(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDGetStreamStartAddrAsync(block, cbForGetStreamStartAddrSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForGetStreamStartAddrSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDGetStreamLengthAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_REQUEST_LENGTH; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDGetStreamLength(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDGetStreamLengthAsync(block, cbForGetStreamLengthSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForGetStreamLengthSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +void __DVDAudioBufferConfig(DVDCommandBlock* block, u32 enable, u32 size, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_AUDIO_BUFFER_CONFIG; + block->offset = enable; + block->length = size; + block->callback = callback; + idle = issueCommand(2, block); +} + +int DVDChangeDiskAsyncForBS(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(2869, block, "DVDChangeDiskAsyncForBS(): null pointer is specified to command block address."); + + block->command = DVD_COMMAND_BS_CHANGE_DISK; + block->callback = callback; + idle = issueCommand(2, block); + ASSERTMSGLINE(2875, idle, "DVDChangeDiskAsyncForBS(): command block is used for processing previous request."); + return idle; +} + +int DVDChangeDiskAsync(DVDCommandBlock* block, DVDDiskID* id, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(2896, block, "DVDChangeDisk(): null pointer is specified to command block address."); + ASSERTMSGLINE(2897, id, "DVDChangeDisk(): null pointer is specified to id address."); + + if (id->company[0] == 0) { + OSReport("DVDChangeDiskAsync(): You can't specify NULL to company name. \n"); + DVD_ASSERTMSGLINE(2902, 0, ""); + } + + block->command = DVD_COMMAND_CHANGE_DISK; + block->id = id; + block->callback = callback; + DCInvalidateRange(bootInfo->FSTLocation, bootInfo->FSTMaxLength); + + idle = issueCommand(2, block); + ASSERTMSGLINE(2913, idle, "DVDChangeDisk(): command block is used for processing previous request."); + return idle; +} + +s32 DVDChangeDisk(DVDCommandBlock* block, DVDDiskID* id) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDChangeDiskAsync(block, id, cbForChangeDiskSync); + if (result == 0) { + return -1; + } + + enabled = OSDisableInterrupts(); + while (1) { + state = block->state; + if (state == DVD_STATE_END) { + retVal = 0; + break; + } else if (state == DVD_STATE_FATAL_ERROR) { + retVal = -1; + break; + } else if (state == DVD_STATE_CANCELED) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForChangeDiskSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDStopMotorAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + ASSERTMSGLINE(2996, block, "DVDStopMotor(): Null address was specified for block"); + + block->command = DVD_COMMAND_UNK_16; + block->callback = callback; + + idle = issueCommand(2, block); + ASSERTMSGLINE(3002, idle, "DVDStopMotor(): command block is used for processing previous request."); + return idle; +} + +s32 DVDStopMotor(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDStopMotorAsync(block, cbForStopMotorSync); + if (result == 0) { + return -1; + } + + enabled = OSDisableInterrupts(); + while (1) { + state = block->state; + if (state == DVD_STATE_END) { + retVal = 0; + break; + } else if (state == DVD_STATE_FATAL_ERROR) { + retVal = -1; + break; + } else if (state == DVD_STATE_CANCELED) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForStopMotorSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(3085, block, "DVDInquiry(): Null address was specified for block"); + ASSERTMSGLINE(3086, info, "DVDInquiry(): Null address was specified for info"); + ASSERTMSGLINE(3088, !OFFSET(info, 32), "DVDInquiry(): Address for info is not 32 bytes aligned"); + + block->command = DVD_COMMAND_INQUIRY; + block->addr = info; + block->length = 0x20; + block->transferredSize = 0; + block->callback = callback; + idle = issueCommand(2, block); + return idle; +} + +s32 DVDInquiry(DVDCommandBlock* block, DVDDriveInfo* info) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDInquiryAsync(block, info, cbForInquirySync); + if (result == 0) { + return -1; + } + + enabled = OSDisableInterrupts(); + while (1) { + state = block->state; + if (state == DVD_STATE_END) { + retVal = (u32)block->transferredSize; + break; + } else if (state == DVD_STATE_FATAL_ERROR) { + retVal = -1; + break; + } else if (state == DVD_STATE_CANCELED) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForInquirySync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +void DVDReset(void) { + DVDLowReset(); + __DIRegs[0] = 0x2A; + __DIRegs[1] = __DIRegs[1]; + ResetRequired = 0; + ResumeFromHere = 0; +} + +int DVDResetRequired(void) { + return ResetRequired; +} + +s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block) { + BOOL enabled; + s32 retVal; + + ASSERTMSGLINE(3197, block, "DVDGetCommandBlockStatus(): null pointer is specified to command block address."); + enabled = OSDisableInterrupts(); + + if (block->state == 3) { + retVal = 1; + } else { + retVal = block->state; + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +s32 DVDGetDriveStatus(void) { + BOOL enabled = OSDisableInterrupts(); + s32 retVal; + + if (FatalErrorFlag != FALSE) { + retVal = DVD_STATE_FATAL_ERROR; + } else { + if (PausingFlag != FALSE) { + retVal = DVD_STATE_PAUSING; + } else { + if (executing == NULL) { + retVal = DVD_STATE_END; + } else if (executing == &DummyCommandBlock) { + retVal = DVD_STATE_END; + } else { + retVal = DVDGetCommandBlockStatus((DVDCommandBlock*)executing); + } + } + } + OSRestoreInterrupts(enabled); + return retVal; +} + +BOOL DVDSetAutoInvalidation(BOOL autoInval) { + BOOL prev; + + prev = autoInvalidation; + autoInvalidation = autoInval; + return prev; +} + +void DVDPause(void) { + BOOL level; + + level = OSDisableInterrupts(); + PauseFlag = 1; + if (executing == NULL) { + PausingFlag = 1; + } + OSRestoreInterrupts(level); +} + +void DVDResume(void) { + BOOL level; + + level = OSDisableInterrupts(); + PauseFlag = 0; + if (PausingFlag != 0) { + PausingFlag = 0; + stateReady(); + } + OSRestoreInterrupts(level); +} + +int DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) { + BOOL enabled; + DVDLowCallback old; + DVDCommandBlock* finished; + + enabled = OSDisableInterrupts(); + + switch (block->state) { + case DVD_STATE_FATAL_ERROR: + case DVD_STATE_END: + case DVD_STATE_CANCELED: + if (callback) + (*callback)(0, block); + break; + case DVD_STATE_BUSY: + if (Canceling) { + OSRestoreInterrupts(enabled); + return FALSE; + } + + Canceling = TRUE; + CancelCallback = callback; + if (block->command == DVD_COMMAND_BSREAD || block->command == DVD_COMMAND_READ) { + DVDLowBreak(); + } + break; + case DVD_STATE_WAITING: + __DVDDequeueWaitingQueue(block); + block->state = DVD_STATE_CANCELED; + + if (block->callback) + (block->callback)(-3, block); + + if (callback) + (*callback)(0, block); + break; + case DVD_STATE_COVER_CLOSED: + switch (block->command) { + case DVD_COMMAND_READID: + case DVD_COMMAND_BSREAD: + case DVD_COMMAND_AUDIO_BUFFER_CONFIG: + case DVD_COMMAND_BS_CHANGE_DISK: + if (callback) + (*callback)(0, block); + break; + + default: + if (Canceling) { + OSRestoreInterrupts(enabled); + return FALSE; + } + Canceling = TRUE; + CancelCallback = callback; + break; + } + break; + case DVD_STATE_NO_DISK: + case DVD_STATE_COVER_OPEN: + case DVD_STATE_WRONG_DISK: + case DVD_STATE_MOTOR_STOPPED: + case DVD_STATE_RETRY: + old = DVDLowClearCallback(); + ASSERTLINE(3418, old == cbForStateMotorStopped); + + if (old != cbForStateMotorStopped) { + OSRestoreInterrupts(enabled); + return FALSE; + } + + if (block->state == DVD_STATE_NO_DISK) + ResumeFromHere = 3; + if (block->state == DVD_STATE_COVER_OPEN) + ResumeFromHere = 4; + if (block->state == DVD_STATE_WRONG_DISK) + ResumeFromHere = 1; + if (block->state == DVD_STATE_RETRY) + ResumeFromHere = 2; + if (block->state == DVD_STATE_MOTOR_STOPPED) + ResumeFromHere = 7; + + finished = executing; + executing = &DummyCommandBlock; + + block->state = DVD_STATE_CANCELED; + if (block->callback) { + (block->callback)(-3, block); + } + + if (callback) { + (callback)(0, block); + } + stateReady(); + break; + } + + OSRestoreInterrupts(enabled); + return TRUE; +} + +s32 DVDCancel(volatile DVDCommandBlock* block) { + int result; + s32 state; + u32 command; + BOOL enabled; + + result = DVDCancelAsync((void*)block, cbForCancelSync); + if (result == 0) { + return -1; + } + + enabled = OSDisableInterrupts(); + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + break; + } + + if (state == DVD_STATE_COVER_CLOSED) { + command = block->command; + if ((command == DVD_COMMAND_BSREAD) || (command == DVD_COMMAND_READID) || (command == DVD_COMMAND_AUDIO_BUFFER_CONFIG) || (command == DVD_COMMAND_BS_CHANGE_DISK)) { + break; + } + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return 0; +} + +static void cbForCancelSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDCancelAllAsync(DVDCBCallback callback) { + BOOL enabled; + DVDCommandBlock* p; + int retVal; + + enabled = OSDisableInterrupts(); + DVDPause(); + while ((p = __DVDPopWaitingQueue())) { + DVDCancelAsync(p, NULL); + } + + if (executing) { + retVal = DVDCancelAsync(executing, callback); + } else { + retVal = 1; + if (callback) { + callback(0, NULL); + } + } + + DVDResume(); + OSRestoreInterrupts(enabled); + return retVal; +} + +s32 DVDCancelAll(void) { + int result; + BOOL enabled; + + enabled = OSDisableInterrupts(); + CancelAllSyncComplete = 0; + result = DVDCancelAllAsync(cbForCancelAllSync); + if (result == 0) { + OSRestoreInterrupts(enabled); + return -1; + } + + while (1) { + if (CancelAllSyncComplete == 0) { + OSSleepThread(&__DVDThreadQueue); + } else { + break; + } + } + + OSRestoreInterrupts(enabled); + return 0; +} + +static void cbForCancelAllSync(s32 result, DVDCommandBlock* block) { + CancelAllSyncComplete = 1; + OSWakeupThread(&__DVDThreadQueue); +} + +DVDDiskID* DVDGetCurrentDiskID(void) { + return (void*)OSPhysicalToCached(0); +} + +BOOL DVDCheckDisk(void) { + BOOL enabled; + s32 retVal; + s32 state; + u32 coverReg; + + enabled = OSDisableInterrupts(); + + if (FatalErrorFlag) { + state = -1; + } else if (PausingFlag) { + state = 8; + } else { + if (executing == NULL) { + state = 0; + } else if (executing == &DummyCommandBlock) { + state = 0; + } else { + state = executing->state; + } + } + + switch (state) { + case DVD_STATE_BUSY: + case DVD_STATE_IGNORED: + case DVD_STATE_CANCELED: + case DVD_STATE_WAITING: + retVal = TRUE; + break; + case DVD_STATE_FATAL_ERROR: + case DVD_STATE_RETRY: + case DVD_STATE_MOTOR_STOPPED: + case DVD_STATE_COVER_CLOSED: + case DVD_STATE_NO_DISK: + case DVD_STATE_COVER_OPEN: + case DVD_STATE_WRONG_DISK: + retVal = FALSE; + break; + case DVD_STATE_END: + case DVD_STATE_PAUSING: + coverReg = __DIRegs[1]; + if (((coverReg >> 2) & 1) || (coverReg & 1)) { + retVal = FALSE; + } else if (ResumeFromHere != 0) { + retVal = FALSE; + } else { + retVal = TRUE; + } + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +void __DVDPrepareResetAsync(DVDCBCallback callback) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + __DVDClearWaitingQueue(); + + if (Canceling) { + CancelCallback = callback; + } else { + if (executing) { + executing->callback = NULL; + } + + DVDCancelAllAsync(callback); + } + + OSRestoreInterrupts(enabled); +} + +int __DVDTestAlarm(const OSAlarm* alarm) { + if (alarm == &ResetAlarm) { + return 1; + } + return __DVDLowTestAlarm(alarm); +} diff --git a/src/dolphin/dvd/dvdFatal.c b/src/dolphin/dvd/dvdFatal.c new file mode 100644 index 0000000..abb3a64 --- /dev/null +++ b/src/dolphin/dvd/dvdFatal.c @@ -0,0 +1,95 @@ +#include +#include + +#include "__dvd.h" + +static void (*FatalFunc)(); + +const char* Japanese = + "\n\n\nエラーが発生しました。\n\n" + "本体のパワーボタンを押して電源をOFFにし、\n" + "本体の取扱説明書の指示に従ってください。"; + +const char* English = + "\n\n\nAn error has occurred.\n" + "Turn the power off and refer to the\n" + "Nintendo GameCube Instruction Booklet\n" + "for further instructions."; + +// TODO: need solution to compile special characters in a cleaner way +const char* const Europe[6] = { + { + "\n\n\nAn error has occurred.\n" + "Turn the power off and refer to the\n" + "Nintendo GameCube Instruction Booklet\n" + "for further instructions." + }, + { + "\n\n\nEin Fehler ist aufgetreten.\n" + "Bitte schalten Sie den Nintendo GameCube\n" + "aus und lesen Sie die Bedienungsanleitung,\n" + "um weitere Informationen zu erhalten." + }, + { + "\n\n\nUne erreur est survenue.\n" + "Eteignez la console et r\xE9" "f" "\xE9rez-vous au\n" + "manuel d'instructions Nintendo GameCube\n" + "pour de plus amples informations." + }, + { + "\n\n\nSe ha producido un error.\n" + "Apaga la consola y consulta el manual\n" + "de instrucciones de Nintendo GameCube\n" + "para obtener m\xE1" "s informaci\xF3" "n." + }, + { + "\n\n\nSi \xE8" " verificato un errore.\n" + "Spegni (OFF) e controlla il manuale\n" + "d'istruzioni del Nintendo GameCube\n" + "per ulteriori indicazioni." + }, + { + "\n\n\nEr is een fout opgetreden.\n" + "Zet de Nintendo GameCube uit en\n" + "raadpleeg de handleiding van de\n" + "Nintendo GameCube voor nadere\n" + "instructies." + }, +}; + +static void ShowMessage(void) { + const char* message; + GXColor bg = {0x00, 0x00, 0x00, 0x00}; + GXColor fg = {0xFF, 0xFF, 0xFF, 0x00}; + + if (VIGetTvFormat() == VI_NTSC) { + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) { + message = Japanese; + } else { + message = English; + } + } else { + message = Europe[OSGetLanguage()]; + } + + OSFatal(fg, bg, message); +} + +int DVDSetAutoFatalMessaging(BOOL enable) { + BOOL enabled; + int prev; + + enabled = OSDisableInterrupts(); + + prev = FatalFunc ? 1 : 0; + FatalFunc = enable ? ShowMessage : NULL; + + OSRestoreInterrupts(enabled); + return prev; +} + +void __DVDPrintFatalMessage(void) { + if (FatalFunc) { + FatalFunc(); + } +} diff --git a/src/dolphin/dvd/dvderror.c b/src/dolphin/dvd/dvderror.c new file mode 100644 index 0000000..894312e --- /dev/null +++ b/src/dolphin/dvd/dvderror.c @@ -0,0 +1,77 @@ +#include +#include +#include + +#include "os/__os.h" +#include "__dvd.h" + +static u32 ErrorTable[18] = { + 0x00000000, + 0x00023A00, + 0x00062800, + 0x00030200, + 0x00031100, + 0x00052000, + 0x00052001, + 0x00052100, + 0x00052400, + 0x00052401, + 0x00052402, + 0x000B5A01, + 0x00056300, + 0x00020401, + 0x00020400, + 0x00040800, + 0x00100007, + 0x00000000, +}; + +#define DIDNT_MATCH 29 + +static u8 ErrorCode2Num(u32 errorCode) { + u32 i; + + for (i = 0; i < 18; i++) { + if (errorCode == ErrorTable[i]) { + ASSERTLINE(73, i < DIDNT_MATCH); + return i; + } + } + + if (errorCode >= 0x100000 && errorCode <= 0x100008) { + return 17; + } + + return DIDNT_MATCH; +} + +static u8 Convert(u32 error) { + u32 statusCode; + u32 errorCode; + u8 errorNum; + + if (error == 0x01234567) { + return -1; + } else if (error == 0x01234568) { + return -2; + } + + statusCode = (error >> 24) & 0xFF; + errorCode = error & 0x00FFFFFF; + errorNum = ErrorCode2Num(errorCode); + if (statusCode >= 6) { + statusCode = 6; + } + + return statusCode * 30 + errorNum; +} + +void __DVDStoreErrorCode(u32 error) { + OSSramEx* sram; + u8 num; + + num = Convert(error); + sram = __OSLockSramEx(); + sram->dvdErrorCode = num; + __OSUnlockSramEx(TRUE); +} diff --git a/src/dolphin/dvd/dvdfs.c b/src/dolphin/dvd/dvdfs.c new file mode 100644 index 0000000..4a0a282 --- /dev/null +++ b/src/dolphin/dvd/dvdfs.c @@ -0,0 +1,630 @@ +#include +#include + +#include "__dvd.h" + +typedef struct FSTEntry { + /* 0x00 */ unsigned int isDirAndStringOff; + /* 0x04 */ unsigned int parentOrPosition; + /* 0x08 */ unsigned int nextEntryOrLength; +} FSTEntry; + +static OSBootInfo* BootInfo; +static FSTEntry* FstStart; +static char* FstStringStart; +static u32 MaxEntryNum; +static u32 currentDirectory; + +OSThreadQueue __DVDThreadQueue; +u32 __DVDLongFileNameFlag; + +// prototypes +static BOOL isSame(const char* path, const char* string); +static u32 myStrncpy(char* dest, char* src, u32 maxlen); +static u32 entryToPath(u32 entry, char* path, u32 maxlen); +static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen); +static void cbForReadAsync(s32 result, DVDCommandBlock* block); +static void cbForReadSync(s32 result, DVDCommandBlock* block); +static void cbForSeekAsync(s32 result, DVDCommandBlock* block); +static void cbForSeekSync(s32 result, DVDCommandBlock* block); +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block); +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block); + +void __DVDFSInit(void) { + BootInfo = (void*)OSPhysicalToCached(0); + FstStart = BootInfo->FSTLocation; + if (FstStart) { + MaxEntryNum = FstStart->nextEntryOrLength; + FstStringStart = (char*)FstStart + (MaxEntryNum* sizeof(FSTEntry)); + } +} + +/* For convenience */ +#define entryIsDir(i) (((FstStart[i].isDirAndStringOff & 0xff000000) == 0) ? FALSE : TRUE) +#define stringOff(i) (FstStart[i].isDirAndStringOff & ~0xff000000) +#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; + + ASSERTMSGLINE(318, pathPtr, "DVDConvertPathToEntrynum(): null pointer is specified "); + + 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__, 387, + "DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): " + "specified directory or file (%s) doesn't match standard 8.3 format. This is a " + "temporary restriction and will be removed soon\n", + origPathPtr); + } 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) { + ASSERTMSGLINE(455, fileInfo, "DVDFastOpen(): null pointer is specified to file info address "); + ASSERTMSG1LINE(458, (entrynum >= 0) && ((u32) entrynum < (u32) MaxEntryNum), "DVDFastOpen(): specified entry number '%d' is out of range ", entrynum); + ASSERTMSG1LINE(461, !entryIsDir(entrynum), "DVDFastOpen(): entry number '%d' is assigned to a directory ", entrynum); + + if (entrynum < 0 || entrynum >= MaxEntryNum || entryIsDir(entrynum)) { + return FALSE; + } + + fileInfo->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]; + + ASSERTMSGLINE(491, fileName, "DVDOpen(): null pointer is specified to file name "); + ASSERTMSGLINE(492, fileInfo, "DVDOpen(): null pointer is specified to file info address "); + + entry = DVDConvertPathToEntrynum(fileName); + + if (0 > entry) { + DVDGetCurrentDir(currentDir, 128); + OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir); + return FALSE; + } + + if (entryIsDir(entry)) { + ASSERTMSG1LINE(506, !entryIsDir(entry), "DVDOpen(): directory '%s' is specified as a filename ", fileName); + return FALSE; + } + + fileInfo->startAddr = filePosition(entry); + fileInfo->length = fileLength(entry); + fileInfo->callback = (DVDCallback)NULL; + fileInfo->cb.state = DVD_STATE_END; + + return TRUE; +} + +BOOL DVDClose(DVDFileInfo* fileInfo) { + ASSERTMSGLINE(530, fileInfo, "DVDClose(): null pointer is specified to file info address "); + DVDCancel(&(fileInfo->cb)); + return TRUE; +} + +static u32 myStrncpy(char* dest, char* src, u32 maxlen) { + u32 i = maxlen; + + while ((i > 0) && (*src != 0)) { + *dest++ = *src++; + i--; + } + + return (maxlen - i); +} + +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; + + ASSERTMSG1LINE(622, (entrynum >= 0) && (entrynum < MaxEntryNum), "DVDConvertEntrynumToPath: specified entrynum(%d) is out of range ", entrynum); + ASSERTMSG1LINE(624, maxlen > 1, "DVDConvertEntrynumToPath: maxlen should be more than 1 (%d is specified)", maxlen); + ASSERTMSGLINE(629, entryIsDir(entrynum), "DVDConvertEntrynumToPath: cannot convert an entry num for a file to path "); + + loc = entryToPath((u32)entrynum, path, maxlen); + + if (loc == maxlen) { + path[maxlen - 1] = '\0'; + return FALSE; + } + + if (entryIsDir(entrynum)) { + if (loc == maxlen - 1) { + path[loc] = '\0'; + return FALSE; + } + + path[loc++] = '/'; + } + + path[loc] = '\0'; + return TRUE; +} + +BOOL DVDGetCurrentDir(char* path, u32 maxlen) { + ASSERTMSG1LINE(671, (maxlen > 1), "DVDGetCurrentDir: maxlen should be more than 1 (%d is specified)", maxlen); + return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); +} + +BOOL DVDChangeDir(const char* dirName) { + s32 entry; + char currentDir[128]; + + ASSERTMSGLINE(693, dirName, "DVDChangeDir(): null pointer is specified to directory name "); + entry = DVDConvertPathToEntrynum(dirName); + ASSERTMSG2LINE(701, entry >= 0, "DVDChangeDir(): directory '%s' is not found under %s ", dirName, (DVDGetCurrentDir(currentDir, 128), currentDir)); + ASSERTMSG1LINE(705, entryIsDir(entry), "DVDChangeDir(): file '%s' is specified as a directory name ", dirName); + + if (entry < 0 || entryIsDir(entry) == FALSE) { + return FALSE; + } + + currentDirectory = (u32)entry; + + return TRUE; +} + +BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, DVDCallback callback, s32 prio) { + ASSERTMSGLINE(736, fileInfo, "DVDReadAsync(): null pointer is specified to file info address "); + ASSERTMSGLINE(737, addr, "DVDReadAsync(): null pointer is specified to addr "); + ASSERTMSGLINE(741, !OFFSET(addr, 32), "DVDReadAsync(): address must be aligned with 32 byte boundaries "); + ASSERTMSGLINE(743, !(length & 0x1F), "DVDReadAsync(): length must be multiple of 32 byte "); + ASSERTMSGLINE(745, !(offset & 3), "DVDReadAsync(): offset must be multiple of 4 byte "); + + DVD_ASSERTMSGLINE(750, (0 <= offset) && (offset <= fileInfo->length), "DVDReadAsync(): specified area is out of the file "); + + DVD_ASSERTMSGLINE(756, (0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE), "DVDReadAsync(): specified area is out of the file "); + + fileInfo->callback = callback; + DVDReadAbsAsyncPrio(&(fileInfo->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)); + ASSERTLINE(774, (void*) &fileInfo->cb == (void*) block); + if (fileInfo->callback) { + (fileInfo->callback)(result, fileInfo); + } +} + +s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) { + int result; + DVDCommandBlock* block; + s32 state; + BOOL enabled; + s32 retVal; + + ASSERTMSGLINE(806, fileInfo, "DVDRead(): null pointer is specified to file info address "); + ASSERTMSGLINE(807, addr, "DVDRead(): null pointer is specified to addr "); + ASSERTMSGLINE(811, !OFFSET(addr, 32), "DVDRead(): address must be aligned with 32 byte boundaries "); + ASSERTMSGLINE(813, !(length & 0x1F), "DVDRead(): length must be multiple of 32 byte "); + ASSERTMSGLINE(815, !(offset & 3), "DVDRead(): offset must be multiple of 4 byte "); + + DVD_ASSERTMSGLINE(820, (0 <= offset) && (offset <= fileInfo->length), "DVDRead(): specified area is out of the file "); + DVD_ASSERTMSGLINE(826, (0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE), "DVDRead(): specified area is out of the file "); + + block = &fileInfo->cb; + result = DVDReadAbsAsyncPrio(block, addr, length, fileInfo->startAddr + offset, cbForReadSync, prio); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = ((volatile DVDCommandBlock*)block)->state; + if (state == 0) { + retVal = (s32)block->transferredSize; + break; + } else if (state == -1) { + retVal = -1; + break; + } else if (state == 10) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForReadSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio) { + ASSERTMSGLINE(898, fileInfo, "DVDSeek(): null pointer is specified to file info address "); + ASSERTMSGLINE(902, !(offset & 3), "DVDSeek(): offset must be multiple of 4 byte "); + + DVD_ASSERTMSGLINE(907, (0 <= offset) && (offset <= fileInfo->length), "DVDSeek(): offset is out of the file "); + + fileInfo->callback = callback; + DVDSeekAbsAsyncPrio(&fileInfo->cb, (u32)(char*)fileInfo->startAddr + offset, cbForSeekAsync, prio); + return 1; +} + +static void cbForSeekAsync(s32 result, DVDCommandBlock* block) { + DVDFileInfo* fileInfo; + + fileInfo = (DVDFileInfo *)&block->next; + ASSERTLINE(925, (void*) &fileInfo->cb == (void*) block); + if (fileInfo->callback) { + (fileInfo->callback)(result, fileInfo); + } +} + +s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio) { + int result; + DVDCommandBlock* block; + s32 state; + BOOL enabled; + s32 retVal; + + ASSERTMSGLINE(955, fileInfo, "DVDSeek(): null pointer is specified to file info address "); + ASSERTMSGLINE(959, !(offset & 3), "DVDSeek(): offset must be multiple of 4 byte "); + ASSERTMSGLINE(963, (offset >= 0) && ((u32) offset <= (u32) fileInfo->length), "DVDSeek(): offset is out of the file "); + + block = &fileInfo->cb; + result = DVDSeekAbsAsyncPrio(block, (u32)(char*)fileInfo->startAddr + offset, cbForSeekSync, prio); + if (!result) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = ((volatile DVDCommandBlock*)block)->state; + if (state == 0) { + retVal = 0; + break; + } else if (state == -1) { + retVal = -1; + break; + } else if (state == 10) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForSeekSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +s32 DVDGetFileInfoStatus(const DVDFileInfo* fileInfo) { + return DVDGetCommandBlockStatus(&fileInfo->cb); +} + +BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) { + ASSERTMSGLINE(1048, dir, "DVDFastOpenDir(): null pointer is specified to dir structure address "); + ASSERTMSG1LINE(1051, entrynum >= 0 && entrynum < MaxEntryNum, "DVDFastOpenDir(): specified entry number \'%d\' is out of range ", entrynum); + ASSERTMSG1LINE(1054, entryIsDir(entrynum), "DVDFastOpenDir(): entry number \'%d\' is assigned to a file ", entrynum); + + if (entrynum < 0 || entrynum >= MaxEntryNum || !entryIsDir(entrynum)) { + return FALSE; + } + + dir->entryNum = entrynum; + dir->location = entrynum + 1; + dir->next = FstStart[entrynum].nextEntryOrLength; + return TRUE; +} + +BOOL DVDOpenDir(const char* dirName, DVDDir* dir) { + s32 entry; + char currentDir[128]; + + ASSERTMSGLINE(1083, dirName, "DVDOpendir(): null pointer is specified to directory name "); + ASSERTMSGLINE(1084, dir, "DVDOpenDir(): null pointer is specified to dir structure address "); + + entry = DVDConvertPathToEntrynum(dirName); + if (entry < 0) { + DVDGetCurrentDir(currentDir, sizeof(currentDir)); + OSReport("Warning: DVDOpenDir(): file \'%s\' was not found under %s.\n", dirName, currentDir); + return FALSE; + } + + if (!entryIsDir(entry)) { + ASSERTMSG1LINE(1098, entryIsDir(entry), "DVDOpendir(): file \'%s\' is specified as a directory name ", dirName); + return FALSE; + } + + dir->entryNum = entry; + dir->location = entry + 1; + dir->next = nextDir(entry); + return TRUE; +} + +int DVDReadDir(DVDDir* dir, DVDDirEntry* dirent) { + u32 loc; + + loc = dir->location; + if ((loc <= (u32) dir->entryNum) || ((u32) dir->next <= loc)) { + return 0; + } + dirent->entryNum = loc; + dirent->isDir = entryIsDir(loc); + dirent->name = FstStringStart + stringOff(loc); + dir->location = entryIsDir(loc) ? nextDir(loc) : loc + 1; + return 1; +} + +int DVDCloseDir(DVDDir* dir) { + return 1; +} + +void DVDRewindDir(DVDDir* dir) { + dir->location = dir->entryNum + 1; +} + +void* DVDGetFSTLocation(void) { + return BootInfo->FSTLocation; +} + +#define RoundUp32KB(x) (((u32)(x) + 32 * 1024 - 1) & ~(32 * 1024 - 1)) +#define Is32KBAligned(x) (((u32)(x) & (32 * 1024 - 1)) == 0) + +BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback) { + u32 start; + + ASSERTMSGLINE(1205, fileInfo, "DVDPrepareStreamAsync(): NULL file info was specified"); + + start = fileInfo->startAddr + offset; + + DVD_ASSERTMSG2LINE(1211, Is32KBAligned(start), "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is not 32KB aligned", fileInfo->startAddr, offset); + + if (length == 0) + length = fileInfo->length - offset; + + DVD_ASSERTMSG1LINE(1221, Is32KBAligned(length), "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", length); + + DVD_ASSERTMSG2LINE(1229, (offset <= fileInfo->length) && (offset + length <= fileInfo->length), "DVDPrepareStreamAsync(): The area specified (offset(0x%x), length(0x%x)) is out of the file", offset, length); + + fileInfo->callback = callback; + return DVDPrepareStreamAbsAsync(&(fileInfo->cb), length, fileInfo->startAddr + offset, cbForPrepareStreamAsync); +} + +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block) { + DVDFileInfo* fileInfo; + + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); + + ASSERTLINE(1248, (void*) &fileInfo->cb == (void*) block); + + if (fileInfo->callback) { + (fileInfo->callback)(result, fileInfo); + } +} + +s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset) { + BOOL result; + DVDCommandBlock* block; + s32 state; + BOOL enabled; + s32 retVal; + u32 start; + + ASSERTMSGLINE(1282, fileInfo, "DVDPrepareStream(): NULL file info was specified"); + + start = fileInfo->startAddr + offset; + + DVD_ASSERTMSG2LINE(1288, Is32KBAligned(start), "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not 32KB aligned", fileInfo->startAddr, offset); + + if (length == 0) + length = fileInfo->length - offset; + + DVD_ASSERTMSG1LINE(1298, Is32KBAligned(length), "DVDPrepareStream(): Specified length (0x%x) is not a multiple of 32768(32*1024)", length); + + DVD_ASSERTMSG2LINE(1306, (offset <= fileInfo->length) && (offset + length <= fileInfo->length), "DVDPrepareStream(): The area specified (offset(0x%x), length(0x%x)) is out of the file", offset, length); + + block = &(fileInfo->cb); + result = DVDPrepareStreamAbsAsync(block, length, start, cbForPrepareStreamSync); + + if (result == FALSE) { + return -1; + } + + enabled = OSDisableInterrupts(); + + while (1) { + state = ((volatile DVDCommandBlock*)block)->state; + + if (state == DVD_STATE_END) { + retVal = 0; + break; + } + if (state == DVD_STATE_FATAL_ERROR) { + retVal = DVD_RESULT_FATAL_ERROR; + break; + } + if (state == DVD_STATE_CANCELED) { + retVal = -3; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +s32 DVDGetTransferredSize(DVDFileInfo* fileinfo) { + s32 bytes; + DVDCommandBlock* cb; + + cb = &(fileinfo->cb); + + switch (cb->state) { + case DVD_STATE_COVER_CLOSED: + case DVD_STATE_NO_DISK: + case DVD_STATE_COVER_OPEN: + case DVD_STATE_WRONG_DISK: + case DVD_STATE_FATAL_ERROR: + case DVD_STATE_MOTOR_STOPPED: + case DVD_STATE_CANCELED: + case DVD_STATE_RETRY: + case DVD_STATE_END: + bytes = (s32)cb->transferredSize; + break; + case DVD_STATE_WAITING: + bytes = 0; + break; + case DVD_STATE_BUSY: + bytes = (s32)(cb->transferredSize + (cb->currTransferSize - __DIRegs[6])); + break; + default: + ASSERTMSG1LINE(1391, FALSE, "DVDGetTransferredSize(): Illegal state (%d)", cb->state); + break; + } + + return bytes; +} diff --git a/src/dolphin/dvd/dvdidutils.c b/src/dolphin/dvd/dvdidutils.c new file mode 100644 index 0000000..a702a65 --- /dev/null +++ b/src/dolphin/dvd/dvdidutils.c @@ -0,0 +1,97 @@ +#include +#include + +#include "__dvd.h" + +static u32 strnlen(const char* str, u32 maxlen) { + u32 i; + + for (i = 0; i < maxlen; i++) { + if (*str++ == 0) { + return i; + } + } + + return maxlen; +} + +int DVDCompareDiskID(const DVDDiskID* id1, const DVDDiskID* id2) { +#ifdef DEBUG + const char* game1; + const char* game2; + const char* company1; + const char* company2; + u8 diskNum1; + u8 diskNum2; + u8 version1; + u8 version2; + u32 length; + + ASSERTMSGLINE(64, id1, "DVDCompareDiskID(): Specified id1 is NULL\n"); + ASSERTMSGLINE(65, id2, "DVDCompareDiskID(): Specified id2 is NULL\n"); + + game1 = id1->gameName; + game2 = id2->gameName; + company1 = id1->company; + company2 = id2->company; + diskNum1 = id1->diskNumber; + diskNum2 = id2->diskNumber; + version1 = id1->gameVersion; + version2 = id2->gameVersion; + + length = strnlen(game1, sizeof(game1)); + ASSERTMSGLINE(78, length == 0 || length == 4, "DVDCompareDiskID(): Specified game name for id1 is neither NULL nor 4 character long\n"); + ASSERTMSGLINE(79, company1, "DVDCompareDiskID(): Specified company name for id1 is NULL\n"); + ASSERTMSGLINE(80, company1[1] != 0, "DVDCompareDiskID(): Specified company name for id1 is not 2 character long\n"); + ASSERTMSGLINE(81, diskNum1 == 0xFF || ((diskNum1 / 16) < 10 && diskNum1 % 16 < 10), "DVDCompareDiskID(): Specified disk number for id1 is neither 0xff nor a BCD number"); + ASSERTMSGLINE(82, version1 == 0xFF || ((version1 / 16) < 10 && version1 % 16 < 10), "DVDCompareDiskID(): Specified version number for id1 is neither 0xff nor a BCD number"); + + length = strnlen(game2, sizeof(game2)); + ASSERTMSGLINE(85, length == 0 || length == 4, "DVDCompareDiskID(): Specified game name for id2 is neither NULL nor 4 character long\n"); + ASSERTMSGLINE(86, company2, "DVDCompareDiskID(): Specified company name for id2 is NULL\n"); + ASSERTMSGLINE(87, company2[1] != 0, "DVDCompareDiskID(): Specified company name for id2 is not 2 character long\n"); + ASSERTMSGLINE(88, diskNum2 == 0xFF || ((diskNum2 / 16) < 10 && diskNum2 % 16 < 10), "DVDCompareDiskID(): Specified disk number for id2 is neither 0xff nor a BCD number"); + ASSERTMSGLINE(89, version2 == 0xFF || ((version2 / 16) < 10 && version2 % 16 < 10), "DVDCompareDiskID(): Specified version number for id2 is neither 0xff nor a BCD number"); +#endif + + if (id1->gameName[0] != 0 && id2->gameName[0] != 0 && strncmp(id1->gameName, id2->gameName, 4) != 0) { + return 0; + } + + if (id1->company[0] == 0 || id2->company[0] == 0 || strncmp(id1->company, id2->company, 2) != 0) { + return 0; + } + + if (id1->diskNumber != 0xFF && id2->diskNumber != 0xFF && id1->diskNumber != id2->diskNumber) { + return 0; + } + + if (id1->gameVersion != 0xFF && id2->gameVersion != 0xFF && id1->gameVersion != id2->gameVersion) { + return 0; + } + + return 1; +} + +DVDDiskID* DVDGenerateDiskID(DVDDiskID* id, const char* game, const char* company, u8 diskNum, u8 version) { + ASSERTMSGLINE(123, id, "DVDGenerateDiskID(): Specified id is NULL\n"); + ASSERTMSGLINE(124, game == NULL || strlen(game) == 4, "DVDGenerateDiskID(): Specified game name is neither NULL nor 4 character long\n"); + ASSERTMSGLINE(125, company, "DVDGenerateDiskID(): Specified company name is NULL\n"); + ASSERTMSGLINE(126, strlen(company) == 2, "DVDGenerateDiskID(): Specified company name is not 2 character long\n"); + ASSERTMSGLINE(127, diskNum == 0xFF || ((diskNum / 16) < 10 && diskNum % 16 < 10), "DVDGenerateDiskID(): Specified disk number is neither 0xff nor a BCD number"); + ASSERTMSGLINE(128, version == 0xFF || ((version / 16) < 10 && version % 16 < 10), "DVDGenerateDiskID(): Specified version number is neither 0xff nor a BCD number"); + + memset(id, 0, sizeof(DVDDiskID)); + + if (game != NULL) { + strncpy(id->gameName, game, 4); + } + + if (company != NULL) { + strncpy(id->company, company, 2); + } + + id->diskNumber = diskNum; + id->gameVersion = version; + return id; +} diff --git a/src/dolphin/dvd/dvdlow.c b/src/dolphin/dvd/dvdlow.c new file mode 100644 index 0000000..79dca99 --- /dev/null +++ b/src/dolphin/dvd/dvdlow.c @@ -0,0 +1,534 @@ +#include +#include + +#include "__dvd.h" +#include "__os.h" + +#define DVD_WATYPE_MAX 2 + +static BOOL FirstRead = TRUE; +static volatile BOOL StopAtNextInt = FALSE; +static u32 LastLength = 0; +static DVDLowCallback Callback = NULL; +static DVDLowCallback ResetCoverCallback = NULL; +static volatile OSTime LastResetEnd = 0; +static volatile u32 ResetOccurred = FALSE; +static volatile BOOL WaitingCoverClose = FALSE; +static volatile BOOL Breaking = FALSE; +static volatile u32 WorkAroundType = 0; +static u32 WorkAroundSeekLocation = 0; +static volatile OSTime LastReadFinished = 0; +static OSTime LastReadIssued = 0; +static volatile BOOL LastCommandWasRead = FALSE; +static volatile u32 NextCommandNumber = 0; + +typedef struct { + void* addr; + u32 length; + u32 offset; +} DVDBuffer; + +typedef struct { + s32 command; + void* address; + 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; + +// prototypes +static void Read(void* address, u32 length, u32 offset, DVDLowCallback callback); +static void SetBreakAlarm(OSTime timeout); + +void __DVDInitWA(void) { + NextCommandNumber = 0; + CommandList[0].command = -1; + __DVDLowSetWAType(0, 0); + OSInitAlarm(); +} + +static BOOL ProcessNextCommand(void) { + s32 n = NextCommandNumber; + + ASSERTLINE(310, n < 3); + + if (CommandList[n].command == 1) { + ++NextCommandNumber; + Read(CommandList[n].address, CommandList[n].length, CommandList[n].offset, CommandList[n].callback); + return TRUE; + } else if (CommandList[n].command == 2) { + ++NextCommandNumber; + DVDLowSeek(CommandList[n].offset, CommandList[n].callback); + return TRUE; + } + + return FALSE; +} + +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) { + DVDLowCallback cb; + OSContext exceptionContext; + u32 cause = 0; + u32 reg; + u32 intr; + u32 mask; + + if (LastCommandWasRead) { + LastReadFinished = __OSGetSystemTime(); + FirstRead = FALSE; + Prev.addr = Curr.addr; + Prev.length = Curr.length; + Prev.offset = Curr.offset; + + if (StopAtNextInt == TRUE) { + cause |= 8; + } + } + + LastCommandWasRead = FALSE; + StopAtNextInt = FALSE; + reg = __DIRegs[0]; + mask = reg & 0x2a; + intr = (reg & 0x54) & (mask << 1); + + if (intr & 0x40) { + cause |= 8; + } + + if (intr & 0x10) { + cause |= 1; + } + + if (intr & 4) { + cause |= 2; + } + + if (cause) { + ResetOccurred = FALSE; + OSCancelAlarm(&AlarmForTimeout); + } + + __DIRegs[0] = intr | mask; + + if (ResetOccurred && (__OSGetSystemTime() - LastResetEnd) < OSMillisecondsToTicks(200)) { + reg = __DIRegs[1]; + mask = reg & 0x2; + intr = (reg & 4) & (mask << 1); + if (intr & 4) { + if (ResetCoverCallback) { + ResetCoverCallback(4); + } + ResetCoverCallback = NULL; + } + + __DIRegs[1] = __DIRegs[1]; + } else if (WaitingCoverClose) { + reg = __DIRegs[1]; + mask = reg & 2; + intr = (reg & 4) & (mask << 1); + + if (intr & 4) { + cause |= 4; + } + + __DIRegs[1] = intr | mask; + WaitingCoverClose = FALSE; + } else { + __DIRegs[1] = 0; + } + + if ((cause & 8) && !Breaking) { + cause &= ~8; + } + + if (cause & 1) { + if (ProcessNextCommand()) { + return; + } + } else { + CommandList[0].command = -1; + NextCommandNumber = 0; + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (cause) { + cb = Callback; + Callback = NULL; + if (cb) { + cb(cause); + } + + Breaking = FALSE; + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +static void AlarmHandler(OSAlarm* alarm, OSContext* context) { + BOOL processed = ProcessNextCommand(); + ASSERTLINE(652, processed); +} + +static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) { + DVDLowCallback cb; + OSContext exceptionContext; + + __OSMaskInterrupts(0x400); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + cb = Callback; + Callback = NULL; + if (cb) { + cb(0x10); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +static void SetTimeoutAlarm(OSTime timeout) { + OSCreateAlarm(&AlarmForTimeout); + OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); +} + +static void Read(void* address, u32 length, u32 offset, DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + LastCommandWasRead = TRUE; + LastReadIssued = __OSGetSystemTime(); + + __DIRegs[2] = 0xa8000000; + __DIRegs[3] = offset / 4; + __DIRegs[4] = length; + __DIRegs[5] = (u32)address; + __DIRegs[6] = length; + LastLength = length; + __DIRegs[7] = 3; + + if (length > 0xa00000) { + SetTimeoutAlarm(OSSecondsToTicks(20)); + } else { + SetTimeoutAlarm(OSSecondsToTicks(10)); + } +} + +static BOOL AudioBufferOn(void) { + DVDDiskID* id; + + id = DVDGetCurrentDiskID(); + if (id->streaming) { + return TRUE; + } + + return FALSE; +} + +static BOOL HitCache(DVDBuffer* curr, DVDBuffer* prev) { + u32 blockNumOfPrevEnd = (prev->offset + prev->length - 1) >> 15; + u32 blockNumOfCurrStart = (curr->offset >> 15); + u32 cacheBlockSize = AudioBufferOn() ? 5 : 15; + + if ((blockNumOfCurrStart > blockNumOfPrevEnd - 2) || (blockNumOfCurrStart < blockNumOfPrevEnd + cacheBlockSize + 3)) { + return TRUE; + } + return FALSE; +} + +static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { + CommandList[0].command = -1; + NextCommandNumber = 0; + Read(addr, length, offset, callback); +} + +static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { + u32 newOffset; + if ((offset & ~0x7FFF) == 0) { + newOffset = 0; + } else { + newOffset = (offset & ~0x7FFF) + WorkAroundSeekLocation; + } + + CommandList[0].command = 2; + CommandList[0].offset = newOffset; + CommandList[0].callback = callback; + CommandList[1].command = 1; + CommandList[1].address = addr; + CommandList[1].length = length; + CommandList[1].offset = offset; + CommandList[1].callback = callback; + CommandList[2].command = -1; + NextCommandNumber = 0; + DVDLowSeek(newOffset, callback); +} + +static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback, OSTime wait) { + CommandList[0].command = 1; + CommandList[0].address = addr; + CommandList[0].length = length; + CommandList[0].offset = offset; + CommandList[0].callback = callback; + CommandList[1].command = -1; + NextCommandNumber = 0; + OSCreateAlarm(&AlarmForWA); + OSSetAlarm(&AlarmForWA, wait, AlarmHandler); +} + +BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { + u32 blockNumOfPrevEnd; + u32 blockNumOfCurrStart; + OSTime diff; + + ASSERTMSGLINE(837, (((u32)addr) & 31) == 0, "DVDLowRead(): address must be aligned with 32 byte boundary."); + ASSERTMSGLINE(838, (length & 31) == 0, "DVDLowRead(): length must be a multiple of 32."); + ASSERTMSGLINE(839, (offset & 3) == 0, "DVDLowRead(): offset must be a multiple of 4."); + ASSERTMSGLINE(841, length != 0, "DVD read: 0 was specified to length of the read\n"); + + __DIRegs[6] = length; + Curr.addr = addr; + Curr.length = length; + Curr.offset = offset; + + if (WorkAroundType == 0) { + DoJustRead(addr, length, offset, callback); + } else if (WorkAroundType == 1) { + if (FirstRead) { + SeekTwiceBeforeRead(addr, length, offset, callback); + } else { + if (!HitCache(&Curr, &Prev)) { + DoJustRead(addr, length, offset, callback); + } else { + blockNumOfPrevEnd = (u32)((Prev.offset + Prev.length - 1) >> 15) & 0x1FFFF; + blockNumOfCurrStart = (u32)((Curr.offset >> 15) & 0x1FFFF); + if (blockNumOfPrevEnd == blockNumOfCurrStart || blockNumOfPrevEnd + 1 == blockNumOfCurrStart) { + diff = __OSGetSystemTime() - LastReadFinished; + if (OSMillisecondsToTicks(5) < diff) { + DoJustRead(addr, length, offset, callback); + } else { + WaitBeforeRead(addr, length, offset, callback, OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500)); + } + } else { + SeekTwiceBeforeRead(addr, length, offset, callback); + } + } + } + } else { + ASSERTLINE(900, FALSE); + } + + return TRUE; +} + +BOOL DVDLowSeek(u32 offset, DVDLowCallback callback) { + ASSERTMSGLINE(920, (offset & 3) == 0, "DVDLowSeek(): offset must be a multiple of 4."); + + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0xab000000; + __DIRegs[3] = offset / 4; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowWaitCoverClose(DVDLowCallback callback) { + Callback = callback; + WaitingCoverClose = TRUE; + StopAtNextInt = FALSE; + __DIRegs[1] = 2; + return TRUE; +} + +BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback) { + ASSERTMSGLINE(986, (((u32)diskID) & 31) == 0, "DVDLowReadID(): id must be aligned with 32 byte boundary."); + + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0xa8000040; + __DIRegs[3] = 0; + __DIRegs[4] = sizeof(DVDDiskID); + __DIRegs[5] = (u32)diskID; + __DIRegs[6] = sizeof(DVDDiskID); + __DIRegs[7] = 3; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowStopMotor(DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0xe3000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowRequestError(DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0xe0000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0x12000000; + __DIRegs[4] = sizeof(DVDDriveInfo); + __DIRegs[5] = (u32)info; + __DIRegs[6] = sizeof(DVDDriveInfo); + __DIRegs[7] = 3; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = subcmd | 0xe1000000; + __DIRegs[3] = offset >> 2; + __DIRegs[4] = length; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = subcmd | 0xe2000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback) { +#ifdef DEBUG + u32 bufSize; + u32 trigger; +#endif + + Callback = callback; + StopAtNextInt = FALSE; + +#ifdef DEBUG + bufSize = size & 0xF; + trigger = (size >> 4) & 0xF; + ASSERTLINE(1242, bufSize < 16); + ASSERTLINE(1243, trigger <= 2); +#endif + + __DIRegs[2] = 0xe4000000 | (enable != 0 ? 0x10000 : 0) | size; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +void DVDLowReset(void) { + 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 | 4 | 1; + ResetOccurred = TRUE; + LastResetEnd = __OSGetSystemTime(); +} + +DVDLowCallback DVDLowSetResetCoverCallback(DVDLowCallback callback) { + DVDLowCallback old; + BOOL enabled; + + enabled = OSDisableInterrupts(); + old = ResetCoverCallback; + ResetCoverCallback = callback; + OSRestoreInterrupts(enabled); + return old; +} + +static void DoBreak(void) { + u32 statusReg; + + statusReg = __DIRegs[0]; + statusReg |= 0x40 | 1; + __DIRegs[0] = statusReg; + Breaking = TRUE; +} + +static void AlarmHandlerForBreak(OSAlarm* alarm, OSContext* context) { + if (__DIRegs[6] < LastLength) { + DoBreak(); + } else { + SetBreakAlarm(OSMillisecondsToTicks(20)); + } +} + +static void SetBreakAlarm(OSTime timeout) { + OSCreateAlarm(&AlarmForBreak); + OSSetAlarm(&AlarmForBreak, timeout, AlarmHandlerForBreak); +} + +BOOL DVDLowBreak(void) { + StopAtNextInt = TRUE; + Breaking = TRUE; + return TRUE; +} + +DVDLowCallback DVDLowClearCallback(void) { + DVDLowCallback old; + __DIRegs[1] = 0; + WaitingCoverClose = FALSE; + old = Callback; + Callback = NULL; + return old; +} + +u32 DVDLowGetCoverStatus(void) { + if ((__OSGetSystemTime() - LastResetEnd) < OSMillisecondsToTicks(100)) { + return 0; + } + + if (__DIRegs[1] & 1) { + return 1; + } + + return 2; +} + +void __DVDLowSetWAType(u32 type, s32 seekLoc) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + ASSERTLINE(1491, type < DVD_WATYPE_MAX); + WorkAroundType = type; + WorkAroundSeekLocation = seekLoc; + OSRestoreInterrupts(enabled); +} + +int __DVDLowTestAlarm(const OSAlarm* alarm) { + if (alarm == &AlarmForBreak) { + return 1; + } + if (alarm == &AlarmForTimeout) { + return 1; + } + + return 0; +} diff --git a/src/dolphin/dvd/dvdqueue.c b/src/dolphin/dvd/dvdqueue.c new file mode 100644 index 0000000..2106f8c --- /dev/null +++ b/src/dolphin/dvd/dvdqueue.c @@ -0,0 +1,172 @@ +#include +#include + +#include "__dvd.h" + +static struct { + /* 0x00 */ DVDCommandBlock* next; + /* 0x04 */ DVDCommandBlock* prev; +} WaitingQueue[4]; + +// prototypes +static DVDCommandBlock* PopWaitingQueuePrio(s32 prio); + +void __DVDClearWaitingQueue(void) { + u32 i; + DVDCommandBlock* q; + + for(i = 0; i < 4; i++) { + q = (DVDCommandBlock*)&WaitingQueue[i].next; + q->next = q; + q->prev = q; + } +} + +int __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) { + BOOL enabled = OSDisableInterrupts(); + DVDCommandBlock* q = (DVDCommandBlock*)&WaitingQueue[prio]; + + q->prev->next = block; + block->prev = q->prev; + block->next = q; + q->prev = block; + OSRestoreInterrupts(enabled); + return 1; +} + +static DVDCommandBlock* PopWaitingQueuePrio(s32 prio) { + DVDCommandBlock* tmp; + BOOL enabled; + DVDCommandBlock* q; + + enabled = OSDisableInterrupts(); + q = (DVDCommandBlock*)&WaitingQueue[prio]; + ASSERTLINE(87, q->next != q); + + tmp = q->next; + q->next = tmp->next; + tmp->next->prev = q; + OSRestoreInterrupts(enabled); + tmp->next = 0; + tmp->prev = 0; + return tmp; +} + +DVDCommandBlock* __DVDPopWaitingQueue(void) { + u32 i; + BOOL enabled; + DVDCommandBlock* q; + + enabled = OSDisableInterrupts(); + for (i = 0; i < 4; i++) { + q = (DVDCommandBlock*)&WaitingQueue[i]; + if (q->next != q) { + OSRestoreInterrupts(enabled); + return PopWaitingQueuePrio(i); + } + } + + OSRestoreInterrupts(enabled); + return NULL; +} + +int __DVDCheckWaitingQueue(void) { + u32 i; + BOOL enabled; + DVDCommandBlock* q; + + enabled = OSDisableInterrupts(); + for (i = 0; i < 4; i++) { + q = (DVDCommandBlock*)&WaitingQueue[i]; + if (q->next != q) { + OSRestoreInterrupts(enabled); + return 1; + } + } + + OSRestoreInterrupts(enabled); + return 0; +} + +int __DVDDequeueWaitingQueue(DVDCommandBlock* block) { + BOOL enabled; + DVDCommandBlock* prev; + DVDCommandBlock* next; + + enabled = OSDisableInterrupts(); + prev = block->prev; + next = block->next; + if (prev == NULL || next == NULL) { + OSRestoreInterrupts(enabled); + return 0; + } + prev->next = next; + next->prev = prev; + OSRestoreInterrupts(enabled); + return 1; +} + +int __DVDIsBlockInWaitingQueue(DVDCommandBlock* block) { + u32 i; + DVDCommandBlock* start; + DVDCommandBlock* q; + + for (i = 0; i < 4; i++) { + start = (DVDCommandBlock*)&WaitingQueue[i]; + if (start->next == start) { + continue; + } + + for (q = start->next; q != start; q = q->next) { + if (q == block) { + return 1; + } + } + } + + return 0; +} + +static char* CommandNames[16] = { + "", + "READ", + "SEEK", + "CHANGE_DISK", + "BSREAD", + "READID", + "INITSTREAM", + "CANCELSTREAM", + "STOP_STREAM_AT_END", + "REQUEST_AUDIO_ERROR", + "REQUEST_PLAY_ADDR", + "REQUEST_START_ADDR", + "REQUEST_LENGTH", + "AUDIO_BUFFER_CONFIG", + "INQUIRY", + "BS_CHANGE_DISK", +}; + +void DVDDumpWaitingQueue(void) { + u32 i; + DVDCommandBlock* start; + DVDCommandBlock* q; + + OSReport("==== DVD Waiting Queue Status ====\n"); + for (i = 0; i < 4; i++) { + OSReport("< Queue #%d > ", i); + start = (DVDCommandBlock*)&WaitingQueue[i]; + if (start->next == start) { + OSReport("None\n"); + } else { + OSReport("\n"); + for (q = start->next; q != start; q = q->next) { + OSReport("0x%08x: Command: %s ", q, CommandNames[q->command]); + if (q->command == 1) { + OSReport("Disk offset: %d, Length: %d, Addr: 0x%08x\n", q->offset, q->length, q->addr); + } else { + OSReport("\n"); + } + } + } + } +} diff --git a/src/dolphin/dvd/fstload.c b/src/dolphin/dvd/fstload.c new file mode 100644 index 0000000..555517d --- /dev/null +++ b/src/dolphin/dvd/fstload.c @@ -0,0 +1,86 @@ +#include +#include +#include + +#include "__dvd.h" + +static u8 bb2Buf[63]; + +static u32 status; +static DVDBB2* bb2; +static DVDDiskID* idTmp; + +// prototypes +static void cb(s32 result, DVDCommandBlock* block); + +static void cb(s32 result, DVDCommandBlock* block) { + if (result > 0) { + switch(status) { + case 0: + status = 1; + DVDReadAbsAsyncForBS(block, bb2, 0x20, 0x420, cb); + return; + case 1: + status = 2; + DVDReadAbsAsyncForBS(block, bb2->FSTAddress, (bb2->FSTLength + 0x1F) & 0xFFFFFFE0, bb2->FSTPosition, cb); + default: + return; + } + } + + if (result == -1) { + return; + } else if (result == -4) { + status = 0; + DVDReset(); + DVDReadDiskID(block, idTmp, cb); + } +} + +void __fstLoad(void) { + OSBootInfo* bootInfo; + DVDDiskID* id; + u8 idTmpBuf[63]; + s32 state; + void* arenaHi; + static DVDCommandBlock block; + + arenaHi = OSGetArenaHi(); + bootInfo = (void*)OSPhysicalToCached(0); + idTmp = (void*)OSRoundUp32B(idTmpBuf); + bb2 = (void*)OSRoundUp32B(bb2Buf); + + DVDReset(); + DVDReadDiskID(&block, idTmp, cb); + + while (1) { + state = DVDGetDriveStatus(); + if (state == 0) { + break; + } + + // weird switch that seemingly wont do anything but break out of its own switch. What was this for? Early DVD development pre-hardware? + switch(state) { + case DVD_STATE_FATAL_ERROR: break; + case DVD_STATE_BUSY: break; + case DVD_STATE_WAITING: break; + case DVD_STATE_COVER_CLOSED: break; + case DVD_STATE_NO_DISK: break; + case DVD_STATE_COVER_OPEN: break; + case DVD_STATE_MOTOR_STOPPED: break; + } + } + + bootInfo->FSTLocation = (void*)bb2->FSTAddress; + bootInfo->FSTMaxLength = bb2->FSTMaxLength; + id = &bootInfo->DVDDiskID; + memcpy(id, idTmp, 0x20); + OSReport("\n"); + OSReport(" Game Name ... %c%c%c%c\n", id->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) ? "OFF" : "ON"); + OSReport("\n"); + OSSetArenaHi(bb2->FSTAddress); +} diff --git a/src/dolphin/exi/EXIAd16.c b/src/dolphin/exi/EXIAd16.c new file mode 100644 index 0000000..668dcaa --- /dev/null +++ b/src/dolphin/exi/EXIAd16.c @@ -0,0 +1,101 @@ +#include +#include + +static BOOL Initialized; + +int AD16Init(void) { + int err; + u32 cmd; + u32 id; + + if (Initialized) { + return 1; + } + + if (!EXILock(2, 0, NULL)) { + return 0; + } + + if (!EXISelect(2, 0, EXI_FREQ_1M)) { + EXIUnlock(2); + return 0; + } + + cmd = 0; + err = 0; + err |= !EXIImm(2, &cmd, 2, EXI_WRITE, NULL); + err |= !EXISync(2); + err |= !EXIImm(2, &id, 4, EXI_READ, NULL); + err |= !EXISync(2); + err |= !EXIDeselect(2); + + EXIUnlock(2); + if (err != 0 || (id - 0x04120000) != 0) { + return 0; + } + + Initialized = TRUE; + return 1; +} + +int AD16WriteReg(u32 word) { + int err; + u32 cmd; + + if (!Initialized || !EXILock(2, 0, NULL)) { + return 0; + } + + if (!EXISelect(2, 0, EXI_FREQ_8M)) { + EXIUnlock(2); + return 0; + } + + cmd = 0xA0000000; + err = 0; + err |= !EXIImm(2, &cmd, 1, EXI_WRITE, NULL); + err |= !EXISync(2); + err |= !EXIImm(2, &word, 4, EXI_WRITE, NULL); + err |= !EXISync(2); + err |= !EXIDeselect(2); + + EXIUnlock(2); + if (err != 0) { + return 0; + } + + return 1; +} + +int AD16ReadReg(u32* word) { + int err; + u32 cmd; + + if (!Initialized || !EXILock(2, 0, NULL)) { + return 0; + } + + if (!EXISelect(2, 0, EXI_FREQ_8M)) { + EXIUnlock(2); + return 0; + } + + cmd = 0xA2000000; + err = 0; + err |= !EXIImm(2, &cmd, 1, EXI_WRITE, NULL); + err |= !EXISync(2); + err |= !EXIImm(2, word, 4, EXI_READ, NULL); + err |= !EXISync(2); + err |= !EXIDeselect(2); + + EXIUnlock(2); + if (err != 0) { + return 0; + } + + return 1; +} + +BOOL AD16Probe(void) { + return Initialized; +} diff --git a/src/dolphin/exi/EXIBios.c b/src/dolphin/exi/EXIBios.c new file mode 100644 index 0000000..4f4465b --- /dev/null +++ b/src/dolphin/exi/EXIBios.c @@ -0,0 +1,870 @@ +#include + +#define REG_MAX 5 +#define REG(chan, idx) (__EXIRegs[((chan) * REG_MAX) + (idx)]) + +#define STATE_IDLE 0 +#define STATE_DMA 1 +#define STATE_IMM 2 +#define STATE_BUSY 3 +#define STATE_SELECTED 4 +#define STATE_ATTACHED 8 +#define STATE_LOCKED 16 + +#define MAX_CHAN 3 + +#define MAX_IMM 4 +#define MAX_TYPE 3 +#define MAX_DEV 3 +#define MAX_FREQ 6 + +#define EXI_0LENGTH_EXILENGTH_MASK 0x03FFFFE0 + +#if DEBUG +const char * __EXIVersion = "<< Dolphin SDK - EXI\tdebug build: Apr 5 2004 03:55:29 (0x2301) >>"; +#else +const char * __EXIVersion = "<< Dolphin SDK - EXI\trelease build: Apr 5 2004 04:14:14 (0x2301) >>"; +#endif + +static EXIControl Ecb[3]; +static u32 IDSerialPort1; + +// external functions +extern void __OSEnableBarnacle(s32 chan, u32 dev); + +// prototypes +u32 EXIClearInterrupts(s32 chan, int exi, int tc, int ext); +static int __EXIProbe(s32 chan); + +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; + u8* buf; + u32 data; + int i; + int len; + + exi = &Ecb[chan]; + ASSERTLINE(366, 0 <= chan && chan < MAX_CHAN); + + if (exi->state & STATE_BUSY) { + if (exi->state & STATE_IMM) { + if ((len = exi->immLen) != 0) { + buf = exi->immBuf; + data = __EXIRegs[(chan * 5) + 4]; + for(i = 0; i < len; i++) { + *buf++ = data >> ((3 - i) * 8); + } + } + } + exi->state &= ~STATE_BUSY; + } +} + +int EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { + EXIControl* exi; + BOOL enabled; + u32 data; + int i; + + exi = &Ecb[chan]; + ASSERTLINE(404, exi->state & STATE_SELECTED); + ASSERTLINE(405, 0 <= chan && chan < MAX_CHAN); + ASSERTLINE(406, 0 < len && len <= MAX_IMM); + ASSERTLINE(407, type < MAX_TYPE); + enabled = OSDisableInterrupts(); + + if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->tcCallback = callback; + if (exi->tcCallback) { + EXIClearInterrupts(chan, 0, 1, 0); + __OSUnmaskInterrupts(0x200000U >> (chan * 3)); + } + + exi->state |= STATE_IMM; + if (type != 0) { + data = 0; + for(i = 0; i < len; i++) { + data |= ((u8*)buf)[i] << ((3 - i) * 8); + } + __EXIRegs[(chan * 5) + 4] = data; + } + + exi->immBuf = buf; + exi->immLen = (type != 1) ? len : 0; + __EXIRegs[(chan * 5) + 3] = (type << 2) | 1 | ((len - 1) << 4); + OSRestoreInterrupts(enabled); + return 1; +} + +int EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) { + s32 xLen; + + while (len) { + xLen = (len < 4) ? len : 4; + if (EXIImm(chan, buf, xLen, mode, 0) == 0) { + return 0; + } + if (EXISync(chan) == 0) { + return 0; + } + ((u8*)buf) += xLen; + len -= xLen; + } + + return 1; +} + +int EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { + EXIControl* exi; + BOOL enabled; + + exi = &Ecb[chan]; + + ASSERTLINE(509, exi->state & STATE_SELECTED); + ASSERTLINE(510, OFFSET(buf, 32) == 0); + ASSERTLINE(511, 0 < len && OFFSET(len, 32) == 0); + ASSERTLINE(513, ((u32) len & ~EXI_0LENGTH_EXILENGTH_MASK) == 0); + ASSERTLINE(515, type == EXI_READ || type == EXI_WRITE); + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->tcCallback = callback; + if ((u32)exi->tcCallback) { + EXIClearInterrupts(chan, 0, 1, 0); + __OSUnmaskInterrupts(0x200000U >> (chan * 3)); + } + + exi->state |= STATE_DMA; + __EXIRegs[(chan * 5) + 1] = (u32)buf & EXI_0LENGTH_EXILENGTH_MASK; + __EXIRegs[(chan * 5) + 2] = len; + __EXIRegs[(chan * 5) + 3] = (type * 4) | 3; + + OSRestoreInterrupts(enabled); + return 1; +} + +int EXISync(s32 chan) { + EXIControl* exi; + int rc; + BOOL enabled; + + exi = &Ecb[chan]; + rc = 0; + ASSERTLINE(565, 0 <= chan && chan < MAX_CHAN); + + while ((exi->state & STATE_SELECTED)) { + if (!(__EXIRegs[(chan * 5) + 3] & 1)) { + enabled = OSDisableInterrupts(); + if (exi->state & STATE_SELECTED) { + CompleteTransfer(chan); + if (__OSGetDIConfig() != 0xFF || (OSGetConsoleType() & 0xf0000000) == 0x20000000 || exi->immLen != 4 || (__EXIRegs[chan * 5] & 0x70) || (__EXIRegs[(chan * 5) + 4] != 0x01010000 && __EXIRegs[(chan * 5) + 4] != 0x05070000 && __EXIRegs[(chan * 5) + 4] != 0x04220001) || __OSDeviceCode == 0x8200) { + rc = 1; + } + } + OSRestoreInterrupts(enabled); + break; + } + } + + ASSERTLINE(593, !(exi->state & STATE_BUSY)); + return rc; +} + +u32 EXIClearInterrupts(s32 chan, int exi, int tc, int ext) { + u32 cpr; + u32 prev; + + ASSERTLINE(614, 0 <= chan && chan < MAX_CHAN); + + cpr = prev = __EXIRegs[(chan * 5)]; + prev &= 0x7F5; + + if (exi != 0) { + prev |= 2; + } + + if (tc != 0) { + prev |= 8; + } + + if (ext != 0) { + prev |= 0x800; + } + + __EXIRegs[(chan * 5)] = prev; + return cpr; +} + +EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) { + EXIControl* exi; + EXICallback prev; + BOOL enabled; + + exi = &Ecb[chan]; + ASSERTLINE(648, 0 <= chan && chan < MAX_CHAN); + enabled = OSDisableInterrupts(); + + prev = exi->exiCallback; + exi->exiCallback = exiCallback; + if (chan != 2) { + SetExiInterruptMask(chan, exi); + } else { + SetExiInterruptMask(0, &Ecb[0]); + } + + OSRestoreInterrupts(enabled); + return prev; +} + +void EXIProbeReset() { + __gUnknown800030C0[0] = __gUnknown800030C0[1] = 0; + Ecb[0].idTime = Ecb[1].idTime = 0; + __EXIProbe(0); + __EXIProbe(1); +} + +static int __EXIProbe(s32 chan) { + EXIControl* exi; + BOOL enabled; + int rc; + u32 cpr; + s32 t; + + exi = &Ecb[chan]; + ASSERTLINE(703, 0 <= chan && chan < MAX_CHAN); + if (chan == 2) { + return 1; + } + + rc = 1; + enabled = OSDisableInterrupts(); + cpr = __EXIRegs[(chan * 5)]; + + if (!(exi->state & STATE_ATTACHED)) { + if (cpr & 0x800) { + EXIClearInterrupts(chan, 0, 0, 1); + __gUnknown800030C0[chan] = exi->idTime = 0; + } + + if (cpr & 0x1000) { + t = ((s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1); + + if (__gUnknown800030C0[chan] == 0) { + __gUnknown800030C0[chan] = t; + } + + if (t - (s32)__gUnknown800030C0[chan] < 3) { + rc = 0; + } + } else { + __gUnknown800030C0[chan] = exi->idTime = 0; + rc = 0; + } + } else if(!(cpr & 0x1000) || (cpr & 0x800)) { + __gUnknown800030C0[chan] = exi->idTime = 0; + rc = 0; + } + + OSRestoreInterrupts(enabled); + return rc; +} + +int EXIProbe(s32 chan) { + EXIControl* exi = &Ecb[chan]; + int rc; + u32 id; + + rc = __EXIProbe(chan); + if (rc && !exi->idTime) { + rc = EXIGetID(chan, 0, &id) ? 1 : 0; + } + + return rc; +} + +s32 EXIProbeEx(s32 chan) { + if (EXIProbe(chan)) { + return 1; + } + + if (__gUnknown800030C0[chan]) { + return 0; + } + + return -1; +} + +static int __EXIAttach(s32 chan, EXICallback extCallback) { + EXIControl* exi; + BOOL enabled; + + exi = &Ecb[chan]; + ASSERTLINE(808, 0 <= chan && chan < 2); + enabled = OSDisableInterrupts(); + + if ((exi->state & STATE_ATTACHED) || !__EXIProbe(chan)) { + OSRestoreInterrupts(enabled); + return 0; + } + + EXIClearInterrupts(chan, 1, 0, 0); + exi->extCallback = extCallback; + __OSUnmaskInterrupts(0x100000U >> (chan * 3)); + exi->state |= STATE_ATTACHED; + + OSRestoreInterrupts(enabled); + return 1; +} + +int EXIAttach(s32 chan, EXICallback extCallback) { + EXIControl* exi; + BOOL enabled; + int rc; + + exi = &Ecb[chan]; + ASSERTLINE(834, 0 <= chan && chan < 2); + + EXIProbe(chan); + enabled = OSDisableInterrupts(); + if (exi->idTime == 0) { + OSRestoreInterrupts(enabled); + return 0; + } + + rc = __EXIAttach(chan, extCallback); + OSRestoreInterrupts(enabled); + return rc; +} + +int EXIDetach(s32 chan) { + EXIControl* exi; + BOOL enabled; + + exi = &Ecb[chan]; + ASSERTLINE(868, 0 <= chan && chan < 2); + enabled = OSDisableInterrupts(); + + if (!(exi->state & STATE_ATTACHED)) { + OSRestoreInterrupts(enabled); + return 1; + } + + if ((exi->state & STATE_LOCKED) && (exi->dev == 0)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state &= ~STATE_ATTACHED; + __OSMaskInterrupts(0x500000U >> (chan * 3)); + + OSRestoreInterrupts(enabled); + return 1; +} + +int EXISelectSD(s32 chan, u32 dev, u32 freq) { + EXIControl* exi; + u32 cpr; + BOOL enabled; + + exi = &Ecb[chan]; + + ASSERTLINE(908, 0 <= chan && chan < MAX_CHAN); + ASSERTLINE(909, chan == 0 && dev < MAX_DEV || dev == 0); + ASSERTLINE(910, freq < MAX_FREQ); + ASSERTLINE(911, !(exi->state & STATE_SELECTED)); + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_SELECTED) || ((chan != 2) && (((dev == 0) && !(exi->state & STATE_ATTACHED) && (EXIProbe(chan) == 0)) || !(exi->state & STATE_LOCKED) || (exi->dev != dev)))) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state |= STATE_SELECTED; + cpr = __EXIRegs[(chan * 5)]; + cpr &= 0x405; + cpr |= freq * 0x10; + __EXIRegs[(chan * 5)] = cpr; + + if (exi->state & STATE_ATTACHED) { + switch (chan) { + case 0: + __OSMaskInterrupts(0x100000U); + break; + case 1: + __OSMaskInterrupts(0x20000U); + break; + } + } + + OSRestoreInterrupts(enabled); + return 1; +} + +int EXISelect(s32 chan, u32 dev, u32 freq) { + EXIControl* exi; + u32 cpr; + BOOL enabled; + + exi = &Ecb[chan]; + + ASSERTLINE(966, 0 <= chan && chan < MAX_CHAN); + ASSERTLINE(967, chan == 0 && dev < MAX_DEV || dev == 0); + ASSERTLINE(968, freq < MAX_FREQ); + ASSERTLINE(969, !(exi->state & STATE_SELECTED)); + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_SELECTED) || ((chan != 2) && (((dev == 0) && !(exi->state & STATE_ATTACHED) && (__EXIProbe(chan) == 0)) || !(exi->state & STATE_LOCKED) || (exi->dev != dev)))) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state |= STATE_SELECTED; + cpr = __EXIRegs[(chan * 5)]; + cpr &= 0x405; + cpr |= (((1 << dev) << 7) | (freq * 0x10)); + __EXIRegs[(chan * 5)] = cpr; + + if (exi->state & STATE_ATTACHED) { + switch (chan) { + case 0: + __OSMaskInterrupts(0x100000U); + break; + case 1: + __OSMaskInterrupts(0x20000U); + break; + } + } + + OSRestoreInterrupts(enabled); + return 1; +} + +int EXIDeselect(s32 chan) { + EXIControl* exi; + u32 cpr; + BOOL enabled; + + exi = &Ecb[chan]; + ASSERTLINE(1020, 0 <= chan && chan < MAX_CHAN); + enabled = OSDisableInterrupts(); + + if (!(exi->state & STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state &= ~STATE_SELECTED; + cpr = __EXIRegs[(chan * 5)]; + __EXIRegs[(chan * 5)] = cpr & 0x405; + + if (exi->state & STATE_ATTACHED) { + switch (chan) { + case 0: + __OSUnmaskInterrupts(0x100000U); + break; + case 1: + __OSUnmaskInterrupts(0x20000U); + break; + } + } + + OSRestoreInterrupts(enabled); + + if ((chan != 2) && (cpr & 0x80)) { + if (__EXIProbe(chan) != 0) { + return 1; + } + return 0; + } + + return 1; +} + +static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { + s32 chan; + EXIControl* exi; + EXICallback callback; + + chan = (interrupt - 9) / 3; + + ASSERTLINE(1071, 0 <= chan && chan < MAX_CHAN); + exi = &Ecb[chan]; + EXIClearInterrupts(chan, 1, 0, 0); + + 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) { + s32 chan; + EXIControl* exi; + EXICallback callback; + + chan = (interrupt - 10) / 3; + + ASSERTLINE(1107, 0 <= chan && chan < MAX_CHAN); + exi = &Ecb[chan]; + __OSMaskInterrupts(0x80000000U >> interrupt); + EXIClearInterrupts(chan, 0, 1, 0); + + callback = exi->tcCallback; + if (callback) { + OSContext exceptionContext; + + exi->tcCallback = NULL; + 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 - 11) / 3; + + ASSERTLINE(1147, 0 <= chan && chan < 2); + __OSMaskInterrupts(0x500000U >> (chan * 3)); + exi = &Ecb[chan]; + callback = exi->extCallback; + exi->state &= ~STATE_ATTACHED; + + if (callback) { + OSContext exceptionContext; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + exi->extCallback = NULL; + callback(chan, context); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +void EXIInit() { + u32 id; + + while (((REG(0, 3) & 1) == 1) || ((REG(1, 3) & 1) == 1) || ((REG(2, 3) & 1) == 1)) {} + + __OSMaskInterrupts(0x7F8000U); + __EXIRegs[0] = 0; + __EXIRegs[5] = 0; + __EXIRegs[10] = 0; + __EXIRegs[0] = 0x2000; + __OSSetInterruptHandler(9, EXIIntrruptHandler); + __OSSetInterruptHandler(10, TCIntrruptHandler); + __OSSetInterruptHandler(11, EXTIntrruptHandler); + __OSSetInterruptHandler(12, EXIIntrruptHandler); + __OSSetInterruptHandler(13, TCIntrruptHandler); + __OSSetInterruptHandler(14, EXTIntrruptHandler); + __OSSetInterruptHandler(15, EXIIntrruptHandler); + __OSSetInterruptHandler(16, TCIntrruptHandler); + + EXIGetID(0, 2, &IDSerialPort1); + + if (__OSInIPL) { + EXIProbeReset(); + } else if (EXIGetID(0, 0, &id) && id == 0x7010000) { + __OSEnableBarnacle(1, 0); + } else if (EXIGetID(1, 0, &id) && id == 0x7010000) { + __OSEnableBarnacle(0, 2); + } + + OSRegisterVersion(__EXIVersion); +} + +int EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) { + EXIControl* exi; + BOOL enabled; + int i; + + exi = &Ecb[chan]; + ASSERTLINE(1259, 0 <= chan && chan < MAX_CHAN); + ASSERTLINE(1260, chan == 0 && dev < MAX_DEV || dev == 0); + enabled = OSDisableInterrupts(); + + if (exi->state & STATE_LOCKED) { + if (unlockedCallback) { + ASSERTLINE(1266, chan == 0 && exi->items < (MAX_DEV - 1) || exi->items == 0); + for(i = 0; i < exi->items; i++) { + if (exi->queue[i].dev == dev) { + OSRestoreInterrupts(enabled); + return 0; + } + } + exi->queue[exi->items].callback = unlockedCallback; + exi->queue[exi->items].dev = dev; + exi->items++; + } + OSRestoreInterrupts(enabled); + return 0; + } + + ASSERTLINE(1282, exi->items == 0); + exi->state |= STATE_LOCKED; + exi->dev = dev; + SetExiInterruptMask(chan, exi); + OSRestoreInterrupts(enabled); + return 1; +} + +int EXIUnlock(s32 chan) { + EXIControl* exi; + BOOL enabled; + EXICallback unlockedCallback; + + exi = &Ecb[chan]; + ASSERTLINE(1306, 0 <= chan && chan < MAX_CHAN); + enabled = OSDisableInterrupts(); + + if (!(exi->state & STATE_LOCKED)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state &= ~STATE_LOCKED; + SetExiInterruptMask(chan, exi); + if (exi->items > 0) { + unlockedCallback = exi->queue[0].callback; + if (--exi->items > 0) { + memmove(&exi->queue[0], &exi->queue[1], exi->items * 8); + } + unlockedCallback(chan, 0); + } + + OSRestoreInterrupts(enabled); + return 1; +} + +u32 EXIGetState(s32 chan) { + EXIControl* exi; + + exi = &Ecb[chan]; + ASSERTLINE(1343, 0 <= chan && chan < MAX_CHAN); + return 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]; + int err; + u32 cmd; + s32 startTime; + BOOL enabled; + + ASSERTLINE(1380, 0 <= chan && chan < MAX_CHAN); + if (chan == 0 && dev == 2 && IDSerialPort1 != 0) { + *id = IDSerialPort1; + return 1; + } + + if ((chan < 2) && (dev == 0)) { + if ((__EXIProbe(chan) == 0)) { + return 0; + } + + if (exi->idTime == __gUnknown800030C0[chan]) { + *id = exi->id; + return exi->idTime; + } + + if (!__EXIAttach(chan, NULL)) { + return 0; + } + + startTime = __gUnknown800030C0[chan]; + } + + enabled = OSDisableInterrupts(); + + err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? &UnlockedHandler : NULL); + if (err == 0) { + err = !EXISelect(chan, dev, 0); + if (err == 0) { + cmd = 0; + err |= !EXIImm(chan, &cmd, 2, 1, 0); + err |= !EXISync(chan); + err |= !EXIImm(chan, id, 4, 0, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + } + + EXIUnlock(chan); + } + + OSRestoreInterrupts(enabled); + + if ((chan < 2) && (dev == 0)) { + EXIDetach(chan); + enabled = OSDisableInterrupts(); + err |= __gUnknown800030C0[chan] != startTime; + + if (!err) { + exi->id = *id; + exi->idTime = startTime; + } + + OSRestoreInterrupts(enabled); + + if (err) { + return 0; + } + + return exi->idTime; + } + + if (err) { + return 0; + } + + return 1; +} + +s32 EXIGetType(s32 chan, u32 dev, u32* type) { + u32 _type; + s32 probe; + + probe = EXIGetID(chan, dev, &_type); + + if (!probe) { + return probe; + } + + switch (_type & ~0xFF) { + case 0x04020300: + case EXI_ETHER: + case 0x04020100: + case EXI_MIC: + *type = (_type & ~0xFF); + return probe; + default: + switch (_type & ~0xFFFF) { + case 0x00000000: + if (!(_type & 0x3803)) { + switch (_type & 0xFC) { + case EXI_MEMORY_CARD_59: + case EXI_MEMORY_CARD_123: + case EXI_MEMORY_CARD_251: + case EXI_MEMORY_CARD_507: + case EXI_MEMORY_CARD_1019: + case EXI_MEMORY_CARD_2043: + *type = _type & 0xFC; + return probe; + } + } + break; + case EXI_IS_VIEWER: + *type = EXI_IS_VIEWER; + return probe; + } + + *type = _type; + return probe; + } +} + +char* EXIGetTypeString(u32 type) { + 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 EXI_NPDP_GDEV: + return "GDEV"; + case EXI_MODEM: + return "Modem"; + case EXI_MARLIN: + return "Marlin"; + case EXI_AD16: + return "AD16"; + case EXI_RS232C: + return "RS232C"; + case 0x80000020: + case 0x80000080: + case 0x80000040: + case 0x80000008: + case 0x80000010: + case 0x80000004: + return "Net Card"; + case EXI_ETHER_VIEWER: + return "Artist Ether"; + case 0x4020100: + case 0x4020300: + case EXI_ETHER: + case 0x4220000: + return "Broadband Adapter"; + case EXI_MIC: + return "Mic"; + case EXI_STREAM_HANGER: + return "Stream Hanger"; + case EXI_IS_VIEWER: + return "IS-DOL-VIEWER"; + default: + return "Unknown"; + } +} diff --git a/src/dolphin/exi/EXIUart.c b/src/dolphin/exi/EXIUart.c new file mode 100644 index 0000000..2d5c868 --- /dev/null +++ b/src/dolphin/exi/EXIUart.c @@ -0,0 +1,194 @@ +#include +#include +#include "__os.h" + +static s32 Chan; +static u32 Dev; +static u32 Enabled; +static u32 BarnacleEnabled; + +// prototypes +int InitializeUART(void); +int ReadUARTN(void); +int WriteUARTN(void *buf, u32 len); +void __OSEnableBarnacle(s32 chan, u32 dev); + +static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) { + int 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, sizeof(cmd), EXI_WRITE, NULL); + err |= !EXISync(chan); + err |= !EXIImm(chan, revision, sizeof(revision), EXI_READ, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + } + + EXIUnlock(chan); + } + + if (chan != 2 && dev == 0) { + EXIDetach(chan); + } + + if (err) { + return FALSE; + } + + if (*revision != 0xFFFFFFFF) { + return TRUE; + } + + return FALSE; +} + +void __OSEnableBarnacle(s32 chan, u32 dev) { + u32 id; + + if (!EXIGetID(chan, dev, &id)) { + return; + } + + switch (id) { + case EXI_MEMORY_CARD_59: + case EXI_MEMORY_CARD_123: + case EXI_MEMORY_CARD_251: + case EXI_MEMORY_CARD_507: + case EXI_USB_ADAPTER: + case EXI_NPDP_GDEV: + case EXI_MODEM: + case 0x03010000: + case 0x04020100: + case EXI_ETHER: + case 0x04020300: + case 0x04220000: + case EXI_RS232C: + case EXI_MIC: + case EXI_AD16: + case EXI_STREAM_HANGER: + case 0x80000004: + case 0x80000008: + case 0x80000010: + case 0x80000020: + case 0xFFFFFFFF: + break; + default: + if (ProbeBarnacle(chan, dev, &id)) { + Chan = chan; + Dev = dev; + Enabled = BarnacleEnabled = 0xA5FF005A; + break; + } + } +} + +int InitializeUART(void) { + if (BarnacleEnabled == 0xA5FF005A) { + return 0; + } + + if ((OSGetConsoleType() & 0x10000000) == 0) { + Enabled = 0; + return 2; + } + + Chan = 0; + Dev = 1; + Enabled = 0xA5FF005A; + return 0; +} + +int ReadUARTN(void) { + return 4; +} + +static int QueueLength(void) { + u32 cmd; + + if (EXISelect(Chan, Dev, 3) == 0) { + return -1; + } + + cmd = 0x20010000; + EXIImm(Chan, &cmd, sizeof(cmd), EXI_WRITE, 0); + EXISync(Chan); + EXIImm(Chan, &cmd, 1, EXI_READ, 0); + EXISync(Chan); + EXIDeselect(Chan); + return 0x10 - (cmd >> 0x18); +} + +int WriteUARTN(void *buf, u32 len) { + u32 cmd; + s32 xLen; + int qLen; + char* ptr; + int locked; + int error; + + if ((Enabled - 0xA5FF0000) != 0x5A) { + return 2; + } + + locked = EXILock(Chan, Dev, 0); + if (locked == 0) { + return 0; + } else { + ptr = (char*)buf; + } + + while ((u32)ptr - (u32)buf < len) { + if (*(s8*)ptr == 0xA) { + *ptr = 0xD; + } + ptr++; + } + error = 0; + cmd = 0xA0010000; + + while (len != 0) { + qLen = QueueLength(); + if (qLen < 0) { + error = 3; + break; + } + + if ((qLen >= 0xC) || (qLen >= len)) { + if (EXISelect(Chan, Dev, EXI_FREQ_8M) == 0) { + error = 3; + break; + } + + EXIImm(Chan, &cmd, sizeof(cmd), EXI_WRITE, 0); + EXISync(Chan); + + while((qLen != 0) && (len != 0)) { + if ((qLen < 4) && (qLen < len)) { + break; + } + + xLen = len < 4 ? (long)len : 4; + + EXIImm(Chan, buf, xLen, EXI_WRITE, 0); + (char*)buf += xLen; + len -= xLen; + qLen -= xLen; + EXISync(Chan); + } + EXIDeselect(Chan); + } + } + + EXIUnlock(Chan); + return error; +} diff --git a/src/dolphin/fileCache/fileCache.c b/src/dolphin/fileCache/fileCache.c new file mode 100644 index 0000000..36151f4 --- /dev/null +++ b/src/dolphin/fileCache/fileCache.c @@ -0,0 +1,145 @@ +#include +#include + +DSCache DODisplayCache; +u8 DOCacheInitialized; + +static u8 AllocCacheNode(DSCacheNodePtr* cacheNode, char* name); +static void FreeCacheNode(DSCacheNodePtr* cacheNode); + +DSCacheNodePtr DSAddCacheNode(DSCachePtr cache, char* name, Ptr data, Ptr OSFreeFunc) { + DSCacheNodePtr cacheNode; + + cacheNode = NULL; + if (!AllocCacheNode(&cacheNode, name)) { + return NULL; + } + Strcpy(cacheNode->Name, name); + cacheNode->Data = data; + cacheNode->Free = (void (*)(Ptr *))OSFreeFunc; + cacheNode->ReferenceCount = 0; + DSInsertListObject(&cache->CacheNodeList, NULL, (Ptr)cacheNode); + return cacheNode; +} + +static u8 AllocCacheNode(DSCacheNodePtr* cacheNode, char* name) { + if (*cacheNode) { + FreeCacheNode(cacheNode); + } + + *cacheNode = OSAlloc(sizeof(DSCacheNode)); + if (!*cacheNode) { + return FALSE; + } + + (*cacheNode)->Name = OSAlloc(Strlen(name) + 1); + if (!(*cacheNode)->Name) { + return FALSE; + } + + return TRUE; +} + +void DSEmptyCache(DSCachePtr cache) { + DSCacheNodePtr cursor; + DSCacheNodePtr cacheNode; + + cursor = (DSCacheNodePtr)cache->CacheNodeList.Head; + while (cursor) { + cacheNode = cursor; + cursor = (DSCacheNodePtr)cursor->Link.Next; + DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); + FreeCacheNode(&cacheNode); + } +} + +static DSCacheNodePtr FindCacheNode(DSCachePtr cache, char* name, Ptr data) { + DSCacheNodePtr cacheNode; + + cacheNode = (DSCacheNodePtr)cache->CacheNodeList.Head; + if (data) { + while (cacheNode) { + if (data == cacheNode->Data) { + return cacheNode; + } + cacheNode = (DSCacheNodePtr)cacheNode->Link.Next; + } + } else if (name) { + while (cacheNode) { + if (Strcmp(name, cacheNode->Name) == 0) { + return cacheNode; + } + cacheNode = (DSCacheNodePtr)cacheNode->Link.Next; + } + } + return NULL; +} + +Ptr DSGetCacheObj(DSCachePtr cache, char* name) { + DSCacheNodePtr cacheNode; + + cacheNode = FindCacheNode(cache, name, NULL); + if (cacheNode) { + cacheNode->ReferenceCount++; + return cacheNode->Data; + } + return NULL; +} + +static void FreeCacheNode(DSCacheNodePtr* cacheNode) { + if (*cacheNode) { + if ((*cacheNode)->Free) { + (*cacheNode)->Free(&(*cacheNode)->Data); + } + OSFree((*cacheNode)->Name); + OSFree(*cacheNode); + *cacheNode = NULL; + } +} + +void DSInitCache(DSCachePtr cache) { + DSCacheNode cacheNode; + + cache->PurgeFlag = DS_AUTO_PURGE; + DSInitList(&cache->CacheNodeList, (Ptr)&cacheNode, &cacheNode.Link); +} + +void DSPurgeCache(DSCachePtr cache) { + DSCacheNodePtr cursor; + DSCacheNodePtr cacheNode; + + cursor = (DSCacheNodePtr)cache->CacheNodeList.Head; + while (cursor) { + cacheNode = cursor; + cursor = (DSCacheNodePtr)cursor->Link.Next; + if (cacheNode->ReferenceCount == 0) { + DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); + FreeCacheNode(&cacheNode); + } + } +} + +void DSReleaseCacheObj(DSCachePtr cache, Ptr data) { + DSCacheNodePtr cacheNode; + + cacheNode = FindCacheNode(cache, NULL, data); + if (cacheNode) { + if (cacheNode->ReferenceCount != 0) { + cacheNode->ReferenceCount--; + } + + if (cacheNode->ReferenceCount == 0 && cache->PurgeFlag == DS_AUTO_PURGE) { + DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); + FreeCacheNode(&cacheNode); + } + } +} + +void DSSetCachePurgeFlag(DSCachePtr cache, u8 purgeFlag) { + cache->PurgeFlag = purgeFlag; +} + +void CSHInitDisplayCache(void) { + DSInitCache(&DODisplayCache); + DOCacheInitialized = TRUE; +} diff --git a/src/dolphin/gd/GDBase.c b/src/dolphin/gd/GDBase.c new file mode 100644 index 0000000..a21e0d6 --- /dev/null +++ b/src/dolphin/gd/GDBase.c @@ -0,0 +1,45 @@ +#include +#include + +GDLObj* __GDCurrentDL = NULL; +static GDOverflowCb overflowcb = NULL; + +void GDInitGDLObj(GDLObj* dl, void* start, u32 length) { + ASSERTMSGLINE(40, !((u32)start & 0x1F), "start must be aligned to 32 bytes"); + ASSERTMSGLINE(41, !((u32)length & 0x1F), "length must be aligned to 32 bytes"); + dl->start = start; + dl->ptr = start; + dl->top = (u8*)start + length; + dl->length = length; +} + +void GDFlushCurrToMem(void) { + DCFlushRange(__GDCurrentDL->start, __GDCurrentDL->length); +} + +void GDPadCurr32(void) { + u32 n; + + n = (u32)__GDCurrentDL->ptr & 0x1F; + if (n != 0) { + for (; n < 32; n = n + 1) { + __GDWrite(0); + } + } +} + +void GDOverflowed(void) { + if (overflowcb) { + (*overflowcb)(); + } else { + ASSERTMSGLINE(77, 0, "GDWrite: display list overflowed"); + } +} + +void GDSetOverflowCallback(GDOverflowCb callback) { + overflowcb = callback; +} + +GDOverflowCb GDGetOverflowCallback(void) { + return overflowcb; +} diff --git a/src/dolphin/gd/GDFile.c b/src/dolphin/gd/GDFile.c new file mode 100644 index 0000000..47ec3af --- /dev/null +++ b/src/dolphin/gd/GDFile.c @@ -0,0 +1,64 @@ +#include +#include + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +s32 GDReadDLFile(const char* fName, u32* numDLs, u32* numPLs, GDGList** DLDescArray, GDGList** PLDescArray) { + DVDFileInfo finfo; + u32 length; + u32 i; + u8* buf; + GDFileHeader* hdr; + + *numDLs = *numPLs = 0; + *DLDescArray = *PLDescArray = NULL; + + if (!DVDOpen(fName, &finfo)) { + OSReport("Can't open file %s\n", fName); + return -3; + } + + length = finfo.length; + + if (NULL == (buf = OSAlloc(ROUND(length, 0x20)))) { + OSReport("Alloc failed\n"); + DVDClose(&finfo); + return -5; + } + + if (DVDReadPrio(&finfo, buf, ROUND(length, 0x20), 0, 2) != ROUND(length, 0x20)) { + OSReport("Error occurred when reading %s\n", fName); + DVDClose(&finfo); + OSFree(buf); + return -2; + } + + DVDClose(&finfo); + + hdr = (GDFileHeader*)buf; + + if (hdr->versionNumber != GD_FILE_VERSION_NUMBER) { + OSReport("Bad version number for GDL file %s\n", fName); + OSFree(buf); + return -4; + } + + *numDLs = hdr->numDLs; + *numPLs = hdr->numPLs; + + // Loaded pointers are relative to disc start, remap + // them to be relative to RAM start + *DLDescArray = (GDGList*)((u32)hdr->DLDescArray + (u32)hdr); + *PLDescArray = (GDGList*)((u32)hdr->PLDescArray + (u32)hdr); + + // And internal pointers too + for (i = 0; i < *numDLs; ++i) { + (*DLDescArray)[i].ptr = (void*)((u32)hdr + (u32)(*DLDescArray)[i].ptr); + } + + for (i = 0; i < *numPLs; ++i) { + (*PLDescArray)[i].ptr = (void*)((u32)hdr + (u32)(*PLDescArray)[i].ptr); + } + + return 0; +} diff --git a/src/dolphin/gd/GDGeometry.c b/src/dolphin/gd/GDGeometry.c new file mode 100644 index 0000000..967acb7 --- /dev/null +++ b/src/dolphin/gd/GDGeometry.c @@ -0,0 +1,430 @@ +#include +#include + +void GDSetVtxDescv(const GXVtxDescList* attrPtr) { + u32 nnorms = 0; + u32 ncols = 0; + u32 ntexs = 0; + u32 pnMtxIdx = GX_NONE; + u32 txMtxIdxMask = 0; + u32 posn = GX_DIRECT; + u32 norm = GX_NONE; + u32 col0 = GX_NONE; + u32 col1 = GX_NONE; + u32 tex0 = GX_NONE; + u32 tex1 = GX_NONE; + u32 tex2 = GX_NONE; + u32 tex3 = GX_NONE; + u32 tex4 = GX_NONE; + u32 tex5 = GX_NONE; + u32 tex6 = GX_NONE; + u32 tex7 = GX_NONE; + + for (; attrPtr->attr != GX_VA_NULL; ++attrPtr) { + ASSERTMSGLINE(91, attrPtr->attr >= GX_VA_PNMTXIDX && attrPtr->attr <= GX_VA_MAX_ATTR, "GDSetVtxDescv: invalid attribute"); + ASSERTMSGLINE(95, attrPtr->type >= GX_NONE && attrPtr->type <= GX_INDEX16, "GDSetVtxDescv: invalid type"); + + ASSERTMSGLINE(101, attrPtr->attr >= GX_VA_PNMTXIDX && attrPtr->attr <= GX_VA_TEX7MTXIDX ? (attrPtr->type == 0 || attrPtr->type == 1) : TRUE, "GDSetVtxDescv: invalid type for given attribute"); + + switch (attrPtr->attr) { + case GX_VA_PNMTXIDX: + pnMtxIdx = attrPtr->type; + break; + case GX_VA_TEX0MTXIDX: + txMtxIdxMask = (txMtxIdxMask & ~0x1) | (attrPtr->type << 0); + break; + case GX_VA_TEX1MTXIDX: + txMtxIdxMask = (txMtxIdxMask & ~0x2) | (attrPtr->type << 1); + break; + case GX_VA_TEX2MTXIDX: + txMtxIdxMask = (txMtxIdxMask & ~0x4) | (attrPtr->type << 2); + break; + case GX_VA_TEX3MTXIDX: + txMtxIdxMask = (txMtxIdxMask & ~0x8) | (attrPtr->type << 3); + break; + case GX_VA_TEX4MTXIDX: + txMtxIdxMask = (txMtxIdxMask & ~0x10) | (attrPtr->type << 4); + break; + case GX_VA_TEX5MTXIDX: + txMtxIdxMask = (txMtxIdxMask & ~0x20) | (attrPtr->type << 5); + break; + case GX_VA_TEX6MTXIDX: + txMtxIdxMask = (txMtxIdxMask & ~0x40) | (attrPtr->type << 6); + break; + case GX_VA_TEX7MTXIDX: + txMtxIdxMask = (txMtxIdxMask & ~0x80) | (attrPtr->type << 7); + break; + case GX_VA_POS: + posn = attrPtr->type; + break; + case GX_VA_NRM: + if (attrPtr->type != GX_NONE) { + norm = attrPtr->type; + nnorms = 1; + } + break; + case GX_VA_NBT: + if (attrPtr->type != GX_NONE) { + norm = attrPtr->type; + nnorms = 2; + } + break; + case GX_VA_CLR0: + col0 = attrPtr->type; + ncols += (col0 != GX_NONE); + break; + case GX_VA_CLR1: + col1 = attrPtr->type; + ncols += (col1 != GX_NONE); + break; + case GX_VA_TEX0: + tex0 = attrPtr->type; + ntexs += (tex0 != GX_NONE); + break; + case GX_VA_TEX1: + tex1 = attrPtr->type; + ntexs += (tex1 != GX_NONE); + break; + case GX_VA_TEX2: + tex2 = attrPtr->type; + ntexs += (tex2 != GX_NONE); + break; + case GX_VA_TEX3: + tex3 = attrPtr->type; + ntexs += (tex3 != GX_NONE); + break; + case GX_VA_TEX4: + tex4 = attrPtr->type; + ntexs += (tex4 != GX_NONE); + break; + case GX_VA_TEX5: + tex5 = attrPtr->type; + ntexs += (tex5 != GX_NONE); + break; + case GX_VA_TEX6: + tex6 = attrPtr->type; + ntexs += (tex6 != GX_NONE); + break; + case GX_VA_TEX7: + tex7 = attrPtr->type; + ntexs += (tex7 != GX_NONE); + break; + } + } + + GDWriteCPCmd(CP_REG_VCD_LO_ID, CP_REG_VCD_LO(pnMtxIdx, txMtxIdxMask, posn, norm, col0, col1)); + GDWriteCPCmd(CP_REG_VCD_HI_ID, CP_REG_VCD_HI(tex0, tex1, tex2, tex3, tex4, tex5, tex6, tex7)); + GDWriteXFCmd(XF_REG_INVERTEXSPEC_ID, XF_REG_INVTXSPEC(ncols, nnorms, ntexs)); +} + +void GDSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list) { + u32 posCnt = GX_POS_XYZ; + u32 posType = GX_F32; + u32 posFrac = 0; + + u32 nrmCnt = GX_NRM_XYZ; + u32 nrmType = GX_F32; + u32 nrmIdx3 = 0; + + u32 c0Cnt = GX_CLR_RGBA; + u32 c0Type = GX_RGBA8; + + u32 c1Cnt = GX_CLR_RGBA; + u32 c1Type = GX_RGBA8; + + u32 tx0Cnt = GX_TEX_ST; + u32 tx0Type = GX_F32; + u32 tx0Frac = 0; + + u32 tx1Cnt = GX_TEX_ST; + u32 tx1Type = GX_F32; + u32 tx1Frac = 0; + + u32 tx2Cnt = GX_TEX_ST; + u32 tx2Type = GX_F32; + u32 tx2Frac = 0; + + u32 tx3Cnt = GX_TEX_ST; + u32 tx3Type = GX_F32; + u32 tx3Frac = 0; + + u32 tx4Cnt = GX_TEX_ST; + u32 tx4Type = GX_F32; + u32 tx4Frac = 0; + + u32 tx5Cnt = GX_TEX_ST; + u32 tx5Type = GX_F32; + u32 tx5Frac = 0; + + u32 tx6Cnt = GX_TEX_ST; + u32 tx6Type = GX_F32; + u32 tx6Frac = 0; + + u32 tx7Cnt = GX_TEX_ST; + u32 tx7Type = GX_F32; + u32 tx7Frac = 0; + + ASSERTMSGLINE(221, vtxfmt < GX_MAX_VTXFMT, "GDSetVtxAttrFmtv: invalid vtx fmt"); + + for (; list->attr != GX_VA_NULL; ++list) { + ASSERTMSGLINE(226, list->attr >= GX_VA_POS && list->attr <= GX_VA_TEX7, "GDSetVtxAttrFmtv: invalid attribute"); + ASSERTMSGLINE(227, list->frac < 32, "GDSetVtxAttrFmtv: invalid frac value"); + + switch (list->attr) { + case GX_VA_POS: + posCnt = list->cnt; + posType = list->type; + posFrac = list->frac; + break; + case GX_VA_NRM: + case GX_VA_NBT: + nrmType = list->type; + if (list->cnt == GX_NRM_NBT3) { + nrmCnt = GX_NRM_NBT; + nrmIdx3 = 1; + } else { + nrmCnt = list->cnt; + nrmIdx3 = 0; + } + break; + case GX_VA_CLR0: + c0Cnt = list->cnt; + c0Type = list->type; + break; + case GX_VA_CLR1: + c1Cnt = list->cnt; + c1Type = list->type; + break; + case GX_VA_TEX0: + tx0Cnt = list->cnt; + tx0Type = list->type; + tx0Frac = list->frac; + break; + case GX_VA_TEX1: + tx1Cnt = list->cnt; + tx1Type = list->type; + tx1Frac = list->frac; + break; + case GX_VA_TEX2: + tx2Cnt = list->cnt; + tx2Type = list->type; + tx2Frac = list->frac; + break; + case GX_VA_TEX3: + tx3Cnt = list->cnt; + tx3Type = list->type; + tx3Frac = list->frac; + break; + case GX_VA_TEX4: + tx4Cnt = list->cnt; + tx4Type = list->type; + tx4Frac = list->frac; + break; + case GX_VA_TEX5: + tx5Cnt = list->cnt; + tx5Type = list->type; + tx5Frac = list->frac; + break; + case GX_VA_TEX6: + tx6Cnt = list->cnt; + tx6Type = list->type; + tx6Frac = list->frac; + break; + case GX_VA_TEX7: + tx7Cnt = list->cnt; + tx7Type = list->type; + tx7Frac = list->frac; + } + } + + GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP0_ID, CP_REG_VAT_GRP0(posCnt, posType, posFrac, nrmCnt, nrmType, c0Cnt, c0Type, c1Cnt, c1Type, tx0Cnt, tx0Type, tx0Frac, 1, nrmIdx3)); + GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP1_ID, CP_REG_VAT_GRP1(tx1Cnt, tx1Type, tx1Frac, tx2Cnt, tx2Type, tx2Frac, tx3Cnt, tx3Type, tx3Frac, tx4Cnt, tx4Type, 1)); + GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP2_ID, CP_REG_VAT_GRP2(tx4Frac, tx5Cnt, tx5Type, tx5Frac, tx6Cnt, tx6Type, tx6Frac, tx7Cnt, tx7Type, tx7Frac)); +} + +void GDSetArray(GXAttr attr, void* base_ptr, u8 stride) { + s32 cpAttr; + if (attr == GX_VA_NBT) { + cpAttr = GX_VA_TEX0MTXIDX; + } else { + cpAttr = attr - GX_VA_POS; + } + + GDWriteCPCmd(cpAttr + CP_REG_ARRAYBASE_ID, OSCachedToPhysical(base_ptr)); + GDWriteCPCmd(cpAttr + CP_REG_ARRAYSTRIDE_ID, stride); +} + +void GDSetArrayRaw(GXAttr attr, u32 base_ptr_raw, u8 stride) { + s32 cpAttr; + if (attr == GX_VA_NBT) { + cpAttr = GX_VA_TEX0MTXIDX; + } else { + cpAttr = attr - GX_VA_POS; + } + + GDWriteCPCmd(cpAttr + CP_REG_ARRAYBASE_ID, base_ptr_raw); + GDWriteCPCmd(cpAttr + CP_REG_ARRAYSTRIDE_ID, stride); +} + +void GDPatchArrayPtr(void* base_ptr) { + GDWrite_u32(OSCachedToPhysical(base_ptr)); +} + +void GDSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u8 normalize, u32 postmtx) { + u32 form; + u32 tgType; + u32 proj; + u32 row; + u32 embossRow; + u32 embossLit; + + form = 0; + proj = 0; + row = 5; + embossRow = 5; + embossLit = 0; + + ASSERTMSGLINE(432, dst_coord < GX_MAX_TEXCOORD, "GDSetTexCoordGen: invalid texcoord ID"); + + switch(src_param) { + case GX_TG_POS: + row = 0; + form = 1; + break; + case GX_TG_NRM: + row = 1; + form = 1; + break; + case GX_TG_BINRM: + row = 3; + form = 1; + break; + case GX_TG_TANGENT: + row = 4; + form = 1; + break; + case GX_TG_COLOR0: + row = 2; + break; + case GX_TG_COLOR1: + row = 2; + break; + case GX_TG_TEX0: + row = 5; + break; + case GX_TG_TEX1: + row = 6; + break; + case GX_TG_TEX2: + row = 7; + break; + case GX_TG_TEX3: + row = 8; + break; + case GX_TG_TEX4: + row = 9; + break; + case GX_TG_TEX5: + row = 10; + break; + case GX_TG_TEX6: + row = 11; + break; + case GX_TG_TEX7: + row = 12; + break; + case GX_TG_TEXCOORD0: + embossRow = 0; + break; + case GX_TG_TEXCOORD1: + embossRow = 1; + break; + case GX_TG_TEXCOORD2: + embossRow = 2; + break; + case GX_TG_TEXCOORD3: + embossRow = 3; + break; + case GX_TG_TEXCOORD4: + embossRow = 4; + break; + case GX_TG_TEXCOORD5: + embossRow = 5; + break; + case GX_TG_TEXCOORD6: + embossRow = 6; + break; + default: + ASSERTMSGLINE(457, 0, "GDSetTexCoordGen: invalid texgen source"); + break; + } + + switch (func) { + case GX_TG_MTX2x4: + tgType = 0; + break; + case GX_TG_MTX3x4: + tgType = 0; + proj = 1; + break; + case GX_TG_BUMP0: + case GX_TG_BUMP1: + case GX_TG_BUMP2: + case GX_TG_BUMP3: + case GX_TG_BUMP4: + case GX_TG_BUMP5: + case GX_TG_BUMP6: + case GX_TG_BUMP7: + ASSERTMSGLINE(481, src_param >= GX_TG_TEXCOORD0 && src_param <= GX_TG_TEXCOORD6, "GDSetTexCoordGen: invalid emboss source"); + tgType = 1; + embossLit = func - GX_TG_BUMP0; + break; + case GX_TG_SRTG: + if (src_param == GX_TG_COLOR0) { + tgType = 2; + } else { + tgType = 3; + } + break; + default: + ASSERTMSGLINE(495, 0, "GDSetTexCoordGen: invalid texgen function"); + break; + } + + GDWriteXFCmd(dst_coord + XF_REG_TEX0_ID, XF_REG_TEX(proj, form, tgType, row, embossRow, embossLit)); + GDWriteXFCmd(dst_coord + XF_REG_DUALTEX0_ID, XF_REG_DUALTEX(postmtx - 0x40, normalize)); +} + +void GDSetCullMode(GXCullMode mode) { + static u8 cm2hw[4] = { 0, 2, 1, 3 }; + + GDWriteBPCmd(0xFE00C000); + GDWriteBPCmd(cm2hw[mode] << 14); +} + +void GDSetGenMode(u8 nTexGens, u8 nChans, u8 nTevs) { + GDWriteBPCmd(0xFE003C3F); + GDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, 0, 0)); + + GDWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans); + GDWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens); +} + +void GDSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm) { + static u8 cm2hw[4] = { 0, 2, 1, 3 }; + + GDWriteBPCmd(0xFE07FC3F); + GDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, cm2hw[cm], nInds)); + + GDWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans); + GDWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens); +} + +void GDSetLPSize(u8 lineWidth, u8 pointSize, GXTexOffset lineOffset, GXTexOffset pointOffset, u8 lineHalfAspect) { + GDWriteBPCmd(BP_LP_SIZE(lineWidth, pointSize, lineOffset, pointOffset, lineHalfAspect, 0x22)); +} + +void GDSetCoPlanar(u8 enable) { + GDWriteBPCmd(0xFE080000); + GDWriteBPCmd(enable << 19); +} diff --git a/src/dolphin/gd/GDIndirect.c b/src/dolphin/gd/GDIndirect.c new file mode 100644 index 0000000..104fce4 --- /dev/null +++ b/src/dolphin/gd/GDIndirect.c @@ -0,0 +1,270 @@ +#include +#include + +void GDSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, + GXIndTexFormat format, GXIndTexBiasSel bias_sel, + GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, + GXIndTexWrap wrap_t, u8 add_prev, u8 utc_lod, + GXIndTexAlphaSel alpha_sel) { + GDWriteBPCmd(BP_TEV_INDIRECT( + ind_stage & 3, + format & 3, + bias_sel & 7, + alpha_sel & 3, + matrix_sel & 0xF, + wrap_s & 7, + wrap_t & 7, + utc_lod & 1, + add_prev & 1, + 0x10 + (tev_stage & 0xF) + )); +} + +void GDSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp) { + u32 id_offset; + + switch (mtx_id) { + case GX_ITM_0: + id_offset = 0; + break; + case GX_ITM_1: + id_offset = 3; + break; + case GX_ITM_2: + id_offset = 6; + break; + default: + ASSERTMSGLINE(111, 0, "GDSetIndTexMtx: Invalid matrix id"); + break; + } + + scale_exp += 17; + + GDWriteBPCmd(BP_IND_MTX( + (s32)(offset[0][0] * 0x400) & 0x7FF, + (s32)(offset[1][0] * 0x400) & 0x7FF, + scale_exp & 3, + 6 + id_offset + )); + + GDWriteBPCmd(BP_IND_MTX( + (s32)(offset[0][1] * 0x400) & 0x7FF, + (s32)(offset[1][1] * 0x400) & 0x7FF, + (scale_exp >> 2) & 3, + 7 + id_offset + )); + + GDWriteBPCmd(BP_IND_MTX( + (s32)(offset[0][2] * 0x400) & 0x7FF, + (s32)(offset[1][2] * 0x400) & 0x7FF, + (scale_exp >> 4) & 3, + 8 + id_offset + )); +} + +void GDSetIndTexCoordScale(GXIndTexStageID indStageEven, GXIndTexScale scaleS0, + GXIndTexScale scaleT0, GXIndTexScale scaleS1, + GXIndTexScale scaleT1) { + GDWriteBPCmd(BP_IND_TEXCOORD_SCALE( + scaleS0 & 0xF, + scaleT0 & 0xF, + scaleS1 & 0xF, + scaleT1 & 0xF, + 0x25 + ((indStageEven >> 1) & 1) + )); +} + +void GDSetIndTexOrder(GXTexCoordID texCoord0, GXTexMapID texMap0, + GXTexCoordID texCoord1, GXTexMapID texMap1, + GXTexCoordID texCoord2, GXTexMapID texMap2, + GXTexCoordID texCoord3, GXTexMapID texMap3) { + GDWriteBPCmd(BP_IND_TEX_ORDER( + texMap0 & 7, + texCoord0 & 7, + texMap1 & 7, + texCoord1 & 7, + texMap2 & 7, + texCoord2 & 7, + texMap3 & 7, + texCoord3 & 7, + 0x27 + )); +} + +void GDSetTevDirect(GXTevStageID tev_stage) { + GDSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, 0, 0, GX_ITBA_OFF); +} + +void GDSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel) { + GXIndTexWrap wrap; + wrap = replace_mode ? GX_ITW_0 : GX_ITW_OFF; + + GDSetTevIndirect(tev_stage, + ind_stage, + GX_ITF_8, + signed_offset ? GX_ITB_STU : GX_ITB_NONE, + matrix_sel, + wrap, + wrap, + 0, + 0, + GX_ITBA_OFF); +} + +void GDSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, + u16 tilesize_s, u16 tilesize_t, u16 tilespacing_s, + u16 tilespacing_t, GXIndTexFormat format, + GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, + GXIndTexAlphaSel alpha_sel) { + GXIndTexWrap wrap_s; + GXIndTexWrap wrap_t; + f32 mtx[2][3]; + + switch (tilesize_s) { + case 256: + wrap_s = GX_ITW_256; + break; + case 128: + wrap_s = GX_ITW_128; + break; + case 64: + wrap_s = GX_ITW_64; + break; + case 32: + wrap_s = GX_ITW_32; + break; + case 16: + wrap_s = GX_ITW_16; + break; + default: + ASSERTMSGLINE(268, 0, "GDSetTevIndTile: Invalid tilesize for S coordinate"); + wrap_s = GX_ITW_OFF; + break; + } + + switch (tilesize_t) { + case 256: + wrap_t = GX_ITW_256; + break; + case 128: + wrap_t = GX_ITW_128; + break; + case 64: + wrap_t = GX_ITW_64; + break; + case 32: + wrap_t = GX_ITW_32; + break; + case 16: + wrap_t = GX_ITW_16; + break; + default: + ASSERTMSGLINE(280, 0, "GDSetTevIndTile: Invalid tilesize for T coordinate"); + wrap_t = GX_ITW_OFF; + break; + } + + mtx[0][0] = (f32)tilespacing_s / 0x400; + mtx[0][1] = mtx[0][2] = 0.0f; + + mtx[1][1] = (f32)tilespacing_t / 0x400; + mtx[1][0] = mtx[1][2] = 0.0f; + GDSetIndTexMtx(matrix_sel, mtx, 10); + + GDSetTevIndirect(tev_stage, + ind_stage, + format, + bias_sel, + matrix_sel, + wrap_s, + wrap_t, + 0, + 1, + alpha_sel); +} + +void GDSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { + GXIndTexMtxID sm; + GXIndTexMtxID tm; + + switch(matrix_sel) { + case GX_ITM_0: + sm = GX_ITM_S0; + tm = GX_ITM_T0; + break; + case GX_ITM_1: + sm = GX_ITM_S1; + tm = GX_ITM_T1; + break; + case GX_ITM_2: + sm = GX_ITM_S2; + tm = GX_ITM_T2; + break; + default: + ASSERTMSGLINE(332, 0, "GDSetTevIndBumpST: Invalid matrix selection"); + break; + } + + GDSetTevIndirect(tev_stage, + ind_stage, + GX_ITF_8, + GX_ITB_ST, + sm, + GX_ITW_0, + GX_ITW_0, + 0, + 0, + GX_ITBA_OFF); + + GDSetTevIndirect(tev_stage + 1, + ind_stage, + GX_ITF_8, + GX_ITB_ST, + tm, + GX_ITW_0, + GX_ITW_0, + 1, + 0, + GX_ITBA_OFF); + + GDSetTevIndirect(tev_stage + 2, + ind_stage, + GX_ITF_8, + GX_ITB_NONE, + GX_ITM_OFF, + GX_ITW_OFF, + GX_ITW_OFF, + 1, + 0, + GX_ITBA_OFF); +} + +void GDSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { + GDSetTevIndirect(tev_stage, + ind_stage, + GX_ITF_8, + GX_ITB_STU, + matrix_sel, + GX_ITW_OFF, + GX_ITW_OFF, + 0, + 0, + GX_ITBA_OFF); +} + +void GDSetTevIndRepeat(GXTevStageID tev_stage) { + GDSetTevIndirect(tev_stage, + GX_INDTEXSTAGE0, + GX_ITF_8, + GX_ITB_NONE, + GX_ITM_OFF, + GX_ITW_0, + GX_ITW_0, + 1, + 0, + GX_ITBA_OFF); +} + +void __GDSetIndTexMask(u32 mask) { + GDWriteBPCmd(BP_IND_MASK(mask & 0xFF, 0xF)); +} diff --git a/src/dolphin/gd/GDLight.c b/src/dolphin/gd/GDLight.c new file mode 100644 index 0000000..96e08a4 --- /dev/null +++ b/src/dolphin/gd/GDLight.c @@ -0,0 +1,206 @@ +#include +#include + +void GDSetLightAttn(GXLightID light, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) { + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_ATTN_ID, 6); + GDWrite_f32(a0); + GDWrite_f32(a1); + GDWrite_f32(a2); + GDWrite_f32(k0); + GDWrite_f32(k1); + GDWrite_f32(k2); +} + +void GDSetLightSpot(GXLightID light, f32 cutoff, GXSpotFn spot_func) { + f32 a0; + f32 a1; + f32 a2; + f32 r; + f32 d; + f32 cr; + + if (cutoff <= 0.0f || cutoff > 90.0f) { + spot_func = 0; + } + + r = M_PI * cutoff / 180.0f; + cr = cosf(r); + + switch(spot_func) { + case GX_SP_FLAT: + a0 = -1000.0f * cr; + a1 = 1000.0f; + a2 = 0.0f; + break; + case GX_SP_COS: + a0 = -cr / (1.0f - cr); + a1 = 1.0f / (1.0f - cr); + a2 = 0.0f; + break; + case GX_SP_COS2: + a0 = 0.0f; + a1 = -cr / (1.0f - cr); + a2 = 1.0f / (1.0f - cr); + break; + case GX_SP_SHARP: + d = (1.0f - cr) * (1.0f - cr); + a0 = (cr * (cr - 2.0f)) / d; + a1 = 2.0f / d; + a2 = -1.0f / d; + break; + case GX_SP_RING1: + d = (1.0f - cr) * (1.0f - cr); + a0 = (-4.0f * cr) / d; + a1 = (4.0f * (1.0f + cr)) / d; + a2 = -4.0f / d; + break; + case GX_SP_RING2: + d = (1.0f - cr) * (1.0f - cr); + a0 = 1.0f - (2.0f * cr * cr) / d; + a1 = (4.0f * cr) / d; + a2 = -2.0f / d; + break; + case GX_SP_OFF: + default: + a0 = 1.0f; + a1 = 0.0f; + a2 = 0.0f; + break; + } + + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_ATTN_ID, 3); + GDWrite_f32(a0); + GDWrite_f32(a1); + GDWrite_f32(a2); +} + +void GDSetLightDistAttn(GXLightID light, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) { + f32 k0; + f32 k1; + f32 k2; + + if (ref_dist < 0.0f || ref_br <= 0.0f || ref_br >= 1.0f) { + dist_func = 0; + } + + switch (dist_func) { + case GX_DA_GENTLE: + k0 = 1.0f; + k1 = (1.0f - ref_br) / (ref_br * ref_dist); + k2 = 0.0f; + break; + case GX_DA_MEDIUM: + k0 = 1.0f; + k1 = (0.5f * (1.0f - ref_br)) / (ref_br * ref_dist); + k2 = (0.5f * (1.0f - ref_br)) / (ref_dist * (ref_br * ref_dist)); + break; + case GX_DA_STEEP: + k0 = 1.0f; + k1 = 0.0f; + k2 = (1.0f - ref_br) / (ref_dist * (ref_br * ref_dist)); + break; + case GX_DA_OFF: + default: + k0 = 1.0f; + k1 = 0.0f; + k2 = 0.0f; + break; + } + + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_DISTATTN_ID, 3); + GDWrite_f32(k0); + GDWrite_f32(k1); + GDWrite_f32(k2); +} + +void GDSetLightColor(GXLightID light, GXColor color) { + GDWriteXFCmd(__GDLightID2Offset(light) + XF_LIGHT_COLOR_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); +} + +void GDSetLightPos(GXLightID light, f32 x, f32 y, f32 z) { + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_POS_ID, 3); + GDWrite_f32(x); + GDWrite_f32(y); + GDWrite_f32(z); +} + +void GDSetLightDir(GXLightID light, f32 nx, f32 ny, f32 nz) { + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_DIR_ID, 3); + GDWrite_f32(nx); + GDWrite_f32(ny); + GDWrite_f32(nz); +} + +void GDSetSpecularDirHA(GXLightID light, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) { + f32 px; + f32 py; + f32 pz; + px = 1000000000000000000.0f * -nx; + py = 1000000000000000000.0f * -ny; + pz = 1000000000000000000.0f * -nz; + + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_SPEC_DIR_ID, 6); + GDWrite_f32(px); + GDWrite_f32(py); + GDWrite_f32(pz); + GDWrite_f32(hx); + GDWrite_f32(hy); + GDWrite_f32(hz); +} + +void GDSetSpecularDir(GXLightID light, f32 nx, f32 ny, f32 nz) { + f32 px; + f32 py; + f32 pz; + f32 hx; + f32 hy; + f32 hz; + f32 mag; + + hx = -nx; + hy = -ny; + hz = 1.0f + -nz; + + mag = hx * hx + hy * hy + hz * hz; + if (mag != 0.0f) { + mag = 1.0f / sqrtf(mag); + } + + hx = hx * mag; + hy = hy * mag; + hz = hz * mag; + px = 1000000000000000000.0f * -nx; + py = 1000000000000000000.0f * -ny; + pz = 1000000000000000000.0f * -nz; + + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_SPEC_DIR_ID, 6); + GDWrite_f32(px); + GDWrite_f32(py); + GDWrite_f32(pz); + GDWrite_f32(hx); + GDWrite_f32(hy); + GDWrite_f32(hz); +} + +void GDLoadLightObjIndx(u32 lt_obj_indx, GXLightID light) { + GDWriteXFIndxDCmd(__GDLightID2Offset(light) + XF_LIGHT_ID, 0x10, lt_obj_indx); +} + +void GDSetChanAmbColor(GXChannelID chan, GXColor color) { + GDWriteXFCmd((chan & 1) + XF_REG_AMBIENT0_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); +} + +void GDSetChanMatColor(GXChannelID chan, GXColor color) { + GDWriteXFCmd((chan & 1) + XF_REG_MATERIAL0_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); +} + +void GDSetChanCtrl(GXChannelID chan, u8 enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn) { + u32 reg; + + reg = XF_REG_CHAN_CTRL(mat_src, enable, light_mask & 0xF, amb_src, attn_fn == GX_AF_SPEC ? GX_DF_NONE : diff_fn, attn_fn != GX_AF_NONE, attn_fn != GX_AF_SPEC, (light_mask >> 4) & 0xF); + GDWriteXFCmd((chan & 3) + XF_REG_COLOR0CNTRL_ID, reg); + + if (chan == 4 || chan == 5) { + GDWriteXFCmd(chan + XF_REG_MATERIAL0_ID, reg); + } +} diff --git a/src/dolphin/gd/GDPixel.c b/src/dolphin/gd/GDPixel.c new file mode 100644 index 0000000..c18cf77 --- /dev/null +++ b/src/dolphin/gd/GDPixel.c @@ -0,0 +1,118 @@ +#include +#include + +void GDSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) { + f32 A; + f32 B; + f32 B_mant; + f32 C; + f32 A_f; + u32 b_expn; + u32 b_m; + u32 a_hex; + u32 c_hex; + u32 fsel; + u32 proj; + + ASSERTMSGLINE(62, farz >= 0.0f, "GDSetFog: The farz should be positive value"); + ASSERTMSGLINE(63, farz >= nearz, "GDSetFog: The farz should be larger than nearz"); + + fsel = type & 7; + proj = (type >> 3) & 1; + + if (proj != 0) { + if (farz == nearz || endz == startz) { + A_f = 0.0f; + C = 0.0f; + } else { + A = 1.0f / (endz - startz); + A_f = (farz - nearz) * A; + C = (startz - nearz) * A; + } + + b_expn = 0; + b_m = 0; + } else { + if (farz == nearz || endz == startz) { + A = 0.0f; + B = 0.5f; + C = 0.0f; + } else { + A = (farz * nearz) / ((farz - nearz) * (endz - startz)); + B = farz / (farz - nearz); + C = startz / (endz - startz); + } + + B_mant = B; + b_expn = 1; + + while (B_mant > 1.0) { + B_mant *= 0.5f; + b_expn++; + } + + while (B_mant > 0.0f && B_mant < 0.5) { + B_mant *= 2.0f; + b_expn--; + } + + A_f = A / (1 << b_expn); + b_m = (u32) (8388638.0f * B_mant); + } + + a_hex = *(u32*)&A_f; + c_hex = *(u32*)&C; + + GDWriteBPCmd(BP_FOG_UNK0(a_hex >> 12, 0xEE)); + GDWriteBPCmd(BP_FOG_UNK1(b_m, 0xEF)); + GDWriteBPCmd(BP_FOG_UNK2(b_expn, 0xF0)); + GDWriteBPCmd(BP_FOG_UNK3(c_hex >> 12, proj, fsel, 0xF1)); + GDWriteBPCmd(BP_FOG_COLOR(color.r, color.g, color.b, 0xF2)); +} + +void GDSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp logic_op) { + GDWriteBPCmd(0xFE00FFE3); + GDWriteBPCmd(BP_BLEND_MODE( + type == GX_BM_BLEND || type == GX_BM_SUBTRACT, + type == GX_BM_LOGIC, + 0, + 0, + 0, + dst_factor, + src_factor, + type == GX_BM_SUBTRACT, + logic_op, + 0x41 + )); +} + +void GDSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor, + GXBlendFactor dst_factor, GXLogicOp logic_op, + u8 color_update_enable, u8 alpha_update_enable, + u8 dither_enable) { + GDWriteBPCmd(BP_BLEND_MODE( + type == GX_BM_BLEND || type == GX_BM_SUBTRACT, + type == GX_BM_LOGIC, + dither_enable, + color_update_enable, + alpha_update_enable, + dst_factor, + src_factor, + type == GX_BM_SUBTRACT, + logic_op, + 0x41 + )); +} + +void GDSetZMode(u8 compare_enable, GXCompare func, u8 update_enable) { + GDWriteBPCmd(BP_Z_MODE(compare_enable, func, update_enable, 0x40)); +} + +void GDSetDstAlpha(u8 enable, u8 alpha) { + GDWriteBPCmd(BP_DST_ALPHA(alpha, enable, 0x42)); +} + +void GDSetDrawSync(u16 token) { + GDWriteBPCmd(BP_TOKEN(token, 0x48)); + GDWriteBPCmd(BP_TOKEN(token, 0x47)); +} diff --git a/src/dolphin/gd/GDTev.c b/src/dolphin/gd/GDTev.c new file mode 100644 index 0000000..69803e8 --- /dev/null +++ b/src/dolphin/gd/GDTev.c @@ -0,0 +1,159 @@ +#include +#include + +void GDSetTevOp(GXTevStageID stage, GXTevMode mode) { + GXTevColorArg carg = GX_CC_RASC; + GXTevAlphaArg aarg = GX_CA_RASA; + + if (stage != GX_TEVSTAGE0) { + carg = GX_CC_CPREV; + aarg = GX_CA_APREV; + } + + switch (mode) { + case GX_MODULATE: + GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_TEXC, carg, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + case GX_DECAL: + GDSetTevColorCalc(stage, carg, GX_CC_TEXC, GX_CC_TEXA, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + case GX_BLEND: + GDSetTevColorCalc(stage, carg, GX_CC_ONE, GX_CC_TEXC, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + case GX_REPLACE: + GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + case GX_PASSCLR: + GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, carg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + default: + ASSERTMSGLINE(110, 0, "GDSetTevOp: Invalid Tev Mode"); + break; + } +} + +void GDSetTevColorCalc(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, + GXTevColorArg c, GXTevColorArg d, GXTevOp op, + GXTevBias bias, GXTevScale scale, u8 clamp, + GXTevRegID out_reg) { + if (op <= GX_TEV_SUB) { + GDWriteBPCmd(BP_TEV_COLOR(d, c, b, a, bias, op & 1, clamp, scale, out_reg, stage * 2 + 0xC0)); + } else { + GDWriteBPCmd(BP_TEV_COLOR(d, c, b, a, 3, op & 1, clamp, (op >> 1) & 3, out_reg, stage * 2 + 0xC0)); + } +} + +void GDSetTevAlphaCalcAndSwap(GXTevStageID stage, GXTevAlphaArg a, + GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d, + GXTevOp op, GXTevBias bias, GXTevScale scale, + u8 clamp, GXTevRegID out_reg, + GXTevSwapSel ras_sel, GXTevSwapSel tex_sel) { + if (op <= GX_TEV_SUB) { + GDWriteBPCmd(BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, bias, op & 1, clamp, scale, out_reg, stage * 2 + 0xC1)); + } else { + GDWriteBPCmd(BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, 3, op & 1, clamp, (op >> 1) & 3, out_reg, stage * 2 + 0xC1)); + } +} + +void GDSetTevColor(GXTevRegID reg, GXColor color) { + u32 regRA; + u32 regBG; + + regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 0, 0xE0 + reg * 2); + regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 0, 0xE1 + reg * 2); + + GDWriteBPCmd(regRA); + GDWriteBPCmd(regBG); + GDWriteBPCmd(regBG); + GDWriteBPCmd(regBG); +} + +void GDSetTevColorS10(GXTevRegID reg, GXColorS10 color) { + u32 regRA; + u32 regBG; + + regRA = BP_TEV_COLOR_REG_RA(color.r & 0x7FF, color.a & 0x7FF, 0, 0xE0 + reg * 2); + regBG = BP_TEV_COLOR_REG_BG(color.b & 0x7FF, color.g & 0x7FF, 0, 0xE1 + reg * 2); + + GDWriteBPCmd(regRA); + GDWriteBPCmd(regBG); + GDWriteBPCmd(regBG); + GDWriteBPCmd(regBG); +} + +void GDSetTevKColor(GXTevKColorID reg, GXColor color) { + u32 regRA; + u32 regBG; + + regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 1, 0xE0 + reg * 2); + regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 1, 0xE1 + reg * 2); + + GDWriteBPCmd(regRA); + GDWriteBPCmd(regBG); +} + +void GDSetTevKonstantSel(GXTevStageID evenStage, GXTevKColorSel kcsel0, + GXTevKAlphaSel kasel0, GXTevKColorSel kcsel1, + GXTevKAlphaSel kasel1) { + GDWriteBPCmd(0xFEFFFFF0); + GDWriteBPCmd(BP_TEV_KSEL(0, 0, kcsel0, kasel0, kcsel1, kasel1, evenStage / 2 + 0xF6)); +} + +void GDSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, + GXTevColorChan green, GXTevColorChan blue, + GXTevColorChan alpha) { + GDWriteBPCmd(0xFE00000F); + GDWriteBPCmd(BP_TEV_KSEL(red, green, 0, 0, 0, 0, table * 2 + 0xF6)); + + GDWriteBPCmd(0xFE00000F); + GDWriteBPCmd(BP_TEV_KSEL(blue, alpha, 0, 0, 0, 0, table * 2 + 0xF7)); +} + +void GDSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) { + GDWriteBPCmd(BP_ALPHA_COMPARE(ref0, ref1, comp0, comp1, op, 0xF3)); +} + +void GDSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias) { + u32 zfmt; + + switch (fmt) { + case GX_TF_Z8: + zfmt = 0; + break; + case GX_TF_Z16: + zfmt = 1; + break; + case GX_TF_Z24X8: + zfmt = 2; + break; + default: + ASSERTMSGLINE(399, 0, "GDSetZTexture: Invalid format"); + zfmt = 2; + break; + } + + GDWriteBPCmd(BP_ZTEX_PARAMS_0(bias, 0xF4)); + GDWriteBPCmd(BP_ZTEX_PARAMS_1(zfmt, op, 0xF5)); +} + +void GDSetTevOrder(GXTevStageID evenStage, GXTexCoordID coord0, GXTexMapID map0, + GXChannelID color0, GXTexCoordID coord1, GXTexMapID map1, + GXChannelID color1) { + static u8 c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6, 0, 0, 0, 0, 0, 0, 7 }; + GDWriteBPCmd(BP_TEV_ORDER( + map0 & 7, + coord0 & 7, + map0 != GX_TEXMAP_NULL && !(map0 & GX_TEX_DISABLE), + c2r[color0 & 0xF], + map1 & 7, + coord1 & 7, + map1 != GX_TEXMAP_NULL && !(map1 & GX_TEX_DISABLE), + c2r[color1 & 0xF], + evenStage / 2 + 0x28 + )); +} diff --git a/src/dolphin/gd/GDTexture.c b/src/dolphin/gd/GDTexture.c new file mode 100644 index 0000000..c3c1a6c --- /dev/null +++ b/src/dolphin/gd/GDTexture.c @@ -0,0 +1,104 @@ +#include +#include + +u8 GD2HWFiltConv[] = {0, 4, 1, 5, 2, 6}; + +u8 GDTexMode0Ids[8] = {128, 129, 130, 131, 160, 161, 162, 163}; +u8 GDTexMode1Ids[8] = {132, 133, 134, 135, 164, 165, 166, 167}; +u8 GDTexImage0Ids[8] = {136, 137, 138, 139, 168, 169, 170, 171}; +u8 GDTexImage1Ids[8] = {140, 141, 142, 143, 172, 173, 174, 175}; +u8 GDTexImage2Ids[8] = {144, 145, 146, 147, 176, 177, 178, 179}; +u8 GDTexImage3Ids[8] = {148, 149, 150, 151, 180, 181, 182, 183}; +u8 GDTexTlutIds[8] = {152, 153, 154, 155, 184, 185, 186, 187}; + +void GDSetTexLookupMode(GXTexMapID id, GXTexWrapMode wrap_s, + GXTexWrapMode wrap_t, GXTexFilter min_filt, + GXTexFilter mag_filt, f32 min_lod, f32 max_lod, + f32 lod_bias, u8 bias_clamp, u8 do_edge_lod, + GXAnisotropy max_aniso) { + GDWriteBPCmd(BP_TEX_MODE0(wrap_s, wrap_t, mag_filt == TRUE, GD2HWFiltConv[min_filt], !do_edge_lod, (u8)(32.0f * lod_bias), max_aniso, bias_clamp, GDTexMode0Ids[id])); + GDWriteBPCmd(BP_TEX_MODE1((u8)(16.0f * min_lod), (u8)(16.0f * max_lod), GDTexMode1Ids[id])); +} + +void GDSetTexImgAttr(GXTexMapID id, u16 width, u16 height, GXTexFmt format) { + GDWriteBPCmd(BP_IMAGE_ATTR(width - 1, height - 1, format, GDTexImage0Ids[id])); +} + +void GDSetTexImgPtr(GXTexMapID id, void* image_ptr) { + GDWriteBPCmd(BP_IMAGE_PTR(OSCachedToPhysical(image_ptr) >> 5, GDTexImage3Ids[id])); +} + +void GDSetTexImgPtrRaw(GXTexMapID id, u32 image_ptr_raw) { + GDWriteBPCmd(BP_IMAGE_PTR(image_ptr_raw, GDTexImage3Ids[id])); +} + +void GDPatchTexImgPtr(void* image_ptr) { + GDWrite_u24(OSCachedToPhysical(image_ptr) >> 5); +} + +void GDSetTexCached(GXTexMapID id, u32 tmem_even, GXTexCacheSize size_even, + u32 tmem_odd, GXTexCacheSize size_odd) { + GDWriteBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, size_even + 3, size_even + 3, 0, GDTexImage1Ids[id])); + + if (size_odd != 3 && tmem_odd < 0x100000) { + GDWriteBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, size_odd + 3, size_odd + 3, GDTexImage2Ids[id])); + } +} + + +void GDSetTexPreLoaded(GXTexMapID id, u32 tmem_even, u32 tmem_odd) { + GDWriteBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, 0, 0, 1, GDTexImage1Ids[id])); + + if (tmem_odd < 0x100000) { + GDWriteBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, 0, 0, GDTexImage2Ids[id])); + } +} + +void GDSetTexTlut(GXTexMapID id, u32 tmem_addr, GXTlutFmt format) { + GDWriteBPCmd(BP_TEX_TLUT((tmem_addr - 0x80000) >> 9, format, GDTexTlutIds[id])); +} + +void GDSetTexCoordScale(GXTexCoordID coord, u16 s_scale, u16 t_scale) { + GDWriteBPCmd(0xFE00FFFF); + GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, 0, 0, 0, 0, coord * 2 + 0x30)); + + GDWriteBPCmd(0xFE00FFFF); + GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, 0, 0, coord * 2 + 0x31)); +} + +void GDSetTexCoordScale2(GXTexCoordID coord, u16 s_scale, u8 s_bias, + u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap) { + GDWriteBPCmd(0xFE03FFFF); + GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, 0, 0, coord * 2 + 0x30)); + GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31)); +} + +void GDSetTexCoordScaleAndTOEs(GXTexCoordID coord, u16 s_scale, u8 s_bias, + u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap, + u8 line_offset, u8 point_offset) { + GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, line_offset, point_offset, coord * 2 + 0x30)); + GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31)); +} + +void GDLoadTlut(void* tlut_ptr, u32 tmem_addr, GXTlutSize size) { + ASSERTMSGLINE(488, !(tmem_addr & 0x1ff), "GDLoadTlut: invalid TMEM pointer"); + ASSERTMSGLINE(489, size <= 0x400, "GDLoadTlut: invalid TLUT size"); + + GDWriteBPCmd(0xFEFFFF00); + GDWriteBPCmd(0xF000000); + GDWriteBPCmd(BP_LOAD_TLUT0(OSCachedToPhysical(tlut_ptr) >> 5, 0x64)); + GDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65)); + GDWriteBPCmd(0xFEFFFF00); + GDWriteBPCmd(0xF000000); +} + +void GDLoadTlutRaw(u32 tlut_ptr_raw, u32 tmem_addr, GXTlutSize size) { + ASSERTMSGLINE(527, size <= 0x400, "GDLoadTlut: invalid TLUT size"); + + GDWriteBPCmd(0xFEFFFF00); + GDWriteBPCmd(0xF000000); + GDWriteBPCmd(BP_LOAD_TLUT0(tlut_ptr_raw, 0x64)); + GDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65)); + GDWriteBPCmd(0xFEFFFF00); + GDWriteBPCmd(0xF000000); +} diff --git a/src/dolphin/gd/GDTransform.c b/src/dolphin/gd/GDTransform.c new file mode 100644 index 0000000..9ac9c66 --- /dev/null +++ b/src/dolphin/gd/GDTransform.c @@ -0,0 +1,127 @@ +#include +#include + +void GDLoadPosMtxImm(const Mtx mtx, u32 id) { + GDWriteXFCmdHdr(4 * id, 12); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][1]); + GDWrite_f32(mtx[0][2]); + GDWrite_f32(mtx[0][3]); + GDWrite_f32(mtx[1][0]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][2]); + GDWrite_f32(mtx[1][3]); + GDWrite_f32(mtx[2][0]); + GDWrite_f32(mtx[2][1]); + GDWrite_f32(mtx[2][2]); + GDWrite_f32(mtx[2][3]); +} + +void GDLoadPosMtxIndx(u16 mtx_indx, u32 id) { + GDWriteXFIndxACmd(4 * id, 12, mtx_indx); +} + +void GDLoadNrmMtxImm(const Mtx mtx, u32 id) { + GDWriteXFCmdHdr(id * 3 + 0x400, 9); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][1]); + GDWrite_f32(mtx[0][2]); + GDWrite_f32(mtx[1][0]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][2]); + GDWrite_f32(mtx[2][0]); + GDWrite_f32(mtx[2][1]); + GDWrite_f32(mtx[2][2]); +} + +void GDLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id) { + GDWriteXFCmdHdr(id * 3 + 0x400, 9); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][1]); + GDWrite_f32(mtx[0][2]); + GDWrite_f32(mtx[1][0]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][2]); + GDWrite_f32(mtx[2][0]); + GDWrite_f32(mtx[2][1]); + GDWrite_f32(mtx[2][2]); +} + +void GDLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id) { + GDWriteXFIndxBCmd(id * 3 + 0x400, 9, mtx_indx); +} + +void GDLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type) { + u16 addr; + u8 count; + + if (id >= 0x40) { + ASSERTMSGLINE(178, type == GX_MTX3x4, "GDLoadTexMtxImm: invalid matrix type"); + addr = ((id - 0x40) << 2) + 0x500; + count = 12; + } else { + addr = 4 * id; + count = type == GX_MTX2x4 ? 8 : 12; + } + + GDWriteXFCmdHdr(addr,count); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][1]); + GDWrite_f32(mtx[0][2]); + GDWrite_f32(mtx[0][3]); + GDWrite_f32(mtx[1][0]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][2]); + GDWrite_f32(mtx[1][3]); + + if (type == GX_MTX3x4) { + GDWrite_f32(mtx[2][0]); + GDWrite_f32(mtx[2][1]); + GDWrite_f32(mtx[2][2]); + GDWrite_f32(mtx[2][3]); + } +} + +void GDLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type) { + u16 addr; + u8 count; + + if (id >= 0x40) { + ASSERTMSGLINE(227, type == GX_MTX3x4, "GDLoadTexMtxIndx: invalid matrix type"); + addr = ((id - 0x40) << 2) + 0x500; + count = 12; + } else { + addr = 4 * id; + count = type == GX_MTX2x4 ? 8 : 12; + } + + GDWriteXFIndxCCmd(addr, count, mtx_indx); +} + +void GDSetCurrentMtx(u32 pn, u32 t0, u32 t1, u32 t2, u32 t3, u32 t4, u32 t5, u32 t6, u32 t7) { + u32 regA; + u32 regB; + + regA = CP_MTX_REG_A(pn, t0, t1, t2, t3); + regB = CP_MTX_REG_B(t4, t5, t6, t7); + + GDWriteCPCmd(CP_MTX_REG_A_ID, regA); + GDWriteCPCmd(CP_MTX_REG_B_ID, regB); + GDWriteXFCmdHdr(XF_REG_MATRIXINDEX0_ID, 2); + GDWrite_u32(regA); + GDWrite_u32(regB); +} + +void GDSetProjection(const Mtx44 mtx, GXProjectionType type) { + u32 c; + c = type == GX_ORTHOGRAPHIC ? 3 : 2; + + GDWriteXFCmdHdr(XF_REG_PROJECTIONA_ID, 7); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][c]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][c]); + GDWrite_f32(mtx[2][2]); + GDWrite_f32(mtx[2][3]); + GDWrite_u32(type); +} diff --git a/src/dolphin/gx/GXAttr.c b/src/dolphin/gx/GXAttr.c new file mode 100644 index 0000000..136661d --- /dev/null +++ b/src/dolphin/gx/GXAttr.c @@ -0,0 +1,641 @@ +#include +#include + +#include "__gx.h" + +#define CHECK_ATTRPTR(line, attrPtr) ASSERTMSGLINE(line, (attrPtr) != NULL, "GXSetVtxDescv: attrPtr is NULL") +#define CHECK_ATTRNAME(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_PNMTXIDX, "GXSetVtxDesc: Invalid vertex attribute name") +#define CHECK_ATTRNAME2(line, attr) ASSERTMSGLINE(line, (attr) <= GX_VA_TEX7 || (attr) == GX_VA_NBT, "GXSetVtxDesc: Invalid vertex attribute name") +#define CHECK_ATTRNAME3(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_PNMTXIDX && (attr) < GX_VA_MAX_ATTR, "GXSetVtxDesc: Invalid vertex attribute name") +#define CHECK_ATTRNAME4(line, attr) ASSERTMSGLINE(line, ((attr) >= GX_VA_POS && (attr) <= GX_VA_TEX7) || (attr) == GX_VA_NBT, "GXSetVtxAttrFmt: Invalid vertex attribute name") +#define CHECK_ATTRNAME5(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_POS && (attr) <= GX_LIGHT_ARRAY, "GXSetArray: Invalid vertex attribute name") +#define CHECK_ATTRTYPE(line, type) ASSERTMSGLINE(line, (type) >= GX_NONE && (type) <= GX_INDEX16, "GXSetVtxDesc: Invalid vertex attribute type") +#define CHECK_VTXFMT(line, vtxfmt) ASSERTMSGLINE(line, (vtxfmt) < GX_MAX_VTXFMT, "GXSetVtxAttrFmt: Format Index is out of range") +#define CHECK_FRAC(line, frac) ASSERTMSGLINE(line, (frac) < 32, "GXSetVtxAttrFmt: Frac value is >= 32") +#define CHECK_LISTPTR(line, list) ASSERTMSGLINE(line, (list) != NULL, "GXSetVtxAttrFmt: list pointer is NULL") +#define CHECK_MTXIDX(line, attr, type) ASSERTMSGLINE(line, (attr) > GX_VA_TEX7MTXIDX || (type) <= GX_VA_TEX0MTXIDX, "GXSetVtxDesc: GX_VA_*MTXIDX accepts GX_NONE or GX_DIRECT only") + +static void __GXXfVtxSpecs(void) { + u32 nCols = 0; + u32 nNrm; + u32 nTex; + u32 reg; + + nNrm = __GXData->hasBiNrms ? 2 : __GXData->hasNrms ? 1 : 0; + +#ifdef DEBUG + nCols = GET_REG_FIELD(__GXData->vcdLo, 2, 13) ? 1 : 0; + nCols += GET_REG_FIELD(__GXData->vcdLo, 2, 15) ? 1 : 0; +#else + nCols = 33 - __cntlzw(GET_REG_FIELD(__GXData->vcdLo, 4, 13)); + nCols /= 2; +#endif + +#ifdef DEBUG + nTex = 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 0) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 2) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 4) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 6) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 8) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 10) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 12) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 14) ? 1 : 0; +#else + nTex = 33 - __cntlzw(GET_REG_FIELD(__GXData->vcdHi, 16, 0)); + nTex /= 2; +#endif + + reg = (nCols) | (nNrm << 2) | (nTex << 4); + GX_WRITE_XF_REG(8, reg); + __GXData->bpSentNot = 1; +} + +static inline void SETVCDATTR(GXAttr Attr, GXAttrType Type) { + switch (Attr) { + case GX_VA_PNMTXIDX: SET_REG_FIELD(212, __GXData->vcdLo, 1, 0, Type); break; + case GX_VA_TEX0MTXIDX: SET_REG_FIELD(213, __GXData->vcdLo, 1, 1, Type); break; + case GX_VA_TEX1MTXIDX: SET_REG_FIELD(214, __GXData->vcdLo, 1, 2, Type); break; + case GX_VA_TEX2MTXIDX: SET_REG_FIELD(215, __GXData->vcdLo, 1, 3, Type); break; + case GX_VA_TEX3MTXIDX: SET_REG_FIELD(216, __GXData->vcdLo, 1, 4, Type); break; + case GX_VA_TEX4MTXIDX: SET_REG_FIELD(217, __GXData->vcdLo, 1, 5, Type); break; + case GX_VA_TEX5MTXIDX: SET_REG_FIELD(218, __GXData->vcdLo, 1, 6, Type); break; + case GX_VA_TEX6MTXIDX: SET_REG_FIELD(219, __GXData->vcdLo, 1, 7, Type); break; + case GX_VA_TEX7MTXIDX: SET_REG_FIELD(220, __GXData->vcdLo, 1, 8, Type); break; + case GX_VA_POS: SET_REG_FIELD(221, __GXData->vcdLo, 2, 9, Type); break; + case GX_VA_NRM: + if (Type != GX_NONE) { + __GXData->hasNrms = 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) { + CHECK_GXBEGIN(264, "GXSetVtxDesc"); + CHECK_ATTRNAME(267, attr); + CHECK_ATTRNAME2(269, attr); + CHECK_ATTRTYPE(271, type); + CHECK_MTXIDX(274, attr, 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 GXSetVtxDescv(const GXVtxDescList *attrPtr) { + CHECK_GXBEGIN(306, "GXSetVtxDescv"); + CHECK_ATTRPTR(307, attrPtr); + + while (attrPtr->attr != GX_VA_NULL) { + CHECK_ATTRNAME(311, attrPtr->attr); + CHECK_ATTRNAME2(314, attrPtr->attr); + CHECK_ATTRTYPE(317, attrPtr->type); + SETVCDATTR(attrPtr->attr, attrPtr->type); + attrPtr++; + } + + if (__GXData->hasNrms || __GXData->hasBiNrms) { + SET_REG_FIELD(326, __GXData->vcdLo, 2, 11, __GXData->nrmType); + } else { + SET_REG_FIELD(326, __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 GXGetVtxDesc(GXAttr attr, GXAttrType* type) { + u32 cpType; + + CHECK_GXBEGIN(458, "GXGetVtxDesc"); + CHECK_ATTRNAME3(460, attr); + + switch (attr) { + case GX_VA_PNMTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 0); break; + case GX_VA_TEX0MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 1); break; + case GX_VA_TEX1MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 2); break; + case GX_VA_TEX2MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 3); break; + case GX_VA_TEX3MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 4); break; + case GX_VA_TEX4MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 5); break; + case GX_VA_TEX5MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 6); break; + case GX_VA_TEX6MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 7); break; + case GX_VA_TEX7MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 8); break; + case GX_VA_POS: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 9); break; + case GX_VA_NRM: cpType = __GXData->hasNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) : 0; break; + case GX_VA_NBT: cpType = __GXData->hasBiNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) : 0; break; + case GX_VA_CLR0: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 13); break; + case GX_VA_CLR1: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 15); break; + case GX_VA_TEX0: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 0); break; + case GX_VA_TEX1: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 2); break; + case GX_VA_TEX2: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 4); break; + case GX_VA_TEX3: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 6); break; + case GX_VA_TEX4: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 8); break; + case GX_VA_TEX5: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 10); break; + case GX_VA_TEX6: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 12); break; + case GX_VA_TEX7: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 14); break; + default: cpType = 0; break; + } + *type = cpType; +} + +void GXGetVtxDescv(GXVtxDescList* vcd) { + GXAttr attr; + + CHECK_GXBEGIN(511, "GXGetVtxDescv"); + CHECK_ATTRPTR(513, vcd); + + for (attr = GX_VA_PNMTXIDX; attr <= GX_VA_TEX7; attr++) { + vcd[attr].attr = attr; + GXGetVtxDesc(attr, &vcd[attr].type); + } + + vcd[attr].attr = GX_VA_NBT; + GXGetVtxDesc(GX_VA_NBT, &vcd[attr].type); + + attr++; + vcd[attr].attr = GX_VA_NULL; +} + +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; + + CHECK_GXBEGIN(713, "GXSetVtxAttrFmtv"); + CHECK_LISTPTR(714, list); + CHECK_VTXFMT(715, vtxfmt); + + va = &__GXData->vatA[vtxfmt]; + vb = &__GXData->vatB[vtxfmt]; + vc = &__GXData->vatC[vtxfmt]; + + while (list->attr != GX_VA_NULL) { + CHECK_ATTRNAME4(725, list->attr); + CHECK_FRAC(726, list->frac); + SETVAT(va, vb, vc, list->attr, list->cnt, list->type, list->frac); +#ifdef DEBUG + __GXVerifyVATImm(list->attr, list->cnt, list->type, list->frac); +#endif + list++; + } + __GXData->dirtyState |= 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 GXGetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt* cnt, GXCompType* type, u8* frac) { + u32* va; + u32* vb; + u32* vc; + + CHECK_GXBEGIN(833, "GXGetVtxAttrFmt"); + CHECK_VTXFMT(834, fmt); + + va = &__GXData->vatA[fmt]; + vb = &__GXData->vatB[fmt]; + vc = &__GXData->vatC[fmt]; + + switch (attr) { + case GX_VA_POS: + *cnt = GET_REG_FIELD(*va, 1, 0); + *type = GET_REG_FIELD(*va, 3, 1); + *frac = (u8)(*va >> 4) & 0x1F; // GET_REG_FIELD(*va, 5, 4) + return; + case GX_VA_NRM: + case GX_VA_NBT: + *cnt = GET_REG_FIELD(*va, 1, 9); + if (*cnt == GX_TEX_ST && (u8)(*va >> 0x1F) != 0) { + *cnt = GX_NRM_NBT3; + } + *type = GET_REG_FIELD(*va, 3, 10); + *frac = GetFracForNrm(*type); + return; + case GX_VA_CLR0: + *cnt = GET_REG_FIELD(*va, 1, 13); + *type = GET_REG_FIELD(*va, 3, 14); + *frac = 0; + return; + case GX_VA_CLR1: + *cnt = GET_REG_FIELD(*va, 1, 17); + *type = GET_REG_FIELD(*va, 3, 18); + *frac = 0; + return; + case GX_VA_TEX0: + *cnt = GET_REG_FIELD(*va, 1, 21); + *type = GET_REG_FIELD(*va, 3, 22); + *frac = (u8)(*va >> 0x19) & 0x1F; + return; + case GX_VA_TEX1: + *cnt = GET_REG_FIELD(*vb, 1, 0); + *type = GET_REG_FIELD(*vb, 3, 1); + *frac = (u8)(*vb >> 4) & 0x1F; + return; + case GX_VA_TEX2: + *cnt = GET_REG_FIELD(*vb, 1, 9); + *type = GET_REG_FIELD(*vb, 3, 10); + *frac = (u8)(*vb >> 0xD) & 0x1F; + return; + case GX_VA_TEX3: + *cnt = GET_REG_FIELD(*vb, 1, 18); + *type = GET_REG_FIELD(*vb, 3, 19); + *frac = (u8)(*vb >> 0x16) & 0x1F; + return; + case GX_VA_TEX4: + *cnt = GET_REG_FIELD(*vb, 1, 27); + *type = GET_REG_FIELD(*vb, 3, 28); + *frac = GET_REG_FIELD(*vc, 5, 0); + return; + case GX_VA_TEX5: + *cnt = GET_REG_FIELD(*vc, 1, 5); + *type = GET_REG_FIELD(*vc, 3, 6); + *frac = (u8)(*vc >> 9) & 0x1F; + return; + case GX_VA_TEX6: + *cnt = GET_REG_FIELD(*vc, 1, 14); + *type = GET_REG_FIELD(*vc, 3, 15); + *frac = (u8)(*vc >> 0x12) & 0x1F; + return; + case GX_VA_TEX7: + *cnt = GET_REG_FIELD(*vc, 1, 23); + *type = GET_REG_FIELD(*vc, 3, 24); + *frac = (int)(*vc >> 0x1B); + return; + default: + *cnt = GX_TEX_ST; + *type = GX_RGB565; + *frac = 0; + return; + } +} + +void GXGetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* vat) { + GXAttr attr; + + CHECK_GXBEGIN(930, "GXGetVtxAttrFmtv"); + CHECK_LISTPTR(931, vat); + CHECK_VTXFMT(932, fmt); + + for (attr = GX_VA_POS; attr <= GX_VA_TEX7; attr++) { + vat->attr = attr; + GXGetVtxAttrFmt(fmt, attr, &vat->cnt, &vat->type, &vat->frac); + vat++; + } + + vat->attr = GX_VA_NULL; +} + +void GXSetArray(GXAttr attr, void* base_ptr, u8 stride) { + GXAttr cpAttr; + u32 phyAddr; + + attr; // needed to match + + CHECK_GXBEGIN(963, "GXSetArray"); + if (attr == GX_VA_NBT) { + attr = GX_VA_NRM; + } + + CHECK_ATTRNAME5(966, attr); + cpAttr = attr - GX_VA_POS; + phyAddr = (u32)base_ptr & 0x3FFFFFFF; + + GX_WRITE_SOME_REG2(8, cpAttr | 0xA0, phyAddr, cpAttr - 12); + GX_WRITE_SOME_REG3(8, cpAttr | 0xB0, stride, cpAttr - 12); +} + +void GXInvalidateVtxCache(void) { + CHECK_GXBEGIN(988, "GXInvalidateVtxCache"); + GX_WRITE_U8(0x48); +} + +void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, GXBool normalize, u32 pt_texmtx) { + u32 reg = 0; + u32 row; + u32 bumprow; // unused + u32 form; + GXAttr mtxIdAttr; + + CHECK_GXBEGIN(1030, "GXSetTexCoordGen"); + ASSERTMSGLINE(1031, dst_coord < GX_MAX_TEXCOORD, "GXSetTexCoordGen: Invalid coordinate Id"); + + form = 0; + row = 5; + switch (src_param) { + case GX_TG_POS: row = 0; form = 1; break; + case GX_TG_NRM: row = 1; form = 1; break; + case GX_TG_BINRM: row = 3; form = 1; break; + case GX_TG_TANGENT: row = 4; form = 1; break; + case GX_TG_COLOR0: row = 2; break; + case GX_TG_COLOR1: row = 2; break; + case GX_TG_TEX0: row = 5; break; + case GX_TG_TEX1: row = 6; break; + case GX_TG_TEX2: row = 7; break; + case GX_TG_TEX3: row = 8; break; + case GX_TG_TEX4: row = 9; break; + case GX_TG_TEX5: row = 10; break; + case GX_TG_TEX6: row = 11; break; + case GX_TG_TEX7: row = 12; break; + case GX_TG_TEXCOORD0: bumprow; break; + case GX_TG_TEXCOORD1: bumprow; break; + case GX_TG_TEXCOORD2: bumprow; break; + case GX_TG_TEXCOORD3: bumprow; break; + case GX_TG_TEXCOORD4: bumprow; break; + case GX_TG_TEXCOORD5: bumprow; break; + case GX_TG_TEXCOORD6: bumprow; break; + default: + ASSERTMSGLINE(1059, 0, "GXSetTexCoordGen: Invalid source parameter"); + break; + } + + switch (func) { + case GX_TG_MTX2x4: + SET_REG_FIELD(1069, reg, 1, 1, 0); + SET_REG_FIELD(1069, reg, 1, 2, form); + SET_REG_FIELD(1071, reg, 3, 4, 0); + SET_REG_FIELD(1071, reg, 5, 7, row); + break; + case GX_TG_MTX3x4: + SET_REG_FIELD(1076, reg, 1, 1, 1); + SET_REG_FIELD(1076, reg, 1, 2, form); + SET_REG_FIELD(1076, reg, 3, 4, 0); + SET_REG_FIELD(1078, reg, 5, 7, row); + break; + case GX_TG_BUMP0: + case GX_TG_BUMP1: + 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/src/dolphin/gx/GXBump.c b/src/dolphin/gx/GXBump.c new file mode 100644 index 0000000..a8534b4 --- /dev/null +++ b/src/dolphin/gx/GXBump.c @@ -0,0 +1,308 @@ +#include +#include + +#include "__gx.h" + +#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: + ASSERTMSGLINE(277, 0, "GXSetIndTexCoordScale: Invalid Indirect Stage Id"); + 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; + } + + ASSERTMSGLINE(314, tex_map < GX_MAX_TEXMAP, "GXSetIndTexOrder: Invalid direct texture Id"); + ASSERTMSGLINE(315, tex_coord < GX_MAX_TEXCOORD, "GXSetIndTexOrder: Invalid texture coord"); + + switch (ind_stage) { + case GX_INDTEXSTAGE0: + 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: + ASSERTMSGLINE(335, 0, "GXSetIndTexOrder: Invalid Indirect Stage Id"); + break; + } + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->iref); + __GXData->dirtyState |= 3; + __GXData->bpSentNot = 0; +} + +void GXSetNumIndStages(u8 nIndStages) { + CHECK_GXBEGIN(353, "GXSetNumIndStages"); + ASSERTMSGLINE(355, nIndStages <= 4, "GXSetNumIndStages: Exceeds max. number of indirect texture stages"); + SET_REG_FIELD(356, __GXData->genMode, 3, 16, nIndStages); + __GXData->dirtyState |= 6; +} + +void GXSetTevDirect(GXTevStageID tev_stage) { + CHECK_GXBEGIN(373, "GXSetTevDirect"); + GXSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); +} + +void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel) { + GXIndTexWrap wrap = (replace_mode != 0) ? GX_ITW_0 : GX_ITW_OFF; + + CHECK_GXBEGIN(395, "GXSetTevIndWarp"); + GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, (signed_offset != 0) ? GX_ITB_STU : GX_ITB_NONE, matrix_sel, wrap, wrap, GX_FALSE, GX_FALSE, GX_ITBA_OFF); +} + +void GXSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u16 tilesize_s, + u16 tilesize_t, u16 tilespacing_s, u16 tilespacing_t, GXIndTexFormat format, + GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, GXIndTexAlphaSel alpha_sel) +{ + GXIndTexWrap wrap_s; + GXIndTexWrap wrap_t; + f32 mtx[2][3]; + + CHECK_GXBEGIN(429, "GXSetTevIndTile"); + ASSERTMSGLINE(430, tev_stage < GX_MAX_TEVSTAGE, "GXSetTevIndTile: Invalid tev stage id"); + ASSERTMSGLINE(431, ind_stage < GX_MAX_INDTEXSTAGE, "GXSetTevIndTile: Invalid indirect stage id"); + + switch (tilesize_s) { + case 256: + wrap_s = GX_ITW_256; + break; + case 128: + wrap_s = GX_ITW_128; + break; + case 64: + wrap_s = GX_ITW_64; + break; + case 32: + wrap_s = GX_ITW_32; + break; + case 16: + wrap_s = GX_ITW_16; + break; + default: + ASSERTMSGLINE(440, 0, "GXSetTevIndTile: Invalid tilesize for S coordinate"); + wrap_s = GX_ITW_OFF; + break; + } + + switch (tilesize_t) { + case 256: + wrap_t = GX_ITW_256; + break; + case 128: + wrap_t = GX_ITW_128; + break; + case 64: + wrap_t = GX_ITW_64; + break; + case 32: + wrap_t = GX_ITW_32; + break; + case 16: + wrap_t = GX_ITW_16; + break; + default: + ASSERTMSGLINE(452, 0, "GXSetTevIndTile: Invalid tilesize for T coordinate"); + wrap_t = GX_ITW_OFF; + break; + } + + mtx[0][0] = tilespacing_s / 1024.0f; + mtx[0][1] = mtx[0][2] = 0.0f; + mtx[1][1] = tilespacing_t / 1024.0f; + mtx[1][0] = mtx[1][2] = 0.0f; + GXSetIndTexMtx(matrix_sel, mtx, 10); + GXSetTevIndirect(tev_stage, ind_stage, format, bias_sel, matrix_sel, wrap_s, wrap_t, GX_FALSE, GX_TRUE, alpha_sel); +} + +void GXSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { + GXIndTexMtxID sm; + GXIndTexMtxID tm; + + CHECK_GXBEGIN(492, "GXSetTevIndBumpST"); + + switch (matrix_sel) { + case GX_ITM_0: + sm = GX_ITM_S0; + tm = GX_ITM_T0; + break; + case GX_ITM_1: + sm = GX_ITM_S1; + tm = GX_ITM_T1; + break; + case GX_ITM_2: + sm = GX_ITM_S2; + tm = GX_ITM_T2; + break; + default: + ASSERTMSGLINE(509, 0, "GXSetTevIndBumpST: Invalid matrix selection"); + break; + } + + GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, GX_ITB_ST, sm, GX_ITW_0, GX_ITW_0, GX_FALSE, GX_FALSE, GX_ITBA_OFF); + GXSetTevIndirect(tev_stage + 1, ind_stage, GX_ITF_8, GX_ITB_ST, tm, GX_ITW_0, GX_ITW_0, GX_TRUE, GX_FALSE, GX_ITBA_OFF); + GXSetTevIndirect(tev_stage + 2, ind_stage, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_TRUE, GX_FALSE, GX_ITBA_OFF); +} + +void GXSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { + CHECK_GXBEGIN(561, "GXSetTevIndBumpXYZ"); + GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, GX_ITB_STU, matrix_sel, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); +} + +void GXSetTevIndRepeat(GXTevStageID tev_stage) { + CHECK_GXBEGIN(590, "GXSetTevIndRepeat"); + GXSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_0, GX_ITW_0, GX_TRUE, GX_FALSE, GX_ITBA_OFF); +} + +void __GXUpdateBPMask(void) {} + +void __GXSetIndirectMask(u32 mask) { + SET_REG_FIELD(664, __GXData->bpMask, 8, ~0xFF, mask); + + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask); + __GXData->bpSentNot = 0; +} + +void __GXFlushTextureState(void) { + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask); + __GXData->bpSentNot = 0; +} diff --git a/src/dolphin/gx/GXDisplayList.c b/src/dolphin/gx/GXDisplayList.c new file mode 100644 index 0000000..86ec49f --- /dev/null +++ b/src/dolphin/gx/GXDisplayList.c @@ -0,0 +1,99 @@ +#include + +#include +#include + +#include "__gx.h" + +static __GXFifoObj DisplayListFifo; +static volatile __GXFifoObj* OldCPUFifo; +static GXData __savedGXdata; + +void GXBeginDisplayList(void* list, u32 size) { + __GXFifoObj* CPUFifo = (__GXFifoObj*)GXGetCPUFifo(); + + CHECK_GXBEGIN(137, "GXBeginDisplayList"); + ASSERTMSGLINE(138, !__GXData->inDispList, "GXBeginDisplayList: display list already in progress"); + ASSERTMSGLINE(139, (size & 0x1F) == 0, "GXBeginDisplayList: size is not 32 byte aligned"); + ASSERTMSGLINE(140, ((u32)list & 0x1F) == 0, "GXBeginDisplayList: list is not 32 byte aligned"); + + if (__GXData->dirtyState != 0) { + __GXSetDirtyState(); + } + + if (__GXData->dlSaveContext != 0) { + memcpy(&__savedGXdata, __GXData, sizeof(__savedGXdata)); + } + + DisplayListFifo.base = (u8*)list; + DisplayListFifo.top = (u8*)list + size - 4; + DisplayListFifo.size = size; + DisplayListFifo.count = 0; + DisplayListFifo.rdPtr = list; + DisplayListFifo.wrPtr = list; + __GXData->inDispList = 1; + GXSaveCPUFifo((GXFifoObj*)CPUFifo); + OldCPUFifo = CPUFifo; + GXSetCPUFifo((GXFifoObj*)&DisplayListFifo); + GXResetWriteGatherPipe(); +} + +u32 GXEndDisplayList(void) { + u32 ov; +#ifdef DEBUG + u32 reg; +#endif + BOOL enabled; + u32 cpenable; + + CHECK_GXBEGIN(195, "GXEndDisplayList"); + ASSERTMSGLINE(196, __GXData->inDispList == TRUE, "GXEndDisplayList: no display list in progress"); + GXFlush(); +#ifdef DEBUG + reg = GX_GET_PI_REG(5); + ov = (reg >> 26) & 1; +#else + ov = (GX_GET_PI_REG(5) >> 26) & 1; +#endif + __GXSaveCPUFifoAux(&DisplayListFifo); + ASSERTMSGLINE(213, !ov, "GXEndDisplayList: display list commands overflowed buffer"); + GXSetCPUFifo((GXFifoObj*)OldCPUFifo); + + if (__GXData->dlSaveContext != 0) { + enabled = OSDisableInterrupts(); + cpenable = __GXData->cpEnable; + memcpy(__GXData, &__savedGXdata, sizeof(*__GXData)); + __GXData->cpEnable = cpenable; + OSRestoreInterrupts(enabled); + } + + __GXData->inDispList = 0; + if (!ov) { + return DisplayListFifo.count; + } + + return 0; +} + +void GXCallDisplayList(void* list, u32 nbytes) { + CHECK_GXBEGIN(254, "GXCallDisplayList"); + ASSERTMSGLINE(255, !__GXData->inDispList, "GXCallDisplayList: display list already in progress"); + ASSERTMSGLINE(256, (nbytes & 0x1F) == 0, "GXCallDisplayList: nbytes is not 32 byte aligned"); + ASSERTMSGLINE(257, ((u32)list & 0x1F) == 0, "GXCallDisplayList: list is not 32 byte aligned"); + + if (__GXData->dirtyState != 0) { + __GXSetDirtyState(); + } + +#if DEBUG + __GXShadowDispList(list, nbytes); +#endif + + if (*(u32*)&__GXData->vNumNot == 0) { // checks both vNum and bpSent + __GXSendFlushPrim(); + } + + GX_WRITE_U8(GX_CMD_CALL_DL); + GX_WRITE_U32(list); + GX_WRITE_U32(nbytes); +} diff --git a/src/dolphin/gx/GXDraw.c b/src/dolphin/gx/GXDraw.c new file mode 100644 index 0000000..0ea0d0b --- /dev/null +++ b/src/dolphin/gx/GXDraw.c @@ -0,0 +1,551 @@ +#include + +#include +#include + +#include "__gx.h" + +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/src/dolphin/gx/GXFifo.c b/src/dolphin/gx/GXFifo.c new file mode 100644 index 0000000..670de8d --- /dev/null +++ b/src/dolphin/gx/GXFifo.c @@ -0,0 +1,629 @@ +#include +#include +#include +#include + +#include "__gx.h" + +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; + + ASSERTMSGLINE(LINE(542, 542, 546), realFifo != CPUFifo, "GXInitFifoBase: fifo is attached to CPU"); + ASSERTMSGLINE(LINE(544, 544, 548), realFifo != GPFifo, "GXInitFifoBase: fifo is attached to GP"); + ASSERTMSGLINE(LINE(546, 546, 550), ((u32)base & 0x1F) == 0, "GXInitFifoBase: base must be 32B aligned"); + ASSERTMSGLINE(LINE(548, 548, 552), base != NULL, "GXInitFifoBase: base pointer is NULL"); + ASSERTMSGLINE(LINE(550, 550, 554), (size & 0x1F) == 0, "GXInitFifoBase: size must be 32B aligned"); + ASSERTMSGLINE(LINE(552, 552, 556), size >= 0x10000, "GXInitFifoBase: fifo is not large enough"); + + realFifo->base = base; + realFifo->top = (u8*)base + size - 4; + realFifo->size = size; + realFifo->count = 0; + GXInitFifoLimits(fifo, size - 0x4000, (size >> 1) & ~0x1F); + GXInitFifoPtrs(fifo, base, base); +} + +void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr) { + __GXFifoObj* realFifo = (__GXFifoObj *)fifo; + BOOL enabled; + + ASSERTMSGLINE(LINE(592, 592, 596), realFifo != CPUFifo, "GXInitFifoPtrs: fifo is attached to CPU"); + ASSERTMSGLINE(LINE(594, 594, 598), realFifo != GPFifo, "GXInitFifoPtrs: fifo is attached to GP"); + ASSERTMSGLINE(LINE(596, 596, 600), ((u32)readPtr & 0x1F) == 0, "GXInitFifoPtrs: readPtr not 32B aligned"); + ASSERTMSGLINE(LINE(598, 598, 602), ((u32)writePtr & 0x1F) == 0, "GXInitFifoPtrs: writePtr not 32B aligned"); + ASSERTMSGLINE(LINE(601, 601, 605), realFifo->base <= readPtr && readPtr < realFifo->top, "GXInitFifoPtrs: readPtr not in fifo range"); + ASSERTMSGLINE(LINE(604, 604, 608), realFifo->base <= writePtr && writePtr < realFifo->top, "GXInitFifoPtrs: writePtr not in fifo range"); + + enabled = OSDisableInterrupts(); + realFifo->rdPtr = readPtr; + realFifo->wrPtr = writePtr; + realFifo->count = (u8*)writePtr - (u8*)readPtr; + if (realFifo->count < 0) { + realFifo->count += realFifo->size; + } + OSRestoreInterrupts(enabled); +} + +void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + ASSERTMSGLINE(LINE(641, 641, 645), realFifo != GPFifo, "GXInitFifoLimits: fifo is attached to GP"); + ASSERTMSGLINE(LINE(643, 643, 647), (hiWatermark & 0x1F) == 0, "GXInitFifoLimits: hiWatermark not 32B aligned"); + ASSERTMSGLINE(LINE(645, 645, 649), (loWatermark & 0x1F) == 0, "GXInitFifoLimits: loWatermark not 32B aligned"); + ASSERTMSGLINE(LINE(647, 647, 651), hiWatermark < realFifo->top - realFifo->base, "GXInitFifoLimits: hiWatermark too large"); + ASSERTMSGLINE(LINE(649, 649, 653), loWatermark < hiWatermark, "GXInitFifoLimits: hiWatermark below lo watermark"); + + realFifo->hiWatermark = hiWatermark; + realFifo->loWatermark = loWatermark; +} + +#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 GXSaveCPUFifo(GXFifoObj* fifo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + ASSERTMSGLINE(LINE(835, 835, 900), realFifo == CPUFifo, "GXSaveCPUFifo: fifo is not attached to CPU"); + GXFlush(); + __GXSaveCPUFifoAux(realFifo); +} + +void __GXSaveCPUFifoAux(__GXFifoObj* realFifo) { + BOOL enabled = OSDisableInterrupts(); + +#if SDK_REVISION < 2 + realFifo->base = OSPhysicalToCached(GX_GET_PI_REG(3)); + realFifo->top = OSPhysicalToCached(GX_GET_PI_REG(4)); + realFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); +#else + __GXSaveFifoPIStat(realFifo); +#endif + + if (CPGPLinked) { +#if SDK_REVISION < 2 + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); +#else + __GXSaveFifoCPStat(realFifo); +#endif + } else { + realFifo->count = (u8*)realFifo->wrPtr - (u8*)realFifo->rdPtr; + if (realFifo->count < 0) + realFifo->count += realFifo->size; + } + OSRestoreInterrupts(enabled); +} + +void GXSaveGPFifo(GXFifoObj* fifo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; +#if SDK_REVISION < 2 + u32 cpStatus; + u8 readIdle; + u32 temp; +#else + BOOL enabled = OSDisableInterrupts(); +#endif + +#if SDK_REVISION < 2 + ASSERTMSGLINE(908, realFifo == GPFifo, "GXSaveGPFifo: fifo is not attached to GP"); + cpStatus = *(u16*)__cpReg; + readIdle = GET_REG_FIELD(cpStatus, 1, 2); + ASSERTMSGLINE(915, readIdle, "GXSaveGPFifo: GP is not idle"); + + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); +#else + __GXSaveFifoCPStat(realFifo); + if (CPGPLinked) { + __GXSaveFifoPIStat(realFifo); + } + OSRestoreInterrupts(enabled); +#endif +} + +void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, GXBool* brkpt) { + __GXData->cpStatus = GX_GET_CP_REG(0); + *overhi = GET_REG_FIELD(__GXData->cpStatus, 1, 0); + *underlow = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 1); + *readIdle = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 2); + *cmdIdle = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 3); + *brkpt = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 4); +} + +void GXGetFifoStatus(GXFifoObj* fifo, GXBool* overhi, GXBool* underflow, u32* fifoCount, GXBool* cpuWrite, GXBool* gpRead, GXBool* fifowrap) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + *underflow = GX_FALSE; + *overhi = GX_FALSE; + *fifoCount = 0; + *fifowrap = GX_FALSE; + + if (realFifo == GPFifo) { + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); + } + + if (realFifo == CPUFifo) { + GXFlush(); + __GXSaveCPUFifoAux(realFifo); + *fifowrap = (int)GET_REG_FIELD(GX_GET_PI_REG(5), 1, 26); + } + + *overhi = (realFifo->count > realFifo->hiWatermark); + *underflow = (realFifo->count < realFifo->loWatermark); + *fifoCount = (realFifo->count); + *cpuWrite = (CPUFifo == realFifo); + *gpRead = (GPFifo == realFifo); +} + +void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + if (realFifo == CPUFifo) { + realFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); + } + + if (realFifo == GPFifo) { + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); + } else { + realFifo->count = (u8*)realFifo->wrPtr - (u8*)realFifo->rdPtr; + if (realFifo->count < 0) { + realFifo->count += realFifo->size; + } + } + + *readPtr = realFifo->rdPtr; + *writePtr = realFifo->wrPtr; +} + +void* GXGetFifoBase(const GXFifoObj* fifo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + return realFifo->base; +} + +u32 GXGetFifoSize(const GXFifoObj* fifo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + return realFifo->size; +} + +void GXGetFifoLimits(const GXFifoObj* fifo, u32* hi, u32* lo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + *hi = realFifo->hiWatermark; + *lo = realFifo->loWatermark; +} + +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); +} + +void __GXInsaneWatermark(void) { + __GXFifoObj* realFifo = GPFifo; + + realFifo->hiWatermark = realFifo->loWatermark + 512; + GX_SET_CP_REG(20, (realFifo->hiWatermark & 0x3FFFFFFF) & 0xFFFF); + GX_SET_CP_REG(21, (realFifo->hiWatermark & 0x3FFFFFFF) >> 16); +} + +void __GXCleanGPFifo(void) { + GXFifoObj dummyFifo; + GXFifoObj* gpFifo; + GXFifoObj* cpuFifo; + void* base; + + gpFifo = GXGetGPFifo(); + if (gpFifo == (GXFifoObj*)NULL) + return; + + cpuFifo = GXGetCPUFifo(); + base = GXGetFifoBase(gpFifo); + + dummyFifo = *gpFifo; + GXInitFifoPtrs(&dummyFifo, base, base); + GXSetGPFifo(&dummyFifo); + if (cpuFifo == gpFifo) { + GXSetCPUFifo(&dummyFifo); + } + GXInitFifoPtrs(gpFifo, base, base); + GXSetGPFifo(gpFifo); + if (cpuFifo == gpFifo) { + GXSetCPUFifo(cpuFifo); + } +} + +OSThread* GXSetCurrentGXThread(void) { + BOOL enabled; + OSThread* prev; + + enabled = OSDisableInterrupts(); + prev = __GXCurrentThread; + ASSERTMSGLINE(LINE(1377, 1377, 1434), !GXOverflowSuspendInProgress, "GXSetCurrentGXThread: Two threads cannot generate GX commands at the same time!"); + __GXCurrentThread = OSGetCurrentThread(); + OSRestoreInterrupts(enabled); + return prev; +} + +OSThread* GXGetCurrentGXThread(void) { + return __GXCurrentThread; +} + +GXFifoObj* GXGetCPUFifo(void) { + return (GXFifoObj*)CPUFifo; +} + +GXFifoObj* GXGetGPFifo(void) { + return (GXFifoObj*)GPFifo; +} + +u32 GXGetOverflowCount(void) { + return __GXOverflowCount; +} + +u32 GXResetOverflowCount(void) { + u32 oldcount; + + oldcount = __GXOverflowCount; + __GXOverflowCount = 0; + return oldcount; +} + +// NONMATCHING +volatile void* GXRedirectWriteGatherPipe(void* ptr) { + u32 reg = 0; + BOOL enabled = OSDisableInterrupts(); + + CHECK_GXBEGIN(LINE(1493, 1493, 1550), "GXRedirectWriteGatherPipe"); + ASSERTLINE(LINE(1494, 1494, 1551), OFFSET(ptr, 32) == 0); + ASSERTLINE(LINE(1496, 1496, 1553), !IsWGPipeRedirected); + +#if DEBUG + IsWGPipeRedirected = TRUE; +#endif + + GXFlush(); + while (PPCMfwpar() & 1) {} + PPCMtwpar((u32)OSUncachedToPhysical((void*)GXFIFO_ADDR)); + if (CPGPLinked) { + __GXFifoLink(0); + __GXWriteFifoIntEnable(0, 0); + } + CPUFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); + GX_SET_PI_REG(3, 0); + GX_SET_PI_REG(4, 0x04000000); + SET_REG_FIELD(LINE(1527, 1527, 1584), reg, 21, 5, ((u32)ptr & 0x3FFFFFFF) >> 5); + reg &= 0xFBFFFFFF; + GX_SET_PI_REG(5, reg); + + PPCSync(); + OSRestoreInterrupts(enabled); + return (volatile void *)GXFIFO_ADDR; +} + +// NONMATCHING +void GXRestoreWriteGatherPipe(void) { + u32 reg = 0; + u32 i; + BOOL enabled; + + ASSERTLINE(1552, IsWGPipeRedirected); + +#if DEBUG + IsWGPipeRedirected = FALSE; +#endif + + enabled = OSDisableInterrupts(); + for (i = 0; i < 31; i++) { + GXWGFifo.u8 = 0; + } + + PPCSync(); + while (PPCMfwpar() & 1) {} + PPCMtwpar((u32)OSUncachedToPhysical((void *)GXFIFO_ADDR)); + GX_SET_PI_REG(3, (u32)CPUFifo->base & 0x3FFFFFFF); + GX_SET_PI_REG(4, (u32)CPUFifo->top & 0x3FFFFFFF); + SET_REG_FIELD(1578, reg, 21, 5, ((u32)CPUFifo->wrPtr & 0x3FFFFFFF) >> 5); + reg &= 0xFBFFFFFF; + GX_SET_PI_REG(5, reg); + if (CPGPLinked) { + __GXWriteFifoIntReset(1, 1); + __GXWriteFifoIntEnable(1, 0); + __GXFifoLink(1); + } + + PPCSync(); + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/gx/GXFrameBuf.c b/src/dolphin/gx/GXFrameBuf.c new file mode 100644 index 0000000..d248566 --- /dev/null +++ b/src/dolphin/gx/GXFrameBuf.c @@ -0,0 +1,603 @@ +#include +#include + +#include "__gx.h" + +GXRenderModeObj GXNtsc240Ds = { + 1, + 640, 240, 240, + 40, 0, + 640, 480, + 0, + 0, + 0, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, + { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc240DsAa = { + 1, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc240Int = { + 0, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc240IntAa = { + 0, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc480IntDf = { + 0, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } +}; + +GXRenderModeObj GXNtsc480Int = { + 0, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc480IntAa = { + 0, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } +}; + +GXRenderModeObj GXNtsc480Prog = { + 2, 640, 480, 480, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc480ProgSoft = { + 2, 640, 480, 480, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } +}; + +GXRenderModeObj GXNtsc480ProgAa = { + 2, 640, 242, 480, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } +}; + +GXRenderModeObj GXMpal240Ds = {9, 640, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal240DsAa = {9, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal240Int = {8, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal240IntAa = {8, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal480IntDf = {8, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; +GXRenderModeObj GXMpal480Int = {8, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal480IntAa = {8, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; +GXRenderModeObj GXPal264Ds = {5, 640, 264, 264, 40, 11, 640, 528, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal264DsAa = {5, 640, 264, 264, 40, 11, 640, 528, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal264Int = {4, 640, 264, 264, 40, 23, 640, 528, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal264IntAa = {4, 640, 264, 264, 40, 23, 640, 528, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal528IntDf = {4, 640, 528, 528, 40, 23, 640, 528, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; +GXRenderModeObj GXPal528Int = {4, 640, 528, 528, 40, 23, 640, 528, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal524IntAa = {4, 640, 264, 524, 40, 23, 640, 524, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; +GXRenderModeObj GXEurgb60Hz240Ds = {21, 640, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz240DsAa = {21, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz240Int = {20, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz240IntAa = {20, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz480IntDf = {20, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; +GXRenderModeObj GXEurgb60Hz480Int = {20, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz480IntAa = {20, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; +GXRenderModeObj GXRmHW = {1, 320, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; + +void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver) { + u16 hor2 = hor * 2; + u16 ver2 = ver * 2; + u32 verf; + u32 mode; + + if (rmin != rmout) { + *rmout = *rmin; + } + + mode = rmin->viTVmode & 3; + rmout->fbWidth = rmin->fbWidth - hor2; + verf = (ver2 * rmin->efbHeight) / (u32)rmin->xfbHeight; + rmout->efbHeight = rmin->efbHeight - verf; + if (rmin->xFBmode == VI_XFBMODE_SF && mode == 0) { + rmout->xfbHeight = rmin->xfbHeight - ver2 / 2; + } else { + rmout->xfbHeight = rmin->xfbHeight - ver2; + } + + rmout->viWidth = rmin->viWidth - hor2; + + if (mode == 1) { + rmout->viHeight = rmin->viHeight - (ver2 * 2); + } else { + rmout->viHeight = rmin->viHeight - ver2; + } + + rmout->viXOrigin = rmin->viXOrigin + hor; + rmout->viYOrigin = rmin->viYOrigin + ver; +} + +void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht) { + CHECK_GXBEGIN(1235, "GXSetDispCopySrc"); + + __GXData->cpDispSrc = 0; + SET_REG_FIELD(1238, __GXData->cpDispSrc, 10, 0, left); + SET_REG_FIELD(1239, __GXData->cpDispSrc, 10, 10, top); + SET_REG_FIELD(1239, __GXData->cpDispSrc, 8, 24, 0x49); + + __GXData->cpDispSize = 0; + SET_REG_FIELD(1243, __GXData->cpDispSize, 10, 0, wd - 1); + SET_REG_FIELD(1244, __GXData->cpDispSize, 10, 10, ht - 1); + SET_REG_FIELD(1244, __GXData->cpDispSize, 8, 24, 0x4A); +} + + +void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht) { + CHECK_GXBEGIN(1263, "GXSetTexCopySrc"); + + __GXData->cpTexSrc = 0; + SET_REG_FIELD(1266, __GXData->cpTexSrc, 10, 0, left); + SET_REG_FIELD(1267, __GXData->cpTexSrc, 10, 10, top); + SET_REG_FIELD(1267, __GXData->cpTexSrc, 8, 24, 0x49); + + __GXData->cpTexSize = 0; + SET_REG_FIELD(1271, __GXData->cpTexSize, 10, 0, wd - 1); + SET_REG_FIELD(1272, __GXData->cpTexSize, 10, 10, ht - 1); + SET_REG_FIELD(1272, __GXData->cpTexSize, 8, 24, 0x4A); +} + +void GXSetDispCopyDst(u16 wd, u16 ht) { + u16 stride; + + ASSERTMSGLINE(1293, (wd & 0xF) == 0, "GXSetDispCopyDst: Width must be a multiple of 16"); + CHECK_GXBEGIN(1294, "GXSetDispCopyDst"); + + stride = (int)wd * 2; + __GXData->cpDispStride = 0; + SET_REG_FIELD(1300, __GXData->cpDispStride, 10, 0, (stride >> 5) ); + SET_REG_FIELD(1300, __GXData->cpDispStride, 8, 24, 0x4D); +} + +void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap) { + u32 rowTiles; + u32 colTiles; + u32 cmpTiles; + u32 peTexFmt; + u32 peTexFmtH; + + CHECK_GXBEGIN(1327, "GXSetTexCopyDst"); + + __GXData->cpTexZ = 0; + peTexFmt = fmt & 0xF; + ASSERTMSGLINEV(1358, peTexFmt < 13, "%s: invalid texture format", "GXSetTexCopyDst"); + + if (fmt == GX_TF_Z16) { + peTexFmt = 0xB; + } + + switch (fmt) { + case GX_TF_I4: + case GX_TF_I8: + case GX_TF_IA4: + case GX_TF_IA8: + case GX_CTF_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; +} + +u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale) { + u32 iScale; + ASSERTMSGLINE(1486, yScale >= 1.0f, "GXGetNumXfbLines: Vertical scale must be >= 1.0"); + + iScale = (u32)(256.0f / yScale) & 0x1FF; + return __GXGetNumXfbLines(efbHeight, iScale); +} + +f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight) { + f32 fScale; + f32 yScale; + u32 iScale; + u32 tgtHt; + u32 realHt; + + ASSERTMSGLINE(1510, xfbHeight <= 1024, "GXGetYScaleFactor: Display copy only supports up to 1024 lines.\n"); + ASSERTMSGLINE(1512, efbHeight <= xfbHeight, "GXGetYScaleFactor: EFB height should not be greater than XFB height.\n"); + + 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; +} + +void GXReadBoundingBox(u16* left, u16* top, u16* right, u16* bottom) { + *left = GX_GET_PE_REG(8); + *top = GX_GET_PE_REG(10); + *right = GX_GET_PE_REG(9); + *bottom = GX_GET_PE_REG(11); +} diff --git a/src/dolphin/gx/GXGeometry.c b/src/dolphin/gx/GXGeometry.c new file mode 100644 index 0000000..b41b70b --- /dev/null +++ b/src/dolphin/gx/GXGeometry.c @@ -0,0 +1,156 @@ +#include +#include +#include + +#include "__gx.h" + +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/src/dolphin/gx/GXInit.c b/src/dolphin/gx/GXInit.c new file mode 100644 index 0000000..02fba28 --- /dev/null +++ b/src/dolphin/gx/GXInit.c @@ -0,0 +1,570 @@ +#include + +#include +#include +#include +#include + +#include "__gx.h" + +#if SDK_REVISION < 2 +#define BUILD_DATE "Apr 5 2004" +#define DBUILD_TIME "03:55:13" +#define RBUILD_TIME "04:13:58" +#else +#define BUILD_DATE "Nov 10 2004" +#define DBUILD_TIME "06:08:50" +#define RBUILD_TIME "06:27:12" +#endif + +#ifdef DEBUG +const char* __GXVersion = "<< Dolphin SDK - GX\tdebug build: "BUILD_DATE" "DBUILD_TIME" (0x2301) >>"; +#else +const char* __GXVersion = "<< Dolphin SDK - GX\trelease build: "BUILD_DATE" "RBUILD_TIME" (0x2301) >>"; +#endif + +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 void DisableWriteGatherPipe(void) { + u32 hid2 = PPCMfhid2(); + + hid2 &= ~0x40000000; + PPCMthid2(hid2); +} + +static GXTexRegion*__GXDefaultTexRegionCallback(const GXTexObj* t_obj, GXTexMapID id) { + GXTexFmt fmt; + u8 mm; + + fmt = GXGetTexObjFmt(t_obj); + mm = GXGetTexObjMipMap(t_obj); + id = (GXTexMapID)(id % GX_MAX_TEXMAP); + + switch (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); + +void __GXInitRevisionBits(void) { + u32 i; + + for (i = 0; i < 8; i++) { + s32 regAddr; + SOME_SET_REG_MACRO(__GXData->vatA[i], 1, 30, 1); + SOME_SET_REG_MACRO(__GXData->vatB[i], 1, 31, 1); + + GX_WRITE_U8(0x8); + GX_WRITE_U8(i | 0x80); + GX_WRITE_U32(__GXData->vatB[i]); + regAddr = i - 12; + } + + { + u32 reg1 = 0; + u32 reg2 = 0; + + SOME_SET_REG_MACRO(reg1, 1, 0, 1); + SOME_SET_REG_MACRO(reg1, 1, 1, 1); + SOME_SET_REG_MACRO(reg1, 1, 2, 1); + SOME_SET_REG_MACRO(reg1, 1, 3, 1); + SOME_SET_REG_MACRO(reg1, 1, 4, 1); + SOME_SET_REG_MACRO(reg1, 1, 5, 1); + GX_WRITE_XF_REG(0, reg1); + + SOME_SET_REG_MACRO(reg2, 1, 0, 1); + GX_WRITE_XF_REG(0x12, reg2); +#if DEBUG + __gxVerif->xfRegsDirty[0] = 0; +#endif + } + + { + u32 reg = 0; + SOME_SET_REG_MACRO(reg, 1, 0, 1); + SOME_SET_REG_MACRO(reg, 1, 1, 1); + SOME_SET_REG_MACRO(reg, 1, 2, 1); + SOME_SET_REG_MACRO(reg, 1, 3, 1); + SOME_SET_REG_MACRO(reg, 8, 24, 0x58); + GX_WRITE_RAS_REG(reg); + } +} + +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 : GX_DISABLE)); + + 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/src/dolphin/gx/GXLight.c b/src/dolphin/gx/GXLight.c new file mode 100644 index 0000000..d1b005d --- /dev/null +++ b/src/dolphin/gx/GXLight.c @@ -0,0 +1,573 @@ +#include +#include +#include + +#include "__gx.h" + +// GXLightObj private data +typedef struct { + u32 reserved[3]; + u32 Color; + f32 a[3]; + f32 k[3]; + f32 lpos[3]; + f32 ldir[3]; +} __GXLightObjInt_struct; + +void GXInitLightAttn(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(129, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(130, "GXInitLightAttn"); + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; + obj->k[0] = k0; + obj->k[1] = k1; + obj->k[2] = k2; +} + +void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(143, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(144, "GXInitLightAttnA"); + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; +} + +void GXGetLightAttnA(const GXLightObj* lt_obj, f32* a0, f32* a1, f32* a2) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(153, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(154, "GXGetLightAttnA"); + *a0 = obj->a[0]; + *a1 = obj->a[1]; + *a2 = obj->a[2]; +} + +void GXInitLightAttnK(GXLightObj* lt_obj, f32 k0, f32 k1, f32 k2) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(163, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(164, "GXInitLightAttnK"); + obj->k[0] = k0; + obj->k[1] = k1; + obj->k[2] = k2; +} + +void GXGetLightAttnK(const GXLightObj* lt_obj, f32* k0, f32* k1, f32* k2) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(173, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(174, "GXGetLightAttnK"); + *k0 = obj->k[0]; + *k1 = obj->k[1]; + *k2 = obj->k[2]; +} + +void GXInitLightSpot(GXLightObj* lt_obj, f32 cutoff, GXSpotFn spot_func) { + f32 a0, a1, a2; + f32 r; + f32 d; + f32 cr; + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(198, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(200, "GXInitLightSpot"); + + if (cutoff <= 0.0f || cutoff > 90.0f) + spot_func = GX_SP_OFF; + + r = (3.1415927f * cutoff) / 180.0f; + cr = cosf(r); + + switch (spot_func) { + case GX_SP_FLAT: + 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; + + ASSERTMSGLINE(273, lt_obj != NULL, "Light Object Pointer is null"); + 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; + + ASSERTMSGLINE(328, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(330, "GXInitLightPos"); + + obj->lpos[0] = x; + obj->lpos[1] = y; + obj->lpos[2] = z; +} + +void GXGetLightPos(const GXLightObj* lt_obj, f32* x, f32* y, f32* z) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(339, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(341, "GXGetLightPos"); + + *x = obj->lpos[0]; + *y = obj->lpos[1]; + *z = obj->lpos[2]; +} + +void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(360, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + + obj->ldir[0] = -nx; + obj->ldir[1] = -ny; + obj->ldir[2] = -nz; +} + +void GXGetLightDir(const GXLightObj* lt_obj, f32* nx, f32* ny, f32* nz) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(372, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + + *nx = -obj->ldir[0]; + *ny = -obj->ldir[1]; + *nz = -obj->ldir[2]; +} + +void GXInitSpecularDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) { + f32 mag; + f32 vx; + f32 vy; + f32 vz; + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(398, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(399, "GXInitSpecularDir"); + + vx = -nx; + vy = -ny; + vz = -nz + 1.0f; + + mag = (vx * vx) + (vy * vy) + (vz * vz); + if (mag != 0.0f) { + mag = 1.0f / sqrtf(mag); + } + + obj->ldir[0] = vx * mag; + obj->ldir[1] = vy * mag; + obj->ldir[2] = vz * mag; + obj->lpos[0] = nx * -1000000000000000000.0f; + obj->lpos[1] = ny * -1000000000000000000.0f; + obj->lpos[2] = nz * -1000000000000000000.0f; +} + +void GXInitSpecularDirHA(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(436, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(437, "GXInitSpecularHA"); + + obj->ldir[0] = hx; + obj->ldir[1] = hy; + obj->ldir[2] = hz; + obj->lpos[0] = nx * -1000000000000000000.0f; + obj->lpos[1] = ny * -1000000000000000000.0f; + obj->lpos[2] = nz * -1000000000000000000.0f; +} + +void GXInitLightColor(GXLightObj* lt_obj, GXColor color) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(462, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(463, "GXInitLightColor"); + + *(u32*)&obj->Color = *(u32*)&color; +} + +void GXGetLightColor(const GXLightObj* lt_obj, GXColor* color) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(476, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(477, "GXGetLightColor"); + + *(u32*)color = *(u32*)&obj->Color; +} + +#if DEBUG +#define WRITE_SOME_LIGHT_REG1(val, addr) \ +do { \ + u32 xfData = val; \ + GX_WRITE_U32(val); \ + VERIF_MTXLIGHT(addr, xfData); \ +} while (0) + +#define WRITE_SOME_LIGHT_REG2(val, addr) \ +do { \ + f32 xfData = val; \ + GX_WRITE_F32(val); \ + VERIF_MTXLIGHT(addr, *(u32 *)&xfData); \ +} while (0) +#else +#define WRITE_SOME_LIGHT_REG1(val, addr) GX_WRITE_U32(val) +#define WRITE_SOME_LIGHT_REG2(val, addr) GX_WRITE_F32(val) +#endif + +static inline u32 ConvLightID2Num(GXLightID id) { + switch (id) { + case GX_LIGHT0: return 0; + case GX_LIGHT1: return 1; + case GX_LIGHT2: return 2; + case GX_LIGHT3: return 3; + case GX_LIGHT4: return 4; + case GX_LIGHT5: return 5; + case GX_LIGHT6: return 6; + case GX_LIGHT7: return 7; + default: return 8; + } +} + +static inline void PushLight(const register GXLightObj* lt_obj, register void* dest) { + 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(const GXLightObj* lt_obj, GXLightID light) { + u32 addr; + u32 idx; + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(568, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(569, "GXLoadLightObjImm"); + +#if DEBUG + idx = ConvLightID2Num(light); +#else + idx = 31 - __cntlzw(light); +#endif + + ASSERTMSGLINE(575, idx < 8, "GXLoadLightObjImm: Invalid Light Id"); + idx &= 7; + + addr = 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; +} + +void GXLoadLightObjIndx(u32 lt_obj_indx, GXLightID light) { + u32 reg; + u32 addr; + u32 idx; + + CHECK_GXBEGIN(624, "GXLoadLightObjIndx"); + +#if DEBUG + idx = ConvLightID2Num(light); +#else + idx = 31 - __cntlzw(light); +#endif + + ASSERTMSGLINE(627, idx < 8, "GXLoadLightObjIndx: Invalid Light Id"); + idx &= 7; + + addr = idx * 0x10 + 0x600; + reg = 0; + SET_REG_FIELD(632, reg, 12, 0, addr); + SET_REG_FIELD(634, reg, 4, 12, 0xF); + SET_REG_FIELD(634, reg, 16, 16, lt_obj_indx); + GX_WRITE_U8(0x38); + GX_WRITE_U32(reg); +#if DEBUG + __GXShadowIndexState(7, reg); +#endif + __GXData->bpSentNot = 1; +} + +#define GXCOLOR_AS_U32(color) (*((u32*)&(color))) + +void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color) { + u32 reg; + u32 rgb; + u32 colIdx; + + CHECK_GXBEGIN(661, "GXSetChanAmbColor"); + + switch (chan) { + case GX_COLOR0: + reg = __GXData->ambColor[GX_COLOR0]; + 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: + ASSERTMSGLINE(731, 0, "GXSetChanAmbColor: Invalid Channel Id"); + 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: + ASSERTMSGLINE(832, 0, "GXSetChanMatColor: Invalid Channel Id"); + return; + } + + GX_WRITE_XF_REG(colIdx + 12, reg); + __GXData->bpSentNot = 1; + __GXData->matColor[colIdx] = reg; +} + +void GXSetNumChans(u8 nChans) { + CHECK_GXBEGIN(857, "GXSetNumChans"); + ASSERTMSGLINE(858, nChans <= 2, "GXSetNumChans: nChans > 2"); + + SET_REG_FIELD(860, __GXData->genMode, 3, 4, nChans); + GX_WRITE_XF_REG(9, nChans); + __GXData->dirtyState |= 4; +} + +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"); + + ASSERTMSGLINE(895, chan >= GX_COLOR0 && chan <= GX_COLOR1A1, "GXSetChanCtrl: Invalid Channel Id"); + +#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/src/dolphin/gx/GXMisc.c b/src/dolphin/gx/GXMisc.c new file mode 100644 index 0000000..3c30698 --- /dev/null +++ b/src/dolphin/gx/GXMisc.c @@ -0,0 +1,481 @@ +#include +#include +#include +#include + +#include "__gx.h" + +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: + ASSERTMSGLINE(223, !__GXData->inDispList, "GXSetMisc: Cannot change DL context setting while making a display list"); + __GXData->dlSaveContext = (val != 0); + break; + case GX_MT_ABORT_WAIT_COPYOUT: + __GXData->abtWaitPECopy = (val != 0); + break; + case GX_MT_NULL: + break; + default: +#if DEBUG + OSReport("GXSetMisc: bad token %d (val %d)\n", token, val); +#endif + break; + } +} + +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(); +} + +void GXResetWriteGatherPipe(void) { + while (PPCMfwpar() & 1) { + } + PPCMtwpar(OSUncachedToPhysical((void *)GXFIFO_ADDR)); +} + +static void __GXAbortWait(u32 clocks) { + OSTime time0; + OSTime time1; + + time0 = OSGetTime(); + do { + time1 = OSGetTime(); + } while (time1 - time0 <= (clocks / 4)); +} + +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 GXAbortFrame(void) { + __GXAbort(); + + if (GXGetGPFifo() != (GXFifoObj*)NULL) { + __GXCleanGPFifo(); + __GXInitRevisionBits(); + __GXData->dirtyState = 0; + GXFlush(); + } +} + +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) { + CHECK_GXBEGIN(566, "GXDrawDone"); + GXSetDrawDone(); + GXWaitDrawDone(); +} + +void GXPixModeSync(void) { + CHECK_GXBEGIN(601, "GXPixModeSync"); + GX_WRITE_RAS_REG(__GXData->peCtrl); + __GXData->bpSentNot = 0; +} + +void GXTexModeSync(void) { + u32 reg; + + CHECK_GXBEGIN(625, "GXTexModeSync"); + reg = 0x63000000; + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +#if DEBUG +void __GXBypass(u32 reg) { + CHECK_GXBEGIN(647, "__GXBypass"); + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +u16 __GXReadPEReg(u32 reg) { + return GX_GET_PE_REG(reg); +} +#endif + +void GXPokeAlphaMode(GXCompare func, u8 threshold) { + u32 reg; + + reg = (func << 8) | threshold; + GX_SET_PE_REG(3, reg); +} + +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); +} + +void GXPeekARGB(u16 x, u16 y, u32* color) { + u32 addr = (u32)OSPhysicalToUncached(0x08000000); + + SET_REG_FIELD(792, addr, 10, 2, x); + SET_REG_FIELD(793, addr, 10, 12, y); + SET_REG_FIELD(793, addr, 2, 22, 0); + *color = *(u32*)addr; +} + +void GXPokeARGB(u16 x, u16 y, u32 color) { + u32 addr = (u32)OSPhysicalToUncached(0x08000000); + + SET_REG_FIELD(0x322, addr, 10, 2, x); + SET_REG_FIELD(0x323, addr, 10, 12, y); + SET_REG_FIELD(0x323, addr, 2, 22, 0); + *(u32*)addr = color; +} + +void GXPeekZ(u16 x, u16 y, u32* z) { + u32 addr = (u32)OSPhysicalToUncached(0x08000000); + + SET_REG_FIELD(812, addr, 10, 2, x); + SET_REG_FIELD(813, addr, 10, 12, y); + SET_REG_FIELD(813, addr, 2, 22, 1); + *z = *(u32*)addr; +} + +void GXPokeZ(u16 x, u16 y, u32 z) { + u32 addr = (u32)OSPhysicalToUncached(0x08000000); + + SET_REG_FIELD(822, addr, 10, 2, x); + SET_REG_FIELD(823, addr, 10, 12, y); + SET_REG_FIELD(823, addr, 2, 22, 1); + *(u32*)addr = z; +} + +GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb) { + GXDrawSyncCallback oldcb; + BOOL enabled; + + oldcb = TokenCB; + enabled = OSDisableInterrupts(); + TokenCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +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); +} + +u32 GXCompressZ16(u32 z24, GXZFmt16 zfmt) { + u32 z16; + u32 z24n; + s32 exp; + s32 shift; +#if DEBUG +#define temp exp +#else + s32 temp; + u8 unused[4]; +#endif + + z24n = ~(z24 << 8); + temp = __cntlzw(z24n); + switch (zfmt) { + case GX_ZC_LINEAR: + z16 = (z24 >> 8) & 0xFFFF; + break; + case GX_ZC_NEAR: + if (temp > 3) { + exp = 3; + } else { + exp = temp; + } + if (exp == 3) { + shift = 7; + } else { + shift = 9 - exp; + } + z16 = ((z24 >> shift) & 0x3FFF & ~0xFFFFC000) | (exp << 14); + break; + case GX_ZC_MID: + if (temp > 7) { + exp = 7; + } else { + exp = temp; + } + if (exp == 7) { + shift = 4; + } else { + shift = 10 - exp; + } + z16 = ((z24 >> shift) & 0x1FFF & ~0xFFFFE000) | (exp << 13); + break; + case GX_ZC_FAR: + if (temp > 12) { + exp = 12; + } else { + exp = temp; + } + if (exp == 12) { + shift = 0; + } else { + shift = 11 - exp; + } + z16 = ((z24 >> shift) & 0xFFF & ~0xFFFFF000) | (exp << 12); + break; + default: + OSPanic(__FILE__, 1004, "GXCompressZ16: Invalid Z format\n"); + break; + } + return z16; +} + +u32 GXDecompressZ16(u32 z16, GXZFmt16 zfmt) { + u32 z24; + u32 cb1; + s32 exp; + s32 shift; + + cb1; cb1; cb1; z16; z16; z16; // needed to match + + switch (zfmt) { + case GX_ZC_LINEAR: + z24 = (z16 << 8) & 0xFFFF00; + break; + case GX_ZC_NEAR: + exp = (z16 >> 14) & 3; + if (exp == 3) { + shift = 7; + } else { + shift = 9 - exp; + } + cb1 = -1 << (24 - exp); + z24 = (cb1 | ((z16 & 0x3FFF) << shift)) & 0xFFFFFF; + break; + case GX_ZC_MID: + exp = (z16 >> 13) & 7; + if (exp == 7) { + shift = 4; + } else { + shift = 10 - exp; + } + cb1 = -1 << (24 - exp); + z24 = (cb1 | ((z16 & 0x1FFF) << shift)) & 0xFFFFFF; + break; + case GX_ZC_FAR: + exp = (z16 >> 12) & 0xF; + if (exp == 12) { + shift = 0; + } else { + shift = 11 - exp; + } + cb1 = -1 << (24 - exp); + z24 = (cb1 | ((z16 & 0xFFF) << shift)) & 0xFFFFFF; + break; + default: + OSPanic(__FILE__, 1054, "GXDecompressZ16: Invalid Z format\n"); + break; + } + return z24; +} diff --git a/src/dolphin/gx/GXPerf.c b/src/dolphin/gx/GXPerf.c new file mode 100644 index 0000000..9a850ee --- /dev/null +++ b/src/dolphin/gx/GXPerf.c @@ -0,0 +1,431 @@ +#include +#include + +#include "__gx.h" + +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: + ASSERTMSGLINE(194, 0, "GXSetGPMetric: Invalid GXPerf0 metric name"); + 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: + ASSERTMSGLINE(244, 0, "GXSetGPMetric: Invalid GXPerf1 metric name"); + break; + } + + __GXData->perf0 = perf0; + switch (__GXData->perf0) { + case GX_PERF0_VERTICES: + ASSERTMSGLINE(258, 0, "The use of GX_PERF0_VERTICES is prohibited. Use GX_PERF1_VERTICES instead.\n"); + reg = 0x273; + GX_WRITE_XF_REG(6, reg); + break; + case GX_PERF0_CLIP_VTX: reg = 0x14A; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_CLIP_CLKS: reg = 0x16B; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_WAIT_IN: reg = 0x84; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_WAIT_OUT: reg = 0xC6; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_XFRM_CLKS: reg = 0x210; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_LIT_CLKS: reg = 0x252; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_BOT_CLKS: reg = 0x231; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_REGLD_CLKS: reg = 0x1AD; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_REGRD_CLKS: reg = 0x1CE; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_CLOCKS: reg = 0x21; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_CLIP_RATIO: reg = 0x153; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_TRIANGLES: reg = 0x2300AE7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_CULLED: reg = 0x23008E7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_PASSED: reg = 0x23009E7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_SCISSORED: reg = 0x23001E7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_0TEX: reg = 0x2300AC3F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_1TEX: reg = 0x2300AC7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_2TEX: reg = 0x2300ACBF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_3TEX: reg = 0x2300ACFF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_4TEX: reg = 0x2300AD3F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_5TEX: reg = 0x2300AD7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_6TEX: reg = 0x2300ADBF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_7TEX: reg = 0x2300ADFF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_8TEX: reg = 0x2300AE3F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_0CLR: reg = 0x2300A27F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_1CLR: reg = 0x2300A67F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_2CLR: reg = 0x2300AA7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_0CVG: reg = 0x2402C0C6; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_NON0CVG: reg = 0x2402C16B; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_1CVG: reg = 0x2402C0E7; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_2CVG: reg = 0x2402C108; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_3CVG: reg = 0x2402C129; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_4CVG: reg = 0x2402C14A; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_AVG_QUAD_CNT: reg = 0x2402C1AD; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_NONE: break; + default: + ASSERTMSGLINE(504, 0, "GXSetGPMetric: Invalid GXPerf0 metric name"); + break; + } + + __GXData->perf1 = perf1; + switch (__GXData->perf1) { + case GX_PERF1_TEXELS: reg = 0x67000042; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TX_IDLE: reg = 0x67000084; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TX_REGS: reg = 0x67000063; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TX_MEMSTALL: reg = 0x67000129; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_MISS: reg = 0x67000252; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_CLOCKS: reg = 0x67000021; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_CHECK1_2: reg = 0x6700014B; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_CHECK3_4: reg = 0x6700018D; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_CHECK5_6: reg = 0x670001CF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_CHECK7_8: reg = 0x67000211; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_VC_ELEMQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 2); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_MISSQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 3); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_MEMREQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 4); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_STATUS7: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 5); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_MISSREP_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 6); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_STREAMBUF_LOW: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 7); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_ALL_STALLS: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 9); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VERTICES: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 8); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_FIFO_REQ: reg = 2; GX_SET_CP_REG(3, reg); break; + case GX_PERF1_CALL_REQ: reg = 3; GX_SET_CP_REG(3, reg); break; + case GX_PERF1_VC_MISS_REQ: reg = 4; GX_SET_CP_REG(3, reg); break; + case GX_PERF1_CP_ALL_REQ: reg = 5; GX_SET_CP_REG(3, reg); break; + case GX_PERF1_NONE: break; + default: + ASSERTMSGLINE(649, 0, "GXSetGPMetric: Invalid GXPerf1 metric name"); + break; + } + + __GXData->bpSentNot = 0; +} + +#pragma scheduling off +void GXReadGPMetric(u32* cnt0, u32* cnt1) { + u32 cpCtr0, cpCtr1, cpCtr2, cpCtr3; + + cpCtr0 = __GXReadCPCounterU32(32, 33); + cpCtr1 = __GXReadCPCounterU32(34, 35); + cpCtr2 = __GXReadCPCounterU32(36, 37); + cpCtr3 = __GXReadCPCounterU32(38, 39); + + switch (__GXData->perf0) { + case GX_PERF0_CLIP_RATIO: + *cnt0 = cpCtr1 * 1000 / cpCtr0; + break; + case GX_PERF0_VERTICES: + case GX_PERF0_CLIP_VTX: + case GX_PERF0_CLIP_CLKS: + case GX_PERF0_XF_WAIT_IN: + case GX_PERF0_XF_WAIT_OUT: + case GX_PERF0_XF_XFRM_CLKS: + case GX_PERF0_XF_LIT_CLKS: + case GX_PERF0_XF_BOT_CLKS: + case GX_PERF0_XF_REGLD_CLKS: + case GX_PERF0_XF_REGRD_CLKS: + case GX_PERF0_TRIANGLES: + case GX_PERF0_TRIANGLES_CULLED: + case GX_PERF0_TRIANGLES_PASSED: + case GX_PERF0_TRIANGLES_SCISSORED: + case GX_PERF0_TRIANGLES_0TEX: + case GX_PERF0_TRIANGLES_1TEX: + case GX_PERF0_TRIANGLES_2TEX: + case GX_PERF0_TRIANGLES_3TEX: + case GX_PERF0_TRIANGLES_4TEX: + case GX_PERF0_TRIANGLES_5TEX: + case GX_PERF0_TRIANGLES_6TEX: + case GX_PERF0_TRIANGLES_7TEX: + case GX_PERF0_TRIANGLES_8TEX: + case GX_PERF0_TRIANGLES_0CLR: + case GX_PERF0_TRIANGLES_1CLR: + case GX_PERF0_TRIANGLES_2CLR: + case GX_PERF0_QUAD_0CVG: + case GX_PERF0_QUAD_NON0CVG: + case GX_PERF0_QUAD_1CVG: + case GX_PERF0_QUAD_2CVG: + case GX_PERF0_QUAD_3CVG: + case GX_PERF0_QUAD_4CVG: + case GX_PERF0_AVG_QUAD_CNT: + case GX_PERF0_CLOCKS: + *cnt0 = cpCtr0; + break; + case GX_PERF0_NONE: + *cnt0 = 0; + break; + default: + ASSERTMSGLINE(765, 0, "GXReadGPMetric: Invalid GXPerf0 metric name"); + *cnt0 = 0; + break; + } + + switch (__GXData->perf1) { + case GX_PERF1_TEXELS: + *cnt1 = cpCtr3 * 4; + break; + case GX_PERF1_TC_CHECK1_2: + *cnt1 = cpCtr2 + (cpCtr3 * 2); + break; + case GX_PERF1_TC_CHECK3_4: + *cnt1 = (cpCtr2 * 3) + (cpCtr3 * 4); + break; + case GX_PERF1_TC_CHECK5_6: + *cnt1 = (cpCtr2 * 5) + (cpCtr3 * 6); + break; + case GX_PERF1_TC_CHECK7_8: + *cnt1 = (cpCtr2 * 7) + (cpCtr3 * 8); + break; + case GX_PERF1_TX_IDLE: + case GX_PERF1_TX_REGS: + case GX_PERF1_TX_MEMSTALL: + case GX_PERF1_TC_MISS: + case GX_PERF1_VC_ELEMQ_FULL: + case GX_PERF1_VC_MISSQ_FULL: + case GX_PERF1_VC_MEMREQ_FULL: + case GX_PERF1_VC_STATUS7: + case GX_PERF1_VC_MISSREP_FULL: + case GX_PERF1_VC_STREAMBUF_LOW: + case GX_PERF1_VC_ALL_STALLS: + case GX_PERF1_VERTICES: + case GX_PERF1_CLOCKS: + *cnt1 = cpCtr3; + break; + case GX_PERF1_FIFO_REQ: + case GX_PERF1_CALL_REQ: + case GX_PERF1_VC_MISS_REQ: + case GX_PERF1_CP_ALL_REQ: + *cnt1 = cpCtr2; + break; + case GX_PERF1_NONE: + *cnt1 = 0; + break; + default: + ASSERTMSGLINE(824, 0, "GXReadGPMetric: Invalid GXPerf1 metric name"); + *cnt1 = 0; + break; + } +} +#pragma scheduling reset + +void GXClearGPMetric(void) { + u32 reg; + + reg = 4; + GX_SET_CP_REG(2, reg); +} + +u32 GXReadGP0Metric(void) { + u32 cnt0, cnt1; + + GXReadGPMetric(&cnt0, &cnt1); + return cnt0; +} + +u32 GXReadGP1Metric(void) { + u32 cnt0, cnt1; + + GXReadGPMetric(&cnt0, &cnt1); + return cnt1; +} + +#pragma scheduling off +void GXReadMemMetric(u32* cp_req, u32* tc_req, u32* cpu_rd_req, u32* cpu_wr_req, u32* dsp_req, u32* io_req, u32* vi_req, u32* pe_req, u32* rf_req, u32* fi_req) { + *cp_req = __GXReadMEMCounterU32(26, 25); + *tc_req = __GXReadMEMCounterU32(28, 27); + *cpu_rd_req = __GXReadMEMCounterU32(30, 29); + *cpu_wr_req = __GXReadMEMCounterU32(32, 31); + *dsp_req = __GXReadMEMCounterU32(34, 33); + *io_req = __GXReadMEMCounterU32(36, 35); + *vi_req = __GXReadMEMCounterU32(38, 37); + *pe_req = __GXReadMEMCounterU32(40, 39); + *rf_req = __GXReadMEMCounterU32(42, 41); + *fi_req = __GXReadMEMCounterU32(44, 43); +} +#pragma scheduling reset + +void GXClearMemMetric(void) { + GX_SET_MEM_REG(25, 0); + GX_SET_MEM_REG(26, 0); + GX_SET_MEM_REG(27, 0); + GX_SET_MEM_REG(28, 0); + GX_SET_MEM_REG(30, 0); + GX_SET_MEM_REG(29, 0); + GX_SET_MEM_REG(32, 0); + GX_SET_MEM_REG(31, 0); + GX_SET_MEM_REG(34, 0); + GX_SET_MEM_REG(33, 0); + GX_SET_MEM_REG(36, 0); + GX_SET_MEM_REG(35, 0); + GX_SET_MEM_REG(38, 0); + GX_SET_MEM_REG(37, 0); + GX_SET_MEM_REG(40, 0); + GX_SET_MEM_REG(39, 0); + GX_SET_MEM_REG(42, 0); + GX_SET_MEM_REG(41, 0); + GX_SET_MEM_REG(44, 0); + GX_SET_MEM_REG(43, 0); +} + +#pragma scheduling off +void GXReadPixMetric(u32* top_pixels_in, u32* top_pixels_out, u32* bot_pixels_in, u32* bot_pixels_out, u32* clr_pixels_in, u32* copy_clks) { + *top_pixels_in = __GXReadPECounterU32(12, 13) * 4; + *top_pixels_out = __GXReadPECounterU32(14, 15) * 4; + *bot_pixels_in = __GXReadPECounterU32(16, 17) * 4; + *bot_pixels_out = __GXReadPECounterU32(18, 19) * 4; + *clr_pixels_in = __GXReadPECounterU32(20, 21) * 4; + *copy_clks = __GXReadPECounterU32(22, 23); +} +#pragma scheduling reset + +void GXClearPixMetric(void) { + u32 reg; + + CHECK_GXBEGIN(1163, "GXClearPixMetric"); + + reg = 0x57000000; + GX_WRITE_RAS_REG(reg); + reg = 0x57000AAA; + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +void GXSetVCacheMetric(GXVCachePerf attr) { + u32 reg; + + SET_REG_FIELD(1194, __GXData->perfSel, 4, 0, attr); + GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); + reg = 1; + GX_WRITE_SOME_REG4(8, 0x10, reg, -12); +} + +#pragma scheduling off +void GXReadVCacheMetric(u32* check, u32* miss, u32* stall) { + *check = __GXReadCPCounterU32(40, 41); + *miss = __GXReadCPCounterU32(42, 43); + *stall = __GXReadCPCounterU32(44, 45); +} +#pragma scheduling reset + +void GXClearVCacheMetric(void) { + GX_WRITE_SOME_REG4(8, 0, 0, -12); +} + +void GXInitXfRasMetric(void) { + u32 reg; + + CHECK_GXBEGIN(1293, "GXInitXfRasMetric"); + + reg = 0x2402C022; + GX_WRITE_RAS_REG(reg); + reg = 0x31000; + GX_WRITE_XF_REG(6, reg); + __GXData->bpSentNot = 1; +} + +#pragma scheduling off +void GXReadXfRasMetric(u32* xf_wait_in, u32* xf_wait_out, u32* ras_busy, u32* clocks) { + *ras_busy = __GXReadCPCounterU32(32, 33); + *clocks = __GXReadCPCounterU32(34, 35); + *xf_wait_in = __GXReadCPCounterU32(36, 37); + *xf_wait_out = __GXReadCPCounterU32(38, 39); +} +#pragma scheduling reset + +u32 GXReadClksPerVtx(void) { + u32 perfCnt; + u32 ctrh; + + GXDrawDone(); + GX_SET_CP_REG(49, 0x1007); + GX_SET_CP_REG(48, 0x1007); + + ctrh = GX_GET_CP_REG(50); + perfCnt = ctrh >> 8; + return perfCnt; +} + +void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial) { + __MEMRegs[9] = cpDial; + __MEMRegs[10] = tcDial; + __MEMRegs[11] = peDial; + __MEMRegs[12] = cpuRdDial; + __MEMRegs[13] = cpuWrDial; +} diff --git a/src/dolphin/gx/GXPixel.c b/src/dolphin/gx/GXPixel.c new file mode 100644 index 0000000..027276c --- /dev/null +++ b/src/dolphin/gx/GXPixel.c @@ -0,0 +1,334 @@ +#include +#include +#include + +#include "__gx.h" + +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"); + + ASSERTMSGLINE(140, farz >= 0.0f, "GXSetFog: The farz should be positive value"); + ASSERTMSGLINE(141, farz >= nearz, "GXSetFog: The farz should be larger than nearz"); + + fsel = type & 7; + proj = (type >> 3) & 1; + + if (proj) { + if (farz == nearz || endz == startz) { + a = 0.0f; + c = 0.0f; + } else { + A = (1.0f / (endz - startz)); + 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 GXSetFogColor(GXColor color) { + u32 rgba; + u32 fogclr = 0xF2000000; + + rgba = *(u32*)&color; + SET_REG_FIELD(250, fogclr, 24, 0, rgba >> 8); + GX_WRITE_RAS_REG(fogclr); + __GXData->bpSentNot = 0; +} + +void GXInitFogAdjTable(GXFogAdjTable *table, u16 width, const f32 projmtx[4][4]) { + f32 xi; + f32 iw; + f32 rangeVal; + f32 nearZ; + f32 sideX; + u32 i; + + CHECK_GXBEGIN(275, "GXInitFogAdjTable"); + ASSERTMSGLINE(276, table != NULL, "GXInitFogAdjTable: table pointer is null"); + ASSERTMSGLINE(277, width <= 640, "GXInitFogAdjTable: invalid width value"); + + if (0.0 == projmtx[3][3]) { + nearZ = projmtx[2][3] / (projmtx[2][2] - 1.0f); + sideX = nearZ / projmtx[0][0]; + } else { + sideX = 1.0f / projmtx[0][0]; + nearZ = 1.73205f * sideX; + } + + iw = 2.0f / width; + for (i = 0; i < 10; i++) { + xi = (i + 1) << 5; + xi *= iw; + xi *= sideX; + rangeVal = sqrtf(1.0f + ((xi * xi) / (nearZ * nearZ))); + table->r[i] = (u32)(256.0f * rangeVal) & 0xFFF; + } +} + +void GXSetFogRangeAdj(GXBool enable, u16 center, const GXFogAdjTable *table) { + u32 i; + u32 range_adj; + u32 range_c; + + CHECK_GXBEGIN(331, "GXSetFogRangeAdj"); + + if (enable) { + ASSERTMSGLINE(334, table != NULL, "GXSetFogRangeAdj: table pointer is null"); + for (i = 0; i < 10; i += 2) { + range_adj = 0; + SET_REG_FIELD(338, range_adj, 12, 0, table->r[i]); + SET_REG_FIELD(339, range_adj, 12, 12, table->r[i + 1]); + SET_REG_FIELD(340, range_adj, 8, 24, (i >> 1) + 0xE9); + GX_WRITE_RAS_REG(range_adj); + } + } + 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; + ASSERTMSGLINE(515, pix_fmt >= GX_PF_RGB8_Z24 && pix_fmt <= GX_PF_YUV420, "Invalid Pixel format"); + SET_REG_FIELD(517, __GXData->peCtrl, 3, 0, p2f[pix_fmt]); + SET_REG_FIELD(518, __GXData->peCtrl, 3, 3, z_fmt); + + 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/src/dolphin/gx/GXSave.c b/src/dolphin/gx/GXSave.c new file mode 100644 index 0000000..90b9a82 --- /dev/null +++ b/src/dolphin/gx/GXSave.c @@ -0,0 +1,528 @@ +#if DEBUG + +#include +#include + +#include "__gx.h" + +static const u8* dlist; +static u32 dlistSize; +static u32 bytesRead; + +// prototypes +void __GXShadowIndexState(u32 idx_reg, u32 reg_data); + +static u8 __ReadMem(void* ptr, u32 sz) { + const u8* src; + u8* dst; + u32 i; + + if (sz > dlistSize - bytesRead) { + return FALSE; + } + + src = dlist; + dst = ptr; + for (i = 0; i < sz; i++) { + *dst++ = *src++; + } + bytesRead += sz; + dlist += sz; + return TRUE; +} + +inline void DPF(char*, ...) { + u8 unused[4]; +} + +static void __SaveCPRegs(u8 reg, u8 vatIdx, u32 data) { + s32 idx; + + DPF("\tCP Stream Reg[0x%x] = 0x%x\n", reg, data); + + switch (reg) { + case 0: + case 1: + case 2: + case 3: + case 4: + break; + case 5: + __GXData->vcdLo = data; + break; + case 6: + __GXData->vcdHi = data; + break; + case 7: + __GXData->vatA[vatIdx & 0xFF] = data; + break; + case 8: + __GXData->vatB[vatIdx & 0xFF] = data; + break; + case 9: + __GXData->vatC[vatIdx & 0xFF] = data; + break; + case 10: + idx = vatIdx - 0x15; + if ((idx >= 0) && (idx < 4)) { + __GXData->indexBase[idx] = data; + } + break; + case 11: + idx = vatIdx - 0x15; + if ((idx >= 0) && (idx < 4)) { + __GXData->indexStride[idx] = data; + } + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_INV_CMD]) { + __GX_WARN(GXWARN_DL_INV_CMD); + } + OSReport("[Invalid CP Stream Register Address 0x%x\n]", reg); + break; + } +} + +static void __ReconstVtxStatus(u8 vatIdx) { + u32 vat; + + if (GET_REG_FIELD(__GXData->vcdLo, 2, 11) & 3) { + vat = __GXData->vatA[vatIdx]; + if ((vat >> 9) & 1) { + __GXData->hasNrms = 0; + __GXData->hasBiNrms = 1; + } else { + __GXData->hasNrms = 1; + __GXData->hasBiNrms = 0; + } + } +} + +static u32 vtxCompSize[5] = { 1, 1, 2, 2, 4 }; +static int clrCompSize[6] = { 2, 3, 4, 2, 3, 4 }; + +static u32 GetAttrSize(u8 vatIdx, u32 attrIdx) { + u32 vcd; + u32 vat; + u32 nc; + + switch (attrIdx) { + case 0: + return GET_REG_FIELD(__GXData->vcdLo, 1, 0) ? 1 : 0; + case 1: + return GET_REG_FIELD(__GXData->vcdLo, 1, 1) ? 1 : 0; + case 2: + return GET_REG_FIELD(__GXData->vcdLo, 1, 2) ? 1 : 0; + case 3: + return GET_REG_FIELD(__GXData->vcdLo, 1, 3) ? 1 : 0; + case 4: + return GET_REG_FIELD(__GXData->vcdLo, 1, 4) ? 1 : 0; + case 5: + return GET_REG_FIELD(__GXData->vcdLo, 1, 5) ? 1 : 0; + case 6: + return GET_REG_FIELD(__GXData->vcdLo, 1, 6) ? 1 : 0; + case 7: + return GET_REG_FIELD(__GXData->vcdLo, 1, 7) ? 1 : 0; + case 8: + return GET_REG_FIELD(__GXData->vcdLo, 1, 8) ? 1 : 0; + case 9: + vcd = __GXData->vcdLo; + vat = __GXData->vatA[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 9)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return ((vat & 1) + 2) * vtxCompSize[(vat >> 1) & 7]; + } + break; + case 10: + vcd = __GXData->vcdLo; + vat = __GXData->vatA[vatIdx & 0xFF]; + + switch (GET_REG_FIELD(vcd, 2, 11)) { + case 0: + return 0; + case 2: + if ((vat >> 9) & 1 && vat >> 31) { + nc = 3; + } else { + nc = 1; + } + return nc; + case 3: + if ((vat >> 9) & 1 && vat >> 31) { + nc = 6; + } else { + nc = 2; + } + return nc; + case 1: + if ((vat >> 9) & 1) { + nc = 9; + } else { + nc = 3; + } + return nc * vtxCompSize[(vat >> 10) & 7]; + } + break; + case 11: + switch (GET_REG_FIELD(__GXData->vcdLo, 2, 13)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + vat = __GXData->vatA[vatIdx]; + return clrCompSize[(vat >> 14) & 7]; + } + break; + case 12: + switch (GET_REG_FIELD(__GXData->vcdLo, 2, 15)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + vat = __GXData->vatA[vatIdx]; + return clrCompSize[(vat >> 18) & 7]; + } + break; + case 13: + vcd = __GXData->vcdHi; + vat = __GXData->vatA[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 0)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 21) & 1) + 1) * vtxCompSize[(vat >> 22) & 7]; + } + break; + case 14: + vcd = __GXData->vcdHi; + vat = __GXData->vatB[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 2)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 0) & 1) + 1) * vtxCompSize[(vat >> 1) & 7]; + } + break; + case 15: + vcd = __GXData->vcdHi; + vat = __GXData->vatB[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 4)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 9) & 1) + 1) * vtxCompSize[(vat >> 10) & 7]; + } + break; + case 16: + vcd = __GXData->vcdHi; + vat = __GXData->vatB[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 6)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 18) & 1) + 1) * vtxCompSize[(vat >> 19) & 7]; + } + break; + case 17: + vcd = __GXData->vcdHi; + vat = __GXData->vatB[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 8)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 27) & 1) + 1) * vtxCompSize[(vat >> 28) & 7]; + } + break; + case 18: + vcd = __GXData->vcdHi; + vat = __GXData->vatC[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 10)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 5) & 1) + 1) * vtxCompSize[(vat >> 6) & 7]; + } + break; + case 19: + vcd = __GXData->vcdHi; + vat = __GXData->vatC[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 12)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 14) & 1) + 1) * vtxCompSize[(vat >> 15) & 7]; + } + break; + case 20: + vcd = __GXData->vcdHi; + vat = __GXData->vatC[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 14)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 23) & 1) + 1) * vtxCompSize[(vat >> 24) & 7]; + } + break; + } + return 0; +} + +static void __ParseVertexData(u8 vatIdx) { + u16 vcnt; + GXAttr attrIdx; + u32 vsize; + + if (__ReadMem(&vcnt, 2)) { + vsize = 0; + for (attrIdx = 0; attrIdx < GX_VA_MAX_ATTR; attrIdx++) { + if (attrIdx != GX_VA_NBT) { + vsize += GetAttrSize(vatIdx, attrIdx); + } + } + vsize *= vcnt; + dlist += vsize; + bytesRead += vsize; + } +} + +void __GXShadowDispList(void* list, u32 nbytes) { + u8 cmd; + u8 cmdOp; + u8 vatIdx; + u32 reg32; + u32 d32; + u8 reg8; + u8 cpAddr; + u32 i; + u32 addr; + u32 cnt; + + if (__gxVerif->verifyLevel == GX_WARN_NONE) { + return; + } + + dlist = list; + dlistSize = nbytes; + bytesRead = 0; + + DPF("Displaylist IN\n"); + + while (dlistSize > bytesRead) { + if (!__ReadMem(&cmd, 1)) { + break; + } + cmdOp = (u32)GET_REG_FIELD((u32)cmd, 5, 3); + vatIdx = cmd & 7; + switch (cmdOp) { + case 0: + case 9: + break; + case 16: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + __ReconstVtxStatus(vatIdx); + __GXVerifyState(vatIdx); + __ParseVertexData(vatIdx); + break; + case 1: + if (__ReadMem(®8, 1) && __ReadMem(&d32, 4)) { + vatIdx = reg8 & 0xF; + cpAddr = (reg8& 0xF0) >> 4; + __SaveCPRegs(cpAddr, vatIdx, d32); + } + break; + case 2: + if (__ReadMem(®32, 4)) { + cnt = GET_REG_FIELD(reg32, 4, 16) + 1; + addr = (u16)reg32; + DPF("\tXFReg = 0x%x, Cnt = %d\n", addr, cnt); + for (i = 0; i < cnt; i++) { + if (__ReadMem(&d32, 4)) { + DPF("\tXFData = 0x%x\n", d32); + VERIF_MTXLIGHT(addr, d32); + addr++; + } + } + } + break; + case 4: + case 5: + case 6: + case 7: + if (__ReadMem(®32, 4)) { + DPF("\tXF_INDEX_LOAD: = 0x%x\n", reg32); + __GXShadowIndexState(cmdOp, reg32); + } + break; + case 8: + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_NESTED]) { + __GX_WARN(GXWARN_DL_NESTED); + } + return; + case 12: + case 13: + if (__ReadMem(®32, 4)) { + DPF("\tSU Bypass = 0x%x\n", reg32); + __gxVerif->rasRegs[(reg32 >> 24) & 0xFF] = reg32; + } + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_INV_CMD]) { + __GX_WARN(GXWARN_DL_INV_CMD); + } + OSReport("[Bad Display List Command: 0x%02X\n]", cmdOp); + break; + } + } + + DPF("Displaylist OUT\n"); +} + +void __GXShadowIndexState(u32 idx_reg, u32 reg_data) { + u32* basePtr; + u32* memAddr; + u32 cnt; + u32 stride; + u32 addr; + u32 data; + u32 index; + u32 i; + + i = idx_reg - 4; + basePtr = OSPhysicalToCached(__GXData->indexBase[i]); + stride = __GXData->indexStride[i]; + addr = reg_data & 0xFFF; + cnt = (reg_data >> 12) & 0xF; + index = reg_data >> 16; + memAddr = (u32*)((u8*)basePtr + (index * stride)); + cnt++; + + while (cnt-- != 0) { + data = *memAddr; + VERIF_MTXLIGHT(addr, data); + memAddr = (u32*)((u8*)memAddr + stride); + addr++; + } + + &data; // needed to match +} + +void __GXPrintShadowState(void) { + u32 i; + u32 j; + + OSReport("CP State:\n"); + OSReport("\tvcdLo = 0x%x\n", __GXData->vcdLo); + OSReport("\tvcdHi = 0x%x\n", __GXData->vcdHi); + OSReport("\thasBiNrms = 0x%x\n", __GXData->hasBiNrms); + + for (i = 0; i < 8; i++) { + OSReport("\tVertex Format %d:\n", i); + OSReport("\t\tvatA = 0x%x\n", __GXData->vatA[i]); + OSReport("\t\tvatB = 0x%x\n", __GXData->vatB[i]); + OSReport("\t\tvatC = 0x%x\n", __GXData->vatC[i]); + } + + OSReport("\n-------------------------------------\n"); + OSReport("XF Pos/Tex Matrix State:\n"); + + for (i = 0; i < 256; i += 4) { + if (__gxVerif->xfMtxDirty[i]) { + OSReport("\tXF_MATRIX[%d] = ", i); + OSReport("%f, %f, %f, %f\n", *(f32*)&__gxVerif->xfMtx[i], *(f32*)&__gxVerif->xfMtx[i + 1], *(f32*)&__gxVerif->xfMtx[i + 2], *(f32*)&__gxVerif->xfMtx[i + 3]); + } + } + + OSReport("\n-------------------------------------\n"); + OSReport("XF Normal Matrix State:\n"); + + for (i = 0; i < 96; i += 3) { + if (__gxVerif->xfNrmDirty[i]) { + OSReport("\tXF_NRM_MTX[%d] = ", i); + OSReport("%f, %f, %f\n", *(f32*)&__gxVerif->xfMtx[i], *(f32*)&__gxVerif->xfMtx[i + 1], *(f32*)&__gxVerif->xfMtx[i + 2]); + } + } + + OSReport("\n-------------------------------------\n"); + OSReport("XF Light State:\n"); + + for (i = 0; i < 128; i += 16) { + if (__gxVerif->xfLightDirty[i]) { + OSReport("\tXF_LIGHT[%d]:\n", i >> 4); + for (j = 0; j < 4; j++) { + OSReport("\t\tparam[%d] = 0x%x\n", j, __gxVerif->xfLight[i + j]); + } + for (j = 4; j < 16; j++) { + OSReport("\t\tparam[%d] = %Lg\n", j, *(f32*)&__gxVerif->xfLight[i + j]); + } + } + } + + OSReport("\n-------------------------------------\n"); + OSReport("XF Register State:\n"); + + for (i = 0; i < 80; i++) { + if (__gxVerif->xfRegsDirty[i]) { + OSReport("\tXF_REG[0x%x] = 0x%x (%f)\n", i, __gxVerif->xfRegs[i], *(f32*)&__gxVerif->xfRegs[i]); + } + } + + OSReport("\n-------------------------------------\n"); + OSReport("Raster Registers State:\n"); + + for (i = 0; i < 256; i++) { + OSReport("\tRAS_REG[0x%x] = 0x%x\n", i, __gxVerif->rasRegs[i]); + } + + OSReport("\n-------------------------------------\n"); +} + +#endif diff --git a/src/dolphin/gx/GXStubs.c b/src/dolphin/gx/GXStubs.c new file mode 100644 index 0000000..c5e36bb --- /dev/null +++ b/src/dolphin/gx/GXStubs.c @@ -0,0 +1,5 @@ +#include + +#include "__gx.h" + +void __GXSetRange(f32 nearz, f32 fgSideX) {} diff --git a/src/dolphin/gx/GXTev.c b/src/dolphin/gx/GXTev.c new file mode 100644 index 0000000..195e605 --- /dev/null +++ b/src/dolphin/gx/GXTev.c @@ -0,0 +1,470 @@ +#include +#include + +#include "__gx.h" + +static struct { + u32 rid : 8; + u32 dest : 2; + u32 shift : 2; + u32 clamp : 1; + u32 sub : 1; + u32 bias : 2; + u32 sela : 4; + u32 selb : 4; + u32 selc : 4; + u32 seld : 4; +} TEVCOpTableST0[5] = { + {192, 0, 0, 1, 0, 0, 15, 8, 10, 15}, // modulate + {192, 0, 0, 1, 0, 0, 10, 8, 9, 15}, // decal + {192, 0, 0, 1, 0, 0, 10, 12, 8, 15}, // blend + {192, 0, 0, 1, 0, 0, 15, 15, 15, 8}, // replace + {192, 0, 0, 1, 0, 0, 15, 15, 15, 10}, // passclr +}; + +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"); + ASSERTMSGLINE(421, id < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); + ASSERTMSGLINE(422, mode <= GX_PASSCLR, "GXSetTevOp: Invalid Tev Mode"); + + if (id == GX_TEVSTAGE0) { + ctmp = (u32*)TEVCOpTableST0 + mode; + atmp = (u32*)TEVAOpTableST0 + mode; + } else { + ctmp = (u32*)TEVCOpTableST1 + mode; + atmp = (u32*)TEVAOpTableST1 + mode; + } + + tevReg = __GXData->tevc[id]; + tevReg = (*ctmp & ~0xFF000000) | (tevReg & 0xFF000000); + GX_WRITE_RAS_REG(tevReg); + __GXData->tevc[id] = tevReg; + + tevReg = __GXData->teva[id]; + tevReg = (*atmp & ~0xFF00000F) | (tevReg & 0xFF00000F); + GX_WRITE_RAS_REG(tevReg); + __GXData->teva[id] = tevReg; + + __GXData->bpSentNot = 0; +} + +void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) { + u32 tevReg; + + CHECK_GXBEGIN(578, "GXSetTevColorIn"); + ASSERTMSGLINE(579, stage < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); + ASSERTMSGLINE(580, a <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(581, b <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(582, c <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(583, d <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + + tevReg = __GXData->tevc[stage]; + SET_REG_FIELD(586, tevReg, 4, 12, a); + SET_REG_FIELD(587, tevReg, 4, 8, b); + SET_REG_FIELD(588, tevReg, 4, 4, c); + SET_REG_FIELD(589, tevReg, 4, 0, d); + + GX_WRITE_RAS_REG(tevReg); + __GXData->tevc[stage] = tevReg; + __GXData->bpSentNot = 0; +} + +void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d) { + u32 tevReg; + + CHECK_GXBEGIN(614, "GXSetTevAlphaIn"); + ASSERTMSGLINE(615, stage < GX_MAX_TEVSTAGE, "GXSetTevAlpha*: Invalid Tev Stage Index"); + ASSERTMSGLINE(616, a <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(617, b <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(618, c <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(619, d <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + + tevReg = __GXData->teva[stage]; + 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"); + ASSERTMSGLINE(654, stage < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); + + 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"); + ASSERTMSGLINE(700, stage < GX_MAX_TEVSTAGE, "GXSetTevAlpha*: Invalid Tev Stage Index"); + + 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; + + ASSERTMSGLINE(777, color.r >= -1024 && color.r < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); + ASSERTMSGLINE(778, color.g >= -1024 && color.g < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); + ASSERTMSGLINE(779, color.b >= -1024 && color.b < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); + ASSERTMSGLINE(780, color.a >= -1024 && color.a < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); + + 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"); + ASSERTMSGLINE(873, stage < GX_MAX_TEVSTAGE, "GXSetTevKColor*: Invalid Tev Stage Index"); + + 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"); + ASSERTMSGLINE(906, stage < GX_MAX_TEVSTAGE, "GXSetTevKColor*: Invalid Tev Stage Index"); + + 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"); + ASSERTMSGLINE(943, stage < GX_MAX_TEVSTAGE, "GXSetTevSwapMode: Invalid Tev Stage Index"); + + 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"); + ASSERTMSGLINE(979, table < GX_MAX_TEVSWAP, "GXSetTevSwapModeTable: Invalid Swap Selection Index"); + +#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 GXSetTevClampMode(void) { + ASSERTMSGLINE(1012, 0, "GXSetTevClampMode: not available on this hardware"); +} + +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: + ASSERTMSGLINE(1089, 0, "GXSetZTexture: Invalid z-texture format"); + 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"); + ASSERTMSGLINE(1132, stage < GX_MAX_TEVSTAGE, "GXSetTevOrder: Invalid Tev Stage Index"); + ASSERTMSGLINE(1134, coord < GX_MAX_TEXCOORD || coord == GX_TEXCOORD_NULL, "GXSetTevOrder: Invalid Texcoord"); + ASSERTMSGLINE(1136, (map & ~GX_TEX_DISABLE) < GX_MAX_TEXMAP || map == GX_TEXMAP_NULL, "GXSetTevOrder: Invalid Tex Map"); + ASSERTMSGLINE(1138, color >= GX_COLOR0A0 && color <= GX_COLOR_NULL, "GXSetTevOrder: Invalid Color Channel ID"); + + 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"); + + ASSERTMSGLINE(1189, nStages != 0 && nStages <= 16, "GXSetNumTevStages: Exceed max number of tex stages"); + SET_REG_FIELD(1190, __GXData->genMode, 4, 10, nStages - 1); + __GXData->dirtyState |= 4; +} diff --git a/src/dolphin/gx/GXTexture.c b/src/dolphin/gx/GXTexture.c new file mode 100644 index 0000000..ad12a7b --- /dev/null +++ b/src/dolphin/gx/GXTexture.c @@ -0,0 +1,1315 @@ +#include +#include + +#include "__gx.h" + +// 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; + + ASSERTMSGLINEV(460, width <= 1024, "%s: width too large", "GXGetTexBufferSize"); + ASSERTMSGLINEV(461, height <= 1024, "%s: height too large", "GXGetTexBufferSize"); + + __GXGetTexTileShift(format, &tileShiftX, &tileShiftY); + if (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) { + tileBytes = 64; + } else { + tileBytes = 32; + } + + if (mipmap == GX_TRUE) { + nx = 1 << (31 - __cntlzw(width)); + ASSERTMSGLINEV(479, width == nx, "%s: width must be a power of 2", "GXGetTexBufferSize"); + ny = 1 << (31 - __cntlzw(height)); + ASSERTMSGLINEV(482, height == ny, "%s: height must be a power of 2", "GXGetTexBufferSize"); + + bufferSize = 0; + for (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, 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; + + ASSERTMSGLINE(565, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(567, "GXInitTexObj"); + ASSERTMSGLINEV(568, width <= 1024, "%s: width too large", "GXInitTexObj"); + ASSERTMSGLINEV(569, height <= 1024, "%s: height too large", "GXInitTexObj"); + ASSERTMSGLINEV(571, !(format & _GX_TF_CTF), "%s: invalid texture format", "GXInitTexObj"); + +#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); + ASSERTMSGLINEV(654, ((u32)image_ptr & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexObj", "image"); + imageBase = (u32)((u32)image_ptr >> 5) & 0x01FFFFFF; + SET_REG_FIELD(656, t->image3, 21, 0, imageBase); + + 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: + ASSERTMSGLINEV(699, 0, "%s: invalid texture format", "GXPreLoadEntireTexture"); + 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, void* image_ptr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap, u32 tlut_name) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(737, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(739, "GXInitTexObjCI"); + GXInitTexObj(obj, image_ptr, width, height, format, wrap_s, wrap_t, mipmap); + t->flags &= 0xFFFFFFFD; + t->tlutName = tlut_name; +} + +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; + + ASSERTMSGLINE(776, obj, "Texture Object Pointer is null"); + 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); + ASSERTMSG1LINE(791, (u32)mag_filt <= 1, "%s: invalid mag_filt value", "GXInitTexObjLOD"); + SET_REG_FIELD(792, t->mode0, 1, 4, (mag_filt == GX_LINEAR) ? 1 : 0); + ASSERTMSG1LINE(795, (u32)min_filt <= 5, "%s: invalid min_filt value", "GXInitTexObjLOD"); + SET_REG_FIELD(796, t->mode0, 3, 5, GX2HWFiltConv[min_filt]); + SET_REG_FIELD(798, t->mode0, 1, 8, do_edge_lod ? 0 : 1); + SET_REG_FIELD(801, t->mode0, 1, 17, 0); + SET_REG_FIELD(801, t->mode0, 1, 18, 0); + SET_REG_FIELD(801, t->mode0, 2, 19, max_aniso); + SET_REG_FIELD(802, t->mode0, 1, 21, bias_clamp); + + if (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); +} + +void GXInitTexObjData(GXTexObj* obj, void* image_ptr) { + u32 imageBase; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(835, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(837, "GXInitTexObjData"); + ASSERTMSGLINEV(840, ((u32)image_ptr & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexObjData", "image"); + imageBase = ((u32)image_ptr >> 5) & 0x01FFFFFF; + SET_REG_FIELD(843, t->image3, 21, 0, imageBase); +} + +void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode sm, GXTexWrapMode tm) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(860, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(862, "GXInitTexObjWrapMode"); + SET_REG_FIELD(864, t->mode0, 2, 0, sm); + SET_REG_FIELD(865, t->mode0, 2, 2, tm); +} + +void GXInitTexObjTlut(GXTexObj* obj, u32 tlut_name) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(881, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(883, "GXInitTexObjTlut"); + t->tlutName = tlut_name; +} + +void GXInitTexObjFilter(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(902, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(904, "GXInitTexObjFilter"); + + ASSERTMSG1LINE(907, (u32)mag_filt <= 1, "%s: invalid mag_filt value", "GXInitTexObjFilter"); + SET_REG_FIELD(908, t->mode0, 1, 4, mag_filt == 1 ? 1 : 0); + + ASSERTMSG1LINE(911, (u32)min_filt <= 5, "%s: invalid min_filt value", "GXInitTexObjFilter"); + SET_REG_FIELD(912, t->mode0, 3, 5, GX2HWFiltConv[min_filt]); +} + +void GXInitTexObjMaxLOD(GXTexObj* obj, f32 max_lod) { + u8 lmax; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(930, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(932, "GXInitTexObjMaxLOD"); + + if (max_lod < 0.0f) { + max_lod = 0.0f; + } else if (max_lod > 10.0f) { + max_lod = 10.0f; + } + lmax = 16.0f * max_lod; + SET_REG_FIELD(938, t->mode1, 8, 8, lmax); +} + +void GXInitTexObjMinLOD(GXTexObj* obj, f32 min_lod) { + u8 lmin; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(956, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(958, "GXInitTexObjMinLOD"); + + if (min_lod < 0.0f) { + min_lod = 0.0f; + } else if (min_lod > 10.0f) { + min_lod = 10.0f; + } + lmin = 16.0f * min_lod; + SET_REG_FIELD(964, t->mode1, 8, 0, lmin); +} + +void GXInitTexObjLODBias(GXTexObj* obj, f32 lod_bias) { + u8 lbias; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(982, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(984, "GXInitTexObjLODBias"); + + if (lod_bias < -4.0f) { + lod_bias = -4.0f; + } else if (lod_bias >= 4.0f) { + lod_bias = 3.99f; + } + lbias = 32.0f * lod_bias; + SET_REG_FIELD(991, t->mode0, 8, 9, lbias); +} + +void GXInitTexObjBiasClamp(GXTexObj* obj, u8 bias_clamp) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1007, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1009, "GXInitTexObjBiasClamp"); + + SET_REG_FIELD(1011, t->mode0, 1, 21, bias_clamp); +} + +void GXInitTexObjEdgeLOD(GXTexObj* obj, u8 do_edge_lod) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1027, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1029, "GXInitTexObjEdgeLOD"); + + SET_REG_FIELD(1031, t->mode0, 1, 8, do_edge_lod ? 0 : 1); +} + +void GXInitTexObjMaxAniso(GXTexObj* obj, GXAnisotropy max_aniso) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1047, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1049, "GXInitTexObjMaxAniso"); + + SET_REG_FIELD(1051, t->mode0, 2, 19, max_aniso); +} + +void GXInitTexObjUserData(GXTexObj* obj, void* user_data) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1068, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1069, "GXInitTexObjUserData"); + t->userData = user_data; +} + +void* GXGetTexObjUserData(const GXTexObj* obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)obj; + + ASSERTMSGLINE(1075, obj, "Texture Object Pointer is null"); + return t->userData; +} + +void GXGetTexObjAll(const GXTexObj* obj, void** image_ptr, u16* width, u16* height, GXTexFmt* format, GXTexWrapMode* wrap_s, GXTexWrapMode* wrap_t, u8* mipmap) { + const __GXTexObjInt* t = (const __GXTexObjInt *)obj; + + ASSERTMSGLINE(1095, obj, "Texture Object Pointer is null"); + *image_ptr = (void *)(GET_REG_FIELD(t->image3, 21, 0) << 5); + *width = (u32)GET_REG_FIELD(t->image0, 10, 0) + 1; + *height = (u32)GET_REG_FIELD(t->image0, 10, 10) + 1; + *format = t->fmt; + *wrap_s = GET_REG_FIELD(t->mode0, 2, 0); + *wrap_t = GET_REG_FIELD(t->mode0, 2, 2); + *mipmap = (t->flags & 1) == 1; +} + +void* GXGetTexObjData(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1108, to, "Texture Object Pointer is null"); + return (void*)(GET_REG_FIELD(t->image3, 21, 0) << 5); +} + +u16 GXGetTexObjWidth(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1114, to, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->image0, 10, 0) + 1; +} + +u16 GXGetTexObjHeight(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1120, to, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->image0, 10, 10) + 1; +} + +GXTexFmt GXGetTexObjFmt(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1126, to, "Texture Object Pointer is null"); + return t->fmt; +} + +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1132, to, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 0); +} + +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1138, to, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 2); +} + +GXBool GXGetTexObjMipMap(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1144, to, "Texture Object Pointer is null"); + return (t->flags & 1) == 1; +} + +void GXGetTexObjLODAll(const GXTexObj* tex_obj, GXTexFilter* min_filt, GXTexFilter* mag_filt, f32* min_lod, f32* max_lod, f32* lod_bias, u8* bias_clamp, u8* do_edge_lod, GXAnisotropy* max_aniso) { + s16 tmp; + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1166, tex_obj, "Texture Object Pointer is null"); + *min_filt = HW2GXFiltConv[GET_REG_FIELD(t->mode0, 3, 5)]; + *mag_filt = GET_REG_FIELD(t->mode0, 1, 4); + *min_lod = (u8)t->mode1 / 16.0f; + *max_lod = (u32)GET_REG_FIELD(t->mode1, 8, 8) / 16.0f; + tmp = (s32)GET_REG_FIELD(t->mode0, 8, 9); + *lod_bias = (s8)tmp / 32.0f; + *bias_clamp = (u32)GET_REG_FIELD(t->mode0, 1, 21); + *do_edge_lod = !GET_REG_FIELD(t->mode0, 1, 8); + *max_aniso = GET_REG_FIELD(t->mode0, 2, 19); +} + +GXTexFilter GXGetTexObjMinFilt(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1182, tex_obj, "Texture Object Pointer is null"); + return HW2GXFiltConv[GET_REG_FIELD(t->mode0, 3, 5)]; +} + +GXTexFilter GXGetTexObjMagFilt(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1189, tex_obj, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 1, 4); +} + +f32 GXGetTexObjMinLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1195, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode1, 8, 0) / 16.0f; +} + +f32 GXGetTexObjMaxLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1201, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode1, 8, 8) / 16.0f; +} + +f32 GXGetTexObjLODBias(const GXTexObj* tex_obj) { + s16 tmp; + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1208, tex_obj, "Texture Object Pointer is null"); + tmp = (s32)GET_REG_FIELD(t->mode0, 8, 9); + return (s8)tmp / 32.0f; +} + +GXBool GXGetTexObjBiasClamp(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1215, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode0, 1, 21); +} + +GXBool GXGetTexObjEdgeLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1221, tex_obj, "Texture Object Pointer is null"); + return !GET_REG_FIELD(t->mode0, 1, 8); +} + +GXAnisotropy GXGetTexObjMaxAniso(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1227, tex_obj, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 19); +} + +u32 GXGetTexObjTlut(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1233, tex_obj, "Texture Object Pointer is null"); + return t->tlutName; +} + +void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID id) { + __GXTlutRegionInt* tlr; + u32 m0; + u32 m1; + u32 img0; + u32 img1; + u32 img2; + u32 img3; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + __GXTexRegionInt* r = (__GXTexRegionInt *)region; + + ASSERTMSGLINE(1257, obj, "Texture Object Pointer is null"); + ASSERTMSGLINE(1257, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1259, "GXLoadTexObjPreLoaded"); + ASSERTMSGLINEV(1260, id < GX_MAX_TEXMAP, "%s: invalid texture map ID", "GXLoadTexObj"); + + m0 = t->mode0; + m1 = t->mode1; + img0 = t->image0; + img1 = r->image1; + img2 = r->image2; + img3 = t->image3; + + SET_REG_FIELD(1271, t->mode0, 8, 24, GXTexMode0Ids[id]); + SET_REG_FIELD(1272, t->mode1, 8, 24, GXTexMode1Ids[id]); + SET_REG_FIELD(1273, t->image0, 8, 24, GXTexImage0Ids[id]); + SET_REG_FIELD(1274, r->image1, 8, 24, GXTexImage1Ids[id]); + SET_REG_FIELD(1275, r->image2, 8, 24, GXTexImage2Ids[id]); + SET_REG_FIELD(1276, t->image3, 8, 24, GXTexImage3Ids[id]); + + GX_WRITE_RAS_REG(t->mode0); + GX_WRITE_RAS_REG(t->mode1); + GX_WRITE_RAS_REG(t->image0); + GX_WRITE_RAS_REG(r->image1); + GX_WRITE_RAS_REG(r->image2); + GX_WRITE_RAS_REG(t->image3); + + if (!(t->flags & 2)) { + ASSERTMSGLINEV(1287, __GXData->tlutRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTexObj/PreLoaded"); + tlr = (__GXTlutRegionInt*)__GXData->tlutRegionCallback(t->tlutName); + ASSERTMSGLINEV(1289, tlr, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTexObj/PreLoaded"); + + SET_REG_FIELD(1291, tlr->tlutObj.tlut, 8, 24, GXTexTlutIds[id]); + GX_WRITE_RAS_REG(tlr->tlutObj.tlut); + } + + __GXData->tImage0[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"); + ASSERTMSGLINEV(1319, id < 8, "%s: invalid texture map ID", "GXLoadTexObj"); + ASSERTMSGLINEV(1324, __GXData->texRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTexObj"); + r = __GXData->texRegionCallback(obj, id); + ASSERTMSGLINEV(1326, r, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTexObj"); + GXLoadTexObjPreLoaded(obj, r, id); +} + +void GXInitTlutObj(GXTlutObj* tlut_obj, void* lut, GXTlutFmt fmt, u16 n_entries) { + __GXTlutObjInt* t = (__GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1350, tlut_obj, "TLut Object Pointer is null"); + CHECK_GXBEGIN(1351, "GXInitTlutObj"); + ASSERTMSGLINEV(1354, n_entries <= 0x4000, "%s: number of entries exceeds maximum", "GXInitTlutObj"); + ASSERTMSGLINEV(1356, ((u32)lut & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTlutObj", "Tlut"); + t->tlut = 0; + SET_REG_FIELD(1359, t->tlut, 2, 10, fmt); + SET_REG_FIELD(1360, t->loadTlut0, 21, 0, ((u32)lut & 0x3FFFFFFF) >> 5); + SET_REG_FIELD(1361, t->loadTlut0, 8, 24, 0x64); + t->numEntries = n_entries; +} + +void GXGetTlutObjAll(const GXTlutObj* tlut_obj, void **data, GXTlutFmt* format, u16* numEntries) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1382, tlut_obj, "TLut Object Pointer is null"); + *data = (void *)(GET_REG_FIELD(t->loadTlut0, 21, 0) << 5); + *format = GET_REG_FIELD(t->tlut, 2, 10); + *numEntries = t->numEntries; +} + +void* GXGetTlutObjData(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1391, tlut_obj, "TLut Object Pointer is null"); + return (void *)(GET_REG_FIELD(t->loadTlut0, 21, 0) << 5); +} + +GXTlutFmt GXGetTlutObjFmt(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1398, tlut_obj, "TLut Object Pointer is null"); + return GET_REG_FIELD(t->tlut, 2, 10); +} + +u16 GXGetTlutObjNumEntries(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1405, tlut_obj, "TLut Object Pointer is null"); + return t->numEntries; +} + +void GXLoadTlut(GXTlutObj* tlut_obj, u32 tlut_name) { + __GXTlutRegionInt* r; + u32 tlut_offset; + __GXTlutObjInt* t = (__GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1432, tlut_obj, "TLut Object Pointer is null"); + CHECK_GXBEGIN(1434, "GXLoadTlut"); + ASSERTMSGLINEV(1435, __GXData->tlutRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTlut"); + r = (__GXTlutRegionInt *)__GXData->tlutRegionCallback(tlut_name); + ASSERTMSGLINEV(1437, r, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTlut"); + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(t->loadTlut0); + GX_WRITE_RAS_REG(r->loadTlut1); + __GXFlushTextureState(); + tlut_offset = r->loadTlut1 & 0x3FF; + SET_REG_FIELD(1453, t->tlut, 10, 0, tlut_offset); + r->tlutObj = *t; +} + +void GXInitTexCacheRegion(GXTexRegion* region, u8 is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd) { + u32 WidthExp2; + __GXTexRegionInt* t = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1484, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1486, "GXInitTexCacheRegion"); + ASSERTMSGLINEV(1488, (tmem_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexCacheRegion", "tmem even"); + ASSERTMSGLINEV(1490, (tmem_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexCacheRegion", "tmem odd"); + + switch (size_even) { + case GX_TEXCACHE_32K: + WidthExp2 = 3; + break; + case GX_TEXCACHE_128K: + WidthExp2 = 4; + break; + case GX_TEXCACHE_512K: + WidthExp2 = 5; + break; + default: + ASSERTMSGLINEV(1498, 0, "%s: Invalid %s size", "GXInitTexCacheRegion", "tmem even"); + break; + } + + t->image1 = 0; + SET_REG_FIELD(1503, t->image1, 15, 0, tmem_even >> 5); + SET_REG_FIELD(1504, t->image1, 3, 15, WidthExp2); + SET_REG_FIELD(1505, t->image1, 3, 18, WidthExp2); + SET_REG_FIELD(1506, t->image1, 1, 21, 0); + + switch (size_odd) { + case GX_TEXCACHE_32K: + WidthExp2 = 3; + break; + case GX_TEXCACHE_128K: + WidthExp2 = 4; + break; + case GX_TEXCACHE_512K: + WidthExp2 = 5; + break; + case GX_TEXCACHE_NONE: + WidthExp2 = 0; + break; + default: + ASSERTMSGLINEV(1514, 0, "%s: Invalid %s size", "GXInitTexCacheRegion", "tmem odd"); + break; + } + + t->image2 = 0; + SET_REG_FIELD(1519, t->image2, 15, 0, tmem_odd >> 5); + SET_REG_FIELD(1520, t->image2, 3, 15, WidthExp2); + SET_REG_FIELD(1521, t->image2, 3, 18, WidthExp2); + t->is32bMipmap = is_32b_mipmap; + t->isCached = 1; +} + +void GXInitTexPreLoadRegion(GXTexRegion* region, u32 tmem_even, u32 size_even, u32 tmem_odd, u32 size_odd) { + __GXTexRegionInt* t = (__GXTexRegionInt *)region; + + ASSERTMSGLINE(1550, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1552, "GXInitTexPreLoadRegion"); + ASSERTMSGLINEV(1554, (tmem_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "tmem even"); + ASSERTMSGLINEV(1556, (tmem_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "tmem odd"); + ASSERTMSGLINEV(1558, (size_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "size even"); + ASSERTMSGLINEV(1560, (size_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "size odd"); + + t->image1 = 0; + SET_REG_FIELD(1564, t->image1, 15, 0, tmem_even >> 5); + SET_REG_FIELD(1565, t->image1, 3, 15, 0); + SET_REG_FIELD(1566, t->image1, 3, 18, 0); + SET_REG_FIELD(1567, t->image1, 1, 21, 1); + + t->image2 = 0; + SET_REG_FIELD(1570, t->image2, 15, 0, tmem_odd >> 5); + SET_REG_FIELD(1571, t->image2, 3, 15, 0); + SET_REG_FIELD(1572, t->image2, 3, 18, 0); + t->is32bMipmap = 0; + t->isCached = 0; + t->sizeEven = (u16)(size_even >> 5); + t->sizeOdd = (u16)(size_odd >> 5); +} + +void GXGetTexRegionAll(const GXTexRegion* region, u8* is_cached, u8* is_32b_mipmap, u32* tmem_even, u32* size_even, u32* tmem_odd, u32* size_odd) { + const __GXTexRegionInt* t = (const __GXTexRegionInt *)region; + + ASSERTMSGLINE(1601, region, "TexRegion Object Pointer is null"); + *tmem_even = GET_REG_FIELD(t->image1, 15, 0) << 5; + *tmem_odd = GET_REG_FIELD(t->image2, 15, 0) << 5; + if (t->isCached) { + switch (GET_REG_FIELD(t->image1, 3, 15)) { + case 3: + *size_even = 0x8000; + break; + case 4: + *size_even = 0x20000; + break; + case 5: + *size_even = 0x80000; + break; + default: + *size_even = 0; + break; + } + + switch (GET_REG_FIELD(t->image2, 3, 15)) { + case 3: + *size_odd = 0x8000; + break; + case 4: + *size_odd = 0x20000; + break; + case 5: + *size_odd = 0x80000; + break; + default: + *size_odd = 0; + break; + } + } else { + *size_even = t->sizeEven << 5; + *size_odd = t->sizeOdd << 5; + } + + *is_32b_mipmap = t->is32bMipmap; + *is_cached = t->isCached; +} + +void GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size) { + __GXTlutRegionInt* t = (__GXTlutRegionInt *)region; + + ASSERTMSGLINE(1652, region, "TLutRegion Object Pointer is null"); + CHECK_GXBEGIN(1654, "GXInitTlutRegion"); + ASSERTMSGLINEV(1655, (tmem_addr & 0x1FF) == 0, "%s: tmem pointer is not aligned to 512B", "GXInitTlutRegion"); + ASSERTMSGLINEV(1656, tlut_size <= 0x400, "%s: tlut size exceeds 16K", "GXInitTlutRegion"); + t->loadTlut1 = 0; + tmem_addr -= 0x80000; + SET_REG_FIELD(1660, t->loadTlut1, 10, 0, tmem_addr >> 9); + SET_REG_FIELD(1661, t->loadTlut1, 11, 10, tlut_size); + SET_REG_FIELD(1662, t->loadTlut1, 8, 24, 0x65); +} + +void GXGetTlutRegionAll(const GXTlutRegion* region, u32* tmem_addr, GXTlutSize* tlut_size) { + const __GXTlutRegionInt* t = (const __GXTlutRegionInt *)region; + + ASSERTMSGLINE(1682, region, "TLutRegion Object Pointer is null"); + *tmem_addr = (GET_REG_FIELD(t->loadTlut1, 10, 0) << 9) + 0x80000; + *tlut_size = GET_REG_FIELD(t->loadTlut1, 11, 10); +} + +void GXInvalidateTexRegion(GXTexRegion* region) { + s32 wle; + s32 hle; + s32 wlo; + s32 hlo; + s32 count; + u32 reg0; + u32 reg1; + __GXTexRegionInt* r = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1705, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1707, "GXInvalidateTexRegion"); + + wle = GET_REG_FIELD(r->image1, 3, 15) - 1; + hle = GET_REG_FIELD(r->image1, 3, 18) - 1; + wlo = GET_REG_FIELD(r->image2, 3, 15) - 1; + hlo = GET_REG_FIELD(r->image2, 3, 18) - 1; + if (wle < 0) { + wle = 0; + } + if (hle < 0) { + hle = 0; + } + if (wlo < 0) { + wlo = 0; + } + if (hlo < 0) { + hlo = 0; + } + count = wle + hle; + if (r->is32bMipmap) { + count = wlo + hlo - 2 + count; + } + + reg0 = 0; + SET_REG_FIELD(1724, reg0, 9, 0, GET_REG_FIELD(r->image1, 9, 6)); + SET_REG_FIELD(1725, reg0, 4, 9, count); + SET_REG_FIELD(1724, reg0, 8, 24, 0x66); + + if (wlo != 0) { + count = wlo + hlo; + if (r->is32bMipmap) { + count = wle + hle - 2 + count; + } + reg1 = 0; + SET_REG_FIELD(1736, reg1, 9, 0, GET_REG_FIELD(r->image2, 9, 6)); + SET_REG_FIELD(1737, reg1, 4, 9, count); + SET_REG_FIELD(1738, reg1, 8, 24, 0x66); + } + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(reg0); + if (wlo != 0) { + GX_WRITE_RAS_REG(reg1); + } + __GXFlushTextureState(); + + reg0; reg1; r; // needed to match +} + +void GXInvalidateTexAll(void) { + u32 reg0; + u32 reg1; + + CHECK_GXBEGIN(1755, "GXInvalidateTexAll"); + reg0 = 0x66001000; + reg1 = 0x66001100; + __GXFlushTextureState(); + GX_WRITE_RAS_REG(reg0); + GX_WRITE_RAS_REG(reg1); + __GXFlushTextureState(); +} + +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback f) { + GXTexRegionCallback oldcb = __GXData->texRegionCallback; + + __GXData->texRegionCallback = f; + return oldcb; +} + +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback f) { + GXTlutRegionCallback oldcb = __GXData->tlutRegionCallback; + + __GXData->tlutRegionCallback = f; + return oldcb; +} + +void GXPreLoadEntireTexture(GXTexObj* tex_obj, GXTexRegion* region) { + GXBool isMipMap; + GXBool is32bit; + u32 wd; + u32 ht; + u32 maxLevelIndex; + u32 loadImage0; + u32 loadImage1; + u32 loadImage2; + u32 loadImage3; + u32 base; + u32 tmem1; + u32 tmem2; + u32 tmemAR; + u32 tmemGB; + u32 nTiles; +#if DEBUG + u32 totalOdd; + u32 totalEven; + u32 count; +#endif + u32 rowTiles; + u32 colTiles; + u32 cmpTiles; + u32 i; + __GXTexObjInt* t = (__GXTexObjInt*)tex_obj; + __GXTexRegionInt* r = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1820, tex_obj, "Texture Object Pointer is null"); + ASSERTMSGLINE(1820, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1822, "GXPreLoadEntireTexture"); + isMipMap = (t->flags & 1) == 1; + is32bit = GET_REG_FIELD(t->image0, 4, 20) == 6; + + loadImage0 = 0; + SET_REG_FIELD(0, loadImage0, 8, 24, 0x60); + base = t->image3 & 0x1FFFFF; + SET_REG_FIELD(1831, loadImage0, 21, 0, base); + + loadImage1 = 0; + SET_REG_FIELD(0, loadImage1, 8, 24, 0x61); + tmem1 = r->image1 & 0x7FFF; + SET_REG_FIELD(1837, loadImage1, 15, 0, tmem1); + + loadImage2 = 0; + SET_REG_FIELD(0, loadImage2, 8, 24, 0x62); + tmem2 = r->image2 & 0x7FFF; + SET_REG_FIELD(1843, loadImage2, 15, 0, tmem2); + + loadImage3 = 0; + SET_REG_FIELD(0, loadImage3, 8, 24, 0x63); + SET_REG_FIELD(1848, loadImage3, 15, 0, t->loadCnt); + SET_REG_FIELD(1849, loadImage3, 2, 15, t->loadFmt); + maxLevelIndex = 0; + nTiles = t->loadCnt; + + if (isMipMap) { + wd = GET_REG_FIELD(t->image0, 10, 0) + 1; + ht = GET_REG_FIELD(t->image0, 10, 10) + 1; + if (wd > ht) { + maxLevelIndex = (u16)(31 - __cntlzw(wd)); + } else { + maxLevelIndex = (u16)(31 - __cntlzw(ht)); + } + +#if DEBUG + count = nTiles; + totalOdd = totalEven = 0; + + for (i = 0; i < maxLevelIndex; i++) { + if (i & 1) { + if (count == 0) { + count = 1; + } + totalOdd += count; + } else { + if (count == 0) { + count = 1; + } + totalEven += count; + } + __GetImageTileCount(t->fmt, wd >> (i + 1), ht >> (i + 1), &rowTiles, &colTiles, &cmpTiles); + count = rowTiles * colTiles; + } +#endif + } else { +#if DEBUG + totalEven = (nTiles == 0) ? 1 : nTiles; + totalOdd = totalEven; +#endif + } + +#if DEBUG + if (is32bit) { + totalOdd = isMipMap ? totalOdd : 0; + totalEven = totalEven + totalOdd; + ASSERTMSGLINE(1890, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + ASSERTMSGLINE(1891, totalEven <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } else if (isMipMap != 0) { + if (r->sizeEven > r->sizeOdd) { + ASSERTMSGLINE(1896, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + ASSERTMSGLINE(1897, totalOdd <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } else { + ASSERTMSGLINE(1900, totalEven <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + ASSERTMSGLINE(1901, totalOdd <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + } + } else if (r->sizeEven > r->sizeOdd) { + ASSERTMSGLINE(1906, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + } else { + ASSERTMSGLINE(1908, totalOdd <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } +#endif + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(loadImage0); + GX_WRITE_RAS_REG(loadImage1); + GX_WRITE_RAS_REG(loadImage2); + GX_WRITE_RAS_REG(loadImage3); + + if (maxLevelIndex != 0) { + tmemAR = tmem1; + tmemGB = tmem2; + for (i = 0; i < maxLevelIndex; i++) { + if (is32bit) { + base += nTiles * 2; + tmemAR += nTiles; + tmemGB += nTiles; + } else { + base += nTiles; + if (i & 1) { + tmemGB += nTiles; + } else { + tmemAR += nTiles; + } + } + tmem1 = (i & 1) ? tmemAR : tmemGB; + tmem2 = (i & 1) ? tmemGB : tmemAR; + __GetImageTileCount(t->fmt, (u16) (wd >> (i + 1)), (u16) (ht >> (i + 1)), &rowTiles, &colTiles, &cmpTiles); + nTiles = rowTiles * colTiles; + SET_REG_FIELD(1957, loadImage0, 21, 0, base); + SET_REG_FIELD(1958, loadImage1, 15, 0, tmem1); + SET_REG_FIELD(1959, loadImage2, 15, 0, tmem2); + SET_REG_FIELD(1960, loadImage3, 15, 0, nTiles); + GX_WRITE_RAS_REG(loadImage0); + GX_WRITE_RAS_REG(loadImage1); + GX_WRITE_RAS_REG(loadImage2); + GX_WRITE_RAS_REG(loadImage3); + } + } + __GXFlushTextureState(); + + // needed to match debug + maxLevelIndex; maxLevelIndex; base; base; base; tmem1; tmem1; tmem2; tmem2; +} + +void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts) { + CHECK_GXBEGIN(1989, "GXSetTexCoordScaleManually"); + ASSERTMSGLINEV(1991, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordScaleManually"); + __GXData->tcsManEnab = (__GXData->tcsManEnab & ~(1 << coord)) | (enable << coord); + + if (enable) { + SET_REG_FIELD(1997, __GXData->suTs0[coord], 16, 0, (u16)(ss - 1)); + SET_REG_FIELD(1998, __GXData->suTs1[coord], 16, 0, (u16)(ts - 1)); + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +void GXSetTexCoordCylWrap(GXTexCoordID coord, u8 s_enable, u8 t_enable) { + CHECK_GXBEGIN(2023, "GXSetTexCoordCylWrap"); + ASSERTMSGLINEV(2025, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordCylWrap"); + SET_REG_FIELD(2027, __GXData->suTs0[coord], 1, 17, s_enable); + SET_REG_FIELD(2028, __GXData->suTs1[coord], 1, 17, t_enable); + + if (__GXData->tcsManEnab & (1 << coord)) { + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +void GXSetTexCoordBias(GXTexCoordID coord, u8 s_enable, u8 t_enable) { + CHECK_GXBEGIN(2054, "GXSetTexCoordBias"); + ASSERTMSGLINEV(2056, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordBias"); + SET_REG_FIELD(2058, __GXData->suTs0[coord], 1, 16, s_enable); + SET_REG_FIELD(2059, __GXData->suTs1[coord], 1, 16, t_enable); + + if (__GXData->tcsManEnab & (1 << coord)) { + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +static void __SetSURegs(u32 tmap, u32 tcoord) { + u32 w; + u32 h; + u8 s_bias; + u8 t_bias; + + w = GET_REG_FIELD(__GXData->tImage0[tmap], 10, 0); + h = GET_REG_FIELD(__GXData->tImage0[tmap], 10, 10); + SET_REG_FIELD(2089, __GXData->suTs0[tcoord], 16, 0, w); + SET_REG_FIELD(2090, __GXData->suTs1[tcoord], 16, 0, h); + s_bias = GET_REG_FIELD(__GXData->tMode0[tmap], 2, 0) == 1; + t_bias = GET_REG_FIELD(__GXData->tMode0[tmap], 2, 2) == 1; + SET_REG_FIELD(2096, __GXData->suTs0[tcoord], 1, 16, s_bias); + SET_REG_FIELD(2097, __GXData->suTs1[tcoord], 1, 16, t_bias); + GX_WRITE_RAS_REG(__GXData->suTs0[tcoord]); + GX_WRITE_RAS_REG(__GXData->suTs1[tcoord]); + __GXData->bpSentNot = 0; +} + +void __GXSetSUTexRegs(void) { + u32 nStages; + u32 nIndStages; + u32 i; + u32 map; + u32 tmap; + u32 coord; + u32* ptref; + + if (__GXData->tcsManEnab != 0xFF) { + nStages = GET_REG_FIELD(__GXData->genMode, 4, 10) + 1; + nIndStages = GET_REG_FIELD(__GXData->genMode, 3, 16); + for (i = 0; i < nIndStages; i++) { + switch (i) { + case 0: + 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 __GXGetSUTexSize(GXTexCoordID coord, u16* width, u16* height) { + *width = (u16)__GXData->suTs0[coord] + 1; + *height = (u16)__GXData->suTs1[coord] + 1; +} + +void __GXSetTmemConfig(u32 config) { + switch (config) { + case 2: + GX_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/src/dolphin/gx/GXTransform.c b/src/dolphin/gx/GXTransform.c new file mode 100644 index 0000000..e454017 --- /dev/null +++ b/src/dolphin/gx/GXTransform.c @@ -0,0 +1,608 @@ +#include +#include +#include + +#include "__gx.h" + +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(const 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) { + ASSERTMSGLINE(370, ptr, "GXGet*: invalid null pointer"); + + ptr[0] = (u32)__GXData->projType != GX_PERSPECTIVE ? 1.0f : 0.0f; + +#if DEBUG + ptr[1] = __GXData->projMtx[0]; + ptr[2] = __GXData->projMtx[1]; + ptr[3] = __GXData->projMtx[2]; + ptr[4] = __GXData->projMtx[3]; + ptr[5] = __GXData->projMtx[4]; + ptr[6] = __GXData->projMtx[5]; +#else + Copy6Floats(__GXData->projMtx, &ptr[1]); +#endif +} + +static void WriteMTXPS4x3(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(const Mtx mtx, u32 id) { + u32 reg; + u32 addr; + + CHECK_GXBEGIN(507, "GXLoadPosMtxImm"); + + addr = id * 4; + reg = addr | 0xB0000; + + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); +#if DEBUG + GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); + GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); + GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); + GX_WRITE_MTX_ELEM(addr + 3, mtx[0][3]); + GX_WRITE_MTX_ELEM(addr + 4, mtx[1][0]); + GX_WRITE_MTX_ELEM(addr + 5, mtx[1][1]); + GX_WRITE_MTX_ELEM(addr + 6, mtx[1][2]); + GX_WRITE_MTX_ELEM(addr + 7, mtx[1][3]); + GX_WRITE_MTX_ELEM(addr + 8, mtx[2][0]); + GX_WRITE_MTX_ELEM(addr + 9, mtx[2][1]); + GX_WRITE_MTX_ELEM(addr + 10, mtx[2][2]); + GX_WRITE_MTX_ELEM(addr + 11, mtx[2][3]); +#else + WriteMTXPS4x3(mtx, &GXWGFifo.f32); +#endif +} + +void GXLoadPosMtxIndx(u16 mtx_indx, u32 id) { + u32 offset; + u32 reg; + + CHECK_GXBEGIN(555, "GXLoadPosMtxIndx"); + offset = id * 4; + reg = 0; + SET_REG_FIELD(561, reg, 12, 0, offset); + SET_REG_FIELD(563, reg, 4, 12, 11); + SET_REG_FIELD(563, reg, 16, 16, mtx_indx); + GX_WRITE_U8(0x20); + GX_WRITE_U32(reg); +#if DEBUG + __GXShadowIndexState(4, reg); +#endif +} + +void GXLoadNrmMtxImm(const Mtx mtx, u32 id) { + u32 reg; + u32 addr; + + CHECK_GXBEGIN(588, "GXLoadNrmMtxImm"); + + addr = id * 3 + 0x400; + reg = addr | 0x80000; + + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); +#if DEBUG + GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); + GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); + GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); + GX_WRITE_MTX_ELEM(addr + 3, mtx[1][0]); + GX_WRITE_MTX_ELEM(addr + 4, mtx[1][1]); + GX_WRITE_MTX_ELEM(addr + 5, mtx[1][2]); + GX_WRITE_MTX_ELEM(addr + 6, mtx[2][0]); + GX_WRITE_MTX_ELEM(addr + 7, mtx[2][1]); + GX_WRITE_MTX_ELEM(addr + 8, mtx[2][2]); +#else + WriteMTXPS3x3from3x4((void*)mtx, &GXWGFifo.f32); +#endif +} + +void GXLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id) { + u32 reg; + u32 addr; + + CHECK_GXBEGIN(633, "GXLoadNrmMtxImm3x3"); + + addr = id * 3 + 0x400; + reg = addr | 0x80000; + + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); +#if DEBUG + GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); + GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); + GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); + GX_WRITE_MTX_ELEM(addr + 3, mtx[1][0]); + GX_WRITE_MTX_ELEM(addr + 4, mtx[1][1]); + GX_WRITE_MTX_ELEM(addr + 5, mtx[1][2]); + GX_WRITE_MTX_ELEM(addr + 6, mtx[2][0]); + GX_WRITE_MTX_ELEM(addr + 7, mtx[2][1]); + GX_WRITE_MTX_ELEM(addr + 8, mtx[2][2]); +#else + WriteMTXPS3x3((void*)mtx, &GXWGFifo.f32); +#endif +} + +void GXLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id) { + u32 offset; + u32 reg; + + CHECK_GXBEGIN(679, "GXLoadNrmMtxIndx3x3"); + offset = id * 3 + 0x400; + reg = 0; + SET_REG_FIELD(685, reg, 12, 0, offset); + SET_REG_FIELD(687, reg, 4, 12, 8); + SET_REG_FIELD(687, reg, 16, 16, mtx_indx); + GX_WRITE_U8(0x28); + GX_WRITE_U32(reg); +#if DEBUG + __GXShadowIndexState(5, reg); +#endif +} + +void GXSetCurrentMtx(u32 id) { + CHECK_GXBEGIN(708, "GXSetCurrentMtx"); + SET_REG_FIELD(712, __GXData->matIdxA, 6, 0, id); + __GXSetMatrixIndex(GX_VA_PNMTXIDX); +} + +void GXLoadTexMtxImm(const 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; + ASSERTMSGLINE(751, type == GX_MTX3x4, "GXLoadTexMtx: Invalid matrix type"); + } 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 GXLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type) { + u32 offset; + u32 reg; + u32 count; + + CHECK_GXBEGIN(813, "GXLoadTexMtxIndx"); + + if (id >= GX_PTTEXMTX0) { + offset = (id - GX_PTTEXMTX0) * 4 + 0x500; + ASSERTMSGLINE(0x337, type == GX_MTX3x4, "GXLoadTexMtx: Invalid matrix type"); + } else { + offset = id * 4; + } + count = (type == GX_MTX2x4) ? 8 : 12; + + reg = 0; + SET_REG_FIELD(830, reg, 12, 0, offset); + SET_REG_FIELD(831, reg, 4, 12, (count - 1)); + SET_REG_FIELD(832, reg, 16, 16, mtx_indx); + GX_WRITE_U8(0x30); + GX_WRITE_U32(reg); +#if DEBUG + __GXShadowIndexState(6, reg); +#endif +} + +void __GXSetViewport(void) { + f32 sx; + f32 sy; + f32 sz; + f32 ox; + f32 oy; + f32 oz; + f32 zmin; + f32 zmax; + u32 reg; + + 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); +} + +void GXGetViewportv(f32* vp) { + ASSERTMSGLINE(968, vp, "GXGet*: invalid null pointer"); + +#if DEBUG + vp[0] = __GXData->vpLeft; + vp[1] = __GXData->vpTop; + vp[2] = __GXData->vpWd; + vp[3] = __GXData->vpHt; + vp[4] = __GXData->vpNearz; + vp[5] = __GXData->vpFarz; +#else + Copy6Floats(&__GXData->vpLeft, vp); +#endif +} + +#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 GXSetZScaleOffset(f32 scale, f32 offset) { + f32 sz; + f32 oz; + f32 zmin; + f32 zmax; + + CHECK_GXBEGIN(996, "GXSetZScaleOffset"); + + oz = offset * 1.6777215e7f; + __GXData->zOffset = oz; + + sz = (scale * 1.6777215e7f) + 1.0f; + __GXData->zScale = sz; + + zmin = __GXData->vpNearz * sz; + zmax = __GXData->vpFarz * sz; + sz = zmax - zmin; + oz = oz + zmax; + + GX_WRITE_XF_REG_F_(0x1C, sz); + GX_WRITE_XF_REG_F_(0x1F, oz); + + __GXData->bpSentNot = 1; +} + +void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht) { + u32 tp; + u32 lf; + u32 bm; + u32 rt; + + CHECK_GXBEGIN(1048, "GXSetScissor"); + ASSERTMSGLINE(1049, left < 1706, "GXSetScissor: Left origin > 1708"); + ASSERTMSGLINE(1050, top < 1706, "GXSetScissor: top origin > 1708"); + ASSERTMSGLINE(1051, left + wd < 1706, "GXSetScissor: right edge > 1708"); + ASSERTMSGLINE(1052, top + ht < 1706, "GXSetScissor: bottom edge > 1708"); + + 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 GXGetScissor(u32* left, u32* top, u32* wd, u32* ht) { + u32 tp; + u32 lf; + u32 bm; + u32 rt; + + ASSERTMSGLINE(1089, left && top && wd && ht, "GXGet*: invalid null pointer"); + + tp = __GXData->suScis0 & 0x7FF; + lf = (__GXData->suScis0 & 0x7FF000) >> 12; + bm = __GXData->suScis1 & 0x7FF; + rt = (__GXData->suScis1 & 0x7FF000) >> 12; + + *left = lf - 342; + *top = tp - 342; + *wd = rt - lf + 1; + *ht = bm - tp + 1; +} + +void GXSetScissorBoxOffset(s32 x_off, s32 y_off) { + u32 reg = 0; + u32 hx; + u32 hy; + + CHECK_GXBEGIN(1119, "GXSetScissorBoxOffset"); + + ASSERTMSGLINE(1122, (u32)(x_off + 342) < 2048, "GXSetScissorBoxOffset: Invalid X offset"); + ASSERTMSGLINE(1124, (u32)(y_off + 342) < 2048, "GXSetScissorBoxOffset: Invalid Y offset"); + + hx = (u32)(x_off + 342) >> 1; + hy = (u32)(y_off + 342) >> 1; + + SET_REG_FIELD(1129, reg, 10, 0, hx); + SET_REG_FIELD(1130, reg, 10, 10, hy); + SET_REG_FIELD(1131, reg, 8, 24, 0x59); + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +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/src/dolphin/gx/GXVerifRAS.c b/src/dolphin/gx/GXVerifRAS.c new file mode 100644 index 0000000..f1aa966 --- /dev/null +++ b/src/dolphin/gx/GXVerifRAS.c @@ -0,0 +1,640 @@ +#if DEBUG + +#include + +#include + +#include "__gx.h" + +static char __data_0[] = "RGB multisample"; +static char _305[] = "GX_TEVPREV(color)"; +static char _306[] = "GX_TEVPREV(alpha)"; +static char _307[] = "GX_TEVREG0(color)"; +static char _308[] = "GX_TEVREG0(alpha)"; +static char _309[] = "GX_TEVREG1(color)"; +static char _310[] = "GX_TEVREG1(alpha)"; +static char _311[] = "GX_TEVREG2(color)"; +static char _312[] = "GX_TEVREG2(alpha)"; + +static char* TevRegNames[8] = {0}; + +#define SOME_GET_REG_MACRO(reg, size, shift) ((u32)((reg) << (shift)) & ((1 << (size)) - 2)) +#define SOME_GET_REG_MACRO2(reg, size, shift) ((u32)((reg) >> (shift)) & ((1 << (size)) - 2)) + +void __GXVerifySU(void) { + s32 scis_l; + s32 scis_r; + s32 scis_t; + s32 scis_b; + + scis_l = (u32)GET_REG_FIELD(__gxVerif->rasRegs[32], 11, 12); + scis_t = (u32)GET_REG_FIELD(__gxVerif->rasRegs[32], 11, 0); + scis_r = (u32)GET_REG_FIELD(__gxVerif->rasRegs[33], 11, 12); + scis_b = (u32)GET_REG_FIELD(__gxVerif->rasRegs[33], 11, 0); + + scis_l = scis_l - (u32)SOME_GET_REG_MACRO(__gxVerif->rasRegs[89], 11, 1); + scis_r = scis_r - (u32)SOME_GET_REG_MACRO(__gxVerif->rasRegs[89], 11, 1); + scis_t = scis_t - (u32)SOME_GET_REG_MACRO2(__gxVerif->rasRegs[89], 11, 9); + scis_b = scis_b - (u32)SOME_GET_REG_MACRO2(__gxVerif->rasRegs[89], 11, 9); + + if (scis_l < 0 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_LEFT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_LEFT, 0); + } + + if (scis_t < 0 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_TOP]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_TOP, 0); + } + + switch (__gxVerif->rasRegs[67] & 7) { + case 4: + case 5: + if (scis_r > 719 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 719, "YUV"); + } + + if (scis_b > 575 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 575, "YUV"); + } + break; + case 0: + case 1: + case 3: + if (scis_r > 639 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 639, "RGB"); + } + + if (scis_b > 527 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 527, "RGB"); + } + break; + case 2: + if (scis_r > 639 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 639, __data_0); + } + + if (scis_b > 263 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 263, __data_0); + } + break; + } +} + +void __GXVerifyBUMP(void) { + u32 i; + u32 nBmp; + u32 nTev; + u32 nTex; + u32 matrix; + + nBmp = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 16); + nTex = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 0); + nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; + + for (i = 0; i < nTev; i++) { + matrix = GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 4, 9); + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if ((u32)(__gxVerif->rasRegs[16 + i] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[7]) { + sprintf(__gxvDummyStr, __gxvWarnings[7], i); + __gxVerif->cb(__gxvWarnLev[7], 7U, __gxvDummyStr); + } + + if ((GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 2, 7) != 0 || matrix != 0) + && GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 2, 0) >= nBmp && __gxVerif->verifyLevel >= __gxvWarnLev[8]) { + sprintf(__gxvDummyStr, __gxvWarnings[8], i); + __gxVerif->cb(__gxvWarnLev[8], 8U, __gxvDummyStr); + } + + if (matrix != 0) { + matrix = (matrix & 3) - 1; + if (((u32)(__gxVerif->rasRegs[(matrix * 3) + 6] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[(matrix * 3) + 7] & 0xFF000000) + 0x01000000 == 0U + || (u32)(__gxVerif->rasRegs[(matrix * 3) + 8] & 0xFF000000) + 0x01000000 == 0U) && __gxVerif->verifyLevel >= __gxvWarnLev[9]) { + sprintf(__gxvDummyStr, __gxvWarnings[9], matrix, i); + __gxVerif->cb(__gxvWarnLev[9], 9U, __gxvDummyStr); + } + } + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if (nBmp != 0 && (u32)(__gxVerif->rasRegs[0x27] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[10]) { + __gxVerif->cb(__gxvWarnLev[10], 0xAU, __gxvWarnings[10]); + } + + if (nBmp != 0 && (u32)(__gxVerif->rasRegs[0x25] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[11]) { + sprintf(__gxvDummyStr, __gxvWarnings[11], 0U, 1); + __gxVerif->cb(__gxvWarnLev[11], 0xBU, __gxvDummyStr); + } + + if (nBmp > 2U && (u32)(__gxVerif->rasRegs[0x26] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[11]) { + sprintf(__gxvDummyStr, __gxvWarnings[11], 2U, 3); + __gxVerif->cb(__gxvWarnLev[11], 0xBU, __gxvDummyStr); + } + + if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 3) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { + sprintf(__gxvDummyStr, __gxvWarnings[12], 0U); + __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); + } + + if (nBmp > 1U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 9) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { + sprintf(__gxvDummyStr, __gxvWarnings[12], 1U); + __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); + } + + if (nBmp > 2U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 15) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { + sprintf(__gxvDummyStr, __gxvWarnings[12], 2U); + __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); + } + + if (nBmp > 3U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 21) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { + sprintf(__gxvDummyStr, __gxvWarnings[12], 3U); + __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); + } + + if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x10], 1, 20) && __gxVerif->verifyLevel >= __gxvWarnLev[13]) { + __gxVerif->cb(__gxvWarnLev[13], 0xDU, __gxvWarnings[13]); + } + + if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x10], 2, 7) != 0 && __gxVerif->verifyLevel >= __gxvWarnLev[14]) { + __gxVerif->cb(__gxvWarnLev[14], 0xEU, __gxvWarnings[14]); + } + + if ((u32)(__gxVerif->rasRegs[0xF] & 0xFF000000) + 0x01000000 == 0 && (nTex != 0 || nBmp != 0) && __gxVerif->verifyLevel >= __gxvWarnLev[15]) { + __gxVerif->cb(__gxvWarnLev[15], 0xFU, __gxvWarnings[15]); + } + } +} + +#define SOMEINDEX(index) (index & 3) + ((index * 8) & ~0x1F) + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +void __GXVerifyTEX(void) { + u32 i; + u32 nBmp; + u32 nTev; + u32 nTex; + u32 enabled; + u32 texId; + u32 direct[8]; + u32 indirect[8]; + u32 h2; + u32 w2; + u32 nlevels; + + nBmp = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 16); + nTex = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 0); + nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; + + for (i = 0; i < 8; i++) { + direct[i] = 0; + indirect[i] = 0; + } + + for (i = 0; i < nTev + nBmp; i++) { + if (i < nTev) { + if (__gxVerif->verifyLevel >= 1) { + if ((__gxVerif->rasRegs[(i >> 1U) + 0x28] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[16]) { + sprintf(__gxvDummyStr, __gxvWarnings[16], i); + __gxVerif->cb(__gxvWarnLev[16], 16, __gxvDummyStr); + } + + if (i & 1) { + enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 18); + if (enabled && (GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 15) >= nTex) && __gxVerif->verifyLevel >= __gxvWarnLev[17]) { + sprintf(__gxvDummyStr, __gxvWarnings[17], i); + __gxVerif->cb(__gxvWarnLev[17], 17, __gxvDummyStr); + } + texId = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 12); + } else { + enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 6); + if (enabled && (GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 3) >= nTex) && __gxVerif->verifyLevel >= __gxvWarnLev[17]) { + sprintf(__gxvDummyStr, __gxvWarnings[17], i); + __gxVerif->cb(__gxvWarnLev[17], 17, __gxvDummyStr); + } + texId = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 0); + } + + if (enabled) { + direct[texId] = 1; + } + } + } else { + enabled = 1; + if ((i - nTev) == 0) { + texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 0); + } else if ((i - nTev) == 1U) { + texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 6); + } else if ((i - nTev) == 2U) { + texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 12); + } else { + texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 18); + } + + if (!indirect[texId] && direct[texId] && __gxVerif->verifyLevel >= __gxvWarnLev[18]) { + sprintf(__gxvDummyStr, __gxvWarnings[18], texId); + __gxVerif->cb(__gxvWarnLev[18], 18, __gxvDummyStr); + } + indirect[texId] = 1; + } + + if (enabled) { + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if (((u32)(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[0x8C + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[0x90 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[19]) { + sprintf(__gxvDummyStr, __gxvWarnings[19], texId); + __gxVerif->cb(__gxvWarnLev[19], 19, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x8C + SOMEINDEX(texId)], 1, 21) == 0 + && (u32)(__gxVerif->rasRegs[0x94 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[20]) { + sprintf(__gxvDummyStr, __gxvWarnings[20], texId); + __gxVerif->cb(__gxvWarnLev[20], 20, __gxvDummyStr); + } + + if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) + && (__gxVerif->rasRegs[0x98 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[21]) { + sprintf(__gxvDummyStr, __gxvWarnings[21], texId); + __gxVerif->cb(__gxvWarnLev[21], 21, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1 == 0) { + w2 = 1; + } else { + w2 = 1; + while (!(w2 & (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1))) { + w2 *= 2; + } + w2 = (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1) == w2; + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1 == 0) { + h2 = 1; + } else { + h2 = 1; + while (!(h2 & (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1))) { + h2 *= 2; + } + h2 = (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1) == h2; + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) && !w2 && __gxVerif->verifyLevel >= __gxvWarnLev[22]) { + sprintf(__gxvDummyStr, __gxvWarnings[22], "Width", texId); + __gxVerif->cb(__gxvWarnLev[22], 22, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) && !h2 && __gxVerif->verifyLevel >= __gxvWarnLev[22]) { + sprintf(__gxvDummyStr, __gxvWarnings[22], "Height", texId); + __gxVerif->cb(__gxvWarnLev[22], 22, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 0) && !w2 && __gxVerif->verifyLevel >= __gxvWarnLev[23]) { + sprintf(__gxvDummyStr, __gxvWarnings[23], "S", texId); + __gxVerif->cb(__gxvWarnLev[23], 23, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 2) && !h2 && __gxVerif->verifyLevel >= __gxvWarnLev[23]) { + sprintf(__gxvDummyStr, __gxvWarnings[23], "T", texId); + __gxVerif->cb(__gxvWarnLev[23], 23, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) != 0 + && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) + && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 1 + && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 5 && __gxVerif->verifyLevel >= __gxvWarnLev[24]) { + sprintf(__gxvDummyStr, __gxvWarnings[24], texId); + __gxVerif->cb(__gxvWarnLev[24], 24, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 0) > (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 8) && __gxVerif->verifyLevel >= __gxvWarnLev[25]) { + sprintf(__gxvDummyStr, __gxvWarnings[25], texId); + __gxVerif->cb(__gxvWarnLev[25], 25, __gxvDummyStr); + } + + for ( + nlevels = 0; + ( + MAX((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1, + (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1) >> nlevels + ) != 0; + nlevels++) { + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 8) > (nlevels - 1) * 16 && __gxVerif->verifyLevel >= __gxvWarnLev[26]) { + sprintf(__gxvDummyStr, __gxvWarnings[26], texId); + __gxVerif->cb(__gxvWarnLev[26], 26, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 21) && GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 8) && __gxVerif->verifyLevel >= __gxvWarnLev[27]) { + sprintf(__gxvDummyStr, __gxvWarnings[27], texId); + __gxVerif->cb(__gxvWarnLev[27], 27, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 19) + && (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) == 0 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 6 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 4) != 1 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 8) != 0 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 21)) && __gxVerif->verifyLevel >= __gxvWarnLev[28]) { + sprintf(__gxvDummyStr, __gxvWarnings[28], texId); + __gxVerif->cb(__gxvWarnLev[28], 28, __gxvDummyStr); + } + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 18) != 0) { + if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 4 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 4) != 1) && __gxVerif->verifyLevel >= __gxvWarnLev[29]) { + sprintf(__gxvDummyStr, __gxvWarnings[29], texId); + __gxVerif->cb(__gxvWarnLev[29], 29, __gxvDummyStr); + } + + if ((!GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 17) || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) != 1 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 19) != 0) && __gxVerif->verifyLevel >= __gxvWarnLev[30]) { + sprintf(__gxvDummyStr, __gxvWarnings[30], texId); + __gxVerif->cb(__gxvWarnLev[30], 30, __gxvDummyStr); + } + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 17) != 0) { + if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) && __gxVerif->verifyLevel >= __gxvWarnLev[31]) { + sprintf(__gxvDummyStr, __gxvWarnings[31], texId); + __gxVerif->cb(__gxvWarnLev[31], 31, __gxvDummyStr); + } + + if ((!GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 18) || 0) && __gxVerif->verifyLevel >= __gxvWarnLev[30]) { + sprintf(__gxvDummyStr, __gxvWarnings[30], texId); + __gxVerif->cb(__gxvWarnLev[30], 30, __gxvDummyStr); + } + } + } + } +} + +#if DEBUG +static char _521[] = "A"; +static char _522[] = "B"; +static char _523[] = "C"; +static char _524[] = "D"; +asm void __GXVerifyTEV(void) { + nofralloc +#include "../../nonmatchings/__GXVerifyTEV.s" +} +#pragma peephole on +#else +void __GXVerifyTEV(void) { + u32 i; // r31 + u32 nTev; // r29 + u32 nCol; // r28 + u32 enabled; // r30 + u32 color; // r27 + u32 Clh[4]; // r1+0x38 + u32 Alh[4]; // r1+0x28 + u32 Cwritten[4]; // r1+0x18 + u32 Awritten[4]; // r1+0x8 + + nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; + nCol = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 4); + nCol; + + for (i = 0; i < 4; i++) { + Clh[i] = 0; + Alh[i] = 0; + Cwritten[i] = 0; + Awritten[i] = 0; + } + + for (i = 0; i < nTev; i++) { + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE + && (((u32) ((__gxVerif->rasRegs[(i * 2) + 0xC0] & 0xFF000000) + 0x01000000) == 0U) || ((u32) ((__gxVerif->rasRegs[(i * 2) + 0xC1] & 0xFF000000) + 0x01000000) == 0U))) { + sprintf(__gxvDummyStr, __gxvWarnings[32], i); + __gxVerif->cb(1, 0x20U, __gxvDummyStr); + } + + if (i & 1) { + color = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 19); + } else { + color = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 7); + } + + if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM && ((color == 0 && nCol < 1) || (color == 1 && nCol < 2))) { + sprintf(__gxvDummyStr, __gxvWarnings[33], i); + __gxVerif->cb(1, 0x21U, __gxvDummyStr); + } + + if (i & 1) { + enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 18); + } else { + enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 6); + } + + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) == 9)) { + sprintf(__gxvDummyStr, __gxvWarnings[0x22], "A", i); + __gxVerif->cb(1, 0x22U, __gxvDummyStr); + } + + if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) == 9)) { + sprintf(__gxvDummyStr, __gxvWarnings[0x22], "B", i); + __gxVerif->cb(1, 0x22U, __gxvDummyStr); + } + + if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) == 9)) { + sprintf(__gxvDummyStr, __gxvWarnings[0x22], "C", i); + __gxVerif->cb(1, 0x22U, __gxvDummyStr); + } + + if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) == 9)) { + sprintf(__gxvDummyStr, __gxvWarnings[0x22], "D", i); + __gxVerif->cb(1, 0x22U, __gxvDummyStr); + } + + if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) == 4) { + sprintf(__gxvDummyStr, __gxvWarnings[0x23], "A", i); + __gxVerif->cb(1, 0x23U, __gxvDummyStr); + } + + if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) == 4) { + sprintf(__gxvDummyStr, __gxvWarnings[0x23], "B", i); + __gxVerif->cb(1, 0x23U, __gxvDummyStr); + } + + if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) == 4) { + sprintf(__gxvDummyStr, __gxvWarnings[0x23], "C", i); + __gxVerif->cb(1, 0x23U, __gxvDummyStr); + } + + if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4) == 4) { + sprintf(__gxvDummyStr, __gxvWarnings[0x23], "D", i); + __gxVerif->cb(1, 0x23U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x24], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 0xCU) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 0xDU) & 7); + __gxVerif->cb(1, 0x24U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x24], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8U) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 9U) & 7); + __gxVerif->cb(1, 0x24U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x24], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4U) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 5U) & 7); + __gxVerif->cb(1, 0x24U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 0) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 1)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 1)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x24], "D", i, (__gxVerif->rasRegs[(i * 2) + 0xC0] & 1) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 1U) & 7); + __gxVerif->cb(1, 0x24U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 4, 14) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)] == 0U) { + sprintf(__gxvDummyStr, __gxvWarnings[0x25], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)); + __gxVerif->cb(1, 0x25U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 11) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)] == 0U) { + sprintf(__gxvDummyStr, __gxvWarnings[0x25], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)); + __gxVerif->cb(1, 0x25U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 8) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)] == 0U) { + sprintf(__gxvDummyStr, __gxvWarnings[0x25], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)); + __gxVerif->cb(1, 0x25U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 3) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4)] == 0U) { + sprintf(__gxvDummyStr, __gxvWarnings[0x25], "D", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4)); + __gxVerif->cb(1, 0x25U, __gxvDummyStr); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_ALL) { + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) <= 7) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x26], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)); + __gxVerif->cb(3, 0x26U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) <= 7) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x26], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)); + __gxVerif->cb(3, 0x26U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) <= 7) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x26], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)); + __gxVerif->cb(3, 0x26U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)] != 0) { + sprintf(__gxvDummyStr, __gxvWarnings[0x27], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 0xDU)); + __gxVerif->cb(3, 0x27U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)] != 0) { + sprintf(__gxvDummyStr, __gxvWarnings[0x27], "B", i, ((__gxVerif->rasRegs[(i * 2) + 0xC1] >> 0xAU) & 7)); + __gxVerif->cb(3, 0x27U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)] != 0) { + sprintf(__gxvDummyStr, __gxvWarnings[0x27], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7U)); + __gxVerif->cb(3, 0x27U, __gxvDummyStr); + } + } + Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 2, 22)] = 1; + Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 22)] = 1; + Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 2, 22)] = (!GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 19)); + Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 22)] = (!GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 1, 19)); + } + + for (i = 0; i < 4; i++) { + if (Cwritten[i] != 0U) { + __gxVerif->rasRegs[(i * 2) + 0xE1] = (__gxVerif->rasRegs[(i * 2) + 0xE1] & 0xFFFFFF) | 0xFF000000; + } + if (Awritten[i] != 0U) { + __gxVerif->rasRegs[(i * 2) + 0xE0] = (__gxVerif->rasRegs[(i * 2) + 0xE0] & 0xFFFFFF) | 0xFF000000; + } + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0xF5], 2, 2) && __gxVerif->verifyLevel >= 1) { + if ((u32) ((__gxVerif->rasRegs[0xF4] & 0xFF000000) + 0x01000000) == 0U) { + __gxVerif->cb(1, 0x28U, __gxvWarnings[0x28]); + } + if (!enabled) { + __gxVerif->cb(1, 0x29U, __gxvWarnings[0x29]); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM) { + if (GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC0], 2, 22)) { + __gxVerif->cb(2, 0x2AU, __gxvWarnings[0x2A]); + } + if (GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 22)) { + __gxVerif->cb(2, 0x2BU, __gxvWarnings[0x2B]); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_ALL) { + if (!GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC0], 1, 19)) { + __gxVerif->cb(3, 0x2CU, __gxvWarnings[0x2C]); + } + if (!GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 1, 19)) { + __gxVerif->cb(3, 0x2DU, __gxvWarnings[0x2D]); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM && GET_REG_FIELD(__gxVerif->rasRegs[0x43], 1, 6) && (GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 2, 22) || ((u32) GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 3, 16) != 7) || ((u32) GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 3, 19) != 7))) { + __gxVerif->cb(2, 0x2EU, __gxvWarnings[0x2E]); + } +} +#endif + +void __GXVerifyPE(void) { + u32 i; + + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE && GET_REG_FIELD(__gxVerif->rasRegs[0x41], 1, 0) && GET_REG_FIELD(__gxVerif->rasRegs[0x41], 1, 1) && __gxVerif->verifyLevel >= __gxvWarnLev[0x2F]) { + __gxVerif->cb(__gxvWarnLev[0x2F], 0x2FU, __gxvWarnings[0x2F]); + } + + if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM) { + if (GET_REG_FIELD(__gxVerif->rasRegs[0], 1, 9) && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) != 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x31]) { + __gxVerif->cb(__gxvWarnLev[0x31], 0x31U, __gxvWarnings[0x31]); + } + if (!GET_REG_FIELD(__gxVerif->rasRegs[0], 1, 9) && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) == 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x32]) { + __gxVerif->cb(__gxvWarnLev[0x32], 0x32U, __gxvWarnings[0x32]); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_ALL) { + for (i = 0; i < 4; i++) { + if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 4) > GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 12) || (u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 12) > (u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 20)) + && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) == 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x33]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x33], i); + __gxVerif->cb(__gxvWarnLev[0x33], 0x33U, __gxvDummyStr); + } + } + } +} + +#endif diff --git a/src/dolphin/gx/GXVerifXF.c b/src/dolphin/gx/GXVerifXF.c new file mode 100644 index 0000000..1e45aab --- /dev/null +++ b/src/dolphin/gx/GXVerifXF.c @@ -0,0 +1,1002 @@ +#if DEBUG + +#include + +#include + +#include "__gx.h" + +static u8 internalDebug; +static u32 DumpCount; +static s8 XFBuf[128]; +static u32 numRegularTextures; +static u32 numBumpmapTextures; +static u32 numColor0Textures; +static u32 numColor1Textures; +static u32 numColorTextures; +static s32 XFChannel = -1; + +static GXAttr TextureEnums[8] = { + GX_VA_TEX0, + GX_VA_TEX1, + GX_VA_TEX2, + GX_VA_TEX3, + GX_VA_TEX4, + GX_VA_TEX5, + GX_VA_TEX6, + GX_VA_TEX7, +}; + +static GXAttr MtxIdxEnums[9] = { + GX_VA_PNMTXIDX, + GX_VA_TEX0MTXIDX, + GX_VA_TEX1MTXIDX, + GX_VA_TEX2MTXIDX, + GX_VA_TEX3MTXIDX, + GX_VA_TEX4MTXIDX, + GX_VA_TEX5MTXIDX, + GX_VA_TEX6MTXIDX, + GX_VA_TEX7MTXIDX, +}; + +static u8 lightRegisterNames[13][256] = { + "Light Color RGBA", + "Cosine Attenuation A0", + "Cosine Attenuation A1", + "Cosine Attenuation A2", + "Distance Attenuation K0", + "Distance Attenuation K1", + "Distance Attenuation K2", + "X Light Position / Infinite Light X Direction", + "Y Light Position / Infinite Light Y Direction", + "Z Light Position / Infinite Light Z Direction", + "X Light Direction / Half Angle X Component", + "Y Light Direction / Half Angle Y Component", + "Z Light Direction / Half Angle Z Component", +}; + +#define LOWORD(var) (((u16 *)&(var))[0]) +#define HIWORD(var) (((u16 *)&(var))[1]) + +#define BYTE0(var) (((u8 *)&(var))[0]) +#define BYTE1(var) (((u8 *)&(var))[1]) +#define BYTE2(var) (((u8 *)&(var))[2]) +#define BYTE3(var) (((u8 *)&(var))[3]) + +static void CountTextureTypes(void) { + u32 i; + u32 texgen_type; + + numRegularTextures = 0; + numBumpmapTextures = 0; + numColor0Textures = 0; + numColor1Textures = 0; + + for (i = 0; i < __gxVerif->xfRegs[0x3F]; i++) { + texgen_type = BYTE3(__gxVerif->xfRegs[i + 64]); + texgen_type = (texgen_type >> 4) & 7; + if (texgen_type == 0) { + numRegularTextures++; + } else if (texgen_type == 1) { + numBumpmapTextures++; + } else if (texgen_type == 2) { + numColor0Textures++; + } else if (texgen_type == 3) { + numColor1Textures++; + } else { + if (__gxVerif->verifyLevel >= __gxvWarnLev[52]) { + __GX_WARNF(GXWARN_INVALID_TG_TYPE, texgen_type, i); + } + } + } + numColorTextures = numColor0Textures + numColor1Textures; +} + +static void InitializeXFVerifyData(void) { + CountTextureTypes(); +} + +static void CheckDirty(u32 index, const char* name) { + if (!__gxVerif->xfRegsDirty[index - 0x1000] && __gxVerif->verifyLevel >= __gxvWarnLev[53]) { + __GX_WARNF(GXWARN_XF_CTRL_UNINIT, index, name); + } +} + +static void CheckClean(u32 index, const char* name) { + if (__gxVerif->xfRegsDirty[index - 0x1000] && __gxVerif->verifyLevel >= __gxvWarnLev[54]) { + __GX_WARNF(GXWARN_XF_CTRL_INIT, index, name); + } +} + +static void CheckCTGColors(void) { + if ((u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) > 2 && __gxVerif->verifyLevel >= __gxvWarnLev[120]) { + __GX_WARNF(120, (u8)(BYTE3(__gxVerif->xfRegs[9]) & 3)); + } +} + +static GXBool __GXVertexPacketHas(GXAttr attr) { + switch (attr) { + case GX_VA_POS: return GET_REG_FIELD(__GXData->vcdLo, 2, 9) != 0; + case GX_VA_NRM: return __GXData->hasNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) != 0 : GX_FALSE; + case GX_VA_NBT: return __GXData->hasBiNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) != 0 : GX_FALSE; + case GX_VA_CLR0: return GET_REG_FIELD(__GXData->vcdLo, 2, 13) != 0; + case GX_VA_CLR1: return GET_REG_FIELD(__GXData->vcdLo, 2, 15) != 0; + case GX_VA_TEX0: return GET_REG_FIELD(__GXData->vcdHi, 2, 0) != 0; + case GX_VA_TEX1: return GET_REG_FIELD(__GXData->vcdHi, 2, 2) != 0; + case GX_VA_TEX2: return GET_REG_FIELD(__GXData->vcdHi, 2, 4) != 0; + case GX_VA_TEX3: return GET_REG_FIELD(__GXData->vcdHi, 2, 6) != 0; + case GX_VA_TEX4: return GET_REG_FIELD(__GXData->vcdHi, 2, 8) != 0; + case GX_VA_TEX5: return GET_REG_FIELD(__GXData->vcdHi, 2, 10) != 0; + case GX_VA_TEX6: return GET_REG_FIELD(__GXData->vcdHi, 2, 12) != 0; + case GX_VA_TEX7: return GET_REG_FIELD(__GXData->vcdHi, 2, 14) != 0; + case GX_VA_PNMTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 0) != 0; + case GX_VA_TEX0MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 1) != 0; + case GX_VA_TEX1MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 2) != 0; + case GX_VA_TEX2MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 3) != 0; + case GX_VA_TEX3MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 4) != 0; + case GX_VA_TEX4MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 5) != 0; + case GX_VA_TEX5MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 6) != 0; + case GX_VA_TEX6MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 7) != 0; + case GX_VA_TEX7MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 8) != 0; + default: + return GX_FALSE; + } +} + +static void CheckVertexPacket(void) { + u32 numHostTextures; + u32 numHostTexAbsent; + u32 i; + u32 numMatrixIndices; + + if (!__GXVertexPacketHas(GX_VA_POS) && __gxVerif->verifyLevel >= __gxvWarnLev[57]) { + __GX_WARN(GXWARN_VTX_NO_GEOM); + } + + if (__GXVertexPacketHas(GX_VA_CLR1) && !__GXVertexPacketHas(GX_VA_CLR0) &&__gxVerif->verifyLevel >= __gxvWarnLev[70]) { + __GX_WARN(GXWARN_VCD_CLR_ORDER); + } + + numHostTextures = 0; + numHostTexAbsent = 0; + + for (i = 0; i < 8; i++) { + if (__GXVertexPacketHas(TextureEnums[i])) { + numHostTextures += 1; + numHostTexAbsent = 0; + } else { + numHostTexAbsent += 1; + } + } + + if (numHostTextures + numHostTexAbsent != 8 && __gxVerif->verifyLevel >= __gxvWarnLev[71]) { + __GX_WARN(GXWARN_VCD_TEX_ORDER); + } + + if ((BYTE3(__gxVerif->xfRegs[8]) & 3) == 0 && ((BYTE3(__gxVerif->xfRegs[8]) >> 2) & 3) == 0 && (u32)((BYTE3(__gxVerif->xfRegs[8]) >> 4) & 0xF) == 0) { + numMatrixIndices = 0; + + for (i = 0; i <= 8; i++) { + if (__GXVertexPacketHas(MtxIdxEnums[i])) { + numMatrixIndices += 1; + } + } + + if (numMatrixIndices != 0 && __gxVerif->verifyLevel >= __gxvWarnLev[69]) { + __GX_WARN(GXWARN_VCD_FMT_UNSUP); + } + } +} + +static void CheckSourceRows(void) { + u32 i; + + for (i = 0; i < numRegularTextures; i++) { + switch ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) { + case 0: + if (!__GXVertexPacketHas(GX_VA_POS) && __gxVerif->verifyLevel >= __gxvWarnLev[72]) { + __GX_WARNF(GXWARN_TEX_SRC_NPOS, i); + } + break; + case 1: + if (!__GXVertexPacketHas(GX_VA_NRM) && !__GXVertexPacketHas(GX_VA_NBT)&& __gxVerif->verifyLevel >= __gxvWarnLev[73]) { + __GX_WARNF(GXWARN_TEX_SRC_NNRM, i); + } + break; + case 2: + if (!__GXVertexPacketHas(GX_VA_CLR0) && __gxVerif->verifyLevel >= __gxvWarnLev[74]) { + __GX_WARNF(GXWARN_TEX_SRC_NCLR0, i); + } + if (!__GXVertexPacketHas(GX_VA_CLR1) && __gxVerif->verifyLevel >= __gxvWarnLev[75]) { + __GX_WARNF(GXWARN_TEX_SRC_NCLR1, i); + } + break; + case 3: + case 4: + if (!__GXVertexPacketHas(GX_VA_NBT) && __gxVerif->verifyLevel >= __gxvWarnLev[76]) { + __GX_WARNF(GXWARN_TEX_SRC_NNBT, i); + } + break; + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + if (!__GXVertexPacketHas(TextureEnums[((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) - 5]) && __gxVerif->verifyLevel >= __gxvWarnLev[77]) { + __GX_WARNF(GXWARN_TEX_SRC_NTEX, i, ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) - 5); + } + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[78]) { + __GX_WARNF(GXWARN_INV_TEX_SRC, i, (u8)((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F)); + } + break; + } + } +} + +static void CheckTextureOrder(void) { + u8 done = 0; + u32 count = 0; + + while (!done) { + if (count == __gxVerif->xfRegs[0x3F] || ((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7)) { + done = 1; + } else { + count += 1; + } + } + + done = 0; + while (done == 0) { + if (count == __gxVerif->xfRegs[0x3F]) { + done = 1; + } else if ((u32)((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) != 1) { + if (!((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) && __gxVerif->verifyLevel >= __gxvWarnLev[79]) { + __GX_WARN(GXWARN_INV_TG_ORDER); + } + done = 1; + } else { + count += 1; + } + } + + done = 0; + while (done == 0) { + if (count == __gxVerif->xfRegs[0x3F]) { + done = 1; + } else if (!((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) || (u32)((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) == 1) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[79]) { + __GX_WARN(GXWARN_INV_TG_ORDER); + } + done = 1; + } else { + count += 1; + } + } +} + +static void CheckRAM(u8 Normal, u32 StartingAddress, u32 Count, GXWarnID WarnID, char* Str) { + u32 i; + u8 printedPreamble; + u8 dirtyBit; + + printedPreamble = 0; + + for (i = StartingAddress; i < StartingAddress + Count; i++) { + dirtyBit = Normal != 0 ? __gxVerif->xfMtxDirty[i - 0x300] : __gxVerif->xfMtxDirty[i]; + + if (dirtyBit == 0) { + if (printedPreamble == 0) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[WarnID]) { + __gxVerif->cb(__gxvWarnLev[WarnID], WarnID, Str); + } + + printedPreamble = 1; + } + } + } +} + +static void CheckBumpmapTextures(void) { + u32 i; + u32 BumpMapSource; + u32 BumpMapLight; + u32 lightRAMOffset; + char Preamble[256]; + + if (!__GXVertexPacketHas(GX_VA_PNMTXIDX)) { + if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x50]) { + __GX_WARNF(0x50, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + } + sprintf(Preamble, __gxvWarnings[0x6A], (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9U, 0x6A, Preamble); + } + + for (i = 0; i < numBumpmapTextures; i++) { + BumpMapSource = BYTE2(__gxVerif->xfRegs[numRegularTextures + i + 64]); + BumpMapSource = (BumpMapSource >> 4) & 7; + if ((BYTE3(__gxVerif->xfRegs[BumpMapSource + 64]) >> 4) & 7 && __gxVerif->verifyLevel >= __gxvWarnLev[0x51]) { + __GX_WARNF(0x51, i + numRegularTextures, BumpMapSource); + } + + BumpMapLight = __gxVerif->xfRegs[numRegularTextures + i + 0x40]; + BumpMapLight = (BumpMapLight >> 15) & 7; + lightRAMOffset = (BumpMapLight * 0x10) + 0x60A; + if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 0] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { + __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "X"); + } + + if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 1] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { + __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "Y"); + } + + if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 2] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { + __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "Z"); + } + + if (!__GXVertexPacketHas(GX_VA_NBT) && __gxVerif->verifyLevel >= __gxvWarnLev[0x53]) { + __GX_WARNF(0x53, i); + } + } + + lightRAMOffset; lightRAMOffset; // needed to match +} + +static void CheckTextureTransformMatrices(void) { + u32 i; + u32 StartingAddress; + u32 Size; + u8 MtxIndexInVertexPacket; + char Preamble[256]; + u32 Val; + + for (i = 0; i < numRegularTextures; i++) { + MtxIndexInVertexPacket = 0; + switch (i) { + case 0: + StartingAddress = (u8)((HIWORD(__gxVerif->xfRegs[0x18]) >> 4U) & 0xFC); + Val = HIWORD(__gxVerif->xfRegs[0x18]); + Val = (Val >> 6) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX0MTXIDX); + break; + case 1: + StartingAddress = (u8)((__gxVerif->xfRegs[0x18] >> 10) & 0xFC); + Val = __gxVerif->xfRegs[0x18]; + Val = (Val >> 12) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX1MTXIDX); + break; + case 2: + StartingAddress = (u8)(BYTE1(__gxVerif->xfRegs[0x18]) & 0xFC); + Val = BYTE1(__gxVerif->xfRegs[0x18]); + Val = (Val >> 2) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX2MTXIDX); + break; + case 3: + StartingAddress = (BYTE0(__gxVerif->xfRegs[0x18]) * 4) & 0xFC; + Val = BYTE0(__gxVerif->xfRegs[0x18]); + Val = Val & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX3MTXIDX); + break; + case 4: + StartingAddress = (BYTE3(__gxVerif->xfRegs[0x19]) * 4) & 0xFC; + Val = BYTE3(__gxVerif->xfRegs[0x19]); + Val = Val & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX4MTXIDX); + break; + case 5: + StartingAddress = (u8)((HIWORD(__gxVerif->xfRegs[0x19]) >> 4) & 0xFC); + Val = HIWORD(__gxVerif->xfRegs[0x19]); + Val = (Val >> 6) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX5MTXIDX); + break; + case 6: + StartingAddress = (u8)((__gxVerif->xfRegs[0x19] >> 10) & 0xFC); + Val = __gxVerif->xfRegs[0x19]; + Val = (Val >> 12) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX6MTXIDX); + break; + case 7: + StartingAddress = (u8)(BYTE1(__gxVerif->xfRegs[0x19]) & 0xFC); + Val = BYTE1(__gxVerif->xfRegs[0x19]); + Val = (Val >> 2) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX7MTXIDX); + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x54]) { + __GX_WARNF(0x54, i); + } + break; + } + + if (MtxIndexInVertexPacket == 0) { + sprintf(Preamble, __gxvWarnings[0x6B], i, i, Val); + if (!((BYTE3(__gxVerif->xfRegs[i + 64]) >> 1) & 1)) { + Size = 8; + } else { + Size = 0xC; + } + CheckRAM(0U, StartingAddress, Size, 0x6B, Preamble); + } + } + + // needed to match + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; +} + +static void CheckInputForms(void) { + u32 i; + + for (i = 0; i < numRegularTextures; i++) { + switch ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) { + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + if ((BYTE3(__gxVerif->xfRegs[i + 64]) >> 2) & 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x79]) { + __GX_WARNF(0x79, i, (u8)((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F)); + } + } + } +} + +static void CheckLight(u32 lightSource) { + u32 lightRAMOffset; + u8 printedPreamble; + u32 i; + + printedPreamble = 0; + lightRAMOffset = (lightSource * 0x10) + 0x603; + for (i = 0; i < 13; i++) { + if (!__gxVerif->xfLightDirty[lightRAMOffset + i - 0x600]) { + if (!printedPreamble) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x6C]) { + __GX_WARNF(0x6C, lightSource); + } + + printedPreamble = 1; + } + } + } +} + +// NONMATCHING +static void CheckColor0(void) { + char Preamble[256]; + u8 haveLight; + u32 i; + u8 lightUsed; + + if ((u8)(BYTE3(__gxVerif->xfRegs[9]) & 3) || numColorTextures != 0) { + if (!__gxVerif->xfRegsDirty[14] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { + __GX_WARNF(0x7A, 0x100E, "Color 0 control register"); + } + + if (!__gxVerif->xfRegsDirty[16] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { + __GX_WARNF(0x7A, 0x1010, "Alpha 0 control register"); + } + + if (!(BYTE3(__gxVerif->xfRegs[14]) & 1) && !__gxVerif->xfRegsDirty[12] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7B]) { + __GX_WARNF(0x7B, 0, 0, 0x100C); + } + + if (!((BYTE3(__gxVerif->xfRegs[14]) >> 6) & 1) && !__gxVerif->xfRegsDirty[10] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7C]) { + __GX_WARNF(0x7C, 0, 0, 0x100A); + } + + if ((u32)((BYTE3(__gxVerif->xfRegs[14]) >> 1) & 1) == 1 || (u32)((BYTE3(__gxVerif->xfRegs[16]) >> 1) & 1) == 1) { + haveLight = 0; + for (i = 0; i < 8; i++) { + lightUsed = 0; + switch (i) { + case 0: + if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 2) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 2) & 1)) { + lightUsed = 1; + } + break; + case 1: + if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 3) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 3) & 1)) { + lightUsed = 1; + } + break; + case 2: + if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 4) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 4) & 1)) { + lightUsed = 1; + } + break; + case 3: + if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 5) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 5) & 1)) { + lightUsed = 1; + } + break; + case 4: + if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 3) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 3) & 1)) { + lightUsed = 1; + } + break; + case 5: + if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 4) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 4) & 1)) { + lightUsed = 1; + } + break; + case 6: + if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 5) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 5) & 1)) { + lightUsed = 1; + } + break; + case 7: + if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 6) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 6) & 1)) { + lightUsed = 1; + } + break; + } + if (lightUsed != 0) { + CheckLight(i); + haveLight = 1; + } + } + + if (haveLight != 0) { + if (!((BYTE2(__gxVerif->xfRegs[14]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[14]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { + __GX_WARNF(0x59, "COLOR0", "COLOR0"); + } + + if (!((BYTE2(__gxVerif->xfRegs[16]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[16]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { + __GX_WARNF(0x59, "ALPHA0", "ALPHA0"); + } + + if (((HIWORD(__gxVerif->xfRegs[14]) >> 7) & 3) + || ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[14]) >> 2) & 1) == 1)) + || ((HIWORD(__gxVerif->xfRegs[16]) >> 7) & 3) + || ((u8)((BYTE2(__gxVerif->xfRegs[16]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[16]) >> 2) & 1) == 1))) { + if ((__GXVertexPacketHas(GX_VA_NRM) == 0) && (__GXVertexPacketHas(GX_VA_NBT) == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[0x5A]) { + __GX_WARNF(0x5A, 0); + } + if (__GXVertexPacketHas(GX_VA_PNMTXIDX) == 0) { + if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x5B]) { + __GX_WARNF(0x5B, 0, (BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + } + sprintf(Preamble, __gxvWarnings[0x6D], 0, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9, 0x6D, Preamble); + } + } + } + } + } +} + +// NONMATCHING +static void CheckColor1(void) { + u8 usingColor1; + char Preamble[256]; + u8 haveLight; + u32 i; + u8 lightUsed; + + if (numColorTextures > 1 && ((u32)((BYTE3(__gxVerif->xfRegs[numRegularTextures + numBumpmapTextures + 1 + 64]) >> 4) & 7) == 3)) { + usingColor1 = 1; + } else { + usingColor1 = 0; + } + + if ((u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) == 2 || usingColor1) { + if (!__gxVerif->xfRegsDirty[15] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { + __GX_WARNF(0x7A, 0x100F, "Color 1 control register"); + } + + if (!__gxVerif->xfRegsDirty[17] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { + __GX_WARNF(0x7A, 0x1011, "Alpha 1 control register"); + } + + if (!(BYTE3(__gxVerif->xfRegs[15]) & 1) && !__gxVerif->xfRegsDirty[13] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7B]) { + __GX_WARNF(0x7B, 1, 1, 0x100D); + } + + if (!((BYTE3(__gxVerif->xfRegs[15]) >> 6) & 1) && !__gxVerif->xfRegsDirty[11] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7C]) { + __GX_WARNF(0x7C, 1, 1, 0x100B); + } + + if ((u32)((BYTE3(__gxVerif->xfRegs[15]) >> 1) & 1) == 1 || (u32)((BYTE3(__gxVerif->xfRegs[17]) >> 1) & 1) == 1) { + haveLight = 0; + for (i = 0; i < 8; i++) { + lightUsed = 0; + switch (i) { + case 0: + if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 2) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 2) & 1)) { + lightUsed = 1; + } + break; + case 1: + if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 3) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 3) & 1)) { + lightUsed = 1; + } + break; + case 2: + if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 4) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 4) & 1)) { + lightUsed = 1; + } + break; + case 3: + if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 5) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 5) & 1)) { + lightUsed = 1; + } + break; + case 4: + if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 3) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 3) & 1)) { + lightUsed = 1; + } + break; + case 5: + if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 4) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 4) & 1)) { + lightUsed = 1; + } + break; + case 6: + if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 5) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 5) & 1)) { + lightUsed = 1; + } + break; + case 7: + if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 6) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 6) & 1)) { + lightUsed = 1; + } + break; + } + if (lightUsed != 0) { + CheckLight(i); + haveLight = 1; + } + } + + if (haveLight != 0) { + if (!((BYTE2(__gxVerif->xfRegs[15]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[15]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { + __GX_WARNF(0x59, "COLOR1", "COLOR1"); + } + + if (!((BYTE2(__gxVerif->xfRegs[17]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[17]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { + __GX_WARNF(0x59, "ALPHA1", "ALPHA1"); + } + + if (((HIWORD(__gxVerif->xfRegs[15]) >> 7) & 3) + || ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[15]) >> 2) & 1) == 1)) + || ((HIWORD(__gxVerif->xfRegs[17]) >> 7) & 3) + || ((u8)((BYTE2(__gxVerif->xfRegs[17]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[17]) >> 2) & 1) == 1))) { + if ((__GXVertexPacketHas(GX_VA_NRM) == 0) && (__GXVertexPacketHas(GX_VA_NBT) == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[0x5A]) { + __GX_WARNF(0x5A, 1); + } + if (__GXVertexPacketHas(GX_VA_PNMTXIDX) == 0) { + if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x5B]) { + __GX_WARNF(0x5B, 1, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + } + sprintf(Preamble, __gxvWarnings[0x6D], 1, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9, 0x6D, Preamble); + } + } + } + } + } +} + +static void CheckViewport(void) { + f32 vl; + f32 vr; + f32 vt; + f32 vb; + + vl = (*(f32*)&__gxVerif->xfRegs[29] - *(f32*)&__gxVerif->xfRegs[26]) - 342.0f; + vt = (*(f32*)&__gxVerif->xfRegs[30] + *(f32*)&__gxVerif->xfRegs[27]) - 342.0f; + vr = (*(f32*)&__gxVerif->xfRegs[29] + *(f32*)&__gxVerif->xfRegs[26]) - 342.0f; + vb = (*(f32*)&__gxVerif->xfRegs[30] - *(f32*)&__gxVerif->xfRegs[27]) - 342.0f; + + if ((vt < -0.5f || vt > 528.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x55]) { + __GX_WARNF(0x55, vt); + } + + if ((vb < 0.0f || vb > 528.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x56]) { + __GX_WARNF(0x56, vb); + } + + if ((vl < 0.0f || vl > 640.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x57]) { + __GX_WARNF(0x57, vl); + } + + if ((vr < 0.0f || vr > 640.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x58]) { + __GX_WARNF(0x58, vr); + } +} + +static void ComputeSignExponentMantissa(f32 floatVal, u32* sign, u32* exponent, u32* mantissa) { + u32 intVal = *(u32*)&floatVal; + + *sign = (intVal >> 31) & 1; + *exponent = (intVal >> 23) & 0xFF; + *mantissa = intVal & 0x7FFFFF; +} + +static void CheckFloatingPointValue(u8 dirtyBit, u32 value, char* label) { + u32 sign; + u32 exponent; + u32 mantissa; + f32 valuef; + + &valuef; + + if ((dirtyBit == 0)) { + return; + } + valuef = *(f32 *)&value; + ComputeSignExponentMantissa(valuef, &sign, &exponent, &mantissa); + + if (exponent == 0 && mantissa == 0) { + return; + } + + if (exponent == 0xFF) { + if (__gxVerif->verifyLevel >= 2) { + if (mantissa == 0) { + if (sign != 0) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5C]) { + __GX_WARNF(0x5C, label, "-", *(u32 *)&valuef); + } + } else { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5C]) { + __GX_WARNF(0x5C, label, "+", *(u32 *)&valuef); + } + } + } else { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5D]) { + __GX_WARNF(0x5D, label, *(u32 *)&valuef); + } + } + } + } else if (__gxVerif->verifyLevel >= 3) { + if (exponent < 0x6BU) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5E]) { + __GX_WARNF(0x5E, label, valuef, *(u32 *)&valuef); + } + } else if (exponent > 0x96U) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5F]) { + __GX_WARNF(0x5F, label, valuef, *(u32 *)&valuef); + } + } + } +} + +static void CheckMatrixRAMRanges(void) { + u32 i; + char label[256]; + + for (i = 0; i <= 255; i++) { + sprintf(label, "Geometry/Texture Matrix ram address 0x%04x", i); + CheckFloatingPointValue(__gxVerif->xfMtxDirty[i], __gxVerif->xfMtx[i], label); + } +} + +static void CheckNormalRAMRanges(void) { + u32 i; + char label[256]; + + for (i = 1024; i <= 1119; i++) { + sprintf(label, "Normal Matrix ram address 0x%04x", i); + CheckFloatingPointValue(__gxVerif->xfNrmDirty[i - 1024], __gxVerif->xfNrm[i - 1024], label); + } +} + +static void CheckDMatrixRAMRanges(void) { + u32 i; + char label[256]; + + for (i = 1280; i <= 1535; i++) { + sprintf(label, "Dual Texture Matrix ram address 0x%04x", i); + CheckFloatingPointValue(__gxVerif->xfDMtxDirty[i - 1280], __gxVerif->xfDMtx[i - 1280], label); + } +} + +static void CheckLightRAMRanges(void) { + u32 lightSource; + u32 lightRAMOffset; + char label[256]; + u32 i; + + for (lightSource = 0; lightSource < 8; lightSource++) { + for (i = 1; i < 13; i++) { + lightRAMOffset = (lightSource << 4) + i; + lightRAMOffset += 0x603; + sprintf(label, "Light %d %s (address 0x%04x)", lightSource, lightRegisterNames[i], lightRAMOffset); + CheckFloatingPointValue(__gxVerif->xfLightDirty[lightRAMOffset - 0x600], __gxVerif->xfLight[(s32) (lightRAMOffset - 0x600)], label); + } + + } + + i; lightSource; // needed to match +} + +static void CheckControlRAMRanges(void) { + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1A], __gxVerif->xfRegs[0x1A], "Viewport Scale X"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1B], __gxVerif->xfRegs[0x1B], "Viewport Scale Y"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1C], __gxVerif->xfRegs[0x1C], "Viewport Scale Z"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1D], __gxVerif->xfRegs[0x1D], "Viewport Offset X"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1E], __gxVerif->xfRegs[0x1E], "Viewport Offset Y"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1F], __gxVerif->xfRegs[0x1F], "Viewport Offset Z"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x20], __gxVerif->xfRegs[0x20], "Projection Matrix A Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x21], __gxVerif->xfRegs[0x21], "Projection Matrix B Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x22], __gxVerif->xfRegs[0x22], "Projection Matrix C Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x23], __gxVerif->xfRegs[0x23], "Projection Matrix D Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x24], __gxVerif->xfRegs[0x24], "Projection Matrix E Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x25], __gxVerif->xfRegs[0x25], "Projection Matrix F Value"); +} + +static void CheckFloatingPointRanges(void) { + CheckMatrixRAMRanges(); + CheckNormalRAMRanges(); + CheckDMatrixRAMRanges(); + CheckLightRAMRanges(); + CheckControlRAMRanges(); +} + +static void CheckMatrixIndices(void) { + if (!__GXVertexPacketHas(GX_VA_PNMTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX0MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX1MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX2MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX3MTXIDX)) + { + CheckDirty(0x1018U, "Geometry & Textures [0-3] transform matrix indices"); + } + + if (__gxVerif->verifyLevel >= 1 && !__GXVertexPacketHas(GX_VA_PNMTXIDX)) { + CheckRAM(0U, (BYTE3(__gxVerif->xfRegs[24]) * 4) & 0xFC, 0xCU, 0x6E, __gxvWarnings[0x6E]); + } + + if ((!__GXVertexPacketHas(GX_VA_TEX4MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX5MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX6MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX7MTXIDX)) + && numRegularTextures > 4 + && __gxVerif->verifyLevel >= 1 + && !__gxVerif->xfRegsDirty[0x19] && __gxVerif->verifyLevel >= __gxvWarnLev[0x60]) { + __GX_WARNF(0x60, numRegularTextures, 0x1019U); + } +} + +static void CheckErrors(void) { + u32 i; + char registerName[80]; + + CheckDirty(0x103FU, "Number of XF output textures"); + CheckDirty(0x1009U, "Number of XF output colors"); + CheckDirty(0x1008U, "InVertexSpec"); + CheckDirty(0x101AU, "Viewport ScaleX"); + CheckDirty(0x101BU, "Viewport ScaleY"); + CheckDirty(0x101CU, "Viewport ScaleZ"); + CheckDirty(0x101DU, "Viewport OffsetX"); + CheckDirty(0x101EU, "Viewport OffsetY"); + CheckDirty(0x101FU, "Viewport OffsetZ"); + CheckDirty(0x1020U, "Projection matrix 'A' value"); + CheckDirty(0x1021U, "Projection matrix 'B' value"); + CheckDirty(0x1022U, "Projection matrix 'C' value"); + CheckDirty(0x1023U, "Projection matrix 'D' value"); + CheckDirty(0x1024U, "Projection matrix 'E' value"); + CheckDirty(0x1025U, "Projection matrix 'F' value"); + CheckDirty(0x1026U, "Projection matrix orthographic/perspective select"); + CheckMatrixIndices(); + + if (__gxVerif->verifyLevel >= 1) { + if (!(u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) && !__gxVerif->xfRegs[0x3F] && __gxVerif->verifyLevel >= __gxvWarnLev[0x38]) { + __GX_WARN(0x38); + } + + CheckCTGColors(); + + if (__gxVerif->xfRegs[0x3F] > 8 && __gxVerif->verifyLevel >= __gxvWarnLev[0x64]) { + __GX_WARNF(0x64, __gxVerif->xfRegs[0x3F], 8); + } + if (numRegularTextures > 8 && __gxVerif->verifyLevel >= __gxvWarnLev[0x65]) { + __GX_WARNF(0x65, numRegularTextures, 8); + } + if (numBumpmapTextures > 3 && __gxVerif->verifyLevel >= __gxvWarnLev[0x66]) { + __GX_WARNF(0x66, numBumpmapTextures, 3); + } + if (numColorTextures > 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x67]) { + __GX_WARNF(0x67, numColorTextures, 2); + } + if (numColor0Textures > 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x69]) { + __GX_WARNF(0x69, 0); + } + if (numColor1Textures > 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x69]) { + __GX_WARNF(0x69, 1); + } + + CheckVertexPacket(); + + for (i = 0; i < __gxVerif->xfRegs[0x3F]; i++) { + sprintf(registerName, "Texture %d settings", i); + CheckDirty(i + 0x1040, registerName); + } + + CheckSourceRows(); + CheckTextureOrder(); + if (numBumpmapTextures != 0) { + CheckBumpmapTextures(); + } + + CheckTextureTransformMatrices(); + if (numColorTextures != 0 && (u32)((BYTE3(__gxVerif->xfRegs[numRegularTextures + numBumpmapTextures + 64]) >> 4) & 7) != 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x68]) { + __GX_WARN(0x68U); + } + + CheckColor0(); + CheckColor1(); + CheckViewport(); + } +} + +static void CheckWarnings(void) { + if (__gxVerif->verifyLevel >= 1) { + CheckInputForms(); + } + + CheckClean(0x1000U, "Internal error register"); + CheckClean(0x1001U, "Internal diagnostic register"); + CheckClean(0x1002U, "Internal state register 0"); + CheckClean(0x1003U, "Internal state register 1"); + CheckClean(0x1004U, "Power savings register"); + + if (__gxVerif->verifyLevel >= 2) { + CheckFloatingPointRanges(); + } +} + +static void DumpXFRegisters(void) { + static u8 firstTime = 1; +} + +void __GXVerifyXF(void) { + if (internalDebug) { + DumpXFRegisters(); + } + InitializeXFVerifyData(); + CheckErrors(); + CheckWarnings(); + DumpCount++; +} + +#endif diff --git a/src/dolphin/gx/GXVerify.c b/src/dolphin/gx/GXVerify.c new file mode 100644 index 0000000..7f07b8f --- /dev/null +++ b/src/dolphin/gx/GXVerify.c @@ -0,0 +1,368 @@ +#if DEBUG + +#include + +#include "__gx.h" + +static __GXVerifyData __gxVerifData; +struct __GXVerifyData* __gxVerif = &__gxVerifData; + +char* __gxvWarnings[125] = { + "Invalid Vertex Format. Normal count must be set to %s.", + "Texture size %ld not initialized.", + "Left edge of scissor rectangle is less than %d.", + "Top edge of scissor rectangle is less than %d.", + "Right edge of scissor rectangle is greater than %d in %s mode.", + "Bottom edge of scissor rectangle is greater than %d in %s mode.", + "%s value for subsample %d in pixel %ld is not 6 when single-sampling.", + "Indirect texture command for stage %ld is not set.", + "Invalid indirect texture request in TEV stage %ld.", + "Indirect matrix %ld requested in stage %d not set.", + "Requested indirect textures never initialized.", + "Indirect texture coordinate scales %d and %d not set.", + "Invalid texture coordinate specified for indirect stage %d.", + "Indirect texture feedback accumulation is on in TEV stage 0.", + "Indirect bump alpha is enabled in TEV stage 0.", + "Indirect vs. direct mask byte never set.", + "Texture reference never written for TEV stage %ld.", + "Invalid texture coordinate specified for TEV stage %ld.", + "Texture %ld is used as both indirect and direct.", + "Texture %ld not configured.", + "Base pointer for cached texture %ld is not specified.", + "TLUT for indexed texture %ld was never set up.", + "%s is not a power of 2 for mipmapped texture %ld.", + "%s is not GX_CLAMP for non-power-of-2 width in texture %ld.", + "Minification filter for texture %ld is not compatible with color index texture format.", + "Minimum LOD is greater than maximum LOD in texture %ld.", + "Maximum LOD is greater than image's maximum LOD for texture %ld.", + "LOD bias clamp shold be used with edge LOD for texture %ld.", + "Texture %ld does not meet requirements for anisotropic mipmapping.", + "Filters are not linear for field prediction in texture %ld.", + "Incomplete rounding mode configuration for texture %ld.", + "Rounding color indexed texture %ld.", + "Environment for TEV stage %ld not fully set up.", + "Invalid color channel selected in TEV stage %ld.", + "Argument %s selects null texture in TEV color stage %ld.", + "Argument %s selects null texture in TEV alpha stage %ld.", + "Color arg %s in TEV stage %ld accesses register %s, which may be dirty.", + "Alpha arg %s in TEV stage %ld accesses register %s, which may be dirty.", + "Color arg %s in TEV stage %ld accesses register %s, which was last unclamped. Possible wrap-around effect.", + "Alpha arg %s in TEV stage %ld accesses register %s, which was last unclamped. Possible wrap-around effect.", + "Z texturing enabled, but no Z offset specified.", + "Z texturing enabled, but no texture specified for final TEV stage.", + "Final TEV stage doesn't write color to register GX_TEVPREV.", + "Final TEV stage doesn't write alpha to register GX_TEVPREV.", + "Final TEV color stage has no clamping. Possible color wrap-around effect.", + "Final TEV alpha stage has no clamping. Possible alpha wrap-around effect.", + "Z buffering is before texture, but alpha compare operation is active.", + "PE blend and logicop are both on.", + "Selected pixel format does not support dithering.", + "Multisample enabled but pixel type is not RGB565.", + "Pixel type is RGB565 but multisample is not enabled.", + "Multisample locations for pixel %ld are not ordered correctly for antialias filter.", + "Invalid texgen_type %d for texture %d.", + "Register address 0x%04x uninitialized (%s).", + "Register address 0x%04x modified (%s), probably should not be.", + "Invalid combination of %d output color channels and %d color texgen textures.", + "Number of color channels and number of texgens are both zero.", + "Vertex packet does not contain position values.", + "Mismatched argument setting in vertex attribute. %s should be used with %s.", + "GXSetVtxAttrFmt: Normals only support signed types.", + "GXSetVtxAttrFmt: Number of fractional bits is fixed for normals. %s uses %d. Your setting will be ignored.", + "GXSetVtxAttrFmt: GX_F32 type doesn't refer the frac argument. Your setting will be ignored.", + "GXSetVtxAttrFmt: Colors don't refer the frac argument. Your setting will be ignored.", + "Invalid value (%d) for INVERTEXSPEC_REG.host_colors.", + "XF is not expecting host normals but cp is sending them.", + "XF is not expecting host normals, binormals and tangents but cp is sending them.", + "XF is expecting host normals but cp is not sending them.", + "XF is expecting host normals but cp is sending normals, binormals, and tangents.", + "XF is expecting host normals, binormals and tangents but cp is only sending normals.", + "This vertex format (Position + Matrix Indices only) is not supported.", + "VCD for GX_VA_CLR1 is activated though GX_VA_CLR0 is set to GX_NONE. GX_VA_CLR0 should be used first.", + "VCDs for input texture coordinates are not used sequentially from smaller IDs.", + "GX_TEXCOORD%d specifies source row of position, but this is not getting sent.", + "GX_TEXCOORD%d specifies source row of normal, but this is not getting sent.", + "GX_TEXCOORD%d specifies source row of color0, but color0 is not getting sent.", + "GX_TEXCOORD%d specifies source row of color1, but color1 is not getting sent.", + "GX_TEXCOORD%d specifies source row of binormal or tangent, but this is not getting sent.", + "GX_TEXCOORD%d specifies source row of input texture coordinate %d, but this is not getting sent.", + "GX_TEXCOORD%d is specifying an invalid source row of %d.", + "TexCoordGen types are out of order. GX_TG_MTX2x4/3x4 should come first (if any), followed by GX_TG_BUMP (if any), then GX_TG_SRTG (if any).", + "Bumpmap texgen is defined, which requires that binormals and tangents be transformed by a normal matrix, but current matrix index is set to an invalid value (%d) for normal transform.", + "GX_TEXCOORD%d (texgen type bumpmap) is referencing texture %d as a source texture, which is not of texgen type regular.", + "GX_TEXCOORD%d (texgen type bumpmap) using light source %d, but light's %c position is not defined.", + "GX_TEXCOORD%d is defined as texgen type bumpmap, but binormals and tangents are not getting sent.", + "Invalid regular texture number (%d)", + "Top edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", + "Bottom edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", + "Left edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", + "Right edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", + "Channel %s uses specular function (GX_AF_SPEC), but diffuse function is not GX_DF_NONE.", + "Channel %d performs lighting which requires a normal, but this is not getting sent.", + "Channel %d performs lighting which requires the normal to be transformed by a normal matrix, but current matrix index is (%d), which may be invalid.", + "%s has a value of %sinfinity (%08x), which is probably not intended.", + "%s has a value of NaN (%08x), which is probably not intended.", + "%s has a value of (%f 0x%08x), which might be unintentionally small.", + "%s has a value of (%f 0x%08x), which might be unintentionally large.", + "%d regular textures active, but MatrixIndex1 register (0x%04x) uninitialized.", + "gen_mode register not initialized.", + "Number of XF output textures does not match what downstream units are expecting.", + "Number of XF output colors does not match what downstream units are expecting.", + "Number of all texgens (%d) > max allowed %d.", + "Number of regular(2x4/3x4) type texgens (%d) > max allowed %d.", + "Number of bumpmap type texgens (%d) > max allowed %d.", + "Number of color texgens (%d) > max allowed %d.", + "First color texgen is not referencing COLOR0.", + "Color texgen from COLOR%d is used more than once.", + "Bumpmap texgen is defined, which requires the normal matrix values pointed by current matrix index (%d) to be loaded, however it may not be loaded yet.", + "GX_TEXCOORD%d requires the matrix values pointed by current texture matrix index %d (%d), however it may not be loaded yet.", + "GX_LIGHT%d is being referenced, however it may not be loaded yet.", + "Channel %d performs lighting which requires the normal matrix values pointed to by the current matrix index (%d), however these values may not be loaded yet.", + "Position matrix values pointed to by the current matrix index must be loaded, however they may not be loaded yet.", + "Address 0x%04x is uninitialized.", + "Register (0x%04x) (%s) is not initialized.", + "Display list contains invalid command.", + "Nested display list.", + "XF is not expecting host colors but cp is sending some.", + "XF is expecting a host color but cp is not sending one.", + "XF is expecting a single host color but cp is sending two.", + "XF is expecting two host colors but cp is not sending first color.", + "XF is expecting two host colors but cp is not sending second color.", + "Invalid number of output colors, %d.", + "Regular texture %d specifying a source row of %d which only has 2 elements, but an input form of ABC1.", + "Output XF colors or color textures enabled, but register address 0x%04x uninitialized (%s).", + "Output XF colors or color textures enabled, COLOR%dCNTRL_REG.material_src == REGISTER, but Material %d register (0x%04x) is not initialized.", + "Output XF colors or color textures enabled, COLOR%dCNTRL_REG.ambient_src == REGISTER, but Ambient %d register (0x%04x) is not initialized." +}; + +GXWarningLevel __gxvWarnLev[125] = { + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_ALL, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_ALL, + GX_WARN_ALL, + 4, + GX_WARN_SEVERE, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_ALL, + GX_WARN_ALL, + GX_WARN_MEDIUM, + 4, + 4, + 4, + 4, + GX_WARN_ALL, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_ALL, + GX_WARN_ALL, + GX_WARN_ALL, + 4, + 4, + 4, + 4, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_ALL, + GX_WARN_ALL, + GX_WARN_SEVERE, + 4, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, +}; + +char __gxvDummyStr[256]; + +static void __GXVerifyGlobal(void) {} + +static void __GXVerifyCP(GXVtxFmt fmt) { + u32 nrmCnt = GET_REG_FIELD(__GXData->vatA[fmt], 1, 9); + + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if (__GXData->hasNrms && nrmCnt != 0) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_INVALID_VTX_FMT]) { + __GX_WARNF(GXWARN_INVALID_VTX_FMT, "GX_NRM_XYZ"); + } + } + else if (__GXData->hasBiNrms && nrmCnt != 1) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_INVALID_VTX_FMT]) { + __GX_WARNF(GXWARN_INVALID_VTX_FMT, "GX_NRM_NBT or GX_NRM_NBT3"); + } + } + } +} + +void __GXVerifyState(GXVtxFmt vtxfmt) { + if (__gxVerif->verifyLevel != GX_WARN_NONE) { + __GXVerifyGlobal(); + __GXVerifyCP(vtxfmt); + __GXVerifyXF(); + __GXVerifySU(); + __GXVerifyBUMP(); + __GXVerifyTEX(); + __GXVerifyTEV(); + __GXVerifyPE(); + } +} + +void __GXVerifyVATImm(GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac) { + if (__gxVerif->verifyLevel != GX_WARN_NONE) { + if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) { + switch (type) { + case GX_RGB565: + case GX_RGB8: + case GX_RGBX8: + if (cnt != GX_CLR_RGB && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_MISMATCH]) { + __GX_WARNF(GXWARN_VAT_MISMATCH, "RGB format type", "GX_CLR_RGB"); + } + break; + case GX_RGBA4: + case GX_RGBA6: + case GX_RGBA8: + if (cnt != GX_CLR_RGBA && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_MISMATCH]) { + __GX_WARNF(GXWARN_VAT_MISMATCH, "RGBA format type", "GX_CLR_RGBA"); + } + break; + } + } + + if (frac != 0) { + if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_CLR_FRAC]) { + __GX_WARN(GXWARN_VAT_CLR_FRAC); + } + } else if (type == GX_F32) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_F32_FRAC]) { + __GX_WARN(GXWARN_VAT_F32_FRAC); + } + } + } + + if (attr == GX_VA_NRM || attr == GX_VA_NBT) { + switch (type) { + case GX_S8: + if (frac != 6 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_FRAC]) { + __GX_WARNF(GXWARN_VAT_NRM_FRAC, "GX_S8", 6); + } + break; + case GX_S16: + if (frac != 14 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_FRAC]) { + __GX_WARNF(GXWARN_VAT_NRM_FRAC, "GX_S16", 14); + } + break; + case GX_F32: + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_TYPE]) { + __GX_WARN(GXWARN_VAT_NRM_TYPE); + } + break; + } + } + } +} + +void GXSetVerifyLevel(GXWarningLevel level) { + __gxVerif->verifyLevel = level; +} + +GXVerifyCallback GXSetVerifyCallback(GXVerifyCallback cb) { + GXVerifyCallback old_cb = __gxVerif->cb; + + __gxVerif->cb = cb; + return old_cb; +} + +#endif // DEBUG diff --git a/src/dolphin/gx/GXVert.c b/src/dolphin/gx/GXVert.c new file mode 100644 index 0000000..df50141 --- /dev/null +++ b/src/dolphin/gx/GXVert.c @@ -0,0 +1,86 @@ +#if DEBUG +#include + +#include "__gx.h" + +#define FUNC_1PARAM(name, T) \ +void name##1##T(T x) { GXWGFifo.T = x; } + +#define FUNC_2PARAM(name, T) \ +void name##2##T(T x, T y) { GXWGFifo.T = x; GXWGFifo.T = y; } + +#define FUNC_3PARAM(name, T) \ +void name##3##T(T x, T y, T z) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; } + +#define FUNC_4PARAM(name, T) \ +void name##4##T(T x, T y, T z, T w) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; GXWGFifo.T = w; } + +#define FUNC_INDEX8(name) \ +void name##1x8(u8 x) { GXWGFifo.u8 = x; } + +#define FUNC_INDEX16(name) \ +void name##1x16(u16 x) { GXWGFifo.u16 = x; } + +// GXCmd +FUNC_1PARAM(GXCmd, u8) +FUNC_1PARAM(GXCmd, u16) +FUNC_1PARAM(GXCmd, u32) + +// GXParam +FUNC_1PARAM(GXParam, u8) +FUNC_1PARAM(GXParam, u16) +FUNC_1PARAM(GXParam, u32) +FUNC_1PARAM(GXParam, s8) +FUNC_1PARAM(GXParam, s16) +FUNC_1PARAM(GXParam, s32) +FUNC_1PARAM(GXParam, f32) +FUNC_3PARAM(GXParam, f32) +FUNC_4PARAM(GXParam, f32) + +// GXPosition +FUNC_3PARAM(GXPosition, f32) +FUNC_3PARAM(GXPosition, u8) +FUNC_3PARAM(GXPosition, s8) +FUNC_3PARAM(GXPosition, u16) +FUNC_3PARAM(GXPosition, s16) +FUNC_2PARAM(GXPosition, f32) +FUNC_2PARAM(GXPosition, u8) +FUNC_2PARAM(GXPosition, s8) +FUNC_2PARAM(GXPosition, u16) +FUNC_2PARAM(GXPosition, s16) +FUNC_INDEX16(GXPosition) +FUNC_INDEX8(GXPosition) + +// GXNormal +FUNC_3PARAM(GXNormal, f32) +FUNC_3PARAM(GXNormal, s16) +FUNC_3PARAM(GXNormal, s8) +FUNC_INDEX16(GXNormal) +FUNC_INDEX8(GXNormal) + +// GXColor +FUNC_4PARAM(GXColor, u8) +FUNC_1PARAM(GXColor, u32) +FUNC_3PARAM(GXColor, u8) +FUNC_1PARAM(GXColor, u16) +FUNC_INDEX16(GXColor) +FUNC_INDEX8(GXColor) + +// GXTexCoord +FUNC_2PARAM(GXTexCoord, f32) +FUNC_2PARAM(GXTexCoord, s16) +FUNC_2PARAM(GXTexCoord, u16) +FUNC_2PARAM(GXTexCoord, s8) +FUNC_2PARAM(GXTexCoord, u8) +FUNC_1PARAM(GXTexCoord, f32) +FUNC_1PARAM(GXTexCoord, s16) +FUNC_1PARAM(GXTexCoord, u16) +FUNC_1PARAM(GXTexCoord, s8) +FUNC_1PARAM(GXTexCoord, u8) +FUNC_INDEX16(GXTexCoord) +FUNC_INDEX8(GXTexCoord) + +// GXMatrixIndex +FUNC_1PARAM(GXMatrixIndex, u8) + +#endif // DEBUG diff --git a/src/dolphin/gx/__gx.h b/src/dolphin/gx/__gx.h new file mode 100644 index 0000000..1e065bb --- /dev/null +++ b/src/dolphin/gx/__gx.h @@ -0,0 +1,592 @@ +#ifndef _DOLPHIN_GX_INTERNAL_H_ +#define _DOLPHIN_GX_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// FIFO WRITE + +#define GX_WRITE_U8(ub) \ + GXWGFifo.u8 = (u8)(ub) + +#define GX_WRITE_U16(us) \ + GXWGFifo.u16 = (u16)(us) + +#define GX_WRITE_U32(ui) \ + GXWGFifo.u32 = (u32)(ui) + +#define GX_WRITE_F32(f) \ + GXWGFifo.f32 = (f32)(f); + + +// REG VERIF + +#if DEBUG +#define VERIF_XF_REG(addr, value) \ +do { \ + s32 regAddr = (addr); \ + if (regAddr >= 0 && regAddr < 0x50) { \ + __gxVerif->xfRegs[regAddr] = (value); \ + __gxVerif->xfRegsDirty[regAddr] = 1; \ + } \ +} while (0) + +#define VERIF_XF_REG_alt(addr, value) \ +do { \ + s32 xfAddr = (addr); \ + if (xfAddr >= 0 && xfAddr < 0x50) { \ + __gxVerif->xfRegs[xfAddr] = (value); \ + __gxVerif->xfRegsDirty[xfAddr] = 1; \ + } \ +} while (0) + +#define VERIF_RAS_REG(value) (__gxVerif->rasRegs[((value) & 0xFF000000) >> 24] = value) + +#define VERIF_MTXLIGHT(addr, data) \ +do { \ + s32 xfAddr; \ + if (addr < 0x400U) { \ + __gxVerif->xfMtx[addr] = data; \ + __gxVerif->xfMtxDirty[addr] = 1; \ + } else if (addr < 0x500U) { \ + xfAddr = addr - 0x400; \ + __gxVerif->xfNrm[xfAddr] = data; \ + __gxVerif->xfNrmDirty[xfAddr] = 1; \ + } else if (addr < 0x600U) { \ + xfAddr = addr - 0x500; \ + __gxVerif->xfDMtx[xfAddr] = data; \ + __gxVerif->xfDMtxDirty[xfAddr] = 1; \ + } else if (addr < 0x680U) { \ + xfAddr = addr - 0x600; \ + __gxVerif->xfLight[xfAddr] = data; \ + __gxVerif->xfLightDirty[xfAddr] = 1; \ + } else { \ + xfAddr = addr - 0x1000; \ + if ((xfAddr >= 0) && (xfAddr < 0x50)) { \ + __gxVerif->xfRegs[xfAddr] = data; \ + __gxVerif->xfRegsDirty[xfAddr] = 1; \ + } \ + } \ +} while (0) +#else +#define VERIF_XF_REG(addr, value) ((void)0) +#define VERIF_XF_REG_alt(addr, value) ((void)0) +#define VERIF_RAS_REG(value) ((void)0) +#endif + +// WRITE REG + +#define GX_WRITE_XF_REG(addr, value) \ +do { \ + GX_WRITE_U8(0x10); \ + GX_WRITE_U32(0x1000 + (addr)); \ + GX_WRITE_U32(value); \ + VERIF_XF_REG(addr, value); \ +} while (0) + +#if DEBUG +#define GX_WRITE_XF_REG_2(addr, value) \ +do { \ + u32 xfData = (value); &xfData; \ + GX_WRITE_U32(value); \ + VERIF_XF_REG_alt(addr, xfData); \ +} while (0) + +#define GX_WRITE_XF_REG_F(addr, value) \ +do { \ + f32 xfData = (value); \ + GX_WRITE_F32(value); \ + VERIF_XF_REG_alt(addr, *(u32 *)&xfData); \ +} while (0) +#else +#define GX_WRITE_XF_REG_2(addr, value) \ +do { \ + GX_WRITE_U32(value); \ +} while (0) + +#define GX_WRITE_XF_REG_F(addr, value) \ +do { \ + GX_WRITE_F32(value); \ +} while (0) +#endif + +#define GX_WRITE_RAS_REG(value) \ +do { \ + GX_WRITE_U8(0x61); \ + GX_WRITE_U32(value); \ + VERIF_RAS_REG(value); \ +} while (0) + +#ifdef DEBUG +#define GX_WRITE_SOME_REG2(a, b, c, addr) \ +do { \ + long regAddr; \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ + regAddr = addr; \ + if (regAddr >= 0 && regAddr < 4) { \ + __GXData->indexBase[regAddr] = c; \ + } \ +} while (0) +#else +#define GX_WRITE_SOME_REG2(a, b, c, addr) \ +do { \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ +} while (0) +#endif + +#ifdef DEBUG +#define GX_WRITE_SOME_REG3(a, b, c, addr) \ +do { \ + long regAddr; \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ + regAddr = addr; \ + if (regAddr >= 0 && regAddr < 4) { \ + __GXData->indexStride[regAddr] = c; \ + } \ +} while (0) +#else +#define GX_WRITE_SOME_REG3(a, b, c, addr) \ +do { \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ +} while (0) +#endif + +#define GX_WRITE_SOME_REG4(a, b, c, addr) \ +do { \ + long regAddr; \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ + regAddr = addr; \ +} while (0) + +// REG MACROS + +#define GET_REG_FIELD(reg, size, shift) ((int)((reg) >> (shift)) & ((1 << (size)) - 1)) + +// TODO: reconcile reg macro differences +// this one is needed to match non GX libs +#define OLD_SET_REG_FIELD(line, reg, size, shift, val) \ +do { \ + ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \ + (reg) = ((u32)(reg) & ~(((1 << (size)) - 1) << (shift))) | ((u32)(val) << (shift)); \ +} while (0) + +// above doesn't seem to work with GX, only can get it to work with this +#define SET_REG_FIELD(line, reg, size, shift, val) \ +do { \ + ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \ + (reg) = ((u32)__rlwimi((u32)(reg), (val), (shift), 32 - (shift) - (size), 31 - (shift))); \ +} while (0) + +#define CHECK_GXBEGIN(line, name) ASSERTMSGLINE(line, !__GXinBegin, "'" name "' is not allowed between GXBegin/GXEnd") + +/* GXAttr */ +void __GXSetVCD(void); +void __GXSetVAT(void); + +/* GXBump */ +void __GXUpdateBPMask(void); +void __GXFlushTextureState(void); + +/* GXFifo */ +// GXFifoObj private data +typedef struct __GXFifoObj { + u8* base; + u8* top; + u32 size; + u32 hiWatermark; + u32 loWatermark; + void* rdPtr; + void* wrPtr; + s32 count; + u8 bind_cpu; + u8 bind_gp; +} __GXFifoObj; + +void __GXSaveCPUFifoAux(__GXFifoObj* realFifo); +void __GXFifoInit(void); +void __GXInsaneWatermark(void); +void __GXCleanGPFifo(void); + +/* GXGeometry */ +void __GXSetDirtyState(void); +void __GXSendFlushPrim(void); +void __GXSetGenMode(void); + +/* GXInit */ +void __GXInitGX(); +void __GXInitRevisionBits(void); + +typedef struct __GXData_struct { + u16 vNumNot; + u16 bpSentNot; + u16 vNum; + u16 vLim; + u32 cpEnable; + u32 cpStatus; + u32 cpClr; + u32 vcdLo; + u32 vcdHi; + u32 vatA[8]; + u32 vatB[8]; + u32 vatC[8]; + u32 lpSize; + u32 matIdxA; + u32 matIdxB; + u32 indexBase[4]; + u32 indexStride[4]; + u32 ambColor[2]; + u32 matColor[2]; + u32 suTs0[8]; + u32 suTs1[8]; + u32 suScis0; + u32 suScis1; + u32 tref[8]; + u32 iref; + u32 bpMask; + u32 IndTexScale0; + u32 IndTexScale1; + u32 tevc[16]; + u32 teva[16]; + u32 tevKsel[8]; + u32 cmode0; + u32 cmode1; + u32 zmode; + u32 peCtrl; + u32 cpDispSrc; + u32 cpDispSize; + u32 cpDispStride; + u32 cpDisp; + u32 cpTexSrc; + u32 cpTexSize; + u32 cpTexStride; + u32 cpTex; + u8 cpTexZ; + u32 genMode; + GXTexRegion TexRegions0[8]; + GXTexRegion TexRegions1[8]; + GXTexRegion TexRegions2[8]; + GXTlutRegion TlutRegions[20]; + GXTexRegion* (*texRegionCallback)(GXTexObj*, GXTexMapID); + GXTlutRegion* (*tlutRegionCallback)(u32); + GXAttrType nrmType; + u8 hasNrms; + u8 hasBiNrms; + u32 projType; + f32 projMtx[6]; + f32 vpLeft; + f32 vpTop; + f32 vpWd; + f32 vpHt; + f32 vpNearz; + f32 vpFarz; + f32 zOffset; + f32 zScale; + u32 tImage0[8]; + u32 tMode0[8]; + u32 texmapId[16]; + u32 tcsManEnab; + u32 tevTcEnab; + GXPerf0 perf0; + GXPerf1 perf1; + u32 perfSel; + u8 inDispList; + u8 dlSaveContext; + u8 abtWaitPECopy; + u8 dirtyVAT; + u32 dirtyState; +} GXData; + +extern GXData* const __GXData; +extern void* __memReg; +extern void* __peReg; +extern void* __cpReg; +extern void* __piReg; + +#if DEBUG +extern GXBool __GXinBegin; +#endif + +#define GX_GET_MEM_REG(offset) (*(volatile u16*)((volatile u16*)(__memReg) + (offset))) +#define GX_GET_CP_REG(offset) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset))) +#define GX_GET_PE_REG(offset) (*(volatile u16*)((volatile u16*)(__peReg) + (offset))) +#define GX_GET_PI_REG(offset) (*(volatile u32*)((volatile u32*)(__piReg) + (offset))) + +#define GX_SET_MEM_REG(offset, val) (*(volatile u16*)((volatile u16*)(__memReg) + (offset)) = val) +#define GX_SET_CP_REG(offset, val) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset)) = val) +#define GX_SET_PE_REG(offset, val) (*(volatile u16*)((volatile u16*)(__peReg) + (offset)) = val) +#define GX_SET_PI_REG(offset, val) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)) = val) + +/* GXMisc */ +void __GXBypass(u32 reg); +u16 __GXReadPEReg(u32 reg); +void __GXPEInit(void); +void __GXAbort(); + +/* GXPerf */ +void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial); + +static inline u32 __GXReadCPCounterU32(u32 regAddrL, u32 regAddrH) { + u32 ctrH0; + u32 ctrH1; + u32 ctrL; + + ctrH0 = GX_GET_CP_REG(regAddrH); + + do { + ctrH1 = ctrH0; + ctrL = GX_GET_CP_REG(regAddrL); + ctrH0 = GX_GET_CP_REG(regAddrH); + } while (ctrH0 != ctrH1); + + return (ctrH0 << 0x10) | ctrL; +} + +static inline u32 __GXReadMEMCounterU32(u32 regAddrL, u32 regAddrH) { + u32 ctrH0; + u32 ctrH1; + u32 ctrL; + + ctrH0 = GX_GET_MEM_REG(regAddrH); + + do { + ctrH1 = ctrH0; + ctrL = GX_GET_MEM_REG(regAddrL); + ctrH0 = GX_GET_MEM_REG(regAddrH); + } while (ctrH0 != ctrH1); + + return (ctrH0 << 0x10) | ctrL; +} + +static inline u32 __GXReadPECounterU32(u32 regAddrL, u32 regAddrH) { + u32 ctrH0; + u32 ctrH1; + u32 ctrL; + + ctrH0 = GX_GET_PE_REG(regAddrH); + + do { + ctrH1 = ctrH0; + ctrL = GX_GET_PE_REG(regAddrL); + ctrH0 = GX_GET_PE_REG(regAddrH); + } while (ctrH0 != ctrH1); + + return (ctrH0 << 0x10) | ctrL; +} + +/* GXSave */ +void __GXShadowDispList(void* list, u32 nbytes); +void __GXShadowIndexState(u32 idx_reg, u32 reg_data); +void __GXPrintShadowState(void); + +/* GXStubs */ +void __GXSetRange(f32 nearz, f32 fgSideX); + +/* GXTexture */ +void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32* rowTiles, u32* colTiles, u32* cmpTiles); +void __GXSetSUTexRegs(void); +void __GXGetSUTexSize(GXTexCoordID coord, u16* width, u16* height); +void __GXSetTmemConfig(u32 config); + +/* GXTransform */ +void __GXSetMatrixIndex(GXAttr matIdxAttr); +void __GXSetProjection(void); +void __GXSetViewport(); + + +/* GXVerifRAS */ +void __GXVerifySU(void); +void __GXVerifyBUMP(void); +void __GXVerifyTEX(void); +void __GXVerifyTEV(void); +void __GXVerifyPE(void); + +/* GXVerif */ +typedef enum { + GXWARN_INVALID_VTX_FMT = 0, + GXWARN_TEX_SIZE_INIT = 1, + GXWARN_SCISSOR_RECT_LEFT = 2, + GXWARN_SCISSOR_RECT_TOP = 3, + GXWARN_SCISSOR_RECT_RIGHT = 4, + GXWARN_SCISSOR_RECT_BOT = 5, + GXWARN_SAMPLE_VALUE = 6, + GXWARN_BUMP_CMD = 7, + GXWARN_INVALID_INDIRECT = 8, + GXWARN_INDIRECT_MTX = 9, + GXWARN_IND_TEX_NO_INIT = 10, + GXWARN_IND_TEX_NO_SCALE = 11, + GXWARN_IND_TEX_BUMP = 12, + GXWARN_BUMP_ACCUMULATION = 13, + GXWARN_BUMP_ALPHA_EN = 14, + GXWARN_IND_DIR_MASK = 15, + GXWARN_TEV_TEX_REF = 16, + GXWARN_TEV_INV_TEX_COORD = 17, + GXWARN_IND_DIR_BOTH = 18, + GXWARN_TEX_CONFIG = 19, + GXWARN_TEX_BASE = 20, + GXWARN_TLUT_CONFIG = 21, + GXWARN_TEX_POW2 = 22, + GXWARN_TEX_CLAMP = 23, + GXWARN_TEX_MIN_FILT = 24, + GXWARN_MIN_LOD = 25, + GXWARN_MAX_LOD = 26, + GXWARN_DIAG_LOD = 27, + GXWARN_TEX_ANISO = 28, + GXWARN_TEX_FIELD = 29, + GXWARN_TEX_RND_FP = 30, + GXWARN_RND_CLR_INDX = 31, + GXWARN_TEV_ENV = 32, + GXWARN_TEV_INV_CHAN = 33, + GXWARN_TEV_NULL_TEX = 34, + GXWARN_TEV_NULL_TEX_A = 35, + GXWARN_TEV_DIRTY_REG = 36, + GXWARN_TEV_DIRTY_REG_A = 37, + GXWARN_TEV_CLR_CLAMP = 38, + GXWARN_TEV_A_CLAMP = 39, + GXWARN_ZTEX_OFFSET = 40, + GXWARN_ZTEX_INVALID = 41, + GXWARN_TEV_LAST_CLR = 42, + GXWARN_TEV_LAST_A = 43, + GXWARN_TEV_LAST_CLR_WRAP = 44, + GXWARN_TEV_LAST_A_WRAP = 45, + GXWARN_Z_BEFORE_T_A = 46, + GXWARN_BLEND_LOGICOP = 47, + GXWARN_DITHER_MODE = 48, + GXWARN_MULTISAMP0 = 49, + GXWARN_MULTISAMP1 = 50, + GXWARN_SAMP_ORDER = 51, + GXWARN_INVALID_TG_TYPE = 52, + GXWARN_XF_CTRL_UNINIT = 53, + GXWARN_XF_CTRL_INIT = 54, + GXWARN_INV_COLOR_TG_COMB = 55, + GXWARN_XF_NO_CLR_TEX = 56, + GXWARN_VTX_NO_GEOM = 57, + GXWARN_VAT_MISMATCH = 58, + GXWARN_VAT_NRM_TYPE = 59, + GXWARN_VAT_NRM_FRAC = 60, + GXWARN_VAT_F32_FRAC = 61, + GXWARN_VAT_CLR_FRAC = 62, + GXWARN_INV_IVS_CLR = 63, + GXWARN_NRM_XF0_CP1 = 64, + GXWARN_NRM_XF0_CP3 = 65, + GXWARN_NRM_XF1_CP0 = 66, + GXWARN_NRM_XF1_CP3 = 67, + GXWARN_NRM_XF3_CP1 = 68, + GXWARN_VCD_FMT_UNSUP = 69, + GXWARN_VCD_CLR_ORDER = 70, + GXWARN_VCD_TEX_ORDER = 71, + GXWARN_TEX_SRC_NPOS = 72, + GXWARN_TEX_SRC_NNRM = 73, + GXWARN_TEX_SRC_NCLR0 = 74, + GXWARN_TEX_SRC_NCLR1 = 75, + GXWARN_TEX_SRC_NNBT = 76, + GXWARN_TEX_SRC_NTEX = 77, + GXWARN_INV_TEX_SRC = 78, + GXWARN_INV_TG_ORDER = 79, + GXWARN_BM_INV_MTX_NDX = 80, + GXWARN_BM_INV_TEX = 81, + GXWARN_BM_INV_LIT_POS = 82, + GXWARN_BM_NO_NBT = 83, + GXWARN_INV_TEX_NUM = 84, + GXWARN_VIEWPORT_TOP = 85, + GXWARN_VIEWPORT_BOTTOM = 86, + GXWARN_VIEWPORT_LEFT = 87, + GXWARN_VIEWPORT_RIGHT = 88, + GXWARN_CLR_INV_SPEC = 89, + GXWARN_CLR_NO_NRM = 90, + GXWARN_CLR_INV_MTX_NDX = 91, + GXWARN_VAL_INFINITY = 92, + GXWARN_VAL_NAN = 93, + GXWARN_VAL_SMALL = 94, + GXWARN_VAL_LARGE = 95, + GXWARN_MTX1_UNINIT = 96, + GXWARN_GM_UNINIT = 97, + GXWARN_TEX_XFN_SUM = 98, + GXWARN_CLR_XFN_SUM = 99, + GXWARN_INV_NUM_ANY_TEX = 100, + GXWARN_INV_NUM_REG_TEX = 101, + GXWARN_INV_NUM_BM_TEX = 102, + GXWARN_INV_NUM_CLR_TEX = 103, + GXWARN_INV_CLR_TEX = 104, + GXWARN_DUP_CLR_TEX = 105, + GXWARN_BM_INV_MTX_VAL = 106, + GXWARN_TEX_INV_MTX_VAL = 107, + GXWARN_LIT_INV_REG = 108, + GXWARN_CLR_INV_MTX_VAL = 109, + GXWARN_INV_MTX_VAL = 110, + GXWARN_ADDR_UNINIT = 111, + GXWARN_REG_UNINIT = 112, + GXWARN_DL_INV_CMD = 113, + GXWARN_DL_NESTED = 114, + GXWARN_CLR_XF0_CP1 = 115, + GXWARN_CLR_XF1_CP0 = 116, + GXWARN_CLR_XF1_CP2 = 117, + GXWARN_CLR_XF2_CPN1 = 118, + GXWARN_CLR_XF2_CPN2 = 119, + GXWARN_INV_NUM_COLORS = 120, + GXWARN_INV_TG_SRC = 121, + GXWARN_CLR_ADDR_UNINIT = 122, + GXWARN_CLR_MAT_UNINIT = 123, + GXWARN_CLR_AMB_UNINIT = 124, + GXWARN_MAX = 125, +} GXWarnID; + +#define __GX_WARN(id) (__gxVerif->cb(__gxvWarnLev[(id)], (id), __gxvWarnings[(id)])) +#define __GX_WARNF(id, ...) \ +do { \ + sprintf(__gxvDummyStr, __gxvWarnings[(id)], __VA_ARGS__); \ + __gxVerif->cb(__gxvWarnLev[(id)], (id), __gxvDummyStr); \ +} while (0) + +#define __GX_WARN2(level, id) (__gxVerif->cb(level, (id), __gxvWarnings[(id)])) +#define __GX_WARN2F(level, id, ...) \ +do { \ + sprintf(__gxvDummyStr, __gxvWarnings[(id)], __VA_ARGS__); \ + __gxVerif->cb(level, (id), __gxvDummyStr); \ +} while (0) + +typedef struct __GXVerifyData { + GXVerifyCallback cb; + GXWarningLevel verifyLevel; + u32 xfRegs[80]; + u32 xfMtx[256]; + u32 xfNrm[96]; + u32 xfDMtx[256]; + u32 xfLight[128]; + u32 rasRegs[256]; + u8 xfRegsDirty[80]; + u8 xfMtxDirty[256]; + u8 xfNrmDirty[96]; + u8 xfDMtxDirty[256]; + u8 xfLightDirty[128]; +} __GXVerifyData; + +extern __GXVerifyData* __gxVerif; +extern char* __gxvWarnings[125]; +extern char __gxvDummyStr[256]; +extern GXWarningLevel __gxvWarnLev[]; + +void __GXVerifyGlobal(void); +void __GXVerifyCP(GXVtxFmt fmt); +void __GXVerifyState(GXVtxFmt vtxfmt); + +/* GXVerifXF */ +void __GXVerifyXF(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/hio/hio.c b/src/dolphin/hio/hio.c new file mode 100644 index 0000000..aa146d5 --- /dev/null +++ b/src/dolphin/hio/hio.c @@ -0,0 +1,409 @@ +#include +#include +#include +#include + +static u32 Dev; +#define HIO_DEV Dev + +#ifdef DEBUG +const char* __HIOVersion = "<< Dolphin SDK - HIO\tdebug build: Apr 5 2004 03:57:05 (0x2301) >>"; +#else +const char* __HIOVersion = "<< Dolphin SDK - HIO\trelease build: Apr 5 2004 04:15:47 (0x2301) >>"; +#endif + +static char __HIODigest1[71] = "\"HIO library - Copyright (C) 2000-2002 Nintendo. All rights reserved.\""; + +#ifdef DEBUG +static char __HIODigest2[34] = "\"HIO built: Apr 5 2004 03:57:05\""; +#else +static char __HIODigest2[34] = "\"HIO built: Apr 5 2004 04:15:47\""; +#endif + +static s32 Chan = -1; +static HIOCallback ExiCallback; +static HIOCallback TxCallback; +static HIOCallback RxCallback; + +static void ExtHandler(s32 chan, OSContext *context) { + Chan = -1; + HIO_DEV = 0; + + if (chan < 2 && HIO_DEV == 0) { + EXISetExiCallback(chan, NULL); + } else if (chan == 0 && HIO_DEV == 2) { + EXISetExiCallback(2, NULL); + } +} + +static void ExiHandler(s32 chan, OSContext* context) { + if (ExiCallback) { + ExiCallback(); + } +} + +static void DbgHandler(__OSInterrupt interrupt, OSContext *context) { + OSContext exceptionContext; + + __PIRegs[0] = 0x1000; + if (ExiCallback) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + ExiCallback(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +static void TxHandler(s32 chan, OSContext* context) { + EXIDeselect(Chan); + EXIUnlock(Chan); + if (TxCallback) { + TxCallback(); + } +} + +static void RxHandler(s32 chan, OSContext* context) { + EXIDeselect(Chan); + EXIUnlock(Chan); + if (RxCallback) { + RxCallback(); + } +} + +BOOL HIOEnumDevices(HIOEnumCallback callback) { + s32 chan; + u32 id; + + if (Chan != -1 || callback == NULL) { + return 0; + } + + HIO_DEV = 0; + for (chan = 0; chan <= 2; chan++) { + if (chan < 2) { + while (EXIProbeEx(chan) == 0) {} + } + + if (EXIGetID(chan, HIO_DEV, &id) != 0 && id - 0x1010000 == 0 && !callback(chan)) { + return 1; + } + } + + return 1; +} + +static inline int CheckConsoleType() { + if (__OSGetDIConfig() == 0xFF) { + if (((OSGetConsoleType() & 0xF0000000) + 0xE0000000) == 0) { + return 1; + } + + switch (__OSDeviceCode) { + case 0x8200: + return 1; + } + + return 0; + } + + return 1; +} + +BOOL HIOInit(s32 chan, HIOCallback callback) { + int err; + u32 cmd; + u32 id; + + while (__OSDeviceCode == 0) {} + + if (CheckConsoleType() == 0) { + Chan = -1; + HIO_DEV = 0; + OSReport("%s\n", __HIODigest1, __HIODigest2); + return 0; + } + + if (Chan != -1) { + return 1; + } + + Chan = chan; + ExiCallback = callback; + TxCallback = NULL; + RxCallback = NULL; + + if (chan < 2 && HIO_DEV == 0) { + while (EXIProbeEx(Chan) == 0) {} + + if (EXIAttach(Chan, ExtHandler) == 0) { + Chan = -1; + HIO_DEV = 0; + return 0; + } + } + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + EXIDetach(Chan); + Chan = -1; + HIO_DEV = 0; + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 0) == 0) { + EXIUnlock(Chan); + EXIDetach(Chan); + Chan = -1; + HIO_DEV = 0; + return 0; + } + + cmd = 0; + err = 0; + err |= !EXIImm(Chan, &cmd, 2, 1, 0); + err |= !EXISync(Chan); + err |= !EXIImm(Chan, &id, 4, 0, 0); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + + if (err != 0 || id != 0x1010000) { + if (chan < 2 && HIO_DEV == 0) { + EXIDetach(Chan); + } + EXIUnlock(Chan); + Chan = -1; + HIO_DEV = 0; + return 0; + } + + if (ExiCallback) { + if (chan < 2) { + if (HIO_DEV == 0) { + EXISetExiCallback(Chan, ExiHandler); + } else { + ASSERTLINE(331, HIO_DEV == 2); + EXISetExiCallback(2, ExiHandler); + } + } else { + __OSSetInterruptHandler(0x19, DbgHandler); + __OSUnmaskInterrupts(0x40); + } + } + + OSRegisterVersion(__HIOVersion); + return 1; +} + +BOOL HIOInitEx(s32 chan, u32 dev, HIOCallback callback) { + ASSERTLINE(348, dev == 0 || chan == 0 && dev == 2); + + if (dev != 0 && (chan != 0 || dev != 2)) { + return 0; + } + + if (Chan != -1) { + return 1; + } + + HIO_DEV = dev; + return HIOInit(chan, callback); +} + +BOOL HIOReadMailbox(u32* word) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = 0x60000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 2, 1, 0); + err |= !EXISync(Chan); + err |= !EXIImm(Chan, word, 4, 0, 0); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} + +BOOL HIOWriteMailbox(u32 word) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = (word & 0x1FFFFFFF) | 0xC0000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} + +BOOL HIORead(u32 addr, void* buffer, s32 size) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + ASSERTLINE(436, (addr % 4) == 0); + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = ((addr << 8) & 0x01FFFC00) | 0x20000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDma(Chan, buffer, size, 0, NULL); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} + +BOOL HIOWrite(u32 addr, void* buffer, s32 size) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + ASSERTLINE(470, (addr % 4) == 0); + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = ((addr << 8) & 0x01FFFC00) | 0xA0000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDma(Chan, buffer, size, 1, NULL); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} + +BOOL HIOReadAsync(u32 addr, void* buffer, s32 size, HIOCallback callback) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + ASSERTLINE(504, (addr % 4) == 0); + RxCallback = callback; + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = ((addr << 8) & 0x01FFFC00) | 0x20000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDma(Chan, buffer, size, 0, RxHandler); + return !err; +} + +BOOL HIOWriteAsync(u32 addr, void* buffer, s32 size, HIOCallback callback) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + ASSERTLINE(537, (addr % 4) == 0); + TxCallback = callback; + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = ((addr << 8) & 0x01FFFC00) | 0xA0000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDma(Chan, buffer, size, 1, TxHandler); + return !err; +} + +BOOL HIOReadStatus(u32* status) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = 0x40000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 2, 1, 0); + err |= !EXISync(Chan); + err |= !EXIImm(Chan, status, 4, 0, 0); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} diff --git a/src/dolphin/mcc/fio.c b/src/dolphin/mcc/fio.c new file mode 100644 index 0000000..dca9488 --- /dev/null +++ b/src/dolphin/mcc/fio.c @@ -0,0 +1,1290 @@ +#include +#include + +#ifdef DEBUG +const char* __FIOVersion = "<< Dolphin SDK - FIO\tdebug build: Apr 5 2004 03:57:07 (0x2301) >>"; +#else +const char* __FIOVersion = "<< Dolphin SDK - FIO\trelease build: Apr 5 2004 04:15:50 (0x2301) >>"; +#endif + +static u8 gBuf[0x2000]; +static u8 gPrintBuf[0x400]; + +static u8 gmSizeOfBlocks = 1; +static u8 gSizeOfBlocks = 1; +volatile static BOOL gProcDone = TRUE; + +static MCC_CHANNEL gmChID; +static MCC_CHANNEL gChID; +static int gQuery; +volatile static int gProcBusy; +volatile static u32 gStreamReady; +static u8 gLastErr; +static BOOL bAsyncIsRead; +static FIO_ASYNC_STATE bAsyncBusy; +static void* bAsyncBuffer; +static u32 gAsyncDataSize; +static u32 gRequestSequenceNumber; + +// prototypes +static BOOL fioIsInitialized(void); +static u16 EndianConvert16(u16 n); +static u32 EndianConvert32(u32 n); +static int MPDWaiting(int timeout, volatile int* flag, int value); +static void ShowChannelInfo(MCC_CHANNEL chID); +static void fioErrorReport(char* msg); +static void fioMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value); +static void* fioPacketMakeHeader(u32 fioCode, u32 dataSize, BOOL bEndianConvert); +static int fioPacketSendPacket(u8 sizeOfBlocks, void* pTopOfSecondBlockData); +static void* fioPacketReceiveResult(u32 fioCode, BOOL bDone); +static void fioPacketReceiveDone(void); +static int fioPacketRead(int fd, void* buffer, int size, int async); +static int fioPacketWrite(int fd, void* buffer, int size, int async); +static int fioPacketResultRead(void* buffer, u32 dataSize); +static int fioPacketResultWrite(void* buffer, u32 dataSize); + +static BOOL fioIsInitialized(void) { + return !!gChID; +} + +static u16 EndianConvert16(u16 n) { + return ((n & 0x00FF) << 8) | ((n & 0xFF00) >> 8); +} + +static u32 EndianConvert32(u32 n) { + return EndianConvert16((n >> 16) & 0xFFFF) | (EndianConvert16(n & 0xFFFF) << 0x10); +} + +static int MPDWaiting(int timeout, volatile int* flag, int value) { + OSTick tickStart; + OSTick tickDist; + + tickStart = OSGetTick(); + while(*flag != value) { + tickDist = OSGetTick() - tickStart; + tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; + if (OSTicksToSeconds(tickDist) >= timeout) { + OSReport("Error:Time is over.\n"); + return 0; + } + } + + return 1; +} + +static void ShowChannelInfo(MCC_CHANNEL chID) { + MCC_Info info; + + MCCGetChannelInfo(chID, &info); + OSReport("%2d: FirstBlock:%02d,BlockLength:%02d,Connect:%s,Lock:%s.\n", + chID, info.firstBlock, info.blockLength, + (info.connect == MCC_CONNECT_DISCONNECT) ? "DISCONNECT" : + (info.connect == MCC_CONNECT_HOST_OPEN) ? "HOST_OPEN" : + (info.connect == MCC_CONNECT_TARGET_OPEN) ? "TARGET_OPEN" : + (info.connect == MCC_CONNECT_CONNECTED) ? "CONNECTED" : "UNKNOWN", + (info.isLocked == FALSE) ? "UNLOCKED" : + (info.isLocked == TRUE) ? "LOCKED" : "UNKNOWN"); +} + +static void fioErrorReport(char* msg) { + OSReport("[fio] Error: %s\n", msg); +} + +static void fioMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value) { + u32 notify; + + switch(event) { + case MCC_EVENT_CONNECT: + gChID = chID; + return; + case MCC_EVENT_DISCONNECT: + gChID = 0; + return; + case MCC_EVENT_UNK_0x100: + notify = value & 0xF00000; + switch (notify) { + case 0x200000: + if ((u16)value == 0x120) { + gQuery = 1; + } + return; + case 0xF00000: + gProcDone = TRUE; + if (bAsyncBusy != 0) { + bAsyncBusy = FIO_ASYNC_STATE_DONE; + return; + } + break; + } + break; + case MCC_EVENT_READ: + gStreamReady = 0x10; + return; + case MCC_EVENT_WRITE: + gStreamReady = 0x20; + break; + } +} + +int FIOInit(MCC_EXI exiChannel, MCC_CHANNEL chID, u8 blockSize) { + OSRegisterVersion(__FIOVersion); + + if (MCCInit(exiChannel, 10, NULL) == 0) { + gLastErr = FIO_ERROR_MCC; + goto exit; + } + if (MCCOpen(chID, blockSize, fioMccChannelEvent) == 0) { + gLastErr = FIO_ERROR_MCC; + goto exit; + } + + gChID = chID; + gmChID = chID; + gSizeOfBlocks = blockSize; + gmSizeOfBlocks = blockSize; + gQuery = 0; + gProcDone = TRUE; + gProcBusy = FALSE; + gLastErr = FIO_ERROR_NONE; + bAsyncBusy = FIO_ASYNC_STATE_IDOL; + bAsyncBuffer = NULL; + bAsyncIsRead = FALSE; + return 1; + +exit:; + return 0; +} + +void FIOExit(void) { + if (MCCClose(gChID) == 0) { + gLastErr = FIO_ERROR_MCC; + return; + } + + gmChID = gChID = 0; + gmSizeOfBlocks = gSizeOfBlocks = 1; + gQuery = 0; + gProcDone = TRUE; + gProcBusy = FALSE; + gLastErr = FIO_ERROR_NONE; + bAsyncBusy = FIO_ASYNC_STATE_IDOL; + bAsyncBuffer = NULL; + bAsyncIsRead = FALSE; +} + +int FIOQuery(void) { + OSTick tick; + + if (fioIsInitialized()) { + gQuery = 0; + if (MCCNotify(gChID, 0x100120) == 0) { + gLastErr = FIO_ERROR_MCC; + goto exit; + } + if (MPDWaiting(10, &gQuery, 1) == 0) { + gLastErr = FIO_ERROR_TIMEOUT; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return 1; + } + +exit:; + tick = OSGetTick(); + do {} while(OSTicksToSeconds(OSGetTick() - tick) < 5); + return 0; +} + +u8 FIOGetLastError(void) { + return gLastErr; +} + +int FIOFopen(const char* filename, u32 mode) { + struct FIO_Code { + /* 0x00 */ u32 flag; + /* 0x04 */ s8 filename; // dynamic length + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 descriptor; + } *coder; + + if (filename == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (mode & ~0xE03) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(0, strlen(filename) + sizeof(u32) + sizeof(s8), FALSE); + code->flag = mode; + memcpy(&code->filename, filename, strlen(filename) + 1); + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(1, TRUE); + if (coder != NULL) { + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return coder->descriptor; + } + } +exit:; + return -1; +} + +int FIOFclose(int handle) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(2, sizeof(struct FIO_Code), FALSE); + code->descriptor = handle; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(3, TRUE); + if (coder != NULL) { + gLastErr = coder->result; + return 1; + } + } + +exit:; + return 0; +} + +u32 FIOFread(int handle, void* data, u32 size) { + char* pBuf; + volatile int nSizeRemain; + int nResult; + int nReadSize; + + pBuf = data; + nSizeRemain = size; + nResult = -1; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (data == NULL || (u32)data & 0x1F) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (size == 0) { + return 0; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + nReadSize = fioPacketRead(handle, pBuf, nSizeRemain, 0); + nSizeRemain = nSizeRemain - nReadSize; + if (nReadSize < 0) { + gLastErr = FIO_ERROR_PACKET_READ; + return -1; + } + + gLastErr = FIO_ERROR_NONE; + return size - nSizeRemain; + +exit:; + return -1; +} + +u32 FIOFwrite(int handle, void* data, u32 size) { + volatile int nSizeRemain; + int nResult; + int nWriteSize; + + nSizeRemain = size; + nResult = 0; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (data == NULL || (u32)data & 0x1F) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (size == 0) { + return 0; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + nWriteSize = fioPacketWrite(handle, data, nSizeRemain, 0); + nSizeRemain -= nWriteSize; + if (nWriteSize < 0) { + gLastErr = FIO_ERROR_PACKET_WRITE; + return -1; + } + + gLastErr = FIO_ERROR_NONE; + return size - nSizeRemain; + +exit:; + return -1; +} + +u32 FIOFseek(int handle, s32 offset, u32 mode) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + /* 0x04 */ u32 offset; + /* 0x08 */ u32 base; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 pos; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (!(mode == 0 || mode == 2 || mode == 1)) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (mode == 0 && offset < 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (mode == 2 && offset > 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(8, sizeof(struct FIO_Code), FALSE); + code->descriptor = handle; + code->offset = offset; + code->base = mode; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(9, TRUE); + if (coder != NULL && coder->result == 0) { + gLastErr = FIO_ERROR_NONE; + return coder->pos; + } + } + +exit: + return -1; +} + +int FIOFprintf(int handle, const char* format, ...) { + char* str; + int length; + int err; + va_list argptr; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (format == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + str = (char*)gPrintBuf; + va_start(argptr, format); + err = vsprintf(str, format, argptr); + if ((length = strlen(str)) < 0x100) { + str[length] = 0; + } else { + str[0xFF] = 0; + } + + length = strlen(str); + if (err < 0) { + gLastErr = FIO_ERROR_MSG_TOO_LONG; + return -1; + } + + gLastErr = FIO_ERROR_NONE; + return FIOFwrite(handle, str, length + 0); + +exit:; + va_end(argptr); + return -1; +} + +int FIOFflush(int handle) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(10, 4, FALSE); + code->descriptor = handle; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(11, TRUE); + if (coder != NULL) { + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return 1; + } + } + +exit: + return 0; +} + +int FIOFstat(int handle, FIO_Stat* stat) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ FIO_Stat stat; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (stat == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(12, 4, FALSE); + code->descriptor = handle; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(13, TRUE); + if (coder != NULL) { + if (stat) { + memcpy(stat, &coder->stat, sizeof(FIO_Stat)); + } + + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + + gLastErr = FIO_ERROR_NONE; + return 1; + } + } + +exit:; + return 0; +} + +int FIOFerror(int handle) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(14, 4, FALSE); + code->descriptor = handle; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(15, TRUE); + if (coder != NULL) { + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return gLastErr; + } + } + +exit:; + return gLastErr; +} + +int FIOFindFirst(const char* filename, FIO_Finddata* finddata) { + struct FIO_Code { + /* 0x00 */ u8 filename; // dynamic length + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ FIO_Finddata findData; + } *coder; + + if (filename == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (finddata == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(16, strlen(filename) + 1, FALSE); + strcpy((void*)&code->filename, filename); + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(17, TRUE); + if (coder != NULL) { + if (finddata) { + memcpy(finddata, &coder->findData, sizeof(FIO_Finddata)); + } + + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + + gLastErr = FIO_ERROR_NONE; + return 1; + } + } + +exit:; + return 0; +} + +int FIOFindNext(FIO_Finddata* finddata) { + struct FIO_Code { + /* 0x00 */ u32 reserved; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ FIO_Finddata findData; + } *coder; + + if (finddata == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(18, 4, FALSE); + code->reserved = 0; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(19, TRUE); + if (coder != NULL) { + if (finddata) { + memcpy(finddata, &coder->findData, sizeof(FIO_Finddata)); + } + + if (coder->result) { + gLastErr = coder->result; + goto exit; + } + + gLastErr = FIO_ERROR_NONE; + return 1; + } + } + +exit:; + return 0; +} + +int FIOOpenDir(const char* dirname, int* dir) { + struct FIO_Code { + /* 0x00 */ s8 filename; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 descriptor; + } *coder; + + if (dirname == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return 0; + } + if (dir == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return 0; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + return 0; + } + + code = fioPacketMakeHeader(20, strlen(dirname) + 1, FALSE); + memcpy(&code->filename, dirname, strlen(dirname) + 1); + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(21, TRUE); + if (coder != NULL) { + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + + gLastErr = FIO_ERROR_NONE; + *dir = coder->descriptor; + return 1; + } + } + +exit:; + return 0; +} + +int FIOCloseDir(int dir) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + } *coder; + + if (dir == 0 || dir == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return 0; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + return 0; + } + + code = fioPacketMakeHeader(22, 4, FALSE); + code->descriptor = dir; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(23, TRUE); + if (coder != NULL) { + gLastErr = coder->result; + return 1; + } + } + + return 0; +} + +s32 FIOGetDirSize(int dir) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 size; + } *coder; + + if (dir == 0 || dir == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return -1; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + return -1; + } + + code = fioPacketMakeHeader(24, 4, FALSE); + code->descriptor = dir; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(25, TRUE); + if (coder != NULL) { + gLastErr = coder->result; + return coder->size; + } + } + + return -1; +} + +s32 FIOReadDir(int dir, FIO_Finddata* data, s32 numOfData) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + /* 0x04 */ u32 size; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 readsize; + } *coder; + s32 readSize; + u32 fReadSize; + + if (dir == 0 || dir == -1 || data == NULL || numOfData < 1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return -1; + } + + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + return -1; + } + + code = fioPacketMakeHeader(26, 8, FALSE); + code->descriptor = dir; + code->size = numOfData; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(27, TRUE); + if (coder != NULL) { + readSize = coder->readsize; + fReadSize = readSize * sizeof(FIO_Finddata); + gLastErr = coder->result; + + if (gLastErr == FIO_ERROR_NONE || gLastErr == FIO_ERROR_UNK_0x91) { + if (FIOFread(dir, data, fReadSize) == 0) { + return -1; + } + } else { + return -1; + } + + return readSize; + } + } + + return -1; +} + +u32 FIOGetAsyncBufferSize(void) { + int nPacketSize; + int nHeaderSize; + u32 nResult; + + if (gChID == 0) { + return 0; + } + + nPacketSize = gSizeOfBlocks << 0xD; + nHeaderSize = 0x18; + + nResult = nPacketSize - nHeaderSize; + return !(nResult & 0x1F) ? nResult : nResult & ~0x1F; +} + +int FIOFreadAsync(int handle, void* data, u32 size) { + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (data == NULL || (u32)data & 0x1F) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + + if (size != 0) { + if (size > FIOGetAsyncBufferSize()) { + gLastErr = FIO_ERROR_ASYNC_SIZE_TOO_BIG; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + bAsyncBusy = TRUE; + bAsyncBuffer = data; + bAsyncIsRead = TRUE; + if (fioPacketRead(handle, data, size, 1) >= 0) { + return 1; + } + } + +exit:; + return 0; +} + +int FIOFwriteAsync(int handle, void* data, u32 size) { + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (data == NULL || (u32)data & 0x1F) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + + if (size != 0) { + if (size > FIOGetAsyncBufferSize()) { + gLastErr = FIO_ERROR_ASYNC_SIZE_TOO_BIG; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + bAsyncBusy = TRUE; + bAsyncBuffer = data; + bAsyncIsRead = FALSE; + if (fioPacketWrite(handle, data, size, 1) >= 0) { + return 1; + } + } + +exit: + return 0; +} + +int FIOCheckAsyncDone(u32* result) { + if (bAsyncBusy) { + if (bAsyncIsRead) { + if (result) { + *result = fioPacketResultRead(bAsyncBuffer, gAsyncDataSize); + } + } else if (result) { + *result = fioPacketResultWrite(bAsyncBuffer, gAsyncDataSize); + } + + bAsyncBusy = FALSE; + return 1; + } + + return 0; +} + +static void* fioPacketMakeHeader(u32 fioCode, u32 dataSize, BOOL bEndianConvert) { + MCC_Hdr* hdrDpci; + MCC_HdrFio* hdrFio; + char* data; + + hdrDpci = (void*)&gBuf[0]; + hdrFio = (void*)((char*)hdrDpci + 0x8); + data = (void*)((char*)hdrFio + 0x8); + + gRequestSequenceNumber += 1; + hdrFio->code = fioCode; + hdrFio->number = gRequestSequenceNumber; + hdrDpci->length = dataSize + 0x10; + hdrDpci->rsvd = 0; + hdrDpci->protocol = 0x120; + + if (bEndianConvert) { + hdrFio->code = EndianConvert32(hdrFio->code); + hdrFio->number = EndianConvert32(hdrFio->number); + hdrDpci->length = EndianConvert32(hdrDpci->length); + hdrDpci->protocol = EndianConvert16(hdrDpci->protocol); + } + return data; +} + +static int fioPacketSendPacket(u8 sizeOfBlocks, void* pTopOfSecondBlockData) { + u32 oldMaskWrite; + u8 indexOfBlocks; + + oldMaskWrite = MCCSetChannelEventMask(gChID, 0xA0); + + do {} while (gProcBusy); + do {} while (!gProcDone); + + gProcDone = FALSE; + gProcBusy = TRUE; + + for (indexOfBlocks = 0; indexOfBlocks < sizeOfBlocks; indexOfBlocks++) { + if (MCCWrite(gChID, ((u8)indexOfBlocks << 0xD), &gBuf, 0x2000, 0) == 0) { + gLastErr = FIO_ERROR_PACKET_WRITE; + MCCSetChannelEventMask(gChID, oldMaskWrite); + fioErrorReport("fioPacketSendPacket.MCCWrite.NG"); + return 0; + } + + if (sizeOfBlocks > 1) { + memcpy(&gBuf, pTopOfSecondBlockData, 0x2000); + ((char*)pTopOfSecondBlockData) += 0x2000; + } + } + + MCCSetChannelEventMask(gChID, oldMaskWrite); + if (MCCNotify(gChID, 0xF00000) == 0) { + gLastErr = FIO_ERROR_MCC; + fioErrorReport("fioPacketSendPacket.MCCNotify.NG"); + return 0; + } + + gLastErr = FIO_ERROR_NONE; + return 1; +} + +static void* fioPacketReceiveResult(u32 fioCode, BOOL bDone) { + u32 oldMaskRead; + MCC_Hdr* hdrDpci; + MCC_HdrFio* hdrFio; + char* data; + + if (MPDWaiting(10, &gProcDone, 1) == 0) { + gLastErr = FIO_ERROR_TIMEOUT; + goto exit; + } + + oldMaskRead = MCCSetChannelEventMask(gChID, 0x50); + if (MCCRead(gChID, 0, &gBuf, 0x2000, 0) == 0) { + gLastErr = FIO_ERROR_PACKET_READ; + MCCSetChannelEventMask(gChID, oldMaskRead); + goto exit; + } + + hdrDpci = (void*)((char*)&gBuf[0]); + hdrFio = (void*)((char*)hdrDpci + 0x8); + data = (void*)((char*)hdrFio + 0x8); + MCCSetChannelEventMask(gChID, oldMaskRead); + + if (hdrFio->code != fioCode) { + gLastErr = FIO_ERROR_WRONG_CODE; + goto exit; + } + if (hdrFio->number != gRequestSequenceNumber) { + gLastErr = FIO_ERROR_WRONG_SEQUENCE; + goto exit; + } + + if (bDone) { + fioPacketReceiveDone(); + } + + gLastErr = FIO_ERROR_NONE; + return data; + +exit:; + fioPacketReceiveDone(); + return NULL; +} + +static void fioPacketReceiveDone(void) { + gProcBusy = 0; +} + +static int fioPacketRead(int fd, void* buffer, int size, int async) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + /* 0x04 */ u32 nbytes; + } *code; + + code = fioPacketMakeHeader(4, sizeof(struct FIO_Code), FALSE); + code->descriptor = fd; + code->nbytes = size; + gStreamReady = 0; + + if (fioPacketSendPacket(1, NULL)) { + if (async == 0) { + return fioPacketResultRead(buffer, size); + } + gAsyncDataSize = size; + return 0; + } + + return -1; +} + +static int fioPacketWrite(int fd, void* buffer, int size, int async) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + /* 0x04 */ u32 nbytes; + } *code; + + code = fioPacketMakeHeader(6, 0xC, FALSE); + code->descriptor = fd; + code->nbytes = size; + + if (fioPacketSendPacket(1, NULL)) { + gStreamReady = 0; + if (async == 0) { + return fioPacketResultWrite(buffer, size); + } + gAsyncDataSize = size; + return 0; + } + + return -1; +} + +static int fioPacketResultRead(void* buffer, u32 dataSize) { + int bResult; + MCC_CHANNEL nChID; + u8 nChannelBlocks; + u32 dataBlockSize; + u32 readDataBlocks; + u32 nPacketSize; + u32 nDataPacketSize; + u32 nFraction; + MCC_CONNECT state; + BOOL bNeedWaitDisconnect; + u32 oldMaskWrite; + u8 err; + char msg[256]; + + bResult = 1; + nChID = gmChID; + nChannelBlocks = gmSizeOfBlocks; + dataBlockSize = (u32) (dataSize + 0x1FFF) >> 0xDU; + nPacketSize = ((u8)nChannelBlocks << 0xD); + nDataPacketSize = dataSize / nPacketSize; + nFraction = dataSize - (nDataPacketSize * nPacketSize); + nFraction = OSRoundUp32B(nFraction) & ~1; + + if (nFraction != 0) { + do {} while ((u32) gStreamReady != 0x20); + MCCRead(nChID, 0, buffer, nFraction, 0); + ((char*)buffer) += nFraction; + } + + if (nDataPacketSize != 0) { + bNeedWaitDisconnect = FALSE; + oldMaskWrite = MCCSetChannelEventMask(nChID, 0); + MCCSetChannelEventMask(nChID, oldMaskWrite); + + if (MCCClose(nChID) == 0) { + fioErrorReport("fioPacketResultRead.MCCClose.NG"); + bResult = 0; + } else { + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 0); + + if (MCCStreamOpen(nChID, nChannelBlocks) == 0) { + fioErrorReport("fioPacketResultRead.MCCStreamOpen.NG"); + bResult = 0; + } else { + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 3); + + if ((nDataPacketSize * nChannelBlocks) != (readDataBlocks = MCCStreamRead(nChID, buffer))) { + err = MCCGetLastError(); + sprintf(msg, "fioPacketResultRead.MCCStreamRead.NG(Err:%d)", err); + fioErrorReport(msg); + bResult = 0; + } + + if (MCCStreamClose(nChID) == 0) { + OSReport("MCCStream:MCCStreamClose.NG\n"); + bResult = 0; + } else { + MCC_CONNECT state; + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 0); + + if (MCCOpen(nChID, nChannelBlocks, fioMccChannelEvent) == 0) { + OSReport("MCCStream:MCCOpen.NG\n"); + bResult = 0; + } else { + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 3); + } + } + } + } + + MCCSetChannelEventMask(gChID, oldMaskWrite); + } + + // scope for variable? + { + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 nbytes; + /* 0x08 */ char data; + } *coder; + + coder = fioPacketReceiveResult(5, FALSE); + if (coder == NULL) { + bResult = 0; + } else if (coder->result != 0) { + gLastErr = coder->result; + bResult = 0; + } else { + gLastErr = FIO_ERROR_NONE; + } + + fioPacketReceiveDone(); + if (bResult == 1) { + return dataSize; + } + goto exit; + } + +exit:; + return -1; +} + +static int fioPacketResultWrite(void* buffer, u32 dataSize) { + register int nResult = 0; + MCC_CHANNEL nChID; + u8 nChannelBlocks = 0; + u32 dataBlockSize; + MCC_CONNECT state; + BOOL bNeedWaitDisconnect; + u32 oldMaskWrite; + + nChID = gmChID; + nChannelBlocks = gmSizeOfBlocks; + dataBlockSize = (dataSize + 0x1FFF) >> 0xD; + bNeedWaitDisconnect = FALSE; + oldMaskWrite = MCCSetChannelEventMask(nChID, 0); + + MCCSetChannelEventMask(nChID, oldMaskWrite); + if (MCCClose(nChID) == 0) { + fioErrorReport("fioPacketResultWrite.MCCClose.NG"); + } else { +loop:; + MCCGetConnectionStatus(nChID, &state); + if (state != 0) { + goto loop; + } + + if (MCCStreamOpen(nChID, nChannelBlocks) == 0) { + fioErrorReport("fioPacketResultWrite.MCCStreamOpen.NG"); + goto loop; + } + + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 3); + + if (MCCStreamWrite(nChID, buffer, dataBlockSize) == 0) { + fioErrorReport("fioPacketResultWrite.MCCStreamWrite.NG"); + } + + { + MCC_CONNECT state; + do { + MCCGetConnectionStatus(nChID, &state); + } while (state == 3); + + if (MCCStreamClose(nChID) == 0) { + OSReport("MCCStream:MCCStreamClose.NG\n"); + } else { + do { + MCCGetConnectionStatus(nChID, &state); + } while (state == 0); + + if (MCCOpen(nChID, nChannelBlocks, fioMccChannelEvent) == 0) { + OSReport("MCCStream:MCCOpen.NG\n"); + } + } + } + goto exit_loop; + } + +exit_loop:; + { + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 nbytes; + } *coder; + + oldMaskWrite = MCCSetChannelEventMask(gChID, oldMaskWrite); + coder = fioPacketReceiveResult(7, TRUE); + + if (coder == NULL) { + (void)0; + } else { + if (coder->result) { + gLastErr = coder->result; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return coder->nbytes; + } + } + +exit: + return -1; +} diff --git a/src/dolphin/mcc/mcc.c b/src/dolphin/mcc/mcc.c new file mode 100644 index 0000000..bed12b5 --- /dev/null +++ b/src/dolphin/mcc/mcc.c @@ -0,0 +1,1417 @@ +#include +#include + +#ifdef DEBUG +const char* __MCCVersion = "<< Dolphin SDK - MCC\tdebug build: Apr 5 2004 03:57:07 (0x2301) >>"; +#else +const char* __MCCVersion = "<< Dolphin SDK - MCC\trelease build: Apr 5 2004 04:15:49 (0x2301) >>"; +#endif + +static MCC_ChannelInfo gChannelInfo[16] ATTRIBUTE_ALIGN(32); +static char gStreamWork[32] ATTRIBUTE_ALIGN(32); +static char m_szAdapterMode[32] ATTRIBUTE_ALIGN(32); +static char m_szInitCode[32] ATTRIBUTE_ALIGN(32); +static MCC_Info channelInfo[16] ATTRIBUTE_ALIGN(32); + +volatile static BOOL gIsChannelinfoDirty = TRUE; + +static void (*volatile gCallbackSysEvent)(MCC_SYSEVENT); +static BOOL gOtherSideInitDone; +volatile static u8 gLastError; +static BOOL gMccInitialized; +static int gMccSession; +volatile static int gPingFlag; +volatile static u16 gAsyncResourceStatus; + +// prototypes +static void mccDebugPrint(char* str); +static void callbackEventStream(MCC_CHANNEL chID, u32 event, u32 value); +static int SetUsbAdapterMode(u8 mode); +static u8 GetUsbAdapterMode(void); +static int InitializeCodeClear(void); +static int InitializeCodeSet(void); +static int InitializeCodeCheck(void); +static void AsyncResourceClearState(void); +static void AsyncResourceSetState(u16 state); +static void AsyncResourceStateBusy(u8 channel, u16 mode); +static void AsyncResourceStateDone(void); +static u16 AsyncResourceGetStat(void); +static u16 AsyncResourceGetMode(void); +static u8 AsyncResourceGetChannel(void); +static int AsyncResourceIsBusy(void); +static int LoadChannelInfo(MCC_ChannelInfo* info); +static int FlushChannelInfo(MCC_ChannelInfo* info); +static void SetChannelInfoDirty(int dirty); +static void ClearChannelInfo(int i); +static void MakeMemoryMap(u8* map); +static BOOL IsChannelOpened(MCC_CHANNEL chID); +static u8 SearchFreeBlocks(MCC_MODE mode, u8* index); +static int NotifyCompulsorily(MCC_CHANNEL chID, u32 notify, u32 timeout); +static int NotifyInit(void); +static int NotifyInitDone(void); +static int NotifyChannelEvent(MCC_CHANNEL chID, u32 notify); +static int WaitAMinute(int timeout, volatile int* flag, int value); +static void MailboxCheck(void); +static void MCCExiCallback(void); +static void MCCTxCallback(void); +static void MCCRxCallback(void); +static int mccInitializeCheck(u8 timeout); + +static void mccDebugPrint(char* str) {} + +static void callbackEventStream(MCC_CHANNEL chID, u32 event, u32 value) { + value; // needed to bump registers. what? + + if (event == MCC_EVENT_READ) { + gChannelInfo[chID].isStreamDone = TRUE; + } + if (event == MCC_EVENT_WRITE) { + gChannelInfo[chID].isStreamDone = TRUE; + } + if (event == MCC_EVENT_CONNECT) { + gChannelInfo[chID].isStreamConnection = TRUE; + } + if (event == MCC_EVENT_DISCONNECT) { + gChannelInfo[chID].isStreamConnection = TRUE; + } + if (event == MCC_EVENT_UNK_0x100) { + gChannelInfo[chID].isStreamConnection = TRUE; + } +} + +BOOL MCCStreamOpen(MCC_CHANNEL chID, u8 blockSize) { + BOOL bResult; + + bResult = FALSE; + if (MCCOpen(chID, blockSize, callbackEventStream)) { + gChannelInfo[chID].isStreamOpened = 0; + gChannelInfo[chID].isStreamConnection = 0; + gChannelInfo[chID].isStreamDone = 0; + bResult = TRUE; + } + + return bResult; +} + +int MCCStreamClose(MCC_CHANNEL chID) { + gChannelInfo[chID].isStreamOpened = FALSE; + return MCCClose(chID); +} + +int MCCStreamWrite(MCC_CHANNEL chID, void* data, u32 dataBlockSize) { + MCC_Info chanInfo; + char* dataAddress; + u32 lastBlocks; + + if (!gMccInitialized) { + gLastError = 1; + } else if (chID < 1 || chID >= 16) { + gLastError = 14; + } else if (LoadChannelInfo(gChannelInfo) == 0) { + gLastError = 11; + } else { + if (gChannelInfo[chID].isStreamOpened != TRUE) { + gChannelInfo[chID].isStreamOpened = TRUE; + } else { + MCCNotify(chID, 0); + } + + if (WaitAMinute(5, &gChannelInfo[chID].isStreamConnection, 1) == 0) { + gLastError = 2; + } else { + gChannelInfo[chID].isStreamConnection = 0; + if (MCCGetChannelInfo(chID, &chanInfo) != 0) { + *(u32*)&gStreamWork = dataBlockSize; + if (MCCWrite(chID, 0, gStreamWork, 0x20, 0) != 0) { + if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { + gLastError = 2; + } else { + dataAddress = data; + lastBlocks = dataBlockSize; + gChannelInfo[chID].isStreamDone = FALSE; + while (lastBlocks) { + if (!MCCWrite(chID, 0, dataAddress, chanInfo.blockLength << 0xD, 0)) { + break; + } + + if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { + gLastError = 2; + break; + } else { + gChannelInfo[chID].isStreamDone = 0; + dataAddress += chanInfo.blockLength << 0xD; + if (lastBlocks > chanInfo.blockLength) { + lastBlocks -= chanInfo.blockLength; + } else { + lastBlocks = 0; + break; + } + } + } + + return lastBlocks == 0; + } + } + } + } + } + + return 0; +} + +u32 MCCStreamRead(MCC_CHANNEL chID, void* data) { + MCC_Info chanInfo; + char* dataAddress; + u32 allBlocks; + u32 lastBlocks; + + if (!gMccInitialized) { + gLastError = 1; + } else if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + } else if (LoadChannelInfo(gChannelInfo) == 0) { + gLastError = 0xB; + } else { + if (gChannelInfo[chID].isStreamOpened != TRUE) { + gChannelInfo[chID].isStreamOpened = TRUE; + } else { + MCCNotify(chID, 0); + } + + if (WaitAMinute(5, &gChannelInfo[chID].isStreamConnection, 1) == 0) { + gLastError = 2; + } else { + gChannelInfo[chID].isStreamConnection = FALSE; + if (MCCGetChannelInfo(chID, &chanInfo) != 0) { + if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { + gLastError = 2; + } else { + gChannelInfo[chID].isStreamDone = FALSE; + if (MCCRead(chID, 0, gStreamWork, 0x20, 0) != 0) { + dataAddress = data; + allBlocks = lastBlocks = *(u32*)&gStreamWork[0]; + while (lastBlocks) { + if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { + gLastError = 2; + break; + } + + gChannelInfo[chID].isStreamDone = FALSE; + if (MCCRead(chID, 0, dataAddress, (lastBlocks > chanInfo.blockLength) ? chanInfo.blockLength << 0xD : lastBlocks << 0xD, 0) != 0) { + dataAddress += chanInfo.blockLength << 0xD; + if (lastBlocks > chanInfo.blockLength) { + lastBlocks -= chanInfo.blockLength; + } else { + lastBlocks = 0; + break; + } + } else { + break; + } + } + return allBlocks - lastBlocks; + } + } + } + } + } + + return 0; +} + +static int SetUsbAdapterMode(u8 mode) { + int result = 0; + + if (HIORead(0x680, m_szAdapterMode, 0x20) != 0) { + DCInvalidateRange(m_szAdapterMode, 0x20); + m_szAdapterMode[0] = mode; + DCFlushRange(m_szAdapterMode, 0x20); + if (HIOWrite(0x680, m_szAdapterMode, 0x20) != 0) { + result = 1; + } + } + return result; +} + +static u8 GetUsbAdapterMode(void) { + if (HIORead(0x680, m_szAdapterMode, 0x20) != 0) { + DCInvalidateRange(m_szAdapterMode, 0x20); + return m_szAdapterMode[0]; + } + return 0; +} + +static int InitializeCodeClear(void) { + memset(m_szInitCode, 0, 0x20); + DCFlushRange(m_szInitCode, 0x20); + HIOWrite(0x600, m_szInitCode, 0x20); +} + +static int InitializeCodeSet(void) { + strcpy(m_szInitCode, "HUDSON/USB2EXI/INITCODE/TARGET"); + DCFlushRange(m_szInitCode, 0x20); + HIOWrite(0x600, m_szInitCode, 0x20); +} + +static int InitializeCodeCheck(void) { + int result; + + if ((result = HIORead(0x600, m_szInitCode, 0x20)) != 0) { + DCInvalidateRange(m_szInitCode, 0x20); + result = strcmp(m_szInitCode, "HUDSON/USB2EXI/INITCODE/HOST"); + return result == 0; + } + return result; +} + +static void AsyncResourceClearState(void) { + gAsyncResourceStatus = 0; +} + +static void AsyncResourceSetState(u16 state) { + gAsyncResourceStatus &= 0xFFFF0FFF; + gAsyncResourceStatus |= state; +} + +static void AsyncResourceStateBusy(u8 channel, u16 mode) { + AsyncResourceClearState(); + AsyncResourceSetState(0x1000); + gAsyncResourceStatus |= channel; + gAsyncResourceStatus |= mode; +} + +static void AsyncResourceStateDone(void) { + AsyncResourceSetState(0x2000); +} + +static u16 AsyncResourceGetStat(void) { + return gAsyncResourceStatus & 0xF000; +} + +static u16 AsyncResourceGetMode(void) { + return gAsyncResourceStatus & 0xF00; +} + +static u8 AsyncResourceGetChannel(void) { + return gAsyncResourceStatus; +} + +static int AsyncResourceIsBusy(void) { + return AsyncResourceGetStat() & 0x1000; +} + +static int LoadChannelInfo(MCC_ChannelInfo* info) { + volatile int result = 0; + u8 count; +#ifndef DEBUG + int unused; // this is fake, but i cant seem to find whats messing with the stack. +#endif + + if (!gIsChannelinfoDirty) { + result = 1; + } else { + count = 0; + mccDebugPrint("+++ Load channel info."); + while ((result = HIORead(0x700, channelInfo, 0x40)) != 1) { + count -= 1; + if (count == 0) { + break; + } + } + + if (result) { + DCInvalidateRange(channelInfo, 0x40); + for(count = 0; count < 16; count++) { + info[count].info = channelInfo[count]; + } + SetChannelInfoDirty(0); + } + } + + return result; +} + +static int FlushChannelInfo(MCC_ChannelInfo* info) { + volatile int result; + u8 count; + + result = 0; + for(count = 0; count < 16; count++) { + channelInfo[count] = info[count].info; + } + + DCFlushRange(channelInfo, 0x40); + while ((result = HIOWrite(0x700, channelInfo, 0x40)) != 1) { + count -= 1; + if (count == 0) { + break; + } + } + + if (result != 0) { + SetChannelInfoDirty(1); + result = NotifyCompulsorily(0, 5, 10); + } + return result; +} + +static void SetChannelInfoDirty(int dirty) { + gIsChannelinfoDirty = dirty; +} + +static void ClearChannelInfo(int i) { + gChannelInfo[i].info.firstBlock = 0; + gChannelInfo[i].info.blockLength = 0; + gChannelInfo[i].info.connect = 0; + gChannelInfo[i].info.isLocked = FALSE; + gChannelInfo[i].eventMask = 0; + gChannelInfo[i].callbackEvent = NULL; + gChannelInfo[i].isStreamDone = FALSE; + //! isStreamConnection isnt cleared. Intentional? +} + +static void MakeMemoryMap(u8* map) { + u8 iMap; + u8 jMap; + + memset(map, 0, 0x10); + for (iMap = 0; iMap < 16; iMap++) { + if (gChannelInfo[iMap].info.connect) { + for (jMap = 0; jMap < gChannelInfo[iMap].info.blockLength; jMap++) { + if (jMap + gChannelInfo[iMap].info.firstBlock < 0x10) { + map[gChannelInfo[iMap].info.firstBlock + jMap] = iMap + 1; + } else { + gLastError = 0xD; + } + } + } + } + + *map = 0xFF; +} + +static int IsChannelOpened(MCC_CHANNEL chID) { + u8 connectSide; + + if (chID <= 0 || chID >= 0x10) { + gLastError = 0xE; + goto exit; + } + connectSide = 2; + + return (connectSide & gChannelInfo[chID].info.connect) ? TRUE : FALSE; + +exit:; + return 0; +} + +static u8 SearchFreeBlocks(MCC_MODE mode, u8* index) { + u8 map[16]; + u8 iMap; + u8 fIndex; + u8 fSize; + u8 fCount; + + MakeMemoryMap(map); + fCount = 0; + fIndex = 0; + fSize = (mode == 0) ? 0x10 : 0; + + //! @bug I think this will read OOB of the map array by 1. + for (iMap = 0; iMap <= 16; iMap++) { + if (map[iMap] || iMap == 16) { + if (fCount != 0) { + if (mode == 0) { + if (fSize > fCount) { + fSize = fCount; + fIndex = iMap - fCount; + } + } else if (mode == 1) { + if (fSize < fCount) { + fSize = fCount; + fIndex = iMap - fCount; + } + } else if (mode == 2) { + fSize += fCount; + } + fCount = 0; + } + } else { + fCount += 1; + } + } + + if (index) { + *index = fIndex; + } + return fSize; +} + +static int NotifyCompulsorily(MCC_CHANNEL chID, u32 notify, u32 timeout) { + u32 status; + u32 notifyData; + volatile u32 tickStart; + volatile u32 tickCur; + volatile u32 tickSec; +#ifndef DEBUG + int unused; // fake but blah +#endif + + status = 0; + tickStart = OSGetTick(); + + notifyData = (chID << 0x18); + notifyData |= (notify & 0x10000000); + notifyData |= (notify & 0xFFFFFF); + + while (1) { + if (!HIOReadStatus(&status)) { + mccDebugPrint("ERROR:HIOReadStatus\n"); + } + + if ((status & 2) == 0) { + break; + } + + tickCur = OSGetTick(); + tickSec = (tickStart < tickCur) ? tickCur - tickStart : (-1 - tickStart) + tickCur; + tickSec = OSTicksToSeconds(tickSec); + if (timeout == 0 || tickSec > timeout) { + break; + } + } + + if (!HIOWriteMailbox(notifyData)) { + gLastError = 6; + goto exit; + } + return 1; + +exit:; + return 0; +} + +static int NotifyInit(void) { + return NotifyCompulsorily(0, 1, 0); +} + +static int NotifyInitDone(void) { + return NotifyCompulsorily(0, 2, 0); +} + +static int NotifyChannelEvent(MCC_CHANNEL chID, u32 notify) { +#ifndef DEBUG + int unused[2]; // fake but blah +#endif + + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:Channel is not opened.\n"); + gLastError = 0x12; + } else if (NotifyCompulsorily(chID, notify, 10) != 0) { + return 1; + } + + return 0; +} + +static int WaitAMinute(int timeout, volatile int* flag, int value) { + u32 tickStart; + u32 tickDist; + + tickStart = OSGetTick(); + while (*flag != value) { + tickDist = OSGetTick() - tickStart; + tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; + if (OSTicksToSeconds(tickDist) >= timeout) { + mccDebugPrint("Error:Time is over.\n"); + return 0; + } + } + return 1; +} + +static void MailboxCheck(void) { + u32 mailbox; + BOOL isNotify; + u8 chID; + u32 value; + BOOL bDoCall; +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + mailbox = 0; + if (HIOReadMailbox(&mailbox) == 0) { + mccDebugPrint("Error:Could not read mailbox.\n"); + gLastError = 5; + return; + } + + isNotify = (mailbox & 0x10000000) != 0; + chID = (mailbox >> 0x18U) & 0xF; + value = (mailbox & 0xFFFFFF); + + if (chID == 0) { + bDoCall = TRUE; + switch(value) { + case 2: + gMccInitialized = TRUE; + gMccSession = 1; + gOtherSideInitDone = TRUE; + break; + case 3: + NotifyCompulsorily(0, 4, 10); + break; + case 1: + gMccSession = 0; + break; + case 4: + if (gPingFlag == 0) { + bDoCall = FALSE; + } + gPingFlag = 0; + break; + case 5: + SetChannelInfoDirty(1); + break; + default: + if (value == 8) { + bDoCall = FALSE; + } else { + value = 0; + } + break; + } + + if (bDoCall && gCallbackSysEvent) { + gCallbackSysEvent(value); + } + } else { + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + return; + } + + if (IsChannelOpened(chID)) { + if (!!isNotify) { + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, MCC_EVENT_UNK_0x100, value); + } + } else { + switch(value) { + case MCC_EVENT_READ_DONE_INSIDE: + case MCC_EVENT_WRITE_DONE_INSIDE: + mccDebugPrint("ERROR: MCC_EVENT_READ_DONE_INSIDE / MCC_EVENT_WRITE_DONE_INSIDE received."); + break; + case MCC_EVENT_CONNECT: + case MCC_EVENT_DISCONNECT: + case MCC_EVENT_LOCK: + case MCC_EVENT_UNLOCK: + case MCC_EVENT_READ: + case MCC_EVENT_WRITE: + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, value, 0); + } + break; + default: + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0, 0); + } + break; + } + } + } + } +} + +static void MCCExiCallback(void) { + MailboxCheck(); +} + +static void MCCTxCallback(void) { + AsyncResourceStateDone(); +} + +static void MCCRxCallback(void) { + AsyncResourceStateDone(); +} + +static int mccInitializeCheck(u8 timeout) { + int dmyFlag; + int i; +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + dmyFlag = 0; + if (InitializeCodeCheck() == 0) { + if (gMccInitialized) { + if (gMccSession == 0) { + SetChannelInfoDirty(1); + for (i = 0; i < 16; i++) { + ClearChannelInfo(i); + } + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + return 0; + } + } + return 1; + } + + InitializeCodeSet(); + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + } else if (timeout != 0 && WaitAMinute(timeout, &gOtherSideInitDone, 1) == 0) { + InitializeCodeClear(); + mccDebugPrint("Error:Time is over.\n"); + gLastError = 2; + return 0; + } else { + return 1; + } + } else { + InitializeCodeClear(); + if (NotifyInitDone() == 0) { + gLastError = 4; + } else { + if (gCallbackSysEvent) { + gCallbackSysEvent(2); + } + gMccInitialized = TRUE; + gMccSession = 1; + return 1; + } + } + return 0; +} + +int MCCInit(MCC_EXI exiChannel, u8 timeout, MCC_CBSysEvent callbackSysEvent) { + int dmyFlag; + u8 adapterMode; + u32 mailbox; + u32 status; + int i; +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + OSRegisterVersion(__MCCVersion); + + mccDebugPrint("MCCInit\n"); + if (gMccInitialized) { + SetChannelInfoDirty(1); + return mccInitializeCheck(timeout); + } + + if (!(exiChannel == 0 || exiChannel == 1 || exiChannel == 2)) { + mccDebugPrint("[MCC] Error: Exi channel is out of range.\n"); + gLastError = 4; + return 0; + } + + if (HIOInit(exiChannel, MCCExiCallback) == 0) { + mccDebugPrint("Error:Initialized Host I/O\n"); + gLastError = 4; + } else { + dmyFlag = 0; + adapterMode = GetUsbAdapterMode(); + adapterMode = SetUsbAdapterMode(1); + mailbox = 0; + status = 0; + + if (HIOReadStatus(&status) != 0 && status & 1) { + HIOReadMailbox(&mailbox); + } + + WaitAMinute(1, &dmyFlag, 1); + if (NotifyInit() == 0) { + gLastError = 4; + } else { + gCallbackSysEvent = callbackSysEvent; + gLastError = 0; + SetChannelInfoDirty(1); + for (i = 0; i < 16; i++) { + ClearChannelInfo(i); + } + AsyncResourceClearState(); + return mccInitializeCheck(timeout); + } + } + + return 0; +} + +void MCCExit(void) { + u8 chID; + + if (!gMccInitialized) { + gLastError = 1; + } else { + mccDebugPrint("MCCExit\n"); + for (chID = 1; chID < 16; chID++) { + if (IsChannelOpened(chID)) { + MCCClose(chID); + } + } + gLastError = 0; + } + + gMccInitialized = FALSE; + gMccSession = 0; +} + +int MCCPing(void) { + mccDebugPrint("MCCPing\n"); + if (!gMccInitialized) { + gLastError = 1; + } else { + gPingFlag = 1; + gLastError = 0; + return NotifyCompulsorily(0, 3, 10); + } + return 0; +} + +int MCCEnumDevices(MCC_CBEnumDevices callbackEnumDevices) { + if (callbackEnumDevices == NULL) { + gLastError = 0xD; + } + + if (HIOEnumDevices(callbackEnumDevices) == 0) { + gLastError = 0xD; + } else { + gLastError = 0; + return 1; + } + + return 0; +} + +u8 MCCGetFreeBlocks(MCC_MODE mode) { +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + mccDebugPrint("MCCGetFreeBlocks\n"); + if (!gMccInitialized) { + gLastError = 1; + } else if (!(mode == 0 || mode == 1 || mode == 2)) { + gLastError = 0xD; + } else { + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else { + gLastError = 0; + return SearchFreeBlocks(mode, NULL); + } + } + + return 0; +} + +u8 MCCGetLastError(void) { + mccDebugPrint("MCCGetFreeBlocks\n"); //! wrong print? + return gLastError; +} + +int MCCGetChannelInfo(MCC_CHANNEL chID, MCC_Info* info) { +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + mccDebugPrint("MCCGetChannelInfo\n"); + if (!gMccInitialized) { + gLastError = 1; + } else if (chID <= 0 || chID >= 0x10) { + gLastError = 0xE; + } else if (!info) { + mccDebugPrint("Error:Bad parameter channelInfo.\n"); + gLastError = 0xD; + } else { + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else { + memcpy(info, &gChannelInfo[chID].info, sizeof(MCC_Info)); + gLastError = 0; + return 1; + } + } + + return 0; +} + +int MCCGetConnectionStatus(MCC_CHANNEL chID, MCC_CONNECT* connect) { + MCC_Info info; +#ifndef DEBUG + int unused[2]; // fake but blah +#endif + + mccDebugPrint("MCCGetConnectionStatus\n"); + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + + if (!connect) { + mccDebugPrint("Error:Parameter error.\n"); + gLastError = 0xD; + } else { + if (MCCGetChannelInfo(chID, &info) != 0) { + *connect = info.connect; + gLastError = 0; + return 1; + } + } + + return 0; +} + +int MCCNotify(MCC_CHANNEL chID, u32 notify) { + MCC_CONNECT connect; +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + + mccDebugPrint("MCCNotify\n"); + if (!gMccInitialized) { + gLastError = 1; + } else if(chID <= 0 || chID >= 0x10) { + gLastError = 0xE;; + } else if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else if(MCCGetConnectionStatus(chID, &connect) == 0) { + gLastError = 9; + } else { + if (connect != 3) { + mccDebugPrint("Error:Channel is not opened.\n"); + gLastError = 0x12; + } else { + notify |= 0x10000000; + return NotifyCompulsorily(chID, notify, 0xAU); + } + } + + return 0; +} + +u32 MCCSetChannelEventMask(MCC_CHANNEL chID, u32 event) { + u32 oldMask; +#ifndef DEBUG + int unused[2]; // fake but blah +#endif + + oldMask = 0xFFFFFFFF; + if (!gMccInitialized) { + gLastError = 1; + } else if (chID <= 0 || chID >= 0x10) { + gLastError = 0xE; + } else if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + } else { + oldMask = gChannelInfo[chID].eventMask; + gChannelInfo[chID].eventMask = (u16)event; + } + + return oldMask; +} + +int MCCOpen(MCC_CHANNEL chID, u8 blockSize, MCC_CBEvent callbackEvent) { + u8 connectSide; + u8 blockIndex; +#ifndef DEBUG + int unused2[2]; +#endif + u8 freeBlocks; +#ifndef DEBUG + int unused[6]; // fake but blah +#endif + + mccDebugPrint("MCCOpen\n"); + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (blockSize == 0) { + gLastError = 0xF; + return 0; + } + + if (chID <= 0 || chID >= 0x10) { + mccDebugPrint("Error:Invalid channel.\n"); + gLastError = 0xE; + goto exit; + } else { + connectSide = 2; + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } else if (!gChannelInfo[chID].info.connect) { + freeBlocks = SearchFreeBlocks(1, &blockIndex); + if (blockSize > freeBlocks) { + mccDebugPrint("Error:Not enough free blocks.\n"); + gLastError = 0xC; + goto exit; + } else { + gChannelInfo[chID].info.firstBlock = blockIndex; + gChannelInfo[chID].info.blockLength = blockSize; + gChannelInfo[chID].info.connect = connectSide; + gChannelInfo[chID].info.isLocked = FALSE; + gChannelInfo[chID].eventMask = 0; + gChannelInfo[chID].callbackEvent = callbackEvent; + gChannelInfo[chID].isStreamDone = FALSE; + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + gLastError = 0; + return 1; + } + } + } + + if (gChannelInfo[chID].info.connect & connectSide) { + mccDebugPrint("Error:Already opened.\n"); + gLastError = 0x11; + goto exit; + } else if (blockSize != gChannelInfo[chID].info.blockLength) { + mccDebugPrint("Error:Block size error.\n"); + gLastError = 0xD; + goto exit; + } + + gChannelInfo[chID].info.connect = 3; + gChannelInfo[chID].callbackEvent = callbackEvent; + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + + if (~(gChannelInfo[chID].eventMask) & 1) { + NotifyCompulsorily(chID, 1, 10); + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 1, 0); + } + } + + gLastError = 0; + return 1; +exit:; + return 0; +} + +int MCCClose(MCC_CHANNEL chID) { + u8 connectSide; +#ifndef DEBUG + int unused[4]; // fake but blah +#endif + + connectSide = 2; + mccDebugPrint("MCCClose\n"); + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + + gChannelInfo[chID].info.connect &= ~connectSide; + if (gChannelInfo[chID].info.connect == 0) { + ClearChannelInfo(chID); + } + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + + if (gChannelInfo[chID].info.connect != 0) { + if (~(gChannelInfo[chID].eventMask) & 2) { + NotifyCompulsorily(chID, 2, 10); + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 2, 0); + } + } + } + + gLastError = 0; + return 1; +exit:; + return 0; +} + +int MCCLock(MCC_CHANNEL chID) { +#ifndef DEBUG + int unused[7]; // fake but blah +#endif + + mccDebugPrint("MCCLock\n"); + + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + if (gChannelInfo[chID].info.isLocked == TRUE) { + mccDebugPrint("Error:This channel is already locked."); + gLastError = 0x13; + goto exit; + } + + gChannelInfo[chID].info.isLocked = TRUE; + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + + if (~(gChannelInfo[chID].eventMask) & 4) { + NotifyChannelEvent(chID, 4); + } + gLastError = 0; + return 1; + +exit:; + return 0; +} + +int MCCUnlock(MCC_CHANNEL chID) { +#ifndef DEBUG + int unused[7]; // fake but blah +#endif + + mccDebugPrint("MCCUnlock\n"); + + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + if (gChannelInfo[chID].info.isLocked == FALSE) { + mccDebugPrint("Error:This channel is already unlocked."); + gLastError = 0x14; + goto exit; + } + + gChannelInfo[chID].info.isLocked = FALSE; + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + + if (~(gChannelInfo[chID].eventMask) & 8) { + NotifyChannelEvent(chID, 8); + } + gLastError = 0; + return 1; + +exit: + return 0; +} + +int MCCRead(MCC_CHANNEL chID, u32 offset, void* data, s32 size, MCC_SYNC_STATE async) { +#ifndef DEBUG + int unused[11]; // fake but blah +#endif + + mccDebugPrint("MCCRead\n"); + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (!(async == 1 || async == 0)) { + gLastError = 0xD; + return 0; + } + if ((offset & 3) || ((u32)data & 0x1F) || (size % 32) != 0) { + gLastError = 0xD; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + if (offset > gChannelInfo[chID].info.blockLength << 0xD) { + mccDebugPrint("Error:Invarid offset"); + gLastError = 0x10; + goto exit; + } + if ((offset + size) > gChannelInfo[chID].info.blockLength << 0xD) { + mccDebugPrint("Error:Invarid data size."); + gLastError = 0xF; + goto exit; + } + + if (async == 1) { + if (MCCCheckAsyncDone() == 0) { + mccDebugPrint("Error:Channel busy."); + gLastError = 0x15; + goto exit; + } + AsyncResourceStateBusy(chID, 0U); + if (HIOReadAsync(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size, MCCRxCallback) == 0) { + mccDebugPrint("Error:Read data error."); + gLastError = 7; + goto exit; + } + DCInvalidateRange(data, size); + gLastError = 0; + return 1; + } + + if (HIORead(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size) == 0) { + mccDebugPrint("Error:Read data error."); + gLastError = 7; + goto exit; + } + + DCInvalidateRange(data, size); + + if (~(gChannelInfo[chID].eventMask) & 0x10) { + NotifyChannelEvent(chID, 0x10); + } + + if (~(gChannelInfo[chID].eventMask) & 0x40 && gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0x40, 0); + } + gLastError = 0; + return 1; + +exit:; + return 0; +} + +int MCCWrite(MCC_CHANNEL chID, u32 offset, void* data, s32 size, MCC_SYNC_STATE async) { +#ifndef DEBUG + int unused[11]; // fake but blah +#endif + mccDebugPrint("MCCWrite\n"); + + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (!(async == 1 || async == 0)) { + gLastError = 0xD; + return 0; + } + if ((offset & 3) || ((u32)data & 0x1F) || (size % 32) != 0) { + gLastError = 0xD; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + if (gChannelInfo[chID].info.isLocked == 1) { + mccDebugPrint("Error:This channel was locked."); + gLastError = 0x13; + goto exit; + } + if (offset > (gChannelInfo[chID].info.blockLength << 0xD)) { + mccDebugPrint("Error:Invarid offset"); + gLastError = 0x10; + goto exit; + } + if (offset + size > (gChannelInfo[chID].info.blockLength << 0xD)) { + mccDebugPrint("Error:Invarid data size."); + gLastError = 0xF; + goto exit; + } + + if (async == 1) { + if (MCCCheckAsyncDone() == 0) { + mccDebugPrint("Error:Channel busy."); + gLastError = 0x15; + goto exit; + } + AsyncResourceStateBusy(chID, 0x100); + DCFlushRange(data, size); + if (HIOWriteAsync(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size, MCCTxCallback) == 0) { + mccDebugPrint("Error:Write data error."); + gLastError = 8; + goto exit; + } + gLastError = 0; + return 1; + } + + DCFlushRange(data, size); + + if (HIOWrite(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size) == 0) { + mccDebugPrint("Error:Write data error."); + gLastError = 8; + goto exit; + } + + if (~(gChannelInfo[chID].eventMask) & 0x20) { + NotifyChannelEvent(chID, 0x20); + } + + if (~(gChannelInfo[chID].eventMask) & 0x80 && gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0x80, 0); + } + gLastError = 0; + return 1; + +exit: + return 0; +} + +int MCCCheckAsyncDone() { + u16 stat; + u16 mode; + u8 chID; +#ifndef DEBUG + int unused[5]; // fake but blah +#endif + + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + + stat = AsyncResourceGetStat(); + + if (stat == 0x1000) { + return 0; + } else if (stat && stat == 0x2000) { + mode = AsyncResourceGetMode(); + chID = AsyncResourceGetChannel(); + AsyncResourceClearState(); + if (mode == 0) { + if (~(gChannelInfo[chID].eventMask) & 0x10) { + NotifyChannelEvent(chID, 0x10); + } + if (~(gChannelInfo[chID].eventMask) & 0x40 && gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0x40, 0); + } + } else { + if (~(gChannelInfo[chID].eventMask) & 0x20) { + NotifyChannelEvent(chID, 0x20); + } + if (~(gChannelInfo[chID].eventMask) & 0x80 && gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0x80, 0); + } + } + } + + return 1; +} diff --git a/src/dolphin/mcc/tty.c b/src/dolphin/mcc/tty.c new file mode 100644 index 0000000..1c230e4 --- /dev/null +++ b/src/dolphin/mcc/tty.c @@ -0,0 +1,260 @@ +#include +#include + +#ifdef DEBUG +const char* __TTYVersion = "<< Dolphin SDK - TTY\tdebug build: Apr 5 2004 03:57:08 (0x2301) >>"; +#else +const char* __TTYVersion = "<< Dolphin SDK - TTY\trelease build: Apr 5 2004 04:15:50 (0x2301) >>"; +#endif + +volatile static u8 gBuf[0x2000]; + +static u32 gOldEvent; +volatile static MCC_CHANNEL gChID; +volatile static int gQuery; +volatile static u32 gReadDone; +volatile static u32 gPrintfID; +volatile static u32 gBufHead; +volatile static u32 gBufTail; + +// prototypes +static int ttyIsInitialized(void); +static void ShowChannelInfo(MCC_CHANNEL chID); +static void ttyMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value); +static void ttyClearProperty(MCC_CHANNEL chID); +static int ttyWaiting(int timeout, volatile int* flag); +static int ttyWrite(u32 offset, void* data, s32 size); +static int ttyFlush(u32 msgID, BOOL waitResult); + +static int ttyIsInitialized(void) { + BOOL bResult = gChID != 0; + return bResult; +} + +static void ShowChannelInfo(MCC_CHANNEL chID) { + MCC_Info info; + + MCCGetChannelInfo(chID, &info); + OSReport("%2d: FirstBlock:%02d,BlockLength:%02d,Connect:%s,Lock:%s.\n", chID, + info.firstBlock,info.blockLength, + (info.connect == MCC_CONNECT_DISCONNECT) ? "DISCONNECT" : + (info.connect == MCC_CONNECT_HOST_OPEN) ? "HOST_OPEN" : + (info.connect == MCC_CONNECT_TARGET_OPEN) ? "TARGET_OPEN" : + (info.connect == MCC_CONNECT_CONNECTED) ? "CONNECTED" : "UNKNOWN", + (info.isLocked == FALSE) ? "UNLOCKED" : + (info.isLocked == TRUE) ? "LOCKED" : "UNKNOWN"); +} + +static void ttyMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value) { + u32 notify; + u32 size; + u32 msgID; + + switch(event) { + case MCC_EVENT_CONNECT: + gChID = chID; + return; + case MCC_EVENT_DISCONNECT: + gChID = 0; + return; + case MCC_EVENT_UNK_0x100: + notify = (value & (0xF00000)); + switch(notify) { + case 0x200000: + if ((u16)value == 0x210) { + gQuery = 1; + } + return; + case 0x400000: + size = (value >> 8) & 0xFF; + msgID = (value) & 0xFF; + if ((gBufTail - gBufHead) >= 0x2000) { + gBufHead = ((u32) gBufHead < 0x2000U) ? gBufHead : gBufHead - 0x2000; + gBufTail = ((u32) gBufTail < 0x2000U) ? gBufTail : gBufTail - 0x2000; + } + if ((u32) gBufHead >= 0x2000U) { + gBufHead -= 0x2000; + gBufTail -= 0x2000; + } + if (size == 0) { + gBufHead += size << 5; + gReadDone = (u32) msgID; + return; + } + gBufHead += size << 5; + gReadDone = (u32) msgID; + } + } +} + +int TTYInit(MCC_EXI exiChannel, MCC_CHANNEL chID) { + if (ttyIsInitialized()) { + return 0; + } + + OSRegisterVersion(__TTYVersion); + + if (MCCInit(exiChannel, 5, NULL) && MCCOpen(chID, 1, ttyMccChannelEvent)) { + gOldEvent = MCCSetChannelEventMask(chID, 0x30); + ttyClearProperty(chID); + return 1; + } + + return 0; +} + +void TTYExit(void) { + if (ttyIsInitialized()) { + MCCSetChannelEventMask(gChID, gOldEvent); + if (MCCClose(gChID) != 0) { + ttyClearProperty(0); + } + } +} + +int TTYQuery(void) { + u32 tick; + + if (ttyIsInitialized()) { + gQuery = 0; + if (MCCNotify(gChID, 0x100210)) { + return ttyWaiting(5, &gQuery); + } + } + + tick = OSGetTick(); + do {} while(OSTicksToSeconds(OSGetTick() - tick) < 5); + return 0; +} + +int TTYPrintf(const char* format, ...) { + if (ttyIsInitialized() && format != NULL) { + MCC_Hdr* hdr; + u32* id; + char* str; + u32 maxDataSize; + u32 formatLength; + u32 dataSize; + int err; + char* eof; + va_list argptr; + u32 prosecced; + + hdr = (void*)&gBuf; + id = (u32*)(hdr + 1); + str = (char*)(id + 1); + + maxDataSize = 8179; + formatLength = strlen(format); + if (formatLength > maxDataSize) { + eof = (void*)((-1 + maxDataSize + (u32)format)); + *(eof) = 0; + } + + va_start(argptr, format); + err = vsprintf(str, format, argptr); + if (strlen(str) < maxDataSize) { + str[strlen(str)] = 0; + } else { + err = -1; + } + + if (err < 0) { + return 0; + } + + hdr->length = strlen(str) + 13; + hdr->rsvd = 0; + hdr->protocol = 0x210; + dataSize = OSRoundUp32B(hdr->length) & ~1; + if ((0x2000 - (gBufTail - gBufHead)) <= dataSize) { + ttyFlush(gPrintfID, 1); + } + + gPrintfID += 1; + gPrintfID = (u8) gPrintfID; + *id = gPrintfID; + + if ((0x2000 - (gBufTail & 0x1FFF)) < dataSize) { + prosecced = 0x2000 - (gBufTail & 0x1FFF); + ttyWrite(gBufTail & 0x1FFF, (char*)&gBuf, prosecced); + ttyWrite(0, (char*)&gBuf + prosecced, dataSize - prosecced); + } else { + ttyWrite(gBufTail & 0x1FFF, (char*)&gBuf, dataSize); + } + + gBufTail += dataSize; + if (strchr(str, '\n') != 0) { + ttyFlush(gPrintfID, TRUE); + } else if (gPrintfID == 0xFF) { + ttyFlush(gPrintfID, TRUE); + } + + va_end(format); + return 1; + } + + return 0; +} + +int TTYFlush(void) { + if (!ttyIsInitialized()) { + return 0; + } + + return ttyFlush(gPrintfID, TRUE); +} + +static void ttyClearProperty(MCC_CHANNEL chID) { + gChID = chID; + gQuery = 0; + gReadDone = 0; + gPrintfID = 0; + gBufHead = 0; + gBufTail = 0; +} + +static int ttyWaiting(int timeout, volatile int* flag) { + u32 tickStart; + u32 tickDist; + + tickStart = OSGetTick(); + timeout = OSSecondsToTicks(timeout); + while(*flag == 0) { + tickDist = OSGetTick() - tickStart; + tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; + if (OSTicksToSeconds(tickDist) >= timeout) { + return 0; + } + } + + return 1; +} + +static int ttyWrite(u32 offset, void* data, s32 size) { + if (MCCWrite(gChID, offset, data, size, 0)) { + return 1; + } + return 0; +} + +static int ttyFlush(u32 msgID, BOOL waitResult) { + u32 notify; + + notify = msgID | 0x300000; + + if ((gBufTail - gBufHead) == 0) { + return 1; + } + + if (MCCNotify(gChID, notify) == 0) { + while(1) + ; + } + + if (waitResult) { + do {} while (gReadDone != msgID); + } + + return 1; +} diff --git a/src/dolphin/mix/mix.c b/src/dolphin/mix/mix.c new file mode 100644 index 0000000..1ec6539 --- /dev/null +++ b/src/dolphin/mix/mix.c @@ -0,0 +1,1035 @@ +#include +#include + +u16 __MIXVolumeTable[965] = { + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 15, 15, 15, + 15, 15, 16, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 18, 18, 18, 18, + 18, 19, 19, 19, 19, 19, 20, 20, + 20, 20, 21, 21, 21, 21, 22, 22, + 22, 22, 23, 23, 23, 24, 24, 24, + 24, 25, 25, 25, 26, 26, 26, 26, + 27, 27, 27, 28, 28, 28, 29, 29, + 29, 30, 30, 30, 31, 31, 32, 32, + 32, 33, 33, 33, 34, 34, 35, 35, + 35, 36, 36, 37, 37, 38, 38, 38, + 39, 39, 40, 40, 41, 41, 42, 42, + 43, 43, 44, 44, 45, 45, 46, 46, + 47, 47, 48, 49, 49, 50, 50, 51, + 51, 52, 53, 53, 54, 55, 55, 56, + 56, 57, 58, 58, 59, 60, 61, 61, + 62, 63, 63, 64, 65, 66, 66, 67, + 68, 69, 70, 70, 71, 72, 73, 74, + 75, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, + 98, 100, 101, 102, 103, 104, 106, 107, + 108, 109, 111, 112, 113, 114, 116, 117, + 118, 120, 121, 123, 124, 126, 127, 128, + 130, 131, 133, 135, 136, 138, 139, 141, + 143, 144, 146, 148, 149, 151, 153, 155, + 156, 158, 160, 162, 164, 166, 168, 170, + 171, 173, 175, 178, 180, 182, 184, 186, + 188, 190, 192, 195, 197, 199, 202, 204, + 206, 209, 211, 214, 216, 219, 221, 224, + 226, 229, 231, 234, 237, 240, 242, 245, + 248, 251, 254, 257, 260, 263, 266, 269, + 272, 275, 278, 282, 285, 288, 292, 295, + 298, 302, 305, 309, 312, 316, 320, 323, + 327, 331, 335, 339, 343, 347, 351, 355, + 359, 363, 367, 371, 376, 380, 384, 389, + 393, 398, 403, 407, 412, 417, 422, 427, + 431, 436, 442, 447, 452, 457, 462, 468, + 473, 479, 484, 490, 495, 501, 507, 513, + 519, 525, 531, 537, 543, 550, 556, 562, + 569, 576, 582, 589, 596, 603, 610, 617, + 624, 631, 638, 646, 653, 661, 669, 676, + 684, 692, 700, 708, 716, 725, 733, 742, + 750, 759, 768, 777, 786, 795, 804, 813, + 823, 832, 842, 852, 861, 871, 881, 892, + 902, 912, 923, 934, 945, 955, 967, 978, + 989, 1001, 1012, 1024, 1036, 1048, 1060, 1072, + 1085, 1097, 1110, 1123, 1136, 1149, 1162, 1176, + 1189, 1203, 1217, 1231, 1245, 1260, 1274, 1289, + 1304, 1319, 1334, 1350, 1365, 1381, 1397, 1414, + 1430, 1446, 1463, 1480, 1497, 1515, 1532, 1550, + 1568, 1586, 1604, 1623, 1642, 1661, 1680, 1700, + 1719, 1739, 1759, 1780, 1800, 1821, 1842, 1864, + 1885, 1907, 1929, 1951, 1974, 1997, 2020, 2043, + 2067, 2091, 2115, 2140, 2164, 2190, 2215, 2241, + 2266, 2293, 2319, 2346, 2373, 2401, 2429, 2457, + 2485, 2514, 2543, 2573, 2602, 2632, 2663, 2694, + 2725, 2757, 2789, 2821, 2853, 2887, 2920, 2954, + 2988, 3023, 3058, 3093, 3129, 3165, 3202, 3239, + 3276, 3314, 3353, 3391, 3431, 3470, 3511, 3551, + 3592, 3634, 3676, 3719, 3762, 3805, 3849, 3894, + 3939, 3985, 4031, 4078, 4125, 4173, 4221, 4270, + 4319, 4369, 4420, 4471, 4523, 4575, 4628, 4682, + 4736, 4791, 4846, 4902, 4959, 5017, 5075, 5133, + 5193, 5253, 5314, 5375, 5438, 5501, 5564, 5629, + 5694, 5760, 5827, 5894, 5962, 6031, 6101, 6172, + 6243, 6316, 6389, 6463, 6538, 6613, 6690, 6767, + 6846, 6925, 7005, 7086, 7168, 7251, 7335, 7420, + 7506, 7593, 7681, 7770, 7860, 7951, 8043, 8136, + 8230, 8326, 8422, 8520, 8618, 8718, 8819, 8921, + 9025, 9129, 9235, 9342, 9450, 9559, 9670, 9782, + 9895, 10010, 10126, 10243, 10362, 10482, 10603, 10726, + 10850, 10976, 11103, 11231, 11361, 11493, 11626, 11761, + 11897, 12035, 12174, 12315, 12458, 12602, 12748, 12895, + 13045, 13196, 13349, 13503, 13659, 13818, 13978, 14140, + 14303, 14469, 14636, 14806, 14977, 15151, 15326, 15504, + 15683, 15865, 16049, 16234, 16422, 16613, 16805, 17000, + 17196, 17396, 17597, 17801, 18007, 18215, 18426, 18640, + 18856, 19074, 19295, 19518, 19744, 19973, 20204, 20438, + 20675, 20914, 21156, 21401, 21649, 21900, 22153, 22410, + 22669, 22932, 23197, 23466, 23738, 24013, 24291, 24572, + 24857, 25144, 25436, 25730, 26028, 26329, 26634, 26943, + 27255, 27570, 27890, 28213, 28539, 28870, 29204, 29542, + 29884, 30230, 30580, 30934, 31293, 31655, 32022, 32392, + 32767, 33147, 33531, 33919, 34312, 34709, 35111, 35518, + 35929, 36345, 36766, 37192, 37622, 38058, 38499, 38944, + 39395, 39851, 40313, 40780, 41252, 41730, 42213, 42702, + 43196, 43696, 44202, 44714, 45232, 45756, 46286, 46821, + 47364, 47912, 48467, 49028, 49596, 50170, 50751, 51339, + 51933, 52535, 53143, 53758, 54381, 55011, 55648, 56292, + 56944, 57603, 58270, 58945, 59627, 60318, 61016, 61723, + 62438, 63161, 63892, 64632, 65380 +}; + +int __MIXPanTable[128] = { + 0x00000000, + 0x00000000, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFE, + 0xFFFFFFFE, + 0xFFFFFFFE, + 0xFFFFFFFD, + 0xFFFFFFFD, + 0xFFFFFFFC, + 0xFFFFFFFC, + 0xFFFFFFFC, + 0xFFFFFFFB, + 0xFFFFFFFB, + 0xFFFFFFFB, + 0xFFFFFFFA, + 0xFFFFFFFA, + 0xFFFFFFF9, + 0xFFFFFFF9, + 0xFFFFFFF9, + 0xFFFFFFF8, + 0xFFFFFFF8, + 0xFFFFFFF7, + 0xFFFFFFF7, + 0xFFFFFFF6, + 0xFFFFFFF6, + 0xFFFFFFF6, + 0xFFFFFFF5, + 0xFFFFFFF5, + 0xFFFFFFF4, + 0xFFFFFFF4, + 0xFFFFFFF3, + 0xFFFFFFF3, + 0xFFFFFFF2, + 0xFFFFFFF2, + 0xFFFFFFF2, + 0xFFFFFFF1, + 0xFFFFFFF1, + 0xFFFFFFF0, + 0xFFFFFFF0, + 0xFFFFFFEF, + 0xFFFFFFEF, + 0xFFFFFFEE, + 0xFFFFFFEE, + 0xFFFFFFED, + 0xFFFFFFEC, + 0xFFFFFFEC, + 0xFFFFFFEB, + 0xFFFFFFEB, + 0xFFFFFFEA, + 0xFFFFFFEA, + 0xFFFFFFE9, + 0xFFFFFFE9, + 0xFFFFFFE8, + 0xFFFFFFE7, + 0xFFFFFFE7, + 0xFFFFFFE6, + 0xFFFFFFE6, + 0xFFFFFFE5, + 0xFFFFFFE4, + 0xFFFFFFE4, + 0xFFFFFFE3, + 0xFFFFFFE2, + 0xFFFFFFE2, + 0xFFFFFFE1, + 0xFFFFFFE0, + 0xFFFFFFDF, + 0xFFFFFFDF, + 0xFFFFFFDE, + 0xFFFFFFDD, + 0xFFFFFFDC, + 0xFFFFFFDC, + 0xFFFFFFDB, + 0xFFFFFFDA, + 0xFFFFFFD9, + 0xFFFFFFD8, + 0xFFFFFFD8, + 0xFFFFFFD7, + 0xFFFFFFD6, + 0xFFFFFFD5, + 0xFFFFFFD4, + 0xFFFFFFD3, + 0xFFFFFFD2, + 0xFFFFFFD1, + 0xFFFFFFD0, + 0xFFFFFFCF, + 0xFFFFFFCE, + 0xFFFFFFCD, + 0xFFFFFFCC, + 0xFFFFFFCA, + 0xFFFFFFC9, + 0xFFFFFFC8, + 0xFFFFFFC7, + 0xFFFFFFC5, + 0xFFFFFFC4, + 0xFFFFFFC3, + 0xFFFFFFC1, + 0xFFFFFFC0, + 0xFFFFFFBE, + 0xFFFFFFBD, + 0xFFFFFFBB, + 0xFFFFFFB9, + 0xFFFFFFB8, + 0xFFFFFFB6, + 0xFFFFFFB4, + 0xFFFFFFB2, + 0xFFFFFFB0, + 0xFFFFFFAD, + 0xFFFFFFAB, + 0xFFFFFFA9, + 0xFFFFFFA6, + 0xFFFFFFA3, + 0xFFFFFFA0, + 0xFFFFFF9D, + 0xFFFFFF9A, + 0xFFFFFF96, + 0xFFFFFF92, + 0xFFFFFF8D, + 0xFFFFFF88, + 0xFFFFFF82, + 0xFFFFFF7B, + 0xFFFFFF74, + 0xFFFFFF6A, + 0xFFFFFF5D, + 0xFFFFFF4C, + 0xFFFFFF2E, + 0xFFFFFC78 +}; + +s16 __MIX_DPL2_front[128] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFD, 0xFFFD, + 0xFFFD, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFB, 0xFFFB, + 0xFFFA, 0xFFFA, 0xFFFA, 0xFFF9, 0xFFF9, 0xFFF8, + 0xFFF8, 0xFFF7, 0xFFF7, 0xFFF6, 0xFFF5, 0xFFF5, + 0xFFF4, 0xFFF4, 0xFFF3, 0xFFF2, 0xFFF2, 0xFFF1, + 0xFFF0, 0xFFEF, 0xFFEF, 0xFFEE, 0xFFED, 0xFFEC, + 0xFFEB, 0xFFEB, 0xFFEA, 0xFFE9, 0xFFE8, 0xFFE7, + 0xFFE6, 0xFFE5, 0xFFE4, 0xFFE3, 0xFFE2, 0xFFE1, + 0xFFE0, 0xFFDE, 0xFFDD, 0xFFDC, 0xFFDB, 0xFFDA, + 0xFFD8, 0xFFD7, 0xFFD6, 0xFFD4, 0xFFD3, 0xFFD1, + 0xFFD0, 0xFFCE, 0xFFCC, 0xFFCB, 0xFFC9, 0xFFC7, + 0xFFC6, 0xFFC4, 0xFFC2, 0xFFC0, 0xFFBE, 0xFFBC, + 0xFFBA, 0xFFB7, 0xFFB5, 0xFFB3, 0xFFB0, 0xFFAE, + 0xFFAB, 0xFFA8, 0xFFA6, 0xFFA3, 0xFFA0, 0xFF9C, + 0xFF99, 0xFF96, 0xFF92, 0xFF8E, 0xFF8A, 0xFF86, + 0xFF82, 0xFF7D, 0xFF78, 0xFF73, 0xFF6E, 0xFF68, + 0xFF61, 0xFF5A, 0xFF53, 0xFF4B, 0xFF42, 0xFF37, + 0xFF2C, 0xFF1F, 0xFF0F, 0xFEFB, 0xFEE2, 0xFEBF, + 0xFE83, 0xFC40 +}; + +s16 __MIX_DPL2_rear[128] = { + 0xFFC3, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC5, 0xFFC6, + 0xFFC6, 0xFFC7, 0xFFC8, 0xFFC8, 0xFFC9, 0xFFC9, + 0xFFCA, 0xFFCB, 0xFFCB, 0xFFCC, 0xFFCC, 0xFFCD, + 0xFFCE, 0xFFCE, 0xFFCF, 0xFFCF, 0xFFD0, 0xFFD0, + 0xFFD1, 0xFFD1, 0xFFD2, 0xFFD2, 0xFFD3, 0xFFD3, + 0xFFD4, 0xFFD4, 0xFFD5, 0xFFD5, 0xFFD6, 0xFFD6, + 0xFFD7, 0xFFD7, 0xFFD8, 0xFFD8, 0xFFD9, 0xFFD9, + 0xFFDA, 0xFFDA, 0xFFDA, 0xFFDB, 0xFFDB, 0xFFDC, + 0xFFDC, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDE, 0xFFDE, + 0xFFDF, 0xFFDF, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE1, + 0xFFE1, 0xFFE1, 0xFFE2, 0xFFE2, 0xFFE3, 0xFFE3, + 0xFFE3, 0xFFE4, 0xFFE4, 0xFFE4, 0xFFE5, 0xFFE5, + 0xFFE5, 0xFFE6, 0xFFE6, 0xFFE6, 0xFFE7, 0xFFE7, + 0xFFE7, 0xFFE8, 0xFFE8, 0xFFE8, 0xFFE9, 0xFFE9, + 0xFFE9, 0xFFEA, 0xFFEA, 0xFFEA, 0xFFEB, 0xFFEB, + 0xFFEB, 0xFFEC, 0xFFEC, 0xFFEC, 0xFFEC, 0xFFED, + 0xFFED, 0xFFED, 0xFFEE, 0xFFEE, 0xFFEE, 0xFFEE, + 0xFFEF, 0xFFEF, 0xFFEF, 0xFFEF, 0xFFF0, 0xFFF0, + 0xFFF0, 0xFFF0, 0xFFF1, 0xFFF1, 0xFFF1, 0xFFF1, + 0xFFF2, 0xFFF2, 0xFFF2, 0xFFF2, 0xFFF3, 0xFFF3, + 0xFFF3, 0xFFF3, 0xFFF3, 0xFFF4, 0xFFF4, 0xFFF4, + 0xFFF4, 0xFFF5 +}; + +u8 __MIXAIVolumeTable[50] = { + 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x02, + 0x02, 0x02, 0x02, 0x03, + 0x03, 0x04, 0x04, 0x05, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, + 0x0E, 0x10, 0x12, 0x14, + 0x16, 0x19, 0x1C, 0x20, + 0x24, 0x28, 0x2D, 0x32, + 0x39, 0x40, 0x47, 0x50, + 0x5A, 0x65, 0x71, 0x7F, + 0x8F, 0xA0, 0xB4, 0xCA, + 0xE3, 0xFF +}; + +static MIXChannel __MIXChannel[64]; + +static int __MIXDvdStreamAttenCurrent; +static int __MIXDvdStreamAttenUser; +static u32 __MIXSoundMode; + +// prototypes +static u16 __MIXGetVolume(int db); +static int __MIXGetPanL(int pan); +static int __MIXGetPanR(int pan); +static void __MIXResetChannel(MIXChannel* channel); +static void __MIXSetPan(MIXChannel* channel); +static int __MIXClampPan(int pan); + +static u16 __MIXGetVolume(int db_) { + int db = db_; + if (db <= -0x388) { + return 0; + } + if (db >= 0x3C) { + return 0xFF64; + } + return __MIXVolumeTable[db + 0x388]; +} + +static void __MIXSetPan(MIXChannel* channel) { + int pan, span; + int ipan, ispan; + + ASSERTLINE(281, (channel->pan <= 127) && (channel->pan >= 0)); + ASSERTLINE(282, (channel->span <= 127) && (channel->span >= 0)); + + pan = channel->pan; + ipan = 127 - pan; + span = channel->span; + ispan = 127 - span; + + if (__MIXSoundMode == MIX_SOUND_MODE_DPL2) { + channel->l = __MIX_DPL2_front[pan]; + channel->r = __MIX_DPL2_front[ipan]; + channel->f = __MIX_DPL2_front[ispan]; + channel->b = __MIX_DPL2_front[span]; + channel->l1 = __MIX_DPL2_rear[ipan]; + channel->r1 = __MIX_DPL2_rear[pan]; + } else { + channel->l = __MIXPanTable[pan]; + channel->r = __MIXPanTable[ipan]; + channel->f = __MIXPanTable[ispan]; + channel->b = __MIXPanTable[span]; + } +} + +static void __MIXResetChannel(MIXChannel* channel) { + channel->mode = 0x50000000; + channel->input = 0; + channel->auxA = -0x3C0; + channel->auxB = -0x3C0; + channel->fader = 0; + channel->pan = 0x40; + channel->span = 0x7F; + + channel->v = channel->vL = channel->vR = channel->vS = channel->vAL = + channel->vAR = channel->vAS = channel->vBL = channel->vBR = channel->vBS = 0; + + __MIXSetPan(channel); +} + +static int __MIXClampPan(int pan) { + if (pan < 0) { + return 0; + } + if (pan > 0x7F) { + return 0x7F; + } + return pan; +} + +void MIXInit(void) { + int i; + + for (i = 0; i < 64; i++) { + __MIXResetChannel(&__MIXChannel[i]); + } + + __MIXDvdStreamAttenCurrent = 0; + __MIXDvdStreamAttenUser = 0; + __MIXSoundMode = MIX_SOUND_MODE_STEREO; +} + +void MIXQuit(void) {} + +void MIXSetSoundMode(u32 mode) { + ASSERTLINE(421, (mode == MIX_SOUND_MODE_MONO) || (mode == MIX_SOUND_MODE_STEREO) || + (mode == MIX_SOUND_MODE_SURROUND) || (mode == MIX_SOUND_MODE_DPL2)); + __MIXSoundMode = mode; +} + +u32 MIXGetSoundMode(void) { + return __MIXSoundMode; +} + +void MIXInitChannel(AXVPB* axvpb, u32 mode, int input, int auxA, int auxB, int pan, int span, int fader) { + BOOL old; + MIXChannel* c; + u16 mixerCtrl; + u16* p; + + ASSERTLINE(478, axvpb); + + c = &__MIXChannel[axvpb->index]; + + c->axvpb = axvpb; + c->mode = mode & 7; + c->input = input; + c->auxA = auxA; + c->auxB = auxB; + c->pan = pan; + c->span = span; + c->fader = fader; + + __MIXSetPan(c); + + if (c->mode & 4) { + c->v = 0; + } else { + c->v = __MIXGetVolume(input); + } + + mixerCtrl = 0; + + switch(__MIXSoundMode) { + case MIX_SOUND_MODE_MONO: + c->vL = __MIXGetVolume(c->fader + c->f); + c->vR = __MIXGetVolume(c->fader + c->f); + c->vS = __MIXGetVolume(c->fader + c->b - 30); + + if (c->mode & 1) { + c->vAL = __MIXGetVolume(c->auxA + c->f); + c->vAR = __MIXGetVolume(c->auxA + c->f); + c->vAS = __MIXGetVolume(c->auxA + c->b - 30); + } else { + c->vAL = __MIXGetVolume(c->fader + c->auxA + c->f); + c->vAR = __MIXGetVolume(c->fader + c->auxA + c->f); + c->vAS = __MIXGetVolume(c->fader + c->auxA + c->b - 30); + } + + if (c->mode & 2) { + c->vBL = __MIXGetVolume(c->auxB + c->f); + c->vBR = __MIXGetVolume(c->auxB + c->f); + c->vBS = __MIXGetVolume(c->auxB + c->b - 30); + } else { + c->vBL = __MIXGetVolume(c->fader + c->auxB + c->f); + c->vBR = __MIXGetVolume(c->fader + c->auxB + c->f); + c->vBS = __MIXGetVolume(c->fader + c->auxB + c->b - 30); + } + break; + case MIX_SOUND_MODE_STEREO: + case MIX_SOUND_MODE_SURROUND: + c->vL = __MIXGetVolume(c->fader + c->l + c->f); + c->vR = __MIXGetVolume(c->fader + c->r + c->f); + c->vS = __MIXGetVolume(c->fader + c->b - 30); + + if (c->mode & 1) { + c->vAL = __MIXGetVolume(c->auxA + c->l + c->f); + c->vAR = __MIXGetVolume(c->auxA + c->r + c->f); + c->vAS = __MIXGetVolume(c->auxA + c->b - 30); + } else { + c->vAL = __MIXGetVolume(c->fader + c->auxA + c->l + c->f); + c->vAR = __MIXGetVolume(c->fader + c->auxA + c->r + c->f); + c->vAS = __MIXGetVolume(c->fader + c->auxA + c->b - 30); + } + + if (c->mode & 2) { + c->vBL = __MIXGetVolume(c->auxB + c->l + c->f); + c->vBR = __MIXGetVolume(c->auxB + c->r + c->f); + c->vBS = __MIXGetVolume(c->auxB + c->b - 30); + } else { + c->vBL = __MIXGetVolume(c->fader + c->auxB + c->l + c->f); + c->vBR = __MIXGetVolume(c->fader + c->auxB + c->r + c->f); + c->vBS = __MIXGetVolume(c->fader + c->auxB + c->b - 30); + } + break; + case MIX_SOUND_MODE_DPL2: + c->vL = __MIXGetVolume(c->fader + c->l + c->f); + c->vR = __MIXGetVolume(c->fader + c->r + c->f); + c->vBL = __MIXGetVolume(c->fader + c->l1 + c->b); + c->vBR = __MIXGetVolume(c->fader + c->r1 + c->b); + + if (c->mode & 1) { + c->vAL = __MIXGetVolume(c->auxA + c->l + c->f); + c->vAR = __MIXGetVolume(c->auxA + c->r + c->f); + c->vAS = __MIXGetVolume(c->auxA + c->l1 + c->b); + c->vBS = __MIXGetVolume(c->auxA + c->r1 + c->b); + } else { + c->vAL = __MIXGetVolume(c->fader + c->auxA + c->l + c->f); + c->vAR = __MIXGetVolume(c->fader + c->auxA + c->r + c->f); + c->vAS = __MIXGetVolume(c->fader + c->auxA + c->l1 + c->b); + c->vBS = __MIXGetVolume(c->fader + c->auxA + c->r1 + c->b); + } + + mixerCtrl |= 0x4000; + break; + } + + old = OSDisableInterrupts(); + axvpb->pb.ve.currentVolume = c->v; + axvpb->pb.ve.currentDelta = 0; + + p = (u16*)&axvpb->pb.mix; + + if ((*p++ = c->vL)) + mixerCtrl |= 0x1; + *p++ = 0; + + if ((*p++ = c->vR)) + mixerCtrl |= 0x2; + *p++ = 0; + + if ((*p++ = c->vAL)) + mixerCtrl |= 0x10; + *p++ = 0; + + if ((*p++ = c->vAR)) + mixerCtrl |= 0x20; + *p++ = 0; + + if ((*p++ = c->vBL)) + mixerCtrl |= 0x200; + *p++ = 0; + + if ((*p++ = c->vBR)) + mixerCtrl |= 0x400; + *p++ = 0; + + if ((*p++ = c->vBS)) + mixerCtrl |= 0x1000; + *p++ = 0; + + if ((*p++ = c->vS)) + mixerCtrl |= 0x4; + *p++ = 0; + + if ((*p++ = c->vAS)) + mixerCtrl |= 0x80; + *p++ = 0; + + axvpb->pb.mixerCtrl = mixerCtrl; + axvpb->sync |= (AX_SYNC_FLAG_COPYMXRCTRL | AX_SYNC_FLAG_COPYAXPBMIX | AX_SYNC_FLAG_COPYVOL); + OSRestoreInterrupts(old); +} + +void MIXReleaseChannel(AXVPB* axvpb) { + ASSERTLINE(657, axvpb); + __MIXChannel[axvpb->index].axvpb = 0; +} + +void MIXResetControls(AXVPB* p) { + __MIXResetChannel(&__MIXChannel[p->index]); +} + +void MIXSetInput(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->input = dB; + channel->mode |= 0x10000000; +} + +void MIXAdjustInput(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->input += dB; + channel->mode |= 0x10000000; +} + +int MIXGetInput(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->input; +} + +void MIXAuxAPostFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode &= 0xFFFFFFFE; + channel->mode |= 0x40000000; +} + +void MIXAuxAPreFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode |= 0x40000001; +} + +int MIXAuxAIsPostFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + if (channel->mode & 1) { + return 0; + } + return 1; +} + +void MIXSetAuxA(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->auxA = dB; + channel->mode |= 0x40000000; +} + +void MIXAdjustAuxA(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->auxA += dB; + channel->mode |= 0x40000000; +} + +int MIXGetAuxA(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->auxA; +} + +void MIXAuxBPostFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode &= 0xFFFFFFFD; + channel->mode |= 0x40000000; +} + +void MIXAuxBPreFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode |= 0x40000002; +} + +int MIXAuxBIsPostFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + if (channel->mode & 2) { + return 0; + } + return 1; +} + +void MIXSetAuxB(AXVPB* p, int dB) { + MIXChannel* channel; + if (__MIXSoundMode == MIX_SOUND_MODE_DPL2) + return; + + channel = &__MIXChannel[p->index]; + channel->auxB = dB; + channel->mode |= 0x40000000; +} + +void MIXAdjustAuxB(AXVPB* p, int dB) { + MIXChannel* channel; + if (__MIXSoundMode == MIX_SOUND_MODE_DPL2) + return; + + channel = &__MIXChannel[p->index]; + channel->auxB += dB; + channel->mode |= 0x40000000; +} + +int MIXGetAuxB(AXVPB* p) { + MIXChannel* channel; + if (__MIXSoundMode == MIX_SOUND_MODE_DPL2) + return -0x3C0; + + channel = &__MIXChannel[p->index]; + return channel->auxB; +} + +void MIXSetPan(AXVPB* p, int pan) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->pan = __MIXClampPan(pan); + __MIXSetPan(channel); + channel->mode |= 0x40000000; +} + +void MIXAdjustPan(AXVPB* p, int pan) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->pan = __MIXClampPan(channel->pan + pan); + __MIXSetPan(channel); + channel->mode |= 0x40000000; +} + +int MIXGetPan(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->pan; +} + +void MIXSetSPan(AXVPB* p, int span) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->span = __MIXClampPan(span); + __MIXSetPan(channel); + channel->mode |= 0x40000000; +} + +void MIXAdjustSPan(AXVPB* p, int span) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->span = __MIXClampPan(channel->span + span); + __MIXSetPan(channel); + channel->mode |= 0x40000000; +} + +int MIXGetSPan(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->span; +} + +void MIXMute(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode |= 0x10000004; +} + +void MIXUnMute(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode &= 0xFFFFFFFB; + channel->mode |= 0x10000000; +} + +int MIXIsMute(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + if (channel->mode & 4) { + return 1; + } + return 0; +} + +void MIXSetFader(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->fader = dB; + channel->mode |= 0x40000000; +} + +void MIXAdjustFader(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->fader += dB; + channel->mode |= 0x40000000; +} + +int MIXGetFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->fader; +} + +void MIXSetDvdStreamFader(int dB) { + int db; + + db = dB; + if (db < -0x31) { + db = -0x31; + } + if (db > 0) { + db = 0; + } + __MIXDvdStreamAttenUser = db; +} + +int MIXGetDvdStreamFader(void) { + return __MIXDvdStreamAttenUser; +} + +void MIXUpdateSettings(void) { + int i; + int setNewMixLevel; + int setNewInputLevel; + MIXChannel* c; + AXVPB* axvpb; + u16 mixerCtrl; + u16* p; + + for (i = 0; i < AX_MAX_VOICES; i++) { + setNewInputLevel = 0; + setNewMixLevel = 0; + + c = &__MIXChannel[i]; + axvpb = c->axvpb; + + if (axvpb) { + mixerCtrl = 0; + + if (c->mode & 0x20000000) { + c->v = c->v1; + c->mode &= ~0x20000000; + setNewInputLevel = TRUE; + } + + if (c->mode & 0x10000000) { + if (c->mode & 4) { + c->v1 = 0; + } else { + c->v1 = __MIXGetVolume(c->input); + } + + c->mode &= ~0x10000000; + c->mode |= 0x20000000; + setNewInputLevel = TRUE; + } + + if (c->mode & 0x80000000) { + c->vL = c->vL1; + c->vR = c->vR1; + c->vS = c->vS1; + c->vAL = c->vAL1; + c->vAR = c->vAR1; + c->vAS = c->vAS1; + c->vBL = c->vBL1; + c->vBR = c->vBR1; + c->vBS = c->vBS1; + + c->mode &= ~0x80000000; + setNewMixLevel = TRUE; + } + + if (c->mode & 0x40000000) { + switch(__MIXSoundMode) { + case MIX_SOUND_MODE_MONO: + c->vL1 = __MIXGetVolume(c->fader + c->f); + c->vR1 = __MIXGetVolume(c->fader + c->f); + c->vS1 = __MIXGetVolume(c->fader + c->b - 30); + + if (c->mode & 1) { + c->vAL1 = __MIXGetVolume(c->auxA + c->f); + c->vAR1 = __MIXGetVolume(c->auxA + c->f); + c->vAS1 = __MIXGetVolume(c->auxA + c->b - 30); + } else { + c->vAL1 = __MIXGetVolume(c->fader + c->auxA + c->f); + c->vAR1 = __MIXGetVolume(c->fader + c->auxA + c->f); + c->vAS1 = __MIXGetVolume(c->fader + c->auxA + c->b - 30); + } + + if (c->mode & 2) { + c->vBL1 = __MIXGetVolume(c->auxB + c->f); + c->vBR1 = __MIXGetVolume(c->auxB + c->f); + c->vBS1 = __MIXGetVolume(c->auxB + c->b - 30); + } else { + c->vBL1 = __MIXGetVolume(c->fader + c->auxB + c->f); + c->vBR1 = __MIXGetVolume(c->fader + c->auxB + c->f); + c->vBS1 = __MIXGetVolume(c->fader + c->auxB + c->b - 30); + } + break; + case MIX_SOUND_MODE_STEREO: + case MIX_SOUND_MODE_SURROUND: + c->vL1 = __MIXGetVolume(c->fader + c->l + c->f); + c->vR1 = __MIXGetVolume(c->fader + c->r + c->f); + c->vS1 = __MIXGetVolume(c->fader + c->b - 30); + + if (c->mode & 1) { + c->vAL1 = __MIXGetVolume(c->auxA + c->l + c->f); + c->vAR1 = __MIXGetVolume(c->auxA + c->r + c->f); + c->vAS1 = __MIXGetVolume(c->auxA + c->b - 30); + } else { + c->vAL1 = __MIXGetVolume(c->fader + c->auxA + c->l + c->f); + c->vAR1 = __MIXGetVolume(c->fader + c->auxA + c->r + c->f); + c->vAS1 = __MIXGetVolume(c->fader + c->auxA + c->b - 30); + } + + if (c->mode & 2) { + c->vBL1 = __MIXGetVolume(c->auxB + c->l + c->f); + c->vBR1 = __MIXGetVolume(c->auxB + c->r + c->f); + c->vBS1 = __MIXGetVolume(c->auxB + c->b - 30); + } else { + c->vBL1 = __MIXGetVolume(c->fader + c->auxB + c->l + c->f); + c->vBR1 = __MIXGetVolume(c->fader + c->auxB + c->r + c->f); + c->vBS1 = __MIXGetVolume(c->fader + c->auxB + c->b - 30); + } + break; + case MIX_SOUND_MODE_DPL2: + c->vL1 = __MIXGetVolume(c->fader + c->l + c->f); + c->vR1 = __MIXGetVolume(c->fader + c->r + c->f); + c->vBL1 = __MIXGetVolume(c->fader + c->l1 + c->b); + c->vBR1 = __MIXGetVolume(c->fader + c->r1 + c->b); + + if (c->mode & 1) { + c->vAL1 = __MIXGetVolume(c->auxA + c->l + c->f); + c->vAR1 = __MIXGetVolume(c->auxA + c->r + c->f); + c->vAS1 = __MIXGetVolume(c->auxA + c->l1 + c->b); + c->vBS1 = __MIXGetVolume(c->auxA + c->r1 + c->b); + } else { + c->vAL1 = __MIXGetVolume(c->fader + c->auxA + c->l + c->f); + c->vAR1 = __MIXGetVolume(c->fader + c->auxA + c->r + c->f); + c->vAS1 = __MIXGetVolume(c->fader + c->auxA + c->l1 + c->b); + c->vBS1 = __MIXGetVolume(c->fader + c->auxA + c->r1 + c->b); + } + + mixerCtrl |= 0x4000; + break; + } + + c->mode &= ~0x40000000; + c->mode |= 0x80000000; + setNewMixLevel = TRUE; + } + + if (setNewInputLevel) { + axvpb->pb.ve.currentVolume = c->v; + axvpb->pb.ve.currentDelta = (s16)((c->v1 - c->v) / 160); + axvpb->sync |= 0x200; + } + + if (setNewMixLevel) { + p = (u16*)&axvpb->pb.mix; + + if ((*p++ = c->vL)) + mixerCtrl |= 0x1; + + if ((*p++ = (u16)((c->vL1 - c->vL) / 160))) + mixerCtrl |= 0x8; + + if ((*p++ = c->vR)) + mixerCtrl |= 0x2; + + if ((*p++ = (u16)((c->vR1 - c->vR) / 160))) + mixerCtrl |= 0x8; + + if ((*p++ = c->vAL)) + mixerCtrl |= 0x10; + + if ((*p++ = (u16)((c->vAL1 - c->vAL) / 160))) + mixerCtrl |= 0x40; + + if ((*p++ = c->vAR)) + mixerCtrl |= 0x20; + + if ((*p++ = (u16)((c->vAR1 - c->vAR) / 160))) + mixerCtrl |= 0x40; + + if ((*p++ = c->vBL)) + mixerCtrl |= 0x200; + + if ((*p++ = (u16)((c->vBL1 - c->vBL) / 160))) + mixerCtrl |= 0x800; + + if ((*p++ = c->vBR)) + mixerCtrl |= 0x400; + + if ((*p++ = (u16)((c->vBR1 - c->vBR) / 160))) + mixerCtrl |= 0x800; + + if ((*p++ = c->vBS)) + mixerCtrl |= 0x1000; + + if ((*p++ = (u16)((c->vBS1 - c->vBS) / 160))) + mixerCtrl |= 0x2000; + + if ((*p++ = c->vS)) + mixerCtrl |= 0x4; + + if ((*p++ = (u16)((c->vS1 - c->vS) / 160))) + mixerCtrl |= 0x8; + + if ((*p++ = c->vAS)) + mixerCtrl |= 0x80; + + if ((*p++ = (u16)((c->vAS1 - c->vAS) / 160))) + mixerCtrl |= 0x100; + + axvpb->pb.mixerCtrl = mixerCtrl; + axvpb->sync |= 0x12; + } + } + } + + if (__MIXDvdStreamAttenUser > __MIXDvdStreamAttenCurrent) { + __MIXDvdStreamAttenCurrent++; + AISetStreamVolLeft(__MIXAIVolumeTable[__MIXDvdStreamAttenCurrent]); + AISetStreamVolRight(__MIXAIVolumeTable[__MIXDvdStreamAttenCurrent]); + } else if (__MIXDvdStreamAttenUser < __MIXDvdStreamAttenCurrent) { + __MIXDvdStreamAttenCurrent--; + AISetStreamVolLeft(__MIXAIVolumeTable[__MIXDvdStreamAttenCurrent]); + AISetStreamVolRight(__MIXAIVolumeTable[__MIXDvdStreamAttenCurrent]); + } +} diff --git a/src/dolphin/mtx/mtx.c b/src/dolphin/mtx/mtx.c new file mode 100644 index 0000000..66b850f --- /dev/null +++ b/src/dolphin/mtx/mtx.c @@ -0,0 +1,1197 @@ +#include +#include +#include "fake_tgmath.h" + +static f32 Unit01[2] = { + 0.0f, + 1.0f +}; + +void C_MTXIdentity(Mtx m) { + ASSERTMSGLINE(189, m, "MtxIdentity(): NULL Mtx 'm' "); + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = 0; +} + +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 + } +} + +void C_MTXCopy(const Mtx src, Mtx dst) { + ASSERTMSGLINE(250, src, "MTXCopy(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(251, dst, "MTXCopy(): NULL MtxPtr 'dst' "); + if (src != dst) { + dst[0][0] = src[0][0]; + dst[0][1] = src[0][1]; + dst[0][2] = src[0][2]; + dst[0][3] = src[0][3]; + dst[1][0] = src[1][0]; + dst[1][1] = src[1][1]; + dst[1][2] = src[1][2]; + dst[1][3] = src[1][3]; + dst[2][0] = src[2][0]; + dst[2][1] = src[2][1]; + dst[2][2] = src[2][2]; + dst[2][3] = src[2][3]; + } +} + +asm void PSMTXCopy(const register Mtx src, register Mtx dst) { + psq_l f0, 0(src), 0, 0 + psq_st f0, 0(dst), 0, 0 + psq_l f1, 8(src), 0, 0 + psq_st f1, 8(dst), 0, 0 + psq_l f2, 16(src), 0, 0 + psq_st f2, 16(dst), 0, 0 + psq_l f3, 24(src), 0, 0 + psq_st f3, 24(dst), 0, 0 + psq_l f4, 32(src), 0, 0 + psq_st f4, 32(dst), 0, 0 + psq_l f5, 40(src), 0, 0 + psq_st f5, 40(dst), 0, 0 +} + +void C_MTXConcat(const Mtx a, const Mtx b, Mtx ab) { + Mtx mTmp; + MtxPtr m; + + ASSERTMSGLINE(324, a, "MTXConcat(): NULL MtxPtr 'a' "); + ASSERTMSGLINE(325, b, "MTXConcat(): NULL MtxPtr 'b' "); + ASSERTMSGLINE(326, ab, "MTXConcat(): NULL MtxPtr 'ab' "); + + if (ab == a || ab == b) { + m = mTmp; + } else { + m = ab; + } + + m[0][0] = 0 + a[0][2] * b[2][0] + ((a[0][0] * b[0][0]) + (a[0][1] * b[1][0])); + m[0][1] = 0 + a[0][2] * b[2][1] + ((a[0][0] * b[0][1]) + (a[0][1] * b[1][1])); + m[0][2] = 0 + a[0][2] * b[2][2] + ((a[0][0] * b[0][2]) + (a[0][1] * b[1][2])); + m[0][3] = a[0][3] + (a[0][2] * b[2][3] + (a[0][0] * b[0][3] + (a[0][1] * b[1][3]))); + + m[1][0] = 0 + a[1][2] * b[2][0] + ((a[1][0] * b[0][0]) + (a[1][1] * b[1][0])); + m[1][1] = 0 + a[1][2] * b[2][1] + ((a[1][0] * b[0][1]) + (a[1][1] * b[1][1])); + m[1][2] = 0 + a[1][2] * b[2][2] + ((a[1][0] * b[0][2]) + (a[1][1] * b[1][2])); + m[1][3] = a[1][3] + (a[1][2] * b[2][3] + (a[1][0] * b[0][3] + (a[1][1] * b[1][3]))); + + m[2][0] = 0 + a[2][2] * b[2][0] + ((a[2][0] * b[0][0]) + (a[2][1] * b[1][0])); + m[2][1] = 0 + a[2][2] * b[2][1] + ((a[2][0] * b[0][1]) + (a[2][1] * b[1][1])); + m[2][2] = 0 + a[2][2] * b[2][2] + ((a[2][0] * b[0][2]) + (a[2][1] * b[1][2])); + m[2][3] = a[2][3] + (a[2][2] * b[2][3] + (a[2][0] * b[0][3] + (a[2][1] * b[1][3]))); + + if (m == mTmp) { + C_MTXCopy(mTmp, ab); + } +} + +asm void PSMTXConcat(const register Mtx a, const register Mtx b, register Mtx ab) { + nofralloc + stwu r1, -64(r1) + psq_l f0, 0(a), 0, 0 + stfd f14, 8(r1) + psq_l f6, 0(b), 0, 0 + lis r6, Unit01@ha + psq_l f7, 8(b), 0, 0 + stfd f15, 16(r1) + addi r6, r6, Unit01@l + stfd f31, 40(r1) + psq_l f8, 16(b), 0, 0 + ps_muls0 f12, f6, f0 + psq_l f2, 16(a), 0, 0 + ps_muls0 f13, f7, f0 + psq_l f31, 0(r6), 0, 0 + ps_muls0 f14, f6, f2 + psq_l f9, 24(b), 0, 0 + ps_muls0 f15, f7, f2 + psq_l f1, 8(a), 0, 0 + ps_madds1 f12, f8, f0, f12 + psq_l f3, 24(a), 0, 0 + ps_madds1 f14, f8, f2, f14 + psq_l f10, 32(b), 0, 0 + ps_madds1 f13, f9, f0, f13 + psq_l f11, 40(b), 0, 0 + ps_madds1 f15, f9, f2, f15 + psq_l f4, 32(a), 0, 0 + psq_l f5, 40(a), 0, 0 + ps_madds0 f12, f10, f1, f12 + ps_madds0 f13, f11, f1, f13 + ps_madds0 f14, f10, f3, f14 + ps_madds0 f15, f11, f3, f15 + psq_st f12, 0(ab), 0, 0 + ps_muls0 f2, f6, f4 + ps_madds1 f13, f31, f1, f13 + ps_muls0 f0, f7, f4 + psq_st f14, 16(ab), 0, 0 + ps_madds1 f15, f31, f3, f15 + psq_st f13, 8(ab), 0, 0 + ps_madds1 f2, f8, f4, f2 + ps_madds1 f0, f9, f4, f0 + ps_madds0 f2, f10, f5, f2 + lfd f14, 8(r1) + psq_st f15, 24(ab), 0, 0 + ps_madds0 f0, f11, f5, f0 + psq_st f2, 32(ab), 0, 0 + ps_madds1 f0, f31, f5, f0 + lfd f15, 16(r1) + psq_st f0, 40(ab), 0, 0 + lfd f31, 40(r1) + addi r1, r1, 64 + blr +} + +void C_MTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count) { + u32 i; + + ASSERTMSGLINE(580, a != 0, "MTXConcatArray(): NULL MtxPtr 'a' "); + ASSERTMSGLINE(581, srcBase != 0, "MTXConcatArray(): NULL MtxPtr 'srcBase' "); + ASSERTMSGLINE(582, dstBase != 0, "MTXConcatArray(): NULL MtxPtr 'dstBase' "); + ASSERTMSGLINE(583, count > 1, "MTXConcatArray(): count must be greater than 1."); + + for (i = 0; i < count; i++) { + C_MTXConcat(a, *srcBase, *dstBase); + srcBase++; + dstBase++; + } +} + +#if DEBUG +#pragma push +#pragma optimization_level 1 +// This function will not compile at optimization level 0 +#endif +void PSMTXConcatArray(const register Mtx a, const register Mtx* srcBase, register Mtx* dstBase, register u32 count) { + register f32 va0, va1, va2, va3, va4, va5; + register f32 vb0, vb1, vb2, vb3, vb4, vb5; + register f32 vd0, vd1, vd2, vd3, vd4, vd5; + register f32 u01; + register f32* u01Ptr = Unit01; + + asm { + psq_l va0, 0(a), 0, 0; + psq_l va1, 8(a), 0, 0; + psq_l va2, 16(a), 0, 0; + psq_l va3, 24(a), 0, 0; + subi count, count, 1; + psq_l va4, 32(a), 0, 0; + psq_l va5, 40(a), 0, 0; + mtctr count; + psq_l u01, 0(u01Ptr), 0, 0; + psq_l vb0, 0(srcBase), 0, 0; + psq_l vb2, 16(srcBase), 0, 0; + ps_muls0 vd0, vb0, va0; + ps_muls0 vd2, vb0, va2; + ps_muls0 vd4, vb0, va4; + psq_l vb4, 32(srcBase), 0, 0; + ps_madds1 vd0, vb2, va0, vd0; + ps_madds1 vd2, vb2, va2, vd2; + ps_madds1 vd4, vb2, va4, vd4; + psq_l vb1, 8(srcBase), 0, 0; + ps_madds0 vd0, vb4, va1, vd0; + ps_madds0 vd2, vb4, va3, vd2; + ps_madds0 vd4, vb4, va5, vd4; + psq_l vb3, 24(srcBase), 0, 0; + psq_st vd0, 0(dstBase), 0, 0; + ps_muls0 vd1, vb1, va0; + ps_muls0 vd3, vb1, va2; + ps_muls0 vd5, vb1, va4; + psq_l vb5, 40(srcBase), 0, 0; + psq_st vd2, 16(dstBase), 0, 0; + ps_madds1 vd1, vb3, va0, vd1; + ps_madds1 vd3, vb3, va2, vd3; + ps_madds1 vd5, vb3, va4, vd5; + _loop: + addi srcBase, srcBase, sizeof(Mtx); + ps_madds0 vd1, vb5, va1, vd1; + ps_madds0 vd3, vb5, va3, vd3; + ps_madds0 vd5, vb5, va5, vd5; + psq_l vb0, 0(srcBase), 0, 0; + psq_st vd4, 32(dstBase), 0, 0; + ps_madd vd1, u01, va1, vd1; + ps_madd vd3, u01, va3, vd3; + ps_madd vd5, u01, va5, vd5; + psq_l vb2, 16(srcBase), 0, 0; + psq_st vd1, 8(dstBase), 0, 0; + ps_muls0 vd0, vb0, va0; + ps_muls0 vd2, vb0, va2; + ps_muls0 vd4, vb0, va4; + psq_l vb4, 32(srcBase), 0, 0; + psq_st vd3, 24(dstBase), 0, 0; + ps_madds1 vd0, vb2, va0, vd0; + ps_madds1 vd2, vb2, va2, vd2; + ps_madds1 vd4, vb2, va4, vd4; + psq_l vb1, 8(srcBase), 0, 0; + psq_st vd5, 40(dstBase), 0, 0; + addi dstBase, dstBase, sizeof(Mtx); + ps_madds0 vd0, vb4, va1, vd0; + ps_madds0 vd2, vb4, va3, vd2; + ps_madds0 vd4, vb4, va5, vd4; + psq_l vb3, 24(srcBase), 0, 0; + psq_st vd0, 0(dstBase), 0, 0; + ps_muls0 vd1, vb1, va0; + ps_muls0 vd3, vb1, va2; + ps_muls0 vd5, vb1, va4; + psq_l vb5, 40(srcBase), 0, 0; + psq_st vd2, 16(dstBase), 0, 0; + ps_madds1 vd1, vb3, va0, vd1; + ps_madds1 vd3, vb3, va2, vd3; + ps_madds1 vd5, vb3, va4, vd5; + bdnz _loop; + psq_st vd4, 32(dstBase), 0, 0; + ps_madds0 vd1, vb5, va1, vd1; + ps_madds0 vd3, vb5, va3, vd3; + ps_madds0 vd5, vb5, va5, vd5; + ps_madd vd1, u01, va1, vd1; + ps_madd vd3, u01, va3, vd3; + ps_madd vd5, u01, va5, vd5; + psq_st vd1, 8(dstBase), 0, 0; + psq_st vd3, 24(dstBase), 0, 0; + psq_st vd5, 40(dstBase), 0, 0; + } +} +#if DEBUG +#pragma pop +#endif + +void C_MTXTranspose(const Mtx src, Mtx xPose) { + Mtx mTmp; + MtxPtr m; + + ASSERTMSGLINE(851, src, "MTXTranspose(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(852, xPose, "MTXTranspose(): NULL MtxPtr 'xPose' "); + + if (src == xPose) { + m = mTmp; + } else { + m = xPose; + } + + m[0][0] = src[0][0]; + m[0][1] = src[1][0]; + m[0][2] = src[2][0]; + m[0][3] = 0; + m[1][0] = src[0][1]; + m[1][1] = src[1][1]; + m[1][2] = src[2][1]; + m[1][3] = 0; + m[2][0] = src[0][2]; + m[2][1] = src[1][2]; + m[2][2] = src[2][2]; + m[2][3] = 0; + if (m == mTmp) { + C_MTXCopy(mTmp, xPose); + } +} + +void PSMTXTranspose(const register Mtx src, register Mtx xPose) { + register f32 c_zero = 0; + register f32 row0a; + register f32 row1a; + register f32 row0b; + register f32 row1b; + register f32 trns0; + register f32 trns1; + register f32 trns2; + + asm { + psq_l row0a, 0(src), 0, 0 + } + xPose[2][3] = c_zero; + asm { + psq_l row1a, 16(src), 0, 0 + ps_merge00 trns0, row0a, row1a + psq_l row0b, 8(src), 1, 0 + ps_merge11 trns1, row0a, row1a + psq_l row1b, 24(src), 1, 0 + psq_st trns0, 0(xPose), 0, 0 + psq_l row0a, 32(src), 0, 0 + ps_merge00 trns2, row0b, row1b + psq_st trns1, 16(xPose), 0, 0 + ps_merge00 trns0, row0a, c_zero + psq_st trns2, 32(xPose), 0, 0 + ps_merge10 trns1, row0a, c_zero + psq_st trns0, 8(xPose), 0, 0 + } + row0b = src[2][2]; + asm { + psq_st trns1, 24(xPose), 0, 0 + } + xPose[2][2] = row0b; +} + +u32 C_MTXInverse(const Mtx src, Mtx inv) { + Mtx mTmp; + MtxPtr m; + f32 det; + + ASSERTMSGLINE(950, src, "MTXInverse(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(951, inv, "MTXInverse(): NULL MtxPtr 'inv' "); + + if (src == inv) { + m = mTmp; + } else { + m = inv; + } + det = ((((src[2][1] * (src[0][2] * src[1][0])) + + ((src[2][2] * (src[0][0] * src[1][1])) + + (src[2][0] * (src[0][1] * src[1][2])))) + - (src[0][2] * (src[2][0] * src[1][1]))) + - (src[2][2] * (src[1][0] * src[0][1]))) + - (src[1][2] * (src[0][0] * src[2][1])); + if (0 == det) { + return 0; + } + det = 1 / det; + m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2]))); + m[0][1] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2]))); + m[0][2] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2]))); + + m[1][0] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2]))); + m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2]))); + m[1][2] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2]))); + + m[2][0] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1]))); + m[2][1] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1]))); + m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1]))); + + m[0][3] = ((-m[0][0] * src[0][3]) - (m[0][1] * src[1][3])) - (m[0][2] * src[2][3]); + m[1][3] = ((-m[1][0] * src[0][3]) - (m[1][1] * src[1][3])) - (m[1][2] * src[2][3]); + m[2][3] = ((-m[2][0] * src[0][3]) - (m[2][1] * src[1][3])) - (m[2][2] * src[2][3]); + + if (m == mTmp) { + C_MTXCopy(mTmp, inv); + } + return 1; +} + +asm u32 PSMTXInverse(const register Mtx src, register Mtx inv) { + psq_l f0, 0(src), 1, 0 + psq_l f1, 4(src), 0, 0 + psq_l f2, 16(src), 1, 0 + ps_merge10 f6, f1, f0 + psq_l f3, 20(src), 0, 0 + psq_l f4, 32(src), 1, 0 + ps_merge10 f7, f3, f2 + psq_l f5, 36(src), 0, 0 + ps_mul f11, f3, f6 + ps_mul f13, f5, f7 + ps_merge10 f8, f5, f4 + ps_msub f11, f1, f7, f11 + ps_mul f12, f1, f8 + ps_msub f13, f3, f8, f13 + ps_mul f10, f3, f4 + ps_msub f12, f5, f6, f12 + ps_mul f9, f0, f5 + ps_mul f8, f1, f2 + ps_sub f6, f6, f6 + ps_msub f10, f2, f5, f10 + ps_mul f7, f0, f13 + ps_msub f9, f1, f4, f9 + ps_madd f7, f2, f12, f7 + ps_msub f8, f0, f3, f8 + ps_madd f7, f4, f11, f7 + ps_cmpo0 cr0, f7, f6 + bne skip_return + li r3, 0 + blr +skip_return: + fres f0, f7 + ps_add f6, f0, f0 + ps_mul f5, f0, f0 + ps_nmsub f0, f7, f5, f6 + lfs f1, 12(src) + ps_muls0 f13, f13, f0 + lfs f2, 28(src) + ps_muls0 f12, f12, f0 + lfs f3, 44(src) + ps_muls0 f11, f11, f0 + ps_merge00 f5, f13, f12 + ps_muls0 f10, f10, f0 + ps_merge11 f4, f13, f12 + ps_muls0 f9, f9, f0 + psq_st f5, 0(inv), 0, 0 + ps_mul f6, f13, f1 + psq_st f4, 16(inv), 0, 0 + ps_muls0 f8, f8, f0 + ps_madd f6, f12, f2, f6 + psq_st f10, 32(inv), 1, 0 + ps_nmadd f6, f11, f3, f6 + psq_st f9, 36(inv), 1, 0 + ps_mul f7, f10, f1 + ps_merge00 f5, f11, f6 + psq_st f8, 40(inv), 1, 0 + ps_merge11 f4, f11, f6 + psq_st f5, 8(inv), 0, 0 + ps_madd f7, f9, f2, f7 + psq_st f4, 24(inv), 0, 0 + ps_nmadd f7, f8, f3, f7 + li r3, 1 + psq_st f7, 44(inv), 1, 0 +} + +u32 C_MTXInvXpose(const Mtx src, Mtx invX) { + Mtx mTmp; + MtxPtr m; + f32 det; + + ASSERTMSGLINE(1185, src, "MTXInvXpose(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(1186, invX, "MTXInvXpose(): NULL MtxPtr 'invX' "); + + if (src == invX) { + m = mTmp; + } else { + m = invX; + } + det = ((((src[2][1] * (src[0][2] * src[1][0])) + + ((src[2][2] * (src[0][0] * src[1][1])) + + (src[2][0] * (src[0][1] * src[1][2])))) + - (src[0][2] * (src[2][0] * src[1][1]))) + - (src[2][2] * (src[1][0] * src[0][1]))) + - (src[1][2] * (src[0][0] * src[2][1])); + if (0 == det) { + return 0; + } + det = 1 / det; + m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2]))); + m[0][1] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2]))); + m[0][2] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1]))); + + m[1][0] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2]))); + m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2]))); + m[1][2] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1]))); + + m[2][0] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2]))); + m[2][1] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2]))); + m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1]))); + + m[0][3] = 0; + m[1][3] = 0; + m[2][3] = 0; + + if (m == mTmp) { + C_MTXCopy(mTmp, invX); + } + return 1; +} + +asm u32 PSMTXInvXpose(const register Mtx src, register Mtx invX) { + psq_l f0, 0(src), 1, 0 + psq_l f1, 4(src), 0, 0 + psq_l f2, 16(src), 1, 0 + ps_merge10 f6, f1, f0 + psq_l f3, 20(src), 0, 0 + psq_l f4, 32(src), 1, 0 + ps_merge10 f7, f3, f2 + psq_l f5, 36(src), 0, 0 + ps_mul f11, f3, f6 + ps_merge10 f8, f5, f4 + ps_mul f13, f5, f7 + ps_msub f11, f1, f7, f11 + ps_mul f12, f1, f8 + ps_msub f13, f3, f8, f13 + ps_msub f12, f5, f6, f12 + ps_mul f10, f3, f4 + ps_mul f9, f0, f5 + ps_mul f8, f1, f2 + ps_msub f10, f2, f5, f10 + ps_msub f9, f1, f4, f9 + ps_msub f8, f0, f3, f8 + ps_mul f7, f0, f13 + ps_sub f1, f1, f1 + ps_madd f7, f2, f12, f7 + ps_madd f7, f4, f11, f7 + ps_cmpo0 cr0, f7, f1 + bne skip_return + li r3, 0 + blr +skip_return: + fres f0, f7 + psq_st f1, 12(invX), 1, 0 + ps_add f6, f0, f0 + ps_mul f5, f0, f0 + psq_st f1, 28(invX), 1, 0 + ps_nmsub f0, f7, f5, f6 + psq_st f1, 44(invX), 1, 0 + ps_muls0 f13, f13, f0 + ps_muls0 f12, f12, f0 + ps_muls0 f11, f11, f0 + psq_st f13, 0(invX), 0, 0 + psq_st f12, 16(invX), 0, 0 + ps_muls0 f10, f10, f0 + ps_muls0 f9, f9, f0 + psq_st f11, 32(invX), 0, 0 + psq_st f10, 8(invX), 1, 0 + ps_muls0 f8, f8, f0 + li r3, 1 + psq_st f9, 24(invX), 1, 0 + psq_st f8, 40(invX), 1, 0 +} + +void C_MTXRotRad(Mtx m, char axis, f32 rad) { + f32 sinA; + f32 cosA; + + ASSERTMSGLINE(1447, m, "MTXRotRad(): NULL MtxPtr 'm' "); + sinA = sinf(rad); + cosA = cosf(rad); + C_MTXRotTrig(m, axis, sinA, cosA); +} + +void PSMTXRotRad(Mtx m, char axis, f32 rad) { + f32 sinA, cosA; + sinA = sinf(rad); + cosA = cosf(rad); + PSMTXRotTrig(m, axis, sinA, cosA); +} + +void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA) { + ASSERTMSGLINE(1502, m, "MTXRotTrig(): NULL MtxPtr 'm' "); + switch(axis) { + case 'x': + case 'X': + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = cosA; + m[1][2] = -sinA; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = sinA; + m[2][2] = cosA; + m[2][3] = 0; + break; + case 'y': + case 'Y': + m[0][0] = cosA; + m[0][1] = 0; + m[0][2] = sinA; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = -sinA; + m[2][1] = 0; + m[2][2] = cosA; + m[2][3] = 0; + break; + case 'z': + case 'Z': + m[0][0] = cosA; + m[0][1] = -sinA; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = sinA; + m[1][1] = cosA; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = 0; + break; + default: + ASSERTMSGLINE(1529, FALSE, "MTXRotTrig(): invalid 'axis' value "); + break; + } +} + +void PSMTXRotTrig(register Mtx m, register char axis, register f32 sinA, register f32 cosA) { + register f32 fc0, fc1, nsinA; + register f32 fw0, fw1, fw2, fw3; + + asm { + frsp sinA, sinA + frsp cosA, cosA + } + + fc0 = 0.0f; + fc1 = 1.0f; + + asm { + ori axis, axis, 0x20 + ps_neg nsinA, sinA + cmplwi axis, 'x' + beq _case_x + cmplwi axis, 'y' + beq _case_y + cmplwi axis, 'z' + beq _case_z + b _end + + _case_x: + psq_st fc1, 0(m), 1, 0 + psq_st fc0, 4(m), 0, 0 + ps_merge00 fw0, sinA, cosA + psq_st fc0, 12(m), 0, 0 + ps_merge00 fw1, cosA, nsinA + psq_st fc0, 28(m), 0, 0 + psq_st fc0, 44(m), 1, 0 + psq_st fw0, 36(m), 0, 0 + psq_st fw1, 20(m), 0, 0 + b _end; + + _case_y: + ps_merge00 fw0, cosA, fc0 + ps_merge00 fw1, fc0, fc1 + psq_st fc0, 24(m), 0, 0 + psq_st fw0, 0(m), 0, 0 + ps_merge00 fw2, nsinA, fc0 + ps_merge00 fw3, sinA, fc0 + psq_st fw0, 40(m), 0, 0; + psq_st fw1, 16(m), 0, 0; + psq_st fw3, 8(m), 0, 0; + psq_st fw2, 32(m), 0, 0; + b _end; + + _case_z: + psq_st fc0, 8(m), 0, 0 + ps_merge00 fw0, sinA, cosA + ps_merge00 fw2, cosA, nsinA + psq_st fc0, 24(m), 0, 0 + psq_st fc0, 32(m), 0, 0 + ps_merge00 fw1, fc1, fc0 + psq_st fw0, 16(m), 0, 0 + psq_st fw2, 0(m), 0, 0 + psq_st fw1, 40(m), 0, 0 + + _end: + } +} + +static void __PSMTXRotAxisRadInternal(register Mtx m, const register Vec* axis, register f32 sT, register f32 cT) { + register f32 tT, fc0; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4; + register f32 tmp5, tmp6, tmp7, tmp8, tmp9; + tmp9 = 0.5f; + tmp8 = 3.0f; + + asm { + frsp cT, cT; + psq_l tmp0, 0(axis), 0, 0; + frsp sT, sT; + lfs tmp1, 8(axis); + ps_mul tmp2, tmp0, tmp0; + fadds tmp7, tmp9, tmp9; + ps_madd tmp3, tmp1, tmp1, tmp2; + fsubs fc0, tmp9, tmp9; + ps_sum0 tmp4, tmp3, tmp1, tmp2; + fsubs tT, tmp7, cT; + frsqrte tmp5, tmp4; + fmuls tmp2, tmp5, tmp5; + fmuls tmp3, tmp5, tmp9; + fnmsubs tmp2, tmp2, tmp4, tmp8; + fmuls tmp5, tmp2, tmp3; + ps_merge00 cT, cT, cT; + ps_muls0 tmp0, tmp0, tmp5; + ps_muls0 tmp1, tmp1, tmp5; + ps_muls0 tmp4, tmp0, tT; + ps_muls0 tmp9, tmp0, sT; + ps_muls0 tmp5, tmp1, tT; + ps_muls1 tmp3, tmp4, tmp0; + ps_muls0 tmp2, tmp4, tmp0; + ps_muls0 tmp4, tmp4, tmp1; + fnmsubs tmp6, tmp1, sT, tmp3; + fmadds tmp7, tmp1, sT, tmp3; + ps_neg tmp0, tmp9; + ps_sum0 tmp8, tmp4, fc0, tmp9; + ps_sum0 tmp2, tmp2, tmp6, cT; + ps_sum1 tmp3, cT, tmp7, tmp3; + ps_sum0 tmp6, tmp0, fc0, tmp4; + psq_st tmp8, 8(m), 0, 0; + ps_sum0 tmp0, tmp4, tmp4, tmp0; + psq_st tmp2, 0(m), 0, 0; + ps_muls0 tmp5, tmp5, tmp1; + psq_st tmp3, 16(m), 0, 0; + ps_sum1 tmp4, tmp9, tmp0, tmp4; + psq_st tmp6, 24(m), 0, 0; + ps_sum0 tmp5, tmp5, fc0, cT; + psq_st tmp4, 32(m), 0, 0; + psq_st tmp5, 40(m), 0, 0; + } +} + +void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { + f32 sinT, cosT; + + sinT = sinf(rad); + cosT = cosf(rad); + + __PSMTXRotAxisRadInternal(m, axis, sinT, cosT); +} + +void C_MTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { + Vec vN; + f32 s; + f32 c; + f32 t; + f32 x; + f32 y; + f32 z; + f32 xSq; + f32 ySq; + f32 zSq; + + ASSERTMSGLINE(1677, m, "MTXRotAxisRad(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(1678, axis, "MTXRotAxisRad(): NULL VecPtr 'axis' "); + + s = sinf(rad); + c = cosf(rad); + t = 1 - c; + C_VECNormalize(axis, &vN); + x = vN.x; + y = vN.y; + z = vN.z; + xSq = (x * x); + ySq = (y * y); + zSq = (z * z); + m[0][0] = (c + (t * xSq)); + m[0][1] = (y * (t * x)) - (s * z); + m[0][2] = (z * (t * x)) + (s * y); + m[0][3] = 0; + m[1][0] = ((y * (t * x)) + (s * z)); + m[1][1] = (c + (t * ySq)); + m[1][2] = ((z * (t * y)) - (s * x)); + m[1][3] = 0; + m[2][0] = ((z * (t * x)) - (s * y)); + m[2][1] = ((z * (t * y)) + (s * x)); + m[2][2] = (c + (t * zSq)); + m[2][3] = 0; +} + +void C_MTXTrans(Mtx m, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(1866, m, "MTXTrans(): NULL MtxPtr 'm' "); + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = xT; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = yT; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = zT; +} + +void PSMTXTrans(register Mtx m, register f32 xT, register f32 yT, register f32 zT) { + register f32 c0 = 0.0f; + register f32 c1 = 1.0f; + + asm { + stfs xT, 12(m) + stfs yT, 28(m) + psq_st c0, 4(m), 0, 0 + psq_st c0, 32(m), 0, 0 + stfs c0, 16(m) + stfs c1, 20(m) + stfs c0, 24(m) + stfs c1, 40(m) + stfs zT, 44(m) + stfs c1, 0(m) + } +} + +void C_MTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(1933, src, "MTXTransApply(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(1934, dst, "MTXTransApply(): NULL MtxPtr 'src' "); //! wrong assert string + + if (src != dst) { + dst[0][0] = src[0][0]; + dst[0][1] = src[0][1]; + dst[0][2] = src[0][2]; + dst[1][0] = src[1][0]; + dst[1][1] = src[1][1]; + dst[1][2] = src[1][2]; + dst[2][0] = src[2][0]; + dst[2][1] = src[2][1]; + dst[2][2] = src[2][2]; + } + + dst[0][3] = (src[0][3] + xT); + dst[1][3] = (src[1][3] + yT); + dst[2][3] = (src[2][3] + zT); +} + +asm void PSMTXTransApply(const register Mtx src, register Mtx dst, register f32 xT, register f32 yT, register f32 zT) { + nofralloc + psq_l fp4, 0(src), 0, 0 + frsp xT, xT + psq_l fp5, 8(src), 0, 0 + frsp yT, yT + psq_l fp7, 24(src), 0, 0 + frsp zT, zT + psq_l fp8, 40(src), 0, 0 + psq_st fp4, 0(dst), 0, 0 + ps_sum1 fp5, xT, fp5, fp5 + psq_l fp6, 16(src), 0, 0 + psq_st fp5, 8(dst), 0, 0 + ps_sum1 fp7, yT, fp7, fp7 + psq_l fp9, 32(src), 0, 0 + psq_st fp6, 16(dst), 0, 0 + ps_sum1 fp8, zT, fp8, fp8 + psq_st fp7, 24(dst), 0, 0 + psq_st fp9, 32(dst), 0, 0 + psq_st fp8, 40(dst), 0, 0 + blr +} + +void C_MTXScale(Mtx m, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(2008, m, "MTXScale(): NULL MtxPtr 'm' "); + m[0][0] = xS; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = yS; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = zS; + m[2][3] = 0; +} + +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) + } +} + +void C_MTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(2070, src, "MTXScaleApply(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(2071, dst, "MTXScaleApply(): NULL MtxPtr 'dst' "); + dst[0][0] = (src[0][0] * xS); + dst[0][1] = (src[0][1] * xS); + dst[0][2] = (src[0][2] * xS); + dst[0][3] = (src[0][3] * xS); + dst[1][0] = (src[1][0] * yS); + dst[1][1] = (src[1][1] * yS); + dst[1][2] = (src[1][2] * yS); + dst[1][3] = (src[1][3] * yS); + dst[2][0] = (src[2][0] * zS); + dst[2][1] = (src[2][1] * zS); + dst[2][2] = (src[2][2] * zS); + dst[2][3] = (src[2][3] * zS); +} + +asm void PSMTXScaleApply(const register Mtx src, register Mtx dst, register f32 xS, register f32 yS, register f32 zS) { + nofralloc + frsp xS, xS + psq_l fp4, 0(src), 0, 0 + frsp yS, yS + psq_l fp5, 8(src), 0, 0 + frsp zS, zS + ps_muls0 fp4, fp4, xS + psq_l fp6, 16(src), 0, 0 + ps_muls0 fp5, fp5, xS + psq_l fp7, 24(src), 0, 0 + ps_muls0 fp6, fp6, yS + psq_l fp8, 32(src), 0, 0 + psq_st fp4, 0(dst), 0, 0 + ps_muls0 fp7, fp7, yS + psq_l fp2, 40(src), 0, 0 + psq_st fp5, 8(dst), 0, 0 + ps_muls0 fp8, fp8, zS + psq_st fp6, 16(dst), 0, 0 + ps_muls0 fp2, fp2, zS + psq_st fp7, 24(dst), 0, 0 + psq_st fp8, 32(dst), 0, 0 + psq_st fp2, 40(dst), 0, 0 + blr +} + +void C_MTXQuat(Mtx m, const Quaternion* q) { + f32 s; + f32 xs; + f32 ys; + f32 zs; + f32 wx; + f32 wy; + f32 wz; + f32 xx; + f32 xy; + f32 xz; + f32 yy; + f32 yz; + f32 zz; + + ASSERTMSGLINE(2145, m, "MTXQuat(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2146, q, "MTXQuat(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(2147, q->x || q->y || q->z || q->w, "MTXQuat(): zero-value quaternion "); + s = 2 / ((q->w * q->w) + ((q->z * q->z) + ((q->x * q->x) + (q->y * q->y)))); + xs = q->x * s; + ys = q->y * s; + zs = q->z * s; + wx = q->w * xs; + wy = q->w * ys; + wz = q->w * zs; + xx = q->x * xs; + xy = q->x * ys; + xz = q->x * zs; + yy = q->y * ys; + yz = q->y * zs; + zz = q->z * zs; + m[0][0] = (1 - (yy + zz)); + m[0][1] = (xy - wz); + m[0][2] = (xz + wy); + m[0][3] = 0; + m[1][0] = (xy + wz); + m[1][1] = (1 - (xx + zz)); + m[1][2] = (yz - wx); + m[1][3] = 0; + m[2][0] = (xz - wy); + m[2][1] = (yz + wx); + m[2][2] = (1 - (xx + yy)); + m[2][3] = 0; +} + +void PSMTXQuat(register Mtx m, const register Quaternion* q) { + register f32 c_zero, c_one, c_two, scale; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4; + register f32 tmp5, tmp6, tmp7, tmp8, tmp9; + c_one = 1.0f; + + asm { + psq_l tmp0, 0(q), 0, 0 + psq_l tmp1, 8(q), 0, 0 + fsubs c_zero, c_one, c_one + fadds c_two, c_one, c_one + ps_mul tmp2, tmp0, tmp0 + ps_merge10 tmp5, tmp0, tmp0 + ps_madd tmp4, tmp1, tmp1, tmp2 + ps_mul tmp3, tmp1, tmp1 + ps_sum0 scale, tmp4, tmp4, tmp4 + ps_muls1 tmp7, tmp5, tmp1 + fres tmp9, scale + ps_sum1 tmp4, tmp3, tmp4, tmp2 + ps_nmsub scale, scale, tmp9, c_two + ps_muls1 tmp6, tmp1, tmp1 + ps_mul scale, tmp9, scale + ps_sum0 tmp2, tmp2, tmp2, tmp2 + fmuls scale, scale, c_two + ps_madd tmp8, tmp0, tmp5, tmp6 + ps_msub tmp6, tmp0, tmp5, tmp6 + psq_st c_zero, 12(m), 1, 0 + ps_nmsub tmp2, tmp2, scale, c_one + ps_nmsub tmp4, tmp4, scale, c_one + psq_st c_zero, 44(m), 1, 0 + ps_mul tmp8, tmp8, scale + ps_mul tmp6, tmp6, scale + psq_st tmp2, 40(m), 1, 0 + ps_madds0 tmp5, tmp0, tmp1, tmp7 + ps_merge00 tmp1, tmp8, tmp4 + ps_nmsub tmp7, tmp7, c_two, tmp5 + ps_merge10 tmp0, tmp4, tmp6 + psq_st tmp1, 16(m), 0, 0 + ps_mul tmp5, tmp5, scale + ps_mul tmp7, tmp7, scale + psq_st tmp0, 0(m), 0, 0 + psq_st tmp5, 8(m), 1, 0 + ps_merge10 tmp3, tmp7, c_zero + ps_merge01 tmp9, tmp7, tmp5 + psq_st tmp3, 24(m), 0, 0 + psq_st tmp9, 32(m), 0, 0 + } +} + +void C_MTXReflect(Mtx m, const Vec* p, const Vec* n) { + f32 vxy; + f32 vxz; + f32 vyz; + f32 pdotn; + + vxy = -2 * n->x * n->y; + vxz = -2 * n->x * n->z; + vyz = -2 * n->y * n->z; + pdotn = 2 * C_VECDotProduct(p, n); + m[0][0] = (1 - (2 * n->x * n->x)); + m[0][1] = vxy; + m[0][2] = vxz; + m[0][3] = (pdotn * n->x); + m[1][0] = vxy; + m[1][1] = (1 - (2 * n->y * n->y)); + m[1][2] = vyz; + m[1][3] = (pdotn * n->y); + m[2][0] = vxz; + m[2][1] = vyz; + m[2][2] = (1 - (2 * n->z * n->z)); + m[2][3] = (pdotn * n->z); +} + +void PSMTXReflect(register Mtx m, const register Vec* p, const register Vec* n) { + register f32 c_one; + register f32 vn_xy, vn_z1; + register f32 n2vn_xy, n2vn_z1; + register f32 pdotn; + register f32 tmp0, tmp1, tmp2, tmp3; + register f32 tmp4, tmp5, tmp6, tmp7; + + c_one = 1.0f; + + asm { + psq_l vn_z1, 0x8(n), 1, 0 + psq_l vn_xy, 0x0(n), 0, 0 + psq_l tmp0, 0x0(p), 0, 0 + ps_nmadd n2vn_z1, vn_z1, c_one, vn_z1 + psq_l tmp1, 0x8(p), 1, 0 + ps_nmadd n2vn_xy, vn_xy, c_one, vn_xy + ps_muls0 tmp4, vn_xy, n2vn_z1 + ps_mul pdotn, n2vn_xy, tmp0 + ps_muls0 tmp2, vn_xy, n2vn_xy + ps_sum0 pdotn, pdotn, pdotn, pdotn + ps_muls1 tmp3, vn_xy, n2vn_xy + psq_st tmp4, 0x20(m), 0, 0 + ps_sum0 tmp2, tmp2, tmp2, c_one + ps_nmadd pdotn, n2vn_z1, tmp1, pdotn + ps_sum1 tmp3, c_one, tmp3, tmp3 + psq_st tmp2, 0x0(m), 0, 0 + ps_muls0 tmp5, vn_xy, pdotn + ps_merge00 tmp6, n2vn_z1, pdotn + psq_st tmp3, 0x10(m), 0, 0 + ps_merge00 tmp7, tmp4, tmp5 + ps_muls0 tmp6, tmp6, vn_z1 + ps_merge11 tmp5, tmp4, tmp5 + psq_st tmp7, 0x8(m), 0, 0 + ps_sum0 tmp6, tmp6, tmp6, c_one + psq_st tmp5, 0x18(m), 0, 0 + psq_st tmp6, 0x28(m), 0, 0 + } +} + +void C_MTXLookAt(Mtx m, const Point3d* camPos, const Vec* camUp, const Point3d* target) { + Vec vLook; + Vec vRight; + Vec vUp; + + ASSERTMSGLINE(2438, m, "MTXLookAt(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2439, camPos, "MTXLookAt(): NULL VecPtr 'camPos' "); + ASSERTMSGLINE(2440, camUp, "MTXLookAt(): NULL VecPtr 'camUp' "); + ASSERTMSGLINE(2441, target, "MTXLookAt(): NULL Point3dPtr 'target' "); + + vLook.x = camPos->x - target->x; + vLook.y = camPos->y - target->y; + vLook.z = camPos->z - target->z; + VECNormalize(&vLook, &vLook); + VECCrossProduct(camUp, &vLook, &vRight); + VECNormalize(&vRight, &vRight); + VECCrossProduct(&vLook, &vRight, &vUp); + m[0][0] = vRight.x; + m[0][1] = vRight.y; + m[0][2] = vRight.z; + m[0][3] = -((camPos->z * vRight.z) + ((camPos->x * vRight.x) + (camPos->y * vRight.y))); + m[1][0] = vUp.x; + m[1][1] = vUp.y; + m[1][2] = vUp.z; + m[1][3] = -((camPos->z * vUp.z) + ((camPos->x * vUp.x) + (camPos->y * vUp.y))); + m[2][0] = vLook.x; + m[2][1] = vLook.y; + m[2][2] = vLook.z; + m[2][3] = -((camPos->z * vLook.z) + ((camPos->x * vLook.x) + (camPos->y * vLook.y))); +} + +void C_MTXLightFrustum(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { + f32 tmp; + + ASSERTMSGLINE(2541, m, "MTXLightFrustum(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2542, (t != b), "MTXLightFrustum(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(2543, (l != r), "MTXLightFrustum(): 'l' and 'r' clipping planes are equal "); + + tmp = 1 / (r - l); + m[0][0] = (scaleS * (2 * n * tmp)); + m[0][1] = 0; + m[0][2] = (scaleS * (tmp * (r + l))) - transS; + m[0][3] = 0; + tmp = 1 / (t - b); + m[1][0] = 0; + m[1][1] = (scaleT * (2 * n * tmp)); + m[1][2] = (scaleT * (tmp * (t + b))) - transT; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = -1; + m[2][3] = 0; +} + +void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { + f32 angle; + f32 cot; + + ASSERTMSGLINE(2605, m, "MTXLightPerspective(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2606, (fovY > 0.0) && (fovY < 180.0), "MTXLightPerspective(): 'fovY' out of range "); + ASSERTMSGLINE(2607, 0 != aspect, "MTXLightPerspective(): 'aspect' is 0 "); + + angle = (0.5f * fovY); + angle = MTXDegToRad(angle); + cot = 1 / tanf(angle); + m[0][0] = (scaleS * (cot / aspect)); + m[0][1] = 0; + m[0][2] = -transS; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = (cot * scaleT); + m[1][2] = -transT; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = -1; + m[2][3] = 0; +} + +void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { + f32 tmp; + + ASSERTMSGLINE(2673, m, "MTXLightOrtho(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2674, (t != b), "MTXLightOrtho(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(2675, (l != r), "MTXLightOrtho(): 'l' and 'r' clipping planes are equal "); + tmp = 1 / (r - l); + m[0][0] = (2 * tmp * scaleS); + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = (transS + (scaleS * (tmp * -(r + l)))); + tmp = 1/ (t - b); + m[1][0] = 0; + m[1][1] = (2 * tmp * scaleT); + m[1][2] = 0; + m[1][3] = (transT + (scaleT * (tmp * -(t + b)))); + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 0; + m[2][3] = 1; +} diff --git a/src/dolphin/mtx/mtx44.c b/src/dolphin/mtx/mtx44.c new file mode 100644 index 0000000..48a9712 --- /dev/null +++ b/src/dolphin/mtx/mtx44.c @@ -0,0 +1,888 @@ +#include +#include +#include "fake_tgmath.h" + +static f32 mtxUnit[] = {0.0f, 1.0f, 0.5f, 3.0f}; + +void C_MTXFrustum(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) { + f32 tmp; + + ASSERTMSGLINE(105, m, "MTXFrustum(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(106, t != b, "MTXFrustum(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(107, l != r, "MTXFrustum(): 'l' and 'r' clipping planes are equal "); + ASSERTMSGLINE(108, n != f, "MTXFrustum(): 'n' and 'f' clipping planes are equal "); + tmp = 1 / (r - l); + m[0][0] = (2 * n * tmp); + m[0][1] = 0; + m[0][2] = (tmp * (r + l)); + m[0][3] = 0; + tmp = 1 / (t - b); + m[1][0] = 0; + m[1][1] = (2 * n * tmp); + m[1][2] = (tmp * (t + b)); + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + tmp = 1 / (f - n); + m[2][2] = (-n * tmp); + m[2][3] = (tmp * -(f * n)); + m[3][0] = 0; + m[3][1] = 0; + m[3][2] = -1; + m[3][3] = 0; +} + +void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f) { + f32 angle; + f32 cot; + f32 tmp; + + ASSERTMSGLINE(179, m, "MTXPerspective(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(180, (fovY > 0.0) && (fovY < 180.0), "MTXPerspective(): 'fovY' out of range "); + ASSERTMSGLINE(181, 0.0f != aspect, "MTXPerspective(): 'aspect' is 0 "); + + angle = (0.5f * fovY); + angle = MTXDegToRad(angle); + cot = 1 / tanf(angle); + m[0][0] = (cot / aspect); + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = (cot); + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + tmp = 1 / (f - n); + m[2][2] = (-n * tmp); + m[2][3] = (tmp * -(f * n)); + m[3][0] = 0; + m[3][1] = 0; + m[3][2] = -1; + m[3][3] = 0; +} + +void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) { + f32 tmp; + + ASSERTMSGLINE(254, m, "MTXOrtho(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(255, t != b, "MTXOrtho(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(256, l != r, "MTXOrtho(): 'l' and 'r' clipping planes are equal "); + ASSERTMSGLINE(257, n != f, "MTXOrtho(): 'n' and 'f' clipping planes are equal "); + tmp = 1 / (r - l); + m[0][0] = 2 * tmp; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = (tmp * -(r + l)); + tmp = 1 / (t - b); + m[1][0] = 0; + m[1][1] = 2 * tmp; + m[1][2] = 0; + m[1][3] = (tmp * -(t + b)); + m[2][0] = 0; + m[2][1] = 0; + tmp = 1 / (f - n); + m[2][2] = (-1 * tmp); + m[2][3] = (-f * tmp); + m[3][0] = 0; + m[3][1] = 0; + m[3][2] = 0; + m[3][3] = 1; +} + +void C_MTX44Identity(Mtx44 m) { + ASSERTMSGLINE(324, m != 0, "MTX44Identity(): NULL Mtx44 'm' "); + + m[0][0] = 1.0f; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + m[1][0] = 0.0f; + m[1][1] = 1.0f; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 1.0f; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + +void PSMTX44Identity(register Mtx44 m) { + register f32 c1 = 1.0f; + register f32 c0 = 0.0f; + + asm { + stfs c1, 0x0(m) + psq_st c0, 0x4(m), 0, 0 + psq_st c0, 0xc(m), 0, 0 + stfs c1, 0x14(m) + psq_st c0, 0x18(m), 0, 0 + psq_st c0, 0x20(m), 0, 0 + stfs c1, 0x28(m) + psq_st c0, 0x2c(m), 0, 0 + psq_st c0, 0x34(m), 0, 0 + stfs c1, 0x3c(m) + } +} + +void C_MTX44Copy(const Mtx44 src, Mtx44 dst) { + ASSERTMSGLINE(382, src != 0, "MTX44Copy(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(383, dst != 0, "MTX44Copy(): NULL Mtx44Ptr 'dst' "); + + if (src != dst) { + dst[0][0] = src[0][0]; + dst[0][1] = src[0][1]; + dst[0][2] = src[0][2]; + dst[0][3] = src[0][3]; + dst[1][0] = src[1][0]; + dst[1][1] = src[1][1]; + dst[1][2] = src[1][2]; + dst[1][3] = src[1][3]; + dst[2][0] = src[2][0]; + dst[2][1] = src[2][1]; + dst[2][2] = src[2][2]; + dst[2][3] = src[2][3]; + dst[3][0] = src[3][0]; + dst[3][1] = src[3][1]; + dst[3][2] = src[3][2]; + dst[3][3] = src[3][3]; + } +} + +asm void PSMTX44Copy(const register Mtx44 src, register Mtx44 dst) { + nofralloc + psq_l f1, 0x0(src), 0, 0 + psq_st f1, 0x0(dst), 0, 0 + psq_l f1, 0x8(src), 0, 0 + psq_st f1, 0x8(dst), 0, 0 + psq_l f1, 0x10(src), 0, 0 + psq_st f1, 0x10(dst), 0, 0 + psq_l f1, 0x18(src), 0, 0 + psq_st f1, 0x18(dst), 0, 0 + psq_l f1, 0x20(src), 0, 0 + psq_st f1, 0x20(dst), 0, 0 + psq_l f1, 0x28(src), 0, 0 + psq_st f1, 0x28(dst), 0, 0 + psq_l f1, 0x30(src), 0, 0 + psq_st f1, 0x30(dst), 0, 0 + psq_l f1, 0x38(src), 0, 0 + psq_st f1, 0x38(dst), 0, 0 + blr +} + +void C_MTX44Concat(const Mtx44 a, const Mtx44 b, Mtx44 ab) { + Mtx44 mTmp; + Mtx44Ptr m; + + ASSERTMSGLINE(454, a, "MTX44Concat(): NULL Mtx44Ptr 'a' "); + ASSERTMSGLINE(455, b, "MTX44Concat(): NULL Mtx44Ptr 'b' "); + ASSERTMSGLINE(456, ab, "MTX44Concat(): NULL Mtx44Ptr 'ab' "); + + if (ab == a || ab == b) { + m = mTmp; + } else { + m = ab; + } + + m[0][0] = (a[0][0] * b[0][0]) + (a[0][1] * b[1][0]) + (a[0][2] * b[2][0]) + (a[0][3] * b[3][0]); + m[0][1] = (a[0][0] * b[0][1]) + (a[0][1] * b[1][1]) + (a[0][2] * b[2][1]) + (a[0][3] * b[3][1]); + m[0][2] = (a[0][0] * b[0][2]) + (a[0][1] * b[1][2]) + (a[0][2] * b[2][2]) + (a[0][3] * b[3][2]); + m[0][3] = (a[0][0] * b[0][3]) + (a[0][1] * b[1][3]) + (a[0][2] * b[2][3]) + (a[0][3] * b[3][3]); + + m[1][0] = (a[1][0] * b[0][0]) + (a[1][1] * b[1][0]) + (a[1][2] * b[2][0]) + (a[1][3] * b[3][0]); + m[1][1] = (a[1][0] * b[0][1]) + (a[1][1] * b[1][1]) + (a[1][2] * b[2][1]) + (a[1][3] * b[3][1]); + m[1][2] = (a[1][0] * b[0][2]) + (a[1][1] * b[1][2]) + (a[1][2] * b[2][2]) + (a[1][3] * b[3][2]); + m[1][3] = (a[1][0] * b[0][3]) + (a[1][1] * b[1][3]) + (a[1][2] * b[2][3]) + (a[1][3] * b[3][3]); + + m[2][0] = (a[2][0] * b[0][0]) + (a[2][1] * b[1][0]) + (a[2][2] * b[2][0]) + (a[2][3] * b[3][0]); + m[2][1] = (a[2][0] * b[0][1]) + (a[2][1] * b[1][1]) + (a[2][2] * b[2][1]) + (a[2][3] * b[3][1]); + m[2][2] = (a[2][0] * b[0][2]) + (a[2][1] * b[1][2]) + (a[2][2] * b[2][2]) + (a[2][3] * b[3][2]); + m[2][3] = (a[2][0] * b[0][3]) + (a[2][1] * b[1][3]) + (a[2][2] * b[2][3]) + (a[2][3] * b[3][3]); + + m[3][0] = (a[3][0] * b[0][0]) + (a[3][1] * b[1][0]) + (a[3][2] * b[2][0]) + (a[3][3] * b[3][0]); + m[3][1] = (a[3][0] * b[0][1]) + (a[3][1] * b[1][1]) + (a[3][2] * b[2][1]) + (a[3][3] * b[3][1]); + m[3][2] = (a[3][0] * b[0][2]) + (a[3][1] * b[1][2]) + (a[3][2] * b[2][2]) + (a[3][3] * b[3][2]); + m[3][3] = (a[3][0] * b[0][3]) + (a[3][1] * b[1][3]) + (a[3][2] * b[2][3]) + (a[3][3] * b[3][3]); + + if (m == mTmp) { + C_MTX44Copy(mTmp, ab); + } +} + +asm void PSMTX44Concat(const register Mtx44 a, const register Mtx44 b, register Mtx44 ab) { + nofralloc + psq_l f0, 0x0(a), 0, 0 + psq_l f2, 0x0(b), 0, 0 + ps_muls0 f6, f2, f0 + psq_l f3, 0x10(b), 0, 0 + psq_l f4, 0x20(b), 0, 0 + ps_madds1 f6, f3, f0, f6 + psq_l f1, 0x8(a), 0, 0 + psq_l f5, 0x30(b), 0, 0 + ps_madds0 f6, f4, f1, f6 + psq_l f0, 0x10(a), 0, 0 + ps_madds1 f6, f5, f1, f6 + psq_l f1, 0x18(a), 0, 0 + ps_muls0 f8, f2, f0 + ps_madds1 f8, f3, f0, f8 + psq_l f0, 0x20(a), 0, 0 + ps_madds0 f8, f4, f1, f8 + ps_madds1 f8, f5, f1, f8 + psq_l f1, 0x28(a), 0, 0 + ps_muls0 f10, f2, f0 + ps_madds1 f10, f3, f0, f10 + psq_l f0, 0x30(a), 0, 0 + ps_madds0 f10, f4, f1, f10 + ps_madds1 f10, f5, f1, f10 + psq_l f1, 0x38(a), 0, 0 + ps_muls0 f12, f2, f0 + psq_l f2, 0x8(b), 0, 0 + ps_madds1 f12, f3, f0, f12 + psq_l f0, 0x0(a), 0, 0 + ps_madds0 f12, f4, f1, f12 + psq_l f3, 0x18(b), 0, 0 + ps_madds1 f12, f5, f1, f12 + psq_l f1, 0x8(a), 0, 0 + ps_muls0 f7, f2, f0 + psq_l f4, 0x28(b), 0, 0 + ps_madds1 f7, f3, f0, f7 + psq_l f5, 0x38(b), 0, 0 + ps_madds0 f7, f4, f1, f7 + psq_l f0, 0x10(a), 0, 0 + ps_madds1 f7, f5, f1, f7 + psq_l f1, 0x18(a), 0, 0 + ps_muls0 f9, f2, f0 + psq_st f6, 0x0(ab), 0, 0 + ps_madds1 f9, f3, f0, f9 + psq_l f0, 0x20(a), 0, 0 + ps_madds0 f9, f4, f1, f9 + psq_st f8, 0x10(ab), 0, 0 + ps_madds1 f9, f5, f1, f9 + psq_l f1, 0x28(a), 0, 0 + ps_muls0 f11, f2, f0 + psq_st f10, 0x20(ab), 0, 0 + ps_madds1 f11, f3, f0, f11 + psq_l f0, 0x30(a), 0, 0 + ps_madds0 f11, f4, f1, f11 + psq_st f12, 0x30(ab), 0, 0 + ps_madds1 f11, f5, f1, f11 + psq_l f1, 0x38(a), 0, 0 + ps_muls0 f13, f2, f0 + psq_st f7, 0x8(ab), 0, 0 + ps_madds1 f13, f3, f0, f13 + psq_st f9, 0x18(ab), 0, 0 + ps_madds0 f13, f4, f1, f13 + psq_st f11, 0x28(ab), 0, 0 + ps_madds1 f13, f5, f1, f13 + psq_st f13, 0x38(ab), 0, 0 + blr +} + +void C_MTX44Transpose(const Mtx44 src, Mtx44 xPose) { + Mtx44 mTmp; + Mtx44Ptr m; + + ASSERTMSGLINE(637, src, "MTX44Transpose(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(638, xPose, "MTX44Transpose(): NULL Mtx44Ptr 'xPose' "); + + if (src == xPose) { + m = mTmp; + } else { + m = xPose; + } + + m[0][0] = src[0][0]; + m[0][1] = src[1][0]; + m[0][2] = src[2][0]; + m[0][3] = src[3][0]; + m[1][0] = src[0][1]; + m[1][1] = src[1][1]; + m[1][2] = src[2][1]; + m[1][3] = src[3][1]; + m[2][0] = src[0][2]; + m[2][1] = src[1][2]; + m[2][2] = src[2][2]; + m[2][3] = src[3][2]; + m[3][0] = src[0][3]; + m[3][1] = src[1][3]; + m[3][2] = src[2][3]; + m[3][3] = src[3][3]; + + if (m == mTmp) { + MTX44Copy(mTmp, xPose); + } +} + +asm void PSMTX44Transpose(const register Mtx44 src, register Mtx44 xPose) { + nofralloc + psq_l f0, 0x0(src), 0, 0 + psq_l f1, 0x10(src), 0, 0 + ps_merge00 f4, f0, f1 + psq_l f2, 0x8(src), 0, 0 + psq_st f4, 0x0(xPose), 0, 0 + ps_merge11 f5, f0, f1 + psq_l f3, 0x18(src), 0, 0 + psq_st f5, 0x10(xPose), 0, 0 + ps_merge00 f4, f2, f3 + psq_l f0, 0x20(src), 0, 0 + psq_st f4, 0x20(xPose), 0, 0 + ps_merge11 f5, f2, f3 + psq_l f1, 0x30(src), 0, 0 + psq_st f5, 0x30(xPose), 0, 0 + ps_merge00 f4, f0, f1 + psq_l f2, 0x28(src), 0, 0 + psq_st f4, 0x8(xPose), 0, 0 + ps_merge11 f5, f0, f1 + psq_l f3, 0x38(src), 0, 0 + psq_st f5, 0x18(xPose), 0, 0 + ps_merge00 f4, f2, f3 + psq_st f4, 0x28(xPose), 0, 0 + ps_merge11 f5, f2, f3 + psq_st f5, 0x38(xPose), 0, 0 + blr +} + +#define SWAP(a, b) \ + { \ + f32 tmp; \ + tmp = a; \ + a = b; \ + b = tmp; \ + } + +u32 C_MTX44Inverse(const Mtx44 src, Mtx44 inv) { + Mtx44 gjm; + s32 i; + s32 j; + s32 k; + f32 w; + f32 max; + s32 swp; + f32 ftmp; + + ASSERTMSGLINE(734, src, "MTX44Inverse(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(735, inv, "MTX44Inverse(): NULL Mtx44Ptr 'inv' "); + + MTX44Copy(src, gjm); + MTX44Identity(inv); + + for (i = 0; i < 4; i++) { + max = 0.0f; + swp = i; + + for (k = i; k < 4; k++) { + ftmp = fabsf(gjm[k][i]); + if (ftmp > max) { + max = ftmp; + swp = k; + } + } + + if (max == 0.0f) { + return 0; + } + + if (swp != i) { + for (k = 0; k < 4; k++) { + SWAP(gjm[i][k], gjm[swp][k]); + SWAP(inv[i][k], inv[swp][k]); + } + } + + w = 1.0f / gjm[i][i]; + for (j = 0; j < 4; j++) { + gjm[i][j] *= w; + inv[i][j] *= w; + } + + for (k = 0; k < 4; k++) { + if (k != i) { + w = gjm[k][i]; + for (j = 0; j < 4; j++) { + gjm[k][j] -= gjm[i][j] * w; + inv[k][j] -= inv[i][j] * w; + } + } + } + } + + return 1; +} + +void C_MTX44Trans(Mtx44 m, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(835, m, "MTX44Trans(): NULL Mtx44Ptr 'm' "); + + m[0][0] = 1.0f; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = xT; + + m[1][0] = 0.0f; + m[1][1] = 1.0f; + m[1][2] = 0.0f; + m[1][3] = yT; + + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 1.0f; + m[2][3] = zT; + + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + +void PSMTX44Trans(register Mtx44 m, register f32 xT, register f32 yT, register f32 zT) { + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; + register f32 c_01; + + asm { + stfs xT, 0xc(m) + stfs yT, 0x1c(m) + ps_merge00 c_01, c_zero, c_one + stfs zT, 0x2c(m) + psq_st c_one, 0x0(m), 1, 0 + psq_st c_zero, 0x4(m), 0, 0 + psq_st c_01, 0x10(m), 0, 0 + psq_st c_zero, 0x18(m), 1, 0 + psq_st c_zero, 0x20(m), 0, 0 + psq_st c_one, 0x28(m), 1, 0 + psq_st c_zero, 0x30(m), 0, 0 + psq_st c_01, 0x38(m), 0, 0 + } +} + +void C_MTX44TransApply(const Mtx44 src, Mtx44 dst, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(899, src, "MTX44TransApply(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(900, dst, "MTX44TransApply(): NULL Mtx44Ptr 'src' "); //! wrong assert string + + if (src != dst) { + dst[0][0] = src[0][0]; + dst[0][1] = src[0][1]; + dst[0][2] = src[0][2]; + + dst[1][0] = src[1][0]; + dst[1][1] = src[1][1]; + dst[1][2] = src[1][2]; + + dst[2][0] = src[2][0]; + dst[2][1] = src[2][1]; + dst[2][2] = src[2][2]; + + dst[3][0] = src[3][0]; + dst[3][1] = src[3][1]; + dst[3][2] = src[3][2]; + + dst[3][3] = src[3][3]; + } + + dst[0][3] = (src[0][3] + xT); + dst[1][3] = (src[1][3] + yT); + dst[2][3] = (src[2][3] + zT); +} + +asm void PSMTX44TransApply(const register Mtx44 src, register Mtx44 dst, register f32 xT, register f32 yT, register f32 zT) { + nofralloc + psq_l f4, 0x0(src), 0, 0 + frsp xT, xT + psq_l f5, 0x8(src), 0, 0 + frsp yT, yT + psq_l f6, 0x10(src), 0, 0 + frsp zT, zT + psq_l f7, 0x18(src), 0, 0 + psq_st f4, 0x0(dst), 0, 0 + ps_sum1 f5, xT, f5, f5 + psq_l f4, 0x28(src), 0, 0 + psq_st f6, 0x10(dst), 0, 0 + ps_sum1 f7, yT, f7, f7 + psq_l f8, 0x20(src), 0, 0 + psq_st f5, 0x8(dst), 0, 0 + ps_sum1 f4, zT, f4, f4 + psq_st f7, 0x18(dst), 0, 0 + psq_st f8, 0x20(dst), 0, 0 + psq_l f5, 0x30(src), 0, 0 + psq_l f6, 0x38(src), 0, 0 + psq_st f4, 0x28(dst), 0, 0 + psq_st f5, 0x30(dst), 0, 0 + psq_st f6, 0x38(dst), 0, 0 + blr +} + +void C_MTX44Scale(Mtx44 m, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(976, m, "MTX44Scale(): NULL Mtx44Ptr 'm' "); + m[0][0] = xS; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + + m[1][0] = 0.0f; + m[1][1] = yS; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = zS; + m[2][3] = 0.0f; + + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + +void PSMTX44Scale(register Mtx44 m, register f32 xS, register f32 yS, register f32 zS) { + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; + + asm { + stfs xS, 0x0(m) + psq_st c_zero, 0x4(m), 0, 0 + psq_st c_zero, 0xc(m), 0, 0 + stfs yS, 0x14(m) + psq_st c_zero, 0x18(m), 0, 0 + psq_st c_zero, 0x20(m), 0, 0 + stfs zS, 0x28(m) + psq_st c_zero, 0x2c(m), 0, 0 + psq_st c_zero, 0x34(m), 0, 0 + stfs c_one, 0x3c(m) + } +} + +void C_MTX44ScaleApply(const Mtx44 src, Mtx44 dst, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(1036, src, "MTX44ScaleApply(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(1037, dst, "MTX44ScaleApply(): NULL Mtx44Ptr 'dst' "); + + dst[0][0] = (src[0][0] * xS); + dst[0][1] = (src[0][1] * xS); + dst[0][2] = (src[0][2] * xS); + dst[0][3] = (src[0][3] * xS); + + dst[1][0] = (src[1][0] * yS); + dst[1][1] = (src[1][1] * yS); + dst[1][2] = (src[1][2] * yS); + dst[1][3] = (src[1][3] * yS); + + dst[2][0] = (src[2][0] * zS); + dst[2][1] = (src[2][1] * zS); + dst[2][2] = (src[2][2] * zS); + dst[2][3] = (src[2][3] * zS); + + dst[3][0] = src[3][0]; + dst[3][1] = src[3][1]; + dst[3][2] = src[3][2]; + dst[3][3] = src[3][3]; +} + +asm void PSMTX44ScaleApply(const register Mtx44 src, register Mtx44 dst, register f32 xS, register f32 yS, register f32 zS) { + nofralloc + psq_l f4, 0x0(src), 0, 0 + frsp xS, xS + psq_l f5, 0x8(src), 0, 0 + frsp yS, yS + psq_l f6, 0x10(src), 0, 0 + ps_muls0 f4, f4, xS + psq_l f7, 0x18(src), 0, 0 + ps_muls0 f5, f5, xS + psq_l f8, 0x20(src), 0, 0 + frsp zS, zS + psq_st f4, 0x0(dst), 0, 0 + ps_muls0 f6, f6, yS + psq_l f9, 0x28(src), 0, 0 + psq_st f5, 0x8(dst), 0, 0 + ps_muls0 f7, f7, yS + psq_l f10, 0x30(src), 0, 0 + psq_st f6, 0x10(dst), 0, 0 + ps_muls0 f8, f8, zS + psq_l f11, 0x38(src), 0, 0 + psq_st f7, 0x18(dst), 0, 0 + ps_muls0 f9, f9, zS + psq_st f8, 0x20(dst), 0, 0 + psq_st f9, 0x28(dst), 0, 0 + psq_st f10, 0x30(dst), 0, 0 + psq_st f11, 0x38(dst), 0, 0 + blr +} + +void C_MTX44RotRad(Mtx44 m, char axis, f32 rad) { + f32 sinA; + f32 cosA; + + ASSERTMSGLINE(1118, m, "MTX44RotRad(): NULL Mtx44Ptr 'm' "); + sinA = sinf(rad); + cosA = cosf(rad); + C_MTX44RotTrig(m, axis, sinA, cosA); +} + +void PSMTX44RotRad(Mtx44 m, char axis, f32 rad) { + f32 sinA; + f32 cosA; + + sinA = sinf(rad); + cosA = cosf(rad); + PSMTX44RotTrig(m, axis, sinA, cosA); +} + +void C_MTX44RotTrig(Mtx44 m, char axis, f32 sinA, f32 cosA) { + ASSERTMSGLINE(1163, m, "MTX44RotTrig(): NULL Mtx44Ptr 'm' "); + + axis |= 0x20; + switch(axis) { + case 'x': + m[0][0] = 1.0f; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + m[1][0] = 0.0f; + m[1][1] = cosA; + m[1][2] = -sinA; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = sinA; + m[2][2] = cosA; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; + break; + case 'y': + m[0][0] = cosA; + m[0][1] = 0.0f; + m[0][2] = sinA; + m[0][3] = 0.0f; + m[1][0] = 0.0f; + m[1][1] = 1.0f; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + m[2][0] = -sinA; + m[2][1] = 0.0f; + m[2][2] = cosA; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; + break; + case 'z': + m[0][0] = cosA; + m[0][1] = -sinA; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + m[1][0] = sinA; + m[1][1] = cosA; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 1.0f; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; + break; + default: + ASSERTMSGLINE(1191, FALSE, "MTX44RotTrig(): invalid 'axis' value "); + break; + } +} + +void PSMTX44RotTrig(register Mtx44 m, register char axis, register f32 sinA, register f32 cosA) { + register f32 ftmp0; + register f32 ftmp1; + register f32 ftmp2; + register f32 ftmp3; + register f32 ftmp4; + + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; + + asm { + frsp sinA, sinA + ori axis, axis, 0x20 + frsp cosA, cosA + cmplwi axis, 'x' + beq L_00001AB4 + cmplwi axis, 'y' + beq L_00001AE8 + cmplwi axis, 'z' + beq L_00001B20 + b L_00001B54 + L_00001AB4: + psq_st c_one, 0x0(m), 1, 0 + psq_st c_zero, 0x4(m), 0, 0 + ps_neg ftmp0, sinA + psq_st c_zero, 0xc(m), 0, 0 + ps_merge00 ftmp1, sinA, cosA + psq_st c_zero, 0x1c(m), 0, 0 + ps_merge00 ftmp0, cosA, ftmp0 + psq_st c_zero, 0x2c(m), 0, 0 + psq_st c_zero, 0x34(m), 0, 0 + psq_st ftmp1, 0x24(m), 0, 0 + psq_st ftmp0, 0x14(m), 0, 0 + psq_st c_one, 0x3c(m), 1, 0 + b L_00001B54 + L_00001AE8: + ps_merge00 ftmp1, cosA, c_zero + psq_st c_zero, 0x30(m), 0, 0 + ps_neg ftmp0, sinA + psq_st c_zero, 0x18(m), 0, 0 + ps_merge00 ftmp3, c_zero, c_one + psq_st ftmp1, 0x0(m), 0, 0 + ps_merge00 ftmp4, ftmp0, c_zero + ps_merge00 ftmp2, sinA, c_zero + psq_st ftmp3, 0x10(m), 0, 0 + psq_st ftmp2, 0x8(m), 0, 0 + psq_st ftmp4, 0x20(m), 0, 0 + psq_st ftmp1, 0x28(m), 0, 0 + psq_st ftmp3, 0x38(m), 0, 0 + b L_00001B54 + L_00001B20: + psq_st c_zero, 0x8(m), 0, 0 + ps_neg ftmp0, sinA + psq_st c_zero, 0x18(m), 0, 0 + ps_merge00 ftmp1, sinA, cosA + psq_st c_zero, 0x20(m), 0, 0 + ps_merge00 ftmp2, c_one, c_zero + psq_st c_zero, 0x30(m), 0, 0 + ps_merge00 ftmp3, c_zero, c_one + psq_st ftmp1, 0x10(m), 0, 0 + ps_merge00 ftmp4, cosA, ftmp0 + psq_st ftmp2, 0x28(m), 0, 0 + psq_st ftmp3, 0x38(m), 0, 0 + psq_st ftmp4, 0x0(m), 0, 0 + L_00001B54: + } +} + +void C_MTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad) { + Vec vN; + f32 s; + f32 c; + f32 t; + f32 x; + f32 y; + f32 z; + f32 xSq; + f32 ySq; + f32 zSq; + + ASSERTMSGLINE(1300, m, "MTX44RotAxisRad(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(1301, axis, "MTX44RotAxisRad(): NULL VecPtr 'axis' "); + + s = sinf(rad); + c = cosf(rad); + t = 1 - c; + + C_VECNormalize(axis, &vN); + + x = vN.x; + y = vN.y; + z = vN.z; + + xSq = (x * x); + ySq = (y * y); + zSq = (z * z); + + m[0][0] = (c + (t * xSq)); + m[0][1] = (y * (t * x)) - (s * z); + m[0][2] = (z * (t * x)) + (s * y); + m[0][3] = 0.0f; + + m[1][0] = ((y * (t * x)) + (s * z)); + m[1][1] = (c + (t * ySq)); + m[1][2] = ((z * (t * y)) - (s * x)); + m[1][3] = 0.0f; + + m[2][0] = ((z * (t * x)) - (s * y)); + m[2][1] = ((z * (t * y)) + (s * x)); + m[2][2] = (c + (t * zSq)); + m[2][3] = 0.0f; + + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + +static void __PSMTX44RotAxisRadInternal(register Mtx44 m, const register Vec* axis, register f32 sT, register f32 cT) { + register f32 tT; + register f32 fc0; + register f32 tmp0; + register f32 tmp1; + register f32 tmp2; + register f32 tmp3; + register f32 tmp4; + register f32 tmp5; + register f32 tmp6; + register f32 tmp7; + register f32 tmp8; + register f32 tmp9; + + tmp9 = 0.5f; + tmp8 = 3.0f; + + asm { + frsp cT, cT + psq_l tmp0, 0x0(axis), 0, 0 + frsp sT, sT + lfs tmp1, 0x8(axis) + ps_mul tmp2, tmp0, tmp0 + fadds tmp7, tmp9, tmp9 + ps_madd tmp3, tmp1, tmp1, tmp2 + fsubs fc0, tmp9, tmp9 + ps_sum0 tmp4, tmp3, tmp1, tmp2 + fsubs tT, tmp7, cT + frsqrte tmp5, tmp4 + ps_merge00 tmp7, fc0, tmp7 + fmuls tmp2, tmp5, tmp5 + fmuls tmp3, tmp5, tmp9 + psq_st fc0, 0x30(m), 0, 0 + fnmsubs tmp2, tmp2, tmp4, tmp8 + fmuls tmp5, tmp2, tmp3 + psq_st tmp7, 0x38(m), 0, 0 + ps_merge00 cT, cT, cT + ps_muls0 tmp0, tmp0, tmp5 + ps_muls0 tmp1, tmp1, tmp5 + ps_muls0 tmp4, tmp0, tT + ps_muls0 tmp9, tmp0, sT + ps_muls0 tmp5, tmp1, tT + ps_muls1 tmp3, tmp4, tmp0 + ps_muls0 tmp2, tmp4, tmp0 + ps_muls0 tmp4, tmp4, tmp1 + fnmsubs tmp6, tmp1, sT, tmp3 + fmadds tmp7, tmp1, sT, tmp3 + ps_neg tmp0, tmp9 + ps_sum0 tmp8, tmp4, fc0, tmp9 + ps_sum0 tmp2, tmp2, tmp6, cT + ps_sum1 tmp3, cT, tmp7, tmp3 + ps_sum0 tmp6, tmp0, fc0, tmp4 + psq_st tmp8, 0x8(m), 0, 0 + ps_sum0 tmp0, tmp4, tmp4, tmp0 + psq_st tmp2, 0x0(m), 0, 0 + ps_muls0 tmp5, tmp5, tmp1 + psq_st tmp3, 0x10(m), 0, 0 + ps_sum1 tmp4, tmp9, tmp0, tmp4 + psq_st tmp6, 0x18(m), 0, 0 + ps_sum0 tmp5, tmp5, fc0, cT + psq_st tmp4, 0x20(m), 0, 0 + psq_st tmp5, 0x28(m), 0, 0 + } +} + +void PSMTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad) { + f32 sinT, cosT; + + sinT = sinf(rad); + cosT = cosf(rad); + + __PSMTX44RotAxisRadInternal(m, axis, sinT, cosT); +} diff --git a/src/dolphin/mtx/mtx44vec.c b/src/dolphin/mtx/mtx44vec.c new file mode 100644 index 0000000..478c49f --- /dev/null +++ b/src/dolphin/mtx/mtx44vec.c @@ -0,0 +1,247 @@ +#include +#include +#include "fake_tgmath.h" + +void C_MTX44MultVec(const Mtx44 m, const Vec* src, Vec* dst) { + Vec vTmp; + f32 w; + + ASSERTMSGLINE(67, m, "MTX44MultVec(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(68, src, "MTX44MultVec(): NULL VecPtr 'src' "); + ASSERTMSGLINE(69, dst, "MTX44MultVec(): NULL VecPtr 'dst' "); + + vTmp.x = m[0][0] * src->x + m[0][1] * src->y + m[0][2] * src->z + m[0][3]; + vTmp.y = m[1][0] * src->x + m[1][1] * src->y + m[1][2] * src->z + m[1][3]; + vTmp.z = m[2][0] * src->x + m[2][1] * src->y + m[2][2] * src->z + m[2][3]; + w = m[3][0] * src->x + m[3][1] * src->y + m[3][2] * src->z + m[3][3]; + w = 1.0f / w; + + dst->x = vTmp.x * w; + dst->y = vTmp.y * w; + dst->z = vTmp.z * w; +} + +asm void PSMTX44MultVec(const register Mtx44 m, const register Vec* src, register Vec* dst) { + nofralloc + psq_l f0, 0x0(src), 0, 0 + psq_l f2, 0x30(m), 0, 0 + psq_l f1, 0x8(src), 1, 0 + ps_mul f4, f0, f2 + psq_l f3, 0x38(m), 0, 0 + ps_madd f5, f1, f3, f4 + ps_merge11 f12, f1, f1 + ps_sum0 f13, f5, f5, f5 + psq_l f4, 0x0(m), 0, 0 + ps_merge00 f13, f13, f13 + psq_l f5, 0x8(m), 0, 0 + ps_div f13, f12, f13 + psq_l f6, 0x10(m), 0, 0 + psq_l f7, 0x18(m), 0, 0 + psq_l f8, 0x20(m), 0, 0 + psq_l f9, 0x28(m), 0, 0 + ps_mul f4, f0, f4 + ps_madd f2, f1, f5, f4 + ps_mul f6, f0, f6 + ps_madd f3, f1, f7, f6 + ps_mul f8, f0, f8 + ps_sum0 f2, f2, f2, f2 + ps_madd f9, f1, f9, f8 + ps_sum1 f2, f3, f2, f3 + ps_sum0 f3, f9, f9, f9 + ps_mul f2, f2, f13 + psq_st f2, 0x0(dst), 0, 0 + ps_mul f3, f3, f13 + psq_st f3, 0x8(dst), 1, 0 + blr +} + +void C_MTX44MultVecArray(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count) { + u32 i; + Vec vTmp; + f32 w; + + ASSERTMSGLINE(154, m, "MTX44MultVecArray(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(155, srcBase, "MTX44MultVecArray(): NULL VecPtr 'srcBase' "); + ASSERTMSGLINE(156, dstBase, "MTX44MultVecArray(): NULL VecPtr 'dstBase' "); + + for(i = 0; i < count; i++) { + vTmp.x = m[0][0] * srcBase->x + m[0][1] * srcBase->y + m[0][2] * srcBase->z + m[0][3]; + vTmp.y = m[1][0] * srcBase->x + m[1][1] * srcBase->y + m[1][2] * srcBase->z + m[1][3]; + vTmp.z = m[2][0] * srcBase->x + m[2][1] * srcBase->y + m[2][2] * srcBase->z + m[2][3]; + w = m[3][0] * srcBase->x + m[3][1] * srcBase->y + m[3][2] * srcBase->z + m[3][3]; + w = 1.0f / w; + dstBase->x = vTmp.x * w; + dstBase->y = vTmp.y * w; + dstBase->z = vTmp.z * w; + srcBase++; + dstBase++; + } +} + +asm void PSMTX44MultVecArray(const register Mtx44 m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + stwu r1, -0x10(r1) + subi count, count, 0x1 + psq_l f6, 0x30(m), 0, 0 + mtctr count + psq_l f8, 0x0(srcBase), 0, 0 + subi dstBase, dstBase, 0x4 + psq_l f7, 0x38(m), 0, 0 + psq_lu f9, 0x8(srcBase), 1, 0 + ps_mul f13, f6, f8 + psq_l f0, 0x0(m), 0, 0 + stfd f14, 0x8(r1) + ps_madd f13, f7, f9, f13 + psq_l f2, 0x10(m), 0, 0 + ps_merge11 f14, f9, f9 + ps_mul f10, f0, f8 + psq_l f4, 0x20(m), 0, 0 + ps_mul f11, f2, f8 + psq_l f1, 0x8(m), 0, 0 + ps_mul f12, f4, f8 + psq_l f3, 0x18(m), 0, 0 + ps_sum0 f13, f13, f13, f13 + psq_l f5, 0x28(m), 0, 0 +L_00000468: + ps_madd f10, f1, f9, f10 + ps_madd f11, f3, f9, f11 + ps_madd f12, f5, f9, f12 + ps_sum0 f10, f10, f10, f10 + ps_sum0 f11, f11, f11, f11 + ps_sum0 f12, f12, f12, f12 + ps_div f13, f14, f13 + psq_lu f8, 0x4(srcBase), 0, 0 + psq_lu f9, 0x8(srcBase), 1, 0 + ps_mul f10, f10, f13 + psq_stu f10, 0x4(dstBase), 1, 0 + ps_mul f11, f11, f13 + psq_stu f11, 0x4(dstBase), 1, 0 + ps_mul f12, f12, f13 + psq_stu f12, 0x4(dstBase), 1, 0 + ps_mul f13, f6, f8 + ps_mul f10, f0, f8 + ps_mul f11, f2, f8 + ps_madd f13, f7, f9, f13 + ps_mul f12, f4, f8 + ps_sum0 f13, f13, f13, f13 + bdnz L_00000468 + ps_madd f10, f1, f9, f10 + ps_madd f11, f3, f9, f11 + ps_madd f12, f5, f9, f12 + ps_sum0 f10, f10, f10, f10 + ps_sum0 f11, f11, f11, f11 + ps_sum0 f12, f12, f12, f12 + ps_div f13, f14, f13 + ps_mul f10, f10, f13 + psq_st f10, 0x4(dstBase), 1, 0 + ps_mul f11, f11, f13 + psq_st f11, 0x8(dstBase), 1, 0 + ps_mul f12, f12, f13 + psq_st f12, 0xc(dstBase), 1, 0 + lfd f14, 0x8(r1) + addi r1, r1, 0x10 + blr +} + +void C_MTX44MultVecSR(const Mtx44 m, const Vec* src, Vec* dst) { + Vec vTmp; + + ASSERTMSGLINE(288, m, "MTX44MultVecSR(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(289, src, "MTX44MultVecSR(): NULL VecPtr 'src' "); + ASSERTMSGLINE(290, dst, "MTX44MultVecSR(): NULL VecPtr 'dst' "); + vTmp.x = (m[0][2] * src->z) + ((m[0][0] * src->x) + (m[0][1] * src->y)); + vTmp.y = (m[1][2] * src->z) + ((m[1][0] * src->x) + (m[1][1] * src->y)); + vTmp.z = (m[2][2] * src->z) + ((m[2][0] * src->x) + (m[2][1] * src->y)); + dst->x = vTmp.x; + dst->y = vTmp.y; + dst->z = vTmp.z; +} + +asm void PSMTX44MultVecSR(const register Mtx m, const register Vec* src, register Vec* dst) { + nofralloc + psq_l f0, 0x0(m), 0, 0 + psq_l f6, 0x0(src), 0, 0 + psq_l f2, 0x10(m), 0, 0 + ps_mul f8, f0, f6 + psq_l f4, 0x20(m), 0, 0 + ps_mul f10, f2, f6 + psq_l f7, 0x8(src), 1, 0 + ps_mul f12, f4, f6 + psq_l f3, 0x18(m), 0, 0 + ps_sum0 f8, f8, f8, f8 + psq_l f5, 0x28(m), 0, 0 + ps_sum0 f10, f10, f10, f10 + psq_l f1, 0x8(m), 0, 0 + ps_sum0 f12, f12, f12, f12 + ps_madd f9, f1, f7, f8 + psq_st f9, 0x0(dst), 1, 0 + ps_madd f11, f3, f7, f10 + psq_st f11, 0x4(dst), 1, 0 + ps_madd f13, f5, f7, f12 + psq_st f13, 0x8(dst), 1, 0 + blr +} + +void C_MTX44MultVecArraySR(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count) { + u32 i; + Vec vTmp; + + ASSERTMSGLINE(379, m, "MTX44MultVecArraySR(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(380, srcBase, "MTX44MultVecArraySR(): NULL VecPtr 'srcBase' "); + ASSERTMSGLINE(381, dstBase, "MTX44MultVecArraySR(): NULL VecPtr 'dstBase' "); + + for(i = 0; i < count; i++) { + vTmp.x = (m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y)); + vTmp.y = (m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y)); + vTmp.z = (m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y)); + dstBase->x = vTmp.x; + dstBase->y = vTmp.y; + dstBase->z = vTmp.z; + srcBase++; + dstBase++; + } +} + +asm void PSMTX44MultVecArraySR(const register Mtx44 m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + psq_l f0, 0x0(m), 0, 0 + subi count, count, 0x1 + psq_l f6, 0x0(srcBase), 0, 0 + ps_mul f8, f0, f6 + psq_l f2, 0x10(m), 0, 0 + ps_mul f9, f2, f6 + psq_l f4, 0x20(m), 0, 0 + psq_lu f7, 0x8(srcBase), 1, 0 + ps_mul f10, f4, f6 + psq_l f1, 0x8(m), 1, 0 + mtctr count + psq_l f3, 0x18(m), 1, 0 + subi dstBase, dstBase, 0x4 + psq_l f5, 0x28(m), 1, 0 +L_00000890: + ps_madd f11, f1, f7, f8 + psq_lu f6, 0x4(srcBase), 0, 0 + ps_madd f12, f3, f7, f9 + ps_madd f13, f5, f7, f10 + psq_lu f7, 0x8(srcBase), 1, 0 + ps_sum0 f11, f11, f8, f8 + psq_stu f11, 0x4(dstBase), 1, 0 + ps_sum0 f12, f12, f9, f9 + psq_stu f12, 0x4(dstBase), 1, 0 + ps_sum0 f13, f13, f10, f10 + psq_stu f13, 0x4(dstBase), 1, 0 + ps_mul f8, f0, f6 + ps_mul f9, f2, f6 + ps_mul f10, f4, f6 + bdnz L_00000890 + ps_madd f11, f1, f7, f8 + ps_madd f12, f3, f7, f9 + ps_madd f13, f5, f7, f10 + ps_sum0 f11, f11, f8, f8 + psq_stu f11, 0x4(dstBase), 1, 0 + ps_sum0 f12, f12, f9, f9 + psq_stu f12, 0x4(dstBase), 1, 0 + ps_sum0 f13, f13, f10, f10 + psq_stu f13, 0x4(dstBase), 1, 0 + blr +} diff --git a/src/dolphin/mtx/mtxstack.c b/src/dolphin/mtx/mtxstack.c new file mode 100644 index 0000000..475175c --- /dev/null +++ b/src/dolphin/mtx/mtxstack.c @@ -0,0 +1,108 @@ +#include +#include +#include "fake_tgmath.h" + +void MTXInitStack(MTXStack* sPtr, u32 numMtx) { + ASSERTMSGLINE(74, sPtr, "MTXInitStack(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(75, sPtr->stackBase, "MTXInitStack(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(76, numMtx, "MTXInitStack(): 'numMtx' is 0 "); + + sPtr->numMtx = numMtx; + sPtr->stackPtr = 0; +} + +MtxPtr MTXPush(MTXStack* sPtr, const Mtx m) { + ASSERTMSGLINE(104, sPtr, "MTXPush(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(105, sPtr->stackBase, "MTXPush(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(106, m, "MTXPush(): NULL MtxPtr 'm' "); + + if (sPtr->stackPtr == NULL) { + sPtr->stackPtr = sPtr->stackBase; + MTXCopy(m, sPtr->stackPtr); + } else { + ASSERTMSGLINE(121, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPush(): stack overflow "); + MTXCopy(m, sPtr->stackPtr + 3); + sPtr->stackPtr += 3; + } + + return sPtr->stackPtr; +} + +MtxPtr MTXPushFwd(MTXStack* sPtr, const Mtx m) { + ASSERTMSGLINE(157, sPtr, "MTXPushFwd(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(158, sPtr->stackBase, "MTXPushFwd(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(159, m, "MTXPushFwd(): NULL MtxPtr 'm' "); + + if (sPtr->stackPtr == NULL) { + sPtr->stackPtr = sPtr->stackBase; + MTXCopy(m, sPtr->stackPtr); + } else { + ASSERTMSGLINE(174, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushFwd(): stack overflow"); + MTXConcat(sPtr->stackPtr, m, sPtr->stackPtr + 3); + sPtr->stackPtr += 3; + } + + return sPtr->stackPtr; +} + +MtxPtr MTXPushInv(MTXStack* sPtr, const Mtx m) { + Mtx mInv; + ASSERTMSGLINE(216, sPtr, "MTXPushInv(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(217, sPtr->stackBase, "MTXPushInv(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(218, m, "MTXPushInv(): NULL MtxPtr 'm' "); + + MTXInverse(m, mInv); + if (sPtr->stackPtr == NULL) { + sPtr->stackPtr = sPtr->stackBase; + MTXCopy(mInv, sPtr->stackPtr); + } else { + ASSERTMSGLINE(236, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushInv(): stack overflow"); + MTXConcat(mInv, sPtr->stackPtr, sPtr->stackPtr + 3); + sPtr->stackPtr += 3; + } + + return sPtr->stackPtr; +} + +MtxPtr MTXPushInvXpose(MTXStack* sPtr, const Mtx m) { + Mtx mIT; + ASSERTMSGLINE(279, sPtr, "MTXPushInvXpose(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(280, sPtr->stackBase, "MTXPushInvXpose(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(281, m, "MTXPushInvXpose(): NULL MtxPtr 'm' "); + + MTXInverse(m, mIT); + MTXTranspose(mIT, mIT); + if (sPtr->stackPtr == NULL) { + sPtr->stackPtr = sPtr->stackBase; + MTXCopy(mIT, sPtr->stackPtr); + } else { + ASSERTMSGLINE(300, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushInvXpose(): stack overflow "); + MTXConcat(sPtr->stackPtr, mIT, sPtr->stackPtr + 3); + sPtr->stackPtr += 3; + } + + return sPtr->stackPtr; +} + +MtxPtr MTXPop(MTXStack* sPtr) { + ASSERTMSGLINE(328, sPtr, "MTXPop(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(329, sPtr->stackBase, "MTXPop(): 'sPtr' contains a NULL ptr to stack memory "); + + if (sPtr->stackPtr == NULL) { + return NULL; + } + + if (sPtr->stackBase == sPtr->stackPtr) { + sPtr->stackPtr = NULL; + return NULL; + } + + sPtr->stackPtr -= 3; + return sPtr->stackPtr; +} + +MtxPtr MTXGetStackPtr(const MTXStack* sPtr) { + ASSERTMSGLINE(366, sPtr, "MTXGetStackPtr(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(367, sPtr->stackBase, "MTXGetStackPtr(): 'sPtr' contains a NULL ptr to stack memory "); + return sPtr->stackPtr; +} diff --git a/src/dolphin/mtx/mtxvec.c b/src/dolphin/mtx/mtxvec.c new file mode 100644 index 0000000..47146ee --- /dev/null +++ b/src/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/src/dolphin/mtx/psmtx.c b/src/dolphin/mtx/psmtx.c new file mode 100644 index 0000000..6ec6c29 --- /dev/null +++ b/src/dolphin/mtx/psmtx.c @@ -0,0 +1,336 @@ +#include +#include +#include "fake_tgmath.h" + +asm void PSMTXReorder(const register Mtx src, register ROMtx dest) { + psq_l f0, 0(src), 0, 0 + psq_l f2, 16(src), 0, 0 + psq_l f4, 32(src), 0, 0 + psq_l f1, 8(src), 0, 0 + ps_merge00 f6, f0, f2 + psq_l f3, 24(src), 0, 0 + ps_merge01 f12, f4, f0 + psq_l f5, 40(src), 0, 0 + ps_merge11 f7, f2, f4 + psq_st f6, 0(dest), 0, 0 + ps_merge00 f8, f1, f3 + psq_st f12, 8(dest), 0, 0 + ps_merge01 f9, f5, f1 + psq_st f7, 16(dest), 0, 0 + ps_merge11 f10, f3, f5 + psq_st f8, 24(dest), 0, 0 + psq_st f9, 32(dest), 0, 0 + psq_st f10, 40(dest), 0, 0 +} + +asm void PSMTXROMultVecArray(const register ROMtx m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + stwu r1, -64(r1) + stfd f14, 8(r1) + subi r7, count, 1 + stfd f15, 16(r1) + srwi r7, r7, 1 + stfd f16, 24(r1) + stfd f17, 32(r1) + stfd f18, 40(r1) + mtctr r7 + psq_l f0, 0(m), 0, 0 + subi srcBase, srcBase, 8 + psq_l f1, 8(m), 1, 0 + subi dstBase, dstBase, 4 + psq_l f6, 36(m), 0, 0 + psq_lu f8, 8(srcBase), 0, 0 + psq_l f7, 44(m), 1, 0 + psq_lu f9, 8(srcBase), 0, 0 + ps_madds0 f11, f0, f8, f6 + psq_l f2, 12(m), 0, 0 + ps_madds0 f12, f1, f8, f7 + psq_l f3, 20(m), 1, 0 + ps_madds1 f13, f0, f9, f6 + psq_lu f10, 8(srcBase), 0, 0 + ps_madds1 f14, f1, f9, f7 + psq_l f5, 32(m), 1, 0 + ps_madds1 f11, f2, f8, f11 + ps_madds1 f12, f3, f8, f12 + psq_l f4, 24(m), 0, 0 + ps_madds0 f13, f2, f10, f13 + psq_lu f8, 8(srcBase), 0, 0 + ps_madds0 f14, f3, f10, f14 + ps_madds0 f15, f4, f9, f11 + ps_madds0 f16, f5, f9, f12 + psq_lu f9, 8(srcBase), 0, 0 + ps_madds1 f17, f4, f10, f13 + ps_madds1 f18, f5, f10, f14 + psq_lu f10, 8(srcBase), 0, 0 +loop: + ps_madds0 f11, f0, f8, f6 + psq_stu f15, 4(dstBase), 0, 0 + ps_madds0 f12, f1, f8, f7 + psq_stu f16, 8(dstBase), 1, 0 + ps_madds1 f13, f0, f9, f6 + psq_stu f17, 4(dstBase), 0, 0 + ps_madds1 f14, f1, f9, f7 + psq_stu f18, 8(dstBase), 1, 0 + ps_madds1 f11, f2, f8, f11 + ps_madds1 f12, f3, f8, f12 + psq_lu f8, 8(srcBase), 0, 0 + ps_madds0 f13, f2, f10, f13 + ps_madds0 f14, f3, f10, f14 + ps_madds0 f15, f4, f9, f11 + ps_madds0 f16, f5, f9, f12 + psq_lu f9, 8(srcBase), 0, 0 + ps_madds1 f17, f4, f10, f13 + ps_madds1 f18, f5, f10, f14 + psq_lu f10, 8(srcBase), 0, 0 + bdnz loop + psq_stu f15, 4(dstBase), 0, 0 + clrlwi. r7, count, 31 + psq_stu f16, 8(dstBase), 1, 0 + bne exit + psq_stu f17, 4(dstBase), 0, 0 + psq_stu f18, 8(dstBase), 1, 0 +exit: + lfd f14, 8(r1) + lfd f15, 16(r1) + lfd f16, 24(r1) + lfd f17, 32(r1) + lfd f18, 40(r1) + addi r1, r1, 64 + blr +} + +asm void PSMTXROSkin2VecArray(const register ROMtx m0, const register ROMtx m1, const register f32* wtBase, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + stwu r1, -160(r1) + stfd f14, 8(r1) + stfd f15, 16(r1) + stfd f16, 24(r1) + stfd f17, 32(r1) + stfd f18, 40(r1) + stfd f19, 48(r1) + stfd f20, 56(r1) + stfd f21, 64(r1) + stfd f22, 72(r1) + stfd f23, 80(r1) + stfd f24, 88(r1) + stfd f25, 96(r1) + stfd f26, 104(r1) + stfd f27, 112(r1) + stfd f28, 120(r1) + stfd f29, 128(r1) + stfd f30, 136(r1) + subi r9, r8, 1 + mtctr r9 + subi srcBase, srcBase, 4 + subi dstBase, dstBase, 4 + subi wtBase, wtBase, 4 + psq_l f14, 0(m0), 0, 0 + psq_l f22, 0(m1), 0, 0 + psq_l f15, 8(m0), 1, 0 + psq_l f23, 8(m1), 1, 0 + psq_l f16, 12(m0), 0, 0 + psq_l f24, 12(m1), 0, 0 + ps_sub f22, f22, f14 + psq_l f17, 20(m0), 1, 0 + psq_l f25, 20(m1), 1, 0 + ps_sub f23, f23, f15 + psq_l f18, 24(m0), 0, 0 + psq_l f26, 24(m1), 0, 0 + ps_sub f24, f24, f16 + psq_l f19, 32(m0), 1, 0 + psq_l f27, 32(m1), 1, 0 + ps_sub f25, f25, f17 + psq_l f20, 36(m0), 0, 0 + psq_l f28, 36(m1), 0, 0 + ps_sub f26, f26, f18 + psq_l f21, 44(m0), 1, 0 + psq_l f29, 44(m1), 1, 0 + ps_sub f27, f27, f19 + ps_sub f28, f28, f20 + ps_sub f29, f29, f21 + psq_lu f30, 4(wtBase), 1, 0 + psq_lu f8, 4(srcBase), 0, 0 + psq_lu f9, 8(srcBase), 1, 0 + ps_madds0 f0, f22, f30, f14 + ps_madds0 f1, f23, f30, f15 + ps_madds0 f2, f24, f30, f16 + ps_madds0 f3, f25, f30, f17 + ps_madds0 f4, f26, f30, f18 + ps_madds0 f5, f27, f30, f19 + ps_madds0 f6, f28, f30, f20 + ps_madds0 f7, f29, f30, f21 + ps_madds0 f12, f0, f8, f6 + ps_madds0 f13, f1, f8, f7 + psq_lu f30, 4(wtBase), 1, 0 +loop: + ps_madds1 f12, f2, f8, f12 + ps_madds1 f13, f3, f8, f13 + psq_lu f8, 4(srcBase), 0, 0 + ps_madds0 f10, f4, f9, f12 + ps_madds0 f11, f5, f9, f13 + psq_lu f9, 8(srcBase), 1, 0 + ps_madds0 f0, f22, f30, f14 + ps_madds0 f1, f23, f30, f15 + ps_madds0 f2, f24, f30, f16 + ps_madds0 f3, f25, f30, f17 + ps_madds0 f4, f26, f30, f18 + ps_madds0 f5, f27, f30, f19 + ps_madds0 f6, f28, f30, f20 + ps_madds0 f7, f29, f30, f21 + psq_stu f10, 4(dstBase), 0, 0 + ps_madds0 f12, f0, f8, f6 + ps_madds0 f13, f1, f8, f7 + psq_stu f11, 8(dstBase), 1, 0 + psq_lu f30, 4(wtBase), 1, 0 + bdnz loop + ps_madds1 f12, f2, f8, f12 + ps_madds1 f13, f3, f8, f13 + ps_madds0 f10, f4, f9, f12 + psq_stu f10, 4(dstBase), 0, 0 + ps_madds0 f11, f5, f9, f13 + psq_stu f11, 8(dstBase), 1, 0 + lfd f14, 8(r1) + lfd f15, 16(r1) + lfd f16, 24(r1) + lfd f17, 32(r1) + lfd f18, 40(r1) + lfd f19, 48(r1) + lfd f20, 56(r1) + lfd f21, 64(r1) + lfd f22, 72(r1) + lfd f23, 80(r1) + lfd f24, 88(r1) + lfd f25, 96(r1) + lfd f26, 104(r1) + lfd f27, 112(r1) + lfd f28, 120(r1) + lfd f29, 128(r1) + lfd f30, 136(r1) + addi r1, r1, 160 + blr +} + +asm void PSMTXROMultS16VecArray(const register Mtx m, const register S16Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + stwu r1, -64(r1) + stfd f14, 8(r1) + subi r7, count, 1 + stfd f15, 16(r1) + srwi r7, r7, 1 + stfd f16, 24(r1) + lis r8, 7 + stfd f17, 32(r1) + mtspr GQR6, r8 + stfd f18, 40(r1) + mtctr r7 + psq_l f0, 0(m), 0, 0 + subi srcBase, srcBase, 4 + psq_l f1, 8(m), 1, 0 + subi dstBase, dstBase, 4 + psq_l f6, 36(m), 0, 0 + psq_lu f8, 4(srcBase), 0, 6 + psq_l f7, 44(m), 1, 0 + psq_lu f9, 4(srcBase), 0, 6 + ps_madds0 f11, f0, f8, f6 + psq_l f2, 12(m), 0, 0 + ps_madds0 f12, f1, f8, f7 + psq_l f3, 20(m), 1, 0 + ps_madds1 f13, f0, f9, f6 + psq_lu f10, 4(srcBase), 0, 6 + ps_madds1 f14, f1, f9, f7 + psq_l f5, 32(m), 1, 0 + ps_madds1 f11, f2, f8, f11 + ps_madds1 f12, f3, f8, f12 + psq_l f4, 24(m), 0, 0 + ps_madds0 f13, f2, f10, f13 + psq_lu f8, 4(srcBase), 0, 6 + ps_madds0 f14, f3, f10, f14 + ps_madds0 f15, f4, f9, f11 + ps_madds0 f16, f5, f9, f12 + psq_lu f9, 4(srcBase), 0, 6 + ps_madds1 f17, f4, f10, f13 + ps_madds1 f18, f5, f10, f14 + psq_lu f10, 4(srcBase), 0, 6 +loop: + ps_madds0 f11, f0, f8, f6 + psq_stu f15, 4(dstBase), 0, 0 + ps_madds0 f12, f1, f8, f7 + psq_stu f16, 8(dstBase), 1, 0 + ps_madds1 f13, f0, f9, f6 + psq_stu f17, 4(dstBase), 0, 0 + ps_madds1 f14, f1, f9, f7 + psq_stu f18, 8(dstBase), 1, 0 + ps_madds1 f11, f2, f8, f11 + ps_madds1 f12, f3, f8, f12 + psq_lu f8, 4(srcBase), 0, 6 + ps_madds0 f13, f2, f10, f13 + ps_madds0 f14, f3, f10, f14 + ps_madds0 f15, f4, f9, f11 + ps_madds0 f16, f5, f9, f12 + psq_lu f9, 4(srcBase), 0, 6 + ps_madds1 f17, f4, f10, f13 + ps_madds1 f18, f5, f10, f14 + psq_lu f10, 4(srcBase), 0, 6 + bdnz loop + psq_stu f15, 4(dstBase), 0, 0 + clrlwi. r7, count, 31 + psq_stu f16, 8(dstBase), 1, 0 + bne exit + psq_stu f17, 4(dstBase), 0, 0 + psq_stu f18, 8(dstBase), 1, 0 +exit: + lfd f14, 8(r1) + lfd f15, 16(r1) + lfd f16, 24(r1) + lfd f17, 32(r1) + lfd f18, 40(r1) + addi r1, r1, 64 + blr +} + +asm void PSMTXMultS16VecArray(const register ROMtx* m, const register S16Vec* srcBase, register Vec* dstBase, register u32 count) { + psq_l f0, 0(m), 0, 0 + lis r7, 7 + mtspr GQR6, r7 + psq_l f6, 0(srcBase), 0, 6 + subi count, count, 1 + psq_l f7, 4(srcBase), 1, 6 + mtctr count + psq_l f1, 8(m), 0, 0 + addi srcBase, srcBase, 4 + psq_l f2, 16(m), 0, 0 + subi dstBase, dstBase, 4 + psq_l f3, 24(m), 0, 0 + ps_mul f8, f0, f6 + psq_l f4, 32(m), 0, 0 + ps_mul f10, f2, f6 + psq_l f5, 40(m), 0, 0 + ps_mul f12, f4, f6 + psq_lu f6, 2(srcBase), 0, 6 + ps_madd f8, f1, f7, f8 + ps_madd f10, f3, f7, f10 + ps_madd f12, f5, f7, f12 + psq_lu f7, 4(srcBase), 1, 6 + ps_sum0 f9, f8, f8, f8 +loop: + ps_sum0 f11, f10, f10, f10 + ps_mul f8, f0, f6 + ps_sum0 f13, f12, f12, f12 + ps_mul f10, f2, f6 + psq_stu f9, 4(dstBase), 1, 0 + ps_mul f12, f4, f6 + psq_stu f11, 4(dstBase), 1, 0 + ps_madd f8, f1, f7, f8 + psq_stu f13, 4(dstBase), 1, 0 + ps_madd f10, f3, f7, f10 + psq_lu f6, 2(srcBase), 0, 6 + ps_madd f12, f5, f7, f12 + psq_lu f7, 4(srcBase), 1, 6 + ps_sum0 f9, f8, f8, f8 + bdnz loop + ps_sum0 f11, f10, f10, f10 + ps_sum0 f13, f12, f12, f12 + psq_stu f9, 4(dstBase), 1, 0 + psq_stu f11, 4(dstBase), 1, 0 + psq_stu f13, 4(dstBase), 1, 0 +} diff --git a/src/dolphin/mtx/quat.c b/src/dolphin/mtx/quat.c new file mode 100644 index 0000000..79687f0 --- /dev/null +++ b/src/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/src/dolphin/mtx/vec.c b/src/dolphin/mtx/vec.c new file mode 100644 index 0000000..994ee18 --- /dev/null +++ b/src/dolphin/mtx/vec.c @@ -0,0 +1,344 @@ +#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* 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(const Vec* a, const Vec* b, Vec* a_b) { + ASSERTMSGLINE(177, a, "VECSubtract(): NULL VecPtr 'a' "); + ASSERTMSGLINE(178, b, "VECSubtract(): NULL VecPtr 'b' "); + ASSERTMSGLINE(179, a_b, "VECSubtract(): NULL VecPtr 'a_b' "); + a_b->x = a->x - b->x; + a_b->y = a->y - b->y; + a_b->z = a->z - b->z; +} + +asm void PSVECSubtract(const register Vec* a, const register Vec* b, register Vec* a_b) { + psq_l f2, Vec.x(a), 0, 0 + psq_l f4, Vec.x(b), 0, 0 + ps_sub f6, f2, f4 + psq_st f6, Vec.x(a_b), 0, 0 + psq_l f3, Vec.z(a), 1, 0 + psq_l f5, Vec.z(b), 1, 0 + ps_sub f7, f3, f5 + psq_st f7, Vec.z(a_b), 1, 0 +} + +void C_VECScale(const Vec* src, Vec* dst, f32 scale) { + 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(const register Vec* src, register Vec* dst, register f32 scale) { + register f32 vxy, vz, rxy, rz; + + 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 + } +} + +void C_VECNormalize(const Vec* src, Vec* unit) { + f32 mag; + + ASSERTMSGLINE(315, src, "VECNormalize(): NULL VecPtr 'src' "); + ASSERTMSGLINE(316, unit, "VECNormalize(): NULL VecPtr 'unit' "); + + mag = (src->z * src->z) + ((src->x * src->x) + (src->y * src->y)); + ASSERTMSGLINE(321, 0.0f != mag, "VECNormalize(): zero magnitude vector "); + + mag = 1.0f/ sqrtf(mag); + unit->x = src->x * mag; + unit->y = src->y * mag; + unit->z = src->z * mag; +} + +void PSVECNormalize(const register Vec* src, register Vec* unit) { + register float c_half = 0.5f; + register float c_three = 3.0f; + register float v1_xy; + register float v1_z; + register float xx_zz; + register float xx_yy; + register float sqsum; + register float rsqrt; + register float nwork0; + register float nwork1; + + asm { + psq_l v1_xy, 0x0(src), 0, 0 + ps_mul xx_yy, v1_xy, v1_xy + psq_l v1_z, 0x8(src), 1, 0 + ps_madd xx_zz, v1_z, v1_z, xx_yy + ps_sum0 sqsum, xx_zz, v1_z, xx_yy + frsqrte rsqrt, sqsum + fmuls nwork0, rsqrt, rsqrt + fmuls nwork1, rsqrt, c_half + fnmsubs nwork0, nwork0, sqsum, c_three + fmuls rsqrt, nwork0, nwork1 + ps_muls0 v1_xy, v1_xy, rsqrt + psq_st v1_xy, 0x0(unit), 0, 0 + ps_muls0 v1_z, v1_z, rsqrt + psq_st v1_z, 0x8(unit), 1, 0 + } +} + +f32 C_VECSquareMag(const Vec* v) { + f32 sqmag; + + ASSERTMSGLINE(405, v, "VECMag(): NULL VecPtr 'v' "); + + sqmag = v->z * v->z + ((v->x * v->x) + (v->y * v->y)); + return sqmag; +} + +f32 PSVECSquareMag(const register Vec* v) { + register f32 vxy, vzz, sqmag; + + asm { + psq_l vxy, 0x0(v), 0, 0 + ps_mul vxy, vxy, vxy + lfs vzz, 0x8(v) + ps_madd sqmag, vzz, vzz, vxy + ps_sum0 sqmag, sqmag, vxy, vxy + } + + return sqmag; +} + +f32 C_VECMag(const Vec* v) { + return sqrtf(C_VECSquareMag(v)); +} + +f32 PSVECMag(const register Vec* v) { + register f32 vxy, vzz; + register f32 sqmag, rmag; + register f32 nwork0, nwork1; + register f32 c_three, c_half, c_zero; + + c_half = 0.5f; + + asm { + psq_l vxy, 0x0(v), 0, 0 + ps_mul vxy, vxy, vxy + lfs vzz, 0x8(v) + fsubs c_zero, c_half, c_half + ps_madd sqmag, vzz, vzz, vxy + ps_sum0 sqmag, sqmag, vxy, vxy + fcmpu cr0, sqmag, c_zero + beq L_000005F0 + frsqrte rmag, sqmag + } + + c_three = 3.0f; + + asm { + fmuls nwork0, rmag, rmag + fmuls nwork1, rmag, c_half + fnmsubs nwork0, nwork0, sqmag, c_three + fmuls rmag, nwork0, nwork1 + fmuls sqmag, sqmag, rmag + L_000005F0: + } + + return sqmag; +} + +f32 C_VECDotProduct(const Vec* a, const Vec* b) { + f32 dot; + + 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(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(const Vec* a, const Vec* b, Vec* axb) { + Vec vTmp; + + ASSERTMSGLINE(602, a, "VECCrossProduct(): NULL VecPtr 'a' "); + ASSERTMSGLINE(603, b, "VECCrossProduct(): NULL VecPtr 'b' "); + ASSERTMSGLINE(604, axb, "VECCrossProduct(): NULL VecPtr 'axb' "); + + vTmp.x = (a->y * b->z) - (a->z * b->y); + vTmp.y = (a->z * b->x) - (a->x * b->z); + vTmp.z = (a->x * b->y) - (a->y * b->x); + axb->x = vTmp.x; + axb->y = vTmp.y; + axb->z = vTmp.z; +} + +asm void PSVECCrossProduct(const register Vec* a, const register Vec* b, register Vec* axb) { + psq_l f1, Vec.x(b), 0, 0 + lfs f2, Vec.z(a) + psq_l f0, Vec.x(a), 0, 0 + ps_merge10 f6, f1, f1 + lfs f3, Vec.z(b) + ps_mul f4, f1, f2 + ps_muls0 f7, f1, f0 + ps_msub f5, f0, f3, f4 + ps_msub f8, f0, f6, f7 + ps_merge11 f9, f5, f5 + ps_merge01 f10, f5, f8 + psq_st f9, Vec.x(axb), 1, 0 + ps_neg f10, f10 + psq_st f10, Vec.y(axb), 0, 0 +} + +void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half) { + Vec aTmp; + Vec bTmp; + Vec hTmp; + + ASSERTMSGLINE(707, a, "VECHalfAngle(): NULL VecPtr 'a' "); + ASSERTMSGLINE(708, b, "VECHalfAngle(): NULL VecPtr 'b' "); + ASSERTMSGLINE(709, half, "VECHalfAngle(): NULL VecPtr 'half' "); + + aTmp.x = -a->x; + aTmp.y = -a->y; + aTmp.z = -a->z; + bTmp.x = -b->x; + bTmp.y = -b->y; + bTmp.z = -b->z; + + VECNormalize(&aTmp, &aTmp); + VECNormalize(&bTmp, &bTmp); + VECAdd(&aTmp, &bTmp, &hTmp); + + if (VECDotProduct(&hTmp, &hTmp) > 0.0f) { + VECNormalize(&hTmp, half); + return; + } + *half = hTmp; +} + +void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst) { + f32 cosA; + Vec uI; + Vec uN; + + ASSERTMSGLINE(763, src, "VECReflect(): NULL VecPtr 'src' "); + ASSERTMSGLINE(764, normal, "VECReflect(): NULL VecPtr 'normal' "); + ASSERTMSGLINE(765, dst, "VECReflect(): NULL VecPtr 'dst' "); + + uI.x = -src->x; + uI.y = -src->y; + uI.z = -src->z; + + VECNormalize(&uI, &uI); + VECNormalize(normal, &uN); + + cosA = VECDotProduct(&uI, &uN); + dst->x = (2.0f * uN.x * cosA) - uI.x; + dst->y = (2.0f * uN.y * cosA) - uI.y; + dst->z = (2.0f * uN.z * cosA) - uI.z; + VECNormalize(dst, dst); +} + +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 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; +} + +f32 C_VECDistance(const Vec* a, const Vec* b) { + return sqrtf(C_VECSquareDistance(a, b)); +} + +f32 PSVECDistance(const register Vec* a, const register Vec* b) { + register f32 v0yz, v1yz, v0xy, v1xy, dyz, dxy; + register f32 sqdist, rdist; + register f32 nwork0, nwork1; + register f32 c_half, c_three, c_zero; + + asm { + 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/src/dolphin/odemustubs/odemustubs.c b/src/dolphin/odemustubs/odemustubs.c new file mode 100644 index 0000000..1014fc3 --- /dev/null +++ b/src/dolphin/odemustubs/odemustubs.c @@ -0,0 +1,34 @@ +#include + +// prototypes +__declspec(weak) int Hu_IsStub(); +void DBInitInterrupts(); +s32 DBQueryData(); +u32 DBRead(); +u32 DBWrite(); +void DBOpen(); +void DBClose(); + +__declspec(weak) int Hu_IsStub() { + return 1; +} + +void DBInitComm(int* inputFlagPtr, int* mtrCallback) {} + +void DBInitInterrupts() {} + +s32 DBQueryData() { + return 0; +} + +u32 DBRead() { + return 0; +} + +u32 DBWrite() { + return 0; +} + +void DBOpen() {} + +void DBClose() {} diff --git a/src/dolphin/odenotstub/odenotstub.c b/src/dolphin/odenotstub/odenotstub.c new file mode 100644 index 0000000..fd35d7a --- /dev/null +++ b/src/dolphin/odenotstub/odenotstub.c @@ -0,0 +1,8 @@ +#include + +// prototypes +__declspec(weak) int Hu_IsStub(); + +__declspec(weak) int Hu_IsStub() { + return 0; +} diff --git a/src/dolphin/os/OS.c b/src/dolphin/os/OS.c new file mode 100644 index 0000000..67fe545 --- /dev/null +++ b/src/dolphin/os/OS.c @@ -0,0 +1,631 @@ +#include +#include +#include +#include +#include + +#include "__os.h" + +#define NOP 0x60000000 + +// external functions +extern void EnableMetroTRKInterrupts(void); +extern void __OSInitMemoryProtection(void); + +#define DB_EXCEPTIONRET_OFFSET 0xC +#define DB_EXCEPTIONDEST_OFFSET 0x8 +#define OS_CURRENTCONTEXT_PADDR 0x00C0 +#define OS_EXCEPTIONTABLE_ADDR 0x3000 +#define OS_DBJUMPPOINT_ADDR 0x60 + +#if SDK_REVISION < 1 +#define BUILD_DATE "Apr 5 2004" +#define DBUILD_TIME "03:55:13" +#define RBUILD_TIME "04:13:58" +#elif SDK_REVISION < 2 +#define BUILD_DATE "May 21 2004" +#define DBUILD_TIME "09:15:32" +#define RBUILD_TIME "09:28:09" +#else +#define BUILD_DATE "Nov 10 2004" +#define DBUILD_TIME "06:08:19" +#define RBUILD_TIME "06:26:41" +#endif + +#ifdef DEBUG +const char* __OSVersion = "<< Dolphin SDK - OS\tdebug build: "BUILD_DATE" "DBUILD_TIME" (0x2301) >>"; +#else +const char* __OSVersion = "<< Dolphin SDK - OS\trelease build: "BUILD_DATE" "RBUILD_TIME" (0x2301) >>"; +#endif + +static DVDDriveInfo DriveInfo; +static DVDCommandBlock DriveBlock; +OSExecParams __OSRebootParams; + +extern u32 __DVDLongFileNameFlag; +extern u32 __PADSpec; + +// defined in link script +extern u8 __ArenaLo[]; +extern char _stack_addr[]; +extern u8 __ArenaHi[]; + +static OSBootInfo* BootInfo; +static u32* BI2DebugFlag; +static u32 BI2DebugFlagHolder; + +OSTime __OSStartTime; +BOOL __OSInIPL; +void (**OSExceptionTable)(u8, OSContext*); +BOOL AreWeInitialized; +f32 ZeroPS[2]; +f64 ZeroF; +BOOL __OSIsGcam; + +// prototypes +static void __OSInitFPRs(void); +static void OSExceptionInit(void); + +// dummy entry points to the OS Exception vector +void __OSEVStart(void); +void __OSEVEnd(void); +void __OSEVSetNumber(void); +void __OSExceptionVector(void); +void __DBVECTOR(void); +void __OSDBINTSTART(void); +void __OSDBINTEND(void); +void __OSDBJUMPSTART(void); +void __OSDBJUMPEND(void); + +u32 __OSIsDebuggerPresent(void) { + return *(u32*)OSPhysicalToCached(0x40); +} + +/* clang-format off */ +#ifdef __GEKKO__ +asm void __OSFPRInit(void) { + // clang-format off + nofralloc + + mfmsr r3 + ori r3, r3, 0x2000 + mtmsr r3 + + mfspr r3, 0x398 + rlwinm. r3, r3, 3, 0x1f, 0x1f + beq skip_ps_init + + lis r3, ZeroPS@ha + addi r3, r3, ZeroPS@l + psq_l f0, 0(r3), 0, 0 + ps_mr f1, f0 + ps_mr f2, f0 + ps_mr f3, f0 + ps_mr f4, f0 + ps_mr f5, f0 + ps_mr f6, f0 + ps_mr f7, f0 + ps_mr f8, f0 + ps_mr f9, f0 + ps_mr f10, f0 + ps_mr f11, f0 + ps_mr f12, f0 + ps_mr f13, f0 + ps_mr f14, f0 + ps_mr f15, f0 + ps_mr f16, f0 + ps_mr f17, f0 + ps_mr f18, f0 + ps_mr f19, f0 + ps_mr f20, f0 + ps_mr f21, f0 + ps_mr f22, f0 + ps_mr f23, f0 + ps_mr f24, f0 + ps_mr f25, f0 + ps_mr f26, f0 + ps_mr f27, f0 + ps_mr f28, f0 + ps_mr f29, f0 + ps_mr f30, f0 + ps_mr f31, f0 + +skip_ps_init: + lfd f0, ZeroF(r13) + fmr f1, f0 + fmr f2, f0 + fmr f3, f0 + fmr f4, f0 + fmr f5, f0 + fmr f6, f0 + fmr f7, f0 + fmr f8, f0 + fmr f9, f0 + fmr f10, f0 + fmr f11, f0 + fmr f12, f0 + fmr f13, f0 + fmr f14, f0 + fmr f15, f0 + fmr f16, f0 + fmr f17, f0 + fmr f18, f0 + fmr f19, f0 + fmr f20, f0 + fmr f21, f0 + fmr f22, f0 + fmr f23, f0 + fmr f24, f0 + fmr f25, f0 + fmr f26, f0 + fmr f27, f0 + fmr f28, f0 + fmr f29, f0 + fmr f30, f0 + fmr f31, f0 + + mtfsf 0xff, f0 + blr + // clang-format on +} +#endif + +static void DisableWriteGatherPipe(void) { + u32 hid2; + + hid2 = PPCMfhid2(); + hid2 &= ~0x40000000; + PPCMthid2(hid2); +} + +u32 OSGetConsoleType(void) { + if (!BootInfo || BootInfo->consoleType == 0) { + return OS_CONSOLE_ARTHUR; + } + return BootInfo->consoleType; +} + +// needed for assert +#undef NULL +#define NULL 0 + +static void ClearArena(void) { + if (!((OSGetResetCode() & 0x80000000) ? TRUE : FALSE)) { + memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + + if (*(u32*)&__OSRebootParams.regionStart == 0) { + memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + + ASSERTLINE(683, __OSRebootParams.regionEnd != NULL); + + if ((u32)OSGetArenaLo() < *(u32*)&__OSRebootParams.regionStart) { + if ((u32)OSGetArenaHi() <= *(u32*)&__OSRebootParams.regionStart) { + memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + + memset(OSGetArenaLo(), 0, *(u32*)&__OSRebootParams.regionStart - (u32)OSGetArenaLo()); + + if ((u32)OSGetArenaHi() > (u32)__OSRebootParams.regionEnd) { + memset(__OSRebootParams.regionEnd, 0, (u32)OSGetArenaHi() - (u32)__OSRebootParams.regionEnd); + } + } +} + +static void InquiryCallback(s32, DVDCommandBlock* block) { + switch (block->state) { + case 0: + __OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode); + break; + default: + __OSDeviceCode = 1; + break; + } +} + +void OSInit(void) { + u32 consoleType; + void* bi2StartAddr; + + if (AreWeInitialized == FALSE) { + AreWeInitialized = TRUE; + + __OSStartTime = __OSGetSystemTime(); + OSDisableInterrupts(); + + __OSGetExecParams(&__OSRebootParams); + PPCMtmmcr0(0); + PPCMtmmcr1(0); + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); + PPCDisableSpeculation(); + PPCSetFpNonIEEEMode(); + + BootInfo = (OSBootInfo*)OSPhysicalToCached(0); + BI2DebugFlag = 0; + __DVDLongFileNameFlag = 0; + + bi2StartAddr = (void*)(*(u32*)OSPhysicalToCached(0xF4)); + if (bi2StartAddr) { + BI2DebugFlag = (void*)((char*)bi2StartAddr + 0xC); + __PADSpec = ((u32*)bi2StartAddr)[9]; + *(u8*)OSPhysicalToCached(0x30E8) = *BI2DebugFlag; + *(u8*)OSPhysicalToCached(0x30E9) = __PADSpec; + } else if (BootInfo->arenaHi) { + BI2DebugFlagHolder = *(u8*)OSPhysicalToCached(0x30E8); + BI2DebugFlag = &BI2DebugFlagHolder; + __PADSpec = *(u8*)OSPhysicalToCached(0x30E9); + } + + __DVDLongFileNameFlag = 1; + + OSSetArenaLo((!BootInfo->arenaLo) ? &__ArenaLo : BootInfo->arenaLo); + if ((!BootInfo->arenaLo) && (BI2DebugFlag) && (*(u32*)BI2DebugFlag < 2)) { + OSSetArenaLo((void*)(((u32)(char*)&_stack_addr + 0x1F) & 0xFFFFFFE0)); + } + OSSetArenaHi((!BootInfo->arenaHi) ? &__ArenaHi : BootInfo->arenaHi); + + OSExceptionInit(); + __OSInitSystemCall(); + OSInitAlarm(); + __OSModuleInit(); + __OSInterruptInit(); + __OSSetInterruptHandler(0x16, &__OSResetSWInterruptHandler); + __OSContextInit(); + __OSCacheInit(); + EXIInit(); + SIInit(); + __OSInitSram(); + __OSThreadInit(); + __OSInitAudioSystem(); + + DisableWriteGatherPipe(); + + if (!__OSInIPL) { + __OSInitMemoryProtection(); + } + + OSReport("\nDolphin OS\n"); +#if DEBUG + OSReport("Kernel built : %s %s\n", BUILD_DATE, DBUILD_TIME); +#else + OSReport("Kernel built : %s %s\n", BUILD_DATE, RBUILD_TIME); +#endif + OSReport("Console Type : "); + + consoleType = OSGetConsoleType(); + switch (consoleType & 0xF0000000) { + case OS_CONSOLE_RETAIL: + OSReport("Retail %d\n", consoleType); + break; + case OS_CONSOLE_DEVELOPMENT: + case OS_CONSOLE_TDEV: + switch (consoleType & 0x0FFFFFFF) { + 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: + OSReport("Development HW%d (%08x)\n", (consoleType & 0xFFFFFFF) - 3, consoleType); + break; + } + break; + default: + OSReport("%08x\n", consoleType); + break; + } + + OSReport("Memory %d MB\n", (u32)BootInfo->memorySize >> 0x14U); + OSReport("Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi()); + OSRegisterVersion(__OSVersion); + + // if location of debug flag exists, and flag is >= 2, enable MetroTRKInterrupts + if (BI2DebugFlag && ((*BI2DebugFlag) >= 2)) { + EnableMetroTRKInterrupts(); + } + + ClearArena(); + OSEnableInterrupts(); + + if (!__OSInIPL) { + DVDInit(); + + if (__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, +}; + +#if DEBUG +char * __OSExceptionNames[17] = { + "System reset", + "MachineCheck", + "DSI", + "ISI", + "External Int.", + "Alignment", + "Program", + "FP Unavailable", + "Decrementer", + "System call", + "Trace", + "Perf mon", + "IABR", + "SMI", + "Thermal Int.", + "Protection error", + "FP Exception", +}; +#endif + +static void OSExceptionInit(void) { + __OSException exception; + void* destAddr; + + // These two vars help us change the exception number embedded + // in the exception handler code. + u32* opCodeAddr; + u32 oldOpCode; + + // Address range of the actual code to be copied. + u8* handlerStart; + u32 handlerSize; + + ASSERTMSGLINE(1063, ((u32)&__OSEVEnd - (u32)&__OSEVStart) <= 0x100, "OSExceptionInit(): too big exception vector code."); + + // Install the first level exception vector. + opCodeAddr = (u32*)__OSEVSetNumber; + oldOpCode = *opCodeAddr; + handlerStart = (u8*)__OSEVStart; + handlerSize = (u32)((u8*)__OSEVEnd - (u8*)__OSEVStart); + + // Install the DB integrator, only if we are the first OSInit to be run + destAddr = (void*)OSPhysicalToCached(OS_DBJUMPPOINT_ADDR); + if (*(u32*)destAddr == 0) // Lomem should be zero cleared only once by BS2 + { + 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 = (void*)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"); +} + +#ifdef __GEKKO__ +static asm void __OSDBIntegrator(void) { + 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 +} +#endif + +#ifdef __GEKKO__ +static asm void __OSDBJump(void) { + nofralloc +entry __OSDBJUMPSTART + bla OS_DBJUMPPOINT_ADDR +entry __OSDBJUMPEND +} +#endif + +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) { + __OSExceptionHandler oldHandler; + + ASSERTMSGLINE(1205, exception < __OS_EXCEPTION_MAX, "__OSSetExceptionHandler(): unknown exception."); + + oldHandler = OSExceptionTable[exception]; + OSExceptionTable[exception] = handler; + return oldHandler; +} + +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) { + ASSERTMSGLINE(1228, exception < __OS_EXCEPTION_MAX, "__OSGetExceptionHandler(): unknown exception."); + return OSExceptionTable[exception]; +} + +#ifdef __GEKKO__ +static asm void OSExceptionVector(void) { + 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 +} +#endif + +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); + +#ifdef __GEKKO__ +asm void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) { + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + mfdsisr r5 + mfdar r6 + + stwu r1, -8(r1) + b __OSUnhandledException +} +#endif + +#ifdef __GEKKO__ +void __OSPSInit(void) { + PPCMthid2(PPCMfhid2() | 0x80000000 | 0x20000000); + ICFlashInvalidate(); + __sync(); + + asm + { + li r3, 0 + mtspr GQR0, r3 + mtspr GQR1, r3 + mtspr GQR2, r3 + mtspr GQR3, r3 + mtspr GQR4, r3 + mtspr GQR5, r3 + mtspr GQR6, r3 + mtspr GQR7, r3 + } +} +#endif + +u32 __OSGetDIConfig(void) { + return (__DIRegs[9] & 0xFF); +} + +void OSRegisterVersion(const char* id) { + OSReport("%s\n", id); +} diff --git a/src/dolphin/os/OSAddress.c b/src/dolphin/os/OSAddress.c new file mode 100644 index 0000000..4445c5a --- /dev/null +++ b/src/dolphin/os/OSAddress.c @@ -0,0 +1,39 @@ +#include + +// undefine the macros so they do not error the file. +#undef OSPhysicalToCached +#undef OSPhysicalToUncached +#undef OSCachedToPhysical +#undef OSUncachedToPhysical +#undef OSCachedToUncached +#undef OSUncachedToCached + +void* OSPhysicalToCached(u32 paddr) { + ASSERTMSGLINE(47, paddr < 0x10000000U, "OSPhysicalToCached(): illegal address."); + return (void*)(paddr + 0x80000000); +} + +void* OSPhysicalToUncached(u32 paddr) { + ASSERTMSGLINE(62, paddr < 0x10000000U, "OSPhysicalToUncached(): illegal address."); + return (void*)(paddr - 0x40000000); +} + +u32 OSCachedToPhysical(void* caddr) { + ASSERTMSGLINE(77, 0x80000000U <= (u32)caddr && (u32)caddr < 0x90000000U, "OSCachedToPhysical(): illegal address."); + return (u32)caddr + 0x80000000; +} + +u32 OSUncachedToPhysical(void* ucaddr) { + ASSERTMSGLINE(92, 0xC0000000U <= (u32)ucaddr && (u32)ucaddr < 0xD0000000U, "OSUncachedToPhysical(): illegal address."); + return (u32)ucaddr + 0x40000000; +} + +void* OSCachedToUncached(void* caddr) { + ASSERTMSGLINE(107, 0x80000000U <= (u32)caddr && (u32)caddr < 0x90000000U, "OSCachedToUncached(): illegal address."); + return (void*)((u32)caddr + 0x40000000); +} + +void* OSUncachedToCached(void* ucaddr) { + ASSERTMSGLINE(122, 0xC0000000U <= (u32)ucaddr && (u32)ucaddr < 0xD0000000U, "OSUncachedToCached(): illegal address."); + return (void*)((u32)ucaddr - 0x40000000); +} diff --git a/src/dolphin/os/OSAlarm.c b/src/dolphin/os/OSAlarm.c new file mode 100644 index 0000000..9a0d0d6 --- /dev/null +++ b/src/dolphin/os/OSAlarm.c @@ -0,0 +1,297 @@ +#include +#include + +#include "__os.h" +#include "__dvd.h" + +typedef struct { + OSAlarm* head; + OSAlarm* tail; +} OSAlarmQueue; + +// prototypes +static void SetTimer(OSAlarm * alarm); +static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler); +static void DecrementerExceptionCallback(register __OSException exception, register OSContext* context); +static void DecrementerExceptionHandler(__OSException exception, OSContext* context); +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 0xFFFFFFFF, NULL, NULL}; +static OSAlarmQueue AlarmQueue; + +#define ASSERTREPORT(line, cond) \ + if (!(cond)) { OSReport("OSCheckAlarmQueue: Failed " #cond " in %d", line); return 0; } + +BOOL OSCheckAlarmQueue(void) { + OSAlarm* alarm; + + ASSERTREPORT(146, AlarmQueue.head == NULL && AlarmQueue.tail == NULL || AlarmQueue.head != NULL && AlarmQueue.tail != NULL); + ASSERTREPORT(147, AlarmQueue.head == NULL || AlarmQueue.head->prev == NULL); + ASSERTREPORT(148, AlarmQueue.tail == NULL || AlarmQueue.tail->next == NULL); + + for(alarm = AlarmQueue.head; alarm; alarm = alarm->next) { + ASSERTREPORT(151, alarm->next == NULL || alarm->next->prev == alarm); + ASSERTREPORT(152, alarm->next != NULL || AlarmQueue.tail == alarm); + } + return TRUE; +} + +static void SetTimer(OSAlarm* alarm) { + OSTime 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); + } + } + + ASSERTLINE(251, alarm->handler == 0); + + 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; + } + + ASSERTLINE(280, next == 0); + + 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; + ASSERTMSGLINE(313, tick > 0, "OSSetAlarm(): tick was less than zero."); + ASSERTMSGLINE(314, handler, "OSSetAlarm(): null handler was specified."); + enabled = OSDisableInterrupts(); + alarm->period = 0; + InsertAlarm(alarm, __OSGetSystemTime() + tick, handler); + ASSERTLINE(321, OSCheckAlarmQueue()); + OSRestoreInterrupts(enabled); +} + +void OSSetAbsAlarm(OSAlarm* alarm, OSTime time, OSAlarmHandler handler) { + BOOL enabled; + + ASSERTMSGLINE(343, handler, "OSSetAbsAlarm(): null handler was specified."); + enabled = OSDisableInterrupts(); + alarm->period = 0; + InsertAlarm(alarm, __OSTimeToSystemTime(time), handler); + ASSERTLINE(350, OSCheckAlarmQueue()); + OSRestoreInterrupts(enabled); +} + +void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler) { + BOOL enabled; + ASSERTMSGLINE(374, period > 0, "OSSetPeriodicAlarm(): period was less than zero."); + ASSERTMSGLINE(375, handler, "OSSetPeriodicAlarm(): null handler was specified."); + enabled = OSDisableInterrupts(); + alarm->period = period; + alarm->start = __OSTimeToSystemTime(start); + InsertAlarm(alarm, 0, handler); + ASSERTLINE(383, OSCheckAlarmQueue()); + 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; + ASSERTLINE(434, OSCheckAlarmQueue()); + 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; + } + + ASSERTLINE(492, OSCheckAlarmQueue()); + + handler = alarm->handler; + alarm->handler = 0; + if (0 < alarm->period) { + InsertAlarm(alarm, 0, handler); + ASSERTLINE(502, OSCheckAlarmQueue()); + } + + if (AlarmQueue.head) { + SetTimer(AlarmQueue.head); + } + + OSDisableScheduler(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + handler(alarm, context); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); +} + +#ifdef __GEKKO__ +static asm void DecrementerExceptionHandler(register __OSException exception, + register OSContext* context) { + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + stwu r1, -8(r1) + b DecrementerExceptionCallback +} +#endif + +void OSSetAlarmTag(OSAlarm* alarm, u32 tag) { + alarm->tag = tag; +} + +void OSCancelAlarms(u32 tag) { + BOOL enabled; + OSAlarm* alarm; + OSAlarm* next; + + ASSERTMSGLINE(569, tag != 0, "OSCancelAlarms(): invalid tag. (tag zero is used by the operating system.)"); + + if (tag != 0) { + enabled = OSDisableInterrupts(); + ASSERTLINE(575, OSCheckAlarmQueue()); + + alarm = AlarmQueue.head; + next = (alarm) ? alarm->next : NULL; + + while (alarm != 0) { + if (alarm->tag == tag) { + OSCancelAlarm(alarm); + } + + alarm = next; + next = (alarm) ? alarm->next : NULL; + } + + ASSERTLINE(585, OSCheckAlarmQueue()); + OSRestoreInterrupts(enabled); + } +} + +static BOOL OnReset(BOOL final) { + OSAlarm* alarm; + OSAlarm* next; + + if (final != FALSE) { + ASSERTLINE(606, OSCheckAlarmQueue()); + + alarm = AlarmQueue.head; + next = (alarm) ? alarm->next : NULL; + + while (alarm != 0) { + if (__DVDTestAlarm(alarm) == FALSE) { + OSCancelAlarm(alarm); + } + + alarm = next; + next = (alarm) ? alarm->next : NULL; + } + + ASSERTLINE(616, OSCheckAlarmQueue()); + } + + return TRUE; +} diff --git a/src/dolphin/os/OSAlloc.c b/src/dolphin/os/OSAlloc.c new file mode 100644 index 0000000..2ad58e3 --- /dev/null +++ b/src/dolphin/os/OSAlloc.c @@ -0,0 +1,609 @@ +#include +#include + +#define ALIGNMENT 32 + +#define InRange(cell, arenaStart, arenaEnd) \ + ((u32) arenaStart <= (u32) cell) && ((u32) cell < (u32) arenaEnd) + +#define HEADERSIZE 32u +#define MINOBJSIZE 64u + +#ifdef DEBUG +#define ENABLE_HEAPDESC +#endif + +typedef struct Cell Cell; +typedef struct HeapDesc HeapDesc; +struct Cell { + Cell* prev; + Cell* next; + s32 size; +#ifdef ENABLE_HEAPDESC + HeapDesc* hd; + s32 requested; +#endif +}; + +struct HeapDesc { + s32 size; + Cell* free; + Cell* allocated; +#ifdef ENABLE_HEAPDESC + u32 paddingBytes; + u32 headerBytes; + u32 payloadBytes; +#endif +}; + +volatile int __OSCurrHeap = -1; + +static HeapDesc* HeapArray; +static int NumHeaps; +static void* ArenaStart; +static void* ArenaEnd; + +// prototypes +static Cell* DLAddFront(Cell* list, Cell* cell); +static Cell* DLLookup(Cell* list, Cell* cell); +static Cell* DLExtract(Cell* list, Cell* cell); +static Cell* DLInsert(Cell* list, Cell* cell); +static int DLOverlap(Cell* list, void* start, void* end); +static s32 DLSize(Cell* list); + +static Cell* DLAddFront(Cell* list, Cell* cell) { + cell->next = list; + cell->prev = 0; + if (list) { + list->prev = cell; + } + return cell; +} + +static Cell* DLLookup(Cell* list, Cell* cell) { + for(; list; list = list->next) { + if (list == cell) { + return list; + } + } + return NULL; +} + +static Cell* DLExtract(Cell* list, Cell* cell) { + if (cell->next) { + cell->next->prev = cell->prev; + } + if (cell->prev == NULL) { + return cell->next; + } + cell->prev->next = cell->next; + return list; +} + +static Cell* DLInsert(Cell* list, Cell* cell) { + Cell* prev; + Cell* next; + + for(next = list, prev = NULL; next != 0; prev = next, next = next->next) { + if (cell <= next) { + break; + } + } + + cell->next = next; + cell->prev = prev; + if (next) { + next->prev = cell; + if ((u8*)cell + cell->size == (u8*)next) { + cell->size += next->size; + next = next->next; + cell->next = next; + if (next) { + next->prev = cell; + } + } + } + if (prev) { + prev->next = cell; + if ((u8*)prev + prev->size == (u8*)cell) { + prev->size += cell->size; + prev->next = next; + if (next) { + next->prev = prev; + } + } + return list; + } + return cell; +} + +static int DLOverlap(Cell* list, void* start, void* end) { + Cell* cell = list; + + while(cell) { + if (((start <= cell) + && (cell < end)) + || ((start < (void* ) ((u8*)cell + cell->size)) + && ((void* ) ((u8*)cell + cell->size) <= end))) { + return 1; + } + cell = cell->next; + } + return 0; +} + +static s32 DLSize(Cell* list) { + Cell* cell; + s32 size; + + size = 0; + cell = list; + + while(cell) { + size += cell->size; + cell = cell->next; + } + + return size; +} + +void* OSAllocFromHeap(int heap, u32 size) { + HeapDesc* hd; + Cell* cell; + Cell* newCell; + s32 leftoverSize; + s32 requested; + + requested = size; + ASSERTMSGLINE(337, HeapArray, "OSAllocFromHeap(): heap is not initialized."); + ASSERTMSGLINE(338, (s32)size > 0, "OSAllocFromHeap(): invalid size."); + ASSERTMSGLINE(339, heap >= 0 && heap < NumHeaps, "OSAllocFromHeap(): invalid heap handle."); + ASSERTMSGLINE(340, HeapArray[heap].size >= 0, "OSAllocFromHeap(): invalid heap handle."); + + hd = &HeapArray[heap]; + size += 0x20; + size = (size + 0x1F) & 0xFFFFFFE0; + + for(cell = hd->free; cell != NULL; cell = cell->next) { + if ((signed)size <= (signed)cell->size) { + break; + } + } + + if (cell == NULL) { +#if DEBUG + OSReport("OSAllocFromHeap: Warning- failed to allocate %d bytes\n", size); +#endif + return NULL; + } + ASSERTMSGLINE(364, !((s32)cell & 0x1F), "OSAllocFromHeap(): heap is broken."); + ASSERTMSGLINE(365, cell->hd == NULL, "OSAllocFromHeap(): heap is broken."); + + leftoverSize = cell->size - size; + if (leftoverSize < 0x40U) { + hd->free = DLExtract(hd->free, cell); + } else { + cell->size = size; + newCell = (void*)((u8*)cell + size); + newCell->size = leftoverSize; +#ifdef ENABLE_HEAPDESC + newCell->hd = 0; +#endif + newCell->prev = cell->prev; + newCell->next = cell->next; + if (newCell->next != NULL) { + newCell->next->prev = newCell; + } + if (newCell->prev != NULL) { + newCell->prev->next = newCell; + } else { + ASSERTMSGLINE(394, hd->free == cell, "OSAllocFromHeap(): heap is broken."); + hd->free = newCell; + } + } + + hd->allocated = DLAddFront(hd->allocated, cell); +#ifdef ENABLE_HEAPDESC + cell->hd = hd; + cell->requested = requested; + hd->headerBytes += 0x20; + hd->paddingBytes += (cell->size - (requested + 0x20)); + hd->payloadBytes += requested; +#endif + return (u8*)cell + 0x20; +} + +void* OSAllocFixed(void* rstart, void* rend) { + int i; + Cell* cell; + Cell* newCell; + HeapDesc* hd; + void* start; + void* end; + void* cellEnd; + + start = (void*)((*(u32*)rstart) & ~((32)-1)); + end = (void*)((*(u32*)rend + 0x1FU) & ~((32)-1)); + + ASSERTMSGLINE(436, HeapArray, "OSAllocFixed(): heap is not initialized."); + ASSERTMSGLINE(437, (u32)start < (u32)end, "OSAllocFixed(): invalid range."); + ASSERTMSGLINE(439, ((u32) ArenaStart <= (u32) start) && ((u32) end <= (u32) ArenaEnd), "OSAllocFixed(): invalid range."); + + for(i = 0; i < NumHeaps; i++) { + hd = &HeapArray[i]; + if(hd->size >= 0) { + if (DLOverlap(hd->allocated, start, end)) { +#if DEBUG + OSReport("OSAllocFixed: Warning - failed to allocate from %p to %p\n", start, end); +#endif + return NULL; + } + } + } + + for(i = 0; i < NumHeaps; i++) { + hd = &HeapArray[i]; + if (hd->size >= 0) { + for(cell = hd->free; cell; cell = cell->next) { + cellEnd = ((u8*)cell + cell->size); + if(cellEnd > start) { + if (end <= cell) { + break; + } + if ((char*)start-0x20 <= (char*)cell && cell < end && (start <= cellEnd) && (cellEnd < ((char*)end + 0x40))) { + if (cell < start) { + start = cell; + } + if (end < cellEnd) { + end = cellEnd; + } + hd->free = DLExtract(hd->free, cell); + hd->size -= cell->size; + } else if((char*)start-0x20 <= (char*)cell && cell < end) { + if (cell < start) { + start = cell; + } + ASSERTLINE(503, MINOBJSIZE <= (char*) cellEnd - (char*) end); + newCell = (Cell*)end; + + newCell->size = (s32) ((char*)cellEnd - (char*)end); +#ifdef ENABLE_HEAPDESC + newCell->hd = 0; +#endif + newCell->next = cell->next; + if (newCell->next) { + newCell->next->prev = newCell; + } + newCell->prev = cell->prev; + if (newCell->prev) { + newCell->prev->next = newCell; + } else { + hd->free = newCell; + } + hd->size -= ((char*)end - (char*)cell); + break; + } else { + if ((start <= cellEnd) && (cellEnd < ((char*)end + 0x40U))) { + if (end < cellEnd) { + end = cellEnd; + } + ASSERTLINE(528, MINOBJSIZE <= (char*) start - (char*) cell); + hd->size -= ((char*)cellEnd - (char*)start); + cell->size = ((char*)start - (char*)cell); + } else { + ASSERTLINE(535, MINOBJSIZE <= (char*) cellEnd - (char*) end); + newCell = (Cell*)end; + newCell->size = ((char*)cellEnd - (char*)end); +#ifdef ENABLE_HEAPDESC + newCell->hd = 0; +#endif + newCell->next = cell->next; + if (newCell->next) { + newCell->next->prev = newCell; + } + newCell->prev = cell; + cell->next = newCell; + cell->size = ((char*)start - (char*)cell); + hd->size -= ((char*)end - (char*)start); + break; + } + } + } + } + ASSERTLINE(550, 0 <= hd->size); + } + } + ASSERTLINE(553, OFFSET(start, ALIGNMENT) == 0); + ASSERTLINE(554, OFFSET(end, ALIGNMENT) == 0); + ASSERTLINE(555, start < end); + *(u32*)rstart = (u32)start; + *(u32*)rend = (u32)end; + return (void*)*(u32*)rstart; +} + +void OSFreeToHeap(int heap, void* ptr) { + HeapDesc* hd; + Cell* cell; + + ASSERTMSGLINE(577, HeapArray, "OSFreeToHeap(): heap is not initialized."); + ASSERTMSGLINE(579, ((u32)ArenaStart+0x20) <= (u32)ptr && (u32)ptr < (u32)ArenaEnd, "OSFreeToHeap(): invalid pointer."); + ASSERTMSGLINE(580, OFFSET(ptr, ALIGNMENT) == 0, "OSFreeToHeap(): invalid pointer."); + ASSERTMSGLINE(581, HeapArray[heap].size >= 0, "OSFreeToHeap(): invalid heap handle."); + cell = (void*)((u32)ptr-0x20); + hd = &HeapArray[heap]; + ASSERTMSGLINE(586, cell->hd == hd, "OSFreeToHeap(): invalid pointer."); + ASSERTMSGLINE(587, DLLookup(hd->allocated, cell), "OSFreeToHeap(): invalid pointer."); +#ifdef ENABLE_HEAPDESC + cell->hd = 0; + hd->headerBytes -= 0x20; + hd->paddingBytes -= (cell->size - (cell->requested + 0x20)); + hd->payloadBytes -= cell->requested; +#endif + hd->allocated = DLExtract(hd->allocated, cell); + hd->free = DLInsert(hd->free, cell); +} + +int OSSetCurrentHeap(int heap) { + int prev; + + ASSERTMSGLINE(619, HeapArray, "OSSetCurrentHeap(): heap is not initialized."); + ASSERTMSGLINE(620, (heap >= 0) && (heap < NumHeaps), "OSSetCurrentHeap(): invalid heap handle."); + ASSERTMSGLINE(621, HeapArray[heap].size >= 0, "OSSetCurrentHeap(): invalid heap handle."); + prev = __OSCurrHeap; + __OSCurrHeap = heap; + return prev; +} + +void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps) { + u32 arraySize; + int i; + HeapDesc* hd; + + ASSERTMSGLINE(647, maxHeaps > 0, "OSInitAlloc(): invalid number of heaps."); + ASSERTMSGLINE(649, (u32)arenaStart < (u32)arenaEnd, "OSInitAlloc(): invalid range."); + ASSERTMSGLINE(652, maxHeaps <= (((u32)arenaEnd - (u32)arenaStart) / 24U), "OSInitAlloc(): too small range."); + arraySize = maxHeaps * sizeof(HeapDesc); + HeapArray = arenaStart; + NumHeaps = maxHeaps; + + for(i = 0; i < NumHeaps; i++) { + hd = &HeapArray[i]; + hd->size = -1; + hd->free = hd->allocated = 0; +#ifdef ENABLE_HEAPDESC + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; +#endif + } + __OSCurrHeap = -1; + arenaStart = (void*) ((u32)((char*)HeapArray + arraySize)); + arenaStart = (void*) (((u32)arenaStart + 0x1F) & 0xFFFFFFE0); + ArenaStart = arenaStart; + ArenaEnd = (void*) ((u32)arenaEnd & 0xFFFFFFE0); + ASSERTMSGLINE(680, ((u32)ArenaEnd - (u32)ArenaStart) >= 0x40U, "OSInitAlloc(): too small range."); + return arenaStart; +} + +int OSCreateHeap(void* start, void* end) { + int heap; + HeapDesc* hd; + Cell* cell; + + ASSERTMSGLINE(705, HeapArray, "OSCreateHeap(): heap is not initialized."); + ASSERTMSGLINE(706, (u32)start < (u32)end, "OSCreateHeap(): invalid range."); + + start = (void*)(((u32)start + 0x1FU) & ~((32)-1)); + end = (void*)(((u32)end) & ~((32)-1)); + + ASSERTMSGLINE(709, (u32)start < (u32)end, "OSCreateHeap(): invalid range."); + ASSERTMSGLINE(711, (u32)ArenaStart <= (u32)start && (u32)end <= (u32)ArenaEnd, "OSCreateHeap(): invalid range."); + ASSERTMSGLINE(713, ((u32)end - (u32)start) >= 0x40U, "OSCreateHeap(): too small range."); + +#if DEBUG + for(heap = 0; heap < NumHeaps; heap++) { + if (HeapArray[heap].size >= 0) { + ASSERTMSGLINE(723, !DLOverlap(HeapArray[heap].free, start, end), "OSCreateHeap(): invalid range."); + ASSERTMSGLINE(725, !DLOverlap(HeapArray[heap].allocated, start, end), "OSCreateHeap(): invalid range."); + } + } +#endif + + for(heap = 0; heap < NumHeaps; heap++) { + hd = &HeapArray[heap]; + if (hd->size < 0) { + hd->size = (u32)end - (u32)start; + cell = start; + cell->prev = 0; + cell->next = 0; + cell->size = hd->size; +#ifdef ENABLE_HEAPDESC + cell->hd = 0; +#endif + hd->free = cell; + hd->allocated = 0; +#ifdef ENABLE_HEAPDESC + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; +#endif + return heap; + } + } +#if DEBUG + OSReport("OSCreateHeap: Warning - Failed to find free heap descriptor."); +#endif + return -1; +} + +void OSDestroyHeap(int heap) { + HeapDesc* hd; + s32 size; + + ASSERTMSGLINE(782, HeapArray, "OSDestroyHeap(): heap is not initialized."); + ASSERTMSGLINE(783, (heap >= 0) && (heap < NumHeaps), "OSDestroyHeap(): invalid heap handle."); + ASSERTMSGLINE(784, HeapArray[heap].size >= 0, "OSDestroyHeap(): invalid heap handle."); + + hd = &HeapArray[heap]; +#if DEBUG + size = DLSize(hd->free); + + if (hd->size != size) { + OSReport("OSDestroyHeap(%d): Warning - free list size %d, heap size %d\n", heap, size, hd->size); + } +#endif + + hd->size = -1; + hd->free = hd->allocated = 0; +#ifdef ENABLE_HEAPDESC + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; + if (__OSCurrHeap == heap) { + __OSCurrHeap = -1; + } +#endif +} + +void OSAddToHeap(int heap, void* start, void* end) { + HeapDesc* hd; + Cell* cell; + int i; + + ASSERTMSGLINE(830, HeapArray, "OSAddToHeap(): heap is not initialized."); + ASSERTMSGLINE(831, (heap >= 0) && (heap < NumHeaps), "OSAddToHeap(): invalid heap handle."); + ASSERTMSGLINE(832, HeapArray[heap].size >= 0, "OSAddToHeap(): invalid heap handle."); + + hd = &HeapArray[heap]; + + ASSERTMSGLINE(836, (u32)start < (u32)end, "OSAddToHeap(): invalid range."); + + start = (void*)(((u32)start + 0x1F) & ~((32)-1)); + end = (void*)(((u32)end) & ~((32)-1)); + + ASSERTMSGLINE(840, ((u32)end - (u32)start) >= 0x40U, "OSAddToHeap(): too small range."); + ASSERTMSGLINE(842, (u32)ArenaStart <= (u32)start && (u32)end <= (u32)ArenaEnd, "OSAddToHeap(): invalid range."); + +#if DEBUG + for(i = 0; i < NumHeaps; i++) { + if (HeapArray[i].size >= 0) { + ASSERTMSGLINE(852, !DLOverlap(HeapArray[i].free, start, end), "OSAddToHeap(): invalid range."); + ASSERTMSGLINE(854, !DLOverlap(HeapArray[i].allocated, start, end), "OSAddToHeap(): invalid range."); + } + } +#endif + cell = (Cell*)start; + cell->size = ((char*)end - (char*)start); +#ifdef ENABLE_HEAPDESC + cell->hd = 0; +#endif + hd->size += cell->size; + hd->free = DLInsert(hd->free, cell); +} + +// custom macro for OSCheckHeap +#define ASSERTREPORT(line, cond) \ + if (!(cond)) { OSReport("OSCheckHeap: Failed " #cond " in %d", line); return -1; } + +s32 OSCheckHeap(int heap) { + HeapDesc* hd; + Cell* cell; + s32 total = 0; + s32 free = 0; + + ASSERTREPORT(898, HeapArray); + ASSERTREPORT(899, 0 <= heap && heap < NumHeaps); + hd = &HeapArray[heap]; + ASSERTREPORT(902, 0 <= hd->size); + + ASSERTREPORT(0x388, hd->allocated == NULL || hd->allocated->prev == NULL); + + for(cell = hd->allocated; cell; cell = cell->next) { + ASSERTREPORT(907, InRange(cell, ArenaStart, ArenaEnd)); + ASSERTREPORT(908, OFFSET(cell, ALIGNMENT) == 0); + ASSERTREPORT(909, cell->next == NULL || cell->next->prev == cell); + ASSERTREPORT(910, MINOBJSIZE <= cell->size); + ASSERTREPORT(911, OFFSET(cell->size, ALIGNMENT) == 0); + total += cell->size; + ASSERTREPORT(914, 0 < total && total <= hd->size); +#ifdef ENABLE_HEAPDESC + ASSERTREPORT(917, cell->hd == hd); + ASSERTREPORT(918, HEADERSIZE + cell->requested <= cell->size); +#endif + } + + + ASSERTREPORT(922, hd->free == NULL || hd->free->prev == NULL); + + for(cell = hd->free; cell; cell = cell->next) { + ASSERTREPORT(925, InRange(cell, ArenaStart, ArenaEnd)); + ASSERTREPORT(926, OFFSET(cell, ALIGNMENT) == 0); + ASSERTREPORT(927, cell->next == NULL || cell->next->prev == cell); + ASSERTREPORT(928, MINOBJSIZE <= cell->size); + ASSERTREPORT(929, OFFSET(cell->size, ALIGNMENT) == 0); + ASSERTREPORT(930, cell->next == NULL || (char*) cell + cell->size < (char*) cell->next); + total += cell->size; + free = (cell->size + free); + free -= HEADERSIZE; + ASSERTREPORT(934, 0 < total && total <= hd->size); +#ifdef ENABLE_HEAPDESC + ASSERTREPORT(937, cell->hd == NULL); +#endif + } + ASSERTREPORT(941, total == hd->size); + return free; +} + +u32 OSReferentSize(void* ptr) { + Cell* cell; + + ASSERTMSGLINE(960, HeapArray, "OSReferentSize(): heap is not initialized."); + ASSERTMSGLINE(962, InRange(ptr, ArenaStart+HEADERSIZE, ArenaEnd), "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(963, !OFFSET(ptr, 32), "OSReferentSize(): invalid pointer."); + cell = (void*)((u32)ptr-HEADERSIZE); + ASSERTMSGLINE(967, cell->hd, "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(969, !(((u32)cell->hd - (u32)HeapArray) % 24), "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(971, ((u32)HeapArray <= (u32)cell->hd) && ((u32)cell->hd < (u32)((u32)HeapArray + (NumHeaps * 0x18))), "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(972, cell->hd->size >= 0, "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(974, DLLookup(cell->hd->allocated, cell), "OSReferentSize(): invalid pointer."); + return (s32)((u32)cell->size-HEADERSIZE); +} + +void OSDumpHeap(int heap) { + HeapDesc* hd; + Cell* cell; + + OSReport("\nOSDumpHeap(%d):\n", heap); + ASSERTMSGLINE(995, HeapArray, "OSDumpHeap(): heap is not initialized."); + ASSERTMSGLINE(996, (heap >= 0) && (heap < NumHeaps), "OSDumpHeap(): invalid heap handle."); + hd = &HeapArray[heap]; + if (hd->size < 0) { + OSReport("--------Inactive\n"); + return; + } + ASSERTMSGLINE(1005, OSCheckHeap(heap) >= 0, "OSDumpHeap(): heap is broken."); +#ifdef ENABLE_HEAPDESC + OSReport("padding %d/(%f%%) header %d/(%f%%) payload %d/(%f%%)\n", + hd->paddingBytes, (100.0 * hd->paddingBytes / hd->size), hd->headerBytes, (100.0 * hd->headerBytes / hd->size), hd->payloadBytes, + (100.0 * hd->payloadBytes / hd->size)); +#endif + OSReport("addr size end prev next\n"); + OSReport("--------Allocated\n"); + + ASSERTMSGLINE(1018, hd->allocated == NULL || hd->allocated->prev == NULL, "OSDumpHeap(): heap is broken."); + + for(cell = hd->allocated; cell; cell = cell->next) { + OSReport("%x %d %x %x %x\n", cell, cell->size, (char*)cell + cell->size, cell->prev, cell->next); + } + OSReport("--------Free\n"); + for(cell = hd->free; cell; cell = cell->next) { + OSReport("%x %d %x %x %x\n", cell, cell->size, (char*)cell + cell->size, cell->prev, cell->next); + } +} + +void OSVisitAllocated(void (*visitor)(void*, u32)) { + u32 heap; + Cell* cell; + + for(heap = 0; heap < NumHeaps; heap++) { + if (HeapArray[heap].size >= 0) { + for(cell = HeapArray[heap].allocated; cell; cell = cell->next) { + visitor((char*)cell+HEADERSIZE, cell->size); + } + } + } +} diff --git a/src/dolphin/os/OSArena.c b/src/dolphin/os/OSArena.c new file mode 100644 index 0000000..ab7b5fe --- /dev/null +++ b/src/dolphin/os/OSArena.c @@ -0,0 +1,52 @@ +#include +#include + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) + +static void* __OSArenaHi; +static void* __OSArenaLo = (void*)-1; + +void* OSGetArenaHi(void) { + ASSERTMSGLINE(55, (u32)__OSArenaLo != -1, "OSGetArenaHi(): OSInit() must be called in advance."); + ASSERTMSGLINE(57, (u32)__OSArenaLo <= (u32)__OSArenaHi, "OSGetArenaHi(): invalid arena (hi < lo)."); + return __OSArenaHi; +} + +void* OSGetArenaLo(void) { + ASSERTMSGLINE(73, (u32)__OSArenaLo != -1, "OSGetArenaLo(): OSInit() must be called in advance."); + ASSERTMSGLINE(75, (u32)__OSArenaLo <= (u32)__OSArenaHi, "OSGetArenaLo(): invalid arena (hi < lo)."); + return __OSArenaLo; +} + +void OSSetArenaHi(void* newHi) { + __OSArenaHi = newHi; +} + +void OSSetArenaLo(void* newLo) { + __OSArenaLo = newLo; +} + +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; +} diff --git a/src/dolphin/os/OSAudioSystem.c b/src/dolphin/os/OSAudioSystem.c new file mode 100644 index 0000000..3ffd440 --- /dev/null +++ b/src/dolphin/os/OSAudioSystem.c @@ -0,0 +1,117 @@ +#include +#include + +#include "__os.h" + +static u8 DSPInitCode[128] = { + 0x02, 0x9F, 0x00, 0x10, 0x02, 0x9F, 0x00, 0x33, 0x02, 0x9F, 0x00, 0x34, 0x02, 0x9F, 0x00, 0x35, + 0x02, 0x9F, 0x00, 0x36, 0x02, 0x9F, 0x00, 0x37, 0x02, 0x9F, 0x00, 0x38, 0x02, 0x9F, 0x00, 0x39, + 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 +}; + +#define __DSPWorkBuffer (void*)0x81000000 + +void __OSInitAudioSystem(void) { + u8 errFlag; + u16 reg16; + u32 start_tick; + + memcpy((void*)((u32)OSGetArenaHi() - 0x80), __DSPWorkBuffer, sizeof(DSPInitCode)); + memcpy(__DSPWorkBuffer, (void*)DSPInitCode, sizeof(DSPInitCode)); + DCFlushRange(__DSPWorkBuffer, sizeof(DSPInitCode)); + + __DSPRegs[9] = 0x43; + ASSERTMSGLINE(113, !(__DSPRegs[5] & 0x200), "__OSInitAudioSystem(): ARAM DMA already in progress"); + ASSERTMSGLINE(117, !(__DSPRegs[5] & 0x400), "__OSInitAudioSystem(): DSP DMA already in progress"); + ASSERTMSGLINE(121, (__DSPRegs[5] & 0x004), "__OSInitAudioSystem(): DSP already working"); + + __DSPRegs[5] = 0x8AC; + __DSPRegs[5] |= 1; + + while (__DSPRegs[5] & 1); + __DSPRegs[0] = 0; + + while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000); + + *(u32*)&__DSPRegs[16] = 0x1000000; + *(u32*)&__DSPRegs[18] = 0; + *(u32*)&__DSPRegs[20] = 0x20; + + reg16 = __DSPRegs[5]; + while (!(reg16 & 0x20)) + reg16 = __DSPRegs[5]; + + __DSPRegs[5] = reg16; + + start_tick = OSGetTick(); + while ((s32)(OSGetTick() - start_tick) < 0x892); + + *(u32*)&__DSPRegs[16] = 0x1000000; + *(u32*)&__DSPRegs[18] = 0; + *(u32*)&__DSPRegs[20] = 0x20; + + reg16 = __DSPRegs[5]; + while (!(reg16 & 0x20)) { + reg16 = __DSPRegs[5]; + } + __DSPRegs[5] = reg16; + + __DSPRegs[5] &= ~0x800; + while ((__DSPRegs[5]) & 0x400); + + __DSPRegs[5] &= ~4; + errFlag = 0; + + reg16 = __DSPRegs[2]; + + while (!(reg16 & 0x8000)) { + reg16 = __DSPRegs[2]; + } + + if(((u32)((reg16 << 16) | __DSPRegs[3]) + 0x7FAC0000U) != 0x4348) { + ASSERTMSGLINE(193, 0, "__OSInitAudioSystem(): DSP returns invalid message"); + } + + reg16 != 0x81800; // fake but fixes reg alloc on retail + __DSPRegs[5] |= 4; + __DSPRegs[5] = 0x8AC; + __DSPRegs[5] |= 1; + while (__DSPRegs[5] & 1); + + memcpy(__DSPWorkBuffer, (void*)((u32)OSGetArenaHi() - 0x80), sizeof(DSPInitCode)); +} + +void __OSStopAudioSystem(void) { + u16 reg16; + u32 start_tick; + + #define waitUntil(load, mask) \ + reg16 = (load); \ + while (reg16 & (mask)) { \ + reg16 = (load); \ + } + + __DSPRegs[5] = 0x804; + reg16 = __DSPRegs[27]; + __DSPRegs[27] = reg16 & ~0x8000; + waitUntil(__DSPRegs[5], 0x400); + waitUntil(__DSPRegs[5], 0x200); + __DSPRegs[5] = 0x8ac; + __DSPRegs[0] = 0; + + while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000); + + start_tick = OSGetTick(); + while ((s32)(OSGetTick() - start_tick) < 0x2c); + + reg16 = __DSPRegs[5]; + __DSPRegs[5] = reg16 | 1; + waitUntil(__DSPRegs[5], 0x001); + + #undef waitUntil +} diff --git a/src/dolphin/os/OSCache.c b/src/dolphin/os/OSCache.c new file mode 100644 index 0000000..b09cfbb --- /dev/null +++ b/src/dolphin/os/OSCache.c @@ -0,0 +1,643 @@ +#include +#include +#include + +#include "__os.h" + +#define HID2 920 + +// prototypes +void DMAErrorHandler(OSError error, OSContext* context, ...); + +#ifdef __GEKKO__ +asm void DCFlashInvalidate(void) { + nofralloc + mfspr r3, HID0 + ori r3, r3, 0x400 + mtspr HID0, r3 + blr +} + +asm void DCEnable(void) { + nofralloc + sync + mfspr r3, HID0 + ori r3, r3, 0x4000 + mtspr HID0, r3 + blr +} + +asm void DCDisable(void) { + nofralloc + sync + mfspr r3, HID0 + rlwinm r3, r3, 0, 18, 16 + mtspr HID0, r3 + blr +} + +asm void DCFreeze(void) { + nofralloc + sync + mfspr r3, HID0 + ori r3, r3, 0x1000 + mtspr HID0, r3 + blr +} + +asm void DCUnfreeze(void) { + nofralloc + mfspr r3, HID0 + rlwinm r3, r3, 0, 20, 18 + mtspr HID0, r3 + blr +} + +asm void DCTouchLoad(register void* addr) { + nofralloc + dcbt r0, addr + blr +} + +asm void DCBlockZero(register void* addr) { + nofralloc + dcbz r0, addr + blr +} + +asm void DCBlockStore(register void* addr) { + nofralloc + dcbst r0, addr + blr +} + +asm void DCBlockFlush(register void* addr) { + nofralloc + dcbf r0, addr + blr +} + +asm void DCBlockInvalidate(register void* addr) { + nofralloc + dcbi r0, addr + blr +} + +asm void DCInvalidateRange(register void* addr, register u32 nBytes) { + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@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 DCTouchRange(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 + dcbt r0, addr + addi addr, addr, 32 + bdnz @1 + + blr +} + +asm void ICInvalidateRange(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 + icbi r0, addr + addi addr, addr, 32 + bdnz @1 + sync + isync + + blr +} + +asm void ICFlashInvalidate(void) { + nofralloc + mfspr r3, HID0 + ori r3, r3, 0x800 + mtspr HID0, r3 + blr +} + +asm void ICEnable(void) { + nofralloc + isync + mfspr r3, HID0 + ori r3, r3, 0x8000 + mtspr HID0, r3 + blr +} + +asm void ICDisable(void) { + nofralloc + isync + mfspr r3, HID0 + rlwinm r3, r3, 0, 17, 15 + mtspr HID0, r3 + blr +} + +asm void ICFreeze(void) { + nofralloc + isync + mfspr r3, HID0 + ori r3, r3, 0x2000 + mtspr HID0, r3 + blr +} + +asm void ICUnfreeze(void) { + nofralloc + mfspr r3, HID0 + rlwinm r3, r3, 0, 19, 17 + mtspr HID0, r3 + blr +} + +asm void ICBlockInvalidate(register void* addr) { + nofralloc + icbi r0, addr + blr +} + +asm void ICSync(void) { + nofralloc + isync + blr +} + +#define LC_LINES 512 +#define CACHE_LINES 1024 + +static asm void __LCEnable(void) { + nofralloc + mfmsr r5 + ori r5, r5, 0x1000 + mtmsr r5 + + lis r3, OS_CACHED_REGION_PREFIX + li r4, CACHE_LINES + mtctr r4 +_touchloop: + dcbt 0,r3 + dcbst 0,r3 + addi r3,r3,32 + bdnz _touchloop + mfspr r4, HID2 + oris r4, r4, 0x100F + mtspr HID2, r4 + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + lis r3, LC_BASE_PREFIX + ori r3, r3, 0x0002 + mtspr DBAT3L, r3 + ori r3, r3, 0x01fe + mtspr DBAT3U, r3 + isync + lis r3, LC_BASE_PREFIX + li r6, LC_LINES + mtctr r6 + li r6, 0 + +_lockloop: + dcbz_l r6, r3 + addi r3, r3, 32 + bdnz+ _lockloop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + blr +} + +void LCEnable(void) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + __LCEnable(); + OSRestoreInterrupts(enabled); +} + +asm void LCDisable(void) { + 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 LCAllocOneTag(register BOOL invalidate, register void* tag) { + nofralloc + cmpwi invalidate, 0 + beq @1 + dcbi r0, tag +@1 + dcbz_l r0, tag + blr +} + +asm void LCAllocTags(register BOOL invalidate, register void* startTag, register u32 numBlocks) { + nofralloc + mflr r6 + cmplwi numBlocks, 0 + ble @3 + mtctr numBlocks + cmpwi invalidate, 0 + beq @2 +@1 + dcbi r0, startTag + dcbz_l r0, startTag + addi startTag, startTag, 32 + bdnz @1 + b @3 +@2 + dcbz_l r0, startTag + addi startTag, startTag, 32 + bdnz @2 +@3 + mtlr r6 + blr +} + +asm void LCLoadBlocks(register void* destTag, register void* srcAddr, register u32 numBlocks) { + nofralloc + rlwinm r6, numBlocks, 30, 27, 31 + rlwinm srcAddr, srcAddr, 0, 4, 31 + or r6, r6, srcAddr + mtspr DMA_U, r6 + rlwinm r6, numBlocks, 2, 28, 29 + or r6, r6, destTag + ori r6, r6, 0x12 + mtspr DMA_L, r6 + blr +} + +asm void LCStoreBlocks(register void* destAddr, register void* srcTag, register u32 numBlocks) { + nofralloc + rlwinm r6, numBlocks, 30, 27, 31 + rlwinm destAddr, destAddr, 0, 4, 31 + or r6, r6, destAddr + mtspr DMA_U, r6 + rlwinm r6, numBlocks, 2, 28, 29 + or r6, r6, srcTag + ori r6, r6, 0x2 + mtspr DMA_L, r6 + blr +} +#endif + +void LCAlloc(void* addr, u32 nBytes) { + u32 numBlocks = nBytes >> 5; + u32 hid2 = PPCMfhid2(); + + ASSERTMSGLINE(1319, !((u32)addr & 31), "LCAlloc(): addr must be 32 byte aligned"); + ASSERTMSGLINE(1321, !((u32)nBytes & 31), "LCAlloc(): nBytes must be 32 byte aligned"); + + if ((hid2 & 0x10000000) == 0) { + LCEnable(); + } + LCAllocTags(TRUE, addr, numBlocks); +} + +void LCAllocNoInvalidate(void* addr, u32 nBytes) { + u32 numBlocks = nBytes >> 5; + u32 hid2 = PPCMfhid2(); + + ASSERTMSGLINE(1366, !((u32)addr & 31), "LCAllocNoFlush(): addr must be 32 byte aligned"); + ASSERTMSGLINE(1368, !((u32)nBytes & 31), "LCAllocNoFlush(): nBytes must be 32 byte aligned"); + + if ((hid2 & 0x10000000) == 0) { + LCEnable(); + } + LCAllocTags(FALSE, addr, numBlocks); +} + +u32 LCLoadData(void* destAddr, void* srcAddr, u32 nBytes) { + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + 128 - 1) / 128; + + ASSERTMSGLINE(1426, !((u32)srcAddr & 31), "LCLoadData(): srcAddr not 32 byte aligned"); + ASSERTMSGLINE(1428, !((u32)destAddr & 31), "LCLoadData(): destAddr not 32 byte aligned"); + + while (numBlocks > 0) { + if (numBlocks < 128) { + LCLoadBlocks(destAddr, srcAddr, numBlocks); + numBlocks = 0; + } else { + 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; + + ASSERTMSGLINE(1494, !((u32)srcAddr & 31), "LCStoreData(): srcAddr not 32 byte aligned"); + ASSERTMSGLINE(1496, !((u32)destAddr & 31), "LCStoreData(): destAddr not 32 byte aligned"); + + while (numBlocks > 0) { + if (numBlocks < 128) { + LCStoreBlocks(destAddr, srcAddr, numBlocks); + numBlocks = 0; + } else { + LCStoreBlocks(destAddr, srcAddr, 0); + numBlocks -= 128; + destAddr = (void*)((u32)destAddr + 4096); + srcAddr = (void*)((u32)srcAddr + 4096); + } + } + + return numTransactions; +} + +#ifdef __GEKKO__ +asm u32 LCQueueLength(void) { + nofralloc + mfspr r4, HID2 + rlwinm r3, r4, 8, 28, 31 + blr +} + +asm void LCQueueWait(register u32 len) { + nofralloc +@1 + mfspr r4, HID2 + rlwinm r4, r4, 8, 28, 31 + cmpw r4, r3 + bgt @1 + blr +} +#endif + +void LCFlushQueue() { + union { + u32 val; + struct { + u32 lcAddr : 27; + u32 dmaLd : 1; + u32 dmaLenL : 2; + u32 dmaTrigger : 1; + u32 dmaFlush : 1; + } f; + } dmaL; + + dmaL.val = 0; + dmaL.f.dmaFlush = 1; + PPCMtdmaU(0); + PPCMtdmaL(dmaL.val); + PPCSync(); +} + +static void L2Init(void) { + u32 oldMSR; + oldMSR = PPCMfmsr(); + __sync(); + PPCMtmsr(MSR_IR | MSR_DR); + __sync(); + L2Disable(); + L2GlobalInvalidate(); + PPCMtmsr(oldMSR); +} + +void L2Enable(void) { + PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); +} + +void L2Disable(void) { + __sync(); + PPCMtl2cr(PPCMfl2cr() & ~0x80000000); + __sync(); +} + +void L2GlobalInvalidate(void) { + L2Disable(); + PPCMtl2cr(PPCMfl2cr() | 0x00200000); + while (PPCMfl2cr() & 0x00000001u); + + PPCMtl2cr(PPCMfl2cr() & ~0x00200000); + while (PPCMfl2cr() & 0x00000001u) { + DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); + } +} + +void L2SetDataOnly(BOOL dataOnly) { + if (dataOnly) { + PPCMtl2cr(PPCMfl2cr() | 0x400000); + return; + } + PPCMtl2cr(PPCMfl2cr() & 0xFFBFFFFF); +} + +void L2SetWriteThrough(BOOL writeThrough) { + if (writeThrough) { + PPCMtl2cr(PPCMfl2cr() | 0x80000); + return; + } + PPCMtl2cr(PPCMfl2cr() & 0xFFF7FFFF); +} + +void DMAErrorHandler(OSError error, OSContext* context, ...) { + u32 hid2 = PPCMfhid2(); + + OSReport("Machine check received\n"); + OSReport("HID2 = 0x%x SRR1 = 0x%x\n", hid2, context->srr1); + if (!(hid2 & (HID2_DCHERR | HID2_DNCERR | HID2_DCMERR | HID2_DQOERR)) || !(context->srr1 & SRR1_DMA_BIT)) { + 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/src/dolphin/os/OSContext.c b/src/dolphin/os/OSContext.c new file mode 100644 index 0000000..a0c49b8 --- /dev/null +++ b/src/dolphin/os/OSContext.c @@ -0,0 +1,626 @@ +#include +#include + +#include "__os.h" + +// external functions +extern void __RAS_OSDisableInterrupts_begin(); +extern void __RAS_OSDisableInterrupts_end(); +extern void DBPrintf(char*, ...); + +#define HID2 920 + +volatile OSContext* __OSCurrentContext AT_ADDRESS(OS_BASE_CACHED | 0x00D4); +volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED | 0x00D8); + +#ifdef __GEKKO__ +static asm void __OSLoadFPUContext(register u32 dummy, register OSContext* fpucontext) { + nofralloc + lhz r5, fpucontext->state; + clrlwi. r5, r5, 31 + beq _return + + 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 +} + +static asm void __OSSaveFPUContext(register u32 dummy1, register u32 dummy2, register OSContext* fpucontext) { + 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 +} + +asm void OSLoadFPUContext(register OSContext* fpucontext) { + nofralloc + addi r4, fpucontext, 0 + b __OSLoadFPUContext +} + +asm void OSSaveFPUContext(register OSContext* fpucontext) { + nofralloc + addi r5, fpucontext, 0 + b __OSSaveFPUContext +} + +asm void OSSetCurrentContext(register OSContext* context){ + 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 +} +#endif + +OSContext* OSGetCurrentContext(void) { + return (OSContext*)__OSCurrentContext; +} + +#ifdef __GEKKO__ +asm u32 OSSaveContext(register OSContext* context) { + 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 +} + +asm void OSLoadContext(register OSContext* context) { + 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 +} + +asm u32 OSGetStackPointer() { + nofralloc + mr r3, r1 + blr +} + +asm u32 OSSwitchStack(register u32 newsp) { + nofralloc + mr r5, r1 + mr r1, newsp + mr r3, r5 + blr +} + +asm int OSSwitchFiber(register u32 pc, register u32 newsp) { + nofralloc + mflr r0 + mr r5, r1 + stwu r5, -8(newsp) + mr r1, newsp + stw r0, 4(r5) + mtlr pc + blrl + lwz r5, 0(r1) + lwz r0, 4(r5) + mtlr r0 + mr r1, r5 + blr +} +#endif + +void OSClearContext(register OSContext* context) { + context->mode = 0; + context->state = 0; + if (context == __OSFPUContext) + __OSFPUContext = NULL; +} + +#ifdef __GEKKO__ +asm void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) { + nofralloc + + stw pc, OS_CONTEXT_SRR0(context) + stw newsp, OS_CONTEXT_R1(context) + li r11, 0 + ori r11, r11, 0x00008000 | 0x00000020 | 0x00000010 | 0x00000002 | 0x00001000 + stw r11, OS_CONTEXT_SRR1(context) + li r0, 0x0 + stw r0, OS_CONTEXT_CR(context) + stw r0, OS_CONTEXT_XER(context) + + + stw r2, OS_CONTEXT_R2(context) + stw r13, OS_CONTEXT_R13(context) + + stw r0, OS_CONTEXT_R3(context) + stw r0, OS_CONTEXT_R4(context) + stw r0, OS_CONTEXT_R5(context) + stw r0, OS_CONTEXT_R6(context) + stw r0, OS_CONTEXT_R7(context) + stw r0, OS_CONTEXT_R8(context) + stw r0, OS_CONTEXT_R9(context) + stw r0, OS_CONTEXT_R10(context) + stw r0, OS_CONTEXT_R11(context) + stw r0, OS_CONTEXT_R12(context) + + stw r0, OS_CONTEXT_R14(context) + stw r0, OS_CONTEXT_R15(context) + stw r0, OS_CONTEXT_R16(context) + stw r0, OS_CONTEXT_R17(context) + stw r0, OS_CONTEXT_R18(context) + stw r0, OS_CONTEXT_R19(context) + stw r0, OS_CONTEXT_R20(context) + stw r0, OS_CONTEXT_R21(context) + stw r0, OS_CONTEXT_R22(context) + stw r0, OS_CONTEXT_R23(context) + stw r0, OS_CONTEXT_R24(context) + stw r0, OS_CONTEXT_R25(context) + stw r0, OS_CONTEXT_R26(context) + stw r0, OS_CONTEXT_R27(context) + stw r0, OS_CONTEXT_R28(context) + stw r0, OS_CONTEXT_R29(context) + stw r0, OS_CONTEXT_R30(context) + stw r0, OS_CONTEXT_R31(context) + + stw r0, OS_CONTEXT_GQR0(context) + stw r0, OS_CONTEXT_GQR1(context) + stw r0, OS_CONTEXT_GQR2(context) + stw r0, OS_CONTEXT_GQR3(context) + stw r0, OS_CONTEXT_GQR4(context) + stw r0, OS_CONTEXT_GQR5(context) + stw r0, OS_CONTEXT_GQR6(context) + stw r0, OS_CONTEXT_GQR7(context) + + b OSClearContext +} +#endif + +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]); + } +} + +#ifdef __GEKKO__ +static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) { + 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 +} +#endif + +void __OSContextInit(void) { + __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); + __OSFPUContext = NULL; + DBPrintf("FPU-unavailable handler installed\n"); +} + +#ifdef __GEKKO__ +asm void OSFillFPUContext(register OSContext* context) { + nofralloc + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 + isync + + stfd fp0, context->fpr[0] + stfd fp1, context->fpr[1] + stfd fp2, context->fpr[2] + stfd fp3, context->fpr[3] + stfd fp4, context->fpr[4] + stfd fp5, context->fpr[5] + stfd fp6, context->fpr[6] + stfd fp7, context->fpr[7] + stfd fp8, context->fpr[8] + stfd fp9, context->fpr[9] + stfd fp10, context->fpr[10] + stfd fp11, context->fpr[11] + stfd fp12, context->fpr[12] + stfd fp13, context->fpr[13] + stfd fp14, context->fpr[14] + stfd fp15, context->fpr[15] + stfd fp16, context->fpr[16] + stfd fp17, context->fpr[17] + stfd fp18, context->fpr[18] + stfd fp19, context->fpr[19] + stfd fp20, context->fpr[20] + stfd fp21, context->fpr[21] + stfd fp22, context->fpr[22] + stfd fp23, context->fpr[23] + stfd fp24, context->fpr[24] + stfd fp25, context->fpr[25] + stfd fp26, context->fpr[26] + stfd fp27, context->fpr[27] + stfd fp28, context->fpr[28] + stfd fp29, context->fpr[29] + stfd fp30, context->fpr[30] + stfd fp31, context->fpr[31] + + mffs fp0 + stfd fp0, OS_CONTEXT_FPSCR(context) + + lfd fp0, context->fpr[0] + + mfspr r5, HID2 + rlwinm. r5, r5, 3, 31, 31 + bc 12, 2, _return + + psq_st fp0, OS_CONTEXT_PSF0(context), 0, 0 + psq_st fp1, OS_CONTEXT_PSF1(context), 0, 0 + psq_st fp2, OS_CONTEXT_PSF2(context), 0, 0 + psq_st fp3, OS_CONTEXT_PSF3(context), 0, 0 + psq_st fp4, OS_CONTEXT_PSF4(context), 0, 0 + psq_st fp5, OS_CONTEXT_PSF5(context), 0, 0 + psq_st fp6, OS_CONTEXT_PSF6(context), 0, 0 + psq_st fp7, OS_CONTEXT_PSF7(context), 0, 0 + psq_st fp8, OS_CONTEXT_PSF8(context), 0, 0 + psq_st fp9, OS_CONTEXT_PSF9(context), 0, 0 + psq_st fp10, OS_CONTEXT_PSF10(context), 0, 0 + psq_st fp11, OS_CONTEXT_PSF11(context), 0, 0 + psq_st fp12, OS_CONTEXT_PSF12(context), 0, 0 + psq_st fp13, OS_CONTEXT_PSF13(context), 0, 0 + psq_st fp14, OS_CONTEXT_PSF14(context), 0, 0 + psq_st fp15, OS_CONTEXT_PSF15(context), 0, 0 + psq_st fp16, OS_CONTEXT_PSF16(context), 0, 0 + psq_st fp17, OS_CONTEXT_PSF17(context), 0, 0 + psq_st fp18, OS_CONTEXT_PSF18(context), 0, 0 + psq_st fp19, OS_CONTEXT_PSF19(context), 0, 0 + psq_st fp20, OS_CONTEXT_PSF20(context), 0, 0 + psq_st fp21, OS_CONTEXT_PSF21(context), 0, 0 + psq_st fp22, OS_CONTEXT_PSF22(context), 0, 0 + psq_st fp23, OS_CONTEXT_PSF23(context), 0, 0 + psq_st fp24, OS_CONTEXT_PSF24(context), 0, 0 + psq_st fp25, OS_CONTEXT_PSF25(context), 0, 0 + psq_st fp26, OS_CONTEXT_PSF26(context), 0, 0 + psq_st fp27, OS_CONTEXT_PSF27(context), 0, 0 + psq_st fp28, OS_CONTEXT_PSF28(context), 0, 0 + psq_st fp29, OS_CONTEXT_PSF29(context), 0, 0 + psq_st fp30, OS_CONTEXT_PSF30(context), 0, 0 + psq_st fp31, OS_CONTEXT_PSF31(context), 0, 0 + +_return: + blr +} +#endif diff --git a/src/dolphin/os/OSError.c b/src/dolphin/os/OSError.c new file mode 100644 index 0000000..5a54539 --- /dev/null +++ b/src/dolphin/os/OSError.c @@ -0,0 +1,215 @@ +#include +#include +#include + +#include "__os.h" + +OSErrorHandler __OSErrorTable[17]; + +#define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) +u32 __OSFpscrEnableBits = FPSCR_ENABLE; + +void OSReport(const char* msg, ...) { + va_list marker; + va_start(marker, msg); + vprintf(msg, marker); + va_end(marker); +} + +void OSVReport(const char* msg, va_list list) { + vprintf(msg, list); +} + +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; + int enabled; + u32 msr; + u32 fpscr; + OSThread* thread; + int i; + + ASSERTMSGLINE(209, error < 17, "OSSetErrorHandler(): unknown error."); + + enabled = OSDisableInterrupts(); + oldHandler = __OSErrorTable[error]; + __OSErrorTable[error] = handler; + + if (error == __OS_EXCEPTION_FLOATING_POINT_EXCEPTION) { + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + fpscr = PPCMffpscr(); + + if (handler) { + for (thread = __OSActiveThreadQueue.head; thread; + thread = thread->linkActive.next) + { + thread->context.srr1 |= MSR_FE0 | MSR_FE1; + if ((thread->context.state & OS_CONTEXT_STATE_FPSAVED) == 0) { + 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; +} + +volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED | 0x00D8); + +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) { + OSTime now; + u32 fpscr; + u32 msr; + + now = OSGetTime(); + + if (!(context->srr1 & MSR_RI)) { + OSReport("Non-recoverable Exception %d", exception); + } else { + if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && + __OSErrorTable[__OS_EXCEPTION_FLOATING_POINT_EXCEPTION] != 0) + { + exception = __OS_EXCEPTION_FLOATING_POINT_EXCEPTION; + + msr = PPCMfmsr(); + PPCMtmsr(msr | 0x2000); + + 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 &= ~0x2000; + __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 &= ~0x2000; + __OSFPUContext = NULL; + } + + OSLoadContext(context); + } + + if (__OSErrorTable[exception]) { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } + if (exception == __OS_EXCEPTION_DECREMENTER) { + OSLoadContext(context); + } + OSReport("Unhandled Exception %d", exception); + } +#if DEBUG + OSReport("(%s)", __OSExceptionNames[exception]); +#endif + OSReport("\n"); + OSDumpContext(context); + OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); + OSReport("TB = 0x%016llx\n", now); + + switch(exception) { + case __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_EXCEPTION_MEMORY_PROTECTION: + OSReport("\n"); + OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[DSP_DMA_START_HI], + __DSPRegs[DSP_DMA_START_LO]); + OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[DSP_ARAM_DMA_MM_HI], + __DSPRegs[DSP_ARAM_DMA_MM_LO]); + OSReport("DI DMA Address = 0x%08x\n", __DIRegs[5]); + break; + } + + OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, + __OSLastInterruptSrr0, __OSLastInterruptTime); + PPCHalt(); +} diff --git a/src/dolphin/os/OSFatal.c b/src/dolphin/os/OSFatal.c new file mode 100644 index 0000000..673ddf9 --- /dev/null +++ b/src/dolphin/os/OSFatal.c @@ -0,0 +1,246 @@ +#include +#include +#include +#include + +#include "__os.h" + +typedef struct OSFatalParam { + GXColor fg; + GXColor bg; + const char* msg; +} OSFatalParam; + +static OSFatalParam FatalParam; +static OSContext FatalContext; + +// prototypes +static void Halt(); + +static void ScreenClear(void* xfb, u16 xfbW, u16 xfbH, GXColor yuv) { + int i; + int j; + u8* ptr; + + ptr = xfb; + for (i = 0; i < xfbH; i++) { + for (j = 0; j < xfbW; j += 2) { + *ptr++ = yuv.r; + *ptr++ = yuv.g; + *ptr++ = yuv.r; + *ptr++ = yuv.b; + } + } +} + +static void ScreenReport(void* xfb, u16 xfbW, u16 xfbH, GXColor yuv, s32 x, s32 y, s32 leading, const char* string) { + u8* ptr; + s32 width; + u32 i; + u32 j; + u32 image[72]; + u32 k; + u32 l; + u8 Y; + u32 pixel; + s32 col; + +loop_1: + if (xfbH - 24 >= y) { + ptr = (u8*)xfb + ((x + (y * xfbW)) * 2); + col = x; + + while ((s8)*string != 0) { + if ((s8)*string == '\n') { + string++; + y += leading; + goto loop_1; + } + + if (xfbW - 48 < col) { + y += leading; + goto loop_1; + } + + for (i = 0; i < 24; i++) { + j = (i & 7) + ((i >> 3) * 24); + image[j + 0 ] = 0; + image[j + 8 ] = 0; + image[j + 16] = 0; + } + + string = OSGetFontTexel((char*)string, image, 0, 6, &width); + + for (i = 0; i < 24; i++) { + j = (i & 7) + ((i >> 3) * 24); + + for (k = 0; k < 24; k++) { + l = j + (k & 0xFFFFFFF8); + + Y = (image[l] >> ((7 - (k & 7)) * 4)) & 0xF; + if (Y != 0) { + Y = (((yuv.r * (Y * 0xEF)) / 255) / 15) + 0x10; + pixel = k + (i * xfbW); + ptr[pixel * 2] = Y; + + if ((col + k) & 1) { + ptr[(pixel * 2) - 1] = yuv.g; + ptr[(pixel * 2) + 1] = yuv.b; + } else { + ptr[(pixel * 2) - 1] = yuv.b; + ptr[(pixel * 2) + 1] = yuv.g; + } + } + } + } + + ptr += width * 2; + col += width; + } + } +} + +static void ConfigureVideo(u16 xfbW, u16 xfbH) { + GXRenderModeObj mode; + mode.fbWidth = xfbW; + mode.efbHeight = 480; + mode.xfbHeight = xfbH; + mode.viXOrigin = 40; + mode.viWidth = 640; + mode.viHeight = xfbH; + + switch (VIGetTvFormat()) { + case 2: + case 0: + if (__VIRegs[54] & 1) { + mode.viTVmode = 2; + mode.viYOrigin = 0; + mode.xFBmode = 0; + } else { + mode.viTVmode = 0; + mode.viYOrigin = 0; + mode.xFBmode = 1; + } + break; + case 5: + mode.viTVmode = 20; + mode.viYOrigin = 0; + mode.xFBmode = 1; + break; + case 1: + mode.viTVmode = 4; + mode.viYOrigin = 47; + mode.xFBmode = 1; + break; + } + + VIConfigure(&mode); + VIConfigurePan(0, 0, 640, 480); +} + +static GXColor RGB2YUV(GXColor rgb) { + f32 Y; + f32 Cb; + f32 Cr; + GXColor yuv; + + Y = 0.5f + (16.0f + ((0.098f * (f32) rgb.b) + ((0.257f * (f32) rgb.r) + (0.504f * (f32) rgb.g)))); + Cb = 0.5f + (128.0f + ((0.439f * (f32) rgb.b) + ((-0.148f * (f32) rgb.r) - (0.291f * (f32) rgb.g)))); + Cr = 0.5f + (128.0f + (((0.439f * (f32) rgb.r) - (0.368f * (f32) rgb.g)) - (0.071f * (f32) rgb.b))); + + yuv.r = (Y > 235.0f) ? 235.0f : (Y < 16.0f) ? 16.0f : Y; + yuv.g = (Cb > 240.0f) ? 240.0f : (Cb < 16.0f) ? 16.0f : Cb; + yuv.b = (Cr > 240.0f) ? 240.0f : (Cr < 16.0f) ? 16.0f : Cr; + yuv.a = 0; + + return yuv; +} + +void OSFatal(GXColor fg, GXColor bg, const char* msg) { + OSBootInfo* bootInfo; + u32 count; + OSTime t; + + bootInfo = (OSBootInfo*)OSPhysicalToCached(0); + OSDisableInterrupts(); + OSDisableScheduler(); + OSClearContext(&FatalContext); + OSSetCurrentContext(&FatalContext); + __OSStopAudioSystem(); + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + VIInit(); + __OSUnmaskInterrupts(0x80); + VISetBlack(TRUE); + VIFlush(); + VISetPreRetraceCallback(NULL); + VISetPostRetraceCallback(NULL); + OSEnableInterrupts(); + + count = VIGetRetraceCount(); + do {} while ((s32)(VIGetRetraceCount() - count) < 1); + + t = OSGetTime(); + while (!__OSCallResetFunctions(FALSE) && OSGetTime() - t < OSMillisecondsToTicks(1000)) {} + + OSDisableInterrupts(); + __OSCallResetFunctions(TRUE); + EXISetExiCallback(0, NULL); + EXISetExiCallback(2, NULL); + + while (!EXILock(0, 1, NULL)) { + EXISync(0); + EXIDeselect(0); + EXIUnlock(0); + } + EXIUnlock(0); + + do {} while ((__EXIRegs[3] & 1) == 1); + + __OSSetExceptionHandler(8, &OSDefaultExceptionHandler); + GXAbortFrame(); + OSSetArenaLo((void*)0x81400000); + OSSetArenaHi(bootInfo->FSTLocation); + + FatalParam.fg = fg; + FatalParam.bg = bg; + FatalParam.msg = msg; + OSSwitchFiber((u32)&Halt, (u32)OSGetArenaHi()); +} + +static void Halt() { + u32 count; + OSFontHeader* fontData; + void* xfb; + u32 len; + OSFatalParam* fp; + + OSEnableInterrupts(); + fp = &FatalParam; + len = strlen(fp->msg) + 1; + fp->msg = memmove(OSAllocFromArenaLo(len, DOLPHIN_ALIGNMENT), fp->msg, len); + + fontData = OSAllocFromArenaLo(0xA1004, DOLPHIN_ALIGNMENT); + OSLoadFont(fontData, OSGetArenaLo()); + + xfb = OSAllocFromArenaLo(0x96000, DOLPHIN_ALIGNMENT); + ScreenClear(xfb, 640, 480, RGB2YUV(fp->bg)); + VISetNextFrameBuffer(xfb); + ConfigureVideo(640, 480); + VIFlush(); + + count = VIGetRetraceCount(); + do {} while ((s32)(VIGetRetraceCount() - count) < 2); + + ScreenReport(xfb, 640, 480, RGB2YUV(fp->fg), 48, 100, fontData->leading, fp->msg); + DCFlushRange(xfb, 0x96000); + VISetBlack(FALSE); + VIFlush(); + + count = VIGetRetraceCount(); + do {} while ((s32)(VIGetRetraceCount() - count) < 1); + + OSDisableInterrupts(); + OSReport("%s\n", fp->msg); + PPCHalt(); +} diff --git a/src/dolphin/os/OSFont.c b/src/dolphin/os/OSFont.c new file mode 100644 index 0000000..4e6738b --- /dev/null +++ b/src/dolphin/os/OSFont.c @@ -0,0 +1,751 @@ +#include +#include + +#include "__os.h" + +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) { + 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; + + do { + // Get next mask + if (flag == 0) { + code = *(u32*)(s + p); + p += sizeof(u32); + flag = sizeof(u32) * 8; + } + + // Non-linked chunk + if (code & 0x80000000) { + d[q++] = s[r25++]; + } + // Linked chunk + else { + // Read offset from link table + j = s[r7] << 8 | s[r7 + 1]; + r7 += sizeof(u16); + + // Apply offset + k = q - (j & 0x0FFF); + cnt = j >> 12; + if (cnt == 0) { + cnt = s[r25++] + 0x12; + } else { + cnt += 2; + } + + // Copy chunk + for (i = 0; i < cnt; i++, q++, k++) { + d[q] = d[k - 1]; + } + } + + // Prepare next mask bit + code <<= 1; + flag--; + } while (q < os); +} + +static u32 GetFontSize(u8* buf) { + if (buf[0] == 'Y' && buf[1] == 'a' && buf[2] == 'y') { + return *(u32*)(buf + 0x4); + } + + return 0; +} + +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; + break; + case VI_PAL: + case VI_MPAL: + case VI_DEBUG: + case VI_DEBUG_PAL: + case VI_EURGB60: + default: + 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); + + if (width != 0) { + *width = ((u8*)font + font->widthTable)[fontCode]; + } + + return (char*)string; +} + +int OSSetFontWidth(int fixed) { + int prev = FixedPitch; + FixedPitch = fixed; + return prev; +} diff --git a/src/dolphin/os/OSInterrupt.c b/src/dolphin/os/OSInterrupt.c new file mode 100644 index 0000000..77d92bb --- /dev/null +++ b/src/dolphin/os/OSInterrupt.c @@ -0,0 +1,509 @@ +#include +#include + +#include "__os.h" + +#if DEBUG +u64 __OSSpuriousInterrupts = 0; +#endif +static __OSInterruptHandler* InterruptHandlerTable; + +volatile OSTime __OSLastInterruptTime; +volatile __OSInterrupt __OSLastInterrupt; +volatile u32 __OSLastInterruptSrr0; + +static OSInterruptMask InterruptPrioTable[] = { + OS_INTERRUPTMASK_PI_ERROR, + OS_INTERRUPTMASK_PI_DEBUG, + OS_INTERRUPTMASK_MEM, + OS_INTERRUPTMASK_PI_RSW, + OS_INTERRUPTMASK_PI_VI, + OS_INTERRUPTMASK_PI_PE, + OS_INTERRUPTMASK_PI_HSP, + OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP | OS_INTERRUPTMASK_AI | + OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI, + OS_INTERRUPTMASK_DSP_AI, + OS_INTERRUPTMASK_PI_CP, + 0xFFFFFFFF, +}; + +#if DEBUG +char* __OSInterruptNames[33] = { + "MEM_0", + "MEM_1", + "MEM_2", + "MEM_3", + "MEM_ADDRESS", + "DSP_AI", + "DSP_ARAM", + "DSP_DSP", + "AI_AI", + "EXI_0_EXI", + "EXI_0_TC", + "EXI_0_EXT", + "EXI_1_EXI", + "EXI_1_TC", + "EXI_1_EXT", + "EXI_2_EXI", + "EXI_2_TC", + "PI_CP", + "PI_PE_TOKEN", + "PI_PE_FINISH", + "PI_SI", + "PI_DI", + "PI_RSW", + "PI_ERROR", + "PI_VI", + "PI_DEBUG", + "PI_HSP", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown" +}; + +char* __OSPIErrors[8] = { + "No Error", + "Misaligned address for CPU request", + "Incorrect transfer type (tt) from CPU", + "Unsupported transfer size", + "Address out of range", + "Write to ROM address space", + "Read from GX Fifo", + "Reserved error code", +}; +#endif + +// prototypes +static void ExternalInterruptHandler(register __OSException exception, register OSContext* context); +extern void __RAS_OSDisableInterrupts_begin(void); +extern void __RAS_OSDisableInterrupts_end(void); + +#ifdef __GEKKO__ +asm BOOL OSDisableInterrupts(void) { + nofralloc +entry __RAS_OSDisableInterrupts_begin + mfmsr r3 + rlwinm r4, r3, 0, 17, 15 + mtmsr r4 +entry __RAS_OSDisableInterrupts_end + rlwinm r3, r3, 17, 31, 31 + blr +} + +asm BOOL OSEnableInterrupts(void) { + nofralloc + + mfmsr r3 + ori r4, r3, 0x8000 + mtmsr r4 + rlwinm r3, r3, 17, 31, 31 + blr +} + +asm BOOL OSRestoreInterrupts(register BOOL level) { + nofralloc + + cmpwi level, 0 + mfmsr r4 + beq _disable + ori r5, r4, 0x8000 + b _restore +_disable: + rlwinm r5, r4, 0, 17, 15 +_restore: + mtmsr r5 + rlwinm r3, r4, 17, 31, 31 + blr +} +#endif + +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) { + __OSInterruptHandler oldHandler; + + ASSERTMSGLINE(411, InterruptHandlerTable, "__OSSetInterruptHandler(): OSInit() must be called in advance."); + ASSERTMSGLINE(413, interrupt < 0x20, "__OSSetInterruptHandler(): unknown interrupt."); + + oldHandler = InterruptHandlerTable[interrupt]; + InterruptHandlerTable[interrupt] = handler; + return oldHandler; +} + +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { + ASSERTMSGLINE(433, InterruptHandlerTable, "__OSGetInterruptHandler(): OSInit() must be called in advance."); + ASSERTMSGLINE(435, interrupt < 0x20, "__OSGetInterruptHandler(): unknown interrupt."); + return InterruptHandlerTable[interrupt]; +} + +void __OSInterruptInit(void) { + InterruptHandlerTable = (void*)OSPhysicalToCached(0x3040); + + memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); + + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0; + *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0; + + __PIRegs[1] = 0xf0; + + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | + OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); + + __OSSetExceptionHandler(4, ExternalInterruptHandler); + #if DEBUG + __PIRegs[0] = 1; + __OSUnmaskInterrupts(0x100); + #endif +} + +static 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; +} + +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) { + #if DEBUG + __OSSpuriousInterrupts++; + #endif + 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; + + #if DEBUG + if (cause & OS_INTERRUPTMASK_PI_ERROR) { + OSReport("PI ERROR\n"); + OSDumpContext(context); + OSReport("\nPIESR = 0x%08x PIEAR = 0x%08x\n", __PIRegs[7], __PIRegs[8]); + __PIRegs[0] = 1; + OSReport("PI Error = %s\n", __OSPIErrors[__PIRegs[7]]); + OSReport("Offending address = 0x%x (from PIEAR)\n", __PIRegs[8]); + } + #endif + + unmasked = cause & ~(*(OSInterruptMask *)OSPhysicalToCached(0x00C4) | + *(OSInterruptMask *)OSPhysicalToCached(0x00C8)); + if (unmasked) { + for (prio = InterruptPrioTable;; ++prio) { + if (unmasked & *prio) { + 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); + } + } + + #if DEBUG + OSReport("Unhandled Interrupt(s): cause %08x intsr %08x\n", cause, intsr); + while (cause) { + interrupt = __cntlzw(cause); + cause &= ~(1 << (0x1F - __cntlzw(cause))); + OSReport(" %s\n", __OSInterruptNames[interrupt]); + } + #endif + + OSLoadContext(context); +} + +#ifdef __GEKKO__ +static asm void ExternalInterruptHandler(register __OSException exception, + register OSContext* context) { +#pragma unused(exception) + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + + stwu r1, -0x8(r1) + b __OSDispatchInterrupt +} +#endif diff --git a/src/dolphin/os/OSLink.c b/src/dolphin/os/OSLink.c new file mode 100644 index 0000000..fbe11fe --- /dev/null +++ b/src/dolphin/os/OSLink.c @@ -0,0 +1,528 @@ +#include +#include + +#include "__os.h" + +#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 AT_ADDRESS(OS_BASE_CACHED | 0x30C8); +const void* __OSStringTable AT_ADDRESS(OS_BASE_CACHED | 0x30D0); + +#define ENQUEUE_INFO(queue, info, link) \ + do { \ + OSModuleInfo* __prev; \ + \ + __prev = (queue)->tail; \ + if (__prev == NULL) \ + (queue)->head = (info); \ + else \ + __prev->link.next = (info); \ + (info)->link.prev = __prev; \ + (info)->link.next = NULL; \ + (queue)->tail = (info); \ + } while (0) + +#define DEQUEUE_INFO(info, queue, link) \ + do { \ + OSModuleInfo* __next; \ + OSModuleInfo* __prev; \ + \ + __next = (info)->link.next; \ + __prev = (info)->link.prev; \ + \ + if (__next == NULL) \ + (queue)->tail = __prev; \ + else \ + __next->link.prev = __prev; \ + \ + if (__prev == NULL) \ + (queue)->head = __next; \ + else \ + __prev->link.next = __next; \ + } while (0) + +#pragma dont_inline on +void OSNotifyLink(OSModuleInfo* module) {} + +void OSNotifyUnlink(OSModuleInfo* module) {} +#pragma dont_inline reset + +void OSSetStringTable(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; +} + +static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { + u32 i; + OSSectionInfo* si; + OSModuleHeader* moduleHeader; + OSModuleInfo* moduleInfo; + OSImportInfo* imp; + + ASSERTLINE(282, newModule->version <= OS_MODULE_VERSION); + + moduleHeader = (OSModuleHeader*)newModule; + moduleHeader->bssSection = 0; + + ASSERTLINE(290, newModule->version < 2 || moduleHeader->align == 0 || (u32) newModule % moduleHeader->align == 0); + ASSERTLINE(293, newModule->version < 2 || moduleHeader->bssAlign == 0 || (u32) bss % moduleHeader->bssAlign == 0); + + if (OS_MODULE_VERSION < newModule->version || + 2 <= newModule->version && + (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || + moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) + { + return FALSE; + } + + ENQUEUE_INFO(&__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) { + ASSERTLINE(326, moduleHeader->bssSection == 0); + moduleHeader->bssSection = (u8)i; + si->offset = (u32)bss; + } + } + + 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) { + ASSERTLINE(400, newModule->version <= OS_MODULE_VERSION && 3 <= newModule->version); + + if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) { + return FALSE; + } + return Link(newModule, bss, TRUE); +} + +static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) { + OSModuleID idNew; + OSImportInfo* imp; + OSRel* rel; + OSSectionInfo* si; + OSSectionInfo* siFlush; + u32* p; + u32 offset; + u32 x; + + ASSERTLINE(434, newModule); + + idNew = newModule->info.id; + ASSERTLINE(436, idNew); + + for (imp = (OSImportInfo*)module->impOffset; + imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) + { + 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; + + ASSERTLINE(546, oldModule->version <= OS_MODULE_VERSION); + + moduleHeader = (OSModuleHeader*)oldModule; + + DEQUEUE_INFO(oldModule, &__OSModuleInfoList, 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) { + ASSERTLINE(589, si->size != 0); + 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; + } + + moduleInfo = __OSModuleInfoList.head; + while (moduleInfo != 0) { + sectionInfo = (OSSectionInfo*)moduleInfo->sectionInfoOffset; + for (i = 0; i < moduleInfo->numSections; i++) { + if (sectionInfo->size != 0) { + baseSection = sectionInfo->offset & 0xFFFFFFFE; + if (baseSection <= (u32)ptr && (u32)ptr < baseSection + sectionInfo->size) { + if (section != 0) { + *section = i; + } + + if (offset != 0) { + *offset = (u32)ptr - baseSection; + } + + return moduleInfo; + } + } + sectionInfo++; + } + moduleInfo = moduleInfo->link.next; + } + + return NULL; +} diff --git a/src/dolphin/os/OSMemory.c b/src/dolphin/os/OSMemory.c new file mode 100644 index 0000000..defbad9 --- /dev/null +++ b/src/dolphin/os/OSMemory.c @@ -0,0 +1,235 @@ +#include +#include +#include + +#include "__os.h" + +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = { + OnReset, + 0x7F, + NULL, + NULL +}; + +u32 OSGetPhysicalMemSize(void) { +#if DEBUG + OSBootInfo* BootInfo = (OSBootInfo*)OSPhysicalToCached(0); + + return BootInfo->memorySize; +#else + return __OSPhysicalMemSize; +#endif +} + +u32 OSGetConsoleSimulatedMemSize(void) { +#if DEBUG + u32* memSize = (u32*)OSPhysicalToCached(0xF0); + + return *memSize; +#else + return __OSSimulatedMemSize; +#endif +} + +static BOOL OnReset(BOOL final) { + if (final != FALSE) { + __MEMRegs[8] = 0xFF; + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_RESET); + } + return TRUE; +} + +void (*__OSErrorTable[])(u16, OSContext*, ...); + +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_EXCEPTION_MEMORY_PROTECTION]) { + __OSErrorTable[__OS_EXCEPTION_MEMORY_PROTECTION](__OS_EXCEPTION_MEMORY_PROTECTION, context, cause, addr); + return; + } + + __OSUnhandledException(__OS_EXCEPTION_MEMORY_PROTECTION, context, cause, addr); +} + +void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) { + BOOL enabled; + u32 start; + u32 end; + u16 reg; + + ASSERTLINE(206, chan < 4); + ASSERTLINE(207, (control & ~(OS_PROTECT_CONTROL_RDWR)) == 0); + + if (4 <= chan) { + return; + } + + control &= 3; + + 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 &= ~(3 << 2 * chan); + reg |= control << 2 * chan; + __MEMRegs[8] = reg; + + if (control != 3) { + __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan)); + } + + OSRestoreInterrupts(enabled); +} + +#ifdef __GEKKO__ +static asm void Config24MB(void) { + nofralloc + li r7, 0x0 + lis r4, 0x0 + addi r4, r4, 0x2 + lis r3, 0x8000 + addi r3, r3, 0x1ff + lis r6, 0x100 + addi r6, r6, 0x2 + lis r5, 0x8100 + addi r5, r5, 0xff + isync + mtdbatu 0, r7 + mtdbatl 0, r4 + mtdbatu 0, r3 + isync + mtibatu 0, r7 + mtibatl 0, r4 + mtibatu 0, r3 + isync + mtdbatu 2, r7 + mtdbatl 2, r6 + mtdbatu 2, r5 + isync + mtibatu 2, r7 + mtibatl 2, r6 + mtibatu 2, r5 + isync + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + mflr r3 + mtsrr0 r3 + rfi +} +#endif + +#ifdef __GEKKO__ +static asm void Config48MB(void) { + nofralloc + li r7, 0x0 + lis r4, 0x0 + addi r4, r4, 0x2 + lis r3, 0x8000 + addi r3, r3, 0x3ff + lis r6, 0x200 + addi r6, r6, 0x2 + lis r5, 0x8200 + addi r5, r5, 0x1ff + isync + mtdbatu 0, r7 + mtdbatl 0, r4 + mtdbatu 0, r3 + isync + mtibatu 0, r7 + mtibatl 0, r4 + mtibatu 0, r3 + isync + mtdbatu 2, r7 + mtdbatl 2, r6 + mtdbatu 2, r5 + isync + mtibatu 2, r7 + mtibatl 2, r6 + mtibatu 2, r5 + isync + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + mflr r3 + mtsrr0 r3 + rfi +} +#endif + +#ifdef __GEKKO__ +static asm void RealMode(register u32 addr) { + nofralloc + clrlwi addr, addr, 2 + mtsrr0 addr + mfmsr addr + rlwinm addr, addr, 0, 28, 25 + mtsrr1 addr + rfi +} +#endif + +void __OSInitMemoryProtection(void) { +#ifndef DEBUG + u32 padding[9]; + u32 temp; +#endif + BOOL enabled; + u32 size; + + size = 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); + +#ifdef DEBUG + if (OSGetConsoleSimulatedMemSize() < OSGetPhysicalMemSize() && OSGetConsoleSimulatedMemSize() == 0x1800000) +#else + temp = OSGetConsoleSimulatedMemSize(); // not sure how else to get the order right on retail + if (temp < OSGetPhysicalMemSize() && temp == 0x1800000) +#endif + { + DCInvalidateRange((void*)0x81800000, 0x1800000); + __MEMRegs[20] = 2; + } + + if (size <= 0x1800000) { + RealMode((u32)&Config24MB); + } else if (size <= 0x3000000) { + RealMode((u32)&Config48MB); + } + + __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/os/OSMessage.c b/src/dolphin/os/OSMessage.c new file mode 100644 index 0000000..476891b --- /dev/null +++ b/src/dolphin/os/OSMessage.c @@ -0,0 +1,70 @@ +#include +#include + +void OSInitMessageQueue(OSMessageQueue* mq, void* msgArray, s32 msgCount) { + OSInitThreadQueue(&mq->queueSend); + OSInitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; +} + +int OSSendMessage(OSMessageQueue* mq, void* msg, s32 flags) { + BOOL enabled; + s32 lastIndex; + + enabled = OSDisableInterrupts(); + while(mq->msgCount <= mq->usedCount) { + if (!(flags & 1)) { + OSRestoreInterrupts(enabled); + return 0; + } + OSSleepThread(&mq->queueSend); + } + lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + ((u32*)mq->msgArray)[lastIndex] = (u32)msg; + mq->usedCount++; + OSWakeupThread(&mq->queueReceive); + OSRestoreInterrupts(enabled); + return 1; +} + +int OSReceiveMessage(OSMessageQueue* mq, void* msg, s32 flags) { + BOOL enabled = OSDisableInterrupts(); + + while(mq->usedCount == 0) { + if (!(flags & 1)) { + OSRestoreInterrupts(enabled); + return 0; + } + OSSleepThread(&mq->queueReceive); + } + if(msg != NULL) { + *(u32*)msg = ((u32*)mq->msgArray)[mq->firstIndex]; + } + + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + OSWakeupThread(&mq->queueSend); + OSRestoreInterrupts(enabled); + return 1; +} + +int OSJamMessage(OSMessageQueue* mq, void* msg, s32 flags) { + BOOL enabled = OSDisableInterrupts(); + + while(mq->msgCount <= mq->usedCount) { + if(!(flags & 1)) { + OSRestoreInterrupts(enabled); + return 0; + } + OSSleepThread(&mq->queueSend); + } + mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; + ((u32*)mq->msgArray)[mq->firstIndex] = (u32)msg; + mq->usedCount++; + OSWakeupThread(&mq->queueReceive); + OSRestoreInterrupts(enabled); + return 1; +} diff --git a/src/dolphin/os/OSMutex.c b/src/dolphin/os/OSMutex.c new file mode 100644 index 0000000..66b4abd --- /dev/null +++ b/src/dolphin/os/OSMutex.c @@ -0,0 +1,256 @@ +#include +#include + +#include "__os.h" + +#define ENQUEUE_MUTEX(mutex, queue, link) \ + do { \ + OSMutex* __prev = (queue)->tail; \ + if (__prev == NULL) { \ + (queue)->head = (mutex); \ + } else { \ + __prev->link.next = (mutex); \ + } \ + (mutex)->link.prev = __prev; \ + (mutex)->link.next = 0; \ + (queue)->tail = (mutex); \ + } while(0); + +#define DEQUEUE_MUTEX(mutex, queue, link) \ + do { \ + OSMutex* __next = (mutex)->link.next; \ + OSMutex* __prev = (mutex)->link.prev; \ + if (__next == NULL) { \ + (queue)->tail = __prev; \ + } else { \ + __next->link.prev = __prev; \ + } \ + if (__prev == NULL) { \ + (queue)->head = __next; \ + } else { \ + __prev->link.next = __next; \ + } \ + } while(0); + +#define DEQUEUE_HEAD(mutex, queue, link) \ + do { \ + OSMutex* __next = mutex->link.next; \ + if (__next == NULL) { \ + (queue)->tail = 0; \ + } else { \ + __next->link.prev = 0; \ + } \ + (queue)->head = __next; \ + } while(0); + +// prototypes +static int IsMember(OSMutexQueue* queue, OSMutex* mutex); +int __OSCheckMutex(OSMutex* mutex); +int __OSCheckDeadLock(OSThread* thread); +int __OSCheckMutexes(OSThread* thread); + +void OSInitMutex(OSMutex* mutex) { + OSInitThreadQueue(&mutex->queue); + mutex->thread = 0; + mutex->count = 0; +} + +void OSLockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + + ASSERTMSGLINE(140, currentThread, "OSLockMutex(): current thread does not exist."); + ASSERTMSGLINE(142, currentThread->state == 2, "OSLockMutex(): current thread is not running."); + + while (1) { + OSThread* ownerThread = mutex->thread; + if (ownerThread == 0) { + mutex->thread = currentThread; + mutex->count++; + ENQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); + break; + } else if (ownerThread == currentThread) { + mutex->count++; + break; + } else { + currentThread->mutex = mutex; + __OSPromoteThread(mutex->thread, currentThread->priority); + ASSERTMSG2LINE(164, __OSCheckDeadLock(currentThread) == 0, "OSLockMutex(): detected deadlock: current thread %p, mutex %p.", currentThread, mutex); + OSSleepThread(&mutex->queue); + currentThread->mutex = NULL; + } + } + OSRestoreInterrupts(enabled); +} + +void OSUnlockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + + ASSERTMSGLINE(189, currentThread, "OSUnlockMutex(): current thread does not exist."); + ASSERTMSGLINE(191, currentThread->state == 2, "OSUnlockMutex(): current thread is not running."); + ASSERTMSG2LINE(194, mutex->thread == currentThread, "OSUnlockMutex(): current thread %p is not the owner of mutex %p.", currentThread, mutex); + + if (mutex->thread == currentThread) { + if (!--mutex->count) { + DEQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); + mutex->thread = 0; + + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); + } + OSWakeupThread(&mutex->queue); + } + } + OSRestoreInterrupts(enabled); +} + +void __OSUnlockAllMutex(OSThread* thread) { + OSMutex* mutex; + + while (thread->queueMutex.head) { + mutex = thread->queueMutex.head; + DEQUEUE_HEAD(mutex, &thread->queueMutex, link); + ASSERTLINE(229, mutex->thread == thread); + mutex->count = 0; + mutex->thread = 0; + OSWakeupThread(&mutex->queue); + } +} + +BOOL OSTryLockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + BOOL locked; + + ASSERTMSGLINE(255, currentThread, "OSTryLockMutex(): current thread does not exist."); + ASSERTMSGLINE(257, currentThread->state == 2, "OSTryLockMutex(): current thread is not running."); + + if (!mutex->thread) { + mutex->thread = currentThread; + mutex->count++; + ENQUEUE_MUTEX(mutex, ¤tThread->queueMutex, 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(); + + ASSERTMSGLINE(313, currentThread, "OSWaitCond(): current thread does not exist."); + ASSERTMSGLINE(315, currentThread->state == 2, "OSWaitCond(): current thread is not running."); + ASSERTMSG2LINE(318, mutex->thread == currentThread, "OSWaitCond(): current thread %p is not the owner of mutex %p.", currentThread, mutex); + + if (mutex->thread == currentThread) { + s32 count = mutex->count; + mutex->count = 0; + DEQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); + mutex->thread = 0; + 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 int IsMember(OSMutexQueue* queue, OSMutex* mutex) { + OSMutex* member = queue->head; + + while (member) { + if (mutex == member) { + return 1; + } + member = member->link.next; + } + return 0; +} + +int __OSCheckMutex(OSMutex* mutex) { + OSThread* thread; + OSThreadQueue* queue; + s32 priority; + + priority = 0; + queue = &mutex->queue; + + if (queue->head != NULL && queue->head->link.prev != NULL) { + return 0; + } + if (queue->tail != NULL && queue->tail->link.next != NULL) { + return 0; + } + thread = queue->head; + while (thread) { + if (thread->link.next != NULL && (thread != thread->link.next->link.prev)) { + return 0; + } + if (thread->link.prev != NULL && (thread != thread->link.prev->link.next)) { + return 0; + } + if (thread->state != 4) { + return 0; + } + if (thread->priority < priority) { + return 0; + } + priority = thread->priority; + thread = thread->link.next; + } + if (mutex->thread) { + if (mutex->count <= 0) { + return 0; + } + } else if (mutex->count != 0) { + return 0; + } + return 1; +} + +int __OSCheckDeadLock(OSThread* thread) { + OSMutex* mutex = thread->mutex; + + while (mutex && mutex->thread) { + if (mutex->thread == thread) { + return 1; + } + mutex = mutex->thread->mutex; + } + return 0; +} + +int __OSCheckMutexes(OSThread* thread) { + OSMutex* mutex = thread->queueMutex.head; + + while (mutex) { + if (mutex->thread != thread) { + return 0; + } + if (__OSCheckMutex(mutex) == 0) { + return 0; + } + mutex = mutex->link.next; + } + return 1; +} diff --git a/src/dolphin/os/OSReboot.c b/src/dolphin/os/OSReboot.c new file mode 100644 index 0000000..c921b4d --- /dev/null +++ b/src/dolphin/os/OSReboot.c @@ -0,0 +1,39 @@ +#include +#include + +#include "__os.h" + +static void* SaveStart; +static void* SaveEnd; + +void __OSReboot(u32 resetCode, u32 bootDol) { + OSContext exceptionContext; + char* argvToPass; + + OSDisableInterrupts(); + OSSetArenaLo((void*)0x81280000); + OSSetArenaHi((void*)0x812f0000); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + argvToPass = NULL; + __OSBootDol(bootDol, resetCode | 0x80000000, &argvToPass); +} + +void OSSetSaveRegion(void* start, void* end) { + ASSERTMSGLINE(134, (u32)start >= 0x80700000 || start == NULL, "OSSetSaveRegion(): start address should be NULL or higher than 0x80700000\n"); + ASSERTMSGLINE(135, 0x81200000 >= (u32)end || end == NULL, "OSSetSaveRegion(): end address should be NULL or lower than 0x81200000\n"); + ASSERTMSGLINE(136, ((start == NULL) ^ (end == NULL)) == 0, "OSSetSaveRegion(): if either start or end is NULL, both should be NULL\n"); + + SaveStart = start; + SaveEnd = end; +} + +void OSGetSaveRegion(void** start, void** end) { + *start = SaveStart; + *end = SaveEnd; +} + +void OSGetSavedRegion(void** start, void** end) { + *start = __OSRebootParams.regionStart; + *end = __OSRebootParams.regionEnd; +} diff --git a/src/dolphin/os/OSReset.c b/src/dolphin/os/OSReset.c new file mode 100644 index 0000000..21953da --- /dev/null +++ b/src/dolphin/os/OSReset.c @@ -0,0 +1,248 @@ +#include +#include + +#include "__os.h" + +// These macros are copied from OSThread.c. Or ARE they the same +// macros? They dont seem to be in the SDK headers. +#define ENQUEUE_INFO(info, queue) \ + do { \ + OSResetFunctionInfo* __prev = (queue)->tail; \ + if (__prev == 0) { \ + (queue)->head = (info); \ + } else { \ + __prev->next = (info); \ + } \ + (info)->prev = __prev; \ + (info)->next = 0; \ + (queue)->tail = (info); \ + } while(0); + +#define DEQUEUE_INFO(info, queue) \ + do { \ + OSResetFunctionInfo* __next = (info)->next; \ + OSResetFunctionInfo* __prev = (info)->prev; \ + if (__next == 0) { \ + (queue)->tail = __prev; \ + } else { \ + __next->prev = __prev; \ + } \ + if (__prev == 0) { \ + (queue)->head = __next; \ + } else { \ + __prev->next = __next; \ + } \ + } while(0); + +#define ENQUEUE_INFO_PRIO(info, queue) \ + do { \ + OSResetFunctionInfo* __prev; \ + OSResetFunctionInfo* __next; \ + for(__next = (queue)->head; __next \ + && (__next->priority <= (info)->priority); \ + __next = __next->next) ; \ + \ + if (__next == 0) { \ + ENQUEUE_INFO(info, queue); \ + } else { \ + (info)->next = __next; \ + __prev = __next->prev; \ + __next->prev = (info); \ + (info)->prev = __prev; \ + if (__prev == 0) { \ + (queue)->head = (info); \ + } else { \ + __prev->next = (info); \ + } \ + } \ + } while(0); + +static OSResetFunctionQueue ResetFunctionQueue; +static u32 bootThisDol; + +// prototypes +static int CallResetFunctions(int final); +static void Reset(u32 resetCode); + +void OSRegisterResetFunction(OSResetFunctionInfo* info) { + ASSERTLINE(208, info->func); + + ENQUEUE_INFO_PRIO(info, &ResetFunctionQueue); +} + +void OSUnregisterResetFunction(OSResetFunctionInfo* info) { + DEQUEUE_INFO(info, &ResetFunctionQueue); +} + +int __OSCallResetFunctions(BOOL final) { + OSResetFunctionInfo* info; + int err; + u32 priority; + + priority = 0; + err = 0; + + for (info = ResetFunctionQueue.head; info != 0;) { + if (err != 0 && priority != info->priority) + break; + err |= !info->func(final); + priority = info->priority; + info = info->next; + } + + err |= !__OSSyncSram(); + if (err) { + return 0; + } + return 1; +} + +#ifdef __GEKKO__ +static asm void Reset(u32 resetCode) { + nofralloc + b L_000001BC +L_000001A0: + mfspr r8, HID0 + ori r8, r8, 0x8 + mtspr HID0, r8 + isync + sync + nop + b L_000001C0 +L_000001BC: + b L_000001DC +L_000001C0: + mftb r5, 268 +L_000001C4: + mftb r6, 268 + subf r7, r5, r6 + cmplwi r7, 0x1124 + blt L_000001C4 + nop + b L_000001E0 +L_000001DC: + b L_000001FC +L_000001E0: + lis r8, 0xcc00 + ori r8, r8, 0x3000 + li r4, 0x3 + stw r4, 0x24(r8) + stw r3, 0x24(r8) + nop + b L_00000200 +L_000001FC: + b L_00000208 +L_00000200: + nop + b L_00000200 +L_00000208: + b L_000001A0 +} +#endif + +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); + continue; + default: + continue; + } + } +} + +void __OSDoHotReset(u32 resetCode) { + OSDisableInterrupts(); + __VIRegs[1] = 0; + ICFlashInvalidate(); + Reset(resetCode * 8); +} + +void __OSShutdownDevices(BOOL doRecal) { + int rc; + BOOL disableRecalibration; + + __OSStopAudioSystem(); + + if (!doRecal) { + disableRecalibration = __PADDisableRecalibration(TRUE); + } + + do {} while (!__OSCallResetFunctions(FALSE)); + do {} while (!__OSSyncSram()); + + OSDisableInterrupts(); + + rc = __OSCallResetFunctions(TRUE); + ASSERTLINE(408, rc); + + LCDisable(); + if (!doRecal) { + __PADDisableRecalibration(disableRecalibration); + } + + KillThreads(); +} + +void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu) { + OSSram* sram; + + OSDisableScheduler(); + + if (reset == TRUE && forceMenu) { + sram = __OSLockSram(); + sram->flags |= 0x40; + __OSUnlockSram(1); + + resetCode = 0; + } + + if (reset == OS_RESET_SHUTDOWN || + (reset == OS_RESET_RESTART && (bootThisDol || resetCode + 0x3fff0000 == 0))) + { + __OSShutdownDevices(FALSE); + } else { + __OSShutdownDevices(TRUE); + } + + if (reset == OS_RESET_HOTRESET) { + __OSDoHotReset(resetCode); + } else if (reset == OS_RESET_RESTART) { + if (forceMenu == TRUE) { + OSReport("OSResetSystem(): You can't specify TRUE to forceMenu if you restart. Ignored\n"); + } + OSEnableScheduler(); + __OSReboot(resetCode, bootThisDol); + } + + 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); +} + +u32 OSGetResetCode() { + u32 resetCode; + if (__OSRebootParams.valid) + resetCode = 0x80000000 | __OSRebootParams.restartCode; + else + resetCode = (__PIRegs[9] & 0xFFFFFFF8) / 8; + + return resetCode; +} + +u32 OSSetBootDol(u32 dolOffset) { + u32 oldDol; + + oldDol = bootThisDol; + bootThisDol = dolOffset; + return oldDol; +} diff --git a/src/dolphin/os/OSResetSW.c b/src/dolphin/os/OSResetSW.c new file mode 100644 index 0000000..bbc5d2d --- /dev/null +++ b/src/dolphin/os/OSResetSW.c @@ -0,0 +1,120 @@ +#include +#include + +#include "__os.h" + +static OSResetCallback ResetCallback; +static BOOL Down; +static BOOL LastState; +static OSTime HoldUp; +static OSTime HoldDown; + +void __OSResetSWInterruptHandler(s16 exception, 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; +} + +OSResetCallback OSSetResetCallback(OSResetCallback callback) { + BOOL enabled; + OSResetCallback prevCallback; + + enabled = OSDisableInterrupts(); + prevCallback = ResetCallback; + ResetCallback = callback; + + if (callback) { + __PIRegs[0] = 2; + __OSUnmaskInterrupts(0x200); + } else { + __OSMaskInterrupts(0x200); + } + OSRestoreInterrupts(enabled); + return prevCallback; +} + +BOOL OSGetResetButtonState(void) { + BOOL enabled = OSDisableInterrupts(); + int state; + u32 reg; + OSTime now; + + now = __OSGetSystemTime(); + ASSERTLINE(158, 0 <= now); + ASSERTLINE(159, HoldUp == 0 || HoldUp < now); + ASSERTLINE(160, HoldDown == 0 || HoldDown < now); + + reg = __PIRegs[0]; + if (!(reg & 0x00010000)) { + if (!Down) { + Down = TRUE; + 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 (__gUnknown800030E3 & 0x1F) { + OSTime fire = (__gUnknown800030E3 & 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; +} + +int OSGetResetSwitchState(void) { + return OSGetResetButtonState(); +} + +void __OSSetResetButtonTimer(u8 min) { + BOOL enabled = OSDisableInterrupts(); + if (min > 0x1F) { + min = 0x1F; + } + + __gUnknown800030E3 &= ~0x1F; + __gUnknown800030E3 |= min; + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/os/OSRtc.c b/src/dolphin/os/OSRtc.c new file mode 100644 index 0000000..7b37b4c --- /dev/null +++ b/src/dolphin/os/OSRtc.c @@ -0,0 +1,513 @@ +#include +#include + +#include "__os.h" + +static SramControl Scb ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT); + +// prototypes +static int GetRTC(u32* rtc); +static int ReadSram(void* buffer); +static void WriteSramCallback(s32, OSContext*); +static int WriteSram(void* buffer, u32 offset, u32 size); +static void* LockSram(u32 offset); +static int UnlockSram(int commit, u32 offset); +static void __OSReadROMCallback(s32 chan); + +static int GetRTC(u32* rtc) { + int err; + u32 cmd; + + if (EXILock(0, 1, NULL) == 0) { + return 0; + } + if (EXISelect(0, 1, 3) == 0) { + EXIUnlock(0); + return 0; + } + cmd = 0x20000000; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIImm(0, &cmd, 4, 0, 0); + err |= !EXISync(0); + err |= !EXIDeselect(0); + EXIUnlock(0); + rtc[0] = cmd; + return !err; +} + +int __OSGetRTC(u32* rtc) { + int err; + u32 t0; + u32 t1; + int i; + + for(i = 0; i < 16; i++) { + err = 0; + err |= !GetRTC(&t0); + err |= !GetRTC(&t1); + if (err) { + break; + } + if (t0 == t1) { + rtc[0] = t0; + return 1; + } + } + return 0; +} + +int __OSSetRTC(u32 rtc) { + int err; + u32 cmd; + + if (EXILock(0, 1, NULL) == 0) { + return 0; + } + if (EXISelect(0, 1, 3) == 0) { + EXIUnlock(0); + return 0; + } + cmd = 0xA0000000; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIImm(0, &rtc, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIDeselect(0); + EXIUnlock(0); + return !err; +} + +static int ReadSram(void* buffer) { + int err; + u32 cmd; + + DCInvalidateRange(buffer, SRAM_SIZE); + if (!EXILock(0, 1, NULL) ) { + return 0; + } + if (!EXISelect(0, 1, 3)) { + EXIUnlock(0); + return 0; + } + cmd = 0x20000100; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIDma(0, buffer, SRAM_SIZE, 0, NULL); + err |= !EXISync(0); + err |= !EXIDeselect(0); + EXIUnlock(0); + return !err; +} + +static void WriteSramCallback(s32, OSContext*) { + ASSERTLINE(258, !Scb.locked); + Scb.sync = WriteSram(&Scb.sram[Scb.offset], Scb.offset, SRAM_SIZE - Scb.offset); + if (Scb.sync != 0) { + Scb.offset = SRAM_SIZE; + } + ASSERTLINE(264, Scb.sync); +} + +static int WriteSram(void* buffer, u32 offset, u32 size) { + int err; + u32 cmd; + + if (!EXILock(0, 1, WriteSramCallback)) { + return 0; + } + if (!EXISelect(0, 1, 3)) { + EXIUnlock(0); + return 0; + } + offset <<= 6; + cmd = ((offset + 0x100) | 0xA0000000); + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIImmEx(0, buffer, size, 1); + err |= !EXIDeselect(0); + EXIUnlock(0); + return !err; +} + +void __OSInitSram(void) { + Scb.locked = Scb.enabled = FALSE; + Scb.sync = ReadSram(&Scb); + ASSERTLINE(318, Scb.sync); + Scb.offset = SRAM_SIZE; + + OSSetGbsMode(OSGetGbsMode()); +} + +static void* LockSram(u32 offset) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + ASSERTLINE(341, !Scb.locked); + if (Scb.locked) { + OSRestoreInterrupts(enabled); + return NULL; + } + Scb.enabled = enabled; + Scb.locked = TRUE; + return &Scb.sram[offset]; +} + +OSSram* __OSLockSram(void) { + return (OSSram*)LockSram(0); +} + +OSSramEx* __OSLockSramEx(void) { + return (OSSramEx*)LockSram(sizeof(OSSram)); +} + +static int UnlockSram(int commit, u32 offset) { + u16* p; + + ASSERTLINE(375, Scb.locked); + if (commit != 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[0x14]); p++) { + sram->checkSum += *p; + sram->checkSumInv += ~(*p); + } + } + if (offset < Scb.offset) { + Scb.offset = offset; + } + + if (Scb.offset <= 0x14) { + OSSramEx* sram = (OSSramEx*)(Scb.sram + sizeof(OSSram)); + if (((u32)sram->gbs & 0x7c00) == 0x5000 || ((u32)sram->gbs & 0xc0) == 0xc0) { + sram->gbs = 0; + } + } + + Scb.sync = WriteSram(&Scb.sram[Scb.offset], Scb.offset, SRAM_SIZE - Scb.offset); + if (Scb.sync != 0) { + Scb.offset = SRAM_SIZE; + } + } + Scb.locked = FALSE; + OSRestoreInterrupts(Scb.enabled); + return Scb.sync; +} + +int __OSUnlockSram(int commit) { + UnlockSram(commit, 0); +} + +int __OSUnlockSramEx(int commit) { + UnlockSram(commit, sizeof(OSSram)); +} + +int __OSSyncSram(void) { + return Scb.sync; +} + +int __OSCheckSram(void) { + u16* p; + u16 checkSum; + u16 checkSumInv; + OSSram* sram; + int unused; + + ASSERTLINE(466, Scb.locked); + + checkSum = checkSumInv = 0; + + sram = (OSSram*)Scb.sram; + + for (p = (void*)&sram->counterBias; p < (u16*)&Scb.sram[0x14]; p++) { + checkSum += *p; + checkSumInv += ~(*p); + } + + return (sram->checkSum == checkSum && sram->checkSumInv == checkSumInv); +} + +int __OSReadROM(void * buffer, s32 length, s32 offset) { + int err; + u32 cmd; + + ASSERTLINE(497, length <= 1024); + DCInvalidateRange(buffer, length); + if (EXILock(0, 1, NULL) == 0) { + return 0; + } + if (EXISelect(0, 1, 3) == 0) { + EXIUnlock(0); + return 0; + } + cmd = offset << 6; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIDma(0, buffer, length, 0, NULL); + err |= !EXISync(0); + err |= !EXIDeselect(0); + EXIUnlock(0); + return !err; +} + +static void __OSReadROMCallback(s32 chan) { + void (*callback)(); + + EXIDeselect(chan); + EXIUnlock(chan); + callback = Scb.callback; + if (callback) { + Scb.callback = NULL; + callback(); + } +} + +int __OSReadROMAsync(void* buffer, s32 length, s32 offset, void (*callback)()) { + int err; + u32 cmd; + + ASSERTLINE(556, length <= 1024); + ASSERTLINE(557, callback); + DCInvalidateRange(buffer, length); + Scb.callback = callback; + if (EXILock(0, 1, NULL) == 0) { + return 0; + } + if (EXISelect(0, 1, 3) == 0) { + EXIUnlock(0); + return 0; + } + cmd = offset << 6; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIDma(0, buffer, length, 0, (void*)__OSReadROMCallback); + return !err; +} + +u32 OSGetSoundMode(void) { + OSSram* sram = __OSLockSram(); + u32 mode = (sram->flags & 4) ? 1 : 0; + + __OSUnlockSram(0); + return mode; +} + +void OSSetSoundMode(u32 mode) { + OSSram* sram; + int unused; + + ASSERTLINE(617, mode == OS_SOUND_MODE_MONO || mode == OS_SOUND_MODE_STEREO); + mode *= 4; + mode &= 4; + sram = __OSLockSram(); + if (mode == (sram->flags & 4)) { + __OSUnlockSram(0); + return; + } + sram->flags &= 0xFFFFFFFB; + sram->flags |= mode; + __OSUnlockSram(1); +} + +u32 OSGetProgressiveMode(void) { + OSSram* sram; + u32 on; + + sram = __OSLockSram(); + on = (sram->flags & 0x80) >> 7; + __OSUnlockSram(FALSE); + return on; +} + +void OSSetProgressiveMode(u32 on) { +#ifndef DEBUG + u32 padding[1]; +#endif + OSSram* sram; + + ASSERTLINE(670, on == OS_PROGRESSIVE_MODE_OFF || on == OS_PROGRESSIVE_MODE_ON); + + on <<= 7; + on &= 0x80; + + sram = __OSLockSram(); + if (on == (sram->flags & 0x80)) { + __OSUnlockSram(FALSE); + return; + } + + sram->flags &= ~0x80; + sram->flags |= on; + __OSUnlockSram(TRUE); +} + +u32 OSGetVideoMode(void) { + OSSram* sram = __OSLockSram(); + u32 mode = sram->flags & 3; + + __OSUnlockSram(0); + + if (mode > 2) { + mode = 0; + } + + return mode; +} + +void OSSetVideoMode(u32 mode) { + OSSram* sram; + int unused; + + ASSERTLINE(731, OS_VIDEO_MODE_NTSC <= mode && mode <= OS_VIDEO_MODE_MPAL); + + if (mode > 2) { + mode = 0; + } + + sram = __OSLockSram(); + + if (mode == (sram->flags & 3)) { + __OSUnlockSram(0); + return; + } + sram->flags &= 0xFFFFFFFC; + sram->flags |= mode; + __OSUnlockSram(1); +} + +u8 OSGetLanguage(void) { + OSSram* sram = __OSLockSram(); + u8 language = sram->language; + + __OSUnlockSram(0); + return language; +} + +void OSSetLanguage(u8 language) { + OSSram* sram = __OSLockSram(); + int unused; + + if (language == sram->language) { + __OSUnlockSram(0); + return; + } + sram->language = language; + __OSUnlockSram(1); +} + +u8 __OSGetBootMode(void) { + OSSram* sram = __OSLockSram(); + u8 ntd = sram->ntd; + __OSUnlockSram(0); + return ntd & 0x80; +} + +void __OSSetBootMode(u8 ntd) { + OSSram* sram; + int unused; + + ntd &= 0x80; + sram = __OSLockSram(); + if (ntd == (sram->ntd & 0x80U)) { + __OSUnlockSram(0); + return; + } + sram->ntd &= 0xFFFFFF7F; + sram->ntd |= ntd; + __OSUnlockSram(1); +} + +u32 OSGetEuRgb60Mode(void) { + OSSram* sram; + u32 on; + + sram = __OSLockSram(); + on = (sram->ntd & 0x40) >> 6; + __OSUnlockSram(0); + return on; +} + +void OSSetEuRgb60Mode(u32 on) { +#ifndef DEBUG + u32 padding[1]; +#endif + OSSram* sram; + + ASSERTLINE(895, on == OS_EURGB60_OFF || on == OS_EURGB60_ON); + on <<= 6; + on &= 0x40; + + sram = __OSLockSram(); + if (on == (sram->ntd & 0x40)) { + __OSUnlockSram(0); + } else { + sram->ntd &= ~0x40; + sram->ntd |= on; + __OSUnlockSram(1); + } +} + +u16 OSGetWirelessID(s32 chan) { + OSSramEx* sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->wirelessPadID[chan]; + __OSUnlockSramEx(FALSE); + return id; +} + +void OSSetWirelessID(s32 chan, u16 id) { + OSSramEx* sram; + + sram = __OSLockSramEx(); + if (sram->wirelessPadID[chan] != id) { + sram->wirelessPadID[chan] = id; + __OSUnlockSramEx(TRUE); + return; + } + + __OSUnlockSramEx(FALSE); +} + +u16 OSGetGbsMode(void) { + OSSramEx* sram; + u16 mode; + + sram = __OSLockSramEx(); + mode = sram->gbs; + __OSUnlockSramEx(FALSE); + return mode; +} + +void OSSetGbsMode(u16 mode) { +#ifndef DEBUG + u32 padding[1]; +#endif + OSSramEx* sram; + + 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); +} diff --git a/src/dolphin/os/OSStopwatch.c b/src/dolphin/os/OSStopwatch.c new file mode 100644 index 0000000..c53c168 --- /dev/null +++ b/src/dolphin/os/OSStopwatch.c @@ -0,0 +1,55 @@ +#include +#include + +void OSInitStopwatch(OSStopwatch* sw, char* name) { + sw->name = name; + sw->total = 0; + sw->hits = 0; + sw->min = 0x00000000FFFFFFFF; + sw->max = 0; +} + +void OSStartStopwatch(OSStopwatch* sw) { + sw->running = TRUE; + sw->last = OSGetTime(); +} + +void OSStopStopwatch(OSStopwatch* sw) { + OSTime interval; + + if (sw->running) { + interval = OSGetTime() - sw->last; + sw->total += interval; + sw->running = FALSE; + sw->hits++; + if (sw->max < interval) { + sw->max = interval; + } + if (interval < sw->min) { + sw->min = interval; + } + } +} + +OSTime OSCheckStopwatch(OSStopwatch* sw) { + OSTime currTotal; + + currTotal = sw->total; + if (sw->running) { + currTotal += OSGetTime() - sw->last; + } + return currTotal; +} + +void OSResetStopwatch(OSStopwatch* sw) { + OSInitStopwatch(sw, sw->name); +} + +void OSDumpStopwatch(OSStopwatch* sw) { + OSReport("Stopwatch [%s] :\n", sw->name); + OSReport("\tTotal= %lld us\n", OSTicksToMicroseconds(sw->total)); + OSReport("\tHits = %d \n", sw->hits); + OSReport("\tMin = %lld us\n", OSTicksToMicroseconds(sw->min)); + OSReport("\tMax = %lld us\n", OSTicksToMicroseconds(sw->max)); + OSReport("\tMean = %lld us\n", OSTicksToMicroseconds(sw->total/sw->hits)); +} diff --git a/src/dolphin/os/OSSync.c b/src/dolphin/os/OSSync.c new file mode 100644 index 0000000..0f91a19 --- /dev/null +++ b/src/dolphin/os/OSSync.c @@ -0,0 +1,33 @@ +#include +#include + +#include "__os.h" + +// prototypes +void __OSSystemCallVectorStart(void); +void __OSSystemCallVectorEnd(void); + +#ifdef __GEKKO__ +static asm void SystemCallVector(void) { +entry __OSSystemCallVectorStart + nofralloc + mfspr r9, HID0 + ori r10, r9, 0x8 + mtspr HID0, r10 + isync + sync + mtspr HID0, r9 + rfi +entry __OSSystemCallVectorEnd + nop +} +#endif + +void __OSInitSystemCall(void) { + void* addr = (void*)OSPhysicalToCached(0xC00); + + memcpy(addr, __OSSystemCallVectorStart, (u32)&__OSSystemCallVectorEnd - (u32)&__OSSystemCallVectorStart); + DCFlushRangeNoSync(addr, 0x100); + __sync(); + ICInvalidateRange(addr, 0x100); +} diff --git a/src/dolphin/os/OSThread.c b/src/dolphin/os/OSThread.c new file mode 100644 index 0000000..6f709ec --- /dev/null +++ b/src/dolphin/os/OSThread.c @@ -0,0 +1,875 @@ +#include +#include + +#include "__os.h" + +#define ENQUEUE_THREAD(thread, queue, link) \ + do { \ + OSThread* __prev = (queue)->tail; \ + if (__prev == NULL) { \ + (queue)->head = (thread); \ + } else { \ + __prev->link.next = (thread); \ + } \ + (thread)->link.prev = __prev; \ + (thread)->link.next = 0; \ + (queue)->tail = (thread); \ + } while(0); + +#define DEQUEUE_THREAD(thread, queue, link) \ + do { \ + OSThread* __next = (thread)->link.next; \ + OSThread* __prev = (thread)->link.prev; \ + if (__next == NULL) { \ + (queue)->tail = __prev; \ + } else { \ + __next->link.prev = __prev; \ + } \ + if (__prev == NULL) { \ + (queue)->head = __next; \ + } else { \ + __prev->link.next = __next; \ + } \ + } while(0); + +#define ENQUEUE_THREAD_PRIO(thread, queue, link) \ + do { \ + OSThread* __prev; \ + OSThread* __next; \ + for(__next = (queue)->head; __next \ + && (__next->priority <= (thread)->priority); \ + __next = __next->link.next) ; \ + \ + if (__next == NULL) { \ + ENQUEUE_THREAD(thread, queue, link); \ + } else { \ + (thread)->link.next = __next; \ + __prev = __next->link.prev; \ + __next->link.prev = (thread); \ + (thread)->link.prev = __prev; \ + if (__prev == NULL) { \ + (queue)->head = (thread); \ + } else { \ + __prev->link.next = (thread); \ + } \ + } \ + } while(0); + +#define DEQUEUE_HEAD(thread, queue, link) \ + do { \ + OSThread* __next = thread->link.next; \ + if (__next == NULL) { \ + (queue)->tail = 0; \ + } else { \ + __next->link.prev = 0; \ + } \ + (queue)->head = __next; \ + } while(0); + +// defined in linkscript +extern u8 _stack_end[]; +extern u8 _stack_addr[]; + +static OSThreadQueue RunQueue[32]; +static OSThread IdleThread; +static OSThread DefaultThread; +static OSContext IdleContext; +static volatile u32 RunQueueBits; +static volatile int RunQueueHint; +static s32 Reschedule; + +#define ALIGN4(val) (((val) + 0x3) & ~0x3) +#define ALIGN8(val) (((val) + 0x7) & ~0x7) + +// prototypes +static void OSInitMutexQueue(OSMutexQueue* queue); +static void __OSSwitchThread(OSThread* nextThread); +static int __OSIsThreadActive(OSThread* thread); +static void SetRun(OSThread* thread); +static void UnsetRun(OSThread* thread); +static OSThread* SetEffectivePriority(OSThread* thread, s32 priority); +static void UpdatePriority(OSThread* thread); +static OSThread* SelectThread(int yield); +static int CheckThreadQueue(OSThreadQueue* queue); +static int IsMember(OSThreadQueue* queue, OSThread* thread); +static void OSSetCurrentThread(OSThread* thread); + +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {} +static OSSwitchThreadCallback SwitchThreadCallback = DefaultSwitchThreadCallback; + +OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback callback) { + OSSwitchThreadCallback prev; + BOOL enabled; + + enabled = OSDisableInterrupts(); + prev = SwitchThreadCallback; + + SwitchThreadCallback = callback ? callback : DefaultSwitchThreadCallback; + OSRestoreInterrupts(enabled); + + if (prev == DefaultSwitchThreadCallback) { + return NULL; + } + + return prev; +} + +static inline void OSSetCurrentThread(OSThread* thread) { + SwitchThreadCallback(__OSCurrentThread, thread); + __OSCurrentThread = thread; +} + +void __OSThreadInit() { + OSThread* thread = &DefaultThread; + OSPriority prio; + + thread->state = OS_THREAD_STATE_RUNNING; + thread->attr = 1; + thread->priority = thread->base = 0x10; + thread->suspend = 0; + thread->val = (void*)-1; // wut + thread->mutex = 0; + + OSInitThreadQueue(&thread->queueJoin); +#ifdef DEBUG + OSInitMutexQueue(&thread->queueMutex); +#else + thread->queueMutex.head = thread->queueMutex.tail = 0; // it got inlined? cant reproduce the inline... +#endif + + ASSERTLINE(LINE(348, 357, 357), PPCMfmsr() & MSR_FP); + + __gUnkThread1 = thread; + OSClearContext(&thread->context); + OSSetCurrentContext(&thread->context); + thread->stackBase = (u8*)&_stack_addr; + thread->stackEnd = (u32*)&_stack_end; + *(u32*)thread->stackEnd = OS_THREAD_STACK_MAGIC; + OSSetCurrentThread(thread); + OSClearStack(0); + RunQueueBits = 0; + RunQueueHint = 0; + + for (prio = 0; prio <= 31; prio++) { + OSInitThreadQueue(&RunQueue[prio]); + } + OSInitThreadQueue(&__OSActiveThreadQueue); + + ENQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + + OSClearContext(&IdleContext); + Reschedule = 0; +} + +#if DEBUG +static void OSInitMutexQueue(OSMutexQueue* queue) { + queue->head = queue->tail = 0; +} +#endif + +void OSInitThreadQueue(OSThreadQueue* queue) { + queue->head = queue->tail = 0; +} + +OSThread* OSGetCurrentThread() { + return __OSCurrentThread; +} + +static void __OSSwitchThread(OSThread* nextThread) { + OSSetCurrentThread(nextThread); + OSSetCurrentContext(&nextThread->context); + OSLoadContext(&nextThread->context); +} + +BOOL OSIsThreadSuspended(OSThread* thread) { + if (thread->suspend > 0) { + return TRUE; + } + return FALSE; +} + +BOOL OSIsThreadTerminated(OSThread* thread) { + return (thread->state == OS_THREAD_STATE_MORIBUND || thread->state == 0) ? TRUE : FALSE; +} + +static BOOL __OSIsThreadActive(OSThread* thread) { + OSThread* active; + + if (thread->state == 0) { + return FALSE; + } + + for (active = __OSActiveThreadQueue.head; active; active = active->linkActive.next) { + if (thread == active) { + return TRUE; + } + } + return FALSE; +} + +s32 OSDisableScheduler(void) { + register BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule; + Reschedule = count + 1; + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSEnableScheduler(void) { + register BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule; + Reschedule = count - 1; + OSRestoreInterrupts(enabled); + return count; +} + +static void SetRun(OSThread* thread) { + ASSERTLINE(LINE(536, 554, 554), !IsSuspended(thread->suspend)); + ASSERTLINE(LINE(537, 555, 555), thread->state == OS_THREAD_STATE_READY); + + ASSERTLINE(LINE(539, 557, 557), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX); + + thread->queue = &RunQueue[thread->priority]; + + ENQUEUE_THREAD(thread, thread->queue, link); + + RunQueueBits |= 1 << (OS_PRIORITY_MAX - thread->priority); + RunQueueHint = 1; +} + +static void UnsetRun(OSThread* thread) { + OSThreadQueue* queue; + + ASSERTLINE(LINE(560, 578, 578), thread->state == OS_THREAD_STATE_READY); + + ASSERTLINE(LINE(562, 580, 580), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX); + ASSERTLINE(LINE(563, 581, 581), thread->queue == &RunQueue[thread->priority]); + + queue = thread->queue; + + DEQUEUE_THREAD(thread, queue, link); + + if (!queue->head) { + RunQueueBits &= ~(1 << (OS_PRIORITY_MAX - thread->priority)); + } + thread->queue = NULL; +} + +s32 __OSGetEffectivePriority(OSThread* thread) { + s32 priority = thread->base; + OSMutex* mutex; + + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { + OSThread* blocked = mutex->queue.head; + if (blocked && blocked->priority < priority) { + priority = blocked->priority; + } + } + return priority; +} + +static OSThread* SetEffectivePriority(OSThread* thread, s32 priority) { + ASSERTLINE(LINE(614, 632, 632), !IsSuspended(thread->suspend)); + + switch(thread->state) { + case OS_THREAD_STATE_READY: + UnsetRun(thread); + thread->priority = priority; + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + DEQUEUE_THREAD(thread, thread->queue, link); + thread->priority = priority; + + ENQUEUE_THREAD_PRIO(thread, thread->queue, link); + + if (thread->mutex) { + ASSERTLINE(LINE(629, 647, 647), thread->mutex->thread); + return thread->mutex->thread; + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = 1; + thread->priority = priority; + break; + } + return 0; +} + +static void UpdatePriority(OSThread* thread) { + s32 priority; + + while (1) { + if(thread->suspend > 0) { + break; + } + priority = __OSGetEffectivePriority(thread); + if (thread->priority == priority) { + break; + } + thread = SetEffectivePriority(thread, priority); + if (thread == 0) { + break; + } + } +} + +void __OSPromoteThread(OSThread* thread, s32 priority) { + while (1) { + if (thread->suspend > 0 || thread->priority <= priority) { + break; + } + thread = SetEffectivePriority(thread, priority); + if (thread == 0) { + break; + } + } +} + +static OSThread* SelectThread(int yield) { + OSContext* currentContext; + OSThread* currentThread; + OSThread* nextThread; + OSPriority priority; + OSThreadQueue* queue; + + if (Reschedule > 0) { + return NULL; + } + + currentContext = OSGetCurrentContext(); + currentThread = OSGetCurrentThread(); + + if (currentContext != ¤tThread->context) { + return NULL; + } + + if (currentThread) { + if (currentThread->state == 2) { + if (yield == 0) { + priority = __cntlzw(RunQueueBits); + if (currentThread->priority <= priority) + return NULL; + } + currentThread->state = OS_THREAD_STATE_READY; + SetRun(currentThread); + } + if (!(currentThread->context.state & 2) && (OSSaveContext(¤tThread->context) != 0)) { + return NULL; + } + } + + if (RunQueueBits == 0) { + OSSetCurrentThread(NULL); + OSSetCurrentContext(&IdleContext); + do { + OSEnableInterrupts(); + while (RunQueueBits == 0) ; + OSDisableInterrupts(); + } while (RunQueueBits == 0); + OSClearContext(&IdleContext); + } + + RunQueueHint = 0; + priority = __cntlzw(RunQueueBits); + + ASSERTLINE(LINE(777, 808, 808), OS_PRIORITY_MIN <= priority && priority <= OS_PRIORITY_MAX); + + queue = &RunQueue[priority]; + nextThread = queue->head; + + DEQUEUE_HEAD(nextThread, queue, link); + + ASSERTLINE(LINE(780, 811, 811), nextThread->priority == priority); + + if (!queue->head) { + RunQueueBits &= ~(1 << (OS_PRIORITY_MAX - priority)); + } + nextThread->queue = 0; + nextThread->state = OS_THREAD_STATE_RUNNING; + __OSSwitchThread(nextThread); + return nextThread; +} + +void __OSReschedule(void) { + if (RunQueueHint != 0) { + SelectThread(0); + } +} + +void OSYieldThread(void) { + BOOL enabled = OSDisableInterrupts(); + + SelectThread(1); + OSRestoreInterrupts(enabled); +} + +int OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, void* stack, u32 stackSize, OSPriority priority, u16 attr) { + BOOL enabled; + u32 sp; + int i; + + ASSERTMSGLINE(LINE(864, 895, 895), ((priority >= OS_PRIORITY_MIN) && (priority <= OS_PRIORITY_MAX)), "OSCreateThread(): priority out of range (0 <= priority <= 31)."); + + // why check this for an assert just to check it again right after? + if ((priority < OS_PRIORITY_MIN) || (priority > OS_PRIORITY_MAX)) { + return 0; + } + + thread->state = OS_THREAD_STATE_READY; + thread->attr = attr & 1U; + thread->base = priority; + thread->priority = priority; + thread->suspend = 1; + thread->val = (void*)-1; + thread->mutex = 0; + OSInitThreadQueue(&thread->queueJoin); +#ifdef DEBUG + OSInitMutexQueue(&thread->queueMutex); +#else + OSInitThreadQueue((void*)&thread->queueMutex); // why +#endif + sp = (u32)stack; + sp &= ~7; + sp -= 8; + ((u32*)sp)[0] = 0; + ((u32*)sp)[1] = 0; + OSInitContext(&thread->context, (u32)func, sp); + thread->context.lr = (u32)&OSExitThread; + thread->context.gpr[3] = (u32)param; + thread->stackBase = stack; + thread->stackEnd = (void*)((unsigned int)stack - stackSize); + *thread->stackEnd = OS_THREAD_STACK_MAGIC; + thread->error = 0; + for (i = 0; i < 2; i++) { + thread->specific[i] = NULL; + } + enabled = OSDisableInterrupts(); + + if (__OSErrorTable[16] != NULL) { + thread->context.srr1 |= 0x900; + thread->context.state |= 1; + thread->context.fpscr = (__OSFpscrEnableBits & 0xf8) | 4; + for (i = 0; i < 32; ++i) { + *(u64*)&thread->context.fpr[i] = (u64)0xffffffffffffffffLL; + *(u64*)&thread->context.psf[i] = (u64)0xffffffffffffffffLL; + } + } + + ASSERTMSG1LINE(LINE(918, 949, 949), __OSIsThreadActive(thread) == 0L, "OSCreateThread(): thread %p is still active.", thread); + + ENQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + + OSRestoreInterrupts(enabled); + return 1; +} + +void OSExitThread(void* val) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + + ASSERTMSGLINE(LINE(943, 974, 974), currentThread, + "OSExitThread(): current thread does not exist."); + ASSERTMSGLINE(LINE(945, 976, 976), currentThread->state == OS_THREAD_STATE_RUNNING, + "OSExitThread(): current thread is not running."); + ASSERTMSGLINE(LINE(947, 978, 978), __OSIsThreadActive(currentThread) != 0, + "OSExitThread(): current thread is not active."); + + OSClearContext(¤tThread->context); + if (currentThread->attr & 1) { + DEQUEUE_THREAD(currentThread, &__OSActiveThreadQueue, linkActive); + currentThread->state = 0; + } else { + currentThread->state = 8; + currentThread->val = val; + } + __OSUnlockAllMutex(currentThread); + OSWakeupThread(¤tThread->queueJoin); + RunQueueHint = 1; +#ifdef DEBUG + __OSReschedule(); +#else + if (RunQueueHint != 0) { + SelectThread(0); + } +#endif + OSRestoreInterrupts(enabled); +} + +void OSCancelThread(OSThread* thread) { + BOOL enabled = OSDisableInterrupts(); + + ASSERTMSG1LINE(LINE(985, 1016, 1016), __OSIsThreadActive(thread) != 0, + "OSExitThread(): thread %p is not active.", thread); + + switch(thread->state) { + case OS_THREAD_STATE_READY: + if (thread->suspend <= 0) { + UnsetRun(thread); + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = 1; + break; + case OS_THREAD_STATE_WAITING: + DEQUEUE_THREAD(thread, thread->queue, link); + thread->queue = 0; + if ((thread->suspend <= 0) && (thread->mutex)) { + ASSERTLINE(LINE(1004, 1035, 1035), thread->mutex->thread); + UpdatePriority(thread->mutex->thread); + } + break; + default: + OSRestoreInterrupts(enabled); + return; + } + OSClearContext(&thread->context); + if (thread->attr & 1) { + DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + thread->state = 0; + } else { + thread->state = 8; + } + __OSUnlockAllMutex(thread); + OSWakeupThread(&thread->queueJoin); + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +int OSJoinThread(OSThread* thread, void* val) { + BOOL enabled = OSDisableInterrupts(); + + ASSERTMSG1LINE(LINE(1061, 1092, 1092), __OSIsThreadActive(thread) != 0, "OSJoinThread(): thread %p is not active.", thread); + + if (!(thread->attr & 1) && (thread->state != OS_THREAD_STATE_MORIBUND) && (thread->queueJoin.head == NULL)) { + OSSleepThread(&thread->queueJoin); + if (__OSIsThreadActive(thread) == 0) { + OSRestoreInterrupts(enabled); + return 0; + } + } + if (thread->state == OS_THREAD_STATE_MORIBUND) { + if (val) { + *(s32*)val = (s32)thread->val; + } + DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + thread->state = 0; + OSRestoreInterrupts(enabled); + return 1; + } + OSRestoreInterrupts(enabled); + return 0; +} + +void OSDetachThread(OSThread* thread) { + BOOL enabled = OSDisableInterrupts(); + + ASSERTMSG1LINE(LINE(1111, 1142, 1142), __OSIsThreadActive(thread) != 0, "OSDetachThread(): thread %p is not active.", thread); + + thread->attr |= 1; + if (thread->state == OS_THREAD_STATE_MORIBUND) { + DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + thread->state = 0; + } + OSWakeupThread(&thread->queueJoin); + OSRestoreInterrupts(enabled); +} + +s32 OSResumeThread(OSThread* thread) { + BOOL enabled = OSDisableInterrupts(); + s32 suspendCount; + + ASSERTMSG1LINE(LINE(1140, 1171, 1171), __OSIsThreadActive(thread) != 0, "OSResumeThread(): thread %p is not active.", thread); + ASSERTMSG1LINE(LINE(1142, 1173, 1173), thread->state != OS_THREAD_STATE_MORIBUND, "OSResumeThread(): thread %p is terminated.", thread); + + suspendCount = thread->suspend--; + if (thread->suspend < 0) { + thread->suspend = 0; + } else if (thread->suspend == 0) { + switch(thread->state) { + case OS_THREAD_STATE_READY: + thread->priority = __OSGetEffectivePriority(thread); + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + ASSERTLINE(LINE(1157, 1188, 1188), thread->queue); + DEQUEUE_THREAD(thread, thread->queue, link); + thread->priority = __OSGetEffectivePriority(thread); + ENQUEUE_THREAD_PRIO(thread, thread->queue, link); + if (thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + } + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; +} + +s32 OSSuspendThread(OSThread* thread) { + BOOL enabled = OSDisableInterrupts(); + s32 suspendCount; + + ASSERTMSG1LINE(LINE(1191, 1222, 1222), __OSIsThreadActive(thread) != 0, "OSSuspendThread(): thread %p is not active.", thread); + ASSERTMSG1LINE(LINE(1193, 1224, 1224), thread->state != OS_THREAD_STATE_MORIBUND, "OSSuspendThread(): thread %p is terminated.", thread); + + suspendCount = thread->suspend++; + if (suspendCount == 0) { + switch(thread->state) { + case OS_THREAD_STATE_RUNNING: + RunQueueHint = 1; + thread->state = 1; + break; + case OS_THREAD_STATE_READY: + UnsetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + DEQUEUE_THREAD(thread, thread->queue, link); + thread->priority = 0x20; + ENQUEUE_THREAD(thread, thread->queue, link); + if (thread->mutex) { + ASSERTLINE(LINE(1214, 1245, 1245), thread->mutex->thread); + UpdatePriority(thread->mutex->thread); + } + break; + } + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; +} + +void OSSleepThread(OSThreadQueue* queue) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + + ASSERTMSGLINE(LINE(1247, 1278, 1278), currentThread, "OSSleepThread(): current thread does not exist."); + ASSERTMSG1LINE(LINE(1249, 1280, 1280), __OSIsThreadActive(currentThread) != 0, "OSSleepThread(): current thread %p is not active.", currentThread); + ASSERTMSG1LINE(LINE(1251, 1282, 1282), currentThread->state == OS_THREAD_STATE_RUNNING, "OSSleepThread(): current thread %p is not running.", currentThread); + ASSERTMSG1LINE(LINE(1253, 1284, 1284), currentThread->suspend <= 0, "OSSleepThread(): current thread %p is suspended.", currentThread); + + currentThread->state = OS_THREAD_STATE_WAITING; + currentThread->queue = queue; + ENQUEUE_THREAD_PRIO(currentThread, queue, link); + RunQueueHint = 1; + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +void OSWakeupThread(OSThreadQueue* queue) { + BOOL enabled = OSDisableInterrupts(); + + while (queue->head) { + OSThread* thread = queue->head; + + DEQUEUE_HEAD(thread, queue, link); + + ASSERTLINE(LINE(1282, 1313, 1313), __OSIsThreadActive(thread)); + ASSERTLINE(LINE(1283, 1314, 1314), thread->state != OS_THREAD_STATE_MORIBUND); + ASSERTLINE(LINE(1284, 1315, 1315), thread->queue == queue); + thread->state = OS_THREAD_STATE_READY; + if (thread->suspend <= 0) { + SetRun(thread); + } + } + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +int OSSetThreadPriority(OSThread* thread, s32 priority) { + BOOL enabled; + + ASSERTMSGLINE(LINE(1310, 1341, 1341), (priority >= OS_PRIORITY_MIN) && (priority <= OS_PRIORITY_MAX), "OSSetThreadPriority(): priority out of range (0 <= priority <= 31)."); + + if ((priority < OS_PRIORITY_MIN) || (priority > OS_PRIORITY_MAX)) { + return 0; + } + enabled = OSDisableInterrupts(); + + ASSERTMSG1LINE(LINE(1317, 1348, 1348), __OSIsThreadActive(thread) != 0, "OSSetThreadPriority(): thread %p is not active.", thread); + ASSERTMSG1LINE(LINE(1319, 1350, 1350), thread->state != 8, "OSSetThreadPriority(): thread %p is terminated.", thread); + + if (thread->base != priority) { + thread->base = priority; + UpdatePriority(thread); + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return 1; +} + +s32 OSGetThreadPriority(OSThread* thread) { + return thread->base; +} + +OSThread* OSSetIdleFunction(OSIdleFunction idleFunction, void* param, void* stack, u32 stackSize) { + if (idleFunction) { + if (IdleThread.state == 0) { + OSCreateThread(&IdleThread, (void*)idleFunction, param, stack, stackSize, OS_PRIORITY_MAX, 1); + OSResumeThread(&IdleThread); + return &IdleThread; + } + } else if (IdleThread.state != 0) { + OSCancelThread(&IdleThread); + } + return NULL; +} + +OSThread* OSGetIdleFunction(void) { + if (IdleThread.state != 0) { + return &IdleThread; + } + return NULL; +} + +static int CheckThreadQueue(OSThreadQueue* queue) { + OSThread* thread; + + if ((queue->head != NULL) && (queue->head->link.prev != NULL)) { + return 0; + } + if ((queue->tail != NULL) && (queue->tail->link.next != NULL)) { + return 0; + } + thread = queue->head; + while (thread) { + if ((thread->link.next != NULL) && (thread != thread->link.next->link.prev)) { + return 0; + } + if ((thread->link.prev != NULL) && (thread != thread->link.prev->link.next)) { + return 0; + } + thread = thread->link.next; + } + return 1; +} + +static BOOL IsMember(OSThreadQueue* queue, OSThread* thread) { + OSThread* member = queue->head; + + while (member) { + if (thread == member) { + return TRUE; + } + member = member->link.next; + } + return FALSE; +} + +// custom macro for OSCheckActiveThreads? +#define ASSERTREPORT(line, cond) \ + if (!(cond)) { \ + OSReport("OSCheckActiveThreads: Failed " #cond " in %d\n", line); \ + OSPanic(__FILE__, line, ""); \ + } + +s32 OSCheckActiveThreads(void) { + OSThread* thread; + s32 prio; + s32 cThread; + BOOL enabled; + + cThread = 0; + enabled = OSDisableInterrupts(); + + for (prio = 0; prio <= OS_PRIORITY_MAX; prio++) { + if (RunQueueBits & (1 << (OS_PRIORITY_MAX - prio))) { + ASSERTREPORT(LINE(1473, 1504, 1504), RunQueue[prio].head != NULL && RunQueue[prio].tail != NULL); + } else { + ASSERTREPORT(LINE(1478, 1509, 1509), RunQueue[prio].head == NULL && RunQueue[prio].tail == NULL); + } + ASSERTREPORT(LINE(1480, 1511, 1511), CheckThreadQueue(&RunQueue[prio])); + } + + ASSERTREPORT(LINE(1485, 1516, 1516), __OSActiveThreadQueue.head == NULL || __OSActiveThreadQueue.head->linkActive.prev == NULL); + ASSERTREPORT(LINE(1487, 1518, 1518), __OSActiveThreadQueue.tail == NULL || __OSActiveThreadQueue.tail->linkActive.next == NULL); + + thread = __OSActiveThreadQueue.head; + while (thread) { + cThread++; + ASSERTREPORT(LINE(1495, 1526, 1526), thread->linkActive.next == NULL || thread == thread->linkActive.next->linkActive.prev); + ASSERTREPORT(LINE(1497, 1528, 1528), thread->linkActive.prev == NULL || thread == thread->linkActive.prev->linkActive.next); + ASSERTREPORT(LINE(1500, 1531, 1531), *(thread->stackEnd) == OS_THREAD_STACK_MAGIC); + ASSERTREPORT(LINE(1503, 1534, 1534), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX+1); + ASSERTREPORT(LINE(1504, 1535, 1535), 0 <= thread->suspend); + ASSERTREPORT(LINE(1505, 1536, 1536), CheckThreadQueue(&thread->queueJoin)); + + switch(thread->state) { + case OS_THREAD_STATE_READY: + if (thread->suspend <= 0) { + ASSERTREPORT(LINE(1511, 1542, 1542), thread->queue == &RunQueue[thread->priority]); + ASSERTREPORT(LINE(1512, 1543, 1543), IsMember(&RunQueue[thread->priority], thread)); + ASSERTREPORT(LINE(1513, 1544, 1544), thread->priority == __OSGetEffectivePriority(thread)); + } + break; + case OS_THREAD_STATE_RUNNING: + ASSERTREPORT(LINE(1517, 1548, 1548), !IsSuspended(thread->suspend)); + ASSERTREPORT(LINE(1518, 1549, 1549), thread->queue == NULL); + ASSERTREPORT(LINE(1519, 1550, 1550), thread->priority == __OSGetEffectivePriority(thread)); + break; + case OS_THREAD_STATE_WAITING: + ASSERTREPORT(LINE(1522, 1553, 1553), thread->queue != NULL); + ASSERTREPORT(LINE(1523, 1554, 1554), CheckThreadQueue(thread->queue)); + ASSERTREPORT(LINE(1524, 1555, 1555), IsMember(thread->queue, thread)); + if (thread->suspend <= 0) { + ASSERTREPORT(LINE(1527, 1558, 1558), thread->priority == __OSGetEffectivePriority(thread)); + } else { + ASSERTREPORT(LINE(1531, 1562, 1562), thread->priority == 32); + } + ASSERTREPORT(LINE(1533, 1564, 1564), !__OSCheckDeadLock(thread)); + break; + case OS_THREAD_STATE_MORIBUND: + ASSERTREPORT(LINE(1537, 1568, 1568), thread->queueMutex.head == NULL && thread->queueMutex.tail == NULL); + break; + default: + OSReport("OSCheckActiveThreads: Failed. unkown thread state (%d) of thread %p\n", thread->state, thread); + OSPanic(__FILE__, LINE(1543, 1574, 1574), ""); + } + ASSERTREPORT(LINE(1548, 1579, 1579), __OSCheckMutexes(thread)); + thread = thread->linkActive.next; + } + OSRestoreInterrupts(enabled); + return cThread; +} + +void OSClearStack(u8 val) { + register u32 sp; + register u32* p; + register u32 pattern; + + pattern = (val << 24) | (val << 16) | (val << 8) | val; + sp = OSGetStackPointer(); + for (p = __OSCurrentThread->stackEnd + 1; (u32)p < sp; ++p) { + *p = pattern; + } +} + +void OSSetThreadSpecific(s32 index, void* ptr) { + OSThread* thread; + + thread = __OSCurrentThread; + ASSERTLINE(LINE(1573, 1604, 1604), 0 <= index && index < OS_THREAD_SPECIFIC_MAX); + + if (thread != 0 && index >= 0 && index < OS_THREAD_SPECIFIC_MAX) { + thread->specific[index] = ptr; + } +} + +void* OSGetThreadSpecific(s32 index) { + OSThread* thread; + + thread = __OSCurrentThread; + ASSERTLINE(LINE(1584, 1615, 1615), 0 <= index && index < OS_THREAD_SPECIFIC_MAX); + + if (thread != 0 && index >= 0 && index < OS_THREAD_SPECIFIC_MAX) { + return thread->specific[index]; + } + + return NULL; +} diff --git a/src/dolphin/os/OSTime.c b/src/dolphin/os/OSTime.c new file mode 100644 index 0000000..5813615 --- /dev/null +++ b/src/dolphin/os/OSTime.c @@ -0,0 +1,200 @@ +#include +#include + +#include "__os.h" + +// End of each month in standard year +static int YearDays[MONTH_MAX] = {0, 31, 59, 90, 120, 151, + 181, 212, 243, 273, 304, 334}; +// End of each month in leap year +static int LeapYearDays[MONTH_MAX] = {0, 31, 60, 91, 121, 152, + 182, 213, 244, 274, 305, 335}; + +#ifdef __GEKKO__ +asm OSTime OSGetTime(void) { +jump: + nofralloc + + mftbu r3 + mftb r4 + + // Check for possible carry from TBL to TBU + mftbu r5 + cmpw r3, r5 + bne jump + + blr +} + +asm OSTick OSGetTick(void){ + nofralloc + + mftb r3 + blr +} + +asm static void __SetTime(OSTime time) { + nofralloc + li r5, 0 + mttbl r5 + mttbu r3 + mttbl r4 + blr +} +#endif + +void __OSSetTime(OSTime time) { + BOOL enabled; + OSTime * timeAdjustAddr; + + timeAdjustAddr = __OSSystemTime; + enabled = OSDisableInterrupts(); + + *timeAdjustAddr += OSGetTime() - time; + __SetTime(time); + EXIProbeReset(); + OSRestoreInterrupts(enabled); +} + +OSTime __OSGetSystemTime() { + BOOL enabled; + OSTime* timeAdjustAddr; + OSTime result; + + timeAdjustAddr = __OSSystemTime; + enabled = OSDisableInterrupts(); + + result = OSGetTime() + *timeAdjustAddr; + OSRestoreInterrupts(enabled); + return result; +} + +OSTime __OSTimeToSystemTime(OSTime time) { + BOOL enabled; + OSTime* timeAdjustAddr = __OSSystemTime; + OSTime result; + + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + time; + OSRestoreInterrupts(enabled); + return result; +} + +#ifdef __GEKKO__ +asm void __OSSetTick(register OSTick newTicks) { + nofralloc + mttbl newTicks + blr +} +#endif + +static int IsLeapYear(int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} + +static int GetYearDays(int year, int mon) { + int* md = (IsLeapYear(year)) ? LeapYearDays : YearDays; + + return md[mon]; +} + +static int GetLeapDays(int year) { + ASSERTLINE(286, 0 <= year); + + if (year < 1) { + return 0; + } + return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; +} + +static void GetDates(int days, OSCalendarTime* td) { + int year; + int n; + int month; + int * md; + + ASSERTLINE(311, 0 <= days); + + td->wday = (days + 6) % WEEK_DAY_MAX; + + for (year = days / YEAR_DAY_MAX; + days < (n = year * YEAR_DAY_MAX + GetLeapDays(year)); year--) { + ; + } + + days -= n; + td->year = year; + td->yday = days; + + md = IsLeapYear(year) ? LeapYearDays : YearDays; + for (month = MONTH_MAX; days < md[--month];) { + ; + } + td->mon = month; + td->mday = days - md[month] + 1; +} + +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) { + int days; + int secs; + OSTime d; + + d = ticks % OS_SEC_TO_TICKS(1); + if (d < 0) { + d += OS_SEC_TO_TICKS(1); + ASSERTLINE(356, 0 <= d); + } + + td->usec = OS_TICKS_TO_USEC(d) % USEC_MAX; + td->msec = OS_TICKS_TO_MSEC(d) % MSEC_MAX; + + ASSERTLINE(360, 0 <= td->usec); + ASSERTLINE(361, 0 <= td->msec); + + ticks -= d; + + ASSERTLINE(364, ticks % OSSecondsToTicks(1) == 0); + ASSERTLINE(368, 0 <= OSTicksToSeconds(ticks) / 86400 + BIAS && OSTicksToSeconds(ticks) / 86400 + BIAS <= INT_MAX); + + days = (OS_TICKS_TO_SEC(ticks) / SECS_IN_DAY) + BIAS; + secs = OS_TICKS_TO_SEC(ticks) % SECS_IN_DAY; + if (secs < 0) { + days -= 1; + secs += SECS_IN_DAY; + ASSERTLINE(375, 0 <= secs); + } + + GetDates(days, td); + td->hour = secs / 60 / 60; + td->min = secs / 60 % 60; + td->sec = secs % 60; +} + +OSTime OSCalendarTimeToTicks(OSCalendarTime* td) { + OSTime secs; + int ov_mon; + int mon; + int year; + + ov_mon = td->mon / MONTH_MAX; + mon = td->mon - (ov_mon * MONTH_MAX); + + if (mon < 0) { + mon += MONTH_MAX; + ov_mon--; + } + + ASSERTLINE(412, (ov_mon <= 0 && 0 <= td->year + ov_mon) || (0 < ov_mon && td->year <= INT_MAX - ov_mon)); + + year = td->year + ov_mon; + + secs = (OSTime)SECS_IN_YEAR * year + + (OSTime)SECS_IN_DAY * (GetLeapDays(year) + GetYearDays(year, mon) + td->mday - 1) + + (OSTime)SECS_IN_HOUR * td->hour + + (OSTime)SECS_IN_MIN * td->min + + td->sec - + (OSTime)0xEB1E1BF80ULL; + + return OS_SEC_TO_TICKS(secs) + OS_MSEC_TO_TICKS((OSTime)td->msec) + + OS_USEC_TO_TICKS((OSTime)td->usec); +} diff --git a/src/dolphin/os/OSTimer.c b/src/dolphin/os/OSTimer.c new file mode 100644 index 0000000..99c13a6 --- /dev/null +++ b/src/dolphin/os/OSTimer.c @@ -0,0 +1,140 @@ +#include +#include + +#include "__os.h" + +struct Timer { + OSTimerCallback callback; + u32 currval; + u32 startval; + u32 mode; + BOOL stopped; + BOOL initialized; +}; +static struct Timer Timer; + +// prototypes +static void DecrementerExceptionHandler(__OSException exception, OSContext* context); + +OSTimerCallback OSSetTimerCallback(OSTimerCallback callback) { + OSTimerCallback prevCallback; + +#if DEBUG + if(!Timer.initialized) { + OSPanic(__FILE__, 135, "OSSetTimerCallback(): timer is not initialized."); + } +#endif + + Timer.stopped = TRUE; + prevCallback = Timer.callback; + Timer.callback = callback; + return prevCallback; +} + +void OSInitTimer(u32 time, u32 mode) { +#if DEBUG + if (time >= 0x80000000) { + OSPanic(__FILE__, 159, "OSInitTimer(): time param must be less than 0x80000000."); + } +#endif + + Timer.stopped = TRUE; + Timer.currval = time; + Timer.startval = time; + Timer.mode = mode; + + if (!Timer.initialized) { + __OSSetExceptionHandler(8, &DecrementerExceptionHandler); + Timer.initialized = TRUE; + Timer.callback = 0; +#if DEBUG + OSReport("Timer initialized\n"); +#endif + } +} + +void OSStartTimer(void) { + BOOL enabled; + +#if DEBUG + if (!Timer.initialized) { + OSPanic(__FILE__, 192, "OSStartTimer(): timer is not initialized."); + } +#endif + enabled = OSDisableInterrupts(); + PPCMtdec(Timer.currval); + Timer.stopped = FALSE; + OSRestoreInterrupts(enabled); +} + +void OSStopTimer(void) { + BOOL enabled; + +#if DEBUG + if (!Timer.initialized) { + OSPanic(__FILE__, 216, "OSStopTimer(): timer is not initialized."); + } +#endif + + enabled = OSDisableInterrupts(); + if (!Timer.stopped) { + Timer.stopped = TRUE; + Timer.currval = PPCMfdec(); + if (Timer.currval & 0x80000000) { + Timer.currval = 0; + } + } + OSRestoreInterrupts(enabled); +} + +static void DecrementerExceptionCallback(__OSException exception, OSContext* context) { + OSContext exceptionContext; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (!Timer.stopped) { + if (Timer.mode == 1) { + PPCMtdec(Timer.startval); + } + if (Timer.mode == 2) { + Timer.stopped = TRUE; + } + if (Timer.callback) { + Timer.callback(); + } + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + OSLoadContext(context); +} + +#ifdef __GEKKO__ +static asm void DecrementerExceptionHandler(__OSException exception, + register OSContext* context) { + nofralloc + + stw r0, context->gpr[0] + stw r1, context->gpr[1] + stw r2, context->gpr[2] + stmw r6, context->gpr[6] + + mfspr r0, GQR1 + stw r0, context->gqr[1] + mfspr r0, GQR2 + stw r0, context->gqr[2] + mfspr r0, GQR3 + stw r0, context->gqr[3] + mfspr r0, GQR4 + stw r0, context->gqr[4] + mfspr r0, GQR5 + stw r0, context->gqr[5] + mfspr r0, GQR6 + stw r0, context->gqr[6] + mfspr r0, GQR7 + stw r0, context->gqr[7] + + stwu r1, -0x8(r1) + b DecrementerExceptionCallback +} +#endif diff --git a/src/dolphin/os/OSUtf.c b/src/dolphin/os/OSUtf.c new file mode 100644 index 0000000..ddfa23d --- /dev/null +++ b/src/dolphin/os/OSUtf.c @@ -0,0 +1,6341 @@ +#include +#include + +char* OSUTF8to32(const char* utf8, u32* utf32) { + u32 u; + u8 c; + unsigned int len; + unsigned int i; + + c = *utf8; + if (c != 0) { + utf8++; + } + + if ((c & 0x80) == 0) { + u = c; + len = 0; + } else if ((c & 0xE0) == 0xC0u) { + u = c & 0x1F; + len = 1; + } else if ((c & 0xF0) == 0xE0u) { + u = c & 0xF; + len = 2; + } else if ((c & 0xF8) == 0xF0u) { + u = c & 0x7; + len = 3; + } else { + return NULL; + } + + for (i = 0; i < len; i++) { + u = u << 6; + c = *utf8++; + if ((c & 0xC0) != 0x80u) { + return NULL; + } + + u |= (c & 0x3F); + } + + if (u <= 0x7Fu) { + if (len != 0) { + return NULL; + } + } else if (u <= 0x7FFu) { + if (len != 1) { + return NULL; + } + } else if (u <= 0xFFFFu) { + if (len != 2) { + return NULL; + } + } + + if (u >= 0xD800u && u <= 0xDFFFu) { + return NULL; + } + + *utf32 = u; + return (char*)utf8; +} + +char* OSUTF32to8(u32 utf32, char* utf8) { + int len; + + if (utf32 >= 0xD800u && utf32 <= 0xDFFFu) { + return NULL; + } + + if (utf32 < 0x80u) { + *utf8 = (s8)utf32; + utf8++; + } else if (utf32 < 0x800u) { + *utf8 = (utf32 >> 6) | 0xC0; + utf8++; + len = 1; + } else if (utf32 < 0x10000u) { + *utf8 = (utf32 >> 0xC) | 0xE0; + utf8++; + len = 2; + } else if (utf32 < 0x110000u) { + *utf8 = (utf32 >> 0x12) | 0xF0; + utf8++; + len = 3; + } else { + return NULL; + } + + while (len-- > 0) { + *utf8 = ((utf32 >> (len * 6)) & 0x3F) | 0x80; + utf8++; + } + + return utf8; +} + +u16* OSUTF16to32(const u16* utf16, u32* utf32) { + u16 w1; + u16 w2; + u32 u; + + w1 = *utf16; + if (w1 != 0) { + utf16++; + } + + if (w1 < 0xD800 || w1 > 0xDFFF) { + u = w1; + } else if (w1 <= 0xDBFF) { + w2 = *utf16; + utf16++; + + if (w2 >= 0xDC00 && w2 <= 0xDFFF) { + u = ((w1 << 10) & 0xFFC00) | ((w2 & 0x3FF) & ~0xFFC00); + u = u + 0x10000; + } else { + return NULL; + } + } else { + return NULL; + } + + *utf32 = u; + return (u16*)utf16; +} + +u16* OSUTF32to16(u32 utf32, u16* utf16) { + u16 w1; + u16 w2; + + if (utf32 >= 0xD800u && utf32 <= 0xDFFFu) { + return NULL; + } + + if (utf32 < 0x10000u) { + *utf16 = utf32; + utf16++; + } else if (utf32 <= 0x10FFFFu) { + w1 = -0x122800; + w2 = -0x122400; + utf32 -= 0x10000; + ASSERTLINE(0xD1, utf32 <= 0xFFFFF); + + w1 |= utf32 >> 10; + w2 |= utf32 & 0x3FF; + + *utf16++ = w1; + *utf16++ = w2; + } else { + return NULL; + } + + return utf16; +} + +static u16 UcsAnsiTable[32] = { + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, + 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, + 0x0152, 0x0000, 0x017D, 0x0000, 0x0000, 0x2018, + 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, + 0x017E, 0x0178, +}; + +u8 OSUTF32toANSI(u32 utf32) { + int i; + + if (utf32 > 0xFF) { + return 0; + } + + if (utf32 < 0x80 || utf32 > 0x9F) { + return utf32; + } + + if (utf32 >= 0x152 && utf32 <= 0x2122) { + for (i = 0; i <= 31; i++) { + if (utf32 == UcsAnsiTable[i]) { + return i + 0x80; + } + } + } + + return 0; +} + +u32 OSANSItoUTF32(u8 ansi) { + if (ansi >= 0x80 && ansi <= 0x9F) { + return UcsAnsiTable[ansi - 0x80]; + } + + return ansi; +} + +static u16 Ucs00[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, + 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, + 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005A, 0x005B, 0x815F, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, + 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8191, 0x8192, 0x0000, 0x005C, 0x0000, 0x8198, + 0x814E, 0x0000, 0x0000, 0x0000, 0x81CA, 0x0000, + 0x0000, 0x0000, 0x818B, 0x817D, 0x0000, 0x0000, + 0x814C, 0x0000, 0x81F7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x817E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8180, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs03[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x839F, 0x83A0, 0x83A1, 0x83A2, 0x83A3, + 0x83A4, 0x83A5, 0x83A6, 0x83A7, 0x83A8, 0x83A9, + 0x83AA, 0x83AB, 0x83AC, 0x83AD, 0x83AE, 0x83AF, + 0x0000, 0x83B0, 0x83B1, 0x83B2, 0x83B3, 0x83B4, + 0x83B5, 0x83B6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x83BF, 0x83C0, 0x83C1, + 0x83C2, 0x83C3, 0x83C4, 0x83C5, 0x83C6, 0x83C7, + 0x83C8, 0x83C9, 0x83CA, 0x83CB, 0x83CC, 0x83CD, + 0x83CE, 0x83CF, 0x0000, 0x83D0, 0x83D1, 0x83D2, + 0x83D3, 0x83D4, 0x83D5, 0x83D6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs04[256] = { + 0x0000, 0x8446, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8440, 0x8441, + 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, + 0x8449, 0x844A, 0x844B, 0x844C, 0x844D, 0x844E, + 0x844F, 0x8450, 0x8451, 0x8452, 0x8453, 0x8454, + 0x8455, 0x8456, 0x8457, 0x8458, 0x8459, 0x845A, + 0x845B, 0x845C, 0x845D, 0x845E, 0x845F, 0x8460, + 0x8470, 0x8471, 0x8472, 0x8473, 0x8474, 0x8475, + 0x8477, 0x8478, 0x8479, 0x847A, 0x847B, 0x847C, + 0x847D, 0x847E, 0x8480, 0x8481, 0x8482, 0x8483, + 0x8484, 0x8485, 0x8486, 0x8487, 0x8488, 0x8489, + 0x848A, 0x848B, 0x848C, 0x848D, 0x848E, 0x848F, + 0x8490, 0x8491, 0x0000, 0x8476, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs20[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x815D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x815C, 0x8161, 0x0000, + 0x8165, 0x8166, 0x0000, 0x0000, 0x8167, 0x8168, + 0x0000, 0x0000, 0x81F5, 0x81F6, 0x0000, 0x0000, + 0x0000, 0x8164, 0x8163, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x81F1, 0x0000, 0x818C, 0x818D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x81A6, + 0x0000, 0x0000, 0x007E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs21[256] = { + 0x0000, 0x0000, 0x0000, 0x818E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x81F0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x81A9, 0x81AA, 0x81A8, 0x81AB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x81CB, 0x0000, 0x81CC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs22[256] = { + 0x81CD, 0x0000, 0x81DD, 0x81CE, 0x0000, 0x0000, + 0x0000, 0x81DE, 0x81B8, 0x0000, 0x0000, 0x81B9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x817C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x81E3, 0x0000, 0x0000, 0x81E5, + 0x8187, 0x0000, 0x81DA, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x81C8, 0x81C9, 0x81BF, + 0x81BE, 0x81E7, 0x81E8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8188, 0x81E6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x81E4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81E0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8182, 0x81DF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8185, 0x8186, 0x0000, 0x0000, 0x81E1, 0x81E2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81BC, 0x81BD, + 0x0000, 0x0000, 0x81BA, 0x81BB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x81DB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs23[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x81DC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs25[256] = { + 0x849F, 0x84AA, 0x84A0, 0x84AB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x84A1, 0x0000, 0x0000, 0x84AC, 0x84A2, 0x0000, + 0x0000, 0x84AD, 0x84A4, 0x0000, 0x0000, 0x84AF, + 0x84A3, 0x0000, 0x0000, 0x84AE, 0x84A5, 0x84BA, + 0x0000, 0x0000, 0x84B5, 0x0000, 0x0000, 0x84B0, + 0x84A7, 0x84BC, 0x0000, 0x0000, 0x84B7, 0x0000, + 0x0000, 0x84B2, 0x84A6, 0x0000, 0x0000, 0x84B6, + 0x84BB, 0x0000, 0x0000, 0x84B1, 0x84A8, 0x0000, + 0x0000, 0x84B8, 0x84BD, 0x0000, 0x0000, 0x84B3, + 0x84A9, 0x0000, 0x0000, 0x84B9, 0x0000, 0x0000, + 0x84BE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x84B4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81A1, 0x81A0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81A3, 0x81A2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x81A5, 0x81A4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x819F, 0x819E, 0x0000, 0x0000, 0x0000, 0x819B, + 0x0000, 0x0000, 0x819D, 0x819C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x81FC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs26[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x819A, + 0x8199, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x818A, 0x0000, + 0x8189, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81F4, 0x0000, + 0x0000, 0x81F3, 0x0000, 0x81F2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs30[256] = { + 0x8140, 0x8141, 0x8142, 0x8156, 0x0000, 0x8158, + 0x8159, 0x815A, 0x8171, 0x8172, 0x8173, 0x8174, + 0x8175, 0x8176, 0x8177, 0x8178, 0x8179, 0x817A, + 0x81A7, 0x81AC, 0x816B, 0x816C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8160, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x829F, + 0x82A0, 0x82A1, 0x82A2, 0x82A3, 0x82A4, 0x82A5, + 0x82A6, 0x82A7, 0x82A8, 0x82A9, 0x82AA, 0x82AB, + 0x82AC, 0x82AD, 0x82AE, 0x82AF, 0x82B0, 0x82B1, + 0x82B2, 0x82B3, 0x82B4, 0x82B5, 0x82B6, 0x82B7, + 0x82B8, 0x82B9, 0x82BA, 0x82BB, 0x82BC, 0x82BD, + 0x82BE, 0x82BF, 0x82C0, 0x82C1, 0x82C2, 0x82C3, + 0x82C4, 0x82C5, 0x82C6, 0x82C7, 0x82C8, 0x82C9, + 0x82CA, 0x82CB, 0x82CC, 0x82CD, 0x82CE, 0x82CF, + 0x82D0, 0x82D1, 0x82D2, 0x82D3, 0x82D4, 0x82D5, + 0x82D6, 0x82D7, 0x82D8, 0x82D9, 0x82DA, 0x82DB, + 0x82DC, 0x82DD, 0x82DE, 0x82DF, 0x82E0, 0x82E1, + 0x82E2, 0x82E3, 0x82E4, 0x82E5, 0x82E6, 0x82E7, + 0x82E8, 0x82E9, 0x82EA, 0x82EB, 0x82EC, 0x82ED, + 0x82EE, 0x82EF, 0x82F0, 0x82F1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x814A, + 0x814B, 0x8154, 0x8155, 0x0000, 0x0000, 0x8340, + 0x8341, 0x8342, 0x8343, 0x8344, 0x8345, 0x8346, + 0x8347, 0x8348, 0x8349, 0x834A, 0x834B, 0x834C, + 0x834D, 0x834E, 0x834F, 0x8350, 0x8351, 0x8352, + 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0x8358, + 0x8359, 0x835A, 0x835B, 0x835C, 0x835D, 0x835E, + 0x835F, 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, + 0x8365, 0x8366, 0x8367, 0x8368, 0x8369, 0x836A, + 0x836B, 0x836C, 0x836D, 0x836E, 0x836F, 0x8370, + 0x8371, 0x8372, 0x8373, 0x8374, 0x8375, 0x8376, + 0x8377, 0x8378, 0x8379, 0x837A, 0x837B, 0x837C, + 0x837D, 0x837E, 0x8380, 0x8381, 0x8382, 0x8383, + 0x8384, 0x8385, 0x8386, 0x8387, 0x8388, 0x8389, + 0x838A, 0x838B, 0x838C, 0x838D, 0x838E, 0x838F, + 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, 0x8395, + 0x8396, 0x0000, 0x0000, 0x0000, 0x0000, 0x8145, + 0x815B, 0x8152, 0x8153, 0x0000 +}; + +static u16 Ucs4E[256] = { + 0x88EA, 0x929A, 0x0000, 0x8EB5, 0x0000, 0x0000, + 0x0000, 0x969C, 0x8FE4, 0x8E4F, 0x8FE3, 0x89BA, + 0x0000, 0x9573, 0x975E, 0x0000, 0x98A0, 0x894E, + 0x0000, 0x0000, 0x8A8E, 0x98A1, 0x90A2, 0x99C0, + 0x8B75, 0x95B8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8FE5, 0x0000, 0x0000, 0x97BC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95C0, 0x0000, 0x0000, 0x0000, + 0x98A2, 0x0000, 0x0000, 0x9286, 0x0000, 0x0000, + 0x0000, 0x98A3, 0x8BF8, 0x0000, 0x0000, 0x0000, + 0x98A4, 0x0000, 0x8ADB, 0x924F, 0x0000, 0x8EE5, + 0x98A5, 0x0000, 0x0000, 0x98A6, 0x0000, 0x0000, + 0x98A7, 0x9454, 0x0000, 0x8B76, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9456, 0x0000, 0x93E1, + 0x8CC1, 0x9652, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE568, 0x98A8, 0x8FE6, 0x98A9, 0x89B3, + 0x0000, 0x0000, 0x0000, 0x8BE3, 0x8CEE, 0x96E7, + 0x0000, 0x0000, 0x9BA4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9790, + 0x0000, 0x93FB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AA3, 0x0000, 0x8B54, 0x0000, 0x98AA, 0x0000, + 0x0000, 0x98AB, 0x97B9, 0x0000, 0x975C, 0x9188, + 0x98AD, 0x8E96, 0x93F1, 0x0000, 0x98B0, 0x0000, + 0x0000, 0x895D, 0x8CDD, 0x0000, 0x8CDC, 0x88E4, + 0x0000, 0x0000, 0x986A, 0x9869, 0x0000, 0x8DB1, + 0x889F, 0x0000, 0x98B1, 0x98B2, 0x98B3, 0x9653, + 0x98B4, 0x0000, 0x8CF0, 0x88E5, 0x9692, 0x0000, + 0x8B9C, 0x0000, 0x0000, 0x8B9D, 0x8B9E, 0x92E0, + 0x97BA, 0x0000, 0x98B5, 0x0000, 0x0000, 0x98B6, + 0x0000, 0x0000, 0x98B7, 0x0000, 0x0000, 0x0000, + 0x906C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F59, 0x906D, 0x98BC, 0x0000, 0x98BA, 0x0000, + 0x98BB, 0x8B77, 0x0000, 0x0000, 0x8DA1, 0x89EE, + 0x0000, 0x98B9, 0x98B8, 0x95A7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E65, 0x8E64, 0x91BC, 0x98BD, + 0x9574, 0x90E5, 0x0000, 0x0000, 0x0000, 0x8157, + 0x98BE, 0x98C0, 0x0000, 0x0000, 0x0000, 0x91E3, + 0x97DF, 0x88C8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98BF, 0x89BC, 0x0000, + 0x8BC2, 0x0000, 0x9287, 0x0000, 0x0000, 0x0000, + 0x8C8F, 0x98C1, 0x0000, 0x0000, 0x0000, 0x9443, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs4F[256] = { + 0x0000, 0x8AE9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98C2, 0x88C9, 0x0000, + 0x0000, 0x8CDE, 0x8AEA, 0x959A, 0x94B0, 0x8B78, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x89EF, 0x0000, 0x98E5, 0x9360, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x948C, + 0x98C4, 0x0000, 0x0000, 0x0000, 0x94BA, 0x0000, + 0x97E0, 0x0000, 0x904C, 0x0000, 0x8E66, 0x0000, + 0x8E97, 0x89BE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92CF, 0x0000, 0x0000, 0x9241, 0x98C8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x88CA, + 0x92E1, 0x8F5A, 0x8DB2, 0x9743, 0x0000, 0x91CC, + 0x0000, 0x89BD, 0x0000, 0x98C7, 0x0000, 0x975D, + 0x98C3, 0x98C5, 0x8DEC, 0x98C6, 0x9B43, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98CE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98D1, 0x98CF, 0x0000, + 0x0000, 0x89C0, 0x0000, 0x95B9, 0x98C9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98CD, 0x8CF1, 0x0000, + 0x0000, 0x8E67, 0x0000, 0x0000, 0x0000, 0x8AA4, + 0x0000, 0x0000, 0x98D2, 0x0000, 0x98CA, 0x0000, + 0x0000, 0x97E1, 0x0000, 0x8E98, 0x0000, 0x98CB, + 0x0000, 0x98D0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x98D3, 0x0000, 0x98CC, 0x0000, 0x0000, 0x8B9F, + 0x0000, 0x88CB, 0x0000, 0x0000, 0x8BA0, 0x89BF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9B44, 0x0000, 0x9699, + 0x958E, 0x8CF2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x904E, 0x97B5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95D6, + 0x0000, 0x0000, 0x8C57, 0x91A3, 0x89E2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8F72, 0x0000, + 0x0000, 0x0000, 0x98D7, 0x0000, 0x98DC, 0x98DA, + 0x0000, 0x0000, 0x98D5, 0x0000, 0x0000, 0x91AD, + 0x98D8, 0x0000, 0x98DB, 0x98D9, 0x0000, 0x95DB, + 0x0000, 0x98D6, 0x0000, 0x904D, 0x0000, 0x9693, + 0x98DD, 0x98DE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8F43, 0x98EB, + 0x0000, 0x0000, 0x0000, 0x946F, 0x0000, 0x9555, + 0x98E6, 0x0000, 0x95EE, 0x0000, 0x89B4, 0x0000, + 0x0000, 0x0000, 0x98EA, 0x0000 +}; + +static u16 Ucs50[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x98E4, + 0x98ED, 0x0000, 0x0000, 0x9171, 0x0000, 0x8CC2, + 0x0000, 0x947B, 0x0000, 0xE0C5, 0x0000, 0x98EC, + 0x937C, 0x0000, 0x98E1, 0x0000, 0x8CF4, 0x0000, + 0x0000, 0x8CF3, 0x98DF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8ED8, 0x0000, 0x98E7, 0x0000, 0x95ED, + 0x926C, 0x98E3, 0x8C91, 0x0000, 0x98E0, 0x98E8, + 0x98E2, 0x97CF, 0x98E9, 0x9860, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8BE4, 0x0000, 0x0000, 0x8C90, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x98EE, 0x0000, 0x0000, 0x0000, 0x98EF, + 0x98F3, 0x88CC, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95CE, 0x98F2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x98F1, 0x98F5, 0x0000, 0x0000, 0x0000, + 0x98F4, 0x0000, 0x92E2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C92, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x98F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8EC3, 0x0000, 0x91A4, 0x92E3, 0x8BF4, 0x0000, + 0x98F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B55, + 0x0000, 0x0000, 0x98F8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x98FA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9654, 0x0000, 0x0000, + 0x0000, 0x8C86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E50, 0x94F5, 0x98F9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8DC3, 0x9762, + 0x0000, 0x0000, 0x0000, 0x0000, 0x98FC, 0x9942, + 0x98FB, 0x8DC2, 0x0000, 0x8F9D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C58, 0x0000, + 0x0000, 0x0000, 0x9943, 0x0000, 0x0000, 0x8BCD, + 0x0000, 0x0000, 0x0000, 0x9940, 0x9941, 0x0000, + 0x0000, 0x93AD, 0x0000, 0x919C, 0x0000, 0x8BA1, + 0x0000, 0x0000, 0x0000, 0x966C, 0x9944, 0x0000, + 0x0000, 0x0000, 0x97BB, 0x0000, 0x0000, 0x0000, + 0x9945, 0x0000, 0x0000, 0x0000, 0x0000, 0x9948, + 0x0000, 0x9946, 0x0000, 0x916D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9947, 0x9949, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x994B, + 0x0000, 0x0000, 0x0000, 0x994A, 0x0000, 0x95C6, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs51[256] = { + 0x8B56, 0x994D, 0x994E, 0x0000, 0x89AD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x994C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8EF2, 0x0000, 0x9951, 0x9950, 0x994F, 0x0000, + 0x98D4, 0x0000, 0x9952, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F9E, 0x0000, 0x9953, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9744, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x96D7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9955, 0x0000, 0x0000, 0x9954, 0x9957, + 0x9956, 0x0000, 0x0000, 0x9958, 0x9959, 0x88F2, + 0x0000, 0x8CB3, 0x8C5A, 0x8F5B, 0x929B, 0x8BA2, + 0x90E6, 0x8CF5, 0x0000, 0x8D8E, 0x995B, 0x96C6, + 0x9365, 0x0000, 0x8E99, 0x0000, 0x995A, 0x0000, + 0x995C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x937D, 0x0000, 0x8A95, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x995D, 0x0000, 0x0000, 0x93FC, + 0x0000, 0x0000, 0x9153, 0x995F, 0x9960, 0x94AA, + 0x8CF6, 0x985A, 0x9961, 0x0000, 0x0000, 0x8BA4, + 0x0000, 0x0000, 0x0000, 0x95BA, 0x91B4, 0x8BEF, + 0x9354, 0x0000, 0x0000, 0x0000, 0x8C93, 0x0000, + 0x0000, 0x0000, 0x9962, 0x0000, 0x9963, 0x0000, + 0x0000, 0x93E0, 0x897E, 0x0000, 0x0000, 0x9966, + 0x8DFB, 0x0000, 0x9965, 0x8DC4, 0x0000, 0x9967, + 0xE3EC, 0x9968, 0x9660, 0x9969, 0x0000, 0x996A, + 0x996B, 0x8FE7, 0x0000, 0x8ECA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8AA5, 0x0000, + 0x996E, 0x0000, 0x996C, 0x96BB, 0x996D, 0x0000, + 0x9579, 0x996F, 0x9970, 0x9971, 0x937E, 0x0000, + 0x0000, 0x0000, 0x9975, 0x9973, 0x9974, 0x9972, + 0x8DE1, 0x9976, 0x96E8, 0x97E2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9977, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x90A6, 0x9978, + 0x8F79, 0x0000, 0x0000, 0x9979, 0x0000, 0x929C, + 0x97BD, 0x9380, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x99C3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x997A, 0xEAA3, 0x8BC3, + 0x0000, 0x0000, 0x997B, 0x967D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8F88, 0x91FA, 0x0000, 0x997D, + 0x93E2, 0x0000, 0x0000, 0x997E, 0x0000, 0x0000, + 0x9980, 0x8A4D, 0x0000, 0x0000, 0x0000, 0x9981, + 0x8BA5, 0x0000, 0x93CA, 0x899A, 0x8F6F, 0x0000, + 0x0000, 0x949F, 0x9982, 0x0000 +}; + +static u16 Ucs52[256] = { + 0x9381, 0x0000, 0x0000, 0x906E, 0x9983, 0x0000, + 0x95AA, 0x90D8, 0x8AA0, 0x0000, 0x8AA7, 0x9984, + 0x0000, 0x0000, 0x9986, 0x0000, 0x0000, 0x8C59, + 0x0000, 0x0000, 0x9985, 0x0000, 0x0000, 0x97F1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F89, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94BB, 0x95CA, 0x0000, 0x9987, 0x0000, 0x9798, + 0x9988, 0x0000, 0x0000, 0x0000, 0x9989, 0x0000, + 0x939E, 0x0000, 0x0000, 0x998A, 0x0000, 0x0000, + 0x90A7, 0x8DFC, 0x8C94, 0x998B, 0x8E68, 0x8D8F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92E4, 0x998D, 0x0000, 0x0000, 0x91A5, + 0x0000, 0x0000, 0x8DED, 0x998E, 0x998F, 0x914F, + 0x0000, 0x998C, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9991, 0x0000, 0x9655, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8D84, 0x0000, 0x0000, 0x9990, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C95, 0x8DDC, 0x948D, + 0x0000, 0x0000, 0x0000, 0x9994, 0x9992, 0x0000, + 0x0000, 0x0000, 0x0000, 0x959B, 0x8FE8, 0x999B, + 0x8A84, 0x9995, 0x9993, 0x916E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9997, + 0x0000, 0x9996, 0x0000, 0x0000, 0x0000, 0x8A63, + 0x0000, 0x0000, 0x0000, 0x8C80, 0x999C, 0x97AB, + 0x0000, 0x0000, 0x0000, 0x9998, 0x0000, 0x0000, + 0x0000, 0x999D, 0x999A, 0x0000, 0x9999, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x97CD, + 0x0000, 0x0000, 0x0000, 0x8CF7, 0x89C1, 0x0000, + 0x0000, 0x97F2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F95, 0x9377, 0x8D85, 0x99A0, 0x99A1, + 0x0000, 0x0000, 0x0000, 0x97E3, 0x0000, 0x0000, + 0x984A, 0x99A3, 0x0000, 0x0000, 0x0000, 0x8CF8, + 0x0000, 0x0000, 0x99A2, 0x0000, 0x8A4E, 0x0000, + 0x0000, 0x99A4, 0x0000, 0x9675, 0x0000, 0x92BA, + 0x0000, 0x9745, 0x0000, 0x95D7, 0x0000, 0x0000, + 0x0000, 0x99A5, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE8D3, 0x0000, 0x0000, 0x93AE, 0x0000, 0x99A6, + 0x8AA8, 0x96B1, 0x0000, 0x0000, 0x0000, 0x8F9F, + 0x99A7, 0x95E5, 0x99AB, 0x0000, 0x90A8, 0x99A8, + 0x8BCE, 0x0000, 0x99A9, 0x8AA9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C4D, 0x99AC, 0x0000, 0x99AD, + 0x0000, 0x0000, 0x99AE, 0x99AF, 0x8ED9, 0x0000, + 0x0000, 0x0000, 0x8CF9, 0x96DC +}; + +static u16 Ucs53[256] = { + 0x0000, 0x96E6, 0x93F5, 0x0000, 0x0000, 0x95EF, + 0x99B0, 0x0000, 0x99B1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x99B3, 0x0000, 0x99B5, 0x99B4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x99B6, 0x89BB, 0x966B, + 0x0000, 0x8DFA, 0x99B7, 0x0000, 0x0000, 0x9178, + 0x0000, 0x0000, 0x8FA0, 0x8BA7, 0x0000, 0x99B8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94D9, 0x0000, 0x0000, 0x0000, 0x0000, 0x99B9, + 0x0000, 0x99BA, 0x0000, 0x99BB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x99BC, 0x9543, 0x8BE6, 0x88E3, + 0x0000, 0x0000, 0x0000, 0x93BD, 0x99BD, 0x8F5C, + 0x0000, 0x90E7, 0x0000, 0x99BF, 0x99BE, 0x8FA1, + 0x8CDF, 0x99C1, 0x94BC, 0x0000, 0x0000, 0x99C2, + 0x0000, 0x0000, 0x0000, 0x94DA, 0x91B2, 0x91EC, + 0x8BA6, 0x0000, 0x0000, 0x93EC, 0x9250, 0x0000, + 0x948E, 0x0000, 0x966D, 0x0000, 0x99C4, 0x0000, + 0x90E8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C54, 0x0000, 0x0000, 0x99C5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x99C6, 0x894B, 0x88F3, 0x8AEB, + 0x0000, 0x91A6, 0x8B70, 0x9791, 0x0000, 0x99C9, + 0x89B5, 0x0000, 0x0000, 0x99C8, 0x0000, 0x0000, + 0x0000, 0x8BA8, 0x0000, 0x0000, 0x99CA, 0x0000, + 0x96EF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x99CB, 0x0000, 0x97D0, 0x0000, 0x8CFA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8CB4, 0x99CC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x99CE, 0x99CD, 0x0000, + 0x907E, 0x8958, 0x0000, 0x0000, 0x0000, 0x897D, + 0x99CF, 0x0000, 0x99D0, 0x0000, 0x0000, 0x8CB5, + 0x0000, 0x0000, 0x99D1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8B8E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E51, 0x99D2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9694, 0x8DB3, 0x8B79, 0x9746, + 0x916F, 0x94BD, 0x8EFB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8F66, 0x0000, 0x8EE6, 0x8EF3, + 0x0000, 0x8F96, 0x0000, 0x94BE, 0x0000, 0x0000, + 0x0000, 0x99D5, 0x0000, 0x8962, 0x9170, 0x8CFB, + 0x8CC3, 0x8BE5, 0x0000, 0x0000, 0x99D9, 0x9240, + 0x91FC, 0x8BA9, 0x8FA2, 0x99DA, 0x99D8, 0x89C2, + 0x91E4, 0x8EB6, 0x8E6A, 0x8945, 0x0000, 0x0000, + 0x8A90, 0x8D86, 0x8E69, 0x0000, 0x99DB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs54[256] = { + 0x0000, 0x99DC, 0x0000, 0x8B68, 0x8A65, 0x0000, + 0x0000, 0x0000, 0x8D87, 0x8B67, 0x92DD, 0x8944, + 0x93AF, 0x96BC, 0x8D40, 0x9799, 0x9366, 0x8CFC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C4E, 0x0000, 0x99E5, + 0x0000, 0x8BE1, 0x9669, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x94DB, 0x0000, 0x0000, 0x99E4, + 0x0000, 0x8ADC, 0x99DF, 0x99E0, 0x99E2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x99E3, 0x0000, 0x8B7A, 0x9081, 0x0000, 0x95AB, + 0x99E1, 0x99DD, 0x8CE1, 0x0000, 0x99DE, 0x0000, + 0x9843, 0x0000, 0x0000, 0x0000, 0x95F0, 0x0000, + 0x92E6, 0x8CE0, 0x8D90, 0x0000, 0x0000, 0x0000, + 0x99E6, 0x0000, 0x0000, 0x93DB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x99EA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8EFC, 0x0000, 0x8EF4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x99ED, 0x99EB, + 0x0000, 0x96A1, 0x0000, 0x99E8, 0x99F1, 0x99EC, + 0x0000, 0x0000, 0x0000, 0x99EF, 0x8CC4, 0x96BD, + 0x0000, 0x0000, 0x99F0, 0x0000, 0x0000, 0x0000, + 0x99F2, 0x0000, 0x99F4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8DEE, 0x9861, 0x0000, 0x99E9, 0x99E7, + 0x99F3, 0x0000, 0x99EE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x99F6, 0x0000, 0x9A42, 0x99F8, 0x0000, 0x0000, + 0x99FC, 0x0000, 0x0000, 0x9A40, 0x99F9, 0x0000, + 0x0000, 0x9A5D, 0x0000, 0x0000, 0x8DE7, 0x8A50, + 0x0000, 0x0000, 0x0000, 0x0000, 0x99F7, 0x0000, + 0x0000, 0x0000, 0x9A44, 0x88F4, 0x9A43, 0x0000, + 0x88A3, 0x9569, 0x9A41, 0x0000, 0x99FA, 0x0000, + 0x0000, 0x99F5, 0x99FB, 0x8DC6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9A45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x88F5, 0x9A4E, 0x0000, + 0x0000, 0x9A46, 0x9A47, 0x0000, 0x8FA3, 0x9689, + 0x0000, 0x0000, 0x0000, 0x9A4C, 0x9A4B, 0x0000, + 0x0000, 0x0000, 0x934E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A4D, 0x0000, + 0x0000, 0x9A4A, 0x0000, 0x0000 +}; + +static u16 Ucs55[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x8953, 0x0000, + 0x8DB4, 0x904F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9A48, 0x9382, 0x0000, + 0x0000, 0x0000, 0x9A49, 0x0000, 0x88A0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A53, 0x9742, + 0x0000, 0x8FA5, 0x0000, 0x9A59, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A58, 0x9A4F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x91C1, 0x0000, 0x9A50, 0x0000, + 0x0000, 0x0000, 0x91ED, 0x9A55, 0x8FA4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A52, 0x0000, + 0x0000, 0x96E2, 0x0000, 0x0000, 0x0000, 0x8C5B, + 0x0000, 0x0000, 0x9A56, 0x9A57, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A54, 0x9A5A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9A51, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9A60, 0x9A65, 0x0000, + 0x9A61, 0x0000, 0x9A5C, 0x0000, 0x0000, 0x9A66, + 0x9150, 0x0000, 0x0000, 0x9A68, 0x0000, 0x8D41, + 0x9A5E, 0x929D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A62, 0x9A5B, 0x8AAB, 0x0000, + 0x8AEC, 0x8A85, 0x9A63, 0x9A5F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C96, + 0x9A69, 0x9A67, 0x9172, 0x8B69, 0x8BAA, 0x0000, + 0x9A64, 0x0000, 0x8BF2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8963, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A6D, 0x9A6B, + 0x0000, 0x9AA5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A70, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A6A, 0x0000, 0x9A6E, 0x0000, + 0x0000, 0x9A6C, 0x0000, 0x0000, 0x0000, 0x8E6B, + 0x9A6F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9A72, 0x0000, 0x9A77, 0x0000, 0x0000, + 0x0000, 0x9A75, 0x9A74, 0x0000 +}; + +static u16 Ucs56[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9251, 0x0000, 0x0000, 0x89C3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A71, 0x0000, 0x9A73, 0x8FA6, + 0x8952, 0x0000, 0x0000, 0x9A76, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89DC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9A82, + 0x0000, 0x8FFA, 0x9A7D, 0x0000, 0x9A7B, 0x0000, + 0x9A7C, 0x0000, 0x9A7E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x895C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9158, 0x0000, + 0x9A78, 0x0000, 0x9A79, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A9A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A81, 0x0000, + 0x0000, 0x0000, 0x8AED, 0x0000, 0x9A84, 0x9A80, + 0x9A83, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95AC, 0x0000, 0x0000, 0x0000, + 0x93D3, 0x0000, 0x94B6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A86, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A85, 0x8A64, 0x0000, 0x0000, + 0x9A87, 0x0000, 0x0000, 0x0000, 0x0000, 0x9A8A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A89, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A88, 0x0000, + 0x9458, 0x0000, 0x0000, 0x9A8B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9A8C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9A8E, 0x0000, 0x9A8D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A90, 0x0000, 0x0000, 0x0000, + 0x9A93, 0x9A91, 0x9A8F, 0x9A92, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A94, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A95, 0x0000, 0x0000, 0x9A96, + 0x0000, 0x9A97, 0x0000, 0x0000, 0x0000, 0x9A98, + 0x9964, 0x0000, 0x8EFA, 0x8E6C, 0x0000, 0x0000, + 0x89F1, 0x0000, 0x88F6, 0x0000, 0x0000, 0x9263, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A99, 0x0000, + 0x8DA2, 0x0000, 0x88CD, 0x907D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9A9A, 0x8CC5, 0x0000, + 0x0000, 0x8D91, 0x0000, 0x9A9C +}; + +static u16 Ucs57[256] = { + 0x9A9B, 0x0000, 0x0000, 0x95DE, 0x9A9D, 0x0000, + 0x0000, 0x0000, 0x9A9F, 0x9A9E, 0x0000, 0x9AA0, + 0x0000, 0x9AA1, 0x0000, 0x8C97, 0x0000, 0x0000, + 0x8980, 0x9AA2, 0x0000, 0x0000, 0x9AA4, 0x0000, + 0x9AA3, 0x0000, 0x0000, 0x0000, 0x9AA6, 0x0000, + 0x0000, 0x9379, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9AA7, 0x88B3, 0x8DDD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C5C, 0x0000, 0x0000, + 0x926E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9AA8, 0x9AA9, 0x0000, 0x0000, 0x9AAB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AAC, 0x0000, + 0x8DE2, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BCF, + 0x0000, 0x0000, 0x9656, 0x0000, 0x0000, 0x0000, + 0x9AAA, 0x9AAD, 0x8DBF, 0x8D42, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9AB1, 0x0000, 0x0000, 0x8DA3, 0x0000, + 0x9252, 0x0000, 0x0000, 0x9AAE, 0x92D8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9AB2, 0x0000, 0x0000, 0x9082, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AB0, 0x9AB3, + 0x0000, 0x8C5E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9AB4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AB5, 0x0000, + 0x8D43, 0x8A5F, 0x9AB7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9AB8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9AB9, 0x0000, 0x0000, 0x9AB6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9AAF, 0x0000, 0x0000, 0x9ABA, 0x0000, 0x0000, + 0x9ABB, 0x0000, 0x0000, 0x0000, 0x0000, 0x9684, + 0x0000, 0x0000, 0x8FE9, 0x0000, 0x0000, 0x0000, + 0x9ABD, 0x9ABE, 0x9ABC, 0x0000, 0x9AC0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9457, 0x0000, + 0x0000, 0x88E6, 0x9575, 0x0000, 0x0000, 0x9AC1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8FFB, 0x0000, + 0x0000, 0x8EB7, 0x0000, 0x947C, 0x8AEE, 0x0000, + 0x8DE9, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs58[256] = { + 0x9678, 0x0000, 0x93B0, 0x0000, 0x0000, 0x8C98, + 0x91CD, 0x0000, 0x0000, 0x0000, 0x9ABF, 0x9AC2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x91C2, 0x0000, 0x0000, + 0x0000, 0x9AC3, 0x0000, 0x0000, 0x0000, 0x9AC4, + 0x0000, 0x0000, 0x0000, 0x9AC6, 0x0000, 0x0000, + 0x92E7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AAC, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA9F, + 0x8981, 0x95F1, 0x0000, 0x0000, 0x8FEA, 0x9367, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8DE4, 0x0000, + 0x0000, 0x9ACC, 0x0000, 0x0000, 0x95BB, 0x97DB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x89F2, 0x9AC8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9159, 0x9ACB, 0x0000, + 0x9383, 0x0000, 0x0000, 0x9368, 0x9384, 0x94B7, + 0x92CB, 0x0000, 0x0000, 0x0000, 0x8DC7, 0x0000, + 0x0000, 0x0000, 0x9AC7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8996, 0x0000, 0x9355, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AC9, 0x0000, + 0x9AC5, 0x0000, 0x0000, 0x906F, 0x0000, 0x0000, + 0x0000, 0x9ACD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F6D, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BAB, + 0x0000, 0x9ACE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x95E6, 0x0000, 0x0000, + 0x0000, 0x919D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x92C4, 0x0000, 0x0000, 0x9AD0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x966E, 0x0000, 0x0000, 0x9AD1, 0x0000, 0x0000, + 0x9AD6, 0x0000, 0x0000, 0x0000, 0x0000, 0x95AD, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AD5, 0x9ACF, + 0x9AD2, 0x9AD4, 0x0000, 0x0000, 0x8DA4, 0x0000, + 0x0000, 0x95C7, 0x0000, 0x0000, 0x0000, 0x9AD7, + 0x0000, 0x9264, 0x0000, 0x0000, 0x89F3, 0x0000, + 0x8FEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x9AD9, + 0x0000, 0x9AD8, 0x0000, 0x8D88, 0x0000, 0x9ADA, + 0x9ADC, 0x9ADB, 0x0000, 0x0000, 0x9ADE, 0x0000, + 0x9AD3, 0x9AE0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9ADF, 0x9ADD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8E6D, 0x9070, 0x0000, 0x9173, 0x9AE1, + 0x90BA, 0x88EB, 0x9484, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92D9, 0x0000, 0x9AE3, 0x9AE2, 0x9AE4, + 0x9AE5, 0x9AE6, 0x0000, 0x0000 +}; + +static u16 Ucs59[256] = { + 0x0000, 0x0000, 0x9AE7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x95CF, 0x9AE8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x89C4, 0x9AE9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x975B, 0x8A4F, 0x0000, + 0x99C7, 0x8F67, 0x91BD, 0x9AEA, 0x96E9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x96B2, 0x0000, + 0x0000, 0x9AEC, 0x0000, 0x91E5, 0x0000, 0x9356, + 0x91BE, 0x9576, 0x9AED, 0x9AEE, 0x899B, 0x0000, + 0x0000, 0x8EB8, 0x9AEF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x88CE, 0x9AF0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9AF1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8982, 0x0000, 0x0000, 0x8AEF, + 0x93DE, 0x95F2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9AF5, 0x9174, 0x9AF4, 0x8C5F, 0x0000, 0x0000, + 0x967A, 0x9AF3, 0x0000, 0x9385, 0x9AF7, 0x0000, + 0x9AF6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9AF9, 0x0000, 0x9AF8, 0x0000, 0x0000, 0x899C, + 0x0000, 0x9AFA, 0x8FA7, 0x9AFC, 0x9244, 0x0000, + 0x9AFB, 0x0000, 0x95B1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F97, 0x937A, 0x0000, 0x0000, 0x0000, + 0x9B40, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D44, + 0x0000, 0x0000, 0x0000, 0x9B41, 0x9440, 0x94DC, + 0x96CF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9444, 0x0000, 0x0000, 0x9B4A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8B57, 0x0000, 0x0000, + 0x9764, 0x0000, 0x0000, 0x96AD, 0x0000, 0x9BAA, + 0x0000, 0x9B42, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9B45, 0x0000, 0x91C3, 0x0000, 0x0000, + 0x9657, 0x0000, 0x0000, 0x0000, 0x9369, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B46, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9685, + 0x0000, 0x8DC8, 0x0000, 0x0000, 0x8FA8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9B47, 0x0000, 0x0000, 0x8E6F, 0x0000, 0x8E6E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x88B7, 0x8CC6, + 0x0000, 0x90A9, 0x88CF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9B4B, 0x9B4C, 0x0000, 0x9B49, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8957, 0x8AAD, 0x0000, 0x9B48, 0x0000, + 0x96C3, 0x9550, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x88A6, 0x0000, 0x0000, 0x0000, 0x0000, 0x88F7, + 0x0000, 0x0000, 0x0000, 0x8E70 +}; + +static u16 Ucs5A[256] = { + 0x0000, 0x88D0, 0x0000, 0x88A1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9B51, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9B4F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x96BA, 0x0000, 0x9B52, 0x0000, 0x9B50, 0x0000, + 0x0000, 0x9B4E, 0x9050, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9B4D, 0x0000, 0x0000, 0x0000, 0x95D8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8CE2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9B56, + 0x9B57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8FA9, 0x0000, 0x0000, 0x0000, 0x9B53, 0x984B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x946B, 0x0000, + 0x0000, 0x9B55, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8DA5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B58, 0x0000, 0x0000, 0x0000, + 0x9577, 0x0000, 0x0000, 0x0000, 0x9B59, 0x0000, + 0x9B54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x96B9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x947D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B5A, 0x9551, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B5B, 0x9B5F, 0x9B5C, 0x0000, + 0x0000, 0x89C5, 0x9B5E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8EB9, 0x0000, 0x9B5D, + 0x8C99, 0x0000, 0x0000, 0x0000, 0x9B6B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B64, 0x9B61, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9284, 0x0000, 0x9B60, + 0x0000, 0x0000, 0x9B62, 0x0000, 0x0000, 0x9B63, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B65, 0x9B66, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs5B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8AF0, 0x0000, 0x9B68, + 0x9B67, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B69, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8FEC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9B6C, 0x0000, 0x92DA, 0x0000, 0x0000, 0x0000, + 0x8964, 0x0000, 0x9B6A, 0x0000, 0x0000, 0x0000, + 0x9B6D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B6E, 0x0000, 0x9B71, 0x0000, + 0x0000, 0x9B6F, 0x0000, 0x9B70, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E71, 0x9B72, 0x0000, 0x0000, + 0x8D45, 0x9B73, 0x0000, 0x8E9A, 0x91B6, 0x0000, + 0x9B74, 0x9B75, 0x8E79, 0x8D46, 0x0000, 0x96D0, + 0x0000, 0x0000, 0x0000, 0x8B47, 0x8CC7, 0x9B76, + 0x8A77, 0x0000, 0x0000, 0x9B77, 0x0000, 0x91B7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B78, 0x9BA1, + 0x0000, 0x9B79, 0x0000, 0x9B7A, 0x0000, 0x0000, + 0x9B7B, 0x0000, 0x9B7D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B7E, 0x0000, 0x0000, 0x9B80, + 0x0000, 0x91EE, 0x0000, 0x8946, 0x8EE7, 0x88C0, + 0x0000, 0x9176, 0x8AAE, 0x8EB3, 0x0000, 0x8D47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9386, + 0x0000, 0x8F40, 0x8AAF, 0x9288, 0x92E8, 0x88B6, + 0x8B58, 0x95F3, 0x0000, 0x8EC0, 0x0000, 0x0000, + 0x8B71, 0x90E9, 0x8EBA, 0x9747, 0x9B81, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8B7B, 0x0000, 0x8DC9, 0x0000, 0x0000, 0x8A51, + 0x8983, 0x8FAA, 0x89C6, 0x0000, 0x9B82, 0x9765, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F68, + 0x0000, 0x0000, 0x8EE2, 0x9B83, 0x8AF1, 0x93D0, + 0x96A7, 0x9B84, 0x0000, 0x9B85, 0x0000, 0x0000, + 0x9578, 0x0000, 0x0000, 0x0000, 0x9B87, 0x0000, + 0x8AA6, 0x8BF5, 0x9B86, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8AB0, 0x0000, 0x9051, + 0x9B8B, 0x8E40, 0x0000, 0x89C7, 0x9B8A, 0x0000, + 0x9B88, 0x9B8C, 0x9B89, 0x944A, 0x9ECB, 0x9052, + 0x0000, 0x9B8D, 0x0000, 0x0000, 0x97BE, 0x0000, + 0x9B8E, 0x0000, 0x0000, 0x9B90, 0x0000, 0x929E, + 0x9B8F, 0x0000, 0x90A1, 0x0000, 0x8E9B, 0x0000, + 0x0000, 0x0000, 0x91CE, 0x8EF5 +}; + +static u16 Ucs5C[256] = { + 0x0000, 0x9595, 0x90EA, 0x0000, 0x8ECB, 0x9B91, + 0x8FAB, 0x9B92, 0x9B93, 0x88D1, 0x91B8, 0x9071, + 0x0000, 0x9B94, 0x93B1, 0x8FAC, 0x0000, 0x8FAD, + 0x0000, 0x9B95, 0x0000, 0x0000, 0x90EB, 0x0000, + 0x0000, 0x0000, 0x8FAE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B96, 0x0000, 0x9B97, 0x0000, + 0x96DE, 0x0000, 0x0000, 0x0000, 0x9B98, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8BC4, 0x0000, 0x0000, + 0x0000, 0x8F41, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B99, 0x9B9A, 0x8EDA, 0x904B, + 0x93F2, 0x9073, 0x94F6, 0x9441, 0x8BC7, 0x9B9B, + 0x0000, 0x0000, 0x0000, 0x8B8F, 0x9B9C, 0x0000, + 0x8BFC, 0x0000, 0x93CD, 0x89AE, 0x0000, 0x8E72, + 0x9B9D, 0x9BA0, 0x9B9F, 0x8BFB, 0x0000, 0x9B9E, + 0x0000, 0x9357, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91AE, 0x0000, + 0x936A, 0x8EC6, 0x0000, 0x0000, 0x9177, 0x979A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9BA2, 0x0000, 0x9BA3, 0x93D4, 0x0000, 0x8E52, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9BA5, 0x0000, + 0x0000, 0x9BA6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9BA7, 0x0000, 0x0000, 0x0000, + 0x8AF2, 0x9BA8, 0x0000, 0x0000, 0x9BA9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89AA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x915A, 0x8AE2, 0x0000, 0x9BAB, 0x96A6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x91D0, 0x0000, 0x8A78, + 0x0000, 0x0000, 0x9BAD, 0x9BAF, 0x8ADD, 0x0000, + 0x0000, 0x9BAC, 0x9BAE, 0x0000, 0x9BB1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BB0, + 0x0000, 0x9BB2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9BB3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x93BB, 0x8BAC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x89E3, 0x9BB4, + 0x9BB9, 0x0000, 0x0000, 0x9BB7, 0x0000, 0x95F5, + 0x95F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9387, 0x0000, 0x0000, 0x0000, 0x9BB6, 0x8F73, + 0x0000, 0x9BB5, 0x0000, 0x0000 +}; + +static u16 Ucs5D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9092, 0x0000, 0x0000, 0x0000, 0x9BBA, + 0x0000, 0x0000, 0x8DE8, 0x0000, 0x0000, 0x9BC0, + 0x0000, 0x0000, 0x9BC1, 0x9BBB, 0x8A52, 0x9BBC, + 0x9BC5, 0x9BC4, 0x9BC3, 0x9BBF, 0x0000, 0x0000, + 0x0000, 0x9BBE, 0x0000, 0x0000, 0x9BC2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95F6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BC9, 0x9BC6, 0x0000, + 0x9BC8, 0x0000, 0x9792, 0x0000, 0x9BC7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9BBD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9093, 0x0000, 0x0000, + 0x9BCA, 0x0000, 0x0000, 0x8DB5, 0x0000, 0x0000, + 0x0000, 0x9BCB, 0x0000, 0x0000, 0x9BCC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9BCF, 0x0000, + 0x9BCE, 0x0000, 0x0000, 0x9BCD, 0x0000, 0x0000, + 0x0000, 0x9388, 0x9BB8, 0x0000, 0x0000, 0x0000, + 0x9BD5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9BD1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9BD0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9BD2, 0x0000, + 0x9BD3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BD6, 0x0000, 0x0000, + 0x97E4, 0x0000, 0x9BD7, 0x9BD4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BD8, 0x0000, 0x0000, + 0x8ADE, 0x9BD9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9BDB, 0x9BDA, 0x0000, 0x0000, 0x9BDC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BDD, 0x0000, 0x90EC, + 0x8F42, 0x0000, 0x0000, 0x8F84, 0x0000, 0x9183, + 0x0000, 0x8D48, 0x8DB6, 0x8D49, 0x8B90, 0x0000, + 0x0000, 0x9BDE, 0x0000, 0x0000, 0x8DB7, 0x0000, + 0x0000, 0x8CC8, 0x9BDF, 0x96A4, 0x9462, 0x9BE0, + 0x0000, 0x8D4A, 0x0000, 0x0000, 0x0000, 0x8AAA, + 0x0000, 0x9246, 0x8BD0, 0x0000 +}; + +static u16 Ucs5E[256] = { + 0x0000, 0x0000, 0x8E73, 0x957A, 0x0000, 0x0000, + 0x94BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BE1, + 0x8AF3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BE4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x929F, 0x0000, + 0x0000, 0x9BE3, 0x9BE2, 0x9BE5, 0x0000, 0x92E9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9083, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8E74, 0x0000, 0x90C8, 0x0000, 0x91D1, + 0x8B41, 0x0000, 0x0000, 0x92A0, 0x0000, 0x0000, + 0x9BE6, 0x9BE7, 0x8FED, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9658, 0x0000, 0x0000, 0x9BEA, 0x0000, + 0x0000, 0x9BE9, 0x9BE8, 0x959D, 0x0000, 0x9BF1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9679, 0x0000, + 0x9BEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9BED, 0x968B, 0x0000, 0x9BEC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BEE, + 0x0000, 0x94A6, 0x9BEF, 0x95BC, 0x9BF0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AB1, 0x95BD, 0x944E, 0x9BF2, 0x9BF3, 0x0000, + 0x8D4B, 0x8AB2, 0x9BF4, 0x8CB6, 0x9763, 0x9748, + 0x8AF4, 0x9BF6, 0x0000, 0x92A1, 0x0000, 0x8D4C, + 0x8FAF, 0x0000, 0x0000, 0x94DD, 0x0000, 0x0000, + 0x8FB0, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F98, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92EA, + 0x95F7, 0x9358, 0x0000, 0x0000, 0x8D4D, 0x0000, + 0x957B, 0x0000, 0x0000, 0x0000, 0x9BF7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9378, 0x8DC0, + 0x0000, 0x0000, 0x0000, 0x8CC9, 0x0000, 0x92EB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x88C1, 0x8F8E, 0x8D4E, 0x9766, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9BF8, 0x9BF9, 0x9470, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9BFA, 0x97F5, 0x984C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BFC, 0x9BFB, 0x0000, + 0x0000, 0x8A66, 0x0000, 0x0000, 0x9C40, 0x0000, + 0x0000, 0x0000, 0x9C43, 0x9C44, 0x0000, 0x9C42, + 0x0000, 0x955F, 0x8FB1, 0x9C46, 0x9C45, 0x9C41, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9C47, 0x9C48, + 0x0000, 0x0000, 0x9C49, 0x0000, 0x0000, 0x0000, + 0x9C4C, 0x9C4A, 0x0000, 0x9C4B, 0x9C4D, 0x0000, + 0x8984, 0x92EC, 0x9C4E, 0x0000, 0x8C9A, 0x89F4, + 0x9455, 0x0000, 0x9C4F, 0x93F9 +}; + +static u16 Ucs5F[256] = { + 0x0000, 0x95D9, 0x0000, 0x9C50, 0x984D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9C51, 0x95BE, 0x9C54, + 0x989F, 0x98AF, 0x0000, 0x8EAE, 0x93F3, 0x9C55, + 0x0000, 0x8B7C, 0x92A2, 0x88F8, 0x9C56, 0x95A4, + 0x8D4F, 0x0000, 0x0000, 0x926F, 0x0000, 0x0000, + 0x0000, 0x92ED, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x96ED, 0x8CB7, 0x8CCA, 0x0000, 0x9C57, + 0x0000, 0x0000, 0x0000, 0x9C58, 0x0000, 0x9C5E, + 0x0000, 0x8EE3, 0x0000, 0x0000, 0x0000, 0x92A3, + 0x0000, 0x8BAD, 0x9C59, 0x0000, 0x0000, 0x0000, + 0x954A, 0x0000, 0x9265, 0x0000, 0x0000, 0x9C5A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9C5B, 0x0000, 0x8BAE, 0x0000, 0x9C5C, 0x0000, + 0x9C5D, 0x0000, 0x0000, 0x9C5F, 0x0000, 0x9396, + 0x0000, 0x0000, 0x9C60, 0x9C61, 0x0000, 0x9C62, + 0x0000, 0x0000, 0x9C53, 0x9C52, 0x0000, 0x0000, + 0x0000, 0x9C63, 0x8C60, 0x0000, 0x0000, 0x0000, + 0x9546, 0x0000, 0x0000, 0x8DCA, 0x9556, 0x92A4, + 0x956A, 0x9C64, 0x0000, 0x0000, 0x8FB2, 0x8965, + 0x0000, 0x9C65, 0x0000, 0x0000, 0x0000, 0x9C66, + 0x0000, 0x96F0, 0x0000, 0x0000, 0x94DE, 0x0000, + 0x0000, 0x9C69, 0x899D, 0x90AA, 0x9C68, 0x9C67, + 0x8C61, 0x91D2, 0x0000, 0x9C6D, 0x9C6B, 0x0000, + 0x9C6A, 0x97A5, 0x8CE3, 0x0000, 0x0000, 0x0000, + 0x8F99, 0x9C6C, 0x936B, 0x8F5D, 0x0000, 0x0000, + 0x0000, 0x93BE, 0x9C70, 0x9C6F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9C6E, 0x0000, 0x9C71, 0x8CE4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9C72, 0x959C, 0x8F7A, 0x0000, 0x0000, 0x9C73, + 0x94F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x93BF, + 0x92A5, 0x0000, 0x0000, 0x0000, 0x0000, 0x934F, + 0x0000, 0x0000, 0x9C74, 0x8B4A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9053, 0x0000, 0x954B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AF5, 0x9445, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9C75, 0x8E75, + 0x9659, 0x965A, 0x0000, 0x0000, 0x899E, 0x9C7A, + 0x0000, 0x0000, 0x9289, 0x0000, 0x0000, 0x0000, + 0x9C77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x89F5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9CAB, 0x9C79, 0x0000, 0x0000, 0x0000, 0x944F, + 0x0000, 0x0000, 0x9C78, 0x0000, 0x0000, 0x9C76, + 0x0000, 0x8D9A, 0x0000, 0x9C7C +}; + +static u16 Ucs60[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9C83, 0x9C89, 0x9C81, 0x0000, + 0x937B, 0x0000, 0x0000, 0x9C86, 0x957C, 0x0000, + 0x0000, 0x9C80, 0x0000, 0x9C85, 0x97E5, 0x8E76, + 0x0000, 0x0000, 0x91D3, 0x9C7D, 0x0000, 0x0000, + 0x0000, 0x8B7D, 0x9C88, 0x90AB, 0x8985, 0x9C82, + 0x89F6, 0x9C87, 0x0000, 0x0000, 0x0000, 0x8BAF, + 0x0000, 0x9C84, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8C, + 0x9C96, 0x9C94, 0x0000, 0x0000, 0x9C91, 0x0000, + 0x0000, 0x0000, 0x9C90, 0x97F6, 0x0000, 0x9C92, + 0x0000, 0x0000, 0x8BB0, 0x0000, 0x8D50, 0x0000, + 0x0000, 0x8F9A, 0x0000, 0x0000, 0x0000, 0x9C99, + 0x9C8B, 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8F, + 0x9C7E, 0x0000, 0x89F8, 0x9C93, 0x9C95, 0x9270, + 0x0000, 0x0000, 0x8DA6, 0x89B6, 0x9C8D, 0x9C98, + 0x9C97, 0x8BB1, 0x0000, 0x91A7, 0x8A86, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C62, 0x0000, 0x9C8E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9C9A, 0x0000, 0x9C9D, + 0x9C9F, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EBB, + 0x0000, 0x9CA5, 0x92EE, 0x9C9B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9CA3, 0x0000, 0x89F7, 0x0000, + 0x9CA1, 0x9CA2, 0x0000, 0x0000, 0x9C9E, 0x9CA0, + 0x0000, 0x0000, 0x0000, 0x8CE5, 0x9749, 0x0000, + 0x0000, 0x8AB3, 0x0000, 0x0000, 0x8978, 0x9CA4, + 0x0000, 0x9459, 0x88AB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x94DF, 0x9C7B, + 0x9CAA, 0x9CAE, 0x96E3, 0x0000, 0x9CA7, 0x0000, + 0x0000, 0x0000, 0x9389, 0x9CAC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8FEE, + 0x9CAD, 0x93D5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9866, + 0x0000, 0x9CA9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9CAF, 0x0000, 0x8D9B, 0x0000, 0x90C9, 0x0000, + 0x0000, 0x88D2, 0x9CA8, 0x9CA6, 0x0000, 0x9179, + 0x0000, 0x0000, 0x0000, 0x9C9C, 0x8E53, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x91C4, 0x9CBB, 0x0000, 0x917A, 0x9CB6, 0x0000, + 0x9CB3, 0x9CB4, 0x0000, 0x8EE4, 0x9CB7, 0x9CBA, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs61[256] = { + 0x9CB5, 0x8F44, 0x0000, 0x9CB8, 0x0000, 0x0000, + 0x9CB2, 0x0000, 0x96FA, 0x96F9, 0x0000, 0x0000, + 0x0000, 0x9CBC, 0x9CBD, 0x88D3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9CB1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8BF0, 0x88A4, 0x0000, 0x0000, + 0x0000, 0x8AB4, 0x0000, 0x9CB9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9CC1, 0x9CC0, 0x0000, + 0x0000, 0x0000, 0x9CC5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9CC6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9CC4, 0x9CC7, 0x9CBF, 0x9CC3, 0x0000, 0x0000, + 0x9CC8, 0x0000, 0x9CC9, 0x0000, 0x0000, 0x9CBE, + 0x8E9C, 0x0000, 0x9CC2, 0x91D4, 0x8D51, 0x9CB0, + 0x9054, 0x0000, 0x0000, 0x0000, 0x0000, 0x9CD6, + 0x0000, 0x95E7, 0x0000, 0x0000, 0x9CCC, 0x9CCD, + 0x9CCE, 0x0000, 0x0000, 0x9CD5, 0x0000, 0x9CD4, + 0x0000, 0x0000, 0x969D, 0x8AB5, 0x0000, 0x9CD2, + 0x0000, 0x8C64, 0x8A53, 0x0000, 0x0000, 0x9CCF, + 0x0000, 0x0000, 0x97B6, 0x9CD1, 0x88D4, 0x9CD3, + 0x0000, 0x9CCA, 0x9CD0, 0x9CD7, 0x8C63, 0x9CCB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x977C, 0x0000, 0x0000, 0x0000, 0x974A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9CDA, 0x0000, 0x0000, + 0x9CDE, 0x0000, 0x0000, 0x0000, 0x919E, 0x0000, + 0x97F7, 0x9CDF, 0x0000, 0x0000, 0x9CDC, 0x0000, + 0x9CD9, 0x0000, 0x0000, 0x9CD8, 0x9CDD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95AE, 0x0000, 0x0000, 0x93B2, + 0x0000, 0x8C65, 0x0000, 0x9CE0, 0x9CDB, 0x0000, + 0x9CE1, 0x0000, 0x0000, 0x0000, 0x8C9B, 0x0000, + 0x0000, 0x0000, 0x89AF, 0x0000, 0x0000, 0x0000, + 0x9CE9, 0x0000, 0x0000, 0x0000, 0x8AB6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9CE7, 0x0000, 0x0000, + 0x9CE8, 0x8DA7, 0x9CE6, 0x9CE4, 0x9CE3, 0x9CEA, + 0x9CE2, 0x9CEC, 0x0000, 0x0000, 0x89F9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9CEE, + 0x0000, 0x0000, 0x9CED, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x92A6, 0x0000, 0x9CF1, 0x0000, + 0x9CEF, 0x9CE5, 0x8C9C, 0x0000, 0x9CF0, 0x0000, + 0x9CF4, 0x9CF3, 0x9CF5, 0x9CF2 +}; + +static u16 Ucs62[256] = { + 0x9CF6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9CF7, 0x9CF8, 0x95E8, 0x0000, + 0x9CFA, 0x9CF9, 0x8F5E, 0x0000, 0x90AC, 0x89E4, + 0x89FA, 0x0000, 0x9CFB, 0x0000, 0x88BD, 0x0000, + 0x0000, 0x0000, 0x90CA, 0x9CFC, 0x0000, 0xE6C1, + 0x9D40, 0x8C81, 0x0000, 0x9D41, 0x0000, 0x0000, + 0x0000, 0x0000, 0x90ED, 0x0000, 0x0000, 0x0000, + 0x9D42, 0x0000, 0x0000, 0x0000, 0x9D43, 0x8B59, + 0x9D44, 0x0000, 0x9D45, 0x9D46, 0x91D5, 0x0000, + 0x0000, 0x0000, 0x8CCB, 0x0000, 0x0000, 0x96DF, + 0x0000, 0x0000, 0x0000, 0x965B, 0x8F8A, 0x9D47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90EE, + 0xE7BB, 0x94E0, 0x0000, 0x8EE8, 0x0000, 0x8DCB, + 0x9D48, 0x0000, 0x0000, 0x0000, 0x0000, 0x91C5, + 0x0000, 0x95A5, 0x0000, 0x0000, 0x91EF, 0x0000, + 0x0000, 0x9D4B, 0x0000, 0x0000, 0x9D49, 0x0000, + 0x9D4C, 0x0000, 0x0000, 0x9D4A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9D4D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95AF, 0x0000, 0x0000, 0x88B5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x957D, 0x0000, + 0x0000, 0x94E1, 0x0000, 0x0000, 0x9D4E, 0x0000, + 0x9D51, 0x8FB3, 0x8B5A, 0x0000, 0x9D4F, 0x9D56, + 0x8FB4, 0x0000, 0x0000, 0x0000, 0x0000, 0x9D50, + 0x9463, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x977D, 0x9D52, 0x9D53, 0x9D57, 0x938A, + 0x9D54, 0x8D52, 0x90DC, 0x0000, 0x0000, 0x9D65, + 0x94B2, 0x0000, 0x91F0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x94E2, 0x9DAB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x95F8, 0x0000, 0x0000, + 0x0000, 0x92EF, 0x0000, 0x0000, 0x0000, 0x9695, + 0x0000, 0x9D5A, 0x899F, 0x928A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9D63, 0x0000, 0x0000, 0x9253, + 0x9D5D, 0x9D64, 0x9D5F, 0x9D66, 0x9D62, 0x0000, + 0x9D61, 0x948F, 0x0000, 0x9D5B, 0x89FB, 0x9D59, + 0x8B91, 0x91F1, 0x9D55, 0x0000, 0x0000, 0x9D58, + 0x8D53, 0x90D9, 0x0000, 0x8FB5, 0x9D60, 0x9471, + 0x0000, 0x0000, 0x8B92, 0x8A67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8A87, 0x9040, 0x9D68, 0x9D6D, + 0x0000, 0x9D69, 0x0000, 0x8C9D, 0x0000, 0x9D6E, + 0x8E41, 0x8D89, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8F45, 0x9D5C +}; + +static u16 Ucs63[256] = { + 0x0000, 0x8E9D, 0x9D6B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8E77, 0x9D6C, 0x88C2, 0x0000, 0x0000, + 0x9D67, 0x0000, 0x0000, 0x0000, 0x0000, 0x92A7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8B93, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8BB2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9D6A, 0x88A5, 0x0000, + 0x0000, 0x8DC1, 0x0000, 0x0000, 0x0000, 0x9055, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x92F0, 0x0000, + 0x0000, 0x94D2, 0x9D70, 0x917D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x91A8, 0x0000, 0x0000, 0x8E4A, 0x9D71, + 0x0000, 0x9D73, 0x9D6F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95DF, 0x0000, 0x92BB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x917B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95F9, 0x8ECC, 0x9D80, 0x0000, 0x9D7E, + 0x0000, 0x0000, 0x9098, 0x0000, 0x0000, 0x0000, + 0x8C9E, 0x0000, 0x0000, 0x0000, 0x9D78, 0x8FB7, + 0x0000, 0x0000, 0x93E6, 0x9450, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9D76, 0x0000, 0x0000, 0x917C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8EF6, 0x9D7B, + 0x0000, 0x0000, 0x8FB6, 0x0000, 0x9D75, 0x9D7A, + 0x0000, 0x0000, 0x9472, 0x0000, 0x0000, 0x0000, + 0x9D74, 0x0000, 0x8C40, 0x0000, 0x0000, 0x8A7C, + 0x0000, 0x0000, 0x0000, 0x9D7C, 0x97A9, 0x8DCC, + 0x9254, 0x9D79, 0x0000, 0x90DA, 0x0000, 0x8D54, + 0x9084, 0x8986, 0x915B, 0x9D77, 0x8B64, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C66, 0x0000, + 0x92CD, 0x9D7D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x917E, 0x0000, 0x0000, 0x9D81, 0x0000, + 0x9D83, 0x0000, 0x0000, 0x91B5, 0x9D89, 0x0000, + 0x9D84, 0x0000, 0x0000, 0x9D86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9560, 0x92F1, 0x0000, + 0x9D87, 0x0000, 0x0000, 0x0000, 0x974B, 0x0000, + 0x0000, 0x0000, 0x9767, 0x8AB7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x88AC, 0x0000, 0x9D85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9D82, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8AF6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8987, 0x0000, + 0x9D88, 0x0000, 0x0000, 0x0000, 0x9768, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs64[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9D8C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x91B9, 0x0000, 0x9D93, 0x0000, 0x0000, + 0x0000, 0x9D8D, 0x0000, 0x0000, 0x9D8A, 0x9D91, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D72, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9D8E, 0x0000, 0x9D92, 0x0000, + 0x0000, 0x0000, 0x94C0, 0x938B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D8B, 0x0000, + 0x9D8F, 0x0000, 0x0000, 0x0000, 0x8C67, 0x0000, + 0x0000, 0x0000, 0x8DEF, 0x0000, 0x0000, 0x0000, + 0x90DB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9D97, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9345, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9D94, 0x0000, 0x9680, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9D95, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D96, 0x0000, + 0x96CC, 0x0000, 0x90A0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C82, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D9D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E54, 0x9D9A, 0x0000, 0x9D99, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9451, 0x0000, + 0x0000, 0x0000, 0x93B3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9350, 0x9D9B, 0x0000, 0x0000, + 0x0000, 0x9D9C, 0x0000, 0x958F, 0x0000, 0x9464, + 0x8E42, 0x0000, 0x90EF, 0x0000, 0x966F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A68, + 0x0000, 0x9DA3, 0x9D9E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9769, 0x9DA5, 0x0000, 0x0000, 0x9DA1, + 0x0000, 0x9DA2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9180, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9DA0, 0x0000, 0x9D5E, 0x0000, 0x0000, 0x0000, + 0x9DA4, 0x0000, 0x9D9F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9DA9, 0x9DAA, 0x9346, 0x9DAC, + 0x0000, 0x0000, 0x8E43, 0x9DA7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8B5B, 0x0000, 0x0000, 0x9DAD, + 0x0000, 0x9DA6, 0x9DB1, 0x0000, 0x9DB0, 0x0000, + 0x9DAF, 0x0000, 0x0000, 0x0000, 0x9DB2, 0x0000, + 0x0000, 0x9DB4, 0x8FEF, 0x0000 +}; + +static u16 Ucs65[256] = { + 0x9DB3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DB7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9DB5, 0x0000, 0x0000, 0x0000, 0x9DB6, 0x9D90, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DB9, + 0x9DB8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9D98, 0x9DBA, 0x9DAE, 0x0000, 0x0000, 0x8E78, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DBB, 0x9DBC, + 0x9DBE, 0x9DBD, 0x9DBF, 0x89FC, 0x0000, 0x8D55, + 0x0000, 0x0000, 0x95FA, 0x90AD, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8CCC, 0x0000, 0x0000, + 0x9DC1, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DC4, + 0x0000, 0x9571, 0x0000, 0x8B7E, 0x0000, 0x0000, + 0x0000, 0x9DC3, 0x9DC2, 0x9473, 0x9DC5, 0x8BB3, + 0x0000, 0x0000, 0x0000, 0x9DC7, 0x9DC6, 0x0000, + 0x0000, 0x0000, 0x8AB8, 0x8E55, 0x0000, 0x0000, + 0x93D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C68, 0x0000, 0x0000, 0x0000, 0x9094, 0x0000, + 0x9DC8, 0x0000, 0x90AE, 0x9347, 0x0000, 0x957E, + 0x9DC9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DCA, 0x9DCB, + 0x0000, 0x0000, 0x0000, 0x95B6, 0x9B7C, 0x90C4, + 0x0000, 0x0000, 0x956B, 0x0000, 0x8DD6, 0x0000, + 0x94E3, 0x94C1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x936C, 0x0000, 0x97BF, 0x0000, 0x9DCD, + 0x8ECE, 0x0000, 0x0000, 0x9DCE, 0x0000, 0x88B4, + 0x0000, 0x0000, 0x8BD2, 0x90CB, 0x0000, 0x9580, + 0x0000, 0x0000, 0x0000, 0x9DCF, 0x8E61, 0x9266, + 0x0000, 0x8E7A, 0x9056, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9DD0, 0x0000, 0x95FB, + 0x0000, 0x0000, 0x8997, 0x8E7B, 0x0000, 0x0000, + 0x0000, 0x9DD3, 0x0000, 0x9DD1, 0x9DD4, 0x97B7, + 0x9DD2, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F9, + 0x9DD5, 0x0000, 0x0000, 0x91B0, 0x0000, 0x0000, + 0x9DD6, 0x0000, 0x0000, 0x0000, 0x0000, 0x8AF8, + 0x0000, 0x9DD8, 0x0000, 0x9DD7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9DD9, 0x9DDA, 0x8AF9, 0x0000, + 0x0000, 0x93FA, 0x9255, 0x8B8C, 0x8E7C, 0x9181, + 0x0000, 0x0000, 0x8F7B, 0x88AE, 0x0000, 0x0000, + 0x0000, 0x9DDB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x89A0, 0x9DDF, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs66[256] = { + 0x0000, 0x0000, 0x8D56, 0x9DDE, 0x0000, 0x0000, + 0x8DA9, 0x8FB8, 0x0000, 0x0000, 0x9DDD, 0x0000, + 0x8FB9, 0x0000, 0x96BE, 0x8DA8, 0x0000, 0x0000, + 0x0000, 0x88D5, 0x90CC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DE4, 0x0000, + 0x0000, 0x90AF, 0x8966, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F74, 0x0000, 0x9686, 0x8DF0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8FBA, 0x0000, 0x90A5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DE3, 0x9DE1, + 0x9DE2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x928B, 0x0000, 0x0000, 0x9E45, 0x0000, 0x9DE8, + 0x8E9E, 0x8D57, 0x9DE6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9DE7, 0x0000, 0x9057, 0x0000, 0x0000, + 0x0000, 0x9DE5, 0x0000, 0x0000, 0x8E4E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9DEA, 0x9DE9, 0x9DEE, + 0x0000, 0x0000, 0x9DEF, 0x0000, 0x9DEB, 0x0000, + 0x8A41, 0x9DEC, 0x9DED, 0x94D3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9581, 0x8C69, 0x9DF0, 0x0000, + 0x0000, 0x0000, 0x90B0, 0x0000, 0x8FBB, 0x0000, + 0x0000, 0x0000, 0x9271, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8BC5, 0x0000, 0x9DF1, + 0x9DF5, 0x0000, 0x0000, 0x89C9, 0x9DF2, 0x9DF4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DF3, 0x0000, + 0x0000, 0x8F8B, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9267, 0x88C3, 0x9DF6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9DF7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x92A8, 0x0000, 0x0000, 0x0000, 0x97EF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8E62, 0x0000, 0x0000, + 0x95E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x965C, 0x0000, 0x0000, 0x0000, 0x9E41, 0x9DF9, + 0x0000, 0x0000, 0x9DFC, 0x0000, 0x9DFB, 0x0000, + 0x0000, 0x9DF8, 0x0000, 0x0000, 0x9E40, 0x0000, + 0x0000, 0x93DC, 0x0000, 0x9DFA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9E42, 0x0000, + 0x0000, 0x8F8C, 0x9E43, 0x0000, 0x976A, 0x9498, + 0x0000, 0x0000, 0x9E44, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E46, 0x0000, 0x0000, 0x9E47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9E48, 0x0000, 0x8BC8, 0x8967, 0x8D58, 0x9E49, + 0x0000, 0x9E4A, 0x8F91, 0x9182, 0x0000, 0x0000, + 0x99D6, 0x915D, 0x915C, 0x91D6 +}; + +static u16 Ucs67[256] = { + 0x8DC5, 0x0000, 0x0000, 0x98F0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C8E, 0x974C, 0x0000, 0x95FC, + 0x0000, 0x959E, 0x0000, 0x9E4B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8DF1, 0x92BD, 0x9E4C, 0x984E, + 0x0000, 0x0000, 0x0000, 0x965D, 0x0000, 0x92A9, + 0x9E4D, 0x8AFA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E4E, 0x9E4F, 0x96D8, 0x0000, + 0x96A2, 0x9696, 0x967B, 0x8E44, 0x9E51, 0x0000, + 0x0000, 0x8EE9, 0x0000, 0x0000, 0x9670, 0x0000, + 0x9E53, 0x9E56, 0x9E55, 0x0000, 0x8AF7, 0x0000, + 0x0000, 0x8B80, 0x0000, 0x9E52, 0x0000, 0x9E54, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9E57, 0x0000, + 0x0000, 0x9099, 0x0000, 0x0000, 0x0000, 0x0000, + 0x979B, 0x88C7, 0x8DDE, 0x91BA, 0x0000, 0x8EDB, + 0x0000, 0x0000, 0x8FF1, 0x0000, 0x0000, 0x9E5A, + 0x0000, 0x0000, 0x936D, 0x0000, 0x9E58, 0x91A9, + 0x9E59, 0x8FF0, 0x96DB, 0x9E5B, 0x9E5C, 0x9788, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9E61, 0x0000, + 0x0000, 0x8D59, 0x0000, 0x9474, 0x9E5E, 0x938C, + 0x9DDC, 0x9DE0, 0x0000, 0x8B6E, 0x0000, 0x9466, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9E60, 0x0000, + 0x8FBC, 0x94C2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9E66, 0x0000, 0x94F8, 0x0000, 0x9E5D, + 0x0000, 0x9E63, 0x9E62, 0x0000, 0x0000, 0x0000, + 0x90CD, 0x0000, 0x0000, 0x0000, 0x0000, 0x968D, + 0x0000, 0x97D1, 0x0000, 0x0000, 0x9687, 0x0000, + 0x89CA, 0x8E7D, 0x0000, 0x0000, 0x9867, 0x9E65, + 0x9095, 0x0000, 0x0000, 0x0000, 0x9E64, 0x0000, + 0x0000, 0x9E5F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8CCD, 0x0000, 0x0000, 0x0000, 0x9E6B, + 0x9E69, 0x0000, 0x89CB, 0x9E67, 0x9E6D, 0x9E73, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x91C6, 0x0000, 0x0000, 0x95BF, 0x0000, + 0x9E75, 0x0000, 0x0000, 0x0000, 0x9541, 0x0000, + 0x0000, 0x0000, 0x9E74, 0x9490, 0x965E, 0x8AB9, + 0x0000, 0x90F5, 0x8F5F, 0x0000, 0x0000, 0x0000, + 0x92D1, 0x0000, 0x974D, 0x0000, 0x0000, 0x9E70, + 0x9E6F, 0x0000, 0x0000, 0x0000, 0x9E71, 0x0000, + 0x9E6E, 0x0000, 0x0000, 0x9E76, 0x0000, 0x9E6C, + 0x0000, 0x0000, 0x9E6A, 0x0000, 0x9E72, 0x9E68, + 0x0000, 0x928C, 0x0000, 0x96F6, 0x8EC4, 0x8DF2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8DB8, + 0x0000, 0x0000, 0x968F, 0x8A60 +}; + +static u16 Ucs68[256] = { + 0x0000, 0x0000, 0x92CC, 0x93C8, 0x8968, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x90F0, 0x0000, 0x0000, 0x90B2, 0x8C49, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9E78, 0x0000, 0x0000, 0x8D5A, 0x8A9C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E7A, + 0x8A94, 0x9E81, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E7D, 0x0000, 0x90F1, 0x0000, + 0x0000, 0x0000, 0x8A6A, 0x8DAA, 0x0000, 0x0000, + 0x8A69, 0x8DCD, 0x0000, 0x0000, 0x9E7B, 0x8C85, + 0x8C6A, 0x938D, 0x0000, 0x0000, 0x9E79, 0x0000, + 0x88C4, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E7C, + 0x9E7E, 0x0000, 0x8BCB, 0x8C4B, 0x0000, 0x8ABA, + 0x8B6A, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E82, + 0x0000, 0x0000, 0x8DF7, 0x9691, 0x0000, 0x8E56, + 0x0000, 0x0000, 0x0000, 0x9E83, 0x0000, 0x0000, + 0x0000, 0x954F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E8F, 0x0000, 0x89B1, 0x9E84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9E95, 0x9E85, 0x0000, 0x97C0, 0x0000, 0x9E8C, + 0x0000, 0x947E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9E94, 0x0000, 0x9E87, + 0x0000, 0x0000, 0x0000, 0x88B2, 0x9E89, 0x0000, + 0x0000, 0x8D5B, 0x0000, 0x0000, 0x0000, 0x9E8B, + 0x0000, 0x9E8A, 0x0000, 0x9E86, 0x9E91, 0x0000, + 0x8FBD, 0x0000, 0x0000, 0x0000, 0x9AEB, 0x8CE6, + 0x979C, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E88, + 0x0000, 0x92F2, 0x8A42, 0x8DAB, 0x0000, 0x9E80, + 0x0000, 0x9E90, 0x8A81, 0x0000, 0x0000, 0x9E8E, + 0x9E92, 0x0000, 0x938E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8AFC, 0x0000, + 0x9EB0, 0x0000, 0x0000, 0x96C7, 0x9E97, 0x8AFB, + 0x0000, 0x9E9E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x965F, 0x0000, 0x9E9F, 0x9EA1, 0x0000, 0x9EA5, + 0x9E99, 0x0000, 0x9249, 0x0000, 0x0000, 0x0000, + 0x0000, 0x938F, 0x9EA9, 0x9E9C, 0x0000, 0x9EA6, + 0x0000, 0x0000, 0x0000, 0x9EA0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9058, 0x9EAA, + 0x0000, 0x0000, 0x90B1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EA8, 0x8ABB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs69[256] = { + 0x986F, 0x9E96, 0x0000, 0x0000, 0x9EA4, 0x88D6, + 0x0000, 0x0000, 0x9E98, 0x0000, 0x0000, 0x96B8, + 0x9E9D, 0x9041, 0x92C5, 0x9E93, 0x0000, 0x0000, + 0x9EA3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x909A, 0x9EAD, 0x8A91, 0x8C9F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EAF, 0x9E9A, 0x9EAE, + 0x0000, 0x9EA7, 0x9E9B, 0x0000, 0x9EAB, 0x0000, + 0x9EAC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EBD, 0x0000, 0x0000, 0x0000, 0x93CC, 0x0000, + 0x9EA2, 0x0000, 0x0000, 0x9EB9, 0x0000, 0x0000, + 0x0000, 0x9EBB, 0x0000, 0x92D6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x976B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9596, + 0x9EB6, 0x91C8, 0x0000, 0x0000, 0x0000, 0x9EBC, + 0x915E, 0x0000, 0x9EB3, 0x9EC0, 0x9EBF, 0x0000, + 0x93ED, 0x9EBE, 0x93E8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9EC2, 0x9EB5, + 0x0000, 0x8BC6, 0x9EB8, 0x8F7C, 0x0000, 0x0000, + 0x0000, 0x9480, 0x9EBA, 0x8BC9, 0x0000, 0x9EB2, + 0x9EB4, 0x9EB1, 0x0000, 0x0000, 0x984F, 0x8A79, + 0x9EB7, 0x0000, 0x0000, 0x9EC1, 0x8A54, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8DE5, 0x0000, 0x0000, 0x0000, 0x897C, 0x0000, + 0x0000, 0x9ED2, 0x0000, 0x0000, 0x9850, 0x9ED5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9059, + 0x9ED4, 0x0000, 0x0000, 0x0000, 0x9ED3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9ED0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EC4, 0x0000, 0x0000, 0x9EE1, 0x9EC3, 0x0000, + 0x9ED6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9ECE, 0x0000, 0x0000, 0x9EC9, 0x9EC6, + 0x0000, 0x9EC7, 0x0000, 0x9ECF, 0x0000, 0x0000, + 0x0000, 0xEAA0, 0x0000, 0x0000, 0x9ECC, 0x8D5C, + 0x92C6, 0x9184, 0x9ECA, 0x0000, 0x9EC5, 0x0000, + 0x0000, 0x9EC8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x976C, 0x968A, 0x0000, 0x0000, 0x0000, 0x9ECD, + 0x9ED7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EDF, 0x9ED8, 0x0000, + 0x0000, 0x9EE5, 0x0000, 0x9EE3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9EDE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EDD, 0x0000, 0x92CE, + 0x0000, 0x9185, 0x0000, 0x9EDB +}; + +static u16 Ucs6A[256] = { + 0x0000, 0x0000, 0x9ED9, 0x0000, 0x0000, 0x9EE0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9EE6, 0x94F3, + 0x9EEC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EE7, 0x9EEA, 0x9EE4, 0x0000, 0x0000, 0x9294, + 0x0000, 0x9557, 0x0000, 0x9EDA, 0x0000, 0x0000, + 0x9EE2, 0x8FBE, 0x0000, 0x96CD, 0x9EF6, 0x9EE9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8CA0, + 0x89A1, 0x8A7E, 0x0000, 0x0000, 0x9ED1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8FBF, + 0x9EEE, 0x0000, 0x9EF5, 0x8EF7, 0x8A92, 0x0000, + 0x0000, 0x924D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9EEB, 0x0000, 0x0000, 0x9EF0, + 0x9EF4, 0x0000, 0x0000, 0x8BB4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8B6B, 0x9EF2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B40, + 0x0000, 0x93C9, 0x9EF1, 0x0000, 0x0000, 0x0000, + 0x9EF3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EED, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A80, 0x9268, 0x0000, 0x0000, 0x0000, + 0x9EFA, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EF8, 0x8CE7, 0x0000, + 0x9EF7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F40, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9E77, 0x0000, 0x0000, 0x0000, 0x9EF9, 0x0000, + 0x9EFB, 0x9EFC, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F4B, 0x0000, 0x9F47, 0x0000, + 0x9E8D, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9F45, 0x0000, + 0x0000, 0x9F42, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9EE8, 0x9F44, 0x9F43, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F49, + 0x0000, 0x9845, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F4C, 0x8BF9, 0x0000, 0x0000, + 0x9F48, 0x9F4A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x94A5, 0x0000, + 0x9F4D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9F51, 0x9F4E, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs6B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x9793, 0x9F4F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9EDC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9F52, 0x0000, 0x0000, 0x0000, 0x9F53, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8954, + 0x0000, 0x9F55, 0x8C87, 0x8E9F, 0x0000, 0x8BD3, + 0x0000, 0x0000, 0x0000, 0x89A2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x977E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F57, 0x9F56, 0x9F59, 0x8B5C, 0x0000, + 0x0000, 0x8BD4, 0x8ABC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F5C, 0x0000, 0x0000, 0x0000, 0x9F5B, + 0x0000, 0x9F5D, 0x0000, 0x0000, 0x89CC, 0x0000, + 0x9256, 0x0000, 0x9F5E, 0x0000, 0x0000, 0x8ABD, + 0x9F60, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F5F, + 0x0000, 0x9F61, 0x0000, 0x0000, 0x0000, 0x9F62, + 0x0000, 0x9F63, 0x8E7E, 0x90B3, 0x8D9F, 0x0000, + 0x9590, 0x0000, 0x0000, 0x95E0, 0x9863, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8E95, 0x0000, 0x0000, + 0x0000, 0x8DCE, 0x97F0, 0x0000, 0x0000, 0x0000, + 0x9F64, 0x9F65, 0x0000, 0x8E80, 0x0000, 0x0000, + 0x0000, 0x9F66, 0x9F67, 0x0000, 0x0000, 0x9F69, + 0x9F68, 0x0000, 0x9677, 0x0000, 0x0000, 0x8F7D, + 0x8EEA, 0x8E63, 0x0000, 0x9F6A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F6C, + 0x9042, 0x0000, 0x9F6B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F6D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F6E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F6F, 0x9F70, 0x0000, 0x0000, + 0x0000, 0x9F71, 0x0000, 0x9F73, 0x9F72, 0x9F74, + 0x89A3, 0x9269, 0x0000, 0x9F75, 0x0000, 0x0000, + 0x8E45, 0x8A6B, 0x9F76, 0x0000, 0x0000, 0x9361, + 0x9ACA, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B42, + 0x9F77, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F78, + 0x0000, 0x95EA, 0x9688, 0x0000, 0x0000, 0x0000, + 0x93C5, 0x9F79, 0x94E4, 0x0000, 0x0000, 0x0000, + 0x94F9, 0x0000, 0x0000, 0x96D1, 0x0000, 0x0000, + 0x0000, 0x9F7A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F7C, 0x9F7B, 0x0000, 0x0000, 0x9F7E, + 0x0000, 0x0000, 0x0000, 0x9F7D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs6C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F81, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8E81, 0x0000, 0x96AF, + 0x0000, 0x9F82, 0x9F83, 0x0000, 0x0000, 0x8B43, + 0x0000, 0x0000, 0x0000, 0x9F84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F86, + 0x9F85, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9085, 0x0000, + 0x0000, 0x9558, 0x8969, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x94C3, 0x0000, 0x92F3, 0x8F60, + 0x8B81, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94C4, 0x0000, 0x8EAC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F88, 0x0000, 0x8ABE, 0x0000, 0x0000, + 0x8998, 0x0000, 0x0000, 0x93F0, 0x9F87, 0x8D5D, + 0x9272, 0x0000, 0x9F89, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F91, 0x0000, 0x9F8A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91BF, 0x0000, + 0x8B82, 0x9F92, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C88, 0x0000, 0x0000, 0x8B44, + 0x9F90, 0x0000, 0x0000, 0x9F8E, 0x9F8B, 0x9780, + 0x0000, 0x0000, 0x0000, 0x0000, 0x92BE, 0x0000, + 0x0000, 0x0000, 0x93D7, 0x9F8C, 0x0000, 0x0000, + 0x9F94, 0x0000, 0x9F93, 0x8C42, 0x0000, 0x0000, + 0x89AB, 0x0000, 0x0000, 0x8DB9, 0x9F8D, 0x9F8F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9676, + 0x91F2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9697, 0x0000, 0x0000, + 0x9F9C, 0x0000, 0x0000, 0x9F9D, 0x0000, 0x89CD, + 0x0000, 0x0000, 0x0000, 0x0000, 0x95A6, 0x96FB, + 0x9F9F, 0x8EA1, 0x8FC0, 0x9F98, 0x9F9E, 0x8988, + 0x0000, 0x8BB5, 0x0000, 0x0000, 0x9F95, 0x9F9A, + 0x0000, 0x0000, 0x0000, 0x90F2, 0x9491, 0x0000, + 0x94E5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F97, 0x0000, 0x9640, 0x0000, 0x9F99, + 0x0000, 0x9FA2, 0x0000, 0x9FA0, 0x0000, 0x9F9B, + 0x0000, 0x0000, 0x0000, 0x9641, 0x9467, 0x8B83, + 0x0000, 0x9344, 0x0000, 0x0000, 0x928D, 0x0000, + 0x9FA3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FA1, + 0x91D7, 0x9F96, 0x0000, 0x896A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs6D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x976D, + 0x9FAE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9FAD, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F4, + 0x0000, 0x9FAA, 0x0000, 0x978C, 0x0000, 0x0000, + 0x93B4, 0x9FA4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92C3, 0x0000, 0x0000, 0x0000, 0x896B, + 0x8D5E, 0x9FA7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8F46, 0x9FAC, 0x0000, 0x9FAB, + 0x9FA6, 0x0000, 0x9FA9, 0x0000, 0x0000, 0x8A88, + 0x0000, 0x9FA8, 0x9468, 0x0000, 0x0000, 0x97AC, + 0x0000, 0x0000, 0x8FF2, 0x90F3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FB4, + 0x9FB2, 0x0000, 0x956C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9FAF, 0x9FB1, 0x0000, + 0x8959, 0x0000, 0x0000, 0x8D5F, 0x9851, 0x0000, + 0x8A5C, 0x0000, 0x9582, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9781, 0x0000, 0x0000, 0x8A43, + 0x905A, 0x9FB3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9FB8, 0x0000, 0x0000, 0x8FC1, 0x0000, + 0x0000, 0x0000, 0x974F, 0x0000, 0x9FB5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9FB0, 0x0000, 0x9FB6, + 0x0000, 0x0000, 0x0000, 0x97DC, 0x0000, 0x9393, + 0x93C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A55, 0x0000, 0x0000, 0x8974, 0x0000, + 0x0000, 0x9FBC, 0x0000, 0x0000, 0x9FBF, 0x0000, + 0x0000, 0x0000, 0x97C1, 0x0000, 0x0000, 0x0000, + 0x9784, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FC6, + 0x9FC0, 0x9FBD, 0x0000, 0x0000, 0x0000, 0x97D2, + 0x9FC3, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F69, + 0x9FC5, 0x0000, 0x0000, 0x9FCA, 0x0000, 0x0000, + 0x9391, 0x9FC8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9FC2, 0x0000, 0x0000, 0x9257, 0x0000, 0x0000, + 0x9FC9, 0x0000, 0x9FBE, 0x0000, 0x9FC4, 0x0000, + 0x9FCB, 0x88FA, 0x9FC1, 0x0000, 0x9FCC, 0x0000, + 0x0000, 0x905B, 0x0000, 0x8F7E, 0x0000, 0x95A3, + 0x0000, 0x8DAC, 0x0000, 0x9FB9, 0x9FC7, 0x9359, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs6E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90B4, + 0x0000, 0x8A89, 0x8DCF, 0x8FC2, 0x9FBB, 0x8F61, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8C6B, 0x0000, 0x9FBA, 0x0000, 0x0000, + 0x0000, 0x9FD0, 0x8F8D, 0x8CB8, 0x0000, 0x9FDF, + 0x0000, 0x9FD9, 0x8B94, 0x936E, 0x0000, 0x9FD4, + 0x9FDD, 0x88AD, 0x8951, 0x0000, 0x0000, 0x89B7, + 0x0000, 0x9FD6, 0x91AA, 0x9FCD, 0x9FCF, 0x8D60, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FE0, 0x0000, 0x9FDB, 0x0000, + 0x0000, 0x0000, 0x9FD3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9FDA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x96A9, 0x0000, 0x0000, 0x9FD8, + 0x9FDC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8CCE, 0x0000, 0x8FC3, 0x0000, + 0x0000, 0x9258, 0x0000, 0x0000, 0x0000, 0x9FD2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x974E, 0x0000, 0x0000, 0x0000, 0x9FD5, + 0x0000, 0x0000, 0x9FCE, 0x9392, 0x0000, 0x0000, + 0x9FD1, 0x0000, 0x0000, 0x0000, 0x9FD7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9870, 0x8EBC, 0x969E, 0x0000, 0x9FE1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x94AC, 0x0000, 0x0000, 0x9FED, + 0x8CB9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F80, 0x0000, 0x9FE3, 0x0000, 0x0000, 0x0000, + 0x97AD, 0x8D61, 0x0000, 0x9FF0, 0x0000, 0x0000, + 0x88EC, 0x0000, 0x0000, 0x9FEE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FE2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9FE8, 0x0000, 0x0000, 0x9FEA, 0x0000, + 0x0000, 0x0000, 0x976E, 0x9FE5, 0x0000, 0x0000, + 0x934D, 0x0000, 0x0000, 0x9FE7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FEF, 0x0000, 0x9FE9, 0x96C5, + 0x0000, 0x0000, 0x0000, 0x9FE4, 0x0000, 0x8EA0, + 0x9FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A8A, + 0x0000, 0x9FE6, 0x9FEB, 0x9FEC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91EA, + 0x91D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FF4, 0x0000, 0x0000, 0x9FFA, + 0x0000, 0x0000, 0x9FF8, 0x0000, 0x9348, 0x0000, + 0x0000, 0xE042, 0x9FF5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FF6, 0x9FDE +}; + +static u16 Ucs6F[256] = { + 0x0000, 0x8B99, 0x9559, 0x0000, 0x0000, 0x0000, + 0x8EBD, 0x0000, 0x0000, 0x8D97, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9852, 0x0000, 0x9FF2, + 0x0000, 0xE041, 0x8989, 0x9186, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9499, 0x0000, 0x8ABF, 0x97F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x969F, 0x92D0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9FF9, 0x9FFB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9151, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE040, 0x9FF7, 0x0000, 0x9FF1, + 0x0000, 0x0000, 0x0000, 0x8AC1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C89, 0x0000, 0x0000, 0x0000, 0xE04E, 0x0000, + 0x0000, 0xE049, 0x90F6, 0x0000, 0x0000, 0x8A83, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8F81, 0x0000, + 0xE052, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE04B, 0x92AA, 0xE048, 0x92D7, 0x0000, + 0x0000, 0x0000, 0xE06B, 0x0000, 0x0000, 0x0000, + 0xE045, 0x0000, 0xE044, 0x0000, 0xE04D, 0x0000, + 0x0000, 0x0000, 0xE047, 0xE046, 0xE04C, 0x0000, + 0x909F, 0x0000, 0xE043, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE04F, 0x0000, + 0x0000, 0xE050, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8AC0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE055, + 0x0000, 0xE054, 0xE056, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE059, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9362, 0x0000, 0xE053, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE057, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C83, 0x91F7, 0xE051, 0x945A, 0x0000, 0x0000, + 0xE058, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE05D, 0xE05B, 0x0000, 0x0000, + 0xE05E, 0x0000, 0x0000, 0xE061, 0x0000, 0x0000, + 0x0000, 0xE05A, 0x8D8A, 0x9447, 0x0000, 0x0000, + 0x9FB7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9794, 0xE05C, 0x0000, 0xE060, 0x91F3, + 0x0000, 0xE05F, 0x0000, 0xE04A, 0x0000, 0x0000, + 0xE889, 0x0000, 0x0000, 0x0000, 0xE064, 0x0000, + 0x0000, 0x0000, 0xE068, 0x0000 +}; + +static u16 Ucs70[256] = { + 0x0000, 0xE066, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE062, 0x0000, 0xE063, + 0x0000, 0x0000, 0x0000, 0xE067, 0x0000, 0xE065, + 0x0000, 0x0000, 0x0000, 0x956D, 0x0000, 0x0000, + 0xE06D, 0x0000, 0xE06A, 0xE069, 0x0000, 0xE06C, + 0x93D2, 0xE06E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9295, 0x91EB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x90A3, 0x0000, 0x0000, 0x0000, + 0xE06F, 0x0000, 0xE071, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE070, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9FF3, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE072, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x93E5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE073, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89CE, + 0x0000, 0x0000, 0x0000, 0x9394, 0x8A44, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8B84, 0x0000, 0x0000, 0x0000, 0x8EDC, 0x8DD0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9846, + 0x9086, 0x0000, 0x0000, 0x0000, 0x898A, 0x0000, + 0x0000, 0x0000, 0xE075, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE074, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE078, 0x9259, + 0xE07B, 0xE076, 0x0000, 0x0000, 0x0000, 0xE07A, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE079, 0x935F, + 0x88D7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x97F3, 0x0000, 0x0000, 0xE07D, + 0x0000, 0x0000, 0x0000, 0x8947, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE080, 0x0000, 0x0000, 0x0000, 0xE07E, + 0x0000, 0xE07C, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE077, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9642, 0x0000, 0x0000, + 0x0000, 0xE082, 0x0000, 0x0000 +}; + +static u16 Ucs71[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE081, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x898B, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE084, 0x95B0, 0x0000, 0xE083, 0x0000, + 0x0000, 0x0000, 0x0000, 0x96B3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8FC5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9152, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8FC4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x97F9, 0x0000, 0x0000, 0xE08A, 0x0000, + 0x90F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE086, 0xE08B, 0x0000, 0x0000, 0x898C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE089, 0x0000, 0x9481, 0xE085, + 0xE088, 0x8FC6, 0x0000, 0x94CF, 0x0000, 0x0000, + 0xE08C, 0x0000, 0x8ECF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE08F, 0x0000, 0x0000, 0x0000, 0xE087, 0x0000, + 0x8C46, 0x0000, 0x0000, 0x0000, 0x0000, 0xE08D, + 0x0000, 0x0000, 0x0000, 0x0000, 0x976F, 0xE090, + 0x0000, 0x0000, 0x0000, 0xEAA4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8F6E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE091, 0x0000, 0x0000, 0x0000, 0xE092, 0x0000, + 0x0000, 0x0000, 0x0000, 0x944D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE094, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE095, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9452, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9395, 0xE097, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE099, 0x0000, 0x97D3, 0x0000, + 0xE096, 0x0000, 0xE098, 0x898D, 0x0000, 0xE093, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9A7A, 0xE09A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9187, 0x8E57, 0xE09C, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE09B, 0x9043, 0x99D7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE09D, + 0x0000, 0x0000, 0x0000, 0xE09F, 0x0000, 0xE08E, + 0xE09E, 0x0000, 0x0000, 0xE0A0 +}; + +static u16 Ucs72[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x949A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0A1, 0x0000, 0x0000, 0xE0A2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0A3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0A4, 0x0000, + 0x92DC, 0x0000, 0xE0A6, 0xE0A5, 0x0000, 0x0000, + 0xE0A7, 0x0000, 0xE0A8, 0x0000, 0x0000, 0x8EDD, + 0x9583, 0x0000, 0x0000, 0x0000, 0x96EA, 0xE0A9, + 0xE0AA, 0x9175, 0x8EA2, 0xE0AB, 0xE0AC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0AD, 0x95D0, + 0x94C5, 0x0000, 0x0000, 0xE0AE, 0x9476, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x92AB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0AF, 0x89E5, + 0x0000, 0x8B8D, 0x0000, 0x96C4, 0x0000, 0x96B4, + 0x0000, 0x89B2, 0x9853, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9671, 0x0000, 0x95A8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x90B5, 0x0000, 0xE0B0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93C1, 0x0000, 0x0000, 0x0000, 0x8CA1, + 0xE0B1, 0x0000, 0x8DD2, 0xE0B3, 0xE0B2, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0B4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0B5, 0x0000, 0x0000, 0x0000, + 0xE0B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8B5D, 0x0000, + 0xE0B7, 0x0000, 0x0000, 0x0000, 0x0000, 0xE0B8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8CA2, 0x0000, + 0x0000, 0x94C6, 0x0000, 0x0000, 0xE0BA, 0x0000, + 0x0000, 0x0000, 0x8FF3, 0x0000, 0x0000, 0xE0B9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8BB6, 0xE0BB, 0xE0BD, 0x0000, + 0xE0BC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0BE, 0x0000, 0x8CCF, 0x0000, + 0xE0BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BE7, + 0x0000, 0x915F, 0x0000, 0x8D9D, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0C1, 0xE0C2, 0xE0C0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EEB, + 0x0000, 0x0000, 0x93C6, 0x8BB7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0C4, 0x924B, 0xE0C3, 0x0000, 0x0000, + 0x9854, 0x9482, 0x0000, 0x0000 +}; + +static u16 Ucs73[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0C7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0C9, 0xE0C6, + 0x0000, 0x0000, 0x0000, 0x96D2, 0xE0C8, 0xE0CA, + 0x0000, 0x97C2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0CE, 0x0000, 0x0000, 0x0000, 0xE0CD, + 0x9296, 0x944C, 0x0000, 0x0000, 0x8CA3, 0xE0CC, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0CB, 0x0000, + 0x9750, 0x9751, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0CF, 0x898E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8D96, 0x8E82, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE0D0, 0xE0D1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0D3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8F62, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0D5, 0x0000, 0xE0D4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0D6, 0x0000, + 0x8A6C, 0x0000, 0x0000, 0xE0D8, 0x0000, 0x0000, + 0xE0D7, 0x0000, 0xE0DA, 0xE0D9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8CBA, 0x0000, 0x0000, 0x97A6, 0x0000, 0x8BCA, + 0x0000, 0x89A4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8BE8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8ADF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x97E6, 0xE0DC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0DE, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE0DF, 0x0000, 0x89CF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0DB, 0x0000, 0x8E58, 0x0000, + 0x0000, 0x92BF, 0xE0DD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE0E2, 0x0000, 0x8EEC, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C5D, 0x0000, 0x0000, 0x94C7, 0xE0E1, 0x0000, + 0x0000, 0xE0FC, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0E7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8CBB, 0x0000 +}; + +static u16 Ucs74[256] = { + 0x0000, 0x0000, 0x0000, 0x8B85, 0x0000, 0xE0E4, + 0x979D, 0x0000, 0x0000, 0x97AE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91F4, 0x0000, + 0x0000, 0xE0E6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0E8, 0x97D4, 0x8BD5, 0x94FA, + 0x9469, 0x0000, 0x0000, 0x0000, 0xE0E9, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0EB, 0x0000, 0xE0EE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0EA, 0x0000, 0x0000, 0x0000, 0xE0ED, + 0x8CE8, 0x896C, 0xE0EF, 0x0000, 0x9090, 0xE0EC, + 0x97DA, 0x0000, 0x0000, 0xE0F2, 0xEAA2, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0F0, 0xE0F3, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0E5, 0xE0F1, 0x0000, + 0x0000, 0x8DBA, 0x0000, 0x0000, 0xE0F4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE0F5, 0x0000, 0x0000, 0x0000, 0x0000, 0x979E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0F6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0F7, 0x0000, 0x0000, 0x0000, + 0xE0E3, 0x0000, 0x0000, 0x0000, 0x0000, 0xE0F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8AC2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8EA3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0F9, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0FA, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0FB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x895A, 0x0000, + 0x0000, 0x0000, 0xE140, 0x0000, 0x955A, 0xE141, + 0x0000, 0x0000, 0x8AA2, 0xE142, 0x0000, 0xE143, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE144, 0x0000, + 0xE146, 0xE147, 0xE145, 0x0000, 0x0000, 0x0000, + 0x9572, 0xE149, 0xE148, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs75[256] = { + 0x0000, 0x0000, 0x0000, 0xE14B, 0xE14A, 0xE14C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE14D, 0xE14F, 0xE14E, 0x0000, 0x0000, 0x8D99, + 0x0000, 0xE151, 0x0000, 0xE150, 0x0000, 0x0000, + 0x8AC3, 0x0000, 0x9072, 0x0000, 0x935B, 0x0000, + 0xE152, 0x90B6, 0x0000, 0x0000, 0x0000, 0x8E59, + 0x0000, 0x8999, 0xE153, 0x0000, 0x9770, 0x0000, + 0x0000, 0x95E1, 0xE154, 0x0000, 0x0000, 0x0000, + 0x9363, 0x9752, 0x8D62, 0x905C, 0x0000, 0x0000, + 0x0000, 0x926A, 0x99B2, 0x0000, 0x92AC, 0x89E6, + 0xE155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE156, 0x0000, 0xE15B, 0x0000, + 0x0000, 0xE159, 0xE158, 0x9DC0, 0x8A45, 0xE157, + 0x0000, 0x88D8, 0x0000, 0x94A8, 0x0000, 0x0000, + 0x94C8, 0x0000, 0x0000, 0x0000, 0x0000, 0x97AF, + 0xE15C, 0xE15A, 0x927B, 0x90A4, 0x0000, 0x0000, + 0x94A9, 0x0000, 0x954C, 0x0000, 0xE15E, 0x97AA, + 0x8C6C, 0xE15F, 0x0000, 0xE15D, 0x94D4, 0xE160, + 0x0000, 0xE161, 0x0000, 0x0000, 0x88D9, 0x0000, + 0x0000, 0x8FF4, 0xE166, 0x0000, 0xE163, 0x93EB, + 0xE162, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8B45, 0x0000, 0x0000, 0xE169, 0x0000, + 0x0000, 0x0000, 0xE164, 0xE165, 0x0000, 0xE168, + 0xE167, 0x9544, 0x0000, 0x0000, 0x9161, 0x9160, + 0x0000, 0x8B5E, 0x0000, 0x0000, 0xE16A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE16B, 0x0000, + 0x0000, 0xE16C, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE16E, 0x0000, 0xE16D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8975, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE176, 0x94E6, 0xE170, + 0x0000, 0xE172, 0x0000, 0x0000, 0xE174, 0x905D, + 0x0000, 0x0000, 0xE175, 0xE173, 0x8EBE, 0x0000, + 0x0000, 0x0000, 0xE16F, 0xE171, 0x0000, 0x9561, + 0x0000, 0x8FC7, 0x0000, 0x0000, 0xE178, 0x0000, + 0x0000, 0xE177, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE179, 0x0000, 0x8EA4, 0x8DAD, 0x0000, 0x0000, + 0x9397, 0xE17A, 0x0000, 0x92C9, 0x0000, 0x0000, + 0xE17C, 0x0000, 0x0000, 0x0000, 0x979F, 0xE17B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9189, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE182, 0x0000, 0xE184, 0xE185, 0x9273, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE183, 0x0000, + 0xE180, 0x0000, 0xE17D, 0xE17E +}; + +static u16 Ucs76[256] = { + 0x0000, 0xE181, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE188, 0x0000, 0xE186, + 0x0000, 0xE187, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE189, 0xE18B, 0xE18C, 0xE18D, 0x0000, + 0xE18E, 0x0000, 0x0000, 0xE18A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE190, 0x0000, 0x0000, 0x0000, 0xE18F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE191, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x97C3, 0x0000, 0x0000, 0x0000, 0xE194, 0xE192, + 0xE193, 0x0000, 0x0000, 0x0000, 0x8AE0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x96FC, 0x0000, + 0x0000, 0x0000, 0x95C8, 0x0000, 0xE196, 0x0000, + 0x0000, 0x0000, 0xE195, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE197, 0xE198, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE19C, 0xE199, 0xE19A, 0xE19B, 0x0000, + 0xE19D, 0x0000, 0x0000, 0x0000, 0xE19E, 0x0000, + 0xE19F, 0x0000, 0x0000, 0x0000, 0xE1A0, 0x0000, + 0xE1A1, 0x0000, 0x94AD, 0x936F, 0xE1A2, 0x9492, + 0x9553, 0x0000, 0xE1A3, 0x0000, 0x0000, 0xE1A4, + 0x9349, 0x0000, 0x8A46, 0x8D63, 0xE1A5, 0x0000, + 0x0000, 0xE1A6, 0x0000, 0x0000, 0xE1A7, 0x0000, + 0x8E48, 0x0000, 0x0000, 0xE1A9, 0x0000, 0x0000, + 0xE1A8, 0x0000, 0x0000, 0xE1AA, 0xE1AB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94E7, 0x0000, 0xE1AC, 0x0000, 0x0000, 0x0000, + 0xE1AD, 0x0000, 0x0000, 0xEA89, 0xE1AE, 0xE1AF, + 0xE1B0, 0x0000, 0x0000, 0x0000, 0x0000, 0x8E4D, + 0x0000, 0x0000, 0xE1B1, 0x9475, 0x0000, 0x0000, + 0x967E, 0x0000, 0x896D, 0x0000, 0x8976, 0x0000, + 0x0000, 0xE1B2, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1B4, 0x0000, 0x0000, 0x0000, 0xE1B3, 0x9390, + 0x0000, 0x0000, 0x0000, 0x90B7, 0x9F58, 0x0000, + 0xE1B5, 0x96BF, 0x0000, 0xE1B6, 0x0000, 0x8AC4, + 0x94D5, 0xE1B7, 0x0000, 0xE1B8, 0x0000, 0x0000, + 0xE1B9, 0x0000, 0x0000, 0x0000, 0x96DA, 0x0000, + 0x0000, 0x0000, 0x96D3, 0x0000, 0x92BC, 0x0000, + 0x0000, 0x0000, 0x918A, 0x0000, 0x0000, 0xE1BB, + 0x0000, 0x0000, 0x8F82, 0x0000 +}; + +static u16 Ucs77[256] = { + 0x0000, 0x8FC8, 0x0000, 0x0000, 0xE1BE, 0x0000, + 0x0000, 0xE1BD, 0xE1BC, 0x94FB, 0x0000, 0x8AC5, + 0x8CA7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE1C4, 0x0000, 0x0000, + 0xE1C1, 0x905E, 0x96B0, 0x0000, 0x0000, 0x0000, + 0xE1C0, 0xE1C2, 0xE1C3, 0x0000, 0x0000, 0xE1BF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1C5, 0xE1C6, 0x0000, 0x92AD, 0x0000, + 0x8AE1, 0x0000, 0x0000, 0x0000, 0x9285, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE1C7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1C8, 0xE1CB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9087, 0x0000, 0x93C2, 0x0000, 0xE1CC, + 0x9672, 0x0000, 0xE1C9, 0x0000, 0x0000, 0xE1CA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1CF, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1CE, 0xE1CD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1D1, 0x0000, 0x0000, 0xE1D0, 0x0000, + 0x0000, 0xE1D2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1D4, 0x0000, 0xE1D3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x95CB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8F75, 0x97C4, + 0x0000, 0x0000, 0xE1D5, 0x0000, 0x0000, 0x93B5, + 0x0000, 0x0000, 0xE1D6, 0x0000, 0x0000, 0xE1D7, + 0x0000, 0xE1DB, 0xE1D9, 0xE1DA, 0x0000, 0xE1D8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1DC, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1DD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE1DE, + 0x0000, 0x0000, 0xE1DF, 0x96B5, 0xE1E0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x96EE, 0xE1E1, + 0x0000, 0x926D, 0x0000, 0x948A, 0x0000, 0x8BE9, + 0x0000, 0x0000, 0x0000, 0x925A, 0xE1E2, 0x8BB8, + 0x0000, 0x0000, 0x0000, 0x90CE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1E3, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs78[256] = { + 0x0000, 0x0000, 0x8DBB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1E5, 0x0000, 0x8CA4, 0x8DD3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1E7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9375, 0x8DD4, 0x8B6D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9643, 0x0000, 0x946A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9376, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8D7B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE1E9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8FC9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x97B0, + 0x8D64, 0x0000, 0x0000, 0x8CA5, 0x0000, 0x0000, + 0x94A1, 0x0000, 0xE1EB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE1ED, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8CE9, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1EC, 0x92F4, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1EF, 0x8A56, 0xE1EA, 0x0000, + 0x0000, 0x94E8, 0x0000, 0x894F, 0x0000, 0x8DEA, + 0x0000, 0x9871, 0x0000, 0x0000, 0xE1EE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1F0, 0x0000, 0x0000, 0x0000, 0x95C9, + 0x0000, 0x90D7, 0xE1F2, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1F3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1F1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8A6D, 0x0000, 0xE1F9, 0x0000, 0xE1F8, 0x0000, + 0x0000, 0x8EA5, 0x0000, 0x0000, 0x0000, 0xE1FA, + 0xE1F5, 0x0000, 0x0000, 0x0000, 0xE1FB, 0xE1F6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x94D6, 0xE1F4, + 0x0000, 0x0000, 0xE1F7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE241, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE240, 0x9681, 0x0000, + 0x0000, 0x0000, 0xE1FC, 0x0000, 0x0000, 0x88E9, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE243, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE242, 0x0000, 0x0000 +}; + +static u16 Ucs79[256] = { + 0x0000, 0x8FCA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE244, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9162, 0x0000, 0x0000, 0xE246, + 0xE245, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE247, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1E6, 0x0000, 0x0000, 0x0000, + 0xE1E8, 0xE249, 0xE248, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8EA6, 0x0000, + 0x97E7, 0x0000, 0x8ED0, 0x0000, 0xE24A, 0x8C56, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B5F, + 0x8B46, 0x8E83, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9753, 0x0000, 0x0000, 0xE250, + 0x0000, 0xE24F, 0x9163, 0xE24C, 0x0000, 0x0000, + 0xE24E, 0x0000, 0x0000, 0x8F6A, 0x905F, 0xE24D, + 0xE24B, 0x0000, 0x9449, 0x0000, 0x0000, 0x8FCB, + 0x0000, 0x0000, 0x955B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8DD5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9398, + 0x0000, 0x0000, 0xE251, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE252, 0xE268, 0x8BD6, 0x0000, 0x0000, + 0x985C, 0x9154, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE253, 0x0000, 0x0000, 0x89D0, 0x92F5, 0x959F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE254, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8B9A, 0xE255, + 0x0000, 0x0000, 0xE257, 0x0000, 0x0000, 0x0000, + 0xE258, 0x0000, 0x9448, 0x0000, 0x0000, 0xE259, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE25A, + 0xE25B, 0x0000, 0x0000, 0x8BD7, 0x89D1, 0x93C3, + 0x8F47, 0x8E84, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE25C, 0x0000, 0x8F48, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89C8, + 0x9562, 0x0000, 0x0000, 0xE25D, 0x0000, 0x0000, + 0x94E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9164, 0x0000, 0xE260, 0x0000, 0xE261, + 0x9489, 0x0000, 0x9060, 0xE25E, 0x0000, 0x9281, + 0x0000, 0x0000, 0xE25F, 0x0000, 0x0000, 0x0000, + 0x8FCC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x88DA, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs7A[256] = { + 0x8B48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE262, 0x0000, 0x0000, 0x92F6, + 0x0000, 0xE263, 0x90C5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x96AB, 0x0000, 0x0000, 0x9542, + 0xE264, 0xE265, 0x9274, 0x0000, 0x97C5, 0x0000, + 0x0000, 0xE267, 0xE266, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8EED, 0x0000, + 0x0000, 0xE269, 0x88EE, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE26C, 0x0000, 0x0000, 0x0000, 0xE26A, + 0x89D2, 0x8C6D, 0xE26B, 0x8D65, 0x8D92, 0x0000, + 0x95E4, 0xE26D, 0x0000, 0x0000, 0x9673, 0x0000, + 0x0000, 0xE26F, 0x0000, 0x0000, 0x0000, 0x90CF, + 0x896E, 0x89B8, 0x88AA, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE26E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE270, 0xE271, 0x8FF5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE272, 0x0000, 0x8A6E, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE274, 0x0000, + 0x0000, 0x0000, 0x8C8A, 0x0000, 0x8B86, 0x0000, + 0x0000, 0xE275, 0x8BF3, 0x0000, 0x0000, 0xE276, + 0x0000, 0x90FA, 0x0000, 0x93CB, 0x0000, 0x90DE, + 0x8DF3, 0x0000, 0x0000, 0x0000, 0xE277, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9282, 0x918B, 0x0000, 0xE279, + 0xE27B, 0xE278, 0xE27A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C41, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE27C, 0x8C45, 0x0000, 0x0000, 0x0000, + 0x8B87, 0x9771, 0xE27E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE280, 0x0000, 0x0000, 0x0000, + 0x894D, 0x0000, 0x0000, 0x0000, 0x0000, 0xE283, + 0x0000, 0x0000, 0x0000, 0x8A96, 0xE282, 0xE281, + 0x0000, 0xE285, 0xE27D, 0x0000, 0xE286, 0x97A7, + 0x0000, 0xE287, 0x0000, 0xE288, 0x0000, 0x0000, + 0x9AF2, 0xE28A, 0x0000, 0xE289, 0x0000, 0x0000, + 0x0000, 0xE28B, 0xE28C, 0x0000, 0x97B3, 0xE28D, + 0x0000, 0xE8ED, 0x8FCD, 0xE28E, 0xE28F, 0x8F76, + 0x0000, 0x93B6, 0xE290, 0x0000, 0x0000, 0x0000, + 0x9247, 0x0000, 0x0000, 0xE291, 0x0000, 0x925B, + 0xE292, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8BA3, 0x0000, 0x995E, 0x927C, 0x8EB1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8AC6 +}; + +static u16 Ucs7B[256] = { + 0x0000, 0x0000, 0xE293, 0x0000, 0xE2A0, 0x0000, + 0xE296, 0x0000, 0x8B88, 0x0000, 0xE295, 0xE2A2, + 0x0000, 0x0000, 0x0000, 0xE294, 0x0000, 0x8FCE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE298, 0xE299, 0x0000, 0x934A, 0x0000, 0x0000, + 0xE29A, 0x0000, 0x8A7D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9079, 0x9584, 0x0000, 0xE29C, 0x0000, + 0x0000, 0x0000, 0x91E6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE297, 0x0000, 0xE29B, + 0xE29D, 0x0000, 0x0000, 0x8DF9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE2A4, 0x954D, 0x0000, + 0x94A4, 0x9399, 0x0000, 0x8BD8, 0xE2A3, 0xE2A1, + 0x0000, 0x94B3, 0xE29E, 0x927D, 0x939B, 0x0000, + 0x939A, 0x0000, 0x8DF4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE2B6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2A6, + 0x0000, 0xE2A8, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE2AB, 0x0000, 0xE2AC, 0x0000, 0xE2A9, 0xE2AA, + 0x0000, 0x0000, 0xE2A7, 0xE2A5, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE29F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95CD, 0x89D3, 0x0000, 0x0000, + 0x0000, 0xE2B3, 0x0000, 0xE2B0, 0x0000, 0xE2B5, + 0x0000, 0x0000, 0xE2B4, 0x0000, 0x9493, 0x96A5, + 0x0000, 0x8E5A, 0xE2AE, 0xE2B7, 0xE2B2, 0x0000, + 0xE2B1, 0xE2AD, 0x0000, 0xE2AF, 0x0000, 0x8AC7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x925C, 0x0000, 0x0000, 0x90FB, + 0x0000, 0x0000, 0x0000, 0x94A0, 0x0000, 0x0000, + 0xE2BC, 0x0000, 0x0000, 0x0000, 0x94A2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x90DF, 0xE2B9, 0x0000, 0x0000, 0x94CD, 0x0000, + 0xE2BD, 0x95D1, 0x0000, 0x927A, 0x0000, 0xE2B8, + 0xE2BA, 0x0000, 0x0000, 0xE2BB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2BE, + 0x0000, 0x0000, 0x8EC2, 0x0000, 0x0000, 0x0000, + 0x93C4, 0xE2C3, 0xE2C2, 0x0000, 0x0000, 0xE2BF, + 0x0000, 0x0000, 0x0000, 0x9855, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE2C8, 0x0000, 0x0000, + 0xE2CC, 0xE2C9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs7C[256] = { + 0xE2C5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2C6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2CB, 0x0000, 0x0000, 0x0000, 0xE2C0, + 0x99D3, 0xE2C7, 0xE2C1, 0x0000, 0x0000, 0xE2CA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2D0, 0x0000, 0x8AC8, 0x0000, 0xE2CD, + 0x0000, 0x0000, 0x0000, 0xE2CE, 0x0000, 0x0000, + 0xE2CF, 0xE2D2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2D1, 0x94F4, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2D3, 0x97FA, 0x95EB, 0xE2D8, 0x0000, + 0x0000, 0xE2D5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE2D4, 0x90D0, + 0x0000, 0xE2D7, 0xE2D9, 0x0000, 0x0000, 0x0000, + 0xE2D6, 0x0000, 0xE2DD, 0x0000, 0xE2DA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2DB, + 0xE2C4, 0x0000, 0x0000, 0x0000, 0xE2DC, 0xE2DE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE2DF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95C4, 0x0000, 0xE2E0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x96E0, 0x0000, 0x0000, 0x8BCC, 0x8C48, 0xE2E1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95B2, + 0x0000, 0x9088, 0x0000, 0x96AE, 0x0000, 0x0000, + 0xE2E2, 0x0000, 0x97B1, 0x0000, 0x0000, 0x9494, + 0x0000, 0x9165, 0x9453, 0x0000, 0x0000, 0x8F6C, + 0x0000, 0x0000, 0x0000, 0x88BE, 0x0000, 0xE2E7, + 0xE2E5, 0x0000, 0xE2E3, 0x8A9F, 0x0000, 0x8FCF, + 0xE2E8, 0x0000, 0x0000, 0xE2E6, 0x0000, 0xE2E4, + 0xE2EC, 0x0000, 0x0000, 0xE2EB, 0xE2EA, 0xE2E9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2ED, + 0x0000, 0x0000, 0x0000, 0xE2EE, 0x90B8, 0x0000, + 0xE2EF, 0x0000, 0xE2F1, 0x0000, 0x0000, 0xE2F0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8CD0, 0x0000, + 0x0000, 0x0000, 0x9157, 0x0000, 0x0000, 0x0000, + 0xE2F3, 0x0000, 0x0000, 0x0000, 0x939C, 0x0000, + 0xE2F2, 0x0000, 0x0000, 0x0000, 0xE2F4, 0x0000, + 0x95B3, 0x918C, 0x8D66, 0x0000, 0xE2F5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97C6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2F7, + 0x0000, 0x0000, 0xE2F8, 0x0000, 0xE2F9, 0x0000, + 0xE2FA, 0x0000, 0x8E85, 0x0000, 0xE2FB, 0x8C6E, + 0x0000, 0x0000, 0x8B8A, 0x0000 +}; + +static u16 Ucs7D[256] = { + 0x8B49, 0x0000, 0xE340, 0x0000, 0x96F1, 0x8D67, + 0xE2FC, 0x0000, 0x0000, 0x0000, 0xE343, 0x96E4, + 0x0000, 0x945B, 0x0000, 0x0000, 0x9552, 0x0000, + 0x0000, 0x0000, 0x8F83, 0xE342, 0x0000, 0x8ED1, + 0x8D68, 0x8E86, 0x8B89, 0x95B4, 0xE341, 0x0000, + 0x0000, 0x0000, 0x9166, 0x9661, 0x8DF5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8E87, 0x92DB, 0x0000, 0xE346, 0x97DD, + 0x8DD7, 0x0000, 0xE347, 0x9061, 0x0000, 0xE349, + 0x0000, 0x0000, 0x0000, 0x8FD0, 0x8DAE, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE348, 0x0000, 0x0000, + 0x8F49, 0x8CBC, 0x9167, 0xE344, 0xE34A, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE345, 0x8C6F, 0x0000, + 0xE34D, 0xE351, 0x8C8B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE34C, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE355, 0x0000, 0x0000, 0x8D69, 0x0000, + 0x0000, 0x978D, 0x88BA, 0xE352, 0x0000, 0x0000, + 0x8B8B, 0x0000, 0xE34F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE350, 0x0000, 0x0000, 0x939D, + 0xE34E, 0xE34B, 0x0000, 0x8A47, 0x90E2, 0x0000, + 0x0000, 0x8CA6, 0x0000, 0x0000, 0x0000, 0xE357, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE354, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE356, + 0x0000, 0x0000, 0x0000, 0xE353, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C70, 0x91B1, 0xE358, + 0x918E, 0x0000, 0x0000, 0xE365, 0x0000, 0x0000, + 0xE361, 0xE35B, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE35F, 0x8EF8, 0x88DB, + 0xE35A, 0xE362, 0xE366, 0x8D6A, 0x96D4, 0x0000, + 0x92D4, 0xE35C, 0x0000, 0x0000, 0xE364, 0x0000, + 0xE359, 0x925D, 0x0000, 0xE35E, 0x88BB, 0x96C8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE35D, 0x0000, 0x0000, 0x8BD9, 0x94EA, + 0x0000, 0x0000, 0x0000, 0x918D, 0x0000, 0x97CE, + 0x8F8F, 0x0000, 0x0000, 0xE38E, 0x0000, 0x0000, + 0xE367, 0x0000, 0x90FC, 0x0000, 0xE363, 0xE368, + 0xE36A, 0x0000, 0x92F7, 0xE36D, 0x0000, 0x0000, + 0xE369, 0x0000, 0x0000, 0x0000, 0x95D2, 0x8AC9, + 0x0000, 0x0000, 0x96C9, 0x0000, 0x0000, 0x88DC, + 0x0000, 0x0000, 0xE36C, 0x0000, 0x97FB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE36B, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs7E[256] = { + 0x0000, 0x898F, 0x0000, 0x0000, 0x93EA, 0xE36E, + 0x0000, 0x0000, 0x0000, 0xE375, 0xE36F, 0xE376, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE372, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x949B, 0x0000, 0x0000, + 0x8EC8, 0xE374, 0x0000, 0xE371, 0xE377, 0xE370, + 0x0000, 0x0000, 0x8F63, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9644, 0x0000, 0x0000, 0x8F6B, 0x0000, + 0x0000, 0xE373, 0xE380, 0x0000, 0x0000, 0xE37B, + 0x0000, 0xE37E, 0x0000, 0xE37C, 0xE381, 0xE37A, + 0x0000, 0xE360, 0x90D1, 0x0000, 0x0000, 0x94C9, + 0x0000, 0xE37D, 0x0000, 0x0000, 0xE378, 0x0000, + 0x0000, 0x0000, 0x9140, 0x8C71, 0x0000, 0x8F4A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9044, 0x9155, 0xE384, 0x0000, 0x0000, 0xE386, + 0xE387, 0x0000, 0x0000, 0xE383, 0xE385, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE379, 0xE382, 0x0000, 0xE38A, 0xE389, 0x0000, + 0x0000, 0x969A, 0x0000, 0x0000, 0x8C4A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE388, 0x0000, 0xE38C, 0xE38B, 0xE38F, + 0x0000, 0xE391, 0x0000, 0x0000, 0x8E5B, 0xE38D, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE392, 0xE393, + 0x0000, 0x0000, 0xE394, 0x0000, 0xE39A, 0x935A, + 0xE396, 0x0000, 0xE395, 0xE397, 0xE398, 0x0000, + 0xE399, 0x0000, 0x0000, 0x0000, 0x0000, 0xE39B, + 0xE39C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs7F[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8ACA, 0x0000, 0xE39D, 0x0000, 0xE39E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE39F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3A0, 0xE3A1, + 0xE3A2, 0x0000, 0xE3A3, 0xE3A4, 0x0000, 0x0000, + 0xE3A6, 0xE3A5, 0x0000, 0x0000, 0xE3A7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3A8, + 0xE3A9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE3AC, 0xE3AA, 0xE3AB, 0x8DDF, 0x8C72, + 0x0000, 0x0000, 0x9275, 0x0000, 0x94B1, 0x0000, + 0x8F90, 0x0000, 0x0000, 0x946C, 0x0000, 0x94EB, + 0xE3AD, 0x9CEB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3AE, 0xE3B0, + 0x0000, 0x9785, 0xE3AF, 0xE3B2, 0xE3B1, 0x0000, + 0x9772, 0x0000, 0xE3B3, 0x0000, 0x94FC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3B4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3B7, 0x0000, + 0x0000, 0xE3B6, 0xE3B5, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE3B8, 0x8C51, 0x0000, 0x0000, 0x0000, + 0x9141, 0x8B60, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE3BC, 0xE3B9, 0x0000, 0x0000, 0xE3BA, 0x0000, + 0x0000, 0x0000, 0xE3BD, 0x0000, 0xE3BE, 0xE3BB, + 0x0000, 0x0000, 0x0000, 0x8948, 0x0000, 0x0000, + 0x0000, 0x89A5, 0x0000, 0x0000, 0x0000, 0xE3C0, + 0xE3C1, 0x0000, 0x0000, 0x0000, 0xE3C2, 0x0000, + 0x9782, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F4B, 0x0000, 0xE3C4, 0xE3C3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9089, 0xE3C5, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE3C6, 0x0000, 0x0000, 0xE3C7, + 0x0000, 0x8AE3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8ACB, 0x0000, 0x0000, 0xE3C8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE3C9, 0x0000, 0x967C, + 0x9783, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs80[256] = { + 0x9773, 0x9856, 0x0000, 0x8D6C, 0xE3CC, 0x8ED2, + 0xE3CB, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3CD, + 0x8EA7, 0x0000, 0x0000, 0x0000, 0x91CF, 0x0000, + 0xE3CE, 0x0000, 0x0000, 0x8D6B, 0x0000, 0x96D5, + 0xE3CF, 0xE3D0, 0x0000, 0x0000, 0xE3D1, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE3D2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8EA8, 0x0000, 0x0000, + 0x96EB, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D5, + 0x0000, 0x925E, 0x0000, 0xE3D4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D7, 0x0000, + 0x0000, 0x0000, 0xE3D6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D8, 0x0000, + 0x0000, 0x0000, 0x90B9, 0x0000, 0xE3D9, 0x0000, + 0xE3DA, 0x0000, 0x0000, 0x0000, 0x95B7, 0xE3DB, + 0x0000, 0x918F, 0xE3DC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE3DD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97FC, 0xE3E0, 0x0000, + 0xE3DF, 0xE3DE, 0x92AE, 0x0000, 0xE3E1, 0x9045, + 0x0000, 0xE3E2, 0x0000, 0x0000, 0x0000, 0xE3E3, + 0x9857, 0xE3E4, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE3E5, 0xE3E7, 0xE3E6, 0x94A3, 0x0000, 0x93F7, + 0x0000, 0x985D, 0x94A7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE3E9, 0x0000, 0x0000, + 0x8FD1, 0x0000, 0x9549, 0x0000, 0xE3EA, 0xE3E8, + 0x0000, 0x8ACC, 0x0000, 0x0000, 0x0000, 0x8CD2, + 0x8E88, 0x0000, 0x0000, 0x94EC, 0x0000, 0x0000, + 0x0000, 0x8CA8, 0x9662, 0x0000, 0xE3ED, 0xE3EB, + 0x0000, 0x8D6D, 0x0000, 0x8D6E, 0x88E7, 0x0000, + 0x8DE6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9478, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x88DD, 0xE3F2, 0x0000, + 0x925F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9477, 0x0000, 0x91D9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F4, 0x0000, + 0x0000, 0xE3F0, 0xE3F3, 0xE3EE, 0x0000, 0xE3F1, + 0x9645, 0x0000, 0x0000, 0x8CD3, 0x0000, 0x0000, + 0x88FB, 0xE3EF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F6, + 0x0000, 0xE3F7, 0x0000, 0x0000, 0x93B7, 0x0000, + 0x0000, 0x0000, 0x8BB9, 0x0000, 0x0000, 0x0000, + 0xE445, 0x945C, 0x0000, 0x0000 +}; + +static u16 Ucs81[256] = { + 0x0000, 0x0000, 0x8E89, 0x0000, 0x0000, 0x8BBA, + 0x90C6, 0x9865, 0x96AC, 0xE3F5, 0x90D2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8B72, 0xE3F8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3FA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3FB, + 0x0000, 0x9245, 0x0000, 0x945D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x92AF, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE442, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE441, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE3FC, 0x0000, 0x0000, + 0x9074, 0x0000, 0x9585, 0xE444, 0x0000, 0xE443, + 0x8D6F, 0x9872, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE454, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE448, + 0xE449, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EEE, + 0x0000, 0x0000, 0xE447, 0x0000, 0x8D98, 0xE446, + 0x0000, 0x0000, 0xE44A, 0x0000, 0x0000, 0x0000, + 0x92B0, 0x95A0, 0x9142, 0x0000, 0x0000, 0x0000, + 0x0000, 0x91DA, 0xE44E, 0x0000, 0xE44F, 0xE44B, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE44C, 0x0000, + 0xE44D, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D70, + 0x0000, 0x0000, 0x0000, 0xE455, 0x0000, 0xE451, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9586, 0x0000, + 0x968C, 0x9547, 0x0000, 0x0000, 0xE450, 0x0000, + 0x0000, 0xE453, 0xE452, 0x0000, 0x0000, 0x0000, + 0x9663, 0xE456, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE457, 0x0000, 0x0000, 0x9156, + 0x0000, 0xE458, 0x0000, 0x0000, 0xE45A, 0x0000, + 0xE45E, 0x0000, 0x0000, 0xE45B, 0xE459, 0x945E, + 0xE45C, 0x0000, 0xE45D, 0x0000, 0x0000, 0x0000, + 0x89B0, 0x0000, 0xE464, 0xE45F, 0x0000, 0x0000, + 0x0000, 0xE460, 0x0000, 0x0000, 0x0000, 0xE461, + 0x0000, 0x919F, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE463, 0xE462, 0xE465, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE466, 0xE467, 0x0000, 0x0000, 0x9062, + 0x0000, 0x89E7, 0x0000, 0xE468, 0x97D5, 0x0000, + 0x8EA9, 0x0000, 0x0000, 0x8F4C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8E8A, 0x9276, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE469, 0xE46A, + 0x8950, 0x0000, 0xE46B, 0x0000 +}; + +static u16 Ucs82[256] = { + 0x0000, 0xE46C, 0xE46D, 0x0000, 0x0000, 0xE46E, + 0x0000, 0xE46F, 0x8BBB, 0x9DA8, 0xE470, 0x0000, + 0x90E3, 0xE471, 0x8EC9, 0x0000, 0xE472, 0x0000, + 0x98AE, 0x0000, 0x0000, 0x0000, 0xE473, 0x95DC, + 0x8ADA, 0x0000, 0x0000, 0x9143, 0x8F77, 0x0000, + 0x9591, 0x8F4D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE474, + 0x8D71, 0xE475, 0x94CA, 0x0000, 0xE484, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE477, 0x0000, 0x91C7, + 0x9495, 0x8CBD, 0xE476, 0x9144, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE478, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE47A, 0xE479, + 0xE47C, 0x0000, 0x0000, 0xE47B, 0x0000, 0xE47D, + 0x0000, 0x0000, 0xE480, 0x0000, 0xE47E, 0x0000, + 0x8ACD, 0x0000, 0xE481, 0x0000, 0xE482, 0xE483, + 0x0000, 0x0000, 0x8DAF, 0x97C7, 0x0000, 0xE485, + 0x9046, 0x0000, 0x0000, 0x0000, 0x8990, 0xE486, + 0xE487, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE488, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x88F0, 0x0000, 0xE489, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE48A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9587, 0x0000, 0x0000, + 0x0000, 0x8EC5, 0x0000, 0xE48C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8A48, 0x88B0, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE48B, 0xE48E, 0x946D, + 0x0000, 0x9063, 0x0000, 0x89D4, 0x0000, 0x9646, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C7C, 0x8BDA, + 0x0000, 0xE48D, 0x0000, 0x89E8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8AA1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8991, + 0xE492, 0x97E8, 0x91DB, 0x0000, 0x0000, 0x9563, + 0x0000, 0xE49E, 0x0000, 0x89D5, 0xE49C, 0x0000, + 0xE49A, 0xE491, 0x0000, 0xE48F, 0x0000, 0xE490, + 0x0000, 0x8EE1, 0x8BEA, 0x9297, 0x0000, 0x0000, + 0x0000, 0x93CF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8970, 0x0000, 0xE494, 0xE493, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE499, 0xE495, 0xE498, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs83[256] = { + 0x0000, 0x0000, 0x96CE, 0xE497, 0x89D6, 0x8A9D, + 0xE49B, 0x0000, 0x0000, 0xE49D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C73, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4A1, 0xE4AA, + 0xE4AB, 0x0000, 0x0000, 0x0000, 0x88A9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE4B2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x88EF, 0x0000, + 0x0000, 0xE4A9, 0x0000, 0x0000, 0x0000, 0xE4A8, + 0x0000, 0xE4A3, 0xE4A2, 0x0000, 0xE4A0, 0xE49F, + 0x9283, 0x0000, 0x91F9, 0xE4A5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4A4, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE4A7, 0x0000, 0x0000, + 0x0000, 0x9190, 0x8C74, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8960, 0xE4A6, 0x0000, 0x8D72, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9191, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE4B8, 0x0000, 0xE4B9, 0x0000, 0x89D7, + 0x0000, 0x0000, 0x0000, 0x89AC, 0xE4B6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE4AC, 0x0000, 0xE4B4, 0x0000, 0xE4BB, + 0xE4B5, 0x0000, 0x0000, 0x0000, 0xE4B3, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE496, 0x0000, 0x0000, + 0xE4B1, 0x0000, 0x0000, 0x0000, 0xE4AD, 0x0000, + 0x0000, 0x0000, 0x8ACE, 0xE4AF, 0xE4BA, 0x0000, + 0xE4B0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE4BC, 0x0000, 0xE4AE, 0x949C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9789, 0x0000, 0x0000, + 0x0000, 0xE4B7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE4CD, 0x0000, 0x0000, + 0x0000, 0xE4C5, 0x0000, 0x0000, 0x0000, 0x909B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8B65, 0x0000, + 0x8BDB, 0x0000, 0xE4C0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x89D9, 0x0000, 0x0000, 0x8FD2, 0x0000, + 0xE4C3, 0x0000, 0x0000, 0x0000, 0x8DD8, 0x0000, + 0x0000, 0x9370, 0xE4C8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95EC, + 0x0000, 0xE4BF, 0x0000, 0x0000, 0x0000, 0x89D8, + 0x8CD4, 0x9548, 0xE4C9, 0x0000, 0xE4BD, 0x0000, + 0x0000, 0xE4C6, 0x0000, 0x0000, 0x0000, 0xE4D0, + 0x0000, 0xE4C1, 0x0000, 0x0000 +}; + +static u16 Ucs84[256] = { + 0x0000, 0x0000, 0x0000, 0xE4C2, 0x93B8, 0x0000, + 0x0000, 0xE4C7, 0x0000, 0x0000, 0x0000, 0xE4C4, + 0x9647, 0xE4CA, 0x88DE, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE4BE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE4CC, 0x0000, 0xE4CB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x948B, + 0xE4D2, 0x0000, 0xE4DD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A9E, 0x0000, 0x0000, 0x0000, 0xE4E0, + 0x0000, 0x0000, 0xE4CE, 0x0000, 0x0000, 0x0000, + 0xE4D3, 0x978E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4DC, 0x0000, + 0x0000, 0x9774, 0x0000, 0x0000, 0x0000, 0x0000, + 0x97A8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9298, 0x0000, 0x0000, + 0x0000, 0x8A8B, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9592, 0xE4E2, 0x939F, 0x0000, 0x0000, + 0x88AF, 0x0000, 0x0000, 0xE4DB, 0x0000, 0xE4D7, + 0x9192, 0xE4D1, 0xE4D9, 0xE4DE, 0x0000, 0x944B, + 0x0000, 0x0000, 0x0000, 0x88A8, 0x0000, 0xE4D6, + 0x0000, 0xE4DF, 0x9598, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4DA, 0x0000, + 0xE4D5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8FD3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F4E, 0x0000, 0x0000, 0x0000, 0x8EAA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x96D6, 0x0000, 0x0000, + 0x9566, 0x0000, 0x0000, 0xE4E5, 0x0000, 0xE4EE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE4D8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8A97, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8FF6, 0xE4E3, + 0x0000, 0xE4E8, 0x9193, 0x0000, 0x0000, 0xE4E4, + 0x0000, 0xE4EB, 0x0000, 0x0000, 0x927E, 0x0000, + 0xE4EC, 0x0000, 0x0000, 0x9775, 0xE4E1, 0x8A57, + 0x0000, 0xE4E7, 0x0000, 0x0000, 0xE4EA, 0x96AA, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4ED, 0x0000, + 0x0000, 0xE4E6, 0xE4E9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9648, 0x0000, 0x9840, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4F1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE4F8, 0x0000, 0x0000, 0xE4F0 +}; + +static u16 Ucs85[256] = { + 0x8EC1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE4CF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95CC, + 0x0000, 0x96A0, 0xE4F7, 0xE4F6, 0x0000, 0xE4F2, + 0xE4F3, 0x0000, 0x8955, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE4F5, 0x0000, 0xE4EF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x92D3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE4F4, 0x88FC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91A0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95C1, 0x0000, 0x0000, 0xE4F9, 0xE540, + 0x0000, 0x94D7, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE4FC, 0x8FD4, 0x8EC7, 0xE542, 0x0000, 0x0000, + 0x8BBC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE543, 0x0000, 0x9599, 0xE4FB, 0x0000, + 0xE4D4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE4FA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x986E, 0x93A0, 0x9593, 0x0000, + 0x0000, 0xE54A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE550, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE551, 0x0000, 0xE544, 0x0000, 0x0000, 0x0000, + 0x9496, 0x0000, 0x0000, 0xE54E, 0xE546, 0x0000, + 0xE548, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE552, 0xE547, 0x0000, 0x0000, 0xE54B, 0x0000, + 0x0000, 0x8992, 0x0000, 0x93E3, 0x0000, 0xE54C, + 0xE54F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE545, 0x0000, 0x9145, 0x0000, + 0xE549, 0x8E46, 0x9064, 0x8C4F, 0x96F2, 0x0000, + 0x96F7, 0x8F92, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE556, + 0xE554, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x986D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE553, 0x0000, 0x0000, + 0x0000, 0x9795, 0x0000, 0xE555, 0xE557, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE558, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE55B, 0xE559, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x93A1, 0xE55A, 0x0000, 0x0000, 0x0000, 0x94CB, + 0xE54D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F93, 0x0000, 0xE55C, 0xE561, 0x9194, + 0x0000, 0x0000, 0xE560, 0x0000 +}; + +static u16 Ucs86[256] = { + 0x0000, 0x0000, 0xE541, 0x0000, 0x0000, 0x0000, + 0xE562, 0x9168, 0x0000, 0x0000, 0xE55D, 0xE55F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE55E, 0x0000, 0x0000, 0x9F50, 0x9F41, + 0x0000, 0x0000, 0xE564, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE563, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9796, 0x0000, 0xE1BA, + 0xE565, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE566, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE567, + 0x8CD5, 0x0000, 0x8B73, 0x0000, 0x0000, 0x0000, + 0xE569, 0x997C, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8B95, 0x0000, 0x97B8, 0x0000, 0x8BF1, 0xE56A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE56B, 0x0000, 0x0000, 0x0000, 0x928E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE56C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93F8, 0x0000, 0x88B8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x89E1, 0xE571, 0xE572, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE56D, 0x0000, 0x8E5C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE56E, 0x9461, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE56F, 0xE570, 0xE57A, 0x0000, 0x0000, + 0x0000, 0xE574, 0xE577, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE573, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE575, 0x0000, + 0xE576, 0x8ED6, 0x0000, 0xE578, 0x0000, 0x9260, + 0x0000, 0x8C75, 0x8A61, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE57B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A5E, 0x0000, 0xE581, 0x0000, 0x0000, + 0xE57C, 0xE580, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94B8, 0x0000, 0x0000, 0x0000, 0x0000, 0xE57D, + 0x0000, 0x0000, 0xE57E, 0x9567, 0x94D8, 0xE582, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x91FB, 0xE58C, 0x0000, 0xE588, + 0x0000, 0x0000, 0x89E9, 0x0000 +}; + +static u16 Ucs87[256] = { + 0xE586, 0x0000, 0x9649, 0xE587, 0x0000, 0x0000, + 0xE584, 0x0000, 0xE585, 0xE58A, 0xE58D, 0x0000, + 0x0000, 0xE58B, 0x0000, 0x0000, 0x0000, 0xE589, + 0xE583, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9277, 0x0000, 0xE594, 0x0000, 0x96A8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE592, 0x0000, 0x0000, 0x0000, 0xE593, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE58E, 0x0000, + 0x0000, 0xE590, 0x0000, 0x0000, 0x0000, 0xE591, + 0x0000, 0x0000, 0x0000, 0xE58F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x90E4, 0x0000, 0x9858, 0xE598, 0x0000, + 0xE599, 0x0000, 0x0000, 0x0000, 0x0000, 0xE59F, + 0x0000, 0x9049, 0x0000, 0xE59B, 0x0000, 0xE59E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE596, + 0xE595, 0x0000, 0x0000, 0xE5A0, 0x0000, 0x0000, + 0x89DA, 0x0000, 0xE59C, 0x0000, 0xE5A1, 0x0000, + 0x0000, 0x0000, 0xE59D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE59A, 0x0000, 0x92B1, 0x0000, + 0xE597, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9488, 0x0000, 0x0000, 0xE5A5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x975A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE5A4, 0x0000, 0x0000, + 0xE5A3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE5AC, 0x0000, 0x0000, + 0x0000, 0xE5A6, 0x0000, 0x0000, 0x0000, 0xE5AE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9786, 0xE5B1, 0x0000, 0xE5A8, 0x0000, 0x0000, + 0xE5A9, 0x0000, 0x0000, 0x0000, 0xE5AD, 0x0000, + 0xE5B0, 0xE5AF, 0x0000, 0x0000, 0x0000, 0xE5A7, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5AA, 0x0000, + 0xE5BB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5B4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5B2, + 0x0000, 0x0000, 0xE5B3, 0x0000, 0x0000, 0x0000, + 0xE5B8, 0xE5B9, 0x0000, 0x8A49, 0x0000, 0x8B61, + 0x0000, 0x0000, 0xE5B7, 0x0000 +}; + +static u16 Ucs88[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5A2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE5B6, 0xE5BA, 0xE5B5, 0x0000, 0xE5BC, + 0x0000, 0x0000, 0x0000, 0xE5BE, 0xE5BD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE5C0, 0xE5BF, 0xE579, + 0x0000, 0x0000, 0x0000, 0xE5C4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE5C1, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE5C2, 0x0000, 0x0000, 0xE5C3, 0x0000, 0xE5C5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C8C, 0x0000, + 0xE5C7, 0x0000, 0xE5C6, 0x0000, 0x8F4F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8D73, 0x9FA5, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5C8, 0x8F70, + 0x0000, 0x0000, 0x0000, 0x8A58, 0x0000, 0xE5C9, + 0x0000, 0x8971, 0x0000, 0x8FD5, 0xE5CA, 0x0000, + 0x0000, 0x8D74, 0xE5CB, 0x88DF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x955C, 0x0000, 0x0000, 0xE5CC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x908A, 0x0000, + 0xE5D3, 0x0000, 0x0000, 0xE5D0, 0x0000, 0x928F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5D1, + 0xE5CE, 0x8BDC, 0x0000, 0xE5CD, 0xE5D4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C55, 0x0000, + 0x0000, 0x91DC, 0x0000, 0xE5DA, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5D6, 0x0000, 0x0000, 0x0000, + 0x91B3, 0xE5D5, 0x0000, 0xE5D8, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5CF, 0x0000, 0x0000, 0x0000, + 0xE5D9, 0x0000, 0xE5DB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x94ED, 0x0000, 0x0000, + 0xE5D7, 0x0000, 0xE5DC, 0xE5DE, 0x0000, 0x0000, + 0x8CD1, 0xE5D2, 0x0000, 0x88BF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5DD, + 0x0000, 0x8DD9, 0x97F4, 0xE5DF, 0xE5E0, 0x9195, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97A0, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5E1, 0x9754, 0x0000, 0x0000, + 0xE5E2, 0xE5E3, 0x0000, 0x0000, 0x95E2, 0xE5E4, + 0x0000, 0x8DBE, 0x0000, 0x97A1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5E9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5EA, 0x8FD6, 0xE5E8, 0x0000, + 0x0000, 0x0000, 0x9787, 0xE5E5, 0x0000, 0x0000, + 0xE5E7, 0x90BB, 0x909E, 0x0000 +}; + +static u16 Ucs89[256] = { + 0x0000, 0x0000, 0xE5E6, 0x0000, 0xE5EB, 0x0000, + 0x0000, 0x95A1, 0x0000, 0x0000, 0xE5ED, 0x0000, + 0xE5EC, 0x0000, 0x0000, 0x0000, 0x8A8C, 0x0000, + 0x964A, 0xE5EE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5FA, + 0xE5F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE5F1, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE5F2, 0xE5F3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE5F7, 0x0000, 0xE5F8, 0x0000, 0x0000, 0xE5F6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5F4, + 0x0000, 0xE5EF, 0xE5F5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5F9, 0xE8B5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x89A6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5FC, 0x8BDD, + 0xE5FB, 0x0000, 0x0000, 0x0000, 0xE641, 0x0000, + 0xE640, 0x0000, 0x0000, 0x0000, 0xE643, 0x0000, + 0x0000, 0xE642, 0x0000, 0xE644, 0x0000, 0x0000, + 0x8F50, 0x0000, 0xE645, 0x0000, 0x0000, 0xE646, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE647, 0x90BC, 0x0000, 0x9776, 0x0000, 0xE648, + 0x0000, 0x0000, 0x95A2, 0x9465, 0xE649, 0x0000, + 0xE64A, 0x8CA9, 0x0000, 0x0000, 0x0000, 0x8B4B, + 0x0000, 0x0000, 0x0000, 0xE64B, 0x0000, 0x0000, + 0x8E8B, 0x9460, 0xE64C, 0x0000, 0x8A6F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE64D, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE64F, 0x9797, + 0x0000, 0xE64E, 0x9065, 0x0000, 0xE650, 0x0000, + 0x0000, 0xE651, 0x0000, 0x0000, 0xE652, 0x8ACF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE653, 0x0000, 0x0000, 0xE654, 0x0000, 0xE655, + 0xE656, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8A70, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE657, 0x0000, 0xE658, 0xE659, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89F0, + 0x0000, 0x0000, 0x9047, 0xE65A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE65B, 0x0000, + 0x0000, 0x0000, 0xE65C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs8A[256] = { + 0x8CBE, 0x0000, 0x92F9, 0xE65D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C76, 0x0000, 0x9075, 0x0000, + 0xE660, 0x0000, 0x93A2, 0x0000, 0xE65F, 0x0000, + 0x0000, 0x8C50, 0x0000, 0x0000, 0xE65E, 0x91F5, + 0x8B4C, 0x0000, 0x0000, 0xE661, 0x0000, 0xE662, + 0x0000, 0x8FD7, 0x0000, 0x0000, 0x0000, 0x8C8D, + 0x0000, 0xE663, 0x0000, 0x0000, 0x0000, 0x0000, + 0x964B, 0x0000, 0x0000, 0x90DD, 0x0000, 0x0000, + 0x0000, 0x8B96, 0x0000, 0x96F3, 0x9169, 0x0000, + 0xE664, 0x0000, 0x0000, 0x0000, 0x9066, 0x9290, + 0x8FD8, 0x0000, 0x0000, 0x0000, 0x0000, 0xE665, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE668, 0x0000, + 0xE669, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8DBC, 0x91C0, 0xE667, 0x0000, + 0x8FD9, 0x955D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE666, 0x0000, 0x0000, 0x8E8C, 0x0000, + 0x8972, 0x0000, 0xE66D, 0x8C77, 0x0000, 0x0000, + 0x8E8E, 0x0000, 0x0000, 0x8E8D, 0x0000, 0x986C, + 0xE66C, 0xE66B, 0x9146, 0x0000, 0x8B6C, 0x9862, + 0x8A59, 0x8FDA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE66A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE66F, 0x0000, + 0xE670, 0xE66E, 0x0000, 0x8CD6, 0x0000, 0x975F, + 0x0000, 0x0000, 0x8E8F, 0x9446, 0x0000, 0x0000, + 0x0000, 0xE673, 0x0000, 0x90BE, 0x0000, 0x9261, + 0x0000, 0x0000, 0x9755, 0x0000, 0xE676, 0x0000, + 0x0000, 0x0000, 0x8CEA, 0x0000, 0x90BD, 0xE672, + 0x0000, 0xE677, 0x8CEB, 0xE674, 0xE675, 0x0000, + 0xE671, 0x0000, 0x0000, 0x0000, 0x90E0, 0x93C7, + 0x0000, 0x0000, 0x924E, 0x0000, 0x89DB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x94EE, + 0x0000, 0x0000, 0x8B62, 0x0000, 0x0000, 0x92B2, + 0x0000, 0x0000, 0xE67A, 0x0000, 0xE678, 0x0000, + 0x0000, 0x926B, 0x0000, 0x0000, 0x0000, 0x90BF, + 0x8AD0, 0xE679, 0x0000, 0x907A, 0x0000, 0x0000, + 0x97C8, 0x0000, 0x0000, 0x0000, 0x985F, 0x0000, + 0x0000, 0x0000, 0xE67B, 0xE687, 0x92B3, 0x0000, + 0xE686, 0x0000, 0xE683, 0xE68B, 0xE684, 0x0000, + 0xE680, 0x0000, 0x92FA, 0xE67E, 0x0000, 0x0000, + 0x0000, 0xE67C, 0x0000, 0x9740, 0x8E90, 0x0000, + 0x0000, 0xE681, 0x0000, 0xE67D, 0x0000, 0x0000, + 0x0000, 0xE685, 0x8F94, 0x0000, 0x8CBF, 0x0000, + 0x0000, 0x0000, 0x91F8, 0x0000 +}; + +static u16 Ucs8B[256] = { + 0x9664, 0x8979, 0x88E0, 0x0000, 0x93A3, 0x0000, + 0x0000, 0xE689, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE688, 0x0000, 0x93E4, 0x0000, 0xE68D, 0x0000, + 0x0000, 0x0000, 0xE682, 0x0000, 0xE68C, 0xE68E, + 0x0000, 0x8CAA, 0xE68A, 0x8D75, 0x0000, 0x8ED3, + 0x0000, 0x0000, 0xE68F, 0x9777, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE692, 0x0000, 0xE695, 0x0000, + 0x0000, 0xE693, 0x9554, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE690, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8BDE, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE694, 0x0000, 0x0000, 0xE696, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE69A, 0x0000, 0x0000, 0xE697, 0x0000, + 0xE699, 0xE698, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE69B, 0x0000, 0x8EAF, 0x0000, + 0xE69D, 0xE69C, 0x9588, 0x0000, 0x0000, 0xE69F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C78, 0x0000, 0x0000, 0x0000, 0x0000, 0xE69E, + 0xE6A0, 0x0000, 0x0000, 0xE6A1, 0x8B63, 0xE3BF, + 0x8FF7, 0x0000, 0xE6A2, 0x0000, 0x0000, 0x8CEC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6A3, + 0x0000, 0x0000, 0xE6A4, 0x0000, 0x0000, 0x8E5D, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9DCC, 0x0000, 0xE6A5, 0x0000, 0xE6A6, 0x0000, + 0x8F51, 0x0000, 0xE6A7, 0xE6A8, 0x0000, 0x0000, + 0xE6A9, 0x0000, 0x0000, 0xE6AA, 0xE6AB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs8C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x924A, 0x0000, 0x0000, 0xE6AC, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE6AE, 0x0000, 0xE6AD, + 0x0000, 0x0000, 0x0000, 0x0000, 0x93A4, 0x0000, + 0xE6AF, 0x0000, 0x964C, 0x0000, 0xE6B0, 0x0000, + 0xE6B1, 0x0000, 0xE6B2, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE6B3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x93D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8FDB, 0xE6B4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8D8B, 0x98AC, + 0xE6B5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6B6, 0x955E, 0xE6B7, 0x0000, 0xE6BF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6B8, 0x0000, + 0x0000, 0xE6BA, 0x0000, 0x0000, 0x0000, 0xE6B9, + 0xE6BB, 0x0000, 0x9665, 0xE6BC, 0xE6BD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6BE, 0x0000, + 0x0000, 0x0000, 0xE6C0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A4C, 0x92E5, 0x0000, 0x9589, 0x8DE0, + 0x8D76, 0x0000, 0x0000, 0x0000, 0x0000, 0x956E, + 0x89DD, 0x94CC, 0xE6C3, 0x8AD1, 0x90D3, 0xE6C2, + 0xE6C7, 0x9299, 0x96E1, 0x0000, 0xE6C5, 0xE6C6, + 0x8B4D, 0x0000, 0xE6C8, 0x9483, 0x91DD, 0x0000, + 0x0000, 0x94EF, 0x935C, 0xE6C4, 0x0000, 0x9666, + 0x89EA, 0xE6CA, 0x9847, 0x92C0, 0x9864, 0x0000, + 0x0000, 0x8E91, 0xE6C9, 0x0000, 0x91AF, 0x0000, + 0x0000, 0xE6DA, 0x9147, 0x0000, 0x0000, 0x93F6, + 0x0000, 0x956F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE6CD, 0x8E5E, 0x8E92, 0x0000, + 0x8FDC, 0x0000, 0x9485, 0x0000, 0x8CAB, 0xE6CC, + 0xE6CB, 0x0000, 0x958A, 0x0000, 0x0000, 0x0000, + 0x8EBF, 0x0000, 0x0000, 0x9371, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6CF, 0xE6D0, + 0x8D77, 0xE6CE, 0x0000, 0x0000 +}; + +static u16 Ucs8D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6D1, 0xE6D2, + 0x0000, 0xE6D4, 0x91A1, 0x0000, 0xE6D3, 0x8AE4, + 0x0000, 0xE6D6, 0x0000, 0xE6D5, 0xE6D7, 0x0000, + 0x0000, 0xE6D9, 0xE6DB, 0x0000, 0xE6DC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x90D4, 0x0000, + 0x8ECD, 0xE6DD, 0x0000, 0x0000, 0x0000, 0x8A71, + 0x0000, 0xE6DE, 0x0000, 0x0000, 0x9196, 0xE6DF, + 0x0000, 0xE6E0, 0x958B, 0x0000, 0x0000, 0x8B4E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE6E1, 0x0000, 0x0000, + 0x0000, 0x92B4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x897A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE6E2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8EEF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9096, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91AB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6E5, 0x0000, 0x0000, 0x0000, 0xE6E4, 0x0000, + 0x0000, 0x0000, 0xE6E3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6EB, + 0xE6E9, 0x0000, 0x0000, 0xE6E6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6E8, 0x0000, + 0x0000, 0x0000, 0xE6E7, 0xE6EA, 0x0000, 0x8B97, + 0x0000, 0xE6EE, 0x0000, 0x90D5, 0x0000, 0xE6EF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8CD7, 0x0000, + 0xE6EC, 0xE6ED, 0x0000, 0x0000, 0x0000, 0x9848, + 0x0000, 0x0000, 0x0000, 0x92B5, 0x0000, 0x9148, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6F0, 0x0000, 0x0000, 0xE6F3 +}; + +static u16 Ucs8E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE6F1, 0xE6F2, 0x9778, 0x0000, + 0x0000, 0x0000, 0x0000, 0x93A5, 0xE6F6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6F4, + 0xE6F5, 0xE6F7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE748, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6FA, 0x0000, 0x0000, 0x0000, 0xE6FB, 0xE6F9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6F8, 0x0000, 0x92FB, 0x0000, 0x0000, 0xE740, + 0xE744, 0xE741, 0xE6FC, 0x0000, 0xE742, 0x0000, + 0x0000, 0x0000, 0xE743, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE74A, 0x0000, 0x0000, 0x0000, 0xE745, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90D6, + 0xE747, 0x0000, 0x0000, 0xE749, 0xE746, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE74C, 0x0000, 0x8F52, 0x0000, 0xE74B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE74D, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE74E, 0x0000, 0x0000, + 0xE751, 0xE750, 0x0000, 0xE74F, 0x0000, 0x0000, + 0xE753, 0xE752, 0x0000, 0x96F4, 0x0000, 0x0000, + 0x0000, 0xE755, 0x0000, 0xE754, 0xE756, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE757, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE759, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE758, 0x9067, 0xE75A, 0x0000, + 0x0000, 0x8BEB, 0xE75B, 0xE75D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE75E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE75F, + 0xE75C, 0x0000, 0xE760, 0x0000, 0x8ED4, 0xE761, + 0x8B4F, 0x8C52, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8CAC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE762, 0x0000, 0x0000, + 0x0000, 0x93EE, 0x0000, 0x0000, 0x935D, 0xE763, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE766, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8EB2, 0x0000, 0x0000, 0xE765, + 0xE764, 0x8C79, 0xE767, 0x0000 +}; + +static u16 Ucs8F[256] = { + 0x0000, 0x0000, 0x0000, 0x8A72, 0x0000, 0xE769, + 0x0000, 0x0000, 0x0000, 0x8DDA, 0xE768, 0x0000, + 0xE771, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE76B, 0xE76D, 0x95E3, 0xE76A, 0x0000, 0x0000, + 0x0000, 0xE76C, 0x0000, 0xE770, 0xE76E, 0x8B50, + 0x0000, 0xE76F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE772, 0x0000, 0x0000, 0x9479, + 0x97D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F53, + 0x0000, 0x0000, 0x0000, 0xE773, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9741, 0xE775, 0x0000, 0xE774, + 0x0000, 0x0000, 0xE778, 0x9760, 0x0000, 0x0000, + 0xE777, 0x0000, 0x8A8D, 0xE776, 0xE77B, 0x0000, + 0x0000, 0xE77A, 0x0000, 0x0000, 0xE779, 0x9351, + 0xE77C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE77D, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE77E, 0x0000, 0x0000, 0x8D8C, + 0x0000, 0x8C44, 0xE780, 0xE781, 0xE782, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9068, + 0xE783, 0x0000, 0x8EAB, 0xE784, 0x0000, 0x0000, + 0x0000, 0xE785, 0x0000, 0x0000, 0x0000, 0x999F, + 0x999E, 0x0000, 0x0000, 0x0000, 0x0000, 0xE786, + 0xE390, 0xE787, 0x9243, 0x904A, 0x945F, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE788, 0x0000, 0x0000, + 0x95D3, 0x92D2, 0x8D9E, 0x0000, 0x0000, 0x9248, + 0x0000, 0x0000, 0x8949, 0x0000, 0x9698, 0x9076, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C7D, 0x0000, 0x0000, 0x8BDF, + 0x0000, 0x0000, 0x95D4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE789, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE78B, 0x0000, + 0x0000, 0xE78A, 0x89DE, 0x0000, 0x0000, 0x93F4, + 0xE78C, 0x9497, 0x0000, 0x9352, 0x0000, 0xE78D, + 0x8F71, 0x0000, 0x0000, 0x0000, 0xE78F, 0x0000, + 0x0000, 0x96C0, 0xE79E, 0xE791, 0xE792, 0x0000, + 0x0000, 0x92C7, 0x0000, 0x0000 +}; + +static u16 Ucs90[256] = { + 0x91DE, 0x9197, 0x0000, 0x93A6, 0x0000, 0xE790, + 0x8B74, 0x0000, 0x0000, 0x0000, 0x0000, 0xE799, + 0x0000, 0xE796, 0xE7A3, 0x93A7, 0x9280, 0xE793, + 0x0000, 0x92FC, 0x9372, 0xE794, 0xE798, 0x9080, + 0x0000, 0x9487, 0x92CA, 0x0000, 0x0000, 0x90C0, + 0xE797, 0x91AC, 0x91A2, 0xE795, 0x88A7, 0x9841, + 0x0000, 0x0000, 0x0000, 0xE79A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91DF, 0x0000, + 0x0000, 0x8F54, 0x9069, 0x0000, 0x0000, 0xE79C, + 0xE79B, 0x0000, 0x88ED, 0xE79D, 0x0000, 0x0000, + 0x954E, 0x0000, 0xE7A5, 0x0000, 0x0000, 0x93D9, + 0x908B, 0x0000, 0x0000, 0x9278, 0x0000, 0x8BF6, + 0x0000, 0xE7A4, 0x9756, 0x895E, 0x0000, 0x95D5, + 0x89DF, 0xE79F, 0xE7A0, 0xE7A1, 0xE7A2, 0x93B9, + 0x9242, 0x88E1, 0xE7A6, 0x0000, 0xE7A7, 0xEAA1, + 0x0000, 0x0000, 0x91BB, 0x0000, 0xE7A8, 0x0000, + 0x8993, 0x916B, 0x0000, 0x8CAD, 0x0000, 0x9779, + 0x0000, 0x0000, 0xE7A9, 0x934B, 0x0000, 0x0000, + 0x0000, 0x9198, 0x8ED5, 0xE7AA, 0x0000, 0x0000, + 0xE7AD, 0x0000, 0x0000, 0x8F85, 0xE7AB, 0x914A, + 0x9149, 0x0000, 0x88E2, 0x0000, 0x97C9, 0xE7AF, + 0x0000, 0x94F0, 0xE7B1, 0xE7B0, 0xE7AE, 0xE284, + 0x8AD2, 0x0000, 0x0000, 0xE78E, 0x0000, 0xE7B3, + 0xE7B2, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7B4, + 0x0000, 0x9757, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93DF, 0x0000, 0x0000, 0x964D, 0x0000, + 0xE7B5, 0x0000, 0x8ED7, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE7B6, 0x0000, 0xE7B7, 0x0000, 0x0000, + 0x0000, 0xE7B8, 0x0000, 0x0000, 0x9340, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x88E8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8D78, 0x0000, + 0x0000, 0x0000, 0x9859, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7BC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C53, 0xE7B9, 0x0000, + 0xE7BA, 0x0000, 0x0000, 0x0000, 0x9594, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8A73, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9758, + 0x0000, 0x8BBD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9373, 0x0000, 0x0000 +}; + +static u16 Ucs91[256] = { + 0x0000, 0x0000, 0xE7BD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7BE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE7BF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9341, 0x0000, 0x0000, + 0xE7C1, 0x0000, 0xE7C0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93D1, 0xE7C2, 0x8F55, 0x8EDE, 0x947A, + 0x9291, 0x0000, 0x0000, 0x0000, 0x8EF0, 0x0000, + 0x908C, 0x0000, 0xE7C3, 0x0000, 0xE7C4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x907C, 0xE7C5, 0x0000, 0xE7C6, + 0x0000, 0x0000, 0x0000, 0xE7C7, 0x978F, 0x0000, + 0x8F56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7C9, 0xE7C8, 0x0000, 0x8D79, 0x0000, 0x8D93, + 0x8E5F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE7CC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8F86, 0x0000, 0xE7CB, + 0x0000, 0xE7CA, 0x0000, 0x91E7, 0x0000, 0x0000, + 0x8CED, 0x0000, 0x90C1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x94AE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F58, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7CD, 0x0000, 0x8FDD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE7D0, 0xE7CE, 0x0000, 0x0000, + 0x0000, 0xE7CF, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7D2, 0xE7D1, 0x0000, 0x0000, 0x8FF8, 0x0000, + 0xE7D3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7D4, 0xE7D5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94CE, 0x8DD1, 0x8EDF, 0xE7D6, 0x0000, 0xE7D7, + 0x97A2, 0x8F64, 0x96EC, 0x97CA, 0xE7D8, 0x8BE0, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE7D9, 0x0000, + 0x9342, 0x0000, 0x0000, 0xE7DC, 0x8A98, 0x906A, + 0x0000, 0xE7DA, 0x0000, 0xE7DB, 0x0000, 0x92DE, + 0x0000, 0x0000, 0x9674, 0x8BFA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7DE, + 0xE7DF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7DD, 0x0000, 0x0000, 0xE7E1 +}; + +static u16 Ucs92[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93DD, 0x8A62, 0x0000, 0x0000, 0xE7E5, + 0x0000, 0x0000, 0xE7E2, 0xE7E4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE86E, + 0x0000, 0x0000, 0xE7E3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x97E9, 0x0000, + 0x0000, 0x8CD8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7ED, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9353, 0xE7E8, 0x0000, 0x0000, + 0xE7EB, 0xE7E9, 0x0000, 0xE7EE, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE7EF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7E7, 0x0000, 0x0000, + 0xE7F4, 0x8994, 0x0000, 0x0000, 0xE7E6, 0x0000, + 0x0000, 0x0000, 0x94AB, 0x0000, 0xE7EA, 0x0000, + 0x8FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D7A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9667, 0x0000, 0x8BE2, 0x0000, 0x0000, 0x8F65, + 0x0000, 0x93BA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x914C, 0x0000, 0xE7F2, 0x0000, 0xE7EC, + 0xE7F1, 0x0000, 0x96C1, 0x0000, 0x92B6, 0xE7F3, + 0xE7F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x914B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7F7, 0x0000, 0xE7F6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7F5, 0x0000, 0x0000, + 0x964E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F9B, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7F8, + 0x95DD, 0x0000, 0x0000, 0x8973, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9565, 0x9292, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8B98, 0x0000, 0xE7FA, 0x0000, + 0x8D7C, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs93[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8E4B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7F9, 0x908D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x908E, 0xE840, 0xE842, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8FF9, 0x0000, 0xE841, 0xE843, + 0x0000, 0x0000, 0x8BD1, 0x0000, 0x9564, 0x0000, + 0x0000, 0x8EE0, 0x9842, 0x0000, 0xE7FC, 0x8DF6, + 0x0000, 0x0000, 0x985E, 0x0000, 0x0000, 0xE845, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE844, 0xE846, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE7FB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x93E7, 0x0000, 0x9374, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x92D5, 0x0000, 0xE84B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9262, 0xE847, 0x0000, 0x0000, 0x0000, + 0xE848, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C4C, 0x0000, 0xE84A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8CAE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE849, 0x0000, + 0x8FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8A99, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE84F, 0x0000, + 0x8DBD, 0x9199, 0x0000, 0x0000, 0x92C8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A5A, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE84D, 0xE84E, + 0x92C1, 0x0000, 0xE84C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE850, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE856, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE859, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE858, 0x934C, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE851, 0xE852, + 0xE855, 0x0000, 0x0000, 0x0000, 0x0000, 0xE857, + 0x0000, 0x0000, 0x0000, 0x8BBE, 0x0000, 0x0000, + 0xE85A, 0xE854, 0x0000, 0x0000, 0xE853, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs94[256] = { + 0x0000, 0x0000, 0x0000, 0xE85E, 0x0000, 0x0000, + 0x0000, 0xE85F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE860, 0x0000, + 0x0000, 0xE85D, 0xE85C, 0x0000, 0x0000, 0x0000, + 0x8FE0, 0x93A8, 0xE85B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE864, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE862, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE863, + 0xE861, 0x0000, 0x91F6, 0x0000, 0xE865, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE866, + 0x0000, 0x0000, 0xE868, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8AD3, 0xE867, 0x96F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE873, 0xE869, 0x0000, 0x0000, 0xE86C, 0x0000, + 0xE86A, 0x0000, 0xE86B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE86D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE86F, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE870, 0x0000, 0xE871, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE874, 0xE872, + 0xE875, 0xE877, 0x0000, 0xE876, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs95[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92B7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x96E5, 0x0000, 0xE878, 0x914D, + 0x0000, 0x0000, 0x0000, 0xE879, 0x0000, 0x95C2, + 0xE87A, 0x8A4A, 0x0000, 0x0000, 0x0000, 0x895B, + 0x0000, 0x8AD5, 0x0000, 0x8AD4, 0xE87B, 0x0000, + 0xE87C, 0x0000, 0xE87D, 0xE87E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE880, 0x0000, + 0x8AD6, 0x8A74, 0x8D7D, 0x94B4, 0x0000, 0xE882, + 0xE881, 0x0000, 0x0000, 0x0000, 0x0000, 0xE883, + 0x0000, 0x0000, 0x0000, 0x0000, 0x897B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE886, + 0x0000, 0xE885, 0xE884, 0x0000, 0xE887, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE88A, 0x0000, 0x0000, + 0x0000, 0x88C5, 0x0000, 0x0000, 0xE888, 0x0000, + 0xE88C, 0xE88B, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE88E, 0xE88D, 0xE88F, 0x0000, + 0x93AC, 0x0000, 0x0000, 0x0000, 0xE890, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE891, 0xE893, 0x0000, + 0x0000, 0xE892, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs96[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x958C, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE894, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE895, 0x0000, + 0x8DE3, 0x0000, 0x0000, 0x0000, 0xE896, 0xE897, + 0x0000, 0x0000, 0x9668, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x916A, + 0x0000, 0x0000, 0x0000, 0x88A2, 0x91C9, 0x0000, + 0xE898, 0x0000, 0x958D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE89B, 0xE899, 0x8D7E, + 0x0000, 0xE89A, 0x8CC0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95C3, 0xE89D, 0xE89F, 0xE89E, 0xE8A0, + 0x0000, 0x0000, 0x8940, 0x9077, 0x8F9C, 0x8AD7, + 0xE8A1, 0x0000, 0x0000, 0x0000, 0x9486, 0x0000, + 0xE8A3, 0x0000, 0x0000, 0x0000, 0x8941, 0x0000, + 0xE8A2, 0x92C2, 0x0000, 0x97CB, 0x93A9, 0xE89C, + 0x97A4, 0x0000, 0x8CAF, 0x0000, 0x0000, 0x977A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8BF7, 0x97B2, 0x0000, 0x8C47, 0x0000, + 0x91E0, 0xE440, 0x0000, 0xE8A4, 0x8A4B, 0x908F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8A75, 0xE8A6, + 0x0000, 0xE8A7, 0xE8A5, 0x8C84, 0x0000, 0x8DDB, + 0x8FE1, 0x0000, 0x0000, 0x0000, 0x8942, 0x0000, + 0x0000, 0x97D7, 0x0000, 0x0000, 0x0000, 0xE8A9, + 0xE7AC, 0x0000, 0xE8A8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE8AC, 0xE8AA, 0xE8AB, 0x0000, + 0xE8AD, 0x0000, 0xE8AE, 0x97EA, 0xE8AF, 0xE8B0, + 0x0000, 0x90C7, 0x94B9, 0x0000, 0x0000, 0x0000, + 0x909D, 0x8AE5, 0x0000, 0x0000, 0x9759, 0x89EB, + 0x8F57, 0x8CD9, 0x0000, 0xE8B3, 0x0000, 0xE8B2, + 0x8E93, 0xE8B4, 0xE8B1, 0x0000, 0x0000, 0x8E47, + 0x0000, 0x0000, 0x0000, 0xE8B8, 0xE5AB, 0x0000, + 0x0000, 0x99D4, 0x0000, 0x9097, 0xE8B6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x97A3, 0x93EF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x894A, 0x0000, + 0x90E1, 0x8EB4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x95B5, 0x0000, 0x895F, 0x0000, 0x0000, 0x0000, + 0x97EB, 0x978B, 0x0000, 0xE8B9, 0x0000, 0x9364, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs97[256] = { + 0x8EF9, 0x0000, 0x0000, 0x0000, 0xE8BA, 0x0000, + 0xE8BB, 0x906B, 0xE8BC, 0x0000, 0x97EC, 0x0000, + 0x0000, 0xE8B7, 0xE8BE, 0xE8C0, 0x0000, 0xE8BF, + 0x0000, 0xE8BD, 0x0000, 0x0000, 0xE8C1, 0x0000, + 0x0000, 0xE8C2, 0x0000, 0x0000, 0x919A, 0x0000, + 0x89E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE8C3, 0x0000, 0x0000, 0x96B6, 0x0000, 0x0000, + 0xE8C4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE8C5, 0x0000, 0x9849, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E50, 0xE8C6, 0x0000, 0x0000, + 0x0000, 0xE8C7, 0xE8C8, 0x0000, 0x0000, 0x0000, + 0xE8CC, 0x0000, 0xE8C9, 0x0000, 0xE8CA, 0x0000, + 0xE8CB, 0xE8CD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x90C2, 0x0000, + 0x0000, 0x0000, 0x96F5, 0x0000, 0x0000, 0x90C3, + 0x0000, 0x0000, 0xE8CE, 0x0000, 0x94F1, 0x0000, + 0xE8CF, 0xEA72, 0x96CA, 0x0000, 0xE8D0, 0x0000, + 0xE8D1, 0x0000, 0xE8D2, 0x8A76, 0x0000, 0xE8D4, + 0x0000, 0x9078, 0x0000, 0x0000, 0x0000, 0xE8D5, + 0x0000, 0x0000, 0x8C43, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE8D6, 0xE8DA, 0x0000, 0xE8D8, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8D9, 0x0000, 0x0000, + 0x8A93, 0xE8D7, 0xE8DB, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE8DC, 0x0000, 0x88C6, 0x0000, 0xE8DD, + 0xE8DE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8FE2, 0x0000, 0x0000, 0x0000, + 0xE8DF, 0x0000, 0x0000, 0x0000, 0x8B66, 0x0000, + 0x0000, 0xE8E2, 0x0000, 0x0000, 0xE8E1, 0x0000, + 0xE8E0, 0x0000, 0x0000, 0xE691, 0x0000, 0x95DA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE8E3, + 0xE8E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8E5, 0x0000, 0x0000, + 0xE8E6, 0x0000, 0xE8E7, 0x0000, 0x0000, 0xE8E8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8AD8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE8E9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8EA, 0x9442, 0x0000, + 0x0000, 0x0000, 0xE8EC, 0x89B9, 0x0000, 0xE8EF, + 0xE8EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x8943, + 0x0000, 0x0000, 0x0000, 0x8BBF +}; + +static u16 Ucs98[256] = { + 0x0000, 0x95C5, 0x92B8, 0x8DA0, 0x0000, 0x8D80, + 0x8F87, 0x0000, 0x907B, 0x0000, 0x0000, 0x0000, + 0xE8F1, 0x0000, 0x0000, 0xE8F0, 0x9761, 0x8AE6, + 0x94D0, 0x93DA, 0x0000, 0x0000, 0x0000, 0x909C, + 0x97CC, 0x0000, 0x8C7A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8F4, 0x0000, 0x0000, + 0xE8F3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x966A, 0x93AA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x896F, 0x0000, + 0x0000, 0xE8F5, 0xE8F2, 0x0000, 0x0000, 0x9570, + 0x978A, 0xE8F6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE8F7, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8F9, 0x91E8, 0x8A7A, + 0x8A7B, 0xE8F8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AE7, 0x8CB0, 0x0000, 0x0000, 0x8AE8, 0x0000, + 0x0000, 0x935E, 0x0000, 0x0000, 0x97DE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8CDA, 0x0000, 0x0000, 0x0000, 0xE8FA, + 0x0000, 0x0000, 0x0000, 0xE8FB, 0xE8FC, 0xE940, + 0x0000, 0xE942, 0xE941, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9597, 0x0000, 0xE943, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE944, 0x0000, 0xE945, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE946, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE948, 0xE947, 0x0000, + 0xE949, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x94F2, 0xE3CA, 0x0000, + 0x0000, 0x9048, 0x0000, 0x0000, 0x8B51, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE94A, + 0x0000, 0xE94B, 0x0000, 0x99AA, 0x9F5A, 0x94D1, + 0x0000, 0x0000, 0x88F9, 0x0000, 0x88B9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8E94, 0x964F, 0x8FFC, 0x0000 +}; + +static u16 Ucs99[256] = { + 0x0000, 0x0000, 0x0000, 0xE94C, 0x0000, 0x96DD, + 0x0000, 0x0000, 0x0000, 0xE94D, 0x977B, 0x0000, + 0x8961, 0x0000, 0x0000, 0x0000, 0x8E60, 0x0000, + 0xE94E, 0x89EC, 0xE94F, 0x0000, 0x0000, 0x0000, + 0xE950, 0x0000, 0x0000, 0x0000, 0x0000, 0xE952, + 0xE953, 0x0000, 0xE955, 0xE951, 0x0000, 0x0000, + 0xE954, 0x0000, 0x0000, 0x0000, 0x8AD9, 0x0000, + 0x0000, 0x0000, 0xE956, 0x0000, 0xE957, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE958, 0xE959, 0x0000, 0x0000, 0x0000, + 0xE95A, 0x0000, 0x0000, 0xE95C, 0x0000, 0x0000, + 0x0000, 0xE95B, 0x0000, 0xE95E, 0xE961, 0x0000, + 0x0000, 0x0000, 0xE95D, 0xE95F, 0xE960, 0x0000, + 0x0000, 0xE962, 0x0000, 0x8BC0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8EF1, 0xE963, 0xE964, 0x8D81, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE965, 0x0000, 0x0000, + 0x8A5D, 0x0000, 0x0000, 0x0000, 0x946E, 0xE966, + 0xE967, 0x0000, 0x0000, 0x0000, 0x0000, 0x9279, + 0x93E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE968, 0x0000, 0x0000, 0x0000, + 0x0000, 0x949D, 0x0000, 0x0000, 0x91CA, 0x8977, + 0x8BEC, 0x0000, 0x8BED, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9293, 0xE96D, + 0x8BEE, 0x0000, 0x0000, 0x89ED, 0x0000, 0x0000, + 0xE96C, 0x0000, 0x0000, 0xE96A, 0x0000, 0xE96B, + 0x0000, 0xE969, 0x0000, 0x0000, 0xE977, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE96E, 0xE96F, 0x0000, + 0x0000, 0xE970, 0xE971, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE973, 0x0000, 0x0000, 0xE972, + 0x0000, 0x0000, 0x0000, 0x8F78 +}; + +static u16 Ucs9A[256] = { + 0x0000, 0xE974, 0x0000, 0x0000, 0x0000, 0xE976, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8B52, 0xE975, 0x0000, 0x0000, + 0x919B, 0x8CB1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE978, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91CB, 0x0000, + 0x0000, 0xE979, 0x0000, 0x0000, 0x0000, 0x0000, + 0x93AB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE97A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE980, 0x0000, 0xE97D, 0x0000, + 0xE97C, 0xE97E, 0x0000, 0xE97B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE982, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE981, 0x0000, 0xE984, 0x0000, 0x0000, + 0x8BC1, 0xE983, 0x0000, 0x0000, 0x0000, 0xE985, + 0x0000, 0x0000, 0xE986, 0x0000, 0xE988, 0xE987, + 0x0000, 0x0000, 0x0000, 0xE989, 0xE98B, 0xE98A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8D9C, 0x0000, 0x0000, 0x0000, 0x0000, 0xE98C, + 0x0000, 0x0000, 0xE98D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8A5B, 0x0000, + 0x0000, 0x0000, 0xE98E, 0x0000, 0x0000, 0x0000, + 0xE98F, 0x0000, 0x0000, 0x0000, 0x9091, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE990, 0x0000, 0xE991, + 0x0000, 0xE992, 0xE993, 0x0000, 0x0000, 0x0000, + 0x8D82, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE994, 0xE995, 0x0000, 0x0000, 0xE996, 0xE997, + 0x0000, 0x0000, 0xE998, 0x0000, 0x0000, 0x0000, + 0x94AF, 0xE99A, 0x0000, 0x9545, 0xE99B, 0xE999, + 0x0000, 0xE99D, 0x0000, 0x0000, 0xE99C, 0x0000, + 0x0000, 0xE99E, 0x0000, 0x0000, 0x0000, 0xE99F, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs9B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9A1, 0x0000, 0xE9A2, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE9A3, 0x0000, 0x0000, 0xE9A4, 0xE9A5, + 0x0000, 0xE9A6, 0x0000, 0xE9A7, 0xE9A8, 0xE9A9, + 0xE9AA, 0x0000, 0x0000, 0x0000, 0xE9AB, 0xE9AC, + 0x0000, 0x9F54, 0xE9AD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2F6, + 0x8B53, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A40, + 0x8DB0, 0xE9AF, 0xE9AE, 0x96A3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9B1, + 0xE9B2, 0xE9B0, 0x0000, 0xE9B3, 0x0000, 0x0000, + 0x9682, 0x0000, 0x0000, 0x0000, 0xE9B4, 0x0000, + 0x8B9B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9844, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE9B5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9B7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x88BC, 0x0000, + 0x0000, 0xE9B8, 0x95A9, 0xE9B6, 0x0000, 0x0000, + 0xE9B9, 0xE9BA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9BB, 0xE9BC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9BD, 0x0000, 0x968E, 0x8E4C, 0x0000, 0x8DF8, + 0x914E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9BE, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9C1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9C2, 0x0000, 0x0000, 0x8CEF, 0xE9C0, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9C3, 0x0000, 0xE9C4, + 0xE9C5, 0x0000, 0xE9C9, 0x0000, 0x8E49, 0x0000, + 0x0000, 0x0000, 0x0000, 0x91E2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9CA, 0xE9C7, 0xE9C6, + 0xE9C8, 0x0000, 0x0000, 0x0000, 0x8C7E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9CE, 0xE9CD, 0xE9CC, 0x0000, 0x0000, 0x88B1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs9C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xE9D8, 0x0000, + 0xE9D4, 0x0000, 0xE9D5, 0xE9D1, 0xE9D7, 0x0000, + 0xE9D3, 0x8A82, 0x0000, 0x0000, 0x986B, 0x0000, + 0xE9D6, 0xE9D2, 0xE9D0, 0xE9CF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9DA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9DD, 0x0000, 0x0000, + 0xE9DC, 0xE9DB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9568, 0xE9D9, 0x88F1, + 0xE9DE, 0x0000, 0xE9E0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8A8F, 0xE9CB, 0x8956, + 0x0000, 0x0000, 0xE9E2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE9E1, 0xE9DF, + 0x924C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9690, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97D8, 0x0000, 0x0000, + 0xE9E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE9E5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE9E6, 0x0000, + 0xE9E7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92B9, 0x0000, 0xE9E8, 0x0000, 0x94B5, + 0x0000, 0xE9ED, 0xE9E9, 0x0000, 0x0000, 0x0000, + 0xE9EA, 0x0000, 0x0000, 0x9650, 0x96C2, 0x0000, + 0x93CE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs9D[256] = { + 0x0000, 0x0000, 0x0000, 0xE9EE, 0x0000, 0x0000, + 0xE9EF, 0x93BC, 0xE9EC, 0xE9EB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x89A8, 0x0000, 0x0000, 0x0000, + 0xE9F7, 0x0000, 0x0000, 0xE9F6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8995, 0x0000, 0x0000, + 0x0000, 0xE9F4, 0x0000, 0x0000, 0x0000, 0xE9F3, + 0x0000, 0x0000, 0xE9F1, 0x0000, 0x8A9B, 0x0000, + 0xE9F0, 0x8EB0, 0x89A7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D83, + 0x0000, 0x0000, 0xE9FA, 0xE9F9, 0x0000, 0xE9F8, + 0x0000, 0x0000, 0xE9F5, 0x0000, 0xE9FB, 0x0000, + 0xE9FC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA44, 0xEA43, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA45, + 0x0000, 0x0000, 0x894C, 0xEA40, 0xEA41, 0x0000, + 0x8D94, 0x96B7, 0x0000, 0x0000, 0xEA42, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9651, 0x0000, 0x0000, 0xEA4A, 0x0000, 0x0000, + 0xEA46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA4B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA48, 0x0000, 0xEA47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C7B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xEA4C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA4D, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA4E, 0x0000, 0xEA49, 0x0000, 0x0000, + 0x0000, 0xE9F2, 0x0000, 0x0000, 0xEA4F, 0x0000, + 0x92DF, 0x0000, 0x0000, 0x0000, 0xEA53, 0x0000, + 0xEA54, 0xEA52, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA51, 0xEA57, 0x0000, 0xEA50, 0x0000, + 0xEA55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA56, 0x0000, 0x0000, + 0x0000, 0xEA59, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA58, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA5B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA5C, 0x0000, 0xEA5D, + 0x0000, 0x0000, 0x9868, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA5A, 0x91E9, 0x8DEB, 0x0000, + 0x0000, 0xEA5E, 0x0000, 0x0000 +}; + +static u16 Ucs9E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA5F, 0xEA60, 0x0000, 0x0000, + 0xEA61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA62, 0x0000, 0x0000, + 0x8CB2, 0xEA63, 0x0000, 0x0000, 0x0000, 0xEA64, + 0x0000, 0x8EAD, 0x0000, 0xEA65, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xEA66, 0x0000, + 0x0000, 0xEA67, 0xEA68, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA6B, 0xEA69, 0x985B, 0x0000, 0xEA6A, + 0x0000, 0x97ED, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA6C, 0x0000, 0x97D9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA6D, 0x949E, 0x0000, + 0x0000, 0xEA6E, 0xEA70, 0x0000, 0x0000, 0xEA71, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xEA6F, 0x8D8D, + 0x96CB, 0x9683, 0x9BF5, 0x0000, 0x9F80, 0x969B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x89A9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xEA73, 0x8B6F, 0xEA74, 0xEA75, 0xEA76, 0x0000, + 0x8D95, 0x0000, 0xEA77, 0x0000, 0x0000, 0x0000, + 0xE0D2, 0x96D9, 0x0000, 0x91E1, 0xEA78, 0xEA7A, + 0xEA79, 0x0000, 0xEA7B, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA7C, 0x0000, 0x0000, 0xEA7D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA7E, + 0x0000, 0x0000, 0x0000, 0x0000, 0xEA80, 0x0000, + 0xEA81, 0xEA82, 0x0000, 0xEA83, 0x0000, 0xEA84, + 0xEA85, 0xEA86, 0x0000, 0x0000 +}; + +static u16 Ucs9F[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA87, 0xEA88, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9343, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8CDB, 0x0000, 0xEA8A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x916C, 0xEA8B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA8C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9540, + 0x0000, 0x0000, 0xEA8D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA8E, 0xE256, 0x0000, 0x0000, + 0xE6D8, 0xE8EB, 0x0000, 0x0000, 0xEA8F, 0x0000, + 0xEA90, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA92, + 0xEA93, 0xEA94, 0x97EE, 0xEA91, 0x0000, 0x0000, + 0xEA95, 0xEA96, 0x0000, 0x0000, 0xEA98, 0x0000, + 0xEA97, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xEA9A, 0x0000, 0x0000, 0x0000, 0xEA9B, 0xEA99, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97B4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA9C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xEA9D, 0xE273, 0x0000, 0x0000, 0xEA9E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 UcsFF[256] = { + 0x0000, 0x8149, 0x0000, 0x8194, 0x8190, 0x8193, + 0x8195, 0x0000, 0x8169, 0x816A, 0x8196, 0x817B, + 0x8143, 0x0000, 0x8144, 0x815E, 0x824F, 0x8250, + 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256, + 0x8257, 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, + 0x8184, 0x8148, 0x8197, 0x8260, 0x8261, 0x8262, + 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8268, + 0x8269, 0x826A, 0x826B, 0x826C, 0x826D, 0x826E, + 0x826F, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, + 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x816D, + 0x0000, 0x816E, 0x814F, 0x8151, 0x814D, 0x8281, + 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287, + 0x8288, 0x8289, 0x828A, 0x828B, 0x828C, 0x828D, + 0x828E, 0x828F, 0x8290, 0x8291, 0x8292, 0x8293, + 0x8294, 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, + 0x829A, 0x816F, 0x8162, 0x8170, 0x0000, 0x0000, + 0x0000, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, + 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, + 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, + 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, + 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, + 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, + 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, + 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, + 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8150, + 0x0000, 0x818F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16* UcsSjisTable[256] = {0}; + +u16 OSUTF32toSJIS(u32 utf32) { + u16* table; + + if (0x10000 <= utf32) { + return 0; + } + + table = UcsSjisTable[(utf32 >> 8) & 0xFF]; + if (table != 0) { + return table[utf32 & 0xFF]; + } + + return 0; +} + +static u16 Sjis00[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, + 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, + 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005A, 0x005B, 0x00A5, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, + 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, + 0x203E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF61, + 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, + 0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, + 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0xFF72, 0xFF73, + 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, + 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, + 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, + 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, + 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90, 0xFF91, + 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97, + 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, + 0xFF9E, 0xFF9F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis81[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3001, + 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B, + 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, + 0x00A8, 0xFF3E, 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, + 0x309D, 0x309E, 0x3003, 0x4EDD, 0x3005, 0x3006, + 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0x005C, + 0x301C, 0x2016, 0xFF5C, 0x2026, 0x2025, 0x2018, + 0x2019, 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, + 0x3015, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D, 0x3008, + 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, + 0x300F, 0x3010, 0x3011, 0xFF0B, 0x2212, 0x00B1, + 0x00D7, 0x0000, 0x00F7, 0xFF1D, 0x2260, 0xFF1C, + 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234, 0x2642, + 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, + 0xFF04, 0x00A2, 0x00A3, 0xFF05, 0xFF03, 0xFF06, + 0xFF0A, 0xFF20, 0x00A7, 0x2606, 0x2605, 0x25CB, + 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1, 0x25A0, + 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B, 0x3012, + 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2208, 0x220B, + 0x2286, 0x2287, 0x2282, 0x2283, 0x222A, 0x2229, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2227, 0x2228, 0x00AC, 0x21D2, + 0x21D4, 0x2200, 0x2203, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2220, 0x22A5, 0x2312, 0x2202, + 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, + 0x223D, 0x221D, 0x2235, 0x222B, 0x222C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, + 0x2021, 0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x25EF, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis82[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, + 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, + 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, + 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, + 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, + 0xFF39, 0xFF3A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFF41, 0xFF42, 0xFF43, + 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, + 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, + 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, + 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3041, 0x3042, 0x3043, + 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, + 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, + 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, + 0x3056, 0x3057, 0x3058, 0x3059, 0x305A, 0x305B, + 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, + 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, + 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, + 0x306E, 0x306F, 0x3070, 0x3071, 0x3072, 0x3073, + 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, + 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, + 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, + 0x3086, 0x3087, 0x3088, 0x3089, 0x308A, 0x308B, + 0x308C, 0x308D, 0x308E, 0x308F, 0x3090, 0x3091, + 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis83[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x30A1, 0x30A2, + 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, + 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, + 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, + 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, + 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, + 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, + 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, + 0x30CD, 0x30CE, 0x30CF, 0x30D0, 0x30D1, 0x30D2, + 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, + 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, + 0x30DF, 0x0000, 0x30E0, 0x30E1, 0x30E2, 0x30E3, + 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, + 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, + 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, + 0x30F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0391, 0x0392, 0x0393, + 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, + 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, + 0x03A7, 0x03A8, 0x03A9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03B1, + 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, + 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, + 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis84[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0410, 0x0411, + 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, + 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, + 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, + 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, + 0x042F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0430, 0x0431, + 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, + 0x043D, 0x0000, 0x043E, 0x043F, 0x0440, 0x0441, + 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, + 0x044E, 0x044F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2500, 0x2502, 0x250C, + 0x2510, 0x2518, 0x2514, 0x251C, 0x252C, 0x2524, + 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513, + 0x251B, 0x2517, 0x2523, 0x2533, 0x252B, 0x253B, + 0x254B, 0x2520, 0x252F, 0x2528, 0x2537, 0x253F, + 0x251D, 0x2530, 0x2525, 0x2538, 0x2542, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis88[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4E9C, 0x5516, 0x5A03, + 0x963F, 0x54C0, 0x611B, 0x6328, 0x59F6, 0x9022, + 0x8475, 0x831C, 0x7A50, 0x60AA, 0x63E1, 0x6E25, + 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, + 0x65A1, 0x6271, 0x5B9B, 0x59D0, 0x867B, 0x98F4, + 0x7D62, 0x7DBE, 0x9B8E, 0x6216, 0x7C9F, 0x88B7, + 0x5B89, 0x5EB5, 0x6309, 0x6697, 0x6848, 0x95C7, + 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, + 0x5049, 0x56F2, 0x5937, 0x59D4, 0x5A01, 0x5C09, + 0x60DF, 0x610F, 0x6170, 0x6613, 0x6905, 0x70BA, + 0x754F, 0x7570, 0x79FB, 0x7DAD, 0x7DEF, 0x80C3, + 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, + 0x4E95, 0x4EA5, 0x57DF, 0x80B2, 0x90C1, 0x78EF, + 0x4E00, 0x58F1, 0x6EA2, 0x9038, 0x7A32, 0x8328, + 0x828B, 0x9C2F, 0x5141, 0x5370, 0x54BD, 0x54E1, + 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, + 0x852D, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis89[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9662, 0x9670, + 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87, 0x70CF, + 0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, + 0x4E11, 0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, + 0x6B1D, 0x851A, 0x9C3B, 0x59E5, 0x53A9, 0x6D66, + 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B, 0x96F2, + 0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, + 0x6620, 0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, + 0x745B, 0x76C8, 0x7A4E, 0x9834, 0x82F1, 0x885B, + 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA, 0x99C5, + 0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, + 0x5186, 0x0000, 0x5712, 0x5830, 0x5944, 0x5BB4, + 0x5EF6, 0x6028, 0x63A9, 0x63F4, 0x6CBF, 0x6F14, + 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01, + 0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, + 0x5869, 0x65BC, 0x6C5A, 0x7525, 0x51F9, 0x592E, + 0x5965, 0x5F80, 0x5FDC, 0x62BC, 0x65FA, 0x6A2A, + 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956, 0x9D2C, + 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, + 0x5C4B, 0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, + 0x4FFA, 0x5378, 0x6069, 0x6E29, 0x7A4F, 0x97F3, + 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D, 0x4FA1, + 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, + 0x5BB6, 0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, + 0x6B4C, 0x6CB3, 0x706B, 0x73C2, 0x798D, 0x79BE, + 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304, 0x8377, + 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, + 0x8FE6, 0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, + 0x6211, 0x7259, 0x753B, 0x81E5, 0x82BD, 0x86FE, + 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB, 0x4F1A, + 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, + 0x602A, 0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, + 0x6539, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8A[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B41, 0x6666, + 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75, + 0x82A5, 0x87F9, 0x958B, 0x968E, 0x8C9D, 0x51F1, + 0x52BE, 0x5916, 0x54B3, 0x5BB3, 0x5D16, 0x6168, + 0x6982, 0x6DAF, 0x788D, 0x84CB, 0x8857, 0x8A72, + 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3, + 0x67FF, 0x86CE, 0x920E, 0x5283, 0x5687, 0x5404, + 0x5ED3, 0x62E1, 0x64B9, 0x683C, 0x6838, 0x6BBB, + 0x7372, 0x78BA, 0x7A6B, 0x899A, 0x89D2, 0x8D6B, + 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66, + 0x5CB3, 0x697D, 0x984D, 0x984E, 0x639B, 0x7B20, + 0x6A2B, 0x0000, 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F, + 0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B, 0x6E07, + 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39, + 0x53F6, 0x691B, 0x6A3A, 0x9784, 0x682A, 0x515C, + 0x7AC3, 0x84B2, 0x91DC, 0x938C, 0x565B, 0x9D28, + 0x6822, 0x8305, 0x8431, 0x7CA5, 0x5208, 0x82C5, + 0x74E6, 0x4E7E, 0x4F83, 0x51A0, 0x5BD2, 0x520A, + 0x52D8, 0x52E7, 0x5DFB, 0x559A, 0x582A, 0x59E6, + 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, + 0x611F, 0x6163, 0x61BE, 0x63DB, 0x6562, 0x67D1, + 0x6853, 0x68FA, 0x6B3E, 0x6B53, 0x6C57, 0x6F22, + 0x6F97, 0x6F45, 0x74B0, 0x7518, 0x76E3, 0x770B, + 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, + 0x809D, 0x8266, 0x839E, 0x89B3, 0x8ACC, 0x8CAB, + 0x9084, 0x9451, 0x9593, 0x9591, 0x95A2, 0x9665, + 0x97D3, 0x9928, 0x8218, 0x4E38, 0x542B, 0x5CB8, + 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, + 0x8D0B, 0x96C1, 0x9811, 0x9854, 0x9858, 0x4F01, + 0x4F0E, 0x5371, 0x559C, 0x5668, 0x57FA, 0x5947, + 0x5B09, 0x5BC4, 0x5C90, 0x5E0C, 0x5E7E, 0x5FCC, + 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, + 0x68C4, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6A5F, 0x5E30, + 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948, 0x5B63, + 0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, + 0x8D77, 0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, + 0x4E80, 0x507D, 0x5100, 0x5993, 0x5B9C, 0x622F, + 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591, 0x7947, + 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, + 0x97A0, 0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, + 0x8A70, 0x7827, 0x6775, 0x9ECD, 0x5374, 0x5BA2, + 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45, 0x4EC7, + 0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, + 0x6551, 0x0000, 0x673D, 0x6C42, 0x6C72, 0x6CE3, + 0x7078, 0x7403, 0x7A76, 0x7AAE, 0x7B08, 0x7D1A, + 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45, + 0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, + 0x8A31, 0x8DDD, 0x92F8, 0x6F01, 0x79A6, 0x9B5A, + 0x4EA8, 0x4EAB, 0x4EAC, 0x4F9B, 0x4FA0, 0x50D1, + 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354, 0x5321, + 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, + 0x5F4A, 0x602F, 0x6050, 0x606D, 0x631F, 0x6559, + 0x6A4B, 0x6CC1, 0x72C2, 0x72ED, 0x77EF, 0x80F8, + 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1, 0x97FF, + 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, + 0x696D, 0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, + 0x7C81, 0x50C5, 0x52E4, 0x5747, 0x5DFE, 0x9326, + 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981, 0x79BD, + 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, + 0x8B39, 0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, + 0x5036, 0x53E5, 0x533A, 0x72D7, 0x7396, 0x77E9, + 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2, 0x5177, + 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, + 0x9047, 0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, + 0x5C48, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6398, 0x7A9F, + 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688, + 0x7C82, 0x6817, 0x7E70, 0x6851, 0x936C, 0x52F2, + 0x541B, 0x85AB, 0x8A13, 0x7FA4, 0x8ECD, 0x90E1, + 0x5366, 0x8888, 0x7941, 0x4FC2, 0x50BE, 0x5211, + 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B, 0x5951, + 0x5F62, 0x5F84, 0x6075, 0x6176, 0x6167, 0x61A9, + 0x63B2, 0x643A, 0x656C, 0x666F, 0x6842, 0x6E13, + 0x7566, 0x7A3D, 0x7CFB, 0x7D4C, 0x7D99, 0x7E4B, + 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63, + 0x8B66, 0x8EFD, 0x981A, 0x9D8F, 0x82B8, 0x8FCE, + 0x9BE8, 0x0000, 0x5287, 0x621F, 0x6483, 0x6FC0, + 0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A, 0x6F54, + 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6, + 0x5039, 0x5026, 0x5065, 0x517C, 0x5238, 0x5263, + 0x55A7, 0x570F, 0x5805, 0x5ACC, 0x5EFA, 0x61B2, + 0x61F8, 0x62F3, 0x6372, 0x691C, 0x6A29, 0x727D, + 0x72AC, 0x732E, 0x7814, 0x786F, 0x7D79, 0x770C, + 0x80A9, 0x898B, 0x8B19, 0x8CE2, 0x8ED2, 0x9063, + 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, + 0x539F, 0x53B3, 0x5E7B, 0x5F26, 0x6E1B, 0x6E90, + 0x7384, 0x73FE, 0x7D43, 0x8237, 0x8A00, 0x8AFA, + 0x9650, 0x4E4E, 0x500B, 0x53E4, 0x547C, 0x56FA, + 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, + 0x6545, 0x67AF, 0x6E56, 0x72D0, 0x7CCA, 0x88B4, + 0x80A1, 0x80E1, 0x83F0, 0x864E, 0x8A87, 0x8DE8, + 0x9237, 0x96C7, 0x9867, 0x9F13, 0x4E94, 0x4E92, + 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, + 0x5FA1, 0x609F, 0x68A7, 0x6A8E, 0x745A, 0x7881, + 0x8A9E, 0x8AA4, 0x8B77, 0x9190, 0x4E5E, 0x9BC9, + 0x4EA4, 0x4F7C, 0x4FAF, 0x5019, 0x5016, 0x5149, + 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, + 0x5411, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x540E, 0x5589, + 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D, 0x5B8F, + 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, + 0x5EB7, 0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, + 0x63A7, 0x653B, 0x6602, 0x6643, 0x66F4, 0x676D, + 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A, 0x6D69, + 0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, + 0x7CE0, 0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, + 0x8003, 0x80AF, 0x80B1, 0x8154, 0x818F, 0x822A, + 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2, 0x8CFC, + 0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, + 0x964D, 0x0000, 0x9805, 0x9999, 0x9AD8, 0x9D3B, + 0x525B, 0x52AB, 0x53F7, 0x5408, 0x58D5, 0x62F7, + 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B, + 0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, + 0x7344, 0x6F09, 0x8170, 0x7511, 0x5FFD, 0x60DA, + 0x9AA8, 0x72DB, 0x8FBC, 0x6B64, 0x9803, 0x4ECA, + 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068, 0x61C7, + 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, + 0x7D3A, 0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, + 0x5506, 0x5D6F, 0x5DE6, 0x5DEE, 0x67FB, 0x6C99, + 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF, 0x5750, + 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, + 0x54C9, 0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, + 0x63A1, 0x683D, 0x6B73, 0x6E08, 0x707D, 0x91C7, + 0x7280, 0x7815, 0x7826, 0x796D, 0x658E, 0x7D30, + 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, + 0x6750, 0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, + 0x583A, 0x698A, 0x80B4, 0x54B2, 0x5D0E, 0x57FC, + 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B, 0x643E, + 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, + 0x932F, 0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, + 0x5237, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5BDF, 0x62F6, + 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1, + 0x7690, 0x9BD6, 0x634C, 0x9306, 0x9BAB, 0x76BF, + 0x6652, 0x4E09, 0x5098, 0x53C2, 0x5C71, 0x60E8, + 0x6492, 0x6563, 0x685F, 0x71E6, 0x73CA, 0x7523, + 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178, + 0x9910, 0x65AC, 0x66AB, 0x6B8B, 0x4ED5, 0x4ED4, + 0x4F3A, 0x4F7F, 0x523A, 0x53F8, 0x53F2, 0x55E3, + 0x56DB, 0x58EB, 0x59CB, 0x59C9, 0x59FF, 0x5B50, + 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307, + 0x652F, 0x5B5C, 0x65AF, 0x65BD, 0x65E8, 0x679D, + 0x6B62, 0x0000, 0x6B7B, 0x6C0F, 0x7345, 0x7949, + 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2, 0x8102, + 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, + 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC, 0x98FC, 0x6B6F, + 0x4E8B, 0x4F3C, 0x4F8D, 0x5150, 0x5B57, 0x5BFA, + 0x6148, 0x6301, 0x6642, 0x6B21, 0x6ECB, 0x6CBB, + 0x723E, 0x74BD, 0x75D4, 0x78C1, 0x793A, 0x800C, + 0x8033, 0x81EA, 0x8494, 0x8F9E, 0x6C50, 0x9E7F, + 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, + 0x96EB, 0x4E03, 0x53F1, 0x57F7, 0x5931, 0x5AC9, + 0x5BA4, 0x6089, 0x6E7F, 0x6F06, 0x75BE, 0x8CEA, + 0x5B9F, 0x8500, 0x7BE0, 0x5072, 0x67F4, 0x829D, + 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, + 0x6368, 0x8D66, 0x659C, 0x716E, 0x793E, 0x7D17, + 0x8005, 0x8B1D, 0x8ECA, 0x906E, 0x86C7, 0x90AA, + 0x501F, 0x52FA, 0x5C3A, 0x6753, 0x707C, 0x7235, + 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, + 0x60F9, 0x4E3B, 0x53D6, 0x5B88, 0x624B, 0x6731, + 0x6B8A, 0x72E9, 0x73E0, 0x7A2E, 0x816B, 0x8DA3, + 0x9152, 0x9996, 0x5112, 0x53D7, 0x546A, 0x5BFF, + 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, + 0x5468, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8F[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5B97, 0x5C31, + 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32, 0x79C0, + 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, + 0x8490, 0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, + 0x9031, 0x914B, 0x916C, 0x96C6, 0x919C, 0x4EC0, + 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E, 0x67D4, + 0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, + 0x53D4, 0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, + 0x7C9B, 0x587E, 0x719F, 0x51FA, 0x8853, 0x8FF0, + 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3, 0x821C, + 0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, + 0x6DF3, 0x0000, 0x6E96, 0x6F64, 0x76FE, 0x7D14, + 0x5DE1, 0x9075, 0x9187, 0x9806, 0x51E6, 0x521D, + 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2, + 0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, + 0x53D9, 0x5973, 0x5E8F, 0x5F90, 0x6055, 0x92E4, + 0x9664, 0x50B7, 0x511F, 0x52DD, 0x5320, 0x5347, + 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617, 0x5968, + 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, + 0x5C1A, 0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, + 0x6284, 0x62DB, 0x638C, 0x6377, 0x6607, 0x660C, + 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F, 0x6A35, + 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, + 0x7167, 0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, + 0x79F0, 0x7AE0, 0x7B11, 0x7CA7, 0x7D39, 0x8096, + 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3, 0x8A1F, + 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, + 0x9266, 0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, + 0x4E08, 0x4E1E, 0x4E57, 0x5197, 0x5270, 0x57CE, + 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5, 0x64FE, + 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, + 0x84B8, 0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, + 0x98FE, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis90[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x62ED, 0x690D, + 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6, + 0x98DF, 0x8755, 0x8FB1, 0x5C3B, 0x4F38, 0x4FE1, + 0x4FB5, 0x5507, 0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, + 0x614E, 0x632F, 0x65B0, 0x664B, 0x68EE, 0x699B, + 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E, + 0x79E6, 0x7D33, 0x81E3, 0x82AF, 0x85AA, 0x89AA, + 0x8A3A, 0x8EAB, 0x8F9B, 0x9032, 0x91DD, 0x9707, + 0x4EBA, 0x4EC1, 0x5203, 0x5875, 0x58EC, 0x5C0B, + 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663, + 0x976D, 0x7B25, 0x8ACF, 0x9808, 0x9162, 0x56F3, + 0x53A8, 0x0000, 0x9017, 0x5439, 0x5782, 0x5E25, + 0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B, 0x7FE0, + 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F, + 0x745E, 0x9AC4, 0x5D07, 0x5D69, 0x6570, 0x67A2, + 0x8DA8, 0x96DB, 0x636E, 0x6749, 0x6919, 0x83C5, + 0x9817, 0x96C0, 0x88FE, 0x6F84, 0x647A, 0x5BF8, + 0x4E16, 0x702C, 0x755D, 0x662F, 0x51C4, 0x5236, + 0x52E2, 0x59D3, 0x5F81, 0x6027, 0x6210, 0x653F, + 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, + 0x6E05, 0x7272, 0x751F, 0x76DB, 0x7CBE, 0x8056, + 0x58F0, 0x88FD, 0x897F, 0x8AA0, 0x8A93, 0x8ACB, + 0x901D, 0x9192, 0x9752, 0x9759, 0x6589, 0x7A0E, + 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, + 0x6614, 0x6790, 0x77F3, 0x7A4D, 0x7C4D, 0x7E3E, + 0x810A, 0x8CAC, 0x8D64, 0x8DE1, 0x8E5F, 0x78A9, + 0x5207, 0x62D9, 0x63A5, 0x6442, 0x6298, 0x8A2D, + 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, + 0x8749, 0x4ED9, 0x5148, 0x5343, 0x5360, 0x5BA3, + 0x5C02, 0x5C16, 0x5DDD, 0x6226, 0x6247, 0x64B0, + 0x6813, 0x6834, 0x6CC9, 0x6D45, 0x6D17, 0x67D3, + 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, + 0x7DDA, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis91[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7E4A, 0x7FA8, + 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E, 0x8CCE, + 0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, + 0x9BAE, 0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, + 0x7985, 0x7E55, 0x81B3, 0x7CCE, 0x564C, 0x5851, + 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A, 0x72D9, + 0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, + 0x7D20, 0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, + 0x9F20, 0x50E7, 0x5275, 0x53CC, 0x53E2, 0x5009, + 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B, 0x5C64, + 0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, + 0x63BB, 0x0000, 0x64CD, 0x65E9, 0x66F9, 0x5DE3, + 0x69CD, 0x69FD, 0x6F15, 0x71E5, 0x4E89, 0x75E9, + 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061, + 0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, + 0x8D70, 0x9001, 0x906D, 0x9397, 0x971C, 0x9A12, + 0x50CF, 0x5897, 0x618E, 0x81D3, 0x8535, 0x8D08, + 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373, 0x606F, + 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, + 0x5C5E, 0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, + 0x5176, 0x63C3, 0x5B58, 0x5B6B, 0x5C0A, 0x640D, + 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A, 0x6C70, + 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, + 0x67C1, 0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, + 0x4F53, 0x5806, 0x5BFE, 0x8010, 0x5CB1, 0x5E2F, + 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF, 0x6CF0, + 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, + 0x9000, 0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, + 0x53F0, 0x5927, 0x7B2C, 0x918D, 0x984C, 0x9DF9, + 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85, 0x6258, + 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, + 0x9438, 0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, + 0x53EA, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis92[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x53E9, 0x4F46, + 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA, + 0x8FBF, 0x68DA, 0x8C37, 0x72F8, 0x9C48, 0x6A3D, + 0x8AB0, 0x4E39, 0x5358, 0x5606, 0x5766, 0x62C5, + 0x63A2, 0x65E6, 0x6B4E, 0x6DE1, 0x6E5B, 0x70AD, + 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6, + 0x86CB, 0x8A95, 0x935B, 0x56E3, 0x58C7, 0x5F3E, + 0x65AD, 0x6696, 0x6A80, 0x6BB5, 0x7537, 0x8AC7, + 0x5024, 0x77E5, 0x5730, 0x5F1B, 0x6065, 0x667A, + 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718, + 0x9045, 0x99B3, 0x7BC9, 0x755C, 0x7AF9, 0x7B51, + 0x84C4, 0x0000, 0x9010, 0x79E9, 0x7A92, 0x8336, + 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99, 0x5FE0, + 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877, + 0x8A3B, 0x914E, 0x92F3, 0x99D0, 0x6A17, 0x7026, + 0x732A, 0x82E7, 0x8457, 0x8CAF, 0x4E01, 0x5146, + 0x51CB, 0x558B, 0x5BF5, 0x5E16, 0x5E33, 0x5E81, + 0x5F14, 0x5F35, 0x5F6B, 0x5FB4, 0x61F2, 0x6311, + 0x66A2, 0x671D, 0x6F6E, 0x7252, 0x753A, 0x773A, + 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, + 0x8D85, 0x8DF3, 0x929A, 0x9577, 0x9802, 0x9CE5, + 0x52C5, 0x6357, 0x76F4, 0x6715, 0x6C88, 0x73CD, + 0x8CC3, 0x93AE, 0x9673, 0x6D25, 0x589C, 0x690E, + 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, + 0x6802, 0x63B4, 0x69FB, 0x4F43, 0x6F2C, 0x67D8, + 0x8FBB, 0x8526, 0x7DB4, 0x9354, 0x693F, 0x6F70, + 0x576A, 0x58F7, 0x5B2C, 0x7D2C, 0x722A, 0x540A, + 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, + 0x5243, 0x8C9E, 0x5448, 0x5824, 0x5B9A, 0x5E1D, + 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F, 0x608C, 0x62B5, + 0x633A, 0x63D0, 0x68AF, 0x6C40, 0x7887, 0x798E, + 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, + 0x9013, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis93[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x90B8, 0x912D, + 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2, 0x6575, + 0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, + 0x54F2, 0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, + 0x5178, 0x586B, 0x5929, 0x5C55, 0x5E97, 0x6DFB, + 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B, 0x70B9, + 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, + 0x5410, 0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, + 0x6597, 0x675C, 0x6E21, 0x767B, 0x83DF, 0x8CED, + 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A, 0x52AA, + 0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, + 0x51AC, 0x0000, 0x51CD, 0x5200, 0x5510, 0x5854, + 0x5858, 0x5957, 0x5B95, 0x5CF6, 0x5D8B, 0x60BC, + 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF, + 0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, + 0x5F53, 0x75D8, 0x7977, 0x7B49, 0x7B54, 0x7B52, + 0x7CD6, 0x7D71, 0x5230, 0x8463, 0x8569, 0x85E4, + 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003, 0x900F, + 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, + 0x52D5, 0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, + 0x6D1E, 0x77B3, 0x7AE5, 0x80F4, 0x8404, 0x9053, + 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97, 0x5FB3, + 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, + 0x72EC, 0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, + 0x6934, 0x5C4A, 0x9CF6, 0x82EB, 0x5BC5, 0x9149, + 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566, 0x6C8C, + 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, + 0x5948, 0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, + 0x8B0E, 0x7058, 0x637A, 0x934B, 0x6962, 0x99B4, + 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF, 0x96E3, + 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, + 0x8CD1, 0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, + 0x5165, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis94[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5982, 0x5C3F, + 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1, + 0x79B0, 0x7962, 0x5BE7, 0x8471, 0x732B, 0x71B1, + 0x5E74, 0x5FF5, 0x637B, 0x649A, 0x71C3, 0x7C98, + 0x4E43, 0x5EFC, 0x4E4B, 0x57DC, 0x56A2, 0x60A9, + 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2, + 0x8997, 0x86A4, 0x5DF4, 0x628A, 0x64AD, 0x8987, + 0x6777, 0x6CE2, 0x6D3E, 0x7436, 0x7834, 0x5A46, + 0x7F75, 0x82AD, 0x99AC, 0x4FF3, 0x5EC3, 0x62DD, + 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC, + 0x80BA, 0x8F29, 0x914D, 0x500D, 0x57F9, 0x5A92, + 0x6885, 0x0000, 0x6973, 0x7164, 0x72FD, 0x8CB7, + 0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F, 0x79E4, + 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD, + 0x67CF, 0x6CCA, 0x767D, 0x7B94, 0x7C95, 0x8236, + 0x8584, 0x8FEB, 0x66DD, 0x6F20, 0x7206, 0x7E1B, + 0x83AB, 0x99C1, 0x9EA6, 0x51FD, 0x7BB1, 0x7872, + 0x7BB8, 0x8087, 0x7B48, 0x6AE8, 0x5E61, 0x808C, + 0x7551, 0x7560, 0x516B, 0x9262, 0x6E8C, 0x767A, + 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, + 0x95A5, 0x9CE9, 0x567A, 0x5859, 0x86E4, 0x96BC, + 0x4F34, 0x5224, 0x534A, 0x53CD, 0x53DB, 0x5E06, + 0x642C, 0x6591, 0x677F, 0x6C3E, 0x6C4E, 0x7248, + 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, + 0x8CA9, 0x7BC4, 0x91C6, 0x7169, 0x9812, 0x98EF, + 0x633D, 0x6669, 0x756A, 0x76E4, 0x78D0, 0x8543, + 0x86EE, 0x532A, 0x5351, 0x5426, 0x5983, 0x5E87, + 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, + 0x6BD4, 0x6CCC, 0x75B2, 0x76AE, 0x7891, 0x79D8, + 0x7DCB, 0x7F77, 0x80A5, 0x88AB, 0x8AB9, 0x8CBB, + 0x907F, 0x975E, 0x98DB, 0x6A0B, 0x7C38, 0x5099, + 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, + 0x7F8E, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis95[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9F3B, 0x67CA, + 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66, 0x819D, + 0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, + 0x903C, 0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, + 0x8B2C, 0x4FF5, 0x5F6A, 0x6A19, 0x6C37, 0x6F02, + 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79, 0x5EDF, + 0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, + 0x849C, 0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, + 0x6D5C, 0x7015, 0x8CA7, 0x8CD3, 0x983B, 0x654F, + 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B, 0x5A66, + 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, + 0x6577, 0x0000, 0x65A7, 0x666E, 0x6D6E, 0x7236, + 0x7B26, 0x8150, 0x819A, 0x8299, 0x8B5C, 0x8CA0, + 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB, + 0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, + 0x6953, 0x98A8, 0x847A, 0x8557, 0x4F0F, 0x526F, + 0x5FA9, 0x5E45, 0x670D, 0x798F, 0x8179, 0x8907, + 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8, 0x4ECF, + 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, + 0x61A4, 0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, + 0x7D1B, 0x96F0, 0x6587, 0x805E, 0x4E19, 0x4F75, + 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A, 0x67C4, + 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, + 0x50FB, 0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, + 0x8511, 0x7B86, 0x504F, 0x5909, 0x7247, 0x7BC7, + 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF, 0x52C9, + 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, + 0x5703, 0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, + 0x7A42, 0x52DF, 0x5893, 0x6155, 0x620A, 0x66AE, + 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8, 0x5305, + 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, + 0x5D29, 0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, + 0x670B, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis96[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6CD5, 0x6CE1, + 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C, + 0x84EC, 0x8702, 0x8912, 0x8A2A, 0x8C4A, 0x90A6, + 0x92D2, 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, + 0x508D, 0x5256, 0x574A, 0x59A8, 0x5E3D, 0x5FD8, + 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2, + 0x5192, 0x7D21, 0x80AA, 0x81A8, 0x8B00, 0x8C8C, + 0x8CBF, 0x927E, 0x9632, 0x5420, 0x982C, 0x5317, + 0x50D5, 0x535C, 0x58A8, 0x64B2, 0x6734, 0x7267, + 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86, + 0x5800, 0x5E4C, 0x5954, 0x672C, 0x7FFB, 0x51E1, + 0x76C6, 0x0000, 0x6469, 0x78E8, 0x9B54, 0x9EBB, + 0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE, 0x54E9, + 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE, + 0x9C52, 0x685D, 0x4EA6, 0x4FE3, 0x53C8, 0x62B9, + 0x672B, 0x6CAB, 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF, + 0x4E07, 0x6162, 0x6E80, 0x6F2B, 0x8513, 0x5473, + 0x672A, 0x9B45, 0x5DF3, 0x7B95, 0x5CAC, 0x5BC6, + 0x871C, 0x6E4A, 0x84D1, 0x7A14, 0x8108, 0x5999, + 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, + 0x725F, 0x77DB, 0x9727, 0x9D61, 0x690B, 0x5A7F, + 0x5A18, 0x51A5, 0x540D, 0x547D, 0x660E, 0x76DF, + 0x8FF7, 0x9298, 0x9CF4, 0x59EA, 0x725D, 0x6EC5, + 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, + 0x6478, 0x6A21, 0x8302, 0x5984, 0x5B5F, 0x6BDB, + 0x731B, 0x76F2, 0x7DB2, 0x8017, 0x8499, 0x5132, + 0x6728, 0x9ED9, 0x76EE, 0x6762, 0x52FF, 0x9905, + 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, + 0x7D0B, 0x9580, 0x5301, 0x4E5F, 0x51B6, 0x591C, + 0x723A, 0x8036, 0x91CE, 0x5F25, 0x77E2, 0x5384, + 0x5F79, 0x7D04, 0x85AC, 0x8A33, 0x8E8D, 0x9756, + 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, + 0x7652, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis97[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8AED, 0x8F38, + 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB, 0x5BA5, + 0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, + 0x6E67, 0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, + 0x88D5, 0x8A98, 0x904A, 0x9091, 0x90F5, 0x96C4, + 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E, 0x8A89, + 0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, + 0x5EB8, 0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, + 0x69D8, 0x6D0B, 0x6EB6, 0x7194, 0x7528, 0x7AAF, + 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981, 0x8B21, + 0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, + 0x6B32, 0x0000, 0x6C83, 0x6D74, 0x7FCC, 0x7FFC, + 0x6DC0, 0x7F85, 0x87BA, 0x88F8, 0x6765, 0x83B1, + 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A, + 0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, + 0x862D, 0x89A7, 0x5229, 0x540F, 0x5C65, 0x674E, + 0x68A8, 0x7406, 0x7483, 0x75E2, 0x88CF, 0x88E1, + 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387, 0x7ACB, + 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, + 0x7409, 0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, + 0x9F8D, 0x4FB6, 0x616E, 0x65C5, 0x865C, 0x4E86, + 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE, 0x6599, + 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, + 0x7CE7, 0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, + 0x9818, 0x529B, 0x7DD1, 0x502B, 0x5398, 0x6797, + 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A, 0x96A3, + 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, + 0x985E, 0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, + 0x5DBA, 0x601C, 0x73B2, 0x793C, 0x82D3, 0x9234, + 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62, 0x66A6, + 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, + 0x604B, 0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, + 0x806F, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis98[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x84EE, 0x9023, + 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2, + 0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, + 0x6717, 0x697C, 0x6994, 0x6D6A, 0x6F0F, 0x7262, + 0x72FC, 0x7BED, 0x8001, 0x807E, 0x874B, 0x90CE, + 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6, + 0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, + 0x60D1, 0x67A0, 0x9DF2, 0x4E99, 0x4E98, 0x9C10, + 0x8A6B, 0x85C1, 0x8568, 0x6900, 0x6E7E, 0x7897, + 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5F0C, 0x4E10, 0x4E15, + 0x4E2A, 0x4E31, 0x4E36, 0x4E3C, 0x4E3F, 0x4E42, + 0x4E56, 0x4E58, 0x4E82, 0x4E85, 0x8C6B, 0x4E8A, + 0x8212, 0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, + 0x4EA2, 0x4EB0, 0x4EB3, 0x4EB6, 0x4ECE, 0x4ECD, + 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7, 0x4EDE, 0x4EED, + 0x4EDF, 0x4EF7, 0x4F09, 0x4F5A, 0x4F30, 0x4F5B, + 0x4F5D, 0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, + 0x4F98, 0x4F7B, 0x4F69, 0x4F70, 0x4F91, 0x4F6F, + 0x4F86, 0x4F96, 0x5118, 0x4FD4, 0x4FDF, 0x4FCE, + 0x4FD8, 0x4FDB, 0x4FD1, 0x4FDA, 0x4FD0, 0x4FE4, + 0x4FE5, 0x501A, 0x5028, 0x5014, 0x502A, 0x5025, + 0x5005, 0x4F1C, 0x4FF6, 0x5021, 0x5029, 0x502C, + 0x4FFE, 0x4FEF, 0x5011, 0x5006, 0x5043, 0x5047, + 0x6703, 0x5055, 0x5050, 0x5048, 0x505A, 0x5056, + 0x506C, 0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, + 0x50B2, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis99[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x50C9, 0x50CA, + 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5, 0x50ED, + 0x50E3, 0x50EE, 0x50F9, 0x50F5, 0x5109, 0x5101, + 0x5102, 0x5116, 0x5115, 0x5114, 0x511A, 0x5121, + 0x513A, 0x5137, 0x513C, 0x513B, 0x513F, 0x5140, + 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8, 0x5169, + 0x516A, 0x516E, 0x5180, 0x5182, 0x56D8, 0x518C, + 0x5189, 0x518F, 0x5191, 0x5193, 0x5195, 0x5196, + 0x51A4, 0x51A6, 0x51A2, 0x51A9, 0x51AA, 0x51AB, + 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5, 0x51BD, + 0x51C5, 0x51C9, 0x51DB, 0x51E0, 0x8655, 0x51E9, + 0x51ED, 0x0000, 0x51F0, 0x51F5, 0x51FE, 0x5204, + 0x520B, 0x5214, 0x520E, 0x5227, 0x522A, 0x522E, + 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C, + 0x525E, 0x5254, 0x526A, 0x5274, 0x5269, 0x5273, + 0x527F, 0x527D, 0x528D, 0x5294, 0x5292, 0x5271, + 0x5288, 0x5291, 0x8FA8, 0x8FA7, 0x52AC, 0x52AD, + 0x52BC, 0x52B5, 0x52C1, 0x52CD, 0x52D7, 0x52DE, + 0x52E3, 0x52E6, 0x98ED, 0x52E0, 0x52F3, 0x52F5, + 0x52F8, 0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, + 0x5310, 0x530F, 0x5315, 0x531A, 0x5323, 0x532F, + 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, 0x5345, + 0x4E17, 0x5349, 0x534D, 0x51D6, 0x535E, 0x5369, + 0x536E, 0x5918, 0x537B, 0x5377, 0x5382, 0x5396, + 0x53A0, 0x53A6, 0x53A5, 0x53AE, 0x53B0, 0x53B6, + 0x53C3, 0x7C12, 0x96D9, 0x53DF, 0x66FC, 0x71EE, + 0x53EE, 0x53E8, 0x53ED, 0x53FA, 0x5401, 0x543D, + 0x5440, 0x542C, 0x542D, 0x543C, 0x542E, 0x5436, + 0x5429, 0x541D, 0x544E, 0x548F, 0x5475, 0x548E, + 0x545F, 0x5471, 0x5477, 0x5470, 0x5492, 0x547B, + 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54C7, + 0x54A2, 0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, + 0x54A8, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9A[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x54AB, 0x54C2, + 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5, 0x54E6, + 0x550F, 0x5514, 0x54FD, 0x54EE, 0x54ED, 0x54FA, + 0x54E2, 0x5539, 0x5540, 0x5563, 0x554C, 0x552E, + 0x555C, 0x5545, 0x5556, 0x5557, 0x5538, 0x5533, + 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A, 0x559F, + 0x557B, 0x557E, 0x5598, 0x559E, 0x55AE, 0x557C, + 0x5583, 0x55A9, 0x5587, 0x55A8, 0x55DA, 0x55C5, + 0x55DF, 0x55C4, 0x55DC, 0x55E4, 0x55D4, 0x5614, + 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B, 0x55F9, + 0x564E, 0x5650, 0x71DF, 0x5634, 0x5636, 0x5632, + 0x5638, 0x0000, 0x566B, 0x5664, 0x562F, 0x566C, + 0x566A, 0x5686, 0x5680, 0x568A, 0x56A0, 0x5694, + 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2, + 0x56BC, 0x56C1, 0x56C3, 0x56C0, 0x56C8, 0x56CE, + 0x56D1, 0x56D3, 0x56D7, 0x56EE, 0x56F9, 0x5700, + 0x56FF, 0x5704, 0x5709, 0x5708, 0x570B, 0x570D, + 0x5713, 0x5718, 0x5716, 0x55C7, 0x571C, 0x5726, + 0x5737, 0x5738, 0x574E, 0x573B, 0x5740, 0x574F, + 0x5769, 0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, + 0x5793, 0x57A0, 0x57B3, 0x57A4, 0x57AA, 0x57B0, + 0x57C3, 0x57C6, 0x57D4, 0x57D2, 0x57D3, 0x580A, + 0x57D6, 0x57E3, 0x580B, 0x5819, 0x581D, 0x5872, + 0x5821, 0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, + 0x583D, 0x5879, 0x5885, 0x58B9, 0x589F, 0x58AB, + 0x58BA, 0x58DE, 0x58BB, 0x58B8, 0x58AE, 0x58C5, + 0x58D3, 0x58D1, 0x58D7, 0x58D9, 0x58D8, 0x58E5, + 0x58DC, 0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, + 0x58FB, 0x58FC, 0x58FD, 0x5902, 0x590A, 0x5910, + 0x591B, 0x68A6, 0x5925, 0x592C, 0x592D, 0x5932, + 0x5938, 0x593E, 0x7AD2, 0x5955, 0x5950, 0x594E, + 0x595A, 0x5958, 0x5962, 0x5960, 0x5967, 0x596C, + 0x5969, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5978, 0x5981, + 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2, 0x59C6, + 0x59E8, 0x59DC, 0x598D, 0x59D9, 0x59DA, 0x5A25, + 0x5A1F, 0x5A11, 0x5A1C, 0x5A09, 0x5A1A, 0x5A40, + 0x5A6C, 0x5A49, 0x5A35, 0x5A36, 0x5A62, 0x5A6A, + 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2, 0x5ABD, + 0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, 0x5AD6, 0x5AFA, + 0x5AFB, 0x5B0C, 0x5B0B, 0x5B16, 0x5B32, 0x5AD0, + 0x5B2A, 0x5B36, 0x5B3E, 0x5B43, 0x5B45, 0x5B40, + 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65, 0x5B69, + 0x5B70, 0x5B73, 0x5B75, 0x5B78, 0x6588, 0x5B7A, + 0x5B80, 0x0000, 0x5B83, 0x5BA6, 0x5BB8, 0x5BC3, + 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0, 0x5BE4, 0x5BE6, + 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6, + 0x5BF3, 0x5C05, 0x5C07, 0x5C08, 0x5C0D, 0x5C13, + 0x5C20, 0x5C22, 0x5C28, 0x5C38, 0x5C39, 0x5C41, + 0x5C46, 0x5C4E, 0x5C53, 0x5C50, 0x5C4F, 0x5B71, + 0x5C6C, 0x5C6E, 0x4E62, 0x5C76, 0x5C79, 0x5C8C, + 0x5C91, 0x5C94, 0x599B, 0x5CAB, 0x5CBB, 0x5CB6, + 0x5CBC, 0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, + 0x5CE9, 0x5CFD, 0x5CFA, 0x5CED, 0x5D8C, 0x5CEA, + 0x5D0B, 0x5D15, 0x5D17, 0x5D5C, 0x5D1F, 0x5D1B, + 0x5D11, 0x5D14, 0x5D22, 0x5D1A, 0x5D19, 0x5D18, + 0x5D4C, 0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, + 0x5D76, 0x5D87, 0x5D84, 0x5D82, 0x5DA2, 0x5D9D, + 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90, 0x5DB7, 0x5DBC, + 0x5DC9, 0x5DCD, 0x5DD3, 0x5DD2, 0x5DD6, 0x5DDB, + 0x5DEB, 0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, + 0x5E11, 0x5E1B, 0x5E36, 0x5E37, 0x5E44, 0x5E43, + 0x5E40, 0x5E4E, 0x5E57, 0x5E54, 0x5E5F, 0x5E62, + 0x5E64, 0x5E47, 0x5E75, 0x5E76, 0x5E7A, 0x9EBC, + 0x5E7F, 0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, + 0x5ECF, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5ED6, 0x5EE3, + 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1, 0x5EE8, + 0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, 0x5EF0, 0x5EF4, + 0x5EF8, 0x5EFE, 0x5F03, 0x5F09, 0x5F5D, 0x5F5C, + 0x5F0B, 0x5F11, 0x5F16, 0x5F29, 0x5F2D, 0x5F38, + 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F, 0x5F51, + 0x5F56, 0x5F57, 0x5F59, 0x5F61, 0x5F6D, 0x5F73, + 0x5F77, 0x5F83, 0x5F82, 0x5F7F, 0x5F8A, 0x5F88, + 0x5F91, 0x5F87, 0x5F9E, 0x5F99, 0x5F98, 0x5FA0, + 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB, 0x5FE4, + 0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, 0x5FFF, 0x6021, + 0x6060, 0x0000, 0x6019, 0x6010, 0x6029, 0x600E, + 0x6031, 0x601B, 0x6015, 0x602B, 0x6026, 0x600F, + 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F, + 0x604A, 0x6046, 0x604D, 0x6063, 0x6043, 0x6064, + 0x6042, 0x606C, 0x606B, 0x6059, 0x6081, 0x608D, + 0x60E7, 0x6083, 0x609A, 0x6084, 0x609B, 0x6096, + 0x6097, 0x6092, 0x60A7, 0x608B, 0x60E1, 0x60B8, + 0x60E0, 0x60D3, 0x60B4, 0x5FF0, 0x60BD, 0x60C6, + 0x60B5, 0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, + 0x60F7, 0x6100, 0x60F4, 0x60FA, 0x6103, 0x6121, + 0x60FB, 0x60F1, 0x610D, 0x610E, 0x6147, 0x613E, + 0x6128, 0x6127, 0x614A, 0x613F, 0x613C, 0x612C, + 0x6134, 0x613D, 0x6142, 0x6144, 0x6173, 0x6177, + 0x6158, 0x6159, 0x615A, 0x616B, 0x6174, 0x616F, + 0x6165, 0x6171, 0x615F, 0x615D, 0x6153, 0x6175, + 0x6199, 0x6196, 0x6187, 0x61AC, 0x6194, 0x619A, + 0x618A, 0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, + 0x61C9, 0x61F7, 0x61C8, 0x61C3, 0x61C6, 0x61BA, + 0x61CB, 0x7F79, 0x61CD, 0x61E6, 0x61E3, 0x61F6, + 0x61FA, 0x61F4, 0x61FF, 0x61FD, 0x61FC, 0x61FE, + 0x6200, 0x6208, 0x6209, 0x620D, 0x620C, 0x6214, + 0x621B, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x621E, 0x6221, + 0x622A, 0x622E, 0x6230, 0x6232, 0x6233, 0x6241, + 0x624E, 0x625E, 0x6263, 0x625B, 0x6260, 0x6268, + 0x627C, 0x6282, 0x6289, 0x627E, 0x6292, 0x6293, + 0x6296, 0x62D4, 0x6283, 0x6294, 0x62D7, 0x62D1, + 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4, 0x62C8, + 0x62DC, 0x62CC, 0x62CA, 0x62C2, 0x62C7, 0x629B, + 0x62C9, 0x630C, 0x62EE, 0x62F1, 0x6327, 0x6302, + 0x6308, 0x62EF, 0x62F5, 0x6350, 0x633E, 0x634D, + 0x641C, 0x634F, 0x6396, 0x638E, 0x6380, 0x63AB, + 0x6376, 0x63A3, 0x638F, 0x6389, 0x639F, 0x63B5, + 0x636B, 0x0000, 0x6369, 0x63BE, 0x63E9, 0x63C0, + 0x63C6, 0x63E3, 0x63C9, 0x63D2, 0x63F6, 0x63C4, + 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, + 0x651D, 0x6417, 0x6428, 0x640F, 0x6467, 0x646F, + 0x6476, 0x644E, 0x652A, 0x6495, 0x6493, 0x64A5, + 0x64A9, 0x6488, 0x64BC, 0x64DA, 0x64D2, 0x64C5, + 0x64C7, 0x64BB, 0x64D8, 0x64C2, 0x64F1, 0x64E7, + 0x8209, 0x64E0, 0x64E1, 0x62AC, 0x64E3, 0x64EF, + 0x652C, 0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, + 0x64FD, 0x6518, 0x651C, 0x6505, 0x6524, 0x6523, + 0x652B, 0x6534, 0x6535, 0x6537, 0x6536, 0x6538, + 0x754B, 0x6548, 0x6556, 0x6555, 0x654D, 0x6558, + 0x655E, 0x655D, 0x6572, 0x6578, 0x6582, 0x6583, + 0x8B8A, 0x659B, 0x659F, 0x65AB, 0x65B7, 0x65C3, + 0x65C6, 0x65C1, 0x65C4, 0x65CC, 0x65D2, 0x65DB, + 0x65D9, 0x65E0, 0x65E1, 0x65F1, 0x6772, 0x660A, + 0x6603, 0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, + 0x661C, 0x664F, 0x6644, 0x6649, 0x6641, 0x665E, + 0x665D, 0x6664, 0x6667, 0x6668, 0x665F, 0x6662, + 0x6670, 0x6683, 0x6688, 0x668E, 0x6689, 0x6684, + 0x6698, 0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, + 0x66BC, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x66C4, 0x66B8, + 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6, 0x66E9, + 0x66F0, 0x66F5, 0x66F7, 0x670F, 0x6716, 0x671E, + 0x6726, 0x6727, 0x9738, 0x672E, 0x673F, 0x6736, + 0x6741, 0x6738, 0x6737, 0x6746, 0x675E, 0x6760, + 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67A9, + 0x677C, 0x676A, 0x678C, 0x678B, 0x67A6, 0x67A1, + 0x6785, 0x67B7, 0x67EF, 0x67B4, 0x67EC, 0x67B3, + 0x67E9, 0x67B8, 0x67E4, 0x67DE, 0x67DD, 0x67E2, + 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7, 0x6A9C, + 0x681E, 0x6846, 0x6829, 0x6840, 0x684D, 0x6832, + 0x684E, 0x0000, 0x68B3, 0x682B, 0x6859, 0x6863, + 0x6877, 0x687F, 0x689F, 0x688F, 0x68AD, 0x6894, + 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874, + 0x68B5, 0x68A0, 0x68BA, 0x690F, 0x688D, 0x687E, + 0x6901, 0x68CA, 0x6908, 0x68D8, 0x6922, 0x6926, + 0x68E1, 0x690C, 0x68CD, 0x68D4, 0x68E7, 0x68D5, + 0x6936, 0x6912, 0x6904, 0x68D7, 0x68E3, 0x6925, + 0x68F9, 0x68E0, 0x68EF, 0x6928, 0x692A, 0x691A, + 0x6923, 0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, + 0x6978, 0x696B, 0x6954, 0x697E, 0x696E, 0x6939, + 0x6974, 0x693D, 0x6959, 0x6930, 0x6961, 0x695E, + 0x695D, 0x6981, 0x696A, 0x69B2, 0x69AE, 0x69D0, + 0x69BF, 0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, + 0x69CA, 0x69DD, 0x69BB, 0x69C3, 0x69A7, 0x6A2E, + 0x6991, 0x69A0, 0x699C, 0x6995, 0x69B4, 0x69DE, + 0x69E8, 0x6A02, 0x6A1B, 0x69FF, 0x6B0A, 0x69F9, + 0x69F2, 0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, + 0x6A14, 0x69EB, 0x6A0A, 0x6A12, 0x6AC1, 0x6A23, + 0x6A13, 0x6A44, 0x6A0C, 0x6A72, 0x6A36, 0x6A78, + 0x6A47, 0x6A62, 0x6A59, 0x6A66, 0x6A48, 0x6A38, + 0x6A22, 0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, + 0x6AA3, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9F[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6A97, 0x8617, + 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3, 0x6AAC, + 0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, 0x6ADA, 0x6AEA, + 0x6AFB, 0x6B05, 0x8616, 0x6AFA, 0x6B12, 0x6B16, + 0x9B31, 0x6B1F, 0x6B38, 0x6B37, 0x76DC, 0x6B39, + 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50, 0x6B59, + 0x6B54, 0x6B5B, 0x6B5F, 0x6B61, 0x6B78, 0x6B79, + 0x6B7F, 0x6B80, 0x6B84, 0x6B83, 0x6B8D, 0x6B98, + 0x6B95, 0x6B9E, 0x6BA4, 0x6BAA, 0x6BAB, 0x6BAF, + 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC, 0x6BC6, + 0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, 0x6BEB, 0x6BF3, + 0x6BEF, 0x0000, 0x9EBE, 0x6C08, 0x6C13, 0x6C14, + 0x6C1B, 0x6C24, 0x6C23, 0x6C5E, 0x6C55, 0x6C62, + 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B, + 0x6C7E, 0x6C68, 0x6C73, 0x6C92, 0x6C90, 0x6CC4, + 0x6CF1, 0x6CD3, 0x6CBD, 0x6CD7, 0x6CC5, 0x6CDD, + 0x6CAE, 0x6CB1, 0x6CBE, 0x6CBA, 0x6CDB, 0x6CEF, + 0x6CD9, 0x6CEA, 0x6D1F, 0x884D, 0x6D36, 0x6D2B, + 0x6D3D, 0x6D38, 0x6D19, 0x6D35, 0x6D33, 0x6D12, + 0x6D0C, 0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, + 0x6D59, 0x6D8E, 0x6D95, 0x6FE4, 0x6D85, 0x6DF9, + 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7, 0x6DE6, 0x6DB8, + 0x6DC6, 0x6DEC, 0x6DDE, 0x6DCC, 0x6DE8, 0x6DD2, + 0x6DC5, 0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, + 0x6DEE, 0x6E2D, 0x6E6E, 0x6E2E, 0x6E19, 0x6E72, + 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B, 0x6E2B, 0x6E76, + 0x6E4D, 0x6E1F, 0x6E43, 0x6E3A, 0x6E4E, 0x6E24, + 0x6EFF, 0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, + 0x6EC9, 0x6EB7, 0x6ED3, 0x6EBD, 0x6EAF, 0x6EC4, + 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F, 0x6EA5, 0x6EC2, + 0x6E9F, 0x6F41, 0x6F11, 0x704C, 0x6EEC, 0x6EF8, + 0x6EFE, 0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, + 0x6ECC, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE0[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6F3E, 0x6F13, + 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81, 0x6F80, + 0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, 0x6F82, 0x6F7C, + 0x6F58, 0x6F8E, 0x6F91, 0x6FC2, 0x6F66, 0x6FB3, + 0x6FA3, 0x6FA1, 0x6FA4, 0x6FB9, 0x6FC6, 0x6FAA, + 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8, 0x6FF1, + 0x6FEE, 0x6FDB, 0x7009, 0x700B, 0x6FFA, 0x7011, + 0x7001, 0x700F, 0x6FFE, 0x701B, 0x701A, 0x6F74, + 0x701D, 0x7018, 0x701F, 0x7030, 0x703E, 0x7032, + 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF, 0x70F1, + 0x70AC, 0x70B8, 0x70B3, 0x70AE, 0x70DF, 0x70CB, + 0x70DD, 0x0000, 0x70D9, 0x7109, 0x70FD, 0x711C, + 0x7119, 0x7165, 0x7155, 0x7188, 0x7166, 0x7162, + 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184, + 0x7195, 0x71A8, 0x71AC, 0x71D7, 0x71B9, 0x71BE, + 0x71D2, 0x71C9, 0x71D4, 0x71CE, 0x71E0, 0x71EC, + 0x71E7, 0x71F5, 0x71FC, 0x71F9, 0x71FF, 0x720D, + 0x7210, 0x721B, 0x7228, 0x722D, 0x722C, 0x7230, + 0x7232, 0x723B, 0x723C, 0x723F, 0x7240, 0x7246, + 0x724B, 0x7258, 0x7274, 0x727E, 0x7282, 0x7281, + 0x7287, 0x7292, 0x7296, 0x72A2, 0x72A7, 0x72B9, + 0x72B2, 0x72C3, 0x72C6, 0x72C4, 0x72CE, 0x72D2, + 0x72E2, 0x72E0, 0x72E1, 0x72F9, 0x72F7, 0x500F, + 0x7317, 0x730A, 0x731C, 0x7316, 0x731D, 0x7334, + 0x732F, 0x7329, 0x7325, 0x733E, 0x734E, 0x734F, + 0x9ED8, 0x7357, 0x736A, 0x7368, 0x7370, 0x7378, + 0x7375, 0x737B, 0x737A, 0x73C8, 0x73B3, 0x73CE, + 0x73BB, 0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, + 0x7405, 0x746F, 0x7425, 0x73F8, 0x7432, 0x743A, + 0x7455, 0x743F, 0x745F, 0x7459, 0x7441, 0x745C, + 0x7469, 0x7470, 0x7463, 0x746A, 0x7476, 0x747E, + 0x748B, 0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, + 0x73F1, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE1[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x74E0, 0x74E3, + 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0, 0x74F1, + 0x74F8, 0x74F7, 0x7504, 0x7503, 0x7505, 0x750C, + 0x750E, 0x750D, 0x7515, 0x7513, 0x751E, 0x7526, + 0x752C, 0x753C, 0x7544, 0x754D, 0x754A, 0x7549, + 0x755B, 0x7546, 0x755A, 0x7569, 0x7564, 0x7567, + 0x756B, 0x756D, 0x7578, 0x7576, 0x7586, 0x7587, + 0x7574, 0x758A, 0x7589, 0x7582, 0x7594, 0x759A, + 0x759D, 0x75A5, 0x75A3, 0x75C2, 0x75B3, 0x75C3, + 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1, 0x75CD, + 0x75CA, 0x75D2, 0x75D9, 0x75E3, 0x75DE, 0x75FE, + 0x75FF, 0x0000, 0x75FC, 0x7601, 0x75F0, 0x75FA, + 0x75F2, 0x75F3, 0x760B, 0x760D, 0x7609, 0x761F, + 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, + 0x7630, 0x763B, 0x7647, 0x7648, 0x7646, 0x765C, + 0x7658, 0x7661, 0x7662, 0x7668, 0x7669, 0x766A, + 0x7667, 0x766C, 0x7670, 0x7672, 0x7676, 0x7678, + 0x767C, 0x7680, 0x7683, 0x7688, 0x768B, 0x768E, + 0x7696, 0x7693, 0x7699, 0x769A, 0x76B0, 0x76B4, + 0x76B8, 0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, + 0x76D2, 0x76DE, 0x76E1, 0x76E5, 0x76E7, 0x76EA, + 0x862F, 0x76FB, 0x7708, 0x7707, 0x7704, 0x7729, + 0x7724, 0x771E, 0x7725, 0x7726, 0x771B, 0x7737, + 0x7738, 0x7747, 0x775A, 0x7768, 0x776B, 0x775B, + 0x7765, 0x777F, 0x777E, 0x7779, 0x778E, 0x778B, + 0x7791, 0x77A0, 0x779E, 0x77B0, 0x77B6, 0x77B9, + 0x77BF, 0x77BC, 0x77BD, 0x77BB, 0x77C7, 0x77CD, + 0x77D7, 0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, + 0x780C, 0x7812, 0x7926, 0x7820, 0x792A, 0x7845, + 0x788E, 0x7874, 0x7886, 0x787C, 0x789A, 0x788C, + 0x78A3, 0x78B5, 0x78AA, 0x78AF, 0x78D1, 0x78C6, + 0x78CB, 0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, + 0x78EC, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE2[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x78E7, 0x78DA, + 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911, 0x7919, + 0x792C, 0x792B, 0x7940, 0x7960, 0x7957, 0x795F, + 0x795A, 0x7955, 0x7953, 0x797A, 0x797F, 0x798A, + 0x799D, 0x79A7, 0x9F4B, 0x79AA, 0x79AE, 0x79B3, + 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7, 0x79EC, + 0x79E1, 0x79E3, 0x7A08, 0x7A0D, 0x7A18, 0x7A19, + 0x7A20, 0x7A1F, 0x7980, 0x7A31, 0x7A3B, 0x7A3E, + 0x7A37, 0x7A43, 0x7A57, 0x7A49, 0x7A61, 0x7A62, + 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D, 0x7A88, + 0x7A97, 0x7A95, 0x7A98, 0x7A96, 0x7AA9, 0x7AC8, + 0x7AB0, 0x0000, 0x7AB6, 0x7AC5, 0x7AC4, 0x7ABF, + 0x9083, 0x7AC7, 0x7ACA, 0x7ACD, 0x7ACF, 0x7AD5, + 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2, + 0x7AE6, 0x7AED, 0x7AF0, 0x7B02, 0x7B0F, 0x7B0A, + 0x7B06, 0x7B33, 0x7B18, 0x7B19, 0x7B1E, 0x7B35, + 0x7B28, 0x7B36, 0x7B50, 0x7B7A, 0x7B04, 0x7B4D, + 0x7B0B, 0x7B4C, 0x7B45, 0x7B75, 0x7B65, 0x7B74, + 0x7B67, 0x7B70, 0x7B71, 0x7B6C, 0x7B6E, 0x7B9D, + 0x7B98, 0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, + 0x7B92, 0x7B8F, 0x7B5D, 0x7B99, 0x7BCB, 0x7BC1, + 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6, 0x7BDD, 0x7BE9, + 0x7C11, 0x7C14, 0x7BE6, 0x7BE5, 0x7C60, 0x7C00, + 0x7C07, 0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, + 0x7BF6, 0x7C23, 0x7C27, 0x7C2A, 0x7C1F, 0x7C37, + 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43, 0x7C54, 0x7C4F, + 0x7C40, 0x7C50, 0x7C58, 0x7C5F, 0x7C64, 0x7C56, + 0x7C65, 0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, + 0x7CAD, 0x7CA2, 0x7CAB, 0x7CA1, 0x7CA8, 0x7CB3, + 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9, 0x7CBD, 0x7CC0, + 0x7CC5, 0x7CC2, 0x7CD8, 0x7CD2, 0x7CDC, 0x7CE2, + 0x9B3B, 0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, + 0x7D06, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE3[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7D02, 0x7D1C, + 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E, 0x7D32, + 0x7D3F, 0x7D35, 0x7D46, 0x7D73, 0x7D56, 0x7D4E, + 0x7D72, 0x7D68, 0x7D6E, 0x7D4F, 0x7D63, 0x7D93, + 0x7D89, 0x7D5B, 0x7D8F, 0x7D7D, 0x7D9B, 0x7DBA, + 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD, 0x7DAB, + 0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, 0x7DB8, 0x7D9F, + 0x7DB0, 0x7DD8, 0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, + 0x7DF2, 0x7DE1, 0x7E05, 0x7E0A, 0x7E23, 0x7E21, + 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B, 0x7E22, + 0x7E46, 0x7E66, 0x7E3B, 0x7E35, 0x7E39, 0x7E43, + 0x7E37, 0x0000, 0x7E32, 0x7E3A, 0x7E67, 0x7E5D, + 0x7E56, 0x7E5E, 0x7E59, 0x7E5A, 0x7E79, 0x7E6A, + 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D, + 0x8FAE, 0x7E7F, 0x7E88, 0x7E89, 0x7E8C, 0x7E92, + 0x7E90, 0x7E93, 0x7E94, 0x7E96, 0x7E8E, 0x7E9B, + 0x7E9C, 0x7F38, 0x7F3A, 0x7F45, 0x7F4C, 0x7F4D, + 0x7F4E, 0x7F50, 0x7F51, 0x7F55, 0x7F54, 0x7F58, + 0x7F5F, 0x7F60, 0x7F68, 0x7F69, 0x7F67, 0x7F78, + 0x7F82, 0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, + 0x7F94, 0x7F9E, 0x7F9D, 0x7F9A, 0x7FA3, 0x7FAF, + 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6, 0x7FB8, 0x8B71, + 0x7FC5, 0x7FC6, 0x7FCA, 0x7FD5, 0x7FD4, 0x7FE1, + 0x7FE6, 0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, + 0x8004, 0x800B, 0x8012, 0x8018, 0x8019, 0x801C, + 0x8021, 0x8028, 0x803F, 0x803B, 0x804A, 0x8046, + 0x8052, 0x8058, 0x805A, 0x805F, 0x8062, 0x8068, + 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807D, + 0x807F, 0x8084, 0x8086, 0x8085, 0x809B, 0x8093, + 0x809A, 0x80AD, 0x5190, 0x80AC, 0x80DB, 0x80E5, + 0x80D9, 0x80DD, 0x80C4, 0x80DA, 0x80D6, 0x8109, + 0x80EF, 0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, + 0x814B, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE4[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x968B, 0x8146, + 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171, 0x816E, + 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818A, + 0x8180, 0x8182, 0x81A0, 0x8195, 0x81A4, 0x81A3, + 0x815F, 0x8193, 0x81A9, 0x81B0, 0x81B5, 0x81BE, + 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA, 0x81C9, + 0x81CD, 0x81D1, 0x81D9, 0x81D8, 0x81C8, 0x81DA, + 0x81DF, 0x81E0, 0x81E7, 0x81FA, 0x81FB, 0x81FE, + 0x8201, 0x8202, 0x8205, 0x8207, 0x820A, 0x820D, + 0x8210, 0x8216, 0x8229, 0x822B, 0x8238, 0x8233, + 0x8240, 0x8259, 0x8258, 0x825D, 0x825A, 0x825F, + 0x8264, 0x0000, 0x8262, 0x8268, 0x826A, 0x826B, + 0x822E, 0x8271, 0x8277, 0x8278, 0x827E, 0x828D, + 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1, + 0x82E3, 0x82DF, 0x82D2, 0x82F4, 0x82F3, 0x82FA, + 0x8393, 0x8303, 0x82FB, 0x82F9, 0x82DE, 0x8306, + 0x82DC, 0x8309, 0x82D9, 0x8335, 0x8334, 0x8316, + 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, 0x8345, + 0x832F, 0x832B, 0x8317, 0x8318, 0x8385, 0x839A, + 0x83AA, 0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, + 0x8387, 0x838A, 0x837C, 0x83B5, 0x8373, 0x8375, + 0x83A0, 0x8389, 0x83A8, 0x83F4, 0x8413, 0x83EB, + 0x83CE, 0x83FD, 0x8403, 0x83D8, 0x840B, 0x83C1, + 0x83F7, 0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, + 0x8420, 0x83BD, 0x8438, 0x8506, 0x83FB, 0x846D, + 0x842A, 0x843C, 0x855A, 0x8484, 0x8477, 0x846B, + 0x84AD, 0x846E, 0x8482, 0x8469, 0x8446, 0x842C, + 0x846F, 0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, + 0x84BF, 0x849F, 0x84D9, 0x84CD, 0x84BB, 0x84DA, + 0x84D0, 0x84C1, 0x84C6, 0x84D6, 0x84A1, 0x8521, + 0x84FF, 0x84F4, 0x8517, 0x8518, 0x852C, 0x851F, + 0x8515, 0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, + 0x8548, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE5[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8541, 0x8602, + 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588, 0x8591, + 0x858A, 0x85A8, 0x856D, 0x8594, 0x859B, 0x85EA, + 0x8587, 0x859C, 0x8577, 0x857E, 0x8590, 0x85C9, + 0x85BA, 0x85CF, 0x85B9, 0x85D0, 0x85D5, 0x85DD, + 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613, 0x860B, + 0x85FE, 0x85FA, 0x8606, 0x8622, 0x861A, 0x8630, + 0x863F, 0x864D, 0x4E55, 0x8654, 0x865F, 0x8667, + 0x8671, 0x8693, 0x86A3, 0x86A9, 0x86AA, 0x868B, + 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6, 0x86B0, + 0x86C9, 0x8823, 0x86AB, 0x86D4, 0x86DE, 0x86E9, + 0x86EC, 0x0000, 0x86DF, 0x86DB, 0x86EF, 0x8712, + 0x8706, 0x8708, 0x8700, 0x8703, 0x86FB, 0x8711, + 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F, + 0x8737, 0x873B, 0x8725, 0x8729, 0x871A, 0x8760, + 0x875F, 0x8778, 0x874C, 0x874E, 0x8774, 0x8757, + 0x8768, 0x876E, 0x8759, 0x8753, 0x8763, 0x876A, + 0x8805, 0x87A2, 0x879F, 0x8782, 0x87AF, 0x87CB, + 0x87BD, 0x87C0, 0x87D0, 0x96D6, 0x87AB, 0x87C4, + 0x87B3, 0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, + 0x87E0, 0x880F, 0x880D, 0x87FE, 0x87F6, 0x87F7, + 0x880E, 0x87D2, 0x8811, 0x8816, 0x8815, 0x8822, + 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883B, + 0x8844, 0x8842, 0x8852, 0x8859, 0x885E, 0x8862, + 0x886B, 0x8881, 0x887E, 0x889E, 0x8875, 0x887D, + 0x88B5, 0x8872, 0x8882, 0x8897, 0x8892, 0x88AE, + 0x8899, 0x88A2, 0x888D, 0x88A4, 0x88B0, 0x88BF, + 0x88B1, 0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, + 0x88DD, 0x88F9, 0x8902, 0x88FC, 0x88F4, 0x88E8, + 0x88F2, 0x8904, 0x890C, 0x890A, 0x8913, 0x8943, + 0x891E, 0x8925, 0x892A, 0x892B, 0x8941, 0x8944, + 0x893B, 0x8936, 0x8938, 0x894C, 0x891D, 0x8960, + 0x895E, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE6[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8966, 0x8964, + 0x896D, 0x896A, 0x896F, 0x8974, 0x8977, 0x897E, + 0x8983, 0x8988, 0x898A, 0x8993, 0x8998, 0x89A1, + 0x89A9, 0x89A6, 0x89AC, 0x89AF, 0x89B2, 0x89BA, + 0x89BD, 0x89BF, 0x89C0, 0x89DA, 0x89DC, 0x89DD, + 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16, 0x8A10, + 0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, 0x8A36, 0x8A41, + 0x8A5B, 0x8A52, 0x8A46, 0x8A48, 0x8A7C, 0x8A6D, + 0x8A6C, 0x8A62, 0x8A85, 0x8A82, 0x8A84, 0x8AA8, + 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A, 0x8AA3, + 0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, 0x8AEB, 0x8AF3, + 0x8AE7, 0x0000, 0x8AE4, 0x8AF1, 0x8B14, 0x8AE0, + 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB, 0x8B0C, 0x8B07, + 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20, + 0x8B33, 0x97AB, 0x8B26, 0x8B2B, 0x8B3E, 0x8B28, + 0x8B41, 0x8B4C, 0x8B4F, 0x8B4E, 0x8B49, 0x8B56, + 0x8B5B, 0x8B5A, 0x8B6B, 0x8B5F, 0x8B6C, 0x8B6F, + 0x8B74, 0x8B7D, 0x8B80, 0x8B8C, 0x8B8E, 0x8B92, + 0x8B93, 0x8B96, 0x8B99, 0x8B9A, 0x8C3A, 0x8C41, + 0x8C3F, 0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, + 0x8C62, 0x8C6C, 0x8C78, 0x8C7A, 0x8C82, 0x8C89, + 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E, 0x8C94, 0x8C7C, + 0x8C98, 0x621D, 0x8CAD, 0x8CAA, 0x8CBD, 0x8CB2, + 0x8CB3, 0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, + 0x8CE3, 0x8CDA, 0x8CFD, 0x8CFA, 0x8CFB, 0x8D04, + 0x8D05, 0x8D0A, 0x8D07, 0x8D0F, 0x8D0D, 0x8D10, + 0x9F4E, 0x8D13, 0x8CCD, 0x8D14, 0x8D16, 0x8D67, + 0x8D6D, 0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, + 0x8DBE, 0x8DBA, 0x8DCF, 0x8DDA, 0x8DD6, 0x8DCC, + 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB, 0x8DDF, 0x8DE3, + 0x8DFC, 0x8E08, 0x8E09, 0x8DFF, 0x8E1D, 0x8E1E, + 0x8E10, 0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, + 0x8E4A, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE7[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8E47, 0x8E49, + 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64, 0x8E60, + 0x8E2A, 0x8E63, 0x8E55, 0x8E76, 0x8E72, 0x8E7C, + 0x8E81, 0x8E87, 0x8E85, 0x8E84, 0x8E8B, 0x8E8A, + 0x8E93, 0x8E91, 0x8E94, 0x8E99, 0x8EAA, 0x8EA1, + 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE, 0x8EC5, + 0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, 0x8EFC, 0x8EFB, + 0x8EEB, 0x8EFE, 0x8F0A, 0x8F05, 0x8F15, 0x8F12, + 0x8F19, 0x8F13, 0x8F1C, 0x8F1F, 0x8F1B, 0x8F0C, + 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45, 0x8F42, + 0x8F3E, 0x8F4C, 0x8F49, 0x8F46, 0x8F4E, 0x8F57, + 0x8F5C, 0x0000, 0x8F62, 0x8F63, 0x8F64, 0x8F9C, + 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF, 0x8FB7, 0x8FDA, + 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4, + 0x9005, 0x8FF9, 0x8FFA, 0x9011, 0x9015, 0x9021, + 0x900D, 0x901E, 0x9016, 0x900B, 0x9027, 0x9036, + 0x9035, 0x9039, 0x8FF8, 0x904F, 0x9050, 0x9051, + 0x9052, 0x900E, 0x9049, 0x903E, 0x9056, 0x9058, + 0x905E, 0x9068, 0x906F, 0x9076, 0x96A8, 0x9072, + 0x9082, 0x907D, 0x9081, 0x9080, 0x908A, 0x9089, + 0x908F, 0x90A8, 0x90AF, 0x90B1, 0x90B5, 0x90E2, + 0x90E4, 0x6248, 0x90DB, 0x9102, 0x9112, 0x9119, + 0x9132, 0x9130, 0x914A, 0x9156, 0x9158, 0x9163, + 0x9165, 0x9169, 0x9173, 0x9172, 0x918B, 0x9189, + 0x9182, 0x91A2, 0x91AB, 0x91AF, 0x91AA, 0x91B5, + 0x91B4, 0x91BA, 0x91C0, 0x91C1, 0x91C9, 0x91CB, + 0x91D0, 0x91D6, 0x91DF, 0x91E1, 0x91DB, 0x91FC, + 0x91F5, 0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, + 0x9215, 0x9211, 0x925E, 0x9257, 0x9245, 0x9249, + 0x9264, 0x9248, 0x9295, 0x923F, 0x924B, 0x9250, + 0x929C, 0x9296, 0x9293, 0x929B, 0x925A, 0x92CF, + 0x92B9, 0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, + 0x932E, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE8[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9319, 0x9322, + 0x931A, 0x9323, 0x933A, 0x9335, 0x933B, 0x935C, + 0x9360, 0x937C, 0x936E, 0x9356, 0x93B0, 0x93AC, + 0x93AD, 0x9394, 0x93B9, 0x93D6, 0x93D7, 0x93E8, + 0x93E5, 0x93D8, 0x93C3, 0x93DD, 0x93D0, 0x93C8, + 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403, 0x9407, + 0x9410, 0x9436, 0x942B, 0x9435, 0x9421, 0x943A, + 0x9441, 0x9452, 0x9444, 0x945B, 0x9460, 0x9462, + 0x945E, 0x946A, 0x9229, 0x9470, 0x9475, 0x9477, + 0x947D, 0x945A, 0x947C, 0x947E, 0x9481, 0x947F, + 0x9582, 0x9587, 0x958A, 0x9594, 0x9596, 0x9598, + 0x9599, 0x0000, 0x95A0, 0x95A8, 0x95A7, 0x95AD, + 0x95BC, 0x95BB, 0x95B9, 0x95BE, 0x95CA, 0x6FF6, + 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6, + 0x95DC, 0x95E1, 0x95E5, 0x95E2, 0x9621, 0x9628, + 0x962E, 0x962F, 0x9642, 0x964C, 0x964F, 0x964B, + 0x9677, 0x965C, 0x965E, 0x965D, 0x965F, 0x9666, + 0x9672, 0x966C, 0x968D, 0x9698, 0x9695, 0x9697, + 0x96AA, 0x96A7, 0x96B1, 0x96B2, 0x96B0, 0x96B4, + 0x96B6, 0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, + 0x96CD, 0x894D, 0x96DC, 0x970D, 0x96D5, 0x96F9, + 0x9704, 0x9706, 0x9708, 0x9713, 0x970E, 0x9711, + 0x970F, 0x9716, 0x9719, 0x9724, 0x972A, 0x9730, + 0x9739, 0x973D, 0x973E, 0x9744, 0x9746, 0x9748, + 0x9742, 0x9749, 0x975C, 0x9760, 0x9764, 0x9766, + 0x9768, 0x52D2, 0x976B, 0x9771, 0x9779, 0x9785, + 0x977C, 0x9781, 0x977A, 0x9786, 0x978B, 0x978F, + 0x9790, 0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, + 0x97B4, 0x97C3, 0x97C6, 0x97C8, 0x97CB, 0x97DC, + 0x97ED, 0x9F4F, 0x97F2, 0x7ADF, 0x97F6, 0x97F5, + 0x980F, 0x980C, 0x9838, 0x9824, 0x9821, 0x9837, + 0x983D, 0x9846, 0x984F, 0x984B, 0x986B, 0x986F, + 0x9870, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE9[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9871, 0x9874, + 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6, 0x98C4, + 0x98C3, 0x98C6, 0x98E9, 0x98EB, 0x9903, 0x9909, + 0x9912, 0x9914, 0x9918, 0x9921, 0x991D, 0x991E, + 0x9924, 0x9920, 0x992C, 0x992E, 0x993D, 0x993E, + 0x9942, 0x9949, 0x9945, 0x9950, 0x994B, 0x9951, + 0x9952, 0x994C, 0x9955, 0x9997, 0x9998, 0x99A5, + 0x99AD, 0x99AE, 0x99BC, 0x99DF, 0x99DB, 0x99DD, + 0x99D8, 0x99D1, 0x99ED, 0x99EE, 0x99F1, 0x99F2, + 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05, 0x99E2, + 0x9A19, 0x9A2B, 0x9A37, 0x9A45, 0x9A42, 0x9A40, + 0x9A43, 0x0000, 0x9A3E, 0x9A55, 0x9A4D, 0x9A5B, + 0x9A57, 0x9A5F, 0x9A62, 0x9A65, 0x9A64, 0x9A69, + 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0, + 0x9ACF, 0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, 0x9ADF, + 0x9AE2, 0x9AE3, 0x9AE6, 0x9AEF, 0x9AEB, 0x9AEE, + 0x9AF4, 0x9AF1, 0x9AF7, 0x9AFB, 0x9B06, 0x9B18, + 0x9B1A, 0x9B1F, 0x9B22, 0x9B23, 0x9B25, 0x9B27, + 0x9B28, 0x9B29, 0x9B2A, 0x9B2E, 0x9B2F, 0x9B32, + 0x9B44, 0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, + 0x9B58, 0x9B74, 0x9B93, 0x9B83, 0x9B91, 0x9B96, + 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8, 0x9BB4, 0x9BC0, + 0x9BCA, 0x9BB9, 0x9BC6, 0x9BCF, 0x9BD1, 0x9BD2, + 0x9BE3, 0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, + 0x9BF2, 0x9BF1, 0x9BF0, 0x9C15, 0x9C14, 0x9C09, + 0x9C13, 0x9C0C, 0x9C06, 0x9C08, 0x9C12, 0x9C0A, + 0x9C04, 0x9C2E, 0x9C1B, 0x9C25, 0x9C24, 0x9C21, + 0x9C30, 0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, + 0x9C60, 0x9C67, 0x9C76, 0x9C78, 0x9CE7, 0x9CEC, + 0x9CF0, 0x9D09, 0x9D08, 0x9CEB, 0x9D03, 0x9D06, + 0x9D2A, 0x9D26, 0x9DAF, 0x9D23, 0x9D1F, 0x9D44, + 0x9D15, 0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, + 0x9D48, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisEA[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D5D, 0x9D5E, + 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72, 0x9D89, + 0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, 0x9D9A, 0x9DA4, + 0x9DA9, 0x9DB2, 0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, + 0x9DBA, 0x9DC6, 0x9DCF, 0x9DC2, 0x9DD9, 0x9DD3, + 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD, 0x9E1A, + 0x9E1B, 0x9E1E, 0x9E75, 0x9E79, 0x9E7D, 0x9E81, + 0x9E88, 0x9E8B, 0x9E8C, 0x9E92, 0x9E95, 0x9E91, + 0x9E9D, 0x9EA5, 0x9EA9, 0x9EB8, 0x9EAA, 0x9EAD, + 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0, 0x9ED4, + 0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, 0x9EE5, 0x9EE8, + 0x9EEF, 0x0000, 0x9EF4, 0x9EF6, 0x9EF7, 0x9EF9, + 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07, 0x9F08, 0x76B7, + 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52, + 0x9F54, 0x9F63, 0x9F5F, 0x9F60, 0x9F61, 0x9F66, + 0x9F67, 0x9F6C, 0x9F6A, 0x9F77, 0x9F72, 0x9F76, + 0x9F95, 0x9F9C, 0x9FA0, 0x582F, 0x69C7, 0x9059, + 0x7464, 0x51DC, 0x7199, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16* SjisUcsTable[256] = {0}; + +u32 OSSJIStoUTF32(u16 sjis) { + u16* table; + + table = SjisUcsTable[(sjis >> 8) & 0xFF]; + if (table != 0) { + return table[sjis & 0xFF]; + } + + return 0; +} diff --git a/src/dolphin/os/__os.h b/src/dolphin/os/__os.h new file mode 100644 index 0000000..452dd20 --- /dev/null +++ b/src/dolphin/os/__os.h @@ -0,0 +1,130 @@ +#ifndef _DOLPHIN_OS_INTERNAL_H_ +#define _DOLPHIN_OS_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// OS +extern char* __OSExceptionNames[17]; // D ONLY + +u32 __OSIsDebuggerPresent(void); +void __OSPSInit(void); + +// OSAlloc +extern volatile int __OSCurrHeap; + +// OSAudioSystem +void __OSInitAudioSystem(void); +void __OSStopAudioSystem(void); + +// OSCache +void __OSCacheInit(void); + +// OSContext +void __OSContextInit(void); + +// OSError +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); + +// OSExec +void __OSGetExecParams(OSExecParams* params); +void __OSSetExecParams(const OSExecParams* params, OSExecParams* addr); +void __OSBootDolSimple(u32 doloffset, u32 restartCode, void* regionStart, void* regionEnd, BOOL argsUseDefault, s32 argc, char** argv); +void __OSBootDol(u32 doloffset, u32 restartCode, const char** argv); + +// OSInterrupt +extern void __RAS_OSDisableInterrupts_begin(void); +extern void __RAS_OSDisableInterrupts_end(void); + +extern u64 __OSSpuriousInterrupts; // D ONLY +extern char* __OSInterruptNames[33]; // D ONLY +extern char* __OSPIErrors[8]; // D ONLY + +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler); +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt); +void __OSInterruptInit(void); +OSInterruptMask __OSMaskInterrupts(OSInterruptMask global); +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global); +void __OSDispatchInterrupt(__OSException exception, OSContext* context); +void __OSModuleInit(void); + +// OSMemory +void __OSInitMemoryProtection(void); + +// OSMutex +void __OSUnlockAllMutex(OSThread* thread); +int __OSCheckDeadLock(OSThread* thread); +int __OSCheckMutexes(OSThread* thread); + +// OSReset +void __OSDoHotReset(u32 resetCode); +void __OSShutdownDevices(BOOL doRecal); +int __OSCallResetFunctions(BOOL final); + +// OSResetSW +void __OSResetSWInterruptHandler(s16 exception, OSContext* context); +void __OSSetResetButtonTimer(u8 min); + +// OSRtc +int __OSGetRTC(u32* rtc); +int __OSSetRTC(u32 rtc); +void __OSInitSram(void); +OSSram* __OSLockSram(void); +OSSramEx* __OSLockSramEx(void); +int __OSUnlockSram(BOOL commit); +int __OSUnlockSramEx(BOOL commit); +int __OSSyncSram(void); +int __OSCheckSram(void); +int __OSReadROM(void* buffer, s32 length, s32 offset); +int __OSReadROMAsync(void* buffer, s32 length, s32 offset, void (*callback)()); +u8 __OSGetBootMode(void); +void __OSSetBootMode(u8 ntd); + +// OSSync +extern void __OSSystemCallVectorStart(); +extern void __OSSystemCallVectorEnd(); + +void __OSInitSystemCall(void); + +// OSThread +void __OSThreadInit(void); +s32 __OSGetEffectivePriority(OSThread* thread); +void __OSPromoteThread(OSThread* thread, s32 priority); +void __OSReschedule(void); + +// OSTime +void __OSSetTime(OSTime time); +OSTime __OSGetSystemTime(); +void __OSSetTick(register OSTick newTicks); +OSTime __OSTimeToSystemTime(OSTime time); + +// ppc_eabi_init +__declspec(section ".init") asm void __init_hardware(void); +__declspec(section ".init") asm void __flush_cache(void* address, unsigned int size); +void __init_user(void); +void _ExitProcess(void); + +// start +__declspec(weak) void InitMetroTRK_BBA(); + +__declspec(section ".init") void __start(void); + +__declspec(section ".init") extern void __start(void); +__declspec(section ".init") void __copy_rom_section(void* dst, const void* src, u32 size); +__declspec(section ".init") void __init_bss_section(void* dst, u32 size); +__declspec(section ".init") extern void __init_registers(void); +__declspec(section ".init") extern void __init_data(void); + +// time.dolphin +OSTime __get_clock(void); +u32 __get_time(void); +int __to_gm_time(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OS_INTERNAL_H_ diff --git a/src/dolphin/os/src/OSExec.c b/src/dolphin/os/src/OSExec.c new file mode 100644 index 0000000..9033bc4 --- /dev/null +++ b/src/dolphin/os/src/OSExec.c @@ -0,0 +1,402 @@ +#include +#include + +#include "__os.h" +#include "__dvd.h" + +extern volatile u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0); +extern volatile u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC); +extern volatile u8 g_unk_800030E2 AT_ADDRESS(0x800030E2); + +static int Prepared; + +static int PackArgs(void* addr, s32 argc, char** argv) { + s32 numArgs; + char* bootInfo2; + char* ptr; + char** list; + u32 i; + + bootInfo2 = (char*)addr; + memset(bootInfo2, 0, 0x2000); + + if (argc == 0) { + *(u32*)(bootInfo2 + 8) = 0; + } else { + numArgs = argc; + ptr = bootInfo2 + 0x2000; + while (--argc >= 0) { + ptr -= strlen(argv[argc]) + 1; + strcpy(ptr, argv[argc]); + argv[argc] = (char*)(ptr - bootInfo2); + } + + ptr = bootInfo2 + ((ptr - bootInfo2) & ~0x3); + ptr -= ((numArgs + 1) * 4); + list = (char**)ptr; + + for (i = 0; i < numArgs + 1; i++) { + list[i] = argv[i]; + } + + ptr -= 4; + *(u32*)ptr = numArgs; + + ASSERTMSGLINE(LINE(129, 138, 140), ptr - bootInfo2 >= 0x1000U, "OSExec: Argument list is too long"); + + *(u32*)(bootInfo2 + 8) = (ptr - bootInfo2); + } + + return 1; +} + +#ifdef __GEKKO__ +static asm void Run(register void* entryPoint) { + nofralloc + + mflr r0 + stw r0, 4(r1) + stwu r1, -0x18(r1) + stw r31, 0x14(r1) + mr r31, entryPoint + bl ICFlashInvalidate + sync + isync + mtlr r31 + blr + + lwz r0, 0x1c(r1) + lwz r31, 0x14(r1) + addi r1, r1, 0x18 + mtlr r0 + blr +} +#endif + +static void StartDol(const OSExecParams* params, void* entry) { + OSExecParams* paramsWork = OSAllocFromArenaLo(sizeof(OSExecParams), 1); + + __OSSetExecParams(params, paramsWork); + __PIRegs[9] = 7; + + OSDisableInterrupts(); + Run(entry); +} + +static void ReadDisc(void* addr, s32 length, s32 offset) { + DVDCommandBlock block; +#if SDK_REVISION < 1 + OSTime start; +#endif + + DVDReadAbsAsyncPrio(&block, addr, length, offset, NULL, 0); + +#if SDK_REVISION < 1 + start = OSGetTime(); +#endif + + while (DVDGetCommandBlockStatus(&block)) { +#if SDK_REVISION < 1 + if (!DVDCheckDisk() || OS_TIMER_CLOCK < (OSGetTime() - start)) +#else + if (!DVDCheckDisk()) +#endif + { + __OSDoHotReset(0); + } + } +} + +static void Callback(s32, DVDCommandBlock*) { + Prepared = TRUE; +} + +static int IsStreamEnabled() { + if (DVDGetCurrentDiskID()->streaming) { + return TRUE; + } + + return FALSE; +} + +void __OSGetExecParams(OSExecParams* params) { + if (0x80000000 <= (u32)__OSExecParams) { + memcpy(params, __OSExecParams, sizeof(OSExecParams)); + } else { + params->valid = FALSE; + } +} + +void __OSSetExecParams(const OSExecParams* params, OSExecParams* addr) { + memcpy(addr, params, sizeof(OSExecParams)); + __OSExecParams = addr; +} + +static void StopStreaming() { + DVDCommandBlock block; +#if SDK_REVISION < 1 + OSTime start; +#endif + + if (!__OSIsGcam && IsStreamEnabled()) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&block, NULL); + +#if SDK_REVISION < 1 + start = OSGetTime(); +#endif + + while (DVDGetCommandBlockStatus(&block)) { +#if SDK_REVISION < 1 + if (!DVDCheckDisk() || OS_TIMER_CLOCK < (OSGetTime() - start)) +#else + if (!DVDCheckDisk()) +#endif + { + __OSDoHotReset(0); + } + } + + AISetStreamPlayState(0); + } +} + +static int GetApploaderPosition(void) { + static s32 apploaderPosition; + + u32* tgcHeader; + s32 apploaderOffsetInTGC; + + if (apploaderPosition != 0) { + return apploaderPosition; + } + + if (__OSAppLoaderOffset != 0) { + tgcHeader = OSAllocFromArenaLo(0x40, DOLPHIN_ALIGNMENT); + ReadDisc(tgcHeader, 0x40, __OSAppLoaderOffset); + apploaderOffsetInTGC = tgcHeader[14]; + ASSERTMSGLINE(LINE(370, 376, 378), apploaderOffsetInTGC != 0, "OSExec() or OSResetSystem(): Wrong apploader offset. Maybe converted by an\nolder version of gcm2tgc. Use gcm2tgc v.1.20 or later."); + + apploaderPosition = __OSAppLoaderOffset + apploaderOffsetInTGC; + } else { + apploaderPosition = 0x2440; + } + return apploaderPosition; +} + +typedef struct { + char date[16]; + u32 entry; + u32 size; + u32 rebootSize; + u32 reserved2; +} AppLoaderStruct; + +static AppLoaderStruct* LoadApploader() { + AppLoaderStruct* header; + + header = (AppLoaderStruct*)OSAllocFromArenaLo(sizeof(AppLoaderStruct), DOLPHIN_ALIGNMENT); + ReadDisc(header, sizeof(AppLoaderStruct), GetApploaderPosition()); + ASSERTMSGLINE(LINE(401, 407, 409), header->rebootSize != 0, "OSResetSystem(): old apploader"); + + ReadDisc((void*)0x81200000, OSRoundUp32B(header->size), GetApploaderPosition() + 0x20); + ICInvalidateRange((void*)0x81200000, OSRoundUp32B(header->size)); + return header; +} + +static void* LoadDol(const OSExecParams* params, AppLoaderCallback getInterface) { + appInitCallback appInit; + appGetNextCallback appGetNext; + appGetEntryCallback appGetEntry; + void* addr; + u32 length; + u32 offset; + OSExecParams* paramsWork; + + getInterface(&appInit, &appGetNext, &appGetEntry); + paramsWork = (OSExecParams*)OSAllocFromArenaLo(sizeof(OSExecParams), 1); + __OSSetExecParams(params, paramsWork); + appInit((void(*)(char*))OSReport); + OSSetArenaLo(paramsWork); + + while (appGetNext(&addr, &length, &offset) != 0) { + ReadDisc(addr, length, offset); + } + + return appGetEntry(); +} + +static BOOL IsNewApploader(AppLoaderStruct* header) { + return strncmp(header->date, "2004/02/01", 10) > 0 ? TRUE : FALSE; +} + +void __OSBootDolSimple(u32 doloffset, u32 restartCode, void* regionStart, void* regionEnd, BOOL argsUseDefault, s32 argc, char** argv) { + OSExecParams* params; + void* dolEntry; + AppLoaderStruct* header; + +#if SDK_REVISION < 1 + OSTime start; +#endif + + OSDisableInterrupts(); + params = (OSExecParams*)OSAllocFromArenaLo(sizeof(OSExecParams), 1); + params->valid = TRUE; + params->restartCode = restartCode; + params->regionStart = regionStart; + params->regionEnd = regionEnd; + params->argsUseDefault = argsUseDefault; + + if (!argsUseDefault) { + params->argsAddr = OSAllocFromArenaLo(0x2000, 1); + PackArgs(params->argsAddr, argc, argv); + } + + DVDInit(); + DVDSetAutoInvalidation(TRUE); + DVDResume(); + + Prepared = FALSE; + + __DVDPrepareResetAsync(Callback); + __OSMaskInterrupts(0xFFFFFFE0); + __OSUnmaskInterrupts(0x400); + OSEnableInterrupts(); + +#if SDK_REVISION < 1 + start = OSGetTime(); +#endif + + while (Prepared != TRUE) { +#if SDK_REVISION < 1 + if (!DVDCheckDisk() || OS_TIMER_CLOCK < (OSGetTime() - start)) +#else + if (!DVDCheckDisk()) +#endif + { + __OSDoHotReset(0); + } + } + + StopStreaming(); + + header = LoadApploader(); + if (IsNewApploader(header)) { + if (doloffset == 0xFFFFFFFF) { + doloffset = (GetApploaderPosition() + 0x20) + header->size; + } + + params->bootDol = doloffset; + dolEntry = LoadDol(params, (AppLoaderCallback)header->entry); + StartDol(params, dolEntry); + } else { + BOOT_REGION_START = (u32)regionStart; + BOOT_REGION_END = (u32)regionEnd; + g_unk_800030E2 = 1; + + ReadDisc((void*)0x81300000, OSRoundUp32B(header->rebootSize), (GetApploaderPosition() + 0x20) + header->size); + ICInvalidateRange((void*)0x81300000, OSRoundUp32B(header->rebootSize)); + OSDisableInterrupts(); + ICFlashInvalidate(); + Run((void*)0x81300000); + } +} + +void __OSBootDol(u32 doloffset, u32 restartCode, const char** argv) { + char doloffInString[20]; + s32 argvlen; + char** argvToPass; + s32 i; + void* saveStart; + void* saveEnd; + + OSGetSaveRegion(&saveStart, &saveEnd); + sprintf(doloffInString, "%d", doloffset); + argvlen = 0; + + if (argv != 0) { + while (argv[argvlen] != 0) { + argvlen++; + } + } + + argvlen++; + argvToPass = OSAllocFromArenaLo((argvlen + 1) * 4, 1); + *argvToPass = doloffInString; + + for (i = 1; i < argvlen; i++) { + argvToPass[i] = (char*)argv[i - 1]; + } + + __OSBootDolSimple(-1, restartCode, saveStart, saveEnd, FALSE, argvlen, argvToPass); +} + +static void ExecCommon(const char* dolfile, const char** argv) { + DVDFileInfo fileInfo; + u32 doloff; + + if ((s8)*dolfile == '\0') { + doloff = 0; + } else if (DVDOpen((char*)dolfile, &fileInfo)) { + doloff = fileInfo.startAddr; + } else { + ASSERTMSGLINE(LINE(689, 695, 697), 0, "OSExec(): The specified file doesn't exist"); + return; + } + + __OSBootDol(doloff, 0xC0000000, argv); +} + +void OSExecv(const char* dolfile, const char** argv) { + ASSERTMSGLINE(LINE(718, 724, 726), dolfile != 0, "OSExecv(): null pointer was specified for the dol file name."); + ASSERTMSGLINE(LINE(719, 725, 727), argv != 0, "OSExecv(): null pointer was specified for argv."); + + OSDisableScheduler(); + __OSShutdownDevices(FALSE); + OSEnableScheduler(); + OSSetArenaLo((void*)0x81280000); + OSSetArenaHi((void*)0x812F0000); + ExecCommon(dolfile, argv); +} + +void OSExecl(const char* dolfile, const char* arg0, ...) { + va_list vl; + char* ptr; + s32 i; + char** argv; + + ASSERTMSGLINE(LINE(759, 765, 767), dolfile != 0, "OSExecl(): null pointer was specified for the dol file name."); + + OSDisableScheduler(); + __OSShutdownDevices(FALSE); + OSEnableScheduler(); + OSSetArenaLo((void*)0x81280000); + OSSetArenaHi((void*)0x812F0000); + + argv = OSAllocFromArenaLo(4, 0x1000); + va_start(vl, arg0); +#if SDK_REVISION < 2 + *argv = (char*)arg0; + + i = 1; + do { + ptr = va_arg(vl, char*); + argv[i++] = ptr; + } while (ptr != 0); +#else + i = 0; + ptr = (char*)arg0; + goto setarg; + + do { + ptr = va_arg(vl, char*); +setarg: + argv[i++] = ptr; + } while (ptr != 0); +#endif + va_end(vl); + ASSERTMSGLINE(LINE(787, 793, 794), i < 0x400U, "OSExecl(): Arguments too long"); + + ExecCommon(dolfile, argv); +} diff --git a/src/dolphin/os/src/OSSemaphore.c b/src/dolphin/os/src/OSSemaphore.c new file mode 100644 index 0000000..c58e20d --- /dev/null +++ b/src/dolphin/os/src/OSSemaphore.c @@ -0,0 +1,56 @@ +#include +#include + +void OSInitSemaphore(OSSemaphore* sem, s32 count) { + BOOL enabled = OSDisableInterrupts(); + + OSInitThreadQueue(&sem->queue); + sem->count = count; + OSRestoreInterrupts(enabled); +} + +s32 OSWaitSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + + while((sem->count = (count = sem->count)) <= 0) { + OSSleepThread(&sem->queue); + } + + sem->count--; + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSTryWaitSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = sem->count; + if (sem->count > 0) { + sem->count = sem->count - 1; + } + + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSSignalSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = sem->count; + sem->count++; + + OSWakeupThread(&sem->queue); + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSGetSemaphoreCount(OSSemaphore* sem) { + return sem->count; +} diff --git a/src/dolphin/os/src/init/__ppc_eabi_init.c b/src/dolphin/os/src/init/__ppc_eabi_init.c new file mode 100644 index 0000000..1a90be2 --- /dev/null +++ b/src/dolphin/os/src/init/__ppc_eabi_init.c @@ -0,0 +1,85 @@ +#include +#include +#include + +#include "__os.h" + +__declspec(section ".ctors") extern void (* _ctors[])(); +__declspec(section ".dtors") extern void (* _dtors[])(); + +static void __init_cpp(void); +static void __fini_cpp(void); + +__declspec(section ".init") asm void __init_hardware(void) +{ // clang-format off + nofralloc + mfmsr r0 + ori r0,r0,MSR_FP + mtmsr r0 + mflr r31 + bl __OSPSInit + bl __OSFPRInit + bl __OSCacheInit + mtlr r31 + blr +} + +__declspec(section ".init") asm void __flush_cache(void *address, unsigned int size) +{ // clang-format off + nofralloc + lis r5, 0xffff + ori r5, r5, 0xfff1 + and r5, r5, r3 + subf r3, r5, r3 + add r4, r4, r3 +rept: + dcbst 0,r5 + sync + icbi 0,r5 + addic r5,r5,0x8 + subic. r4,r4,0x8 + bge rept + isync + blr +} + +void __init_user(void) { + __init_cpp(); +} + +static void __init_cpp(void) { + void (* * constructor)(); + + /* + * call static initializers + */ + for (constructor = _ctors; *constructor; constructor++) { + (*constructor)(); + } +} + +static void __fini_cpp(void) { + void (* * destructor)(); + + /* + * call destructors + */ + for (destructor = _dtors; *destructor; destructor++) { + (*destructor)(); + } +} + +__declspec(weak) +void abort(void) { + _ExitProcess(); +} + +__declspec(weak) +void exit(int status) { + __fini_cpp(); + _ExitProcess(); +} + +void _ExitProcess(void) { + PPCHalt(); +} diff --git a/src/dolphin/os/src/init/__start.c b/src/dolphin/os/src/init/__start.c new file mode 100644 index 0000000..736cae0 --- /dev/null +++ b/src/dolphin/os/src/init/__start.c @@ -0,0 +1,265 @@ +#include +#include + +#include "__os.h" + +#define PAD3_BUTTON_ADDR 0x800030E4 +#define OS_RESET_RESTART 0 +#define FALSE 0 +#define TRUE 1 +#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 DOL_ADDR_LIMIT 0x80700000 + +u16 Pad3Button AT_ADDRESS(PAD3_BUTTON_ADDR); +static u8 Debug_BBA = 0; + +extern void InitMetroTRK(); + +__declspec(weak) void InitMetroTRK_BBA() {} + +__declspec(section ".init") extern char _stack_addr[]; +__declspec(section ".init") extern char _SDA_BASE_[]; +__declspec(section ".init") extern char _SDA2_BASE_[]; + +typedef struct __rom_copy_info { + char* rom; + char* addr; + unsigned int size; +} __rom_copy_info; + +__declspec(section ".init") extern __rom_copy_info _rom_copy_info[]; + +typedef struct __bss_init_info { + char* addr; + unsigned int size; +} __bss_init_info; + +__declspec(section ".init") extern __bss_init_info _bss_init_info[]; +extern int main(int argc, char* argv[]); +extern void exit(int); + +__declspec(section ".init") extern void __init_hardware(void); +__declspec(section ".init") extern void __flush_cache(void* address, unsigned int size); + +__declspec(section ".init") static void __check_pad3(void); +__declspec(section ".init") static void __set_debug_bba(void); +__declspec(section ".init") static u8 __get_debug_bba(void); + +static void __init_registers(void); +static void __init_data(void); + +static void __check_pad3(void) { + if ((Pad3Button & 0xEEF) == 0xEEF) { + OSResetSystem(OS_RESET_RESTART, 0, FALSE); + } +} + +static void __set_debug_bba(void) { + Debug_BBA = 1; +} + +static u8 __get_debug_bba(void) { + return Debug_BBA; +} + +#ifdef __GEKKO__ +__declspec(section ".init") +__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 +} +#endif + +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); + } +} + +static void __init_bss_section(void* dst, unsigned long size) { + if (size) { + memset(dst, 0, size); + } +} + +#ifdef __GEKKO__ +asm static void __init_registers(void) { + 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 +} +#endif + +static 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/src/dolphin/os/time.dolphin.c b/src/dolphin/os/time.dolphin.c new file mode 100644 index 0000000..5e9d20a --- /dev/null +++ b/src/dolphin/os/time.dolphin.c @@ -0,0 +1,16 @@ +#include +#include + +#include "__os.h" + +OSTime __get_clock(void) { + return __OSGetSystemTime(); +} + +u32 __get_time(void) { + return OSTicksToSeconds(OSGetTime()) - 0x43E83E00; +} + +int __to_gm_time(void) { + return 0; +} diff --git a/src/dolphin/pad/Pad.c b/src/dolphin/pad/Pad.c new file mode 100644 index 0000000..27c5545 --- /dev/null +++ b/src/dolphin/pad/Pad.c @@ -0,0 +1,841 @@ +#include +#include +#include + +#include "__si.h" + +#if DEBUG +const char* __PADVersion = "<< Dolphin SDK - PAD\tdebug build: Apr 5 2004 03:56:05 (0x2301) >>"; +#else +const char* __PADVersion = "<< Dolphin SDK - PAD\trelease build: Apr 5 2004 04:14:49 (0x2301) >>"; +#endif + +#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 s32 ResettingChan = 0x20; +static u32 XPatchBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT; +static u32 AnalogMode = 0x300; +static u32 Spec = PAD_SPEC_5; + +static BOOL Initialized; +static u32 EnabledBits; +static u32 ResettingBits; +static u32 RecalibrateBits; +static u32 WaitingBits; +static u32 CheckingBits; +static u32 PendingBits; +static u32 BarrelBits; + +static u32 Type[4]; +static PADStatus Origin[4]; + +u32 __PADSpec; + +// prototypes +static void PADTypeAndStatusCallback(s32 chan, u32 type); +static u16 GetWirelessID(s32 chan); +static void SetWirelessID(s32 chan, u16 id); +static void DoReset(); +static void PADEnable(s32 chan); +static void ProbeWireless(s32 chan); +static void PADProbeCallback(s32 chan, u32 error, OSContext *context); +static void PADDisable(s32 chan); +static void UpdateOrigin(s32 chan); +static void PADOriginCallback(s32 chan, u32 error, OSContext *context); +static void PADFixCallback(s32 unused, u32 error, struct OSContext *context); +static void PADResetCallback(s32 unused, u32 error, struct OSContext *context); +static void PADReceiveCheckCallback(s32 chan, u32 error); +static void SPEC0_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); +static void SPEC1_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); +static s8 ClampS8(s8 var, s8 org); +static u8 ClampU8(u8 var, u8 org); +static void SPEC2_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); +static BOOL OnReset(BOOL f); +void __PADDisableXPatch(void); +BOOL __PADDisableRumble(BOOL disable); + +typedef void (*SPECCallback)(s32, PADStatus*, u32*); +static SPECCallback MakeStatus = SPEC2_MakeStatus; + +static u32 CmdTypeAndStatus; +static u32 CmdReadOrigin = 0x41000000; +static u32 CmdCalibrate = 0x42000000; +static u32 CmdProbeDevice[4]; + +static OSResetFunctionInfo ResetFunctionInfo = { + OnReset, + 127, + NULL, + NULL, +}; + +static void PADEnable(s32 chan) { + u32 cmd; + u32 chanBit; + u32 data[2]; + + chanBit = PAD_CHAN0_BIT >> chan; + EnabledBits |= chanBit; + SIGetResponse(chan, &data); + cmd = (AnalogMode | 0x400000); + 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() { + u32 chanBit; + + ResettingChan = __cntlzw(ResettingBits); + if (ResettingChan != 32) { + ASSERTLINE(559, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + chanBit = (PAD_CHAN0_BIT >> ResettingChan); + ResettingBits &= ~chanBit; + + memset(&Origin[ResettingChan], 0, sizeof(PADStatus)); + SIGetTypeAsync(ResettingChan, PADTypeAndStatusCallback); + } +} + +static void UpdateOrigin(s32 chan) { + PADStatus* origin; + u32 chanBit = PAD_CHAN0_BIT >> chan; + + origin = &Origin[chan]; + switch (AnalogMode & 0x00000700u) { + case 0x00000000u: + case 0x00000500u: + case 0x00000600u: + case 0x00000700u: + origin->triggerLeft &= ~15; + origin->triggerRight &= ~15; + origin->analogA &= ~15; + origin->analogB &= ~15; + break; + case 0x00000100u: + origin->substickX &= ~15; + origin->substickY &= ~15; + origin->analogA &= ~15; + origin->analogB &= ~15; + break; + case 0x00000200u: + origin->substickX &= ~15; + origin->substickY &= ~15; + origin->triggerLeft &= ~15; + origin->triggerRight &= ~15; + break; + case 0x00000300u: break; + case 0x00000400u: break; + } + + origin->stickX -= 128; + origin->stickY -= 128; + origin->substickX -= 128; + origin->substickY -= 128; + + if (XPatchBits & chanBit) { + if (64 < origin->stickX && (SIGetType(chan) & 0xFFFF0000) == SI_GC_CONTROLLER) { + origin->stickX = 0; + } + } +} + +static void PADOriginCallback(s32 chan, u32 error, OSContext* context) { + ASSERTLINE(641, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERTLINE(642, chan == ResettingChan); + + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) + { + UpdateOrigin(ResettingChan); + PADEnable(ResettingChan); + } + + DoReset(); +} + +static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context) { + ASSERTLINE(671, 0 <= chan && chan < SI_MAX_CHAN); + if (!(EnabledBits & (PAD_CHAN0_BIT >> chan))) + return; + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) + UpdateOrigin(chan); + if (error & SI_ERROR_NO_RESPONSE) { + PADDisable(chan); + } +} + +static void PADProbeCallback(s32 chan, u32 error, OSContext* context) { + u32 type; + ASSERTLINE(710, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERTLINE(711, chan == ResettingChan); + ASSERTLINE(713, (Type[chan] & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && !(Type[chan] & SI_WIRELESS_LITE)); + + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) + { + PADEnable(ResettingChan); + WaitingBits |= PAD_CHAN0_BIT >> ResettingChan; + } + + DoReset(); +} + +static void PADTypeAndStatusCallback(s32 chan, u32 type) { + u32 chanBit; + u32 recalibrate; + BOOL rc = TRUE; + u32 error; + + ASSERTLINE(746, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERTLINE(747, chan == ResettingChan); + + chanBit = PAD_CHAN0_BIT >> ResettingChan; + error = type & 0xFF; + ASSERTLINE(756, !(error & SI_ERROR_BUSY)); + + recalibrate = RecalibrateBits & chanBit; + RecalibrateBits &= ~chanBit; + + if (error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) + { + 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) { + 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); + } + } +} + +int PADReset(u32 mask) { + BOOL enabled; + u32 disableBits; + + ASSERTMSGLINE(0x381, !(mask & 0x0FFFFFFF), "PADReset(): invalid mask"); + + enabled = OSDisableInterrupts(); + mask |= PendingBits; + PendingBits = 0; + mask &= ~(WaitingBits | CheckingBits); + ResettingBits |= mask; + disableBits = ResettingBits & EnabledBits; + EnabledBits &= ~mask; + BarrelBits &= ~mask; + + if (Spec == 4) { + RecalibrateBits |= mask; + } + + SIDisablePolling(disableBits); + + if (ResettingChan == 0x20) { + DoReset(); + } + + OSRestoreInterrupts(enabled); + return 1; +} + +BOOL PADRecalibrate(u32 mask) { + BOOL enabled; + u32 disableBits; + + ASSERTMSGLINE(939, !(mask & 0x0FFFFFFF), "PADReset(): invalid mask"); + enabled = OSDisableInterrupts(); + + mask |= PendingBits; + PendingBits = 0; + mask &= ~(WaitingBits | CheckingBits); + ResettingBits |= mask; + disableBits = ResettingBits & EnabledBits; + EnabledBits &= ~mask; + BarrelBits &= ~mask; + + if (!(__gUnknown800030E3 & 0x40)) { + RecalibrateBits |= mask; + } + + SIDisablePolling(disableBits); + if (ResettingChan == 32) + DoReset(); + + OSRestoreInterrupts(enabled); + return 1; +} + +BOOL PADInit() { + s32 chan; + if (Initialized) { + return 1; + } + + 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); +} + +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 < 4; 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)); + } else if ((ResettingBits & chanBit) || ResettingChan == chan) { + status->err = PAD_ERR_NOT_READY; + memset(status, 0, offsetof(PADStatus, err)); + } else if (!(EnabledBits & chanBit)) { + status->err = PAD_ERR_NO_CONTROLLER; + memset(status, 0, offsetof(PADStatus, err)); + } else if (SIIsChanBusy(chan)) { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + } else { + sr = SIGetStatus(chan); + if (sr & SI_ERROR_NO_RESPONSE) { + SIGetResponse(chan, data); + + if (WaitingBits & chanBit) { + status->err = PAD_ERR_NONE; + memset(status, 0, offsetof(PADStatus, err)); + + if (!(CheckingBits & chanBit)) { + CheckingBits |= chanBit; + SIGetTypeAsync(chan, PADReceiveCheckCallback); + } + } else { + PADDisable(chan); + status->err = PAD_ERR_NO_CONTROLLER; + memset(status, 0, offsetof(PADStatus, err)); + } + } else { + if (!(SIGetType(chan) & SI_GC_NOMOTOR)) { + motor |= chanBit; + } + + if (!SIGetResponse(chan, &data)) { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + } else if (data[0] & 0x80000000) { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + } else { + MakeStatus(chan, status, data); + + // Check and clear PAD_ORIGIN bit + if (status->button & 0x2000) { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + + // Get origin. It is okay if the following transfer fails + // since the PAD_ORIGIN bit remains until the read origin + // command complete. + SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0); + } else { + status->err = PAD_ERR_NONE; + + // Clear PAD_INTERFERE bit + status->button &= ~0x0080; + } + } + } + } + } + + OSRestoreInterrupts(enabled); + return motor; +} + +typedef struct XY { + u8 line; + u8 count; +} XY; + +void PADSetSamplingRate(u32 msec) { + SISetSamplingRate(msec); +} + +#if DEBUG +void __PADTestSamplingRate(u32 tvmode) { + __SITestSamplingRate(tvmode); +} +#endif + +void PADControlAllMotors(const u32* commandArray) { + BOOL enabled; + int chan; + u32 command; + BOOL commit; + u32 chanBit; + + enabled = OSDisableInterrupts(); + commit = FALSE; + + for (chan = 0; chan < SI_MAX_CHAN; chan++, commandArray++) { + chanBit = PAD_CHAN0_BIT >> chan; + if ((EnabledBits & chanBit) && !(SIGetType(chan) & 0x20000000)) { + command = *commandArray; + ASSERTMSGLINE(0x4B5, !(command & 0xFFFFFFFC), "PADControlAllMotors(): invalid command"); + if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) + command = PAD_MOTOR_STOP; + if (__gUnknown800030E3 & 0x20) + command = PAD_MOTOR_STOP; + SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); + commit = TRUE; + } + } + + if (commit) + SITransferCommands(); + + OSRestoreInterrupts(enabled); +} + +void PADControlMotor(s32 chan, u32 command) { + BOOL enabled; + u32 chanBit; + + ASSERTMSGLINE(1244, !(command & 0xFFFFFFFC), "PADControlMotor(): invalid command"); + + enabled = OSDisableInterrupts(); + chanBit = 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 (__gUnknown800030E3 & 0x20) + command = PAD_MOTOR_STOP; + SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); + SITransferCommands(); + } + + OSRestoreInterrupts(enabled); +} + +void PADSetSpec(u32 spec) { + ASSERTLINE(1282, !Initialized); + __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; +} + +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; + return; + } 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); +} + +int PADGetType(s32 chan, u32* type) { + u32 chanBit; + + *type = SIGetType(chan); + chanBit = PAD_CHAN0_BIT >> chan; + if (ResettingBits & chanBit || ResettingChan == chan || !(EnabledBits & chanBit)) { + return 0; + } + return 1; +} + +BOOL PADSync(void) { + return ResettingBits == 0 && (s32)ResettingChan == 32 && !SIBusy(); +} + +void PADSetAnalogMode(u32 mode) { + BOOL enabled; + u32 mask; + + ASSERTMSGLINE(1615, (mode < 8), "PADSetAnalogMode(): invalid mode"); + + enabled = OSDisableInterrupts(); + AnalogMode = mode << 8; + mask = EnabledBits; + + EnabledBits &= ~mask; + WaitingBits &= ~mask; + CheckingBits &= ~mask; + + SIDisablePolling(mask); + OSRestoreInterrupts(enabled); +} + +static void (*SamplingCallback)(); + +static BOOL OnReset(BOOL final) { + BOOL sync; + static BOOL recalibrated = FALSE; + + if (SamplingCallback) + PADSetSamplingCallback(NULL); + + if (!final) { + 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 = (__gUnknown800030E3 & 0x40) ? TRUE : FALSE; + __gUnknown800030E3 &= ~0x40; + if (disable) { + __gUnknown800030E3 |= 0x40; + } + + OSRestoreInterrupts(enabled); + return prev; +} + +BOOL __PADDisableRumble(BOOL disable) { + BOOL enabled; + BOOL prev; + + enabled = OSDisableInterrupts(); + prev = (__gUnknown800030E3 & 0x20) ? TRUE : FALSE; + __gUnknown800030E3 &= ~0x20; + if (disable) { + __gUnknown800030E3 |= 0x20; + } + OSRestoreInterrupts(enabled); + return prev; +} + +BOOL PADIsBarrel(s32 chan) { + if (chan < 0 || chan >= 4) { + return FALSE; + } + + if (BarrelBits & (PAD_CHAN0_BIT >> chan)) { + return TRUE; + } + + return FALSE; +} diff --git a/src/dolphin/pad/Padclamp.c b/src/dolphin/pad/Padclamp.c new file mode 100644 index 0000000..edc31dc --- /dev/null +++ b/src/dolphin/pad/Padclamp.c @@ -0,0 +1,152 @@ +#include +#include +#include + +static const PADClampRegion ClampRegion = { + // Triggers + 30, + 180, + + // Left stick + 15, + 72, + 40, + + // Right stick + 15, + 59, + 31, + + // Stick radii + 56, + 44, +}; + +// prototypes +static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min); +static void ClampCircle(s8* px, s8* py, s8 radius, s8 min); +static void ClampTrigger(u8* trigger, u8 min, u8 max); + +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; + } else { + if (max < *trigger) { + *trigger = max; + } + *trigger -= min; + } +} + +void PADClamp(PADStatus * status) { + int i; + + for (i = 0; i < 4; i++, status++) { + if (status->err == PAD_ERR_NONE) { + ClampStick(&status->stickX, &status->stickY, ClampRegion.maxStick, ClampRegion.xyStick, ClampRegion.minStick); + ClampStick(&status->substickX, &status->substickY, ClampRegion.maxSubstick, ClampRegion.xySubstick, ClampRegion.minSubstick); + ClampTrigger(&status->triggerLeft, ClampRegion.minTrigger, ClampRegion.maxTrigger); + ClampTrigger(&status->triggerRight, ClampRegion.minTrigger, ClampRegion.maxTrigger); + } + } +} + +void PADClampCircle(PADStatus* status) { + int i; + for (i = 0; i < 4; ++i, status++) { + if (status->err == PAD_ERR_NONE) { + ClampCircle(&status->stickX, &status->stickY, ClampRegion.radStick, ClampRegion.minStick); + ClampCircle(&status->substickX, &status->substickY, ClampRegion.radSubstick, ClampRegion.minSubstick); + ClampTrigger(&status->triggerLeft, ClampRegion.minTrigger, ClampRegion.maxTrigger); + ClampTrigger(&status->triggerRight, ClampRegion.minTrigger, ClampRegion.maxTrigger); + } + } +} diff --git a/src/dolphin/perf/__perf.h b/src/dolphin/perf/__perf.h new file mode 100644 index 0000000..0257b57 --- /dev/null +++ b/src/dolphin/perf/__perf.h @@ -0,0 +1,14 @@ +#ifndef _DOLPHIN_PERF_INTERNAL_H_ +#define _DOLPHIN_PERF_INTERNAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void __PERFDrawInit(void (*id)()); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_PERF_INTERNAL_H_ diff --git a/src/dolphin/perf/perf.c b/src/dolphin/perf/perf.c new file mode 100644 index 0000000..7ad66a7 --- /dev/null +++ b/src/dolphin/perf/perf.c @@ -0,0 +1,467 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__perf.h" +#include "../gx/__gx.h" + +#if DEBUG +const char* __PERFVersion = "<< Dolphin SDK - PERF\tdebug build: Apr 5 2004 03:57:10 (0x2301) >>"; +#else +const char* __PERFVersion = "<< Dolphin SDK - PERF\trelease build: Apr 5 2004 04:15:51 (0x2301) >>"; +#endif + +#define TOKEN_MAX 0xFFFF + +static OSAlarm PERFAlarm; + +static volatile s32 CurrAutoSample = 0xFFFFFFFF; +static volatile u32 CurrToken = 0x0000FFFF; + +static volatile u8 magic; +static void* (*PerfAlloc)(u32); +static void (*PerfFree)(void*); +static void (*DSCB)(u16); +u32 PERFNumFrames; +u32 PERFNumEvents; +u32 PERFNumSamples; +Frame* PERFFrames; +PerfEvent* PERFEvents; +u32 PERFCurrFrame; +volatile s32 PERFCurrSample; + +// prototypes +static void PERFResetAllMemMetrics(void); +static void PERFGetAllMemMetrics(PerfSample* s, u32 i); +void PERFSetDrawSyncCallback(void (*cb)(u16)); +static void PERFTokenCallback(u16 token); +u32 PERFInit(u32 numSamples, u32 numFramesHistory, u32 numTypes, PERFAllocator allocator, PERFDeallocator deallocator, void (*initDraw)()); +void PERFSetEvent(u8 id, char* name, PerfType type); +void PERFSetEventColor(u8 id, GXColor color); +void PERFStartFrame(void); +void PERFEndFrame(void); +void PERFEventStart(u8 id); +__declspec(weak) s32 PERFGetNewSample(void); +void PERFEventEnd(u8 id); +static void PERFStartAutoSample(void); +static void PERFEndAutoSample(void); +static void PERFTimerCallback(OSAlarm* alarm, OSContext* context); +void PERFStartAutoSampling(f32 msInterval); +void PERFStopAutoSampling(void); + +#ifndef DEBUG +inline s32 PERFGetNewSample(void) { + if (PERFCurrSample >= (PERFNumSamples - 1)) { + PERFCurrSample = PERFNumSamples - 1; + return PERFCurrSample; + } + return PERFCurrSample++; +} +#endif + +static void PERFResetAllMemMetrics(void) { + ((u16*)__memReg)[25] = 0; + ((u16*)__memReg)[26] = 0; + ((u16*)__memReg)[27] = 0; + ((u16*)__memReg)[28] = 0; + ((u16*)__memReg)[30] = 0; + ((u16*)__memReg)[29] = 0; + ((u16*)__memReg)[32] = 0; + ((u16*)__memReg)[31] = 0; + ((u16*)__memReg)[34] = 0; + ((u16*)__memReg)[33] = 0; + ((u16*)__memReg)[36] = 0; + ((u16*)__memReg)[35] = 0; + ((u16*)__memReg)[38] = 0; + ((u16*)__memReg)[37] = 0; + ((u16*)__memReg)[40] = 0; + ((u16*)__memReg)[39] = 0; + ((u16*)__memReg)[42] = 0; + ((u16*)__memReg)[41] = 0; + ((u16*)__memReg)[44] = 0; + ((u16*)__memReg)[43] = 0; +} + +static void PERFGetAllMemMetrics(PerfSample* s, u32 i) { + u32 ctrl; + u32 ctrh; + + GXReadXfRasMetric(&s->xfWaitIn[i], &s->xfWaitOut[i], &s->rasBusy[i], &s->rasClocks[i]); + + ctrl = ((u16*)__memReg)[26]; + ctrh = ((u16*)__memReg)[25]; + s->cpReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[28]; + ctrh = ((u16*)__memReg)[27]; + s->tcReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[30]; + ctrh = ((u16*)__memReg)[29]; + s->cpuRdReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[32]; + ctrh = ((u16*)__memReg)[31]; + s->cpuWrReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[34]; + ctrh = ((u16*)__memReg)[33]; + s->dspReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[36]; + ctrh = ((u16*)__memReg)[35]; + s->ioReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[38]; + ctrh = ((u16*)__memReg)[37]; + s->viReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[40]; + ctrh = ((u16*)__memReg)[39]; + s->peReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[42]; + ctrh = ((u16*)__memReg)[41]; + s->rfReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[44]; + ctrh = ((u16*)__memReg)[43]; + s->fiReq[i] = ((ctrh << 0x10) | ctrl); +} + +void PERFSetDrawSyncCallback(void (*cb)(u16)) { + DSCB = cb; +} + +static void PERFTokenCallback(u16 token) { + s32 sample; + + if ((token < 0xE000) || (((int)((u32)token >> 8) & 0xF) != magic) || (PERFCurrSample == 0)) { + if (DSCB) { + DSCB(token); + } + } else { + if (token >= 0xF000) { + if (CurrToken == TOKEN_MAX) { + ASSERTLINE(341, CurrAutoSample >= 0); + PERFEndAutoSample(); + PERFStartAutoSample(); + return; + } + + sample = (u8)(u32)token; + if ((u8)(u16)CurrToken != sample) { + sample = (u8)(u16)CurrToken; + } + + ASSERTLINE(357, sample < PERFCurrSample); + + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[1] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[1] = PPCMfpmc1(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 1); + if (CurrAutoSample >= 0) { + ASSERTLINE(369, CurrToken == TOKEN_MAX); + PERFEndAutoSample(); + } + CurrToken = 0xFFFF; + PERFStartAutoSample(); + return; + } + + if (CurrToken < 0xFFFF) { + ASSERTLINE(384, CurrAutoSample < 0); + sample = (u8)(u16)CurrToken; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[1] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[1] = PPCMfpmc1(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 1); + } else { + ASSERTLINE(394, CurrAutoSample >= 0); + PERFEndAutoSample(); + } + + sample = (u8)(u32)token; + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = PERFFrames[PERFCurrFrame].samples[sample].origgpStart = PPCMfpmc4(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 0); + CurrToken = (u32)(u16)token; + } +} + +u32 PERFInit(u32 numSamples, u32 numFramesHistory, u32 numTypes, PERFAllocator allocator, PERFDeallocator deallocator, void (*initDraw)()) { + u32 i; + u32 size; + + OSRegisterVersion(__PERFVersion); + + PerfAlloc = allocator; + PerfFree = deallocator; + PERFNumFrames = numFramesHistory; + PERFNumEvents = numTypes; + PERFNumSamples = numSamples; + + size = (numFramesHistory * 0x10); + size += (numFramesHistory * (numSamples * 0xB0)); + size += (numTypes* 0x10); + + PERFFrames = (Frame*)PerfAlloc(numFramesHistory * 0x10); + + for (i = 0; i < PERFNumFrames; i++) { + PERFFrames[i].samples = (PerfSample *)PerfAlloc(numSamples* 0xB0); + PERFFrames[i].lastSample = 0; + } + + PERFEvents = (PerfEvent *)PerfAlloc(numTypes* 0x10); + + for (i = 0; i < numTypes; i++) { + PERFEvents[i].name = 0; + PERFEvents[i].currSample = -1; + } + + __PERFDrawInit(initDraw); + GXSetDrawSyncCallback(PERFTokenCallback); + GXInitXfRasMetric(); + return size; +} + +void PERFSetEvent(u8 id, char* name, PerfType type) { + GXColor def = {0xFF, 0x19, 0x00, 0xC8}; + + PERFEvents[id].name = name; + PERFEvents[id].type = type; + PERFEvents[id].currSample = -1; + PERFEvents[id].color = def; +} + +void PERFSetEventColor(u8 id, GXColor color) { + PERFEvents[id].color = color; +} + +void PERFStartFrame(void) { + BOOL enabled = OSDisableInterrupts(); + + PERFCurrSample = 0; + CurrToken = 0xFFFF; + GXSetDrawSyncCallback(PERFTokenCallback); + PERFFrames[PERFCurrFrame].lastSample = 0; + PERFResetAllMemMetrics(); + GXClearGPMetric(); + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); + PPCMtmmcr0(0x8B); + PPCMtmmcr1(0x78400000); + PERFStartAutoSample(); + OSRestoreInterrupts(enabled); +} + +void PERFEndFrame(void) { + u32 i; + BOOL enabled; + + enabled = OSDisableInterrupts(); + PERFEndAutoSample(); + GXSetDrawSyncCallback(DSCB); + PERFFrames[PERFCurrFrame].end = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].lastSample = PERFCurrSample; + PERFFrames[PERFCurrFrame].cachemisscycles = PPCMfpmc3(); + PERFCurrFrame = (PERFCurrFrame + 1) % PERFNumFrames; + PERFCurrSample = 0; + + for (i = 0; i < PERFNumEvents; i++) { + PERFEvents[i].currSample = -1; + } + + magic += 1; + + if ((u8)magic >= 0x10) { + magic = 0; + } + + OSRestoreInterrupts(enabled); +} + +void PERFEventStart(u8 id) { + BOOL enabled; + s32 sample; + + enabled = OSDisableInterrupts(); + + sample = PERFEvents[id].currSample; + if (sample < 0) { + sample = PERFGetNewSample(); + PERFEvents[id].currSample = sample; + PERFFrames[PERFCurrFrame].samples[sample].id = id; + PERFFrames[PERFCurrFrame].samples[sample].interrupted = 0; + + switch(PERFEvents[id].type) { + case PERF_GP_EVENT: + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = 0; + PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = 0; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = 0; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = 0; + GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x2000); + break; + case PERF_CPU_GP_EVENT: + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = 0; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = 0; + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); + GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x2000); + // fallthrough + case PERF_CPU_EVENT: + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[2] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[2] = PPCMfpmc1(); + PERFFrames[PERFCurrFrame].samples[sample].origcpuStart = PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampStart = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampEnd = 0; + break; + default: + OSReport("PERF : Unknown event type for ID %d - possibly out of memory\n", id); + break; + } + } else { + OSReport("PERF : event is still open for CPU!\n"); + } + + OSRestoreInterrupts(enabled); +} + +#if DEBUG +__declspec(weak) s32 PERFGetNewSample(void) { + if (PERFCurrSample >= (PERFNumSamples - 1)) { + PERFCurrSample = PERFNumSamples - 1; + return PERFCurrSample; + } + return PERFCurrSample++; +} +#endif + +void PERFEventEnd(u8 id) { + BOOL enabled; + s32 sample; + + enabled = OSDisableInterrupts(); + sample = PERFEvents[id].currSample; + if (sample < 0) { + OSReport("PERF : ending an event that never started!\n"); + OSRestoreInterrupts(enabled); + return; + } + + switch(PERFEvents[id].type) { + case PERF_GP_EVENT: + GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x1000); + break; + case PERF_CPU_GP_EVENT: + GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x1000); + case PERF_CPU_EVENT: + PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampEnd = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[3] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[3] = PPCMfpmc1(); + break; + } + + PERFEvents[id].currSample = -1; + OSRestoreInterrupts(enabled); +} + +static void PERFStartAutoSample(void) { + CurrAutoSample = PERFGetNewSample(); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].id = 0xFF; + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].interrupted = 0; + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 0); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampStart = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = 0; + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].cacheMisses[0] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].instructions[0] = PPCMfpmc1(); +} + +static void PERFEndAutoSample(void) { + if (CurrAutoSample >= 0) { + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = PPCMfpmc4(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 1); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].cacheMisses[1] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].instructions[1] = PPCMfpmc1(); + } + CurrAutoSample = -1; +} + +static void PERFTimerCallback(OSAlarm* alarm, OSContext* context) { + s32 sample; + s32 newsample; + + if (PERFCurrSample != 0) { + if (CurrToken < 0xFFFF) { + sample = (u8)(u16)CurrToken; + // stupid CurrToken loading AGAIN + if ((u8)((CurrToken >> 8) & 0xF) != (s32)magic) { + PERFEndAutoSample(); + PERFStartAutoSample(); + return; + } + + ASSERTLINE(884, CurrAutoSample < 0); + + newsample = PERFGetNewSample(); + memcpy(&PERFFrames[PERFCurrFrame].samples[newsample], &PERFFrames[PERFCurrFrame].samples[sample], 0xB0); + PERFFrames[PERFCurrFrame].samples[newsample].gpTimeStampEnd = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[newsample].cacheMisses[1] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[newsample].instructions[1] = PPCMfpmc1(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[newsample], 1); + PERFFrames[PERFCurrFrame].samples[newsample].id = 0xFF; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 0); + PERFFrames[PERFCurrFrame].samples[sample].interrupted = 1; + CurrAutoSample = -1; + return; + } + + if (CurrAutoSample < 0) { + OSReport("PERF : AUTOSAMPLE < 0!!!! SHOULD NEVER HAPPEN!\n"); + return; + } + + PERFEndAutoSample(); + PERFStartAutoSample(); + } +} + +void PERFStartAutoSampling(f32 msInterval) { + OSSetPeriodicAlarm(&PERFAlarm, OSGetTime(), (u32)OSMillisecondsToTicks(msInterval), PERFTimerCallback); +} + +void PERFStopAutoSampling(void) { + BOOL enabled = OSDisableInterrupts(); + + if (CurrAutoSample >= 0) { + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = PPCMfpmc4(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 1); + } + + OSCancelAlarm(&PERFAlarm); + OSRestoreInterrupts(enabled); +} + +void PERFShutDown(void) { + BOOL enabled; + u32 i; + + enabled = OSDisableInterrupts(); + PERFStopAutoSampling(); + PERFEndAutoSample(); + GXSetDrawSyncCallback(DSCB); + + for (i = 0; i < PERFNumFrames; i++) { + PerfFree(PERFFrames[i].samples); + } + + PerfFree(PERFEvents); + PerfFree(PERFFrames); + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/perf/perfdraw.c b/src/dolphin/perf/perfdraw.c new file mode 100644 index 0000000..036e918 --- /dev/null +++ b/src/dolphin/perf/perfdraw.c @@ -0,0 +1,695 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__perf.h" + +__declspec(weak) f32 HEIGHT(u32 a, f32 f); +__declspec(weak) f32 COORD(u32 a); + +// internal macro for Perfdraw. +#define DRAW_RECT(x1, x2, y1, y2, color) \ + do { \ + GXSetChanMatColor(GX_COLOR0A0, color); \ + GXBegin(GX_QUADS, GX_VTXFMT0, 4); \ + GXPosition3f32((x1), (y1), -1.0f); \ + GXPosition3f32((x1), (y2), -1.0f); \ + GXPosition3f32((x2), (y2), -1.0f); \ + GXPosition3f32((x2), (y1), -1.0f); \ + GXEnd(); \ + } while(0) + +static u32 DrawFrameMax; +static f32 DrawFrameH; +static u32 MaxBusTransactions; + +static u32 DrawNumFrames = 3; +static f32 DrawFrameW = 205.33333f; +static GXColor DrawFrameBGColor = { 0xC8, 0xC8, 0xC8, 0xC8 }; +static GXColor DrawFrameColor = { 0x19, 0x19, 0x19, 0xC8 }; +static GXColor DrawCPUColor = { 0xFF, 0x19, 0x00, 0xC8 }; +static GXColor DrawFullColor = { 0xFF, 0x00, 0xFF, 0xC8 }; +static GXColor DrawGPColor = { 0x00, 0x64, 0xFF, 0xC8 }; +static GXColor DrawCPUCacheColor = { 0x00, 0x96, 0x00, 0xC8 }; +static GXColor DrawConnectColor = { 0x00, 0x00, 0x00, 0xC8 }; +static GXColor DrawBWBarColor = { 0x32, 0x32, 0x32, 0xC8 }; +static GXColor DrawIPCBarColor = { 0x00, 0x00, 0x5A, 0xAA }; +static GXColor DrawGPUBarColor = { 0x5A, 0x00, 0x00, 0xAA }; +static GXColor DrawIPCColor = { 0xC8, 0x64, 0x00, 0xAA }; +static GXColor DrawCPColor = { 0xC8, 0x00, 0xC8, 0xC8 }; +static GXColor DrawTCColor = { 0x00, 0xC8, 0x00, 0xC8 }; +static GXColor DrawCPURDColor = { 0xFF, 0xFF, 0x00, 0xC8 }; +static GXColor DrawCPUWRColor = { 0x00, 0x64, 0x64, 0xC8 }; +static GXColor DrawDSPColor = { 0xC8, 0x00, 0x00, 0xC8 }; +static GXColor DrawIOColor = { 0x96, 0x96, 0x32, 0xC8 }; +static GXColor DrawVIColor = { 0xFF, 0xFF, 0xFF, 0xC8 }; +static GXColor DrawPEColor = { 0x00, 0x00, 0xC8, 0xC8 }; +static GXColor DrawRFColor = { 0x00, 0xFF, 0xFF, 0xC8 }; +static GXColor DrawFIColor = { 0xC8, 0x64, 0x64, 0xC8 }; +static GXColor DrawGPXFIColor = { 0x00, 0xC8, 0x00, 0xAA }; +static GXColor DrawGPXFOColor = { 0x00, 0x00, 0xC8, 0xAA }; +static GXColor DrawGPRASIDLEColor = { 0xC8, 0xC8, 0x00, 0xAA }; + +static BOOL bDrawBWBar = TRUE; +static BOOL bDrawCPUBar = TRUE; +static BOOL bDrawXFBars = TRUE; +static BOOL bDrawRASBar = TRUE; +static BOOL bAutoScale = TRUE; + +static BOOL bDrawBWBarKey; +static f32 lastx; + +static f32 FramePts[28] = { + 0.0f, + 0.0f, + 0.0f, + 10.0f, + 0.0f, + 0.0f, + 616.0f, + 0.0f, + 616.0f, + 0.0f, + 616.0f, + 10.0f, + 0.0f, + 10.0f, + 616.0f, + 10.0f, + 205.33333f, + 0.0f, + 205.33333f, + 10.0f, + 410.66666f, + 0.0f, + 410.66666f, + 10.0f, + 616.0f, + 0.0f, + 616.0f, + 10.0f, +}; + +static f32 CPUPts[4] = { + 0.0f, + 0.0f, + 616.0f, + 0.0f, +}; + +static f32 GPPts[4] = { + 0.0f, + 0.0f, + 616.0f, + 0.0f, +}; + +void (*GameDrawInit)(); +Mtx mID; + +#ifndef DEBUG +inline f32 HEIGHT(u32 a, f32 f) { + return 140.0f * ((f32) a / ((f32) MaxBusTransactions * f)); +} + +inline f32 COORD(u32 a) { + return 616.0f * ((f32) a / (f32) DrawFrameMax); +} +#endif + +void __PERFDrawInit(void (*id)()) { + MTXIdentity(mID); + GameDrawInit = id; + DrawFrameMax = (OS_CORE_CLOCK / 60) * 3; + DrawFrameH = (PERFNumEvents + 1) * 7; + MaxBusTransactions = (OS_BUS_CLOCK / 120); + FramePts[3] = FramePts[11] = FramePts[13] = FramePts[15] = FramePts[19] = FramePts[23] = DrawFrameH; + FramePts[6] = FramePts[8] = FramePts[10] = FramePts[14] = 616.0f; + GPPts[1] = (PERFNumEvents + 2) * 19; + GPPts[3] = GPPts[1]; +} + +static Mtx44 mProj; +f32 pSave[7]; + +void PERFPreDraw(void) { + u32 i; + u32 j; + + GXGetProjectionv(pSave); + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + mProj[i][j] = 0.0f; + } + } + + mProj[0][0] = 0.003125f; + mProj[1][1] = 0.004166667f; + mProj[2][2] = 1.0f; + mProj[3][3] = 1.0f; + mProj[0][3] = -0.95f; + mProj[1][3] = -0.87500005f; + + GXSetProjection(mProj, GX_ORTHOGRAPHIC); + GXClearVtxDesc(); + GXInvalidateVtxCache(); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + GXSetZCompLoc(GX_FALSE); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetZMode(GX_DISABLE, GX_ALWAYS, GX_DISABLE); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_TEX_ST, GX_RGBA6, 0); +} + +static void DrawBWBar(PerfSample* s) { + u32 delta; + u32 interval; + f32 bwscale; + f32 lastY; + f32 x1; + f32 x2; + f32 height; + u32 rasclocks; + u32 rasBusy; + u32 xfI; + u32 xfO; + u32 instructions; + f32 ipc; + f32 ipcscale; + u32 misses; + + interval = s->gpTimeStampEnd - s->gpTimeStampStart; + bwscale = (f32)interval / (OS_CORE_CLOCK / 60); + lastY = 7.0f + DrawFrameH; + x1 = COORD(s->gpTimeStampStart); + x2 = COORD(s->gpTimeStampEnd); + if (fabs(lastx - x1) < 1.0f) { + x1 = lastx; + } + lastx = x2; + + // Draw BW Bars if toggled + if (bDrawBWBar) { + delta = s->cpReq[1] - s->cpReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPColor); + lastY += height; + } + delta = s->tcReq[1] - s->tcReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawTCColor); + lastY += height; + } + delta = s->cpuRdReq[1] - s->cpuRdReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPURDColor); + lastY += height; + } + delta = s->cpuWrReq[1] - s->cpuWrReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPUWRColor); + lastY += height; + } + delta = s->dspReq[1] - s->dspReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawDSPColor); + lastY += height; + } + delta = s->ioReq[1] - s->ioReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawIOColor); + lastY += height; + } + delta = s->viReq[1] - s->viReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawVIColor); + lastY += height; + } + delta = s->peReq[1] - s->peReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawPEColor); + lastY += height; + } + delta = s->rfReq[1] - s->rfReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawRFColor); + lastY += height; + } + s->fiReq[0] /= 2; + s->fiReq[1] /= 2; + delta = s->fiReq[1] - s->fiReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawFIColor); + } + } + + if (bDrawCPUBar) { + instructions = s->instructions[1] - s->instructions[0]; + ipc = (f32)instructions / (f32) interval; + ipcscale = ipc / 2.0f; + misses = s->cacheMisses[1] - s->cacheMisses[0]; + lastY = 7.0f + (140.0f + (7.0f + DrawFrameH)); + height = ipcscale * 50.0f; + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawIPCColor); + } + height = (50.0f * (f32) misses) / (f32) interval; + DRAW_RECT(x1, x2, (50.0f + lastY) - height, (50.0f + lastY), DrawCPUCacheColor); + } + + rasclocks = s->rasClocks[1] - s->rasClocks[0]; + + if (bDrawXFBars) { + lastY = 14.0f + (50.0f + (140.0f + (7.0f + DrawFrameH))); + xfI = s->xfWaitIn[1] - s->xfWaitIn[0]; + xfO = s->xfWaitOut[1] - s->xfWaitOut[0]; + if (rasclocks >= (u32) (xfO + xfI)) { + xfI = rasclocks - (xfO + xfI); + height = (50.0f * xfI) / rasclocks; + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawGPXFIColor); + } + } + } + + if (bDrawRASBar) { + lastY = 50.0f + (21.0f + (50.0f + (140.0f + (7.0f + DrawFrameH)))); + rasBusy = s->rasBusy[1] - s->rasBusy[0]; + height = (50.0f * (f32)rasBusy) / rasclocks; + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawGPRASIDLEColor); + } + } +} + +#if DEBUG +__declspec(weak) f32 HEIGHT(u32 a, f32 f) { + return 140.0f * ((f32) a / ((f32) MaxBusTransactions * f)); +} + +__declspec(weak) f32 COORD(u32 a) { + return 616.0f * ((f32) a / (f32) DrawFrameMax); +} +#endif + +static void DrawKey(void) { + u32 delta; + u32 foo[2]; + f32 bwscale; + f32 lastY; + f32 x1; + f32 x2; + f32 height; + + x1 = 595.4667f; + x2 = 616.0f; + lastY = 7.0f + DrawFrameH; + bwscale = 1.0f; + foo[0] = 0; + foo[1] = MaxBusTransactions / 10; + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawTCColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPURDColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPUWRColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawDSPColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawIOColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawVIColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawPEColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawRFColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawFIColor); + lastY += height; + } +} + +void PERFDumpScreen(void) { + PerfSample* samples; + u32 s; + u32 id; + u32 i; + u32 delta; + u32 e; + f32 c; + f32 lastY; + f32 allX; + f32 xcoord; + + if (GameDrawInit) { + samples = PERFFrames[PERFCurrFrame].samples; + + if (bAutoScale) { + DrawNumFrames = PERFFrames[PERFCurrFrame].end / (OS_CORE_CLOCK / 60) + 1; + } + + DrawFrameMax = (OS_CORE_CLOCK / 60) * DrawNumFrames; + DrawFrameW = 616.0f / DrawNumFrames; + allX = COORD(PERFFrames[PERFCurrFrame].end); + GXLoadPosMtxImm(mID, 0); + DRAW_RECT(0.0f, 616.0f, 0.0f, DrawFrameH, DrawFrameBGColor); + GXSetChanMatColor(GX_COLOR0A0, DrawFrameColor); + GXSetLineWidth(0xCU, GX_TO_ZERO); + + // different draw shape? Consider other forms of this draw macro that may work. If anything will work. + GXBegin(GX_LINES, GX_VTXFMT0, 8); + GXPosition3f32(FramePts[0], FramePts[1], -1.0f); + GXPosition3f32(FramePts[2], FramePts[3], -1.0f); + GXPosition3f32(FramePts[4], FramePts[5], -1.0f); + GXPosition3f32(FramePts[6], FramePts[7], -1.0f); + GXPosition3f32(FramePts[8], FramePts[9], -1.0f); + GXPosition3f32(FramePts[10], FramePts[11], -1.0f); + GXPosition3f32(FramePts[12], FramePts[13], -1.0f); + GXPosition3f32(FramePts[14], FramePts[15], -1.0f); + GXEnd(); + + if (DrawNumFrames > 1) { + GXBegin(GX_LINES, GX_VTXFMT0, (DrawNumFrames - 1) * 2); + for(i = 1; i < DrawNumFrames; i++) { + xcoord = COORD(i * (OS_CORE_CLOCK / 60)); + GXPosition3f32(xcoord, FramePts[17], -1.0f); + GXPosition3f32(xcoord, FramePts[19], -1.0f); + } + GXEnd(); + } + + GXSetChanMatColor(GX_COLOR0A0, DrawFullColor); + GXSetLineWidth(0x20U, GX_TO_ZERO); + + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, -1.0f); + GXPosition3f32(allX, 0.0f, -1.0f); + GXEnd(); + + GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); + + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, -1.0f); + GXPosition3f32(COORD(PERFFrames[PERFCurrFrame].cachemisscycles), 0.0f, -1.0f); + GXEnd(); + + if (bDrawBWBar) { + lastY = 7.0f + DrawFrameH; + GXSetChanMatColor(GX_COLOR0A0, DrawBWBarColor); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(0.0f, lastY, -1.0f); + GXPosition3f32(0.0f, 140.0f + lastY, -1.0f); + GXPosition3f32(allX, 140.0f + lastY, -1.0f); + GXPosition3f32(allX, lastY, -1.0f); + GXEnd(); + } + + if (bDrawCPUBar) { + lastY = 7.0f + (140.0f + (7.0f + DrawFrameH)); + GXSetChanMatColor(GX_COLOR0A0, DrawIPCBarColor); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(0.0f, lastY, -1.0f); + GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, lastY, -1.0f); + GXEnd(); + GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); + GXSetLineWidth(6, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 25.0f + lastY, -1.0f); + GXPosition3f32(allX, 25.0f + lastY, -1.0f); + GXEnd(); + } + + if (bDrawXFBars) { + lastY = 14.0f + (50.0f + (140.0f + (7.0f + DrawFrameH))); + GXSetChanMatColor(GX_COLOR0A0, DrawGPUBarColor); + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(0.0f, lastY, -1.0f); + GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, lastY, -1.0f); + GXEnd(); + } + + if (bDrawRASBar) { + lastY = 50.0f + (21.0f + (50.0f + (140.0f + (7.0f + DrawFrameH)))); + GXSetChanMatColor(GX_COLOR0A0, DrawGPUBarColor); + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(0.0f, lastY, -1.0f); + GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, lastY, -1.0f); + GXEnd(); + } + + for (s = 0; s < PERFFrames[PERFCurrFrame].lastSample; s++) { + id = samples[s].id; + if (id == 0xFF) { + DrawBWBar(&samples[s]); + } else { + switch(PERFEvents[id].type) { + case PERF_CPU_GP_EVENT: + GXSetChanMatColor(GX_COLOR0A0, PERFEvents[id].color); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + delta = samples[s].cacheMisses[3] - samples[s].cacheMisses[2]; + if (delta) { + e = delta + samples[s].cpuTimeStampStart; + c = COORD(e); + GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(c, (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + } + + if (samples[s].gpTimeStampEnd != 0) { + if (!samples[s].interrupted) { + GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXEnd(); + + DrawBWBar(&samples[s]); + + GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); + GXSetLineWidth(6, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 4); + GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + } else { + GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXEnd(); + + DrawBWBar(&samples[s]); + + GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); + GXSetLineWidth(6, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 4); + GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].origcpuStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + } + } + break; + case PERF_CPU_EVENT: + GXSetChanMatColor(GX_COLOR0A0, PERFEvents[id].color); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + !samples[s].cpuTimeStampStart; // needed to match + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + + delta = samples[s].cacheMisses[3] - samples[s].cacheMisses[2]; + if (delta != 0) { + e = delta + samples[s].cpuTimeStampStart; + c = COORD(e); + GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(c, (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + } + break; + case PERF_GP_EVENT: + if (samples[s].interrupted == 0) { + GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXEnd(); + DrawBWBar(&samples[s]); + } else { + GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXEnd(); + DrawBWBar(&samples[s]); + } + break; + } + } + } + + if (bDrawBWBarKey) { + DrawKey(); + } + } +} + +void PERFPostDraw(void) { + u32 i; + u32 j; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + mProj[i][j] = 0.0f; + } + } + + mProj[0][0] = pSave[1]; + mProj[0][2] = pSave[2]; + mProj[1][1] = pSave[3]; + mProj[1][2] = pSave[4]; + mProj[2][2] = pSave[5]; + mProj[2][3] = pSave[6]; + mProj[3][2] = -1.0f; + GXSetProjection(mProj, GX_PERSPECTIVE); + GameDrawInit(); +} + +void PERFSetDrawBWBarKey(BOOL tf) { + bDrawBWBarKey = tf; +} + +void PERFSetDrawBWBar(BOOL tf) { + bDrawBWBar = tf; +} + +void PERFSetDrawCPUBar(BOOL tf) { + bDrawCPUBar = tf; +} + +void PERFSetDrawXFBars(BOOL tf) { + bDrawXFBars = tf; +} + +void PERFSetDrawRASBar(BOOL tf) { + bDrawRASBar = tf; +} + +void PERFToggleDrawBWBarKey(void) { + bDrawBWBarKey = (bDrawBWBarKey) ? FALSE : TRUE; +} + +void PERFToggleDrawBWBar(void) { + bDrawBWBar = (bDrawBWBar) ? FALSE : TRUE; +} + +void PERFToggleDrawCPUBar(void) { + bDrawCPUBar = (bDrawCPUBar) ? FALSE : TRUE; +} + +void PERFToggleDrawXFBars(void) { + bDrawXFBars = (bDrawXFBars) ? FALSE : TRUE; +} + +void PERFToggleDrawRASBar(void) { + bDrawRASBar = (bDrawRASBar) ? FALSE : TRUE; +} + +void PERFSetDrawFrames(u32 frames) { + if (frames != 0) { + DrawNumFrames = frames; + bAutoScale = FALSE; + } else { + bAutoScale = TRUE; + } +} diff --git a/src/dolphin/seq/seq.c b/src/dolphin/seq/seq.c new file mode 100644 index 0000000..582a323 --- /dev/null +++ b/src/dolphin/seq/seq.c @@ -0,0 +1,468 @@ +#include +#include + +static u8 __SEQMidiEventLength[128] = { + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x00, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +static SEQSEQUENCE* __SEQSequenceList; + +// prototypes +static void __SEQPushSequenceList(SEQSEQUENCE* sequence); +static void __SEQRemoveSequenceFromList(SEQSEQUENCE* sequence); +static u32 __SEQGetIntTrack(SEQTRACK* track); +static void __SEQHandleSysExEvent(SEQTRACK* track); +static void __SEQSetTicksPerFrame(SEQTRACK* track, f32 bps); +static void __SEQTempoMetaEvent(SEQTRACK* track); +static void __SEQTrackEnd(SEQTRACK* track); +static void __SEQHandleMetaEvent(SEQTRACK* track); +static void __SEQHandleSynthEvent(SYNSYNTH* synth, SEQTRACK* track); +static void __SEQRunEvent(SYNSYNTH* synth, SEQTRACK* track); +static void __SEQInitTracks(SEQSEQUENCE* sequence, u8* read, int tracks); +static void __SEQReadHeader(SEQSEQUENCE* sequence, u8* midiStream); + +static void __SEQPushSequenceList(SEQSEQUENCE* sequence) { + BOOL old; + + old = OSDisableInterrupts(); + if (__SEQSequenceList) { + sequence->next = __SEQSequenceList; + } else { + sequence->next = NULL; + } + + __SEQSequenceList = sequence; + OSRestoreInterrupts(old); +} + +static void __SEQRemoveSequenceFromList(SEQSEQUENCE* sequence) { + BOOL old; + SEQSEQUENCE* thisSequence; + SEQSEQUENCE* next; + + old = OSDisableInterrupts(); + thisSequence = __SEQSequenceList; + __SEQSequenceList = NULL; + + while(thisSequence) { + next = thisSequence->next; + if (thisSequence != sequence) { + __SEQPushSequenceList(thisSequence); + } + thisSequence = next; + } + + OSRestoreInterrupts(old); +} + +static u32 __SEQGetIntTrack(SEQTRACK* track) { + u32 value; + + ASSERTLINE(120, track); + for (value = *track->current & 0x7F; *track->current & 0x80; value = (value << 7) + (*track->current & 0x7F)) { + track->current++; + } + track->current++; + return value; +} + +static void __SEQHandleSysExEvent(SEQTRACK* track) { + u32 length; + + ASSERTLINE(143, track); + length = __SEQGetIntTrack(track); + track->current += length; +} + +static void __SEQSetTicksPerFrame(SEQTRACK* track, f32 bps) { + SEQSEQUENCE* sequence; + + ASSERTLINE(157, track); + sequence = track->sequence; + track->beatsPerSec = bps; + track->ticksPerFrame = (65536.0f * (160.0f / ((32000.0f / bps) / sequence->timeFormat))); +} + +static void __SEQTempoMetaEvent(SEQTRACK* track) { + u32 data; + f32 beatsPerSec; + + data = *track->current; + track->current++; + + data = (data << 8) + *track->current; + track->current++; + + data = (data << 8) + *track->current; + track->current++; + + beatsPerSec = 1000000 / (f32)data; + __SEQSetTicksPerFrame(track, beatsPerSec); +} + +static void __SEQTrackEnd(SEQTRACK* track) { + SEQSEQUENCE* sequence; + ASSERTLINE(199, track); + + sequence = track->sequence; + sequence->tracksRunning--; + track->state = 0; + if (sequence->tracksRunning == 0) { + sequence->end = 1; + } +} + +static void __SEQHandleMetaEvent(SEQTRACK* track) { + u8 type; + u32 length; + + ASSERTLINE(218, track); + type = *track->current; + track->current++; + + switch(type) { + case 0x2F: + __SEQTrackEnd(track); + return; + case 0x51: + length = __SEQGetIntTrack(track); + __SEQTempoMetaEvent(track); + return; + default: + length = __SEQGetIntTrack(track); + track->current += length; + return; + } +} + +static void __SEQHandleSynthEvent(SYNSYNTH* synth, SEQTRACK* track) { + u8 ch[3]; + u32 bytes; + void (*callback)(void *, u8); + + bytes = __SEQMidiEventLength[track->status - 0x80]; + ch[0] = track->status; + + switch(bytes) { + case 0: + break; + case 1: + ch[1] = *track->current; track->current++; + break; + case 2: + ch[1] = *track->current; track->current++; + ch[2] = *track->current; track->current++; + break; + } + + if ((ch[0] & 0xF0) == 0xB0) { + callback = ((SEQSEQUENCE*)track->sequence)->callback[ch[1]]; + if (callback) { + callback(track, ch[1]); + } + } + + SYNMidiInput(synth, ch); +} + +static void __SEQRunEvent(SYNSYNTH* synth, SEQTRACK* track) { + u8 event; + + ASSERTLINE(303, synth); + ASSERTLINE(304, track); + + event = *track->current; + if (event >= 0x80) { + track->status = event; track->current++; + } + + switch(track->status) { + case 0xF7: + case 0xF0: + __SEQHandleSysExEvent(track); + break; + case 0xFF: + __SEQHandleMetaEvent(track); + break; + default: + __SEQHandleSynthEvent(synth, track); + break; + } + + if (track->current >= track->end) { + __SEQTrackEnd(track); + } +} + +static void __SEQInitTracks(SEQSEQUENCE* sequence, u8* read, int tracks) { + int i; + u8* p; + u32 chunk; + u32 bytes; + SEQTRACK* track; + + i = 0; + p = read; + + while (tracks) { + while (1) { + chunk = *(u32*)p; + p += 4; + bytes = *(u32*)p; + p += 4; + if (chunk == 'MTrk') { + track = &sequence->track[i]; + track->sequence = sequence; + track->start = p; + track->end = &p[bytes]; + track->current = p; + track->defaultTicksPerFrame = (u32)(65536.0f * (160.0f / (16000.0f / (f32)sequence->timeFormat))); + track->state = 0; + p += bytes; + break; + } + p += bytes; + } + tracks--; + i++; + } +} + +static void __SEQReadHeader(SEQSEQUENCE* sequence, u8* midiStream) { + u8* read; + u32 bytes; + u32 fileType; + + read = midiStream; + ASSERTMSGLINE(401, *(u32*)read == 'MThd', "!!!midiStream is not a valid MIDI file\n!!!"); + read += 4; + + bytes = *(u32*)read; + read += 4; + + fileType = *(u16*)read; + read+=2; + + sequence->nTracks = *(u16*)read; + read+=2; + + sequence->timeFormat = *(s16*)read; + read+=2; + + ASSERTMSGLINE(416, sequence->timeFormat >= 0, "!!!SEQ does not support SMPTE time!!!\n"); + bytes -= 6; + read += bytes; + + switch(fileType) { + case 0: + sequence->nTracks = 1; + __SEQInitTracks(sequence, read, 1); + break; + case 1: + ASSERTMSGLINE(438, sequence->nTracks < 0x40, "exceeded SEQ_MAX_TRACKS, please increase SEQ_MAX_TRACKS\n"); + __SEQInitTracks(sequence, read, sequence->nTracks); + break; + default: + ASSERTMSGLINE(446, 0, "!!!Invalid MIDI file type\n!!!"); + break; + } + + sequence->tracksRunning = sequence->nTracks; +} + +void SEQInit(void) { + __SEQSequenceList = NULL; +} + +void SEQQuit(void) { + __SEQSequenceList = NULL; +} + +void SEQRunAudioFrame(void) { + SEQSEQUENCE* sequence; + u32 i; + SEQTRACK* track; + u32 ticks; + + for (sequence = __SEQSequenceList; sequence; sequence = sequence->next) { + if ((sequence->state == 1) || (sequence->state == 2)) { + for (i = 0; i < sequence->nTracks; i++) { + track = &sequence->track[i]; + if ((track->state == 1) || (track->state == 2)) { + ticks = track->ticksPerFrame; + if (track->delay > ticks) { + track->delay -= ticks; + } else { + while (ticks >= track->delay) { + ticks -= track->delay; + __SEQRunEvent(&sequence->synth, track); + if (track->state != 0) { + track->delay = __SEQGetIntTrack(track) << 0x10; + } else { + break; + } + } + + track->delay -= ticks; + } + } + } + } + + if (sequence->end != 0) { + if (sequence->state == 2) { + SEQSetState(sequence, 0); + SEQSetState(sequence, 2); + } else { + SEQSetState(sequence, 0); + } + } + } +} + +void SEQAddSequence(SEQSEQUENCE* sequence, u8* midiStream, void* wt, u32 aramBase, u32 zeroBase, u32 priorityVoiceAlloc, u32 priorityNoteOn, u32 priorityNoteRelease) { + int i; + + ASSERTLINE(559, sequence); + ASSERTLINE(560, midiStream); + ASSERTLINE(561, wt); + ASSERTLINE(562, aramBase); + ASSERTLINE(563, (priorityVoiceAlloc < 32) && (priorityVoiceAlloc > 0)); + ASSERTLINE(564, (priorityNoteOn < 32) && (priorityNoteOn > 0)); + ASSERTLINE(565, (priorityNoteRelease < 32) && (priorityNoteRelease > 0)); + + SYNInitSynth(&sequence->synth, wt, aramBase, zeroBase, priorityVoiceAlloc, priorityNoteOn, priorityNoteRelease); + sequence->state = 0; + + for(i = 0; i < 0x80; i++) { + sequence->callback[i] = 0; + } + + __SEQReadHeader(sequence, midiStream); + __SEQPushSequenceList(sequence); +} + +void SEQRemoveSequence(SEQSEQUENCE* sequence) { + ASSERTLINE(598, sequence); + __SEQRemoveSequenceFromList(sequence); + SYNQuitSynth(&sequence->synth); +} + +void SEQRegisterControllerCallback(SEQSEQUENCE* sequence, u8 controller, void (*callback)(void*, u8)) { + ASSERTLINE(617, sequence); + ASSERTLINE(618, controller < 128); + ASSERTLINE(619, callback); + sequence->callback[controller] = callback; +} + +void SEQSetState(SEQSEQUENCE* sequence, u32 state) { + int i; + + ASSERTLINE(632, sequence); + + switch(state) { + case 1: + case 2: + if (sequence->state == 0) { + int old; + + old = OSDisableInterrupts(); + for (i = 0; i < sequence->nTracks; i++) { + SEQTRACK* track = &sequence->track[i]; + track->current = track->start; + track->ticksPerFrame = track->defaultTicksPerFrame; + track->delay = __SEQGetIntTrack(track) << 0x10; + track->state = 1; + } + sequence->tracksRunning = sequence->nTracks; + OSRestoreInterrupts(old); + } + sequence->end = 0; + break; + case 0: + case 3: { + int old; + u8 ch[3]; + + for (i = 0; i < 16; i++) { + old = OSDisableInterrupts(); + ch[0] = (i | 0xB0); + ch[1] = 0x7B; + ch[2] = 0; + SYNMidiInput(&sequence->synth, ch); + OSRestoreInterrupts(old); + } + break; + } + } + + sequence->state = state; +} + +u32 SEQGetState(SEQSEQUENCE* sequence) { + ASSERTLINE(700, sequence); + return sequence->state; +} + +void SEQSetTempo(SEQSEQUENCE* sequence, u32 trackIndex, f32 bpm) { + int i; + + ASSERTLINE(711, sequence); + ASSERTLINE(712, (trackIndex < sequence->nTracks) || (trackIndex == SEQ_ALL_TRACKS)); + + if (trackIndex == -1) { + for (i = 0; i < sequence->nTracks; i++) { + __SEQSetTicksPerFrame(&sequence->track[i], bpm / 60.0f); + } + return; + } + + __SEQSetTicksPerFrame(&sequence->track[trackIndex], bpm / 60.0f); +} + +f32 SEQGetTempo(SEQSEQUENCE* sequence, u32 trackIndex) { + ASSERTLINE(733, sequence); + ASSERTLINE(734, trackIndex < sequence->nTracks); + return 60.0f* sequence->track[trackIndex].beatsPerSec; +} + +void SEQSetVolume(SEQSEQUENCE* sequence, s32 dB) { + ASSERTLINE(745, sequence); + SYNSetMasterVolume(&sequence->synth, dB); +} + +long SEQGetVolume(SEQSEQUENCE* sequence) { + ASSERTLINE(756, sequence); + SYNGetMasterVolume(&sequence->synth); +} diff --git a/src/dolphin/si/SIBios.c b/src/dolphin/si/SIBios.c new file mode 100644 index 0000000..cc7164e --- /dev/null +++ b/src/dolphin/si/SIBios.c @@ -0,0 +1,798 @@ +#include +#include + +#include "__os.h" + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +#ifdef DEBUG +const char* __SIVersion = "<< Dolphin SDK - SI\tdebug build: Apr 5 2004 03:55:31 (0x2301) >>"; +#else +const char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Apr 5 2004 04:14:16 (0x2301) >>"; +#endif + +static SIControl Si = { + /* chan */ -1, + /* poll */ 0, + /* inputBytes */ 0, + /* input */ NULL, + /* callback */ NULL +}; + +static SIPacket Packet[4]; +static OSAlarm Alarm[4]; +static u32 Type[4] = { SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE }; +static OSTime TypeTime[4]; +static OSTime XferTime[4]; +static SITypeCallback TypeCallback[4][4]; +static __OSInterruptHandler RDSTHandler[4]; +static BOOL InputBufferValid[4]; +static u32 InputBuffer[4][2]; +static volatile u32 InputBufferVcount[4]; + +u32 __PADFixBits; + +// prototypes +static u32 CompleteTransfer(); +static void SITransferNext(s32 chan); +static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context); +static int __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback); +static void AlarmHandler(OSAlarm* alarm, OSContext* context); +static void GetTypeCallback(s32 chan, u32 error, OSContext* context); +static int SIGetResponseRaw(s32 chan); + +BOOL SIBusy(void) { + return (Si.chan != -1) ? TRUE : FALSE; +} + +BOOL SIIsChanBusy(s32 chan) { + return Packet[chan].chan != -1 || Si.chan == chan; +} + +static void SIClearTCInterrupt(void) { + u32 reg; + + reg = __SIRegs[SI_COMCSR_IDX]; + reg |= SI_COMCSR_TCINT_MASK; + reg &= ~SI_COMCSR_TSTART_MASK; + __SIRegs[SI_COMCSR_IDX] = reg; +} + +static u32 CompleteTransfer(void) { + u32 sr; + u32 i; + u32 rLen; + u8* input; + u32 temp; + + sr = __SIRegs[SI_STATUS_IDX]; + SIClearTCInterrupt(); + + if (Si.chan != -1) { + XferTime[Si.chan] = __OSGetSystemTime(); + input = Si.input; + rLen = Si.inputBytes / sizeof(u32); + for (i = 0; i < rLen; i++) { + *((u32*)input)++ = __SIRegs[i+0x20]; + } + + rLen = Si.inputBytes & 3; + if (rLen != 0) { + temp = __SIRegs[i + 32]; + for (i = 0; i < rLen; i++) { + *(input++) = temp >> ((3 - i) * 8); + } + } + + if (__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_COMERR_MASK) { + sr >>= (3 - Si.chan) * 8; + sr &= 0xF; + if ((sr & 8) != 0 && (Type[Si.chan] & 0x80) == 0) { + Type[Si.chan] = 8; + } + + if (sr == 0) { + sr = 4; + } + } 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 < 4; i++) { + chan++; + chan %= 4; + packet = &Packet[chan]; + + if (packet->chan != -1) { + if (packet->fire <= __OSGetSystemTime()) { + if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, packet->inputBytes, packet->callback) != 0) { + OSCancelAlarm(&Alarm[chan]); + packet->chan = -1; + } + return; + } + } + } +} + +#define CHAN_NONE -1 + +static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) { + u32 reg; + s32 chan; + u32 sr; + SICallback callback; + int i; + u32 vcount; + u32 x; + + reg = __SIRegs[SI_COMCSR_IDX]; + if ((reg & (SI_COMCSR_TCINT_MASK | SI_COMCSR_TCINTMSK_MASK)) == (SI_COMCSR_TCINT_MASK | SI_COMCSR_TCINTMSK_MASK)) { + ASSERTLINE(376, Si.chan != CHAN_NONE); + + chan = Si.chan; + sr = CompleteTransfer(); + callback = Si.callback; + Si.callback = NULL; + SITransferNext(chan); + + if (callback) { + callback(chan, sr, context); + } + + sr = __SIRegs[SI_STATUS_IDX]; + sr &= 0x0F000000 >> (chan << 3); + __SIRegs[SI_STATUS_IDX] = sr; + + if (Type[chan] == SI_ERROR_BUSY && !SIIsChanBusy(chan)) { + static u32 cmdTypeAndStatus; + + SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, &GetTypeCallback, OSMicrosecondsToTicks(65)); + } + } + + if ((reg & (SI_COMCSR_RDSTINT_MASK | SI_COMCSR_RDSTINTMSK_MASK)) == (SI_COMCSR_RDSTINT_MASK | SI_COMCSR_RDSTINTMSK_MASK)) { + vcount = 1 + VIGetCurrentLine(); + x = (Si.poll & (0x3FF << 16)) >> 16; + + for (i = 0; i < 4; i++) { + if (SIGetResponseRaw(i)) { + InputBufferVcount[i] = vcount; + } + } + + for (i = 0; i < 4; i++) { + if ((Si.poll & (0x80000000 >> (24 + i))) != 0) { + if (InputBufferVcount[i] == 0 || ((x >> 1) + InputBufferVcount[i]) < vcount) { + return; + } + } + } + + for (i = 0; i < 4; i++) { + InputBufferVcount[i] = 0; + } + + for (i = 0; i < 4; i++) { + if (RDSTHandler[i] != 0) { + (*RDSTHandler[i])(interrupt, context); + } + } + } +} + +static BOOL SIEnablePollingInterrupt(BOOL enable) { + BOOL enabled; + BOOL rc; + u32 reg; + int i; + + enabled = OSDisableInterrupts(); + reg = __SIRegs[SI_COMCSR_IDX]; + rc = ((reg & SI_COMCSR_RDSTINTMSK_MASK) != 0) ? TRUE : FALSE; + + if (enable) { + reg |= SI_COMCSR_RDSTINTMSK_MASK; + + for (i = 0; i < 4; i++) { + InputBufferVcount[i] = 0; + } + } else { + reg &= ~SI_COMCSR_RDSTINTMSK_MASK; + } + + reg &= ~(SI_COMCSR_TCINT_MASK | SI_COMCSR_TSTART_MASK); + __SIRegs[SI_COMCSR_IDX] = 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] != 0) { + break; + } + } + + if (i == 4) { + SIEnablePollingInterrupt(FALSE); + } + + OSRestoreInterrupts(enabled); + return TRUE; + } + } + + 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); + + do {} while(__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_TSTART_MASK); + + __SIRegs[SI_COMCSR_IDX] = SI_COMCSR_TCINT_MASK; + __OSSetInterruptHandler(0x14, SIInterruptHandler); + __OSUnmaskInterrupts(0x800); + + SIGetType(0); + SIGetType(1); + SIGetType(2); + SIGetType(3); +} + +static int __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback) { + BOOL enabled; + u32 rLen; + u32 i; + u32 sr; + union { + u32 val; + struct { + u32 tcint : 1; + u32 tcintmsk : 1; + u32 comerr : 1; + u32 rdstint : 1; + u32 rdstintmsk : 1; + u32 pad2 : 4; + u32 outlngth : 7; + u32 pad1 : 1; + u32 inlngth : 7; + u32 pad0 : 5; + u32 channel : 2; + u32 tstart : 1; + } f; + } comcsr; + + ASSERTMSGLINE(627, (chan >= 0) && (chan < 4), "SITransfer(): invalid channel."); + ASSERTMSGLINE(629, (outputBytes != 0) && (outputBytes <= 128), "SITransfer(): output size is out of range (must be 1 to 128)."); + ASSERTMSGLINE(631, (inputBytes != 0) && (inputBytes <= 128), "SITransfer(): input size is out of range (must be 1 to 128)."); + + enabled = OSDisableInterrupts(); + if (Si.chan != -1) { + OSRestoreInterrupts(enabled); + return 0; + } + + ASSERTLINE(641, (__SIRegs[SI_COMCSR_IDX] & (SI_COMCSR_TSTART_MASK | SI_COMCSR_TCINT_MASK)) == 0); + sr = __SIRegs[SI_STATUS_IDX]; + sr &= (0x0F000000 >> (chan* 8)); + __SIRegs[SI_STATUS_IDX] = sr; + + Si.chan = chan; + Si.callback = callback; + Si.inputBytes = inputBytes; + Si.input = input; + + rLen = ROUND(outputBytes, 4) / 4; + for (i = 0; i < rLen; i++) { + __SIRegs[i + 0x20] = ((u32*)output)[i]; + } + + comcsr.val = __SIRegs[SI_COMCSR_IDX]; + comcsr.f.tcint = 1; + comcsr.f.tcintmsk = callback ? 1 : 0; + comcsr.f.outlngth = outputBytes == 0x80 ? 0 : outputBytes; + comcsr.f.inlngth = inputBytes == 0x80 ? 0 : inputBytes; + comcsr.f.channel = chan; + comcsr.f.tstart = 1; + + __SIRegs[SI_COMCSR_IDX] = comcsr.val; + OSRestoreInterrupts(enabled); + return 1; +} + +u32 SISync(void) { + BOOL enabled; + u32 sr; + + do {} while(__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_TSTART_MASK); + + enabled = OSDisableInterrupts(); + sr = CompleteTransfer(); + SITransferNext(4); + OSRestoreInterrupts(enabled); + return sr; +} + +u32 SIGetStatus(s32 chan) { + BOOL enabled; + u32 sr; + int chanShift; + + enabled = OSDisableInterrupts(); + sr = __SIRegs[SI_STATUS_IDX]; + chanShift = (3 - chan) * 8; + sr >>= chanShift; + + if ((sr & 8) != 0) { + if ((Type[chan] & SI_ERROR_BUSY) == 0) { + Type[chan] = 8; + } + } + + OSRestoreInterrupts(enabled); + return sr; +} + +void SISetCommand(s32 chan, u32 command) { + ASSERTMSGLINE(752, (chan >= 0) && (chan < 4), "SISetCommand(): invalid channel."); + __SIRegs[chan* 3] = command; +} + +u32 SIGetCommand(s32 chan) { + ASSERTMSGLINE(770, (chan >= 0) && (chan < 4), "SIGetCommand(): invalid channel."); + return __SIRegs[chan* 3]; +} + +void SITransferCommands(void) { + __SIRegs[SI_STATUS_IDX] = SI_COMCSR_TCINT_MASK; +} + +u32 SISetXY(u32 x, u32 y) { + u32 poll; + BOOL enabled; + + ASSERTMSGLINE(803, x >= 8, "SISetXY(): x is out of range (8 <= x <= 1023)."); + ASSERTMSGLINE(804, x <= 1023, "SISetXY(): x is out of range (8 <= x <= 1023)."); + ASSERTMSGLINE(805, y <= 255, "SISetXY(): y is out of range (0 <= y <= 255)."); + + poll = x << 0x10; + poll |= y << 8; + enabled = OSDisableInterrupts(); + Si.poll &= 0xFC0000FF; + Si.poll |= poll; + poll = Si.poll; + __SIRegs[0x30 / 4] = poll; + OSRestoreInterrupts(enabled); + return poll; +} + +u32 SIEnablePolling(u32 poll) { + BOOL enabled; + u32 en; + + ASSERTMSGLINE(834, (poll & 0x0FFFFFFF) == 0, "SIEnablePolling(): invalid chan bit(s)."); + if (poll == 0) { + return Si.poll; + } + + enabled = OSDisableInterrupts(); + poll = poll >> 24; + en = poll & 0xF0; + ASSERTLINE(865, en); + poll &= ((en >> 4) | 0x03FFFFF0); + poll &= 0xFC0000FF; + + Si.poll &= ~(en >> 4); + Si.poll |= poll; + poll = Si.poll; + SITransferCommands(); + __SIRegs[0x30 / 4] = poll; + OSRestoreInterrupts(enabled); + return poll; +} + +u32 SIDisablePolling(u32 poll) { + BOOL enabled; + + ASSERTMSGLINE(908, (poll & 0x0FFFFFFF) == 0, "SIDisablePolling(): invalid chan bit(s)."); + if (poll == 0) { + return Si.poll; + } + + enabled = OSDisableInterrupts(); + poll = poll >> 24; + poll &= 0xF0; + ASSERTLINE(921, poll); + poll = Si.poll & ~poll; + __SIRegs[0x30 / 4] = poll; + Si.poll = poll; + OSRestoreInterrupts(enabled); + return poll; +} + +static BOOL SIGetResponseRaw(s32 chan) { + u32 sr; + + sr = SIGetStatus(chan); + if (sr & 0x20) { + InputBuffer[chan][0] = __SIRegs[1 + chan * 3]; + InputBuffer[chan][1] = __SIRegs[2 + chan * 3]; + InputBufferValid[chan] = TRUE; + return TRUE; + } + + return FALSE; +} + +BOOL SIGetResponse(s32 chan, void* data) { + BOOL rc; + BOOL enabled; + + ASSERTMSGLINE(971, ((chan >= 0) && (chan < 4)), "SIGetResponse(): invalid channel."); + enabled = OSDisableInterrupts(); + SIGetResponseRaw(chan); + rc = InputBufferValid[chan]; + InputBufferValid[chan] = FALSE; + + if (rc) { + ((u32*)data)[0] = InputBuffer[chan][0]; + ((u32*)data)[1] = InputBuffer[chan][1]; + } + + OSRestoreInterrupts(enabled); + return rc; +} + +static void AlarmHandler(OSAlarm* alarm, OSContext* context) { + s32 chan; + SIPacket* packet; + + chan = (s32)(alarm - Alarm); + ASSERTLINE(1002, 0 <= chan && chan < SI_MAX_CHAN); + + packet = &Packet[chan]; + if (packet->chan != -1) { + ASSERTLINE(1006, packet->fire <= __OSGetSystemTime()); + + 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; + OSTime now; + OSTime fire; + + packet = &Packet[chan]; + enabled = OSDisableInterrupts(); + + if (packet->chan != -1 || Si.chan == chan) { + OSRestoreInterrupts(enabled); + return FALSE; + } + + now = __OSGetSystemTime(); + if (delay == 0) { + fire = now; + } else { + fire = delay + XferTime[chan]; + } + + 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) { + SITypeCallback callback; + int i; + + for (i = 0; i < 4; i++) { + callback = TypeCallback[chan][i]; + + if (callback != 0) { + TypeCallback[chan][i] = 0; + (*callback)(chan, type); + } + } +} + +static void GetTypeCallback(s32 chan, u32 error, OSContext* context) { + u32 type; + u32 chanBit; + int fix; + u32 id; + + ASSERTLINE(1137, 0 <= chan && chan < SI_MAX_CHAN); + + ASSERTLINE(1139, (Type[chan] & 0xff) == SI_ERROR_BUSY); + Type[chan] &= ~SI_ERROR_BUSY; + Type[chan] |= error; + TypeTime[chan] = __OSGetSystemTime(); + + type = Type[chan]; + chanBit = 0x80000000 >> chan; + fix = __PADFixBits & chanBit; + __PADFixBits &= ~chanBit; + + if ((error & 0xF) != 0 || (type & 0x18000000) != 0x08000000 || (type & 0x80000000) == 0 || (type & 0x04000000) != 0) { + OSSetWirelessID(chan, 0); + CallTypeAndStatusCallback(chan, Type[chan]); + } else { + static u32 cmdFixDevice[4]; + + id = OSGetWirelessID(chan) << 8; + + if (fix != 0 && (id & 0x100000) != 0) { + cmdFixDevice[chan] = 0x4E000000 | (id & 0xCFFF00) | 0x100000; + Type[chan] = SI_ERROR_BUSY; + SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); + return; + } + + if ((type & 0x00100000) != 0) { + if ((id & 0xCFFF00) != (type & 0xCFFF00)) { + if ((id & 0x100000) == 0) { + id = type & 0xCFFF00; + id |= 0x100000; + OSSetWirelessID(chan, id >> 8); + } + + cmdFixDevice[chan] = 0x4E000000 | id; + Type[chan] = SI_ERROR_BUSY; + SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); + return; + } + } else { + if ((type & 0x40000000) != 0) { + id = type & 0xCFFF00; + id |= 0x100000; + OSSetWirelessID(chan, id >> 8); + + cmdFixDevice[chan] = 0x4E000000 | id; + Type[chan] = SI_ERROR_BUSY; + SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); + return; + } + + OSSetWirelessID(chan, 0); + } + + CallTypeAndStatusCallback(chan, Type[chan]); + } +} + +u32 SIGetType(s32 chan) { + static u32 cmdTypeAndStatus; + BOOL enabled; + u32 type; + OSTime diff; + + enabled = OSDisableInterrupts(); + ASSERTLINE(1243, 0 <= chan && chan < SI_MAX_CHAN); + type = Type[chan]; + diff = __OSGetSystemTime() - TypeTime[chan]; + if ((Si.poll & (0x80 >> chan)) != 0) { + if (type != 8) { + TypeTime[chan] = __OSGetSystemTime(); + OSRestoreInterrupts(enabled); + return type; + } + + type = Type[chan] = SI_ERROR_BUSY; + } else { + if (diff <= OSMillisecondsToTicks(50) && type != 8) { + OSRestoreInterrupts(enabled); + return type; + } + + if (diff <= OSMillisecondsToTicks(75)) { + Type[chan] = SI_ERROR_BUSY; + } else { + type = Type[chan] = SI_ERROR_BUSY; + } + } + + TypeTime[chan] = __OSGetSystemTime(); + SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, &GetTypeCallback, OSMicrosecondsToTicks(65)); + OSRestoreInterrupts(enabled); + return type; +} + +u32 SIGetTypeAsync(s32 chan, SITypeCallback callback) { + BOOL enabled; + u32 type; + int i; + + enabled = OSDisableInterrupts(); + type = SIGetType(chan); + + if ((Type[chan] & SI_ERROR_BUSY) != 0) { + for (i = 0; i < SI_MAX_TYPE; i++) { + if (TypeCallback[chan][i] == callback) { + break; + } + + if (TypeCallback[chan][i] == 0) { + TypeCallback[chan][i] = callback; + break; + } + } + + ASSERTLINE(1324, i < SI_MAX_TYPE); + } else { + (*callback)(chan, type); + } + + OSRestoreInterrupts(enabled); + return type; +} + +u32 SIDecodeType(u32 type) { + u32 error; + + error = type & 0xFF; + type &= ~0xFF; + + if (error & SI_ERROR_NO_RESPONSE) { + return SI_ERROR_NO_RESPONSE; + } + + if (error & (SI_ERROR_UNKNOWN | SI_ERROR_COLLISION | SI_ERROR_OVER_RUN | SI_ERROR_UNDER_RUN)) { + return SI_ERROR_UNKNOWN; + } + + if (error != 0) { + ASSERTLINE(1371, error == SI_ERROR_BUSY); + return SI_ERROR_BUSY; + } + + if ((type & SI_TYPE_MASK) == SI_TYPE_N64) { + switch (type & 0xFFFF0000) { + case SI_N64_MIC: + case SI_N64_KEYBOARD: + case SI_GBA: + case SI_N64_MOUSE: + case SI_N64_CONTROLLER: + return type & 0xFFFF0000; + default: + return SI_ERROR_UNKNOWN; + } + } + + if ((type & SI_TYPE_MASK) != SI_TYPE_DOLPHIN) { + return SI_ERROR_UNKNOWN; + } + + switch (type & 0xFFFF0000) { + case SI_GC_STEERING: + case SI_GC_CONTROLLER: + return type & 0xFFFF0000; + } + + if ((type & 0xFFE00000) == SI_GC_KEYBOARD) { + return SI_GC_KEYBOARD; + } + + if ((type & SI_GC_WIRELESS) != 0 && (type & SI_WIRELESS_IR) == 0) { + if ((type & SI_GC_WAVEBIRD) == SI_GC_WAVEBIRD) { + return SI_GC_WAVEBIRD; + } + + if ((type & SI_WIRELESS_STATE) == 0) { + return SI_GC_RECEIVER; + } + } + + if ((type & SI_GC_CONTROLLER) == SI_GC_CONTROLLER) { + return SI_GC_CONTROLLER; + } + + return SI_ERROR_UNKNOWN; +} + +u32 SIProbe(s32 chan) { + return SIDecodeType(SIGetType(chan)); +} + +char* SIGetTypeString(u32 type) { + switch (SIDecodeType(type)) { + case SI_ERROR_NO_RESPONSE: + return "No response"; + case SI_ERROR_BUSY: + return "Busy"; + case SI_N64_CONTROLLER: + return "N64 controller"; + case SI_N64_MIC: + 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"; + case SI_ERROR_UNKNOWN: + default: + return "Unknown"; + } +} diff --git a/src/dolphin/si/SISamplingRate.c b/src/dolphin/si/SISamplingRate.c new file mode 100644 index 0000000..b1a6f60 --- /dev/null +++ b/src/dolphin/si/SISamplingRate.c @@ -0,0 +1,125 @@ +#include +#include + +#include "__os.h" + +#define LATENCY 8 + +static u32 SamplingRate = 0; + +typedef struct XY { + u16 line; + u8 count; +} XY; + +static XY XYNTSC[12] = { + {0x00F6, 0x02}, + {0x000E, 0x13}, + {0x001E, 0x09}, + {0x002C, 0x06}, + {0x0034, 0x05}, + {0x0041, 0x04}, + {0x0057, 0x03}, + {0x0057, 0x03}, + {0x0057, 0x03}, + {0x0083, 0x02}, + {0x0083, 0x02}, + {0x0083, 0x02}, +}; + +static XY XYPAL[12] = { + {0x0128, 0x02}, + {0x000F, 0x15}, + {0x001D, 0x0B}, + {0x002D, 0x07}, + {0x0034, 0x06}, + {0x003F, 0x05}, + {0x004E, 0x04}, + {0x0068, 0x03}, + {0x0068, 0x03}, + {0x0068, 0x03}, + {0x0068, 0x03}, + {0x009C, 0x02}, +}; + +void SISetSamplingRate(u32 msec) { + XY* xy; + BOOL progressive; + BOOL enabled; + + ASSERTMSGLINE(377, 0 <= msec && msec <= 11, "SISetSamplingRate(): out of rage (0 <= msec <= 11)"); + if (msec > 11) { + msec = 11; + } + enabled = OSDisableInterrupts(); + SamplingRate = msec; + + switch (VIGetTvFormat()) { + 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; + } + + progressive = __VIRegs[VI_CLOCK_SEL] & 1; + SISetXY((progressive ? 2 : 1) * xy[msec].line, xy[msec].count); + OSRestoreInterrupts(enabled); +} + +void SIRefreshSamplingRate(void) { + SISetSamplingRate(SamplingRate); +} + +#if DEBUG +void __SITestSamplingRate(u32 tvmode) { + u32 msec; + u32 line; + u32 count; + XY* xy; + + switch (tvmode) { + case VI_NTSC: + case VI_MPAL: + xy = XYNTSC; + for (msec = 0; msec <= 11; msec++) { + line = xy[msec].line; + count = xy[msec].count; + OSReport("%2d[msec]: count %3d, line %3d, last %3d, diff0 %2d.%03d, diff1 %2d.%03d\n", + msec, count, line, line * (count - 1) + LATENCY, (line * 636) / 10000, (line * 636) % 10000, + ((263 - line * (count - 1)) * 636) / 10000, ((263 - line * (count - 1)) * 636) % 10000); + ASSERTLINE(446, line * (count - 1) + LATENCY < 263); + + if (msec != 0) { + ASSERTLINE(449, 636 * line < msec * 10000); + ASSERTLINE(450, 636 * (263 - line * (count - 1)) < msec * 10000); + } + } + break; + case VI_PAL: + xy = XYPAL; + for (msec = 0; msec <= 11; msec++) { + line = xy[msec].line; + count = xy[msec].count; + OSReport("%2d[msec]: count %3d, line %3d, last %3d, diff0 %2d.%03d, diff1 %2d.%03d\n", + msec, count, line, line * (count - 1) + LATENCY, (line * 640) / 10000, (line * 640) % 10000, + ((313 - line * (count - 1)) * 640) / 10000, ((313 - line * (count - 1)) * 640) % 10000); + ASSERTLINE(470, line * (count - 1) + LATENCY < 313); + + if (msec != 0) { + ASSERTLINE(473, 640 * line < msec * 10000); + ASSERTLINE(474, 640 * (313 - line * (count - 1)) < msec * 10000); + } + } + break; + } +} +#endif diff --git a/src/dolphin/si/SISteering.c b/src/dolphin/si/SISteering.c new file mode 100644 index 0000000..c0d6c66 --- /dev/null +++ b/src/dolphin/si/SISteering.c @@ -0,0 +1,120 @@ +#include +#include + +#include "__si.h" + +// prototypes +static void DefaultCallback(s32, s32); +static s32 SISteeringBegin(SISteeringControl* sc, SISteeringCallback callback); +static void ResetProc(s32 chan); +static int OnReset(BOOL final); + +SISteeringControl __SISteering[4]; +BOOL __SIResetSteering; + +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127}; + +void SIInitSteering(void) { + static BOOL initialized; + SISteeringControl* sc; + s32 chan; + + if (!initialized) { + initialized = TRUE; + + for (chan = 0; chan < 4; chan++) { + sc = &__SISteering[chan]; + sc->ret = 0; + OSInitThreadQueue(&sc->threadQueue); + } + + SIRefreshSamplingRate(); + __SIResetSteering = 0; + OSRegisterResetFunction(&ResetFunctionInfo); + } +} + +static void DefaultCallback(s32, s32) {} + +static s32 SISteeringBegin(SISteeringControl* sc, SISteeringCallback callback) { + BOOL enabled; + s32 ret; + + callback = callback != 0 ? callback : DefaultCallback; + + enabled = OSDisableInterrupts(); + if (sc->callback) { + ret = -2; + } else { + sc->callback = callback; + ret = 0; + } + + OSRestoreInterrupts(enabled); + return ret; +} + +static void ResetProc(s32 chan) { + SISteeringControl* sc = &__SISteering[chan]; + + if (sc->ret == 0 && __SIResetSteering == 0) { + __SISteeringEnable(chan); + } +} + +s32 SIResetSteeringAsync(s32 chan, SISteeringCallback callback) { + SISteeringControl* sc; + s32 ret; + + sc = &__SISteering[chan]; + ret = SISteeringBegin(sc, callback); + if (ret != 0) { + return ret; + } + + sc->output[0] = 0xFF; + return __SISteeringTransfer(chan, 1, 3, ResetProc); +} + +s32 SIResetSteering(s32 chan) { + SISteeringControl* sc; + s32 ret; + +#ifndef DEBUG + u32 padding; +#endif + + sc = &__SISteering[chan]; + ret = SIResetSteeringAsync(chan, __SISteeringSyncCallback); + if (ret != 0) { + return ret; + } + + return __SISteeringSync(chan); +} + +static int OnReset(BOOL final) { + static s32 count; + s32 chan; + + if (!__SIResetSteering) { + __SIResetSteering = TRUE; + + for (chan = 0; chan < 4; chan++) { + if ((0x80000000 >> chan) & __SISteeringEnableBits) { + SIControlSteering(chan, 0x400, 0); + } + } + + count = VIGetRetraceCount(); + } + + if ((s32)VIGetRetraceCount() - count > 2) { + while (__SISteeringEnableBits != 0) { + __SISteeringDisable(__cntlzw(__SISteeringEnableBits)); + } + return 1; + } + + return 0; +} diff --git a/src/dolphin/si/SISteeringAuto.c b/src/dolphin/si/SISteeringAuto.c new file mode 100644 index 0000000..b8e23e9 --- /dev/null +++ b/src/dolphin/si/SISteeringAuto.c @@ -0,0 +1,130 @@ +#include +#include + +static void (*SamplingCallback)(); +u32 __SISteeringEnableBits; + +void __SISteeringEnable(s32 chan) { + u32 cmd; + u32 chanBit; + u32 data[2]; + + chanBit = 0x80000000 >> chan; + if (!(__SISteeringEnableBits & chanBit)) { + __SISteeringEnableBits |= chanBit; + SIGetResponse(chan, &data); + + cmd = 0x300680; + SISetCommand(chan, cmd); + SIEnablePolling(__SISteeringEnableBits); + } +} + +void __SISteeringDisable(s32 chan) { + u32 chanBit; + + chanBit = 0x80000000 >> chan; + SIDisablePolling(chanBit); + __SISteeringEnableBits &= ~chanBit; +} + +s32 SIReadSteering(s32 chan, SISteeringStatus* status) { + BOOL enabled; + SISteeringControl* sc; + u32 data[2]; + u32 chanBit; + u32 sr; + s32 ret; + + enabled = OSDisableInterrupts(); + sc = &__SISteering[chan]; + chanBit = 0x80000000 >> chan; + + if (SIIsChanBusy(chan)) { + sc->ret = -2; + } else if (!(__SISteeringEnableBits & chanBit)) { + sc->ret = -1; + } else { + sr = SIGetStatus(chan); + if (sr & 8) { + SIGetResponse(chan, &data); + __SISteeringDisable(chan); + sc->ret = -1; + } else if ((SIGetResponse(chan, &data) == 0) || (data[0] & 0x80000000)) { + sc->ret = -3; + } else { + sc->ret = 0; + if (status != 0) { + status->button = data[0] >> 0x10; + status->misc = data[0] >> 8; + status->steering = (data[0] & 0xFF) - 0x80; + status->gas = data[1] >> 0x18; + status->brake = data[1] >> 0x10; + status->left = data[1] >> 8; + status->right = data[1]; + } + } + } + + if (status != 0) { + status->err = sc->ret; + } + + ret = sc->ret; + OSRestoreInterrupts(enabled); + return ret; +} + +static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) { + OSContext exceptionContext; + + if (SamplingCallback != 0) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + SamplingCallback(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +void (* SISetSteeringSamplingCallback(void (*callback)()))() { + void (*prev)() = SamplingCallback; + SamplingCallback = callback; + + if (callback != 0) { + SIRegisterPollingHandler(SamplingHandler); + } else { + SIUnregisterPollingHandler(SamplingHandler); + } + + return prev; +} + +void SIControlSteering(s32 chan, u32 control, s32 level) { + BOOL enabled; + u32 chanBit; + u32 command; + + control &= 0x600; + + if (level <= -0x80) { + command = 0; + } else if (level >= 0x80) { + command = 0x100; + } else { + command = level + 0x80; + } + + command |= control; + command &= 0x7FF; + + enabled = OSDisableInterrupts(); + chanBit = 0x80000000 >> chan; + if (__SISteeringEnableBits & chanBit) { + command |= 0x300000; + SISetCommand(chan, command); + SITransferCommands(); + } + + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/si/SISteeringXfer.c b/src/dolphin/si/SISteeringXfer.c new file mode 100644 index 0000000..3bb8abd --- /dev/null +++ b/src/dolphin/si/SISteeringXfer.c @@ -0,0 +1,118 @@ +#include +#include + +#include "__os.h" + +static void __SISteeringHandler(s32 chan, u32 error, OSContext* context) { + SISteeringControl* sc; + void (*proc)(s32); + SISteeringCallback callback; + OSContext exceptionContext; + + sc = &__SISteering[chan]; + if (!__SIResetSteering) { + if (error & 8) { + sc->ret = -1; + } else if (error & 7) { + sc->ret = -3; + } else { + sc->ret = 0; + } + + if (sc->proc != 0) { + proc = sc->proc; + sc->proc = NULL; + proc(chan); + } + + if (sc->callback != 0) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + callback = sc->callback; + sc->callback = NULL; + callback(chan, sc->ret); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } + } +} + +void __SISteeringSyncCallback(s32 chan) { + SISteeringControl* sc; + + sc = &__SISteering[chan]; + OSWakeupThread(&sc->threadQueue); +} + +s32 __SISteeringSync(s32 chan) { + SISteeringControl* sc; + s32 ret; + BOOL enabled; + + sc = &__SISteering[chan]; + enabled = OSDisableInterrupts(); + + while (sc->callback != 0) { + OSSleepThread(&sc->threadQueue); + } + + ret = sc->ret; + OSRestoreInterrupts(enabled); + return ret; +} + +static void TypeAndStatusCallback(s32 chan, u32 type) { + SISteeringControl* sc; + void (*proc)(s32); + SISteeringCallback callback; + OSContext exceptionContext; + OSContext* context; + + sc = &__SISteering[chan]; + if (!__SIResetSteering) { + ASSERTLINE(127, !(type & SI_ERROR_BUSY)); + + if ((u32)((type & 0xFFFF0000) + 0xF8000000) == 0) { + if (SITransfer(chan, sc, sc->outputBytes, sc->input, sc->inputBytes, __SISteeringHandler, 0)) { + return; + } + sc->ret = -2; + } else { + sc->ret = -1; + } + + if (sc->proc != 0) { + proc = sc->proc; + sc->proc = NULL; + proc(chan); + } + + if (sc->callback != 0) { + context = OSGetCurrentContext(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + callback = sc->callback; + sc->callback = NULL; + callback(chan, sc->ret); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + __OSReschedule(); + } + } +} + +s32 __SISteeringTransfer(s32 chan, u32 outputBytes, u32 inputBytes, void (*proc)(s32)) { + BOOL enabled; + SISteeringControl* sc; + + sc = &__SISteering[chan]; + enabled = OSDisableInterrupts(); + + sc->proc = proc; + sc->outputBytes = outputBytes; + sc->inputBytes = inputBytes; + SIGetTypeAsync(chan, &TypeAndStatusCallback); + + OSRestoreInterrupts(enabled); + return 0; +} diff --git a/src/dolphin/si/__si.h b/src/dolphin/si/__si.h new file mode 100644 index 0000000..d609f90 --- /dev/null +++ b/src/dolphin/si/__si.h @@ -0,0 +1,21 @@ +#ifndef _DOLPHIN_SI_INTERNAL_H_ +#define _DOLPHIN_SI_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __SISteeringEnable(s32 chan); +s32 __SISteeringTransfer(s32 chan, u32 outputBytes, u32 inputBytes, void (*proc)(s32)); +void __SISteeringSyncCallback(s32 chan, s32); +s32 __SISteeringSync(s32 chan); +void __SISteeringDisable(s32 chan); +void __SITestSamplingRate(u32 tvmode); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/sp/sp.c b/src/dolphin/sp/sp.c new file mode 100644 index 0000000..b934423 --- /dev/null +++ b/src/dolphin/sp/sp.c @@ -0,0 +1,404 @@ +#include +#include + +void SPInitSoundTable(SPSoundTable* table, u32 aramBase, u32 zeroBase) { + int i; + SPSoundEntry* sound; + SPADPCM* adpcm; + u32 aramBase4, aramBase8, aramBase16; + u32 zeroBase4, zeroBase8, zeroBase16; + + ASSERTLINE(34, table); + + aramBase4 = aramBase << 1; + zeroBase4 = (zeroBase << 1) + 2; + aramBase8 = aramBase; + + zeroBase8 = zeroBase; + aramBase16 = aramBase >> 1; + zeroBase16 = zeroBase >> 1; + + sound = &table->sound[0]; + adpcm = (SPADPCM*)&table->sound[table->entries]; + + for (i = 0; i < table->entries; i++) { + switch (sound->type) { + case 0: + sound->loopAddr = zeroBase4; + sound->loopEndAddr = 0; + sound->endAddr = aramBase4 + sound->endAddr; + sound->currentAddr = aramBase4 + sound->currentAddr; + sound->adpcm = adpcm; + adpcm++; + break; + case 1: + sound->loopAddr = aramBase4 + sound->loopAddr; + sound->loopEndAddr = aramBase4 + sound->loopEndAddr; + sound->endAddr = aramBase4 + sound->endAddr; + sound->currentAddr = aramBase4 + sound->currentAddr; + sound->adpcm = adpcm; + adpcm++; + break; + case 2: + sound->loopAddr = zeroBase16; + sound->loopEndAddr = 0; + sound->endAddr = aramBase16 + sound->endAddr; + sound->currentAddr = aramBase16 + sound->currentAddr; + break; + case 3: + sound->loopAddr = aramBase16 + sound->loopAddr; + sound->loopEndAddr = aramBase16 + sound->loopEndAddr; + sound->endAddr = aramBase16 + sound->endAddr; + sound->currentAddr = aramBase16 + sound->currentAddr; + break; + case 4: + sound->loopAddr = zeroBase8; + sound->loopEndAddr = 0; + sound->endAddr = aramBase8 + sound->endAddr; + sound->currentAddr = aramBase8 + sound->currentAddr; + break; + case 5: + sound->loopAddr = aramBase8 + sound->loopAddr; + sound->loopEndAddr = aramBase8 + sound->loopEndAddr; + sound->endAddr = aramBase8 + sound->endAddr; + sound->currentAddr = aramBase8 + sound->currentAddr; + break; + } + sound++; + } +} + +SPSoundEntry* SPGetSoundEntry(SPSoundTable* table, u32 index) { + ASSERTLINE(123, table); + + if (table->entries > index) { + return &table->sound[index]; + } + + return NULL; +} + +void SPPrepareSound(SPSoundEntry* sound, AXVPB* axvpb, u32 sampleRate) { + BOOL old; + u32 srcBits; + u32 loopAddr, endAddr, currentAddr; + u16* p; + u16* p1; + + ASSERTLINE(140, sound); + ASSERTLINE(141, axvpb); + + srcBits = 0x10000 * ((f32)sampleRate / 32000); + + switch (sound->type) { + case 0: + loopAddr = sound->loopAddr; + endAddr = sound->endAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + p1 = (u16*)sound->adpcm; + + old = OSDisableInterrupts(); + + *p++ = 0; + *p++ = 0; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + case 1: + loopAddr = sound->loopAddr; + endAddr = sound->loopEndAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + p1 = (u16*)sound->adpcm; + + old = OSDisableInterrupts(); + + *p++ = 1; + *p++ = 0; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + + axvpb->sync |= 0x161000; + OSRestoreInterrupts(old); + break; + case 2: + loopAddr = sound->loopAddr; + endAddr = sound->endAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + + old = OSDisableInterrupts(); + + *p++ = 0; + *p++ = 10; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0x800; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + case 3: + loopAddr = sound->loopAddr; + endAddr = sound->loopEndAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + + old = OSDisableInterrupts(); + + *p++ = 1; + *p++ = 10; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0x800; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + case 4: + loopAddr = sound->loopAddr; + endAddr = sound->endAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + + old = OSDisableInterrupts(); + + *p++ = 0; + *p++ = 0x19; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0x100; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + case 5: + loopAddr = sound->loopAddr; + endAddr = sound->loopEndAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + + old = OSDisableInterrupts(); + + *p++ = 1; + *p++ = 0x19; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0x100; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + } +} + +void SPPrepareEnd(SPSoundEntry* sound, AXVPB* axvpb) { + BOOL old; + + ASSERTLINE(497, sound); + ASSERTLINE(498, axvpb); + + old = OSDisableInterrupts(); + + axvpb->pb.addr.loopFlag = 0; + axvpb->pb.addr.endAddressHi = sound->endAddr >> 0x10; + axvpb->pb.addr.endAddressLo = sound->endAddr & 0xFFFF; + + axvpb->sync |= 0xA000; + OSRestoreInterrupts(old); +} diff --git a/src/dolphin/stub.c b/src/dolphin/stub.c new file mode 100644 index 0000000..63edf6b --- /dev/null +++ b/src/dolphin/stub.c @@ -0,0 +1,80 @@ +/* symbols just to satisfy the linker*/ +#define TEXT_STUB(name) void name(void) {} +#define DATA_STUB(name) int name; + +TEXT_STUB(_start) + +TEXT_STUB(__ArenaHi) +TEXT_STUB(__ArenaLo) +TEXT_STUB(__cvt_fp2unsigned) +TEXT_STUB(__div2i) +TEXT_STUB(__init_registers) +TEXT_STUB(__mod2i) +TEXT_STUB(__shl2i) +TEXT_STUB(__shr2i) +TEXT_STUB(__shr2u) +TEXT_STUB(_ctors) +TEXT_STUB(_dtors) +TEXT_STUB(_bss_init_info) +TEXT_STUB(_restfpr_18) +TEXT_STUB(_restfpr_19) +TEXT_STUB(_restfpr_20) +TEXT_STUB(_restfpr_21) +TEXT_STUB(_restfpr_22) +TEXT_STUB(_restfpr_23) +TEXT_STUB(_restfpr_24) +TEXT_STUB(_restfpr_25) +TEXT_STUB(_restfpr_26) +TEXT_STUB(_restfpr_27) +TEXT_STUB(_restfpr_28) +TEXT_STUB(_restfpr_29) +TEXT_STUB(_restfpr_30) +TEXT_STUB(_rom_copy_info) +TEXT_STUB(_savefpr_18) +TEXT_STUB(_savefpr_19) +TEXT_STUB(_savefpr_20) +TEXT_STUB(_savefpr_21) +TEXT_STUB(_savefpr_22) +TEXT_STUB(_savefpr_23) +TEXT_STUB(_savefpr_24) +TEXT_STUB(_savefpr_25) +TEXT_STUB(_savefpr_26) +TEXT_STUB(_savefpr_27) +TEXT_STUB(_savefpr_28) +TEXT_STUB(_savefpr_29) +TEXT_STUB(_savefpr_30) +TEXT_STUB(_stack_addr) +TEXT_STUB(_stack_end) +TEXT_STUB(DSPAddTask) +TEXT_STUB(DSPAssertTask) +TEXT_STUB(DSPCheckInit) +TEXT_STUB(DSPCheckMailToDSP) +TEXT_STUB(DSPGetDMAStatus) +TEXT_STUB(DSPHalt) +TEXT_STUB(DSPInit) +TEXT_STUB(DSPReset) +TEXT_STUB(DSPSendMailToDSP) +TEXT_STUB(EnableMetroTRKInterrupts) +TEXT_STUB(InitMetroTRK) +TEXT_STUB(cosf) +TEXT_STUB(main) +TEXT_STUB(memcmp) +TEXT_STUB(memcpy) +TEXT_STUB(memmove) +TEXT_STUB(memset) +TEXT_STUB(powf) +TEXT_STUB(rand) +TEXT_STUB(sinf) +TEXT_STUB(sprintf) +TEXT_STUB(srand) +TEXT_STUB(strchr) +TEXT_STUB(strcmp) +TEXT_STUB(strcpy) +TEXT_STUB(strlen) +TEXT_STUB(strncpy) +TEXT_STUB(tanf) +TEXT_STUB(tolower) +TEXT_STUB(vprintf) +TEXT_STUB(vsprintf) +TEXT_STUB(atan2f) +TEXT_STUB(acosf) diff --git a/src/dolphin/support/HTable.c b/src/dolphin/support/HTable.c new file mode 100644 index 0000000..6cee989 --- /dev/null +++ b/src/dolphin/support/HTable.c @@ -0,0 +1,68 @@ +#include +#include + +void DSInitHTable(DSHashTable* hTable, u16 size, DSList* listArray, DSHashFunc* hashFunc, Ptr obj, DSLinkPtr link) { + u16 i; + + hTable->table = listArray; + hTable->tableSize = size; + hTable->hash = hashFunc; + for (i = 0; i < size; i++) { + DSInitList(&listArray[i], obj, link); + } +} + +void DSInsertHTableObj(DSHashTable* hTable, Ptr obj) { + DSList* list = &hTable->table[hTable->hash(obj)]; + DSInsertListObject(list, 0, obj); +} + +void DSHTableToList(DSHashTable* hTable, DSList* list) { + DSLink* link = NULL; + u16 i = 0; + + list->Offset = hTable->table[i].Offset; + for (i = 0; i < hTable->tableSize; i++) { + DSAttachList(list, &hTable->table[i]); + } +} + +void* DSNextHTableObj(DSHashTable* hTable, Ptr obj) { + s32 currentIndex; + void* cursor; + + if (!hTable) { + return NULL; + } + + if (!obj) { + currentIndex = 0; + cursor = DSNextListObj(&hTable->table[currentIndex], NULL); + } else { + currentIndex = DSHTableIndex(hTable, obj); + if (currentIndex == -1) { + return NULL; + } + cursor = DSNextListObj(&hTable->table[currentIndex], obj); + } + + while (cursor == NULL && currentIndex < hTable->tableSize - 1) { + currentIndex++; + cursor = DSNextListObj(&hTable->table[currentIndex], NULL); + } + return cursor; +} + +s32 DSHTableIndex(DSHashTable* hTable, Ptr obj) { + if (!hTable || !obj) { + return -1; + } + return hTable->hash(obj); +} + +void* DSHTableHead(DSHashTable* hTable, s32 index) { + if (index < 0 || index >= hTable->tableSize) { + return NULL; + } + return DSNextListObj(&hTable->table[index], NULL); +} diff --git a/src/dolphin/support/List.c b/src/dolphin/support/List.c new file mode 100644 index 0000000..34b6bc8 --- /dev/null +++ b/src/dolphin/support/List.c @@ -0,0 +1,92 @@ +#include + +void DSInitList(DSListPtr list, Ptr obj, DSLinkPtr link) { + list->Head = NULL; + list->Tail = NULL; + list->Offset = (Ptr)link - obj; +} + +void DSInsertListObject(DSListPtr list, Ptr cursor, Ptr obj) { + DSLinkPtr link; + DSLinkPtr linkNext; + DSLinkPtr linkPrev; + + link = (DSLinkPtr)(obj + list->Offset); + if (list->Head) { + if (!cursor) { + linkPrev = (DSLinkPtr)(list->Tail + list->Offset); + linkPrev->Next = obj; + link->Prev = list->Tail; + link->Next = NULL; + list->Tail = obj; + } else { + linkNext = (DSLinkPtr)(cursor + list->Offset); + if (cursor == list->Head) { + list->Head = obj; + link->Next = cursor; + linkNext->Prev = obj; + } else { + linkPrev = (DSLinkPtr)(linkNext->Prev + list->Offset); + link->Next = cursor; + link->Prev = linkNext->Prev; + linkNext->Prev = obj; + linkPrev->Next = obj; + } + } + } else { + list->Tail = obj; + list->Head = obj; + link->Next = link->Prev = NULL; + } +} + +void DSRemoveListObject(DSListPtr list, Ptr obj) { + DSLinkPtr link = (DSLinkPtr)(obj + list->Offset); + + if (obj) { + if (link->Prev) { + ((DSLinkPtr)(link->Prev + list->Offset))->Next = link->Next; + } else { + list->Head = link->Next; + } + + if (link->Next) { + ((DSLinkPtr)(link->Next + list->Offset))->Prev = link->Prev; + } else { + list->Tail = link->Prev; + } + + link->Prev = NULL; + link->Next = NULL; + } +} + +void DSAttachList(DSListPtr baseList, DSListPtr attachList) { + DSLinkPtr link; + DSLinkPtr linkPrev; + + if (baseList->Offset == attachList->Offset && (attachList->Head || attachList->Tail)) { + linkPrev = (DSLinkPtr)(attachList->Head + attachList->Offset); + if (baseList->Head) { + link = (DSLinkPtr)(baseList->Tail + baseList->Offset); + link->Next = attachList->Head; + linkPrev->Prev = baseList->Tail; + baseList->Tail = attachList->Tail; + return; + } + baseList->Head = attachList->Head; + baseList->Tail = attachList->Tail; + linkPrev; // needed to match + } +} + +void* DSNextListObj(DSListPtr list, Ptr obj) { + if (!list) { + return NULL; + } + if (!obj) { + return list->Head; + } + + return ((DSLinkPtr)(obj + list->Offset))->Next; +} diff --git a/src/dolphin/support/Tree.c b/src/dolphin/support/Tree.c new file mode 100644 index 0000000..34ced45 --- /dev/null +++ b/src/dolphin/support/Tree.c @@ -0,0 +1,106 @@ +#include + +void DSExtractBranch(DSTreePtr tree, Ptr obj) { + DSBranchPtr branch = (DSBranchPtr)(obj + tree->Offset); + Ptr cursor = branch->Children; + Ptr next; + + while (cursor) { + next = ((DSBranchPtr)(cursor + tree->Offset))->Next; + DSInsertBranchBelow(tree, branch->Parent, cursor); + cursor = next; + } + DSRemoveBranch(tree, obj); +} + +void DSInitTree(DSTreePtr tree, Ptr obj, DSBranchPtr branch) { + tree->Root = NULL; + tree->Offset = (Ptr)branch - obj; +} + +void DSInsertBranchBelow(DSTreePtr tree, Ptr cursor, Ptr obj) { + DSBranchPtr branch; + DSBranchPtr objBranch = (DSBranchPtr)(obj + tree->Offset); + Ptr tail = NULL; + + if (cursor) { + branch = (DSBranchPtr)(cursor + tree->Offset); + if (branch->Children) { + tail = branch->Children; + } else { + branch->Children = obj; + } + } else if (tree->Root) { + tail = tree->Root; + } else { + tree->Root = obj; + } + + if (tail) { + while (((DSBranchPtr)(tail + tree->Offset))->Next) { + tail = ((DSBranchPtr)(tail + tree->Offset))->Next; + } + ((DSBranchPtr)(tail + tree->Offset))->Next = obj; + objBranch->Prev = tail; + } else { + objBranch->Prev = NULL; + } + + objBranch->Next = NULL; + objBranch->Parent = cursor; +} + +void DSInsertBranchBeside(DSTreePtr tree, Ptr cursor, Ptr obj) { + DSBranchPtr parent; + DSBranchPtr branch; + + branch = (DSBranchPtr)(obj + tree->Offset); + if (!cursor) { + if (!tree->Root) { + tree->Root = obj; + branch->Next = NULL; + branch->Prev = NULL; + branch->Children = NULL; + branch->Parent = NULL; + return; + } + cursor = tree->Root; + } + + while (((DSBranchPtr)(cursor + tree->Offset))->Next) { + cursor = ((DSBranchPtr)(cursor + tree->Offset))->Next; + } + + parent = (DSBranchPtr)(cursor + tree->Offset); + parent->Next = obj; + branch->Prev = cursor; + branch->Next = NULL; + branch->Parent = parent->Parent; +} + +void DSRemoveBranch(DSTreePtr tree, Ptr obj) { + DSBranchPtr branch; + DSBranchPtr parent; + + branch = (DSBranchPtr)(obj + tree->Offset); + if (branch->Parent) { + parent = (DSBranchPtr)(branch->Parent + tree->Offset); + if (parent->Children == obj) { + parent->Children = branch->Next; + } + } else if (tree->Root == obj) { + tree->Root = branch->Next; + } + + if (branch->Prev) { + ((DSBranchPtr)(branch->Prev + tree->Offset))->Next = branch->Next; + } + + if (branch->Next) { + ((DSBranchPtr)(branch->Next + tree->Offset))->Prev = branch->Prev; + } + + branch->Prev = NULL; + branch->Next = NULL; + branch->Parent = NULL; +} diff --git a/src/dolphin/support/string.c b/src/dolphin/support/string.c new file mode 100644 index 0000000..f55ec79 --- /dev/null +++ b/src/dolphin/support/string.c @@ -0,0 +1,74 @@ +#include + +u8 Strcat(char* str1, char* str2, char* dst) { + char* srcCursor = str1; + char* dstCursor = dst;; + + if (!dst) { + return 0; + } + if (!str1) { + return 0; + } + if (!str2) { + return 0; + } + + while ((s8)*srcCursor != 0) { + *dstCursor = *srcCursor; + dstCursor++; + srcCursor++; + } + + srcCursor = str2; + while ((s8)*srcCursor != 0) { + *dstCursor = *srcCursor; + dstCursor++; + srcCursor++; + } + + *dstCursor = 0; + return 1; +} + +void Strcpy(char* dst, char* src) { + do { + *dst = *src; + dst++; + src++; + } while ((s8)*src != 0); +} + +s8 Strcmp(char* str1, char* str2) { + char* cursor1 = str1; + char* cursor2 = str2; + while (1) { + if ((s8)*cursor1 < (s8)*cursor2) { + return 1; + } + if ((s8)*cursor1 > (s8)*cursor2) { + return -1; + } + cursor1++; + cursor2++; + if ((s8)*cursor1 == 0 || (s8)*cursor2 == 0) { + return 0; + } + } +} + +u32 Strlen(char* str) { + char* cursor = str; + u32 counter = 0; + + if (!str) { + return 0; + } + + while ((s8)*cursor != 0) { + cursor++; + counter++; + } + + return counter; +} diff --git a/src/dolphin/syn/__syn.h b/src/dolphin/syn/__syn.h new file mode 100644 index 0000000..ce2e970 --- /dev/null +++ b/src/dolphin/syn/__syn.h @@ -0,0 +1,67 @@ +#ifndef _DOLPHIN_SYN_INTERNAL_H_ +#define _DOLPHIN_SYN_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// syn +extern SYNSYNTH* __SYNSynthList; + +// synctrl +extern f32 __SYNn128[128]; + +void __SYNClearAllNotes(SYNSYNTH* synth); +void __SYNSetController(SYNSYNTH* synth, u8 midiChannel, u8 function, u8 value); +void __SYNResetController0(SYNSYNTH* synth, u8 midiChannel); +void __SYNResetController(SYNSYNTH* synth, u8 midiChannel); +void __SYNResetAllControllers(SYNSYNTH* synth); +void __SYNRunInputBufferEvents(SYNSYNTH* synth); + +// synenv +s32 __SYNGetEnvelopeTime(s32 scale, s32 mod, u8 key); +void __SYNSetupVolumeEnvelope(SYNVOICE* voice); +void __SYNSetupPitchEnvelope(SYNVOICE* voice); +void __SYNRunVolumeEnvelope(SYNVOICE* voice); +void __SYNRunPitchEnvelope(SYNVOICE* voice); + +// synlfo +void __SYNSetupLfo(SYNVOICE* voice); +void __SYNRunLfo(SYNVOICE* voice); + +// synmix +extern s32 __SYNVolumeAttenuation[128]; +extern s32 __SYNAttackAttnTable[100]; + +void __SYNSetupVolume(SYNVOICE* voice); +void __SYNSetupPan(SYNVOICE* voice); +s32 __SYNGetVoiceInput(SYNVOICE* voice); +s32 __SYNGetVoiceFader(SYNVOICE* voice); +void __SYNUpdateMix(SYNVOICE* voice); + +// synpitch +f32 __SYNGetRelativePitch(SYNVOICE* voice); +void __SYNSetupPitch(SYNVOICE* voice); +void __SYNSetupSrc(SYNVOICE* voice); +void __SYNUpdateSrc(SYNVOICE* voice); + +// synsample +void __SYNSetupSample(SYNVOICE* voice); + +// synvoice +extern SYNVOICE __SYNVoice[64]; + +void __SYNClearVoiceReferences(void* p); +void __SYNSetVoiceToRelease(SYNVOICE* voice, u32 priority); +void __SYNServiceVoice(int i); + +// synwt +int __SYNGetWavetableData(SYNVOICE* voice); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_SYN_INTERNAL_H_ diff --git a/src/dolphin/syn/syn.c b/src/dolphin/syn/syn.c new file mode 100644 index 0000000..17bdebc --- /dev/null +++ b/src/dolphin/syn/syn.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +SYNSYNTH* __SYNSynthList; + +// prototypes +static void __SYNAddSynthToList(SYNSYNTH* synth); +static void __SYNRemoveSynthFromList(SYNSYNTH* synth); + +static void __SYNAddSynthToList(SYNSYNTH* synth) { + BOOL old = OSDisableInterrupts(); + + if (__SYNSynthList) { + synth->next = __SYNSynthList; + } else { + synth->next = NULL; + } + __SYNSynthList = synth; + OSRestoreInterrupts(old); +} + +static void __SYNRemoveSynthFromList(SYNSYNTH* synth) { + SYNSYNTH* tempHead; + SYNSYNTH* tempTail; + SYNSYNTH* tempSynth; + BOOL old; + + old = OSDisableInterrupts(); + tempHead = NULL; + tempTail = NULL; + + for (tempSynth = __SYNSynthList; tempSynth; tempSynth = tempSynth->next) { + if (tempSynth != synth) { + if (tempHead) { + tempTail->next = tempSynth; + tempTail = tempSynth; + } else { + tempHead = tempTail = tempSynth; + } + } + } + + if (tempTail) { + tempTail->next = NULL; + } + + __SYNSynthList = tempHead; + OSRestoreInterrupts(old); +} + +void SYNInit(void) { + int i; + + for (i = 0; i < 64; i++) { + __SYNVoice[i].synth = 0; + } + __SYNSynthList = NULL; +} + +void SYNQuit(void) { + SYNInit(); +} + +void SYNRunAudioFrame(void) { + int i; + SYNSYNTH* synth; + + for (i = 0; i < 64; i++) { + __SYNServiceVoice(i); + } + + for (synth = __SYNSynthList; synth; synth = synth->next) { + __SYNRunInputBufferEvents(synth); + } +} + +void SYNInitSynth(SYNSYNTH* synth, void* wavetable, u32 aramBase, u32 zeroBase, u32 priorityVoiceAlloc, u32 priorityNoteOn, u32 priorityNoteRelease) { + u32* p; + u32 midiChannel; + u32 noteNumber; + + ASSERTLINE(158, synth); + ASSERTLINE(159, wavetable); + ASSERTLINE(160, aramBase); + + p = wavetable; + synth->percussiveInst = (void*)((u32)wavetable + *(p)); p += 1; + synth->melodicInst = (void*)((u32)wavetable + *(p)); p += 1; + synth->region = (void*)((u32)wavetable + *(p)); p += 1; + synth->art = (void*)((u32)wavetable + *(p)); p += 1; + synth->sample = (void*)((u32)wavetable + *(p)); p += 1; + synth->adpcm = (void*)((u32)wavetable + *(p)); p += 1; + synth->aramBaseWord = (aramBase >> 1); + synth->aramBaseByte = aramBase; + synth->aramBaseNibble = (aramBase << 1); + synth->zeroBaseWord = zeroBase >> 1; + synth->zeroBaseByte = zeroBase; + synth->zeroBaseNibble = (zeroBase << 1); + synth->priorityVoiceAlloc = priorityVoiceAlloc; + synth->priorityNoteOn = priorityNoteOn; + synth->priorityNoteRelease = priorityNoteRelease; + synth->masterVolume = 0; + __SYNResetAllControllers(synth); + synth->inputPosition = &synth->input[0][0]; + synth->inputCounter = 0; + synth->notes = 0; + + for (midiChannel = 0; midiChannel < 16; midiChannel++) { + for (noteNumber = 0; noteNumber < 16; noteNumber++) { + synth->keyGroup[midiChannel][noteNumber] = 0; + } + } + + for (midiChannel = 0; midiChannel < 16; midiChannel++) { + for (noteNumber = 0; noteNumber < 128; noteNumber++) { + synth->voice[midiChannel][noteNumber] = 0; + } + } + + __SYNAddSynthToList(synth); +} + +void SYNQuitSynth(SYNSYNTH* synth) { + int i; + BOOL old; + SYNVOICE* voice; + + old = OSDisableInterrupts(); + if (synth->notes) { + for (i = 0; i < 64; i++) { + voice = &__SYNVoice[i]; + if (voice->synth == synth) { + MIXReleaseChannel(voice->axvpb); + AXFreeVoice(voice->axvpb); + voice->synth = 0; + } + } + } + + __SYNRemoveSynthFromList(synth); + OSRestoreInterrupts(old); +} + +void SYNMidiInput(SYNSYNTH* synth, u8* input) { + u8* src; + + ASSERTLINE(244, synth); + ASSERTLINE(245, input); + + src = input; + *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; + *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; + *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; + synth->inputCounter++; + + if (synth->inputCounter >= SYN_INPUT_BUFFER_SIZE) { + ASSERTMSGLINE(258, FALSE, "synth input buffer exceeded, increase SYN_INPUT_BUFFER_SIZE"); + } +} + +void SYNSetMasterVolume(SYNSYNTH* synth, s32 dB) { + ASSERTLINE(267, synth); + synth->masterVolume = (dB << 0x10); +} + +s32 SYNGetMasterVolume(SYNSYNTH* synth) { + ASSERTLINE(278, synth); + return synth->masterVolume >> 0x10; +} + +u32 SYNGetActiveNotes(SYNSYNTH* synth) { + ASSERTLINE(289, synth); + return synth->notes; +} diff --git a/src/dolphin/syn/synctrl.c b/src/dolphin/syn/synctrl.c new file mode 100644 index 0000000..cfae4ec --- /dev/null +++ b/src/dolphin/syn/synctrl.c @@ -0,0 +1,510 @@ +#include +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +f32 __SYNn128[128] = { + 0.000000f, + 0.007813f, + 0.015625f, + 0.023438f, + 0.031250f, + 0.039063f, + 0.046875f, + 0.054688f, + 0.062500f, + 0.070313f, + 0.078125f, + 0.085938f, + 0.093750f, + 0.101563f, + 0.109375f, + 0.117188f, + 0.125000f, + 0.132813f, + 0.140625f, + 0.148438f, + 0.156250f, + 0.164063f, + 0.171875f, + 0.179688f, + 0.187500f, + 0.195313f, + 0.203125f, + 0.210938f, + 0.218750f, + 0.226563f, + 0.234375f, + 0.242188f, + 0.250000f, + 0.257813f, + 0.265625f, + 0.273438f, + 0.281250f, + 0.289063f, + 0.296875f, + 0.304688f, + 0.312500f, + 0.320313f, + 0.328125f, + 0.335938f, + 0.343750f, + 0.351563f, + 0.359375f, + 0.367188f, + 0.375000f, + 0.382813f, + 0.390625f, + 0.398438f, + 0.406250f, + 0.414063f, + 0.421875f, + 0.429688f, + 0.437500f, + 0.445313f, + 0.453125f, + 0.460938f, + 0.468750f, + 0.476563f, + 0.484375f, + 0.492188f, + 0.500000f, + 0.507813f, + 0.515625f, + 0.523438f, + 0.531250f, + 0.539063f, + 0.546875f, + 0.554688f, + 0.562500f, + 0.570313f, + 0.578125f, + 0.585938f, + 0.593750f, + 0.601563f, + 0.609375f, + 0.617188f, + 0.625000f, + 0.632813f, + 0.640625f, + 0.648438f, + 0.656250f, + 0.664063f, + 0.671875f, + 0.679688f, + 0.687500f, + 0.695313f, + 0.703125f, + 0.710938f, + 0.718750f, + 0.726563f, + 0.734375f, + 0.742188f, + 0.750000f, + 0.757813f, + 0.765625f, + 0.773438f, + 0.781250f, + 0.789063f, + 0.796875f, + 0.804688f, + 0.812500f, + 0.820313f, + 0.828125f, + 0.835938f, + 0.843750f, + 0.851563f, + 0.859375f, + 0.867188f, + 0.875000f, + 0.882813f, + 0.890625f, + 0.898438f, + 0.906250f, + 0.914063f, + 0.921875f, + 0.929688f, + 0.937500f, + 0.945313f, + 0.953125f, + 0.960938f, + 0.968750f, + 0.976563f, + 0.984375f, + 0.992188f +}; + +// prototypes +static void __SYNSetData(SYNSYNTH* synth, u8 midiChannel); +static void __SYNSetSustainPedal(SYNSYNTH* synth, u8 midiChannel, u8 data); +static void __SYNProgramChange(SYNSYNTH* synth, u8 midiChannel, u8 program); +static void __SYNReleaseChannelNotes(SYNSYNTH* synth, u8 midiChannel); +static void __SYNNoteOff(SYNSYNTH* synth, u8 midiChannel, u8 keyNum); +static void __SYNNoteOn(SYNSYNTH* synth, u8 midiChannel, u8 keyNum, u8 keyVel); +static void __SYNPitchWheel(SYNSYNTH* synth, u8 midiChannel, u8 lsb, u8 msb); +static void __SYNMidiIn(SYNSYNTH* synth, u8* input); + +static void __SYNSetData(SYNSYNTH* synth, u8 midiChannel) { + ASSERTLINE(59, synth); + ASSERTLINE(60, midiChannel < 16); + + if (synth->rpn[midiChannel]) { + u16 param = (synth->controller[midiChannel][0x65] << 8) + synth->controller[midiChannel][0x64]; + switch(param) { + case 0: + synth->pwMaxCents[midiChannel] = (synth->controller[midiChannel][0x26] + (synth->controller[midiChannel][0x6] * 100)) << 0x10; + break; + case 1: + ASSERTMSGLINE(80, FALSE, "RPN 0001 not supported\n"); + break; + case 2: + ASSERTMSGLINE(86, FALSE, "RPN 0002 not supported\n"); + break; + case 3: + ASSERTMSGLINE(92, FALSE, "RPN 0003 not supported\n"); + break; + case 4: + ASSERTMSGLINE(98, FALSE, "RPN 0004 not supported\n"); + break; + } + } +} + +static void __SYNSetSustainPedal(SYNSYNTH* synth, u8 midiChannel, u8 data) { + int i; + SYNVOICE* voice; + + ASSERTLINE(111, synth); + ASSERTLINE(112, midiChannel < 16); + ASSERTLINE(113, data < 128); + + // check if you're below 0x80 only to check if you're below 0x40. ok then. + if (data < 64) { + for (i = 0; i < 128; i++) { + voice = synth->voice[midiChannel][i]; + if (voice && voice->hold) { + __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); + voice->synth->voice[voice->midiChannel][voice->keyNum] = 0; + } + } + } +} + +static void __SYNProgramChange(SYNSYNTH* synth, u8 midiChannel, u8 program) { + ASSERTLINE(142, synth); + ASSERTLINE(143, midiChannel < 16); + ASSERTLINE(144, program < 128); + + if (midiChannel == 9) { + synth->inst[midiChannel] = synth->percussiveInst; + } else { + synth->inst[midiChannel] = synth->melodicInst; + } + + synth->inst[midiChannel] += program; +} + +static void __SYNReleaseChannelNotes(SYNSYNTH* synth, u8 midiChannel) { + int i; + SYNVOICE* voice; + + ASSERTLINE(162, synth); + ASSERTLINE(163, midiChannel < 16); + + for (i = 0; i < 128; i++) { + voice = synth->voice[midiChannel][i]; + if (voice) { + __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); + synth->voice[midiChannel][i] = 0; + } + } +} + +void __SYNClearAllNotes(SYNSYNTH* synth) { + u8 i; + + ASSERTLINE(189, synth); + + for (i = 0; i < 16; i++) { + __SYNReleaseChannelNotes(synth, i); + } +} + +void __SYNSetController(SYNSYNTH* synth, u8 midiChannel, u8 function, u8 value) { + ASSERTLINE(201, synth); + ASSERTLINE(202, midiChannel < 16); + ASSERTLINE(203, function < 128); + ASSERTLINE(204, value < 128); + + synth->controller[midiChannel][function] = value; + switch(function) { + case 6: + __SYNSetData(synth, midiChannel); + break; + case 7: + synth->volAttn[midiChannel] = __SYNVolumeAttenuation[value]; + break; + case 11: + synth->expAttn[midiChannel] = __SYNVolumeAttenuation[value]; + break; + case 0x26: + __SYNSetData(synth, midiChannel); + break; + case 0x40: + __SYNSetSustainPedal(synth, midiChannel, value); + break; + case 0x5B: + synth->auxAAttn[midiChannel] = __SYNVolumeAttenuation[value]; + break; + case 0x5C: + synth->auxBAttn[midiChannel] = __SYNVolumeAttenuation[value]; + break; + case 0x5D: + break; + case 0x62: + case 0x63: + synth->rpn[midiChannel] = 0; + break; + case 0x64: + case 0x65: + synth->rpn[midiChannel] = 1; + break; + case 0x78: + __SYNReleaseChannelNotes(synth, midiChannel); + break; + case 0x79: + if (value == 0) { + __SYNResetController0(synth, midiChannel); + } else { + __SYNResetController(synth, midiChannel); + } + break; + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + __SYNReleaseChannelNotes(synth, midiChannel); + break; + default: + break; + } +} + +void __SYNResetController0(SYNSYNTH* synth, u8 midiChannel) { + u8 volume; + u8 pan; + u8 expression; + int i; + + ASSERTLINE(315, synth); + ASSERTLINE(316, midiChannel < 16); + + synth->pwMaxCents[midiChannel] = 0xC80000; + synth->pwCents[midiChannel] = 0; + volume = synth->controller[midiChannel][7]; + pan = synth->controller[midiChannel][10]; + expression = synth->controller[midiChannel][11]; + + for (i = 0; i < 128; i++) { + synth->controller[midiChannel][i] = 0; + } + + __SYNSetController(synth, midiChannel, 7, volume); + __SYNSetController(synth, midiChannel, 0xA, pan); + __SYNSetController(synth, midiChannel, 0xB, expression); + __SYNSetController(synth, midiChannel, 0x5B, 0); + __SYNSetController(synth, midiChannel, 0x5C, 0); +} + +void __SYNResetController(SYNSYNTH* synth, u8 midiChannel) { + int i; + + ASSERTLINE(345, synth); + ASSERTLINE(346, midiChannel < 16); + + synth->pwMaxCents[midiChannel] = 0xC80000; + synth->pwCents[midiChannel] = 0; + + for (i = 0; i < 128; i++) { + synth->controller[midiChannel][i] = 0; + } + + __SYNSetController(synth, midiChannel, 7, 0x64); + __SYNSetController(synth, midiChannel, 0xA, 0x40); + __SYNSetController(synth, midiChannel, 0xB, 0x7F); + __SYNSetController(synth, midiChannel, 0x5B, 0); + __SYNSetController(synth, midiChannel, 0x5C, 0); +} + +void __SYNResetAllControllers(SYNSYNTH* synth) { + u8 midiChannel; + + ASSERTLINE(372, synth); + + for (midiChannel = 0; midiChannel < 16; midiChannel++) { + __SYNProgramChange(synth, midiChannel, 0); + __SYNResetController(synth, midiChannel); + } +} + +static void __SYNNoteOff(SYNSYNTH* synth, u8 midiChannel, u8 keyNum) { + SYNVOICE* voice; + + ASSERTLINE(389, synth); + ASSERTLINE(390, midiChannel < 16); + ASSERTLINE(391, keyNum < 128); + + voice = synth->voice[midiChannel][keyNum]; + if (voice) { + if (synth->controller[midiChannel][64] > 64) { + voice->hold = 1; + return; + } + __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); + synth->voice[midiChannel][keyNum] = 0; + } +} + +static void __SYNNoteOn(SYNSYNTH* synth, u8 midiChannel, u8 keyNum, u8 keyVel) { + AXVPB* axvpb; + SYNVOICE* voice; + SYNVOICE* oldVoice; + + ASSERTLINE(420, synth); + ASSERTLINE(421, midiChannel < 16); + ASSERTLINE(422, keyNum < 128); + ASSERTLINE(423, keyVel < 128); + + if (keyVel) { + if (synth->voice[midiChannel][keyNum]) { + __SYNSetVoiceToRelease(synth->voice[midiChannel][keyNum], synth->priorityNoteRelease); + synth->voice[midiChannel][keyNum] = 0; + } + + axvpb = AXAcquireVoice(synth->priorityVoiceAlloc, &__SYNClearVoiceReferences, (u32)synth); + + if (axvpb) { + voice = &__SYNVoice[axvpb->index]; + voice->axvpb = axvpb; + voice->synth = synth; + voice->midiChannel = midiChannel; + voice->keyNum = keyNum; + voice->keyVel = keyVel; + voice->hold = 0; + + if (__SYNGetWavetableData(voice) != 0) { + synth->voice[midiChannel][keyNum] = voice; + synth->notes++; + voice->keyGroup = voice->region->keyGroup; + if (voice->keyGroup != 0) { + oldVoice = synth->keyGroup[midiChannel][voice->keyGroup]; + if (oldVoice) { + oldVoice->synth = 0; + MIXReleaseChannel(oldVoice->axvpb); + AXFreeVoice(oldVoice->axvpb); + synth->voice[midiChannel][oldVoice->keyNum] = 0; + synth->notes--; + } + synth->keyGroup[midiChannel][voice->keyGroup] = voice; + } + + __SYNSetupPitch(voice); + __SYNSetupVolume(voice); + __SYNSetupPan(voice); + __SYNSetupLfo(voice); + __SYNSetupVolumeEnvelope(voice); + __SYNSetupPitchEnvelope(voice); + + if (midiChannel == 9) { + MIXInitChannel(axvpb, 0, __SYNGetVoiceInput(voice), synth->auxAAttn[midiChannel] >> 0x10, synth->auxBAttn[midiChannel] >> 0x10, voice->pan, 0x7F, __SYNGetVoiceFader(voice)); + } else { + MIXInitChannel(axvpb, 0, __SYNGetVoiceInput(voice), synth->auxAAttn[midiChannel] >> 0x10, synth->auxBAttn[midiChannel] >> 0x10, synth->controller[midiChannel][10], 0x7F, __SYNGetVoiceFader(voice)); + } + + __SYNSetupSample(voice); + __SYNSetupSrc(voice); + axvpb->pb.state = 1; + axvpb->sync = (axvpb->sync | 4); + AXSetVoicePriority(axvpb, synth->priorityNoteOn); + return; + } + + voice->synth = NULL; + MIXReleaseChannel(axvpb); + AXFreeVoice(axvpb); + } + } else { + __SYNNoteOff(synth, midiChannel, keyNum); + } +} + +static void __SYNPitchWheel(SYNSYNTH* synth, u8 midiChannel, u8 lsb, u8 msb) { + s32 position; + + ASSERTLINE(565, synth); + ASSERTLINE(566, midiChannel < 16); + ASSERTLINE(567, lsb < 128); + ASSERTLINE(568, msb < 128); + + position = lsb + (msb << 7) - 0x2000; + synth->pwCents[midiChannel] = (synth->pwMaxCents[midiChannel] * ((f32)position / 8192.0f)); +} + +static void __SYNMidiIn(SYNSYNTH* synth, u8* input) { + u8* ch; + u8 midiFunction; + u8 midiChannel; + u8 _2ndByte; + u8 _3rdByte; + + ASSERTLINE(589, synth); + ASSERTLINE(590, input); + + ch = input; + midiFunction = (*(ch) >> 4); ch += 0; + midiChannel = (*(ch) & 0xF); ch += 1; + _2ndByte = *(ch); ch += 1; + + switch(midiFunction) { + case 8: + __SYNNoteOff(synth, midiChannel, _2ndByte); + return; + case 9: + _3rdByte = *(ch); ch += 1; + __SYNNoteOn(synth, midiChannel, _2ndByte, _3rdByte); + return; + case 11: + _3rdByte = *(ch); ch += 1; + __SYNSetController(synth, midiChannel, _2ndByte, _3rdByte); + return; + case 12: + __SYNProgramChange(synth, midiChannel, _2ndByte); + return; + case 14: + _3rdByte = *(ch); ch+=1; + __SYNPitchWheel(synth, midiChannel, _2ndByte, _3rdByte); + return; + } +} + +void __SYNRunInputBufferEvents(SYNSYNTH* synth) { + u8* input; + + for (input = &synth->input[0][0]; synth->inputCounter; synth->inputCounter--) { + __SYNMidiIn(synth, input); + input+=3; + } + + synth->inputPosition = &synth->input[0][0]; +} + +u8 SYNGetMidiController(SYNSYNTH* synth, u8 midiChannel, u8 function) { + ASSERTLINE(678, synth); + ASSERTLINE(679, midiChannel < 16); + ASSERTLINE(680, function < 128); + return synth->controller[midiChannel][function]; +} diff --git a/src/dolphin/syn/synenv.c b/src/dolphin/syn/synenv.c new file mode 100644 index 0000000..caafb5e --- /dev/null +++ b/src/dolphin/syn/synenv.c @@ -0,0 +1,185 @@ +#include +#include +#include +#include "fake_tgmath.h" +#include "cmath.h" + +#include "__syn.h" + +s32 __SYNGetEnvelopeTime(s32 scale, s32 mod, u8 key) { + if (scale == 0x80000000) { + return 0; + } + + if (mod == 0x80000000) { + return (1000.0f* powf(2.0f, (f32)scale / (65536* 1200))); + } + + return (1000.0f* powf(2.0f, ((f32)scale + (mod* __SYNn128[key])) / (65535* 1200))); +} + +void __SYNSetupVolumeEnvelope(SYNVOICE* voice) { + ASSERTLINE(46, voice); + + if (voice->art->eg1Attack + 0x80000000 == 0) { + voice->veState = 1; + voice->veAttn = 0; + if (voice->art->eg1Decay + 0x80000000 == 0) { + voice->veState = 2; + voice->veAttn = voice->art->eg1Sustain; + } + } else { + s32 frames = __SYNGetEnvelopeTime(voice->art->eg1Attack, voice->art->eg1Vel2Attack, voice->keyVel) / 5; + if (frames != 0) { + voice->veAttack = 0; + voice->veAttackDelta = 0x640000 / frames; + voice->veAttn = 0xFC400000; + voice->veState = 0; + } else { + voice->veAttack = 0; + voice->veAttackDelta = 0x640000; + voice->veAttn = 0xFC400000; + voice->veState = 0; + } + } + + if (voice->veState < 2) { + s32 frames = __SYNGetEnvelopeTime(voice->art->eg1Decay, voice->art->eg1Key2Decay, voice->keyNum) / 5; + if (frames != 0) { + voice->veDecay = -0x03C00000 / frames; + } else { + voice->veDecay = -0x03C00000; + } + } + + voice->veSustain = voice->art->eg1Sustain; + voice->veRelease = voice->art->eg1Release; +} + +void __SYNSetupPitchEnvelope(SYNVOICE* voice) { + ASSERTLINE(110, voice); + + voice->peCents = 0; + voice->pePitch = voice->art->eg2Pitch; + if (voice->pePitch != 0) { + if (voice->art->eg2Attack + 0x80000000 == 0) { + voice->peState = 1; + voice->peCents = voice->pePitch; + if (voice->art->eg2Decay + 0x80000000 == 0) { + voice->peState = 2; + voice->peCents = voice->art->eg2Sustain; + } + } else { + s32 frames = __SYNGetEnvelopeTime(voice->art->eg2Attack, voice->art->eg2Vel2Attack, voice->keyVel) / 5; + if (frames != 0) { + voice->peAttack = voice->pePitch / frames; + voice->peState = 0; + } else { + voice->peAttack = voice->pePitch; + voice->peState = 0; + } + } + + if (voice->peState < 2) { + s32 frames = __SYNGetEnvelopeTime(voice->art->eg2Decay, voice->art->eg2Key2Decay, voice->keyNum) / 5; + if (frames != 0) { + voice->peDecay = voice->pePitch / frames; + } else { + voice->peDecay = voice->pePitch; + } + voice->peDecay = voice->peDecay * -1; + } + voice->peSustain = voice->art->eg2Sustain; + voice->peRelease = voice->art->eg2Release; + } +} + +void __SYNRunVolumeEnvelope(SYNVOICE* voice) { + ASSERTLINE(178, voice); + + switch(voice->veState) { + case 0: + voice->veAttack = (voice->veAttack + voice->veAttackDelta); + if (voice->veAttack >= 0x630000) { + voice->veAttn = 0; + } else { + voice->veAttn = __SYNAttackAttnTable[voice->veAttack >> 0x10]; + } + if (voice->veAttn == 0) { + voice->veState = 1; + } + case 2: + return; + case 1: + voice->veAttn = (voice->veAttn + voice->veDecay); + if (voice->veAttn <= voice->veSustain) { + voice->veAttn = voice->veSustain; + voice->veState = 2; + } + if (voice->veAttn <= -0x02D00000) { + voice->veState = 4; + voice->synth->voice[voice->midiChannel][voice->keyNum] = 0; + } + return; + case 3: + if (voice->veAttn <= -0x02D00000) { + voice->veState = 4; + } else { + voice->veAttn = (voice->veAttn + voice->veRelease); + } + return; + } +} + +void __SYNRunPitchEnvelope(SYNVOICE* voice) { + ASSERTLINE(243, voice); + + if (voice->pePitch != 0) { + switch(voice->peState) { + case 0: + voice->peCents = (voice->peCents + voice->peAttack); + if (voice->pePitch > 0) { + if (voice->peCents >= voice->pePitch) { + voice->pePitch = voice->peCents; + voice->peState = 1; + } + } else if (voice->peCents <= voice->pePitch) { + voice->pePitch = voice->peCents; + voice->peState = 1; + } + case 2: + return; + case 1: + voice->peCents = (voice->peCents + voice->peDecay); + if (voice->pePitch > 0) { + if (voice->peCents <= 0) { + voice->peCents = 0; + voice->pePitch = 0; + } else if (voice->peCents <= voice->peSustain) { + voice->peCents = voice->peSustain; + voice->peState = 2; + } + } else { + if (voice->peCents >= 0) { + voice->peCents = 0; + voice->pePitch = 0; + } else if (voice->peCents >= voice->peSustain) { + voice->peCents = voice->peSustain; + voice->peState = 2; + } + } + break; + case 3: + voice->peCents = (voice->peCents + voice->peRelease); + if (voice->pePitch > 0) { + if (voice->peCents <= 0) { + voice->peCents = 0; + voice->pePitch = 0; + } + } else if (voice->peCents >= 0) { + voice->peCents = 0; + voice->pePitch = 0; + } + } + } +} diff --git a/src/dolphin/syn/synlfo.c b/src/dolphin/syn/synlfo.c new file mode 100644 index 0000000..22ace20 --- /dev/null +++ b/src/dolphin/syn/synlfo.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +static f32 __SYNLfo[64] = { + 0.000000f, + 0.098020f, + 0.195090f, + 0.290280f, + 0.382680f, + 0.471400f, + 0.555570f, + 0.634390f, + 0.707110f, + 0.773010f, + 0.831470f, + 0.881920f, + 0.923880f, + 0.956940f, + 0.980790f, + 0.995180f, + 1.000000f, + 0.995180f, + 0.980790f, + 0.956940f, + 0.923880f, + 0.881920f, + 0.831470f, + 0.773010f, + 0.707110f, + 0.634390f, + 0.555570f, + 0.471400f, + 0.382680f, + 0.290280f, + 0.195090f, + 0.098020f, + 0.000000f, + -0.098020f, + -0.195090f, + -0.290280f, + -0.382680f, + -0.471400f, + -0.555570f, + -0.634390f, + -0.707110f, + -0.773010f, + -0.831470f, + -0.881920f, + -0.923880f, + -0.956940f, + -0.980790f, + -0.995180f, + -1.000000f, + -0.995180f, + -0.980790f, + -0.956940f, + -0.923880f, + -0.881920f, + -0.831470f, + -0.773010f, + -0.707110f, + -0.634390f, + -0.555570f, + -0.471400f, + -0.382680f, + -0.290280f, + -0.195090f, + -0.098020f, +}; + +void __SYNSetupLfo(SYNVOICE* voice) { + ASSERTLINE(47, voice); + + voice->lfoState = voice->lfoAttn = voice->lfoCents = 0; + voice->lfoFreq = voice->art->lfoFreq; + voice->lfoDelay = voice->art->lfoDelay; + voice->lfoAttn_ = voice->art->lfoAtten; + voice->lfoCents = voice->art->lfoPitch; + voice->lfoModAttn = voice->art->lfoMod2Atten; + voice->lfoModCents = voice->art->lfoMod2Pitch; +} + +void __SYNRunLfo(SYNVOICE* voice) { + f32 lfoAmplitude; + f32 lfoModWheel; + + ASSERTLINE(66, voice); + + if (voice->lfoDelay != 0) { + voice->lfoDelay--; + } else { + voice->lfoState += voice->lfoFreq; + lfoAmplitude = __SYNLfo[(voice->lfoState >> 0x10) % 64]; + lfoModWheel = __SYNn128[voice->synth->controller[voice->midiChannel][1]]; + voice->lfoAttn = (lfoAmplitude * (voice->lfoAttn_ + (voice->lfoModAttn* lfoModWheel))); + voice->lfoCents = (lfoAmplitude * (voice->lfoCents_ + (voice->lfoModCents* lfoModWheel))); + } +} diff --git a/src/dolphin/syn/synmix.c b/src/dolphin/syn/synmix.c new file mode 100644 index 0000000..56dc0ac --- /dev/null +++ b/src/dolphin/syn/synmix.c @@ -0,0 +1,274 @@ +#include +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +s32 __SYNVolumeAttenuation[128] = { + 0xFC400000, + 0xFCB67A80, + 0xFD2EE3F9, + 0xFD7553B8, + 0xFDA74D72, + 0xFDCE1108, + 0xFDEDBD30, + 0xFE08848A, + 0xFE1FB6EA, + 0xFE342CEF, + 0xFE467A80, + 0xFE57091D, + 0xFE6626A9, + 0xFE740E4D, + 0xFE80EE03, + 0xFE8CEA3F, + 0xFE982063, + 0xFEA2A878, + 0xFEAC9668, + 0xFEB5FADF, + 0xFEBEE3F9, + 0xFEC75DC2, + 0xFECF7295, + 0xFED72B6E, + 0xFEDE9022, + 0xFEE5A78F, + 0xFEEC77C6, + 0xFEF30626, + 0xFEF9577C, + 0xFEFF700E, + 0xFF0553B8, + 0xFF0B05F0, + 0xFF1089DC, + 0xFF15E254, + 0xFF1B11F1, + 0xFF201B12, + 0xFF24FFE1, + 0xFF29C25C, + 0xFF2E6457, + 0xFF32E784, + 0xFF374D72, + 0xFF3B9791, + 0xFF3FC73A, + 0xFF43DDAC, + 0xFF47DC0E, + 0xFF4BC376, + 0xFF4F94E7, + 0xFF535152, + 0xFF56F99B, + 0xFF5A8E94, + 0xFF5E1108, + 0xFF6181B0, + 0xFF64E13E, + 0xFF68305A, + 0xFF6B6F9F, + 0xFF6E9FA4, + 0xFF71C0F4, + 0xFF74D416, + 0xFF77D987, + 0xFF7AD1BF, + 0xFF7DBD30, + 0xFF809C47, + 0xFF836F69, + 0xFF8636F9, + 0xFF88F355, + 0xFF8BA4D4, + 0xFF8E4BCD, + 0xFF90E890, + 0xFF937B6A, + 0xFF9604A6, + 0xFF98848A, + 0xFF9AFB5B, + 0xFF9D6959, + 0xFF9FCEC3, + 0xFFA22BD4, + 0xFFA480C6, + 0xFFA6CDD0, + 0xFFA91327, + 0xFFAB50FD, + 0xFFAD8784, + 0xFFAFB6EA, + 0xFFB1DF5E, + 0xFFB4010A, + 0xFFB61C19, + 0xFFB830B3, + 0xFFBA3F00, + 0xFFBC4724, + 0xFFBE4946, + 0xFFC04587, + 0xFFC23C0A, + 0xFFC42CEF, + 0xFFC61857, + 0xFFC7FE60, + 0xFFC9DF28, + 0xFFCBBACB, + 0xFFCD9166, + 0xFFCF6313, + 0xFFD12FED, + 0xFFD2F80D, + 0xFFD4BB8B, + 0xFFD67A80, + 0xFFD83502, + 0xFFD9EB29, + 0xFFDB9D08, + 0xFFDD4AB7, + 0xFFDEF449, + 0xFFE099D2, + 0xFFE23B66, + 0xFFE3D918, + 0xFFE572F9, + 0xFFE7091D, + 0xFFE89B93, + 0xFFEA2A6D, + 0xFFEBB5BC, + 0xFFED3D8F, + 0xFFEEC1F6, + 0xFFF04300, + 0xFFF1C0BC, + 0xFFF33B38, + 0xFFF4B283, + 0xFFF626A9, + 0xFFF797B9, + 0xFFF905BF, + 0xFFFA70C9, + 0xFFFBD8E2, + 0xFFFD3E16, + 0xFFFEA072, + 0x00000000 +}; + +s32 __SYNAttackAttnTable[100] = { + 0xFC400000, + 0xFE70DF7B, + 0xFEAD1437, + 0xFED04C17, + 0xFEE948F4, + 0xFEFCAABF, + 0xFF0C80D3, + 0xFF19E480, + 0xFF257DB0, + 0xFF2FB8B2, + 0xFF38DF7B, + 0xFF4126C9, + 0xFF48B58F, + 0xFF4FA961, + 0xFF56193C, + 0xFF5C175A, + 0xFF61B26C, + 0xFF66F677, + 0xFF6BED6F, + 0xFF709FAA, + 0xFF751437, + 0xFF79511C, + 0xFF7D5B85, + 0xFF8137F2, + 0xFF84EA4C, + 0xFF887602, + 0xFF8BDE1E, + 0xFF8F254E, + 0xFF924DF9, + 0xFF955A42, + 0xFF984C17, + 0xFF9B2533, + 0xFF9DE729, + 0xFFA09365, + 0xFFA32B33, + 0xFFA5AFC4, + 0xFFA8222B, + 0xFFAA8369, + 0xFFACD466, + 0xFFAF15FD, + 0xFFB148F4, + 0xFFB36E03, + 0xFFB585D8, + 0xFFB79111, + 0xFFB99042, + 0xFFBB83F6, + 0xFFBD6CAE, + 0xFFBF4AE4, + 0xFFC11F08, + 0xFFC2E985, + 0xFFC4AABF, + 0xFFC66313, + 0xFFC812DA, + 0xFFC9BA68, + 0xFFCB5A0A, + 0xFFCCF20D, + 0xFFCE82B5, + 0xFFD00C46, + 0xFFD18EFE, + 0xFFD30B1A, + 0xFFD480D3, + 0xFFD5F05E, + 0xFFD759EF, + 0xFFD8BDB7, + 0xFFDA1BE5, + 0xFFDB74A5, + 0xFFDCC821, + 0xFFDE1683, + 0xFFDF5FF0, + 0xFFE0A48E, + 0xFFE1E480, + 0xFFE31FE8, + 0xFFE456E7, + 0xFFE5899C, + 0xFFE6B825, + 0xFFE7E29E, + 0xFFE90923, + 0xFFEA2BCE, + 0xFFEB4AB9, + 0xFFEC65FD, + 0xFFED7DB0, + 0xFFEE91EA, + 0xFFEFA2C0, + 0xFFF0B047, + 0xFFF1BA94, + 0xFFF2C1BB, + 0xFFF3C5CD, + 0xFFF4C6DE, + 0xFFF5C4FE, + 0xFFF6C040, + 0xFFF7B8B2, + 0xFFF8AE66, + 0xFFF9A16B, + 0xFFFA91CF, + 0xFFFB7FA0, + 0xFFFC6AEE, + 0xFFFD53C4, + 0xFFFE3A31, + 0xFFFF1E41, + 0x00000000 +}; + +void __SYNSetupVolume(SYNVOICE* voice) { + ASSERTLINE(85, voice); + voice->attn = (voice->region->attn + __SYNVolumeAttenuation[voice->keyVel]); +} + +void __SYNSetupPan(SYNVOICE* voice) { + ASSERTLINE(98, voice); + if (voice->midiChannel == 9) { + voice->pan = voice->art->pan; + } else { + voice->pan = voice->synth->controller[voice->midiChannel][10]; + } +} + +s32 __SYNGetVoiceInput(SYNVOICE* voice) { + return (voice->attn + voice->lfoAttn + voice->veAttn) >> 0x10; +} + +s32 __SYNGetVoiceFader(SYNVOICE* voice) { + return (voice->synth->volAttn[voice->midiChannel] + voice->synth->expAttn[voice->midiChannel] + voice->synth->masterVolume) >> 0x10; +} + +void __SYNUpdateMix(SYNVOICE* voice) { + MIXSetInput(voice->axvpb, __SYNGetVoiceInput(voice)); + MIXSetAuxA(voice->axvpb, voice->synth->auxAAttn[voice->midiChannel] >> 0x10); + MIXSetAuxB(voice->axvpb, voice->synth->auxBAttn[voice->midiChannel] >> 0x10); + MIXSetFader(voice->axvpb, __SYNGetVoiceFader(voice)); + + if (voice->midiChannel != 9) { + MIXSetPan(voice->axvpb, voice->synth->controller[voice->midiChannel][10]); + } +} diff --git a/src/dolphin/syn/synpitch.c b/src/dolphin/syn/synpitch.c new file mode 100644 index 0000000..ed1d543 --- /dev/null +++ b/src/dolphin/syn/synpitch.c @@ -0,0 +1,340 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +static f32 __SYNCentsTable[100] = { + 1.000000f, + 1.000578f, + 1.001156f, + 1.001734f, + 1.002313f, + 1.002892f, + 1.003472f, + 1.004052f, + 1.004632f, + 1.005212f, + 1.005793f, + 1.006374f, + 1.006956f, + 1.007537f, + 1.008120f, + 1.008702f, + 1.009285f, + 1.009868f, + 1.010451f, + 1.011035f, + 1.011619f, + 1.012204f, + 1.012789f, + 1.013374f, + 1.013959f, + 1.014545f, + 1.015132f, + 1.015718f, + 1.016305f, + 1.016892f, + 1.017480f, + 1.018068f, + 1.018656f, + 1.019244f, + 1.019833f, + 1.020423f, + 1.021012f, + 1.021602f, + 1.022192f, + 1.022783f, + 1.023374f, + 1.023965f, + 1.024557f, + 1.025149f, + 1.025741f, + 1.026334f, + 1.026927f, + 1.027520f, + 1.028114f, + 1.028708f, + 1.029302f, + 1.029897f, + 1.030492f, + 1.031087f, + 1.031683f, + 1.032279f, + 1.032876f, + 1.033472f, + 1.034070f, + 1.034667f, + 1.035265f, + 1.035863f, + 1.036462f, + 1.037060f, + 1.037660f, + 1.038259f, + 1.038859f, + 1.039459f, + 1.040060f, + 1.040661f, + 1.041262f, + 1.041864f, + 1.042466f, + 1.043068f, + 1.043671f, + 1.044274f, + 1.044877f, + 1.045481f, + 1.046085f, + 1.046689f, + 1.047294f, + 1.047899f, + 1.048505f, + 1.049111f, + 1.049717f, + 1.050323f, + 1.050930f, + 1.051537f, + 1.052145f, + 1.052753f, + 1.053361f, + 1.053970f, + 1.054579f, + 1.055188f, + 1.055798f, + 1.056408f, + 1.057018f, + 1.057629f, + 1.058240f, + 1.058851f, +}; + +static f32 __SYNOctavesTableUp[12] = { + 1.000000f, + 2.000000f, + 4.000000f, + 8.000000f, + 16.000000f, + 32.000000f, + 64.000000f, + 128.000000f, + 256.000000f, + 512.000000f, + 1024.000000f, + 2048.000000f, +}; + +static f32 __SYNSemitonesTableUp[12] = { + 1.000000f, + 1.059463f, + 1.122462f, + 1.189207f, + 1.259921f, + 1.334840f, + 1.414214f, + 1.498307f, + 1.587401f, + 1.681793f, + 1.781797f, + 1.887749f, +}; + +static f32 __SYNSemitonesTableDown[128] = { + 1.000000f, + 0.943874f, + 0.890899f, + 0.840896f, + 0.793701f, + 0.749154f, + 0.707107f, + 0.667420f, + 0.629961f, + 0.594604f, + 0.561231f, + 0.529732f, + 0.500000f, + 0.471937f, + 0.445449f, + 0.420448f, + 0.396850f, + 0.374577f, + 0.353553f, + 0.333710f, + 0.314980f, + 0.297302f, + 0.280616f, + 0.264866f, + 0.250000f, + 0.235969f, + 0.222725f, + 0.210224f, + 0.198425f, + 0.187288f, + 0.176777f, + 0.166855f, + 0.157490f, + 0.148651f, + 0.140308f, + 0.132433f, + 0.125000f, + 0.117984f, + 0.111362f, + 0.105112f, + 0.099213f, + 0.093644f, + 0.088388f, + 0.083427f, + 0.078745f, + 0.074325f, + 0.070154f, + 0.066216f, + 0.062500f, + 0.058992f, + 0.055681f, + 0.052556f, + 0.049606f, + 0.046822f, + 0.044194f, + 0.041714f, + 0.039373f, + 0.037163f, + 0.035077f, + 0.033108f, + 0.031250f, + 0.029496f, + 0.027841f, + 0.026278f, + 0.024803f, + 0.023411f, + 0.022097f, + 0.020857f, + 0.019686f, + 0.018581f, + 0.017538f, + 0.016554f, + 0.015625f, + 0.014748f, + 0.013920f, + 0.013139f, + 0.012402f, + 0.011706f, + 0.011049f, + 0.010428f, + 0.009843f, + 0.009291f, + 0.008769f, + 0.008277f, + 0.007813f, + 0.007374f, + 0.006960f, + 0.006570f, + 0.006201f, + 0.005853f, + 0.005524f, + 0.005214f, + 0.004922f, + 0.004645f, + 0.004385f, + 0.004139f, + 0.003906f, + 0.003687f, + 0.003480f, + 0.003285f, + 0.003100f, + 0.002926f, + 0.002762f, + 0.002607f, + 0.002461f, + 0.002323f, + 0.002192f, + 0.002069f, + 0.001953f, + 0.001844f, + 0.001740f, + 0.001642f, + 0.001550f, + 0.001463f, + 0.001381f, + 0.001304f, + 0.001230f, + 0.001161f, + 0.001096f, + 0.001035f, + 0.000977f, + 0.000922f, + 0.000870f, + 0.000821f, + 0.000775f, + 0.000732f, + 0.000691f, + 0.000652f, +}; + +f32 __SYNGetRelativePitch(SYNVOICE* voice) { + s32 cents; + + cents = voice->cents + voice->lfoCents + voice->peCents + voice->synth->pwCents[voice->midiChannel]; + cents = cents / 65536; + + if (cents > 0) { + s32 octaves = (cents / 1200); + s32 semitones = (cents % 1200) / 100; + cents = (cents % 100); + return __SYNOctavesTableUp[octaves] * __SYNSemitonesTableUp[semitones] * __SYNCentsTable[cents]; + } + + if (cents < 0) { + s32 semitones = cents / 100; + cents = (cents % 100); + if (cents != 0) { + cents += 100; + semitones-=1; + } + semitones *= -1; + return __SYNSemitonesTableDown[semitones] * __SYNCentsTable[cents]; + } + + return 1.0f; +} + +void __SYNSetupPitch(SYNVOICE* voice) { + voice->srcRatio = (voice->sample->sampleRate / 32000.0f); + voice->cents = (voice->keyNum - voice->region->unityNote) * 100; + voice->cents = (voice->cents + voice->region->fineTune); + voice->cents = (voice->cents << 0x10); +} + +void __SYNSetupSrc(SYNVOICE* voice) { + f32 srcRatio; + u32 value; + u16* p; + + srcRatio = voice->srcRatio* __SYNGetRelativePitch(voice); + if (srcRatio > 4.0f) { + value = 0x40000; + } else { + value = (65536.0f* srcRatio); + } + + voice->axvpb->pb.srcSelect = 1; + p = (void*)&voice->axvpb->pb.src; + *(p) = (value >> 0x10); p += 1; + *(p) = (value); p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + + voice->axvpb->sync &= 0xFFF7FFFF; + voice->axvpb->sync |= 0x40001; +} + +void __SYNUpdateSrc(SYNVOICE* voice) { + u32 ratio = (65536.0f * (voice->srcRatio * __SYNGetRelativePitch(voice))); + + if (ratio > 0x40000) { + ratio = 0x40000; + } + + *(u32*)&voice->axvpb->pb.src.ratioHi = ratio; + voice->axvpb->sync |= 0x80000; +} diff --git a/src/dolphin/syn/synsample.c b/src/dolphin/syn/synsample.c new file mode 100644 index 0000000..8419c57 --- /dev/null +++ b/src/dolphin/syn/synsample.c @@ -0,0 +1,241 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +// prototypes +static u32 __SYNGetNibbleAddress(u32 count); +static void __SYNSetupAdpcm(SYNVOICE* voice); +static void __SYNSetupPcm16(SYNVOICE* voice); +static void __SYNSetupPcm8(SYNVOICE* voice); + +static u32 __SYNGetNibbleAddress(u32 count) { + u32 samples = count; + u32 frames = (samples / 14); + u32 samplesLeft = (samples % 14); + + return (frames * 0x10) + 2 + samplesLeft; +} + +static void __SYNSetupAdpcm(SYNVOICE* voice) { + AXVPB* axvpb = voice->axvpb; + + if ((voice->region->loopStart + voice->region->loopLength) != 0) { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + u32* adpcm; + u16* adpcmloop; + + adpcm = (void*)&voice->adpcm->a; + voice->type = 1; + sampleStart = voice->synth->aramBaseNibble + voice->sample->offset; + sampleLoop = sampleStart + __SYNGetNibbleAddress(voice->region->loopStart); + sampleEnd = sampleStart + __SYNGetNibbleAddress(voice->region->loopStart + voice->region->loopLength - 1); + ASSERTLINE(79, (sampleStart & 0x000f) == 0); + ASSERTLINE(80, (sampleLoop & 0x000f) > 1); + ASSERTLINE(81, (sampleEnd & 0x000f) > 1); + + // the hell? why not just write the members??? what is this doing??? + // why not just write to the members directly? + sampleStart = sampleStart + 2; + p = (u32*)&axvpb->pb.addr; + *(p) = 0x10000; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + adpcmloop = (void*)(adpcm); + axvpb->pb.adpcmLoop.loop_pred_scale = *(adpcmloop); adpcmloop += 1; + axvpb->pb.adpcmLoop.loop_yn1 = *(adpcmloop); adpcmloop += 1; + axvpb->pb.adpcmLoop.loop_yn2 = *(adpcmloop); adpcmloop += 1; + axvpb->sync &= 0xFFFE1FFF; + axvpb->sync |= 0x121000; + } else { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + u32* adpcm; + + adpcm = (void*)&voice->adpcm->a; + voice->type = 0; + sampleStart = voice->synth->aramBaseNibble + voice->sample->offset; + sampleLoop = sampleStart + __SYNGetNibbleAddress(voice->synth->zeroBaseNibble); + sampleEnd = sampleStart + __SYNGetNibbleAddress(voice->sample->length - 1); + + ASSERTLINE(135, (sampleStart & 0x000f) == 0); + ASSERTLINE(136, (sampleEnd & 0x000f) > 1); + + // same wtf writes here + sampleStart = sampleStart + 2; + p = (void*)&axvpb->pb.addr; + *(p) = 0; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + axvpb->sync &= 0xFFFE1FFF; + axvpb->sync |= 0x21000; + } +} + +static void __SYNSetupPcm16(SYNVOICE* voice) { + AXVPB* axvpb = voice->axvpb; + + if ((voice->region->loopStart + voice->region->loopLength) != 0) { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + + voice->type = 1; + sampleStart = voice->synth->aramBaseWord + voice->sample->offset; + sampleLoop = sampleStart + voice->region->loopStart; + sampleEnd = sampleLoop + voice->region->loopLength - 1; + + p = (u32*)&axvpb->pb.addr; + *(p) = 0x1000A; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0x08000000; p += 1; + *(p) = 0; p += 1; + } else { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + + voice->type = 0; + sampleStart = voice->synth->aramBaseWord + voice->sample->offset; + sampleLoop = voice->synth->zeroBaseWord; + sampleEnd = sampleStart + voice->sample->length - 1; + + p = (u32*)&axvpb->pb.addr; + *(p) = 0x0000A; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0x08000000; p += 1; + *(p) = 0; p += 1; + } + axvpb->sync &= 0xFFFE1FFF; + axvpb->sync |= 0x21000; +} + +static void __SYNSetupPcm8(SYNVOICE* voice) { + AXVPB* axvpb = voice->axvpb; + + if ((voice->region->loopStart + voice->region->loopLength) != 0) { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + + voice->type = 1; + sampleStart = voice->synth->aramBaseByte + voice->sample->offset; + sampleLoop = sampleStart + voice->region->loopStart; + sampleEnd = sampleLoop + voice->region->loopLength - 1; + p = (u32*)&axvpb->pb.addr; + *(p) = 0x10019; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0x01000000; p += 1; + *(p) = 0; p += 1; + } else { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + + voice->type = 0; + sampleStart = voice->synth->aramBaseByte + voice->sample->offset; + sampleLoop = voice->synth->zeroBaseByte; + sampleEnd = sampleStart + voice->sample->length - 1; + + p = (u32*)&axvpb->pb.addr; + *(p) = 0x19; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0x01000000; p += 1; + *(p) = 0; p += 1; + } + + axvpb->sync &= 0xFFFE1FFF; + axvpb->sync |= 0x21000; +} + +void __SYNSetupSample(SYNVOICE* voice) { + ASSERTLINE(361, voice); + + switch(voice->sample->format) { + case SYN_SAMPLE_FORMAT_ADPCM: + __SYNSetupAdpcm(voice); + return; + case SYN_SAMPLE_FORMAT_PCM16: + __SYNSetupPcm16(voice); + return; + case SYN_SAMPLE_FORMAT_PCM8: + __SYNSetupPcm8(voice); + return; + default: + ASSERTMSGLINE(385, FALSE, "unknown sample format\n"); + return; + } +} diff --git a/src/dolphin/syn/synvoice.c b/src/dolphin/syn/synvoice.c new file mode 100644 index 0000000..ea5e66d --- /dev/null +++ b/src/dolphin/syn/synvoice.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +#define AX_MAX_VOICES 64 + +SYNVOICE __SYNVoice[64]; + +void __SYNClearVoiceReferences(void* p) { + AXVPB* axvpb; + SYNSYNTH* synth; + SYNVOICE* voice; + + ASSERTLINE(33, p); + + axvpb = p; + synth = (void*)axvpb->userContext; + voice = &__SYNVoice[axvpb->index]; + + ASSERTLINE(38, synth); + ASSERTLINE(39, axvpb->index < AX_MAX_VOICES); + MIXReleaseChannel(axvpb); + + if (voice->keyGroup) { + synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; + } + if (synth->voice[voice->midiChannel][voice->keyNum] == voice) { + synth->voice[voice->midiChannel][voice->keyNum] = 0; + } + + voice->synth = 0; + synth->notes--; +} + +void __SYNSetVoiceToRelease(SYNVOICE* voice, u32 priority) { + ASSERTLINE(63, voice); + voice->veState = 3; + voice->peState = 3; + AXSetVoicePriority(voice->axvpb, priority); +} + +void __SYNServiceVoice(int i) { + SYNVOICE* voice; + SYNSYNTH* synth; + + voice = &__SYNVoice[i]; + synth = voice->synth; + + if (synth != NULL) { + if ((voice->type == 0) && (voice->axvpb->pb.state == 0)) { + if (voice->keyGroup != 0) { + voice->synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; + } + if (synth->voice[voice->midiChannel][voice->keyNum] == voice) { + synth->voice[voice->midiChannel][voice->keyNum] = 0; + } + voice->veState = 4; + } + + __SYNRunVolumeEnvelope(voice); + + if (voice->veState == 4) { + if (voice->keyGroup != 0) { + voice->synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; + } + voice->synth = NULL; + MIXReleaseChannel(voice->axvpb); + AXFreeVoice(voice->axvpb); + synth->notes--; + return; + } + + __SYNRunLfo(voice); + __SYNRunPitchEnvelope(voice); + __SYNUpdateMix(voice); + __SYNUpdateSrc(voice); + } +} diff --git a/src/dolphin/syn/synwt.c b/src/dolphin/syn/synwt.c new file mode 100644 index 0000000..6a03e03 --- /dev/null +++ b/src/dolphin/syn/synwt.c @@ -0,0 +1,21 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +int __SYNGetWavetableData(SYNVOICE* voice) { + u32 regionIndex; + SYNSYNTH* synth; + + synth = voice->synth; + regionIndex = synth->inst[voice->midiChannel]->keyRegion[voice->keyNum]; + if (regionIndex == 0xFFFF) { + return 0; + } + voice->region = &synth->region[regionIndex]; + voice->art = &synth->art[voice->region->articulationIndex]; + voice->sample = &synth->sample[voice->region->sampleIndex]; + voice->adpcm = &synth->adpcm[voice->sample->adpcmIndex]; + return 1; +} diff --git a/src/dolphin/texPalette/texPalette.c b/src/dolphin/texPalette/texPalette.c new file mode 100644 index 0000000..7f3a87f --- /dev/null +++ b/src/dolphin/texPalette/texPalette.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include + +static void LoadTexPalette(TEXPalettePtr* pal, char* name); +static void UnpackTexPalette(TEXPalettePtr pal); +static void TexFreeFunc(TEXPalettePtr* pal); + +void TEXGetPalette(TEXPalettePtr* pal, char* name) { + void* p = TexFreeFunc; + + if (DOCacheInitialized) { + *pal = (TEXPalettePtr)DSGetCacheObj(&DODisplayCache, name); + } + + if (!*pal) { + LoadTexPalette(pal, name); + if (DOCacheInitialized) { + DSAddCacheNode(&DODisplayCache, name, (Ptr)*pal, p); + DSGetCacheObj(&DODisplayCache, name); + } + } +} + +static void LoadTexPalette(TEXPalettePtr* pal, char* name) { + DVDFileInfo dfi; + + DVDOpen(name, &dfi); + *pal = OSAlloc(OSRoundUp32B(dfi.length)); + DVDReadPrio(&dfi, *pal, OSRoundUp32B(dfi.length), 0, 2); + DVDClose(&dfi); + UnpackTexPalette(*pal); +} + +#define PALETTE_VERSION 0x20AF30 + +static void UnpackTexPalette(TEXPalettePtr pal) { + u16 i; + + if (pal->versionNumber != PALETTE_VERSION) { + OSPanic(__FILE__, 86, "invalid version number for texture palette"); + } + + pal->descriptorArray = (TEXDescriptorPtr)((Ptr)pal->descriptorArray + (u32)pal); + for (i = 0; i < pal->numDescriptors; i++) { + if (pal->descriptorArray[i].textureHeader) { + pal->descriptorArray[i].textureHeader = (TEXHeaderPtr)((Ptr)pal + (u32)pal->descriptorArray[i].textureHeader); + if (!pal->descriptorArray[i].textureHeader->unpacked) { + pal->descriptorArray[i].textureHeader->data = (Ptr)pal + (u32)pal->descriptorArray[i].textureHeader->data; + pal->descriptorArray[i].textureHeader->unpacked = TRUE; + } + } + + if (pal->descriptorArray[i].CLUTHeader) { + pal->descriptorArray[i].CLUTHeader = (CLUTHeaderPtr)((u8 *)pal + (u32)pal->descriptorArray[i].CLUTHeader); + if (!pal->descriptorArray[i].CLUTHeader->unpacked) { + pal->descriptorArray[i].CLUTHeader->data = (Ptr)pal + (u32)pal->descriptorArray[i].CLUTHeader->data; + pal->descriptorArray[i].CLUTHeader->unpacked = TRUE; + } + } + } +} + +TEXDescriptorPtr TEXGet(TEXPalettePtr pal, u32 id) { + ASSERTMSGLINE(147, id < pal->numDescriptors, "GetTexture(): Texture Not Found "); + return &pal->descriptorArray[id]; +} + +static void TexFreeFunc(TEXPalettePtr* pal) { + OSFree(*pal); + *pal = NULL; +} + +void TEXReleasePalette(TEXPalettePtr* pal) { + if (DOCacheInitialized) { + DSReleaseCacheObj(&DODisplayCache, (Ptr)*pal); + } else { + OSFree(*pal); + *pal = NULL; + } +} + +void TEXGetGXTexObjFromPalette(TEXPalettePtr pal, GXTexObj* to, u32 id) { + TEXDescriptorPtr tdp; + GXBool mipMap; + + tdp = TEXGet(pal, id); + if (tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD) { + mipMap = GX_FALSE; + } else { + mipMap = GX_TRUE; + } + GXInitTexObj(to, tdp->textureHeader->data, tdp->textureHeader->width, tdp->textureHeader->height, tdp->textureHeader->format, tdp->textureHeader->wrapS, tdp->textureHeader->wrapT, mipMap); + GXInitTexObjLOD(to, tdp->textureHeader->minFilter, tdp->textureHeader->magFilter, tdp->textureHeader->minLOD, tdp->textureHeader->maxLOD, tdp->textureHeader->LODBias, GX_DISABLE, tdp->textureHeader->edgeLODEnable, GX_ANISO_1); +} + +void TEXGetGXTexObjFromPaletteCI(TEXPalettePtr pal, GXTexObj* to, GXTlutObj* tlo, GXTlut tluts, u32 id) { + GXBool mipMap; + TEXDescriptorPtr tdp; + + tdp = TEXGet(pal, id); + if (tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD) { + mipMap = GX_FALSE; + } else { + mipMap = GX_TRUE; + } + GXInitTlutObj(tlo, tdp->CLUTHeader->data, tdp->CLUTHeader->format, tdp->CLUTHeader->numEntries); + GXInitTexObjCI(to, tdp->textureHeader->data, tdp->textureHeader->width, tdp->textureHeader->height, tdp->textureHeader->format, tdp->textureHeader->wrapS, tdp->textureHeader->wrapT, mipMap, tluts); + GXInitTexObjLOD(to, tdp->textureHeader->minFilter, tdp->textureHeader->magFilter, tdp->textureHeader->minLOD, tdp->textureHeader->maxLOD, tdp->textureHeader->LODBias, GX_DISABLE, tdp->textureHeader->edgeLODEnable, GX_ANISO_1); +} diff --git a/src/dolphin/vi/__vi.h b/src/dolphin/vi/__vi.h new file mode 100644 index 0000000..1132f8c --- /dev/null +++ b/src/dolphin/vi/__vi.h @@ -0,0 +1,37 @@ +#ifndef _DOLPHIN_VI_INTERNAL_H_ +#define _DOLPHIN_VI_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* gpioexi.c */ + +void __VIInitI2C(void); +void __VISetSCL(int value); +int __VIGetSCL(void); +void __VISetSDA(int value); +int __VIGetSDA(void); + +/* i2c.c */ + +int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes); + +/* initphilips.c */ + +void __VIInitPhilips(void); + +/* vi.c */ + +void __VIInit(VITVMode mode); +void __VISetAdjustingValues(s16 x, s16 y); +void __VIGetAdjustingValues(s16* x, s16* y); +void __VIGetCurrentPosition(s16* x, s16* y); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/vi/gpioexi.c b/src/dolphin/vi/gpioexi.c new file mode 100644 index 0000000..db3c8f3 --- /dev/null +++ b/src/dolphin/vi/gpioexi.c @@ -0,0 +1,146 @@ +#include +#include +#include + +#include "__vi.h" + +static u8 shadowGPIOOE; +static u8 shadowGPIOData; + +// prototypes +static void initGpioExi(void); +static void setVideoReset(int value); +static void setI2CEnable(int value); +static int gpioOutput(u8 value); +static int gpioOE(u8 value); +static int gpioOut(u32 addr, u8 value); +static int gpioInput(u8* p); + +void __VIInitI2C(void) { + OSTime time; + + initGpioExi(); + setVideoReset(0); + time = OSGetTime(); + while (OSGetTime() - time < OS_USEC_TO_TICKS(100)) {} + setVideoReset(1); + setI2CEnable(1); +} + +static void initGpioExi(void) { + shadowGPIOOE = 0; + shadowGPIOData = 0; + gpioOutput(shadowGPIOData); + gpioOE(shadowGPIOOE); +} + +void __VISetSCL(int value) { + shadowGPIOOE &= ~2; + if (value == 0) { + shadowGPIOOE |= 2; + } + gpioOE(shadowGPIOOE); +} + +int __VIGetSCL(void) { + u8 value; + + gpioInput(&value); + if (value & 2) { + return 1; + } else { + return 0; + } +} + +void __VISetSDA(int value) { + shadowGPIOOE &= ~1; + if (value == 0) { + shadowGPIOOE |= 1; + } + gpioOE(shadowGPIOOE); +} + +int __VIGetSDA(void) { + u8 value; + + gpioInput(&value); + if (value & 1) { + return 1; + } else { + return 0; + } +} + +static void setVideoReset(int value) { + if (value != 0) { + shadowGPIOData |= 4; + } else { + shadowGPIOData &= ~4; + } + shadowGPIOOE |= 4; + gpioOutput(shadowGPIOData); + gpioOE(shadowGPIOOE); +} + +static void setI2CEnable(int value) { + if (value != 0) { + shadowGPIOData &= ~0x10; + } else { + shadowGPIOData |= 0x10; + } + shadowGPIOOE |= 0x10; + gpioOutput(shadowGPIOData); + gpioOE(shadowGPIOOE); +} + +static int gpioOutput(u8 value) { + return gpioOut(0x800404U, value); +} + +static int gpioOE(u8 value) { + return gpioOut(0x800408U, value); +} + +static int gpioOut(u32 addr, u8 value) { + u32 cmd; + + cmd = (addr | 0x02000000) << 6; + if (EXILock(0, 1, 0) == 0) { + return 0; + } + if (EXISelect(0, 1, 4) == 0) { + EXIUnlock(0); + return 0; + } + + EXIImm(0, &cmd, 4, EXI_WRITE, 0); + EXISync(0); + cmd = value << 24; + EXIImm(0, &cmd, 1, EXI_WRITE, 0); + EXISync(0); + EXIDeselect(0); + EXIUnlock(0); + return 1; +} + +static int gpioInput(u8* p) { + u32 cmd; + + if (EXILock(0, 1, 0) == 0) { + return 0; + } + if (EXISelect(0, 1, 4) == 0) { + EXIUnlock(0); + return 0; + } + cmd = 0x20010100; + EXIImm(0, &cmd, 4, EXI_WRITE, 0); + EXISync(0); + EXIImm(0, &cmd, 1, EXI_READ, 0); + EXISync(0); + EXIDeselect(0); + EXIUnlock(0); + *p = cmd >> 24; + return 1; +} diff --git a/src/dolphin/vi/i2c.c b/src/dolphin/vi/i2c.c new file mode 100644 index 0000000..af048c6 --- /dev/null +++ b/src/dolphin/vi/i2c.c @@ -0,0 +1,105 @@ +#include + +#include "__vi.h" + +static int lastError; + +static int wait4ClkHigh(void) { + int n; + + for (n = 0; n < 1000; n++) { + if (__VIGetSCL() != 0) { + return 1; + } + } + + lastError = 2; + return 0; +} + +static int sendSlaveAddr(u8 slaveAddr) { + int i; + + __VISetSDA(0); + __VISetSCL(0); + + for (i = 0; i < 8; i++) { + if (slaveAddr & 0x80) { + __VISetSDA(1); + } else { + __VISetSDA(0); + } + + __VISetSCL(1); + if (wait4ClkHigh() == 0) { + return 0; + } + + __VISetSCL(0); + slaveAddr <<= 1; + } + + __VISetSDA(1); + __VISetSCL(1); + + if (wait4ClkHigh() == 0) { + return 0; + } + + if (__VIGetSDA() != 0) { + lastError = 1; + return 0; + } + + __VISetSCL(0); + return 1; +} + +int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes) { + s32 i; + u8 data; + + if (sendSlaveAddr(slaveAddr) == 0) { + return 0; + } + + while (nBytes != 0) { + data = *pData++; + for (i = 0; i < 8; i++) { + if (data & 0x80) { + __VISetSDA(1); + } else { + __VISetSDA(0); + } + + __VISetSCL(1); + + if (wait4ClkHigh() == 0) { + return 0; + } + + __VISetSCL(0); + data <<= 1; + } + + __VISetSDA(1); + __VISetSCL(1); + + if (wait4ClkHigh() == 0) { + return 0; + } + + if (nBytes != 1 && __VIGetSDA() != 0) { + lastError = 1; + return 0; + } + + __VISetSCL(0); + nBytes--; + } + + __VISetSDA(0); + __VISetSCL(1); + __VISetSDA(1); + return 1; +} diff --git a/src/dolphin/vi/initphilips.c b/src/dolphin/vi/initphilips.c new file mode 100644 index 0000000..81358ad --- /dev/null +++ b/src/dolphin/vi/initphilips.c @@ -0,0 +1,73 @@ +#include + +#include "__vi.h" + +static u8 ntscRange0[4] = { 0x00, 0x00, 0x19, 0x1D }; + +static u8 ntscRange1[38] = { + 0x2D, 0x76, 0xA5, 0x2A, + 0x2E, 0x2E, 0x00, 0x15, + 0x3F, 0x1F, 0x7C, 0xF0, + 0x21, 0x55, 0x56, 0x67, + 0x58, 0x20, 0xF9, 0x00, + 0xB0, 0x14, 0x80, 0xE8, + 0x10, 0x42, 0x03, 0x03, + 0x05, 0x16, 0x04, 0x16, + 0x18, 0x38, 0x40, 0x00, + 0x00, 0x00 +}; + +static u8 palRange0[4] = { 0x00, 0x00, 0x21, 0x1D }; + +static u8 palRange1[38] = { + 0x0C, 0x7D, 0xAF, 0x23, + 0x35, 0x35, 0x00, 0x06, + 0x2F, 0xCB, 0x8A, 0x09, + 0x2A, 0x55, 0x56, 0x67, + 0x58, 0x20, 0x05, 0x20, + 0xA0, 0x14, 0x80, 0xE8, + 0x10, 0x42, 0x03, 0x03, + 0x05, 0x16, 0x04, 0x16, + 0x18, 0x38, 0x40, 0x00, + 0x00, 0x00 +}; + +static u8 value3a = 19; + +static void send7120Data(u8 *range0, u8 *range1) { + u8 i; + u8 buffer[2]; + + for (i = 0; i < 38; i++) { + buffer[0] = i; + buffer[1] = 0; + __VISendI2CData(0x88, buffer, 2); + } + + for (i = 38; i < 42; i++) { + buffer[0] = i; + buffer[1] = range0[i - 38]; + __VISendI2CData(0x88, buffer, 2); + } + + for (i = 42; i < 58; i++) { + buffer[0] = i; + buffer[1] = 0; + __VISendI2CData(0x88, buffer, 2); + } + + buffer[0] = 0x3A; + buffer[1] = value3a; + __VISendI2CData(0x88, buffer, 2); + + for (i = 90; i < 128; i++) { + buffer[0] = i; + buffer[1] = range1[i - 90]; + __VISendI2CData(0x88, buffer, 2); + } +} + +void __VIInitPhilips(void) { + __VIInitI2C(); + send7120Data(ntscRange0, ntscRange1); +} diff --git a/src/dolphin/vi/vi.c b/src/dolphin/vi/vi.c new file mode 100644 index 0000000..c28ed1c --- /dev/null +++ b/src/dolphin/vi/vi.c @@ -0,0 +1,1307 @@ +#include +#include +#include +#include +#include + +#include "__gx.h" +#include "__os.h" +#include "__vi.h" + +#ifdef DEBUG +const char* __VIVersion = "<< Dolphin SDK - VI\tdebug build: Apr 7 2004 03:55:59 (0x2301) >>"; +#else +const char* __VIVersion = "<< Dolphin SDK - VI\trelease build: Apr 7 2004 04:13:59 (0x2301) >>"; +#endif + +typedef struct { + u8 equ; + u16 acv; + u16 prbOdd; + u16 prbEven; + u16 psbOdd; + u16 psbEven; + u8 bs1; + u8 bs2; + u8 bs3; + u8 bs4; + u16 be1; + u16 be2; + u16 be3; + u16 be4; + u16 nhlines; + u16 hlw; + u8 hsy; + u8 hcs; + u8 hce; + u8 hbe640; + u16 hbs640; + u8 hbeCCIR656; + u16 hbsCCIR656; +} VITiming; + +typedef struct { + u16 DispPosX; + u16 DispPosY; + u16 DispSizeX; + u16 DispSizeY; + u16 AdjustedDispPosX; + u16 AdjustedDispPosY; + u16 AdjustedDispSizeY; + u16 AdjustedPanPosY; + u16 AdjustedPanSizeY; + u16 FBSizeX; + u16 FBSizeY; + u16 PanPosX; + u16 PanPosY; + u16 PanSizeX; + u16 PanSizeY; + VIXFBMode FBMode; + u32 nonInter; + u32 tv; + u8 wordPerLine; + u8 std; + u8 wpl; + u32 bufAddr; + u32 tfbb; + u32 bfbb; + u8 xof; + BOOL black; + BOOL threeD; + u32 rbufAddr; + u32 rtfbb; + u32 rbfbb; + VITiming* timing; +} SomeVIStruct; + +static BOOL IsInitialized; +static volatile u32 retraceCount; + +static volatile u32 flushFlag; +static OSThreadQueue retraceQueue; +static void (*PreCB)(u32); +static void (*PostCB)(u32); +static void (*PositionCallback)(s16, s16); +static u32 encoderType; +static s16 displayOffsetH; +static s16 displayOffsetV; +static volatile u32 changeMode; +static volatile u64 changed; +static volatile u32 shdwChangeMode; +static volatile u16 regs[59]; +static volatile u64 shdwChanged; +static VITiming* CurrTiming; +static u32 CurrTvMode; +static u32 NextBufAddr; +static u32 CurrBufAddr; +static volatile u16 shdwRegs[59]; + +#define MARK_CHANGED(index) (changed |= 1LL << (63 - (index))) + +static VITiming timing[10] = { + { 6, 240, 24, 25, 3, 2, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 6, 240, 24, 24, 4, 4, 12, 12, 12, 12, 520, 520, 520, 520, 526, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 5, 287, 35, 36, 1, 0, 13, 12, 11, 10, 619, 618, 617, 620, 625, 432, 64, 75, 106, 172, 380, 133, 420 }, + { 5, 287, 33, 33, 2, 2, 13, 11, 13, 11, 619, 621, 619, 621, 624, 432, 64, 75, 106, 172, 380, 133, 420 }, + { 6, 240, 24, 25, 3, 2, 16, 15, 14, 13, 518, 517, 516, 519, 525, 429, 64, 78, 112, 162, 373, 122, 412 }, + { 6, 240, 24, 24, 4, 4, 16, 14, 16, 14, 518, 520, 518, 520, 526, 429, 64, 78, 112, 162, 373, 122, 412 }, + { 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 12, 480, 44, 44, 10, 10, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 168, 379, 122, 412 }, + { 6, 241, 24, 25, 1, 0, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 159, 370, 122, 412 }, + { 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 180, 391, 122, 412 } +}; + +static u16 taps[25] = { + 0x01F0, 0x01DC, + 0x01AE, 0x0174, + 0x0129, 0x00DB, + 0x008E, 0x0046, + 0x000C, 0x00E2, + 0x00CB, 0x00C0, + 0x00C4, 0x00CF, + 0x00DE, 0x00EC, + 0x00FC, 0x0008, + 0x000F, 0x0013, + 0x0013, 0x000F, + 0x000C, 0x0008, + 0x0001 +}; + +static SomeVIStruct HorVer; +static u32 FBSet; +static VITiming* timingExtra; + +// prototypes +static u32 getCurrentFieldEvenOdd(void); +VITiming* __VISetExtraTiming(VITiming* t); +void __VIEnableRawPositionInterrupt(s16 x, s16 y, void (*callback)(s16, s16)); +void (*__VIDisableRawPositionInterrupt())(s16, s16); +void __VIDisplayPositionToXY(u32 hct, u32 vct, s16* x, s16* y); +void __VISetLatchMode(u32 mode); +int __VIGetLatch0Position(s16* px, s16* py); +int __VIGetLatch1Position(s16* px, s16* py); +int __VIGetLatchPosition(u32 port, s16* px, s16* py); + + +static u32 getEncoderType(void) { + return 1; +} + +static s32 cntlzd(u64 bit) { + u32 hi; + u32 lo; + s32 value; + + hi = bit >> 32; + lo = bit & 0xFFFFFFFF; + value = __cntlzw(hi); + if (value < 32) { + return value; + } + return __cntlzw(lo) + 32; +} + +static int VISetRegs(void) { + s32 regIndex; + + if (shdwChangeMode != 1 || getCurrentFieldEvenOdd() != 0) { + while (shdwChanged != 0) { + regIndex = cntlzd(shdwChanged); + __VIRegs[regIndex] = shdwRegs[regIndex]; + shdwChanged &= ~((u64)1 << (63 - regIndex)); + } + + shdwChangeMode = 0; + CurrTiming = HorVer.timing; + CurrTvMode = HorVer.tv; + CurrBufAddr = NextBufAddr; + return 1; + } + + return 0; +} + +static void __VIRetraceHandler(__OSInterrupt unused, OSContext* context) { + OSContext exceptionContext; + u16 reg; + u32 inter; +#if DEBUG + static u32 dbgCount; +#endif + + inter = 0; + reg = __VIRegs[0x18]; + if (reg & 0x8000) { + __VIRegs[0x18] = reg & ~0x8000; + inter |= 1; + } + reg = __VIRegs[0x1A]; + if (reg & 0x8000) { + __VIRegs[0x1A] = reg & ~0x8000; + inter |= 2; + } + reg = __VIRegs[0x1C]; + if (reg & 0x8000) { + __VIRegs[0x1C] = reg & ~0x8000; + inter |= 4; + } + reg = __VIRegs[0x1E]; + if (reg & 0x8000) { + __VIRegs[0x1E] = reg & ~0x8000; + inter |= 8; + } + reg = __VIRegs[0x1E]; + + if ((inter & 4) || (inter & 8)) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (PositionCallback != 0) { + s16 x, y; + __VIGetCurrentPosition(&x, &y); + (*PositionCallback)(x, y); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + return; + } + + if (inter == 0) { + ASSERTLINE(955, FALSE); + } + + retraceCount += 1; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (PreCB) { + PreCB(retraceCount); + } + + if (flushFlag != 0) { +#if DEBUG + dbgCount = 0; +#endif + if (VISetRegs() != 0) { + flushFlag = 0; + SIRefreshSamplingRate(); + } + } +#if DEBUG + else if (changed != 0) { + dbgCount++; + if (dbgCount > 60) { + OSReport("Warning: VIFlush() was not called for 60 frames although VI settings were changed\n"); + dbgCount = 0; + } + } +#endif + + if (PostCB) { + OSClearContext(&exceptionContext); + PostCB(retraceCount); + } + + OSWakeupThread(&retraceQueue); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback cb) { + BOOL enabled; + VIRetraceCallback oldcb; + + oldcb = PreCB; + enabled = OSDisableInterrupts(); + PreCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback cb) { + BOOL enabled; + VIRetraceCallback oldcb; + + oldcb = PostCB; + enabled = OSDisableInterrupts(); + PostCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +VITiming* __VISetExtraTiming(VITiming* t) { + VITiming* old = timingExtra; + + timingExtra = t; + return old; +} + +#pragma dont_inline on +static VITiming* getTiming(VITVMode mode) { + switch (mode) { + case VI_TVMODE_NTSC_INT: return &timing[0]; + case VI_TVMODE_NTSC_DS: return &timing[1]; + case VI_TVMODE_PAL_INT: return &timing[2]; + case VI_TVMODE_PAL_DS: return &timing[3]; + case VI_TVMODE_EURGB60_INT: return &timing[0]; + case VI_TVMODE_EURGB60_DS: return &timing[1]; + case VI_TVMODE_MPAL_INT: return &timing[4]; + case VI_TVMODE_MPAL_DS: return &timing[5]; + case VI_TVMODE_NTSC_PROG: return &timing[6]; + case 3: return &timing[7]; + case VI_TVMODE_DEBUG_PAL_INT: return &timing[2]; + case VI_TVMODE_DEBUG_PAL_DS: return &timing[3]; + case 24: return &timing[8]; + case 26: return &timing[9]; + case 29: + case 30: + case 28: + return timingExtra; + default: + return NULL; + } +} +#pragma dont_inline reset + +void __VIInit(VITVMode mode) { + VITiming* tm; + u32 nonInter; + u32 tv; + u32 tvForReg; + volatile u32 a; + u16 hct; + u16 vct; + u32 encoderType; + + encoderType = getEncoderType(); + if (encoderType == 0) { + __VIInitPhilips(); + } + + nonInter = mode & 3; + tv = (u32)mode >> 2; + *(u32*)OSPhysicalToCached(0xCC) = tv; + if (encoderType == 0) { + tv = 3; + } + tm = getTiming(mode); + __VIRegs[1] = 2; + + // why? + for (a = 0; a < 1000; a++) {} + + __VIRegs[1] = 0; + __VIRegs[3] = (u32)tm->hlw; + __VIRegs[2] = tm->hce | (tm->hcs << 8); + __VIRegs[5] = tm->hsy | ((tm->hbe640 & 0x1FF) << 7); + __VIRegs[4] = (tm->hbe640 >> 9) | ((tm->hbs640 & 0xFFFF) << 1); + if (encoderType == 0) { + __VIRegs[0x39] = tm->hbeCCIR656 | 0x8000; + __VIRegs[0x3A] = (u32)tm->hbsCCIR656; + } + __VIRegs[0] = (u32)tm->equ; + __VIRegs[7] = (u32)(tm->prbOdd + (tm->acv * 2) - 2); + __VIRegs[6] = (u32)(tm->psbOdd + 2); + __VIRegs[9] = (u32)(tm->prbEven + (tm->acv * 2) - 2); + __VIRegs[8] = (u32)(tm->psbEven + 2); + __VIRegs[11] = tm->bs1 | (tm->be1 << 5); + __VIRegs[10] = tm->bs3 | (tm->be3 << 5); + __VIRegs[13] = tm->bs2 | (tm->be2 << 5); + __VIRegs[12] = tm->bs4 | (tm->be4 << 5); + __VIRegs[36] = 0x2828; + __VIRegs[27] = 1; + __VIRegs[26] = 0x1001; + hct = tm->hlw + 1; + vct = (tm->nhlines / 2) + 1; + __VIRegs[25] = (u16)(u32)hct; + __VIRegs[24] = vct | 0x1000; + + switch (tv) { + case 1: + case 2: + case 3: + tvForReg = tv; + break; + default: + tvForReg = 0; + } + + if (nonInter == 0 || nonInter == 1) { + __VIRegs[1] = ((nonInter << 2) & 4) | 1 | (tvForReg << 8); + __VIRegs[54] = 0; + return; + } + + __VIRegs[1] = (tvForReg << 8) | 5; + __VIRegs[54] = 1; +} + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define CLAMP(val, min, max) ((val) > (max) ? (max) : (val) < (min) ? (min) : (val)) + +static void AdjustPosition(u16 acv) { + s32 coeff; + s32 frac; + + HorVer.AdjustedDispPosX = CLAMP((s16)HorVer.DispPosX + displayOffsetH, 0, 0x2D0 - HorVer.DispSizeX); + coeff = (HorVer.FBMode == VI_XFBMODE_SF) ? 2 : 1; + frac = HorVer.DispPosY & 1; + HorVer.AdjustedDispPosY = MAX((s16)HorVer.DispPosY + displayOffsetV, frac); + HorVer.AdjustedDispSizeY = HorVer.DispSizeY + + MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) + - MAX((s16)HorVer.DispPosY + (s16)HorVer.DispSizeY + displayOffsetV - (((s16)acv * 2) - frac), 0); + HorVer.AdjustedPanPosY = HorVer.PanPosY + - (MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) / coeff); + HorVer.AdjustedPanSizeY = HorVer.PanSizeY + + (MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) / coeff) + - (MAX((s16)HorVer.DispPosY + (s16)HorVer.DispSizeY + displayOffsetV - (((s16)acv * 2) - frac), 0) / coeff); +} + +static void ImportAdjustingValues(void) { + OSSram* sram = __OSLockSram(); + + ASSERTLINE(1322, sram); + displayOffsetH = sram->displayOffsetH; + displayOffsetV = 0; + __OSUnlockSram(0); +} + +void VIInit(void) { + u16 dspCfg; + u32 value; + u32 tv; + u32 tvInBootrom; + + if (IsInitialized) { + return; + } + + OSRegisterVersion(__VIVersion); + IsInitialized = TRUE; + + encoderType = getEncoderType(); + if (!(__VIRegs[1] & 1)) { + __VIInit(VI_TVMODE_NTSC_INT); + } + + retraceCount = 0; + changed = 0; + shdwChanged = 0; + changeMode = 0; + shdwChangeMode = 0; + flushFlag = 0; + + __VIRegs[39] = taps[0] | ((taps[1] & 0x3F) << 10); + __VIRegs[38] = (taps[1] >> 6) | (taps[2] << 4); + __VIRegs[41] = taps[3] | ((taps[4] & 0x3F) << 10); + __VIRegs[40] = (taps[4] >> 6) | (taps[5] << 4); + __VIRegs[43] = taps[6] | ((taps[7] & 0x3F) << 10); + __VIRegs[42] = (taps[7] >> 6) | (taps[8] << 4); + __VIRegs[45] = taps[9] | (taps[10] << 8); + __VIRegs[44] = taps[11] | (taps[12] << 8); + __VIRegs[47] = taps[13] | (taps[14] << 8); + __VIRegs[46] = taps[15] | (taps[16] << 8); + __VIRegs[49] = taps[17] | (taps[18] << 8); + __VIRegs[48] = taps[19] | (taps[20] << 8); + __VIRegs[51] = taps[21] | (taps[22] << 8); + __VIRegs[50] = taps[23] | (taps[24] << 8); + __VIRegs[56] = 0x280; + ImportAdjustingValues(); + + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + dspCfg = __VIRegs[1]; + HorVer.nonInter = (s32) ((dspCfg >> 2U) & 1); + HorVer.tv = ((u32)(dspCfg) & 0x300) >> 8; + + if (tvInBootrom == VI_PAL && HorVer.tv == VI_NTSC) { + HorVer.tv = VI_EURGB60; + } + + tv = (HorVer.tv == 3) ? 0 : HorVer.tv; + HorVer.timing = getTiming((tv << 2) + HorVer.nonInter); + regs[1] = dspCfg; + + CurrTiming = HorVer.timing; + CurrTvMode = HorVer.tv; + + HorVer.DispSizeX = 640; + HorVer.DispSizeY = CurrTiming->acv * 2; + HorVer.DispPosX = (720 - HorVer.DispSizeX) / 2; + HorVer.DispPosY = 0; + AdjustPosition(CurrTiming->acv); + HorVer.FBSizeX = 640; + HorVer.FBSizeY = CurrTiming->acv * 2; + HorVer.PanPosX = 0; + HorVer.PanPosY = 0; + HorVer.PanSizeX = 640; + HorVer.PanSizeY = CurrTiming->acv * 2; + HorVer.FBMode = 0; + + HorVer.wordPerLine = 40; + HorVer.std = 40; + HorVer.wpl = 40; + HorVer.xof = 0; + HorVer.black = 1; + HorVer.threeD = 0; + OSInitThreadQueue(&retraceQueue); + value = __VIRegs[24]; + value &= ~0x8000; +#if !DEBUG + value = (u16)value; +#endif + __VIRegs[24] = value; + value = __VIRegs[26]; + value = value & ~0x8000; +#if !DEBUG + value = (u16)value; +#endif + __VIRegs[26] = value; + PreCB = NULL; + PostCB = NULL; + __OSSetInterruptHandler(0x18, __VIRetraceHandler); + __OSUnmaskInterrupts(0x80); +} + +void VIWaitForRetrace(void) { + BOOL enabled; + u32 count; + + enabled = OSDisableInterrupts(); + count = retraceCount; + do { + OSSleepThread(&retraceQueue); + } while (count == retraceCount); + OSRestoreInterrupts(enabled); +} + +static void setInterruptRegs(VITiming* tm) { +#if DEBUG + u16 vct, hct; +#else + u16 hct, vct; +#endif + u16 borrow; + + vct = tm->nhlines / 2; + borrow = tm->nhlines % 2; + if (borrow != 0) { + hct = tm->hlw; + } else { + hct = 0; + } + vct++; + hct++; + regs[25] = (u16)(u32)hct; + MARK_CHANGED(25); + regs[24] = vct | 0x1000; + MARK_CHANGED(24); + + vct; // fixes regalloc +} + +static void setPicConfig(u16 fbSizeX, VIXFBMode xfbMode, u16 panPosX, u16 panSizeX, u8* wordPerLine, u8* std, u8* wpl, u8* xof) { + *wordPerLine = (fbSizeX + 15) / 16; + *std = (xfbMode == VI_XFBMODE_SF) ? *wordPerLine : (u8)(*wordPerLine * 2); + *xof = panPosX % 16; + *wpl = (*xof + panSizeX + 15) / 16; + regs[0x24] = *std | (*wpl << 8); + changed |= 0x8000000; +} + +static void setBBIntervalRegs(VITiming* tm) { + u16 val; + + val = tm->bs1 | (tm->be1 << 5); + regs[11] = val; + changed |= 0x10000000000000; + + val = tm->bs3 | (tm->be3 << 5); + regs[10] = val; + changed |= 0x20000000000000; + + val = tm->bs2 | (tm->be2 << 5); + regs[13] = val; + changed |= 0x4000000000000; + + val = tm->bs4 | (tm->be4 << 5); + regs[12] = val; + changed |= (1LL << (63-12)); +} + +static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL threeD) { + u32 scale; + + panSizeX = threeD ? (panSizeX << 1) : panSizeX; + if (panSizeX < dispSizeX) { + scale = (u32)(dispSizeX + (panSizeX << 8) - 1) / dispSizeX; + regs[37] = scale | 0x1000; + changed |= 0x04000000; + regs[56] = (u32)panSizeX; + changed |= 0x80; + } else { + regs[37] = 0x100; + changed |= 0x04000000; + } +} + +static void calcFbbs(u32 bufAddr, u16 panPosX, u16 panPosY, u8 wordPerLine, VIXFBMode xfbMode, u16 dispPosY, u32* tfbb, u32* bfbb) { + u32 bytesPerLine; + u32 xoffInWords; + u32 tmp; + + xoffInWords = (panPosX & ~0xF) >> 4; + bytesPerLine = (wordPerLine & 0xFF) << 5; + *tfbb = bufAddr + (xoffInWords << 5) + (bytesPerLine * panPosY); + *bfbb = (xfbMode == VI_XFBMODE_SF) ? *tfbb : *tfbb + bytesPerLine; + if (dispPosY % 2 == 1) { + tmp = *tfbb; + *tfbb = *bfbb; + *bfbb = tmp; + } + *tfbb &= 0x3FFFFFFF; + *bfbb &= 0x3FFFFFFF; +} + +static void setFbbRegs(SomeVIStruct* HorVer, u32* tfbb, u32* bfbb, u32* rtfbb, u32* rbfbb) { + u32 shifted; + + calcFbbs(HorVer->bufAddr, HorVer->PanPosX, HorVer->AdjustedPanPosY, HorVer->wordPerLine, HorVer->FBMode, HorVer->AdjustedDispPosY, tfbb, bfbb); + if (HorVer->threeD) { + calcFbbs(HorVer->rbufAddr, HorVer->PanPosX, HorVer->AdjustedPanPosY, HorVer->wordPerLine, HorVer->FBMode, HorVer->AdjustedDispPosY, rtfbb, rbfbb); + } + + if (*tfbb < 0x01000000U && *bfbb < 0x01000000U && *rtfbb < 0x01000000U && *rbfbb < 0x01000000U) { + shifted = 0; + } else { + shifted = 1; + } + + if (shifted) { + *tfbb >>= 5; + *bfbb >>= 5; + *rtfbb >>= 5; + *rbfbb >>= 5; + } + + regs[15] = (u16)*tfbb & 0xFFFF; + MARK_CHANGED(15); + regs[14] = (shifted << 12) | ((*tfbb >> 16) | (HorVer->xof << 8)); + MARK_CHANGED(14); + regs[19] = (u16)*bfbb & 0xFFFF; + MARK_CHANGED(19); + regs[18] = (*bfbb >> 16); + MARK_CHANGED(18); + + if (HorVer->threeD) { + regs[17] = (u16)*rtfbb & 0xFFFF; + MARK_CHANGED(17); + regs[16] = *rtfbb >> 16; + MARK_CHANGED(16); + regs[21] = (u16)*rbfbb & 0xFFFF; + MARK_CHANGED(21); + regs[20] = *rbfbb >> 16; + MARK_CHANGED(20); + } +} + +static void setHorizontalRegs(VITiming* tm, u16 dispPosX, u16 dispSizeX) { + u32 hbe; + u32 hbs; + u32 hbeLo; + u32 hbeHi; + + regs[3] = (u16)(u32)tm->hlw; + MARK_CHANGED(3); + regs[2] = tm->hce | (tm->hcs << 8); + MARK_CHANGED(2); + hbe = tm->hbe640 - 40 + dispPosX; + hbs = tm->hbs640 + 40 + dispPosX - (720 - dispSizeX); + hbeLo = hbe & 0x1FF; + hbeHi = hbe >> 9; + regs[5] = tm->hsy | (hbeLo << 7); + MARK_CHANGED(5); + regs[4] = hbeHi | (hbs * 2); + MARK_CHANGED(4); +} + +static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 prbOdd, u16 prbEven, u16 psbOdd, u16 psbEven, BOOL black) { + u16 actualPrbOdd; + u16 actualPrbEven; + u16 actualPsbOdd; + u16 actualPsbEven; + u16 actualAcv; + u16 c; + u16 d; + + if (regs[54] & 1) { + c = 1; + d = 2; + } else { + c = 2; + d = 1; + } + + if ((dispPosY % 2) == 0) { + actualPrbOdd = prbOdd + (d * dispPosY); + actualPsbOdd = psbOdd + (d * (((c * acv) - dispSizeY) - dispPosY)); + actualPrbEven = prbEven + (d * dispPosY); + actualPsbEven = psbEven + (d * (((c * acv) - dispSizeY) - dispPosY)); + } else { + actualPrbOdd = prbEven + (d * dispPosY); + actualPsbOdd = psbEven + (d * (((c * acv) - dispSizeY) - dispPosY)); + actualPrbEven = prbOdd + (d * dispPosY); + actualPsbEven = psbOdd + (d * (((c * acv) - dispSizeY) - dispPosY)); + } + + actualAcv = dispSizeY / c; + + if (black) { + actualPrbOdd += 2 * actualAcv - 2; + actualPsbOdd += 2; + actualPrbEven += 2 * actualAcv - 2; + actualPsbEven += 2; + actualAcv = 0; + } + + regs[0] = equ | (actualAcv << 4); + MARK_CHANGED(0); + regs[7] = (u16)(u32)actualPrbOdd; + MARK_CHANGED(7); + regs[6] = (u16)(u32)actualPsbOdd; + MARK_CHANGED(6); + regs[9] = (u16)(u32)actualPrbEven; + MARK_CHANGED(9); + regs[8] = (u16)(u32)actualPsbEven; + MARK_CHANGED(8); +} + +static void PrintDebugPalCaution(void) { + static u32 message; + + 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* rm) { + VITiming* tm; + u32 regDspCfg; + u32 regClksel; + BOOL enabled; + u32 newNonInter; + u32 tvInBootrom; + u32 tvInGame; + + enabled = OSDisableInterrupts(); + newNonInter = rm->viTVmode & 3; + + if (HorVer.nonInter != newNonInter) { + changeMode = 1; + HorVer.nonInter = newNonInter; + } + + ASSERTMSGLINEV(1926, (rm->viHeight & 1) == 0, + "VIConfigure(): Odd number(%d) is specified to viHeight\n", + rm->viHeight); + +#ifdef DEBUG + if (rm->xFBmode == VI_XFBMODE_DF || newNonInter == VI_TVMODE_NTSC_PROG || newNonInter == 3) { + ASSERTMSGLINEV(1933, rm->xfbHeight == rm->viHeight, + "VIConfigure(): xfbHeight(%d) is not equal to viHeight(%d) when DF XFB mode or progressive mode is specified\n", + rm->xfbHeight, rm->viHeight); + } + + if (rm->xFBmode == VI_XFBMODE_SF && newNonInter != VI_TVMODE_NTSC_PROG && newNonInter != 3) { + ASSERTMSGLINEV(1941, rm->viHeight == rm->xfbHeight * 2, + "VIConfigure(): xfbHeight(%d) is not as twice as viHeight(%d) when SF XFB mode is specified\n", + rm->xfbHeight, rm->viHeight); + } +#endif + + tvInGame = (u32)rm->viTVmode >> 2; + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + + if (tvInGame == VI_DEBUG_PAL) { + PrintDebugPalCaution(); + } + + switch (tvInBootrom) { + case VI_MPAL: + case VI_NTSC: + case 6: + case 7: + if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == 6 || tvInGame == 7) { + break; + } + goto panic; + case VI_PAL: + case VI_EURGB60: + if (tvInGame == VI_PAL || tvInGame == VI_EURGB60) { + break; + } + default: + panic: + OSPanic(__FILE__, 1979, + "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 = rm->viXOrigin; + HorVer.DispPosY = (HorVer.nonInter == 1) ? (u16)(rm->viYOrigin * 2) : rm->viYOrigin; + HorVer.DispSizeX = rm->viWidth; + HorVer.FBSizeX = rm->fbWidth; + HorVer.FBSizeY = rm->xfbHeight; + HorVer.FBMode = rm->xFBmode; + HorVer.PanSizeX = HorVer.FBSizeX; + HorVer.PanSizeY = HorVer.FBSizeY; + HorVer.PanPosX = 0; + HorVer.PanPosY = 0; + HorVer.DispSizeY = (HorVer.nonInter == 2) ? HorVer.PanSizeY : + (HorVer.nonInter == 3) ? HorVer.PanSizeY : + (HorVer.FBMode == VI_XFBMODE_SF) ? (u16)(HorVer.PanSizeY * 2) : + HorVer.PanSizeY; + HorVer.threeD = (HorVer.nonInter == 3) ? TRUE : FALSE; + + tm = getTiming((HorVer.tv << 2) + HorVer.nonInter); + HorVer.timing = tm; + + AdjustPosition(tm->acv); + ASSERTMSGLINEV(2022, rm->viXOrigin <= tm->hlw + 40 - tm->hbe640, + "VIConfigure(): viXOrigin(%d) cannot be greater than %d in this TV mode\n", + rm->viXOrigin, tm->hlw + 40 - tm->hbe640); + ASSERTMSGLINEV(2027, rm->viXOrigin + rm->viWidth >= 680 - tm->hbs640, + "VIConfigure(): viXOrigin + viWidth (%d) cannot be less than %d in this TV mode\n", + rm->viXOrigin + rm->viWidth, 680 - tm->hbs640); + + if (encoderType == 0) { + HorVer.tv = 3; + } + setInterruptRegs(tm); + + regDspCfg = regs[1]; + regClksel = regs[54]; + if (HorVer.nonInter == VI_PROGRESSIVE || HorVer.nonInter == 3) { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(1)) << 2); + regClksel = (((u32)(regClksel)) & ~0x00000001) | (((u32)(1)) << 0); + } else { + OLD_SET_REG_FIELD(2052, regDspCfg, 1, 2, HorVer.nonInter & 1); + regClksel = (((u32)(regClksel)) & ~0x00000001); + } + + OLD_SET_REG_FIELD(2056, regDspCfg, 1, 3, HorVer.threeD); + + if ((HorVer.tv == VI_PAL) || (HorVer.tv == VI_MPAL) || (HorVer.tv == 3)) { + OLD_SET_REG_FIELD(2060, regDspCfg, 2, 8, HorVer.tv); + } else { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000300); + } + + regs[1] = regDspCfg; + regs[54] = (u16)regClksel; + + MARK_CHANGED(1); + MARK_CHANGED(54); + + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + setHorizontalRegs(tm, HorVer.AdjustedDispPosX, HorVer.DispSizeX); + setBBIntervalRegs(tm); + setPicConfig(HorVer.FBSizeX, HorVer.FBMode, HorVer.PanPosX, HorVer.PanSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); + if (FBSet != 0) { + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + } + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.AdjustedDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void VIConfigurePan(u16 xOrg, u16 yOrg, u16 width, u16 height) { + BOOL enabled; + VITiming* tm; + +#if DEBUG + ASSERTMSGLINEV(2118, (xOrg & 1) == 0, + "VIConfigurePan(): Odd number(%d) is specified to xOrg\n", + xOrg); + if (HorVer.FBMode == VI_XFBMODE_DF) { + ASSERTMSGLINEV(2123, (height & 1) == 0, + "VIConfigurePan(): Odd number(%d) is specified to height when DF XFB mode\n", + height); + } +#endif + enabled = OSDisableInterrupts(); + HorVer.PanPosX = xOrg; + HorVer.PanPosY = yOrg; + HorVer.PanSizeX = width; + HorVer.PanSizeY = height; + HorVer.DispSizeY = (HorVer.nonInter == 2) ? HorVer.PanSizeY : + (HorVer.nonInter == 3) ? HorVer.PanSizeY : + (HorVer.FBMode == VI_XFBMODE_SF) ? (u16)(HorVer.PanSizeY * 2) : + HorVer.PanSizeY; + tm = HorVer.timing; + AdjustPosition(tm->acv); + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + setPicConfig(HorVer.FBSizeX, HorVer.FBMode, HorVer.PanPosX, HorVer.PanSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); + if (FBSet != 0) { + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + } + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.DispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void VIFlush(void) { + BOOL enabled; + s32 regIndex; + + enabled = OSDisableInterrupts(); + shdwChangeMode |= changeMode; + changeMode = 0; + shdwChanged |= changed; + + while (changed != 0) { + regIndex = cntlzd(changed); + shdwRegs[regIndex] = regs[regIndex]; + changed &= ~((u64)1 << (63 - regIndex)); + } + + flushFlag = 1; + NextBufAddr = HorVer.bufAddr; + OSRestoreInterrupts(enabled); +} + +void VISetNextFrameBuffer(void* fb) { + BOOL enabled; + + ASSERTMSGLINEV(2216, ((u32)fb & 0x1F) == 0, + "VISetNextFrameBuffer(): Frame buffer address(0x%08x) is not 32byte aligned\n", + fb); + enabled = OSDisableInterrupts(); + HorVer.bufAddr = (u32)fb; + FBSet = 1; + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + OSRestoreInterrupts(enabled); +} + +void* VIGetNextFrameBuffer(void) { + return *(void**)(&NextBufAddr); +} + +void* VIGetCurrentFrameBuffer(void) { + return *(void**)(&CurrBufAddr); +} + +void VISetNextRightFrameBuffer(void* fb) { + BOOL enabled; + + ASSERTMSGLINEV(2284, ((u32)fb & 0x1F) == 0, + "VISetNextFrameBuffer(): Frame buffer address(0x%08x) is not 32byte aligned\n", + fb); + enabled = OSDisableInterrupts(); + HorVer.rbufAddr = (u32)fb; + FBSet = 1; + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + OSRestoreInterrupts(enabled); +} + +void VISetBlack(BOOL black) { + BOOL enabled; + VITiming* tm; + + enabled = OSDisableInterrupts(); + HorVer.black = black; + tm = HorVer.timing; + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.DispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void VISet3D(BOOL threeD) { + BOOL enabled; + u32 reg; + + enabled = OSDisableInterrupts(); + HorVer.threeD = threeD; + reg = regs[1]; + OLD_SET_REG_FIELD(2355, reg, 1, 3, HorVer.threeD); + regs[1] = reg; + MARK_CHANGED(1); + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + OSRestoreInterrupts(enabled); +} + +u32 VIGetRetraceCount(void) { + return retraceCount; +} + +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(void) { + return (getCurrentHalfLine() < CurrTiming->nhlines) ? 1 : 0; +} + +u32 VIGetNextField(void) { + s32 nextField; + BOOL enabled; +#if !DEBUG + u8 unused[4]; +#endif + + enabled = OSDisableInterrupts(); + nextField = getCurrentFieldEvenOdd() ^ 1; + OSRestoreInterrupts(enabled); + return nextField ^ (HorVer.AdjustedDispPosY & 1); +} + +u32 VIGetCurrentLine(void) { + u32 halfLine; + VITiming* tm; + BOOL enabled; + + tm = CurrTiming; + enabled = OSDisableInterrupts(); + halfLine = getCurrentHalfLine(); + OSRestoreInterrupts(enabled); + if (halfLine >= tm->nhlines) { + halfLine -= tm->nhlines; + } + return halfLine >> 1U; +} + +u32 VIGetTvFormat(void) { + u32 format; + BOOL enabled; + + enabled = OSDisableInterrupts(); + + switch (CurrTvMode) { + case VI_NTSC: + case VI_DEBUG: + case 6: + case 7: + format = VI_NTSC; + break; + case VI_PAL: + case VI_DEBUG_PAL: + format = VI_PAL; + break; + case VI_EURGB60: + case VI_MPAL: + format = CurrTvMode; + break; + default: + ASSERTLINE(2527, FALSE); + } + + OSRestoreInterrupts(enabled); + return format; +} + +u32 VIGetScanMode(void) { + u32 scanMode; + BOOL enabled = OSDisableInterrupts(); + + if ((u32)(__VIRegs[54] & 1) == 1) { + scanMode = 2; + } else if (!((__VIRegs[1] & (1 << 2)) >> 2)) { + scanMode = 0; + } else { + scanMode = 1; + } + + OSRestoreInterrupts(enabled); + return scanMode; +} + +u32 VIGetDTVStatus(void) { + u32 dtvStatus; + BOOL enabled = OSDisableInterrupts(); + + dtvStatus = __VIRegs[55] & 3; + OSRestoreInterrupts(enabled); + return dtvStatus & 1; +} + +void __VISetAdjustingValues(s16 x, s16 y) { + BOOL enabled; + VITiming* tm; + + ASSERTMSGLINE(2611, (y & 1) == 0, "__VISetAdjustValues(): y offset should be an even number"); + enabled = OSDisableInterrupts(); + displayOffsetH = x; + displayOffsetV = y; + tm = HorVer.timing; + AdjustPosition(tm->acv); + setHorizontalRegs(tm, HorVer.AdjustedDispPosX, HorVer.DispSizeX); + if (FBSet != 0) { + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + } + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.AdjustedDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void __VIGetAdjustingValues(s16* x, s16* y) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + *x = displayOffsetH; + *y = displayOffsetV; + OSRestoreInterrupts(enabled); +} + +// DEBUG NONMATCHING - wrong reg use, equivalent +void __VIEnableRawPositionInterrupt(s16 x, s16 y, void (*callback)(s16, s16)) { + BOOL enabled; + u32 halfLine; + u32 halfLineOff; + + enabled = OSDisableInterrupts(); + __VIRegs[29] = x + 1U; + __VIRegs[31] = x + 1U; + + if (HorVer.nonInter == 0) { + if (y & 1) { + halfLineOff = CurrTiming->prbEven + ((CurrTiming->equ * 3) + CurrTiming->nhlines); + __VIRegs[30] = (((halfLineOff / 2) + (y / 2)) + 1) | 0x1000; + } else { + halfLineOff = CurrTiming->prbOdd + (CurrTiming->equ * 3); + __VIRegs[28] = (((halfLineOff / 2) + (y / 2)) + 1) | 0x1000; + } + } else if (HorVer.nonInter == 1) { + ASSERTLINE(2702, (y & 1) == 0); + halfLine = CurrTiming->prbOdd + ((CurrTiming->equ * 3)) + y; + __VIRegs[28] = ((halfLine / 2) + 1) | 0x1000; + __VIRegs[30] = (((halfLine + CurrTiming->nhlines) / 2) + 1) | 0x1000; + } else if (HorVer.nonInter == 2) { + halfLine = CurrTiming->prbOdd + ((CurrTiming->equ * 3)) + y; + __VIRegs[28] = (halfLine + 1) | 0x1000; + __VIRegs[30] = 0; + } + + PositionCallback = callback; + OSRestoreInterrupts(enabled); +} + +void (*__VIDisableRawPositionInterrupt())(s16, s16) { + BOOL enabled; + void (*old)(s16, s16); + + enabled = OSDisableInterrupts(); + __VIRegs[28] = 0; + __VIRegs[30] = 0; + + old = PositionCallback; + PositionCallback = 0; + OSRestoreInterrupts(enabled); + return old; +} + +void __VIDisplayPositionToXY(u32 hct, u32 vct, s16* x, s16* y) { + u32 halfLine = ((vct - 1) << 1) + ((hct - 1) / CurrTiming->hlw); + + if (HorVer.nonInter == VI_INTERLACE) { + if (halfLine < CurrTiming->nhlines) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); + } + } else { + halfLine -= CurrTiming->nhlines; + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbEven) { + *y = -1; + } else { + *y = (s16)(((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1) + 1); + } + } + } else if (HorVer.nonInter == VI_NON_INTERLACE) { + if (halfLine >= CurrTiming->nhlines) { + halfLine -= CurrTiming->nhlines; + } + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); + } + } else if (HorVer.nonInter == VI_PROGRESSIVE) { + if (halfLine < CurrTiming->nhlines) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)(halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd); + } + } else { + halfLine -= CurrTiming->nhlines; + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + *y = -1; + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbEven) { + *y = -1; + } else + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1); + } + } + + *x = (s16)(hct - 1); +} + +void __VIGetCurrentPosition(s16* x, s16* y) { + u32 hcount, vcount; + GetCurrentDisplayPosition(&hcount, &vcount); + __VIDisplayPositionToXY(hcount, vcount, x, y); +} + +void __VISetLatchMode(u32 mode) { + u32 reg; + + reg = __VIRegs[1]; + OLD_SET_REG_FIELD(2834, reg, 2, 4, mode); + OLD_SET_REG_FIELD(2835, reg, 2, 6, mode); + __VIRegs[1] = reg; +} + +#pragma dont_inline on +int __VIGetLatch0Position(s16* px, s16* py) { + u32 hcount; + u32 vcount; + + if (((__VIRegs[32] & 0x8000) >> 15) != 0) { + vcount = __VIRegs[32] & 0x7FF; + hcount = __VIRegs[33] & 0x7FF; + __VIRegs[32] = 0; + __VIRegs[33] = 0; + __VIDisplayPositionToXY(hcount, vcount, px, py); + return 1; + } + + *px = *py = -1; + return 0; +} +#pragma dont_inline reset + +#pragma dont_inline on +int __VIGetLatch1Position(s16* px, s16* py) { + u32 hcount; + u32 vcount; + + if (((__VIRegs[34] & 0x8000) >> 15) != 0) { + vcount = __VIRegs[34] & 0x7FF; + hcount = __VIRegs[35] & 0x7FF; + __VIRegs[34] = 0; + __VIRegs[35] = 0; + __VIDisplayPositionToXY(hcount, vcount, px, py); + return 1; + } + + *px = *py = -1; + return 0; +} +#pragma dont_inline reset + +int __VIGetLatchPosition(u32 port, s16* px, s16* py) { + if (port == 0) { + return __VIGetLatch0Position(px, py); + } else { + return __VIGetLatch1Position(px, py); + } +} From 0261f5a6da65b3a2ef10d3773bc9ffe0826ca258 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sun, 4 May 2025 21:29:15 -0400 Subject: [PATCH 2/2] too many things to list. Creating as a backup so i have an option if i mess my repo up --- .vscode/settings.json | 18 +- config/GGVE78/splits.txt | 400 +- configure.py | 810 ++- .../include FROM PIKMIN2/GX/GXBump.h | 46 + .../include FROM PIKMIN2/GX/GXData.h | 259 + .../include FROM PIKMIN2/GX/GXEnum.h | 2411 +++++++ .../include FROM PIKMIN2/GX/GXFifo.h | 211 + .../include FROM PIKMIN2/GX/GXFrameBuffer.h | 85 + .../include FROM PIKMIN2/GX/GXGeometry.h | 56 + .../include FROM PIKMIN2/GX/GXHardware.h | 129 + .../include FROM PIKMIN2/GX/GXLight.h | 67 + .../include FROM PIKMIN2/GX/GXMisc.h | 88 + .../include FROM PIKMIN2/GX/GXPerf.h | 39 + .../include FROM PIKMIN2/GX/GXPixel.h | 42 + .../include FROM PIKMIN2/GX/GXTev.h | 44 + .../include FROM PIKMIN2/GX/GXTexture.h | 88 + .../include FROM PIKMIN2/GX/GXTransform.h | 59 + .../include FROM PIKMIN2/GX/GXTypes.h | 158 + .../include FROM PIKMIN2/OS/OSAlarm.h | 55 + .../include FROM PIKMIN2/OS/OSAlloc.h | 56 + .../include FROM PIKMIN2/OS/OSBootInfo.h | 53 + .../include FROM PIKMIN2/OS/OSCache.h | 61 + .../include FROM PIKMIN2/OS/OSContext.h | 209 + .../include FROM PIKMIN2/OS/OSError.h | 51 + .../include FROM PIKMIN2/OS/OSException.h | 78 + .../include FROM PIKMIN2/OS/OSExpansion.h | 93 + .../include FROM PIKMIN2/OS/OSFastCast.h | 113 + .../include FROM PIKMIN2/OS/OSFont.h | 88 + .../include FROM PIKMIN2/OS/OSInterrupt.h | 160 + .../include FROM PIKMIN2/OS/OSMemory.h | 40 + .../include FROM PIKMIN2/OS/OSMessage.h | 51 + .../include FROM PIKMIN2/OS/OSModule.h | 112 + .../include FROM PIKMIN2/OS/OSMutex.h | 48 + .../include FROM PIKMIN2/OS/OSReset.h | 92 + .../include FROM PIKMIN2/OS/OSSerial.h | 89 + .../include FROM PIKMIN2/OS/OSThread.h | 263 + .../include FROM PIKMIN2/OS/OSUtil.h | 104 + .../include FROM PIKMIN2/PPCArch.h | 100 + .../include FROM PIKMIN2/__start.h | 61 + .../include FROM PIKMIN2/card.h | 399 ++ .../include FROM PIKMIN2/db.h | 34 + .../include FROM PIKMIN2/dsp.h | 95 + .../include FROM PIKMIN2/dvd.h | 204 + .../include FROM PIKMIN2/exi.h | 79 + .../include FROM PIKMIN2/gba.h | 101 + .../include FROM PIKMIN2/gd.h | 109 + .../include FROM PIKMIN2/gx.h | 31 + .../include FROM PIKMIN2/hw_regs.h | 243 + .../include FROM PIKMIN2/mtx.h | 85 + .../include FROM PIKMIN2/os.h | 273 + .../include FROM PIKMIN2/pad.h | 112 + .../include FROM PIKMIN2/print.h | 17 + .../include FROM PIKMIN2/rand.h | 26 + .../include FROM PIKMIN2/si.h | 87 + .../include FROM PIKMIN2/stl.h | 78 + .../include FROM PIKMIN2/vec.h | 42 + .../include FROM PIKMIN2/vi.h | 208 + .../src/MSL_C/MSL_Common/FILE_POS.C | 170 + .../src/MSL_C/MSL_Common/alloc.c | 588 ++ .../src/MSL_C/MSL_Common/ansi_files.c | 163 + .../src/MSL_C/MSL_Common/arith.c | 180 + .../src/MSL_C/MSL_Common/buffer_io.c | 48 + .../src/MSL_C/MSL_Common/ctype.c | 184 + .../src/MSL_C/MSL_Common/direct_io.c | 163 + .../src/MSL_C/MSL_Common/errno.c | 3 + .../src/MSL_C/MSL_Common/extras.c | 705 ++ .../src/MSL_C/MSL_Common/file_io.c | 78 + .../src/MSL_C/MSL_Common/float.c | 10 + .../src/MSL_C/MSL_Common/locale.c | 33 + .../src/MSL_C/MSL_Common/mbstring.c | 252 + .../src/MSL_C/MSL_Common/mem.c | 113 + .../src/MSL_C/MSL_Common/mem_funcs.c | 236 + .../src/MSL_C/MSL_Common/misc_io.c | 45 + .../src/MSL_C/MSL_Common/printf.c | 1310 ++++ .../src/MSL_C/MSL_Common/rand.c | 19 + .../src/MSL_C/MSL_Common/scanf.c | 710 ++ .../src/MSL_C/MSL_Common/string.c | 345 + .../src/MSL_C/MSL_Common/strtold.c | 603 ++ .../src/MSL_C/MSL_Common/strtoul.c | 393 + .../src/MSL_C/MSL_Common/wchar_io.c | 117 + .../Math/Double_precision/e_asin.c | 118 + .../Math/Double_precision/e_atan2.c | 144 + .../Math/Double_precision/e_exp.c | 162 + .../Math/Double_precision/e_fmod.c | 168 + .../Math/Double_precision/e_log.c | 163 + .../Math/Double_precision/e_log10.c | 100 + .../Math/Double_precision/e_pow.c | 409 ++ .../Math/Double_precision/e_rem_pio2.c | 182 + .../Math/Double_precision/e_sqrt.c | 468 ++ .../Math/Double_precision/k_cos.c | 94 + .../Math/Double_precision/k_rem_pio2.c | 354 + .../Math/Double_precision/k_sin.c | 81 + .../Math/Double_precision/k_tan.c | 181 + .../Math/Double_precision/s_atan.c | 144 + .../Math/Double_precision/s_ceil.c | 91 + .../Math/Double_precision/s_copysign.c | 31 + .../Math/Double_precision/s_cos.c | 83 + .../Math/Double_precision/s_floor.c | 90 + .../Math/Double_precision/s_frexp.c | 59 + .../Math/Double_precision/s_ldexp.c | 63 + .../Math/Double_precision/s_modf.c | 80 + .../Math/Double_precision/s_sin.c | 83 + .../Math/Double_precision/s_tan.c | 74 + .../Math/Double_precision/w_asin.c | 22 + .../Math/Double_precision/w_atan2.c | 22 + .../Math/Double_precision/w_exp.c | 22 + .../Math/Double_precision/w_fmod.c | 22 + .../Math/Double_precision/w_log10.c | 22 + .../Math/Double_precision/w_pow.c | 22 + .../Math/Double_precision/w_sqrt.c | 22 + .../src/MSL_C/MSL_Common_Embedded/ansi_fp.c | 835 +++ .../src/MSL_C/PPC_EABI/abort_exit.c | 85 + .../PPC_EABI/critical_regions.gamecube.c | 38 + .../src/MSL_C/PPC_EABI/math_ppc.c | 956 +++ .../src/MSL_C/PPC_EABI/uart_console_io_gcn.c | 71 + .../src/OdemuExi2/DebuggerDriver.c | 416 ++ .../src/Runtime/CPlusLibPPC.cp | 62 + .../src/Runtime/GCN_mem_alloc.c | 35 + .../src/Runtime/Gecko_ExceptionPPC.cp | 1052 +++ .../src/Runtime/NMWException.cp | 277 + .../src/Runtime/__init_cpp_exceptions.cpp | 46 + .../src/Runtime/__mem.c | 83 + .../src/Runtime/__va_arg.c | 48 + .../src/Runtime/global_destructor_chain.c | 33 + dolphin sdk not yet linked/src/Runtime/ptmf.c | 106 + .../src/Runtime/runtime.c | 1035 +++ .../src/TRK_MINNOW_DOLPHIN/CircleBuffer.c | 101 + .../MWCriticalSection_gc.cpp | 33 + .../src/TRK_MINNOW_DOLPHIN/MWTrace.c | 8 + .../src/TRK_MINNOW_DOLPHIN/UDP_Stubs.c | 56 + .../src/TRK_MINNOW_DOLPHIN/__exception.s | 476 ++ .../src/TRK_MINNOW_DOLPHIN/ddh/main.c | 176 + .../src/TRK_MINNOW_DOLPHIN/dispatch.c | 66 + .../src/TRK_MINNOW_DOLPHIN/dolphin_trk.c | 371 + .../src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c | 248 + .../src/TRK_MINNOW_DOLPHIN/flush_cache.c | 27 + .../src/TRK_MINNOW_DOLPHIN/gdev/main.c | 175 + .../src/TRK_MINNOW_DOLPHIN/main_TRK.c | 22 + .../src/TRK_MINNOW_DOLPHIN/mainloop.c | 89 + .../src/TRK_MINNOW_DOLPHIN/mem_TRK.c | 85 + .../src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c | 254 + .../src/TRK_MINNOW_DOLPHIN/msg.c | 12 + .../src/TRK_MINNOW_DOLPHIN/msgbuf.c | 473 ++ .../src/TRK_MINNOW_DOLPHIN/msghndlr.c | 633 ++ .../src/TRK_MINNOW_DOLPHIN/mslsupp.c | 142 + .../src/TRK_MINNOW_DOLPHIN/mutex_TRK.c | 19 + .../src/TRK_MINNOW_DOLPHIN/notify.c | 42 + .../src/TRK_MINNOW_DOLPHIN/nubevent.c | 99 + .../src/TRK_MINNOW_DOLPHIN/nubinit.c | 90 + .../src/TRK_MINNOW_DOLPHIN/serpoll.c | 108 + .../src/TRK_MINNOW_DOLPHIN/support.c | 303 + .../src/TRK_MINNOW_DOLPHIN/targcont.c | 14 + .../src/TRK_MINNOW_DOLPHIN/target_options.c | 19 + .../src/TRK_MINNOW_DOLPHIN/targimpl.c | 1341 ++++ .../src/TRK_MINNOW_DOLPHIN/targsupp.c | 20 + .../src/TRK_MINNOW_DOLPHIN/usr_put.c | 145 + dolphin sdk not yet linked/src/ai/ai.c | 581 ++ .../src/amcstubs/AmcExi2Stubs.c | 50 + dolphin sdk not yet linked/src/ar/ar.c | 428 ++ dolphin sdk not yet linked/src/ar/arq.c | 191 + .../src/ax}/AX.c | 0 .../src/ax}/AXAlloc.c | 0 .../src/ax}/AXAux.c | 0 .../src/ax}/AXCL.c | 0 .../src/ax}/AXComp.c | 0 .../src/ax}/AXOut.c | 0 .../src/ax}/AXProf.c | 0 .../src/ax}/AXSPB.c | 0 dolphin sdk not yet linked/src/ax/AXVPB.c | 966 +++ .../src/ax}/DSPCode.c | 0 .../src/ax}/__ax.h | 0 .../src/axfx}/__axfx.h | 0 .../src/axfx}/axfx.c | 0 .../src/axfx}/chorus.c | 0 .../src/axfx}/delay.c | 0 .../src/axfx/reverb_hi.c | 735 ++ .../src/axfx}/reverb_hi_4ch.c | 0 .../src/axfx}/reverb_std.c | 0 dolphin sdk not yet linked/src/base/PPCArch.c | 513 ++ .../src/card/CARDBios.c | 769 ++ .../src/card/CARDBlock.c | 156 + .../src/card/CARDCheck.c | 353 + .../src/card/CARDCreate.c | 131 + .../src/card}/CARDDelete.c | 0 dolphin sdk not yet linked/src/card/CARDDir.c | 106 + .../src/card/CARDFormat.c | 137 + .../src/card/CARDMount.c | 407 ++ dolphin sdk not yet linked/src/card/CARDNet.c | 34 + .../src/card/CARDOpen.c | 172 + .../src/card/CARDRdwr.c | 119 + .../src/card/CARDRead.c | 158 + .../src/card/CARDStat.c | 163 + .../src/card}/CARDStatEx.c | 0 .../src/card/CARDUnlock.c | 433 ++ .../src/card/CARDWrite.c | 139 + dolphin sdk not yet linked/src/db/db.c | 91 + dolphin sdk not yet linked/src/dsp/dsp.c | 79 + .../src/dsp/dsp_debug.c | 17 + dolphin sdk not yet linked/src/dsp/dsp_task.c | 212 + dolphin sdk not yet linked/src/dvd/dvd.c | 1603 +++++ dolphin sdk not yet linked/src/dvd/dvdFatal.c | 31 + dolphin sdk not yet linked/src/dvd/dvderror.c | 55 + dolphin sdk not yet linked/src/dvd/dvdfs.c | 585 ++ .../src/dvd/dvdidutils.c | 56 + dolphin sdk not yet linked/src/dvd/dvdlow.c | 618 ++ dolphin sdk not yet linked/src/dvd/dvdqueue.c | 110 + dolphin sdk not yet linked/src/dvd/fstload.c | 94 + dolphin sdk not yet linked/src/exi/EXIBios.c | 817 +++ dolphin sdk not yet linked/src/exi/EXIUart.c | 206 + dolphin sdk not yet linked/src/gba/GBA.c | 116 + dolphin sdk not yet linked/src/gba/GBARead.c | 42 + dolphin sdk not yet linked/src/gba/GBAWrite.c | 42 + dolphin sdk not yet linked/src/gba/GBAXfer.c | 118 + dolphin sdk not yet linked/src/gd/GDBase.c | 61 + .../src/gd/GDGeometry.c | 200 + dolphin sdk not yet linked/src/gx/GXAttr.c | 573 ++ dolphin sdk not yet linked/src/gx/GXBump.c | 240 + .../src/gx/GXDisplayList.c | 18 + dolphin sdk not yet linked/src/gx/GXFifo.c | 550 ++ .../src/gx/GXFrameBuf.c | 529 ++ .../src/gx/GXGeometry.c | 155 + dolphin sdk not yet linked/src/gx/GXInit.c | 590 ++ dolphin sdk not yet linked/src/gx/GXLight.c | 463 ++ dolphin sdk not yet linked/src/gx/GXMisc.c | 477 ++ dolphin sdk not yet linked/src/gx/GXPerf.c | 424 ++ dolphin sdk not yet linked/src/gx/GXPixel.c | 312 + dolphin sdk not yet linked/src/gx/GXTev.c | 450 ++ dolphin sdk not yet linked/src/gx/GXTexture.c | 1036 +++ .../src/gx/GXTransform.c | 452 ++ .../src}/mix/mix.c | 0 dolphin sdk not yet linked/src/mtx/mtx.c | 893 +++ dolphin sdk not yet linked/src/mtx/mtx44.c | 321 + dolphin sdk not yet linked/src/mtx/mtxvec.c | 159 + dolphin sdk not yet linked/src/mtx/vec.c | 303 + .../src/odenotstub/odenotstub.c | 7 + dolphin sdk not yet linked/src/os/OS.c | 759 ++ dolphin sdk not yet linked/src/os/OSAlarm.c | 241 + dolphin sdk not yet linked/src/os/OSAlloc.c | 321 + dolphin sdk not yet linked/src/os/OSArena.c | 44 + .../src/os/OSAudioSystem.c | 118 + dolphin sdk not yet linked/src/os/OSCache.c | 741 ++ dolphin sdk not yet linked/src/os/OSContext.c | 709 ++ dolphin sdk not yet linked/src/os/OSError.c | 224 + .../src/os}/OSExec.c | 0 dolphin sdk not yet linked/src/os/OSFont.c | 593 ++ .../src/os/OSInterrupt.c | 478 ++ dolphin sdk not yet linked/src/os/OSLink.c | 26 + dolphin sdk not yet linked/src/os/OSMemory.c | 260 + dolphin sdk not yet linked/src/os/OSMessage.c | 113 + dolphin sdk not yet linked/src/os/OSMutex.c | 150 + dolphin sdk not yet linked/src/os/OSReboot.c | 172 + dolphin sdk not yet linked/src/os/OSReset.c | 223 + dolphin sdk not yet linked/src/os/OSResetSW.c | 97 + dolphin sdk not yet linked/src/os/OSRtc.c | 477 ++ .../src/os}/OSSemaphore.c | 0 dolphin sdk not yet linked/src/os/OSSync.c | 40 + dolphin sdk not yet linked/src/os/OSThread.c | 634 ++ dolphin sdk not yet linked/src/os/OSTime.c | 142 + .../src/os/__ppc_eabi_init.cpp | 88 + dolphin sdk not yet linked/src/os/__start.c | 214 + dolphin sdk not yet linked/src/pad/Pad.c | 912 +++ dolphin sdk not yet linked/src/pad/Padclamp.c | 188 + dolphin sdk not yet linked/src/si/SIBios.c | 894 +++ .../src/si/SISamplingRate.c | 76 + dolphin sdk not yet linked/src/thp/THPAudio.c | 165 + dolphin sdk not yet linked/src/thp/THPDec.c | 2330 ++++++ dolphin sdk not yet linked/src/vi/vi.c | 1201 ++++ .../MSL/MSL_C++/MSL_Common/Include/exception | 6 - .../MSL_C++/MSL_Common/Include/exception.h | 27 - .../MSL/MSL_C++/MSL_Common/Include/new | 6 - .../MSL/MSL_C++/MSL_Common/Include/new.h | 40 - .../MSL/MSL_C/MSL_Common/Include/cctype | 6 - .../MSL/MSL_C/MSL_Common/Include/climits | 6 - .../MSL/MSL_C/MSL_Common/Include/cmath | 66 - .../MSL/MSL_C/MSL_Common/Include/cstdarg | 8 - .../MSL/MSL_C/MSL_Common/Include/cstddef | 6 - .../MSL/MSL_C/MSL_Common/Include/cstdlib | 6 - .../MSL/MSL_C/MSL_Common/Include/cstring | 14 - .../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 | 39 - .../MSL/MSL_C/MSL_Common/Include/size_t.h | 12 - .../MSL/MSL_C/MSL_Common/Include/stdarg.h | 6 - .../MSL/MSL_C/MSL_Common/Include/stdio.h | 27 - .../MSL/MSL_C/MSL_Common/Include/stdlib.h | 21 - .../MSL/MSL_C/MSL_Common/Include/string.h | 28 - .../MSL/MSL_C/MSL_Common/Include/time.h | 6 - .../MSL/MSL_C/MSL_Common/Include/va_list.h | 6 - .../MSL_C++/MSL_Common/Include/algorithm.h | 103 + .../MSL_C++/MSL_Common/Include/msl_memory.h | 34 + .../MSL_C/MSL_Common/FILE_POS.h | 20 + .../MSL_C/MSL_Common/alloc.h | 8 + .../MSL_C/MSL_Common/ansi_files.h | 88 + .../MSL_C/MSL_Common/ansi_fp.h | 40 + .../MSL_C/MSL_Common/arith.h | 25 + .../MSL_C/MSL_Common/critical_regions.h | 32 + .../MSL_C/MSL_Common/ctype_api.h | 34 + .../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/math_api.h | 65 + .../MSL_C/MSL_Common/mbstring.h | 21 + .../MSL_C/MSL_Common/mem_funcs.h | 16 + .../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/stdio_api.h | 38 + .../MSL_C/MSL_Common/strtold.h | 17 + .../MSL_C/MSL_Common/strtoul.h | 21 + .../MSL_C/MSL_Common/wchar_io.h | 9 + .../MSL_C/PPC_EABI/math_ppc.h | 11 + .../MetroTRK/custconn/CircleBuffer.h | 24 + .../MetroTRK/custconn/cc_gdev.h | 23 + .../PowerPC_EABI_Support/MetroTRK/dstypes.h | 27 + .../PowerPC_EABI_Support/MetroTRK/memmap.h | 15 + .../PowerPC_EABI_Support/MetroTRK/ppc_reg.h | 242 + include/PowerPC_EABI_Support/MetroTRK/trk.h | 201 + .../PowerPC_EABI_Support/MetroTRK/trkenum.h | 201 + .../PowerPC_EABI_Support/MetroTRK/trktypes.h | 147 + .../Runtime/Gecko_ExceptionPPC.h | 229 + .../PowerPC_EABI_Support/Runtime/MWCPlusLib.h | 34 + .../Runtime/NMWException.h | 45 + .../Runtime/__init_cpp_exceptions.h | 17 + include/PowerPC_EABI_Support/Runtime/__mem.h | 15 + .../Runtime/__ppc_eabi_linker.h | 72 + .../PowerPC_EABI_Support/Runtime/__va_arg.h | 12 + .../PowerPC_EABI_Support/Runtime/exception.h | 38 + .../Runtime/global_destructor_chain.h | 36 + .../PowerPC_EABI_Support/Runtime/runtime.h | 19 + include/bink/bink.h | 6 +- include/cmath.h | 12 + include/dolphin.h | 38 +- include/dolphin/AmcExi2Stubs.h | 33 + include/dolphin/card.h | 96 +- 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/types.h | 22 +- include/libc/stddef.h | 2 +- include/libc/stdio.h | 2 +- include/libc/stdlib.h | 6 +- include/libc/string.h | 3 +- include/libc/wchar.h | 4 +- include/rwsdk/rwplcore.h | 4 +- include/types.h | 1 + src/Dolphin/ai/ai.c | 638 ++ src/Dolphin/amcstubs/AmcExi2Stubs.c | 50 + src/Dolphin/ar/ar.c | 428 ++ src/Dolphin/ar/arq.c | 191 + src/SB/Core/gc/iFMV.h | 2 +- src/SB/Core/gc/iTRC.cpp | 6 +- src/SB/Core/gc/iWad.cpp | 12 +- src/SB/Core/gc/iWad.h | 4 + src/SB/Core/x/xCamera.cpp | 3 +- src/SB/Core/x/xEnt.h | 2 +- src/SB/Core/x/xString.h | 3 +- src/SB/Core/x/xWad1.cpp | 2 +- src/SB/Core/x/xWad1.h | 2 + src/SB/Core/x/xWad2.h | 6 +- src/SB/Core/x/xWad3.h | 2 +- src/SB/Core/x/xWad5.h | 2 +- src/SB/Core/x/xpkrsvc.h | 2 +- src/SB/Game/zCameraTweak.h | 2 +- src/SB/Game/zWad3.cpp | 2 + src/dolphin/G2D/G2D.c | 721 -- src/dolphin/ai/src/ai.c | 411 -- src/dolphin/am/src/__am.h | 39 - src/dolphin/am/src/am.c | 322 - src/dolphin/amcnotstub/src/amcnotstub.c | 8 - src/dolphin/amcstubs/src/AmcExi2Stubs.c | 29 - src/dolphin/ar/src/__ar.h | 24 - src/dolphin/ar/src/ar.c | 446 -- src/dolphin/ar/src/arq.c | 253 - src/dolphin/ax/src/AXVPB.c | 1412 ---- src/dolphin/axart/src/axart.c | 330 - src/dolphin/axart/src/axart3d.c | 317 - src/dolphin/axart/src/axartcents.c | 280 - src/dolphin/axart/src/axartenv.c | 33 - src/dolphin/axart/src/axartlfo.c | 85 - src/dolphin/axart/src/axartlpf.c | 42 - src/dolphin/axart/src/axartsound.c | 122 - src/dolphin/axfx/src/reverb_hi.c | 890 --- src/dolphin/base/src/PPCArch.c | 292 - src/dolphin/base/src/PPCPm.c | 34 - src/dolphin/card/src/CARDBios.c | 856 --- src/dolphin/card/src/CARDBlock.c | 160 - src/dolphin/card/src/CARDCheck.c | 343 - src/dolphin/card/src/CARDCreate.c | 126 - src/dolphin/card/src/CARDDir.c | 89 - src/dolphin/card/src/CARDErase.c | 102 - src/dolphin/card/src/CARDFormat.c | 137 - src/dolphin/card/src/CARDMount.c | 394 - src/dolphin/card/src/CARDNet.c | 138 - src/dolphin/card/src/CARDOpen.c | 174 - src/dolphin/card/src/CARDProgram.c | 100 - src/dolphin/card/src/CARDRaw.c | 82 - src/dolphin/card/src/CARDRdwr.c | 105 - src/dolphin/card/src/CARDRead.c | 174 - src/dolphin/card/src/CARDRename.c | 70 - src/dolphin/card/src/CARDStat.c | 156 - src/dolphin/card/src/CARDUnlock.c | 436 -- src/dolphin/card/src/CARDWrite.c | 123 - src/dolphin/card/src/__card.h | 104 - src/dolphin/db/src/db.c | 59 - src/dolphin/demo/DEMOAVX.c | 118 - src/dolphin/demo/DEMOFont.c | 773 -- src/dolphin/demo/DEMOInit.c | 432 -- src/dolphin/demo/DEMOPad.c | 120 - src/dolphin/demo/DEMOPuts.c | 403 -- src/dolphin/demo/DEMOStats.c | 416 -- src/dolphin/demo/DEMOWin.c | 981 --- src/dolphin/demo/__demo.h | 11 - src/dolphin/dsp/__dsp.h | 27 - src/dolphin/dsp/dsp.c | 185 - src/dolphin/dsp/dsp_debug.c | 9 - src/dolphin/dsp/dsp_perf.c | 0 src/dolphin/dsp/dsp_task.c | 362 - src/dolphin/dtk/dtk.c | 483 -- src/dolphin/dvd/__dvd.h | 53 - src/dolphin/dvd/dvd.c | 1854 ----- src/dolphin/dvd/dvdFatal.c | 95 - src/dolphin/dvd/dvderror.c | 77 - src/dolphin/dvd/dvdfs.c | 630 -- src/dolphin/dvd/dvdidutils.c | 97 - src/dolphin/dvd/dvdlow.c | 534 -- src/dolphin/dvd/dvdqueue.c | 172 - src/dolphin/dvd/fstload.c | 86 - src/dolphin/exi/EXIAd16.c | 101 - src/dolphin/exi/EXIBios.c | 870 --- src/dolphin/exi/EXIUart.c | 194 - src/dolphin/fileCache/fileCache.c | 145 - src/dolphin/gd/GDBase.c | 45 - src/dolphin/gd/GDFile.c | 64 - src/dolphin/gd/GDGeometry.c | 430 -- src/dolphin/gd/GDIndirect.c | 270 - src/dolphin/gd/GDLight.c | 206 - src/dolphin/gd/GDPixel.c | 118 - src/dolphin/gd/GDTev.c | 159 - src/dolphin/gd/GDTexture.c | 104 - src/dolphin/gd/GDTransform.c | 127 - src/dolphin/gx/GXAttr.c | 641 -- src/dolphin/gx/GXBump.c | 308 - src/dolphin/gx/GXDisplayList.c | 99 - src/dolphin/gx/GXDraw.c | 551 -- src/dolphin/gx/GXFifo.c | 629 -- src/dolphin/gx/GXFrameBuf.c | 603 -- src/dolphin/gx/GXGeometry.c | 156 - src/dolphin/gx/GXInit.c | 570 -- src/dolphin/gx/GXLight.c | 573 -- src/dolphin/gx/GXMisc.c | 481 -- src/dolphin/gx/GXPerf.c | 431 -- src/dolphin/gx/GXPixel.c | 334 - src/dolphin/gx/GXSave.c | 528 -- src/dolphin/gx/GXStubs.c | 5 - src/dolphin/gx/GXTev.c | 470 -- src/dolphin/gx/GXTexture.c | 1315 ---- src/dolphin/gx/GXTransform.c | 608 -- src/dolphin/gx/GXVerifRAS.c | 640 -- src/dolphin/gx/GXVerifXF.c | 1002 --- src/dolphin/gx/GXVerify.c | 368 - src/dolphin/gx/GXVert.c | 86 - src/dolphin/gx/__gx.h | 592 -- src/dolphin/hio/hio.c | 409 -- src/dolphin/mcc/fio.c | 1290 ---- src/dolphin/mcc/mcc.c | 1417 ---- src/dolphin/mcc/tty.c | 260 - src/dolphin/mtx/mtx.c | 1197 ---- src/dolphin/mtx/mtx44.c | 888 --- src/dolphin/mtx/mtx44vec.c | 247 - src/dolphin/mtx/mtxstack.c | 108 - src/dolphin/mtx/mtxvec.c | 204 - src/dolphin/mtx/psmtx.c | 336 - src/dolphin/mtx/quat.c | 486 -- src/dolphin/mtx/vec.c | 344 - src/dolphin/odemustubs/odemustubs.c | 34 - src/dolphin/odenotstub/odenotstub.c | 8 - src/dolphin/os/OS.c | 631 -- src/dolphin/os/OSAddress.c | 39 - src/dolphin/os/OSAlarm.c | 297 - src/dolphin/os/OSAlloc.c | 609 -- src/dolphin/os/OSArena.c | 52 - src/dolphin/os/OSAudioSystem.c | 117 - src/dolphin/os/OSCache.c | 643 -- src/dolphin/os/OSContext.c | 626 -- src/dolphin/os/OSError.c | 215 - src/dolphin/os/OSFatal.c | 246 - src/dolphin/os/OSFont.c | 751 -- src/dolphin/os/OSInterrupt.c | 509 -- src/dolphin/os/OSLink.c | 528 -- src/dolphin/os/OSMemory.c | 235 - src/dolphin/os/OSMessage.c | 70 - src/dolphin/os/OSMutex.c | 256 - src/dolphin/os/OSReboot.c | 39 - src/dolphin/os/OSReset.c | 248 - src/dolphin/os/OSResetSW.c | 120 - src/dolphin/os/OSRtc.c | 513 -- src/dolphin/os/OSStopwatch.c | 55 - src/dolphin/os/OSSync.c | 33 - src/dolphin/os/OSThread.c | 875 --- src/dolphin/os/OSTime.c | 200 - src/dolphin/os/OSTimer.c | 140 - src/dolphin/os/OSUtf.c | 6341 ----------------- src/dolphin/os/__os.h | 130 - src/dolphin/os/src/init/__ppc_eabi_init.c | 85 - src/dolphin/os/src/init/__start.c | 265 - src/dolphin/os/time.dolphin.c | 16 - src/dolphin/pad/Pad.c | 841 --- src/dolphin/pad/Padclamp.c | 152 - src/dolphin/perf/__perf.h | 14 - src/dolphin/perf/perf.c | 467 -- src/dolphin/perf/perfdraw.c | 695 -- src/dolphin/seq/seq.c | 468 -- src/dolphin/si/SIBios.c | 798 --- src/dolphin/si/SISamplingRate.c | 125 - src/dolphin/si/SISteering.c | 120 - src/dolphin/si/SISteeringAuto.c | 130 - src/dolphin/si/SISteeringXfer.c | 118 - src/dolphin/si/__si.h | 21 - src/dolphin/sp/sp.c | 404 -- src/dolphin/stub.c | 80 - src/dolphin/support/HTable.c | 68 - src/dolphin/support/List.c | 92 - src/dolphin/support/Tree.c | 106 - src/dolphin/support/string.c | 74 - src/dolphin/syn/__syn.h | 67 - src/dolphin/syn/syn.c | 180 - src/dolphin/syn/synctrl.c | 510 -- src/dolphin/syn/synenv.c | 185 - src/dolphin/syn/synlfo.c | 102 - src/dolphin/syn/synmix.c | 274 - src/dolphin/syn/synpitch.c | 340 - src/dolphin/syn/synsample.c | 241 - src/dolphin/syn/synvoice.c | 82 - src/dolphin/syn/synwt.c | 21 - src/dolphin/texPalette/texPalette.c | 112 - src/dolphin/vi/__vi.h | 37 - src/dolphin/vi/gpioexi.c | 146 - src/dolphin/vi/i2c.c | 105 - src/dolphin/vi/initphilips.c | 73 - src/dolphin/vi/vi.c | 1307 ---- 567 files changed, 65616 insertions(+), 65752 deletions(-) create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXBump.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXData.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXEnum.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXFifo.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXFrameBuffer.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXGeometry.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXHardware.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXLight.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXMisc.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXPerf.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXPixel.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTev.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTexture.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTransform.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTypes.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSAlarm.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSAlloc.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSBootInfo.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSCache.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSContext.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSError.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSException.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSExpansion.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSFastCast.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSFont.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSInterrupt.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMemory.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMessage.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSModule.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMutex.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSReset.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSSerial.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSThread.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSUtil.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/PPCArch.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/__start.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/card.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/db.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/dsp.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/dvd.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/exi.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/gba.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/gd.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/gx.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/hw_regs.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/mtx.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/os.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/pad.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/print.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/rand.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/si.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/stl.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/vec.h create mode 100644 dolphin sdk not yet linked/include FROM PIKMIN2/vi.h create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/FILE_POS.C create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/alloc.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/ansi_files.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/arith.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/buffer_io.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/ctype.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/direct_io.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/errno.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/extras.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/file_io.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/float.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/locale.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/mbstring.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/mem.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/mem_funcs.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/misc_io.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/printf.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/rand.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/scanf.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/string.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/strtold.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/strtoul.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common/wchar_io.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/ansi_fp.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/PPC_EABI/abort_exit.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/PPC_EABI/critical_regions.gamecube.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/PPC_EABI/math_ppc.c create mode 100644 dolphin sdk not yet linked/src/MSL_C/PPC_EABI/uart_console_io_gcn.c create mode 100644 dolphin sdk not yet linked/src/OdemuExi2/DebuggerDriver.c create mode 100644 dolphin sdk not yet linked/src/Runtime/CPlusLibPPC.cp create mode 100644 dolphin sdk not yet linked/src/Runtime/GCN_mem_alloc.c create mode 100644 dolphin sdk not yet linked/src/Runtime/Gecko_ExceptionPPC.cp create mode 100644 dolphin sdk not yet linked/src/Runtime/NMWException.cp create mode 100644 dolphin sdk not yet linked/src/Runtime/__init_cpp_exceptions.cpp create mode 100644 dolphin sdk not yet linked/src/Runtime/__mem.c create mode 100644 dolphin sdk not yet linked/src/Runtime/__va_arg.c create mode 100644 dolphin sdk not yet linked/src/Runtime/global_destructor_chain.c create mode 100644 dolphin sdk not yet linked/src/Runtime/ptmf.c create mode 100644 dolphin sdk not yet linked/src/Runtime/runtime.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/CircleBuffer.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/MWCriticalSection_gc.cpp create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/MWTrace.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/UDP_Stubs.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/__exception.s create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/ddh/main.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dispatch.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dolphin_trk.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/flush_cache.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/gdev/main.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/main_TRK.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mainloop.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mem_TRK.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msg.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msgbuf.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msghndlr.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mslsupp.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mutex_TRK.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/notify.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/nubevent.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/nubinit.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/serpoll.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/support.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targcont.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/target_options.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targimpl.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targsupp.c create mode 100644 dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/usr_put.c create mode 100644 dolphin sdk not yet linked/src/ai/ai.c create mode 100644 dolphin sdk not yet linked/src/amcstubs/AmcExi2Stubs.c create mode 100644 dolphin sdk not yet linked/src/ar/ar.c create mode 100644 dolphin sdk not yet linked/src/ar/arq.c rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/AX.c (100%) rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/AXAlloc.c (100%) rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/AXAux.c (100%) rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/AXCL.c (100%) rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/AXComp.c (100%) rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/AXOut.c (100%) rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/AXProf.c (100%) rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/AXSPB.c (100%) create mode 100644 dolphin sdk not yet linked/src/ax/AXVPB.c rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/DSPCode.c (100%) rename {src/dolphin/ax/src => dolphin sdk not yet linked/src/ax}/__ax.h (100%) rename {src/dolphin/axfx/src => dolphin sdk not yet linked/src/axfx}/__axfx.h (100%) rename {src/dolphin/axfx/src => dolphin sdk not yet linked/src/axfx}/axfx.c (100%) rename {src/dolphin/axfx/src => dolphin sdk not yet linked/src/axfx}/chorus.c (100%) rename {src/dolphin/axfx/src => dolphin sdk not yet linked/src/axfx}/delay.c (100%) create mode 100644 dolphin sdk not yet linked/src/axfx/reverb_hi.c rename {src/dolphin/axfx/src => dolphin sdk not yet linked/src/axfx}/reverb_hi_4ch.c (100%) rename {src/dolphin/axfx/src => dolphin sdk not yet linked/src/axfx}/reverb_std.c (100%) create mode 100644 dolphin sdk not yet linked/src/base/PPCArch.c create mode 100644 dolphin sdk not yet linked/src/card/CARDBios.c create mode 100644 dolphin sdk not yet linked/src/card/CARDBlock.c create mode 100644 dolphin sdk not yet linked/src/card/CARDCheck.c create mode 100644 dolphin sdk not yet linked/src/card/CARDCreate.c rename {src/dolphin/card/src => dolphin sdk not yet linked/src/card}/CARDDelete.c (100%) create mode 100644 dolphin sdk not yet linked/src/card/CARDDir.c create mode 100644 dolphin sdk not yet linked/src/card/CARDFormat.c create mode 100644 dolphin sdk not yet linked/src/card/CARDMount.c create mode 100644 dolphin sdk not yet linked/src/card/CARDNet.c create mode 100644 dolphin sdk not yet linked/src/card/CARDOpen.c create mode 100644 dolphin sdk not yet linked/src/card/CARDRdwr.c create mode 100644 dolphin sdk not yet linked/src/card/CARDRead.c create mode 100644 dolphin sdk not yet linked/src/card/CARDStat.c rename {src/dolphin/card/src => dolphin sdk not yet linked/src/card}/CARDStatEx.c (100%) create mode 100644 dolphin sdk not yet linked/src/card/CARDUnlock.c create mode 100644 dolphin sdk not yet linked/src/card/CARDWrite.c create mode 100644 dolphin sdk not yet linked/src/db/db.c create mode 100644 dolphin sdk not yet linked/src/dsp/dsp.c create mode 100644 dolphin sdk not yet linked/src/dsp/dsp_debug.c create mode 100644 dolphin sdk not yet linked/src/dsp/dsp_task.c create mode 100644 dolphin sdk not yet linked/src/dvd/dvd.c create mode 100644 dolphin sdk not yet linked/src/dvd/dvdFatal.c create mode 100644 dolphin sdk not yet linked/src/dvd/dvderror.c create mode 100644 dolphin sdk not yet linked/src/dvd/dvdfs.c create mode 100644 dolphin sdk not yet linked/src/dvd/dvdidutils.c create mode 100644 dolphin sdk not yet linked/src/dvd/dvdlow.c create mode 100644 dolphin sdk not yet linked/src/dvd/dvdqueue.c create mode 100644 dolphin sdk not yet linked/src/dvd/fstload.c create mode 100644 dolphin sdk not yet linked/src/exi/EXIBios.c create mode 100644 dolphin sdk not yet linked/src/exi/EXIUart.c create mode 100644 dolphin sdk not yet linked/src/gba/GBA.c create mode 100644 dolphin sdk not yet linked/src/gba/GBARead.c create mode 100644 dolphin sdk not yet linked/src/gba/GBAWrite.c create mode 100644 dolphin sdk not yet linked/src/gba/GBAXfer.c create mode 100644 dolphin sdk not yet linked/src/gd/GDBase.c create mode 100644 dolphin sdk not yet linked/src/gd/GDGeometry.c create mode 100644 dolphin sdk not yet linked/src/gx/GXAttr.c create mode 100644 dolphin sdk not yet linked/src/gx/GXBump.c create mode 100644 dolphin sdk not yet linked/src/gx/GXDisplayList.c create mode 100644 dolphin sdk not yet linked/src/gx/GXFifo.c create mode 100644 dolphin sdk not yet linked/src/gx/GXFrameBuf.c create mode 100644 dolphin sdk not yet linked/src/gx/GXGeometry.c create mode 100644 dolphin sdk not yet linked/src/gx/GXInit.c create mode 100644 dolphin sdk not yet linked/src/gx/GXLight.c create mode 100644 dolphin sdk not yet linked/src/gx/GXMisc.c create mode 100644 dolphin sdk not yet linked/src/gx/GXPerf.c create mode 100644 dolphin sdk not yet linked/src/gx/GXPixel.c create mode 100644 dolphin sdk not yet linked/src/gx/GXTev.c create mode 100644 dolphin sdk not yet linked/src/gx/GXTexture.c create mode 100644 dolphin sdk not yet linked/src/gx/GXTransform.c rename {src/dolphin => dolphin sdk not yet linked/src}/mix/mix.c (100%) create mode 100644 dolphin sdk not yet linked/src/mtx/mtx.c create mode 100644 dolphin sdk not yet linked/src/mtx/mtx44.c create mode 100644 dolphin sdk not yet linked/src/mtx/mtxvec.c create mode 100644 dolphin sdk not yet linked/src/mtx/vec.c create mode 100644 dolphin sdk not yet linked/src/odenotstub/odenotstub.c create mode 100644 dolphin sdk not yet linked/src/os/OS.c create mode 100644 dolphin sdk not yet linked/src/os/OSAlarm.c create mode 100644 dolphin sdk not yet linked/src/os/OSAlloc.c create mode 100644 dolphin sdk not yet linked/src/os/OSArena.c create mode 100644 dolphin sdk not yet linked/src/os/OSAudioSystem.c create mode 100644 dolphin sdk not yet linked/src/os/OSCache.c create mode 100644 dolphin sdk not yet linked/src/os/OSContext.c create mode 100644 dolphin sdk not yet linked/src/os/OSError.c rename {src/dolphin/os/src => dolphin sdk not yet linked/src/os}/OSExec.c (100%) create mode 100644 dolphin sdk not yet linked/src/os/OSFont.c create mode 100644 dolphin sdk not yet linked/src/os/OSInterrupt.c create mode 100644 dolphin sdk not yet linked/src/os/OSLink.c create mode 100644 dolphin sdk not yet linked/src/os/OSMemory.c create mode 100644 dolphin sdk not yet linked/src/os/OSMessage.c create mode 100644 dolphin sdk not yet linked/src/os/OSMutex.c create mode 100644 dolphin sdk not yet linked/src/os/OSReboot.c create mode 100644 dolphin sdk not yet linked/src/os/OSReset.c create mode 100644 dolphin sdk not yet linked/src/os/OSResetSW.c create mode 100644 dolphin sdk not yet linked/src/os/OSRtc.c rename {src/dolphin/os/src => dolphin sdk not yet linked/src/os}/OSSemaphore.c (100%) create mode 100644 dolphin sdk not yet linked/src/os/OSSync.c create mode 100644 dolphin sdk not yet linked/src/os/OSThread.c create mode 100644 dolphin sdk not yet linked/src/os/OSTime.c create mode 100644 dolphin sdk not yet linked/src/os/__ppc_eabi_init.cpp create mode 100644 dolphin sdk not yet linked/src/os/__start.c create mode 100644 dolphin sdk not yet linked/src/pad/Pad.c create mode 100644 dolphin sdk not yet linked/src/pad/Padclamp.c create mode 100644 dolphin sdk not yet linked/src/si/SIBios.c create mode 100644 dolphin sdk not yet linked/src/si/SISamplingRate.c create mode 100644 dolphin sdk not yet linked/src/thp/THPAudio.c create mode 100644 dolphin sdk not yet linked/src/thp/THPDec.c create mode 100644 dolphin sdk not yet linked/src/vi/vi.c delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h 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/cmath 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/cstdlib delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring 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/size_t.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/stdio.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.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/time.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h create mode 100644 include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/algorithm.h create mode 100644 include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/msl_memory.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h create mode 100644 include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h create mode 100644 include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h create mode 100644 include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h create mode 100644 include/PowerPC_EABI_Support/MetroTRK/dstypes.h create mode 100644 include/PowerPC_EABI_Support/MetroTRK/memmap.h create mode 100644 include/PowerPC_EABI_Support/MetroTRK/ppc_reg.h create mode 100644 include/PowerPC_EABI_Support/MetroTRK/trk.h create mode 100644 include/PowerPC_EABI_Support/MetroTRK/trkenum.h create mode 100644 include/PowerPC_EABI_Support/MetroTRK/trktypes.h create mode 100644 include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h create mode 100644 include/PowerPC_EABI_Support/Runtime/MWCPlusLib.h create mode 100644 include/PowerPC_EABI_Support/Runtime/NMWException.h create mode 100644 include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h create mode 100644 include/PowerPC_EABI_Support/Runtime/__mem.h create mode 100644 include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h create mode 100644 include/PowerPC_EABI_Support/Runtime/__va_arg.h create mode 100644 include/PowerPC_EABI_Support/Runtime/exception.h create mode 100644 include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h create mode 100644 include/PowerPC_EABI_Support/Runtime/runtime.h create mode 100644 include/cmath.h create mode 100644 include/dolphin/AmcExi2Stubs.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 src/Dolphin/ai/ai.c create mode 100644 src/Dolphin/amcstubs/AmcExi2Stubs.c create mode 100644 src/Dolphin/ar/ar.c create mode 100644 src/Dolphin/ar/arq.c delete mode 100644 src/dolphin/G2D/G2D.c delete mode 100644 src/dolphin/ai/src/ai.c delete mode 100644 src/dolphin/am/src/__am.h delete mode 100644 src/dolphin/am/src/am.c delete mode 100644 src/dolphin/amcnotstub/src/amcnotstub.c delete mode 100644 src/dolphin/amcstubs/src/AmcExi2Stubs.c delete mode 100644 src/dolphin/ar/src/__ar.h delete mode 100644 src/dolphin/ar/src/ar.c delete mode 100644 src/dolphin/ar/src/arq.c delete mode 100644 src/dolphin/ax/src/AXVPB.c delete mode 100644 src/dolphin/axart/src/axart.c delete mode 100644 src/dolphin/axart/src/axart3d.c delete mode 100644 src/dolphin/axart/src/axartcents.c delete mode 100644 src/dolphin/axart/src/axartenv.c delete mode 100644 src/dolphin/axart/src/axartlfo.c delete mode 100644 src/dolphin/axart/src/axartlpf.c delete mode 100644 src/dolphin/axart/src/axartsound.c delete mode 100644 src/dolphin/axfx/src/reverb_hi.c delete mode 100644 src/dolphin/base/src/PPCArch.c delete mode 100644 src/dolphin/base/src/PPCPm.c delete mode 100644 src/dolphin/card/src/CARDBios.c delete mode 100644 src/dolphin/card/src/CARDBlock.c delete mode 100644 src/dolphin/card/src/CARDCheck.c delete mode 100644 src/dolphin/card/src/CARDCreate.c delete mode 100644 src/dolphin/card/src/CARDDir.c delete mode 100644 src/dolphin/card/src/CARDErase.c delete mode 100644 src/dolphin/card/src/CARDFormat.c delete mode 100644 src/dolphin/card/src/CARDMount.c delete mode 100644 src/dolphin/card/src/CARDNet.c delete mode 100644 src/dolphin/card/src/CARDOpen.c delete mode 100644 src/dolphin/card/src/CARDProgram.c delete mode 100644 src/dolphin/card/src/CARDRaw.c delete mode 100644 src/dolphin/card/src/CARDRdwr.c delete mode 100644 src/dolphin/card/src/CARDRead.c delete mode 100644 src/dolphin/card/src/CARDRename.c delete mode 100644 src/dolphin/card/src/CARDStat.c delete mode 100644 src/dolphin/card/src/CARDUnlock.c delete mode 100644 src/dolphin/card/src/CARDWrite.c delete mode 100644 src/dolphin/card/src/__card.h delete mode 100644 src/dolphin/db/src/db.c delete mode 100644 src/dolphin/demo/DEMOAVX.c delete mode 100644 src/dolphin/demo/DEMOFont.c delete mode 100644 src/dolphin/demo/DEMOInit.c delete mode 100644 src/dolphin/demo/DEMOPad.c delete mode 100644 src/dolphin/demo/DEMOPuts.c delete mode 100644 src/dolphin/demo/DEMOStats.c delete mode 100644 src/dolphin/demo/DEMOWin.c delete mode 100644 src/dolphin/demo/__demo.h delete mode 100644 src/dolphin/dsp/__dsp.h delete mode 100644 src/dolphin/dsp/dsp.c delete mode 100644 src/dolphin/dsp/dsp_debug.c delete mode 100644 src/dolphin/dsp/dsp_perf.c delete mode 100644 src/dolphin/dsp/dsp_task.c delete mode 100644 src/dolphin/dtk/dtk.c delete mode 100644 src/dolphin/dvd/__dvd.h delete mode 100644 src/dolphin/dvd/dvd.c delete mode 100644 src/dolphin/dvd/dvdFatal.c delete mode 100644 src/dolphin/dvd/dvderror.c delete mode 100644 src/dolphin/dvd/dvdfs.c delete mode 100644 src/dolphin/dvd/dvdidutils.c delete mode 100644 src/dolphin/dvd/dvdlow.c delete mode 100644 src/dolphin/dvd/dvdqueue.c delete mode 100644 src/dolphin/dvd/fstload.c delete mode 100644 src/dolphin/exi/EXIAd16.c delete mode 100644 src/dolphin/exi/EXIBios.c delete mode 100644 src/dolphin/exi/EXIUart.c delete mode 100644 src/dolphin/fileCache/fileCache.c delete mode 100644 src/dolphin/gd/GDBase.c delete mode 100644 src/dolphin/gd/GDFile.c delete mode 100644 src/dolphin/gd/GDGeometry.c delete mode 100644 src/dolphin/gd/GDIndirect.c delete mode 100644 src/dolphin/gd/GDLight.c delete mode 100644 src/dolphin/gd/GDPixel.c delete mode 100644 src/dolphin/gd/GDTev.c delete mode 100644 src/dolphin/gd/GDTexture.c delete mode 100644 src/dolphin/gd/GDTransform.c delete mode 100644 src/dolphin/gx/GXAttr.c delete mode 100644 src/dolphin/gx/GXBump.c delete mode 100644 src/dolphin/gx/GXDisplayList.c delete mode 100644 src/dolphin/gx/GXDraw.c delete mode 100644 src/dolphin/gx/GXFifo.c delete mode 100644 src/dolphin/gx/GXFrameBuf.c delete mode 100644 src/dolphin/gx/GXGeometry.c delete mode 100644 src/dolphin/gx/GXInit.c delete mode 100644 src/dolphin/gx/GXLight.c delete mode 100644 src/dolphin/gx/GXMisc.c delete mode 100644 src/dolphin/gx/GXPerf.c delete mode 100644 src/dolphin/gx/GXPixel.c delete mode 100644 src/dolphin/gx/GXSave.c delete mode 100644 src/dolphin/gx/GXStubs.c delete mode 100644 src/dolphin/gx/GXTev.c delete mode 100644 src/dolphin/gx/GXTexture.c delete mode 100644 src/dolphin/gx/GXTransform.c delete mode 100644 src/dolphin/gx/GXVerifRAS.c delete mode 100644 src/dolphin/gx/GXVerifXF.c delete mode 100644 src/dolphin/gx/GXVerify.c delete mode 100644 src/dolphin/gx/GXVert.c delete mode 100644 src/dolphin/gx/__gx.h delete mode 100644 src/dolphin/hio/hio.c delete mode 100644 src/dolphin/mcc/fio.c delete mode 100644 src/dolphin/mcc/mcc.c delete mode 100644 src/dolphin/mcc/tty.c delete mode 100644 src/dolphin/mtx/mtx.c delete mode 100644 src/dolphin/mtx/mtx44.c delete mode 100644 src/dolphin/mtx/mtx44vec.c delete mode 100644 src/dolphin/mtx/mtxstack.c delete mode 100644 src/dolphin/mtx/mtxvec.c delete mode 100644 src/dolphin/mtx/psmtx.c delete mode 100644 src/dolphin/mtx/quat.c delete mode 100644 src/dolphin/mtx/vec.c delete mode 100644 src/dolphin/odemustubs/odemustubs.c delete mode 100644 src/dolphin/odenotstub/odenotstub.c delete mode 100644 src/dolphin/os/OS.c delete mode 100644 src/dolphin/os/OSAddress.c delete mode 100644 src/dolphin/os/OSAlarm.c delete mode 100644 src/dolphin/os/OSAlloc.c delete mode 100644 src/dolphin/os/OSArena.c delete mode 100644 src/dolphin/os/OSAudioSystem.c delete mode 100644 src/dolphin/os/OSCache.c delete mode 100644 src/dolphin/os/OSContext.c delete mode 100644 src/dolphin/os/OSError.c delete mode 100644 src/dolphin/os/OSFatal.c delete mode 100644 src/dolphin/os/OSFont.c delete mode 100644 src/dolphin/os/OSInterrupt.c delete mode 100644 src/dolphin/os/OSLink.c delete mode 100644 src/dolphin/os/OSMemory.c delete mode 100644 src/dolphin/os/OSMessage.c delete mode 100644 src/dolphin/os/OSMutex.c delete mode 100644 src/dolphin/os/OSReboot.c delete mode 100644 src/dolphin/os/OSReset.c delete mode 100644 src/dolphin/os/OSResetSW.c delete mode 100644 src/dolphin/os/OSRtc.c delete mode 100644 src/dolphin/os/OSStopwatch.c delete mode 100644 src/dolphin/os/OSSync.c delete mode 100644 src/dolphin/os/OSThread.c delete mode 100644 src/dolphin/os/OSTime.c delete mode 100644 src/dolphin/os/OSTimer.c delete mode 100644 src/dolphin/os/OSUtf.c delete mode 100644 src/dolphin/os/__os.h delete mode 100644 src/dolphin/os/src/init/__ppc_eabi_init.c delete mode 100644 src/dolphin/os/src/init/__start.c delete mode 100644 src/dolphin/os/time.dolphin.c delete mode 100644 src/dolphin/pad/Pad.c delete mode 100644 src/dolphin/pad/Padclamp.c delete mode 100644 src/dolphin/perf/__perf.h delete mode 100644 src/dolphin/perf/perf.c delete mode 100644 src/dolphin/perf/perfdraw.c delete mode 100644 src/dolphin/seq/seq.c delete mode 100644 src/dolphin/si/SIBios.c delete mode 100644 src/dolphin/si/SISamplingRate.c delete mode 100644 src/dolphin/si/SISteering.c delete mode 100644 src/dolphin/si/SISteeringAuto.c delete mode 100644 src/dolphin/si/SISteeringXfer.c delete mode 100644 src/dolphin/si/__si.h delete mode 100644 src/dolphin/sp/sp.c delete mode 100644 src/dolphin/stub.c delete mode 100644 src/dolphin/support/HTable.c delete mode 100644 src/dolphin/support/List.c delete mode 100644 src/dolphin/support/Tree.c delete mode 100644 src/dolphin/support/string.c delete mode 100644 src/dolphin/syn/__syn.h delete mode 100644 src/dolphin/syn/syn.c delete mode 100644 src/dolphin/syn/synctrl.c delete mode 100644 src/dolphin/syn/synenv.c delete mode 100644 src/dolphin/syn/synlfo.c delete mode 100644 src/dolphin/syn/synmix.c delete mode 100644 src/dolphin/syn/synpitch.c delete mode 100644 src/dolphin/syn/synsample.c delete mode 100644 src/dolphin/syn/synvoice.c delete mode 100644 src/dolphin/syn/synwt.c delete mode 100644 src/dolphin/texPalette/texPalette.c delete mode 100644 src/dolphin/vi/__vi.h delete mode 100644 src/dolphin/vi/gpioexi.c delete mode 100644 src/dolphin/vi/i2c.c delete mode 100644 src/dolphin/vi/initphilips.c delete mode 100644 src/dolphin/vi/vi.c diff --git a/.vscode/settings.json b/.vscode/settings.json index 4b05bcf..4743809 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,7 +32,23 @@ "math.h": "c", "os.h": "c", "va_list.h": "c", - "fake_tgmath.h": "c" + "fake_tgmath.h": "c", + "gxenum.h": "c", + "__axfx.h": "c", + "new": "cpp", + "dolphinstring.h": "c", + "string.c": "cpp", + "__card.h": "c", + "card.h": "c", + "exi.h": "c", + "osutil.h": "c", + "ai.h": "c", + "cmath.h": "c", + "hw_regs.h": "c", + "gxstruct.h": "c", + "ossemaphore.h": "c", + "osexec.h": "c", + "amcexi2stubs.h": "c" }, // Disable C/C++ IntelliSense, use clangd instead "C_Cpp.intelliSenseEngine": "default", diff --git a/config/GGVE78/splits.txt b/config/GGVE78/splits.txt index 205ef13..5df42ca 100644 --- a/config/GGVE78/splits.txt +++ b/config/GGVE78/splits.txt @@ -920,280 +920,280 @@ ios.cpp: .data start:0x803BA2B8 end:0x803BA2C8 .sdata start:0x804B0530 end:0x804B0538 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/abort_exit.c: +Dolphin/MSL_C/PPC_EABI/abort_exit.c: .text start:0x802A2000 end:0x802A218C .bss start:0x80461CF8 end:0x80461DF8 .sbss start:0x804B1C20 end:0x804B1C30 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c: +Dolphin/MSL_C/MSL_Common/alloc.c: .text start:0x802A218C end:0x802A388C .rodata start:0x8037DE40 end:0x8037DE58 .bss start:0x80461DF8 end:0x80461E30 .sbss start:0x804B1C30 end:0x804B1C38 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/errno.c: +Dolphin/MSL_C/MSL_Common/errno.c: .sbss start:0x804B1C38 end:0x804B1C40 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c: +Dolphin/MSL_C/MSL_Common/ansi_files.c: .text start:0x802A388C end:0x802A39A4 .data start:0x803BA2C8 end:0x803BA408 .bss start:0x80461E30 end:0x80462130 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c: +Dolphin/MSL_C/MSL_Common_Embedded/ansi_fp.c: .text start:0x802A39A4 end:0x802A6F80 .rodata start:0x8037DE58 end:0x8037DF38 .data start:0x803BA408 end:0x803BA570 .sdata2 start:0x804B4268 end:0x804B4298 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c: +Dolphin/MSL_C/MSL_Common/arith.c: .text start:0x802A6F80 end:0x802A6F90 bsearch.c: .text start:0x802A6F90 end:0x802A707C -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/buffer_io.c: +Dolphin/MSL_C/MSL_Common/buffer_io.c: .text start:0x802A707C end:0x802A7174 -PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/critical_regions.gamecube.c: +Dolphin/MSL_C/PPC_EABI/critical_regions.gamecube.c: .text start:0x802A7174 end:0x802A7180 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c: +Dolphin/MSL_C/MSL_Common/ctype.c: .text start:0x802A7180 end:0x802A71A4 .data start:0x803BA570 end:0x803BA870 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c: +Dolphin/MSL_C/MSL_Common/locale.c: .rodata start:0x8037DF38 end:0x8037DF40 .data start:0x803BA870 end:0x803BA8A8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c: +Dolphin/MSL_C/MSL_Common/direct_io.c: .text start:0x802A71A4 end:0x802A752C -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c: +Dolphin/MSL_C/MSL_Common/file_io.c: .text start:0x802A752C end:0x802A7820 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.C: +Dolphin/MSL_C/MSL_Common/FILE_POS.C: .text start:0x802A7820 end:0x802A7BE0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c: +Dolphin/MSL_C/MSL_Common/mbstring.c: .text start:0x802A7BE0 end:0x802A7F04 .sdata2 start:0x804B4298 end:0x804B42A0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c: +Dolphin/MSL_C/MSL_Common/mem.c: .text start:0x802A7F04 end:0x802A8074 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c: +Dolphin/MSL_C/MSL_Common/mem_funcs.c: .text start:0x802A8074 end:0x802A8344 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/misc_io.c: +Dolphin/MSL_C/MSL_Common/misc_io.c: .text start:0x802A8344 end:0x802A8354 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c: +Dolphin/MSL_C/MSL_Common/printf.c: .text start:0x802A8354 end:0x802AA454 .rodata start:0x8037DF40 end:0x8037DF68 .data start:0x803BA8A8 end:0x803BAAD8 .sdata start:0x804B0538 end:0x804B0540 .sdata2 start:0x804B42A0 end:0x804B42A8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/qsort.c: +Dolphin/MSL_C/MSL_Common/qsort.c: .text start:0x802AA454 end:0x802AA5C0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/rand.c: +Dolphin/MSL_C/MSL_Common/rand.c: .text start:0x802AA5C0 end:0x802AA5E0 .sdata start:0x804B0540 end:0x804B0548 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c: +Dolphin/MSL_C/MSL_Common/scanf.c: .text start:0x802AA5E0 end:0x802AB628 .rodata start:0x8037DF68 end:0x8037DF90 .data start:0x803BAAD8 end:0x803BABA8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c: +Dolphin/MSL_C/MSL_Common/signal.c: .text start:0x802AB628 end:0x802AB6E8 .bss start:0x80462130 end:0x80462148 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c: +Dolphin/MSL_C/MSL_Common/string.c: .text start:0x802AB6E8 end:0x802ABBB4 .rodata start:0x8037DF90 end:0x8037E320 .sdata start:0x804B0548 end:0x804B0550 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c: +Dolphin/MSL_C/MSL_Common/float.c: .sdata start:0x804B0550 end:0x804B0588 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c: +Dolphin/MSL_C/MSL_Common/strtold.c: .text start:0x802ABBB4 end:0x802ACC4C .rodata start:0x8037E320 end:0x8037E358 .sdata2 start:0x804B42A8 end:0x804B42C0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c: +Dolphin/MSL_C/MSL_Common/strtoul.c: .text start:0x802ACC4C end:0x802AD490 .data start:0x803BABA8 end:0x803BAC30 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c: +Dolphin/MSL_C/MSL_Common/wchar_io.c: .text start:0x802AD490 end:0x802AD518 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/uart_console_io_gcn.c: +Dolphin/MSL_C/PPC_EABI/uart_console_io_gcn.c: .text start:0x802AD518 end:0x802AD5F0 .sbss start:0x804B1C40 end:0x804B1C48 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c: .text start:0x802AD5F0 end:0x802AD82C .sdata2 start:0x804B42C0 end:0x804B4348 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c: .text start:0x802AD82C end:0x802ADA64 .sdata2 start:0x804B4348 end:0x804B43D0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c: .text start:0x802ADA64 end:0x802ADCF4 .sdata2 start:0x804B43D0 end:0x804B4428 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c: .text start:0x802ADCF4 end:0x802ADF18 .rodata start:0x8037E358 end:0x8037E388 .sdata2 start:0x804B4428 end:0x804B44A0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c: .text start:0x802ADF18 end:0x802AE254 .rodata start:0x8037E388 end:0x8037E398 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c: .text start:0x802AE254 end:0x802AE4D0 .sbss start:0x804B1C48 end:0x804B1C50 .sdata2 start:0x804B44A0 end:0x804B4520 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c: .text start:0x802AE4D0 end:0x802AED00 .rodata start:0x8037E398 end:0x8037E3C8 .sdata2 start:0x804B4520 end:0x804B4630 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c: .text start:0x802AED00 end:0x802AF0A0 .rodata start:0x8037E3C8 end:0x8037E550 .sdata2 start:0x804B4630 end:0x804B4688 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c: .text start:0x802AF0A0 end:0x802AF194 .sdata2 start:0x804B4688 end:0x804B46D0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c: .text start:0x802AF194 end:0x802AFFE8 .rodata start:0x8037E550 end:0x8037E5A0 .sdata2 start:0x804B46D0 end:0x804B4710 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c: .text start:0x802AFFE8 end:0x802B0088 .sdata2 start:0x804B4710 end:0x804B4748 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c: .text start:0x802B0088 end:0x802B029C .rodata start:0x8037E5A0 end:0x8037E608 .sdata2 start:0x804B4748 end:0x804B4780 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c: .text start:0x802B029C end:0x802B04B4 .rodata start:0x8037E608 end:0x8037E6A0 .sdata2 start:0x804B4780 end:0x804B47A8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c: .text start:0x802B04B4 end:0x802B05F8 .sdata2 start:0x804B47A8 end:0x804B47B8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c: .text start:0x802B05F8 end:0x802B0620 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c: .text start:0x802B0620 end:0x802B06F4 .sdata2 start:0x804B47B8 end:0x804B47C0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c: .text start:0x802B06F4 end:0x802B083C .sdata2 start:0x804B47C0 end:0x804B47D0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c: .text start:0x802B083C end:0x802B08C8 .sdata2 start:0x804B47D0 end:0x804B47D8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c: .text start:0x802B08C8 end:0x802B0A8C .sdata2 start:0x804B47D8 end:0x804B4800 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c: .text start:0x802B0A8C end:0x802B0B88 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c: .text start:0x802B0B88 end:0x802B0C60 .sdata2 start:0x804B4800 end:0x804B4808 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c: .text start:0x802B0C60 end:0x802B0CD8 .sdata2 start:0x804B4808 end:0x804B4810 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c: .text start:0x802B0CD8 end:0x802B0CF8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c: .text start:0x802B0CF8 end:0x802B0D18 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c: .text start:0x802B0D18 end:0x802B0D38 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c: .text start:0x802B0D38 end:0x802B0D58 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c: .text start:0x802B0D58 end:0x802B0D78 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c: .text start:0x802B0D78 end:0x802B0D98 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c: .text start:0x802B0D98 end:0x802B0DB8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c: .text start:0x802B0DB8 end:0x802B0FDC .sdata2 start:0x804B4810 end:0x804B4818 -PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/math_ppc.c: +Dolphin/MSL_C/PPC_EABI/math_ppc.c: .text start:0x802B0FDC end:0x802B1048 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c: +Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c: .text start:0x802B1048 end:0x802B1068 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c: +Dolphin/MSL_C/MSL_Common/extras.c: .text start:0x802B1068 end:0x802B11C4 -PowerPC_EABI_Support/Runtime/Src/__va_arg.c: +Dolphin/Runtime/__va_arg.c: .text start:0x802B11C4 end:0x802B128C -PowerPC_EABI_Support/Runtime/Src/global_destructor_chain.c: +Dolphin/Runtime/global_destructor_chain.c: .text start:0x802B128C end:0x802B12EC .dtors start:0x8035F508 end:0x8035F50C .sbss start:0x804B1C50 end:0x804B1C58 -PowerPC_EABI_Support/Runtime/Src/CPlusLibPPC.cp: +Dolphin/Runtime/CPlusLibPPC.cp: .text start:0x802B12EC end:0x802B131C -PowerPC_EABI_Support/Runtime/Src/New.cp: +Dolphin/Runtime/New.cp: extab start:0x80005608 end:0x80005630 extabindex start:0x8000570C end:0x80005718 .text start:0x802B131C end:0x802B1368 -PowerPC_EABI_Support/Runtime/Src/NMWException.cp: +Dolphin/Runtime/NMWException.cp: extab start:0x80005630 end:0x80005688 extabindex start:0x80005718 end:0x8000576C .text start:0x802B1368 end:0x802B18E4 .sdata start:0x804B0588 end:0x804B0590 -PowerPC_EABI_Support/Runtime/Src/runtime.c: +Dolphin/Runtime/runtime.c: .text start:0x802B18E4 end:0x802B2074 .rodata start:0x8037E6A0 end:0x8037E6B8 -PowerPC_EABI_Support/Runtime/Src/__init_cpp_exceptions.cpp: +Dolphin/Runtime/__init_cpp_exceptions.cpp: .text start:0x802B2074 end:0x802B20F0 .ctors start:0x8035F4C0 end:0x8035F4C4 .dtors start:0x8035F500 end:0x8035F508 .sdata start:0x804B0590 end:0x804B0598 -PowerPC_EABI_Support/Runtime/Src/Gecko_ExceptionPPC.cp: +Dolphin/Runtime/Gecko_ExceptionPPC.cp: extab start:0x80005688 end:0x800056FC extabindex start:0x8000576C end:0x800057C0 .text start:0x802B20F0 end:0x802B3528 @@ -1202,135 +1202,135 @@ PowerPC_EABI_Support/Runtime/Src/Gecko_ExceptionPPC.cp: .bss start:0x80462148 end:0x80462158 .sdata start:0x804B0598 end:0x804B05A8 -PowerPC_EABI_Support/Runtime/Src/GCN_mem_alloc.c: +Dolphin/Runtime/GCN_mem_alloc.c: .text start:0x802B3528 end:0x802B3698 .rodata start:0x8037E750 end:0x8037E7C8 -TRK_MINNOW_DOLPHIN/Portable/mainloop.c: +Dolphin/TRK_MINNOW_DOLPHIN/mainloop.c: .text start:0x802B3698 end:0x802B3790 -TRK_MINNOW_DOLPHIN/Portable/nubevent.c: +Dolphin/TRK_MINNOW_DOLPHIN/nubevent.c: .text start:0x802B3790 end:0x802B39B8 .bss start:0x80462158 end:0x80462180 -TRK_MINNOW_DOLPHIN/Portable/nubinit.c: +Dolphin/TRK_MINNOW_DOLPHIN/nubinit.c: .text start:0x802B39B8 end:0x802B3B50 .rodata start:0x8037E7C8 end:0x8037E7F8 .bss start:0x80462180 end:0x80462188 -TRK_MINNOW_DOLPHIN/Portable/msg.c: +Dolphin/TRK_MINNOW_DOLPHIN/msg.c: .text start:0x802B3B50 end:0x802B3B94 .rodata start:0x8037E7F8 end:0x8037E820 -TRK_MINNOW_DOLPHIN/Portable/msgbuf.c: +Dolphin/TRK_MINNOW_DOLPHIN/msgbuf.c: .text start:0x802B3B94 end:0x802B43D0 .rodata start:0x8037E820 end:0x8037E840 .bss start:0x80462188 end:0x80463B38 -TRK_MINNOW_DOLPHIN/Portable/serpoll.c: +Dolphin/TRK_MINNOW_DOLPHIN/serpoll.c: .text start:0x802B43D0 end:0x802B4688 .rodata start:0x8037E840 end:0x8037E9D0 .bss start:0x80463B38 end:0x80463B50 .sbss start:0x804B1C58 end:0x804B1C60 -TRK_MINNOW_DOLPHIN/Portable/usr_put.c: +Dolphin/TRK_MINNOW_DOLPHIN/usr_put.c: .text start:0x802B4688 end:0x802B4714 -TRK_MINNOW_DOLPHIN/Portable/dispatch.c: +Dolphin/TRK_MINNOW_DOLPHIN/dispatch.c: .text start:0x802B4714 end:0x802B488C .rodata start:0x8037E9D0 end:0x8037EA10 .data start:0x803BAD18 end:0x803BAD88 -TRK_MINNOW_DOLPHIN/Portable/msghndlr.c: +Dolphin/TRK_MINNOW_DOLPHIN/msghndlr.c: .text start:0x802B488C end:0x802B58FC .rodata start:0x8037EA10 end:0x8037EBF8 .data start:0x803BAD88 end:0x803BADC0 .bss start:0x80463B50 end:0x80463B58 -TRK_MINNOW_DOLPHIN/Portable/support.c: +Dolphin/TRK_MINNOW_DOLPHIN/support.c: .text start:0x802B58FC end:0x802B6010 .rodata start:0x8037EBF8 end:0x8037ECA0 -TRK_MINNOW_DOLPHIN/Portable/mutex_TRK.c: +Dolphin/TRK_MINNOW_DOLPHIN/mutex_TRK.c: .text start:0x802B6010 end:0x802B6028 -TRK_MINNOW_DOLPHIN/Portable/notify.c: +Dolphin/TRK_MINNOW_DOLPHIN/notify.c: .text start:0x802B6028 end:0x802B60C0 -TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.c: +Dolphin/TRK_MINNOW_DOLPHIN/flush_cache.c: .text start:0x802B60C0 end:0x802B60F8 -PowerPC_EABI_Support/Runtime/Src/__mem.c: +Dolphin/Runtime/__mem.c: .init start:0x80003100 end:0x80003130 -TRK_MINNOW_DOLPHIN/Portable/mem_TRK.c: +Dolphin/TRK_MINNOW_DOLPHIN/mem_TRK.c: .init start:0x80003238 end:0x8000328C .text start:0x802B60F8 end:0x802B61B0 -TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c: +Dolphin/TRK_MINNOW_DOLPHIN/targimpl.c: .text start:0x802B61B0 end:0x802B7D40 .rodata start:0x8037ECA0 end:0x8037ED38 .data start:0x803BADC0 end:0x803BADF0 .bss start:0x80463B58 end:0x804640D8 -TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s: +Dolphin/TRK_MINNOW_DOLPHIN/targsupp.s: .text start:0x802B7D40 end:0x802B7D60 -TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.c: +Dolphin/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c: .text start:0x802B7D60 end:0x802B80D0 -TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.s: +Dolphin/TRK_MINNOW_DOLPHIN/__exception.s: .init start:0x8000328C end:0x800051C0 -TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c: +Dolphin/TRK_MINNOW_DOLPHIN/dolphin_trk.c: .init start:0x800051C0 end:0x800051EC .text start:0x802B80D0 end:0x802B870C .data start:0x803BADF0 end:0x803BAE30 .bss start:0x804640D8 end:0x804640E0 -TRK_MINNOW_DOLPHIN/Portable/main_TRK.c: +Dolphin/TRK_MINNOW_DOLPHIN/main_TRK.c: .text start:0x802B870C end:0x802B8764 .rodata start:0x8037ED38 end:0x8037ED48 .bss start:0x804640E0 end:0x804640E8 -TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.c: +Dolphin/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c: .text start:0x802B8764 end:0x802B8CBC .rodata start:0x8037ED48 end:0x8037EE50 .data start:0x803BAE30 end:0x803BAE58 .bss start:0x804640E8 end:0x804640F0 -TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.c: +Dolphin/TRK_MINNOW_DOLPHIN/targcont.c: .text start:0x802B8CBC end:0x802B8CF0 -TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.c: +Dolphin/TRK_MINNOW_DOLPHIN/target_options.c: .text start:0x802B8CF0 end:0x802B8D0C .bss start:0x804640F0 end:0x804640F8 -TRK_MINNOW_DOLPHIN/MetroTRK/Export/mslsupp.c: +Dolphin/TRK_MINNOW_DOLPHIN/mslsupp.c: .text start:0x802B8D0C end:0x802B8E84 -UDP_Stubs.c: +Dolphin/TRK_MINNOW_DOLPHIN/UDP_Stubs.c: .text start:0x802B8E84 end:0x802B8ECC -main.c: +Dolphin/TRK_MINNOW_DOLPHIN/ddh/main.c: .text start:0x802B8ECC end:0x802B9210 .rodata start:0x8037EE50 end:0x8037EF30 .bss start:0x804640F8 end:0x80464918 .sbss start:0x804B1C60 end:0x804B1C68 -CircleBuffer.c: +Dolphin/TRK_MINNOW_DOLPHIN/CircleBuffer.c: .text start:0x802B9210 end:0x802B9478 -DupeCDir/main.c_1: +Dolphin/TRK_MINNOW_DOLPHIN/gdev/main.c: .text start:0x802B9478 end:0x802B97C4 .rodata start:0x8037EF30 end:0x8037F010 .bss start:0x80464918 end:0x80464E38 .sbss start:0x804B1C68 end:0x804B1C70 -MWTrace.c: +Dolphin/TRK_MINNOW_DOLPHIN/MWTrace.c: .text start:0x802B97C4 end:0x802B9814 -MWCriticalSection_gc.cpp: +Dolphin/TRK_MINNOW_DOLPHIN/MWCriticalSection_gc.cpp: .text start:0x802B9814 end:0x802B986C fmusic.c: @@ -1467,229 +1467,229 @@ system_time.c: system_string.c: .text start:0x802D3520 end:0x802D3754 -dolphin/ai/src/ai.c: +Dolphin/ai/ai.c: .text start:0x802D3754 end:0x802D4040 .data start:0x803BBBB0 end:0x803BBBF8 .sdata start:0x804B05E8 end:0x804B05F0 .sbss start:0x804B1D28 end:0x804B1D68 -dolphin/amcstubs/src/AmcExi2Stubs.c: +Dolphin/amcstubs/AmcExi2Stubs.c: .text start:0x802D4040 end:0x802D4070 -dolphin/ar/src/ar.c: +Dolphin/ar/ar.c: .text start:0x802D4070 end:0x802D5B50 .data start:0x803BBBF8 end:0x803BBC40 .sdata start:0x804B05F0 end:0x804B05F8 .sbss start:0x804B1D68 end:0x804B1D88 -dolphin/ar/src/arq.c: +Dolphin/ar/arq.c: .text start:0x802D5B50 end:0x802D5EEC .data start:0x803BBC40 end:0x803BBC88 .sdata start:0x804B05F8 end:0x804B0600 .sbss start:0x804B1D88 end:0x804B1DB0 -dolphin/ax/src/AX.c: +Dolphin/ax/AX.c: .text start:0x802D5EEC end:0x802D5F90 .data start:0x803BBC88 end:0x803BBCD0 .sdata start:0x804B0600 end:0x804B0608 -dolphin/ax/src/AXAlloc.c: +Dolphin/ax/AXAlloc.c: .text start:0x802D5F90 end:0x802D6500 .bss start:0x80469658 end:0x80469760 .sbss start:0x804B1DB0 end:0x804B1DB8 -dolphin/ax/src/AXAux.c: +Dolphin/ax/AXAux.c: .text start:0x802D6500 end:0x802D69A0 .bss start:0x80469760 end:0x8046C460 .sbss start:0x804B1DB8 end:0x804B1DF0 -dolphin/ax/src/AXCL.c: +Dolphin/ax/AXCL.c: .text start:0x802D69A0 end:0x802D70D0 .bss start:0x8046C460 end:0x8046CA60 .sbss start:0x804B1DF0 end:0x804B1E08 -dolphin/ax/src/AXOut.c: +Dolphin/ax/AXOut.c: .text start:0x802D70D0 end:0x802D78DC .bss start:0x8046CA60 end:0x80471500 .sbss start:0x804B1E08 end:0x804B1E40 -dolphin/ax/src/AXSPB.c: +Dolphin/ax/AXSPB.c: .text start:0x802D78DC end:0x802D7DA4 .bss start:0x80471500 end:0x80471540 .sbss start:0x804B1E40 end:0x804B1E68 -dolphin/ax/src/AXVPB.c: +Dolphin/ax/AXVPB.c: .text start:0x802D7DA4 end:0x802D8E84 .data start:0x803BBCD0 end:0x803BBDC0 .bss start:0x80471540 end:0x80482D40 .sbss start:0x804B1E68 end:0x804B1E78 .sdata2 start:0x804B4988 end:0x804B4990 -dolphin/ax/src/AXComp.c: +Dolphin/ax/AXComp.c: .data start:0x803BBDC0 end:0x803BD800 -dolphin/ax/src/DSPCode.c: +Dolphin/ax/DSPCode.c: .data start:0x803BD800 end:0x803BF6C0 .sdata start:0x804B0608 end:0x804B0610 -dolphin/ax/src/AXProf.c: +Dolphin/ax/AXProf.c: .text start:0x802D8E84 end:0x802D8ECC .sbss start:0x804B1E78 end:0x804B1E88 -dolphin/axfx/src/reverb_hi.c: +Dolphin/axfx/reverb_hi.c: .text start:0x802D8ECC end:0x802D9D10 .data start:0x803BF6C0 end:0x803BF6E0 .sdata2 start:0x804B4990 end:0x804B49D0 -dolphin/axfx/src/reverb_std.c: +Dolphin/axfx/reverb_std.c: .text start:0x802D9D10 end:0x802D9E58 -dolphin/axfx/src/chorus.c: +Dolphin/axfx/chorus.c: .text start:0x802D9E58 end:0x802D9EA8 -dolphin/axfx/src/delay.c: +Dolphin/axfx/delay.c: .text start:0x802D9EA8 end:0x802D9F38 -dolphin/axfx/src/axfx.c: +Dolphin/axfx/axfx.c: .text start:0x802D9F38 end:0x802D9F88 .sdata start:0x804B0610 end:0x804B0618 -dolphin/axfx/src/reverb_hi_4ch.c: +Dolphin/axfx/reverb_hi_4ch.c: .text start:0x802D9F88 end:0x802DAC68 .data start:0x803BF6E0 end:0x803BF708 .sdata2 start:0x804B49D0 end:0x804B4A08 -dolphin/base/src/PPCArch.c: +Dolphin/base/PPCArch.c: .text start:0x802DAC68 end:0x802DAD7C -dolphin/card/src/CARDBios.c: +Dolphin/card/CARDBios.c: .text start:0x802DAD7C end:0x802DC16C .data start:0x803BF708 end:0x803BF760 .bss start:0x80482D40 end:0x80482F80 .sdata start:0x804B0618 end:0x804B0620 .sbss start:0x804B1E88 end:0x804B1E90 -dolphin/card/src/CARDUnlock.c: +Dolphin/card/CARDUnlock.c: .text start:0x802DC16C end:0x802DD3CC .data start:0x803BF760 end:0x803BF8C0 .sdata start:0x804B0620 end:0x804B0628 -dolphin/card/src/CARDRdwr.c: +Dolphin/card/CARDRdwr.c: .text start:0x802DD3CC end:0x802DD664 -dolphin/card/src/CARDBlock.c: +Dolphin/card/CARDBlock.c: .text start:0x802DD664 end:0x802DDA68 -dolphin/card/src/CARDDir.c: +Dolphin/card/CARDDir.c: .text start:0x802DDA68 end:0x802DDCCC -dolphin/card/src/CARDCheck.c: +Dolphin/card/CARDCheck.c: .text start:0x802DDCCC end:0x802DEC90 -dolphin/card/src/CARDMount.c: +Dolphin/card/CARDMount.c: .text start:0x802DEC90 end:0x802DF750 .data start:0x803BF8C0 end:0x803BF900 -dolphin/card/src/CARDFormat.c: +Dolphin/card/CARDFormat.c: .text start:0x802DF750 end:0x802DFF88 -dolphin/card/src/CARDOpen.c: +Dolphin/card/CARDOpen.c: .text start:0x802DFF88 end:0x802E053C -dolphin/card/src/CARDCreate.c: +Dolphin/card/CARDCreate.c: .text start:0x802E053C end:0x802E088C -dolphin/card/src/CARDRead.c: +Dolphin/card/CARDRead.c: .text start:0x802E088C end:0x802E0D04 -dolphin/card/src/CARDWrite.c: +Dolphin/card/CARDWrite.c: .text start:0x802E0D04 end:0x802E1038 -dolphin/card/src/CARDDelete.c: +Dolphin/card/CARDDelete.c: .text start:0x802E1038 end:0x802E11EC -dolphin/card/src/CARDStat.c: +Dolphin/card/CARDStat.c: .text start:0x802E11EC end:0x802E16CC -dolphin/card/src/CARDStatEx.c: +Dolphin/card/CARDStatEx.c: .text start:0x802E16CC end:0x802E19DC -dolphin/card/src/CARDNet.c: +Dolphin/card/CARDNet.c: .text start:0x802E19DC end:0x802E1A60 .sdata start:0x804B0628 end:0x804B0630 -dolphin/db/src/db.c: +Dolphin/db/db.c: .text start:0x802E1A60 end:0x802E1B4C .data start:0x803BF900 end:0x803BF918 .sbss start:0x804B1E90 end:0x804B1E98 -dolphin/dsp/src/dsp.c: +Dolphin/dsp/dsp.c: .text start:0x802E1B4C end:0x802E1DDC .data start:0x803BF918 end:0x803BF998 .sdata start:0x804B0630 end:0x804B0638 .sbss start:0x804B1E98 end:0x804B1EA0 -dolphin/dsp/src/dsp_debug.c: +Dolphin/dsp/dsp_debug.c: .text start:0x802E1DDC end:0x802E1E2C -dolphin/dsp/src/dsp_task.c: +Dolphin/dsp/dsp_task.c: .text start:0x802E1E2C end:0x802E26B0 .data start:0x803BF998 end:0x803BFAD8 .sbss start:0x804B1EA0 end:0x804B1EB8 -dolphin/dvd/src/dvdlow.c: +Dolphin/dvd/dvdlow.c: .text start:0x802E26B0 end:0x802E352C .bss start:0x80482F80 end:0x80483060 .sdata start:0x804B0638 end:0x804B0640 .sbss start:0x804B1EB8 end:0x804B1F00 -dolphin/dvd/src/dvdfs.c: +Dolphin/dvd/dvdfs.c: .text start:0x802E352C end:0x802E3D94 .data start:0x803BFAD8 end:0x803BFC38 .sdata start:0x804B0640 end:0x804B0648 .sbss start:0x804B1F00 end:0x804B1F20 -dolphin/dvd/src/dvd.c: +Dolphin/dvd/dvd.c: .text start:0x802E3D94 end:0x802E6594 .data start:0x803BFC38 end:0x803BFDB8 .bss start:0x80483060 end:0x804830F8 .sdata start:0x804B0648 end:0x804B0660 .sbss start:0x804B1F20 end:0x804B1F68 -dolphin/dvd/src/dvdqueue.c: +Dolphin/dvd/dvdqueue.c: .text start:0x802E6594 end:0x802E678C .bss start:0x804830F8 end:0x80483118 -dolphin/dvd/src/dvderror.c: +Dolphin/dvd/dvderror.c: .text start:0x802E678C end:0x802E6924 .data start:0x803BFDB8 end:0x803BFE00 -dolphin/dvd/src/dvdidutils.c: +Dolphin/dvd/dvdidutils.c: .text start:0x802E6924 end:0x802E6A1C -dolphin/dvd/src/dvdFatal.c: +Dolphin/dvd/dvdFatal.c: .text start:0x802E6A1C end:0x802E6A4C .sbss start:0x804B1F68 end:0x804B1F70 -dolphin/dvd/src/emu_level2/fstload.c: +Dolphin/dvd/fstload.c: .text start:0x802E6A4C end:0x802E6C8C .data start:0x803BFE00 end:0x803BFE70 .bss start:0x80483118 end:0x80483188 .sdata start:0x804B0660 end:0x804B0670 .sbss start:0x804B1F70 end:0x804B1F80 -dolphin/exi/src/EXIBios.c: +Dolphin/exi/EXIBios.c: .text start:0x802E6C8C end:0x802E8668 .data start:0x803BFE70 end:0x803BFF80 .bss start:0x80483188 end:0x80483248 .sdata start:0x804B0670 end:0x804B0678 .sbss start:0x804B1F80 end:0x804B1F88 -dolphin/exi/src/EXIUart.c: +Dolphin/exi/EXIUart.c: .text start:0x802E8668 end:0x802E8C3C .sbss start:0x804B1F88 end:0x804B1F98 -dolphin/gx/src/GXInit.c: +Dolphin/gx/GXInit.c: .text start:0x802E8C3C end:0x802E9FBC .data start:0x803BFF80 end:0x803C01C0 .bss start:0x80483248 end:0x80483878 @@ -1697,221 +1697,221 @@ dolphin/gx/src/GXInit.c: .sbss start:0x804B1F98 end:0x804B1FC0 .sdata2 start:0x804B4A08 end:0x804B4A30 -dolphin/gx/src/GXFifo.c: +Dolphin/gx/GXFifo.c: .text start:0x802E9FBC end:0x802EA7B8 .sbss start:0x804B1FC0 end:0x804B1FE0 -dolphin/gx/src/GXAttr.c: +Dolphin/gx/GXAttr.c: .text start:0x802EA7B8 end:0x802EB50C .data start:0x803C01C0 end:0x803C0320 .sdata start:0x804B0680 end:0x804B0690 -dolphin/gx/src/GXMisc.c: +Dolphin/gx/GXMisc.c: .text start:0x802EB50C end:0x802EBBF4 .sbss start:0x804B1FE0 end:0x804B1FF8 -dolphin/gx/src/GXGeometry.c: +Dolphin/gx/GXGeometry.c: .text start:0x802EBBF4 end:0x802EBF74 -dolphin/gx/src/GXFrameBuf.c: +Dolphin/gx/GXFrameBuf.c: .text start:0x802EBF74 end:0x802ECB10 .data start:0x803C0320 end:0x803C0410 .sdata2 start:0x804B4A30 end:0x804B4A40 -dolphin/gx/src/GXLight.c: +Dolphin/gx/GXLight.c: .text start:0x802ECB10 end:0x802ED124 .data start:0x803C0410 end:0x803C0430 .sdata2 start:0x804B4A40 end:0x804B4A70 -dolphin/gx/src/GXTexture.c: +Dolphin/gx/GXTexture.c: .text start:0x802ED124 end:0x802EE1CC .data start:0x803C0430 end:0x803C0560 .sdata start:0x804B0690 end:0x804B06D0 .sdata2 start:0x804B4A70 end:0x804B4AA8 -dolphin/gx/src/GXBump.c: +Dolphin/gx/GXBump.c: .text start:0x802EE1CC end:0x802EE6A4 .sdata2 start:0x804B4AA8 end:0x804B4AB0 -dolphin/gx/src/GXTev.c: +Dolphin/gx/GXTev.c: .text start:0x802EE6A4 end:0x802EEE08 .data start:0x803C0560 end:0x803C05D8 -dolphin/gx/src/GXPixel.c: +Dolphin/gx/GXPixel.c: .text start:0x802EEE08 end:0x802EF450 .data start:0x803C05D8 end:0x803C05F8 .sdata2 start:0x804B4AB0 end:0x804B4AE8 -dolphin/gx/src/GXDisplayList.c: +Dolphin/gx/GXDisplayList.c: .text start:0x802EF450 end:0x802EF4C0 -dolphin/gx/src/GXTransform.c: +Dolphin/gx/GXTransform.c: .text start:0x802EF4C0 end:0x802EFA54 .sdata2 start:0x804B4AE8 end:0x804B4AF8 -dolphin/gx/src/GXPerf.c: +Dolphin/gx/GXPerf.c: .text start:0x802EFA54 end:0x802F0414 .data start:0x803C05F8 end:0x803C06E8 -dolphin/mix/src/mix.c: +Dolphin/mix/mix.c: .text start:0x802F0414 end:0x802F2748 .data start:0x803C06E8 end:0x803C12A8 .bss start:0x80483878 end:0x80485080 .sbss start:0x804B1FF8 end:0x804B2008 -dolphin/mtx/src/mtx.c: +Dolphin/mtx/mtx.c: .text start:0x802F2748 end:0x802F2868 .sdata start:0x804B06D0 end:0x804B06D8 .sdata2 start:0x804B4AF8 end:0x804B4B00 -dolphin/mtx/src/mtx44.c: +Dolphin/mtx/mtx44.c: .text start:0x802F2868 end:0x802F2900 .sdata2 start:0x804B4B00 end:0x804B4B10 -dolphin/odenotstub/src/odenotstub.c: +Dolphin/odenotstub/odenotstub.c: .text start:0x802F2900 end:0x802F2908 -dolphin/os/src/OS.c: +Dolphin/os/OS.c: .text start:0x802F2908 end:0x802F33D4 .data start:0x803C12A8 end:0x803C14A0 .bss start:0x80485080 end:0x804850F0 .sdata start:0x804B06D8 end:0x804B06E8 .sbss start:0x804B2008 end:0x804B2040 -dolphin/os/src/OSAlarm.c: +Dolphin/os/OSAlarm.c: .text start:0x802F33D4 end:0x802F3BAC .data start:0x803C14A0 end:0x803C14B0 .sbss start:0x804B2040 end:0x804B2048 -dolphin/os/src/OSAlloc.c: +Dolphin/os/OSAlloc.c: .text start:0x802F3BAC end:0x802F3EBC .sdata start:0x804B06E8 end:0x804B06F0 .sbss start:0x804B2048 end:0x804B2058 -dolphin/os/src/OSArena.c: +Dolphin/os/OSArena.c: .text start:0x802F3EBC end:0x802F3F08 .sdata start:0x804B06F0 end:0x804B06F8 .sbss start:0x804B2058 end:0x804B2060 -dolphin/os/src/OSAudioSystem.c: +Dolphin/os/OSAudioSystem.c: .text start:0x802F3F08 end:0x802F419C .data start:0x803C14B0 end:0x803C1530 -dolphin/os/src/OSCache.c: +Dolphin/os/OSCache.c: .text start:0x802F419C end:0x802F45D4 .data start:0x803C1530 end:0x803C1760 -dolphin/os/src/OSContext.c: +Dolphin/os/OSContext.c: .text start:0x802F45D4 end:0x802F4E44 .data start:0x803C1760 end:0x803C1938 -dolphin/os/src/OSError.c: +Dolphin/os/OSError.c: .text start:0x802F4E44 end:0x802F54F0 .data start:0x803C1938 end:0x803C1C58 .bss start:0x804850F0 end:0x80485140 .sdata start:0x804B06F8 end:0x804B0700 -dolphin/os/src/OSExec.c: +Dolphin/os/OSExec.c: .text start:0x802F54F0 end:0x802F5E50 .data start:0x803C1C58 end:0x803C1C68 .sdata start:0x804B0700 end:0x804B0708 .sbss start:0x804B2060 end:0x804B2068 -dolphin/os/src/OSFont.c: +Dolphin/os/OSFont.c: .text start:0x802F5E50 end:0x802F6BB0 .data start:0x803C1C68 end:0x803C2778 .sdata start:0x804B0708 end:0x804B0710 .sbss start:0x804B2068 end:0x804B2078 .sdata2 start:0x804B4B10 end:0x804B4B18 -dolphin/os/src/OSInterrupt.c: +Dolphin/os/OSInterrupt.c: .text start:0x802F6BB0 end:0x802F741C .data start:0x803C2778 end:0x803C27A8 .sbss start:0x804B2078 end:0x804B2090 -dolphin/os/src/OSLink.c: +Dolphin/os/OSLink.c: .text start:0x802F741C end:0x802F7434 -dolphin/os/src/OSMemory.c: +Dolphin/os/OSMemory.c: .text start:0x802F7434 end:0x802F770C .data start:0x803C27A8 end:0x803C27B8 -dolphin/os/src/OSMutex.c: +Dolphin/os/OSMutex.c: .text start:0x802F770C end:0x802F7928 -dolphin/os/src/OSReboot.c: +Dolphin/os/OSReboot.c: .text start:0x802F7928 end:0x802F79AC .sbss start:0x804B2090 end:0x804B2098 -dolphin/os/src/OSReset.c: +Dolphin/os/OSReset.c: .text start:0x802F79AC end:0x802F7E30 .data start:0x803C27B8 end:0x803C2808 .sbss start:0x804B2098 end:0x804B20A8 -dolphin/os/src/OSResetSW.c: +Dolphin/os/OSResetSW.c: .text start:0x802F7E30 end:0x802F8230 .sbss start:0x804B20A8 end:0x804B20C8 -dolphin/os/src/OSRtc.c: +Dolphin/os/OSRtc.c: .text start:0x802F8230 end:0x802F8DD0 .bss start:0x80485140 end:0x80485198 -dolphin/os/src/OSSemaphore.c: +Dolphin/os/OSSemaphore.c: .text start:0x802F8DD0 end:0x802F8EF8 -dolphin/os/src/OSSync.c: +Dolphin/os/OSSync.c: .text start:0x802F8EF8 end:0x802F8F7C -dolphin/os/src/OSThread.c: +Dolphin/os/OSThread.c: .text start:0x802F8F7C end:0x802FAA58 .data start:0x803C2808 end:0x803C3018 .bss start:0x80485198 end:0x80485B90 .sdata start:0x804B0710 end:0x804B0718 .sbss start:0x804B20C8 end:0x804B20D8 -dolphin/os/src/OSTime.c: +Dolphin/os/OSTime.c: .text start:0x802FAA58 end:0x802FAED4 .data start:0x803C3018 end:0x803C3078 -dolphin/os/src/__start.c: +Dolphin/os/__start.c: .init start:0x800051EC end:0x800054EC .sbss start:0x804B20D8 end:0x804B20E0 -dolphin/os/src/__ppc_eabi_init.cpp: +Dolphin/os/__ppc_eabi_init.cpp: .init start:0x800054EC end:0x80005544 .text start:0x802FAED4 end:0x802FAF68 -dolphin/pad/src/Padclamp.c: +Dolphin/pad/Padclamp.c: .text start:0x802FAF68 end:0x802FB1AC .rodata start:0x8037F4B8 end:0x8037F4C8 -dolphin/pad/src/Pad.c: +Dolphin/pad/Pad.c: .text start:0x802FB1AC end:0x802FCAF4 .data start:0x803C3078 end:0x803C30D0 .bss start:0x80485B90 end:0x80485BE0 .sdata start:0x804B0718 end:0x804B0738 .sbss start:0x804B20E0 end:0x804B2110 -dolphin/si/src/SIBios.c: +Dolphin/si/SIBios.c: .text start:0x802FCAF4 end:0x802FE1E4 .data start:0x803C30D0 end:0x803C31E8 .bss start:0x80485BE0 end:0x80485DE0 .sdata start:0x804B0738 end:0x804B0740 .sbss start:0x804B2110 end:0x804B2120 -dolphin/si/src/SISamplingRate.c: +Dolphin/si/SISamplingRate.c: .text start:0x802FE1E4 end:0x802FE2EC .data start:0x803C31E8 end:0x803C3280 .sbss start:0x804B2120 end:0x804B2128 -dolphin/vi/src/vi.c: +Dolphin/vi/vi.c: .text start:0x802FE2EC end:0x802FFE0C .data start:0x803C3280 end:0x803C3650 .bss start:0x80485DE0 end:0x80485F28 .sdata start:0x804B0740 end:0x804B0750 .sbss start:0x804B2128 end:0x804B2180 -OdemuExi2/DebuggerDriver.c: +Dolphin/OdemuExi2/DebuggerDriver.c: .text start:0x802FFE0C end:0x8030088C .sdata start:0x804B0750 end:0x804B0758 .sbss start:0x804B2180 end:0x804B2198 diff --git a/configure.py b/configure.py index b722782..d7789c9 100644 --- a/configure.py +++ b/configure.py @@ -186,7 +186,7 @@ "-enum int", "-fp hardware", "-Cpp_exceptions off", - # "-W all", + "-w off", "-O4,p", "-inline auto", '-pragma "cats off"', @@ -215,9 +215,10 @@ *cflags_base, "-use_lmw_stmw on", "-str reuse,pool,readonly", - "-gccinc", "-common off", "-inline auto", + "-cwd source", + "-i src/dolphin", ] # REL flags @@ -231,20 +232,21 @@ *cflags_base, "-common on", "-char unsigned", - "-str reuse,pool,readonly", + "-str reuse,readonly", "-use_lmw_stmw on", '-pragma "cpp_extensions on"', "-inline off", "-gccinc", - "-sym on", - "-i include/bink", - f"-i include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include", - f"-i include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include", + "-i include/bink", + "-i include/PowerPC_EABI_Support", + "-i include/PowerPC_EABI_Support", + "-i include/Dolphin", "-i include/inline", - "-i include/rwsdk", + "-i include/rwsdk", "-i src/SB/Core/gc", "-i src/SB/Core/x", "-i src/SB/Game", + "-i src/dolphin", "-DGAMECUBE", ] @@ -380,318 +382,538 @@ def MatchingFor(*versions): Object(NonMatching, "bink/src/sdk/bitplane.c"), ], }, - DolphinLib( - "ai", - [ - Object(NonMatching, "dolphin/ai/src/ai.c"), - ], - ), - DolphinLib( - "amcstubs", - [ - Object(NonMatching, "dolphin/amcstubs/src/AmcExi2Stubs.c"), - ], - ), - DolphinLib( - "ar", - [ - Object(NonMatching, "dolphin/ar/src/ar.c"), - Object(NonMatching, "dolphin/ar/src/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"), - ], - ), - DolphinLib( - "axfx", - [ - Object(NonMatching, "dolphin/axfx/src/axfx.c"), - Object(NonMatching, "dolphin/axfx/src/chorus.c"), - Object(NonMatching, "dolphin/axfx/src/delay.c"), - Object(NonMatching, "dolphin/axfx/src/reverb_hi.c"), - Object(NonMatching, "dolphin/axfx/src/reverb_hi_4ch.c"), - Object(NonMatching, "dolphin/axfx/src/reverb_std.c"), - ], - ), - DolphinLib( - "base", - [ - Object(NonMatching, "dolphin/base/src/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"), - ], - ), - DolphinLib( - "db", - [ - Object(NonMatching, "dolphin/db/src/db.c"), + { + "lib": "TRK_MINNOW_DOLPHIN", + "cflags": [*cflags_runtime, "-inline deferred", "-sdata 0", "-sdata2 0"], + "mw_version": "GC/2.6", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/mainloop.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/nubevent.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/nubinit.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/msg.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/msgbuf.c"), + Object( + Matching, + "Dolphin/TRK_MINNOW_DOLPHIN/serpoll.c", + extra_cflags=["-sdata 8"], + ), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/usr_put.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/dispatch.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/msghndlr.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/support.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/mutex_TRK.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/notify.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/flush_cache.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/mem_TRK.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/targimpl.c"), + Object( + Matching, + "Dolphin/TRK_MINNOW_DOLPHIN/targsupp.c", + extra_cflags=["-func_align 32"], + ), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/__exception.s"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/dolphin_trk.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/main_TRK.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/targcont.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/target_options.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/mslsupp.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/UDP_Stubs.c"), + Object( + Matching, + "Dolphin/TRK_MINNOW_DOLPHIN/ddh/main.c", + extra_cflags=["-sdata 8"], + ), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/CircleBuffer.c"), + Object( + Matching, + "Dolphin/TRK_MINNOW_DOLPHIN/gdev/main.c", + extra_cflags=["-sdata 8"], + ), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/MWTrace.c"), + Object(Matching, "Dolphin/TRK_MINNOW_DOLPHIN/MWCriticalSection_gc.cpp"), ], - ), - 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"), + }, + { + "lib": "Runtime", + "cflags": [*cflags_runtime, "-inline deferred"], + "mw_version": "GC/2.6", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/Runtime/__va_arg.c"), + Object(Matching, "Dolphin/Runtime/global_destructor_chain.c"), + Object(Matching, "Dolphin/Runtime/CPlusLibPPC.cp"), + Object( + Matching, + "Dolphin/Runtime/NMWException.cp", + extra_cflags=["-Cpp_exceptions on"], + ), + Object(Matching, "Dolphin/Runtime/ptmf.c"), + Object(Matching, "Dolphin/Runtime/runtime.c"), + Object(Matching, "Dolphin/Runtime/__init_cpp_exceptions.cpp"), + Object( + Matching, + "Dolphin/Runtime/Gecko_ExceptionPPC.cp", + extra_cflags=["-Cpp_exceptions on"], + ), + Object(Matching, "Dolphin/Runtime/GCN_mem_alloc.c"), + Object(Matching, "Dolphin/Runtime/__mem.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"), + }, + { + "lib": "MSL_C", + "cflags": [*cflags_runtime, "-inline deferred"], + "mw_version": "GC/2.6", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/MSL_C/PPC_EABI/abort_exit.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/alloc.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/ansi_files.c"), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/ansi_fp.c", + extra_cflags=["-str pool"], + ), + Object(Matching, "Dolphin/MSL_C/MSL_Common/arith.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/buffer_io.c"), + Object(Matching, "Dolphin/MSL_C/PPC_EABI/critical_regions.gamecube.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/ctype.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/direct_io.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/errno.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/file_io.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/FILE_POS.C"), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common/locale.c", + extra_cflags=["-str pool"], + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common/mbstring.c", + extra_cflags=["-inline noauto,deferred"], + ), + Object(Matching, "Dolphin/MSL_C/MSL_Common/mem.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/mem_funcs.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/misc_io.c"), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common/printf.c", + extra_cflags=["-str pool"], + ), + Object(Matching, "Dolphin/MSL_C/MSL_Common/rand.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/float.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/scanf.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/string.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/strtold.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/strtoul.c"), + Object(Matching, "Dolphin/MSL_C/MSL_Common/wchar_io.c"), + Object(Matching, "Dolphin/MSL_C/PPC_EABI/uart_console_io_gcn.c"), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c", + ), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c", + ), + Object(Matching, "Dolphin/MSL_C/PPC_EABI/math_ppc.c"), + Object( + Matching, + "Dolphin/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c", + ), + Object(Matching, "Dolphin/MSL_C/MSL_Common/extras.c"), ], - ), - DolphinLib( - "exi", - [ - Object(NonMatching, "dolphin/exi/src/EXIBios.c"), - Object(NonMatching, "dolphin/exi/src/EXIUart.c"), + }, + { + "lib": "OdemuExi2", + "cflags": [*cflags_runtime, "-inline deferred"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [Object(Matching, "Dolphin/OdemuExi2/DebuggerDriver.c")], + }, + { + "lib": "vi", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [Object(Matching, "Dolphin/vi/vi.c")], + }, + { + "lib": "amcstubs", + "cflags": cflags_runtime, + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [Object(Matching, "Dolphin/amcstubs/AmcExi2Stubs.c")], + }, + { + "lib": "ar", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/ar/ar.c"), + Object(Matching, "Dolphin/ar/arq.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"), + }, + { + "lib": "ax", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/ax/AX.c"), + Object(Matching, "Dolphin/ax/AXAlloc.c"), + Object(Matching, "Dolphin/ax/AXAux.c"), + Object(Matching, "Dolphin/ax/AXCL.c"), + Object(Matching, "Dolphin/ax/AXOut.c"), + Object(Matching, "Dolphin/ax/AXSPB.c"), + Object(Matching, "Dolphin/ax/AXVPB.c"), + Object(Matching, "Dolphin/ax/AXComp.c"), + Object(Matching, "Dolphin/ax/DSPCode.c"), + Object(Matching, "Dolphin/ax/AXProf.c"), ], - ), - DolphinLib( - "mix", - [ - Object(NonMatching, "dolphin/mix/src/mix.c"), + }, + { + "lib": "axfx", + "cflags": cflags_runtime, + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/axfx/reverb_hi.c"), + Object(Matching, "Dolphin/axfx/reverb_std.c"), + Object(Matching, "Dolphin/axfx/chorus.c"), + Object(Matching, "Dolphin/axfx/delay.c"), + Object(Matching, "Dolphin/axfx/axfx.c"), + Object(Matching, "Dolphin/axfx/reverb_hi_4ch.c") ], - ), - DolphinLib( - "mtx", - [ - Object(NonMatching, "dolphin/mtx/src/mtx.c"), - Object(NonMatching, "dolphin/mtx/src/mtx44.c"), + }, + { + "lib": "base", + "cflags": cflags_runtime, + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [Object(Matching, "Dolphin/base/PPCArch.c")], + }, + { + "lib": "mix", + "cflags": cflags_runtime, + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [Object(Matching, "Dolphin/mix/mix.c")], + }, + { + "lib": "card", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/card/CARDBios.c"), + Object(Matching, "Dolphin/card/CARDUnlock.c"), + Object(Matching, "Dolphin/card/CARDRdwr.c"), + Object(Matching, "Dolphin/card/CARDBlock.c"), + Object(Matching, "Dolphin/card/CARDDir.c"), + Object(Matching, "Dolphin/card/CARDCheck.c"), + Object(Matching, "Dolphin/card/CARDMount.c"), + Object(Matching, "Dolphin/card/CARDFormat.c"), + Object(Matching, "Dolphin/card/CARDOpen.c"), + Object(Matching, "Dolphin/card/CARDCreate.c"), + Object(Matching, "Dolphin/card/CARDRead.c"), + Object(Matching, "Dolphin/card/CARDWrite.c"), + Object(Matching, "Dolphin/card/CARDStat.c"), + Object(Matching, "Dolphin/card/CARDNet.c"), + Object(Matching, "Dolphin/card/CARDDelete.c"), + Object(Matching, "Dolphin/card/CARDStatEx.c"), ], - ), - DolphinLib( - "odenotstub", - [ - Object(NonMatching, "dolphin/odenotstub/src/odenotstub.c"), + }, + { + "lib": "db", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [Object(Matching, "Dolphin/db/db.c")], + }, + { + "lib": "dsp", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/dsp/dsp.c"), + Object(Matching, "Dolphin/dsp/dsp_debug.c"), + Object(Matching, "Dolphin/dsp/dsp_task.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/OSExec.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/OSSemaphore.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/__start.c"), - Object(NonMatching, "dolphin/os/src/__ppc_eabi_init.cpp"), + }, + { + "lib": "dvd", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/dvd/dvdlow.c"), + Object(Matching, "Dolphin/dvd/dvdfs.c"), + Object(Matching, "Dolphin/dvd/dvd.c"), + Object(Matching, "Dolphin/dvd/dvdqueue.c"), + Object(Matching, "Dolphin/dvd/dvderror.c"), + Object(Matching, "Dolphin/dvd/dvdidutils.c"), + Object(Matching, "Dolphin/dvd/dvdFatal.c"), + Object(Matching, "Dolphin/dvd/fstload.c"), ], - ), - DolphinLib( - "pad", - [ - Object(NonMatching, "dolphin/pad/src/Padclamp.c"), - Object(NonMatching, "dolphin/pad/src/Pad.c"), + }, + { + "lib": "exi", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/exi/EXIBios.c"), + Object(Matching, "Dolphin/exi/EXIUart.c"), ], - ), - DolphinLib( - "si", - [ - Object(NonMatching, "dolphin/si/src/SIBios.c"), - Object(NonMatching, "dolphin/si/src/SISamplingRate.c"), + }, + { + "lib": "gd", + "cflags": cflags_runtime, + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/gd/GDBase.c"), + Object(Matching, "Dolphin/gd/GDGeometry.c"), ], - ), - DolphinLib( - "vi", - [ - Object(NonMatching, "dolphin/vi/src/vi.c"), + }, + { + "lib": "gx", + "cflags": [*cflags_runtime, "-str noreadonly", "-fp_contract off"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/gx/GXInit.c"), + Object(Matching, "Dolphin/gx/GXFifo.c"), + Object(Matching, "Dolphin/gx/GXAttr.c"), + Object(Matching, "Dolphin/gx/GXMisc.c"), + Object(Matching, "Dolphin/gx/GXGeometry.c"), + Object(Matching, "Dolphin/gx/GXFrameBuf.c"), + Object(Matching, "Dolphin/gx/GXLight.c"), + Object(Matching, "Dolphin/gx/GXTexture.c"), + Object(Matching, "Dolphin/gx/GXBump.c"), + Object(Matching, "Dolphin/gx/GXTev.c"), + Object(Matching, "Dolphin/gx/GXPixel.c"), + Object(Matching, "Dolphin/gx/GXDisplayList.c"), + Object(Matching, "Dolphin/gx/GXTransform.c"), + Object(Matching, "Dolphin/gx/GXPerf.c"), ], - ), + }, { - "lib": "Runtime.PPCEABI.H", - "mw_version": config.linker_version, + "lib": "mtx", "cflags": cflags_runtime, - "progress_category": "sdk", + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, "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"), + Object(Matching, "Dolphin/mtx/mtx.c"), + Object(Matching, "Dolphin/mtx/mtxvec.c"), + Object(Matching, "Dolphin/mtx/mtx44.c"), + Object(Matching, "Dolphin/mtx/vec.c"), ], }, { - "lib": "TRK_Minnow_Dolphin", - "mw_version": "GC/1.3.2", + "lib": "odenotstub", "cflags": cflags_runtime, - "progress_category": "sdk", + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [Object(Matching, "Dolphin/odenotstub/odenotstub.c")], + }, + { + "lib": "os", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, "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"), + Object(Matching, "Dolphin/os/OS.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(Matching, "Dolphin/os/OSCache.c"), + Object(Matching, "Dolphin/os/OSContext.c"), + Object(Matching, "Dolphin/os/OSError.c"), + Object(Matching, "Dolphin/os/OSExec.c"), + Object(Matching, "Dolphin/os/OSFont.c"), + Object(Matching, "Dolphin/os/OSInterrupt.c"), + Object(Matching, "Dolphin/os/OSLink.c"), + Object(Matching, "Dolphin/os/OSMessage.c"), + Object(Matching, "Dolphin/os/OSMemory.c"), + Object(Matching, "Dolphin/os/OSMutex.c"), + Object(Matching, "Dolphin/os/OSReboot.c"), + Object(Matching, "Dolphin/os/OSReset.c"), + Object(Matching, "Dolphin/os/OSResetSW.c"), + Object(Matching, "Dolphin/os/OSRtc.c"), + Object(Matching, "Dolphin/os/OSSync.c"), + Object(Matching, "Dolphin/os/OSSemaphore.c"), + Object(Matching, "Dolphin/os/OSThread.c"), + Object(Matching, "Dolphin/os/OSTime.c"), + Object(Matching, "Dolphin/os/__start.c"), + Object(Matching, "Dolphin/os/__ppc_eabi_init.cpp"), ], }, { - "lib": "OdemuExi2", - "mw_version": "GC/1.3.2", - "cflags": cflags_runtime, - "progress_category": "sdk", + "lib": "pad", + "cflags": [*cflags_runtime, "-fp_contract off", "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, "objects": [ - Object(NonMatching, "OdemuExi2/DebuggerDriver.c"), + Object(Matching, "Dolphin/pad/Padclamp.c"), + Object(Matching, "Dolphin/pad/Pad.c"), ], }, + { + "lib": "si", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [ + Object(Matching, "Dolphin/si/SIBios.c"), + Object(Matching, "Dolphin/si/SISamplingRate.c"), + ], + }, + { + "lib": "ai", + "cflags": [*cflags_runtime, "-str noreadonly"], + "mw_version": "GC/1.2.5n", + "progress_category" : "sdk", + "host": False, + "objects": [Object(Matching, "Dolphin/ai/ai.c")], + }, RenderWareLib( "rpcollis", [ diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXBump.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXBump.h new file mode 100644 index 0000000..2a429f3 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXBump.h @@ -0,0 +1,46 @@ +#ifndef _DOLPHIN_GXBUMP_H +#define _DOLPHIN_GXBUMP_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" +#include "Dolphin/mtx.h" + +////////////// BUMP FUNCTIONS ////////////// +// Flush functions. +extern void __GXFlushTextureState(); + +// Indirect texture functions. +extern void GXSetTevIndirect(GXTevStageID tevStage, GXIndTexStageID indStage, GXIndTexFormat format, GXIndTexBiasSel bias, + GXIndTexMtxID mtx, GXIndTexWrap sWrap, GXIndTexWrap tWrap, GXBool doAddPrev, GXBool isIndLOD, + GXIndTexAlphaSel alpha); +extern void GXSetIndTexMtx(GXIndTexMtxID mtx, const Mtx23 offsets, s8 scale); +extern void GXSetIndTexCoordScale(GXIndTexStageID stage, GXIndTexScale sScale, GXIndTexScale tScale); +extern void GXSetIndTexOrder(GXIndTexStageID stage, GXTexCoordID texCoord, GXTexMapID texMap); +extern void GXSetNumIndStages(u8 stageCount); +extern void __GXSetIndirectMask(u32 mask); + +// Convenience functions. +extern void GXSetTevDirect(GXTevStageID stage); +extern void GXSetTevIndWarp(GXTevStageID tevStage, GXIndTexStageID indStage, GXBool isSignedOffset, GXBool isReplaceMode, + GXIndTexMtxID mtx); + +// Unused/inlined in P2. +extern void GXSetTevIndTile(GXTevStageID tevStage, GXIndTexStageID indStage, u16 sTileSize, u16 tTileSize, u16 sTileSpacing, + u16 tTileSpacing, GXIndTexFormat format, GXIndTexMtxID mtx, GXIndTexBiasSel bias, GXIndTexAlphaSel alpha); +extern void GXSetTevIndBumpST(GXTevStageID tevStage, GXIndTexStageID indStage, GXIndTexMtxID mtx); +extern void GXSetTevIndBumpXYZ(GXTevStageID tevStage, GXIndTexStageID indStage, GXIndTexMtxID mtx); +extern void GXSetTevIndRepeat(GXTevStageID stage); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXData.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXData.h new file mode 100644 index 0000000..b9f0b18 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXData.h @@ -0,0 +1,259 @@ +#ifndef _DOLPHIN_GXDATA_H +#define _DOLPHIN_GXDATA_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" +#include "Dolphin/GX/GXTexture.h" + +/////////////// CONTROL ENUMS ////////////// +typedef enum _CPStatus { + GX_FIFO_OVERFLOW = 0x1, + GX_FIFO_UNDERFLOW = 0x2, + GP_IS_IDLE_FOR_READING = 0x4, + GP_IS_IDLE_FOR_COMMANDS = 0x8, + BP_INTERRUPT = 0x10, +} CPStatus; + +typedef enum _CPControl { + GP_FIFO_READ_ENABLE = 0x1, + CP_IRQ_ENABLE_MAYBE = 0x2, + FIFO_OVERFLOW_IRQ_ENABLE_MAYBE = 0x4, + FIFO_UNDERFLOW_IRQ_ENABLE_MAYBE = 0x8, + GP_LINK_ENABLE = 0x10, + BP_ENABLE = 0x20, +} CPControl; + +typedef enum _CPClear { + CLEAR_FIFO_OVERFLOW = 0x1, + CLEAR_FIFO_UNDERFLOW = 0x2, +} CPClear; + +//////////////////////////////////////////// + +////////////// GXDATA STRUCTS ////////////// +// size: 0x5B0 +typedef struct _GXData { + // Bypass and vertex info + u16 vNumNot; // _000, !(# flush verts to send) + u16 bpSentNot; // _002, !(bypass reg sent last?) + u16 vNum; // _004, # flush verts to send + u16 vLim; // _006, max vert size + + // Command process (CP) regs + u32 cpEnable; // _008 + u32 cpStatus; // _00C + u32 cpClr; // _010 + u32 vcdLo; // _014 + u32 vcdHi; // _018 + u32 vatA[8]; // _01C + u32 vatB[8]; // _03C + u32 vatC[8]; // _05C + u32 lpSize; // _07C + u32 matIdxA; // _080 + u32 matIdxB; // _084 + + // Index loading base/stride regs (pos, nrm, tex, light) + u32 indexBase[4]; // _088 + u32 indexStride[4]; // _098 + + // Transform and lighting regs + u32 ambColor[2]; // _0A8 + u32 matColor[2]; // _0B0 + + // Setup regs + u32 suTs0[8]; // _0B8 + u32 suTs1[8]; // _0D8 + u32 suScis0; // _0F8 + u32 suScis1; // _0FC + + // Raster regs + u32 tref[8]; // _100 + u32 iref; // _120 + + // Bump/Indirect texture regs + u32 bpMask; // _124 + u32 IndTexScale0; // _128 + u32 IndTexScale1; // _12C + + // Tev regs + u32 tevc[16]; // _130 + u32 teva[16]; // _170 + u32 tevKsel[8]; // _1B0 + + // Performance regs + u32 cmode0; // _1D0 + u32 cmode1; // _1D4 + u32 zmode; // _1D8 + u32 peCtrl; // _1DC + + // Display copy regs + u32 cpDispSrc; // _1E0 + u32 cpDispSize; // _1E4 + u32 cpDispStride; // _1E8 + u32 cpDisp; // _1EC + + // Texture copy regs + u32 cpTexSrc; // _1F0 + u32 cpTexSize; // _1F4 + u32 cpTexStride; // _1F8 + u32 cpTex; // _1FC + GXBool cpTexZ; // _200 + + // General raster mode + u32 genMode; // _204 + + // Texture regions + GXTexRegion TexRegions0[GX_MAX_TEXMAP]; // _208 + GXTexRegion TexRegions1[GX_MAX_TEXMAP]; // _288 + GXTexRegion TexRegions2[GX_MAX_TEXMAP]; // _308 + + // Texture lookup table regions + GXTlutRegion TlutRegions[GX_MAX_TLUT_ALL]; // _388 + GXTexRegionCallback texRegionCallback; // _4C8 + GXTlutRegionCallback tlutRegionCallback; // _4CC + + // Command processor vars + GXAttrType nrmType; // _4D0 + GXBool hasNrms; // _4D4 + GXBool hasBiNrms; // _4D5 + u32 projType; // _4D8 + f32 projMtx[6]; // _4DC + + // Viewport parms + f32 vpLeft; // _4F4 + f32 vpTop; // _4F8 + f32 vpWd; // _4FC + f32 vpHt; // _500 + f32 vpNearz; // _504 + f32 vpFarz; // _508 + f32 zOffset; // _50C + f32 zScale; // _510 + + // Texture regs + u32 tImage0[8]; // _514 + u32 tMode0[8]; // _534 + u32 texmapId[16]; // _554 + u32 tcsManEnab; // _594 + u32 tevTcEnab; // _598 + + // Performance metrics + GXPerf0 perf0; // _59C + GXPerf1 perf1; // _5A0 + u32 perfSel; // _5A4 + + // Flags + GXBool inDispList; // _5A8 + GXBool dlSaveContext; // _5A9 + GXBool abtWaitPECopy; // _5AA + u8 dirtyVAT; // _5AB + u32 dirtyState; // _5AC +} GXData; +extern GXData* const __GXData; // NB: this is const in SMG1 decomp. + +#define gx __GXData + +//////////////////////////////////////////// + +///////////// REGISTER DEFINES ///////////// +// Declare registers. +extern void* __cpReg; +extern void* __piReg; +extern void* __memReg; +extern void* __peReg; + +// Define register addresses. +#define GX_CP_ADDR (0x0C000000) +#define GX_PE_ADDR (0x0C001000) +#define GX_PI_ADDR (0x0C003000) +#define GX_MEM_ADDR (0x0C004000) + +// i hate writing out the damn volatile shit so many times +#define GX_GET_MEM_REG(offset) (*(vu16*)((vu16*)(__memReg) + (offset))) +#define GX_GET_CP_REG(offset) (*(vu16*)((vu16*)(__cpReg) + (offset))) +#define GX_GET_PE_REG(offset) (*(vu16*)((vu16*)(__peReg) + (offset))) +#define GX_GET_PI_REG(offset) (*(vu32*)((vu32*)(__piReg) + (offset))) + +#define GX_SET_MEM_REG(offset, val) (*(vu16*)((vu16*)(__memReg) + (offset)) = val) +#define GX_SET_CP_REG(offset, val) (*(vu16*)((vu16*)(__cpReg) + (offset)) = val) +#define GX_SET_PE_REG(offset, val) (*(vu16*)((vu16*)(__peReg) + (offset)) = val) +#define GX_SET_PI_REG(offset, val) (*(vu32*)((vu32*)(__piReg) + (offset)) = val) + +// Useful reading register inlines +static inline u32 GXReadMEMReg(u32 addrLo, u32 addrHi) +{ + u32 hiStart, hiNew, lo; + hiStart = GX_GET_MEM_REG(addrHi); + do { + hiNew = hiStart; + lo = GX_GET_MEM_REG(addrLo); + hiStart = GX_GET_MEM_REG(addrHi); + } while (hiStart != hiNew); + + return ((hiStart << 16) | lo); +} + +static inline u32 GXReadCPReg(u32 addrLo, u32 addrHi) +{ + u32 hiStart, hiNew, lo; + hiStart = GX_GET_CP_REG(addrHi); + do { + hiNew = hiStart; + lo = GX_GET_CP_REG(addrLo); + hiStart = GX_GET_CP_REG(addrHi); + } while (hiStart != hiNew); + + return ((hiStart << 16) | lo); +} + +static inline u32 GXReadPEReg(u32 addrLo, u32 addrHi) +{ + u32 hiStart, hiNew, lo; + hiStart = GX_GET_PE_REG(addrHi); + do { + hiNew = hiStart; + lo = GX_GET_PE_REG(addrLo); + hiStart = GX_GET_PE_REG(addrHi); + } while (hiStart != hiNew); + + return ((hiStart << 16) | lo); +} + +static inline u32 GXReadPIReg(u32 addrLo, u32 addrHi) +{ + u32 hiStart, hiNew, lo; + hiStart = GX_GET_PI_REG(addrHi); + do { + hiNew = hiStart; + lo = GX_GET_PI_REG(addrLo); + hiStart = GX_GET_PI_REG(addrHi); + } while (hiStart != hiNew); + + return ((hiStart << 16) | lo); +} + +//////////////////////////////////////////// + +/////////// OTHER USEFUL DEFINES /////////// +// useful define to check first two GXData members together +// used in GXDisplayList, saves having a union in the struct +#define GX_CHECK_FLUSH() (!(*(u32*)(&gx->vNumNot))) + +// do the damn rlwimi thing +#define FAST_FLAG_SET(regOrg, newFlag, shift, size) \ + do { \ + (regOrg) = (u32)__rlwimi((int)(regOrg), (int)(newFlag), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXEnum.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXEnum.h new file mode 100644 index 0000000..e1876e1 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXEnum.h @@ -0,0 +1,2411 @@ +#ifndef _DOLPHIN_GXENUM_H +#define _DOLPHIN_GXENUM_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////////////////// BASICS ////////////////// +// Set up custom GX bool +typedef u8 GXBool; + +#define GX_TRUE ((GXBool)1) +#define GX_FALSE ((GXBool)0) +#define GX_ENABLE ((GXBool)1) +#define GX_DISABLE ((GXBool)0) + +#define GX_LARGE_NUMBER 1.0e+18f; + +// Logical comparison operators. +typedef enum _GXCompare { + GX_NEVER = 0, // never true + GX_LESS = 1, // < + GX_EQUAL = 2, // == + GX_LEQUAL = 3, // <= + GX_GREATER = 4, // > + GX_NEQUAL = 5, // != + GX_GEQUAL = 6, // >= + GX_ALWAYS = 7, // always true +} GXCompare; +typedef GXCompare _SDK_GXCompare; + +// Logical operation types. +// Source is the input coefficient and Destination is the output coefficient. +typedef enum _GXLogicOp { + GX_LO_CLEAR = 0, // 0x00 + GX_LO_AND = 1, // Source & Destination + GX_LO_REVAND = 2, // Source & ~Destination + GX_LO_COPY = 3, // Source + GX_LO_INVAND = 4, //~Source & Destination + GX_LO_NOOP = 5, // Destination + GX_LO_XOR = 6, // Source ^ Destination + GX_LO_OR = 7, // Source | Destination + GX_LO_NOR = 8, //~(Source | Destination) + GX_LO_EQUIV = 9, //~(Source ^ Destination) + GX_LO_INV = 10, //~Destination + GX_LO_REVOR = 11, // Source | ~Destination + GX_LO_INVCOPY = 12, //~Source + GX_LO_INVOR = 13, //~Source | Destination + GX_LO_NAND = 14, //~(Source & Destination) + GX_LO_SET = 15, // 0xff +} GXLogicOp; + +typedef GXLogicOp _SDK_GXLogicOp; + +// Primitive types. +typedef enum _GXPrimitive { + GX_POINTS = 0xB8, + GX_LINES = 0xA8, + GX_LINESTRIP = 0xB0, + GX_TRIANGLES = 0x90, + GX_TRIANGLESTRIP = 0x98, + GX_TRIANGLEFAN = 0xa0, + GX_QUADS = 0x80, +} GXPrimitive; + +// Position-normal matrix sizes/types. +typedef enum _GXPosNrmMtx { + GX_PNMTX0 = 3 * 0, // 0 + GX_PNMTX1 = 3 * 1, // 3 + GX_PNMTX2 = 3 * 2, // 6 + GX_PNMTX3 = 3 * 3, // 9 + GX_PNMTX4 = 3 * 4, // 12 + GX_PNMTX5 = 3 * 5, // 15 + GX_PNMTX6 = 3 * 6, // 18 + GX_PNMTX7 = 3 * 7, // 21 + GX_PNMTX8 = 3 * 8, // 24 + GX_PNMTX9 = 3 * 9, // 27 +} GXPosNrmMtx; + +// Command display list opcodes. +typedef enum _GXCommand { + GX_CMD_LOAD_INDX_A = 0x20, + GX_CMD_LOAD_INDX_B = 0x28, + GX_CMD_LOAD_INDX_C = 0x30, + GX_CMD_LOAD_INDX_D = 0x38, + + GX_CMD_LOAD_BP_REG = 0x61, + GX_CMD_LOAD_CP_REG = 0x08, + GX_CMD_LOAD_XF_REG = 0x10, + + GX_CMD_CALL_DL = 0x40, + GX_CMD_INVL_VC = 0x48, + + GX_CMD_NOP = 0x00, + GX_CMD_DRAW_QUADS = 0x80, + GX_CMD_DRAW_TRIANGLES = 0x90, + GX_CMD_DRAW_TRIANGLE_STRIP = 0x98, + GX_CMD_DRAW_TRIANGLE_FAN = 0xA0, + GX_CMD_DRAW_LINES = 0xA8, + GX_CMD_DRAW_LINE_STRIP = 0xB0, + GX_CMD_DRAW_POINTS = 0xB8, +} GXCommand; + +#define GX_OPCODE_MASK 0xF8 +#define GX_VAT_MASK 0x07 + +//////////////////////////////////////////// + +//////////////// ATTRIBUTES //////////////// +// Name of the vertex attribute or array. Attributes are listed in the ascending +// order vertex data is required to be sent to the GP. +typedef enum _GXAttr { + GX_VA_PNMTXIDX = 0, // Position coordinate/normal matrix index. + GX_VA_TEX0MTXIDX = 1, // GX_TXCOORD0 matrix index. + GX_VA_TEX1MTXIDX = 2, // GX_TXCOORD1 matrix index. + GX_VA_TEX2MTXIDX = 3, // GX_TXCOORD2 matrix index. + GX_VA_TEX3MTXIDX = 4, // GX_TXCOORD3 matrix index. + GX_VA_TEX4MTXIDX = 5, // GX_TXCOORD4 matrix index. + GX_VA_TEX5MTXIDX = 6, // GX_TXCOORD5 matrix index. + GX_VA_TEX6MTXIDX = 7, // GX_TXCOORD6 matrix index. + GX_VA_TEX7MTXIDX = 8, // GX_TXCOORD7 matrix index. + + GX_VA_POS = 9, // Position coordinates. + GX_VA_NRM = 10, // Normal. + GX_VA_CLR0 = 11, // Color 0. + GX_VA_CLR1 = 12, // Color 1. + GX_VA_TEX0 = 13, // Texture coordinate 0. + GX_VA_TEX1 = 14, // Texture coordinate 1. + GX_VA_TEX2 = 15, // Texture coordinate 2. + GX_VA_TEX3 = 16, // Texture coordinate 3. + GX_VA_TEX4 = 17, // Texture coordinate 4. + GX_VA_TEX5 = 18, // Texture coordinate 5. + GX_VA_TEX6 = 19, // Texture coordinate 6. + GX_VA_TEX7 = 20, // Texture coordinate 7. + + GX_POS_MTX_ARRAY = 21, // Position coordinates matrix array. + GX_NRM_MTX_ARRAY = 22, // Normal matrix array. + GX_TEX_MTX_ARRAY = 23, // Texture matrix array. + GX_LIGHT_ARRAY = 24, // Light structure array. + GX_VA_NBT = 25, // Normal/bi-normal/tangent. + + GX_VA_MAX_ATTR, // Max number of attributes (26). + + GX_VA_NULL = 0xFF, // Indicates that it is none of these data types. +} GXAttr; + +#define GX_MAX_VTXARRAY 16 + +// Type of vertex attribute reference. +// NB: havent confirmed the GX docs match pikmin 2 here +typedef enum _GXAttrType { + GX_NONE = 0, // No data to be sent. + GX_DIRECT = 1, // Value sent is value of data. + GX_INDEX8 = 2, // Value sent is INDEX value of data array (8-bit). + GX_INDEX16 = 3, // Value sent is INDEX value of data array (16-bit). +} GXAttrType; + +// Vertex format IDs. +// NB: havent confirmed the GX docs match pikmin 2 here +typedef enum _GXVtxFmt { + GX_VTXFMT0 = 0, // Vertex attribute format ID 0. + GX_VTXFMT1 = 1, // Vertex attribute format ID 1. + GX_VTXFMT2 = 2, // Vertex attribute format ID 2. + GX_VTXFMT3 = 3, // Vertex attribute format ID 3. + GX_VTXFMT4 = 4, // Vertex attribute format ID 4. + GX_VTXFMT5 = 5, // Vertex attribute format ID 5. + GX_VTXFMT6 = 6, // Vertex attribute format ID 6. + GX_VTXFMT7 = 7, // Vertex attribute format ID 7. + + GX_MAX_VTXFMT, // Max vertex formats (8) +} GXVtxFmt; + +// Number of components in an attribute. +// NB: havent confirmed the GX docs match pikmin 2 here +typedef enum _GXCompCnt { + GX_POS_XY = 0, // Position X, Y (two components). + GX_POS_XYZ = 1, // Position X, Y, Z (three components). + + GX_NRM_XYZ = 0, // Normal X, Y, Z (three components). + GX_NRM_NBT = 1, // Normal, binormal, tangent (three components). + GX_NRM_NBT3 = 2, // Normal, binormal, tangent (three components). Use when NBT + // normal is indexed independently. + + GX_CLR_RGB = 0, // RGB (three components). + GX_CLR_RGBA = 1, // RGBA (four components). + + GX_TEX_S = 0, // Texture coordinate S (one component). + GX_TEX_ST = 1, // Texture coordinates S, T (two components). + + GX_COMPCNT_NULL = 0, // Null count. +} GXCompCnt; + +// Type of components in an attribute. +// NB: havent confirmed the GX docs match pikmin 2 here +typedef enum _GXCompType { + GX_U8 = 0, // Unsigned 8-bit. + GX_S8 = 1, // Signed 8-bit. + GX_U16 = 2, // Unsigned 16-bit. + GX_S16 = 3, // Signed 16-bit. + GX_F32 = 4, // Floating-point 32-bit. + + GX_RGB565 = 0, // RGB565 16-bit. + GX_RGB8 = 1, // RGB888 24-bit. + GX_RGBX8 = 2, // RGB888x 32-bit. + GX_RGBA4 = 3, // RGBA4444 16-bit. + GX_RGBA6 = 4, // RGBA6666 24-bit. + GX_RGBA8 = 5, // RGBA8888 32-bit. + + GX_COMP_NULL = 0, // Null type. +} GXCompType; + +// Anisotropy (direction-dependent) types. +// NB: unsure what each type means. +typedef enum _GXAnisotropy { + GX_ANISO_1 = 0, + GX_ANISO_2 = 1, + GX_ANISO_4 = 2, + + GX_MAX_ANISOTROPY, // Max types (3). +} GXAnisotropy; + +//////////////////////////////////////////// + +///////////// LIGHT/FOG/BLEND ////////////// +// Light levels. +typedef enum _GXLightID { + GX_LIGHT_NULL = 0x0, + GX_LIGHT0 = 0x1, + GX_LIGHT1 = 0x2, + GX_LIGHT2 = 0x4, + GX_LIGHT3 = 0x8, + GX_LIGHT4 = 0x10, + GX_LIGHT5 = 0x20, + GX_LIGHT6 = 0x40, + GX_LIGHT7 = 0x80, + GX_MAX_LIGHT = 0x100, +} GXLightID; + +// Diffuse light functions. +typedef enum _GXDiffuseFn { + GX_DF_NONE = 0, + GX_DF_SIGN = 1, + GX_DF_CLAMP = 2, +} GXDiffuseFn; + +// Light attenuation functions. +typedef enum _GXAttnFn { + GX_AF_SPEC = 0, // Specular attenuation. + GX_AF_SPOT = 1, // Spotlight/distance attenuation. + GX_AF_NONE = 2, // Attenuation off. +} GXAttnFn; + +// Spotlight attenuation functions. +typedef enum _GXSpotFn { + GX_SP_OFF = 0, + GX_SP_FLAT = 1, + GX_SP_COS = 2, + GX_SP_COS2 = 3, + GX_SP_SHARP = 4, + GX_SP_RING1 = 5, + GX_SP_RING2 = 6, +} GXSpotFn; + +// Distance attentuation functions. +typedef enum _GXDistAttnFn { + GX_DA_OFF = 0, + GX_DA_GENTLE = 1, + GX_DA_MEDIUM = 2, + GX_DA_STEEP = 3, +} GXDistAttnFn; + +// Fog density functions for perspective projection mode. +typedef enum _GXFogType { + GX_FOG_NONE = 0, // No fog. + GX_FOG_LINEAR = 2, // Linear density. + GX_FOG_EXPONENT = 4, // Exponential density. + GX_FOG_EXPONENT2 = 5, // Exponential-squared density. + GX_FOG_REVERSEEXP = 6, // Inverse exponential density. + GX_FOG_REVERSEXP2 = 7 // Inverse exponential-squared density. +} GXFogType; + +typedef GXFogType _SDK_GXFogType; + +// Blending type. +typedef enum _GXBlendMode { + GX_BM_NONE = 0, // No blending. + GX_BM_BLEND = 1, // Blending. + GX_BM_LOGIC = 2, // Logic operations. + GX_BM_SUBTRACT = 3, // Subtractive blending. + GX_MAX_BLENDMODE, // Max blend modes (4). +} GXBlendMode; + +typedef GXBlendMode _SDK_GXBlendMode; + +// Blending controls. Dest = frame buffer, src = current/source. +typedef enum _GXBlendFactor { + GX_BL_ZERO = 0, // 0.0 + GX_BL_ONE = 1, // 1.0 + GX_BL_SRCCOL = 2, + GX_BL_DSTCOL = GX_BL_SRCCOL, // Frame buffer color, Source color + GX_BL_INVSRCCOL = 3, + GX_BL_INVDSTCOL = GX_BL_INVSRCCOL, // 1.0 - (Frame buffer color), 1.0 - (Source color) + GX_BL_SRCALPHA = 4, // Source alpha + GX_BL_INVSRCALPHA = 5, // 1.0 - (Source alpha) + GX_BL_DSTALPHA = 6, // Frame buffer alpha + GX_BL_INVDSTALPHA = 7, // 1.0 - (Frame buffer alpha) +} GXBlendFactor; + +typedef GXBlendFactor _SDK_GXBlendFactor; + +//////////////////////////////////////////// + +/////////////// MANIP MODES //////////////// +// Culling modes. +typedef enum _GXCullMode { + GX_CULL_NONE = 0, + GX_CULL_FRONT = 1, + GX_CULL_BACK = 2, + GX_CULL_ALL = 3, + + GX_CULL_INVALID = 0xFF, +} GXCullMode; + +// Clipping modes. +// NB: These are deliberately reversed from normal on/off. +typedef enum _GXClipMode { + GX_CLIP_ENABLE = 0, + GX_CLIP_DISABLE = 1, +} GXClipMode; + +// Copy modes. +typedef enum _GXCopyMode { + GX_COPY_PROGRESSIVE = 0, + GX_COPY_INTLC_EVEN = 2, + GX_COPY_INTLC_ODD = 3, +} GXCopyMode; + +//////////////////////////////////////////// + +/////////////// COLOR MANIP //////////////// +// Color Channel IDs. +typedef enum _GXChannelID { + GX_COLOR0 = 0, // Color 0. + GX_COLOR1 = 1, // Color 1. + GX_ALPHA0 = 2, // Alpha 0. + GX_ALPHA1 = 3, // Alpha 1. + GX_COLOR0A0 = 4, // Color 0 + Alpha 0. + GX_COLOR1A1 = 5, // Color 1 + Alpha 1. + GX_COLOR_ZERO = 6, // RGBA = 0. + GX_ALPHA_BUMP = 7, // Bump alpha 0-248, RGB = 0. + GX_ALPHA_BUMPN = 8, // Norm bump alpha 0-255, RGB = 0. + + GX_COLOR_NULL = 0xFF, // Null channel. +} GXChannelID; + +// Color sources. +typedef enum _GXColorSrc { + GX_SRC_REG = 0, // Color source from material color register. + GX_SRC_VTX = 1, // Color source from vertex. +} GXColorSrc; + +// Alpha operators. +typedef enum _GXAlphaOp { + GX_AOP_AND = 0, + GX_AOP_OR = 1, + GX_AOP_XOR = 2, + GX_AOP_XNOR = 3, + + GX_MAX_ALPHAOP, // Max num alpha operators (4). +} GXAlphaOp; + +// Alpha read mode. +typedef enum _GXAlphaReadMode { + GX_READ_00 = 0, + GX_READ_FF = 1, + GX_READ_NONE = 2, +} GXAlphaReadMode; + +// Gamma modes. +// NB: not sure what these modes are. +typedef enum _GXGamma { + GX_GM_1_0 = 0, + GX_GM_1_7 = 1, + GX_GM_2_2 = 2, +} GXGamma; + +//////////////////////////////////////////// + +///////////////// TEXTURES ///////////////// +// Texture Coordinate IDs +typedef enum _GXTexCoordID { + GX_TEXCOORD0 = 0, // Generated tex coord 0. + GX_TEXCOORD1 = 1, // Generated tex coord 1. + GX_TEXCOORD2 = 2, // Generated tex coord 2. + GX_TEXCOORD3 = 3, // Generated tex coord 3. + GX_TEXCOORD4 = 4, // Generated tex coord 4. + GX_TEXCOORD5 = 5, // Generated tex coord 5. + GX_TEXCOORD6 = 6, // Generated tex coord 6. + GX_TEXCOORD7 = 7, // Generated tex coord 7. + + GX_MAX_TEXCOORD, // Max num texture coords (8). + + GX_TEXCOORD_NULL = 0xFF, // Null coordinate. +} GXTexCoordID; + +// Texture generation types. +typedef enum _GXTexGenType { + GX_TG_MTX2X4 = 0, + GX_TG_MTX3X4 = 1, + + GX_TG_BUMP0 = 2, + GX_TG_BUMP1 = 3, + GX_TG_BUMP2 = 4, + GX_TG_BUMP3 = 5, + GX_TG_BUMP4 = 6, + GX_TG_BUMP5 = 7, + GX_TG_BUMP6 = 8, + GX_TG_BUMP7 = 9, + + GX_TG_SRTG = 10, +} GXTexGenType; + +// Texture generation sources. +typedef enum _GXTexGenSrc { + GX_TG_POS = 0, // Position. + GX_TG_NRM = 1, // Normal. + GX_TG_BINRM = 2, // Bi-normal. + GX_TG_TANGENT = 3, // Tangent. + + GX_TG_TEX0 = 4, // Texture 0. + GX_TG_TEX1 = 5, // Texture 1. + GX_TG_TEX2 = 6, // Texture 2. + GX_TG_TEX3 = 7, // Texture 3. + GX_TG_TEX4 = 8, // Texture 4. + GX_TG_TEX5 = 9, // Texture 5. + GX_TG_TEX6 = 10, // Texture 6. + GX_TG_TEX7 = 11, // Texture 7. + + GX_TG_TEXCOORD0 = 12, // Tex coord 0. + GX_TG_TEXCOORD1 = 13, // Tex coord 1. + GX_TG_TEXCOORD2 = 14, // Tex coord 2. + GX_TG_TEXCOORD3 = 15, // Tex coord 3. + GX_TG_TEXCOORD4 = 16, // Tex coord 4. + GX_TG_TEXCOORD5 = 17, // Tex coord 5. + GX_TG_TEXCOORD6 = 18, // Tex coord 6. No 7? + + GX_TG_COLOR0 = 19, // Color 0. + GX_TG_COLOR1 = 20, // Color 1. +} GXTexGenSrc; + +// Texture map names. +// NB: havent confirmed the GX docs match pikmin 2 here +typedef enum _GXTexMapID { + GX_TEXMAP0 = 0, // Texture map ID 0. + GX_TEXMAP1 = 1, // Texture map ID 1. + GX_TEXMAP2 = 2, // Texture map ID 2. + GX_TEXMAP3 = 3, // Texture map ID 3. + GX_TEXMAP4 = 4, // Texture map ID 4. + GX_TEXMAP5 = 5, // Texture map ID 5. + GX_TEXMAP6 = 6, // Texture map ID 6. + GX_TEXMAP7 = 7, // Texture map ID 7. + + GX_MAX_TEXMAP, // Max num texture map IDs (8). + + GX_TEXMAP_NULL = 0xFF, // No textures used. + GX_TEX_DISABLE = 0x100, // No texture map look-up. +} GXTexMapID; + +// Texture format types. +/** + * RGB, RGBA, Intensity, Intensity/Alpha, Compressed, and Z texture format + * types. See GXCITexFmt for information on color index formats. The CTF format + * is used only by the GXSetTexCopyDst function to specify how data is copied + * out of the EFB into a texture in main memory. In order to actually use that + * texture, you must specify a non-copy format of matching size. For example, if + * copying using GX_CTF_RG8, you would apply the resulting texture using + * GX_TF_IA8. + */ +typedef enum _GXTexFmt { + // Intensities (I) and RGB/RGBA. + GX_TF_I4 = 0x0, // 4-bit I + GX_TF_I8 = 0x1, // 8-bit I + GX_TF_IA4 = 0x2, // 8-bit I + alpha (4+4). + GX_TF_IA8 = 0x3, // 16-bit I + alpha (8+8). + GX_TF_RGB565 = 0x4, // 16-bit RGB. + GX_TF_RGB5A3 = 0x5, // MSB=1, RGB555 (opaque). MSB=0, RGBA4443 (transparent). + GX_TF_RGBA8 = 0x6, // 32-bit RGB. + GX_TF_CMPR = 0xE, // Compressed 4-bit texel. + + // Z-texture format. + GX_TF_Z8 = 0x11, // Unsigned 8-bit Z. For texture copies, specify the upper 8 bits of Z. + GX_TF_Z16 = 0x13, // Unsigned 16-bit Z. For texture copies, specify the upper 16 bits of Z. + GX_TF_Z24X8 = 0x16, // Unsigned 24-bit (32-bit texture) Z. For texture copies, copy the 24-bit Z and 0xff. + + // Copy-texture format. + GX_CTF_R4 = 0x20, // 4-bit red. For copying 4 bits from red. + GX_CTF_RA4 = 0x22, // 4-bit red + 4-bit alpha. For copying 4 bits from red, 4 bits from alpha. + GX_CTF_RA8 = 0x23, // 8-bit red + 8-bit alpha. For copying 8 bits from red, 8 bits from alpha. + GX_CTF_YUVA8 = 0x26, // 8-bit YUV + alpha. For copying 8 bits from YUV, 8 bits from alpha. + GX_CTF_A8 = 0x26, // 8-bit alpha. For copying 8 bits from alpha. + GX_CTF_R8 = 0x27, // 8-bit red. For copying 8 bits from red. + GX_CTF_G8 = 0x28, // 8-bit green. For copying 8 bits from green. + GX_CTF_B8 = 0x29, // 8-bit blue. For copying 8 bits from blue. + GX_CTF_RG8 = 0x2A, // 8-bit red +8-bit green. For copying 8 bits from red, 8 bits from green. + GX_CTF_GB8 = 0x2B, // 8-bit green +8-bit blue. For copying 8 bits from green, 8 bits from blue. + + // Copy-Z-texture format. + GX_CTF_Z4 = 0x30, // 4-bit Z. For copying the 4 upper bits from Z. + GX_CTF_Z8M = 0x39, // 8-bit Z (median byte). For copying the middle 8 bits of Z. + GX_CTF_Z8L = 0x3A, // 8-bit Z (lower byte). For copying the lower 8 bits of Z. + GX_CTF_Z16L = 0x3C, // 16-bit Z (lower portion). For copying the lower 16 bits of Z. +} GXTexFmt; + +// Color index formats. +typedef enum _GXCITexFmt { + GX_TF_C4 = 0x8, + GX_TF_C8 = 0x9, + GX_TF_C14X2 = 0xA, +} GXCITexFmt; + +// Texture matrix ID. +typedef enum _GXTexMtx { + GX_TEXMTX0 = 30 + 0 * 3, // 30, Mtx0 + GX_TEXMTX1 = 30 + 1 * 3, // 33, Mtx1 + GX_TEXMTX2 = 30 + 2 * 3, // 36, Mtx2 + GX_TEXMTX3 = 30 + 3 * 3, // 39, Mtx3 + GX_TEXMTX4 = 30 + 4 * 3, // 42, Mtx4 + GX_TEXMTX5 = 30 + 5 * 3, // 45, Mtx5 + GX_TEXMTX6 = 30 + 6 * 3, // 48, Mtx6 + GX_TEXMTX7 = 30 + 7 * 3, // 51, Mtx7 + GX_TEXMTX8 = 30 + 8 * 3, // 54, Mtx8 + GX_TEXMTX9 = 30 + 9 * 3, // 57, Mtx9 + + GX_IDENTITY = 60, // 60, Identity mtx + + GX_TEXMTX_NULL = 0, // 0, no matrix selected +} GXTexMtx; + +// Texture matrix type. +typedef enum _GXTexMtxType { + GX_MTX3x4 = 0, + GX_MTX2x4 = 1, +} GXTexMtxType; + +// PT Texture matrix ID (?). +typedef enum _GXPTTexMtx { + GX_PTTEXMTX0 = 64 + 0 * 3, // 64, Mtx0 + GX_PTTEXMTX1 = 64 + 1 * 3, // 67, Mtx1 + GX_PTTEXMTX2 = 64 + 2 * 3, // 70, Mtx2 + GX_PTTEXMTX3 = 64 + 3 * 3, // 73, Mtx3 + GX_PTTEXMTX4 = 64 + 4 * 3, // 76, Mtx4 + GX_PTTEXMTX5 = 64 + 5 * 3, // 79, Mtx5 + GX_PTTEXMTX6 = 64 + 6 * 3, // 82, Mtx6 + GX_PTTEXMTX7 = 64 + 7 * 3, // 85, Mtx7 + GX_PTTEXMTX8 = 64 + 8 * 3, // 88, Mtx8 + GX_PTTEXMTX9 = 64 + 9 * 3, // 91, Mtx9 + GX_PTTEXMTX10 = 64 + 10 * 3, // 94, Mtx10 + GX_PTTEXMTX11 = 64 + 11 * 3, // 97, Mtx11 + GX_PTTEXMTX12 = 64 + 12 * 3, // 100, Mtx12 + GX_PTTEXMTX13 = 64 + 13 * 3, // 103, Mtx13 + GX_PTTEXMTX14 = 64 + 14 * 3, // 106, Mtx14 + GX_PTTEXMTX15 = 64 + 15 * 3, // 109, Mtx15 + GX_PTTEXMTX16 = 64 + 16 * 3, // 112, Mtx16 + GX_PTTEXMTX17 = 64 + 17 * 3, // 115, Mtx17 + GX_PTTEXMTX18 = 64 + 18 * 3, // 118, Mtx18 + GX_PTTEXMTX19 = 64 + 19 * 3, // 121, Mtx19 + + GX_PTIDENTITY = 125, // 125, Identity mtx +} GXPTTexMtx; + +// Texture offset types. +typedef enum _GXTexOffset { + GX_TO_ZERO = 0, + GX_TO_SIXTEENTH = 1, + GX_TO_EIGHTH = 2, + GX_TO_FOURTH = 3, + GX_TO_HALF = 4, + GX_TO_ONE = 5, + + GX_MAX_TEXOFFSET, // Max num texture offset types (6). +} GXTexOffset; + +// Texture wrap modes. +typedef enum _GXTexWrapMode { + GX_CLAMP = 0, // Clamp/cut off at wrap. + GX_REPEAT = 1, // Repeat past wrap. + GX_MIRROR = 2, // Mirror past wrap. +} GXTexWrapMode; + +// Texture filtering types. +typedef enum _GXTexFilter { + GX_NEAR = 0, // Filter near. + GX_LINEAR = 1, // Filter linear. + GX_NEAR_MIP_NEAR = 2, // Near + MIPmap near. + GX_LIN_MIP_NEAR = 3, // Linear + MIPmap near. + GX_NEAR_MIP_LIN = 4, // Near + MIPmap linear. + GX_LIN_MIP_LIN = 5, // Linear + MIPmap linear. +} GXTexFilter; + +// Texture cache sizes. +typedef enum _GXTexCacheSize { + GX_TEXCACHE_32K = 0, // Small. + GX_TEXCACHE_128K = 1, // Medium. + GX_TEXCACHE_512K = 2, // Large. + GX_TEXCACHE_NONE = 3, // No cache. +} GXTexCacheSize; + +//////////////////////////////////////////// + +////////// TEXTURE LOOK-UP TABLES ////////// +// Texture look-up table (Tlut) names. +/** + * Names of texture lookup tables (TLUTs) in texture memory. + * Each table GX_TLUT0 through GX_TLUT15 contains 256 entries, at 16 bits per + * entry. Each table GX_BIGTLUT0 through BIGTLUT3 contains 1024 entries, at 16 + * bits per entry. Used for setting texture memory in the GXInit function. + */ +typedef enum _GXTlut { + GX_TLUT0 = 0, // TLUT (256 16-bit entries) ID 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_MAX_TLUT = 16, + + GX_BIGTLUT0 = 16, // BIGTLUT (1024 16-bit entries) ID 0. + GX_BIGTLUT1 = 17, + GX_BIGTLUT2 = 18, + GX_BIGTLUT3 = 19, + + GX_MAX_BIGTLUT = 4, + + GX_MAX_TLUT_ALL = GX_MAX_TLUT + GX_MAX_BIGTLUT, // 20 +} GXTlut; + +// Texture look-up (Tlut) formats. +typedef enum _GXTlutFmt { + GX_TL_IA8 = 0, // 16-bit intensity + alpha (8I+8A). + GX_TL_RGB565 = 1, // 16-bit RGB (R5+G6+B5). + GX_TL_RGB5A3 = 2, // MSB=1, RGB555 (opaque); MSB=0, RGBA4443 (transparent). + + GX_MAX_TLUTFMT, // Max number of formats (3). +} GXTlutFmt; + +// Texture look-up (Tlut) sizes. +typedef enum _GXTlutSize { + GX_TLUT_16 = 1, // Number of 16 entry blocks. + 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; + +//////////////////////////////////////////// + +//////////// INDIRECT TEXTURES ///////////// +// Indirect texture formats. +typedef enum _GXIndTexFormat { + GX_ITF_8 = 0, // 8-bit texture offsets. + GX_ITF_5 = 1, // 5-bit texture offsets. + GX_ITF_4 = 2, // 4-bit texture offsets. + GX_ITF_3 = 3, // 3-bit texture offsets. + + GX_MAX_ITFORMAT, // Max num formats (4). +} GXIndTexFormat; + +// Indirect texture stage names. +typedef enum _GXIndTexStageID { + GX_IND_TEX_STAGE_0 = 0, + GX_IND_TEX_STAGE_1 = 1, + GX_IND_TEX_STAGE_2 = 2, + GX_IND_TEX_STAGE_3 = 3, + + GX_IND_MAX_TEX_STAGE_ID, // Max num stages (4). +} GXIndTexStageID; + +// Indirect texture matrix IDs. +typedef enum _GXIndTexMtxID { + GX_ITM_OFF = 0, + GX_ITM_0 = 1, + GX_ITM_1 = 2, + GX_ITM_2 = 3, + + GX_ITM_S0 = 5, + GX_ITM_S1 = 6, + GX_ITM_S2 = 7, + + GX_ITM_T0 = 9, + GX_ITM_T1 = 10, + GX_ITM_T2 = 11, +} GXIndTexMtxID; + +// Indirect texture scaling amounts. +typedef enum _GXIndTexScale { + GX_ITS_1 = 0, // Scale by 1. + GX_ITS_2 = 1, // Scale by 1/2. + GX_ITS_4 = 2, // Scale by 1/4. + GX_ITS_8 = 3, // Scale by 1/8. + GX_ITS_16 = 4, // Scale by 1/16. + GX_ITS_32 = 5, // Scale by 1/32. + GX_ITS_64 = 6, // Scale by 1/64. + GX_ITS_128 = 7, // Scale by 1/128. + GX_ITS_256 = 8, // Scale by 1/256. + + GX_MAX_ITSCALE, // Max scaling types (9) +} GXIndTexScale; + +// Indirect texture wrapping amounts. +typedef enum _GXIndTexWrap { + GX_ITW_OFF = 0, // No wrapping. + GX_ITW_256 = 1, // Wrap 256. + GX_ITW_128 = 2, // Wrap 128. + GX_ITW_64 = 3, // Wrap 64. + GX_ITW_32 = 4, // Wrap 32. + GX_ITW_16 = 5, // Wrap 16. + GX_ITW_0 = 6, // Wrap 0. + + GX_MAX_ITWRAP, // Max wrapping types (7) +} GXIndTexWrap; + +// Indirect texture bias selections. +// STU = surface coordinate system (s,t,u) with u normal to surface. +typedef enum _GXIndTexBiasSel { + GX_ITB_NONE = 0, + GX_ITB_S = 1, + GX_ITB_T = 2, + GX_ITB_ST = 3, + GX_ITB_U = 4, + GX_ITB_SU = 5, + GX_ITB_TU = 6, + GX_ITB_STU = 7, + + GX_MAX_ITBIAS, // Max num bias types (8). +} GXIndTexBiasSel; + +// Indirect texture alpha selections. +// STU = surface coordinate system (s,t,u) with u normal to surface. +typedef enum _GXIndTexAlphaSel { + GX_ITBA_OFF = 0, + GX_ITBA_S = 1, + GX_ITBA_T = 2, + GX_ITBA_U = 3, + + GX_MAX_ITBALPHA, // Max num alpha types (4). +} GXIndTexAlphaSel; + +//////////////////////////////////////////// + +/////// TEXTURE ENVIRONMENTS (TEV) ///////// +// TEV stage names. +typedef enum _GXTevStageID { + GX_TEVSTAGE0 = 0, // TEV Stage 0. + GX_TEVSTAGE1 = 1, // TEV Stage 1. + GX_TEVSTAGE2 = 2, // TEV Stage 2. + GX_TEVSTAGE3 = 3, // TEV Stage 3. + GX_TEVSTAGE4 = 4, // TEV Stage 4. + GX_TEVSTAGE5 = 5, // TEV Stage 5. + GX_TEVSTAGE6 = 6, // TEV Stage 6. + GX_TEVSTAGE7 = 7, // TEV Stage 7. + GX_TEVSTAGE8 = 8, // TEV Stage 8. + GX_TEVSTAGE9 = 9, // TEV Stage 9. + GX_TEVSTAGE10 = 10, // TEV Stage 10. + GX_TEVSTAGE11 = 11, // TEV Stage 11. + GX_TEVSTAGE12 = 12, // TEV Stage 12. + GX_TEVSTAGE13 = 13, // TEV Stage 13. + GX_TEVSTAGE14 = 14, // TEV Stage 14. + GX_TEVSTAGE15 = 15, // TEV Stage 15. + + GX_MAXTEVSTAGE, // Max num TEV stages (16). +} GXTevStageID; + +// TEV register names. +typedef enum _GXTevRegID { + GX_TEVPREV = 0, // TEV register 3. Used primarily to store previous TEVStage output. + GX_TEVREG0 = 1, // TEV register 0. + GX_TEVREG1 = 2, // TEV register 1. + GX_TEVREG2 = 3, // TEV register 2. + + GX_MAX_TEVREG, // Max num TEV registers (4). +} GXTevRegID; + +// TEV operations. +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, // Alpha channel (14) + GX_TEV_COMP_A8_EQ = GX_TEV_COMP_RGB8_EQ // Alpha channel (15) +} GXTevOp; + +// TEV mode. +typedef enum _GXTevMode { + GX_MODULATE = 0, + GX_DECAL = 1, + GX_BLEND = 2, + GX_REPLACE = 3, + GX_PASSCLR = 4, +} GXTevMode; + +// TEV color channels. +// NB: we used to have this called GXTevColor (like TP). +typedef enum _GXTevColorChan { + GX_CH_RED = 0, + GX_CH_GREEN = 1, + GX_CH_BLUE = 2, + GX_CH_ALPHA = 3, +} GXTevColorChan; + +// TEV color arguments. +typedef enum _GXTevColorArg { + GX_CC_CPREV = 0, + GX_CC_APREV = 1, + GX_CC_C0 = 2, + GX_CC_C1 = 3, + GX_CC_C2 = 4, + GX_CC_A0 = 5, + GX_CC_A1 = 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, +} GXTevColorArg; + +// TEV alpha-specific arguments. +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, +} GXTevAlphaArg; + +// TEV bias. +typedef enum _GXTevBias { + GX_TB_ZERO = 0, + GX_TB_ADDHALF = 1, + GX_TB_SUBHALF = 2, + + GX_MAX_TEVBIAS, // Max num bias types (3). +} GXTevBias; + +// TEV clamp modes. +typedef enum _GXTevClampMode { + GX_TC_LINEAR = 0, + GX_TC_GE = 1, + GX_TC_EQ = 2, + GX_TC_LE = 3, + + GX_MAX_TEVCLAMPMODE, // Max num clamp modes (4). +} GXTevClampMode; + +// TEV scale types. These multiply the final TEVStage output by 1, 2, 4, or 0.5. +typedef enum _GXTevScale { + GX_CS_SCALE_1 = 0, + GX_CS_SCALE_2 = 1, + GX_CS_SCALE_4 = 2, + GX_CS_DIVIDE_2 = 3, + GX_MAX_TEVSCALE, // Max num scale types (4). +} GXTevScale; + +// TEV swap selections. +typedef enum _GXTevSwapSel { + GX_TEV_SWAP0 = 0, + GX_TEV_SWAP1 = 1, + GX_TEV_SWAP2 = 2, + GX_TEV_SWAP3 = 3, + GX_MAX_TEVSWAP, // Max num swap selections (4). +} GXTevSwapSel; + +// TEV const (konst) color IDs. +typedef enum _GXTevKColorID { + GX_KCOLOR0 = 0, // kColor 0. + GX_KCOLOR1 = 1, // kColor 1. + GX_KCOLOR2 = 2, // kColor 2. + GX_KCOLOR3 = 3, // kColor 3. + GX_MAX_KCOLOR, // Max num kColors (4). +} GXTevKColorID; + +// TEV const (konst) color selections. +typedef enum _GXTevKColorSel { + GX_TEV_KCSEL_1 = 0, + GX_TEV_KCSEL_7_8 = 1, + GX_TEV_KCSEL_3_4 = 2, + GX_TEV_KCSEL_5_8 = 3, + GX_TEV_KCSEL_1_2 = 4, + GX_TEV_KCSEL_3_8 = 5, + GX_TEV_KCSEL_1_4 = 6, + GX_TEV_KCSEL_1_8 = 7, + + GX_TEV_KCSEL_K0 = 12, + GX_TEV_KCSEL_K1 = 13, + GX_TEV_KCSEL_K2 = 14, + GX_TEV_KCSEL_K3 = 15, + + GX_TEV_KCSEL_K0_R = 16, + GX_TEV_KCSEL_K1_R = 17, + GX_TEV_KCSEL_K2_R = 18, + GX_TEV_KCSEL_K3_R = 19, + + GX_TEV_KCSEL_K0_G = 20, + GX_TEV_KCSEL_K1_G = 21, + GX_TEV_KCSEL_K2_G = 22, + GX_TEV_KCSEL_K3_G = 23, + + GX_TEV_KCSEL_K0_B = 24, + GX_TEV_KCSEL_K1_B = 25, + GX_TEV_KCSEL_K2_B = 26, + GX_TEV_KCSEL_K3_B = 27, + + GX_TEV_KCSEL_K0_A = 28, + GX_TEV_KCSEL_K1_A = 29, + GX_TEV_KCSEL_K2_A = 30, + GX_TEV_KCSEL_K3_A = 31, +} GXTevKColorSel; + +// TEV const (konst) alpha selectors. +typedef enum _GXTevKAlphaSel { + GX_TEV_KASEL_1 = 0, + GX_TEV_KASEL_7_8 = 1, + GX_TEV_KASEL_3_4 = 2, + GX_TEV_KASEL_5_8 = 3, + GX_TEV_KASEL_1_2 = 4, + GX_TEV_KASEL_3_8 = 5, + GX_TEV_KASEL_1_4 = 6, + GX_TEV_KASEL_1_8 = 7, + + GX_TEV_KASEL_K0_R = 16, + GX_TEV_KASEL_K1_R = 17, + GX_TEV_KASEL_K2_R = 18, + GX_TEV_KASEL_K3_R = 19, + + GX_TEV_KASEL_K0_G = 20, + GX_TEV_KASEL_K1_G = 21, + GX_TEV_KASEL_K2_G = 22, + GX_TEV_KASEL_K3_G = 23, + + GX_TEV_KASEL_K0_B = 24, + GX_TEV_KASEL_K1_B = 25, + GX_TEV_KASEL_K2_B = 26, + GX_TEV_KASEL_K3_B = 27, + + GX_TEV_KASEL_K0_A = 28, + GX_TEV_KASEL_K1_A = 29, + GX_TEV_KASEL_K2_A = 30, + GX_TEV_KASEL_K3_A = 31, +} GXTevKAlphaSel; + +//////////////////////////////////////////// + +/////////// OTHER FORMATS/MODES //////////// +// Frame buffer pixel formats. +typedef enum _GXPixelFmt { + GX_PF_RGB8_Z24 = 0, // Non-antialiased (RGB 888). + GX_PF_RGBA6_Z24 = 1, // Non-antialiased (RGBA 6666). + GX_PF_RGB565_Z16 = 2, // Anti-aliasing. + GX_PF_Z24 = 3, + GX_PF_Y8 = 4, + GX_PF_U8 = 5, + GX_PF_V8 = 6, + GX_PF_YUV420 = 7, + GX_MAX_PIXELFMT, // 8 +} GXPixelFmt; + +typedef GXPixelFmt _SDK_GXPixelFmt; + +// Compressed Z format. +typedef enum _GXZFmt16 { + GX_ZC_LINEAR = 0, // 16-bit linear. + GX_ZC_NEAR = 1, // Compressed format (14e2) for smaller far/near ratio. + GX_ZC_MID = 2, // Compressed format (13e3) for medium far/near ratio. + GX_ZC_FAR = 3, // Compressed format (12e4) for large far/near ratio. +} GXZFmt16; + +typedef GXZFmt16 _SDK_GXZFmt16; + +// Projection types. +typedef enum _GXProjectionType { + GX_PERSPECTIVE = 0, + GX_ORTHOGRAPHIC = 1, +} GXProjectionType; + +// FB clamp types. +typedef enum _GXFBClamp { + GX_CLAMP_NONE = 0, + GX_CLAMP_TOP = 1, + GX_CLAMP_BOTTOM = 2, + GX_CLAMP_BOTH = GX_CLAMP_TOP | GX_CLAMP_BOTTOM, +} GXFBClamp; + +// Z-Texture operations. +typedef enum _GXZTexOp { + GX_ZT_DISABLE = 0, + GX_ZT_ADD = 1, + GX_ZT_REPLACE = 2, + + GX_MAX_ZTEXOP, // Max num operations (3). +} GXZTexOp; + +// Perf-0 types. +typedef enum _GXPerf0 { + GX_PERF0_VERTICES = 0, + GX_PERF0_CLIP_VTX = 1, + GX_PERF0_CLIP_CLKS = 2, + GX_PERF0_XF_WAIT_IN = 3, + GX_PERF0_XF_WAIT_OUT = 4, + GX_PERF0_XF_XFRM_CLKS = 5, + GX_PERF0_XF_LIT_CLKS = 6, + GX_PERF0_XF_BOT_CLKS = 7, + GX_PERF0_XF_REGLD_CLKS = 8, + GX_PERF0_XF_REGRD_CLKS = 9, + GX_PERF0_CLIP_RATIO = 10, + + GX_PERF0_TRIANGLES = 11, + GX_PERF0_TRIANGLES_CULLED = 12, + GX_PERF0_TRIANGLES_PASSED = 13, + GX_PERF0_TRIANGLES_SCISSORED = 14, + GX_PERF0_TRIANGLES_0TEX = 15, + GX_PERF0_TRIANGLES_1TEX = 16, + GX_PERF0_TRIANGLES_2TEX = 17, + GX_PERF0_TRIANGLES_3TEX = 18, + GX_PERF0_TRIANGLES_4TEX = 19, + GX_PERF0_TRIANGLES_5TEX = 20, + GX_PERF0_TRIANGLES_6TEX = 21, + GX_PERF0_TRIANGLES_7TEX = 22, + GX_PERF0_TRIANGLES_8TEX = 23, + GX_PERF0_TRIANGLES_0CLR = 24, + GX_PERF0_TRIANGLES_1CLR = 25, + GX_PERF0_TRIANGLES_2CLR = 26, + + GX_PERF0_QUAD_0CVG = 27, + GX_PERF0_QUAD_NON0CVG = 28, + GX_PERF0_QUAD_1CVG = 29, + GX_PERF0_QUAD_2CVG = 30, + GX_PERF0_QUAD_3CVG = 31, + GX_PERF0_QUAD_4CVG = 32, + GX_PERF0_AVG_QUAD_CNT = 33, + + GX_PERF0_CLOCKS = 34, + GX_PERF0_NONE = 35, +} GXPerf0; + +// Perf-1 types. +typedef enum _GXPerf1 { + GX_PERF1_TEXELS = 0, + GX_PERF1_TX_IDLE = 1, + GX_PERF1_TX_REGS = 2, + GX_PERF1_TX_MEMSTALL = 3, + GX_PERF1_TC_CHECK1_2 = 4, + GX_PERF1_TC_CHECK3_4 = 5, + GX_PERF1_TC_CHECK5_6 = 6, + GX_PERF1_TC_CHECK7_8 = 7, + GX_PERF1_TC_MISS = 8, + + GX_PERF1_VC_ELEMQ_FULL = 9, + GX_PERF1_VC_MISSQ_FULL = 10, + GX_PERF1_VC_MEMREQ_FULL = 11, + GX_PERF1_VC_STATUS7 = 12, + GX_PERF1_VC_MISSREP_FULL = 13, + GX_PERF1_VC_STREAMBUF_LOW = 14, + GX_PERF1_VC_ALL_STALLS = 15, + GX_PERF1_VERTICES = 16, + + GX_PERF1_FIFO_REQ = 17, + GX_PERF1_CALL_REQ = 18, + GX_PERF1_VC_MISS_REQ = 19, + GX_PERF1_CP_ALL_REQ = 20, + + GX_PERF1_CLOCKS = 21, + GX_PERF1_NONE = 22, +} GXPerf1; + +// Vertex cache perf types. +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; + +// Miscellaneous token types. +typedef enum _GXMiscToken { + GX_MT_NULL = 0, + GX_MT_XF_FLUSH = 1, + GX_MT_DL_SAVE_CONTEXT = 2, + GX_MT_ABORT_WAIT_COPYOUT = 3, +} GXMiscToken; + +//////////////////////////////////////////// + +//////////// HARDWARE REGISTERS //////////// + +// Flags for setting GXData dirtyState. +typedef enum _GXDirtyFlag { + GX_DIRTY_SU_TEX = (1 << 0), // 0x1 + GX_DIRTY_BP_MASK = (1 << 1), // 0x2 + GX_DIRTY_GEN_MODE = (1 << 2), // 0x4 + GX_DIRTY_VCD = (1 << 3), // 0x8 + GX_DIRTY_VAT = (1 << 4), // 0x10 + // . . . + GX_DIRTY_AMB_COLOR0 = (1 << 8), // 0x100 + GX_DIRTY_AMB_COLOR1 = (1 << 9), // 0x200 + GX_DIRTY_MAT_COLOR0 = (1 << 10), // 0x400 + GX_DIRTY_MAT_COLOR1 = (1 << 11), // 0x800 + GX_DIRTY_CHAN_COLOR0 = (1 << 12), // 0x1000 + GX_DIRTY_CHAN_COLOR1 = (1 << 13), // 0x2000 + GX_DIRTY_CHAN_ALPHA0 = (1 << 14), // 0x4000 + GX_DIRTY_CHAN_ALPHA1 = (1 << 15), // 0x8000 + GX_DIRTY_TEX0 = (1 << 16), // 0x10000 + GX_DIRTY_TEX1 = (1 << 17), // 0x20000 + GX_DIRTY_TEX2 = (1 << 18), // 0x40000 + GX_DIRTY_TEX3 = (1 << 19), // 0x80000 + GX_DIRTY_TEX4 = (1 << 20), // 0x100000 + GX_DIRTY_TEX5 = (1 << 21), // 0x200000 + GX_DIRTY_TEX6 = (1 << 22), // 0x400000 + GX_DIRTY_TEX7 = (1 << 23), // 0x800000 + GX_DIRTY_NUM_COLORS = (1 << 24), // 0x1000000 + GX_DIRTY_NUM_TEX = (1 << 25), // 0x2000000 + GX_DIRTY_MTX_IDX = (1 << 26), // 0x4000000 + GX_DIRTY_PROJECTION = (1 << 27), // 0x8000000 + GX_DIRTY_VIEWPORT = (1 << 28), // 0x10000000 + + GX_AMB_MAT_MASK = GX_DIRTY_AMB_COLOR0 | GX_DIRTY_AMB_COLOR1 | GX_DIRTY_MAT_COLOR0 | GX_DIRTY_MAT_COLOR1, // 0xF00 + + GX_LIGHT_CHAN_MASK + = GX_DIRTY_CHAN_COLOR0 | GX_DIRTY_CHAN_COLOR1 | GX_DIRTY_CHAN_ALPHA0 | GX_DIRTY_CHAN_ALPHA1 | GX_DIRTY_NUM_COLORS, // 0x100F000 + + GX_TEX_GEN_MASK = 0x2FF0000, // all GX_DIRTY_TEXs | GX_DIRTY_NUM_TEX +} GXDirtyFlag; + +// Commands for interacting with the GXFifo pipe. +typedef enum _GXFifoCmd { + GX_FIFO_CMD_NOOP = 0x00, // no operation + + GX_FIFO_CMD_LOAD_BP_REG = 0x61, // load blitting processor reg + GX_FIFO_CMD_LOAD_CP_REG = 0x08, // load command processor reg + GX_FIFO_CMD_LOAD_XF_REG = 0x10, // load transform unit reg + + GX_FIFO_CMD_LOAD_INDX_A = 0x20, // load index A + GX_FIFO_CMD_LOAD_INDX_B = 0x28, // load index B + GX_FIFO_CMD_LOAD_INDX_C = 0x30, // load index C + GX_FIFO_CMD_LOAD_INDX_D = 0x38, // load index D + + GX_FIFO_CMD_CALL_DL = 0x40, // call displaylist + GX_FIFO_CMD_INVAL_VTX = 0x48, // invalid vertex + +} GXFifoCmd; + +// Texture register fields for XF (transform) unit. +typedef enum _GXXfTexReg { + GX_XF_TEX_PROJ_ST = 0, // (s,t) (2x4) + GX_XF_TEX_PROJ_STQ = 1, // (s,t,q) (3x4) + + GX_XF_TEX_FORM_AB11 = 0, // (A, B, 1.0f, 1.0f), used for regular tex src + GX_XF_TEX_FORM_ABC1 = 1, // (A, B, C, 1.0f), used for geometry/normal src +} GXXfTexReg; + +// General texture commands. +typedef enum _GXXfTexGen { + GX_XF_TG_REGULAR = 0, // Regular; transform incoming data. + GX_XF_TG_BUMP = 1, // Texgen bump mapping. + GX_XF_TG_CLR0 = 2, // Color texgen for color 0 (s,t) = (r, g:b) + GX_XF_TG_CLR1 = 3, // Color texgen for color 1 (s,t) = (r, g:b) +} GXXfTexGen; + +// Transform memory types. +typedef enum _GXXfMem { + GX_XF_MEM_POSMTX = 0x000, // position coord matrix + GX_XF_MEM_NRMMTX = 0x400, // normal coord matrix + GX_XF_MEM_DUALTEXMTX = 0x500, // dual texture matrix + GX_XF_MEM_LIGHTOBJ = 0x600, // light object +} GXXfMem; + +// Blitting processor registers. +typedef enum _GXBPRegs { + // gen mode + GX_BP_REG_GENMODE = 0x0, // gen mode + + // display copy filters + GX_BP_REG_DISPCOPYFILTER0 = 0x1, // display copy filter 0 + GX_BP_REG_DISPCOPYFILTER1 = 0x2, // display copy filter 1 + GX_BP_REG_DISPCOPYFILTER2 = 0x3, // display copy filter 2 + GX_BP_REG_DISPCOPYFILTER3 = 0x4, // display copy filter 3 + + // indirect matrices + GX_BP_REG_INDMTX0A = 0x6, // indirect matrix 0A + GX_BP_REG_INDMTX0B = 0x7, // indirect matrix 0B + GX_BP_REG_INDMTX0C = 0x8, // indirect matrix 0C + GX_BP_REG_INDMTX1A = 0x9, // indirect matrix 1A + GX_BP_REG_INDMTX1B = 0xA, // indirect matrix 1B + GX_BP_REG_INDMTX1C = 0xB, // indirect matrix 1C + GX_BP_REG_INDMTX2A = 0xC, // indirect matrix 2A + GX_BP_REG_INDMTX2B = 0xD, // indirect matrix 2B + GX_BP_REG_INDMTX2C = 0xE, // indirect matrix 2C + GX_BP_REG_INDIMASK = 0xF, // indirect mask + + // indirect TEV stages + GX_BP_REG_INDTEVSTAGE0 = 0x10, // indirect TEV stage 0 + GX_BP_REG_INDTEVSTAGE1 = 0x11, // indirect TEV stage 1 + GX_BP_REG_INDTEVSTAGE2 = 0x12, // indirect TEV stage 2 + GX_BP_REG_INDTEVSTAGE3 = 0x13, // indirect TEV stage 3 + GX_BP_REG_INDTEVSTAGE4 = 0x14, // indirect TEV stage 4 + GX_BP_REG_INDTEVSTAGE5 = 0x15, // indirect TEV stage 5 + GX_BP_REG_INDTEVSTAGE6 = 0x16, // indirect TEV stage 6 + GX_BP_REG_INDTEVSTAGE7 = 0x17, // indirect TEV stage 7 + GX_BP_REG_INDTEVSTAGE8 = 0x18, // indirect TEV stage 8 + GX_BP_REG_INDTEVSTAGE9 = 0x19, // indirect TEV stage 9 + GX_BP_REG_INDTEVSTAGE10 = 0x1A, // indirect TEV stage 10 + GX_BP_REG_INDTEVSTAGE11 = 0x1B, // indirect TEV stage 11 + GX_BP_REG_INDTEVSTAGE12 = 0x1C, // indirect TEV stage 12 + GX_BP_REG_INDTEVSTAGE13 = 0x1D, // indirect TEV stage 13 + GX_BP_REG_INDTEVSTAGE14 = 0x1E, // indirect TEV stage 14 + GX_BP_REG_INDTEVSTAGE15 = 0x1F, // indirect TEV stage 15 + + // performance manips + GX_BP_REG_SCISSORTL = 0x20, // scissor top left + GX_BP_REG_SCISSORBR = 0x21, // scissor bottom right + GX_BP_REG_LINEPTWIDTH = 0x22, // line point width + GX_BP_REG_PERF0TRI = 0x23, // performance 0 (triangle) + GX_BP_REG_PERF0QUAD = 0x24, // performance 0 (quad) + + // rasters + GX_BP_REG_RAS1_SS0 = 0x25, + GX_BP_REG_RAS1_SS1 = 0x26, + GX_BP_REG_RAS1_IREF = 0x27, + GX_BP_REG_RAS1_TREF0 = 0x28, + GX_BP_REG_RAS1_TREF1 = 0x29, + GX_BP_REG_RAS1_TREF2 = 0x2A, + GX_BP_REG_RAS1_TREF3 = 0x2B, + GX_BP_REG_RAS1_TREF4 = 0x2C, + GX_BP_REG_RAS1_TREF5 = 0x2D, + GX_BP_REG_RAS1_TREF6 = 0x2E, + GX_BP_REG_RAS1_TREF7 = 0x2F, + + // setup sizes + GX_BP_REG_SU_SSIZE0 = 0x30, + GX_BP_REG_SU_TSIZE0 = 0x31, + GX_BP_REG_SU_SSIZE1 = 0x32, + GX_BP_REG_SU_TSIZE1 = 0x33, + GX_BP_REG_SU_SSIZE2 = 0x34, + GX_BP_REG_SU_TSIZE2 = 0x35, + GX_BP_REG_SU_SSIZE3 = 0x36, + GX_BP_REG_SU_TSIZE3 = 0x37, + GX_BP_REG_SU_SSIZE4 = 0x38, + GX_BP_REG_SU_TSIZE4 = 0x39, + GX_BP_REG_SU_SSIZE5 = 0x3A, + GX_BP_REG_SU_TSIZE5 = 0x3B, + GX_BP_REG_SU_SSIZE6 = 0x3C, + GX_BP_REG_SU_TSIZE6 = 0x3D, + GX_BP_REG_SU_SSIZE7 = 0x3E, + GX_BP_REG_SU_TSIZE7 = 0x3F, + + // Z and blend controls + GX_BP_REG_ZMODE = 0x40, + GX_BP_REG_BLENDMODE = 0x41, + GX_BP_REG_DSTALPHA = 0x42, + GX_BP_REG_ZCONTROL = 0x43, + GX_BP_REG_FIELDMASK = 0x44, + GX_BP_REG_DRAWDONE = 0x45, + GX_BP_REG_PETOKEN = 0x47, + GX_BP_REG_PETOKENINT = 0x48, + + // copying + GX_BP_REG_TEXCOPYSRCXY = 0x49, + GX_BP_REG_TEXCOPYSRCWH = 0x4A, + GX_BP_REG_TEXCOPYDST = 0x4B, + GX_BP_REG_DISPCOPYSTRIDE = 0x4D, + GX_BP_REG_DISPCOPYSCALEY = 0x4E, + GX_BP_REG_COPYCLEARAR = 0x4F, + GX_BP_REG_COPYCLEARGB = 0x50, + GX_BP_REG_COPYCLEARZ = 0x51, + GX_BP_REG_COPYFILTER0 = 0x53, + GX_BP_REG_COPYFILTER1 = 0x54, + + // + GX_BP_REG_BOUNDINGBOX0 = 0x55, + GX_BP_REG_BOUNDINGBOX1 = 0x56, + + GX_BP_REG_SCISSOROFFSET = 0x59, + + // texture memory + GX_BP_REG_TMEMPRELOADADDR = 0x60, + GX_BP_REG_TMEMPRELOADEVEN = 0x61, + GX_BP_REG_TMEMPRELOADODD = 0x62, + GX_BP_REG_TMEMPRELOADMODE = 0x63, + GX_BP_REG_TMEMTLUTSRC = 0x64, + GX_BP_REG_TMEMTLUTDST = 0x65, + GX_BP_REG_TMEMTEXINVALIDATE = 0x66, + + // performance 1 + GX_BP_REG_PERF1 = 0x67, + GX_BP_REG_FIELDMODE = 0x68, + + // set modes + GX_BP_REG_SETMODE0_TEX0 = 0x80, + GX_BP_REG_SETMODE0_TEX1 = 0x81, + GX_BP_REG_SETMODE0_TEX2 = 0x82, + GX_BP_REG_SETMODE0_TEX3 = 0x83, + GX_BP_REG_SETMODE1_TEX0 = 0x84, + GX_BP_REG_SETMODE1_TEX1 = 0x85, + GX_BP_REG_SETMODE1_TEX2 = 0x86, + GX_BP_REG_SETMODE1_TEX3 = 0x87, + + // set images + GX_BP_REG_SETIMAGE0_TEX0 = 0x88, + GX_BP_REG_SETIMAGE0_TEX1 = 0x89, + GX_BP_REG_SETIMAGE0_TEX2 = 0x8A, + GX_BP_REG_SETIMAGE0_TEX3 = 0x8B, + GX_BP_REG_SETIMAGE1_TEX0 = 0x8C, + GX_BP_REG_SETIMAGE1_TEX1 = 0x8D, + GX_BP_REG_SETIMAGE1_TEX2 = 0x8E, + GX_BP_REG_SETIMAGE1_TEX3 = 0x8F, + GX_BP_REG_SETIMAGE2_TEX0 = 0x90, + GX_BP_REG_SETIMAGE2_TEX1 = 0x91, + GX_BP_REG_SETIMAGE2_TEX2 = 0x92, + GX_BP_REG_SETIMAGE2_TEX3 = 0x93, + GX_BP_REG_SETIMAGE3_TEX0 = 0x94, + GX_BP_REG_SETIMAGE3_TEX1 = 0x95, + GX_BP_REG_SETIMAGE3_TEX2 = 0x96, + GX_BP_REG_SETIMAGE3_TEX3 = 0x97, + + // set texture lookups + GX_BP_REG_SETTLUT_TEX0 = 0x98, + GX_BP_REG_SETTLUT_TEX1 = 0x99, + GX_BP_REG_SETTLUT_TEX2 = 0x9A, + GX_BP_REG_SETTLUT_TEX3 = 0x9B, + + // set modes continued + GX_BP_REG_SETMODE0_TEX4 = 0xA0, + GX_BP_REG_SETMODE0_TEX5 = 0xA1, + GX_BP_REG_SETMODE0_TEX6 = 0xA2, + GX_BP_REG_SETMODE0_TEX7 = 0xA3, + GX_BP_REG_SETMODE1_TEX4 = 0xA4, + GX_BP_REG_SETMODE1_TEX5 = 0xA5, + GX_BP_REG_SETMODE1_TEX6 = 0xA6, + GX_BP_REG_SETMODE1_TEX7 = 0xA7, + + // set images continued + GX_BP_REG_SETIMAGE0_TEX4 = 0xA8, + GX_BP_REG_SETIMAGE0_TEX5 = 0xA9, + GX_BP_REG_SETIMAGE0_TEX6 = 0xAA, + GX_BP_REG_SETIMAGE0_TEX7 = 0xAB, + GX_BP_REG_SETIMAGE1_TEX4 = 0xAC, + GX_BP_REG_SETIMAGE1_TEX5 = 0xAD, + GX_BP_REG_SETIMAGE1_TEX6 = 0xAE, + GX_BP_REG_SETIMAGE1_TEX7 = 0xAF, + GX_BP_REG_SETIMAGE2_TEX4 = 0xB0, + GX_BP_REG_SETIMAGE2_TEX5 = 0xB1, + GX_BP_REG_SETIMAGE2_TEX6 = 0xB2, + GX_BP_REG_SETIMAGE2_TEX7 = 0xB3, + GX_BP_REG_SETIMAGE3_TEX4 = 0xB4, + GX_BP_REG_SETIMAGE3_TEX5 = 0xB5, + GX_BP_REG_SETIMAGE3_TEX6 = 0xB6, + GX_BP_REG_SETIMAGE3_TEX7 = 0xB7, + + // set texture lookups continued + GX_BP_REG_SETTLUT_TEX4 = 0xB8, + GX_BP_REG_SETTLUT_TEX5 = 0xB9, + GX_BP_REG_SETTLUT_TEX6 = 0xBA, + GX_BP_REG_SETTLUT_TEX7 = 0xBB, + + // TEV color manips + GX_BP_REG_TEVCOLORCOMBINER0 = 0xC0, + GX_BP_REG_TEVALPHACOMBINER0 = 0xC1, + GX_BP_REG_TEVCOLORCOMBINER1 = 0xC2, + GX_BP_REG_TEVALPHACOMBINER1 = 0xC3, + GX_BP_REG_TEVCOLORCOMBINER2 = 0xC4, + GX_BP_REG_TEVALPHACOMBINER2 = 0xC5, + GX_BP_REG_TEVCOLORCOMBINER3 = 0xC6, + GX_BP_REG_TEVALPHACOMBINER3 = 0xC7, + GX_BP_REG_TEVCOLORCOMBINER4 = 0xC8, + GX_BP_REG_TEVALPHACOMBINER4 = 0xC9, + GX_BP_REG_TEVCOLORCOMBINER5 = 0xCA, + GX_BP_REG_TEVALPHACOMBINER5 = 0xCB, + GX_BP_REG_TEVCOLORCOMBINER6 = 0xCC, + GX_BP_REG_TEVALPHACOMBINER6 = 0xCD, + GX_BP_REG_TEVCOLORCOMBINER7 = 0xCE, + GX_BP_REG_TEVALPHACOMBINER7 = 0xCF, + GX_BP_REG_TEVCOLORCOMBINER8 = 0xD0, + GX_BP_REG_TEVALPHACOMBINER8 = 0xD1, + GX_BP_REG_TEVCOLORCOMBINER9 = 0xD2, + GX_BP_REG_TEVALPHACOMBINER9 = 0xD3, + GX_BP_REG_TEVCOLORCOMBINER10 = 0xD4, + GX_BP_REG_TEVALPHACOMBINER10 = 0xD5, + GX_BP_REG_TEVCOLORCOMBINER11 = 0xD6, + GX_BP_REG_TEVALPHACOMBINER11 = 0xD7, + GX_BP_REG_TEVCOLORCOMBINER12 = 0xD8, + GX_BP_REG_TEVALPHACOMBINER12 = 0xD9, + GX_BP_REG_TEVCOLORCOMBINER13 = 0xDA, + GX_BP_REG_TEVALPHACOMBINER13 = 0xDB, + GX_BP_REG_TEVCOLORCOMBINER14 = 0xDC, + GX_BP_REG_TEVALPHACOMBINER14 = 0xDD, + GX_BP_REG_TEVCOLORCOMBINER15 = 0xDE, + GX_BP_REG_TEVALPHACOMBINER15 = 0xDF, + + // TEV registers + GX_BP_REG_TEVREG0LO = 0xE0, + GX_BP_REG_TEVREG0HI = 0xE1, + GX_BP_REG_TEVREG1LO = 0xE2, + GX_BP_REG_TEVREG1HI = 0xE3, + GX_BP_REG_TEVREG2LO = 0xE4, + GX_BP_REG_TEVREG2HI = 0xE5, + GX_BP_REG_TEVREG3LO = 0xE6, + GX_BP_REG_TEVREG3HI = 0xE7, + + // fog registers + GX_BP_REG_FOGRANGE = 0xE8, + GX_BP_REG_FOGRANGEK0 = 0xE9, + GX_BP_REG_FOGRANGEK1 = 0xEA, + GX_BP_REG_FOGRANGEK2 = 0xEB, + GX_BP_REG_FOGRANGEK3 = 0xEC, + GX_BP_REG_FOGRANGEK4 = 0xED, + GX_BP_REG_FOGPARAM0 = 0xEE, + GX_BP_REG_FOGPARAM1 = 0xEF, + GX_BP_REG_FOGPARAM2 = 0xF0, + GX_BP_REG_FOGPARAM3 = 0xF1, + GX_BP_REG_FOGCOLOR = 0xF2, + + // performance manip registers + GX_BP_REG_ALPHACOMPARE = 0xF3, + GX_BP_REG_ZTEXTURE0 = 0xF4, + GX_BP_REG_ZTEXTURE1 = 0xF5, + + // TEV K selectors + GX_BP_REG_TEVKSEL0 = 0xF6, + GX_BP_REG_TEVKSEL1 = 0xF7, + GX_BP_REG_TEVKSEL2 = 0xF8, + GX_BP_REG_TEVKSEL3 = 0xF9, + GX_BP_REG_TEVKSEL4 = 0xFA, + GX_BP_REG_TEVKSEL5 = 0xFB, + GX_BP_REG_TEVKSEL6 = 0xFC, + GX_BP_REG_TEVKSEL7 = 0xFD, + + // SS mask + GX_BP_REG_SSMASK = 0xFE, +} GXBPRegs; + +// Command processor registers. +typedef enum _GXCPRegs { + GX_CP_REG_MTXIDXA = 0x30, // Matrix index A + GX_CP_REG_MTXIDXB = 0x40, // Matrix index B + GX_CP_REG_VCD_LO = 0x50, // Vertex descriptor (lo) + GX_CP_REG_VCD_HI = 0x60, // Vertex descriptor (hi) + GX_CP_REG_VAT_GRP0 = 0x70, // Vertex attribute table (group 0) + GX_CP_REG_VAT_GRP1 = 0x80, // Vertex attribute table (group 1) + GX_CP_REG_VAT_GRP2 = 0x90, // Vertex attribute table (group 2) + GX_CP_REG_ARRAYBASE = 0xA0, // Vertex array start/base + GX_CP_REG_ARRAYSTRIDE = 0xB0, // Vertex array stride +} GXCPRegs; + +// Transform unit registers. +typedef enum _GXXFRegs { + GX_XF_REG_ERROR = 0x1000, + GX_XF_REG_DIAGNOSTICS = 0x1001, + GX_XF_REG_STATE0 = 0x1002, + GX_XF_REG_STATE1 = 0x1003, + GX_XF_REG_CLOCK = 0x1004, + GX_XF_REG_CLIPDISABLE = 0x1005, + GX_XF_REG_PERF0 = 0x1006, + GX_XF_REG_PERF1 = 0x1007, + GX_XF_REG_INVERTEXSPEC = 0x1008, + GX_XF_REG_NUMCOLORS = 0x1009, + GX_XF_REG_AMBIENT0 = 0x100A, + GX_XF_REG_AMBIENT1 = 0x100B, + GX_XF_REG_MATERIAL0 = 0x100C, + GX_XF_REG_MATERIAL1 = 0x100D, + GX_XF_REG_COLOR0CNTRL = 0x100E, + GX_XF_REG_COLOR1CNTRL = 0x100F, + GX_XF_REG_ALPHA0CNTRL = 0x1010, + GX_XF_REG_ALPHA1CNTRL = 0x1011, + GX_XF_REG_DUALTEXTRAN = 0x1012, + GX_XF_REG_MATRIXINDEX0 = 0x1018, + GX_XF_REG_MATRIXINDEX1 = 0x1019, + GX_XF_REG_SCALEX = 0x101A, + GX_XF_REG_SCALEY = 0x101B, + GX_XF_REG_SCALEZ = 0x101C, + GX_XF_REG_OFFSETX = 0x101D, + GX_XF_REG_OFFSETY = 0x101E, + GX_XF_REG_OFFSETZ = 0x101F, + GX_XF_REG_PROJECTIONA = 0x1020, + GX_XF_REG_PROJECTIONB = 0x1021, + GX_XF_REG_PROJECTIONC = 0x1022, + GX_XF_REG_PROJECTIOND = 0x1023, + GX_XF_REG_PROJECTIONE = 0x1024, + GX_XF_REG_PROJECTIONF = 0x1025, + GX_XF_REG_PROJECTORTHO = 0x1026, + GX_XF_REG_NUMTEX = 0x103F, + GX_XF_REG_TEX0 = 0x1040, + GX_XF_REG_TEX1 = 0x1041, + GX_XF_REG_TEX2 = 0x1042, + GX_XF_REG_TEX3 = 0x1043, + GX_XF_REG_TEX4 = 0x1044, + GX_XF_REG_TEX5 = 0x1045, + GX_XF_REG_TEX6 = 0x1046, + GX_XF_REG_TEX7 = 0x1047, + GX_XF_REG_DUALTEX0 = 0x1050, + GX_XF_REG_DUALTEX1 = 0x1051, + GX_XF_REG_DUALTEX2 = 0x1052, + GX_XF_REG_DUALTEX3 = 0x1053, + GX_XF_REG_DUALTEX4 = 0x1054, + GX_XF_REG_DUALTEX5 = 0x1055, + GX_XF_REG_DUALTEX6 = 0x1056, + GX_XF_REG_DUALTEX7 = 0x1057, +} GXXFRegs; + +// BP GenMode locators. +typedef enum _GXBPGenMode { + // Active texture counts [28-31] + GX_BP_GENMODE_NUMTEX_ST = 28, + GX_BP_GENMODE_NUMTEX_END = 31, + + // Color/channel counts [25-27] + GX_BP_GENMODE_NUMCOLORS_ST = 25, + GX_BP_GENMODE_NUMCOLORS_END = 27, + + // Multisample mode [22-22] + GX_BP_GENMODE_MULTISAMPLE_ST = 22, + GX_BP_GENMODE_MULTISAMPLE_END = 22, + + // Cull mode [16-17] + GX_BP_GENMODE_CULLMODE_ST = 16, + GX_BP_GENMODE_CULLMODE_END = 17, + + // Indirect stage counts [13-15] + GX_BP_GENMODE_NUMINDSTAGES_ST = 13, + GX_BP_GENMODE_NUMINDSTAGES_END = 15, + + // Toggle co-planar/Z-freeze [12-12] + GX_BP_GENMODE_COPLANAR_ST = 12, + GX_BP_GENMODE_COPLANAR_END = 12, +} GXBPGenMode; + +// BP locators for indirect texture matrices (same for A, B, and C). +typedef enum _GXBPIndMtx { + // Texture offset matrix [0][0] [21-31] + GX_BP_INDMTX_M00_ST = 21, + GX_BP_INDMTX_M00_END = 31, + + // Texture offset matrix [1][0] [10-20] + GX_BP_INDMTX_M10_ST = 10, + GX_BP_INDMTX_M10_END = 20, + + // Texture scaling exponent (2^x) [8-9] + GX_BP_INDMTX_EXP_ST = 8, + GX_BP_INDMTX_EXP_END = 9, +} GXBPIndMtx; + +// BP locators for indirect texture masks. +typedef enum _GXBPIndIMask { + // Indirect mask [24-31] + GX_BP_INDIMASK_ST = 24, + GX_BP_INDIMASK_END = 31, +} GXBPIndIMask; + +// BP locators for indirect texture environment details. +typedef enum _GXBPIndTevStage { + // Indirect texture stage ID [30-31] + GX_BP_INDTEV_STAGE_ST = 30, + GX_BP_INDTEV_STAGE_END = 31, + + // Indirect texture format [28-29] + GX_BP_INDTEV_FMT_ST = 28, + GX_BP_INDTEV_FMT_END = 29, + + // Indirect texture bias [25-27] + GX_BP_INDTEV_BIAS_ST = 25, + GX_BP_INDTEV_BIAS_END = 27, + + // Indirect texture alpha [23-24] + GX_BP_INDTEV_ALPHA_ST = 23, + GX_BP_INDTEV_ALPHA_END = 24, + + // Indirect texture matrices [19-22] + GX_BP_INDTEV_MTX_ST = 19, + GX_BP_INDTEV_MTX_END = 22, + + // Indirect texture S component wrap factor [16-18] + GX_BP_INDTEV_WRAPS_ST = 16, + GX_BP_INDTEV_WRAPS_END = 18, + + // Indirect texture T component wrap factor [13-15] + GX_BP_INDTEV_WRAPT_ST = 13, + GX_BP_INDTEV_WRAPT_END = 15, + + // Indirect texture unmodified texcoord setting (for mipmaps) [12-12] + GX_BP_INDTEV_UNMODTEXCOORD_ST = 12, + GX_BP_INDTEV_UNMODTEXCOORD_END = 12, + + // Indiret texture add previous results setting [11-11] + GX_BP_INDTEV_ADDPREV_ST = 11, + GX_BP_INDTEV_ADDPREV_END = 11, +} GXBPIndTevStage; + +// BP locators for top-left scissor. +typedef enum _GXBPScissorTL { + // Top component [21-31] + GX_BP_SCISSORTL_TOP_ST = 21, + GX_BP_SCISSORTL_TOP_END = 31, + + // Left component [9-19] + GX_BP_SCISSORTL_LEFT_ST = 9, + GX_BP_SCISSORTL_LEFT_END = 19, +} GXBPScissorTL; + +// BP locators for bottom-right scissor. +typedef enum _GXBPScissorBR { + // Bottom component [21-31] + GX_BP_SCISSORBR_BOT_ST = 21, + GX_BP_SCISSORBR_BOT_END = 31, + + // Right component [9-19] + GX_BP_SCISSORBR_RIGHT_ST = 9, + GX_BP_SCISSORBR_RIGHT_END = 19, +} GXBPScissorBR; + +// BP locators for line and point settings. +typedef enum _GXBPLinePtWidth { + // Line size/width [24-31] + GX_BP_LINEPTWIDTH_LINESZ_ST = 24, + GX_BP_LINEPTWIDTH_LINESZ_END = 31, + + // Point size [16-23] + GX_BP_LINEPTWIDTH_POINTSZ_ST = 16, + GX_BP_LINEPTWIDTH_POINTSZ_END = 23, + + // Line offset [13-15] + GX_BP_LINEPTWIDTH_LINEOFS_ST = 13, + GX_BP_LINEPTWIDTH_LINEOFS_END = 15, + + // Point offset [10-12] + GX_BP_LINEPTWIDTH_POINTOFS_ST = 10, + GX_BP_LINEPTWIDTH_POINTOFS_END = 12, + + // Interlacing adjustment for aspect ratio [9-9] + GX_BP_LINEPTWIDTH_ADJUST_ST = 9, + GX_BP_LINEPTWIDTH_ADJUST_END = 9, +} GXBPLinePtWidth; + +// BP locators for raster 1 SS0. +typedef enum _GXBPRas1SS0 { + // S-component scale (stage 0) [28-31] + GX_BP_RAS1_SS0_S0_ST = 28, + GX_BP_RAS1_SS0_S0_END = 31, + + // T-component scale (stage 0) [24-27] + GX_BP_RAS1_SS0_T0_ST = 24, + GX_BP_RAS1_SS0_T0_END = 27, + + // S-component scale (stage 1) [20-23] + GX_BP_RAS1_SS0_S1_ST = 20, + GX_BP_RAS1_SS0_S1_END = 23, + + // T-component scale (stage 1) [16-19] + GX_BP_RAS1_SS0_T1_ST = 16, + GX_BP_RAS1_SS0_T1_END = 19, +} GXBPRas1SS0; + +// BP locators for raster 1 SS1. +typedef enum _GXBPRas1SS1 { + // S-component scale (stage 2) [28-31] + GX_BP_RAS1_SS1_S2_ST = 28, + GX_BP_RAS1_SS1_S2_END = 31, + + // T-component scale (stage 2) [24-27] + GX_BP_RAS1_SS1_T2_ST = 24, + GX_BP_RAS1_SS1_T2_END = 27, + + // S-component scale (stage 3) [20-23] + GX_BP_RAS1_SS1_S3_ST = 20, + GX_BP_RAS1_SS1_S3_END = 23, + + // T-component scale (stage 3) [16-19] + GX_BP_RAS1_SS1_T3_ST = 16, + GX_BP_RAS1_SS1_T3_END = 19, +} GXBPRas1SS1; + +// BP locators for raster 1 ID-reference. +typedef enum _GXBPRasIRef { + // Texmap ID (stage 0) [29-31] + GX_BP_RAS1_IREF_MAP0_ST = 29, + GX_BP_RAS1_IREF_MAP0_END = 31, + + // Texcoord ID (stage 0) [26-28] + GX_BP_RAS1_IREF_TXC0_ST = 26, + GX_BP_RAS1_IREF_TXC0_END = 28, + + // Texmap ID (stage 1) [23-25] + GX_BP_RAS1_IREF_MAP1_ST = 23, + GX_BP_RAS1_IREF_MAP1_END = 25, + + // Texcoord ID (stage 1) [20-22] + GX_BP_RAS1_IREF_TXC1_ST = 20, + GX_BP_RAS1_IREF_TXC1_END = 22, + + // Texmap ID (stage 2) [17-19] + GX_BP_RAS1_IREF_MAP2_ST = 17, + GX_BP_RAS1_IREF_MAP2_END = 19, + + // Texcoord ID (stage 2) [14-16] + GX_BP_RAS1_IREF_TXC2_ST = 14, + GX_BP_RAS1_IREF_TXC2_END = 16, + + // Texmap ID (stage 3) [11-13] + GX_BP_RAS1_IREF_MAP3_ST = 11, + GX_BP_RAS1_IREF_MAP3_END = 13, + + // Texcoord ID (stage 3) [8-10] + GX_BP_RAS1_IREF_TXC3_ST = 8, + GX_BP_RAS1_IREF_TXC3_END = 10, +} GXBPRasIRef; + +// BP locators for setup size. +typedef enum _GXBPSUSSize { + // Use line offsets [13-13] + GX_BP_SU_SSIZE_USELINEOFS_ST = 13, + GX_BP_SU_SSIZE_USELINEOFS_END = 13, + + // Use point offsets [12-12] + GX_BP_SU_SSIZE_USEPTOFS_ST = 12, + GX_BP_SU_SSIZE_USEPTOFS_END = 12, +} GXBPSUSSize; + +// BP locators for Z mode. +typedef enum _GXBPZMode { + // Test enable [31-31] + GX_BP_ZMODE_TEST_ENABLE_ST = 31, + GX_BP_ZMODE_TEST_ENABLE_END = 31, + + // Compare [28-30] + GX_BP_ZMODE_COMPARE_ST = 28, + GX_BP_ZMODE_COMPARE_END = 30, + + // Update enable [27-27] + GX_BP_ZMODE_UPDATE_ENABLE_ST = 27, + GX_BP_ZMODE_UPDATE_ENABLE_END = 27, +} GXBPZMode; + +// BP locators for blend mode. +typedef enum _GXBPBlendMode { + // Blend enable [31-31] + GX_BP_BLENDMODE_ENABLE_ST = 31, + GX_BP_BLENDMODE_ENABLE_END = 31, + + // Logic operation enable [30-30] + GX_BP_BLENDMODE_LOGIC_OP_ST = 30, + GX_BP_BLENDMODE_LOGIC_OP_END = 30, + + // Dither [29-29] + GX_BP_BLENDMODE_DITHER_ST = 29, + GX_BP_BLENDMODE_DITHER_END = 29, + + // Color update [28-28] + GX_BP_BLENDMODE_COLOR_UPDATE_ST = 28, + GX_BP_BLENDMODE_COLOR_UPDATE_END = 28, + + // Alpha update [27-27] + GX_BP_BLENDMODE_ALPHA_UPDATE_ST = 27, + GX_BP_BLENDMODE_ALPHA_UPDATE_END = 27, + + // Destination factor [24-26] + GX_BP_BLENDMODE_DSTFACTOR_ST = 24, + GX_BP_BLENDMODE_DSTFACTOR_END = 26, + + // Source factor [21-23] + GX_BP_BLENDMODE_SRCFACTOR_ST = 21, + GX_BP_BLENDMODE_SRCFACTOR_END = 23, + + // Subtract [20-20] + GX_BP_BLENDMODE_SUBTRACT_ST = 20, + GX_BP_BLENDMODE_SUBTRACT_END = 20, + + // Logic mode [16-19] + GX_BP_BLENDMODE_LOGICMODE_ST = 16, + GX_BP_BLENDMODE_LOGICMODE_END = 19, +} GXBPBlendMode; + +// BP locators for destination alpha. +typedef enum _GXBPDstAlpha { + // Alpha [24-31] + GX_BP_DSTALPHA_ALPHA_ST = 24, + GX_BP_DSTALPHA_ALPHA_END = 31, + + // Enable [23-23] + GX_BP_DSTALPHA_ENABLE_ST = 23, + GX_BP_DSTALPHA_ENABLE_END = 23, + + // YUV format [21-22] + GX_BP_DSTALPHA_YUV_FMT_ST = 21, + GX_BP_DSTALPHA_YUV_FMT_END = 22, +} GXBPDstAlpha; + +// BP locators for Z control. +typedef enum _GXBPZControl { + // Pixel format [29-31] + GX_BP_ZCONTROL_PIXEL_FMT_ST = 29, + GX_BP_ZCONTROL_PIXEL_FMT_END = 31, + + // Z format [26-28] + GX_BP_ZCONTROL_Z_FMT_ST = 26, + GX_BP_ZCONTROL_Z_FMT_END = 28, + + // Whether to do Z-buffering before or after texturing [25-25] + GX_BP_ZCONTROL_BEFORE_TEX_ST = 25, + GX_BP_ZCONTROL_BEFORE_TEX_END = 25, +} GXBPZControl; + +// BP locators for field mask. +typedef enum _GXBPFieldMask { + // Whether to write odd fields to the EFB [31-31] + GX_BP_FIELDMASK_ODD_ST = 31, + GX_BP_FIELDMASK_ODD_END = 31, + + // Whether to write even fields to the EFB [30-30] + GX_BP_FIELDMASK_EVEN_ST = 30, + GX_BP_FIELDMASK_EVEN_END = 30, +} GXBPFieldMask; + +// BP locators for scissor offset. +typedef enum _GXBPScissorOffset { + // X offset [22-31] + GX_BP_SCISSOROFS_OX_ST = 22, + GX_BP_SCISSOROFS_OX_END = 31, + + // Y offset [12-21] + GX_BP_SCISSOROFS_OY_ST = 12, + GX_BP_SCISSOROFS_OY_END = 21, +} GXBPScissorOffset; + +// BP locators for field mode. +typedef enum _GXBPFieldMode { + // Adjust vertex tex LOD computation to account for interlacing + GX_BP_FIELDMODE_TEX_LOD_ST = 31, + GX_BP_FIELDMODE_TEX_LOD_END = 31, +} GXBPFieldMode; + +// BP locators for fog range. +typedef enum _GXBPFogRange { + // Center [22-31] + GX_BP_FOGRANGE_CENTER_ST = 22, + GX_BP_FOGRANGE_CENTER_END = 31, + + // Enabled [21-21] + GX_BP_FOGRANGE_ENABLED_ST = 21, + GX_BP_FOGRANGE_ENABLED_END = 21, +} GXBPFogRange; + +// BP locators for fog range K. +typedef enum _GXBPFogRangeK { + // Hi [20-31] + GX_BP_FOGRANGEK_HI_ST = 20, + GX_BP_FOGRANGEK_HI_END = 31, + + // Lo [8-19] + GX_BP_FOGRANGEK_LO_ST = 8, + GX_BP_FOGRANGEK_LO_END = 19, +} GXBPFogRangeK; + +// BP locators for fog parameter 0. +typedef enum _GXBPFogParam0 { + // A mantissa [21-31] + GX_BP_FOGPARAM0_A_MANT_ST = 21, + GX_BP_FOGPARAM0_A_MANT_END = 31, + + // A exponent [13-20] + GX_BP_FOGPARAM0_A_EXP_ST = 13, + GX_BP_FOGPARAM0_A_EXP_END = 20, + + // A sign [12-12] + GX_BP_FOGPARAM0_A_SIGN_ST = 12, + GX_BP_FOGPARAM0_A_SIGN_END = 12, +} GXBPFogParam0; + +// BP locators for fog parameter 1. +typedef enum _GXBPFogParam1 { + // B magnitude [8-31] + GX_BP_FOGPARAM1_B_MAG_ST = 8, + GX_BP_FOGPARAM1_B_MAG_END = 31, +} GXBPFogParam1; + +// BP locators for fog parameter 2. +typedef enum _GXBPFogParam2 { + // B shift [27-31] + GX_BP_FOGPARAM2_B_SHIFT_ST = 27, + GX_BP_FOGPARAM2_B_SHIFT_END = 31, +} GXBPFogParam2; + +// BP locators for fog parameter 3. +typedef enum _GXBPFogParam3 { + // C mantissa [21-31] + GX_BP_FOGPARAM3_C_MANT_ST = 21, + GX_BP_FOGPARAM3_C_MANT_END = 31, + + // C exponent [13-20] + GX_BP_FOGPARAM3_C_EXP_ST = 13, + GX_BP_FOGPARAM3_C_EXP_END = 20, + + // C sign [12-12] + GX_BP_FOGPARAM3_C_SIGN_ST = 12, + GX_BP_FOGPARAM3_C_SIGN_END = 12, + + // Projection [11] + GX_BP_FOGPARAM3_PROJ_ST = 11, + GX_BP_FOGPARAM3_PROJ_END = 11, + + // F select [8-10] + GX_BP_FOGPARAM3_FSEL_ST = 8, + GX_BP_FOGPARAM3_FSEL_END = 10, +} GXBPFogParam3; + +// BP locators for fog color. +typedef enum _GXBPFogColor { + // RGB components of color [8-31] + GX_BP_FOGCOLOR_RGB_ST = 8, + GX_BP_FOGCOLOR_RGB_END = 31, +} GXBPFogColor; + +// CP locator for matrix index A. +typedef enum _GXCPMtxIdxA { + // Geometry [26-31] + GX_CP_MTXIDXA_GEOM_ST = 26, + GX_CP_MTXIDXA_GEOM_END = 31, + + // Tex0 [20-25] + GX_CP_MTXIDXA_TEX0_ST = 20, + GX_CP_MTXIDXA_TEX0_END = 25, + + // Tex1 [14-19] + GX_CP_MTXIDXA_TEX1_ST = 14, + GX_CP_MTXIDXA_TEX1_END = 19, + + // Tex2 [8-13] + GX_CP_MTXIDXA_TEX2_ST = 8, + GX_CP_MTXIDXA_TEX2_END = 13, + + // Tex3 [2-7] + GX_CP_MTXIDXA_TEX3_ST = 2, + GX_CP_MTXIDXA_TEX3_END = 7, +} GXCPMtxIdxA; + +// CP locator for matrix index B. +typedef enum _GXCPMtxIdxB { + // Tex4 [26-31] + GX_CP_MTXIDXB_TEX4_ST = 26, + GX_CP_MTXIDXB_TEX4_END = 31, + + // Tex5 [20-25] + GX_CP_MTXIDXB_TEX5_ST = 20, + GX_CP_MTXIDXB_TEX5_END = 25, + + // Tex6 [14-19] + GX_CP_MTXIDXB_TEX6_ST = 14, + GX_CP_MTXIDXB_TEX6_END = 19, + + // Tex7 [8-13] + GX_CP_MTXIDXB_TEX7_ST = 8, + GX_CP_MTXIDXB_TEX7_END = 13, +} GXCPMtxIdxB; + +// CP locator for vertex descriptor (lo). +typedef enum _GXCPVCDLo { + // Position matrix idx [31] + GX_CP_VCD_LO_POSMTXIDX_ST = 31, + GX_CP_VCD_LO_POSMTXIDX_END = 31, + + // Tex 0 matrix idx [30] + GX_CP_VCD_LO_TEX0MTXIDX_ST = 30, + GX_CP_VCD_LO_TEX0MTXIDX_END = 30, + + // Tex 1 matrix idx [29] + GX_CP_VCD_LO_TEX1MTXIDX_ST = 29, + GX_CP_VCD_LO_TEX1MTXIDX_END = 29, + + // Tex 2 matrix idx [28] + GX_CP_VCD_LO_TEX2MTXIDX_ST = 28, + GX_CP_VCD_LO_TEX2MTXIDX_END = 28, + + // Tex 3 matrix idx [27] + GX_CP_VCD_LO_TEX3MTXIDX_ST = 27, + GX_CP_VCD_LO_TEX3MTXIDX_END = 27, + + // Tex 4 matrix idx [26] + GX_CP_VCD_LO_TEX4MTXIDX_ST = 26, + GX_CP_VCD_LO_TEX4MTXIDX_END = 26, + + // Tex 5 matrix idx [25] + GX_CP_VCD_LO_TEX5MTXIDX_ST = 25, + GX_CP_VCD_LO_TEX5MTXIDX_END = 25, + + // Tex 6 matrix idx [24] + GX_CP_VCD_LO_TEX6MTXIDX_ST = 24, + GX_CP_VCD_LO_TEX6MTXIDX_END = 24, + + // Tex 7 matrix idx [23] + GX_CP_VCD_LO_TEX7MTXIDX_ST = 23, + GX_CP_VCD_LO_TEX7MTXIDX_END = 23, + + // Position [21-22] + GX_CP_VCD_LO_POS_ST = 21, + GX_CP_VCD_LO_POS_END = 22, + + // Normal [19-20] + GX_CP_VCD_LO_NRM_ST = 19, + GX_CP_VCD_LO_NRM_END = 20, + + // Color diffused [17-18] + GX_CP_VCD_LO_CLRDIF_ST = 17, + GX_CP_VCD_LO_CLRDIF_END = 18, + + // Color specular [15-16] + GX_CP_VCD_LO_CLRSPEC_ST = 15, + GX_CP_VCD_LO_CLRSPEC_END = 16, +} GXCPVCDLo; + +// CP locators for vertex descriptor (hi). +typedef enum _GXCPVCDHi { + // Tex0 coordinates [30-31] + GX_CP_VCD_HI_TEX0COORD_ST = 30, + GX_CP_VCD_HI_TEX0COORD_END = 31, + + // Tex1 coordinates [28-29] + GX_CP_VCD_HI_TEX1COORD_ST = 28, + GX_CP_VCD_HI_TEX1COORD_END = 29, + + // Tex2 coordinates [26-27] + GX_CP_VCD_HI_TEX2COORD_ST = 26, + GX_CP_VCD_HI_TEX2COORD_END = 27, + + // Tex3 coordinates [24-25] + GX_CP_VCD_HI_TEX3COORD_ST = 24, + GX_CP_VCD_HI_TEX3COORD_END = 25, + + // Tex4 coordinates [22-23] + GX_CP_VCD_HI_TEX4COORD_ST = 22, + GX_CP_VCD_HI_TEX4COORD_END = 23, + + // Tex5 coordinates [20-21] + GX_CP_VCD_HI_TEX5COORD_ST = 20, + GX_CP_VCD_HI_TEX5COORD_END = 21, + + // Tex6 coordinates [18-19] + GX_CP_VCD_HI_TEX6COORD_ST = 18, + GX_CP_VCD_HI_TEX6COORD_END = 19, + + // Tex7 coordinates [16-17] + GX_CP_VCD_HI_TEX7COORD_ST = 16, + GX_CP_VCD_HI_TEX7COORD_END = 17, +} GXCPVCDHi; + +// CP locator for vertex attribute table (group 0). +typedef enum _GXCPVATGrp0 { + // Position count [31-31] + GX_CP_VAT_GRP0_POS_CNT_ST = 31, + GX_CP_VAT_GRP0_POS_CNT_END = 31, + + // Position type [28-30] + GX_CP_VAT_GRP0_POS_TYPE_ST = 28, + GX_CP_VAT_GRP0_POS_TYPE_END = 30, + + // Position shift [23-27] + GX_CP_VAT_GRP0_POS_SHIFT_ST = 23, + GX_CP_VAT_GRP0_POS_SHIFT_END = 27, + + // Normal count [22-22] + GX_CP_VAT_GRP0_NRM_CNT_ST = 22, + GX_CP_VAT_GRP0_NRM_CNT_END = 22, + + // Normal type [19-21] + GX_CP_VAT_GRP0_NRM_TYPE_ST = 19, + GX_CP_VAT_GRP0_NRM_TYPE_END = 21, + + // Color diffused count [18-18] + GX_CP_VAT_GRP0_CLRDIFF_CNT_ST = 18, + GX_CP_VAT_GRP0_CLRDIFF_CNT_END = 18, + + // Color diffused type [15-17] + GX_CP_VAT_GRP0_CLRDIFF_TYPE_ST = 15, + GX_CP_VAT_GRP0_CLRDIFF_TYPE_END = 17, + + // Color specular count [14-14] + GX_CP_VAT_GRP0_CLRSPEC_CNT_ST = 14, + GX_CP_VAT_GRP0_CLRSPEC_CNT_END = 14, + + // Color specular type [11-13] + GX_CP_VAT_GRP0_CLRSPEC_TYPE_ST = 11, + GX_CP_VAT_GRP0_CLRSPEC_TYPE_END = 13, + + // Tex0 coord count [10-10] + GX_CP_VAT_GRP0_TXC0_CNT_ST = 10, + GX_CP_VAT_GRP0_TXC0_CNT_END = 10, + + // Tex0 coord type [7-9] + GX_CP_VAT_GRP0_TXC0_TYPE_ST = 7, + GX_CP_VAT_GRP0_TXC0_TYPE_END = 9, + + // Tex0 coord shift [2-6] + GX_CP_VAT_GRP0_TXC0_SHIFT_ST = 2, + GX_CP_VAT_GRP0_TXC0_SHIFT_END = 6, + + // Byte dequantised [1-1] + GX_CP_VAT_GRP0_BYTEDEQ_ST = 1, + GX_CP_VAT_GRP0_BYTEDEQ_END = 1, + + // Normal index 3 [0-0] (Input will be treated as three staggered indices (one per triple biased by component size) into normal table)) + GX_CP_VAT_GRP0_NRMIDX3_ST = 0, + GX_CP_VAT_GRP0_NRMIDX3_END = 0, +} GXCPVATGrp0; + +// CP locators for vertex attribute table (group 1). +typedef enum _GXCPVATGrp1 { + // Tex1 coord count [31-31] + GX_CP_VAT_GRP1_TXC1_CNT_ST = 31, + GX_CP_VAT_GRP1_TXC1_CNT_END = 31, + + // Tex1 coord type [28-30] + GX_CP_VAT_GRP1_TXC1_TYPE_ST = 28, + GX_CP_VAT_GRP1_TXC1_TYPE_END = 30, + + // Tex1 coord shift [23-27] + GX_CP_VAT_GRP1_TXC1_SHIFT_ST = 23, + GX_CP_VAT_GRP1_TXC1_SHIFT_END = 27, + + // Tex2 coord count [22-22] + GX_CP_VAT_GRP1_TXC2_CNT_ST = 22, + GX_CP_VAT_GRP1_TXC2_CNT_END = 22, + + // Tex2 coord type [19-21] + GX_CP_VAT_GRP1_TXC2_TYPE_ST = 19, + GX_CP_VAT_GRP1_TXC2_TYPE_END = 21, + + // Tex2 coord shift [14-18] + GX_CP_VAT_GRP1_TXC2_SHIFT_ST = 14, + GX_CP_VAT_GRP1_TXC2_SHIFT_END = 18, + + // Tex3 coord count [13-13] + GX_CP_VAT_GRP1_TXC3_CNT_ST = 13, + GX_CP_VAT_GRP1_TXC3_CNT_END = 13, + + // Tex3 coord type [10-12] + GX_CP_VAT_GRP1_TXC3_TYPE_ST = 10, + GX_CP_VAT_GRP1_TXC3_TYPE_END = 12, + + // Tex3 coord shift [5-9] + GX_CP_VAT_GRP1_TXC3_SHIFT_ST = 5, + GX_CP_VAT_GRP1_TXC3_SHIFT_END = 9, + + // Tex4 coord count [4-4] + GX_CP_VAT_GRP1_TXC4_CNT_ST = 4, + GX_CP_VAT_GRP1_TXC4_CNT_END = 4, + + // Tex4 coord type [1-3] + GX_CP_VAT_GRP1_TXC4_TYPE_ST = 1, + GX_CP_VAT_GRP1_TXC4_TYPE_END = 3, + +} GXCPVATGrp1; + +// CP locators for vertex attribute table (group 2). +typedef enum _GXCPVATGrp2 { + // Tex4 coord shift [27-31] + GX_CP_VAT_GRP2_TXC4_SHIFT_ST = 27, + GX_CP_VAT_GRP2_TXC4_SHIFT_END = 31, + + // Tex5 coord count [26-26] + GX_CP_VAT_GRP2_TXC5_CNT_ST = 26, + GX_CP_VAT_GRP2_TXC5_CNT_END = 26, + + // Tex5 coord type [23-25] + GX_CP_VAT_GRP2_TXC5_TYPE_ST = 23, + GX_CP_VAT_GRP2_TXC5_TYPE_END = 25, + + // Tex5 coord shift [18-22] + GX_CP_VAT_GRP2_TXC5_SHIFT_ST = 18, + GX_CP_VAT_GRP2_TXC5_SHIFT_END = 22, + + // Tex6 coord count [17-17] + GX_CP_VAT_GRP2_TXC6_CNT_ST = 17, + GX_CP_VAT_GRP2_TXC6_CNT_END = 17, + + // Tex6 coord type [14-16] + GX_CP_VAT_GRP2_TXC6_TYPE_ST = 14, + GX_CP_VAT_GRP2_TXC6_TYPE_END = 16, + + // Tex6 coord shift [9-13] + GX_CP_VAT_GRP2_TXC6_SHIFT_ST = 9, + GX_CP_VAT_GRP2_TXC6_SHIFT_END = 13, + + // Tex7 coord count [8-8] + GX_CP_VAT_GRP2_TXC7_CNT_ST = 8, + GX_CP_VAT_GRP2_TXC7_CNT_END = 8, + + // Tex7 coord type [5-7] + GX_CP_VAT_GRP2_TXC7_TYPE_ST = 5, + GX_CP_VAT_GRP2_TXC7_TYPE_END = 7, + + // Tex7 coord shift [0-4] + GX_CP_VAT_GRP2_TXC7_SHIFT_ST = 0, + GX_CP_VAT_GRP2_TXC7_SHIFT_END = 4, +} GXCPVATGrp2; + +// CP locators for array base. +typedef enum _GXCPArrayBase { + // Base [6-31] + GX_CP_ARRAYBASE_BASE_ST = 6, + GX_CP_ARRAYBASE_BASE_END = 31, +} GXCPArrayBase; + +// CP locators for array stride. +typedef enum _GXCPArrayStride { + // Stride [24-31] + GX_CP_ARRAYSTRIDE_STRIDE_ST = 24, + GX_CP_ARRAYSTRIDE_STRIDE_END = 31, +} GXCPArrayStride; + +// XF locators for clip disabling. +typedef enum _GXXFClipDisable { + // Disable detection [31-31] + GX_XF_CLIPDISABLE_DETECT_ST = 31, + GX_XF_CLIPDISABLE_DETECT_END = 31, + + // Disable trivial rejection [30-30] + GX_XF_CLIPDISABLE_REJECT_ST = 30, + GX_XF_CLIPDISABLE_REJECT_END = 30, + + // Disable cpoly clipping acceleration [29-29] + GX_XF_CLIPDISABLE_ACCEL_ST = 29, + GX_XF_CLIPDISABLE_ACCEL_END = 29, +} GXXFClipDisable; + +// XF locators for InVertexSpec. +typedef enum _GXXFInVertexSpec { + // Color [30-31] + GX_XF_INVERTEXSPEC_CLR_ST = 30, + GX_XF_INVERTEXSPEC_CLR_END = 31, + + // Normal [28-29] + GX_XF_INVERTEXSPEC_NRM_ST = 28, + GX_XF_INVERTEXSPEC_NRM_END = 29, + + // Tex coords [24-27] + GX_XF_INVERTEXSPEC_TEX_ST = 24, + GX_XF_INVERTEXSPEC_TEX_END = 27, +} GXXFInVertexSpec; + +// XF locators for Color 0 control. +typedef enum _GXXFClr0Ctrl { + // Matrix source [31-31] + GX_XF_CLR0CTRL_MTXSRC_ST = 31, + GX_XF_CLR0CTRL_MTXSRC_END = 31, + + // Light [30-30] + GX_XF_CLR0CTRL_LIGHT_ST = 30, + GX_XF_CLR0CTRL_LIGHT_END = 30, + + // Light mask (hi) [26-29] + GX_XF_CLR0CTRL_LMASKHI_ST = 26, + GX_XF_CLR0CTRL_LMASKHI_END = 29, + + // Ambient source [25-25] + GX_XF_CLR0CTRL_AMBSRC_ST = 25, + GX_XF_CLR0CTRL_AMBSRC_END = 25, + + // Diffuse attenuation [23-24] + GX_XF_CLR0CTRL_DIFATTN_ST = 23, + GX_XF_CLR0CTRL_DIFATTN_END = 24, + + // Enable attentuation [22-22] + GX_XF_CLR0CTRL_ATTNENABLE_ST = 22, + GX_XF_CLR0CTRL_ATTNENABLE_END = 22, + + // Select attentuation [21-21] + GX_XF_CLR0CTRL_ATTNSEL_ST = 21, + GX_XF_CLR0CTRL_ATTNSEL_END = 21, + + // Light mask (lo) [17-20] + GX_XF_CLR0CTRL_LMASKLO_ST = 17, + GX_XF_CLR0CTRL_LMASKLO_END = 20, +} GXXFClr0Ctrl; + +// XF locators for matrix index 0. +typedef enum _GXXFMtxIdx0 { + // Geometry [26-31] + GX_XF_MTXIDX0_GEOM_ST = 26, + GX_XF_MTXIDX0_GEOM_END = 31, + + // Tex 0 [20-25] + GX_XF_MTXIDX0_TEX0_ST = 20, + GX_XF_MTXIDX0_TEX0_END = 25, + + // Tex 1 [14-19] + GX_XF_MTXIDX0_TEX1_ST = 14, + GX_XF_MTXIDX0_TEX1_END = 19, + + // Tex 2 [8-13] + GX_XF_MTXIDX0_TEX2_ST = 8, + GX_XF_MTXIDX0_TEX2_END = 13, + + // Tex 3 [2-7] + GX_XF_MTXIDX0_TEX3_ST = 2, + GX_XF_MTXIDX0_TEX3_END = 7, +} GXXFMtxIdx0; + +// XF locators for matrix index 1. +typedef enum _GXXFMtxIdx1 { + // Tex 4 [26-31] + GX_XF_MTXIDX1_TEX4_ST = 26, + GX_XF_MTXIDX1_TEX4_END = 31, + + // Tex 5 [20-25] + GX_XF_MTXIDX1_TEX5_ST = 20, + GX_XF_MTXIDX1_TEX5_END = 25, + + // Tex 6 [14-19] + GX_XF_MTXIDX1_TEX6_ST = 14, + GX_XF_MTXIDX1_TEX6_END = 19, + + // Tex 7 [8-13] + GX_XF_MTXIDX1_TEX7_ST = 8, + GX_XF_MTXIDX1_TEX7_END = 13, +} GXXFMtxIdx1; + +// XF locators for textures. +typedef enum _GXXFTex { + // Projection type [30-30] + GX_XF_TEX_PROJTYPE_ST = 30, + GX_XF_TEX_PROJTYPE_END = 30, + + // Input format [29-29] + GX_XF_TEX_INPUTFORM_ST = 29, + GX_XF_TEX_INPUTFORM_END = 29, + + // Texture gen type [25-27] + GX_XF_TEX_TEXGENTYPE_ST = 25, + GX_XF_TEX_TEXGENTYPE_END = 27, + + // Source row [20-24] + GX_XF_TEX_SRCROW_ST = 20, + GX_XF_TEX_SRCROW_END = 24, + + // Bump source texture [17-19] + GX_XF_TEX_BUMPSRCTEX_ST = 17, + GX_XF_TEX_BUMPSRCTEX_END = 19, + + // Bump source light [14-16] + GX_XF_TEX_BUMPSRCLIGHT_ST = 14, + GX_XF_TEX_BUMPSRCLIGHT_END = 16, +} GXXFTex; + +// XF locators for dual textures. +typedef enum _GXXFDualTex { + // Base row of the transform matrix [26-31] + GX_XF_DUALTEX_BASEROW_ST = 26, + GX_XF_DUALTEX_BASEROW_END = 31, + + // Normalise texcoord before sending transform [23-23] + GX_XF_DUALTEX_NORMALISE_ST = 23, + GX_XF_DUALTEX_NORMALISE_END = 23, +} GXXFDualTex; + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXFifo.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXFifo.h new file mode 100644 index 0000000..80265ed --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXFifo.h @@ -0,0 +1,211 @@ +#ifndef _DOLPHIN_GXFIFO_H +#define _DOLPHIN_GXFIFO_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" + +/////////////// FIFO STRUCTS /////////////// +#define GX_FIFO_MINSIZE (64 * 1024) +#define GX_FIFO_OBJ_SIZE (128) + +#define GXFIFO_ADDR 0xCC008000 + +// Generic struct for FIFO access (size 0x80). +typedef struct _GXFifoObj { + u8 padding[GX_FIFO_OBJ_SIZE]; // _00 +} GXFifoObj; + +// Internal struct for FIFO access. +typedef struct _GXFifoObjPriv { + void* base; // _00 + void* end; // _04 + u32 size; // _08 + u32 highWatermark; // _0C + u32 lowWatermark; // _10 + void* readPtr; // _14 + void* writePtr; // _18 + s32 rwDistance; // _1C + u8 _20[0x60]; // _20 +} GXFifoObjPriv; + +typedef void (*GXBreakPtCallback)(void); + +// PPC Write Gather Pipe +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 + +//////////////////////////////////////////// + +//////////// FIFO MACROS/INLINES /////////// +#define GX_WRITE_U8(val) (GXWGFifo.u8 = val) +#define GX_WRITE_U16(val) (GXWGFifo.u16 = val) +#define GX_WRITE_U32(val) (GXWGFifo.u32 = (u32)val) +#define GX_WRITE_F32(val) (GXWGFifo.f32 = (f32)val) + +static inline void GXPosition2f32(const f32 x, const f32 y) +{ + GXWGFifo.f32 = x; + GXWGFifo.f32 = y; +} + +static inline void GXPosition3s16(const s16 x, const s16 y, const s16 z) +{ + GXWGFifo.s16 = x; + GXWGFifo.s16 = y; + GXWGFifo.s16 = z; +} + +static inline void GXPosition3u16(const u16 x, const u16 y, const u16 z) +{ + GXWGFifo.u16 = x; + GXWGFifo.u16 = y; + GXWGFifo.u16 = z; +} + +static inline void GXPosition3f32(f32 x, f32 y, f32 z) +{ + GXWGFifo.f32 = x; + GXWGFifo.f32 = y; + GXWGFifo.f32 = z; +} + +static inline void GXNormal3f32(const f32 x, const f32 y, const f32 z) +{ + GXWGFifo.f32 = x; + GXWGFifo.f32 = y; + GXWGFifo.f32 = z; +} + +static inline void GXColor1u32(u32 c) { GXWGFifo.u32 = c; } + +static inline void GXColor4u8(const u8 r, const u8 g, const u8 b, const u8 a) +{ + GXWGFifo.u8 = r; + GXWGFifo.u8 = g; + GXWGFifo.u8 = b; + GXWGFifo.u8 = a; +} + +static inline void GXTexCoord2s8(const s8 u, const s8 v) +{ + GXWGFifo.s8 = u; + GXWGFifo.s8 = v; +} + +static inline void GXTexCoord2u8(u8 s, u8 t) +{ + GXWGFifo.u8 = s; + GXWGFifo.u8 = t; +} + +static inline void GXPosition2u16(u16 x, u16 y) +{ + GXWGFifo.u16 = x; + GXWGFifo.u16 = y; +} + +static inline void GXTexCoord2s16(const s16 u, const s16 v) +{ + GXWGFifo.s16 = u; + GXWGFifo.s16 = v; +} + +static inline void GXTexCoord2u16(const u16 u, const u16 v) +{ + GXWGFifo.u16 = u; + GXWGFifo.u16 = v; +} + +static inline void GXTexCoord2f32(const f32 u, const f32 v) +{ + GXWGFifo.f32 = u; + GXWGFifo.f32 = v; +} + +static inline void GXEnd(void) { } + +//////////////////////////////////////////// + +//////////// FIFO INIT/SET/SAVE //////////// +// Init. +extern void __GXFifoInit(); +extern void GXInitFifoBase(GXFifoObj* obj, void* base, u32 size); +extern void GXInitFifoPtrs(GXFifoObj* obj, void* readPtr, void* writePtr); +extern void GXInitFifoLimits(GXFifoObj* obj, u32 hiWaterMark, u32 loWaterMark); + +// Set. +extern void GXSetCPUFifo(GXFifoObj* obj); +extern void GXSetGPFifo(GXFifoObj* obj); +extern void GXSaveCPUFifo(GXFifoObj* obj); + +//////////////////////////////////////////// + +/////////////// FIFO GETTERS /////////////// +extern void GXGetGPStatus(GXBool* isOverHi, GXBool* isUnderLo, GXBool* isReadIdle, GXBool* isCmdIdle, GXBool* isHitBrkPt); +extern GXFifoObj* GXGetCPUFifo(); +extern GXFifoObj* GXGetGPFifo(); + +//////////////////////////////////////////// + +//////////// DISPLAY LIST FUNCS //////////// +extern void GXBeginDisplayList(void* list, u32 size); +extern u32 GXEndDisplayList(); +extern void GXCallDisplayList(void* list, u32 numBytes); + +//////////////////////////////////////////// + +///////////// BREAKPOINT FUNCS ///////////// +extern GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback callback); + +//////////////////////////////////////////// + +/////////////// OTHER FUNCS //////////////// +void __GXSaveCPUFifoAux(GXFifoObj* obj); +void __GXFifoReadEnable(); +void __GXFifoReadDisable(); +void __GXFifoLink(u8); +void __GXWriteFifoIntEnable(u32, u32); +void __GXWriteFifoIntReset(u32, u32); + +// Unused/inlined in P2. +extern void GXSaveGPFifo(GXFifoObj* obj); + +extern void GXGetFifoStatus(GXFifoObj* obj, GXBool* isOverHi, GXBool* isUnderLo, u32* fifoCount, GXBool* isCpuWrite, GXBool* isGPRead, + GXBool* isFifoWrap); +extern void GXGetFifoPtrs(GXFifoObj* obj, void** readPtr, void** writePtr); +extern void* GXGetFifoBase(GXFifoObj* obj); +extern u32 GXGetFifoSize(GXFifoObj* obj); +extern void GXGetFifoLimits(GXFifoObj* obj, u32* hi, u32* lo); + +extern void GXEnableBreakPt(void* breakPtr); +extern void GXDisableBreakPt(); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXFrameBuffer.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXFrameBuffer.h new file mode 100644 index 0000000..baa6409 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXFrameBuffer.h @@ -0,0 +1,85 @@ +#ifndef _DOLPHIN_GXFRAMEBUFFER_H +#define _DOLPHIN_GXFRAMEBUFFER_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" + +///////////// RENDER MODE OBJS ///////////// +// NB: commented out objects are unused in P2. +// 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 GXPal524IntAa; +// extern GXRenderModeObj GXEurgb60Hz240Ds; +// extern GXRenderModeObj GXEurgb60Hz240DsAa; +// extern GXRenderModeObj GXEurgb60Hz240Int; +// extern GXRenderModeObj GXEurgb60Hz240IntAa; +extern GXRenderModeObj GXEurgb60Hz480IntDf; +// extern GXRenderModeObj GXEurgb60Hz480Int; +// extern GXRenderModeObj GXEurgb60Hz480IntAa; +// extern GXRenderModeObj GXRmHW; + +//////////////////////////////////////////// + +///////////// BUFFER FUNCTIONS ///////////// +// Source/dest copy-set functions. +extern void GXSetDispCopySrc(u16 left, u16 top, u16 width, u16 height); +extern void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height); +extern void GXSetDispCopyDst(u16 width, u16 height); +extern void GXSetTexCopyDst(u16 width, u16 height, GXTexFmt format, GXBool useMIPmap); + +// Other copy-set functions. +extern void GXSetDispCopyFrame2Field(GXCopyMode mode); +extern void GXSetCopyClamp(GXFBClamp clamp); +extern u32 GXSetDispCopyYScale(f32 vertScale); +extern void GXSetCopyClear(GXColor clearColor, u32 clearZ); +extern void GXSetCopyFilter(GXBool useAA, u8 samplePattern[12][2], GXBool doVertFilt, u8 vFilt[7]); +extern void GXSetDispCopyGamma(GXGamma gamma); + +// Copy data functions. +extern void GXCopyDisp(void* dest, GXBool doClear); +extern void GXCopyTex(void* dest, GXBool doClear); + +// Get functions. +extern u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale); +extern f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight); + +// Clear functions. +extern void GXClearBoundingBox(); + +// Unused/inlined in P2. +extern void GXAdjustForOverscan(GXRenderModeObj* rIn, GXRenderModeObj* rOut, u16 horiz, u16 vert); +extern void GXReadBoundingBox(u16* left, u16* top, u16* right, u16* bottom); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXGeometry.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXGeometry.h new file mode 100644 index 0000000..38833a4 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXGeometry.h @@ -0,0 +1,56 @@ +#ifndef _DOLPHIN_GXGEOMETRY_H +#define _DOLPHIN_GXGEOMETRY_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" + +//////////// GEOMETRY FUNCTIONS //////////// +// Basic GX functions. +extern void __GXSetDirtyState(); +extern void GXBegin(GXPrimitive type, GXVtxFmt format, u16 numVertices); +extern void __GXSendFlushPrim(); + +// Attr functions. +extern void GXSetVtxDesc(GXAttr attr, GXAttrType type); +extern void GXClearVtxDesc(); + +extern void GXSetVtxAttrFmt(GXVtxFmt format, GXAttr attr, GXCompCnt count, GXCompType type, u8 frac); +extern void GXSetVtxAttrFmtv(GXVtxFmt format, GXVtxAttrFmtList* list); + +extern void GXSetArray(GXAttr attr, void* basePtr, u8 stride); +extern void GXInvalidateVtxCache(); +extern void GXSetTexCoordGen2(GXTexCoordID coord, GXTexGenType genType, GXTexGenSrc srcParam, u32 mtx, GXBool doNormalise, u32 postMtx); +extern void GXSetNumTexGens(u8 count); + +// Geometry functions. +extern void GXSetLineWidth(u8 width, GXTexOffset offset); +extern void GXSetPointSize(u8 pointSize, GXTexOffset offset); +extern void GXEnableTexOffsets(GXTexCoordID coord, GXBool enableLine, GXBool enablePoint); +extern void __GXSetGenMode(); + +// Cull and manip functions. +extern void GXSetCullMode(GXCullMode mode); +extern void GXSetCoPlanar(GXBool doEnable); + +// Unused/inlined in P2. +extern void GXSetVtxDescv(GXVtxDescList* attrList); +extern void GXGetVtxDesc(GXAttr attr, GXAttrType* type); +extern void GXGetVtxDescv(GXVtxDescList* list); +extern void GXGetVtxAttrFmtv(GXVtxFmt format, GXVtxAttrFmtList* list); +extern void GXGetLineWidth(u8* width, GXTexOffset* offset); +extern void GXGetPointSize(u8* pointSize, GXTexOffset* offset); +extern void GXGetCullMode(GXCullMode* mode); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXHardware.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXHardware.h new file mode 100644 index 0000000..2fcb7d8 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXHardware.h @@ -0,0 +1,129 @@ +#ifndef _DOLPHIN_GXHARDWARE_H +#define _DOLPHIN_GXHARDWARE_H + +#include "Dolphin/GX/GXTypes.h" +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/** + * Documentation from: + * https://www.gc-forever.com/yagcd/chap8.html#sec8 + * https://www.gc-forever.com/yagcd/chap5.html#sec5 + * https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/VideoCommon/BPMemory.h + * https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/VideoCommon/XFMemory.h + * https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/VideoCommon/OpcodeDecoding.h + * https://patents.google.com/patent/US6700586B1/en + * https://patents.google.com/patent/US6639595B1/en + * https://patents.google.com/patent/US7002591 + * https://patents.google.com/patent/US6697074 + */ + +#define GX_REG_MASK(st, end) (((1 << ((end) - (st) + 1)) - 1) << 31 - (end)) +#define GX_GET_REG(reg, st, end) GX_BITGET((reg), (st), ((end) - (st) + 1)) +#define GX_SET_REG(reg, x, st, end) GX_BITFIELD_SET((reg), (st), ((end) - (st) + 1), (x)) +#define GX_SET_TRUNC(reg, x, st, end) GX_BITFIELD_TRUNC((reg), (st), ((end) - (st) + 1), (x)) + +/************************************************************ + * + * + * GX FIFO + * + * + ***********************************************************/ + +#define __GX_FIFO_SET_LOAD_INDX_DST(reg, x) ((reg) = GX_BITFIELD_SET(reg, 20, 12, x)) +#define __GX_FIFO_SET_LOAD_INDX_NELEM(reg, x) ((reg) = GX_BITFIELD_SET(reg, 16, 4, x)) +#define __GX_FIFO_SET_LOAD_INDX_INDEX(reg, x) ((reg) = GX_BITFIELD_SET(reg, 0, 16, x)) + +#define __GX_FIFO_LOAD_INDX(reg, dst, nelem, index) \ + { \ + u32 cmd = 0; \ + __GX_FIFO_SET_LOAD_INDX_DST(cmd, dst); \ + __GX_FIFO_SET_LOAD_INDX_NELEM(cmd, nelem); \ + __GX_FIFO_SET_LOAD_INDX_INDEX(cmd, index); \ + GXWGFifo.s8 = reg; \ + GXWGFifo.s32 = cmd; \ + } + +#define GX_FIFO_LOAD_INDX_A(dst, nelem, index) __GX_FIFO_LOAD_INDX(GX_FIFO_CMD_LOAD_INDX_A, dst, nelem, index) + +#define GX_FIFO_LOAD_INDX_B(dst, nelem, index) __GX_FIFO_LOAD_INDX(GX_FIFO_CMD_LOAD_INDX_B, dst, nelem, index) + +#define GX_FIFO_LOAD_INDX_C(dst, nelem, index) __GX_FIFO_LOAD_INDX(GX_FIFO_CMD_LOAD_INDX_C, dst, nelem, index) + +#define GX_FIFO_LOAD_INDX_D(dst, nelem, index) __GX_FIFO_LOAD_INDX(GX_FIFO_CMD_LOAD_INDX_D, dst, nelem, index) + +/************************************************************ + * + * + * GX Blitting Processor (BP) + * + * + ***********************************************************/ + +/** + * Load immediate value into BP register + */ +#define GX_BP_LOAD_REG(data) \ + GXWGFifo.s8 = GX_FIFO_CMD_LOAD_BP_REG; \ + GXWGFifo.s32 = (data); + +/** + * Set BP command opcode (first 8 bits) + */ +#define GX_BP_SET_OPCODE(cmd, opcode) (cmd) = GX_BITFIELD_SET(cmd, 0, 8, (opcode)) + +/************************************************************ + * + * + * GX Command Processor (CP) + * + * + ***********************************************************/ + +/** + * Load immediate value into CP register + */ +#define GX_CP_LOAD_REG(addr, data) \ + GXWGFifo.s8 = GX_FIFO_CMD_LOAD_CP_REG; \ + GXWGFifo.s8 = (addr); \ + GXWGFifo.s32 = (data); + +/************************************************************ + * + * + * GX Transform Unit (XF) + * + * + ***********************************************************/ + +/** + * Header for an XF register load + */ +#define GX_XF_LOAD_REG_HDR(addr) \ + GXWGFifo.s8 = GX_FIFO_CMD_LOAD_XF_REG; \ + GXWGFifo.s32 = (addr); + +/** + * Load immediate value into XF register + */ +#define GX_XF_LOAD_REG(addr, data) \ + GX_XF_LOAD_REG_HDR(addr); \ + GXWGFifo.s32 = (data); + +/** + * Load immediate values into multiple XF registers + */ +#define GX_XF_LOAD_REGS(size, addr) \ + { \ + u32 cmd = (size) << 16 | addr; \ + GX_XF_LOAD_REG_HDR(cmd); \ + } + +#ifdef __cplusplus +} +#endif +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXLight.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXLight.h new file mode 100644 index 0000000..43fc872 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXLight.h @@ -0,0 +1,67 @@ +#ifndef _DOLPHIN_GXLIGHT_H +#define _DOLPHIN_GXLIGHT_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" + +///////////// LIGHT FUNCTIONS ////////////// +// Init functions. +extern void GXInitLightAttn(GXLightObj* obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2); + +extern void GXInitLightSpot(GXLightObj* obj, f32 cutoff, GXSpotFn spotFunc); +extern void GXInitLightDistAttn(GXLightObj* obj, f32 refDist, f32 refBrightness, GXDistAttnFn distFunc); + +extern void GXInitLightPos(GXLightObj* obj, f32 x, f32 y, f32 z); +extern void GXInitLightDir(GXLightObj* obj, f32 nX, f32 nY, f32 nZ); +extern void GXInitSpecularDir(GXLightObj* obj, f32 nX, f32 nY, f32 nZ); +extern void GXInitLightColor(GXLightObj* obj, GXColor color); + +// Load functions. +extern void GXLoadLightObjImm(GXLightObj* obj, GXLightID light); + +// Set functions. +extern void GXSetChanAmbColor(GXChannelID channel, GXColor color); +extern void GXSetChanMatColor(GXChannelID channel, GXColor color); +extern void GXSetNumChans(u8 count); +extern void GXSetChanCtrl(GXChannelID channel, GXBool doEnable, GXColorSrc ambSrc, GXColorSrc matSrc, u32 mask, GXDiffuseFn diffFunc, + GXAttnFn attnFunc); + +// Unused/inlined in P2. +extern void GXInitLightAttnA(GXLightObj* obj, f32 a0, f32 a1, f32 a2); +extern void GXGetLightAttnA(GXLightObj* obj, f32* a0, f32* a1, f32* a2); +extern void GXInitLightAttnK(GXLightObj* obj, f32 k0, f32 k1, f32 k2); +extern void GXGetLightAttnK(GXLightObj* obj, f32* k0, f32* k1, f32* k2); + +extern void GXGetLightPos(GXLightObj* obj, f32* x, f32* y, f32* z); +extern void GXGetLightDir(GXLightObj* obj, f32* nX, f32* nY, f32* nZ); + +extern void GXInitSpecularDirHA(GXLightObj* obj, f32 nX, f32 nY, f32 nZ, f32 hX, f32 hY, f32 hZ); + +extern void GXGetLightColor(GXLightObj* obj, GXColor* color); + +extern void GXLoadLightObjIndx(u32 objIndex, GXLightID light); + +//////////////////////////////////////////// + +/////////////// LIGHT MACROS /////////////// +#define GXInitLightPosVec(obj, vec) (GXInitLightPos((obj), *(f32*)(vec), *((f32*)(vec) + 1), *((f32*)(vec) + 2))) + +#define GXInitLightDirVec(obj, vec) (GXInitLightDir((obj), *(f32*)(vec), *((f32*)(vec) + 1), *((f32*)(vec) + 2))) + +#define GXInitSpecularDirVec(obj, vec) (GXInitSpecularDir((obj), *(f32*)(vec), *((f32*)(vec) + 1), *((f32*)(vec) + 2))) + +#define GXInitLightShininess(obj, shine) (GXInitLightAttn((obj), 0.0f, 0.0f, 1.0f, (shine) / 2.0f, 0.0f, 1.0f - (shine) / 2.0f)) + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXMisc.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXMisc.h new file mode 100644 index 0000000..99daf85 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXMisc.h @@ -0,0 +1,88 @@ +#ifndef _DOLPHIN_GXMISC_H +#define _DOLPHIN_GXMISC_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" +#include "Dolphin/GX/GXFifo.h" +#include "Dolphin/OS/OSInterrupt.h" + +//////////////// CALLBACKS ///////////////// +typedef void (*GXDrawSyncCallback)(u16 token); +typedef void (*GXDrawDoneCallback)(void); + +//////////////////////////////////////////// + +///////////// BASIC FUNCTIONS ////////////// +static GXTexRegion* __GXDefaultTexRegionCallback(const GXTexObj* obj, GXTexMapID id); +static GXTlutRegion* __GXDefaultTlutRegionCallback(u32 tlut); +static BOOL __GXShutdown(BOOL final); // need to check types + +//////////////////////////////////////////// + +////////////// INIT FUNCTIONS ////////////// +extern GXFifoObj* GXInit(void* base, u32 size); +extern void __GXInitGX(); // need to check types +extern void __GXPEInit(); + +//////////////////////////////////////////// + +////////////// MISC FUNCTIONS ////////////// +// Basic functions. +extern void GXSetMisc(GXMiscToken token, u32 val); +extern void GXFlush(); +extern void __GXAbort(); // need to check types +extern void GXAbortFrame(); + +// Draw functions. +extern void GXSetDrawSync(u16 token); +extern void GXSetDrawDone(); +extern void GXWaitDrawDone(); +extern void GXDrawDone(); + +// Other syncs/interrupts. +extern void GXPixModeSync(); +extern GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback callback); +extern void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context); +extern GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback callback); +extern void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* context); + +// Poke functions. +extern void GXPokeAlphaMode(GXCompare func, u8 threshold); +extern void GXPokeAlphaRead(GXAlphaReadMode mode); +extern void GXPokeAlphaUpdate(GXBool doUpdate); +extern void GXPokeBlendMode(GXBlendMode mode, GXBlendFactor srcFactor, GXBlendFactor destFactor, GXLogicOp op); +extern void GXPokeColorUpdate(GXBool doUpdate); +extern void GXPokeDstAlpha(GXBool doEnable, u8 alpha); +extern void GXPokeDither(GXBool doDither); +extern void GXPokeZMode(GXBool doCompare, GXCompare func, GXBool doUpdate); + +// Unused/inlined in P2. +extern BOOL IsWriteGatherBufferEmpty(); +extern void EnableWriteGatherPipe(); +extern void DisableWriteGatherPipe(); +extern void GXResetWriteGatherPipe(); + +extern void GXReadDrawSync(); +extern void GXTexModeSync(); + +extern void GXPeekARGB(u16 x, u16 y, u32* color); +extern void GXPokeARGB(u16 x, u16 y, u32 color); +extern void GXPeekZ(u16 x, u16 y, u32* z); +extern void GXPokeZ(u16 x, u16 y, u32 z); + +extern u32 GXCompressZ16(u32 z24, GXZFmt16 zFormat); +extern u32 GXDecompressZ16(u32 z16, GXZFmt16 zFormat); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXPerf.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXPerf.h new file mode 100644 index 0000000..675fcc8 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXPerf.h @@ -0,0 +1,39 @@ +#ifndef _DOLPHIN_GXPERF_H +#define _DOLPHIN_GXPERF_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" + +///////////// METRIC FUNCTIONS ///////////// +extern void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1); +extern void GXClearGPMetric(); +extern void GXReadXfRasMetric(u32* xfWaitIn, u32* xfWaitOut, u32* rasBusy, u32* clocks); + +// Unused/inlined in P2. +extern void GXReadGPMetric(u32* count0, u32* count1); +extern u32 GXReadGP0Metric(); +extern u32 GXReadGP1Metric(); +extern void GXReadMemMetric(u32* cpReq, u32* tcReq, u32* cpuReadReq, u32* cpuWriteReq, u32* dspReq, u32* ioReq, u32* viReq, u32* peReq, + u32* rfReq, u32* fiReq); +extern void GXClearMemMetric(); +extern void GXReadPixMetric(u32* topIn, u32* topOut, u32* bottomIn, u32* bottomOut, u32* clearIn, u32* copyClocks); +extern void GXClearPixMetric(); +extern void GXSetVCacheMetric(GXVCachePerf attr); +extern void GXReadVCacheMetric(u32* check, u32* miss, u32* stall); +extern void GXClearVCacheMetric(); +extern void GXInitXfRasMetric(); +extern u32 GXReadClksPerVtx(); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXPixel.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXPixel.h new file mode 100644 index 0000000..d37bfd3 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXPixel.h @@ -0,0 +1,42 @@ +#ifndef _DOLPHIN_GXPIXEL_H +#define _DOLPHIN_GXPIXEL_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" +#include "Dolphin/mtx.h" + +///////////// PIXEL FUNCTIONS ////////////// +// Fog functions. +extern void GXSetFog(GXFogType type, f32 startZ, f32 endZ, f32 nearZ, f32 farZ, GXColor color); +extern void GXInitFogAdjTable(GXFogAdjTable* table, u16 width, const Mtx44 projMtx); +extern void GXSetFogRangeAdj(GXBool doEnable, u16 center, GXFogAdjTable* table); + +// Blend functions. +extern void GXSetBlendMode(GXBlendMode type, GXBlendFactor srcFactor, GXBlendFactor destFactor, GXLogicOp op); + +// Color update functions. +extern void GXSetColorUpdate(GXBool enableUpdate); +extern void GXSetAlphaUpdate(GXBool enableUpdate); + +// Other setter functions. +extern void GXSetZMode(GXBool enableCompare, GXCompare func, GXBool enableUpdate); +extern void GXSetZCompLoc(GXBool isBeforeTex); +extern void GXSetPixelFmt(GXPixelFmt pixelFormat, GXZFmt16 zFormat); +extern void GXSetDither(GXBool doDither); +extern void GXSetDstAlpha(GXBool doEnable, u8 alpha); +extern void GXSetFieldMask(GXBool doOddMask, GXBool doEvenMask); +extern void GXSetFieldMode(GXBool doFieldMode, GXBool doHalfAspectRatio); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTev.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTev.h new file mode 100644 index 0000000..bccfdda --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTev.h @@ -0,0 +1,44 @@ +#ifndef _DOLPHIN_GXTEV_H +#define _DOLPHIN_GXTEV_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" + +////// TEXTURE ENVIRONMENT FUNCTIONS /////// +extern void GXSetTevOp(GXTevStageID stage, GXTevMode mode); +extern void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d); +extern void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d); +extern void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool doClamp, GXTevRegID outReg); +extern void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool doClamp, GXTevRegID outReg); + +extern void GXSetTevColor(GXTevRegID reg, GXColor color); +extern void GXSetTevColorS10(GXTevRegID reg, GXColorS10 color); + +extern void GXSetTevKColor(GXTevKColorID id, GXColor color); +extern void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel); +extern void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel); + +extern void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel rasSel, GXTevSwapSel texSel); +extern void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, GXTevColorChan blue, GXTevColorChan alpha); + +extern void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1); +extern void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color); +extern void GXSetZTexture(GXZTexOp op, GXTexFmt format, u32 bias); +extern void GXSetNumTevStages(u8 count); + +// Unused/inlined in P2. +extern void GXSetTevClampMode(GXTevStageID stage, GXTevClampMode mode); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTexture.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTexture.h new file mode 100644 index 0000000..52a9ec4 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTexture.h @@ -0,0 +1,88 @@ +#ifndef _DOLPHIN_GXTEXTURE_H +#define _DOLPHIN_GXTEXTURE_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" + +//////////// TEXTURE CALLBACKS ///////////// + +typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* t_obj, GXTexMapID id); +typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 idx); + +//////////////////////////////////////////// + +////////////// TEXTURE MODES /////////////// +// Texture mode IDs. +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]; + +// Filter conversion arrays (HW2GX unused in P2). +extern u8 GX2HWFiltConv[6]; +// extern u8 HW2GXFiltConv[8]; + +//////////////////////////////////////////// + +//////////// TEXTURE FUNCTIONS ///////////// +// Init functions. +extern void GXInitTexObj(GXTexObj* obj, void* imagePtr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode sWrap, GXTexWrapMode tWrap, + GXBool useMIPmap); +extern void GXInitTexObjCI(GXTexObj* obj, void* imagePtr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode sWrap, + GXTexWrapMode tWrap, GXBool useMIPmap, u32 tlutName); +extern void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilter, GXTexFilter maxFilter, f32 minLOD, f32 maxLOD, f32 lodBias, + GXBool doBiasClamp, GXBool doEdgeLOD, GXAnisotropy maxAniso); + +// Get functions. +extern GXTexFmt GXGetTexObjFmt(GXTexObj* obj); +extern GXBool GXGetTexObjMipMap(GXTexObj* obj); +extern u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod); + +// Load functions. +extern void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID map); +extern void GXLoadTexObj(GXTexObj* obj, GXTexMapID map); + +// Tlut functions. +extern void GXInitTlutObj(GXTlutObj* obj, void* table, GXTlutFmt format, u16 numEntries); +extern void GXLoadTlut(GXTlutObj* obj, u32 tlutName); + +// Region functions. +extern void GXInitTexCacheRegion(GXTexRegion* region, GXBool is32bMIPmap, u32 memEven, GXTexCacheSize sizeEven, u32 memOdd, + GXTexCacheSize sizeOdd); +extern void GXInitTlutRegion(GXTlutRegion* region, u32 memAddr, GXTlutSize tlutSize); + +// Other functions. +extern void GXInvalidateTexAll(); +extern GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback func); +extern GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback func); + +// Unknown arg functions. +// TODO: work these out. +extern void __SetSURegs(); +extern void __GXSetSUTexRegs(); +extern void __GXSetTmemConfig(u32 config); + +// Unused/inlined in P2. +extern void GXInitTexObjData(GXTexObj* obj, void* imagePtr); +extern void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode sWrap, GXTexWrapMode tWrap); +extern void GXInitTexObjTlut(GXTexObj* obj, u32 tlutName); +// TODO: finish filling these out for reference purposes. + +extern void __GetImageTileCount(GXTexFmt format, u16 width, u16 height, u32* a, u32* b, u32* c); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTransform.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTransform.h new file mode 100644 index 0000000..ba27eb9 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTransform.h @@ -0,0 +1,59 @@ +#ifndef _DOLPHIN_GXTRANSFORM_H +#define _DOLPHIN_GXTRANSFORM_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" +#include "Dolphin/mtx.h" + +/////////// TRANSFORM FUNCTIONS //////////// +// Matrix and projection functions. +extern void GXSetProjection(const Mtx44 mtx, GXProjectionType type); +extern void GXSetProjectionv(const f32* ptr); +extern void GXLoadPosMtxImm(Mtx mtx, u32 id); +extern void GXLoadNrmMtxImm(Mtx mtx, u32 id); +extern void GXSetCurrentMtx(u32 id); +extern void GXLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type); +extern void __GXSetMatrixIndex(GXAttr index); + +// Viewport functions. +extern void __GXSetViewport(); // confirm types +extern void GXSetViewport(f32 left, f32 top, f32 width, f32 height, f32 nearZ, f32 farZ); + +// Scissor/clip functions. +extern void GXSetScissor(u32 left, u32 top, u32 width, u32 height); +extern void GXSetScissorBoxOffset(s32 x, s32 y); +extern void GXGetScissor(u32* left, u32* top, u32* width, u32* height); +extern void GXGetScissorBoxOffset(int xOffset, int yOffset); +extern void GXSetClipMode(GXClipMode mode); + +// Unused/inlined in P2. +extern void GXProject(f32 x, f32 y, f32 z, Mtx viewMtx, f32* projMtx, f32* viewport, f32* screenX, f32* screenY, f32* screenZ); +extern void GXGetProjectionv(f32* ptr); +extern void GXLoadPosMtxIndx(u16 index, u32 id); +extern void GXLoadNrmMtxImm3x3(Mtx33, u32 id); +extern void GXLoadNrmMtxIndx3x3(u16 index, u32 id); +extern void GXLoadTexMtxIndx(u16 index, u32 id, GXTexMtxType type); +extern void GXSetViewportJitter(f32 left, f32 top, f32 width, f32 height, f32 nearZ, f32 farZ, u32 field); +extern void GXGetViewportv(f32* viewport); + +//////////////////////////////////////////// + +////////////// USEFUL EXTRAS /////////////// +#define GX_PROJECTION_SZ 7 +#define GX_VIEWPORT_SZ 6 + +static inline void GXSetViewportv(f32* port) { GXSetViewport(port[0], port[1], port[2], port[3], port[4], port[5]); } + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTypes.h b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTypes.h new file mode 100644 index 0000000..9931fde --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/GX/GXTypes.h @@ -0,0 +1,158 @@ +#ifndef _DOLPHIN_GXTYPES_H +#define _DOLPHIN_GXTYPES_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/vi.h" + +///////////// USEFUL HELPERS /////////////// +// Set bitfields manually. +#define GX_BITFIELD(field, pos, size, value) (__rlwimi((field), (value), 31 - (pos) - (size) + 1, (pos), (pos) + (size) - 1)) +#define GX_BITFIELD_SET(field, pos, size, value) ((field) = GX_BITFIELD(field, pos, size, value)) +#define GX_BITFIELD_TRUNC(field, pos, size, value) (__rlwimi((field), (value), 0, (pos), (pos) + (size) - 1)) +#define GX_BITGET(field, pos, size) ((field) >> (31 - (pos) - (size) + 1) & ((1 << (size)) - 1)) +//////////////////////////////////////////// + +////////////////// COLORS ////////////////// +// Generic 8-bit-component colors. +typedef struct _GXColor { + u8 r, g, b, a; // _00, _01, _02, _03 +} GXColor; + +#define GXCOLOR_AS_U32(color) (*((u32*)&(color))) +#define RGBA_TO_U32(r, g, b, a) (((u8)(r) << 24) | ((u8)(g) << 16) | ((u8)(b) << 8) | ((u8)(a))) + +// Signed 10-bit-component colors for TEV const (konst) colors. +typedef struct _GXColorS10 { + s16 r, g, b, a; // _00, _02, _04, _06 +} GXColorS10; + +//////////////////////////////////////////// + +///////////////// TEXTURES ///////////////// +// NB: these are all generic structs. Members aren't +// referenced directly, they only exist for size. + +// Generic struct for texture objects. +typedef struct _GXTexObj { + u8 pad[0x20]; // _00 +} GXTexObj; // size 0x20 + +// Internal struct for texture objects. +typedef struct _GXTexObjPriv { + u32 mode0; // _00 + u32 mode1; // _04 + u32 image0; // _08 + u32 image3; // _0C + void* userData; // _10 + GXTexFmt format; // _14 + u32 tlutName; // _18 + u16 loadCount; // _1C + u8 loadFormat; // _1E + u8 flags; // _1F +} GXTexObjPriv; + +// Generic struct for texture memory storage. +typedef struct _GXTexRegion { + u8 padding[0x10]; // _00 +} GXTexRegion; + +typedef struct _GXTexRegionPriv { + u32 unk0; // _00 + u32 unk4; // _04 + u32 unk8; // _08 + u8 unkC; // _0C + u8 unkD; // _0D + u8 padding[2]; // _0E +} GXTexRegionPriv; + +// Generic struct for texture look-up table objects. +typedef struct _GXTlutObj { + u8 padding[0xc]; // _00 +} GXTlutObj; + +typedef struct _GXTlutObjPriv { + u32 unk0; // _00 + u32 unk4; // _04 + u16 numEntries; // _08 + u8 padding[0x2]; // _0A +} GXTlutObjPriv; + +// Generic struct for texture look-up table memory storage. +typedef struct _GXTlutRegion { + u8 padding[0x10]; // _00 +} GXTlutRegion; + +typedef struct _GXTlutRegionPriv { + u32 unk0; // _00 + GXTlutObjPriv tlutObj; // _04 +} GXTlutRegionPriv; + +// Generic struct for light information. +typedef struct _GXLightObj { + u8 padding[0x40]; // _00 +} GXLightObj; // size 0x40 + +typedef struct __GXLightObjPriv { + u32 reserved[3]; // _00 + GXColor color; // _0C, light color + f32 a[3]; // _10, angle-attenuation coefficients + f32 k[3]; // _1C, distance-attenuation coefficients + f32 lpos[3]; // _28, diffuse: position; specular: direction + f32 ldir[3]; // _34, diffuse: direction; specular: half-angle +} GXLightObjPriv; + +//////////////////////////////////////////// + +/////////////// VERTEX INFO //////////////// +// Struct for vertex descriptive info. +typedef struct _GXVtxDescList { + GXAttr mAttr; // _00 + GXAttrType mType; // _04 +} GXVtxDescList; + +// Struct for vertex attribute formats. +typedef struct _GXVtxAttrFmtList { + GXAttr mAttr; // _00 + GXCompCnt mCount; // _04 + GXCompType mType; // _08 + u8 mFrac; // _0C +} GXVtxAttrFmtList; + +//////////////////////////////////////////// + +///////////// OTHER RENDERING ////////////// +// Struct for rendering modes. +typedef struct _GXRenderModeObj { + VITVMode viTVmode; // _00 + u16 fbWidth; // _04, frame buffer width (same for emb. and ext.) + u16 efbHeight; // _06, embedded frame buffer height + u16 xfbHeight; // _08, external frame buffer height (may scale emb.) + u16 viXOrigin; // _0A + u16 viYOrigin; // _0C + u16 viWidth; // _0E + u16 viHeight; // _10 + VIXFBMode xFBmode; // _14, single or double field for external frame buffer + u8 field_rendering; // _18, rendering fields/frames + u8 aa; // _19, is anti-aliasing on + u8 sample_pattern[12][2]; // _1C, anti-aliasing sample pattern + u8 vfilter[7]; // _34, vertical filter coeffs +} GXRenderModeObj; + +// Struct for storing fog adjustment values. +typedef struct _GXFogAdjTable { + u16 fogVals[10]; // _00 +} GXFogAdjTable; + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSAlarm.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSAlarm.h new file mode 100644 index 0000000..5c10a95 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSAlarm.h @@ -0,0 +1,55 @@ +#ifndef _DOLPHIN_OS_OSALARM_H +#define _DOLPHIN_OS_OSALARM_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" +#include "Dolphin/OS/OSUtil.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////////// ALARM TYPES ////////// +typedef struct OSAlarm OSAlarm; +typedef struct OSAlarmQueue OSAlarmQueue; + +// Generic alarm handler function. +typedef void (*OSAlarmHandler)(OSAlarm* alarm, OSContext* context); + +// Struct for storing alarm information (size 0x28). +struct OSAlarm { + OSAlarmHandler handler; // _00 + u32 tag; // _04 + OSTime fire; // _08 + OSAlarm* prev; // _10 + OSAlarm* next; // _14 + OSTime period; // _18, period of periodic alarm + OSTime start; // _20, start of periodic alarm +}; + +// Queue struct for OSAlarm. +struct OSAlarmQueue { + OSAlarm* head; + OSAlarm* tail; +}; + +// Alarm functions. +void OSInitAlarm(); +void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler); +void OSCreateAlarm(OSAlarm* alarm); +void OSCancelAlarm(OSAlarm* alarm); + +// Unused/inlined in P2. +BOOL OSCheckAlarmQueue(); +void OSSetAbsAlarm(OSAlarm* alarm, OSTime time, OSAlarmHandler handler); +void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler); +void OSSetAlarmTag(OSAlarm* alarm, u32 tag); +void OSCancelAlarms(u32 tag); + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSAlloc.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSAlloc.h new file mode 100644 index 0000000..5853c30 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSAlloc.h @@ -0,0 +1,56 @@ +#ifndef _DOLPHIN_OS_OSALLOC_H +#define _DOLPHIN_OS_OSALLOC_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////////// HEAP TYPES /////////// +// Useful typedef for heap locations. +typedef int OSHeapHandle; + +// Alloc visitor function type. +typedef void (*OSAllocVisitor)(void* obj, u32 size); + +// Current heap. +extern volatile OSHeapHandle __OSCurrHeap; + +////////////////////////////////// + +///////// HEAP FUNCTIONS ///////// +// Heap functions. +void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps); +OSHeapHandle OSCreateHeap(void* start, void* end); +OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap); +void OSFreeToHeap(OSHeapHandle heap, void* ptr); + +// Unused/inlined in P2. +void* OSAllocFromHeap(OSHeapHandle heap, u32 size); +void* OSAllocFixed(void** rStart, void** rEnd); +void OSDestroyHeap(OSHeapHandle heap); +void OSAddToHeap(OSHeapHandle heap, void* start, void* end); +s32 OSCheckHeap(OSHeapHandle heap); +void OSDumpHeap(OSHeapHandle heap); +u32 OSReferentSize(void* ptr); +void OSVisitAllocated(OSAllocVisitor visitor); + +////////////////////////////////// + +////////// HEAP MACROS /////////// +// Allocate 'size' bytes from current heap (unused in P2). +// Returns ptr to allocated space (32-aligned). +#define OSAlloc(size) OSAllocFromHeap(__OSCurrHeap, (size)) + +// Deallocates 'ptr' to current heap. +#define OSFree(ptr) OSFreeToHeap(__OSCurrHeap, (ptr)) + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSBootInfo.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSBootInfo.h new file mode 100644 index 0000000..dc53851 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSBootInfo.h @@ -0,0 +1,53 @@ +#ifndef _DOLPHIN_OS_OSBOOTINFO_H +#define _DOLPHIN_OS_OSBOOTINFO_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" +#include "Dolphin/dvd.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +//////// BOOT INFO TYPES ///////// +// Struct for boot information (size 0x40). +typedef struct OSBootInfo { + DVDDiskID DVDDiskID; // _00 + u32 magic; // _20 + u32 version; // _24 + u32 memorySize; // _28 + u32 consoleType; // _2C + void* arenaLo; // _30, overrides __ArenaLo if non-null + void* arenaHi; // _34, overrides FSTLocation if non-null + void* FSTLocation; // _38, start addr of FST area + u32 FSTMaxLength; // _3C, length of FST area +} OSBootInfo; + +// Disk header information, a.k.a. BI2 (size 0x28). +typedef struct BI2Debug { + int debugMonSize; // _00 + int simMemSize; // _04 + u32 argOffset; // _08 + u32 debugFlag; // _0C + int trackLocation; // _10 + int trackSize; // _14 + u32 countryCode; // _18 + u8 _1C[0x8]; // _1C, unknown + u32 padSpec; // _24 +} BI2Debug; + +// Magic number defines. +#define OS_BOOTINFO_MAGIC 0x0D15EA5E +#define OS_BOOTINFO_MAGIC_JTAG 0xE5207C22 +#define OS_DVD_MAGIC_NINTENDO 0xC2339F3D +#define OS_THREAD_STACK_MAGIC 0xDEADBABE + +#define OS_BOOTROM_ADDR 0x81300000 + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSCache.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSCache.h new file mode 100644 index 0000000..1b93ce6 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSCache.h @@ -0,0 +1,61 @@ +#ifndef _DOLPHIN_OS_OSCACHE_H +#define _DOLPHIN_OS_OSCACHE_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" +#include "Dolphin/OS/OSThread.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +///////// CACHE FUNCTIONS //////// +// Data cache functions. +void DCInvalidateRange(void* addr, u32 numBytes); +void DCFlushRange(void* addr, u32 numBytes); +void DCStoreRange(void* addr, u32 numBytes); +void DCFlushRangeNoSync(void* addr, u32 numBytes); +void DCStoreRangeNoSync(void* addr, u32 numBytes); +void DCZeroRange(void* addr, u32 numBytes); + +// Instruction cache functions. +void ICInvalidateRange(void* addr, u32 numBytes); +void ICFlashInvalidate(); +void ICEnable(); + +// Locked cache functions. +void LCEnable(); +void LCDisable(); +void LCStoreBlocks(void* destAddr, void* srcTag, u32 numBlocks); +u32 LCStoreData(void* destAddr, void* srcAddr, u32 numBytes); +void LCQueueWait(u32 length); + +// L2 cache functions. +void L2GlobalInvalidate(); + +// Unused/inlined in P2. +void DCTouchRange(void* addr, u32 numBytes); + +void ICSync(); +void ICDisable(); +void ICFreeze(); +void ICUnfreeze(); +void ICBlockInvalidate(void* addr); + +void LCLoadBlocks(void* destTag, void* srcAddr, u32 numBlocks); +u32 LCLoadData(void* destAddr, void* srcAddr, u32 numBytes); +u32 LCQueueLength(); +void LCFlushQueue(); + +void L2Enable(); +void L2Disable(); +void L2SetDataOnly(BOOL doDataOnly); +void L2SetWriteThrough(BOOL doWriteThrough); + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSContext.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSContext.h new file mode 100644 index 0000000..5b32cd8 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSContext.h @@ -0,0 +1,209 @@ +#ifndef _DOLPHIN_OS_OSCONTEXT_H +#define _DOLPHIN_OS_OSCONTEXT_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////////// CONTEXT TYPES ///////// +// Struct for holding register context info (size 0x2C8). +typedef struct OSContext { + u32 gpr[32]; // _00, general purpose registers. + u32 cr; // _80 + u32 lr; // _84 + u32 ctr; // _88 + u32 xer; // _8C + f64 fpr[32]; // _90, floating point registers. + u32 fpscr_pad; // _190 + u32 fpscr; // _194 + u32 srr0; // _198, exception handling 0. + u32 srr1; // _19C, exception handling 1. + u16 mode; // _1A0, context mode. + u16 state; // _1A2, |'d OS_CONTEXT_STATE_* + u32 gqr[8]; // _1A4, Gekko additional registers. + f64 psf[32]; // _1C8, Gekko additional registers. +} OSContext; + +// Size of context frame. +// NB: size of context + padding for stack frame header. +#define __OS_CONTEXT_FRAME 768 + +// Current context address (for asm functions). +#define OS_CURRENTCONTEXT_PADDR 0xC0 + +////////////////////////////////// + +/////// CONTEXT FUNCTIONS //////// +// Context functions. +void OSLoadContext(OSContext* context); +void OSClearContext(OSContext* context); +void OSInitContext(OSContext* context, u32 pc, u32 stackPtr); +void OSDumpContext(OSContext* context); +u32 OSSaveContext(OSContext* context); + +u32 OSGetStackPointer(); + +// Current context functions. +OSContext* OSGetCurrentContext(); +void OSSetCurrentContext(OSContext* context); + +// FPU functions. +void OSSaveFPUContext(OSContext* context); +void OSFillFPUContext(OSContext* context); + +// Unused/inlined in P2. +u32 OSSwitchStack(u32 newStackPtr); +int OSSwitchFiber(u32 pc, u32 newStackPtr); + +void OSLoadFPUContext(OSContext* context); + +////////////////////////////////// + +//////// REGISTER DEFINES //////// +// Floating point modes. +#define OS_CONTEXT_MODE_FPU (0x01U) +#define OS_CONTEXT_MODE_PSFP (0x02U) + +// Context states. +#define OS_CONTEXT_STATE_FPSAVED (0x01U) +#define OS_CONTEXT_STATE_EXC (0x02U) + +// General purpose registers. +#define OS_CONTEXT_R0 0 +#define OS_CONTEXT_R1 4 +#define OS_CONTEXT_R2 8 +#define OS_CONTEXT_R3 12 +#define OS_CONTEXT_R4 16 +#define OS_CONTEXT_R5 20 +#define OS_CONTEXT_R6 24 +#define OS_CONTEXT_R7 28 +#define OS_CONTEXT_R8 32 +#define OS_CONTEXT_R9 36 +#define OS_CONTEXT_R10 40 +#define OS_CONTEXT_R11 44 +#define OS_CONTEXT_R12 48 +#define OS_CONTEXT_R13 52 +#define OS_CONTEXT_R14 56 +#define OS_CONTEXT_R15 60 +#define OS_CONTEXT_R16 64 +#define OS_CONTEXT_R17 68 +#define OS_CONTEXT_R18 72 +#define OS_CONTEXT_R19 76 +#define OS_CONTEXT_R20 80 +#define OS_CONTEXT_R21 84 +#define OS_CONTEXT_R22 88 +#define OS_CONTEXT_R23 92 +#define OS_CONTEXT_R24 96 +#define OS_CONTEXT_R25 100 +#define OS_CONTEXT_R26 104 +#define OS_CONTEXT_R27 108 +#define OS_CONTEXT_R28 112 +#define OS_CONTEXT_R29 116 +#define OS_CONTEXT_R30 120 +#define OS_CONTEXT_R31 124 + +// Other registers. +#define OS_CONTEXT_CR 128 +#define OS_CONTEXT_LR 132 +#define OS_CONTEXT_CTR 136 +#define OS_CONTEXT_XER 140 + +// Floating point registers. +#define OS_CONTEXT_FPR0 144 +#define OS_CONTEXT_FPR1 152 +#define OS_CONTEXT_FPR2 160 +#define OS_CONTEXT_FPR3 168 +#define OS_CONTEXT_FPR4 176 +#define OS_CONTEXT_FPR5 184 +#define OS_CONTEXT_FPR6 192 +#define OS_CONTEXT_FPR7 200 +#define OS_CONTEXT_FPR8 208 +#define OS_CONTEXT_FPR9 216 +#define OS_CONTEXT_FPR10 224 +#define OS_CONTEXT_FPR11 232 +#define OS_CONTEXT_FPR12 240 +#define OS_CONTEXT_FPR13 248 +#define OS_CONTEXT_FPR14 256 +#define OS_CONTEXT_FPR15 264 +#define OS_CONTEXT_FPR16 272 +#define OS_CONTEXT_FPR17 280 +#define OS_CONTEXT_FPR18 288 +#define OS_CONTEXT_FPR19 296 +#define OS_CONTEXT_FPR20 304 +#define OS_CONTEXT_FPR21 312 +#define OS_CONTEXT_FPR22 320 +#define OS_CONTEXT_FPR23 328 +#define OS_CONTEXT_FPR24 336 +#define OS_CONTEXT_FPR25 344 +#define OS_CONTEXT_FPR26 352 +#define OS_CONTEXT_FPR27 360 +#define OS_CONTEXT_FPR28 368 +#define OS_CONTEXT_FPR29 376 +#define OS_CONTEXT_FPR30 384 +#define OS_CONTEXT_FPR31 392 + +// Floating point scratch (0x8 incl. padding) +#define OS_CONTEXT_FPSCR 400 + +// Exception handling registers. +#define OS_CONTEXT_SRR0 408 +#define OS_CONTEXT_SRR1 412 + +// Context mode registers (0x2 each). +#define OS_CONTEXT_MODE 416 +#define OS_CONTEXT_STATE 418 + +// Gekko-specific GQR registers. +#define OS_CONTEXT_GQR0 420 +#define OS_CONTEXT_GQR1 424 +#define OS_CONTEXT_GQR2 428 +#define OS_CONTEXT_GQR3 432 +#define OS_CONTEXT_GQR4 436 +#define OS_CONTEXT_GQR5 440 +#define OS_CONTEXT_GQR6 444 +#define OS_CONTEXT_GQR7 448 +#define __OSCONTEXT_PADDING 452 // padding for double-word alignment of PSFs. + +// Gekko-specific PSF registers. +#define OS_CONTEXT_PSF0 456 +#define OS_CONTEXT_PSF1 464 +#define OS_CONTEXT_PSF2 472 +#define OS_CONTEXT_PSF3 480 +#define OS_CONTEXT_PSF4 488 +#define OS_CONTEXT_PSF5 496 +#define OS_CONTEXT_PSF6 504 +#define OS_CONTEXT_PSF7 512 +#define OS_CONTEXT_PSF8 520 +#define OS_CONTEXT_PSF9 528 +#define OS_CONTEXT_PSF10 536 +#define OS_CONTEXT_PSF11 544 +#define OS_CONTEXT_PSF12 552 +#define OS_CONTEXT_PSF13 560 +#define OS_CONTEXT_PSF14 568 +#define OS_CONTEXT_PSF15 576 +#define OS_CONTEXT_PSF16 584 +#define OS_CONTEXT_PSF17 592 +#define OS_CONTEXT_PSF18 600 +#define OS_CONTEXT_PSF19 608 +#define OS_CONTEXT_PSF20 616 +#define OS_CONTEXT_PSF21 624 +#define OS_CONTEXT_PSF22 632 +#define OS_CONTEXT_PSF23 640 +#define OS_CONTEXT_PSF24 648 +#define OS_CONTEXT_PSF25 656 +#define OS_CONTEXT_PSF26 664 +#define OS_CONTEXT_PSF27 672 +#define OS_CONTEXT_PSF28 680 +#define OS_CONTEXT_PSF29 688 +#define OS_CONTEXT_PSF30 696 +#define OS_CONTEXT_PSF31 704 + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSError.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSError.h new file mode 100644 index 0000000..e1e1b1c --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSError.h @@ -0,0 +1,51 @@ +#ifndef _DOLPHIN_OS_OSERROR_H +#define _DOLPHIN_OS_OSERROR_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" +#include "Dolphin/OS/OSUtil.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////////// ERROR TYPES ////////// +// Useful typedef for errors. +typedef u16 OSError; + +// Error handler function type. +typedef void (*OSErrorHandler)(OSError error, OSContext* context, ...); +typedef void (*OSErrorHandlerNoVARG)(OSError error, OSContext* context, u32 p1, u32 p2); + +// Error functions. +OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler); + +// Error defines. +#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_PROTECTION (15) +#define OS_ERROR_MAX (OS_ERROR_PROTECTION + 1) + +// Error table. +extern OSErrorHandler __OSErrorTable[16]; + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSException.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSException.h new file mode 100644 index 0000000..34a1113 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSException.h @@ -0,0 +1,78 @@ +#ifndef _DOLPHIN_OS_OSEXCEPTION_H +#define _DOLPHIN_OS_OSEXCEPTION_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" +#include "Dolphin/OS/OSUtil.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +//////// EXCEPTION TYPES ///////// +// Useful typedef for exceptions. +typedef u8 __OSException; + +// Exception handler function type. +typedef void (*__OSExceptionHandler)(__OSException exception, OSContext* context); + +// Exception handling functions. +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler); +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception); + +////////////////////////////////// + +/////////// EXCEPTIONS /////////// +// Exception codes. +#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) + +////////////////////////////////// + +///////// CONTEXT SAVING ///////// +// Macro for saving context on exception (for asm functions). +#define OS_EXCEPTION_SAVE_GPRS(context) \ + stw r0, OS_CONTEXT_R0(context); \ + stw r1, OS_CONTEXT_R1(context); \ + stw r2, OS_CONTEXT_R2(context); \ + stmw r6, OS_CONTEXT_R6(context); \ + /* Save GQR1 to GQR7. GQR0 must always be zero */ \ + mfspr r0, GQR1; \ + stw r0, OS_CONTEXT_GQR1(context); \ + mfspr r0, GQR2; \ + stw r0, OS_CONTEXT_GQR2(context); \ + mfspr r0, GQR3; \ + stw r0, OS_CONTEXT_GQR3(context); \ + mfspr r0, GQR4; \ + stw r0, OS_CONTEXT_GQR4(context); \ + mfspr r0, GQR5; \ + stw r0, OS_CONTEXT_GQR5(context); \ + mfspr r0, GQR6; \ + stw r0, OS_CONTEXT_GQR6(context); \ + mfspr r0, GQR7; \ + stw r0, OS_CONTEXT_GQR7(context); + +// Moved from OSContext.h due to include looping. +void OSSwitchFPUContext(__OSException exception, OSContext* context); + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSExpansion.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSExpansion.h new file mode 100644 index 0000000..656c52b --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSExpansion.h @@ -0,0 +1,93 @@ +#ifndef _DOLPHIN_OS_OSEXPANSION_H +#define _DOLPHIN_OS_OSEXPANSION_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////////// EXI FUNCTIONS ///////// +// Callback function type. +typedef void (*EXICallback)(s32 channel, OSContext* context); + +// EXI functions. +BOOL EXIProbe(s32 channel); +s32 EXIProbeEx(s32 channel); + +s32 EXIGetType(s32 channel, u32 dev, u32* type); +char* EXIGetTypeString(u32 type); + +u32 __OSGetDIConfig(void); +void __OSEnableBarnacle(s32 chan, u32 dev); + +////////////////////////////////// + +/////////// EXI DEFINES ////////// +// Memory card defines. +#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 + +// Other external defines. +#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 + +// Freq defines. +#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 + +// Read/write. +#define EXI_READ 0 +#define EXI_WRITE 1 + +// EXI status. +#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 + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSFastCast.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSFastCast.h new file mode 100644 index 0000000..eec0764 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSFastCast.h @@ -0,0 +1,113 @@ +#ifndef _DOLPHIN_OS_OSFASTCAST_H +#define _DOLPHIN_OS_OSFASTCAST_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////// FAST CAST DEFINES //////// +// GQR formats. +#define OS_GQR_U8 (0x0004) // GQR 1 +#define OS_GQR_U16 (0x0005) // GQR 2 +#define OS_GQR_S8 (0x0006) // GQR 3 +#define OS_GQR_S16 (0x0007) // GQR 4 + +// GQRs for fast casting. +#define OS_FASTCAST_U8 (2) +#define OS_FASTCAST_U16 (3) +#define OS_FASTCAST_S8 (4) +#define OS_FASTCAST_S16 (5) + +////////////////////////////////// + +/////// FAST CAST INLINES //////// +// Initialise fast casting. +static inline void OSInitFastCast() +{ +#ifdef __MWERKS__ // clang-format off + asm { + li r3, OS_GQR_U8 + oris r3, r3, OS_GQR_U8 + mtspr 0x392, r3 + li r3, OS_GQR_U16 + oris r3, r3, OS_GQR_U16 + mtspr 0x393, r3 + li r3, OS_GQR_S8 + oris r3, r3, OS_GQR_S8 + mtspr 0x394, r3 + li r3, OS_GQR_S16 + oris r3, r3, OS_GQR_S16 + mtspr 0x395, r3 + } +#endif // clang-format on +} + +// Float to int. +// NB: should theoretically have these for u8/u16/s8/s16 eventually. +static inline s16 __OSf32tos16(register f32 inF) +{ + register s16 out; + u32 tmp; + register u32* tmpPtr = &tmp; +#ifdef __MWERKS__ // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_S16 + lha out, 0(tmpPtr) + } +#endif // 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; +#ifdef __MWERKS__ // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_U8 + lbz out, 0(tmpPtr) + } +#endif // clang-format on + + return out; +} + +static inline void OSf32tou8(f32* f, u8* out) { *out = __OSf32tou8(*f); } + +static inline s8 __OSf32tos8(register f32 inF) +{ + register s8 out; + u32 tmp; + register u32* tmpPtr = &tmp; +#ifdef __MWERKS__ // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_S8 + lbz out, 0(tmpPtr) + extsb out, out + } +#endif // clang-format on + + return out; +} + +static inline void OSf32tos8(f32* f, s8* out) { *out = __OSf32tos8(*f); } + +// Int to float. +// NB: should have these for u8/u16/s8/s16 eventually. + +// TODO: make these based on above/as necessary. + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSFont.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSFont.h new file mode 100644 index 0000000..98e459a --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSFont.h @@ -0,0 +1,88 @@ +#ifndef _DOLPHIN_OS_OSFONT_H +#define _DOLPHIN_OS_OSFONT_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////////// FONT HEADER ////////// +// Struct for holding font information (size 0x30). +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; + +////////////////////////////////// + +///////// FONT FUNCTIONS ///////// +// Common functions. +u16 OSGetFontEncode(); +char* OSGetFontWidth(const char* string, s32* width); + +// High-level functions. +BOOL OSInitFont(OSFontHeader* fontInfo); +char* OSGetFontTexture(const char* string, void** image, s32* x, s32* y, s32* width); + +// Low-level functions. +u32 OSLoadFont(OSFontHeader* fontInfo, void* temp); + +// Unused/inlined in P2. +char* OSGetFontTexel(char* string, void* image, s32 pos, s32 stride, s32* width); + +////////////////////////////////// + +////////// FONT DEFINES ////////// +typedef enum { + OS_FONT_ENCODE_ANSI, // 0 + OS_FONT_ENCODE_SJIS, // 1 + OS_FONT_ENCODE_2, // 2 + OS_FONT_ENCODE_UTF8, // 3 + OS_FONT_ENCODE_UTF16, // 4 + OS_FONT_ENCODE_UTF32, // 5 + OS_FONT_ENCODE_MAX, // 6 +} OSFontEncode; + +#define OS_FONT_ENCODE_NULL -1 +#define OS_FONT_ENCODE_ANSI 0 +#define OS_FONT_ENCODE_SJIS 1 + +#define OS_FONT_SIZE_ANSI (288 + 131072) // 9 sheets +#define OS_FONT_SIZE_SJIS (3840 + 1179648) // 1 sheet + +#define OS_FONT_ROM_SIZE_ANSI 12288 // 0x03000 +#define OS_FONT_ROM_SIZE_SJIS 315392 // 0x4D000 + +#define OS_FONT_DATA_SIZE_ANSI 65824 +#define OS_FONT_DATA_SIZE_SJIS 593636 + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSInterrupt.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSInterrupt.h new file mode 100644 index 0000000..7f25021 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSInterrupt.h @@ -0,0 +1,160 @@ +#ifndef _DOLPHIN_OS_OSINTERRUPT_H +#define _DOLPHIN_OS_OSINTERRUPT_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" +#include "Dolphin/OS/OSException.h" +#include "Dolphin/OS/OSUtil.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +//////// INTERRUPT TYPES ///////// +// Useful typedef for interrupts. +typedef s16 __OSInterrupt; + +// Interrupt handler function type. +typedef void (*__OSInterruptHandler)(__OSInterrupt interrupt, OSContext* context); + +// Mask type for interrupts, to use with defines. +typedef u32 OSInterruptMask; + +// Last interrupts. +extern volatile __OSInterrupt __OSLastInterrupt; // one of the Interrupt Codes below. +extern vu32 __OSLastInterruptSrr0; // SRR0 value at time of interrupt. +extern volatile OSTime __OSLastInterruptTime; // time of interrupt (from OSGetTime()). + +// Interrupt global addresses. +volatile OSInterruptMask __OSPriorInterruptMask AT_ADDRESS((u32)OSPhysicalToCached(0x00C4)); +volatile OSInterruptMask __OSCurrentInterruptMask AT_ADDRESS((u32)OSPhysicalToCached(0x00C8)); + +////////////////////////////////// + +////// INTERRUPT FUNCTIONS /////// +// Handler functions. +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler); +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt); + +// Interrupt functions. +void __OSDispatchInterrupt(__OSException exception, OSContext* context); +BOOL OSEnableInterrupts(); +BOOL OSDisableInterrupts(); +BOOL OSRestoreInterrupts(BOOL level); + +// Mask functions. +OSInterruptMask __OSMaskInterrupts(OSInterruptMask mask); +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask); + +// Unused/inlined in P2. +OSInterruptMask OSGetInterruptMask(); +OSInterruptMask OSSetInterruptMask(OSInterruptMask mask); + +////////////////////////////////// + +//////// INTERRUPT CODES ///////// +// Interrupt codes. +#define __OS_INTERRUPT_MEM_0 0 // Memory-related interrupts. +#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 // Audio-related interrupts. +#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 // Expanded-mem-related interrupts. +#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 // Processor-related interrupts. +#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 + +////////////////////////////////// + +//////// INTERRUPT MASKS ///////// +// Macro for masking interrupts. +#define OS_INTERRUPTMASK(interrupt) (0x80000000u >> (interrupt)) + +// Masks for memory-related interrupts. +#define OS_INTERRUPTMASK_MEM_0 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0) +#define OS_INTERRUPTMASK_MEM_1 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_1) +#define OS_INTERRUPTMASK_MEM_2 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_2) +#define OS_INTERRUPTMASK_MEM_3 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_3) +#define OS_INTERRUPTMASK_MEM_ADDRESS OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_ADDRESS) +#define OS_INTERRUPTMASK_MEM_RESET (OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | OS_INTERRUPTMASK_MEM_3) + +#define OS_INTERRUPTMASK_MEM \ + (OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | OS_INTERRUPTMASK_MEM_3 | OS_INTERRUPTMASK_MEM_ADDRESS) + +// Masks for audio-related interrupts. +#define OS_INTERRUPTMASK_DSP_AI OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_AI) +#define OS_INTERRUPTMASK_DSP_ARAM OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_ARAM) +#define OS_INTERRUPTMASK_DSP_DSP OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_DSP) + +#define OS_INTERRUPTMASK_DSP (OS_INTERRUPTMASK_DSP_AI | OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP) + +#define OS_INTERRUPTMASK_AI_AI OS_INTERRUPTMASK(__OS_INTERRUPT_AI_AI) +#define OS_INTERRUPTMASK_AI (OS_INTERRUPTMASK_AI_AI) + +// Masks for expanded-mem-related interrupts. +#define OS_INTERRUPTMASK_EXI_0_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXI) +#define OS_INTERRUPTMASK_EXI_0_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_TC) +#define OS_INTERRUPTMASK_EXI_0_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXT) + +#define OS_INTERRUPTMASK_EXI_0 (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT) + +#define OS_INTERRUPTMASK_EXI_1_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXI) +#define OS_INTERRUPTMASK_EXI_1_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_TC) +#define OS_INTERRUPTMASK_EXI_1_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXT) + +#define OS_INTERRUPTMASK_EXI_1 (OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT) + +#define OS_INTERRUPTMASK_EXI_2_EXI OS_INTERRUPTMASK(__OS_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) + +// Masks for processor-related interrupts. +#define OS_INTERRUPTMASK_PI_PE_TOKEN OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_TOKEN) +#define OS_INTERRUPTMASK_PI_PE_FINISH OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_FINISH) + +#define OS_INTERRUPTMASK_PI_PE (OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH) + +#define OS_INTERRUPTMASK_PI_CP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_CP) +#define OS_INTERRUPTMASK_PI_SI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_SI) +#define OS_INTERRUPTMASK_PI_DI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DI) +#define OS_INTERRUPTMASK_PI_RSW OS_INTERRUPTMASK(__OS_INTERRUPT_PI_RSW) +#define OS_INTERRUPTMASK_PI_ERROR OS_INTERRUPTMASK(__OS_INTERRUPT_PI_ERROR) +#define OS_INTERRUPTMASK_PI_VI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_VI) +#define OS_INTERRUPTMASK_PI_DEBUG OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DEBUG) +#define OS_INTERRUPTMASK_PI_HSP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_HSP) + +#define OS_INTERRUPTMASK_PI \ + (OS_INTERRUPTMASK_PI_CP | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI | OS_INTERRUPTMASK_PI_RSW | OS_INTERRUPTMASK_PI_ERROR \ + | OS_INTERRUPTMASK_PI_VI | OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH | OS_INTERRUPTMASK_PI_DEBUG \ + | OS_INTERRUPTMASK_PI_HSP) + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMemory.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMemory.h new file mode 100644 index 0000000..d784f60 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMemory.h @@ -0,0 +1,40 @@ +#ifndef _DOLPHIN_OS_OSMEMORY_H +#define _DOLPHIN_OS_OSMEMORY_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////////// PROTECT INFO ////////// +// Protect function. +void OSProtectRange(u32 channel, void* addr, u32 numBytes, u32 control); + +// Channels. +#define OS_PROTECT_CHAN0 0 +#define OS_PROTECT_CHAN1 1 +#define OS_PROTECT_CHAN2 2 +#define OS_PROTECT_CHAN3 3 + +// Control codes. +#define OS_PROTECT_CONTROL_NONE 0x00 +#define OS_PROTECT_CONTROL_READ 0x01 // Can read. +#define OS_PROTECT_CONTROL_WRITE 0x02 // Can write. +#define OS_PROTECT_CONTROL_RDWR (OS_PROTECT_CONTROL_READ | OS_PROTECT_CONTROL_WRITE) + +// DSISR bits for mem error handler. +#define OS_PROTECT0_BIT 0x00000001 // Channel 0. +#define OS_PROTECT1_BIT 0x00000002 // Channel 1. +#define OS_PROTECT2_BIT 0x00000004 // Channel 2. +#define OS_PROTECT3_BIT 0x00000008 // Channel 3. +#define OS_PROTECT_ADDRERR_BIT 0x00000010 // Other mem. + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMessage.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMessage.h new file mode 100644 index 0000000..2bc49a7 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMessage.h @@ -0,0 +1,51 @@ +#ifndef _DOLPHIN_OS_OSMESSAGE_H +#define _DOLPHIN_OS_OSMESSAGE_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" +#include "Dolphin/OS/OSThread.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +///////// MESSAGE TYPES ////////// +typedef struct OSMessageQueue OSMessageQueue; + +// Useful typedef for messages. +typedef void* OSMessage; + +// Struct for managing the message queue. +struct OSMessageQueue { + OSThreadQueue queueSend; // _00 + OSThreadQueue queueReceive; // _08 + OSMessage* msgArray; // _10, array of messages. + s32 msgCount; // _14, array limit size. + s32 firstIndex; // _18, first message index in array. + s32 usedCount; // _1C, actual number of used messages. +}; + +// Defines for message flags for sending/receiving. +#define OS_MESSAGE_NOBLOCK (0) +#define OS_MESSAGE_BLOCK (1) + +typedef enum { + OS_MSG_PERSISTENT = (1 << 0), +} OSMessageFlags; + +////////////////////////////////// + +/////// MESSAGE FUNCTIONS //////// +// Functions for handling messages. +void OSInitMessageQueue(OSMessageQueue* queue, OSMessage* msgArray, s32 msgCount); +BOOL OSSendMessage(OSMessageQueue* queue, OSMessage msg, s32 flags); +BOOL OSJamMessage(OSMessageQueue* queue, OSMessage msg, s32 flags); +BOOL OSReceiveMessage(OSMessageQueue* queue, OSMessage* msgPtr, s32 flags); + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSModule.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSModule.h new file mode 100644 index 0000000..5f81d61 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSModule.h @@ -0,0 +1,112 @@ +#ifndef _DOLPHIN_OS_OSMODULE_H +#define _DOLPHIN_OS_OSMODULE_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////////// MODULE TYPES ////////// +// Forward declarations. +typedef struct OSModuleQueue OSModuleQueue; +typedef struct OSModuleLink OSModuleLink; +typedef struct OSModuleInfo OSModuleInfo; +typedef struct OSModuleHeader OSModuleHeader; +typedef struct OSSectionInfo OSSectionInfo; +typedef struct OSImportInfo OSImportInfo; +typedef struct OSRel OSRel; + +// Convenient typedef for module ID. +typedef u32 OSModuleID; + +// Module queue. +struct OSModuleQueue { + OSModuleInfo* head; // _00 + OSModuleInfo* tail; // _04 +}; + +// Module (doubly) linked list. +struct OSModuleLink { + OSModuleInfo* next; // _00 + OSModuleInfo* prev; // _04 +}; + +// Struct for module information (size 0x20). +struct OSModuleInfo { + OSModuleID id; // _00, unique id for module. + OSModuleLink link; // _04 + u32 numSections; // _0C + u32 sectionInfoOffset; // _10, section info table offset + u32 nameOffset; // _14, module name offset + u32 nameSize; // _18 + u32 version; // _1C +}; + +// Module header struct. +struct OSModuleHeader { + OSModuleInfo info; // _00 + u32 bssSize; // _20, total size of bss sections (bytes). + u32 relOffset; // _24 + u32 impOffset; // _28 + u32 impSize; // _2C, in bytes. + u8 prologSection; // _30, prolog section # + u8 epilogSection; // _31, epilog section # + u8 unresolvedSection; // _32, unresolved section # + u32 prolog; // _34, prolog offset + u32 epilog; // 38, epilog offset + u32 unresolved; // _3C, unresolved offset + + // may have 0x8 more here? check if needed for P2. + // u32 align; // _40 + // u32 bssAlign; // _44 +}; + +// Section information struct. +struct OSSectionInfo { + u32 offset; // _00 + u32 size; // _04 +}; + +// Import information struct. +struct OSImportInfo { + OSModuleID id; // _00 + u32 offset; // _04, offset to OSRel instructions. +}; + +// Rel information. +struct OSRel { + u16 offset; // _00 + u8 type; // _02 + u8 section; // _03 + u32 addend; // _04 +}; + +////////////////////////////////// + +//////// MODULE FUNCTIONS //////// +// Unused/inlined in P2. +void OSSetStringTable(void* stringTable); +BOOL OSLink(OSModuleInfo* newModule, void* bss); +BOOL OSUnlink(OSModuleInfo* oldModule); + +OSModuleInfo* OSSearchModule(void* ptr, u32* section, u32* offset); + +// Module defines/macros. +#define OSGetSectionInfo(module) ((OSSectionInfo*)(((OSModuleInfo*)(module))->sectionInfoOffset)) + +#define OS_SECTIONINFO_EXEC 0x1 +#define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~0x1) + +#define R_DOLPHIN_NOP 201 +#define R_DOLPHIN_SECTION 202 +#define R_DOLPHIN_END 203 + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMutex.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMutex.h new file mode 100644 index 0000000..08ec622 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSMutex.h @@ -0,0 +1,48 @@ +#ifndef _DOLPHIN_OS_OSMUTEX_H +#define _DOLPHIN_OS_OSMUTEX_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" +#include "Dolphin/OS/OSThread.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////////// MUTEX TYPES /////////// +// Main mutually exclusive (mutex) locking struct. +struct OSMutex { + OSThreadQueue queue; // _00 + OSThread* thread; // _08, current owner. + int count; // _0C, lock count. + OSMutexLink link; // _10 +}; + +// Cond struct (?) (size 0x8). +typedef struct OSCond { + OSThreadQueue queue; // _00 +} OSCond; + +////////////////////////////////// + +//////// MUTEX FUNCTIONS ///////// +// Mutex functions. +void OSInitMutex(OSMutex* mutex); +void OSLockMutex(OSMutex* mutex); +void OSUnlockMutex(OSMutex* mutex); +BOOL OSTryLockMutex(OSMutex* mutex); + +void __OSUnlockAllMutex(OSThread* thread); + +// Cond functions. +void OSInitCond(OSCond* cond); +void OSWaitCond(OSCond* cond, OSMutex* mutex); +void OSSignalCond(OSCond* cond); + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSReset.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSReset.h new file mode 100644 index 0000000..7ac764b --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSReset.h @@ -0,0 +1,92 @@ +#ifndef _DOLPHIN_OS_OSRESET_H +#define _DOLPHIN_OS_OSRESET_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////////// RESET INFO /////////// +typedef struct OSResetFunctionInfo OSResetFunctionInfo; + +// Reset function type. +typedef BOOL (*OSResetFunction)(BOOL final); + +// Reset callback type. +typedef void (*OSResetCallback)(void); + +// Struct for storing reset function information. +struct OSResetFunctionInfo { + OSResetFunction func; // _00 + u32 priority; // _04 + OSResetFunctionInfo* next; // _08 + OSResetFunctionInfo* prev; // _0C +}; + +// Queue struct for ResetFunctionInfos. +typedef struct OSResetQueue { + OSResetFunctionInfo* head; + OSResetFunctionInfo* tail; +} OSResetQueue; + +////////////////////////////////// + +//////// RESET FUNCTIONS ///////// +// Basic reset functions. +void OSRegisterResetFunction(OSResetFunctionInfo* info); +void OSResetSystem(int reset, u32 code, BOOL doForceMenu); +u32 OSGetResetCode(); +void OSGetSaveRegion(void** start, void** end); +void OSSetSaveRegion(void* start, void* end); + +// Reset switch functions. +BOOL OSGetResetButtonState(); +BOOL OSGetResetSwitchState(); + +// Reboot functions. +void __OSReboot(u32 resetCode, u32 bootDol); +void __OSDoHotReset(s32 code); +void OSSetSaveRegion(void* start, void* end); +void OSGetSaveRegion(void** start, void** end); +void OSGetSavedRegion(void** start, void** end); + +// Unused/inlined in P2. +void OSUnregisterResetFunction(OSResetFunctionInfo* info); +OSResetCallback OSSetResetCallback(OSResetCallback callback); + +////////////////////////////////// + +///////// RESET DEFINES ////////// +// Reset codes. +#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 + +// Reset priorities. +#define OS_RESET_PRIO_SO 110 +#define OS_RESET_PRIO_IP 111 +#define OS_RESET_PRIO_CARD 127 +#define OS_RESET_PRIO_MEM 127 +#define OS_RESET_PRIO_PAD 127 +#define OS_RESET_PRIO_GX 127 +#define OS_RESET_PRIO_ALARM 0xFFFFFFFF + +extern BOOL __OSIsGcam; + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSSerial.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSSerial.h new file mode 100644 index 0000000..94939c2 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSSerial.h @@ -0,0 +1,89 @@ +#ifndef _DOLPHIN_OS_OSSERIAL_H +#define _DOLPHIN_OS_OSSERIAL_H + +#include "types.h" +#include "Dolphin/OS/OSContext.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////////// SI FUNCTIONS ////////// +// Basic serial functions. +u32 SIProbe(s32 chan); +void SIRefreshSamplingRate(); +void SISetSamplingRate(u32 msec); + +////////////////////////////////// + +////////// SI DEFINES //////////// +// Max settings. +#define SI_MAX_CHAN 4 +#define SI_MAX_COMCSR_INLNGTH 128 +#define SI_MAX_COMCSR_OUTLNGTH 128 + +// Serial error codes. +#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 + +// Channels. +#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)) + +// Command type and status codes. +#define SI_TYPE_MASK 0x18000000u +#define SI_TYPE_N64 0x00000000u +#define SI_TYPE_DOLPHIN 0x08000000u +#define SI_TYPE_GC SI_TYPE_DOLPHIN + +// GC-specific codes. +#define SI_GC_WIRELESS 0x80000000 +#define SI_GC_NOMOTOR 0x20000000 +#define SI_GC_STANDARD 0x01000000 + +// WaveBird codes. +#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) + +// Other controller codes. +#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) + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSThread.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSThread.h new file mode 100644 index 0000000..d3ce453 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSThread.h @@ -0,0 +1,263 @@ +#ifndef _DOLPHIN_OS_OSTHREAD_H +#define _DOLPHIN_OS_OSTHREAD_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" +#include "Dolphin/OS/OSContext.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////////// THREAD TYPES ////////// +// Forward declarations. +typedef struct OSThread OSThread; +typedef struct OSThreadQueue OSThreadQueue; +typedef struct OSThreadLink OSThreadLink; +typedef struct OSMutex OSMutex; +typedef struct OSMutexQueue OSMutexQueue; +typedef struct OSMutexLink OSMutexLink; + +// Useful typedef for priority calls - 0 (high) to 31 (low). +typedef s32 OSPriority; + +// Idle function type. +typedef void (*OSIdleFunction)(void* param); + +// Start function. +typedef void* (*OSThreadStartFunction)(void*); + +// Thread switching function. +typedef void (*OSSwitchThreadCallback)(OSThread* from, OSThread* to); + +// Queues and links for threads. +struct OSThreadQueue { + OSThread* head; // _00 + OSThread* tail; // _04 +}; + +struct OSThreadLink { + OSThread* next; // _00 + OSThread* prev; // _04 +}; + +// Queues and links for mutexes. +struct OSMutexQueue { + OSMutex* head; // _00 + OSMutex* tail; // _04 +}; + +struct OSMutexLink { + OSMutex* next; // _00 + OSMutex* prev; // _04 +}; + +// Struct for managing threads. +struct OSThread { + OSContext context; // _000 + u16 state; // _2C8, see OS_THREAD_STATE enum. + u16 attr; // _2CA, 1 = detached. + s32 suspend; // _2CC, if > 0, suspend. + OSPriority priority; // _2D0, effective scheduling prio. + OSPriority base; // _2D4, base scheduling prio. + void* val; // _2D8, exit value. + OSThreadQueue* queue; // _2DC, owner queue. + OSThreadLink link; // _2E0 + OSThreadQueue queueJoin; // _2E8, threads waiting for termination. + OSMutex* mutex; // _2F0 + OSMutexQueue queueMutex; // _2F4, owned mutexes. + OSThreadLink linkActive; // _2FC, list of active threads + u8* stackBase; // _304, stack high addr. + u32* stackEnd; // _308, stack low addr (last word). + s32 error; // _30C + void* specific[2]; // _310 +}; + +// Thread global addresses. +volatile OSContext* __OSCurrentContext AT_ADDRESS((u32)OSPhysicalToCached(0x00D4)); +volatile OSContext* __OSFPUContext AT_ADDRESS((u32)OSPhysicalToCached(0x00D8)); +OSThreadQueue __OSActiveThreadQueue AT_ADDRESS((u32)OSPhysicalToCached(0x00DC)); +OSThread* __OSCurrentThread AT_ADDRESS((u32)OSPhysicalToCached(0x00E4)); + +////////////////////////////////// + +//////// THREAD FUNCTIONS //////// +// Basic thread functions. +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 priority, 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); + +void OSClearStack(u8 val); + +// Priority functions. +OSPriority OSGetThreadPriority(OSThread* thread); + +// 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(); +s32 OSCheckActiveThreads(); + +////////////////////////////////// + +///////// THREAD DEFINES ///////// +// Thread states. +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. +}; + +// Thread attributes. +#define OS_THREAD_ATTR_DETACH 0x1U + +// Thread priority. +#define OS_PRIORITY_MIN (0) // highest prio +#define OS_PRIORITY_MAX (31) // lowest prio +#define OS_PRIORITY_IDLE (OS_PRIORITY_MAX) // idle = lowest prio + +////////////////////////////////// + +///////// THREAD MACROS ////////// +// Add link to queue at tail. +#define AddTail(queue, thread, link) \ + do { \ + OSThread* prev; \ + \ + prev = (queue)->tail; \ + if (prev == nullptr) \ + (queue)->head = (thread); \ + else \ + prev->link.next = (thread); \ + (thread)->link.prev = prev; \ + (thread)->link.next = nullptr; \ + (queue)->tail = (thread); \ + } while (0) + +// Add link to queue in priority order. +#define AddPrio(queue, thread, link) \ + do { \ + OSThread *prev, *next; \ + \ + for (next = (queue)->head; next && next->priority <= thread->priority; next = next->link.next) \ + ; \ + if (next == nullptr) \ + AddTail(queue, thread, link); \ + else { \ + (thread)->link.next = next; \ + prev = next->link.prev; \ + next->link.prev = (thread); \ + (thread)->link.prev = prev; \ + if (prev == nullptr) \ + (queue)->head = (thread); \ + else \ + prev->link.next = (thread); \ + } \ + } while (0) + +// Remove link from queue. +#define RemoveItem(queue, thread, link) \ + do { \ + OSThread *next, *prev; \ + next = (thread)->link.next; \ + prev = (thread)->link.prev; \ + if (next == nullptr) \ + (queue)->tail = prev; \ + else \ + next->link.prev = prev; \ + if (prev == nullptr) \ + (queue)->head = next; \ + else \ + prev->link.next = next; \ + } while (0) + +// Remove head link from queue. +#define RemoveHead(queue, thread, link) \ + do { \ + OSThread* __next; \ + (thread) = (queue)->head; \ + __next = (thread)->link.next; \ + if (__next == nullptr) \ + (queue)->tail = nullptr; \ + else \ + __next->link.prev = nullptr; \ + (queue)->head = __next; \ + } while (0) + +////////////////////////////////// + +////////// MUTEX MACROS ////////// +// Add link to queue at tail. +#define AddTailMutex(queue, mutex, link) \ + do { \ + OSMutex* prev; \ + \ + prev = (queue)->tail; \ + if (prev == nullptr) \ + (queue)->head = (mutex); \ + else \ + prev->link.next = (mutex); \ + (mutex)->link.prev = prev; \ + (mutex)->link.next = nullptr; \ + (queue)->tail = (mutex); \ + } while (0) + +// Remove head link. +#define RemoveHeadMutex(queue, mutex, link) \ + do { \ + OSMutex* next; \ + \ + (mutex) = (queue)->head; \ + next = (mutex)->link.next; \ + if (next == nullptr) \ + (queue)->tail = nullptr; \ + else \ + next->link.prev = nullptr; \ + (queue)->head = next; \ + } while (0) + +// Remove item. +#define RemoveItemMutex(queue, mutex, link) \ + do { \ + OSMutex* next; \ + OSMutex* prev; \ + \ + next = (mutex)->link.next; \ + prev = (mutex)->link.prev; \ + \ + if (next == nullptr) \ + (queue)->tail = prev; \ + else \ + next->link.prev = prev; \ + \ + if (prev == nullptr) \ + (queue)->head = next; \ + else \ + prev->link.next = next; \ + } while (0) +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSUtil.h b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSUtil.h new file mode 100644 index 0000000..3458f3c --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/OS/OSUtil.h @@ -0,0 +1,104 @@ +#ifndef _DOLPHIN_OS_OSUTIL_H +#define _DOLPHIN_OS_OSUTIL_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +///// USEFUL MACROS/DEFINES ////// +// Macro for making clear things are addresses. +// if-def for future proofing and so VSCode doesn't yell. +#ifdef __MWERKS__ +#define AT_ADDRESS(addr) : (addr) +#else +#define AT_ADDRESS(addr) +#endif + +// Defines for cached and uncached memory. +#define OS_BASE_CACHED (0x80000000) +#define OS_BASE_UNCACHED (0xC0000000) + +// Necessary for inline asm functions. +#define OS_CACHED_REGION_PREFIX (0x8000) +#define OS_UNCACHED_REGION_PREFIX (0xC000) +#define OS_PHYSICAL_MASK (0x3FFF) + +////////////////////////////////// + +////////// CLOCK UTILS /////////// +// Time and tick typedefs for convenience. +typedef s64 OSTime; +typedef u32 OSTick; + +extern OSTime __OSStartTime; + +// Clock speeds. +u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); +u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); + +OSTime __OSGetSystemTime(); + +#define OS_BUS_CLOCK __OSBusClock +#define OS_CORE_CLOCK __OSCoreClock +#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4) + +// Tick conversions. +#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)) + +// Time-related getters. +OSTick OSGetTick(); +OSTime OSGetTime(); + +// Struct for 'calendar time'. +typedef struct OSCalendarTime +{ + int sec; // _00, secs after minute + int min; // _04, mins after hour + int hour; // _08, hours since midnight + int mday; // _0C, day of month + int mon; // _10, month since Jan + int year; // _14, years since 0000 + int wday; // _18, days since Sunday + int yday; // _1C, days since Jan 1 + int msec; // _20, millisecs after sec + int usec; // _24, microsecs after millisec +} OSCalendarTime; + +// Calendar time functions. +OSTime OSCalendarTimeToTicks(OSCalendarTime* timeDate); +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* timeDate); + +// Macros for rounding to 32-alignment. +#define OSRoundUp32B(x) (((u32)(x) + 0x1F) & ~(0x1F)) +#define OSRoundDown32B(x) (((u32)(x)) & ~(0x1F)) + +// Address conversions. +#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))) + +// Other useful addresses. +u16 __OSDeviceCode AT_ADDRESS(OS_BASE_CACHED | 0x30E6); + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/PPCArch.h b/dolphin sdk not yet linked/include FROM PIKMIN2/PPCArch.h new file mode 100644 index 0000000..f08fbf0 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/PPCArch.h @@ -0,0 +1,100 @@ +#ifndef _DOLPHIN_PPCARCH_H +#define _DOLPHIN_PPCARCH_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HID0 0x3f0 +#define HID0_ICE 0x8000 +#define HID0_ICFI 0x800 +#define HID0_DCE 0x4000 +#define HID2 0x398 +#define HID2_LCE_BIT 3 +#define MSR_ME 0x1000 +#define LC_BASE_PREFIX (0xE000) +#define LC_BASE (LC_BASE_PREFIX << 16) +#define DBAT3L 3 +#define DBAT3U 3 +#define DMA_U 0x39a +#define DMA_L 0x39b +#define DMA_L_STORE 0 +#define DMA_L_TRIGGER 2 +#define LC_MAX_DMA_BLOCKS 128 +#define LC_MAX_DMA_BYTES 0x1000 + +#define LCGetBase() ((void*)LC_BASE) + +#define MSR_IR 0x00000020 // instruction relocate +#define MSR_DR 0x00000010 // data relocate + +#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 L2CR_L2E 0x80000000 // L2 Enable +#define L2CR_L2I 0x00200000 // Global invalidate +#define L2CR_L2IP 0x00000001 // L2 global invalidate in progress + +#define SRR1_DMA_BIT 0x00200000 +#define SRR1_L2DP_BIT 0x00100000 + +#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 + +u32 PPCMfmsr(); +void PPCMtmsr(u32 newMSR); +// u32 PPCOrMsr(u32 value); +void PPCOrMsr(); +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(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/__start.h b/dolphin sdk not yet linked/include FROM PIKMIN2/__start.h new file mode 100644 index 0000000..df5a33e --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/__start.h @@ -0,0 +1,61 @@ +#include "types.h" +#include "Dolphin/db.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#define PAD3_BUTTON_ADDR 0x800030E4 +#define OS_RESET_RESTART 0 +#define FALSE 0 +#define TRUE 1 +#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 DOL_ADDR_LIMIT 0x80700000 + +extern void InitMetroTRK(); + +u16 Pad3Button : PAD3_BUTTON_ADDR; +static u8 Debug_BBA = 0; + +extern int main(int argc, char* argv[]); +extern void exit(int); +extern void __init_user(void); +extern void InitMetroTRK_BBA(void); +extern void OSInit(void); +extern void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu); +extern void __init_hardware(void); + +DECL_SECT(".init") extern void __check_pad3(void); +DECL_SECT(".init") extern void __set_debug_bba(void); +DECL_SECT(".init") extern u8 __get_debug_bba(void); +DECL_SECT(".init") extern void __start(void); +DECL_SECT(".init") extern void __init_registers(void); +DECL_SECT(".init") extern void __init_data(void); + +DECL_SECT(".init") extern u8 _stack_addr[]; +DECL_SECT(".init") extern char _SDA_BASE_[]; +DECL_SECT(".init") extern char _SDA2_BASE_[]; + +typedef struct __rom_copy_info { + char* rom; + char* addr; + uint size; +} __rom_copy_info; + +DECL_SECT(".init") extern __rom_copy_info _rom_copy_info[]; + +typedef struct __bss_init_info { + char* addr; + uint size; +} __bss_init_info; + +DECL_SECT(".init") extern __bss_init_info _bss_init_info[]; + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/card.h b/dolphin sdk not yet linked/include FROM PIKMIN2/card.h new file mode 100644 index 0000000..f52d5c5 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/card.h @@ -0,0 +1,399 @@ +#ifndef _DOLPHIN_CARD_H +#define _DOLPHIN_CARD_H + +#include "Dolphin/dsp.h" +#include "Dolphin/os.h" +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +//////////// BASIC CARD DEFINES //////////// +// Encodings. +#define CARD_ENCODE_ANSI 0u +#define CARD_ENCODE_SJIS 1u + +// Sizes. +#define CARD_WORKAREA_SIZE (5 * 8 * 1024) // 0xA000 (5 * 0x2000) +#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) + +//////////////////////////////////////////// + +//////////////// CARD TYPES //////////////// +// Forward declarations. +typedef struct CARDFileInfo CARDFileInfo; +typedef struct CARDStat CARDStat; +typedef struct CARDDir CARDDir; +typedef struct CARDDirCheck CARDDirCheck; +typedef struct CARDControl CARDControl; +typedef struct CARDID CARDID; +typedef struct CARDHeaderBlock CARDHeaderBlock; +typedef struct CARDDirectoryBlock CARDDirectoryBlock; +typedef struct CARDFatBlock CARDFatBlock; +typedef struct CARDMemoryCard CARDMemoryCard; + +// CARD callback function type. +typedef void (*CARDCallback)(s32 channel, s32 result); + +// Struct for storing basic file information (size 0x12). +struct CARDFileInfo { + s32 chan; // _00, channel. + s32 fileNo; // _04, file number. + s32 offset; // _08 + s32 length; // _0C + u16 iBlock; // _10 +}; + +// Struct for managing CARD status (size 0x70). +struct CARDStat { + char fileName[CARD_FILENAME_MAX]; // _00 + u32 length; // _20 + u32 time; // _24, secs since 01/01/2000 00:00. + u8 gameName[4]; // _28 + u8 company[2]; // _2C + u8 bannerFormat; // _2E + u32 iconAddr; // _30 + u16 iconFormat; // _34 + u16 iconSpeed; // _36 + u32 commentAddr; // _38 + u32 offsetBanner; // _3C + u32 offsetBannerTlut; // _40 + u32 offsetIcon[CARD_ICON_MAX]; // _44 + u32 offsetIconTlut; // _64 + u32 offsetData; // _68 + u32 reserved_6C; // _6C +}; + +// CARD directory entry information (size 0x40). +// NB: we had this called CARDDirEntry before. +struct CARDDir { + u8 gameName[4]; // _00 + u8 company[2]; // _04 + u8 reserved_06; // _06 + u8 bannerFormat; // _07, CARDBannerFlag, see enum. + u8 fileName[CARD_FILENAME_MAX]; // _08 + u32 time; // _28, secs since 01/01/2000, 00:00. + u32 iconAddr; // _2C, 0xFFFFFFFF if unused. + u16 iconFormat; // _30 + u16 iconSpeed; // _32 + u8 permission; // _34, CARDFilePermissions, see enum. + u8 copyTimes; // _35, # times copied from one card to another. + u16 startBlock; // _36 + u16 length; // _38, length of file in blocks. + u16 reserved_3A; // _3A + u32 commentAddr; // _3C +}; + +// Struct for DirectoryBlock-specific checksum information (size 0x40). +// Replaces the last CARDDir in CARDDirectoryBlock. +struct CARDDirCheck { + u8 padding[0x3A]; // _00 + s16 checkCode; // _3A + u16 checkSum; // _3C + u16 checkSumInv; // _3E +}; + +// Struct for CARD information (size 0x110). +// NB: we had this as CARDBlock previously. +struct CARDControl { + BOOL attached; // _00 + s32 result; // _04 + u16 size; // _08, size in Mbits. + u16 pageSize; // _0A, program size in bytes. + s32 sectorSize; // _0C, erase size in bytes. + u16 cBlock; // _10, # blocks. + u16 vendorID; // _12, 0xC243 for MX, 0xECE6 for Samsung + s32 latency; // _14, read latency in bytes. + u8 id[0xC]; // _18 + int mountStep; // _24 + int formatStep; // _28 + u32 scramble; // _2C, for __CARDUnlock(). + DSPTaskInfo task; // _30 + CARDMemoryCard* workArea; // _80, void* in docs. + CARDDirectoryBlock* currentDir; // _84, CARDDir* in docs. + CARDFatBlock* currentFat; // _88, u16* in docs. + OSThreadQueue threadQueue; // _8C, for sync functions. + u8 cmd[9]; // _94, for DMA mode commands. + s32 cmdlen; // _A0 + u32 mode; // _A4 + int retry; // _A8 + int repeat; // _AC, for multi xfer + u32 addr; // _B0 + void* buffer; // _B4 + s32 xferred; // _B8, for statistics. + u16 freeNo; // _BC + u16 startBlock; // _BE + CARDFileInfo* fileInfo; // _C0 + CARDCallback extCallback; // _C4 + CARDCallback txCallback; // _C8 + CARDCallback exiCallback; // _CC + CARDCallback apiCallback; // _D0 + CARDCallback xferCallback; // _D4 + CARDCallback eraseCallback; // _D8 + CARDCallback unlockCallback; // _DC + OSAlarm alarm; // _E0, for timeout. + u32 cid; // _108 + const DVDDiskID* diskID; // _10C +}; + +// CARD identification struct (size 0x200). +// NB: we had this as part of CARDHeaderBlock before. +struct CARDID { + u8 serial[0x20]; // _00, flashID(0xC), timebase(8), counterBias(4), lang(4), XXX(4). + u16 deviceID; // _20 + u16 size; // _22 + u16 encode; // _24 + u8 padding[0x1D4]; // _26 + s16 checkCode; // _1FA + u16 checkSum; // _1FC + u16 checkSumInv; // _1FE +}; + +// Header block for CARDMemoryCard (size 0x2000). +// NB: fabricated - this is just void*. +struct CARDHeaderBlock { + CARDID id; // _000 + u8 buffer[0x1E00]; // _200 +}; + +// Directory information block for CARDMemoryCard (size 0x2000). +// NB: fabricated - this is just CARDDir* (with a cast for the last one). +struct CARDDirectoryBlock { + CARDDir entries[CARD_MAX_FILE]; // _0000 + CARDDirCheck check; // _1FC0 +}; + +// File allocation table struct for CARDMemoryCard (size 0x2000). +// NB: fabricated - this is just u16*. +struct CARDFatBlock { + u16 checkSum; // _00 + u16 checkSumInv; // _02 + u16 checkCode; // _04 + u16 freeBlocks; // _06 + u16 lastAllocBlock; // _08 + u16 allocMap[0xFFB]; // _0A +}; + +// Struct for working area of memory card (size 0xA000). +// NB: fabricated - this is just void*. +struct CARDMemoryCard { + CARDHeaderBlock header; // _0000 + CARDDirectoryBlock dirBlock; // _2000 + CARDDirectoryBlock dirBlockBackup; // _4000 + CARDFatBlock blockAllocMap; // _6000 + CARDFatBlock blockAllocMapBackup; // _8000 +}; + +// Struct for use in CARDUnlock. +typedef struct CARDDecodeParameters { + u8* inputAddr; // _00 + u32 inputLength; // _04 + u32 aramAddr; // _08 + u8* outputAddr; // _0C +} CARDDecodeParameters; + +// Enum for 'permission' in CARDDir. +typedef enum { FilePermPublic = 0x2, FilePermNoCopy = 0x4, FilePermNoMove = 0x8 } CARDFilePermissions; + +// Enum for banner format in CARDDir. +typedef enum { BannerColorCI8 = 0x1, BannerPresent = 0x2, IconAnimationPingPong = 0x4 } CARDBannerFlag; + +// Managers for both memory card slots (A and B). +extern CARDControl __CARDBlock[2]; + +// Other CARD information. +extern DVDDiskID __CARDDiskNone; +extern u16 __CARDVendorID; +extern u8 __CARDPermMask; + +//////////////////////////////////////////// + +////////////// CARD FUNCTIONS ////////////// +// Basic CARD functions. +void CARDInit(); + +// CARD checking functions. +s32 CARDCheck(s32 channel); +s32 CARDCheckExAsync(s32 channel, s32* xferBytes, CARDCallback callback); + +// CARD BIOS functions. +s32 CARDFreeBlocks(s32 channel, s32* byteNotUsed, s32* filesNotUsed); + +// CARD mounting functions. +BOOL CARDProbe(s32 channel); +s32 CARDProbeEx(s32 channel, s32* memSize, s32* sectorSize); +s32 CARDMountAsync(s32 channel, CARDMemoryCard* workArea, CARDCallback detachCallback, CARDCallback attachCallback); +s32 CARDMount(s32 channel, CARDMemoryCard* workArea, CARDCallback detachCallback); +s32 CARDUnmount(s32 channel); + +// CARD formatting functions. +s32 CARDFormat(s32 channel); + +// CARD open/close. +s32 CARDOpen(s32 channel, char* fileName, CARDFileInfo* fileInfo); +s32 CARDClose(CARDFileInfo* fileInfo); + +// CARD create/read/write functions. +s32 CARDCreate(s32 channel, char* fileName, u32 size, CARDFileInfo* fileInfo); +s32 CARDCreateAsync(s32 channel, char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback); +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, void* addr, s32 length, s32 offset); +s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset, CARDCallback callback); + +// CARD status functions. +s32 CARDGetStatus(s32 channel, s32 fileNo, CARDStat* state); +s32 CARDSetStatus(s32 channel, s32 fileNo, CARDStat* state); +s32 CARDSetStatusAsync(s32 channel, s32 fileNo, CARDStat* state, CARDCallback callback); + +// CARD serial functions. +s32 CARDGetSerialNo(s32 channel, u64* serialNo); + +// NB: steal more functions from prime as required. + +//////////////////////////////////////////// + +////////// PRIVATE CARD FUNCTIONS ////////// +// Handlers and callbacks. +void __CARDDefaultApiCallback(s32 channel, s32 result); +void __CARDSyncCallback(s32 channel, s32 result); +void __CARDExtHandler(s32 channel, OSContext* context); +void __CARDExiHandler(s32 channel, OSContext* context); +void __CARDTxHandler(s32 channel, OSContext* context); +void __CARDUnlockedHandler(s32 channel, OSContext* context); + +// Other CARD BIOS functions. +s32 __CARDEnableInterrupt(s32 channel, BOOL enable); +s32 __CARDReadStatus(s32 channel, u8* status); +s32 __CARDClearStatus(s32 channel); +s32 __CARDStart(s32 channel, CARDCallback txCallback, CARDCallback exiCallback); +s32 __CARDReadSegment(s32 channel, CARDCallback callback); +s32 __CARDWritePage(s32 channel, CARDCallback callback); +s32 __CARDEraseSector(s32 channel, u32 addr, CARDCallback callback); +u16 __CARDGetFontEncode(); +void __CARDSetDiskID(const DVDDiskID* diskID); +s32 __CARDGetControlBlock(s32 channel, CARDControl** card); +s32 __CARDPutControlBlock(CARDControl* card, s32 result); +s32 __CARDSync(s32 channel); +void __CARDCheckSum(void* data, int length, u16* checksum, u16* checksumInv); + +CARDDirectoryBlock* __CARDGetDirBlock(CARDControl* card); +CARDFatBlock* __CARDGetFatBlock(CARDControl* card); + +//////////////////////////////////////////// + +//////////// OTHER CARD DEFINES //////////// +// Icon animation modes. +#define CARD_MODE_NORMAL 0 +#define CARD_MODE_FAST 1 + +// Result codes. +#define CARD_RESULT_UNLOCKED 1 +#define CARD_RESULT_READY 0 +#define CARD_RESULT_BUSY -1 +#define CARD_RESULT_WRONGDEVICE -2 +#define CARD_RESULT_NOCARD -3 +#define CARD_RESULT_NOFILE -4 +#define CARD_RESULT_IOERROR -5 +#define CARD_RESULT_BROKEN -6 +#define CARD_RESULT_EXIST -7 +#define CARD_RESULT_NOENT -8 +#define CARD_RESULT_INSSPACE -9 +#define CARD_RESULT_NOPERM -10 +#define CARD_RESULT_LIMIT -11 +#define CARD_RESULT_NAMETOOLONG -12 +#define CARD_RESULT_ENCODING -13 +#define CARD_RESULT_CANCELED -14 +#define CARD_RESULT_FATAL_ERROR -128 + +// Icon status codes. +#define CARD_STAT_ICON_NONE 0 +#define CARD_STAT_ICON_C8 1 +#define CARD_STAT_ICON_RGB5A3 2 +#define CARD_STAT_ICON_MASK 3 + +// Banner status codes. +#define CARD_STAT_BANNER_NONE 0 +#define CARD_STAT_BANNER_C8 1 +#define CARD_STAT_BANNER_RGB5A3 2 +#define CARD_STAT_BANNER_MASK 3 + +// Animation status codes. +#define CARD_STAT_ANIM_LOOP 0x00 +#define CARD_STAT_ANIM_BOUNCE 0x04 +#define CARD_STAT_ANIM_MASK 0x04 + +// Animation speed status codes. +#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 + +// CARD attribute codes. +#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 + +// Private info defines. +#define CARD_FAT_AVAIL 0x0000u +#define CARD_FAT_CHECKSUM 0x0000u +#define CARD_FAT_CHECKSUMINV 0x0001u +#define CARD_FAT_CHECKCODE 0x0002u +#define CARD_FAT_FREEBLOCKS 0x0003u +#define CARD_FAT_LASTSLOT 0x0004u + +#define CARD_PAGE_SIZE 128u +#define CARD_SEG_SIZE 512u + +#define CARD_NUM_SYSTEM_BLOCK 5 +#define CARD_SYSTEM_BLOCK_SIZE (8 * 1024u) + +#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2) + +// Useful conversion macros. +#define TRUNC(n, a) (((u32)(n)) & ~((a) - 1)) +#define OFFSET(n, a) (((u32)(n)) & ((a) - 1)) + +#define CARDIsValidBlockNo(card, iBlock) (CARD_NUM_SYSTEM_BLOCK <= (iBlock) && (iBlock) < (card)->cBlock) + +#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 CARDGetDirectoryBlock(card, i) ((CARDDirectoryBlock*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE)) +#define CARDGetFatBlock(card, i) ((CARDFatBlock*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE)) + +//////////////////////////////////////////// +#ifdef __cplusplus +} +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/db.h b/dolphin sdk not yet linked/include FROM PIKMIN2/db.h new file mode 100644 index 0000000..14bd53f --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/db.h @@ -0,0 +1,34 @@ +#ifndef _DOLPHIN_DB_H +#define _DOLPHIN_DB_H + +#include "types.h" +#include "Dolphin/os.h" +#include "Dolphin/AmcExi2Stubs.h" + +#define ExceptionHookDestination 0x80000048 +#define IsDebuggerPresent 0x80000040 + +// static int __DBInterface; + +struct DBInterface { + u8 filler0[4]; + u32 unk4; +}; + +static struct DBInterface* __DBInterface; +static int DBVerbose; + +void DBInit(void); +void DBInitComm(vu8**, AmcEXICallback); // possibly not this type, but some similar construction + +void DBInitInterrupts(); +u32 DBQueryData(); +BOOL DBRead(void*, u32); +BOOL DBWrite(const void*, u32); +void DBOpen(); +void DBClose(); + +static void __DBExceptionDestination(void); +void DBPrintf(const char* format, ...); + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/dsp.h b/dolphin sdk not yet linked/include FROM PIKMIN2/dsp.h new file mode 100644 index 0000000..76e55b3 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/dsp.h @@ -0,0 +1,95 @@ +#ifndef _DOLPHIN_DSP_H +#define _DOLPHIN_DSP_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" +#include "Dolphin/OS/OSContext.h" +#include "Dolphin/OS/OSInterrupt.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +//////////////// DSP TYPES ///////////////// +typedef struct STRUCT_DSP_TASK DSPTaskInfo; + +// Digital signal processor callback. +typedef void (*DSPCallback)(void* task); + +// Struct for digital signal processing information (size 0x50). +struct STRUCT_DSP_TASK { + vu32 state; // _00, state of task. + vu32 priority; // _04 + vu32 flags; // _08 + u16* iram_mmem_addr; // _0C, IRAM image info. + u32 iram_length; // _10 + u32 iram_addr; // _14 + u16* dram_mmem_addr; // _18, DRAM image info. + u32 dram_length; // _1C + u32 dram_addr; // _20 + u16 dsp_init_vector; // _24, start vector on first exec. + u16 dsp_resume_vector; // _26, start vector on resume. + DSPCallback init_cb; // _28, callbacks for states. + DSPCallback res_cb; // _2C + DSPCallback done_cb; // _30 + DSPCallback req_cb; // _34 + DSPTaskInfo* next; // _38, linked list. + DSPTaskInfo* prev; // _3C + OSTime t_context; // _40 + OSTime t_task; // _48 +}; + +// Task information storage. +extern DSPTaskInfo* __DSP_tmp_task; +extern DSPTaskInfo* __DSP_last_task; +extern DSPTaskInfo* __DSP_first_task; +extern DSPTaskInfo* __DSP_curr_task; + +// Useful defines. +#define DSP_TASK_FLAG_CLEARALL 0x00000000 +#define DSP_TASK_FLAG_ATTACHED 0x00000001 +#define DSP_TASK_FLAG_CANCEL 0x00000002 + +#define DSP_TASK_STATE_INIT 0 +#define DSP_TASK_STATE_RUN 1 +#define DSP_TASK_STATE_YIELD 2 +#define DSP_TASK_STATE_DONE 3 + +#define DSPGetTaskState(t) (t->state) // u32 +#define DSPGetTaskPriority(t) (t->priority) // u32 +#define DSPSetTaskPriority(t, x) (t->priority |= x) // x should be u32 + +//////////////////////////////////////////// + +////////////// DSP FUNCTIONS /////////////// +// Private functions. +void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next); +void __DSP_boot_task(DSPTaskInfo* task); +void __DSP_remove_task(DSPTaskInfo* task); +void __DSP_insert_task(DSPTaskInfo* task); +void __DSP_debug_printf(const char* format, ...); + +// Basic DSP functions. +void DSPInit(); +void DSPAssertInt(); +void DSPSendMailToDSP(u32 mail); +u32 DSPReadMailFromDSP(); +u32 DSPCheckMailToDSP(); +u32 DSPCheckMailFromDSP(); + +// Used/defined in JSystem. +DSPTaskInfo* DSPAddTask(DSPTaskInfo* task); +void __DSPHandler(__OSInterrupt interrupt, OSContext* context); + +// Unused/inlined in P2. +void __DSP_add_task(DSPTaskInfo* task); +void DSPHalt(); +void DSPReset(); + +//////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/dvd.h b/dolphin sdk not yet linked/include FROM PIKMIN2/dvd.h new file mode 100644 index 0000000..66bf9dc --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/dvd.h @@ -0,0 +1,204 @@ +#ifndef _DOLPHIN_DVD_H +#define _DOLPHIN_DVD_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////////// DVD TYPES /////////// +typedef struct DVDCommandBlock DVDCommandBlock; +typedef struct DVDFileInfo DVDFileInfo; + +// Callback function types. +typedef void (*DVDCallback)(s32 result, DVDFileInfo* fileInfo); +typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock* block); +typedef void (*DVDLowCallback)(u32 intType); +typedef void (*DVDDoneReadCallback)(s32, DVDFileInfo*); +typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, DVDLowCallback callback); + +typedef struct DVDDriveInfo { + u16 revisionLevel; // _00 + u16 deviceCode; // _02 + u32 releaseDate; // _04 + u8 padding[24]; // _08 +} DVDDriveInfo; + +// Struct for DVD information (size 0x20) +typedef struct DVDDiskID { + char gameName[4]; // _00 + char company[2]; // _04 + u8 diskNumber; // _06 + u8 gameVersion; // _07 + u8 streaming; // _08 + u8 streamBufSize; // _09, default = 0 + u8 padding[22]; // _0A, all 0s +} DVDDiskID; + +// Struct for command information (size 0x30). +struct DVDCommandBlock { + DVDCommandBlock* next; // _00 + DVDCommandBlock* prev; // _04 + u32 command; // _08 + s32 state; // _0C + u32 offset; // _10 + u32 length; // _14 + void* addr; // _18 + u32 currTransferSize; // _1C + u32 transferredSize; // _20 + DVDDiskID* id; // _24 + DVDCBCallback callback; // _28 + void* userData; // _2C +}; + +// Struct for file information (size 0x3C). +// NB: we had this as DVDPlayer previously. +struct DVDFileInfo { + DVDCommandBlock cBlock; // _00 + u32 startAddr; // _30 + u32 length; // _34 + DVDCallback callback; // _38 +}; + +// Struct for directory information (size 0xC). +typedef struct DVDDir { + u32 entryNum; // _00 + u32 location; // _04 + u32 next; // _08 +} DVDDir; + +// Struct for directory entries (size 0xC). +typedef struct DVDDirEntry { + u32 entryNum; // _00 + BOOL isDir; // _04 + char* name; // _08 +} DVDDirEntry; + +// Struct for handing queues. +typedef struct DVDQueue DVDQueue; + +struct DVDQueue { + DVDQueue* mHead; // _00 + DVDQueue* mTail; // _04 +}; + +// DVD Boot information instructions. +// Struct 1. +typedef struct DVDBB1 { + u32 appLoaderLength; // _00 + void* appLoaderFunc1; // _04 + void* appLoaderFunc2; // _08 + void* appLoaderFunc3; // _0C +} DVDBB1; + +// Struct 2. +typedef struct DVDBB2 { + u32 bootFilePosition; // _00 + u32 FSTPosition; // _04 + u32 FSTLength; // _08 + u32 FSTMaxLength; // _0C + void* FSTAddress; // _10 + u32 userPosition; // _14 + u32 userLength; // _18 + u32 reserved_1C; // _1C +} DVDBB2; + +////////////////////////////////// + +///////// DVD FUNCTIONS ////////// +// Basic DVD functions. +void DVDInit(); +BOOL DVDOpen(char* filename, DVDFileInfo* fileInfo); +BOOL DVDFastOpen(s32 entryNum, DVDFileInfo* fileInfo); +s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio); +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 DVDClose(DVDFileInfo* fileInfo); + +void DVDResume(); +void DVDReset(); + +BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDCancel(DVDCommandBlock* block); + +s32 DVDChangeDisk(DVDCommandBlock* block, DVDDiskID* id); +BOOL DVDChangeDiskAsync(DVDCommandBlock* block, DVDDiskID* id, DVDCBCallback callback); + +// Status functions. +s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block); +s32 DVDGetDriveStatus(); +BOOL DVDSetAutoInvalidation(BOOL doAutoInval); +void* DVDGetFSTLocation(); + +// DVD Dir functions. +BOOL DVDOpenDir(char* dirName, DVDDir* dir); +BOOL DVDReadDir(DVDDir* dir, DVDDirEntry* dirEntry); +BOOL DVDCloseDir(DVDDir* dir); +BOOL DVDGetCurrentDir(char* path, u32 maxLength); +BOOL DVDChangeDir(char* dirName); +s32 DVDConvertPathToEntrynum(char* path); + +// Other disk functions. +s32 DVDGetTransferredSize(DVDFileInfo* fileInfo); +DVDDiskID* DVDGetCurrentDiskID(); +BOOL DVDCompareDiskID(DVDDiskID* id1, DVDDiskID* id2); +DVDLowCallback DVDLowClearCallback(); + +BOOL DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback); + +BOOL DVDCheckDisk(); + +// Unused/inlined in P2. +void DVDPause(); +s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio); +BOOL DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio); +s32 DVDGetFileInfoStatus(DVDFileInfo* fileInfo); +BOOL DVDFastOpenDir(s32 entryNum, DVDDir* dir); +BOOL DVDCancelAllAsync(DVDCBCallback callback); +s32 DVDCancelAll(); +void DVDDumpWaitingQueue(); + +////////////////////////////////// + +////// USEFUL DVD DEFINES //////// +// Macro for reading. +#define DVDReadAsync(fileInfo, addr, length, offset, callback) DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2) + +// Minimum transfer size. +#define DVD_MIN_TRANSFER_SIZE 32 + +// DVD states. +#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 + +// File info states. +#define DVD_FILEINFO_READY 0 +#define DVD_FILEINFO_BUSY 1 + +// DVD results. +#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 0 + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/exi.h b/dolphin sdk not yet linked/include FROM PIKMIN2/exi.h new file mode 100644 index 0000000..b94c16f --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/exi.h @@ -0,0 +1,79 @@ +#ifndef _DOLPHIN_EXI_H +#define _DOLPHIN_EXI_H + +#include "types.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////////// EXI DEFINES ////////// +// Useful numbers. +#define EXI_TX 0x800400u +#define EXI_MAGIC 0xa5ff005a +#define EXI_MAX_DEV 3 +#define EXI_MAX_CHAN 3 +#define EXI_REG_MAX 5 + +// Useful macros. +#define EXI_0CR(tstart, dma, rw, tlen) ((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4)) + +#define EXIREG(chan, idx) (__EXIRegs[((chan) * EXI_REG_MAX) + (idx)]) + +#define EXI_CPR_CS(x) ((1u << (x)) << 7) +#define EXI_CPR_CLK(x) ((x) << 4) + +s32 __EXIProbeStartTime[2] AT_ADDRESS(OS_BASE_CACHED | 0x30C0); + +////////////////////////////////// + +/////////// EXI STRUCTS ////////// +// Struct for handling expansion information (size 0x40). +typedef struct EXIControl { + EXICallback exiCallback; // _00 + EXICallback tcCallback; // _04 + EXICallback extCallback; // _08 + vu32 state; // _0C + int immLen; // _10 + u8* immBuf; // _14 + u32 dev; // _18 + u32 id; // _1C + s32 idTime; // _20 + int items; // _24 + struct { + u32 dev; + EXICallback callback; + } queue[EXI_MAX_DEV]; // _28 +} EXIControl; + +////////////////////////////////// + +////////// EXI FUNCTIONS ///////// +void EXIInit(); + +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 EXIClearInterrupts(s32 channel, BOOL clearExiBit, BOOL clearTcBit, BOOL clearExtBit); +EXICallback EXISetExiCallback(s32 channel, EXICallback callback); +BOOL EXIAttach(s32 channel, EXICallback callback); +BOOL EXIDetach(s32 channel); +BOOL EXISelect(s32 channel, u32 device, u32 frequency); +BOOL EXIDeselect(s32 channel); + +void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context); +BOOL EXILock(s32 channel, u32 device, EXICallback callback); +BOOL EXIUnlock(s32 channel); +u32 EXIGetState(s32 channel); +s32 EXIGetID(s32 channel, u32 device, u32* id); + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/gba.h b/dolphin sdk not yet linked/include FROM PIKMIN2/gba.h new file mode 100644 index 0000000..601fa8f --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/gba.h @@ -0,0 +1,101 @@ +#ifndef _DOLPHIN_GBA_H +#define _DOLPHIN_GBA_H + +#include "Dolphin/os.h" +#include "Dolphin/db.h" +#include "Dolphin/dsp.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////////// GBA TYPES //////////// + +typedef void (*GBASyncCallback)(s32 chan, int ret); +typedef void (*GBAProcHandler)(s32 chan); + +// Struct for SecParam (size 0x40). +typedef struct GBASecParam { + u8 readbuf[4]; // _00 + int paletteColor; // _04 + int paletteSpeed; // _08 + int length; // _0C + u32* output; // _10 + u8 _pad0[0xC]; // _14 + u32 keyA; // _20 + int keyB; // _24 + u8 _pad1[0x18]; // _28 +} GBASecParam; + +// Struct for GBA boot information (size 0x68). +typedef struct GBABootInfo { + int paletteColor; // _00 + int paletteSpeed; // _04 + u8* program; // _08 + int length; // _0C + u8* status; // _10 + GBASyncCallback callback; // _14 + u8 readbuf[4]; // _18 + u8 writebuf[4]; // _1C + int i; // _20 + OSTick start; // _24 + OSTime begin; // _28 + int firstXfer; // _30 + int curOffset; // _34 + u32 crc; // _38 + u32 dummyWord[7]; // _3C + u32 keyA; // _58 + int keyB; // _5C + u32 initialCode; // _60 + int realLength; // _64 +} GBABootInfo; + +// Struct for main GBA information (size 0x100). +typedef struct GBAControl { + u8 output[5]; // _00 + u8 input[5]; // _05 + int outputBytes; // _0C + int inputBytes; // _10 + u8* status; // _14 + u8* ptr; // _18 + GBASyncCallback callback; // _1C + int ret; // _20 + OSThreadQueue threadQueue; // _24 + OSTime delay; // _30 + GBAProcHandler proc; // _38 + GBABootInfo bootInfo; // _40 + DSPTaskInfo task; // _A8 + GBASecParam* param; // _F8 +} GBAControl; + +////////////////////////////////// + +///////// GBA FUNCTIONS ////////// +void GBAInit(); +BOOL __GBATransfer(s32 portIndex, u32, u32, GBAProcHandler); +int __GBASync(s32 portIndex); +void __GBASyncCallback(s32 portIndex, int); +BOOL OnReset(); +void ShortCommandProc(s32 portIndex); +void ReadProc(s32 portIndex); +int GBAReset(s32 portIndex, u8* p2); +int GBAGetStatus(s32 portIndex, u8* p2); +int GBARead(s32 portIndex, u8* p2, u8* p3); +int GBAWrite(s32 portIndex, u8* p2, u8* p3); + +static inline GBAProcHandler getGBAHandler(GBAControl* gba) { return gba->proc; } + +////////////////////////////////// + +//////// GBA DECLARATIONS //////// + +extern GBAControl __GBA[4]; +extern BOOL __GBAReset; + +////////////////////////////////// + +#ifdef __cplusplus +} +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/gd.h b/dolphin sdk not yet linked/include FROM PIKMIN2/gd.h new file mode 100644 index 0000000..c9f2998 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/gd.h @@ -0,0 +1,109 @@ +#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* data; // _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->data++ = data; } + +static inline void __GDCheckOverflowed(size_t size) +{ + if (__GDCurrentDL->data + 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]); +} + +// check if data we're about to add will take us outside data region +static inline void GDOverflowCheck(u32 len) +{ + if (__GDCurrentDL->data + len > __GDCurrentDL->end) { + GDOverflowed(); + } +} + +// get current data pointer +static inline u8* GDGetCurrPointer() { return __GDCurrentDL->data; } + +// how far from the start is the current data pointer? +static inline s32 GDGetCurrOffset() { return __GDCurrentDL->data - __GDCurrentDL->begin; } + +// track to set offset +static inline void GDSetCurrOffset(s32 offs) { __GDCurrentDL->data = __GDCurrentDL->begin + offs; } + +// forward a set distance +static inline void GDAdvCurrOffset(s32 distance) { __GDCurrentDL->data += distance; } + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/gx.h b/dolphin sdk not yet linked/include FROM PIKMIN2/gx.h new file mode 100644 index 0000000..2622eb4 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/gx.h @@ -0,0 +1,31 @@ +#ifndef _DOLPHIN_GX_H +#define _DOLPHIN_GX_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/vi.h" +#include "Dolphin/mtx.h" +#include "Dolphin/GX/GXEnum.h" +#include "Dolphin/GX/GXTypes.h" +#include "Dolphin/GX/GXBump.h" +#include "Dolphin/GX/GXLight.h" +#include "Dolphin/GX/GXFrameBuffer.h" +#include "Dolphin/GX/GXPerf.h" +#include "Dolphin/GX/GXPixel.h" +#include "Dolphin/GX/GXTev.h" +#include "Dolphin/GX/GXTexture.h" +#include "Dolphin/GX/GXGeometry.h" +#include "Dolphin/GX/GXTransform.h" +#include "Dolphin/GX/GXMisc.h" +#include "Dolphin/GX/GXData.h" +#include "Dolphin/GX/GXHardware.h" + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/hw_regs.h b/dolphin sdk not yet linked/include FROM PIKMIN2/hw_regs.h new file mode 100644 index 0000000..bea349c --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/hw_regs.h @@ -0,0 +1,243 @@ +#ifndef _DOLPHIN_HW_REGS_H +#define _DOLPHIN_HW_REGS_H + +#include "types.h" +#include "Dolphin/OS/OSUtil.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#define HW_REG(reg, type) *(volatile type*)(u32)(reg) // generic HW_REG macro (please do not use this) + +/////// HARDWARE REGISTERS /////// +// Video Interface registers. +vu16 __VIRegs[59] AT_ADDRESS(0xCC002000); + +// offsets for __VIRegs[i] +#define VI_VERT_TIMING (0) +#define VI_DISP_CONFIG (1) +#define VI_HORIZ_TIMING_0L (2) +#define VI_HORIZ_TIMING_0U (3) +#define VI_HORIZ_TIMING_1L (4) +#define VI_HORIZ_TIMING_1U (5) +#define VI_VERT_TIMING_ODD (6) +#define VI_VERT_TIMING_ODD_U (7) +#define VI_VERT_TIMING_EVEN (8) +#define VI_VERT_TIMING_EVEN_U (9) + +#define VI_BBI_ODD (10) // burst blanking interval +#define VI_BBI_ODD_U (11) // burst blanking interval +#define VI_BBI_EVEN (12) // burst blanking interval +#define VI_BBI_EVEN_U (13) // burst blanking interval + +#define VI_TOP_FIELD_BASE_LEFT (14) // top in 2d, top of left pic in 3d +#define VI_TOP_FIELD_BASE_LEFT_U (15) // top in 2d, top of left pic in 3d + +#define VI_TOP_FIELD_BASE_RIGHT (16) // top of right pic in 3d +#define VI_TOP_FIELD_BASE_RIGHT_U (17) // top of right pic in 3d + +#define VI_BTTM_FIELD_BASE_LEFT (18) // bottom in 2d, bottom of left pic in 3d +#define VI_BTTM_FIELD_BASE_LEFT_U (19) // bottom in 2d, bottom of left pic in 3d + +#define VI_BTTM_FIELD_BASE_RIGHT (20) // bottom of right pic in 3d +#define VI_BTTM_FIELD_BASE_RIGHT_U (21) // bottom of right pic in 3d + +#define VI_VERT_COUNT (22) // vertical display position +#define VI_HORIZ_COUNT (23) // horizontal display position + +#define VI_DISP_INT_0 (24) // display interrupt 0L +#define VI_DISP_INT_0U (25) // display interrupt 0U +#define VI_DISP_INT_1 (26) // display interrupt 1L +#define VI_DISP_INT_1U (27) // display interrupt 1U +#define VI_DISP_INT_2 (28) // display interrupt 2L +#define VI_DISP_INT_2U (29) // display interrupt 2U +#define VI_DISP_INT_3 (30) // display interrupt 3L +#define VI_DISP_INT_3U (31) // display interrupt 3U + +#define VI_HSW (36) // horizontal scaling width +#define VI_HSR (37) // horizontal scaling register + +#define VI_FCT_0 (38) // filter coefficient table 0L +#define VI_FCT_0U (39) // filter coefficient table 0U +#define VI_FCT_1 (40) // filter coefficient table 1L +#define VI_FCT_1U (41) // filter coefficient table 1U +#define VI_FCT_2 (42) // filter coefficient table 2L +#define VI_FCT_2U (43) // filter coefficient table 2U +#define VI_FCT_3 (44) // filter coefficient table 3L +#define VI_FCT_3U (45) // filter coefficient table 3U +#define VI_FCT_4 (46) // filter coefficient table 4L +#define VI_FCT_4U (47) // filter coefficient table 4U +#define VI_FCT_5 (48) // filter coefficient table 5L +#define VI_FCT_5U (49) // filter coefficient table 5U +#define VI_FCT_6 (50) // filter coefficient table 6L +#define VI_FCT_6U (51) // filter coefficient table 6U + +#define VI_CLOCK_SEL (54) // clock select +#define VI_DTV_STAT (55) // DTV status + +#define VI_WIDTH (56) + +// Processor Interface registers. +vu32 __PIRegs[12] AT_ADDRESS(0xCC003000); + +// 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) + +// Memory Interface registers. +vu16 __MEMRegs[64] AT_ADDRESS(0xCC004000); + +// 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 + +// Digital Signal Processor registers (for audio mixing). +vu16 __DSPRegs[32] AT_ADDRESS(0xCC005000); + +// offsets for __DSPRegs[i] +#define DSP_MAILBOX_IN_HI (0) +#define DSP_MAILBOX_IN_LO (1) +#define DSP_MAILBOX_OUT_HI (2) +#define DSP_MAILBOX_OUT_LO (3) +#define DSP_CONTROL_STATUS (5) + +#define DSP_ARAM_SIZE (9) +#define DSP_ARAM_MODE (11) +#define DSP_ARAM_REFRESH (13) +#define DSP_ARAM_DMA_MM_HI (16) // Main mem address +#define DSP_ARAM_DMA_MM_LO (17) +#define DSP_ARAM_DMA_ARAM_HI (18) // ARAM address +#define DSP_ARAM_DMA_ARAM_LO (19) +#define DSP_ARAM_DMA_SIZE_HI (20) // DMA buffer size +#define DSP_ARAM_DMA_SIZE_LO (21) + +#define DSP_DMA_START_HI (24) // DMA start address +#define DSP_DMA_START_LO (25) +#define DSP_DMA_CONTROL_LEN (27) +#define DSP_DMA_BYTES_LEFT (29) + +#define DSP_DMA_START_FLAG (0x8000) // set to start DSP + +// DVD Interface registers. +vu32 __DIRegs[16] AT_ADDRESS(0xCC006000); + +// 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) + +// Serial Interface registers. +vu32 __SIRegs[64] AT_ADDRESS(0xCC006400); + +// 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) + +// Expansion/External Interface registers. +vu32 __EXIRegs[16] AT_ADDRESS(0xCC006800); + +// 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 + +// Audio Streaming Interface registers. +vu32 __AIRegs[8] AT_ADDRESS(0xCC006C00); + +// 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 // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/mtx.h b/dolphin sdk not yet linked/include FROM PIKMIN2/mtx.h new file mode 100644 index 0000000..684a3d5 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/mtx.h @@ -0,0 +1,85 @@ +#ifndef _DOLPHIN_MTX_H +#define _DOLPHIN_MTX_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/vec.h" + +/////////////// TYPE DEFINES /////////////// +#define MTXDegToRad(a) ((a) * 0.01745329252f) + +typedef f32 Mtx[3][4]; +typedef f32 Mtx23[2][3]; +typedef f32 Mtx33[3][3]; +typedef f32 Mtx44[4][4]; +typedef f32 (*MtxP)[4]; +typedef f32 (*Mtx3P)[3]; +typedef const f32 (*CMtxP)[4]; // Change name later? +typedef f32 PSQuaternion[4]; + +typedef struct Quaternion { + f32 x, y, z, w; +} Quaternion; + +//////////////////////////////////////////// + +////// PAIRED SINGLE MATRIX FUNCTIONS ////// +void PSMTXIdentity(Mtx mtx); +void PSMTXCopy(const Mtx src, Mtx dest); +void PSMTXConcat(const Mtx A, const Mtx B, Mtx concat); + +void PSMTXTranspose(const Mtx src, Mtx xPose); +u32 PSMTXInverse(const Mtx src, Mtx inv); + +void __PSMTXRotAxisRadInternal(Mtx mtx, const Vec* axis, f32 sinA, f32 cosA); +void PSMTXRotRad(Mtx mtx, char axis, f32 angle); +void PSMTXRotTrig(Mtx mtx, char axis, f32 sinA, f32 cosA); +void PSMTXRotAxisRad(Mtx mtx, const Vec* axis, f32 angle); + +void PSMTXTrans(Mtx mtx, f32 xT, f32 yT, f32 zT); +void PSMTXTransApply(const Mtx src, Mtx dest, f32 xT, f32 yT, f32 zT); + +void PSMTXScale(Mtx mtx, f32 xS, f32 yS, f32 zS); +void PSMTXScaleApply(const Mtx src, Mtx dest, f32 xS, f32 yS, f32 zS); +void PSMTXQuat(Mtx mtx, const PSQuaternion* quat); + +//////////////////////////////////////////// + +//// PAIRED SINGLE MATRIX VEC FUNCTIONS //// +void PSMTXMultVec(const Mtx, const Vec*, Vec*); +void PSMTXMultVecSR(const Mtx, const Vec*, Vec*); +void PSMTXMultVecArraySR(const Mtx, f32*, f32*, f32*); + +//////////////////////////////////////////// + +/////////// MATRIX44 FUNCTIONS //////////// +void PSMTX44Copy(Mtx44 src, Mtx44 dest); +void C_MTXPerspective(Mtx44 mtx, f32 fovY, f32 aspect, f32 n, f32 f); +void C_MTXOrtho(Mtx44 mtx, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f); +//////////////////////////////////////////// + +///////// CODED C MATRIX FUNCTIONS ///////// +void C_MTXLookAt(Mtx, const Vec*, const Vec*, const Vec*); +void C_MTXLightPerspective(Mtx mtx, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, f32 transT); +void C_MTXLightOrtho(Mtx mtx, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, f32 transT); +//////////////////////////////////////////// + +////////////// MATRIX INLINES ////////////// +static inline void MTXSetPosition(Mtx mtx, const Vec* pos) +{ + mtx[0][3] = pos->x; + mtx[1][3] = pos->y; + mtx[2][3] = pos->z; +} + +//////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/os.h b/dolphin sdk not yet linked/include FROM PIKMIN2/os.h new file mode 100644 index 0000000..66ff780 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/os.h @@ -0,0 +1,273 @@ +#ifndef _DOLPHIN_OS_H +#define _DOLPHIN_OS_H + +#include "types.h" +#include "Dolphin/PPCArch.h" +#include "Dolphin/dvd.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "Dolphin/OS/OSUtil.h" +#include "Dolphin/OS/OSAlarm.h" +#include "Dolphin/OS/OSAlloc.h" +#include "Dolphin/OS/OSBootInfo.h" +#include "Dolphin/OS/OSCache.h" +#include "Dolphin/OS/OSContext.h" +#include "Dolphin/OS/OSError.h" +#include "Dolphin/OS/OSException.h" +#include "Dolphin/OS/OSExpansion.h" +#include "Dolphin/OS/OSFastCast.h" +#include "Dolphin/OS/OSFont.h" +#include "Dolphin/OS/OSInterrupt.h" +#include "Dolphin/OS/OSMemory.h" +#include "Dolphin/OS/OSMessage.h" +#include "Dolphin/OS/OSModule.h" +#include "Dolphin/OS/OSMutex.h" +#include "Dolphin/OS/OSReset.h" +#include "Dolphin/OS/OSSerial.h" +#include "Dolphin/OS/OSThread.h" + +///////// OS FUNCTIONS /////////// +// Initialisers. +extern void __OSPSInit(); +extern void __OSFPRInit(); +extern void __OSCacheInit(); +extern void __OSContextInit(); +extern void __OSInterruptInit(); +extern void __OSInitSystemCall(); +extern void __OSModuleInit(); +extern void __OSInitAudioSystem(); +extern void __OSStopAudioSystem(); +extern void __OSInitMemoryProtection(); +extern void __OSInitAlarm(); + +void OSInit(); + +// OS logging and reporting. +void OSReport(const char* message, ...); +void OSPanic(const char* file, int line, const char* message, ...); + +#define OSError(...) OSPanic(__FILE__, __LINE__, __VA_ARGS__) +#ifndef MATCHING +#define OSErrorLine(line, ...) OSError(__VA_ARGS__) +#else +#define OSErrorLine(line, ...) OSPanic(__FILE__, line, __VA_ARGS__) +#endif + +// Other OS functions. +void OSRegisterVersion(const char*); +#define OS_CONSOLE_RETAIL4 0x00000004 +#define OS_CONSOLE_RETAIL3 0x00000003 +#define OS_CONSOLE_RETAIL2 0x00000002 +#define OS_CONSOLE_RETAIL1 0x00000001 +#define OS_CONSOLE_RETAIL 0x00000000 +#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_DEVELOPMENT 0x10000000 +#define OS_CONSOLE_DEVKIT 0x10000000 +#define OS_CONSOLE_TDEVKIT 0x20000000 + +u32 OSGetConsoleType(); + +#define OS_SOUND_MODE_MONO 0u +#define OS_SOUND_MODE_STEREO 1u + +u32 OSGetSoundMode(); +void OSSetSoundMode(u32 mode); + +#define OS_PROGRESSIVE_MODE_OFF 0u +#define OS_PROGRESSIVE_MODE_ON 1u + +u32 OSGetProgressiveMode(); +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 OSSetLanguage(u8 language); + +#define OS_EURGB60_OFF 0u +#define OS_EURGB60_ON 1u + +u32 OSGetEuRgb60Mode(); +void OSSetEuRgb60Mode(u32 on); + +// Arena functions. +extern void* __OSArenaHi; + +void* OSGetArenaHi(void); +void* OSGetArenaLo(void); +void OSSetArenaHi(void* addr); +void OSSetArenaLo(void* addr); + +// targsupp +extern u32 TRKAccessFile(u32, u32, u32*, u8*); +extern u32 TRKOpenFile(u32, u32, u32*, u8*); +extern u32 TRKCloseFile(u32, u32); +extern u32 TRKPositionFile(u32, u32, u32*, u8*); + +#define OS_SYS_CALL_HANDLER ((void*)0x80000C00) +#define OS_HANDLER_SLOT_SIZE (0x100) + +void __OSSystemCallVectorStart(); +void __OSSystemCallVectorEnd(); + +void OSFillFPUContext(OSContext*); +extern u32 __OSFpscrEnableBits; /** TODO: find a wrapper for this. Symbol is defined in OSError.c. */ + +u16 __OSWirelessPadFixMode AT_ADDRESS(OS_BASE_CACHED | 0x30E0); +u8 GameChoice AT_ADDRESS(OS_BASE_CACHED | 0x30E3); + +volatile int __OSTVMode AT_ADDRESS(OS_BASE_CACHED | 0xCC); + +// u32 GameCode : 0x80000000; +// u32 FSTLocationInRam : 0x80000038; + +////////////////////////////////// + +///////// OS RTC TYPES /////////// +// Sram function type. +typedef void (*SramCallback)(void); + +// Struct for static RAM (size 0x14). +typedef struct OSSram { + u16 checkSum; // _00 + u16 checkSumInv; // _02 + u32 ead0; // _04 + u32 ead1; // _08 + u32 counterBias; // _0C + s8 displayOffsetH; // _10 + u8 ntd; // _11 + u8 language; // _12 + u8 flags; // _13 +} OSSram; + +// Struct for expanded/external static RAM (size 0x2C). +typedef struct OSSramEx { + u8 flashID[2][12]; // _00 + u32 wirelessKeyboardID; // _18 + u16 wirelessPadID[4]; // _1C + u8 dvdErrorCode; // _24 + u8 reserved_25; // _25 + u8 flashIDCheckSum[2]; // _26 + u16 gbs; // _28 + u8 reserved_2A[2]; // _2A +} OSSramEx; + +// Struct for controlling static RAM (for OSRtc.c). +typedef struct SramControlBlock { + u8 sram[0x40]; // _00 + u32 offset; // _40 + BOOL enabled; // _44 + BOOL locked; // _48 + BOOL sync; // _4C + SramCallback callback; // _50 +} SramControlBlock; + +// SRAM functions. +OSSram* __OSLockSram(); +OSSramEx* __OSLockSramEx(); +BOOL __OSUnlockSram(BOOL commit); +BOOL __OSUnlockSramEx(BOOL commit); +void OSSetWirelessID(s32 channel, u16 id); +u16 OSGetWirelessID(s32 channel); +void OSSetGbsMode(u16 mode); +u16 OSGetGbsMode(); + +// RTC defines. +#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 + +// extern things. +extern OSThreadQueue __DVDThreadQueue; +extern u8 _stack_addr[]; +extern u8 _stack_end[]; +extern BOOL __OSInIPL; + +////////////////////////////////// + +#ifdef _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) (void)((exp) || (OSPanic(__FILE__, __LINE__, "Failed assertion " #exp), 0)) +#endif + +#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 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 + +#ifndef ASSERTMSG2 +#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)) +#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 + +#endif // _DEBUG + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/pad.h b/dolphin sdk not yet linked/include FROM PIKMIN2/pad.h new file mode 100644 index 0000000..0620857 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/pad.h @@ -0,0 +1,112 @@ +#ifndef _DOLPHIN_PAD_H +#define _DOLPHIN_PAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "types.h" +#include "Dolphin/os.h" + +typedef struct PADStatus { + u16 button; // _00, Or-ed PAD_BUTTON_* bits + s8 stickX; // _02, -128 <= stickX <= 127 + s8 stickY; // _03, -128 <= stickY <= 127 + s8 substickX; // _04, -128 <= substickX <= 127 + s8 substickY; // _05, -128 <= substickY <= 127 + u8 triggerLeft; // _06, 0 <= triggerLeft <= 255 + u8 triggerRight; // _07, 0 <= triggerRight <= 255 + u8 analogA; // _08, 0 <= analogA <= 255 + u8 analogB; // _09, 0 <= analogB <= 255 + s8 err; // _0A, one of PAD_ERR_* number +} PADStatus; + +#define PAD_MAX_CONTROLLERS 4 + +#define PAD_BUTTON_LEFT 0x0001 +#define PAD_BUTTON_RIGHT 0x0002 +#define PAD_BUTTON_DOWN 0x0004 +#define PAD_BUTTON_UP 0x0008 +#define PAD_TRIGGER_Z 0x0010 +#define PAD_TRIGGER_R 0x0020 +#define PAD_TRIGGER_L 0x0040 +#define PAD_BUTTON_A 0x0100 +#define PAD_BUTTON_B 0x0200 +#define PAD_BUTTON_X 0x0400 +#define PAD_BUTTON_Y 0x0800 +#define PAD_BUTTON_MENU 0x1000 +#define PAD_BUTTON_START 0x1000 + +#define PAD_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) + +#define PAD_SPEC_0 0 +#define PAD_SPEC_1 1 +#define PAD_SPEC_2 2 +#define PAD_SPEC_3 3 +#define PAD_SPEC_4 4 +#define PAD_SPEC_5 5 + +#define PAD_CHAN0 0 +#define PAD_CHAN1 1 +#define PAD_CHAN2 2 +#define PAD_CHAN3 3 +#define PAD_CHANMAX 4 + +#define PAD_CHAN0_BIT 0x80000000 +#define PAD_CHAN1_BIT 0x40000000 +#define PAD_CHAN2_BIT 0x20000000 +#define PAD_CHAN3_BIT 0x10000000 + +#define PAD_ERR_NONE 0 +#define PAD_ERR_NO_CONTROLLER -1 +#define PAD_ERR_NOT_READY -2 +#define PAD_ERR_TRANSFER -3 + +#define PAD_MOTOR_STOP 0 +#define PAD_MOTOR_RUMBLE 1 +#define PAD_MOTOR_STOP_HARD 2 + +// PADSetAnalogMode() param +#define PAD_MODE_0 0 +#define PAD_MODE_1 1 +#define PAD_MODE_2 2 +#define PAD_MODE_3 3 +#define PAD_MODE_4 4 +#define PAD_MODE_5 5 +#define PAD_MODE_6 6 +#define PAD_MODE_7 7 + +#define PADButtonDown(buttonLast, button) ((u16)(((buttonLast) ^ (button)) & (button))) + +#define PADButtonUp(buttonLast, button) ((u16)(((buttonLast) ^ (button)) & (buttonLast))) + +#define PADStartMotor(chan) PADControlMotor((chan), PAD_MOTOR_RUMBLE) +#define PADStopMotorHard(chan) PADControlMotor((chan), PAD_MOTOR_STOP_HARD) +#define PADStopMotor(chan) PADControlMotor((chan), PAD_MOTOR_STOP) + +BOOL PADInit(void); +BOOL PADReset(u32 mask); +u32 PADRead(PADStatus* status); +void PADSetSamplingRate(u32 msec); +void PADClamp(PADStatus* status); +void PADClampCircle(PADStatus* status); +void PADControlAllMotors(u32* command); +void PADControlMotor(s32 chan, u32 command); +BOOL PADRecalibrate(u32 mask); +BOOL PADSync(void); +void PADSetAnalogMode(u32 mode); +void PADSetSpec(u32 spec); + +typedef void (*PADSamplingCallback)(void); + +PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback); + +extern u32 __PADFixBits; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/print.h b/dolphin sdk not yet linked/include FROM PIKMIN2/print.h new file mode 100644 index 0000000..8def102 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/print.h @@ -0,0 +1,17 @@ +#ifndef _DOLPHIN_PRINT_H +#define _DOLPHIN_PRINT_H + +#include "stdio.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#define DEFINE__PRINT(unit) \ + inline static void _Print(char*, ...) { printf(unit); } + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/rand.h b/dolphin sdk not yet linked/include FROM PIKMIN2/rand.h new file mode 100644 index 0000000..a1e01e3 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/rand.h @@ -0,0 +1,26 @@ +#ifndef _DOLPHIN_RAND_H +#define _DOLPHIN_RAND_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#define RAND_MAX (SHORT_FLOAT_MAX) +#define RAND_EBISAWA_MAX (32767.0f) + +inline f32 randEbisawaFloat() { return (f32)rand() / RAND_EBISAWA_MAX; } +inline f32 randFloat() { return (f32)rand() / RAND_MAX; } +inline int randInt(int multiplier) { return multiplier * randFloat(); } +inline f32 randWeightFloat(f32 range) { return (range * (f32)rand()) / RAND_MAX; } + +#define RAND_FLOAT_RANGE(origin, deviation) (origin - randFloat() * deviation) +#define RAND_FLOAT_BETWEEN(min, max) (min + randFloat() * (max - min)) + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/si.h b/dolphin sdk not yet linked/include FROM PIKMIN2/si.h new file mode 100644 index 0000000..a973feb --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/si.h @@ -0,0 +1,87 @@ +#ifndef _DOLPHIN_SI_H +#define _DOLPHIN_SI_H + +#include "types.h" +#include "Dolphin/os.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +///////////////// SI TYPES ///////////////// +// SI callback function type. +typedef void (*SICallback)(s32 chan, u32 sr, OSContext* context); +typedef void (*SITypeAndStatusCallback)(s32 chan, u32 type); + +// Struct for SI information transfer (size 0x20). +typedef struct SIPacket { + s32 chan; // _00 + void* output; // _04 + u32 outputBytes; // _08 + void* input; // _0C + u32 inputBytes; // _10 + SICallback callback; // _14 + OSTime fire; // _18 +} SIPacket; + +// Struct for 'Si' object in SIBios.c (size 0x14). +typedef struct SIControl { + s32 chan; // _00 + u32 poll; // _04 + u32 inputBytes; // _08 + void* input; // _0C + SICallback callback; // _10 +} SIControl; + +// Struct to set and store flags (size 0x4). +typedef struct SICommFlags { + 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; +} SICommFlags; + +// Union to control setting flags or overall word value (size 0x4). +typedef union SIComm { + u32 val; + SICommFlags flags; +} SIComm; + +//////////////////////////////////////////// + +/////////////// SI FUNCTIONS /////////////// +BOOL SIBusy(); +BOOL SIIsChanBusy(s32 chan); + +BOOL SIRegisterPollingHandler(__OSInterruptHandler handler); +BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler); + +void SIInit(void); +u32 SIGetStatus(s32 chan); +void SISetCommand(s32 chan, u32 command); +void SITransferCommands(void); +u32 SISetXY(u32 x, u32 y); +u32 SIEnablePolling(u32 poll); +u32 SIDisablePolling(u32 poll); +BOOL SIGetResponse(s32 chan, void* data); +BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback, OSTime delay); +u32 SIGetType(s32 chan); +u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback); +u32 SIDecodeType(u32 type); +u32 SIProbe(s32 chan); + +//////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/stl.h b/dolphin sdk not yet linked/include FROM PIKMIN2/stl.h new file mode 100644 index 0000000..b850393 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/stl.h @@ -0,0 +1,78 @@ +#ifndef _DOLPHIN_STL_H +#define _DOLPHIN_STL_H + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#ifndef size_t +typedef u32 size_t; +#endif + +DECL_SECT(".init") void* memcpy(void*, const void*, size_t); +DECL_SECT(".init") void __fill_mem(void*, int, size_t); +DECL_SECT(".init") void* memset(void*, int, size_t); + +// typedef struct __va_list_struct { +// char gpr; +// char fpr; +// char* input_arg_area; +// char* reg_save_area; +// } va_list[1]; + +// void* __va_arg(va_list, int); + +// #define va_start(ARG, VA_LIST) ((void)ARG, __builtin_va_info(&VA_LIST)) +// #define va_end(VA_LIST) ((void)VA_LIST) +// #define va_arg(VA_LIST, ARG_TYPE) (*(ARG_TYPE*)) __va_arg(VA_LIST, _var_arg_typeof(ARG_TYPE)) + +#ifdef __MWERKS__ +typedef 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, u8 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 + +/** + * @note Address: N/A + * @note Size: 0xE0 or 0xE4, depending on param. + */ +#define DEFINE__PRINT(unit) \ + inline static void _Print(char*, ...) { printf(unit); } + +int printf(const char*, ...); +int vprintf(const char*, va_list); +int sprintf(char*, char*, ...); +int snprintf(char*, size_t, const char*, ...); +int vsnprintf(char*, size_t, const char*, va_list); +int vsprintf(char* s, const char* format, va_list arg); + +void* memcpy(void* dest, const void* src, size_t n); +int memcmp(const void* a, const void* b, size_t n); +void* memset(void* str, int c, size_t n); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/vec.h b/dolphin sdk not yet linked/include FROM PIKMIN2/vec.h new file mode 100644 index 0000000..2852e53 --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/vec.h @@ -0,0 +1,42 @@ +#ifndef _DOLPHIN_VEC_H +#define _DOLPHIN_VEC_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +typedef struct Vec { + f32 x; + f32 y; + f32 z; +} Vec; + +typedef struct SVec { + s16 x; + s16 y; + s16 z; +} SVec; + +void PSVECAdd(const Vec*, const Vec*, Vec*); +void PSVECSubtract(const Vec*, const Vec*, Vec*); +void PSVECNormalize(const Vec*, Vec*); +f32 PSVECMag(const Vec*); +void PSVECCrossProduct(const Vec*, const Vec*, Vec*); + +#ifdef __cplusplus +} +#endif + +// lfs f1,0(r3) +// lfs f0,4(r3) +// fmuls f1,f1,f1 +// lfs f2,8(r3) +// fmuls f0,f0,f0 +// fmuls f2,f2,f2 +// fadds f0,f1,f0 +// fadds f1,f2,f0 +// blr + +#endif diff --git a/dolphin sdk not yet linked/include FROM PIKMIN2/vi.h b/dolphin sdk not yet linked/include FROM PIKMIN2/vi.h new file mode 100644 index 0000000..17fd07e --- /dev/null +++ b/dolphin sdk not yet linked/include FROM PIKMIN2/vi.h @@ -0,0 +1,208 @@ +#ifndef _DOLPHIN_VI_H +#define _DOLPHIN_VI_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////// VIDEO INTERFACE DEFINES ///// +// Display pixel size. +#define VI_DISPLAY_PIX_SZ (2) + +// Interlacing types +#define VI_INTERLACE (0) +#define VI_NON_INTERLACE (1) +#define VI_PROGRESSIVE (2) +#define VI_3D (3) + +// Video output formats +#define VI_NTSC (0) +#define VI_PAL (1) +#define VI_MPAL (2) +#define VI_DEBUG (3) +#define VI_DEBUG_PAL (4) +#define VI_EURGB60 (5) +#define VI_GCA (6) + +// Conversion to TVMode used in enums +#define VI_TVMODE(FMT, INT) (((FMT) << 2) + (INT)) + +// Fields +#define VI_FIELD_ABOVE (1) +#define VI_FIELD_BELOW (0) + +// Max screen dimensions +// NTSC +#define VI_MAX_WIDTH_NTSC (720) +#define VI_MAX_HEIGHT_NTSC (480) + +// PAL +#define VI_MAX_WIDTH_PAL (720) +#define VI_MAX_HEIGHT_PAL (574) + +// MPAL +#define VI_MAX_WIDTH_MPAL (720) +#define VI_MAX_HEIGHT_MPAL (480) + +// EU RGB60 (same as NTSC) +#define VI_MAX_WIDTH_EURGB60 VI_MAX_WIDTH_NTSC +#define VI_MAX_HEIGHT_EURGB60 VI_MAX_HEIGHT_NTSC + +// Conversion to padded FB width from screen width +#define VIPadFrameBufferWidth(width) ((u16)(((u16)(width) + 15) & ~15)) + +//////////////////////////////////// + +/////// VIDEO INTERFACE TYPES ////// +// Retrace callback function type. +typedef void (*VIRetraceCallback)(u32 retraceCount); + +// Position callback function type. +typedef void (*VIPositionCallback)(s16 x, s16 y); + +// TV Modes +typedef enum { + // NTSC + VI_TVMODE_NTSC_INT = VI_TVMODE(VI_NTSC, VI_INTERLACE), // 0 + VI_TVMODE_NTSC_DS = VI_TVMODE(VI_NTSC, VI_NON_INTERLACE), // 1 + VI_TVMODE_NTSC_PROG = VI_TVMODE(VI_NTSC, VI_PROGRESSIVE), // 2 + VI_TVMODE_NTSC_3D = VI_TVMODE(VI_NTSC, VI_3D), // 3 + + // PAL + VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE), // 4 + VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE), // 5 + + // MPAL + VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE), // 8 + VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE), // 9 + + // Debug + VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE), // 12 + + // Debug PAL + VI_TVMODE_DEBUG_PAL_INT = VI_TVMODE(VI_DEBUG_PAL, VI_INTERLACE), // 16 + VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE), // 17 + + // EU RGB60 + VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE), // 20 + VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE), // 21 + + // GCA + VI_TVMODE_GCA_INT = VI_TVMODE(VI_GCA, VI_INTERLACE), // 24 + VI_TVMODE_GCA_DS = VI_TVMODE(VI_GCA, VI_NON_INTERLACE), // 25 + VI_TVMODE_GCA_PROG = VI_TVMODE(VI_GCA, VI_PROGRESSIVE), // 26 +} VITVMode; + +// External frame buffer modes (single and double?) +typedef enum { + VI_XFBMODE_SF = 0, + VI_XFBMODE_DF = 1, +} 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; + +//////////////////////////////////// + +///// VIDEO INTERFACE FUNCTIONS //// +// Basic VI functions. +void VIInit(void); +void VIFlush(void); +void VIWaitForRetrace(void); + +// Configure functions. +void VIConfigure(const struct _GXRenderModeObj* obj); + +// Retrace callbacks. +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback); +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback); + +// Getters and setters +void VISetNextFrameBuffer(void* fb); +void* VIGetCurrentFrameBuffer(); + +void __VIGetCurrentPosition(s16* x, s16* y); + +void VISetBlack(BOOL isBlack); + +u32 VIGetRetraceCount(void); +u32 VIGetNextField(void); +u32 VIGetCurrentLine(void); +u32 VIGetTvFormat(void); + +u32 VIGetDTVStatus(void); + +// Unused/stripped in P2. +void VIConfigurePan(u16 panPosX, u16 panPosY, u16 panSizeX, u16 panSizeY); +void* VIGetNextFrameBuffer(); +void VISetNextRightFrameBuffer(void* fb); +void VISet3D(); // unsure on arguments + +//////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/FILE_POS.C b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/FILE_POS.C new file mode 100644 index 0000000..0513f9b --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/FILE_POS.C @@ -0,0 +1,170 @@ +#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) + +/** + * @note Address: 0x800C6BE0 + * @note Size: 0xE4 + */ +int ftell(FILE* stream) +{ + int retval; + + __begin_critical_region(stdin_access); + retval = (s32)_ftell(stream); + __end_critical_region(stdin_access); + return retval; +} + +/** + * @note Address: N/A + * @note Size: 0xAC + */ +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 = EFPOS; + 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; + } + + 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); +} + +/** + * @note Address: 0x800C6970 + * @note Size: 0x270 + */ +int _fseek(FILE* file, u32 offset, int whence) +{ + int bufferCode; + int pos; + int adjust; + u32 state; + int buffLen; + + char* ptr; + + if (file->mMode.file_kind != __disk_file || file->mState.error != 0) { + errno = EFPOS; + return -1; + } + + if (file->mState.io_state == __writing) { + if (__flush_buffer(file, nullptr) != 0) { + file->mState.error = 1; + file->mBufferLength = 0; + errno = EFPOS; + return -1; + } + } + + if (whence == SEEK_CUR) { + whence = SEEK_SET; + adjust = 0; + if ((file->mMode.file_kind != __disk_file && file->mMode.file_kind != __console_file) || file->mState.error != 0) { + errno = EFPOS; + pos = -1; + } else { + state = file->mState.io_state; + if (state == __neutral) { + pos = file->mPosition; + } else { + pos = file->mBufferPosition; + ptr = file->mBuffer; + buffLen = (file->mBufferPtr - ptr); + pos += buffLen; + if ((state >= __rereading)) { + adjust = (state - 2); + pos -= adjust; + } + + if (file->mMode.binary_io == 0) { + int i; + for (i = (buffLen - adjust); i != 0; i--) { + u8 c = *ptr; + ptr++; + if (c == 10) { + pos++; + } + } + } + } + } + offset += pos; + } + + if ((whence != SEEK_END) && (file->mMode.io_mode != 3) + && (file->mState.io_state == __reading || file->mState.io_state == __rereading)) { + if ((offset >= file->mPosition) || !(offset >= file->mBufferPosition)) { + file->mState.io_state = __neutral; + } else { + file->mBufferPtr = file->mBuffer + (offset - file->mBufferPosition); + file->mBufferLength = file->mPosition - offset; + file->mState.io_state = __reading; + } + } else { + file->mState.io_state = __neutral; + } + + if (file->mState.io_state == __neutral) { + if (file->positionFunc != nullptr && (int)file->positionFunc(file->mHandle, &offset, whence, file->ref_con)) { + file->mState.error = 1; + file->mBufferLength = 0; + errno = EFPOS; + return -1; + } else { + file->mState.eof = 0; + file->mPosition = offset; + file->mBufferLength = 0; + } + } + + return 0; +} + +/** + * @note Address: 0x800C6904 + * @note Size: 0x6C + */ +int fseek(FILE* stream, u32 offset, int whence) +{ + int code; + __begin_critical_region(stdin_access); + code = _fseek(stream, offset, whence); // 0 if successful, -1 if error + __end_critical_region(stdin_access); + return code; +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/alloc.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/alloc.c new file mode 100644 index 0000000..41110cd --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/alloc.c @@ -0,0 +1,588 @@ +#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; + u32 max_size; + u32 size; +} Block; + +typedef struct SubBlock { + u32 size; + Block* block; + struct SubBlock* prev; + struct SubBlock* next; +} SubBlock; + +struct FixSubBlock; + +typedef struct FixBlock { + struct FixBlock* prev_; + struct FixBlock* next_; + u32 client_size_; + struct FixSubBlock* start_; + u32 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 s32 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)(u32, 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; + u32 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 u32 fix_pool_sizes[] = { 4, 12, 20, 36, 52, 68 }; + +#define SubBlock_size(ths) ((ths)->size & 0xFFFFFFF8) +#define SubBlock_block(ths) ((Block*)((u32)((ths)->block) & ~0x1)) +#define Block_size(ths) ((ths)->size & 0xFFFFFFF8) +#define Block_start(ths) (*(SubBlock**)((char*)(ths) + Block_size((ths)) - sizeof(u32))) + +#define SubBlock_set_free(ths) \ + u32 this_size = SubBlock_size((ths)); \ + (ths)->size &= ~0x2; \ + *(u32*)((char*)(ths) + this_size) &= ~0x4; \ + *(u32*)((char*)(ths) + this_size - sizeof(u32)) = 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))) \ + *(u32*)((char*)(ths) + (sz) - sizeof(u32)) = (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) (*(u32*)((char*)(ptr) - sizeof(u32)) & 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 + +/** + * @note Address: N/A + * @note Size: 0x238 + */ +void Block_construct(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1E4 + */ +void Block_subBlock(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1F0 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x74 + */ +void Block_unlink(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x284 + */ +void Block_report(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x50 + */ +void SubBlock_construct(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xE0 + */ +void SubBlock_split(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +static SubBlock* SubBlock_merge_prev(SubBlock* ths, SubBlock** start) +{ + u32 prevsz; + SubBlock* p; + + if (!(ths->size & 0x04)) { + prevsz = *(u32*)((char*)ths - sizeof(u32)); + 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; +} + +/** + * @note Address: N/A + * @note Size: 0xB8 + */ +static void SubBlock_merge_next(SubBlock* pBlock, SubBlock** pStart) +{ + SubBlock* next_sub_block; + u32 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)) { + *(u32*)((char*)(pBlock) + (this_cur_size)-4) = (this_cur_size); + } + + if (!(pBlock->size & 2)) { + *(u32*)((char*)pBlock + this_cur_size) &= ~4; + } else { + *(u32*)((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; + } +} + +/** + * @note Address: N/A + * @note Size: 0x88 + */ +void SubBlock_report(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void link(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +void link_new_block(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xDC + */ +void allocate_from_var_pools(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xD8 + */ +void soft_allocate_from_var_pools(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C2770 + * @note Size: 0x294 + */ +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); + } +} + +/** + * @note Address: N/A + * @note Size: 0x128 + */ +void FixBlock_construct(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void __init_pool_obj(__mem_pool* pool_obj) { memset(pool_obj, 0, sizeof(__mem_pool_obj)); } + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +static __mem_pool* get_malloc_pool(void) +{ + static __mem_pool protopool; + static u8 init = 0; + if (!init) { + __init_pool_obj(&protopool); + init = 1; + } + + return &protopool; +} + +/** + * @note Address: N/A + * @note Size: 0x2D0 + */ +void allocate_from_fixed_pools(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C2618 + * @note Size: 0x158 + */ +void deallocate_from_fixed_pools(__mem_pool_obj* pool_obj, void* ptr, u32 size) +{ + u32 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); + } +} + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +void __report_on_pool_heap(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xE4 + */ +void __report_on_heap(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void __msize(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +void __pool_alloc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C25C0 + * @note Size: 0x58 + */ +void __pool_free(__mem_pool* pool, void* ptr) +{ + __mem_pool_obj* pool_obj; + u32 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); + } +} + +/** + * @note Address: N/A + * @note Size: 0x7B4 + */ +void __pool_realloc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void __pool_alloc_clear(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void malloc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C2550 + * @note Size: 0x70 + */ +void free(void* ptr) +{ + __begin_critical_region(malloc_pool_access); + __pool_free(get_malloc_pool(), ptr); + __end_critical_region(malloc_pool_access); +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void realloc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x88 + */ +void calloc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +void __pool_free_all(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x90 + */ +void __malloc_free_all(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/ansi_files.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/ansi_files.c new file mode 100644 index 0000000..2ddf10a --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/ansi_files.c @@ -0,0 +1,163 @@ +#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 + __console_file, // _04, file_kind + 0, // _04, binary_io + __neutral, // _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 + __console_file, // _04, file_kind + 0, // _04, binary_io + __neutral, // _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 + __console_file, // _04, file_kind + 0, // _04, binary_io + __neutral, // _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 + +/** + * @note Address: 0x800C2A74 + * @note Size: 0xA8 + */ +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); +} + +/** + * @note Address: 0x800C2A04 + * @note Size: 0x70 + */ + +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/dolphin sdk not yet linked/src/MSL_C/MSL_Common/arith.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/arith.c new file mode 100644 index 0000000..b760bf8 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/arith.c @@ -0,0 +1,180 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h" + +/** + * @note Address: 0x800C6150 + * @note Size: 0x10 + */ +int abs(int x) { return x > 0 ? x : -x; } + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +s32 labs(s32 x) +{ + // UNUSED FUNCTION + return x > 0 ? x : -x; +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +void llabs(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C60F8 + * @note Size: 0x58 + */ +div_t div(s32 __numer, s32 __denom) +{ + 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; +} + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +void ldiv(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x15C + */ +void lldiv(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x60 + */ +void __msl_add(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x60 + */ +void __msl_ladd(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xD8 + */ +void __lladd(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +void __msl_mul(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +void __msl_lmul(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x148 + */ +void __llmul(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +void __msl_div(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +void __msl_ldiv(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C4 + */ +void __lldiv(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x5C + */ +void __msl_mod(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x5C + */ +void __msl_lmod(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x198 + */ +void __llmod(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/buffer_io.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/buffer_io.c new file mode 100644 index 0000000..1bfdc07 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/buffer_io.c @@ -0,0 +1,48 @@ +#include "Dolphin/MSL_C/MSL_Common/ansi_files.h" + +/** + * @note Address: 0x800C6224 + * @note Size: 0x34 + */ +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; +} + +/** + * @note Address: 0x800C6160 + * @note Size: 0xC4 + */ +int __flush_buffer(FILE* file, size_t* length) +{ + size_t bufferLen; + int writeCode; + + bufferLen = file->mBufferPtr - file->mBuffer; + if (bufferLen) + { + file->mBufferLength = bufferLen; + 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; + } + + file->mBufferPtr = file->mBuffer; + file->mBufferLength = file->mBufferSize; + file->mBufferLength = file->mBufferLength - (file->mPosition & file->mBufferAlignment); + file->mBufferPosition = file->mPosition; + return 0; +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/ctype.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/ctype.c new file mode 100644 index 0000000..5315ceb --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/ctype.c @@ -0,0 +1,184 @@ +#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 + +u8 __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 }; + +u8 __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, +}; + +u8 __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, +}; + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// void isalnum(void) +//{ +// // UNUSED FUNCTION +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// void isalpha(void) +//{ +// // UNUSED FUNCTION +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// void iscntrl(void) +//{ +// // UNUSED FUNCTION +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// BOOL isdigit(int c) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// void isgraph(void) +//{ +// // UNUSED FUNCTION +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// BOOL islower(u8 c) +//{ +// // UNUSED FUNCTION +// return __ctype_map[c] & olowc; +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// void isprint(void) +//{ +// // UNUSED FUNCTION +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// void ispunct(void) +//{ +// // UNUSED FUNCTION +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// void isspace(void) +//{ +// // UNUSED FUNCTION +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// void isupper(void) +//{ +// // UNUSED FUNCTION +//} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +// BOOL isxdigit(u8 c) +//{ +// // UNUSED FUNCTION +// return (__ctype_map[c] & ohexd) != 0; +//} + +/** + * @note Address: 0x800C6264 + * @note Size: 0x24 + */ +WEAKFUNC int tolower(int __c) { return _tolower(__c); } + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +// int toupper(int __c) +//{ +// // UNUSED FUNCTION +// { +// if (__c == -1) { +// return 0xffffffff; +// } +// return (uint)__upper_map[__c & 0xff]; +// } +// + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +// void iswblank(void) +//{ +// // UNUSED FUNCTION +//} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/direct_io.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/direct_io.c new file mode 100644 index 0000000..4b6b809 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/direct_io.c @@ -0,0 +1,163 @@ +#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" + +// define standard C file pointer location names +#define SEEK_SET (0) +#define SEEK_CUR (1) +#define SEEK_END (2) + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void fread(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x350 + */ +void __fread(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C6594 + * @note Size: 0x7C + */ +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; +} + +/** + * @note Address: 0x800C6288 + * @note Size: 0x30C + */ +size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) +{ + u8* 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 == __closed_file) { + return 0; + } + + if (pFile->mMode.file_kind == __console_file) { + __stdio_atexit(); + } + + buff = (!pFile->mMode.binary_io || pFile->mMode.buffer_mode == 2 || pFile->mMode.buffer_mode == 1); + + if (pFile->mState.io_state == __neutral && pFile->mMode.io_mode & 2) { + if (pFile->mMode.io_mode & 4) { + if (fseek(pFile, 0, SEEK_END)) { + return 0; + } + } + + pFile->mState.io_state = __writing; + __prep_buffer(pFile); + } + + if (pFile->mState.io_state != __writing) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + return 0; + } + + cur_ptr = (u8*)pPtr; + bytes_written = 0; + + if (rem_bytes && (pFile->mBufferPtr != pFile->mBuffer || buff)) { + pFile->mBufferLength = pFile->mBufferSize - (pFile->mBufferPtr - pFile->mBuffer); + + do { + u8* 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 = (u8*)__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) { + u8* save_buf = (u8*)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/dolphin sdk not yet linked/src/MSL_C/MSL_Common/errno.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/errno.c new file mode 100644 index 0000000..afee599 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/errno.c @@ -0,0 +1,3 @@ +#include "errno.h" + +int errno; diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/extras.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/extras.c new file mode 100644 index 0000000..7f1be1f --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/extras.c @@ -0,0 +1,705 @@ +#include "types.h" +#include "ctype.h" + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void strdup(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _strdup(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void strlwr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void _strlwr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +void ultoa(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +void _ultoa(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x48 + */ +void gcvt(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x48 + */ +void _gcvt(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void heapmin(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void _heapmin(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800CFCDC + * @note Size: 0x8C + */ +int stricmp(char* str1, char* str2) +{ + s8 a_var; + s8 b_var; + + do { + a_var = *str1; + str1++; + b_var = _tolower(a_var); + + a_var = *str2; + str2++; + 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; +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void _stricmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void strnicmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _strnicmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void strupr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void _strupr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +void strdate(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +void _strdate(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void strset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _strset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +void strnset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +void _strnset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void strspnp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void _strspnp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void strncasecmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _strncasecmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void strcmpi(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void _strcmpi(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void strncmpi(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _strncmpi(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void strcasecmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void _strcasecmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void _stricoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _strncoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _strnicoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void stricoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void strncoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void strnicoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void itoa(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _itoa(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void strrev(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _strrev(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +void filelength(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +void _filelength(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C0 + */ +void chsize(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _chsize(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void wtoi(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void _wtoi(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x40 + */ +void wcslwr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +void _wcslwr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x40 + */ +void wcsupr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +void _wcsupr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void wcsicmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void _wcsicmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void wcsnicmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void _wcsnicmp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +void wcsrev(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +void _wcsrev(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void wcsset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _wcsset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void wcsnset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void _wcsnset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void wcsspnp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void _wcsspnp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +void wcsdup(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +void _wcsdup(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +void wstrrev(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +void _wstrrev(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void _wcsicoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void _wcsncoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void _wcsnicoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void wcsicoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void wcsncoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void wcsnicoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xF8 + */ +void itow(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xF8 + */ +void _itow(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/file_io.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/file_io.c new file mode 100644 index 0000000..aad49a1 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/file_io.c @@ -0,0 +1,78 @@ +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +/** + * @note Address: 0x800C6748 + * @note Size: 0x1BC + */ +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); +} + +/** + * @note Address: 0x800C6610 + * @note Size: 0x138 + */ +int fflush(FILE* file) +{ + int 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 >= __rereading) { + file->mState.io_state = __reading; + } + + if (file->mState.io_state == __reading) { + file->mBufferLength = 0; + } + + if (file->mState.io_state != __writing) { + file->mState.io_state = __neutral; + return 0; + } + + if (file->mMode.file_kind != __disk_file) { + pos = 0; + } else { + pos = ftell(file); + } + + if (__flush_buffer(file, 0) != 0) { + file->mState.error = 1; + file->mBufferLength = 0; + return -1; + } + + file->mState.io_state = __neutral; + file->mPosition = pos; + file->mBufferLength = 0; + return 0; +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/float.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/float.c new file mode 100644 index 0000000..89253ae --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/float.c @@ -0,0 +1,10 @@ +#include "types.h" + +s32 __float_nan[] = { 0x7FFFFFFF }; +s32 __float_huge[] = { 0x7F800000 }; +s32 __double_max[] = { 0x7FEFFFFF, 0xFFFFFFFF }; +s32 __double_huge[] = { 0x7FF00000, 0 }; +s32 __extended_min[] = { 0x00100000, 0 }; +s32 __extended_max[] = { 0x7FEFFFFF, 0xFFFFFFFF }; +s32 __float_max[] = { 0x7F7FFFFF }; +s32 __float_epsilon[] = { 0x34000000 }; diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/locale.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/locale.c new file mode 100644 index 0000000..7b7961b --- /dev/null +++ b/dolphin sdk not yet linked/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/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mbstring.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mbstring.c new file mode 100644 index 0000000..47b8d6b --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mbstring.c @@ -0,0 +1,252 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h" + +/** + * @note Address: N/A + * @note Size: 0x11C + */ +// void mblen(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800C6EFC + * @note Size: 0xEC + */ +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); + } +} + +/** + * @note Address: N/A + * @note Size: 0x120 + */ +// void utf8_to_unicode(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800C6DDC + * @note Size: 0x120 + */ +int mbtowc(wchar_t* pwc, const char* s, size_t n) { return mbstowcs(pwc, s, n); } + +/** + * @note Address: N/A + * @note Size: 0xA4 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0xA4 + */ +inline int wctomb(char* s, wchar_t wchar) { return (unicode_to_UTF8(s, wchar)); } + +/** + * @note Address: N/A + * @note Size: 0x188 + */ +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; +} + +/** + * @note Address: 0x800C6CC4 + * @note Size: 0x118 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +// void mbrlen(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: N/A + * @note Size: 0x188 + */ +// void mbrtowc(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: N/A + * @note Size: 0xB0 + */ +// void wcrtomb(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: N/A + * @note Size: 0x1E0 + */ +// void mbsrtowcs(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: N/A + * @note Size: 0x114 + */ +// void wcsrtombs(void) +// { +// // UNUSED FUNCTION +// } diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mem.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mem.c new file mode 100644 index 0000000..5b27f9f --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mem.c @@ -0,0 +1,113 @@ +#include "mem.h" + +// thanks, kiwi! +/** + * @note Address: 0x800C708C + * @note Size: 0xCC + */ +void* memmove(void* dst, const void* src, size_t len) +{ + u8* csrc; + u8* cdst; + + int reverse = (u32)src < (u32)dst; + + if (len >= 32) { + if (((u32)dst ^ (u32)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) { + csrc = ((u8*)src) - 1; + cdst = ((u8*)dst) - 1; + len++; + + while (--len > 0) { + *++cdst = *++csrc; + } + } else { + csrc = (u8*)src + len; + cdst = (u8*)dst + len; + len++; + + while (--len > 0) { + *--cdst = *--csrc; + } + } + } + + return dst; +} + +/** + * @note Address: 0x800C7060 + * @note Size: 0x2C + */ +void* memchr(u8* s, int c, size_t n) +{ + int n_count; + size_t char_check; + + char_check = (u8)c; + s = &s[-1]; + n_count = n + 1; + while (--n_count) { + if (*++s == char_check) { + return s; + } + } + + return 0; +} + +/** + * @note Address: 0x800C7034 + * @note Size: 0x2C + */ +u8* __memrchr(u8* s, u8 c, size_t n) +{ + int n_count; + size_t char_check; + + char_check = (u8)c; + s = &s[n]; + n_count = n + 1; + while (--n_count) { + if (*--s == char_check) { + return s; + } + } + + return 0; +} + +/** + * @note Address: 0x800C6FE8 + * @note Size: 0x4C + */ +int memcmp(const void* __s1, const void* __s2, size_t __n) +{ + const u8* val1 = ((const u8*)__s1 - 1); + const u8* val2 = ((const u8*)__s2 - 1); + size_t size = __n + 1; + + while (--size > 0) { + if (*++val1 != *++val2) { + return (val1[0]) < (val2[0]) ? -1 : 1; + } + } + + return 0; +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mem_funcs.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mem_funcs.c new file mode 100644 index 0000000..bf00b7d --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/mem_funcs.c @@ -0,0 +1,236 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h" + +/** + * @note Address: N/A + * @note Size: 0x60 + */ +void __copy_mem(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1FC + */ +void __move_mem(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C736C + * @note Size: 0xBC + */ +void __copy_longs_aligned(void* pDest, const void* pSrc, u32 len) +{ + u32 i = (-(u32)pDest) & 3; + srcCharPtr = ((u8*)pSrc) - 1; + destCharPtr = ((u8*)pDest) - 1; + + if (i != 0) { + len -= i; + + do { + *++(destCharPtr) = *++(srcCharPtr); + } while (--i); + } + + srcLongPtr = ((u32*)(srcCharPtr + 1)) - 1; + destLongPtr = ((u32*)(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 = ((u8*)(srcLongPtr + 1)) - 1; + destCharPtr = ((u8*)(destLongPtr + 1)) - 1; + + len &= 3; + + if (len != 0) { + do + *++(destCharPtr) = *++(srcCharPtr); + while (--len); + } +} + +/** + * @note Address: 0x800C72C4 + * @note Size: 0xA8 + */ +void __copy_longs_rev_aligned(void* pDest, const void* pSrc, u32 len) +{ + u32 i; + srcCharPtr = ((u8*)pSrc) + len; + destCharPtr = ((u8*)pDest) + len; + i = ((u32)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); + } +} + +/** + * @note Address: 0x800C7204 + * @note Size: 0xC0 + */ +void __copy_longs_unaligned(void* pDest, const void* pSrc, u32 len) +{ + u32 i, v1, v2; + uint src, ls, rs; + + i = (-(u32)pDest) & 3; + srcCharPtr = ((u8*)pSrc) - 1; + destCharPtr = ((u8*)pDest) - 1; + + if (i != 0) { + len -= i; + + do { + *++destCharPtr = *++srcCharPtr; + } while (--i); + } + + src = ((uint)(srcCharPtr + 1)) & 3; + ls = src << 3; + rs = 32 - ls; + + srcCharPtr -= src; + + srcLongPtr = ((u32*)(srcCharPtr + 1)) - 1; + destLongPtr = ((u32*)(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 = ((u8*)(srcLongPtr + 1)) - 1; + destCharPtr = ((u8*)(destLongPtr + 1)) - 1; + + len &= 3; + + if (len != 0) { + srcCharPtr -= 4 - src; + do { + *++destCharPtr = *++srcCharPtr; + } while (--len); + } +} + +/** + * @note Address: 0x800C7158 + * @note Size: 0xAC + */ +void __copy_longs_rev_unaligned(void* pDest, const void* pSrc, u32 len) +{ + u32 i, v1, v2; + uint src, ls, rs; + + srcCharPtr = ((u8*)pSrc) + len; + destCharPtr = ((u8*)pDest) + len; + i = ((u32)pDest) & 3; + + if (i != 0) { + len -= i; + + do { + *--destCharPtr = *--srcCharPtr; + } while (--i); + } + + src = ((uint)(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/dolphin sdk not yet linked/src/MSL_C/MSL_Common/misc_io.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/misc_io.c new file mode 100644 index 0000000..dde7eb4 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/misc_io.c @@ -0,0 +1,45 @@ +extern void (*__stdio_exit)(void); + +extern void __close_all(void); + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void clearerr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void feof(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void ferror(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x74 + */ +void perror(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C7428 + * @note Size: 0x10 + */ +void __stdio_atexit(void) { __stdio_exit = __close_all; } diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/printf.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/printf.c new file mode 100644 index 0000000..722e701 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/printf.c @@ -0,0 +1,1310 @@ +#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 s64 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 { + u8 justification_options; // _0 + u8 sign_options; // _1 + u8 precision_specified; // _2 + u8 alternate_form; // _3 + u8 argument_options; // _4 + u8 conversion_char; // _5 + int field_width; // _8 + int precision; // _C +} print_format; + +/** + * @note Address: 0x800C9094 + * @note Size: 0x504 + */ +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); +} + +/** + * @note Address: 0x800C8E3C + * @note Size: 0x258 + */ +static char* long2str(s32 num, char* buff, print_format format) +{ + u32 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; +} + +/** + * @note Address: 0x800C8B28 + * @note Size: 0x314 + */ +static char* longlong2str(s64 num, char* pBuf, print_format fmt) +{ + u64 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; +} + +/** + * @note Address: 0x800C87F0 + * @note Size: 0x338 + */ +static char* double2hex(f128 num, char* buff, print_format format) +{ + int offset, what_nibble = 0; + char* wrk_byte_ptr; + char *p, *q; + char working_byte; + f128 ld; + s16* sptr; + s16 snum; + s32 exp; + print_format exp_format; + int hex_precision; + decform form; + decimal dec; + + p = buff; + ld = num; + sptr = (s16*)&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; +} + +/** + * @note Address: 0x800C86C4 + * @note Size: 0x12C + */ +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; +} + +/** + * @note Address: 0x800C7FA8 + * @note Size: 0x71C + */ +static char* float2str(f128 num, char* buff, print_format format) +{ + decimal dec; + decform form; + char* p; + char* q; + int n, digits, sign; + int int_digits, frac_digits; + int radix_marker; + + radix_marker = '.'; + + 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 = radix_marker; + } + + *--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 = radix_marker; + + 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; +} + +/** + * @note Address: 0x800C7834 + * @note Size: 0x774 + */ +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; + s32 long_num; + s64 long_long_num; + f128 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, s32); + } else if (format.argument_options == long_long_argument) { + long_long_num = va_arg(arg, s64); + } else { + long_num = va_arg(arg, int); + } + + if (format.argument_options == short_argument) { + long_num = (s16)long_num; + } + + if (format.argument_options == char_argument) { + long_num = (s8)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, u32); + } else if (format.argument_options == long_long_argument) { + long_long_num = va_arg(arg, s64); + } else { + long_num = va_arg(arg, uint); + } + + if (format.argument_options == short_argument) { + long_num = (u16)long_num; + } + + if (format.argument_options == char_argument) { + long_num = (u8)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, f128); + } else { + long_double_num = va_arg(arg, f64); + } + + 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, f128); + } else { + long_double_num = va_arg(arg, f64); + } + + 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 = (u8)*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((u8*)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: + *(s16*)buff_ptr = chars_written; + break; + case long_argument: + *(s32*)buff_ptr = chars_written; + break; + case long_long_argument: + *(s64*)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; +} + +/** + * @note Address: 0x800C77DC + * @note Size: 0x58 + */ +static void* __FileWrite(void* pFile, const char* pBuffer, size_t char_num) +{ + return (fwrite(pBuffer, 1, char_num, (FILE*)pFile) == char_num ? pFile : 0); +} + +/** + * @note Address: 0x800C7770 + * @note Size: 0x6C + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0xE8 + */ +void printf(const char* format, ...) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xE0 + */ +int fprintf(FILE* file, const char* format, ...) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C76D8 + * @note Size: 0x98 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void vfprintf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C7664 + * @note Size: 0x74 + */ +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; +} + +/** + * @note Address: 0x800C75EC + * @note Size: 0x78 + */ +int vsprintf(char* s, const char* format, va_list arg) { return vsnprintf(s, 0xFFFFFFFF, format, arg); } + +/** + * @note Address: 0x800C7518 + * @note Size: 0xD4 + */ +int snprintf(char* s, size_t n, const char* format, ...) +{ + va_list args; + va_start(args, format); + return vsnprintf(s, n, format, args); +} + +/** + * @note Address: 0x800C7438 + * @note Size: 0xE0 + */ +int sprintf(char* s, const char* format, ...) +{ + va_list args; + va_start(args, format); + return vsnprintf(s, 0xFFFFFFFF, format, args); +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/rand.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/rand.c new file mode 100644 index 0000000..9b00a18 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/rand.c @@ -0,0 +1,19 @@ +#include "Dolphin/rand.h" + +static u32 next = 1; + +/** + * @note Address: 0x800C95A0 + * @note Size: 0x20 + */ +int rand() +{ + next = next * 1103515245 + 12345; + return ((next >> 16) & 0x7fff); +} + +/** + * @note Address: 0x800C9598 + * @note Size: 0x8 + */ +void srand(u32 seed) { next = seed; } diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/scanf.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/scanf.c new file mode 100644 index 0000000..427d313 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/scanf.c @@ -0,0 +1,710 @@ +#include "math.h" +#include "stdarg.h" +#include "ctype.h" +#include "stdio.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" + +typedef s64 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 u8 char_map[32]; + +typedef struct { + u8 suppress_assignment; + u8 field_width_specified; + u8 argument_options; + u8 conversion_char; + int field_width; + char_map char_set; +} scan_format; + +#define set_char_map(map, ch) map[(u8)ch >> 3] |= (1 << (ch & 7)) +#define tst_char_map(map, ch) (map[(u8)ch >> 3] & (1 << (ch & 7))) + +/** + * @note Address: 0x800CA0C0 + * @note Size: 0x548 + */ +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; + u8* 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; + u8* 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); +} + +/** + * @note Address: 0x800C9714 + * @note Size: 0x9AC + */ +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; + s32 long_num; + u32 u_long_num; + s64 long_long_num; + u64 u_long_long_num; + f128 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)) != (u8)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: + *(s8*)arg_ptr = long_num; + break; + case short_argument: + *(s16*)arg_ptr = long_num; + break; + case long_argument: + *(s32*)arg_ptr = long_num; + break; + case long_long_argument: + *(s64*)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: + *(uint*)arg_ptr = u_long_num; + break; + case char_argument: + *(u8*)arg_ptr = u_long_num; + break; + case short_argument: + *(u16*)arg_ptr = u_long_num; + break; + case long_argument: + *(u32*)arg_ptr = u_long_num; + break; + case long_long_argument: + *(u64*)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: + *(f32*)arg_ptr = long_double_num; + break; + case double_argument: + *(f64*)arg_ptr = long_double_num; + break; + case long_double_argument: + *(f128*)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: + *(s16*)arg_ptr = chars_read; + break; + case long_argument: + *(s32*)arg_ptr = chars_read; + break; + case char_argument: + *(char*)arg_ptr = chars_read; + break; + case long_long_argument: + *(s64*)arg_ptr = chars_read; + break; + } + continue; + case 0xFF: + default: + goto exit; + } + } + +exit: + + if ((*ReadProc)(ReadProcArg, 0, __TestForError) && conversions == 0) + return -1; + + return items_assigned; +} + +/** + * @note Address: N/A + * @note Size: 0x84 + */ +void __FileRead(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C9684 + * @note Size: 0x90 + */ +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 (u8)ret; + } + + case __UngetAChar: + if (Iscp->NullCharDetected == 0) { + Iscp->NextChar--; + } else { + Iscp->NullCharDetected = 0; + } + + return ch; + + case __TestForError: + return Iscp->NullCharDetected; + } + + return 0; +} + +/** + * @note Address: N/A + * @note Size: 0xF0 + */ +void fscanf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x90 + */ +void vscanf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xE0 + */ +void scanf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x5C + */ +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); +} + +/** + * @note Address: 0x800C95C0 + * @note Size: 0xC4 + */ +int sscanf(const char* s, const char* pFormat, ...) +{ + va_list args; + va_start(args, pFormat); + return vsscanf(s, pFormat, args); +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/string.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/string.c new file mode 100644 index 0000000..b55c785 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/string.c @@ -0,0 +1,345 @@ +#include "types.h" +#define K1 0x80808080 +#define K2 0xFEFEFEFF + +/** + * @note Address: 0x800CA910 + * @note Size: 0x1C + */ +size_t(strlen)(const char* str) +{ + size_t len = -1; + u8* p = (u8*)str - 1; + + do + len++; + while (*++p); + return (len); +} + +/** + * @note Address: 0x800CA858 + * @note Size: 0xB8 + */ +char*(strcpy)(char* dst, const char* src) +{ + register u8 *destb, *fromb; + register u32 w, t, align; + + 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)); + + t = w + K2; + + 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; +} + +/** + * @note Address: 0x800CA814 + * @note Size: 0x44 + */ +char* strncpy(char* dst, const char* src, size_t n) +{ + const u8* p = (const u8*)src - 1; + u8* q = (u8*)dst - 1; + u8 zero = 0; + + n++; + + while (--n) + if (!(*++q = *++p)) { + while (--n) + *++q = 0; + break; + } + return (dst); +} + +/** + * @note Address: 0x800CA7E8 + * @note Size: 0x2C + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void strncat(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800CA6C0 + * @note Size: 0x128 + */ +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; + + 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; + 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); +} + +/** + * @note Address: 0x800CA680 + * @note Size: 0x40 + */ +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; +} + +/** + * @note Address: 0x800CA650 + * @note Size: 0x30 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void strcoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +void strxfrm(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800CA608 + * @note Size: 0x48 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0xD4 + */ +void strpbrk(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xD0 + */ +void strspn(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xD0 + */ +void strcspn(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x13C + */ +void strtok(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x68 + */ +void strstr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void strerror(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x458 + */ +void __strerror(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/strtold.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/strtold.c new file mode 100644 index 0000000..1b2e5e6 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/strtold.c @@ -0,0 +1,603 @@ +#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 "stl/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) + +/** + * @note Address: 0x800CA92C + * @note Size: 0x100C + */ +f128 __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; + s32 exp_value = 0; + int exp_adjust = 0; + f128 result; + int sign_detected = 0; + + u8* chptr = (u8*)&result; + u8 uch, uch1; + int ui; + int chindex; + int NibbleIndex; + int expsign = 0; + int exp_digits = 0; + int intdigits = 0; + int RadixPointFound = 0; + s16 exponent = 0; + int dot; + + dot = *(u8*)(__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; + u8* 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 { + u64* uptr = (u64*)&result; + + if (result) { + if (expsign) { + exponent = -exponent; + } + + while ((*(s16*)(&result) & 0x00f0) != 0x0010) { + *uptr >>= 1; + exponent++; + } + + exponent += 4 * (intdigits - 1); + *(s16*)&result &= 0x000f; + *(s16*)(&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) { + *(s16*)(&result) |= 0x8000; + } + } else { + result = 0.0; + } + return result; + } +} + +/** + * @note Address: N/A + * @note Size: 0xBC + */ +void strtold(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xBC + */ +void strtod(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void atof(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/strtoul.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/strtoul.c new file mode 100644 index 0000000..0fb4773 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/strtoul.c @@ -0,0 +1,393 @@ +#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 "stl/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) + +/** + * @note Address: 0x800CBEE0 + * @note Size: 0x378 + */ +u32 __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; + u32 value = 0; + u32 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 = 0; + value = 0; + *chars_scanned = 0; + } else { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + return value; +} + +/** + * @note Address: 0x800CBAD4 + * @note Size: 0x40C + */ +u64 __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; + u64 value = 0; + u64 value_max = 0; + u64 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 = ULLONG_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 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 = 0; + value = *chars_scanned = 0; + } else { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + return value; +} + +/** + * @brief STRing TO Unsigned Long. Converts any numbers (of base `base`) at start of input string `str` to u32 and returns. + * Any remaining string part goes in `end`. + * + * @note Address: 0x800CBA28 + * @note Size: 0xAC + */ +u32 strtoul(const char* str, char** end, int base) +{ + u32 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 = ERANGE; + } else if (negative) { + value = -value; + } + + return value; +} + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +void strtoull(void) +{ + // UNUSED FUNCTION +} + +/** + * @brief STRing TO Long. Converts any numbers (of base `base`) at start of input string `str` to s32 and returns. + * Any remaining string part goes in `end`. + * + * @note Address: 0x800CB938 + * @note Size: 0xF0 + */ +s32 strtol(const char* str, char** end, int base) +{ + u32 uvalue; + s32 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 ? (s32)-uvalue : (s32)uvalue); + } + + return svalue; +} + +/** + * @note Address: N/A + * @note Size: 0x124 + */ +void strtoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC0 + */ +int atoi(const char* str) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC0 + */ +void atol(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common/wchar_io.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/wchar_io.c new file mode 100644 index 0000000..fde7d84 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common/wchar_io.c @@ -0,0 +1,117 @@ +#include "types.h" + +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +/** + * @note Address: N/A + * @note Size: 0xC8 + */ +void putwc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xCC + */ +void putwchar(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC8 + */ +void fputwc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC4 + */ +void getwc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xCC + */ +void getwchar(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC4 + */ +void fgetwc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x154 + */ +void ungetwc(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x110 + */ +void fputws(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x150 + */ +void fgetws(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800CC258 + * @note Size: 0x88 + */ +int fwide(FILE* stream, int mode) +{ + 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; + + return mode; + + case __wide_oriented: + return 1; + + case __char_oriented: + return -1; + } +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c new file mode 100644 index 0000000..8d8ca00 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c @@ -0,0 +1,118 @@ + +/* @(#)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 f64 +#else +static f64 +#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__ +f64 __ieee754_asin(f64 x) +#else +f64 __ieee754_asin(x) +f64 x; +#endif +{ + f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c new file mode 100644 index 0000000..a7ebef1 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c @@ -0,0 +1,144 @@ + +/* @(#)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 f64 +#else +static f64 +#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__ +f64 __ieee754_atan2(f64 y, f64 x) +#else +f64 __ieee754_atan2(y, x) +f64 y, x; +#endif +{ + f64 z; + int k, m, hx, hy, ix, iy; + uint 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c new file mode 100644 index 0000000..8089728 --- /dev/null +++ b/dolphin sdk not yet linked/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 f64 +#else +static f64 +#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__ +f64 __ieee754_exp(f64 x) /* default IEEE double exp */ +#else +f64 __ieee754_exp(x) /* default IEEE double exp */ +f64 x; +#endif +{ + f64 y, hi, lo, c, t; + int k, xsb; + uint 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c new file mode 100644 index 0000000..8f05faf --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c @@ -0,0 +1,168 @@ + +/* @(#)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 f64 one = 1.0, Zero[] = { + 0.0, + -0.0, +}; +#else +static f64 one = 1.0, Zero[] = { + 0.0, + -0.0, +}; +#endif + +#ifdef __STDC__ +f64 __ieee754_fmod(f64 x, f64 y) +#else +f64 __ieee754_fmod(x, y) +f64 x, y; +#endif +{ + int n, hx, hy, hz, ix, iy, sx, i; + uint 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c new file mode 100644 index 0000000..7a3df89 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c @@ -0,0 +1,163 @@ +/** + * @note Address: 0x800CCDD8 + * @note Size: 0x27C + */ + +/* @(#)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 f64 +#else +static f64 +#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 f64 zero = 0.0; + +#ifdef __STDC__ +f64 __ieee754_log(f64 x) +#else +f64 __ieee754_log(x) +f64 x; +#endif +{ + f64 hfsq, f, s, z, R, w, t1, t2, dk; + int k, hx, i, j; + uint 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 = EDOM; + 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 = (f64)k; + return dk * ln2_hi + dk * ln2_lo; + } + R = f * f * (0.5 - 0.33333333333333333 * f); + if (k == 0) + return f - R; + else { + dk = (f64)k; + return dk * ln2_hi - ((R - dk * ln2_lo) - f); + } + } + s = f / (2.0 + f); + dk = (f64)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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c new file mode 100644 index 0000000..18b2170 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c @@ -0,0 +1,100 @@ + +/* @(#)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 f64 +#else +static f64 +#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 f64 zero = 0.0; + +#ifdef __STDC__ +f64 __ieee754_log10(f64 x) +#else +f64 __ieee754_log10(x) +f64 x; +#endif +{ + f64 y, z; + int i, k, hx; + uint 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 = EDOM; + return -two54 / zero; + } /* log(+-0)=-inf */ + if (hx < 0) { + errno = EDOM; + 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 = (f64)(k + i); + __HI(x) = hx; + z = y * log10_2lo + ivln10 * __ieee754_log(x); + return z + y * log10_2hi; +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c new file mode 100644 index 0000000..5f3d038 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c @@ -0,0 +1,409 @@ +//======================================================================== +// +// 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 f64 +#else +static f64 +#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 =(f32)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__ +f64 __ieee754_pow(f64 x, f64 y) +#else +f64 __ieee754_pow(x, y) +f64 x, y; +#endif +{ + f64 z, ax, z_h, z_l, p_h, p_l; + f64 y1, t1, t2, r, s, t, u, v, w; + f64 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 = EDOM; + return (f64)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 { + f64 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 = (f64)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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c new file mode 100644 index 0000000..b905cf9 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c @@ -0,0 +1,182 @@ + +/* @(#)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 "math.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 f64 +#else +static f64 +#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(f64 x, f64* y) +#else +int __ieee754_rem_pio2(x, y) +f64 x, y[]; +#endif +{ + f64 z, w, t, r, fn; + f64 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 = (f64)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] = (f64)((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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c new file mode 100644 index 0000000..7a8c51c --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c @@ -0,0 +1,468 @@ +/** + * @note Address: 0x800CFA2C + * @note Size: 0x224 + */ + +/* @(#)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 f64 one = 1.0, tiny = 1.0e-300; +#else +static f64 one = 1.0, tiny = 1.0e-300; +#endif + +#ifdef __STDC__ +f64 __ieee754_sqrt(f64 x) +#else +f64 __ieee754_sqrt(x) +f64 x; +#endif +{ + f64 z; + int sign = (int)0x80000000; + uint 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 = EDOM; + 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 = EDOM; + 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, f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c new file mode 100644 index 0000000..af27aec --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c @@ -0,0 +1,94 @@ + +/* @(#)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 f64 +#else +static f64 +#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__ +f64 __kernel_cos(f64 x, f64 y) +#else +f64 __kernel_cos(x, y) +f64 x, y; +#endif +{ + f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c new file mode 100644 index 0000000..01f27cd --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c @@ -0,0 +1,354 @@ + +#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) + * f64 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: + * + * f128 t,w,r_head, r_tail; + * t = (f128)y[2] + (f128)y[1]; + * w = (f128)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: + * f64 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 f64 PIo2[] = { +#else +static f64 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 f64 +#else +static f64 +#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(f64* x, f64* 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 -*/ +f64 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 -*/ + f64 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 : (f64)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 = (f64)((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 -= (f64)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] = (f64)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 = (f64)((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 * (f64)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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c new file mode 100644 index 0000000..2813916 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c @@ -0,0 +1,81 @@ + +/* @(#)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 f64 +#else +static f64 +#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__ +f64 __kernel_sin(f64 x, f64 y, int iy) +#else +f64 __kernel_sin(x, y, iy) +f64 x, y; +int iy; /* iy=0 if y is zero */ +#endif +{ + f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c new file mode 100644 index 0000000..72aa40c --- /dev/null +++ b/dolphin sdk not yet linked/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 "math.h" +static const f64 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 */ + }; + +f64 __kernel_tan(f64 x, f64 y, int iy) +{ + f64 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) { + f64 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 = (f64)iy; + return (f64)(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 */ + f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c new file mode 100644 index 0000000..43f5873 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c @@ -0,0 +1,144 @@ + +/* @(#)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 f64 atanhi[] = { +#else +static f64 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 f64 atanlo[] = { +#else +static f64 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 f64 aT[] = { +#else +static f64 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 f64 +#else +static f64 +#endif + one + = 1.0, + huge = 1.0e300; + +#ifdef __STDC__ +f64 atan(f64 x) +#else +f64 atan(x) +f64 x; +#endif +{ + f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c new file mode 100644 index 0000000..c7bd267 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c @@ -0,0 +1,91 @@ + +/* @(#)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 f64 huge = 1.0e300; +#else +static f64 huge = 1.0e300; +#endif + +#ifdef __STDC__ +f64 ceil(f64 x) +#else +f64 ceil(x) +f64 x; +#endif +{ + int i0, i1, j0; + uint 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c new file mode 100644 index 0000000..471c0e4 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c @@ -0,0 +1,31 @@ + +/* @(#)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(f64 x, f64 y) + * copysign(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +f64 copysign(f64 x, f64 y) +#else +f64 copysign(x, y) +f64 x, y; +#endif +{ + __HI(x) = (__HI(x) & 0x7fffffff) | (__HI(y) & 0x80000000); + return x; +} diff --git a/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c new file mode 100644 index 0000000..00b929d --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c @@ -0,0 +1,83 @@ + +/* @(#)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__ +f64 cos(f64 x) +#else +f64 cos(x) +f64 x; +#endif +{ + f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c new file mode 100644 index 0000000..76b924d --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c @@ -0,0 +1,90 @@ + +/* @(#)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 f64 huge = 1.0e300; +#else +static f64 huge = 1.0e300; +#endif + +#ifdef __STDC__ +f64 floor(f64 x) +#else +f64 floor(x) +f64 x; +#endif +{ + int i0, i1, j0; + uint 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c new file mode 100644 index 0000000..7d54abd --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c @@ -0,0 +1,59 @@ + +/* @(#)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 f64 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 f64 +#else +static f64 +#endif + two54 + = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ + +#ifdef __STDC__ +f64 frexp(f64 x, int* eptr) +#else +f64 frexp(x, eptr) +f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c new file mode 100644 index 0000000..46a3153 --- /dev/null +++ b/dolphin sdk not yet linked/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 "math.h" /* for isfinite macro */ +static const f64 + + two54 + = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ + twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ + big = 1.0e+300, tiny = 1.0e-300; + +f64 ldexp(f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c new file mode 100644 index 0000000..c9208c6 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c @@ -0,0 +1,80 @@ + +/* @(#)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(f64 x, f64 *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 f64 one = 1.0; +#else +static f64 one = 1.0; +#endif + +#ifdef __STDC__ +f64 modf(f64 x, f64* iptr) +#else +f64 modf(x, iptr) +f64 x, *iptr; +#endif +{ + int i0, i1, j0; + uint 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c new file mode 100644 index 0000000..e1e7fc1 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c @@ -0,0 +1,83 @@ + +/* @(#)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__ +f64 sin(f64 x) +#else +f64 sin(x) +f64 x; +#endif +{ + f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c new file mode 100644 index 0000000..60b0b4a --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c @@ -0,0 +1,74 @@ + +/* @(#)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__ +f64 tan(f64 x) +#else +f64 tan(x) +f64 x; +#endif +{ + f64 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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c new file mode 100644 index 0000000..9db6c72 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c @@ -0,0 +1,22 @@ +#include "types.h" + +extern f64 __ieee754_asin(); + +/** + * @note Address: 0x800CF96C + * @note Size: 0x20 + */ + +f64 asin(f64 __x) { return (f64)__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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c new file mode 100644 index 0000000..801bfff --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c @@ -0,0 +1,22 @@ +#include "types.h" + +extern f64 __ieee754_atan2(); + +/** + * @note Address: 0x800CF98C + * @note Size: 0x20 + */ + +f64 atan2(f64 __x, f64 __y) { return (f64)__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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c new file mode 100644 index 0000000..738ec35 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c @@ -0,0 +1,22 @@ +#include "types.h" + +extern f64 __ieee754_exp(); + +/** + * @note Address: 0x800CF9AC + * @note Size: 0x20 + */ + +f64 exp(f64 __x) { return (f64)__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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c new file mode 100644 index 0000000..efe2d9e --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c @@ -0,0 +1,22 @@ +#include "types.h" + +extern f64 __ieee754_fmod(); + +/** + * @note Address: 0x800CF9CC + * @note Size: 0x20 + */ + +f64 fmod(f64 __x, f64 __y) { return (f64)__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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c new file mode 100644 index 0000000..9be02d6 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c @@ -0,0 +1,22 @@ +#include "types.h" + +extern f64 __ieee754_log10(); + +/** + * @note Address: 0x800CF9EC + * @note Size: 0x20 + */ + +f64 log10(f64 __x) { return (f64)__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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c new file mode 100644 index 0000000..40ffa47 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c @@ -0,0 +1,22 @@ +#include "types.h" + +extern f64 __ieee754_pow(); + +/** + * @note Address: 0x800CFA0C + * @note Size: 0x20 + */ + +f64 pow(f64 __x, f64 __y) { return (f64)__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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c new file mode 100644 index 0000000..7bbde7a --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c @@ -0,0 +1,22 @@ +#include "types.h" + +extern f64 __ieee754_sqrt(); + +/** + * @note Address: 0x800CFCBC + * @note Size: 0x20 + */ + +f64 sqrt(f64 __x) { return (f64)__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/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/ansi_fp.c b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/ansi_fp.c new file mode 100644 index 0000000..7f8e6ec --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/MSL_Common_Embedded/ansi_fp.c @@ -0,0 +1,835 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h" +#include "ctype.h" +#include "stl/limits.h" + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +static int __count_trailing_zerol(u32 x) +{ + int result = 0; + int bits_not_checked = sizeof(u32) * CHAR_BIT; + int n = bits_not_checked / 2; + int mask_size = n; + u32 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; +} + +/** + * @note Address: N/A + * @note Size: 0xFC + */ +static int __count_trailing_zero(f64 x) +{ + u32* l = (u32*)&x; + + if (l[1] != 0) { + return __count_trailing_zerol(l[1]); + } + + return (int)(sizeof(u32) * CHAR_BIT + __count_trailing_zerol(l[0] | 0x00100000)); +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +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; + } +} + +/** + * @note Address: N/A + * @note Size: 0xFC + */ +static void __rounddec(decimal* d, int digits) +{ + if (digits > 0 && digits < d->sig.length) { + int unkBool = __must_round(d, digits); + d->sig.length = digits; + + if (unkBool >= 0) { + __dorounddecup(d, digits); + } + } +} + +/** + * @note Address: N/A + * @note Size: 0x110 + */ +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; +} + +/** + * @note Address: 0x800C5E80 + * @note Size: 0x278 + */ +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 = (s16)(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); + } +} + +/** + * @note Address: N/A + * @note Size: 0xF0 + */ +void __str2dec(decimal* d, const char* s, s16 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); + } +} + +/** + * @note Address: 0x800C46FC + * @note Size: 0x1784 + */ +void __two_exp(decimal* result, s32 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); + } + } +} + +/** + * @note Address: 0x800C45F0 + * @note Size: 0x10C + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0xF8 + */ +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; +} + +/** + * @note Address: 0x800C40F4 + * @note Size: 0x4FC + */ +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); +} + +/** + * @note Address: 0x800C3D40 + * @note Size: 0x3B4 + */ +void __num2dec_internal(decimal* d, f64 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; + f64 frac = frexp(x, &exp); + s32 num_bits_extract = DBL_MANT_DIG - __count_trailing_zero(frac); + f64 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; + } +} + +/** + * @note Address: 0x800C3B9C + * @note Size: 0x1A4 + */ +void __num2dec(const decform* form, f64 x, decimal* d) +{ + s16 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'; + } +} + +/** + * @note Address: 0x800C2B1C + * @note Size: 0x1080 + */ +f64 __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((f64)INFINITY, d->sign == 0 ? 1.0 : -1.0); + case 'N': { + f64 result; + u64* ll = (u64*)&result; + + *ll = 0x7FF0000000000000; + if (d->sign) + *ll |= 0x8000000000000000; + + if (d->sig.length == 1) + *ll |= 0x8000000000000; + else { + u8* p = (u8*)&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) { + u8 c = d->sig.text[i]; + + if (isdigit(c)) { + c -= '0'; + } else { + c = (u8)(_tolower(c) - 'a' + 10); + } + + if (c != 0) { + placed_non_zero = 1; + } + + if (low) { + *p++ |= c; + } else { + *p = (u8)(c << 4); + } + + low = !low; + } + + if (!placed_non_zero) { + *ll |= 0x0008000000000000; + } + } + + return result; + } + } + + { + static f64 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; + f64 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; + f64 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; + f64 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; + f64 next_guess = first_guess; + u64* ull = (u64*)&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 (*(u64*)&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/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/abort_exit.c b/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/abort_exit.c new file mode 100644 index 0000000..ac38646 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/abort_exit.c @@ -0,0 +1,85 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.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); + +/** + * @note Address: N/A + * @note Size: 0x9C + */ +void abort(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void atexit(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x6C + */ +void __atexit(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C2460 + * @note Size: 0xF0 + */ +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; + } + } + __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(); +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void __exit(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/critical_regions.gamecube.c b/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/critical_regions.gamecube.c new file mode 100644 index 0000000..00764c9 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/critical_regions.gamecube.c @@ -0,0 +1,38 @@ +#include "types.h" +#include "Dolphin/MSL_C/PPC_EABI/critical_regions.h" + +/** + * @note Address: N/A + * @note Size: 0x4 + */ +void __init_critical_regions(void) +{ + return; +} + +/** + * @note Address: 0x800C6260 + * @note Size: 0x4 + */ +void __kill_critical_regions(void) +{ + return; +} + +/** + * @note Address: 0x800C625C + * @note Size: 0x4 + */ +void __begin_critical_region(int region) +{ + return; +} + +/** + * @note Address: 0x800C6258 + * @note Size: 0x4 + */ +void __end_critical_region(int region) +{ + return; +} diff --git a/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/math_ppc.c b/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/math_ppc.c new file mode 100644 index 0000000..329ae57 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/math_ppc.c @@ -0,0 +1,956 @@ +#include "PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h" +#include "fdlibm.h" + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +void __fpclassifyf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +void __fpclassifyd(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +f64 scalbn(f64 x, int y) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void scalbln(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void acosl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void asinl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void atanl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void atan2l(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void cosl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void sinl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void tanl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void coshl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void sinhl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void tanhl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void acoshl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void asinhl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void atanhl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void expl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void frexpl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void ldexpl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void logl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void log10l(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +void modfl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void exp2l(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void expm1l(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void log1pl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void log2l(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void logbl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void scalbnl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void scalblnl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void fabsl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void powl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void sqrtl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void hypotl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void erfl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void erfcl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void gammal(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void lgammal(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void nextafterl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void ceill(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void floorl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void nearbyintl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void rintl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void lrintl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void llrintl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void truncl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void fmodl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void remainderl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void copysignl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void remquol(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void fdiml(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void fmaxl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void fminl(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void acosf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void asinf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void atanf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void atan2f(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800CFC98 + * @note Size: 0x24 + */ +WEAKFUNC f32 cosf(f32 __x) { return cos((f64)__x); } + +/** + * @note Address: 0x800CFC74 + * @note Size: 0x24 + */ +WEAKFUNC f32 sinf(f32 __x) { return sin((f64)__x); } + +/** + * @note Address: 0x800CFC50 + * @note Size: 0x24 + */ +WEAKFUNC f32 tanf(f32 __x) { return tan((f64)__x); } + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void coshf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void sinhf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void tanhf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void expf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void frexpf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void ldexpf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void logf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void log10f(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void fabsf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void powf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void ceilf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void floorf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void fmodf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +void log2f(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xE4 + */ +void sqrtf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +void _inv_sqrtf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +f64 fabs(f64 x) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x130 + */ +void modff(f32 f1, f32* fp) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void acoshf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void asinhf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void atanhf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +void exp2f(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void expm1f(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void log1pf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void logbf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void scalbnf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void scalblnf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void hypotf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void erff(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void erfcf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void gammaf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void lgammaf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void nextafterf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void nearbyintf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void rintf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void lrintf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void llroundf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void llrintf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void truncf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void remainderf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void copysignf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void remquof(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void fdimf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void fmaxf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void fminf(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void log2(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void exp2(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/uart_console_io_gcn.c b/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/uart_console_io_gcn.c new file mode 100644 index 0000000..84bc331 --- /dev/null +++ b/dolphin sdk not yet linked/src/MSL_C/PPC_EABI/uart_console_io_gcn.c @@ -0,0 +1,71 @@ +#include "types.h" + +s32 InitializeUART(u32); /* extern */ +s32 OSGetConsoleType(); /* extern */ +s32 WriteUARTN(s32, s32); /* extern */ +s32 __TRK_write_console(s32, s32, s32*, s32); /* extern */ +static BOOL initialized; + +/** + * @note Address: 0x800CC2E0 + * @note Size: 0xD0 + */ +WEAKFUNC BOOL __write_console(s32 arg0, s32 arg1, s32* arg2, s32 arg3) +{ + + if ((OSGetConsoleType() & 0x20000000) == 0) { + int r3_cond = 0; + if (initialized == FALSE) { + r3_cond = InitializeUART(0xE100); + ; + if (r3_cond == 0) { + initialized = TRUE; + } + } + if (r3_cond != 0) { + return TRUE; + } + if (WriteUARTN(arg1, *arg2) != 0) { + *arg2 = 0; + return TRUE; + } + } + __TRK_write_console(arg0, arg1, arg2, arg3); + return FALSE; +} + +/** + * @note Address: N/A + * @note Size: 0x48 + */ +void __init_uart_console(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __delete_file(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __rename_file(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xCC + */ +void __temp_file_name(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/OdemuExi2/DebuggerDriver.c b/dolphin sdk not yet linked/src/OdemuExi2/DebuggerDriver.c new file mode 100644 index 0000000..ad1ba0f --- /dev/null +++ b/dolphin sdk not yet linked/src/OdemuExi2/DebuggerDriver.c @@ -0,0 +1,416 @@ +#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))) + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void DBGEXIInit() +{ + __OSMaskInterrupts(0x18000); + __EXIRegs[10] = 0; +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +static u32 DBGEXISelect(u32 v) +{ + u32 regs = __EXIRegs[10]; + regs &= 0x405; + regs |= 0x80 | (v << 4); + __EXIRegs[10] = regs; + return TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +BOOL DBGEXIDeselect(void) +{ + __EXIRegs[10] &= 0x405; + return TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +static BOOL DBGEXISync() +{ + while (__EXIRegs[13] & 1) + ; + + return TRUE; +} + +/** + * @note Address: 0x800D0550 + * @note Size: 0x298 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +void DBGEXIClearInterrupts(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xAC + */ +void DBGCheckID(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +static BOOL DBGWriteMailbox(u32 p1) +{ + u32 cmd = 0xc0000000; + u32 v; + u32 base = p1; + BOOL total = FALSE; + + DBGEXISelect(4); + v = (base & 0x1fffffff) | (cmd); + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 1)); + total |= IS_FALSE(DBGEXISync()); + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} + +/** + * @note Address: 0x800D04A4 + * @note Size: 0xAC + */ +#pragma dont_inline on +static BOOL DBGReadMailbox(u32* p1) +{ + BOOL total = FALSE; + u32 v; + + DBGEXISelect(4); + + v = 0x60000000; + total |= IS_FALSE(DBGEXIImm(&v, 2, 1)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIImm(p1, 4, 0)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} +#pragma dont_inline reset + +/** + * @note Address: 0x800D03C8 + * @note Size: 0xDC + */ +static BOOL DBGRead(u32 count, u32* buffer, s32 param3) +{ + BOOL total = FALSE; + u32* buf_p = (u32*)buffer; + u32 v1; + u32 v; + + DBGEXISelect(4); + + v1 = (count & 0x1fffc) << 8 | 0x20000000; + total |= IS_FALSE(DBGEXIImm(&v1, sizeof(v1), 1)); + total |= IS_FALSE(DBGEXISync()); + + while (param3) { + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 0)); + total |= IS_FALSE(DBGEXISync()); + + *buf_p++ = v; + + param3 -= 4; + if (param3 < 0) { + param3 = 0; + } + } + + total |= IS_FALSE(DBGEXIDeselect()); + return IS_FALSE(total); +} + +/** + * @note Address: 0x800D02EC + * @note Size: 0xDC + */ +static BOOL DBGWrite(u32 count, void* buffer, s32 param3) +{ + BOOL total = FALSE; + u32* buf_p = (u32*)buffer; + u32 v1; + u32 v; + + DBGEXISelect(4); + + v1 = (count & 0x1fffc) << 8 | 0xa0000000; + total |= IS_FALSE(DBGEXIImm(&v1, sizeof(v1), 1)); + total |= IS_FALSE(DBGEXISync()); + + while (param3 != 0) { + v = *buf_p++; + + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 1)); + total |= IS_FALSE(DBGEXISync()); + + param3 -= 4; + if (param3 < 0) { + param3 = 0; + } + } + + total |= IS_FALSE(DBGEXIDeselect()); + return IS_FALSE(total); +} + +/** + * @note Address: 0x800D0240 + * @note Size: 0xAC + */ +inline static BOOL _DBGReadStatus(u32* p1) +{ + BOOL total = FALSE; + u32 v; + + DBGEXISelect(4); + + v = 1 << 30; + total |= IS_FALSE(DBGEXIImm(&v, 2, 1)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIImm(p1, 4, 0)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} +#pragma dont_inline on +static BOOL DBGReadStatus(u32* p1) { return _DBGReadStatus(p1); } +#pragma dont_inline reset + +/** + * @note Address: 0x800D0204 + * @note Size: 0x3C + */ + +static void MWCallback(u32 a, OSContext* b) +{ + EXIInputFlag = TRUE; + if (MTRCallback) { + MTRCallback(0); + } +} + +/** + * @note Address: 0x800D01C4 + * @note Size: 0x40 + */ +static void DBGHandler(s16 a, OSContext* b) +{ + *__PIRegs = 0x1000; + if (DBGCallback) { + DBGCallback(a, b); + } +} + +/** + * @note Address: 0x800D014C + * @note Size: 0x78 + */ +void DBInitComm(u8** a, MTRCallbackType b) +{ + BOOL interrupts = OSDisableInterrupts(); + { + pEXIInputFlag = (u8*)EXIInputFlag; + pEXIInputFlag = &EXIInputFlag; + + *a = pEXIInputFlag; + + MTRCallback = b; + + DBGEXIInit(); + } + OSRestoreInterrupts(interrupts); +} + +/** + * @note Address: 0x800D00F8 + * @note Size: 0x54 + */ +void DBInitInterrupts(void) +{ + __OSMaskInterrupts(0x18000); + __OSMaskInterrupts(0x40); + DBGCallback = &MWCallback; + __OSSetInterruptHandler(0x19, DBGHandler); + __OSUnmaskInterrupts(0x40); +} + +/** + * @note Address: N/A + * @note Size: 0x150 + */ +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; + } + } +} + +/** + * @note Address: 0x800D005C + * @note Size: 0x9C + */ +u32 DBQueryData(void) +{ + EXIInputFlag = 0; + if (!RecvDataLeng) { + BOOL interrupts = OSDisableInterrupts(); + CheckMailBox(); + OSRestoreInterrupts(interrupts); + } + return RecvDataLeng; +} + +/** + * @note Address: 0x800CFFD0 + * @note Size: 0x8C + */ +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; +} + +/** + * @note Address: 0x800CFD70 + * @note Size: 0x260 + */ +BOOL DBWrite(void* src, u32 size) +{ + u32 v; + u32 busyFlag; + BOOL interrupts = OSDisableInterrupts(); + + do { + _DBGReadStatus(&busyFlag); + } while (busyFlag & 2); + + SendCount++; + v = ((SendCount & 1) ? 0x1000 : 0); + + while (!DBGWrite(v | 0x1c000, src, ROUND_UP(size, 4))) + ; + + do { + _DBGReadStatus(&busyFlag); + } while (busyFlag & 2); + + v = SendCount; + while (!DBGWriteMailbox((0x1f000000) | v << 0x10 | size)) + ; + + do { + while (!_DBGReadStatus(&busyFlag)) + ; + } while (busyFlag & 2); + + OSRestoreInterrupts(interrupts); + + return 0; +} + +/** + * @note Address: 0x800CFD6C + * @note Size: 0x4 + */ +void DBOpen(void) { return; } + +/** + * @note Address: 0x800CFD68 + * @note Size: 0x4 + */ +void DBClose(void) { return; } diff --git a/dolphin sdk not yet linked/src/Runtime/CPlusLibPPC.cp b/dolphin sdk not yet linked/src/Runtime/CPlusLibPPC.cp new file mode 100644 index 0000000..b0bc22b --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/CPlusLibPPC.cp @@ -0,0 +1,62 @@ +#include "types.h" +extern "C"{ + +/** + * @note Address: 0x800C1718 + * @note Size: 0x30 + */ + +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); +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +void __init_arr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x88 + */ +void __new_arr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void __del_arr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x74 + */ +void __dc_arr(void) +{ + // UNUSED FUNCTION +} + +} diff --git a/dolphin sdk not yet linked/src/Runtime/GCN_mem_alloc.c b/dolphin sdk not yet linked/src/Runtime/GCN_mem_alloc.c new file mode 100644 index 0000000..2be5f23 --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/GCN_mem_alloc.c @@ -0,0 +1,35 @@ +#include "types.h" +#include "Dolphin/os.h" + +inline 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); +} + +/** + * @note Address: 0x800C23A8 + * @note Size: 0xB8 + */ +WEAKFUNC extern void __sys_free(void* ptr) +{ + if (__OSCurrHeap == -1) { + InitDefaultHeap(); + } + OSFreeToHeap(__OSCurrHeap, ptr); +} diff --git a/dolphin sdk not yet linked/src/Runtime/Gecko_ExceptionPPC.cp b/dolphin sdk not yet linked/src/Runtime/Gecko_ExceptionPPC.cp new file mode 100644 index 0000000..304d22e --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/Gecko_ExceptionPPC.cp @@ -0,0 +1,1052 @@ +#include "PowerPC_EABI_Support/Runtime/MWCPlusLib.h" +#include "PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h" +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" + +#define RETURN_ADDRESS 4 + +union MWE_GeckoVector64 { + f64 d; + f32 f[2]; +}; + +typedef union MWE_GeckoVector64 MWE_GeckoVector64; + +struct GeckoFPRContext { + f64 d; + MWE_GeckoVector64 v; +}; + +typedef struct GeckoFPRContext GeckoFPRContext; + +typedef struct ThrowContext { + GeckoFPRContext FPR[32]; + s32 GPR[32]; + s32 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; + s32 current_R31; +} ActionIterator; + +#define MAXFRAGMENTS 1 +static ProcessInfo fragmentinfo[MAXFRAGMENTS]; + +typedef void (*DeleteFunc)(void*); + +/** + * @note Address: 0x800C2374 + * @note Size: 0x34 + */ +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; +} + +/** + * @note Address: 0x800C2340 + * @note Size: 0x34 + */ +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; + } +} + +/** + * @note Address: N/A + * @note Size: 0x88 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x204 + */ +static void ExPPC_FindExceptionRecord(char* returnaddr, MWExceptionInfo* info) +{ + FragmentInfo* fragment; + FragmentInfo frag; + ExceptionTableIndex *exceptionindex, *p; + u32 returnoffset; + s32 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++) { + u32 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; + } + } + } +} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +static s32 ExPPC_PopR31(char* SP, MWExceptionInfo* info) +{ + f64* FPR_save_area; + s32* GPR_save_area; + int saved_GPRs, saved_FPRs; + + saved_FPRs = ET_GetSavedFPRs(info->exception_record->et_field); + FPR_save_area = (f64*)(SP - saved_FPRs * 8); + saved_GPRs = ET_GetSavedGPRs(info->exception_record->et_field); + GPR_save_area = (s32*)FPR_save_area; + + return GPR_save_area[-1]; +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x1C0 + */ +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) { + 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: + 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; + } +} + +/** + * @note Address: N/A + * @note Size: 0x248 + */ +static char* ExPPC_PopStackFrame(ThrowContext* context, MWExceptionInfo* info) +{ + char *SP, *callers_SP; + f64* FPR_save_area; + s32* 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 = (f64*)Vector_save_area; + } else { + FPR_save_area = (f64*)(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 = (s32*)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); +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +static void ExPPC_DestroyLocal(ThrowContext* context, const ex_destroylocal* ex) { DTORCALL_COMPLETE(ex->dtor, context->FP + ex->local); } + +/** + * @note Address: N/A + * @note Size: 0x74 + */ +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); + } +} + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x84 + */ +static void ExPPC_DestroyLocalArray(ThrowContext* context, const ex_destroylocalarray* ex) +{ + char* ptr = context->FP + ex->localarray; + s32 n = ex->elements; + s32 size = ex->element_size; + + for (ptr = ptr + size * n; n > 0; n--) { + ptr -= size; + DTORCALL_COMPLETE(ex->dtor, ptr); + } +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +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); + } +} + +/** + * @note Address: N/A + * @note Size: 0xAC + */ +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); + s32 n = ex->elements; + s32 size = ex->element_size; + + ptr += ex->offset; + + for (ptr = ptr + size * n; n > 0; n--) { + ptr -= size; + DTORCALL_COMPLETE(ex->dtor, ptr); + } +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +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); + } +} + +/** + * @note Address: N/A + * @note Size: 0x50C + */ +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) { + 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: + terminate(); + } + + if (action & EXACTION_ENDBIT) + info->action_pointer = 0; + } +} + +/** + * @note Address: N/A + * @note Size: 0x88 + */ +static int ExPPC_IsInSpecification(char* extype, ex_specification* spec) +{ + s32 i, offset; + + for (i = 0; i < spec->specs; i++) { + if (__throw_catch_compare(extype, spec->spec[i], &offset)) + return 1; + } + + return 0; +} + +/** + * @note Address: N/A + * @note Size: 0x1B4 + */ +extern void __unexpected(CatchInfo* catchinfo) +{ + ex_specification* unexp = (ex_specification*)catchinfo->stacktop; + +#pragma exception_magic // allow access to __exception_magic in try/catch blocks + + try { + unexpected(); + } catch (...) { + if (ExPPC_IsInSpecification((char*)((CatchInfo*)&__exception_magic)->typeinfo, unexp)) { + throw; + } + if (ExPPC_IsInSpecification("!bad_exception!!", unexp)) { + throw bad_exception(); + } + if (ExPPC_IsInSpecification("!std::bad_exception!!", unexp)) { + throw bad_exception(); + } + } + terminate(); +} + +/** + * @note Address: N/A + * @note Size: 0x104 + */ +ASM static void ExPPC_LongJump(register ThrowContext* context, register void* newRTOC, register void* newPC) +{ +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x84 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x410 + */ +static void ExPPC_ThrowHandler(ThrowContext* context) +{ + ActionIterator iter; + MWExceptionInfo info; + exaction_type action; + CatchInfo* catchinfo; + s32 offset; + + ExPPC_FindExceptionRecord(context->returnaddr, &info); + + if (info.exception_record == 0) { + 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: + 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: + 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 = *(s32*)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 = *(s32*)context->location + offset; + } else { + catchinfo->sublocation = (char*)context->location + offset; + } + + ExPPC_LongJump(context, info.TOC, info.current_function + catchblock->catch_pcoffset); + } +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void __end__catch(CatchInfo* catchinfo) +{ + if (catchinfo->location && catchinfo->dtor) { + DTORCALL_COMPLETE(catchinfo->dtor, catchinfo->location); + } +} + +/** + * @note Address: N/A + * @note Size: 0x144 + */ +ASM void __throw(char* throwtype, void* location, void* dtor) +{ +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/Runtime/NMWException.cp b/dolphin sdk not yet linked/src/Runtime/NMWException.cp new file mode 100644 index 0000000..4153272 --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/NMWException.cp @@ -0,0 +1,277 @@ +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/MWCPlusLib.h" + +#define ARRAY_HEADER_SIZE 16 + +extern "C" { +extern void abort(); +} + +namespace std { +/** + * @note Address: N/A + * @note Size: 0x20 + */ +static void dthandler() { abort(); } + +static terminate_handler thandler = dthandler; + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +static void duhandler() { terminate(); } + +static unexpected_handler uhandler = duhandler; + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +extern terminate_handler set_terminate(terminate_handler handler) +{ + terminate_handler old = thandler; + thandler = handler; + return old; +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +extern void terminate() { thandler(); } + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +extern unexpected_handler set_unexpected(unexpected_handler handler) +{ + unexpected_handler old = uhandler; + uhandler = handler; + return old; +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +extern void unexpected() { uhandler(); } +} // namespace std + +/** + * @note Address: N/A + * @note Size: 0x22C + */ +extern char __throw_catch_compare(const char* throwtype, const char* catchtype, s32* offset_result) +{ + const char *cptr1, *cptr2; + + *offset_result = 0; + + if ((cptr2 = catchtype) == 0) { + return true; + } + + cptr1 = throwtype; + + if (*cptr2 == 'P') { + cptr2++; + if (*cptr2 == 'C') + cptr2++; + if (*cptr2 == 'V') + cptr2++; + if (*cptr2 == 'v') { + if (*cptr1 == 'P' || *cptr1 == '*') { + return true; + } + } + cptr2 = catchtype; + } + + switch (*cptr1) { + case '*': + case '!': + if (*cptr1++ != *cptr2++) + return false; + for (;;) { + if (*cptr1 == *cptr2++) { + if (*cptr1++ == '!') { + s32 offset; + + for (offset = 0; *cptr1 != '!';) { + offset = offset * 10 + *cptr1++ - '0'; + } + *offset_result = offset; + return true; + } + } else { + while (*cptr1++ != '!') { } + while (*cptr1++ != '!') { } + if (*cptr1 == 0) + return false; + + cptr2 = catchtype + 1; + } + } + return false; + } + + while ((*cptr1 == 'P' || *cptr1 == 'R') && *cptr1 == *cptr2) { + cptr1++; + cptr2++; + + if (*cptr2 == 'C') { + if (*cptr1 == 'C') + cptr1++; + cptr2++; + } + if (*cptr1 == 'C') + return false; + + if (*cptr2 == 'V') { + if (*cptr1 == 'V') + cptr1++; + cptr2++; + } + if (*cptr1 == 'V') + return false; + } + + for (; *cptr1 == *cptr2; cptr1++, cptr2++) { + if (*cptr1 == 0) + return true; + } + + return false; +} + +class __partial_array_destructor { +private: + void* p; + size_t size; + size_t n; + ConstructorDestructor dtor; + +public: + size_t i; + + __partial_array_destructor(void* array, size_t elementsize, size_t nelements, ConstructorDestructor destructor) + { + p = array; + size = elementsize; + n = nelements; + dtor = destructor; + i = n; + } + + ~__partial_array_destructor() + { + char* ptr; + + if (i < n && dtor) { + for (ptr = (char*)p + size * i; i > 0; i--) { + ptr -= size; + DTORCALL_COMPLETE(dtor, ptr); + } + } + } +}; + +/** + * @note Address: 0x800C19F0 + * @note Size: 0x104 + */ +extern void* __construct_new_array(void* block, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n) +{ + char* ptr; + + if ((ptr = (char*)block) != 0L) { + size_t* p = (size_t*)ptr; + + p[0] = size; + p[1] = n; + ptr += ARRAY_HEADER_SIZE; + + if (ctor) { + __partial_array_destructor pad(ptr, size, n, dtor); + char* p; + + for (pad.i = 0, p = (char*)ptr; pad.i < n; pad.i++, p += size) { + CTORCALL_COMPLETE(ctor, p); + } + } + } + return ptr; +} + +/** + * @note Address: 0x800C183C + * @note Size: 0xFC + */ +extern void __construct_array(void* ptr, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n) +{ + __partial_array_destructor pad(ptr, size, n, dtor); + char* p; + + for (pad.i = 0, p = (char*)ptr; pad.i < n; pad.i++, p += size) { + CTORCALL_COMPLETE(ctor, p); + } +} + +/** + * @note Address: 0x800C17C4 + * @note Size: 0x78 + */ +extern void __destroy_arr(void* block, ConstructorDestructor* dtor, size_t size, size_t n) +{ + char* p; + + for (p = (char*)block + size * n; n > 0; n--) { + p -= size; + DTORCALL_COMPLETE(dtor, p); + } +} + +/** + * @note Address: 0x800C1748 + * @note Size: 0x7C + */ +extern void __destroy_new_array(void* block, ConstructorDestructor dtor) +{ + if (block) { + if (dtor) { + size_t i, objects, objectsize; + char* p; + + objectsize = *(size_t*)((char*)block - ARRAY_HEADER_SIZE); + objects = ((size_t*)((char*)block - ARRAY_HEADER_SIZE))[1]; + p = (char*)block + (objectsize * objects); + + for (i = 0; i < objects; i++) { + p -= objectsize; + DTORCALL_COMPLETE(dtor, p); + } + } + + ::operator delete[]((char*)block - ARRAY_HEADER_SIZE); + } +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +void __destroy_new_array2(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xBC + */ +void __destroy_new_array3(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/Runtime/__init_cpp_exceptions.cpp b/dolphin sdk not yet linked/src/Runtime/__init_cpp_exceptions.cpp new file mode 100644 index 0000000..85be0ab --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/__init_cpp_exceptions.cpp @@ -0,0 +1,46 @@ +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" + +static int fragmentID = -2; + +/** + * @note Address: 0x800C22C4 + * @note Size: 0x8 + */ +ASM static char* GetR2() +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mr r3, r2 + blr +#endif // clang-format on +} +extern "C" { +/** + * @note Address: 0x800C2300 + * @note Size: 0x40 + */ +void __init_cpp_exceptions() +{ + if ((s32)fragmentID == -2) { + char* R2 = GetR2(); + fragmentID = __register_fragment(_eti_init_info, R2); + } +} + +/** + * @note Address: 0x800C22CC + * @note Size: 0x34 + */ +void __fini_cpp_exceptions() +{ + if ((s32)fragmentID != -2) { + __unregister_fragment(fragmentID); + fragmentID = -2; + } +} +} + +DECL_SECT(".ctors") extern void* const __init_cpp_exceptions_reference = __init_cpp_exceptions; +DECL_SECT(".dtors") extern void* const __destroy_global_chain_reference = __destroy_global_chain; +DECL_SECT(".dtors") extern void* const __fini_cpp_exceptions_reference = __fini_cpp_exceptions; diff --git a/dolphin sdk not yet linked/src/Runtime/__mem.c b/dolphin sdk not yet linked/src/Runtime/__mem.c new file mode 100644 index 0000000..84fccd3 --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/__mem.c @@ -0,0 +1,83 @@ +#include "types.h" +#include "PowerPC_EABI_Support/Runtime/__mem.h" +void* memcpy(void* dst, const void* src, size_t n) +{ + const char* p; + char* q; + int rev = ((u32)src < (u32)dst); + + if (!rev) { + + for (p = (const char*)src - 1, q = (char*)dst - 1, n++; --n;) + *++q = *++p; + + } else { + for (p = (const char*)src + n, q = (char*)dst + n, n++; --n;) + *--q = *--p; + } + return (dst); +} + +void __fill_mem(void* dst, int val, u32 n) +{ + u32 v = (u8)val; + u32 i; + + ((u8*)dst) = ((u8*)dst) - 1; + + if (n >= 32) { + i = (~(u32)dst) & 3; + + if (i) { + n -= i; + + do + *++(((u8*)dst)) = v; + while (--i); + } + + if (v) + v |= v << 24 | v << 16 | v << 8; + + ((u32*)dst) = ((u32*)(((u8*)dst) + 1)) - 1; + + i = n >> 5; + + if (i) + do { + *++(((u32*)dst)) = v; + *++(((u32*)dst)) = v; + *++(((u32*)dst)) = v; + *++(((u32*)dst)) = v; + *++(((u32*)dst)) = v; + *++(((u32*)dst)) = v; + *++(((u32*)dst)) = v; + *++(((u32*)dst)) = v; + } while (--i); + + i = (n & 31) >> 2; + + if (i) + do + *++(((u32*)dst)) = v; + while (--i); + + ((u8*)dst) = ((u8*)(((u32*)dst) + 1)) - 1; + + n &= 3; + } + + if (n) + do + *++(((u8*)dst)) = v; + while (--n); + + return; +} + +void* memset(void* dst, int val, size_t n) +{ + __fill_mem(dst, val, n); + + return (dst); +} diff --git a/dolphin sdk not yet linked/src/Runtime/__va_arg.c b/dolphin sdk not yet linked/src/Runtime/__va_arg.c new file mode 100644 index 0000000..e71fd7b --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/__va_arg.c @@ -0,0 +1,48 @@ +#include "types.h" +#include "PowerPC_EABI_Support/Runtime/__va_arg.h" + +/** + * @note Address: 0x800C15F0 + * @note Size: 0xC8 + */ +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/dolphin sdk not yet linked/src/Runtime/global_destructor_chain.c b/dolphin sdk not yet linked/src/Runtime/global_destructor_chain.c new file mode 100644 index 0000000..6553739 --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/global_destructor_chain.c @@ -0,0 +1,33 @@ +#include "PowerPC_EABI_Support/Runtime/global_destructor_chain.h" + +DestructorChain* __global_destructor_chain; + +/** + * @note Address: 0x800C1700 + * @note Size: 0x18 + */ +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; +} + +/** + * @note Address: 0x800C16B8 + * @note Size: 0x48 + */ +void __destroy_global_chain(void) +{ + DestructorChain* iter; + + while ((iter = __global_destructor_chain) != 0) { + __global_destructor_chain = iter->next; + DTORCALL_COMPLETE(iter->destructor, iter->object); + } +} + +DECL_SECT(".dtors") static void* const __destroy_global_chain_reference = __destroy_global_chain; diff --git a/dolphin sdk not yet linked/src/Runtime/ptmf.c b/dolphin sdk not yet linked/src/Runtime/ptmf.c new file mode 100644 index 0000000..576f9ce --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/ptmf.c @@ -0,0 +1,106 @@ +#include "types.h" + +// presumably, ptmf = pointer to member function + +typedef struct PTMF { + s32 this_delta; // self-explanatory + s32 v_offset; // vtable offset + union { + void* f_addr; // function address + s32 ve_offset; // virtual function entry offset (of vtable) + } f_data; +} PTMF; + +const PTMF __ptmf_null = { 0, 0, 0 }; + +s32 __ptmf_test(PTMF* ptmf); +void __ptmf_scall(...); + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void __ptmf_cast(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void __ptmf_scall4(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void __ptmf_call4(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void __ptmf_call(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +void __ptmf_cmpr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C1AF4 + * @note Size: 0x30 + */ +ASM s32 __ptmf_test(register PTMF* ptmf) { +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800C1B24 + * @note Size: 0x28 + */ +ASM void __ptmf_scall(...) +{ +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/Runtime/runtime.c b/dolphin sdk not yet linked/src/Runtime/runtime.c new file mode 100644 index 0000000..eeaf8c5 --- /dev/null +++ b/dolphin sdk not yet linked/src/Runtime/runtime.c @@ -0,0 +1,1035 @@ +#include "PowerPC_EABI_Support/Runtime/runtime.h" + +#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_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); + +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 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 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 u32 __constants[] = { + 0x00000000, 0x00000000, 0x41F00000, 0x00000000, 0x41E00000, 0x00000000, +}; + +/** + * @note Address: 0x800C1B4C + * @note Size: 0x5C + */ +ASM u32 __cvt_fp2unsigned(register f64 d) +{ +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800C1BA8 + * @note Size: 0x4C + */ +ASM static void __save_fpr(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + ENTRY_SAVE_FPR(14) + stfd fp14,-144(save_restore_reg) + ENTRY_SAVE_FPR(15) + stfd fp15,-136(save_restore_reg) + ENTRY_SAVE_FPR(16) + stfd fp16,-128(save_restore_reg) + ENTRY_SAVE_FPR(17) + stfd fp17,-120(save_restore_reg) + ENTRY_SAVE_FPR(18) + stfd fp18,-112(save_restore_reg) + ENTRY_SAVE_FPR(19) + stfd fp19,-104(save_restore_reg) + ENTRY_SAVE_FPR(20) + stfd fp20,-96(save_restore_reg) + ENTRY_SAVE_FPR(21) + stfd fp21,-88(save_restore_reg) + ENTRY_SAVE_FPR(22) + stfd fp22,-80(save_restore_reg) + ENTRY_SAVE_FPR(23) + stfd fp23,-72(save_restore_reg) + ENTRY_SAVE_FPR(24) + stfd fp24,-64(save_restore_reg) + ENTRY_SAVE_FPR(25) + stfd fp25,-56(save_restore_reg) + ENTRY_SAVE_FPR(26) + stfd fp26,-48(save_restore_reg) + ENTRY_SAVE_FPR(27) + stfd fp27,-40(save_restore_reg) + ENTRY_SAVE_FPR(28) + stfd fp28,-32(save_restore_reg) + ENTRY_SAVE_FPR(29) + stfd fp29,-24(save_restore_reg) + ENTRY_SAVE_FPR(30) + stfd fp30,-16(save_restore_reg) + ENTRY_SAVE_FPR(31) + stfd fp31,-8(save_restore_reg) + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800C1BF4 + * @note Size: 0x4C + */ +ASM static void __restore_fpr(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + ENTRY_RESTORE_FPR(14) + lfd fp14,-144(save_restore_reg) + ENTRY_RESTORE_FPR(15) + lfd fp15,-136(save_restore_reg) + ENTRY_RESTORE_FPR(16) + lfd fp16,-128(save_restore_reg) + ENTRY_RESTORE_FPR(17) + lfd fp17,-120(save_restore_reg) + ENTRY_RESTORE_FPR(18) + lfd fp18,-112(save_restore_reg) + ENTRY_RESTORE_FPR(19) + lfd fp19,-104(save_restore_reg) + ENTRY_RESTORE_FPR(20) + lfd fp20,-96(save_restore_reg) + ENTRY_RESTORE_FPR(21) + lfd fp21,-88(save_restore_reg) + ENTRY_RESTORE_FPR(22) + lfd fp22,-80(save_restore_reg) + ENTRY_RESTORE_FPR(23) + lfd fp23,-72(save_restore_reg) + ENTRY_RESTORE_FPR(24) + lfd fp24,-64(save_restore_reg) + ENTRY_RESTORE_FPR(25) + lfd fp25,-56(save_restore_reg) + ENTRY_RESTORE_FPR(26) + lfd fp26,-48(save_restore_reg) + ENTRY_RESTORE_FPR(27) + lfd fp27,-40(save_restore_reg) + ENTRY_RESTORE_FPR(28) + lfd fp28,-32(save_restore_reg) + ENTRY_RESTORE_FPR(29) + lfd fp29,-24(save_restore_reg) + ENTRY_RESTORE_FPR(30) + lfd fp30,-16(save_restore_reg) + ENTRY_RESTORE_FPR(31) + lfd fp31,-8(save_restore_reg) + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800C1C40 + * @note Size: 0x4C + */ +ASM static void __save_gpr(void) { +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800C1C8C + * @note Size: 0x4C + */ +ASM static void __restore_gpr(void) { +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800C1CD8 + * @note Size: 0xEC + */ +ASM void __div2u(void) { +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800C1DC4 + * @note Size: 0x138 + */ +ASM void __div2i(void) { +#ifdef __MWERKS__ // clang-format off + 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 cr0,no_adjust + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800C1EFC + * @note Size: 0xE4 + */ +ASM void __mod2u(void) { +#ifdef __MWERKS__ // clang-format off + 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 + mr r4,r8 + mr r3,r7 + blr +lab9: + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800C1FE0 + * @note Size: 0x10C + */ +ASM void __mod2i(void) { +#ifdef __MWERKS__ // clang-format off + 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: + bge cr7,no_adjust + subfic r4,r4,0 + subfze r3,r3 +no_adjust: + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800C20EC + * @note Size: 0x24 + */ +ASM void __shl2i(void) { +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800C2110 + * @note Size: 0x24 + */ +ASM void __shr2u(void) { +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800C2134 + * @note Size: 0x28 + */ +ASM void __shr2i(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + 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 around + or r4, r4, r10 +around: + sraw r3, r3, r5 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0xB0 + */ +ASM void __cvt_sll_dbl(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + stwu r1,-16(r1) + rlwinm. r5,r3,0,0,0 + beq positive + subfic r4,r4,0 + subfze r3,r3 +positive: + or. r7,r3,r4 + li r6,0 + beq zero + cntlzw r7,r3 + cntlzw r8,r4 + rlwinm r9,r7,26,0,4 + srawi r9,r9,31 + and r9,r9,r8 + add r7,r7,r9 + subfic r8,r7,32 + subic r9,r7,32 + slw r3,r3,r7 + srw r10,r4,r8 + or r3,r3,r10 + slw r10,r4,r9 + or r3,r3,r10 + slw r4,r4,r7 + sub r6,r6,r7 + rlwinm r7,r4,0,21,31 + cmpi cr0,r7,0x400 + addi r6,r6,1086 + blt noround + bgt round + rlwinm. r7,r4,0,20,20 + beq noround +round: + addic r4,r4,0x0800 + addze r3,r3 + addze r6,r6 +noround: + rlwinm r4,r4,21,0,31 + rlwimi r4,r3,21,0,10 + rlwinm r3,r3,21,12,31 + rlwinm r6,r6,20,0,11 + or r3,r6,r3 + or r3,r5,r3 +zero: + stw r3,8(r1) + stw r4,12(r1) + lfd f1,8(r1) + addi r1,r1,16 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800C215C + * @note Size: 0x9C + */ +ASM void __cvt_ull_dbl(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + stwu r1,-0x10(r1) + or. r7,r3,r4 + li r6,0x0 + beq zero + cntlzw r7,r3 + cntlzw r8,r4 + rlwinm r9,r7,0x1a,0x0,0x4 + srawi r9,r9,0x1f + and r9,r9,r8 + add r7,r7,r9 + subfic r8,r7,0x20 + subic 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 + rlwinm r7,r4,0x0,0x15,0x1f + cmpwi r7,0x400 + addi r6,r6,0x43e + blt noround + bgt round + rlwinm. r7,r4,0x0,0x14,0x14 + beq noround +round: + addic r4,r4,0x800 + addze r3,r3 + addze r6,r6 +noround: + rlwinm r4,r4,0x15,0x0,0x1f + rlwimi r4,r3,0x15,0x0,0xa + rlwinm r3,r3,0x15,0xc,0x1f + rlwinm r6,r6,0x14,0x0,0xb + or r3,r6,r3 +zero: + stw r3,0x8(r1) + stw r4,0xc(r1) + lfd f1,0x8(r1) + addi r1,r1,0x10 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +ASM void __cvt_sll_flt(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + stwu r1, -0x10(r1) + clrrwi. r5, r3, 31 + beq positive + subfic r4, r4, 0x0 + subfze r3, r3 +positive: + or. r7, r3, r4 + li r6, 0x0 + beq zero + 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 noround + bgt round + rlwinm. r7, r4, 0, 20, 20 + beq noround +round: + addic r4, r4, 0x800 + addze r3, r3 + addze r6, r6 +noround: + 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 +zero: + stw r3, 0x8(r1) + stw r4, 0xc(r1) + lfd f1, 0x8(r1) + frsp f1, f1 + addi r1, r1, 0x10 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0xA0 + */ +ASM void __cvt_ull_flt(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + stwu r1,-0x10(r1) + or. r7,r3,r4 + li r6,0x0 + beq zero + cntlzw r7,r3 + cntlzw r8,r4 + rlwinm r9,r7,0x1a,0x0,0x4 + srawi r9,r9,0x1f + and r9,r9,r8 + add r7,r7,r9 + subfic r8,r7,0x20 + subic 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 + rlwinm r7,r4,0x0,0x15,0x1f + cmpwi r7,0x400 + addi r6,r6,0x43e + blt noround + bgt round + rlwinm. r7,r4,0x0,0x14,0x14 + beq noround +round: + addic r4,r4,0x800 + addze r3,r3 + addze r6,r6 +noround: + rlwinm r4,r4,0x15,0x0,0x1f + rlwimi r4,r3,0x15,0x0,0xa + rlwinm r3,r3,0x15,0xc,0x1f + rlwinm r6,r6,0x14,0x0,0xb + or r3,r6,r3 +zero: + stw r3,0x8(r1) + stw r4,0xc(r1) + lfd f1,0x8(r1) + frsp f1,f1 + addi r1,r1,0x10 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800C21F8 + * @note Size: 0xCC + */ +ASM void __cvt_dbl_usll(void) +{ +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +#ifdef __cplusplus +} +#endif diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/CircleBuffer.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/CircleBuffer.c new file mode 100644 index 0000000..05d78c2 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/CircleBuffer.c @@ -0,0 +1,101 @@ +#include "PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h" + +/** + * @note Address: 0x800C11F4 + * @note Size: 0x8 + */ +u32 CBGetBytesAvailableForRead(CircleBuffer* cb) { return cb->mBytesToRead; } + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +u32 CBGetBytesAvailableForWrite(CircleBuffer* cb) { return cb->mBytesToWrite; } + +/** + * @note Address: 0x800C11A4 + * @note Size: 0x50 + */ +void CircleBufferInitialize(CircleBuffer* cb, u8* buf, u32 size) +{ + cb->mStartPtr = buf; + cb->mSize = size; + cb->mReadPtr = cb->mStartPtr; + cb->mWritePtr = cb->mStartPtr; + cb->mBytesToRead = 0; + cb->mBytesToWrite = cb->mSize; + MWInitializeCriticalSection(&cb->mSection); +} + +/** + * @note Address: N/A + * @note Size: 0x40 + */ +void CircleBufferTerminate(CircleBuffer* cb) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C109C + * @note Size: 0x108 + */ +int CircleBufferWriteBytes(CircleBuffer* cb, u8* buf, u32 size) +{ + int availSize; + + if (size > cb->mBytesToWrite) { + return -1; + } + MWEnterCriticalSection(&cb->mSection); + availSize = cb->mSize - (cb->mWritePtr - cb->mStartPtr); + if (availSize >= size) { + memcpy(cb->mWritePtr, buf, size); + cb->mWritePtr += size; + } else { + memcpy(cb->mWritePtr, buf, availSize); + memcpy(cb->mStartPtr, buf + availSize, size - availSize); + cb->mWritePtr = cb->mStartPtr + size - availSize; + } + + if (cb->mSize == (cb->mWritePtr - cb->mStartPtr)) { + cb->mWritePtr = cb->mStartPtr; + } + + cb->mBytesToWrite -= size; + cb->mBytesToRead += size; + MWExitCriticalSection(&cb->mSection); + return 0; +} + +/** + * @note Address: 0x800C0F94 + * @note Size: 0x108 + */ +int CircleBufferReadBytes(CircleBuffer* cb, u8* buf, u32 size) +{ + int availSize; + + if (size > cb->mBytesToRead) { + return -1; + } + MWEnterCriticalSection(&cb->mSection); + availSize = cb->mSize - (cb->mReadPtr - cb->mStartPtr); + if (size < availSize) { + memcpy(buf, cb->mReadPtr, size); + cb->mReadPtr += size; + } else { + memcpy(buf, cb->mReadPtr, availSize); + memcpy(buf + availSize, cb->mStartPtr, size - availSize); + cb->mReadPtr = cb->mStartPtr + size - availSize; + } + + if (cb->mSize == (cb->mReadPtr - cb->mStartPtr)) { + cb->mReadPtr = cb->mStartPtr; + } + + cb->mBytesToWrite += size; + cb->mBytesToRead -= size; + MWExitCriticalSection(&cb->mSection); + return 0; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/MWCriticalSection_gc.cpp b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/MWCriticalSection_gc.cpp new file mode 100644 index 0000000..cf5e9b3 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/MWCriticalSection_gc.cpp @@ -0,0 +1,33 @@ +#include "types.h" + +extern "C" { +bool OSRestoreInterrupts(uint); +uint OSDisableInterrupts(); + +/** + * @note Address: 0x800C15EC + * @note Size: 0x4 + */ +void MWInitializeCriticalSection(uint* section) { } + +/** + * @note Address: 0x800C15BC + * @note Size: 0x30 + */ +void MWEnterCriticalSection(uint* section) { *section = OSDisableInterrupts(); } + +/** + * @note Address: 0x800C1598 + * @note Size: 0x24 + */ +void MWExitCriticalSection(uint* section) { OSRestoreInterrupts(*section); } + +/** + * @note Address: N/A + * @note Size: 0x4 + */ +void MWTerminateCriticalSection() +{ + // UNUSED FUNCTION +} +}; diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/MWTrace.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/MWTrace.c new file mode 100644 index 0000000..2f0db5e --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/MWTrace.c @@ -0,0 +1,8 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/** + * @note Address: 0x800C1548 + * @note Size: 0x50 + */ + +void MWTRACE(u8, char*, ...) { } diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/UDP_Stubs.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/UDP_Stubs.c new file mode 100644 index 0000000..5b989cd --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/UDP_Stubs.c @@ -0,0 +1,56 @@ +#include "types.h" +#include "Dolphin/OS/OSInterrupt.h" + +/** + * @note Address: 0x800C0C48 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_initialize(void* flagOut, __OSInterruptHandler handler) { return -1; } + +/** + * @note Address: 0x800C0C40 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_shutdown(void) { return -1; } + +/** + * @note Address: 0x800C0C38 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_open(void) { return -1; } + +/** + * @note Address: 0x800C0C30 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_close(void) { return -1; } + +/** + * @note Address: 0x800C0C28 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_read(u8* dest, int size) { return 0; } + +/** + * @note Address: 0x800C0C20 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_write(const u8* src, int size) { return 0; } + +/** + * @note Address: 0x800C0C18 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_peek(void) { return 0; } + +/** + * @note Address: 0x800C0C10 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_pre_continue(void) { return -1; } + +/** + * @note Address: 0x800C0C08 + * @note Size: 0x8 + */ +WEAKFUNC int udp_cc_post_stop(void) { return -1; } diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/__exception.s b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/__exception.s new file mode 100644 index 0000000..10b5015 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/__exception.s @@ -0,0 +1,476 @@ +.include "macros.inc" + +.section .init, "ax" # 0x80003100 - 0x80005600 + +.global gTRKInterruptVectorTable +gTRKInterruptVectorTable: +.asciz "Metrowerks Target Resident Kernel for PowerPC" +.balign 4 +.fill 0xD0 + +############################################# +# Interrupt vector slot 0x0000 is reserved. # +############################################# + +# Slot 0x0100: System Reset Exception + b __TRK_reset +.fill 0xFC + +# Slot 0x0200: Machine Check Exception +/* 80003354 00000354 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003358 00000358 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 8000335C 0000035C 7C 00 17 AC */ icbi 0, r2 +/* 80003360 00000360 7C 53 02 A6 */ mfdar r2 +/* 80003364 00000364 7C 00 13 AC */ dcbi 0, r2 +/* 80003368 00000368 7C 51 42 A6 */ mfspr r2, 0x111 +/* 8000336C 0000036C 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003370 00000370 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003374 00000374 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003378 00000378 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 8000337C 0000037C 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003380 00000380 7C 60 00 A6 */ mfmsr r3 +/* 80003384 00000384 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003388 00000388 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 8000338C 0000038C 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003390 00000390 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 80003394 00000394 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003398 00000398 38 60 02 00 */ li r3, 0x200 +/* 8000339C 0000039C 4C 00 00 64 */ rfi +.fill 0xB4 + +# Slot 0x0300: DSI Exception +/* 80003454 00000454 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003458 00000458 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000345C 0000045C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003460 00000460 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003464 00000464 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003468 00000468 7C 60 00 A6 */ mfmsr r3 +/* 8000346C 0000046C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003470 00000470 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003474 00000474 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003478 00000478 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000347C 0000047C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003480 00000480 38 60 03 00 */ li r3, 0x300 +/* 80003484 00000484 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x0400: ISI Exception +/* 80003554 00000554 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003558 00000558 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000355C 0000055C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003560 00000560 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003564 00000564 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003568 00000568 7C 60 00 A6 */ mfmsr r3 +/* 8000356C 0000056C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003570 00000570 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003574 00000574 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003578 00000578 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000357C 0000057C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003580 00000580 38 60 04 00 */ li r3, 0x400 +/* 80003584 00000584 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x0500: External Interrupt Exception +/* 80003654 00000654 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003658 00000658 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000365C 0000065C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003660 00000660 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003664 00000664 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003668 00000668 7C 60 00 A6 */ mfmsr r3 +/* 8000366C 0000066C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003670 00000670 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003674 00000674 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003678 00000678 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000367C 0000067C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003680 00000680 38 60 05 00 */ li r3, 0x500 +/* 80003684 00000684 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x0600: Alignment Exception +/* 80003754 00000754 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003758 00000758 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000375C 0000075C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003760 00000760 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003764 00000764 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003768 00000768 7C 60 00 A6 */ mfmsr r3 +/* 8000376C 0000076C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003770 00000770 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003774 00000774 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003778 00000778 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000377C 0000077C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003780 00000780 38 60 06 00 */ li r3, 0x600 +/* 80003784 00000784 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x0700: Program Exception +/* 80003854 00000854 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003858 00000858 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000385C 0000085C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003860 00000860 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003864 00000864 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003868 00000868 7C 60 00 A6 */ mfmsr r3 +/* 8000386C 0000086C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003870 00000870 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003874 00000874 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003878 00000878 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000387C 0000087C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003880 00000880 38 60 07 00 */ li r3, 0x700 +/* 80003884 00000884 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x0800: Floating Point Unavailable Exception +/* 80003954 00000954 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003958 00000958 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000395C 0000095C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003960 00000960 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003964 00000964 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003968 00000968 7C 60 00 A6 */ mfmsr r3 +/* 8000396C 0000096C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003970 00000970 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003974 00000974 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003978 00000978 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000397C 0000097C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003980 00000980 38 60 08 00 */ li r3, 0x800 +/* 80003984 00000984 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x0900: Decrementer Exception +/* 80003A54 00000A54 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003A58 00000A58 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003A5C 00000A5C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003A60 00000A60 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003A64 00000A64 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003A68 00000A68 7C 60 00 A6 */ mfmsr r3 +/* 80003A6C 00000A6C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003A70 00000A70 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003A74 00000A74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003A78 00000A78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 80003A7C 00000A7C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003A80 00000A80 38 60 09 00 */ li r3, 0x900 +/* 80003A84 00000A84 4C 00 00 64 */ rfi +.fill 0xCC + +###################################################### +# Interrupt vector slots 0x0A00 & 0x0B00 are reserved. +.fill 0x100 +.fill 0x100 +###################################################### + +# Slot 0x0C00: System Call Exception +/* 80003D54 00000D54 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003D58 00000D58 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003D5C 00000D5C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003D60 00000D60 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003D64 00000D64 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003D68 00000D68 7C 60 00 A6 */ mfmsr r3 +/* 80003D6C 00000D6C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003D70 00000D70 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003D74 00000D74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003D78 00000D78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 80003D7C 00000D7C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003D80 00000D80 38 60 0C 00 */ li r3, 0xc00 +/* 80003D84 00000D84 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x0D00: Trace Exception +/* 80003E54 00000E54 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003E58 00000E58 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003E5C 00000E5C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003E60 00000E60 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003E64 00000E64 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003E68 00000E68 7C 60 00 A6 */ mfmsr r3 +/* 80003E6C 00000E6C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003E70 00000E70 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003E74 00000E74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003E78 00000E78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 80003E7C 00000E7C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003E80 00000E80 38 60 0D 00 */ li r3, 0xd00 +/* 80003E84 00000E84 4C 00 00 64 */ rfi +.fill 0xCC + +############################################################################ +# Slot 0x0E00 is usually for the Floating Point Assist Exception Handler, # +# however that exception is not implemented in the PPC 750CL architecture. # +############################################################################ + +# Slot 0x0F00: Performance Monitor Exception +/* 80003F54 00000F54 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003F58 00000F58 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003F5C 00000F5C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003F60 00000F60 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003F64 00000F64 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003F68 00000F68 7C 60 00 A6 */ mfmsr r3 +/* 80003F6C 00000F6C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003F70 00000F70 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003F74 00000F74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80003F78 00000F78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 80003F7C 00000F7C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003F80 00000F80 38 60 0E 00 */ li r3, 0xe00 +/* 80003F84 00000F84 4C 00 00 64 */ rfi +.fill 0xCC + +################################################################################## +# Interrupt vector slots 0x1000 through 0x1200 are not implemented in the 750CL. # +################################################################################## + +# Slot 0x1300: Instruction Address Breakpoint Exception +/* 80004054 00001054 48 00 00 54 */ b .L_800040A8 +.fill 0x1C +/* 80004074 00001074 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004078 00001078 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000407C 0000107C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004080 00001080 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004084 00001084 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004088 00001088 7C 60 00 A6 */ mfmsr r3 +/* 8000408C 0000108C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004090 00001090 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004094 00001094 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80004098 00001098 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000409C 0000109C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800040A0 000010A0 38 60 0F 20 */ li r3, 0xf20 +/* 800040A4 000010A4 4C 00 00 64 */ rfi +.L_800040A8: +/* 800040A8 000010A8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800040AC 000010AC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800040B0 000010B0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800040B4 000010B4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800040B8 000010B8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800040BC 000010BC 7C 60 00 A6 */ mfmsr r3 +/* 800040C0 000010C0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800040C4 000010C4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800040C8 000010C8 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 800040CC 000010CC 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 800040D0 000010D0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800040D4 000010D4 38 60 0F 00 */ li r3, 0xf00 +/* 800040D8 000010D8 4C 00 00 64 */ rfi +.fill 0x78 + +# Slot 0x1400: System Management Interrupt Exception +/* 80004154 00001154 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004158 00001158 7C 40 00 26 */ mfcr r2 +/* 8000415C 0000115C 7C 52 43 A6 */ mtspr 0x112, r2 +/* 80004160 00001160 7C 40 00 A6 */ mfmsr r2 +/* 80004164 00001164 74 42 00 02 */ andis. r2, r2, 2 +/* 80004168 00001168 41 82 00 1C */ beq .L_80004184 +/* 8000416C 0000116C 7C 40 00 A6 */ mfmsr r2 +/* 80004170 00001170 6C 42 00 02 */ xoris r2, r2, 2 +/* 80004174 00001174 7C 00 04 AC */ sync 0 +/* 80004178 00001178 7C 40 01 24 */ mtmsr r2 +/* 8000417C 0000117C 7C 00 04 AC */ sync 0 +/* 80004180 00001180 7C 51 43 A6 */ mtspr 0x111, r2 +.L_80004184: +/* 80004184 00001184 7C 52 42 A6 */ mfspr r2, 0x112 +/* 80004188 00001188 7C 4F F1 20 */ mtcrf 0xff, r2 +/* 8000418C 0000118C 7C 51 42 A6 */ mfspr r2, 0x111 +/* 80004190 00001190 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004194 00001194 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004198 00001198 7C 93 43 A6 */ mtspr 0x113, r4 +/* 8000419C 0000119C 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800041A0 000011A0 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800041A4 000011A4 7C 60 00 A6 */ mfmsr r3 +/* 800041A8 000011A8 60 63 00 30 */ ori r3, r3, 0x30 +/* 800041AC 000011AC 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800041B0 000011B0 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 800041B4 000011B4 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 800041B8 000011B8 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800041BC 000011BC 38 60 10 00 */ li r3, 0x1000 +/* 800041C0 000011C0 4C 00 00 64 */ rfi +.fill 0x90 + + +############################################################################## +# Interrupt vector slots 0x1500 and 0x1600 are not implemented in the 750CL. # +############################################################################## + +# Slot 0x1700: Thermal-Management Interrupt Exception +/* 80004254 00001254 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004258 00001258 7C 40 00 26 */ mfcr r2 +/* 8000425C 0000125C 7C 52 43 A6 */ mtspr 0x112, r2 +/* 80004260 00001260 7C 40 00 A6 */ mfmsr r2 +/* 80004264 00001264 74 42 00 02 */ andis. r2, r2, 2 +/* 80004268 00001268 41 82 00 1C */ beq .L_80004284 +/* 8000426C 0000126C 7C 40 00 A6 */ mfmsr r2 +/* 80004270 00001270 6C 42 00 02 */ xoris r2, r2, 2 +/* 80004274 00001274 7C 00 04 AC */ sync 0 +/* 80004278 00001278 7C 40 01 24 */ mtmsr r2 +/* 8000427C 0000127C 7C 00 04 AC */ sync 0 +/* 80004280 00001280 7C 51 43 A6 */ mtspr 0x111, r2 +.L_80004284: +/* 80004284 00001284 7C 52 42 A6 */ mfspr r2, 0x112 +/* 80004288 00001288 7C 4F F1 20 */ mtcrf 0xff, r2 +/* 8000428C 0000128C 7C 51 42 A6 */ mfspr r2, 0x111 +/* 80004290 00001290 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004294 00001294 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004298 00001298 7C 93 43 A6 */ mtspr 0x113, r4 +/* 8000429C 0000129C 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800042A0 000012A0 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800042A4 000012A4 7C 60 00 A6 */ mfmsr r3 +/* 800042A8 000012A8 60 63 00 30 */ ori r3, r3, 0x30 +/* 800042AC 000012AC 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800042B0 000012B0 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 800042B4 000012B4 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 800042B8 000012B8 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800042BC 000012BC 38 60 11 00 */ li r3, 0x1100 +/* 800042C0 000012C0 4C 00 00 64 */ rfi +.fill 0x90 + +# Slot 0x1800(?) +/* 80004354 00001354 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004358 00001358 7C 40 00 26 */ mfcr r2 +/* 8000435C 0000135C 7C 52 43 A6 */ mtspr 0x112, r2 +/* 80004360 00001360 7C 40 00 A6 */ mfmsr r2 +/* 80004364 00001364 74 42 00 02 */ andis. r2, r2, 2 +/* 80004368 00001368 41 82 00 1C */ beq .L_80004384 +/* 8000436C 0000136C 7C 40 00 A6 */ mfmsr r2 +/* 80004370 00001370 6C 42 00 02 */ xoris r2, r2, 2 +/* 80004374 00001374 7C 00 04 AC */ sync 0 +/* 80004378 00001378 7C 40 01 24 */ mtmsr r2 +/* 8000437C 0000137C 7C 00 04 AC */ sync 0 +/* 80004380 00001380 7C 51 43 A6 */ mtspr 0x111, r2 +.L_80004384: +/* 80004384 00001384 7C 52 42 A6 */ mfspr r2, 0x112 +/* 80004388 00001388 7C 4F F1 20 */ mtcrf 0xff, r2 +/* 8000438C 0000138C 7C 51 42 A6 */ mfspr r2, 0x111 +/* 80004390 00001390 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004394 00001394 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004398 00001398 7C 93 43 A6 */ mtspr 0x113, r4 +/* 8000439C 0000139C 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800043A0 000013A0 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800043A4 000013A4 7C 60 00 A6 */ mfmsr r3 +/* 800043A8 000013A8 60 63 00 30 */ ori r3, r3, 0x30 +/* 800043AC 000013AC 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800043B0 000013B0 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 800043B4 000013B4 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 800043B8 000013B8 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800043BC 000013BC 38 60 12 00 */ li r3, 0x1200 +/* 800043C0 000013C0 4C 00 00 64 */ rfi +.fill 0x90 + +# Slot 0x1900(?) +/* 80004454 00001454 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004458 00001458 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000445C 0000145C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004460 00001460 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004464 00001464 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004468 00001468 7C 60 00 A6 */ mfmsr r3 +/* 8000446C 0000146C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004470 00001470 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004474 00001474 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80004478 00001478 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000447C 0000147C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004480 00001480 38 60 13 00 */ li r3, 0x1300 +/* 80004484 00001484 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x1A00(?) +/* 80004554 00001554 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004558 00001558 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000455C 0000155C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004560 00001560 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004564 00001564 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004568 00001568 7C 60 00 A6 */ mfmsr r3 +/* 8000456C 0000156C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004570 00001570 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004574 00001574 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80004578 00001578 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000457C 0000157C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004580 00001580 38 60 14 00 */ li r3, 0x1400 +/* 80004584 00001584 4C 00 00 64 */ rfi +.fill 0x1CC + +# Slot 0x1B00(?) +/* 80004754 00001754 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004758 00001758 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000475C 0000175C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004760 00001760 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004764 00001764 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004768 00001768 7C 60 00 A6 */ mfmsr r3 +/* 8000476C 0000176C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004770 00001770 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004774 00001774 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80004778 00001778 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000477C 0000177C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004780 00001780 38 60 16 00 */ li r3, 0x1600 +/* 80004784 00001784 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x1C00(?) +/* 80004854 00001854 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004858 00001858 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000485C 0000185C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004860 00001860 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004864 00001864 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004868 00001868 7C 60 00 A6 */ mfmsr r3 +/* 8000486C 0000186C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004870 00001870 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004874 00001874 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80004878 00001878 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000487C 0000187C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004880 00001880 38 60 17 00 */ li r3, 0x1700 +/* 80004884 00001884 4C 00 00 64 */ rfi +.fill 0x4CC + +# Slot 0x1D00(?) +/* 80004D54 00001D54 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004D58 00001D58 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004D5C 00001D5C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004D60 00001D60 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004D64 00001D64 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004D68 00001D68 7C 60 00 A6 */ mfmsr r3 +/* 80004D6C 00001D6C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004D70 00001D70 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004D74 00001D74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80004D78 00001D78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 80004D7C 00001D7C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004D80 00001D80 38 60 1C 00 */ li r3, 0x1c00 +/* 80004D84 00001D84 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x1E00(?) +/* 80004E54 00001E54 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004E58 00001E58 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004E5C 00001E5C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004E60 00001E60 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004E64 00001E64 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004E68 00001E68 7C 60 00 A6 */ mfmsr r3 +/* 80004E6C 00001E6C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004E70 00001E70 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004E74 00001E74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80004E78 00001E78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 80004E7C 00001E7C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004E80 00001E80 38 60 1D 00 */ li r3, 0x1d00 +/* 80004E84 00001E84 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x1F00(?) +/* 80004F54 00001F54 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004F58 00001F58 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004F5C 00001F5C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004F60 00001F60 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004F64 00001F64 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004F68 00001F68 7C 60 00 A6 */ mfmsr r3 +/* 80004F6C 00001F6C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004F70 00001F70 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004F74 00001F74 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80004F78 00001F78 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 80004F7C 00001F7C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004F80 00001F80 38 60 1E 00 */ li r3, 0x1e00 +/* 80004F84 00001F84 4C 00 00 64 */ rfi +.fill 0xCC + +# Slot 0x2000(?) +/* 80005054 00002054 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80005058 00002058 7C 72 43 A6 */ mtspr 0x112, r3 +/* 8000505C 0000205C 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80005060 00002060 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80005064 00002064 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80005068 00002068 7C 60 00 A6 */ mfmsr r3 +/* 8000506C 0000206C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80005070 00002070 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80005074 00002074 3C 60 80 0B */ lis r3, TRKInterruptHandler@h +/* 80005078 00002078 60 63 DE F4 */ ori r3, r3, TRKInterruptHandler@l +/* 8000507C 0000207C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80005080 00002080 38 60 1F 00 */ li r3, 0x1f00 +/* 80005084 00002084 4C 00 00 64 */ rfi +.global gTRKInterruptVectorTableEnd +gTRKInterruptVectorTableEnd: diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/ddh/main.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/ddh/main.c new file mode 100644 index 0000000..8010be2 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/ddh/main.c @@ -0,0 +1,176 @@ +#include "types.h" +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "Dolphin/AmcExi2Stubs.h" +#include "PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h" + +#define DDH_BUF_SIZE (0x800) + +static CircleBuffer gRecvCB; +static u8 gRecvBuf[DDH_BUF_SIZE]; +static BOOL gIsInitialized; + +/** + * @note Address: 0x800C0F0C + * @note Size: 0x88 + */ +int ddh_cc_initialize(void* inputPendingPtrRef, AmcEXICallback monitorCallback) +{ + MWTRACE(1, "CALLING EXI2_Init\n"); + EXI2_Init(inputPendingPtrRef, monitorCallback); + MWTRACE(1, "DONE CALLING EXI2_Init\n"); + CircleBufferInitialize(&gRecvCB, gRecvBuf, DDH_BUF_SIZE); + return 0; +} + +/** + * @note Address: 0x800C0F04 + * @note Size: 0x8 + */ +int ddh_cc_shutdown() { return 0; } + +/** + * @note Address: 0x800C0EE0 + * @note Size: 0x24 + */ +int ddh_cc_open() +{ + if (gIsInitialized) { + return DDH_ERR_ALREADY_INITIALIZED; + } + + gIsInitialized = TRUE; + return 0; +} + +/** + * @note Address: 0x800C0ED8 + * @note Size: 0x8 + */ +int ddh_cc_close() { return 0; } + +/** + * @note Address: 0x800C0DEC + * @note Size: 0xEC + */ +int ddh_cc_read(u8* data, int size) +{ + u8 buff[DDH_BUF_SIZE]; + int originalDataSize; + u32 result; + int expectedDataSize; + int poll; + + result = 0; + if (!gIsInitialized) { + return DDH_ERR_NOT_INITIALIZED; + } + + MWTRACE(1, "Expected packet size : 0x%08x (%ld)\n", size, size); + + originalDataSize = expectedDataSize = size; + while ((u32)CBGetBytesAvailableForRead(&gRecvCB) < expectedDataSize) { + result = 0; + + poll = EXI2_Poll(); + if (poll != 0) { + result = EXI2_ReadN(buff, poll); + if (result == 0) { + CircleBufferWriteBytes(&gRecvCB, buff, poll); + } + } + } + + if (result == 0) { + CircleBufferReadBytes(&gRecvCB, data, originalDataSize); + } else { + MWTRACE(8, "cc_read : error reading bytes from EXI2 %ld\n", result); + } + + return result; +} + +/** + * @note Address: 0x800C0D2C + * @note Size: 0xC0 + */ +int ddh_cc_write(const u8* bytes, int length) +{ + int exi2Len; + int n_copy; + u32 hexCopy; + + hexCopy = (u32)bytes; + n_copy = length; + + if (gIsInitialized == FALSE) { + MWTRACE(8, "cc not initialized\n"); + return DDH_ERR_NOT_INITIALIZED; + } + + MWTRACE(8, "cc_write : Output data 0x%08x %ld bytes\n", bytes, length); + + while (n_copy > 0) { + MWTRACE(1, "cc_write sending %ld bytes\n", n_copy); + exi2Len = EXI2_WriteN((const void*)hexCopy, n_copy); + if (exi2Len == AMC_EXI_NO_ERROR) { + break; + } + hexCopy += exi2Len; + n_copy -= exi2Len; + } + + return 0; +} + +/** + * @note Address: 0x800C0D08 + * @note Size: 0x24 + */ +int ddh_cc_pre_continue() +{ + EXI2_Unreserve(); + return 0; +} + +/** + * @note Address: 0x800C0CE4 + * @note Size: 0x24 + */ +int ddh_cc_post_stop() +{ + EXI2_Reserve(); + return 0; +} + +/** + * @note Address: 0x800C0C74 + * @note Size: 0x70 + */ +int ddh_cc_peek() +{ + int poll; + u8 buff[DDH_BUF_SIZE]; + + poll = EXI2_Poll(); + if (poll <= 0) { + return 0; + } + + if (EXI2_ReadN(buff, poll) == 0) { + CircleBufferWriteBytes(&gRecvCB, buff, poll); + } else { + return DDH_ERR_READ_ERROR; + } + + return poll; +} + +/** + * @note Address: 0x800C0C50 + * @note Size: 0x24 + */ +int ddh_cc_initinterrupts() +{ + EXI2_EnableInterrupts(); + return 0; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dispatch.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dispatch.c new file mode 100644 index 0000000..87d6fdd --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dispatch.c @@ -0,0 +1,66 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/** + * @note Address: 0x800BC57C + * @note Size: 0x8 + */ +DSError TRKInitializeDispatcher(void) { return DS_NoError; } + +/** + * @note Address: 0x800BC40C + * @note Size: 0x170 + */ +DSError TRKDispatchMessage(MessageBuffer* msg) +{ + u32 err; + + err = DS_DispatchError; + TRKSetBufferPosition(msg, 0); + MWTRACE(1, "Dispatch command 0x%08x\n", msg->data[4]); + switch (msg->data[4]) { + case DSMSG_Connect: + err = TRKDoConnect(msg); + break; + case DSMSG_Disconnect: + err = TRKDoDisconnect(msg); + break; + case DSMSG_Reset: + err = TRKDoReset(msg); + break; + case DSMSG_Override: + err = TRKDoOverride(msg); + break; + case DSMSG_Versions: + err = TRKDoVersions(msg); + break; + case DSMSG_SupportMask: + err = TRKDoSupportMask(msg); + break; + case DSMSG_ReadMemory: + err = TRKDoReadMemory(msg); + break; + case DSMSG_WriteMemory: + err = TRKDoWriteMemory(msg); + break; + case DSMSG_ReadRegisters: + err = TRKDoReadRegisters(msg); + break; + case DSMSG_WriteRegisters: + err = TRKDoWriteRegisters(msg); + break; + case DSMSG_Continue: + err = TRKDoContinue(msg); + break; + case DSMSG_Step: + err = TRKDoStep(msg); + break; + case DSMSG_Stop: + err = TRKDoStop(msg); + break; + case DSMSG_SetOption: + err = TRKDoSetOption(msg); + break; + } + MWTRACE(1, "Dispatch complete err = %ld\n", err); + return err; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dolphin_trk.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dolphin_trk.c new file mode 100644 index 0000000..6f691e5 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dolphin_trk.c @@ -0,0 +1,371 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "Dolphin/ar.h" + +extern u8 _db_stack_addr[]; +#define EXCEPTIONMASK_ADDR 0x80000044 + +extern void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu); + +static u32 lc_base; + +static u32 TRK_ISR_OFFSETS[15] = { PPC_SystemReset, + PPC_MachineCheck, + PPC_DataStorage, + PPC_InstructionStorage, + PPC_ExternalInterrupt, + PPC_Alignment, + PPC_Program, + PPC_FloatingPointUnavaiable, + PPC_Decrementer, + PPC_SystemCall, + PPC_Trace, + PPC_PerformanceMonitor, + PPC_InstructionAddressBreakpoint, + PPC_SystemManagementInterrupt, + PPC_ThermalManagementInterrupt }; + +DECL_SECT(".init") void __TRK_reset() { OSResetSystem(FALSE, 0, FALSE); } + +/** + * @note Address: 0x800C03EC + * @note Size: 0x20 + */ +void EnableMetroTRKInterrupts(void) { EnableEXI2Interrupts(); } + +/** + * @note Address: 0x800C0394 + * @note Size: 0x58 + */ +u32 TRKTargetTranslate(u32 val) +{ + if (val >= lc_base && val < lc_base + 0x4000) { + if (((u32*)(&gTRKCPUState.Extended1))[36] & 3) + return val; + } + + if (val >= 0x7E000000 && val <= 0x80000000) { + return val; + } + + return (val & 0x3FFFFFFF) | 0x80000000; +} + +/** + * @note Address: N/A + * @note Size: 0xB0 + */ +void TRK_copy_vector(u32 offset) +{ + void* destPtr = (void*)TRKTargetTranslate(offset); + TRK_memcpy(destPtr, (void*)(gTRKInterruptVectorTable + offset), 0x100); + TRK_flush_cache(destPtr, 0x100); +} + +/** + * @note Address: 0x800C0268 + * @note Size: 0x12C + */ +void __TRK_copy_vectors(void) +{ + u32 r3 = lc_base; + u32* isrOffsetPtr; + int i; + u32 r29; + + if (r3 <= 0x44 && r3 + 0x4000 > 0x44 && gTRKCPUState.Extended1.DBAT3U_ & 3) { + r3 = 0x44; + } else { + r3 = EXCEPTIONMASK_ADDR; + } + + i = 0; + r29 = *(u32*)r3; + isrOffsetPtr = TRK_ISR_OFFSETS; + + do { + if ((r29 & (1 << i)) && i != 4) { + TRK_copy_vector(isrOffsetPtr[i]); + } + + i++; + } while (i <= 14); +} + +/** + * @note Address: 0x800C021C + * @note Size: 0x4C + */ +DSError TRKInitializeTarget() +{ + gTRKState.isStopped = TRUE; + gTRKState.msr = __TRK_get_MSR(); + lc_base = 0xE0000000; + return DS_NoError; +} + +#define __dcbi(a, b) asm { dcbi a, b } +#define __dcbfASM(a, b) asm { dcbf a, b } + +/** + * @note Address: 0x800C00E8 + * @note Size: 0x134 + */ +void TRK__read_aram(register int c, register u32 p2, void* p3) +{ + u32 err; + int i; + register int counter; + u16 r; + u32 g; + u32 x; + u32 size; + + if ((size_t)p2 < 0x4000 || p2 + *(u32*)p3 > 0x8000000) { + return; + } + + x = p2 & ~0x1F; + size = *(u32*)p3 + (p2 & 0x1F); + size = OSRoundUp32B(size); + counter = 0; + + for (i = 0; i < size; i += 0x20) { + __dcbi(counter, c); + counter += 0x20; + } + + do { + err = ARGetDMAStatus(); + } while (err); + + r = __ARGetInterruptStatus(); + g = 0x8000000; + __ARClearInterrupt(); + + ARStartDMA(1, c, x, size); + + while (!__ARGetInterruptStatus()) { } + + if (!r) { + __ARClearInterrupt(); + } +} + +/** + * @note Address: N/A + * @note Size: 0x5C + */ +void __read_aram_1block(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BFEFC + * @note Size: 0x1EC + */ +void TRK__write_aram(register int c, register u32 p2, void* p3) +{ + u8 buff[32] ATTRIBUTE_ALIGN(32); + u32 err; + register int count = c; + register u32 bf; + u32 uVar1; + u32 size; + u16 r; + register u32 g; + register int counter; + u32 i; + + if ((size_t)p2 < 0x4000 || p2 + *(u32*)p3 > 0x8000000) { + return; + } + + uVar1 = p2 & ~0x1f; + counter = 0; + size = *(u32*)p3 + (p2 & 0x1f); + size = OSRoundUp32B(size); + + for (i = 0; i < size; i += 0x20) { + __dcbf((void*)counter, count); + counter += 0x20; + } + + do { + err = ARGetDMAStatus(); + } while (err); + + r = __ARGetInterruptStatus(); + g = 0x8000000; + + counter = p2 & 0x1f; + if (counter) { + g = uVar1; + bf = (u32)buff; + __dcbi(r0, bf); + __ARClearInterrupt(); + + ARStartDMA(1, bf, uVar1, 0x20); + + while (!__ARGetInterruptStatus()) { } + + TRK_memcpy((void*)c, buff, counter); + __dcbfASM(r0, c); + } + + p2 += *(u32*)p3; + counter = p2 & 0x1f; + if (counter) { + u32 val = p2 & ~0x1F; + if (val != g) { + bf = (u32)buff; + __dcbi(r0, bf); + __ARClearInterrupt(); + ARStartDMA(1, bf, val, 0x20); + + while (!__ARGetInterruptStatus()) { } + } + g = c + p2; + TRK_memcpy((void*)g, (void*)(buff + counter), 0x20 - counter); + + __dcbfASM(r0, g); + } + __sync(); + __ARClearInterrupt(); + ARStartDMA(0, c, uVar1, size); + if (!r) { + while (!__ARGetInterruptStatus()) { } + + __ARClearInterrupt(); + } +} + +/** + * @note Address: 0x800BFDD0 + * @note Size: 0x98 + */ +ASM void InitMetroTRK(void) +{ +#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 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800BFE68 + * @note Size: 0x94 + */ +ASM void InitMetroTRK_BBA(void) +{ +#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) + //Turn on external interrupts + mfmsr r4 + ori r3, r4, (1 << (31 - 16)) + mtmsr r3 + mtsrr1 r4 //Copy original 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 the stack pointer + lis r1, _db_stack_addr@h + ori r1, r1, _db_stack_addr@l + li r3, 2 + bl InitMetroTRKCommTable //Initialize comm table as BBA hardware + /* + If InitMetroTRKCommTable returned 1 (failure), something went wrong + or whatever reason. If everything goes as expected, 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) + blr +initCommTableSuccess: + b TRK_main //Jump to TRK_main + blr +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c new file mode 100644 index 0000000..4c1401a --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/dolphin_trk_glue.c @@ -0,0 +1,248 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "Dolphin/os.h" + +BOOL _MetroTRK_Has_Framing; // UNUSED +// GPVE01 _MetroTRK_Has_Framing = .bss:0x804F4814; // type:object size:0x4 scope:global align:4 +// GPVE01_D17 _MetroTRK_Has_Framing = .bss:0x804F4754; // type:object size:0x4 scope:global align:4 +u8 TRK_Use_BBA; + +DBCommTable gDBCommTable = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + +/** + * @note Address: 0x800C0984 + * @note Size: 0x38 + */ +void TRKEXICallBack(s16 r3, OSContext* ctx) +{ + OSEnableScheduler(); + TRKLoadContext(ctx, 0x500); +} + +/** + * @note Address: 0x800C0718 + * @note Size: 0x26C + */ +int InitMetroTRKCommTable(int hwId) +{ + int result = 1; + OSReport("Devkit set to : %ld\n", hwId); + TRK_Use_BBA = 0; + + if (hwId == HARDWARE_BBA) { // BBA hardware + OSReport("MetroTRK : Set to BBA\n"); + // Initialize gDBCommTable + TRK_Use_BBA = 1; + gDBCommTable.initialize_func = udp_cc_initialize; + gDBCommTable.open_func = udp_cc_open; + gDBCommTable.close_func = udp_cc_close; + gDBCommTable.read_func = udp_cc_read; + gDBCommTable.write_func = udp_cc_write; + gDBCommTable.shutdown_func = udp_cc_shutdown; + gDBCommTable.peek_func = udp_cc_peek; + gDBCommTable.pre_continue_func = udp_cc_pre_continue; + gDBCommTable.post_stop_func = udp_cc_post_stop; + gDBCommTable.init_interrupts_func = nullptr; + return 0; + } + + if (hwId == HARDWARE_GDEV) { // NDEV hardware + OSReport("MetroTRK : Set to GDEV hardware\n"); + // Initialize gDBCommTable + result = Hu_IsStub(); + gDBCommTable.initialize_func = gdev_cc_initialize; + gDBCommTable.open_func = gdev_cc_open; + gDBCommTable.close_func = gdev_cc_close; + gDBCommTable.read_func = gdev_cc_read; + gDBCommTable.write_func = gdev_cc_write; + gDBCommTable.shutdown_func = gdev_cc_shutdown; + gDBCommTable.peek_func = gdev_cc_peek; + gDBCommTable.pre_continue_func = gdev_cc_pre_continue; + gDBCommTable.post_stop_func = gdev_cc_post_stop; + gDBCommTable.init_interrupts_func = gdev_cc_initinterrupts; + + } else if (hwId == HARDWARE_AMC_DDH) { + OSReport("MetroTRK : Set to AMC DDH hardware\n"); + result = AMC_IsStub(); + // Initialize gDBCommTable + gDBCommTable.initialize_func = ddh_cc_initialize; + gDBCommTable.open_func = ddh_cc_open; + gDBCommTable.close_func = ddh_cc_close; + gDBCommTable.read_func = ddh_cc_read; + gDBCommTable.write_func = ddh_cc_write; + gDBCommTable.shutdown_func = ddh_cc_shutdown; + gDBCommTable.peek_func = ddh_cc_peek; + gDBCommTable.pre_continue_func = ddh_cc_pre_continue; + gDBCommTable.post_stop_func = ddh_cc_post_stop; + gDBCommTable.init_interrupts_func = ddh_cc_initinterrupts; + + } else { // unknown hardware + OSReport("MetroTRK : Set to UNKNOWN hardware. (%ld)\n", hwId); + OSReport("MetroTRK : Invalid hardware ID passed from OS\n"); + OSReport("MetroTRK : Defaulting to GDEV Hardware\n"); + } + + return result; +} + +/** + * @note Address: 0x800C06C8 + * @note Size: 0x50 + */ +DSError TRKInitializeIntDrivenUART(u32, u32, u32, void* r5) +{ + gDBCommTable.initialize_func(r5, TRKEXICallBack); + gDBCommTable.open_func(); + return DS_NoError; +} + +/** + * @note Address: 0x800C0680 + * @note Size: 0x48 + */ +void EnableEXI2Interrupts(void) +{ + if (!TRK_Use_BBA) { + if (gDBCommTable.init_interrupts_func != nullptr) { + gDBCommTable.init_interrupts_func(); + } + } +} + +/** + * @note Address: 0x800C0650 + * @note Size: 0x30 + */ +int TRKPollUART(void) { return gDBCommTable.peek_func(); } + +/** + * @note Address: 0x800C0614 + * @note Size: 0x3C + */ +UARTError TRKReadUARTN(void* bytes, u32 length) +{ + int readErr = gDBCommTable.read_func(bytes, length); + return ((-readErr | readErr) >> 31); +} + +/** + * @note Address: 0x800C05D8 + * @note Size: 0x3C + */ +UARTError TRKWriteUARTN(const void* bytes, u32 length) +{ + int writeErr = gDBCommTable.write_func(bytes, length); + return ((-writeErr | writeErr) >> 31); +} + +/** + * @note Address: N/A + * @note Size: 0xE0 + */ +void WriteUARTFlush(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void WriteUART1(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xF0 + */ +void TRKReadUARTPoll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800C05A8 + * @note Size: 0x30 + */ +void ReserveEXI2Port(void) { gDBCommTable.post_stop_func(); } + +/** + * @note Address: 0x800C0578 + * @note Size: 0x30 + */ +void UnreserveEXI2Port(void) { gDBCommTable.pre_continue_func(); } + +/** + * @note Address: 0x800C0548 + * @note Size: 0x30 + */ +void TRK_board_display(char* str) { OSReport("%s\n", str); } + +/** + * @note Address: 0x800C04F0 + * @note Size: 0x58 + */ +DSError InitializeProgramEndTrap(void) +{ + static const u32 EndofProgramInstruction = 'END'; + + u8* endOfProgramInstructionBytes = (u8*)&EndofProgramInstruction; + u8* ppcHaltPtr = (u8*)PPCHalt; + TRK_memcpy(ppcHaltPtr + 4, endOfProgramInstructionBytes, 4); + ICInvalidateRange(ppcHaltPtr + 4, 4); + DCFlushRange(ppcHaltPtr + 4, 4); +} + +/** + * @note Address: 0x800C04EC + * @note Size: 0x4 + */ +void TRKUARTInterruptHandler(void) { } + +/** + * @note Address: 0x800C0464 + * @note Size: 0x88 + */ +ASM void TRKLoadContext(OSContext* ctx, u32 r4) +{ +#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 L_802CC24C + rlwinm r5, r5, 0, 0x1f, 0x1d + sth r5, OSContext.state(r3) + lmw r5, OSContext.gpr[5](r3) + b L_802CC250 +L_802CC24C: + lmw r13, OSContext.gpr[13](r3) +L_802CC250: + 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 +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/flush_cache.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/flush_cache.c new file mode 100644 index 0000000..456d1e3 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/flush_cache.c @@ -0,0 +1,27 @@ +#include "types.h" + +/** + * @note Address: 0x800BDDB8 + * @note Size: 0x38 + */ +ASM void TRK_flush_cache(u32 param_1, int param_2) +{ +#ifdef __MWERKS__ // clang-format off + 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 + 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/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/gdev/main.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/gdev/main.c new file mode 100644 index 0000000..4fa8875 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/gdev/main.c @@ -0,0 +1,175 @@ +#include "Dolphin/db.h" +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "Dolphin/AmcExi2Stubs.h" +#include "PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h" + +#define GDEV_BUF_SIZE (0x500) + +static CircleBuffer gRecvCB; +static u8 gRecvBuf[GDEV_BUF_SIZE]; +static BOOL gIsInitialized; + +/** + * @note Address: 0x800C14C0 + * @note Size: 0x88 + */ +int gdev_cc_initialize(void* inputPendingPtrRef, AmcEXICallback monitorCallback) +{ + MWTRACE(1, "CALLING EXI2_Init\n"); + DBInitComm(inputPendingPtrRef, monitorCallback); + MWTRACE(1, "DONE CALLING EXI2_Init\n"); + CircleBufferInitialize(&gRecvCB, gRecvBuf, GDEV_BUF_SIZE); + return 0; +} + +/** + * @note Address: 0x800C14B8 + * @note Size: 0x8 + */ +int gdev_cc_shutdown() { return 0; } + +/** + * @note Address: 0x800C1494 + * @note Size: 0x24 + */ +int gdev_cc_open() +{ + if (gIsInitialized) { + return -0x2715; + } + + gIsInitialized = TRUE; + return 0; +} + +/** + * @note Address: 0x800C148C + * @note Size: 0x8 + */ +int gdev_cc_close() { return 0; } + +/** + * @note Address: 0x800C1398 + * @note Size: 0xF4 + */ +int gdev_cc_read(u8* data, int size) +{ + u8 buff[GDEV_BUF_SIZE]; + int p1; + u32 retval; + int p2; + int poll; + retval = 0; + if (!gIsInitialized) { + return -0x2711; + } + + MWTRACE(1, "Expected packet size : 0x%08x (%ld)\n", size, size); + + p1 = size; + p2 = size; + while ((u32)CBGetBytesAvailableForRead(&gRecvCB) < p2) { + retval = 0; + poll = DBQueryData(); + if (poll != 0) { + retval = DBRead(buff, p2); + if (retval == 0) { + CircleBufferWriteBytes(&gRecvCB, buff, poll); + } + } + } + + if (retval == 0) { + CircleBufferReadBytes(&gRecvCB, data, p1); + } else { + MWTRACE(8, "cc_read : error reading bytes from EXI2 %ld\n", retval); + } + + return retval; +} + +/** + * @note Address: 0x800C12D8 + * @note Size: 0xC0 + */ +int gdev_cc_write(const u8* bytes, int length) +{ + int exi2Len; + int n_copy; + u32 hexCopy; + + hexCopy = (u32)bytes; + n_copy = length; + + if (gIsInitialized == FALSE) { + MWTRACE(8, "cc not initialized\n"); + return -0x2711; + } + + MWTRACE(8, "cc_write : Output data 0x%08x %ld bytes\n", bytes, length); + + while (n_copy > 0) { + MWTRACE(1, "cc_write sending %ld bytes\n", n_copy); + exi2Len = DBWrite((const void*)hexCopy, n_copy); + if (exi2Len == AMC_EXI_NO_ERROR) { + break; + } + hexCopy += exi2Len; + n_copy -= exi2Len; + } + + return 0; +} + +/** + * @note Address: 0x800C12B4 + * @note Size: 0x24 + */ +int gdev_cc_pre_continue() +{ + DBClose(); + return 0; +} + +/** + * @note Address: 0x800C1290 + * @note Size: 0x24 + */ +int gdev_cc_post_stop() +{ + DBOpen(); + return 0; +} + +/** + * @note Address: 0x800C1220 + * @note Size: 0x70 + */ +int gdev_cc_peek() +{ + int poll; + u8 buff[GDEV_BUF_SIZE]; + + poll = DBQueryData(); + if (poll <= 0) { + return 0; + } + + if (DBRead(buff, poll) == 0) { + CircleBufferWriteBytes(&gRecvCB, buff, poll); + } else { + return -0x2719; + } + + return poll; +} + +/** + * @note Address: 0x800C11FC + * @note Size: 0x24 + */ +int gdev_cc_initinterrupts() +{ + DBInitInterrupts(); + return 0; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/main_TRK.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/main_TRK.c new file mode 100644 index 0000000..33ee609 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/main_TRK.c @@ -0,0 +1,22 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +static DSError TRK_mainError; + +/** + * @note Address: 0x800C040C + * @note Size: 0x58 + */ +DSError TRK_main(void) +{ + MWTRACE(1, "TRK_Main \n"); + TRK_mainError = TRKInitializeNub(); + + if (TRK_mainError == DS_NoError) { + TRKNubWelcome(); + TRKNubMainLoop(); + } + + TRK_mainError = TRKTerminateNub(); + + return TRK_mainError; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mainloop.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mainloop.c new file mode 100644 index 0000000..cb87722 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mainloop.c @@ -0,0 +1,89 @@ +#include "types.h" +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +extern TRKEventQueue gTRKEventQueue; +extern TRKState gTRKState; + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void TRKHandleRequestEvent(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void TRKHandleSupportEvent(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +void TRKIdle(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BB390 + * @note Size: 0xF8 + */ +void TRKNubMainLoop(void) +{ + void* msg; + TRKEvent event; + BOOL isShutdownRequested; + BOOL isNewInput; + + isShutdownRequested = FALSE; + isNewInput = FALSE; + while (isShutdownRequested == FALSE) { + if (TRKGetNextEvent(&event) != FALSE) { + isNewInput = FALSE; + + switch (event.eventType) { + case NUBEVENT_Null: + break; + + case NUBEVENT_Request: + msg = TRKGetBuffer(event.msgBufID); + TRKDispatchMessage(msg); + break; + + case NUBEVENT_Shutdown: + isShutdownRequested = TRUE; + break; + + case NUBEVENT_Breakpoint: + case NUBEVENT_Exception: + TRKTargetInterrupt(&event); + break; + + case NUBEVENT_Support: + TRKTargetSupportRequest(); + break; + } + + TRKDestructEvent(&event); + continue; + } + + if ((isNewInput == FALSE) || (*(u8*)gTRKInputPendingPtr != '\0')) { + isNewInput = TRUE; + TRKGetInput(); + continue; + } + + if (TRKTargetStopped() == FALSE) { + TRKTargetContinue(); + } + isNewInput = FALSE; + } +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mem_TRK.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mem_TRK.c new file mode 100644 index 0000000..d1981ba --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mem_TRK.c @@ -0,0 +1,85 @@ +#include "types.h" + +#define WRITE(dst, add, n_dst, n_src) ((u##n_dst*)dst) = ((u##n_dst*)(((u##n_src*)dst) + add)) - 1 +#define WRITE_BYTE(dst, add) WRITE(dst, add, 8, 32) +#define WRITE_WORD(dst, add) WRITE(dst, add, 32, 8) + +DECL_SECT(".init") void* TRK_memcpy(void* dst, const void* src, size_t n); +DECL_SECT(".init") void* TRK_memset(void* dst, int val, size_t n); + +/** + * @note Address: 0x800BDDF0 + * @note Size: 0xB8 + */ +#pragma dont_inline on +void TRK_fill_mem(void* dst, int val, size_t n) +{ + u32 v = (u8)val; + u32 i, j; + + WRITE_BYTE(dst, 0); + + if (n >= 32) { + i = (~(u32)dst) & 3; + + if (i) { + n -= i; + + do { + *++(((u8*)dst)) = v; + } while (--i); + } + + if (v) + v |= v << 24 | v << 16 | v << 8; + + WRITE_WORD(dst, 4); + WRITE_WORD(dst, 1); + + i = n / 32; + + if (i) { + do { + for (j = 0; j < 8; j++) + *++((u32*)dst) = v; + } while (--i); + } + + i = (n / 4) % 8; + + if (i) { + do { + *++((u32*)dst) = v; + } while (--i); + } + + WRITE_BYTE(dst, 1); + + n %= 4; + } + + if (n) + do { + *++((u8*)dst) = v; + } while (--n); + + return; +} +#pragma dont_inline reset + +void* TRK_memcpy(void* dst, const void* src, size_t n) +{ + const u8* s = (const u8*)src - 1; + u8* d = (u8*)dst - 1; + + n++; + while (--n != 0) + *++d = *++s; + return dst; +} + +void* TRK_memset(void* dst, int val, size_t n) +{ + TRK_fill_mem(dst, val, n); + return dst; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c new file mode 100644 index 0000000..734d307 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mpc_7xx_603e.c @@ -0,0 +1,254 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/** + * @note Address: 0x800BFA60 + * @note Size: 0x1B8 + */ +ASM void TRKSaveExtended1Block(void) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + mfsr r16, 0 + mfsr r17, 0x1 + mfsr r18, 0x2 + mfsr r19, 0x3 + mfsr r20, 0x4 + mfsr r21, 0x5 + mfsr r22, 0x6 + mfsr r23, 0x7 + mfsr r24, 0x8 + mfsr r25, 0x9 + 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 + mfspr r15, 0x11F + mfibatu r16, 0 + mfibatl r17, 0 + mfibatu r18, 0x1 + mfibatl r19, 0x1 + mfibatu r20, 0x2 + mfibatl r21, 0x2 + mfibatu r22, 0x3 + mfibatl r23, 0x3 + mfdbatu r24, 0 + mfdbatl r25, 0 + mfdbatu r26, 0x1 + mfdbatl r27, 0x1 + mfdbatu r28, 0x2 + mfdbatl r29, 0x2 + mfdbatu r30, 0x3 + mfdbatl r31, 0x3 + stmw r10, 0x1E8(r2) + mfsdr1 r22 + mfdar r23 + mfdsisr r24 + mfsprg r25, 0 + mfsprg r26, 0x1 + mfsprg r27, 0x2 + mfsprg r28, 0x3 + li r29, 0 + mfspr r30, 0x3F2 + mfear r31 + 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 loc_0x150 + + 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) + +loc_0x150: + mfspr r19, 0x3F5 + mfspr r20, 0x3B9 + mfspr r21, 0x3BA + mfspr r22, 0x3BD + mfspr r23, 0x3BE + mfspr r24, 0x3BB + mfspr r25, 0x3B8 + mfspr r26, 0x3BC + mfspr r27, 0x3FC + mfspr r28, 0x3FD + mfspr r29, 0x3FE + mfspr r30, 0x3FB + mfspr r31, 0x3F9 + stmw r19, 0x284(r2) + blr + mfspr r25, 0x3D0 + mfspr r26, 0x3D1 + mfspr r27, 0x3D2 + mfspr r28, 0x3D3 + mfspr r29, 0x3D4 + mfspr r30, 0x3D5 + mfspr r31, 0x3D6 + stmw r25, 0x240(r2) + mfdec r31 + stw r31, 0x278(r2) + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800BFC18 + * @note Size: 0x1B8 + */ +ASM void TRKRestoreExtended1Block() +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + lis r5, gTRKRestoreFlags@h + ori r5, r5, gTRKRestoreFlags@l + lbz r3, 0x0(r5) + lbz r6, 0x1(r5) + li r0, 0 + stb r0, 0x0(r5) + stb r0, 0x1(r5) + cmpwi r3, 0 + beq- loc_0x3C + lwz r24, 0x1E8(r2) + lwz r25, 0x1EC(r2) + mttbl r24 + mttbu r25 + +loc_0x3C: + lmw r20, 0x2FC(r2) + mtspr 912, r20 + mtspr 913, r21 + mtspr 914, r22 + mtspr 915, r23 + mtspr 916, r24 + mtspr 917, r25 + mtspr 918, r26 + mtspr 919, r27 + mtspr 920, r28 + mtspr 922, r30 + mtspr 923, r31 + b loc_0x88 + lmw r26, 0x2E0(r2) + mtspr 944, r26 + mtspr 951, r27 + mtspr 1014, r29 + mtspr 1015, r30 + mtspr 1023, r31 + +loc_0x88: + lmw r19, 0x284(r2) + mtspr 1013, r19 + mtspr 953, r20 + mtspr 954, r21 + mtspr 957, r22 + mtspr 958, r23 + mtspr 955, r24 + mtspr 952, r25 + mtspr 956, r26 + mtspr 1020, r27 + mtspr 1021, r28 + mtspr 1022, r29 + mtspr 1019, r30 + mtspr 1017, r31 + b loc_0xF4 + cmpwi r6, 0 + beq- loc_0xD4 + lwz r26, 0x278(r2) + mtdec r26 + +loc_0xD4: + lmw r25, 0x240(r2) + mtspr 976, r25 + mtspr 977, r26 + mtspr 978, r27 + mtspr 979, r28 + mtspr 980, r29 + mtspr 981, r30 + mtspr 982, r31 + +loc_0xF4: + 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 10, r26 + mtsr 11, r27 + mtsr 12, r28 + mtsr 13, r29 + mtsr 14, r30 + mtsr 15, r31 + lmw r12, 0x1F0(r2) + mtspr 1008, r12 + mtspr 1009, r13 + mtsrr1 r14 + mtspr 287, 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) + mtsdr1 r22 + mtdar r23 + mtdsisr r24 + mtsprg 0, r25 + mtsprg 1, r26 + mtsprg 2, r27 + mtsprg 3, r28 + mtspr 1010, r30 + mtear r31 + blr +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msg.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msg.c new file mode 100644 index 0000000..61b97fc --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msg.c @@ -0,0 +1,12 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/** + * @note Address: 0x800BB848 + * @note Size: 0x44 + */ +DSError TRKMessageSend(MessageBuffer* msg) +{ + DSError writeErr = TRKWriteUARTN(&msg->data, msg->length); + MWTRACE(1, "MessageSend : cc_write returned %ld\n", writeErr); + return DS_NoError; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msgbuf.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msgbuf.c new file mode 100644 index 0000000..431df63 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msgbuf.c @@ -0,0 +1,473 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +MessageBuffer gTRKMsgBufs[3]; + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void TRKSetBufferUsed(MessageBuffer* msg, BOOL state) { msg->isInUse = state; } + +/** + * @note Address: 0x800BC054 + * @note Size: 0x74 + */ +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; +} + +/** + * @note Address: 0x800BBF8C + * @note Size: 0xC8 + */ +DSError TRKGetFreeBuffer(int* msgID, MessageBuffer** outMsg) +{ + MessageBuffer* buf; + DSError error = DS_NoMessageBufferAvailable; + int i; + + *outMsg = nullptr; + + for (i = 0; i < 3; i++) { + buf = TRKGetBuffer(i); + + TRKAcquireMutex(buf); + if (!buf->isInUse) { + TRKResetBuffer(buf, TRUE); + TRKSetBufferUsed(buf, TRUE); + error = DS_NoError; + *outMsg = buf; + *msgID = i; + i = 3; // why not break? weird choice + } + TRKReleaseMutex(buf); + } + + if (error == DS_NoMessageBufferAvailable) { + usr_puts_serial("ERROR : No buffer available\n"); + } + + return error; +} + +/** + * @note Address: 0x800BBF60 + * @note Size: 0x2C + */ +void* TRKGetBuffer(int idx) +{ + MessageBuffer* buf = nullptr; + if (idx >= 0 && idx < 3) { + buf = &gTRKMsgBufs[idx]; + } + + return buf; +} + +/** + * @note Address: 0x800BBEFC + * @note Size: 0x64 + */ +void TRKReleaseBuffer(int idx) +{ + MessageBuffer* msg; + if (idx != -1 && idx >= 0 && idx < 3) { + msg = &gTRKMsgBufs[idx]; + TRKAcquireMutex(msg); + TRKSetBufferUsed(msg, FALSE); + TRKReleaseMutex(msg); + } +} + +/** + * @note Address: 0x800BBEBC + * @note Size: 0x40 + */ +void TRKResetBuffer(MessageBuffer* msg, BOOL keepData) +{ + msg->length = 0; + msg->position = 0; + + if (!keepData) { + TRK_memset(msg->data, 0, 0x880); + } +} + +/** + * @note Address: 0x800BBE8C + * @note Size: 0x30 + */ +DSError TRKSetBufferPosition(MessageBuffer* 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; +} + +/** + * @note Address: 0x800BBDE8 + * @note Size: 0xA4 + */ +DSError TRKAppendBuffer(MessageBuffer* 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; +} + +/** + * @note Address: 0x800BBD5C + * @note Size: 0x8C + */ +DSError TRKReadBuffer(MessageBuffer* msg, void* data, size_t length) +{ + DSError error = DS_NoError; + uint bytesLeft; // this has to be uint 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; +} + +/** + * @note Address: N/A + * @note Size: 0xC8 + */ +void TRKAppendBuffer1_ui16(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xD8 + */ +DSError TRKAppendBuffer1_ui32(MessageBuffer* 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)); +} + +/** + * @note Address: 0x800BBC60 + * @note Size: 0xFC + */ +DSError TRKAppendBuffer1_ui64(MessageBuffer* 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)); +} + +/** + * @note Address: N/A + * @note Size: 0x128 + */ +void TRKAppendBuffer1_ui128(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BBBF8 + * @note Size: 0x68 + */ +DSError TRKAppendBuffer_ui8(MessageBuffer* 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; +} + +/** + * @note Address: N/A + * @note Size: 0xEC + */ +void TRKAppendBuffer_ui16(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BBAFC + * @note Size: 0xFC + */ +DSError TRKAppendBuffer_ui32(MessageBuffer* 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; +} + +/** + * @note Address: N/A + * @note Size: 0x124 + */ +void TRKAppendBuffer_ui64(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x154 + */ +void TRKAppendBuffer_ui128(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +DSError TRKReadBuffer1_ui8(MessageBuffer* buffer, u8* data) { return TRKReadBuffer(buffer, (void*)data, 1); } + +/** + * @note Address: N/A + * @note Size: 0xB8 + */ +void TRKReadBuffer1_ui16(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC8 + */ +DSError TRKReadBuffer1_ui32(MessageBuffer* buffer, u32* data) +{ + DSError err; + + u8* bigEndianData; + u8* byteData; + u8 swapBuffer[sizeof(data)]; + + if (gTRKBigEndian) { + bigEndianData = (u8*)data; + } else { + bigEndianData = swapBuffer; + } + + err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data)); + + if (!gTRKBigEndian && err == DS_NoError) { + byteData = (u8*)data; + + byteData[0] = bigEndianData[3]; + byteData[1] = bigEndianData[2]; + byteData[2] = bigEndianData[1]; + byteData[3] = bigEndianData[0]; + } + + return err; + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BBA14 + * @note Size: 0xE8 + */ +DSError TRKReadBuffer1_ui64(MessageBuffer* 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; +} + +/** + * @note Address: N/A + * @note Size: 0x128 + */ +void TRKReadBuffer1_ui128(MessageBuffer* buffer, u8* p2, int p3) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BB97C + * @note Size: 0x98 + */ +DSError TRKReadBuffer_ui8(MessageBuffer* 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; +} + +/** + * @note Address: N/A + * @note Size: 0xE0 + */ +void TRKReadBuffer_ui16(MessageBuffer* buffer, u8* p2, int p3) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BB88C + * @note Size: 0xF0 + */ +DSError TRKReadBuffer_ui32(MessageBuffer* 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; +} + +/** + * @note Address: N/A + * @note Size: 0x110 + */ +void TRKReadBuffer_ui64(MessageBuffer* buffer, u8* p2, int p3) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x150 + */ +void TRKReadBuffer_ui128(MessageBuffer* buffer, u8* p2, int p3) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msghndlr.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msghndlr.c new file mode 100644 index 0000000..1cc0fdb --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/msghndlr.c @@ -0,0 +1,633 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "Dolphin/print.h" +static BOOL IsTRKConnected; +static u32 g_CurrentSequence; + +/** + * @note Address: 0x800BD54C + * @note Size: 0xA8 + */ +void OutputData(void* data, int length) +{ + // u8 byte; + int i; + u8* datapointer = data; + + for (i = 0; i < length; i++) { + MWTRACE(8, "%02x ", datapointer[i]); + if (i % 16 == 15) { + MWTRACE(8, "\n"); + } + } + + MWTRACE(8, "\n"); +} + +/** + * @note Address: 0x800BD53C + * @note Size: 0x10 + */ +int GetTRKConnected(void) { return IsTRKConnected; } + +/** + * @note Address: 0x800BD530 + * @note Size: 0xC + */ +void SetTRKConnected(int isConnected) { IsTRKConnected = isConnected; } + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +void TRKMessageIntoReply(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +DSError TRKSendACK(MessageBuffer* buffer) +{ + DSError err; + MWTRACE(1, "SendACK : Calling MessageSend\n"); + err = TRKMessageSend(buffer); + MWTRACE(1, "MessageSend err : %ld\n", err); + return err; +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +DSError TRKStandardACK(MessageBuffer* buffer, MessageCommandID commandID, DSReplyError replyError) +{ + CommandReply reply; + + memset(&reply, 0, sizeof(CommandReply)); + reply.commandID.b = commandID; + reply._00 = 0x40; + reply.replyError.b = replyError; + TRKWriteUARTN(&reply, sizeof(CommandReply)); + return DS_NoError; +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void TRKDoError(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +void TRKDoUnsupported(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BD4CC + * @note Size: 0x64 + */ +DSError TRKDoConnect(MessageBuffer* buffer) +{ + IsTRKConnected = TRUE; + return TRKStandardACK(buffer, 0x80, DSREPLY_NoError); +} + +/** + * @note Address: 0x800BD454 + * @note Size: 0x78 + */ +DSError TRKDoDisconnect(MessageBuffer* buffer) +{ + TRKEvent event; + + IsTRKConnected = FALSE; + TRKStandardACK(buffer, 0x80, DSREPLY_NoError); + TRKConstructEvent(&event, 1); + TRKPostEvent(&event); + return DS_NoError; +} + +/** + * @note Address: 0x800BD3FC + * @note Size: 0x58 + */ +DSError TRKDoReset(MessageBuffer* buffer) +{ + TRKStandardACK(buffer, 0x80, DSREPLY_NoError); + __TRK_reset(); + return DS_NoError; +} + +/** + * @note Address: 0x800BD3A4 + * @note Size: 0x58 + */ +DSError TRKDoOverride(MessageBuffer* buffer) +{ + TRKStandardACK(buffer, 0x80, DSREPLY_NoError); + __TRK_copy_vectors(); + return DS_NoError; +} + +/** + * @note Address: 0x800BD39C + * @note Size: 0x8 + */ +DSError TRKDoVersions(MessageBuffer*) { return DS_NoError; } + +/** + * @note Address: 0x800BD394 + * @note Size: 0x8 + */ +DSError TRKDoSupportMask(MessageBuffer*) { return DS_NoError; } + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void TRKDoCPUType(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BD150 + * @note Size: 0x244 + */ +DSError TRKDoReadMemory(MessageBuffer* buffer) +{ + u8 buf[0x820] __attribute__((aligned(32))); + size_t tempLength; + int result; + int replyErr; + int options; + size_t length; + u32 start; + + start = *(u32*)(buffer->data + 16); + length = *(u16*)(buffer->data + 12); + options = buffer->data[8]; + + MWTRACE(1, "ReadMemory (0x%02x) : 0x%08x 0x%08x 0x%08x\n", buffer->data[4], start, length, options); + + if (options & DSMSGMEMORY_Extended) { + return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError); + } + + tempLength = length; + + if (options & DSMSGMEMORY_Space_data) { + result = TRKTargetAccessARAM(buf, start, &tempLength, TRUE); + } else { + result = TRKTargetAccessMemory(buf, start, &tempLength, options & DSMSGMEMORY_Userview ? 0 : 1, TRUE); + } + + TRKResetBuffer(buffer, 0); + + if (result == DS_NoError) { + CommandReply reply; + memset(&reply, 0, sizeof(CommandReply)); + reply.replyError.b = result; + reply._00 = tempLength + 0x40; + reply.commandID.b = DSMSG_ReplyACK; + TRKAppendBuffer(buffer, &reply, sizeof(CommandReply)); + + if (options & 0x40) { + result = TRKAppendBuffer(buffer, buf + (start & 0x1F), tempLength); + } else { + result = TRKAppendBuffer(buffer, buf, tempLength); + } + } + + if (result) { + switch (result) { + case DS_CWDSException: + replyErr = DSREPLY_CWDSException; + break; + case DS_InvalidMemory: + replyErr = DSREPLY_InvalidMemoryRange; + break; + case DS_InvalidProcessID: + replyErr = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyErr = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyErr = DSREPLY_OSError; + break; + default: + replyErr = DSREPLY_CWDSError; + break; + } + return TRKStandardACK(buffer, DSMSG_ReplyACK, replyErr); + } + + return TRKSendACK(buffer); +} + +/** + * @note Address: 0x800BCF14 + * @note Size: 0x23C + */ +DSError TRKDoWriteMemory(MessageBuffer* b) +{ + u8 buf[0x820] __attribute__((aligned(32))); + size_t tempLength; + int options; + int result; + int replyErr; + size_t length; + u32 start; + + start = *(u32*)(&b->data[16]); + length = *(u16*)(&b->data[12]); + options = b->data[8]; + + MWTRACE(1, "WriteMemory (0x%02x) : 0x%08x 0x%08x 0x%08x\n", (uint)b->data[0x4], start, length, options); + + if (options & DSMSGMEMORY_Extended) { + return TRKStandardACK(b, DSMSG_ReplyACK, DSMSG_ReadRegisters); + } + + tempLength = length; + + TRKSetBufferPosition(b, DSMSGMEMORY_Space_data); + if (options & DSMSGMEMORY_Space_data) { + TRKReadBuffer(b, buf + (start & 0x1f), tempLength); + result = TRKTargetAccessARAM(buf, start, &tempLength, FALSE); + } else { + TRKReadBuffer(b, buf, tempLength); + result = TRKTargetAccessMemory(buf, start, &tempLength, options & DSMSGMEMORY_Userview ? 0 : 1, FALSE); + } + + TRKResetBuffer(b, 0); + + if (result == DS_NoError) { + CommandReply reply; + memset(&reply, 0, sizeof(CommandReply)); + reply._00 = 0x40; + reply.commandID.b = DSMSG_ReplyACK; + reply.replyError.b = result; + result = TRKAppendBuffer(b, &reply, sizeof(CommandReply)); + } + + if (result != DS_NoError) { + switch (result) { + case DS_CWDSException: + replyErr = DSREPLY_CWDSException; + break; + case DS_InvalidMemory: + replyErr = DSREPLY_InvalidMemoryRange; + break; + case DS_InvalidProcessID: + replyErr = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyErr = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyErr = DSREPLY_OSError; + break; + default: + replyErr = DSREPLY_CWDSError; + break; + } + return TRKStandardACK(b, DSMSG_ReplyACK, replyErr); + } + + return TRKSendACK(b); +} + +/** + * @note Address: 0x800BCC34 + * @note Size: 0x2E0 + */ +DSError TRKDoReadRegisters(MessageBuffer* b) +{ + int error; + u8 options; + u16 firstRegister; + u16 lastRegister; + size_t registersLength; + CommandReply local_50; + + options = b->data[8]; + firstRegister = *(u16*)(b->data + 12); + lastRegister = *(u16*)(b->data + 16); + + if (firstRegister > lastRegister) { + return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_InvalidRegisterRange); + } + + local_50.commandID.b = DSMSG_ReplyACK; + local_50._00 = 0x468; + + TRKResetBuffer(b, 0); + MWTRACE(4, "DoReadRegisters : Buffer length 0x%08x\n", b->length); + + TRKAppendBuffer_ui8(b, (u8*)&local_50, sizeof(CommandReply)); + MWTRACE(4, "DoReadRegisters : Buffer length 0x%08x\n", b->length); + + error = TRKTargetAccessDefault(0, 36, b, ®istersLength, TRUE); + MWTRACE(4, "DoReadRegisters : Error reading default regs 0x%08x\n", error); + MWTRACE(4, "DoReadRegisters : Buffer length 0x%08x\n", b->length); + + if (error == DS_NoError) { + error = TRKTargetAccessFP(0, 33, b, ®istersLength, TRUE); + } + MWTRACE(4, "DoReadRegisters : Error FP regs 0x%08x\n", error); + MWTRACE(4, "DoReadRegisters : Buffer length 0x%08x\n", b->length); + if (error == DS_NoError) { + error = TRKTargetAccessExtended1(0, 0x60, b, ®istersLength, TRUE); + } + MWTRACE(4, "DoReadRegisters : Error extended1 regs 0x%08x\n", error); + MWTRACE(4, "DoReadRegisters : Buffer length 0x%08x\n", b->length); + if (error == DS_NoError) { + error = TRKTargetAccessExtended2(0, 31, b, ®istersLength, TRUE); + } + MWTRACE(4, "DoReadRegisters : Error extended2 regs 0x%08x\n", error); + MWTRACE(4, "DoReadRegisters : Buffer length 0x%08x\n", b->length); + + // Check if there was an error, and respond accordingly + if (error != DS_NoError) { + int replyError; + switch (error) { + case DS_UnsupportedError: + replyError = DSREPLY_UnsupportedOptionError; + break; + case DS_InvalidRegister: + replyError = DSREPLY_InvalidRegisterRange; + break; + case DS_CWDSException: + replyError = DSREPLY_CWDSException; + break; + case DS_InvalidProcessID: + replyError = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyError = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyError = DSREPLY_OSError; + break; + default: + replyError = DSREPLY_CWDSError; + } + + return TRKStandardACK(b, DSMSG_ReplyACK, replyError); + } else { + // No error, send ack + return TRKSendACK(b); + } +} + +/** + * @note Address: 0x800BC9A4 + * @note Size: 0x290 + */ +DSError TRKDoWriteRegisters(MessageBuffer* b) +{ + int error; + int replyError; + u8 options; + u16 firstRegister; + u16 lastRegister; + size_t registersLength; + + options = b->data[8]; + firstRegister = *(u16*)(b->data + 12); + lastRegister = *(u16*)(b->data + 16); + + TRKSetBufferPosition(b, 0); + + if (firstRegister > lastRegister) { + return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_InvalidRegisterRange); + } + + TRKSetBufferPosition(b, 0x40); + + switch (options) { + case DSREG_Default: + error = TRKTargetAccessDefault(firstRegister, lastRegister, b, ®istersLength, FALSE); + break; + case DSREG_FP: + error = TRKTargetAccessFP(firstRegister, lastRegister, b, ®istersLength, FALSE); + break; + case DSREG_Extended1: + error = TRKTargetAccessExtended1(firstRegister, lastRegister, b, ®istersLength, FALSE); + break; + case DSREG_Extended2: + error = TRKTargetAccessExtended2(firstRegister, lastRegister, b, ®istersLength, FALSE); + break; + default: + // invalid option + error = DS_UnsupportedError; + break; + } + + TRKResetBuffer(b, 0); + + if (error == DS_NoError) { + CommandReply local_50; + memset(&local_50, 0, sizeof(CommandReply)); + local_50._00 = 0x40; + local_50.commandID.b = DSMSG_ReplyACK; + local_50.replyError.b = error; + error = TRKAppendBuffer(b, (u8*)&local_50, sizeof(CommandReply)); + } + + // Check if there was an error, and respond accordingly + if (error != DS_NoError) { + switch (error) { + case DS_UnsupportedError: + replyError = DSREPLY_UnsupportedOptionError; + break; + case DS_InvalidRegister: + replyError = DSREPLY_InvalidRegisterRange; + break; + case DS_MessageBufferReadError: + replyError = DSREPLY_PacketSizeError; + break; + case DS_CWDSException: + replyError = DSREPLY_CWDSException; + break; + case DS_InvalidProcessID: + replyError = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyError = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyError = DSREPLY_OSError; + break; + default: + replyError = DSREPLY_CWDSError; + } + + return TRKStandardACK(b, DSMSG_ReplyACK, replyError); + } else { + // No error, send ack + return TRKSendACK(b); + } +} + +/** + * @note Address: N/A + * @note Size: 0x250 + */ +void TRKDoFlushCache(void) +{ + MWTRACE(1, "DoFlushCache unimplemented!!!\n"); + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BC8F4 + * @note Size: 0xB0 + */ +DSError TRKDoContinue(MessageBuffer*) +{ + MWTRACE(1, "DoContinue\n"); + if (!TRKTargetStopped()) { + u8 arr[0x40]; + memset(arr, 0, 0x40); + + arr[4] = 0x80; + *(u32*)arr = 0x40; + arr[8] = 0x16; + + TRKWriteUARTN(arr, 0x40); + return DS_NoError; + } else { + u8 arr[0x40]; + memset(arr, 0, 0x40); + + arr[4] = 0x80; + *(u32*)arr = 0x40; + arr[8] = 0x00; + + TRKWriteUARTN(arr, 0x40); + return TRKTargetContinue(); + } +} + +/** + * @note Address: 0x800BC6D4 + * @note Size: 0x220 + */ + +DSError TRKDoStep(MessageBuffer* b) +{ + DSError result; + u8 options; + u8 count; + u32 rangeStart; + u32 rangeEnd; + u32 pc; + TRKSetBufferPosition(b, 0); + + options = *(u8*)&b->data[8]; + rangeStart = *(u32*)&b->data[16]; + rangeEnd = *(u32*)&b->data[20]; + + switch (options) { + case DSSTEP_IntoCount: + case DSSTEP_OverCount: + count = b->data[12]; + if (count >= 1) { + break; + } + return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_ParameterError); + case DSSTEP_IntoRange: + case DSSTEP_OverRange: + pc = TRKTargetGetPC(); + if (pc >= rangeStart && pc <= rangeEnd) { + break; + } + return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_ParameterError); + default: + return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError); + } + + if (!TRKTargetStopped()) { + return TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_NotStopped); + } else { + result = TRKStandardACK(b, DSMSG_ReplyACK, DSREPLY_NoError); + switch (options) { + case DSSTEP_IntoCount: + case DSSTEP_OverCount: + result = TRKTargetSingleStep(count, (options == DSSTEP_OverCount)); + break; + case DSSTEP_IntoRange: + case DSSTEP_OverRange: + result = TRKTargetStepOutOfRange(rangeStart, rangeEnd, (options == DSSTEP_OverRange)); + break; + } + + return result; + } +} + +/** + * @note Address: 0x800BC62C + * @note Size: 0xA8 + */ +DSError TRKDoStop(MessageBuffer* b) +{ + MessageCommandID c; + + switch (TRKTargetStop()) { + case DS_NoError: + c = DSMSG_Ping; + break; + case DS_InvalidProcessID: + c = '!'; + break; + case DS_InvalidThreadID: + c = '\"'; + break; + case DS_OSError: + c = ' '; + break; + default: + c = DSMSG_Connect; + break; + } + + TRKStandardACK(b, DSMSG_ReplyACK, c); + + return DS_NoError; +} + +/** + * @note Address: 0x800BC584 + * @note Size: 0xA8 + */ +DSError TRKDoSetOption(MessageBuffer* message) +{ + u8 enable = message->data[0xc]; + + if (message->data[0x8] == '\1') { + usr_puts_serial("\nMetroTRK Option : SerialIO - "); + if (enable) { + usr_puts_serial("Enable\n"); + } else { + usr_puts_serial("Disable\n"); + } + SetUseSerialIO(enable); + } + + TRKStandardACK(message, DSMSG_ReplyACK, DS_NoError); + + return 0; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mslsupp.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mslsupp.c new file mode 100644 index 0000000..358a810 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mslsupp.c @@ -0,0 +1,142 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +// forward declares +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); + +/** + * @note Address: 0x800C0B4C + * @note Size: 0xBC + */ +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); +} + +/** + * @note Address: 0x800C0A90 + * @note Size: 0xBC + */ +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); +} + +/** + * @note Address: 0x800C0A0C + * @note Size: 0x84 + */ +DSIOResult __close_console(u32 handle, u8* buffer, size_t* count, void* ref_con) { return __close_file(handle, buffer, count, ref_con); } + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + return __access_file(handle, buffer, count, ref_con, DSMSG_ReadFile); +} + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + return __access_file(handle, buffer, count, ref_con, DSMSG_WriteFile); +} + +/** + * @note Address: N/A + * @note Size: 0x17C + */ +void __open_file(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x84 + */ +DSIOResult __close_file(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + u32 r0; + + if (GetTRKConnected() == DS_NoError) { + return DS_IOError; + } + + r0 = TRKCloseFile(DSMSG_CloseFile, handle); + + switch ((u8)r0) { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; +} + +/** + * @note Address: N/A + * @note Size: 0xDC + */ +void __position_file(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xE0 + */ +void convertFileMode(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC0 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x1D0 + */ +void __open_temp_file(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mutex_TRK.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mutex_TRK.c new file mode 100644 index 0000000..0f231b3 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/mutex_TRK.c @@ -0,0 +1,19 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/** + * @note Address: 0x800BDD18 + * @note Size: 0x8 + */ +DSError TRKInitializeMutex(void* p1) { return DS_NoError; } + +/** + * @note Address: 0x800BDD10 + * @note Size: 0x8 + */ +DSError TRKAcquireMutex(void* p1) { return DS_NoError; } + +/** + * @note Address: 0x800BDD08 + * @note Size: 0x8 + */ +DSError TRKReleaseMutex(void* p1) { return DS_NoError; } diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/notify.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/notify.c new file mode 100644 index 0000000..c9f7f37 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/notify.c @@ -0,0 +1,42 @@ +#include "types.h" +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +void TRKWaitForACK(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BDD20 + * @note Size: 0x98 + */ +DSError TRKDoNotifyStopped(MessageCommandID cmd) +{ + int reqIdx; + int bufIdx; + MessageBuffer* msg; + DSError err; + DSError bufError; + + bufError = TRKGetFreeBuffer(&bufIdx, &msg); + if ((err = bufError) == FALSE) { + if (err == DS_NoError) { + if (cmd == DSMSG_NotifyStopped) { + TRKTargetAddStopInfo(msg); + } else { + TRKTargetAddExceptionInfo(msg); + } + } + bufError = TRKRequestSend(msg, &reqIdx, 2, 3, 1); + err = bufError; + if (err == DS_NoError) { + TRKReleaseBuffer(reqIdx); + } + TRKReleaseBuffer(bufIdx); + } + return err; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/nubevent.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/nubevent.c new file mode 100644 index 0000000..e9047ae --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/nubevent.c @@ -0,0 +1,99 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +TRKEventQueue gTRKEventQueue; + +/** + * @note Address: 0x800BB658 + * @note Size: 0x58 + */ +DSError TRKInitializeEventQueue() +{ + TRKInitializeMutex(&gTRKEventQueue); + TRKAcquireMutex(&gTRKEventQueue); + gTRKEventQueue.count = 0; + gTRKEventQueue.next = 0; + gTRKEventQueue.eventID = 0x100; + TRKReleaseMutex(&gTRKEventQueue); + return DS_NoError; +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void TRKCopyEvent(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BB5A4 + * @note Size: 0xB4 + */ +BOOL TRKGetNextEvent(TRKEvent* ev) +{ + BOOL ret = FALSE; + + TRKAcquireMutex(&gTRKEventQueue); + + if (gTRKEventQueue.count > 0) { + TRK_memcpy(ev, &gTRKEventQueue.events[gTRKEventQueue.next], sizeof(TRKEvent)); + gTRKEventQueue.count--; + + if (++gTRKEventQueue.next == 2) { + gTRKEventQueue.next = 0; + } + + ret = TRUE; + } + + TRKReleaseMutex(&gTRKEventQueue); + return ret; +} + +/** + * @note Address: 0x800BB4C4 + * @note Size: 0xE0 + */ +DSError TRKPostEvent(TRKEvent* event) +{ + DSError ret = DS_NoError; + int nextEventID; + + TRKAcquireMutex(&gTRKEventQueue); + + if (gTRKEventQueue.count == 2) { + ret = DS_EventQueueFull; + + } else { + nextEventID = (gTRKEventQueue.next + gTRKEventQueue.count) % 2; + TRK_memcpy(&gTRKEventQueue.events[nextEventID], event, sizeof(TRKEvent)); + gTRKEventQueue.events[nextEventID].eventID = gTRKEventQueue.eventID; + + if (++gTRKEventQueue.eventID < 0x100) { + gTRKEventQueue.eventID = 0x100; + } + + gTRKEventQueue.count++; + } + + TRKReleaseMutex(&gTRKEventQueue); + return ret; +} + +/** + * @note Address: 0x800BB4AC + * @note Size: 0x18 + */ +void TRKConstructEvent(TRKEvent* event, int eventType) +{ + event->eventType = eventType; + event->eventID = 0; + event->msgBufID = -1; +} + +/** + * @note Address: 0x800BB488 + * @note Size: 0x24 + */ +void TRKDestructEvent(TRKEvent* event) { TRKReleaseBuffer(event->msgBufID); } diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/nubinit.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/nubinit.c new file mode 100644 index 0000000..dbca6aa --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/nubinit.c @@ -0,0 +1,90 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +BOOL gTRKBigEndian; + +/** + * @note Address: 0x800BB6FC + * @note Size: 0x14C + */ +DSError TRKInitializeNub(void) +{ + DSError ret; + DSError uartErr; + + ret = TRKInitializeEndian(); + + MWTRACE(1, "Initialize NUB\n"); + 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(); + } + InitializeProgramEndTrap(); + if (ret == DS_NoError) { + ret = TRKInitializeSerialHandler(); + } + if (ret == DS_NoError) { + ret = TRKInitializeTarget(); + } + if (ret == DS_NoError) { + + uartErr = TRKInitializeIntDrivenUART(0x0000e100, 1, 0, &gTRKInputPendingPtr); + TRKTargetSetInputPendingPtr(gTRKInputPendingPtr); + if (uartErr != DS_NoError) { + ret = uartErr; + } + } + return ret; +} + +/** + * @note Address: 0x800BB6D8 + * @note Size: 0x24 + */ +DSError TRKTerminateNub(void) +{ + TRKTerminateSerialHandler(); + return DS_NoError; +} + +/** + * @note Address: 0x800BB6B0 + * @note Size: 0x28 + */ +void TRKNubWelcome(void) +{ + TRK_board_display("MetroTRK for GAMECUBE v2.6"); //"MetroTRK for GAMECUBE v2.6" + return; +} + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +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/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/serpoll.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/serpoll.c new file mode 100644 index 0000000..98cd946 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/serpoll.c @@ -0,0 +1,108 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +static TRKFramingState gTRKFramingState; +void* gTRKInputPendingPtr; + +/** + * @note Address: 0x800BC244 + * @note Size: 0x13C + */ +MessageBufferID TRKTestForPacket() +{ + u8 payloadBuf[0x880]; + u8 packetBuf[0x40]; + int bufID; + MessageBuffer* msg; + MessageBufferID result; + + if (TRKPollUART() <= 0) { + return -1; + } + + result = TRKGetFreeBuffer(&bufID, &msg); + + MWTRACE(4, "TestForPacket : FreeBuffer is %ld\n", result); + + TRKSetBufferPosition(msg, 0); + if (TRKReadUARTN(packetBuf, 0x40) == UART_NoError) { + int readSize; + + TRKAppendBuffer_ui8(msg, packetBuf, 0x40); + readSize = ((u32*)packetBuf)[0] - 0x40; + result = bufID; + if (readSize > 0) { + MWTRACE(1, "Reading payload %ld bytes\n", readSize); + if (TRKReadUARTN(payloadBuf, ((u32*)packetBuf)[0] - 0x40) == UART_NoError) { + TRKAppendBuffer_ui8(msg, payloadBuf, ((u32*)packetBuf)[0]); + } else { + MWTRACE(8, "TestForPacket : Invalid size of packet hdr.size\n"); + TRKReleaseBuffer(result); + result = -1; + } + } + } else { + MWTRACE(8, "TestForPacket : Invalid size of packet\n"); + TRKReleaseBuffer(result); + result = -1; + } + + MWTRACE(1, "TestForPacket returning %ld\n", result); + return result; +} + +/** + * @note Address: 0x800BC1E4 + * @note Size: 0x60 + */ +void TRKGetInput(void) +{ + MessageBufferID id = TRKTestForPacket(); + if (id != -1) { + TRKEvent event; + TRKGetBuffer(id); + TRKConstructEvent(&event, NUBEVENT_Request); + event.msgBufID = id; + gTRKFramingState.msgBufID = -1; + TRKPostEvent(&event); + } +} + +/** + * @note Address: 0x800BC194 + * @note Size: 0x50 + */ +void TRKProcessInput(int bufferIdx) +{ + TRKEvent event; + + TRKConstructEvent(&event, NUBEVENT_Request); + event.msgBufID = bufferIdx; + gTRKFramingState.msgBufID = -1; + TRKPostEvent(&event); +} + +/** + * @note Address: 0x800BC0D0 + * @note Size: 0xC4 + */ +DSError TRKInitializeSerialHandler() +{ + gTRKFramingState.msgBufID = -1; + gTRKFramingState.receiveState = DSRECV_Wait; + gTRKFramingState.isEscape = FALSE; + + MWTRACE(1, "TRK_Packet_Header \t %ld bytes\n", 0x40); + MWTRACE(1, "TRK_CMD_ReadMemory %ld bytes\n", 0x40); + MWTRACE(1, "TRK_CMD_WriteMemory %ld bytes\n", 0x40); + MWTRACE(1, "TRK_CMD_Connect \t %ld bytes\n", 0x40); + MWTRACE(1, "TRK_CMD_ReplyAck\t %ld bytes\n", 0x40); + MWTRACE(1, "TRK_CMD_ReadRegisters\t%ld bytes\n", 0x40); + + return DS_NoError; +} + +/** + * @note Address: 0x800BC0C8 + * @note Size: 0x8 + */ +DSError TRKTerminateSerialHandler(void) { return DS_NoError; } diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/support.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/support.c new file mode 100644 index 0000000..d2d8830 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/support.c @@ -0,0 +1,303 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "Dolphin/print.h" +/** + * @note Address: 0x800BDAE8 + * @note Size: 0x220 + */ +DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, DSIOResult* io_result, BOOL need_reply, BOOL read) +{ + DSError error; + int replyBufferId; + MessageBuffer* replyBuffer; + u32 length; + int bufferId; + MessageBuffer* buffer; + u32 i; + u8 replyIOResult; + u32 replyLength; + BOOL exit; + CommandReply reply; + + if (data == nullptr || *count == 0) { + return DS_ParameterError; + } + + exit = FALSE; + *io_result = DS_IONoError; + i = 0; + error = DS_NoError; + while (!exit && i < *count && error == DS_NoError && *io_result == 0) { + memset(&reply, 0, sizeof(CommandReply)); + + if (*count - i <= 0x800) { + length = *count - i; + } else { + length = 0x800; + } + + reply.commandID.b = read ? DSMSG_ReadFile : DSMSG_WriteFile; + + if (read) { + reply._00 = 0x40; + } else { + reply._00 = length + 0x40; + } + + reply.replyError.r = file_handle; + *(u16*)&reply._0C = length; + + TRKGetFreeBuffer(&bufferId, &buffer); + error = TRKAppendBuffer_ui8(buffer, (u8*)&reply, 0x40); + + if (!read && error == DS_NoError) { + error = TRKAppendBuffer_ui8(buffer, data + i, length); + } + + if (error == DS_NoError) { + if (need_reply) { + BOOL b = read && file_handle == 0; + + error = TRKRequestSend(buffer, &replyBufferId, read ? 5 : 5, 3, !b); + if (error == DS_NoError) { + replyBuffer = (MessageBuffer*)TRKGetBuffer(replyBufferId); + } + replyIOResult = *(u32*)(replyBuffer->data + 0x10); + replyLength = *(u16*)(replyBuffer->data + 0x14); + if (read && error == DS_NoError && replyLength <= length) { + TRKSetBufferPosition(replyBuffer, 0x40); + error = TRKReadBuffer_ui8(replyBuffer, data + i, replyLength); + if (error == DS_MessageBufferReadError) { + error = DS_NoError; + } + } + + if (replyLength != length) { + length = replyLength; + exit = TRUE; + } + + *io_result = (DSIOResult)replyIOResult; + TRKReleaseBuffer(replyBufferId); + } else { + error = TRKMessageSend(buffer); + } + } + + TRKReleaseBuffer(bufferId); + i += length; + } + + *count = i; + return error; +} + +/** + * @note Address: 0x800BD908 + * @note Size: 0x1E0 + */ +DSError TRKRequestSend(MessageBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3) +{ + int error = DS_NoError; + MessageBuffer* buffer; + u32 counter; + int count; + u8 msgCmd; + int msgReplyError; + BOOL badReply = TRUE; + + *bufferId = -1; + + for (count = p2 + 1; count != 0 && *bufferId == -1 && error == DS_NoError; count--) { + MWTRACE(1, "Calling MessageSend\n"); + error = TRKMessageSend(msgBuf); + if (error == DS_NoError) { + + if (p3) { + counter = 0; + } + + while (TRUE) { + do { + *bufferId = TRKTestForPacket(); + if (*bufferId != -1) + break; + } while (!p3 || ++counter < 79999980); + + if (*bufferId == -1) + break; + + badReply = 0; + + buffer = TRKGetBuffer(*bufferId); + TRKSetBufferPosition(buffer, 0); + OutputData(&buffer->data[0], buffer->length); + msgCmd = buffer->data[4]; + MWTRACE(1, "msg_command : 0x%02x hdr->cmdID 0x%02x\n", msgCmd, msgCmd); + + if (msgCmd >= DSMSG_ReplyACK) + break; + + TRKProcessInput(*bufferId); + *bufferId = -1; + } + + if (*bufferId != -1) { + if (buffer->length < 0x40) { + // OSReport("MetroTRK - bad reply size %ld\n", buffer->length); + badReply = TRUE; + } + if (error == DS_NoError && !badReply) { + msgReplyError = buffer->data[8]; + MWTRACE(1, "msg_error : 0x%02x\n", msgReplyError); + } + if (error == DS_NoError && !badReply) { + if ((int)msgCmd != DSMSG_ReplyACK || msgReplyError != DSREPLY_NoError) { + MWTRACE(8, "RequestSend : Bad ack or non ack received msg_command : 0x%02x msg_error 0x%02x\n", msgCmd, + msgReplyError); + badReply = TRUE; + } + } + if (error != DS_NoError || badReply) { + TRKReleaseBuffer(*bufferId); + *bufferId = -1; + } + } + } + } + + if (*bufferId == -1) { + error = DS_Error800; + } + + return error; +} + +/** + * @note Address: 0x800BD7EC + * @note Size: 0x11C + */ +DSError HandleOpenFileSupportRequest(const char* path, u8 replyError, u32* param_3, DSIOResult* ioResult) +{ + DSError error; + int bufferId2; + int bufferId1; + MessageBuffer* tempBuffer; + MessageBuffer* buffer; + CommandReply reply; + + memset(&reply, 0, sizeof(CommandReply)); + *param_3 = 0; + reply.commandID.b = DSMSG_OpenFile; + reply._00 = strlen(path) + 0x40 + 1; + reply.replyError.b = replyError; + *(u16*)&reply._0C = strlen(path) + 1; + TRKGetFreeBuffer(&bufferId1, &buffer); + error = TRKAppendBuffer_ui8(buffer, (u8*)&reply, 0x40); + + if (error == DS_NoError) { + error = TRKAppendBuffer_ui8(buffer, (u8*)path, strlen(path) + 1); + } + + if (error == DS_NoError) { + *ioResult = DS_IONoError; + error = TRKRequestSend(buffer, &bufferId2, 7, 3, 0); + + if (error == DS_NoError) { + tempBuffer = TRKGetBuffer(bufferId2); + } + + *ioResult = *(u32*)(tempBuffer->data + 0x10); + *param_3 = *(u32*)(tempBuffer->data + 0x8); + TRKReleaseBuffer(bufferId2); + } + TRKReleaseBuffer(bufferId1); + return error; +} + +/** + * @note Address: 0x800BD704 + * @note Size: 0xE8 + */ +DSError HandleCloseFileSupportRequest(int replyError, DSIOResult* ioResult) +{ + DSError error; + int replyBufferId; + int bufferId; + MessageBuffer* buffer1; + MessageBuffer* buffer2; + CommandReply reply; + + memset(&reply, 0, sizeof(CommandReply)); + reply.commandID.b = DSMSG_CloseFile; + reply._00 = 0x40; + reply.replyError.r = replyError; + error = TRKGetFreeBuffer(&bufferId, &buffer1); + + if (error == DS_NoError) { + error = TRKAppendBuffer_ui8(buffer1, (u8*)&reply, sizeof(CommandReply)); + } + + if (error == DS_NoError) { + *ioResult = DS_IONoError; + error = TRKRequestSend(buffer1, &replyBufferId, 3, 3, 0); + + if (error == DS_NoError) { + buffer2 = TRKGetBuffer(replyBufferId); + } + + if (error == DS_NoError) { + *ioResult = *(u32*)(buffer2->data + 0x10); + } + + TRKReleaseBuffer(replyBufferId); + } + + TRKReleaseBuffer(bufferId); + return error; +} + +/** + * @note Address: 0x800BD5F4 + * @note Size: 0x110 + */ +DSError HandlePositionFileSupportRequest(DSReplyError replyErr, u32* param_2, u8 param_3, DSIOResult* ioResult) +{ + DSError error; + int bufferId2; + int bufferId1; + MessageBuffer* buffer1; + MessageBuffer* buffer2; + CommandReply reply; + + memset(&reply, 0, sizeof(CommandReply)); + reply.commandID.b = DSMSG_PositionFile; + reply._00 = 0x40; + reply.replyError.r = replyErr; + reply._0C = *param_2; + reply._10[0] = param_3; + error = TRKGetFreeBuffer(&bufferId1, &buffer1); + + if (error == DS_NoError) { + error = TRKAppendBuffer_ui8(buffer1, (u8*)&reply, sizeof(CommandReply)); + } + + if (error == DS_NoError) { + *ioResult = DS_IONoError; + *param_2 = -1; + error = TRKRequestSend(buffer1, &bufferId2, 3, 3, 0); + + if (error == DS_NoError) { + buffer2 = TRKGetBuffer(bufferId2); + + if (buffer2 != nullptr) { + *ioResult = *(u32*)(buffer2->data + 0x10); + *param_2 = *(u32*)(buffer2->data + 0x18); + } + } + + TRKReleaseBuffer(bufferId2); + } + + TRKReleaseBuffer(bufferId1); + return error; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targcont.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targcont.c new file mode 100644 index 0000000..ecf2c1d --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targcont.c @@ -0,0 +1,14 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/** + * @note Address: 0x800C09BC + * @note Size: 0x34 + */ +DSError TRKTargetContinue(void) +{ + TRKTargetSetStopped(0); + UnreserveEXI2Port(); + TRKSwapAndGo(); + ReserveEXI2Port(); + return DS_NoError; +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/target_options.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/target_options.c new file mode 100644 index 0000000..3c70856 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/target_options.c @@ -0,0 +1,19 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +static u8 bUseSerialIO; + +/** + * @note Address: 0x800C0A00 + * @note Size: 0xC + */ +void SetUseSerialIO(u8 sio) +{ + bUseSerialIO = sio; + return; +} + +/** + * @note Address: 0x800C09F0 + * @note Size: 0x10 + */ +u8 GetUseSerialIO(void) { return bUseSerialIO; } diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targimpl.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targimpl.c new file mode 100644 index 0000000..334eb4e --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targimpl.c @@ -0,0 +1,1341 @@ +#include "PowerPC_EABI_Support/MetroTRK/ppc_reg.h" +#include "PowerPC_EABI_Support/MetroTRK/trktypes.h" +#include "PowerPC_EABI_Support/MetroTRK/trkenum.h" +#include "PowerPC_EABI_Support/MetroTRK/dstypes.h" +#include "PowerPC_EABI_Support/MetroTRK/memmap.h" + +extern void TRKUARTInterruptHandler(void); // should probably go in a header + +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 + DSMessageStepOptions type; // 0x4 + u32 count; // 0x8 + u32 rangeStart; // 0xC + u32 rangeEnd; // 0x10 +} TRKStepStatus; + +ProcessorRestoreFlags_PPC gTRKRestoreFlags = { FALSE, FALSE }; + +static TRKExceptionStatus gTRKExceptionStatus = { { 0, 0, 0 }, TRUE, 0 }; + +static TRKStepStatus gTRKStepStatus = { FALSE, DSSTEP_IntoCount, 0, 0 }; + +typedef void (*RegAccessFunc)(void* srcDestPtr, u128 val); + +static void TRKExceptionHandler(u16); +void TRKInterruptHandlerEnableInterrupts(); +static void GetThreadInfo(int*, int*); +DSError TRKPPCAccessSPR(void* srcDestPtr, u32 spr, BOOL read); +DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read); +DSError TRKPPCAccessSpecialReg(void* srcDestPtr, u32* instructionData, BOOL read); +DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read); +void WriteFPSCR(f64*); +void ReadFPSCR(f64*); + +static u16 TRK_saved_exceptionID = 0; +TRKState gTRKState; +Default_PPC gTRKSaveState; +ProcessorState_PPC gTRKCPUState; +u128 TRKvalue128_temp; + +// Instruction macros +#define INSTR_NOP 0x60000000 +#define INSTR_BLR 0x4E800020 +#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) + +#define DSFetch_u32(_p_) (*((u32*)_p_)) +#define DSFetch_u64(_p_) (*((u64*)_p_)) + +void __TRK_set_MSR(register u32 msr); +u32 __TRK_get_MSR(); +void TRK_ppc_memcpy(register void* dest, register const void* src, register int n, register u32 param_4, register u32 param_5); + +/** + * @note Address: 0x800BF790 + * @note Size: 0x2A4 + */ +DSError TRKValidMemory32(const void* addr, size_t length, ValidMemoryOptions readWriteable) +{ + DSError err = DS_InvalidMemory; /* assume range is invalid */ + + const u8* start; + const u8* end; + + s32 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 (((readWriteable == VALIDMEM_Readable) && !gTRKMemMap[i].readable) + || ((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; +} + +/** + * @note Address: 0x800BF644 + * @note Size: 0x14C + */ +DSError TRKTargetAccessMemory(void* data, u32 start, size_t* length, MemoryAccessOptions accessOptions, BOOL read) +{ + DSError error; + u32 uVar5; + void* addr; + u32 param4; + TRKExceptionStatus tempExceptionStatus = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; + + addr = (void*)TRKTargetTranslate(start); + error = TRKValidMemory32(addr, *length, read == FALSE); + + if (error != DS_NoError) { + *length = 0; + } else { + uVar5 = __TRK_get_MSR(); + param4 = uVar5 | gTRKCPUState.Extended1.MSR & 0x10; + + if (read) { + TRK_ppc_memcpy(data, addr, *length, uVar5, param4); + } else { + TRK_ppc_memcpy(addr, data, *length, param4, uVar5); + TRK_flush_cache((u32)addr, *length); + if ((void*)start != addr) { + TRK_flush_cache(start, *length); + } + } + } + + if (gTRKExceptionStatus.exceptionDetected) { + *length = 0; + error = DS_CWDSException; + } + + gTRKExceptionStatus = tempExceptionStatus; + return error; +} + +/** + * @note Address: 0x800BF5F8 + * @note Size: 0x4C + */ +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; +} + +/** + * @note Address: 0x800BF504 + * @note Size: 0xF4 + */ +DSError TRKTargetAccessDefault(u32 firstRegister, u32 lastRegister, MessageBuffer* 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; +} + +/** + * @note Address: 0x800BEFF8 + * @note Size: 0x50C + */ +DSError TRKTargetAccessFP(u32 firstRegister, u32 lastRegister, MessageBuffer* 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; +} + +/** + * @note Address: 0x800BEE88 + * @note Size: 0x170 + */ +DSError TRKTargetAccessExtended1(u32 firstRegister, u32 lastRegister, MessageBuffer* 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; +} + +/** + * @note Address: 0x800BEA50 + * @note Size: 0x438 + */ +DSError TRKTargetAccessExtended2(u32 firstRegister, u32 lastRegister, MessageBuffer* b, size_t* registerStorageSize, BOOL read) +{ + TRKExceptionStatus savedException; + u32 i; + u32 value_buf0[1]; + u32 value_buf[2]; + DSError err; + u32 access_func[10]; + + 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; +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void TRKTargetVersions(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xA4 + */ +void TRKTargetSupportMask(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x60 + */ +void TRKTargetCPUType(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void TRKTargetCheckException(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BE9A4 + * @note Size: 0xAC + */ +void TRKPostInterruptEvent(void) +{ + int eventType; + int local_14; + size_t registerSize; + TRKEvent event; + + if (gTRKState.inputActivated) { + gTRKState.inputActivated = FALSE; + } else { + switch (gTRKCPUState.Extended1.exceptionID & 0xFFFF) { + case 0xd00: + case 0x700: + registerSize = 4; + TRKTargetReadInstruction(&local_14, gTRKCPUState.Default.PC); + + if (local_14 == 0xfe00000) { + eventType = NUBEVENT_Support; + } else { + eventType = NUBEVENT_Breakpoint; + } + break; + default: + eventType = NUBEVENT_Exception; + break; + } + + TRKConstructEvent(&event, eventType); + TRKPostEvent(&event); + } +} + +/** + * @note Address: 0x800BE814 + * @note Size: 0x190 + */ +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; +} + +/** + * @note Address: 0x800BE788 + * @note Size: 0x8C + */ +u32* ConvertAddress(u32 addr) { return (u32*)(addr | 0x80000000); } +DSError TRKTargetAddStopInfo(MessageBuffer* b) +{ + DSError error; + CommandReply reply; + int t; + + memset(&reply, 0, 0x40); + reply._00 = 0x40; + reply.commandID.b = 0x90; + reply.replyError.r = gTRKCPUState.Default.PC; + TRKTargetReadInstruction(&t, gTRKCPUState.Default.PC); + + reply._0C = t; + *(u32*)reply._10 = gTRKCPUState.Extended1.exceptionID & 0xFFFF; + error = TRKAppendBuffer_ui8(b, (u8*)&reply, 0x40); + return error; +} + +/** + * @note Address: 0x800BE704 + * @note Size: 0x84 + */ +void TRKTargetAddExceptionInfo(MessageBuffer* b) +{ + size_t local_58; + u32 local_54; + CommandReply reply; + + memset(&reply, 0, 0x40); + + reply._00 = 0x40; + reply.commandID.b = 0x91; + reply.replyError.r = gTRKExceptionStatus.exceptionInfo.PC; + + TRKTargetReadInstruction(&local_54, gTRKExceptionStatus.exceptionInfo.PC); + + reply._0C = local_54; + *(u32*)reply._10 = gTRKExceptionStatus.exceptionInfo.exceptionID; + + TRKAppendBuffer_ui8(b, (u8*)&reply, 0x40); +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +inline DSError TRKTargetEnableTrace(BOOL val) +{ + if (val) { + gTRKCPUState.Extended1.MSR = (gTRKCPUState.Extended1.MSR | 0x400); + } else { + gTRKCPUState.Extended1.MSR = (gTRKCPUState.Extended1.MSR & ~0x400); + } + return DS_NoError; +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +inline DSError TRKTargetDoStep() +{ + gTRKStepStatus.active = TRUE; + MWTRACE(1, "TargetDoStep()\n"); + TRKTargetEnableTrace(TRUE); + + if (gTRKStepStatus.type == DSSTEP_IntoCount || gTRKStepStatus.type == DSSTEP_OverCount) { + gTRKStepStatus.count--; + } + + TRKTargetSetStopped(FALSE); + return DS_NoError; +} + +/** + * @note Address: N/A + * @note Size: 0x148 + */ +static BOOL TRKTargetCheckStep() +{ + if (gTRKStepStatus.active) { + TRKTargetEnableTrace(FALSE); + + if (TRKTargetStepDone()) { + gTRKStepStatus.active = FALSE; + } else { + TRKTargetDoStep(); + } + } + + return gTRKStepStatus.active; +} + +/** + * @note Address: 0x800BE658 + * @note Size: 0xAC + */ +DSError TRKTargetSingleStep(u32 count, BOOL stepOver) +{ + DSError error = DS_NoError; + + if (stepOver) { + error = DS_UnsupportedError; + } else { + gTRKStepStatus.count = count; + gTRKStepStatus.type = DSSTEP_IntoCount; + error = TRKTargetDoStep(); + } + + return error; +} + +/** + * @note Address: 0x800BE5A0 + * @note Size: 0xB8 + */ +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; +} + +/** + * @note Address: 0x800BE590 + * @note Size: 0x10 + */ +u32 TRKTargetGetPC(void) { return gTRKCPUState.Default.PC; } + +/** + * @note Address: 0x800BE390 + * @note Size: 0x200 + */ + +DSError TRKTargetSupportRequest() +{ + DSIOResult ioResult; + size_t* length; + MessageCommandID commandId; + DSError error; + u32 local_28; + TRKEvent event; + + commandId = gTRKCPUState.Default.GPR[3]; + if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile && commandId != DSMSG_OpenFile && commandId != DSMSG_CloseFile + && commandId != DSMSG_PositionFile) { + TRKConstructEvent(&event, 4); + TRKPostEvent(&event); + return DS_NoError; + } else if (commandId == DSMSG_OpenFile) { + error = HandleOpenFileSupportRequest(gTRKCPUState.Default.GPR[4], gTRKCPUState.Default.GPR[5] & 0xff, gTRKCPUState.Default.GPR[6], + &ioResult); + + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + + gTRKCPUState.Default.GPR[3] = ioResult; + } else if (commandId == DSMSG_CloseFile) { + error = HandleCloseFileSupportRequest(gTRKCPUState.Default.GPR[4], &ioResult); + + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + + gTRKCPUState.Default.GPR[3] = ioResult; + } else if (commandId == DSMSG_PositionFile) { + local_28 = *(u32*)gTRKCPUState.Default.GPR[5]; + error = HandlePositionFileSupportRequest(gTRKCPUState.Default.GPR[4], &local_28, (u8)gTRKCPUState.Default.GPR[6], &ioResult); + + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + + gTRKCPUState.Default.GPR[3] = ioResult; + *(u32*)gTRKCPUState.Default.GPR[5] = local_28; + } else { + length = (size_t*)gTRKCPUState.Default.GPR[5]; + error = TRKSuppAccessFile(gTRKCPUState.Default.GPR[4], (u8*)gTRKCPUState.Default.GPR[6], length, &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(gTRKCPUState.Default.GPR[6], *length); + } + } + + gTRKCPUState.Default.PC += 4; + return error; +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +void TRKTargetFlushCache(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BE380 + * @note Size: 0x10 + */ +BOOL TRKTargetStopped(void) { return gTRKState.isStopped; } + +/** + * @note Address: 0x800BE370 + * @note Size: 0x10 + */ +void TRKTargetSetStopped(uint stopped) { gTRKState.isStopped = stopped; } + +/** + * @note Address: 0x800BE358 + * @note Size: 0x18 + */ +BOOL TRKTargetStop() +{ + gTRKState.isStopped = 1; + return FALSE; +} + +/** + * @note Address: N/A + * @note Size: 0x108 + */ +DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read) +{ + /* Initialize instruction array with nop */ + + u32 access_func[10] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, 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); +} + +/** + * @note Address: N/A + * @note Size: 0xDC + */ +DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read) +{ + // all nop by default + u32 instructionData[] + = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, 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); +} + +/** + * @note Address: N/A + * @note Size: 0x21C + */ +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, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + + if (fpr < 0x20) { + 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 == 0x20) { + if (read) { + ReadFPSCR(srcDestPtr); + } else { + WriteFPSCR(srcDestPtr); + } + + *(u64*)srcDestPtr &= 0xFFFFFFFF; + } else if (fpr == 0x21) { + if (!read) { + *(u32*)srcDestPtr = *((u32*)(srcDestPtr) + 1); + } + + error = TRKPPCAccessSPR(srcDestPtr, SPR_FPECR, read); + if (read) { + DSFetch_u64(srcDestPtr) = DSFetch_u32(srcDestPtr) & 0xffffffffLL; + } + } + + return error; +} + +/** + * @note Address: N/A + * @note Size: 0x68 + */ +#define DEBUG_VECTORREG_ACCESS 0 + +DSError TRKPPCAccessSpecialReg(void* value, u32* access_func, BOOL read) +{ +#if defined(__MWERKS__) +#pragma unused(read) +#elif defined(__GNUC__) + UNUSED(read); +#endif + + typedef void (*asm_access_type)(void*, void*); + + asm_access_type asm_access; + + /* + ** 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[9] = INSTR_BLR; + + /* + ** Now that the instruction array is built, get a function pointer to it. + */ + + asm_access = (asm_access_type)access_func; + +#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((u32)access_func, (sizeof(access_func) * 10)); + (*asm_access)((u32*)value, (void*)&TRKvalue128_temp); + + return DS_NoError; +} + +/** + * @note Address: 0x800BE348 + * @note Size: 0x10 + */ +void TRKTargetSetInputPendingPtr(void* ptr) { gTRKState.inputPendingPtr = ptr; } + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void SetInputState(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void TRKGetInTRKFlag(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BE284 + * @note Size: 0xC4 + */ +DSError TRKTargetAccessARAM(u32 p1, u32 p2, u32* p3, BOOL read) +{ + DSError err; + TRKExceptionStatus status; + + err = DS_NoError; + status = gTRKExceptionStatus; + + gTRKExceptionStatus.exceptionDetected = 0; + + if (read) { + TRK__read_aram(p1, p2, p3); + } else { + TRK__write_aram(p1, p2, p3); + } + + if (gTRKExceptionStatus.exceptionDetected) { + *p3 = 0; + err = 0x702; + } + gTRKExceptionStatus = status; + return err; +} + +/** + * @note Address: 0x800BDEA8 + * @note Size: 0x8 + */ +#ifdef __MWERKS__ // clang-format off +asm u32 __TRK_get_MSR(void) +{ + nofralloc + mfmsr r3 + blr +} +#endif // clang-format on + +/** + * @note Address: 0x800BDEB0 + * @note Size: 0x8 + */ +#ifdef __MWERKS__ // clang-format off +asm void __TRK_set_MSR(register u32 v) +{ + mtmsr v + blr +} +#endif // clang-format on + +/** + * @note Address: 0x800BDEB8 + * @note Size: 0x3C + */ +#ifdef __MWERKS__ // clang-format off +static asm void TRK_ppc_memcpy(register void* dest, register const void* src, register int n, register u32 param_4, register u32 param_5){ + #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 + +/** + * @note Address: 0x800BDEF4 + * @note Size: 0x194 + */ +#ifdef __MWERKS__ // clang-format off +asm void TRKInterruptHandler() { + 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 + +/** + * @note Address: 0x800BE088 + * @note Size: 0x9C + */ +#ifdef __MWERKS__ // clang-format off +static asm void TRKExceptionHandler(u16 r3){ + 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 + +/** + * @note Address: 0x800BE124 + * @note Size: 0xC4 + */ +#ifdef __MWERKS__ // clang-format off +asm void TRKSwapAndGo(){ + 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 + +/** + * @note Address: 0x800BE1E8 + * @note Size: 0x54 + */ +#ifdef __MWERKS__ // clang-format off +asm void TRKInterruptHandlerEnableInterrupts(void) +{ + 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 + +/** + * @note Address: 0x800BE23C + * @note Size: 0x24 + */ +#ifdef __MWERKS__ // clang-format off +asm void ReadFPSCR(register f64*) +{ + nofralloc + stwu r1, -0x40(r1) + stfd f31, 0x10(r1) + psq_st f31, 0x20(r1),0,0 + mffs f31 + stfd f31, 0x0(r3) + psq_l f31, 0x20(r1),0,0 + lfd f31, 0x10(r1) + addi r1, r1, 0x40 + blr + +} +#endif // clang-format on + +/** + * @note Address: 0x800BE260 + * @note Size: 0x24 + */ +#ifdef __MWERKS__ // clang-format off +asm void WriteFPSCR(register f64*){ + nofralloc + stwu r1, -0x40(r1) + stfd f31, 0x10(r1) + psq_st f31, 0x20(r1), 0, 0 + lfd f31, 0(r3) + mtfsf 0xff, f31 + psq_l f31, 0x20(r1), 0, 0 + lfd f31, 0x10(r1) + addi r1, r1, 0x40 + blr +} +#endif // clang-format on diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targsupp.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targsupp.c new file mode 100644 index 0000000..22ed13a --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/targsupp.c @@ -0,0 +1,20 @@ +#include "Dolphin/os.h" + +ASM void targsupp(void) // encapsulating function to get the file to align properly +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + entry TRKAccessFile + twi 31, r0, 0 + blr + entry TRKOpenFile + twi 31, r0, 0 + blr + entry TRKCloseFile + twi 31, r0, 0 + blr + entry TRKPositionFile + twi 31, r0, 0 + blr +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/usr_put.c b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/usr_put.c new file mode 100644 index 0000000..d134369 --- /dev/null +++ b/dolphin sdk not yet linked/src/TRK_MINNOW_DOLPHIN/usr_put.c @@ -0,0 +1,145 @@ +#include "types.h" + +// can't include OS headers bc report needs to not generate crclr +extern void SetTRKConnected(u32); +extern u32 GetTRKConnected(void); +extern void OSReport(const char*); + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +void usr_putchar_serial(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BC384 + * @note Size: 0x88 + */ +BOOL usr_puts_serial(const char* msg) +{ + BOOL connect_ = FALSE; + char c; + char buf[2]; + + while (!connect_ && (c = *msg++) != '\0') { + BOOL connect = GetTRKConnected(); + + buf[0] = c; + buf[1] = '\0'; + + SetTRKConnected(FALSE); + OSReport(buf); + + SetTRKConnected(connect); + connect_ = FALSE; + } + return connect_; +} + +/** + * @note Address: N/A + * @note Size: 0x4 + */ +void usr_put_initialize_ram(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void usr_putchar_ram(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +void usr_puts_ram(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800BC380 + * @note Size: 0x4 + */ +void usr_put_initialize(void) { } + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void usr_putchar(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void usr_puts(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __do_putchar(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __do_puts(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x130 + */ +void __do_puthex32(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __do_puthex8(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __do_puthex4(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __do_puthex2(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/ai/ai.c b/dolphin sdk not yet linked/src/ai/ai.c new file mode 100644 index 0000000..cb4f010 --- /dev/null +++ b/dolphin sdk not yet linked/src/ai/ai.c @@ -0,0 +1,581 @@ +#include "Dolphin/ai.h" +#include "Dolphin/hw_regs.h" +#include "Dolphin/os.h" + +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 vs32 __AI_init_flag = FALSE; +static vs32 __AID_Active = FALSE; + +static OSTime bound_32KHz; +static OSTime bound_48KHz; +static OSTime min_wait; +static OSTime max_wait; +static OSTime buffer; + +static void __AI_set_stream_sample_rate(u32 rate); +static void __AISHandler(s16 interrupt, OSContext* context); +static void __AIDHandler(s16 interrupt, OSContext* context); +static void __AICallbackStackSwitch(register AIDCallback cb); +static void __AI_SRC_INIT(void); + +/** + * @note Address: 0x800F6864 + * @note Size: 0x44 + */ +AIDCallback AIRegisterDMACallback(AIDCallback callback) +{ + s32 oldInts; + AIDCallback ret; + + ret = __AID_Callback; + oldInts = OSDisableInterrupts(); + __AID_Callback = callback; + OSRestoreInterrupts(oldInts); + return ret; +} + +/** + * @note Address: 0x800F68A8 + * @note Size: 0x88 + */ +void AIInitDMA(u32 address, u32 length) +{ + s32 previousInterruptState; + + previousInterruptState = OSDisableInterrupts(); + + __DSPRegs[DSP_DMA_START_HI] = (u16)((__DSPRegs[DSP_DMA_START_HI] & ~0x3FF) | (address >> 16)); + __DSPRegs[DSP_DMA_START_LO] = (u16)((__DSPRegs[DSP_DMA_START_LO] & ~0xFFE0) | (address & 0xFFFF)); + __DSPRegs[DSP_DMA_CONTROL_LEN] = (u16)((__DSPRegs[DSP_DMA_CONTROL_LEN] & ~0x7FFF) | ((length >> 5) & 0xFFFF)); + + OSRestoreInterrupts(previousInterruptState); +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +BOOL AIGetDMAEnableFlag(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F6930 + * @note Size: 0x18 + */ +void AIStartDMA(void) { SET_FLAG(__DSPRegs[DSP_DMA_CONTROL_LEN], DSP_DMA_START_FLAG); } + +/** + * @note Address: 0x800F6948 + * @note Size: 0x18 + */ +void AIStopDMA(void) { RESET_FLAG(__DSPRegs[DSP_DMA_CONTROL_LEN], DSP_DMA_START_FLAG); } + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +u32 AIGetDMABytesLeft(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +u32 AIGetDMAStartAddr(void) +{ + const u32 startAddressHigh = (__DSPRegs[DSP_DMA_START_HI] & 0x03FF) << 16; + const u32 startAddressLow = __DSPRegs[DSP_DMA_START_LO] & 0xFFE0; + + return startAddressHigh | startAddressLow; +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +u32 AIGetDMALength(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +BOOL AICheckInit(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +AISCallback AIRegisterStreamCallback(AISCallback newCallback) +{ + s32 previousInterruptState; + AISCallback previousCallback; + + previousCallback = __AIS_Callback; + + previousInterruptState = OSDisableInterrupts(); + __AIS_Callback = newCallback; + OSRestoreInterrupts(previousInterruptState); + + return previousCallback; +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +u32 AIGetStreamSampleCount(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +void AIResetStreamSampleCount(void) +{ + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_COUNT) | AI_CONTROL_STREAM_SAMPLE_COUNT; +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ + +void AISetStreamTrigger(u32 trigger) { __AIRegs[AI_INTRPT_TIMING] = trigger; } + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +u32 AIGetStreamTrigger(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F6960 + * @note Size: 0xD8 + */ +void AISetStreamPlayState(u32 playState) +{ + s32 previousInterruptState; + u8 rightVolume; + u8 leftVolume; + + // If the requested state is the same as the current state, do nothing + if (playState == AIGetStreamPlayState()) { + return; + } + + // If the sample rate is 0 and the requested state is play, initialize the sample rate converter + if (AIGetStreamSampleRate() == 0 && playState == TRUE) { + rightVolume = AIGetStreamVolRight(); + leftVolume = AIGetStreamVolLeft(); + + // Temporarily mute the audio + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + + // Disable interrupts and initialize the sample rate converter + previousInterruptState = OSDisableInterrupts(); + __AI_SRC_INIT(); + + // Set the stream and state bits in the control register + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_COUNT) | AI_CONTROL_STREAM_SAMPLE_COUNT; + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_PLAY_STATE) | AI_CONTROL_PLAY_STATE; + + // Restore the previous interrupt state + OSRestoreInterrupts(previousInterruptState); + + // Restore the audio volume + AISetStreamVolLeft(rightVolume); + AISetStreamVolRight(leftVolume); + } else { + // Set the state bit in the control register to the requested state + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_PLAY_STATE) | playState; + } +} + +/** + * @note Address: 0x800F6A38 + * @note Size: 0x10 + */ +u32 AIGetStreamPlayState(void) { return __AIRegs[AI_CONTROL] & AI_CONTROL_PLAY_STATE; } + +/** + * @note Address: 0x800F6A48 + * @note Size: 0xE0 + */ +void AISetDSPSampleRate(u32 rate) +{ + u32 playState; + s32 previousInterruptState; + u8 leftVolume; + u8 rightVolume; + u32 streamSampleRate; + + // If the requested rate is the same as the current rate, do nothing + if (rate == AIGetDSPSampleRate()) { + return; + } + + // Clear the DSP sample rate bit in the control register + __AIRegs[AI_CONTROL] &= ~AI_CONTROL_DSP_SAMPLE_RATE; + + if (rate == 0) { + leftVolume = AIGetStreamVolLeft(); + rightVolume = AIGetStreamVolRight(); + playState = AIGetStreamPlayState(); + streamSampleRate = AIGetStreamSampleRate(); + + // Temporarily mute the audio + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + + // Disable interrupts and initialize the sample rate converter + previousInterruptState = OSDisableInterrupts(); + __AI_SRC_INIT(); + + // Set the stream sample count, stream sample rate, and play state bits in the control register + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_COUNT) | AI_CONTROL_STREAM_SAMPLE_COUNT; + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_RATE) | (streamSampleRate * 2); + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_PLAY_STATE) | playState; + + // Set the DSP sample rate bit in the control register + __AIRegs[AI_CONTROL] |= AI_CONTROL_DSP_SAMPLE_RATE; + + // Restore the previous interrupt state + OSRestoreInterrupts(previousInterruptState); + + // Restore the audio volume + AISetStreamVolLeft(leftVolume); + AISetStreamVolRight(rightVolume); + } +} + +/** + * @note Address: 0x800F6B28 + * @note Size: 0x14 + */ +u32 AIGetDSPSampleRate(void) { return ((__AIRegs[AI_CONTROL] >> 6) & 1) ^ 1; } + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void AISetStreamSampleRate(u32 rate) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void __AI_DEBUG_set_stream_sample_rate(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F6B3C + * @note Size: 0xD4 + */ +static void __AI_set_stream_sample_rate(u32 rate) +{ + s32 previousInterruptState; + s32 playState; + u8 leftVolume; + u8 rightVolume; + s32 dspSampleRateState; + + // If the requested rate is the same as the current rate, do nothing + if (rate == AIGetStreamSampleRate()) { + return; + } + + playState = AIGetStreamPlayState(); + leftVolume = AIGetStreamVolLeft(); + rightVolume = AIGetStreamVolRight(); + + // Temporarily mute the audio + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + + // Save the state of the DSP sample rate bit and clear it in the control register + dspSampleRateState = __AIRegs[AI_CONTROL] & AI_CONTROL_DSP_SAMPLE_RATE; + __AIRegs[AI_CONTROL] &= ~AI_CONTROL_DSP_SAMPLE_RATE; + + // Disable interrupts and initialize the sample rate converter + previousInterruptState = OSDisableInterrupts(); + __AI_SRC_INIT(); + + // Restore the DSP sample rate bit in the control register + __AIRegs[AI_CONTROL] |= dspSampleRateState; + + // Set the stream sample count and stream sample rate bits in the control register + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_COUNT) | AI_CONTROL_STREAM_SAMPLE_COUNT; + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_RATE) | (rate * 2); + + // Restore the previous interrupt state + OSRestoreInterrupts(previousInterruptState); + + // Restore the audio play state and volume + AISetStreamPlayState(playState); + AISetStreamVolLeft(leftVolume); + AISetStreamVolRight(rightVolume); +} + +/** + * @note Address: 0x800F6C10 + * @note Size: 0x10 + */ +u32 AIGetStreamSampleRate(void) { return (__AIRegs[AI_CONTROL] >> 1) & 1; } + +/** + * @note Address: 0x800F6C20 + * @note Size: 0x1C + */ +void AISetStreamVolLeft(u8 volume) { __AIRegs[AI_VOLUME] = (__AIRegs[AI_VOLUME] & ~0xFF) | (volume & 0xFF); } + +/** + * @note Address: 0x800F6C3C + * @note Size: 0x10 + */ +u8 AIGetStreamVolLeft(void) { return __AIRegs[AI_VOLUME]; } + +/** + * @note Address: 0x800F6C4C + * @note Size: 0x1C + */ +void AISetStreamVolRight(u8 volume) { __AIRegs[AI_VOLUME] = (__AIRegs[AI_VOLUME] & ~0xFF00) | ((volume & 0xFF) << 8); } + +/** + * @note Address: 0x800F6C68 + * @note Size: 0x10 + */ +u8 AIGetStreamVolRight(void) { return __AIRegs[AI_VOLUME] >> 8; } + +/** + * @note Address: 0x800F6C78 + * @note Size: 0x16C + */ +void AIInit(u8* stack) +{ + // If AI is already initialized, do nothing + if (__AI_init_flag == TRUE) { + return; + } + + // Register AI version + OSRegisterVersion(__AIVersion); + + // Set bounds and buffer sizes in ticks + bound_32KHz = OSNanosecondsToTicks(31524); + bound_48KHz = OSNanosecondsToTicks(42024); + min_wait = OSNanosecondsToTicks(42000); + max_wait = OSNanosecondsToTicks(63000); + buffer = OSNanosecondsToTicks(3000); + + // Initialize AI stream settings + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + AISetStreamTrigger(0); + AIResetStreamSampleCount(); + __AI_set_stream_sample_rate(1); + AISetDSPSampleRate(0); + + // Clear callbacks and set callback stack + __AIS_Callback = 0; + __AID_Callback = 0; + __CallbackStack = stack; + + // Set interrupt handlers and unmask interrupts + __OSSetInterruptHandler(5, __AIDHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_AI); + __OSSetInterruptHandler(8, __AISHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_AI); + + // Set AI initialisation flag to TRUE + __AI_init_flag = TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void AIReset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F6DE4 + * @note Size: 0x7C + */ +static void __AISHandler(s16 interrupt, OSContext* context) +{ + OSContext tmpContext; + __AIRegs[AI_CONTROL] |= 8; + OSClearContext(&tmpContext); + OSSetCurrentContext(&tmpContext); + if (__AIS_Callback != NULL) { + __AIS_Callback(__AIRegs[AI_SAMPLE_COUNTER]); + } + OSClearContext(&tmpContext); + OSSetCurrentContext(context); +} + +/** + * @note Address: 0x800F6E60 + * @note Size: 0xAC + */ +static 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); +} + +/** + * @note Address: 0x800F6F0C + * @note Size: 0x58 + */ +ASM static void __AICallbackStackSwitch(register AIDCallback cb) +{ +#ifdef __MWERKS__ // clang-format off + // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800F6F64 + * @note Size: 0x1E4 + */ +static 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[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~0x20) | 0x20; + __AIRegs[AI_CONTROL] &= ~2; + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~1) | 1; + + temp0 = __AIRegs[AI_SAMPLE_COUNTER]; + + while (temp0 == __AIRegs[AI_SAMPLE_COUNTER]) + ; + rising_32khz = OSGetTime(); + + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~2) | 2; + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~1) | 1; + + temp1 = __AIRegs[AI_SAMPLE_COUNTER]; + while (temp1 == __AIRegs[AI_SAMPLE_COUNTER]) + ; + + rising_48khz = OSGetTime(); + + diff = rising_48khz - rising_32khz; + __AIRegs[AI_CONTROL] &= ~2; + __AIRegs[AI_CONTROL] &= ~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()) + ; +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __ai_src_get_time(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/amcstubs/AmcExi2Stubs.c b/dolphin sdk not yet linked/src/amcstubs/AmcExi2Stubs.c new file mode 100644 index 0000000..ba2c6f2 --- /dev/null +++ b/dolphin sdk not yet linked/src/amcstubs/AmcExi2Stubs.c @@ -0,0 +1,50 @@ +#include "types.h" +#include "Dolphin/AmcExi2Stubs.h" + +/** + * @note Address: 0x800D2644 + * @note Size: 0x4 + */ +void EXI2_Init(vu8** inputPendingPtrRef, AmcEXICallback monitorCallback) { return; } + +/** + * @note Address: 0x800D2648 + * @note Size: 0x4 + */ +void EXI2_EnableInterrupts() { return; } + +/** + * @note Address: 0x800D264C + * @note Size: 0x8 + */ +int EXI2_Poll() { return 0; } + +/** + * @note Address: 0x800D2654 + * @note Size: 0x8 + */ +AmcExiError EXI2_ReadN(void* bytes, u32 length) { return AMC_EXI_NO_ERROR; } + +/** + * @note Address: 0x800D265C + * @note Size: 0x8 + */ +AmcExiError EXI2_WriteN(const void* bytes, u32 length) { return AMC_EXI_NO_ERROR; } + +/** + * @note Address: 0x800D2664 + * @note Size: 0x4 + */ +void EXI2_Reserve() { return; } + +/** + * @note Address: 0x800D2668 + * @note Size: 0x4 + */ +void EXI2_Unreserve() { return; } + +/** + * @note Address: 0x800D266C + * @note Size: 0x8 + */ +BOOL AMC_IsStub() { return TRUE; } diff --git a/dolphin sdk not yet linked/src/ar/ar.c b/dolphin sdk not yet linked/src/ar/ar.c new file mode 100644 index 0000000..6200395 --- /dev/null +++ b/dolphin sdk not yet linked/src/ar/ar.c @@ -0,0 +1,428 @@ +#include "Dolphin/ar.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +char* __ARVersion = "<< Dolphin SDK - AR\trelease build: Nov 26 2003 05:19:42 (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); + +/** + * @note Address: 0x800D2674 + * @note Size: 0x44 + */ +ARCallback ARRegisterDMACallback(ARCallback callback) +{ + ARCallback oldCb; + BOOL enabled; + oldCb = __AR_Callback; + enabled = OSDisableInterrupts(); + __AR_Callback = callback; + OSRestoreInterrupts(enabled); + return oldCb; +} + +/** + * @note Address: 0x800D26B8 + * @note Size: 0x3C + */ +u32 ARGetDMAStatus() +{ + BOOL enabled; + u32 val; + enabled = OSDisableInterrupts(); + val = __DSPRegs[DSP_CONTROL_STATUS] & 0x0200; + OSRestoreInterrupts(enabled); + return val; +} + +/** + * @note Address: 0x800D26F4 + * @note Size: 0xF0 + */ +void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + + // Set main mem address + __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x3ff) | (u16)(mainmem_addr >> 16); + __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)(__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mainmem_addr & 0xffff); + + // Set ARAM address + __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x3ff) | (u16)(aram_addr >> 16); + __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)(__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff); + + // Set DMA buffer size + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x8000) | (type << 15)); + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x3ff) | (u16)(length >> 16); + __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff); + + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800D27E4 + * @note Size: 0x68 + */ +u32 ARAlloc(u32 length) +{ + u32 oldStackPtr; + BOOL enabled; + + enabled = OSDisableInterrupts(); + oldStackPtr = __AR_StackPointer; + __AR_StackPointer += length; + *__AR_BlockLength = length; + __AR_BlockLength++; + __AR_FreeBlocks--; + OSRestoreInterrupts(enabled); + + return oldStackPtr; +} + +/** + * @note Address: 0x800D284C + * @note Size: 0xC4 + */ +u32 ARInit(u32* stack_index_addr, u32 num_entries) +{ + BOOL old; + u16 refresh; + + if (__AR_init_flag == TRUE) { + return __AR_ARAM_USR_BASE_ADDR; + } + + OSRegisterVersion(__ARVersion); + + old = OSDisableInterrupts(); + + __AR_Callback = NULL; + + __OSSetInterruptHandler(__OS_INTERRUPT_DSP_ARAM, __ARHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_ARAM); + + __AR_StackPointer = __AR_ARAM_USR_BASE_ADDR; + __AR_FreeBlocks = num_entries; + __AR_BlockLength = stack_index_addr; + + refresh = (u16)(__DSPRegs[DSP_ARAM_REFRESH] & 0xFF); + + __DSPRegs[DSP_ARAM_REFRESH] = (u16)((__DSPRegs[DSP_ARAM_REFRESH] & ~0xFF) | (refresh & 0xFF)); + + __ARChecksize(); + + __AR_init_flag = TRUE; + + OSRestoreInterrupts(old); + + return __AR_StackPointer; +} + +/** + * @note Address: 0x800D2910 + * @note Size: 0x8 + */ +u32 ARGetBaseAddress() { return __AR_ARAM_USR_BASE_ADDR; } + +/** + * @note Address: 0x800D2918 + * @note Size: 0x8 + */ +u32 ARGetSize() { return __AR_Size; } + +/** + * @note Address: 0x800D2920 + * @note Size: 0x78 + */ +void __ARHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + u16 tmp; + + tmp = __DSPRegs[DSP_CONTROL_STATUS]; + tmp = (u16)((tmp & ~(0x80 | 0x8)) | 0x20); + __DSPRegs[DSP_CONTROL_STATUS] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (__AR_Callback) { + (*__AR_Callback)(); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +/** + * @note Address: 0x800D2998 + * @note Size: 0x20 + */ +void __ARClearInterrupt() +{ + u16 tmp; + tmp = __DSPRegs[DSP_CONTROL_STATUS]; + tmp = (u16)((tmp & ~(0x80 | 0x8)) | 0x20); + __DSPRegs[DSP_CONTROL_STATUS] = tmp; +} + +/** + * @note Address: 0x800D29B8 + * @note Size: 0x10 + */ +u16 __ARGetInterruptStatus() { return ((u16)(__DSPRegs[DSP_CONTROL_STATUS] & 0x20)); } + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +void __ARWaitForDMA() +{ + while (__DSPRegs[DSP_CONTROL_STATUS] & 0x0200) { } +} + +/** + * @note Address: N/A + * @note Size: 0xB0 + */ +void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) +{ + // Main mem address + __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + // ARAM address + __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + // DMA buffer size + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x8000); + + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff)); + + __ARWaitForDMA(); + + __ARClearInterrupt(); +} + +/** + * @note Address: N/A + * @note Size: 0xB0 + */ +void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) +{ + // Main mem address + __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + // ARAM address + __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + // DMA buffer size + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] | 0x8000); + + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff)); + + __ARWaitForDMA(); + + __ARClearInterrupt(); +} + +/** + * @note Address: 0x800D29C8 + * @note Size: 0x17F4 + */ +void __ARChecksize() +{ + u8 test_data_pad[0x20 + 31]; + u8 dummy_data_pad[0x20 + 31]; + u8 buffer_pad[0x20 + 31]; + + u8 save_pad_1[0x20 + 31]; + u8 save_pad_2[0x20 + 31]; + u8 save_pad_3[0x20 + 31]; + u8 save_pad_4[0x20 + 31]; + u8 save_pad_5[0x20 + 31]; + + 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[DSP_ARAM_MODE] & 1)) { } + + ARAM_mode = 3; + ARAM_size = __AR_InternalSize = 0x1000000; + __DSPRegs[DSP_ARAM_SIZE] = (u16)((__DSPRegs[DSP_ARAM_SIZE] & ~(0x7 | 0x38)) | 0x20 | 2 | 1); + + test_data = (u32*)(OSRoundUp32B((u32)(test_data_pad))); + dummy_data = (u32*)(OSRoundUp32B((u32)(dummy_data_pad))); + buffer = (u32*)(OSRoundUp32B((u32)(buffer_pad))); + + save1 = (u32*)(OSRoundUp32B((u32)(save_pad_1))); + save2 = (u32*)(OSRoundUp32B((u32)(save_pad_2))); + save3 = (u32*)(OSRoundUp32B((u32)(save_pad_3))); + save4 = (u32*)(OSRoundUp32B((u32)(save_pad_4))); + save5 = (u32*)(OSRoundUp32B((u32)(save_pad_5))); + + for (i = 0; i < 8; i++) { + *(test_data + i) = 0xDEADBEEF; + *(dummy_data + i) = 0xBAD0BAD0; + } + + DCFlushRange((void*)test_data, 0x20); + DCFlushRange((void*)dummy_data, 0x20); + + __AR_ExpansionSize = 0; + + DCInvalidateRange((void*)save1, 0x20); + __ARReadDMA((u32)save1, ARAM_size + 0, 0x20); + PPCSync(); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + + DCInvalidateRange((void*)save2, 0x20); + __ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save3, 0x20); + __ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save4, 0x20); + __ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save5, 0x20); + __ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + + ARAM_mode |= 0 << 1; + ARAM_size += 0x0200000; + __AR_ExpansionSize = 0x0200000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + + ARAM_mode |= 4 << 1; + ARAM_size += 0x0400000; + __AR_ExpansionSize = 0x0400000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + + ARAM_mode |= 8 << 1; + ARAM_size += 0x0800000; + __AR_ExpansionSize = 0x0800000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + + ARAM_mode |= 12 << 1; + ARAM_size += 0x1000000; + __AR_ExpansionSize = 0x1000000; + } else { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + __ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + + ARAM_mode |= 16 << 1; + ARAM_size += 0x2000000; + __AR_ExpansionSize = 0x2000000; + } + } + } + } + __DSPRegs[DSP_ARAM_SIZE] = (u16)((__DSPRegs[DSP_ARAM_SIZE] & ~(0x7 | 0x38)) | ARAM_mode); + } + + *(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size; + + __AR_Size = ARAM_size; +} diff --git a/dolphin sdk not yet linked/src/ar/arq.c b/dolphin sdk not yet linked/src/ar/arq.c new file mode 100644 index 0000000..9ef2b08 --- /dev/null +++ b/dolphin sdk not yet linked/src/ar/arq.c @@ -0,0 +1,191 @@ +#include "Dolphin/ar.h" + +const char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Nov 26 2003 05:19:43 (0x2301) >>"; + +static ARQRequest* __ARQRequestQueueHi; +static ARQRequest* __ARQRequestTailHi; +static ARQRequest* __ARQRequestQueueLo; +static ARQRequest* __ARQRequestTailLo; +static ARQRequest* __ARQRequestPendingHi; +static ARQRequest* __ARQRequestPendingLo; +static ARQCallback __ARQCallbackHi; +static ARQCallback __ARQCallbackLo; +static u32 __ARQChunkSize; + +static volatile BOOL __ARQ_init_flag = FALSE; + +void __ARQPopTaskQueueHi(void); +void __ARQServiceQueueLo(void); +void __ARQCallbackHack(void); +void __ARQInterruptServiceRoutine(void); +void __ARQInitTempQueue(void); +void __ARQPushTempQueue(ARQRequest* task); + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +void __ARQPopTaskQueueHi() +{ + if (__ARQRequestQueueHi) { + if (__ARQRequestQueueHi->type == ARQ_TYPE_MRAM_TO_ARAM) { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->length); + } else { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->source, __ARQRequestQueueHi->length); + } + + __ARQCallbackHi = __ARQRequestQueueHi->callback; + + __ARQRequestPendingHi = __ARQRequestQueueHi; + + __ARQRequestQueueHi = __ARQRequestQueueHi->next; + } +} + +/** + * @note Address: 0x800D41BC + * @note Size: 0x100 + */ +void __ARQServiceQueueLo() +{ + + if ((__ARQRequestPendingLo == nullptr) && (__ARQRequestQueueLo)) { + __ARQRequestPendingLo = __ARQRequestQueueLo; + __ARQRequestQueueLo = __ARQRequestQueueLo->next; + } + + if (__ARQRequestPendingLo) { + if (__ARQRequestPendingLo->length <= __ARQChunkSize) { + + if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM) { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, + __ARQRequestPendingLo->length); + } else { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, + __ARQRequestPendingLo->length); + } + + __ARQCallbackLo = __ARQRequestPendingLo->callback; + + } else if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM) { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQChunkSize); + + } else { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQChunkSize); + } + + __ARQRequestPendingLo->length -= __ARQChunkSize; + __ARQRequestPendingLo->source += __ARQChunkSize; + __ARQRequestPendingLo->dest += __ARQChunkSize; + } +} + +/** + * @note Address: 0x800D42BC + * @note Size: 0x4 + */ +void __ARQCallbackHack() { } + +/** + * @note Address: 0x800D42C0 + * @note Size: 0xCC + */ +void __ARQInterruptServiceRoutine() +{ + if (__ARQCallbackHi) { + (*__ARQCallbackHi)((u32)__ARQRequestPendingHi); + __ARQRequestPendingHi = nullptr; + __ARQCallbackHi = nullptr; + + } else if (__ARQCallbackLo) { + (*__ARQCallbackLo)((u32)__ARQRequestPendingLo); + __ARQRequestPendingLo = nullptr; + __ARQCallbackLo = nullptr; + } + + __ARQPopTaskQueueHi(); + + if (__ARQRequestPendingHi == nullptr) { + __ARQServiceQueueLo(); + } +} + +/** + * @note Address: 0x800D438C + * @note Size: 0x70 + */ +void ARQInit() +{ + if (__ARQ_init_flag == TRUE) { + return; + } + + OSRegisterVersion(__ARQVersion); + + __ARQRequestQueueHi = __ARQRequestQueueLo = nullptr; + __ARQChunkSize = ARQ_CHUNK_SIZE_DEFAULT; + ARRegisterDMACallback(&__ARQInterruptServiceRoutine); + __ARQRequestPendingHi = nullptr; + __ARQRequestPendingLo = nullptr; + __ARQCallbackHi = nullptr; + __ARQCallbackLo = nullptr; + + __ARQ_init_flag = TRUE; +} + +/** + * @note Address: 0x800D43FC + * @note Size: 0x15C + */ +void ARQPostRequest(ARQRequest* task, u32 owner, u32 type, u32 priority, u32 source, u32 dest, u32 length, ARQCallback callback) +{ + BOOL enabled; + + task->next = nullptr; + task->owner = owner; + task->type = type; + task->source = source; + task->dest = dest; + task->length = length; + + if (callback) { + task->callback = callback; + } else { + task->callback = (ARQCallback)&__ARQCallbackHack; + } + + enabled = OSDisableInterrupts(); + + switch (priority) { + case ARQ_PRIORITY_LOW: + if (__ARQRequestQueueLo) { + __ARQRequestTailLo->next = task; + } else { + __ARQRequestQueueLo = task; + } + __ARQRequestTailLo = task; + + break; + + case ARQ_PRIORITY_HIGH: + if (__ARQRequestQueueHi) { + __ARQRequestTailHi->next = task; + } else { + __ARQRequestQueueHi = task; + } + + __ARQRequestTailHi = task; + + break; + } + + if ((__ARQRequestPendingHi == nullptr) && (__ARQRequestPendingLo == nullptr)) { + __ARQPopTaskQueueHi(); + + if (__ARQRequestPendingHi == nullptr) { + __ARQServiceQueueLo(); + } + } + + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/ax/src/AX.c b/dolphin sdk not yet linked/src/ax/AX.c similarity index 100% rename from src/dolphin/ax/src/AX.c rename to dolphin sdk not yet linked/src/ax/AX.c diff --git a/src/dolphin/ax/src/AXAlloc.c b/dolphin sdk not yet linked/src/ax/AXAlloc.c similarity index 100% rename from src/dolphin/ax/src/AXAlloc.c rename to dolphin sdk not yet linked/src/ax/AXAlloc.c diff --git a/src/dolphin/ax/src/AXAux.c b/dolphin sdk not yet linked/src/ax/AXAux.c similarity index 100% rename from src/dolphin/ax/src/AXAux.c rename to dolphin sdk not yet linked/src/ax/AXAux.c diff --git a/src/dolphin/ax/src/AXCL.c b/dolphin sdk not yet linked/src/ax/AXCL.c similarity index 100% rename from src/dolphin/ax/src/AXCL.c rename to dolphin sdk not yet linked/src/ax/AXCL.c diff --git a/src/dolphin/ax/src/AXComp.c b/dolphin sdk not yet linked/src/ax/AXComp.c similarity index 100% rename from src/dolphin/ax/src/AXComp.c rename to dolphin sdk not yet linked/src/ax/AXComp.c diff --git a/src/dolphin/ax/src/AXOut.c b/dolphin sdk not yet linked/src/ax/AXOut.c similarity index 100% rename from src/dolphin/ax/src/AXOut.c rename to dolphin sdk not yet linked/src/ax/AXOut.c diff --git a/src/dolphin/ax/src/AXProf.c b/dolphin sdk not yet linked/src/ax/AXProf.c similarity index 100% rename from src/dolphin/ax/src/AXProf.c rename to dolphin sdk not yet linked/src/ax/AXProf.c diff --git a/src/dolphin/ax/src/AXSPB.c b/dolphin sdk not yet linked/src/ax/AXSPB.c similarity index 100% rename from src/dolphin/ax/src/AXSPB.c rename to dolphin sdk not yet linked/src/ax/AXSPB.c diff --git a/dolphin sdk not yet linked/src/ax/AXVPB.c b/dolphin sdk not yet linked/src/ax/AXVPB.c new file mode 100644 index 0000000..eba17fd --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AXVPB.c @@ -0,0 +1,966 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__ax.h" + +static u32 __AXSrcCycles[5] = { + 0x00000DF8, + 0x00000F78, + 0x000014B8, + 0x000019F8, + 0x000019F8 +}; + +static u32 __AXMainMixCycles[16] = { + 0x00000000, 0x000002F8, 0x000002F8, + 0x000005BE, 0x000002F8, 0x000005F0, + 0x000005F0, 0x000008B6, 0x00000000, + 0x000004F1, 0x000004F1, 0x000009A6, + 0x000004F1, 0x000009E2, 0x000009E2, + 0x00000E97 +}; + +static u32 __AXAuxMixCycles[32] = { + 0x00000000, 0x000002F8, 0x000002F8, + 0x000005BE, 0x00000000, 0x000004F1, + 0x000004F1, 0x000009A6, 0x000002F8, + 0x000005F0, 0x000005F0, 0x000008B6, + 0x000002F8, 0x000007E9, 0x000007E9, + 0x00000C9E, 0x00000000, 0x000002F8, + 0x000002F8, 0x000005BE, 0x00000000, + 0x000004F1, 0x000004F1, 0x000009A6, + 0x000004F1, 0x000007E9, 0x000007E9, + 0x00000AAF, 0x000004F1, 0x000009E2, + 0x000009E2, 0x00000E97 +}; + +static AXPB __AXPB[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXPBITDBUFFER __AXITD[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXPBU __AXUpdates[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXVPB __AXVPB[AX_MAX_VOICES]; + +static u32 __AXMaxDspCycles; +static u32 __AXRecDspCycles; +static u32 __AXNumVoices; + +u32 __AXGetNumVoices(void) { + return __AXNumVoices; +} + +void __AXServiceVPB(AXVPB* pvpb) { + AXPB* ppbDsp; + AXPB* ppbUser; + u32 sync; + + ASSERTLINE(238, (pvpb->index >= 0) && (pvpb->index < AX_MAX_VOICES)); + + __AXNumVoices += 1; + ppbDsp = &__AXPB[pvpb->index]; + ppbUser = &pvpb->pb; + sync = pvpb->sync; + if (sync == 0) { + ppbUser->state = ppbDsp->state; + ppbUser->ve.currentVolume = ppbDsp->ve.currentVolume; + ppbUser->addr.currentAddressHi = ppbDsp->addr.currentAddressHi; + ppbUser->addr.currentAddressLo = ppbDsp->addr.currentAddressLo; + return; + } + if (sync & AX_SYNC_FLAG_COPYALL) { + // copy the whole PB struct. (size: 0xF4) + u32* src; + u32* dst; + src = (void*)ppbUser; + dst = (void*)ppbDsp; + + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + + if (pvpb->updateCounter != 0) { + u32 count; + src = (void*)&__AXUpdates[pvpb->index]; + dst = (void*)pvpb->updateData; + for (count = pvpb->updateCounter; count; count--) { + *(dst) = *(src); dst+=1; src+=1; + } + } + return; + } + + if (sync & AX_SYNC_FLAG_COPYSELECT) { + ppbDsp->srcSelect = ppbUser->srcSelect; + ppbDsp->coefSelect = ppbUser->coefSelect; + } + + if (sync & AX_SYNC_FLAG_COPYMXRCTRL) { + ppbDsp->mixerCtrl = ppbUser->mixerCtrl; + } + + if (sync & AX_SYNC_FLAG_COPYSTATE) { + ppbDsp->state = ppbUser->state; + } else { + ppbUser->state = ppbDsp->state; + } + + if (sync & AX_SYNC_FLAG_COPYTYPE) { + ppbDsp->type = ppbUser->type; + } + + if (sync & AX_SYNC_FLAG_COPYAXPBMIX) { + // copy AXPBMIX. + u16* src; + u16* dst; + src = (void*)&ppbUser->mix; + dst = (void*)&ppbDsp->mix; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + if (sync & AX_SYNC_FLAG_COPYTSHIFT) { + ppbDsp->itd.targetShiftL = ppbUser->itd.targetShiftL; + ppbDsp->itd.targetShiftR = ppbUser->itd.targetShiftR; + } else if (sync & AX_SYNC_FLAG_COPYITD) { + // copy ITD struct. + u16* src; + u16* dst; + u32* dst_; + src = (void*)&ppbUser->itd; + dst = (void*)&ppbDsp->itd; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); src+=1; + + dst; // fixes reg alloc + dst_ = pvpb->itdBuffer; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; + } + + if (sync & AX_SYNC_FLAG_COPYUPDATE) { + // copy UPDATE struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->update; + src = (void*)&ppbUser->update; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + + if (pvpb->updateCounter) { + u32* src_; + u32* dst_; + u32 count; + + dst_ = (void*)&__AXUpdates[pvpb->index]; + src_ = (void*)&pvpb->updateData; + + for (count = pvpb->updateCounter; count; count--) { + *(dst_) = *(src_); dst_+=1; src_+=1; + } + } + } + + if (sync & AX_SYNC_FLAG_COPYDPOP) { + // copy DPOP struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->dpop; + src = (void*)&ppbUser->dpop; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + if (sync & AX_SYNC_FLAG_SWAPVOL) { + ppbUser->ve.currentVolume = ppbDsp->ve.currentVolume; + ppbDsp->ve.currentDelta = ppbUser->ve.currentDelta; + } else if (sync & AX_SYNC_FLAG_COPYVOL) { + ppbDsp->ve.currentVolume = ppbUser->ve.currentVolume; + ppbDsp->ve.currentDelta = ppbUser->ve.currentDelta; + } + + if (sync & AX_SYNC_FLAG_COPYFIR) { + // copy FIR struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->fir; + src = (void*)&ppbUser->fir; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + if (sync & (AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | AX_SYNC_FLAG_COPYCURADDR)) { + if (sync & AX_SYNC_FLAG_COPYLOOP) { + ppbDsp->addr.loopFlag = ppbUser->addr.loopFlag; + } + if (sync & AX_SYNC_FLAG_COPYLOOPADDR) { + *(u32*)&ppbDsp->addr.loopAddressHi = *(u32*)&ppbUser->addr.loopAddressHi; + } + if (sync & AX_SYNC_FLAG_COPYENDADDR) { + *(u32*)&ppbDsp->addr.endAddressHi = *(u32*)&ppbUser->addr.endAddressHi; + } + if (sync & AX_SYNC_FLAG_COPYCURADDR) { + *(u32*)&ppbDsp->addr.currentAddressHi = *(u32*)&ppbUser->addr.currentAddressHi; + } else { + *(u32*)&ppbUser->addr.currentAddressHi = *(u32*)&ppbDsp->addr.currentAddressHi; + } + } else if (sync & AX_SYNC_FLAG_COPYADDR) { + // copy ADDR struct. + u32* src; + u32* dst; + dst = (void*)&ppbDsp->addr; + src = (void*)&ppbUser->addr; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } else { + ppbUser->addr.currentAddressHi = ppbDsp->addr.currentAddressHi; + ppbUser->addr.currentAddressLo = ppbDsp->addr.currentAddressLo; + } + + if (sync & AX_SYNC_FLAG_COPYADPCM) { + // copy ADPCM struct. + u32* src; + u32* dst; + dst = (void*)&ppbDsp->adpcm; + src = (void*)&ppbUser->adpcm; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + + if (sync & AX_SYNC_FLAG_COPYRATIO) { + ppbDsp->src.ratioHi = ppbUser->src.ratioHi; + ppbDsp->src.ratioLo = ppbUser->src.ratioLo; + } else if (sync & AX_SYNC_FLAG_COPYSRC) { + // copy SRC struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->src; + src = (void*)&ppbUser->src; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + + if (sync & AX_SYNC_FLAG_COPYADPCMLOOP) { + // copy ADPCMLOOP struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->adpcmLoop; + src = (void*)&ppbUser->adpcmLoop; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + if (sync & 0x400000) { + ppbDsp->lpf.a0 = ppbUser->lpf.a0; + ppbDsp->lpf.b0 = ppbUser->lpf.b0; + return; + } + + if (sync & 0x200000) { + // copy AXPBLPF struct + u16* src; + u16* dst; + + dst = (void*)&ppbDsp->lpf; + src = (void*)&ppbUser->lpf; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } +} + +void __AXDumpVPB(AXVPB* pvpb) { + AXPB* ppbDsp; + + ppbDsp = &__AXPB[pvpb->index]; + if (ppbDsp->state == 1) { + __AXDepopVoice(ppbDsp); + } + pvpb->pb.state = ppbDsp->state = ppbDsp->update.updNum[0] + = ppbDsp->update.updNum[1] = ppbDsp->update.updNum[2] + = ppbDsp->update.updNum[3] = ppbDsp->update.updNum[4] = 0; + __AXPushCallbackStack(pvpb); +} + +void __AXSyncPBs(u32 lessDlpfycles) { + u32 cycles; + u32 i; + AXVPB* pvpb; + + __AXNumVoices = 0; + DCInvalidateRange(__AXPB, sizeof(__AXPB)); + DCInvalidateRange(__AXITD, sizeof(__AXITD)); + cycles = (__AXGetCommandListCycles() + 0x10000) - 0x55F0 + lessDlpfycles; + + for (i = 31; i; i--) { + for (pvpb = __AXGetStackHead(i); pvpb; pvpb = pvpb->next) { + if (pvpb->depop != 0) { + __AXDepopVoice(&__AXPB[pvpb->index]); + } + + if ((pvpb->pb.state == 1) || (pvpb->updateCounter != 0)) { + if (pvpb->pb.srcSelect != 2) { + cycles += __AXSrcCycles[pvpb->pb.src.ratioHi]; + } + + if (pvpb->pb.lpf.on) { + cycles += 555; + } + + cycles += __AXMainMixCycles[pvpb->pb.mixerCtrl & 0xF] + __AXAuxMixCycles[(pvpb->pb.mixerCtrl >> 4) & 0x1F] + __AXAuxMixCycles[(pvpb->pb.mixerCtrl >> 9) & 0x1F] + 0x8C; + if (__AXMaxDspCycles > cycles) { + __AXServiceVPB(pvpb); + } else { + __AXDumpVPB(pvpb); + } + } else { + __AXServiceVPB(pvpb); + } + + pvpb->sync = 0; + pvpb->depop = 0; + pvpb->updateMS = pvpb->updateCounter = 0; + pvpb->updateWrite = pvpb->updateData; + } + } + + __AXRecDspCycles = cycles; + for (pvpb = __AXGetStackHead(0); pvpb; pvpb = pvpb->next) { + if (pvpb->depop != 0) { + __AXDepopVoice(&__AXPB[pvpb->index]); + } + pvpb->depop = 0; + __AXPB[pvpb->index].state = __AXPB[pvpb->index].update.updNum[0] = __AXPB[pvpb->index].update.updNum[1] + = __AXPB[pvpb->index].update.updNum[2] = __AXPB[pvpb->index].update.updNum[3] + = __AXPB[pvpb->index].update.updNum[4] = 0; + } + + DCFlushRange(__AXPB, sizeof(__AXPB)); + DCFlushRange(__AXITD, sizeof(__AXITD)); + DCFlushRange(__AXUpdates, sizeof(__AXUpdates)); +} + +AXPB* __AXGetPBs(void) { + return __AXPB; +} + +void __AXSetPBDefault(AXVPB* p) { + p->pb.state = 0; + p->pb.itd.flag = 0; + p->sync = 0x2000A4; + p->updateMS = p->updateCounter = 0; + p->updateWrite = p->updateData; + p->pb.update.updNum[0] = p->pb.update.updNum[1] = p->pb.update.updNum[2] = p->pb.update.updNum[3] = p->pb.update.updNum[4] = 0; + p->pb.lpf.on = 0; +} + +void __AXVPBInit(void) { + u32 i; + AXPB* ppb; + AXPBITDBUFFER* ppbi; + AXPBU* ppbu; + AXVPB* pvpb; + u32* p; + +#ifdef DEBUG + OSReport("Initializing AXVPB code module\n"); +#endif + __AXMaxDspCycles = OS_BUS_CLOCK / 400; + __AXRecDspCycles = 0; + +#define BUFFER_MEMSET(buffer, size) \ + { \ + p = (u32*)&buffer; \ + for (i = size; i != 0; i--) { \ + *p = 0; \ + p++; \ + } \ + } + + BUFFER_MEMSET(__AXPB, 0xF40); + BUFFER_MEMSET(__AXITD, 0x400); + BUFFER_MEMSET(__AXVPB, 0x22C0); + + for (i = 0; i < AX_MAX_VOICES; i++) { + ppb = &__AXPB[i]; + ppbi = &__AXITD[i]; + ppbu = &__AXUpdates[i]; + pvpb = &__AXVPB[i]; + + ASSERTLINE(913, (u32)ppb ^ 0x1F); + ASSERTLINE(914, (u32)ppbi ^ 0x1F); + ASSERTLINE(915, (u32)ppbu ^ 0x1F); + + pvpb->index = i; + pvpb->updateWrite = pvpb->updateData; + pvpb->itdBuffer = ppbi; + __AXSetPBDefault(pvpb); + + if (i == 0x3F) { + pvpb->pb.nextHi = pvpb->pb.nextLo = ppb->nextHi = ppb->nextLo = 0; + } else { + pvpb->pb.nextHi = (u16)( (u32)((char*)ppb + sizeof(AXPB)) >> 16 ); + pvpb->pb.nextLo = (u16)( (u32)((char*)ppb + sizeof(AXPB)) ); + ppb->nextHi = (u16)( (u32)((char*)ppb + sizeof(AXPB)) >> 16 ); + ppb->nextLo = (u16)( (u32)((char*)ppb + sizeof(AXPB)) ); + } + + pvpb->pb.currHi = (u16)(((u32)ppb) >> 16); + pvpb->pb.currLo = (u16)((u32)ppb); + ppb->currHi = (u16)(((u32)ppb) >> 16); + ppb->currLo = (u16)((u32)ppb); + pvpb->pb.itd.bufferHi = (u16)(((u32)ppbi) >> 16); + pvpb->pb.itd.bufferLo = (u16)((u32)ppbi); + ppb->itd.bufferHi = (u16)(((u32)ppbi) >> 16); + ppb->itd.bufferLo = (u16)((u32)ppbi); + pvpb->pb.update.dataHi = (u16)(((u32)ppbu) >> 16); + pvpb->pb.update.dataLo = (u16)((u32)ppbu); + ppb->update.dataHi = (u16)(((u32)ppbu) >> 16); + ppb->update.dataLo = (u16)((u32)ppbu); + + pvpb->priority = 1; + __AXPushFreeStack(pvpb); + } + + DCFlushRange(__AXPB, sizeof(__AXPB)); +} + +void __AXVPBQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXVPB code module\n"); +#endif +} + +void AXSetVoiceSrcType(AXVPB* p, u32 type) { + BOOL old; + AXPB* ppb; + + ASSERTLINE(1020, p); + ASSERTLINE(1021, type <= AX_SRC_TYPE_4TAP_16K); + + old = OSDisableInterrupts(); + ppb = &p->pb; + switch(type) { + case AX_SRC_TYPE_NONE: + ppb->srcSelect = 2; + break; + case AX_SRC_TYPE_LINEAR: + ppb->srcSelect = 1; + break; + case AX_SRC_TYPE_4TAP_8K: + ppb->srcSelect = 0; + ppb->coefSelect = 0; + break; + case AX_SRC_TYPE_4TAP_12K: + ppb->srcSelect = 0; + ppb->coefSelect = 1; + break; + case AX_SRC_TYPE_4TAP_16K: + ppb->srcSelect = 0; + ppb->coefSelect = 2; + break; + } + + p->sync |= AX_SYNC_FLAG_COPYSELECT; + OSRestoreInterrupts(old); +} + +void AXSetVoiceState(AXVPB* p, u16 state) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.state = state; + p->sync |= AX_SYNC_FLAG_COPYSTATE; + if (state == 0) { + p->depop = 1; + } + OSRestoreInterrupts(old); +} + +void AXSetVoiceType(AXVPB* p, u16 type) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.type = type; + p->sync |= AX_SYNC_FLAG_COPYTYPE; + OSRestoreInterrupts(old); +} + +void AXSetVoiceMix(AXVPB* p, AXPBMIX* mix) { + BOOL old; + u16 mixerCtrl; + u16* dst; + u16* src; + + src = (u16*)mix; + dst = (u16*)&p->pb.mix; + mixerCtrl = 0; + + old = OSDisableInterrupts(); + + if ((*dst++ = *src++)) mixerCtrl |= 0x1; + if ((*dst++ = *src++)) mixerCtrl |= 0x9; + if ((*dst++ = *src++)) mixerCtrl |= 0x2; + if ((*dst++ = *src++)) mixerCtrl |= 0xA; + if ((*dst++ = *src++)) mixerCtrl |= 0x10; + if ((*dst++ = *src++)) mixerCtrl |= 0x50; + if ((*dst++ = *src++)) mixerCtrl |= 0x20; + if ((*dst++ = *src++)) mixerCtrl |= 0x60; + if ((*dst++ = *src++)) mixerCtrl |= 0x200; + if ((*dst++ = *src++)) mixerCtrl |= 0xA00; + if ((*dst++ = *src++)) mixerCtrl |= 0x400; + if ((*dst++ = *src++)) mixerCtrl |= 0xC00; + if ((*dst++ = *src++)) mixerCtrl |= 0x1000; + if ((*dst++ = *src++)) mixerCtrl |= 0x3000; + if ((*dst++ = *src++)) mixerCtrl |= 0x4; + if ((*dst++ = *src++)) mixerCtrl |= 0xC; + if ((*dst++ = *src++)) mixerCtrl |= 0x80; + if ((*dst++ = *src++)) mixerCtrl |= 0x180; + + p->pb.mixerCtrl = mixerCtrl; + p->sync |= (AX_SYNC_FLAG_COPYAXPBMIX | AX_SYNC_FLAG_COPYMXRCTRL); + OSRestoreInterrupts(old); +} + +void AXSetVoiceItdOn(AXVPB* p) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.itd.flag = 1; + p->pb.itd.shiftL = p->pb.itd.shiftR = p->pb.itd.targetShiftL = p->pb.itd.targetShiftR = 0; + p->sync &= ~(AX_SYNC_FLAG_COPYTSHIFT); + p->sync |= AX_SYNC_FLAG_COPYITD; + OSRestoreInterrupts(old); +} + +void AXSetVoiceItdTarget(AXVPB* p, u16 lShift, u16 rShift) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.itd.targetShiftL = lShift; + p->pb.itd.targetShiftR = rShift; + p->sync |= AX_SYNC_FLAG_COPYTSHIFT; + OSRestoreInterrupts(old); +} + +void AXSetVoiceUpdateIncrement(AXVPB* p) { + BOOL old; + + old = OSDisableInterrupts(); + p->updateMS++; + p->sync |= AX_SYNC_FLAG_COPYUPDATE; + ASSERTMSGLINE(1191, p->updateMS <= 4, "PB updates cannot exceed 5ms\n"); + OSRestoreInterrupts(old); +} + +void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data) { + BOOL old; + + old = OSDisableInterrupts(); + p->updateCounter+=2; + ASSERTMSGLINE(1205, p->updateCounter <= 128, "PB update block exceeded 128 words\n"); + + *(p->updateWrite) = param; p->updateWrite+=1; + *(p->updateWrite) = data; p->updateWrite+=1; + p->sync |= AX_SYNC_FLAG_COPYUPDATE; + OSRestoreInterrupts(old); +} + +void AXSetVoiceDpop(AXVPB* p, AXPBDPOP* dpop) { + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.dpop; + src = (void*)dpop; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + p->sync |= AX_SYNC_FLAG_COPYDPOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceVe(AXVPB* p, AXPBVE* ve) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.ve.currentVolume = ve->currentVolume; + p->pb.ve.currentDelta = ve->currentDelta; + p->sync |= AX_SYNC_FLAG_COPYVOL; + OSRestoreInterrupts(old); +} + +void AXSetVoiceVeDelta(AXVPB* p, s16 delta) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.ve.currentDelta = delta; + p->sync |= AX_SYNC_FLAG_SWAPVOL; + OSRestoreInterrupts(old); +} + +void AXSetVoiceFir(AXVPB* p, AXPBFIR* fir) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.fir.numCoefs = fir->numCoefs; + p->pb.fir.coefsHi = fir->coefsHi; + p->pb.fir.coefsLo = fir->coefsLo; + p->sync |= AX_SYNC_FLAG_COPYFIR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr) { + BOOL old; + u32* dst; + u32* src; + + dst = (void*)&p->pb.addr; + src = (void*)addr; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + switch(addr->format) { + case 0: + ASSERTMSGLINE(1335, (addr->loopAddressLo & 0xF) > 1, "*** loop address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(1340, (addr->endAddressLo & 0xF) > 1, "*** end address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(1345, (addr->currentAddressLo & 0xF) > 1, "*** current address on ADPCM frame header! ***\n"); + break; + case 10: + dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0x08000000; dst+=1; + *(dst) = 0; dst+=1; + break; + case 25: + dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0x01000000; dst+=1; + *(dst) = 0; dst+=1; + break; + default: + ASSERTMSGLINE(1389, 0, "unknown addr->formaqt in PB\n"); + break; + } + + p->sync &= ~(AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | AX_SYNC_FLAG_COPYCURADDR); + p->sync |= (AX_SYNC_FLAG_COPYADDR | AX_SYNC_FLAG_COPYADPCM); + OSRestoreInterrupts(old); +} + +void AXSetVoiceLoop(AXVPB* p, u16 loop) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.loopFlag = loop; + p->sync |= AX_SYNC_FLAG_COPYLOOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceLoopAddr(AXVPB* p, u32 addr) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.loopAddressHi = (addr >> 0x10); + p->pb.addr.loopAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYLOOPADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceEndAddr(AXVPB* p, u32 addr) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.endAddressHi = (addr >> 0x10); + p->pb.addr.endAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYENDADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceCurrentAddr(AXVPB* p, u32 addr) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.currentAddressHi = (addr >> 0x10); + p->pb.addr.currentAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYCURADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAdpcm(AXVPB* p, AXPBADPCM* adpcm) { + BOOL old; + u32* dst; + u32* src; + + dst = (void*)&p->pb.adpcm; + src = (void*)adpcm; + + old = OSDisableInterrupts(); + + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + p->sync |= AX_SYNC_FLAG_COPYADPCM; + OSRestoreInterrupts(old); +} + +void AXSetVoiceSrc(AXVPB* p, AXPBSRC* src_) { + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.src; + src = (void*)src_; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + p->sync &= ~(AX_SYNC_FLAG_COPYRATIO); + p->sync |= AX_SYNC_FLAG_COPYSRC; + OSRestoreInterrupts(old); +} + +void AXSetVoiceSrcRatio(AXVPB* p, float ratio) { + u32 r; + BOOL old; + + old = OSDisableInterrupts(); + r = 65536.0f* ratio; + if (r > 0x40000) { + r = 0x40000; + } + p->pb.src.ratioHi = ((u32)r >> 0x10); + p->pb.src.ratioLo = ((u32)r); + p->sync |= AX_SYNC_FLAG_COPYRATIO; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAdpcmLoop(AXVPB* p, AXPBADPCMLOOP* adpcmloop) { + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.adpcmLoop; + src = (void*)adpcmloop; + old = OSDisableInterrupts(); + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + p->sync |= AX_SYNC_FLAG_COPYADPCMLOOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceLpf(AXVPB* p, AXPBLPF* lpf) { + BOOL old; + u16* dst; + u16* src; + + dst = (u16*)&p->pb.lpf; + src = (u16*)lpf; + + old = OSDisableInterrupts(); + + *dst = *src; dst++; src++; + *dst = *src; dst++; src++; + *dst = *src; dst++; src++; + *dst = *src; dst++; src++; + p->sync |= 0x200000; + + OSRestoreInterrupts(old); +} + +void AXSetVoiceLpfCoefs(AXVPB* p, u16 a0, u16 b0) { + BOOL old; + old = OSDisableInterrupts(); + + p->pb.lpf.a0 = a0; + p->pb.lpf.b0 = b0; + p->sync |= 0x400000; + + OSRestoreInterrupts(old); +} + +#define PI 3.14159265358979323846f + +void AXGetLpfCoefs(u16 freq, u16* a0, u16* b0) { + f32 bb; + f32 cc; + + ASSERTMSGLINE(1616, freq <= 16000, "freq is out of range"); + + cc = 2.0f - cos(((PI * 2) * (f32)freq) / 32000.0f); + bb = sqrt((cc * cc) - 1.0f) - cc; + + *b0 = 32768.0f * -bb; + *a0 = 0x7FFF - *b0; +} + +void AXSetMaxDspCycles(u32 cycles) { + __AXMaxDspCycles = cycles; +} + +u32 AXGetMaxDspCycles(void) { + return __AXMaxDspCycles; +} + +u32 AXGetDspCycles(void) { + return __AXRecDspCycles; +} diff --git a/src/dolphin/ax/src/DSPCode.c b/dolphin sdk not yet linked/src/ax/DSPCode.c similarity index 100% rename from src/dolphin/ax/src/DSPCode.c rename to dolphin sdk not yet linked/src/ax/DSPCode.c diff --git a/src/dolphin/ax/src/__ax.h b/dolphin sdk not yet linked/src/ax/__ax.h similarity index 100% rename from src/dolphin/ax/src/__ax.h rename to dolphin sdk not yet linked/src/ax/__ax.h diff --git a/src/dolphin/axfx/src/__axfx.h b/dolphin sdk not yet linked/src/axfx/__axfx.h similarity index 100% rename from src/dolphin/axfx/src/__axfx.h rename to dolphin sdk not yet linked/src/axfx/__axfx.h diff --git a/src/dolphin/axfx/src/axfx.c b/dolphin sdk not yet linked/src/axfx/axfx.c similarity index 100% rename from src/dolphin/axfx/src/axfx.c rename to dolphin sdk not yet linked/src/axfx/axfx.c diff --git a/src/dolphin/axfx/src/chorus.c b/dolphin sdk not yet linked/src/axfx/chorus.c similarity index 100% rename from src/dolphin/axfx/src/chorus.c rename to dolphin sdk not yet linked/src/axfx/chorus.c diff --git a/src/dolphin/axfx/src/delay.c b/dolphin sdk not yet linked/src/axfx/delay.c similarity index 100% rename from src/dolphin/axfx/src/delay.c rename to dolphin sdk not yet linked/src/axfx/delay.c diff --git a/dolphin sdk not yet linked/src/axfx/reverb_hi.c b/dolphin sdk not yet linked/src/axfx/reverb_hi.c new file mode 100644 index 0000000..f770700 --- /dev/null +++ b/dolphin sdk not yet linked/src/axfx/reverb_hi.c @@ -0,0 +1,735 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__axfx.h" + +// prototypes +static void DLsetdelay(AXFX_REVHI_DELAYLINE* dl, s32 lag); +static int DLcreate(AXFX_REVHI_DELAYLINE* dl, s32 max_length); +static void DLdelete(AXFX_REVHI_DELAYLINE* dl); +static int ReverbHICreate(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk); +static int ReverbHIModify(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk); +static void HandleReverb(s32* sptr, AXFX_REVHI_WORK* rv, s32 k); +static void ReverbHICallback(s32* left, s32* right, s32* surround, AXFX_REVHI_WORK* rv); +static void ReverbHIFree(AXFX_REVHI_WORK* rv); + +static void DLsetdelay(AXFX_REVHI_DELAYLINE* dl, s32 lag) { + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) { + dl->outPoint += dl->length; + } +} + +static int DLcreate(AXFX_REVHI_DELAYLINE* dl, s32 max_length) { + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length << 2); + ASSERTMSGLINE(51, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) { + return 0; + } + + memset(dl->inputs, 0, max_length << 2); + dl->lastOutput = 0.0f; + DLsetdelay(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdelete(AXFX_REVHI_DELAYLINE* dl) { + __AXFXFree(dl->inputs); +} + +static int ReverbHICreate(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk) { + u8 i; + u8 k; + static s32 lens[8] = { + 0x000006FD, + 0x000007CF, + 0x0000091D, + 0x000001B1, + 0x00000095, + 0x0000002F, + 0x00000049, + 0x00000043 + }; + + ASSERTMSGLINE(105, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + crosstalk >= 0.0f && crosstalk <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (crosstalk < 0.0f ) || (crosstalk > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f )) { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVHI_WORK)); + + for (k = 0; k < 3; k++) { + for (i = 0; i < 3; i++) { + if (DLcreate(&rv->C[i + (k * 3)], lens[i] + 2) == 0) { + ReverbHIFree(rv); + return 0; + } + + DLsetdelay(&rv->C[i + (k * 3)], lens[i]); + rv->combCoef[i + (k * 3)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) { + if (DLcreate(&rv->AP[i + (k * 3)], lens[i + 3] + 2) == 0) { + ReverbHIFree(rv); + return 0; + } + DLsetdelay(&rv->AP[i + (k * 3)], lens[i + 3]); + } + + if (DLcreate(&rv->AP[2 + (k * 3)], lens[k + 5] + 2) == 0) { + ReverbHIFree(rv); + return 0; + } + DLsetdelay(&rv->AP[2 + (k * 3)], lens[k + 5]); + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->crosstalk = crosstalk; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + if (0.0f != preDelay) { + rv->preDelayTime = (32000.0f * preDelay); + for(i = 0; i < 3; i++) { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(173, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) { + ReverbHIFree(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } else { + rv->preDelayTime = 0; + for(i = 0; i < 3; i++) { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbHIModify(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk) { + u8 i; + + ASSERTMSGLINE(209, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + crosstalk >= 0.0f && crosstalk <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f ) + || (mix < 0.0f ) || (mix > 1.0f ) + || (crosstalk < 0.0f ) || (crosstalk > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f)) { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->crosstalk = crosstalk; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 9; i++) { + DLdelete(&rv->AP[i]); + } + + for (i = 0; i < 9; i++) { + DLdelete(&rv->C[i]); + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbHICreate(rv, coloration, time, mix, damping, preDelay, crosstalk); +} + +const static double i2fMagic = 4503601774854144.0; +const static f32 value1_0 = 1.0f; +const static f32 value0_3 = 0.3f; +const static f32 value0_6 = 0.6f; + +asm static void DoCrossTalk(register s32* l, register s32* r, register f32 cross, register f32 invcross) { + nofralloc + stwu r1, -48(r1) + stfd f14, 40(r1) + lis r5, i2fMagic@ha + lfd f0, i2fMagic@l(r5) + lis r5, 0x4330 // 176.0f (0x43300000) + stw r5, 8(r1) + stw r5, 16(r1) + stw r5, 24(r1) + stw r5, 32(r1) + ps_merge00 f3, invcross, cross + ps_merge00 f4, cross, invcross + lis r5, value1_0@ha + lfs f5, value1_0@l(r5) + li r5, 79 + mtctr r5 + li r10, -8 + li r11, -4 + ps_muls0 f4, f4, f5 + lwz r6, 0(l) + lwz r7, 0(r) + xoris r6, r6, 0x8000 + lwz r8, 4(l) + xoris r7, r7, 0x8000 + lwz r9, 4(r) + xoris r8, r8, 0x8000 + stw r6, 12(r1) + xoris r9, r9, 0x8000 + stw r7, 20(r1) + stw r8, 28(r1) + stw r9, 36(r1) + lfd f5, 8(r1) + lfd f6, 16(r1) + fsubs f5, f5, f0 + lfd f7, 24(r1) + fsubs f6, f6, f0 + lfd f8, 32(r1) + fsubs f7, f7, f0 + fsubs f8, f8, f0 +loop: + ps_merge00 f9, f5, f6 + lwzu r6, 8(l) + ps_merge00 f10, f7, f8 + lwzu r7, 8(r) + xoris r6, r6, 0x8000 + lwz r8, 4(l) + ps_mul f11, f9, f3 + xoris r7, r7, 0x8000 + ps_mul f12, f9, f4 + lwz r9, 4(r) + ps_mul f13, f10, f3 + xoris r8, r8, 0x8000 + ps_mul f14, f10, f4 + stw r6, 12(r1) + ps_sum0 f11, f11, f11, f11 + xoris r9, r9, 0x8000 + ps_sum0 f12, f12, f12, f12 + stw r7, 20(r1) + ps_sum0 f13, f13, f13, f13 + stw r8, 28(r1) + ps_sum0 f14, f14, f14, f14 + stw r9, 36(r1) + fctiw f11, f11 + lfd f5, 8(r1) + fctiw f12, f12 + lfd f6, 16(r1) + fctiw f13, f13 + fsubs f5, f5, f0 + fctiw f14, f14 + lfd f7, 24(r1) + stfiwx f11, r10, l + fsubs f6, f6, f0 + stfiwx f12, r10, r + lfd f8, 32(r1) + stfiwx f13, r11, l + fsubs f7, f7, f0 + stfiwx f14, r11, r + fsubs f8, f8, f0 + bdnz loop + ps_merge00 f9, f5, f6 + addi l, l, 8 + ps_merge00 f10, f7, f8 + addi r, r, 8 + ps_mul f11, f9, f3 + ps_mul f12, f9, f4 + ps_mul f13, f10, f3 + ps_mul f14, f10, f4 + ps_sum0 f11, f11, f11, f11 + ps_sum0 f12, f12, f12, f12 + ps_sum0 f13, f13, f13, f13 + ps_sum0 f14, f14, f14, f14 + fctiw f11, f11 + fctiw f12, f12 + fctiw f13, f13 + fctiw f14, f14 + stfiwx f11, r10, l + stfiwx f12, r10, r + stfiwx f13, r11, l + stfiwx f14, r11, r + lfd f14, 40(r1) + addi r1, r1, 48 + blr +} + +asm static void HandleReverb(register s32* sptr, register AXFX_REVHI_WORK* rv, register s32 k) { + nofralloc + stwu r1, -0xc0(r1) + stmw r14, 0x8(r1) + stfd f14, 0x60(r1) + stfd f15, 0x68(r1) + stfd f16, 0x70(r1) + stfd f17, 0x78(r1) + stfd f18, 0x80(r1) + stfd f19, 0x88(r1) + stfd f20, 0x90(r1) + stfd f21, 0x98(r1) + stfd f22, 0xa0(r1) + stfd f23, 0xa8(r1) + stfd f24, 0xb0(r1) + stfd f25, 0xb8(r1) + stw k, 0x50(r1) + stw rv, 0x54(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, AXFX_REVHI_WORK.allPassCoeff(rv) + lfs f15, AXFX_REVHI_WORK.damping(rv) + lfs f8, AXFX_REVHI_WORK.level(rv) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 + addi r29, rv, AXFX_REVHI_WORK.C + add r29, r29, r31 + addi r27, rv, AXFX_REVHI_WORK.AP + add r27, r27, r31 + slwi r31, r30, 2 + add r31, r31, rv + lfs f22, AXFX_REVHI_WORK.combCoef[0](r31) + lfs f23, AXFX_REVHI_WORK.combCoef[1](r31) + lfs f24, AXFX_REVHI_WORK.combCoef[2](r31) + slwi r31, k, 2 + add r31, r31, rv + lfs f25, AXFX_REVHI_WORK.lpLastout[0](r31) + lwz r31, AXFX_REVHI_WORK.preDelayTime(rv) + lis r30, 0x4330 + stw r30, 0x58(r1) + subi r22, r31, 1 + slwi r22, r22, 2 + slwi r28, k, 2 + add r28, r28, rv + cmpwi cr7, r31, 0 + lwz r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + lwz r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + lwz r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + lwz r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + lwz r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + lwz r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + lfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + lfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + lfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + lwz r25, AXFX_REVHI_DELAYLINE.length + 0x00(r29) // C[0] + lwz r24, AXFX_REVHI_DELAYLINE.length + 0x14(r29) // C[1] + lwz r23, AXFX_REVHI_DELAYLINE.length + 0x28(r29) // C[2] + lwz r4, AXFX_REVHI_DELAYLINE.inputs + 0x00(r29) // C[0] + lwz r5, AXFX_REVHI_DELAYLINE.inputs + 0x14(r29) // C[1] + lwz r6, AXFX_REVHI_DELAYLINE.inputs + 0x28(r29) // C[2] + lwz r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + lwz r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + lwz r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + lwz r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + lwz r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + lwz r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + lfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + lfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + lfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + lwz r15, AXFX_REVHI_DELAYLINE.length + 0x00(r27) // AP[0] + lwz r14, AXFX_REVHI_DELAYLINE.length + 0x14(r27) // AP[1] + //? missing load for length of AP[3]? Maybe intentional? + lwz r30, 0(r3) + xoris r30, r30, 0x8000 + stw r30, 0x5c(r1) + lfd f12, 0x58(r1) + fsubs f12, f12, f5 + li r31, 159 + mtctr r31 +L_00000964: + fmr f13, f12 + beq cr7, L_00000994 + lwz r30, AXFX_REVHI_WORK.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000990 + mr r29, r30 +L_00000990: + stw r29, AXFX_REVHI_WORK.preDelayPtr(r30) +L_00000994: + fmadds f8, f22, f16, f13 + lwzu r29, 4(r3) + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_000009E0 + li r21, 0 +L_000009E0: + fmadds f8, f24, f18, f13 + bne+ cr1, L_000009EC + li r20, 0 +L_000009EC: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_000009FC + li r19, 0 +L_000009FC: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000A10 + li r18, 0 +L_00000A10: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000A28 + li r17, 0 +L_00000A28: + bne+ cr1, L_00000A30 + li r16, 0 +L_00000A30: + xoris r29, r29, 0x8000 + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000A60 + li r12, 0x0 +L_00000A60: + stw r29, 0x5c(r1) + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000A78 + li r11, 0 +L_00000A78: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + lfd f10, 0x58(r1) + fmadds f14, f15, f25, f14 + bne+ L_00000A9C + li r10, 0 +L_00000A9C: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000AB0 + li r9, 0 +L_00000AB0: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r31, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r31 + cmpw cr6, r7, r31 + fctiwz f14, f14 + bne+ cr5, L_00000AE4 + li r8, 0 +L_00000AE4: + bne+ cr6, L_00000AEC + li r7, 0 +L_00000AEC: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, sptr, r31 + bdnz L_00000964 + fmr f13, f12 + beq cr7, L_00000B2C + lwz r30, AXFX_REVHI_WORK.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000B28 + mr r29, r30 +L_00000B28: + stw r29, AXFX_REVHI_WORK.preDelayPtr(r30) +L_00000B2C: + fmadds f8, f22, f16, f13 + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_00000B74 + li r21, 0 +L_00000B74: + fmadds f8, f24, f18, f13 + bne+ cr1, L_00000B80 + li r20, 0 +L_00000B80: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_00000B90 + li r19, 0 +L_00000B90: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000BA4 + li r18, 0 +L_00000BA4: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000BBC + li r17, 0 +L_00000BBC: + bne+ cr1, L_00000BC4 + li r16, 0 +L_00000BC4: + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000BF0 + li r12, 0 +L_00000BF0: + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000C04 + li r11, 0 +L_00000C04: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + fmadds f14, f15, f25, f14 + bne+ L_00000C24 + li r10, 0 +L_00000C24: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + lwz k, 0x50(r1) + lwz rv, 0x54(r1) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000C40 + li r9, 0 +L_00000C40: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r29, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r29 + cmpw cr6, r7, r29 + fctiwz f14, f14 + bne+ cr5, L_00000C74 + li r8, 0 +L_00000C74: + bne+ cr6, L_00000C7C + li r7, 0 +L_00000C7C: + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 // sizeof AXFX_REVHI_DELAYLINE + stfiwx f14, r0, sptr + addi r29, rv, AXFX_REVHI_WORK.C + add r29, r29, r31 + stw r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + stw r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + stw r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + stw r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + stw r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + stw r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + stfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + stfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + stfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + stw r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + stw r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + stw r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + stw r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + stw r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + stw r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + stfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + stfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + stfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + slwi r31, k, 2 + add r31, r31, rv + stfs f25, AXFX_REVHI_WORK.lpLastout(r31) + lfd f14, 0x60(r1) + lfd f15, 0x68(r1) + lfd f16, 0x70(r1) + lfd f17, 0x78(r1) + lfd f18, 0x80(r1) + lfd f19, 0x88(r1) + lfd f20, 0x90(r1) + lfd f21, 0x98(r1) + lfd f22, 0xa0(r1) + lfd f23, 0xa8(r1) + lfd f24, 0xb0(r1) + lfd f25, 0xb8(r1) + lmw r14, 0x8(r1) + addi r1, r1, 0xc0 + blr +} + +static void ReverbHICallback(s32* left, s32* right, s32* surround, AXFX_REVHI_WORK* rv) { + u8 k; + + for (k = 0; k < 3; k++) { + switch(k) { + case 0: + if (0.0f != rv->crosstalk) { + DoCrossTalk(left, right, 0.5f * rv->crosstalk, 1.0f - (0.5f * rv->crosstalk)); + } + HandleReverb(left, rv, 0); + break; + case 1: + HandleReverb(right, rv, 1); + break; + case 2: + HandleReverb(surround, rv, 2); + break; + } + } +} + +static void ReverbHIFree(AXFX_REVHI_WORK* rv) { + u8 i; + + for (i = 0; i < 9; i++) { + if (rv->AP[i].inputs != 0) { + DLdelete(&rv->AP[i]); + rv->AP[i].inputs = NULL; + } + } + + for (i = 0; i < 9; i++) { + if (rv->C[i].inputs != 0) { + DLdelete(&rv->C[i]); + rv->C[i].inputs = NULL; + } + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + if (rv->preDelayLine[i] != 0) { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = NULL; + } + } + } +} + +int AXFXReverbHiInit(AXFX_REVERBHI* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 0; + ret = ReverbHICreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay, rev->crosstalk); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbHiShutdown(AXFX_REVERBHI* rev) { + BOOL old; + + old = OSDisableInterrupts(); + ReverbHIFree(&rev->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbHiSettings(AXFX_REVERBHI* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbHIModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay, rev->crosstalk); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbHiCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBHI* reverb) { + if (reverb->tempDisableFX == 0) { + ReverbHICallback(bufferUpdate->left, bufferUpdate->right, bufferUpdate->surround, &reverb->rv); + } +} diff --git a/src/dolphin/axfx/src/reverb_hi_4ch.c b/dolphin sdk not yet linked/src/axfx/reverb_hi_4ch.c similarity index 100% rename from src/dolphin/axfx/src/reverb_hi_4ch.c rename to dolphin sdk not yet linked/src/axfx/reverb_hi_4ch.c diff --git a/src/dolphin/axfx/src/reverb_std.c b/dolphin sdk not yet linked/src/axfx/reverb_std.c similarity index 100% rename from src/dolphin/axfx/src/reverb_std.c rename to dolphin sdk not yet linked/src/axfx/reverb_std.c diff --git a/dolphin sdk not yet linked/src/base/PPCArch.c b/dolphin sdk not yet linked/src/base/PPCArch.c new file mode 100644 index 0000000..a145008 --- /dev/null +++ b/dolphin sdk not yet linked/src/base/PPCArch.c @@ -0,0 +1,513 @@ +#include "types.h" +#include "Dolphin/PPCArch.h" + +union FpscrUnion { + f64 f; + struct { + u32 fpscr_pad; + u32 fpscr; + } u; +}; + +#define HID0_SPD 0x00000200 // Speculative cache access enable (0 enable) + +void PPCMthid0(u32 newHID0); + +/** + * @note Address: 0x800D4558 + * @note Size: 0x8 + */ +ASM u32 PPCMfmsr(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r3 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800D4560 + * @note Size: 0x8 + */ +ASM void PPCMtmsr(register u32 newMSR) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtmsr newMSR + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void PPCOrMsr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void PPCAndMsr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void PPCAndCMsr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D4568 + * @note Size: 0x8 + */ +ASM u32 PPCMfhid0(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfspr r3, HID0 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800D4570 + * @note Size: 0x8 + */ +ASM void PPCMthid0(register u32 newHID0) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr HID0, newHID0 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfhid1(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D4578 + * @note Size: 0x8 + */ +ASM u32 PPCMfl2cr(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfspr r3, L2CR + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800D4580 + * @note Size: 0x8 + */ +ASM void PPCMtl2cr(register u32 newL2cr) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr L2CR, newL2cr + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800D4588 + * @note Size: 0x8 + */ +WEAKFUNC ASM void PPCMtdec(register u32 newDec) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtdec newDec + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfdec(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D4590 + * @note Size: 0x8 + */ +ASM void PPCSync(void) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + sc + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void PPCEieio(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D4598 + * @note Size: 0x14 + */ +WEAKFUNC ASM void PPCHalt(void) // spins infinitely +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + + sync + +_spin: + nop + li r3, 0 + nop + b _spin + + // NEVER REACHED +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfmmcr0(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D45AC + * @note Size: 0x8 + */ +ASM void PPCMtmmcr0(register u32 newMmcr0) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr MMCR0, newMmcr0 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfmmcr1(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D45B4 + * @note Size: 0x8 + */ +ASM void PPCMtmmcr1(register u32 newMmcr1) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr MMCR1, newMmcr1 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfpmc1(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D45BC + * @note Size: 0x8 + */ +ASM void PPCMtpmc1(register u32 newPmc1) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr PMC1, newPmc1 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfpmc2(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D45C4 + * @note Size: 0x8 + */ +ASM void PPCMtpmc2(register u32 newPmc2) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr PMC2, newPmc2 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfpmc3(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D45CC + * @note Size: 0x8 + */ +ASM void PPCMtpmc3(register u32 newPmc3) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr PMC3, newPmc3 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfpmc4(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D45D4 + * @note Size: 0x8 + */ +ASM void PPCMtpmc4(register u32 newPmc4) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr PMC4, newPmc4 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfsia(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMtsia(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D45DC + * @note Size: 0x20 + */ +u32 PPCMffpscr(void) +{ + union FpscrUnion m; + +#ifdef __MWERKS__ // clang-format off + asm { + mffs fp31 + stfd fp31, m.f; + } +#endif // clang-format on + + return m.u.fpscr; +} + +/** + * @note Address: 0x800D45FC + * @note Size: 0x28 + */ +void PPCMtfpscr(register u32 newFPSCR) +{ + union FpscrUnion m; + +#ifdef __MWERKS__ // clang-format off + asm { + li r4, 0 + stw r4, m.u.fpscr_pad; + stw newFPSCR, m.u.fpscr + lfd fp31, m.f + mtfsf 0xff, fp31 + } +#endif // clang-format on +} + +/** + * @note Address: 0x800D4624 + * @note Size: 0x8 + */ +ASM u32 PPCMfhid2(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfspr r3, 920 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800D462C + * @note Size: 0x8 + */ +ASM void PPCMthid2(register u32 newhid2) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr 920, newhid2 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0xC + * UNUSED + */ +ASM u32 PPCMfwpar(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + sync + mfspr r3, 921 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800D4634 + * @note Size: 0x8 + */ +ASM void PPCMtwpar(register u32 newwpar) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr WPAR, newwpar + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfdmaU(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfdmaL(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMtdmaU(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMtdmaL(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void PPCMfpvr(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void PPCEnableSpeculation(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D463C + * @note Size: 0x28 + */ +void PPCDisableSpeculation(void) { PPCMthid0(PPCMfhid0() | HID0_SPD); } + +/** + * @note Address: N/A + * @note Size: 0x8 + * UNUSED + */ +ASM void PPCSetFpIEEEMode(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mtfsb0 29 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800D4664 + * @note Size: 0x8 + */ +ASM void PPCSetFpNonIEEEMode(void) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtfsb1 29 + blr +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/card/CARDBios.c b/dolphin sdk not yet linked/src/card/CARDBios.c new file mode 100644 index 0000000..638f6ab --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDBios.c @@ -0,0 +1,769 @@ +#include "Dolphin/card.h" +#include "Dolphin/exi.h" +#include "types.h" + +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); +BOOL OnReset(BOOL f); + +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 127 }; + +// bit manip stuff for __CARDReadSegment, __CARDWritePage, __CARDEraseSector +#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)) + +/** + * @note Address: 0x800D466C + * @note Size: 0x4 + */ +void __CARDDefaultApiCallback(s32 channel, s32 result) { } + +/** + * @note Address: 0x800D4670 + * @note Size: 0x34 + */ +void __CARDSyncCallback(s32 channel, s32 result) { OSWakeupThread(&__CARDBlock[channel].threadQueue); } + +/** + * @note Address: 0x800D46A4 + * @note Size: 0xD8 + */ +void __CARDExtHandler(s32 channel, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[channel]; + if (card->attached) { + card->attached = FALSE; + EXISetExiCallback(channel, nullptr); + OSCancelAlarm(&card->alarm); + callback = card->exiCallback; + + if (callback) { + card->exiCallback = nullptr; + callback(channel, 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 = nullptr; + callback(channel, CARD_RESULT_NOCARD); + } + } +} + +/** + * @note Address: 0x800D477C + * @note Size: 0x118 + */ +void __CARDExiHandler(s32 channel, OSContext* context) +{ + + CARDControl* card; + CARDCallback callback; + u8 status; + s32 result; + + card = &__CARDBlock[channel]; + + OSCancelAlarm(&card->alarm); + + if (!card->attached) { + return; + } + + if (!EXILock(channel, 0, 0)) { + result = CARD_RESULT_FATAL_ERROR; + goto fatal; + } + + if ((result = __CARDReadStatus(channel, &status)) < 0 || (result = __CARDClearStatus(channel)) < 0) { + goto error; + } + + if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == CARD_RESULT_IOERROR && --card->retry > 0) { + result = Retry(channel); + if (result >= 0) { + return; + } + goto fatal; + } + +error: + EXIUnlock(channel); + +fatal: + callback = card->exiCallback; + if (callback) { + card->exiCallback = nullptr; + callback(channel, result); + } +} + +/** + * @note Address: 0x800D4894 + * @note Size: 0xA8 + */ +void __CARDTxHandler(s32 channel, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + BOOL err; + + card = &__CARDBlock[channel]; + err = !EXIDeselect(channel); + EXIUnlock(channel); + callback = card->txCallback; + if (callback) { + card->txCallback = nullptr; + callback(channel, (!err && EXIProbe(channel)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD); + } +} + +/** + * @note Address: 0x800D493C + * @note Size: 0x84 + */ +void __CARDUnlockedHandler(s32 channel, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[channel]; + callback = card->unlockCallback; + if (callback) { + card->unlockCallback = nullptr; + callback(channel, EXIProbe(channel) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD); + } +} + +/** + * @note Address: 0x800D49C0 + * @note Size: 0xC0 + */ +s32 __CARDEnableInterrupt(s32 channel, BOOL enable) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(channel, 0, 4)) { + return CARD_RESULT_NOCARD; + } + + cmd = enable ? 0x81010000 : 0x81000000; + err = FALSE; + err |= !EXIImm(channel, &cmd, 2, 1, nullptr); + err |= !EXISync(channel); + err |= !EXIDeselect(channel); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +/** + * @note Address: 0x800D4A80 + * @note Size: 0xF0 + */ +s32 __CARDReadStatus(s32 channel, u8* status) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(channel, 0, 4)) { + return CARD_RESULT_NOCARD; + } + + cmd = 0x83000000; + err = FALSE; + err |= !EXIImm(channel, &cmd, 2, 1, nullptr); + err |= !EXISync(channel); + err |= !EXIImm(channel, status, 1, 0, nullptr); + err |= !EXISync(channel); + err |= !EXIDeselect(channel); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +/** + * @note Address: 0x800D4B70 + * @note Size: 0xAC + */ +s32 __CARDClearStatus(s32 channel) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(channel, 0, 4)) { + return CARD_RESULT_NOCARD; + } + + cmd = 0x89000000; + err = FALSE; + err |= !EXIImm(channel, &cmd, 1, 1, nullptr); + err |= !EXISync(channel); + err |= !EXIDeselect(channel); + + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +// /** +// * @note Address: N/A +// * @note Size: 0xAC +// */ +// void __CARDSleep(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0xAC +// */ +// void __CARDWakeup(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800D4C1C + * @note Size: 0xA4 + */ +void TimeoutHandler(OSAlarm* alarm, OSContext* context) +{ + s32 channel; + CARDControl* card; + CARDCallback callback; + for (channel = 0; channel < 2; channel++) { + card = &__CARDBlock[channel]; + if (alarm == &card->alarm) { + break; + } + } + + if (!card->attached) { + return; + } + + EXISetExiCallback(channel, NULL); + callback = card->exiCallback; + if (callback) { + card->exiCallback = nullptr; + callback(channel, CARD_RESULT_IOERROR); + } +} + +/** + * @note Address: N/A + * @note Size: 0xF8 + */ +void SetupTimeoutAlarm(CARDControl* card) +{ + OSCancelAlarm(&card->alarm); + switch (card->cmd[0]) { + case 0xF2: + OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler); + break; + case 0xF3: + break; + case 0xF4: + case 0xF1: + OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), TimeoutHandler); + break; + } +} + +/** + * @note Address: 0x800D4CC0 + * @note Size: 0x22C + */ +s32 Retry(s32 channel) +{ + CARDControl* card; + card = &__CARDBlock[channel]; + + if (!EXISelect(channel, 0, 4)) { + EXIUnlock(channel); + return CARD_RESULT_NOCARD; + } + + SetupTimeoutAlarm(card); + + if (!EXIImmEx(channel, card->cmd, card->cmdlen, 1)) { + EXIDeselect(channel); + EXIUnlock(channel); + return CARD_RESULT_NOCARD; + } + + if (card->cmd[0] == 0x52 && !EXIImmEx(channel, card->workArea->header.buffer, card->latency, 1)) { + EXIDeselect(channel); + EXIUnlock(channel); + return CARD_RESULT_NOCARD; + } + + if (card->mode == 0xffffffff) { + EXIDeselect(channel); + EXIUnlock(channel); + return CARD_RESULT_READY; + } + + if (!EXIDma(channel, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : 128), card->mode, __CARDTxHandler)) { + EXIDeselect(channel); + EXIUnlock(channel); + return CARD_RESULT_NOCARD; + } + + return CARD_RESULT_READY; +} + +/** + * @note Address: 0x800D4EEC + * @note Size: 0x110 + */ +void UnlockedCallback(s32 channel, s32 result) +{ + CARDCallback callback; + CARDControl* card; + + card = &__CARDBlock[channel]; + if (result >= 0) { + card->unlockCallback = UnlockedCallback; + if (!EXILock(channel, 0, __CARDUnlockedHandler)) { + result = CARD_RESULT_READY; + } else { + card->unlockCallback = nullptr; + result = Retry(channel); + } + } + + if (result < 0) { + switch (card->cmd[0]) { + case 0x52: + callback = card->txCallback; + if (callback) { + card->txCallback = nullptr; + callback(channel, result); + } + + break; + case 0xF2: + case 0xF4: + case 0xF1: + callback = card->exiCallback; + if (callback) { + card->exiCallback = nullptr; + callback(channel, result); + } + break; + } + } +} + +/** + * @note Address: 0x800D4FFC + * @note Size: 0x1B4 + */ +s32 __CARDStart(s32 channel, CARDCallback txCallback, CARDCallback exiCallback) +{ + BOOL enabled; + CARDControl* card; + s32 result; + + enabled = OSDisableInterrupts(); + + card = &__CARDBlock[channel]; + if (!card->attached) { + result = CARD_RESULT_NOCARD; + } else { + + if (txCallback) { + card->txCallback = txCallback; + } + if (exiCallback) { + card->exiCallback = exiCallback; + } + card->unlockCallback = UnlockedCallback; + if (!EXILock(channel, 0, __CARDUnlockedHandler)) { + result = CARD_RESULT_BUSY; + } else { + card->unlockCallback = nullptr; + + if (!EXISelect(channel, 0, 4)) { + EXIUnlock(channel); + result = CARD_RESULT_NOCARD; + } else { + SetupTimeoutAlarm(card); + result = CARD_RESULT_READY; + } + } + } + + OSRestoreInterrupts(enabled); + return result; +} + +/** + * @note Address: 0x800D51B0 + * @note Size: 0x134 + */ +s32 __CARDReadSegment(s32 channel, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[channel]; + 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(channel, callback, 0); + if (result == CARD_RESULT_BUSY) { + result = CARD_RESULT_READY; + } else if (result >= 0) { + if (!EXIImmEx(channel, card->cmd, card->cmdlen, 1) + || !EXIImmEx(channel, card->workArea->header.buffer, card->latency, + 1) + || // XXX use DMA if possible + !EXIDma(channel, card->buffer, 512, card->mode, __CARDTxHandler)) { + card->txCallback = 0; + EXIDeselect(channel); + EXIUnlock(channel); + result = CARD_RESULT_NOCARD; + } else { + result = CARD_RESULT_READY; + } + } + return result; +} + +/** + * @note Address: 0x800D52E4 + * @note Size: 0x11C + */ +s32 __CARDWritePage(s32 channel, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[channel]; + 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(channel, nullptr, callback); + if (result == CARD_RESULT_BUSY) { + result = CARD_RESULT_READY; + } else if (result >= 0) { + if (!EXIImmEx(channel, card->cmd, card->cmdlen, 1) || !EXIDma(channel, card->buffer, 128, card->mode, __CARDTxHandler)) { + card->exiCallback = nullptr; + EXIDeselect(channel); + EXIUnlock(channel); + result = CARD_RESULT_NOCARD; + } else { + result = CARD_RESULT_READY; + } + } + + return result; +} + +/** + * @note Address: 0x800D5400 + * @note Size: 0xE0 + */ +s32 __CARDEraseSector(s32 channel, u32 addr, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[channel]; + 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(channel, nullptr, callback); + + if (result == CARD_RESULT_BUSY) { + result = CARD_RESULT_READY; + } else if (result >= 0) { + if (!EXIImmEx(channel, card->cmd, card->cmdlen, 1)) { + card->exiCallback = nullptr; + result = CARD_RESULT_NOCARD; + } else { + result = CARD_RESULT_READY; + } + + EXIDeselect(channel); + EXIUnlock(channel); + } + return result; +} + +/** + * @note Address: 0x800D54E0 + * @note Size: 0xAC + */ +void CARDInit() +{ + s32 channel; + + if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) { + return; + } + + __CARDEncode = OSGetFontEncode(); + + OSRegisterVersion(__CARDVersion); + + DSPInit(); + OSInitAlarm(); + + for (channel = 0; channel < 2; channel++) { + CARDControl* card = &__CARDBlock[channel]; + + card->result = CARD_RESULT_NOCARD; + OSInitThreadQueue(&card->threadQueue); + OSCreateAlarm(&card->alarm); + } + + __CARDSetDiskID((DVDDiskID*)OSPhysicalToCached(0x0)); + + OSRegisterResetFunction(&ResetFunctionInfo); +} + +/** + * @note Address: 0x800D558C + * @note Size: 0x8 + */ +u16 __CARDGetFontEncode() { return __CARDEncode; } + +// /** +// * @note Address: N/A +// * @note Size: 0x28 +// */ +// void __CARDSetFontEncode(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800D5594 + * @note Size: 0x38 + */ +void __CARDSetDiskID(const DVDDiskID* diskID) +{ + __CARDBlock[0].diskID = diskID ? diskID : &__CARDDiskNone; + __CARDBlock[1].diskID = diskID ? diskID : &__CARDDiskNone; +} + +// /** +// * @note Address: N/A +// * @note Size: 0x18 +// */ +// void CARDGetDiskID(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x78 +// */ +// void CARDSetDiskID(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800D55CC + * @note Size: 0xB8 + */ +s32 __CARDGetControlBlock(s32 channel, CARDControl** card) +{ + BOOL enabled; + s32 result; + CARDControl* reqCard; + + reqCard = &__CARDBlock[channel]; + if (channel < 0 || channel >= 2 || reqCard->diskID == NULL) { + return CARD_RESULT_FATAL_ERROR; + } + + enabled = OSDisableInterrupts(); + if (!reqCard->attached) { + result = CARD_RESULT_NOCARD; + } else if (reqCard->result == CARD_RESULT_BUSY) { + result = CARD_RESULT_BUSY; + } else { + reqCard->result = CARD_RESULT_BUSY; + result = CARD_RESULT_READY; + reqCard->apiCallback = nullptr; + *card = reqCard; + } + OSRestoreInterrupts(enabled); + return result; +} + +/** + * @note Address: 0x800D5684 + * @note Size: 0x64 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +s32 CARDGetResultCode(s32 channel) +{ + CARDControl* card; + + if (channel < 0 || channel >= 2) { + return CARD_RESULT_FATAL_ERROR; + } + + card = &__CARDBlock[channel]; + return card->result; +} + +/** + * @note Address: 0x800D56E8 + * @note Size: 0x150 + */ +s32 CARDFreeBlocks(s32 channel, s32* byteNotUsed, s32* filesNotUsed) +{ + CARDControl* card; + s32 result; + CARDFatBlock* fat; + CARDDirectoryBlock* dir; + CARDDir* ent; + u16 fileNo; + + result = __CARDGetControlBlock(channel, &card); + if (result < 0) { + return result; + } + + fat = __CARDGetFatBlock(card); + dir = __CARDGetDirBlock(card); + if (fat == nullptr || dir == nullptr) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + if (byteNotUsed) { + *byteNotUsed = (s32)(card->sectorSize * fat->freeBlocks); + } + + if (filesNotUsed) { + *filesNotUsed = 0; + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + ent = &dir->entries[fileNo]; + if (ent->fileName[0] == 0xff) { + ++*filesNotUsed; + } + } + } + + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +// /** +// * @note Address: N/A +// * @note Size: 0x88 +// */ +// void CARDGetEncoding(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x84 +// */ +// void CARDGetMemSize(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x84 +// */ +// void CARDGetSectorSize(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800D5838 + * @note Size: 0x98 + */ +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; +} + +/** + * @note Address: 0x800D58D0 + * @note Size: 0x50 + */ +BOOL OnReset(BOOL f) +{ + if (!f) { + if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) { + return FALSE; + } + } + + return TRUE; +} diff --git a/dolphin sdk not yet linked/src/card/CARDBlock.c b/dolphin sdk not yet linked/src/card/CARDBlock.c new file mode 100644 index 0000000..cb3bc25 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDBlock.c @@ -0,0 +1,156 @@ +#include "Dolphin/card.h" + +void WriteCallback(s32 channel, s32 result); +void EraseCallback(s32 channel, s32 result); +s32 __CARDUpdateFatBlock(s32 channel, CARDFatBlock* fat, CARDCallback callback); + +/** + * @note Address: 0x800D6E00 + * @note Size: 0x8 + */ +CARDFatBlock* __CARDGetFatBlock(CARDControl* card) { return card->currentFat; } + +/** + * @note Address: 0x800D6E08 + * @note Size: 0xD4 + */ +void WriteCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + CARDFatBlock* fat; + CARDFatBlock* fatBack; + + card = &__CARDBlock[channel]; + + if (result >= 0) { + fat = &card->workArea->blockAllocMap; + fatBack = &card->workArea->blockAllocMapBackup; + + if (card->currentFat == fat) { + card->currentFat = fatBack; + memcpy(fatBack, fat, 0x2000); + } else { + card->currentFat = fat; + memcpy(fat, fatBack, 0x2000); + } + } + + if (card->apiCallback == nullptr) { + __CARDPutControlBlock(card, result); + } + + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = nullptr; + callback(channel, result); + } +} + +/** + * @note Address: 0x800D6EDC + * @note Size: 0xC8 + */ +void EraseCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + u32 temp[2]; /* this compiler sucks */ + CARDFatBlock* fat; + u32 addr; + + card = &__CARDBlock[channel]; + if (result < 0) { + goto error; + } + + fat = __CARDGetFatBlock(card); + addr = ((u32)fat - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize; + result = __CARDWrite(channel, addr, CARD_SYSTEM_BLOCK_SIZE, fat, WriteCallback); + if (result < 0) { + goto error; + } + + return; + +error: + if (card->apiCallback == nullptr) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = nullptr; + callback(channel, result); + } +} + +/** + * @note Address: 0x800D6FA4 + * @note Size: 0x118 + */ +s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback) +{ + CARDControl* card; + CARDFatBlock* fat; + u16 iBlock; + u16 startBlock; + u16 prevBlock; + u16 count; + + card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + fat = __CARDGetFatBlock(card); + if (fat->freeBlocks < cBlock) { + return CARD_RESULT_INSSPACE; + } + + fat->freeBlocks -= cBlock; + startBlock = 0xFFFF; + iBlock = fat->lastAllocBlock; + count = 0; + while (0 < cBlock) { + if (card->cBlock - 5 < ++count) { + return CARD_RESULT_BROKEN; + } + + iBlock++; + if (!CARDIsValidBlockNo(card, iBlock)) { + iBlock = 5; + } + + if (((u16*)fat)[iBlock] == 0x0000u) { + if (startBlock == 0xFFFF) { + startBlock = iBlock; + } else { + ((u16*)fat)[prevBlock] = iBlock; + } + prevBlock = iBlock; + ((u16*)fat)[iBlock] = 0xFFFF; + --cBlock; + } + } + fat->lastAllocBlock = iBlock; + card->startBlock = startBlock; + + return __CARDUpdateFatBlock(chan, fat, callback); +} + +/** + * @note Address: 0x800D70BC + * @note Size: 0xAC + */ +s32 __CARDUpdateFatBlock(s32 channel, CARDFatBlock* fat, CARDCallback callback) +{ + CARDControl* card; + + card = &__CARDBlock[channel]; + ++fat->checkCode; + __CARDCheckSum(&fat->checkCode, 0x1FFC, &fat->checkSum, &fat->checkSumInv); + DCStoreRange(fat, 0x2000); + card->eraseCallback = callback; + + return __CARDEraseSector(channel, (((u32)fat - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE) * card->sectorSize, EraseCallback); +} diff --git a/dolphin sdk not yet linked/src/card/CARDCheck.c b/dolphin sdk not yet linked/src/card/CARDCheck.c new file mode 100644 index 0000000..63b2be2 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDCheck.c @@ -0,0 +1,353 @@ +#include "Dolphin/card.h" + +/** + * @note Address: 0x800D73CC + * @note Size: 0x1B0 + */ +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; + } +} + +/** + * @note Address: 0x800D757C + * @note Size: 0x284 + */ +static s32 VerifyID(CARDControl* card) +{ + CARDID* id; + u16 checksum; + u16 checksumInv; + OSSramEx* sramEx; + OSTime rand; + int i; + + id = &card->workArea->header.id; + + 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; +} + +/** + * @note Address: 0x800D7800 + * @note Size: 0x240 + */ +static s32 VerifyDir(CARDControl* card, int* outCurrent) +{ + CARDDirectoryBlock* 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] = CARDGetDirectoryBlock(card, i); + check[i] = &dir[i]->check; + __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 = nullptr; + } + } + + if (errors == 0) { + 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; +} + +/** + * @note Address: 0x800D7A40 + * @note Size: 0x284 + */ +static s32 VerifyFAT(CARDControl* card, int* outCurrent) +{ + CARDFatBlock* fat[2]; + CARDFatBlock* 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] = CARDGetFatBlock(card, i); + + __CARDCheckSum(&fatp->checkCode, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv); + if (fatp->checkSum != checkSum || fatp->checkSumInv != checkSumInv) { + ++errors; + current = i; + card->currentFat = nullptr; + continue; + } + + cFree = 0; + for (nBlock = CARD_NUM_SYSTEM_BLOCK; nBlock < card->cBlock; nBlock++) { + if (((u16*)fatp)[nBlock] == CARD_FAT_AVAIL) { + cFree++; + } + } + if (cFree != fatp->freeBlocks) { + ++errors; + current = i; + card->currentFat = nullptr; + continue; + } + } + + if (0 == errors) { + if (card->currentFat == 0) { + if (((s16)fat[0]->checkCode - (s16)fat[1]->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; +} + +/** + * @note Address: 0x800D7CC4 + * @note Size: 0x8C + */ +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; + } +} + +/** + * @note Address: 0x800D7D50 + * @note Size: 0x590 + */ +s32 CARDCheckExAsync(s32 channel, s32* xferBytes, CARDCallback callback) +{ + CARDControl* card; + CARDDirectoryBlock* dir[2]; + CARDFatBlock* 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(channel, &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] = &card->workArea->dirBlock; + dir[1] = &card->workArea->dirBlockBackup; + fat[0] = &card->workArea->blockAllocMap; + fat[1] = &card->workArea->blockAllocMapBackup; + + 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 = (u16*)fat[currentFat ^ 1]; + memset(map, 0, CARD_SYSTEM_BLOCK_SIZE); + + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + CARDDir* ent; + + ent = &card->currentDir->entries[fileNo]; + if (ent->gameName[0] == 0xff) { + continue; + } + + for (iBlock = ent->startBlock, cBlock = 0; iBlock != 0xFFFF && cBlock < ent->length; + iBlock = ((u16*)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 = ((u16*)card->currentFat)[iBlock]; + if (map[iBlock] == 0) { + if (nextBlock != CARD_FAT_AVAIL) { + ((u16*)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->freeBlocks) { + card->currentFat->freeBlocks = cFree; + updateOrphan = TRUE; + } + if (updateOrphan) { + __CARDCheckSum(&card->currentFat->checkCode, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &card->currentFat->checkSum, + &card->currentFat->checkSumInv); + } + + memcpy(fat[currentFat ^ 1], fat[currentFat], CARD_SYSTEM_BLOCK_SIZE); + + if (updateDir) { + if (xferBytes) { + *xferBytes = CARD_SYSTEM_BLOCK_SIZE; + } + return __CARDUpdateDir(channel, callback); + } + + if (updateFat | updateOrphan) { + if (xferBytes) { + *xferBytes = CARD_SYSTEM_BLOCK_SIZE; + } + return __CARDUpdateFatBlock(channel, card->currentFat, callback); + } + + __CARDPutControlBlock(card, CARD_RESULT_READY); + if (callback) { + BOOL enabled = OSDisableInterrupts(); + callback(channel, CARD_RESULT_READY); + OSRestoreInterrupts(enabled); + } + return CARD_RESULT_READY; +} + +/** + * @note Address: 0x800D82E0 + * @note Size: 0x54 + */ +s32 CARDCheck(s32 channel) +{ + s32 result; + s32 xferBytes; + + result = CARDCheckExAsync(channel, &xferBytes, __CARDSyncCallback); + + if (result < 0 || &xferBytes == nullptr) { + return result; + } + + return __CARDSync(channel); +} diff --git a/dolphin sdk not yet linked/src/card/CARDCreate.c b/dolphin sdk not yet linked/src/card/CARDCreate.c new file mode 100644 index 0000000..1ea6b56 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDCreate.c @@ -0,0 +1,131 @@ +#include "Dolphin/card.h" + +/** + * @note Address: 0x800D9AB0 + * @note Size: 0x130 + */ +static void CreateCallbackFat(s32 channel, s32 result) +{ + CARDControl* card; + CARDDirectoryBlock* dir; + CARDDir* ent; + CARDCallback callback; + + card = &__CARDBlock[channel]; + callback = card->apiCallback; + card->apiCallback = nullptr; + if (result < 0) { + goto error; + } + + dir = __CARDGetDirBlock(card); + ent = &dir->entries[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 = CARD_STAT_BANNER_NONE; + ent->iconAddr = 0xFFFFFFFF; + ent->iconFormat = CARD_STAT_ICON_NONE; + ent->iconSpeed = CARD_STAT_SPEED_END; + 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(channel, callback); + if (result < 0) { + goto error; + } + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) { + callback(channel, result); + } +} + +/** + * @note Address: 0x800D9BE0 + * @note Size: 0x220 + */ +s32 CARDCreateAsync(s32 channel, char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback) +{ + CARDControl* card; + CARDDirectoryBlock* dir; + CARDDir* ent; + s32 result; + u16 fileNo; + u16 freeNo; + CARDFatBlock* fat; + + if (strlen(fileName) > (u32)CARD_FILENAME_MAX) { + return CARD_RESULT_NAMETOOLONG; + } + + result = __CARDGetControlBlock(channel, &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->entries[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->freeBlocks < size) { + return __CARDPutControlBlock(card, CARD_RESULT_INSSPACE); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + card->freeNo = freeNo; + ent = &dir->entries[freeNo]; + ent->length = (u16)(size / card->sectorSize); + strncpy(ent->fileName, fileName, CARD_FILENAME_MAX); + + card->fileInfo = fileInfo; + fileInfo->chan = channel; + fileInfo->fileNo = freeNo; + + result = __CARDAllocBlock(channel, size / card->sectorSize, CreateCallbackFat); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + return result; +} + +/** + * @note Address: 0x800D9E00 + * @note Size: 0x48 + */ +s32 CARDCreate(s32 channel, char* fileName, u32 size, CARDFileInfo* fileInfo) +{ + s32 result = CARDCreateAsync(channel, fileName, size, fileInfo, __CARDSyncCallback); + if (result < 0) { + return result; + } + return __CARDSync(channel); +} diff --git a/src/dolphin/card/src/CARDDelete.c b/dolphin sdk not yet linked/src/card/CARDDelete.c similarity index 100% rename from src/dolphin/card/src/CARDDelete.c rename to dolphin sdk not yet linked/src/card/CARDDelete.c diff --git a/dolphin sdk not yet linked/src/card/CARDDir.c b/dolphin sdk not yet linked/src/card/CARDDir.c new file mode 100644 index 0000000..508b66d --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDDir.c @@ -0,0 +1,106 @@ +#include "Dolphin/card.h" + +/** + * @note Address: 0x800D7168 + * @note Size: 0x8 + */ +CARDDirectoryBlock* __CARDGetDirBlock(CARDControl* card) { return card->currentDir; } + +/** + * @note Address: 0x800D7170 + * @note Size: 0xD0 + */ +static void WriteCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[channel]; + if (0 <= result) { + CARDDirectoryBlock* dir = &card->workArea->dirBlock; + CARDDirectoryBlock* dirBack = &card->workArea->dirBlockBackup; + + if (card->currentDir == dir) { + card->currentDir = dirBack; + memcpy(dirBack, dir, 0x2000); + } else { + card->currentDir = dir; + memcpy(dir, dirBack, 0x2000); + } + } + +error: + if (card->apiCallback == nullptr) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = nullptr; + callback(channel, result); + } +} + +/** + * @note Address: 0x800D7240 + * @note Size: 0xC8 + */ +static void EraseCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + CARDDirectoryBlock* dir; + u32 tmp[2]; + u32 addr; + + card = &__CARDBlock[channel]; + if (result < 0) { + goto error; + } + + dir = __CARDGetDirBlock(card); + addr = ((u32)dir - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize; + result = __CARDWrite(channel, addr, CARD_SYSTEM_BLOCK_SIZE, dir, WriteCallback); + if (result < 0) { + goto error; + } + + return; + +error: + if (card->apiCallback == 0) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = nullptr; + callback(channel, result); + } +} + +/** + * @note Address: 0x800D7308 + * @note Size: 0xC4 + */ +s32 __CARDUpdateDir(s32 channel, CARDCallback callback) +{ + CARDControl* card; + CARDDirCheck* check; + u32 tmp[2]; + u32 addr; + CARDDirectoryBlock* dir; + + card = &__CARDBlock[channel]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + dir = __CARDGetDirBlock(card); + check = &dir->check; + ++check->checkCode; + __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum, &check->checkSumInv); + DCStoreRange(dir, CARD_SYSTEM_BLOCK_SIZE); + + card->eraseCallback = callback; + addr = ((u32)dir - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize; + return __CARDEraseSector(channel, addr, EraseCallback); +} diff --git a/dolphin sdk not yet linked/src/card/CARDFormat.c b/dolphin sdk not yet linked/src/card/CARDFormat.c new file mode 100644 index 0000000..532d9a8 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDFormat.c @@ -0,0 +1,137 @@ +#include "Dolphin/card.h" +#include "Dolphin/hw_regs.h" + +/** + * @note Address: 0x800D8E2C + * @note Size: 0x144 + */ +static void FormatCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[channel]; + if (result < 0) { + goto error; + } + + ++card->formatStep; + if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) { + result = __CARDEraseSector(channel, (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(channel, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, + (u8*)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), FormatCallback); + if (result >= 0) { + return; + } + } else { + card->currentDir = &card->workArea->dirBlock; + memcpy(card->currentDir, &card->workArea->dirBlockBackup, CARD_SYSTEM_BLOCK_SIZE); + + card->currentFat = &card->workArea->blockAllocMap; + memcpy(card->currentFat, &card->workArea->blockAllocMapBackup, CARD_SYSTEM_BLOCK_SIZE); + } + +error: + callback = card->apiCallback; + card->apiCallback = nullptr; + __CARDPutControlBlock(card, result); + callback(channel, result); +} + +/** + * @note Address: 0x800D8F70 + * @note Size: 0x658 + */ +s32 __CARDFormatRegionAsync(s32 channel, u16 encode, CARDCallback callback) +{ + CARDControl* card; + CARDID* id; + CARDDirectoryBlock* dir; + CARDFatBlock* fat; + s16 i; + s32 result; + OSSram* sram; + OSSramEx* sramEx; + u16 viDTVStatus; + OSTime time; + OSTime rand; + + result = __CARDGetControlBlock(channel, &card); + if (result < 0) { + return result; + } + + id = &card->workArea->header.id; + 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[channel][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 = CARDGetDirectoryBlock(card, i); + memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE); + check = &dir->check; + check->checkCode = i; + __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum, &check->checkSumInv); + } + for (i = 0; i < 2; i++) { + fat = CARDGetFatBlock(card, i); + memset(fat, 0x00, CARD_SYSTEM_BLOCK_SIZE); + fat->checkCode = (u16)i; + fat->freeBlocks = (u16)(card->cBlock - CARD_NUM_SYSTEM_BLOCK); + fat->lastAllocBlock = CARD_NUM_SYSTEM_BLOCK - 1; + __CARDCheckSum(&fat->checkCode, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &fat->checkSum, &fat->checkSumInv); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + DCStoreRange(card->workArea, CARD_WORKAREA_SIZE); + + card->formatStep = 0; + result = __CARDEraseSector(channel, (u32)card->sectorSize * card->formatStep, FormatCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +/** + * @note Address: 0x800D95C8 + * @note Size: 0x54 + */ +s32 CARDFormat(s32 channel) +{ + s32 result = __CARDFormatRegionAsync(channel, __CARDGetFontEncode(), __CARDSyncCallback); + if (result < 0) { + return result; + } + return __CARDSync(channel); +} diff --git a/dolphin sdk not yet linked/src/card/CARDMount.c b/dolphin sdk not yet linked/src/card/CARDMount.c new file mode 100644 index 0000000..1501919 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDMount.c @@ -0,0 +1,407 @@ +#include "Dolphin/card.h" + +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 channel, s32 result); +static void DoUnmount(s32 channel, s32 result); + +/** + * @note Address: 0x800D8334 + * @note Size: 0xCC + */ +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; +} + +/** + * @note Address: 0x800D8400 + * @note Size: 0x38 + */ +BOOL CARDProbe(s32 channel) +{ + if (GameChoice & 0x80) { + return CARD_RESULT_READY; + } + + return EXIProbe(channel); +} + +/** + * @note Address: 0x800D8438 + * @note Size: 0x17C + */ +s32 CARDProbeEx(s32 channel, s32* memSize, s32* sectorSize) +{ + u32 id; + CARDControl* card; + BOOL enabled; + s32 result; + int probe; + + if (channel < 0 || 2 <= channel) { + return CARD_RESULT_FATAL_ERROR; + } + + if (GameChoice & 0x80) { + return CARD_RESULT_NOCARD; + } + + card = &__CARDBlock[channel]; + enabled = OSDisableInterrupts(); + + probe = EXIProbeEx(channel); + 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(channel) & 8)) { + result = CARD_RESULT_WRONGDEVICE; + } else if (!EXIGetID(channel, 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; +} + +/** + * @note Address: 0x800D85B4 + * @note Size: 0x410 + */ +static s32 DoMount(s32 channel) +{ + CARDControl* card; + u32 id; + u8 status; + s32 result; + OSSramEx* sram; + int i; + u8 checkSum; + int step; + + card = &__CARDBlock[channel]; + + if (card->mountStep == 0) { + if (EXIGetID(channel, 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(channel); + if (result < 0) { + goto error; + } + result = __CARDReadStatus(channel, &status); + if (result < 0) { + goto error; + } + + if (!EXIProbe(channel)) { + result = CARD_RESULT_NOCARD; + goto error; + } + + if (!(status & 0x40)) { + result = __CARDUnlock(channel, card->id); + if (result < 0) { + goto error; + } + + checkSum = 0; + sram = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + sram->flashID[channel][i] = card->id[i]; + checkSum += card->id[i]; + } + sram->flashIDCheckSum[channel] = (u8)~checkSum; + __OSUnlockSramEx(TRUE); + + return result; + } else { + card->mountStep = 1; + + checkSum = 0; + sram = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + checkSum += sram->flashID[channel][i]; + } + __OSUnlockSramEx(FALSE); + if (sram->flashIDCheckSum[channel] != (u8)~checkSum) { + result = CARD_RESULT_IOERROR; + goto error; + } + } + } + + if (card->mountStep == 1) { + if (card->cid == 0x80000004) { + u16 vendorID; + + sram = __OSLockSramEx(); + vendorID = *(u16*)sram->flashID[channel]; + __OSUnlockSramEx(FALSE); + + if (__CARDVendorID == 0xffff || vendorID != __CARDVendorID) { + result = CARD_RESULT_WRONGDEVICE; + goto error; + } + } + + card->mountStep = 2; + + result = __CARDEnableInterrupt(channel, TRUE); + if (result < 0) { + goto error; + } + + EXISetExiCallback(channel, __CARDExiHandler); + EXIUnlock(channel); + DCInvalidateRange(card->workArea, CARD_WORKAREA_SIZE); + } + + step = card->mountStep - 2; + result = __CARDRead(channel, (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(channel); + DoUnmount(channel, result); + return result; +} + +/** + * @note Address: 0x800D89C4 + * @note Size: 0x138 + */ +void __CARDMountCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[channel]; + + switch (result) { + case CARD_RESULT_READY: + if (++card->mountStep < CARD_MAX_MOUNT_STEP) { + result = DoMount(channel); + if (0 <= result) { + return; + } + } else { + result = __CARDVerify(card); + } + break; + case CARD_RESULT_UNLOCKED: + card->unlockCallback = __CARDMountCallback; + if (!EXILock(channel, 0, __CARDUnlockedHandler)) { + return; + } + card->unlockCallback = nullptr; + + result = DoMount(channel); + if (0 <= result) { + return; + } + break; + case CARD_RESULT_IOERROR: + case CARD_RESULT_NOCARD: + DoUnmount(channel, result); + break; + } + + callback = card->apiCallback; + card->apiCallback = nullptr; + __CARDPutControlBlock(card, result); + callback(channel, result); +} + +/** + * @note Address: 0x800D8AFC + * @note Size: 0x1A0 + */ +s32 CARDMountAsync(s32 channel, CARDMemoryCard* workArea, CARDCallback detachCallback, CARDCallback attachCallback) +{ + CARDControl* card; + BOOL enabled; + + if (channel < 0 || 2 <= channel) { + return CARD_RESULT_FATAL_ERROR; + } + if (GameChoice & 0x80) { + return CARD_RESULT_NOCARD; + } + card = &__CARDBlock[channel]; + + enabled = OSDisableInterrupts(); + if (card->result == CARD_RESULT_BUSY) { + OSRestoreInterrupts(enabled); + return CARD_RESULT_BUSY; + } + + if (!card->attached && (EXIGetState(channel) & 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 = nullptr; + + if (!card->attached && !EXIAttach(channel, __CARDExtHandler)) { + card->result = CARD_RESULT_NOCARD; + OSRestoreInterrupts(enabled); + return CARD_RESULT_NOCARD; + } + + card->mountStep = 0; + card->attached = TRUE; + EXISetExiCallback(channel, 0); + OSCancelAlarm(&card->alarm); + + card->currentDir = 0; + card->currentFat = 0; + + OSRestoreInterrupts(enabled); + + card->unlockCallback = __CARDMountCallback; + if (!EXILock(channel, 0, __CARDUnlockedHandler)) { + return CARD_RESULT_READY; + } + card->unlockCallback = nullptr; + + return DoMount(channel); +} + +/** + * @note Address: 0x800D8C9C + * @note Size: 0x48 + */ +s32 CARDMount(s32 channel, CARDMemoryCard* workArea, CARDCallback detachCallback) +{ + s32 result = CARDMountAsync(channel, workArea, detachCallback, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(channel); +} + +/** + * @note Address: 0x800D8CE4 + * @note Size: 0x9C + */ +static void DoUnmount(s32 channel, s32 result) +{ + CARDControl* card; + BOOL enabled; + + card = &__CARDBlock[channel]; + enabled = OSDisableInterrupts(); + if (card->attached) { + EXISetExiCallback(channel, 0); + EXIDetach(channel); + OSCancelAlarm(&card->alarm); + card->attached = FALSE; + card->result = result; + card->mountStep = 0; + } + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800D8D80 + * @note Size: 0xAC + */ +s32 CARDUnmount(s32 channel) +{ + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(channel, &card); + if (result < 0) { + return result; + } + DoUnmount(channel, CARD_RESULT_NOCARD); + return CARD_RESULT_READY; +} diff --git a/dolphin sdk not yet linked/src/card/CARDNet.c b/dolphin sdk not yet linked/src/card/CARDNet.c new file mode 100644 index 0000000..eb96e04 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDNet.c @@ -0,0 +1,34 @@ +#include "Dolphin/card.h" + +u16 __CARDVendorID = 0xFFFF; +u8 __CARDPermMask = 28; + +/** + * @note Address: 0x800DAB00 + * @note Size: 0xC4 + */ +s32 CARDGetSerialNo(s32 channel, u64* serialNo) +{ + CARDControl* card; + CARDID* id; + int i; + u64 code; + s32 result; + + if (!(0 <= channel && channel < 2)) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDGetControlBlock(channel, &card); + if (result < 0) { + return result; + } + + id = &card->workArea->header.id; + for (code = 0, i = 0; i < sizeof(id->serial) / sizeof(u64); ++i) { + code ^= *(u64*)&id->serial[sizeof(u64) * i]; + } + *serialNo = code; + + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} diff --git a/dolphin sdk not yet linked/src/card/CARDOpen.c b/dolphin sdk not yet linked/src/card/CARDOpen.c new file mode 100644 index 0000000..59285b7 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDOpen.c @@ -0,0 +1,172 @@ +#include "Dolphin/card.h" + +/** + * @note Address: 0x800D961C + * @note Size: 0x68 + */ +BOOL __CARDCompareFileName(CARDDir* entry, const char* fileName) +{ + char* entName; + char c1; + char c2; + int n; + + entName = (char*)entry->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; +} + +/** + * @note Address: 0x800D9684 + * @note Size: 0x94 + */ +s32 __CARDAccess(CARDControl* card, CARDDir* entry) +{ + const DVDDiskID* diskID = card->diskID; + if (entry->gameName[0] == 0xFF) { + return CARD_RESULT_NOFILE; + } + + if (diskID == &__CARDDiskNone + || (memcmp(entry->gameName, diskID->gameName, 4) == 0 && memcmp(entry->company, diskID->company, 2) == 0)) { + return CARD_RESULT_READY; + } + + return CARD_RESULT_NOPERM; +} + +/** + * @note Address: 0x800D9718 + * @note Size: 0x134 + */ +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; +} + +/** + * @note Address: 0x800D984C + * @note Size: 0xF4 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x150 + */ +static s32 __CARDGetFileNo(CARDControl* card, char* fileName, s32* outFileNo) +{ + CARDDirectoryBlock* dir; + CARDDir* entry; + s32 fileNo; + s32 result; + + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + entry = &dir->entries[fileNo]; + result = __CARDAccess(card, entry); + if (result < 0) { + continue; + } + if (__CARDCompareFileName(entry, fileName)) { + *outFileNo = fileNo; + return CARD_RESULT_READY; + } + } + + return CARD_RESULT_NOFILE; +} + +/** + * @note Address: 0x800D9940 + * @note Size: 0x11C + */ +s32 CARDOpen(s32 chan, char* fileName, CARDFileInfo* fileInfo) +{ + CARDControl* card; + CARDDirectoryBlock* 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->entries[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); +} + +/** + * @note Address: 0x800D9A5C + * @note Size: 0x54 + */ +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); +} diff --git a/dolphin sdk not yet linked/src/card/CARDRdwr.c b/dolphin sdk not yet linked/src/card/CARDRdwr.c new file mode 100644 index 0000000..892edf8 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDRdwr.c @@ -0,0 +1,119 @@ +#include "Dolphin/card.h" + +/** + * @note Address: 0x800D6B80 + * @note Size: 0xDC + */ +static void BlockReadCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[channel]; + 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(channel, BlockReadCallback); + if (result < 0) { + goto error; + } + return; + +error: + if (card->apiCallback == nullptr) { + __CARDPutControlBlock(card, result); + } + callback = card->xferCallback; + if (callback) { + card->xferCallback = nullptr; + callback(channel, result); + } +} + +/** + * @note Address: 0x800D6C5C + * @note Size: 0x64 + */ +int __CARDRead(s32 channel, u32 addr, s32 length, void* dst, CARDCallback callback) +{ + CARDControl* card; + card = &__CARDBlock[channel]; + 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(channel, BlockReadCallback); +} + +/** + * @note Address: 0x800D6CC0 + * @note Size: 0xDC + */ +static void BlockWriteCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[channel]; + 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(channel, BlockWriteCallback); + if (result < 0) { + goto error; + } + return; + +error: + if (card->apiCallback == nullptr) { + __CARDPutControlBlock(card, result); + } + callback = card->xferCallback; + if (callback) { + card->xferCallback = nullptr; + callback(channel, result); + } +} + +/** + * @note Address: 0x800D6D9C + * @note Size: 0x64 + */ +s32 __CARDWrite(s32 channel, u32 addr, s32 length, void* dst, CARDCallback callback) +{ + CARDControl* card; + card = &__CARDBlock[channel]; + 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(channel, BlockWriteCallback); +} diff --git a/dolphin sdk not yet linked/src/card/CARDRead.c b/dolphin sdk not yet linked/src/card/CARDRead.c new file mode 100644 index 0000000..3d1a324 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDRead.c @@ -0,0 +1,158 @@ +#include "Dolphin/card.h" + +/** + * @note Address: 0x800D9E48 + * @note Size: 0x1B8 + */ +s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** outCard) +{ + CARDControl* card; + CARDDirectoryBlock* dir; + CARDDir* ent; + s32 result; + CARDFatBlock* 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->entries[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 = ((u16*)fat)[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + + fileInfo->offset = offset; + + *outCard = card; + return CARD_RESULT_READY; +} + +/** + * @note Address: 0x800DA000 + * @note Size: 0x130 + */ +static void ReadCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + CARDFatBlock* fat; + CARDFileInfo* fileInfo; + s32 length; + + card = &__CARDBlock[channel]; + 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 = ((u16*)fat)[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + result = CARD_RESULT_BROKEN; + goto error; + } + + result = __CARDRead(channel, 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 = nullptr; + __CARDPutControlBlock(card, result); + callback(channel, result); +} + +/** + * @note Address: 0x800DA130 + * @note Size: 0x144 + */ +s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buffer, s32 length, s32 offset, CARDCallback callback) +{ + CARDControl* card; + s32 result; + CARDDirectoryBlock* 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->entries[fileInfo->fileNo]; + result = __CARDIsReadable(card, ent); + + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + DCInvalidateRange(buffer, (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, buffer, ReadCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +/** + * @note Address: 0x800DA274 + * @note Size: 0x48 + */ +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); +} diff --git a/dolphin sdk not yet linked/src/card/CARDStat.c b/dolphin sdk not yet linked/src/card/CARDStat.c new file mode 100644 index 0000000..9bcc397 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDStat.c @@ -0,0 +1,163 @@ +#include "Dolphin/card.h" + +/** + * @note Address: 0x800DA638 + * @note Size: 0x1F8 + */ +static void UpdateIconOffsets(CARDDir* entry, CARDStat* state) +{ + u32 offset; + BOOL iconTlut; + int i; + + offset = entry->iconAddr; + if (offset == 0xffffffff) { + state->bannerFormat = 0; + state->iconFormat = 0; + state->iconSpeed = 0; + offset = 0; + } + + iconTlut = FALSE; + switch (CARDGetBannerFormat(entry)) { + case CARD_STAT_BANNER_C8: + state->offsetBanner = offset; + offset += CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; + state->offsetBannerTlut = offset; + offset += 2 * 256; + break; + case CARD_STAT_BANNER_RGB5A3: + state->offsetBanner = offset; + offset += 2 * CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; + state->offsetBannerTlut = 0xffffffff; + break; + default: + state->offsetBanner = 0xffffffff; + state->offsetBannerTlut = 0xffffffff; + break; + } + for (i = 0; i < CARD_ICON_MAX; ++i) { + switch (CARDGetIconFormat(entry, i)) { + case CARD_STAT_ICON_C8: + state->offsetIcon[i] = offset; + offset += CARD_ICON_WIDTH * CARD_ICON_HEIGHT; + iconTlut = TRUE; + break; + case CARD_STAT_ICON_RGB5A3: + state->offsetIcon[i] = offset; + offset += 2 * CARD_ICON_WIDTH * CARD_ICON_HEIGHT; + break; + default: + state->offsetIcon[i] = 0xffffffff; + break; + } + } + if (iconTlut) { + state->offsetIconTlut = offset; + offset += 2 * 256; + } else { + state->offsetIconTlut = 0xffffffff; + } + state->offsetData = offset; +} + +/** + * @note Address: 0x800DA830 + * @note Size: 0x114 + */ +s32 CARDGetStatus(s32 channel, s32 fileNo, CARDStat* state) +{ + CARDControl* card; + CARDDirectoryBlock* dir; + CARDDir* ent; + s32 result; + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo) { + return CARD_RESULT_FATAL_ERROR; + } + result = __CARDGetControlBlock(channel, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir->entries[fileNo]; + result = __CARDIsReadable(card, ent); + + if (result >= 0) { + memcpy(state->gameName, ent->gameName, sizeof(state->gameName)); + memcpy(state->company, ent->company, sizeof(state->company)); + state->length = (u32)ent->length * card->sectorSize; + memcpy(state->fileName, ent->fileName, CARD_FILENAME_MAX); + state->time = ent->time; + + state->bannerFormat = ent->bannerFormat; + state->iconAddr = ent->iconAddr; + state->iconFormat = ent->iconFormat; + state->iconSpeed = ent->iconSpeed; + state->commentAddr = ent->commentAddr; + + UpdateIconOffsets(ent, state); + } + return __CARDPutControlBlock(card, result); +} + +/** + * @note Address: 0x800DA944 + * @note Size: 0x174 + */ +s32 CARDSetStatusAsync(s32 channel, s32 fileNo, CARDStat* state, CARDCallback callback) +{ + CARDControl* card; + CARDDirectoryBlock* dir; + CARDDir* ent; + s32 result; + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo || (state->iconAddr != 0xffffffff && CARD_READ_SIZE <= state->iconAddr) + || (state->commentAddr != 0xffffffff && CARD_SYSTEM_BLOCK_SIZE - CARD_COMMENT_SIZE < state->commentAddr % CARD_SYSTEM_BLOCK_SIZE)) { + return CARD_RESULT_FATAL_ERROR; + } + result = __CARDGetControlBlock(channel, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir->entries[fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + ent->bannerFormat = state->bannerFormat; + ent->iconAddr = state->iconAddr; + ent->iconFormat = state->iconFormat; + ent->iconSpeed = state->iconSpeed; + ent->commentAddr = state->commentAddr; + UpdateIconOffsets(ent, state); + + if (ent->iconAddr == 0xffffffff) { + CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST); + } + + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + result = __CARDUpdateDir(channel, callback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +/** + * @note Address: 0x800DAAB8 + * @note Size: 0x48 + */ +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/src/dolphin/card/src/CARDStatEx.c b/dolphin sdk not yet linked/src/card/CARDStatEx.c similarity index 100% rename from src/dolphin/card/src/CARDStatEx.c rename to dolphin sdk not yet linked/src/card/CARDStatEx.c diff --git a/dolphin sdk not yet linked/src/card/CARDUnlock.c b/dolphin sdk not yet linked/src/card/CARDUnlock.c new file mode 100644 index 0000000..0c85db0 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDUnlock.c @@ -0,0 +1,433 @@ +#include "Dolphin/card.h" +#include "Dolphin/dsp.h" + +static void InitCallback(void* task); +static void DoneCallback(void* task); + +static u8 CardData[] ATTRIBUTE_ALIGN(32) = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, + 0x00, 0x88, 0xFF, 0xFF, 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF, 0x00, 0x88, + 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00, + 0x02, 0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E, 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A, + 0x00, 0x10, 0x00, 0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF, 0x00, 0x88, 0x16, 0xFC, + 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94, + 0x00, 0x48, 0x27, 0xFF, 0x03, 0x80, 0x00, 0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F, + 0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, + 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7, + 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, + 0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05, + 0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00, 0x88, 0x02, 0xDF, 0x27, 0xFE, + 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD, 0x00, 0xF9, 0xFF, 0xC9, + 0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D, 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static u32 next = 1; + +// bit manip macros for use in ReadArrayUnlock +#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)) + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +int CARDRand() +{ + next = next * 1103515245 + 12345; + return (int)((u32)(next / 65536) % 32768); +} + +/** + * @note Address: N/A + * @note Size: 0x8 + * Fun fact: making the argument of this a u32 instead of uint + * makes the inlined versions of this not match (: + * LOVE this compiler. + */ +void CARDSrand(uint seed) { next = seed; } + +/** + * @note Address: N/A + * @note Size: 0x174 + */ +u32 exnor_1st(u32 data, u32 rshift) +{ + u32 wk; + u32 w; + u32 i; + + w = data; + for (i = 0; i < rshift; i++) { + wk = ~(w ^ (w >> 7) ^ (w >> 15) ^ (w >> 23)); + w = (w >> 1) | ((wk << 30) & 0x40000000); + } + return w; +} + +/** + * @note Address: N/A + * @note Size: 0x174 + */ +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); + } + return w; +} + +/** + * @note Address: 0x800D5920 + * @note Size: 0x16C + */ +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; +} + +/** + * @note Address: 0x800D5A8C + * @note Size: 0x144 + */ +s32 ReadArrayUnlock(s32 channel, u32 data, void* buffer, s32 rlen, s32 mode) +{ + CARDControl* card; + BOOL err; + u8 cmd[5]; + + card = &__CARDBlock[channel]; + if (!EXISelect(channel, 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(channel, cmd, 5, 1); + err |= !EXIImmEx(channel, card->workArea->header.buffer, card->latency, 1); + err |= !EXIImmEx(channel, buffer, rlen, 0); + err |= !EXIDeselect(channel); + + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +u32 GetInitVal() +{ + u32 tmp; + u32 tick; + + tick = OSGetTick(); + CARDSrand(tick); + tmp = 0x7FEC8000; + tmp |= CARDRand(); + tmp &= 0xFFFFF000; + return tmp; +} + +/** + * @note Address: 0x800D5BD0 + * @note Size: 0xC4 + */ +s32 DummyLen() +{ + u32 tick; + u32 wk; + s32 tmp; + u32 max; + + wk = 1; + max = 0; + tick = OSGetTick(); + CARDSrand(tick); + + tmp = CARDRand(); + tmp &= 0x0000001f; + tmp += 1; + while ((tmp < 4) && (max < 10)) { + tick = OSGetTick(); + tmp = (s32)(tick << wk); + wk++; + if (wk > 16) { + wk = 1; + } + CARDSrand((u32)tmp); + tmp = CARDRand(); + tmp &= 0x0000001f; + tmp += 1; + max++; + } + if (tmp < 4) { + tmp = 4; + } + + return tmp; +} + +/** + * @note Address: 0x800D5C94 + * @note Size: 0xB58 + */ +s32 __CARDUnlock(s32 channel, u8 flashID[12]) +{ + u32 init_val; + u32 data; + + s32 dummy; + s32 rlen; + u32 rshift; + + u8 fsts; + u32 wk, wk1; + u32 Ans1 = 0; + u32 Ans2 = 0; + u32* dp; + u8 rbuf[64]; + u32 para1A = 0; + u32 para1B = 0; + u32 para2A = 0; + u32 para2B = 0; + + CARDControl* card; + DSPTaskInfo* task; + CARDDecodeParameters* param; + u8* input; + u8* output; + + card = &__CARDBlock[channel]; + task = &card->task; + param = (CARDDecodeParameters*)card->workArea; + input = (u8*)((u8*)param + sizeof(CARDDecodeParameters)); + input = (u8*)OSRoundUp32B(input); + output = input + 32; + + fsts = 0; + init_val = GetInitVal(); + + dummy = DummyLen(); + rlen = dummy; + if (ReadArrayUnlock(channel, init_val, rbuf, rlen, 0) < 0) { + return CARD_RESULT_NOCARD; + } + + rshift = (u32)(dummy * 8 + 1); + wk = exnor_1st(init_val, rshift); + wk1 = ~(wk ^ (wk >> 7) ^ (wk >> 15) ^ (wk >> 23)); + card->scramble = (wk | ((wk1 << 31) & 0x80000000)); + card->scramble = bitrev(card->scramble); + dummy = DummyLen(); + rlen = 20 + dummy; + data = 0; + if (ReadArrayUnlock(channel, 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(CARDDecodeParameters)); + + 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 = nullptr; + task->done_cb = DoneCallback; + task->req_cb = nullptr; + DSPAddTask(task); + + dp = (u32*)flashID; + *dp++ = para1A; + *dp++ = para1B; + *dp = Ans1; + + return CARD_RESULT_READY; +} + +/** + * @note Address: 0x800D67EC + * @note Size: 0x70 + */ +void InitCallback(void* dspTask) +{ + s32 chan; + CARDControl* card; + DSPTaskInfo* task; + CARDDecodeParameters* param; + + task = dspTask; + for (chan = 0; chan < 2; ++chan) { + card = &__CARDBlock[chan]; + if ((DSPTaskInfo*)&card->task == task) { + break; + } + } + param = (CARDDecodeParameters*)card->workArea; + + DSPSendMailToDSP(0xff000000); + while (DSPCheckMailToDSP()) { } + + DSPSendMailToDSP((u32)param); + while (DSPCheckMailToDSP()) { } +} + +/** + * @note Address: 0x800D685C + * @note Size: 0x324 + */ +void DoneCallback(void* dspTask) +{ + 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; + CARDDecodeParameters* param; + + u8* input; + u8* output; + task = dspTask; + for (chan = 0; chan < 2; ++chan) { + card = &__CARDBlock[chan]; + if ((DSPTaskInfo*)&card->task == task) { + break; + } + } + + param = (CARDDecodeParameters*)card->workArea; + input = (u8*)((u8*)param + sizeof(CARDDecodeParameters)); + 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); +} diff --git a/dolphin sdk not yet linked/src/card/CARDWrite.c b/dolphin sdk not yet linked/src/card/CARDWrite.c new file mode 100644 index 0000000..da2570c --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDWrite.c @@ -0,0 +1,139 @@ +#include "Dolphin/card.h" + +static void EraseCallback(s32 chan, s32 result); + +/** + * @note Address: 0x800DA2BC + * @note Size: 0x170 + */ +static void WriteCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + CARDFatBlock* fat; + CARDDirectoryBlock* dir; + CARDDir* ent; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[channel]; + 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->entries[fileInfo->fileNo]; + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + callback = card->apiCallback; + card->apiCallback = nullptr; + result = __CARDUpdateDir(channel, callback); + + } else { + fat = __CARDGetFatBlock(card); + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = ((u16*)fat)[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + result = CARD_RESULT_BROKEN; + goto error; + } + result = __CARDEraseSector(channel, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + } + + if (result < 0) { + goto error; + } + return; + +error: + callback = card->apiCallback; + card->apiCallback = nullptr; + __CARDPutControlBlock(card, result); + callback(channel, result); +} + +/** + * @note Address: 0x800DA42C + * @note Size: 0xB0 + */ +static void EraseCallback(s32 channel, s32 result) +{ + CARDControl* card; + CARDCallback callback; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[channel]; + if (result < 0) { + goto error; + } + + fileInfo = card->fileInfo; + result = __CARDWrite(channel, card->sectorSize * (u32)fileInfo->iBlock, card->sectorSize, card->buffer, WriteCallback); + if (result < 0) { + goto error; + } + return; + +error: + callback = card->apiCallback; + card->apiCallback = nullptr; + __CARDPutControlBlock(card, result); + callback(channel, result); +} + +/** + * @note Address: 0x800DA4DC + * @note Size: 0x114 + */ +s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buffer, s32 length, s32 offset, CARDCallback callback) +{ + CARDControl* card; + s32 result; + CARDDirectoryBlock* 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->entries[fileInfo->fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + DCStoreRange(buffer, (u32)length); + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + card->buffer = buffer; + result = __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +/** + * @note Address: 0x800DA5F0 + * @note Size: 0x48 + */ +s32 CARDWrite(CARDFileInfo* fileInfo, void* buffer, s32 length, s32 offset) +{ + s32 result = CARDWriteAsync(fileInfo, buffer, length, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(fileInfo->chan); +} diff --git a/dolphin sdk not yet linked/src/db/db.c b/dolphin sdk not yet linked/src/db/db.c new file mode 100644 index 0000000..4b8bb05 --- /dev/null +++ b/dolphin sdk not yet linked/src/db/db.c @@ -0,0 +1,91 @@ +#include "types.h" +#include "Dolphin/db.h" +#include "Dolphin/os.h" + +/** + * @note Address: 0x800DABC4 + * @note Size: 0x28 + */ +void DBInit(void) +{ + __DBInterface = (void*)IsDebuggerPresent; + // WTF?? is this the only way to match? + *(u32*)ExceptionHookDestination = (u32)__DBExceptionDestination - OS_BASE_CACHED; + DBVerbose = 1; +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void DBIsDebuggerPresent(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800DABEC + * @note Size: 0x48 + */ +static void __DBExceptionDestinationAux(void) +{ + u8 dummy[8]; + OSContext* ctx = (void*)(OS_BASE_CACHED + *(u32*)0xC0); // WTF?? + OSReport("DBExceptionDestination\n"); + OSDumpContext(ctx); + PPCHalt(); +} + +/** + * @note Address: 0x800DAC34 + * @note Size: 0x10 + */ +#ifdef __MWERKS__ // clang-format off +ASM static void __DBExceptionDestination(void) +{ + nofralloc + mfmsr r3 + ori r3, r3, 0x30 + mtmsr r3 + b __DBExceptionDestinationAux +} +#else // clang-format on +static void __DBExceptionDestination(void) +{ + asm("mfmsr %r3\n" + "ori %r3, %r3, 0x30\n" + "mtmsr %r3\n" + "b __DBExceptionDestinationAux\n"); +} +#endif + +/** + * @note Address: 0x800DAC44 + * @note Size: 0x1C + */ +int __DBIsExceptionMarked(u8 a) { return __DBInterface->unk4 & (1 << a); } + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void __DBMarkException(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void __DBSetPresent(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800DAC60 + * @note Size: 0x50 + */ + +void DBPrintf(const char*, ...) { } diff --git a/dolphin sdk not yet linked/src/dsp/dsp.c b/dolphin sdk not yet linked/src/dsp/dsp.c new file mode 100644 index 0000000..49bc63c --- /dev/null +++ b/dolphin sdk not yet linked/src/dsp/dsp.c @@ -0,0 +1,79 @@ +#include "Dolphin/dsp.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" +#include "types.h" + +BOOL __DSP_init_flag; +char* __DSPVersion = "<< Dolphin SDK - DSP\trelease build: Apr 17 2003 12:34:16 (0x2301) >>"; + +/** + * @note Address: 0x800DACB0 + * @note Size: 0x10 + */ +u32 DSPCheckMailToDSP() { return __DSPRegs[DSP_MAILBOX_IN_HI] >> 0xF & 1; } + +/** + * @note Address: 0x800DACC0 + * @note Size: 0x10 + */ +u32 DSPCheckMailFromDSP() { return __DSPRegs[DSP_MAILBOX_OUT_HI] >> 0xF & 1; } + +/** + * @note Address: 0x800DACD0 + * @note Size: 0x18 + */ +u32 DSPReadMailFromDSP() { return (__DSPRegs[DSP_MAILBOX_OUT_HI] << 0x10) | __DSPRegs[DSP_MAILBOX_OUT_LO]; } + +/** + * @note Address: 0x800DACE8 + * @note Size: 0x14 + */ +void DSPSendMailToDSP(u32 mail) +{ + __DSPRegs[DSP_MAILBOX_IN_HI] = mail >> 0x10; + __DSPRegs[DSP_MAILBOX_IN_LO] = mail; +} + +/** + * @note Address: 0x800DACFC + * @note Size: 0x40 + */ +void DSPAssertInt() +{ + u32 tmp; + BOOL interrupts = OSDisableInterrupts(); + tmp = __DSPRegs[DSP_CONTROL_STATUS]; + __DSPRegs[DSP_CONTROL_STATUS] = (tmp & ~0xA8) | 2; + OSRestoreInterrupts(interrupts); +} + +/** + * @note Address: 0x800DAD3C + * @note Size: 0xC4 + */ +void DSPInit() +{ + u32 tmp; + BOOL old; + __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", "Apr 17 2003", "12:34:16"); + if (__DSP_init_flag == TRUE) { + return; + } + OSRegisterVersion(__DSPVersion); + old = OSDisableInterrupts(); + __OSSetInterruptHandler(7, __DSPHandler); + __OSUnmaskInterrupts(0x80000000 >> 7); + + tmp = __DSPRegs[DSP_CONTROL_STATUS]; + __DSPRegs[DSP_CONTROL_STATUS] = (tmp & ~0xA8) | 0x800; + + tmp = __DSPRegs[DSP_CONTROL_STATUS]; + __DSPRegs[DSP_CONTROL_STATUS] = (tmp & ~0xAC); + + __DSP_tmp_task = nullptr; + __DSP_curr_task = nullptr; + __DSP_last_task = nullptr; + __DSP_first_task = nullptr; + __DSP_init_flag = TRUE; + OSRestoreInterrupts(old); +} diff --git a/dolphin sdk not yet linked/src/dsp/dsp_debug.c b/dolphin sdk not yet linked/src/dsp/dsp_debug.c new file mode 100644 index 0000000..1cad16d --- /dev/null +++ b/dolphin sdk not yet linked/src/dsp/dsp_debug.c @@ -0,0 +1,17 @@ +#include "Dolphin/dsp.h" + +/** + * @note Address: 0x800DAE00 + * @note Size: 0x50 + */ + +void __DSP_debug_printf(const char* format, ...) { } + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __DSPGetCurrentTask(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/dsp/dsp_task.c b/dolphin sdk not yet linked/src/dsp/dsp_task.c new file mode 100644 index 0000000..5efd157 --- /dev/null +++ b/dolphin sdk not yet linked/src/dsp/dsp_task.c @@ -0,0 +1,212 @@ +#include "Dolphin/dsp.h" + +DSPTaskInfo* __DSP_curr_task; +DSPTaskInfo* __DSP_first_task; +DSPTaskInfo* __DSP_last_task; +DSPTaskInfo* __DSP_tmp_task; + +/** + * @note Address: 0x800DAE50 + * @note Size: 0x1A0 + */ +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 + +/** + * @note Address: 0x800DAFF0 + * @note Size: 0x18C + */ +void __DSP_boot_task(DSPTaskInfo* task) +{ + + vu32 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)); +} + +/** + * @note Address: 0x800DB17C + * @note Size: 0xA0 + */ +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; + } + } +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +// Unused, but close enough. +void __DSP_add_task(DSPTaskInfo* task) +{ + if (__DSP_last_task == NULL) { + __DSP_first_task = __DSP_last_task = __DSP_curr_task = task; + task->next = task->prev = NULL; + } else { + __DSP_last_task->next = task; + task->next = NULL; + task->prev = __DSP_last_task; + __DSP_last_task = task; + } + __DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", (u32)(task->next)); +} + +/** + * @note Address: 0x800DB21C + * @note Size: 0x94 + */ +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; + } +} diff --git a/dolphin sdk not yet linked/src/dvd/dvd.c b/dolphin sdk not yet linked/src/dvd/dvd.c new file mode 100644 index 0000000..01c75cf --- /dev/null +++ b/dolphin sdk not yet linked/src/dvd/dvd.c @@ -0,0 +1,1603 @@ +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" +#include "types.h" +#include "Dolphin/dvd.h" +#include "mem.h" + +const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Sep 16 2003 09:50:54 (0x2301) >>"; + +// forward declarations for local functions, as needed: +static void AlarmHandler(OSAlarm* alarm, OSContext* context); +static void cbForCancelSync(s32 result, DVDCommandBlock* block); +static void cbForStateBusy(u32 p1); +static void cbForStateCheckID1(u32 p1); +static void cbForStateCheckID2(u32 p1); +static void cbForStateCheckID2a(u32 p1); +static void cbForStateCheckID3(u32 p1); +static void cbForStateCoverClosed(u32 p1); +static void cbForStateMotorStopped(u32 p1); +static void cbForStateReadingFST(u32 p1); +static void cbForStateGettingError(u32 p1); +static void cbForStateGoToRetry(u32 p1); +static void cbForUnrecoveredError(u32 p1); +static void cbForUnrecoveredErrorRetry(u32 p1); +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block); +static void defaultOptionalCommandChecker(DVDCommandBlock* block, DVDLowCallback cb); +static void stateBusy(DVDCommandBlock*); +static void stateCheckID2(DVDCommandBlock*); +static void stateCheckID2a(DVDCommandBlock*); +static void stateCheckID3(DVDCommandBlock*); +static void stateCoverClosed(); +static void stateCoverClosed_CMD(DVDCommandBlock*); +static void stateGettingError(); +static void stateGoToRetry(); +static void stateMotorStopped(); +static void stateReady(); +static void stateTimeout(); + +// Private/weak functions from other files. +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context); +DVDCommandBlock* __DVDPopWaitingQueue(); + +typedef void (*stateFunc)(DVDCommandBlock* block); +stateFunc LastState; + +static DVDBB2 BB2 ATTRIBUTE_ALIGN(32); +static DVDDiskID CurrDiskID ATTRIBUTE_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 FirstTimeInBootrom = FALSE; + +static DVDCommandBlock DummyCommandBlock; +static OSAlarm ResetAlarm; + +static BOOL DVDInitialized = FALSE; +static DVDOptionalCommandChecker checkOptionalCommand = defaultOptionalCommandChecker; + +/** + * @note Address: 0x800DCD28 + * @note Size: 0x4 + */ +static void defaultOptionalCommandChecker(DVDCommandBlock* block, DVDLowCallback cb) { } + +/** + * @note Address: 0x800DCD2C + * @note Size: 0xCC + */ +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[DI_STATUS] = 42; + __DIRegs[DI_COVER_STATUS] = 0; + if (bootInfo->magic == OS_BOOTINFO_MAGIC_JTAG) { + OSReport("load fst\n"); + __fstLoad(); + } else if (bootInfo->magic != 0xD15EA5E) { + FirstTimeInBootrom = TRUE; + } +} + +/** + * @note Address: 0x800DCDF8 + * @note Size: 0x94 + */ +static void stateReadingFST() +{ + LastState = (stateFunc)stateReadingFST; + + if (bootInfo->FSTMaxLength < BB2.FSTLength) { + OSErrorLine(650, "DVDChangeDisk(): FST in the new disc is too big. "); + } + + DVDLowRead(bootInfo->FSTLocation, OSRoundUp32B(BB2.FSTLength), BB2.FSTPosition, cbForStateReadingFST); +} + +/** + * @note Address: 0x800DCE8C + * @note Size: 0x8C + */ +static void cbForStateReadingFST(u32 p1) +{ + DVDCommandBlock* cmdBlock; + if (p1 == 0x10) { + executing->state = -1; + stateTimeout(); + } else if ((p1 & 1) != 0) { + NumInternalRetry = 0; + __DVDFSInit(); + cmdBlock = executing; + executing = &DummyCommandBlock; + cmdBlock->state = 0; + if (cmdBlock->callback) { + (cmdBlock->callback)(0, cmdBlock); + } + stateReady(); + } else { + stateGettingError(); + } +} + +/** + * @note Address: 0x800DCF18 + * @note Size: 0xAC + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +static void stateError(u32 error) +{ + __DVDStoreErrorCode(error); + DVDLowStopMotor(cbForStateError); +} + +/** + * @note Address: 0x800DCFC4 + * @note Size: 0x34 + */ +static void stateTimeout() +{ + __DVDStoreErrorCode(0x1234568); + DVDReset(); + cbForStateError(0); +} + +/** + * @note Address: 0x800DCFF8 + * @note Size: 0x28 + */ +static void stateGettingError() { DVDLowRequestError(cbForStateGettingError); } + +/** + * @note Address: 0x800DD020 + * @note Size: 0xB4 + */ +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; + } + } +} + +/** + * @note Address: N/A + * @note Size: 0x9C + */ +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; +} + +/** + * @note Address: 0x800DD0D4 + * @note Size: 0x294 + */ +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[DI_MM_BUF]; + 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; + } +} + +/** + * @note Address: 0x800DD368 + * @note Size: 0x68 + */ +static void cbForUnrecoveredError(u32 p1) +{ + if (p1 == 16) { + executing->state = -1; + stateTimeout(); + return; + } + + if (p1 & 1) { + stateGoToRetry(); + return; + } + + DVDLowRequestError(cbForUnrecoveredErrorRetry); +} + +/** + * @note Address: 0x800DD3D0 + * @note Size: 0x98 + */ +void cbForUnrecoveredErrorRetry(u32 p1) +{ + if (p1 == 0x10) { + executing->state = -1; + __DVDStoreErrorCode(0x1234568); + DVDReset(); + cbForStateError(0); + return; + } + + executing->state = -1; + + if ((p1 & 2) != 0) { + __DVDStoreErrorCode(0x1234567); + DVDLowStopMotor(cbForStateError); + return; + } + + __DVDStoreErrorCode(__DIRegs[DI_MM_BUF]); + DVDLowStopMotor(cbForStateError); +} + +/** + * @note Address: 0x800DD468 + * @note Size: 0x28 + */ +void stateGoToRetry() { DVDLowStopMotor(cbForStateGoToRetry); } + +/** + * @note Address: 0x800DD490 + * @note Size: 0x158 + */ +void cbForStateGoToRetry(u32 p1) +{ + if (p1 == 16) { + executing->state = -1; + stateTimeout(); + return; + } + + if (p1 & 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(); + } +} + +/** + * @note Address: 0x800DD5E8 + * @note Size: 0xE0 + */ +static void stateCheckID() +{ + switch (CurrCommand) { + case 3: + if (DVDCompareDiskID(&CurrDiskID, executing->id) != FALSE) { + memcpy(IDShouldBe, &CurrDiskID, sizeof(DVDDiskID)); + executing->state = 1; + DCInvalidateRange(&BB2, sizeof(DVDBB2)); + LastState = stateCheckID2a; + stateCheckID2a(executing); + } else { + DVDLowStopMotor(cbForStateCheckID1); + } + break; + default: + if (memcmp(&CurrDiskID, IDShouldBe, sizeof(DVDDiskID)) != 0) { + DVDLowStopMotor(cbForStateCheckID1); + } else { + LastState = stateCheckID3; + stateCheckID3(executing); + } + break; + } +} + +/** + * @note Address: 0x800DD6C8 + * @note Size: 0x34 + */ +static void stateCheckID3(DVDCommandBlock* cmdBlock) { DVDLowAudioBufferConfig(IDShouldBe->streaming, 10, cbForStateCheckID3); } + +/** + * @note Address: 0x800DD6FC + * @note Size: 0x34 + */ +static void stateCheckID2a(DVDCommandBlock* cmdBlock) { DVDLowAudioBufferConfig(IDShouldBe->streaming, 10, cbForStateCheckID2a); } + +/** + * @note Address: 0x800DD730 + * @note Size: 0x74 + */ +void cbForStateCheckID2a(u32 p1) +{ + if (p1 == 0x10) { + executing->state = -1; + __DVDStoreErrorCode(0x1234568); + DVDReset(); + cbForStateError(0); + } else if ((p1 & 1) != 0) { + NumInternalRetry = 0; + stateCheckID2(executing); + } else { + DVDLowRequestError(cbForStateGettingError); + } +} + +/** + * @note Address: 0x800DD7A4 + * @note Size: 0x38 + */ +static void stateCheckID2(DVDCommandBlock* block) { DVDLowRead(&BB2, OSRoundUp32B(sizeof(DVDBB2)), 0x420, cbForStateCheckID2); } + +/** + * @note Address: 0x800DD7DC + * @note Size: 0x114 + */ +void cbForStateCheckID1(u32 p1) +{ + if (p1 == 16) { + executing->state = -1; + stateTimeout(); + return; + } + + if (p1 & 2) { + executing->state = -1; + stateError(0x1234567); + return; + } + + NumInternalRetry = 0; + + if (!CheckCancel(1)) { + executing->state = 6; + stateMotorStopped(); + } +} + +/** + * @note Address: 0x800DD8F0 + * @note Size: 0xE4 + */ +void cbForStateCheckID2(u32 p1) +{ + if (p1 == 16) { + executing->state = -1; + stateTimeout(); + return; + } + + if (p1 & 1) { + NumInternalRetry = 0; + stateReadingFST(); + + } else { + stateGettingError(); + } +} + +/** + * @note Address: 0x800DD9D4 + * @note Size: 0xFC + */ +static void cbForStateCheckID3(u32 p1) +{ + if (p1 == 16) { + executing->state = -1; + stateTimeout(); + return; + } + + if (p1 & 1) { + NumInternalRetry = 0; + + if (!CheckCancel(0)) { + executing->state = 1; + stateBusy(executing); + } + + } else { + stateGettingError(); + } +} + +/** + * @note Address: 0x800DDAD0 + * @note Size: 0x44 + */ +static void AlarmHandler(OSAlarm* alarm, OSContext* context) +{ + DVDReset(); + DCInvalidateRange(&CurrDiskID, sizeof(DVDDiskID)); + LastState = stateCoverClosed_CMD; + stateCoverClosed_CMD(executing); +} + +/** + * @note Address: 0x800DDB14 + * @note Size: 0xCC + */ +static void stateCoverClosed() +{ + DVDCommandBlock* cmdBlock; + switch (CurrCommand) { + case 4: + case 5: + case 13: + case 15: + __DVDClearWaitingQueue(); + cmdBlock = executing; + executing = &DummyCommandBlock; + if (cmdBlock->callback) { + (cmdBlock->callback)(-4, cmdBlock); + } + stateReady(); + break; + default: + DVDReset(); + OSCreateAlarm(&ResetAlarm); + OSSetAlarm(&ResetAlarm, OSMillisecondsToTicks(1150), AlarmHandler); + break; + } +} + +/** + * @note Address: 0x800DDBE0 + * @note Size: 0x30 + */ +void stateCoverClosed_CMD(DVDCommandBlock* cmdBlock) { DVDLowReadDiskID(&CurrDiskID, cbForStateCoverClosed); } + +/** + * @note Address: 0x800DDC10 + * @note Size: 0x70 + */ +void cbForStateCoverClosed(u32 p1) +{ + if (p1 == 16) { + executing->state = -1; + stateTimeout(); + return; + } + + if (p1 & 1) { + NumInternalRetry = 0; + stateCheckID(); + } else { + stateGettingError(); + } +} + +/** + * @note Address: 0x800DDC80 + * @note Size: 0x28 + */ +static void stateMotorStopped() { DVDLowWaitCoverClose(cbForStateMotorStopped); } + +/** + * @note Address: 0x800DDCA8 + * @note Size: 0xE4 + */ +void cbForStateMotorStopped(u32 p1) +{ + __DIRegs[DI_COVER_STATUS] = 0; + executing->state = 3; + stateCoverClosed(); +} + +/** + * @note Address: 0x800DDD8C + * @note Size: 0x230 + */ +void stateReady() +{ + DVDCommandBlock* finished; + + if (!__DVDCheckWaitingQueue()) { + executing = (DVDCommandBlock*)nullptr; + return; + } + + if (PauseFlag) { + PausingFlag = TRUE; + executing = (DVDCommandBlock*)nullptr; + 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); + } +} + +// idk why this file insists on doing this in the opposite order +#define DVDMIN(a, b) (((a) > (b)) ? (b) : (a)) + +/** + * @note Address: 0x800DDFBC + * @note Size: 0x320 + */ +void stateBusy(DVDCommandBlock* block) +{ + DVDCommandBlock* finished; + LastState = stateBusy; + switch (block->command) { + case 5: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + 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[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + block->currTransferSize = DVDMIN(block->length - block->transferredSize, 0x80000); + DVDLowRead((void*)((u8*)block->addr + block->transferredSize), block->currTransferSize, block->offset + block->transferredSize, + cbForStateBusy); + } + break; + + case 2: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + DVDLowSeek(block->offset, cbForStateBusy); + break; + + case 3: + DVDLowStopMotor(cbForStateBusy); + break; + + case 15: + DVDLowStopMotor(cbForStateBusy); + break; + + case 6: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + if (AutoFinishing) { + executing->currTransferSize = 0; + DVDLowRequestAudioStatus(0, cbForStateBusy); + } else { + executing->currTransferSize = 1; + DVDLowAudioStream(0, block->length, block->offset, cbForStateBusy); + } + break; + + case 7: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + DVDLowAudioStream(0x10000, 0, 0, cbForStateBusy); + break; + + case 8: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + AutoFinishing = TRUE; + DVDLowAudioStream(0, 0, 0, cbForStateBusy); + break; + + case 9: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + DVDLowRequestAudioStatus(0, cbForStateBusy); + break; + + case 10: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + DVDLowRequestAudioStatus(0x10000, cbForStateBusy); + break; + + case 11: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + DVDLowRequestAudioStatus(0x20000, cbForStateBusy); + break; + + case 12: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + DVDLowRequestAudioStatus(0x30000, cbForStateBusy); + break; + + case 13: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + DVDLowAudioBufferConfig(block->offset, block->length, cbForStateBusy); + break; + + case 14: + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + block->currTransferSize = sizeof(DVDDriveInfo); + DVDLowInquiry(block->addr, cbForStateBusy); + break; + + default: + checkOptionalCommand(block, cbForStateBusy); + break; + } +} + +// these will be from one of the stripped functions. +static u32 ImmCommand[] = { 0xffffffff, 0xffffffff, 0xffffffff }; +static char string_DVDChangeDiskAsyncMsg[] = "DVDChangeDiskAsync(): You can't specify NULL to company name. \n"; + +/** + * @note Address: N/A + * @note Size: 0x5C + */ +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; +} + +static u32 DmaCommand[] = { 0xFFFFFFFF }; + +/** + * @note Address: N/A + * @note Size: 0x40 + */ +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; +} + +/** + * @note Address: 0x800DE2DC + * @note Size: 0x638 + */ +void cbForStateBusy(u32 p1) +{ + DVDCommandBlock* finished; + + if (p1 == 16) { + executing->state = -1; + stateTimeout(); + return; + } + + if ((CurrCommand == 3) || (CurrCommand == 15)) { + if (p1 & 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 (p1 & 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 (p1 & 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[DI_MM_BUF] << 2); + } else { + result = (s32)__DIRegs[DI_MM_BUF]; + } + 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[DI_MM_BUF] & 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(); + } +} + +/** + * @note Address: N/A + * @note Size: 0xBC + */ +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*)nullptr) && (PauseFlag == FALSE)) { + stateReady(); + } + + OSRestoreInterrupts(level); + + return result; +} + +/** + * @note Address: 0x800DE914 + * @note Size: 0xDC + */ +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; +} + +/** + * @note Address: 0x800DE9F0 + * @note Size: 0xD0 + */ +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; +} + +/** + * @note Address: 0x800DEAC0 + * @note Size: 0xD4 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0xC4 + */ +static 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; +} + +/** + * @note Address: 0x800DEB94 + * @note Size: 0xBC + */ +BOOL DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + block->command = 7; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +/** + * @note Address: N/A + * @note Size: 0xA0 + */ +static BOOL 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; +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block) +{ + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +/** + * @note Address: N/A + * @note Size: 0xBC + */ +static BOOL DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 8; + block->callback = callback; + + idle = issueCommand(1, block); + + return idle; +} + +/** + * @note Address: 0x800DEC50 + * @note Size: 0xD0 + */ +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; +} + +/** + * @note Address: 0x800DED20 + * @note Size: 0x44 + */ +void DVDReset() +{ + DVDLowReset(); + __DIRegs[DI_STATUS] = 42; + __DIRegs[DI_COVER_STATUS] = __DIRegs[DI_COVER_STATUS]; + ResetRequired = FALSE; + ResumeFromHere = 0; +} + +/** + * @note Address: 0x800DED64 + * @note Size: 0x4C + */ +s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block) +{ + int interrupts = OSDisableInterrupts(); + int result; + if (block->state == 3) { + result = 1; + } else { + result = block->state; + } + OSRestoreInterrupts(interrupts); + return result; +} + +/** + * @note Address: 0x800DEDB0 + * @note Size: 0xAC + */ +s32 DVDGetDriveStatus() +{ + int interrupts = OSDisableInterrupts(); + int result; + if (FatalErrorFlag != FALSE) { + result = DVD_STATE_FATAL_ERROR; + } else { + if (PausingFlag != FALSE) { + result = DVD_STATE_PAUSING; + } else { + if (executing == nullptr) { + result = DVD_STATE_END; + } else if (executing == &DummyCommandBlock) { + result = DVD_STATE_END; + } else { + result = DVDGetCommandBlockStatus((struct DVDCommandBlock*)executing); + } + } + } + OSRestoreInterrupts(interrupts); + return result; +} + +/** + * @note Address: 0x800DEE5C + * @note Size: 0x10 + */ +int DVDSetAutoInvalidation(int newValue) +{ + int oldValue = autoInvalidation; + autoInvalidation = newValue; + return oldValue; +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +static void DVDPause() +{ + BOOL level; + level = OSDisableInterrupts(); + PauseFlag = TRUE; + if (executing == (DVDCommandBlock*)NULL) { + PausingFlag = TRUE; + } + OSRestoreInterrupts(level); +} + +/** + * @note Address: 0x800DEE6C + * @note Size: 0x50 + */ +void DVDResume() +{ + BOOL level; + level = OSDisableInterrupts(); + PauseFlag = FALSE; + if (PausingFlag) { + PausingFlag = FALSE; + stateReady(); + } + OSRestoreInterrupts(level); +} + +/** + * @note Address: 0x800DEEBC + * @note Size: 0x27C + */ +BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL enabled; + DVDLowCallback old; + u32 tmp; // dumb ass compiler + + 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; +} + +/** + * @note Address: 0x800DF138 + * @note Size: 0xAC + */ +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; +} + +/** + * @note Address: 0x800DF1E4 + * @note Size: 0x24 + */ +static void cbForCancelSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); } + +/** + * @note Address: N/A + * @note Size: 0xEC + */ +static 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; +} + +/** + * @note Address: 0x800DF208 + * @note Size: 0x8 + */ +DVDDiskID* DVDGetCurrentDiskID() { return (DVDDiskID*)OSPhysicalToCached(0); } + +/** + * @note Address: 0x800DF210 + * @note Size: 0xF8 + */ +BOOL DVDCheckDisk() +{ + BOOL enabled; + s32 result; + 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: + result = TRUE; + break; + + case -1: + case 11: + case 7: + case 3: + case 4: + case 5: + case 6: + result = FALSE; + break; + + case 0: + case 8: + coverReg = __DIRegs[1]; + if (((coverReg >> 2) & 1) || (coverReg & 1)) { + result = FALSE; + } else if (ResumeFromHere != 0) { + result = FALSE; + } else { + result = TRUE; + } + } + + OSRestoreInterrupts(enabled); + + return result; +} + +/** + * @note Address: 0x800DF308 + * @note Size: 0x11C + */ +void __DVDPrepareResetAsync(DVDCBCallback callback) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + + __DVDClearWaitingQueue(); + + if (Canceling) { + CancelCallback = callback; + } else { + if (executing) { + executing->callback = nullptr; + } + + DVDCancelAllAsync(callback); + } + + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800DF424 + * @note Size: 0x38 + */ +BOOL __DVDTestAlarm(OSAlarm* alarm) { return (alarm == &ResetAlarm) ? TRUE : __DVDLowTestAlarm(alarm); } diff --git a/dolphin sdk not yet linked/src/dvd/dvdFatal.c b/dolphin sdk not yet linked/src/dvd/dvdFatal.c new file mode 100644 index 0000000..f260f6a --- /dev/null +++ b/dolphin sdk not yet linked/src/dvd/dvdFatal.c @@ -0,0 +1,31 @@ +static void (*FatalFunc)(); + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +/* void ShowMessage(void) +{ + // UNUSED FUNCTION +} */ + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +/* void DVDSetAutoFatalMessaging(void) +{ + // UNUSED FUNCTION +} */ + +/** + * @note Address: 0x800DF8E4 + * @note Size: 0x30 + */ +void __DVDPrintFatalMessage(void) +{ + if (FatalFunc != 0) { + (*FatalFunc)(); + } + return; +} diff --git a/dolphin sdk not yet linked/src/dvd/dvderror.c b/dolphin sdk not yet linked/src/dvd/dvderror.c new file mode 100644 index 0000000..2469531 --- /dev/null +++ b/dolphin sdk not yet linked/src/dvd/dvderror.c @@ -0,0 +1,55 @@ +#include "Dolphin/dvd.h" +#include "Dolphin/os.h" + +u32 ErrorTable[18] = { 0x00000000, 0x00023A00, 0x00062800, 0x00030200, 0x00031100, 0x00052000, 0x00052001, 0x00052100, 0x00052400, + 0x00052401, 0x00052402, 0x000B5A01, 0x00056300, 0x00020401, 0x00020400, 0x00040800, 0x00100007, 0x00000000 }; +#pragma dont_inline on +/** + * @note Address: 0x800DF654 + * @note Size: 0x11C + */ +u8 ErrorCode2Num(u32 errorCode) +{ + int i; + + for (i = 0; i < 18; i++) { + if (errorCode == ErrorTable[i]) { + return i; + } + } + + if (errorCode >= 0x100000 && errorCode <= 0x100008) { + return 17; + } + + return 29; +} +#pragma dont_inline reset + +/** + * @note Address: 0x800DF770 + * @note Size: 0x7C + */ +void __DVDStoreErrorCode(u32 errCode) +{ + u8 storedCode; + OSSramEx* sramPtr; + u32 upperByte; + + if (errCode == 0x1234567) { + storedCode = -1; + } else if (errCode == 0x1234568) { + storedCode = -2; + } else { + upperByte = errCode >> 0x18; + storedCode = ErrorCode2Num(errCode & 0xffffff); + if (errCode >> 0x18 >= 6) { + upperByte = 6; + } + storedCode = storedCode + upperByte * 30; + } + + sramPtr = __OSLockSramEx(); + sramPtr->dvdErrorCode = storedCode; + __OSUnlockSramEx(TRUE); +} diff --git a/dolphin sdk not yet linked/src/dvd/dvdfs.c b/dolphin sdk not yet linked/src/dvd/dvdfs.c new file mode 100644 index 0000000..0607806 --- /dev/null +++ b/dolphin sdk not yet linked/src/dvd/dvdfs.c @@ -0,0 +1,585 @@ +#include "types.h" +#include "Dolphin/dvd.h" +#include "Dolphin/os.h" + +typedef struct FSTEntry FSTEntry; + +struct FSTEntry { + uint isDirAndStringOff; + uint parentOrPosition; + uint 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); + +#ifndef offsetof +#define offsetof(type, memb) ((u32) & ((type*)0)->memb) +#endif + +/** + * @note Address: 0x800DC12C + * @note Size: 0x38 + */ +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) + +/** + * @note Address: N/A + * @note Size: 0xA0 + */ +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; +} + +/** + * @note Address: 0x800DC164 + * @note Size: 0x2F4 + */ +s32 DVDConvertPathToEntrynum(char* pathPtr) +{ + const char* ptr; + char* stringPtr; + BOOL isDir; + u32 length; + u32 dirLookAt; + u32 i; + const char* origPathPtr = pathPtr; + const char* extentionStart; + BOOL illegal; + BOOL extention; + + dirLookAt = currentDirectory; + + while (1) { + + if (*pathPtr == '\0') { + return (s32)dirLookAt; + } else if (*pathPtr == '/') { + dirLookAt = 0; + pathPtr++; + continue; + } else if (*pathPtr == '.') { + if (*(pathPtr + 1) == '.') { + if (*(pathPtr + 2) == '/') { + dirLookAt = parentDir(dirLookAt); + pathPtr += 3; + continue; + } else if (*(pathPtr + 2) == '\0') { + return (s32)parentDir(dirLookAt); + } + } else if (*(pathPtr + 1) == '/') { + pathPtr += 2; + continue; + } else if (*(pathPtr + 1) == '\0') { + return (s32)dirLookAt; + } + } + + if (__DVDLongFileNameFlag == 0) { + extention = FALSE; + illegal = FALSE; + + for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) { + if (*ptr == '.') { + if ((ptr - pathPtr > 8) || (extention == TRUE)) { + illegal = TRUE; + break; + } + extention = TRUE; + extentionStart = ptr + 1; + + } else if (*ptr == ' ') + illegal = TRUE; + } + + if ((extention == TRUE) && (ptr - extentionStart > 3)) + illegal = TRUE; + + if (illegal) + OSErrorLine(387, + "DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): " + "specified directory or file (%s) doesn't match standard 8.3 format. This is a " + "temporary restriction and will be removed soon\n", + origPathPtr); + } 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; + } +} + +/** + * @note Address: 0x800DC458 + * @note Size: 0x74 + */ +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->cBlock.state = DVD_STATE_END; + + return TRUE; +} + +/** + * @note Address: 0x800DC4CC + * @note Size: 0xC8 + */ +BOOL DVDOpen(char* fileName, DVDFileInfo* fileInfo) +{ + s32 entry; + char currentDir[128]; + + entry = DVDConvertPathToEntrynum(fileName); + + if (0 > entry) { + DVDGetCurrentDir(currentDir, 128); + OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir); + return FALSE; + } + + if (entryIsDir(entry)) { + return FALSE; + } + + fileInfo->startAddr = filePosition(entry); + fileInfo->length = fileLength(entry); + fileInfo->callback = (DVDCallback)NULL; + fileInfo->cBlock.state = DVD_STATE_END; + + return TRUE; +} + +/** + * @note Address: 0x800DC594 + * @note Size: 0x24 + */ +BOOL DVDClose(DVDFileInfo* fileInfo) +{ + DVDCancel(&(fileInfo->cBlock)); + return TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +static u32 myStrncpy(char* dest, char* src, u32 maxlen) +{ + u32 i = maxlen; + + while ((i > 0) && (*src != 0)) { + *dest++ = *src++; + i--; + } + + return (maxlen - i); +} + +/** + * @note Address: 0x800DC5B8 + * @note Size: 0x160 + */ +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; +} + +/** + * @note Address: 0x800DC718 + * @note Size: 0x154 + */ +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; +} + +/** + * @note Address: 0x800DC86C + * @note Size: 0xC4 + */ +BOOL DVDGetCurrentDir(char* path, u32 maxlen) { return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); } + +/** + * @note Address: 0x800DC930 + * @note Size: 0x60 + */ +BOOL DVDChangeDir(char* dirName) +{ + s32 entry; + entry = DVDConvertPathToEntrynum(dirName); + if ((entry < 0) || (entryIsDir(entry) == FALSE)) { + return FALSE; + } + + currentDirectory = (u32)entry; + + return TRUE; +} + +/** + * @note Address: 0x800DC990 + * @note Size: 0xC0 + */ +BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, DVDCallback callback, s32 prio) +{ + + if (!((0 <= offset) && (offset <= fileInfo->length))) { + OSErrorLine(750, "DVDReadAsync(): specified area is out of the file "); + } + + if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) { + OSErrorLine(756, "DVDReadAsync(): specified area is out of the file "); + } + + fileInfo->callback = callback; + DVDReadAbsAsyncPrio(&(fileInfo->cBlock), addr, length, (s32)(fileInfo->startAddr + offset), cbForReadAsync, prio); + + return TRUE; +} + +/** + * @note Address: 0x800DCA50 + * @note Size: 0x30 + */ +static void cbForReadAsync(s32 result, DVDCommandBlock* block) +{ + DVDFileInfo* fileInfo; + + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cBlock)); + if (fileInfo->callback) { + (fileInfo->callback)(result, fileInfo); + } +} + +/** + * @note Address: 0x800DCA80 + * @note Size: 0x118 + */ +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))) { + OSErrorLine(820, "DVDRead(): specified area is out of the file "); + } + + if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) { + OSErrorLine(826, "DVDRead(): specified area is out of the file "); + } + + block = &(fileInfo->cBlock); + + result = DVDReadAbsAsyncPrio(block, addr, length, (s32)(fileInfo->startAddr + offset), cbForReadSync, prio); + + if (result == FALSE) { + return -1; + } + + enabled = OSDisableInterrupts(); + + while (TRUE) { + 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; +} + +/** + * @note Address: 0x800DCB98 + * @note Size: 0x24 + */ +static void cbForReadSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); } + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +BOOL DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +static void cbForSeekAsync(s32 result, DVDCommandBlock* block) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xAC + */ +s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +static void cbForSeekSync(s32 result, DVDCommandBlock* block) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +s32 DVDGetFileInfoStatus(DVDFileInfo* fileInfo) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x68 + */ +BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800DCBBC + * @note Size: 0xC0 + */ +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; +} + +/** + * @note Address: 0x800DCC7C + * @note Size: 0xA4 + */ +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; +} + +/** + * @note Address: 0x800DCD20 + * @note Size: 0x8 + */ +BOOL DVDCloseDir(DVDDir* dir) { return TRUE; } + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void DVDRewindDir(DVDDir* dir) { dir->location = dir->entryNum + 1; } + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void* DVDGetFSTLocation() { return BootInfo->FSTLocation; } + +/** + * @note Address: N/A + * @note Size: 0xEC + */ +BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x144 + */ +void DVDPrepareStream() +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x6C + */ +s32 DVDGetTransferredSize(DVDFileInfo* fileinfo) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/dvd/dvdidutils.c b/dolphin sdk not yet linked/src/dvd/dvdidutils.c new file mode 100644 index 0000000..0a97487 --- /dev/null +++ b/dolphin sdk not yet linked/src/dvd/dvdidutils.c @@ -0,0 +1,56 @@ +#include "types.h" +#include "string.h" +#include "Dolphin/dvd.h" + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +void strnlen(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800DF7EC + * @note Size: 0xF8 + */ +BOOL DVDCompareDiskID(DVDDiskID* discID1, DVDDiskID* discID2) +{ + u8 temp_r0; + u8 temp_r3; + + if ((discID1->gameName[0] != 0) && (discID2->gameName[0] != 0) && (strncmp(discID1->gameName, discID2->gameName, 4) != 0)) { + return FALSE; + } + if ((discID1->company[0] == 0) || (discID2->company[0] == 0) || (strncmp(discID1->company, discID2->company, 2) != 0)) { + return FALSE; + } + + temp_r3 = discID1->diskNumber; + temp_r0 = temp_r3; + if (temp_r3 != 0xFF) { + temp_r0 = discID2->diskNumber; + if ((temp_r0 != 0xFF) && (temp_r3 != temp_r0)) { + return FALSE; + } + } + temp_r3 = discID1->gameVersion; + temp_r0 = temp_r3; + if (temp_r3 != 0xFF) { + temp_r0 = discID2->gameVersion; + if ((temp_r0 != 0xFF) && (temp_r3 != temp_r0)) { + return FALSE; + } + } + return TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +void DVDGenerateDiskID(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/dvd/dvdlow.c b/dolphin sdk not yet linked/src/dvd/dvdlow.c new file mode 100644 index 0000000..09c4ee3 --- /dev/null +++ b/dolphin sdk not yet linked/src/dvd/dvdlow.c @@ -0,0 +1,618 @@ +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +void __DVDLowSetWAType(unknown, unknown); + +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 vu32 ResetOccurred = FALSE; +static volatile BOOL WaitingCoverClose = FALSE; +static BOOL Breaking = FALSE; +static vu32 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; + +/** + * @note Address: 0x800DB2B0 + * @note Size: 0x40 + */ +WEAKFUNC void __DVDInitWA() +{ + NextCommandNumber = 0; + CommandList[0].cmd = -1; + __DVDLowSetWAType(0, 0); + OSInitAlarm(); +} + +static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback); + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +static BOOL ProcessNextCommand() +{ + s32 n = NextCommandNumber; + + 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; +} + +/** + * @note Address: 0x800DB2F0 + * @note Size: 0x2E0 + */ +WEAKFUNC 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); +} + +/** + * @note Address: 0x800DB5D0 + * @note Size: 0x84 + */ +static void AlarmHandler(OSAlarm* alarm, OSContext* context) { BOOL error = ProcessNextCommand(); } + +/** + * @note Address: 0x800DB654 + * @note Size: 0x70 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +static void SetTimeoutAlarm(OSTime timeout) +{ + OSCreateAlarm(&AlarmForTimeout); + OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); +} + +/** + * @note Address: 0x800DB6C4 + * @note Size: 0x110 + */ +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)); + } +} + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +void AudioBufferOn(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xA0 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) +{ + CommandList[0].cmd = -1; + NextCommandNumber = 0; + Read(addr, length, offset, callback); +} + +/** + * @note Address: 0x800DB7D4 + * @note Size: 0x80 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +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); +} + +/** + * @note Address: 0x800DB854 + * @note Size: 0x298 + */ +WEAKFUNC 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; +} + +/** + * @note Address: 0x800DBAEC + * @note Size: 0x94 + */ +WEAKFUNC BOOL DVDLowSeek(u32 offset, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xab000000; + __DIRegs[3] = offset / 4; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +/** + * @note Address: 0x800DBB80 + * @note Size: 0x2C + */ +WEAKFUNC BOOL DVDLowWaitCoverClose(DVDLowCallback callback) +{ + Callback = callback; + WaitingCoverClose = TRUE; + StopAtNextInt = FALSE; + __DIRegs[1] = 2; + return TRUE; +} + +/** + * @note Address: 0x800DBBAC + * @note Size: 0xA4 + */ +WEAKFUNC 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; +} + +/** + * @note Address: 0x800DBC50 + * @note Size: 0x8C + */ +WEAKFUNC BOOL DVDLowStopMotor(DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xe3000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +/** + * @note Address: 0x800DBCDC + * @note Size: 0x8C + */ +WEAKFUNC BOOL DVDLowRequestError(DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xe0000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +/** + * @note Address: 0x800DBD68 + * @note Size: 0x9C + */ +WEAKFUNC 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; +} + +/** + * @note Address: 0x800DBE04 + * @note Size: 0x98 + */ +WEAKFUNC 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; +} + +/** + * @note Address: 0x800DBE9C + * @note Size: 0x8C + */ +WEAKFUNC BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = subcmd | 0xe2000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +/** + * @note Address: 0x800DBF28 + * @note Size: 0x9C + */ +WEAKFUNC 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; +} + +/** + * @note Address: 0x800DBFC4 + * @note Size: 0xBC + */ +WEAKFUNC 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(); +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void DVDLowSetResetCoverCallback(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void DoBreak(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x74 + */ +void AlarmHandlerForBreak(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +void SetBreakAlarm(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800DC080 + * @note Size: 0x14 + */ +WEAKFUNC BOOL DVDLowBreak() +{ + StopAtNextInt = TRUE; + Breaking = TRUE; + return TRUE; +} + +/** + * @note Address: 0x800DC094 + * @note Size: 0x1C + */ +WEAKFUNC DVDLowCallback DVDLowClearCallback() +{ + DVDLowCallback old; + __DIRegs[1] = 0; + old = Callback; + Callback = NULL; + WaitingCoverClose = FALSE; + return old; +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void DVDLowGetCoverStatus(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800DC0B0 + * @note Size: 0x44 + */ + +WEAKFUNC void __DVDLowSetWAType(u32 type, u32 location) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + WorkAroundType = type; + WorkAroundSeekLocation = location; + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800DC0F4 + * @note Size: 0x38 + */ +BOOL __DVDLowTestAlarm(OSAlarm* alarm) +{ + if (alarm == &AlarmForBreak) { + return TRUE; + } else if (alarm == &AlarmForTimeout) { + return TRUE; + } else { + return FALSE; + } +} diff --git a/dolphin sdk not yet linked/src/dvd/dvdqueue.c b/dolphin sdk not yet linked/src/dvd/dvdqueue.c new file mode 100644 index 0000000..34ddf23 --- /dev/null +++ b/dolphin sdk not yet linked/src/dvd/dvdqueue.c @@ -0,0 +1,110 @@ +#include "types.h" +#include "Dolphin/dvd.h" + +struct DVDQueue WaitingQueue[4]; + +/** + * @note Address: 0x800DF45C + * @note Size: 0x38 + */ +void __DVDClearWaitingQueue() +{ + int i; + + for (i = 0; i < 4; i++) { + struct DVDQueue* ptr = &WaitingQueue[i]; + + ptr->mHead = ptr; + ptr->mTail = ptr; + } +} + +/** + * @note Address: 0x800DF494 + * @note Size: 0x68 + */ +BOOL __DVDPushWaitingQueue(int idx, struct DVDQueue* newTail) +{ + BOOL intrEnabled = OSDisableInterrupts(); + + struct DVDQueue* waitingQueue = &WaitingQueue[idx]; + + waitingQueue->mTail->mHead = newTail; + newTail->mTail = waitingQueue->mTail; + newTail->mHead = waitingQueue; + waitingQueue->mTail = newTail; + + OSRestoreInterrupts(intrEnabled); + return TRUE; +} + +/** + * @note Address: 0x800DF4FC + * @note Size: 0xA0 + */ +struct DVDQueue* __DVDPopWaitingQueue() +{ + BOOL intrEnabled = OSDisableInterrupts(); + int i; + + for (i = 0; i < 4; i++) { + if (WaitingQueue[i].mHead != &WaitingQueue[i]) { + struct DVDQueue* tempQueue; + struct DVDQueue* outQueue; + + OSRestoreInterrupts(intrEnabled); + + intrEnabled = OSDisableInterrupts(); + tempQueue = &WaitingQueue[i]; + outQueue = tempQueue->mHead; + tempQueue->mHead = outQueue->mHead; + outQueue->mHead->mTail = tempQueue; + OSRestoreInterrupts(intrEnabled); + + outQueue->mHead = nullptr; + outQueue->mTail = nullptr; + return outQueue; + } + } + OSRestoreInterrupts(intrEnabled); + return NULL; +} + +/** + * @note Address: 0x800DF59C + * @note Size: 0x58 + */ +BOOL __DVDCheckWaitingQueue() +{ + BOOL intrEnabled = OSDisableInterrupts(); + int i; + + for (i = 0; i < 4; i++) { + if (WaitingQueue[i].mHead != &WaitingQueue[i]) { + OSRestoreInterrupts(intrEnabled); + return TRUE; + } + } + OSRestoreInterrupts(intrEnabled); + return FALSE; +} + +/** + * @note Address: 0x800DF5F4 + * @note Size: 0x60 + */ +BOOL __DVDDequeueWaitingQueue(struct DVDQueue* queue) +{ + BOOL intrEnabled = OSDisableInterrupts(); + struct DVDQueue* tail = queue->mTail; + struct DVDQueue* head = queue->mHead; + + if (tail == nullptr || head == nullptr) { + OSRestoreInterrupts(intrEnabled); + return FALSE; + } + tail->mHead = head; + head->mTail = tail; + OSRestoreInterrupts(intrEnabled); + return TRUE; +} diff --git a/dolphin sdk not yet linked/src/dvd/fstload.c b/dolphin sdk not yet linked/src/dvd/fstload.c new file mode 100644 index 0000000..64177ab --- /dev/null +++ b/dolphin sdk not yet linked/src/dvd/fstload.c @@ -0,0 +1,94 @@ +#include "types.h" +#include "Dolphin/os.h" +#include "Dolphin/dvd.h" + +struct bb2struct { + u32 _00; + u32 offset; + s32 length; + u32 maxLength; + void* addr; +}; + +static u32 status; +static struct bb2struct* bb2; // pointer? +static u8* idTmp; // also pointer +static u8 bb2Buf[0x3F]; +static u8 block[0x30]; + +struct blah { + s8 Gamecode[4]; + s8 Company[2]; + u8 DiskID; + u8 Version; + u8 Streaming; + u8 filler[0x38 - 0x9]; + void* FSTLocationInRam; + u32 FSTMaxLength; +}; // diskinfo : 0x80000000; + +/** + * @note Address: 0x800DF914 + * @note Size: 0xD8 + */ + +static void cb(s32 type, DVDCommandBlock* cmdBlock) +{ + if (type > 0) { + switch (status) { + case 0: + status = 1; + DVDReadAbsAsyncForBS(cmdBlock, bb2, 0x20, 0x420, cb); + break; + case 1: + status = 2; + DVDReadAbsAsyncForBS(cmdBlock, bb2->addr, OSRoundUp32B(bb2->length), bb2->offset, cb); + break; + } + } else if (type == -1) { + } else if (type == -4) { + status = 0; + DVDReset(); + DVDReadDiskID(cmdBlock, idTmp, cb); + } +} + +/** + * @note Address: 0x800DF9EC + * @note Size: 0x168 + */ +void __fstLoad(void) +{ + int status; + char* onStr; + u8 idBuffer[64]; + void* arenaHi; + struct blah* di; + + arenaHi = OSGetArenaHi(); + idTmp = (void*)OSRoundUp32B(idBuffer); + bb2 = (void*)OSRoundUp32B(bb2Buf); + DVDReset(); + DVDReadDiskID(&block, idTmp, cb); + do { + status = DVDGetDriveStatus(); + } while (status != DVD_STATE_END); + di = (void*)OS_BASE_CACHED; + di->FSTLocationInRam = bb2->addr; + di->FSTMaxLength = bb2->maxLength; + memcpy(di, idTmp, 32); + OSReport("\n"); + OSReport(" Game Name ... %c%c%c%c\n", di->Gamecode[0], di->Gamecode[1], di->Gamecode[2], di->Gamecode[3]); + OSReport(" Company ..... %c%c\n", di->Company[0], di->Company[1]); + OSReport(" Disk # ...... %d\n", di->DiskID); + OSReport(" Game ver .... %d\n", di->Version); + if (di->Streaming == 0) { + onStr = "OFF"; + } else { + onStr = "ON"; + } + OSReport(" Streaming ... %s\n", onStr); + OSReport("\n"); + OSSetArenaHi(bb2->addr); + return; +} diff --git a/dolphin sdk not yet linked/src/exi/EXIBios.c b/dolphin sdk not yet linked/src/exi/EXIBios.c new file mode 100644 index 0000000..a7cf0f6 --- /dev/null +++ b/dolphin sdk not yet linked/src/exi/EXIBios.c @@ -0,0 +1,817 @@ +#include "Dolphin/exi.h" + +#pragma scheduling off + +char* __EXIVersion = "<< Dolphin SDK - EXI\trelease build: Apr 17 2003 12:33:17 (0x2301) >>"; + +static EXIControl Ecb[EXI_MAX_CHAN]; +static u32 IDSerialPort1; + +/** + * @note Address: 0x800DFB54 + * @note Size: 0xF4 + */ +static void SetExiInterruptMask(s32 chan, EXIControl* exi) +{ + EXIControl* exi2; + + exi2 = &Ecb[2]; + switch (chan) { + case 0: + if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & EXI_STATE_LOCKED)) { + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI); + } else { + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI); + } + break; + case 1: + if (exi->exiCallback == 0 || (exi->state & EXI_STATE_LOCKED)) { + __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 & EXI_STATE_LOCKED)) { + __OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG); + } else { + __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG); + } + break; + } +} + +/** + * @note Address: N/A + * @note Size: 0x154 + */ +static void CompleteTransfer(s32 chan) +{ + EXIControl* exi = &Ecb[chan]; + u8* buf; + u32 data; + int i; + int len; + + if (exi->state & EXI_STATE_BUSY) { + if ((exi->state & EXI_STATE_IMM) && (len = exi->immLen)) { + buf = exi->immBuf; + data = EXIREG(chan, 4); + for (i = 0; i < len; i++) { + *buf++ = (u8)((data >> ((3 - i) * 8)) & 0xff); + } + } + exi->state &= ~EXI_STATE_BUSY; + } +} + +/** + * @note Address: 0x800DFC48 + * @note Size: 0x25C + */ +BOOL EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) +{ + EXIControl* exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & EXI_STATE_BUSY) || !(exi->state & EXI_STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->tcCallback = callback; + if (exi->tcCallback) { + EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan)); + } + + exi->state |= EXI_STATE_IMM; + + if (type != EXI_READ) { + u32 data; + int i; + + data = 0; + for (i = 0; i < len; i++) { + data |= ((u8*)buf)[i] << ((3 - i) * 8); + } + EXIREG(chan, 4) = data; + } + + exi->immBuf = buf; + exi->immLen = (type != EXI_WRITE) ? len : 0; + + EXIREG(chan, 3) = EXI_0CR(1, 0, type, len - 1); + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +/** + * @note Address: 0x800DFEA4 + * @note Size: 0xA0 + */ +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; +} + +/** + * @note Address: 0x800DFF44 + * @note Size: 0xEC + */ +BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) +{ + EXIControl* exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & EXI_STATE_BUSY) || !(exi->state & EXI_STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->tcCallback = callback; + if (exi->tcCallback) { + EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan)); + } + + exi->state |= EXI_STATE_DMA; + + EXIREG(chan, 1) = (u32)buf & 0x3ffffe0; + EXIREG(chan, 2) = (u32)len; + EXIREG(chan, 3) = EXI_0CR(1, 1, type, 0); + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +/** + * @note Address: 0x800E0030 + * @note Size: 0x24C + */ +BOOL EXISync(s32 chan) +{ + EXIControl* exi = &Ecb[chan]; + BOOL rc = FALSE; + BOOL enabled; + + while (exi->state & EXI_STATE_SELECTED) { + if (((EXIREG(chan, 3) & 1) >> 0) == 0) { + enabled = OSDisableInterrupts(); + if (exi->state & EXI_STATE_SELECTED) { + CompleteTransfer(chan); + if (__OSGetDIConfig() != 0xff || ((OSGetConsoleType() & 0xF0000000) == OS_CONSOLE_TDEVKIT) || exi->immLen != 4 + || (EXIREG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) + || (EXIREG(chan, 4) != EXI_USB_ADAPTER && EXIREG(chan, 4) != EXI_IS_VIEWER && EXIREG(chan, 4) != 0x04220001) + || __OSDeviceCode == 0x8200) { + rc = TRUE; + } + } + OSRestoreInterrupts(enabled); + break; + } + } + return rc; +} + +/** + * @note Address: 0x800E027C + * @note Size: 0x48 + */ +int EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) +{ + u32 cpr; + u32 prev; + + prev = cpr = EXIREG(chan, 0); + cpr &= 0x7f5; + if (exi) + cpr |= 2; + if (tc) + cpr |= 8; + if (ext) + cpr |= 0x800; + EXIREG(chan, 0) = cpr; + return prev; +} + +/** + * @note Address: 0x800E02C4 + * @note Size: 0x7C + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void EXIProbeReset(void) +{ + __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0; + Ecb[0].idTime = Ecb[1].idTime = 0; + __EXIProbe(0); + __EXIProbe(1); +} + +/** + * @note Address: 0x800E0340 + * @note Size: 0x174 + */ +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 = EXIREG(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; +} + +/** + * @note Address: 0x800E04B4 + * @note Size: 0x80 + */ +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; +} + +/** + * @note Address: 0x800E0534 + * @note Size: 0xB4 + */ +s32 EXIProbeEx(s32 chan) +{ + if (EXIProbe(chan)) { + return 1; + } else if (__EXIProbeStartTime[chan] != 0) { + return 0; + } else { + return -1; + } +} + +/** + * @note Address: N/A + * @note Size: 0xD4 + */ +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 |= EXI_STATE_ATTACHED; + OSRestoreInterrupts(enabled); + + return TRUE; +} + +/** + * @note Address: 0x800E05E8 + * @note Size: 0x10C + */ +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; +} + +/** + * @note Address: 0x800E06F4 + * @note Size: 0xBC + */ +BOOL EXIDetach(s32 chan) +{ + EXIControl* exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if (!(exi->state & EXI_STATE_ATTACHED)) { + OSRestoreInterrupts(enabled); + return TRUE; + } + if ((exi->state & EXI_STATE_LOCKED) && exi->dev == 0) { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->state &= ~EXI_STATE_ATTACHED; + __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan)); + OSRestoreInterrupts(enabled); + return TRUE; +} + +/** + * @note Address: 0x800E07B0 + * @note Size: 0x12C + */ +BOOL EXISelect(s32 chan, u32 dev, u32 freq) +{ + EXIControl* exi = &Ecb[chan]; + u32 cpr; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & EXI_STATE_SELECTED) + || chan != 2 + && (dev == 0 && !(exi->state & EXI_STATE_ATTACHED) && !__EXIProbe(chan) || !(exi->state & EXI_STATE_LOCKED) + || (exi->dev != dev))) { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->state |= EXI_STATE_SELECTED; + cpr = EXIREG(chan, 0); + cpr &= 0x405; + cpr |= EXI_CPR_CS(dev) | EXI_CPR_CLK(freq); + EXIREG(chan, 0) = cpr; + + if (exi->state & EXI_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; +} + +/** + * @note Address: 0x800E08DC + * @note Size: 0x110 + */ +BOOL EXIDeselect(s32 chan) +{ + EXIControl* exi = &Ecb[chan]; + u32 cpr; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if (!(exi->state & EXI_STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return FALSE; + } + exi->state &= ~EXI_STATE_SELECTED; + cpr = EXIREG(chan, 0); + EXIREG(chan, 0) = cpr & 0x405; + + if (exi->state & EXI_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 & EXI_CPR_CS(0))) { + return __EXIProbe(chan) ? TRUE : FALSE; + } + + return TRUE; +} + +/** + * @note Address: 0x800E09EC + * @note Size: 0xC8 + */ +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); + } + + // needed for stack fixing + { + s32 dummy1; + s32 dummy2; + } +} + +/** + * @note Address: 0x800E0AB4 + * @note Size: 0x218 + */ +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); + } + + // needed for stack fixing + { + s32 dummy1; + s32 dummy2; + } +} + +/** + * @note Address: 0x800E0CCC + * @note Size: 0xD0 + */ +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 &= ~EXI_STATE_ATTACHED; + if (callback) { + OSContext exceptionContext; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + exi->extCallback = 0; + callback(chan, context); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +/** + * @note Address: 0x800E0D9C + * @note Size: 0x1D4 + */ +void EXIInit(void) +{ + u32 id; + while (((EXIREG(0, 3) & 0x1) == 1) || ((EXIREG(1, 3) & 0x1) == 1) || ((EXIREG(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); + + EXIREG(0, 0) = 0; + EXIREG(1, 0) = 0; + EXIREG(2, 0) = 0; + + EXIREG(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); +} + +/** + * @note Address: 0x800E0F70 + * @note Size: 0xF4 + */ +BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) +{ + EXIControl* exi = &Ecb[chan]; + BOOL enabled; + int i; + + enabled = OSDisableInterrupts(); + if (exi->state & EXI_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 |= EXI_STATE_LOCKED; + exi->dev = dev; + SetExiInterruptMask(chan, exi); + + OSRestoreInterrupts(enabled); + return TRUE; +} + +/** + * @note Address: 0x800E1064 + * @note Size: 0xDC + */ +BOOL EXIUnlock(s32 chan) +{ + EXIControl* exi = &Ecb[chan]; + BOOL enabled; + EXICallback unlockedCallback; + + enabled = OSDisableInterrupts(); + if (!(exi->state & EXI_STATE_LOCKED)) { + OSRestoreInterrupts(enabled); + return FALSE; + } + exi->state &= ~EXI_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; +} + +/** + * @note Address: 0x800E1140 + * @note Size: 0x18 + */ +u32 EXIGetState(s32 chan) +{ + EXIControl* exi = &Ecb[chan]; + + return (u32)exi->state; +} + +/** + * @note Address: 0x800E1158 + * @note Size: 0x28 + */ +static void UnlockedHandler(s32 chan, OSContext* context) +{ + u32 id; + + EXIGetID(chan, 0, &id); +} + +/** + * @note Address: 0x800E1180 + * @note Size: 0x3B0 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x234 + */ +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/dolphin sdk not yet linked/src/exi/EXIUart.c b/dolphin sdk not yet linked/src/exi/EXIUart.c new file mode 100644 index 0000000..e672167 --- /dev/null +++ b/dolphin sdk not yet linked/src/exi/EXIUart.c @@ -0,0 +1,206 @@ +#include "Dolphin/os.h" +#include "Dolphin/exi.h" + +static s32 Chan; +static u32 Dev; +static u32 Enabled = 0; +static u32 BarnacleEnabled = 0; + +/** + * @note Address: 0x800E1530 + * @note Size: 0x18C + */ +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; +} + +/** + * @note Address: 0x800E16BC + * @note Size: 0x1BC + */ +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; + } + } +} + +/** + * @note Address: 0x800E1878 + * @note Size: 0x70 + */ +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; + } +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +u32 ReadUARTN(void* bytes, u32 len) { return 4; } + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +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); +} + +/** + * @note Address: 0x800E18E8 + * @note Size: 0x21C + */ +u32 WriteUARTN(const void* buf, u32 len) +{ + u32 cmd; + BOOL interrupt; + int qLen; + s32 xLen; + char* ptr; + BOOL locked; + u32 error; + + if (Enabled != EXI_MAGIC) + return 2; + + interrupt = OSDisableInterrupts(); + + locked = EXILock(Chan, Dev, 0); + if (!locked) { + OSRestoreInterrupts(interrupt); + 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) ? (s32)len : 4; + EXIImm(Chan, (void*)buf, xLen, EXI_WRITE, NULL); + (u8*)buf += xLen; + len -= xLen; + qLen -= xLen; + EXISync(Chan); + } + EXIDeselect(Chan); + } + + EXIUnlock(Chan); + OSRestoreInterrupts(interrupt); + return error; +} diff --git a/dolphin sdk not yet linked/src/gba/GBA.c b/dolphin sdk not yet linked/src/gba/GBA.c new file mode 100644 index 0000000..1cb0c63 --- /dev/null +++ b/dolphin sdk not yet linked/src/gba/GBA.c @@ -0,0 +1,116 @@ +#include "Dolphin/gba.h" + +char* __GBAVersion = "<< Dolphin SDK - GBA\trelease build: Dec 3 2003 18:41:55 (0x2301) >>"; +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 0x7E }; +static GBASecParam SecParams[4] ATTRIBUTE_ALIGN(32); +GBAControl __GBA[4]; +static BOOL Initialized; +BOOL __GBAReset; + +/** + * @note Address: 0x800FEB2C + * @note Size: 0x54 + */ +static void ShortCommandProc(s32 chan) +{ + GBAControl* port = &__GBA[chan]; + if (port->ret != 0) { + return; + } + if ((port->input[0] != 0) || (port->input[1] != 4)) { + port->ret = 1; + return; + } + *port->status = port->input[2] & 0x3A; +} + +/** + * @note Address: 0x800FEB80 + * @note Size: 0xC0 + */ +void GBAInit(void) +{ + GBAControl* gba; + s32 chan; + + if (Initialized == FALSE) { + Initialized = TRUE; + OSRegisterVersion(__GBAVersion); + for (chan = 0; chan < 4; ++chan) { + gba = &__GBA[chan]; + gba->delay = OSMicrosecondsToTicks(60); + OSInitThreadQueue(&gba->threadQueue); + gba->param = &SecParams[chan]; + } + OSInitAlarm(); + + DSPInit(); + + __GBAReset = FALSE; + OSRegisterResetFunction(&ResetFunctionInfo); + } +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +int GBAGetStatusAsync(s32 chan, u8* statusPtr) +{ + GBAControl* gba = &__GBA[chan]; + if (gba->callback) { + return 2; + } + + gba->output[0] = 0; + gba->status = statusPtr; + gba->callback = __GBASyncCallback; + return __GBATransfer(chan, 1, 3, ShortCommandProc); +} + +/** + * @note Address: 0x800FEC40 + * @note Size: 0x90 + */ +int GBAGetStatus(s32 chan, u8* statusPtr) +{ + int status = GBAGetStatusAsync(chan, statusPtr); + return (status != 0) ? status : __GBASync(chan); +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +int GBAResetAsync(s32 chan, u8* statusPtr) +{ + GBAControl* gba = &__GBA[chan]; + if (gba->callback) { + return 2; + } + + gba->output[0] = 0xFF; + gba->status = statusPtr; + gba->callback = __GBASyncCallback; + return __GBATransfer(chan, 1, 3, ShortCommandProc); +} + +/** + * @note Address: 0x800FECD0 + * @note Size: 0x90 + */ +int GBAReset(s32 chan, u8* statusPtr) +{ + int status = GBAResetAsync(chan, statusPtr); + return (status != 0) ? status : __GBASync(chan); +} + +/** + * @note Address: 0x800FED60 + * @note Size: 0x10 + */ +static int OnReset(void) +{ + __GBAReset = TRUE; + return 1; +} diff --git a/dolphin sdk not yet linked/src/gba/GBARead.c b/dolphin sdk not yet linked/src/gba/GBARead.c new file mode 100644 index 0000000..2381d2d --- /dev/null +++ b/dolphin sdk not yet linked/src/gba/GBARead.c @@ -0,0 +1,42 @@ +#include "Dolphin/gba.h" + +/** + * @note Address: 0x800FED70 + * @note Size: 0x60 + */ +void ReadProc(s32 chan) +{ + GBAControl* gba = &__GBA[chan]; + if (gba->ret == 0) { + memcpy(gba->ptr, &gba->input, 4); + *gba->status = gba->input[4] & 0x3A; + } +} + +/** + * @note Address: N/A + * @note Size: 0x6C + */ +int GBAReadAsync(s32 chan, u8* ptr, u8* statusPtr) +{ + GBAControl* gba = &__GBA[chan]; + if (gba->callback) { + return 2; + } + gba->output[0] = 0x14; + gba->ptr = ptr; + gba->status = statusPtr; + gba->callback = __GBASyncCallback; + return __GBATransfer(chan, 1, 5, ReadProc); +} + +/** + * @note Address: 0x800FEDD0 + * @note Size: 0x94 + */ +int GBARead(s32 chan, u8* ptr, u8* statusPtr) +{ + int _unused; // for stack size, probably commented out code + int status = GBAReadAsync(chan, ptr, statusPtr); + return (status != 0) ? status : __GBASync(chan); +} diff --git a/dolphin sdk not yet linked/src/gba/GBAWrite.c b/dolphin sdk not yet linked/src/gba/GBAWrite.c new file mode 100644 index 0000000..fb0b99e --- /dev/null +++ b/dolphin sdk not yet linked/src/gba/GBAWrite.c @@ -0,0 +1,42 @@ +#include "Dolphin/gba.h" + +/** + * @note Address: 0x800FEE64 + * @note Size: 0x30 + */ +void WriteProc(s32 chan) +{ + GBAControl* gba = &__GBA[chan]; + if (gba->ret == 0) { + *gba->status = gba->input[0] & 0x3A; + } +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +int GBWriteAsync(s32 chan, u8* ptr, u8* statusPtr) +{ + GBAControl* gba = &__GBA[chan]; + if (gba->callback) { + return 2; + } + gba->output[0] = 0x15; + memcpy(&gba->output[1], ptr, 4); + gba->ptr = ptr; + gba->status = statusPtr; + gba->callback = __GBASyncCallback; + return __GBATransfer(chan, 5, 1, WriteProc); +} + +/** + * @note Address: 0x800FEE94 + * @note Size: 0xC4 + */ +int GBAWrite(s32 chan, u8* ptr, u8* statusPtr) +{ + int _unused; // for stack size, probably commented out code + int status = GBWriteAsync(chan, ptr, statusPtr); + return (status != 0) ? status : __GBASync(chan); +} diff --git a/dolphin sdk not yet linked/src/gba/GBAXfer.c b/dolphin sdk not yet linked/src/gba/GBAXfer.c new file mode 100644 index 0000000..61df958 --- /dev/null +++ b/dolphin sdk not yet linked/src/gba/GBAXfer.c @@ -0,0 +1,118 @@ +#include "Dolphin/gba.h" +#include "Dolphin/os.h" +#include "Dolphin/si.h" + +/** + * @note Address: 0x800FEF58 + * @note Size: 0xDC + */ +static void __GBAHandler(s32 chan, u32 flag, OSContext* context) +{ + GBASyncCallback syncCallback; + GBAProcHandler procHandler; + GBAControl* gba = &__GBA[chan]; + OSContext syncContext; + + if (__GBAReset == FALSE) { + if (flag & 0xF) { + gba->ret = 1; + } else { + gba->ret = 0; + } + procHandler = getGBAHandler(gba); + if (procHandler) { + gba->proc = nullptr; + procHandler(chan); + } + if (gba->callback) { + OSClearContext(&syncContext); + OSSetCurrentContext(&syncContext); + syncCallback = gba->callback; + gba->callback = nullptr; + syncCallback(chan, gba->ret); + OSClearContext(&syncContext); + OSSetCurrentContext(context); + } + } +} + +/** + * @note Address: 0x800FF034 + * @note Size: 0x34 + */ +void __GBASyncCallback(s32 chan, int ret) { OSWakeupThread(&__GBA[chan].threadQueue); } + +/** + * @note Address: 0x800FF068 + * @note Size: 0x6C + */ +int __GBASync(s32 chan) +{ + int result; + GBAControl* gba = &__GBA[chan]; + int interrupts = OSDisableInterrupts(); + while (gba->callback) { + OSSleepThread(&gba->threadQueue); + } + result = gba->ret; + OSRestoreInterrupts(interrupts); + return result; +} + +/** + * @note Address: 0x800FF0D4 + * @note Size: 0x124 + */ +static void TypeAndStatusCallback(s32 chan, u32 flags) +{ + GBAControl* gba = &__GBA[chan]; + OSContext* osContext; + GBAProcHandler procHandler; + OSContext newContext; + GBASyncCallback syncCallback; + + if (__GBAReset == FALSE) { + if ((u8)flags != 0 || ((flags & 0xFFFF0000) + 0xFFFC0000) != 0) { + gba->ret = 1; + } else { + if (SITransfer(chan, gba->output, gba->outputBytes, gba->input, gba->inputBytes, &__GBAHandler, gba->delay) != 0) { + return; + } + gba->ret = 2; + } + procHandler = getGBAHandler(gba); + if (procHandler) { + gba->proc = nullptr; + procHandler(chan); + } + if (gba->callback) { + osContext = OSGetCurrentContext(); + OSClearContext(&newContext); + OSSetCurrentContext(&newContext); + syncCallback = gba->callback; + gba->callback = nullptr; + syncCallback(chan, gba->ret); + OSClearContext(&newContext); + OSSetCurrentContext(osContext); + __OSReschedule(); + } + } +} + +/** + * @note Address: 0x800FF1F8 + * @note Size: 0x74 + */ +BOOL __GBATransfer(s32 chan, u32 outputBytes, u32 inputBytes, GBAProcHandler gbaProcHandler) +{ + u32 interruptsTemp; + GBAControl* gba = &__GBA[chan]; + + interruptsTemp = OSDisableInterrupts(); + gba->proc = gbaProcHandler; + gba->outputBytes = outputBytes; + gba->inputBytes = inputBytes; + SIGetTypeAsync(chan, &TypeAndStatusCallback); + OSRestoreInterrupts(interruptsTemp); + return FALSE; +} diff --git a/dolphin sdk not yet linked/src/gd/GDBase.c b/dolphin sdk not yet linked/src/gd/GDBase.c new file mode 100644 index 0000000..0aeb5a8 --- /dev/null +++ b/dolphin sdk not yet linked/src/gd/GDBase.c @@ -0,0 +1,61 @@ +#include "types.h" +#include "Dolphin/os.h" +#include "Dolphin/gd.h" + +GDCurrentDL* __GDCurrentDL = (GDCurrentDL*)NULL; +GDOverflowCallback overflowcb = (GDOverflowCallback)NULL; + +/** + * @note Address: 0x800E1B04 + * @note Size: 0x18 + */ +void GDInitGDLObj(GDCurrentDL* GDL_Obj, u8* start, s32 len) +{ + GDL_Obj->begin = start; + GDL_Obj->data = start; + GDL_Obj->end = start + len; + GDL_Obj->length = len; +} + +/** + * @note Address: 0x800E1B1C + * @note Size: 0x2C + */ +void GDFlushCurrToMem() { DCFlushRange(__GDCurrentDL->begin, __GDCurrentDL->length); } + +/** + * @note Address: 0x800E1B48 + * @note Size: 0xF8 + */ +void GDPadCurr32() +{ + u32 i = ((u32)__GDCurrentDL->data & 31); + if (i) { + for (i; i < 32; i++) { + __GDWrite(0); + } + } +} + +/** + * @note Address: 0x800E1C40 + * @note Size: 0x30 + */ +void GDOverflowed(void) +{ + if (overflowcb) { + (*overflowcb)(); + } +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void GDSetOverflowCallback(GDOverflowCallback cb) { overflowcb = cb; } + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +GDOverflowCallback GDGetOverflowCallback(void) { return overflowcb; } diff --git a/dolphin sdk not yet linked/src/gd/GDGeometry.c b/dolphin sdk not yet linked/src/gd/GDGeometry.c new file mode 100644 index 0000000..2b9f9b7 --- /dev/null +++ b/dolphin sdk not yet linked/src/gd/GDGeometry.c @@ -0,0 +1,200 @@ +#include "Dolphin/gd.h" +#include "Dolphin/os.h" + +/** + * @note Address: 0x800E1C70 + * @note Size: 0x5FC + */ +void GDSetVtxDescv(GXVtxDescList* lists) +{ + u32 v1 = 0; // r31 + u32 v2 = 0; // r30 + u32 v3 = 0; // r29 + u32 v4 = 0; // r28 + u32 v5 = 0; // r27 + u32 v6 = 1; // r26 + u32 v7 = 0; // r25 + u32 v8 = 0; // r24 + u32 v9 = 0; // r23 + u32 v10 = 0; // r22 + u32 v11 = 0; // r21 + u32 v12 = 0; // r20 + u32 v13 = 0; // r19 + u32 v14 = 0; // r18 + u32 v15 = 0; // r17 + u32 v16 = 0; // r16 + u32 v17 = 0; // r15 + + while (lists->mAttr != GX_VA_NULL) { + switch (lists->mAttr) { + case GX_VA_PNMTXIDX: + v4 = lists->mType; + break; + case GX_VA_TEX0MTXIDX: + v5 = v5 & ~0x1 | lists->mType; + break; + case GX_VA_TEX1MTXIDX: + v5 = v5 & ~0x2 | lists->mType << 1; + break; + case GX_VA_TEX2MTXIDX: + v5 = v5 & ~0x4 | lists->mType << 2; + break; + case GX_VA_TEX3MTXIDX: + v5 = v5 & ~0x8 | lists->mType << 3; + break; + case GX_VA_TEX4MTXIDX: + v5 = v5 & ~0x10 | lists->mType << 4; + break; + case GX_VA_TEX5MTXIDX: + v5 = v5 & ~0x20 | lists->mType << 5; + break; + case GX_VA_TEX6MTXIDX: + v5 = v5 & ~0x40 | lists->mType << 6; + break; + case GX_VA_TEX7MTXIDX: + v5 = v5 & ~0x80 | lists->mType << 7; + break; + + case GX_VA_POS: + v6 = lists->mType; + break; + case GX_VA_NRM: + if (lists->mType != GX_NONE) { + v1 = 1; + v7 = lists->mType; + } + break; + case GX_VA_NBT: + if (lists->mType != GX_NONE) { + v1 = 2; + v7 = lists->mType; + } + break; + case GX_VA_CLR0: + v8 = lists->mType; + v2 += (v8 != 0); + break; + case GX_VA_CLR1: + v9 = lists->mType; + v2 += (v9 != 0); + break; + case GX_VA_TEX0: + v10 = lists->mType; + v3 += (v10 != 0); + break; + case GX_VA_TEX1: + v11 = lists->mType; + v3 += (v11 != 0); + break; + case GX_VA_TEX2: + v12 = lists->mType; + v3 += (v12 != 0); + break; + case GX_VA_TEX3: + v13 = lists->mType; + v3 += (v13 != 0); + break; + case GX_VA_TEX4: + v14 = lists->mType; + v3 += (v14 != 0); + break; + case GX_VA_TEX5: + v15 = lists->mType; + v3 += (v15 != 0); + break; + case GX_VA_TEX6: + v16 = lists->mType; + v3 += (v16 != 0); + break; + case GX_VA_TEX7: + v17 = lists->mType; + v3 += (v17 != 0); + break; + + case GX_POS_MTX_ARRAY: + case GX_NRM_MTX_ARRAY: + case GX_TEX_MTX_ARRAY: + case GX_LIGHT_ARRAY: + break; + } + lists++; + } + __GDCheckOverflowed(1); + __GDWriteU8(8); + __GDCheckOverflowed(1); + __GDWriteU8(80); + __GDCheckOverflowed(4); + __GDWriteU32(v4 | v5 << 1 | v6 << 9 | v7 << 11 | v8 << 13 | v9 << 15); + + __GDCheckOverflowed(1); + __GDWriteU8(8); + __GDCheckOverflowed(1); + __GDWriteU8(96); + __GDCheckOverflowed(4); + __GDWriteU32(v10 | v11 << 2 | v12 << 4 | v13 << 6 | v14 << 8 | v15 << 10 | v16 << 12 | v17 << 14); + + __GDCheckOverflowed(1); + __GDWriteU8(16); + __GDCheckOverflowed(2); + __GDWriteU16(0); + __GDCheckOverflowed(2); + __GDWriteU16(4104); + __GDCheckOverflowed(4); + __GDWriteU32(v2 | v1 << 2 | v3 << 4); +} + +/** + * @note Address: 0x800E226C + * @note Size: 0x20C + */ +void GDSetArray(GXAttr attr, const void* data, u8 stride) +{ + u32 v1; + if (attr == GX_VA_NBT) { + v1 = 1; + } else { + v1 = attr - 9; + } + + __GDCheckOverflowed(1); + __GDWriteU8(8); + __GDCheckOverflowed(1); + __GDWriteU8(v1 + 160); + __GDCheckOverflowed(4); + __GDWriteU32(OS_BASE_CACHED + (u32)data); + + __GDCheckOverflowed(1); + __GDWriteU8(8); + __GDCheckOverflowed(1); + __GDWriteU8(v1 + 176); + __GDCheckOverflowed(4); + __GDWriteU32(stride); +} + +/** + * @note Address: 0x800E2478 + * @note Size: 0x208 + */ +void GDSetArrayRaw(GXAttr attr, u32 data, u8 stride) +{ + u32 v1; + if (attr == GX_VA_NBT) { + v1 = 1; + } else { + v1 = attr - 9; + } + + __GDCheckOverflowed(1); + __GDWriteU8(8); + __GDCheckOverflowed(1); + __GDWriteU8(v1 + 160); + __GDCheckOverflowed(4); + __GDWriteU32(data); + + __GDCheckOverflowed(1); + __GDWriteU8(8); + __GDCheckOverflowed(1); + __GDWriteU8(v1 + 176); + __GDCheckOverflowed(4); + __GDWriteU32(stride); +} diff --git a/dolphin sdk not yet linked/src/gx/GXAttr.c b/dolphin sdk not yet linked/src/gx/GXAttr.c new file mode 100644 index 0000000..1ad6333 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXAttr.c @@ -0,0 +1,573 @@ +#include "Dolphin/gx.h" +#include "Dolphin/GX/GXHardware.h" + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +static void __GXXfVtxSpecs(void) +{ + u32 normCount, colorCount, texCount; + + normCount = gx->hasBiNrms ? 2 : (gx->hasNrms ? 1 : 0); + + // Both fields in one access + colorCount = 33 - __cntlzw((gx->vcdLo & (0xf << 0xd)) >> 0xd); + colorCount /= 2; // equivalent to /=2 and >>= 1 + + // All 16 assigned bits in VCD_Hi + texCount = 33 - __cntlzw((gx->vcdHi & (0xffff << 0)) >> 0); + texCount /= 2; // equivalent to /=2 and >>= 1 + + GX_XF_LOAD_REG(GX_XF_REG_INVERTEXSPEC, (colorCount) | (normCount << 2) | (texCount << 4)); + gx->bpSentNot = GX_TRUE; + + return; +} + +/** + * @note Address: 0x800E4284 + * @note Size: 0x26C + */ + +void GXSetVtxDesc(GXAttr attr, GXAttrType type) +{ + switch (attr) { + case GX_VA_PNMTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_POSMTXIDX_ST, GX_CP_VCD_LO_POSMTXIDX_END); + break; + case GX_VA_TEX0MTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX0MTXIDX_ST, GX_CP_VCD_LO_TEX0MTXIDX_END); + break; + case GX_VA_TEX1MTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX1MTXIDX_ST, GX_CP_VCD_LO_TEX1MTXIDX_END); + break; + case GX_VA_TEX2MTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX2MTXIDX_ST, GX_CP_VCD_LO_TEX2MTXIDX_END); + break; + case GX_VA_TEX3MTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX3MTXIDX_ST, GX_CP_VCD_LO_TEX3MTXIDX_END); + break; + case GX_VA_TEX4MTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX4MTXIDX_ST, GX_CP_VCD_LO_TEX4MTXIDX_END); + break; + case GX_VA_TEX5MTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX5MTXIDX_ST, GX_CP_VCD_LO_TEX5MTXIDX_END); + break; + case GX_VA_TEX6MTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX6MTXIDX_ST, GX_CP_VCD_LO_TEX6MTXIDX_END); + break; + case GX_VA_TEX7MTXIDX: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_TEX7MTXIDX_ST, GX_CP_VCD_LO_TEX7MTXIDX_END); + break; + case GX_VA_POS: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_POS_ST, GX_CP_VCD_LO_POS_END); + break; + case GX_VA_NRM: + if (type != GX_NONE) { + gx->hasNrms = TRUE; + gx->hasBiNrms = FALSE; + gx->nrmType = type; + } else { + gx->hasNrms = FALSE; + } + break; + case GX_VA_NBT: + if (type != GX_NONE) { + gx->hasBiNrms = TRUE; + gx->hasNrms = FALSE; + gx->nrmType = type; + } else { + gx->hasBiNrms = FALSE; + } + break; + case GX_VA_CLR0: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_CLRDIF_ST, GX_CP_VCD_LO_CLRDIF_END); + break; + case GX_VA_CLR1: + GX_SET_REG(gx->vcdLo, type, GX_CP_VCD_LO_CLRSPEC_ST, GX_CP_VCD_LO_CLRSPEC_END); + break; + case GX_VA_TEX0: + GX_SET_REG(gx->vcdHi, type, GX_CP_VCD_HI_TEX0COORD_ST, GX_CP_VCD_HI_TEX0COORD_END); + break; + case GX_VA_TEX1: + GX_SET_REG(gx->vcdHi, type, GX_CP_VCD_HI_TEX1COORD_ST, GX_CP_VCD_HI_TEX1COORD_END); + break; + case GX_VA_TEX2: + GX_SET_REG(gx->vcdHi, type, GX_CP_VCD_HI_TEX2COORD_ST, GX_CP_VCD_HI_TEX2COORD_END); + break; + case GX_VA_TEX3: + GX_SET_REG(gx->vcdHi, type, GX_CP_VCD_HI_TEX3COORD_ST, GX_CP_VCD_HI_TEX3COORD_END); + break; + case GX_VA_TEX4: + GX_SET_REG(gx->vcdHi, type, GX_CP_VCD_HI_TEX4COORD_ST, GX_CP_VCD_HI_TEX4COORD_END); + break; + case GX_VA_TEX5: + GX_SET_REG(gx->vcdHi, type, GX_CP_VCD_HI_TEX5COORD_ST, GX_CP_VCD_HI_TEX5COORD_END); + break; + case GX_VA_TEX6: + GX_SET_REG(gx->vcdHi, type, GX_CP_VCD_HI_TEX6COORD_ST, GX_CP_VCD_HI_TEX6COORD_END); + break; + case GX_VA_TEX7: + GX_SET_REG(gx->vcdHi, type, GX_CP_VCD_HI_TEX7COORD_ST, GX_CP_VCD_HI_TEX7COORD_END); + break; + } + + if (gx->hasNrms || gx->hasBiNrms) { + GX_SET_REG(gx->vcdLo, gx->nrmType, GX_CP_VCD_LO_NRM_ST, GX_CP_VCD_LO_NRM_END); + } else { + GX_SET_REG(gx->vcdLo, GX_NONE, GX_CP_VCD_LO_NRM_ST, GX_CP_VCD_LO_NRM_END); + } + + gx->dirtyState |= GX_DIRTY_VCD; +} + +/** + * @note Address: N/A + * @note Size: 0x288 + */ +void GXSetVtxDescv(GXVtxDescList* list) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E44F0 + * @note Size: 0xBC + */ +void __GXSetVCD(void) +{ + + GX_CP_LOAD_REG(GX_CP_REG_VCD_LO, gx->vcdLo); + GX_CP_LOAD_REG(GX_CP_REG_VCD_HI, gx->vcdHi); + + __GXXfVtxSpecs(); +} + +/** + * @note Address: 0x800E45AC + * @note Size: 0x124 + */ +void __GXCalculateVLim(void) +{ + static u8 tbl1[] = { 0, 4, 1, 2 }; + static u8 tbl2[] = { 0, 8, 1, 2 }; + static u8 tbl3[] = { 0, 12, 1, 2 }; + + u32 vlim; + u32 vcdLo; + u32 vcdHi; + s32 compCnt; + + if (gx->vNum == 0) { + return; + } + + vcdLo = gx->vcdLo; + vcdHi = gx->vcdHi; + + // GXCompCnt bit of normal parameters + compCnt = gx->vatA[GX_VTXFMT0]; + compCnt = (compCnt & 0x200) >> 9; + + vlim = GX_GET_REG(vcdLo, GX_CP_VCD_LO_POSMTXIDX_ST, GX_CP_VCD_LO_POSMTXIDX_END); + vlim += GX_GET_REG(vcdLo, GX_CP_VCD_LO_TEX0MTXIDX_ST, GX_CP_VCD_LO_TEX0MTXIDX_END); + vlim += GX_GET_REG(vcdLo, GX_CP_VCD_LO_TEX1MTXIDX_ST, GX_CP_VCD_LO_TEX1MTXIDX_END); + vlim += GX_GET_REG(vcdLo, GX_CP_VCD_LO_TEX2MTXIDX_ST, GX_CP_VCD_LO_TEX2MTXIDX_END); + vlim += GX_GET_REG(vcdLo, GX_CP_VCD_LO_TEX3MTXIDX_ST, GX_CP_VCD_LO_TEX3MTXIDX_END); + vlim += GX_GET_REG(vcdLo, GX_CP_VCD_LO_TEX4MTXIDX_ST, GX_CP_VCD_LO_TEX4MTXIDX_END); + vlim += GX_GET_REG(vcdLo, GX_CP_VCD_LO_TEX5MTXIDX_ST, GX_CP_VCD_LO_TEX5MTXIDX_END); + vlim += GX_GET_REG(vcdLo, GX_CP_VCD_LO_TEX6MTXIDX_ST, GX_CP_VCD_LO_TEX6MTXIDX_END); + vlim += GX_GET_REG(vcdLo, GX_CP_VCD_LO_TEX7MTXIDX_ST, GX_CP_VCD_LO_TEX7MTXIDX_END); + + vlim += tbl3[GX_GET_REG(vcdLo, GX_CP_VCD_LO_POS_ST, GX_CP_VCD_LO_POS_END)]; + vlim += tbl3[GX_GET_REG(vcdLo, GX_CP_VCD_LO_NRM_ST, GX_CP_VCD_LO_NRM_END)] * (compCnt == GX_NRM_NBT ? 3 : 1); + vlim += tbl1[GX_GET_REG(vcdLo, GX_CP_VCD_LO_CLRDIF_ST, GX_CP_VCD_LO_CLRDIF_END)]; + vlim += tbl1[GX_GET_REG(vcdLo, GX_CP_VCD_LO_CLRSPEC_ST, GX_CP_VCD_LO_CLRSPEC_END)]; + + vlim += tbl2[GX_GET_REG(vcdHi, GX_CP_VCD_HI_TEX0COORD_ST, GX_CP_VCD_HI_TEX0COORD_END)]; + vlim += tbl2[GX_GET_REG(vcdHi, GX_CP_VCD_HI_TEX1COORD_ST, GX_CP_VCD_HI_TEX1COORD_END)]; + vlim += tbl2[GX_GET_REG(vcdHi, GX_CP_VCD_HI_TEX2COORD_ST, GX_CP_VCD_HI_TEX2COORD_END)]; + vlim += tbl2[GX_GET_REG(vcdHi, GX_CP_VCD_HI_TEX3COORD_ST, GX_CP_VCD_HI_TEX3COORD_END)]; + vlim += tbl2[GX_GET_REG(vcdHi, GX_CP_VCD_HI_TEX4COORD_ST, GX_CP_VCD_HI_TEX4COORD_END)]; + vlim += tbl2[GX_GET_REG(vcdHi, GX_CP_VCD_HI_TEX5COORD_ST, GX_CP_VCD_HI_TEX5COORD_END)]; + vlim += tbl2[GX_GET_REG(vcdHi, GX_CP_VCD_HI_TEX6COORD_ST, GX_CP_VCD_HI_TEX6COORD_END)]; + vlim += tbl2[GX_GET_REG(vcdHi, GX_CP_VCD_HI_TEX7COORD_ST, GX_CP_VCD_HI_TEX7COORD_END)]; + + gx->vLim = vlim; +} + +/** + * @note Address: N/A + * @note Size: 0x1B4 + */ +void GXGetVtxDesc(GXAttr attr, GXAttrType* type) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x90 + */ +void GXGetVtxDescv(GXVtxDescList* list) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E46D0 + * @note Size: 0x38 + */ +void GXClearVtxDesc(void) +{ + gx->vcdLo = 0; + GX_SET_REG(gx->vcdLo, GX_DIRECT, GX_CP_VCD_LO_POS_ST, GX_CP_VCD_LO_POS_END); + gx->vcdHi = 0; + gx->hasNrms = FALSE; + gx->hasBiNrms = FALSE; + gx->dirtyState |= GX_DIRTY_VCD; +} + +static inline void SETVAT(u32* vatA, u32* vatB, u32* vatC, GXAttr attr, GXCompCnt compCnt, GXCompType compType, u8 shift) +{ + switch (attr) { + case GX_VA_POS: + GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_POS_CNT_ST, GX_CP_VAT_GRP0_POS_CNT_END); + GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_POS_TYPE_ST, GX_CP_VAT_GRP0_POS_TYPE_END); + GX_SET_REG(*vatA, shift, GX_CP_VAT_GRP0_POS_SHIFT_ST, GX_CP_VAT_GRP0_POS_SHIFT_END); + break; + case GX_VA_NRM: + case GX_VA_NBT: + GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_NRM_TYPE_ST, GX_CP_VAT_GRP0_NRM_TYPE_END); + if (compCnt == GX_NRM_NBT3) { + // Probably because the compCnt can only be one bit? + GX_SET_REG(*vatA, GX_NRM_NBT, GX_CP_VAT_GRP0_NRM_CNT_ST, GX_CP_VAT_GRP0_NRM_CNT_END); + GX_SET_REG(*vatA, TRUE, GX_CP_VAT_GRP0_NRMIDX3_ST, GX_CP_VAT_GRP0_NRMIDX3_END); + } else { + GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_NRM_CNT_ST, GX_CP_VAT_GRP0_NRM_CNT_END); + GX_SET_REG(*vatA, FALSE, GX_CP_VAT_GRP0_NRMIDX3_ST, GX_CP_VAT_GRP0_NRMIDX3_END); + } + break; + case GX_VA_CLR0: + GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_CLRDIFF_CNT_ST, GX_CP_VAT_GRP0_CLRDIFF_CNT_END); + GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRDIFF_TYPE_ST, GX_CP_VAT_GRP0_CLRDIFF_TYPE_END); + break; + case GX_VA_CLR1: + GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_CLRSPEC_CNT_ST, GX_CP_VAT_GRP0_CLRSPEC_CNT_END); + GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRSPEC_TYPE_ST, GX_CP_VAT_GRP0_CLRSPEC_TYPE_END); + break; + case GX_VA_TEX0: + GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_TXC0_CNT_ST, GX_CP_VAT_GRP0_TXC0_CNT_END); + GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_TXC0_TYPE_ST, GX_CP_VAT_GRP0_TXC0_TYPE_END); + GX_SET_REG(*vatA, shift, GX_CP_VAT_GRP0_TXC0_SHIFT_ST, GX_CP_VAT_GRP0_TXC0_SHIFT_END); + break; + case GX_VA_TEX1: + GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC1_CNT_ST, GX_CP_VAT_GRP1_TXC1_CNT_END); + GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC1_TYPE_ST, GX_CP_VAT_GRP1_TXC1_TYPE_END); + GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC1_SHIFT_ST, GX_CP_VAT_GRP1_TXC1_SHIFT_END); + break; + case GX_VA_TEX2: + GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC2_CNT_ST, GX_CP_VAT_GRP1_TXC2_CNT_END); + GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC2_TYPE_ST, GX_CP_VAT_GRP1_TXC2_TYPE_END); + GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC2_SHIFT_ST, GX_CP_VAT_GRP1_TXC2_SHIFT_END); + break; + case GX_VA_TEX3: + GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC3_CNT_ST, GX_CP_VAT_GRP1_TXC3_CNT_END); + GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC3_TYPE_ST, GX_CP_VAT_GRP1_TXC3_TYPE_END); + GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC3_SHIFT_ST, GX_CP_VAT_GRP1_TXC3_SHIFT_END); + break; + case GX_VA_TEX4: + GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC4_CNT_ST, GX_CP_VAT_GRP1_TXC4_CNT_END); + GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC4_TYPE_ST, GX_CP_VAT_GRP1_TXC4_TYPE_END); + GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC4_SHIFT_ST, GX_CP_VAT_GRP2_TXC4_SHIFT_END); + break; + case GX_VA_TEX5: + GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC5_CNT_ST, GX_CP_VAT_GRP2_TXC5_CNT_END); + GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC5_TYPE_ST, GX_CP_VAT_GRP2_TXC5_TYPE_END); + GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC5_SHIFT_ST, GX_CP_VAT_GRP2_TXC5_SHIFT_END); + break; + case GX_VA_TEX6: + GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC6_CNT_ST, GX_CP_VAT_GRP2_TXC6_CNT_END); + GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC6_TYPE_ST, GX_CP_VAT_GRP2_TXC6_TYPE_END); + GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC6_SHIFT_ST, GX_CP_VAT_GRP2_TXC6_SHIFT_END); + break; + case GX_VA_TEX7: + GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC7_CNT_ST, GX_CP_VAT_GRP2_TXC7_CNT_END); + GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC7_TYPE_ST, GX_CP_VAT_GRP2_TXC7_TYPE_END); + GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC7_SHIFT_ST, GX_CP_VAT_GRP2_TXC7_SHIFT_END); + break; + } +} + +/** + * @note Address: 0x800E4708 + * @note Size: 0x25C + */ +void GXSetVtxAttrFmt(GXVtxFmt format, GXAttr attr, GXCompCnt count, GXCompType type, u8 frac) +{ + u32* vA = &gx->vatA[format]; + u32* vB = &gx->vatB[format]; + u32* vC = &gx->vatC[format]; + + SETVAT(vA, vB, vC, attr, count, type, frac); + + gx->dirtyState |= GX_DIRTY_VAT; + gx->dirtyVAT |= (u8)(1 << (u8)format); +} + +/** + * @note Address: 0x800E4964 + * @note Size: 0x280 + */ +void GXSetVtxAttrFmtv(GXVtxFmt format, GXVtxAttrFmtList* list) +{ + u32* vatA; + u32* vatB; + u32* vatC; + + vatA = &gx->vatA[format]; + vatB = &gx->vatB[format]; + vatC = &gx->vatC[format]; + + for (; list->mAttr != GX_VA_NULL; list++) { + SETVAT(vatA, vatB, vatC, list->mAttr, list->mCount, list->mType, list->mFrac); + } + + gx->dirtyState |= GX_DIRTY_VAT; + gx->dirtyVAT |= (u8)(1 << (u8)format); +} + +/** + * @note Address: 0x800E4BE4 + * @note Size: 0x9C + */ +void __GXSetVAT(void) +{ + u8 i; + for (i = 0; i < 8; i++) { + if (gx->dirtyVAT & (1 << (u8)i)) { + GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP0 | i, gx->vatA[i]); + GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP1 | i, gx->vatB[i]); + GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP2 | i, gx->vatC[i]); + } + } + + gx->dirtyVAT = 0; +} + +/** + * @note Address: N/A + * @note Size: 0x280 + */ +void GXGetVtxAttrFmt(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x74 + */ +void GXGetVtxAttrFmtv(GXVtxFmt format, GXVtxAttrFmtList* list) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E4C80 + * @note Size: 0x8C + */ +void GXSetArray(GXAttr attr, void* basePtr, u8 stride) +{ + s32 idx; + s32 newAttr; + s32 attrReg; + + newAttr = attr; + if (newAttr == GX_VA_NBT) { + newAttr = GX_VA_NRM; + } + + attrReg = newAttr - GX_VA_POS; + + GX_CP_LOAD_REG(GX_BP_REG_SETMODE0_TEX4 | attrReg, + // Address -> offset? + (u32)basePtr & ~0xC0000000); + + idx = attrReg - 12; + if (idx >= 0 && idx < 4) { + gx->indexBase[idx] = (u32)basePtr & ~0xC0000000; + } + + GX_CP_LOAD_REG(GX_BP_REG_SETIMAGE2_TEX4 | attrReg, stride); + + idx = attrReg - 12; + if (idx >= 0 && idx < 4) { + gx->indexStride[idx] = stride; + } +} + +/** + * @note Address: 0x800E4D0C + * @note Size: 0x10 + */ +void GXInvalidateVtxCache(void) { GX_WRITE_U8(GX_FIFO_CMD_INVAL_VTX); } + +/** + * @note Address: 0x800E4D1C + * @note Size: 0x280 + */ +void GXSetTexCoordGen2(GXTexCoordID id, GXTexGenType type, GXTexGenSrc src, u32 texMtxIdx, GXBool normalize, u32 dualTexMtxIdx) +{ + u32 reg; + u32 inputRow; + GXXfTexReg inputForm; + + reg = 0; + inputForm = GX_XF_TEX_FORM_AB11; + inputRow = 5; + + switch (src) { + case GX_TG_POS: + inputRow = 0; + inputForm = GX_XF_TEX_FORM_ABC1; + break; + case GX_TG_NRM: + inputRow = 1; + inputForm = GX_XF_TEX_FORM_ABC1; + break; + case GX_TG_BINRM: + inputRow = 3; + inputForm = GX_XF_TEX_FORM_ABC1; + break; + case GX_TG_TANGENT: + inputRow = 4; + inputForm = GX_XF_TEX_FORM_ABC1; + break; + case GX_TG_COLOR0: + inputRow = 2; + break; + case GX_TG_COLOR1: + inputRow = 2; + break; + case GX_TG_TEX0: + inputRow = 5; + break; + case GX_TG_TEX1: + inputRow = 6; + break; + case GX_TG_TEX2: + inputRow = 7; + break; + case GX_TG_TEX3: + inputRow = 8; + break; + case GX_TG_TEX4: + inputRow = 9; + break; + case GX_TG_TEX5: + inputRow = 10; + break; + case GX_TG_TEX6: + inputRow = 11; + break; + case GX_TG_TEX7: + inputRow = 12; + break; + } + + switch (type) { + case GX_TG_NRM: + // reg = 0; + GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, GX_XF_TEX_PROJTYPE_END); // 2x4 projection + GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); + GX_SET_REG(reg, GX_TG_POS, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + break; + case GX_TG_POS: + // reg = 0; + GX_SET_REG(reg, GX_XF_TEX_PROJ_STQ, GX_XF_TEX_PROJTYPE_ST, GX_XF_TEX_PROJTYPE_END); // 3x4 projection + GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); + GX_SET_REG(reg, GX_TG_POS, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + 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: + // reg = 0; + GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, GX_XF_TEX_PROJTYPE_END); // 2x4 projection + GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); + GX_SET_REG(reg, GX_TG_NRM, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + GX_SET_REG(reg, src - GX_TG_TEXCOORD0, GX_XF_TEX_BUMPSRCTEX_ST, GX_XF_TEX_BUMPSRCTEX_END); + GX_SET_REG(reg, type - GX_TG_BUMP0, GX_XF_TEX_BUMPSRCLIGHT_ST, GX_XF_TEX_BUMPSRCLIGHT_END); + break; + case GX_TG_SRTG: + // reg = 0; + GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, GX_XF_TEX_PROJTYPE_END); // 2x4 projection + GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); + + if (src == GX_TG_COLOR0) { + GX_SET_REG(reg, GX_XF_TG_CLR0, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + } else { + GX_SET_REG(reg, GX_XF_TG_CLR1, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + } + GX_SET_REG(reg, 2, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + break; + default: + break; + } + + GX_XF_LOAD_REG(GX_XF_REG_TEX0 + id, reg); + + reg = 0; + GX_SET_REG(reg, dualTexMtxIdx - 0x40, GX_XF_MTXIDX0_GEOM_ST, GX_XF_MTXIDX0_GEOM_END); + GX_SET_REG(reg, normalize, GX_XF_DUALTEX_NORMALISE_ST, GX_XF_DUALTEX_NORMALISE_END); + + GX_XF_LOAD_REG(GX_XF_REG_DUALTEX0 + id, reg); + + switch (id) { + case GX_TEXCOORD0: + GX_SET_REG(gx->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX0_ST, GX_XF_MTXIDX0_TEX0_END); + break; + case GX_TEXCOORD1: + GX_SET_REG(gx->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX1_ST, GX_XF_MTXIDX0_TEX1_END); + break; + case GX_TEXCOORD2: + GX_SET_REG(gx->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX2_ST, GX_XF_MTXIDX0_TEX2_END); + break; + case GX_TEXCOORD3: + GX_SET_REG(gx->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX3_ST, GX_XF_MTXIDX0_TEX3_END); + break; + case GX_TEXCOORD4: + GX_SET_REG(gx->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX4_ST, GX_XF_MTXIDX1_TEX4_END); + break; + case GX_TEXCOORD5: + GX_SET_REG(gx->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX5_ST, GX_XF_MTXIDX1_TEX5_END); + break; + case GX_TEXCOORD6: + GX_SET_REG(gx->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX6_ST, GX_XF_MTXIDX1_TEX6_END); + break; + default: + GX_SET_REG(gx->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX7_ST, GX_XF_MTXIDX1_TEX7_END); + break; + } + __GXSetMatrixIndex(id + 1); +} + +/** + * @note Address: 0x800E4F9C + * @note Size: 0x3C + */ +void GXSetNumTexGens(u8 count) +{ + GX_SET_REG(gx->genMode, count, GX_BP_GENMODE_NUMTEX_ST, GX_BP_GENMODE_NUMTEX_END); + GX_XF_LOAD_REG(GX_XF_REG_NUMTEX, count); + gx->dirtyState |= GX_DIRTY_GEN_MODE; +} diff --git a/dolphin sdk not yet linked/src/gx/GXBump.c b/dolphin sdk not yet linked/src/gx/GXBump.c new file mode 100644 index 0000000..7ba1fc6 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXBump.c @@ -0,0 +1,240 @@ +#include "types.h" +#include "Dolphin/gx.h" + +/** + * @note Address: 0x800E7F40 + * @note Size: 0x6C + */ +// modified from Open_RVL +void GXSetTevIndirect(GXTevStageID tevStage, GXIndTexStageID texStage, GXIndTexFormat texFmt, GXIndTexBiasSel biasSel, GXIndTexMtxID mtxId, + GXIndTexWrap wrapS, GXIndTexWrap wrapT, u8 addPrev, u8 utcLod, GXIndTexAlphaSel alphaSel) +{ + u32 field = 0; + const u32 stage = tevStage + 0x10; + + GX_SET_REG(field, texStage, GX_BP_INDTEV_STAGE_ST, GX_BP_INDTEV_STAGE_END); + GX_SET_REG(field, texFmt, GX_BP_INDTEV_FMT_ST, GX_BP_INDTEV_FMT_END); + GX_SET_REG(field, biasSel, GX_BP_INDTEV_BIAS_ST, GX_BP_INDTEV_BIAS_END); + GX_SET_REG(field, alphaSel, GX_BP_INDTEV_ALPHA_ST, GX_BP_INDTEV_ALPHA_END); + GX_SET_REG(field, mtxId, GX_BP_INDTEV_MTX_ST, GX_BP_INDTEV_MTX_END); + GX_SET_REG(field, wrapS, GX_BP_INDTEV_WRAPS_ST, GX_BP_INDTEV_WRAPS_END); + GX_SET_REG(field, wrapT, GX_BP_INDTEV_WRAPT_ST, GX_BP_INDTEV_WRAPT_END); + GX_SET_REG(field, utcLod, GX_BP_INDTEV_UNMODTEXCOORD_ST, GX_BP_INDTEV_UNMODTEXCOORD_END); + GX_SET_REG(field, addPrev, GX_BP_INDTEV_ADDPREV_ST, GX_BP_INDTEV_ADDPREV_END); + GX_SET_REG(field, stage, 0, 7); + + GX_BP_LOAD_REG(field); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E7FAC + * @note Size: 0x178 + */ +// modified from Open_RVL +void GXSetIndTexMtx(GXIndTexMtxID id, const Mtx23 mtx, s8 scale_exp) +{ + u32 val; + u32 field; + f32 mtx2[6]; + + // scale_exp range is -17..46 + // we need it in range 0..63 + scale_exp += 17; + + switch (id) { + case GX_ITM_0: + case GX_ITM_1: + case GX_ITM_2: + val = id - 1; + break; + case GX_ITM_S0: + case GX_ITM_S1: + case GX_ITM_S2: + val = id - 5; + break; + case GX_ITM_T0: + case GX_ITM_T1: + case GX_ITM_T2: + val = id - 9; + break; + default: + val = 0; + } + + field = 0; + GX_SET_REG(field, 1024.0f * mtx[0][0], GX_BP_INDMTX_M00_ST, GX_BP_INDMTX_M00_END); + GX_SET_REG(field, 1024.0f * mtx[1][0], GX_BP_INDMTX_M10_ST, GX_BP_INDMTX_M10_END); + GX_SET_REG(field, (scale_exp >> 0) & 3, GX_BP_INDMTX_EXP_ST, GX_BP_INDMTX_EXP_END); + GX_SET_REG(field, val * 3 + 6, 0, 7); + + GX_BP_LOAD_REG(field); + + field = 0; + GX_SET_REG(field, 1024.0f * mtx[0][1], GX_BP_INDMTX_M00_ST, GX_BP_INDMTX_M00_END); + GX_SET_REG(field, 1024.0f * mtx[1][1], GX_BP_INDMTX_M10_ST, GX_BP_INDMTX_M10_END); + GX_SET_REG(field, (scale_exp >> 2) & 3, GX_BP_INDMTX_EXP_ST, GX_BP_INDMTX_EXP_END); + GX_SET_REG(field, val * 3 + 7, 0, 7); + + GX_BP_LOAD_REG(field); + + field = 0; + GX_SET_REG(field, 1024.0f * mtx[0][2], GX_BP_INDMTX_M00_ST, GX_BP_INDMTX_M00_END); + GX_SET_REG(field, 1024.0f * mtx[1][2], GX_BP_INDMTX_M10_ST, GX_BP_INDMTX_M10_END); + GX_SET_REG(field, (scale_exp >> 4) & 3, GX_BP_INDMTX_EXP_ST, GX_BP_INDMTX_EXP_END); + GX_SET_REG(field, val * 3 + 8, 0, 7); + + GX_BP_LOAD_REG(field); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8124 + * @note Size: 0x144 + */ +// modified from Open_RVL +void GXSetIndTexCoordScale(GXIndTexStageID stage, GXIndTexScale scaleS, GXIndTexScale scaleT) +{ + GXData* data; + switch (stage) { + case GX_IND_TEX_STAGE_0: + GX_SET_REG(gx->IndTexScale0, scaleS, GX_BP_RAS1_SS0_S0_ST, GX_BP_RAS1_SS0_S0_END); + GX_SET_REG(gx->IndTexScale0, scaleT, GX_BP_RAS1_SS0_T0_ST, GX_BP_RAS1_SS0_T0_END); + GX_SET_REG(gx->IndTexScale0, 0x25, 0, 7); + + GX_BP_LOAD_REG(gx->IndTexScale0); + break; + + case GX_IND_TEX_STAGE_1: + GX_SET_REG(gx->IndTexScale0, scaleS, GX_BP_RAS1_SS0_S1_ST, GX_BP_RAS1_SS0_S1_END); + GX_SET_REG(gx->IndTexScale0, scaleT, GX_BP_RAS1_SS0_T1_ST, GX_BP_RAS1_SS0_T1_END); + GX_SET_REG(gx->IndTexScale0, 0x25, 0, 7); + + GX_BP_LOAD_REG(gx->IndTexScale0); + break; + + case GX_IND_TEX_STAGE_2: + GX_SET_REG(gx->IndTexScale1, scaleS, GX_BP_RAS1_SS1_S2_ST, GX_BP_RAS1_SS1_S2_END); + GX_SET_REG(gx->IndTexScale1, scaleT, GX_BP_RAS1_SS1_T2_ST, GX_BP_RAS1_SS1_T2_END); + GX_SET_REG(gx->IndTexScale1, 0x26, 0, 7); + + GX_BP_LOAD_REG(gx->IndTexScale1); + break; + + case GX_IND_TEX_STAGE_3: + GX_SET_REG(gx->IndTexScale1, scaleS, GX_BP_RAS1_SS1_S3_ST, GX_BP_RAS1_SS1_S3_END); + GX_SET_REG(gx->IndTexScale1, scaleT, GX_BP_RAS1_SS1_T3_ST, GX_BP_RAS1_SS1_T3_END); + GX_SET_REG(gx->IndTexScale1, 0x26, 0, 7); + + GX_BP_LOAD_REG(gx->IndTexScale1); + break; + } + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8268 + * @note Size: 0xEC + */ +// modified from Open_RVL +void GXSetIndTexOrder(GXIndTexStageID stage, GXTexCoordID coord, GXTexMapID map) +{ + GXData* data; + if (map == GX_TEXMAP_NULL) { + map = GX_TEXMAP0; + } + + if (coord == GX_TEXCOORD_NULL) { + coord = GX_TEXCOORD0; + } + + switch (stage) { + case GX_IND_TEX_STAGE_0: + GX_SET_REG(gx->iref, map, GX_BP_RAS1_IREF_MAP0_ST, GX_BP_RAS1_IREF_MAP0_END); + GX_SET_REG(gx->iref, coord, GX_BP_RAS1_IREF_TXC0_ST, GX_BP_RAS1_IREF_TXC0_END); + break; + + case GX_IND_TEX_STAGE_1: + GX_SET_REG(gx->iref, map, GX_BP_RAS1_IREF_MAP1_ST, GX_BP_RAS1_IREF_MAP1_END); + GX_SET_REG(gx->iref, coord, GX_BP_RAS1_IREF_TXC1_ST, GX_BP_RAS1_IREF_TXC1_END); + break; + + case GX_IND_TEX_STAGE_2: + GX_SET_REG(gx->iref, map, GX_BP_RAS1_IREF_MAP2_ST, GX_BP_RAS1_IREF_MAP2_END); + GX_SET_REG(gx->iref, coord, GX_BP_RAS1_IREF_TXC2_ST, GX_BP_RAS1_IREF_TXC2_END); + break; + + case GX_IND_TEX_STAGE_3: + GX_SET_REG(gx->iref, map, GX_BP_RAS1_IREF_MAP3_ST, GX_BP_RAS1_IREF_MAP3_END); + GX_SET_REG(gx->iref, coord, GX_BP_RAS1_IREF_TXC3_ST, GX_BP_RAS1_IREF_TXC3_END); + break; + } + + GX_BP_LOAD_REG(gx->iref); + + gx->dirtyState |= (GX_DIRTY_SU_TEX | GX_DIRTY_BP_MASK); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8354 + * @note Size: 0x24 + */ +// modified from Open_RVL +void GXSetNumIndStages(u8 num) +{ + GX_SET_REG(gx->genMode, num, GX_BP_GENMODE_NUMINDSTAGES_ST, GX_BP_GENMODE_NUMINDSTAGES_END); + gx->dirtyState |= (GX_DIRTY_BP_MASK | GX_DIRTY_GEN_MODE); +} + +/** + * @note Address: 0x800E8378 + * @note Size: 0x48 + */ +// modified from Open_RVL +void GXSetTevDirect(GXTevStageID stage) +{ + GXSetTevIndirect(stage, GX_IND_TEX_STAGE_0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, FALSE, FALSE, GX_ITBA_OFF); +} + +/** + * @note Address: 0x800E83C0 + * @note Size: 0x64 + */ +void GXSetTevIndWarp(GXTevStageID stage, GXIndTexStageID indStage, GXBool doSignedBias, GXBool doWrap, GXIndTexMtxID mtxID) +{ + GXIndTexWrap wrapVal = ((doWrap) ? GX_ITW_0 : GX_ITW_OFF); + + GXSetTevIndirect(stage, indStage, GX_ITF_8, ((doSignedBias) ? GX_ITB_STU : GX_ITB_NONE), mtxID, wrapVal, wrapVal, FALSE, FALSE, + GX_ITBA_OFF); +} + +/** + * @note Address: 0x800E8424 + * @note Size: 0x4 + */ +void __GXUpdateBPMask() { } + +/** + * @note Address: 0x800E8428 + * @note Size: 0x30 + */ +// modified from Open_RVL +void __GXSetIndirectMask(u32 mask) +{ + GX_SET_REG(gx->bpMask, mask, GX_BP_INDIMASK_ST, GX_BP_INDIMASK_END); + GX_BP_LOAD_REG(gx->bpMask); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8458 + * @note Size: 0x24 + */ +void __GXFlushTextureState() +{ + GX_BP_LOAD_REG(gx->bpMask); + gx->bpSentNot = GX_FALSE; +} diff --git a/dolphin sdk not yet linked/src/gx/GXDisplayList.c b/dolphin sdk not yet linked/src/gx/GXDisplayList.c new file mode 100644 index 0000000..832ed35 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXDisplayList.c @@ -0,0 +1,18 @@ +#include "Dolphin/gx.h" + +/** + * @note Address: 0x800E93D8 + * @note Size: 0x70 + */ +void GXCallDisplayList(void* dl, u32 byteCnt) +{ + if (gx->dirtyState) { + __GXSetDirtyState(); + } + if (GX_CHECK_FLUSH()) { + __GXSendFlushPrim(); + } + GX_WRITE_U8(GX_FIFO_CMD_CALL_DL); + GX_WRITE_U32((u32)dl); + GX_WRITE_U32(byteCnt); +} diff --git a/dolphin sdk not yet linked/src/gx/GXFifo.c b/dolphin sdk not yet linked/src/gx/GXFifo.c new file mode 100644 index 0000000..232b6cd --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXFifo.c @@ -0,0 +1,550 @@ +#include "Dolphin/gx.h" +#include "Dolphin/os.h" + +static GXFifoObj* CPUFifo; +static GXFifoObj* GPFifo; +static OSThread* __GXCurrentThread; +static u8 CPGPLinked; +static BOOL GXOverflowSuspendInProgress; +static GXBreakPtCallback BreakPointCB; +static u32 __GXOverflowCount; +static u32 __GXCurrentBP; // unused and removed + +/** + * @note Address: N/A + * @note Size: 0x50 + */ +void GXOverflowHandler() +{ + __GXOverflowCount += 1; + __GXWriteFifoIntEnable(0, 1); + __GXWriteFifoIntReset(1, 0); + GXOverflowSuspendInProgress = TRUE; + OSSuspendThread(__GXCurrentThread); +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void GXUnderflowHandler() +{ + OSResumeThread(__GXCurrentThread); + GXOverflowSuspendInProgress = FALSE; + __GXWriteFifoIntReset(1, 1); + __GXWriteFifoIntEnable(1, 0); +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +void GXBreakPointHandler(OSContext* context) +{ + OSContext bpContext; + GX_SET_REG(gx->cpEnable, 0, 26, 26); + GX_SET_CP_REG(1, gx->cpEnable); + + if (BreakPointCB) { + OSClearContext(&bpContext); + OSSetCurrentContext(&bpContext); + BreakPointCB(); + OSClearContext(&bpContext); + OSSetCurrentContext(context); + } +} + +/** + * @note Address: 0x800E3A00 + * @note Size: 0x134 + */ +void GXCPInterruptHandler(s16 p1, OSContext* context) +{ + + gx->cpStatus = GX_GET_CP_REG(0); + + if ((gx->cpEnable >> 3 & 1) && (gx->cpStatus >> 1 & 1)) { + GXUnderflowHandler(); + } + + if ((gx->cpEnable >> 2 & 1) && (gx->cpStatus >> 0 & 1)) { + GXOverflowHandler(); + } + + if ((gx->cpEnable >> 5 & 1) && (gx->cpStatus >> 4 & 1)) { + GXBreakPointHandler(context); + } +} + +/** + * @note Address: 0x800E3B34 + * @note Size: 0x6C + */ +void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size) +{ + GXFifoObjPriv* pFifo = (GXFifoObjPriv*)fifo; + pFifo->base = base; + pFifo->end = (void*)((u32)base + size - 4); + pFifo->size = size; + pFifo->rwDistance = 0; + GXInitFifoLimits(fifo, size - 0x4000, OSRoundDown32B(size / 2)); + GXInitFifoPtrs(fifo, base, base); +} + +/** + * @note Address: 0x800E3BA0 + * @note Size: 0x70 + */ +void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr) +{ + GXFifoObjPriv* pFifo = (GXFifoObjPriv*)fifo; + int interrupts = OSDisableInterrupts(); + pFifo->readPtr = readPtr; + pFifo->writePtr = writePtr; + pFifo->rwDistance = (u32)writePtr - (u32)readPtr; + if (pFifo->rwDistance < 0) { + pFifo->rwDistance += pFifo->size; + } + OSRestoreInterrupts(interrupts); +} + +/** + * @note Address: 0x800E3C10 + * @note Size: 0xC + */ +void GXInitFifoLimits(GXFifoObj* fifo, u32 highWatermark, u32 lowWatermark) +{ + GXFifoObjPriv* pFifo = (GXFifoObjPriv*)fifo; + pFifo->highWatermark = highWatermark; + pFifo->lowWatermark = lowWatermark; +} + +/** + * @note Address: 0x800E3C1C + * @note Size: 0x128 + */ +void GXSetCPUFifo(GXFifoObj* fifo) +{ + BOOL interrupts; + interrupts = OSDisableInterrupts(); + + CPUFifo = fifo; + + if (fifo == GPFifo) { + u32 reg; + GX_SET_PI_REG(3, (u32)((GXFifoObjPriv*)fifo)->base & 0x3FFFFFFF); + GX_SET_PI_REG(4, (u32)((GXFifoObjPriv*)fifo)->end & 0x3FFFFFFF); + reg = 0; + GX_SET_REG(reg, (u32)((GXFifoObjPriv*)fifo)->writePtr >> 5, 6, 26); + GX_SET_REG(reg, 0, 5, 5); + 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); + + GX_SET_PI_REG(3, (u32)((GXFifoObjPriv*)fifo)->base & 0x3FFFFFFF); + GX_SET_PI_REG(4, (u32)((GXFifoObjPriv*)fifo)->end & 0x3FFFFFFF); + reg = 0; + GX_SET_REG(reg, (u32)((GXFifoObjPriv*)fifo)->writePtr >> 5, 6, 26); + GX_SET_REG(reg, 0, 5, 5); + GX_SET_PI_REG(5, reg); + } + + PPCSync(); + + OSRestoreInterrupts(interrupts); +} + +/** + * @note Address: 0x800E3D44 + * @note Size: 0x178 + */ +void GXSetGPFifo(GXFifoObj* fifo) +{ + GXFifoObjPriv* pFifo = (GXFifoObjPriv*)fifo; + int interrupts = OSDisableInterrupts(); + __GXFifoReadDisable(); + __GXWriteFifoIntEnable(0, 0); + GPFifo = fifo; + GX_SET_CP_REG(16, (u16)pFifo->base); + GX_SET_CP_REG(18, (u16)pFifo->end); + GX_SET_CP_REG(24, (u16)pFifo->rwDistance); + GX_SET_CP_REG(26, (u16)pFifo->writePtr); + GX_SET_CP_REG(28, (u16)pFifo->readPtr); + GX_SET_CP_REG(20, (u16)pFifo->highWatermark); + GX_SET_CP_REG(22, (u16)pFifo->lowWatermark); + + GX_SET_CP_REG(17, ((u32)pFifo->base & 0x3FFFFFFF) >> 16); + GX_SET_CP_REG(19, ((u32)pFifo->end & 0x3FFFFFFF) >> 16); + GX_SET_CP_REG(25, (pFifo->rwDistance) >> 16); + GX_SET_CP_REG(27, ((u32)pFifo->writePtr & 0x3FFFFFFF) >> 16); + GX_SET_CP_REG(29, ((u32)pFifo->readPtr & 0x3FFFFFFF) >> 16); + GX_SET_CP_REG(21, (pFifo->highWatermark) >> 16); + GX_SET_CP_REG(23, (pFifo->lowWatermark) >> 16); + + PPCSync(); + + if (CPUFifo == GPFifo) { + CPGPLinked = 1; + __GXWriteFifoIntEnable(1, 0); + __GXFifoLink(1); + } else { + CPGPLinked = 0; + __GXWriteFifoIntEnable(0, 0); + __GXFifoLink(0); + } + __GXWriteFifoIntReset(1, 1); + __GXFifoReadEnable(); + OSRestoreInterrupts(interrupts); +} + +/** + * @note Address: 0x800E3EBC + * @note Size: 0x34 + */ +void GXSaveCPUFifo(GXFifoObj* fifo) +{ + GXFlush(); + __GXSaveCPUFifoAux(fifo); +} + +/** + * @note Address: 0x800E3EF0 + * @note Size: 0xC8 + */ +void __GXSaveCPUFifoAux(GXFifoObj* fifo) +{ + GXFifoObjPriv* pFifo = (GXFifoObjPriv*)fifo; + int interrupts = OSDisableInterrupts(); + pFifo->base = OSPhysicalToCached(GX_GET_PI_REG(3)); + pFifo->end = OSPhysicalToCached(GX_GET_PI_REG(4)); + pFifo->writePtr = OSPhysicalToCached(GX_GET_PI_REG(5) & ~0x4000000); + if (CPGPLinked != 0) { + u32 reg = GX_GET_CP_REG(29) << 16; + u32 reg2 = GX_GET_CP_REG(28) | reg; + pFifo->readPtr = (void*)(reg2 + -0x80000000); + reg = GX_GET_CP_REG(25) << 16; + pFifo->rwDistance = (((u32)GX_GET_CP_REG(24) | reg)); + + } else { + pFifo->rwDistance = (u32)pFifo->writePtr - (u32)pFifo->readPtr; + if (pFifo->rwDistance < 0) { + pFifo->rwDistance += pFifo->size; + } + } + OSRestoreInterrupts(interrupts); +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +void GXSaveGPFifo(GXFifoObj* fifo) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E3FB8 + * @note Size: 0x50 + */ +void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, GXBool* brkpt) +{ + gx->cpStatus = GX_GET_CP_REG(0); + *overhi = gx->cpStatus & 1; + *underlow = (gx->cpStatus >> 1) & 1; + *readIdle = (gx->cpStatus >> 2) & 1; + *cmdIdle = (gx->cpStatus >> 3) & 1; + *brkpt = (gx->cpStatus >> 4) & 1; +} + +/** + * @note Address: N/A + * @note Size: 0x114 + */ +void GXGetFifoStatus(GXFifoObj* obj, GXBool* isOverHi, GXBool* isUnderLo, u32* fifoCount, GXBool* isCpuWrite, GXBool* isGPRead, + GXBool* isFifoWrap) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +void GXGetFifoPtrs(GXFifoObj* obj, void** readPtr, void** writePtr) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void* GXGetFifoBase(GXFifoObj* obj) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +u32 GXGetFifoSize(GXFifoObj* obj) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x14 + */ +void GXGetFifoLimits(GXFifoObj* obj, u32* hi, u32* lo) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E4008 + * @note Size: 0x44 + */ +GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb) +{ + GXBreakPtCallback oldCallback = BreakPointCB; + int interrupts = OSDisableInterrupts(); + BreakPointCB = cb; + OSRestoreInterrupts(interrupts); + return oldCallback; +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void GXEnableBreakPt(void* breakPtr) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +void GXDisableBreakPt(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E404C + * @note Size: 0x4C + */ +void __GXFifoInit(void) +{ + __OSSetInterruptHandler(0x11, GXCPInterruptHandler); + __OSUnmaskInterrupts(0x4000); + __GXCurrentThread = OSGetCurrentThread(); + GXOverflowSuspendInProgress = 0; + CPUFifo = nullptr; + GPFifo = nullptr; +} + +/** + * @note Address: 0x800E4098 + * @note Size: 0x24 + */ +void __GXFifoReadEnable(void) +{ + GX_SET_REG(gx->cpEnable, GX_TRUE, 31, 31); + GX_SET_CP_REG(1, gx->cpEnable); +} + +/** + * @note Address: 0x800E40BC + * @note Size: 0x24 + */ +void __GXFifoReadDisable(void) +{ + GX_SET_REG(gx->cpEnable, GX_FALSE, 31, 31); + GX_SET_CP_REG(1, gx->cpEnable); +} + +/** + * @note Address: 0x800E40E0 + * @note Size: 0x34 + */ +void __GXFifoLink(u8 link) +{ + u32 b; + if (link) { + b = 1; + } else { + b = 0; + } + GX_SET_REG(gx->cpEnable, b, 27, 27); + GX_SET_CP_REG(1, gx->cpEnable); +} + +/** + * @note Address: 0x800E4114 + * @note Size: 0x30 + */ +void __GXWriteFifoIntEnable(u32 p1, u32 p2) +{ + GX_SET_REG(gx->cpEnable, p1, 29, 29); + GX_SET_REG(gx->cpEnable, (u8)p2, 28, 28); + GX_SET_CP_REG(1, gx->cpEnable); +} + +/** + * @note Address: 0x800E4144 + * @note Size: 0x30 + */ +void __GXWriteFifoIntReset(u32 p1, u32 p2) +{ + GX_SET_REG(gx->cpClr, p1, 31, 31); + GX_SET_REG(gx->cpClr, (u8)p2, 30, 30); + GX_SET_CP_REG(2, gx->cpClr); +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +void __GXInsaneWatermark(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E4174 + * @note Size: 0x100 + */ +void __GXCleanGPFifo(void) +{ + BOOL interrupts; + GXFifoObjPriv tempObj; // 0x14 + u32 i, j, k; // stack alloc + GXFifoObjPriv* gpFifo; // r31 + GXFifoObjPriv* cpuFifo; // r30 + void* tempPtr; // r29 + + gpFifo = (GXFifoObjPriv*)GXGetGPFifo(); + if (!gpFifo) { + return; + } + + cpuFifo = (GXFifoObjPriv*)GXGetCPUFifo(); + tempPtr = gpFifo->base; + + tempObj = *gpFifo; + + interrupts = OSDisableInterrupts(); + + tempObj.readPtr = tempPtr; + tempObj.writePtr = tempPtr; + tempObj.rwDistance = 0; + if (tempObj.rwDistance < 0) { + tempObj.rwDistance += tempObj.size; + } + + OSRestoreInterrupts(interrupts); + + GXSetGPFifo((GXFifoObj*)&tempObj); + + if (cpuFifo == gpFifo) { + GXSetCPUFifo((GXFifoObj*)&tempObj); + } + + interrupts = OSDisableInterrupts(); + + gpFifo->readPtr = tempPtr; + gpFifo->writePtr = tempPtr; + gpFifo->rwDistance = 0; + + if (gpFifo->rwDistance < 0) { + gpFifo->rwDistance += gpFifo->size; + } + OSRestoreInterrupts(interrupts); + + GXSetGPFifo((GXFifoObj*)gpFifo); + if (cpuFifo == gpFifo) { + GXSetCPUFifo((GXFifoObj*)cpuFifo); + } +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void GXSetCurrentGXThread(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void GXGetCurrentGXThread(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E4274 + * @note Size: 0x8 + */ +GXFifoObj* GXGetCPUFifo(void) { return CPUFifo; } + +/** + * @note Address: 0x800E427C + * @note Size: 0x8 + */ +GXFifoObj* GXGetGPFifo(void) { return GPFifo; } + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void GXGetOverflowCount(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void GXResetOverflowCount(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x108 + */ +void GXRedirectWriteGatherPipe(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1A0 + */ +void GXRestoreWriteGatherPipe(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/gx/GXFrameBuf.c b/dolphin sdk not yet linked/src/gx/GXFrameBuf.c new file mode 100644 index 0000000..ca3169e --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXFrameBuf.c @@ -0,0 +1,529 @@ +#include "Dolphin/gx.h" + +// clang-format off +GXRenderModeObj GXNtsc480IntDf = { + VI_TVMODE_NTSC_INT, 640, 480, 480, 40, 0, 640, 480, VI_XFBMODE_DF, GX_FALSE, GX_FALSE, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 8, 8, 10, 12, 10, 8, 8, +}; + +GXRenderModeObj GXNtsc480Int = { + VI_TVMODE_NTSC_INT, 640, 480, 480, 40, 0, 640, 480, VI_XFBMODE_DF, GX_FALSE, GX_FALSE, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 0, 0, 21, 22, 21, 0, 0, +}; + +GXRenderModeObj GXMpal480IntDf = { + VI_TVMODE_MPAL_INT, 640, 480, 480, 40, 0, 640, 480, VI_XFBMODE_DF, GX_FALSE, GX_FALSE, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 8, 8, 10, 12, 10, 8, 8, +}; + +GXRenderModeObj GXPal528IntDf = { + VI_TVMODE_PAL_INT, 640, 528, 528, 40, 23, 640, 528, VI_XFBMODE_DF, GX_FALSE, GX_FALSE, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 8, 8, 10, 12, 10, 8, 8, +}; + +GXRenderModeObj GXEurgb60Hz480IntDf = { + VI_TVMODE_EURGB60_INT, 640, 480, 480, 40, 0, 640, 480, VI_XFBMODE_DF, GX_FALSE, GX_FALSE, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 8, 8, 10, 12, 10, 8, 8, +}; +// clang-format on + +/** + * @note Address: N/A + * @note Size: 0x144 + */ +void GXAdjustForOverscan(GXRenderModeObj* rIn, GXRenderModeObj* rOut, u16 horiz, u16 vert) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E5C44 + * @note Size: 0x7C + */ +void GXSetDispCopySrc(u16 left, u16 top, u16 width, u16 height) +{ + gx->cpDispSrc = 0; + GX_SET_REG(gx->cpDispSrc, left, 22, 31); + GX_SET_REG(gx->cpDispSrc, top, 12, 21); + GX_SET_REG(gx->cpDispSrc, 0x49, 0, 7); + + gx->cpDispSize = 0; + GX_SET_REG(gx->cpDispSize, width - 1, 22, 31); + GX_SET_REG(gx->cpDispSize, height - 1, 12, 21); + GX_SET_REG(gx->cpDispSize, 0x4A, 0, 7); +} + +/** + * @note Address: 0x800E5CC0 + * @note Size: 0x7C + */ +void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height) +{ + gx->cpTexSrc = 0; + GX_SET_REG(gx->cpTexSrc, left, 22, 31); + GX_SET_REG(gx->cpTexSrc, top, 12, 21); + GX_SET_REG(gx->cpTexSrc, 0x49, 0, 7); + + gx->cpTexSize = 0; + GX_SET_REG(gx->cpTexSize, width - 1, 22, 31); + GX_SET_REG(gx->cpTexSize, height - 1, 12, 21); + GX_SET_REG(gx->cpTexSize, 0x4A, 0, 7); +} + +/** + * @note Address: 0x800E5D3C + * @note Size: 0x34 + */ +void GXSetDispCopyDst(u16 width, u16 height) +{ + u16 stride = width * 2; + gx->cpDispStride = 0; + GX_SET_REG(gx->cpDispStride, stride >> 5, 22, 31); + GX_SET_REG(gx->cpDispStride, 0x4D, 0, 7); +} + +/** + * @note Address: 0x800E5D70 + * @note Size: 0x130 + */ +void GXSetTexCopyDst(u16 width, u16 height, GXTexFmt format, GXBool useMIPmap) +{ + u32 sp20, sp1C, sp18; + u32 value; + u8 depthRelated; + + gx->cpTexZ = GX_NONE; + + depthRelated = format & 0xf; + if (format == GX_TF_Z16) { + depthRelated = 0xb; + } + + switch (format) { + case GX_TF_I4: + case GX_TF_I8: + case GX_TF_IA4: + case GX_TF_IA8: + case GX_CTF_A8: + GX_SET_REG(gx->cpTex, 3, 15, 16); + break; + default: + GX_SET_REG(gx->cpTex, 2, 15, 16); + break; + } + + gx->cpTexZ = (format & 0x10) == 0x10; + + value = depthRelated >> 3; + + GX_SET_REG(gx->cpTex, value, 28, 28); + + depthRelated &= 7; + + __GetImageTileCount(format, width, height, &sp20, &sp1C, &sp18); + + gx->cpTexStride = GX_NONE; + GX_SET_REG(gx->cpTexStride, sp20 * sp18, 22, 31); + GX_SET_REG(gx->cpTexStride, 0x4D, 0, 7); + + GX_SET_REG(gx->cpTex, useMIPmap, 22, 22); + GX_SET_REG(gx->cpTex, depthRelated, 25, 27); +} + +/** + * @note Address: 0x800E5EA0 + * @note Size: 0x24 + */ +void GXSetDispCopyFrame2Field(GXCopyMode mode) +{ + GX_SET_REG(gx->cpDisp, mode, 18, 19); + GX_SET_REG(gx->cpTex, 0, 18, 19); +} + +/** + * @note Address: 0x800E5EC4 + * @note Size: 0x58 + */ +void GXSetCopyClamp(GXFBClamp clamp) +{ + GXBool clamp1 = ((clamp & 1) == 1); + GXBool clamp2 = ((clamp & 2) == 2); + GX_SET_REG(gx->cpDisp, clamp1, 31, 31); + GX_SET_REG(gx->cpDisp, clamp2, 30, 30); + GX_SET_REG(gx->cpTex, clamp1, 31, 31); + GX_SET_REG(gx->cpTex, clamp2, 30, 30); +} + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +static u32 __GXGetNumXfbLines(u32 height, u32 scale) +{ + u32 numLines; + u32 actualHeight; + u32 newScale; + + numLines = (height - 1) * 0x100; + actualHeight = (numLines / scale) + 1; + + newScale = scale; + + if (newScale > 0x80 && newScale < 0x100) { + while (newScale % 2 == 0) { + newScale /= 2; + } + + if (height % newScale == 0) { + actualHeight++; + } + } + + if (actualHeight > 0x400) { + actualHeight = 0x400; + } + + return actualHeight; +} + +/** + * @note Address: 0x800E5F1C + * @note Size: 0x90 + */ +u16 GXGetNumXfbLines(const u16 efbHeight, f32 yScale) +{ + u32 scale = (u32)(256.0f / yScale) & 0x1FF; + + return __GXGetNumXfbLines(efbHeight, scale); +} + +/** + * @note Address: 0x800E5FAC + * @note Size: 0x238 + */ +f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight) +{ + u32 scale; + u32 height1; + u32 height2; + f32 scale2; + f32 scale1; + + height1 = xfbHeight; + scale1 = (f32)xfbHeight / (f32)efbHeight; + scale = (u32)(256.0f / scale1) & 0x1FF; + height2 = __GXGetNumXfbLines(efbHeight, scale); + + while (height2 > xfbHeight) { + height1--; + scale1 = (f32)height1 / (f32)efbHeight; + scale = (u32)(256.0f / scale1) & 0x1FF; + height2 = __GXGetNumXfbLines(efbHeight, scale); + } + + scale2 = scale1; + while (height2 < xfbHeight) { + scale2 = scale1; + height1++; + scale1 = (f32)height1 / (f32)efbHeight; + scale = (u32)(256.0f / scale1) & 0x1FF; + height2 = __GXGetNumXfbLines(efbHeight, scale); + } + + return scale2; +} + +/** + * @note Address: 0x800E61E4 + * @note Size: 0xCC + */ +u32 GXSetDispCopyYScale(f32 vertScale) +{ + u32 scale; + GXBool check; + u32 height; + u32 reg; + + scale = (u32)(256.0f / vertScale) & 0x1FF; + check = (scale != 0x100); + + reg = 0; + GX_SET_REG(reg, scale, 23, 31); + GX_SET_REG(reg, 0x4E, 0, 7); + GX_BP_LOAD_REG(reg); + gx->bpSentNot = GX_FALSE; + + GX_SET_REG(gx->cpDisp, check, 21, 21); + + height = (gx->cpDispSize >> 10 & 0x3FF) + 1; + + return __GXGetNumXfbLines(height, scale); +} + +/** + * @note Address: 0x800E62B0 + * @note Size: 0x78 + */ +void GXSetCopyClear(GXColor clearColor, u32 clearZ) +{ + u32 reg = 0; + GX_SET_REG(reg, clearColor.r, 24, 31); + GX_SET_REG(reg, clearColor.a, 16, 23); + GX_SET_REG(reg, 0x4F, 0, 7); + GX_BP_LOAD_REG(reg); + + reg = 0; + GX_SET_REG(reg, clearColor.b, 24, 31); + GX_SET_REG(reg, clearColor.g, 16, 23); + GX_SET_REG(reg, 0x50, 0, 7); + GX_BP_LOAD_REG(reg); + + reg = 0; + GX_SET_REG(reg, clearZ, 8, 31); + GX_SET_REG(reg, 0x51, 0, 7); + GX_BP_LOAD_REG(reg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E6328 + * @note Size: 0x208 + */ +void GXSetCopyFilter(GXBool useAA, u8 samplePattern[12][2], GXBool doVertFilt, u8 vFilt[7]) +{ + u32 vals[4]; + u32 unk1; + u32 unk2; + + if (useAA) { + vals[0] = 0; + GX_SET_REG(vals[0], samplePattern[0][0], 28, 31); + GX_SET_REG(vals[0], samplePattern[0][1], 24, 27); + GX_SET_REG(vals[0], samplePattern[1][0], 20, 23); + GX_SET_REG(vals[0], samplePattern[1][1], 16, 19); + GX_SET_REG(vals[0], samplePattern[2][0], 12, 15); + GX_SET_REG(vals[0], samplePattern[2][1], 8, 11); + GX_SET_REG(vals[0], 1, 0, 7); + + vals[1] = 0; + GX_SET_REG(vals[1], samplePattern[3][0], 28, 31); + GX_SET_REG(vals[1], samplePattern[3][1], 24, 27); + GX_SET_REG(vals[1], samplePattern[4][0], 20, 23); + GX_SET_REG(vals[1], samplePattern[4][1], 16, 19); + GX_SET_REG(vals[1], samplePattern[5][0], 12, 15); + GX_SET_REG(vals[1], samplePattern[5][1], 8, 11); + GX_SET_REG(vals[1], 2, 0, 7); + + vals[2] = 0; + GX_SET_REG(vals[2], samplePattern[6][0], 28, 31); + GX_SET_REG(vals[2], samplePattern[6][1], 24, 27); + GX_SET_REG(vals[2], samplePattern[7][0], 20, 23); + GX_SET_REG(vals[2], samplePattern[7][1], 16, 19); + GX_SET_REG(vals[2], samplePattern[8][0], 12, 15); + GX_SET_REG(vals[2], samplePattern[8][1], 8, 11); + GX_SET_REG(vals[2], 3, 0, 7); + + vals[3] = 0; + GX_SET_REG(vals[3], samplePattern[9][0], 28, 31); + GX_SET_REG(vals[3], samplePattern[9][1], 24, 27); + GX_SET_REG(vals[3], samplePattern[10][0], 20, 23); + GX_SET_REG(vals[3], samplePattern[10][1], 16, 19); + GX_SET_REG(vals[3], samplePattern[11][0], 12, 15); + GX_SET_REG(vals[3], samplePattern[11][1], 8, 11); + GX_SET_REG(vals[3], 4, 0, 7); + } else { + vals[0] = 0x01666666; + vals[1] = 0x02666666; + vals[2] = 0x03666666; + vals[3] = 0x04666666; + } + + GX_BP_LOAD_REG(vals[0]); + GX_BP_LOAD_REG(vals[1]); + GX_BP_LOAD_REG(vals[2]); + GX_BP_LOAD_REG(vals[3]); + + unk1 = 0; + GX_SET_REG(unk1, 0x53, 0, 7); + unk2 = 0; + GX_SET_REG(unk2, 0x54, 0, 7); + + if (doVertFilt) { + GX_SET_REG(unk1, vFilt[0], 26, 31); + GX_SET_REG(unk1, vFilt[1], 20, 25); + GX_SET_REG(unk1, vFilt[2], 14, 19); + GX_SET_REG(unk1, vFilt[3], 8, 13); + GX_SET_REG(unk2, vFilt[4], 26, 31); + GX_SET_REG(unk2, vFilt[5], 20, 25); + GX_SET_REG(unk2, vFilt[6], 14, 19); + + } else { + GX_SET_REG(unk1, 0, 26, 31); + GX_SET_REG(unk1, 0, 20, 25); + GX_SET_REG(unk1, 21, 14, 19); + GX_SET_REG(unk1, 22, 8, 13); + GX_SET_REG(unk2, 21, 26, 31); + GX_SET_REG(unk2, 0, 20, 25); + GX_SET_REG(unk2, 0, 14, 19); + } + + GX_BP_LOAD_REG(unk1); + GX_BP_LOAD_REG(unk2); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E6530 + * @note Size: 0x14 + */ +void GXSetDispCopyGamma(GXGamma gamma) { GX_SET_REG(gx->cpDisp, gamma, 23, 24); } + +/** + * @note Address: 0x800E6544 + * @note Size: 0x168 + */ +void GXCopyDisp(void* dest, GXBool doClear) +{ + u32 reg; + u32 newDest; + GXBool check; + + if (doClear) { + reg = gx->zmode; + GX_SET_REG(reg, 1, 31, 31); + GX_SET_REG(reg, 7, 28, 30); + GX_BP_LOAD_REG(reg); + + reg = gx->cmode0; + GX_SET_REG(reg, 0, 31, 31); + GX_SET_REG(reg, 0, 30, 30); + GX_BP_LOAD_REG(reg); + } + + check = GX_FALSE; + if ((doClear || (gx->peCtrl & 0x7) == 3) && (gx->peCtrl >> 6 & 0x1) == 1) { + check = GX_TRUE; + reg = gx->peCtrl; + GX_SET_REG(reg, 0, 25, 25); + GX_BP_LOAD_REG(reg); + } + + GX_BP_LOAD_REG(gx->cpDispSrc); + GX_BP_LOAD_REG(gx->cpDispSize); + GX_BP_LOAD_REG(gx->cpDispStride); + + newDest = (u32)dest & 0x3FFFFFFF; + reg = 0; + GX_SET_REG(reg, newDest >> 5, 11, 31); + GX_SET_REG(reg, 0x4B, 0, 7); + GX_BP_LOAD_REG(reg); + + GX_SET_REG(gx->cpDisp, doClear, 20, 20); + GX_SET_REG(gx->cpDisp, 1, 17, 17); + GX_SET_REG(gx->cpDisp, 0x52, 0, 7); + GX_BP_LOAD_REG(gx->cpDisp); + + if (doClear) { + GX_BP_LOAD_REG(gx->zmode); + GX_BP_LOAD_REG(gx->cmode0); + } + + if (check) { + GX_BP_LOAD_REG(gx->peCtrl); + } + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E66AC + * @note Size: 0x18C + */ +void GXCopyTex(void* dest, GXBool doClear) +{ + u32 reg; + u32 reg2; + u32 newDest; + GXBool check; + + if (doClear) { + reg = gx->zmode; + GX_SET_REG(reg, 1, 31, 31); + GX_SET_REG(reg, 7, 28, 30); + GX_BP_LOAD_REG(reg); + + reg = gx->cmode0; + GX_SET_REG(reg, 0, 31, 31); + GX_SET_REG(reg, 0, 30, 30); + GX_BP_LOAD_REG(reg); + } + + check = GX_FALSE; + reg2 = gx->peCtrl; + if (gx->cpTexZ && (reg2 & 0x7) != 3) { + check = GX_TRUE; + GX_SET_REG(reg2, 3, 29, 31); + } + + if ((doClear || (reg2 & 0x7) == 3) && (reg2 >> 6 & 0x1) == 1) { + check = GX_TRUE; + GX_SET_REG(reg2, 0, 25, 25); + } + + if (check) { + GX_BP_LOAD_REG(reg2); + } + + GX_BP_LOAD_REG(gx->cpTexSrc); + GX_BP_LOAD_REG(gx->cpTexSize); + GX_BP_LOAD_REG(gx->cpTexStride); + + newDest = (u32)dest & 0x3FFFFFFF; + reg = 0; + GX_SET_REG(reg, newDest >> 5, 11, 31); + GX_SET_REG(reg, 0x4B, 0, 7); + GX_BP_LOAD_REG(reg); + + GX_SET_REG(gx->cpTex, doClear, 20, 20); + GX_SET_REG(gx->cpTex, 0, 17, 17); + GX_SET_REG(gx->cpTex, 0x52, 0, 7); + GX_BP_LOAD_REG(gx->cpTex); + + if (doClear) { + GX_BP_LOAD_REG(gx->zmode); + GX_BP_LOAD_REG(gx->cmode0); + } + + if (check) { + GX_BP_LOAD_REG(gx->peCtrl); + } + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E6838 + * @note Size: 0x38 + */ +void GXClearBoundingBox(void) +{ + GX_BP_LOAD_REG(0x550003FF); + GX_BP_LOAD_REG(0x560003FF); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void GXReadBoundingBox(u16* left, u16* top, u16* right, u16* bottom) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/gx/GXGeometry.c b/dolphin sdk not yet linked/src/gx/GXGeometry.c new file mode 100644 index 0000000..2f3ed5d --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXGeometry.c @@ -0,0 +1,155 @@ +#include "Dolphin/gx.h" + +/** + * @note Address: 0x800E5908 + * @note Size: 0x80 + */ +void __GXSetDirtyState(void) +{ + u32 dirtyFlags = gx->dirtyState; + + if (dirtyFlags & 1) { + __GXSetSUTexRegs(); + } + + if (dirtyFlags & 2) { + __GXUpdateBPMask(); + } + + if (dirtyFlags & 4) { + __GXSetGenMode(); + } + + if (dirtyFlags & 8) { + __GXSetVCD(); + } + + if (dirtyFlags & 0x10) { + __GXSetVAT(); + } + + if (dirtyFlags & 0x18) { + __GXCalculateVLim(); + } + + gx->dirtyState = 0; +} + +/** + * @note Address: 0x800E5988 + * @note Size: 0xD0 + */ +void GXBegin(GXPrimitive type, GXVtxFmt fmt, u16 vert_num) +{ + if (gx->dirtyState) { + __GXSetDirtyState(); + } + + if (GX_CHECK_FLUSH()) { + __GXSendFlushPrim(); + } + + GX_WRITE_U8(fmt | type); + GX_WRITE_U16(vert_num); +} + +/** + * @note Address: 0x800E5A58 + * @note Size: 0x88 + */ +void __GXSendFlushPrim(void) +{ + u32 i; + u32 sz = (gx->vNum * gx->vLim); + + GX_WRITE_U8(0x98); + GX_WRITE_U16(gx->vNum); + + for (i = 0; i < sz; i += 4) { + GX_WRITE_U32(0); + } + + gx->bpSentNot = GX_TRUE; +} + +/** + * @note Address: 0x800E5AE0 + * @note Size: 0x40 + */ +void GXSetLineWidth(u8 width, GXTexOffset offsets) +{ + GX_SET_REG(gx->lpSize, width, 24, 31); + GX_SET_REG(gx->lpSize, offsets, 13, 15); + + GX_BP_LOAD_REG(gx->lpSize); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E5B20 + * @note Size: 0x40 + */ +void GXSetPointSize(u8 size, GXTexOffset offsets) +{ + GX_SET_REG(gx->lpSize, size, 16, 23); + GX_SET_REG(gx->lpSize, offsets, 10, 12); + + GX_BP_LOAD_REG(gx->lpSize); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E5B60 + * @note Size: 0x48 + */ +void GXEnableTexOffsets(GXTexCoordID coord, GXBool line, GXBool point) +{ + GX_SET_REG(gx->suTs0[coord], line, 13, 13); + GX_SET_REG(gx->suTs0[coord], point, 12, 12); + + GX_BP_LOAD_REG(gx->suTs0[coord]); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E5BA8 + * @note Size: 0x44 + */ +void GXSetCullMode(GXCullMode mode) +{ + switch (mode) { + case GX_CULL_FRONT: + mode = GX_CULL_BACK; + break; + case GX_CULL_BACK: + mode = GX_CULL_FRONT; + break; + } + + GX_SET_REG(gx->genMode, mode, 16, 17); + gx->dirtyState |= 4; +} + +/** + * @note Address: 0x800E5BEC + * @note Size: 0x34 + */ +void GXSetCoPlanar(GXBool enable) +{ + GX_SET_REG(gx->genMode, enable, 12, 12); + GX_BP_LOAD_REG(0xFE080000); + GX_BP_LOAD_REG(gx->genMode); +} + +/** + * @note Address: 0x800E5C20 + * @note Size: 0x24 + */ +void __GXSetGenMode(void) +{ + GX_BP_LOAD_REG(gx->genMode); + gx->bpSentNot = GX_FALSE; +} diff --git a/dolphin sdk not yet linked/src/gx/GXInit.c b/dolphin sdk not yet linked/src/gx/GXInit.c new file mode 100644 index 0000000..56ac219 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXInit.c @@ -0,0 +1,590 @@ +#include "Dolphin/gx.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +static GXFifoObj FifoObj; +static GXData gxData; +GXData* const __GXData = &gxData; + +char* __GXVersion = "<< Dolphin SDK - GX\trelease build: Nov 26 2003 05:19:07 (0x2301) >>"; + +void* __piReg = nullptr; +void* __cpReg = nullptr; +void* __peReg = nullptr; +void* __memReg = nullptr; + +static u16 DefaultTexData[] ATTRIBUTE_ALIGN(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, GX_COMPCNT_NULL, GX_COMP_NULL, 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, +}; + +// forward declaring static reset function +static BOOL __GXShutdown(BOOL); + +static OSResetFunctionInfo GXResetFuncInfo = { __GXShutdown, OS_RESET_PRIO_GX }; + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +ASM BOOL IsWriteGatherBufferEmpty(void) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + sync; + + mfspr r3, WPAR; + andi. r3, r3, 1; + blr; +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x40 + */ +static void EnableWriteGatherPipe() +{ + u32 hid2; // r31 + hid2 = PPCMfhid2(); + PPCMtwpar(OSUncachedToPhysical((void*)GXFIFO_ADDR)); + hid2 |= 0x40000000; + PPCMthid2(hid2); +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +static void DisableWriteGatherPipe() +{ + u32 hid2; + hid2 = PPCMfhid2(); + hid2 &= ~0x40000000; + PPCMthid2(hid2); +} + +/** + * @note Address: 0x800E2680 + * @note Size: 0xFC + */ +static GXTexRegion* __GXDefaultTexRegionCallback(const GXTexObj* obj, GXTexMapID id) +{ + GXTexFmt format; // r31 + GXBool isMipMap; // r3 + + format = GXGetTexObjFmt(obj); + isMipMap = GXGetTexObjMipMap(obj); + id = (GXTexMapID)(id % GX_MAX_TEXMAP); + + switch (format) { + case GX_TF_RGBA8: + if (isMipMap) { + return &gx->TexRegions2[id]; + } + return &gx->TexRegions1[id]; + + case GX_TF_C4: + case GX_TF_C8: + case GX_TF_C14X2: + return &gx->TexRegions0[id]; + + default: + if (isMipMap) { + return &gx->TexRegions1[id]; + } + return &gx->TexRegions0[id]; + } +} + +/** + * @note Address: 0x800E277C + * @note Size: 0x24 + */ +static GXTlutRegion* __GXDefaultTlutRegionCallback(u32 tlut) +{ + if (tlut >= GX_MAX_TLUT_ALL) { + return nullptr; + } + + return &gx->TlutRegions[tlut]; +} + +/** + * @note Address: 0x800E27A0 + * @note Size: 0x190 + */ +BOOL __GXShutdown(BOOL final) +{ + static u32 peCount; + static OSTime time; + static u32 calledOnce = 0; + + u32 val; + u32 newPeCount; + OSTime newTime; + + if (!final) { + if (!calledOnce) { + peCount = GXReadMEMReg(0x28, 0x27); + time = OSGetTime(); + calledOnce = 1; + return FALSE; + } + + newTime = OSGetTime(); + newPeCount = GXReadMEMReg(0x28, 0x27); + + if (newTime - time < 10) { + return FALSE; + } + + if (newPeCount != peCount) { + peCount = newPeCount; + time = newTime; + return FALSE; + } + + } else { + GXSetBreakPtCallback(nullptr); + GXSetDrawSyncCallback(nullptr); + GXSetDrawDoneCallback(nullptr); + + 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(); + + GX_SET_CP_REG(1, 0); + GX_SET_CP_REG(2, 3); + + gx->abtWaitPECopy = GX_TRUE; + + __GXAbort(); + } + + return TRUE; +} + +/** + * @note Address: 0x800E2930 + * @note Size: 0x798 + */ +GXFifoObj* GXInit(void* base, u32 size) +{ + static u32 resetFuncRegistered = 0; + u32 i; + u32 pad; // for stack matching + u32 pad2; // for stack matching + + OSRegisterVersion(__GXVersion); + gx->inDispList = GX_FALSE; + gx->dlSaveContext = GX_TRUE; + gx->abtWaitPECopy = GX_TRUE; + + gx->tcsManEnab = 0; + gx->tevTcEnab = 0; + + GXSetMisc(GX_MT_XF_FLUSH, 0); + + __piReg = (void*)OSPhysicalToUncached(GX_PI_ADDR); + __cpReg = (void*)OSPhysicalToUncached(GX_CP_ADDR); + __peReg = (void*)OSPhysicalToUncached(GX_PE_ADDR); + __memReg = (void*)OSPhysicalToUncached(GX_MEM_ADDR); + + __GXFifoInit(); + + GXInitFifoBase(&FifoObj, base, size); + GXSetCPUFifo(&FifoObj); + GXSetGPFifo(&FifoObj); + + if (!resetFuncRegistered) { + OSRegisterResetFunction(&GXResetFuncInfo); + resetFuncRegistered = 1; + } + + __GXPEInit(); + EnableWriteGatherPipe(); + + gx->genMode = 0; + GX_SET_REG(gx->genMode, 0, 0, 7); + + gx->bpMask = 255; + GX_SET_REG(gx->bpMask, 0xF, 0, 7); + + gx->lpSize = 0; + GX_SET_REG(gx->lpSize, 34, 0, 7); + + for (i = 0; i < GX_MAXTEVSTAGE; i++) { + gx->tevc[i] = 0; + gx->teva[i] = 0; + gx->tref[i / 2] = 0; + gx->texmapId[i] = GX_TEXMAP_NULL; + + GX_SET_REG(gx->tevc[i], 0xC0 + i * 2, 0, 7); + GX_SET_REG(gx->teva[i], 0xC1 + i * 2, 0, 7); + GX_SET_REG(gx->tevKsel[i / 2], 0xF6 + i / 2, 0, 7); + GX_SET_REG(gx->tref[i / 2], 0x28 + i / 2, 0, 7); + } + + gx->iref = 0; + GX_SET_REG(gx->iref, 0x27, 0, 7); + + for (i = 0; i < GX_MAX_TEXCOORD; i++) { + gx->suTs0[i] = 0; + gx->suTs1[i] = 0; + + GX_SET_REG(gx->suTs0[i], 0x30 + i * 2, 0, 7); + GX_SET_REG(gx->suTs1[i], 0x31 + i * 2, 0, 7); + } + + GX_SET_REG(gx->suScis0, 0x20, 0, 7); + GX_SET_REG(gx->suScis1, 0x21, 0, 7); + + GX_SET_REG(gx->cmode0, 0x41, 0, 7); + GX_SET_REG(gx->cmode1, 0x42, 0, 7); + + GX_SET_REG(gx->zmode, 0x40, 0, 7); + GX_SET_REG(gx->peCtrl, 0x43, 0, 7); + + GX_SET_REG(gx->cpTex, 0, 23, 24); + + gx->zScale = 1.6777216E7f; + gx->zOffset = 0.0f; + + gx->dirtyState = 0; + gx->dirtyVAT = 0; + + { + u32 val1; + u32 val2; + + val2 = OS_BUS_CLOCK / 500; + + __GXFlushTextureState(); + + val1 = (val2 / 2048) | 0x69000400; + + GX_BP_LOAD_REG(val1); + + __GXFlushTextureState(); + + val1 = (val2 / 4224) | 0x46000200; + + GX_BP_LOAD_REG(val1); + } + + for (i = 0; i < 8; i++) { + GX_SET_REG(gx->vatA[i], 1, 1, 1); + GX_SET_REG(gx->vatB[i], 1, 0, 0); + + GX_CP_LOAD_REG(i | 0x80, gx->vatB[i]); + } + + { + u32 reg1 = 0; + u32 reg2 = 0; + + GX_SET_REG(reg1, 1, 31, 31); + GX_SET_REG(reg1, 1, 30, 30); + GX_SET_REG(reg1, 1, 29, 29); + GX_SET_REG(reg1, 1, 28, 28); + GX_SET_REG(reg1, 1, 27, 27); + GX_SET_REG(reg1, 1, 26, 26); + + GX_XF_LOAD_REG(0x1000, reg1); + + GX_SET_REG(reg2, 1, 31, 31); + + GX_XF_LOAD_REG(0x1012, reg2); + } + + { + u32 reg = 0; + GX_SET_REG(reg, 1, 31, 31); + GX_SET_REG(reg, 1, 30, 30); + GX_SET_REG(reg, 1, 29, 29); + GX_SET_REG(reg, 1, 28, 28); + GX_SET_REG(reg, 0x58, 0, 7); + + GX_BP_LOAD_REG(reg); + } + + for (i = 0; i < GX_MAX_TEXMAP; i++) { + GXInitTexCacheRegion(&gx->TexRegions0[i], GX_FALSE, GXTexRegionAddrTable[i], GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 8], + GX_TEXCACHE_32K); + GXInitTexCacheRegion(&gx->TexRegions1[i], GX_FALSE, GXTexRegionAddrTable[i + 16], GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 24], + GX_TEXCACHE_32K); + GXInitTexCacheRegion(&gx->TexRegions2[i], GX_TRUE, GXTexRegionAddrTable[i + 32], GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 40], + GX_TEXCACHE_32K); + } + + for (i = 0; i < GX_MAX_TLUT; i++) { + GXInitTlutRegion(&gx->TlutRegions[i], 0xC0000 + 0x2000 * i, GX_TLUT_256); + } + + for (i = 0; i < GX_MAX_BIGTLUT; i++) { + GXInitTlutRegion(&gx->TlutRegions[i + 16], 0xE0000 + 0x8000 * i, GX_TLUT_1K); + } + + GX_SET_CP_REG(3, 0); + + GX_SET_REG(gx->perfSel, 0, 24, 27); + + GX_CP_LOAD_REG(0x20, gx->perfSel) + + GX_XF_LOAD_REG(0x1006, 0); + + GX_BP_LOAD_REG(0x23000000) + GX_BP_LOAD_REG(0x24000000) + GX_BP_LOAD_REG(0x67000000) + + __GXSetIndirectMask(0); + __GXSetTmemConfig(2); + __GXInitGX(); + + return &FifoObj; +} + +/** + * @note Address: 0x800E30C8 + * @note Size: 0x938 + */ +void __GXInitGX(void) +{ + GXRenderModeObj* renderObj; + GXTexObj texObj; + Mtx ident; + GXColor clearColor = { 64, 64, 64, 255 }; + GXColor ambColor = { 0, 0, 0, 0 }; + GXColor matColor = { 255, 255, 255, 255 }; + u32 i; + + switch (VIGetTvFormat()) { + case VI_NTSC: + renderObj = &GXNtsc480IntDf; + break; + + case VI_PAL: + renderObj = &GXPal528IntDf; + break; + + case VI_EURGB60: + renderObj = &GXEurgb60Hz480IntDf; + break; + + case VI_MPAL: + renderObj = &GXMpal480IntDf; + break; + + default: + renderObj = &GXNtsc480IntDf; + break; + } + + GXSetCopyClear(clearColor, 0xFFFFFF); + + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX3X4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX3X4, GX_TG_TEX1, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD2, GX_TG_MTX3X4, GX_TG_TEX2, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD3, GX_TG_MTX3X4, GX_TG_TEX3, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD4, GX_TG_MTX3X4, GX_TG_TEX4, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD5, GX_TG_MTX3X4, GX_TG_TEX5, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD6, GX_TG_MTX3X4, GX_TG_TEX6, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD7, GX_TG_MTX3X4, GX_TG_TEX7, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + + GXSetNumTexGens(1); + GXClearVtxDesc(); + GXInvalidateVtxCache(); + + for (i = GX_VA_POS; i <= GX_LIGHT_ARRAY; i++) { + GXSetArray((GXAttr)i, gx, 0); + } + + for (i = 0; i < GX_MAX_VTXFMT; i++) { + GXSetVtxAttrFmtv((GXVtxFmt)i, GXDefaultVATList); + } + + GXSetLineWidth(6, GX_TO_ZERO); + GXSetPointSize(6, GX_TO_ZERO); + GXEnableTexOffsets(GX_TEXCOORD0, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD1, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD2, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD3, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD4, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD5, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD6, GX_FALSE, GX_FALSE); + GXEnableTexOffsets(GX_TEXCOORD7, GX_FALSE, GX_FALSE); + + ident[0][0] = 1.0f; + ident[0][1] = 0.0f; + ident[0][2] = 0.0f; + ident[0][3] = 0.0f; + + ident[1][0] = 0.0f; + ident[1][1] = 1.0f; + ident[1][2] = 0.0f; + ident[1][3] = 0.0f; + + ident[2][0] = 0.0f; + ident[2][1] = 0.0f; + ident[2][2] = 1.0f; + ident[2][3] = 0.0f; + + GXLoadPosMtxImm(ident, GX_PNMTX0); + GXLoadNrmMtxImm(ident, GX_PNMTX0); + GXSetCurrentMtx(GX_PNMTX0); + + GXLoadTexMtxImm(ident, GX_IDENTITY, GX_MTX3x4); + GXLoadTexMtxImm(ident, GX_PTIDENTITY, GX_MTX3x4); + + GXSetViewport(0.0f, 0.0f, renderObj->fbWidth, renderObj->xfbHeight, 0.0f, 1.0f); + + GXSetProjectionv(GXDefaultProjData); + + GXSetCoPlanar(GX_FALSE); + GXSetCullMode(GX_CULL_BACK); + GXSetClipMode(GX_CLIP_ENABLE); + + GXSetScissor(0, 0, renderObj->fbWidth, renderObj->efbHeight); + GXSetScissorBoxOffset(0, 0); + + GXSetNumChans(0); + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE); + GXSetChanAmbColor(GX_COLOR0A0, ambColor); + GXSetChanMatColor(GX_COLOR0A0, matColor); + + GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE); + GXSetChanAmbColor(GX_COLOR1A1, ambColor); + GXSetChanMatColor(GX_COLOR1A1, matColor); + + GXInvalidateTexAll(); + GXSetTexRegionCallback(__GXDefaultTexRegionCallback); + GXSetTlutRegionCallback(__GXDefaultTlutRegionCallback); + + GXInitTexObj(&texObj, DefaultTexData, 4, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GXLoadTexObj(&texObj, GX_TEXMAP0); + GXLoadTexObj(&texObj, GX_TEXMAP1); + GXLoadTexObj(&texObj, GX_TEXMAP2); + GXLoadTexObj(&texObj, GX_TEXMAP3); + GXLoadTexObj(&texObj, GX_TEXMAP4); + GXLoadTexObj(&texObj, GX_TEXMAP5); + GXLoadTexObj(&texObj, GX_TEXMAP6); + GXLoadTexObj(&texObj, GX_TEXMAP7); + + 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 = 0; i < GX_MAXTEVSTAGE; 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 = 0; i < GX_MAXTEVSTAGE; i++) { + GXSetTevDirect((GXTevStageID)i); + } + + GXSetNumIndStages(0); + GXSetIndTexCoordScale(GX_IND_TEX_STAGE_0, GX_ITS_1, GX_ITS_1); + GXSetIndTexCoordScale(GX_IND_TEX_STAGE_1, GX_ITS_1, GX_ITS_1); + GXSetIndTexCoordScale(GX_IND_TEX_STAGE_2, GX_ITS_1, GX_ITS_1); + GXSetIndTexCoordScale(GX_IND_TEX_STAGE_3, GX_ITS_1, GX_ITS_1); + + GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, ambColor); + GXSetFogRangeAdj(GX_FALSE, 0, nullptr); + + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + + GXSetColorUpdate(GX_TRUE); + GXSetAlphaUpdate(GX_TRUE); + + GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + GXSetZCompLoc(GX_TRUE); + + GXSetDither(GX_TRUE); + + GXSetDstAlpha(GX_FALSE, 0); + GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + + GXSetFieldMask(GX_TRUE, GX_TRUE); + GXSetFieldMode((GXBool)renderObj->field_rendering, (GXBool)((renderObj->viHeight == 2 * renderObj->xfbHeight) ? GX_TRUE : GX_FALSE)); + + GXSetDispCopySrc(0, 0, renderObj->fbWidth, renderObj->efbHeight); + GXSetDispCopyDst(renderObj->fbWidth, renderObj->efbHeight); + GXSetDispCopyYScale((f32)renderObj->xfbHeight / (f32)renderObj->efbHeight); + GXSetCopyClamp(GX_CLAMP_BOTH); + + GXSetCopyFilter(renderObj->aa, renderObj->sample_pattern, GX_TRUE, renderObj->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_FALSE, 0); + GXPokeZMode(GX_TRUE, GX_ALWAYS, GX_TRUE); + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + GXClearGPMetric(); +} diff --git a/dolphin sdk not yet linked/src/gx/GXLight.c b/dolphin sdk not yet linked/src/gx/GXLight.c new file mode 100644 index 0000000..29b4820 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXLight.c @@ -0,0 +1,463 @@ +#include "Dolphin/gx.h" +#include "math.h" + +/** + * @note Address: 0x800E6870 + * @note Size: 0x1C + */ +void GXInitLightAttn(GXLightObj* obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) +{ + GXLightObjPriv* pObj = (GXLightObjPriv*)obj; + pObj->a[0] = a0; + pObj->a[1] = a1; + pObj->a[2] = a2; + + pObj->k[0] = k0; + pObj->k[1] = k1; + pObj->k[2] = k2; +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void GXInitLightAttnA(GXLightObj* obj, f32 a0, f32 a1, f32 a2) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void GXGetLightAttnA(GXLightObj* obj, f32* a0, f32* a1, f32* a2) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void GXInitLightAttnK(GXLightObj* obj, f32 k0, f32 k1, f32 k2) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void GXGetLightAttnK(GXLightObj* obj, f32* k0, f32* k1, f32* k2) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E688C + * @note Size: 0x190 + */ +void GXInitLightSpot(GXLightObj* obj, f32 cutoff, GXSpotFn spotFunc) +{ + f32 a0, a1, a2, r, d, cr; + GXLightObjPriv* pObj = (GXLightObjPriv*)obj; + + if (cutoff <= 0.0f || cutoff > 90.0f) { + spotFunc = GX_SP_OFF; + } + + r = cutoff * PI / 180.0f; + cr = cosf(r); + + switch (spotFunc) { + 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; + } + + pObj->a[0] = a0; + pObj->a[1] = a1; + pObj->a[2] = a2; +} + +/** + * @note Address: 0x800E6A1C + * @note Size: 0xD0 + */ +void GXInitLightDistAttn(GXLightObj* obj, f32 refDist, f32 refBrightness, GXDistAttnFn distFunc) +{ + f32 k0, k1, k2; + GXLightObjPriv* pObj = (GXLightObjPriv*)obj; + + if (refDist < 0.0F) { + distFunc = GX_DA_OFF; + } + + if (refBrightness <= 0.0F || refBrightness >= 1.0F) { + distFunc = GX_DA_OFF; + } + + switch (distFunc) { + case GX_DA_GENTLE: + k0 = 1.0F; + k1 = (1.0F - refBrightness) / (refBrightness * refDist); + k2 = 0.0F; + break; + case GX_DA_MEDIUM: + k0 = 1.0f; + k1 = 0.5f * (1.0f - refBrightness) / (refBrightness * refDist); + k2 = 0.5f * (1.0f - refBrightness) / (refBrightness * refDist * refDist); + break; + case GX_DA_STEEP: + k0 = 1.0f; + k1 = 0.0f; + k2 = (1.0f - refBrightness) / (refBrightness * refDist * refDist); + break; + case GX_DA_OFF: + default: + k0 = 1.0f; + k1 = 0.0f; + k2 = 0.0f; + break; + } + + pObj->k[0] = k0; + pObj->k[1] = k1; + pObj->k[2] = k2; +} + +/** + * @note Address: 0x800E6AEC + * @note Size: 0x10 + */ +void GXInitLightPos(GXLightObj* obj, f32 x, f32 y, f32 z) +{ + GXLightObjPriv* pObj = (GXLightObjPriv*)obj; + pObj->lpos[0] = x; + pObj->lpos[1] = y; + pObj->lpos[2] = z; +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void GXGetLightPos(GXLightObj* obj, f32* x, f32* y, f32* z) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E6AFC + * @note Size: 0x1C + */ +void GXInitLightDir(GXLightObj* obj, f32 nX, f32 nY, f32 nZ) +{ + GXLightObjPriv* pObj = (GXLightObjPriv*)obj; + pObj->ldir[0] = -nX; + pObj->ldir[1] = -nY; + pObj->ldir[2] = -nZ; +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void GXGetLightDir(GXLightObj* obj, f32* nX, f32* nY, f32* nZ) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E6B18 + * @note Size: 0xE4 + */ +void GXInitSpecularDir(GXLightObj* obj, f32 nX, f32 nY, f32 nZ) +{ + f32 mag; + f32 vx, vy, vz; + GXLightObjPriv* pObj = (GXLightObjPriv*)obj; + + vx = -nX; + vy = -nY; + vz = (-nZ + 1.0F); + mag = vx * vx + vy * vy + vz * vz; + + if (mag != 0.0f) { + mag = 1.0f / dolsqrtf(mag); + } + + pObj->ldir[0] = vx * mag; + pObj->ldir[1] = vy * mag; + pObj->ldir[2] = vz * mag; + + pObj->lpos[0] = nX * -GX_LARGE_NUMBER; + pObj->lpos[1] = nY * -GX_LARGE_NUMBER; + pObj->lpos[2] = nZ * -GX_LARGE_NUMBER; +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +void GXInitSpecularDirHA(GXLightObj* obj, f32 nX, f32 nY, f32 nZ, f32 hX, f32 hY, f32 hZ) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E6BFC + * @note Size: 0xC + */ +void GXInitLightColor(GXLightObj* obj, GXColor color) +{ + GXLightObjPriv* pObj = (GXLightObjPriv*)obj; + pObj->color = color; +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetLightColor(GXLightObj* obj, GXColor* color) +{ + // UNUSED FUNCTION +} + +static inline void PushLight(const register GXLightObjPriv* 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 +} + +/** + * @note Address: 0x800E6C08 + * @note Size: 0x7C + */ +void GXLoadLightObjImm(GXLightObj* obj, GXLightID light) +{ + u32 addr; + u32 idx; + GXLightObjPriv* pObj = (GXLightObjPriv*)obj; + + idx = 31 - __cntlzw(light); + idx &= 7; + + addr = 0x600 + idx * 0x10; + + GX_XF_LOAD_REG_HDR(addr | (0x10 - 1) << 16); + + PushLight(pObj, (void*)GXFIFO_ADDR); + __GXData->bpSentNot = 1; +} + +/** + * @note Address: N/A + * @note Size: 0x48 + */ +void GXLoadLightObjIndx(u32 objIndex, GXLightID light) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E6C84 + * @note Size: 0xF0 + */ +void GXSetChanAmbColor(GXChannelID channel, GXColor color) +{ + u32 reg; + u32 rgb; + u32 colorID; + u8 alpha; + + switch (channel) { + case GX_COLOR0: + rgb = gx->ambColor[GX_COLOR0]; + reg = GX_SET_TRUNC(GXCOLOR_AS_U32(color) & ~0xff, rgb, 24, 31); + colorID = GX_COLOR0; + break; + case GX_COLOR1: + rgb = gx->ambColor[GX_COLOR1]; + reg = GX_SET_TRUNC(GXCOLOR_AS_U32(color) & ~0xff, rgb, 24, 31); + colorID = GX_COLOR1; + break; + case GX_ALPHA0: + reg = gx->ambColor[GX_COLOR0]; + reg = GX_SET_TRUNC(reg, color.a, 24, 31); + colorID = GX_COLOR0; + break; + case GX_ALPHA1: + reg = gx->ambColor[GX_COLOR1]; + reg = GX_SET_TRUNC(reg, color.a, 24, 31); + colorID = GX_COLOR1; + break; + case GX_COLOR0A0: + reg = GXCOLOR_AS_U32(color); + colorID = GX_COLOR0; + break; + case GX_COLOR1A1: + reg = GXCOLOR_AS_U32(color); + colorID = GX_COLOR1; + break; + default: + return; + } + + GX_XF_LOAD_REG(GX_XF_REG_AMBIENT0 + colorID, reg); + gx->bpSentNot = GX_TRUE; + gx->ambColor[colorID] = reg; +} + +/** + * @note Address: 0x800E6D74 + * @note Size: 0xF0 + */ +void GXSetChanMatColor(GXChannelID channel, GXColor color) +{ + u32 reg = 0; + u32 rgb; + GXChannelID colorID; + + switch (channel) { + case GX_COLOR0: + rgb = gx->matColor[GX_COLOR0]; + reg = GX_SET_TRUNC(GXCOLOR_AS_U32(color) & ~0xff, rgb, 24, 31); + colorID = GX_COLOR0; + break; + case GX_COLOR1: + rgb = gx->matColor[GX_COLOR1]; + reg = GX_SET_TRUNC(GXCOLOR_AS_U32(color) & ~0xff, rgb, 24, 31); + colorID = GX_COLOR1; + break; + case GX_ALPHA0: + reg = gx->matColor[GX_COLOR0]; + reg = GX_SET_TRUNC(reg, color.a, 24, 31); + colorID = GX_COLOR0; + break; + case GX_ALPHA1: + reg = gx->matColor[GX_COLOR1]; + reg = GX_SET_TRUNC(reg, color.a, 24, 31); + colorID = GX_COLOR1; + break; + case GX_COLOR0A0: + reg = GXCOLOR_AS_U32(color); + colorID = GX_COLOR0; + break; + case GX_COLOR1A1: + reg = GXCOLOR_AS_U32(color); + colorID = GX_COLOR1; + break; + default: + return; + } + + GX_XF_LOAD_REG(GX_XF_REG_MATERIAL0 + colorID, reg); + gx->bpSentNot = GX_TRUE; + gx->matColor[colorID] = reg; +} + +/** + * @note Address: 0x800E6E64 + * @note Size: 0x3C + */ +void GXSetNumChans(u8 count) +{ + GX_SET_REG(gx->genMode, count, 25, 27); + GX_XF_LOAD_REG(GX_XF_REG_NUMCOLORS, count); + gx->dirtyState |= GX_DIRTY_GEN_MODE; +} + +/** + * @note Address: 0x800E6EA0 + * @note Size: 0xB8 + */ +void GXSetChanCtrl(GXChannelID channel, GXBool doEnable, GXColorSrc ambSrc, GXColorSrc matSrc, u32 mask, GXDiffuseFn diffFunc, + GXAttnFn attnFunc) +{ + const u32 colorID = (u32)channel & 0x3; + u32 reg = 0; + + GX_SET_REG(reg, doEnable, GX_XF_CLR0CTRL_LIGHT_ST, GX_XF_CLR0CTRL_LIGHT_END); + GX_SET_REG(reg, matSrc, GX_XF_CLR0CTRL_MTXSRC_ST, GX_XF_CLR0CTRL_MTXSRC_END); + GX_SET_REG(reg, ambSrc, GX_XF_CLR0CTRL_AMBSRC_ST, GX_XF_CLR0CTRL_AMBSRC_END); + GX_SET_REG(reg, (attnFunc == GX_AF_SPEC ? GX_DF_NONE : diffFunc), GX_XF_CLR0CTRL_DIFATTN_ST, GX_XF_CLR0CTRL_DIFATTN_END); + GX_SET_REG(reg, (attnFunc != GX_AF_NONE), GX_XF_CLR0CTRL_ATTNENABLE_ST, GX_XF_CLR0CTRL_ATTNENABLE_END); + GX_SET_REG(reg, (attnFunc != GX_AF_SPEC), GX_XF_CLR0CTRL_ATTNSEL_ST, GX_XF_CLR0CTRL_ATTNSEL_END); + + // why are we unmasking bits we're about to overwrite? + + reg = (reg & ~(0xf << 2)) | ((mask & 0xf) << 2); + + reg = (reg & ~(0xf << 11)) | (((mask >> 4) & 0xf) << 11); + + GX_XF_LOAD_REG(GX_XF_REG_COLOR0CNTRL + colorID, reg); + + if (channel == GX_COLOR0A0) { + GX_XF_LOAD_REG(GX_XF_REG_ALPHA0CNTRL, reg); + } else if (channel == GX_COLOR1A1) { + GX_XF_LOAD_REG(GX_XF_REG_ALPHA1CNTRL, reg); + } + + gx->bpSentNot = GX_TRUE; +} diff --git a/dolphin sdk not yet linked/src/gx/GXMisc.c b/dolphin sdk not yet linked/src/gx/GXMisc.c new file mode 100644 index 0000000..e4c0b62 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXMisc.c @@ -0,0 +1,477 @@ +#include "Dolphin/gx.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +static GXDrawSyncCallback TokenCB; +static GXDrawDoneCallback DrawDoneCB; +static GXBool DrawDone; +static OSThreadQueue FinishQueue; + +/** + * @note Address: 0x800E4FD8 + * @note Size: 0x94 + */ +void GXSetMisc(GXMiscToken token, u32 val) +{ + switch (token) { + case GX_MT_NULL: + break; + + case GX_MT_XF_FLUSH: + gx->vNum = val; + gx->vNumNot = !gx->vNum; + gx->bpSentNot = GX_TRUE; + + if (gx->vNum) { + gx->dirtyState |= GX_DIRTY_VCD; + } + break; + + case GX_MT_DL_SAVE_CONTEXT: + gx->dlSaveContext = (val != 0); + break; + + case GX_MT_ABORT_WAIT_COPYOUT: + gx->abtWaitPECopy = (val != 0); + break; + } +} + +/** + * @note Address: 0x800E506C + * @note Size: 0x5C + */ +void GXFlush(void) +{ + if (gx->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(); +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void GXResetWriteGatherPipe(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +static void __GXAbortWait(u32 clocks) +{ + OSTime time0, time1; + time0 = OSGetTime(); + + do { + time1 = OSGetTime(); + } while (time1 - time0 <= clocks / 4); +} + +/** + * @note Address: N/A + * @note Size: 0xC4 + */ +static void __GXAbortWaitPECopyDone(void) +{ + u32 peCnt0, peCnt1; + + peCnt0 = GXReadMEMReg(0x28, 0x27); + do { + peCnt1 = peCnt0; + __GXAbortWait(32); + + peCnt0 = GXReadMEMReg(0x28, 0x27); + } while (peCnt0 != peCnt1); +} + +/** + * @note Address: 0x800E50C8 + * @note Size: 0x16C + */ +void __GXAbort(void) +{ + if (gx->abtWaitPECopy && GXGetGPFifo()) { + __GXAbortWaitPECopyDone(); + } + + __PIRegs[0x18 / 4] = 1; + __GXAbortWait(200); + __PIRegs[0x18 / 4] = 0; + __GXAbortWait(20); +} + +/** + * @note Address: 0x800E5234 + * @note Size: 0x170 + */ +void GXAbortFrame(void) +{ + __GXAbort(); + __GXCleanGPFifo(); +} + +/** + * @note Address: 0x800E53A4 + * @note Size: 0xB4 + */ +void GXSetDrawSync(u16 token) +{ + u32 reg; + BOOL interrupts; + + interrupts = OSDisableInterrupts(); + reg = token | 0x48000000; + GX_BP_LOAD_REG(reg); + GX_SET_REG(reg, token, 16, 31); + GX_SET_REG(reg, 0x47, 0, 7); + GX_BP_LOAD_REG(reg); + + GXFlush(); + OSRestoreInterrupts(interrupts); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXReadDrawSync(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E5458 + * @note Size: 0x98 + */ +void GXSetDrawDone(void) +{ + u32 reg; + BOOL interrupts; + + interrupts = OSDisableInterrupts(); + reg = 0x45000002; + GX_BP_LOAD_REG(reg); + + GXFlush(); + DrawDone = GX_FALSE; + OSRestoreInterrupts(interrupts); +} + +/** + * @note Address: 0x800E54F0 + * @note Size: 0x4C + */ +void GXWaitDrawDone(void) +{ + BOOL interrupts; + interrupts = OSDisableInterrupts(); + while (!DrawDone) { + OSSleepThread(&FinishQueue); + } + + OSRestoreInterrupts(interrupts); +} + +/** + * @note Address: 0x800E553C + * @note Size: 0x80 + */ +void GXDrawDone(void) +{ + GXSetDrawDone(); + GXWaitDrawDone(); +} + +/** + * @note Address: 0x800E55BC + * @note Size: 0x24 + */ +void GXPixModeSync(void) +{ + GX_BP_LOAD_REG(gx->peCtrl); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void GXTexModeSync(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E55E0 + * @note Size: 0x14 + */ +void GXPokeAlphaMode(GXCompare func, u8 threshold) { GX_SET_PE_REG(3, func << 8 | threshold); } + +/** + * @note Address: 0x800E55F4 + * @note Size: 0x20 + */ +void GXPokeAlphaRead(GXAlphaReadMode mode) +{ + u32 reg = 0; + GX_SET_REG(reg, mode, 30, 31); + GX_SET_REG(reg, 1, 29, 29); + GX_SET_PE_REG(4, reg); +} + +/** + * @note Address: 0x800E5614 + * @note Size: 0x18 + */ +void GXPokeAlphaUpdate(GXBool doUpdate) +{ + u32 reg; + reg = GX_GET_PE_REG(1); + GX_SET_REG(reg, doUpdate, 27, 27); + GX_SET_PE_REG(1, reg); +} + +/** + * @note Address: 0x800E562C + * @note Size: 0x64 + */ +void GXPokeBlendMode(GXBlendMode mode, GXBlendFactor srcFactor, GXBlendFactor destFactor, GXLogicOp op) +{ + u32 reg; + + reg = GX_GET_PE_REG(1); + GX_SET_REG(reg, (mode == GX_BM_BLEND) || (mode == GX_BM_SUBTRACT), 31, 31); + GX_SET_REG(reg, (mode == GX_BM_SUBTRACT), 20, 20); + GX_SET_REG(reg, (mode == GX_BM_LOGIC), 30, 30); + GX_SET_REG(reg, op, 16, 19); + GX_SET_REG(reg, srcFactor, 21, 23); + GX_SET_REG(reg, destFactor, 24, 26); + GX_SET_REG(reg, 0x41, 0, 7); + GX_SET_PE_REG(1, reg); +} + +/** + * @note Address: 0x800E5690 + * @note Size: 0x18 + */ +void GXPokeColorUpdate(GXBool doUpdate) +{ + u32 reg; + reg = GX_GET_PE_REG(1); + GX_SET_REG(reg, doUpdate, 28, 28); + GX_SET_PE_REG(1, reg); +} + +/** + * @note Address: 0x800E56A8 + * @note Size: 0x24 + */ +void GXPokeDstAlpha(GXBool doEnable, u8 alpha) +{ + u32 reg; + reg = 0; + GX_SET_REG(reg, alpha, 24, 31); + GX_SET_REG(reg, doEnable, 23, 23); + GX_SET_PE_REG(2, reg); +} + +/** + * @note Address: 0x800E56CC + * @note Size: 0x18 + */ +void GXPokeDither(GXBool doDither) +{ + u32 reg; + reg = GX_GET_PE_REG(1); + GX_SET_REG(reg, doDither, 29, 29); + GX_SET_PE_REG(1, reg); +} + +/** + * @note Address: 0x800E56E4 + * @note Size: 0x20 + */ +void GXPokeZMode(GXBool doCompare, GXCompare func, GXBool doUpdate) +{ + u32 reg; + reg = 0; + GX_SET_REG(reg, doCompare, 31, 31); + GX_SET_REG(reg, func, 28, 30); + GX_SET_REG(reg, doUpdate, 27, 27); + GX_SET_PE_REG(0, reg); +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void GXPeekARGB(u16 x, u16 y, u32* color) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void GXPokeARGB(u16 x, u16 y, u32 color) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void GXPeekZ(u16 x, u16 y, u32* z) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void GXPokeZ(u16 x, u16 y, u32 z) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E5704 + * @note Size: 0x44 + */ +GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback callback) +{ + GXDrawSyncCallback prevCB; + BOOL interrupts; + + prevCB = TokenCB; + interrupts = OSDisableInterrupts(); + TokenCB = callback; + OSRestoreInterrupts(interrupts); + return prevCB; +} + +/** + * @note Address: 0x800E5748 + * @note Size: 0x88 + */ +static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u16 token; + OSContext exceptContext; + u32 reg; + + token = GX_GET_PE_REG(7); + + if (TokenCB) { + OSClearContext(&exceptContext); + OSSetCurrentContext(&exceptContext); + TokenCB(token); + OSClearContext(&exceptContext); + OSSetCurrentContext(context); + } + + reg = GX_GET_PE_REG(5); + GX_SET_REG(reg, 1, 29, 29); + GX_SET_PE_REG(5, reg); +} + +/** + * @note Address: 0x800E57D0 + * @note Size: 0x44 + */ +GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback callback) +{ + GXDrawDoneCallback prevCB; + BOOL interrupts; + + prevCB = DrawDoneCB; + interrupts = OSDisableInterrupts(); + DrawDoneCB = callback; + OSRestoreInterrupts(interrupts); + return prevCB; +} + +/** + * @note Address: 0x800E5814 + * @note Size: 0x80 + */ +static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptContext; + u32 reg; + + reg = GX_GET_PE_REG(5); + GX_SET_REG(reg, 1, 28, 28); + GX_SET_PE_REG(5, reg); + + DrawDone = GX_TRUE; + + if (DrawDoneCB) { + OSClearContext(&exceptContext); + OSSetCurrentContext(&exceptContext); + DrawDoneCB(); + OSClearContext(&exceptContext); + OSSetCurrentContext(context); + } + + OSWakeupThread(&FinishQueue); +} + +/** + * @note Address: 0x800E5894 + * @note Size: 0x74 + */ +void __GXPEInit(void) +{ + u32 reg; + + __OSSetInterruptHandler(__OS_INTERRUPT_PI_PE_TOKEN, GXTokenInterruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_PI_PE_FINISH, GXFinishInterruptHandler); + + OSInitThreadQueue(&FinishQueue); + + __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_PE_TOKEN); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_PE_FINISH); + + reg = GX_GET_PE_REG(5); + GX_SET_REG(reg, 1, 29, 29); + GX_SET_REG(reg, 1, 28, 28); + GX_SET_REG(reg, 1, 31, 31); + GX_SET_REG(reg, 1, 30, 30); + GX_SET_PE_REG(5, reg); +} + +/** + * @note Address: N/A + * @note Size: 0x134 + */ +u32 GXCompressZ16(u32 z24, GXZFmt16 zFormat) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x11C + */ +u32 GXDecompressZ16(u32 z16, GXZFmt16 zFormat) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/gx/GXPerf.c b/dolphin sdk not yet linked/src/gx/GXPerf.c new file mode 100644 index 0000000..d11d239 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXPerf.c @@ -0,0 +1,424 @@ +#include "Dolphin/gx.h" + +/** + * @note Address: 0x800E9984 + * @note Size: 0x848 + */ +void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) +{ + switch (gx->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: + GX_XF_LOAD_REG(0x1006, 0); + 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: + GX_BP_LOAD_REG(0x23000000); + 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: + GX_BP_LOAD_REG(0x24000000); + break; + + case GX_PERF0_NONE: + break; + } + + switch (gx->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: + GX_BP_LOAD_REG(0x67000000); + 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: + GX_SET_REG(gx->perfSel, 0, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + + case GX_PERF1_FIFO_REQ: + case GX_PERF1_CALL_REQ: + case GX_PERF1_VC_MISS_REQ: + case GX_PERF1_CP_ALL_REQ: + GX_SET_CP_REG(3, 0); + break; + + case GX_PERF1_NONE: + break; + } + + gx->perf0 = perf0; + + switch (gx->perf0) { + case GX_PERF0_VERTICES: + GX_XF_LOAD_REG(0x1006, 0x273); + break; + case GX_PERF0_CLIP_VTX: + GX_XF_LOAD_REG(0x1006, 0x14A); + break; + case GX_PERF0_CLIP_CLKS: + GX_XF_LOAD_REG(0x1006, 0x16B); + break; + case GX_PERF0_XF_WAIT_IN: + GX_XF_LOAD_REG(0x1006, 0x84); + break; + case GX_PERF0_XF_WAIT_OUT: + GX_XF_LOAD_REG(0x1006, 0xC6); + break; + case GX_PERF0_XF_XFRM_CLKS: + GX_XF_LOAD_REG(0x1006, 0x210); + break; + case GX_PERF0_XF_LIT_CLKS: + GX_XF_LOAD_REG(0x1006, 0x252); + break; + case GX_PERF0_XF_BOT_CLKS: + GX_XF_LOAD_REG(0x1006, 0x231); + break; + case GX_PERF0_XF_REGLD_CLKS: + GX_XF_LOAD_REG(0x1006, 0x1AD); + break; + case GX_PERF0_XF_REGRD_CLKS: + GX_XF_LOAD_REG(0x1006, 0x1CE); + break; + case GX_PERF0_CLOCKS: + GX_XF_LOAD_REG(0x1006, 0x21); + break; + case GX_PERF0_CLIP_RATIO: + GX_XF_LOAD_REG(0x1006, 0x153); + break; + + case GX_PERF0_TRIANGLES: + GX_BP_LOAD_REG(0x2300AE7F); + break; + case GX_PERF0_TRIANGLES_CULLED: + GX_BP_LOAD_REG(0x23008E7F); + break; + case GX_PERF0_TRIANGLES_PASSED: + GX_BP_LOAD_REG(0x23009E7F); + break; + case GX_PERF0_TRIANGLES_SCISSORED: + GX_BP_LOAD_REG(0x23001E7F); + break; + case GX_PERF0_TRIANGLES_0TEX: + GX_BP_LOAD_REG(0x2300AC3F); + break; + case GX_PERF0_TRIANGLES_1TEX: + GX_BP_LOAD_REG(0x2300AC7F); + break; + case GX_PERF0_TRIANGLES_2TEX: + GX_BP_LOAD_REG(0x2300ACBF); + break; + case GX_PERF0_TRIANGLES_3TEX: + GX_BP_LOAD_REG(0x2300ACFF); + break; + case GX_PERF0_TRIANGLES_4TEX: + GX_BP_LOAD_REG(0x2300AD3F); + break; + case GX_PERF0_TRIANGLES_5TEX: + GX_BP_LOAD_REG(0x2300AD7F); + break; + case GX_PERF0_TRIANGLES_6TEX: + GX_BP_LOAD_REG(0x2300ADBF); + break; + case GX_PERF0_TRIANGLES_7TEX: + GX_BP_LOAD_REG(0x2300ADFF); + break; + case GX_PERF0_TRIANGLES_8TEX: + GX_BP_LOAD_REG(0x2300AE3F); + break; + case GX_PERF0_TRIANGLES_0CLR: + GX_BP_LOAD_REG(0x2300A27F); + break; + case GX_PERF0_TRIANGLES_1CLR: + GX_BP_LOAD_REG(0x2300A67F); + break; + case GX_PERF0_TRIANGLES_2CLR: + GX_BP_LOAD_REG(0x2300AA7F); + break; + + case GX_PERF0_QUAD_0CVG: + GX_BP_LOAD_REG(0x2402C0C6); + break; + case GX_PERF0_QUAD_NON0CVG: + GX_BP_LOAD_REG(0x2402C16B); + break; + case GX_PERF0_QUAD_1CVG: + GX_BP_LOAD_REG(0x2402C0E7); + break; + case GX_PERF0_QUAD_2CVG: + GX_BP_LOAD_REG(0x2402C108); + break; + case GX_PERF0_QUAD_3CVG: + GX_BP_LOAD_REG(0x2402C129); + break; + case GX_PERF0_QUAD_4CVG: + GX_BP_LOAD_REG(0x2402C14A); + break; + case GX_PERF0_AVG_QUAD_CNT: + GX_BP_LOAD_REG(0x2402C1AD); + break; + + case GX_PERF0_NONE: + break; + } + + gx->perf1 = perf1; + + switch (gx->perf1) { + case GX_PERF1_TEXELS: + GX_BP_LOAD_REG(0x67000042); + break; + case GX_PERF1_TX_IDLE: + GX_BP_LOAD_REG(0x67000084); + break; + case GX_PERF1_TX_REGS: + GX_BP_LOAD_REG(0x67000063); + break; + case GX_PERF1_TX_MEMSTALL: + GX_BP_LOAD_REG(0x67000129); + break; + case GX_PERF1_TC_MISS: + GX_BP_LOAD_REG(0x67000252); + break; + case GX_PERF1_CLOCKS: + GX_BP_LOAD_REG(0x67000021); + break; + case GX_PERF1_TC_CHECK1_2: + GX_BP_LOAD_REG(0x6700014B); + break; + case GX_PERF1_TC_CHECK3_4: + GX_BP_LOAD_REG(0x6700018D); + break; + case GX_PERF1_TC_CHECK5_6: + GX_BP_LOAD_REG(0x670001CF); + break; + case GX_PERF1_TC_CHECK7_8: + GX_BP_LOAD_REG(0x67000211); + break; + + case GX_PERF1_VC_ELEMQ_FULL: + GX_SET_REG(gx->perfSel, 2, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + case GX_PERF1_VC_MISSQ_FULL: + GX_SET_REG(gx->perfSel, 3, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + case GX_PERF1_VC_MEMREQ_FULL: + GX_SET_REG(gx->perfSel, 4, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + case GX_PERF1_VC_STATUS7: + GX_SET_REG(gx->perfSel, 5, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + case GX_PERF1_VC_MISSREP_FULL: + GX_SET_REG(gx->perfSel, 6, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + case GX_PERF1_VC_STREAMBUF_LOW: + GX_SET_REG(gx->perfSel, 7, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + case GX_PERF1_VC_ALL_STALLS: + GX_SET_REG(gx->perfSel, 9, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + case GX_PERF1_VERTICES: + GX_SET_REG(gx->perfSel, 8, 24, 27); + GX_CP_LOAD_REG(0x20, gx->perfSel); + break; + + case GX_PERF1_FIFO_REQ: + GX_SET_CP_REG(3, 2); + break; + case GX_PERF1_CALL_REQ: + GX_SET_CP_REG(3, 3); + break; + case GX_PERF1_VC_MISS_REQ: + GX_SET_CP_REG(3, 4); + break; + case GX_PERF1_CP_ALL_REQ: + GX_SET_CP_REG(3, 5); + break; + + case GX_PERF1_NONE: + break; + } + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: N/A + * @note Size: 0x1A8 + */ +void GXReadGPMetric(u32* count0, u32* count1) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA1CC + * @note Size: 0x10 + */ +void GXClearGPMetric(void) { GX_SET_CP_REG(2, 4); } + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +u32 GXReadGP0Metric(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +u32 GXReadGP1Metric(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x214 + */ +void GXReadMemMetric(u32* cpReq, u32* tcReq, u32* cpuReadReq, u32* cpuWriteReq, u32* dspReq, u32* ioReq, u32* viReq, u32* peReq, u32* rfReq, + u32* fiReq) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xA8 + */ +void GXClearMemMetric(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x138 + */ +void GXReadPixMetric(u32* topIn, u32* topOut, u32* bottomIn, u32* bottomOut, u32* clearIn, u32* copyClocks) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +void GXClearPixMetric(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void GXSetVCacheMetric(GXVCachePerf attr) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void GXReadVCacheMetric(u32* check, u32* miss, u32* stall) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void GXClearVCacheMetric(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +void GXInitXfRasMetric(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA1DC + * @note Size: 0xC4 + * TODO: use enums for the read regs + */ +#pragma scheduling off +void GXReadXfRasMetric(u32* xfWaitIn, u32* xfWaitOut, u32* rasBusy, u32* clocks) +{ + *rasBusy = GXReadCPReg(32, 33); + *clocks = GXReadCPReg(34, 35); + *xfWaitIn = GXReadCPReg(36, 37); + *xfWaitOut = GXReadCPReg(38, 39); +} +#pragma scheduling reset +/** + * @note Address: N/A + * @note Size: 0x40 + */ +u32 GXReadClksPerVtx(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/gx/GXPixel.c b/dolphin sdk not yet linked/src/gx/GXPixel.c new file mode 100644 index 0000000..373af50 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXPixel.c @@ -0,0 +1,312 @@ +#include "Dolphin/gx.h" +#include "math.h" + +/** + * @note Address: 0x800E8BE0 + * @note Size: 0x224 + */ +void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) +{ + f32 a, c; + u32 a_bits, c_bits; + + u32 fogColorReg = 0; + u32 fogParamReg0 = 0; + u32 fogParamReg1 = 0; + u32 fogParamReg2 = 0; + u32 fogParamReg3 = 0; + + u32 fsel = type & 7; + BOOL isOrtho = (type >> 3) & 1; + + if (isOrtho) { + if (farz == nearz || endz == startz) { + a = 0.0f; + c = 0.0f; + } else { + a = (1.0f / (endz - startz)) * (farz - nearz); + c = (1.0f / (endz - startz)) * (startz - nearz); + } + } else { + f32 tmpA, tmpB, tmpC; + u32 expB, magB, shiftB; + + if (farz == nearz || endz == startz) { + tmpA = 0.0f; + tmpB = 0.5f; + tmpC = 0.0f; + } else { + tmpA = (farz * nearz) / ((farz - nearz) * (endz - startz)); + tmpB = farz / (farz - nearz); + tmpC = startz / (endz - startz); + } + + expB = 0; + while (tmpB > 1.0) { + tmpB /= 2.0f; + expB++; + } + while (tmpB > 0.0f && tmpB < 0.5) { + tmpB *= 2.0f; + expB--; + } + + a = tmpA / (1 << expB + 1); + magB = 8388638.0f * tmpB; + shiftB = expB + 1; + c = tmpC; + + GX_SET_REG(fogParamReg1, magB, GX_BP_FOGPARAM1_B_MAG_ST, GX_BP_FOGPARAM1_B_MAG_END); + GX_SET_REG(fogParamReg2, shiftB, GX_BP_FOGPARAM2_B_SHIFT_ST, GX_BP_FOGPARAM2_B_SHIFT_END); + + GX_SET_REG(fogParamReg1, GX_BP_REG_FOGPARAM1, 0, 7); + GX_SET_REG(fogParamReg2, GX_BP_REG_FOGPARAM2, 0, 7); + } + + a_bits = *(u32*)&a; + c_bits = *(u32*)&c; + + GX_SET_REG(fogParamReg0, a_bits >> 12, GX_BP_FOGPARAM0_A_MANT_ST, GX_BP_FOGPARAM0_A_MANT_END); + GX_SET_REG(fogParamReg0, a_bits >> 23, GX_BP_FOGPARAM0_A_EXP_ST, GX_BP_FOGPARAM0_A_EXP_END); + GX_SET_REG(fogParamReg0, a_bits >> 31, GX_BP_FOGPARAM0_A_SIGN_ST, GX_BP_FOGPARAM0_A_SIGN_END); + + GX_SET_REG(fogParamReg0, GX_BP_REG_FOGPARAM0, 0, 7); + + GX_SET_REG(fogParamReg3, c_bits >> 12, GX_BP_FOGPARAM3_C_MANT_ST, GX_BP_FOGPARAM3_C_MANT_END); + GX_SET_REG(fogParamReg3, c_bits >> 23, GX_BP_FOGPARAM3_C_EXP_ST, GX_BP_FOGPARAM3_C_EXP_END); + GX_SET_REG(fogParamReg3, c_bits >> 31, GX_BP_FOGPARAM3_C_SIGN_ST, GX_BP_FOGPARAM3_C_SIGN_END); + + GX_SET_REG(fogParamReg3, isOrtho, GX_BP_FOGPARAM3_PROJ_ST, GX_BP_FOGPARAM3_PROJ_END); + GX_SET_REG(fogParamReg3, fsel, GX_BP_FOGPARAM3_FSEL_ST, GX_BP_FOGPARAM3_FSEL_END); + + GX_SET_REG(fogParamReg3, GX_BP_REG_FOGPARAM3, 0, 7); + + GX_SET_REG(fogColorReg, color.b, GX_BP_FOGCOLOR_RGB_ST + 16, GX_BP_FOGCOLOR_RGB_END); + GX_SET_REG(fogColorReg, color.g, (GX_BP_FOGCOLOR_RGB_ST + 8), (GX_BP_FOGCOLOR_RGB_END - 8)); + GX_SET_REG(fogColorReg, color.r, (GX_BP_FOGCOLOR_RGB_ST + 0), (GX_BP_FOGCOLOR_RGB_END - 16)); + GX_SET_REG(fogColorReg, GX_BP_REG_FOGCOLOR, 0, 7); + + GX_BP_LOAD_REG(fogParamReg0); + GX_BP_LOAD_REG(fogParamReg1); + GX_BP_LOAD_REG(fogParamReg2); + GX_BP_LOAD_REG(fogParamReg3); + GX_BP_LOAD_REG(fogColorReg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8E04 + * @note Size: 0x1B0 + */ +void GXInitFogAdjTable(GXFogAdjTable* table, u16 width, const Mtx44 proj) +{ + f32 x, nearZ, scale, sideX, dist; + u32 i; + + if (proj[3][3] == 0.0) { + nearZ = proj[2][3] / (proj[2][2] - 1.0f); + sideX = nearZ / proj[0][0]; + } else { + sideX = 1.0f / proj[0][0]; + nearZ = M_SQRT3 * sideX; + } + + scale = 2.0f / width; + + for (i = 0; i < ARRAY_SIZE(table->fogVals); i++) { + x = (i + 1) * 32; + x *= scale; + x *= sideX; + dist = dolsqrtf(1.0f + (x * x) / (nearZ * nearZ)); + table->fogVals[i] = (u32)(dist * 256.0f) & 0xFFF; + } +} + +/** + * @note Address: 0x800E8FB4 + * @note Size: 0x124 + */ +void GXSetFogRangeAdj(GXBool enable, u16 center, GXFogAdjTable* table) +{ + u32 fogRangeReg; + u32 fogRangeRegK; + u32 i; + + if (enable) { + for (i = 0; i < ARRAY_SIZE(table->fogVals); i += 2) { + fogRangeRegK = 0; + GX_SET_REG(fogRangeRegK, table->fogVals[i], GX_BP_FOGRANGEK_HI_ST, GX_BP_FOGRANGEK_HI_END); + GX_SET_REG(fogRangeRegK, table->fogVals[i + 1], GX_BP_FOGRANGEK_LO_ST, GX_BP_FOGRANGEK_LO_END); + GX_SET_REG(fogRangeRegK, GX_BP_REG_FOGRANGEK0 + (i / 2), 0, 7); + GX_BP_LOAD_REG(fogRangeRegK); + } + } + + fogRangeReg = 0; + GX_SET_REG(fogRangeReg, center + 342, GX_BP_FOGRANGE_CENTER_ST, GX_BP_FOGRANGE_CENTER_END); + GX_SET_REG(fogRangeReg, enable, GX_BP_FOGRANGE_ENABLED_ST, GX_BP_FOGRANGE_ENABLED_END); + GX_SET_REG(fogRangeReg, GX_BP_REG_FOGRANGE, 0, 7); + GX_BP_LOAD_REG(fogRangeReg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E90D8 + * @note Size: 0x54 + */ +void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op) +{ + u32 blendModeReg = gx->cmode0; + GX_SET_REG(blendModeReg, type == GX_BM_SUBTRACT, GX_BP_BLENDMODE_SUBTRACT_ST, GX_BP_BLENDMODE_SUBTRACT_END); + GX_SET_REG(blendModeReg, type, GX_BP_BLENDMODE_ENABLE_ST, GX_BP_BLENDMODE_ENABLE_END); + GX_SET_REG(blendModeReg, type == GX_BM_LOGIC, GX_BP_BLENDMODE_LOGIC_OP_ST, GX_BP_BLENDMODE_LOGIC_OP_END); + GX_SET_REG(blendModeReg, op, GX_BP_BLENDMODE_LOGICMODE_ST, GX_BP_BLENDMODE_LOGICMODE_END); + GX_SET_REG(blendModeReg, src_factor, GX_BP_BLENDMODE_SRCFACTOR_ST, GX_BP_BLENDMODE_SRCFACTOR_END); + GX_SET_REG(blendModeReg, dst_factor, GX_BP_BLENDMODE_DSTFACTOR_ST, GX_BP_BLENDMODE_DSTFACTOR_END); + + GX_BP_LOAD_REG(blendModeReg); + gx->cmode0 = blendModeReg; + + gx->bpSentNot = FALSE; +} + +/** + * @note Address: 0x800E912C + * @note Size: 0x2C + */ +void GXSetColorUpdate(GXBool updateEnable) +{ + u32 blendModeReg = gx->cmode0; + GX_SET_REG(blendModeReg, updateEnable, GX_BP_BLENDMODE_COLOR_UPDATE_ST, GX_BP_BLENDMODE_COLOR_UPDATE_END); + GX_BP_LOAD_REG(blendModeReg); + gx->cmode0 = blendModeReg; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E9158 + * @note Size: 0x2C + */ +void GXSetAlphaUpdate(GXBool updateEnable) +{ + u32 blendModeReg = gx->cmode0; + GX_SET_REG(blendModeReg, updateEnable, GX_BP_BLENDMODE_ALPHA_UPDATE_ST, GX_BP_BLENDMODE_ALPHA_UPDATE_END); + GX_BP_LOAD_REG(blendModeReg); + gx->cmode0 = blendModeReg; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E9184 + * @note Size: 0x34 + */ +void GXSetZMode(GXBool compareEnable, GXCompare func, GXBool updateEnable) +{ + u32 zModeReg = gx->zmode; + GX_SET_REG(zModeReg, compareEnable, GX_BP_ZMODE_TEST_ENABLE_ST, GX_BP_ZMODE_TEST_ENABLE_END); + GX_SET_REG(zModeReg, func, GX_BP_ZMODE_COMPARE_ST, GX_BP_ZMODE_COMPARE_END); + GX_SET_REG(zModeReg, updateEnable, GX_BP_ZMODE_UPDATE_ENABLE_ST, GX_BP_ZMODE_UPDATE_ENABLE_END); + GX_BP_LOAD_REG(zModeReg); + gx->zmode = zModeReg; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E91B8 + * @note Size: 0x34 + */ +void GXSetZCompLoc(GXBool beforeTex) +{ + GX_SET_REG(gx->peCtrl, beforeTex, GX_BP_ZCONTROL_BEFORE_TEX_ST, GX_BP_ZCONTROL_BEFORE_TEX_END); + GX_BP_LOAD_REG(gx->peCtrl); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E91EC + * @note Size: 0xD4 + */ +void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt16 zFmt) +{ + GXBool isZ16; + static u32 p2f[GX_MAX_PIXELFMT] + = { GX_PF_RGB8_Z24, GX_PF_RGBA6_Z24, GX_PF_RGB565_Z16, GX_PF_Z24, GX_PF_Y8, GX_PF_Y8, GX_PF_Y8, GX_PF_U8 }; + + const u32 zControlRegOld = gx->peCtrl; + + GX_SET_REG(gx->peCtrl, p2f[pixelFmt], GX_BP_ZCONTROL_PIXEL_FMT_ST, GX_BP_ZCONTROL_PIXEL_FMT_END); + GX_SET_REG(gx->peCtrl, zFmt, GX_BP_ZCONTROL_Z_FMT_ST, GX_BP_ZCONTROL_Z_FMT_END); + + if (zControlRegOld != gx->peCtrl) { + GX_BP_LOAD_REG(gx->peCtrl); + isZ16 = (pixelFmt == GX_PF_RGB565_Z16) ? GX_TRUE : GX_FALSE; + GX_SET_REG(gx->genMode, isZ16, GX_BP_GENMODE_MULTISAMPLE_ST, GX_BP_GENMODE_MULTISAMPLE_END); + gx->dirtyState |= GX_DIRTY_GEN_MODE; + } + + if (p2f[pixelFmt] == GX_PF_Y8) { + GX_SET_REG(gx->cmode1, pixelFmt - GX_PF_Y8, GX_BP_DSTALPHA_YUV_FMT_ST, GX_BP_DSTALPHA_YUV_FMT_END); + GX_SET_REG(gx->cmode1, GX_BP_REG_DSTALPHA, 0, 7); + GX_BP_LOAD_REG(gx->cmode1); + } + + gx->bpSentNot = FALSE; +} + +/** + * @note Address: 0x800E92C0 + * @note Size: 0x2C + */ +void GXSetDither(GXBool dither) +{ + u32 blendModeReg = gx->cmode0; + GX_SET_REG(blendModeReg, dither, GX_BP_BLENDMODE_DITHER_ST, GX_BP_BLENDMODE_DITHER_END); + GX_BP_LOAD_REG(blendModeReg); + gx->cmode0 = blendModeReg; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E92EC + * @note Size: 0x3C + */ +void GXSetDstAlpha(GXBool enable, u8 alpha) +{ + u32 dstAlpha = gx->cmode1; + GX_SET_REG(dstAlpha, alpha, GX_BP_DSTALPHA_ALPHA_ST, GX_BP_DSTALPHA_ALPHA_END); + GX_SET_REG(dstAlpha, enable, GX_BP_DSTALPHA_ENABLE_ST, GX_BP_DSTALPHA_ENABLE_END); + GX_BP_LOAD_REG(dstAlpha); + gx->cmode1 = dstAlpha; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E9328 + * @note Size: 0x38 + */ +void GXSetFieldMask(GXBool enableEven, GXBool enableOdd) +{ + u32 fieldMaskReg = 0; + GX_SET_REG(fieldMaskReg, enableOdd, GX_BP_FIELDMASK_ODD_ST, GX_BP_FIELDMASK_ODD_END); + GX_SET_REG(fieldMaskReg, enableEven, GX_BP_FIELDMASK_EVEN_ST, GX_BP_FIELDMASK_EVEN_END); + GX_SET_REG(fieldMaskReg, GX_BP_REG_FIELDMASK, 0, 7); + + GX_BP_LOAD_REG(fieldMaskReg); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E9360 + * @note Size: 0x78 + */ +void GXSetFieldMode(GXBool texLOD, GXBool adjustAR) +{ + GX_SET_REG(gx->lpSize, adjustAR, GX_BP_LINEPTWIDTH_ADJUST_ST, GX_BP_LINEPTWIDTH_ADJUST_END); + GX_BP_LOAD_REG(gx->lpSize); + + __GXFlushTextureState(); + GX_BP_LOAD_REG(GX_BP_REG_FIELDMODE << 24 | texLOD); + __GXFlushTextureState(); +} diff --git a/dolphin sdk not yet linked/src/gx/GXTev.c b/dolphin sdk not yet linked/src/gx/GXTev.c new file mode 100644 index 0000000..86ef401 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXTev.c @@ -0,0 +1,450 @@ +#include "Dolphin/gx.h" + +static u32 TEVCOpTableST0[] = { + 0xC008F8AF, // modulate + 0xC008A89F, // decal + 0xC008AC8F, // blend + 0xC008FFF8, // replace + 0xC008FFFA, // passclr +}; + +static u32 TEVCOpTableST1[] = { + 0xC008F80F, // modulate + 0xC008089F, // decal + 0xC0080C8F, // blend + 0xC008FFF8, // replace + 0xC008FFF0, // passclr +}; + +static u32 TEVAOpTableST0[] = { + 0xC108F2F0, // modulate + 0xC108FFD0, // decal + 0xC108F2F0, // blend + 0xC108FFC0, // replace + 0xC108FFD0, // passclr +}; + +static u32 TEVAOpTableST1[] = { + 0xC108F070, // modulate + 0xC108FF80, // decal + 0xC108F070, // blend + 0xC108FFC0, // replace + 0xC108FF80, // passclr +}; + +/** + * @note Address: 0x800E847C + * @note Size: 0x8C + */ +void GXSetTevOp(GXTevStageID stage, GXTevMode mode) +{ + u32* color; + u32* alpha; + u32 tevReg; + + if (stage == GX_TEVSTAGE0) { + color = &TEVCOpTableST0[mode]; + alpha = &TEVAOpTableST0[mode]; + } else { + color = &TEVCOpTableST1[mode]; + alpha = &TEVAOpTableST1[mode]; + } + + tevReg = gx->tevc[stage]; + tevReg = (*color & ~0xFF000000) | (tevReg & 0xFF000000); + + GX_BP_LOAD_REG(tevReg); + + gx->tevc[stage] = tevReg; + + tevReg = gx->teva[stage]; + tevReg = (*alpha & ~0xFF00000F) | (tevReg & 0xFF00000F); + + GX_BP_LOAD_REG(tevReg); + + gx->teva[stage] = tevReg; + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8508 + * @note Size: 0x44 + */ +void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) +{ + u32 tevReg; + + tevReg = gx->tevc[stage]; + + GX_SET_REG(tevReg, a, 16, 19); + GX_SET_REG(tevReg, b, 20, 23); + GX_SET_REG(tevReg, c, 24, 27); + GX_SET_REG(tevReg, d, 28, 31); + + GX_BP_LOAD_REG(tevReg); + + gx->tevc[stage] = tevReg; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E854C + * @note Size: 0x44 + */ +void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d) +{ + u32 tevReg; + + tevReg = gx->teva[stage]; + + GX_SET_REG(tevReg, a, 16, 18); + GX_SET_REG(tevReg, b, 19, 21); + GX_SET_REG(tevReg, c, 22, 24); + GX_SET_REG(tevReg, d, 25, 27); + + GX_BP_LOAD_REG(tevReg); + + gx->teva[stage] = tevReg; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8590 + * @note Size: 0x68 + */ +void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool doClamp, GXTevRegID outReg) +{ + u32 tevReg; + + tevReg = gx->tevc[stage]; + GX_SET_REG(tevReg, op & 1, 13, 13); + + if (op <= 1) { + GX_SET_REG(tevReg, scale, 10, 11); + GX_SET_REG(tevReg, bias, 14, 15); + } else { + GX_SET_REG(tevReg, (op >> 1) & 3, 10, 11); + GX_SET_REG(tevReg, 3, 14, 15); + } + + GX_SET_REG(tevReg, doClamp, 12, 12); + GX_SET_REG(tevReg, outReg, 8, 9); + + GX_BP_LOAD_REG(tevReg); + + gx->tevc[stage] = tevReg; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E85F8 + * @note Size: 0x68 + */ +void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool doClamp, GXTevRegID outReg) +{ + u32 tevReg; + + tevReg = gx->teva[stage]; + GX_SET_REG(tevReg, op & 1, 13, 13); + + if (op <= 1) { + GX_SET_REG(tevReg, scale, 10, 11); + GX_SET_REG(tevReg, bias, 14, 15); + } else { + GX_SET_REG(tevReg, (op >> 1) & 3, 10, 11); + GX_SET_REG(tevReg, 3, 14, 15); + } + + GX_SET_REG(tevReg, doClamp, 12, 12); + GX_SET_REG(tevReg, outReg, 8, 9); + + GX_BP_LOAD_REG(tevReg); + + gx->teva[stage] = tevReg; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8660 + * @note Size: 0x7C + */ +void GXSetTevColor(GXTevRegID reg, GXColor color) +{ + u32 ra = 0; + u32 bg = 0; + + GX_SET_REG(ra, color.r, 21, 31); + GX_SET_REG(ra, color.a, 9, 19); + GX_SET_REG(bg, color.b, 21, 31); + GX_SET_REG(bg, color.g, 9, 19); + + GX_SET_REG(ra, 0xE0 + reg * 2, 0, 7); + GX_SET_REG(bg, 0xE1 + reg * 2, 0, 7); + + GX_BP_LOAD_REG(ra); + GX_BP_LOAD_REG(bg); + GX_BP_LOAD_REG(bg); + GX_BP_LOAD_REG(bg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E86DC + * @note Size: 0x7C + */ +void GXSetTevColorS10(GXTevRegID reg, GXColorS10 color) +{ + u32 ra, bg; + + ra = 0; + GX_SET_REG(ra, color.r & 0x7ff, 21, 31); + GX_SET_REG(ra, color.a & 0x7ff, 9, 19); + GX_SET_REG(ra, GX_BP_REG_TEVREG0LO + reg * 2, 0, 7); + + bg = 0; + GX_SET_REG(bg, color.b & 0x7ff, 21, 31); + GX_SET_REG(bg, color.g & 0x7ff, 9, 19); + GX_SET_REG(bg, GX_BP_REG_TEVREG0HI + reg * 2, 0, 7); + + GX_BP_LOAD_REG(ra); + + GX_BP_LOAD_REG(bg); + GX_BP_LOAD_REG(bg); + GX_BP_LOAD_REG(bg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8758 + * @note Size: 0x74 + */ +void GXSetTevKColor(GXTevKColorID id, GXColor color) +{ + u32 ra; + u32 bg; + + ra = 0; + GX_SET_REG(ra, color.r, 24, 31); + GX_SET_REG(ra, color.a, 12, 19); + GX_SET_REG(ra, 8, 8, 11); + GX_SET_REG(ra, 0xE0 + id * 2, 0, 7); + + bg = 0; + GX_SET_REG(bg, color.b, 24, 31); + GX_SET_REG(bg, color.g, 12, 19); + GX_SET_REG(bg, 8, 8, 11); + GX_SET_REG(bg, 0xE1 + id * 2, 0, 7); + + GX_BP_LOAD_REG(ra); + GX_BP_LOAD_REG(bg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E87CC + * @note Size: 0x5C + */ +void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel) +{ + u32* reg; + + reg = &gx->tevKsel[stage >> 1]; + + if (stage & 1) { + GX_SET_REG(*reg, sel, 13, 17); + } else { + GX_SET_REG(*reg, sel, 23, 27); + } + + GX_BP_LOAD_REG(*reg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8828 + * @note Size: 0x5C + */ +void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel) +{ + u32* reg; + + reg = &gx->tevKsel[stage >> 1]; + + if (stage & 1) { + GX_SET_REG(*reg, sel, 8, 12); + } else { + GX_SET_REG(*reg, sel, 18, 22); + } + + GX_BP_LOAD_REG(*reg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8884 + * @note Size: 0x48 + */ +void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel rasSel, GXTevSwapSel texSel) +{ + u32* reg = &gx->teva[stage]; + GX_SET_REG(*reg, rasSel, 30, 31); + GX_SET_REG(*reg, texSel, 28, 29); + + GX_BP_LOAD_REG(*reg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E88CC + * @note Size: 0x80 + */ +void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, GXTevColorChan blue, GXTevColorChan alpha) +{ + u32* reg; + + reg = &gx->tevKsel[table << 1]; + GX_SET_REG(*reg, red, 30, 31); + GX_SET_REG(*reg, green, 28, 29); + + GX_BP_LOAD_REG(*reg); + + reg = &gx->tevKsel[(table << 1) + 1]; + GX_SET_REG(*reg, blue, 30, 31); + GX_SET_REG(*reg, alpha, 28, 29); + + GX_BP_LOAD_REG(*reg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: N/A + * @note Size: 0x4 + */ +void GXSetTevClampMode(GXTevStageID stage, GXTevClampMode mode) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E894C + * @note Size: 0x44 + */ +void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) +{ + u32 reg = 0xF3000000; + + GX_SET_REG(reg, ref0, 24, 31); + GX_SET_REG(reg, ref1, 16, 23); + GX_SET_REG(reg, comp0, 13, 15); + GX_SET_REG(reg, comp1, 10, 12); + GX_SET_REG(reg, op, 8, 9); + + GX_BP_LOAD_REG(reg); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8990 + * @note Size: 0x8C + */ +void GXSetZTexture(GXZTexOp op, GXTexFmt format, u32 bias) +{ + u32 val1; + u32 val2; + u32 val3; + + val1 = 0; + GX_SET_REG(val1, bias, 8, 31); + GX_SET_REG(val1, 0xF4, 0, 7); + + val2 = 0; + switch (format) { + case GX_TF_Z8: + val3 = 0; + break; + case GX_TF_Z16: + val3 = 1; + break; + case GX_TF_Z24X8: + val3 = 2; + break; + default: + val3 = 2; + break; + } + + GX_SET_REG(val2, val3, 30, 31); + GX_SET_REG(val2, op, 28, 29); + GX_SET_REG(val2, 0xF5, 0, 7); + + GX_BP_LOAD_REG(val1); + + GX_BP_LOAD_REG(val2); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E8A1C + * @note Size: 0x19C + */ +void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color) +{ + static int c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6 }; + + u32* reg; + u32 tempMap; + u32 tempCoord; + + reg = &gx->tref[stage / 2]; + gx->texmapId[stage] = map; + + tempMap = map & ~0x100; + tempMap = (tempMap >= GX_MAX_TEXMAP) ? GX_TEXMAP0 : tempMap; + + if (coord >= GX_MAX_TEXCOORD) { + tempCoord = GX_TEXCOORD0; + gx->tevTcEnab = gx->tevTcEnab & ~(1 << stage); + } else { + tempCoord = coord; + gx->tevTcEnab = gx->tevTcEnab | (1 << stage); + } + + if (stage & 1) { + GX_SET_REG(*reg, tempMap, 17, 19); + GX_SET_REG(*reg, tempCoord, 14, 16); + GX_SET_REG(*reg, (color == GX_COLOR_NULL ? 7 : c2r[color]), 10, 12); + GX_SET_REG(*reg, ((map != GX_TEXMAP_NULL) && !(map & 0x100)), 13, 13); + + } else { + GX_SET_REG(*reg, tempMap, 29, 31); + GX_SET_REG(*reg, tempCoord, 26, 28); + GX_SET_REG(*reg, (color == GX_COLOR_NULL ? 7 : c2r[color]), 22, 24); + GX_SET_REG(*reg, ((map != GX_TEXMAP_NULL) && !(map & 0x100)), 25, 25); + } + + GX_BP_LOAD_REG(*reg); + + gx->bpSentNot = GX_FALSE; + gx->dirtyState |= 1; +} + +/** + * @note Address: 0x800E8BB8 + * @note Size: 0x28 + */ +void GXSetNumTevStages(u8 count) +{ + GX_SET_REG(gx->genMode, count - 1, 18, 21); + + gx->dirtyState |= 0x4; +} diff --git a/dolphin sdk not yet linked/src/gx/GXTexture.c b/dolphin sdk not yet linked/src/gx/GXTexture.c new file mode 100644 index 0000000..c5c79a8 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXTexture.c @@ -0,0 +1,1036 @@ +#include "Dolphin/gx.h" + +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 }; + +u8 GX2HWFiltConv[6] = { 0x00, 0x04, 0x01, 0x05, 0x02, 0x06 }; + +#define GET_TILE_COUNT(a, b) (((a) + (1 << (b)) - 1) >> (b)) + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +inline void __GXGetTexTileShift(GXTexFmt format, u32* widthTiles, u32* heightTiles) +{ + switch (format) { + case GX_TF_I4: + case GX_TF_C4: + case GX_TF_CMPR: + case GX_CTF_R4: + case GX_CTF_Z4: + *widthTiles = 3; + *heightTiles = 3; + break; + + case GX_TF_I8: + case GX_TF_IA4: + case GX_TF_C8: + case GX_TF_Z8: + case GX_CTF_RA4: + case GX_CTF_R8: + case GX_CTF_G8: + case GX_CTF_B8: + case GX_CTF_RG8: + case GX_CTF_Z8M: + case GX_CTF_Z8L: + *widthTiles = 3; + *heightTiles = 2; + break; + + case GX_TF_IA8: + case GX_TF_RGB565: + case GX_TF_RGB5A3: + case GX_TF_RGBA8: + case GX_TF_C14X2: + case GX_TF_Z16: + case GX_TF_Z24X8: + case GX_CTF_RA8: + case GX_CTF_GB8: + case 44: + case GX_CTF_Z16L: + *widthTiles = 2; + *heightTiles = 2; + break; + + default: + *heightTiles = 0; + *widthTiles = 0; + break; + } +} + +/** + * @note Address: 0x800E6F58 + * @note Size: 0x15C + */ +u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod) +{ + u32 widthTiles, heightTiles, tileSize, bufferSize, numX, numY, i; + + __GXGetTexTileShift(format, &widthTiles, &heightTiles); + + if (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) { + tileSize = 0x40; + } else { + tileSize = 0x20; + } + + if (mipmap == GX_TRUE) { + + bufferSize = 0; + + for (i = 0; i < max_lod; i++) { + numX = GET_TILE_COUNT(width, widthTiles); + numY = GET_TILE_COUNT(height, heightTiles); + + bufferSize += numX * numY * tileSize; + if (width == 1 && height == 1) { + break; + } + + width = (width > 1) ? (width >> 1) : 1; + height = (height > 1) ? (height >> 1) : 1; + } + + } else { + numX = GET_TILE_COUNT(width, widthTiles); + numY = GET_TILE_COUNT(height, heightTiles); + bufferSize = numX * numY * tileSize; + } + + return bufferSize; +} + +/** + * @note Address: 0x800E70B4 + * @note Size: 0xC8 + */ +void __GetImageTileCount(GXTexFmt format, u16 width, u16 height, u32* a, u32* b, u32* c) +{ + u32 widthTiles, heightTiles; + + __GXGetTexTileShift(format, &widthTiles, &heightTiles); + + if (width <= 0) { + width = 1; + } + + if (height <= 0) { + height = 1; + } + + *a = GET_TILE_COUNT(width, widthTiles); + *b = GET_TILE_COUNT(height, heightTiles); + *c = (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) ? 2 : 1; +} + +/** + * @note Address: 0x800E717C + * @note Size: 0x24C + */ +void GXInitTexObj(GXTexObj* obj, void* imagePtr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode sWrap, GXTexWrapMode tWrap, + GXBool useMIPmap) +{ + u32 imageBase; + u16 a, b; + u32 c, d; + + GXTexObjPriv* internal = (GXTexObjPriv*)obj; + memset(internal, 0, sizeof(*internal)); + + GX_SET_REG(internal->mode0, sWrap, 30, 31); + GX_SET_REG(internal->mode0, tWrap, 28, 29); + GX_SET_REG(internal->mode0, GX_TRUE, 27, 27); + + if (useMIPmap) { + u32 maxDimSize; + internal->flags |= 1; + if (format == 8 || format == 9 || format == 10) { + GX_SET_REG(internal->mode0, 5, 24, 26); + } else { + GX_SET_REG(internal->mode0, 6, 24, 26); + } + + maxDimSize = width > height ? 31 - __cntlzw(width) : 31 - __cntlzw(height); + + GX_SET_REG(internal->mode1, (maxDimSize) * 16.f, 16, 23); + } else { + GX_SET_REG(internal->mode0, 4, 24, 26); + } + + internal->format = format; + GX_SET_REG(internal->image0, width - 1, 22, 31); + GX_SET_REG(internal->image0, height - 1, 12, 21); + + GX_SET_REG(internal->image0, format & 0xf, 8, 11); + imageBase = (u32)imagePtr >> 5; + GX_SET_REG(internal->image3, imageBase, 11, 31); + + switch (format & 0xf) { + case 0: + case 8: + internal->loadFormat = 1; + a = 3; + b = 3; + break; + case 1: + case 2: + case 9: + internal->loadFormat = 2; + a = 3; + b = 2; + break; + case 3: + case 4: + case 5: + case 10: + internal->loadFormat = 2; + a = 2; + b = 2; + break; + case 6: + internal->loadFormat = 3; + a = 2; + b = 2; + break; + case 0xe: + internal->loadFormat = 0; + a = 3; + b = 3; + break; + default: + internal->loadFormat = 2; + a = 2; + b = 2; + break; + } + + internal->loadCount = (GET_TILE_COUNT(width, a) * GET_TILE_COUNT(height, b)) & 0x7fff; + + internal->flags |= 2; +} + +/** + * @note Address: 0x800E73C8 + * @note Size: 0x48 + */ +void GXInitTexObjCI(GXTexObj* obj, void* imagePtr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode sWrap, GXTexWrapMode tWrap, + GXBool useMIPmap, u32 tlutName) +{ + GXTexObjPriv* internal = (GXTexObjPriv*)obj; + + GXInitTexObj(obj, imagePtr, width, height, format, sWrap, tWrap, useMIPmap); + + internal->flags &= ~2; + internal->tlutName = tlutName; +} + +/** + * @note Address: 0x800E7410 + * @note Size: 0x164 + */ +void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilter, GXTexFilter maxFilter, f32 minLOD, f32 maxLOD, f32 lodBias, GXBool doBiasClamp, + GXBool doEdgeLOD, GXAnisotropy maxAniso) +{ + GXTexObjPriv* internal = (GXTexObjPriv*)obj; + u8 reg1, reg2; + if (lodBias < -4.0f) { + lodBias = -4.0f; + } else if (lodBias >= 4.0f) { + lodBias = 3.99f; + } + + GX_SET_REG(internal->mode0, lodBias * 32.0f, 15, 22); + GX_SET_REG(internal->mode0, maxFilter == 1 ? 1 : 0, 27, 27); + GX_SET_REG(internal->mode0, GX2HWFiltConv[minFilter], 24, 26); + GX_SET_REG(internal->mode0, doEdgeLOD ? 0 : 1, 23, 23); + GX_SET_REG(internal->mode0, 0, 14, 14); + GX_SET_REG(internal->mode0, 0, 13, 13); + GX_SET_REG(internal->mode0, maxAniso, 11, 12); + GX_SET_REG(internal->mode0, doBiasClamp, 10, 10); + + if (minLOD < 0.0f) { + minLOD = 0.0f; + } else if (minLOD > 10.0f) { + minLOD = 10.0f; + } + reg1 = minLOD * 16.0f; + + if (maxLOD < 0.0f) { + maxLOD = 0.0f; + } else if (maxLOD > 10.0f) { + maxLOD = 10.0f; + } + reg2 = maxLOD * 16.0f; + + GX_SET_REG(internal->mode1, reg1, 24, 31); + GX_SET_REG(internal->mode1, reg2, 16, 23); +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void GXInitTexObjData(GXTexObj* obj, void* imagePtr) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode sWrap, GXTexWrapMode tWrap) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void GXInitTexObjTlut(GXTexObj* obj, u32 tlutName) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +void GXInitTexObjFilter(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x50 + */ +void GXInitTexObjMaxLOD(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x50 + */ +void GXInitTexObjMinLOD(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +void GXInitTexObjLODBias(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x14 + */ +void GXInitTexObjBiasClamp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void GXInitTexObjEdgeLOD(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void GXInitTexObjMaxAniso(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void GXInitTexObjUserData(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void GXGetTexObjUserData(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x68 + */ +void GXGetTexObjAll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetTexObjData(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void GXGetTexObjWidth(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +void GXGetTexObjHeight(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E7574 + * @note Size: 0x8 + */ +GXTexFmt GXGetTexObjFmt(GXTexObj* obj) +{ + GXTexObjPriv* pObj = (GXTexObjPriv*)obj; + return pObj->format; +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetTexObjWrapS(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetTexObjWrapT(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E757C + * @note Size: 0x18 + */ +GXBool GXGetTexObjMipMap(GXTexObj* obj) +{ + GXTexObjPriv* internal = (GXTexObjPriv*)obj; + return (internal->flags & 1) == 1; +} + +/** + * @note Address: N/A + * @note Size: 0xE4 + */ +void GXGetTexObjLODAll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x14 + */ +void GXGetTexObjMinFilt(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetTexObjMagFilt(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void GXGetTexObjMinLOD(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void GXGetTexObjMaxLOD(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x40 + */ +void GXGetTexObjLODBias(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetTexObjBiasClamp(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x14 + */ +void GXGetTexObjEdgeLOD(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetTexObjMaxAniso(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void GXGetTexObjTlut(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E7594 + * @note Size: 0x17C + */ + +void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID map) +{ + u8 stackManipulation[0x18]; + + GXTexObjPriv* internalObj = (GXTexObjPriv*)obj; + GXTexRegionPriv* internalRegion = (GXTexRegionPriv*)region; + + GX_SET_REG(internalObj->mode0, GXTexMode0Ids[map], 0, 7); + GX_SET_REG(internalObj->mode1, GXTexMode1Ids[map], 0, 7); + GX_SET_REG(internalObj->image0, GXTexImage0Ids[map], 0, 7); + + GX_SET_REG(internalRegion->unk0, GXTexImage1Ids[map], 0, 7); + GX_SET_REG(internalRegion->unk4, GXTexImage2Ids[map], 0, 7); + + GX_SET_REG(internalObj->image3, GXTexImage3Ids[map], 0, 7); + + GX_BP_LOAD_REG(internalObj->mode0); + GX_BP_LOAD_REG(internalObj->mode1); + GX_BP_LOAD_REG(internalObj->image0); + GX_BP_LOAD_REG(internalRegion->unk0); + GX_BP_LOAD_REG(internalRegion->unk4); + GX_BP_LOAD_REG(internalObj->image3); + + if ((internalObj->flags & 2) == 0) { + GXTlutObjPriv* tlut = (GXTlutObjPriv*)gx->tlutRegionCallback(internalObj->tlutName); + GX_SET_REG(tlut->unk4, GXTexTlutIds[map], 0, 7); + + GX_BP_LOAD_REG(tlut->unk4); + } + + gx->tImage0[map] = internalObj->image0; + gx->tMode0[map] = internalObj->mode0; + + gx->dirtyState |= GX_DIRTY_SU_TEX; + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E7710 + * @note Size: 0x54 + */ +void GXLoadTexObj(GXTexObj* obj, GXTexMapID map) +{ + GXTexRegion* ret = (GXTexRegion*)gx->texRegionCallback(obj, map); + + GXLoadTexObjPreLoaded(obj, ret, map); +} + +/** + * @note Address: 0x800E7764 + * @note Size: 0x38 + */ +void GXInitTlutObj(GXTlutObj* obj, void* table, GXTlutFmt format, u16 numEntries) +{ + GXTlutObjPriv* internal = (GXTlutObjPriv*)obj; + + internal->unk0 = 0; + + GX_SET_REG(internal->unk0, format, 20, 21); + GX_SET_REG(internal->unk4, (u32)table >> 5, 11, 31); + GX_SET_REG(internal->unk4, 100, 0, 7); + + internal->numEntries = numEntries; +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void GXGetTlutObjAll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetTlutObjData(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void GXGetTlutObjFmt(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void GXGetTlutObjNumEntries(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E779C + * @note Size: 0x98 + */ +void GXLoadTlut(GXTlutObj* obj, u32 tlutName) +{ + GXTlutObjPriv* internal = (GXTlutObjPriv*)obj; + GXTlutRegionPriv* ret = (GXTlutRegionPriv*)gx->tlutRegionCallback(tlutName); + u32 reg; + + __GXFlushTextureState(); + + GX_BP_LOAD_REG(internal->unk4); + GX_BP_LOAD_REG(ret->unk0); + + __GXFlushTextureState(); + + reg = ret->unk0; + GX_SET_REG(internal->unk0, reg, 22, 31); + + ret->tlutObj = *internal; +} + +/** + * @note Address: 0x800E7834 + * @note Size: 0xF4 + */ +void GXInitTexCacheRegion(GXTexRegion* region, GXBool is32bMIPmap, u32 memEven, GXTexCacheSize sizeEven, u32 memOdd, GXTexCacheSize sizeOdd) +{ + GXTexRegionPriv* internal = (GXTexRegionPriv*)region; + + u32 reg; + switch (sizeEven) { + case 0: + reg = 3; + break; + case 1: + reg = 4; + break; + case 2: + reg = 5; + break; + } + + internal->unk0 = 0; + + GX_SET_REG(internal->unk0, memEven >> 5, 17, 31); + GX_SET_REG(internal->unk0, reg, 14, 16); + GX_SET_REG(internal->unk0, reg, 11, 13); + GX_SET_REG(internal->unk0, 0, 10, 10); + + switch (sizeOdd) { + case 0: + reg = 3; + break; + case 1: + reg = 4; + break; + case 2: + reg = 5; + break; + case 3: + reg = 0; + break; + } + + internal->unk4 = 0; + GX_SET_REG(internal->unk4, memOdd >> 5, 17, 31); + GX_SET_REG(internal->unk4, reg, 14, 16); + GX_SET_REG(internal->unk4, reg, 11, 13); + + internal->unkC = is32bMIPmap; + internal->unkD = 1; +} + +/** + * @note Address: N/A + * @note Size: 0x84 + */ +void GXInitTexPreLoadRegion(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x10C + */ +void GXGetTexRegionAll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E7928 + * @note Size: 0x38 + */ +void GXInitTlutRegion(GXTlutRegion* region, u32 memAddr, GXTlutSize tlutSize) +{ + GXTlutRegionPriv* internal = (GXTlutRegionPriv*)region; + + internal->unk0 = 0; + GX_SET_REG(internal->unk0, (memAddr - 0x80000) >> 9, 22, 31); + GX_SET_REG(internal->unk0, tlutSize, 11, 21); + GX_SET_REG(internal->unk0, 0x65, 0, 7); +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void GXGetTlutRegionAll(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x12C + */ +void GXInvalidateTexRegion(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E7960 + * @note Size: 0x48 + */ +void GXInvalidateTexAll(void) +{ + __GXFlushTextureState(); + GX_BP_LOAD_REG(0x66001000); + GX_BP_LOAD_REG(0x66001100); + __GXFlushTextureState(); +} + +/** + * @note Address: 0x800E79A8 + * @note Size: 0x14 + */ +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback func) +{ + GXTexRegionCallback oldFunc = gx->texRegionCallback; + + gx->texRegionCallback = func; + + return oldFunc; +} + +/** + * @note Address: 0x800E79BC + * @note Size: 0x14 + */ +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback func) +{ + GXTlutRegionCallback oldFunc = gx->tlutRegionCallback; + + gx->tlutRegionCallback = func; + + return oldFunc; +} + +/** + * @note Address: N/A + * @note Size: 0x264 + */ +void GXPreLoadEntireTexture(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void GXSetTexCoordScaleManually(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +void GXSetTexCoordCylWrap(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +void GXSetTexCoordBias(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E79D0 + * @note Size: 0xA0 + */ +void __SetSURegs(u32 texImgIndex, u32 setUpRegIndex) +{ + u16 a1, a2; + GXBool b, c; + + a1 = GX_GET_REG(gx->tImage0[texImgIndex], 22, 31); + // a2 = GX_GET_REG(gx->tImage0[texImgIndex], 12, 21); + a2 = (gx->tImage0[texImgIndex] & (0x3ff << 10)) >> 10; + + GX_SET_REG(gx->suTs0[setUpRegIndex], a1, 16, 31); + GX_SET_REG(gx->suTs1[setUpRegIndex], a2, 16, 31); + + b = GX_GET_REG(gx->tMode0[texImgIndex], 30, 31) == 1; + c = GX_GET_REG(gx->tMode0[texImgIndex], 28, 29) == 1; + + GX_SET_REG(gx->suTs0[setUpRegIndex], b, 15, 15); + GX_SET_REG(gx->suTs1[setUpRegIndex], c, 15, 15); + + GX_BP_LOAD_REG(gx->suTs0[setUpRegIndex]); + GX_BP_LOAD_REG(gx->suTs1[setUpRegIndex]); + + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E7A70 + * @note Size: 0x17C + */ +#pragma dont_inline on +void __GXSetSUTexRegs(void) +{ + u32 i; + u32 b; + u32 a; + u32 c; + u32 d; + u32 stackFiller; + if (gx->tcsManEnab != 0xff) { + a = GX_GET_REG(gx->genMode, 18, 21) + 1; + b = GX_GET_REG(gx->genMode, 13, 15); + for (i = 0; i < b; i++) { + switch (i) { + case 0: + c = GX_GET_REG(gx->iref, 29, 31); + d = GX_GET_REG(gx->iref, 26, 28); + break; + case 1: + c = GX_GET_REG(gx->iref, 23, 25); + d = GX_GET_REG(gx->iref, 20, 22); + break; + case 2: + c = GX_GET_REG(gx->iref, 17, 19); + d = GX_GET_REG(gx->iref, 14, 16); + break; + case 3: + c = GX_GET_REG(gx->iref, 11, 13); + d = GX_GET_REG(gx->iref, 8, 10); + break; + } + + if (!(gx->tcsManEnab & (1 << d))) { + __SetSURegs(c, d); + } + } + + for (i = 0; i < a; i++) { + u32* g = &gx->tref[i / 2]; + + c = gx->texmapId[i] & ~0x100; + + if (i & 1) { + d = GX_GET_REG(*g, 14, 16); + } else { + d = GX_GET_REG(*g, 26, 28); + } + + if (c != 0xff && !(gx->tcsManEnab & (1 << d)) && gx->tevTcEnab & (1 << i)) { + __SetSURegs(c, d); + } + } + } +} +#pragma dont_inline reset + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +void __GXGetSUTexSize(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E7BEC + * @note Size: 0x354 + */ +void __GXSetTmemConfig(u32 config) +{ + switch (config) { + case 2: + GX_BP_LOAD_REG(0x8c0d8000); + GX_BP_LOAD_REG(0x900dc000); + + GX_BP_LOAD_REG(0x8d0d8800); + GX_BP_LOAD_REG(0x910dc800); + + GX_BP_LOAD_REG(0x8e0d9000); + GX_BP_LOAD_REG(0x920dd000); + + GX_BP_LOAD_REG(0x8f0d9800); + GX_BP_LOAD_REG(0x930dd800); + + GX_BP_LOAD_REG(0xac0da000); + GX_BP_LOAD_REG(0xb00dc400); + + GX_BP_LOAD_REG(0xad0da800); + GX_BP_LOAD_REG(0xb10dcc00); + + GX_BP_LOAD_REG(0xae0db000); + GX_BP_LOAD_REG(0xb20dd400); + + GX_BP_LOAD_REG(0xaf0db800); + GX_BP_LOAD_REG(0xb30ddc00); + break; + case 1: + GX_BP_LOAD_REG(0x8c0d8000); + GX_BP_LOAD_REG(0x900dc000); + + GX_BP_LOAD_REG(0x8d0d8800); + GX_BP_LOAD_REG(0x910dc800); + + GX_BP_LOAD_REG(0x8e0d9000); + GX_BP_LOAD_REG(0x920dd000); + + GX_BP_LOAD_REG(0x8f0d9800); + GX_BP_LOAD_REG(0x930dd800); + + GX_BP_LOAD_REG(0xac0da000); + GX_BP_LOAD_REG(0xb00de000); + + GX_BP_LOAD_REG(0xad0da800); + GX_BP_LOAD_REG(0xb10de800); + + GX_BP_LOAD_REG(0xae0db000); + GX_BP_LOAD_REG(0xb20df000); + + GX_BP_LOAD_REG(0xaf0db800); + GX_BP_LOAD_REG(0xb30df800); + + break; + case 0: + default: + GX_BP_LOAD_REG(0x8c0d8000); + GX_BP_LOAD_REG(0x900dc000); + + GX_BP_LOAD_REG(0x8d0d8400); + GX_BP_LOAD_REG(0x910dc400); + + GX_BP_LOAD_REG(0x8e0d8800); + GX_BP_LOAD_REG(0x920dc800); + + GX_BP_LOAD_REG(0x8f0d8c00); + GX_BP_LOAD_REG(0x930dcc00); + + GX_BP_LOAD_REG(0xac0d9000); + GX_BP_LOAD_REG(0xb00dd000); + + GX_BP_LOAD_REG(0xad0d9400); + GX_BP_LOAD_REG(0xb10dd400); + + GX_BP_LOAD_REG(0xae0d9800); + GX_BP_LOAD_REG(0xb20dd800); + + GX_BP_LOAD_REG(0xaf0d9c00); + GX_BP_LOAD_REG(0xb30ddc00); + + break; + } +} diff --git a/dolphin sdk not yet linked/src/gx/GXTransform.c b/dolphin sdk not yet linked/src/gx/GXTransform.c new file mode 100644 index 0000000..27b36a7 --- /dev/null +++ b/dolphin sdk not yet linked/src/gx/GXTransform.c @@ -0,0 +1,452 @@ +#include "Dolphin/gx.h" + +/** + * @note Address: N/A + * @note Size: 0x174 + */ +void GXProject(f32 x, f32 y, f32 z, Mtx viewMtx, f32* projMtx, f32* viewport, f32* screenX, f32* screenY, f32* screenZ) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +static void WriteProjPS(const register f32 src[6], register volatile void* dst) +{ + register f32 ps_0, ps_1, ps_2; + +#ifdef __MWERKS__ // clang-format off + asm { + psq_l ps_0, 0(src), 0, 0 + psq_l ps_1, 8(src), 0, 0 + psq_l ps_2, 16(src), 0, 0 + psq_st ps_0, 0(dst), 0, 0 + psq_st ps_1, 0(dst), 0, 0 + psq_st ps_2, 0(dst), 0, 0 + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +static void Copy6Floats(const register f32 src[6], register f32 dst[6]) +{ + register f32 ps_0, ps_1, ps_2; + +#ifdef __MWERKS__ // clang-format off + asm { + psq_l ps_0, 0(src), 0, 0 + psq_l ps_1, 8(src), 0, 0 + psq_l ps_2, 16(src), 0, 0 + psq_st ps_0, 0(dst), 0, 0 + psq_st ps_1, 8(dst), 0, 0 + psq_st ps_2, 16(dst), 0, 0 + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x48 + */ +void __GXSetProjection(void) +{ + GX_XF_LOAD_REGS(6, GX_XF_REG_PROJECTIONA); + WriteProjPS(gx->projMtx, (volatile void*)GXFIFO_ADDR); + GX_WRITE_U32(gx->projType); +} + +/** + * @note Address: 0x800E9448 + * @note Size: 0xA4 + */ +void GXSetProjection(const Mtx44 proj, GXProjectionType type) +{ + gx->projType = type; + + gx->projMtx[0] = proj[0][0]; + gx->projMtx[2] = proj[1][1]; + gx->projMtx[4] = proj[2][2]; + gx->projMtx[5] = proj[2][3]; + + if (type == GX_ORTHOGRAPHIC) { + gx->projMtx[1] = proj[0][3]; + gx->projMtx[3] = proj[1][3]; + } else { + gx->projMtx[1] = proj[0][2]; + gx->projMtx[3] = proj[1][2]; + } + + __GXSetProjection(); + + gx->bpSentNot = GX_TRUE; +} + +/** + * @note Address: 0x800E94EC + * @note Size: 0x8C + */ +void GXSetProjectionv(const f32* proj) +{ + gx->projType = proj[0] == 0.0f ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC; + Copy6Floats(&proj[1], gx->projMtx); + + __GXSetProjection(); + gx->bpSentNot = GX_TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0x48 + */ +void GXGetProjectionv(f32* ptr) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void WriteMTXPS4x3(register volatile void* dst, register const Mtx src) +{ + register f32 ps_0, ps_1, ps_2, ps_3, ps_4, ps_5; + +#ifdef __MWERKS__ // clang-format off + asm { + psq_l ps_0, 0(src), 0, 0 + psq_l ps_1, 8(src), 0, 0 + psq_l ps_2, 16(src), 0, 0 + psq_l ps_3, 24(src), 0, 0 + psq_l ps_4, 32(src), 0, 0 + psq_l ps_5, 40(src), 0, 0 + + psq_st ps_0, 0(dst), 0, 0 + psq_st ps_1, 0(dst), 0, 0 + psq_st ps_2, 0(dst), 0, 0 + psq_st ps_3, 0(dst), 0, 0 + psq_st ps_4, 0(dst), 0, 0 + psq_st ps_5, 0(dst), 0, 0 + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void WriteMTXPS3x3from3x4(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +void WriteMTXPS3x3(register volatile void* dst, register const Mtx src) +{ + register f32 ps_0, ps_1, ps_2, ps_3, ps_4, ps_5; + +#ifdef __MWERKS__ // clang-format off + asm { + psq_l ps_0, 0(src), 0, 0 + lfs ps_1, 8(src) + psq_l ps_2, 16(src), 0, 0 + lfs ps_3, 24(src) + psq_l ps_4, 32(src), 0, 0 + lfs ps_5, 40(src) + + psq_st ps_0, 0(dst), 0, 0 + stfs ps_1, 0(dst) + psq_st ps_2, 0(dst), 0, 0 + stfs ps_3, 0(dst) + psq_st ps_4, 0(dst), 0, 0 + stfs ps_5, 0(dst) + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void WriteMTXPS4x2(register volatile void* dst, register const Mtx src) +{ + register f32 ps_0, ps_1, ps_2, ps_3; + +#ifdef __MWERKS__ // clang-format off + asm { + psq_l ps_0, 0(src), 0, 0 + psq_l ps_1, 8(src), 0, 0 + psq_l ps_2, 16(src), 0, 0 + psq_l ps_3, 24(src), 0, 0 + + psq_st ps_0, 0(dst), 0, 0 + psq_st ps_1, 0(dst), 0, 0 + psq_st ps_2, 0(dst), 0, 0 + psq_st ps_3, 0(dst), 0, 0 + } +#endif // clang-format on +} + +/** + * @note Address: 0x800E9578 + * @note Size: 0x50 + */ +void GXLoadPosMtxImm(Mtx mtx, u32 id) +{ + GX_XF_LOAD_REGS(4 * 3 - 1, id * 4 + GX_XF_MEM_POSMTX); + WriteMTXPS4x3(&GXWGFifo, mtx); +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +void GXLoadPosMtxIndx(u16 index, u32 id) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E95C8 + * @note Size: 0x50 + */ +void GXLoadNrmMtxImm(Mtx mtx, u32 id) +{ + GX_XF_LOAD_REGS(3 * 3 - 1, id * 3 + GX_XF_MEM_NRMMTX); + WriteMTXPS3x3(&GXWGFifo, mtx); +} + +/** + * @note Address: N/A + * @note Size: 0x48 + */ +void GXLoadNrmMtxImm3x3(Mtx33, u32 id) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void GXLoadNrmMtxIndx3x3(u16 index, u32 id) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E9618 + * @note Size: 0x34 + */ +void GXSetCurrentMtx(u32 id) +{ + GX_SET_REG(gx->matIdxA, id, GX_XF_MTXIDX0_GEOM_ST, GX_XF_MTXIDX0_GEOM_END); + __GXSetMatrixIndex(GX_VA_PNMTXIDX); +} + +/** + * @note Address: 0x800E964C + * @note Size: 0xB4 + */ +void GXLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type) +{ + u32 addr; + u32 num; + u32 reg; + + // Matrix address in XF memory + addr = id >= GX_PTTEXMTX0 ? (id - GX_PTTEXMTX0) * 4 + GX_XF_MEM_DUALTEXMTX : id * 4 + (u64)GX_XF_MEM_POSMTX; + + // Number of elements in matrix + num = type == GX_MTX2x4 ? (u64)(2 * 4) : 3 * 4; + + reg = addr | (num - 1) << 16; + + GX_XF_LOAD_REG_HDR(reg); + + if (type == GX_MTX3x4) { + WriteMTXPS4x3(&GXWGFifo, mtx); + } else { + WriteMTXPS4x2(&GXWGFifo, mtx); + } +} + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +void GXLoadTexMtxIndx(u16 index, u32 id, GXTexMtxType type) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E9700 + * @note Size: 0x90 + */ +void __GXSetViewport(void) +{ + f32 a, b, c, d, e, f; + f32 near, far; + + a = gx->vpWd / 2.0f; + b = -gx->vpHt / 2.0f; + d = gx->vpLeft + (gx->vpWd / 2.0f) + 342.0f; + e = gx->vpTop + (gx->vpHt / 2.0f) + 342.0f; + + near = gx->vpNearz * gx->zScale; + far = gx->vpFarz * gx->zScale; + + c = far - near; + f = far + gx->zOffset; + + GX_XF_LOAD_REGS(5, GX_XF_REG_SCALEX); + GX_WRITE_F32(a); + GX_WRITE_F32(b); + GX_WRITE_F32(c); + GX_WRITE_F32(d); + GX_WRITE_F32(e); + GX_WRITE_F32(f); +} + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +void GXSetViewportJitter(f32 left, f32 top, f32 width, f32 height, f32 nearZ, f32 farZ, u32 field) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E9790 + * @note Size: 0x48 + */ +void GXSetViewport(f32 left, f32 top, f32 width, f32 height, f32 nearZ, f32 farZ) +{ + gx->vpLeft = left; + gx->vpTop = top; + gx->vpWd = width; + gx->vpHt = height; + gx->vpNearz = nearZ; + gx->vpFarz = farZ; + __GXSetViewport(); + gx->bpSentNot = GX_TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void GXGetViewportv(f32* viewport) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x6C + */ +void GXSetZScaleOffset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800E97D8 + * @note Size: 0x78 + */ +void GXSetScissor(u32 left, u32 top, u32 width, u32 height) +{ + u32 y1, x1, y2, x2; + u32 reg; + + y1 = top + 342; + x1 = left + 342; + + GX_SET_REG(gx->suScis0, y1, GX_BP_SCISSORTL_TOP_ST, GX_BP_SCISSORTL_TOP_END); + GX_SET_REG(gx->suScis0, x1, GX_BP_SCISSORTL_LEFT_ST, GX_BP_SCISSORTL_LEFT_END); + + y2 = y1 + height - 1; + x2 = x1 + width - 1; + + GX_SET_REG(gx->suScis1, y2, GX_BP_SCISSORBR_BOT_ST, GX_BP_SCISSORBR_BOT_END); + GX_SET_REG(gx->suScis1, x2, GX_BP_SCISSORBR_RIGHT_ST, GX_BP_SCISSORBR_RIGHT_END); + + GX_BP_LOAD_REG(gx->suScis0); + GX_BP_LOAD_REG(gx->suScis1); + gx->bpSentNot = FALSE; +} + +/** + * @note Address: 0x800E9850 + * @note Size: 0x48 + */ +void GXGetScissor(u32* left, u32* top, u32* width, u32* height) +{ + u32 y1 = (gx->suScis0 & 0x0007FF) >> 0; + u32 x1 = (gx->suScis0 & 0x7FF000) >> 12; + u32 y2 = (gx->suScis1 & 0x0007FF) >> 0; + u32 x2 = (gx->suScis1 & 0x7FF000) >> 12; + + *left = x1 - 0x156; + *top = y1 - 0x156; + *width = (x2 - x1) + 1; + *height = (y2 - y1) + 1; +} + +/** + * @note Address: 0x800E9898 + * @note Size: 0x40 + */ +void GXSetScissorBoxOffset(s32 x, s32 y) +{ + u32 cmd = 0; + u32 x1; + u32 y1; + + x1 = (u32)(x + 342) / 2; + y1 = (u32)(y + 342) / 2; + GX_SET_REG(cmd, x1, GX_BP_SCISSOROFS_OX_ST, GX_BP_SCISSOROFS_OX_END); + GX_SET_REG(cmd, y1, GX_BP_SCISSOROFS_OY_ST, GX_BP_SCISSOROFS_OY_END); + + GX_SET_REG(cmd, GX_BP_REG_SCISSOROFFSET, 0, 7); + + GX_BP_LOAD_REG(cmd); + gx->bpSentNot = GX_FALSE; +} + +/** + * @note Address: 0x800E98D8 + * @note Size: 0x28 + */ +void GXSetClipMode(GXClipMode mode) +{ + GX_XF_LOAD_REG(GX_XF_REG_CLIPDISABLE, mode); + gx->bpSentNot = GX_TRUE; +} + +/** + * @note Address: 0x800E9900 + * @note Size: 0x84 + */ +void __GXSetMatrixIndex(GXAttr index) +{ + // Tex4 and after is stored in XF MatrixIndex1 + if (index < GX_VA_TEX4MTXIDX) { + GX_CP_LOAD_REG(GX_CP_REG_MTXIDXA, gx->matIdxA); + GX_XF_LOAD_REG(GX_XF_REG_MATRIXINDEX0, gx->matIdxA); + } else { + GX_CP_LOAD_REG(GX_CP_REG_MTXIDXB, gx->matIdxB); + GX_XF_LOAD_REG(GX_XF_REG_MATRIXINDEX1, gx->matIdxB); + } + + gx->bpSentNot = GX_TRUE; +} diff --git a/src/dolphin/mix/mix.c b/dolphin sdk not yet linked/src/mix/mix.c similarity index 100% rename from src/dolphin/mix/mix.c rename to dolphin sdk not yet linked/src/mix/mix.c diff --git a/dolphin sdk not yet linked/src/mtx/mtx.c b/dolphin sdk not yet linked/src/mtx/mtx.c new file mode 100644 index 0000000..d3a3db1 --- /dev/null +++ b/dolphin sdk not yet linked/src/mtx/mtx.c @@ -0,0 +1,893 @@ +#include "types.h" +#include "fdlibm.h" +#include "Dolphin/mtx.h" +#include "math.h" +static f32 Unit01[] = { 0.0f, 1.0f }; + +extern f32 sinf(f32); + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +void C_MTXIdentity(Mtx mtx) +{ + mtx[0][0] = 1.0f; + mtx[0][1] = 0.0f; + mtx[0][2] = 0.0f; + mtx[1][0] = 0.0f; + mtx[1][1] = 1.0f; + mtx[1][2] = 0.0f; + mtx[2][0] = 0.0f; + mtx[2][1] = 0.0f; + mtx[2][2] = 1.0f; + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA2A0 + * @note Size: 0x2C + */ +void PSMTXIdentity(register Mtx m) +{ + register f32 zero_c = 0.0f; + register f32 one_c = 1.0f; + register f32 c_01; + register f32 c_10; + +#ifdef __MWERKS__ // clang-format off + asm { + psq_st zero_c, 8(m), 0, 0 + ps_merge01 c_01, zero_c, one_c + psq_st zero_c, 24(m), 0, 0 + ps_merge10 c_10, one_c, zero_c + psq_st zero_c, 32(m), 0, 0 + psq_st c_01, 16(m), 0, 0 + psq_st c_10, 0(m), 0, 0 + psq_st c_10, 40(m), 0, 0 + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x6C + */ +void C_MTXCopy(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA2CC + * @note Size: 0x34 + */ +ASM void PSMTXCopy(const register Mtx src, register Mtx dst) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + + psq_l fp0, 0(src), 0, 0 + psq_st fp0, 0(dst), 0, 0 + psq_l fp1, 8(src), 0, 0 + psq_st fp1, 8(dst), 0, 0 + psq_l fp2, 16(src), 0, 0 + psq_st fp2, 16(dst), 0, 0 + psq_l fp3, 24(src), 0, 0 + psq_st fp3, 24(dst), 0, 0 + psq_l fp4, 32(src), 0, 0 + psq_st fp4, 32(dst), 0, 0 + psq_l fp5, 40(src), 0, 0 + psq_st fp5, 40(dst), 0, 0 + + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x2A8 + */ +void C_MTXConcat(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA300 + * @note Size: 0xCC + */ +ASM void PSMTXConcat(const register Mtx mA, // r3 + const register Mtx mB, // r4 + register Mtx mAB // r5 +) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + +#define FP0 fp0 +#define FP1 fp1 +#define FP2 fp2 +#define FP3 fp3 +#define FP4 fp4 +#define FP5 fp5 +#define FP6 fp6 +#define FP7 fp7 +#define FP8 fp8 +#define FP9 fp9 +#define FP10 fp10 +#define FP11 fp11 +#define FP12 fp12 +#define FP13 fp13 +#define FP14 fp14 +#define FP15 fp15 +#define FP31 fp31 + stwu r1, -64(r1) + psq_l FP0, 0(mA), 0, 0 + stfd fp14, 8(r1) + psq_l FP6, 0(mB), 0, 0 + addis r6, 0, Unit01@ha + psq_l FP7, 8(mB), 0, 0 + stfd fp15, 16(r1) + addi r6, r6, Unit01@l + stfd fp31, 40(r1) + psq_l FP8, 16(mB), 0, 0 + ps_muls0 FP12, FP6, FP0 + psq_l FP2, 16(mA), 0, 0 + ps_muls0 FP13, FP7, FP0 + psq_l FP31, 0(r6), 0, 0 + ps_muls0 FP14, FP6, FP2 + psq_l FP9, 24(mB), 0, 0 + ps_muls0 FP15, FP7, FP2 + psq_l FP1, 8(mA), 0, 0 + ps_madds1 FP12, FP8, FP0, FP12 + psq_l FP3, 24(mA), 0, 0 + ps_madds1 FP14, FP8, FP2, FP14 + psq_l FP10, 32(mB), 0, 0 + ps_madds1 FP13, FP9, FP0, FP13 + psq_l FP11, 40(mB), 0, 0 + ps_madds1 FP15, FP9, FP2, FP15 + psq_l FP4, 32(mA), 0, 0 + psq_l FP5, 40(mA), 0, 0 + ps_madds0 FP12, FP10, FP1, FP12 + ps_madds0 FP13, FP11, FP1, FP13 + ps_madds0 FP14, FP10, FP3, FP14 + ps_madds0 FP15, FP11, FP3, FP15 + psq_st FP12, 0(mAB), 0, 0 + + ps_muls0 FP2, FP6, FP4 + ps_madds1 FP13, FP31, FP1, FP13 + ps_muls0 FP0, FP7, FP4 + psq_st FP14, 16(mAB), 0, 0 + ps_madds1 FP15, FP31, FP3, FP15 + + psq_st FP13, 8(mAB), 0, 0 + + ps_madds1 FP2, FP8, FP4, FP2 + ps_madds1 FP0, FP9, FP4, FP0 + ps_madds0 FP2, FP10, FP5, FP2 + lfd fp14, 8(r1) + psq_st FP15, 24(mAB), 0, 0 + ps_madds0 FP0, FP11, FP5, FP0 + psq_st FP2, 32(mAB), 0, 0 + ps_madds1 FP0, FP31, FP5, FP0 + lfd fp15, 16(r1) + psq_st FP0, 40(mAB), 0, 0 + + lfd fp31, 40(r1) + addi r1, r1, 64 + + blr + +#undef FP0 +#undef FP1 +#undef FP2 +#undef FP3 +#undef FP4 +#undef FP5 +#undef FP6 +#undef FP7 +#undef FP8 +#undef FP9 +#undef FP10 +#undef FP11 +#undef FP12 +#undef FP13 +#undef FP14 +#undef FP15 +#undef FP31 +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x68 + */ +void C_MTXConcatArray(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x158 + */ +void PSMTXConcatArray(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x9C + */ +void C_MTXTranspose(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA3CC + * @note Size: 0x50 + */ +#pragma scheduling off +void PSMTXTranspose(const register Mtx src, register Mtx xPose) +{ + register f32 c_zero = 0.0f; + register f32 row0a, row1a, row0b, row1b; + register f32 trns0, trns1, trns2; + +#ifdef __MWERKS__ // clang-format off + asm { + psq_l row0a, 0(src), 0, 0 + stfs c_zero, 44(xPose) + psq_l row1a, 16(src), 0, 0 + ps_merge00 trns0, row0a, row1a + psq_l row0b, 8(src), 1, 0 + ps_merge11 trns1, row0a, row1a + psq_l row1b, 24(src), 1, 0 + psq_st trns0, 0(xPose), 0, 0 + psq_l row0a, 32(src), 0, 0 + ps_merge00 trns2, row0b, row1b + psq_st trns1, 16(xPose), 0, 0 + ps_merge00 trns0, row0a, c_zero + psq_st trns2, 32(xPose), 0, 0 + ps_merge10 trns1, row0a, c_zero + psq_st trns0, 8(xPose), 0, 0 + lfs row0b, 40(src) + psq_st trns1, 24(xPose), 0, 0 + stfs row0b, 40(xPose) + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x2AC + */ +void C_MTXInverse(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA41C + * @note Size: 0xF8 + */ +ASM u32 PSMTXInverse(const register Mtx src, register Mtx inv) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + psq_l fp0, 0(src), 1, 0 + psq_l fp1, 4(src), 0, 0 + psq_l fp2, 16(src), 1, 0 + ps_merge10 fp6, fp1, fp0 + psq_l fp3, 20(src), 0, 0 + psq_l fp4, 32(src), 1, 0 + ps_merge10 fp7, fp3, fp2 + psq_l fp5, 36(src), 0, 0 + ps_mul fp11, fp3, fp6 + ps_mul fp13, fp5, fp7 + ps_merge10 fp8, fp5, fp4 + ps_msub fp11, fp1, fp7, fp11 + ps_mul fp12, fp1, fp8 + ps_msub fp13, fp3, fp8, fp13 + ps_mul fp10, fp3, fp4 + ps_msub fp12, fp5, fp6, fp12 + ps_mul fp9, fp0, fp5 + ps_mul fp8, fp1, fp2 + ps_sub fp6, fp6, fp6 + ps_msub fp10, fp2, fp5, fp10 + ps_mul fp7, fp0, fp13 + ps_msub fp9, fp1, fp4, fp9 + ps_madd fp7, fp2, fp12, fp7 + ps_msub fp8, fp0, fp3, fp8 + ps_madd fp7, fp4, fp11, fp7 + ps_cmpo0 cr0, fp7, fp6 + bne _regular + addi r3, 0, 0 + blr + _regular: + fres fp0, fp7 + ps_add fp6, fp0, fp0 + ps_mul fp5, fp0, fp0 + ps_nmsub fp0, fp7, fp5, fp6 + lfs fp1, 12(src) + ps_muls0 fp13, fp13, fp0 + lfs fp2, 28(src) + ps_muls0 fp12, fp12, fp0 + lfs fp3, 44(src) + ps_muls0 fp11, fp11, fp0 + ps_merge00 fp5, fp13, fp12 + ps_muls0 fp10, fp10, fp0 + ps_merge11 fp4, fp13, fp12 + ps_muls0 fp9, fp9, fp0 + psq_st fp5, 0(inv), 0, 0 + ps_mul fp6, fp13, fp1 + psq_st fp4, 16(inv), 0, 0 + ps_muls0 fp8, fp8, fp0 + ps_madd fp6, fp12, fp2, fp6 + psq_st fp10, 32(inv), 1, 0 + ps_nmadd fp6, fp11, fp3, fp6 + psq_st fp9, 36(inv), 1, 0 + ps_mul fp7, fp10, fp1 + ps_merge00 fp5, fp11, fp6 + psq_st fp8, 40(inv), 1, 0 + ps_merge11 fp4, fp11, fp6 + psq_st fp5, 8(inv), 0, 0 + ps_madd fp7, fp9, fp2, fp7 + psq_st fp4, 24(inv), 0, 0 + ps_nmadd fp7, fp8, fp3, fp7 + addi r3, 0, 1 + psq_st fp7, 44(inv), 1, 0 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x21C + */ +void C_MTXInvXpose(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC8 + */ +void PSMTXInvXpose(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +void C_MTXRotRad(void) +{ + // UNUSED FUNCTION +} +#pragma scheduling reset +/** + * @note Address: 0x800EA514 + * @note Size: 0x70 + */ +void PSMTXRotRad(Mtx m, char axis, f32 rad) +{ + f32 sinA, cosA; + sinA = sinf(rad); + cosA = cosf(rad); + PSMTXRotTrig(m, axis, sinA, cosA); +} + +/** + * @note Address: N/A + * @note Size: 0x104 + */ +void C_MTXRotTrig(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA584 + * @note Size: 0xB0 + */ +void PSMTXRotTrig(register Mtx m, register char axis, register f32 sinA, register f32 cosA) +{ + register f32 fc0, fc1, nsinA; + register f32 fw0, fw1, fw2, fw3; + +#ifdef __MWERKS__ // clang-format off + asm { + frsp sinA, sinA + frsp cosA, cosA + } +#endif // clang-format on + + fc0 = 0.0f; + fc1 = 1.0f; + +#ifdef __MWERKS__ // clang-format off + asm { + ori axis, axis, 0x20 + ps_neg nsinA, sinA + cmplwi axis, 'x' + beq _case_x + cmplwi axis, 'y' + beq _case_y + cmplwi axis, 'z' + beq _case_z + b _end + + _case_x: + psq_st fc1, 0(m), 1, 0 + psq_st fc0, 4(m), 0, 0 + ps_merge00 fw0, sinA, cosA + psq_st fc0, 12(m), 0, 0 + ps_merge00 fw1, cosA, nsinA + psq_st fc0, 28(m), 0, 0 + psq_st fc0, 44(m), 1, 0 + psq_st fw0, 36(m), 0, 0 + psq_st fw1, 20(m), 0, 0 + b _end; + + _case_y: + ps_merge00 fw0, cosA, fc0 + ps_merge00 fw1, fc0, fc1 + psq_st fc0, 24(m), 0, 0 + psq_st fw0, 0(m), 0, 0 + ps_merge00 fw2, nsinA, fc0 + ps_merge00 fw3, sinA, fc0 + psq_st fw0, 40(m), 0, 0; + psq_st fw1, 16(m), 0, 0; + psq_st fw3, 8(m), 0, 0; + psq_st fw2, 32(m), 0, 0; + b _end; + + _case_z: + psq_st fc0, 8(m), 0, 0 + ps_merge00 fw0, sinA, cosA + ps_merge00 fw2, cosA, nsinA + psq_st fc0, 24(m), 0, 0 + psq_st fc0, 32(m), 0, 0 + ps_merge00 fw1, fc1, fc0 + psq_st fw0, 16(m), 0, 0 + psq_st fw2, 0(m), 0, 0 + psq_st fw1, 40(m), 0, 0 + + _end: + + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x118 + */ +void C_MTXRotAxisRad(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA634 + * @note Size: 0xB0 + */ +static void __PSMTXRotAxisRadInternal(register Mtx m, const register Vec* axis, register f32 sT, register f32 cT) +{ + register f32 tT, fc0; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4; + register f32 tmp5, tmp6, tmp7, tmp8, tmp9; + + tmp9 = 0.5f; + tmp8 = 3.0f; + +#ifdef __MWERKS__ // clang-format off + asm { + frsp cT, cT + psq_l tmp0, 0(axis), 0, 0 + frsp sT, sT + lfs tmp1, 8(axis) + ps_mul tmp2, tmp0, tmp0 + fadds tmp7, tmp9, tmp9 + ps_madd tmp3, tmp1, tmp1, tmp2 + fsubs fc0, tmp9, tmp9 + ps_sum0 tmp4, tmp3, tmp1, tmp2 + fsubs tT, tmp7, cT + frsqrte tmp5, tmp4 + fmuls tmp2, tmp5, tmp5 + fmuls tmp3, tmp5, tmp9 + fnmsubs tmp2, tmp2, tmp4, tmp8 + fmuls tmp5, tmp2, tmp3 + ps_merge00 cT, cT, cT + ps_muls0 tmp0, tmp0, tmp5 + ps_muls0 tmp1, tmp1, tmp5 + ps_muls0 tmp4, tmp0, tT + ps_muls0 tmp9, tmp0, sT + ps_muls0 tmp5, tmp1, tT + ps_muls1 tmp3, tmp4, tmp0 + ps_muls0 tmp2, tmp4, tmp0 + ps_muls0 tmp4, tmp4, tmp1 + fnmsubs tmp6, tmp1, sT, tmp3 + fmadds tmp7, tmp1, sT, tmp3 + ps_neg tmp0, tmp9 + ps_sum0 tmp8, tmp4, fc0, tmp9 + ps_sum0 tmp2, tmp2, tmp6, cT + ps_sum1 tmp3, cT, tmp7, tmp3 + ps_sum0 tmp6, tmp0, fc0 ,tmp4 + psq_st tmp8, 8(m), 0, 0 + ps_sum0 tmp0, tmp4, tmp4, tmp0 + psq_st tmp2, 0(m), 0, 0 + ps_muls0 tmp5, tmp5, tmp1 + psq_st tmp3, 16(m), 0, 0 + ps_sum1 tmp4, tmp9, tmp0, tmp4 + psq_st tmp6, 24(m), 0, 0 + ps_sum0 tmp5, tmp5, fc0, cT + psq_st tmp4, 32(m), 0, 0 + psq_st tmp5, 40(m), 0, 0 + } +#endif // clang-format on +} + +/** + * @note Address: 0x800EA6E4 + * @note Size: 0x70 + */ +void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) +{ + f32 sinT, cosT; + + sinT = sinf(rad); + cosT = cosf(rad); + + __PSMTXRotAxisRadInternal(m, axis, sinT, cosT); +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +void C_MTXTrans(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA754 + * @note Size: 0x34 + */ +void PSMTXTrans(register Mtx m, register f32 xT, register f32 yT, register f32 zT) +{ + register f32 c0 = 0.0f; + register f32 c1 = 1.0f; + +#ifdef __MWERKS__ // clang-format off + asm { + stfs xT, 12(m) + stfs yT, 28(m) + psq_st c0, 4(m), 0, 0 + psq_st c0, 32(m), 0, 0 + stfs c0, 16(m) + stfs c1, 20(m) + stfs c0, 24(m) + stfs c1, 40(m) + stfs zT, 44(m) + stfs c1, 0(m) + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +void C_MTXTransApply(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA788 + * @note Size: 0x4C + */ +ASM void PSMTXTransApply(const register Mtx src, register Mtx dst, register f32 xT, register f32 yT, register f32 zT) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l fp4, 0(src), 0, 0; + frsp xT, xT; + psq_l fp5, 8(src), 0, 0; + frsp yT, yT; + psq_l fp7, 24(src), 0, 0; + frsp zT, zT; + psq_l fp8, 40(src), 0, 0; + psq_st fp4, 0(dst), 0, 0; + ps_sum1 fp5, xT, fp5, fp5; + psq_l fp6, 16(src), 0, 0; + psq_st fp5, 8(dst), 0, 0; + ps_sum1 fp7, yT, fp7, fp7; + psq_l fp9, 32(src), 0, 0; + psq_st fp6, 16(dst), 0, 0; + ps_sum1 fp8, zT, fp8, fp8; + psq_st fp7, 24(dst), 0, 0; + psq_st fp9, 32(dst), 0, 0; + psq_st fp8, 40(dst), 0, 0; + blr; +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +void C_MTXScale(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA7D4 + * @note Size: 0x28 + */ +void PSMTXScale(register Mtx m, register f32 xS, register f32 yS, register f32 zS) +{ + register f32 c0 = 0.0f; + +#ifdef __MWERKS__ // clang-format off + asm { + stfs xS, 0(m) + psq_st c0, 4(m), 0, 0 + psq_st c0, 12(m), 0, 0 + stfs yS, 20(m) + psq_st c0, 24(m), 0, 0 + psq_st c0, 32(m), 0, 0 + stfs zS, 40(m) + stfs c0, 44(m) + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void C_MTXScaleApply(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA7FC + * @note Size: 0x58 + */ +ASM void PSMTXScaleApply(const register Mtx src, register Mtx dst, register f32 xS, register f32 yS, register f32 zS) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + frsp xS, xS; + psq_l fp4, 0(src), 0, 0; + frsp yS, yS; + psq_l fp5, 8(src), 0, 0; + frsp zS, zS; + ps_muls0 fp4, fp4, xS; + psq_l fp6, 16(src), 0, 0; + ps_muls0 fp5, fp5, xS; + psq_l fp7, 24(src), 0, 0; + ps_muls0 fp6, fp6, yS; + psq_l fp8, 32(src), 0, 0; + psq_st fp4, 0(dst), 0, 0; + ps_muls0 fp7, fp7, yS; + psq_l fp2, 40(src), 0, 0; + psq_st fp5, 8(dst), 0, 0; + ps_muls0 fp8, fp8, zS; + psq_st fp6, 16(dst), 0, 0; + ps_muls0 fp2, fp2, zS; + psq_st fp7, 24(dst), 0, 0; + psq_st fp8, 32(dst), 0, 0; + psq_st fp2, 40(dst), 0, 0; + blr; +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0xF0 + */ +void C_MTXQuat(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EA854 + * @note Size: 0xA4 + */ +void PSMTXQuat(register Mtx m, const register PSQuaternion* q) +{ + register f32 c_zero, c_one, c_two, scale; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4; + register f32 tmp5, tmp6, tmp7, tmp8, tmp9; + c_one = 1.0f; +#ifdef __MWERKS__ // clang-format off + asm { + psq_l tmp0, 0(q), 0, 0 + psq_l tmp1, 8(q), 0, 0 + fsubs c_zero, c_one, c_one + fadds c_two, c_one, c_one + ps_mul tmp2, tmp0, tmp0 + ps_merge10 tmp5, tmp0, tmp0 + ps_madd tmp4, tmp1, tmp1, tmp2 + ps_mul tmp3, tmp1, tmp1 + ps_sum0 scale, tmp4, tmp4, tmp4 + ps_muls1 tmp7, tmp5, tmp1 + fres tmp9, scale + ps_sum1 tmp4, tmp3, tmp4, tmp2 + ps_nmsub scale, scale, tmp9, c_two + ps_muls1 tmp6, tmp1, tmp1 + ps_mul scale, tmp9, scale + ps_sum0 tmp2, tmp2, tmp2, tmp2 + fmuls scale, scale, c_two + ps_madd tmp8, tmp0, tmp5, tmp6 + ps_msub tmp6, tmp0, tmp5, tmp6 + psq_st c_zero, 12(m), 1, 0 + ps_nmsub tmp2, tmp2, scale, c_one + ps_nmsub tmp4, tmp4, scale, c_one + psq_st c_zero, 44(m), 1, 0 + ps_mul tmp8, tmp8, scale + ps_mul tmp6, tmp6, scale + psq_st tmp2, 40(m), 1, 0 + ps_madds0 tmp5, tmp0, tmp1, tmp7 + ps_merge00 tmp1, tmp8, tmp4 + ps_nmsub tmp7, tmp7, c_two, tmp5 + ps_merge10 tmp0, tmp4, tmp6 + psq_st tmp1, 16(m), 0, 0 + ps_mul tmp5, tmp5, scale + ps_mul tmp7, tmp7, scale + psq_st tmp0, 0(m), 0, 0 + psq_st tmp5, 8(m), 1, 0 + ps_merge10 tmp3, tmp7, c_zero + ps_merge01 tmp9, tmp7, tmp5 + psq_st tmp3, 24(m), 0, 0 + psq_st tmp9, 32(m), 0, 0 + } +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x100 + */ +void C_MTXReflect(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +void PSMTXReflect(void) +{ + // UNUSED FUNCTION +} + +#pragma fp_contract off + +/** + * @note Address: 0x800EA8F8 + * @note Size: 0x18C + */ +void C_MTXLookAt(Mtx m, const Vec* camPos, const Vec* camUp, const Vec* target) +{ + + Vec vLook, vRight, vUp; + + vLook.x = camPos->x - target->x; + vLook.y = camPos->y - target->y; + vLook.z = camPos->z - target->z; + PSVECNormalize(&vLook, &vLook); + + PSVECCrossProduct(camUp, &vLook, &vRight); + PSVECNormalize(&vRight, &vRight); + + PSVECCrossProduct(&vLook, &vRight, &vUp); + + m[0][0] = vRight.x; + m[0][1] = vRight.y; + m[0][2] = vRight.z; + m[0][3] = -(camPos->x * vRight.x + camPos->y * vRight.y + camPos->z * vRight.z); + + m[1][0] = vUp.x; + m[1][1] = vUp.y; + m[1][2] = vUp.z; + m[1][3] = -(camPos->x * vUp.x + camPos->y * vUp.y + camPos->z * vUp.z); + + m[2][0] = vLook.x; + m[2][1] = vLook.y; + m[2][2] = vLook.z; + m[2][3] = -(camPos->x * vLook.x + camPos->y * vLook.y + camPos->z * vLook.z); +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void C_MTXLightFrustum(Mtx m, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, f32 arg8, f32 arg9) +{ + f32 tmp = 1.0f / (arg4 - arg3); + m[0][0] = ((2 * arg5) * tmp) * arg6; + m[0][1] = 0.0f; + m[0][2] = (((arg4 + arg3) * tmp) * arg6) - arg8; + m[0][3] = 0.0f; + tmp = 1.0f / (arg1 - arg2); + m[1][0] = 0.0f; + m[1][1] = ((2 * arg5) * tmp) * arg7; + m[1][2] = (((arg1 + arg2) * tmp) * arg7) - arg9; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = -1.0f; + m[2][3] = 0.0f; +} + +/** + * @note Address: 0x800EAA84 + * @note Size: 0xCC + */ +void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, f32 transT) +{ + f32 angle; + f32 cot; + + angle = fovY * 0.5f; + angle = MTXDegToRad(angle); + + cot = 1.0f / tanf(angle); + + m[0][0] = (cot / aspect) * scaleS; + m[0][1] = 0.0f; + m[0][2] = -transS; + m[0][3] = 0.0f; + + m[1][0] = 0.0f; + m[1][1] = cot * scaleT; + m[1][2] = -transT; + m[1][3] = 0.0f; + + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = -1.0f; + m[2][3] = 0.0f; +} + +/** + * @note Address: 0x800EAB50 + * @note Size: 0x88 + */ +void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, f32 transT) +{ + f32 tmp; + + tmp = 1.0f / (r - l); + m[0][0] = (2.0f * tmp * scaleS); + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = ((-(r + l) * tmp) * scaleS) + transS; + + tmp = 1.0f / (t - b); + m[1][0] = 0.0f; + m[1][1] = (2.0f * tmp) * scaleT; + m[1][2] = 0.0f; + m[1][3] = ((-(t + b) * tmp) * scaleT) + transT; + + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 0.0f; + m[2][3] = 1.0f; +} +#pragma fp_contract reset diff --git a/dolphin sdk not yet linked/src/mtx/mtx44.c b/dolphin sdk not yet linked/src/mtx/mtx44.c new file mode 100644 index 0000000..19475fe --- /dev/null +++ b/dolphin sdk not yet linked/src/mtx/mtx44.c @@ -0,0 +1,321 @@ +#include "Dolphin/mtx.h" +#include "math.h" + +/** + * @note Address: N/A + * @note Size: 0x9C + */ +void C_MTXFrustum(Mtx44 m, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6) +{ + f32 tmp = 1.0f / (arg4 - arg3); + m[0][0] = (2 * arg5) * tmp; + m[0][1] = 0.0f; + m[0][2] = (arg4 + arg3) * tmp; + m[0][3] = 0.0f; + tmp = 1.0f / (arg1 - arg2); + m[1][0] = 0.0f; + m[1][1] = (2 * arg5) * tmp; + m[1][2] = (arg1 + arg2) * tmp; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + tmp = 1.0f / (arg6 - arg5); + m[2][2] = -(arg5)*tmp; + m[2][3] = -(arg6 * arg5) * tmp; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = -1.0f; + m[3][3] = 0.0f; +} + +/** + * @note Address: 0x800EAD08 + * @note Size: 0xD0 + */ +void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f) +{ + f32 angle = fovY * 0.5f; + f32 cot; + f32 tmp; + angle = MTXDegToRad(angle); + cot = 1.0f / tanf(angle); + m[0][0] = cot / aspect; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + m[1][0] = 0.0f; + m[1][1] = cot; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + tmp = 1.0f / (f - n); + m[2][2] = -(n)*tmp; + m[2][3] = -(f * n) * tmp; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = -1.0f; + m[3][3] = 0.0f; +} + +/** + * @note Address: 0x800EADD8 + * @note Size: 0x98 + */ +void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) +{ + f32 tmp = 1.0f / (r - l); + m[0][0] = 2.0f * tmp; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = -(r + l) * tmp; + tmp = 1.0f / (t - b); + m[1][0] = 0.0f; + m[1][1] = 2.0f * tmp; + m[1][2] = 0.0f; + m[1][3] = -(t + b) * tmp; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + tmp = 1.0f / (f - n); + m[2][2] = -(1.0f) * tmp; + m[2][3] = -(f)*tmp; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void C_MTX44Identity(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void PSMTX44Identity(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void C_MTX44Copy(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAE70 + * @note Size: 0x44 + */ +ASM void PSMTX44Copy(register Mtx44 src, register Mtx44 dest) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l fp1, 0(src), 0, 0; + psq_st fp1, 0(dest), 0, 0; + psq_l fp1, 8(src), 0, 0; + psq_st fp1, 8(dest), 0, 0; + psq_l fp1, 0x10(src), 0, 0; + psq_st fp1, 0x10(dest), 0, 0; + psq_l fp1, 0x18(src), 0, 0; + psq_st fp1, 0x18(dest), 0, 0; + psq_l fp1, 0x20(src), 0, 0; + psq_st fp1, 0x20(dest), 0, 0; + psq_l fp1, 0x28(src), 0, 0; + psq_st fp1, 0x28(dest), 0, 0; + psq_l fp1, 0x30(src), 0, 0; + psq_st fp1, 0x30(dest), 0, 0; + psq_l fp1, 0x38(src), 0, 0; + psq_st fp1, 0x38(dest), 0, 0; + blr; +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x450 + */ +void C_MTX44Concat(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x104 + */ +void PSMTX44Concat(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC4 + */ +void C_MTX44Transpose(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +void PSMTX44Transpose(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x3F0 + */ +void C_MTX44Inverse(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void C_MTX44Trans(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +void PSMTX44Trans(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +void C_MTX44TransApply(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x5C + */ +void PSMTX44TransApply(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void C_MTX44Scale(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void PSMTX44Scale(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xB4 + */ +void C_MTX44ScaleApply(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x68 + */ +void PSMTX44ScaleApply(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +void C_MTX44RotRad(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +void PSMTX44RotRad(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x11C + */ +void C_MTX44RotTrig(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xD4 + */ +void PSMTX44RotTrig(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x12C + */ +void C_MTX44RotAxisRad(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xBC + */ +void __PSMTX44RotAxisRadInternal(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +void PSMTX44RotAxisRad(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/mtx/mtxvec.c b/dolphin sdk not yet linked/src/mtx/mtxvec.c new file mode 100644 index 0000000..a860922 --- /dev/null +++ b/dolphin sdk not yet linked/src/mtx/mtxvec.c @@ -0,0 +1,159 @@ +#include "Dolphin/mtx.h" + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void C_MTXMultVec(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EABD8 + * @note Size: 0x54 + */ +ASM void PSMTXMultVec(const register Mtx m, const register Vec* in, register Vec* out) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l fp0, 0(in), 0, 0; + psq_l fp2, 0(m), 0, 0; + psq_l fp1, 8(in), 1, 0; + ps_mul fp4, fp2, fp0; + psq_l fp3, 8(m), 0, 0; + ps_madd fp5, fp3, fp1, fp4; + psq_l fp8, 16(m), 0, 0; + ps_sum0 fp6, fp5, fp6, fp5; + psq_l fp9, 24(m), 0, 0; + ps_mul fp10, fp8, fp0; + psq_st fp6, 0(out), 1, 0; + ps_madd fp11, fp9, fp1, fp10; + psq_l fp2, 32(m), 0, 0; + ps_sum0 fp12, fp11, fp12, fp11; + psq_l fp3, 40(m), 0, 0; + ps_mul fp4, fp2, fp0; + psq_st fp12, 4(out), 1, 0; + ps_madd fp5, fp3, fp1, fp4; + ps_sum0 fp6, fp5, fp6, fp5; + psq_st fp6, 8(out), 1, 0; + blr; +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x204 + */ +void C_MTXMultVecArray(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8C + */ +void PSMTXMultVecArray(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +void C_MTXMultVecSR(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAC2C + * @note Size: 0x54 + */ +ASM void PSMTXMultVecSR(const register Mtx mtx, const register Vec* in, register Vec* out) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l fp0, 0(mtx), 0, 0; + psq_l fp6, 0(in), 0, 0; + psq_l fp2, 0x10(mtx), 0, 0; + ps_mul fp8, fp0, fp6; + psq_l fp4, 0x20(mtx), 0, 0; + ps_mul fp10, fp2, fp6; + psq_l fp7, 8(in), 1, 0; + ps_mul fp12, fp4, fp6; + psq_l fp3, 0x18(mtx), 0, 0; + ps_sum0 fp8, fp8, fp8, fp8; + psq_l fp5, 0x28(mtx), 0, 0; + ps_sum0 fp10, fp10, fp10, fp10; + psq_l fp1, 8(mtx), 0, 0; + ps_sum0 fp12, fp12, fp12, fp12; + ps_madd fp9, fp1, fp7, fp8; + psq_st fp9, 0(out), 1, 0; + ps_madd fp11, fp3, fp7, fp10; + psq_st fp11, 4(out), 1, 0; + ps_madd fp13, fp5, fp7, fp12; + psq_st fp13, 8(out), 1, 0; + blr; +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x1BC + */ +void C_MTXMultVecArraySR(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAC80 + * @note Size: 0x88 + */ +ASM void PSMTXMultVecArraySR(const register Mtx mtx, register f32* in, register f32* out, register f32* count) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l fp13, 0(mtx), 0, 0; + psq_l fp12, 0x10(mtx), 0, 0; + subi count, count, 1; + psq_l fp11, 8(mtx), 1, 0; + ps_merge00 fp0, fp13, fp12; + subi out, out, 4; + psq_l fp10, 0x18(mtx), 1, 0; + ps_merge11 fp1, fp13, fp12; + mtctr count; + + psq_l fp3, 0x20(mtx), 0, 0; + ps_merge00 fp2, fp11, fp10; + psq_l fp4, 0x28(mtx), 1, 0; + psq_l fp6, 0(in), 0, 0; + psq_lu fp7, 8(in), 1, 0; + ps_muls0 fp8, fp0, fp6; + ps_mul fp9, fp3, fp6; + ps_madds1 fp8, fp1, fp6, fp8; + ps_madd fp10, fp4, fp7, fp9; + +loop: + psq_lu fp6, 4(in), 0, 0; + ps_madds0 fp12, fp2, fp7, fp8; + psq_lu fp7, 8(in), 1, 0; + ps_sum0 fp13, fp10, fp9, fp9; + ps_muls0 fp8, fp0, fp6; + ps_mul fp9, fp3, fp6; + psq_stu fp12, 4(out), 0, 0; + ps_madds1 fp8, fp1, fp6, fp8; + psq_stu fp13, 8(out), 1, 0; + ps_madd fp10, fp4, fp7, fp9; + bdnz + loop; + + ps_madds0 fp12, fp2, fp7, fp8; + ps_sum0 fp13, fp10, fp9, fp9; + psq_stu fp12, 4(out), 0, 0; + psq_stu fp13, 8(out), 1, 0; + blr; +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/mtx/vec.c b/dolphin sdk not yet linked/src/mtx/vec.c new file mode 100644 index 0000000..944bf73 --- /dev/null +++ b/dolphin sdk not yet linked/src/mtx/vec.c @@ -0,0 +1,303 @@ +#include "types.h" +#include "Dolphin/vec.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 +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void C_VECAdd(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAEB4 + * @note Size: 0x24 + */ +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 +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +void C_VECSubtract(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAED8 + * @note Size: 0x24 + */ +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 +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void C_VECScale(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void PSVECScale(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xC8 + */ +void C_VECNormalize(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAEFC + * @note Size: 0x44 + */ +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 +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void C_VECSquareMag(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +void PSVECSquareMag(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +void C_VECMag(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAF40 + * @note Size: 0x44 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +void C_VECDotProduct(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void PSVECDotProduct(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +void C_VECCrossProduct(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAF84 + * @note Size: 0x3C + */ +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 +} + +/** + * @note Address: N/A + * @note Size: 0xD8 + */ +void C_VECHalfAngle(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xD4 + */ +void C_VECReflect(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +void C_VECSquareDistance(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void PSVECSquareDistance(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xAC + */ +void C_VECDistance(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +void PSVECDistance(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/odenotstub/odenotstub.c b/dolphin sdk not yet linked/src/odenotstub/odenotstub.c new file mode 100644 index 0000000..37ac2c6 --- /dev/null +++ b/dolphin sdk not yet linked/src/odenotstub/odenotstub.c @@ -0,0 +1,7 @@ +#include "types.h" + +/** + * @note Address: 0x800EAFC0 + * @note Size: 0x8 + */ +WEAKFUNC BOOL Hu_IsStub(void) { return FALSE; } diff --git a/dolphin sdk not yet linked/src/os/OS.c b/dolphin sdk not yet linked/src/os/OS.c new file mode 100644 index 0000000..2a3ee1b --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OS.c @@ -0,0 +1,759 @@ +#include "types.h" +#include "Dolphin/os.h" +#include "Dolphin/PPCArch.h" +#include "Dolphin/hw_regs.h" + +DECL_SECT(".init") extern char _db_stack_end[]; + +// memory locations for important stuff +#define OS_DBINTERFACE_ADDR 0x40 +#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 + +extern u8 __ArenaHi[]; +extern u8 __ArenaLo[]; +extern u32 __DVDLongFileNameFlag; +extern u32 __PADSpec; +// OS version +char* __OSVersion = "<< Dolphin SDK - OS\trelease build: Nov 26 2003 05:18:37 (0x2301) >>"; + +// main workhorse functions +void ClearArena(); +void DVDInit(); +void DVDInquiryAsync(void*, void*, void*); +void EXIInit(); +void EnableMetroTRKInterrupts(); +int OSEnableInterrupts(); +void OSExceptionInit(); +void OSRegisterVersion(const char*); +void PPCMtmmcr0(int); +void PPCMtmmcr1(int); +void PPCMtpmc1(int); +void PPCMtpmc2(int); +void PPCMtpmc3(int); +void PPCMtpmc4(int); +void SIInit(); +void __OSContextInit(); +void __OSInitAudioSystem(); +void __OSInitMemoryProtection(); +void __OSInitSram(); +void __OSInitSystemCall(); +void __OSInterruptInit(); +void __OSThreadInit(); +OSTime __OSGetSystemTime(); +void DBPrintf(const char*, ...); +BOOL __DBIsExceptionMarked(u8); +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); +extern char* __OSResetSWInterruptHandler[]; + +// 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; +// }; + +// The exception table. It points to a location in LoMem. It is set by +// OSExceptionInit +// typedef u32 __OSExceptionHandler; +#define OS_EXCEPTIONTABLE_ADDR 0x3000 +#define OS_DBJUMPPOINT_ADDR 0x60 + +vu16 __OSDeviceCode : (OS_BASE_CACHED | OS_DVD_DEVICECODE); +void OSDefaultExceptionHandler(__OSException exception, OSContext* context); +static DVDDriveInfo DriveInfo ATTRIBUTE_ALIGN(32); +static DVDCommandBlock DriveBlock; + +// flags and system info +static OSBootInfo* BootInfo; +static vu32* BI2DebugFlag; +static u32* BI2DebugFlagHolder; +WEAKFUNC BOOL __OSIsGcam = FALSE; +static f64 ZeroF; +static f32 ZeroPS[2]; +static BOOL AreWeInitialized = FALSE; +static __OSExceptionHandler* OSExceptionTable; +OSTime __OSStartTime; +BOOL __OSInIPL; +void* __OSSavedRegionStart; +void* __OSSavedRegionEnd; + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void __OSIsDebuggerPresent(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EAFC8 + * @note Size: 0x128 + */ +ASM void __OSFPRInit(void) +{ +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void DisableWriteGatherPipe(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EB0F0 + * @note Size: 0x28 + */ +u32 OSGetConsoleType() +{ + if (BootInfo == NULL || BootInfo->consoleType == 0) { + return 0x10000002; // default console type + } + return BootInfo->consoleType; +} + +void* __OSSavedRegionStart; +void* __OSSavedRegionEnd; + +extern u32 BOOT_REGION_START : 0x812FDFF0; //(*(u32 *)0x812fdff0) +extern u32 BOOT_REGION_END : 0x812FDFEC; //(*(u32 *)0x812fdfec) + +/** + * @note Address: 0x800EB118 + * @note Size: 0x128 + */ +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); + } + } +} + +/** + * @note Address: 0x800EB240 + * @note Size: 0x3C + */ +static void InquiryCallback(s32 result, DVDCommandBlock* block) +{ + switch (block->state) { + case 0: + __OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode); + break; + default: + __OSDeviceCode = 1; + break; + } +} + +/** + * @note Address: 0x800EB27C + * @note Size: 0x3D8 + */ +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", "Nov 26 2003", "05:18:37"); + 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_TDEVKIT: + // 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((char*)&DriveBlock, &DriveInfo, InquiryCallback); + } + } +} + +static u32 __OSExceptionLocations[] = { + 0x00000100, // 0 System reset + 0x00000200, // 1 Machine check + 0x00000300, // 2 DSI - seg fault or DABR + 0x00000400, // 3 ISI + 0x00000500, // 4 External interrupt + 0x00000600, // 5 Alignment + 0x00000700, // 6 Program + 0x00000800, // 7 FP Unavailable + 0x00000900, // 8 Decrementer + 0x00000C00, // 9 System call + 0x00000D00, // 10 Trace + 0x00000F00, // 11 Performance monitor + 0x00001300, // 12 Instruction address breakpoint. + 0x00001400, // 13 System management interrupt + 0x00001700 // 14 Thermal interrupt +}; + +// 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 + +/** + * @note Address: 0x800EB654 + * @note Size: 0x280 + */ +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"); +} + +/** + * @note Address: 0x800EB8D4 + * @note Size: 0x24 + */ +ASM static void __OSDBIntegrator(void) { +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800EB8F8 + * @note Size: 0x4 + */ +ASM static void __OSDBJump(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc +entry __OSDBJUMPSTART + bla OS_DBJUMPPOINT_ADDR +entry __OSDBJUMPEND +#endif // clang-format on +} + +/** + * @note Address: 0x800EB8FC + * @note Size: 0x1C + */ +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) +{ + __OSExceptionHandler oldHandler; + oldHandler = OSExceptionTable[exception]; + OSExceptionTable[exception] = handler; + return oldHandler; +} + +/** + * @note Address: 0x800EB918 + * @note Size: 0x14 + */ +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) { return OSExceptionTable[exception]; } + +/** + * @note Address: 0x800EB92C + * @note Size: 0x9C + */ +ASM static void OSExceptionVector(void) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800EB9C8 + * @note Size: 0x58 + */ +ASM void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) +{ +#pragma unused(exception) +#ifdef __MWERKS__ // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + // Load DSISR and DAR + mfdsisr r5 + mfdar r6 + + stwu r1,-8(r1) + b __OSUnhandledException + // NOT REACHED HERE +#endif // clang-format on +} + +/** + * @note Address: 0x800EBA20 + * @note Size: 0x54 + */ +void __OSPSInit(void) +{ + PPCMthid2(PPCMfhid2() | 0xA0000000); + ICFlashInvalidate(); + __sync(); +#ifdef __MWERKS__ // 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 + } +#endif // clang-format on +} + +/** + * @note Address: 0x800EBA74 + * @note Size: 0x14 + */ +#define DI_CONFIG_IDX 0x9 +#define DI_CONFIG_CONFIG_MASK 0xFF +u32 __OSGetDIConfig(void) { return (__DIRegs[DI_CONFIG_IDX] & DI_CONFIG_CONFIG_MASK); } + +/** + * @note Address: 0x800EBA88 + * @note Size: 0x2C + */ +void OSRegisterVersion(const char* id) { OSReport("%s\n", id); } diff --git a/dolphin sdk not yet linked/src/os/OSAlarm.c b/dolphin sdk not yet linked/src/os/OSAlarm.c new file mode 100644 index 0000000..9126d48 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSAlarm.c @@ -0,0 +1,241 @@ +#include "Dolphin/os.h" + +// forward declarations +BOOL __DVDTestAlarm(OSAlarm* alarm); + +static OSAlarmQueue AlarmQueue; + +static void DecrementerExceptionHandler(__OSException exception, OSContext* context); +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, OS_RESET_PRIO_ALARM }; + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +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); + } +} + +/** + * @note Address: 0x800EBAB4 + * @note Size: 0x58 + */ +void OSInitAlarm() +{ + if (__OSGetExceptionHandler(8) != DecrementerExceptionHandler) { + AlarmQueue.head = AlarmQueue.tail = nullptr; + __OSSetExceptionHandler(8, DecrementerExceptionHandler); + OSRegisterResetFunction(&ResetFunctionInfo); + } +} + +/** + * @note Address: 0x800EBB0C + * @note Size: 0x10 + */ +void OSCreateAlarm(OSAlarm* alarm) +{ + alarm->handler = nullptr; + alarm->tag = 0; +} + +/** + * @note Address: 0x800EBB1C + * @note Size: 0x250 + */ +static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler) +{ + OSAlarm* next; + OSAlarm* prev; + + if (alarm->period > 0) { + 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 = nullptr; + prev = AlarmQueue.tail; + AlarmQueue.tail = alarm; + alarm->prev = prev; + if (prev) { + prev->next = alarm; + } else { + AlarmQueue.head = AlarmQueue.tail = alarm; + SetTimer(alarm); + } +} + +/** + * @note Address: 0x800EBD6C + * @note Size: 0x68 + */ +void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + alarm->period = 0; + InsertAlarm(alarm, __OSGetSystemTime() + tick, handler); + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800EBDD4 + * @note Size: 0x11C + */ +void OSCancelAlarm(OSAlarm* alarm) +{ + OSAlarm* next; + BOOL enabled; + + enabled = OSDisableInterrupts(); + + if (alarm->handler == nullptr) { + OSRestoreInterrupts(enabled); + return; + } + + next = alarm->next; + if (next == nullptr) { + 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 = nullptr; + + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800EBEF0 + * @note Size: 0x230 + */ +static void DecrementerExceptionCallback(__OSException exception, OSContext* context) +{ + OSAlarm* alarm; + OSAlarm* next; + OSAlarmHandler handler; + OSTime time; + OSContext exceptionContext; + time = __OSGetSystemTime(); + alarm = AlarmQueue.head; + if (alarm == nullptr) { + OSLoadContext(context); + } + + if (time < alarm->fire) { + SetTimer(alarm); + OSLoadContext(context); + } + + next = alarm->next; + AlarmQueue.head = next; + if (next == nullptr) { + AlarmQueue.tail = nullptr; + } else { + next->prev = nullptr; + } + + handler = alarm->handler; + alarm->handler = nullptr; + 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); +} + +/** + * @note Address: 0x800EC120 + * @note Size: 0x50 + */ +ASM static void DecrementerExceptionHandler(register __OSException exception, register OSContext* context) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + stwu r1, -8(r1) + b DecrementerExceptionCallback +#endif // clang-format on +} + +/** + * @note Address: 0x800EC170 + * @note Size: 0xA0 + */ +static BOOL OnReset(BOOL final) +{ + OSAlarm* alarm; + OSAlarm* next; + + if (final != FALSE) { + alarm = AlarmQueue.head; + next = (alarm) ? alarm->next : nullptr; + + while (alarm != nullptr) { + if (__DVDTestAlarm(alarm) == FALSE) { + OSCancelAlarm(alarm); + } + + alarm = next; + next = (alarm) ? alarm->next : nullptr; + } + } + + return TRUE; +} diff --git a/dolphin sdk not yet linked/src/os/OSAlloc.c b/dolphin sdk not yet linked/src/os/OSAlloc.c new file mode 100644 index 0000000..b595e11 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSAlloc.c @@ -0,0 +1,321 @@ +#include "types.h" +#include "Dolphin/os.h" +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 + +/** + * @note Address: N/A + * @note Size: 0x20 + * inserts 'cell' before 'neighbor' and returns 'cell' + */ +static inline void* DLAddFront(struct HeapCell* neighbor, struct HeapCell* cell) +{ + cell->next = neighbor; + cell->prev = NULL; + if (neighbor != NULL) + neighbor->prev = cell; + return cell; +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void DLLookup(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x34 + * 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; +} + +/** + * @note Address: 0x800EC210 + * @note Size: 0xAC + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x48 + */ +void DLOverlap(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x24 + */ +void DLSize(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0xFC + */ +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; +} + +// /** +// * @note Address: N/A +// * @note Size: 0x284 +// */ +// void OSAllocFixed(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800EC2BC + * @note Size: 0x7C + */ +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); +} + +/** + * @note Address: 0x800EC338 + * @note Size: 0x10 + */ +OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap) +{ + OSHeapHandle old = __OSCurrHeap; + + __OSCurrHeap = heap; + return old; +} + +/** + * @note Address: 0x800EC348 + * @note Size: 0x70 + */ +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; +} + +/** + * @note Address: 0x800EC3B8 + * @note Size: 0x6C + */ +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; +} + +// /** +// * @note Address: N/A +// * @note Size: 0x14 +// */ +// void OSDestroyHeap(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x60 +// */ +// void OSAddToHeap(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x360 +// */ +// s32 OSCheckHeap(int) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0xC +// */ +// void OSReferentSize(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x104 +// */ +// void OSDumpHeap(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x9C +// */ +// void OSVisitAllocated(void) +// { +// // UNUSED FUNCTION +// } diff --git a/dolphin sdk not yet linked/src/os/OSArena.c b/dolphin sdk not yet linked/src/os/OSArena.c new file mode 100644 index 0000000..5ce6c8a --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSArena.c @@ -0,0 +1,44 @@ +static void* __OSArenaHi = (void*)0x00000000; +static void* __OSArenaLo = (void*)0xffffffff; + +/** + * @note Address: 0x800EC424 + * @note Size: 0x8 + */ +void* OSGetArenaHi(void) { return __OSArenaHi; } + +/** + * @note Address: 0x800EC42C + * @note Size: 0x8 + */ +void* OSGetArenaLo(void) { return __OSArenaLo; } + +/** + * @note Address: 0x800EC434 + * @note Size: 0x8 + */ +void OSSetArenaHi(void* arena_hi) { __OSArenaHi = arena_hi; } + +/** + * @note Address: 0x800EC43C + * @note Size: 0x8 + */ +void OSSetArenaLo(void* arena_lo) { __OSArenaLo = arena_lo; } + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +void OSAllocFromArenaLo(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void OSAllocFromArenaHi(void) +{ + // UNUSED FUNCTION +} diff --git a/dolphin sdk not yet linked/src/os/OSAudioSystem.c b/dolphin sdk not yet linked/src/os/OSAudioSystem.c new file mode 100644 index 0000000..f58bdae --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSAudioSystem.c @@ -0,0 +1,118 @@ +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static u8 DSPInitCode[128] + = { 0x02, 0x9F, 0x00, 0x10, 0x02, 0x9F, 0x00, 0x33, 0x02, 0x9F, 0x00, 0x34, 0x02, 0x9F, 0x00, 0x35, 0x02, 0x9F, 0x00, 0x36, 0x02, 0x9F, + 0x00, 0x37, 0x02, 0x9F, 0x00, 0x38, 0x02, 0x9F, 0x00, 0x39, 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 }; + +vu16 __DSPRegs[] : 0xCC005000; +#define __DSPWorkBuffer (void*)0x81000000 + +/** + * @note Address: 0x800EC444 + * @note Size: 0x1BC + */ +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]; + + // the nonmatching part + 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); +} + +/** + * @note Address: 0x800EC600 + * @note Size: 0xD8 + */ +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); +} + +#ifdef __cplusplus +} +#endif diff --git a/dolphin sdk not yet linked/src/os/OSCache.c b/dolphin sdk not yet linked/src/os/OSCache.c new file mode 100644 index 0000000..5d9f58d --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSCache.c @@ -0,0 +1,741 @@ +#include "Dolphin/os.h" +#include "Dolphin/db.h" +#define PPCSYNC sc // system call performs PPCSync() + +// /** +// * @note Address: N/A +// * @note Size: 0x10 +// */ +// void DCFlashInvalidate(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800EC6D8 + * @note Size: 0x14 + */ +ASM void DCEnable(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + + sync + + mfspr r3, HID0 + ori r3, r3, HID0_DCE + mtspr HID0, r3 + + blr +#endif // clang-format on +} + +// /** +// * @note Address: N/A +// * @note Size: 0x14 +// */ +// void DCDisable(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x14 +// */ +// void DCFreeze(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x10 +// */ +// void DCUnfreeze(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x8 +// */ +// void DCTouchLoad(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x8 +// */ +// void DCBlockZero(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x8 +// */ +// void DCBlockStore(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x8 +// */ +// void DCBlockFlush(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x8 +// */ +// void DCBlockInvalidate(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800EC6EC + * @note Size: 0x2C + */ +ASM void DCInvalidateRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes,0 + blelr- + rlwinm r5,addr,0,27,31 + add nBytes,nBytes,r5 + addi nBytes,nBytes,31 + srwi nBytes,nBytes,5 + mtctr nBytes +_loop: + dcbi 0,addr + addi addr,addr,32 + bdnz _loop + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EC718 + * @note Size: 0x30 + */ +ASM void DCFlushRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes,0 + blelr- + rlwinm r5,addr,0,27,31 + add nBytes,nBytes,r5 + addi nBytes,nBytes,31 + srwi nBytes,nBytes,5 + mtctr nBytes +_loop: + dcbf 0,addr + addi addr,addr,32 + bdnz _loop + + PPCSYNC + + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EC748 + * @note Size: 0x30 + */ +ASM void DCStoreRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes,0 + blelr- + rlwinm r5,addr,0,27,31 + add nBytes,nBytes,r5 + addi nBytes,nBytes,31 + srwi nBytes,nBytes,5 + mtctr nBytes +_loop: + dcbst 0,addr + addi addr,addr,32 + bdnz _loop + + PPCSYNC + + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EC778 + * @note Size: 0x2C + */ +ASM void DCFlushRangeNoSync(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes,0 + blelr- + rlwinm r5,addr,0,27,31 + add nBytes,nBytes,r5 + addi nBytes,nBytes,31 + srwi nBytes,nBytes,5 + mtctr nBytes +_loop: + dcbf 0,addr + addi addr,addr,32 + bdnz _loop + + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EC7A4 + * @note Size: 0x2C + */ +ASM void DCStoreRangeNoSync(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes,0 + blelr- + rlwinm r5,addr,0,27,31 + add nBytes,nBytes,r5 + addi nBytes,nBytes,31 + srwi nBytes,nBytes,5 + mtctr nBytes +_loop: + dcbst 0,addr + addi addr,addr,32 + bdnz _loop + + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EC7D0 + * @note Size: 0x2C + */ +ASM void DCZeroRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes,0 + blelr- + rlwinm r5,addr,0,27,31 + add nBytes,nBytes,r5 + addi nBytes,nBytes,31 + srwi nBytes,nBytes,5 + mtctr nBytes +_loop: + dcbz 0,addr + addi addr,addr,32 + bdnz _loop + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +ASM void DCTouchRange(register void* addr, register u32 nBytes) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800EC7FC + * @note Size: 0x34 + */ +ASM void ICInvalidateRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes,0 + blelr- + rlwinm r5,addr,0,27,31 + add nBytes,nBytes,r5 + addi nBytes,nBytes,31 + srwi nBytes,nBytes,5 + mtctr nBytes +_loop: + icbi 0,addr + addi addr,addr,32 + bdnz _loop + sync + isync + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EC830 + * @note Size: 0x10 + */ +ASM void ICFlashInvalidate(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + + mfspr r3, HID0 + ori r3, r3, HID0_ICFI + mtspr HID0, r3 + + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EC840 + * @note Size: 0x14 + */ +ASM void ICEnable(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + + isync + + mfspr r3, HID0 + ori r3, r3, HID0_ICE + mtspr HID0, r3 + + blr +#endif // clang-format on +} + +// /** +// * @note Address: N/A +// * @note Size: 0x14 +// */ +// void ICDisable(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x14 +// */ +// void ICFreeze(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x10 +// */ +// void ICUnfreeze(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x8 +// */ +// void ICBlockInvalidate(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x8 +// */ +// void ICSync(void) +// { +// // UNUSED FUNCTION +// } + +#define CACHE_LINES 1024 +#define LC_LINES 512 + +/** + * @note Address: 0x800EC854 + * @note Size: 0xCC + */ +ASM static void __LCEnable(void) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r5 + ori r5, r5, MSR_ME + mtmsr r5 + lis r3, OS_CACHED_REGION_PREFIX + li r4, CACHE_LINES + mtctr r4 +_loop: + dcbt 0,r3 + dcbst 0,r3 + addi r3,r3,32 + bdnz _loop + + 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 + mtdbatl DBAT3L, r3 + ori r3, r3, 0x01fe + mtdbatu DBAT3U, r3 + isync + + lis r3, LC_BASE_PREFIX + li r6, LC_LINES + mtctr r6 + li r6, 0 + +_lock: + dcbz_l r6, r3 + addi r3, r3, 32 + bdnz+ _lock + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EC920 + * @note Size: 0x38 + */ +void LCEnable(void) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + __LCEnable(); + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800EC958 + * @note Size: 0x28 + */ +ASM void LCDisable(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + + lis r3, LC_BASE_PREFIX + li r4, LC_LINES + mtctr r4 +_loop: + dcbi 0, r3 + addi r3, r3, 32 + bdnz+ _loop + mfspr r4, HID2 + rlwinm r4, r4, 0, HID2_LCE_BIT+1, HID2_LCE_BIT-1 + mtspr HID2, r4 + blr +#endif // clang-format on +} + +// /** +// * @note Address: N/A +// * @note Size: 0x14 +// */ +// void LCAllocOneTag(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x40 +// */ +// void LCAllocTags(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x24 +// */ +// void LCLoadBlocks(void* destTag, void* srcAddr, u32 numBlocks) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800EC980 + * @note Size: 0x24 + */ +ASM void LCStoreBlocks(register void* destAddr, register void* srcTag, register u32 numBlocks) { +#ifdef __MWERKS__ // clang-format off + 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, DMA_L_STORE | DMA_L_TRIGGER + mtspr DMA_L, r6 + blr +#endif // clang-format on +} + +// /** +// * @note Address: N/A +// * @note Size: 0x70 +// */ +// void LCAlloc(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x70 +// */ +// void LCAllocNoInvalidate(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0xAC +// */ +// u32 LCLoadData(void* destAddr, void* srcAddr, u32 nBytes) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800EC9A4 + * @note Size: 0xAC + */ +u32 LCStoreData(void* destAddr, // to main memory destination + void* srcAddr, // from locked cache source + u32 nBytes) +{ + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + LC_MAX_DMA_BLOCKS - 1) / LC_MAX_DMA_BLOCKS; + + while (numBlocks > 0) { + if (numBlocks < LC_MAX_DMA_BLOCKS) { + LCStoreBlocks(destAddr, srcAddr, numBlocks); + numBlocks = 0; + } else { + LCStoreBlocks(destAddr, srcAddr, 0); + numBlocks -= LC_MAX_DMA_BLOCKS; + destAddr = (void*)((u32)destAddr + LC_MAX_DMA_BYTES); + srcAddr = (void*)((u32)srcAddr + LC_MAX_DMA_BYTES); + } + } + + return numTransactions; +} + +// /** +// * @note Address: N/A +// * @note Size: 0xC +// */ +// u32 LCQueueLength(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800ECA50 + * @note Size: 0x14 + */ +ASM void LCQueueWait(register u32 len) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + +_waitloop: + mfspr r4, HID2 + rlwinm r4, r4, 8, 28, 31 + cmpw r4, len + bgt _waitloop + + blr +#endif // clang-format on +} + +// /** +// * @note Address: N/A +// * @note Size: 0x48 +// */ +// void LCFlushQueue(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: N/A + * @note Size: 0x4C + */ +inline static void L2Init(void) +{ + u32 oldMSR; + + oldMSR = PPCMfmsr(); + + __sync(); + PPCMtmsr(MSR_IR | MSR_DR); + __sync(); + + L2Disable(); + + L2GlobalInvalidate(); + + PPCMtmsr(oldMSR); +} + +/** + * @note Address: N/A + * @note Size: 0x2C + */ +inline void L2Enable(void) { PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); } + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +inline void L2Disable(void) +{ + __sync(); + PPCMtl2cr(PPCMfl2cr() & ~L2CR_L2E); + __sync(); +} + +/** + * @note Address: 0x800ECA64 + * @note Size: 0x98 + */ +void L2GlobalInvalidate(void) +{ + L2Disable(); + + PPCMtl2cr(PPCMfl2cr() | L2CR_L2I); + + while (PPCMfl2cr() & L2CR_L2IP) + ; + + PPCMtl2cr(PPCMfl2cr() & ~L2CR_L2I); + + while (PPCMfl2cr() & L2CR_L2IP) { + DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); + } +} + +// /** +// * @note Address: N/A +// * @note Size: 0x40 +// */ +// void L2SetDataOnly(void) +// { +// // UNUSED FUNCTION +// } + +// /** +// * @note Address: N/A +// * @note Size: 0x40 +// */ +// void L2SetWriteThrough(void) +// { +// // UNUSED FUNCTION +// } + +/** + * @note Address: 0x800ECAFC + * @note Size: 0x160 + */ +void DMAErrorHandler(OSError error, OSContext* context, ...) +{ +#pragma unused(error) + 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(); + // spins forever, so not reached + } + + 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); +} + +/** + * @note Address: 0x800ECC5C + * @note Size: 0xF4 + */ +void __OSCacheInit(void) +{ + 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/dolphin sdk not yet linked/src/os/OSContext.c b/dolphin sdk not yet linked/src/os/OSContext.c new file mode 100644 index 0000000..f1d6345 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSContext.c @@ -0,0 +1,709 @@ +#include "Dolphin/os.h" +#include "Dolphin/db.h" + +// necessary for some asm functions +extern void __RAS_OSDisableInterrupts_begin(); +extern void __RAS_OSDisableInterrupts_end(); + +/** + * @note Address: 0x800ECD50 + * @note Size: 0x124 + */ +ASM static void __OSLoadFPUContext(register u32, register OSContext* fpuContext) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800ECE74 + * @note Size: 0x128 + */ +ASM static void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext) { +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +ASM void OSLoadFPUContext(register OSContext* fpuContext) { +#ifdef __MWERKS__ // clang-format off + nofralloc + addi r4, fpuContext, 0 + b __OSLoadFPUContext +#endif // clang-format on +} + +/** + * @note Address: 0x800ECF9C + * @note Size: 0x8 + */ +ASM void OSSaveFPUContext(register OSContext* fpuContext) { +#ifdef __MWERKS__ // clang-format off + nofralloc + addi r5, fpuContext, 0 + b __OSSaveFPUContext +#endif // clang-format on +} + +/** + * @note Address: 0x800ECFA4 + * @note Size: 0x5C + */ +ASM void OSSetCurrentContext(register OSContext* context) { +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800ED000 + * @note Size: 0xC + */ +OSContext* OSGetCurrentContext() +{ + return (OSContext*)__OSCurrentContext; +} + +/** + * @note Address: 0x800ED00C + * @note Size: 0x80 + */ +ASM u32 OSSaveContext(register OSContext* context) { +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800ED08C + * @note Size: 0xD8 + */ +ASM void OSLoadContext(register OSContext* context) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800ED164 + * @note Size: 0x8 + */ +ASM u32 OSGetStackPointer() { +#ifdef __MWERKS__ // clang-format off + nofralloc + mr r3, r1 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +ASM u32 OSSwitchStack(register u32 newsp) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mr r5, r1 + mr r1, newsp + mr r3, r5 + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x30 + */ +ASM int OSSwitchFiber(register u32 pc, register u32 newsp) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800ED16C + * @note Size: 0x24 + */ +void OSClearContext(OSContext* context) +{ + context->mode = 0; + context->state = 0; + if (context == __OSFPUContext) { + __OSFPUContext = nullptr; + } +} + +/** + * @note Address: 0x800ED190 + * @note Size: 0xBC + */ +ASM void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800ED24C + * @note Size: 0x2A8 + */ +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]); + } +} + +/** + * @note Address: 0x800ED4F4 + * @note Size: 0x84 + */ +ASM static void OSSwitchFPUContext(register __OSException exception, register OSContext* context) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800ED578 + * @note Size: 0x48 + */ +void __OSContextInit() +{ + __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); + __OSFPUContext = nullptr; + DBPrintf("FPU-unavailable handler installed\n"); +} + +/** + * @note Address: 0x800ED5C0 + * @note Size: 0x12C + */ +ASM void OSFillFPUContext(register OSContext* context) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/os/OSError.c b/dolphin sdk not yet linked/src/os/OSError.c new file mode 100644 index 0000000..3b925ca --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSError.c @@ -0,0 +1,224 @@ +#include "types.h" +#include "Dolphin/os.h" +#include "stdio.h" +#include "Dolphin/PPCArch.h" +#include "Dolphin/hw_regs.h" + +// All enable +#define FPSCR_ENABLE 0xF8 + +OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; +u32 __OSFpscrEnableBits = FPSCR_ENABLE; + +/** + * @note Address: 0x800ED6EC + * @note Size: 0x80 + */ +WEAKFUNC void OSReport(const char* msg, ...) +{ + va_list marker; + + va_start(marker, msg); + vprintf(msg, marker); + va_end(marker); +} + +/** + * @note Address: N/A + * @note Size: 0x20 + * same as OSReport but without va start/end + */ +WEAKFUNC void OSVReport(const char* msg, va_list list) { vprintf(msg, list); } + +/** + * @note Address: 0x800ED76C + * @note Size: 0x12C + */ +WEAKFUNC 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); + + // actually useful for debugging- stack crawl + OSReport("\nAddress: Back Chain LR Save\n"); + for (i = 0, p = (u32*)OSGetStackPointer(); // get current stack pointer + p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) // get caller stack pointer + { + OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); + } + + PPCHalt(); +} + +/** + * @note Address: 0x800ED898 + * @note Size: 0x218 + */ +OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) +{ + OSErrorHandler oldHandler; + BOOL enabled; + + enabled = OSDisableInterrupts(); + oldHandler = __OSErrorTable[error]; + __OSErrorTable[error] = handler; + + if (error == OS_ERROR_MAX) { + u32 msr; + u32 fpscr; + OSThread* thread; + + msr = PPCMfmsr(); + PPCMtmsr(msr | 0x2000); // Enable FPU + fpscr = PPCMffpscr(); + if (handler) { + for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) { + thread->context.srr1 |= 0x900; + if ((thread->context.state & OS_CONTEXT_STATE_FPSAVED) == 0) { + int i; + + // Initialize FPU context too so that FPSCR can be changed per thread + 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 = 4; + } + thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + thread->context.fpscr &= 0x6005F8FF; // idk what this value represents, but it matches + } + fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + msr |= 0x900; + } else { + for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) { + thread->context.srr1 &= ~(0x900); + thread->context.fpscr &= ~FPSCR_ENABLE; + thread->context.fpscr &= 0x6005F8FF; + } + fpscr &= ~FPSCR_ENABLE; + msr &= ~0x900; + } + + fpscr &= 0x6005F8FF; // mismatch on this line + + PPCMtfpscr(fpscr); + PPCMtmsr(msr); // Restore FPU + } + + OSRestoreInterrupts(enabled); + return oldHandler; +} + +/** + * @note Address: 0x800EDAB0 + * @note Size: 0x2E8 + */ +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) +{ + OSTime now; + + now = OSGetTime(); + + if (!(context->srr1 & 2)) { + OSReport("Non-recoverable Exception %d", exception); + + } else { + if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && __OSErrorTable[OS_ERROR_MAX] != 0) { + u32 fpscr; + u32 msr; + + exception = OS_ERROR_MAX; + + msr = PPCMfmsr(); + PPCMtmsr(msr | 0x2000); + + 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 &= ~0x2000; + __OSFPUContext = nullptr; + + 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 &= ~0x2000; + __OSFPUContext = nullptr; + } + + 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[DSP_DMA_START_HI], __DSPRegs[DSP_DMA_START_LO]); + OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[DSP_ARAM_DMA_MM_HI], __DSPRegs[DSP_ARAM_DMA_MM_LO]); + OSReport("DI DMA Address = 0x%08x\n", __DIRegs[DI_DMA_MEM_ADDR]); + break; + } + + OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, __OSLastInterruptSrr0, __OSLastInterruptTime); + + PPCHalt(); +} diff --git a/src/dolphin/os/src/OSExec.c b/dolphin sdk not yet linked/src/os/OSExec.c similarity index 100% rename from src/dolphin/os/src/OSExec.c rename to dolphin sdk not yet linked/src/os/OSExec.c diff --git a/dolphin sdk not yet linked/src/os/OSFont.c b/dolphin sdk not yet linked/src/os/OSFont.c new file mode 100644 index 0000000..5d4c3e6 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSFont.c @@ -0,0 +1,593 @@ +#include "Dolphin/os.h" +#include "Dolphin/vi.h" +#include "Dolphin/hw_regs.h" +#include "Dolphin/gx.h" + +// outside functions +BOOL __OSReadROM(void* buffer, s32 length, s32 offset); + +static OSFontHeader* FontData; // type unsure +static u8* SheetImage; // type unsure +static u8* WidthTable; // type unsure +static int CharsInSheet; // type unsure + +// clang-format off +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 ZenkakuToCode[] + = { 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 + }; +// clang-format on + +/** + * @note Address: N/A + * @note Size: 0x58 + */ +static BOOL IsSjisLeadByte(u8 letter) +{ + return (0x81 <= letter && letter <= 0x9F) || (0xE0 <= letter && letter <= 0xFC); + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x40 + */ +static BOOL IsSjisTrailByte(u8 letter) { return (letter >= 0x40 && letter <= 0xFC && letter != 0x7F); } + +/** + * @note Address: 0x800EDD98 + * @note Size: 0x19C + */ +static int GetFontCode(u16 code) +{ + int preCode; + int lastByte; + + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) { + if (code >= 0x20 && code <= 0xDF) { + return HankakuToCode[code - 0x20]; + } + + if (code > 0x889E && code <= 0x9872) { + preCode = ((code >> 8) - 0x88) * 188; + lastByte = code & 0xFF; + + if (!IsSjisTrailByte(lastByte)) { + return 0; + } + + lastByte -= 0x40; + + if (lastByte >= 0x40) { + lastByte--; + } + + return (preCode + lastByte + 0x2BE); + } + + if (code >= 0x8140 && code < 0x879E) { + preCode = ((code >> 8) - 0x81) * 188; + lastByte = code & 0xFF; + + if (!IsSjisTrailByte(lastByte)) { + return 0; + } + + lastByte -= 0x40; + + if (lastByte >= 0x40) { + lastByte--; + } + + return ZenkakuToCode[preCode + lastByte]; + } + + } else if (code > 0x20 && code <= 0xFF) { + return code - 0x20; + } + + return 0; +} + +/** + * @note Address: 0x800EDF34 + * @note Size: 0x174 + */ +static void Decode(u8* src, u8* dst) +{ + int j; + int linkOfs; + int chunkPos; + int i; + int maskTblPos; + int linkTblOfs; + int chunksOfs; + int count; + int expandSize; + u32 maskBits; + u32 mask; + + expandSize = *(int*)(src + 0x4); + linkTblOfs = *(int*)(src + 0x8); + chunksOfs = *(int*)(src + 0xC); + + i = 0; + maskBits = 0; + maskTblPos = 16; + + do { + // Get next mask + if (maskBits == 0) { + mask = *(u32*)(src + maskTblPos); + maskTblPos += sizeof(u32); + maskBits = sizeof(u32) * 8; + } + + // Non-linked chunk + if (mask & 0x80000000) { + dst[i++] = src[chunksOfs++]; + } + // Linked chunk + else { + // Read offset from link table + linkOfs = src[linkTblOfs] << 8 | src[linkTblOfs + 1]; + linkTblOfs += sizeof(u16); + + // Apply offset + chunkPos = i - (linkOfs & 0x0FFF); + count = linkOfs >> 12; + if (count == 0) { + count = src[chunksOfs++] + 0x12; + } else { + count += 2; + } + + // Copy chunk + for (j = 0; j < count; j++, i++, chunkPos++) { + dst[i] = dst[chunkPos - 1]; + } + } + + // Prepare next mask bit + mask <<= 1; + maskBits--; + } while (i < expandSize); +} + +/** + * @note Address: N/A + * @note Size: 0x34 + */ +static u32 GetFontSize(u8* in) +{ + if (in[0] == 'Y' && in[1] == 'a' && in[2] == 'y') { + return *(u32*)(in + 0x4); + } + + return 0; +} + +/** + * @note Address: 0x800EE0A8 + * @note Size: 0x58 + */ +u16 OSGetFontEncode(void) +{ + static u16 fontEncode = 0xFFFF; + 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; +} + +/** + * @note Address: 0x800EE100 + * @note Size: 0x8C + */ +static void ReadROM(void* string, int len, int offset) +{ + int inc; + while (len > 0) { + if (len <= 0x100) { + inc = len; + } else { + inc = 0x100; + } + + len -= inc; + + while (!__OSReadROM(string, inc, offset)) { + ; + } + + offset += inc; + (u8*)string += inc; + } +} + +/** + * @note Address: N/A + * @note Size: 0x16C + */ +static u32 ReadFont(void* img, u16 encode, void* fontInfo) +{ + SheetImage = fontInfo; + if (OSGetFontEncode() == encode) { + ReadROM(img, OS_FONT_ROM_SIZE_SJIS, 0x1AFF00); + } else { + ReadROM(img, OS_FONT_ROM_SIZE_ANSI, 0x1FCF00); + } + + return GetFontSize(img); +} + +/** + * @note Address: 0x800EE18C + * @note Size: 0x334 + */ +u32 OSLoadFont(OSFontHeader* fontInfo, void* temp) +{ + u8* image; + u8* ptr; + int fontCodeT, sheet, numChars, row, column, x, y; + + u32 fontSize = ReadFont(temp, OS_FONT_ENCODE_SJIS, nullptr); + if (fontSize) { + Decode(temp, (void*)fontInfo); + FontData = fontInfo; + WidthTable = (u8*)FontData + fontInfo->widthTable; + CharsInSheet = fontInfo->sheetColumn * fontInfo->sheetRow; + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) { + // what is this even doing + + const u16 codes[4] = { 0x2ABE, 0x003D, 0x003D, 0x003D }; + + fontCodeT = GetFontCode('T'); // ???? + sheet = fontCodeT / CharsInSheet; + numChars = fontCodeT - sheet * CharsInSheet; + row = numChars / FontData->sheetColumn; + column = numChars - row * FontData->sheetColumn; + row *= FontData->cellHeight; + column *= FontData->cellWidth; + + image = (u8*)FontData + FontData->sheetImage; + image += sheet * FontData->sheetSize / 2; + + for (y = 4; y < 8; y++) { + x = 0; + ptr = image + (((FontData->sheetWidth / 8) * 32) / 2) * ((row + y) / 8); + ptr += 16 * ((column + x) / 8); + ptr += 2 * ((row + y) % 8); + ptr += ((column + x) % 8) / 4; + + *(u16*)ptr = codes[y - 4]; + } + } + } + + return fontSize; +} + +/** + * @note Address: 0x800EE4C0 + * @note Size: 0x3B0 + */ +static void ExpandFontSheet(u8* source, u8* dest) +{ + int i; + const u8* tmp = &FontData->c0; + + if (FontData->sheetFormat == GX_TF_I4) { + for (i = (s32)FontData->sheetFullSize / 2 - 1; i >= 0; i--) { + dest[i * 2 + 0] = tmp[source[i] >> 6 & 3] & 0xF0 | tmp[source[i] >> 4 & 3] & 0x0F; + dest[i * 2 + 1] = tmp[source[i] >> 2 & 3] & 0xF0 | tmp[source[i] >> 0 & 3] & 0x0F; + } + } else if (FontData->sheetFormat == GX_TF_IA4) { + for (i = (s32)FontData->sheetFullSize / 4 - 1; i >= 0; i--) { + dest[i * 4 + 0] = tmp[source[i] >> 6 & 3]; + dest[i * 4 + 1] = tmp[source[i] >> 4 & 3]; + dest[i * 4 + 2] = tmp[source[i] >> 2 & 3]; + dest[i * 4 + 3] = tmp[source[i] >> 0 & 3]; + } + } + + DCStoreRange(dest, FontData->sheetFullSize); +} + +/** + * @note Address: 0x800EE870 + * @note Size: 0xE0 + */ +BOOL OSInitFont(OSFontHeader* font) +{ + u8* sheets; + void* a; + u32 size; + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) { + a = (u8*)font + 0xD3F00; + } else { + a = (u8*)font + 0x1D120; + } + size = OSLoadFont(font, (void*)((u32)a & ~0x1F)); + if (size == 0) { + return FALSE; + } + + SheetImage = (u8*)FontData + FontData->sheetImage; + SheetImage = (u8*)(((u32)SheetImage + 31) & ~0x1F); // ??? + ExpandFontSheet((u8*)FontData + FontData->sheetImage, (u8*)SheetImage); + + return TRUE; +} + +/** + * @note Address: 0x800EE950 + * @note Size: 0x1A8 + */ +char* OSGetFontTexture(const char* string, void** image, s32* x, s32* y, s32* width) +{ + int numRestTex; + int code; + u32 sheet; + u32 row; + u32 col; + + u16 firstChar = (u8)string[0]; + + if (firstChar == 0) { + ((u32*)image)[0] = 0; + return string; + } + string++; + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) { + if (IsSjisLeadByte(firstChar) && string[0]) { + firstChar = ((firstChar << 8) | (u8)*string++); + } + } + + code = GetFontCode(firstChar); + + // Font sheet on which the texture resides + sheet = code / CharsInSheet; + // Font code texture + *image = (FontData->sheetSize * sheet) + SheetImage; + + // Number of succeeding textures on the sheet + numRestTex = code - (sheet * CharsInSheet); + + // Sheet row on which the texure resides + row = numRestTex / FontData->sheetColumn; + + // Sheet column on which the texture resides + col = numRestTex - row * FontData->sheetColumn; + + // Texture position + *x = col * FontData->cellWidth; + *y = row * FontData->cellHeight; + + if (width) { + *width = WidthTable[code]; + } + + return string; +} + +/** + * @note Address: 0x800EEAF8 + * @note Size: 0x140 + */ +char* OSGetFontWidth(const char* string, s32* width) +{ + u16 firstChar = (u8)string[0]; + + if (firstChar == 0) { + return string; + } + string++; + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) { + if (IsSjisLeadByte(firstChar) && string[0]) { + firstChar = ((firstChar << 8) | (u8)*string++); + } + } + + if (width) { + *width = WidthTable[GetFontCode(firstChar)]; + } + + return string; +} diff --git a/dolphin sdk not yet linked/src/os/OSInterrupt.c b/dolphin sdk not yet linked/src/os/OSInterrupt.c new file mode 100644 index 0000000..91e1a99 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSInterrupt.c @@ -0,0 +1,478 @@ +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +ASM static 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, +}; + +volatile OSTime __OSLastInterruptTime; +volatile __OSInterrupt __OSLastInterrupt; +vu32 __OSLastInterruptSrr0; + +/** + * @note Address: 0x800EEC38 + * @note Size: 0x14 + */ +ASM BOOL OSDisableInterrupts() { +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800EEC4C + * @note Size: 0x14 + */ +ASM BOOL OSEnableInterrupts() { +#ifdef __MWERKS__ // clang-format off + nofralloc + + mfmsr r3 + ori r4, r3, 0x8000 + mtmsr r4 + rlwinm r3, r3, 17, 31, 31 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800EEC60 + * @note Size: 0x24 + */ +ASM BOOL OSRestoreInterrupts(register BOOL level) { +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800EEC84 + * @note Size: 0x1C + */ +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) +{ + __OSInterruptHandler oldHandler; + + oldHandler = InterruptHandlerTable[interrupt]; + InterruptHandlerTable[interrupt] = handler; + return oldHandler; +} + +/** + * @note Address: 0x800EECA0 + * @note Size: 0x14 + */ +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { return InterruptHandlerTable[interrupt]; } + +/** + * @note Address: 0x800EECB4 + * @note Size: 0x74 + */ +void __OSInterruptInit() +{ + InterruptHandlerTable = OSPhysicalToCached(0x3040); + memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); + + __OSPriorInterruptMask = 0; + + __OSCurrentInterruptMask = 0; + + __PIRegs[PI_INTRPT_MASK] = 0xF0; + + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); + + __OSSetExceptionHandler(4, ExternalInterruptHandler); +} + +/** + * @note Address: 0x800EED28 + * @note Size: 0x2D8 + */ +static 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[MEM_INTRPT_MASK] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_MEM; + break; + + case __OS_INTERRUPT_DSP_AI: + case __OS_INTERRUPT_DSP_ARAM: + case __OS_INTERRUPT_DSP_DSP: + reg = __DSPRegs[DSP_CONTROL_STATUS]; + 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[DSP_CONTROL_STATUS] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_DSP; + break; + + case __OS_INTERRUPT_AI_AI: + reg = __AIRegs[AI_CONTROL]; + reg &= ~0x2C; + if (!(current & OS_INTERRUPTMASK_AI_AI)) { + reg |= 0x4; + } + __AIRegs[AI_CONTROL] = 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[EXI_CHAN_0_STAT]; + 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[EXI_CHAN_0_STAT] = 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[EXI_CHAN_1_STAT]; + 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[EXI_CHAN_1_STAT] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_1; + break; + + case __OS_INTERRUPT_EXI_2_EXI: + case __OS_INTERRUPT_EXI_2_TC: + reg = __EXIRegs[EXI_CHAN_2_STAT]; + reg &= ~0xF; + if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) { + reg |= 0x1; + } + if (!(current & OS_INTERRUPTMASK_EXI_2_TC)) { + reg |= 0x4; + } + + __EXIRegs[EXI_CHAN_2_STAT] = 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[PI_INTRPT_MASK] = reg; + mask &= ~OS_INTERRUPTMASK_PI; + break; + + default: + break; + } + + return mask; +} + +/** + * @note Address: 0x800EF000 + * @note Size: 0x88 + */ +OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) +{ + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = __OSPriorInterruptMask; + local = __OSCurrentInterruptMask; + mask = ~(prev | local) & global; + global |= prev; + __OSPriorInterruptMask = global; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + +/** + * @note Address: 0x800EF088 + * @note Size: 0x88 + */ +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) +{ + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = __OSPriorInterruptMask; + local = __OSCurrentInterruptMask; + mask = (prev | local) & global; + global = prev & ~global; + __OSPriorInterruptMask = global; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + +/** + * @note Address: 0x800EF110 + * @note Size: 0x344 + */ +void __OSDispatchInterrupt(__OSException exception, OSContext* context) +{ + u32 intsr; + u32 reg; + OSInterruptMask cause; + OSInterruptMask unmasked; + OSInterruptMask* prio; + __OSInterrupt interrupt; + __OSInterruptHandler handler; + intsr = __PIRegs[PI_INTRPT_SRC]; + intsr &= ~PI_INTRPT_RSWST; + + if (intsr == 0 || (intsr & __PIRegs[PI_INTRPT_MASK]) == 0) { + OSLoadContext(context); + } + + cause = 0; + + if (intsr & PI_INTRPT_MEM) { + reg = __MEMRegs[MEM_INTRPT_SRC]; + 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 & PI_INTRPT_DSP) { + reg = __DSPRegs[DSP_CONTROL_STATUS]; + 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 & PI_INTRPT_AI) { + reg = __AIRegs[AI_CONTROL]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_AI_AI; + } + + if (intsr & PI_INTRPT_EXI) { + reg = __EXIRegs[EXI_CHAN_0_STAT]; + 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[EXI_CHAN_1_STAT]; + 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[EXI_CHAN_2_STAT]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_2_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_2_TC; + } + + if (intsr & PI_INTRPT_HSP) + cause |= OS_INTERRUPTMASK_PI_HSP; + if (intsr & PI_INTRPT_DEBUG) + cause |= OS_INTERRUPTMASK_PI_DEBUG; + if (intsr & PI_INTRPT_PE_FINISH) + cause |= OS_INTERRUPTMASK_PI_PE_FINISH; + if (intsr & PI_INTRPT_PE_TOKEN) + cause |= OS_INTERRUPTMASK_PI_PE_TOKEN; + if (intsr & PI_INTRPT_VI) + cause |= OS_INTERRUPTMASK_PI_VI; + if (intsr & PI_INTRPT_SI) + cause |= OS_INTERRUPTMASK_PI_SI; + if (intsr & PI_INTRPT_DVD) + cause |= OS_INTERRUPTMASK_PI_DI; + if (intsr & PI_INTRPT_RSW) + cause |= OS_INTERRUPTMASK_PI_RSW; + if (intsr & PI_INTRPT_CP) + cause |= OS_INTERRUPTMASK_PI_CP; + if (intsr & PI_INTRPT_ERR) + cause |= OS_INTERRUPTMASK_PI_ERROR; + + unmasked = cause & ~(__OSPriorInterruptMask | __OSCurrentInterruptMask); + 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); +} + +/** + * @note Address: 0x800EF454 + * @note Size: 0x50 + */ +ASM static void ExternalInterruptHandler(register __OSException exception, register OSContext* context) +{ +#pragma unused(exception) +#ifdef __MWERKS__ // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + + stwu r1, -8(r1) + b __OSDispatchInterrupt +#endif // clang-format on +} diff --git a/dolphin sdk not yet linked/src/os/OSLink.c b/dolphin sdk not yet linked/src/os/OSLink.c new file mode 100644 index 0000000..2c5226c --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSLink.c @@ -0,0 +1,26 @@ +#define OS_MODULE_LIST_ADDR 0x800030C8 +#define OS_STRING_TABLE_ADDR 0x800030D0 +#define OS_BASE_CACHED 0x80003000 + +/** + * @note Address: 0x800EF4A4 + * @note Size: 0x18 + */ +struct OSModuleQueue { /* Relocatable Module Queue @ 800030c8 */ + int* pFirst; + int* pLast; +}; + +struct OSModuleQueue __OSModuleInfoList : (OS_BASE_CACHED | OS_MODULE_LIST_ADDR); +const void* __OSStringTable : (OS_BASE_CACHED | OS_STRING_TABLE_ADDR); + +/** + * @note Address: 0x801F979C + * @note Size: 0x18 + */ +void __OSModuleInit(void) +{ + __OSModuleInfoList.pLast = 0; + __OSModuleInfoList.pFirst = 0; + __OSStringTable = 0; +} diff --git a/dolphin sdk not yet linked/src/os/OSMemory.c b/dolphin sdk not yet linked/src/os/OSMemory.c new file mode 100644 index 0000000..6e42ab4 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSMemory.c @@ -0,0 +1,260 @@ +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +// forward declarations. +static BOOL OnReset(BOOL final); + +// Local reset function information. +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, OS_RESET_PRIO_MEM }; + +// useful macros. +#define TRUNC(n, a) (((u32)(n)) & ~((a) - 1)) +#define ROUND(n, a) (((u32)(n) + (a) - 1) & ~((a) - 1)) + +/** + * @note Address: N/A + * @note Size: 0xC + */ +static u32 OSGetPhysicalMemSize() { return *(u32*)(OSPhysicalToCached(0x28)); } + +/** + * @note Address: N/A + * @note Size: 0xC + */ +static u32 OSGetConsoleSimulatedMemSize() { return *(u32*)(OSPhysicalToCached(0xF0)); } + +/** + * @note Address: 0x800EF794 + * @note Size: 0x3C + */ +static BOOL OnReset(BOOL final) +{ + if (final != FALSE) { + __MEMRegs[MEM_PROT_TYPE] = 0xFF; + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_RESET); + } + return TRUE; +} + +/** + * @note Address: 0x800EF7D0 + * @note Size: 0x6C + */ +static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u32 addr; + u32 cause; + + cause = __MEMRegs[MEM_INTRPT_SRC]; + addr = (((u32)__MEMRegs[MEM_INTRPT_ADDR_HI] & 0x3ff) << 16) | __MEMRegs[MEM_INTRPT_ADDR_LO]; + __MEMRegs[MEM_INTRPT_FLAG] = 0; + + if (__OSErrorTable[OS_ERROR_PROTECTION]) { + __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr); + return; + } + + __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr); +} + +/** + * @note Address: 0x800EF83C + * @note Size: 0xC4 + */ +void OSProtectRange(u32 channel, void* addr, u32 numBytes, u32 control) +{ + BOOL enabled; + u32 start; + u32 end; + u16 reg; + if (channel >= 4) { + return; + } + + control &= OS_PROTECT_CONTROL_RDWR; + + end = (u32)addr + numBytes; + start = TRUNC(addr, 1u << 10); + end = ROUND(end, 1u << 10); + + DCFlushRange((void*)start, end - start); + + enabled = OSDisableInterrupts(); + + __OSMaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + channel)); + + __MEMRegs[0 + 2 * channel] = (u16)(start >> 10); + __MEMRegs[1 + 2 * channel] = (u16)(end >> 10); + + reg = __MEMRegs[MEM_PROT_TYPE]; + reg &= ~(OS_PROTECT_CONTROL_RDWR << 2 * channel); + reg |= control << 2 * channel; + __MEMRegs[MEM_PROT_TYPE] = reg; + + if (control != OS_PROTECT_CONTROL_RDWR) { + __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + channel)); + } + + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800EF900 + * @note Size: 0x80 + */ +ASM static void Config24MB() +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800EF980 + * @note Size: 0x80 + */ +ASM static void Config48MB() +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800EFA00 + * @note Size: 0x18 + */ +ASM static void RealMode(register u32 addr) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + clrlwi r3, r3, 2 + mtsrr0 r3 + mfmsr r3 + rlwinm r3, r3, 0, 28, 25 + mtsrr1 r3 + rfi +#endif // clang-format on +} + +/** + * @note Address: 0x800EFA18 + * @note Size: 0x118 + */ +void __OSInitMemoryProtection() +{ + u32 padding[8]; + u32 simulatedSize; + BOOL enabled; + simulatedSize = OSGetConsoleSimulatedMemSize(); + enabled = OSDisableInterrupts(); + + __MEMRegs[MEM_INTRPT_FLAG] = 0; + __MEMRegs[MEM_PROT_TYPE] = 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[MEM_UNK_FLAG] = 2; + } + + if (simulatedSize <= 0x1800000) { + RealMode((u32)&Config24MB); + } else if (simulatedSize <= 0x3000000) { + RealMode((u32)&Config48MB); + } + + __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); + OSRestoreInterrupts(enabled); +} diff --git a/dolphin sdk not yet linked/src/os/OSMessage.c b/dolphin sdk not yet linked/src/os/OSMessage.c new file mode 100644 index 0000000..7058198 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSMessage.c @@ -0,0 +1,113 @@ +#include "Dolphin/os.h" + +// TODO: this matches, but breaks JKRAramStream with types etc, need to fix both together + +/** + * @note Address: 0x800EF4BC + * @note Size: 0x60 + */ +void OSInitMessageQueue(OSMessageQueue* queue, OSMessage* msgArray, s32 msgCount) +{ + OSInitThreadQueue(&queue->queueSend); + OSInitThreadQueue(&queue->queueReceive); + queue->msgArray = msgArray; + queue->msgCount = msgCount; + queue->firstIndex = 0; + queue->usedCount = 0; +} + +/** + * When (`flags` & 1), then this function blocks execution of the current + * thread if `queue` is full, until such a time that it is no longer full. + * When not (`flags` & 1), this function returns `false` immediately if + * `queue` is full. This function returns `true` when the message is + * successfully queued. + * @note Address: 0x800EF51C + * @note Size: 0xC8 + */ +BOOL OSSendMessage(OSMessageQueue* queue, void* msg, s32 flags) +{ + int mesgId; + u32 interrupt; + + interrupt = OSDisableInterrupts(); + + while (queue->msgCount <= queue->usedCount) { + if (!(flags & OS_MSG_PERSISTENT)) { + OSRestoreInterrupts(interrupt); + return FALSE; + } + + OSSleepThread(&queue->queueSend); + } + + mesgId = (queue->firstIndex + queue->usedCount) % queue->msgCount; + queue->msgArray[mesgId] = msg; + queue->usedCount++; + + OSWakeupThread(&queue->queueReceive); + OSRestoreInterrupts(interrupt); + return TRUE; +} + +/** + * @note Address: 0x800EF5E4 + * @note Size: 0xDC + */ +BOOL OSReceiveMessage(OSMessageQueue* queue, void** buffer, s32 flags) +{ + u32 interrupt; + + interrupt = OSDisableInterrupts(); + + while (queue->usedCount == 0) { + if (!(flags & OS_MSG_PERSISTENT)) { + OSRestoreInterrupts(interrupt); + return FALSE; + } + + OSSleepThread(&queue->queueReceive); + } + + if (buffer) { + buffer[0] = queue->msgArray[queue->firstIndex]; + } + + queue->firstIndex = (queue->firstIndex + 1) % queue->msgCount; + queue->usedCount--; + + OSWakeupThread(&queue->queueSend); + OSRestoreInterrupts(interrupt); + return TRUE; +} + +/** + * @note Address: 0x800EF6C0 + * @note Size: 0xD4 + */ +BOOL OSJamMessage(OSMessageQueue* queue, void* msg, s32 flags) +{ + s32 lastMesg; + u32 interrupt; + + interrupt = OSDisableInterrupts(); + + while (queue->msgCount <= queue->usedCount) { + if (!(flags & OS_MSG_PERSISTENT)) { + OSRestoreInterrupts(interrupt); + return FALSE; + } + + OSSleepThread(&queue->queueSend); + } + + // Find last position in queue + lastMesg = (queue->firstIndex + queue->msgCount - 1) % queue->msgCount; + queue->firstIndex = lastMesg; + queue->msgArray[queue->firstIndex] = msg; + queue->usedCount++; + + OSWakeupThread(&queue->queueReceive); + OSRestoreInterrupts(interrupt); + return TRUE; +} diff --git a/dolphin sdk not yet linked/src/os/OSMutex.c b/dolphin sdk not yet linked/src/os/OSMutex.c new file mode 100644 index 0000000..d71a547 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSMutex.c @@ -0,0 +1,150 @@ +#include "Dolphin/os.h" + +/** + * @note Address: 0x800EFB30 + * @note Size: 0x38 + */ +void OSInitMutex(OSMutex* mutex) +{ + OSInitThreadQueue(&mutex->queue); + mutex->thread = nullptr; + mutex->count = 0; +} + +/** + * @note Address: 0x800EFB68 + * @note Size: 0xDC + */ +void OSLockMutex(OSMutex* mutex) +{ + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + OSThread* ownerThread; + + while (TRUE) { + ownerThread = mutex->thread; + if (ownerThread == 0) { + mutex->thread = currentThread; + mutex->count++; + AddTailMutex(¤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 = nullptr; + } + } + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800EFC44 + * @note Size: 0xC8 + */ +void OSUnlockMutex(OSMutex* mutex) +{ + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + + if (mutex->thread == currentThread && --mutex->count == 0) { + RemoveItemMutex(¤tThread->queueMutex, mutex, link); + mutex->thread = nullptr; + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); + } + + OSWakeupThread(&mutex->queue); + } + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800EFD0C + * @note Size: 0x70 + */ +void __OSUnlockAllMutex(OSThread* thread) +{ + OSMutex* mutex; + + while (thread->queueMutex.head) { + RemoveHeadMutex(&thread->queueMutex, mutex, link); + mutex->count = 0; + mutex->thread = nullptr; + OSWakeupThread(&mutex->queue); + } +} + +/** + * @note Address: 0x800EFD7C + * @note Size: 0xBC + */ +BOOL OSTryLockMutex(OSMutex* mutex) +{ + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + BOOL locked; + + if (mutex->thread == nullptr) { + mutex->thread = currentThread; + mutex->count++; + AddTailMutex(¤tThread->queueMutex, mutex, link); + locked = TRUE; + + } else if (mutex->thread == currentThread) { + mutex->count++; + locked = TRUE; + + } else { + locked = FALSE; + } + + OSRestoreInterrupts(enabled); + return locked; +} + +/** + * @note Address: 0x800EFE38 + * @note Size: 0x20 + */ +void OSInitCond(OSCond* cond) { OSInitThreadQueue(&cond->queue); } + +/** + * @note Address: 0x800EFE58 + * @note Size: 0xD4 + */ +void OSWaitCond(OSCond* cond, OSMutex* mutex) +{ + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + s32 count; + + if (mutex->thread == currentThread) { + count = mutex->count; + mutex->count = 0; + RemoveItemMutex(¤tThread->queueMutex, mutex, link); + mutex->thread = nullptr; + + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); + } + + OSDisableScheduler(); + OSWakeupThread(&mutex->queue); + OSEnableScheduler(); + OSSleepThread(&cond->queue); + OSLockMutex(mutex); + mutex->count = count; + } + + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800EFF2C + * @note Size: 0x20 + */ +void OSSignalCond(OSCond* cond) { OSWakeupThread(&cond->queue); } diff --git a/dolphin sdk not yet linked/src/os/OSReboot.c b/dolphin sdk not yet linked/src/os/OSReboot.c new file mode 100644 index 0000000..0ca42bf --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSReboot.c @@ -0,0 +1,172 @@ +#include "Dolphin/os.h" +#include "Dolphin/ai.h" + +static void* SaveStart = nullptr; +static void* SaveEnd = nullptr; +static BOOL Prepared; + +extern u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0); //(*(u32 *)0x812fdff0) +extern u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC); //(*(u32 *)0x812fdfec) +extern u32 OS_RESET_CODE AT_ADDRESS(0x800030F0); +extern u8 OS_REBOOT_BOOL AT_ADDRESS(0x800030E2); // unknown function, set to true by __OSReboot + +extern void* __OSSavedRegionStart; +extern void* __OSSavedRegionEnd; + +// 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 ATTRIBUTE_ALIGN(32); + +/** + * @note Address: N/A + * @note Size: 0x38 + */ +BOOL IsStreamEnabled(void) +{ + if (DVDGetCurrentDiskID()->streaming) { + return TRUE; + } + return FALSE; +} + +/** + * @note Address: 0x800EFF4C + * @note Size: 0x10 + */ +ASM static void Run(register u32 addr) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + + sync + isync + mtlr addr + blr +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0xD8 + */ +void ReadApploader(OSTime time1) +{ + if (!DVDCheckDisk() || OSGetTime() - time1 > OS_TIMER_CLOCK) { + __OSDoHotReset(0); + } +} + +/** + * @note Address: 0x800EFF5C + * @note Size: 0xC + */ +static void Callback(void) { Prepared = TRUE; } + +/** + * @note Address: 0x800EFF68 + * @note Size: 0x330 + */ +void __OSReboot(u32 resetCode, u32 bootDol) +{ + OSContext exceptionContext; + OSTime time1; + DVDCommandBlock dvdCmd; + DVDCommandBlock dvdCmd2; + DVDCommandBlock dvdCmd3; + u32 numBytes; + u32 offset; + OSDisableInterrupts(); + OS_RESET_CODE = resetCode; + 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(0xffffffe0); + __OSUnmaskInterrupts(0x400); + OSEnableInterrupts(); + + time1 = OSGetTime(); + while (Prepared != TRUE) { + ReadApploader(time1); + }; + + if (!__OSIsGcam) { + if (IsStreamEnabled()) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&dvdCmd, nullptr); + time1 = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd)) { + ReadApploader(time1); + } + + AISetStreamPlayState(0); + } + } + + DVDReadAbsAsyncPrio(&dvdCmd2, Header.date, 32, 0x2440, nullptr, 0); + + time1 = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd2)) { + ReadApploader(time1); + } + + offset = Header.size + 0x20; + numBytes = OSRoundUp32B(Header.rebootSize); + DVDReadAbsAsyncPrio(&dvdCmd3, (void*)(OS_BOOTROM_ADDR), numBytes, offset + 0x2440, nullptr, 0); + + time1 = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd3)) { + ReadApploader(time1); + } + + ICInvalidateRange((void*)(OS_BOOTROM_ADDR), numBytes); + OSDisableInterrupts(); + ICFlashInvalidate(); + Run(OS_BOOTROM_ADDR); +} + +/** + * @note Address: 0x800F0298 + * @note Size: 0xC + */ +void OSSetSaveRegion(void* start, void* end) +{ + SaveStart = start; + SaveEnd = end; +} + +/** + * @note Address: N/A + * @note Size: 0x14 + */ +void OSGetSaveRegion(void** start, void** end) +{ + *start = SaveStart; + *end = SaveEnd; +} + +/** + * @note Address: N/A + * @note Size: 0x14 + */ +void OSGetSavedRegion(void** start, void** end) +{ + *start = __OSSavedRegionStart; + *end = __OSSavedRegionEnd; +} diff --git a/dolphin sdk not yet linked/src/os/OSReset.c b/dolphin sdk not yet linked/src/os/OSReset.c new file mode 100644 index 0000000..39aae74 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSReset.c @@ -0,0 +1,223 @@ +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +static OSResetQueue ResetFunctionQueue; +static u32 bootThisDol; + +/** + * @note Address: 0x800F02A4 + * @note Size: 0x84 + */ +void OSRegisterResetFunction(OSResetFunctionInfo* info) +{ + OSResetFunctionInfo* tmp; + OSResetFunctionInfo* iter; + + for (iter = ResetFunctionQueue.head; iter && iter->priority <= info->priority; iter = iter->next) { + ; + } + + if (iter == nullptr) { + tmp = ResetFunctionQueue.tail; + if (tmp == nullptr) { + ResetFunctionQueue.head = info; + } else { + tmp->next = info; + } + info->prev = tmp; + info->next = nullptr; + ResetFunctionQueue.tail = info; + return; + } + + info->next = iter; + tmp = iter->prev; + iter->prev = info; + info->prev = tmp; + if (tmp == nullptr) { + ResetFunctionQueue.head = info; + return; + } + tmp->next = info; +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +BOOL __OSCallResetFunctions(BOOL final) +{ + OSResetFunctionInfo* iter; + BOOL retCode = FALSE; + + for (iter = ResetFunctionQueue.head; (iter != nullptr && retCode == FALSE); iter = iter->next) { + retCode |= !iter->func(final); + } + + retCode |= !__OSSyncSram(); + + if (retCode) { + return FALSE; + } + return TRUE; +} + +/** + * @note Address: 0x800F0328 + * @note Size: 0x70 + */ +ASM static void Reset(register s32 resetCode) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + b _jump1 + +_begin: + mfspr r8, HID0 + ori r8, r8, 8 + mtspr HID0, r8 + isync + sync + nop + b _preloop + +_jump1: + b _jump2 + +_preloop: + mftb r5, 268 +_loop: + mftb r6, 268 + subf r7, r5, r6 + cmplwi r7, 0x1124 + blt _loop + nop + b _setPIReg + +_jump2: + b _jump3 + +_setPIReg: + lis r8, 0xCC003000@h + ori r8, r8, 0xCC003000@l + li r4, 3 + stw r4, 0x24(r8) + stw r3, 0x24(r8) + nop + b _noptrap + +_jump3: + b _jump4 + +_noptrap: + nop + b _noptrap + +_jump4: + b _begin +#endif // clang-format on +} + +/** + * @note Address: N/A + * @note Size: 0x68 + */ +static void KillThreads() +{ + 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; + } + } +} + +/** + * @note Address: 0x800F0398 + * @note Size: 0x48 + */ +void __OSDoHotReset(s32 code) +{ + OSDisableInterrupts(); + __VIRegs[VI_DISP_CONFIG] = 0; + ICFlashInvalidate(); + Reset(code * 8); +} + +/** + * @note Address: 0x800F03E0 + * @note Size: 0x2BC + */ +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()) { + ; + } + resetCode = 0; + } + + 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); +} + +/** + * @note Address: 0x800F069C + * @note Size: 0x34 + */ +u32 OSGetResetCode() +{ + if (*(u8*)OSPhysicalToCached(0x30E2) != 0) { + return *(u32*)OSPhysicalToCached(0x30F0) | 0x80000000; + } + + return ((__PIRegs[PI_RESETCODE] & ~7) >> 3); +} diff --git a/dolphin sdk not yet linked/src/os/OSResetSW.c b/dolphin sdk not yet linked/src/os/OSResetSW.c new file mode 100644 index 0000000..5806112 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSResetSW.c @@ -0,0 +1,97 @@ +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +static OSResetCallback ResetCallback; +static BOOL Down; +static BOOL LastState; +static OSTime HoldUp; +static OSTime HoldDown; + +/** + * @note Address: 0x800F06D0 + * @note Size: 0xF4 + */ +void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSResetCallback callback; + + HoldDown = __OSGetSystemTime(); + while (__OSGetSystemTime() - HoldDown < OSMicrosecondsToTicks(100) && !(__PIRegs[PI_INTRPT_SRC] & PI_INTRPT_RSWST)) { + ; + } + if (!(__PIRegs[PI_INTRPT_SRC] & PI_INTRPT_RSWST)) { + LastState = Down = TRUE; + __OSMaskInterrupts(OS_INTERRUPTMASK_PI_RSW); + if (ResetCallback) { + callback = ResetCallback; + ResetCallback = nullptr; + callback(); + } + } + __PIRegs[PI_INTRPT_SRC] = 2; +} + +/** + * @note Address: 0x800F07C4 + * @note Size: 0x298 + */ +BOOL OSGetResetButtonState() +{ + BOOL enabled; + BOOL state; + u32 reg; + OSTime now; + + enabled = OSDisableInterrupts(); + + now = __OSGetSystemTime(); + + reg = __PIRegs[PI_INTRPT_SRC]; + if (!(reg & PI_INTRPT_RSWST)) { + 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; +} + +/** + * @note Address: 0x800F0A5C + * @note Size: 0x20 + */ +BOOL OSGetResetSwitchState() { return OSGetResetButtonState(); } diff --git a/dolphin sdk not yet linked/src/os/OSRtc.c b/dolphin sdk not yet linked/src/os/OSRtc.c new file mode 100644 index 0000000..84e33e5 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSRtc.c @@ -0,0 +1,477 @@ +#include "Dolphin/os.h" + +// forward declarations. +static BOOL WriteSram(void* buffer, u32 offset, u32 size); + +static SramControlBlock Scb ATTRIBUTE_ALIGN(32); + +/** + * @note Address: N/A + * @note Size: 0x118 + */ +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, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIImm(RTC_CHAN, &cmd, 4, 0, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + *rtc = cmd; + + return !err; +} + +/** + * @note Address: N/A + * @note Size: 0x22C + */ +static 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; +} + +/** + * @note Address: N/A + * @note Size: 0x108 + */ +static 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, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIImm(RTC_CHAN, &rtc, 4, 1, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +/** + * @note Address: N/A + * @note Size: 0x11C + */ +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, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIDma(RTC_CHAN, buffer, RTC_SRAM_SIZE, 0, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +/** + * @note Address: 0x800F0A7C + * @note Size: 0x60 + */ +static void WriteSramCallback(s32 channel, OSContext* context) +{ + Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); + if (Scb.sync) { + Scb.offset = RTC_SRAM_SIZE; + } +} + +/** + * @note Address: 0x800F0ADC + * @note Size: 0x118 + */ +static 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, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIImmEx(RTC_CHAN, buffer, (s32)size, 1); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +/** + * @note Address: 0x800F0BF4 + * @note Size: 0x13C + */ +void __OSInitSram() +{ + Scb.locked = Scb.enabled = FALSE; + Scb.sync = ReadSram(Scb.sram); + Scb.offset = RTC_SRAM_SIZE; + OSSetGbsMode(OSGetGbsMode()); +} + +/** + * @note Address: N/A + * @note Size: 0x68 + */ +static void* LockSram(u32 offset) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + + if (Scb.locked != FALSE) { + OSRestoreInterrupts(enabled); + return nullptr; + } + + Scb.enabled = enabled; + Scb.locked = TRUE; + + return Scb.sram + offset; +} + +/** + * @note Address: 0x800F0D30 + * @note Size: 0x5C + */ +OSSram* __OSLockSram() { return LockSram(0); } + +/** + * @note Address: 0x800F0D8C + * @note Size: 0x5C + */ +OSSramEx* __OSLockSramEx() { return LockSram(sizeof(OSSram)); } + +/** + * @note Address: 0x800F0DE8 + * @note Size: 0x33C + */ +static BOOL UnlockSram(BOOL commit, u32 offset) +{ + u16* p; + u16* ptr2; + + 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; +} + +/** + * @note Address: 0x800F1124 + * @note Size: 0x24 + */ +BOOL __OSUnlockSram(BOOL commit) { return UnlockSram(commit, 0); } + +/** + * @note Address: 0x800F1148 + * @note Size: 0x24 + */ +BOOL __OSUnlockSramEx(BOOL commit) { return UnlockSram(commit, sizeof(OSSram)); } + +/** + * @note Address: 0x800F116C + * @note Size: 0x10 + */ +BOOL __OSSyncSram() { return Scb.sync; } + +/** + * @note Address: 0x800F117C + * @note Size: 0x124 + */ +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, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIDma(RTC_CHAN, buffer, length, 0, nullptr); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +/** + * @note Address: 0x800F12A0 + * @note Size: 0x80 + */ +u32 OSGetSoundMode() +{ + OSSram* sram; + u32 mode; + u32 tmp; // dumbass compiler + + sram = LockSram(0); + mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; + __OSUnlockSram(FALSE); + return mode; +} + +/** + * @note Address: 0x800F1320 + * @note Size: 0xA4 + */ +void OSSetSoundMode(u32 mode) +{ + OSSram* sram; + u32 tmp; // dumbass compiler + + mode <<= 2; + mode &= 4; + + sram = LockSram(0); + if (mode == (sram->flags & 4)) { + __OSUnlockSram(FALSE); + return; + } + + sram->flags &= ~4; + sram->flags |= mode; + __OSUnlockSram(TRUE); +} + +/** + * @note Address: 0x800F13C4 + * @note Size: 0x70 + */ +u32 OSGetProgressiveMode() +{ + OSSram* sram; + u32 mode; + u32 tmp; // dumbass compiler + + sram = LockSram(0); + mode = (sram->flags & 0x80) >> 7; + __OSUnlockSram(FALSE); + return mode; +} + +/** + * @note Address: 0x800F1434 + * @note Size: 0xA4 + */ +void OSSetProgressiveMode(u32 mode) +{ + OSSram* sram; + u32 tmp; // dumbass compiler + + mode <<= 7; + mode &= 0x80; + + sram = LockSram(0); + if (mode == (sram->flags & 0x80)) { + __OSUnlockSram(FALSE); + return; + } + + sram->flags &= ~0x80; + sram->flags |= mode; + __OSUnlockSram(TRUE); +} + +/** + * @note Address: 0x800F14D8 + * @note Size: 0xA4 + */ +void OSSetEuRgb60Mode(u32 on) +{ + OSSram* sram; + u32 tmp; // dumbass compiler + + on <<= 6; + on &= 0x40; + + sram = LockSram(0); + if (on == (sram->ntd & 0x40)) { + __OSUnlockSram(FALSE); + return; + } + + sram->ntd &= ~0x40; + sram->ntd |= on; + __OSUnlockSram(TRUE); +} + +/** + * @note Address: 0x800F157C + * @note Size: 0x84 + */ +u16 OSGetWirelessID(s32 channel) +{ + OSSramEx* sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->wirelessPadID[channel]; + __OSUnlockSramEx(FALSE); + return id; +} + +/** + * @note Address: 0x800F1600 + * @note Size: 0xAC + */ +void OSSetWirelessID(s32 channel, u16 id) +{ + OSSramEx* sram; + + sram = __OSLockSramEx(); + if (sram->wirelessPadID[channel] != id) { + sram->wirelessPadID[channel] = id; + __OSUnlockSramEx(TRUE); + return; + } + + __OSUnlockSramEx(FALSE); +} + +/** + * @note Address: 0x800F16AC + * @note Size: 0x70 + */ +u16 OSGetGbsMode() +{ + OSSramEx* sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->gbs; + __OSUnlockSramEx(FALSE); + return id; +} + +/** + * @note Address: 0x800F171C + * @note Size: 0xB8 + */ +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); +} diff --git a/src/dolphin/os/src/OSSemaphore.c b/dolphin sdk not yet linked/src/os/OSSemaphore.c similarity index 100% rename from src/dolphin/os/src/OSSemaphore.c rename to dolphin sdk not yet linked/src/os/OSSemaphore.c diff --git a/dolphin sdk not yet linked/src/os/OSSync.c b/dolphin sdk not yet linked/src/os/OSSync.c new file mode 100644 index 0000000..9ae4f8c --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSSync.c @@ -0,0 +1,40 @@ +#include "Dolphin/os.h" + +/** + * @note Address: 0x800F17D4 + * @note Size: 0x20 + */ +ASM static void SystemCallVector() +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + + entry __OSSystemCallVectorStart + mfspr r9, DBSR + ori r10, r9, 8 + mtspr DBSR, r10 + isync + sync + mtspr DBSR, r9 + rfi + + entry __OSSystemCallVectorEnd + nop +#endif // clang-format on +} + +/** + * @note Address: 0x800F17F4 + * @note Size: 0x64 + */ +void __OSInitSystemCall() +{ + void* handler = OS_SYS_CALL_HANDLER; + memcpy(handler, __OSSystemCallVectorStart, (u32)__OSSystemCallVectorEnd - (u32)__OSSystemCallVectorStart); + + DCFlushRangeNoSync(handler, OS_HANDLER_SLOT_SIZE); +#ifdef __MWERKS__ // clang-format off + asm { sync } +#endif // clang-format on + ICInvalidateRange(handler, OS_HANDLER_SLOT_SIZE); +} diff --git a/dolphin sdk not yet linked/src/os/OSThread.c b/dolphin sdk not yet linked/src/os/OSThread.c new file mode 100644 index 0000000..58ea3ff --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSThread.c @@ -0,0 +1,634 @@ +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.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; + +// Fabricated helper inlines. +// Initialise mutex queue (mutex equiv. to OSInitThreadQueue below). +static inline void InitMutexQueue(OSMutexQueue* queue) { queue->head = queue->tail = NULL; } + +// Set current thread. +static inline void SetCurrentThread(OSThread* thread) +{ + SwitchThreadCallback(__OSCurrentThread, thread); + __OSCurrentThread = thread; +} + +/** + * @note Address: 0x800F1858 + * @note Size: 0x4 + */ +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) { } + +/** + * @note Address: 0x800F185C + * @note Size: 0x158 + */ +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 = nullptr; + OSInitThreadQueue(&thread->queueJoin); + InitMutexQueue(&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; + + SetCurrentThread(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; +} + +/** + * @note Address: 0x800F19B4 + * @note Size: 0x10 + */ +void OSInitThreadQueue(OSThreadQueue* threadQueue) { threadQueue->head = threadQueue->tail = nullptr; } + +/** + * @note Address: 0x800F19C4 + * @note Size: 0xC + */ +OSThread* OSGetCurrentThread() { return __OSCurrentThread; } + +/** + * @note Address: N/A + * @note Size: 0x5C + */ +static void __OSSwitchThread(OSThread* nextThread) +{ + SwitchThreadCallback(__OSCurrentThread, nextThread); + __OSCurrentThread = nextThread; + OSSetCurrentContext(&nextThread->context); + OSLoadContext(&nextThread->context); +} + +/** + * @note Address: 0x800F19D0 + * @note Size: 0x34 + */ +BOOL OSIsThreadTerminated(OSThread* thread) +{ + return (thread->state == OS_THREAD_STATE_MORIBUND || thread->state == OS_THREAD_STATE_NULL) ? TRUE : FALSE; +} + +/** + * @note Address: 0x800F1A04 + * @note Size: 0x40 + */ +s32 OSDisableScheduler() +{ + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule++; + OSRestoreInterrupts(enabled); + return count; +} + +/** + * @note Address: 0x800F1A44 + * @note Size: 0x40 + */ +s32 OSEnableScheduler() +{ + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule--; + OSRestoreInterrupts(enabled); + return count; +} + +/** + * @note Address: N/A + * @note Size: 0x6C + */ +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 +/** + * @note Address: 0x800F1A84 + * @note Size: 0x68 + */ +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 = nullptr; +} +#pragma dont_inline reset + +/** + * @note Address: 0x800F1AEC + * @note Size: 0x3C + */ +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; +} + +/** + * @note Address: 0x800F1B28 + * @note Size: 0x1C0 + */ +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 nullptr; +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +static void UpdatePriority(OSThread* thread) +{ + OSPriority priority; + + do { + if (thread->suspend > 0) { + break; + } + priority = __OSGetEffectivePriority(thread); + if (thread->priority == priority) { + break; + } + thread = SetEffectivePriority(thread, priority); + } while (thread); +} + +/** + * @note Address: 0x800F1CE8 + * @note Size: 0x50 + */ +void __OSPromoteThread(OSThread* thread, OSPriority priority) +{ + do { + if (thread->suspend > 0) { + break; + } + if (thread->priority <= priority) { + break; + } + + thread = SetEffectivePriority(thread, priority); + } while (thread); +} + +/** + * @note Address: 0x800F1D38 + * @note Size: 0x228 + */ +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; +} + +/** + * @note Address: 0x800F1F60 + * @note Size: 0x30 + */ +void __OSReschedule() +{ + if (!RunQueueHint) { + return; + } + + SelectThread(FALSE); +} + +/** + * @note Address: 0x800F1F90 + * @note Size: 0x3C + */ +void OSYieldThread() +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + SelectThread(TRUE); + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800F1FCC + * @note Size: 0x1E8 + */ +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); + InitMutexQueue(&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[16] != 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; +} + +/** + * @note Address: 0x800F21B4 + * @note Size: 0xE4 + */ +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); +} + +/** + * @note Address: 0x800F2298 + * @note Size: 0x1BC + */ +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 = OS_THREAD_STATE_NULL; + } else { + thread->state = OS_THREAD_STATE_MORIBUND; + } + + __OSUnlockAllMutex(thread); + + OSWakeupThread(&thread->queueJoin); + + __OSReschedule(); + OSRestoreInterrupts(enabled); + + return; +} + +/** + * @note Address: 0x800F2454 + * @note Size: 0xA0 + */ +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); +} + +/** + * @note Address: 0x800F24F4 + * @note Size: 0x288 + */ +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; +} + +/** + * @note Address: 0x800F277C + * @note Size: 0x170 + */ +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; +} + +/** + * @note Address: 0x800F28EC + * @note Size: 0xEC + */ +void OSSleepThread(OSThreadQueue* threadQueue) +{ + BOOL enabled; + OSThread* currentThread; + + enabled = OSDisableInterrupts(); + currentThread = OSGetCurrentThread(); + + currentThread->state = OS_THREAD_STATE_WAITING; + currentThread->queue = threadQueue; + AddPrio(threadQueue, currentThread, link); + RunQueueHint = TRUE; + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800F29D8 + * @note Size: 0x104 + */ +void OSWakeupThread(OSThreadQueue* threadQueue) +{ + BOOL enabled; + OSThread* thread; + + enabled = OSDisableInterrupts(); + while (threadQueue->head) { + RemoveHead(threadQueue, thread, link); + thread->state = OS_THREAD_STATE_READY; + if (!(0 < thread->suspend)) { + SetRun(thread); + } + } + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800F2ADC + * @note Size: 0x8 + */ +OSPriority OSGetThreadPriority(OSThread* thread) { return thread->base; } + +/** + * @note Address: 0x800F2AE4 + * @note Size: 0xAC + */ +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/dolphin sdk not yet linked/src/os/OSTime.c b/dolphin sdk not yet linked/src/os/OSTime.c new file mode 100644 index 0000000..1865aad --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSTime.c @@ -0,0 +1,142 @@ +#include "Dolphin/os.h" + +#define OS_TIME_MONTH_MAX 12 +#define OS_TIME_WEEK_DAY_MAX 7 +#define OS_TIME_YEAR_DAY_MAX 365 +#define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400) + +// 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 }; + +/** + * @note Address: 0x800F2B90 + * @note Size: 0x18 + */ +ASM s64 OSGetTime() { +#ifdef __MWERKS__ // clang-format off + nofralloc + + mftbu r3 + mftb r4 + + // Check for possible carry from TBL to TBU + mftbu r5 + cmpw r3, r5 + bne OSGetTime + + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800F2BA8 + * @note Size: 0x8 + */ +ASM u32 OSGetTick() { +#ifdef __MWERKS__ // clang-format off + nofralloc + + mftb r3 + blr +#endif // clang-format on +} + +/** + * @note Address: 0x800F2BB0 + * @note Size: 0x64 + */ +OSTime __OSGetSystemTime() +{ + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OSPhysicalToCached(0x30D8)); + OSTime result; + + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + OSGetTime(); + OSRestoreInterrupts(enabled); + + return result; +} + +/** + * @note Address: N/A + * @note Size: 0x88 + */ +static BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } + +/** + * @note Address: N/A + * @note Size: 0x50 + */ +static s32 GetLeapDays(s32 year) +{ + if (year < 1) { + return 0; + } + return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; +} + +/** + * @note Address: 0x800F2C14 + * @note Size: 0x19C + */ +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; +} + +#pragma dont_inline on +/** + * @note Address: 0x800F2DB0 + * @note Size: 0x204 + */ +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* cal) +{ + int days; + int secs; + OSTime d; + + d = ticks % OSSecondsToTicks(1); + if (d < 0) { + d += OSSecondsToTicks(1); + } + cal->usec = (int)(OSTicksToMicroseconds(d) % 1000); + cal->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, cal); + + cal->hour = secs / 60 / 60; + cal->min = (secs / 60) % 60; + cal->sec = secs % 60; +} +#pragma dont_inline reset diff --git a/dolphin sdk not yet linked/src/os/__ppc_eabi_init.cpp b/dolphin sdk not yet linked/src/os/__ppc_eabi_init.cpp new file mode 100644 index 0000000..2010d10 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/__ppc_eabi_init.cpp @@ -0,0 +1,88 @@ +#include "types.h" +#include "Dolphin/os.h" +#include "Dolphin/PPCArch.h" + +#ifdef __cplusplus +extern "C" { +#endif +typedef void (*voidfunctionptr)(); // pointer to function returning void +DECL_SECT(".ctors") extern voidfunctionptr _ctors[]; +DECL_SECT(".dtors") extern voidfunctionptr _dtors[]; + +static void __init_cpp(); + +DECL_SECT(".init") +ASM void __init_hardware() { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r0 + ori r0,r0,0x2000 + mtmsr r0 + mflr r31 + bl __OSPSInit + bl __OSFPRInit + bl __OSCacheInit + mtlr r31 + blr +#endif // clang-format on +} + +DECL_SECT(".init") ASM void __flush_cache(u32 addr, int size) +{ +#ifdef __MWERKS__ // clang-format off + 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800F2FB4 + * @note Size: 0x20 + */ +void __init_user() { __init_cpp(); } + +/** + * @note Address: 0x800F2FD4 + * @note Size: 0x54 + */ +static void __init_cpp() +{ + voidfunctionptr* constructor; + /** + * call static initializers + */ + for (constructor = _ctors; *constructor; constructor++) { + (*constructor)(); + } +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +void __fini_cpp() +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F3028 + * @note Size: 0x20 + */ +void _ExitProcess() { PPCHalt(); } +#ifdef __cplusplus +} +#endif diff --git a/dolphin sdk not yet linked/src/os/__start.c b/dolphin sdk not yet linked/src/os/__start.c new file mode 100644 index 0000000..687b12d --- /dev/null +++ b/dolphin sdk not yet linked/src/os/__start.c @@ -0,0 +1,214 @@ +#include "Dolphin/__start.h" + +#pragma section code_type ".init" + +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; } + +WEAKFUNC ASM void __start(void) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +ASM static void __init_registers(void) +{ +#ifdef __MWERKS__ // 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 +#endif // clang-format on +} + +DECL_SECT(".init") extern __rom_copy_info _rom_copy_info[]; +DECL_SECT(".init") extern __bss_init_info _bss_init_info[]; + +inline static void __copy_rom_section(void* dst, const void* src, u32 size) +{ + if (size && (dst != src)) { + memcpy(dst, src, size); + __flush_cache(dst, size); + } +} + +inline static void __init_bss_section(void* dst, u32 size) +{ + if (size) { + memset(dst, 0, size); + } +} + +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/dolphin sdk not yet linked/src/pad/Pad.c b/dolphin sdk not yet linked/src/pad/Pad.c new file mode 100644 index 0000000..787f8c8 --- /dev/null +++ b/dolphin sdk not yet linked/src/pad/Pad.c @@ -0,0 +1,912 @@ +#include "Dolphin/pad.h" +#include "Dolphin/si.h" +#include "Dolphin/os.h" + +const char* __PADVersion = "<< Dolphin SDK - PAD\trelease build: Aug 6 2003 04:30:02 (0x2301) >>"; + +// forward declarations of static functions. +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 BOOL OnReset(BOOL final); + +// static symbols. +static u32 Type[SI_MAX_CHAN]; +static PADStatus Origin[SI_MAX_CHAN]; +static u32 CmdProbeDevice[SI_MAX_CHAN]; + +static s32 ResettingChan = 32; +static u32 XPatchBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT; +static u32 AnalogMode = 0x00000300u; +static u32 Spec = 5; +static void (*MakeStatus)(s32, PADStatus*, u32[2]) = SPEC2_MakeStatus; + +static u32 CmdReadOrigin = 0x41 << 24; +static u32 CmdCalibrate = 0x42 << 24; + +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 127 }; + +static BOOL Initialized; + +static u32 EnabledBits; +static u32 ResettingBits; +static u32 RecalibrateBits; +static u32 WaitingBits; +static u32 CheckingBits; +static u32 PendingBits; +static u32 BarrelBits; + +static void (*SamplingCallback)(void); + +// global symbols +u32 __PADSpec; + +// useful macros +#define offsetof(type, memb) ((u32) & ((type*)0)->memb) + +/** + * @note Address: N/A + * @note Size: 0x60 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0xA4 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +static void DoReset(void) +{ + u32 chanBit; + + ResettingChan = __cntlzw(ResettingBits); + if (ResettingChan == 32) { + return; + } + + ASSERT(0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + + chanBit = PAD_CHAN0_BIT >> ResettingChan; + ResettingBits &= ~chanBit; + + memset(&Origin[ResettingChan], 0, sizeof(PADStatus)); + SIGetTypeAsync(ResettingChan, (SITypeAndStatusCallback)PADTypeAndStatusCallback); +} + +/** + * @note Address: 0x800F3540 + * @note Size: 0x1A4 + */ +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; + } + } +} + +/** + * @note Address: 0x800F36E4 + * @note Size: 0xC4 + */ +static void PADOriginCallback(s32 chan, u32 error, OSContext* context) +{ + ASSERT(0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERT(chan == ResettingChan); + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) { + UpdateOrigin(ResettingChan); + PADEnable(ResettingChan); + } + DoReset(); +} + +/** + * @note Address: 0x800F37A8 + * @note Size: 0xCC + */ +static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context) +{ + ASSERT(0 <= chan && chan < SI_MAX_CHAN); + + if (!(EnabledBits & (PAD_CHAN0_BIT >> chan))) { + return; + } + + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) { + UpdateOrigin(chan); + } + + if (error & SI_ERROR_NO_RESPONSE) { + PADDisable(chan); + } +} + +/** + * @note Address: 0x800F3874 + * @note Size: 0xD8 + */ +static void PADProbeCallback(s32 chan, u32 error, OSContext* context) +{ + ASSERT(0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERT(chan == ResettingChan); + ASSERT((Type[chan] & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && !(Type[chan] & SI_WIRELESS_LITE)); + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) { + PADEnable(ResettingChan); + WaitingBits |= PAD_CHAN0_BIT >> ResettingChan; + } + DoReset(); +} + +/** + * @note Address: 0x800F394C + * @note Size: 0x32C + */ +static void PADTypeAndStatusCallback(s32 chan, u32 type) +{ + u32 chanBit; + u32 recalibrate; + BOOL rc = TRUE; + u32 error; + + ASSERT(0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERT(chan == ResettingChan); + + 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, (SICallback)PADOriginCallback, 0); + } else { + rc = SITransfer(ResettingChan, &CmdReadOrigin, 1, &Origin[ResettingChan], 10, (SICallback)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, (SICallback)PADOriginCallback, 0); + } else { + rc = SITransfer(ResettingChan, &CmdProbeDevice[ResettingChan], 3, &Origin[ResettingChan], 8, (SICallback)PADProbeCallback, 0); + } + } + if (!rc) { + PendingBits |= chanBit; + DoReset(); + return; + } +} + +/** + * @note Address: 0x800F3C78 + * @note Size: 0x140 + */ +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, (SICallback)PADOriginUpdateCallback, 0); + } else { + PADDisable(chan); + } +} + +/** + * @note Address: 0x800F3DB8 + * @note Size: 0x110 + */ +BOOL PADReset(u32 mask) +{ + BOOL enabled; + u32 diableBits; + + ASSERTMSG((mask & ~(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT)) == 0, "PADReset(): invalid mask"); + + 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; +} + +/** + * @note Address: 0x800F3EC8 + * @note Size: 0x114 + */ +BOOL PADRecalibrate(u32 mask) +{ + BOOL enabled; + u32 disableBits; + + ASSERTMSG((mask & ~(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT)) == 0, "PADReset(): invalid mask"); + enabled = OSDisableInterrupts(); + + mask |= PendingBits; + PendingBits = 0; + mask &= ~(WaitingBits | CheckingBits); + ResettingBits |= mask; + disableBits = ResettingBits & EnabledBits; + EnabledBits &= ~mask; + BarrelBits &= ~mask; + + if (!(GameChoice & 0x40)) { + RecalibrateBits |= mask; + } + + SIDisablePolling(disableBits); + if (ResettingChan == 32) { + DoReset(); + } + OSRestoreInterrupts(enabled); + return TRUE; +} + +/** + * @note Address: 0x800F3FDC + * @note Size: 0x150 + */ +BOOL PADInit(void) +{ + 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); +} + +/** + * @note Address: 0x800F412C + * @note Size: 0x300 + */ +u32 PADRead(PADStatus* status) +{ + BOOL enabled; + s32 chan; + u32 data[2]; + u32 chanBit; + u32 sr; + s32 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, (SITypeAndStatusCallback)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, (SICallback)PADOriginUpdateCallback, 0); + continue; + } + + status->err = PAD_ERR_NONE; + + // Clear PAD_INTERFERE bit + status->button &= ~0x0080; + } + + OSRestoreInterrupts(enabled); + return motor; +} + +/** + * @note Address: N/A + * @note Size: 0xCC + */ +void PADControlAllMotors(u32* commandArray) +{ + BOOL enabled; + s32 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; + } + + SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); + commit = TRUE; + } + } + if (commit) { + SITransferCommands(); + } + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800F442C + * @note Size: 0xB8 + */ +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 (GameChoice & 0x20) { + command = PAD_MOTOR_STOP; + } + + SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); + SITransferCommands(); + } + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800F44E4 + * @note Size: 0x60 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +u32 PADGetSpec(void) { return Spec; } + +/** + * @note Address: 0x800F4544 + * @note Size: 0x174 + */ +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; +} + +/** + * @note Address: 0x800F46B8 + * @note Size: 0x174 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x54 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +static u8 ClampU8(u8 var, u8 org) +{ + if (var < org) { + var = org; + } + return var -= org; +} + +/** + * @note Address: 0x800F482C + * @note Size: 0x470 + */ +static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) +{ + PADStatus* origin; + u32 type; + + 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; + + type = Type[chan]; + + 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; + return; + } 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); +} + +/** + * @note Address: N/A + * @note Size: 0x74 + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x64 + */ +BOOL PADSync(void) { return ResettingBits == 0 && ResettingChan == 32 && !SIBusy(); } + +/** + * @note Address: 0x800F4C9C + * @note Size: 0x74 + */ +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); +} + +/** + * @note Address: 0x800F4D10 + * @note Size: 0xBC + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void __PADDisableXPatch(void) { XPatchBits = 0; } + +/** + * @note Address: 0x800F4DCC + * @note Size: 0x60 + */ +static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + + if (SamplingCallback) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + SamplingCallback(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +/** + * @note Address: 0x800F4E2C + * @note Size: 0x54 + */ +PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback) +{ + PADSamplingCallback prev; + + prev = SamplingCallback; + SamplingCallback = callback; + if (callback) { + SIRegisterPollingHandler(SamplingHandler); + } else { + SIUnregisterPollingHandler(SamplingHandler); + } + return prev; +} + +/** + * @note Address: 0x800F4E80 + * @note Size: 0x7C + */ +BOOL __PADDisableRecalibration(BOOL disable) +{ + BOOL enabled; + BOOL prev; + + enabled = OSDisableInterrupts(); + prev = (GameChoice & 0x40) ? TRUE : FALSE; + GameChoice &= ~0x40; + if (disable) { + GameChoice |= 0x40; + } + OSRestoreInterrupts(enabled); + return prev; +} diff --git a/dolphin sdk not yet linked/src/pad/Padclamp.c b/dolphin sdk not yet linked/src/pad/Padclamp.c new file mode 100644 index 0000000..4ff8d22 --- /dev/null +++ b/dolphin sdk not yet linked/src/pad/Padclamp.c @@ -0,0 +1,188 @@ +#include "types.h" +#include "Dolphin/pad.h" +#include "math.h" + +typedef struct PADClampRegion { + u8 minTrigger; + u8 maxTrigger; + s8 minStick; + s8 maxStick; + s8 xyStick; + s8 minSubstick; + s8 maxSubstick; + s8 xySubstick; + s8 radStick; + s8 radSubstick; +} PADClampRegion; + +static const PADClampRegion ClampRegion = { + // Triggers + 30, + 180, + + // Left stick + 15, + 72, + 40, + + // Right stick + 15, + 59, + 31, + + // Stick radii + 56, + 44, +}; + +/** + * @note Address: 0x800F3048 + * @note Size: 0x130 + */ +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); +} + +/** + * @note Address: 0x800F3178 + * @note Size: 0x1A8 + */ +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 = dolsqrtf(squared); + x = (x * radius) / length; + y = (y * radius) / length; + } + + *px = x; + *py = y; +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +inline void ClampTrigger(u8* trigger, u8 min, u8 max) +{ + if (*trigger <= min) { + *trigger = 0; + } else { + if (max < *trigger) { + *trigger = max; + } + *trigger -= min; + } +} + +/** + * @note Address: 0x800F3320 + * @note Size: 0x114 + */ +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); + } +} + +/** + * @note Address: 0x800F3434 + * @note Size: 0x10C + */ +void PADClampCircle(PADStatus* status) +{ + int i; + for (i = 0; i < 4; ++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/dolphin sdk not yet linked/src/si/SIBios.c b/dolphin sdk not yet linked/src/si/SIBios.c new file mode 100644 index 0000000..2090ed0 --- /dev/null +++ b/dolphin sdk not yet linked/src/si/SIBios.c @@ -0,0 +1,894 @@ +#include "Dolphin/si.h" +#include "Dolphin/hw_regs.h" + +char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Apr 17 2003 12:33:19 (0x2301) >>"; + +static SIControl Si = { -1, 0, 0, nullptr, nullptr }; +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]; +static BOOL InputBufferValid[SI_MAX_CHAN]; +static u32 InputBuffer[SI_MAX_CHAN][2]; +static vu32 InputBufferVcount[SI_MAX_CHAN]; + +u32 __PADFixBits; + +// forward-declared static functions. +static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback); +static BOOL SIGetResponseRaw(s32 chan); +static void GetTypeCallback(s32 chan, u32 error, OSContext* context); + +// useful macros. +#define ROUND(n, a) (((u32)(n) + (a) - 1) & ~((a) - 1)) + +/** + * @note Address: 0x800F4EFC + * @note Size: 0x20 + */ +BOOL SIBusy() { return Si.chan != -1 ? TRUE : FALSE; } + +/** + * @note Address: 0x800F4F1C + * @note Size: 0x3C + */ +BOOL SIIsChanBusy(s32 chan) { return Packet[chan].chan != -1 || Si.chan == chan; } + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +void SIClearTCInterrupt(void) +{ + u32 reg; + + reg = __SIRegs[SI_CC_STAT]; + reg |= 0x80000000; + reg &= ~0x00000001; + __SIRegs[SI_CC_STAT] = reg; +} + +/** + * @note Address: 0x800F4F58 + * @note Size: 0x2FC + */ +static u32 CompleteTransfer(void) +{ + u32 sr; + u32 i; + u32 rLen; + u8* input; + + sr = __SIRegs[SI_STAT]; + + 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[SI_IO_BUFFER + i]; + input += 4; + } + + rLen = Si.inputBytes & 3; + if (rLen) { + u32 temp = __SIRegs[SI_IO_BUFFER + i]; + + for (i = 0; i < rLen; i++) { + *input++ = (u8)((temp >> ((3 - i) * 8)) & 0xff); + } + } + + if (__SIRegs[SI_CC_STAT] & 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; +} + +/** + * @note Address: N/A + * @note Size: 0xF0 + */ +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; + } + } +} + +/** + * @note Address: 0x800F5254 + * @note Size: 0x344 + */ +static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u32 reg; + + reg = __SIRegs[SI_CC_STAT]; + + 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[SI_STAT]; + sr &= 0xf000000 >> (8 * chan); + __SIRegs[SI_STAT] = 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); + } + } + } +} + +/** + * @note Address: 0x800F5598 + * @note Size: 0x98 + */ +static BOOL SIEnablePollingInterrupt(BOOL doEnable) +{ + BOOL enabled; + BOOL rc; + u32 reg; + int i; + + enabled = OSDisableInterrupts(); + reg = __SIRegs[SI_CC_STAT]; + rc = (reg & 0x08000000) ? TRUE : FALSE; + + if (doEnable) { + reg |= 0x08000000; + for (i = 0; i < SI_MAX_CHAN; ++i) { + InputBufferVcount[i] = 0; + } + + } else { + reg &= ~0x08000000; + } + + reg &= ~0x80000001; + __SIRegs[SI_CC_STAT] = reg; + + OSRestoreInterrupts(enabled); + return rc; +} + +/** + * @note Address: 0x800F5630 + * @note Size: 0xCC + */ +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; +} + +/** + * @note Address: 0x800F56FC + * @note Size: 0xF4 + */ +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; + } + } + + OSRestoreInterrupts(enabled); + return FALSE; +} + +/** + * @note Address: 0x800F57F0 + * @note Size: 0xB4 + */ +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[SI_CC_STAT] & 1) { + ; + } + + __SIRegs[SI_CC_STAT] = 0x80000000; + + __OSSetInterruptHandler(__OS_INTERRUPT_PI_SI, SIInterruptHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_SI); + + SIGetType(0); + SIGetType(1); + SIGetType(2); + SIGetType(3); +} + +/** + * @note Address: 0x800F58A4 + * @note Size: 0x20C + */ +static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback) +{ + BOOL enabled; + u32 rLen; + u32 i; + u32 sr; + SIComm comcsr; + + enabled = OSDisableInterrupts(); + if (Si.chan != -1) { + OSRestoreInterrupts(enabled); + return FALSE; + } + + sr = __SIRegs[SI_STAT]; + sr &= (0xF000000) >> (8 * chan); + __SIRegs[SI_STAT] = 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[SI_IO_BUFFER + i] = ((u32*)output)[i]; + } + + comcsr.val = __SIRegs[SI_CC_STAT]; + comcsr.flags.tcint = 1; + comcsr.flags.tcintmsk = callback ? 1 : 0; + comcsr.flags.outlngth = (outputBytes == SI_MAX_COMCSR_OUTLNGTH) ? 0 : outputBytes; + comcsr.flags.inlngth = (inputBytes == SI_MAX_COMCSR_INLNGTH) ? 0 : inputBytes; + comcsr.flags.channel = chan; + comcsr.flags.tstart = 1; + __SIRegs[SI_CC_STAT] = comcsr.val; + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0x108 + */ +u32 SISync(void) +{ + BOOL enabled; + u32 sr; + + while (__SIRegs[SI_CC_STAT] & 1) { + ; + } + + enabled = OSDisableInterrupts(); + sr = CompleteTransfer(); + + SITransferNext(SI_MAX_CHAN); + + OSRestoreInterrupts(enabled); + + return sr; +} + +/** + * @note Address: 0x800F5AB0 + * @note Size: 0x7C + */ +u32 SIGetStatus(s32 chan) +{ + BOOL enabled; + u32 sr; + s32 chanShift; + + enabled = OSDisableInterrupts(); + + sr = __SIRegs[SI_STAT]; + 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; +} + +/** + * @note Address: 0x800F5B2C + * @note Size: 0x14 + */ +void SISetCommand(s32 chan, u32 command) { __SIRegs[3 * chan] = command; } + +/** + * @note Address: N/A + * @note Size: 0x14 + */ +u32 SIGetCommand(s32 chan) { return __SIRegs[3 * chan]; } + +/** + * @note Address: 0x800F5B40 + * @note Size: 0x10 + */ +void SITransferCommands(void) { __SIRegs[SI_STAT] = 0x80000000; } + +/** + * @note Address: 0x800F5B50 + * @note Size: 0x6C + */ +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[SI_POLL] = poll; + + OSRestoreInterrupts(enabled); + return poll; +} + +/** + * @note Address: 0x800F5BBC + * @note Size: 0x9C + */ +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[SI_POLL] = poll; + + OSRestoreInterrupts(enabled); + + return poll; +} + +/** + * @note Address: 0x800F5C58 + * @note Size: 0x6C + */ +u32 SIDisablePolling(u32 poll) +{ + BOOL enabled; + + if (poll == 0) { + return Si.poll; + } + + enabled = OSDisableInterrupts(); + + poll >>= (31 - 7); + poll &= 0xF0; + + poll = Si.poll & ~poll; + + __SIRegs[SI_POLL] = poll; + Si.poll = poll; + + OSRestoreInterrupts(enabled); + return poll; +} + +/** + * @note Address: 0x800F5CC4 + * @note Size: 0xD4 + */ +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; +} + +/** + * @note Address: 0x800F5D98 + * @note Size: 0xC4 + */ +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; +} + +/** + * @note Address: 0x800F5E5C + * @note Size: 0x8C + */ +static void AlarmHandler(OSAlarm* alarm, OSContext* 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; + } + } +} + +/** + * @note Address: 0x800F5EE8 + * @note Size: 0x16C + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x78 + */ +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); + } + } +} + +/** + * @note Address: 0x800F6054 + * @note Size: 0x298 + */ +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]); +} + +/** + * @note Address: 0x800F62EC + * @note Size: 0x1C4 + */ +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; +} + +/** + * @note Address: 0x800F64B0 + * @note Size: 0x13C + */ +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; +} + +/** + * @note Address: 0x800F65EC + * @note Size: 0x14C + */ +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; + } + + 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; + } + + 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; +} + +/** + * @note Address: 0x800F6738 + * @note Size: 0x24 + */ +u32 SIProbe(s32 chan) { return SIDecodeType(SIGetType(chan)); } + +/** + * @note Address: N/A + * @note Size: 0x158 + */ +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"; + } +} diff --git a/dolphin sdk not yet linked/src/si/SISamplingRate.c b/dolphin sdk not yet linked/src/si/SISamplingRate.c new file mode 100644 index 0000000..28a8368 --- /dev/null +++ b/dolphin sdk not yet linked/src/si/SISamplingRate.c @@ -0,0 +1,76 @@ +#include "types.h" +#include "Dolphin/OS.h" +#include "Dolphin/vi.h" + +extern u32 SISetXY(int x, int y); + +struct tvformat { + u16 mTvShort; + u8 mTvByte; +}; + +u16 _viRegList : 0xCC00206C; + +static u32 SamplingRate; +static struct tvformat XYNTSC[12] = { 0x00F6, 0x02, 0x000F, 0x12, 0x001E, 0x09, 0x002C, 0x06, 0x0034, 0x05, 0x0041, 0x04, + 0x0057, 0x03, 0x0057, 0x03, 0x0057, 0x03, 0x0083, 0x02, 0x0083, 0x02, 0x0083, 0x02 }; +static struct tvformat XYPAL[12] = { 0x0128, 0x02, 0x000F, 0x15, 0x001D, 0x0B, 0x002D, 0x07, 0x0034, 0x06, 0x003F, 0x05, + 0x004E, 0x04, 0x0068, 0x03, 0x0068, 0x03, 0x0068, 0x03, 0x0068, 0x03, 0x009C, 0x02 }; + +/** + * @brief Sets the controller port sampling rate in milliseconds. + * + * All the attached controller devices share the same sampling rate setting. + * Since the sampling rate is controlled by the Flipper's video clock, the actual sampling rate set differs from the one specified. + * + * @param msec The desired sampling rate in milliseconds. If the value is greater than 11, it will be set to 11. + * + * @note Address: 0x800F675C + * @note Size: 0xE4 + */ +void SISetSamplingRate(u32 msec) +{ + BOOL interruptState; + u16 viRegList; + int xScale; + struct tvformat* format; // r4 + + if (msec > 11) { + msec = 11; + } + + interruptState = OSDisableInterrupts(); + SamplingRate = msec; + + switch (VIGetTvFormat()) { + case VI_NTSC: + case VI_MPAL: + case VI_EURGB60: + format = XYNTSC; + break; + case VI_PAL: + format = XYPAL; + break; + default: + OSReport("SISetSamplingRate: unknown TV format. Use default."); + msec = 0; + format = XYNTSC; + break; + } + + viRegList = (_viRegList); + if ((viRegList & 1) != 0) { + xScale = 2; + } else { + xScale = 1; + } + + SISetXY(xScale * format[msec].mTvShort, format[msec].mTvByte); + OSRestoreInterrupts(interruptState); +} + +/** + * @note Address: 0x800F6840 + * @note Size: 0x24 + */ +void SIRefreshSamplingRate(void) { SISetSamplingRate(SamplingRate); } diff --git a/dolphin sdk not yet linked/src/thp/THPAudio.c b/dolphin sdk not yet linked/src/thp/THPAudio.c new file mode 100644 index 0000000..04b7320 --- /dev/null +++ b/dolphin sdk not yet linked/src/thp/THPAudio.c @@ -0,0 +1,165 @@ +#include "THP/THPAudio.h" +#include "stl/limits.h" + +/** + * @note Address: 0x800FE6B0 + * @note Size: 0x3B0 + */ +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; + + yn += 0x8000; + + if (yn > INT_MAX) { + yn = INT_MAX; + } + + if (yn < INT_MIN) { + yn = INT_MIN; + } + + *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; + yn += 0x8000; + + if (yn > INT_MAX) { + yn = INT_MAX; + } + + if (yn < INT_MIN) { + yn = INT_MIN; + } + + *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; + + yn += 0x8000; + + if (yn > INT_MAX) { + yn = INT_MAX; + } + + if (yn < INT_MIN) { + yn = INT_MIN; + } + + *decRightPtr = (s16)(yn >> 16); + decRightPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + } + + return header->sampleSize; +} + +/** + * @note Address: 0x800FEA60 + * @note Size: 0x90 + */ +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; +} + +/** + * @note Address: 0x800FEAF0 + * @note Size: 0x3C + */ +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++; +} diff --git a/dolphin sdk not yet linked/src/thp/THPDec.c b/dolphin sdk not yet linked/src/thp/THPDec.c new file mode 100644 index 0000000..5849ca0 --- /dev/null +++ b/dolphin sdk not yet linked/src/thp/THPDec.c @@ -0,0 +1,2330 @@ +#include "THP/THPVideoDecode.h" +#include "THP/THP.h" + +char* __THPVersion = "<< Dolphin SDK - THP\trelease build: Jan 9 2004 13:06:55 (0x2301) >>"; + +static THPHuffmanTab* Ydchuff ATTRIBUTE_ALIGN(32); +static THPHuffmanTab* Udchuff ATTRIBUTE_ALIGN(32); +static THPHuffmanTab* Vdchuff ATTRIBUTE_ALIGN(32); +static THPHuffmanTab* Yachuff ATTRIBUTE_ALIGN(32); +static THPHuffmanTab* Uachuff ATTRIBUTE_ALIGN(32); +static THPHuffmanTab* Vachuff ATTRIBUTE_ALIGN(32); +static f32 __THPIDCTWorkspace[64] ATTRIBUTE_ALIGN(32); +static u8* __THPHuffmanBits; +static u8* __THPHuffmanSizeTab; +static u16* __THPHuffmanCodeTab; +static THPSample* Gbase ATTRIBUTE_ALIGN(32); +static u32 Gwid ATTRIBUTE_ALIGN(32); +static f32* Gq ATTRIBUTE_ALIGN(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 THPROUNDUP(a, b) ((((s32)(a)) + ((s32)(b) - 1L)) / ((s32)(b))) + +/** + * Decodes a THP video file. + * + * @param file Pointer to the THP video file. + * @param tileY Pointer to the output tile for Y component. + * @param tileU Pointer to the output tile for U component. + * @param tileV Pointer to the output tile for V component. + * @param work Pointer to the work area. + * @return Error code indicating the success or failure of the decoding process. + * + * @note Address: 0x800F7148 + * @note Size: 0x244 + */ +s32 THPVideoDecode(void* file, void* tileY, void* tileU, void* tileV, void* workArea) +{ + u8 all_done, status; + s32 errorCode; + + if (!file) { + goto _err_no_input; + } + + if (tileY == NULL || tileU == NULL || tileV == NULL) { + goto _err_no_output; + } + + if (!workArea) { + goto _err_no_work; + } + + if (!(PPCMfhid2() & 0x10000000)) { + goto _err_lc_not_enabled; + } + + if (__THPInitFlag == FALSE) { + goto _err_not_initialized; + } + + __THPWorkArea = (u8*)workArea; + __THPInfo = (THPFileInfo*)OSRoundUp32B(__THPWorkArea); + __THPWorkArea = (u8*)OSRoundUp32B(__THPWorkArea) + sizeof(THPFileInfo); + + DCZeroRange(__THPInfo, sizeof(THPFileInfo)); + __THPInfo->cnt = 33; + __THPInfo->decompressedY = 0; + __THPInfo->file = (u8*)file; + + all_done = FALSE; + + for (;;) { + if ((*(__THPInfo->file)++) != 0xFF) { + goto _err_bad_syntax; + } + + while (*__THPInfo->file == 0xFF) { + ((__THPInfo->file)++); + } + + status = (*(__THPInfo->file)++); + + if (status <= 0xD7) { + if (status == 0xC4) { + 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->file += (__THPInfo->file)[0] << 8 | (__THPInfo->file)[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; +} + +/** + * @note Address: 0x800F738C + * @note Size: 0x44 + */ +static void __THPSetupBuffers(void) +{ + u8 i; + THPCoeff* buffer; + + buffer = (THPCoeff*)OSRoundUp32B(__THPWorkArea); + + for (i = 0; i < 6; i++) { + __THPMCUBuffer[i] = &buffer[i * 64]; + } +} + +/** + * @note Address: 0x800F73D0 + * @note Size: 0x13C + */ +static u8 __THPReadFrameHeader(void) +{ + u8 i, utmp8; + + __THPInfo->file += 2; + + utmp8 = (*(__THPInfo->file)++); + + if (utmp8 != 8) { + return 10; + } + + __THPInfo->yPixelSize = (u16)((__THPInfo->file)[0] << 8 | (__THPInfo->file)[1]); + __THPInfo->file += 2; + __THPInfo->xPixelSize = (u16)((__THPInfo->file)[0] << 8 | (__THPInfo->file)[1]); + __THPInfo->file += 2; + + utmp8 = (*(__THPInfo->file)++); + if (utmp8 != 3) { + return 12; + } + + for (i = 0; i < 3; i++) { + utmp8 = (*(__THPInfo->file)++); + utmp8 = (*(__THPInfo->file)++); + if ((i == 0 && utmp8 != 0x22) || (i > 0 && utmp8 != 0x11)) { + return 19; + } + + __THPInfo->components[i].quantizationTableSelector = (*(__THPInfo->file)++); + } + + return 0; +} + +/** + * @note Address: 0x800F750C + * @note Size: 0x11C + */ +static u8 __THPReadScaneHeader(void) +{ + u8 i, utmp8; + __THPInfo->file += 2; + + utmp8 = (*(__THPInfo->file)++); + + if (utmp8 != 3) { + return 12; + } + + for (i = 0; i < 3; i++) { + utmp8 = (*(__THPInfo->file)++); + + utmp8 = (*(__THPInfo->file)++); + __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->file += 3; + __THPInfo->MCUsPerRow = (u16)THPROUNDUP(__THPInfo->xPixelSize, 16); + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + return 0; +} + +/** + * @note Address: 0x800F7628 + * @note Size: 0x3BC + */ +static u8 __THPReadQuantizationTable(void) +{ + u16 length, id, i, row, col; + f32 q_temp[64]; + + length = (u16)((__THPInfo->file)[0] << 8 | (__THPInfo->file)[1]); + __THPInfo->file += 2; + length -= 2; + + for (;;) { + id = (*(__THPInfo->file)++); + + for (i = 0; i < 64; i++) { + q_temp[__THPJpegNaturalOrder[i]] = (f32)(*(__THPInfo->file)++); + } + + 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; +} + +/** + * @note Address: 0x800F79E4 + * @note Size: 0x1E0 + */ +static 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->file)[0] << 8 | (__THPInfo->file)[1]); + __THPInfo->file += 2; + length -= 2; + + for (;;) { + i = (*(__THPInfo->file)++); + id = (u8)(i & 15); + t_class = (u8)(i >> 4); + __THPHuffmanBits = __THPInfo->file; + tab_index = (u8)((id << 1) + t_class); + num_Vij = 0; + + for (i = 0; i < 16; i++) { + num_Vij += (*(__THPInfo->file)++); + } + + __THPInfo->huffmanTabs[tab_index].Vij = __THPInfo->file; + __THPInfo->file += num_Vij; + __THPHuffGenerateSizeTable(); + __THPHuffGenerateCodeTable(); + __THPHuffGenerateDecoderTables(tab_index); + __THPInfo->validHuffmanTabs |= 1 << tab_index; + length -= 17 + num_Vij; + + if (length == 0) { + break; + } + } + + return 0; +} + +/** + * @note Address: 0x800F7BC4 + * @note Size: 0xF0 + */ +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; +} + +/** + * @note Address: 0x800F7CB4 + * @note Size: 0x68 + */ +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++; + } +} + +/** + * @note Address: 0x800F7D1C + * @note Size: 0x1BC + */ +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; +} + +/** + * @note Address: 0x800F7ED8 + * @note Size: 0x54 + */ +static void __THPRestartDefinition(void) +{ + __THPInfo->RST = TRUE; + __THPInfo->file += 2; + __THPInfo->nMCU = (u16)((__THPInfo->file)[0] << 8 | (__THPInfo->file)[1]); + __THPInfo->file += 2; + __THPInfo->currMCU = __THPInfo->nMCU; +} + +static inline void __THPGQRSetup(void) +{ + register u32 tmp1, tmp2; + +#ifdef __MWERKS__ // clang-format off + asm { + mfspr tmp1, GQR5; + mfspr tmp2, GQR6; + } +#endif // clang-format on + + __THPOldGQR5 = tmp1; + __THPOldGQR6 = tmp2; + +#ifdef __MWERKS__ // clang-format off + asm { + li r3, 0x0007 + oris r3, r3, 0x0007 + mtspr GQR5, r3 + li r3, 0x3D04 + oris r3, r3, 0x3D04 + mtspr GQR6, r3 + } +#endif // clang-format on +} + +static inline void __THPGQRRestore(void) +{ + register u32 tmp1, tmp2; + tmp1 = __THPOldGQR5; + tmp2 = __THPOldGQR6; + +#ifdef __MWERKS__ // clang-format off + asm { + mtspr GQR5, tmp1; + mtspr GQR6, tmp2; + } +#endif // clang-format on +} + +/** + * @note Address: 0x800F7F2C + * @note Size: 0x24C + */ +void __THPPrepBitStream(void) +{ + u32* ptr; + u32 offset, i, j, k; + + ptr = (u32*)((u32)__THPInfo->file & 0xFFFFFFFC); + offset = (u32)__THPInfo->file & 3; + + if (__THPInfo->cnt != 33) { + __THPInfo->cnt -= (3 - offset) * 8; + } else { + __THPInfo->cnt = (offset * 8) + 1; + } + + __THPInfo->file = (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]; + } +} + +/** + * @note Address: 0x800F8178 + * @note Size: 0x10C + */ +static 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; +#ifdef __MWERKS__ // clang-format off + 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: + + } +#endif // clang-format on + } + + ws = &__THPIDCTWorkspace[0]; + + { + register THPSample* obase = Gbase; + register u32 wid = Gwid; + + register u32 itmp0, off0, off1; + register THPSample *out0, *out1; + +#ifdef __MWERKS__ // clang-format off + 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 + } +#endif // clang-format on + } +} + +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; + +#ifdef __MWERKS__ // clang-format off + 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: + + } +#endif // clang-format on + } + + ws = &__THPIDCTWorkspace[0]; + + { + register THPSample* obase = Gbase; + register u32 wid = Gwid; + + register u32 itmp0, off0, off1; + register THPSample *out0, *out1; + +#ifdef __MWERKS__ // clang-format off + 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 + } +#endif // clang-format on + } +} + +/** + * @note Address: 0x800F8284 + * @note Size: 0x1A88 + */ +static 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; + +#ifdef __MWERKS__ // clang-format off + asm { + lwz cnt, info->cnt; + addi increment, h, 32; + lwz cb, info->currByte; + addi code, cnt, 4; + cmpwi cnt, 28; + rlwnm tmp, cb, code, 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; + } +#endif // clang-format on + _done: return code; + + { + register u32 maxcodebase; + register u32 tmp2; + + _FailedCheckEnoughBits: + maxcodebase = (u32) & (h->maxCode); + cnt += 5; + +#ifdef __MWERKS__ // clang-format off + 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->file; + li cnt, 1; + lwzu cb, 4(increment); + lwzu tmp2, 4(maxcodebase); + + stw increment, info->file; + 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; + } +#endif // clang-format on + } +_FCEB_Done: + info->cnt = cnt; + return (h->Vij[(s32)(tmp + h->valPtr[code])]); + +#ifdef __MWERKS__ // clang-format off + asm { + _notEnoughBits: + cmpwi cnt, 33; + lwz tmp, info->file; + beq _getfullword; + + cmpwi cnt, 32; + rlwnm code, cb, code, 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; + } +#endif // clang-format on + return tmp; + +#ifdef __MWERKS__ // clang-format off + asm { + _1bitleft: + lwzu cb, 4(tmp); + + stw tmp, info->file; + 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 _Read4; + + } +#endif // clang-format on + return tmp; + +_Read4: { + register u32 maxcodebase = (u32) & (h->maxCode); + register u32 tmp2; + +#ifdef __MWERKS__ // clang-format off + 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; + } +#endif // clang-format on +} + + info->cnt = cnt; +__CODE_PLUS_VP_CNT: + return (h->Vij[(s32)(code + h->valPtr[cnt])]); + +_getfullword: +#ifdef __MWERKS__ // clang-format off + asm { + lwzu cb, 4(tmp); + + rlwinm code, cb, 5, 27, 31 + stw tmp, info->file; + 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; + } +#endif // clang-format on + return (s32)cnt; + +_FailedCheckEnoughbits_Updated: + + cnt = 5; + do { +#ifdef __MWERKS__ // clang-format off + asm { + subfic tmp, cnt, 31; + addi cnt, cnt, 1; + srw code, cb, tmp; + } +#endif // clang-format on + } while (code > h->maxCode[cnt]); + + info->cnt = cnt + 1; + goto __CODE_PLUS_VP_CNT; + +_FailedCheckNoBits0: +_FailedCheckNoBits1: + +{ + register u32 mask = 0xFFFFFFFF << (33 - cnt); + register u32 tmp2; + + code = (s32)(cb & (~mask)); + mask = (u32) & (h->maxCode); + +#ifdef __MWERKS__ // clang-format off + asm { + lwz tmp, info->file; + subfic tmp2, cnt, 33; + addi cnt, tmp2, 1; + slwi tmp2, tmp2, 2; + lwzu cb, 4(tmp); + add mask,mask, tmp2; + stw tmp, info->file; + 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; + } +#endif // clang-format on +} + + info->cnt = (u32)tmp; + return (h->Vij[(s32)(code + h->valPtr[cnt])]); +} + +/** + * @note Address: 0x800F9D0C + * @note Size: 0x1A8C + */ +static 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; +} + +/** + * @note Address: 0x800FB798 + * @note Size: 0x1AAC + */ +static 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)); +} + +/** + * @note Address: 0x800FD244 + * @note Size: 0x67C + */ +static 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 code; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; +#ifdef __MWERKS__ // clang-format off + asm { + lwz cnt,info->cnt; + subfic code,cnt,33; + lwz cb,info->currByte; + + subfc. tmp, code, 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; + } +#endif // clang-format on + +#ifdef __MWERKS__ // clang-format off + asm { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->file; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, code; + stw tmp1, info->file; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } +#endif // clang-format on + } + + 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; + +#ifdef __MWERKS__ // clang-format off + asm { + lwz cnt, info->cnt; + addi increment, h, 32; + lwz cb, info->currByte; + } +#endif // clang-format on + + for (k = 1; k < 64; k++) + { + register s32 ssss; + register s32 rrrr; + +#ifdef __MWERKS__ // clang-format off + asm { + addi code, cnt, 4; + cmpwi cnt, 28; + rlwnm tmp, cb, code, 27, 31; + bgt _notEnoughBits; + + lbzx ssss, h, tmp; + lbzx code, increment, tmp; + cmpwi ssss, 0xFF; + + beq _FailedCheckEnoughBits; + add cnt, cnt, code; + b _DoneDecodeTab; + } +#endif // clang-format on + + { + register u32 maxcodebase; + register u32 tmp2; + + _FailedCheckEnoughBits: + cnt += 5; + maxcodebase = (u32) & (h->maxCode); +#ifdef __MWERKS__ // clang-format off + 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->file; + li cnt, 1; + lwzu cb, 4(ssss); + + lwzu tmp2, 4(maxcodebase); + + stw ssss, info->file; + 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; + } +#endif // clang-format on + } + _FCEB_Done: + ssss = (h->Vij[(s32)(tmp + h->valPtr[code])]); + goto _DoneDecodeTab; + + _notEnoughBits: +#ifdef __MWERKS__ // clang-format off + asm { + cmpwi cnt, 33; + lwz tmp, info->file; + beq _getfullword; + + cmpwi cnt, 32; + rlwnm code, cb, code, 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; + } +#endif // clang-format on + cnt = (u32)code; + goto _DoneDecodeTab; + + _getfullword: { +#ifdef __MWERKS__ // clang-format off + asm { + lwzu cb, 4(tmp); + rlwinm code, cb, 5, 27, 31 + stw tmp, info->file; + lbzx ssss, h, code; + lbzx tmp, increment, code; + cmpwi ssss, 0xFF + addi cnt, tmp, 1 + beq _FailedCheckEnoughbits_Updated; + } +#endif // clang-format on + } + goto _DoneDecodeTab; + + _FailedCheckEnoughbits_Updated: + ssss = 5; + do { +#ifdef __MWERKS__ // clang-format off + asm { + subfic tmp, ssss, 31; + addi ssss, ssss, 1; + srw code, cb, tmp; + } +#endif // clang-format on + } while (code > h->maxCode[ssss]); + + cnt = (u32)(ssss + 1); + ssss = (h->Vij[(s32)(code + h->valPtr[ssss])]); + + goto _DoneDecodeTab; + + _1bitleft: +#ifdef __MWERKS__ // clang-format off + asm { + lwzu cb, 4(tmp); + + stw tmp, info->file; + rlwimi code, cb, 4, 28, 31; + lbzx ssss, h, code; + lbzx cnt, increment, code + cmpwi ssss, 0xFF + beq _Read4; + } +#endif // clang-format on + + goto _DoneDecodeTab; + + _Read4: { + register u32 maxcodebase = (u32) & (h->maxCode); + register u32 tmp2; + +#ifdef __MWERKS__ // clang-format off + 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; + } +#endif // clang-format on + } + 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); + +#ifdef __MWERKS__ // clang-format off + asm { + lwz tmp, info->file; + subfic tmp2, cnt, 33; + addi tmp3, tmp2, 1; + slwi tmp2, tmp2, 2; + lwzu cb, 4(tmp); + add mask,mask, tmp2; + stw tmp, info->file; + 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; + } +#endif // clang-format on + ssss = (h->Vij[(s32)(code + h->valPtr[tmp3])]); + } + + goto _DoneDecodeTab; + + _DoneDecodeTab: +#ifdef __MWERKS__ // clang-format off + asm { + andi. rrrr, ssss, 15; + srawi ssss, ssss, 4; + beq _RECV_SSSS_ZERO; + } +#endif // clang-format on + + { + k += ssss; + { + register s32 v; + register u32 cnt1; + register u32 tmp1; +#ifdef __MWERKS__ // clang-format off + asm { + subfic code,cnt,33; + subfc. tmp, code, rrrr; + subi cnt1,cnt,1; + bgt _RECVnotEnoughBits; + add cnt,cnt,rrrr; + slw tmp1,cb,cnt1; + subfic v,rrrr,32; + srw ssss,tmp1,v; + b _RECVDone; + _RECVnotEnoughBits: + lwz tmp1, info->file; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi cnt, tmp, 1; + stw tmp1, info->file; + srw tmp1, cb, code; + + add v, tmp1, v; + subfic tmp, rrrr, 32; + srw ssss, v, tmp; + _RECVDone: + } +#endif // clang-format on + } + + 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; + }; + +#ifdef __MWERKS__ // clang-format off + asm { _RECV_END: } +#else // clang-format on + _RECV_END: // Exists just to shut up VSCode +#endif + } + info->cnt = cnt; + info->currByte = cb; + } +} + +/** + * @note Address: 0x800FD8C0 + * @note Size: 0x6A8 + */ +static 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) { +#ifdef __MWERKS__ // clang-format off + 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; + } +#endif // clang-format on + +#ifdef __MWERKS__ // clang-format off + asm { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->file; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->file; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } +#endif // clang-format on + + 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; +#ifdef __MWERKS__ // clang-format off + 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; + } +#endif // clang-format on + +#ifdef __MWERKS__ // clang-format off + asm { + b _Done; + _notEnoughBits: + lwz tmp1, info->file; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->file; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, ssss, 32; + srw rrrr, v, tmp; + _Done: + } +#endif // clang-format on + + if (__cntlzw((u32)rrrr) > 32 - ssss) { + rrrr += ((0xFFFFFFFF << ssss) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)rrrr; + } + + else { + if (rrrr != 15) + break; + k += 15; + } + } +} + +/** + * @note Address: 0x800FDF68 + * @note Size: 0x6A8 + */ +static 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) { +#ifdef __MWERKS__ // clang-format off + 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; + } +#endif // clang-format on + +#ifdef __MWERKS__ // clang-format off + asm { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->file; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->file; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } +#endif // clang-format on + + 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; + +#ifdef __MWERKS__ // clang-format off + 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; + } +#endif // clang-format on + +#ifdef __MWERKS__ // clang-format off + asm { + b _Done; + _notEnoughBits: + lwz tmp1, info->file; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->file; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, ssss, 32; + srw rrrr, v, tmp; + _Done: + } +#endif // clang-format on + + if (__cntlzw((u32)rrrr) > 32 - ssss) { + rrrr += ((0xFFFFFFFF << ssss) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)rrrr; + } else { + if (rrrr != 15) + break; + k += 15; + } + } +} + +/** + * @note Address: 0x800FE610 + * @note Size: 0xA0 + */ + +BOOL THPInit(void) +{ + u8* base; + OSRegisterVersion(__THPVersion); + base = (u8*)(0xE000 << 16); + + __THPLCWork512[0] = base; + base += 0x2000; + __THPLCWork512[1] = base; + base += 0x800; + __THPLCWork512[2] = base; + base += 0x200; + + base = (u8*)(0xE000 << 16); + __THPLCWork672[0] = base; + base += 0x2A00; + __THPLCWork672[1] = base; + base += 0xA80; + __THPLCWork672[2] = base; + base += 0xA80; + + OSInitFastCast(); + + __THPInitFlag = TRUE; + return TRUE; +} diff --git a/dolphin sdk not yet linked/src/vi/vi.c b/dolphin sdk not yet linked/src/vi/vi.c new file mode 100644 index 0000000..d29266b --- /dev/null +++ b/dolphin sdk not yet linked/src/vi/vi.c @@ -0,0 +1,1201 @@ +#include "Dolphin/vi.h" +#include "Dolphin/gx.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +// Useful macros. +#define CLAMP(x, l, h) (((x) > (h)) ? (h) : (((x) < (l)) ? (l) : (x))) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define IS_LOWER_16MB(x) ((x) < 16 * 1024 * 1024) +#define ToPhysical(fb) (u32)(((u32)(fb)) & 0x3FFFFFFF) +#define ONES(x) ((1 << (x)) - 1) +#define VI_BITMASK(index) (1ull << (63 - (index))) + +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(); + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +static void getEncoderType(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x5C + */ +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)); +} + +/** + * @note Address: N/A + * @note Size: 0x120 + */ +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; +} + +/** + * @note Address: 0x800D07E8 + * @note Size: 0x274 + */ +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); +} + +/** + * @note Address: 0x800D0A5C + * @note Size: 0x44 + */ +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback) +{ + int interrupt; + VIRetraceCallback oldCallback; + + oldCallback = PreCB; + + interrupt = OSDisableInterrupts(); + PreCB = callback; + OSRestoreInterrupts(interrupt); + + return oldCallback; +} + +/** + * @note Address: 0x800D0AA0 + * @note Size: 0x44 + */ +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback) +{ + int interrupt; + VIRetraceCallback oldCallback; + + oldCallback = PostCB; + + interrupt = OSDisableInterrupts(); + PostCB = callback; + OSRestoreInterrupts(interrupt); + + return oldCallback; +} + +/** + * @note Address: 0x800D0AE4 + * @note Size: 0xA0 + */ +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; +} + +/** + * @note Address: 0x800D0B84 + * @note Size: 0x200 + */ +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; + } +} + +/** + * @note Address: N/A + * @note Size: 0x160 + */ +static void AdjustPosition(u16 acv) +{ + s32 coeff, frac; + + HorVer.adjDispPosX = (u16)CLAMP((s16)HorVer.dispPosX + displayOffsetH, 0, 720 - HorVer.dispSizeX); + + coeff = (HorVer.xfbMode == VI_XFBMODE_SF) ? 2 : 1; + frac = HorVer.dispPosY & 1; + + HorVer.adjDispPosY = (u16)MAX((s16)HorVer.dispPosY + displayOffsetV, frac); + + HorVer.adjDispSizeY = (u16)(HorVer.dispSizeY + MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0) + - MAX((s16)HorVer.dispPosY + (s16)HorVer.dispSizeY + displayOffsetV - ((s16)acv * 2 - frac), 0)); + + HorVer.adjPanPosY = (u16)(HorVer.panPosY - MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0) / coeff); + + HorVer.adjPanSizeY = (u16)(HorVer.panSizeY + MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0) / coeff + - MAX((s16)HorVer.dispPosY + (s16)HorVer.dispSizeY + displayOffsetV - ((s16)acv * 2 - frac), 0) / coeff); +} + +/** + * @note Address: N/A + * @note Size: 0x3C + */ +static void ImportAdjustingValues(void) +{ + displayOffsetH = __OSLockSram()->displayOffsetH; + displayOffsetV = 0; + __OSUnlockSram(FALSE); +} + +/** + * @note Address: 0x800D0D84 + * @note Size: 0x4B0 + */ +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))); +} + +/** + * @note Address: 0x800D1234 + * @note Size: 0x54 + */ +void VIWaitForRetrace(void) +{ + int interrupt; + u32 startCount; + + interrupt = OSDisableInterrupts(); + startCount = retraceCount; + do { + OSSleepThread(&retraceQueue); + } while (startCount == retraceCount); + OSRestoreInterrupts(interrupt); +} + +/** + * @note Address: N/A + * @note Size: 0x7C + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x98 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0xBC + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x9C + */ +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); + } +} + +/** + * @note Address: N/A + * @note Size: 0x80 + */ +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); +} + +/** + * @note Address: 0x800D1288 + * @note Size: 0x2D4 + */ +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); + } +} + +/** + * @note Address: N/A + * @note Size: 0xCC + */ +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); +} + +/** + * @note Address: 0x800D155C + * @note Size: 0x1A0 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x94 + */ +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"); + } +} + +/** + * @note Address: 0x800D16FC + * @note Size: 0x828 + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x394 + */ +void VIConfigurePan(u16 panPosX, u16 panPosY, u16 panSizeX, u16 panSizeY) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D1F24 + * @note Size: 0x130 + */ +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); +} + +/** + * @note Address: 0x800D2054 + * @note Size: 0x6C + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void* VIGetNextFrameBuffer() +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D20C0 + * @note Size: 0x8 + */ +void* VIGetCurrentFrameBuffer(void) { return (void*)CurrBufAddr; } + +/** + * @note Address: N/A + * @note Size: 0x6C + */ +void VISetNextRightFrameBuffer(void* fb) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D20C8 + * @note Size: 0x7C + */ +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); +} + +/** + * @note Address: N/A + * @note Size: 0x100 + */ +void VISet3D(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800D2144 + * @note Size: 0x8 + */ +u32 VIGetRetraceCount(void) { return retraceCount; } + +/** + * @note Address: 0x800D214C + * @note Size: 0x3C + */ +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; +} + +/** + * @note Address: N/A + * @note Size: 0x50 + */ +static u32 getCurrentHalfLine(void) +{ + u32 hcount, vcount; + GetCurrentDisplayPosition(&hcount, &vcount); + + return ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); +} + +/** + * @note Address: 0x800D2188 + * @note Size: 0x68 + */ +static u32 getCurrentFieldEvenOdd() { return (getCurrentHalfLine() < CurrTiming->numHalfLines) ? 1 : 0; } + +/** + * @note Address: 0x800D21F0 + * @note Size: 0x9C + */ +u32 VIGetNextField(void) +{ + u32 nextField; + int interrupt; + + interrupt = OSDisableInterrupts(); + nextField = getCurrentFieldEvenOdd() ^ 1; + OSRestoreInterrupts(interrupt); + return nextField ^ (HorVer.adjDispPosY & 1); +} + +/** + * @note Address: 0x800D228C + * @note Size: 0x98 + */ +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); +} + +/** + * @note Address: 0x800D2324 + * @note Size: 0x68 + */ +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; +} + +/** + * @note Address: 0x800D238C + * @note Size: 0x3C + */ +u32 VIGetDTVStatus(void) +{ + u32 stat; + int interrupt; + + interrupt = OSDisableInterrupts(); + stat = (__VIRegs[VI_DTV_STAT] & 3); + OSRestoreInterrupts(interrupt); + return (stat & 1); +} + +/** + * @note Address: 0x800D23C8 + * @note Size: 0x21C + */ +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); +} + +/** + * @note Address: 0x800D25E4 + * @note Size: 0x60 + */ +void __VIGetCurrentPosition(s16* x, s16* y) +{ + u32 h, v; + GetCurrentDisplayPosition(&h, &v); + __VIDisplayPositionToXY(h, v, x, y); +} diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception b/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception deleted file mode 100644 index f887c4f..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _EXCEPTION -#define _EXCEPTION - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception.h b/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception.h deleted file mode 100644 index f0e0bae..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _EXCEPTION_H -#define _EXCEPTION_H - -namespace std -{ - class exception - { - public: - exception() throw(); - exception(const exception&) throw(); - exception& operator=(const exception&) throw(); - virtual ~exception() throw(); - virtual const char* what() const throw(); - }; - - class bad_exception : public exception - { - public: - bad_exception() throw(); - bad_exception(const bad_exception&) throw(); - bad_exception& operator=(const bad_exception&) throw(); - virtual ~bad_exception() throw(); - virtual const char* what() const throw(); - }; -} // namespace std - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new b/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new deleted file mode 100644 index 679aa45..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _NEW -#define _NEW - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h b/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h deleted file mode 100644 index 4b9d555..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _NEW_H -#define _NEW_H - -#include -#include "exception.h" - -namespace std -{ - class bad_alloc : public exception - { - public: - bad_alloc() throw(); - bad_alloc(const bad_alloc&) throw(); - bad_alloc& operator=(const bad_alloc&) throw(); - virtual ~bad_alloc() throw(); - virtual const char* what() const throw(); - }; - - struct nothrow_t - { - }; -} // namespace std - -void* operator new(size_t size) throw(std::bad_alloc); -void* operator new(size_t size, const std::nothrow_t&) throw(); -void* operator new(size_t, void* ptr) throw(); - -void operator delete(void* ptr) throw(); -void operator delete(void* ptr, const std::nothrow_t&) throw(); -void operator delete(void*, void*) throw(); - -void* operator new[](size_t size) throw(std::bad_alloc); -void* operator new[](size_t size, const std::nothrow_t&) throw(); -void* operator new[](size_t, void* ptr) throw(); - -void operator delete[](void* ptr) throw(); -void operator delete[](void* ptr, const std::nothrow_t&) throw(); -void operator delete[](void*, void*) throw(); - -#endif 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 4e84d98..0000000 --- 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 2a3cdf3..0000000 --- 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/cmath b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath deleted file mode 100644 index c11c2f7..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _MSL_CMATH -#define _MSL_CMATH - -namespace std -{ - // TODO: fix inline function ordering - -#ifndef INLINE - float atan2f(float y, float x); - float sinf(float x); - float cosf(float x); - float tanf(float x); - float ceilf(float x); - float asinf(float x); - float acosf(float x); - float expf(float x); - float floorf(float x); -#else - inline float atan2f(float y, float x) - { - return (float)atan2((double)y, (double)x); - } - - inline float sinf(float x) - { - return (float)sin((double)x); - } - - inline float cosf(float x) - { - return (float)cos((double)x); - } - - inline float tanf(float x) - { - return (float)tan((double)x); - } - - inline float ceilf(float x) - { - return (float)ceil((double)x); - } - - inline float asinf(float x) - { - return (float)asin((double)x); - } - - inline float acosf(float x) - { - return (float)acos((double)x); - } - - inline float expf(float x) - { - return (float)exp((double)x); - } - - inline float floorf(float x) - { - return (float)floor((double)x); - } -#endif -} // namespace std - -#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 51ecd3f..0000000 --- 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 64f3ce0..0000000 --- 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/cstdlib b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib deleted file mode 100644 index 7850167..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CSTDLIB_H -#define _MSL_CSTDLIB_H - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring deleted file mode 100644 index fa22574..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _MSL_CSTRING_H -#define _MSL_CSTRING_H - -#include - -namespace std -{ - inline static char* strstr(char* haystack, const char* needle) - { - return ::strstr(haystack, needle); - } -} // namespace std - -#endif 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 f7b51a4..0000000 --- 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 221e222..0000000 --- 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 530c1ee..0000000 --- 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 dfd2999..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h +++ /dev/null @@ -1,39 +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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h deleted file mode 100644 index 5ee1402..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _MSL_SIZE_T_H -#define _MSL_SIZE_T_H - -#ifdef _MSC_VER -typedef size_t; // hack to make VS Code not complain about size_t in operator new -#elif !defined(__MWERKS__) || __MWERKS__ < 0x2400 -typedef unsigned long size_t; -#else -typedef __typeof__(sizeof(0)) size_t; -#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 52d613f..0000000 --- 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/stdio.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h deleted file mode 100644 index 5541080..0000000 --- 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 -{ - unsigned char 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/stdlib.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h deleted file mode 100644 index 65ab762..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _MSL_STDLIB -#define _MSL_STDLIB - -#include "size_t.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int rand(void); -int atoi(const char* nptr); -double atof(const char* nptr); -void exit(int __status); -void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); -long abs(long n); - -#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 73c45e2..0000000 --- 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/time.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/time.h deleted file mode 100644 index e49250c..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/time.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_TIME_H -#define _MSL_TIME_H - -typedef long time_t; - -#endif \ No newline at end of file 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 46a9131..0000000 --- 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 diff --git a/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/algorithm.h b/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/algorithm.h new file mode 100644 index 0000000..5de7a4f --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/algorithm.h @@ -0,0 +1,103 @@ +#ifndef MSL_ALGORITHM_H_ +#define MSL_ALGORITHM_H_ + +#include "mem.h" + +namespace std { +template +ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& val) +{ + int count = last - first; // probably needs to be std::distance or w/e but im not gonna be the one to implement it + ForwardIterator it; + u32 step; + + while (count > 0) { + it = first; + step = count / 2; + it += step; + if (*it < val) { + first = ++it; + count -= step + 1; + } else { + count = step; + } + } +} + +template +ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& val); + +template +InputIt find_if(InputIt first, InputIt last, UnaryPredicate p); + +/* +template +struct __fill_n { + OutputIt fill_n(OutputIt first, Size count, const unsigned long& value); +}; + +template<> +unsigned long* __fill_n::fill_n(unsigned long* first, long count, const unsigned long& value) { + for (; count > 0; count--) { + *first++ = value; + } + return first; +} + +template +OutputIt fill_n(OutputIt first, Size count, const T& value) { + return __fill_n::fill_n(first, count, value); +} + + +template +void __fill(ForwardIt first, ForwardIt last, const T& value, std::random_access_iterator_tag param_3) { + fill_n(first, last - first, value); +} +*/ + +template +void fill(ForwardIt first, ForwardIt last, const T& value) +{ + for (; first != last; ++first) { + *first = value; + } +} + +template +inline OutputIt copy(InputIt first, InputIt last, OutputIt d_first) +{ + for (; first < last;) { + *d_first++ = *first++; + } + return d_first; +} + +template +class __copy_backward { +public: + static T* copy_backward(T* begin, T* end, T* dest) + { +#ifdef DEBUG + size_t size = (end - begin); + dest -= size; + memmove(dest, begin, size * sizeof(begin)); + return dest; +#else + for (; end > begin;) { + *--dest = *--end; + } + return end; +#endif + } +}; + +template +inline T* copy_backward(T* first, T* last, T* d_last) +{ + return __copy_backward::copy_backward(first, last, d_last); +} + +} // namespace std + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/msl_memory.h b/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/msl_memory.h new file mode 100644 index 0000000..f128809 --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/msl_memory.h @@ -0,0 +1,34 @@ +#ifndef MSL_MEMORY_H_ +#define MSL_MEMORY_H_ + +namespace std { + +template +inline ForwardIt uninitialized_fill_n(ForwardIt first, Size count, const T& value) +{ + for (; count > 0; ++first, (void)--count) { + *first = value; + } + return first; +} + +template +class __uninitialized_copy_helper { + static T* uninitialized_copy(T* begin, T* end, T* dest) + { + for (; begin < end; ++begin, ++dest) { + *dest = *begin; + } + return dest; + } +}; + +template +inline T* uninitialized_copy(T* first, T* last, T* d_first) +{ + return __uninitialized_copy_helper::uninitialized_copy(first, last, d_first); +} + +} // namespace std + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h new file mode 100644 index 0000000..3d395cc --- /dev/null +++ b/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, u32 offset, int whence); +int _fseek(FILE* stream, u32 offset, int whence); +int ftell(FILE* stream); +int _ftell(FILE* stream); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h new file mode 100644 index 0000000..a189b18 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h new file mode 100644 index 0000000..a36a3ed --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h @@ -0,0 +1,88 @@ +#ifndef _MSL_COMMON_ANSI_FILES_H +#define _MSL_COMMON_ANSI_FILES_H + +#include "types.h" + +typedef u32 __file_handle; +typedef u32 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 + +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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h new file mode 100644 index 0000000..b7061cf --- /dev/null +++ b/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; + s16 digits; +} decform; + +void __ull2dec(decimal*, u64); +void __timesdec(decimal*, const decimal*, const decimal*); +void __str2dec(decimal*, const char*, s16); +void __two_exp(decimal*, s32); +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*, f64); +void __num2dec(const decform*, f64, decimal*); +f64 __dec2num(const decimal*); + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h new file mode 100644 index 0000000..ede47a1 --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h @@ -0,0 +1,25 @@ +#ifndef _MSL_COMMON_ARITH_H +#define _MSL_COMMON_ARITH_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +typedef struct { + int quot; /* quotient */ + int rem; /* remainder */ +} div_t; + +int abs(int __x); +s32 labs(s32 __x); +div_t div(s32 __numer, s32 __denom); + +inline int _abs(int __x) { return __x > 0 ? __x : -__x; } + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h new file mode 100644 index 0000000..cc80ccb --- /dev/null +++ b/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_C/MSL_Common/ctype_api.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h new file mode 100644 index 0000000..da8788d --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h @@ -0,0 +1,34 @@ +#ifndef _MSL_CTYPE_API_H +#define _MSL_CTYPE_API_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +extern u8 __ctype_map[256]; +extern u8 __lower_map[256]; +extern u8 __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 diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h new file mode 100644 index 0000000..4679ca0 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h new file mode 100644 index 0000000..d649b49 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h new file mode 100644 index 0000000..a4ec16d --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h new file mode 100644 index 0000000..ddd6e9b --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h @@ -0,0 +1,65 @@ +#ifndef _MSL_MATH_API_H +#define _MSL_MATH_API_H + +#include "types.h" +#include "stl/fdlibm.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +// int __fpclassifyf(f32); +// int __signbitd(f64); +// int __fpclassifyd(f64); + +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; +} +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; +} + +#define fpclassify(x) ((sizeof(x) == sizeof(f32)) ? __fpclassifyf((f32)(x)) : __fpclassifyd((f64)(x))) + +#define isinf(x) ((fpclassify(x) == 2)) +#define isfinite(x) ((fpclassify(x) > 2)) + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h new file mode 100644 index 0000000..0c1fb5a --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h new file mode 100644 index 0000000..df85787 --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h @@ -0,0 +1,16 @@ +#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); + +#define srcCharPtr ((u8*)pSrc) +#define destCharPtr ((u8*)pDest) +#define srcLongPtr ((u32*)pSrc) +#define destLongPtr ((u32*)pDest) + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h new file mode 100644 index 0000000..7ef4118 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h new file mode 100644 index 0000000..ce88b02 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h new file mode 100644 index 0000000..7ca4d59 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h new file mode 100644 index 0000000..e9a5e7b --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h new file mode 100644 index 0000000..e471455 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h new file mode 100644 index 0000000..308903b --- /dev/null +++ b/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_C/MSL_Common/strtold.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h new file mode 100644 index 0000000..0e8314b --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h @@ -0,0 +1,17 @@ +#ifndef _MSL_STRTOLD_H +#define _MSL_STRTOLD_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +f128 __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* overflow); +s32 strtol(const char* str, char** end, int base); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h new file mode 100644 index 0000000..af0ae5d --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h @@ -0,0 +1,21 @@ +#ifndef _MSL_STRTOUL_H +#define _MSL_STRTOUL_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +u32 __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* negative, + int* overflow); +u64 __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); +u32 strtoul(const char* str, char** end, int base); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h b/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h new file mode 100644 index 0000000..984294c --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h b/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h new file mode 100644 index 0000000..3604b5a --- /dev/null +++ b/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h @@ -0,0 +1,11 @@ +#ifndef _MATH_PPC_H +#define _MATH_PPC_H + +#include "types.h" + +f64 nan(const char*); +f32 cosf(f32 __x); +f32 sinf(f32 __x); +f32 tanf(f32 __x); + +#endif diff --git a/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h b/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h new file mode 100644 index 0000000..1657f98 --- /dev/null +++ b/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* mReadPtr; // _00 + u8* mWritePtr; // _04 + u8* mStartPtr; // _08 + u32 mSize; // _0C + u32 mBytesToRead; // _10 + u32 mBytesToWrite; // _14 + uint mSection; // _18 + u32 _1C; // _1C +} 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/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h b/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h new file mode 100644 index 0000000..218cbe2 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MetroTRK/dstypes.h b/include/PowerPC_EABI_Support/MetroTRK/dstypes.h new file mode 100644 index 0000000..9da0770 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MetroTRK/memmap.h b/include/PowerPC_EABI_Support/MetroTRK/memmap.h new file mode 100644 index 0000000..2052466 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MetroTRK/ppc_reg.h b/include/PowerPC_EABI_Support/MetroTRK/ppc_reg.h new file mode 100644 index 0000000..11411a7 --- /dev/null +++ b/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/include/PowerPC_EABI_Support/MetroTRK/trk.h b/include/PowerPC_EABI_Support/MetroTRK/trk.h new file mode 100644 index 0000000..bf13e4e --- /dev/null +++ b/include/PowerPC_EABI_Support/MetroTRK/trk.h @@ -0,0 +1,201 @@ +#ifndef _DOLPHIN_TRK_H +#define _DOLPHIN_TRK_H + +#include "types.h" +#include "PowerPC_EABI_Support/MetroTRK/trktypes.h" +#include "PowerPC_EABI_Support/MetroTRK/ppc_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +////// MSG HANDLING FUNCTIONS ////// +DSError TRKDoConnect(MessageBuffer*); +DSError TRKDoDisconnect(MessageBuffer*); +DSError TRKDoReset(MessageBuffer*); +DSError TRKDoVersions(MessageBuffer*); +DSError TRKDoSupportMask(MessageBuffer*); +DSError TRKDoOverride(MessageBuffer*); +DSError TRKDoReadMemory(MessageBuffer*); +DSError TRKDoWriteMemory(MessageBuffer*); +DSError TRKDoReadRegisters(MessageBuffer*); +DSError TRKDoWriteRegisters(MessageBuffer*); +DSError TRKDoSetOption(MessageBuffer*); +DSError TRKDoContinue(MessageBuffer*); +DSError TRKDoStep(MessageBuffer*); +DSError TRKDoStop(MessageBuffer*); + +void SetBufferPosition(MessageBuffer*, u32); +void SetTRKConnected(int); +int GetTRKConnected(void); + +DSError TRKGetFreeBuffer(int*, MessageBuffer**); +void OutputData(void* data, int length); +void TRKResetBuffer(MessageBuffer* msg, BOOL keepData); + +DSError TRKReadBuffer1_ui64(MessageBuffer* buffer, u64* data); +DSError TRKAppendBuffer1_ui64(MessageBuffer* buffer, const u64 data); +//////////////////////////////////// + +/////// DOLPHIN TRK FUNCTIONS ////// +void InitMetroTRK(void); +void InitMetroTRK_BBA(void); +void EnableMetroTRKInterrupts(void); + +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(MessageBuffer*); +void* TRKGetBuffer(int); +void TRKReleaseBuffer(int); +void TRKGetInput(); +//////////////////////////////////// + +///////// TARGET FUNCTIONS ///////// +DSError TRKTargetContinue(void); +DSError TRKTargetInterrupt(TRKEvent*); +BOOL TRKTargetStopped(); +void TRKTargetSetStopped(uint); +DSError TRKTargetSupportRequest(); +//////////////////////////////////// + +////// NUB AND MEM FUNCTIONS /////// +DSError TRKAppendBuffer_ui8(MessageBuffer*, const u8*, int); +DSError TRKSetBufferPosition(MessageBuffer*, u32); + +DSError TRKMessageSend(MessageBuffer*); +void TRKSwapAndGo(void); +DSError TRKInitializeNub(void); +DSError TRKTerminateNub(void); +void TRKNubWelcome(void); +void TRKNubMainLoop(void); + +DSError TRKInitializeMutex(void*); +DSError TRKAcquireMutex(void*); +DSError TRKReleaseMutex(void*); +void* TRK_memcpy(void* dst, const void* src, size_t n); +//////////////////////////////////// + +/////// 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 FUNCTIONS /////////// +void MWTRACE(u8, char*, ...); +//////////////////////////////////// + +//////// SUPPORT FUNCTIONS ///////// +DSError TRKRequestSend(); +u32 TRKAccessFile(u32, u32, u32*, u8*); +//////////////////////////////////// + +////////// OTHER FUNCTIONS ///////// +DSError TRK_main(void); +UARTError InitializeUART(UARTBaudRate baudRate); +DSError TRKInitializeIntDrivenUART(u32, u32, u32, void*); +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); + +DSError TRKTargetAddStopInfo(MessageBuffer*); +void TRKTargetAddExceptionInfo(MessageBuffer*); +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 MessageBuffer gTRKMsgBufs[3]; +//////////////////////////////////// + +////////// USEFUL STATICS ////////// +static inline DSError TRKAppendBuffer1_ui8(MessageBuffer* buffer, const u8 data) +{ + if (buffer->position >= 0x880) { + return DS_MessageBufferOverflow; + } + + buffer->data[buffer->position++] = data; + buffer->length++; + return DS_NoError; +} +//////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/PowerPC_EABI_Support/MetroTRK/trkenum.h b/include/PowerPC_EABI_Support/MetroTRK/trkenum.h new file mode 100644 index 0000000..f337fd9 --- /dev/null +++ b/include/PowerPC_EABI_Support/MetroTRK/trkenum.h @@ -0,0 +1,201 @@ +#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; + +// 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/include/PowerPC_EABI_Support/MetroTRK/trktypes.h b/include/PowerPC_EABI_Support/MetroTRK/trktypes.h new file mode 100644 index 0000000..cd98333 --- /dev/null +++ b/include/PowerPC_EABI_Support/MetroTRK/trktypes.h @@ -0,0 +1,147 @@ +#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 int (*DBCommInitFunc)(void*, __OSInterruptHandler); +typedef int (*DBCommReadFunc)(u8*, int); +typedef int (*DBCommWriteFunc)(const u8*, int); + +// Message buffer ID type. +typedef int MessageBufferID; + +// 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 MessageBuffer { + u32 _00; // _00, unknown + BOOL isInUse; // _04 + u32 length; // _08 + u32 position; // _0C + u8 data[TRKMSGBUF_SIZE]; // _10 +} MessageBuffer; + +// Struct for storing DB communication functions (size 0x28). +typedef struct DBCommTable { + DBCommInitFunc initialize_func; // _00 + DBCommFunc init_interrupts_func; // _04 + DBCommFunc shutdown_func; // _08 + DBCommFunc peek_func; // _0C + DBCommReadFunc read_func; // _10 + DBCommWriteFunc write_func; // _14 + DBCommFunc open_func; // _18 + DBCommFunc close_func; // _1C + DBCommFunc pre_continue_func; // _20 + DBCommFunc post_stop_func; // _24 +} 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 { + MessageBufferID msgBufID; // _00 + MessageBuffer* buffer; // _04 + ReceiverState 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 { + NubEventType eventType; // _00 + NubEventID eventID; // _04 + MessageBufferID 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/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h b/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h new file mode 100644 index 0000000..91f5333 --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h @@ -0,0 +1,229 @@ +#ifndef _RUNTIME_GECKO_EXCEPTIONPPC_H +#define _RUNTIME_GECKO_EXCEPTIONPPC_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/include/PowerPC_EABI_Support/Runtime/MWCPlusLib.h b/include/PowerPC_EABI_Support/Runtime/MWCPlusLib.h new file mode 100644 index 0000000..2339140 --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/MWCPlusLib.h @@ -0,0 +1,34 @@ +#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; + +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 diff --git a/include/PowerPC_EABI_Support/Runtime/NMWException.h b/include/PowerPC_EABI_Support/Runtime/NMWException.h new file mode 100644 index 0000000..aba83f4 --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/NMWException.h @@ -0,0 +1,45 @@ +#ifndef _NMWEXCEPTION +#define _NMWEXCEPTION + +#include "types.h" +#include "PowerPC_EABI_Support/Runtime/exception.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" + +#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; + +typedef struct DestructorChain { + struct DestructorChain* next; + void* destructor; + void* object; +} DestructorChain; + +extern void* __register_global_object(void* object, void* destructor, void* registration); +extern void __destroy_global_chain(void); + +extern void __end__catch(CatchInfo* catchinfo); +extern void __throw(char* throwtype, void* location, void* dtor); +extern char __throw_catch_compare(const char* throwtype, const char* catchtype, s32* offset_result); +extern void __unexpected(CatchInfo* catchinfo); + +extern int __register_fragment(struct __eti_init_info* info, char* TOC); +extern void __unregister_fragment(int fragmentID); + +#ifdef __cplusplus +} +#endif + +#endif // _NMWEXCEPTION diff --git a/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h b/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h new file mode 100644 index 0000000..006a83f --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h @@ -0,0 +1,17 @@ +#ifndef _RUNTIME_INIT_CPP_EXCEPTIONS_H +#define _RUNTIME_INIT_CPP_EXCEPTIONS_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void __init_cpp_exceptions(void); +void __fini_cpp_exceptions(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/PowerPC_EABI_Support/Runtime/__mem.h b/include/PowerPC_EABI_Support/Runtime/__mem.h new file mode 100644 index 0000000..62b19df --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/__mem.h @@ -0,0 +1,15 @@ +#ifndef _RUNTIME_MEM_H +#define _RUNTIME_MEM_H +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +DECL_SECT(".init") void* memcpy(void* dest, const void* src, size_t n); +DECL_SECT(".init") void __fill_mem(void* dest, int val, size_t count); +DECL_SECT(".init") void* memset(void* dest, int val, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h b/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h new file mode 100644 index 0000000..16c0b18 --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h @@ -0,0 +1,72 @@ +#ifndef __PPC_EABI_LINKER +#define __PPC_EABI_LINKER + +DECL_SECT(".init") extern char _stack_addr[]; +DECL_SECT(".init") extern char _stack_end[]; +DECL_SECT(".init") extern char _heap_addr[]; +DECL_SECT(".init") extern char _heap_end[]; +DECL_SECT(".init") extern const char _fextabindex_rom[]; +DECL_SECT(".init") extern char _fextabindex[]; +DECL_SECT(".init") extern char _eextabindex[]; + +DECL_SECT(".init") extern char _SDA_BASE_[]; + +DECL_SECT(".init") extern char _SDA2_BASE_[]; + +typedef struct __rom_copy_info { + char* rom; + char* addr; + uint size; +} __rom_copy_info; + +DECL_SECT(".init") extern __rom_copy_info _rom_copy_info[]; + +typedef struct __bss_init_info { + char* addr; + uint size; +} __bss_init_info; + +DECL_SECT(".init") extern __bss_init_info _bss_init_info[]; + +typedef struct __eti_init_info { + void* eti_start; + void* eti_end; + void* code_start; + u32 code_size; +} __eti_init_info; + +DECL_SECT(".init") extern __eti_init_info _eti_init_info[]; +DECL_SECT(".init") extern const char _f_init_rom[]; +DECL_SECT(".init") extern char _f_init[]; +DECL_SECT(".init") extern char _e_init[]; +DECL_SECT(".init") extern const char _f_text_rom[]; +DECL_SECT(".init") extern char _f_text[]; +DECL_SECT(".init") extern char _e_text[]; +DECL_SECT(".init") extern const char _f_rodata_rom[]; +DECL_SECT(".init") extern char _f_rodata[]; +DECL_SECT(".init") extern char _e_rodata[]; +DECL_SECT(".init") extern const char _fextab_rom[]; +DECL_SECT(".init") extern char _fextab[]; +DECL_SECT(".init") extern char _eextab[]; +DECL_SECT(".init") extern const char _f_data_rom[]; +DECL_SECT(".init") extern char _f_data[]; +DECL_SECT(".init") extern char _e_data[]; +DECL_SECT(".init") extern char _f_bss[]; +DECL_SECT(".init") extern char _e_bss[]; +DECL_SECT(".init") extern const char _f_sdata_rom[]; +DECL_SECT(".init") extern char _f_sdata[]; +DECL_SECT(".init") extern char _e_sdata[]; +DECL_SECT(".init") extern char _f_sbss[]; +DECL_SECT(".init") extern char _e_sbss[]; +DECL_SECT(".init") extern const char _f_sdata2_rom[]; +DECL_SECT(".init") extern char _f_sdata2[]; +DECL_SECT(".init") extern char _e_sdata2[]; +DECL_SECT(".init") extern char _f_sbss2[]; +DECL_SECT(".init") extern char _e_sbss2[]; +DECL_SECT(".init") extern const char _f_PPC_EMB_sdata0_rom[]; +DECL_SECT(".init") extern char _f_PPC_EMB_sdata0[]; +DECL_SECT(".init") extern char _e_PPC_EMB_sdata0[]; +DECL_SECT(".init") extern char _f_PPC_EMB_sbss0[]; +DECL_SECT(".init") extern char _e_PPC_EMB_sbss0[]; + +#endif // __PPC_EABI_LINKER diff --git a/include/PowerPC_EABI_Support/Runtime/__va_arg.h b/include/PowerPC_EABI_Support/Runtime/__va_arg.h new file mode 100644 index 0000000..59e9f92 --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/__va_arg.h @@ -0,0 +1,12 @@ +#ifndef _RUNTIME_VA_ARG_H +#define _RUNTIME_VA_ARG_H +#include "Dolphin/types.h" +struct va_list +{ + char mG_register; + char mFloat_register; + char mPadding[2]; + char* mInput_arg_area; + char* mReg_save_area; +}; +#endif diff --git a/include/PowerPC_EABI_Support/Runtime/exception.h b/include/PowerPC_EABI_Support/Runtime/exception.h new file mode 100644 index 0000000..2530b3d --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/exception.h @@ -0,0 +1,38 @@ +#ifndef _EXCEPTION +#define _EXCEPTION + +namespace std { +class exception { +public: + exception() { } + virtual ~exception() { } + virtual const char* what() const { return "exception"; } +}; + +class bad_exception : public exception { +public: + bad_exception() { } + virtual ~bad_exception() { } + virtual const char* what() const { return "bad_exception"; } +}; + +typedef void (*unexpected_handler)(); +unexpected_handler set_unexpected(unexpected_handler handler); +void unexpected(); + +typedef void (*terminate_handler)(); +terminate_handler set_terminate(terminate_handler handler); +void terminate(); + +} // namespace std + +using std::bad_exception; +using std::exception; +using std::set_terminate; +using std::set_unexpected; +using std::terminate; +using std::terminate_handler; +using std::unexpected; +using std::unexpected_handler; + +#endif diff --git a/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h b/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h new file mode 100644 index 0000000..5458dda --- /dev/null +++ b/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h @@ -0,0 +1,36 @@ +#ifndef _GLOBALDESTRUCTORCHAIN +#define _GLOBALDESTRUCTORCHAIN + +#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)) + +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/include/PowerPC_EABI_Support/Runtime/runtime.h b/include/PowerPC_EABI_Support/Runtime/runtime.h new file mode 100644 index 0000000..e648776 --- /dev/null +++ b/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 + +u32 __cvt_fp2unsigned(f64); +// TODO: The rest + +void* __copy(char*, char*, size_t); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/bink/bink.h b/include/bink/bink.h index 8de9e6d..c7bc596 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 @@ -52,8 +52,8 @@ extern int Lock_RAD_3D_image(HRAD3DIMAGE rad_image, void* out_pixel_buffer, unsigned int* out_buffer_pitch, unsigned int* arg3); extern void Unlock_RAD_3D_image(HRAD3DIMAGE rad_image); extern void Blit_RAD_3D_image(HRAD3DIMAGE Image, float, float, float, float, float); -extern void RADSetAudioMemory(void* (*malloc)(size_t), void (*free)(void*)); -extern void RADSetMemory(void* (*malloc)(size_t), void (*free)(void*)); +//extern void RADSetAudioMemory(void* (*malloc)(size_t), void (*free)(void*)); +//extern void RADSetMemory(void* (*malloc)(size_t), void (*free)(void*)); extern HBINK BinkOpen(const char* fname, void*); extern void BinkGetError(); extern void BinkSetVolume(HBINK bink, unsigned int, int volume); diff --git a/include/cmath.h b/include/cmath.h new file mode 100644 index 0000000..3271816 --- /dev/null +++ b/include/cmath.h @@ -0,0 +1,12 @@ +#ifndef _DOLPHIN_CMATH_H_ +#define _DOLPHIN_CMATH_H_ + +float powf(float x, float y); +float tanf(float); + +extern float sinf(float); +extern float cosf(float); +extern float acosf(float); +extern float atan2f(float, float); + +#endif // _DOLPHIN_CMATH_H_ diff --git a/include/dolphin.h b/include/dolphin.h index ac1ebcf..655b8ca 100644 --- a/include/dolphin.h +++ b/include/dolphin.h @@ -1,24 +1,24 @@ #ifndef _DOLPHIN_H_ #define _DOLPHIN_H_ -#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 +#include +#include +#include +#include +#include +#include +#include +#include #endif diff --git a/include/dolphin/AmcExi2Stubs.h b/include/dolphin/AmcExi2Stubs.h new file mode 100644 index 0000000..7e3420a --- /dev/null +++ b/include/dolphin/AmcExi2Stubs.h @@ -0,0 +1,33 @@ +#ifndef _DOLPHIN_AMCEXI2STUBS_H +#define _DOLPHIN_AMCEXI2STUBS_H + +#include "types.h" +#include "Dolphin/os.h" +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +// EXI callback function pointer type +typedef __OSInterruptHandler AmcEXICallback; + +// EXI error codes +typedef enum { + AMC_EXI_NO_ERROR = 0, + AMC_EXI_UNSELECTED + +} AmcExiError; + +void EXI2_Init(vu8**, AmcEXICallback); +void EXI2_EnableInterrupts(void); +int EXI2_Poll(void); +AmcExiError EXI2_ReadN(void*, u32); +AmcExiError EXI2_WriteN(const void*, u32); +void EXI2_Reserve(void); +void EXI2_Unreserve(void); +BOOL AMC_IsStub(void); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/dolphin/card.h b/include/dolphin/card.h index f335a2a..81860c7 100644 --- a/include/dolphin/card.h +++ b/include/dolphin/card.h @@ -15,8 +15,7 @@ extern "C" { typedef void (*CARDCallback)(s32 chan, s32 result); -typedef struct CARDFileInfo -{ +typedef struct CARDFileInfo { s32 chan; s32 fileNo; s32 offset; @@ -24,14 +23,13 @@ typedef struct CARDFileInfo u16 iBlock; } CARDFileInfo; -typedef struct CARDDir -{ +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 time; // seconds since 01/01/2000 midnight u32 iconAddr; // 0xffffffff if not used u16 iconFormat; u16 iconSpeed; @@ -43,8 +41,7 @@ typedef struct CARDDir u32 commentAddr; // 0xffffffff if not used } CARDDir; -typedef struct CARDControl -{ +typedef struct CARDControl { /* 0x000 */ BOOL attached; /* 0x004 */ s32 result; /* 0x008 */ u16 size; @@ -59,7 +56,7 @@ typedef struct CARDControl /* 0x028 */ u32 scramble; /* 0x02C */ DSPTaskInfo task; /* 0x080 */ void* workArea; - /* 0x084 */ CARDDir* currentDir; + /* 0x084 */ CARDDir *currentDir; /* 0x088 */ u16* currentFat; /* 0x08C */ OSThreadQueue threadQueue; /* 0x094 */ u8 cmd[9]; @@ -85,16 +82,14 @@ typedef struct CARDControl /* 0x10C */ const DVDDiskID* diskID; } CARDControl; -typedef struct CARDDecParam -{ +typedef struct CARDDecParam { /* 0x00 */ u8* inputAddr; /* 0x04 */ u32 inputLength; /* 0x08 */ u32 aramAddr; /* 0x0C */ u8* outputAddr; } CARDDecParam; -typedef struct CARDID -{ +typedef struct CARDID { /* 0x000 */ u8 serial[32]; /* 0x020 */ u16 deviceID; /* 0x022 */ u16 size; @@ -104,8 +99,7 @@ typedef struct CARDID /* 0x1FE */ u16 checkSumInv; } CARDID; -typedef struct CARDDirCheck -{ +typedef struct CARDDirCheck { /* 0x00 */ u8 padding0[56]; /* 0x38 */ u16 padding1; /* 0x3A */ s16 checkCode; @@ -113,8 +107,7 @@ typedef struct CARDDirCheck /* 0x3E */ u16 checkSumInv; } CARDDirCheck; -typedef struct CARDStat -{ +typedef struct CARDStat { /* 0x00 */ char fileName[CARD_FILENAME_MAX]; /* 0x20 */ u32 length; /* 0x24 */ u32 time; @@ -132,10 +125,10 @@ typedef struct CARDStat /* 0x68 */ u32 offsetData; } CARDStat; -#define CARD_ATTR_PUBLIC 0x04u +#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_GLOBAL 0x20u #define CARD_ATTR_COMPANY 0x40u #define CARD_FAT_AVAIL 0x0000u @@ -162,26 +155,25 @@ typedef struct CARDStat #define CARD_STAT_SPEED_SLOW 3 #define CARD_STAT_SPEED_MASK 3 -#define CARD_RESULT_UNLOCKED 1 -#define CARD_RESULT_READY 0 -#define CARD_RESULT_BUSY -1 -#define CARD_RESULT_WRONGDEVICE -2 -#define CARD_RESULT_NOCARD -3 -#define CARD_RESULT_NOFILE -4 -#define CARD_RESULT_IOERROR -5 -#define CARD_RESULT_BROKEN -6 -#define CARD_RESULT_EXIST -7 -#define CARD_RESULT_NOENT -8 -#define CARD_RESULT_INSSPACE -9 -#define CARD_RESULT_NOPERM -10 -#define CARD_RESULT_LIMIT -11 -#define CARD_RESULT_NAMETOOLONG -12 -#define CARD_RESULT_ENCODING -13 -#define CARD_RESULT_CANCELED -14 +#define CARD_RESULT_UNLOCKED 1 +#define CARD_RESULT_READY 0 +#define CARD_RESULT_BUSY -1 +#define CARD_RESULT_WRONGDEVICE -2 +#define CARD_RESULT_NOCARD -3 +#define CARD_RESULT_NOFILE -4 +#define CARD_RESULT_IOERROR -5 +#define CARD_RESULT_BROKEN -6 +#define CARD_RESULT_EXIST -7 +#define CARD_RESULT_NOENT -8 +#define CARD_RESULT_INSSPACE -9 +#define CARD_RESULT_NOPERM -10 +#define CARD_RESULT_LIMIT -11 +#define CARD_RESULT_NAMETOOLONG -12 +#define CARD_RESULT_ENCODING -13 +#define CARD_RESULT_CANCELED -14 #define CARD_RESULT_FATAL_ERROR -128 -#define CARDIsValidBlockNo(card, blockNo) \ - ((blockNo) >= CARD_NUM_SYSTEM_BLOCK && (blockNo) < (card)->cBlock) +#define CARDIsValidBlockNo(card, blockNo) ((blockNo) >= CARD_NUM_SYSTEM_BLOCK && (blockNo) < (card)->cBlock) #define CARD_READ_SIZE 512 #define CARD_COMMENT_SIZE 64 @@ -205,10 +197,6 @@ typedef struct CARDStat #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) @@ -219,11 +207,11 @@ typedef struct CARDStat #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))))) + ((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))))) + ((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) @@ -240,7 +228,7 @@ 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 CARDRenameAsync(s32 chan, const char* old, const char* new, CARDCallback callback); // CARDBios void CARDInit(void); @@ -262,8 +250,7 @@ s32 CARDCheckEx(s32 chan, s32* xferBytes); s32 CARDCheck(s32 chan); // CARDCreate -s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, - CARDCallback callback); +s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback); s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo); // CARDDelete @@ -282,8 +269,7 @@ s32 CARDFormat(s32 chan); // CARDMount int CARDProbe(s32 chan); s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize); -s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, - CARDCallback attachCallback); +s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback); s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback); s32 CARDUnmount(s32 chan); @@ -302,8 +288,7 @@ 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 CARDProgramAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback); s32 CARDProgram(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); // CARDRdwr @@ -311,20 +296,19 @@ 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 CARDRead(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); s32 CARDCancel(CARDFileInfo* fileInfo); // CARDRename -s32 CARDRename(s32 chan, const char* old, const char* _new); +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); +s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat* stat); // CARDWrite -s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, - CARDCallback callback); +s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback); s32 CARDWrite(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); #ifdef __cplusplus diff --git a/include/dolphin/dolphin/ar.h b/include/dolphin/dolphin/ar.h deleted file mode 100644 index 210f136..0000000 --- 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 0e90e54..0000000 --- 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 2a24dc6..0000000 --- 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 b9933c9..0000000 --- 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 46aa3e3..0000000 --- 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 cac4381..0000000 --- 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 15c5eb0..0000000 --- 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 1e32f63..0000000 --- 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 c3686e5..0000000 --- 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 1452975..0000000 --- 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 73b513f..0000000 --- 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 188fa7a..0000000 --- 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 d1ba630..0000000 --- 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 83c5aae..0000000 --- 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 fd899d3..0000000 --- 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 bd1b474..0000000 --- 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 d61838d..0000000 --- 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 0e7dc0b..0000000 --- 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 8deb22d..0000000 --- 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 f42dc22..0000000 --- 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 1e7f94e..0000000 --- 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 93a1b29..0000000 --- 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 e674041..0000000 --- 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 aaaaf6f..0000000 --- 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 af41844..0000000 --- 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 f9b6086..0000000 --- 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 1334696..0000000 --- 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/types.h b/include/dolphin/types.h index 213fe1a..d601da8 100644 --- a/include/dolphin/types.h +++ b/include/dolphin/types.h @@ -1,19 +1,19 @@ #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 long s32; -typedef unsigned long u32; -typedef signed long long int s64; +typedef signed char s8; +typedef unsigned char u8; +typedef signed short int s16; +typedef unsigned short int u16; +typedef signed long s32; +typedef unsigned long u32; +typedef signed long long int s64; typedef unsigned long long int u64; -typedef float f32; +typedef float f32; typedef double f64; -typedef char* Ptr; +typedef char *Ptr; typedef int BOOL; @@ -24,7 +24,7 @@ typedef int BOOL; #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. +#define AT_ADDRESS(addr) // was removed in GCC. define in linker script instead. #else #error unknown compiler #endif @@ -42,6 +42,6 @@ typedef int BOOL; #include "libc/string.h" #include "libc/ctype.h" -#include +#include "cmath.h" #endif diff --git a/include/libc/stddef.h b/include/libc/stddef.h index 8ca5874..b7917e5 100644 --- a/include/libc/stddef.h +++ b/include/libc/stddef.h @@ -3,7 +3,7 @@ #define offsetof(type, member) ((size_t) & (((type*)0)->member)) -//typedef unsigned int size_t; +typedef unsigned long size_t; #ifndef NULL #define NULL 0L diff --git a/include/libc/stdio.h b/include/libc/stdio.h index 130f903..8ddcb0d 100644 --- a/include/libc/stdio.h +++ b/include/libc/stdio.h @@ -1,7 +1,7 @@ #ifndef _STDIO_H_ #define _STDIO_H_ -#include "libc/stdarg.h" +#include typedef struct { diff --git a/include/libc/stdlib.h b/include/libc/stdlib.h index 8707808..ea14475 100644 --- a/include/libc/stdlib.h +++ b/include/libc/stdlib.h @@ -1,8 +1,8 @@ #ifndef _STDLIB_H_ #define _STDLIB_H_ -#include -#include +#include +#include #define RAND_MAX 32767 @@ -10,7 +10,7 @@ void srand(unsigned int seed); int rand(void); void abort(void); void exit(int status); -size_t wcstombs(char *dest, const wchar_t *src, size_t max); +size_t wcstombs(char* dest, const wchar_t* src, size_t max); #ifdef __MWERKS__ #define abs(x) __abs(x) diff --git a/include/libc/string.h b/include/libc/string.h index bb4dbd1..6d76046 100644 --- a/include/libc/string.h +++ b/include/libc/string.h @@ -1,7 +1,8 @@ #ifndef _STRING_H_ #define _STRING_H_ -#include +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/include/libc/wchar.h b/include/libc/wchar.h index e5c2056..08bc6c8 100644 --- a/include/libc/wchar.h +++ b/include/libc/wchar.h @@ -1,9 +1,9 @@ #ifndef _WCHAR_H_ #define _WCHAR_H_ -#include +#include -typedef unsigned short wchar_t; +//typedef U8 wchar_t; int fwide(FILE* stream, int mode); diff --git a/include/rwsdk/rwplcore.h b/include/rwsdk/rwplcore.h index c8a27d1..599942a 100644 --- a/include/rwsdk/rwplcore.h +++ b/include/rwsdk/rwplcore.h @@ -2,7 +2,7 @@ #define RWPLCORE_H #include -#include +#include #define rwBIGENDIAN @@ -53,7 +53,7 @@ struct RwInt128 #define RwUInt16MAXVAL 0xFFFF #define RwUInt16MINVAL 0x0000 -#include +#include #define _RW_C1 ((float)4.1666667908e-02) #define _RW_C2 ((float)-1.3888889225e-03) diff --git a/include/types.h b/include/types.h index 19547d0..fc2fa37 100644 --- a/include/types.h +++ b/include/types.h @@ -17,6 +17,7 @@ typedef unsigned long long U64; typedef float F32; typedef double F64; + #endif #ifdef NULL diff --git a/src/Dolphin/ai/ai.c b/src/Dolphin/ai/ai.c new file mode 100644 index 0000000..b9edc83 --- /dev/null +++ b/src/Dolphin/ai/ai.c @@ -0,0 +1,638 @@ +#include "Dolphin/ai.h" +#include "Dolphin/hw_regs.h" +#include "Dolphin/os.h" + +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 vs32 __AI_init_flag = FALSE; +static vs32 __AID_Active = FALSE; + +static OSTime bound_32KHz; +static OSTime bound_48KHz; +static OSTime min_wait; +static OSTime max_wait; +static OSTime buffer; + +static void __AI_set_stream_sample_rate(u32 rate); +static void __AISHandler(s16 interrupt, OSContext* context); +static void __AIDHandler(s16 interrupt, OSContext* context); +static void __AICallbackStackSwitch(register AIDCallback cb); +static void __AI_SRC_INIT(void); + +/** + * @note Address: 0x800F6864 + * @note Size: 0x44 + */ +AIDCallback AIRegisterDMACallback(AIDCallback callback) +{ + s32 oldInts; + AIDCallback ret; + + ret = __AID_Callback; + oldInts = OSDisableInterrupts(); + __AID_Callback = callback; + OSRestoreInterrupts(oldInts); + return ret; +} + +/** + * @note Address: 0x800F68A8 + * @note Size: 0x88 + */ +void AIInitDMA(u32 address, u32 length) +{ + s32 previousInterruptState; + + previousInterruptState = OSDisableInterrupts(); + + __DSPRegs[DSP_DMA_START_HI] = (u16)((__DSPRegs[DSP_DMA_START_HI] & ~0x3FF) | (address >> 16)); + __DSPRegs[DSP_DMA_START_LO] = + (u16)((__DSPRegs[DSP_DMA_START_LO] & ~0xFFE0) | (address & 0xFFFF)); + __DSPRegs[DSP_DMA_CONTROL_LEN] = + (u16)((__DSPRegs[DSP_DMA_CONTROL_LEN] & ~0x7FFF) | ((length >> 5) & 0xFFFF)); + + OSRestoreInterrupts(previousInterruptState); +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +BOOL AIGetDMAEnableFlag(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F6930 + * @note Size: 0x18 + */ +void AIStartDMA(void) +{ + SET_FLAG(__DSPRegs[DSP_DMA_CONTROL_LEN], DSP_DMA_START_FLAG); +} + +/** + * @note Address: 0x800F6948 + * @note Size: 0x18 + */ +void AIStopDMA(void) +{ + RESET_FLAG(__DSPRegs[DSP_DMA_CONTROL_LEN], DSP_DMA_START_FLAG); +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +u32 AIGetDMABytesLeft(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x1C + */ +u32 AIGetDMAStartAddr(void) +{ + const u32 startAddressHigh = (__DSPRegs[DSP_DMA_START_HI] & 0x03FF) << 16; + const u32 startAddressLow = __DSPRegs[DSP_DMA_START_LO] & 0xFFE0; + + return startAddressHigh | startAddressLow; +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +u32 AIGetDMALength(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +BOOL AICheckInit(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x44 + */ +AISCallback AIRegisterStreamCallback(AISCallback newCallback) +{ + s32 previousInterruptState; + AISCallback previousCallback; + + previousCallback = __AIS_Callback; + + previousInterruptState = OSDisableInterrupts(); + __AIS_Callback = newCallback; + OSRestoreInterrupts(previousInterruptState); + + return previousCallback; +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +u32 AIGetStreamSampleCount(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +void AIResetStreamSampleCount(void) +{ + __AIRegs[AI_CONTROL] = + (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_COUNT) | AI_CONTROL_STREAM_SAMPLE_COUNT; +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ + +void AISetStreamTrigger(u32 trigger) +{ + __AIRegs[AI_INTRPT_TIMING] = trigger; +} + +/** + * @note Address: N/A + * @note Size: 0x10 + */ +u32 AIGetStreamTrigger(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F6960 + * @note Size: 0xD8 + */ +void AISetStreamPlayState(u32 playState) +{ + s32 previousInterruptState; + u8 rightVolume; + u8 leftVolume; + + // If the requested state is the same as the current state, do nothing + if (playState == AIGetStreamPlayState()) + { + return; + } + + // If the sample rate is 0 and the requested state is play, initialize the sample rate converter + if (AIGetStreamSampleRate() == 0 && playState == TRUE) + { + rightVolume = AIGetStreamVolRight(); + leftVolume = AIGetStreamVolLeft(); + + // Temporarily mute the audio + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + + // Disable interrupts and initialize the sample rate converter + previousInterruptState = OSDisableInterrupts(); + __AI_SRC_INIT(); + + // Set the stream and state bits in the control register + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_COUNT) | + AI_CONTROL_STREAM_SAMPLE_COUNT; + __AIRegs[AI_CONTROL] = + (__AIRegs[AI_CONTROL] & ~AI_CONTROL_PLAY_STATE) | AI_CONTROL_PLAY_STATE; + + // Restore the previous interrupt state + OSRestoreInterrupts(previousInterruptState); + + // Restore the audio volume + AISetStreamVolLeft(rightVolume); + AISetStreamVolRight(leftVolume); + } + else + { + // Set the state bit in the control register to the requested state + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_PLAY_STATE) | playState; + } +} + +/** + * @note Address: 0x800F6A38 + * @note Size: 0x10 + */ +u32 AIGetStreamPlayState(void) +{ + return __AIRegs[AI_CONTROL] & AI_CONTROL_PLAY_STATE; +} + +/** + * @note Address: 0x800F6A48 + * @note Size: 0xE0 + */ +void AISetDSPSampleRate(u32 rate) +{ + u32 playState; + s32 previousInterruptState; + u8 leftVolume; + u8 rightVolume; + u32 streamSampleRate; + + // If the requested rate is the same as the current rate, do nothing + if (rate == AIGetDSPSampleRate()) + { + return; + } + + // Clear the DSP sample rate bit in the control register + __AIRegs[AI_CONTROL] &= ~AI_CONTROL_DSP_SAMPLE_RATE; + + if (rate == 0) + { + leftVolume = AIGetStreamVolLeft(); + rightVolume = AIGetStreamVolRight(); + playState = AIGetStreamPlayState(); + streamSampleRate = AIGetStreamSampleRate(); + + // Temporarily mute the audio + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + + // Disable interrupts and initialize the sample rate converter + previousInterruptState = OSDisableInterrupts(); + __AI_SRC_INIT(); + + // Set the stream sample count, stream sample rate, and play state bits in the control register + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_COUNT) | + AI_CONTROL_STREAM_SAMPLE_COUNT; + __AIRegs[AI_CONTROL] = + (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_RATE) | (streamSampleRate * 2); + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_PLAY_STATE) | playState; + + // Set the DSP sample rate bit in the control register + __AIRegs[AI_CONTROL] |= AI_CONTROL_DSP_SAMPLE_RATE; + + // Restore the previous interrupt state + OSRestoreInterrupts(previousInterruptState); + + // Restore the audio volume + AISetStreamVolLeft(leftVolume); + AISetStreamVolRight(rightVolume); + } +} + +/** + * @note Address: 0x800F6B28 + * @note Size: 0x14 + */ +u32 AIGetDSPSampleRate(void) +{ + return ((__AIRegs[AI_CONTROL] >> 6) & 1) ^ 1; +} + +/** + * @note Address: N/A + * @note Size: 0x28 + */ +void AISetStreamSampleRate(u32 rate) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: N/A + * @note Size: 0x20 + */ +void __AI_DEBUG_set_stream_sample_rate(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F6B3C + * @note Size: 0xD4 + */ +static void __AI_set_stream_sample_rate(u32 rate) +{ + s32 previousInterruptState; + s32 playState; + u8 leftVolume; + u8 rightVolume; + s32 dspSampleRateState; + + // If the requested rate is the same as the current rate, do nothing + if (rate == AIGetStreamSampleRate()) + { + return; + } + + playState = AIGetStreamPlayState(); + leftVolume = AIGetStreamVolLeft(); + rightVolume = AIGetStreamVolRight(); + + // Temporarily mute the audio + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + + // Save the state of the DSP sample rate bit and clear it in the control register + dspSampleRateState = __AIRegs[AI_CONTROL] & AI_CONTROL_DSP_SAMPLE_RATE; + __AIRegs[AI_CONTROL] &= ~AI_CONTROL_DSP_SAMPLE_RATE; + + // Disable interrupts and initialize the sample rate converter + previousInterruptState = OSDisableInterrupts(); + __AI_SRC_INIT(); + + // Restore the DSP sample rate bit in the control register + __AIRegs[AI_CONTROL] |= dspSampleRateState; + + // Set the stream sample count and stream sample rate bits in the control register + __AIRegs[AI_CONTROL] = + (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_COUNT) | AI_CONTROL_STREAM_SAMPLE_COUNT; + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~AI_CONTROL_STREAM_SAMPLE_RATE) | (rate * 2); + + // Restore the previous interrupt state + OSRestoreInterrupts(previousInterruptState); + + // Restore the audio play state and volume + AISetStreamPlayState(playState); + AISetStreamVolLeft(leftVolume); + AISetStreamVolRight(rightVolume); +} + +/** + * @note Address: 0x800F6C10 + * @note Size: 0x10 + */ +u32 AIGetStreamSampleRate(void) +{ + return (__AIRegs[AI_CONTROL] >> 1) & 1; +} + +/** + * @note Address: 0x800F6C20 + * @note Size: 0x1C + */ +void AISetStreamVolLeft(u8 volume) +{ + __AIRegs[AI_VOLUME] = (__AIRegs[AI_VOLUME] & ~0xFF) | (volume & 0xFF); +} + +/** + * @note Address: 0x800F6C3C + * @note Size: 0x10 + */ +u8 AIGetStreamVolLeft(void) +{ + return __AIRegs[AI_VOLUME]; +} + +/** + * @note Address: 0x800F6C4C + * @note Size: 0x1C + */ +void AISetStreamVolRight(u8 volume) +{ + __AIRegs[AI_VOLUME] = (__AIRegs[AI_VOLUME] & ~0xFF00) | ((volume & 0xFF) << 8); +} + +/** + * @note Address: 0x800F6C68 + * @note Size: 0x10 + */ +u8 AIGetStreamVolRight(void) +{ + return __AIRegs[AI_VOLUME] >> 8; +} + +/** + * @note Address: 0x800F6C78 + * @note Size: 0x16C + */ +void AIInit(u8* stack) +{ + // If AI is already initialized, do nothing + if (__AI_init_flag == TRUE) + { + return; + } + + // Register AI version + OSRegisterVersion(__AIVersion); + + // Set bounds and buffer sizes in ticks + bound_32KHz = OSNanosecondsToTicks(31524); + bound_48KHz = OSNanosecondsToTicks(42024); + min_wait = OSNanosecondsToTicks(42000); + max_wait = OSNanosecondsToTicks(63000); + buffer = OSNanosecondsToTicks(3000); + + // Initialize AI stream settings + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + AISetStreamTrigger(0); + AIResetStreamSampleCount(); + __AI_set_stream_sample_rate(1); + AISetDSPSampleRate(0); + + // Clear callbacks and set callback stack + __AIS_Callback = 0; + __AID_Callback = 0; + __CallbackStack = stack; + + // Set interrupt handlers and unmask interrupts + __OSSetInterruptHandler(5, __AIDHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_AI); + __OSSetInterruptHandler(8, __AISHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_AI); + + // Set AI initialisation flag to TRUE + __AI_init_flag = TRUE; +} + +/** + * @note Address: N/A + * @note Size: 0xC + */ +void AIReset(void) +{ + // UNUSED FUNCTION +} + +/** + * @note Address: 0x800F6DE4 + * @note Size: 0x7C + */ +static void __AISHandler(s16 interrupt, OSContext* context) +{ + OSContext tmpContext; + __AIRegs[AI_CONTROL] |= 8; + OSClearContext(&tmpContext); + OSSetCurrentContext(&tmpContext); + if (__AIS_Callback != NULL) + { + __AIS_Callback(__AIRegs[AI_SAMPLE_COUNTER]); + } + OSClearContext(&tmpContext); + OSSetCurrentContext(context); +} + +/** + * @note Address: 0x800F6E60 + * @note Size: 0xAC + */ +static 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); +} + +/** + * @note Address: 0x800F6F0C + * @note Size: 0x58 + */ +ASM static void __AICallbackStackSwitch(register AIDCallback cb) +{ +#ifdef __MWERKS__ // clang-format off + // 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 +#endif // clang-format on +} + +/** + * @note Address: 0x800F6F64 + * @note Size: 0x1E4 + */ +static 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[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~0x20) | 0x20; + __AIRegs[AI_CONTROL] &= ~2; + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~1) | 1; + + temp0 = __AIRegs[AI_SAMPLE_COUNTER]; + + while (temp0 == __AIRegs[AI_SAMPLE_COUNTER]) + ; + rising_32khz = OSGetTime(); + + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~2) | 2; + __AIRegs[AI_CONTROL] = (__AIRegs[AI_CONTROL] & ~1) | 1; + + temp1 = __AIRegs[AI_SAMPLE_COUNTER]; + while (temp1 == __AIRegs[AI_SAMPLE_COUNTER]) + ; + + rising_48khz = OSGetTime(); + + diff = rising_48khz - rising_32khz; + __AIRegs[AI_CONTROL] &= ~2; + __AIRegs[AI_CONTROL] &= ~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()) + ; +} + +/** + * @note Address: N/A + * @note Size: 0x8 + */ +void __ai_src_get_time(void) +{ + // UNUSED FUNCTION +} diff --git a/src/Dolphin/amcstubs/AmcExi2Stubs.c b/src/Dolphin/amcstubs/AmcExi2Stubs.c new file mode 100644 index 0000000..ba2c6f2 --- /dev/null +++ b/src/Dolphin/amcstubs/AmcExi2Stubs.c @@ -0,0 +1,50 @@ +#include "types.h" +#include "Dolphin/AmcExi2Stubs.h" + +/** + * @note Address: 0x800D2644 + * @note Size: 0x4 + */ +void EXI2_Init(vu8** inputPendingPtrRef, AmcEXICallback monitorCallback) { return; } + +/** + * @note Address: 0x800D2648 + * @note Size: 0x4 + */ +void EXI2_EnableInterrupts() { return; } + +/** + * @note Address: 0x800D264C + * @note Size: 0x8 + */ +int EXI2_Poll() { return 0; } + +/** + * @note Address: 0x800D2654 + * @note Size: 0x8 + */ +AmcExiError EXI2_ReadN(void* bytes, u32 length) { return AMC_EXI_NO_ERROR; } + +/** + * @note Address: 0x800D265C + * @note Size: 0x8 + */ +AmcExiError EXI2_WriteN(const void* bytes, u32 length) { return AMC_EXI_NO_ERROR; } + +/** + * @note Address: 0x800D2664 + * @note Size: 0x4 + */ +void EXI2_Reserve() { return; } + +/** + * @note Address: 0x800D2668 + * @note Size: 0x4 + */ +void EXI2_Unreserve() { return; } + +/** + * @note Address: 0x800D266C + * @note Size: 0x8 + */ +BOOL AMC_IsStub() { return TRUE; } diff --git a/src/Dolphin/ar/ar.c b/src/Dolphin/ar/ar.c new file mode 100644 index 0000000..6200395 --- /dev/null +++ b/src/Dolphin/ar/ar.c @@ -0,0 +1,428 @@ +#include "Dolphin/ar.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +char* __ARVersion = "<< Dolphin SDK - AR\trelease build: Nov 26 2003 05:19:42 (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); + +/** + * @note Address: 0x800D2674 + * @note Size: 0x44 + */ +ARCallback ARRegisterDMACallback(ARCallback callback) +{ + ARCallback oldCb; + BOOL enabled; + oldCb = __AR_Callback; + enabled = OSDisableInterrupts(); + __AR_Callback = callback; + OSRestoreInterrupts(enabled); + return oldCb; +} + +/** + * @note Address: 0x800D26B8 + * @note Size: 0x3C + */ +u32 ARGetDMAStatus() +{ + BOOL enabled; + u32 val; + enabled = OSDisableInterrupts(); + val = __DSPRegs[DSP_CONTROL_STATUS] & 0x0200; + OSRestoreInterrupts(enabled); + return val; +} + +/** + * @note Address: 0x800D26F4 + * @note Size: 0xF0 + */ +void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + + // Set main mem address + __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x3ff) | (u16)(mainmem_addr >> 16); + __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)(__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mainmem_addr & 0xffff); + + // Set ARAM address + __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x3ff) | (u16)(aram_addr >> 16); + __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)(__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff); + + // Set DMA buffer size + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x8000) | (type << 15)); + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x3ff) | (u16)(length >> 16); + __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff); + + OSRestoreInterrupts(enabled); +} + +/** + * @note Address: 0x800D27E4 + * @note Size: 0x68 + */ +u32 ARAlloc(u32 length) +{ + u32 oldStackPtr; + BOOL enabled; + + enabled = OSDisableInterrupts(); + oldStackPtr = __AR_StackPointer; + __AR_StackPointer += length; + *__AR_BlockLength = length; + __AR_BlockLength++; + __AR_FreeBlocks--; + OSRestoreInterrupts(enabled); + + return oldStackPtr; +} + +/** + * @note Address: 0x800D284C + * @note Size: 0xC4 + */ +u32 ARInit(u32* stack_index_addr, u32 num_entries) +{ + BOOL old; + u16 refresh; + + if (__AR_init_flag == TRUE) { + return __AR_ARAM_USR_BASE_ADDR; + } + + OSRegisterVersion(__ARVersion); + + old = OSDisableInterrupts(); + + __AR_Callback = NULL; + + __OSSetInterruptHandler(__OS_INTERRUPT_DSP_ARAM, __ARHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_ARAM); + + __AR_StackPointer = __AR_ARAM_USR_BASE_ADDR; + __AR_FreeBlocks = num_entries; + __AR_BlockLength = stack_index_addr; + + refresh = (u16)(__DSPRegs[DSP_ARAM_REFRESH] & 0xFF); + + __DSPRegs[DSP_ARAM_REFRESH] = (u16)((__DSPRegs[DSP_ARAM_REFRESH] & ~0xFF) | (refresh & 0xFF)); + + __ARChecksize(); + + __AR_init_flag = TRUE; + + OSRestoreInterrupts(old); + + return __AR_StackPointer; +} + +/** + * @note Address: 0x800D2910 + * @note Size: 0x8 + */ +u32 ARGetBaseAddress() { return __AR_ARAM_USR_BASE_ADDR; } + +/** + * @note Address: 0x800D2918 + * @note Size: 0x8 + */ +u32 ARGetSize() { return __AR_Size; } + +/** + * @note Address: 0x800D2920 + * @note Size: 0x78 + */ +void __ARHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + u16 tmp; + + tmp = __DSPRegs[DSP_CONTROL_STATUS]; + tmp = (u16)((tmp & ~(0x80 | 0x8)) | 0x20); + __DSPRegs[DSP_CONTROL_STATUS] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (__AR_Callback) { + (*__AR_Callback)(); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +/** + * @note Address: 0x800D2998 + * @note Size: 0x20 + */ +void __ARClearInterrupt() +{ + u16 tmp; + tmp = __DSPRegs[DSP_CONTROL_STATUS]; + tmp = (u16)((tmp & ~(0x80 | 0x8)) | 0x20); + __DSPRegs[DSP_CONTROL_STATUS] = tmp; +} + +/** + * @note Address: 0x800D29B8 + * @note Size: 0x10 + */ +u16 __ARGetInterruptStatus() { return ((u16)(__DSPRegs[DSP_CONTROL_STATUS] & 0x20)); } + +/** + * @note Address: N/A + * @note Size: 0x18 + */ +void __ARWaitForDMA() +{ + while (__DSPRegs[DSP_CONTROL_STATUS] & 0x0200) { } +} + +/** + * @note Address: N/A + * @note Size: 0xB0 + */ +void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) +{ + // Main mem address + __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + // ARAM address + __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + // DMA buffer size + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x8000); + + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff)); + + __ARWaitForDMA(); + + __ARClearInterrupt(); +} + +/** + * @note Address: N/A + * @note Size: 0xB0 + */ +void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) +{ + // Main mem address + __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + // ARAM address + __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + // DMA buffer size + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] | 0x8000); + + __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff)); + + __ARWaitForDMA(); + + __ARClearInterrupt(); +} + +/** + * @note Address: 0x800D29C8 + * @note Size: 0x17F4 + */ +void __ARChecksize() +{ + u8 test_data_pad[0x20 + 31]; + u8 dummy_data_pad[0x20 + 31]; + u8 buffer_pad[0x20 + 31]; + + u8 save_pad_1[0x20 + 31]; + u8 save_pad_2[0x20 + 31]; + u8 save_pad_3[0x20 + 31]; + u8 save_pad_4[0x20 + 31]; + u8 save_pad_5[0x20 + 31]; + + 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[DSP_ARAM_MODE] & 1)) { } + + ARAM_mode = 3; + ARAM_size = __AR_InternalSize = 0x1000000; + __DSPRegs[DSP_ARAM_SIZE] = (u16)((__DSPRegs[DSP_ARAM_SIZE] & ~(0x7 | 0x38)) | 0x20 | 2 | 1); + + test_data = (u32*)(OSRoundUp32B((u32)(test_data_pad))); + dummy_data = (u32*)(OSRoundUp32B((u32)(dummy_data_pad))); + buffer = (u32*)(OSRoundUp32B((u32)(buffer_pad))); + + save1 = (u32*)(OSRoundUp32B((u32)(save_pad_1))); + save2 = (u32*)(OSRoundUp32B((u32)(save_pad_2))); + save3 = (u32*)(OSRoundUp32B((u32)(save_pad_3))); + save4 = (u32*)(OSRoundUp32B((u32)(save_pad_4))); + save5 = (u32*)(OSRoundUp32B((u32)(save_pad_5))); + + for (i = 0; i < 8; i++) { + *(test_data + i) = 0xDEADBEEF; + *(dummy_data + i) = 0xBAD0BAD0; + } + + DCFlushRange((void*)test_data, 0x20); + DCFlushRange((void*)dummy_data, 0x20); + + __AR_ExpansionSize = 0; + + DCInvalidateRange((void*)save1, 0x20); + __ARReadDMA((u32)save1, ARAM_size + 0, 0x20); + PPCSync(); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + + DCInvalidateRange((void*)save2, 0x20); + __ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save3, 0x20); + __ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save4, 0x20); + __ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save5, 0x20); + __ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + + ARAM_mode |= 0 << 1; + ARAM_size += 0x0200000; + __AR_ExpansionSize = 0x0200000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + + ARAM_mode |= 4 << 1; + ARAM_size += 0x0400000; + __AR_ExpansionSize = 0x0400000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + + ARAM_mode |= 8 << 1; + ARAM_size += 0x0800000; + __AR_ExpansionSize = 0x0800000; + } else { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + + ARAM_mode |= 12 << 1; + ARAM_size += 0x1000000; + __AR_ExpansionSize = 0x1000000; + } else { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + __ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + + ARAM_mode |= 16 << 1; + ARAM_size += 0x2000000; + __AR_ExpansionSize = 0x2000000; + } + } + } + } + __DSPRegs[DSP_ARAM_SIZE] = (u16)((__DSPRegs[DSP_ARAM_SIZE] & ~(0x7 | 0x38)) | ARAM_mode); + } + + *(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size; + + __AR_Size = ARAM_size; +} diff --git a/src/Dolphin/ar/arq.c b/src/Dolphin/ar/arq.c new file mode 100644 index 0000000..9ef2b08 --- /dev/null +++ b/src/Dolphin/ar/arq.c @@ -0,0 +1,191 @@ +#include "Dolphin/ar.h" + +const char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Nov 26 2003 05:19:43 (0x2301) >>"; + +static ARQRequest* __ARQRequestQueueHi; +static ARQRequest* __ARQRequestTailHi; +static ARQRequest* __ARQRequestQueueLo; +static ARQRequest* __ARQRequestTailLo; +static ARQRequest* __ARQRequestPendingHi; +static ARQRequest* __ARQRequestPendingLo; +static ARQCallback __ARQCallbackHi; +static ARQCallback __ARQCallbackLo; +static u32 __ARQChunkSize; + +static volatile BOOL __ARQ_init_flag = FALSE; + +void __ARQPopTaskQueueHi(void); +void __ARQServiceQueueLo(void); +void __ARQCallbackHack(void); +void __ARQInterruptServiceRoutine(void); +void __ARQInitTempQueue(void); +void __ARQPushTempQueue(ARQRequest* task); + +/** + * @note Address: N/A + * @note Size: 0x70 + */ +void __ARQPopTaskQueueHi() +{ + if (__ARQRequestQueueHi) { + if (__ARQRequestQueueHi->type == ARQ_TYPE_MRAM_TO_ARAM) { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->length); + } else { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->source, __ARQRequestQueueHi->length); + } + + __ARQCallbackHi = __ARQRequestQueueHi->callback; + + __ARQRequestPendingHi = __ARQRequestQueueHi; + + __ARQRequestQueueHi = __ARQRequestQueueHi->next; + } +} + +/** + * @note Address: 0x800D41BC + * @note Size: 0x100 + */ +void __ARQServiceQueueLo() +{ + + if ((__ARQRequestPendingLo == nullptr) && (__ARQRequestQueueLo)) { + __ARQRequestPendingLo = __ARQRequestQueueLo; + __ARQRequestQueueLo = __ARQRequestQueueLo->next; + } + + if (__ARQRequestPendingLo) { + if (__ARQRequestPendingLo->length <= __ARQChunkSize) { + + if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM) { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, + __ARQRequestPendingLo->length); + } else { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, + __ARQRequestPendingLo->length); + } + + __ARQCallbackLo = __ARQRequestPendingLo->callback; + + } else if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM) { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQChunkSize); + + } else { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQChunkSize); + } + + __ARQRequestPendingLo->length -= __ARQChunkSize; + __ARQRequestPendingLo->source += __ARQChunkSize; + __ARQRequestPendingLo->dest += __ARQChunkSize; + } +} + +/** + * @note Address: 0x800D42BC + * @note Size: 0x4 + */ +void __ARQCallbackHack() { } + +/** + * @note Address: 0x800D42C0 + * @note Size: 0xCC + */ +void __ARQInterruptServiceRoutine() +{ + if (__ARQCallbackHi) { + (*__ARQCallbackHi)((u32)__ARQRequestPendingHi); + __ARQRequestPendingHi = nullptr; + __ARQCallbackHi = nullptr; + + } else if (__ARQCallbackLo) { + (*__ARQCallbackLo)((u32)__ARQRequestPendingLo); + __ARQRequestPendingLo = nullptr; + __ARQCallbackLo = nullptr; + } + + __ARQPopTaskQueueHi(); + + if (__ARQRequestPendingHi == nullptr) { + __ARQServiceQueueLo(); + } +} + +/** + * @note Address: 0x800D438C + * @note Size: 0x70 + */ +void ARQInit() +{ + if (__ARQ_init_flag == TRUE) { + return; + } + + OSRegisterVersion(__ARQVersion); + + __ARQRequestQueueHi = __ARQRequestQueueLo = nullptr; + __ARQChunkSize = ARQ_CHUNK_SIZE_DEFAULT; + ARRegisterDMACallback(&__ARQInterruptServiceRoutine); + __ARQRequestPendingHi = nullptr; + __ARQRequestPendingLo = nullptr; + __ARQCallbackHi = nullptr; + __ARQCallbackLo = nullptr; + + __ARQ_init_flag = TRUE; +} + +/** + * @note Address: 0x800D43FC + * @note Size: 0x15C + */ +void ARQPostRequest(ARQRequest* task, u32 owner, u32 type, u32 priority, u32 source, u32 dest, u32 length, ARQCallback callback) +{ + BOOL enabled; + + task->next = nullptr; + task->owner = owner; + task->type = type; + task->source = source; + task->dest = dest; + task->length = length; + + if (callback) { + task->callback = callback; + } else { + task->callback = (ARQCallback)&__ARQCallbackHack; + } + + enabled = OSDisableInterrupts(); + + switch (priority) { + case ARQ_PRIORITY_LOW: + if (__ARQRequestQueueLo) { + __ARQRequestTailLo->next = task; + } else { + __ARQRequestQueueLo = task; + } + __ARQRequestTailLo = task; + + break; + + case ARQ_PRIORITY_HIGH: + if (__ARQRequestQueueHi) { + __ARQRequestTailHi->next = task; + } else { + __ARQRequestQueueHi = task; + } + + __ARQRequestTailHi = task; + + break; + } + + if ((__ARQRequestPendingHi == nullptr) && (__ARQRequestPendingLo == nullptr)) { + __ARQPopTaskQueueHi(); + + if (__ARQRequestPendingHi == nullptr) { + __ARQServiceQueueLo(); + } + } + + OSRestoreInterrupts(enabled); +} diff --git a/src/SB/Core/gc/iFMV.h b/src/SB/Core/gc/iFMV.h index 5d0a57c..610f8bd 100644 --- a/src/SB/Core/gc/iFMV.h +++ b/src/SB/Core/gc/iFMV.h @@ -3,7 +3,7 @@ #include #include -#include +#include struct _GXRenderModeObj; diff --git a/src/SB/Core/gc/iTRC.cpp b/src/SB/Core/gc/iTRC.cpp index be1c0b5..aeee55c 100644 --- a/src/SB/Core/gc/iTRC.cpp +++ b/src/SB/Core/gc/iTRC.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #define FONT_MATRIX_ID 0x1E @@ -148,7 +148,7 @@ void ROMFont::DrawTextBox(S32 param_1, S32 param_2, S32 param_3, S32 param_4, ch { RenderBegin(); strcpy(acStack_128, str); - tokenizedString = strtok(acStack_128, " "); + //tokenizedString = strtok(acStack_128, " "); baseWidth = GetWidth(" "); iVar4 = param_2 + param_4; iVar5 = param_1; @@ -161,7 +161,7 @@ void ROMFont::DrawTextBox(S32 param_1, S32 param_2, S32 param_3, S32 param_4, ch iVar5 = param_1; } DrawString(iVar5, param_2, tokenizedString); - tokenizedString = strtok(NULL, " "); + //tokenizedString = strtok(NULL, " "); iVar5 = tokWidth + baseWidth + iVar5; } RenderEnd(); diff --git a/src/SB/Core/gc/iWad.cpp b/src/SB/Core/gc/iWad.cpp index a49499a..5bf3c10 100644 --- a/src/SB/Core/gc/iWad.cpp +++ b/src/SB/Core/gc/iWad.cpp @@ -1198,7 +1198,7 @@ static void iSG_upd_icostat(CARDStat*, CARDStat* stat) CARDSetCommentAddress(stat, 0); CARDSetBannerFormat(stat, CARD_STAT_BANNER_RGB5A3); CARDSetIconAddress(stat, 0x40); - CARDSetIconAnim(stat, CARD_STAT_ANIM_LOOP); + //CARDSetIconAnim(stat, CARD_STAT_ANIM_LOOP); for (S32 i = 0; i < CARD_ICON_MAX; ++i) { @@ -2493,17 +2493,17 @@ void iMath3Init() F32 itan(F32 x) { - return std::tanf(x); + return tanf(x); } F32 icos(F32 x) { - return std::cosf(x); + return cosf(x); } F32 isin(F32 x) { - return std::sinf(x); + return sinf(x); } // iLight @@ -2822,8 +2822,8 @@ static void PlayFMV(char* fname, u32 buttons, F32 time) GXGetCullMode(&cull_mode); iFMV::InitDisplay(_RwDlRenderMode); iPadStopRumble(globals.pad0); - RADSetAudioMemory(arammalloc, aramfree); - RADSetMemory(iFMVmalloc, iFMVfree); + //RADSetAudioMemory(arammalloc, aramfree); + //RADSetMemory(iFMVmalloc, iFMVfree); Setup_surface_array(); for (char* c = fname; *c != NULL; c++) diff --git a/src/SB/Core/gc/iWad.h b/src/SB/Core/gc/iWad.h index b967af5..306e7f0 100644 --- a/src/SB/Core/gc/iWad.h +++ b/src/SB/Core/gc/iWad.h @@ -2,6 +2,10 @@ #define IWAD_H #include "../src/sb/game/zGlobals.h" +#include "types.h" +#include "dolphin/types.h" +#include "cmath.h" +#include "math.h" #include "iAnim.h" #include "iAnimSKB.h" diff --git a/src/SB/Core/x/xCamera.cpp b/src/SB/Core/x/xCamera.cpp index 3c5a3f2..0192323 100644 --- a/src/SB/Core/x/xCamera.cpp +++ b/src/SB/Core/x/xCamera.cpp @@ -9,8 +9,7 @@ #include "iMath.h" -#include -#include +#include struct cameraFXShake { diff --git a/src/SB/Core/x/xEnt.h b/src/SB/Core/x/xEnt.h index e097784..004d0de 100644 --- a/src/SB/Core/x/xEnt.h +++ b/src/SB/Core/x/xEnt.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include "xBase.h" #include "xMath3.h" diff --git a/src/SB/Core/x/xString.h b/src/SB/Core/x/xString.h index c2dfaf3..8f8be6a 100644 --- a/src/SB/Core/x/xString.h +++ b/src/SB/Core/x/xString.h @@ -2,7 +2,8 @@ #define XSTRING_H #include -#include +#include <../src/dolphin/support/string.c> + struct substr { const char* text; diff --git a/src/SB/Core/x/xWad1.cpp b/src/SB/Core/x/xWad1.cpp index b6388e2..9090453 100644 --- a/src/SB/Core/x/xWad1.cpp +++ b/src/SB/Core/x/xWad1.cpp @@ -2023,7 +2023,7 @@ void xAnimFileEval(xAnimFile* data, F32 time, F32* bilinear, U32 flags, xVec3* t for (i = 0; i < 2; ++i) { F32 f30 = CLAMP(bilinear[i], 0.0f, data->NumAnims[i] - 1); - f32 t = std::floorf(f30); + f32 t = floorf(f30); bilerp[i] = f30 - t; biindex[i] = t; biplus[i] = MIN(biindex[i] + 1, data->NumAnims[i]); diff --git a/src/SB/Core/x/xWad1.h b/src/SB/Core/x/xWad1.h index d8218c1..60e66aa 100644 --- a/src/SB/Core/x/xWad1.h +++ b/src/SB/Core/x/xWad1.h @@ -1,6 +1,8 @@ #ifndef XWAD1_H #define XWAD1_H +#include + #include "zGlobals.h" #include "xCutscene.h" #include "iCutscene.h" diff --git a/src/SB/Core/x/xWad2.h b/src/SB/Core/x/xWad2.h index 03e6a16..c252d1d 100644 --- a/src/SB/Core/x/xWad2.h +++ b/src/SB/Core/x/xWad2.h @@ -1,10 +1,14 @@ #ifndef XWAD2_H #define XWAD2_H +#include +#include "cmath.h" + #include "zGlobals.h" #include #include -#include "stdlib.h" +#include +#include #include "xString.h" #include "string.h" #include diff --git a/src/SB/Core/x/xWad3.h b/src/SB/Core/x/xWad3.h index e986e74..367b1e8 100644 --- a/src/SB/Core/x/xWad3.h +++ b/src/SB/Core/x/xWad3.h @@ -1,7 +1,7 @@ #ifndef XWAD3_H #define XWAD3_H -#include "stdlib.h" +#include #include #include "dolphin\types.h" #include diff --git a/src/SB/Core/x/xWad5.h b/src/SB/Core/x/xWad5.h index 7f9e7dd..fad0e71 100644 --- a/src/SB/Core/x/xWad5.h +++ b/src/SB/Core/x/xWad5.h @@ -4,7 +4,7 @@ #include #include "zGlobals.h" #include "xVec3.h" -#include "stdlib.h" +#include #include #include "fastmath.h" #include "xVolume.h" diff --git a/src/SB/Core/x/xpkrsvc.h b/src/SB/Core/x/xpkrsvc.h index 28148c0..a4f78a1 100644 --- a/src/SB/Core/x/xpkrsvc.h +++ b/src/SB/Core/x/xpkrsvc.h @@ -2,7 +2,7 @@ #define XPKRSVC_H #include -#include +#include "iTime.h" #include "xhipio.h" #include "xordarray.h" diff --git a/src/SB/Game/zCameraTweak.h b/src/SB/Game/zCameraTweak.h index b2e7344..2b92a2c 100644 --- a/src/SB/Game/zCameraTweak.h +++ b/src/SB/Game/zCameraTweak.h @@ -3,7 +3,7 @@ #include "xDynAsset.h" -#include +#include <../src/dolphin/support/string.c> struct CameraTweak_asset : xDynAsset { diff --git a/src/SB/Game/zWad3.cpp b/src/SB/Game/zWad3.cpp index 65daa1f..8822645 100644 --- a/src/SB/Game/zWad3.cpp +++ b/src/SB/Game/zWad3.cpp @@ -1,5 +1,7 @@ #include "zWad3.h" +#include <../src/dolphin/support/string.c> + // zVolume struct PreCalcOcclude diff --git a/src/dolphin/G2D/G2D.c b/src/dolphin/G2D/G2D.c deleted file mode 100644 index 351a504..0000000 --- a/src/dolphin/G2D/G2D.c +++ /dev/null @@ -1,721 +0,0 @@ -#include -#include -#include -#include "fake_tgmath.h" - -static G2DGlob glob; - -void G2DInitSprite(G2DSprite *sprite) { - f32 rInvWidth; - f32 rInvHeight; - - rInvWidth = 1.0f / (f32)GXGetTexObjWidth(sprite->to); - rInvHeight = 1.0f / (f32)GXGetTexObjHeight(sprite->to); - sprite->rS0 = (0.5f + (f32)sprite->nTlcS) * rInvWidth; - sprite->rS1 = rInvWidth * (((f32)sprite->nTlcS + (f32)sprite->nWidth) - 0.5f); - sprite->rT0 = (0.5f + (f32)sprite->nTlcT) * rInvHeight; - sprite->rT1 = rInvHeight * (((f32)sprite->nTlcT + (f32)sprite->nHeight) - 0.5f); -} - -void G2DDrawSprite(G2DSprite* sprite, G2DPosOri* po) { - f32 rOX, rOY; - f32 rWX, rWY; - f32 rHX, rHY; - f32 rRelX, rRelY; - - GXClearVtxDesc(); - GXLoadTexObj(sprite->to, GX_TEXMAP0); - - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); - GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); - GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); - GXSetNumTexGens(1); - GXSetNumChans(0); - - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); - - rOX = 0.5f * po->rOriX; - rOY = 0.5f * po->rOriY; - - rWX = (f32)sprite->nWidth * rOX; - rWY = (f32)sprite->nWidth * rOY; - rHX = (f32)sprite->nHeight * rOX; - rHY = (f32)sprite->nHeight * rOY; - - rRelX = po->rPosX - glob.poCam.rPosX; - rRelY = po->rPosY - glob.poCam.rPosY; - if (rRelX >= glob.rHalfX) { - rRelX -= glob.rWorldX; - } - if (rRelX < -glob.rHalfX) { - rRelX += glob.rWorldX; - } - if (rRelY >= glob.rHalfY) { - rRelY -= glob.rWorldY; - } - if (rRelY < -glob.rHalfY) { - rRelY += glob.rWorldY; - } - - rRelX += glob.poCam.rPosX; - rRelY += glob.poCam.rPosY; - - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - - GXPosition2f32(rWY + (rRelX - rHX), (rRelY - rHY) - rWX); - GXTexCoord2f32(sprite->rS0, sprite->rT1); - - GXPosition2f32(rWY + (rRelX + rHX), (rRelY + rHY) - rWX); - GXTexCoord2f32(sprite->rS0, sprite->rT0); - - GXPosition2f32((rRelX + rHX) - rWY, rWX + (rRelY + rHY)); - GXTexCoord2f32(sprite->rS1, sprite->rT0); - - GXPosition2f32((rRelX - rHX) - rWY, rWX + (rRelY - rHY)); - GXTexCoord2f32(sprite->rS1, sprite->rT1); - - GXEnd(); -} - -static inline void FillSection(G2DLayer* layer, s8* aSortBuffer, s32* nScanLine, s32 nEvent, s16* nIdx, - s32* nL, s32* nR, f32* rLeft, f32* rRight, f32 rStep0, f32 rStep1, s32 nMapX, - s32 nMapY) { - s32 nHMask; - s32 nVMask; - s32 nI; - s32 nJ; - s32 nK; - s32 nM; - s16 nMaterial; - s16* pAddr; - - nHMask = (1 << layer->nHS) - 1; - nVMask = (1 << layer->nVS) - 1; - if (layer->nBPI == 1) { - u8 nTile; - if (layer->bWrap) { - for (; *nScanLine <= nEvent; (*nScanLine)++) { - nJ = *nScanLine - 1; - nK = (nVMask & (nJ + nMapY)) << layer->nHS; - for (nI = *nL; nI <= *nR; nI++) { - nTile = ((u8*)layer->map)[nK + (nHMask & (nI + nMapX))]; - nMaterial = layer->tileDesc[nTile].nMaterial; - pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; - pAddr[1]++; - - if (*pAddr != *nIdx) { - *nIdx += 2; - *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; - } - *(s16*)&aSortBuffer[*nIdx] = nTile; - *nIdx += 2; - aSortBuffer[(*nIdx)++] = nI; - aSortBuffer[(*nIdx)++] = nJ; - *pAddr = *nIdx; - } - *rLeft += rStep0; - *rRight += rStep1; - *nL = floor(*rLeft); - *nR = floor(*rRight); - } - } else { - for (; *nScanLine <= nEvent; (*nScanLine)++) { - nJ = *nScanLine - 1 + nMapY; - if (nJ < 0) { - nK = 0; - } - else if ( nJ > nVMask ) { - nK = nVMask << layer->nHS; - } - else { - nK = nJ << layer->nHS; - } - - nM = *nR + nMapX; - for (nI = *nL + nMapX; nI <= nM; nI++) { - if ( nI < 0 ) { - nTile = ((u8*)layer->map)[nK]; - } - else if ( nI > nHMask ) { - nTile = ((u8*)layer->map)[nK + nHMask]; - } - else { - nTile = ((u8*)layer->map)[nK + nI]; - } - - nMaterial = layer->tileDesc[nTile].nMaterial; - pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; - pAddr[1]++; - - if (*pAddr != *nIdx) { - *nIdx += 2; - *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; - } - *(s16*)&aSortBuffer[*nIdx] = nTile; - *nIdx += 2; - aSortBuffer[(*nIdx)++] = nI - nMapX; - aSortBuffer[(*nIdx)++] = nJ - nMapY; - *pAddr = *nIdx; - } - - *rLeft += rStep0; - *rRight += rStep1; - *nL = floor(*rLeft); - *nR = floor(*rRight); - } - } - } else { - u16 nTile; - if (layer->bWrap) { - for (; *nScanLine <= nEvent; (*nScanLine)++) { - nJ = *nScanLine - 1; - nK = (nVMask & (nJ + nMapY)) << layer->nHS; - for (nI = *nL; nI <= *nR; nI++) { - nTile = ((u16*)layer->map)[nK + (nHMask & (nI + nMapX))]; - nMaterial = layer->tileDesc[nTile].nMaterial; - pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; - pAddr[1]++; - - if (*pAddr != *nIdx) { - *nIdx += 2; - *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; - } - *(s16*)&aSortBuffer[*nIdx] = nTile; - *nIdx += 2; - aSortBuffer[(*nIdx)++] = nI; - aSortBuffer[(*nIdx)++] = nJ; - *pAddr = *nIdx; - } - - *rLeft += rStep0; - *rRight += rStep1; - *nL = floor(*rLeft); - *nR = floor(*rRight); - } - } else { - for (; *nScanLine <= nEvent; (*nScanLine)++) { - nJ = *nScanLine - 1 + nMapY; - if (nJ < 0) { - nK = 0; - } - else if ( nJ > nVMask ) { - nK = nVMask << layer->nHS; - } - else { - nK = nJ << layer->nHS; - } - - nM = *nR + nMapX; - for (nI = *nL + nMapX; nI <= nM; nI++) { - if ( nI < 0 ) { - nTile = ((u16*)layer->map)[nK]; - } - else if ( nI > nHMask ) { - nTile = ((u16*)layer->map)[nK + nHMask]; - } - else { - nTile = ((u16*)layer->map)[nK + nI]; - } - - nMaterial = layer->tileDesc[nTile].nMaterial; - pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; - pAddr[1]++; - - if (*pAddr != *nIdx) { - *nIdx += 2; - *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; - } - *(s16*)&aSortBuffer[*nIdx] = nTile; - *nIdx += 2; - aSortBuffer[(*nIdx)++] = nI - nMapX; - aSortBuffer[(*nIdx)++] = nJ - nMapY; - *pAddr = *nIdx; - } - - *rLeft += rStep0; - *rRight += rStep1; - *nL = floor(*rLeft); - *nR = floor(*rRight); - } - } - } -} - -void G2DDrawLayer(G2DLayer* layer, s8* aSortBuffer) { - s16* pAddr; - s16 aCount0; - s16 aCount1; - s16 aCount2; - f32 rInvTileWidth; - f32 rInvTileHeight; - s16 nIdx; - s32 nI; - s32 nJ; - s32 nK; - s32 nL; - s32 nR; - f32 rX; - f32 rY; - f32 rTlcX; - f32 rTrcX; - f32 rBlcX; - f32 rBrcX; - f32 rTlcY; - f32 rTrcY; - f32 rBlcY; - f32 rBrcY; - s32 nScanLine; - f32 rLeft; - f32 rRight; - f32 rLeftY; - f32 rRightY; - f32 rStep0; - f32 rStep1; - f32 rMid; - s32 nEvent0; - s32 nEvent1; - s32 nEvent2; - f32 rFrcX; - f32 rFrcY; - s32 nMapX; - s32 nMapY; - s32 nLocalMapX; - s32 nLocalMapY; - f32 rCamOriX; - f32 rCamOriY; - s16 nTile; - s16 nMaterial; - f32 rRatio; - - aCount0 = 0; - aCount1 = 0; - aCount2 = 0; - rInvTileWidth = 1.0f / (f32)layer->nTileWidth; - rInvTileHeight = 1.0f / (f32)layer->nTileHeight; - - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); - - for (nI = 0; nI < layer->nNumMaterials; nI++) { - pAddr = (s16*)&layer->matDesc[nI]; - pAddr[0] = nI << 1; - pAddr[1] = 0; - } - nIdx = (nI - 1) << 1; - - rFrcX = glob.poCam.rPosX * rInvTileWidth; - rFrcY = glob.poCam.rPosY * rInvTileHeight; - nMapX = (s32)rFrcX; - nMapY = (s32)rFrcY; - rFrcX -= nMapX; - rFrcY -= nMapY; - - rCamOriX = glob.poCam.rOriX; - rCamOriY = glob.poCam.rOriY; - if (rCamOriX < 0.0001 && rCamOriX > -0.0001) { - rCamOriX = 0.0001f; - } - else if (rCamOriY < 0.0001 && rCamOriY > -0.0001) { - rCamOriY = 0.0001f; - } - - rX = 0.5f * (f32)glob.nViewportWidth; - rY = 0.5f * (f32)glob.nViewportHeight; - rTlcX = rFrcX + (rInvTileWidth * ((rY * rCamOriX) + (rX * rCamOriY))); - rTlcY = (rFrcY + (rInvTileHeight * ((rY * rCamOriY) - (rX * rCamOriX)))); - rTrcX = rFrcX + (rInvTileWidth * ((rY * rCamOriX) - (rX * rCamOriY))); - rTrcY = (rFrcY + (rInvTileHeight * ((rY * rCamOriY) + (rX * rCamOriX)))); - rBlcX = rFrcX - (rInvTileWidth * ((rY * rCamOriX) - (rX * rCamOriY))); - rBlcY = rFrcY - (rInvTileHeight * ((rY * rCamOriY) + (rX * rCamOriX))); - rBrcX = rFrcX - (rInvTileWidth * ((rY * rCamOriX) + (rX * rCamOriY))); - rBrcY = rFrcY - (rInvTileHeight * ((rY * rCamOriY) - (rX * rCamOriX))); - - if (rCamOriY < 0.0f) { - if (rCamOriX >= 0.0f) { - nScanLine = (s32)floor(rTlcY) + 1; - rY = nScanLine - rTlcY; - rLeft = rTlcX; - rLeftY = rBlcY; - rRightY = rTrcY; - nEvent2 = (s32)floor(rBrcY); - rStep0 = rCamOriX / rCamOriY; - rStep1 = -rCamOriY / rCamOriX; - } - else { - nScanLine = (s32)floor(rTrcY) + 1; - rY = nScanLine - rTrcY; - rLeft = rTrcX; - rLeftY = rTlcY; - rRightY = rBrcY; - nEvent2 = (s32)floor(rBlcY); - rStep0 = -rCamOriY / rCamOriX; - rStep1 = rCamOriX / rCamOriY; - } - } else { - if (rCamOriX >= 0.0f) { - nScanLine = (s32)floor(rBlcY) + 1; - rY = nScanLine - rBlcY; - rLeft = rBlcX; - rLeftY = rBrcY; - rRightY = rTlcY; - nEvent2 = (s32)floor(rTrcY); - rStep0 = -rCamOriY / rCamOriX; - rStep1 = rCamOriX / rCamOriY; - } else { - nScanLine = (s32)floor(rBrcY) + 1; - rY = nScanLine - rBrcY; - rLeft = rBrcX; - rLeftY = rTrcY; - rRightY = rBlcY; - nEvent2 = (s32)floor(rTlcY); - rStep0 = rCamOriX / rCamOriY; - rStep1 = -rCamOriY / rCamOriX; - } - } - - rRatio = (f32)layer->nTileHeight / (f32)layer->nTileWidth; - rStep0 *= rRatio; - rStep1 *= rRatio; - rRight = rLeft + (rY * rStep1); - rLeft = rLeft + (rY * rStep0); - - if (rLeftY < rRightY) { - nEvent0 = (s32)floor(rLeftY); - nEvent1 = (s32)floor(rRightY); - rMid = rStep1; - } else { - nEvent0 = (s32)floor(rRightY); - nEvent1 = (s32)floor(rLeftY); - rMid = rStep0; - } - - nL = (s32)floor(rLeft); - nR = (s32)floor(rRight); - nLocalMapX = nMapX; - nLocalMapY = nMapY; - - if (!layer->bWrap) { - f32 rInvTileWidth = 1.0f / (f32)layer->nTileWidth; - f32 rInvTileHeight = 1.0f / (f32)layer->nTileHeight; - f32 rLocalPosX = glob.poCam.rPosX; - f32 rLocalPosY = glob.poCam.rPosY; - f32 rSplitX = 0.5f * (glob.rWorldX + (f32)(layer->nTileWidth * (1 << layer->nHS))); - f32 rSplitY = 0.5f * (glob.rWorldY + (f32)(layer->nTileHeight * (1 << layer->nVS))); - - if (rLocalPosX >= rSplitX) { - rLocalPosX -= glob.rWorldX; - } - - if (rLocalPosY >= rSplitY) { - rLocalPosY -= glob.rWorldY; - } - - rFrcX = rLocalPosX * rInvTileWidth; - rFrcY = rLocalPosY * rInvTileHeight; - - nLocalMapX = floor(rFrcX); - nLocalMapY = floor(rFrcY); - } - - FillSection(layer, aSortBuffer, &nScanLine, nEvent0, &nIdx, &nL, &nR, &rLeft, &rRight, rStep0, rStep1, nLocalMapX, nLocalMapY); - - pAddr = (s16*)&layer->matDesc[0].nReserved; - aCount0 = pAddr[1]; - pAddr = (s16*)&layer->matDesc[1].nReserved; - aCount1 = pAddr[1]; - pAddr = (s16*)&layer->matDesc[2].nReserved; - aCount2 = pAddr[1]; - - if ((f32)nScanLine > rLeftY) { - rLeft -= rStep0 * ((f32)nScanLine - rLeftY); - nL = (s32)floor(rLeft); - rLeft += rStep1 * (((f32)nScanLine - rLeftY) - 1.0f); - rLeftY = 1000.0f; - } - - if ((f32)nScanLine > rRightY) { - rRight -= rStep1 * ((f32)nScanLine - rRightY); - nR = (s32)floor(rRight); - rRight += rStep0 * (((f32)nScanLine - rRightY) - 1.0f); - rRightY = 1000.0f; - } - - FillSection(layer, aSortBuffer, &nScanLine, nEvent1, &nIdx, &nL, &nR, &rLeft, &rRight, rMid, rMid, nLocalMapX, nLocalMapY); - - pAddr = (s16*)&layer->matDesc[0].nReserved; - aCount0 = pAddr[1]; - pAddr = (s16*)&layer->matDesc[1].nReserved; - aCount1 = pAddr[1]; - pAddr = (s16*)&layer->matDesc[2].nReserved; - aCount2 = pAddr[1]; - - if ((f32)nScanLine > rLeftY) { - rLeft -= rStep0 * ((f32)nScanLine - rLeftY); - nL = (s32)floor(rLeft); - rLeft += rStep1 * (((f32)nScanLine - rLeftY) - 1.0f); - } - - if ((f32)nScanLine > rRightY) { - rRight -= rStep1 * ((f32)nScanLine - rRightY); - nR = (s32)floor(rRight); - rRight += rStep0 * (((f32)nScanLine - rRightY) - 1.0f); - } - - FillSection(layer, aSortBuffer, &nScanLine, nEvent2 + 1, &nIdx, &nL, &nR, &rLeft, &rRight, rStep1, rStep0, nLocalMapX, nLocalMapY); - - pAddr = (s16*)&layer->matDesc[0].nReserved; - aCount0 = pAddr[1]; - pAddr = (s16*)&layer->matDesc[1].nReserved; - aCount1 = pAddr[1]; - pAddr = (s16*)&layer->matDesc[2].nReserved; - aCount2 = pAddr[1]; - - for (nMaterial = 0; nMaterial < layer->nNumMaterials; nMaterial++) { - pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; - if (!pAddr[1]) { - continue; - } - - switch (layer->matDesc[nMaterial].nCategory) { - case G2D_CTG_EMPTY: - continue; - - case G2D_CTG_RGBA_INDEX8: { - GXClearVtxDesc(); - - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - - GXSetNumTexGens(0); - GXSetVtxDesc(GX_VA_TEX0, GX_NONE); - GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); - GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8); - GXSetArray(GX_VA_CLR0, layer->matDesc[nMaterial].clut, 4); - - GXSetNumChans(1); - GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_VTX, GX_SRC_VTX, 1, GX_DF_NONE, GX_AF_NONE); - - nIdx = nMaterial << 1; - GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); - - for (nK = pAddr[1]; nK--; ) { - f32 rI, rJ; - u8 nCI; - - nTile = *((s16*)&aSortBuffer[nIdx]); - if (nTile < 0) { - nIdx -= nTile; - nTile = *((s16*)&aSortBuffer[nIdx]); - } - nIdx += 2; - nI = aSortBuffer[nIdx++]; - nJ = aSortBuffer[nIdx++]; - - rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); - rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); - nCI = layer->tileDesc[nTile].nCI; - - GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); - GXColor1x8(nCI); - - GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); - GXColor1x8(nCI); - - GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); - GXColor1x8(nCI); - - GXPosition2f32(rI, rJ); - GXColor1x8(nCI); - } - - GXEnd(); - break; - } - - case G2D_CTG_RGB_DIRECT: { - GXClearVtxDesc(); - - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - - GXSetNumTexGens(0); - GXSetVtxDesc(GX_VA_TEX0, GX_NONE); - GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0); - GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); - - GXSetNumChans(1); - GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_VTX, GX_SRC_VTX, 1, GX_DF_NONE, GX_AF_NONE); - - nIdx = nMaterial << 1; - GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); - - for (nK = pAddr[1]; nK--; ) { - f32 rI, rJ; - u8 nR, nG, nB; - - nTile = *((s16*)&aSortBuffer[nIdx]); - if (nTile < 0) { - nIdx -= nTile; - nTile = *((s16*)&aSortBuffer[nIdx]); - } - - nIdx += 2; - nI = aSortBuffer[nIdx++]; - nJ = aSortBuffer[nIdx++]; - - rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); - rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); - nR = layer->tileDesc[nTile].nS; - nG = layer->tileDesc[nTile].nT; - nB = layer->tileDesc[nTile].nCI; - - GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); - GXColor3u8(nR, nG, nB); - - GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); - GXColor3u8(nR, nG, nB); - - GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); - GXColor3u8(nR, nG, nB); - - GXPosition2f32(rI, rJ); - GXColor3u8(nR, nG, nB); - } - - GXEnd(); - break; - } - - case G2D_CTG_TEXTURE: { - f32 rInvTileWidth = 1.0f / (f32)GXGetTexObjWidth(layer->matDesc[nMaterial].to); - f32 rInvTileHeight = 1.0f / (f32)GXGetTexObjHeight(layer->matDesc[nMaterial].to); - - f32 rWidth = (f32)layer->nTileWidth * rInvTileWidth; - f32 rHeight = (f32)layer->nTileHeight * rInvTileHeight; - - f32 rS0 = 0.0f; - f32 rT0 = 0.0f; - f32 rS1 = rWidth; - f32 rT1 = rHeight; - - GXClearVtxDesc(); - - GXLoadTexObj(layer->matDesc[nMaterial].to, GX_TEXMAP0); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - - GXSetNumTexGens(1); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); - GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); - - if ( layer->matDesc[nMaterial].color ) { - GXSetNumChans(1); - GXSetChanMatColor(GX_COLOR0A0, *layer->matDesc[nMaterial].color); - GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_REG, GX_SRC_REG, 1, GX_DF_NONE, GX_AF_NONE); - GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); - } else { - GXSetNumChans(0); - GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); - } - - nIdx = nMaterial << 1; - GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); - - for (nK = pAddr[1]; nK--; ) { - f32 rI; - f32 rJ; - f32 rS; - f32 rT; - - nTile = *((s16*)&aSortBuffer[nIdx]); - if (nTile < 0) { - nIdx -= nTile; - nTile = *((s16*)&aSortBuffer[nIdx]); - } - - nIdx += 2; - nI = aSortBuffer[nIdx++]; - nJ = aSortBuffer[nIdx++]; - - rS = rS0 + (rWidth * (f32)layer->tileDesc[nTile].nS); - rT = rT0 + (rHeight * (f32)layer->tileDesc[nTile].nT); - rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); - rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); - - GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); - GXTexCoord2f32(rS + rS1, rT); - - GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); - GXTexCoord2f32(rS + rS1, rT + rT1); - - GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); - GXTexCoord2f32(rS, rT + rT1); - - GXPosition2f32(rI, rJ); - GXTexCoord2f32(rS, rT); - } - - GXEnd(); - break; - } - } - } -} - -void G2DSetCamera(G2DPosOri* po) { - Mtx mView; - Vec vPos; - Vec vUp; - Vec vAt; - f32 rX; - f32 rY; - - glob.poCam = *po; - - vUp.x = po->rOriX; - vUp.y = po->rOriY; - vUp.z = 0.0f; - - rX = (((640 - glob.nViewportWidth) >> 1) - glob.nViewportTlcX); - rY = (((448 - glob.nViewportHeight) >> 1) - glob.nViewportTlcY); - - vPos.x = po->rPosX - (vUp.x * rY) - (vUp.y * rX); - vPos.y = po->rPosY + (vUp.x * rX) - (vUp.y * rY); - vPos.z = -300.0f; - - vAt.x = vPos.x; - vAt.y = vPos.y; - vAt.z = 0.0f; - - MTXLookAt(mView, &vPos, &vUp, &vAt); - GXLoadPosMtxImm(mView, GX_PNMTX0); -} - -void G2DInitWorld(u32 nWorldX, u32 nWorldY) { - Mtx44 mProjection; - - glob.rWorldX = (f32)nWorldX; - glob.rWorldY = (f32)nWorldY; - glob.rHalfX = (f32)(nWorldX >> 1); - glob.rHalfY = (f32)(nWorldY >> 1); - GXSetZMode(0, GX_ALWAYS, 1); - MTXOrtho(mProjection, 224.0f, -224.0f, -320.0f, 320.0f, 100.0f, 1000.0f); - GXSetProjection(mProjection, GX_ORTHOGRAPHIC); -} - -void G2DSetViewport(u16 nLeft, u16 nTop, u16 nWidth, u16 nHeight) { - glob.nViewportTlcX = nLeft; - glob.nViewportTlcY = nTop; - glob.nViewportWidth = nWidth; - glob.nViewportHeight = nHeight; - GXSetScissor(nLeft, nTop, nWidth, nHeight); -} diff --git a/src/dolphin/ai/src/ai.c b/src/dolphin/ai/src/ai.c deleted file mode 100644 index c9c38ee..0000000 --- a/src/dolphin/ai/src/ai.c +++ /dev/null @@ -1,411 +0,0 @@ -#include -#include -#include -#include - -#include "__gx.h" - -#ifdef DEBUG -const char* __AIVersion = "<< Dolphin SDK - AI\tdebug build: Apr 5 2004 03:56:18 (0x2301) >>"; -#else -const char* __AIVersion = "<< Dolphin SDK - AI\trelease build: Apr 5 2004 04:15:02 (0x2301) >>"; -#endif - -static AISCallback __AIS_Callback; -static AIDCallback __AID_Callback; -static u8* __CallbackStack; -static u8* __OldStack; -static BOOL __AI_init_flag; -static BOOL __AID_Active; -static OSTime bound_32KHz; -static OSTime bound_48KHz; -static OSTime min_wait; -static OSTime max_wait; -static OSTime buffer; - -typedef struct { - OSTime t_start; - OSTime t1; - OSTime t2; - OSTime t3; - OSTime t4; - OSTime t_end; -} STRUCT_TIMELOG; -STRUCT_TIMELOG profile; - -OSTime __ai_src_time_start; -OSTime __ai_src_time_end; - -// prototypes -void __AI_DEBUG_set_stream_sample_rate(u32 rate); -STRUCT_TIMELOG* __ai_src_get_time(void); - -static void __AI_set_stream_sample_rate(u32 rate); -static void __AIDHandler(__OSInterrupt interrupt, OSContext* context); -static void __AISHandler(__OSInterrupt interrupt, OSContext* context); -static void __AICallbackStackSwitch(void* cb); -static void __AI_SRC_INIT(void); - -AIDCallback AIRegisterDMACallback(AIDCallback callback) { - AIDCallback old_callback; - BOOL old; - - old_callback = __AID_Callback; - old = OSDisableInterrupts(); - __AID_Callback = callback; - OSRestoreInterrupts(old); - return old_callback; -} - -void AIInitDMA(u32 start_addr, u32 length) { - BOOL old; - - old = OSDisableInterrupts(); - __DSPRegs[24] = (__DSPRegs[24] & 0xFFFFFC00) | (start_addr >> 16); - __DSPRegs[25] = (__DSPRegs[25] & 0xFFFF001F) | (start_addr & 0xFFFF); - ASSERTMSGLINE(316, (length & 0x1F) == 0, "AIStartDMA: length must be multiple of 32 bytes"); - __DSPRegs[27] = (__DSPRegs[27] & 0xFFFF8000) | ((length >> 5) & 0xFFFF); - OSRestoreInterrupts(old); -} - -BOOL AIGetDMAEnableFlag(void) { - return (__DSPRegs[27] & (1 << 15)) >> 15; -} - -void AIStartDMA(void) { - __DSPRegs[27] = __DSPRegs[27] | 0x8000; -} - -void AIStopDMA(void) { - __DSPRegs[27] = __DSPRegs[27] & ~0x8000; -} - -u32 AIGetDMABytesLeft(void) { - return (__DSPRegs[29] & 0x7FFF) << 5; -} - -u32 AIGetDMAStartAddr(void) { - return ((__DSPRegs[24] << 16) & 0x03FF0000) | (__DSPRegs[25] & 0xFFE0); -} - -u32 AIGetDMALength(void) { - return (__DSPRegs[27] & 0x7FFF) << 5; -} - -BOOL AICheckInit(void) { - return __AI_init_flag; -} - -AISCallback AIRegisterStreamCallback(AISCallback callback) { - AISCallback old_callback; - BOOL old; - - old_callback = __AIS_Callback; - old = OSDisableInterrupts(); - __AIS_Callback = callback; - OSRestoreInterrupts(old); - return old_callback; -} - -u32 AIGetStreamSampleCount(void) { - return __AIRegs[2]; -} - -void AIResetStreamSampleCount(void) { - __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; -} - -void AISetStreamTrigger(u32 trigger) { - __AIRegs[3] = trigger; -} - -u32 AIGetStreamTrigger(void) { - return __AIRegs[3]; -} - -void AISetStreamPlayState(u32 state) { - BOOL old; - u8 vol_left; - u8 vol_right; - - if (state != AIGetStreamPlayState()) { - if (AIGetStreamSampleRate() == 0 && state == AI_STREAM_START) { - vol_left = AIGetStreamVolRight(); - vol_right = AIGetStreamVolLeft(); - AISetStreamVolRight(0); - AISetStreamVolLeft(0); - old = OSDisableInterrupts(); - __AI_SRC_INIT(); - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); - OSRestoreInterrupts(old); - AISetStreamVolLeft(vol_left); - AISetStreamVolRight(vol_right); - return; - } - OLD_SET_REG_FIELD(653, __AIRegs[0], 1, 0, state); - } -} - -u32 AIGetStreamPlayState(void) { - return __AIRegs[0] & 1; -} - -void AISetDSPSampleRate(u32 rate) { - BOOL old; - u32 play_state; - u32 afr_state; - u8 vol_left; - u8 vol_right; - - if (rate != AIGetDSPSampleRate()) { - __AIRegs[0] = (__AIRegs[0] & 0xFFFFFFBF); - if (rate == AI_SAMPLERATE_32KHZ) { - vol_left = AIGetStreamVolLeft(); - vol_right = AIGetStreamVolRight(); - play_state = AIGetStreamPlayState(); - afr_state = AIGetStreamSampleRate(); - AISetStreamVolLeft(0U); - AISetStreamVolRight(0U); - old = OSDisableInterrupts(); - __AI_SRC_INIT(); - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); - OLD_SET_REG_FIELD(743, __AIRegs[0], 1, 1, afr_state); - OLD_SET_REG_FIELD(744, __AIRegs[0], 1, 0, play_state); - __AIRegs[0] |= 0x40; - OSRestoreInterrupts(old); - AISetStreamVolLeft(vol_left); - AISetStreamVolRight(vol_right); - } - } -} - -u32 AIGetDSPSampleRate(void) { - return GET_REG_FIELD(__AIRegs[0], 1, 6) ^ 1; -} - -void AISetStreamSampleRate(u32 rate) { - if (rate == AI_SAMPLERATE_48KHZ) { - __AI_set_stream_sample_rate(rate); - return; - } -#if DEBUG - OSReport("AISetStreamSampleRate(): OBSOLETED. Only 48KHz streaming from disk is supported!\n"); -#endif -} - -void __AI_DEBUG_set_stream_sample_rate(u32 rate) { - __AI_set_stream_sample_rate(rate); -} - -static void __AI_set_stream_sample_rate(u32 rate) { - BOOL old; - u32 play_state; - u8 vol_left; - u8 vol_right; - u32 dsp_src_state; - - if (rate != AIGetStreamSampleRate()) { - play_state = AIGetStreamPlayState(); - vol_left = AIGetStreamVolLeft(); - vol_right = AIGetStreamVolRight(); - AISetStreamVolRight(0); - AISetStreamVolLeft(0); - dsp_src_state = __AIRegs[0] & 0x40; - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 6, 0); - old = OSDisableInterrupts(); - __AI_SRC_INIT(); - __AIRegs[0] |= dsp_src_state; - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); - OLD_SET_REG_FIELD(887, __AIRegs[0], 1, 1, rate); - OSRestoreInterrupts(old); - AISetStreamPlayState(play_state); - AISetStreamVolLeft(vol_left); - AISetStreamVolRight(vol_right); - } -} - -u32 AIGetStreamSampleRate(void) { - return GET_REG_FIELD(__AIRegs[0], 1, 1); -} - -void AISetStreamVolLeft(u8 vol) { - OLD_SET_REG_FIELD(945, __AIRegs[1], 8, 0, vol); -} - -u8 AIGetStreamVolLeft(void) { - return GET_REG_FIELD(__AIRegs[1], 8, 0); -} - -void AISetStreamVolRight(u8 vol) { - OLD_SET_REG_FIELD(986, __AIRegs[1], 8, 8, vol); -} - -u8 AIGetStreamVolRight(void) -{ - return (__AIRegs[1] & (0xFF << 8)) >> 8; -} - -void AIInit(u8* stack) { - if (__AI_init_flag != TRUE) { - OSRegisterVersion(__AIVersion); - - bound_32KHz = OSNanosecondsToTicks(31524); - bound_48KHz = OSNanosecondsToTicks(42024); - min_wait = OSNanosecondsToTicks(42000); - max_wait = OSNanosecondsToTicks(63000); - buffer = OSNanosecondsToTicks(3000); - AISetStreamVolRight(0); - AISetStreamVolLeft(0); - AISetStreamTrigger(0); - AIResetStreamSampleCount(); - __AI_set_stream_sample_rate(AI_SAMPLERATE_48KHZ); - AISetDSPSampleRate(AI_SAMPLERATE_32KHZ); -#if DEBUG - OSReport("AIInit(): DSP is 32KHz\n"); -#endif - __AIS_Callback = NULL; - __AID_Callback = NULL; - __CallbackStack = stack; - if (stack) { - ASSERTMSGLINE(1107, ((u32)stack & 7) == 0, "AIInit: stack must be 8-byte aligned"); - } - __OSSetInterruptHandler(5, __AIDHandler); - __OSUnmaskInterrupts(0x04000000); - __OSSetInterruptHandler(8, __AISHandler); - __OSUnmaskInterrupts(0x800000); - __AI_init_flag = TRUE; - } -} - -void AIReset(void) { - __AI_init_flag = FALSE; -} - -static void __AISHandler(__OSInterrupt interrupt, OSContext* context) { - OSContext exceptionContext; - - __AIRegs[0] |= 8; - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - if (__AIS_Callback) { - __AIS_Callback(__AIRegs[2]); - } - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); -} - -static void __AIDHandler(__OSInterrupt interrupt, OSContext* context) { - OSContext exceptionContext; - u16 tmp; - - tmp = __DSPRegs[5]; - tmp = (tmp & ~0xA0) | 8; - __DSPRegs[5] = tmp; - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - if (__AID_Callback && !__AID_Active) { - __AID_Active = TRUE; - if (__CallbackStack) { - __AICallbackStackSwitch(__AID_Callback); - } else { - __AID_Callback(); - } - __AID_Active = FALSE; - } - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); -} - -static asm void __AICallbackStackSwitch(register void* cb) { - nofralloc - mflr r0 - stw r0, 0x4(r1) - stwu r1, -0x18(r1) - stw r31, 0x14(r1) - mr r31, r3 - lis r5, __OldStack@ha - addi r5, r5, __OldStack@l - stw r1, 0x0(r5) - lis r5, __CallbackStack@ha - addi r5, r5, __CallbackStack@l - lwz r1, 0x0(r5) - subi r1, r1, 0x8 - mtlr r31 - blrl - lis r5, __OldStack@ha - addi r5, r5, __OldStack@l - lwz r1, 0x0(r5) - lwz r0, 0x1c(r1) - lwz r31, 0x14(r1) - addi r1, r1, 0x18 - mtlr r0 - blr -} - -void __AI_SRC_INIT(void) { - OSTime rising_32khz = 0; - OSTime rising_48khz = 0; - OSTime diff = 0; - OSTime t1 = 0; - OSTime temp; - u32 temp0; - u32 temp1; - u32 done = 0; - u32 volume = 0; - u32 Init_Cnt = 0; - u32 walking = 0; - - walking = 0; - Init_Cnt = 0; - temp = 0; - -#if DEBUG - profile.t_start = OSGetTime(); -#endif - - while (!done) { - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 0); - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); - temp0 = __AIRegs[2]; - while (temp0 == __AIRegs[2]) { - } - rising_32khz = OSGetTime(); - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 1); - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); - temp1 = __AIRegs[2]; - while (temp1 == __AIRegs[2]) { - } - rising_48khz = OSGetTime(); - diff = rising_48khz - rising_32khz; - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 0); - OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_STOP); - if (diff < bound_32KHz - buffer) { - temp = min_wait; - done = 1; - 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()) { - } -#if DEBUG - profile.t_end = OSGetTime(); -#endif -} - -STRUCT_TIMELOG* __ai_src_get_time(void) { -#if DEBUG - return &profile; -#else - return NULL; -#endif -} diff --git a/src/dolphin/am/src/__am.h b/src/dolphin/am/src/__am.h deleted file mode 100644 index 7907a62..0000000 --- a/src/dolphin/am/src/__am.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _DOLPHIN_AM_INTERNAL_H_ -#define _DOLPHIN_AM_INTERNAL_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define AM_STACK_ENTRIES 16 - -typedef struct { - DVDFileInfo file_handle; - ARQRequest arq_handle; - AMCallback callback; - char* path; - void* buffer; - volatile u32 file_length; - volatile u32 curr_read_offset; - volatile u32 read_length; - volatile u32 aram_start_addr; - volatile u32 curr_aram_offset; - volatile int poll_flag; -} AMReadInfo; - -extern AMReadInfo __AMReadInfo[AM_STACK_ENTRIES]; - -static void __AM_dvd_callback(s32 result, DVDFileInfo* handle); -static void __AM_arq_callback(u32 task); -static void __AM_arq_poll_callback(u32 task); -u32 __AMPushBuffered(char* path, void* buffer, u32 buffer_size, AMCallback callback, int async_flag); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/dolphin/am/src/am.c b/src/dolphin/am/src/am.c deleted file mode 100644 index 56350a9..0000000 --- a/src/dolphin/am/src/am.c +++ /dev/null @@ -1,322 +0,0 @@ -#include -#include - -#include "__am.h" - -static u32 __AMStackPointer[AM_STACK_ENTRIES]; -static AMReadInfo __AMReadInfo[AM_STACK_ENTRIES]; - -static u32 __AMStackLocation; -static u32 __AMFreeBytes; -static u32 __AMPendingReads; - -static void __AM_dvd_callback(s32 result, DVDFileInfo* handle) { - u32 i; - AMReadInfo* ptr; - - for (i = 0; i < AM_STACK_ENTRIES; i++) { - if (handle == &(__AMReadInfo[i].file_handle)) { - ptr = &__AMReadInfo[i]; - break; - } - } - - ASSERTLINE(136, i != AM_STACK_ENTRIES); - - if (DVDGetCommandBlockStatus(&ptr->file_handle.cb) == 0) { - ARQPostRequest(&ptr->arq_handle, i, 0, 1, (u32)ptr->buffer, ptr->curr_aram_offset, result, __AM_arq_callback); - ptr->curr_aram_offset += result; - ptr->curr_read_offset += result; - } -} - -static void __AM_arq_callback(u32 task) { - u32 i; - AMReadInfo* ptr; - u32 remainder; - u32 read_request_length; - - for (i = 0; i < AM_STACK_ENTRIES; i++) { - if ((ARQRequest*)task == &__AMReadInfo[i].arq_handle) { - ptr = &__AMReadInfo[i]; - break; - } - } - - ASSERTLINE(198, i != AM_STACK_ENTRIES); - - if (ptr->curr_read_offset < ptr->file_length) { - remainder = ptr->file_length - ptr->curr_read_offset; - read_request_length = OSRoundUp32B(ptr->read_length > remainder ? remainder : ptr->read_length); - DVDReadAsync(&ptr->file_handle, ptr->buffer, read_request_length, ptr->curr_read_offset, __AM_dvd_callback); - } else { - ASSERTMSGLINE(220, __AMPendingReads, "AMPushBuffered(): Dangling read-complete event!\n"); - __AMPendingReads--; - - if (ptr->callback) { - (*ptr->callback)(ptr->path); - } - } -} - -static void __AM_arq_poll_callback(u32 task) { - u32 i; - AMReadInfo* ptr; - - for (i = 0; i < AM_STACK_ENTRIES; i++) { - if ((ARQRequest*)task == &__AMReadInfo[i].arq_handle) { - ptr = &__AMReadInfo[i]; - break; - } - } - - ASSERTLINE(262, i != AM_STACK_ENTRIES); - - ptr->poll_flag = 1; -} - -void* AMLoadFile(char* path, u32* length) { - DVDFileInfo dvdFileInfo; - u32 roundLength; - s32 readLength; - void* buffer; - int old; - - if (!DVDOpen(path, &dvdFileInfo)) { - char ch[1024]; - sprintf(ch, "Cannot open %s", path); - ASSERTMSGLINE(290, 0, ch); - } - - ASSERTMSGLINE(294, dvdFileInfo.length, "File length is 0\n"); - - roundLength = OSRoundUp32B(dvdFileInfo.length); - - old = OSDisableInterrupts(); - buffer = OSAlloc(roundLength); - OSRestoreInterrupts(old); - - ASSERTMSGLINE(303, buffer, "Unable to allocate buffer\n"); - readLength = DVDReadPrio(&dvdFileInfo, buffer, roundLength, 0, 2); - ASSERTMSGLINE(307, readLength > 0, "Read length <= 0\n"); - if (length != 0) { - *length = roundLength; - } - - return buffer; -} - -u32 AMPush(char* path) { - DVDFileInfo handle; - void* buffer; - u32 buffer_length; - u32 ret_val; - BOOL old; - - if (!DVDOpen(path, &handle)) { - OSReport("AMPushBuffered(): Unable to open file '%s'\n", path); - OSPanic(__FILE__, 343, "AM: FATAL ERROR\n"); - } - - buffer_length = OSRoundUp32B(handle.length); - if (buffer_length) { - old = OSDisableInterrupts(); - buffer = OSAlloc(buffer_length); - OSRestoreInterrupts(old); - - ASSERTMSGLINE(356, buffer, "AMPush(): Memory allocation failure.\n"); - - ret_val = __AMPushBuffered(path, buffer, buffer_length, NULL, FALSE); - OSFree(buffer); - return ret_val; - } else { -#ifdef DEBUG - OSReport("AMPush(): WARNING: File has zero length.\n"); -#endif - return 0; - } -} - -u32 AMPushData(void* buffer, u32 length) { - BOOL old; - u32 round_length; - AMReadInfo* ptr; - - ASSERTMSGLINE(401, ((u32)buffer & 0x1F) == 0, "AMPushData(): buffer is not 32-byte aligned!\n"); - ASSERTLINE(404, length); - - round_length = OSRoundUp32B(length); - if (__AMFreeBytes >= round_length && __AMStackLocation < AM_STACK_ENTRIES - 1) { - ptr = &__AMReadInfo[__AMStackLocation]; - - old = OSDisableInterrupts(); - - ptr->aram_start_addr = __AMStackPointer[__AMStackLocation]; - __AMStackLocation++; - __AMStackPointer[__AMStackLocation] = ptr->aram_start_addr + round_length; - __AMFreeBytes -= round_length; - - ptr->poll_flag = 0; - - ARQPostRequest(&ptr->arq_handle, __AMStackLocation - 1, 0, 1, (u32)buffer, ptr->aram_start_addr, round_length, &__AM_arq_poll_callback); - - OSRestoreInterrupts(old); - - do {} while (!ptr->poll_flag); - - return ptr->aram_start_addr; - } - - return 0; -} - -u32 __AMPushBuffered(char* path, void* buffer, u32 buffer_size, AMCallback callback, int async_flag) { - BOOL old; - u32 round_file_length; - u32 stack_index; - AMReadInfo* ptr; - u32 remainder; - u32 read_request_length; - s32 actual_read_length; - - ASSERTMSGLINE(477, ((u32)buffer & 0x1F) == 0, "AMPushBuffered(): buffer is not 32-byte aligned!\n"); - ASSERTMSGLINE(480, buffer_size > 31, "AMPushBuffered(): buffer_size is less than 32 bytes!\n"); - - if (__AMStackLocation < AM_STACK_ENTRIES - 1) { - ptr = &__AMReadInfo[__AMStackLocation]; - stack_index = __AMStackLocation; - - if (!DVDOpen(path, &ptr->file_handle)) { - OSReport("AMPushBuffered(): Unable to open file '%s'\n", path); - OSPanic(__FILE__, 494, "AM: FATAL ERROR\n"); - } - - ptr->file_length = ptr->file_handle.length; - round_file_length = OSRoundUp32B(ptr->file_length); - - if (__AMFreeBytes >= round_file_length) { - ptr->aram_start_addr = __AMStackPointer[__AMStackLocation]; - - old = OSDisableInterrupts(); - - __AMStackLocation++; - __AMStackPointer[__AMStackLocation] = ptr->aram_start_addr + round_file_length; - __AMFreeBytes -= round_file_length; - - ptr->curr_read_offset = 0; - ptr->curr_aram_offset = ptr->aram_start_addr; - ptr->read_length = buffer_size & ~0x1F; - ptr->callback = callback; - ptr->path = path; - ptr->buffer = buffer; - - OSRestoreInterrupts(old); - - if (async_flag == 1) { - DVDReadAsync(&ptr->file_handle, ptr->buffer, ptr->read_length, 0, __AM_dvd_callback); - __AMPendingReads++; - } else { - while (ptr->curr_read_offset < ptr->file_length) { - remainder = ptr->file_length - ptr->curr_read_offset; - read_request_length = OSRoundUp32B(ptr->read_length > remainder ? remainder : ptr->read_length); - actual_read_length = DVDReadPrio(&ptr->file_handle, ptr->buffer, read_request_length, ptr->curr_read_offset, 2); - - ASSERTMSGLINE(558, actual_read_length > 0, "AMPushBuffered(): Fatal Error - synchronuous DVD read\n"); - - ptr->curr_read_offset += actual_read_length; - ptr->poll_flag = FALSE; - - ARQPostRequest(&(ptr->arq_handle), stack_index, 0, 1, (u32)ptr->buffer, ptr->curr_aram_offset, actual_read_length, __AM_arq_poll_callback); - - ptr->curr_aram_offset += (u32)(actual_read_length); - - do {} while (!ptr->poll_flag); - } - } - } else { -#ifdef DEBUG - OSReport("AMPushBuffered(): WARNING: Not enough space in ARAM.\n"); -#endif - return 0; - } - } else { -#ifdef DEBUG - OSReport("AMPushBuffered(): WARNING: Stack table is full.\n"); -#endif - return 0; - } - - return ptr->aram_start_addr; -} - -void AMPop(void) { - BOOL old; - old = OSDisableInterrupts(); - - if (__AMPendingReads == 0) { - if (__AMStackLocation > 1) { - __AMFreeBytes += __AMStackPointer[__AMStackLocation] - __AMStackPointer[__AMStackLocation - 1]; - __AMStackLocation--; - } - } - - OSRestoreInterrupts(old); -} - -u32 AMGetZeroBuffer(void) { - return __AMStackPointer[0]; -} - -u32 AMGetReadStatus(void) { - BOOL old; - u32 tmp; - - old = OSDisableInterrupts(); - tmp = __AMPendingReads; - - OSRestoreInterrupts(old); - return tmp; -} - -u32 AMGetFreeSize(void) { - BOOL old; - u32 tmp; - - old = OSDisableInterrupts(); - tmp = __AMFreeBytes; - - OSRestoreInterrupts(old); - return tmp; -} - -u32 AMGetStackPointer(void) { - BOOL old; - u32 tmp; - - old = OSDisableInterrupts(); - tmp = __AMStackPointer[__AMStackLocation]; - - OSRestoreInterrupts(old); - return tmp; -} - -void AMInit(u32 aramBase, u32 aramBytes) { - u32 i; - u8 __AMZeroBuffer[256 + 31]; - u8* ptr; - - ASSERTLINE(760, aramBytes); - - ptr = (u8*)OSRoundUp32B(__AMZeroBuffer); - - __AMStackLocation = 0; - __AMStackPointer[0] = aramBase; - __AMFreeBytes = aramBytes; - __AMPendingReads = 0; - - for (i = 0; i < 256; i++) { - ptr[i] = 0; - } - - AMPushData(ptr, 256); -} diff --git a/src/dolphin/amcnotstub/src/amcnotstub.c b/src/dolphin/amcnotstub/src/amcnotstub.c deleted file mode 100644 index f1a59e7..0000000 --- a/src/dolphin/amcnotstub/src/amcnotstub.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -// this file is a stub. -__declspec(weak) int AMC_IsStub(void); - -__declspec(weak) int AMC_IsStub(void) { - return 0; -} diff --git a/src/dolphin/amcstubs/src/AmcExi2Stubs.c b/src/dolphin/amcstubs/src/AmcExi2Stubs.c deleted file mode 100644 index 99073a3..0000000 --- a/src/dolphin/amcstubs/src/AmcExi2Stubs.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -// prototypes -int AMC_IsStub(void); - -void EXI2_Init(volatile unsigned char **inputPendingPtrRef, EXICallback monitorCallback) {} - -void EXI2_EnableInterrupts(void) {} - -int EXI2_Poll(void) { - return 0; -} - -AmcExiError EXI2_ReadN(void *bytes, unsigned long length) { - return AMC_EXI_NO_ERROR; -} - -AmcExiError EXI2_WriteN(const void *bytes, unsigned long length) { - return AMC_EXI_NO_ERROR; -} - -void EXI2_Reserve(void) {} - -void EXI2_Unreserve(void) {} - -int AMC_IsStub(void) { - return 1; -} diff --git a/src/dolphin/ar/src/__ar.h b/src/dolphin/ar/src/__ar.h deleted file mode 100644 index 8cab34c..0000000 --- a/src/dolphin/ar/src/__ar.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _DOLPHIN_AR_INTERNAL_H_ -#define _DOLPHIN_AR_INTERNAL_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void __ARClearInterrupt(void); -u16 __ARGetInterruptStatus(void); - -void __ARQPopTaskQueueHi(void); -void __ARQServiceQueueLo(void); -void __ARQCallbackHack(u32 pointerToARQRequest); -void __ARQInterruptServiceRoutine(void); -void __ARQInitTempQueue(void); -void __ARQPushTempQueue(ARQRequest* task); - -#ifdef __cplusplus -} -#endif - -#endif // _DOLPHIN_AR_INTERNAL_H_ diff --git a/src/dolphin/ar/src/ar.c b/src/dolphin/ar/src/ar.c deleted file mode 100644 index d431eeb..0000000 --- a/src/dolphin/ar/src/ar.c +++ /dev/null @@ -1,446 +0,0 @@ -#include -#include -#include "fake_tgmath.h" - -#include "__ar.h" - -#ifdef DEBUG -const char* __ARVersion = "<< Dolphin SDK - AR\tdebug build: Apr 5 2004 03:56:19 (0x2301) >>"; -#else -const char* __ARVersion = "<< Dolphin SDK - AR\trelease build: Apr 5 2004 04:15:03 (0x2301) >>"; -#endif - -static void (*__AR_Callback)(); -static u32 __AR_Size; -static u32 __AR_InternalSize; -static u32 __AR_ExpansionSize; -static u32 __AR_StackPointer; -static u32 __AR_FreeBlocks; -static u32* __AR_BlockLength; -static BOOL __AR_init_flag; - -// prototypes -static void __ARHandler(__OSInterrupt exception, OSContext* context); -static void __ARWaitForDMA(void); -static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length); -static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length); -static void __ARChecksize(void); -static void __ARClearArea(u32 start_addr, u32 length); - -ARQCallback ARRegisterDMACallback(ARQCallback callback) { - ARQCallback old_callback; - BOOL old; - - old_callback = __AR_Callback; - old = OSDisableInterrupts(); - __AR_Callback = callback; - OSRestoreInterrupts(old); - return old_callback; -} - -u32 ARGetDMAStatus(void) { - BOOL old; - u32 val; - - old = OSDisableInterrupts(); - val = __DSPRegs[5] & 0x200; - OSRestoreInterrupts(old); - return val; -} - -void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) { - BOOL old; - - old = OSDisableInterrupts(); - ASSERTMSGLINE(376, !(__DSPRegs[5] & 0x200), "ARAM DMA already in progress\n"); - ASSERTMSGLINE(377, !(mainmem_addr & 0x1F), "AR: Main memory address is not a multiple of 32 bytes!\n"); - ASSERTMSGLINE(378, !(length & 0x1F), "AR: DMA transfer length is not a multiple of 32 bytes!\n"); - __DSPRegs[16] = (__DSPRegs[16] & 0xFFFFFC00 | (mainmem_addr >> 0x10)); - __DSPRegs[17] = (__DSPRegs[17] & 0xFFFF001F | ((u16)mainmem_addr)); - __DSPRegs[18] = (__DSPRegs[18] & 0xFFFFFC00 | (aram_addr >> 0x10)); - __DSPRegs[19] = (__DSPRegs[19] & 0xFFFF001F | ((u16)aram_addr)); - __DSPRegs[20] = __DSPRegs[20] & ~0x8000 | ((type << 0xF) & ~0x7FFF); - __DSPRegs[20] = (__DSPRegs[20] & 0xFFFFFC00) | (length >> 0x10); - __DSPRegs[21] = (__DSPRegs[21] & 0xFFFF001F) | (length & 0x0000FFFF); - OSRestoreInterrupts(old); -} - -u32 ARAlloc(u32 length) { - u32 tmp; - BOOL old; - - old = OSDisableInterrupts(); - ASSERTMSGLINE(430, !(length & 0x1F), "ARAlloc(): length is not multiple of 32bytes!"); - ASSERTMSGLINE(434, length <= (__AR_Size - __AR_StackPointer), "ARAlloc(): Out of ARAM!"); - ASSERTMSGLINE(435, __AR_FreeBlocks, "ARAlloc(): No more free blocks!"); - - tmp = __AR_StackPointer; - __AR_StackPointer += length; - *__AR_BlockLength = length; - __AR_BlockLength += 1; - __AR_FreeBlocks -= 1; - OSRestoreInterrupts(old); - return tmp; -} - -u32 ARFree(u32* length) { - BOOL old; - - old = OSDisableInterrupts(); - __AR_BlockLength -= 1; - if (length) { - *length = *__AR_BlockLength; - } - __AR_StackPointer -= *__AR_BlockLength; - __AR_FreeBlocks += 1; - OSRestoreInterrupts(old); - return __AR_StackPointer; -} - -BOOL ARCheckInit(void) { - return __AR_init_flag; -} - -u32 ARInit(u32* stack_index_addr, u32 num_entries) { - BOOL old; - u16 refresh; - - if (__AR_init_flag == TRUE) { - return 0x4000; - } - - OSRegisterVersion(__ARVersion); - - old = OSDisableInterrupts(); - __AR_Callback = NULL; - __OSSetInterruptHandler(6, __ARHandler); - __OSUnmaskInterrupts(0x02000000); - __AR_StackPointer = 0x4000; - __AR_FreeBlocks = num_entries; - __AR_BlockLength = stack_index_addr; - refresh = __DSPRegs[13] & 0xFF; - - ASSERTMSGLINE(590, (refresh <= 196.0f), "ARInit(): ILLEGAL SDRAM REFRESH VALUE\n"); - __DSPRegs[13] = (u16)((__DSPRegs[13] & ~0xFF) | (refresh & 0xFF)); - - __ARChecksize(); - __AR_init_flag = TRUE; - OSRestoreInterrupts(old); - return __AR_StackPointer; -} - -void ARReset(void) { - __AR_init_flag = FALSE; -} - -void ARSetSize(void) { -#ifdef DEBUG - OSReport("ARSetSize(): I don't do anything anymore!\n"); -#endif -} - -u32 ARGetBaseAddress(void) { - return 0x4000; -} - -u32 ARGetSize(void) { - return __AR_Size; -} - -u32 ARGetInternalSize(void) { - return __AR_InternalSize; -} - -void ARClear(u32 flag) { - switch (flag) { - case 0: - if (__AR_InternalSize != 0) { - __ARClearArea(0, __AR_InternalSize); - } - return; - case 1: - if (__AR_InternalSize != 0) { - __ARClearArea(0x4000, __AR_InternalSize - 0x4000); - } - break; - case 2: - if (__AR_InternalSize != 0 && __AR_ExpansionSize != 0) { - __ARClearArea(__AR_InternalSize, __AR_ExpansionSize); - } - break; - default: - ASSERTMSGLINE(774, 0, "ARClear(): Unknown flag.\n"); - break; - } -} - -static void __ARHandler(__OSInterrupt exception, OSContext* context) { - OSContext exceptionContext; - u16 tmp; - - tmp = __DSPRegs[5]; - tmp = (tmp & ~0x88) | 0x20; - __DSPRegs[5] = (tmp); - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - if (__AR_Callback) { - __AR_Callback(); - } - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); -} - -void __ARClearInterrupt(void) { - u16 tmp; - - tmp = __DSPRegs[5]; - tmp = (tmp & ~0x88) | 0x20; - __DSPRegs[5] = (tmp); -} - -u16 __ARGetInterruptStatus(void) { - return __DSPRegs[5] & 0x20; -} - -static void __ARWaitForDMA(void) { - while (__DSPRegs[5] & 0x200); -} - -static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) { - // Main mem address - __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16)); - __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); - - // ARAM address - __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16)); - __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff)); - - // DMA buffer size - __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x8000); - - __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16)); - __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff)); - - __ARWaitForDMA(); - __ARClearInterrupt(); -} - -static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) { - // Main mem address - __DSPRegs[DSP_ARAM_DMA_MM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_HI] & ~0x03ff) | (u16)(mmem_addr >> 16)); - __DSPRegs[DSP_ARAM_DMA_MM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_MM_LO] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); - - // ARAM address - __DSPRegs[DSP_ARAM_DMA_ARAM_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_HI] & ~0x03ff) | (u16)(aram_addr >> 16)); - __DSPRegs[DSP_ARAM_DMA_ARAM_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_ARAM_LO] & ~0xffe0) | (u16)(aram_addr & 0xffff)); - - // DMA buffer size - __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)(__DSPRegs[DSP_ARAM_DMA_SIZE_HI] | 0x8000); - - __DSPRegs[DSP_ARAM_DMA_SIZE_HI] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_HI] & ~0x03ff) | (u16)(length >> 16)); - __DSPRegs[DSP_ARAM_DMA_SIZE_LO] = (u16)((__DSPRegs[DSP_ARAM_DMA_SIZE_LO] & ~0xffe0) | (u16)(length & 0xffff)); - - __ARWaitForDMA(); - __ARClearInterrupt(); -} - -static void __ARChecksize(void) { - u8 test_data_pad[63]; - u8 dummy_data_pad[63]; - u8 buffer_pad[63]; - u8 save_pad_1[63]; - u8 save_pad_2[63]; - u8 save_pad_3[63]; - u8 save_pad_4[63]; - u8 save_pad_5[63]; - u32* test_data; - u32* dummy_data; - u32* buffer; - u32* save1; - u32* save2; - u32* save3; - u32* save4; - u32* save5; - u16 ARAM_mode = 0; - u32 ARAM_size = 0; - u32 i; - - do {} while(!(__DSPRegs[11] & 1)); - - ARAM_mode = 3; - ARAM_size = __AR_InternalSize = 0x1000000; - __DSPRegs[9] = ((__DSPRegs[9] & 0xFFFFFFC0) | 3) | 0x20; - - test_data = (u32*)(OSRoundUp32B((u32)(test_data_pad))); - dummy_data = (u32*)(OSRoundUp32B((u32)(dummy_data_pad))); - buffer = (u32*)(OSRoundUp32B((u32)(buffer_pad))); - - save1 = (u32*)(OSRoundUp32B((u32)(save_pad_1))); - save2 = (u32*)(OSRoundUp32B((u32)(save_pad_2))); - save3 = (u32*)(OSRoundUp32B((u32)(save_pad_3))); - save4 = (u32*)(OSRoundUp32B((u32)(save_pad_4))); - save5 = (u32*)(OSRoundUp32B((u32)(save_pad_5))); - - for (i = 0; i < 8; i++) { - *(test_data + i) = 0xDEADBEEF; - *(dummy_data + i) = 0xBAD0BAD0; - } - - DCFlushRange((void*)test_data, 0x20); - DCFlushRange((void*)dummy_data, 0x20); - - __AR_ExpansionSize = 0; - - DCInvalidateRange((void*)save1, 0x20); - __ARReadDMA((u32)save1, ARAM_size + 0, 0x20); - PPCSync(); - - __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); - - memset((void*)buffer, 0, 0x20); - DCFlushRange((void*)buffer, 0x20); - - __ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20); - PPCSync(); - - if (buffer[0] == test_data[0]) { - DCInvalidateRange((void*)save2, 0x20); - __ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20); - PPCSync(); - - DCInvalidateRange((void*)save3, 0x20); - __ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20); - PPCSync(); - - DCInvalidateRange((void*)save4, 0x20); - __ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20); - PPCSync(); - - DCInvalidateRange((void*)save5, 0x20); - __ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20); - PPCSync(); - - __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20); - __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); - - memset((void*)buffer, 0, 0x20); - DCFlushRange((void*)buffer, 0x20); - - __ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20); - PPCSync(); - - if (buffer[0] == test_data[0]) { - __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); - - ARAM_mode |= 0 << 1; - ARAM_size += 0x0200000; - __AR_ExpansionSize = 0x0200000; - } else { - __ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20); - __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); - - memset((void*)buffer, 0, 0x20); - DCFlushRange((void*)buffer, 0x20); - - __ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20); - PPCSync(); - - if (buffer[0] == test_data[0]) { - __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); - __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); - - ARAM_mode |= 4 << 1; - ARAM_size += 0x0400000; - __AR_ExpansionSize = 0x0400000; - } else { - __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20); - __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); - - memset((void*)buffer, 0, 0x20); - DCFlushRange((void*)buffer, 0x20); - - __ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20); - PPCSync(); - - if (buffer[0] == test_data[0]) { - __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); - __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); - __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); - - ARAM_mode |= 8 << 1; - ARAM_size += 0x0800000; - __AR_ExpansionSize = 0x0800000; - } else { - __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20); - - __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); - - memset((void*)buffer, 0, 0x20); - DCFlushRange((void*)buffer, 0x20); - - __ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20); - PPCSync(); - - if (buffer[0] == test_data[0]) { - __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); - __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); - __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); - __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); - - ARAM_mode |= 12 << 1; - ARAM_size += 0x1000000; - __AR_ExpansionSize = 0x1000000; - } else { - __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); - __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); - __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); - __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); - __ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20); - - ARAM_mode |= 16 << 1; - ARAM_size += 0x2000000; - __AR_ExpansionSize = 0x2000000; - } - } - } - } - -#ifdef DEBUG - OSReport("__ARChecksize(): ARAM Expansion present.\n"); -#endif - __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x07 | 0x38)) | ARAM_mode); - } - - *(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size; - __AR_Size = ARAM_size; -} - -static void __ARClearArea(u32 start_addr, u32 length) { - u8 zero_buffer[2079]; - u8* ptr; - u32 curr_addr; - u32 curr_len; - u32 end_addr; - u32 remainder; - - ASSERTMSGLINE(0x529, !(start_addr & 0x1F), "__ARClearArea(): Destination address not 32-byte aligned.\n"); - ASSERTMSGLINE(0x52A, !(length & 0x1F), "__ARClearArea(): Length not multiple of 32 bytes.\n"); - - ptr = (u8*)(OSRoundUp32B((u32)(zero_buffer))); - - do {} while(!(__DSPRegs[11] & 1)); - - memset(ptr, 0, 0x800); - DCFlushRange(ptr, 0x800); - - curr_addr = start_addr; - end_addr = start_addr + length; - - while (curr_addr < end_addr) { - remainder = end_addr - curr_addr; - - curr_len = OSRoundUp32B(remainder < 0x800 ? remainder : 0x800); - __ARWriteDMA((u32)ptr, curr_addr, curr_len); - curr_addr += curr_len; - } -} diff --git a/src/dolphin/ar/src/arq.c b/src/dolphin/ar/src/arq.c deleted file mode 100644 index 1adf24b..0000000 --- a/src/dolphin/ar/src/arq.c +++ /dev/null @@ -1,253 +0,0 @@ -#include -#include - -#include "__ar.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 5 2004 04:15:04 (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 __ARQPopTaskQueueHi(void) { - 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; - } -} - -void __ARQServiceQueueLo(void) { - if (__ARQRequestPendingLo == 0 && __ARQRequestQueueLo) { - __ARQRequestPendingLo = __ARQRequestQueueLo; - __ARQRequestQueueLo = __ARQRequestQueueLo->next; - } - - if (__ARQRequestPendingLo) { - if (__ARQRequestPendingLo->length <= __ARQChunkSize) { - if (__ARQRequestPendingLo->type == 0) { - ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->length); - } else { - ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQRequestPendingLo->length); - } - __ARQCallbackLo = __ARQRequestPendingLo->callback; - } else if (__ARQRequestPendingLo->type == 0) { - ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQChunkSize); - } else { - ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQChunkSize); - } - - __ARQRequestPendingLo->length -= __ARQChunkSize; - __ARQRequestPendingLo->source += __ARQChunkSize; - __ARQRequestPendingLo->dest += __ARQChunkSize; - } -} - -void __ARQCallbackHack(u32 unused) {} - -void __ARQInterruptServiceRoutine() { - if (__ARQCallbackHi) { - __ARQCallbackHi((u32)__ARQRequestPendingHi); - __ARQRequestPendingHi = NULL; - __ARQCallbackHi = NULL; - } else if (__ARQCallbackLo) { - __ARQCallbackLo((u32)__ARQRequestPendingLo); - __ARQRequestPendingLo = NULL; - __ARQCallbackLo = NULL; - } - - __ARQPopTaskQueueHi(); - - if (__ARQRequestPendingHi == 0) { - __ARQServiceQueueLo(); - } -} - -void __ARQInitTempQueue(void) { - __ARQRequestQueueTemp = NULL; - __ARQRequestTailTemp = NULL; -} - -void __ARQPushTempQueue(ARQRequest* task) { - if (!__ARQRequestQueueTemp) { - __ARQRequestQueueTemp = task; - __ARQRequestTailTemp = task; - } else { - __ARQRequestTailTemp->next = task; - __ARQRequestTailTemp = task; - } -} - -void ARQInit(void) { - if (__ARQ_init_flag != TRUE) { - OSRegisterVersion(__ARQVersion); - - __ARQRequestQueueHi = __ARQRequestQueueLo = NULL; - __ARQChunkSize = 0x1000; - ARRegisterDMACallback(__ARQInterruptServiceRoutine); - __ARQRequestPendingHi = NULL; - __ARQRequestPendingLo = NULL; - __ARQCallbackHi = NULL; - __ARQCallbackLo = NULL; - __ARQ_init_flag = TRUE; - } -} - -void ARQReset(void) { - __ARQ_init_flag = FALSE; -} - -void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest, u32 length, ARQCallback callback) { - BOOL level; - - ASSERTLINE(437, request); - ASSERTLINE(438, (type == ARQ_TYPE_MRAM_TO_ARAM) || (type == ARQ_TYPE_ARAM_TO_MRAM)); - ASSERTLINE(439, (priority == ARQ_PRIORITY_LOW) || (priority == ARQ_PRIORITY_HIGH)); - ASSERTLINE(442, (length % ARQ_DMA_ALIGNMENT) == 0); - - request->next = NULL; - request->owner = owner; - request->type = type; - request->source = source; - request->dest = dest; - request->length = length; - if (callback) { - request->callback = callback; - } else { - request->callback = __ARQCallbackHack; - } - - level = OSDisableInterrupts(); - switch(priority) { - case ARQ_PRIORITY_LOW: - if (__ARQRequestQueueLo) { - __ARQRequestTailLo->next = request; - } else { - __ARQRequestQueueLo = request; - } - __ARQRequestTailLo = request; - break; - case ARQ_PRIORITY_HIGH: - if (__ARQRequestQueueHi) { - __ARQRequestTailHi->next = request; - } else { - __ARQRequestQueueHi = request; - } - __ARQRequestTailHi = request; - break; - } - - if ((__ARQRequestPendingHi == 0) && ( __ARQRequestPendingLo == 0)) { - __ARQPopTaskQueueHi(); - if ( __ARQRequestPendingHi == 0) { - __ARQServiceQueueLo(); - } - } - - OSRestoreInterrupts(level); -} - -void ARQRemoveRequest(ARQRequest* request) { - ARQRequest* thisRequest; - BOOL level; - - level = OSDisableInterrupts(); - __ARQInitTempQueue(); - - for (thisRequest = __ARQRequestQueueHi; thisRequest; thisRequest = thisRequest->next) { - if (thisRequest != request) { - __ARQPushTempQueue(thisRequest); - } - } - - __ARQRequestQueueHi = __ARQRequestQueueTemp; - __ARQRequestTailHi = __ARQRequestTailTemp; - __ARQInitTempQueue(); - - for (thisRequest = __ARQRequestQueueLo; thisRequest; thisRequest = thisRequest->next) { - if (thisRequest != request) { - __ARQPushTempQueue(thisRequest); - } - } - - __ARQRequestQueueLo = __ARQRequestQueueTemp; - __ARQRequestTailLo = __ARQRequestTailTemp; - OSRestoreInterrupts(level); -} - -void ARQRemoveOwnerRequest(u32 owner) { - ARQRequest* thisRequest; - BOOL level; - - level = OSDisableInterrupts(); - __ARQInitTempQueue(); - - for (thisRequest = __ARQRequestQueueHi; thisRequest; thisRequest = thisRequest->next) { - if (thisRequest->owner != owner) { - __ARQPushTempQueue(thisRequest); - } - } - - __ARQRequestQueueHi = __ARQRequestQueueTemp; - __ARQRequestTailHi = __ARQRequestTailTemp; - __ARQInitTempQueue(); - - for (thisRequest = __ARQRequestQueueLo; thisRequest; thisRequest = thisRequest->next) { - if (thisRequest->owner != owner) { - __ARQPushTempQueue(thisRequest); - } - } - - __ARQRequestQueueLo = __ARQRequestQueueTemp; - __ARQRequestTailLo = __ARQRequestTailTemp; - OSRestoreInterrupts(level); -} - -void ARQFlushQueue(void) { - BOOL level; - - level = OSDisableInterrupts(); - __ARQRequestQueueHi = NULL; - __ARQRequestTailHi = NULL; - __ARQRequestQueueLo = NULL; - __ARQRequestTailLo = NULL; - - OSRestoreInterrupts(level); -} - -void ARQSetChunkSize(u32 size) { - u32 i; - - i = size & 0x1F; - if (i) { - __ARQChunkSize = size + (0x20 - i); - return; - } - __ARQChunkSize = size; -} - -u32 ARQGetChunkSize(void) { - return __ARQChunkSize; -} - -BOOL ARQCheckInit(void) { - return __ARQ_init_flag; -} diff --git a/src/dolphin/ax/src/AXVPB.c b/src/dolphin/ax/src/AXVPB.c deleted file mode 100644 index 8c51a48..0000000 --- a/src/dolphin/ax/src/AXVPB.c +++ /dev/null @@ -1,1412 +0,0 @@ -#include -#include -#include - -#include "__ax.h" - -static u32 __AXSrcCycles[5] = { 0x00000DF8, 0x00000F78, 0x000014B8, 0x000019F8, 0x000019F8 }; - -static u32 __AXMainMixCycles[16] = { 0x00000000, 0x000002F8, 0x000002F8, 0x000005BE, - 0x000002F8, 0x000005F0, 0x000005F0, 0x000008B6, - 0x00000000, 0x000004F1, 0x000004F1, 0x000009A6, - 0x000004F1, 0x000009E2, 0x000009E2, 0x00000E97 }; - -static u32 __AXAuxMixCycles[32] = { - 0x00000000, 0x000002F8, 0x000002F8, 0x000005BE, 0x00000000, 0x000004F1, 0x000004F1, 0x000009A6, - 0x000002F8, 0x000005F0, 0x000005F0, 0x000008B6, 0x000002F8, 0x000007E9, 0x000007E9, 0x00000C9E, - 0x00000000, 0x000002F8, 0x000002F8, 0x000005BE, 0x00000000, 0x000004F1, 0x000004F1, 0x000009A6, - 0x000004F1, 0x000007E9, 0x000007E9, 0x00000AAF, 0x000004F1, 0x000009E2, 0x000009E2, 0x00000E97 -}; - -static AXPB __AXPB[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); -static AXPBITDBUFFER __AXITD[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); -static AXPBU __AXUpdates[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); -static AXVPB __AXVPB[AX_MAX_VOICES]; - -static u32 __AXMaxDspCycles; -static u32 __AXRecDspCycles; -static u32 __AXNumVoices; - -u32 __AXGetNumVoices(void) -{ - return __AXNumVoices; -} - -void __AXServiceVPB(AXVPB* pvpb) -{ - AXPB* ppbDsp; - AXPB* ppbUser; - u32 sync; - - ASSERTLINE(238, (pvpb->index >= 0) && (pvpb->index < AX_MAX_VOICES)); - - __AXNumVoices += 1; - ppbDsp = &__AXPB[pvpb->index]; - ppbUser = &pvpb->pb; - sync = pvpb->sync; - if (sync == 0) - { - ppbUser->state = ppbDsp->state; - ppbUser->ve.currentVolume = ppbDsp->ve.currentVolume; - ppbUser->addr.currentAddressHi = ppbDsp->addr.currentAddressHi; - ppbUser->addr.currentAddressLo = ppbDsp->addr.currentAddressLo; - return; - } - if (sync & AX_SYNC_FLAG_COPYALL) - { - // copy the whole PB struct. (size: 0xF4) - u32* src; - u32* dst; - src = (void*)ppbUser; - dst = (void*)ppbDsp; - - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - - if (pvpb->updateCounter != 0) - { - u32 count; - src = (void*)&__AXUpdates[pvpb->index]; - dst = (void*)pvpb->updateData; - for (count = pvpb->updateCounter; count; count--) - { - *(dst) = *(src); - dst += 1; - src += 1; - } - } - return; - } - - if (sync & AX_SYNC_FLAG_COPYSELECT) - { - ppbDsp->srcSelect = ppbUser->srcSelect; - ppbDsp->coefSelect = ppbUser->coefSelect; - } - - if (sync & AX_SYNC_FLAG_COPYMXRCTRL) - { - ppbDsp->mixerCtrl = ppbUser->mixerCtrl; - } - - if (sync & AX_SYNC_FLAG_COPYSTATE) - { - ppbDsp->state = ppbUser->state; - } - else - { - ppbUser->state = ppbDsp->state; - } - - if (sync & AX_SYNC_FLAG_COPYTYPE) - { - ppbDsp->type = ppbUser->type; - } - - if (sync & AX_SYNC_FLAG_COPYAXPBMIX) - { - // copy AXPBMIX. - u16* src; - u16* dst; - src = (void*)&ppbUser->mix; - dst = (void*)&ppbDsp->mix; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - } - - if (sync & AX_SYNC_FLAG_COPYTSHIFT) - { - ppbDsp->itd.targetShiftL = ppbUser->itd.targetShiftL; - ppbDsp->itd.targetShiftR = ppbUser->itd.targetShiftR; - } - else if (sync & AX_SYNC_FLAG_COPYITD) - { - // copy ITD struct. - u16* src; - u16* dst; - u32* dst_; - src = (void*)&ppbUser->itd; - dst = (void*)&ppbDsp->itd; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - src += 1; - - dst; // fixes reg alloc - dst_ = pvpb->itdBuffer; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - dst_ += 1; - *(dst_) = 0; - } - - if (sync & AX_SYNC_FLAG_COPYUPDATE) - { - // copy UPDATE struct. - u16* src; - u16* dst; - dst = (void*)&ppbDsp->update; - src = (void*)&ppbUser->update; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - - if (pvpb->updateCounter) - { - u32* src_; - u32* dst_; - u32 count; - - dst_ = (void*)&__AXUpdates[pvpb->index]; - src_ = (void*)&pvpb->updateData; - - for (count = pvpb->updateCounter; count; count--) - { - *(dst_) = *(src_); - dst_ += 1; - src_ += 1; - } - } - } - - if (sync & AX_SYNC_FLAG_COPYDPOP) - { - // copy DPOP struct. - u16* src; - u16* dst; - dst = (void*)&ppbDsp->dpop; - src = (void*)&ppbUser->dpop; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - } - - if (sync & AX_SYNC_FLAG_SWAPVOL) - { - ppbUser->ve.currentVolume = ppbDsp->ve.currentVolume; - ppbDsp->ve.currentDelta = ppbUser->ve.currentDelta; - } - else if (sync & AX_SYNC_FLAG_COPYVOL) - { - ppbDsp->ve.currentVolume = ppbUser->ve.currentVolume; - ppbDsp->ve.currentDelta = ppbUser->ve.currentDelta; - } - - if (sync & AX_SYNC_FLAG_COPYFIR) - { - // copy FIR struct. - u16* src; - u16* dst; - dst = (void*)&ppbDsp->fir; - src = (void*)&ppbUser->fir; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - } - - if (sync & (AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | - AX_SYNC_FLAG_COPYCURADDR)) - { - if (sync & AX_SYNC_FLAG_COPYLOOP) - { - ppbDsp->addr.loopFlag = ppbUser->addr.loopFlag; - } - if (sync & AX_SYNC_FLAG_COPYLOOPADDR) - { - *(u32*)&ppbDsp->addr.loopAddressHi = *(u32*)&ppbUser->addr.loopAddressHi; - } - if (sync & AX_SYNC_FLAG_COPYENDADDR) - { - *(u32*)&ppbDsp->addr.endAddressHi = *(u32*)&ppbUser->addr.endAddressHi; - } - if (sync & AX_SYNC_FLAG_COPYCURADDR) - { - *(u32*)&ppbDsp->addr.currentAddressHi = *(u32*)&ppbUser->addr.currentAddressHi; - } - else - { - *(u32*)&ppbUser->addr.currentAddressHi = *(u32*)&ppbDsp->addr.currentAddressHi; - } - } - else if (sync & AX_SYNC_FLAG_COPYADDR) - { - // copy ADDR struct. - u32* src; - u32* dst; - dst = (void*)&ppbDsp->addr; - src = (void*)&ppbUser->addr; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - } - else - { - ppbUser->addr.currentAddressHi = ppbDsp->addr.currentAddressHi; - ppbUser->addr.currentAddressLo = ppbDsp->addr.currentAddressLo; - } - - if (sync & AX_SYNC_FLAG_COPYADPCM) - { - // copy ADPCM struct. - u32* src; - u32* dst; - dst = (void*)&ppbDsp->adpcm; - src = (void*)&ppbUser->adpcm; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - } - - if (sync & AX_SYNC_FLAG_COPYRATIO) - { - ppbDsp->src.ratioHi = ppbUser->src.ratioHi; - ppbDsp->src.ratioLo = ppbUser->src.ratioLo; - } - else if (sync & AX_SYNC_FLAG_COPYSRC) - { - // copy SRC struct. - u16* src; - u16* dst; - dst = (void*)&ppbDsp->src; - src = (void*)&ppbUser->src; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - } - - if (sync & AX_SYNC_FLAG_COPYADPCMLOOP) - { - // copy ADPCMLOOP struct. - u16* src; - u16* dst; - dst = (void*)&ppbDsp->adpcmLoop; - src = (void*)&ppbUser->adpcmLoop; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - } - - if (sync & 0x400000) - { - ppbDsp->lpf.a0 = ppbUser->lpf.a0; - ppbDsp->lpf.b0 = ppbUser->lpf.b0; - return; - } - - if (sync & 0x200000) - { - // copy AXPBLPF struct - u16* src; - u16* dst; - - dst = (void*)&ppbDsp->lpf; - src = (void*)&ppbUser->lpf; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - } -} - -void __AXDumpVPB(AXVPB* pvpb) -{ - AXPB* ppbDsp; - - ppbDsp = &__AXPB[pvpb->index]; - if (ppbDsp->state == 1) - { - __AXDepopVoice(ppbDsp); - } - pvpb->pb.state = ppbDsp->state = ppbDsp->update.updNum[0] = ppbDsp->update.updNum[1] = - ppbDsp->update.updNum[2] = ppbDsp->update.updNum[3] = ppbDsp->update.updNum[4] = 0; - __AXPushCallbackStack(pvpb); -} - -void __AXSyncPBs(u32 lessDlpfycles) -{ - u32 cycles; - u32 i; - AXVPB* pvpb; - - __AXNumVoices = 0; - DCInvalidateRange(__AXPB, sizeof(__AXPB)); - DCInvalidateRange(__AXITD, sizeof(__AXITD)); - cycles = (__AXGetCommandListCycles() + 0x10000) - 0x55F0 + lessDlpfycles; - - for (i = 31; i; i--) - { - for (pvpb = __AXGetStackHead(i); pvpb; pvpb = pvpb->next) - { - if (pvpb->depop != 0) - { - __AXDepopVoice(&__AXPB[pvpb->index]); - } - - if ((pvpb->pb.state == 1) || (pvpb->updateCounter != 0)) - { - if (pvpb->pb.srcSelect != 2) - { - cycles += __AXSrcCycles[pvpb->pb.src.ratioHi]; - } - - if (pvpb->pb.lpf.on) - { - cycles += 555; - } - - cycles += __AXMainMixCycles[pvpb->pb.mixerCtrl & 0xF] + - __AXAuxMixCycles[(pvpb->pb.mixerCtrl >> 4) & 0x1F] + - __AXAuxMixCycles[(pvpb->pb.mixerCtrl >> 9) & 0x1F] + 0x8C; - if (__AXMaxDspCycles > cycles) - { - __AXServiceVPB(pvpb); - } - else - { - __AXDumpVPB(pvpb); - } - } - else - { - __AXServiceVPB(pvpb); - } - - pvpb->sync = 0; - pvpb->depop = 0; - pvpb->updateMS = pvpb->updateCounter = 0; - pvpb->updateWrite = pvpb->updateData; - } - } - - __AXRecDspCycles = cycles; - for (pvpb = __AXGetStackHead(0); pvpb; pvpb = pvpb->next) - { - if (pvpb->depop != 0) - { - __AXDepopVoice(&__AXPB[pvpb->index]); - } - pvpb->depop = 0; - __AXPB[pvpb->index].state = __AXPB[pvpb->index].update.updNum[0] = - __AXPB[pvpb->index].update.updNum[1] = __AXPB[pvpb->index].update.updNum[2] = - __AXPB[pvpb->index].update.updNum[3] = __AXPB[pvpb->index].update.updNum[4] = 0; - } - - DCFlushRange(__AXPB, sizeof(__AXPB)); - DCFlushRange(__AXITD, sizeof(__AXITD)); - DCFlushRange(__AXUpdates, sizeof(__AXUpdates)); -} - -AXPB* __AXGetPBs(void) -{ - return __AXPB; -} - -void __AXSetPBDefault(AXVPB* p) -{ - p->pb.state = 0; - p->pb.itd.flag = 0; - p->sync = 0x2000A4; - p->updateMS = p->updateCounter = 0; - p->updateWrite = p->updateData; - p->pb.update.updNum[0] = p->pb.update.updNum[1] = p->pb.update.updNum[2] = - p->pb.update.updNum[3] = p->pb.update.updNum[4] = 0; - p->pb.lpf.on = 0; -} - -void __AXVPBInit(void) -{ - u32 i; - AXPB* ppb; - AXPBITDBUFFER* ppbi; - AXPBU* ppbu; - AXVPB* pvpb; - u32* p; - -#ifdef DEBUG - OSReport("Initializing AXVPB code module\n"); -#endif - __AXMaxDspCycles = OS_BUS_CLOCK / 400; - __AXRecDspCycles = 0; - -#define BUFFER_MEMSET(buffer, size) \ - { \ - p = (u32*)&buffer; \ - for (i = size; i != 0; i--) \ - { \ - *p = 0; \ - p++; \ - } \ - } - - BUFFER_MEMSET(__AXPB, 0xF40); - BUFFER_MEMSET(__AXITD, 0x400); - BUFFER_MEMSET(__AXVPB, 0x22C0); - - for (i = 0; i < AX_MAX_VOICES; i++) - { - ppb = &__AXPB[i]; - ppbi = &__AXITD[i]; - ppbu = &__AXUpdates[i]; - pvpb = &__AXVPB[i]; - - ASSERTLINE(913, (u32)ppb ^ 0x1F); - ASSERTLINE(914, (u32)ppbi ^ 0x1F); - ASSERTLINE(915, (u32)ppbu ^ 0x1F); - - pvpb->index = i; - pvpb->updateWrite = pvpb->updateData; - pvpb->itdBuffer = ppbi; - __AXSetPBDefault(pvpb); - - if (i == 0x3F) - { - pvpb->pb.nextHi = pvpb->pb.nextLo = ppb->nextHi = ppb->nextLo = 0; - } - else - { - pvpb->pb.nextHi = (u16)((u32)((char*)ppb + sizeof(AXPB)) >> 16); - pvpb->pb.nextLo = (u16)((u32)((char*)ppb + sizeof(AXPB))); - ppb->nextHi = (u16)((u32)((char*)ppb + sizeof(AXPB)) >> 16); - ppb->nextLo = (u16)((u32)((char*)ppb + sizeof(AXPB))); - } - - pvpb->pb.currHi = (u16)(((u32)ppb) >> 16); - pvpb->pb.currLo = (u16)((u32)ppb); - ppb->currHi = (u16)(((u32)ppb) >> 16); - ppb->currLo = (u16)((u32)ppb); - pvpb->pb.itd.bufferHi = (u16)(((u32)ppbi) >> 16); - pvpb->pb.itd.bufferLo = (u16)((u32)ppbi); - ppb->itd.bufferHi = (u16)(((u32)ppbi) >> 16); - ppb->itd.bufferLo = (u16)((u32)ppbi); - pvpb->pb.update.dataHi = (u16)(((u32)ppbu) >> 16); - pvpb->pb.update.dataLo = (u16)((u32)ppbu); - ppb->update.dataHi = (u16)(((u32)ppbu) >> 16); - ppb->update.dataLo = (u16)((u32)ppbu); - - pvpb->priority = 1; - __AXPushFreeStack(pvpb); - } - - DCFlushRange(__AXPB, sizeof(__AXPB)); -} - -void __AXVPBQuit(void) -{ -#ifdef DEBUG - OSReport("Shutting down AXVPB code module\n"); -#endif -} - -void AXSetVoiceSrcType(AXVPB* p, u32 type) -{ - BOOL old; - AXPB* ppb; - - ASSERTLINE(1020, p); - ASSERTLINE(1021, type <= AX_SRC_TYPE_4TAP_16K); - - old = OSDisableInterrupts(); - ppb = &p->pb; - switch (type) - { - case AX_SRC_TYPE_NONE: - ppb->srcSelect = 2; - break; - case AX_SRC_TYPE_LINEAR: - ppb->srcSelect = 1; - break; - case AX_SRC_TYPE_4TAP_8K: - ppb->srcSelect = 0; - ppb->coefSelect = 0; - break; - case AX_SRC_TYPE_4TAP_12K: - ppb->srcSelect = 0; - ppb->coefSelect = 1; - break; - case AX_SRC_TYPE_4TAP_16K: - ppb->srcSelect = 0; - ppb->coefSelect = 2; - break; - } - - p->sync |= AX_SYNC_FLAG_COPYSELECT; - OSRestoreInterrupts(old); -} - -void AXSetVoiceState(AXVPB* p, u16 state) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.state = state; - p->sync |= AX_SYNC_FLAG_COPYSTATE; - if (state == 0) - { - p->depop = 1; - } - OSRestoreInterrupts(old); -} - -void AXSetVoiceType(AXVPB* p, u16 type) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.type = type; - p->sync |= AX_SYNC_FLAG_COPYTYPE; - OSRestoreInterrupts(old); -} - -void AXSetVoiceMix(AXVPB* p, AXPBMIX* mix) -{ - BOOL old; - u16 mixerCtrl; - u16* dst; - u16* src; - - src = (u16*)mix; - dst = (u16*)&p->pb.mix; - mixerCtrl = 0; - - old = OSDisableInterrupts(); - - if ((*dst++ = *src++)) - mixerCtrl |= 0x1; - if ((*dst++ = *src++)) - mixerCtrl |= 0x9; - if ((*dst++ = *src++)) - mixerCtrl |= 0x2; - if ((*dst++ = *src++)) - mixerCtrl |= 0xA; - if ((*dst++ = *src++)) - mixerCtrl |= 0x10; - if ((*dst++ = *src++)) - mixerCtrl |= 0x50; - if ((*dst++ = *src++)) - mixerCtrl |= 0x20; - if ((*dst++ = *src++)) - mixerCtrl |= 0x60; - if ((*dst++ = *src++)) - mixerCtrl |= 0x200; - if ((*dst++ = *src++)) - mixerCtrl |= 0xA00; - if ((*dst++ = *src++)) - mixerCtrl |= 0x400; - if ((*dst++ = *src++)) - mixerCtrl |= 0xC00; - if ((*dst++ = *src++)) - mixerCtrl |= 0x1000; - if ((*dst++ = *src++)) - mixerCtrl |= 0x3000; - if ((*dst++ = *src++)) - mixerCtrl |= 0x4; - if ((*dst++ = *src++)) - mixerCtrl |= 0xC; - if ((*dst++ = *src++)) - mixerCtrl |= 0x80; - if ((*dst++ = *src++)) - mixerCtrl |= 0x180; - - p->pb.mixerCtrl = mixerCtrl; - p->sync |= (AX_SYNC_FLAG_COPYAXPBMIX | AX_SYNC_FLAG_COPYMXRCTRL); - OSRestoreInterrupts(old); -} - -void AXSetVoiceItdOn(AXVPB* p) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.itd.flag = 1; - p->pb.itd.shiftL = p->pb.itd.shiftR = p->pb.itd.targetShiftL = p->pb.itd.targetShiftR = 0; - p->sync &= ~(AX_SYNC_FLAG_COPYTSHIFT); - p->sync |= AX_SYNC_FLAG_COPYITD; - OSRestoreInterrupts(old); -} - -void AXSetVoiceItdTarget(AXVPB* p, u16 lShift, u16 rShift) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.itd.targetShiftL = lShift; - p->pb.itd.targetShiftR = rShift; - p->sync |= AX_SYNC_FLAG_COPYTSHIFT; - OSRestoreInterrupts(old); -} - -void AXSetVoiceUpdateIncrement(AXVPB* p) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->updateMS++; - p->sync |= AX_SYNC_FLAG_COPYUPDATE; - ASSERTMSGLINE(1191, p->updateMS <= 4, "PB updates cannot exceed 5ms\n"); - OSRestoreInterrupts(old); -} - -void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->updateCounter += 2; - ASSERTMSGLINE(1205, p->updateCounter <= 128, "PB update block exceeded 128 words\n"); - - *(p->updateWrite) = param; - p->updateWrite += 1; - *(p->updateWrite) = data; - p->updateWrite += 1; - p->sync |= AX_SYNC_FLAG_COPYUPDATE; - OSRestoreInterrupts(old); -} - -void AXSetVoiceDpop(AXVPB* p, AXPBDPOP* dpop) -{ - BOOL old; - u16* dst; - u16* src; - - dst = (void*)&p->pb.dpop; - src = (void*)dpop; - - old = OSDisableInterrupts(); - { - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - } - p->sync |= AX_SYNC_FLAG_COPYDPOP; - OSRestoreInterrupts(old); -} - -void AXSetVoiceVe(AXVPB* p, AXPBVE* ve) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.ve.currentVolume = ve->currentVolume; - p->pb.ve.currentDelta = ve->currentDelta; - p->sync |= AX_SYNC_FLAG_COPYVOL; - OSRestoreInterrupts(old); -} - -void AXSetVoiceVeDelta(AXVPB* p, s16 delta) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.ve.currentDelta = delta; - p->sync |= AX_SYNC_FLAG_SWAPVOL; - OSRestoreInterrupts(old); -} - -void AXSetVoiceFir(AXVPB* p, AXPBFIR* fir) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.fir.numCoefs = fir->numCoefs; - p->pb.fir.coefsHi = fir->coefsHi; - p->pb.fir.coefsLo = fir->coefsLo; - p->sync |= AX_SYNC_FLAG_COPYFIR; - OSRestoreInterrupts(old); -} - -void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr) -{ - BOOL old; - u32* dst; - u32* src; - - dst = (void*)&p->pb.addr; - src = (void*)addr; - - old = OSDisableInterrupts(); - { - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - } - - switch (addr->format) - { - case 0: - ASSERTMSGLINE(1335, (addr->loopAddressLo & 0xF) > 1, - "*** loop address on ADPCM frame header! ***\n"); - ASSERTMSGLINE(1340, (addr->endAddressLo & 0xF) > 1, - "*** end address on ADPCM frame header! ***\n"); - ASSERTMSGLINE(1345, (addr->currentAddressLo & 0xF) > 1, - "*** current address on ADPCM frame header! ***\n"); - break; - case 10: - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0x08000000; - dst += 1; - *(dst) = 0; - dst += 1; - break; - case 25: - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0; - dst += 1; - *(dst) = 0x01000000; - dst += 1; - *(dst) = 0; - dst += 1; - break; - default: - ASSERTMSGLINE(1389, 0, "unknown addr->formaqt in PB\n"); - break; - } - - p->sync &= ~(AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | - AX_SYNC_FLAG_COPYCURADDR); - p->sync |= (AX_SYNC_FLAG_COPYADDR | AX_SYNC_FLAG_COPYADPCM); - OSRestoreInterrupts(old); -} - -void AXSetVoiceLoop(AXVPB* p, u16 loop) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.addr.loopFlag = loop; - p->sync |= AX_SYNC_FLAG_COPYLOOP; - OSRestoreInterrupts(old); -} - -void AXSetVoiceLoopAddr(AXVPB* p, u32 addr) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.addr.loopAddressHi = (addr >> 0x10); - p->pb.addr.loopAddressLo = (addr); - p->sync |= AX_SYNC_FLAG_COPYLOOPADDR; - OSRestoreInterrupts(old); -} - -void AXSetVoiceEndAddr(AXVPB* p, u32 addr) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.addr.endAddressHi = (addr >> 0x10); - p->pb.addr.endAddressLo = (addr); - p->sync |= AX_SYNC_FLAG_COPYENDADDR; - OSRestoreInterrupts(old); -} - -void AXSetVoiceCurrentAddr(AXVPB* p, u32 addr) -{ - BOOL old; - - old = OSDisableInterrupts(); - p->pb.addr.currentAddressHi = (addr >> 0x10); - p->pb.addr.currentAddressLo = (addr); - p->sync |= AX_SYNC_FLAG_COPYCURADDR; - OSRestoreInterrupts(old); -} - -void AXSetVoiceAdpcm(AXVPB* p, AXPBADPCM* adpcm) -{ - BOOL old; - u32* dst; - u32* src; - - dst = (void*)&p->pb.adpcm; - src = (void*)adpcm; - - old = OSDisableInterrupts(); - - { - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - } - p->sync |= AX_SYNC_FLAG_COPYADPCM; - OSRestoreInterrupts(old); -} - -void AXSetVoiceSrc(AXVPB* p, AXPBSRC* src_) -{ - BOOL old; - u16* dst; - u16* src; - - dst = (void*)&p->pb.src; - src = (void*)src_; - - old = OSDisableInterrupts(); - { - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - } - p->sync &= ~(AX_SYNC_FLAG_COPYRATIO); - p->sync |= AX_SYNC_FLAG_COPYSRC; - OSRestoreInterrupts(old); -} - -void AXSetVoiceSrcRatio(AXVPB* p, float ratio) -{ - u32 r; - BOOL old; - - old = OSDisableInterrupts(); - r = 65536.0f * ratio; - if (r > 0x40000) - { - r = 0x40000; - } - p->pb.src.ratioHi = ((u32)r >> 0x10); - p->pb.src.ratioLo = ((u32)r); - p->sync |= AX_SYNC_FLAG_COPYRATIO; - OSRestoreInterrupts(old); -} - -void AXSetVoiceAdpcmLoop(AXVPB* p, AXPBADPCMLOOP* adpcmloop) -{ - BOOL old; - u16* dst; - u16* src; - - dst = (void*)&p->pb.adpcmLoop; - src = (void*)adpcmloop; - old = OSDisableInterrupts(); - { - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - *(dst) = *(src); - dst += 1; - src += 1; - } - p->sync |= AX_SYNC_FLAG_COPYADPCMLOOP; - OSRestoreInterrupts(old); -} - -void AXSetVoiceLpf(AXVPB* p, AXPBLPF* lpf) -{ - BOOL old; - u16* dst; - u16* src; - - dst = (u16*)&p->pb.lpf; - src = (u16*)lpf; - - old = OSDisableInterrupts(); - - *dst = *src; - dst++; - src++; - *dst = *src; - dst++; - src++; - *dst = *src; - dst++; - src++; - *dst = *src; - dst++; - src++; - p->sync |= 0x200000; - - OSRestoreInterrupts(old); -} - -void AXSetVoiceLpfCoefs(AXVPB* p, u16 a0, u16 b0) -{ - BOOL old; - old = OSDisableInterrupts(); - - p->pb.lpf.a0 = a0; - p->pb.lpf.b0 = b0; - p->sync |= 0x400000; - - OSRestoreInterrupts(old); -} - -#define PI 3.14159265358979323846f - -void AXGetLpfCoefs(u16 freq, u16* a0, u16* b0) -{ - f32 bb; - f32 cc; - - ASSERTMSGLINE(1616, freq <= 16000, "freq is out of range"); - - cc = 2.0f - cos(((PI * 2) * (f32)freq) / 32000.0f); - bb = sqrt((cc * cc) - 1.0f) - cc; - - *b0 = 32768.0f * -bb; - *a0 = 0x7FFF - *b0; -} - -void AXSetMaxDspCycles(u32 cycles) -{ - __AXMaxDspCycles = cycles; -} - -u32 AXGetMaxDspCycles(void) -{ - return __AXMaxDspCycles; -} - -u32 AXGetDspCycles(void) -{ - return __AXRecDspCycles; -} diff --git a/src/dolphin/axart/src/axart.c b/src/dolphin/axart/src/axart.c deleted file mode 100644 index 93c42ab..0000000 --- a/src/dolphin/axart/src/axart.c +++ /dev/null @@ -1,330 +0,0 @@ -#include -#include -#include - -static AXART_SOUND* __AXARTSoundList; - -void AXARTInit(void) { - __AXARTSoundList = 0; - AXARTSet3DDistanceScale(40.0f); - AXARTSet3DDopplerScale(20.0f); -} - -void AXARTQuit(void) { - BOOL old; - AXART_SOUND* sound; - - old = OSDisableInterrupts(); - - for (sound = __AXARTSoundList; sound != 0; sound = (AXART_SOUND*)sound->next) { - MIXReleaseChannel(sound->axvpb); - } - - __AXARTSoundList = 0; - OSRestoreInterrupts(old); -} - -void AXARTServiceSounds(void) { - AXART_SOUND* sound; - - for (sound = __AXARTSoundList; sound != 0; sound = (AXART_SOUND*)sound->next) { - AXARTServiceSound(sound); - } -} - -void AXARTInitSound(AXART_SOUND* sound, AXVPB* voice, u32 sampleRate) { - ASSERTLINE(141, sound); - ASSERTLINE(142, voice); - - sound->articulators = NULL; - sound->axvpb = voice; - sound->sampleRate = sampleRate; -} - -void AXARTAddSound(AXART_SOUND* sound) { - AXART_ART* articulator; - AXVPB* axvpb; - s32 cents; - s32 atten; - s32 auxA; - s32 auxB; - f32 pitch; - u8 pan; - u8 span; - u8 src; - u16 itdL; - u16 itdR; - BOOL old; - - ASSERTLINE(173, sound); - ASSERTLINE(174, sound->axvpb); - - AXSetVoiceItdOn(sound->axvpb); - - cents = atten = auxA = auxB = 0; - pitch = sound->sampleRate / 32000.0f; - pan = 0x40; - span = 0x7F; - src = 1; - itdL = itdR = 0; - articulator = sound->articulators; - - while (articulator != 0) { - switch (articulator->type) { - case AXART_TYPE_3D: - AXART3DSound((AXART_3D*)articulator); - pan = ((AXART_3D*)articulator)->pan; - span = ((AXART_3D*)articulator)->span; - itdL = ((AXART_3D*)articulator)->itdL; - itdR = ((AXART_3D*)articulator)->itdR; - src = ((AXART_3D*)articulator)->src; - pitch += ((AXART_3D*)articulator)->pitch; - atten += ((AXART_3D*)articulator)->attenuation; - break; - case AXART_TYPE_PANNING: - pan = ((AXART_PANNING*)articulator)->pan; - span = ((AXART_PANNING*)articulator)->span; - break; - case AXART_TYPE_ITD: - itdL = ((AXART_ITD*)articulator)->itdL; - itdR = ((AXART_ITD*)articulator)->itdR; - break; - case AXART_TYPE_SRC: - src = ((AXART_SRC*)articulator)->src; - break; - case AXART_TYPE_PITCH: - cents += ((AXART_PITCH*)articulator)->cents; - break; - case AXART_TYPE_PITCH_ENV: - cents += ((AXART_PITCH_ENV*)articulator)->cents; - break; - case AXART_TYPE_PITCH_MOD: - cents += (s32)(((AXART_PITCH_MOD*)articulator)->cents * ((AXART_PITCH_MOD*)articulator)->lfo.output); - break; - case AXART_TYPE_VOLUME: - atten += ((AXART_VOLUME*)articulator)->attenuation; - break; - case AXART_TYPE_AUX_A_VOLUME: - auxA += ((AXART_AUXA_VOLUME*)articulator)->attenuation; - break; - case AXART_TYPE_AUX_B_VOLUME: - auxB += ((AXART_AUXB_VOLUME*)articulator)->attenuation; - break; - case AXART_TYPE_VOLUME_ENV: - atten += ((AXART_VOLUME_ENV*)articulator)->attenuation; - break; - case AXART_TYPE_AUX_A_VOLUME_ENV: - auxA += ((AXART_AUXA_VOLUME_ENV*)articulator)->attenuation; - break; - case AXART_TYPE_AUX_B_VOLUME_ENV: - auxB += ((AXART_AUXB_VOLUME_ENV*)articulator)->attenuation; - break; - case AXART_TYPE_VOLUME_MOD: - atten += (s32)(((AXART_VOLUME_MOD*)articulator)->attenuation * ((AXART_VOLUME_MOD*)articulator)->lfo.output); - break; - case AXART_TYPE_AUX_A_VOLUME_MOD: - auxA += (s32)(((AXART_AUXA_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); - break; - case AXART_TYPE_AUX_B_VOLUME_MOD: - auxB += (s32)(((AXART_AUXB_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); - break; - case AXART_TYPE_LPF: - AXARTLpf((AXART_LPF*)articulator, sound->axvpb); - break; - case AXART_TYPE_NONE: - default: - ASSERTMSGLINE(306, 0, "unknown articulator type!\n"); - } - - articulator = articulator->next; - } - - pitch *= AXARTCents(cents >> 0x10); - axvpb = sound->axvpb; - - AXSetVoiceSrcType(axvpb, src); - AXSetVoiceSrcRatio(axvpb, pitch); - AXSetVoiceItdTarget(axvpb, itdL, itdR); - MIXInitChannel(sound->axvpb, 0, atten >> 0x10, auxA >> 0x10, auxB >> 0x10, pan, span, 0); - old = OSDisableInterrupts(); - - if (__AXARTSoundList != 0) { - __AXARTSoundList->prev = sound; - sound->next = __AXARTSoundList; - } else { - sound->next = 0; - } - - sound->prev = 0; - __AXARTSoundList = sound; - OSRestoreInterrupts(old); -} - -void AXARTRemoveSound(AXART_SOUND* sound) { - BOOL old; - - ASSERTLINE(369, sound); - - old = OSDisableInterrupts(); - - if (sound == __AXARTSoundList) { - __AXARTSoundList = sound->next; - if (__AXARTSoundList != 0) { - __AXARTSoundList->prev = 0; - } - } else { - AXART_SOUND* prev = sound->prev; - AXART_SOUND* next = sound->next; - - prev->next = next; - if (next != 0) { - next->prev = prev; - } - } - - OSRestoreInterrupts(old); - MIXReleaseChannel(sound->axvpb); -} - -void AXARTInitLfo(AXART_LFO* lfo, f32* samples, u32 length, f32 delta) { - ASSERTLINE(417, samples); - ASSERTLINE(418, length); - - lfo->lfo = samples; - lfo->length = length; - lfo->delta = delta; - lfo->sampleIndex = 0; - lfo->counter = lfo->sample1 = lfo->sample = lfo->output = 0.0f; -} - -void AXARTInitArt3D(AXART_3D* articulator) { - ASSERTLINE(446, articulator); - - articulator->art.type = AXART_TYPE_3D; - articulator->hAngle = articulator->vAngle = articulator->dist = articulator->closingSpeed = articulator->update = 0.0f; - articulator->pan = 64; - articulator->span = 127; - articulator->src = 1; - articulator->itdL = articulator->itdR = 0; - articulator->pitch = 1.0f; - articulator->attenuation = -0x03C00000; -} - -void AXARTInitArtPanning(AXART_PANNING* articulator) { - ASSERTLINE(481, articulator); - - articulator->art.type = AXART_TYPE_PANNING; - articulator->pan = 64; - articulator->span = 127; -} - -void AXARTInitArtItd(AXART_ITD* articulator) { - ASSERTLINE(503, articulator); - - articulator->art.type = AXART_TYPE_ITD; - articulator->itdL = articulator->itdR = 0; -} - -void AXARTInitArtSrctype(AXART_SRC* articulator) { - ASSERTLINE(526, articulator); - - articulator->art.type = AXART_TYPE_SRC; - articulator->src = 1; -} - -void AXARTInitArtPitch(AXART_PITCH* articulator) { - ASSERTLINE(547, articulator); - - articulator->art.type = AXART_TYPE_PITCH; - articulator->cents = 0; -} - -void AXARTInitArtPitchEnv(AXART_PITCH_ENV* articulator) { - ASSERTLINE(569, articulator); - - articulator->art.type = AXART_TYPE_PITCH_ENV; - articulator->delta = articulator->target = articulator->cents = 0; -} - -void AXARTInitArtPitchMod(AXART_PITCH_MOD* articulator) { - ASSERTLINE(594, articulator); - - articulator->art.type = AXART_TYPE_PITCH_MOD; - articulator->cents = 0; - AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); -} - -void AXARTInitArtVolume(AXART_VOLUME* articulator) { - ASSERTLINE(617, articulator); - - articulator->art.type = AXART_TYPE_VOLUME; - articulator->attenuation = 0; -} - -void AXARTInitArtAuxAVolume(AXART_AUXA_VOLUME* articulator) { - ASSERTLINE(639, articulator); - - articulator->art.type = AXART_TYPE_AUX_A_VOLUME; - articulator->attenuation = 0; -} - -void AXARTInitArtAuxBVolume(AXART_AUXB_VOLUME* articulator) { - ASSERTLINE(661, articulator); - - articulator->art.type = AXART_TYPE_AUX_B_VOLUME; - articulator->attenuation = 0; -} - -void AXARTInitArtVolumeEnv(AXART_VOLUME_ENV* articulator) { - ASSERTLINE(683, articulator); - - articulator->art.type = AXART_TYPE_VOLUME_ENV; - articulator->delta = articulator->target = articulator->attenuation = 0; -} - -void AXARTInitArtAuxAVolumeEnv(AXART_AUXA_VOLUME_ENV* articulator) { - ASSERTLINE(707, articulator); - - articulator->art.type = AXART_TYPE_AUX_A_VOLUME_ENV; - articulator->delta = articulator->target = articulator->attenuation = 0; -} - -void AXARTInitArtAuxBVolumeEnv(AXART_AUXB_VOLUME_ENV* articulator) { - ASSERTLINE(731, articulator); - - articulator->art.type = AXART_TYPE_AUX_B_VOLUME_ENV; - articulator->delta = articulator->target = articulator->attenuation = 0; -} - -void AXARTInitArtVolumeMod(AXART_VOLUME_MOD* articulator) { - ASSERTLINE(756, articulator); - - articulator->art.type = AXART_TYPE_VOLUME_MOD; - articulator->attenuation = 0; - AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); -} - -void AXARTInitArtAuxAVolumeMod(AXART_AUXA_VOLUME_MOD* articulator) { - ASSERTLINE(781, articulator); - - articulator->art.type = AXART_TYPE_AUX_A_VOLUME_MOD; - articulator->attenuation = 0; - AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); -} - -void AXARTInitArtAuxBVolumeMod(AXART_AUXB_VOLUME_MOD* articulator) { - ASSERTLINE(806, articulator); - - articulator->art.type = AXART_TYPE_AUX_B_VOLUME_MOD; - articulator->attenuation = 0; - AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); -} - -void AXARTInitArtLpf(AXART_LPF* articulator) { - ASSERTLINE(830, articulator); - - articulator->art.type = AXART_TYPE_LPF; - articulator->initLPF = 1; - articulator->frequency = 0; - articulator->update = 1; -} diff --git a/src/dolphin/axart/src/axart3d.c b/src/dolphin/axart/src/axart3d.c deleted file mode 100644 index b2d90db..0000000 --- a/src/dolphin/axart/src/axart3d.c +++ /dev/null @@ -1,317 +0,0 @@ -#include -#include -#include - -static u8 __AXART3DPan[360] = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, - 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F -}; - -static u8 __AXART3DSpan[360] = { - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, - 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, - 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, - 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, - 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, - 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, - 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48, - 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, - 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, - 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, - 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, - 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, - 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, - 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, -}; - -static u8 __AXART3DPanDPL2[360] = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, - 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, - 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, - 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, - 0x63, 0x62, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, - 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D, 0x4C, - 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, - 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, - 0x33, 0x32, 0x31, 0x30, 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, - 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, - 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, - 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F -}; - -static u8 __AXART3DItdL[360] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x1F, - 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, - 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, - 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, - 0x1D, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x1B, 0x1B, 0x1B, - 0x1B, 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, - 0x1A, 0x19, 0x19, 0x19, 0x19, 0x19, 0x18, 0x18, - 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16, 0x15, - 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, - 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, - 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 __AXART3DItdR[360] = { - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, - 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1A, - 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, - 0x1B, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D, - 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, - 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, - 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, - 0x1F, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, - 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, - 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, - 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 __AXART3DSrc[360+1] = { - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, -}; - -static f32 __AXART3DDopplerScale = 0; -static f32 __AXART3DDistanceScale = 0; - -void AXARTSet3DDopplerScale(f32 scale) { - ASSERTLINE(323, scale > 0); - __AXART3DDopplerScale = scale; -} - -void AXARTSet3DDistanceScale(f32 scale) { - ASSERTLINE(340, scale > 0); - __AXART3DDistanceScale = scale; -} - -void AXART3DSound(AXART_3D* articulator) { - u32 hAngle; - u32 vAngle; - - if (articulator->update) { - if (articulator->hAngle > 0) { - hAngle = (articulator->hAngle / 6.283185f) * 360.0f; - } else if (articulator->hAngle < 0) { - hAngle = 360.0f + (articulator->hAngle / 6.283185f) * 360.0f; - } else { - hAngle = 0; - } - - // @BUG? - hAngle missing a bounds assert - - if (articulator->vAngle > 0) { - vAngle = (articulator->vAngle / 6.283185f) * 360.0f; - } else if (articulator->vAngle < 0) { - vAngle = 360.0f + (articulator->vAngle / 6.283185f) * 360.0f; - } else { - vAngle = 0; - } - - ASSERTLINE(379, vAngle <= 360); - - articulator->update = 0; - - if (MIXGetSoundMode() == 3) { - articulator->pan = __AXART3DPanDPL2[hAngle]; - } else { - articulator->pan = __AXART3DPan[hAngle]; - } - - articulator->span = __AXART3DSpan[hAngle]; - articulator->itdL = __AXART3DItdL[hAngle]; - articulator->itdR = __AXART3DItdR[hAngle]; - articulator->src = __AXART3DSrc[vAngle]; - articulator->pitch = articulator->closingSpeed / __AXART3DDopplerScale; - articulator->attenuation = (articulator->dist / __AXART3DDistanceScale) * -3932160.0f; - } -} diff --git a/src/dolphin/axart/src/axartcents.c b/src/dolphin/axart/src/axartcents.c deleted file mode 100644 index 6086bf4..0000000 --- a/src/dolphin/axart/src/axartcents.c +++ /dev/null @@ -1,280 +0,0 @@ -#include -#include -#include - -static f32 __AXLFOCentsTable[100] = { - 1.000000f, - 1.000578f, - 1.001156f, - 1.001734f, - 1.002313f, - 1.002892f, - 1.003472f, - 1.004052f, - 1.004632f, - 1.005212f, - 1.005793f, - 1.006374f, - 1.006956f, - 1.007537f, - 1.008120f, - 1.008702f, - 1.009285f, - 1.009868f, - 1.010451f, - 1.011035f, - 1.011619f, - 1.012204f, - 1.012789f, - 1.013374f, - 1.013959f, - 1.014545f, - 1.015132f, - 1.015718f, - 1.016305f, - 1.016892f, - 1.017480f, - 1.018068f, - 1.018656f, - 1.019244f, - 1.019833f, - 1.020423f, - 1.021012f, - 1.021602f, - 1.022192f, - 1.022783f, - 1.023374f, - 1.023965f, - 1.024557f, - 1.025149f, - 1.025741f, - 1.026334f, - 1.026927f, - 1.027520f, - 1.028114f, - 1.028708f, - 1.029302f, - 1.029897f, - 1.030492f, - 1.031087f, - 1.031683f, - 1.032279f, - 1.032876f, - 1.033472f, - 1.034070f, - 1.034667f, - 1.035265f, - 1.035863f, - 1.036462f, - 1.037060f, - 1.037660f, - 1.038259f, - 1.038859f, - 1.039459f, - 1.040060f, - 1.040661f, - 1.041262f, - 1.041864f, - 1.042466f, - 1.043068f, - 1.043671f, - 1.044274f, - 1.044877f, - 1.045481f, - 1.046085f, - 1.046689f, - 1.047294f, - 1.047899f, - 1.048505f, - 1.049111f, - 1.049717f, - 1.050323f, - 1.050930f, - 1.051537f, - 1.052145f, - 1.052753f, - 1.053361f, - 1.053970f, - 1.054579f, - 1.055188f, - 1.055798f, - 1.056408f, - 1.057018f, - 1.057629f, - 1.058240f, - 1.058851f, -}; - -static f32 __AXLFOOctavesTableUp[12] = { - 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, - 256.0f, 512.0f, 1024.0f, 2048.0f, -}; - -static f32 __AXLFOSemitonesTableUp[12] = { - 1.000000f, - 1.059463f, - 1.122462f, - 1.189207f, - 1.259921f, - 1.334840f, - 1.414214f, - 1.498307f, - 1.587401f, - 1.681793f, - 1.781797f, - 1.887749f, -}; - -static f32 __AXLFOSemitonesTableDown[128] = { - 1.000000f, - 0.943874f, - 0.890899f, - 0.840896f, - 0.793701f, - 0.749154f, - 0.707107f, - 0.667420f, - 0.629961f, - 0.594604f, - 0.561231f, - 0.529732f, - 0.500000f, - 0.471937f, - 0.445449f, - 0.420448f, - 0.396850f, - 0.374577f, - 0.353553f, - 0.333710f, - 0.314980f, - 0.297302f, - 0.280616f, - 0.264866f, - 0.250000f, - 0.235969f, - 0.222725f, - 0.210224f, - 0.198425f, - 0.187288f, - 0.176777f, - 0.166855f, - 0.157490f, - 0.148651f, - 0.140308f, - 0.132433f, - 0.125000f, - 0.117984f, - 0.111362f, - 0.105112f, - 0.099213f, - 0.093644f, - 0.088388f, - 0.083427f, - 0.078745f, - 0.074325f, - 0.070154f, - 0.066216f, - 0.062500f, - 0.058992f, - 0.055681f, - 0.052556f, - 0.049606f, - 0.046822f, - 0.044194f, - 0.041714f, - 0.039373f, - 0.037163f, - 0.035077f, - 0.033108f, - 0.031250f, - 0.029496f, - 0.027841f, - 0.026278f, - 0.024803f, - 0.023411f, - 0.022097f, - 0.020857f, - 0.019686f, - 0.018581f, - 0.017538f, - 0.016554f, - 0.015625f, - 0.014748f, - 0.013920f, - 0.013139f, - 0.012402f, - 0.011706f, - 0.011049f, - 0.010428f, - 0.009843f, - 0.009291f, - 0.008769f, - 0.008277f, - 0.007813f, - 0.007374f, - 0.006960f, - 0.006570f, - 0.006201f, - 0.005853f, - 0.005524f, - 0.005214f, - 0.004922f, - 0.004645f, - 0.004385f, - 0.004139f, - 0.003906f, - 0.003687f, - 0.003480f, - 0.003285f, - 0.003100f, - 0.002926f, - 0.002762f, - 0.002607f, - 0.002461f, - 0.002323f, - 0.002192f, - 0.002069f, - 0.001953f, - 0.001844f, - 0.001740f, - 0.001642f, - 0.001550f, - 0.001463f, - 0.001381f, - 0.001304f, - 0.001230f, - 0.001161f, - 0.001096f, - 0.001035f, - 0.000977f, - 0.000922f, - 0.000870f, - 0.000821f, - 0.000775f, - 0.000732f, - 0.000691f, - 0.000652f, -}; - -f32 AXARTCents(s32 cents) { - if (cents > 0) { - s32 octaves = cents / 1200; - s32 semitones = (cents % 1200) / 100; - cents %= 100; - - return __AXLFOOctavesTableUp[octaves] * __AXLFOSemitonesTableUp[semitones] * __AXLFOCentsTable[cents]; - } else if (cents < 0) { - s32 semitones = cents / 100; - cents %= 100; - - if (cents != 0) { - cents += 100; - semitones -= 1; - } - - semitones *= -1; - return __AXLFOSemitonesTableDown[semitones] * __AXLFOCentsTable[cents]; - } else { - return 1.0f; - } -} diff --git a/src/dolphin/axart/src/axartenv.c b/src/dolphin/axart/src/axartenv.c deleted file mode 100644 index 278bfb5..0000000 --- a/src/dolphin/axart/src/axartenv.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include - -void AXARTPitchEnv(AXART_PITCH_ENV* articulator) { - if (articulator->cents != articulator->target) { - articulator->cents += articulator->delta; - if (articulator->delta > 0) { - if (articulator->cents > articulator->target) { - articulator->cents = articulator->target; - } - } else if (articulator->delta < 0) { - if (articulator->cents < articulator->target) { - articulator->cents = articulator->target; - } - } - } -} - -void AXARTVolumeEnv(AXART_VOLUME_ENV* articulator) { - if (articulator->attenuation != articulator->target) { - articulator->attenuation += articulator->delta; - if (articulator->delta > 0) { - if (articulator->attenuation > articulator->target) { - articulator->attenuation = articulator->target; - } - } else if (articulator->delta < 0) { - if (articulator->attenuation < articulator->target) { - articulator->attenuation = articulator->target; - } - } - } -} diff --git a/src/dolphin/axart/src/axartlfo.c b/src/dolphin/axart/src/axartlfo.c deleted file mode 100644 index 58c9f45..0000000 --- a/src/dolphin/axart/src/axartlfo.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include - -f32 AXARTSine[64] = { - 0.0f, 0.09802f, 0.19509f, 0.29028f, 0.38268f, 0.4714f, 0.55557f, 0.63439f, - 0.70711f, 0.77301f, 0.83147f, 0.88192f, 0.92388f, 0.95694f, 0.98079f, 0.99518f, - 1.0f, 0.99518f, 0.98079f, 0.95694f, 0.92388f, 0.88192f, 0.83147f, 0.77301f, - 0.70711f, 0.63439f, 0.55557f, 0.4714f, 0.38268f, 0.29028f, 0.19509f, 0.09802f, - 0.0f, -0.09802f, -0.19509f, -0.29028f, -0.38268f, -0.4714f, -0.55557f, -0.63439f, - -0.70711f, -0.77301f, -0.83147f, -0.88192f, -0.92388f, -0.95694f, -0.98079f, -0.99518f, - -1.0f, -0.99518f, -0.98079f, -0.95694f, -0.92388f, -0.88192f, -0.83147f, -0.77301f, - -0.70711f, -0.63439f, -0.55557f, -0.4714f, -0.38268f, -0.29028f, -0.19509f, -0.09802f, -}; - -static f32 AXARTSquare[64] = { - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, - -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, - -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, - -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, - -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -}; - -static f32 AXARTSaw[64] = { - -1.0f, -0.96875f, -0.9375f, -0.90625f, -0.875f, -0.84375f, -0.8125f, -0.78125f, - -0.75f, -0.71875f, -0.6875f, -0.65625f, -0.625f, -0.59375f, -0.5625f, -0.53125f, - -0.5f, -0.46875f, -0.4375f, -0.40625f, -0.375f, -0.34375f, -0.3125f, -0.28125f, - -0.25f, -0.21875f, -0.1875f, -0.15625f, -0.125f, -0.09375f, -0.0625f, -0.03125f, - 0.0f, 0.03125f, 0.0625f, 0.09375f, 0.125f, 0.15625f, 0.1875f, 0.21875f, - 0.25f, 0.28125f, 0.3125f, 0.34375f, 0.375f, 0.40625f, 0.4375f, 0.46875f, - 0.5f, 0.53125f, 0.5625f, 0.59375f, 0.625f, 0.65625f, 0.6875f, 0.71875f, - 0.75f, 0.78125f, 0.8125f, 0.84375f, 0.875f, 0.90625f, 0.9375f, 0.96875f, -}; - -static f32 AXARTReverseSaw[64] = { - 1.0f, 0.96875f, 0.9375f, 0.90625f, 0.875f, 0.84375f, 0.8125f, 0.78125f, - 0.75f, 0.71875f, 0.6875f, 0.65625f, 0.625f, 0.59375f, 0.5625f, 0.53125f, - 0.5f, 0.46875f, 0.4375f, 0.40625f, 0.375f, 0.34375f, 0.3125f, 0.28125f, - 0.25f, 0.21875f, 0.1875f, 0.15625f, 0.125f, 0.09375f, 0.0625f, 0.03125f, - 0.0f, -0.03125f, -0.0625f, -0.09375f, -0.125f, -0.15625f, -0.1875f, -0.21875f, - -0.25f, -0.28125f, -0.3125f, -0.34375f, -0.375f, -0.40625f, -0.4375f, -0.46875f, - -0.5f, -0.53125f, -0.5625f, -0.59375f, -0.625f, -0.65625f, -0.6875f, -0.71875f, - -0.75f, -0.78125f, -0.8125f, -0.84375f, -0.875f, -0.90625f, -0.9375f, -0.96875f, -}; - -static f32 AXARTTriangle[64] = { - 0.0f, 0.0625f, 0.125f, 0.1875f, 0.25f, 0.3125f, 0.375f, 0.4375f, - 0.5f, 0.5625f, 0.625f, 0.6875f, 0.75f, 0.8125f, 0.875f, 0.9375f, - 1.0f, 0.9375f, 0.875f, 0.8125f, 0.75f, 0.6875f, 0.625f, 0.5625f, - 0.5f, 0.4375f, 0.375f, 0.3125f, 0.25f, 0.1875f, 0.125f, 0.0625f, - 0.0f, -0.0625f, -0.125f, -0.1875f, -0.25f, -0.3125f, -0.375f, -0.4375f, - -0.5f, -0.5625f, -0.625f, -0.6875f, -0.75f, -0.8125f, -0.875f, -0.9375f, - -1.0f, -0.9375f, -0.875f, -0.8125f, -0.75f, -0.6875f, -0.625f, -0.5625f, - -0.5f, -0.4375f, -0.375f, -0.3125f, -0.25f, -0.1875f, -0.125f, -0.0625f, -}; - -static f32 AXARTNoise[64] = { - -0.759363f, -0.805919f, -0.62015f, -0.78302f, 0.263439f, 0.467792f, -0.102506f, 0.700646f, - 0.852924f, 0.586413f, 0.32763f, 0.313143f, 0.66009f, 0.778686f, -0.698379f, -0.635841f, - -0.087795f, 0.577847f, 0.887183f, -0.325427f, -0.890347f, 0.111084f, -0.325035f, 0.43995f, - -0.62506f, -0.515152f, -0.299054f, -0.353217f, 0.512053f, 0.03931f, 0.869222f, -0.626512f, - 0.017653f, 0.891789f, -0.191419f, 0.411077f, 0.965653f, 0.134522f, -0.761372f, 0.543137f, - -0.887949f, 0.454729f, 0.860104f, -0.005229f, 0.28682f, -0.036344f, -0.976264f, -0.400756f, - 0.662483f, -0.44099f, -0.02479f, 0.066671f, -0.045242f, 0.150543f, 0.810762f, -0.35605f, - 0.364502f, 0.63764f, -0.212945f, 0.394563f, 0.496392f, 0.727584f, -0.564585f, 0.040292f, -}; - -void AXARTLfo(AXART_LFO* lfo) { - lfo->counter += lfo->delta; - - if (lfo->counter >= 1.0f) { - f32 lfoSamples = lfo->counter; - - lfo->counter -= lfoSamples; - lfo->sampleIndex += (u32)lfoSamples; - lfo->sampleIndex %= lfo->length; - lfo->sample1 = lfo->sample; - lfo->sample = lfo->lfo[lfo->sampleIndex]; - } - - lfo->output = lfo->sample1 - lfo->counter * (lfo->sample1 - lfo->sample); -} diff --git a/src/dolphin/axart/src/axartlpf.c b/src/dolphin/axart/src/axartlpf.c deleted file mode 100644 index c2aecfa..0000000 --- a/src/dolphin/axart/src/axartlpf.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include "fake_tgmath.h" - -static u16 __coefs[48] = { - 0x6A09, 0x15F6, 0x6871, 0x178E, 0x6463, 0x1B9C, - 0x5DB3, 0x224C, 0x5618, 0x29E7, 0x4D7A, 0x3285, - 0x4367, 0x3C98, 0x3A5A, 0x45A5, 0x31C5, 0x4E3A, - 0x2924, 0x56DB, 0x2244, 0x5DBB, 0x1C50, 0x63AF, - 0x16C0, 0x693F, 0x1292, 0x6D6D, 0x0F18, 0x70E7, - 0x0BF5, 0x740A, 0x09A9, 0x7656, 0x07CA, 0x7835, - 0x0646, 0x79B9, 0x04ED, 0x7B12, 0x03F5, 0x7C0A, - 0x032D, 0x7CD2, 0x027D, 0x7D82, 0x01FE, 0x7E01 -}; - -void AXARTLpf(AXART_LPF* articulator, AXVPB* voice) { - u32 i; - ASSERTLINE(68, articulator); - ASSERTLINE(69, voice); - - if (articulator->update != 0) { - if (articulator->initLPF != 0) { - articulator->initLPF = 0; - voice->pb.lpf.on = 1; - voice->pb.lpf.yn1 = 0; - voice->sync |= 0x200000; - } else { - voice->sync |= 0x400000; - } - - i = articulator->frequency; - ASSERTMSGLINE(90, i < 24, "AXART: roll off frequency should be < 24"); - - i *= 2; - voice->pb.lpf.a0 = __coefs[i]; - - i++; - voice->pb.lpf.b0 = __coefs[i]; - articulator->update = 0; - } -} diff --git a/src/dolphin/axart/src/axartsound.c b/src/dolphin/axart/src/axartsound.c deleted file mode 100644 index 732171d..0000000 --- a/src/dolphin/axart/src/axartsound.c +++ /dev/null @@ -1,122 +0,0 @@ -#include -#include -#include - -void AXARTServiceSound(AXART_SOUND* sound) { - AXART_ART* articulator; - AXVPB* axvpb; - s32 cents; - s32 atten; - s32 auxA; - s32 auxB; - f32 pitch; - u8 pan; - u8 span; - u8 src; - u16 itdL; - u16 itdR; - - cents = atten = auxA = auxB = 0; - pitch = sound->sampleRate / 32000.0f; - pan = 64; - span = 127; - src = 1; - itdL = itdR = 0; - - for (articulator = sound->articulators; articulator != 0; articulator = (AXART_ART*)articulator->next) { - switch (articulator->type) { - case AXART_TYPE_3D: - AXART3DSound((AXART_3D*)articulator); - pan = ((AXART_3D*)articulator)->pan; - span = ((AXART_3D*)articulator)->span; - itdL = ((AXART_3D*)articulator)->itdL; - itdR = ((AXART_3D*)articulator)->itdR; - src = ((AXART_3D*)articulator)->src; - pitch += ((AXART_3D*)articulator)->pitch; - atten += ((AXART_3D*)articulator)->attenuation; - break; - case AXART_TYPE_PANNING: - pan = ((AXART_PANNING*)articulator)->pan; - span = ((AXART_PANNING*)articulator)->span; - break; - case AXART_TYPE_ITD: - itdL = ((AXART_ITD*)articulator)->itdL; - itdR = ((AXART_ITD*)articulator)->itdR; - break; - case AXART_TYPE_SRC: - src = ((AXART_SRC*)articulator)->src; - break; - case AXART_TYPE_PITCH: - cents += ((AXART_PITCH*)articulator)->cents; - break; - case AXART_TYPE_PITCH_ENV: - AXARTPitchEnv((AXART_PITCH_ENV*)articulator); - cents += ((AXART_PITCH_ENV*)articulator)->cents; - break; - case AXART_TYPE_PITCH_MOD: - AXARTLfo(&((AXART_PITCH_MOD*)articulator)->lfo); - cents += (s32)(((AXART_PITCH_MOD*)articulator)->cents * ((AXART_PITCH_MOD*)articulator)->lfo.output); - break; - case AXART_TYPE_VOLUME: - atten += ((AXART_VOLUME*)articulator)->attenuation; - break; - case AXART_TYPE_AUX_A_VOLUME: - auxA += ((AXART_AUXA_VOLUME*)articulator)->attenuation; - break; - case AXART_TYPE_AUX_B_VOLUME: - auxB += ((AXART_AUXB_VOLUME*)articulator)->attenuation; - break; - case AXART_TYPE_VOLUME_ENV: - AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); - atten += ((AXART_VOLUME_ENV*)articulator)->attenuation; - break; - case AXART_TYPE_AUX_A_VOLUME_ENV: - AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); - auxA += ((AXART_AUXA_VOLUME_ENV*)articulator)->attenuation; - break; - case AXART_TYPE_AUX_B_VOLUME_ENV: - AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); - auxB += ((AXART_AUXB_VOLUME_ENV*)articulator)->attenuation; - break; - case AXART_TYPE_VOLUME_MOD: - AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); - atten += (s32)(((AXART_VOLUME_MOD*)articulator)->attenuation * ((AXART_VOLUME_MOD*)articulator)->lfo.output); - break; - case AXART_TYPE_AUX_A_VOLUME_MOD: - AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); - auxA += (s32)(((AXART_AUXA_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); - break; - case AXART_TYPE_AUX_B_VOLUME_MOD: - AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); - auxB += (s32)(((AXART_AUXB_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXB_VOLUME_MOD*)articulator)->lfo.output); - break; - case AXART_TYPE_LPF: - AXARTLpf((AXART_LPF*)articulator, sound->axvpb); - break; - default: -#ifdef DEBUG - OSPanic(__FILE__, 196, "unknown articulator type!\n"); -#endif - break; - } - } - - pitch *= AXARTCents(cents >> 16); - axvpb = sound->axvpb; - AXSetVoiceSrcType(axvpb, src); - AXSetVoiceSrcRatio(axvpb, pitch); - AXSetVoiceItdTarget(axvpb, itdL, itdR); - MIXSetInput(axvpb, atten >> 16); - MIXSetAuxA(axvpb, auxA >> 16); - MIXSetAuxB(axvpb, auxB >> 16); - MIXSetPan(axvpb, pan); - MIXSetSPan(axvpb, span); -} - -void AXARTAddArticulator(AXART_SOUND* sound, AXART_ART* articulator) { - ASSERTLINE(232, sound); - ASSERTLINE(233, articulator); - - articulator->next = sound->articulators; - sound->articulators = articulator; -} diff --git a/src/dolphin/axfx/src/reverb_hi.c b/src/dolphin/axfx/src/reverb_hi.c deleted file mode 100644 index cba8c2a..0000000 --- a/src/dolphin/axfx/src/reverb_hi.c +++ /dev/null @@ -1,890 +0,0 @@ -#include -#include -#include -#include - -#include "__axfx.h" - -// prototypes -static void DLsetdelay(AXFX_REVHI_DELAYLINE* dl, s32 lag); -static int DLcreate(AXFX_REVHI_DELAYLINE* dl, s32 max_length); -static void DLdelete(AXFX_REVHI_DELAYLINE* dl); -static int ReverbHICreate(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, - f32 preDelay, f32 crosstalk); -static int ReverbHIModify(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, - f32 preDelay, f32 crosstalk); -static void HandleReverb(s32* sptr, AXFX_REVHI_WORK* rv, s32 k); -static void ReverbHICallback(s32* left, s32* right, s32* surround, AXFX_REVHI_WORK* rv); -static void ReverbHIFree(AXFX_REVHI_WORK* rv); - -static void DLsetdelay(AXFX_REVHI_DELAYLINE* dl, s32 lag) -{ - dl->outPoint = dl->inPoint - (lag * 4); - while (dl->outPoint < 0) - { - dl->outPoint += dl->length; - } -} - -static int DLcreate(AXFX_REVHI_DELAYLINE* dl, s32 max_length) -{ - dl->length = (max_length * 4); - dl->inputs = __AXFXAlloc(max_length << 2); - ASSERTMSGLINE(51, dl->inputs, "Can't allocate the memory."); - if (dl->inputs == NULL) - { - return 0; - } - - memset(dl->inputs, 0, max_length << 2); - dl->lastOutput = 0.0f; - DLsetdelay(dl, max_length >> 1); - dl->inPoint = 0; - dl->outPoint = 0; - return 1; -} - -static void DLdelete(AXFX_REVHI_DELAYLINE* dl) -{ - __AXFXFree(dl->inputs); -} - -static int ReverbHICreate(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, - f32 preDelay, f32 crosstalk) -{ - u8 i; - u8 k; - static s32 lens[8] = { 0x000006FD, 0x000007CF, 0x0000091D, 0x000001B1, - 0x00000095, 0x0000002F, 0x00000049, 0x00000043 }; - - ASSERTMSGLINE(105, - coloration >= 0.0f && coloration <= 1.0f && time >= 0.01f && time <= 10.0f && - mix >= 0.0f && mix <= 1.0f && crosstalk >= 0.0f && crosstalk <= 1.0f && - damping >= 0.0f && damping <= 1.0f && preDelay >= 0.0f && preDelay <= 0.1f, - "The value of specified parameter is out of range."); - - if ((coloration < 0.0f) || (coloration > 1.0f) || (time < 0.01f) || (time > 10.0f) || - (mix < 0.0f) || (mix > 1.0f) || (crosstalk < 0.0f) || (crosstalk > 1.0f) || - (damping < 0.0f) || (damping > 1.0f) || (preDelay < 0.0f) || (preDelay > 0.1f)) - { - return 0; - } - - memset(rv, 0, sizeof(AXFX_REVHI_WORK)); - - for (k = 0; k < 3; k++) - { - for (i = 0; i < 3; i++) - { - if (DLcreate(&rv->C[i + (k * 3)], lens[i] + 2) == 0) - { - ReverbHIFree(rv); - return 0; - } - - DLsetdelay(&rv->C[i + (k * 3)], lens[i]); - rv->combCoef[i + (k * 3)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); - } - - for (i = 0; i < 2; i++) - { - if (DLcreate(&rv->AP[i + (k * 3)], lens[i + 3] + 2) == 0) - { - ReverbHIFree(rv); - return 0; - } - DLsetdelay(&rv->AP[i + (k * 3)], lens[i + 3]); - } - - if (DLcreate(&rv->AP[2 + (k * 3)], lens[k + 5] + 2) == 0) - { - ReverbHIFree(rv); - return 0; - } - DLsetdelay(&rv->AP[2 + (k * 3)], lens[k + 5]); - rv->lpLastout[k] = 0.0f; - } - - rv->allPassCoeff = coloration; - rv->level = mix; - rv->crosstalk = crosstalk; - rv->damping = damping; - if (rv->damping < 0.05f) - { - rv->damping = 0.05f; - } - rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); - - if (0.0f != preDelay) - { - rv->preDelayTime = (32000.0f * preDelay); - for (i = 0; i < 3; i++) - { - rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); - ASSERTMSGLINE(173, rv->preDelayLine[i], "Can't allocate the memory."); - if (rv->preDelayLine[i] == NULL) - { - ReverbHIFree(rv); - return 0; - } - - memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); - rv->preDelayPtr[i] = rv->preDelayLine[i]; - } - } - else - { - rv->preDelayTime = 0; - for (i = 0; i < 3; i++) - { - rv->preDelayPtr[i] = 0; - rv->preDelayLine[i] = 0; - } - } - - return 1; -} - -static int ReverbHIModify(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, - f32 preDelay, f32 crosstalk) -{ - u8 i; - - ASSERTMSGLINE(209, - coloration >= 0.0f && coloration <= 1.0f && time >= 0.01f && time <= 10.0f && - mix >= 0.0f && mix <= 1.0f && crosstalk >= 0.0f && crosstalk <= 1.0f && - damping >= 0.0f && damping <= 1.0f && preDelay >= 0.0f && preDelay <= 0.1f, - "The value of specified parameter is out of range."); - - if ((coloration < 0.0f) || (coloration > 1.0f) || (time < 0.01f) || (time > 10.0f) || - (mix < 0.0f) || (mix > 1.0f) || (crosstalk < 0.0f) || (crosstalk > 1.0f) || - (damping < 0.0f) || (damping > 1.0f) || (preDelay < 0.0f) || (preDelay > 0.1f)) - { - return 0; - } - - rv->allPassCoeff = coloration; - rv->level = mix; - rv->crosstalk = crosstalk; - rv->damping = damping; - if (rv->damping < 0.05f) - { - rv->damping = 0.05f; - } - rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); - - for (i = 0; i < 9; i++) - { - DLdelete(&rv->AP[i]); - } - - for (i = 0; i < 9; i++) - { - DLdelete(&rv->C[i]); - } - - if (rv->preDelayTime) - { - for (i = 0; i < 3; i++) - { - __AXFXFree(rv->preDelayLine[i]); - } - } - - return ReverbHICreate(rv, coloration, time, mix, damping, preDelay, crosstalk); -} - -const static double i2fMagic = 4503601774854144.0; -const static f32 value1_0 = 1.0f; -const static f32 value0_3 = 0.3f; -const static f32 value0_6 = 0.6f; - -asm static void DoCrossTalk(register s32* l, register s32* r, register f32 cross, - register f32 invcross) -{ - nofralloc stwu r1, -48(r1)stfd f14, 40(r1)lis r5, i2fMagic @ha lfd f0, i2fMagic @l(r5) lis r5, - 0x4330 // 176.0f (0x43300000) - stw r5, - 8(r1)stw r5, 16(r1)stw r5, 24(r1)stw r5, 32(r1)ps_merge00 f3, invcross, cross ps_merge00 f4, - cross, invcross lis r5, value1_0 @ha lfs f5, value1_0 @l(r5) li r5, 79 mtctr r5 li r10, - -8 li r11, -4 ps_muls0 f4, f4, f5 lwz r6, 0(l)lwz r7, 0(r)xoris r6, r6, 0x8000 lwz r8, - 4(l)xoris r7, r7, 0x8000 lwz r9, 4(r)xoris r8, r8, 0x8000 stw r6, 12(r1)xoris r9, r9, - 0x8000 stw r7, 20(r1)stw r8, 28(r1)stw r9, 36(r1)lfd f5, 8(r1)lfd f6, 16(r1)fsubs f5, f5, - f0 lfd f7, 24(r1)fsubs f6, f6, f0 lfd f8, 32(r1)fsubs f7, f7, f0 fsubs f8, f8, - f0 loop : ps_merge00 f9, - f5, - f6 lwzu r6, - 8(l)ps_merge00 f10, - f7, - f8 lwzu r7, - 8(r)xoris r6, - r6, - 0x8000 lwz r8, - 4(l)ps_mul f11, - f9, - f3 xoris r7, - r7, - 0x8000 ps_mul f12, - f9, - f4 lwz r9, - 4(r)ps_mul f13, - f10, - f3 xoris r8, - r8, - 0x8000 ps_mul f14, - f10, - f4 stw r6, - 12(r1)ps_sum0 f11, - f11, - f11, - f11 xoris r9, - r9, - 0x8000 ps_sum0 f12, - f12, - f12, - f12 stw r7, - 20(r1)ps_sum0 f13, - f13, - f13, - f13 stw r8, - 28(r1)ps_sum0 f14, - f14, - f14, - f14 stw r9, - 36(r1)fctiw f11, - f11 lfd f5, - 8(r1)fctiw f12, - f12 lfd f6, - 16(r1)fctiw f13, - f13 fsubs f5, - f5, - f0 fctiw f14, - f14 lfd f7, - 24(r1)stfiwx f11, - r10, - l fsubs f6, - f6, - f0 stfiwx f12, - r10, - r lfd f8, - 32(r1)stfiwx f13, - r11, - l fsubs f7, - f7, - f0 stfiwx f14, - r11, - r fsubs f8, - f8, - f0 bdnz loop ps_merge00 f9, - f5, - f6 addi l, - l, - 8 ps_merge00 f10, - f7, - f8 addi r, - r, - 8 ps_mul f11, - f9, - f3 ps_mul f12, - f9, - f4 ps_mul f13, - f10, - f3 ps_mul f14, - f10, - f4 ps_sum0 f11, - f11, - f11, - f11 ps_sum0 f12, - f12, - f12, - f12 ps_sum0 f13, - f13, - f13, - f13 ps_sum0 f14, - f14, - f14, - f14 fctiw f11, - f11 fctiw f12, - f12 fctiw f13, - f13 fctiw f14, - f14 stfiwx f11, - r10, - l stfiwx f12, - r10, - r stfiwx f13, - r11, - l stfiwx f14, - r11, - r lfd f14, - 40(r1)addi r1, - r1, - 48 blr -} - -asm static void HandleReverb(register s32* sptr, register AXFX_REVHI_WORK* rv, register s32 k) -{ - nofralloc stwu r1, -0xc0(r1)stmw r14, 0x8(r1)stfd f14, 0x60(r1)stfd f15, 0x68(r1)stfd f16, - 0x70(r1)stfd f17, 0x78(r1)stfd f18, 0x80(r1)stfd f19, 0x88(r1)stfd f20, 0x90(r1)stfd f21, - 0x98(r1)stfd f22, 0xa0(r1)stfd f23, 0xa8(r1)stfd f24, 0xb0(r1)stfd f25, 0xb8(r1)stw k, - 0x50(r1)stw rv, 0x54(r1)lis r31, value0_3 @ha lfs f6, value0_3 @l(r31) lis r31, - value0_6 @ha lfs f9, value0_6 @l(r31) lis r31, i2fMagic @ha lfd f5, i2fMagic @l(r31) lfs f2, - AXFX_REVHI_WORK.allPassCoeff(rv) lfs f15, AXFX_REVHI_WORK.damping(rv) lfs f8, - AXFX_REVHI_WORK.level(rv) fmuls f3, f8, f9 fsubs f4, f9, f3 slwi r30, k, 1 add r30, r30, - k mulli r31, r30, 0x14 addi r29, rv, AXFX_REVHI_WORK.C add r29, r29, r31 addi r27, rv, - AXFX_REVHI_WORK.AP add r27, r27, r31 slwi r31, r30, 2 add r31, r31, rv lfs f22, - AXFX_REVHI_WORK.combCoef[0](r31) lfs f23, AXFX_REVHI_WORK.combCoef[1](r31) lfs f24, - AXFX_REVHI_WORK.combCoef[2](r31) slwi r31, k, 2 add r31, r31, rv lfs f25, - AXFX_REVHI_WORK.lpLastout[0](r31) lwz r31, AXFX_REVHI_WORK.preDelayTime(rv) lis r30, - 0x4330 stw r30, 0x58(r1)subi r22, r31, 1 slwi r22, r22, 2 slwi r28, k, 2 add r28, r28, - rv cmpwi cr7, r31, 0 lwz r21, - AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] - lwz r20, - AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] - lwz r19, - AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] - lwz r18, - AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] - lwz r17, - AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] - lwz r16, - AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] - lfs f16, - AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] - lfs f17, - AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] - lfs f18, - AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] - lwz r25, - AXFX_REVHI_DELAYLINE.length + 0x00(r29) // C[0] - lwz r24, - AXFX_REVHI_DELAYLINE.length + 0x14(r29) // C[1] - lwz r23, - AXFX_REVHI_DELAYLINE.length + 0x28(r29) // C[2] - lwz r4, - AXFX_REVHI_DELAYLINE.inputs + 0x00(r29) // C[0] - lwz r5, - AXFX_REVHI_DELAYLINE.inputs + 0x14(r29) // C[1] - lwz r6, - AXFX_REVHI_DELAYLINE.inputs + 0x28(r29) // C[2] - lwz r12, - AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] - lwz r11, - AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] - lwz r10, - AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] - lwz r9, - AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] - lwz r8, - AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] - lwz r7, - AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] - lfs f19, - AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] - lfs f20, - AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] - lfs f21, - AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] - lwz r15, - AXFX_REVHI_DELAYLINE.length + 0x00(r27) // AP[0] - lwz r14, - AXFX_REVHI_DELAYLINE.length + 0x14(r27) // AP[1] - //? missing load for length of AP[3]? Maybe intentional? - lwz r30, - 0(r3)xoris r30, r30, 0x8000 stw r30, 0x5c(r1)lfd f12, 0x58(r1)fsubs f12, f12, f5 li r31, - 159 mtctr r31 L_00000964 : fmr f13, - f12 beq cr7, - L_00000994 lwz r30, - AXFX_REVHI_WORK.preDelayLine(r28) lwz r29, - AXFX_REVHI_WORK.preDelayPtr(r28) add r31, - r22, - r30 addi r29, - r29, - 4 lfs f13, - -4(r29)cmpw r29, - r31 stfs f12, - -4(r29)bne + L_00000990 mr r29, - r30 L_00000990 - : stw r29, - AXFX_REVHI_WORK.preDelayPtr(r30) L_00000994 : fmadds f8, - f22, - f16, - f13 lwzu r29, - 4(r3)fmadds f9, - f23, - f17, - f13 stfsx f8, - rv, - r21 addi r21, - r21, - 4 stfsx f9, - k, - r19 lfsx f14, - rv, - r20 addi r20, - r20, - 4 lfsx f17, - k, - r18 cmpw r21, - r25 cmpw cr1, - r20, - r25 addi r19, - r19, - 4 addi r18, - r18, - 4 fmr f16, - f14 cmpw cr5, - r19, - r24 fadds f14, - f14, - f17 cmpw cr6, - r18, - r24 bne + L_000009E0 li r21, - 0 L_000009E0 : fmadds f8, - f24, - f18, - f13 bne + cr1, - L_000009EC li r20, - 0 L_000009EC : stfsx f8, - r6, - r17 addi r17, - r17, - 4 bne + cr5, - L_000009FC li r19, - 0 L_000009FC : lfsx f18, - r6, - r16 addi r16, - r16, - 4 cmpw r17, - r23 bne + cr6, - L_00000A10 li r18, - 0 L_00000A10 - : fadds f14, - f14, - f18 cmpw cr1, - r16, - r23 lwz r26, - AXFX_REVHI_DELAYLINE.inputs(r27) fmadds f9, - f2, - f19, - f14 bne + L_00000A28 li r17, - 0 L_00000A28 : bne + cr1, - L_00000A30 li r16, - 0 L_00000A30 : xoris r29, - r29, - 0x8000 stfsx f9, - r26, - r12 fnmsubs f14, - f2, - f9, - f19 addi r12, - r12, - 4 lfsx f19, - r26, - r11 cmpw cr5, - r12, - r15 addi r11, - r11, - 4 lwz r26, - AXFX_REVHI_DELAYLINE.inputs + 0x14(r27)cmpw cr6, - r11, - r15 fmadds f8, - f2, - f20, - f14 bne + cr5, - L_00000A60 li r12, - 0x0 L_00000A60 : stw r29, - 0x5c(r1)stfsx f8, - r26, - r10 fnmsubs f14, - f2, - f8, - f20 addi r10, - r10, - 4 bne + cr6, - L_00000A78 li r11, - 0 L_00000A78 : lfsx f20, - r26, - r9 cmpw r10, - r14 fmuls f14, - f14, - f6 addi r9, - r9, - 4 cmpw cr1, - r9, - r14 lfd f10, - 0x58(r1)fmadds f14, - f15, - f25, - f14 bne + L_00000A9C li r10, - 0 L_00000A9C - : lwz r26, - AXFX_REVHI_DELAYLINE.inputs + 0x28(r27)fmadds f9, - f2, - f21, - f14 fmr f25, - f14 bne + cr1, - L_00000AB0 li r9, - 0 L_00000AB0 : stfsx f9, - r26, - r8 fnmsubs f14, - f2, - f9, - f21 lwz r31, - AXFX_REVHI_DELAYLINE.length + 0x28(r27)fmuls f8, - f4, - f12 lfsx f21, - r26, - r7 addi r8, - r8, - 4 addi r7, - r7, - 4 fmadds f14, - f3, - f14, - f8 cmpw cr5, - r8, - r31 cmpw cr6, - r7, - r31 fctiwz f14, - f14 bne + cr5, - L_00000AE4 li r8, - 0 L_00000AE4 : bne + cr6, - L_00000AEC li r7, - 0 L_00000AEC : li r31, - -4 fsubs f12, - f10, - f5 stfiwx f14, - sptr, - r31 bdnz L_00000964 fmr f13, - f12 beq cr7, - L_00000B2C lwz r30, - AXFX_REVHI_WORK.preDelayLine(r28) lwz r29, - AXFX_REVHI_WORK.preDelayPtr(r28) add r31, - r22, - r30 addi r29, - r29, - 4 lfs f13, - -4(r29)cmpw r29, - r31 stfs f12, - -4(r29)bne + L_00000B28 mr r29, - r30 L_00000B28 - : stw r29, - AXFX_REVHI_WORK.preDelayPtr(r30) L_00000B2C : fmadds f8, - f22, - f16, - f13 fmadds f9, - f23, - f17, - f13 stfsx f8, - rv, - r21 addi r21, - r21, - 4 stfsx f9, - k, - r19 lfsx f14, - rv, - r20 addi r20, - r20, - 4 lfsx f17, - k, - r18 cmpw r21, - r25 cmpw cr1, - r20, - r25 addi r19, - r19, - 4 addi r18, - r18, - 4 fmr f16, - f14 cmpw cr5, - r19, - r24 fadds f14, - f14, - f17 cmpw cr6, - r18, - r24 bne + L_00000B74 li r21, - 0 L_00000B74 : fmadds f8, - f24, - f18, - f13 bne + cr1, - L_00000B80 li r20, - 0 L_00000B80 : stfsx f8, - r6, - r17 addi r17, - r17, - 4 bne + cr5, - L_00000B90 li r19, - 0 L_00000B90 : lfsx f18, - r6, - r16 addi r16, - r16, - 4 cmpw r17, - r23 bne + cr6, - L_00000BA4 li r18, - 0 L_00000BA4 - : fadds f14, - f14, - f18 cmpw cr1, - r16, - r23 lwz r26, - AXFX_REVHI_DELAYLINE.inputs(r27) fmadds f9, - f2, - f19, - f14 bne + L_00000BBC li r17, - 0 L_00000BBC : bne + cr1, - L_00000BC4 li r16, - 0 L_00000BC4 : stfsx f9, - r26, - r12 fnmsubs f14, - f2, - f9, - f19 addi r12, - r12, - 4 lfsx f19, - r26, - r11 cmpw cr5, - r12, - r15 addi r11, - r11, - 4 lwz r26, - AXFX_REVHI_DELAYLINE.inputs + 0x14(r27)cmpw cr6, - r11, - r15 fmadds f8, - f2, - f20, - f14 bne + cr5, - L_00000BF0 li r12, - 0 L_00000BF0 : stfsx f8, - r26, - r10 fnmsubs f14, - f2, - f8, - f20 addi r10, - r10, - 4 bne + cr6, - L_00000C04 li r11, - 0 L_00000C04 : lfsx f20, - r26, - r9 cmpw r10, - r14 fmuls f14, - f14, - f6 addi r9, - r9, - 4 cmpw cr1, - r9, - r14 fmadds f14, - f15, - f25, - f14 bne + L_00000C24 li r10, - 0 L_00000C24 - : lwz r26, - AXFX_REVHI_DELAYLINE.inputs + 0x28(r27)lwz k, - 0x50(r1)lwz rv, - 0x54(r1)fmadds f9, - f2, - f21, - f14 fmr f25, - f14 bne + cr1, - L_00000C40 li r9, - 0 L_00000C40 : stfsx f9, - r26, - r8 fnmsubs f14, - f2, - f9, - f21 lwz r29, - AXFX_REVHI_DELAYLINE.length + 0x28(r27)fmuls f8, - f4, - f12 lfsx f21, - r26, - r7 addi r8, - r8, - 4 addi r7, - r7, - 4 fmadds f14, - f3, - f14, - f8 cmpw cr5, - r8, - r29 cmpw cr6, - r7, - r29 fctiwz f14, - f14 bne + cr5, - L_00000C74 li r8, - 0 L_00000C74 : bne + cr6, - L_00000C7C li r7, - 0 L_00000C7C : slwi r30, - k, - 1 add r30, - r30, - k mulli r31, - r30, - 0x14 // sizeof AXFX_REVHI_DELAYLINE - stfiwx f14, - r0, - sptr addi r29, - rv, - AXFX_REVHI_WORK.C add r29, - r29, - r31 stw r21, - AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] - stw r20, - AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] - stw r19, - AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] - stw r18, - AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] - stw r17, - AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] - stw r16, - AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] - stfs f16, - AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] - stfs f17, - AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] - stfs f18, - AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] - stw r12, - AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] - stw r11, - AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] - stw r10, - AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] - stw r9, - AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] - stw r8, - AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] - stw r7, - AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] - stfs f19, - AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] - stfs f20, - AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] - stfs f21, - AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] - slwi r31, - k, - 2 add r31, - r31, - rv stfs f25, - AXFX_REVHI_WORK.lpLastout(r31) lfd f14, - 0x60(r1)lfd f15, - 0x68(r1)lfd f16, - 0x70(r1)lfd f17, - 0x78(r1)lfd f18, - 0x80(r1)lfd f19, - 0x88(r1)lfd f20, - 0x90(r1)lfd f21, - 0x98(r1)lfd f22, - 0xa0(r1)lfd f23, - 0xa8(r1)lfd f24, - 0xb0(r1)lfd f25, - 0xb8(r1)lmw r14, - 0x8(r1)addi r1, - r1, - 0xc0 blr -} - -static void ReverbHICallback(s32* left, s32* right, s32* surround, AXFX_REVHI_WORK* rv) -{ - u8 k; - - for (k = 0; k < 3; k++) - { - switch (k) - { - case 0: - if (0.0f != rv->crosstalk) - { - DoCrossTalk(left, right, 0.5f * rv->crosstalk, 1.0f - (0.5f * rv->crosstalk)); - } - HandleReverb(left, rv, 0); - break; - case 1: - HandleReverb(right, rv, 1); - break; - case 2: - HandleReverb(surround, rv, 2); - break; - } - } -} - -static void ReverbHIFree(AXFX_REVHI_WORK* rv) -{ - u8 i; - - for (i = 0; i < 9; i++) - { - if (rv->AP[i].inputs != 0) - { - DLdelete(&rv->AP[i]); - rv->AP[i].inputs = NULL; - } - } - - for (i = 0; i < 9; i++) - { - if (rv->C[i].inputs != 0) - { - DLdelete(&rv->C[i]); - rv->C[i].inputs = NULL; - } - } - - if (rv->preDelayTime) - { - for (i = 0; i < 3; i++) - { - if (rv->preDelayLine[i] != 0) - { - __AXFXFree(rv->preDelayLine[i]); - rv->preDelayLine[i] = NULL; - } - } - } -} - -int AXFXReverbHiInit(AXFX_REVERBHI* rev) -{ - int ret; - BOOL old; - - old = OSDisableInterrupts(); - rev->tempDisableFX = 0; - ret = ReverbHICreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, - rev->preDelay, rev->crosstalk); - OSRestoreInterrupts(old); - return ret; -} - -int AXFXReverbHiShutdown(AXFX_REVERBHI* rev) -{ - BOOL old; - - old = OSDisableInterrupts(); - ReverbHIFree(&rev->rv); - OSRestoreInterrupts(old); - return 1; -} - -int AXFXReverbHiSettings(AXFX_REVERBHI* rev) -{ - int ret; - BOOL old; - - old = OSDisableInterrupts(); - rev->tempDisableFX = 1; - ret = ReverbHIModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, - rev->preDelay, rev->crosstalk); - rev->tempDisableFX = 0; - OSRestoreInterrupts(old); - return ret; -} - -void AXFXReverbHiCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBHI* reverb) -{ - if (reverb->tempDisableFX == 0) - { - ReverbHICallback(bufferUpdate->left, bufferUpdate->right, bufferUpdate->surround, - &reverb->rv); - } -} diff --git a/src/dolphin/base/src/PPCArch.c b/src/dolphin/base/src/PPCArch.c deleted file mode 100644 index 511f102..0000000 --- a/src/dolphin/base/src/PPCArch.c +++ /dev/null @@ -1,292 +0,0 @@ -#include -#include - -asm u32 PPCMfmsr() { - nofralloc - mfmsr r3 - blr -} - -asm void PPCMtmsr(register u32 newMSR) { - nofralloc - mtmsr newMSR - blr -} - -asm u32 PPCOrMsr(register u32 value) { - nofralloc - mfmsr r4 - or value, r4, value - blr -} - -asm u32 PPCAndMsr(register u32 value) { - nofralloc - mfmsr r4 - and value, r4, value - blr -} - -asm u32 PPCAndCMsr(register u32 value) { - nofralloc - mfmsr r4 - andc value, r4, value - blr -} - -asm u32 PPCMfhid0() { - nofralloc - mfspr r3, HID0 - blr -} - -asm void PPCMthid0(register u32 newHID0) { - nofralloc - mtspr HID0, newHID0 - blr -} - -asm u32 PPCMfhid1() { - nofralloc - mfspr r3, HID1 - blr -} - -asm u32 PPCMfl2cr() { - nofralloc - mfspr r3, L2CR - blr -} - -asm void PPCMtl2cr(register u32 newL2cr) { - nofralloc - mtspr L2CR, newL2cr - blr -} - -asm void PPCMtdec(register u32 newDec) { - nofralloc - mtdec newDec - blr -} - -asm u32 PPCMfdec() { - nofralloc - mfdec r3 - blr -} - -asm void PPCSync() { - nofralloc - sc - blr -} - -asm void PPCEieio() { - nofralloc - mfmsr r5 - rlwinm r6, r5, 0, 17, 15 - mtmsr r6 - mfspr r3, HID0 - ori r4, r3, 0x8 - mtspr HID0, r4 - isync - eieio - isync - mtspr HID0, r3 - mtmsr r5 - isync - blr -} - -asm void PPCHalt() { - nofralloc - sync -loop: - nop - li r3, 0 - nop - b loop -} - -asm u32 PPCMfmmcr0() { - nofralloc - mfspr r3, MMCR0 - blr -} - -asm void PPCMtmmcr0(register u32 newMmcr0) { - nofralloc - mtspr MMCR0, newMmcr0 - blr -} - -asm u32 PPCMfmmcr1() { - nofralloc - mfspr r3, MMCR1 - blr -} - -asm void PPCMtmmcr1(register u32 newMmcr1) { - nofralloc - mtspr MMCR1, newMmcr1 - blr -} - -asm u32 PPCMfpmc1() { - nofralloc - mfspr r3, PMC1 - blr -} - -asm void PPCMtpmc1(register u32 newPmc1) { - nofralloc - mtspr PMC1, newPmc1 - blr -} - -asm u32 PPCMfpmc2() { - nofralloc - mfspr r3, PMC2 - blr -} - -asm void PPCMtpmc2(register u32 newPmc2) { - nofralloc - mtspr PMC2, newPmc2 - blr -} - -asm u32 PPCMfpmc3() { - nofralloc - mfspr r3, PMC3 - blr -} - -asm void PPCMtpmc3(register u32 newPmc3) { - nofralloc - mtspr PMC3, newPmc3 - blr -} - -asm u32 PPCMfpmc4() { - nofralloc - mfspr r3, PMC4 - blr -} - -asm void PPCMtpmc4(register u32 newPmc4) { - nofralloc - mtspr PMC4, newPmc4 - blr -} - -asm u32 PPCMfsia() { - nofralloc - mfspr r3, SIA - blr -} - -asm void PPCMtsia(register u32 newSia) { - nofralloc - mtspr SIA, newSia - blr -} - -u32 PPCMffpscr() { - union FpscrUnion m; - - asm { - mffs fp31 - stfd fp31, m.f; - } - - return m.u.fpscr; -} - -void PPCMtfpscr(register u32 newFPSCR) { - union FpscrUnion m; - - asm { - li r4, 0 - stw r4, m.u.fpscr_pad; - stw newFPSCR, m.u.fpscr - lfd fp31, m.f - mtfsf 0xff, fp31 - } -} - -asm u32 PPCMfhid2() { - nofralloc - mfspr r3, HID2 - blr -} - -asm void PPCMthid2(register u32 newhid2) { - nofralloc - mtspr HID2, newhid2 - blr -} - -asm u32 PPCMfwpar() { - nofralloc - sync - mfspr r3, WPAR - blr -} - -asm void PPCMtwpar(register u32 newwpar) { - nofralloc - mtspr WPAR, newwpar - blr -} - -asm u32 PPCMfdmaU() { - nofralloc - mfspr r3, DMA_U - blr -} - -asm u32 PPCMfdmaL() { - nofralloc - mfspr r3, DMA_L - blr -} - -asm void PPCMtdmaU(register u32 newdmau) { - nofralloc - mtspr DMA_U, newdmau - blr -} - -asm void PPCMtdmaL(register u32 newdmal) { - nofralloc - mtspr DMA_L, newdmal - blr -} - -asm u32 PPCMfpvr() { - nofralloc - mfspr r3, PVR - blr -} - -void PPCEnableSpeculation(void) { - PPCMthid0(PPCMfhid0() & ~HID0_SPD); -} - -void PPCDisableSpeculation(void) { - PPCMthid0(PPCMfhid0() | HID0_SPD); -} - -asm void PPCSetFpIEEEMode() { - nofralloc - mtfsb0 29 - blr -} - -asm void PPCSetFpNonIEEEMode() { - nofralloc - mtfsb1 29 - blr -} diff --git a/src/dolphin/base/src/PPCPm.c b/src/dolphin/base/src/PPCPm.c deleted file mode 100644 index d5ffcb4..0000000 --- a/src/dolphin/base/src/PPCPm.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include - -void PMBegin(void) { - PPCMtmmcr0(0); - PPCMtmmcr1(0); - PPCMtpmc1(0); - PPCMtpmc2(0); - PPCMtpmc3(0); - PPCMtpmc4(0); - PPCMtmmcr0(0x4F); - PPCMtmmcr1(0x78800000); -} - -void PMEnd(void) { - PPCMtmmcr0(0); - PPCMtmmcr1(0); -} - -void PMCycles(void) { - PPCMfpmc1(); -} - -void PML1FetchMisses(void) { - PPCMfpmc2(); -} - -void PML1MissCycles(void) { - PPCMfpmc3(); -} - -void PMInstructions(void) { - PPCMfpmc4(); -} diff --git a/src/dolphin/card/src/CARDBios.c b/src/dolphin/card/src/CARDBios.c deleted file mode 100644 index e293456..0000000 --- a/src/dolphin/card/src/CARDBios.c +++ /dev/null @@ -1,856 +0,0 @@ -#include - -#include "__card.h" - -#if DEBUG -const char* __CARDVersion = "<< Dolphin SDK - CARD\tdebug build: Apr 5 2004 03:56:53 (0x2301) >>"; -#else -const char* __CARDVersion = "<< Dolphin SDK - CARD\trelease build: Apr 5 2004 04:15:35 (0x2301) >>"; -#endif - -u32 __CARDFreq = EXI_FREQ_16M; - -CARDControl __CARDBlock[2]; - -static u16 __CARDEncode; -static u16 __CARDFastMode; - -DVDDiskID __CARDDiskNone; - -// prototypes -static void TimeoutHandler(OSAlarm* alarm, OSContext* context); -static void SetupTimeoutAlarm(CARDControl* card); -static s32 Retry(s32 chan); -static void UnlockedCallback(s32 chan, s32 result); -static BOOL OnReset(BOOL f); - -static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127}; - -void __CARDDefaultApiCallback(s32 chan, s32 result) {} - -void __CARDSyncCallback(s32 chan, s32 result) { - CARDControl* card; - card = &__CARDBlock[chan]; - OSWakeupThread(&card->threadQueue); -} - -void __CARDExtHandler(s32 chan, OSContext* context) { - CARDControl* card; - CARDCallback callback; - - ASSERTLINE(232, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (card->attached) { - ASSERTLINE(239, card->txCallback == 0); - card->attached = FALSE; - EXISetExiCallback(chan, 0); - OSCancelAlarm(&card->alarm); - callback = card->exiCallback; - - if (callback) { - card->exiCallback = 0; - callback(chan, CARD_RESULT_NOCARD); - } - - if (card->result != CARD_RESULT_BUSY) { - card->result = CARD_RESULT_NOCARD; - } - - callback = card->extCallback; - if (callback && CARD_MAX_MOUNT_STEP <= card->mountStep) { - card->extCallback = 0; - callback(chan, CARD_RESULT_NOCARD); - } - } -} - -void __CARDExiHandler(s32 chan, OSContext* context) { - CARDControl* card; - CARDCallback callback; - u8 status; - s32 result; - - ASSERTLINE(283, 0 <= chan && chan < 2); - card = &__CARDBlock[chan]; - - OSCancelAlarm(&card->alarm); - - if (!card->attached) { - return; - } - - if (!EXILock(chan, 0, 0)) { - result = CARD_RESULT_FATAL_ERROR; - goto fatal; - } - - if ((result = __CARDReadStatus(chan, &status)) < 0 || (result = __CARDClearStatus(chan)) < 0) { - goto error; - } - - if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == CARD_RESULT_IOERROR && - --card->retry > 0) - { - result = Retry(chan); - if (result >= 0) - { - return; - } - goto fatal; - } - -error: - EXIUnlock(chan); - -fatal: - callback = card->exiCallback; - if (callback) { - card->exiCallback = 0; - callback(chan, result); - } -} - -void __CARDTxHandler(s32 chan, OSContext* context) { - CARDControl* card; - CARDCallback callback; - int err; - - ASSERTLINE(365, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - err = !EXIDeselect(chan); - EXIUnlock(chan); - callback = card->txCallback; - if (callback) { - card->txCallback = NULL; - callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD); - } -} - -void __CARDUnlockedHandler(s32 chan, OSContext* context) { - CARDControl* card; - CARDCallback callback; - - ASSERTLINE(412, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - callback = card->unlockCallback; - if (callback) { - card->unlockCallback = 0; - callback(chan, EXIProbe(chan) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD); - } -} - -s32 __CARDEnableInterrupt(s32 chan, BOOL enable) { - BOOL err; - u32 cmd; - - ASSERTLINE(431, 0 <= chan && chan < 2); - - if (!EXISelect(chan, 0, CARDFreq)) { - return CARD_RESULT_NOCARD; - } - - cmd = enable ? 0x81010000 : 0x81000000; - err = FALSE; - err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); - err |= !EXISync(chan); - err |= !EXIDeselect(chan); - return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; -} - -s32 __CARDReadStatus(s32 chan, u8* status) { - BOOL err; - u32 cmd; - - ASSERTLINE(450, 0 <= chan && chan < 2); - - if (!EXISelect(chan, 0, CARDFreq)) { - return CARD_RESULT_NOCARD; - } - - cmd = 0x83000000; - err = FALSE; - err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); - err |= !EXISync(chan); - err |= !EXIImm(chan, status, 1, EXI_READ, NULL); - err |= !EXISync(chan); - err |= !EXIDeselect(chan); - return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; -} - -int __CARDReadVendorID(s32 chan, u16* id) { - BOOL err; - u32 cmd; - - ASSERTLINE(471, 0 <= chan && chan < 2); - - if (!EXISelect(chan, 0, CARDFreq)) { - return CARD_RESULT_NOCARD; - } - cmd = 0x85000000; - err = 0; - err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, 0); - err |= !EXISync(chan); - err |= !EXIImm(chan, id, 2, EXI_READ, 0); - err |= !EXISync(chan); - err |= !EXIDeselect(chan); - return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; -} - -s32 __CARDClearStatus(s32 chan) { - BOOL err; - u32 cmd; - - ASSERTLINE(492, 0 <= chan && chan < 2); - - if (!EXISelect(chan, 0, CARDFreq)) { - return CARD_RESULT_NOCARD; - } - - cmd = 0x89000000; - err = FALSE; - err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); - err |= !EXISync(chan); - err |= !EXIDeselect(chan); - - return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; -} - -s32 __CARDSleep(s32 chan) { - int err; - u32 cmd; - - ASSERTLINE(511, 0 <= chan && chan < 2); - - if (!EXISelect(chan, 0, CARDFreq)) { - return CARD_RESULT_NOCARD; - } - cmd = 0x88000000; - err = 0; - err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); - err |= !EXISync(chan); - err |= !EXIDeselect(chan); - - if(err) { - return CARD_RESULT_NOCARD; - } - return CARD_RESULT_READY; -} - -s32 __CARDWakeup(s32 chan) { - int err; - u32 cmd; - - ASSERTLINE(530, 0 <= chan && chan < 2); - if (!EXISelect(chan, 0, CARDFreq)) { - return CARD_RESULT_NOCARD; - } - cmd = 0x87000000; - err = 0; - err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); - err |= !EXISync(chan); - err |= !EXIDeselect(chan); - - if(err) { - return CARD_RESULT_NOCARD; - } - return CARD_RESULT_READY; -} - -static void TimeoutHandler(OSAlarm* alarm, OSContext* context) { - s32 chan; - CARDControl* card; - CARDCallback callback; - for (chan = 0; chan < 2; ++chan) { - card = &__CARDBlock[chan]; - if (alarm == &card->alarm) { - break; - } - } - - ASSERTLINE(578, 0 <= chan && chan < 2); - - if (!card->attached) { - return; - } - - EXISetExiCallback(chan, NULL); - callback = card->exiCallback; - if (callback) { - card->exiCallback = 0; - callback(chan, CARD_RESULT_IOERROR); - } -} - -static void SetupTimeoutAlarm(CARDControl* card) { - OSCancelAlarm(&card->alarm); - switch (card->cmd[0]) { - case 0xF2: - OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), - TimeoutHandler); - break; - case 0xF3: - break; - case 0xF4: - if (card->pageSize > 0x80) { - OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->cBlock / 0x40), - TimeoutHandler); - break; - } - case 0xF1: - OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), - TimeoutHandler); - break; - } -} - -static s32 Retry(s32 chan) { - CARDControl* card; - - ASSERTLINE(654, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (!EXISelect(chan, 0, CARDFreq)) { - EXIUnlock(chan); - return CARD_RESULT_NOCARD; - } - - SetupTimeoutAlarm(card); - - if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE)) { - EXIDeselect(chan); - EXIUnlock(chan); - return CARD_RESULT_NOCARD; - } - - if (card->cmd[0] == 0x52 && - !EXIImmEx(chan, (u8* )card->workArea + sizeof(CARDID), card->latency, EXI_WRITE)) - { - EXIDeselect(chan); - EXIUnlock(chan); - return CARD_RESULT_NOCARD; - } - - if (card->mode == 0xffffffff) { - EXIDeselect(chan); - EXIUnlock(chan); - return CARD_RESULT_READY; - } - - if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : card->pageSize), card->mode, - __CARDTxHandler)) - { - EXIDeselect(chan); - EXIUnlock(chan); - return CARD_RESULT_NOCARD; - } - - return CARD_RESULT_READY; -} - -static void UnlockedCallback(s32 chan, s32 result) { - CARDCallback callback; - CARDControl* card; - - ASSERTLINE(718, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (result >= 0) { - card->unlockCallback = UnlockedCallback; - if (!EXILock(chan, 0, __CARDUnlockedHandler)) { - result = CARD_RESULT_READY; - } else { - card->unlockCallback = 0; - result = Retry(chan); - } - } - - if (result < 0) { - switch (card->cmd[0]) { - case 0x52: - callback = card->txCallback; - if (callback) { - card->txCallback = NULL; - callback(chan, result); - } - break; - case 0xF2: - case 0xF4: - case 0xF1: - callback = card->exiCallback; - if (callback) { - card->exiCallback = 0; - callback(chan, result); - } - break; - } - } -} - -static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback) { - BOOL enabled; - CARDControl* card; - s32 result; - - enabled = OSDisableInterrupts(); - - ASSERTLINE(784, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (!card->attached) { - result = CARD_RESULT_NOCARD; - } else { - if (txCallback) { - card->txCallback = txCallback; - } - - if (exiCallback) { - card->exiCallback = exiCallback; - } - - card->unlockCallback = UnlockedCallback; - - if (!EXILock(chan, 0, __CARDUnlockedHandler)) { - result = CARD_RESULT_BUSY; - } else { - card->unlockCallback = 0; - - if (!EXISelect(chan, 0, CARDFreq)) { - EXIUnlock(chan); - result = CARD_RESULT_NOCARD; - } else { - SetupTimeoutAlarm(card); - result = CARD_RESULT_READY; - } - } - } - - OSRestoreInterrupts(enabled); - return result; -} - -#define AD1(x) ((u8)(((x) >> 17) & 0x7f)) -#define AD1EX(x) ((u8)(AD1(x) | 0x80)); -#define AD2(x) ((u8)(((x) >> 9) & 0xff)) -#define AD3(x) ((u8)(((x) >> 7) & 0x03)) -#define BA(x) ((u8)((x)&0x7f)) - -s32 __CARDReadSegment(s32 chan, CARDCallback callback) { - CARDControl* card; - s32 result; - - ASSERTLINE(846, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - ASSERTLINE(848, card->addr % CARD_SEG_SIZE == 0); - ASSERTLINE(849, card->addr < (u32) card->size * 1024 * 1024 / 8); - - card->cmd[0] = 0x52; - card->cmd[1] = AD1(card->addr); - card->cmd[2] = AD2(card->addr); - card->cmd[3] = AD3(card->addr); - card->cmd[4] = BA(card->addr); - card->cmdlen = 5; - card->mode = 0; - card->retry = 0; - - result = __CARDStart(chan, callback, 0); - if (result == CARD_RESULT_BUSY) { - result = CARD_RESULT_READY; - } else if (result >= 0) { - if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE) || - !EXIImmEx(chan, (u8* )card->workArea + sizeof(CARDID), card->latency, - EXI_WRITE) || // XXX use DMA if possible - !EXIDma(chan, card->buffer, 512, card->mode, __CARDTxHandler)) - { - card->txCallback = NULL; - EXIDeselect(chan); - EXIUnlock(chan); - result = CARD_RESULT_NOCARD; - } else { - result = CARD_RESULT_READY; - } - } - - return result; -} - -s32 __CARDWritePage(s32 chan, CARDCallback callback) { - CARDControl* card; - s32 result; - - ASSERTLINE(903, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - ASSERTLINE(905, card->addr % card->pageSize == 0); - ASSERTLINE(906, card->addr < (u32) card->size * 1024 * 1024 / 8); - card->cmd[0] = 0xF2; - - if (card->pageSize > 0x80) { - card->cmd[1] = AD1(card->addr) | 0x80; - } else { - card->cmd[1] = AD1(card->addr); - } - - card->cmd[2] = AD2(card->addr); - card->cmd[3] = AD3(card->addr); - card->cmd[4] = BA(card->addr); - card->cmdlen = 5; - card->mode = 1; - card->retry = 3; - - result = __CARDStart(chan, 0, callback); - if (result == CARD_RESULT_BUSY) { - result = CARD_RESULT_READY; - } else if (result >= 0) { - if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE) || - !EXIDma(chan, card->buffer, card->pageSize, card->mode, __CARDTxHandler)) - { - card->exiCallback = 0; - EXIDeselect(chan); - EXIUnlock(chan); - result = CARD_RESULT_NOCARD; - } else { - result = CARD_RESULT_READY; - } - } - - return result; -} - -s32 __CARDErase(s32 chan, CARDCallback callback) { - CARDControl* card; - s32 result; - - ASSERTLINE(962, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - card->cmd[0] = 0xF4; - card->cmd[1] = 0; - card->cmd[2] = 0; - card->cmdlen = 3; - card->mode = -1; - card->retry = 3; - result = __CARDStart(chan, 0, callback); - if (result == CARD_RESULT_BUSY) { - result = CARD_RESULT_READY; - } else if (result >= 0) { - if (EXIImmEx(chan, &card->cmd, card->cmdlen, EXI_WRITE) == 0) { - result = CARD_RESULT_NOCARD; - card->exiCallback = 0; - } else { - result = CARD_RESULT_READY; - } - - EXIDeselect(chan); - EXIUnlock(chan); - } - - return result; -} - -s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) { - CARDControl* card; - s32 result; - - ASSERTLINE(1010, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - ASSERTLINE(1012, addr % card->sectorSize == 0); - ASSERTLINE(1013, addr < (u32) card->size * 1024 * 1024 / 8); - - if (card->pageSize > 0x80) { - if (callback) { - callback(chan, 0); - } - return 0; - } - - card->cmd[0] = 0xF1; - card->cmd[1] = AD1(addr); - card->cmd[2] = AD2(addr); - card->cmdlen = 3; - card->mode = -1; - card->retry = 3; - - result = __CARDStart(chan, 0, callback); - - if (result == CARD_RESULT_BUSY) { - result = CARD_RESULT_READY; - } else if (result >= 0) { - if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE)) { - result = CARD_RESULT_NOCARD; - card->exiCallback = NULL; - } else { - result = CARD_RESULT_READY; - } - - EXIDeselect(chan); - EXIUnlock(chan); - } - return result; -} - -void CARDInit(void) { - int chan; - - if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) { - return; - } - - __CARDEncode = OSGetFontEncode(); - - OSRegisterVersion(__CARDVersion); - - DSPInit(); - OSInitAlarm(); - - for (chan = 0; chan < 2; ++chan) { - CARDControl* card = &__CARDBlock[chan]; - - card->result = CARD_RESULT_NOCARD; - OSInitThreadQueue(&card->threadQueue); - OSCreateAlarm(&card->alarm); - } - __CARDSetDiskID((void*)OSPhysicalToCached(0)); - - OSRegisterResetFunction(&ResetFunctionInfo); -} - -u16 __CARDGetFontEncode(void) { - return __CARDEncode; -} - -u16 __CARDSetFontEncode(u16 encode) { - u16 prev = __CARDEncode; - - switch (encode) { - case CARD_ENCODE_ANSI: - case CARD_ENCODE_SJIS: - __CARDEncode = encode; - break; - } - - return prev; -} - -void __CARDSetDiskID(const DVDDiskID* id) { - __CARDBlock[0].diskID = id ? id : &__CARDDiskNone; - __CARDBlock[1].diskID = id ? id : &__CARDDiskNone; -} - -const DVDDiskID* CARDGetDiskID(s32 chan) { - ASSERTLINE(1168, 0 <= chan && chan < 2); - return __CARDBlock[chan].diskID; -} - -s32 CARDSetDiskID(s32 chan, const DVDDiskID* diskID) { - BOOL enabled; - CARDControl* card; - - card = &__CARDBlock[chan]; - ASSERTLINE(1189, 0 <= chan && chan < 2); - - enabled = OSDisableInterrupts(); - - if (card->result == CARD_RESULT_BUSY) { - return CARD_RESULT_BUSY; - } - - card->diskID = diskID != 0 ? diskID : (const DVDDiskID*)OSPhysicalToCached(0); - OSRestoreInterrupts(enabled); - return 0; -} - -s32 __CARDGetControlBlock(s32 chan, CARDControl** pcard) { - BOOL enabled; - s32 result; - CARDControl* card; - - card = &__CARDBlock[chan]; - - if (chan < 0 || chan >= 2 || card->diskID == 0) { - return CARD_RESULT_FATAL_ERROR; - } - - enabled = OSDisableInterrupts(); - - if (!card->attached) { - result = CARD_RESULT_NOCARD; - } else if (card->result == CARD_RESULT_BUSY) { - result = CARD_RESULT_BUSY; - } else { - card->result = CARD_RESULT_BUSY; - result = CARD_RESULT_READY; - card->apiCallback = NULL; - *pcard = card; - } - - OSRestoreInterrupts(enabled); - return result; -} - -s32 __CARDPutControlBlock(CARDControl* card, s32 result) { - BOOL enabled; - - ASSERTLINE(1259, result != CARD_RESULT_BUSY); - - enabled = OSDisableInterrupts(); - if (card->attached) { - card->result = result; - } else if (card->result == CARD_RESULT_BUSY) { - card->result = result; - } - - OSRestoreInterrupts(enabled); - return result; -} - -s32 CARDGetResultCode(s32 chan) { - CARDControl* card; - - ASSERTLINE(1292, 0 <= chan && chan < 2); - - if (chan < 0 || chan >= 2) { - return CARD_RESULT_FATAL_ERROR; - } - card = &__CARDBlock[chan]; - return card->result; -} - -s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed) { - CARDControl* card; - s32 result; - u16* fat; - CARDDir* dir; - CARDDir* ent; - u16 fileNo; - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return result; - } - - fat = __CARDGetFatBlock(card); - dir = __CARDGetDirBlock(card); - if (fat == 0 || dir == 0) { - return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); - } - - if (byteNotUsed) { - *byteNotUsed = (s32)(card->sectorSize * fat[CARD_FAT_FREEBLOCKS]); - } - - if (filesNotUsed) { - *filesNotUsed = 0; - for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { - ent = &dir[fileNo]; - if (ent->fileName[0] == 0xff) { - ++*filesNotUsed; - } - } - } - - return __CARDPutControlBlock(card, CARD_RESULT_READY); -} - -s32 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 CARDGetMemSize(s32 chan, u16* size) { - CARDControl* card; - s32 result; - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return result; - } - - *size = card->size; - return __CARDPutControlBlock(card, CARD_RESULT_READY); -} - -s32 CARDGetSectorSize(s32 chan, u32* size) { - CARDControl* card; - s32 result; - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return result; - } - - *size = card->sectorSize; - return __CARDPutControlBlock(card, CARD_RESULT_READY); -} - -s32 __CARDSync(s32 chan) { - CARDControl* block; - s32 result; - s32 enabled; - - block = &__CARDBlock[chan]; - enabled = OSDisableInterrupts(); - while ((result = CARDGetResultCode(chan)) == CARD_RESULT_BUSY) { - OSSleepThread(&block->threadQueue); - } - - OSRestoreInterrupts(enabled); - return result; -} - -static BOOL OnReset(BOOL final) { - if (!final) { - if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) { - return FALSE; - } - } - - return TRUE; -} - -BOOL CARDSetFastMode(BOOL enable) { - u16 prev = __CARDFastMode; - __CARDFastMode = enable ? TRUE : FALSE; - - return prev ? TRUE : FALSE; -} - -BOOL CARDGetFastMode(void) { - return __CARDFastMode ? TRUE : FALSE; -} - -s32 CARDGetCurrentMode(s32 chan, u32* mode) { - CARDControl* card; - s32 result; - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return result; - } - - switch (card->pageSize) { - case 512: - *mode = 1; - break; - case 128: - default: - *mode = 0; - break; - } - - return __CARDPutControlBlock(card, CARD_RESULT_READY); -} diff --git a/src/dolphin/card/src/CARDBlock.c b/src/dolphin/card/src/CARDBlock.c deleted file mode 100644 index b7af255..0000000 --- a/src/dolphin/card/src/CARDBlock.c +++ /dev/null @@ -1,160 +0,0 @@ -#include - -#include "__card.h" - -// prototypes -static void WriteCallback(s32 chan, s32 result); -static void EraseCallback(s32 chan, s32 result); - -void* __CARDGetFatBlock(CARDControl* card) { - ASSERTLINE(57, card->currentFat); - return card->currentFat; -} - -static void WriteCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - u16* fat0; - u16* fat1; - - card = &__CARDBlock[chan]; - - if (result >= 0) { - fat0 = (u16*)((u8*)card->workArea + 0x6000); - fat1 = (u16*)((u8*)card->workArea + 0x8000); - - ASSERTLINE(82, card->currentFat); - if (card->currentFat == fat0) { - card->currentFat = fat1; - memcpy(fat1, fat0, 0x2000); - } else { - ASSERTLINE(90, card->currentFat == fat1); - card->currentFat = fat0; - memcpy(fat0, fat1, 0x2000); - } - } - - if (!card->apiCallback) - __CARDPutControlBlock(card, result); - - callback = card->eraseCallback; - if (callback) { - card->eraseCallback = NULL; - callback(chan, result); - } -} - -static void EraseCallback(s32 chan, s32 result) { - CARDControl* card = &__CARDBlock[chan]; - CARDCallback callback; - u16* fat; - u32 addr; - - if (result < 0) - goto error; - - fat = __CARDGetFatBlock(card); - addr = ((u32)fat - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize; - result = __CARDWrite(chan, addr, CARD_SYSTEM_BLOCK_SIZE, fat, WriteCallback); - if (result < 0) - goto error; - - return; - -error: - if (!card->apiCallback) - __CARDPutControlBlock(card, result); - - callback = card->eraseCallback; - if (callback) { - card->eraseCallback = NULL; - callback(chan, result); - } -} - -s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback) { - CARDControl* card; - u16* fat; - u16 iBlock; - u16 startBlock; - u16 prevBlock; - u16 count; - - ASSERTLINE(182, 0 < cBlock); - ASSERTLINE(183, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (!card->attached) - return CARD_RESULT_NOCARD; - - fat = __CARDGetFatBlock(card); - if (fat[3] < cBlock) - return CARD_RESULT_INSSPACE; - - fat[3] -= cBlock; - startBlock = 0xFFFF; - iBlock = fat[4]; - count = 0; - while (0 < cBlock) { - if (card->cBlock - 5 < ++count) - return CARD_RESULT_BROKEN; - - iBlock++; - if (!CARDIsValidBlockNo(card, iBlock)) - iBlock = 5; - - if (fat[iBlock] == 0x0000u) { - if (startBlock == 0xFFFF) - startBlock = iBlock; - else - fat[prevBlock] = iBlock; - prevBlock = iBlock; - fat[iBlock] = 0xFFFF; - --cBlock; - } - } - - fat[4] = iBlock; - card->startBlock = startBlock; - return __CARDUpdateFatBlock(chan, fat, callback); -} - -s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback) { - CARDControl* card; - u16* fat; - u16 nextBlock; - - ASSERTLINE(253, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (!card->attached) - return CARD_RESULT_NOCARD; - - fat = __CARDGetFatBlock(card); - while (nBlock != 0xFFFF) { - if (!CARDIsValidBlockNo(card, nBlock)) - return CARD_RESULT_BROKEN; - - nextBlock = fat[nBlock]; - fat[nBlock] = 0; - nBlock = nextBlock; - ++fat[3]; - } - - return __CARDUpdateFatBlock(chan, fat, callback); -} - -s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback) { - CARDControl* card; - u32 addr; - - ASSERTLINE(295, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - ++fat[2]; - __CARDCheckSum(fat + 2, 0x1FFC, fat, fat + 1); - DCStoreRange(fat, 0x2000); - card->eraseCallback = callback; - addr = (((char*)fat - (char*)card->workArea) / 8192u) * card->sectorSize; - return __CARDEraseSector(chan, addr, EraseCallback); -} diff --git a/src/dolphin/card/src/CARDCheck.c b/src/dolphin/card/src/CARDCheck.c deleted file mode 100644 index 4a9b78c..0000000 --- a/src/dolphin/card/src/CARDCheck.c +++ /dev/null @@ -1,343 +0,0 @@ -#include - -#include "os/__os.h" -#include "__card.h" - -// prototypes -static s32 VerifyID(CARDControl* card); -static s32 VerifyDir(CARDControl* card, int* pcurrent); -static s32 VerifyFAT(CARDControl* card, int* pcurrent); - -void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv) { - u16* p; - int i; - - ASSERTLINE(82, length % sizeof(u16) == 0); - - length /= sizeof(u16); - *checksum = *checksumInv = 0; - for (i = 0, p = ptr; i < length; i++, p++) { - *checksum += *p; - *checksumInv += ~*p; - } - - if (*checksum == 0xFFFF) - *checksum = 0; - - if (*checksumInv == 0xFFFF) - *checksumInv = 0; -} - -static s32 VerifyID(CARDControl* card) { - CARDID* id; - u16 checksum; - u16 checksumInv; - OSSramEx* sramEx; - OSTime rand; - int i; - - id = card->workArea; - - if (id->deviceID != 0 || id->size != card->size) - return CARD_RESULT_BROKEN; - - __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &checksum, &checksumInv); - if (id->checkSum != checksum || id->checkSumInv != checksumInv) - return CARD_RESULT_BROKEN; - - rand = *(OSTime*)&id->serial[12]; - sramEx = __OSLockSramEx(); - for (i = 0; i < 12; i++) { - rand = (rand * 1103515245 + 12345) >> 16; - if (id->serial[i] != (u8)(sramEx->flashID[card - __CARDBlock][i] + rand)) { - __OSUnlockSramEx(FALSE); - return CARD_RESULT_BROKEN; - } - rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF; - } - - __OSUnlockSramEx(FALSE); - - if (id->encode != __CARDGetFontEncode()) - return CARD_RESULT_ENCODING; - - return CARD_RESULT_READY; -} - -static s32 VerifyDir(CARDControl* card, int* pcurrent) { - CARDDir* dir[2]; - CARDDirCheck* check[2]; - u16 checkSum; - u16 checkSumInv; - int i; - int errors; - int current; - - current = errors = 0; - for (i = 0; i < 2; i++) { - dir[i] = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); - check[i] = CARDGetDirCheck(dir[i]); - __CARDCheckSum(dir[i], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv); - if (check[i]->checkSum != checkSum || check[i]->checkSumInv != checkSumInv) { - ++errors; - current = i; - card->currentDir = 0; - } - } - - if (0 == errors) { - if (card->currentDir == 0) { - if ((check[0]->checkCode - check[1]->checkCode) < 0) - current = 0; - else - current = 1; - card->currentDir = dir[current]; - memcpy(dir[current], dir[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); - } else { - current = (card->currentDir == dir[0]) ? 0 : 1; - } - } - - if (pcurrent) - *pcurrent = current; - - return errors; -} - -static s32 VerifyFAT(CARDControl* card, int* pcurrent) { - u16* fat[2]; - u16* fatp; - u16 nBlock; - u16 cFree; - int i; - u16 checkSum; - u16 checkSumInv; - int errors; - int current; - - current = errors = 0; - for (i = 0; i < 2; i++) { - fatp = fat[i] = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE); - - __CARDCheckSum(&fatp[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv); - if (fatp[CARD_FAT_CHECKSUM] != checkSum || fatp[CARD_FAT_CHECKSUMINV] != checkSumInv) { - ++errors; - current = i; - card->currentFat = 0; - continue; - } - - cFree = 0; - for (nBlock = CARD_NUM_SYSTEM_BLOCK; nBlock < card->cBlock; nBlock++) { - if (fatp[nBlock] == CARD_FAT_AVAIL) - cFree++; - } - - if (cFree != fatp[CARD_FAT_FREEBLOCKS]) { - ++errors; - current = i; - card->currentFat = 0; - continue; - } - } - - if (0 == errors) { - if (card->currentFat == 0) { - if (((s16)fat[0][CARD_FAT_CHECKCODE] - (s16)fat[1][CARD_FAT_CHECKCODE]) < 0) - current = 0; - else - current = 1; - card->currentFat = fat[current]; - memcpy(fat[current], fat[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); - } else - current = (card->currentFat == fat[0]) ? 0 : 1; - } - - if (pcurrent) - *pcurrent = current; - - return errors; -} - -s32 __CARDVerify(CARDControl* card) { - s32 result; - int errors; - - result = VerifyID(card); - if (result < 0) - return result; - - errors = VerifyDir(card, NULL); - errors += VerifyFAT(card, NULL); - switch (errors) { - case 0: - ASSERTLINE(301, card->currentDir); - ASSERTLINE(302, card->currentFat); - return CARD_RESULT_READY; - case 1: - return CARD_RESULT_BROKEN; - default: - return CARD_RESULT_BROKEN; - } -} - -s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) { - CARDControl* card; - CARDDir* dir[2]; - u16* fat[2]; - u16* map; - s32 result; - int errors; - int currentFat; - int currentDir; - s32 fileNo; - u16 iBlock; - u16 cBlock; - u16 cFree; - BOOL updateFat = FALSE; - BOOL updateDir = FALSE; - BOOL updateOrphan = FALSE; - - ASSERTLINE(346, 0 <= chan && chan < 2); - - if (xferBytes) { - *xferBytes = 0; - } - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return result; - } - - result = VerifyID(card); - if (result < 0) { - return __CARDPutControlBlock(card, result); - } - - errors = VerifyDir(card, ¤tDir); - errors += VerifyFAT(card, ¤tFat); - if (1 < errors) { - return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); - } - - dir[0] = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE); - dir[1] = (CARDDir*)((u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE); - fat[0] = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE); - fat[1] = (u16*)((u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE); - - ASSERTLINE(377, errors == 0 || errors == 1); - - switch (errors) { - case 0: - ASSERTLINE(381, card->currentDir); - ASSERTLINE(382, card->currentFat); - break; - case 1: - if (!card->currentDir) { - ASSERTLINE(387, card->currentFat); - card->currentDir = dir[currentDir]; - memcpy(dir[currentDir], dir[currentDir ^ 1], CARD_SYSTEM_BLOCK_SIZE); - updateDir = TRUE; - } else { - ASSERTLINE(394, !card->currentFat); - card->currentFat = fat[currentFat]; - memcpy(fat[currentFat], fat[currentFat ^ 1], CARD_SYSTEM_BLOCK_SIZE); - updateFat = TRUE; - } - break; - } - - map = fat[currentFat ^ 1]; - memset(map, 0, CARD_SYSTEM_BLOCK_SIZE); - - for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { - CARDDir* ent; - - ent = &card->currentDir[fileNo]; - if (ent->gameName[0] == 0xff) { - continue; - } - - for (iBlock = ent->startBlock, cBlock = 0; iBlock != 0xFFFF && cBlock < ent->length; - iBlock = card->currentFat[iBlock], ++cBlock) - { - if (!CARDIsValidBlockNo(card, iBlock) || 1 < ++map[iBlock]) { - return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); - } - } - - if (cBlock != ent->length || iBlock != 0xFFFF) { - return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); - } - } - - cFree = 0; - for (iBlock = CARD_NUM_SYSTEM_BLOCK; iBlock < card->cBlock; iBlock++) { - u16 nextBlock; - - nextBlock = card->currentFat[iBlock]; - if (map[iBlock] == 0) { - if (nextBlock != CARD_FAT_AVAIL) { - card->currentFat[iBlock] = CARD_FAT_AVAIL; - updateOrphan = TRUE; - } - cFree++; - } else if (!CARDIsValidBlockNo(card, nextBlock) && nextBlock != 0xFFFF) { - return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); - } - } - - if (cFree != card->currentFat[CARD_FAT_FREEBLOCKS]) { - card->currentFat[CARD_FAT_FREEBLOCKS] = cFree; - updateOrphan = TRUE; - } - - if (updateOrphan) { - __CARDCheckSum(&card->currentFat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), - &card->currentFat[CARD_FAT_CHECKSUM], - &card->currentFat[CARD_FAT_CHECKSUMINV]); - } - - memcpy(fat[currentFat ^ 1], fat[currentFat], CARD_SYSTEM_BLOCK_SIZE); - - if (updateDir) { - if (xferBytes) { - *xferBytes = CARD_SYSTEM_BLOCK_SIZE; - } - return __CARDUpdateDir(chan, callback); - } - - if (updateFat | updateOrphan) { - if (xferBytes) { - *xferBytes = CARD_SYSTEM_BLOCK_SIZE; - } - return __CARDUpdateFatBlock(chan, card->currentFat, callback); - } - - __CARDPutControlBlock(card, CARD_RESULT_READY); - if (callback) { - BOOL enabled = OSDisableInterrupts(); - callback(chan, CARD_RESULT_READY); - OSRestoreInterrupts(enabled); - } - return CARD_RESULT_READY; -} - -s32 CARDCheckAsync(s32 chan, CARDCallback callback) { - s32 xferBytes; - return CARDCheckExAsync(chan, &xferBytes, callback); -} - -s32 CARDCheckEx(s32 chan, s32* xferBytes) { - s32 result = CARDCheckExAsync(chan, xferBytes, __CARDSyncCallback); - if (result < 0 || xferBytes == 0) { - return result; - } - - return __CARDSync(chan); -} - -s32 CARDCheck(s32 chan) { - s32 xferBytes; - return CARDCheckEx(chan, &xferBytes); -} diff --git a/src/dolphin/card/src/CARDCreate.c b/src/dolphin/card/src/CARDCreate.c deleted file mode 100644 index 7da5ab0..0000000 --- a/src/dolphin/card/src/CARDCreate.c +++ /dev/null @@ -1,126 +0,0 @@ -#include - -#include "__card.h" - -// prototypes -static void CreateCallbackFat(s32 chan, s32 result); - -static void CreateCallbackFat(s32 chan, s32 result) { - CARDControl* card; - CARDDir* dir; - CARDDir* ent; - CARDCallback callback; - - card = &__CARDBlock[chan]; - callback = card->apiCallback; - card->apiCallback = NULL; - - if (result >= 0) { - dir = __CARDGetDirBlock(card); - ent = &dir[card->freeNo]; - memcpy(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)); - memcpy(ent->company, card->diskID->company, sizeof(ent->company)); - ent->permission = 4; - ent->copyTimes = 0; - - ASSERTLINE(111, CARDIsValidBlockNo(card, card->startBlock)); - ent->startBlock = (u16)card->startBlock; - ent->bannerFormat = 0; - ent->iconAddr = -1; - ent->iconFormat = 0; - ent->iconSpeed = 0; - ent->commentAddr = -1; - - CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST); - card->fileInfo->offset = 0; - card->fileInfo->iBlock = ent->startBlock; - ent->time = OSTicksToSeconds(OSGetTime()); - result = __CARDUpdateDir(chan, callback); - if (result < 0) { - goto after; - } - } else { -after:; - __CARDPutControlBlock(card, result); - if (callback) { - callback(chan, result); - } - } -} - -s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback) { - CARDControl* card; - CARDDir* dir; - CARDDir* ent; - u16 fileNo; - u16 freeNo; - u16* fat; - s32 result; - - ASSERTLINE(175, 0 <= chan && chan < 2); - ASSERTLINE(176, strlen(fileName) <= CARD_FILENAME_MAX); - - if (strlen(fileName) > (u32)CARD_FILENAME_MAX) { - return CARD_RESULT_NAMETOOLONG; - } - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return result; - } - - ASSERTLINE(188, 0 < size && (size % card->sectorSize) == 0); - - if (size <= 0 || (size % card->sectorSize) != 0) { - return CARD_RESULT_FATAL_ERROR; - } - - freeNo = (u16)-1; - dir = __CARDGetDirBlock(card); - for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { - ent = &dir[fileNo]; - if (ent->gameName[0] == 0xff) { - if (freeNo == (u16)-1) { - freeNo = fileNo; - } - } else if (memcmp(ent->gameName, card->diskID->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((char*)ent->fileName, fileName, CARD_FILENAME_MAX); - - card->fileInfo = fileInfo; - fileInfo->chan = chan; - fileInfo->fileNo = freeNo; - - result = __CARDAllocBlock(chan, size / card->sectorSize, CreateCallbackFat); - if (result < 0) { - return __CARDPutControlBlock(card, result); - } - return result; -} - -s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo) { - s32 result = CARDCreateAsync(chan, fileName, size, fileInfo, __CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(chan); -} diff --git a/src/dolphin/card/src/CARDDir.c b/src/dolphin/card/src/CARDDir.c deleted file mode 100644 index e154a9c..0000000 --- a/src/dolphin/card/src/CARDDir.c +++ /dev/null @@ -1,89 +0,0 @@ -#include - -#include "__card.h" - -// prototypes -static void WriteCallback(s32 chan, s32 result); -static void EraseCallback(s32 chan, s32 result); - -CARDDir* __CARDGetDirBlock(CARDControl* card) { - ASSERTLINE(54, card->currentDir); - return card->currentDir; -} - -static void WriteCallback(s32 chan, s32 result) { - CARDControl* card = &__CARDBlock[chan]; - CARDCallback callback; - - if (result >= 0) { - CARDDir* dir0 = (CARDDir*)((u8*)card->workArea + 0x2000); - CARDDir* dir1 = (CARDDir*)((u8*)card->workArea + 0x4000); - - ASSERTLINE(79, card->currentDir); - - if (card->currentDir == dir0) { - card->currentDir = dir1; - memcpy(dir1, dir0, 0x2000); - } else { - ASSERTLINE(87, card->currentDir == dir1); - card->currentDir = dir0; - memcpy(dir0, dir1, 0x2000); - } - } - - if (!card->apiCallback) - __CARDPutControlBlock(card, result); - - callback = card->eraseCallback; - if (callback) { - card->eraseCallback = NULL; - callback(chan, result); - } -} - -static void EraseCallback(s32 chan, s32 result) { - CARDControl* card = &__CARDBlock[chan]; - CARDCallback callback; - CARDDir* dir; - u32 addr; - - if (result >= 0) { - dir = __CARDGetDirBlock(card); - addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; - result = __CARDWrite(chan, addr, 0x2000, dir, WriteCallback); - if (result >= 0) - return; - } - - if (!card->apiCallback) - __CARDPutControlBlock(card, result); - - callback = card->eraseCallback; - if (callback) { - card->eraseCallback = NULL; - callback(chan, result); - } -} - -s32 __CARDUpdateDir(s32 chan, CARDCallback callback) { - CARDControl* card; - CARDDirCheck* check; - u32 addr; - CARDDir* dir; - - ASSERTLINE(173, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (!card->attached) - return CARD_RESULT_NOCARD; - - dir = __CARDGetDirBlock(card); - check = CARDGetDirCheck(dir); - ++check->checkCode; - __CARDCheckSum(dir, 0x2000 - sizeof(u32), &check->checkSum, &check->checkSumInv); - DCStoreRange(dir, 0x2000); - - card->eraseCallback = callback; - addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; - return __CARDEraseSector(chan, addr, EraseCallback); -} diff --git a/src/dolphin/card/src/CARDErase.c b/src/dolphin/card/src/CARDErase.c deleted file mode 100644 index 73bb8ef..0000000 --- a/src/dolphin/card/src/CARDErase.c +++ /dev/null @@ -1,102 +0,0 @@ -#include - -#include "__card.h" - -static void EraseCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - u16* fat; - CARDDir* dir; - CARDDir* ent; - CARDFileInfo* fileInfo; - - card = &__CARDBlock[chan]; - - if (result >= 0) { - fileInfo = card->fileInfo; - if (fileInfo->length < 0) { - result = CARD_RESULT_CANCELED; - goto error; - } - - fileInfo->length -= card->sectorSize; - if (fileInfo->length <= 0) { - dir = __CARDGetDirBlock(card); - ent = dir + fileInfo->fileNo; - ent->time = OSTicksToSeconds(OSGetTime()); - callback = card->apiCallback; - card->apiCallback = NULL; - - result = __CARDUpdateDir(chan, callback); - } else { - fat = __CARDGetFatBlock(card); - fileInfo->offset += card->sectorSize; - fileInfo->iBlock = fat[fileInfo->iBlock]; - - if (fileInfo->iBlock < 5 || fileInfo->iBlock >= card->cBlock) { - result = CARD_RESULT_BROKEN; - goto error; - } - - result = __CARDEraseSector(chan, card->sectorSize * fileInfo->iBlock, EraseCallback); - } - - if (result < 0) { - goto error; - } - return; - } - -error: - callback = card->apiCallback; - card->apiCallback = NULL; - __CARDPutControlBlock(card, result); - ASSERTLINE(98, callback); - callback(chan, result); -} - -s32 CARDEraseAsync(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDCallback callback) { - CARDControl* card; - s32 result; - CARDDir* dir; - CARDDir* ent; - - ASSERTLINE(132, 0 < length); - - result = __CARDSeek(fileInfo, length, offset, &card); - if (result < 0) { - return result; - } - - ASSERTLINE(138, OFFSET(offset, card->sectorSize) == 0); - ASSERTLINE(139, OFFSET(length, card->sectorSize) == 0); - - if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) { - return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); - } - - dir = __CARDGetDirBlock(card); - ent = dir + fileInfo->fileNo; - result = __CARDIsWritable(card, ent); - if (result < 0) { - return __CARDPutControlBlock(card, result); - } - - card->apiCallback = callback ? callback : __CARDDefaultApiCallback; - - result = __CARDEraseSector(fileInfo->chan, card->sectorSize * fileInfo->iBlock, EraseCallback); - if (result < 0) { - __CARDPutControlBlock(card, result); - } - - return result; -} - -s32 CARDErase(CARDFileInfo* fileInfo, s32 length, s32 offset) { - s32 result = CARDEraseAsync(fileInfo, length, offset, __CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(fileInfo->chan); -} diff --git a/src/dolphin/card/src/CARDFormat.c b/src/dolphin/card/src/CARDFormat.c deleted file mode 100644 index 7bcc76d..0000000 --- a/src/dolphin/card/src/CARDFormat.c +++ /dev/null @@ -1,137 +0,0 @@ -#include - -#include "os/__os.h" -#include "__card.h" - -static void FormatCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - - card = &__CARDBlock[chan]; - if (result < 0) - goto error; - - ++card->formatStep; - if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) { - result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); - if (result >= 0) - return; - } else if (card->formatStep < 2 * CARD_NUM_SYSTEM_BLOCK) { - int step = card->formatStep - CARD_NUM_SYSTEM_BLOCK; - result = __CARDWrite(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, - (u8* )card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), FormatCallback); - if (result >= 0) - return; - } else { - card->currentDir = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE); - memcpy(card->currentDir, (u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE, CARD_SYSTEM_BLOCK_SIZE); - card->currentFat = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE); - memcpy(card->currentFat, (u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE, CARD_SYSTEM_BLOCK_SIZE); - } - -error: - callback = card->apiCallback; - card->apiCallback = NULL; - __CARDPutControlBlock(card, result); - ASSERTLINE(133, callback); - callback(chan, result); -} - -s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { - CARDControl* card; - CARDID* id; - CARDDir* dir; - u16* fat; - s16 i; - s32 result; - OSSram* sram; - OSSramEx* sramEx; - u16 dvdstatus; - OSTime time; - OSTime rand; - - ASSERTLINE(167, encode == CARD_ENCODE_ANSI || encode == CARD_ENCODE_SJIS); - ASSERTLINE(168, 0 <= chan && chan < 2); - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) - return result; - - id = (CARDID*)card->workArea; - memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE); - dvdstatus = __VIRegs[55]; - - id->encode = encode; - sram = __OSLockSram(); - *(u32*)&id->serial[20] = sram->counterBias; - *(u32*)&id->serial[24] = sram->language; - __OSUnlockSram(FALSE); - - rand = time = OSGetTime(); - - sramEx = __OSLockSramEx(); - for (i = 0; i < 12; i++) { - rand = (rand * 1103515245 + 12345) >> 16; - id->serial[i] = (u8)(sramEx->flashID[chan][i] + rand); - rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF; - } - __OSUnlockSramEx(FALSE); - - *(u32*)&id->serial[28] = dvdstatus; - *(OSTime*)&id->serial[12] = time; - - id->deviceID = 0; - id->size = card->size; - __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &id->checkSum, &id->checkSumInv); - - for (i = 0; i < 2; i++) { - CARDDirCheck* check; - - dir = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); - memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE); - check = CARDGetDirCheck(dir); - check->checkCode = i; - __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum, &check->checkSumInv); - } - - for (i = 0; i < 2; i++) { - fat = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE); - memset(fat, 0x00, CARD_SYSTEM_BLOCK_SIZE); - fat[CARD_FAT_CHECKCODE] = (u16)i; - fat[CARD_FAT_FREEBLOCKS] = (u16)(card->cBlock - CARD_NUM_SYSTEM_BLOCK); - fat[CARD_FAT_LASTSLOT] = CARD_NUM_SYSTEM_BLOCK - 1; - __CARDCheckSum(&fat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &fat[CARD_FAT_CHECKSUM], - &fat[CARD_FAT_CHECKSUMINV]); - } - - card->apiCallback = callback ? callback : __CARDDefaultApiCallback; - DCStoreRange(card->workArea, CARD_WORKAREA_SIZE); - - card->formatStep = 0; - result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); - if (result < 0) - __CARDPutControlBlock(card, result); - return result; -} - -s32 __CARDFormatRegion(s32 chan, u16 encode) { - s32 result = __CARDFormatRegionAsync(chan, encode, &__CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(chan); -} - -s32 CARDFormatAsync(s32 chan, CARDCallback callback) { - return __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), callback); -} - -s32 CARDFormat(s32 chan) { - s32 result = __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), &__CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(chan); -} diff --git a/src/dolphin/card/src/CARDMount.c b/src/dolphin/card/src/CARDMount.c deleted file mode 100644 index 4ca607d..0000000 --- a/src/dolphin/card/src/CARDMount.c +++ /dev/null @@ -1,394 +0,0 @@ -#include -#include - -#include "os/__os.h" -#include "__card.h" - -static u32 SectorSizeTable[8] = { - 8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024, 256 * 1024, 0, 0, -}; - -static u32 LatencyTable[8] = { - 4, 8, 16, 32, 64, 128, 256, 512, -}; - -// prototypes -static s32 DoMount(s32 chan); -static void DoUnmount(s32 chan, s32 result); - -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; -} - -void __CARDDisable(BOOL disable) { - BOOL enabled = OSDisableInterrupts(); - - __gUnknown800030E3 &= ~0x80; - if (disable) { - __gUnknown800030E3 |= 0x80; - } - - OSRestoreInterrupts(enabled); -} - -int CARDProbe(s32 chan) { - if (__gUnknown800030E3 & 0x80) { - return 0; - } else { - return EXIProbe(chan); - } -} - -s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) { - u32 id; - CARDControl* card; - BOOL enabled; - s32 result; - int probe; - - if (chan < 0 || 2 <= chan) - return CARD_RESULT_FATAL_ERROR; - - if (__gUnknown800030E3 & 0x80) { - return CARD_RESULT_NOCARD; - } - - card = &__CARDBlock[chan]; - enabled = OSDisableInterrupts(); - - probe = EXIProbeEx(chan); - if (probe == -1) - result = CARD_RESULT_NOCARD; - else if (probe == 0) - result = CARD_RESULT_BUSY; - else if (card->attached) { - if (card->mountStep < 1) - result = CARD_RESULT_BUSY; - else { - if (memSize) - *memSize = card->size; - - if (sectorSize) - *sectorSize = card->sectorSize; - - result = CARD_RESULT_READY; - } - } - else if ((EXIGetState(chan) & 8)) - result = CARD_RESULT_WRONGDEVICE; - else if (!EXIGetID(chan, 0, &id)) - result = CARD_RESULT_BUSY; - else if (IsCard(id)) { - if (memSize) - *memSize = (s32)(id & 0xfc); - - if (sectorSize) - *sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; - result = CARD_RESULT_READY; - } else { - result = CARD_RESULT_WRONGDEVICE; - } - - OSRestoreInterrupts(enabled); - return result; -} - -static s32 DoMount(s32 chan) { - CARDControl* card; - u32 id; - u8 status; - s32 result; - OSSramEx* sram; - int i; - u8 checkSum; - int step; - - ASSERTLINE(399, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (card->mountStep == 0) { - if (EXIGetID(chan, 0, &id) == 0) { - result = CARD_RESULT_NOCARD; - } else if (IsCard(id)) { - result = CARD_RESULT_READY; - } else { - result = CARD_RESULT_WRONGDEVICE; - } - - if (result < 0) - goto error; - - card->cid = id; - card->size = (u16)(id & 0xFC); - ASSERTLINE(424, card->size); - - card->sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; - ASSERTLINE(426, card->sectorSize); - - card->cBlock = (u16)((card->size * 1024 * 1024 / 8) / card->sectorSize); - ASSERTLINE(428, 8 <= card->cBlock); - - card->latency = LatencyTable[(id & 0x00000700) >> 8]; - - result = __CARDReadVendorID(chan, &card->vendorID); - if (result < 0) - goto error; - - if (CARDGetFastMode() && (card->vendorID >> 8) == 0xEC) { - card->pageSize = 512; - } else { - card->pageSize = 128; - } - - result = __CARDClearStatus(chan); - if (result < 0) - goto error; - - result = __CARDReadStatus(chan, &status); - if (result < 0) - goto error; - - if (!EXIProbe(chan)) { - result = CARD_RESULT_NOCARD; - goto error; - } - - if (!(status & 0x40)) { - result = __CARDUnlock(chan, card->id); - if (result < 0) - goto error; - - checkSum = 0; - sram = __OSLockSramEx(); - for (i = 0; i < 12; i++) { - sram->flashID[chan][i] = card->id[i]; - checkSum += card->id[i]; - } - sram->flashIDCheckSum[chan] = (u8)~checkSum; - __OSUnlockSramEx(TRUE); - - return result; - } else { - card->mountStep = 1; - - checkSum = 0; - sram = __OSLockSramEx(); - for (i = 0; i < 12; i++) - checkSum += sram->flashID[chan][i]; - - __OSUnlockSramEx(FALSE); - if (sram->flashIDCheckSum[chan] != (u8)~checkSum) { - result = CARD_RESULT_IOERROR; - goto error; - } - } - } - - if (card->mountStep == 1) { - if (card->cid == 0x80000004) { - u16 vendorID; - - sram = __OSLockSramEx(); - vendorID = *(u16*)sram->flashID[chan]; - __OSUnlockSramEx(FALSE); - - if (__CARDVendorID == 0xFFFF || vendorID != __CARDVendorID) { - result = CARD_RESULT_WRONGDEVICE; - goto error; - } - } - - card->mountStep = 2; - - result = __CARDEnableInterrupt(chan, TRUE); - if (result < 0) - goto error; - - EXISetExiCallback(chan, __CARDExiHandler); - EXIUnlock(chan); - DCInvalidateRange(card->workArea, CARD_WORKAREA_SIZE); - } - - step = card->mountStep - 2; - result = __CARDRead(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, - (u8 *)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), __CARDMountCallback); - if (result < 0) - __CARDPutControlBlock(card, result); - return result; - -error: - EXIUnlock(chan); - DoUnmount(chan, result); - return result; -} - -void __CARDMountCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - - ASSERTLINE(570, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - switch (result) { - case CARD_RESULT_READY: - if (++card->mountStep < CARD_MAX_MOUNT_STEP) { - result = DoMount(chan); - if (0 <= result) - return; - } else - result = __CARDVerify(card); - break; - case CARD_RESULT_UNLOCKED: - card->unlockCallback = __CARDMountCallback; - if (!EXILock(chan, 0, __CARDUnlockedHandler)) { - return; - } - card->unlockCallback = 0; - - result = DoMount(chan); - if (result >= 0) - return; - break; - case CARD_RESULT_IOERROR: - case CARD_RESULT_NOCARD: - DoUnmount(chan, result); - break; - } - - callback = card->apiCallback; - card->apiCallback = NULL; - __CARDPutControlBlock(card, result); - ASSERTLINE(620, callback); - callback(chan, result); -} - -s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback) { - CARDControl* card; - BOOL enabled; - - ASSERTLINE(652, workArea && ((u32) workArea % 32 == 0)); - ASSERTLINE(653, 0 <= chan && chan < 2); - - if (chan < 0 || 2 <= chan) - return CARD_RESULT_FATAL_ERROR; - - if (__gUnknown800030E3 & 0x80) { - return CARD_RESULT_NOCARD; - } - - card = &__CARDBlock[chan]; - - enabled = OSDisableInterrupts(); - if (card->result == CARD_RESULT_BUSY) { - OSRestoreInterrupts(enabled); - return CARD_RESULT_BUSY; - } - - if (!card->attached && (EXIGetState(chan) & 0x08)) { - OSRestoreInterrupts(enabled); - return CARD_RESULT_WRONGDEVICE; - } - - card->result = CARD_RESULT_BUSY; - card->workArea = workArea; - card->extCallback = detachCallback; - card->apiCallback = attachCallback ? attachCallback : __CARDDefaultApiCallback; - card->exiCallback = 0; - - if (!card->attached && !EXIAttach(chan, __CARDExtHandler)) { - card->result = CARD_RESULT_NOCARD; - OSRestoreInterrupts(enabled); - return CARD_RESULT_NOCARD; - } - - card->mountStep = 0; - card->attached = TRUE; - EXISetExiCallback(chan, 0); - OSCancelAlarm(&card->alarm); - - card->currentDir = 0; - card->currentFat = 0; - - OSRestoreInterrupts(enabled); - - card->unlockCallback = __CARDMountCallback; - if (!EXILock(chan, 0, __CARDUnlockedHandler)) - return CARD_RESULT_READY; - - card->unlockCallback = 0; - return DoMount(chan); -} - -s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback) { - s32 result = CARDMountAsync(chan, workArea, detachCallback, __CARDSyncCallback); - - if (result < 0) - return result; - return __CARDSync(chan); -} - -static void DoUnmount(s32 chan, s32 result) { - CARDControl* card; - BOOL enabled; - - ASSERTLINE(758, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - enabled = OSDisableInterrupts(); - if (card->attached) { - EXISetExiCallback(chan, 0); - EXIDetach(chan); - OSCancelAlarm(&card->alarm); - card->attached = FALSE; - card->result = result; - card->mountStep = 0; - } - OSRestoreInterrupts(enabled); -} - -s32 CARDUnmount(s32 chan) { - CARDControl* card; - s32 result; - - ASSERTLINE(793, 0 <= chan && chan < 2); - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) - return result; - - DoUnmount(chan, CARD_RESULT_NOCARD); - return CARD_RESULT_READY; -} diff --git a/src/dolphin/card/src/CARDNet.c b/src/dolphin/card/src/CARDNet.c deleted file mode 100644 index 5f43d3b..0000000 --- a/src/dolphin/card/src/CARDNet.c +++ /dev/null @@ -1,138 +0,0 @@ -#include - -#include "os/__os.h" -#include "__card.h" - -u16 __CARDVendorID = 0xFFFF; -u8 __CARDPermMask = 0x1C; - -u16 CARDSetVendorID(u16 vendorID) { - u16 prevID = __CARDVendorID; - __CARDVendorID = vendorID; - - return prevID; -} - -u16 CARDGetVendorID() { - return __CARDVendorID; -} - -s32 CARDGetSerialNo(s32 chan, u64* serialNo) { - CARDControl* card; - s32 result; - CARDID* id; - u64 code; - int i; - - ASSERTLINE(105, 0 <= chan && chan < 2); - - if (!(0 <= chan && chan < 2)) { - return CARD_RESULT_FATAL_ERROR; - } - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return result; - } - - id = (CARDID*)card->workArea; - for (code = 0, i = 0; i < sizeof(id->serial) / sizeof(u64); ++i) { - code ^= *(u64*)&id->serial[sizeof(u64) * i]; - } - *serialNo = code; - - return __CARDPutControlBlock(card, CARD_RESULT_READY); -} - -s32 CARDGetUniqueCode(s32 chan, u64* uniqueCode) { - CARDControl* card; - s32 result; - OSSramEx* sram; - - ASSERTLINE(146, 0 <= chan && chan < 2); - - if (!(0 <= chan && chan < 2)) { - return CARD_RESULT_FATAL_ERROR; - } - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return result; - } - - sram = __OSLockSramEx(); - memcpy(uniqueCode, &sram->flashID[chan][4], 8); - __OSUnlockSramEx(0); - return __CARDPutControlBlock(card, CARD_RESULT_READY); -} - -s32 CARDGetAttributes(s32 chan, s32 fileNo, u8* attr) { - CARDDir dirent; - s32 result; - - result = __CARDGetStatusEx(chan, fileNo, &dirent); - if (result == 0) { - *attr = dirent.permission; - } - - return result; -} - -#define CARDCheckAttr(attr, flag) ((u32)(attr & flag) != 0) - -s32 CARDSetAttributesAsync(s32 chan, s32 fileNo, u8 attr, CARDCallback callback) { - CARDDir dirent; - s32 result; - - if (attr & ~__CARDPermMask) { - return CARD_RESULT_NOPERM; - } - - result = __CARDGetStatusEx(chan, fileNo, &dirent); - if (result < 0) { - return result; - } - - if ((CARDCheckAttr(dirent.permission, 0x20) && !CARDCheckAttr(attr, 0x20)) || (CARDCheckAttr(dirent.permission, 0x40) && !CARDCheckAttr(attr, 0x40))) { - return CARD_RESULT_NOPERM; - } - - if ((CARDCheckAttr(attr, 0x20) && CARDCheckAttr(attr, 0x40)) || (CARDCheckAttr(attr, 0x20) && CARDCheckAttr(dirent.permission, 0x40)) || (CARDCheckAttr(attr, 0x40) && CARDCheckAttr(dirent.permission, 0x20))) { - return CARD_RESULT_NOPERM; - } - - dirent.permission = attr; - return __CARDSetStatusExAsync(chan, fileNo, &dirent, callback); -} - -s32 CARDSetAttributes(s32 chan, s32 fileNo, u8 attr) { - s32 result; - - result = CARDSetAttributesAsync(chan, fileNo, attr, __CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(chan); -} - -static int __CARDEnablePerm(u8 perm, BOOL enable) { - int prev; - prev = __CARDPermMask & perm ? TRUE : FALSE; - - if (enable) { - __CARDPermMask |= perm; - } else { - __CARDPermMask &= ~perm; - } - - return prev; -} - -int __CARDEnableGlobal(BOOL enable) { - return __CARDEnablePerm(0x20, enable); -} - -int __CARDEnableCompany(BOOL enable) { - return __CARDEnablePerm(0x40, enable); -} diff --git a/src/dolphin/card/src/CARDOpen.c b/src/dolphin/card/src/CARDOpen.c deleted file mode 100644 index bd86568..0000000 --- a/src/dolphin/card/src/CARDOpen.c +++ /dev/null @@ -1,174 +0,0 @@ -#include - -#include "__card.h" - -BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName) { - char* entName = (char*)ent->fileName; - char c1; - char c2; - int n = CARD_FILENAME_MAX; - - while (--n >= 0) { - if ((c1 = *entName++) != (c2 = *fileName++)) - return FALSE; - else if (c2 == '\0') - return TRUE; - } - - if (*fileName == '\0') - return TRUE; - return FALSE; -} - -s32 __CARDAccess(CARDControl* card, CARDDir* ent) { - const DVDDiskID* diskID = card->diskID; - - if (ent->gameName[0] == 0xFF) - return CARD_RESULT_NOFILE; - - if (diskID == &__CARDDiskNone - || (memcmp(ent->gameName, diskID->gameName, sizeof(ent->gameName)) == 0 - && memcmp(ent->company, diskID->company, sizeof(ent->company)) == 0)) - return CARD_RESULT_READY; - - return CARD_RESULT_NOPERM; -} - -s32 __CARDIsWritable(CARDControl* card, CARDDir* ent) { - const DVDDiskID* diskID = card->diskID; - s32 result; - u8 perm; - - result = __CARDAccess(card, ent); - if (result == CARD_RESULT_NOPERM) { - perm = ent->permission & __CARDPermMask; - if (perm & 0x20 && (memcmp(ent->gameName, __CARDDiskNone.gameName, sizeof(ent->gameName)) == 0 && - memcmp(ent->company, __CARDDiskNone.company, sizeof(ent->company)) == 0)) - { - return CARD_RESULT_READY; - } else if (perm & 0x40 && (memcmp(ent->gameName, __CARDDiskNone.gameName, sizeof(ent->gameName)) == 0 && - memcmp(ent->company, diskID->company, sizeof(ent->company)) == 0)) - { - return CARD_RESULT_READY; - } - } - - return result; -} - -s32 __CARDIsReadable(CARDControl* card, CARDDir* ent) { - s32 result = __CARDIsWritable(card, ent); - if (result == CARD_RESULT_NOPERM && (ent->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; - - ASSERTLINE(278, 0 <= fileNo && fileNo < CARD_MAX_FILE); - ASSERTLINE(279, 0 <= chan && chan < 2); - - if (fileNo < 0 || fileNo >= CARD_MAX_FILE) - return CARD_RESULT_FATAL_ERROR; - - fileInfo->chan = -1; - result = __CARDGetControlBlock(chan, &card); - if (result < 0) - 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; - s32 fileNo; - s32 result; - CARDDir* dir; - CARDDir* ent; - - ASSERTLINE(336, 0 <= chan && chan < 2); - - fileInfo->chan = -1; - result = __CARDGetControlBlock(chan, &card); - if (result < 0) - return result; - - result = __CARDGetFileNo(card, fileName, &fileNo); - if (result >= 0) { - dir = __CARDGetDirBlock(card); - ent = &dir[fileNo]; - if (!CARDIsValidBlockNo(card, ent->startBlock)) - result = CARD_RESULT_BROKEN; - else { - fileInfo->chan = chan; - fileInfo->fileNo = fileNo; - fileInfo->offset = 0; - fileInfo->iBlock = ent->startBlock; - } - } - - return __CARDPutControlBlock(card, result); -} - -s32 CARDClose(CARDFileInfo* fileInfo) { - CARDControl* card; - s32 result; - - ASSERTLINE(380, 0 <= fileInfo->chan && fileInfo->chan < 2); - ASSERTLINE(381, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE); - - result = __CARDGetControlBlock(fileInfo->chan, &card); - if (result < 0) - return result; - - fileInfo->chan = -1; - return __CARDPutControlBlock(card, CARD_RESULT_READY); -} - -BOOL __CARDIsOpened(CARDControl* card, s32 fileNo) { - return FALSE; -} diff --git a/src/dolphin/card/src/CARDProgram.c b/src/dolphin/card/src/CARDProgram.c deleted file mode 100644 index 2e60377..0000000 --- a/src/dolphin/card/src/CARDProgram.c +++ /dev/null @@ -1,100 +0,0 @@ -#include - -#include "__card.h" - -#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) -#define CARD_PROGRAM_SIZE 128 - -static void ProgramCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - u16* fat; - CARDFileInfo* fileInfo; - s32 length; - - card = &__CARDBlock[chan]; - - if (result >= 0) { - fileInfo = card->fileInfo; - if (fileInfo->length < 0) { - result = CARD_RESULT_CANCELED; - goto error; - } - - length = TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; - fileInfo->length -= length; - if (fileInfo->length > 0) { - fat = __CARDGetFatBlock(card); - fileInfo->offset += length; - fileInfo->iBlock = fat[fileInfo->iBlock]; - - if (fileInfo->iBlock < 5 || fileInfo->iBlock >= card->cBlock) { - result = CARD_RESULT_BROKEN; - goto error; - } - - ASSERTLINE(94, OFFSET(fileInfo->length, CARD_PROGRAM_SIZE) == 0); - ASSERTLINE(95, OFFSET(fileInfo->offset, card->sectorSize) == 0); - - result = __CARDWrite(chan, card->sectorSize * fileInfo->iBlock, fileInfo->length < card->sectorSize ? fileInfo->length : card->sectorSize, card->buffer, ProgramCallback); - if (result >= 0) { - return; - } - } - } - -error: - callback = card->apiCallback; - card->apiCallback = NULL; - __CARDPutControlBlock(card, result); - ASSERTLINE(114, callback); - callback(chan, result); -} - -s32 CARDProgramAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { - CARDControl* card; - s32 result; - CARDDir* dir; - CARDDir* ent; - - ASSERTLINE(147, buf && OFFSET(buf, 32) == 0); - ASSERTLINE(148, OFFSET(offset, CARD_PROGRAM_SIZE) == 0); - ASSERTLINE(149, 0 < length && OFFSET(length, CARD_PROGRAM_SIZE) == 0); - - if (offset & 0x7F || length & 0x7F) { - return CARD_RESULT_FATAL_ERROR; - } - - result = __CARDSeek(fileInfo, length, offset, &card); - if (result < 0) { - return result; - } - - dir = __CARDGetDirBlock(card); - ent = &dir[fileInfo->fileNo]; - result = __CARDIsWritable(card, ent); - if (result < 0) { - return __CARDPutControlBlock(card, result); - } - - DCStoreRange(buf, length); - - card->apiCallback = callback ? callback : &__CARDDefaultApiCallback; - offset = fileInfo->offset & (card->sectorSize - 1); - length = length < (card->sectorSize - offset) ? length : card->sectorSize - offset; - - result = __CARDWrite(fileInfo->chan, offset + (card->sectorSize * fileInfo->iBlock), length, buf, ProgramCallback); - if (result < 0) { - __CARDPutControlBlock(card, result); - } - - return result; -} - -s32 CARDProgram(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { - s32 result = CARDProgramAsync(fileInfo, buf, length, offset, __CARDSyncCallback); - if (result < 0) - return result; - - return __CARDSync(fileInfo->chan); -} diff --git a/src/dolphin/card/src/CARDRaw.c b/src/dolphin/card/src/CARDRaw.c deleted file mode 100644 index 584a9be..0000000 --- a/src/dolphin/card/src/CARDRaw.c +++ /dev/null @@ -1,82 +0,0 @@ -#include - -#include "__card.h" - -s32 __CARDRawReadAsync(s32 chan, void* buf, s32 length, s32 offset, CARDCallback callback) { - CARDControl* card; - s32 result; - - ASSERTLINE(59, buf && ((u32) buf % 32) == 0); - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return __CARDPutControlBlock(card, result); - } - - ASSERTLINE(67, 0 < length && (length % CARD_SEG_SIZE) == 0 && length < CARD_MAX_SIZE); - ASSERTLINE(68, (offset % card->sectorSize) == 0); - - DCInvalidateRange(buf, length); - result = __CARDRead(chan, offset, length, buf, callback); - if (result < 0) { - __CARDPutControlBlock(card, result); - } - return result; -} - -s32 __CARDRawRead(s32 chan, void* buf, s32 length, s32 offset) { - s32 result = __CARDRawReadAsync(chan, buf, length, offset, __CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(chan); -} - -static void EraseCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - - card = &__CARDBlock[chan]; - callback = card->apiCallback; - card->apiCallback = NULL; - - __CARDPutControlBlock(card, result); - - ASSERTLINE(117, callback); - callback(chan, result); -} - -s32 __CARDRawEraseAsync(s32 chan, s32 offset, CARDCallback callback) { - CARDControl* card; - s32 result; - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) { - return __CARDPutControlBlock(card, result); - } - - if (offset % card->sectorSize) { - return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); - } - - if ((card->size * 1024 * 1024) / 8 <= offset) { - return __CARDPutControlBlock(card, CARD_RESULT_LIMIT); - } - - card->apiCallback = callback ? callback : __CARDDefaultApiCallback; - result = __CARDEraseSector(chan, offset, EraseCallback); - if (result < 0) { - __CARDPutControlBlock(card, result); - } - return result; -} - -s32 __CARDRawErase(s32 chan, s32 offset) { - s32 result = __CARDRawEraseAsync(chan, offset, __CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(chan); -} diff --git a/src/dolphin/card/src/CARDRdwr.c b/src/dolphin/card/src/CARDRdwr.c deleted file mode 100644 index 8350f57..0000000 --- a/src/dolphin/card/src/CARDRdwr.c +++ /dev/null @@ -1,105 +0,0 @@ -#include - -#include "__card.h" - -// prototypes -static void BlockReadCallback(s32 chan, s32 result); -static void BlockWriteCallback(s32 chan, s32 result); - -static void BlockReadCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - - card = &__CARDBlock[chan]; - - if ((result >= 0)) { - card->xferred += 0x200; - card->addr += 0x200; - ((u8*)card->buffer) += 0x200; - - if (--card->repeat > 0) { - result = __CARDReadSegment(chan, BlockReadCallback); - if (result >= 0) { - return; - } - } - } - - if (!card->apiCallback) { - __CARDPutControlBlock(card, result); - } - - callback = card->xferCallback; - if (callback) { - card->xferCallback = NULL; - callback(chan, result); - } -} - -s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) { - CARDControl* card; - - ASSERTLINE(91, 0 < length && length % CARD_SEG_SIZE == 0); - ASSERTLINE(92, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (card->attached == 0) { - return CARD_RESULT_NOCARD; - } - card->xferCallback = callback; - card->repeat = (length / 512u); - card->addr = addr; - card->buffer = dst; - return __CARDReadSegment(chan, BlockReadCallback); -} - -static void BlockWriteCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - - card = &__CARDBlock[chan]; - if (result >= 0) { - card->xferred += card->pageSize; - card->addr += card->pageSize; - ((u8*)card->buffer) += card->pageSize; - - if (--card->repeat > 0) { - result = __CARDWritePage(chan, BlockWriteCallback); - if (result >= 0) { - return; - } - } - } - - if (!card->apiCallback) { - __CARDPutControlBlock(card, result); - } - - callback = card->xferCallback; - if (callback) { - card->xferCallback = NULL; - callback(chan, result); - } -} - -s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) { - CARDControl* card; - card = &__CARDBlock[chan]; - - ASSERTLINE(153, 0 < length && length % card->pageSize == 0); - ASSERTLINE(154, 0 <= chan && chan < 2); - - if (card->attached == 0) { - return CARD_RESULT_NOCARD; - } - card->xferCallback = callback; - card->repeat = (length / card->pageSize); - card->addr = addr; - card->buffer = dst; - return __CARDWritePage(chan, BlockWriteCallback); -} - -s32 CARDGetXferredBytes(s32 chan) { - ASSERTLINE(183, 0 <= chan && chan < 2); - return __CARDBlock[chan].xferred; -} diff --git a/src/dolphin/card/src/CARDRead.c b/src/dolphin/card/src/CARDRead.c deleted file mode 100644 index 74bd544..0000000 --- a/src/dolphin/card/src/CARDRead.c +++ /dev/null @@ -1,174 +0,0 @@ -#include - -#include "__card.h" - -#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) - -// prototypes -static void ReadCallback(s32 chan, s32 result); - -s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard) { - CARDControl* card; - CARDDir* dir; - CARDDir* ent; - s32 result; - u16* fat; - - ASSERTLINE(98, 0 <= fileInfo->chan && fileInfo->chan < 2); - ASSERTLINE(99, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE); - - result = __CARDGetControlBlock(fileInfo->chan, &card); - if (result < 0) - return result; - - ASSERTLINE(106, CARDIsValidBlockNo(card, fileInfo->iBlock)); - ASSERTLINE(107, fileInfo->offset < card->cBlock * card->sectorSize); - - if (!CARDIsValidBlockNo(card, fileInfo->iBlock) || card->cBlock * card->sectorSize <= fileInfo->offset) - return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); - - dir = __CARDGetDirBlock(card); - ent = &dir[fileInfo->fileNo]; - - ASSERTLINE(117, ent->gameName[0] != 0xff); - - if (ent->length * card->sectorSize <= offset || ent->length * card->sectorSize < offset + length) - return __CARDPutControlBlock(card, CARD_RESULT_LIMIT); - - card->fileInfo = fileInfo; - fileInfo->length = length; - if (offset < fileInfo->offset) { - fileInfo->offset = 0; - fileInfo->iBlock = ent->startBlock; - if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) - return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); - } - - fat = __CARDGetFatBlock(card); - while (fileInfo->offset < TRUNC(offset, card->sectorSize)) { - fileInfo->offset += card->sectorSize; - fileInfo->iBlock = fat[fileInfo->iBlock]; - if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) - return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); - } - - fileInfo->offset = offset; - - *pcard = card; - return CARD_RESULT_READY; -} - -static void ReadCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - u16* fat; - CARDFileInfo* fileInfo; - s32 length; - - card = &__CARDBlock[chan]; - if (result < 0) - goto error; - - fileInfo = card->fileInfo; - if (fileInfo->length < 0) { - result = CARD_RESULT_CANCELED; - goto error; - } - - length = TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; - fileInfo->length -= length; - if (fileInfo->length <= 0) - goto error; - - fat = __CARDGetFatBlock(card); - fileInfo->offset += length; - fileInfo->iBlock = fat[fileInfo->iBlock]; - if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { - result = CARD_RESULT_BROKEN; - goto error; - } - - ASSERTLINE(199, OFFSET(fileInfo->length, CARD_SEG_SIZE) == 0); - ASSERTLINE(200, OFFSET(fileInfo->offset, card->sectorSize) == 0); - - result = __CARDRead(chan, card->sectorSize * (u32)fileInfo->iBlock, - (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize, card->buffer, - ReadCallback); - if (result < 0) - goto error; - - return; - -error: - callback = card->apiCallback; - card->apiCallback = NULL; - __CARDPutControlBlock(card, result); - ASSERTLINE(217, callback); - callback(chan, result); -} - -s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { - CARDControl* card; - s32 result; - CARDDir* dir; - CARDDir* ent; - - ASSERTLINE(250, buf && OFFSET(buf, 32) == 0); - ASSERTLINE(251, OFFSET(offset, CARD_SEG_SIZE) == 0); - ASSERTLINE(252, 0 < length && OFFSET(length, CARD_SEG_SIZE) == 0); - - if (OFFSET(offset, CARD_SEG_SIZE) != 0 || OFFSET(length, CARD_SEG_SIZE) != 0) - return CARD_RESULT_FATAL_ERROR; - - result = __CARDSeek(fileInfo, length, offset, &card); - if (result < 0) - return result; - - dir = __CARDGetDirBlock(card); - ent = &dir[fileInfo->fileNo]; - result = __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* buf, s32 length, s32 offset) { - s32 result = CARDReadAsync(fileInfo, buf, length, offset, __CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(fileInfo->chan); -} - -s32 CARDCancel(CARDFileInfo* fileInfo) { - BOOL enabled; - s32 result; - CARDControl* card; - - ASSERTLINE(338, 0 <= fileInfo->chan && fileInfo->chan < 2); - ASSERTLINE(339, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE); - - enabled = OSDisableInterrupts(); - - card = &__CARDBlock[fileInfo->chan]; - result = CARD_RESULT_READY; - if (!card->attached) - result = CARD_RESULT_NOCARD; - else if (card->result == CARD_RESULT_BUSY && card->fileInfo == fileInfo) { - fileInfo->length = -1; - result = CARD_RESULT_CANCELED; - } - - OSRestoreInterrupts(enabled); - return result; -} diff --git a/src/dolphin/card/src/CARDRename.c b/src/dolphin/card/src/CARDRename.c deleted file mode 100644 index 0a76aca..0000000 --- a/src/dolphin/card/src/CARDRename.c +++ /dev/null @@ -1,70 +0,0 @@ -#include - -#include "__card.h" - -s32 CARDRenameAsync(s32 chan, const char* old, const char* new, CARDCallback callback) { - CARDControl* card; - CARDDir* dir; - CARDDir* ent; - s32 result; - int fileNo; - int newNo; - int oldNo; - - ASSERTLINE(0x56, 0 <= chan && chan < 2); - ASSERTLINE(0x57, *old != 0xff && *new != 0xff); - ASSERTLINE(0x58, *old != 0x00 && *new != 0x00); - - if (old[0] == 0xFF || new[0] == 0xFF || old[0] == 0 || new[0] == 0) - return CARD_RESULT_FATAL_ERROR; - if (CARD_FILENAME_MAX < (u32)strlen(old) || CARD_FILENAME_MAX < (u32)strlen(new)) - return CARD_RESULT_NAMETOOLONG; - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) - return result; - - newNo = oldNo = -1; - dir = __CARDGetDirBlock(card); - for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { - ent = &dir[fileNo]; - if (ent->gameName[0] == 0xFF) - continue; - - if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) != 0 - || memcmp(ent->company, card->diskID->company, sizeof(ent->company)) != 0) - continue; - - if (__CARDCompareFileName(ent, old)) - oldNo = fileNo; - if (__CARDCompareFileName(ent, new)) - newNo = fileNo; - } - - if (oldNo == -1) - return __CARDPutControlBlock(card, CARD_RESULT_NOFILE); - if (newNo != -1) - return __CARDPutControlBlock(card, CARD_RESULT_EXIST); - - ent = &dir[oldNo]; - result = __CARDIsWritable(card, ent); - if (result < 0) - return __CARDPutControlBlock(card, result); - - strncpy((char*)ent->fileName, new, CARD_FILENAME_MAX); - ent->time = (u32)OSTicksToSeconds(OSGetTime()); - - result = __CARDUpdateDir(chan, callback); - if (result < 0) - __CARDPutControlBlock(card, result); - - return result; -} - -s32 CARDRename(s32 chan, const char* old, const char* new) { - s32 result = CARDRenameAsync(chan, old, new, __CARDSyncCallback); - if (result < 0) - return result; - - return __CARDSync(chan); -} diff --git a/src/dolphin/card/src/CARDStat.c b/src/dolphin/card/src/CARDStat.c deleted file mode 100644 index f99455b..0000000 --- a/src/dolphin/card/src/CARDStat.c +++ /dev/null @@ -1,156 +0,0 @@ -#include - -#include "__card.h" - -static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) { - u32 offset; - BOOL iconTlut; - int i; - - offset = ent->iconAddr; - if (offset == 0xffffffff) { - stat->bannerFormat = 0; - stat->iconFormat = 0; - stat->iconSpeed = 0; - offset = 0; - } - - iconTlut = FALSE; - switch (CARDGetBannerFormat(ent)) { - case CARD_STAT_BANNER_C8: - stat->offsetBanner = offset; - offset += CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; - stat->offsetBannerTlut = offset; - offset += 2 * 256; - break; - case CARD_STAT_BANNER_RGB5A3: - stat->offsetBanner = offset; - offset += 2 * CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; - stat->offsetBannerTlut = 0xffffffff; - break; - default: - stat->offsetBanner = 0xffffffff; - stat->offsetBannerTlut = 0xffffffff; - break; - } - - for (i = 0; i < CARD_ICON_MAX; ++i) { - switch (CARDGetIconFormat(ent, i)) { - case CARD_STAT_ICON_C8: - stat->offsetIcon[i] = offset; - offset += CARD_ICON_WIDTH * CARD_ICON_HEIGHT; - iconTlut = TRUE; - break; - case CARD_STAT_ICON_RGB5A3: - stat->offsetIcon[i] = offset; - offset += 2 * CARD_ICON_WIDTH * CARD_ICON_HEIGHT; - break; - default: - stat->offsetIcon[i] = 0xffffffff; - break; - } - } - - if (iconTlut) { - stat->offsetIconTlut = offset; - offset += 2 * 256; - } else { - stat->offsetIconTlut = 0xffffffff; - } - stat->offsetData = offset; -} - -s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat) { - CARDControl* card; - CARDDir* dir; - CARDDir* ent; - s32 result; - - ASSERTLINE(172, 0 <= chan && chan < 2); - ASSERTLINE(173, 0 <= fileNo && fileNo < CARD_MAX_FILE); - - if (fileNo < 0 || CARD_MAX_FILE <= fileNo) - return CARD_RESULT_FATAL_ERROR; - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) - return result; - - dir = __CARDGetDirBlock(card); - ent = &dir[fileNo]; - result = __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; - - ASSERTLINE(231, 0 <= fileNo && fileNo < CARD_MAX_FILE); - ASSERTLINE(232, 0 <= chan && chan < 2); - ASSERTMSGLINE(240, stat->iconAddr == 0xffffffff || stat->iconAddr < CARD_READ_SIZE, "CARDSetStatus[Async](): stat->iconAddr must be 0xffffffff or less than CARD_READ_SIZE."); - ASSERTMSGLINE(243, stat->commentAddr == 0xffffffff || (stat->commentAddr & 0x1FFF) <= 8128, "CARDSetStatus[Async](): comment strings (set by stat->commentAddr) must not cross 8KB byte boundary."); - - if (fileNo < 0 || CARD_MAX_FILE <= fileNo || - (stat->iconAddr != 0xffffffff && CARD_READ_SIZE <= stat->iconAddr) || - (stat->commentAddr != 0xffffffff && - CARD_SYSTEM_BLOCK_SIZE - CARD_COMMENT_SIZE < stat->commentAddr % CARD_SYSTEM_BLOCK_SIZE)) - { - return CARD_RESULT_FATAL_ERROR; - } - - result = __CARDGetControlBlock(chan, &card); - if (result < 0) - return result; - - dir = __CARDGetDirBlock(card); - ent = &dir[fileNo]; - result = __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 chan, s32 fileNo, CARDStat* stat) { - s32 result = CARDSetStatusAsync(chan, fileNo, stat, __CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(chan); -} diff --git a/src/dolphin/card/src/CARDUnlock.c b/src/dolphin/card/src/CARDUnlock.c deleted file mode 100644 index 8cc5b21..0000000 --- a/src/dolphin/card/src/CARDUnlock.c +++ /dev/null @@ -1,436 +0,0 @@ -#include -#include -#include - -#include "__card.h" - -static u8 CardData[352] ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, - 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF, - 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF, - 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, - 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00, 0x02, 0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E, - 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A, 0x00, 0x10, - 0x00, 0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF, - 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00, - 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94, 0x00, 0x48, 0x27, 0xFF, 0x03, 0x80, - 0x00, 0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F, - 0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, - 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF, - 0x03, 0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7, 0xFF, 0xFF, 0x02, 0xBF, - 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF, - 0x00, 0x8E, 0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF, - 0x02, 0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05, 0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, - 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00, 0x88, 0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0, - 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD, - 0x00, 0xF9, 0xFF, 0xC9, 0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D, - 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u32 next = 1; - -// prototypes -static u32 exnor_1st(u32 data, u32 rshift); -static u32 exnor(u32 data, u32 lshift); -static u32 bitrev(u32 data); -static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, int mode); -static u32 GetInitVal(void); -static s32 DummyLen(void); -static void InitCallback(void* _task); -static void DoneCallback(void* _task); - -static int CARDRand(void) -{ - next = (next * 0x41C64E6D) + 0x3039; - return (next / 0x10000) & 0x7FFF; -} - -static void CARDSrand(unsigned int seed) -{ - next = seed; -} - -static u32 exnor_1st(u32 data, u32 rshift) -{ - u32 wk; - u32 work; - u32 i; - - work = data; - for (i = 0; i < rshift; i++) - { - wk = ~(work ^ (work >> 7) ^ (work >> 15) ^ (work >> 23)); - work = (work >> 1) | ((wk << 30) & 0x40000000); - } - - return work; -} - -static u32 exnor(u32 data, u32 lshift) -{ - u32 wk; - u32 work; - u32 i; - - work = data; - for (i = 0; i < lshift; i++) - { - // 1bit Left Shift - wk = ~(work ^ (work << 7) ^ (work << 15) ^ (work << 23)); - work = (work << 1) | ((wk >> 30) & 0x00000002); - } - - return work; -} - -static u32 bitrev(u32 data) -{ - u32 wk; - u32 i; - u32 k = 0; - u32 j = 1; - - wk = 0; - for (i = 0; i < 32; i++) - { - if (i > 15) - { - if (i == 31) - wk |= (((data & (0x01 << 31)) >> 31) & 0x01); - else - { - wk |= ((data & (0x01 << i)) >> j); - j += 2; - } - } - else - { - wk |= ((data & (0x01 << i)) << (31 - i - k)); - k++; - } - } - - return wk; -} - -#define SEC_AD1(x) ((u8)(((x) >> 29) & 0x03)) -#define SEC_AD2(x) ((u8)(((x) >> 21) & 0xff)) -#define SEC_AD3(x) ((u8)(((x) >> 19) & 0x03)) -#define SEC_BA(x) ((u8)(((x) >> 12) & 0x7f)) - -static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, int mode) -{ - CARDControl* card; - BOOL err; - u8 cmd[5]; - - ASSERTLINE(240, 0 <= chan && chan < 2); - - card = &__CARDBlock[chan]; - if (!EXISelect(chan, 0, CARDFreq)) - return CARD_RESULT_NOCARD; - - data &= 0xfffff000; - memset(cmd, 0, 5); - cmd[0] = 0x52; - if (mode == 0) - { - cmd[1] = SEC_AD1(data); - cmd[2] = SEC_AD2(data); - cmd[3] = SEC_AD3(data); - cmd[4] = SEC_BA(data); - } - else - { - cmd[1] = (u8)((data & 0xff000000) >> 24); - cmd[2] = (u8)((data & 0x00ff0000) >> 16); - } - - err = FALSE; - err |= !EXIImmEx(chan, cmd, 5, 1); - err |= !EXIImmEx(chan, (u8*)card->workArea + (u32)sizeof(CARDID), card->latency, 1); - err |= !EXIImmEx(chan, rbuf, rlen, 0); - err |= !EXIDeselect(chan); - - return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; -} - -static u32 GetInitVal(void) -{ - u32 tmp; - u32 tick; - - tick = OSGetTick(); - CARDSrand(tick); - tmp = 0x7fec8000; - tmp |= CARDRand(); - tmp &= 0xfffff000; - return tmp; -} - -static s32 DummyLen(void) -{ - u32 tick; - u32 wk; - s32 tmp; - u32 max; - - wk = 1; - max = 0; - tick = OSGetTick(); - CARDSrand(tick); - - tmp = CARDRand(); - tmp &= 0x0000001f; - tmp += 1; - while ((tmp < 4) && (max < 10)) - { - tick = OSGetTick(); - tmp = (s32)(tick << wk); - wk++; - if (wk > 16) - wk = 1; - CARDSrand((u32)tmp); - tmp = CARDRand(); - tmp &= 0x0000001f; - tmp += 1; - max++; - } - - if (tmp < 4) - tmp = 4; - - return tmp; -} - -s32 __CARDUnlock(s32 chan, u8 flashID[12]) -{ - u32 init_val; - u32 data; - - s32 dummy; - s32 rlen; - u32 rshift; - - u8 fsts; - u32 wk, wk1; - u32 Ans1 = 0; - u32 Ans2 = 0; - u32* dp; - u8 rbuf[64]; - u32 para1A = 0; - u32 para1B = 0; - u32 para2A = 0; - u32 para2B = 0; - - CARDControl* card; - DSPTaskInfo* task; - CARDDecParam* param; - u8* input; - u8* output; - - card = &__CARDBlock[chan]; - task = &card->task; - param = (CARDDecParam*)card->workArea; - input = (u8*)((u8*)param + sizeof(CARDDecParam)); - input = (u8*)OSRoundUp32B(input); - output = input + 32; - - fsts = 0; - init_val = GetInitVal(); - - dummy = DummyLen(); - rlen = dummy; - if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) - return CARD_RESULT_NOCARD; - - rshift = (u32)(dummy * 8 + 1); - wk = exnor_1st(init_val, rshift); - wk1 = ~(wk ^ (wk >> 7) ^ (wk >> 15) ^ (wk >> 23)); - card->scramble = (wk | ((wk1 << 31) & 0x80000000)); - card->scramble = bitrev(card->scramble); - dummy = DummyLen(); - rlen = 20 + dummy; - data = 0; - if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) - return CARD_RESULT_NOCARD; - - dp = (u32*)rbuf; - para1A = *dp++; - para1B = *dp++; - Ans1 = *dp++; - para2A = *dp++; - para2B = *dp++; - para1A = (para1A ^ card->scramble); - rshift = 32; - wk = exnor(card->scramble, rshift); - wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); - card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); - - para1B = (para1B ^ card->scramble); - rshift = 32; - wk = exnor(card->scramble, rshift); - wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); - card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); - - Ans1 ^= card->scramble; - rshift = 32; - wk = exnor(card->scramble, rshift); - wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); - card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); - - para2A = (para2A ^ card->scramble); - rshift = 32; - wk = exnor(card->scramble, rshift); - wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); - card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); - - para2B = (para2B ^ card->scramble); - rshift = (u32)(dummy * 8); - wk = exnor(card->scramble, rshift); - wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); - card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); - - rshift = 32 + 1; - wk = exnor(card->scramble, rshift); - wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); - card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); - - *(u32*)&input[0] = para2A; - *(u32*)&input[4] = para2B; - - param->inputAddr = input; - param->inputLength = 8; - param->outputAddr = output; - param->aramAddr = 0; - - DCFlushRange(input, 8); - DCInvalidateRange(output, 4); - DCFlushRange(param, sizeof(CARDDecParam)); - - task->priority = 255; - task->iram_mmem_addr = (u16*)OSCachedToPhysical(CardData); - task->iram_length = 0x160; - task->iram_addr = 0; - task->dsp_init_vector = 0x10; - task->init_cb = InitCallback; - task->res_cb = NULL; - task->done_cb = DoneCallback; - task->req_cb = NULL; - DSPAddTask(task); - - dp = (u32*)flashID; - *dp++ = para1A; - *dp++ = para1B; - *dp = Ans1; - - return CARD_RESULT_READY; -} - -static void InitCallback(void* _task) -{ - s32 chan; - CARDControl* card; - DSPTaskInfo* task; - CARDDecParam* param; - - task = _task; - for (chan = 0; chan < 2; ++chan) - { - card = &__CARDBlock[chan]; - if ((DSPTaskInfo*)&card->task == task) - break; - } - - ASSERTLINE(514, 0 <= chan && chan < 2); - - param = (CARDDecParam*)card->workArea; - - DSPSendMailToDSP(0xff000000); - while (DSPCheckMailToDSP()) - ; - - DSPSendMailToDSP((u32)param); - while (DSPCheckMailToDSP()) - ; -} - -static void DoneCallback(void* _task) -{ - u8 rbuf[64]; - u32 data; - s32 dummy; - s32 rlen; - u32 rshift; - - u8 unk; - u32 wk, wk1; - u32 Ans2; - - s32 chan; - CARDControl* card; - s32 result; - DSPTaskInfo* task; - CARDDecParam* param; - - u8* input; - u8* output; - task = _task; - for (chan = 0; chan < 2; ++chan) - { - card = &__CARDBlock[chan]; - if ((DSPTaskInfo*)&card->task == task) - break; - } - - ASSERTLINE(563, 0 <= chan && chan < 2); - - param = (CARDDecParam*)card->workArea; - input = (u8*)((u8*)param + sizeof(CARDDecParam)); - input = (u8*)OSRoundUp32B(input); - output = input + 32; - - Ans2 = *(u32*)output; - dummy = DummyLen(); - rlen = dummy; - data = ((Ans2 ^ card->scramble) & 0xffff0000); - if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) - { - EXIUnlock(chan); - __CARDMountCallback(chan, CARD_RESULT_NOCARD); - return; - } - - rshift = (u32)((dummy + 4 + card->latency) * 8 + 1); - wk = exnor(card->scramble, rshift); - wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); - card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); - - dummy = DummyLen(); - rlen = dummy; - data = (((Ans2 << 16) ^ card->scramble) & 0xffff0000); - if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) - { - EXIUnlock(chan); - __CARDMountCallback(chan, CARD_RESULT_NOCARD); - return; - } - - result = __CARDReadStatus(chan, &unk); - if (!EXIProbe(chan)) - { - EXIUnlock(chan); - __CARDMountCallback(chan, CARD_RESULT_NOCARD); - return; - } - - if (result == CARD_RESULT_READY && !(unk & 0x40)) - { - EXIUnlock(chan); - result = CARD_RESULT_IOERROR; - } - - __CARDMountCallback(chan, result); -} diff --git a/src/dolphin/card/src/CARDWrite.c b/src/dolphin/card/src/CARDWrite.c deleted file mode 100644 index ad9fa4a..0000000 --- a/src/dolphin/card/src/CARDWrite.c +++ /dev/null @@ -1,123 +0,0 @@ -#include - -#include "__card.h" - -// prototypes -static void WriteCallback(s32 chan, s32 result); -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) { - fileInfo = card->fileInfo; - if (fileInfo->length < 0) { - result = CARD_RESULT_CANCELED; - goto after; - } - fileInfo->length -= card->sectorSize; - if (fileInfo->length <= 0) { - dir = __CARDGetDirBlock(card); - ent = dir + fileInfo->fileNo; - ent->time = OSGetTime()/(__OSBusClock/4); - callback = card->apiCallback; - card->apiCallback = NULL; - result = __CARDUpdateDir(chan, callback); - goto check; - } else { - fat = __CARDGetFatBlock(card); - fileInfo->offset += card->sectorSize; - fileInfo->iBlock = fat[fileInfo->iBlock]; - if ((fileInfo->iBlock < 5) || (fileInfo->iBlock >= card->cBlock)) { - result = CARD_RESULT_BROKEN; - goto after; - } - result = __CARDEraseSector(chan, card->sectorSize * fileInfo->iBlock, EraseCallback); -check:; - if (result < 0) { - goto after; - } - } - } else { -after:; - callback = card->apiCallback; - card->apiCallback = NULL; - __CARDPutControlBlock(card, result); - ASSERTLINE(0x86, callback); - callback(chan, result); - } -} - -static void EraseCallback(s32 chan, s32 result) { - CARDControl* card; - CARDCallback callback; - CARDFileInfo* fileInfo; - - card = &__CARDBlock[chan]; - if (result >= 0) { - fileInfo = card->fileInfo; - ASSERTLINE(161, OFFSET(fileInfo->offset, card->sectorSize) == 0); - result = __CARDWrite(chan, card->sectorSize * fileInfo->iBlock, card->sectorSize, card->buffer, WriteCallback); - if (result < 0) { - goto after; - } - } else { -after:; - callback = card->apiCallback; - card->apiCallback = NULL; - __CARDPutControlBlock(card, result); - ASSERTLINE(175, callback); - callback(chan, result); - } -} - -s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { - CARDControl* card; - s32 result; - CARDDir* dir; - CARDDir* ent; - - ASSERTLINE(210, buf && ((u32) buf % 32) == 0); - ASSERTLINE(211, 0 < length); - - result = __CARDSeek(fileInfo, length, offset, &card); - if (result < 0) { - return result; - } - - ASSERTLINE(217, OFFSET(offset, card->sectorSize) == 0); - ASSERTLINE(218, OFFSET(length, card->sectorSize) == 0); - - if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) - return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); - - dir = __CARDGetDirBlock(card); - ent = &dir[fileInfo->fileNo]; - result = __CARDIsWritable(card, ent); - if (result < 0) - return __CARDPutControlBlock(card, result); - - DCStoreRange((void*)buf, (u32)length); - card->apiCallback = callback ? callback : __CARDDefaultApiCallback; - card->buffer = (void*)buf; - - result = __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); - if (result < 0) - __CARDPutControlBlock(card, result); - return result; -} - -s32 CARDWrite(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { - s32 result = CARDWriteAsync(fileInfo, buf, length, offset, __CARDSyncCallback); - if (result < 0) { - return result; - } - - return __CARDSync(fileInfo->chan); -} diff --git a/src/dolphin/card/src/__card.h b/src/dolphin/card/src/__card.h deleted file mode 100644 index 4625c63..0000000 --- a/src/dolphin/card/src/__card.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef _DOLPHIN_CARD_INTERNAL_H_ -#define _DOLPHIN_CARD_INTERNAL_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// CARDStatEx -s32 __CARDGetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent); -s32 __CARDSetStatusExAsync(s32 chan, s32 fileNo, CARDDir* dirent, CARDCallback callback); -s32 __CARDSetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent); - -// CARDUnlock -s32 __CARDUnlock(s32 chan, u8 flashID[12]); - -// CARDRead -s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard); - -// CARDRdwr -s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback); -s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback); - -// CARDRaw -s32 __CARDRawReadAsync(s32 chan, void* buf, s32 length, s32 offset, CARDCallback callback); -s32 __CARDRawRead(s32 chan, void* buf, s32 length, s32 offset); -s32 __CARDRawErase(s32 chan, s32 offset); -s32 __CARDRawEraseAsync(s32 chan, s32 offset, CARDCallback callback); - -// CARDOpen -BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName); -s32 __CARDAccess(CARDControl* card, CARDDir* ent); -s32 __CARDIsPublic(CARDDir* ent); -s32 __CARDGetFileNo(CARDControl* card, const char* fileName, s32* pfileNo); -BOOL __CARDIsOpened(CARDControl* card, s32 fileNo); -s32 __CARDIsWritable(CARDControl* card, CARDDir* ent); -s32 __CARDIsReadable(CARDControl* card, CARDDir* ent); - -// CARDNet -extern u16 __CARDVendorID; -extern u8 __CARDPermMask; -int __CARDEnableGlobal(int enable); -int __CARDEnableCompany(int enable); - -// CARDMount -void __CARDMountCallback(s32 chan, s32 result); -void __CARDDisable(BOOL disable); - -// CARDFormat -s32 CARDFormatAsync(s32 chan, CARDCallback callback); -s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback); -s32 __CARDFormatRegion(s32 chan, u16 encode); - -// CARDDir -CARDDir* __CARDGetDirBlock(CARDControl* card); -s32 __CARDUpdateDir(s32 chan, CARDCallback callback); - -// CARDCheck -void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv); -s32 __CARDVerify(CARDControl* card); - -// CARDBlock -void* __CARDGetFatBlock(CARDControl* card); -s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback); -s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback); -s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback); - -// CARDBios -extern CARDControl __CARDBlock[2]; - -extern DVDDiskID* __CARDDiskID; -extern DVDDiskID __CARDDiskNone; - -void __CARDDefaultApiCallback(s32 chan, s32 result); -void __CARDSyncCallback(s32 chan, s32 result); -void __CARDExtHandler(s32 chan, OSContext* context); -void __CARDExiHandler(s32 chan, OSContext* context); -void __CARDTxHandler(s32 chan, OSContext* context); -void __CARDUnlockedHandler(s32 chan, OSContext* context); -int __CARDReadNintendoID(s32 chan, u32* id); -s32 __CARDEnableInterrupt(s32 chan, BOOL enable); -s32 __CARDReadStatus(s32 chan, u8* status); -int __CARDReadVendorID(s32 chan, u16* id); -s32 __CARDClearStatus(s32 chan); -s32 __CARDSleep(s32 chan); -s32 __CARDWakeup(s32 chan); -s32 __CARDReadSegment(s32 chan, CARDCallback callback); -s32 __CARDWritePage(s32 chan, CARDCallback callback); -s32 __CARDErase(s32 chan, CARDCallback callback); -s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback); -void __CARDSetDiskID(const DVDDiskID* id); -s32 __CARDGetControlBlock(s32 chan, CARDControl **pcard); -s32 __CARDPutControlBlock(CARDControl* card, s32 result); -s32 __CARDSync(s32 chan); -u16 __CARDGetFontEncode(void); -u16 __CARDSetFontEncode(u16 encode); - -#ifdef __cplusplus -} -#endif - -#endif // _DOLPHIN_CARD_INTERNAL_H_ diff --git a/src/dolphin/db/src/db.c b/src/dolphin/db/src/db.c deleted file mode 100644 index 3e16342..0000000 --- a/src/dolphin/db/src/db.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include - -u8 DBStack[0x1000]; -u8* DBStackEnd = DBStack + (sizeof(DBStack) - 8); -BOOL DBVerbose; -DBInterface* __DBInterface; - -void DBInit(void) { - __DBInterface = OSPhysicalToCached(0x40); - __DBInterface->ExceptionDestination = (void *)OSCachedToPhysical(__DBExceptionDestination); - DBVerbose = TRUE; -} - -BOOL DBIsDebuggerPresent(void) { - if (__DBInterface == NULL) - return FALSE; - return __DBInterface->bPresent; -} - -void __DBExceptionDestinationAux(void) { - u32* contextAddr; - OSContext* context; - - contextAddr = (void*)0xC0; - context = OSPhysicalToCached(*contextAddr); - OSReport("DBExceptionDestination\n"); - OSDumpContext(context); - PPCHalt(); -} - -asm void __DBExceptionDestination(void) { - nofralloc - mfmsr r3 - ori r3, r3, 0x30 - mtmsr r3 - b __DBExceptionDestinationAux -} - -BOOL __DBIsExceptionMarked(__OSException exception) { - u32 mask = (1 << exception); - return __DBInterface->exceptionMask & mask; -} - -void __DBMarkException(__OSException exception, int value) { - u32 mask = (1 << exception); - - if (value != 0) - __DBInterface->exceptionMask = __DBInterface->exceptionMask | mask; - else - __DBInterface->exceptionMask = __DBInterface->exceptionMask & ~mask; -} - -void __DBSetPresent(u32 value) { - __DBInterface->bPresent = value; -} - -void DBPrintf(char* str, ...) {} diff --git a/src/dolphin/demo/DEMOAVX.c b/src/dolphin/demo/DEMOAVX.c deleted file mode 100644 index 27d4917..0000000 --- a/src/dolphin/demo/DEMOAVX.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include -#include "fake_tgmath.h" - -static s16 __AVX_internal_buffer[3200] ATTRIBUTE_ALIGN(32); - -static void (*__AVX_save_isr)(void); - -static u32 __AVX_num_frames; -static u32 __AVX_num_filled; -static u32 __AVX_curr_frame; - -static u16* __AVX_buffer; -static s16* __AVX_left_buffer; -static s16* __AVX_right_buffer; -static u32 __AVX_write_ptr = 0; -static u32 __AVX_buffer_size = 0; - -static BOOL flag = FALSE; - -static void __DEMOAVX_isr(void) { - u32 frame_address; - - if (__AVX_save_isr) { - (*__AVX_save_isr)(); - - frame_address = 0x80000000 | AIGetDMAStartAddr(); - ASSERTMSGLINE(83, frame_address, "AVX: frame address is NULL!\n"); - - DCInvalidateRange((void*)frame_address, 640); - memcpy((void *)&__AVX_buffer[__AVX_curr_frame * 320], (void*)frame_address, 640); - DCFlushRange((void*)&__AVX_buffer[__AVX_curr_frame * 320], 640); - - __AVX_curr_frame = (__AVX_curr_frame + 1) % __AVX_num_frames; - __AVX_num_filled = (__AVX_num_filled + 1) % 10; - if (__AVX_curr_frame > 4) { - flag = TRUE; - } - } -} - -u32 DEMOAVXGetNumFilled(void) { - u32 tmp; - BOOL old; - - old = OSDisableInterrupts(); - - tmp = __AVX_num_filled; - __AVX_num_filled = 0; - - OSRestoreInterrupts(old); - return tmp; -} - -u32 DEMOAVXGetFrameCounter(void) { - return __AVX_curr_frame; -} - -u32 DEMOAVXRefreshBuffer(u32* start_index, u32* end_index) { - u32 num_filled; - u32 curr_frame; - u32 i; - u32 j; - - if (flag) { - num_filled = DEMOAVXGetNumFilled(); - curr_frame = (__AVX_num_frames + DEMOAVXGetFrameCounter() - num_filled) % __AVX_num_frames; - - *start_index = __AVX_write_ptr; - - for (i = 0; i < num_filled; i++) { - DCInvalidateRange((void*)&__AVX_buffer[curr_frame * 320], 640); - - for (j = 0; j < 320; j += 2) { - __AVX_left_buffer [__AVX_write_ptr] = __AVX_buffer[curr_frame * 320 + j]; - __AVX_right_buffer[__AVX_write_ptr] = __AVX_buffer[curr_frame * 320 + j + 1]; - __AVX_write_ptr = (__AVX_write_ptr + 1) % __AVX_buffer_size; - } - - curr_frame = (curr_frame + 1) % __AVX_num_frames; - } - - *end_index = __AVX_write_ptr; - return num_filled * 160; - } - - return 0; -} - -void DEMOAVXInit(s16* left, s16* right, u32 size) { - __AVX_left_buffer = left; - __AVX_right_buffer = right; - __AVX_write_ptr = 0; - __AVX_buffer_size = size; - - DEMOAVXAttach(__AVX_internal_buffer, 10); -} - -void DEMOAVXAttach(void* buffer, u32 num_frames) { - BOOL old; - u32 i; - - __AVX_buffer = (u16*)buffer; - __AVX_num_frames = num_frames; - __AVX_num_filled = 0; - __AVX_curr_frame = 0; - - for (i = 0; i < num_frames * 320; i++) { - __AVX_buffer[i] = 0; - } - - DCFlushRange(__AVX_buffer, num_frames * 320); - - old = OSDisableInterrupts(); - __AVX_save_isr = AIRegisterDMACallback(__DEMOAVX_isr); - OSRestoreInterrupts(old); -} diff --git a/src/dolphin/demo/DEMOFont.c b/src/dolphin/demo/DEMOFont.c deleted file mode 100644 index 9b37170..0000000 --- a/src/dolphin/demo/DEMOFont.c +++ /dev/null @@ -1,773 +0,0 @@ -#include -#include - -u32 DEMOFontBitmap[768] ATTRIBUTE_ALIGN(32) = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x000FF000, - 0x000FF000, - 0x000FF000, - 0x00000000, - 0x000FF000, - 0x00000000, - 0x00F00F00, - 0x00F00F00, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00F00F00, - 0x00F00F00, - 0x0FFFFFF0, - 0x00F00F00, - 0x0FFFFFF0, - 0x00F00F00, - 0x00F00F00, - 0x00000000, - 0x0000F000, - 0x00FFFFF0, - 0x0F00F000, - 0x00FFFF00, - 0x0000F0F0, - 0x0FFFFF00, - 0x0000F000, - 0x00000000, - 0x0FF000F0, - 0x0FF00F00, - 0x0000F000, - 0x000F0000, - 0x00F00FF0, - 0x0F000FF0, - 0x00000000, - 0x00000000, - 0x000F0000, - 0x00F0F000, - 0x00F0F000, - 0x00FF0000, - 0x0F000FF0, - 0x0F0000F0, - 0x00FFFF00, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x0000F000, - 0x000F0000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x0000F000, - 0x000F0000, - 0x00F00000, - 0x00F00000, - 0x00F00000, - 0x000F0000, - 0x0000F000, - 0x00000000, - 0x000F0000, - 0x0000F000, - 0x00000F00, - 0x00000F00, - 0x00000F00, - 0x0000F000, - 0x000F0000, - 0x00000000, - 0x00000000, - 0x00F000F0, - 0x000F0F00, - 0x00FFFFF0, - 0x000F0F00, - 0x00F000F0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x0000F000, - 0x0000F000, - 0x00FFFFF0, - 0x0000F000, - 0x0000F000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x0000F000, - 0x000F0000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00FFFFF0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x00000000, - 0x000000F0, - 0x00000F00, - 0x0000F000, - 0x000F0000, - 0x00F00000, - 0x0F000000, - 0x00000000, - 0x00000000, - 0x000FF000, - 0x00F00F00, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x00F00F00, - 0x000FF000, - 0x00000000, - 0x0000F000, - 0x000FF000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x000FFF00, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x000000F0, - 0x00000F00, - 0x0000F000, - 0x000F0000, - 0x0FFFFFF0, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x000000F0, - 0x0000FF00, - 0x000000F0, - 0x0F0000F0, - 0x00FFFF00, - 0x00000000, - 0x00000F00, - 0x0000FF00, - 0x000F0F00, - 0x00F00F00, - 0x0FFFFFF0, - 0x00000F00, - 0x00000F00, - 0x00000000, - 0x0FFFFFF0, - 0x0F000000, - 0x0F000000, - 0x0FFFFF00, - 0x000000F0, - 0x0F0000F0, - 0x00FFFF00, - 0x00000000, - 0x000FFF00, - 0x00F00000, - 0x0F000000, - 0x0FFFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x00FFFF00, - 0x00000000, - 0x0FFFFFF0, - 0x0F0000F0, - 0x00000F00, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x00FFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x00FFFF00, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x00FFFFF0, - 0x000000F0, - 0x000000F0, - 0x00FFFF00, - 0x00000000, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x00000000, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x0000F000, - 0x000F0000, - 0x00000000, - 0x00000F00, - 0x0000F000, - 0x000F0000, - 0x00F00000, - 0x000F0000, - 0x0000F000, - 0x00000F00, - 0x00000000, - 0x00000000, - 0x00000000, - 0x0FFFFFF0, - 0x00000000, - 0x0FFFFFF0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00F00000, - 0x000F0000, - 0x0000F000, - 0x00000F00, - 0x0000F000, - 0x000F0000, - 0x00F00000, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x0000FF00, - 0x000FF000, - 0x00000000, - 0x000FF000, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x0F000FF0, - 0x0F00F0F0, - 0x0F00FFF0, - 0x0F000000, - 0x00FFFFF0, - 0x00000000, - 0x000FF000, - 0x00F00F00, - 0x0F0000F0, - 0x0F0000F0, - 0x0FFFFFF0, - 0x0F0000F0, - 0x0F0000F0, - 0x00000000, - 0x0FFFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x0FFFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x0FFFFF00, - 0x00000000, - 0x000FFF00, - 0x00F000F0, - 0x0F000000, - 0x0F000000, - 0x0F000000, - 0x00F000F0, - 0x000FFF00, - 0x00000000, - 0x0FFFF000, - 0x0F000F00, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F000F00, - 0x0FFFF000, - 0x00000000, - 0x0FFFFFF0, - 0x0F000000, - 0x0F000000, - 0x0FFFFF00, - 0x0F000000, - 0x0F000000, - 0x0FFFFFF0, - 0x00000000, - 0x0FFFFFF0, - 0x0F000000, - 0x0F000000, - 0x0FFFFF00, - 0x0F000000, - 0x0F000000, - 0x0F000000, - 0x00000000, - 0x000FFF00, - 0x00F00000, - 0x0F000000, - 0x0F00FFF0, - 0x0F0000F0, - 0x00F000F0, - 0x000FFF00, - 0x00000000, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0FFFFFF0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x00000000, - 0x000FFF00, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x000FFF00, - 0x00000000, - 0x0000FFF0, - 0x00000F00, - 0x00000F00, - 0x00000F00, - 0x00000F00, - 0x0F000F00, - 0x00FFF000, - 0x00000000, - 0x0F0000F0, - 0x0F000F00, - 0x0F00F000, - 0x0FFF0000, - 0x0F00F000, - 0x0F000F00, - 0x0F0000F0, - 0x00000000, - 0x0F000000, - 0x0F000000, - 0x0F000000, - 0x0F000000, - 0x0F000000, - 0x0F000000, - 0x0FFFFFF0, - 0x00000000, - 0x0F00000F, - 0x0FF000FF, - 0x0F0F0F0F, - 0x0F00F00F, - 0x0F00F00F, - 0x0F00000F, - 0x0F00000F, - 0x00000000, - 0x0F0000F0, - 0x0FF000F0, - 0x0F0F00F0, - 0x0F00F0F0, - 0x0F00F0F0, - 0x0F000FF0, - 0x0F0000F0, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x00FFFF00, - 0x00000000, - 0x0FFFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x0FFFFF00, - 0x0F000000, - 0x0F000000, - 0x0F000000, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F00F0F0, - 0x0F000F00, - 0x00FFF0F0, - 0x00000000, - 0x0FFFFF00, - 0x0F0000F0, - 0x0F0000F0, - 0x0FFFFF00, - 0x0F00F000, - 0x0F000F00, - 0x0F0000F0, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x0F000000, - 0x00FFFF00, - 0x000000F0, - 0x0F0000F0, - 0x00FFFF00, - 0x00000000, - 0x0FFFFFFF, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x00000000, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x00FFFF00, - 0x00000000, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x0F0000F0, - 0x00F00F00, - 0x00F00F00, - 0x000FF000, - 0x00000000, - 0x0F00000F, - 0x0F00000F, - 0x0F00000F, - 0x0F00F00F, - 0x0F00F00F, - 0x0F00F00F, - 0x00FF0FF0, - 0x00000000, - 0x0F0000F0, - 0x0F0000F0, - 0x00F00F00, - 0x000FF000, - 0x00F00F00, - 0x0F0000F0, - 0x0F0000F0, - 0x00000000, - 0x0F00000F, - 0x00F000F0, - 0x000F0F00, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x00000000, - 0x0FFFFFF0, - 0x000000F0, - 0x00000F00, - 0x000FF000, - 0x00F00000, - 0x0F000000, - 0x0FFFFFF0, - 0x00000000, - 0x000FFF00, - 0x000F0000, - 0x000F0000, - 0x000F0000, - 0x000F0000, - 0x000F0000, - 0x000FFF00, - 0x00000000, - 0x0F000000, - 0x00F00000, - 0x000F0000, - 0x0000F000, - 0x00000F00, - 0x000000F0, - 0x00000000, - 0x00000000, - 0x00FFF000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x00FFF000, - 0x00000000, - 0x000FF000, - 0x00F00F00, - 0x0F0000F0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x0FFFFFF0, - 0x00000000, - 0x000FF000, - 0x000FF000, - 0x000F0000, - 0x0000F000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00FFFF00, - 0x0F000F00, - 0x0F000F00, - 0x0F000F00, - 0x00FFFFF0, - 0x00000000, - 0x00F00000, - 0x00F00000, - 0x00F00000, - 0x00FFFF00, - 0x00F000F0, - 0x00F000F0, - 0x00FFFF00, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00FFFF00, - 0x0F000000, - 0x0F000000, - 0x0F000000, - 0x00FFFF00, - 0x00000000, - 0x000000F0, - 0x000000F0, - 0x000000F0, - 0x000FFFF0, - 0x00F000F0, - 0x00F000F0, - 0x000FFFF0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00FFFF00, - 0x0F0000F0, - 0x0FFFFFF0, - 0x0F000000, - 0x00FFFF00, - 0x00000000, - 0x0000FF00, - 0x000F0000, - 0x000F0000, - 0x0FFFFF00, - 0x000F0000, - 0x000F0000, - 0x000F0000, - 0x00000000, - 0x00000000, - 0x000FFFF0, - 0x00F000F0, - 0x00F000F0, - 0x000FFFF0, - 0x000000F0, - 0x000FFF00, - 0x00000000, - 0x00F00000, - 0x00F00000, - 0x00F00000, - 0x00F0FF00, - 0x00FF00F0, - 0x00F000F0, - 0x00F000F0, - 0x00000000, - 0x00000000, - 0x0000F000, - 0x00000000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x00000000, - 0x00000F00, - 0x00000000, - 0x00000F00, - 0x00000F00, - 0x00000F00, - 0x00F00F00, - 0x000FF000, - 0x00000000, - 0x00000000, - 0x00F00000, - 0x00F00000, - 0x00F00F00, - 0x00F0F000, - 0x00FFF000, - 0x00F00F00, - 0x00000000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x00000F00, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00F0FF00, - 0x0F0F00F0, - 0x0F0F00F0, - 0x0F0F00F0, - 0x0F0F00F0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00F0FF00, - 0x00FF00F0, - 0x00F000F0, - 0x00F000F0, - 0x00F000F0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x000FFF00, - 0x00F000F0, - 0x00F000F0, - 0x00F000F0, - 0x000FFF00, - 0x00000000, - 0x00000000, - 0x00FFF000, - 0x00F00F00, - 0x00F00F00, - 0x00FFF000, - 0x00F00000, - 0x00F00000, - 0x00000000, - 0x00000000, - 0x000FFF00, - 0x00F00F00, - 0x00F00F00, - 0x000FFF00, - 0x00000F00, - 0x00000FF0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00F0FFF0, - 0x00FF0000, - 0x00F00000, - 0x00F00000, - 0x00F00000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x000FFFF0, - 0x00F00000, - 0x000FFF00, - 0x000000F0, - 0x00FFFF00, - 0x00000000, - 0x00000000, - 0x0000F000, - 0x00FFFFF0, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x00000FF0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00F000F0, - 0x00F000F0, - 0x00F000F0, - 0x00F000F0, - 0x000FFFF0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00F000F0, - 0x00F000F0, - 0x00F000F0, - 0x000F0F00, - 0x0000F000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x0F0000F0, - 0x0F00F0F0, - 0x0F00F0F0, - 0x0F00F0F0, - 0x00FF0F00, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00F000F0, - 0x000F0F00, - 0x0000F000, - 0x000F0F00, - 0x00F000F0, - 0x00000000, - 0x00000000, - 0x0F000F00, - 0x0F000F00, - 0x00F00F00, - 0x000FFF00, - 0x00000F00, - 0x00FFF000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00FFFFF0, - 0x00000F00, - 0x0000F000, - 0x000F0000, - 0x00FFFFF0, - 0x00000000, - 0x00000F00, - 0x0000F000, - 0x0000F000, - 0x00FF0000, - 0x0000F000, - 0x0000F000, - 0x00000F00, - 0x00000000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x0000F000, - 0x00000000, - 0x000F0000, - 0x0000F000, - 0x0000F000, - 0x00000FF0, - 0x0000F000, - 0x0000F000, - 0x000F0000, - 0x00000000, - 0x00FF00FF, - 0x0F00FF00, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00FF0000, - 0x0FF00000, - 0xFFFFFFFF, - 0xFFFFF000, - 0xFFFFF000, - 0xFFF00000, - 0x00000000 -}; diff --git a/src/dolphin/demo/DEMOInit.c b/src/dolphin/demo/DEMOInit.c deleted file mode 100644 index 630c2f5..0000000 --- a/src/dolphin/demo/DEMOInit.c +++ /dev/null @@ -1,432 +0,0 @@ -#include -#include -#include -#include -#include - -#include "__demo.h" - -extern u8 DemoStatEnable; - -static GXRenderModeObj rmodeobj; - -static u8 DemoFirstFrame = 1; - -static void* DefaultFifo = NULL; -static GXFifoObj* DefaultFifoObj = NULL; -static GXRenderModeObj* rmode; -static u32 allocatedFrameBufferSize; -static int GPHangWorkaround; -static u32 FrameCount; -static u32 FrameMissThreshold; -void* DemoFrameBuffer1; -void* DemoFrameBuffer2; -void* DemoCurrentBuffer; - -// prototypes -static void __DEMOInitRenderMode(GXRenderModeObj* mode); -static void __DEMOInitMem(void); -static void __DEMOInitGX(void); -static void __DEMOInitVI(void); -static void __DEMOInitForEmu(void); -static void __NoHangRetraceCallback(u32 count); -static void __NoHangDoneRender(void); -static void __DEMODiagnoseHang(void); - -void DEMOInit(GXRenderModeObj* mode) { - OSInit(); - DVDInit(); - VIInit(); - DEMOPadInit(); - __DEMOInitRenderMode(mode); - __DEMOInitMem(); - VIConfigure(rmode); - DefaultFifo = OSAllocFromHeap(__OSCurrHeap, 0x40000); - DefaultFifoObj = GXInit(DefaultFifo, 0x40000); - __DEMOInitGX(); - __DEMOInitVI(); -} - -static void __DEMOInitRenderMode(GXRenderModeObj* mode) { - if (mode != NULL) { - rmodeobj = *mode; - rmode = &rmodeobj; - return; - } - - switch(VIGetTvFormat()) { - case VI_NTSC: - rmode = &GXNtsc480IntDf; - break; - case VI_PAL: - rmode = &GXPal528IntDf; - break; - case VI_EURGB60: - rmode = &GXEurgb60Hz480IntDf; - break; - case VI_MPAL: - rmode = &GXMpal480IntDf; - break; - default: - OSPanic(__FILE__, 473, "DEMOInit: invalid TV format\n"); - break; - } - - GXAdjustForOverscan(rmode, &rmodeobj, 0, 16); - rmode = &rmodeobj; -} - -static void __DEMOInitMem(void) { - void* arenaLo = OSGetArenaLo(); - void* arenaHi = OSGetArenaHi(); - u32 fbSize = ((u16)(rmode->fbWidth + 15) & 0xFFF0) * rmode->xfbHeight * 2; - allocatedFrameBufferSize = fbSize; - - DemoFrameBuffer1 = (void*)OSRoundUp32B(arenaLo); - DemoFrameBuffer2 = (void*)OSRoundUp32B((u32)DemoFrameBuffer1 + fbSize); - DemoCurrentBuffer = DemoFrameBuffer2; - - arenaLo = (void*)OSRoundUp32B((u32)DemoFrameBuffer2 + fbSize); - OSSetArenaLo(arenaLo); - - arenaLo = OSGetArenaLo(); - arenaHi = OSGetArenaHi(); - arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); - OSSetArenaLo(arenaLo); - - arenaLo = (void*)OSRoundUp32B(arenaLo); - arenaHi = (void*)OSRoundDown32B(arenaHi); - OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi)); - OSSetArenaLo((arenaLo = arenaHi)); -} - -static void __DEMOInitGX(void) { - u16 xfbHeight; - f32 yScale; - - GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f); - GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight); - - yScale = GXGetYScaleFactor(rmode->efbHeight, rmode->xfbHeight); - xfbHeight = GXSetDispCopyYScale(yScale); - - GXSetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight); - GXSetDispCopyDst(rmode->fbWidth, xfbHeight); - GXSetCopyFilter(rmode->aa, rmode->sample_pattern, 1, rmode->vfilter); - - if (rmode->aa != 0) { - GXSetPixelFmt(2, 0); - } else { - GXSetPixelFmt(0, 0); - } - - GXCopyDisp(DemoCurrentBuffer, 1); - GXSetDispCopyGamma(0); -} - -static void __DEMOInitVI(void) { - u32 nin; - - VISetNextFrameBuffer(DemoFrameBuffer1); - DemoCurrentBuffer = DemoFrameBuffer2; - VIFlush(); - VIWaitForRetrace(); - nin = rmode->viTVmode & 1; - if (nin != 0) { - VIWaitForRetrace(); - } -} - -static void __DEMOInitForEmu(void) {} - -void DEMOBeforeRender(void) { - if (GPHangWorkaround != 0) { - GXSetDrawSync(0xFEEB); - GXClearGPMetric(); - } - - if (rmode->field_rendering != 0) { - GXSetViewportJitter(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f, VIGetNextField()); - } else { - GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f); - } - - GXInvalidateVtxCache(); - GXInvalidateTexAll(); -} - -void DEMODoneRender(void) { - if (GPHangWorkaround != 0) { - ASSERTMSGLINE(749, !DemoStatEnable, "DEMOStats and GP hang diagnosis are mutually exclusive"); - __NoHangDoneRender(); - return; - } - - if (DemoStatEnable != 0) { - GXDrawDone(); - DEMOUpdateStats(1); - DEMOPrintStats(); - GXDrawDone(); - DEMOUpdateStats(0); - } - - GXSetZMode(1, 3, 1); - GXSetColorUpdate(1); - GXCopyDisp(DemoCurrentBuffer, 1); - GXDrawDone(); - DEMOSwapBuffers(); -} - -void DEMOSwapBuffers(void) { - VISetNextFrameBuffer(DemoCurrentBuffer); - if (DemoFirstFrame != 0) { - VISetBlack(0); - DemoFirstFrame = 0; - } - - VIFlush(); - VIWaitForRetrace(); - - if ((u32)DemoCurrentBuffer == (u32)DemoFrameBuffer1) { - DemoCurrentBuffer = DemoFrameBuffer2; - } else { - DemoCurrentBuffer = DemoFrameBuffer1; - } -} - -void DEMOSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) { - u32 swap = 0; - - if (a == GX_CC_TEXC) { - swap = 0xF; - } else if (a >= GX_CC_TEXRRR) { - swap = a; - a = GX_CC_TEXC; - } - - if (b == GX_CC_TEXC) { - swap = 0xF; - } else if (b >= GX_CC_TEXRRR) { - swap = b; - b = GX_CC_TEXC; - } - - if (c == GX_CC_TEXC) { - swap = 0xF; - } else if (c >= GX_CC_TEXRRR) { - swap = c; - c = GX_CC_TEXC; - } - - if (d == GX_CC_TEXC) { - swap = 0xF; - } else if (d >= GX_CC_TEXRRR) { - swap = d; - d = GX_CC_TEXC; - } - - GXSetTevColorIn(stage, a, b, c, d); - if (swap != 0) { - GXSetTevSwapMode(stage, 0, swap - 0xF); - } -} - -void DEMOSetTevOp(GXTevStageID id, GXTevMode mode) { - GXTevColorArg carg = GX_CC_RASC; - GXTevAlphaArg aarg = GX_TEVSTAGE5; - - if (id != 0) { - carg = 0; - aarg = 0; - } - - switch(mode) { - case 0: - DEMOSetTevColorIn(id, 0xF, 8, carg, 0xF); - GXSetTevAlphaIn(id, 7, 4, aarg, 7); - break; - case 1: - DEMOSetTevColorIn(id, carg, 8, 9, 0xF); - GXSetTevAlphaIn(id, 7, 7, 7, aarg); - break; - case 2: - DEMOSetTevColorIn(id, carg, 0xC, 8, 0xF); - GXSetTevAlphaIn(id, 7, 4, aarg, 7); - break; - case 3: - DEMOSetTevColorIn(id, 0xF, 0xF, 0xF, 8); - GXSetTevAlphaIn(id, 7, 7, 7, 4); - break; - case 4: - DEMOSetTevColorIn(id, 0xF, 0xF, 0xF, carg); - GXSetTevAlphaIn(id, 7, 7, 7, aarg); - break; - default: - ASSERTMSGLINE(914, FALSE, "DEMOSetTevOp: Invalid Tev Mode"); - break; - } - - GXSetTevColorOp(id, 0, 0, 0, 1, 0); - GXSetTevAlphaOp(id, 0, 0, 0, 1, 0); -} - -GXRenderModeObj* DEMOGetRenderModeObj(void) { - return rmode; -} - -u32 DEMOGetCurrentBuffer(void) { - return (u32)DemoCurrentBuffer; -} - -void DEMOEnableGPHangWorkaround(u32 timeoutFrames) { - if (timeoutFrames != 0) { - ASSERTMSGLINE(989, !DemoStatEnable, "DEMOStats and GP hang diagnosis are mutually exclusive"); - GPHangWorkaround = 1; - FrameMissThreshold = timeoutFrames; - VISetPreRetraceCallback(__NoHangRetraceCallback); - DEMOSetGPHangMetric(1); - } else { - GPHangWorkaround = 0; - FrameMissThreshold = 0; - DEMOSetGPHangMetric(0); - VISetPreRetraceCallback(NULL); - } -} - -static void __NoHangRetraceCallback(u32 count) { - static u32 ovFrameCount = 0; - static u32 lastOvc = 0; - u32 ovc; - u8 overhi; - u8 junk; - - FrameCount++; - - GXGetGPStatus(&overhi, &junk, &junk, &junk, &junk); - ovc = GXGetOverflowCount(); - - if (overhi && ovc == lastOvc) { - ovFrameCount++; - if (ovFrameCount >= FrameMissThreshold) { - OSReport("---------WARNING : HANG AT HIGH WATERMARK----------\n"); - __DEMODiagnoseHang(); - OSPanic(__FILE__, 1048, "Halting program"); - } - } else { - lastOvc = ovc; - ovFrameCount = 0; - } -} - -static void __NoHangDoneRender(void) { - BOOL abort = FALSE; - - GXCopyDisp(DemoCurrentBuffer, 1); - GXSetDrawSync(0xB00B); - - FrameCount = 0; - - while (GXReadDrawSync() != 0xB00B && !abort) { - if (FrameCount >= FrameMissThreshold) { - OSReport("---------WARNING : ABORTING FRAME----------\n"); - abort = TRUE; - __DEMODiagnoseHang(); - DEMOReInit(rmode); - DEMOSetGPHangMetric(1); - } - } - - DEMOSwapBuffers(); -} - -void DEMOSetGPHangMetric(u8 enable) { - if (enable) { - GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); - - GXCmd1u8(0x61); - GXParam1u32(0x2402C004); - - GXCmd1u8(0x61); - GXParam1u32(0x23000020); - - GXCmd1u8(0x10); - GXParam1u16(0); - GXParam1u16(0x1006); - GXParam1u32(0x84400); - } else { - GXCmd1u8(0x61); - GXParam1u32(0x24000000); - - GXCmd1u8(0x61); - GXParam1u32(0x23000000); - - GXCmd1u8(0x10); - GXParam1u16(0); - GXParam1u16(0x1006); - GXParam1u32(0); - } -} - -static void __DEMODiagnoseHang(void) { - u32 xfTop0, xfBot0, suRdy0, r0Rdy0; - u32 xfTop1, xfBot1, suRdy1, r0Rdy1; - u32 xfTopD, xfBotD, suRdyD, r0RdyD; - u8 readIdle, cmdIdle; - u8 junk; - - GXReadXfRasMetric(&xfBot0, &xfTop0, &r0Rdy0, &suRdy0); - GXReadXfRasMetric(&xfBot1, &xfTop1, &r0Rdy1, &suRdy1); - - xfTopD = (xfTop1 - xfTop0) == 0; - xfBotD = (xfBot1 - xfBot0) == 0; - suRdyD = (suRdy1 - suRdy0) > 0; - r0RdyD = (r0Rdy1 - r0Rdy0) > 0; - - GXGetGPStatus(&junk, &junk, &readIdle, &cmdIdle, &junk); - OSReport("GP status %d%d%d%d%d%d --> ", readIdle, cmdIdle, xfTopD, xfBotD, suRdyD, r0RdyD); - - if (xfBotD == 0 && suRdyD != 0) { - OSReport("GP hang due to XF stall bug.\n"); - } else if (xfTopD == 0 && xfBotD != 0 && suRdyD != 0) { - OSReport("GP hang due to unterminated primitive.\n"); - } else if (cmdIdle == 0 && xfTopD != 0 && xfBotD != 0 && suRdyD != 0) { - OSReport("GP hang due to illegal instruction.\n"); - } else if (readIdle != 0 && cmdIdle != 0 && xfTopD != 0 && xfBotD != 0 && suRdyD != 0 && r0RdyD != 0) { - OSReport("GP appears to be not hung (waiting for input).\n"); - } else { - OSReport("GP is in unknown state.\n"); - } -} - -void DEMOReInit(GXRenderModeObj* mode) { - u32 fbSize; - GXFifoObj tmpobj; - void* tmpFifo; - GXFifoObj* realFifoObj; - void* realFifoBase; - u32 realFifoSize; - - tmpFifo = OSAlloc(64 * 1024); - - realFifoObj = GXGetCPUFifo(); - realFifoBase = GXGetFifoBase(realFifoObj); - realFifoSize = GXGetFifoSize(realFifoObj); - - GXAbortFrame(); - - GXInitFifoBase(&tmpobj, tmpFifo, 64 * 1024); - - GXSetCPUFifo(&tmpobj); - GXSetGPFifo(&tmpobj); - - __DEMOInitRenderMode(mode); - - fbSize = ((u16)(rmode->fbWidth + 15) & ~0xF) * rmode->xfbHeight * 2; - ASSERTMSGLINE(1260, fbSize <= allocatedFrameBufferSize, "DEMOReInit - Previously allocated frame buffer is too small for the new render mode."); - DefaultFifoObj = GXInit(realFifoBase, realFifoSize); - - __DEMOInitGX(); - VIConfigure(rmode); - __DEMOInitVI(); - OSFree(tmpFifo); -} diff --git a/src/dolphin/demo/DEMOPad.c b/src/dolphin/demo/DEMOPad.c deleted file mode 100644 index 3320523..0000000 --- a/src/dolphin/demo/DEMOPad.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include - -#include "__demo.h" - -static u32 PadChanMask[4] = { - PAD_CHAN0_BIT, - PAD_CHAN1_BIT, - PAD_CHAN2_BIT, - PAD_CHAN3_BIT, -}; - -static PADStatus Pad[4]; -DEMODMPad DemoPad[4]; - -u32 DemoNumValidPads; - -// prototypes -static void DEMOPadCopy(PADStatus* pad, DEMODMPad* dmpad); - -static void DEMOPadCopy(PADStatus* pad, DEMODMPad* dmpad) { - u16 dirs; - - if (pad->err != -3) { - dirs = 0; - if (pad->stickX < -0x30) { - dirs |= 0x4000; - } - if (pad->stickX > 0x30) { - dirs |= 0x8000; - } - if (pad->stickY < -0x30) { - dirs |= 0x2000; - } - if (pad->stickY > 0x30) { - dirs |= 0x1000; - } - if (pad->substickX < -0x30) { - dirs |= 0x400; - } - if (pad->substickX > 0x30) { - dirs |= 0x800; - } - if (pad->substickY < -0x30) { - dirs |= 0x200; - } - if (pad->substickY > 0x30) { - dirs |= 0x100; - } - - dmpad->dirsNew = (dirs & (dmpad->dirs ^ dirs)); - dmpad->dirsReleased = (dmpad->dirs & (dmpad->dirs ^ dirs)); - dmpad->dirs = dirs; - dmpad->buttonDown = (pad->button & (dmpad->pst.button ^ pad->button)); - dmpad->buttonUp = (dmpad->pst.button & (dmpad->pst.button ^ pad->button)); - dmpad->stickDeltaX = (pad->stickX - dmpad->pst.stickX); - dmpad->stickDeltaY = (pad->stickY - dmpad->pst.stickY); - dmpad->substickDeltaX = (pad->substickX - dmpad->pst.substickX); - dmpad->substickDeltaY = (pad->substickY - dmpad->pst.substickY); - dmpad->pst = *pad; - } else { - dmpad->dirsNew = dmpad->dirsReleased = 0; - dmpad->buttonDown = dmpad->buttonUp = 0; - dmpad->stickDeltaX = dmpad->stickDeltaY = 0; - dmpad->substickDeltaX = dmpad->substickDeltaY = 0; - } -} - -void DEMOPadRead(void) { - s32 i; - u32 ResetReq = 0; - - PADRead(&Pad[0]); - PADClamp(&Pad[0]); - - DemoNumValidPads = 0; - - for (i = 0; i < 4; i++) { - if (Pad[i].err == 0 || Pad[i].err == -3) { - DemoNumValidPads++; - } else if (Pad[i].err == -1) { - ResetReq |= PadChanMask[i]; - } - - DEMOPadCopy(&Pad[i], &DemoPad[i]); - } - - if (ResetReq != 0) { - PADReset(ResetReq); - } -} - -void DEMOPadInit(void) { - s32 i; - - PADInit(); - - for (i = 0; i < 4; i++) { - DemoPad[i].pst.button = 0; - DemoPad[i].pst.stickX = 0; - DemoPad[i].pst.stickY = 0; - DemoPad[i].pst.substickX = 0; - DemoPad[i].pst.substickY = 0; - DemoPad[i].pst.triggerLeft = 0; - DemoPad[i].pst.triggerRight = 0; - DemoPad[i].pst.analogA = 0; - DemoPad[i].pst.analogB = 0; - DemoPad[i].pst.err = 0; - DemoPad[i].buttonDown = 0; - DemoPad[i].buttonUp = 0; - DemoPad[i].dirs = 0; - DemoPad[i].dirsNew = 0; - DemoPad[i].dirsReleased = 0; - DemoPad[i].stickDeltaX = 0; - DemoPad[i].stickDeltaY = 0; - DemoPad[i].substickDeltaX = 0; - DemoPad[i].substickDeltaY = 0; - } -} diff --git a/src/dolphin/demo/DEMOPuts.c b/src/dolphin/demo/DEMOPuts.c deleted file mode 100644 index af0ea2f..0000000 --- a/src/dolphin/demo/DEMOPuts.c +++ /dev/null @@ -1,403 +0,0 @@ -#include -#include -#include -#include - -#include "__demo.h" - -static GXTexObj fontTexObj; - -static s32 fontShift; -static OSFontHeader* FontData; -static void* LastSheet; -static s16 FontSize; -static s16 FontSpace; - -// prototypes -static void DrawFontChar(int x, int y, int z, int xChar, int yChar); -static void LoadSheet(void* image, GXTexMapID texMapID); - -void DEMOSetFontType(s32 attr) { - switch(attr) { - case DM_FT_RVS: - GXSetBlendMode(GX_BM_LOGIC, GX_BL_ZERO, GX_BL_ZERO, GX_LO_INVCOPY); - break; - case DM_FT_XLU: - GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); - break; - case DM_FT_OPQ: - default: - GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); - break; - } -} - -void DEMOLoadFont(GXTexMapID texMap, GXTexMtx texMtx, DMTexFlt texFlt) { - Mtx fontTMtx; - u16 width; - u16 height; - - width = 64; - height = 0x1800 / width; - GXInitTexObj(&fontTexObj, (void*)DEMOFontBitmap, width, (u16)height, GX_TF_I4, GX_CLAMP, GX_CLAMP, 0); - - if (texFlt == DMTF_POINTSAMPLE) { - GXInitTexObjLOD(&fontTexObj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); - fontShift = 0; - } else { - fontShift = 1; - } - - GXLoadTexObj(&fontTexObj, texMap); - MTXScale(fontTMtx, 1.0f / width, 1.0f / height, 1.0f); - GXLoadTexMtxImm(fontTMtx, texMtx, GX_MTX2x4); - GXSetNumTexGens(1); - GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, texMtx); -} - -void DEMOSetupScrnSpc(s32 width, s32 height, f32 depth) { - Mtx44 pMtx; - Mtx mMtx; - f32 top; - - if (DEMOGetRenderModeObj()->field_rendering && !VIGetNextField()) { - top = -0.667f; - } else { - top = 0.0f; - } - - MTXOrtho(pMtx, top, height, 0.0f, width, 0.0f, -depth); - GXSetProjection(pMtx, GX_ORTHOGRAPHIC); - MTXIdentity(mMtx); - GXLoadPosMtxImm(mMtx, GX_PNMTX0); - GXSetCurrentMtx(GX_PNMTX0); -} - -void DEMOInitCaption(s32 font_type, s32 width, s32 height) { - DEMOSetupScrnSpc(width, height, 100.0f); - GXSetZMode(GX_ENABLE, GX_ALWAYS, GX_ENABLE); - GXSetNumChans(0); - GXSetNumTevStages(1); - GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); - DEMOLoadFont(GX_TEXMAP0, GX_TEXMTX0, DMTF_POINTSAMPLE); - DEMOSetFontType(font_type); -} - -void DEMOPuts(s16 x, s16 y, s16 z, char* string) { - char* str; - s32 s; - s32 t; - s32 c; - s32 w; - s32 len; - s32 i; - - str = string; - GXClearVtxDesc(); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 1); - - // calc len - len = 0; - while (1) { - c = *(str++); - if ((c >= 0x20) && (c <= 0x7F)) { - len++; - continue; - } - - if (len > 0) { - GXBegin(GX_QUADS, GX_VTXFMT0, len * 4); - for(i = 0; i < len; i++) { - w = string[i] - 0x20; - s = fontShift + ((w % 8) * 0x10); - t = fontShift + ((w / 8) * 0x10); - GXPosition3s16(x + (i * 8), y, z); - GXTexCoord2s16(s, t); - GXPosition3s16(x + (i * 8) + 8, y, z); - GXTexCoord2s16(s + 0x10, t); - GXPosition3s16(x + (i * 8) + 8, y + 8, z); - GXTexCoord2s16(s + 0x10, t + 0x10); - GXPosition3s16(x + (i * 8), y + 8, z); - GXTexCoord2s16(s, t + 0x10); - } - GXEnd(); - len = 0; - } - - string = str; - if (c == 0xA) { - y += 0x8; - } else { - break; - } - } -} - -void DEMOPrintf(s16 x, s16 y, s16 z, char* fmt, ...) { - va_list vlist; - char buf[256]; - - va_start(vlist, fmt); - vsprintf(buf, fmt, vlist); - DEMOPuts(x, y, z, buf); - va_end(vlist); -} - -OSFontHeader* DEMOInitROMFont(void) { - switch (OSGetFontEncode()) { - case OS_FONT_ENCODE_SJIS: - FontData = OSAlloc(OS_FONT_SIZE_SJIS); - break; - case OS_FONT_ENCODE_ANSI: - FontData = OSAlloc(OS_FONT_SIZE_ANSI); - break; - default: - FontData = OSAlloc(0x141020); - break; - } - - if (!FontData) { - OSPanic(__FILE__, 446, "Ins. memory to load ROM font."); - } - - if (OSInitFont(FontData) == 0) { - OSPanic(__FILE__, 450, "ROM font is available in boot ROM ver 0.8 or later."); - } - - FontSize = FontData->cellWidth * 16; - FontSpace = -16; - return FontData; -} - -void DEMOSetROMFontSize(s16 size, s16 space) { - FontSize = size * 16; - FontSpace = space * 16; -} - -void DEMOGetROMFontSize(s16* size, s16* space) { - if (size != 0) { - *size = FontSize / 16; - } - - if (space != 0) { - *space = FontSpace / 16; - } -} - -static void DrawFontChar(int x, int y, int z, int xChar, int yChar) { - s16 posLeft = x; - s16 posRight = posLeft + FontSize; - s16 posTop = y - (FontData->ascent * FontSize / FontData->cellWidth); - s16 posBottom = y + (FontData->descent * FontSize / FontData->cellWidth); - - s16 texLeft = xChar; - s16 texRight = (xChar + FontData->cellWidth); - s16 texTop = yChar; - s16 texBottom = (yChar + FontData->cellHeight); - - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - GXPosition3s16(posLeft, posTop, z); - GXTexCoord2s16(texLeft, texTop); - GXPosition3s16(posRight, posTop, z); - GXTexCoord2s16(texRight, texTop); - GXPosition3s16(posRight, posBottom, z); - GXTexCoord2s16(texRight, texBottom); - GXPosition3s16(posLeft, posBottom, z); - GXTexCoord2s16(texLeft, texBottom); - GXEnd(); -} - -static void LoadSheet(void* image, GXTexMapID texMapID) { - Mtx mtx; - GXTexObj texObj; - - if (LastSheet != image) { - LastSheet = image; - GXInitTexObj(&texObj, image, FontData->sheetWidth, FontData->sheetHeight, FontData->sheetFormat, 0, 0, 0); - GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); - GXLoadTexObj(&texObj, texMapID); - MTXScale(mtx, 1.0f / FontData->sheetWidth, 1.0f / FontData->sheetHeight, 1.0f); - GXLoadTexMtxImm(mtx, GX_TEXMTX0, GX_MTX2x4); - GXSetNumTexGens(1); - GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0); - } -} - -int DEMORFPuts(s16 x, s16 y, s16 z, char* string) { - s32 cx; - void* image; - s32 xChar; - s32 yChar; - s32 width; - - ASSERTLINE(583, FontData); - LastSheet = NULL; - - GXClearVtxDesc(); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 4); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0); - - x *= 16; - y *= 16; - z *= 16; - - width = 0; - while (*string != 0) { - if (*string == '\n') { - width = 0; - y += FontData->leading * FontSize / FontData->cellWidth; - string++; - } else if (*string == '\t') { - width += 8 * (FontSize + FontSpace); - width -= width % (8 * (FontSize + FontSpace)); - string++; - } else { - string = OSGetFontTexture(string, &image, &xChar, &yChar, &cx); - LoadSheet(image, GX_TEXMAP0); - DrawFontChar(x + width, y, z, xChar, yChar); - width = FontSpace + ((FontSize * cx) / FontData->cellWidth) + width; - } - } - - return (width + 15) / 16; -} - -int DEMORFPutsEx(s16 x, s16 y, s16 z, char* string, s16 maxWidth, int length) { - s32 cx; - void* image; - s32 xChar; - s32 yChar; - s32 width; - char* end; - - ASSERTLINE(636, FontData); - LastSheet = NULL; - - GXClearVtxDesc(); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 4); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0); - - x *= 16; - y *= 16; - z *= 16; - maxWidth *= 16; - - end = (char*)&string[length]; - width = 0; - while (*string && string < end) { - if (*string == '\n') { - width = 0; - y += FontData->leading * FontSize / FontData->cellWidth; - string++; - } else { - string = OSGetFontTexture(string, &image, &xChar, &yChar, &cx); - if (maxWidth < width + (FontSize * cx / FontData->cellWidth) + FontSpace) { - width = 0; - y += FontData->leading * FontSize / FontData->cellWidth; - } - LoadSheet(image, GX_TEXMAP0); - DrawFontChar(x + width, y, z, xChar, yChar); - width = FontSpace + (FontSize * cx / FontData->cellWidth) + width; - } - } - - return (width + 15) / 16; -} - -int DEMORFPrintf(s16 x, s16 y, s16 z, char* fmt, ...) { - va_list vlist; - char buf[256]; - - va_start(vlist, fmt); - vsprintf(buf, fmt, vlist); - DEMORFPuts(x, y, z, buf); -} - -char* DEMODumpROMFont(char* string) { - u32 image[288]; - void* temp; - int i; - int j; - s32 width; - - ASSERTLINE(724, FontData); - - switch (OSGetFontEncode()) { - case OS_FONT_ENCODE_SJIS: - temp = (u8*)FontData + OS_FONT_SIZE_SJIS - OS_FONT_ROM_SIZE_SJIS; - break; - case OS_FONT_ENCODE_ANSI: - temp = (u8*)FontData + OS_FONT_SIZE_ANSI - OS_FONT_ROM_SIZE_ANSI; - break; - default: - temp = (u8*)FontData + 0xF4020; - break; - } - - temp = (void*)OSRoundDown32B(temp); - OSLoadFont(FontData, temp); - - memset(image, 0, sizeof(image)); - string = OSGetFontTexel(string, &image[0], 0, 0xC, &width); - for (i = 0; i < 0x30; i++) { - j = (i % 8) + ((i / 8) * 0x30); - OSReport("%08x%08x%08x%08x%08x%08x\n", image[j], image[j+8], image[j+0x10], image[j+0x18], image[j+0x20], image[j+0x28]); - } - - OSReport("\nwidth %d\n", width); - OSInitFont(FontData); - return string; -} - -int DEMOGetRFTextWidth(char* string) { - s32 cx; - s32 width; - s32 maxWidth; - - ASSERTLINE(779, FontData); - maxWidth = width = 0; - - while (*string != 0) { - if (*string == '\n') { - if (maxWidth < width) { - maxWidth = width; - } - - width = 0; - } - - string = OSGetFontWidth(string, &cx); - width = FontSpace + ((FontSize * cx) / FontData->cellWidth) + width; - } - - if (maxWidth < width) { - maxWidth = width; - } - - return (maxWidth + 15) / 16; -} - -int DEMOGetRFTextHeight(char* string) { - s32 height; - - ASSERTLINE(815, FontData); - - height = 1; - while (*string) { - if (*string == '\n') { - height++; - } - string++; - } - - height *= FontData->leading * FontSize / FontData->cellWidth; - return (height + 15) / 16; -} diff --git a/src/dolphin/demo/DEMOStats.c b/src/dolphin/demo/DEMOStats.c deleted file mode 100644 index ca79eff..0000000 --- a/src/dolphin/demo/DEMOStats.c +++ /dev/null @@ -1,416 +0,0 @@ -#include -#include -#include - -#include "__demo.h" - -u8 DemoStatEnable = 0; -static DemoStatData* DemoStat; -static u32 DemoStatIndx; -static u32 DemoStatMaxIndx; -static u32 DemoStatClocks; -static u32 DemoStatDisp; -static u32 DemoStatStrLen; -static u32 topPixIn; -static u32 topPixOut; -static u32 botPixIn; -static u32 botPixOut; -static u32 clrPixIn; -static u32 copyClks; -static u32 vcCheck; -static u32 vcMiss; -static u32 vcStall; -static u32 cpReq; -static u32 tcReq; -static u32 cpuRdReq; -static u32 cpuWrReq; -static u32 dspReq; -static u32 ioReq; -static u32 viReq; -static u32 peReq; -static u32 rfReq; -static u32 fiReq; - -// prototypes -static void DEMOWriteStats(u8 update); -static void DEMOWriteStats(u8 update); - -void DEMOSetStats(DemoStatData* stat, u32 nstats, DEMO_STAT_DISP disp) { - if (stat == 0 || nstats == 0) { - DemoStatEnable = FALSE; - } else { - DemoStatEnable = TRUE; - DemoStat = stat; - DemoStatIndx = 0; - DemoStatMaxIndx = nstats; - DemoStatDisp = disp; - DemoStatStrLen = strlen(DemoStat->text); - } -} - -static void DEMOWriteStats(u8 update) { - u32 cnt0; - u32 cnt1; - u32 cnt2; - u32 cnt3; - u32 cnt4; - u32 cnt5; - u32 cnt6; - u32 cnt7; - u32 cnt8; - u32 cnt9; - - switch (DemoStat[DemoStatIndx].stat_type) { - case DEMO_STAT_GP0: - if (update) { - cnt0 = GXReadGP0Metric(); - DemoStat[DemoStatIndx].count = cnt0; - GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); - } else { - GXSetGPMetric(DemoStat[DemoStatIndx].stat, GX_PERF1_NONE); - GXClearGPMetric(); - } - break; - case DEMO_STAT_GP1: - if (update) { - cnt0 = GXReadGP1Metric(); - DemoStat[DemoStatIndx].count = cnt0; - GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); - } else { - GXSetGPMetric(GX_PERF0_NONE, DemoStat[DemoStatIndx].stat); - GXClearGPMetric(); - } - break; - case DEMO_STAT_MEM: - if (update) { - GXReadMemMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5, &cnt6, &cnt7, &cnt8, &cnt9); - cpReq = cnt0; - tcReq = cnt1; - cpuRdReq = cnt2; - cpuWrReq = cnt3; - dspReq = cnt4; - ioReq = cnt5; - viReq = cnt6; - peReq = cnt7; - rfReq = cnt8; - fiReq = cnt9; - } else { - GXClearMemMetric(); - } - break; - case DEMO_STAT_PIX: - if (update) { - GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); - topPixIn = cnt0; - topPixOut = cnt1; - botPixIn = cnt2; - botPixOut = cnt3; - clrPixIn = cnt4; - copyClks = cnt5; - } else { - GXClearPixMetric(); - } - break; - case DEMO_STAT_VC: - if (update) { - GXReadVCacheMetric(&cnt0, &cnt1, &cnt2); - vcCheck = cnt0; - vcMiss = cnt1; - vcStall = cnt2; - } else { - GXSetVCacheMetric(0); - GXClearVCacheMetric(); - } - break; - case DEMO_STAT_FR: - if (update) { - GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); - topPixIn = cnt0; - topPixOut = cnt1; - botPixIn = cnt2; - botPixOut = cnt3; - clrPixIn = cnt4; - copyClks = cnt5; - DemoStatClocks = GXReadGP0Metric(); - GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); - } else { - GXClearPixMetric(); - GXSetGPMetric(GX_PERF0_CLOCKS, GX_PERF1_NONE); - GXClearGPMetric(); - } - break; - case DEMO_STAT_TBW: - case DEMO_STAT_TBP: - GXClearPixMetric(); - if (update) { - GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); - topPixIn = cnt0; - topPixOut = cnt1; - botPixIn = cnt2; - botPixOut = cnt3; - clrPixIn = cnt4; - copyClks = cnt5; - DemoStatClocks = GXReadGP0Metric(); - GXReadMemMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5, &cnt6, &cnt7, &cnt8, &cnt9); - tcReq = cnt1; - GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); - } else { - GXClearMemMetric(); - GXSetGPMetric(GX_PERF0_CLOCKS, GX_PERF1_NONE); - GXClearGPMetric(); - } - break; - case DEMO_STAT_MYC: - case DEMO_STAT_MYR: - break; - default: - OSPanic(__FILE__, 295, "DEMOSetStats: Unknown demo stat type\n"); - } -} - -void DEMOUpdateStats(u8 inc) { - DEMOWriteStats(inc); - if (inc) { - DemoStatIndx = DemoStatIndx + 1; - if (DemoStatIndx == DemoStatMaxIndx) { - DemoStatIndx = 0; - } - } -} - -void DEMOPrintStats(void) { - GXRenderModeObj* rmode; - u32 i; - s16 text_x; - s16 text_y; - s16 text_yinc; - u16 wd; - u16 ht; - f32 rate; - - if (DemoStatDisp == DEMO_STAT_IO) { - for (i = 0; i < DemoStatMaxIndx; i++) { - switch (DemoStat[i].stat_type) { - case DEMO_STAT_PIX: - switch (DemoStat[i].stat) { - case 0: - OSReport("%s: %8d\n", DemoStat[i].text, topPixIn); - break; - case 1: - OSReport("%s: %8d\n", DemoStat[i].text, topPixOut); - break; - case 2: - OSReport("%s: %8d\n", DemoStat[i].text, botPixIn); - break; - case 3: - OSReport("%s: %8d\n", DemoStat[i].text, botPixOut); - break; - case 4: - OSReport("%s: %8d\n", DemoStat[i].text, clrPixIn); - break; - case 5: - OSReport("%s: %8d\n", DemoStat[i].text, copyClks); - break; - } - break; - case DEMO_STAT_FR: - rate = 162.0f * (topPixIn + botPixIn) / (f32) (DemoStatClocks - copyClks); - OSReport("%s: %8.2f\n", DemoStat[i].text, rate); - break; - case DEMO_STAT_TBW: - rate = 162.0f * (tcReq << 5) / (f32) (DemoStatClocks - copyClks); - OSReport("%s: %8.2f\n", DemoStat[i].text, rate); - break; - case DEMO_STAT_TBP: - rate = (tcReq << 5) / (f32) (topPixIn + botPixIn); - OSReport("%s: %8.2f\n", DemoStat[i].text, rate); - break; - case DEMO_STAT_VC: - switch (DemoStat[i].stat) { - case 0: - OSReport("%s: %8d\n", DemoStat[i].text, vcCheck); - break; - case 1: - OSReport("%s: %8d\n", DemoStat[i].text, vcMiss); - break; - case 2: - OSReport("%s: %8d\n", DemoStat[i].text, vcStall); - break; - } - break; - case DEMO_STAT_MYR: - rate = DemoStat[i].stat / (f32) DemoStat[i].count; - OSReport("%s: %8.2f\n", DemoStat[i].text, rate); - break; - case DEMO_STAT_MEM: - switch (DemoStat[i].stat) { - case 0: - OSReport("%s: %8d\n", DemoStat[i].text, cpReq); - break; - case 1: - OSReport("%s: %8d\n", DemoStat[i].text, tcReq); - break; - case 2: - OSReport("%s: %8d\n", DemoStat[i].text, cpuRdReq); - break; - case 3: - OSReport("%s: %8d\n", DemoStat[i].text, cpuWrReq); - break; - case 4: - OSReport("%s: %8d\n", DemoStat[i].text, dspReq); - break; - case 5: - OSReport("%s: %8d\n", DemoStat[i].text, ioReq); - break; - case 6: - OSReport("%s: %8d\n", DemoStat[i].text, viReq); - break; - case 7: - OSReport("%s: %8d\n", DemoStat[i].text, peReq); - break; - case 8: - OSReport("%s: %8d\n", DemoStat[i].text, rfReq); - break; - case 9: - OSReport("%s: %8d\n", DemoStat[i].text, fiReq); - break; - } - break; - default: - OSReport("%s: %8d\n", DemoStat[i].text, DemoStat[i].count); - break; - } - } - } else { - rmode = DEMOGetRenderModeObj(); - switch (DemoStatDisp) { - case DEMO_STAT_TL: - text_x = 0x10; - text_y = 0x10; - text_yinc = 0xA; - wd = rmode->fbWidth; - ht = rmode->xfbHeight; - break; - case DEMO_STAT_BL: - text_x = 0x10; - text_y = rmode->xfbHeight - 0x18; - text_yinc = -0xA; - wd = rmode->fbWidth; - ht = rmode->xfbHeight; - break; - case DEMO_STAT_TLD: - text_x = 8; - text_y = 8; - text_yinc = 9; - wd = rmode->fbWidth / 2; - ht = rmode->xfbHeight / 2; - break; - case DEMO_STAT_BLD: - text_x = 8; - text_y = (rmode->xfbHeight - 0x18) / 2; - text_yinc = -9; - wd = rmode->fbWidth / 2; - ht = rmode->xfbHeight / 2; - break; - } - DEMOInitCaption(0, wd, ht); - for (i = 0; i < DemoStatMaxIndx; i++) { - switch (DemoStat[i].stat_type) { - case DEMO_STAT_PIX: - switch (DemoStat[i].stat) { - case 0: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, topPixIn); - break; - case 1: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, topPixOut); - break; - case 2: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, botPixIn); - break; - case 3: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, botPixOut); - break; - case 4: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, clrPixIn); - break; - case 5: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, copyClks); - break; - } - break; - case DEMO_STAT_FR: - rate = 162.0f * (topPixIn + botPixIn) / (f32) (DemoStatClocks - copyClks); - DEMOPrintf(text_x, text_y, 0, "%s: %8.2f\n", DemoStat[i].text, rate); - break; - case DEMO_STAT_TBW: - rate = 162.0f * (tcReq << 5) / (f32) (DemoStatClocks - copyClks); - DEMOPrintf(text_x, text_y, 0, "%s: %8.2f\n", DemoStat[i].text, rate); - break; - case DEMO_STAT_TBP: - rate = (tcReq << 5) / (f32) (topPixIn - botPixIn); - DEMOPrintf(text_x, text_y, 0, "%s: %8.3f\n", DemoStat[i].text, rate); - break; - case DEMO_STAT_VC: - switch (DemoStat[i].stat) { - case 0: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcCheck); - break; - case 1: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcMiss); - break; - case 2: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcStall); - break; - } - break; - case DEMO_STAT_MEM: - switch (DemoStat[i].stat) { - case 0: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpReq); - break; - case 1: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, tcReq); - break; - case 2: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpuRdReq); - break; - case 3: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpuWrReq); - break; - case 4: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, dspReq); - break; - case 5: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, ioReq); - break; - case 6: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, viReq); - break; - case 7: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, peReq); - break; - case 8: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, rfReq); - break; - case 9: - DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, fiReq); - break; - } - break; - case DEMO_STAT_GP0: - case DEMO_STAT_GP1: - case DEMO_STAT_MYC: - DEMOPrintf(text_x, text_y, 0, "%s: %8d", DemoStat[i].text, DemoStat[i].count); - break; - case DEMO_STAT_MYR: - rate = DemoStat[i].stat / (f32) DemoStat[i].count; - DEMOPrintf(text_x, text_y, 0, "%s: %8.3f", DemoStat[i].text, rate); - break; - default: - OSReport("Undefined stat type %d in DEMOPrintStats()\n", DemoStat[i].stat_type); - break; - } - text_y += text_yinc; - } - } -} diff --git a/src/dolphin/demo/DEMOWin.c b/src/dolphin/demo/DEMOWin.c deleted file mode 100644 index 108e376..0000000 --- a/src/dolphin/demo/DEMOWin.c +++ /dev/null @@ -1,981 +0,0 @@ -#include -#include -#include - - -static u32 __DEMOWIN_PAD_repeat_threshold = 0x0000000F; -static u32 __DEMOWIN_PAD_repeat_rate = 0x00000002; - -DEMOWindow* __first_node; -DEMOWindow* __last_node; -DEMOWindow* __curr_node; -GXRenderModeObj* __rmp; - -s32 fontShift = 0; - -// functions -static void __DEMOWin_add_node(DEMOWindow* handle); -static void __DEMOWin_delete_node(DEMOWindow* handle); -static void __DEMOWin_puts_n(s16 x, s16 y, s16 z, u16 n, char* string); -static void __DEMOWinMenu_refesh_menu(DEMOWindow* w); -static u16 __DEMOWinMenu_get_user_input(DEMOWinPadInfo* p); -static void __DEMOWinList_refresh_list(DEMOWindow* w); - -void DEMOWinInit() { - __first_node = NULL; - __last_node = NULL; - __curr_node = NULL; - __rmp = DEMOGetRenderModeObj(); - GXSetCopyClear((GXColor){0, 0, 0, 0}, 0xFFFFFF); -} - -DEMOWindow* DEMOWinCreateWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, u16 scroll, void* func) { - DEMOWindow* handle; - ASSERTMSGLINE(188, x1 < x2, "DEMOWIN: Illegal X coords for window\n"); - ASSERTMSGLINE(189, y1 < y2, "DEMOWIN: Illegal y coords for window\n"); - - handle = (void*)OSAlloc(sizeof(DEMOWindow)); - ASSERTMSGLINE(193, handle, "DEMOWIN: FAILED TO ALLOCATE WINDOW!\n"); - - handle->x1 = x1; - handle->y1 = y1; - handle->x2 = x2; - handle->y2 = y2; - handle->pixel_width = (x2 - x1) + 1; - handle->pixel_height = (y2 - y1) + 1; - handle->caption = caption; - handle->char_width = (handle->pixel_width / 8) - 1; - handle->char_height = (handle->pixel_height / 8) - 2; - handle->x_cal = (((handle->pixel_width - (handle->char_width * 8)) + 1) / 2); - handle->y_cal = (((handle->pixel_height - 7) - (handle->char_height * 8)) / 2); - handle->num_scroll_lines = scroll; - handle->total_lines = handle->char_height + handle->num_scroll_lines; - handle->curr_output_line = 0; - handle->curr_output_col = 0; - handle->curr_view_line = 0; - handle->refresh = func; - handle->flags = 0; - handle->priority = 0; - - handle->buffer = (void*)OSAlloc(handle->total_lines * handle->char_width); - ASSERTMSGLINE(249, handle->buffer, "DEMOWinCreateWindow(): Unable to allocation buffer!\n"); - memset(handle->buffer, ' ', handle->total_lines * handle->char_width); // set to all empty spaces - - DEMOWinSetWindowColor(handle, DEMOWIN_ITEM_DEFAULT, 0, 0, 0, 0); - handle->cursor_line = -1; - handle->parent = 0; - __DEMOWin_add_node(handle); - return handle; -} - -void DEMOWinDestroyWindow(DEMOWindow* handle) { - BOOL old; - ASSERTMSGLINE(287, handle, "DEMOWinDestroyWindow(): NULL handle!\n"); - old = OSDisableInterrupts(); - __DEMOWin_delete_node(handle); - OSFree(handle->buffer); - OSFree(handle); - OSRestoreInterrupts(old); -} - -void DEMOWinOpenWindow(DEMOWindow* handle) { - ASSERTMSGLINE(321, handle, "DEMOWinOpenWindow(): NULL handle!\n"); - handle->flags |= DEMOWIN_FLAGS_OPENED; -} - -void DEMOWinCloseWindow(DEMOWindow* handle) { - ASSERTMSGLINE(337, handle, "DEMOWinCloseWindow(): NULL handle!\n"); - handle->flags &= ~(DEMOWIN_FLAGS_OPENED); -} - -void DEMOWinSetWindowColor(DEMOWindow* handle, u32 item, u8 r, u8 g, u8 b, u8 a) { - ASSERTMSGLINE(355, handle, "DEMOWinSetWinColor(): NULL window handle\n"); - - switch(item) { - case DEMOWIN_ITEM_CAP: // set cap - handle->cap.r = r; - handle->cap.g = g; - handle->cap.b = b; - handle->cap.a = a; - return; - case DEMOWIN_ITEM_BORDER: // set border - handle->border.r = r; - handle->border.g = g; - handle->border.b = b; - handle->border.a = a; - return; - case DEMOWIN_ITEM_BKGND: // set background - handle->bkgnd.r = r; - handle->bkgnd.g = g; - handle->bkgnd.b = b; - handle->bkgnd.a = a; - return; - case DEMOWIN_ITEM_DEFAULT: // default window colors - // RGB 26, 31, 33; Cinder (grey) - handle->bkgnd.r = 26; - handle->bkgnd.g = 31; - handle->bkgnd.b = 33; - handle->bkgnd.a = 255; - // RGB 85, 31, 31; Burnt Crimson (red) - handle->cap.r = 85; - handle->cap.g = 31; - handle->cap.b = 31; - handle->cap.a = 255; - // RGB 69, 37, 37; Bulgarian Rose (red) - handle->border.r = 69; - handle->border.g = 37; - handle->border.b = 37; - handle->border.a = 255; - return; - default: - ASSERTMSGLINE(398, FALSE, "DEMOWinSetWinColor(): Unknown item\n"); - return; - } -} - -void DEMOWinLogPrintf(DEMOWindow* handle, char* fmt, ...) { - va_list vlist; - char buffer[128]; - u16 len; - u16 i; - BOOL old; - u16 index; - - va_start(vlist, fmt); - vsprintf(buffer, fmt, vlist); - - old = OSDisableInterrupts(); - len = strlen(buffer); - for (i = 0; i < len; i++) { - if(buffer[i] == 0xA) { - handle->curr_output_line = (handle->curr_output_line + 1) % handle->total_lines; - handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; - handle->curr_output_col = 0; - index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); - memset(&handle->buffer[index], ' ', handle->char_width); - } else { - index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); - handle->buffer[index] = buffer[i]; - handle->curr_output_col++; - } - - if (handle->curr_output_col >= handle->char_width) { - handle->curr_output_col = 0; - handle->curr_output_line = (handle->curr_output_line + 1) % handle->total_lines; - handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; - index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); - memset(&handle->buffer[index], ' ', handle->char_width); - } - } - - OSRestoreInterrupts(old); - va_end(vlist); -} - -void DEMOWinPrintfXY(DEMOWindow* handle, u16 col, u16 row, char* fmt, ...) { - BOOL old; - va_list vlist; - char string[128]; - u16 buffer_row; - u16 i; - u16 index; - - if (row >= handle->char_height || col >= handle->char_width) { - return; - } - - old = OSDisableInterrupts(); - va_start(vlist, fmt); - vsprintf(string, fmt, vlist); - buffer_row = ((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines; - buffer_row = (((buffer_row) + row) % handle->total_lines); - string[handle->char_width - col] = 0; - index = (col + buffer_row* handle->char_width); - - for (i = 0; i < strlen(string); i++) { - handle->buffer[index + i] = string[i]; - } - - OSRestoreInterrupts(old); -} - -void DEMOWinScrollWindow(DEMOWindow* handle, u32 dir) { - BOOL old; - u16 n; - u16 v_start; - - ASSERTMSGLINE(550, handle, "DEMOWinScrollWindow(): NULL handle!\n"); - ASSERTMSGLINE(551, handle->num_scroll_lines, "DEMOWinScrollWindow(): No scrollback buffer!\n"); - - switch(dir) { - case 1: - old = OSDisableInterrupts(); - n = (handle->curr_view_line + handle->total_lines - 1) % handle->total_lines; - v_start = ((n + handle->total_lines) - handle->char_height + 1) % handle->total_lines; - if (v_start != handle->curr_output_line) { - handle->curr_view_line = n; - } - OSRestoreInterrupts(old); - return; - case 2: - old = OSDisableInterrupts(); - if (handle->curr_view_line != handle->curr_output_line) { - handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; - } - OSRestoreInterrupts(old); - return; - case 0: - old = OSDisableInterrupts(); - handle->curr_view_line = handle->curr_output_line; - OSRestoreInterrupts(old); - return; - default: - ASSERTMSGLINE(586, FALSE, "DEMOWinScrollWindow(): Unknown token\n"); - return; - } -} - -void DEMOWinBringToFront(DEMOWindow* handle) { - DEMOWindow* ptr; - ASSERTMSGLINE(609, __first_node, "DEMOWinBringToFront(): Window list is empty!\n"); - ASSERTMSGLINE(610, handle, "DEMOWinBringToFront(): NULL handle!\n"); - - if (handle->priority) { - for(ptr = __first_node; ptr; ptr = ptr->next) { - ptr->priority = 1; - } - handle->priority = 0; - } -} - -void DEMOWinSendToBack(DEMOWindow* handle) { - ASSERTMSGLINE(645, handle, "DEMOWinSendToBack(): NULL handle!\n"); - handle->priority = 1; -} - -void DEMOWinClearRow(DEMOWindow* handle, u16 row) { - u16 buffer_row; - u16 index; - u16 i; - BOOL old; - - ASSERTMSGLINE(669, handle, "DEMOWinClearRow(): NULL handle!\n"); - - if (row < handle->char_height) { - old = OSDisableInterrupts(); - buffer_row = (((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines); - buffer_row = (((buffer_row + row) % handle->total_lines)); - index = (buffer_row* handle->char_width); - - for (i = 0; i < handle->char_width; i++) { - handle->buffer[index + i] = ' '; - } - - OSRestoreInterrupts(old); - } -} - -void DEMOWinClearWindow(DEMOWindow* handle) { - u16 buffer_row; - u16 index; - u16 i; - BOOL old; - - ASSERTMSGLINE(718, handle, "DEMOWinClearWindow(): NULL handle!\n"); - - old = OSDisableInterrupts(); - buffer_row = ((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines; - - for (i = 0; i < handle->char_height; i++) { - index = buffer_row* handle->char_width; - memset(&handle->buffer[index], ' ', handle->char_width); - buffer_row = (buffer_row + 1) % handle->total_lines; - } - - OSRestoreInterrupts(old); -} - -void DEMOWinClearBuffer(DEMOWindow* handle) { - BOOL old; - - ASSERTMSGLINE(752, handle, "DEMOWinClearBuffer(): NULL handle!\n"); - old = OSDisableInterrupts(); - memset(handle->buffer, ' ', handle->total_lines* handle->char_width); - OSRestoreInterrupts(old); -} - -void DEMOWinRefresh(void) { - DEMOWindow* ptr; - u16 i; - u16 index; - u16 n; - u16 y; - BOOL old; - - ASSERTMSGLINE(792, __first_node, "DEMOWinRefresh(): Windowlist is empty!\n"); - - for (ptr = __first_node; ptr; ptr = ptr->next) { - if (ptr->flags & DEMOWIN_FLAGS_OPENED) { - GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); - GXClearVtxDesc(); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); - GXSetNumChans(1); - GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); - GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GXSetNumTexGens(0); - GXSetNumTevStages(1); - GXSetLineWidth(6, GX_TO_ZERO); - - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); - GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); - GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); - GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); - GXPosition3f32(ptr->x2, ptr->y2, ptr->priority); - GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); - GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); - GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); - GXEnd(); - - GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); - - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); - GXColor4u8(ptr->cap.r, ptr->cap.g, ptr->cap.b, 255); - GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); - GXColor4u8(0, 0, 0, 0x40); - GXPosition3f32(ptr->x2, ptr->y1 + 10, ptr->priority); - GXColor4u8(0, 0, 0, 0x40); - GXPosition3f32(ptr->x1, ptr->y1 + 10, ptr->priority); - GXColor4u8(ptr->cap.r, ptr->cap.g, ptr->cap.b, 255); - GXEnd(); - - GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); - - // macro? - do { - // would initialize on init, but DWARF order for 2nd macro suggests they didnt init on same declare. - u8 r1; - u8 g1; - u8 b1; - u8 r2; - u8 g2; - u8 b2; - u8 a; - - r1 = 1.3 * (f32)ptr->border.r; - g1 = 1.3 * (f32)ptr->border.g; - b1 = 1.3 * (f32)ptr->border.b; - r2 = 0.4 * (f32)ptr->border.r; - g2 = 0.4 * (f32)ptr->border.g; - b2 = 0.4 * (f32)ptr->border.b; - a = 64; - - GXSetLineWidth(6, GX_TO_ZERO); - - GXBegin(GX_LINESTRIP, GX_VTXFMT0, 7); - GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); - GXColor4u8(r1, g1, b1, a); - GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); - GXColor4u8(r1, g1, b1, a); - GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); - GXColor4u8(r2, g2, b2, a); - GXPosition3f32(ptr->x2, ptr->y2, ptr->priority); - GXColor4u8(r2, g2, b2, a); - GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); - GXColor4u8(r2, g2, b2, a); - GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); - GXColor4u8(r1, g1, b1, a); - GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); - GXColor4u8(r1, g1, b1, a); - GXEnd(); - } while(0); - - if (ptr->refresh) { - ptr->refresh(ptr); - } - - DEMOInitCaption(DM_FT_XLU, __rmp->fbWidth, __rmp->efbHeight); - GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); - - old = OSDisableInterrupts(); - y = (ptr->y2 - 8) - ptr->y_cal; - n = ptr->curr_view_line; - index = n* ptr->char_width; - - for (i = 0; i < ptr->char_height; i++) { - __DEMOWin_puts_n(ptr->x1 + ptr->x_cal, y, ptr->priority, ptr->char_width, (void*)&ptr->buffer[index]); - y = y - 8; - n = (n + (ptr->total_lines) - 1) % ptr->total_lines; - index = n* ptr->char_width; - } - - DEMOPrintf(ptr->x1 + 2, ptr->y1, ptr->priority, "%s", ptr->caption); - - if (ptr->cursor_line >= 0) { - GXSetLineWidth(6, GX_TO_ZERO); - GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); - GXClearVtxDesc(); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); - GXSetNumChans(1); - GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); - GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GXSetNumTexGens(0); - GXSetNumTevStages(1); - GXSetLineWidth(6, GX_TO_ZERO); - - // macro? - do { - u8 r; - u8 g; - u8 b; - u8 a; - s32 curr_y; - - curr_y = (ptr->y2 - 8) - ptr->y_cal; - curr_y -= ((ptr->char_height - 1) * 8) - ptr->cursor_line * 8; - r = 1.9 * (f32)ptr->bkgnd.r; - g = 1.9 * (f32)ptr->bkgnd.g; - b = 1.9 * (f32)ptr->bkgnd.b; - - a = 100; - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - GXPosition3f32(ptr->x1, curr_y, ptr->priority); - GXColor4u8(r, g, b, a); - GXPosition3f32(ptr->x2, curr_y, ptr->priority); - GXColor4u8(r, g, b, a); - GXPosition3f32(ptr->x2, (f32)(curr_y + 8), ptr->priority); - GXColor4u8(r, g, b, a); - GXPosition3f32(ptr->x1, (f32)(curr_y + 8), ptr->priority); - GXColor4u8(r, g, b, a); - GXEnd(); - } while(0); - } - OSRestoreInterrupts(old); - } - } -} - -static void __DEMOWin_add_node(DEMOWindow* handle) { - ASSERTMSGLINE(1032, handle, "__add_node(): you're adding a NULL node!\n"); - - // WHY. why it backwards. who writes like this? - if (NULL == __last_node) { - __curr_node = handle; - __last_node = handle; - __first_node = handle; - handle->next = 0; - handle->prev = 0; - ASSERTMSGLINE(1042, __first_node, " > __first_node: NULL HANDLE!\n"); - } else { - __last_node->next = handle; - handle->next = 0; - handle->prev = __last_node; - __last_node = handle; - } - - handle->flags |= DEMOWIN_FLAGS_INIT; -} - -static void __DEMOWin_delete_node(DEMOWindow* handle) { - ASSERTMSGLINE(1071, handle, "__delete_node(): you're deleting a NULL node!\n"); - - if (__first_node == handle) { - if (handle->next) { - __first_node = handle->next; - handle->next->prev = NULL; - } else { - __first_node = __last_node = NULL; - } - } else if (__last_node == handle) { - if (handle->prev) { - __last_node = handle->prev; - handle->prev->next = NULL; - } else { - __first_node = __last_node = NULL; - } - } else { - handle->prev->next = handle->next; - handle->next->prev = handle->prev; - } - - handle->flags &= ~(DEMOWIN_FLAGS_INIT); -} - -static void __DEMOWin_puts_n(s16 x, s16 y, s16 z, u16 n, char* string) { - s32 s; - s32 t; - s32 w; - s32 len; - s32 i; - - GXClearVtxDesc(); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 1); - - len = n; - if (len > 0) { - GXBegin(GX_QUADS, GX_VTXFMT0, len * 4); - for (i = 0; i < len; i++) { - w = string[i] - 0x20; - s = fontShift + (((w) % 8) * 16); - t = fontShift + (((w) / 8) * 16); - GXPosition3s16(x + (i * 8), y, z); - GXTexCoord2s16(s, t); - GXPosition3s16(x + (i * 8) + 8, y, z); - GXTexCoord2s16(s + 16, t); - GXPosition3s16(x + (i * 8) + 8, y + 8, z); - GXTexCoord2s16(s + 16, t + 16); - GXPosition3s16(x + (i * 8), y + 8, z); - GXTexCoord2s16(s, t + 16); - } - GXEnd(); - } -} - -DEMOWinMenu* DEMOWinCreateMenuWindow(DEMOWinMenu* menu, u16 x, u16 y) { - DEMOWinMenuItem* ptr; - - ptr = menu->items; - menu->max_str_len = strlen(menu->title); - menu->num_items = 0; - - while(!(ptr->flags & 0x80000000)) { - if (strlen(ptr->name) > menu->max_str_len) { - menu->max_str_len = strlen(ptr->name); - } - menu->num_items++; - ptr++; - } - - if (menu->num_items > menu->max_display_items) { - menu->num_display_items = menu->max_display_items; - } else { - menu->num_display_items = menu->num_items; - } - - menu->handle = DEMOWinCreateWindow((s16)x, (s16)y, (s16)(((menu->max_str_len + 7) * 8) + 4 + x), (s16)(((menu->num_display_items + 2) * 8) + 4 + y), menu->title, 0, __DEMOWinMenu_refesh_menu); - menu->handle->parent = menu; - if (menu->num_items) { - return menu; - } - - return NULL; -} - -void DEMOWinDestroyMenuWindow(DEMOWinMenu* menu) { - if (menu->handle) { - DEMOWinCloseWindow(menu->handle); - DEMOWinDestroyWindow(menu->handle); - menu->handle = NULL; - } -} - -u32 DEMOWinMenuChild(DEMOWinMenu* menu, int child_flag) { - DEMOWinPadInfo* pad; - DEMOWindow* handle; - u16 user_input; - int exit_flag; - u32 result; - - exit_flag = 0; - result = 0; - handle = menu->handle; - pad = &menu->handle->pad; - - DEMOWinOpenWindow(handle); - DEMOWinBringToFront(handle); - menu->curr_pos = 0; - menu->display_pos = 0; - - if(menu->cb_open) { - menu->cb_open(menu, menu->curr_pos); - } - - DEMOWinPadInit(pad); - DEMOBeforeRender(); - DEMOWinRefresh(); - DEMODoneRender(); - DEMOWinPadRead(pad); - DEMOBeforeRender(); - DEMOWinRefresh(); - DEMODoneRender(); - - while (!exit_flag) { - user_input = __DEMOWinMenu_get_user_input(pad); - switch(user_input) { - case 1: - menu->curr_pos = ((menu->curr_pos - 1 + menu->num_items) % menu->num_items) & 0xFFFF; - while (menu->items[menu->curr_pos].flags & 9) { - menu->curr_pos = ((menu->curr_pos - 1 + menu->num_items) % menu->num_items) & 0xFFFF; - } - if (menu->cb_move) { - menu->cb_move(menu, menu->curr_pos); - } - break; - case 2: - menu->curr_pos = ((menu->curr_pos + 1) % menu->num_items) & 0xFFFF; - while (menu->items[menu->curr_pos].flags & 9) { - menu->curr_pos = ((menu->curr_pos + 1) % menu->num_items) & 0xFFFF; - } - if (menu->cb_move) { - menu->cb_move(menu, menu->curr_pos); - } - break; - case 3: - if (child_flag == 1) { - exit_flag = 1; - if (menu->cb_cancel) { - menu->cb_cancel(menu, menu->curr_pos); - } - } - break; - case 4: - if (menu->cb_move) { - menu->cb_move(menu, menu->curr_pos); - } - if (menu->items[menu->curr_pos].link) { - if (menu->items[menu->curr_pos].link->handle) { - menu->items[menu->curr_pos].link->handle->x1 = (handle->x1 + 20) & 0xFFFF; - menu->items[menu->curr_pos].link->handle->y1 = (handle->y1 + 20) & 0xFFFF; - result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); - if (menu->items[menu->curr_pos].link->flags & 1) { - exit_flag = 1; - } - } else { - DEMOWinCreateMenuWindow(menu->items[menu->curr_pos].link, (handle->x1 + 20), (handle->y1 + 20)); - result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); - if (menu->items[menu->curr_pos].link->flags & 1) { - exit_flag = 1; - } - DEMOWinDestroyMenuWindow(menu->items[menu->curr_pos].link); - } - VIWaitForRetrace(); - DEMOWinPadRead(pad); - } - break; - case 5: - if (menu->cb_select) { - menu->cb_select(menu, menu->curr_pos); - } - if (menu->items[menu->curr_pos].link) { - if (menu->items[menu->curr_pos].link->handle) { - menu->items[menu->curr_pos].link->handle->x1 = (handle->x1 + 20) & 0xFFFF; - menu->items[menu->curr_pos].link->handle->y1 = (handle->y1 + 20) & 0xFFFF; - result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); - if (menu->items[menu->curr_pos].link->flags & 1) { - exit_flag = 1; - } - } else { - DEMOWinCreateMenuWindow(menu->items[menu->curr_pos].link, (handle->x1 + 20), (handle->y1 + 20)); - result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); - if (menu->items[menu->curr_pos].link->flags & 1) { - exit_flag = 1; - } - DEMOWinDestroyMenuWindow(menu->items[menu->curr_pos].link); - } - VIWaitForRetrace(); - DEMOWinPadRead(pad); - } else if (menu->items[menu->curr_pos].function) { - menu->items[menu->curr_pos].function(menu, menu->curr_pos, &result); - if (menu->items[menu->curr_pos].flags & 0x10) { - exit_flag = 1; - } - VIWaitForRetrace(); - DEMOWinPadRead(pad); - } - break; - case 6: - if (menu->cb_cancel) { - menu->cb_cancel(menu, menu->curr_pos); - } - exit_flag = 1; - break; - } - - if (menu->curr_pos > (menu->display_pos + menu->num_display_items - 1)) { - menu->display_pos = (menu->curr_pos - menu->num_display_items) + 1; - } else if (menu->curr_pos < menu->display_pos) { - menu->display_pos = menu->curr_pos; - } - - if (menu->display_pos > menu->curr_pos) { - handle->cursor_line = (menu->display_pos - menu->curr_pos); - } else { - handle->cursor_line = (menu->curr_pos - menu->display_pos); - } - - DEMOBeforeRender(); - DEMOWinRefresh(); - DEMODoneRender(); - } - - DEMOWinCloseWindow(handle); - DEMOBeforeRender(); - DEMOWinRefresh(); - DEMODoneRender(); - return result; -} - -static void __DEMOWinMenu_refesh_menu(DEMOWindow* w) { - DEMOWinMenu* m; - s32 i; - s32 j; - char check; - char para_start; - char para_end; - char link; - - DEMOWinClearWindow(w); - m = w->parent; - j = m->display_pos; - - for (i = 0; i < m->num_display_items; j++, i++) { - if (m->items[j].flags & 8) { - if (strlen(m->items[j & 0xFFFF].name)) { - DEMOWinPrintfXY(w, 0, i, " %s ", m->items[j & 0xFFFF].name); - } - } else { - check = (s8)((m->items[j].flags & 4) ? 'X' : ' '); - para_start = (s8)((m->items[j].flags & 1) ? '(' : ' '); - para_end = (s8)((m->items[j].flags & 1) ? ')' : ' '); - link = (s8)((NULL != m->items[j].link) ? '>' : ' '); - DEMOWinPrintfXY(w, 0, i, "%c %c%s%c %c", check, para_start, m->items[j & 0xFFFF].name, para_end, link); - } - } -} - -void DEMOWinPadInit(DEMOWinPadInfo* p) { - u16 i; - - for (i = 0; i < 4; i++) { - p->old_button[i] = 0; - p->changed_button[i] = 0; - p->repeat_button[i] = 0; - p->repeat_ctr[i] = 0; - } -} - -void DEMOWinPadRead(DEMOWinPadInfo* p) { - PADStatus* pad; - u16 index; - u32 curr; - u32 old; - u32 repeat; - - PADRead(p->pads); - - for (index = 0; index < 4; index++) { - old = p->old_button[index]; - pad = &p->pads[index]; - - curr = ((pad->stickX > 0x40 ? 0x00040000 : 0) - | (pad->stickX < -0x40 ? 0x00080000 : 0) - | (pad->stickY > 0x40 ? 0x00010000 : 0) - | (pad->stickY < -0x40 ? 0x00020000 : 0) - | (pad->substickX > +0x40 ? 0x00400000 : 0) - | (pad->substickX < -0x40 ? 0x00800000 : 0) - | (pad->substickY > +0x40 ? 0x00100000 : 0) - | (pad->substickY < -0x40 ? 0x00200000 : 0) - | (pad->triggerLeft > +0x80 ? 0x02000000 : 0) - | (pad->triggerRight > +0x80 ? 0x01000000 : 0) - | pad->button); - - p->changed_button[index] = (curr & (old ^ curr)); - if (curr) { - if (old == curr) { - p->repeat_ctr[index]++; - } else { - p->repeat_ctr[index] = 1; - } - } else { - p->repeat_ctr[index] = 0; - } - - repeat = p->repeat_ctr[index]; - - if (repeat == 1) { - p->repeat_button[index] = curr; - } else if (repeat > __DEMOWIN_PAD_repeat_threshold) { - if (((repeat - __DEMOWIN_PAD_repeat_threshold) % __DEMOWIN_PAD_repeat_rate) == 0) { - p->repeat_button[index] = curr; - } else { - p->repeat_button[index] = 0; - } - } else { - p->repeat_button[index] = 0; - } - - p->old_button[index] = curr; - } -} - -static u16 __DEMOWinMenu_get_user_input(DEMOWinPadInfo* p) { - u16 user_input; - - DEMOWinPadRead(p); - if (p->repeat_button[0] & 0x00010008) { - user_input = 1; - } else if (p->repeat_button[0] & 0x00020004) { - user_input = 2; - } else if (p->repeat_button[0] & 0x00080001) { - user_input = 3; - } else if (p->repeat_button[0] & 0x00040002) { - user_input = 4; - } else if (p->changed_button[0] & 0x00000100) { - user_input = 5; - } else if (p->changed_button[0] & 0x00000200) { - user_input = 6; - } else { - user_input = 0; - } - - return user_input; -} - -void DEMOWinSetRepeat(u32 threshold, u32 rate) { - __DEMOWIN_PAD_repeat_rate = rate; - __DEMOWIN_PAD_repeat_threshold = threshold; -} - -void DEMOWinResetRepeat(void) { - __DEMOWIN_PAD_repeat_threshold = 15; - __DEMOWIN_PAD_repeat_rate = 2; -} - -DEMOWinListbox* DEMOWinCreateListWindow(DEMOWinListbox* list, u16 x, u16 y) { - DEMOWinListboxItem* ptr; - ASSERTMSGLINE(1846, list, "DEMOWinCreateListWindow(): List is NULL!\n"); - - ptr = list->items; - list->max_str_len = strlen(list->title); - list->num_items = 0; - - while (!(ptr->flags & 0x80000000)) { - if (strlen(ptr->name) > list->max_str_len) { - list->max_str_len = strlen(ptr->name); - } - list->num_items++; - ptr++; - } - - if (list->num_items > list->max_display_items) { - list->num_display_items = list->max_display_items; - } else { - list->num_display_items = list->num_items; - } - - list->handle = DEMOWinCreateWindow((s16)x, (s16)y, (s16)((list->max_str_len + 7) * 8 + 4 + x), (s16)((list->num_display_items + 2) * 8 + 4 + y), list->title, 0, __DEMOWinList_refresh_list); - list->handle->parent = list; - if (list->num_items) { - return list; - } - return NULL; -} - -void DEMOWinDestroyListWindow(DEMOWinListbox* list) { - if (list->handle) { - DEMOWinCloseWindow(list->handle); - DEMOWinDestroyWindow(list->handle); - list->handle = NULL; - } -} - -static void __DEMOWinList_refresh_list(DEMOWindow* w) { - DEMOWinListbox* l; - s32 i; - s32 j; - - l = w->parent; - l->curr_pos = (l->curr_pos % l->num_items); - if (l->curr_pos > (l->display_pos + l->num_display_items - 1)) { - l->display_pos = (l->curr_pos - l->num_display_items + 1); - } else if(l->curr_pos < l->display_pos) { - l->display_pos = l->curr_pos; - } - - if (l->cursor_state != 0) { - if(l->display_pos > l->curr_pos) { - w->cursor_line = (l->display_pos - l->curr_pos); - } else { - w->cursor_line = (l->curr_pos - l->display_pos); - } - } else { - w->cursor_line = -1; - } - - DEMOWinClearWindow(w); - - j = l->display_pos; - for (i = 0; i < l->num_display_items; i++) { - if (!(l->items[j].flags & 0x8)) { - DEMOWinPrintfXY(w, 0, i, " %s ", l->items[j & 0xFFFF].name); - } - j++; - } -} - -void DEMOWinListSetCursor(DEMOWinListbox* list, int x) { - list->cursor_state = x; -} - -s32 DEMOWinListScrollList(DEMOWinListbox* list, u32 dir) { - ASSERTMSGLINE(2032, list, "DEMOWinListScrollList(): NULL handle!\n"); - - switch(dir) { - case 1: - if (list->display_pos) { - list->display_pos = (u16)((list->display_pos - 1 + list->num_items) % list->num_items); - } - break; - case 2: - if (list->display_pos < (list->num_items - list->num_display_items)) { - list->display_pos = (u16)((list->display_pos + 1) % list->num_items); - } - break; - case 0: - list->display_pos = 0; - break; - default: - ASSERTMSGLINE(2057, FALSE, "DEMOWinListScrollList(): Invalid dimension!\n"); - break; - } - - if (list->curr_pos > (list->display_pos + list->num_display_items - 1)) { - list->curr_pos = (list->display_pos + list->num_display_items - 1); - } else if (list->curr_pos < list->display_pos) { - list->curr_pos = list->display_pos; - } - - return list->display_pos; -} - -s32 DEMOWinListMoveCursor(DEMOWinListbox* list, u32 dir) { - ASSERTMSGLINE(2092, list, "DEMOWinListScrollList(): NULL handle!\n"); - - switch (dir) { - case 1: - list->curr_pos = (list->curr_pos + list->num_items - 1) % list->num_items; - break; - case 2: - list->curr_pos = (list->curr_pos + 1) % list->num_items; - break; - default: - ASSERTMSGLINE(2105, FALSE, "DEMOWinListMoveCursor(): Invalid dimension!\n"); - break; - } - - return list->curr_pos; -} diff --git a/src/dolphin/demo/__demo.h b/src/dolphin/demo/__demo.h deleted file mode 100644 index 47f0826..0000000 --- a/src/dolphin/demo/__demo.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _DOLPHIN_DEMO_INTERNAL_H_ -#define _DOLPHIN_DEMO_INTERNAL_H_ - -#include - -extern struct STRUCT_DEMOWIN * __first_node; -extern struct STRUCT_DEMOWIN * __last_node; -extern struct STRUCT_DEMOWIN * __curr_node; -extern struct _GXRenderModeObj * __rmp; - -#endif // _DOLPHIN_DEMO_INTERNAL_H_ diff --git a/src/dolphin/dsp/__dsp.h b/src/dolphin/dsp/__dsp.h deleted file mode 100644 index a739806..0000000 --- a/src/dolphin/dsp/__dsp.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _DOLPHIN_DSP_INTERNAL_H_ -#define _DOLPHIN_DSP_INTERNAL_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern DSPTaskInfo* __DSP_first_task; -extern DSPTaskInfo* __DSP_last_task; -extern DSPTaskInfo* __DSP_curr_task; -extern DSPTaskInfo* __DSP_tmp_task; - -void __DSPHandler(__OSInterrupt, OSContext*); -void __DSP_exec_task(DSPTaskInfo*, DSPTaskInfo*); -void __DSP_boot_task(DSPTaskInfo*); -void __DSP_insert_task(DSPTaskInfo*); -void __DSP_add_task(DSPTaskInfo* task); -void __DSP_remove_task(DSPTaskInfo* task); -void __DSP_debug_printf(const char* fmt, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/dolphin/dsp/dsp.c b/src/dolphin/dsp/dsp.c deleted file mode 100644 index d5570b1..0000000 --- a/src/dolphin/dsp/dsp.c +++ /dev/null @@ -1,185 +0,0 @@ -#include -#include -#include - -#include "__dsp.h" - -#define BUILD_DATE "Apr 5 2004" -#if DEBUG -#define BUILD_TIME "03:56:49" -#else -#define BUILD_TIME "04:15:32" -#endif - -#ifdef DEBUG -const char* __DSPVersion = "<< Dolphin SDK - DSP\tdebug build: Apr 5 2004 03:56:49 (0x2301) >>"; -#else -const char* __DSPVersion = "<< Dolphin SDK - DSP\trelease build: Apr 5 2004 04:15:32 (0x2301) >>"; -#endif - -extern DSPTaskInfo* __DSP_rude_task; -extern int __DSP_rude_task_pending; - -static BOOL __DSP_init_flag; - - -u32 DSPCheckMailToDSP(void) { - return (__DSPRegs[0] & (1 << 15)) >> 15; -} - -u32 DSPCheckMailFromDSP(void) { - return (__DSPRegs[2] & (1 << 15)) >> 15; -} - -u32 DSPReadCPUToDSPMbox(void) { - return (__DSPRegs[0] << 16) | __DSPRegs[1]; -} - -u32 DSPReadMailFromDSP(void) { - return (__DSPRegs[2] << 16) | __DSPRegs[3]; -} - -void DSPSendMailToDSP(u32 mail) { - __DSPRegs[0] = mail >> 16; - __DSPRegs[1] = mail & 0xFFFF; -} - -void DSPAssertInt(void) { - BOOL old; - u16 tmp; - - old = OSDisableInterrupts(); - tmp = __DSPRegs[5]; - tmp = (tmp & ~0xA8) | 2; - __DSPRegs[5] = tmp; - OSRestoreInterrupts(old); -} - -void DSPInit(void) { - BOOL old; - u16 tmp; - - __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", BUILD_DATE, BUILD_TIME); - - if (__DSP_init_flag == 1) - return; - - OSRegisterVersion(__DSPVersion); - - old = OSDisableInterrupts(); - __OSSetInterruptHandler(7, __DSPHandler); - __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_DSP); - - tmp = __DSPRegs[5]; - tmp = (tmp & ~0xA8) | 0x800; - __DSPRegs[5] = tmp; - - tmp = __DSPRegs[5]; - __DSPRegs[5] = tmp = tmp & ~0xAC; - - __DSP_first_task = __DSP_last_task = __DSP_curr_task = __DSP_tmp_task = NULL; - __DSP_init_flag = 1; - - OSRestoreInterrupts(old); -} - -BOOL DSPCheckInit(void) { - return __DSP_init_flag; -} - -void DSPReset(void) { - BOOL old; - u16 tmp; - - old = OSDisableInterrupts(); - tmp = __DSPRegs[5]; - tmp = (tmp & ~0xA8) | 0x800 | 1; - __DSPRegs[5] = tmp; - __DSP_init_flag = 0; - OSRestoreInterrupts(old); -} - -void DSPHalt(void) { - BOOL old; - u16 tmp; - - old = OSDisableInterrupts(); - tmp = __DSPRegs[5]; - tmp = (tmp & ~0xA8) | 4; - __DSPRegs[5] = tmp; - OSRestoreInterrupts(old); -} - -void DSPUnhalt(void) { - BOOL old; - u16 tmp; - - old = OSDisableInterrupts(); - tmp = __DSPRegs[5]; - tmp = (tmp & ~0xAC); - __DSPRegs[5] = tmp; - OSRestoreInterrupts(old); -} - -u32 DSPGetDMAStatus(void) { - return (__DSPRegs[5] & (1 << 9)); -} - -DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) { - BOOL old; - - ASSERTMSGLINE(556, __DSP_init_flag == 1, "DSPAddTask(): DSP driver not initialized!\n"); - - old = OSDisableInterrupts(); - - __DSP_insert_task(task); - task->state = 0; - task->flags = 1; - - OSRestoreInterrupts(old); - if (task == __DSP_first_task) - __DSP_boot_task(task); - return task; -} - -DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task) { - BOOL old; - - ASSERTMSGLINE(592, __DSP_init_flag == 1, "DSPCancelTask(): DSP driver not initialized!\n"); - - old = OSDisableInterrupts(); - - task->flags |= 2; - - OSRestoreInterrupts(old); - return task; -} - -DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task) { - s32 old; - - ASSERTMSGLINE(623, __DSP_init_flag == 1, "DSPAssertTask(): DSP driver not initialized!\n"); - ASSERTMSGLINE(624, task->flags & 1, "DSPAssertTask(): Specified task not in active task list!\n"); - - old = OSDisableInterrupts(); - - if (__DSP_curr_task == task) { - __DSP_rude_task = task; - __DSP_rude_task_pending = 1; - OSRestoreInterrupts(old); - return task; - } - - if (task->priority < __DSP_curr_task->priority) { - __DSP_rude_task = task; - __DSP_rude_task_pending = 1; - if (__DSP_curr_task->state == 1) { - DSPAssertInt(); - } - OSRestoreInterrupts(old); - return task; - } - - OSRestoreInterrupts(old); - return NULL; -} diff --git a/src/dolphin/dsp/dsp_debug.c b/src/dolphin/dsp/dsp_debug.c deleted file mode 100644 index 3cb3fb0..0000000 --- a/src/dolphin/dsp/dsp_debug.c +++ /dev/null @@ -1,9 +0,0 @@ -#include - -#include "__dsp.h" - -void __DSP_debug_printf(const char* fmt, ...) {} - -DSPTaskInfo* __DSPGetCurrentTask(void) { - return __DSP_curr_task; -} diff --git a/src/dolphin/dsp/dsp_perf.c b/src/dolphin/dsp/dsp_perf.c deleted file mode 100644 index e69de29..0000000 diff --git a/src/dolphin/dsp/dsp_task.c b/src/dolphin/dsp/dsp_task.c deleted file mode 100644 index be844c3..0000000 --- a/src/dolphin/dsp/dsp_task.c +++ /dev/null @@ -1,362 +0,0 @@ -#include - -#include -#include - -#include "__dsp.h" - -static u32 t0, t1, t2; // unused - -DSPTaskInfo* __DSP_curr_task; -DSPTaskInfo* __DSP_first_task; -DSPTaskInfo* __DSP_last_task; -DSPTaskInfo* __DSP_tmp_task; -DSPTaskInfo* __DSP_rude_task; -int __DSP_rude_task_pending; - -void __DSPHandler(__OSInterrupt intr, OSContext* context) { - u8 unused[4]; - OSContext exceptionContext; - u16 tmp; - u32 mail; - - tmp = __DSPRegs[5]; - tmp = (tmp & ~0x28) | 0x80; - __DSPRegs[5] = tmp; - - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - ASSERTMSGLINE(143, __DSP_curr_task != NULL, "__DSPHandler(): No current task! Someone set us up the bomb!\n"); - - while (DSPCheckMailFromDSP() == 0) - ; - - mail = DSPReadMailFromDSP(); - if ((__DSP_curr_task->flags & (1<<(31-0x1E))) && (mail + 0x232F0000) == 2) - mail = 0xDCD10003; - - switch (mail) { - case 0xDCD10000: - __DSP_curr_task->state = 1; - if (__DSP_curr_task->init_cb != NULL) - __DSP_curr_task->init_cb(__DSP_curr_task); - break; - case 0xDCD10001: - __DSP_curr_task->state = 1; - if (__DSP_curr_task->res_cb != NULL) - __DSP_curr_task->res_cb(__DSP_curr_task); - break; - case 0xDCD10002: - if (__DSP_rude_task_pending) { - if (__DSP_curr_task == __DSP_rude_task) { - DSPSendMailToDSP(0xCDD10003); - while (DSPCheckMailToDSP() != 0) - ; - __DSP_rude_task = NULL; - __DSP_rude_task_pending = 0; - - if (__DSP_curr_task->res_cb != NULL) - __DSP_curr_task->res_cb(__DSP_curr_task); - } else { - DSPSendMailToDSP(0xCDD10001); - while (DSPCheckMailToDSP() != 0) - ; - __DSP_exec_task(__DSP_curr_task, __DSP_rude_task); - __DSP_curr_task->state = 2; - __DSP_curr_task = __DSP_rude_task; - __DSP_rude_task = NULL; - __DSP_rude_task_pending = 0; - } - } else { - if (__DSP_curr_task->next == NULL) { - if (__DSP_curr_task == __DSP_first_task) { - DSPSendMailToDSP(0xCDD10003); - while (DSPCheckMailToDSP() != 0) - ; - if (__DSP_curr_task->res_cb != NULL) - __DSP_curr_task->res_cb(__DSP_curr_task); - } else { - DSPSendMailToDSP(0xCDD10001); - while (DSPCheckMailToDSP() != 0) - ; - __DSP_exec_task(__DSP_curr_task, __DSP_first_task); - __DSP_curr_task->state = 2; - __DSP_curr_task = __DSP_first_task; - } - } else { - DSPSendMailToDSP(0xCDD10001); - while (DSPCheckMailToDSP() != 0) - ; - __DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next); - __DSP_curr_task->state = 2; - __DSP_curr_task = __DSP_curr_task->next; - } - } - break; - case 0xDCD10003: - if (__DSP_rude_task_pending) { - if (__DSP_curr_task->done_cb != NULL) - __DSP_curr_task->done_cb(__DSP_curr_task); - - DSPSendMailToDSP(0xCDD10001); - while (DSPCheckMailToDSP() != 0) - ; - __DSP_exec_task(NULL, __DSP_rude_task); - __DSP_remove_task(__DSP_curr_task); - __DSP_curr_task = __DSP_rude_task; - __DSP_rude_task = NULL; - __DSP_rude_task_pending = 0; - } else { - if (__DSP_curr_task->next == NULL) { - if (__DSP_curr_task == __DSP_first_task) { - if (__DSP_curr_task->done_cb != NULL) - __DSP_curr_task->done_cb(__DSP_curr_task); - - DSPSendMailToDSP(0xCDD10002); - while (DSPCheckMailToDSP() != 0) - ; - __DSP_curr_task->state = 3; - __DSP_remove_task(__DSP_curr_task); - } else { - if (__DSP_curr_task->done_cb != NULL) - __DSP_curr_task->done_cb(__DSP_curr_task); - - DSPSendMailToDSP(0xCDD10001); - while (DSPCheckMailToDSP() != 0) - ; - __DSP_curr_task->state = 3; - __DSP_exec_task(NULL, __DSP_first_task); - __DSP_curr_task = __DSP_first_task; - __DSP_remove_task(__DSP_last_task); - } - } else { - if (__DSP_curr_task->done_cb != NULL) - __DSP_curr_task->done_cb(__DSP_curr_task); - - DSPSendMailToDSP(0xCDD10001); - while (DSPCheckMailToDSP() != 0) - ; - __DSP_curr_task->state = 3; - __DSP_exec_task(NULL, __DSP_curr_task->next); - __DSP_curr_task = __DSP_curr_task->next; - __DSP_remove_task(__DSP_curr_task->prev); - } - } - break; - case 0xDCD10004: - if (__DSP_curr_task->req_cb != NULL) - __DSP_curr_task->req_cb(__DSP_curr_task); - break; - default: - ASSERTMSGLINEV(519, 0, "__DSPHandler(): Unknown msg from DSP 0x%08X - task sync failed!\n", mail); - } - - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); -} - -void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next) { - ASSERTMSGLINE(552, next != NULL, "__DSP_exec_task(): NULL task. It is to weep.\n"); - - if (curr != NULL) { - DSPSendMailToDSP((u32)curr->dram_mmem_addr); - while (DSPCheckMailToDSP() != 0) - ; - DSPSendMailToDSP(curr->dram_length); - while (DSPCheckMailToDSP() != 0) - ; - DSPSendMailToDSP(curr->dram_addr); - while (DSPCheckMailToDSP() != 0) - ; - } else { - DSPSendMailToDSP(0); - while (DSPCheckMailToDSP() != 0) - ; - DSPSendMailToDSP(0); - while (DSPCheckMailToDSP() != 0) - ; - DSPSendMailToDSP(0); - while (DSPCheckMailToDSP() != 0) - ; - } - - DSPSendMailToDSP((u32)next->iram_mmem_addr); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(next->iram_length); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(next->iram_addr); - while (DSPCheckMailToDSP() != 0) - ; - - if (next->state == 0) { - DSPSendMailToDSP(next->dsp_init_vector); - while (DSPCheckMailToDSP() != 0) - ; - DSPSendMailToDSP(0); - while (DSPCheckMailToDSP() != 0) - ; - DSPSendMailToDSP(0); - while (DSPCheckMailToDSP() != 0) - ; - DSPSendMailToDSP(0); - while (DSPCheckMailToDSP() != 0) - ; - } else { - DSPSendMailToDSP(next->dsp_resume_vector); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP((u32)next->dram_mmem_addr); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(next->dram_length); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(next->dram_addr); - while (DSPCheckMailToDSP() != 0) - ; - } -} - -void __DSP_boot_task(DSPTaskInfo* task) { - volatile u32 mail; - - ASSERTMSGLINE(634, task != NULL, "__DSP_boot_task(): NULL task!\n"); - while (DSPCheckMailFromDSP() == 0) - ; - - mail = DSPReadMailFromDSP(); - ASSERTMSGLINEV(640, mail == 0x8071FEED, "__DSP_boot_task(): Failed to sync DSP on boot! (0x%08X)\n", mail); - - DSPSendMailToDSP(0x80F3A001); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP((u32)task->iram_mmem_addr); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(0x80F3C002); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(task->iram_addr & 0xFFFF); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(0x80F3A002); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(task->iram_length); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(0x80F3B002); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(0); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(0x80F3D001); - while (DSPCheckMailToDSP() != 0) - ; - - DSPSendMailToDSP(task->dsp_init_vector); - while (DSPCheckMailToDSP() != 0) - ; - - __DSP_debug_printf("DSP is booting task: 0x%08X\n", (u32)task); - __DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", (u32)task->iram_mmem_addr); - __DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", task->iram_addr); - __DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", task->iram_length); - __DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", task->dram_length); - __DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", task->dsp_init_vector); -} - -void __DSP_insert_task(DSPTaskInfo* task) { - DSPTaskInfo* temp; - - if (__DSP_first_task == NULL) { - __DSP_curr_task = task; - __DSP_first_task = __DSP_last_task = task; - task->next = task->prev = NULL; - return; - } - - temp = __DSP_first_task; - while (temp != NULL) { - if (task->priority < temp->priority) { - task->prev = temp->prev; - temp->prev = task; - task->next = temp; - if (task->prev == NULL) - __DSP_first_task = task; - else - task->prev->next = task; - break; - } - temp = temp->next; - } - - if (temp == NULL) { - __DSP_last_task->next = task; - task->next = NULL; - task->prev = __DSP_last_task; - __DSP_last_task = task; - } -} - -void __DSP_add_task(DSPTaskInfo* task) { - ASSERTMSGLINE(771, task != NULL, "__DSP_add_task(): Why are you adding a NULL task?\n"); - - if (__DSP_last_task == NULL) { - __DSP_curr_task = task; - __DSP_last_task = task; - __DSP_first_task = task; - task->next = task->prev = NULL; - } else { - __DSP_last_task->next = task; - task->next = NULL; - task->prev = __DSP_last_task; - __DSP_last_task = task; - } - - task->state = 0; - __DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", (u32)task); -} - -void __DSP_remove_task(DSPTaskInfo* task) { - ASSERTMSGLINE(813, task != NULL, "__DSP_remove_task(): NULL task! Why? WHY?!?!\n"); - task->flags = 0; - task->state = 3; - - if (__DSP_first_task == task) { - if (task->next != NULL) { - __DSP_first_task = task->next; - task->next->prev = NULL; - } - else - __DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL; - return; - } - - if (__DSP_last_task == task) { - __DSP_last_task = task->prev; - task->prev->next = NULL; - __DSP_curr_task = __DSP_first_task; - return; - } - - __DSP_curr_task = task->next; - task->prev->next = task->next; - task->next->prev = task->prev; -} diff --git a/src/dolphin/dtk/dtk.c b/src/dolphin/dtk/dtk.c deleted file mode 100644 index c1bfd05..0000000 --- a/src/dolphin/dtk/dtk.c +++ /dev/null @@ -1,483 +0,0 @@ -#include -#include -#include -#include - -static DTKTrack* __DTKCurrentTrack; -static DTKTrack* __DTKPlayListHead; -static DTKTrack* __DTKPlayListTail; -static volatile u32 __DTKState; -static volatile u32 __DTKTempState; -static volatile u32 __DTKRepeatMode; -static volatile u32 __DTKPosition; -static volatile u32 __DTKInterruptFrequency; -static volatile u8 __DTKVolumeL; -static volatile u8 __DTKVolumeR; -static volatile u32 __DTKShutdownFlag; -static volatile u32 __DTKTrackEnded; -static DTKFlushCallback __DTKFlushCallback; -static int __busy_for_ais_address; - -static DVDCommandBlock __block_for_run_callback; -static DVDCommandBlock __block_for_prep_callback; -static DVDCommandBlock __block_for_stream_status; -static DVDCommandBlock __block_for_ais_isr; -static DVDCommandBlock __block_for_flushtracks; -static DVDCommandBlock __block_for_repeatmode; -static DVDCommandBlock __block_for_set_state; -static DVDCommandBlock __block_for_next_track; -static DVDCommandBlock __block_for_prev_track; - -static void __DTKStartAi(void) { - AISetStreamVolLeft(__DTKVolumeL); - AISetStreamVolRight(__DTKVolumeR); - AIResetStreamSampleCount(); - AISetStreamTrigger(__DTKInterruptFrequency); - AISetStreamPlayState(1); -} - -static void __DTKStopAi(void) { - AISetStreamVolLeft(0); - AISetStreamVolRight(0); - AISetStreamPlayState(0); -} - -static void __DTKCheckUserCallback(DTKTrack* track, u32 event) { - ASSERTLINE(84, track); - if (track && track->callback && (track->eventMask & event)) { - track->callback(track->eventMask & event); - } -} - -static void __DTKForward(void) { - BOOL old = OSDisableInterrupts(); - if (__DTKCurrentTrack && __DTKCurrentTrack->next) { - __DTKCurrentTrack = __DTKCurrentTrack->next; - } - OSRestoreInterrupts(old); -} - -static void __DTKBackward(void) { - BOOL old = OSDisableInterrupts(); - if (__DTKCurrentTrack && __DTKCurrentTrack->prev) { - __DTKCurrentTrack = __DTKCurrentTrack->prev; - } - OSRestoreInterrupts(old); -} - -static void __DTKCallbackForStreamStatus(s32 result, DVDCommandBlock* block) { - if ((result & 0xFF) == 0) { - __DTKTrackEnded = 1; - __DTKPosition = 0; - } -} - -static void __DTKCallbackForRun(s32 result, DVDFileInfo* fileInfo) { - __DTKStartAi(); - DVDStopStreamAtEndAsync(&__block_for_run_callback, 0); - __DTKState = DTK_STATE_RUN; - __DTKCheckUserCallback(__DTKCurrentTrack, 1); -} - -static void __DTKCallbackForPreparePaused(s32 result, DVDFileInfo* fileInfo) { - __DTKStopAi(); - DVDStopStreamAtEndAsync(&__block_for_prep_callback, 0); - __DTKState = DTK_STATE_PAUSE; - __DTKCheckUserCallback(__DTKCurrentTrack, 32); -} - -static void __DTKPrepareCurrentTrack(void) { - DVDPrepareStreamAsync(&__DTKCurrentTrack->dvdFileInfo, 0, 0, __DTKCallbackForRun); -} - -static void __DTKPrepareCurrentTrackPaused(void) { - DVDPrepareStreamAsync(&__DTKCurrentTrack->dvdFileInfo, 0, 0, __DTKCallbackForPreparePaused); -} - -static void __DTKCallbackForPlaylist(s32 result, DVDCommandBlock* block) { - __DTKPosition = result; - __busy_for_ais_address = 0; - - if (__DTKTrackEnded) { - __DTKTrackEnded = 0; - __DTKCheckUserCallback(__DTKCurrentTrack, 16); - __DTKState = DTK_STATE_BUSY; - - switch (__DTKRepeatMode) { - case DTK_MODE_NOREPEAT: - if (__DTKCurrentTrack) { - if (__DTKCurrentTrack->next) { - __DTKCurrentTrack = __DTKCurrentTrack->next; - __DTKStopAi(); - __DTKPrepareCurrentTrack(); - } else { - __DTKCurrentTrack = __DTKPlayListHead; - __DTKStopAi(); - __DTKState = DTK_STATE_STOP; - } - } - break; - case DTK_MODE_ALLREPEAT: - if (__DTKCurrentTrack) { - if (__DTKCurrentTrack->next) { - __DTKCurrentTrack = __DTKCurrentTrack->next; - __DTKStopAi(); - __DTKPrepareCurrentTrack(); - } else { - __DTKCurrentTrack = __DTKPlayListHead; - __DTKStopAi(); - __DTKPrepareCurrentTrack(); - } - } - break; - case DTK_MODE_REPEAT1: - if (__DTKCurrentTrack) { - __DTKStopAi(); - __DTKPrepareCurrentTrack(); - } - break; - } - } else { - DVDGetStreamErrorStatusAsync(&__block_for_stream_status, __DTKCallbackForStreamStatus); - } -} - -static void __DTKCallbackForAIInterrupt(u32 count) { - AISetStreamTrigger(count + __DTKInterruptFrequency); - if (__DTKCurrentTrack && !__busy_for_ais_address) { - __busy_for_ais_address = 1; - DVDGetStreamPlayAddrAsync(&__block_for_ais_isr, __DTKCallbackForPlaylist); - } -} - -static void __DTKCallbackForFlush(s32 result, DVDCommandBlock* block) { - DTKTrack* track; - - AISetStreamPlayState(0); - track = __DTKPlayListHead; - while (track) { - DVDClose(&track->dvdFileInfo); - track = track->next; - } - - __DTKPlayListHead = NULL; - __DTKPlayListTail = NULL; - __DTKCurrentTrack = NULL; - __DTKState = DTK_STATE_STOP; - - if (__DTKFlushCallback) { - __DTKFlushCallback(); - __DTKFlushCallback = NULL; - } - - __DTKState = DTK_STATE_STOP; - __DTKShutdownFlag = 0; -} - -static void __DTKCallbackForStop(s32 result, DVDCommandBlock* block) { - __DTKCheckUserCallback(__DTKCurrentTrack, 2); - __DTKState = DTK_STATE_STOP; -} - -static void __DTKCallbackForNextTrack(s32 result, DVDCommandBlock* block) { - AISetStreamPlayState(0); - __DTKForward(); - __DTKState = DTK_STATE_STOP; - DTKSetState(__DTKTempState); -} - -static void __DTKCallbackForPrevTrack(s32 result, DVDCommandBlock* block) { - AISetStreamPlayState(0); - __DTKBackward(); - __DTKState = DTK_STATE_STOP; - DTKSetState(__DTKTempState); -} - -void DTKInit(void) { - __DTKCurrentTrack = NULL; - __DTKPlayListHead = NULL; - __DTKPlayListTail = NULL; - __DTKState = DTK_STATE_STOP; - __DTKRepeatMode = DTK_MODE_NOREPEAT; - __DTKPosition = 0; - __DTKInterruptFrequency = 48000; - __DTKVolumeL = 255; - __DTKVolumeR = 255; - - AISetStreamVolLeft(0); - AISetStreamVolRight(0); - AIRegisterStreamCallback(__DTKCallbackForAIInterrupt); - AIResetStreamSampleCount(); - AISetStreamPlayState(0); -} - -void DTKShutdown(void) { - AISetStreamVolLeft(0); - AISetStreamVolRight(0); - AIRegisterStreamCallback(NULL); - AIResetStreamSampleCount(); - AISetStreamPlayState(0); - - __DTKShutdownFlag = 1; - DTKFlushTracks(NULL); - __DTKState = DTK_STATE_STOP; - - while (__DTKShutdownFlag) {} -} - -u32 DTKQueueTrack(char* fileName, DTKTrack* track, u32 eventMask, DTKCallback callback) { - u32 startTrack; - BOOL old; - - startTrack = 0; - if (!DVDOpen(fileName, &track->dvdFileInfo)) { - return 1; - } - - old = OSDisableInterrupts(); - track->fileName = fileName; - track->eventMask = eventMask; - track->callback = callback; - - if (__DTKPlayListHead == NULL) { - __DTKPlayListHead = track; - __DTKPlayListTail = track; - track->prev = NULL; - track->next = NULL; - if (__DTKState == DTK_STATE_RUN) { - startTrack = 1; - } - } else { - __DTKPlayListTail->next = track; - track->prev = __DTKPlayListTail; - __DTKPlayListTail = track; - track->next = NULL; - } - - if (__DTKCurrentTrack == NULL) { - __DTKCurrentTrack = track; - } - - OSRestoreInterrupts(old); - __DTKCheckUserCallback(track, 8); - - if (startTrack != 0) { - __DTKState = DTK_STATE_BUSY; - __DTKPrepareCurrentTrack(); - } - - return 0; -} - -u32 DTKRemoveTrack(DTKTrack* track) { - BOOL old; - - if (track == __DTKCurrentTrack) { - return 2; - } - - old = OSDisableInterrupts(); - DVDClose(&track->dvdFileInfo); - - if (track == __DTKPlayListHead && track == __DTKPlayListTail) { - __DTKPlayListHead = NULL; - __DTKPlayListTail = NULL; - OSRestoreInterrupts(old); - return 0; - } - - if (track == __DTKPlayListHead) { - __DTKPlayListHead = track->next; - __DTKPlayListHead->prev = NULL; - if (__DTKRepeatMode == DTK_MODE_ALLREPEAT) { - __DTKPlayListTail->next = __DTKPlayListHead; - } - OSRestoreInterrupts(old); - return 0; - } - - if (track == __DTKPlayListTail) { - __DTKPlayListTail = track->prev; - __DTKPlayListTail->next = NULL; - if (__DTKRepeatMode == DTK_MODE_ALLREPEAT) { - __DTKPlayListTail->next = __DTKPlayListHead; - } - OSRestoreInterrupts(old); - return 0; - } - - track->prev->next = track->next; - track->next->prev = track->prev; - OSRestoreInterrupts(old); - return 0; -} - -int DTKFlushTracks(DTKFlushCallback callback) { - u32 temp; - - if (__DTKState == DTK_STATE_BUSY) { - return 0; - } - - temp = __DTKState; - __DTKState = DTK_STATE_BUSY; - __DTKFlushCallback = callback; - if (temp == DTK_STATE_RUN) { - DVDCancelStreamAsync(&__block_for_flushtracks, __DTKCallbackForFlush); - } else { - __DTKCallbackForFlush(0, 0); - } - return 1; -} - -void DTKSetSampleRate(u32 samplerate) { - // obsolete -} - -void DTKSetInterruptFrequency(u32 samples) { - __DTKInterruptFrequency = samples; - AIResetStreamSampleCount(); - AISetStreamTrigger(__DTKInterruptFrequency); -} - -void DTKSetRepeatMode(u32 repeat) { - __DTKRepeatMode = repeat; -} - -int DTKSetState(u32 state) { - if (__DTKState == state) { - return 1; - } - - if (__DTKState == DTK_STATE_BUSY) { - return 0; - } - - switch (state) { - case DTK_STATE_STOP: - if (__DTKCurrentTrack) { - __DTKState = DTK_STATE_BUSY; - AISetStreamVolLeft(0); - AISetStreamVolRight(0); - AISetStreamPlayState(0); - DVDCancelStreamAsync(&__block_for_set_state, __DTKCallbackForStop); - } - break; - case DTK_STATE_RUN: - if (__DTKState == DTK_STATE_PAUSE) { - __DTKStartAi(); - __DTKState = DTK_STATE_RUN; - if (__DTKCurrentTrack) { - __DTKCheckUserCallback(__DTKCurrentTrack, 1); - } - } else if (__DTKCurrentTrack) { - __DTKState = DTK_STATE_BUSY; - __DTKPrepareCurrentTrack(); - } else { - __DTKState = DTK_STATE_RUN; - } - __DTKTrackEnded = 0; - break; - case DTK_STATE_PREPARE: - if (__DTKState == DTK_STATE_STOP) { - if (__DTKCurrentTrack) { - __DTKState = DTK_STATE_BUSY; - __DTKPrepareCurrentTrackPaused(); - } - __DTKTrackEnded = 0; - } - break; - case DTK_STATE_PAUSE: - AISetStreamPlayState(0); - if (__DTKState == DTK_STATE_RUN) { - __DTKState = DTK_STATE_PAUSE; - } - __DTKCheckUserCallback(__DTKCurrentTrack, 4); - break; - } - - return 1; -} - -int DTKNextTrack(void) { - if (__DTKState == DTK_STATE_BUSY) { - return 0; - } - - if (__DTKCurrentTrack) { - __DTKTempState = __DTKState; - __DTKState = DTK_STATE_BUSY; - if (__DTKTempState == DTK_STATE_RUN) { - AISetStreamVolLeft(0); - AISetStreamVolRight(0); - DVDCancelStreamAsync(&__block_for_next_track, __DTKCallbackForNextTrack); - } else { - __DTKForward(); - __DTKState = __DTKTempState; - } - - return 1; - } - - return 0; -} - -int DTKPrevTrack(void) { - if (__DTKState == DTK_STATE_BUSY) { - return 0; - } - - if (__DTKCurrentTrack) { - __DTKTempState = __DTKState; - __DTKState = DTK_STATE_BUSY; - if (__DTKTempState == DTK_STATE_RUN) { - AISetStreamVolLeft(0); - AISetStreamVolRight(0); - DVDCancelStreamAsync(&__block_for_prev_track, __DTKCallbackForPrevTrack); - } else { - __DTKBackward(); - __DTKState = __DTKTempState; - } - - return 1; - } - - return 0; -} - -u32 DTKGetSampleRate(void) { - return 1; // obsolete -} - -u32 DTKGetRepeatMode(void) { - return __DTKRepeatMode; -} - -u32 DTKGetState(void) { - return __DTKState; -} - -u32 DTKGetPosition(void) { - return __DTKPosition; -} - -u32 DTKGetInterruptFrequency(void) { - return __DTKInterruptFrequency; -} - -DTKTrack* DTKGetCurrentTrack(void) { - return __DTKCurrentTrack; -} - -void DTKSetVolume(u8 left, u8 right) { - __DTKVolumeL = left; - __DTKVolumeR = right; - if (__DTKState == DTK_STATE_RUN) { - AISetStreamVolLeft(left); - AISetStreamVolRight(right); - } -} - -u16 DTKGetVolume(void) { - return (__DTKVolumeL << 8) | __DTKVolumeR; -} diff --git a/src/dolphin/dvd/__dvd.h b/src/dolphin/dvd/__dvd.h deleted file mode 100644 index 197c13e..0000000 --- a/src/dolphin/dvd/__dvd.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _DOLPHIN_DVD_INTERNAL_H_ -#define _DOLPHIN_DVD_INTERNAL_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// DVD -DVDCommandChecker __DVDSetOptionalCommandChecker(DVDCommandChecker func); -void __DVDSetImmCommand(u32 command); -void __DVDSetDmaCommand(u32 command); -void* __DVDGetIssueCommandAddr(void); -void __DVDAudioBufferConfig(DVDCommandBlock* block, u32 enable, u32 size, DVDCBCallback callback); -void __DVDPrepareResetAsync(DVDCBCallback callback); -int __DVDTestAlarm(const OSAlarm* alarm); - -// DVD ERROR -void __DVDStoreErrorCode(u32 error); - -// DVD FATAL -void __DVDPrintFatalMessage(void); - -// DVD FS -extern OSThreadQueue __DVDThreadQueue; -extern u32 __DVDLongFileNameFlag; - -void __DVDFSInit(void); - -// DVD LOW -void __DVDInitWA(void); -void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context); -void __DVDLowSetWAType(u32 type, s32 seekLoc); -int __DVDLowTestAlarm(const OSAlarm* alarm); - -// DVD QUEUE -void __DVDClearWaitingQueue(void); -int __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block); -DVDCommandBlock* __DVDPopWaitingQueue(void); -int __DVDCheckWaitingQueue(void); -int __DVDDequeueWaitingQueue(DVDCommandBlock* block); -int __DVDIsBlockInWaitingQueue(DVDCommandBlock* block); - -// FST LOAD -void __fstLoad(void); - -#ifdef __cplusplus -} -#endif - -#endif // _DOLPHIN_DVD_INTERNAL_H_ diff --git a/src/dolphin/dvd/dvd.c b/src/dolphin/dvd/dvd.c deleted file mode 100644 index 3b7e970..0000000 --- a/src/dolphin/dvd/dvd.c +++ /dev/null @@ -1,1854 +0,0 @@ -#include -#include -#include - -#include "os/__os.h" -#include "__dvd.h" - -// externs -extern void __DVDPrintFatalMessage(); -extern int DVDCompareDiskID(const struct DVDDiskID * id1 /* r29 */, const struct DVDDiskID * id2 /* r30 */); -extern int __DVDLowTestAlarm(const OSAlarm * alarm /* r3 */); - -#ifdef DEBUG -const char* __DVDVersion = "<< Dolphin SDK - DVD\tdebug build: Apr 5 2004 03:56:07 (0x2301) >>"; -#else -const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Apr 5 2004 04:14:51 (0x2301) >>"; -#endif - -static BOOL autoInvalidation = TRUE; - -static void defaultOptionalCommandChecker(DVDCommandBlock*, DVDCommandCheckerCallback); -static DVDCommandChecker checkOptionalCommand = defaultOptionalCommandChecker; - -static DVDBB2 BB2; -static DVDDiskID CurrDiskID; -static DVDCommandBlock DummyCommandBlock; -static OSAlarm ResetAlarm; - -static DVDCommandBlock* executing; -static DVDDiskID* IDShouldBe; -static OSBootInfo* bootInfo; -static volatile int PauseFlag; -static volatile int PausingFlag; -static int AutoFinishing; -static BOOL FatalErrorFlag; -static volatile u32 CurrCommand; -static volatile u32 Canceling; -static void (*CancelCallback)(s32, DVDCommandBlock*); -static volatile u32 ResumeFromHere; -static volatile u32 CancelLastError; -static u32 LastError; -static volatile s32 NumInternalRetry; -static int ResetRequired; -static int CancelAllSyncComplete; -static volatile u32 ResetCount; -static BOOL FirstTimeInBootrom; -static u32 MotorState; -static int DVDInitialized; -void (*LastState)(DVDCommandBlock*); - -// prototypes -static void stateReadingFST(); -static void cbForStateReadingFST(u32 intType); -static void cbForStateError(u32 intType); -static void stateError(u32 error); -static void stateTimeout(); -static void stateGettingError(); -static u32 CategorizeError(u32 error); -static BOOL CheckCancel(u32 resume); -static void cbForStateGettingError(u32 intType); -static void cbForUnrecoveredError(u32 intType); -static void cbForUnrecoveredErrorRetry(u32 intType); -static void stateGoToRetry(); -static void cbForStateGoToRetry(u32 intType); -static void stateCheckID(); -static void stateCheckID3(); -static void stateCheckID2a(); -static void stateCheckID2(); -static void cbForStateCheckID1(u32 intType); -static void cbForStateCheckID2(u32 intType); -static void cbForStateCheckID3(u32 intType); -static void cbForStateCheckID2a(u32 intType); -static void AlarmHandler(OSAlarm* alarm, OSContext* context); -static void stateCoverClosed(); -static void stateCoverClosed_CMD(DVDCommandBlock* command); -static void cbForStateCoverClosed(u32 intType); -static void stateMotorStopped(); -static void cbForStateMotorStopped(u32 intType); -static void stateReady(); -static void stateBusy(DVDCommandBlock* block); -static BOOL IsImmCommandWithResult(u32 command); -static int IsDmaCommand(u32 command); -static void cbForStateBusy(u32 intType); -static int issueCommand(s32 prio, DVDCommandBlock* block); -static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block); -static void cbForStopStreamAtEndSync(s32 result, DVDCommandBlock* block); -static void cbForGetStreamErrorStatusSync(s32 result, DVDCommandBlock* block); -static void cbForGetStreamPlayAddrSync(s32 result, DVDCommandBlock* block); -static void cbForGetStreamStartAddrSync(s32 result, DVDCommandBlock* block); -static void cbForGetStreamLengthSync(s32 result, DVDCommandBlock* block); -static void cbForChangeDiskSync(s32 result, DVDCommandBlock* block); -static void cbForStopMotorSync(s32 result, DVDCommandBlock* block); -static void cbForInquirySync(s32 result, DVDCommandBlock* block); -static void cbForCancelSync(s32 result, DVDCommandBlock* block); -static void cbForCancelAllSync(s32 result, DVDCommandBlock* block); - -static void defaultOptionalCommandChecker(DVDCommandBlock*, DVDCommandCheckerCallback) {} - -DVDCommandChecker __DVDSetOptionalCommandChecker(DVDCommandChecker func) { - DVDCommandChecker old = checkOptionalCommand; - checkOptionalCommand = func; - return checkOptionalCommand; -} - -void DVDInit(void) { - if (!DVDInitialized) { - OSRegisterVersion(__DVDVersion); - DVDInitialized = TRUE; - - __DVDFSInit(); - __DVDClearWaitingQueue(); - __DVDInitWA(); - - MotorState = 0; - bootInfo = (void*)OSPhysicalToCached(0); - IDShouldBe = &bootInfo->DVDDiskID; - - __OSSetInterruptHandler(0x15, __DVDInterruptHandler); - __OSUnmaskInterrupts(0x400); - OSInitThreadQueue(&__DVDThreadQueue); - __DIRegs[0] = 0x2A; - __DIRegs[1] = 0; - - if (bootInfo->magic == 0xE5207C22) { - OSReport("load fst\n"); - __fstLoad(); - } else if (bootInfo->magic == 0x0D15EA5E) { - - } else { - FirstTimeInBootrom = TRUE; - } - } -} - -static void stateReadingFST() { - LastState = stateReadingFST; - ASSERTLINE(652, ((u32)(bootInfo->FSTLocation) & (32 - 1)) == 0); - DVD_ASSERTMSGLINE(661, bootInfo->FSTMaxLength >= BB2.FSTLength, "DVDChangeDisk(): FST in the new disc is too big. "); - DVDLowRead(bootInfo->FSTLocation, (u32)(BB2.FSTLength + 0x1F) & 0xFFFFFFE0, BB2.FSTPosition, cbForStateReadingFST); -} - -static u32 DmaCommand[1] = {0xFFFFFFFF}; - -static void cbForStateReadingFST(u32 intType) { - DVDCommandBlock* finished; - - if (intType == 16) { - stateTimeout(); - return; - } - - ASSERTLINE(680, (intType & DVD_INTTYPE_CVR) == 0); - - if (intType & DVD_INTTYPE_TC) { - ASSERTLINE(685, (intType & DVD_INTTYPE_DE) == 0); - NumInternalRetry = 0; - - __DVDFSInit(); - finished = executing; - executing = &DummyCommandBlock; - finished->state = DVD_STATE_END; - - if (finished->callback) { - finished->callback(0, finished); - } - - stateReady(); - return; - } - - ASSERTLINE(712, intType == DVD_INTTYPE_DE); - stateGettingError(); -} - -static void cbForStateError(u32 intType) { - DVDCommandBlock* finished; - executing->state = -1; - - if (intType == 16) { - stateTimeout(); - return; - } - - __DVDPrintFatalMessage(); - - FatalErrorFlag = TRUE; - finished = executing; - executing = &DummyCommandBlock; - - if (finished->callback) { - (finished->callback)(-1, finished); - } - - if (Canceling) { - Canceling = FALSE; - if (CancelCallback) - (CancelCallback)(0, finished); - } - - stateReady(); -} - -static void stateError(u32 error) { - __DVDStoreErrorCode(error); - DVDLowStopMotor(&cbForStateError); -} - -static void stateTimeout() { - __DVDStoreErrorCode(0x01234568); - DVDReset(); - cbForStateError(0); -} - -static void stateGettingError() { - DVDLowRequestError(cbForStateGettingError); -} - -static u32 CategorizeError(u32 error) { - if (error == 0x20400) { - LastError = error; - return 1; - } - - error &= 0x00FFFFFF; - if (error == 0x62800 || error == 0x23A00 || error == 0xB5A01) { - return 0; - } - - NumInternalRetry++; - if (NumInternalRetry == 2) { - if (error == LastError) { - LastError = error; - return 1; - } - LastError = error; - return 2; - } - - LastError = error; - - if (error == 0x31100 || executing->command == DVD_COMMAND_READID) { - return 2; - } - - return 3; -} - -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) { - stateTimeout(); - return; - } - - if (intType & 2) { - stateError(0x1234567); - return; - } - - ASSERTLINE(956, intType == DVD_INTTYPE_TC); - - error = __DIRegs[8]; - status = error & 0xff000000; - - errorCategory = CategorizeError(error); - - if (errorCategory == 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 { - stateError(0x1234567); - return; - } -} - -static void cbForUnrecoveredError(u32 intType) { - if (intType == 16) { - stateTimeout(); - return; - } - - if (intType & 1) { - stateGoToRetry(); - return; - } - - ASSERTLINE(1055, intType == DVD_INTTYPE_DE); - DVDLowRequestError(cbForUnrecoveredErrorRetry); -} - -static void cbForUnrecoveredErrorRetry(u32 intType) { - if (intType == 0x10) { - stateTimeout(); - } else { - if (intType & 2) { - stateError(0x01234567); - return; - } - - stateError(__DIRegs[8]); - } -} - -static void stateGoToRetry() { - DVDLowStopMotor(cbForStateGoToRetry); -} - -static void cbForStateGoToRetry(u32 intType) { - if (intType == 16) { - stateTimeout(); - return; - } - - if (intType & 2) { - stateError(0x1234567); - return; - } - - ASSERTLINE(1104, intType == DVD_INTTYPE_TC); - 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 DVD_COMMAND_CHANGE_DISK: - if (DVDCompareDiskID(&CurrDiskID, executing->id)) { - memcpy(IDShouldBe, &CurrDiskID, sizeof(DVDDiskID)); - executing->state = DVD_STATE_BUSY; - DCInvalidateRange(&BB2.bootFilePosition, 0x20); - LastState = stateCheckID2a; - stateCheckID2a(executing); - } else { - DVDLowStopMotor(cbForStateCheckID1); - } - break; - default: - if (memcmp(&CurrDiskID, IDShouldBe, sizeof(DVDDiskID)) != 0) { - DVDLowStopMotor(cbForStateCheckID1); - } else { - LastState = stateCheckID3; - stateCheckID3(executing); - } - break; - } -} - -static void stateCheckID3() { - DVDLowAudioBufferConfig(IDShouldBe->streaming, 0xA, cbForStateCheckID3); -} - -static void stateCheckID2a() { - DVDLowAudioBufferConfig(IDShouldBe->streaming, 0xA, cbForStateCheckID2a); -} - -static void cbForStateCheckID2a(u32 intType) { - if (intType == 16) { - stateTimeout(); - return; - } - - ASSERTLINE(1227, (intType & DVD_INTTYPE_CVR) == 0); - - if (intType & DVD_INTTYPE_TC) { - ASSERTLINE(1232, (intType & DVD_INTTYPE_DE) == 0); - NumInternalRetry = 0; - stateCheckID2(executing); - return; - } - - ASSERTLINE(1243, intType == DVD_INTTYPE_DE); - stateGettingError(); -} - -static void stateCheckID2() { - DVDLowRead(&BB2, 0x20, 0x420, cbForStateCheckID2); -} - -static void cbForStateCheckID1(u32 intType) { - if (intType == 16) { - stateTimeout(); - return; - } - - if (intType & DVD_INTTYPE_DE) { - stateError(0x01234567); - return; - } - - ASSERTLINE(1279, intType == DVD_INTTYPE_TC); - NumInternalRetry = 0; - - if (CheckCancel(1) == FALSE) { - executing->state = DVD_STATE_WRONG_DISK; - stateMotorStopped(); - } -} - -static void cbForStateCheckID2(u32 intType) { - if (intType == 16) { - stateTimeout(); - return; - } - - ASSERTLINE(1300, (intType & DVD_INTTYPE_CVR) == 0); - - if (intType & DVD_INTTYPE_TC) { - ASSERTLINE(1305, (intType & DVD_INTTYPE_DE) == 0); - NumInternalRetry = 0; - stateReadingFST(); - return; - } - - ASSERTLINE(1321, intType == DVD_INTTYPE_DE); - stateGettingError(); -} - -static void cbForStateCheckID3(u32 intType) { - if (intType == 16) { - stateTimeout(); - return; - } - - ASSERTLINE(1336, (intType & DVD_INTTYPE_CVR) == 0); - - if (intType & DVD_INTTYPE_TC) { - ASSERTLINE(1341, (intType & DVD_INTTYPE_DE) == 0); - NumInternalRetry = 0; - if (CheckCancel(0) == FALSE) { - executing->state = DVD_STATE_BUSY; - stateBusy(executing); - } - return; - } - - ASSERTLINE(1355, intType == DVD_INTTYPE_DE); - 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 DVD_COMMAND_BSREAD: - case DVD_COMMAND_READID: - case DVD_COMMAND_AUDIO_BUFFER_CONFIG: - case DVD_COMMAND_BS_CHANGE_DISK: - __DVDClearWaitingQueue(); - finished = executing; - executing = &DummyCommandBlock; - if (finished->callback) { - finished->callback(-4, finished); - } - stateReady(); - break; - default: - MotorState = 0; - DVDReset(); - OSCreateAlarm(&ResetAlarm); - OSSetAlarm(&ResetAlarm, OSMillisecondsToTicks(1150), &AlarmHandler); - break; - } -} - -static void stateCoverClosed_CMD(DVDCommandBlock* command) { - DVDLowReadDiskID(&CurrDiskID, cbForStateCoverClosed); -} - -static void cbForStateCoverClosed(u32 intType) { - if (intType == 16) { - stateTimeout(); - return; - } - - ASSERTLINE(1437, (intType & DVD_INTTYPE_CVR) == 0); - - if (intType & DVD_INTTYPE_TC) { - ASSERTLINE(1442, (intType & DVD_INTTYPE_DE) == 0); - NumInternalRetry = 0; - stateCheckID(); - return; - } - - ASSERTLINE(1454, intType == DVD_INTTYPE_DE); - stateGettingError(); -} - -static void stateMotorStopped() { - DVDLowWaitCoverClose(cbForStateMotorStopped); -} - -static void cbForStateMotorStopped(u32 intType) { - ASSERTLINE(1483, intType == DVD_INTTYPE_CVR); - __DIRegs[1] = 0; - executing->state = DVD_STATE_COVER_CLOSED; - stateCoverClosed(); -} - -static void stateReady() { - if (__DVDCheckWaitingQueue() == 0) { - executing = NULL; - return; - } - - if (PauseFlag != 0) { - PausingFlag = 1; - executing = NULL; - return; - } - - executing = __DVDPopWaitingQueue(); - - if (FatalErrorFlag) { - DVDCommandBlock* finished; - - executing->state = DVD_STATE_FATAL_ERROR; - finished = executing; - executing = &DummyCommandBlock; - if (finished->callback) { - (*finished->callback)(-1, finished); - } - - stateReady(); - return; - } - - CurrCommand = executing->command; - if (ResumeFromHere != 0) { - switch (ResumeFromHere) { - case 2: - executing->state = DVD_STATE_RETRY; - stateMotorStopped(); - break; - case 3: - executing->state = DVD_STATE_NO_DISK; - stateMotorStopped(); - break; - case 4: - executing->state = DVD_STATE_COVER_OPEN; - stateMotorStopped(); - break; - case 1: - case 6: - case 7: - executing->state = DVD_STATE_COVER_CLOSED; - stateCoverClosed(); - break; - case 5: - stateError(CancelLastError); - break; - } - - ResumeFromHere = 0; - return; - } - - if (MotorState == 0) { - executing->state = DVD_STATE_BUSY; - stateBusy(executing); - } else { - stateCoverClosed(); - } -} - -static void stateBusy(DVDCommandBlock* block) { - DVDCommandBlock* finished; - LastState = stateBusy; - - switch(block->command) { - case DVD_COMMAND_READID: - __DIRegs[1] = __DIRegs[1]; - block->currTransferSize = 0x20; - DVDLowReadDiskID(block->addr, cbForStateBusy); - return; - case DVD_COMMAND_READ: - case DVD_COMMAND_BSREAD: - if (block->length == 0) { - finished = executing; - executing = &DummyCommandBlock; - finished->state = 0; - - if (finished->callback != 0) { - (*finished->callback)(0, finished); - } - - stateReady(); - } else { - __DIRegs[1] = __DIRegs[1]; - block->currTransferSize = (block->length - block->transferredSize > 0x80000) ? 0x80000 : (block->length - block->transferredSize); - DVDLowRead((char*)block->addr + block->transferredSize, block->currTransferSize, block->offset + block->transferredSize, cbForStateBusy); - } - return; - case DVD_COMMAND_SEEK: - __DIRegs[1] = __DIRegs[1]; - DVDLowSeek(block->offset, cbForStateBusy); - return; - case DVD_COMMAND_CHANGE_DISK: - DVDLowStopMotor(cbForStateBusy); - return; - case DVD_COMMAND_BS_CHANGE_DISK: - DVDLowStopMotor(cbForStateBusy); - return; - case DVD_COMMAND_INITSTREAM: - __DIRegs[1] = __DIRegs[1]; - if (AutoFinishing != 0) { - executing->currTransferSize = 0; - DVDLowRequestAudioStatus(0, cbForStateBusy); - return; - } - executing->currTransferSize = 1; - DVDLowAudioStream(0, block->length, block->offset, cbForStateBusy); - return; - case DVD_COMMAND_CANCELSTREAM: - __DIRegs[1] = __DIRegs[1]; - DVDLowAudioStream(0x10000, 0U, 0U, cbForStateBusy); - return; - case DVD_COMMAND_STOP_STREAM_AT_END: - __DIRegs[1] = __DIRegs[1]; - AutoFinishing = 1; - DVDLowAudioStream(0, 0U, 0U, cbForStateBusy); - return; - case DVD_COMMAND_REQUEST_AUDIO_ERROR: - __DIRegs[1] = __DIRegs[1]; - DVDLowRequestAudioStatus(0, cbForStateBusy); - return; - case DVD_COMMAND_REQUEST_PLAY_ADDR: - __DIRegs[1] = __DIRegs[1]; - DVDLowRequestAudioStatus(0x10000, cbForStateBusy); - return; - case DVD_COMMAND_REQUEST_START_ADDR: - __DIRegs[1] = __DIRegs[1]; - DVDLowRequestAudioStatus(0x20000, cbForStateBusy); - return; - case DVD_COMMAND_REQUEST_LENGTH: - __DIRegs[1] = __DIRegs[1]; - DVDLowRequestAudioStatus(0x30000, cbForStateBusy); - return; - case DVD_COMMAND_AUDIO_BUFFER_CONFIG: - __DIRegs[1] = __DIRegs[1]; - DVDLowAudioBufferConfig(block->offset, block->length, cbForStateBusy); - return; - case DVD_COMMAND_INQUIRY: - __DIRegs[1] = __DIRegs[1]; - block->currTransferSize = 0x20; - DVDLowInquiry(block->addr, cbForStateBusy); - return; - case DVD_COMMAND_UNK_16: - __DIRegs[1] = __DIRegs[1]; - DVDLowStopMotor(cbForStateBusy); - return; - default: - checkOptionalCommand(block, cbForStateBusy); - return; - } -} - -static u32 ImmCommand[3] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; - -void __DVDSetImmCommand(u32 command) { - static u32 immCount; - ASSERTLINE(1790, immCount < sizeof(ImmCommand)/sizeof(ImmCommand[0])); - ImmCommand[immCount++] = command; -} - -void __DVDSetDmaCommand(u32 command) { - static u32 dmaCount; - ASSERTLINE(1798, dmaCount < sizeof(DmaCommand)/sizeof(DmaCommand[0])); - DmaCommand[dmaCount++] = command; -} - -static BOOL IsImmCommandWithResult(u32 command) { - u32 i; - - if (command == 9 || command == 10 || command == 11 || command == 12) { - return 1; - } - - for (i = 0; i < 3; i++) { - if (command == ImmCommand[i]) { - return TRUE; - } - } - - return FALSE; -} - -static int IsDmaCommand(u32 command) { - u32 i; - - if (command == 1 || command == 4 || command == 5 || command == 14) { - return 1; - } - - for (i = 0; i < 1; i++) { - if (command == DmaCommand[i]) { - return TRUE; - } - } - - return FALSE; -} - -static void cbForStateBusy(u32 intType) { - DVDCommandBlock* finished; - s32 result; - - if (intType == 16) { - stateTimeout(); - return; - } - - if ((CurrCommand == DVD_COMMAND_CHANGE_DISK) || (CurrCommand == DVD_COMMAND_BS_CHANGE_DISK)) { - if (intType & DVD_INTTYPE_DE) { - stateError(0x01234567); - return; - } - - ASSERTLINE(1857, intType == DVD_INTTYPE_TC); - NumInternalRetry = 0; - - if (CurrCommand == DVD_COMMAND_BS_CHANGE_DISK) { - ResetRequired = 1; - } - - if (CheckCancel(7) == FALSE) { - executing->state = DVD_STATE_MOTOR_STOPPED; - stateMotorStopped(); - } - return; - } - - ASSERTLINE(1877, (intType & DVD_INTTYPE_CVR) == 0); - - if (IsDmaCommand(CurrCommand)) { - executing->transferredSize += executing->currTransferSize - __DIRegs[6]; - } - - if (intType & 8) { - Canceling = 0; - finished = executing; - executing = &DummyCommandBlock; - finished->state = DVD_STATE_CANCELED; - - if (finished->callback) { - finished->callback(-3, finished); - } - - if (CancelCallback) { - CancelCallback(0, finished); - } - - stateReady(); - return; - } - - if (intType & 1) { - ASSERTLINE(1915, (intType & DVD_INTTYPE_DE) == 0); - NumInternalRetry = 0; - - if (CurrCommand == 0x10) { - MotorState = 1; - finished = executing; - executing = &DummyCommandBlock; - finished->state = 0; - - if (finished->callback != 0) { - (*finished->callback)(0, finished); - } - - stateReady(); - return; - } - - if (CheckCancel(0) != FALSE) { - return; - } - - if (IsDmaCommand(CurrCommand)) { - if (executing->transferredSize != executing->length) { - stateBusy(executing); - return; - } - - finished = executing; - executing = &DummyCommandBlock; - finished->state = DVD_STATE_END; - if (finished->callback) { - finished->callback(finished->transferredSize, finished); - } - - stateReady(); - return; - } else if (IsImmCommandWithResult(CurrCommand)) { - if (CurrCommand == DVD_COMMAND_REQUEST_START_ADDR || CurrCommand == DVD_COMMAND_REQUEST_PLAY_ADDR) { - result = __DIRegs[8] * 4; - } else { - result = __DIRegs[8]; - } - - finished = executing; - executing = &DummyCommandBlock; - finished->state = DVD_STATE_END; - if (finished->callback) { - finished->callback(result, finished); - } - - stateReady(); - return; - } else if (CurrCommand == DVD_COMMAND_INITSTREAM) { - if (executing->currTransferSize == 0) { - if (__DIRegs[8] & 1) { - finished = executing; - executing = &DummyCommandBlock; - finished->state = DVD_STATE_IGNORED; - if (finished->callback) { - finished->callback(-2, finished); - } - stateReady(); - return; - } - - AutoFinishing = 0; - executing->currTransferSize = 1; - DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy); - return; - } - - finished = executing; - executing = &DummyCommandBlock; - finished->state = DVD_STATE_END; - if (finished->callback) { - finished->callback(0, finished); - } - - stateReady(); - return; - } else { - finished = executing; - executing = &DummyCommandBlock; - finished->state = DVD_STATE_END; - if (finished->callback) { - finished->callback(0, finished); - } - - stateReady(); - return; - } - } else { - ASSERTLINE(2063, intType == DVD_INTTYPE_DE); - - if (CurrCommand == 14) { - 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 = DVD_STATE_END; - if (finished->callback) { - (finished->callback)((s32)finished->transferredSize, finished); - } - stateReady(); - return; - } - - stateGettingError(); - } -} - -void* __DVDGetIssueCommandAddr(void) { - return issueCommand; -} - -static int issueCommand(s32 prio, DVDCommandBlock* block) { - BOOL level; - int result; - - if (autoInvalidation != 0 && (block->command == DVD_COMMAND_READ || block->command == DVD_COMMAND_BSREAD - || block->command == DVD_COMMAND_READID || block->command == DVD_COMMAND_INQUIRY)) { - DCInvalidateRange(block->addr, block->length); - } - - level = OSDisableInterrupts(); -#if DEBUG - if (executing == block || block->state == DVD_STATE_WAITING && __DVDIsBlockInWaitingQueue(block)) { - ASSERTMSGLINE(2151, FALSE, "DVD library: Specified command block (or file info) is already in use\n"); - } -#endif - - block->state = DVD_STATE_WAITING; - result = __DVDPushWaitingQueue(prio, block); - if (executing == NULL && PauseFlag == 0) { - stateReady(); - } - - OSRestoreInterrupts(level); - return result; -} - -int DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback, s32 prio) { - int idle; - - ASSERTMSGLINE(2191, block, "DVDReadAbsAsync(): null pointer is specified to command block address."); - ASSERTMSGLINE(2192, addr, "DVDReadAbsAsync(): null pointer is specified to addr."); - ASSERTMSGLINE(2194, !OFFSET(addr, 32), "DVDReadAbsAsync(): address must be aligned with 32 byte boundary."); - ASSERTMSGLINE(2196, !(length & (32-1)), "DVDReadAbsAsync(): length must be a multiple of 32."); - ASSERTMSGLINE(2198, !(offset & (4-1)), "DVDReadAbsAsync(): offset must be a multiple of 4."); - ASSERTMSGLINE(2200, length >= 0, "DVD read: negative value was specified to length of the read\n"); - - block->command = DVD_COMMAND_READ; - block->addr = addr; - block->length = length; - block->offset = offset; - block->transferredSize = 0; - block->callback = callback; - - idle = issueCommand(prio, block); - ASSERTMSGLINE(2210, idle, "DVDReadAbsAsync(): command block is used for processing previous request."); - return idle; -} - -int DVDSeekAbsAsyncPrio(DVDCommandBlock* block, s32 offset, DVDCBCallback callback, s32 prio) { - int idle; - - ASSERTMSGLINE(2233, block, "DVDSeekAbs(): null pointer is specified to command block address."); - ASSERTMSGLINE(2235, !(offset & (4-1)), "DVDSeekAbs(): offset must be a multiple of 4."); - - block->command = DVD_COMMAND_SEEK; - block->offset = offset; - block->callback = callback; - - idle = issueCommand(prio, block); - ASSERTMSGLINE(2242, idle, "DVDSeekAbs(): command block is used for processing previous request."); - return idle; -} - -int DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback) { - int idle; - - ASSERTMSGLINE(2272, block, "DVDReadAbsAsyncForBS(): null pointer is specified to command block address."); - ASSERTMSGLINE(2273, addr, "DVDReadAbsAsyncForBS(): null pointer is specified to addr."); - ASSERTMSGLINE(2275, !OFFSET(addr, 32), "DVDReadAbsAsyncForBS(): address must be aligned with 32 byte boundary."); - ASSERTMSGLINE(2277, !(length & (32-1)), "DVDReadAbsAsyncForBS(): length must be a multiple of 32."); - ASSERTMSGLINE(2279, !(offset & (4-1)), "DVDReadAbsAsyncForBS(): offset must be a multiple of 4."); - - block->command = DVD_COMMAND_BSREAD; - block->addr = addr; - block->length = length; - block->offset = offset; - block->transferredSize = 0; - block->callback = callback; - - idle = issueCommand(2, block); - ASSERTMSGLINE(2289, idle, "DVDReadAbsAsyncForBS(): command block is used for processing previous request."); - return idle; -} - -int DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback) { - int idle; - - ASSERTMSGLINE(2312, block, "DVDReadDiskID(): null pointer is specified to command block address."); - ASSERTMSGLINE(2313, diskID, "DVDReadDiskID(): null pointer is specified to id address."); - ASSERTMSGLINE(2315, !OFFSET(diskID, 32), "DVDReadDiskID(): id must be aligned with 32 byte boundary."); - - block->command = DVD_COMMAND_READID; - block->addr = diskID; - block->length = 0x20; - block->offset = 0; - block->transferredSize = 0; - block->callback = callback; - - idle = issueCommand(2, block); - ASSERTMSGLINE(2325, idle, "DVDReadDiskID(): command block is used for processing previous request."); - return idle; -} - -int DVDPrepareStreamAbsAsync(DVDCommandBlock* block, u32 length, u32 offset, DVDCBCallback callback) { - int idle; - - block->command = DVD_COMMAND_INITSTREAM; - block->length = length; - block->offset = offset; - block->callback = callback; - idle = issueCommand(1, block); - return idle; -} - -int DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback) { - int idle; - - block->command = DVD_COMMAND_CANCELSTREAM; - block->callback = callback; - idle = issueCommand(1, block); - return idle; -} - -s32 DVDCancelStream(DVDCommandBlock* block) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDCancelStreamAsync(block, cbForCancelStreamSync); - if (result == 0) { - return -1; - } - enabled = OSDisableInterrupts(); - - while (1) { - state = block->state; - if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { - retVal = block->transferredSize; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block) { - block->transferredSize = (u32)result; - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback) { - int idle; - - block->command = DVD_COMMAND_STOP_STREAM_AT_END; - block->callback = callback; - idle = issueCommand(1, block); - return idle; -} - -s32 DVDStopStreamAtEnd(DVDCommandBlock* block) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDStopStreamAtEndAsync(block, cbForStopStreamAtEndSync); - if (result == 0) { - return -1; - } - enabled = OSDisableInterrupts(); - - while (1) { - state = block->state; - if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { - retVal = block->transferredSize; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForStopStreamAtEndSync(s32 result, DVDCommandBlock* block) { - block->transferredSize = (u32)result; - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback) { - int idle; - - block->command = DVD_COMMAND_REQUEST_AUDIO_ERROR; - block->callback = callback; - idle = issueCommand(1, block); - return idle; -} - -s32 DVDGetStreamErrorStatus(DVDCommandBlock* block) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDGetStreamErrorStatusAsync(block, cbForGetStreamErrorStatusSync); - if (result == 0) { - return -1; - } - enabled = OSDisableInterrupts(); - - while (1) { - state = block->state; - if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { - retVal = block->transferredSize; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForGetStreamErrorStatusSync(s32 result, DVDCommandBlock* block) { - block->transferredSize = (u32)result; - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) { - int idle; - - block->command = DVD_COMMAND_REQUEST_PLAY_ADDR; - block->callback = callback; - idle = issueCommand(1, block); - return idle; -} - -s32 DVDGetStreamPlayAddr(DVDCommandBlock* block) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDGetStreamPlayAddrAsync(block, cbForGetStreamPlayAddrSync); - if (result == 0) { - return -1; - } - enabled = OSDisableInterrupts(); - - while (1) { - state = block->state; - if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { - retVal = block->transferredSize; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForGetStreamPlayAddrSync(s32 result, DVDCommandBlock* block) { - block->transferredSize = (u32)result; - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDGetStreamStartAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) { - int idle; - - block->command = DVD_COMMAND_REQUEST_START_ADDR; - block->callback = callback; - idle = issueCommand(1, block); - return idle; -} - -s32 DVDGetStreamStartAddr(DVDCommandBlock* block) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDGetStreamStartAddrAsync(block, cbForGetStreamStartAddrSync); - if (result == 0) { - return -1; - } - enabled = OSDisableInterrupts(); - - while (1) { - state = block->state; - if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { - retVal = block->transferredSize; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForGetStreamStartAddrSync(s32 result, DVDCommandBlock* block) { - block->transferredSize = (u32)result; - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDGetStreamLengthAsync(DVDCommandBlock* block, DVDCBCallback callback) { - int idle; - - block->command = DVD_COMMAND_REQUEST_LENGTH; - block->callback = callback; - idle = issueCommand(1, block); - return idle; -} - -s32 DVDGetStreamLength(DVDCommandBlock* block) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDGetStreamLengthAsync(block, cbForGetStreamLengthSync); - if (result == 0) { - return -1; - } - enabled = OSDisableInterrupts(); - - while (1) { - state = block->state; - if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { - retVal = block->transferredSize; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForGetStreamLengthSync(s32 result, DVDCommandBlock* block) { - block->transferredSize = (u32)result; - OSWakeupThread(&__DVDThreadQueue); -} - -void __DVDAudioBufferConfig(DVDCommandBlock* block, u32 enable, u32 size, DVDCBCallback callback) { - int idle; - - block->command = DVD_COMMAND_AUDIO_BUFFER_CONFIG; - block->offset = enable; - block->length = size; - block->callback = callback; - idle = issueCommand(2, block); -} - -int DVDChangeDiskAsyncForBS(DVDCommandBlock* block, DVDCBCallback callback) { - int idle; - - ASSERTMSGLINE(2869, block, "DVDChangeDiskAsyncForBS(): null pointer is specified to command block address."); - - block->command = DVD_COMMAND_BS_CHANGE_DISK; - block->callback = callback; - idle = issueCommand(2, block); - ASSERTMSGLINE(2875, idle, "DVDChangeDiskAsyncForBS(): command block is used for processing previous request."); - return idle; -} - -int DVDChangeDiskAsync(DVDCommandBlock* block, DVDDiskID* id, DVDCBCallback callback) { - int idle; - - ASSERTMSGLINE(2896, block, "DVDChangeDisk(): null pointer is specified to command block address."); - ASSERTMSGLINE(2897, id, "DVDChangeDisk(): null pointer is specified to id address."); - - if (id->company[0] == 0) { - OSReport("DVDChangeDiskAsync(): You can't specify NULL to company name. \n"); - DVD_ASSERTMSGLINE(2902, 0, ""); - } - - block->command = DVD_COMMAND_CHANGE_DISK; - block->id = id; - block->callback = callback; - DCInvalidateRange(bootInfo->FSTLocation, bootInfo->FSTMaxLength); - - idle = issueCommand(2, block); - ASSERTMSGLINE(2913, idle, "DVDChangeDisk(): command block is used for processing previous request."); - return idle; -} - -s32 DVDChangeDisk(DVDCommandBlock* block, DVDDiskID* id) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDChangeDiskAsync(block, id, cbForChangeDiskSync); - if (result == 0) { - return -1; - } - - enabled = OSDisableInterrupts(); - while (1) { - state = block->state; - if (state == DVD_STATE_END) { - retVal = 0; - break; - } else if (state == DVD_STATE_FATAL_ERROR) { - retVal = -1; - break; - } else if (state == DVD_STATE_CANCELED) { - retVal = -3; - break; - } - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForChangeDiskSync(s32 result, DVDCommandBlock* block) { - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDStopMotorAsync(DVDCommandBlock* block, DVDCBCallback callback) { - int idle; - ASSERTMSGLINE(2996, block, "DVDStopMotor(): Null address was specified for block"); - - block->command = DVD_COMMAND_UNK_16; - block->callback = callback; - - idle = issueCommand(2, block); - ASSERTMSGLINE(3002, idle, "DVDStopMotor(): command block is used for processing previous request."); - return idle; -} - -s32 DVDStopMotor(DVDCommandBlock* block) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDStopMotorAsync(block, cbForStopMotorSync); - if (result == 0) { - return -1; - } - - enabled = OSDisableInterrupts(); - while (1) { - state = block->state; - if (state == DVD_STATE_END) { - retVal = 0; - break; - } else if (state == DVD_STATE_FATAL_ERROR) { - retVal = -1; - break; - } else if (state == DVD_STATE_CANCELED) { - retVal = -3; - break; - } - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForStopMotorSync(s32 result, DVDCommandBlock* block) { - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback) { - int idle; - - ASSERTMSGLINE(3085, block, "DVDInquiry(): Null address was specified for block"); - ASSERTMSGLINE(3086, info, "DVDInquiry(): Null address was specified for info"); - ASSERTMSGLINE(3088, !OFFSET(info, 32), "DVDInquiry(): Address for info is not 32 bytes aligned"); - - block->command = DVD_COMMAND_INQUIRY; - block->addr = info; - block->length = 0x20; - block->transferredSize = 0; - block->callback = callback; - idle = issueCommand(2, block); - return idle; -} - -s32 DVDInquiry(DVDCommandBlock* block, DVDDriveInfo* info) { - int result; - s32 state; - BOOL enabled; - s32 retVal; - - result = DVDInquiryAsync(block, info, cbForInquirySync); - if (result == 0) { - return -1; - } - - enabled = OSDisableInterrupts(); - while (1) { - state = block->state; - if (state == DVD_STATE_END) { - retVal = (u32)block->transferredSize; - break; - } else if (state == DVD_STATE_FATAL_ERROR) { - retVal = -1; - break; - } else if (state == DVD_STATE_CANCELED) { - retVal = -3; - break; - } - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForInquirySync(s32 result, DVDCommandBlock* block) { - OSWakeupThread(&__DVDThreadQueue); -} - -void DVDReset(void) { - DVDLowReset(); - __DIRegs[0] = 0x2A; - __DIRegs[1] = __DIRegs[1]; - ResetRequired = 0; - ResumeFromHere = 0; -} - -int DVDResetRequired(void) { - return ResetRequired; -} - -s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block) { - BOOL enabled; - s32 retVal; - - ASSERTMSGLINE(3197, block, "DVDGetCommandBlockStatus(): null pointer is specified to command block address."); - enabled = OSDisableInterrupts(); - - if (block->state == 3) { - retVal = 1; - } else { - retVal = block->state; - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -s32 DVDGetDriveStatus(void) { - BOOL enabled = OSDisableInterrupts(); - s32 retVal; - - if (FatalErrorFlag != FALSE) { - retVal = DVD_STATE_FATAL_ERROR; - } else { - if (PausingFlag != FALSE) { - retVal = DVD_STATE_PAUSING; - } else { - if (executing == NULL) { - retVal = DVD_STATE_END; - } else if (executing == &DummyCommandBlock) { - retVal = DVD_STATE_END; - } else { - retVal = DVDGetCommandBlockStatus((DVDCommandBlock*)executing); - } - } - } - OSRestoreInterrupts(enabled); - return retVal; -} - -BOOL DVDSetAutoInvalidation(BOOL autoInval) { - BOOL prev; - - prev = autoInvalidation; - autoInvalidation = autoInval; - return prev; -} - -void DVDPause(void) { - BOOL level; - - level = OSDisableInterrupts(); - PauseFlag = 1; - if (executing == NULL) { - PausingFlag = 1; - } - OSRestoreInterrupts(level); -} - -void DVDResume(void) { - BOOL level; - - level = OSDisableInterrupts(); - PauseFlag = 0; - if (PausingFlag != 0) { - PausingFlag = 0; - stateReady(); - } - OSRestoreInterrupts(level); -} - -int DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) { - BOOL enabled; - DVDLowCallback old; - DVDCommandBlock* finished; - - enabled = OSDisableInterrupts(); - - switch (block->state) { - case DVD_STATE_FATAL_ERROR: - case DVD_STATE_END: - case DVD_STATE_CANCELED: - if (callback) - (*callback)(0, block); - break; - case DVD_STATE_BUSY: - if (Canceling) { - OSRestoreInterrupts(enabled); - return FALSE; - } - - Canceling = TRUE; - CancelCallback = callback; - if (block->command == DVD_COMMAND_BSREAD || block->command == DVD_COMMAND_READ) { - DVDLowBreak(); - } - break; - case DVD_STATE_WAITING: - __DVDDequeueWaitingQueue(block); - block->state = DVD_STATE_CANCELED; - - if (block->callback) - (block->callback)(-3, block); - - if (callback) - (*callback)(0, block); - break; - case DVD_STATE_COVER_CLOSED: - switch (block->command) { - case DVD_COMMAND_READID: - case DVD_COMMAND_BSREAD: - case DVD_COMMAND_AUDIO_BUFFER_CONFIG: - case DVD_COMMAND_BS_CHANGE_DISK: - if (callback) - (*callback)(0, block); - break; - - default: - if (Canceling) { - OSRestoreInterrupts(enabled); - return FALSE; - } - Canceling = TRUE; - CancelCallback = callback; - break; - } - break; - case DVD_STATE_NO_DISK: - case DVD_STATE_COVER_OPEN: - case DVD_STATE_WRONG_DISK: - case DVD_STATE_MOTOR_STOPPED: - case DVD_STATE_RETRY: - old = DVDLowClearCallback(); - ASSERTLINE(3418, old == cbForStateMotorStopped); - - if (old != cbForStateMotorStopped) { - OSRestoreInterrupts(enabled); - return FALSE; - } - - if (block->state == DVD_STATE_NO_DISK) - ResumeFromHere = 3; - if (block->state == DVD_STATE_COVER_OPEN) - ResumeFromHere = 4; - if (block->state == DVD_STATE_WRONG_DISK) - ResumeFromHere = 1; - if (block->state == DVD_STATE_RETRY) - ResumeFromHere = 2; - if (block->state == DVD_STATE_MOTOR_STOPPED) - ResumeFromHere = 7; - - finished = executing; - executing = &DummyCommandBlock; - - block->state = DVD_STATE_CANCELED; - if (block->callback) { - (block->callback)(-3, block); - } - - if (callback) { - (callback)(0, block); - } - stateReady(); - break; - } - - OSRestoreInterrupts(enabled); - return TRUE; -} - -s32 DVDCancel(volatile DVDCommandBlock* block) { - int result; - s32 state; - u32 command; - BOOL enabled; - - result = DVDCancelAsync((void*)block, cbForCancelSync); - if (result == 0) { - return -1; - } - - enabled = OSDisableInterrupts(); - while (1) { - state = block->state; - if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { - break; - } - - if (state == DVD_STATE_COVER_CLOSED) { - command = block->command; - if ((command == DVD_COMMAND_BSREAD) || (command == DVD_COMMAND_READID) || (command == DVD_COMMAND_AUDIO_BUFFER_CONFIG) || (command == DVD_COMMAND_BS_CHANGE_DISK)) { - break; - } - } - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return 0; -} - -static void cbForCancelSync(s32 result, DVDCommandBlock* block) { - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDCancelAllAsync(DVDCBCallback callback) { - BOOL enabled; - DVDCommandBlock* p; - int retVal; - - enabled = OSDisableInterrupts(); - DVDPause(); - while ((p = __DVDPopWaitingQueue())) { - DVDCancelAsync(p, NULL); - } - - if (executing) { - retVal = DVDCancelAsync(executing, callback); - } else { - retVal = 1; - if (callback) { - callback(0, NULL); - } - } - - DVDResume(); - OSRestoreInterrupts(enabled); - return retVal; -} - -s32 DVDCancelAll(void) { - int result; - BOOL enabled; - - enabled = OSDisableInterrupts(); - CancelAllSyncComplete = 0; - result = DVDCancelAllAsync(cbForCancelAllSync); - if (result == 0) { - OSRestoreInterrupts(enabled); - return -1; - } - - while (1) { - if (CancelAllSyncComplete == 0) { - OSSleepThread(&__DVDThreadQueue); - } else { - break; - } - } - - OSRestoreInterrupts(enabled); - return 0; -} - -static void cbForCancelAllSync(s32 result, DVDCommandBlock* block) { - CancelAllSyncComplete = 1; - OSWakeupThread(&__DVDThreadQueue); -} - -DVDDiskID* DVDGetCurrentDiskID(void) { - return (void*)OSPhysicalToCached(0); -} - -BOOL DVDCheckDisk(void) { - BOOL enabled; - s32 retVal; - s32 state; - u32 coverReg; - - enabled = OSDisableInterrupts(); - - if (FatalErrorFlag) { - state = -1; - } else if (PausingFlag) { - state = 8; - } else { - if (executing == NULL) { - state = 0; - } else if (executing == &DummyCommandBlock) { - state = 0; - } else { - state = executing->state; - } - } - - switch (state) { - case DVD_STATE_BUSY: - case DVD_STATE_IGNORED: - case DVD_STATE_CANCELED: - case DVD_STATE_WAITING: - retVal = TRUE; - break; - case DVD_STATE_FATAL_ERROR: - case DVD_STATE_RETRY: - case DVD_STATE_MOTOR_STOPPED: - case DVD_STATE_COVER_CLOSED: - case DVD_STATE_NO_DISK: - case DVD_STATE_COVER_OPEN: - case DVD_STATE_WRONG_DISK: - retVal = FALSE; - break; - case DVD_STATE_END: - case DVD_STATE_PAUSING: - coverReg = __DIRegs[1]; - if (((coverReg >> 2) & 1) || (coverReg & 1)) { - retVal = FALSE; - } else if (ResumeFromHere != 0) { - retVal = FALSE; - } else { - retVal = TRUE; - } - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -void __DVDPrepareResetAsync(DVDCBCallback callback) { - BOOL enabled; - - enabled = OSDisableInterrupts(); - - __DVDClearWaitingQueue(); - - if (Canceling) { - CancelCallback = callback; - } else { - if (executing) { - executing->callback = NULL; - } - - DVDCancelAllAsync(callback); - } - - OSRestoreInterrupts(enabled); -} - -int __DVDTestAlarm(const OSAlarm* alarm) { - if (alarm == &ResetAlarm) { - return 1; - } - return __DVDLowTestAlarm(alarm); -} diff --git a/src/dolphin/dvd/dvdFatal.c b/src/dolphin/dvd/dvdFatal.c deleted file mode 100644 index abb3a64..0000000 --- a/src/dolphin/dvd/dvdFatal.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include - -#include "__dvd.h" - -static void (*FatalFunc)(); - -const char* Japanese = - "\n\n\nエラーが発生しました。\n\n" - "本体のパワーボタンを押して電源をOFFにし、\n" - "本体の取扱説明書の指示に従ってください。"; - -const char* English = - "\n\n\nAn error has occurred.\n" - "Turn the power off and refer to the\n" - "Nintendo GameCube Instruction Booklet\n" - "for further instructions."; - -// TODO: need solution to compile special characters in a cleaner way -const char* const Europe[6] = { - { - "\n\n\nAn error has occurred.\n" - "Turn the power off and refer to the\n" - "Nintendo GameCube Instruction Booklet\n" - "for further instructions." - }, - { - "\n\n\nEin Fehler ist aufgetreten.\n" - "Bitte schalten Sie den Nintendo GameCube\n" - "aus und lesen Sie die Bedienungsanleitung,\n" - "um weitere Informationen zu erhalten." - }, - { - "\n\n\nUne erreur est survenue.\n" - "Eteignez la console et r\xE9" "f" "\xE9rez-vous au\n" - "manuel d'instructions Nintendo GameCube\n" - "pour de plus amples informations." - }, - { - "\n\n\nSe ha producido un error.\n" - "Apaga la consola y consulta el manual\n" - "de instrucciones de Nintendo GameCube\n" - "para obtener m\xE1" "s informaci\xF3" "n." - }, - { - "\n\n\nSi \xE8" " verificato un errore.\n" - "Spegni (OFF) e controlla il manuale\n" - "d'istruzioni del Nintendo GameCube\n" - "per ulteriori indicazioni." - }, - { - "\n\n\nEr is een fout opgetreden.\n" - "Zet de Nintendo GameCube uit en\n" - "raadpleeg de handleiding van de\n" - "Nintendo GameCube voor nadere\n" - "instructies." - }, -}; - -static void ShowMessage(void) { - const char* message; - GXColor bg = {0x00, 0x00, 0x00, 0x00}; - GXColor fg = {0xFF, 0xFF, 0xFF, 0x00}; - - if (VIGetTvFormat() == VI_NTSC) { - if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) { - message = Japanese; - } else { - message = English; - } - } else { - message = Europe[OSGetLanguage()]; - } - - OSFatal(fg, bg, message); -} - -int DVDSetAutoFatalMessaging(BOOL enable) { - BOOL enabled; - int prev; - - enabled = OSDisableInterrupts(); - - prev = FatalFunc ? 1 : 0; - FatalFunc = enable ? ShowMessage : NULL; - - OSRestoreInterrupts(enabled); - return prev; -} - -void __DVDPrintFatalMessage(void) { - if (FatalFunc) { - FatalFunc(); - } -} diff --git a/src/dolphin/dvd/dvderror.c b/src/dolphin/dvd/dvderror.c deleted file mode 100644 index 894312e..0000000 --- a/src/dolphin/dvd/dvderror.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include - -#include "os/__os.h" -#include "__dvd.h" - -static u32 ErrorTable[18] = { - 0x00000000, - 0x00023A00, - 0x00062800, - 0x00030200, - 0x00031100, - 0x00052000, - 0x00052001, - 0x00052100, - 0x00052400, - 0x00052401, - 0x00052402, - 0x000B5A01, - 0x00056300, - 0x00020401, - 0x00020400, - 0x00040800, - 0x00100007, - 0x00000000, -}; - -#define DIDNT_MATCH 29 - -static u8 ErrorCode2Num(u32 errorCode) { - u32 i; - - for (i = 0; i < 18; i++) { - if (errorCode == ErrorTable[i]) { - ASSERTLINE(73, i < DIDNT_MATCH); - return i; - } - } - - if (errorCode >= 0x100000 && errorCode <= 0x100008) { - return 17; - } - - return DIDNT_MATCH; -} - -static u8 Convert(u32 error) { - u32 statusCode; - u32 errorCode; - u8 errorNum; - - if (error == 0x01234567) { - return -1; - } else if (error == 0x01234568) { - return -2; - } - - statusCode = (error >> 24) & 0xFF; - errorCode = error & 0x00FFFFFF; - errorNum = ErrorCode2Num(errorCode); - if (statusCode >= 6) { - statusCode = 6; - } - - return statusCode * 30 + errorNum; -} - -void __DVDStoreErrorCode(u32 error) { - OSSramEx* sram; - u8 num; - - num = Convert(error); - sram = __OSLockSramEx(); - sram->dvdErrorCode = num; - __OSUnlockSramEx(TRUE); -} diff --git a/src/dolphin/dvd/dvdfs.c b/src/dolphin/dvd/dvdfs.c deleted file mode 100644 index 4a0a282..0000000 --- a/src/dolphin/dvd/dvdfs.c +++ /dev/null @@ -1,630 +0,0 @@ -#include -#include - -#include "__dvd.h" - -typedef struct FSTEntry { - /* 0x00 */ unsigned int isDirAndStringOff; - /* 0x04 */ unsigned int parentOrPosition; - /* 0x08 */ unsigned int nextEntryOrLength; -} FSTEntry; - -static OSBootInfo* BootInfo; -static FSTEntry* FstStart; -static char* FstStringStart; -static u32 MaxEntryNum; -static u32 currentDirectory; - -OSThreadQueue __DVDThreadQueue; -u32 __DVDLongFileNameFlag; - -// prototypes -static BOOL isSame(const char* path, const char* string); -static u32 myStrncpy(char* dest, char* src, u32 maxlen); -static u32 entryToPath(u32 entry, char* path, u32 maxlen); -static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen); -static void cbForReadAsync(s32 result, DVDCommandBlock* block); -static void cbForReadSync(s32 result, DVDCommandBlock* block); -static void cbForSeekAsync(s32 result, DVDCommandBlock* block); -static void cbForSeekSync(s32 result, DVDCommandBlock* block); -static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block); -static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block); - -void __DVDFSInit(void) { - BootInfo = (void*)OSPhysicalToCached(0); - FstStart = BootInfo->FSTLocation; - if (FstStart) { - MaxEntryNum = FstStart->nextEntryOrLength; - FstStringStart = (char*)FstStart + (MaxEntryNum* sizeof(FSTEntry)); - } -} - -/* For convenience */ -#define entryIsDir(i) (((FstStart[i].isDirAndStringOff & 0xff000000) == 0) ? FALSE : TRUE) -#define stringOff(i) (FstStart[i].isDirAndStringOff & ~0xff000000) -#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; - - ASSERTMSGLINE(318, pathPtr, "DVDConvertPathToEntrynum(): null pointer is specified "); - - 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__, 387, - "DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): " - "specified directory or file (%s) doesn't match standard 8.3 format. This is a " - "temporary restriction and will be removed soon\n", - origPathPtr); - } 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) { - ASSERTMSGLINE(455, fileInfo, "DVDFastOpen(): null pointer is specified to file info address "); - ASSERTMSG1LINE(458, (entrynum >= 0) && ((u32) entrynum < (u32) MaxEntryNum), "DVDFastOpen(): specified entry number '%d' is out of range ", entrynum); - ASSERTMSG1LINE(461, !entryIsDir(entrynum), "DVDFastOpen(): entry number '%d' is assigned to a directory ", entrynum); - - if (entrynum < 0 || entrynum >= MaxEntryNum || entryIsDir(entrynum)) { - return FALSE; - } - - fileInfo->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]; - - ASSERTMSGLINE(491, fileName, "DVDOpen(): null pointer is specified to file name "); - ASSERTMSGLINE(492, fileInfo, "DVDOpen(): null pointer is specified to file info address "); - - entry = DVDConvertPathToEntrynum(fileName); - - if (0 > entry) { - DVDGetCurrentDir(currentDir, 128); - OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir); - return FALSE; - } - - if (entryIsDir(entry)) { - ASSERTMSG1LINE(506, !entryIsDir(entry), "DVDOpen(): directory '%s' is specified as a filename ", fileName); - return FALSE; - } - - fileInfo->startAddr = filePosition(entry); - fileInfo->length = fileLength(entry); - fileInfo->callback = (DVDCallback)NULL; - fileInfo->cb.state = DVD_STATE_END; - - return TRUE; -} - -BOOL DVDClose(DVDFileInfo* fileInfo) { - ASSERTMSGLINE(530, fileInfo, "DVDClose(): null pointer is specified to file info address "); - DVDCancel(&(fileInfo->cb)); - return TRUE; -} - -static u32 myStrncpy(char* dest, char* src, u32 maxlen) { - u32 i = maxlen; - - while ((i > 0) && (*src != 0)) { - *dest++ = *src++; - i--; - } - - return (maxlen - i); -} - -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; - - ASSERTMSG1LINE(622, (entrynum >= 0) && (entrynum < MaxEntryNum), "DVDConvertEntrynumToPath: specified entrynum(%d) is out of range ", entrynum); - ASSERTMSG1LINE(624, maxlen > 1, "DVDConvertEntrynumToPath: maxlen should be more than 1 (%d is specified)", maxlen); - ASSERTMSGLINE(629, entryIsDir(entrynum), "DVDConvertEntrynumToPath: cannot convert an entry num for a file to path "); - - loc = entryToPath((u32)entrynum, path, maxlen); - - if (loc == maxlen) { - path[maxlen - 1] = '\0'; - return FALSE; - } - - if (entryIsDir(entrynum)) { - if (loc == maxlen - 1) { - path[loc] = '\0'; - return FALSE; - } - - path[loc++] = '/'; - } - - path[loc] = '\0'; - return TRUE; -} - -BOOL DVDGetCurrentDir(char* path, u32 maxlen) { - ASSERTMSG1LINE(671, (maxlen > 1), "DVDGetCurrentDir: maxlen should be more than 1 (%d is specified)", maxlen); - return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); -} - -BOOL DVDChangeDir(const char* dirName) { - s32 entry; - char currentDir[128]; - - ASSERTMSGLINE(693, dirName, "DVDChangeDir(): null pointer is specified to directory name "); - entry = DVDConvertPathToEntrynum(dirName); - ASSERTMSG2LINE(701, entry >= 0, "DVDChangeDir(): directory '%s' is not found under %s ", dirName, (DVDGetCurrentDir(currentDir, 128), currentDir)); - ASSERTMSG1LINE(705, entryIsDir(entry), "DVDChangeDir(): file '%s' is specified as a directory name ", dirName); - - if (entry < 0 || entryIsDir(entry) == FALSE) { - return FALSE; - } - - currentDirectory = (u32)entry; - - return TRUE; -} - -BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, DVDCallback callback, s32 prio) { - ASSERTMSGLINE(736, fileInfo, "DVDReadAsync(): null pointer is specified to file info address "); - ASSERTMSGLINE(737, addr, "DVDReadAsync(): null pointer is specified to addr "); - ASSERTMSGLINE(741, !OFFSET(addr, 32), "DVDReadAsync(): address must be aligned with 32 byte boundaries "); - ASSERTMSGLINE(743, !(length & 0x1F), "DVDReadAsync(): length must be multiple of 32 byte "); - ASSERTMSGLINE(745, !(offset & 3), "DVDReadAsync(): offset must be multiple of 4 byte "); - - DVD_ASSERTMSGLINE(750, (0 <= offset) && (offset <= fileInfo->length), "DVDReadAsync(): specified area is out of the file "); - - DVD_ASSERTMSGLINE(756, (0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE), "DVDReadAsync(): specified area is out of the file "); - - fileInfo->callback = callback; - DVDReadAbsAsyncPrio(&(fileInfo->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)); - ASSERTLINE(774, (void*) &fileInfo->cb == (void*) block); - if (fileInfo->callback) { - (fileInfo->callback)(result, fileInfo); - } -} - -s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) { - int result; - DVDCommandBlock* block; - s32 state; - BOOL enabled; - s32 retVal; - - ASSERTMSGLINE(806, fileInfo, "DVDRead(): null pointer is specified to file info address "); - ASSERTMSGLINE(807, addr, "DVDRead(): null pointer is specified to addr "); - ASSERTMSGLINE(811, !OFFSET(addr, 32), "DVDRead(): address must be aligned with 32 byte boundaries "); - ASSERTMSGLINE(813, !(length & 0x1F), "DVDRead(): length must be multiple of 32 byte "); - ASSERTMSGLINE(815, !(offset & 3), "DVDRead(): offset must be multiple of 4 byte "); - - DVD_ASSERTMSGLINE(820, (0 <= offset) && (offset <= fileInfo->length), "DVDRead(): specified area is out of the file "); - DVD_ASSERTMSGLINE(826, (0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE), "DVDRead(): specified area is out of the file "); - - block = &fileInfo->cb; - result = DVDReadAbsAsyncPrio(block, addr, length, fileInfo->startAddr + offset, cbForReadSync, prio); - if (result == 0) { - return -1; - } - enabled = OSDisableInterrupts(); - - while (1) { - state = ((volatile DVDCommandBlock*)block)->state; - if (state == 0) { - retVal = (s32)block->transferredSize; - break; - } else if (state == -1) { - retVal = -1; - break; - } else if (state == 10) { - retVal = -3; - break; - } - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForReadSync(s32 result, DVDCommandBlock* block) { - OSWakeupThread(&__DVDThreadQueue); -} - -int DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio) { - ASSERTMSGLINE(898, fileInfo, "DVDSeek(): null pointer is specified to file info address "); - ASSERTMSGLINE(902, !(offset & 3), "DVDSeek(): offset must be multiple of 4 byte "); - - DVD_ASSERTMSGLINE(907, (0 <= offset) && (offset <= fileInfo->length), "DVDSeek(): offset is out of the file "); - - fileInfo->callback = callback; - DVDSeekAbsAsyncPrio(&fileInfo->cb, (u32)(char*)fileInfo->startAddr + offset, cbForSeekAsync, prio); - return 1; -} - -static void cbForSeekAsync(s32 result, DVDCommandBlock* block) { - DVDFileInfo* fileInfo; - - fileInfo = (DVDFileInfo *)&block->next; - ASSERTLINE(925, (void*) &fileInfo->cb == (void*) block); - if (fileInfo->callback) { - (fileInfo->callback)(result, fileInfo); - } -} - -s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio) { - int result; - DVDCommandBlock* block; - s32 state; - BOOL enabled; - s32 retVal; - - ASSERTMSGLINE(955, fileInfo, "DVDSeek(): null pointer is specified to file info address "); - ASSERTMSGLINE(959, !(offset & 3), "DVDSeek(): offset must be multiple of 4 byte "); - ASSERTMSGLINE(963, (offset >= 0) && ((u32) offset <= (u32) fileInfo->length), "DVDSeek(): offset is out of the file "); - - block = &fileInfo->cb; - result = DVDSeekAbsAsyncPrio(block, (u32)(char*)fileInfo->startAddr + offset, cbForSeekSync, prio); - if (!result) { - return -1; - } - enabled = OSDisableInterrupts(); - - while (1) { - state = ((volatile DVDCommandBlock*)block)->state; - if (state == 0) { - retVal = 0; - break; - } else if (state == -1) { - retVal = -1; - break; - } else if (state == 10) { - retVal = -3; - break; - } - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForSeekSync(s32 result, DVDCommandBlock* block) { - OSWakeupThread(&__DVDThreadQueue); -} - -s32 DVDGetFileInfoStatus(const DVDFileInfo* fileInfo) { - return DVDGetCommandBlockStatus(&fileInfo->cb); -} - -BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) { - ASSERTMSGLINE(1048, dir, "DVDFastOpenDir(): null pointer is specified to dir structure address "); - ASSERTMSG1LINE(1051, entrynum >= 0 && entrynum < MaxEntryNum, "DVDFastOpenDir(): specified entry number \'%d\' is out of range ", entrynum); - ASSERTMSG1LINE(1054, entryIsDir(entrynum), "DVDFastOpenDir(): entry number \'%d\' is assigned to a file ", entrynum); - - if (entrynum < 0 || entrynum >= MaxEntryNum || !entryIsDir(entrynum)) { - return FALSE; - } - - dir->entryNum = entrynum; - dir->location = entrynum + 1; - dir->next = FstStart[entrynum].nextEntryOrLength; - return TRUE; -} - -BOOL DVDOpenDir(const char* dirName, DVDDir* dir) { - s32 entry; - char currentDir[128]; - - ASSERTMSGLINE(1083, dirName, "DVDOpendir(): null pointer is specified to directory name "); - ASSERTMSGLINE(1084, dir, "DVDOpenDir(): null pointer is specified to dir structure address "); - - entry = DVDConvertPathToEntrynum(dirName); - if (entry < 0) { - DVDGetCurrentDir(currentDir, sizeof(currentDir)); - OSReport("Warning: DVDOpenDir(): file \'%s\' was not found under %s.\n", dirName, currentDir); - return FALSE; - } - - if (!entryIsDir(entry)) { - ASSERTMSG1LINE(1098, entryIsDir(entry), "DVDOpendir(): file \'%s\' is specified as a directory name ", dirName); - return FALSE; - } - - dir->entryNum = entry; - dir->location = entry + 1; - dir->next = nextDir(entry); - return TRUE; -} - -int DVDReadDir(DVDDir* dir, DVDDirEntry* dirent) { - u32 loc; - - loc = dir->location; - if ((loc <= (u32) dir->entryNum) || ((u32) dir->next <= loc)) { - return 0; - } - dirent->entryNum = loc; - dirent->isDir = entryIsDir(loc); - dirent->name = FstStringStart + stringOff(loc); - dir->location = entryIsDir(loc) ? nextDir(loc) : loc + 1; - return 1; -} - -int DVDCloseDir(DVDDir* dir) { - return 1; -} - -void DVDRewindDir(DVDDir* dir) { - dir->location = dir->entryNum + 1; -} - -void* DVDGetFSTLocation(void) { - return BootInfo->FSTLocation; -} - -#define RoundUp32KB(x) (((u32)(x) + 32 * 1024 - 1) & ~(32 * 1024 - 1)) -#define Is32KBAligned(x) (((u32)(x) & (32 * 1024 - 1)) == 0) - -BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback) { - u32 start; - - ASSERTMSGLINE(1205, fileInfo, "DVDPrepareStreamAsync(): NULL file info was specified"); - - start = fileInfo->startAddr + offset; - - DVD_ASSERTMSG2LINE(1211, Is32KBAligned(start), "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is not 32KB aligned", fileInfo->startAddr, offset); - - if (length == 0) - length = fileInfo->length - offset; - - DVD_ASSERTMSG1LINE(1221, Is32KBAligned(length), "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", length); - - DVD_ASSERTMSG2LINE(1229, (offset <= fileInfo->length) && (offset + length <= fileInfo->length), "DVDPrepareStreamAsync(): The area specified (offset(0x%x), length(0x%x)) is out of the file", offset, length); - - fileInfo->callback = callback; - return DVDPrepareStreamAbsAsync(&(fileInfo->cb), length, fileInfo->startAddr + offset, cbForPrepareStreamAsync); -} - -static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block) { - DVDFileInfo* fileInfo; - - fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); - - ASSERTLINE(1248, (void*) &fileInfo->cb == (void*) block); - - if (fileInfo->callback) { - (fileInfo->callback)(result, fileInfo); - } -} - -s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset) { - BOOL result; - DVDCommandBlock* block; - s32 state; - BOOL enabled; - s32 retVal; - u32 start; - - ASSERTMSGLINE(1282, fileInfo, "DVDPrepareStream(): NULL file info was specified"); - - start = fileInfo->startAddr + offset; - - DVD_ASSERTMSG2LINE(1288, Is32KBAligned(start), "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not 32KB aligned", fileInfo->startAddr, offset); - - if (length == 0) - length = fileInfo->length - offset; - - DVD_ASSERTMSG1LINE(1298, Is32KBAligned(length), "DVDPrepareStream(): Specified length (0x%x) is not a multiple of 32768(32*1024)", length); - - DVD_ASSERTMSG2LINE(1306, (offset <= fileInfo->length) && (offset + length <= fileInfo->length), "DVDPrepareStream(): The area specified (offset(0x%x), length(0x%x)) is out of the file", offset, length); - - block = &(fileInfo->cb); - result = DVDPrepareStreamAbsAsync(block, length, start, cbForPrepareStreamSync); - - if (result == FALSE) { - return -1; - } - - enabled = OSDisableInterrupts(); - - while (1) { - state = ((volatile DVDCommandBlock*)block)->state; - - if (state == DVD_STATE_END) { - retVal = 0; - break; - } - if (state == DVD_STATE_FATAL_ERROR) { - retVal = DVD_RESULT_FATAL_ERROR; - break; - } - if (state == DVD_STATE_CANCELED) { - retVal = -3; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block) { - OSWakeupThread(&__DVDThreadQueue); -} - -s32 DVDGetTransferredSize(DVDFileInfo* fileinfo) { - s32 bytes; - DVDCommandBlock* cb; - - cb = &(fileinfo->cb); - - switch (cb->state) { - case DVD_STATE_COVER_CLOSED: - case DVD_STATE_NO_DISK: - case DVD_STATE_COVER_OPEN: - case DVD_STATE_WRONG_DISK: - case DVD_STATE_FATAL_ERROR: - case DVD_STATE_MOTOR_STOPPED: - case DVD_STATE_CANCELED: - case DVD_STATE_RETRY: - case DVD_STATE_END: - bytes = (s32)cb->transferredSize; - break; - case DVD_STATE_WAITING: - bytes = 0; - break; - case DVD_STATE_BUSY: - bytes = (s32)(cb->transferredSize + (cb->currTransferSize - __DIRegs[6])); - break; - default: - ASSERTMSG1LINE(1391, FALSE, "DVDGetTransferredSize(): Illegal state (%d)", cb->state); - break; - } - - return bytes; -} diff --git a/src/dolphin/dvd/dvdidutils.c b/src/dolphin/dvd/dvdidutils.c deleted file mode 100644 index a702a65..0000000 --- a/src/dolphin/dvd/dvdidutils.c +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include - -#include "__dvd.h" - -static u32 strnlen(const char* str, u32 maxlen) { - u32 i; - - for (i = 0; i < maxlen; i++) { - if (*str++ == 0) { - return i; - } - } - - return maxlen; -} - -int DVDCompareDiskID(const DVDDiskID* id1, const DVDDiskID* id2) { -#ifdef DEBUG - const char* game1; - const char* game2; - const char* company1; - const char* company2; - u8 diskNum1; - u8 diskNum2; - u8 version1; - u8 version2; - u32 length; - - ASSERTMSGLINE(64, id1, "DVDCompareDiskID(): Specified id1 is NULL\n"); - ASSERTMSGLINE(65, id2, "DVDCompareDiskID(): Specified id2 is NULL\n"); - - game1 = id1->gameName; - game2 = id2->gameName; - company1 = id1->company; - company2 = id2->company; - diskNum1 = id1->diskNumber; - diskNum2 = id2->diskNumber; - version1 = id1->gameVersion; - version2 = id2->gameVersion; - - length = strnlen(game1, sizeof(game1)); - ASSERTMSGLINE(78, length == 0 || length == 4, "DVDCompareDiskID(): Specified game name for id1 is neither NULL nor 4 character long\n"); - ASSERTMSGLINE(79, company1, "DVDCompareDiskID(): Specified company name for id1 is NULL\n"); - ASSERTMSGLINE(80, company1[1] != 0, "DVDCompareDiskID(): Specified company name for id1 is not 2 character long\n"); - ASSERTMSGLINE(81, diskNum1 == 0xFF || ((diskNum1 / 16) < 10 && diskNum1 % 16 < 10), "DVDCompareDiskID(): Specified disk number for id1 is neither 0xff nor a BCD number"); - ASSERTMSGLINE(82, version1 == 0xFF || ((version1 / 16) < 10 && version1 % 16 < 10), "DVDCompareDiskID(): Specified version number for id1 is neither 0xff nor a BCD number"); - - length = strnlen(game2, sizeof(game2)); - ASSERTMSGLINE(85, length == 0 || length == 4, "DVDCompareDiskID(): Specified game name for id2 is neither NULL nor 4 character long\n"); - ASSERTMSGLINE(86, company2, "DVDCompareDiskID(): Specified company name for id2 is NULL\n"); - ASSERTMSGLINE(87, company2[1] != 0, "DVDCompareDiskID(): Specified company name for id2 is not 2 character long\n"); - ASSERTMSGLINE(88, diskNum2 == 0xFF || ((diskNum2 / 16) < 10 && diskNum2 % 16 < 10), "DVDCompareDiskID(): Specified disk number for id2 is neither 0xff nor a BCD number"); - ASSERTMSGLINE(89, version2 == 0xFF || ((version2 / 16) < 10 && version2 % 16 < 10), "DVDCompareDiskID(): Specified version number for id2 is neither 0xff nor a BCD number"); -#endif - - if (id1->gameName[0] != 0 && id2->gameName[0] != 0 && strncmp(id1->gameName, id2->gameName, 4) != 0) { - return 0; - } - - if (id1->company[0] == 0 || id2->company[0] == 0 || strncmp(id1->company, id2->company, 2) != 0) { - return 0; - } - - if (id1->diskNumber != 0xFF && id2->diskNumber != 0xFF && id1->diskNumber != id2->diskNumber) { - return 0; - } - - if (id1->gameVersion != 0xFF && id2->gameVersion != 0xFF && id1->gameVersion != id2->gameVersion) { - return 0; - } - - return 1; -} - -DVDDiskID* DVDGenerateDiskID(DVDDiskID* id, const char* game, const char* company, u8 diskNum, u8 version) { - ASSERTMSGLINE(123, id, "DVDGenerateDiskID(): Specified id is NULL\n"); - ASSERTMSGLINE(124, game == NULL || strlen(game) == 4, "DVDGenerateDiskID(): Specified game name is neither NULL nor 4 character long\n"); - ASSERTMSGLINE(125, company, "DVDGenerateDiskID(): Specified company name is NULL\n"); - ASSERTMSGLINE(126, strlen(company) == 2, "DVDGenerateDiskID(): Specified company name is not 2 character long\n"); - ASSERTMSGLINE(127, diskNum == 0xFF || ((diskNum / 16) < 10 && diskNum % 16 < 10), "DVDGenerateDiskID(): Specified disk number is neither 0xff nor a BCD number"); - ASSERTMSGLINE(128, version == 0xFF || ((version / 16) < 10 && version % 16 < 10), "DVDGenerateDiskID(): Specified version number is neither 0xff nor a BCD number"); - - memset(id, 0, sizeof(DVDDiskID)); - - if (game != NULL) { - strncpy(id->gameName, game, 4); - } - - if (company != NULL) { - strncpy(id->company, company, 2); - } - - id->diskNumber = diskNum; - id->gameVersion = version; - return id; -} diff --git a/src/dolphin/dvd/dvdlow.c b/src/dolphin/dvd/dvdlow.c deleted file mode 100644 index 79dca99..0000000 --- a/src/dolphin/dvd/dvdlow.c +++ /dev/null @@ -1,534 +0,0 @@ -#include -#include - -#include "__dvd.h" -#include "__os.h" - -#define DVD_WATYPE_MAX 2 - -static BOOL FirstRead = TRUE; -static volatile BOOL StopAtNextInt = FALSE; -static u32 LastLength = 0; -static DVDLowCallback Callback = NULL; -static DVDLowCallback ResetCoverCallback = NULL; -static volatile OSTime LastResetEnd = 0; -static volatile u32 ResetOccurred = FALSE; -static volatile BOOL WaitingCoverClose = FALSE; -static volatile BOOL Breaking = FALSE; -static volatile u32 WorkAroundType = 0; -static u32 WorkAroundSeekLocation = 0; -static volatile OSTime LastReadFinished = 0; -static OSTime LastReadIssued = 0; -static volatile BOOL LastCommandWasRead = FALSE; -static volatile u32 NextCommandNumber = 0; - -typedef struct { - void* addr; - u32 length; - u32 offset; -} DVDBuffer; - -typedef struct { - s32 command; - void* address; - 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; - -// prototypes -static void Read(void* address, u32 length, u32 offset, DVDLowCallback callback); -static void SetBreakAlarm(OSTime timeout); - -void __DVDInitWA(void) { - NextCommandNumber = 0; - CommandList[0].command = -1; - __DVDLowSetWAType(0, 0); - OSInitAlarm(); -} - -static BOOL ProcessNextCommand(void) { - s32 n = NextCommandNumber; - - ASSERTLINE(310, n < 3); - - if (CommandList[n].command == 1) { - ++NextCommandNumber; - Read(CommandList[n].address, CommandList[n].length, CommandList[n].offset, CommandList[n].callback); - return TRUE; - } else if (CommandList[n].command == 2) { - ++NextCommandNumber; - DVDLowSeek(CommandList[n].offset, CommandList[n].callback); - return TRUE; - } - - return FALSE; -} - -void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) { - DVDLowCallback cb; - OSContext exceptionContext; - u32 cause = 0; - u32 reg; - u32 intr; - u32 mask; - - if (LastCommandWasRead) { - LastReadFinished = __OSGetSystemTime(); - FirstRead = FALSE; - Prev.addr = Curr.addr; - Prev.length = Curr.length; - Prev.offset = Curr.offset; - - if (StopAtNextInt == TRUE) { - cause |= 8; - } - } - - LastCommandWasRead = FALSE; - StopAtNextInt = FALSE; - reg = __DIRegs[0]; - mask = reg & 0x2a; - intr = (reg & 0x54) & (mask << 1); - - if (intr & 0x40) { - cause |= 8; - } - - if (intr & 0x10) { - cause |= 1; - } - - if (intr & 4) { - cause |= 2; - } - - if (cause) { - ResetOccurred = FALSE; - OSCancelAlarm(&AlarmForTimeout); - } - - __DIRegs[0] = intr | mask; - - if (ResetOccurred && (__OSGetSystemTime() - LastResetEnd) < OSMillisecondsToTicks(200)) { - reg = __DIRegs[1]; - mask = reg & 0x2; - intr = (reg & 4) & (mask << 1); - if (intr & 4) { - if (ResetCoverCallback) { - ResetCoverCallback(4); - } - ResetCoverCallback = NULL; - } - - __DIRegs[1] = __DIRegs[1]; - } else if (WaitingCoverClose) { - reg = __DIRegs[1]; - mask = reg & 2; - intr = (reg & 4) & (mask << 1); - - if (intr & 4) { - cause |= 4; - } - - __DIRegs[1] = intr | mask; - WaitingCoverClose = FALSE; - } else { - __DIRegs[1] = 0; - } - - if ((cause & 8) && !Breaking) { - cause &= ~8; - } - - if (cause & 1) { - if (ProcessNextCommand()) { - return; - } - } else { - CommandList[0].command = -1; - NextCommandNumber = 0; - } - - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - - if (cause) { - cb = Callback; - Callback = NULL; - if (cb) { - cb(cause); - } - - Breaking = FALSE; - } - - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); -} - -static void AlarmHandler(OSAlarm* alarm, OSContext* context) { - BOOL processed = ProcessNextCommand(); - ASSERTLINE(652, processed); -} - -static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) { - DVDLowCallback cb; - OSContext exceptionContext; - - __OSMaskInterrupts(0x400); - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - cb = Callback; - Callback = NULL; - if (cb) { - cb(0x10); - } - - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); -} - -static void SetTimeoutAlarm(OSTime timeout) { - OSCreateAlarm(&AlarmForTimeout); - OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); -} - -static void Read(void* address, u32 length, u32 offset, DVDLowCallback callback) { - Callback = callback; - StopAtNextInt = FALSE; - LastCommandWasRead = TRUE; - LastReadIssued = __OSGetSystemTime(); - - __DIRegs[2] = 0xa8000000; - __DIRegs[3] = offset / 4; - __DIRegs[4] = length; - __DIRegs[5] = (u32)address; - __DIRegs[6] = length; - LastLength = length; - __DIRegs[7] = 3; - - if (length > 0xa00000) { - SetTimeoutAlarm(OSSecondsToTicks(20)); - } else { - SetTimeoutAlarm(OSSecondsToTicks(10)); - } -} - -static BOOL AudioBufferOn(void) { - DVDDiskID* id; - - id = DVDGetCurrentDiskID(); - if (id->streaming) { - return TRUE; - } - - return FALSE; -} - -static BOOL HitCache(DVDBuffer* curr, DVDBuffer* prev) { - u32 blockNumOfPrevEnd = (prev->offset + prev->length - 1) >> 15; - u32 blockNumOfCurrStart = (curr->offset >> 15); - u32 cacheBlockSize = AudioBufferOn() ? 5 : 15; - - if ((blockNumOfCurrStart > blockNumOfPrevEnd - 2) || (blockNumOfCurrStart < blockNumOfPrevEnd + cacheBlockSize + 3)) { - return TRUE; - } - return FALSE; -} - -static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { - CommandList[0].command = -1; - NextCommandNumber = 0; - Read(addr, length, offset, callback); -} - -static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { - u32 newOffset; - if ((offset & ~0x7FFF) == 0) { - newOffset = 0; - } else { - newOffset = (offset & ~0x7FFF) + WorkAroundSeekLocation; - } - - CommandList[0].command = 2; - CommandList[0].offset = newOffset; - CommandList[0].callback = callback; - CommandList[1].command = 1; - CommandList[1].address = addr; - CommandList[1].length = length; - CommandList[1].offset = offset; - CommandList[1].callback = callback; - CommandList[2].command = -1; - NextCommandNumber = 0; - DVDLowSeek(newOffset, callback); -} - -static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback, OSTime wait) { - CommandList[0].command = 1; - CommandList[0].address = addr; - CommandList[0].length = length; - CommandList[0].offset = offset; - CommandList[0].callback = callback; - CommandList[1].command = -1; - NextCommandNumber = 0; - OSCreateAlarm(&AlarmForWA); - OSSetAlarm(&AlarmForWA, wait, AlarmHandler); -} - -BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { - u32 blockNumOfPrevEnd; - u32 blockNumOfCurrStart; - OSTime diff; - - ASSERTMSGLINE(837, (((u32)addr) & 31) == 0, "DVDLowRead(): address must be aligned with 32 byte boundary."); - ASSERTMSGLINE(838, (length & 31) == 0, "DVDLowRead(): length must be a multiple of 32."); - ASSERTMSGLINE(839, (offset & 3) == 0, "DVDLowRead(): offset must be a multiple of 4."); - ASSERTMSGLINE(841, length != 0, "DVD read: 0 was specified to length of the read\n"); - - __DIRegs[6] = length; - Curr.addr = addr; - Curr.length = length; - Curr.offset = offset; - - if (WorkAroundType == 0) { - DoJustRead(addr, length, offset, callback); - } else if (WorkAroundType == 1) { - if (FirstRead) { - SeekTwiceBeforeRead(addr, length, offset, callback); - } else { - if (!HitCache(&Curr, &Prev)) { - DoJustRead(addr, length, offset, callback); - } else { - blockNumOfPrevEnd = (u32)((Prev.offset + Prev.length - 1) >> 15) & 0x1FFFF; - blockNumOfCurrStart = (u32)((Curr.offset >> 15) & 0x1FFFF); - if (blockNumOfPrevEnd == blockNumOfCurrStart || blockNumOfPrevEnd + 1 == blockNumOfCurrStart) { - diff = __OSGetSystemTime() - LastReadFinished; - if (OSMillisecondsToTicks(5) < diff) { - DoJustRead(addr, length, offset, callback); - } else { - WaitBeforeRead(addr, length, offset, callback, OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500)); - } - } else { - SeekTwiceBeforeRead(addr, length, offset, callback); - } - } - } - } else { - ASSERTLINE(900, FALSE); - } - - return TRUE; -} - -BOOL DVDLowSeek(u32 offset, DVDLowCallback callback) { - ASSERTMSGLINE(920, (offset & 3) == 0, "DVDLowSeek(): offset must be a multiple of 4."); - - Callback = callback; - StopAtNextInt = FALSE; - __DIRegs[2] = 0xab000000; - __DIRegs[3] = offset / 4; - __DIRegs[7] = 1; - SetTimeoutAlarm(OSSecondsToTicks(10)); - return TRUE; -} - -BOOL DVDLowWaitCoverClose(DVDLowCallback callback) { - Callback = callback; - WaitingCoverClose = TRUE; - StopAtNextInt = FALSE; - __DIRegs[1] = 2; - return TRUE; -} - -BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback) { - ASSERTMSGLINE(986, (((u32)diskID) & 31) == 0, "DVDLowReadID(): id must be aligned with 32 byte boundary."); - - Callback = callback; - StopAtNextInt = FALSE; - __DIRegs[2] = 0xa8000040; - __DIRegs[3] = 0; - __DIRegs[4] = sizeof(DVDDiskID); - __DIRegs[5] = (u32)diskID; - __DIRegs[6] = sizeof(DVDDiskID); - __DIRegs[7] = 3; - SetTimeoutAlarm(OSSecondsToTicks(10)); - return TRUE; -} - -BOOL DVDLowStopMotor(DVDLowCallback callback) { - Callback = callback; - StopAtNextInt = FALSE; - __DIRegs[2] = 0xe3000000; - __DIRegs[7] = 1; - SetTimeoutAlarm(OSSecondsToTicks(10)); - return TRUE; -} - -BOOL DVDLowRequestError(DVDLowCallback callback) { - Callback = callback; - StopAtNextInt = FALSE; - __DIRegs[2] = 0xe0000000; - __DIRegs[7] = 1; - SetTimeoutAlarm(OSSecondsToTicks(10)); - return TRUE; -} - -BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback) { - Callback = callback; - StopAtNextInt = FALSE; - __DIRegs[2] = 0x12000000; - __DIRegs[4] = sizeof(DVDDriveInfo); - __DIRegs[5] = (u32)info; - __DIRegs[6] = sizeof(DVDDriveInfo); - __DIRegs[7] = 3; - SetTimeoutAlarm(OSSecondsToTicks(10)); - return TRUE; -} - -BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback) { - Callback = callback; - StopAtNextInt = FALSE; - __DIRegs[2] = subcmd | 0xe1000000; - __DIRegs[3] = offset >> 2; - __DIRegs[4] = length; - __DIRegs[7] = 1; - SetTimeoutAlarm(OSSecondsToTicks(10)); - return TRUE; -} - -BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback) { - Callback = callback; - StopAtNextInt = FALSE; - __DIRegs[2] = subcmd | 0xe2000000; - __DIRegs[7] = 1; - SetTimeoutAlarm(OSSecondsToTicks(10)); - return TRUE; -} - -BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback) { -#ifdef DEBUG - u32 bufSize; - u32 trigger; -#endif - - Callback = callback; - StopAtNextInt = FALSE; - -#ifdef DEBUG - bufSize = size & 0xF; - trigger = (size >> 4) & 0xF; - ASSERTLINE(1242, bufSize < 16); - ASSERTLINE(1243, trigger <= 2); -#endif - - __DIRegs[2] = 0xe4000000 | (enable != 0 ? 0x10000 : 0) | size; - __DIRegs[7] = 1; - SetTimeoutAlarm(OSSecondsToTicks(10)); - return TRUE; -} - -void DVDLowReset(void) { - 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 | 4 | 1; - ResetOccurred = TRUE; - LastResetEnd = __OSGetSystemTime(); -} - -DVDLowCallback DVDLowSetResetCoverCallback(DVDLowCallback callback) { - DVDLowCallback old; - BOOL enabled; - - enabled = OSDisableInterrupts(); - old = ResetCoverCallback; - ResetCoverCallback = callback; - OSRestoreInterrupts(enabled); - return old; -} - -static void DoBreak(void) { - u32 statusReg; - - statusReg = __DIRegs[0]; - statusReg |= 0x40 | 1; - __DIRegs[0] = statusReg; - Breaking = TRUE; -} - -static void AlarmHandlerForBreak(OSAlarm* alarm, OSContext* context) { - if (__DIRegs[6] < LastLength) { - DoBreak(); - } else { - SetBreakAlarm(OSMillisecondsToTicks(20)); - } -} - -static void SetBreakAlarm(OSTime timeout) { - OSCreateAlarm(&AlarmForBreak); - OSSetAlarm(&AlarmForBreak, timeout, AlarmHandlerForBreak); -} - -BOOL DVDLowBreak(void) { - StopAtNextInt = TRUE; - Breaking = TRUE; - return TRUE; -} - -DVDLowCallback DVDLowClearCallback(void) { - DVDLowCallback old; - __DIRegs[1] = 0; - WaitingCoverClose = FALSE; - old = Callback; - Callback = NULL; - return old; -} - -u32 DVDLowGetCoverStatus(void) { - if ((__OSGetSystemTime() - LastResetEnd) < OSMillisecondsToTicks(100)) { - return 0; - } - - if (__DIRegs[1] & 1) { - return 1; - } - - return 2; -} - -void __DVDLowSetWAType(u32 type, s32 seekLoc) { - BOOL enabled; - - enabled = OSDisableInterrupts(); - ASSERTLINE(1491, type < DVD_WATYPE_MAX); - WorkAroundType = type; - WorkAroundSeekLocation = seekLoc; - OSRestoreInterrupts(enabled); -} - -int __DVDLowTestAlarm(const OSAlarm* alarm) { - if (alarm == &AlarmForBreak) { - return 1; - } - if (alarm == &AlarmForTimeout) { - return 1; - } - - return 0; -} diff --git a/src/dolphin/dvd/dvdqueue.c b/src/dolphin/dvd/dvdqueue.c deleted file mode 100644 index 2106f8c..0000000 --- a/src/dolphin/dvd/dvdqueue.c +++ /dev/null @@ -1,172 +0,0 @@ -#include -#include - -#include "__dvd.h" - -static struct { - /* 0x00 */ DVDCommandBlock* next; - /* 0x04 */ DVDCommandBlock* prev; -} WaitingQueue[4]; - -// prototypes -static DVDCommandBlock* PopWaitingQueuePrio(s32 prio); - -void __DVDClearWaitingQueue(void) { - u32 i; - DVDCommandBlock* q; - - for(i = 0; i < 4; i++) { - q = (DVDCommandBlock*)&WaitingQueue[i].next; - q->next = q; - q->prev = q; - } -} - -int __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) { - BOOL enabled = OSDisableInterrupts(); - DVDCommandBlock* q = (DVDCommandBlock*)&WaitingQueue[prio]; - - q->prev->next = block; - block->prev = q->prev; - block->next = q; - q->prev = block; - OSRestoreInterrupts(enabled); - return 1; -} - -static DVDCommandBlock* PopWaitingQueuePrio(s32 prio) { - DVDCommandBlock* tmp; - BOOL enabled; - DVDCommandBlock* q; - - enabled = OSDisableInterrupts(); - q = (DVDCommandBlock*)&WaitingQueue[prio]; - ASSERTLINE(87, q->next != q); - - tmp = q->next; - q->next = tmp->next; - tmp->next->prev = q; - OSRestoreInterrupts(enabled); - tmp->next = 0; - tmp->prev = 0; - return tmp; -} - -DVDCommandBlock* __DVDPopWaitingQueue(void) { - u32 i; - BOOL enabled; - DVDCommandBlock* q; - - enabled = OSDisableInterrupts(); - for (i = 0; i < 4; i++) { - q = (DVDCommandBlock*)&WaitingQueue[i]; - if (q->next != q) { - OSRestoreInterrupts(enabled); - return PopWaitingQueuePrio(i); - } - } - - OSRestoreInterrupts(enabled); - return NULL; -} - -int __DVDCheckWaitingQueue(void) { - u32 i; - BOOL enabled; - DVDCommandBlock* q; - - enabled = OSDisableInterrupts(); - for (i = 0; i < 4; i++) { - q = (DVDCommandBlock*)&WaitingQueue[i]; - if (q->next != q) { - OSRestoreInterrupts(enabled); - return 1; - } - } - - OSRestoreInterrupts(enabled); - return 0; -} - -int __DVDDequeueWaitingQueue(DVDCommandBlock* block) { - BOOL enabled; - DVDCommandBlock* prev; - DVDCommandBlock* next; - - enabled = OSDisableInterrupts(); - prev = block->prev; - next = block->next; - if (prev == NULL || next == NULL) { - OSRestoreInterrupts(enabled); - return 0; - } - prev->next = next; - next->prev = prev; - OSRestoreInterrupts(enabled); - return 1; -} - -int __DVDIsBlockInWaitingQueue(DVDCommandBlock* block) { - u32 i; - DVDCommandBlock* start; - DVDCommandBlock* q; - - for (i = 0; i < 4; i++) { - start = (DVDCommandBlock*)&WaitingQueue[i]; - if (start->next == start) { - continue; - } - - for (q = start->next; q != start; q = q->next) { - if (q == block) { - return 1; - } - } - } - - return 0; -} - -static char* CommandNames[16] = { - "", - "READ", - "SEEK", - "CHANGE_DISK", - "BSREAD", - "READID", - "INITSTREAM", - "CANCELSTREAM", - "STOP_STREAM_AT_END", - "REQUEST_AUDIO_ERROR", - "REQUEST_PLAY_ADDR", - "REQUEST_START_ADDR", - "REQUEST_LENGTH", - "AUDIO_BUFFER_CONFIG", - "INQUIRY", - "BS_CHANGE_DISK", -}; - -void DVDDumpWaitingQueue(void) { - u32 i; - DVDCommandBlock* start; - DVDCommandBlock* q; - - OSReport("==== DVD Waiting Queue Status ====\n"); - for (i = 0; i < 4; i++) { - OSReport("< Queue #%d > ", i); - start = (DVDCommandBlock*)&WaitingQueue[i]; - if (start->next == start) { - OSReport("None\n"); - } else { - OSReport("\n"); - for (q = start->next; q != start; q = q->next) { - OSReport("0x%08x: Command: %s ", q, CommandNames[q->command]); - if (q->command == 1) { - OSReport("Disk offset: %d, Length: %d, Addr: 0x%08x\n", q->offset, q->length, q->addr); - } else { - OSReport("\n"); - } - } - } - } -} diff --git a/src/dolphin/dvd/fstload.c b/src/dolphin/dvd/fstload.c deleted file mode 100644 index 555517d..0000000 --- a/src/dolphin/dvd/fstload.c +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include - -#include "__dvd.h" - -static u8 bb2Buf[63]; - -static u32 status; -static DVDBB2* bb2; -static DVDDiskID* idTmp; - -// prototypes -static void cb(s32 result, DVDCommandBlock* block); - -static void cb(s32 result, DVDCommandBlock* block) { - if (result > 0) { - switch(status) { - case 0: - status = 1; - DVDReadAbsAsyncForBS(block, bb2, 0x20, 0x420, cb); - return; - case 1: - status = 2; - DVDReadAbsAsyncForBS(block, bb2->FSTAddress, (bb2->FSTLength + 0x1F) & 0xFFFFFFE0, bb2->FSTPosition, cb); - default: - return; - } - } - - if (result == -1) { - return; - } else if (result == -4) { - status = 0; - DVDReset(); - DVDReadDiskID(block, idTmp, cb); - } -} - -void __fstLoad(void) { - OSBootInfo* bootInfo; - DVDDiskID* id; - u8 idTmpBuf[63]; - s32 state; - void* arenaHi; - static DVDCommandBlock block; - - arenaHi = OSGetArenaHi(); - bootInfo = (void*)OSPhysicalToCached(0); - idTmp = (void*)OSRoundUp32B(idTmpBuf); - bb2 = (void*)OSRoundUp32B(bb2Buf); - - DVDReset(); - DVDReadDiskID(&block, idTmp, cb); - - while (1) { - state = DVDGetDriveStatus(); - if (state == 0) { - break; - } - - // weird switch that seemingly wont do anything but break out of its own switch. What was this for? Early DVD development pre-hardware? - switch(state) { - case DVD_STATE_FATAL_ERROR: break; - case DVD_STATE_BUSY: break; - case DVD_STATE_WAITING: break; - case DVD_STATE_COVER_CLOSED: break; - case DVD_STATE_NO_DISK: break; - case DVD_STATE_COVER_OPEN: break; - case DVD_STATE_MOTOR_STOPPED: break; - } - } - - bootInfo->FSTLocation = (void*)bb2->FSTAddress; - bootInfo->FSTMaxLength = bb2->FSTMaxLength; - id = &bootInfo->DVDDiskID; - memcpy(id, idTmp, 0x20); - OSReport("\n"); - OSReport(" Game Name ... %c%c%c%c\n", id->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) ? "OFF" : "ON"); - OSReport("\n"); - OSSetArenaHi(bb2->FSTAddress); -} diff --git a/src/dolphin/exi/EXIAd16.c b/src/dolphin/exi/EXIAd16.c deleted file mode 100644 index 668dcaa..0000000 --- a/src/dolphin/exi/EXIAd16.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include - -static BOOL Initialized; - -int AD16Init(void) { - int err; - u32 cmd; - u32 id; - - if (Initialized) { - return 1; - } - - if (!EXILock(2, 0, NULL)) { - return 0; - } - - if (!EXISelect(2, 0, EXI_FREQ_1M)) { - EXIUnlock(2); - return 0; - } - - cmd = 0; - err = 0; - err |= !EXIImm(2, &cmd, 2, EXI_WRITE, NULL); - err |= !EXISync(2); - err |= !EXIImm(2, &id, 4, EXI_READ, NULL); - err |= !EXISync(2); - err |= !EXIDeselect(2); - - EXIUnlock(2); - if (err != 0 || (id - 0x04120000) != 0) { - return 0; - } - - Initialized = TRUE; - return 1; -} - -int AD16WriteReg(u32 word) { - int err; - u32 cmd; - - if (!Initialized || !EXILock(2, 0, NULL)) { - return 0; - } - - if (!EXISelect(2, 0, EXI_FREQ_8M)) { - EXIUnlock(2); - return 0; - } - - cmd = 0xA0000000; - err = 0; - err |= !EXIImm(2, &cmd, 1, EXI_WRITE, NULL); - err |= !EXISync(2); - err |= !EXIImm(2, &word, 4, EXI_WRITE, NULL); - err |= !EXISync(2); - err |= !EXIDeselect(2); - - EXIUnlock(2); - if (err != 0) { - return 0; - } - - return 1; -} - -int AD16ReadReg(u32* word) { - int err; - u32 cmd; - - if (!Initialized || !EXILock(2, 0, NULL)) { - return 0; - } - - if (!EXISelect(2, 0, EXI_FREQ_8M)) { - EXIUnlock(2); - return 0; - } - - cmd = 0xA2000000; - err = 0; - err |= !EXIImm(2, &cmd, 1, EXI_WRITE, NULL); - err |= !EXISync(2); - err |= !EXIImm(2, word, 4, EXI_READ, NULL); - err |= !EXISync(2); - err |= !EXIDeselect(2); - - EXIUnlock(2); - if (err != 0) { - return 0; - } - - return 1; -} - -BOOL AD16Probe(void) { - return Initialized; -} diff --git a/src/dolphin/exi/EXIBios.c b/src/dolphin/exi/EXIBios.c deleted file mode 100644 index 4f4465b..0000000 --- a/src/dolphin/exi/EXIBios.c +++ /dev/null @@ -1,870 +0,0 @@ -#include - -#define REG_MAX 5 -#define REG(chan, idx) (__EXIRegs[((chan) * REG_MAX) + (idx)]) - -#define STATE_IDLE 0 -#define STATE_DMA 1 -#define STATE_IMM 2 -#define STATE_BUSY 3 -#define STATE_SELECTED 4 -#define STATE_ATTACHED 8 -#define STATE_LOCKED 16 - -#define MAX_CHAN 3 - -#define MAX_IMM 4 -#define MAX_TYPE 3 -#define MAX_DEV 3 -#define MAX_FREQ 6 - -#define EXI_0LENGTH_EXILENGTH_MASK 0x03FFFFE0 - -#if DEBUG -const char * __EXIVersion = "<< Dolphin SDK - EXI\tdebug build: Apr 5 2004 03:55:29 (0x2301) >>"; -#else -const char * __EXIVersion = "<< Dolphin SDK - EXI\trelease build: Apr 5 2004 04:14:14 (0x2301) >>"; -#endif - -static EXIControl Ecb[3]; -static u32 IDSerialPort1; - -// external functions -extern void __OSEnableBarnacle(s32 chan, u32 dev); - -// prototypes -u32 EXIClearInterrupts(s32 chan, int exi, int tc, int ext); -static int __EXIProbe(s32 chan); - -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; - u8* buf; - u32 data; - int i; - int len; - - exi = &Ecb[chan]; - ASSERTLINE(366, 0 <= chan && chan < MAX_CHAN); - - if (exi->state & STATE_BUSY) { - if (exi->state & STATE_IMM) { - if ((len = exi->immLen) != 0) { - buf = exi->immBuf; - data = __EXIRegs[(chan * 5) + 4]; - for(i = 0; i < len; i++) { - *buf++ = data >> ((3 - i) * 8); - } - } - } - exi->state &= ~STATE_BUSY; - } -} - -int EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { - EXIControl* exi; - BOOL enabled; - u32 data; - int i; - - exi = &Ecb[chan]; - ASSERTLINE(404, exi->state & STATE_SELECTED); - ASSERTLINE(405, 0 <= chan && chan < MAX_CHAN); - ASSERTLINE(406, 0 < len && len <= MAX_IMM); - ASSERTLINE(407, type < MAX_TYPE); - enabled = OSDisableInterrupts(); - - if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) { - OSRestoreInterrupts(enabled); - return 0; - } - - exi->tcCallback = callback; - if (exi->tcCallback) { - EXIClearInterrupts(chan, 0, 1, 0); - __OSUnmaskInterrupts(0x200000U >> (chan * 3)); - } - - exi->state |= STATE_IMM; - if (type != 0) { - data = 0; - for(i = 0; i < len; i++) { - data |= ((u8*)buf)[i] << ((3 - i) * 8); - } - __EXIRegs[(chan * 5) + 4] = data; - } - - exi->immBuf = buf; - exi->immLen = (type != 1) ? len : 0; - __EXIRegs[(chan * 5) + 3] = (type << 2) | 1 | ((len - 1) << 4); - OSRestoreInterrupts(enabled); - return 1; -} - -int EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) { - s32 xLen; - - while (len) { - xLen = (len < 4) ? len : 4; - if (EXIImm(chan, buf, xLen, mode, 0) == 0) { - return 0; - } - if (EXISync(chan) == 0) { - return 0; - } - ((u8*)buf) += xLen; - len -= xLen; - } - - return 1; -} - -int EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { - EXIControl* exi; - BOOL enabled; - - exi = &Ecb[chan]; - - ASSERTLINE(509, exi->state & STATE_SELECTED); - ASSERTLINE(510, OFFSET(buf, 32) == 0); - ASSERTLINE(511, 0 < len && OFFSET(len, 32) == 0); - ASSERTLINE(513, ((u32) len & ~EXI_0LENGTH_EXILENGTH_MASK) == 0); - ASSERTLINE(515, type == EXI_READ || type == EXI_WRITE); - - enabled = OSDisableInterrupts(); - if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) { - OSRestoreInterrupts(enabled); - return 0; - } - - exi->tcCallback = callback; - if ((u32)exi->tcCallback) { - EXIClearInterrupts(chan, 0, 1, 0); - __OSUnmaskInterrupts(0x200000U >> (chan * 3)); - } - - exi->state |= STATE_DMA; - __EXIRegs[(chan * 5) + 1] = (u32)buf & EXI_0LENGTH_EXILENGTH_MASK; - __EXIRegs[(chan * 5) + 2] = len; - __EXIRegs[(chan * 5) + 3] = (type * 4) | 3; - - OSRestoreInterrupts(enabled); - return 1; -} - -int EXISync(s32 chan) { - EXIControl* exi; - int rc; - BOOL enabled; - - exi = &Ecb[chan]; - rc = 0; - ASSERTLINE(565, 0 <= chan && chan < MAX_CHAN); - - while ((exi->state & STATE_SELECTED)) { - if (!(__EXIRegs[(chan * 5) + 3] & 1)) { - enabled = OSDisableInterrupts(); - if (exi->state & STATE_SELECTED) { - CompleteTransfer(chan); - if (__OSGetDIConfig() != 0xFF || (OSGetConsoleType() & 0xf0000000) == 0x20000000 || exi->immLen != 4 || (__EXIRegs[chan * 5] & 0x70) || (__EXIRegs[(chan * 5) + 4] != 0x01010000 && __EXIRegs[(chan * 5) + 4] != 0x05070000 && __EXIRegs[(chan * 5) + 4] != 0x04220001) || __OSDeviceCode == 0x8200) { - rc = 1; - } - } - OSRestoreInterrupts(enabled); - break; - } - } - - ASSERTLINE(593, !(exi->state & STATE_BUSY)); - return rc; -} - -u32 EXIClearInterrupts(s32 chan, int exi, int tc, int ext) { - u32 cpr; - u32 prev; - - ASSERTLINE(614, 0 <= chan && chan < MAX_CHAN); - - cpr = prev = __EXIRegs[(chan * 5)]; - prev &= 0x7F5; - - if (exi != 0) { - prev |= 2; - } - - if (tc != 0) { - prev |= 8; - } - - if (ext != 0) { - prev |= 0x800; - } - - __EXIRegs[(chan * 5)] = prev; - return cpr; -} - -EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) { - EXIControl* exi; - EXICallback prev; - BOOL enabled; - - exi = &Ecb[chan]; - ASSERTLINE(648, 0 <= chan && chan < MAX_CHAN); - enabled = OSDisableInterrupts(); - - prev = exi->exiCallback; - exi->exiCallback = exiCallback; - if (chan != 2) { - SetExiInterruptMask(chan, exi); - } else { - SetExiInterruptMask(0, &Ecb[0]); - } - - OSRestoreInterrupts(enabled); - return prev; -} - -void EXIProbeReset() { - __gUnknown800030C0[0] = __gUnknown800030C0[1] = 0; - Ecb[0].idTime = Ecb[1].idTime = 0; - __EXIProbe(0); - __EXIProbe(1); -} - -static int __EXIProbe(s32 chan) { - EXIControl* exi; - BOOL enabled; - int rc; - u32 cpr; - s32 t; - - exi = &Ecb[chan]; - ASSERTLINE(703, 0 <= chan && chan < MAX_CHAN); - if (chan == 2) { - return 1; - } - - rc = 1; - enabled = OSDisableInterrupts(); - cpr = __EXIRegs[(chan * 5)]; - - if (!(exi->state & STATE_ATTACHED)) { - if (cpr & 0x800) { - EXIClearInterrupts(chan, 0, 0, 1); - __gUnknown800030C0[chan] = exi->idTime = 0; - } - - if (cpr & 0x1000) { - t = ((s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1); - - if (__gUnknown800030C0[chan] == 0) { - __gUnknown800030C0[chan] = t; - } - - if (t - (s32)__gUnknown800030C0[chan] < 3) { - rc = 0; - } - } else { - __gUnknown800030C0[chan] = exi->idTime = 0; - rc = 0; - } - } else if(!(cpr & 0x1000) || (cpr & 0x800)) { - __gUnknown800030C0[chan] = exi->idTime = 0; - rc = 0; - } - - OSRestoreInterrupts(enabled); - return rc; -} - -int EXIProbe(s32 chan) { - EXIControl* exi = &Ecb[chan]; - int rc; - u32 id; - - rc = __EXIProbe(chan); - if (rc && !exi->idTime) { - rc = EXIGetID(chan, 0, &id) ? 1 : 0; - } - - return rc; -} - -s32 EXIProbeEx(s32 chan) { - if (EXIProbe(chan)) { - return 1; - } - - if (__gUnknown800030C0[chan]) { - return 0; - } - - return -1; -} - -static int __EXIAttach(s32 chan, EXICallback extCallback) { - EXIControl* exi; - BOOL enabled; - - exi = &Ecb[chan]; - ASSERTLINE(808, 0 <= chan && chan < 2); - enabled = OSDisableInterrupts(); - - if ((exi->state & STATE_ATTACHED) || !__EXIProbe(chan)) { - OSRestoreInterrupts(enabled); - return 0; - } - - EXIClearInterrupts(chan, 1, 0, 0); - exi->extCallback = extCallback; - __OSUnmaskInterrupts(0x100000U >> (chan * 3)); - exi->state |= STATE_ATTACHED; - - OSRestoreInterrupts(enabled); - return 1; -} - -int EXIAttach(s32 chan, EXICallback extCallback) { - EXIControl* exi; - BOOL enabled; - int rc; - - exi = &Ecb[chan]; - ASSERTLINE(834, 0 <= chan && chan < 2); - - EXIProbe(chan); - enabled = OSDisableInterrupts(); - if (exi->idTime == 0) { - OSRestoreInterrupts(enabled); - return 0; - } - - rc = __EXIAttach(chan, extCallback); - OSRestoreInterrupts(enabled); - return rc; -} - -int EXIDetach(s32 chan) { - EXIControl* exi; - BOOL enabled; - - exi = &Ecb[chan]; - ASSERTLINE(868, 0 <= chan && chan < 2); - enabled = OSDisableInterrupts(); - - if (!(exi->state & STATE_ATTACHED)) { - OSRestoreInterrupts(enabled); - return 1; - } - - if ((exi->state & STATE_LOCKED) && (exi->dev == 0)) { - OSRestoreInterrupts(enabled); - return 0; - } - - exi->state &= ~STATE_ATTACHED; - __OSMaskInterrupts(0x500000U >> (chan * 3)); - - OSRestoreInterrupts(enabled); - return 1; -} - -int EXISelectSD(s32 chan, u32 dev, u32 freq) { - EXIControl* exi; - u32 cpr; - BOOL enabled; - - exi = &Ecb[chan]; - - ASSERTLINE(908, 0 <= chan && chan < MAX_CHAN); - ASSERTLINE(909, chan == 0 && dev < MAX_DEV || dev == 0); - ASSERTLINE(910, freq < MAX_FREQ); - ASSERTLINE(911, !(exi->state & STATE_SELECTED)); - - enabled = OSDisableInterrupts(); - if ((exi->state & STATE_SELECTED) || ((chan != 2) && (((dev == 0) && !(exi->state & STATE_ATTACHED) && (EXIProbe(chan) == 0)) || !(exi->state & STATE_LOCKED) || (exi->dev != dev)))) { - OSRestoreInterrupts(enabled); - return 0; - } - - exi->state |= STATE_SELECTED; - cpr = __EXIRegs[(chan * 5)]; - cpr &= 0x405; - cpr |= freq * 0x10; - __EXIRegs[(chan * 5)] = cpr; - - if (exi->state & STATE_ATTACHED) { - switch (chan) { - case 0: - __OSMaskInterrupts(0x100000U); - break; - case 1: - __OSMaskInterrupts(0x20000U); - break; - } - } - - OSRestoreInterrupts(enabled); - return 1; -} - -int EXISelect(s32 chan, u32 dev, u32 freq) { - EXIControl* exi; - u32 cpr; - BOOL enabled; - - exi = &Ecb[chan]; - - ASSERTLINE(966, 0 <= chan && chan < MAX_CHAN); - ASSERTLINE(967, chan == 0 && dev < MAX_DEV || dev == 0); - ASSERTLINE(968, freq < MAX_FREQ); - ASSERTLINE(969, !(exi->state & STATE_SELECTED)); - - enabled = OSDisableInterrupts(); - if ((exi->state & STATE_SELECTED) || ((chan != 2) && (((dev == 0) && !(exi->state & STATE_ATTACHED) && (__EXIProbe(chan) == 0)) || !(exi->state & STATE_LOCKED) || (exi->dev != dev)))) { - OSRestoreInterrupts(enabled); - return 0; - } - - exi->state |= STATE_SELECTED; - cpr = __EXIRegs[(chan * 5)]; - cpr &= 0x405; - cpr |= (((1 << dev) << 7) | (freq * 0x10)); - __EXIRegs[(chan * 5)] = cpr; - - if (exi->state & STATE_ATTACHED) { - switch (chan) { - case 0: - __OSMaskInterrupts(0x100000U); - break; - case 1: - __OSMaskInterrupts(0x20000U); - break; - } - } - - OSRestoreInterrupts(enabled); - return 1; -} - -int EXIDeselect(s32 chan) { - EXIControl* exi; - u32 cpr; - BOOL enabled; - - exi = &Ecb[chan]; - ASSERTLINE(1020, 0 <= chan && chan < MAX_CHAN); - enabled = OSDisableInterrupts(); - - if (!(exi->state & STATE_SELECTED)) { - OSRestoreInterrupts(enabled); - return 0; - } - - exi->state &= ~STATE_SELECTED; - cpr = __EXIRegs[(chan * 5)]; - __EXIRegs[(chan * 5)] = cpr & 0x405; - - if (exi->state & STATE_ATTACHED) { - switch (chan) { - case 0: - __OSUnmaskInterrupts(0x100000U); - break; - case 1: - __OSUnmaskInterrupts(0x20000U); - break; - } - } - - OSRestoreInterrupts(enabled); - - if ((chan != 2) && (cpr & 0x80)) { - if (__EXIProbe(chan) != 0) { - return 1; - } - return 0; - } - - return 1; -} - -static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { - s32 chan; - EXIControl* exi; - EXICallback callback; - - chan = (interrupt - 9) / 3; - - ASSERTLINE(1071, 0 <= chan && chan < MAX_CHAN); - exi = &Ecb[chan]; - EXIClearInterrupts(chan, 1, 0, 0); - - 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) { - s32 chan; - EXIControl* exi; - EXICallback callback; - - chan = (interrupt - 10) / 3; - - ASSERTLINE(1107, 0 <= chan && chan < MAX_CHAN); - exi = &Ecb[chan]; - __OSMaskInterrupts(0x80000000U >> interrupt); - EXIClearInterrupts(chan, 0, 1, 0); - - callback = exi->tcCallback; - if (callback) { - OSContext exceptionContext; - - exi->tcCallback = NULL; - 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 - 11) / 3; - - ASSERTLINE(1147, 0 <= chan && chan < 2); - __OSMaskInterrupts(0x500000U >> (chan * 3)); - exi = &Ecb[chan]; - callback = exi->extCallback; - exi->state &= ~STATE_ATTACHED; - - if (callback) { - OSContext exceptionContext; - - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - exi->extCallback = NULL; - callback(chan, context); - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); - } -} - -void EXIInit() { - u32 id; - - while (((REG(0, 3) & 1) == 1) || ((REG(1, 3) & 1) == 1) || ((REG(2, 3) & 1) == 1)) {} - - __OSMaskInterrupts(0x7F8000U); - __EXIRegs[0] = 0; - __EXIRegs[5] = 0; - __EXIRegs[10] = 0; - __EXIRegs[0] = 0x2000; - __OSSetInterruptHandler(9, EXIIntrruptHandler); - __OSSetInterruptHandler(10, TCIntrruptHandler); - __OSSetInterruptHandler(11, EXTIntrruptHandler); - __OSSetInterruptHandler(12, EXIIntrruptHandler); - __OSSetInterruptHandler(13, TCIntrruptHandler); - __OSSetInterruptHandler(14, EXTIntrruptHandler); - __OSSetInterruptHandler(15, EXIIntrruptHandler); - __OSSetInterruptHandler(16, TCIntrruptHandler); - - EXIGetID(0, 2, &IDSerialPort1); - - if (__OSInIPL) { - EXIProbeReset(); - } else if (EXIGetID(0, 0, &id) && id == 0x7010000) { - __OSEnableBarnacle(1, 0); - } else if (EXIGetID(1, 0, &id) && id == 0x7010000) { - __OSEnableBarnacle(0, 2); - } - - OSRegisterVersion(__EXIVersion); -} - -int EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) { - EXIControl* exi; - BOOL enabled; - int i; - - exi = &Ecb[chan]; - ASSERTLINE(1259, 0 <= chan && chan < MAX_CHAN); - ASSERTLINE(1260, chan == 0 && dev < MAX_DEV || dev == 0); - enabled = OSDisableInterrupts(); - - if (exi->state & STATE_LOCKED) { - if (unlockedCallback) { - ASSERTLINE(1266, chan == 0 && exi->items < (MAX_DEV - 1) || exi->items == 0); - for(i = 0; i < exi->items; i++) { - if (exi->queue[i].dev == dev) { - OSRestoreInterrupts(enabled); - return 0; - } - } - exi->queue[exi->items].callback = unlockedCallback; - exi->queue[exi->items].dev = dev; - exi->items++; - } - OSRestoreInterrupts(enabled); - return 0; - } - - ASSERTLINE(1282, exi->items == 0); - exi->state |= STATE_LOCKED; - exi->dev = dev; - SetExiInterruptMask(chan, exi); - OSRestoreInterrupts(enabled); - return 1; -} - -int EXIUnlock(s32 chan) { - EXIControl* exi; - BOOL enabled; - EXICallback unlockedCallback; - - exi = &Ecb[chan]; - ASSERTLINE(1306, 0 <= chan && chan < MAX_CHAN); - enabled = OSDisableInterrupts(); - - if (!(exi->state & STATE_LOCKED)) { - OSRestoreInterrupts(enabled); - return 0; - } - - exi->state &= ~STATE_LOCKED; - SetExiInterruptMask(chan, exi); - if (exi->items > 0) { - unlockedCallback = exi->queue[0].callback; - if (--exi->items > 0) { - memmove(&exi->queue[0], &exi->queue[1], exi->items * 8); - } - unlockedCallback(chan, 0); - } - - OSRestoreInterrupts(enabled); - return 1; -} - -u32 EXIGetState(s32 chan) { - EXIControl* exi; - - exi = &Ecb[chan]; - ASSERTLINE(1343, 0 <= chan && chan < MAX_CHAN); - return 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]; - int err; - u32 cmd; - s32 startTime; - BOOL enabled; - - ASSERTLINE(1380, 0 <= chan && chan < MAX_CHAN); - if (chan == 0 && dev == 2 && IDSerialPort1 != 0) { - *id = IDSerialPort1; - return 1; - } - - if ((chan < 2) && (dev == 0)) { - if ((__EXIProbe(chan) == 0)) { - return 0; - } - - if (exi->idTime == __gUnknown800030C0[chan]) { - *id = exi->id; - return exi->idTime; - } - - if (!__EXIAttach(chan, NULL)) { - return 0; - } - - startTime = __gUnknown800030C0[chan]; - } - - enabled = OSDisableInterrupts(); - - err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? &UnlockedHandler : NULL); - if (err == 0) { - err = !EXISelect(chan, dev, 0); - if (err == 0) { - cmd = 0; - err |= !EXIImm(chan, &cmd, 2, 1, 0); - err |= !EXISync(chan); - err |= !EXIImm(chan, id, 4, 0, 0); - err |= !EXISync(chan); - err |= !EXIDeselect(chan); - } - - EXIUnlock(chan); - } - - OSRestoreInterrupts(enabled); - - if ((chan < 2) && (dev == 0)) { - EXIDetach(chan); - enabled = OSDisableInterrupts(); - err |= __gUnknown800030C0[chan] != startTime; - - if (!err) { - exi->id = *id; - exi->idTime = startTime; - } - - OSRestoreInterrupts(enabled); - - if (err) { - return 0; - } - - return exi->idTime; - } - - if (err) { - return 0; - } - - return 1; -} - -s32 EXIGetType(s32 chan, u32 dev, u32* type) { - u32 _type; - s32 probe; - - probe = EXIGetID(chan, dev, &_type); - - if (!probe) { - return probe; - } - - switch (_type & ~0xFF) { - case 0x04020300: - case EXI_ETHER: - case 0x04020100: - case EXI_MIC: - *type = (_type & ~0xFF); - return probe; - default: - switch (_type & ~0xFFFF) { - case 0x00000000: - if (!(_type & 0x3803)) { - switch (_type & 0xFC) { - case EXI_MEMORY_CARD_59: - case EXI_MEMORY_CARD_123: - case EXI_MEMORY_CARD_251: - case EXI_MEMORY_CARD_507: - case EXI_MEMORY_CARD_1019: - case EXI_MEMORY_CARD_2043: - *type = _type & 0xFC; - return probe; - } - } - break; - case EXI_IS_VIEWER: - *type = EXI_IS_VIEWER; - return probe; - } - - *type = _type; - return probe; - } -} - -char* EXIGetTypeString(u32 type) { - 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 EXI_NPDP_GDEV: - return "GDEV"; - case EXI_MODEM: - return "Modem"; - case EXI_MARLIN: - return "Marlin"; - case EXI_AD16: - return "AD16"; - case EXI_RS232C: - return "RS232C"; - case 0x80000020: - case 0x80000080: - case 0x80000040: - case 0x80000008: - case 0x80000010: - case 0x80000004: - return "Net Card"; - case EXI_ETHER_VIEWER: - return "Artist Ether"; - case 0x4020100: - case 0x4020300: - case EXI_ETHER: - case 0x4220000: - return "Broadband Adapter"; - case EXI_MIC: - return "Mic"; - case EXI_STREAM_HANGER: - return "Stream Hanger"; - case EXI_IS_VIEWER: - return "IS-DOL-VIEWER"; - default: - return "Unknown"; - } -} diff --git a/src/dolphin/exi/EXIUart.c b/src/dolphin/exi/EXIUart.c deleted file mode 100644 index 2d5c868..0000000 --- a/src/dolphin/exi/EXIUart.c +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include -#include "__os.h" - -static s32 Chan; -static u32 Dev; -static u32 Enabled; -static u32 BarnacleEnabled; - -// prototypes -int InitializeUART(void); -int ReadUARTN(void); -int WriteUARTN(void *buf, u32 len); -void __OSEnableBarnacle(s32 chan, u32 dev); - -static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) { - int 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, sizeof(cmd), EXI_WRITE, NULL); - err |= !EXISync(chan); - err |= !EXIImm(chan, revision, sizeof(revision), EXI_READ, NULL); - err |= !EXISync(chan); - err |= !EXIDeselect(chan); - } - - EXIUnlock(chan); - } - - if (chan != 2 && dev == 0) { - EXIDetach(chan); - } - - if (err) { - return FALSE; - } - - if (*revision != 0xFFFFFFFF) { - return TRUE; - } - - return FALSE; -} - -void __OSEnableBarnacle(s32 chan, u32 dev) { - u32 id; - - if (!EXIGetID(chan, dev, &id)) { - return; - } - - switch (id) { - case EXI_MEMORY_CARD_59: - case EXI_MEMORY_CARD_123: - case EXI_MEMORY_CARD_251: - case EXI_MEMORY_CARD_507: - case EXI_USB_ADAPTER: - case EXI_NPDP_GDEV: - case EXI_MODEM: - case 0x03010000: - case 0x04020100: - case EXI_ETHER: - case 0x04020300: - case 0x04220000: - case EXI_RS232C: - case EXI_MIC: - case EXI_AD16: - case EXI_STREAM_HANGER: - case 0x80000004: - case 0x80000008: - case 0x80000010: - case 0x80000020: - case 0xFFFFFFFF: - break; - default: - if (ProbeBarnacle(chan, dev, &id)) { - Chan = chan; - Dev = dev; - Enabled = BarnacleEnabled = 0xA5FF005A; - break; - } - } -} - -int InitializeUART(void) { - if (BarnacleEnabled == 0xA5FF005A) { - return 0; - } - - if ((OSGetConsoleType() & 0x10000000) == 0) { - Enabled = 0; - return 2; - } - - Chan = 0; - Dev = 1; - Enabled = 0xA5FF005A; - return 0; -} - -int ReadUARTN(void) { - return 4; -} - -static int QueueLength(void) { - u32 cmd; - - if (EXISelect(Chan, Dev, 3) == 0) { - return -1; - } - - cmd = 0x20010000; - EXIImm(Chan, &cmd, sizeof(cmd), EXI_WRITE, 0); - EXISync(Chan); - EXIImm(Chan, &cmd, 1, EXI_READ, 0); - EXISync(Chan); - EXIDeselect(Chan); - return 0x10 - (cmd >> 0x18); -} - -int WriteUARTN(void *buf, u32 len) { - u32 cmd; - s32 xLen; - int qLen; - char* ptr; - int locked; - int error; - - if ((Enabled - 0xA5FF0000) != 0x5A) { - return 2; - } - - locked = EXILock(Chan, Dev, 0); - if (locked == 0) { - return 0; - } else { - ptr = (char*)buf; - } - - while ((u32)ptr - (u32)buf < len) { - if (*(s8*)ptr == 0xA) { - *ptr = 0xD; - } - ptr++; - } - error = 0; - cmd = 0xA0010000; - - while (len != 0) { - qLen = QueueLength(); - if (qLen < 0) { - error = 3; - break; - } - - if ((qLen >= 0xC) || (qLen >= len)) { - if (EXISelect(Chan, Dev, EXI_FREQ_8M) == 0) { - error = 3; - break; - } - - EXIImm(Chan, &cmd, sizeof(cmd), EXI_WRITE, 0); - EXISync(Chan); - - while((qLen != 0) && (len != 0)) { - if ((qLen < 4) && (qLen < len)) { - break; - } - - xLen = len < 4 ? (long)len : 4; - - EXIImm(Chan, buf, xLen, EXI_WRITE, 0); - (char*)buf += xLen; - len -= xLen; - qLen -= xLen; - EXISync(Chan); - } - EXIDeselect(Chan); - } - } - - EXIUnlock(Chan); - return error; -} diff --git a/src/dolphin/fileCache/fileCache.c b/src/dolphin/fileCache/fileCache.c deleted file mode 100644 index 36151f4..0000000 --- a/src/dolphin/fileCache/fileCache.c +++ /dev/null @@ -1,145 +0,0 @@ -#include -#include - -DSCache DODisplayCache; -u8 DOCacheInitialized; - -static u8 AllocCacheNode(DSCacheNodePtr* cacheNode, char* name); -static void FreeCacheNode(DSCacheNodePtr* cacheNode); - -DSCacheNodePtr DSAddCacheNode(DSCachePtr cache, char* name, Ptr data, Ptr OSFreeFunc) { - DSCacheNodePtr cacheNode; - - cacheNode = NULL; - if (!AllocCacheNode(&cacheNode, name)) { - return NULL; - } - Strcpy(cacheNode->Name, name); - cacheNode->Data = data; - cacheNode->Free = (void (*)(Ptr *))OSFreeFunc; - cacheNode->ReferenceCount = 0; - DSInsertListObject(&cache->CacheNodeList, NULL, (Ptr)cacheNode); - return cacheNode; -} - -static u8 AllocCacheNode(DSCacheNodePtr* cacheNode, char* name) { - if (*cacheNode) { - FreeCacheNode(cacheNode); - } - - *cacheNode = OSAlloc(sizeof(DSCacheNode)); - if (!*cacheNode) { - return FALSE; - } - - (*cacheNode)->Name = OSAlloc(Strlen(name) + 1); - if (!(*cacheNode)->Name) { - return FALSE; - } - - return TRUE; -} - -void DSEmptyCache(DSCachePtr cache) { - DSCacheNodePtr cursor; - DSCacheNodePtr cacheNode; - - cursor = (DSCacheNodePtr)cache->CacheNodeList.Head; - while (cursor) { - cacheNode = cursor; - cursor = (DSCacheNodePtr)cursor->Link.Next; - DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); - FreeCacheNode(&cacheNode); - } -} - -static DSCacheNodePtr FindCacheNode(DSCachePtr cache, char* name, Ptr data) { - DSCacheNodePtr cacheNode; - - cacheNode = (DSCacheNodePtr)cache->CacheNodeList.Head; - if (data) { - while (cacheNode) { - if (data == cacheNode->Data) { - return cacheNode; - } - cacheNode = (DSCacheNodePtr)cacheNode->Link.Next; - } - } else if (name) { - while (cacheNode) { - if (Strcmp(name, cacheNode->Name) == 0) { - return cacheNode; - } - cacheNode = (DSCacheNodePtr)cacheNode->Link.Next; - } - } - return NULL; -} - -Ptr DSGetCacheObj(DSCachePtr cache, char* name) { - DSCacheNodePtr cacheNode; - - cacheNode = FindCacheNode(cache, name, NULL); - if (cacheNode) { - cacheNode->ReferenceCount++; - return cacheNode->Data; - } - return NULL; -} - -static void FreeCacheNode(DSCacheNodePtr* cacheNode) { - if (*cacheNode) { - if ((*cacheNode)->Free) { - (*cacheNode)->Free(&(*cacheNode)->Data); - } - OSFree((*cacheNode)->Name); - OSFree(*cacheNode); - *cacheNode = NULL; - } -} - -void DSInitCache(DSCachePtr cache) { - DSCacheNode cacheNode; - - cache->PurgeFlag = DS_AUTO_PURGE; - DSInitList(&cache->CacheNodeList, (Ptr)&cacheNode, &cacheNode.Link); -} - -void DSPurgeCache(DSCachePtr cache) { - DSCacheNodePtr cursor; - DSCacheNodePtr cacheNode; - - cursor = (DSCacheNodePtr)cache->CacheNodeList.Head; - while (cursor) { - cacheNode = cursor; - cursor = (DSCacheNodePtr)cursor->Link.Next; - if (cacheNode->ReferenceCount == 0) { - DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); - FreeCacheNode(&cacheNode); - } - } -} - -void DSReleaseCacheObj(DSCachePtr cache, Ptr data) { - DSCacheNodePtr cacheNode; - - cacheNode = FindCacheNode(cache, NULL, data); - if (cacheNode) { - if (cacheNode->ReferenceCount != 0) { - cacheNode->ReferenceCount--; - } - - if (cacheNode->ReferenceCount == 0 && cache->PurgeFlag == DS_AUTO_PURGE) { - DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); - FreeCacheNode(&cacheNode); - } - } -} - -void DSSetCachePurgeFlag(DSCachePtr cache, u8 purgeFlag) { - cache->PurgeFlag = purgeFlag; -} - -void CSHInitDisplayCache(void) { - DSInitCache(&DODisplayCache); - DOCacheInitialized = TRUE; -} diff --git a/src/dolphin/gd/GDBase.c b/src/dolphin/gd/GDBase.c deleted file mode 100644 index a21e0d6..0000000 --- a/src/dolphin/gd/GDBase.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include - -GDLObj* __GDCurrentDL = NULL; -static GDOverflowCb overflowcb = NULL; - -void GDInitGDLObj(GDLObj* dl, void* start, u32 length) { - ASSERTMSGLINE(40, !((u32)start & 0x1F), "start must be aligned to 32 bytes"); - ASSERTMSGLINE(41, !((u32)length & 0x1F), "length must be aligned to 32 bytes"); - dl->start = start; - dl->ptr = start; - dl->top = (u8*)start + length; - dl->length = length; -} - -void GDFlushCurrToMem(void) { - DCFlushRange(__GDCurrentDL->start, __GDCurrentDL->length); -} - -void GDPadCurr32(void) { - u32 n; - - n = (u32)__GDCurrentDL->ptr & 0x1F; - if (n != 0) { - for (; n < 32; n = n + 1) { - __GDWrite(0); - } - } -} - -void GDOverflowed(void) { - if (overflowcb) { - (*overflowcb)(); - } else { - ASSERTMSGLINE(77, 0, "GDWrite: display list overflowed"); - } -} - -void GDSetOverflowCallback(GDOverflowCb callback) { - overflowcb = callback; -} - -GDOverflowCb GDGetOverflowCallback(void) { - return overflowcb; -} diff --git a/src/dolphin/gd/GDFile.c b/src/dolphin/gd/GDFile.c deleted file mode 100644 index 47ec3af..0000000 --- a/src/dolphin/gd/GDFile.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include - -#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) - -s32 GDReadDLFile(const char* fName, u32* numDLs, u32* numPLs, GDGList** DLDescArray, GDGList** PLDescArray) { - DVDFileInfo finfo; - u32 length; - u32 i; - u8* buf; - GDFileHeader* hdr; - - *numDLs = *numPLs = 0; - *DLDescArray = *PLDescArray = NULL; - - if (!DVDOpen(fName, &finfo)) { - OSReport("Can't open file %s\n", fName); - return -3; - } - - length = finfo.length; - - if (NULL == (buf = OSAlloc(ROUND(length, 0x20)))) { - OSReport("Alloc failed\n"); - DVDClose(&finfo); - return -5; - } - - if (DVDReadPrio(&finfo, buf, ROUND(length, 0x20), 0, 2) != ROUND(length, 0x20)) { - OSReport("Error occurred when reading %s\n", fName); - DVDClose(&finfo); - OSFree(buf); - return -2; - } - - DVDClose(&finfo); - - hdr = (GDFileHeader*)buf; - - if (hdr->versionNumber != GD_FILE_VERSION_NUMBER) { - OSReport("Bad version number for GDL file %s\n", fName); - OSFree(buf); - return -4; - } - - *numDLs = hdr->numDLs; - *numPLs = hdr->numPLs; - - // Loaded pointers are relative to disc start, remap - // them to be relative to RAM start - *DLDescArray = (GDGList*)((u32)hdr->DLDescArray + (u32)hdr); - *PLDescArray = (GDGList*)((u32)hdr->PLDescArray + (u32)hdr); - - // And internal pointers too - for (i = 0; i < *numDLs; ++i) { - (*DLDescArray)[i].ptr = (void*)((u32)hdr + (u32)(*DLDescArray)[i].ptr); - } - - for (i = 0; i < *numPLs; ++i) { - (*PLDescArray)[i].ptr = (void*)((u32)hdr + (u32)(*PLDescArray)[i].ptr); - } - - return 0; -} diff --git a/src/dolphin/gd/GDGeometry.c b/src/dolphin/gd/GDGeometry.c deleted file mode 100644 index 967acb7..0000000 --- a/src/dolphin/gd/GDGeometry.c +++ /dev/null @@ -1,430 +0,0 @@ -#include -#include - -void GDSetVtxDescv(const GXVtxDescList* attrPtr) { - u32 nnorms = 0; - u32 ncols = 0; - u32 ntexs = 0; - u32 pnMtxIdx = GX_NONE; - u32 txMtxIdxMask = 0; - u32 posn = GX_DIRECT; - u32 norm = GX_NONE; - u32 col0 = GX_NONE; - u32 col1 = GX_NONE; - u32 tex0 = GX_NONE; - u32 tex1 = GX_NONE; - u32 tex2 = GX_NONE; - u32 tex3 = GX_NONE; - u32 tex4 = GX_NONE; - u32 tex5 = GX_NONE; - u32 tex6 = GX_NONE; - u32 tex7 = GX_NONE; - - for (; attrPtr->attr != GX_VA_NULL; ++attrPtr) { - ASSERTMSGLINE(91, attrPtr->attr >= GX_VA_PNMTXIDX && attrPtr->attr <= GX_VA_MAX_ATTR, "GDSetVtxDescv: invalid attribute"); - ASSERTMSGLINE(95, attrPtr->type >= GX_NONE && attrPtr->type <= GX_INDEX16, "GDSetVtxDescv: invalid type"); - - ASSERTMSGLINE(101, attrPtr->attr >= GX_VA_PNMTXIDX && attrPtr->attr <= GX_VA_TEX7MTXIDX ? (attrPtr->type == 0 || attrPtr->type == 1) : TRUE, "GDSetVtxDescv: invalid type for given attribute"); - - switch (attrPtr->attr) { - case GX_VA_PNMTXIDX: - pnMtxIdx = attrPtr->type; - break; - case GX_VA_TEX0MTXIDX: - txMtxIdxMask = (txMtxIdxMask & ~0x1) | (attrPtr->type << 0); - break; - case GX_VA_TEX1MTXIDX: - txMtxIdxMask = (txMtxIdxMask & ~0x2) | (attrPtr->type << 1); - break; - case GX_VA_TEX2MTXIDX: - txMtxIdxMask = (txMtxIdxMask & ~0x4) | (attrPtr->type << 2); - break; - case GX_VA_TEX3MTXIDX: - txMtxIdxMask = (txMtxIdxMask & ~0x8) | (attrPtr->type << 3); - break; - case GX_VA_TEX4MTXIDX: - txMtxIdxMask = (txMtxIdxMask & ~0x10) | (attrPtr->type << 4); - break; - case GX_VA_TEX5MTXIDX: - txMtxIdxMask = (txMtxIdxMask & ~0x20) | (attrPtr->type << 5); - break; - case GX_VA_TEX6MTXIDX: - txMtxIdxMask = (txMtxIdxMask & ~0x40) | (attrPtr->type << 6); - break; - case GX_VA_TEX7MTXIDX: - txMtxIdxMask = (txMtxIdxMask & ~0x80) | (attrPtr->type << 7); - break; - case GX_VA_POS: - posn = attrPtr->type; - break; - case GX_VA_NRM: - if (attrPtr->type != GX_NONE) { - norm = attrPtr->type; - nnorms = 1; - } - break; - case GX_VA_NBT: - if (attrPtr->type != GX_NONE) { - norm = attrPtr->type; - nnorms = 2; - } - break; - case GX_VA_CLR0: - col0 = attrPtr->type; - ncols += (col0 != GX_NONE); - break; - case GX_VA_CLR1: - col1 = attrPtr->type; - ncols += (col1 != GX_NONE); - break; - case GX_VA_TEX0: - tex0 = attrPtr->type; - ntexs += (tex0 != GX_NONE); - break; - case GX_VA_TEX1: - tex1 = attrPtr->type; - ntexs += (tex1 != GX_NONE); - break; - case GX_VA_TEX2: - tex2 = attrPtr->type; - ntexs += (tex2 != GX_NONE); - break; - case GX_VA_TEX3: - tex3 = attrPtr->type; - ntexs += (tex3 != GX_NONE); - break; - case GX_VA_TEX4: - tex4 = attrPtr->type; - ntexs += (tex4 != GX_NONE); - break; - case GX_VA_TEX5: - tex5 = attrPtr->type; - ntexs += (tex5 != GX_NONE); - break; - case GX_VA_TEX6: - tex6 = attrPtr->type; - ntexs += (tex6 != GX_NONE); - break; - case GX_VA_TEX7: - tex7 = attrPtr->type; - ntexs += (tex7 != GX_NONE); - break; - } - } - - GDWriteCPCmd(CP_REG_VCD_LO_ID, CP_REG_VCD_LO(pnMtxIdx, txMtxIdxMask, posn, norm, col0, col1)); - GDWriteCPCmd(CP_REG_VCD_HI_ID, CP_REG_VCD_HI(tex0, tex1, tex2, tex3, tex4, tex5, tex6, tex7)); - GDWriteXFCmd(XF_REG_INVERTEXSPEC_ID, XF_REG_INVTXSPEC(ncols, nnorms, ntexs)); -} - -void GDSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list) { - u32 posCnt = GX_POS_XYZ; - u32 posType = GX_F32; - u32 posFrac = 0; - - u32 nrmCnt = GX_NRM_XYZ; - u32 nrmType = GX_F32; - u32 nrmIdx3 = 0; - - u32 c0Cnt = GX_CLR_RGBA; - u32 c0Type = GX_RGBA8; - - u32 c1Cnt = GX_CLR_RGBA; - u32 c1Type = GX_RGBA8; - - u32 tx0Cnt = GX_TEX_ST; - u32 tx0Type = GX_F32; - u32 tx0Frac = 0; - - u32 tx1Cnt = GX_TEX_ST; - u32 tx1Type = GX_F32; - u32 tx1Frac = 0; - - u32 tx2Cnt = GX_TEX_ST; - u32 tx2Type = GX_F32; - u32 tx2Frac = 0; - - u32 tx3Cnt = GX_TEX_ST; - u32 tx3Type = GX_F32; - u32 tx3Frac = 0; - - u32 tx4Cnt = GX_TEX_ST; - u32 tx4Type = GX_F32; - u32 tx4Frac = 0; - - u32 tx5Cnt = GX_TEX_ST; - u32 tx5Type = GX_F32; - u32 tx5Frac = 0; - - u32 tx6Cnt = GX_TEX_ST; - u32 tx6Type = GX_F32; - u32 tx6Frac = 0; - - u32 tx7Cnt = GX_TEX_ST; - u32 tx7Type = GX_F32; - u32 tx7Frac = 0; - - ASSERTMSGLINE(221, vtxfmt < GX_MAX_VTXFMT, "GDSetVtxAttrFmtv: invalid vtx fmt"); - - for (; list->attr != GX_VA_NULL; ++list) { - ASSERTMSGLINE(226, list->attr >= GX_VA_POS && list->attr <= GX_VA_TEX7, "GDSetVtxAttrFmtv: invalid attribute"); - ASSERTMSGLINE(227, list->frac < 32, "GDSetVtxAttrFmtv: invalid frac value"); - - switch (list->attr) { - case GX_VA_POS: - posCnt = list->cnt; - posType = list->type; - posFrac = list->frac; - break; - case GX_VA_NRM: - case GX_VA_NBT: - nrmType = list->type; - if (list->cnt == GX_NRM_NBT3) { - nrmCnt = GX_NRM_NBT; - nrmIdx3 = 1; - } else { - nrmCnt = list->cnt; - nrmIdx3 = 0; - } - break; - case GX_VA_CLR0: - c0Cnt = list->cnt; - c0Type = list->type; - break; - case GX_VA_CLR1: - c1Cnt = list->cnt; - c1Type = list->type; - break; - case GX_VA_TEX0: - tx0Cnt = list->cnt; - tx0Type = list->type; - tx0Frac = list->frac; - break; - case GX_VA_TEX1: - tx1Cnt = list->cnt; - tx1Type = list->type; - tx1Frac = list->frac; - break; - case GX_VA_TEX2: - tx2Cnt = list->cnt; - tx2Type = list->type; - tx2Frac = list->frac; - break; - case GX_VA_TEX3: - tx3Cnt = list->cnt; - tx3Type = list->type; - tx3Frac = list->frac; - break; - case GX_VA_TEX4: - tx4Cnt = list->cnt; - tx4Type = list->type; - tx4Frac = list->frac; - break; - case GX_VA_TEX5: - tx5Cnt = list->cnt; - tx5Type = list->type; - tx5Frac = list->frac; - break; - case GX_VA_TEX6: - tx6Cnt = list->cnt; - tx6Type = list->type; - tx6Frac = list->frac; - break; - case GX_VA_TEX7: - tx7Cnt = list->cnt; - tx7Type = list->type; - tx7Frac = list->frac; - } - } - - GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP0_ID, CP_REG_VAT_GRP0(posCnt, posType, posFrac, nrmCnt, nrmType, c0Cnt, c0Type, c1Cnt, c1Type, tx0Cnt, tx0Type, tx0Frac, 1, nrmIdx3)); - GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP1_ID, CP_REG_VAT_GRP1(tx1Cnt, tx1Type, tx1Frac, tx2Cnt, tx2Type, tx2Frac, tx3Cnt, tx3Type, tx3Frac, tx4Cnt, tx4Type, 1)); - GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP2_ID, CP_REG_VAT_GRP2(tx4Frac, tx5Cnt, tx5Type, tx5Frac, tx6Cnt, tx6Type, tx6Frac, tx7Cnt, tx7Type, tx7Frac)); -} - -void GDSetArray(GXAttr attr, void* base_ptr, u8 stride) { - s32 cpAttr; - if (attr == GX_VA_NBT) { - cpAttr = GX_VA_TEX0MTXIDX; - } else { - cpAttr = attr - GX_VA_POS; - } - - GDWriteCPCmd(cpAttr + CP_REG_ARRAYBASE_ID, OSCachedToPhysical(base_ptr)); - GDWriteCPCmd(cpAttr + CP_REG_ARRAYSTRIDE_ID, stride); -} - -void GDSetArrayRaw(GXAttr attr, u32 base_ptr_raw, u8 stride) { - s32 cpAttr; - if (attr == GX_VA_NBT) { - cpAttr = GX_VA_TEX0MTXIDX; - } else { - cpAttr = attr - GX_VA_POS; - } - - GDWriteCPCmd(cpAttr + CP_REG_ARRAYBASE_ID, base_ptr_raw); - GDWriteCPCmd(cpAttr + CP_REG_ARRAYSTRIDE_ID, stride); -} - -void GDPatchArrayPtr(void* base_ptr) { - GDWrite_u32(OSCachedToPhysical(base_ptr)); -} - -void GDSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u8 normalize, u32 postmtx) { - u32 form; - u32 tgType; - u32 proj; - u32 row; - u32 embossRow; - u32 embossLit; - - form = 0; - proj = 0; - row = 5; - embossRow = 5; - embossLit = 0; - - ASSERTMSGLINE(432, dst_coord < GX_MAX_TEXCOORD, "GDSetTexCoordGen: invalid texcoord ID"); - - switch(src_param) { - case GX_TG_POS: - row = 0; - form = 1; - break; - case GX_TG_NRM: - row = 1; - form = 1; - break; - case GX_TG_BINRM: - row = 3; - form = 1; - break; - case GX_TG_TANGENT: - row = 4; - form = 1; - break; - case GX_TG_COLOR0: - row = 2; - break; - case GX_TG_COLOR1: - row = 2; - break; - case GX_TG_TEX0: - row = 5; - break; - case GX_TG_TEX1: - row = 6; - break; - case GX_TG_TEX2: - row = 7; - break; - case GX_TG_TEX3: - row = 8; - break; - case GX_TG_TEX4: - row = 9; - break; - case GX_TG_TEX5: - row = 10; - break; - case GX_TG_TEX6: - row = 11; - break; - case GX_TG_TEX7: - row = 12; - break; - case GX_TG_TEXCOORD0: - embossRow = 0; - break; - case GX_TG_TEXCOORD1: - embossRow = 1; - break; - case GX_TG_TEXCOORD2: - embossRow = 2; - break; - case GX_TG_TEXCOORD3: - embossRow = 3; - break; - case GX_TG_TEXCOORD4: - embossRow = 4; - break; - case GX_TG_TEXCOORD5: - embossRow = 5; - break; - case GX_TG_TEXCOORD6: - embossRow = 6; - break; - default: - ASSERTMSGLINE(457, 0, "GDSetTexCoordGen: invalid texgen source"); - break; - } - - switch (func) { - case GX_TG_MTX2x4: - tgType = 0; - break; - case GX_TG_MTX3x4: - tgType = 0; - proj = 1; - break; - case GX_TG_BUMP0: - case GX_TG_BUMP1: - case GX_TG_BUMP2: - case GX_TG_BUMP3: - case GX_TG_BUMP4: - case GX_TG_BUMP5: - case GX_TG_BUMP6: - case GX_TG_BUMP7: - ASSERTMSGLINE(481, src_param >= GX_TG_TEXCOORD0 && src_param <= GX_TG_TEXCOORD6, "GDSetTexCoordGen: invalid emboss source"); - tgType = 1; - embossLit = func - GX_TG_BUMP0; - break; - case GX_TG_SRTG: - if (src_param == GX_TG_COLOR0) { - tgType = 2; - } else { - tgType = 3; - } - break; - default: - ASSERTMSGLINE(495, 0, "GDSetTexCoordGen: invalid texgen function"); - break; - } - - GDWriteXFCmd(dst_coord + XF_REG_TEX0_ID, XF_REG_TEX(proj, form, tgType, row, embossRow, embossLit)); - GDWriteXFCmd(dst_coord + XF_REG_DUALTEX0_ID, XF_REG_DUALTEX(postmtx - 0x40, normalize)); -} - -void GDSetCullMode(GXCullMode mode) { - static u8 cm2hw[4] = { 0, 2, 1, 3 }; - - GDWriteBPCmd(0xFE00C000); - GDWriteBPCmd(cm2hw[mode] << 14); -} - -void GDSetGenMode(u8 nTexGens, u8 nChans, u8 nTevs) { - GDWriteBPCmd(0xFE003C3F); - GDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, 0, 0)); - - GDWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans); - GDWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens); -} - -void GDSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm) { - static u8 cm2hw[4] = { 0, 2, 1, 3 }; - - GDWriteBPCmd(0xFE07FC3F); - GDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, cm2hw[cm], nInds)); - - GDWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans); - GDWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens); -} - -void GDSetLPSize(u8 lineWidth, u8 pointSize, GXTexOffset lineOffset, GXTexOffset pointOffset, u8 lineHalfAspect) { - GDWriteBPCmd(BP_LP_SIZE(lineWidth, pointSize, lineOffset, pointOffset, lineHalfAspect, 0x22)); -} - -void GDSetCoPlanar(u8 enable) { - GDWriteBPCmd(0xFE080000); - GDWriteBPCmd(enable << 19); -} diff --git a/src/dolphin/gd/GDIndirect.c b/src/dolphin/gd/GDIndirect.c deleted file mode 100644 index 104fce4..0000000 --- a/src/dolphin/gd/GDIndirect.c +++ /dev/null @@ -1,270 +0,0 @@ -#include -#include - -void GDSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, - GXIndTexFormat format, GXIndTexBiasSel bias_sel, - GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, - GXIndTexWrap wrap_t, u8 add_prev, u8 utc_lod, - GXIndTexAlphaSel alpha_sel) { - GDWriteBPCmd(BP_TEV_INDIRECT( - ind_stage & 3, - format & 3, - bias_sel & 7, - alpha_sel & 3, - matrix_sel & 0xF, - wrap_s & 7, - wrap_t & 7, - utc_lod & 1, - add_prev & 1, - 0x10 + (tev_stage & 0xF) - )); -} - -void GDSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp) { - u32 id_offset; - - switch (mtx_id) { - case GX_ITM_0: - id_offset = 0; - break; - case GX_ITM_1: - id_offset = 3; - break; - case GX_ITM_2: - id_offset = 6; - break; - default: - ASSERTMSGLINE(111, 0, "GDSetIndTexMtx: Invalid matrix id"); - break; - } - - scale_exp += 17; - - GDWriteBPCmd(BP_IND_MTX( - (s32)(offset[0][0] * 0x400) & 0x7FF, - (s32)(offset[1][0] * 0x400) & 0x7FF, - scale_exp & 3, - 6 + id_offset - )); - - GDWriteBPCmd(BP_IND_MTX( - (s32)(offset[0][1] * 0x400) & 0x7FF, - (s32)(offset[1][1] * 0x400) & 0x7FF, - (scale_exp >> 2) & 3, - 7 + id_offset - )); - - GDWriteBPCmd(BP_IND_MTX( - (s32)(offset[0][2] * 0x400) & 0x7FF, - (s32)(offset[1][2] * 0x400) & 0x7FF, - (scale_exp >> 4) & 3, - 8 + id_offset - )); -} - -void GDSetIndTexCoordScale(GXIndTexStageID indStageEven, GXIndTexScale scaleS0, - GXIndTexScale scaleT0, GXIndTexScale scaleS1, - GXIndTexScale scaleT1) { - GDWriteBPCmd(BP_IND_TEXCOORD_SCALE( - scaleS0 & 0xF, - scaleT0 & 0xF, - scaleS1 & 0xF, - scaleT1 & 0xF, - 0x25 + ((indStageEven >> 1) & 1) - )); -} - -void GDSetIndTexOrder(GXTexCoordID texCoord0, GXTexMapID texMap0, - GXTexCoordID texCoord1, GXTexMapID texMap1, - GXTexCoordID texCoord2, GXTexMapID texMap2, - GXTexCoordID texCoord3, GXTexMapID texMap3) { - GDWriteBPCmd(BP_IND_TEX_ORDER( - texMap0 & 7, - texCoord0 & 7, - texMap1 & 7, - texCoord1 & 7, - texMap2 & 7, - texCoord2 & 7, - texMap3 & 7, - texCoord3 & 7, - 0x27 - )); -} - -void GDSetTevDirect(GXTevStageID tev_stage) { - GDSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, 0, 0, GX_ITBA_OFF); -} - -void GDSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel) { - GXIndTexWrap wrap; - wrap = replace_mode ? GX_ITW_0 : GX_ITW_OFF; - - GDSetTevIndirect(tev_stage, - ind_stage, - GX_ITF_8, - signed_offset ? GX_ITB_STU : GX_ITB_NONE, - matrix_sel, - wrap, - wrap, - 0, - 0, - GX_ITBA_OFF); -} - -void GDSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, - u16 tilesize_s, u16 tilesize_t, u16 tilespacing_s, - u16 tilespacing_t, GXIndTexFormat format, - GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, - GXIndTexAlphaSel alpha_sel) { - GXIndTexWrap wrap_s; - GXIndTexWrap wrap_t; - f32 mtx[2][3]; - - switch (tilesize_s) { - case 256: - wrap_s = GX_ITW_256; - break; - case 128: - wrap_s = GX_ITW_128; - break; - case 64: - wrap_s = GX_ITW_64; - break; - case 32: - wrap_s = GX_ITW_32; - break; - case 16: - wrap_s = GX_ITW_16; - break; - default: - ASSERTMSGLINE(268, 0, "GDSetTevIndTile: Invalid tilesize for S coordinate"); - wrap_s = GX_ITW_OFF; - break; - } - - switch (tilesize_t) { - case 256: - wrap_t = GX_ITW_256; - break; - case 128: - wrap_t = GX_ITW_128; - break; - case 64: - wrap_t = GX_ITW_64; - break; - case 32: - wrap_t = GX_ITW_32; - break; - case 16: - wrap_t = GX_ITW_16; - break; - default: - ASSERTMSGLINE(280, 0, "GDSetTevIndTile: Invalid tilesize for T coordinate"); - wrap_t = GX_ITW_OFF; - break; - } - - mtx[0][0] = (f32)tilespacing_s / 0x400; - mtx[0][1] = mtx[0][2] = 0.0f; - - mtx[1][1] = (f32)tilespacing_t / 0x400; - mtx[1][0] = mtx[1][2] = 0.0f; - GDSetIndTexMtx(matrix_sel, mtx, 10); - - GDSetTevIndirect(tev_stage, - ind_stage, - format, - bias_sel, - matrix_sel, - wrap_s, - wrap_t, - 0, - 1, - alpha_sel); -} - -void GDSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { - GXIndTexMtxID sm; - GXIndTexMtxID tm; - - switch(matrix_sel) { - case GX_ITM_0: - sm = GX_ITM_S0; - tm = GX_ITM_T0; - break; - case GX_ITM_1: - sm = GX_ITM_S1; - tm = GX_ITM_T1; - break; - case GX_ITM_2: - sm = GX_ITM_S2; - tm = GX_ITM_T2; - break; - default: - ASSERTMSGLINE(332, 0, "GDSetTevIndBumpST: Invalid matrix selection"); - break; - } - - GDSetTevIndirect(tev_stage, - ind_stage, - GX_ITF_8, - GX_ITB_ST, - sm, - GX_ITW_0, - GX_ITW_0, - 0, - 0, - GX_ITBA_OFF); - - GDSetTevIndirect(tev_stage + 1, - ind_stage, - GX_ITF_8, - GX_ITB_ST, - tm, - GX_ITW_0, - GX_ITW_0, - 1, - 0, - GX_ITBA_OFF); - - GDSetTevIndirect(tev_stage + 2, - ind_stage, - GX_ITF_8, - GX_ITB_NONE, - GX_ITM_OFF, - GX_ITW_OFF, - GX_ITW_OFF, - 1, - 0, - GX_ITBA_OFF); -} - -void GDSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { - GDSetTevIndirect(tev_stage, - ind_stage, - GX_ITF_8, - GX_ITB_STU, - matrix_sel, - GX_ITW_OFF, - GX_ITW_OFF, - 0, - 0, - GX_ITBA_OFF); -} - -void GDSetTevIndRepeat(GXTevStageID tev_stage) { - GDSetTevIndirect(tev_stage, - GX_INDTEXSTAGE0, - GX_ITF_8, - GX_ITB_NONE, - GX_ITM_OFF, - GX_ITW_0, - GX_ITW_0, - 1, - 0, - GX_ITBA_OFF); -} - -void __GDSetIndTexMask(u32 mask) { - GDWriteBPCmd(BP_IND_MASK(mask & 0xFF, 0xF)); -} diff --git a/src/dolphin/gd/GDLight.c b/src/dolphin/gd/GDLight.c deleted file mode 100644 index 96e08a4..0000000 --- a/src/dolphin/gd/GDLight.c +++ /dev/null @@ -1,206 +0,0 @@ -#include -#include - -void GDSetLightAttn(GXLightID light, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) { - GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_ATTN_ID, 6); - GDWrite_f32(a0); - GDWrite_f32(a1); - GDWrite_f32(a2); - GDWrite_f32(k0); - GDWrite_f32(k1); - GDWrite_f32(k2); -} - -void GDSetLightSpot(GXLightID light, f32 cutoff, GXSpotFn spot_func) { - f32 a0; - f32 a1; - f32 a2; - f32 r; - f32 d; - f32 cr; - - if (cutoff <= 0.0f || cutoff > 90.0f) { - spot_func = 0; - } - - r = M_PI * cutoff / 180.0f; - cr = cosf(r); - - switch(spot_func) { - case GX_SP_FLAT: - a0 = -1000.0f * cr; - a1 = 1000.0f; - a2 = 0.0f; - break; - case GX_SP_COS: - a0 = -cr / (1.0f - cr); - a1 = 1.0f / (1.0f - cr); - a2 = 0.0f; - break; - case GX_SP_COS2: - a0 = 0.0f; - a1 = -cr / (1.0f - cr); - a2 = 1.0f / (1.0f - cr); - break; - case GX_SP_SHARP: - d = (1.0f - cr) * (1.0f - cr); - a0 = (cr * (cr - 2.0f)) / d; - a1 = 2.0f / d; - a2 = -1.0f / d; - break; - case GX_SP_RING1: - d = (1.0f - cr) * (1.0f - cr); - a0 = (-4.0f * cr) / d; - a1 = (4.0f * (1.0f + cr)) / d; - a2 = -4.0f / d; - break; - case GX_SP_RING2: - d = (1.0f - cr) * (1.0f - cr); - a0 = 1.0f - (2.0f * cr * cr) / d; - a1 = (4.0f * cr) / d; - a2 = -2.0f / d; - break; - case GX_SP_OFF: - default: - a0 = 1.0f; - a1 = 0.0f; - a2 = 0.0f; - break; - } - - GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_ATTN_ID, 3); - GDWrite_f32(a0); - GDWrite_f32(a1); - GDWrite_f32(a2); -} - -void GDSetLightDistAttn(GXLightID light, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) { - f32 k0; - f32 k1; - f32 k2; - - if (ref_dist < 0.0f || ref_br <= 0.0f || ref_br >= 1.0f) { - dist_func = 0; - } - - switch (dist_func) { - case GX_DA_GENTLE: - k0 = 1.0f; - k1 = (1.0f - ref_br) / (ref_br * ref_dist); - k2 = 0.0f; - break; - case GX_DA_MEDIUM: - k0 = 1.0f; - k1 = (0.5f * (1.0f - ref_br)) / (ref_br * ref_dist); - k2 = (0.5f * (1.0f - ref_br)) / (ref_dist * (ref_br * ref_dist)); - break; - case GX_DA_STEEP: - k0 = 1.0f; - k1 = 0.0f; - k2 = (1.0f - ref_br) / (ref_dist * (ref_br * ref_dist)); - break; - case GX_DA_OFF: - default: - k0 = 1.0f; - k1 = 0.0f; - k2 = 0.0f; - break; - } - - GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_DISTATTN_ID, 3); - GDWrite_f32(k0); - GDWrite_f32(k1); - GDWrite_f32(k2); -} - -void GDSetLightColor(GXLightID light, GXColor color) { - GDWriteXFCmd(__GDLightID2Offset(light) + XF_LIGHT_COLOR_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); -} - -void GDSetLightPos(GXLightID light, f32 x, f32 y, f32 z) { - GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_POS_ID, 3); - GDWrite_f32(x); - GDWrite_f32(y); - GDWrite_f32(z); -} - -void GDSetLightDir(GXLightID light, f32 nx, f32 ny, f32 nz) { - GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_DIR_ID, 3); - GDWrite_f32(nx); - GDWrite_f32(ny); - GDWrite_f32(nz); -} - -void GDSetSpecularDirHA(GXLightID light, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) { - f32 px; - f32 py; - f32 pz; - px = 1000000000000000000.0f * -nx; - py = 1000000000000000000.0f * -ny; - pz = 1000000000000000000.0f * -nz; - - GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_SPEC_DIR_ID, 6); - GDWrite_f32(px); - GDWrite_f32(py); - GDWrite_f32(pz); - GDWrite_f32(hx); - GDWrite_f32(hy); - GDWrite_f32(hz); -} - -void GDSetSpecularDir(GXLightID light, f32 nx, f32 ny, f32 nz) { - f32 px; - f32 py; - f32 pz; - f32 hx; - f32 hy; - f32 hz; - f32 mag; - - hx = -nx; - hy = -ny; - hz = 1.0f + -nz; - - mag = hx * hx + hy * hy + hz * hz; - if (mag != 0.0f) { - mag = 1.0f / sqrtf(mag); - } - - hx = hx * mag; - hy = hy * mag; - hz = hz * mag; - px = 1000000000000000000.0f * -nx; - py = 1000000000000000000.0f * -ny; - pz = 1000000000000000000.0f * -nz; - - GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_SPEC_DIR_ID, 6); - GDWrite_f32(px); - GDWrite_f32(py); - GDWrite_f32(pz); - GDWrite_f32(hx); - GDWrite_f32(hy); - GDWrite_f32(hz); -} - -void GDLoadLightObjIndx(u32 lt_obj_indx, GXLightID light) { - GDWriteXFIndxDCmd(__GDLightID2Offset(light) + XF_LIGHT_ID, 0x10, lt_obj_indx); -} - -void GDSetChanAmbColor(GXChannelID chan, GXColor color) { - GDWriteXFCmd((chan & 1) + XF_REG_AMBIENT0_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); -} - -void GDSetChanMatColor(GXChannelID chan, GXColor color) { - GDWriteXFCmd((chan & 1) + XF_REG_MATERIAL0_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); -} - -void GDSetChanCtrl(GXChannelID chan, u8 enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn) { - u32 reg; - - reg = XF_REG_CHAN_CTRL(mat_src, enable, light_mask & 0xF, amb_src, attn_fn == GX_AF_SPEC ? GX_DF_NONE : diff_fn, attn_fn != GX_AF_NONE, attn_fn != GX_AF_SPEC, (light_mask >> 4) & 0xF); - GDWriteXFCmd((chan & 3) + XF_REG_COLOR0CNTRL_ID, reg); - - if (chan == 4 || chan == 5) { - GDWriteXFCmd(chan + XF_REG_MATERIAL0_ID, reg); - } -} diff --git a/src/dolphin/gd/GDPixel.c b/src/dolphin/gd/GDPixel.c deleted file mode 100644 index c18cf77..0000000 --- a/src/dolphin/gd/GDPixel.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include - -void GDSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) { - f32 A; - f32 B; - f32 B_mant; - f32 C; - f32 A_f; - u32 b_expn; - u32 b_m; - u32 a_hex; - u32 c_hex; - u32 fsel; - u32 proj; - - ASSERTMSGLINE(62, farz >= 0.0f, "GDSetFog: The farz should be positive value"); - ASSERTMSGLINE(63, farz >= nearz, "GDSetFog: The farz should be larger than nearz"); - - fsel = type & 7; - proj = (type >> 3) & 1; - - if (proj != 0) { - if (farz == nearz || endz == startz) { - A_f = 0.0f; - C = 0.0f; - } else { - A = 1.0f / (endz - startz); - A_f = (farz - nearz) * A; - C = (startz - nearz) * A; - } - - b_expn = 0; - b_m = 0; - } else { - if (farz == nearz || endz == startz) { - A = 0.0f; - B = 0.5f; - C = 0.0f; - } else { - A = (farz * nearz) / ((farz - nearz) * (endz - startz)); - B = farz / (farz - nearz); - C = startz / (endz - startz); - } - - B_mant = B; - b_expn = 1; - - while (B_mant > 1.0) { - B_mant *= 0.5f; - b_expn++; - } - - while (B_mant > 0.0f && B_mant < 0.5) { - B_mant *= 2.0f; - b_expn--; - } - - A_f = A / (1 << b_expn); - b_m = (u32) (8388638.0f * B_mant); - } - - a_hex = *(u32*)&A_f; - c_hex = *(u32*)&C; - - GDWriteBPCmd(BP_FOG_UNK0(a_hex >> 12, 0xEE)); - GDWriteBPCmd(BP_FOG_UNK1(b_m, 0xEF)); - GDWriteBPCmd(BP_FOG_UNK2(b_expn, 0xF0)); - GDWriteBPCmd(BP_FOG_UNK3(c_hex >> 12, proj, fsel, 0xF1)); - GDWriteBPCmd(BP_FOG_COLOR(color.r, color.g, color.b, 0xF2)); -} - -void GDSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp logic_op) { - GDWriteBPCmd(0xFE00FFE3); - GDWriteBPCmd(BP_BLEND_MODE( - type == GX_BM_BLEND || type == GX_BM_SUBTRACT, - type == GX_BM_LOGIC, - 0, - 0, - 0, - dst_factor, - src_factor, - type == GX_BM_SUBTRACT, - logic_op, - 0x41 - )); -} - -void GDSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor, - GXBlendFactor dst_factor, GXLogicOp logic_op, - u8 color_update_enable, u8 alpha_update_enable, - u8 dither_enable) { - GDWriteBPCmd(BP_BLEND_MODE( - type == GX_BM_BLEND || type == GX_BM_SUBTRACT, - type == GX_BM_LOGIC, - dither_enable, - color_update_enable, - alpha_update_enable, - dst_factor, - src_factor, - type == GX_BM_SUBTRACT, - logic_op, - 0x41 - )); -} - -void GDSetZMode(u8 compare_enable, GXCompare func, u8 update_enable) { - GDWriteBPCmd(BP_Z_MODE(compare_enable, func, update_enable, 0x40)); -} - -void GDSetDstAlpha(u8 enable, u8 alpha) { - GDWriteBPCmd(BP_DST_ALPHA(alpha, enable, 0x42)); -} - -void GDSetDrawSync(u16 token) { - GDWriteBPCmd(BP_TOKEN(token, 0x48)); - GDWriteBPCmd(BP_TOKEN(token, 0x47)); -} diff --git a/src/dolphin/gd/GDTev.c b/src/dolphin/gd/GDTev.c deleted file mode 100644 index 69803e8..0000000 --- a/src/dolphin/gd/GDTev.c +++ /dev/null @@ -1,159 +0,0 @@ -#include -#include - -void GDSetTevOp(GXTevStageID stage, GXTevMode mode) { - GXTevColorArg carg = GX_CC_RASC; - GXTevAlphaArg aarg = GX_CA_RASA; - - if (stage != GX_TEVSTAGE0) { - carg = GX_CC_CPREV; - aarg = GX_CA_APREV; - } - - switch (mode) { - case GX_MODULATE: - GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_TEXC, carg, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); - GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); - break; - case GX_DECAL: - GDSetTevColorCalc(stage, carg, GX_CC_TEXC, GX_CC_TEXA, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); - GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); - break; - case GX_BLEND: - GDSetTevColorCalc(stage, carg, GX_CC_ONE, GX_CC_TEXC, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); - GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); - break; - case GX_REPLACE: - GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); - GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); - break; - case GX_PASSCLR: - GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, carg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); - GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); - break; - default: - ASSERTMSGLINE(110, 0, "GDSetTevOp: Invalid Tev Mode"); - break; - } -} - -void GDSetTevColorCalc(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, - GXTevColorArg c, GXTevColorArg d, GXTevOp op, - GXTevBias bias, GXTevScale scale, u8 clamp, - GXTevRegID out_reg) { - if (op <= GX_TEV_SUB) { - GDWriteBPCmd(BP_TEV_COLOR(d, c, b, a, bias, op & 1, clamp, scale, out_reg, stage * 2 + 0xC0)); - } else { - GDWriteBPCmd(BP_TEV_COLOR(d, c, b, a, 3, op & 1, clamp, (op >> 1) & 3, out_reg, stage * 2 + 0xC0)); - } -} - -void GDSetTevAlphaCalcAndSwap(GXTevStageID stage, GXTevAlphaArg a, - GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d, - GXTevOp op, GXTevBias bias, GXTevScale scale, - u8 clamp, GXTevRegID out_reg, - GXTevSwapSel ras_sel, GXTevSwapSel tex_sel) { - if (op <= GX_TEV_SUB) { - GDWriteBPCmd(BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, bias, op & 1, clamp, scale, out_reg, stage * 2 + 0xC1)); - } else { - GDWriteBPCmd(BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, 3, op & 1, clamp, (op >> 1) & 3, out_reg, stage * 2 + 0xC1)); - } -} - -void GDSetTevColor(GXTevRegID reg, GXColor color) { - u32 regRA; - u32 regBG; - - regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 0, 0xE0 + reg * 2); - regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 0, 0xE1 + reg * 2); - - GDWriteBPCmd(regRA); - GDWriteBPCmd(regBG); - GDWriteBPCmd(regBG); - GDWriteBPCmd(regBG); -} - -void GDSetTevColorS10(GXTevRegID reg, GXColorS10 color) { - u32 regRA; - u32 regBG; - - regRA = BP_TEV_COLOR_REG_RA(color.r & 0x7FF, color.a & 0x7FF, 0, 0xE0 + reg * 2); - regBG = BP_TEV_COLOR_REG_BG(color.b & 0x7FF, color.g & 0x7FF, 0, 0xE1 + reg * 2); - - GDWriteBPCmd(regRA); - GDWriteBPCmd(regBG); - GDWriteBPCmd(regBG); - GDWriteBPCmd(regBG); -} - -void GDSetTevKColor(GXTevKColorID reg, GXColor color) { - u32 regRA; - u32 regBG; - - regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 1, 0xE0 + reg * 2); - regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 1, 0xE1 + reg * 2); - - GDWriteBPCmd(regRA); - GDWriteBPCmd(regBG); -} - -void GDSetTevKonstantSel(GXTevStageID evenStage, GXTevKColorSel kcsel0, - GXTevKAlphaSel kasel0, GXTevKColorSel kcsel1, - GXTevKAlphaSel kasel1) { - GDWriteBPCmd(0xFEFFFFF0); - GDWriteBPCmd(BP_TEV_KSEL(0, 0, kcsel0, kasel0, kcsel1, kasel1, evenStage / 2 + 0xF6)); -} - -void GDSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, - GXTevColorChan green, GXTevColorChan blue, - GXTevColorChan alpha) { - GDWriteBPCmd(0xFE00000F); - GDWriteBPCmd(BP_TEV_KSEL(red, green, 0, 0, 0, 0, table * 2 + 0xF6)); - - GDWriteBPCmd(0xFE00000F); - GDWriteBPCmd(BP_TEV_KSEL(blue, alpha, 0, 0, 0, 0, table * 2 + 0xF7)); -} - -void GDSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) { - GDWriteBPCmd(BP_ALPHA_COMPARE(ref0, ref1, comp0, comp1, op, 0xF3)); -} - -void GDSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias) { - u32 zfmt; - - switch (fmt) { - case GX_TF_Z8: - zfmt = 0; - break; - case GX_TF_Z16: - zfmt = 1; - break; - case GX_TF_Z24X8: - zfmt = 2; - break; - default: - ASSERTMSGLINE(399, 0, "GDSetZTexture: Invalid format"); - zfmt = 2; - break; - } - - GDWriteBPCmd(BP_ZTEX_PARAMS_0(bias, 0xF4)); - GDWriteBPCmd(BP_ZTEX_PARAMS_1(zfmt, op, 0xF5)); -} - -void GDSetTevOrder(GXTevStageID evenStage, GXTexCoordID coord0, GXTexMapID map0, - GXChannelID color0, GXTexCoordID coord1, GXTexMapID map1, - GXChannelID color1) { - static u8 c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6, 0, 0, 0, 0, 0, 0, 7 }; - GDWriteBPCmd(BP_TEV_ORDER( - map0 & 7, - coord0 & 7, - map0 != GX_TEXMAP_NULL && !(map0 & GX_TEX_DISABLE), - c2r[color0 & 0xF], - map1 & 7, - coord1 & 7, - map1 != GX_TEXMAP_NULL && !(map1 & GX_TEX_DISABLE), - c2r[color1 & 0xF], - evenStage / 2 + 0x28 - )); -} diff --git a/src/dolphin/gd/GDTexture.c b/src/dolphin/gd/GDTexture.c deleted file mode 100644 index c3c1a6c..0000000 --- a/src/dolphin/gd/GDTexture.c +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include - -u8 GD2HWFiltConv[] = {0, 4, 1, 5, 2, 6}; - -u8 GDTexMode0Ids[8] = {128, 129, 130, 131, 160, 161, 162, 163}; -u8 GDTexMode1Ids[8] = {132, 133, 134, 135, 164, 165, 166, 167}; -u8 GDTexImage0Ids[8] = {136, 137, 138, 139, 168, 169, 170, 171}; -u8 GDTexImage1Ids[8] = {140, 141, 142, 143, 172, 173, 174, 175}; -u8 GDTexImage2Ids[8] = {144, 145, 146, 147, 176, 177, 178, 179}; -u8 GDTexImage3Ids[8] = {148, 149, 150, 151, 180, 181, 182, 183}; -u8 GDTexTlutIds[8] = {152, 153, 154, 155, 184, 185, 186, 187}; - -void GDSetTexLookupMode(GXTexMapID id, GXTexWrapMode wrap_s, - GXTexWrapMode wrap_t, GXTexFilter min_filt, - GXTexFilter mag_filt, f32 min_lod, f32 max_lod, - f32 lod_bias, u8 bias_clamp, u8 do_edge_lod, - GXAnisotropy max_aniso) { - GDWriteBPCmd(BP_TEX_MODE0(wrap_s, wrap_t, mag_filt == TRUE, GD2HWFiltConv[min_filt], !do_edge_lod, (u8)(32.0f * lod_bias), max_aniso, bias_clamp, GDTexMode0Ids[id])); - GDWriteBPCmd(BP_TEX_MODE1((u8)(16.0f * min_lod), (u8)(16.0f * max_lod), GDTexMode1Ids[id])); -} - -void GDSetTexImgAttr(GXTexMapID id, u16 width, u16 height, GXTexFmt format) { - GDWriteBPCmd(BP_IMAGE_ATTR(width - 1, height - 1, format, GDTexImage0Ids[id])); -} - -void GDSetTexImgPtr(GXTexMapID id, void* image_ptr) { - GDWriteBPCmd(BP_IMAGE_PTR(OSCachedToPhysical(image_ptr) >> 5, GDTexImage3Ids[id])); -} - -void GDSetTexImgPtrRaw(GXTexMapID id, u32 image_ptr_raw) { - GDWriteBPCmd(BP_IMAGE_PTR(image_ptr_raw, GDTexImage3Ids[id])); -} - -void GDPatchTexImgPtr(void* image_ptr) { - GDWrite_u24(OSCachedToPhysical(image_ptr) >> 5); -} - -void GDSetTexCached(GXTexMapID id, u32 tmem_even, GXTexCacheSize size_even, - u32 tmem_odd, GXTexCacheSize size_odd) { - GDWriteBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, size_even + 3, size_even + 3, 0, GDTexImage1Ids[id])); - - if (size_odd != 3 && tmem_odd < 0x100000) { - GDWriteBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, size_odd + 3, size_odd + 3, GDTexImage2Ids[id])); - } -} - - -void GDSetTexPreLoaded(GXTexMapID id, u32 tmem_even, u32 tmem_odd) { - GDWriteBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, 0, 0, 1, GDTexImage1Ids[id])); - - if (tmem_odd < 0x100000) { - GDWriteBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, 0, 0, GDTexImage2Ids[id])); - } -} - -void GDSetTexTlut(GXTexMapID id, u32 tmem_addr, GXTlutFmt format) { - GDWriteBPCmd(BP_TEX_TLUT((tmem_addr - 0x80000) >> 9, format, GDTexTlutIds[id])); -} - -void GDSetTexCoordScale(GXTexCoordID coord, u16 s_scale, u16 t_scale) { - GDWriteBPCmd(0xFE00FFFF); - GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, 0, 0, 0, 0, coord * 2 + 0x30)); - - GDWriteBPCmd(0xFE00FFFF); - GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, 0, 0, coord * 2 + 0x31)); -} - -void GDSetTexCoordScale2(GXTexCoordID coord, u16 s_scale, u8 s_bias, - u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap) { - GDWriteBPCmd(0xFE03FFFF); - GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, 0, 0, coord * 2 + 0x30)); - GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31)); -} - -void GDSetTexCoordScaleAndTOEs(GXTexCoordID coord, u16 s_scale, u8 s_bias, - u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap, - u8 line_offset, u8 point_offset) { - GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, line_offset, point_offset, coord * 2 + 0x30)); - GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31)); -} - -void GDLoadTlut(void* tlut_ptr, u32 tmem_addr, GXTlutSize size) { - ASSERTMSGLINE(488, !(tmem_addr & 0x1ff), "GDLoadTlut: invalid TMEM pointer"); - ASSERTMSGLINE(489, size <= 0x400, "GDLoadTlut: invalid TLUT size"); - - GDWriteBPCmd(0xFEFFFF00); - GDWriteBPCmd(0xF000000); - GDWriteBPCmd(BP_LOAD_TLUT0(OSCachedToPhysical(tlut_ptr) >> 5, 0x64)); - GDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65)); - GDWriteBPCmd(0xFEFFFF00); - GDWriteBPCmd(0xF000000); -} - -void GDLoadTlutRaw(u32 tlut_ptr_raw, u32 tmem_addr, GXTlutSize size) { - ASSERTMSGLINE(527, size <= 0x400, "GDLoadTlut: invalid TLUT size"); - - GDWriteBPCmd(0xFEFFFF00); - GDWriteBPCmd(0xF000000); - GDWriteBPCmd(BP_LOAD_TLUT0(tlut_ptr_raw, 0x64)); - GDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65)); - GDWriteBPCmd(0xFEFFFF00); - GDWriteBPCmd(0xF000000); -} diff --git a/src/dolphin/gd/GDTransform.c b/src/dolphin/gd/GDTransform.c deleted file mode 100644 index 9ac9c66..0000000 --- a/src/dolphin/gd/GDTransform.c +++ /dev/null @@ -1,127 +0,0 @@ -#include -#include - -void GDLoadPosMtxImm(const Mtx mtx, u32 id) { - GDWriteXFCmdHdr(4 * id, 12); - GDWrite_f32(mtx[0][0]); - GDWrite_f32(mtx[0][1]); - GDWrite_f32(mtx[0][2]); - GDWrite_f32(mtx[0][3]); - GDWrite_f32(mtx[1][0]); - GDWrite_f32(mtx[1][1]); - GDWrite_f32(mtx[1][2]); - GDWrite_f32(mtx[1][3]); - GDWrite_f32(mtx[2][0]); - GDWrite_f32(mtx[2][1]); - GDWrite_f32(mtx[2][2]); - GDWrite_f32(mtx[2][3]); -} - -void GDLoadPosMtxIndx(u16 mtx_indx, u32 id) { - GDWriteXFIndxACmd(4 * id, 12, mtx_indx); -} - -void GDLoadNrmMtxImm(const Mtx mtx, u32 id) { - GDWriteXFCmdHdr(id * 3 + 0x400, 9); - GDWrite_f32(mtx[0][0]); - GDWrite_f32(mtx[0][1]); - GDWrite_f32(mtx[0][2]); - GDWrite_f32(mtx[1][0]); - GDWrite_f32(mtx[1][1]); - GDWrite_f32(mtx[1][2]); - GDWrite_f32(mtx[2][0]); - GDWrite_f32(mtx[2][1]); - GDWrite_f32(mtx[2][2]); -} - -void GDLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id) { - GDWriteXFCmdHdr(id * 3 + 0x400, 9); - GDWrite_f32(mtx[0][0]); - GDWrite_f32(mtx[0][1]); - GDWrite_f32(mtx[0][2]); - GDWrite_f32(mtx[1][0]); - GDWrite_f32(mtx[1][1]); - GDWrite_f32(mtx[1][2]); - GDWrite_f32(mtx[2][0]); - GDWrite_f32(mtx[2][1]); - GDWrite_f32(mtx[2][2]); -} - -void GDLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id) { - GDWriteXFIndxBCmd(id * 3 + 0x400, 9, mtx_indx); -} - -void GDLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type) { - u16 addr; - u8 count; - - if (id >= 0x40) { - ASSERTMSGLINE(178, type == GX_MTX3x4, "GDLoadTexMtxImm: invalid matrix type"); - addr = ((id - 0x40) << 2) + 0x500; - count = 12; - } else { - addr = 4 * id; - count = type == GX_MTX2x4 ? 8 : 12; - } - - GDWriteXFCmdHdr(addr,count); - GDWrite_f32(mtx[0][0]); - GDWrite_f32(mtx[0][1]); - GDWrite_f32(mtx[0][2]); - GDWrite_f32(mtx[0][3]); - GDWrite_f32(mtx[1][0]); - GDWrite_f32(mtx[1][1]); - GDWrite_f32(mtx[1][2]); - GDWrite_f32(mtx[1][3]); - - if (type == GX_MTX3x4) { - GDWrite_f32(mtx[2][0]); - GDWrite_f32(mtx[2][1]); - GDWrite_f32(mtx[2][2]); - GDWrite_f32(mtx[2][3]); - } -} - -void GDLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type) { - u16 addr; - u8 count; - - if (id >= 0x40) { - ASSERTMSGLINE(227, type == GX_MTX3x4, "GDLoadTexMtxIndx: invalid matrix type"); - addr = ((id - 0x40) << 2) + 0x500; - count = 12; - } else { - addr = 4 * id; - count = type == GX_MTX2x4 ? 8 : 12; - } - - GDWriteXFIndxCCmd(addr, count, mtx_indx); -} - -void GDSetCurrentMtx(u32 pn, u32 t0, u32 t1, u32 t2, u32 t3, u32 t4, u32 t5, u32 t6, u32 t7) { - u32 regA; - u32 regB; - - regA = CP_MTX_REG_A(pn, t0, t1, t2, t3); - regB = CP_MTX_REG_B(t4, t5, t6, t7); - - GDWriteCPCmd(CP_MTX_REG_A_ID, regA); - GDWriteCPCmd(CP_MTX_REG_B_ID, regB); - GDWriteXFCmdHdr(XF_REG_MATRIXINDEX0_ID, 2); - GDWrite_u32(regA); - GDWrite_u32(regB); -} - -void GDSetProjection(const Mtx44 mtx, GXProjectionType type) { - u32 c; - c = type == GX_ORTHOGRAPHIC ? 3 : 2; - - GDWriteXFCmdHdr(XF_REG_PROJECTIONA_ID, 7); - GDWrite_f32(mtx[0][0]); - GDWrite_f32(mtx[0][c]); - GDWrite_f32(mtx[1][1]); - GDWrite_f32(mtx[1][c]); - GDWrite_f32(mtx[2][2]); - GDWrite_f32(mtx[2][3]); - GDWrite_u32(type); -} diff --git a/src/dolphin/gx/GXAttr.c b/src/dolphin/gx/GXAttr.c deleted file mode 100644 index 136661d..0000000 --- a/src/dolphin/gx/GXAttr.c +++ /dev/null @@ -1,641 +0,0 @@ -#include -#include - -#include "__gx.h" - -#define CHECK_ATTRPTR(line, attrPtr) ASSERTMSGLINE(line, (attrPtr) != NULL, "GXSetVtxDescv: attrPtr is NULL") -#define CHECK_ATTRNAME(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_PNMTXIDX, "GXSetVtxDesc: Invalid vertex attribute name") -#define CHECK_ATTRNAME2(line, attr) ASSERTMSGLINE(line, (attr) <= GX_VA_TEX7 || (attr) == GX_VA_NBT, "GXSetVtxDesc: Invalid vertex attribute name") -#define CHECK_ATTRNAME3(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_PNMTXIDX && (attr) < GX_VA_MAX_ATTR, "GXSetVtxDesc: Invalid vertex attribute name") -#define CHECK_ATTRNAME4(line, attr) ASSERTMSGLINE(line, ((attr) >= GX_VA_POS && (attr) <= GX_VA_TEX7) || (attr) == GX_VA_NBT, "GXSetVtxAttrFmt: Invalid vertex attribute name") -#define CHECK_ATTRNAME5(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_POS && (attr) <= GX_LIGHT_ARRAY, "GXSetArray: Invalid vertex attribute name") -#define CHECK_ATTRTYPE(line, type) ASSERTMSGLINE(line, (type) >= GX_NONE && (type) <= GX_INDEX16, "GXSetVtxDesc: Invalid vertex attribute type") -#define CHECK_VTXFMT(line, vtxfmt) ASSERTMSGLINE(line, (vtxfmt) < GX_MAX_VTXFMT, "GXSetVtxAttrFmt: Format Index is out of range") -#define CHECK_FRAC(line, frac) ASSERTMSGLINE(line, (frac) < 32, "GXSetVtxAttrFmt: Frac value is >= 32") -#define CHECK_LISTPTR(line, list) ASSERTMSGLINE(line, (list) != NULL, "GXSetVtxAttrFmt: list pointer is NULL") -#define CHECK_MTXIDX(line, attr, type) ASSERTMSGLINE(line, (attr) > GX_VA_TEX7MTXIDX || (type) <= GX_VA_TEX0MTXIDX, "GXSetVtxDesc: GX_VA_*MTXIDX accepts GX_NONE or GX_DIRECT only") - -static void __GXXfVtxSpecs(void) { - u32 nCols = 0; - u32 nNrm; - u32 nTex; - u32 reg; - - nNrm = __GXData->hasBiNrms ? 2 : __GXData->hasNrms ? 1 : 0; - -#ifdef DEBUG - nCols = GET_REG_FIELD(__GXData->vcdLo, 2, 13) ? 1 : 0; - nCols += GET_REG_FIELD(__GXData->vcdLo, 2, 15) ? 1 : 0; -#else - nCols = 33 - __cntlzw(GET_REG_FIELD(__GXData->vcdLo, 4, 13)); - nCols /= 2; -#endif - -#ifdef DEBUG - nTex = 0; - nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 0) ? 1 : 0; - nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 2) ? 1 : 0; - nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 4) ? 1 : 0; - nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 6) ? 1 : 0; - nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 8) ? 1 : 0; - nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 10) ? 1 : 0; - nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 12) ? 1 : 0; - nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 14) ? 1 : 0; -#else - nTex = 33 - __cntlzw(GET_REG_FIELD(__GXData->vcdHi, 16, 0)); - nTex /= 2; -#endif - - reg = (nCols) | (nNrm << 2) | (nTex << 4); - GX_WRITE_XF_REG(8, reg); - __GXData->bpSentNot = 1; -} - -static inline void SETVCDATTR(GXAttr Attr, GXAttrType Type) { - switch (Attr) { - case GX_VA_PNMTXIDX: SET_REG_FIELD(212, __GXData->vcdLo, 1, 0, Type); break; - case GX_VA_TEX0MTXIDX: SET_REG_FIELD(213, __GXData->vcdLo, 1, 1, Type); break; - case GX_VA_TEX1MTXIDX: SET_REG_FIELD(214, __GXData->vcdLo, 1, 2, Type); break; - case GX_VA_TEX2MTXIDX: SET_REG_FIELD(215, __GXData->vcdLo, 1, 3, Type); break; - case GX_VA_TEX3MTXIDX: SET_REG_FIELD(216, __GXData->vcdLo, 1, 4, Type); break; - case GX_VA_TEX4MTXIDX: SET_REG_FIELD(217, __GXData->vcdLo, 1, 5, Type); break; - case GX_VA_TEX5MTXIDX: SET_REG_FIELD(218, __GXData->vcdLo, 1, 6, Type); break; - case GX_VA_TEX6MTXIDX: SET_REG_FIELD(219, __GXData->vcdLo, 1, 7, Type); break; - case GX_VA_TEX7MTXIDX: SET_REG_FIELD(220, __GXData->vcdLo, 1, 8, Type); break; - case GX_VA_POS: SET_REG_FIELD(221, __GXData->vcdLo, 2, 9, Type); break; - case GX_VA_NRM: - if (Type != GX_NONE) { - __GXData->hasNrms = 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) { - CHECK_GXBEGIN(264, "GXSetVtxDesc"); - CHECK_ATTRNAME(267, attr); - CHECK_ATTRNAME2(269, attr); - CHECK_ATTRTYPE(271, type); - CHECK_MTXIDX(274, attr, 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 GXSetVtxDescv(const GXVtxDescList *attrPtr) { - CHECK_GXBEGIN(306, "GXSetVtxDescv"); - CHECK_ATTRPTR(307, attrPtr); - - while (attrPtr->attr != GX_VA_NULL) { - CHECK_ATTRNAME(311, attrPtr->attr); - CHECK_ATTRNAME2(314, attrPtr->attr); - CHECK_ATTRTYPE(317, attrPtr->type); - SETVCDATTR(attrPtr->attr, attrPtr->type); - attrPtr++; - } - - if (__GXData->hasNrms || __GXData->hasBiNrms) { - SET_REG_FIELD(326, __GXData->vcdLo, 2, 11, __GXData->nrmType); - } else { - SET_REG_FIELD(326, __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 GXGetVtxDesc(GXAttr attr, GXAttrType* type) { - u32 cpType; - - CHECK_GXBEGIN(458, "GXGetVtxDesc"); - CHECK_ATTRNAME3(460, attr); - - switch (attr) { - case GX_VA_PNMTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 0); break; - case GX_VA_TEX0MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 1); break; - case GX_VA_TEX1MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 2); break; - case GX_VA_TEX2MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 3); break; - case GX_VA_TEX3MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 4); break; - case GX_VA_TEX4MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 5); break; - case GX_VA_TEX5MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 6); break; - case GX_VA_TEX6MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 7); break; - case GX_VA_TEX7MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 8); break; - case GX_VA_POS: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 9); break; - case GX_VA_NRM: cpType = __GXData->hasNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) : 0; break; - case GX_VA_NBT: cpType = __GXData->hasBiNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) : 0; break; - case GX_VA_CLR0: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 13); break; - case GX_VA_CLR1: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 15); break; - case GX_VA_TEX0: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 0); break; - case GX_VA_TEX1: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 2); break; - case GX_VA_TEX2: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 4); break; - case GX_VA_TEX3: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 6); break; - case GX_VA_TEX4: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 8); break; - case GX_VA_TEX5: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 10); break; - case GX_VA_TEX6: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 12); break; - case GX_VA_TEX7: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 14); break; - default: cpType = 0; break; - } - *type = cpType; -} - -void GXGetVtxDescv(GXVtxDescList* vcd) { - GXAttr attr; - - CHECK_GXBEGIN(511, "GXGetVtxDescv"); - CHECK_ATTRPTR(513, vcd); - - for (attr = GX_VA_PNMTXIDX; attr <= GX_VA_TEX7; attr++) { - vcd[attr].attr = attr; - GXGetVtxDesc(attr, &vcd[attr].type); - } - - vcd[attr].attr = GX_VA_NBT; - GXGetVtxDesc(GX_VA_NBT, &vcd[attr].type); - - attr++; - vcd[attr].attr = GX_VA_NULL; -} - -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; - - CHECK_GXBEGIN(713, "GXSetVtxAttrFmtv"); - CHECK_LISTPTR(714, list); - CHECK_VTXFMT(715, vtxfmt); - - va = &__GXData->vatA[vtxfmt]; - vb = &__GXData->vatB[vtxfmt]; - vc = &__GXData->vatC[vtxfmt]; - - while (list->attr != GX_VA_NULL) { - CHECK_ATTRNAME4(725, list->attr); - CHECK_FRAC(726, list->frac); - SETVAT(va, vb, vc, list->attr, list->cnt, list->type, list->frac); -#ifdef DEBUG - __GXVerifyVATImm(list->attr, list->cnt, list->type, list->frac); -#endif - list++; - } - __GXData->dirtyState |= 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 GXGetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt* cnt, GXCompType* type, u8* frac) { - u32* va; - u32* vb; - u32* vc; - - CHECK_GXBEGIN(833, "GXGetVtxAttrFmt"); - CHECK_VTXFMT(834, fmt); - - va = &__GXData->vatA[fmt]; - vb = &__GXData->vatB[fmt]; - vc = &__GXData->vatC[fmt]; - - switch (attr) { - case GX_VA_POS: - *cnt = GET_REG_FIELD(*va, 1, 0); - *type = GET_REG_FIELD(*va, 3, 1); - *frac = (u8)(*va >> 4) & 0x1F; // GET_REG_FIELD(*va, 5, 4) - return; - case GX_VA_NRM: - case GX_VA_NBT: - *cnt = GET_REG_FIELD(*va, 1, 9); - if (*cnt == GX_TEX_ST && (u8)(*va >> 0x1F) != 0) { - *cnt = GX_NRM_NBT3; - } - *type = GET_REG_FIELD(*va, 3, 10); - *frac = GetFracForNrm(*type); - return; - case GX_VA_CLR0: - *cnt = GET_REG_FIELD(*va, 1, 13); - *type = GET_REG_FIELD(*va, 3, 14); - *frac = 0; - return; - case GX_VA_CLR1: - *cnt = GET_REG_FIELD(*va, 1, 17); - *type = GET_REG_FIELD(*va, 3, 18); - *frac = 0; - return; - case GX_VA_TEX0: - *cnt = GET_REG_FIELD(*va, 1, 21); - *type = GET_REG_FIELD(*va, 3, 22); - *frac = (u8)(*va >> 0x19) & 0x1F; - return; - case GX_VA_TEX1: - *cnt = GET_REG_FIELD(*vb, 1, 0); - *type = GET_REG_FIELD(*vb, 3, 1); - *frac = (u8)(*vb >> 4) & 0x1F; - return; - case GX_VA_TEX2: - *cnt = GET_REG_FIELD(*vb, 1, 9); - *type = GET_REG_FIELD(*vb, 3, 10); - *frac = (u8)(*vb >> 0xD) & 0x1F; - return; - case GX_VA_TEX3: - *cnt = GET_REG_FIELD(*vb, 1, 18); - *type = GET_REG_FIELD(*vb, 3, 19); - *frac = (u8)(*vb >> 0x16) & 0x1F; - return; - case GX_VA_TEX4: - *cnt = GET_REG_FIELD(*vb, 1, 27); - *type = GET_REG_FIELD(*vb, 3, 28); - *frac = GET_REG_FIELD(*vc, 5, 0); - return; - case GX_VA_TEX5: - *cnt = GET_REG_FIELD(*vc, 1, 5); - *type = GET_REG_FIELD(*vc, 3, 6); - *frac = (u8)(*vc >> 9) & 0x1F; - return; - case GX_VA_TEX6: - *cnt = GET_REG_FIELD(*vc, 1, 14); - *type = GET_REG_FIELD(*vc, 3, 15); - *frac = (u8)(*vc >> 0x12) & 0x1F; - return; - case GX_VA_TEX7: - *cnt = GET_REG_FIELD(*vc, 1, 23); - *type = GET_REG_FIELD(*vc, 3, 24); - *frac = (int)(*vc >> 0x1B); - return; - default: - *cnt = GX_TEX_ST; - *type = GX_RGB565; - *frac = 0; - return; - } -} - -void GXGetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* vat) { - GXAttr attr; - - CHECK_GXBEGIN(930, "GXGetVtxAttrFmtv"); - CHECK_LISTPTR(931, vat); - CHECK_VTXFMT(932, fmt); - - for (attr = GX_VA_POS; attr <= GX_VA_TEX7; attr++) { - vat->attr = attr; - GXGetVtxAttrFmt(fmt, attr, &vat->cnt, &vat->type, &vat->frac); - vat++; - } - - vat->attr = GX_VA_NULL; -} - -void GXSetArray(GXAttr attr, void* base_ptr, u8 stride) { - GXAttr cpAttr; - u32 phyAddr; - - attr; // needed to match - - CHECK_GXBEGIN(963, "GXSetArray"); - if (attr == GX_VA_NBT) { - attr = GX_VA_NRM; - } - - CHECK_ATTRNAME5(966, attr); - cpAttr = attr - GX_VA_POS; - phyAddr = (u32)base_ptr & 0x3FFFFFFF; - - GX_WRITE_SOME_REG2(8, cpAttr | 0xA0, phyAddr, cpAttr - 12); - GX_WRITE_SOME_REG3(8, cpAttr | 0xB0, stride, cpAttr - 12); -} - -void GXInvalidateVtxCache(void) { - CHECK_GXBEGIN(988, "GXInvalidateVtxCache"); - GX_WRITE_U8(0x48); -} - -void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, GXBool normalize, u32 pt_texmtx) { - u32 reg = 0; - u32 row; - u32 bumprow; // unused - u32 form; - GXAttr mtxIdAttr; - - CHECK_GXBEGIN(1030, "GXSetTexCoordGen"); - ASSERTMSGLINE(1031, dst_coord < GX_MAX_TEXCOORD, "GXSetTexCoordGen: Invalid coordinate Id"); - - form = 0; - row = 5; - switch (src_param) { - case GX_TG_POS: row = 0; form = 1; break; - case GX_TG_NRM: row = 1; form = 1; break; - case GX_TG_BINRM: row = 3; form = 1; break; - case GX_TG_TANGENT: row = 4; form = 1; break; - case GX_TG_COLOR0: row = 2; break; - case GX_TG_COLOR1: row = 2; break; - case GX_TG_TEX0: row = 5; break; - case GX_TG_TEX1: row = 6; break; - case GX_TG_TEX2: row = 7; break; - case GX_TG_TEX3: row = 8; break; - case GX_TG_TEX4: row = 9; break; - case GX_TG_TEX5: row = 10; break; - case GX_TG_TEX6: row = 11; break; - case GX_TG_TEX7: row = 12; break; - case GX_TG_TEXCOORD0: bumprow; break; - case GX_TG_TEXCOORD1: bumprow; break; - case GX_TG_TEXCOORD2: bumprow; break; - case GX_TG_TEXCOORD3: bumprow; break; - case GX_TG_TEXCOORD4: bumprow; break; - case GX_TG_TEXCOORD5: bumprow; break; - case GX_TG_TEXCOORD6: bumprow; break; - default: - ASSERTMSGLINE(1059, 0, "GXSetTexCoordGen: Invalid source parameter"); - break; - } - - switch (func) { - case GX_TG_MTX2x4: - SET_REG_FIELD(1069, reg, 1, 1, 0); - SET_REG_FIELD(1069, reg, 1, 2, form); - SET_REG_FIELD(1071, reg, 3, 4, 0); - SET_REG_FIELD(1071, reg, 5, 7, row); - break; - case GX_TG_MTX3x4: - SET_REG_FIELD(1076, reg, 1, 1, 1); - SET_REG_FIELD(1076, reg, 1, 2, form); - SET_REG_FIELD(1076, reg, 3, 4, 0); - SET_REG_FIELD(1078, reg, 5, 7, row); - break; - case GX_TG_BUMP0: - case GX_TG_BUMP1: - 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/src/dolphin/gx/GXBump.c b/src/dolphin/gx/GXBump.c deleted file mode 100644 index a8534b4..0000000 --- a/src/dolphin/gx/GXBump.c +++ /dev/null @@ -1,308 +0,0 @@ -#include -#include - -#include "__gx.h" - -#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: - ASSERTMSGLINE(277, 0, "GXSetIndTexCoordScale: Invalid Indirect Stage Id"); - 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; - } - - ASSERTMSGLINE(314, tex_map < GX_MAX_TEXMAP, "GXSetIndTexOrder: Invalid direct texture Id"); - ASSERTMSGLINE(315, tex_coord < GX_MAX_TEXCOORD, "GXSetIndTexOrder: Invalid texture coord"); - - switch (ind_stage) { - case GX_INDTEXSTAGE0: - 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: - ASSERTMSGLINE(335, 0, "GXSetIndTexOrder: Invalid Indirect Stage Id"); - break; - } - GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->iref); - __GXData->dirtyState |= 3; - __GXData->bpSentNot = 0; -} - -void GXSetNumIndStages(u8 nIndStages) { - CHECK_GXBEGIN(353, "GXSetNumIndStages"); - ASSERTMSGLINE(355, nIndStages <= 4, "GXSetNumIndStages: Exceeds max. number of indirect texture stages"); - SET_REG_FIELD(356, __GXData->genMode, 3, 16, nIndStages); - __GXData->dirtyState |= 6; -} - -void GXSetTevDirect(GXTevStageID tev_stage) { - CHECK_GXBEGIN(373, "GXSetTevDirect"); - GXSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); -} - -void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel) { - GXIndTexWrap wrap = (replace_mode != 0) ? GX_ITW_0 : GX_ITW_OFF; - - CHECK_GXBEGIN(395, "GXSetTevIndWarp"); - GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, (signed_offset != 0) ? GX_ITB_STU : GX_ITB_NONE, matrix_sel, wrap, wrap, GX_FALSE, GX_FALSE, GX_ITBA_OFF); -} - -void GXSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u16 tilesize_s, - u16 tilesize_t, u16 tilespacing_s, u16 tilespacing_t, GXIndTexFormat format, - GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, GXIndTexAlphaSel alpha_sel) -{ - GXIndTexWrap wrap_s; - GXIndTexWrap wrap_t; - f32 mtx[2][3]; - - CHECK_GXBEGIN(429, "GXSetTevIndTile"); - ASSERTMSGLINE(430, tev_stage < GX_MAX_TEVSTAGE, "GXSetTevIndTile: Invalid tev stage id"); - ASSERTMSGLINE(431, ind_stage < GX_MAX_INDTEXSTAGE, "GXSetTevIndTile: Invalid indirect stage id"); - - switch (tilesize_s) { - case 256: - wrap_s = GX_ITW_256; - break; - case 128: - wrap_s = GX_ITW_128; - break; - case 64: - wrap_s = GX_ITW_64; - break; - case 32: - wrap_s = GX_ITW_32; - break; - case 16: - wrap_s = GX_ITW_16; - break; - default: - ASSERTMSGLINE(440, 0, "GXSetTevIndTile: Invalid tilesize for S coordinate"); - wrap_s = GX_ITW_OFF; - break; - } - - switch (tilesize_t) { - case 256: - wrap_t = GX_ITW_256; - break; - case 128: - wrap_t = GX_ITW_128; - break; - case 64: - wrap_t = GX_ITW_64; - break; - case 32: - wrap_t = GX_ITW_32; - break; - case 16: - wrap_t = GX_ITW_16; - break; - default: - ASSERTMSGLINE(452, 0, "GXSetTevIndTile: Invalid tilesize for T coordinate"); - wrap_t = GX_ITW_OFF; - break; - } - - mtx[0][0] = tilespacing_s / 1024.0f; - mtx[0][1] = mtx[0][2] = 0.0f; - mtx[1][1] = tilespacing_t / 1024.0f; - mtx[1][0] = mtx[1][2] = 0.0f; - GXSetIndTexMtx(matrix_sel, mtx, 10); - GXSetTevIndirect(tev_stage, ind_stage, format, bias_sel, matrix_sel, wrap_s, wrap_t, GX_FALSE, GX_TRUE, alpha_sel); -} - -void GXSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { - GXIndTexMtxID sm; - GXIndTexMtxID tm; - - CHECK_GXBEGIN(492, "GXSetTevIndBumpST"); - - switch (matrix_sel) { - case GX_ITM_0: - sm = GX_ITM_S0; - tm = GX_ITM_T0; - break; - case GX_ITM_1: - sm = GX_ITM_S1; - tm = GX_ITM_T1; - break; - case GX_ITM_2: - sm = GX_ITM_S2; - tm = GX_ITM_T2; - break; - default: - ASSERTMSGLINE(509, 0, "GXSetTevIndBumpST: Invalid matrix selection"); - break; - } - - GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, GX_ITB_ST, sm, GX_ITW_0, GX_ITW_0, GX_FALSE, GX_FALSE, GX_ITBA_OFF); - GXSetTevIndirect(tev_stage + 1, ind_stage, GX_ITF_8, GX_ITB_ST, tm, GX_ITW_0, GX_ITW_0, GX_TRUE, GX_FALSE, GX_ITBA_OFF); - GXSetTevIndirect(tev_stage + 2, ind_stage, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_TRUE, GX_FALSE, GX_ITBA_OFF); -} - -void GXSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { - CHECK_GXBEGIN(561, "GXSetTevIndBumpXYZ"); - GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, GX_ITB_STU, matrix_sel, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); -} - -void GXSetTevIndRepeat(GXTevStageID tev_stage) { - CHECK_GXBEGIN(590, "GXSetTevIndRepeat"); - GXSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_0, GX_ITW_0, GX_TRUE, GX_FALSE, GX_ITBA_OFF); -} - -void __GXUpdateBPMask(void) {} - -void __GXSetIndirectMask(u32 mask) { - SET_REG_FIELD(664, __GXData->bpMask, 8, ~0xFF, mask); - - GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask); - __GXData->bpSentNot = 0; -} - -void __GXFlushTextureState(void) { - GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask); - __GXData->bpSentNot = 0; -} diff --git a/src/dolphin/gx/GXDisplayList.c b/src/dolphin/gx/GXDisplayList.c deleted file mode 100644 index 86ec49f..0000000 --- a/src/dolphin/gx/GXDisplayList.c +++ /dev/null @@ -1,99 +0,0 @@ -#include - -#include -#include - -#include "__gx.h" - -static __GXFifoObj DisplayListFifo; -static volatile __GXFifoObj* OldCPUFifo; -static GXData __savedGXdata; - -void GXBeginDisplayList(void* list, u32 size) { - __GXFifoObj* CPUFifo = (__GXFifoObj*)GXGetCPUFifo(); - - CHECK_GXBEGIN(137, "GXBeginDisplayList"); - ASSERTMSGLINE(138, !__GXData->inDispList, "GXBeginDisplayList: display list already in progress"); - ASSERTMSGLINE(139, (size & 0x1F) == 0, "GXBeginDisplayList: size is not 32 byte aligned"); - ASSERTMSGLINE(140, ((u32)list & 0x1F) == 0, "GXBeginDisplayList: list is not 32 byte aligned"); - - if (__GXData->dirtyState != 0) { - __GXSetDirtyState(); - } - - if (__GXData->dlSaveContext != 0) { - memcpy(&__savedGXdata, __GXData, sizeof(__savedGXdata)); - } - - DisplayListFifo.base = (u8*)list; - DisplayListFifo.top = (u8*)list + size - 4; - DisplayListFifo.size = size; - DisplayListFifo.count = 0; - DisplayListFifo.rdPtr = list; - DisplayListFifo.wrPtr = list; - __GXData->inDispList = 1; - GXSaveCPUFifo((GXFifoObj*)CPUFifo); - OldCPUFifo = CPUFifo; - GXSetCPUFifo((GXFifoObj*)&DisplayListFifo); - GXResetWriteGatherPipe(); -} - -u32 GXEndDisplayList(void) { - u32 ov; -#ifdef DEBUG - u32 reg; -#endif - BOOL enabled; - u32 cpenable; - - CHECK_GXBEGIN(195, "GXEndDisplayList"); - ASSERTMSGLINE(196, __GXData->inDispList == TRUE, "GXEndDisplayList: no display list in progress"); - GXFlush(); -#ifdef DEBUG - reg = GX_GET_PI_REG(5); - ov = (reg >> 26) & 1; -#else - ov = (GX_GET_PI_REG(5) >> 26) & 1; -#endif - __GXSaveCPUFifoAux(&DisplayListFifo); - ASSERTMSGLINE(213, !ov, "GXEndDisplayList: display list commands overflowed buffer"); - GXSetCPUFifo((GXFifoObj*)OldCPUFifo); - - if (__GXData->dlSaveContext != 0) { - enabled = OSDisableInterrupts(); - cpenable = __GXData->cpEnable; - memcpy(__GXData, &__savedGXdata, sizeof(*__GXData)); - __GXData->cpEnable = cpenable; - OSRestoreInterrupts(enabled); - } - - __GXData->inDispList = 0; - if (!ov) { - return DisplayListFifo.count; - } - - return 0; -} - -void GXCallDisplayList(void* list, u32 nbytes) { - CHECK_GXBEGIN(254, "GXCallDisplayList"); - ASSERTMSGLINE(255, !__GXData->inDispList, "GXCallDisplayList: display list already in progress"); - ASSERTMSGLINE(256, (nbytes & 0x1F) == 0, "GXCallDisplayList: nbytes is not 32 byte aligned"); - ASSERTMSGLINE(257, ((u32)list & 0x1F) == 0, "GXCallDisplayList: list is not 32 byte aligned"); - - if (__GXData->dirtyState != 0) { - __GXSetDirtyState(); - } - -#if DEBUG - __GXShadowDispList(list, nbytes); -#endif - - if (*(u32*)&__GXData->vNumNot == 0) { // checks both vNum and bpSent - __GXSendFlushPrim(); - } - - GX_WRITE_U8(GX_CMD_CALL_DL); - GX_WRITE_U32(list); - GX_WRITE_U32(nbytes); -} diff --git a/src/dolphin/gx/GXDraw.c b/src/dolphin/gx/GXDraw.c deleted file mode 100644 index 0ea0d0b..0000000 --- a/src/dolphin/gx/GXDraw.c +++ /dev/null @@ -1,551 +0,0 @@ -#include - -#include -#include - -#include "__gx.h" - -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/src/dolphin/gx/GXFifo.c b/src/dolphin/gx/GXFifo.c deleted file mode 100644 index 670de8d..0000000 --- a/src/dolphin/gx/GXFifo.c +++ /dev/null @@ -1,629 +0,0 @@ -#include -#include -#include -#include - -#include "__gx.h" - -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; - - ASSERTMSGLINE(LINE(542, 542, 546), realFifo != CPUFifo, "GXInitFifoBase: fifo is attached to CPU"); - ASSERTMSGLINE(LINE(544, 544, 548), realFifo != GPFifo, "GXInitFifoBase: fifo is attached to GP"); - ASSERTMSGLINE(LINE(546, 546, 550), ((u32)base & 0x1F) == 0, "GXInitFifoBase: base must be 32B aligned"); - ASSERTMSGLINE(LINE(548, 548, 552), base != NULL, "GXInitFifoBase: base pointer is NULL"); - ASSERTMSGLINE(LINE(550, 550, 554), (size & 0x1F) == 0, "GXInitFifoBase: size must be 32B aligned"); - ASSERTMSGLINE(LINE(552, 552, 556), size >= 0x10000, "GXInitFifoBase: fifo is not large enough"); - - realFifo->base = base; - realFifo->top = (u8*)base + size - 4; - realFifo->size = size; - realFifo->count = 0; - GXInitFifoLimits(fifo, size - 0x4000, (size >> 1) & ~0x1F); - GXInitFifoPtrs(fifo, base, base); -} - -void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr) { - __GXFifoObj* realFifo = (__GXFifoObj *)fifo; - BOOL enabled; - - ASSERTMSGLINE(LINE(592, 592, 596), realFifo != CPUFifo, "GXInitFifoPtrs: fifo is attached to CPU"); - ASSERTMSGLINE(LINE(594, 594, 598), realFifo != GPFifo, "GXInitFifoPtrs: fifo is attached to GP"); - ASSERTMSGLINE(LINE(596, 596, 600), ((u32)readPtr & 0x1F) == 0, "GXInitFifoPtrs: readPtr not 32B aligned"); - ASSERTMSGLINE(LINE(598, 598, 602), ((u32)writePtr & 0x1F) == 0, "GXInitFifoPtrs: writePtr not 32B aligned"); - ASSERTMSGLINE(LINE(601, 601, 605), realFifo->base <= readPtr && readPtr < realFifo->top, "GXInitFifoPtrs: readPtr not in fifo range"); - ASSERTMSGLINE(LINE(604, 604, 608), realFifo->base <= writePtr && writePtr < realFifo->top, "GXInitFifoPtrs: writePtr not in fifo range"); - - enabled = OSDisableInterrupts(); - realFifo->rdPtr = readPtr; - realFifo->wrPtr = writePtr; - realFifo->count = (u8*)writePtr - (u8*)readPtr; - if (realFifo->count < 0) { - realFifo->count += realFifo->size; - } - OSRestoreInterrupts(enabled); -} - -void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark) { - __GXFifoObj* realFifo = (__GXFifoObj*)fifo; - - ASSERTMSGLINE(LINE(641, 641, 645), realFifo != GPFifo, "GXInitFifoLimits: fifo is attached to GP"); - ASSERTMSGLINE(LINE(643, 643, 647), (hiWatermark & 0x1F) == 0, "GXInitFifoLimits: hiWatermark not 32B aligned"); - ASSERTMSGLINE(LINE(645, 645, 649), (loWatermark & 0x1F) == 0, "GXInitFifoLimits: loWatermark not 32B aligned"); - ASSERTMSGLINE(LINE(647, 647, 651), hiWatermark < realFifo->top - realFifo->base, "GXInitFifoLimits: hiWatermark too large"); - ASSERTMSGLINE(LINE(649, 649, 653), loWatermark < hiWatermark, "GXInitFifoLimits: hiWatermark below lo watermark"); - - realFifo->hiWatermark = hiWatermark; - realFifo->loWatermark = loWatermark; -} - -#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 GXSaveCPUFifo(GXFifoObj* fifo) { - __GXFifoObj* realFifo = (__GXFifoObj*)fifo; - ASSERTMSGLINE(LINE(835, 835, 900), realFifo == CPUFifo, "GXSaveCPUFifo: fifo is not attached to CPU"); - GXFlush(); - __GXSaveCPUFifoAux(realFifo); -} - -void __GXSaveCPUFifoAux(__GXFifoObj* realFifo) { - BOOL enabled = OSDisableInterrupts(); - -#if SDK_REVISION < 2 - realFifo->base = OSPhysicalToCached(GX_GET_PI_REG(3)); - realFifo->top = OSPhysicalToCached(GX_GET_PI_REG(4)); - realFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); -#else - __GXSaveFifoPIStat(realFifo); -#endif - - if (CPGPLinked) { -#if SDK_REVISION < 2 - SOME_MACRO1(realFifo); - SOME_MACRO2(realFifo); -#else - __GXSaveFifoCPStat(realFifo); -#endif - } else { - realFifo->count = (u8*)realFifo->wrPtr - (u8*)realFifo->rdPtr; - if (realFifo->count < 0) - realFifo->count += realFifo->size; - } - OSRestoreInterrupts(enabled); -} - -void GXSaveGPFifo(GXFifoObj* fifo) { - __GXFifoObj* realFifo = (__GXFifoObj*)fifo; -#if SDK_REVISION < 2 - u32 cpStatus; - u8 readIdle; - u32 temp; -#else - BOOL enabled = OSDisableInterrupts(); -#endif - -#if SDK_REVISION < 2 - ASSERTMSGLINE(908, realFifo == GPFifo, "GXSaveGPFifo: fifo is not attached to GP"); - cpStatus = *(u16*)__cpReg; - readIdle = GET_REG_FIELD(cpStatus, 1, 2); - ASSERTMSGLINE(915, readIdle, "GXSaveGPFifo: GP is not idle"); - - SOME_MACRO1(realFifo); - SOME_MACRO2(realFifo); -#else - __GXSaveFifoCPStat(realFifo); - if (CPGPLinked) { - __GXSaveFifoPIStat(realFifo); - } - OSRestoreInterrupts(enabled); -#endif -} - -void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, GXBool* brkpt) { - __GXData->cpStatus = GX_GET_CP_REG(0); - *overhi = GET_REG_FIELD(__GXData->cpStatus, 1, 0); - *underlow = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 1); - *readIdle = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 2); - *cmdIdle = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 3); - *brkpt = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 4); -} - -void GXGetFifoStatus(GXFifoObj* fifo, GXBool* overhi, GXBool* underflow, u32* fifoCount, GXBool* cpuWrite, GXBool* gpRead, GXBool* fifowrap) { - __GXFifoObj* realFifo = (__GXFifoObj*)fifo; - - *underflow = GX_FALSE; - *overhi = GX_FALSE; - *fifoCount = 0; - *fifowrap = GX_FALSE; - - if (realFifo == GPFifo) { - SOME_MACRO1(realFifo); - SOME_MACRO2(realFifo); - } - - if (realFifo == CPUFifo) { - GXFlush(); - __GXSaveCPUFifoAux(realFifo); - *fifowrap = (int)GET_REG_FIELD(GX_GET_PI_REG(5), 1, 26); - } - - *overhi = (realFifo->count > realFifo->hiWatermark); - *underflow = (realFifo->count < realFifo->loWatermark); - *fifoCount = (realFifo->count); - *cpuWrite = (CPUFifo == realFifo); - *gpRead = (GPFifo == realFifo); -} - -void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr) { - __GXFifoObj* realFifo = (__GXFifoObj*)fifo; - - if (realFifo == CPUFifo) { - realFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); - } - - if (realFifo == GPFifo) { - SOME_MACRO1(realFifo); - SOME_MACRO2(realFifo); - } else { - realFifo->count = (u8*)realFifo->wrPtr - (u8*)realFifo->rdPtr; - if (realFifo->count < 0) { - realFifo->count += realFifo->size; - } - } - - *readPtr = realFifo->rdPtr; - *writePtr = realFifo->wrPtr; -} - -void* GXGetFifoBase(const GXFifoObj* fifo) { - __GXFifoObj* realFifo = (__GXFifoObj*)fifo; - - return realFifo->base; -} - -u32 GXGetFifoSize(const GXFifoObj* fifo) { - __GXFifoObj* realFifo = (__GXFifoObj*)fifo; - - return realFifo->size; -} - -void GXGetFifoLimits(const GXFifoObj* fifo, u32* hi, u32* lo) { - __GXFifoObj* realFifo = (__GXFifoObj*)fifo; - - *hi = realFifo->hiWatermark; - *lo = realFifo->loWatermark; -} - -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); -} - -void __GXInsaneWatermark(void) { - __GXFifoObj* realFifo = GPFifo; - - realFifo->hiWatermark = realFifo->loWatermark + 512; - GX_SET_CP_REG(20, (realFifo->hiWatermark & 0x3FFFFFFF) & 0xFFFF); - GX_SET_CP_REG(21, (realFifo->hiWatermark & 0x3FFFFFFF) >> 16); -} - -void __GXCleanGPFifo(void) { - GXFifoObj dummyFifo; - GXFifoObj* gpFifo; - GXFifoObj* cpuFifo; - void* base; - - gpFifo = GXGetGPFifo(); - if (gpFifo == (GXFifoObj*)NULL) - return; - - cpuFifo = GXGetCPUFifo(); - base = GXGetFifoBase(gpFifo); - - dummyFifo = *gpFifo; - GXInitFifoPtrs(&dummyFifo, base, base); - GXSetGPFifo(&dummyFifo); - if (cpuFifo == gpFifo) { - GXSetCPUFifo(&dummyFifo); - } - GXInitFifoPtrs(gpFifo, base, base); - GXSetGPFifo(gpFifo); - if (cpuFifo == gpFifo) { - GXSetCPUFifo(cpuFifo); - } -} - -OSThread* GXSetCurrentGXThread(void) { - BOOL enabled; - OSThread* prev; - - enabled = OSDisableInterrupts(); - prev = __GXCurrentThread; - ASSERTMSGLINE(LINE(1377, 1377, 1434), !GXOverflowSuspendInProgress, "GXSetCurrentGXThread: Two threads cannot generate GX commands at the same time!"); - __GXCurrentThread = OSGetCurrentThread(); - OSRestoreInterrupts(enabled); - return prev; -} - -OSThread* GXGetCurrentGXThread(void) { - return __GXCurrentThread; -} - -GXFifoObj* GXGetCPUFifo(void) { - return (GXFifoObj*)CPUFifo; -} - -GXFifoObj* GXGetGPFifo(void) { - return (GXFifoObj*)GPFifo; -} - -u32 GXGetOverflowCount(void) { - return __GXOverflowCount; -} - -u32 GXResetOverflowCount(void) { - u32 oldcount; - - oldcount = __GXOverflowCount; - __GXOverflowCount = 0; - return oldcount; -} - -// NONMATCHING -volatile void* GXRedirectWriteGatherPipe(void* ptr) { - u32 reg = 0; - BOOL enabled = OSDisableInterrupts(); - - CHECK_GXBEGIN(LINE(1493, 1493, 1550), "GXRedirectWriteGatherPipe"); - ASSERTLINE(LINE(1494, 1494, 1551), OFFSET(ptr, 32) == 0); - ASSERTLINE(LINE(1496, 1496, 1553), !IsWGPipeRedirected); - -#if DEBUG - IsWGPipeRedirected = TRUE; -#endif - - GXFlush(); - while (PPCMfwpar() & 1) {} - PPCMtwpar((u32)OSUncachedToPhysical((void*)GXFIFO_ADDR)); - if (CPGPLinked) { - __GXFifoLink(0); - __GXWriteFifoIntEnable(0, 0); - } - CPUFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); - GX_SET_PI_REG(3, 0); - GX_SET_PI_REG(4, 0x04000000); - SET_REG_FIELD(LINE(1527, 1527, 1584), reg, 21, 5, ((u32)ptr & 0x3FFFFFFF) >> 5); - reg &= 0xFBFFFFFF; - GX_SET_PI_REG(5, reg); - - PPCSync(); - OSRestoreInterrupts(enabled); - return (volatile void *)GXFIFO_ADDR; -} - -// NONMATCHING -void GXRestoreWriteGatherPipe(void) { - u32 reg = 0; - u32 i; - BOOL enabled; - - ASSERTLINE(1552, IsWGPipeRedirected); - -#if DEBUG - IsWGPipeRedirected = FALSE; -#endif - - enabled = OSDisableInterrupts(); - for (i = 0; i < 31; i++) { - GXWGFifo.u8 = 0; - } - - PPCSync(); - while (PPCMfwpar() & 1) {} - PPCMtwpar((u32)OSUncachedToPhysical((void *)GXFIFO_ADDR)); - GX_SET_PI_REG(3, (u32)CPUFifo->base & 0x3FFFFFFF); - GX_SET_PI_REG(4, (u32)CPUFifo->top & 0x3FFFFFFF); - SET_REG_FIELD(1578, reg, 21, 5, ((u32)CPUFifo->wrPtr & 0x3FFFFFFF) >> 5); - reg &= 0xFBFFFFFF; - GX_SET_PI_REG(5, reg); - if (CPGPLinked) { - __GXWriteFifoIntReset(1, 1); - __GXWriteFifoIntEnable(1, 0); - __GXFifoLink(1); - } - - PPCSync(); - OSRestoreInterrupts(enabled); -} diff --git a/src/dolphin/gx/GXFrameBuf.c b/src/dolphin/gx/GXFrameBuf.c deleted file mode 100644 index d248566..0000000 --- a/src/dolphin/gx/GXFrameBuf.c +++ /dev/null @@ -1,603 +0,0 @@ -#include -#include - -#include "__gx.h" - -GXRenderModeObj GXNtsc240Ds = { - 1, - 640, 240, 240, - 40, 0, - 640, 480, - 0, - 0, - 0, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, - { 0, 0, 21, 22, 21, 0, 0 } -}; - -GXRenderModeObj GXNtsc240DsAa = { - 1, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } -}; - -GXRenderModeObj GXNtsc240Int = { - 0, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } -}; - -GXRenderModeObj GXNtsc240IntAa = { - 0, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } -}; - -GXRenderModeObj GXNtsc480IntDf = { - 0, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } -}; - -GXRenderModeObj GXNtsc480Int = { - 0, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } -}; - -GXRenderModeObj GXNtsc480IntAa = { - 0, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } -}; - -GXRenderModeObj GXNtsc480Prog = { - 2, 640, 480, 480, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } -}; - -GXRenderModeObj GXNtsc480ProgSoft = { - 2, 640, 480, 480, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } -}; - -GXRenderModeObj GXNtsc480ProgAa = { - 2, 640, 242, 480, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } -}; - -GXRenderModeObj GXMpal240Ds = {9, 640, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXMpal240DsAa = {9, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXMpal240Int = {8, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXMpal240IntAa = {8, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXMpal480IntDf = {8, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; -GXRenderModeObj GXMpal480Int = {8, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXMpal480IntAa = {8, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; -GXRenderModeObj GXPal264Ds = {5, 640, 264, 264, 40, 11, 640, 528, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXPal264DsAa = {5, 640, 264, 264, 40, 11, 640, 528, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXPal264Int = {4, 640, 264, 264, 40, 23, 640, 528, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXPal264IntAa = {4, 640, 264, 264, 40, 23, 640, 528, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXPal528IntDf = {4, 640, 528, 528, 40, 23, 640, 528, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; -GXRenderModeObj GXPal528Int = {4, 640, 528, 528, 40, 23, 640, 528, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXPal524IntAa = {4, 640, 264, 524, 40, 23, 640, 524, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; -GXRenderModeObj GXEurgb60Hz240Ds = {21, 640, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXEurgb60Hz240DsAa = {21, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXEurgb60Hz240Int = {20, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXEurgb60Hz240IntAa = {20, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXEurgb60Hz480IntDf = {20, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; -GXRenderModeObj GXEurgb60Hz480Int = {20, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXEurgb60Hz480IntAa = {20, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; -GXRenderModeObj GXRmHW = {1, 320, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; - -void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver) { - u16 hor2 = hor * 2; - u16 ver2 = ver * 2; - u32 verf; - u32 mode; - - if (rmin != rmout) { - *rmout = *rmin; - } - - mode = rmin->viTVmode & 3; - rmout->fbWidth = rmin->fbWidth - hor2; - verf = (ver2 * rmin->efbHeight) / (u32)rmin->xfbHeight; - rmout->efbHeight = rmin->efbHeight - verf; - if (rmin->xFBmode == VI_XFBMODE_SF && mode == 0) { - rmout->xfbHeight = rmin->xfbHeight - ver2 / 2; - } else { - rmout->xfbHeight = rmin->xfbHeight - ver2; - } - - rmout->viWidth = rmin->viWidth - hor2; - - if (mode == 1) { - rmout->viHeight = rmin->viHeight - (ver2 * 2); - } else { - rmout->viHeight = rmin->viHeight - ver2; - } - - rmout->viXOrigin = rmin->viXOrigin + hor; - rmout->viYOrigin = rmin->viYOrigin + ver; -} - -void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht) { - CHECK_GXBEGIN(1235, "GXSetDispCopySrc"); - - __GXData->cpDispSrc = 0; - SET_REG_FIELD(1238, __GXData->cpDispSrc, 10, 0, left); - SET_REG_FIELD(1239, __GXData->cpDispSrc, 10, 10, top); - SET_REG_FIELD(1239, __GXData->cpDispSrc, 8, 24, 0x49); - - __GXData->cpDispSize = 0; - SET_REG_FIELD(1243, __GXData->cpDispSize, 10, 0, wd - 1); - SET_REG_FIELD(1244, __GXData->cpDispSize, 10, 10, ht - 1); - SET_REG_FIELD(1244, __GXData->cpDispSize, 8, 24, 0x4A); -} - - -void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht) { - CHECK_GXBEGIN(1263, "GXSetTexCopySrc"); - - __GXData->cpTexSrc = 0; - SET_REG_FIELD(1266, __GXData->cpTexSrc, 10, 0, left); - SET_REG_FIELD(1267, __GXData->cpTexSrc, 10, 10, top); - SET_REG_FIELD(1267, __GXData->cpTexSrc, 8, 24, 0x49); - - __GXData->cpTexSize = 0; - SET_REG_FIELD(1271, __GXData->cpTexSize, 10, 0, wd - 1); - SET_REG_FIELD(1272, __GXData->cpTexSize, 10, 10, ht - 1); - SET_REG_FIELD(1272, __GXData->cpTexSize, 8, 24, 0x4A); -} - -void GXSetDispCopyDst(u16 wd, u16 ht) { - u16 stride; - - ASSERTMSGLINE(1293, (wd & 0xF) == 0, "GXSetDispCopyDst: Width must be a multiple of 16"); - CHECK_GXBEGIN(1294, "GXSetDispCopyDst"); - - stride = (int)wd * 2; - __GXData->cpDispStride = 0; - SET_REG_FIELD(1300, __GXData->cpDispStride, 10, 0, (stride >> 5) ); - SET_REG_FIELD(1300, __GXData->cpDispStride, 8, 24, 0x4D); -} - -void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap) { - u32 rowTiles; - u32 colTiles; - u32 cmpTiles; - u32 peTexFmt; - u32 peTexFmtH; - - CHECK_GXBEGIN(1327, "GXSetTexCopyDst"); - - __GXData->cpTexZ = 0; - peTexFmt = fmt & 0xF; - ASSERTMSGLINEV(1358, peTexFmt < 13, "%s: invalid texture format", "GXSetTexCopyDst"); - - if (fmt == GX_TF_Z16) { - peTexFmt = 0xB; - } - - switch (fmt) { - case GX_TF_I4: - case GX_TF_I8: - case GX_TF_IA4: - case GX_TF_IA8: - case GX_CTF_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; -} - -u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale) { - u32 iScale; - ASSERTMSGLINE(1486, yScale >= 1.0f, "GXGetNumXfbLines: Vertical scale must be >= 1.0"); - - iScale = (u32)(256.0f / yScale) & 0x1FF; - return __GXGetNumXfbLines(efbHeight, iScale); -} - -f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight) { - f32 fScale; - f32 yScale; - u32 iScale; - u32 tgtHt; - u32 realHt; - - ASSERTMSGLINE(1510, xfbHeight <= 1024, "GXGetYScaleFactor: Display copy only supports up to 1024 lines.\n"); - ASSERTMSGLINE(1512, efbHeight <= xfbHeight, "GXGetYScaleFactor: EFB height should not be greater than XFB height.\n"); - - 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; -} - -void GXReadBoundingBox(u16* left, u16* top, u16* right, u16* bottom) { - *left = GX_GET_PE_REG(8); - *top = GX_GET_PE_REG(10); - *right = GX_GET_PE_REG(9); - *bottom = GX_GET_PE_REG(11); -} diff --git a/src/dolphin/gx/GXGeometry.c b/src/dolphin/gx/GXGeometry.c deleted file mode 100644 index b41b70b..0000000 --- a/src/dolphin/gx/GXGeometry.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include - -#include "__gx.h" - -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/src/dolphin/gx/GXInit.c b/src/dolphin/gx/GXInit.c deleted file mode 100644 index 02fba28..0000000 --- a/src/dolphin/gx/GXInit.c +++ /dev/null @@ -1,570 +0,0 @@ -#include - -#include -#include -#include -#include - -#include "__gx.h" - -#if SDK_REVISION < 2 -#define BUILD_DATE "Apr 5 2004" -#define DBUILD_TIME "03:55:13" -#define RBUILD_TIME "04:13:58" -#else -#define BUILD_DATE "Nov 10 2004" -#define DBUILD_TIME "06:08:50" -#define RBUILD_TIME "06:27:12" -#endif - -#ifdef DEBUG -const char* __GXVersion = "<< Dolphin SDK - GX\tdebug build: "BUILD_DATE" "DBUILD_TIME" (0x2301) >>"; -#else -const char* __GXVersion = "<< Dolphin SDK - GX\trelease build: "BUILD_DATE" "RBUILD_TIME" (0x2301) >>"; -#endif - -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 void DisableWriteGatherPipe(void) { - u32 hid2 = PPCMfhid2(); - - hid2 &= ~0x40000000; - PPCMthid2(hid2); -} - -static GXTexRegion*__GXDefaultTexRegionCallback(const GXTexObj* t_obj, GXTexMapID id) { - GXTexFmt fmt; - u8 mm; - - fmt = GXGetTexObjFmt(t_obj); - mm = GXGetTexObjMipMap(t_obj); - id = (GXTexMapID)(id % GX_MAX_TEXMAP); - - switch (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); - -void __GXInitRevisionBits(void) { - u32 i; - - for (i = 0; i < 8; i++) { - s32 regAddr; - SOME_SET_REG_MACRO(__GXData->vatA[i], 1, 30, 1); - SOME_SET_REG_MACRO(__GXData->vatB[i], 1, 31, 1); - - GX_WRITE_U8(0x8); - GX_WRITE_U8(i | 0x80); - GX_WRITE_U32(__GXData->vatB[i]); - regAddr = i - 12; - } - - { - u32 reg1 = 0; - u32 reg2 = 0; - - SOME_SET_REG_MACRO(reg1, 1, 0, 1); - SOME_SET_REG_MACRO(reg1, 1, 1, 1); - SOME_SET_REG_MACRO(reg1, 1, 2, 1); - SOME_SET_REG_MACRO(reg1, 1, 3, 1); - SOME_SET_REG_MACRO(reg1, 1, 4, 1); - SOME_SET_REG_MACRO(reg1, 1, 5, 1); - GX_WRITE_XF_REG(0, reg1); - - SOME_SET_REG_MACRO(reg2, 1, 0, 1); - GX_WRITE_XF_REG(0x12, reg2); -#if DEBUG - __gxVerif->xfRegsDirty[0] = 0; -#endif - } - - { - u32 reg = 0; - SOME_SET_REG_MACRO(reg, 1, 0, 1); - SOME_SET_REG_MACRO(reg, 1, 1, 1); - SOME_SET_REG_MACRO(reg, 1, 2, 1); - SOME_SET_REG_MACRO(reg, 1, 3, 1); - SOME_SET_REG_MACRO(reg, 8, 24, 0x58); - GX_WRITE_RAS_REG(reg); - } -} - -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 : GX_DISABLE)); - - 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/src/dolphin/gx/GXLight.c b/src/dolphin/gx/GXLight.c deleted file mode 100644 index d1b005d..0000000 --- a/src/dolphin/gx/GXLight.c +++ /dev/null @@ -1,573 +0,0 @@ -#include -#include -#include - -#include "__gx.h" - -// GXLightObj private data -typedef struct { - u32 reserved[3]; - u32 Color; - f32 a[3]; - f32 k[3]; - f32 lpos[3]; - f32 ldir[3]; -} __GXLightObjInt_struct; - -void GXInitLightAttn(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(129, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(130, "GXInitLightAttn"); - obj->a[0] = a0; - obj->a[1] = a1; - obj->a[2] = a2; - obj->k[0] = k0; - obj->k[1] = k1; - obj->k[2] = k2; -} - -void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(143, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(144, "GXInitLightAttnA"); - obj->a[0] = a0; - obj->a[1] = a1; - obj->a[2] = a2; -} - -void GXGetLightAttnA(const GXLightObj* lt_obj, f32* a0, f32* a1, f32* a2) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(153, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(154, "GXGetLightAttnA"); - *a0 = obj->a[0]; - *a1 = obj->a[1]; - *a2 = obj->a[2]; -} - -void GXInitLightAttnK(GXLightObj* lt_obj, f32 k0, f32 k1, f32 k2) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(163, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(164, "GXInitLightAttnK"); - obj->k[0] = k0; - obj->k[1] = k1; - obj->k[2] = k2; -} - -void GXGetLightAttnK(const GXLightObj* lt_obj, f32* k0, f32* k1, f32* k2) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(173, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(174, "GXGetLightAttnK"); - *k0 = obj->k[0]; - *k1 = obj->k[1]; - *k2 = obj->k[2]; -} - -void GXInitLightSpot(GXLightObj* lt_obj, f32 cutoff, GXSpotFn spot_func) { - f32 a0, a1, a2; - f32 r; - f32 d; - f32 cr; - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(198, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(200, "GXInitLightSpot"); - - if (cutoff <= 0.0f || cutoff > 90.0f) - spot_func = GX_SP_OFF; - - r = (3.1415927f * cutoff) / 180.0f; - cr = cosf(r); - - switch (spot_func) { - case GX_SP_FLAT: - 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; - - ASSERTMSGLINE(273, lt_obj != NULL, "Light Object Pointer is null"); - 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; - - ASSERTMSGLINE(328, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(330, "GXInitLightPos"); - - obj->lpos[0] = x; - obj->lpos[1] = y; - obj->lpos[2] = z; -} - -void GXGetLightPos(const GXLightObj* lt_obj, f32* x, f32* y, f32* z) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(339, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(341, "GXGetLightPos"); - - *x = obj->lpos[0]; - *y = obj->lpos[1]; - *z = obj->lpos[2]; -} - -void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(360, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - - obj->ldir[0] = -nx; - obj->ldir[1] = -ny; - obj->ldir[2] = -nz; -} - -void GXGetLightDir(const GXLightObj* lt_obj, f32* nx, f32* ny, f32* nz) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(372, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - - *nx = -obj->ldir[0]; - *ny = -obj->ldir[1]; - *nz = -obj->ldir[2]; -} - -void GXInitSpecularDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) { - f32 mag; - f32 vx; - f32 vy; - f32 vz; - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(398, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(399, "GXInitSpecularDir"); - - vx = -nx; - vy = -ny; - vz = -nz + 1.0f; - - mag = (vx * vx) + (vy * vy) + (vz * vz); - if (mag != 0.0f) { - mag = 1.0f / sqrtf(mag); - } - - obj->ldir[0] = vx * mag; - obj->ldir[1] = vy * mag; - obj->ldir[2] = vz * mag; - obj->lpos[0] = nx * -1000000000000000000.0f; - obj->lpos[1] = ny * -1000000000000000000.0f; - obj->lpos[2] = nz * -1000000000000000000.0f; -} - -void GXInitSpecularDirHA(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(436, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(437, "GXInitSpecularHA"); - - obj->ldir[0] = hx; - obj->ldir[1] = hy; - obj->ldir[2] = hz; - obj->lpos[0] = nx * -1000000000000000000.0f; - obj->lpos[1] = ny * -1000000000000000000.0f; - obj->lpos[2] = nz * -1000000000000000000.0f; -} - -void GXInitLightColor(GXLightObj* lt_obj, GXColor color) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(462, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(463, "GXInitLightColor"); - - *(u32*)&obj->Color = *(u32*)&color; -} - -void GXGetLightColor(const GXLightObj* lt_obj, GXColor* color) { - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(476, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(477, "GXGetLightColor"); - - *(u32*)color = *(u32*)&obj->Color; -} - -#if DEBUG -#define WRITE_SOME_LIGHT_REG1(val, addr) \ -do { \ - u32 xfData = val; \ - GX_WRITE_U32(val); \ - VERIF_MTXLIGHT(addr, xfData); \ -} while (0) - -#define WRITE_SOME_LIGHT_REG2(val, addr) \ -do { \ - f32 xfData = val; \ - GX_WRITE_F32(val); \ - VERIF_MTXLIGHT(addr, *(u32 *)&xfData); \ -} while (0) -#else -#define WRITE_SOME_LIGHT_REG1(val, addr) GX_WRITE_U32(val) -#define WRITE_SOME_LIGHT_REG2(val, addr) GX_WRITE_F32(val) -#endif - -static inline u32 ConvLightID2Num(GXLightID id) { - switch (id) { - case GX_LIGHT0: return 0; - case GX_LIGHT1: return 1; - case GX_LIGHT2: return 2; - case GX_LIGHT3: return 3; - case GX_LIGHT4: return 4; - case GX_LIGHT5: return 5; - case GX_LIGHT6: return 6; - case GX_LIGHT7: return 7; - default: return 8; - } -} - -static inline void PushLight(const register GXLightObj* lt_obj, register void* dest) { - 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(const GXLightObj* lt_obj, GXLightID light) { - u32 addr; - u32 idx; - __GXLightObjInt_struct* obj; - - ASSERTMSGLINE(568, lt_obj != NULL, "Light Object Pointer is null"); - obj = (__GXLightObjInt_struct*)lt_obj; - CHECK_GXBEGIN(569, "GXLoadLightObjImm"); - -#if DEBUG - idx = ConvLightID2Num(light); -#else - idx = 31 - __cntlzw(light); -#endif - - ASSERTMSGLINE(575, idx < 8, "GXLoadLightObjImm: Invalid Light Id"); - idx &= 7; - - addr = 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; -} - -void GXLoadLightObjIndx(u32 lt_obj_indx, GXLightID light) { - u32 reg; - u32 addr; - u32 idx; - - CHECK_GXBEGIN(624, "GXLoadLightObjIndx"); - -#if DEBUG - idx = ConvLightID2Num(light); -#else - idx = 31 - __cntlzw(light); -#endif - - ASSERTMSGLINE(627, idx < 8, "GXLoadLightObjIndx: Invalid Light Id"); - idx &= 7; - - addr = idx * 0x10 + 0x600; - reg = 0; - SET_REG_FIELD(632, reg, 12, 0, addr); - SET_REG_FIELD(634, reg, 4, 12, 0xF); - SET_REG_FIELD(634, reg, 16, 16, lt_obj_indx); - GX_WRITE_U8(0x38); - GX_WRITE_U32(reg); -#if DEBUG - __GXShadowIndexState(7, reg); -#endif - __GXData->bpSentNot = 1; -} - -#define GXCOLOR_AS_U32(color) (*((u32*)&(color))) - -void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color) { - u32 reg; - u32 rgb; - u32 colIdx; - - CHECK_GXBEGIN(661, "GXSetChanAmbColor"); - - switch (chan) { - case GX_COLOR0: - reg = __GXData->ambColor[GX_COLOR0]; - 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: - ASSERTMSGLINE(731, 0, "GXSetChanAmbColor: Invalid Channel Id"); - 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: - ASSERTMSGLINE(832, 0, "GXSetChanMatColor: Invalid Channel Id"); - return; - } - - GX_WRITE_XF_REG(colIdx + 12, reg); - __GXData->bpSentNot = 1; - __GXData->matColor[colIdx] = reg; -} - -void GXSetNumChans(u8 nChans) { - CHECK_GXBEGIN(857, "GXSetNumChans"); - ASSERTMSGLINE(858, nChans <= 2, "GXSetNumChans: nChans > 2"); - - SET_REG_FIELD(860, __GXData->genMode, 3, 4, nChans); - GX_WRITE_XF_REG(9, nChans); - __GXData->dirtyState |= 4; -} - -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"); - - ASSERTMSGLINE(895, chan >= GX_COLOR0 && chan <= GX_COLOR1A1, "GXSetChanCtrl: Invalid Channel Id"); - -#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/src/dolphin/gx/GXMisc.c b/src/dolphin/gx/GXMisc.c deleted file mode 100644 index 3c30698..0000000 --- a/src/dolphin/gx/GXMisc.c +++ /dev/null @@ -1,481 +0,0 @@ -#include -#include -#include -#include - -#include "__gx.h" - -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: - ASSERTMSGLINE(223, !__GXData->inDispList, "GXSetMisc: Cannot change DL context setting while making a display list"); - __GXData->dlSaveContext = (val != 0); - break; - case GX_MT_ABORT_WAIT_COPYOUT: - __GXData->abtWaitPECopy = (val != 0); - break; - case GX_MT_NULL: - break; - default: -#if DEBUG - OSReport("GXSetMisc: bad token %d (val %d)\n", token, val); -#endif - break; - } -} - -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(); -} - -void GXResetWriteGatherPipe(void) { - while (PPCMfwpar() & 1) { - } - PPCMtwpar(OSUncachedToPhysical((void *)GXFIFO_ADDR)); -} - -static void __GXAbortWait(u32 clocks) { - OSTime time0; - OSTime time1; - - time0 = OSGetTime(); - do { - time1 = OSGetTime(); - } while (time1 - time0 <= (clocks / 4)); -} - -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 GXAbortFrame(void) { - __GXAbort(); - - if (GXGetGPFifo() != (GXFifoObj*)NULL) { - __GXCleanGPFifo(); - __GXInitRevisionBits(); - __GXData->dirtyState = 0; - GXFlush(); - } -} - -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) { - CHECK_GXBEGIN(566, "GXDrawDone"); - GXSetDrawDone(); - GXWaitDrawDone(); -} - -void GXPixModeSync(void) { - CHECK_GXBEGIN(601, "GXPixModeSync"); - GX_WRITE_RAS_REG(__GXData->peCtrl); - __GXData->bpSentNot = 0; -} - -void GXTexModeSync(void) { - u32 reg; - - CHECK_GXBEGIN(625, "GXTexModeSync"); - reg = 0x63000000; - GX_WRITE_RAS_REG(reg); - __GXData->bpSentNot = 0; -} - -#if DEBUG -void __GXBypass(u32 reg) { - CHECK_GXBEGIN(647, "__GXBypass"); - GX_WRITE_RAS_REG(reg); - __GXData->bpSentNot = 0; -} - -u16 __GXReadPEReg(u32 reg) { - return GX_GET_PE_REG(reg); -} -#endif - -void GXPokeAlphaMode(GXCompare func, u8 threshold) { - u32 reg; - - reg = (func << 8) | threshold; - GX_SET_PE_REG(3, reg); -} - -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); -} - -void GXPeekARGB(u16 x, u16 y, u32* color) { - u32 addr = (u32)OSPhysicalToUncached(0x08000000); - - SET_REG_FIELD(792, addr, 10, 2, x); - SET_REG_FIELD(793, addr, 10, 12, y); - SET_REG_FIELD(793, addr, 2, 22, 0); - *color = *(u32*)addr; -} - -void GXPokeARGB(u16 x, u16 y, u32 color) { - u32 addr = (u32)OSPhysicalToUncached(0x08000000); - - SET_REG_FIELD(0x322, addr, 10, 2, x); - SET_REG_FIELD(0x323, addr, 10, 12, y); - SET_REG_FIELD(0x323, addr, 2, 22, 0); - *(u32*)addr = color; -} - -void GXPeekZ(u16 x, u16 y, u32* z) { - u32 addr = (u32)OSPhysicalToUncached(0x08000000); - - SET_REG_FIELD(812, addr, 10, 2, x); - SET_REG_FIELD(813, addr, 10, 12, y); - SET_REG_FIELD(813, addr, 2, 22, 1); - *z = *(u32*)addr; -} - -void GXPokeZ(u16 x, u16 y, u32 z) { - u32 addr = (u32)OSPhysicalToUncached(0x08000000); - - SET_REG_FIELD(822, addr, 10, 2, x); - SET_REG_FIELD(823, addr, 10, 12, y); - SET_REG_FIELD(823, addr, 2, 22, 1); - *(u32*)addr = z; -} - -GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb) { - GXDrawSyncCallback oldcb; - BOOL enabled; - - oldcb = TokenCB; - enabled = OSDisableInterrupts(); - TokenCB = cb; - OSRestoreInterrupts(enabled); - return oldcb; -} - -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); -} - -u32 GXCompressZ16(u32 z24, GXZFmt16 zfmt) { - u32 z16; - u32 z24n; - s32 exp; - s32 shift; -#if DEBUG -#define temp exp -#else - s32 temp; - u8 unused[4]; -#endif - - z24n = ~(z24 << 8); - temp = __cntlzw(z24n); - switch (zfmt) { - case GX_ZC_LINEAR: - z16 = (z24 >> 8) & 0xFFFF; - break; - case GX_ZC_NEAR: - if (temp > 3) { - exp = 3; - } else { - exp = temp; - } - if (exp == 3) { - shift = 7; - } else { - shift = 9 - exp; - } - z16 = ((z24 >> shift) & 0x3FFF & ~0xFFFFC000) | (exp << 14); - break; - case GX_ZC_MID: - if (temp > 7) { - exp = 7; - } else { - exp = temp; - } - if (exp == 7) { - shift = 4; - } else { - shift = 10 - exp; - } - z16 = ((z24 >> shift) & 0x1FFF & ~0xFFFFE000) | (exp << 13); - break; - case GX_ZC_FAR: - if (temp > 12) { - exp = 12; - } else { - exp = temp; - } - if (exp == 12) { - shift = 0; - } else { - shift = 11 - exp; - } - z16 = ((z24 >> shift) & 0xFFF & ~0xFFFFF000) | (exp << 12); - break; - default: - OSPanic(__FILE__, 1004, "GXCompressZ16: Invalid Z format\n"); - break; - } - return z16; -} - -u32 GXDecompressZ16(u32 z16, GXZFmt16 zfmt) { - u32 z24; - u32 cb1; - s32 exp; - s32 shift; - - cb1; cb1; cb1; z16; z16; z16; // needed to match - - switch (zfmt) { - case GX_ZC_LINEAR: - z24 = (z16 << 8) & 0xFFFF00; - break; - case GX_ZC_NEAR: - exp = (z16 >> 14) & 3; - if (exp == 3) { - shift = 7; - } else { - shift = 9 - exp; - } - cb1 = -1 << (24 - exp); - z24 = (cb1 | ((z16 & 0x3FFF) << shift)) & 0xFFFFFF; - break; - case GX_ZC_MID: - exp = (z16 >> 13) & 7; - if (exp == 7) { - shift = 4; - } else { - shift = 10 - exp; - } - cb1 = -1 << (24 - exp); - z24 = (cb1 | ((z16 & 0x1FFF) << shift)) & 0xFFFFFF; - break; - case GX_ZC_FAR: - exp = (z16 >> 12) & 0xF; - if (exp == 12) { - shift = 0; - } else { - shift = 11 - exp; - } - cb1 = -1 << (24 - exp); - z24 = (cb1 | ((z16 & 0xFFF) << shift)) & 0xFFFFFF; - break; - default: - OSPanic(__FILE__, 1054, "GXDecompressZ16: Invalid Z format\n"); - break; - } - return z24; -} diff --git a/src/dolphin/gx/GXPerf.c b/src/dolphin/gx/GXPerf.c deleted file mode 100644 index 9a850ee..0000000 --- a/src/dolphin/gx/GXPerf.c +++ /dev/null @@ -1,431 +0,0 @@ -#include -#include - -#include "__gx.h" - -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: - ASSERTMSGLINE(194, 0, "GXSetGPMetric: Invalid GXPerf0 metric name"); - 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: - ASSERTMSGLINE(244, 0, "GXSetGPMetric: Invalid GXPerf1 metric name"); - break; - } - - __GXData->perf0 = perf0; - switch (__GXData->perf0) { - case GX_PERF0_VERTICES: - ASSERTMSGLINE(258, 0, "The use of GX_PERF0_VERTICES is prohibited. Use GX_PERF1_VERTICES instead.\n"); - reg = 0x273; - GX_WRITE_XF_REG(6, reg); - break; - case GX_PERF0_CLIP_VTX: reg = 0x14A; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_CLIP_CLKS: reg = 0x16B; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_XF_WAIT_IN: reg = 0x84; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_XF_WAIT_OUT: reg = 0xC6; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_XF_XFRM_CLKS: reg = 0x210; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_XF_LIT_CLKS: reg = 0x252; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_XF_BOT_CLKS: reg = 0x231; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_XF_REGLD_CLKS: reg = 0x1AD; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_XF_REGRD_CLKS: reg = 0x1CE; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_CLOCKS: reg = 0x21; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_CLIP_RATIO: reg = 0x153; GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_TRIANGLES: reg = 0x2300AE7F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_CULLED: reg = 0x23008E7F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_PASSED: reg = 0x23009E7F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_SCISSORED: reg = 0x23001E7F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_0TEX: reg = 0x2300AC3F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_1TEX: reg = 0x2300AC7F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_2TEX: reg = 0x2300ACBF; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_3TEX: reg = 0x2300ACFF; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_4TEX: reg = 0x2300AD3F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_5TEX: reg = 0x2300AD7F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_6TEX: reg = 0x2300ADBF; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_7TEX: reg = 0x2300ADFF; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_8TEX: reg = 0x2300AE3F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_0CLR: reg = 0x2300A27F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_1CLR: reg = 0x2300A67F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_TRIANGLES_2CLR: reg = 0x2300AA7F; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_QUAD_0CVG: reg = 0x2402C0C6; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_QUAD_NON0CVG: reg = 0x2402C16B; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_QUAD_1CVG: reg = 0x2402C0E7; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_QUAD_2CVG: reg = 0x2402C108; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_QUAD_3CVG: reg = 0x2402C129; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_QUAD_4CVG: reg = 0x2402C14A; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_AVG_QUAD_CNT: reg = 0x2402C1AD; GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_NONE: break; - default: - ASSERTMSGLINE(504, 0, "GXSetGPMetric: Invalid GXPerf0 metric name"); - break; - } - - __GXData->perf1 = perf1; - switch (__GXData->perf1) { - case GX_PERF1_TEXELS: reg = 0x67000042; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_TX_IDLE: reg = 0x67000084; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_TX_REGS: reg = 0x67000063; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_TX_MEMSTALL: reg = 0x67000129; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_TC_MISS: reg = 0x67000252; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_CLOCKS: reg = 0x67000021; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_TC_CHECK1_2: reg = 0x6700014B; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_TC_CHECK3_4: reg = 0x6700018D; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_TC_CHECK5_6: reg = 0x670001CF; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_TC_CHECK7_8: reg = 0x67000211; GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_VC_ELEMQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 2); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_VC_MISSQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 3); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_VC_MEMREQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 4); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_VC_STATUS7: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 5); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_VC_MISSREP_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 6); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_VC_STREAMBUF_LOW: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 7); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_VC_ALL_STALLS: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 9); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_VERTICES: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 8); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_FIFO_REQ: reg = 2; GX_SET_CP_REG(3, reg); break; - case GX_PERF1_CALL_REQ: reg = 3; GX_SET_CP_REG(3, reg); break; - case GX_PERF1_VC_MISS_REQ: reg = 4; GX_SET_CP_REG(3, reg); break; - case GX_PERF1_CP_ALL_REQ: reg = 5; GX_SET_CP_REG(3, reg); break; - case GX_PERF1_NONE: break; - default: - ASSERTMSGLINE(649, 0, "GXSetGPMetric: Invalid GXPerf1 metric name"); - break; - } - - __GXData->bpSentNot = 0; -} - -#pragma scheduling off -void GXReadGPMetric(u32* cnt0, u32* cnt1) { - u32 cpCtr0, cpCtr1, cpCtr2, cpCtr3; - - cpCtr0 = __GXReadCPCounterU32(32, 33); - cpCtr1 = __GXReadCPCounterU32(34, 35); - cpCtr2 = __GXReadCPCounterU32(36, 37); - cpCtr3 = __GXReadCPCounterU32(38, 39); - - switch (__GXData->perf0) { - case GX_PERF0_CLIP_RATIO: - *cnt0 = cpCtr1 * 1000 / cpCtr0; - break; - case GX_PERF0_VERTICES: - case GX_PERF0_CLIP_VTX: - case GX_PERF0_CLIP_CLKS: - case GX_PERF0_XF_WAIT_IN: - case GX_PERF0_XF_WAIT_OUT: - case GX_PERF0_XF_XFRM_CLKS: - case GX_PERF0_XF_LIT_CLKS: - case GX_PERF0_XF_BOT_CLKS: - case GX_PERF0_XF_REGLD_CLKS: - case GX_PERF0_XF_REGRD_CLKS: - case GX_PERF0_TRIANGLES: - case GX_PERF0_TRIANGLES_CULLED: - case GX_PERF0_TRIANGLES_PASSED: - case GX_PERF0_TRIANGLES_SCISSORED: - case GX_PERF0_TRIANGLES_0TEX: - case GX_PERF0_TRIANGLES_1TEX: - case GX_PERF0_TRIANGLES_2TEX: - case GX_PERF0_TRIANGLES_3TEX: - case GX_PERF0_TRIANGLES_4TEX: - case GX_PERF0_TRIANGLES_5TEX: - case GX_PERF0_TRIANGLES_6TEX: - case GX_PERF0_TRIANGLES_7TEX: - case GX_PERF0_TRIANGLES_8TEX: - case GX_PERF0_TRIANGLES_0CLR: - case GX_PERF0_TRIANGLES_1CLR: - case GX_PERF0_TRIANGLES_2CLR: - case GX_PERF0_QUAD_0CVG: - case GX_PERF0_QUAD_NON0CVG: - case GX_PERF0_QUAD_1CVG: - case GX_PERF0_QUAD_2CVG: - case GX_PERF0_QUAD_3CVG: - case GX_PERF0_QUAD_4CVG: - case GX_PERF0_AVG_QUAD_CNT: - case GX_PERF0_CLOCKS: - *cnt0 = cpCtr0; - break; - case GX_PERF0_NONE: - *cnt0 = 0; - break; - default: - ASSERTMSGLINE(765, 0, "GXReadGPMetric: Invalid GXPerf0 metric name"); - *cnt0 = 0; - break; - } - - switch (__GXData->perf1) { - case GX_PERF1_TEXELS: - *cnt1 = cpCtr3 * 4; - break; - case GX_PERF1_TC_CHECK1_2: - *cnt1 = cpCtr2 + (cpCtr3 * 2); - break; - case GX_PERF1_TC_CHECK3_4: - *cnt1 = (cpCtr2 * 3) + (cpCtr3 * 4); - break; - case GX_PERF1_TC_CHECK5_6: - *cnt1 = (cpCtr2 * 5) + (cpCtr3 * 6); - break; - case GX_PERF1_TC_CHECK7_8: - *cnt1 = (cpCtr2 * 7) + (cpCtr3 * 8); - break; - case GX_PERF1_TX_IDLE: - case GX_PERF1_TX_REGS: - case GX_PERF1_TX_MEMSTALL: - case GX_PERF1_TC_MISS: - case GX_PERF1_VC_ELEMQ_FULL: - case GX_PERF1_VC_MISSQ_FULL: - case GX_PERF1_VC_MEMREQ_FULL: - case GX_PERF1_VC_STATUS7: - case GX_PERF1_VC_MISSREP_FULL: - case GX_PERF1_VC_STREAMBUF_LOW: - case GX_PERF1_VC_ALL_STALLS: - case GX_PERF1_VERTICES: - case GX_PERF1_CLOCKS: - *cnt1 = cpCtr3; - break; - case GX_PERF1_FIFO_REQ: - case GX_PERF1_CALL_REQ: - case GX_PERF1_VC_MISS_REQ: - case GX_PERF1_CP_ALL_REQ: - *cnt1 = cpCtr2; - break; - case GX_PERF1_NONE: - *cnt1 = 0; - break; - default: - ASSERTMSGLINE(824, 0, "GXReadGPMetric: Invalid GXPerf1 metric name"); - *cnt1 = 0; - break; - } -} -#pragma scheduling reset - -void GXClearGPMetric(void) { - u32 reg; - - reg = 4; - GX_SET_CP_REG(2, reg); -} - -u32 GXReadGP0Metric(void) { - u32 cnt0, cnt1; - - GXReadGPMetric(&cnt0, &cnt1); - return cnt0; -} - -u32 GXReadGP1Metric(void) { - u32 cnt0, cnt1; - - GXReadGPMetric(&cnt0, &cnt1); - return cnt1; -} - -#pragma scheduling off -void GXReadMemMetric(u32* cp_req, u32* tc_req, u32* cpu_rd_req, u32* cpu_wr_req, u32* dsp_req, u32* io_req, u32* vi_req, u32* pe_req, u32* rf_req, u32* fi_req) { - *cp_req = __GXReadMEMCounterU32(26, 25); - *tc_req = __GXReadMEMCounterU32(28, 27); - *cpu_rd_req = __GXReadMEMCounterU32(30, 29); - *cpu_wr_req = __GXReadMEMCounterU32(32, 31); - *dsp_req = __GXReadMEMCounterU32(34, 33); - *io_req = __GXReadMEMCounterU32(36, 35); - *vi_req = __GXReadMEMCounterU32(38, 37); - *pe_req = __GXReadMEMCounterU32(40, 39); - *rf_req = __GXReadMEMCounterU32(42, 41); - *fi_req = __GXReadMEMCounterU32(44, 43); -} -#pragma scheduling reset - -void GXClearMemMetric(void) { - GX_SET_MEM_REG(25, 0); - GX_SET_MEM_REG(26, 0); - GX_SET_MEM_REG(27, 0); - GX_SET_MEM_REG(28, 0); - GX_SET_MEM_REG(30, 0); - GX_SET_MEM_REG(29, 0); - GX_SET_MEM_REG(32, 0); - GX_SET_MEM_REG(31, 0); - GX_SET_MEM_REG(34, 0); - GX_SET_MEM_REG(33, 0); - GX_SET_MEM_REG(36, 0); - GX_SET_MEM_REG(35, 0); - GX_SET_MEM_REG(38, 0); - GX_SET_MEM_REG(37, 0); - GX_SET_MEM_REG(40, 0); - GX_SET_MEM_REG(39, 0); - GX_SET_MEM_REG(42, 0); - GX_SET_MEM_REG(41, 0); - GX_SET_MEM_REG(44, 0); - GX_SET_MEM_REG(43, 0); -} - -#pragma scheduling off -void GXReadPixMetric(u32* top_pixels_in, u32* top_pixels_out, u32* bot_pixels_in, u32* bot_pixels_out, u32* clr_pixels_in, u32* copy_clks) { - *top_pixels_in = __GXReadPECounterU32(12, 13) * 4; - *top_pixels_out = __GXReadPECounterU32(14, 15) * 4; - *bot_pixels_in = __GXReadPECounterU32(16, 17) * 4; - *bot_pixels_out = __GXReadPECounterU32(18, 19) * 4; - *clr_pixels_in = __GXReadPECounterU32(20, 21) * 4; - *copy_clks = __GXReadPECounterU32(22, 23); -} -#pragma scheduling reset - -void GXClearPixMetric(void) { - u32 reg; - - CHECK_GXBEGIN(1163, "GXClearPixMetric"); - - reg = 0x57000000; - GX_WRITE_RAS_REG(reg); - reg = 0x57000AAA; - GX_WRITE_RAS_REG(reg); - __GXData->bpSentNot = 0; -} - -void GXSetVCacheMetric(GXVCachePerf attr) { - u32 reg; - - SET_REG_FIELD(1194, __GXData->perfSel, 4, 0, attr); - GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); - reg = 1; - GX_WRITE_SOME_REG4(8, 0x10, reg, -12); -} - -#pragma scheduling off -void GXReadVCacheMetric(u32* check, u32* miss, u32* stall) { - *check = __GXReadCPCounterU32(40, 41); - *miss = __GXReadCPCounterU32(42, 43); - *stall = __GXReadCPCounterU32(44, 45); -} -#pragma scheduling reset - -void GXClearVCacheMetric(void) { - GX_WRITE_SOME_REG4(8, 0, 0, -12); -} - -void GXInitXfRasMetric(void) { - u32 reg; - - CHECK_GXBEGIN(1293, "GXInitXfRasMetric"); - - reg = 0x2402C022; - GX_WRITE_RAS_REG(reg); - reg = 0x31000; - GX_WRITE_XF_REG(6, reg); - __GXData->bpSentNot = 1; -} - -#pragma scheduling off -void GXReadXfRasMetric(u32* xf_wait_in, u32* xf_wait_out, u32* ras_busy, u32* clocks) { - *ras_busy = __GXReadCPCounterU32(32, 33); - *clocks = __GXReadCPCounterU32(34, 35); - *xf_wait_in = __GXReadCPCounterU32(36, 37); - *xf_wait_out = __GXReadCPCounterU32(38, 39); -} -#pragma scheduling reset - -u32 GXReadClksPerVtx(void) { - u32 perfCnt; - u32 ctrh; - - GXDrawDone(); - GX_SET_CP_REG(49, 0x1007); - GX_SET_CP_REG(48, 0x1007); - - ctrh = GX_GET_CP_REG(50); - perfCnt = ctrh >> 8; - return perfCnt; -} - -void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial) { - __MEMRegs[9] = cpDial; - __MEMRegs[10] = tcDial; - __MEMRegs[11] = peDial; - __MEMRegs[12] = cpuRdDial; - __MEMRegs[13] = cpuWrDial; -} diff --git a/src/dolphin/gx/GXPixel.c b/src/dolphin/gx/GXPixel.c deleted file mode 100644 index 027276c..0000000 --- a/src/dolphin/gx/GXPixel.c +++ /dev/null @@ -1,334 +0,0 @@ -#include -#include -#include - -#include "__gx.h" - -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"); - - ASSERTMSGLINE(140, farz >= 0.0f, "GXSetFog: The farz should be positive value"); - ASSERTMSGLINE(141, farz >= nearz, "GXSetFog: The farz should be larger than nearz"); - - fsel = type & 7; - proj = (type >> 3) & 1; - - if (proj) { - if (farz == nearz || endz == startz) { - a = 0.0f; - c = 0.0f; - } else { - A = (1.0f / (endz - startz)); - 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 GXSetFogColor(GXColor color) { - u32 rgba; - u32 fogclr = 0xF2000000; - - rgba = *(u32*)&color; - SET_REG_FIELD(250, fogclr, 24, 0, rgba >> 8); - GX_WRITE_RAS_REG(fogclr); - __GXData->bpSentNot = 0; -} - -void GXInitFogAdjTable(GXFogAdjTable *table, u16 width, const f32 projmtx[4][4]) { - f32 xi; - f32 iw; - f32 rangeVal; - f32 nearZ; - f32 sideX; - u32 i; - - CHECK_GXBEGIN(275, "GXInitFogAdjTable"); - ASSERTMSGLINE(276, table != NULL, "GXInitFogAdjTable: table pointer is null"); - ASSERTMSGLINE(277, width <= 640, "GXInitFogAdjTable: invalid width value"); - - if (0.0 == projmtx[3][3]) { - nearZ = projmtx[2][3] / (projmtx[2][2] - 1.0f); - sideX = nearZ / projmtx[0][0]; - } else { - sideX = 1.0f / projmtx[0][0]; - nearZ = 1.73205f * sideX; - } - - iw = 2.0f / width; - for (i = 0; i < 10; i++) { - xi = (i + 1) << 5; - xi *= iw; - xi *= sideX; - rangeVal = sqrtf(1.0f + ((xi * xi) / (nearZ * nearZ))); - table->r[i] = (u32)(256.0f * rangeVal) & 0xFFF; - } -} - -void GXSetFogRangeAdj(GXBool enable, u16 center, const GXFogAdjTable *table) { - u32 i; - u32 range_adj; - u32 range_c; - - CHECK_GXBEGIN(331, "GXSetFogRangeAdj"); - - if (enable) { - ASSERTMSGLINE(334, table != NULL, "GXSetFogRangeAdj: table pointer is null"); - for (i = 0; i < 10; i += 2) { - range_adj = 0; - SET_REG_FIELD(338, range_adj, 12, 0, table->r[i]); - SET_REG_FIELD(339, range_adj, 12, 12, table->r[i + 1]); - SET_REG_FIELD(340, range_adj, 8, 24, (i >> 1) + 0xE9); - GX_WRITE_RAS_REG(range_adj); - } - } - 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; - ASSERTMSGLINE(515, pix_fmt >= GX_PF_RGB8_Z24 && pix_fmt <= GX_PF_YUV420, "Invalid Pixel format"); - SET_REG_FIELD(517, __GXData->peCtrl, 3, 0, p2f[pix_fmt]); - SET_REG_FIELD(518, __GXData->peCtrl, 3, 3, z_fmt); - - 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/src/dolphin/gx/GXSave.c b/src/dolphin/gx/GXSave.c deleted file mode 100644 index 90b9a82..0000000 --- a/src/dolphin/gx/GXSave.c +++ /dev/null @@ -1,528 +0,0 @@ -#if DEBUG - -#include -#include - -#include "__gx.h" - -static const u8* dlist; -static u32 dlistSize; -static u32 bytesRead; - -// prototypes -void __GXShadowIndexState(u32 idx_reg, u32 reg_data); - -static u8 __ReadMem(void* ptr, u32 sz) { - const u8* src; - u8* dst; - u32 i; - - if (sz > dlistSize - bytesRead) { - return FALSE; - } - - src = dlist; - dst = ptr; - for (i = 0; i < sz; i++) { - *dst++ = *src++; - } - bytesRead += sz; - dlist += sz; - return TRUE; -} - -inline void DPF(char*, ...) { - u8 unused[4]; -} - -static void __SaveCPRegs(u8 reg, u8 vatIdx, u32 data) { - s32 idx; - - DPF("\tCP Stream Reg[0x%x] = 0x%x\n", reg, data); - - switch (reg) { - case 0: - case 1: - case 2: - case 3: - case 4: - break; - case 5: - __GXData->vcdLo = data; - break; - case 6: - __GXData->vcdHi = data; - break; - case 7: - __GXData->vatA[vatIdx & 0xFF] = data; - break; - case 8: - __GXData->vatB[vatIdx & 0xFF] = data; - break; - case 9: - __GXData->vatC[vatIdx & 0xFF] = data; - break; - case 10: - idx = vatIdx - 0x15; - if ((idx >= 0) && (idx < 4)) { - __GXData->indexBase[idx] = data; - } - break; - case 11: - idx = vatIdx - 0x15; - if ((idx >= 0) && (idx < 4)) { - __GXData->indexStride[idx] = data; - } - break; - default: - if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_INV_CMD]) { - __GX_WARN(GXWARN_DL_INV_CMD); - } - OSReport("[Invalid CP Stream Register Address 0x%x\n]", reg); - break; - } -} - -static void __ReconstVtxStatus(u8 vatIdx) { - u32 vat; - - if (GET_REG_FIELD(__GXData->vcdLo, 2, 11) & 3) { - vat = __GXData->vatA[vatIdx]; - if ((vat >> 9) & 1) { - __GXData->hasNrms = 0; - __GXData->hasBiNrms = 1; - } else { - __GXData->hasNrms = 1; - __GXData->hasBiNrms = 0; - } - } -} - -static u32 vtxCompSize[5] = { 1, 1, 2, 2, 4 }; -static int clrCompSize[6] = { 2, 3, 4, 2, 3, 4 }; - -static u32 GetAttrSize(u8 vatIdx, u32 attrIdx) { - u32 vcd; - u32 vat; - u32 nc; - - switch (attrIdx) { - case 0: - return GET_REG_FIELD(__GXData->vcdLo, 1, 0) ? 1 : 0; - case 1: - return GET_REG_FIELD(__GXData->vcdLo, 1, 1) ? 1 : 0; - case 2: - return GET_REG_FIELD(__GXData->vcdLo, 1, 2) ? 1 : 0; - case 3: - return GET_REG_FIELD(__GXData->vcdLo, 1, 3) ? 1 : 0; - case 4: - return GET_REG_FIELD(__GXData->vcdLo, 1, 4) ? 1 : 0; - case 5: - return GET_REG_FIELD(__GXData->vcdLo, 1, 5) ? 1 : 0; - case 6: - return GET_REG_FIELD(__GXData->vcdLo, 1, 6) ? 1 : 0; - case 7: - return GET_REG_FIELD(__GXData->vcdLo, 1, 7) ? 1 : 0; - case 8: - return GET_REG_FIELD(__GXData->vcdLo, 1, 8) ? 1 : 0; - case 9: - vcd = __GXData->vcdLo; - vat = __GXData->vatA[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 9)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return ((vat & 1) + 2) * vtxCompSize[(vat >> 1) & 7]; - } - break; - case 10: - vcd = __GXData->vcdLo; - vat = __GXData->vatA[vatIdx & 0xFF]; - - switch (GET_REG_FIELD(vcd, 2, 11)) { - case 0: - return 0; - case 2: - if ((vat >> 9) & 1 && vat >> 31) { - nc = 3; - } else { - nc = 1; - } - return nc; - case 3: - if ((vat >> 9) & 1 && vat >> 31) { - nc = 6; - } else { - nc = 2; - } - return nc; - case 1: - if ((vat >> 9) & 1) { - nc = 9; - } else { - nc = 3; - } - return nc * vtxCompSize[(vat >> 10) & 7]; - } - break; - case 11: - switch (GET_REG_FIELD(__GXData->vcdLo, 2, 13)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - vat = __GXData->vatA[vatIdx]; - return clrCompSize[(vat >> 14) & 7]; - } - break; - case 12: - switch (GET_REG_FIELD(__GXData->vcdLo, 2, 15)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - vat = __GXData->vatA[vatIdx]; - return clrCompSize[(vat >> 18) & 7]; - } - break; - case 13: - vcd = __GXData->vcdHi; - vat = __GXData->vatA[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 0)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return (((vat >> 21) & 1) + 1) * vtxCompSize[(vat >> 22) & 7]; - } - break; - case 14: - vcd = __GXData->vcdHi; - vat = __GXData->vatB[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 2)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return (((vat >> 0) & 1) + 1) * vtxCompSize[(vat >> 1) & 7]; - } - break; - case 15: - vcd = __GXData->vcdHi; - vat = __GXData->vatB[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 4)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return (((vat >> 9) & 1) + 1) * vtxCompSize[(vat >> 10) & 7]; - } - break; - case 16: - vcd = __GXData->vcdHi; - vat = __GXData->vatB[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 6)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return (((vat >> 18) & 1) + 1) * vtxCompSize[(vat >> 19) & 7]; - } - break; - case 17: - vcd = __GXData->vcdHi; - vat = __GXData->vatB[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 8)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return (((vat >> 27) & 1) + 1) * vtxCompSize[(vat >> 28) & 7]; - } - break; - case 18: - vcd = __GXData->vcdHi; - vat = __GXData->vatC[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 10)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return (((vat >> 5) & 1) + 1) * vtxCompSize[(vat >> 6) & 7]; - } - break; - case 19: - vcd = __GXData->vcdHi; - vat = __GXData->vatC[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 12)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return (((vat >> 14) & 1) + 1) * vtxCompSize[(vat >> 15) & 7]; - } - break; - case 20: - vcd = __GXData->vcdHi; - vat = __GXData->vatC[vatIdx & 0xFF]; - switch (GET_REG_FIELD(vcd, 2, 14)) { - case 0: - return 0; - case 2: - return 1; - case 3: - return 2; - case 1: - return (((vat >> 23) & 1) + 1) * vtxCompSize[(vat >> 24) & 7]; - } - break; - } - return 0; -} - -static void __ParseVertexData(u8 vatIdx) { - u16 vcnt; - GXAttr attrIdx; - u32 vsize; - - if (__ReadMem(&vcnt, 2)) { - vsize = 0; - for (attrIdx = 0; attrIdx < GX_VA_MAX_ATTR; attrIdx++) { - if (attrIdx != GX_VA_NBT) { - vsize += GetAttrSize(vatIdx, attrIdx); - } - } - vsize *= vcnt; - dlist += vsize; - bytesRead += vsize; - } -} - -void __GXShadowDispList(void* list, u32 nbytes) { - u8 cmd; - u8 cmdOp; - u8 vatIdx; - u32 reg32; - u32 d32; - u8 reg8; - u8 cpAddr; - u32 i; - u32 addr; - u32 cnt; - - if (__gxVerif->verifyLevel == GX_WARN_NONE) { - return; - } - - dlist = list; - dlistSize = nbytes; - bytesRead = 0; - - DPF("Displaylist IN\n"); - - while (dlistSize > bytesRead) { - if (!__ReadMem(&cmd, 1)) { - break; - } - cmdOp = (u32)GET_REG_FIELD((u32)cmd, 5, 3); - vatIdx = cmd & 7; - switch (cmdOp) { - case 0: - case 9: - break; - case 16: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - __ReconstVtxStatus(vatIdx); - __GXVerifyState(vatIdx); - __ParseVertexData(vatIdx); - break; - case 1: - if (__ReadMem(®8, 1) && __ReadMem(&d32, 4)) { - vatIdx = reg8 & 0xF; - cpAddr = (reg8& 0xF0) >> 4; - __SaveCPRegs(cpAddr, vatIdx, d32); - } - break; - case 2: - if (__ReadMem(®32, 4)) { - cnt = GET_REG_FIELD(reg32, 4, 16) + 1; - addr = (u16)reg32; - DPF("\tXFReg = 0x%x, Cnt = %d\n", addr, cnt); - for (i = 0; i < cnt; i++) { - if (__ReadMem(&d32, 4)) { - DPF("\tXFData = 0x%x\n", d32); - VERIF_MTXLIGHT(addr, d32); - addr++; - } - } - } - break; - case 4: - case 5: - case 6: - case 7: - if (__ReadMem(®32, 4)) { - DPF("\tXF_INDEX_LOAD: = 0x%x\n", reg32); - __GXShadowIndexState(cmdOp, reg32); - } - break; - case 8: - if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_NESTED]) { - __GX_WARN(GXWARN_DL_NESTED); - } - return; - case 12: - case 13: - if (__ReadMem(®32, 4)) { - DPF("\tSU Bypass = 0x%x\n", reg32); - __gxVerif->rasRegs[(reg32 >> 24) & 0xFF] = reg32; - } - break; - default: - if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_INV_CMD]) { - __GX_WARN(GXWARN_DL_INV_CMD); - } - OSReport("[Bad Display List Command: 0x%02X\n]", cmdOp); - break; - } - } - - DPF("Displaylist OUT\n"); -} - -void __GXShadowIndexState(u32 idx_reg, u32 reg_data) { - u32* basePtr; - u32* memAddr; - u32 cnt; - u32 stride; - u32 addr; - u32 data; - u32 index; - u32 i; - - i = idx_reg - 4; - basePtr = OSPhysicalToCached(__GXData->indexBase[i]); - stride = __GXData->indexStride[i]; - addr = reg_data & 0xFFF; - cnt = (reg_data >> 12) & 0xF; - index = reg_data >> 16; - memAddr = (u32*)((u8*)basePtr + (index * stride)); - cnt++; - - while (cnt-- != 0) { - data = *memAddr; - VERIF_MTXLIGHT(addr, data); - memAddr = (u32*)((u8*)memAddr + stride); - addr++; - } - - &data; // needed to match -} - -void __GXPrintShadowState(void) { - u32 i; - u32 j; - - OSReport("CP State:\n"); - OSReport("\tvcdLo = 0x%x\n", __GXData->vcdLo); - OSReport("\tvcdHi = 0x%x\n", __GXData->vcdHi); - OSReport("\thasBiNrms = 0x%x\n", __GXData->hasBiNrms); - - for (i = 0; i < 8; i++) { - OSReport("\tVertex Format %d:\n", i); - OSReport("\t\tvatA = 0x%x\n", __GXData->vatA[i]); - OSReport("\t\tvatB = 0x%x\n", __GXData->vatB[i]); - OSReport("\t\tvatC = 0x%x\n", __GXData->vatC[i]); - } - - OSReport("\n-------------------------------------\n"); - OSReport("XF Pos/Tex Matrix State:\n"); - - for (i = 0; i < 256; i += 4) { - if (__gxVerif->xfMtxDirty[i]) { - OSReport("\tXF_MATRIX[%d] = ", i); - OSReport("%f, %f, %f, %f\n", *(f32*)&__gxVerif->xfMtx[i], *(f32*)&__gxVerif->xfMtx[i + 1], *(f32*)&__gxVerif->xfMtx[i + 2], *(f32*)&__gxVerif->xfMtx[i + 3]); - } - } - - OSReport("\n-------------------------------------\n"); - OSReport("XF Normal Matrix State:\n"); - - for (i = 0; i < 96; i += 3) { - if (__gxVerif->xfNrmDirty[i]) { - OSReport("\tXF_NRM_MTX[%d] = ", i); - OSReport("%f, %f, %f\n", *(f32*)&__gxVerif->xfMtx[i], *(f32*)&__gxVerif->xfMtx[i + 1], *(f32*)&__gxVerif->xfMtx[i + 2]); - } - } - - OSReport("\n-------------------------------------\n"); - OSReport("XF Light State:\n"); - - for (i = 0; i < 128; i += 16) { - if (__gxVerif->xfLightDirty[i]) { - OSReport("\tXF_LIGHT[%d]:\n", i >> 4); - for (j = 0; j < 4; j++) { - OSReport("\t\tparam[%d] = 0x%x\n", j, __gxVerif->xfLight[i + j]); - } - for (j = 4; j < 16; j++) { - OSReport("\t\tparam[%d] = %Lg\n", j, *(f32*)&__gxVerif->xfLight[i + j]); - } - } - } - - OSReport("\n-------------------------------------\n"); - OSReport("XF Register State:\n"); - - for (i = 0; i < 80; i++) { - if (__gxVerif->xfRegsDirty[i]) { - OSReport("\tXF_REG[0x%x] = 0x%x (%f)\n", i, __gxVerif->xfRegs[i], *(f32*)&__gxVerif->xfRegs[i]); - } - } - - OSReport("\n-------------------------------------\n"); - OSReport("Raster Registers State:\n"); - - for (i = 0; i < 256; i++) { - OSReport("\tRAS_REG[0x%x] = 0x%x\n", i, __gxVerif->rasRegs[i]); - } - - OSReport("\n-------------------------------------\n"); -} - -#endif diff --git a/src/dolphin/gx/GXStubs.c b/src/dolphin/gx/GXStubs.c deleted file mode 100644 index c5e36bb..0000000 --- a/src/dolphin/gx/GXStubs.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -#include "__gx.h" - -void __GXSetRange(f32 nearz, f32 fgSideX) {} diff --git a/src/dolphin/gx/GXTev.c b/src/dolphin/gx/GXTev.c deleted file mode 100644 index 195e605..0000000 --- a/src/dolphin/gx/GXTev.c +++ /dev/null @@ -1,470 +0,0 @@ -#include -#include - -#include "__gx.h" - -static struct { - u32 rid : 8; - u32 dest : 2; - u32 shift : 2; - u32 clamp : 1; - u32 sub : 1; - u32 bias : 2; - u32 sela : 4; - u32 selb : 4; - u32 selc : 4; - u32 seld : 4; -} TEVCOpTableST0[5] = { - {192, 0, 0, 1, 0, 0, 15, 8, 10, 15}, // modulate - {192, 0, 0, 1, 0, 0, 10, 8, 9, 15}, // decal - {192, 0, 0, 1, 0, 0, 10, 12, 8, 15}, // blend - {192, 0, 0, 1, 0, 0, 15, 15, 15, 8}, // replace - {192, 0, 0, 1, 0, 0, 15, 15, 15, 10}, // passclr -}; - -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"); - ASSERTMSGLINE(421, id < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); - ASSERTMSGLINE(422, mode <= GX_PASSCLR, "GXSetTevOp: Invalid Tev Mode"); - - if (id == GX_TEVSTAGE0) { - ctmp = (u32*)TEVCOpTableST0 + mode; - atmp = (u32*)TEVAOpTableST0 + mode; - } else { - ctmp = (u32*)TEVCOpTableST1 + mode; - atmp = (u32*)TEVAOpTableST1 + mode; - } - - tevReg = __GXData->tevc[id]; - tevReg = (*ctmp & ~0xFF000000) | (tevReg & 0xFF000000); - GX_WRITE_RAS_REG(tevReg); - __GXData->tevc[id] = tevReg; - - tevReg = __GXData->teva[id]; - tevReg = (*atmp & ~0xFF00000F) | (tevReg & 0xFF00000F); - GX_WRITE_RAS_REG(tevReg); - __GXData->teva[id] = tevReg; - - __GXData->bpSentNot = 0; -} - -void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) { - u32 tevReg; - - CHECK_GXBEGIN(578, "GXSetTevColorIn"); - ASSERTMSGLINE(579, stage < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); - ASSERTMSGLINE(580, a <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); - ASSERTMSGLINE(581, b <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); - ASSERTMSGLINE(582, c <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); - ASSERTMSGLINE(583, d <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); - - tevReg = __GXData->tevc[stage]; - SET_REG_FIELD(586, tevReg, 4, 12, a); - SET_REG_FIELD(587, tevReg, 4, 8, b); - SET_REG_FIELD(588, tevReg, 4, 4, c); - SET_REG_FIELD(589, tevReg, 4, 0, d); - - GX_WRITE_RAS_REG(tevReg); - __GXData->tevc[stage] = tevReg; - __GXData->bpSentNot = 0; -} - -void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d) { - u32 tevReg; - - CHECK_GXBEGIN(614, "GXSetTevAlphaIn"); - ASSERTMSGLINE(615, stage < GX_MAX_TEVSTAGE, "GXSetTevAlpha*: Invalid Tev Stage Index"); - ASSERTMSGLINE(616, a <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); - ASSERTMSGLINE(617, b <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); - ASSERTMSGLINE(618, c <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); - ASSERTMSGLINE(619, d <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); - - tevReg = __GXData->teva[stage]; - 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"); - ASSERTMSGLINE(654, stage < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); - - 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"); - ASSERTMSGLINE(700, stage < GX_MAX_TEVSTAGE, "GXSetTevAlpha*: Invalid Tev Stage Index"); - - 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; - - ASSERTMSGLINE(777, color.r >= -1024 && color.r < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); - ASSERTMSGLINE(778, color.g >= -1024 && color.g < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); - ASSERTMSGLINE(779, color.b >= -1024 && color.b < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); - ASSERTMSGLINE(780, color.a >= -1024 && color.a < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); - - 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"); - ASSERTMSGLINE(873, stage < GX_MAX_TEVSTAGE, "GXSetTevKColor*: Invalid Tev Stage Index"); - - 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"); - ASSERTMSGLINE(906, stage < GX_MAX_TEVSTAGE, "GXSetTevKColor*: Invalid Tev Stage Index"); - - 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"); - ASSERTMSGLINE(943, stage < GX_MAX_TEVSTAGE, "GXSetTevSwapMode: Invalid Tev Stage Index"); - - 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"); - ASSERTMSGLINE(979, table < GX_MAX_TEVSWAP, "GXSetTevSwapModeTable: Invalid Swap Selection Index"); - -#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 GXSetTevClampMode(void) { - ASSERTMSGLINE(1012, 0, "GXSetTevClampMode: not available on this hardware"); -} - -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: - ASSERTMSGLINE(1089, 0, "GXSetZTexture: Invalid z-texture format"); - 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"); - ASSERTMSGLINE(1132, stage < GX_MAX_TEVSTAGE, "GXSetTevOrder: Invalid Tev Stage Index"); - ASSERTMSGLINE(1134, coord < GX_MAX_TEXCOORD || coord == GX_TEXCOORD_NULL, "GXSetTevOrder: Invalid Texcoord"); - ASSERTMSGLINE(1136, (map & ~GX_TEX_DISABLE) < GX_MAX_TEXMAP || map == GX_TEXMAP_NULL, "GXSetTevOrder: Invalid Tex Map"); - ASSERTMSGLINE(1138, color >= GX_COLOR0A0 && color <= GX_COLOR_NULL, "GXSetTevOrder: Invalid Color Channel ID"); - - 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"); - - ASSERTMSGLINE(1189, nStages != 0 && nStages <= 16, "GXSetNumTevStages: Exceed max number of tex stages"); - SET_REG_FIELD(1190, __GXData->genMode, 4, 10, nStages - 1); - __GXData->dirtyState |= 4; -} diff --git a/src/dolphin/gx/GXTexture.c b/src/dolphin/gx/GXTexture.c deleted file mode 100644 index ad12a7b..0000000 --- a/src/dolphin/gx/GXTexture.c +++ /dev/null @@ -1,1315 +0,0 @@ -#include -#include - -#include "__gx.h" - -// 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; - - ASSERTMSGLINEV(460, width <= 1024, "%s: width too large", "GXGetTexBufferSize"); - ASSERTMSGLINEV(461, height <= 1024, "%s: height too large", "GXGetTexBufferSize"); - - __GXGetTexTileShift(format, &tileShiftX, &tileShiftY); - if (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) { - tileBytes = 64; - } else { - tileBytes = 32; - } - - if (mipmap == GX_TRUE) { - nx = 1 << (31 - __cntlzw(width)); - ASSERTMSGLINEV(479, width == nx, "%s: width must be a power of 2", "GXGetTexBufferSize"); - ny = 1 << (31 - __cntlzw(height)); - ASSERTMSGLINEV(482, height == ny, "%s: height must be a power of 2", "GXGetTexBufferSize"); - - bufferSize = 0; - for (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, 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; - - ASSERTMSGLINE(565, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(567, "GXInitTexObj"); - ASSERTMSGLINEV(568, width <= 1024, "%s: width too large", "GXInitTexObj"); - ASSERTMSGLINEV(569, height <= 1024, "%s: height too large", "GXInitTexObj"); - ASSERTMSGLINEV(571, !(format & _GX_TF_CTF), "%s: invalid texture format", "GXInitTexObj"); - -#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); - ASSERTMSGLINEV(654, ((u32)image_ptr & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexObj", "image"); - imageBase = (u32)((u32)image_ptr >> 5) & 0x01FFFFFF; - SET_REG_FIELD(656, t->image3, 21, 0, imageBase); - - 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: - ASSERTMSGLINEV(699, 0, "%s: invalid texture format", "GXPreLoadEntireTexture"); - 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, void* image_ptr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap, u32 tlut_name) { - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(737, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(739, "GXInitTexObjCI"); - GXInitTexObj(obj, image_ptr, width, height, format, wrap_s, wrap_t, mipmap); - t->flags &= 0xFFFFFFFD; - t->tlutName = tlut_name; -} - -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; - - ASSERTMSGLINE(776, obj, "Texture Object Pointer is null"); - 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); - ASSERTMSG1LINE(791, (u32)mag_filt <= 1, "%s: invalid mag_filt value", "GXInitTexObjLOD"); - SET_REG_FIELD(792, t->mode0, 1, 4, (mag_filt == GX_LINEAR) ? 1 : 0); - ASSERTMSG1LINE(795, (u32)min_filt <= 5, "%s: invalid min_filt value", "GXInitTexObjLOD"); - SET_REG_FIELD(796, t->mode0, 3, 5, GX2HWFiltConv[min_filt]); - SET_REG_FIELD(798, t->mode0, 1, 8, do_edge_lod ? 0 : 1); - SET_REG_FIELD(801, t->mode0, 1, 17, 0); - SET_REG_FIELD(801, t->mode0, 1, 18, 0); - SET_REG_FIELD(801, t->mode0, 2, 19, max_aniso); - SET_REG_FIELD(802, t->mode0, 1, 21, bias_clamp); - - if (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); -} - -void GXInitTexObjData(GXTexObj* obj, void* image_ptr) { - u32 imageBase; - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(835, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(837, "GXInitTexObjData"); - ASSERTMSGLINEV(840, ((u32)image_ptr & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexObjData", "image"); - imageBase = ((u32)image_ptr >> 5) & 0x01FFFFFF; - SET_REG_FIELD(843, t->image3, 21, 0, imageBase); -} - -void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode sm, GXTexWrapMode tm) { - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(860, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(862, "GXInitTexObjWrapMode"); - SET_REG_FIELD(864, t->mode0, 2, 0, sm); - SET_REG_FIELD(865, t->mode0, 2, 2, tm); -} - -void GXInitTexObjTlut(GXTexObj* obj, u32 tlut_name) { - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(881, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(883, "GXInitTexObjTlut"); - t->tlutName = tlut_name; -} - -void GXInitTexObjFilter(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt) { - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(902, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(904, "GXInitTexObjFilter"); - - ASSERTMSG1LINE(907, (u32)mag_filt <= 1, "%s: invalid mag_filt value", "GXInitTexObjFilter"); - SET_REG_FIELD(908, t->mode0, 1, 4, mag_filt == 1 ? 1 : 0); - - ASSERTMSG1LINE(911, (u32)min_filt <= 5, "%s: invalid min_filt value", "GXInitTexObjFilter"); - SET_REG_FIELD(912, t->mode0, 3, 5, GX2HWFiltConv[min_filt]); -} - -void GXInitTexObjMaxLOD(GXTexObj* obj, f32 max_lod) { - u8 lmax; - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(930, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(932, "GXInitTexObjMaxLOD"); - - if (max_lod < 0.0f) { - max_lod = 0.0f; - } else if (max_lod > 10.0f) { - max_lod = 10.0f; - } - lmax = 16.0f * max_lod; - SET_REG_FIELD(938, t->mode1, 8, 8, lmax); -} - -void GXInitTexObjMinLOD(GXTexObj* obj, f32 min_lod) { - u8 lmin; - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(956, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(958, "GXInitTexObjMinLOD"); - - if (min_lod < 0.0f) { - min_lod = 0.0f; - } else if (min_lod > 10.0f) { - min_lod = 10.0f; - } - lmin = 16.0f * min_lod; - SET_REG_FIELD(964, t->mode1, 8, 0, lmin); -} - -void GXInitTexObjLODBias(GXTexObj* obj, f32 lod_bias) { - u8 lbias; - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(982, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(984, "GXInitTexObjLODBias"); - - if (lod_bias < -4.0f) { - lod_bias = -4.0f; - } else if (lod_bias >= 4.0f) { - lod_bias = 3.99f; - } - lbias = 32.0f * lod_bias; - SET_REG_FIELD(991, t->mode0, 8, 9, lbias); -} - -void GXInitTexObjBiasClamp(GXTexObj* obj, u8 bias_clamp) { - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(1007, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(1009, "GXInitTexObjBiasClamp"); - - SET_REG_FIELD(1011, t->mode0, 1, 21, bias_clamp); -} - -void GXInitTexObjEdgeLOD(GXTexObj* obj, u8 do_edge_lod) { - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(1027, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(1029, "GXInitTexObjEdgeLOD"); - - SET_REG_FIELD(1031, t->mode0, 1, 8, do_edge_lod ? 0 : 1); -} - -void GXInitTexObjMaxAniso(GXTexObj* obj, GXAnisotropy max_aniso) { - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(1047, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(1049, "GXInitTexObjMaxAniso"); - - SET_REG_FIELD(1051, t->mode0, 2, 19, max_aniso); -} - -void GXInitTexObjUserData(GXTexObj* obj, void* user_data) { - __GXTexObjInt* t = (__GXTexObjInt*)obj; - - ASSERTMSGLINE(1068, obj, "Texture Object Pointer is null"); - CHECK_GXBEGIN(1069, "GXInitTexObjUserData"); - t->userData = user_data; -} - -void* GXGetTexObjUserData(const GXTexObj* obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)obj; - - ASSERTMSGLINE(1075, obj, "Texture Object Pointer is null"); - return t->userData; -} - -void GXGetTexObjAll(const GXTexObj* obj, void** image_ptr, u16* width, u16* height, GXTexFmt* format, GXTexWrapMode* wrap_s, GXTexWrapMode* wrap_t, u8* mipmap) { - const __GXTexObjInt* t = (const __GXTexObjInt *)obj; - - ASSERTMSGLINE(1095, obj, "Texture Object Pointer is null"); - *image_ptr = (void *)(GET_REG_FIELD(t->image3, 21, 0) << 5); - *width = (u32)GET_REG_FIELD(t->image0, 10, 0) + 1; - *height = (u32)GET_REG_FIELD(t->image0, 10, 10) + 1; - *format = t->fmt; - *wrap_s = GET_REG_FIELD(t->mode0, 2, 0); - *wrap_t = GET_REG_FIELD(t->mode0, 2, 2); - *mipmap = (t->flags & 1) == 1; -} - -void* GXGetTexObjData(const GXTexObj* to) { - const __GXTexObjInt* t = (const __GXTexObjInt *)to; - - ASSERTMSGLINE(1108, to, "Texture Object Pointer is null"); - return (void*)(GET_REG_FIELD(t->image3, 21, 0) << 5); -} - -u16 GXGetTexObjWidth(const GXTexObj* to) { - const __GXTexObjInt* t = (const __GXTexObjInt *)to; - - ASSERTMSGLINE(1114, to, "Texture Object Pointer is null"); - return (u32)GET_REG_FIELD(t->image0, 10, 0) + 1; -} - -u16 GXGetTexObjHeight(const GXTexObj* to) { - const __GXTexObjInt* t = (const __GXTexObjInt *)to; - - ASSERTMSGLINE(1120, to, "Texture Object Pointer is null"); - return (u32)GET_REG_FIELD(t->image0, 10, 10) + 1; -} - -GXTexFmt GXGetTexObjFmt(const GXTexObj* to) { - const __GXTexObjInt* t = (const __GXTexObjInt *)to; - - ASSERTMSGLINE(1126, to, "Texture Object Pointer is null"); - return t->fmt; -} - -GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* to) { - const __GXTexObjInt* t = (const __GXTexObjInt *)to; - - ASSERTMSGLINE(1132, to, "Texture Object Pointer is null"); - return GET_REG_FIELD(t->mode0, 2, 0); -} - -GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* to) { - const __GXTexObjInt* t = (const __GXTexObjInt *)to; - - ASSERTMSGLINE(1138, to, "Texture Object Pointer is null"); - return GET_REG_FIELD(t->mode0, 2, 2); -} - -GXBool GXGetTexObjMipMap(const GXTexObj* to) { - const __GXTexObjInt* t = (const __GXTexObjInt *)to; - - ASSERTMSGLINE(1144, to, "Texture Object Pointer is null"); - return (t->flags & 1) == 1; -} - -void GXGetTexObjLODAll(const GXTexObj* tex_obj, GXTexFilter* min_filt, GXTexFilter* mag_filt, f32* min_lod, f32* max_lod, f32* lod_bias, u8* bias_clamp, u8* do_edge_lod, GXAnisotropy* max_aniso) { - s16 tmp; - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1166, tex_obj, "Texture Object Pointer is null"); - *min_filt = HW2GXFiltConv[GET_REG_FIELD(t->mode0, 3, 5)]; - *mag_filt = GET_REG_FIELD(t->mode0, 1, 4); - *min_lod = (u8)t->mode1 / 16.0f; - *max_lod = (u32)GET_REG_FIELD(t->mode1, 8, 8) / 16.0f; - tmp = (s32)GET_REG_FIELD(t->mode0, 8, 9); - *lod_bias = (s8)tmp / 32.0f; - *bias_clamp = (u32)GET_REG_FIELD(t->mode0, 1, 21); - *do_edge_lod = !GET_REG_FIELD(t->mode0, 1, 8); - *max_aniso = GET_REG_FIELD(t->mode0, 2, 19); -} - -GXTexFilter GXGetTexObjMinFilt(const GXTexObj* tex_obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1182, tex_obj, "Texture Object Pointer is null"); - return HW2GXFiltConv[GET_REG_FIELD(t->mode0, 3, 5)]; -} - -GXTexFilter GXGetTexObjMagFilt(const GXTexObj* tex_obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1189, tex_obj, "Texture Object Pointer is null"); - return GET_REG_FIELD(t->mode0, 1, 4); -} - -f32 GXGetTexObjMinLOD(const GXTexObj* tex_obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1195, tex_obj, "Texture Object Pointer is null"); - return (u32)GET_REG_FIELD(t->mode1, 8, 0) / 16.0f; -} - -f32 GXGetTexObjMaxLOD(const GXTexObj* tex_obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1201, tex_obj, "Texture Object Pointer is null"); - return (u32)GET_REG_FIELD(t->mode1, 8, 8) / 16.0f; -} - -f32 GXGetTexObjLODBias(const GXTexObj* tex_obj) { - s16 tmp; - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1208, tex_obj, "Texture Object Pointer is null"); - tmp = (s32)GET_REG_FIELD(t->mode0, 8, 9); - return (s8)tmp / 32.0f; -} - -GXBool GXGetTexObjBiasClamp(const GXTexObj* tex_obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1215, tex_obj, "Texture Object Pointer is null"); - return (u32)GET_REG_FIELD(t->mode0, 1, 21); -} - -GXBool GXGetTexObjEdgeLOD(const GXTexObj* tex_obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1221, tex_obj, "Texture Object Pointer is null"); - return !GET_REG_FIELD(t->mode0, 1, 8); -} - -GXAnisotropy GXGetTexObjMaxAniso(const GXTexObj* tex_obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1227, tex_obj, "Texture Object Pointer is null"); - return GET_REG_FIELD(t->mode0, 2, 19); -} - -u32 GXGetTexObjTlut(const GXTexObj* tex_obj) { - const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; - - ASSERTMSGLINE(1233, tex_obj, "Texture Object Pointer is null"); - return t->tlutName; -} - -void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID id) { - __GXTlutRegionInt* tlr; - u32 m0; - u32 m1; - u32 img0; - u32 img1; - u32 img2; - u32 img3; - __GXTexObjInt* t = (__GXTexObjInt*)obj; - __GXTexRegionInt* r = (__GXTexRegionInt *)region; - - ASSERTMSGLINE(1257, obj, "Texture Object Pointer is null"); - ASSERTMSGLINE(1257, region, "TexRegion Object Pointer is null"); - CHECK_GXBEGIN(1259, "GXLoadTexObjPreLoaded"); - ASSERTMSGLINEV(1260, id < GX_MAX_TEXMAP, "%s: invalid texture map ID", "GXLoadTexObj"); - - m0 = t->mode0; - m1 = t->mode1; - img0 = t->image0; - img1 = r->image1; - img2 = r->image2; - img3 = t->image3; - - SET_REG_FIELD(1271, t->mode0, 8, 24, GXTexMode0Ids[id]); - SET_REG_FIELD(1272, t->mode1, 8, 24, GXTexMode1Ids[id]); - SET_REG_FIELD(1273, t->image0, 8, 24, GXTexImage0Ids[id]); - SET_REG_FIELD(1274, r->image1, 8, 24, GXTexImage1Ids[id]); - SET_REG_FIELD(1275, r->image2, 8, 24, GXTexImage2Ids[id]); - SET_REG_FIELD(1276, t->image3, 8, 24, GXTexImage3Ids[id]); - - GX_WRITE_RAS_REG(t->mode0); - GX_WRITE_RAS_REG(t->mode1); - GX_WRITE_RAS_REG(t->image0); - GX_WRITE_RAS_REG(r->image1); - GX_WRITE_RAS_REG(r->image2); - GX_WRITE_RAS_REG(t->image3); - - if (!(t->flags & 2)) { - ASSERTMSGLINEV(1287, __GXData->tlutRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTexObj/PreLoaded"); - tlr = (__GXTlutRegionInt*)__GXData->tlutRegionCallback(t->tlutName); - ASSERTMSGLINEV(1289, tlr, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTexObj/PreLoaded"); - - SET_REG_FIELD(1291, tlr->tlutObj.tlut, 8, 24, GXTexTlutIds[id]); - GX_WRITE_RAS_REG(tlr->tlutObj.tlut); - } - - __GXData->tImage0[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"); - ASSERTMSGLINEV(1319, id < 8, "%s: invalid texture map ID", "GXLoadTexObj"); - ASSERTMSGLINEV(1324, __GXData->texRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTexObj"); - r = __GXData->texRegionCallback(obj, id); - ASSERTMSGLINEV(1326, r, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTexObj"); - GXLoadTexObjPreLoaded(obj, r, id); -} - -void GXInitTlutObj(GXTlutObj* tlut_obj, void* lut, GXTlutFmt fmt, u16 n_entries) { - __GXTlutObjInt* t = (__GXTlutObjInt *)tlut_obj; - - ASSERTMSGLINE(1350, tlut_obj, "TLut Object Pointer is null"); - CHECK_GXBEGIN(1351, "GXInitTlutObj"); - ASSERTMSGLINEV(1354, n_entries <= 0x4000, "%s: number of entries exceeds maximum", "GXInitTlutObj"); - ASSERTMSGLINEV(1356, ((u32)lut & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTlutObj", "Tlut"); - t->tlut = 0; - SET_REG_FIELD(1359, t->tlut, 2, 10, fmt); - SET_REG_FIELD(1360, t->loadTlut0, 21, 0, ((u32)lut & 0x3FFFFFFF) >> 5); - SET_REG_FIELD(1361, t->loadTlut0, 8, 24, 0x64); - t->numEntries = n_entries; -} - -void GXGetTlutObjAll(const GXTlutObj* tlut_obj, void **data, GXTlutFmt* format, u16* numEntries) { - const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; - - ASSERTMSGLINE(1382, tlut_obj, "TLut Object Pointer is null"); - *data = (void *)(GET_REG_FIELD(t->loadTlut0, 21, 0) << 5); - *format = GET_REG_FIELD(t->tlut, 2, 10); - *numEntries = t->numEntries; -} - -void* GXGetTlutObjData(const GXTlutObj* tlut_obj) { - const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; - - ASSERTMSGLINE(1391, tlut_obj, "TLut Object Pointer is null"); - return (void *)(GET_REG_FIELD(t->loadTlut0, 21, 0) << 5); -} - -GXTlutFmt GXGetTlutObjFmt(const GXTlutObj* tlut_obj) { - const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; - - ASSERTMSGLINE(1398, tlut_obj, "TLut Object Pointer is null"); - return GET_REG_FIELD(t->tlut, 2, 10); -} - -u16 GXGetTlutObjNumEntries(const GXTlutObj* tlut_obj) { - const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; - - ASSERTMSGLINE(1405, tlut_obj, "TLut Object Pointer is null"); - return t->numEntries; -} - -void GXLoadTlut(GXTlutObj* tlut_obj, u32 tlut_name) { - __GXTlutRegionInt* r; - u32 tlut_offset; - __GXTlutObjInt* t = (__GXTlutObjInt *)tlut_obj; - - ASSERTMSGLINE(1432, tlut_obj, "TLut Object Pointer is null"); - CHECK_GXBEGIN(1434, "GXLoadTlut"); - ASSERTMSGLINEV(1435, __GXData->tlutRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTlut"); - r = (__GXTlutRegionInt *)__GXData->tlutRegionCallback(tlut_name); - ASSERTMSGLINEV(1437, r, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTlut"); - - __GXFlushTextureState(); - GX_WRITE_RAS_REG(t->loadTlut0); - GX_WRITE_RAS_REG(r->loadTlut1); - __GXFlushTextureState(); - tlut_offset = r->loadTlut1 & 0x3FF; - SET_REG_FIELD(1453, t->tlut, 10, 0, tlut_offset); - r->tlutObj = *t; -} - -void GXInitTexCacheRegion(GXTexRegion* region, u8 is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd) { - u32 WidthExp2; - __GXTexRegionInt* t = (__GXTexRegionInt*)region; - - ASSERTMSGLINE(1484, region, "TexRegion Object Pointer is null"); - CHECK_GXBEGIN(1486, "GXInitTexCacheRegion"); - ASSERTMSGLINEV(1488, (tmem_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexCacheRegion", "tmem even"); - ASSERTMSGLINEV(1490, (tmem_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexCacheRegion", "tmem odd"); - - switch (size_even) { - case GX_TEXCACHE_32K: - WidthExp2 = 3; - break; - case GX_TEXCACHE_128K: - WidthExp2 = 4; - break; - case GX_TEXCACHE_512K: - WidthExp2 = 5; - break; - default: - ASSERTMSGLINEV(1498, 0, "%s: Invalid %s size", "GXInitTexCacheRegion", "tmem even"); - break; - } - - t->image1 = 0; - SET_REG_FIELD(1503, t->image1, 15, 0, tmem_even >> 5); - SET_REG_FIELD(1504, t->image1, 3, 15, WidthExp2); - SET_REG_FIELD(1505, t->image1, 3, 18, WidthExp2); - SET_REG_FIELD(1506, t->image1, 1, 21, 0); - - switch (size_odd) { - case GX_TEXCACHE_32K: - WidthExp2 = 3; - break; - case GX_TEXCACHE_128K: - WidthExp2 = 4; - break; - case GX_TEXCACHE_512K: - WidthExp2 = 5; - break; - case GX_TEXCACHE_NONE: - WidthExp2 = 0; - break; - default: - ASSERTMSGLINEV(1514, 0, "%s: Invalid %s size", "GXInitTexCacheRegion", "tmem odd"); - break; - } - - t->image2 = 0; - SET_REG_FIELD(1519, t->image2, 15, 0, tmem_odd >> 5); - SET_REG_FIELD(1520, t->image2, 3, 15, WidthExp2); - SET_REG_FIELD(1521, t->image2, 3, 18, WidthExp2); - t->is32bMipmap = is_32b_mipmap; - t->isCached = 1; -} - -void GXInitTexPreLoadRegion(GXTexRegion* region, u32 tmem_even, u32 size_even, u32 tmem_odd, u32 size_odd) { - __GXTexRegionInt* t = (__GXTexRegionInt *)region; - - ASSERTMSGLINE(1550, region, "TexRegion Object Pointer is null"); - CHECK_GXBEGIN(1552, "GXInitTexPreLoadRegion"); - ASSERTMSGLINEV(1554, (tmem_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "tmem even"); - ASSERTMSGLINEV(1556, (tmem_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "tmem odd"); - ASSERTMSGLINEV(1558, (size_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "size even"); - ASSERTMSGLINEV(1560, (size_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "size odd"); - - t->image1 = 0; - SET_REG_FIELD(1564, t->image1, 15, 0, tmem_even >> 5); - SET_REG_FIELD(1565, t->image1, 3, 15, 0); - SET_REG_FIELD(1566, t->image1, 3, 18, 0); - SET_REG_FIELD(1567, t->image1, 1, 21, 1); - - t->image2 = 0; - SET_REG_FIELD(1570, t->image2, 15, 0, tmem_odd >> 5); - SET_REG_FIELD(1571, t->image2, 3, 15, 0); - SET_REG_FIELD(1572, t->image2, 3, 18, 0); - t->is32bMipmap = 0; - t->isCached = 0; - t->sizeEven = (u16)(size_even >> 5); - t->sizeOdd = (u16)(size_odd >> 5); -} - -void GXGetTexRegionAll(const GXTexRegion* region, u8* is_cached, u8* is_32b_mipmap, u32* tmem_even, u32* size_even, u32* tmem_odd, u32* size_odd) { - const __GXTexRegionInt* t = (const __GXTexRegionInt *)region; - - ASSERTMSGLINE(1601, region, "TexRegion Object Pointer is null"); - *tmem_even = GET_REG_FIELD(t->image1, 15, 0) << 5; - *tmem_odd = GET_REG_FIELD(t->image2, 15, 0) << 5; - if (t->isCached) { - switch (GET_REG_FIELD(t->image1, 3, 15)) { - case 3: - *size_even = 0x8000; - break; - case 4: - *size_even = 0x20000; - break; - case 5: - *size_even = 0x80000; - break; - default: - *size_even = 0; - break; - } - - switch (GET_REG_FIELD(t->image2, 3, 15)) { - case 3: - *size_odd = 0x8000; - break; - case 4: - *size_odd = 0x20000; - break; - case 5: - *size_odd = 0x80000; - break; - default: - *size_odd = 0; - break; - } - } else { - *size_even = t->sizeEven << 5; - *size_odd = t->sizeOdd << 5; - } - - *is_32b_mipmap = t->is32bMipmap; - *is_cached = t->isCached; -} - -void GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size) { - __GXTlutRegionInt* t = (__GXTlutRegionInt *)region; - - ASSERTMSGLINE(1652, region, "TLutRegion Object Pointer is null"); - CHECK_GXBEGIN(1654, "GXInitTlutRegion"); - ASSERTMSGLINEV(1655, (tmem_addr & 0x1FF) == 0, "%s: tmem pointer is not aligned to 512B", "GXInitTlutRegion"); - ASSERTMSGLINEV(1656, tlut_size <= 0x400, "%s: tlut size exceeds 16K", "GXInitTlutRegion"); - t->loadTlut1 = 0; - tmem_addr -= 0x80000; - SET_REG_FIELD(1660, t->loadTlut1, 10, 0, tmem_addr >> 9); - SET_REG_FIELD(1661, t->loadTlut1, 11, 10, tlut_size); - SET_REG_FIELD(1662, t->loadTlut1, 8, 24, 0x65); -} - -void GXGetTlutRegionAll(const GXTlutRegion* region, u32* tmem_addr, GXTlutSize* tlut_size) { - const __GXTlutRegionInt* t = (const __GXTlutRegionInt *)region; - - ASSERTMSGLINE(1682, region, "TLutRegion Object Pointer is null"); - *tmem_addr = (GET_REG_FIELD(t->loadTlut1, 10, 0) << 9) + 0x80000; - *tlut_size = GET_REG_FIELD(t->loadTlut1, 11, 10); -} - -void GXInvalidateTexRegion(GXTexRegion* region) { - s32 wle; - s32 hle; - s32 wlo; - s32 hlo; - s32 count; - u32 reg0; - u32 reg1; - __GXTexRegionInt* r = (__GXTexRegionInt*)region; - - ASSERTMSGLINE(1705, region, "TexRegion Object Pointer is null"); - CHECK_GXBEGIN(1707, "GXInvalidateTexRegion"); - - wle = GET_REG_FIELD(r->image1, 3, 15) - 1; - hle = GET_REG_FIELD(r->image1, 3, 18) - 1; - wlo = GET_REG_FIELD(r->image2, 3, 15) - 1; - hlo = GET_REG_FIELD(r->image2, 3, 18) - 1; - if (wle < 0) { - wle = 0; - } - if (hle < 0) { - hle = 0; - } - if (wlo < 0) { - wlo = 0; - } - if (hlo < 0) { - hlo = 0; - } - count = wle + hle; - if (r->is32bMipmap) { - count = wlo + hlo - 2 + count; - } - - reg0 = 0; - SET_REG_FIELD(1724, reg0, 9, 0, GET_REG_FIELD(r->image1, 9, 6)); - SET_REG_FIELD(1725, reg0, 4, 9, count); - SET_REG_FIELD(1724, reg0, 8, 24, 0x66); - - if (wlo != 0) { - count = wlo + hlo; - if (r->is32bMipmap) { - count = wle + hle - 2 + count; - } - reg1 = 0; - SET_REG_FIELD(1736, reg1, 9, 0, GET_REG_FIELD(r->image2, 9, 6)); - SET_REG_FIELD(1737, reg1, 4, 9, count); - SET_REG_FIELD(1738, reg1, 8, 24, 0x66); - } - - __GXFlushTextureState(); - GX_WRITE_RAS_REG(reg0); - if (wlo != 0) { - GX_WRITE_RAS_REG(reg1); - } - __GXFlushTextureState(); - - reg0; reg1; r; // needed to match -} - -void GXInvalidateTexAll(void) { - u32 reg0; - u32 reg1; - - CHECK_GXBEGIN(1755, "GXInvalidateTexAll"); - reg0 = 0x66001000; - reg1 = 0x66001100; - __GXFlushTextureState(); - GX_WRITE_RAS_REG(reg0); - GX_WRITE_RAS_REG(reg1); - __GXFlushTextureState(); -} - -GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback f) { - GXTexRegionCallback oldcb = __GXData->texRegionCallback; - - __GXData->texRegionCallback = f; - return oldcb; -} - -GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback f) { - GXTlutRegionCallback oldcb = __GXData->tlutRegionCallback; - - __GXData->tlutRegionCallback = f; - return oldcb; -} - -void GXPreLoadEntireTexture(GXTexObj* tex_obj, GXTexRegion* region) { - GXBool isMipMap; - GXBool is32bit; - u32 wd; - u32 ht; - u32 maxLevelIndex; - u32 loadImage0; - u32 loadImage1; - u32 loadImage2; - u32 loadImage3; - u32 base; - u32 tmem1; - u32 tmem2; - u32 tmemAR; - u32 tmemGB; - u32 nTiles; -#if DEBUG - u32 totalOdd; - u32 totalEven; - u32 count; -#endif - u32 rowTiles; - u32 colTiles; - u32 cmpTiles; - u32 i; - __GXTexObjInt* t = (__GXTexObjInt*)tex_obj; - __GXTexRegionInt* r = (__GXTexRegionInt*)region; - - ASSERTMSGLINE(1820, tex_obj, "Texture Object Pointer is null"); - ASSERTMSGLINE(1820, region, "TexRegion Object Pointer is null"); - CHECK_GXBEGIN(1822, "GXPreLoadEntireTexture"); - isMipMap = (t->flags & 1) == 1; - is32bit = GET_REG_FIELD(t->image0, 4, 20) == 6; - - loadImage0 = 0; - SET_REG_FIELD(0, loadImage0, 8, 24, 0x60); - base = t->image3 & 0x1FFFFF; - SET_REG_FIELD(1831, loadImage0, 21, 0, base); - - loadImage1 = 0; - SET_REG_FIELD(0, loadImage1, 8, 24, 0x61); - tmem1 = r->image1 & 0x7FFF; - SET_REG_FIELD(1837, loadImage1, 15, 0, tmem1); - - loadImage2 = 0; - SET_REG_FIELD(0, loadImage2, 8, 24, 0x62); - tmem2 = r->image2 & 0x7FFF; - SET_REG_FIELD(1843, loadImage2, 15, 0, tmem2); - - loadImage3 = 0; - SET_REG_FIELD(0, loadImage3, 8, 24, 0x63); - SET_REG_FIELD(1848, loadImage3, 15, 0, t->loadCnt); - SET_REG_FIELD(1849, loadImage3, 2, 15, t->loadFmt); - maxLevelIndex = 0; - nTiles = t->loadCnt; - - if (isMipMap) { - wd = GET_REG_FIELD(t->image0, 10, 0) + 1; - ht = GET_REG_FIELD(t->image0, 10, 10) + 1; - if (wd > ht) { - maxLevelIndex = (u16)(31 - __cntlzw(wd)); - } else { - maxLevelIndex = (u16)(31 - __cntlzw(ht)); - } - -#if DEBUG - count = nTiles; - totalOdd = totalEven = 0; - - for (i = 0; i < maxLevelIndex; i++) { - if (i & 1) { - if (count == 0) { - count = 1; - } - totalOdd += count; - } else { - if (count == 0) { - count = 1; - } - totalEven += count; - } - __GetImageTileCount(t->fmt, wd >> (i + 1), ht >> (i + 1), &rowTiles, &colTiles, &cmpTiles); - count = rowTiles * colTiles; - } -#endif - } else { -#if DEBUG - totalEven = (nTiles == 0) ? 1 : nTiles; - totalOdd = totalEven; -#endif - } - -#if DEBUG - if (is32bit) { - totalOdd = isMipMap ? totalOdd : 0; - totalEven = totalEven + totalOdd; - ASSERTMSGLINE(1890, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); - ASSERTMSGLINE(1891, totalEven <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); - } else if (isMipMap != 0) { - if (r->sizeEven > r->sizeOdd) { - ASSERTMSGLINE(1896, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); - ASSERTMSGLINE(1897, totalOdd <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); - } else { - ASSERTMSGLINE(1900, totalEven <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); - ASSERTMSGLINE(1901, totalOdd <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); - } - } else if (r->sizeEven > r->sizeOdd) { - ASSERTMSGLINE(1906, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); - } else { - ASSERTMSGLINE(1908, totalOdd <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); - } -#endif - - __GXFlushTextureState(); - GX_WRITE_RAS_REG(loadImage0); - GX_WRITE_RAS_REG(loadImage1); - GX_WRITE_RAS_REG(loadImage2); - GX_WRITE_RAS_REG(loadImage3); - - if (maxLevelIndex != 0) { - tmemAR = tmem1; - tmemGB = tmem2; - for (i = 0; i < maxLevelIndex; i++) { - if (is32bit) { - base += nTiles * 2; - tmemAR += nTiles; - tmemGB += nTiles; - } else { - base += nTiles; - if (i & 1) { - tmemGB += nTiles; - } else { - tmemAR += nTiles; - } - } - tmem1 = (i & 1) ? tmemAR : tmemGB; - tmem2 = (i & 1) ? tmemGB : tmemAR; - __GetImageTileCount(t->fmt, (u16) (wd >> (i + 1)), (u16) (ht >> (i + 1)), &rowTiles, &colTiles, &cmpTiles); - nTiles = rowTiles * colTiles; - SET_REG_FIELD(1957, loadImage0, 21, 0, base); - SET_REG_FIELD(1958, loadImage1, 15, 0, tmem1); - SET_REG_FIELD(1959, loadImage2, 15, 0, tmem2); - SET_REG_FIELD(1960, loadImage3, 15, 0, nTiles); - GX_WRITE_RAS_REG(loadImage0); - GX_WRITE_RAS_REG(loadImage1); - GX_WRITE_RAS_REG(loadImage2); - GX_WRITE_RAS_REG(loadImage3); - } - } - __GXFlushTextureState(); - - // needed to match debug - maxLevelIndex; maxLevelIndex; base; base; base; tmem1; tmem1; tmem2; tmem2; -} - -void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts) { - CHECK_GXBEGIN(1989, "GXSetTexCoordScaleManually"); - ASSERTMSGLINEV(1991, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordScaleManually"); - __GXData->tcsManEnab = (__GXData->tcsManEnab & ~(1 << coord)) | (enable << coord); - - if (enable) { - SET_REG_FIELD(1997, __GXData->suTs0[coord], 16, 0, (u16)(ss - 1)); - SET_REG_FIELD(1998, __GXData->suTs1[coord], 16, 0, (u16)(ts - 1)); - GX_WRITE_RAS_REG(__GXData->suTs0[coord]); - GX_WRITE_RAS_REG(__GXData->suTs1[coord]); - __GXData->bpSentNot = 0; - } -} - -void GXSetTexCoordCylWrap(GXTexCoordID coord, u8 s_enable, u8 t_enable) { - CHECK_GXBEGIN(2023, "GXSetTexCoordCylWrap"); - ASSERTMSGLINEV(2025, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordCylWrap"); - SET_REG_FIELD(2027, __GXData->suTs0[coord], 1, 17, s_enable); - SET_REG_FIELD(2028, __GXData->suTs1[coord], 1, 17, t_enable); - - if (__GXData->tcsManEnab & (1 << coord)) { - GX_WRITE_RAS_REG(__GXData->suTs0[coord]); - GX_WRITE_RAS_REG(__GXData->suTs1[coord]); - __GXData->bpSentNot = 0; - } -} - -void GXSetTexCoordBias(GXTexCoordID coord, u8 s_enable, u8 t_enable) { - CHECK_GXBEGIN(2054, "GXSetTexCoordBias"); - ASSERTMSGLINEV(2056, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordBias"); - SET_REG_FIELD(2058, __GXData->suTs0[coord], 1, 16, s_enable); - SET_REG_FIELD(2059, __GXData->suTs1[coord], 1, 16, t_enable); - - if (__GXData->tcsManEnab & (1 << coord)) { - GX_WRITE_RAS_REG(__GXData->suTs0[coord]); - GX_WRITE_RAS_REG(__GXData->suTs1[coord]); - __GXData->bpSentNot = 0; - } -} - -static void __SetSURegs(u32 tmap, u32 tcoord) { - u32 w; - u32 h; - u8 s_bias; - u8 t_bias; - - w = GET_REG_FIELD(__GXData->tImage0[tmap], 10, 0); - h = GET_REG_FIELD(__GXData->tImage0[tmap], 10, 10); - SET_REG_FIELD(2089, __GXData->suTs0[tcoord], 16, 0, w); - SET_REG_FIELD(2090, __GXData->suTs1[tcoord], 16, 0, h); - s_bias = GET_REG_FIELD(__GXData->tMode0[tmap], 2, 0) == 1; - t_bias = GET_REG_FIELD(__GXData->tMode0[tmap], 2, 2) == 1; - SET_REG_FIELD(2096, __GXData->suTs0[tcoord], 1, 16, s_bias); - SET_REG_FIELD(2097, __GXData->suTs1[tcoord], 1, 16, t_bias); - GX_WRITE_RAS_REG(__GXData->suTs0[tcoord]); - GX_WRITE_RAS_REG(__GXData->suTs1[tcoord]); - __GXData->bpSentNot = 0; -} - -void __GXSetSUTexRegs(void) { - u32 nStages; - u32 nIndStages; - u32 i; - u32 map; - u32 tmap; - u32 coord; - u32* ptref; - - if (__GXData->tcsManEnab != 0xFF) { - nStages = GET_REG_FIELD(__GXData->genMode, 4, 10) + 1; - nIndStages = GET_REG_FIELD(__GXData->genMode, 3, 16); - for (i = 0; i < nIndStages; i++) { - switch (i) { - case 0: - 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 __GXGetSUTexSize(GXTexCoordID coord, u16* width, u16* height) { - *width = (u16)__GXData->suTs0[coord] + 1; - *height = (u16)__GXData->suTs1[coord] + 1; -} - -void __GXSetTmemConfig(u32 config) { - switch (config) { - case 2: - GX_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/src/dolphin/gx/GXTransform.c b/src/dolphin/gx/GXTransform.c deleted file mode 100644 index e454017..0000000 --- a/src/dolphin/gx/GXTransform.c +++ /dev/null @@ -1,608 +0,0 @@ -#include -#include -#include - -#include "__gx.h" - -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(const 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) { - ASSERTMSGLINE(370, ptr, "GXGet*: invalid null pointer"); - - ptr[0] = (u32)__GXData->projType != GX_PERSPECTIVE ? 1.0f : 0.0f; - -#if DEBUG - ptr[1] = __GXData->projMtx[0]; - ptr[2] = __GXData->projMtx[1]; - ptr[3] = __GXData->projMtx[2]; - ptr[4] = __GXData->projMtx[3]; - ptr[5] = __GXData->projMtx[4]; - ptr[6] = __GXData->projMtx[5]; -#else - Copy6Floats(__GXData->projMtx, &ptr[1]); -#endif -} - -static void WriteMTXPS4x3(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(const Mtx mtx, u32 id) { - u32 reg; - u32 addr; - - CHECK_GXBEGIN(507, "GXLoadPosMtxImm"); - - addr = id * 4; - reg = addr | 0xB0000; - - GX_WRITE_U8(0x10); - GX_WRITE_U32(reg); -#if DEBUG - GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); - GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); - GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); - GX_WRITE_MTX_ELEM(addr + 3, mtx[0][3]); - GX_WRITE_MTX_ELEM(addr + 4, mtx[1][0]); - GX_WRITE_MTX_ELEM(addr + 5, mtx[1][1]); - GX_WRITE_MTX_ELEM(addr + 6, mtx[1][2]); - GX_WRITE_MTX_ELEM(addr + 7, mtx[1][3]); - GX_WRITE_MTX_ELEM(addr + 8, mtx[2][0]); - GX_WRITE_MTX_ELEM(addr + 9, mtx[2][1]); - GX_WRITE_MTX_ELEM(addr + 10, mtx[2][2]); - GX_WRITE_MTX_ELEM(addr + 11, mtx[2][3]); -#else - WriteMTXPS4x3(mtx, &GXWGFifo.f32); -#endif -} - -void GXLoadPosMtxIndx(u16 mtx_indx, u32 id) { - u32 offset; - u32 reg; - - CHECK_GXBEGIN(555, "GXLoadPosMtxIndx"); - offset = id * 4; - reg = 0; - SET_REG_FIELD(561, reg, 12, 0, offset); - SET_REG_FIELD(563, reg, 4, 12, 11); - SET_REG_FIELD(563, reg, 16, 16, mtx_indx); - GX_WRITE_U8(0x20); - GX_WRITE_U32(reg); -#if DEBUG - __GXShadowIndexState(4, reg); -#endif -} - -void GXLoadNrmMtxImm(const Mtx mtx, u32 id) { - u32 reg; - u32 addr; - - CHECK_GXBEGIN(588, "GXLoadNrmMtxImm"); - - addr = id * 3 + 0x400; - reg = addr | 0x80000; - - GX_WRITE_U8(0x10); - GX_WRITE_U32(reg); -#if DEBUG - GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); - GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); - GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); - GX_WRITE_MTX_ELEM(addr + 3, mtx[1][0]); - GX_WRITE_MTX_ELEM(addr + 4, mtx[1][1]); - GX_WRITE_MTX_ELEM(addr + 5, mtx[1][2]); - GX_WRITE_MTX_ELEM(addr + 6, mtx[2][0]); - GX_WRITE_MTX_ELEM(addr + 7, mtx[2][1]); - GX_WRITE_MTX_ELEM(addr + 8, mtx[2][2]); -#else - WriteMTXPS3x3from3x4((void*)mtx, &GXWGFifo.f32); -#endif -} - -void GXLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id) { - u32 reg; - u32 addr; - - CHECK_GXBEGIN(633, "GXLoadNrmMtxImm3x3"); - - addr = id * 3 + 0x400; - reg = addr | 0x80000; - - GX_WRITE_U8(0x10); - GX_WRITE_U32(reg); -#if DEBUG - GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); - GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); - GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); - GX_WRITE_MTX_ELEM(addr + 3, mtx[1][0]); - GX_WRITE_MTX_ELEM(addr + 4, mtx[1][1]); - GX_WRITE_MTX_ELEM(addr + 5, mtx[1][2]); - GX_WRITE_MTX_ELEM(addr + 6, mtx[2][0]); - GX_WRITE_MTX_ELEM(addr + 7, mtx[2][1]); - GX_WRITE_MTX_ELEM(addr + 8, mtx[2][2]); -#else - WriteMTXPS3x3((void*)mtx, &GXWGFifo.f32); -#endif -} - -void GXLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id) { - u32 offset; - u32 reg; - - CHECK_GXBEGIN(679, "GXLoadNrmMtxIndx3x3"); - offset = id * 3 + 0x400; - reg = 0; - SET_REG_FIELD(685, reg, 12, 0, offset); - SET_REG_FIELD(687, reg, 4, 12, 8); - SET_REG_FIELD(687, reg, 16, 16, mtx_indx); - GX_WRITE_U8(0x28); - GX_WRITE_U32(reg); -#if DEBUG - __GXShadowIndexState(5, reg); -#endif -} - -void GXSetCurrentMtx(u32 id) { - CHECK_GXBEGIN(708, "GXSetCurrentMtx"); - SET_REG_FIELD(712, __GXData->matIdxA, 6, 0, id); - __GXSetMatrixIndex(GX_VA_PNMTXIDX); -} - -void GXLoadTexMtxImm(const 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; - ASSERTMSGLINE(751, type == GX_MTX3x4, "GXLoadTexMtx: Invalid matrix type"); - } 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 GXLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type) { - u32 offset; - u32 reg; - u32 count; - - CHECK_GXBEGIN(813, "GXLoadTexMtxIndx"); - - if (id >= GX_PTTEXMTX0) { - offset = (id - GX_PTTEXMTX0) * 4 + 0x500; - ASSERTMSGLINE(0x337, type == GX_MTX3x4, "GXLoadTexMtx: Invalid matrix type"); - } else { - offset = id * 4; - } - count = (type == GX_MTX2x4) ? 8 : 12; - - reg = 0; - SET_REG_FIELD(830, reg, 12, 0, offset); - SET_REG_FIELD(831, reg, 4, 12, (count - 1)); - SET_REG_FIELD(832, reg, 16, 16, mtx_indx); - GX_WRITE_U8(0x30); - GX_WRITE_U32(reg); -#if DEBUG - __GXShadowIndexState(6, reg); -#endif -} - -void __GXSetViewport(void) { - f32 sx; - f32 sy; - f32 sz; - f32 ox; - f32 oy; - f32 oz; - f32 zmin; - f32 zmax; - u32 reg; - - 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); -} - -void GXGetViewportv(f32* vp) { - ASSERTMSGLINE(968, vp, "GXGet*: invalid null pointer"); - -#if DEBUG - vp[0] = __GXData->vpLeft; - vp[1] = __GXData->vpTop; - vp[2] = __GXData->vpWd; - vp[3] = __GXData->vpHt; - vp[4] = __GXData->vpNearz; - vp[5] = __GXData->vpFarz; -#else - Copy6Floats(&__GXData->vpLeft, vp); -#endif -} - -#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 GXSetZScaleOffset(f32 scale, f32 offset) { - f32 sz; - f32 oz; - f32 zmin; - f32 zmax; - - CHECK_GXBEGIN(996, "GXSetZScaleOffset"); - - oz = offset * 1.6777215e7f; - __GXData->zOffset = oz; - - sz = (scale * 1.6777215e7f) + 1.0f; - __GXData->zScale = sz; - - zmin = __GXData->vpNearz * sz; - zmax = __GXData->vpFarz * sz; - sz = zmax - zmin; - oz = oz + zmax; - - GX_WRITE_XF_REG_F_(0x1C, sz); - GX_WRITE_XF_REG_F_(0x1F, oz); - - __GXData->bpSentNot = 1; -} - -void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht) { - u32 tp; - u32 lf; - u32 bm; - u32 rt; - - CHECK_GXBEGIN(1048, "GXSetScissor"); - ASSERTMSGLINE(1049, left < 1706, "GXSetScissor: Left origin > 1708"); - ASSERTMSGLINE(1050, top < 1706, "GXSetScissor: top origin > 1708"); - ASSERTMSGLINE(1051, left + wd < 1706, "GXSetScissor: right edge > 1708"); - ASSERTMSGLINE(1052, top + ht < 1706, "GXSetScissor: bottom edge > 1708"); - - 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 GXGetScissor(u32* left, u32* top, u32* wd, u32* ht) { - u32 tp; - u32 lf; - u32 bm; - u32 rt; - - ASSERTMSGLINE(1089, left && top && wd && ht, "GXGet*: invalid null pointer"); - - tp = __GXData->suScis0 & 0x7FF; - lf = (__GXData->suScis0 & 0x7FF000) >> 12; - bm = __GXData->suScis1 & 0x7FF; - rt = (__GXData->suScis1 & 0x7FF000) >> 12; - - *left = lf - 342; - *top = tp - 342; - *wd = rt - lf + 1; - *ht = bm - tp + 1; -} - -void GXSetScissorBoxOffset(s32 x_off, s32 y_off) { - u32 reg = 0; - u32 hx; - u32 hy; - - CHECK_GXBEGIN(1119, "GXSetScissorBoxOffset"); - - ASSERTMSGLINE(1122, (u32)(x_off + 342) < 2048, "GXSetScissorBoxOffset: Invalid X offset"); - ASSERTMSGLINE(1124, (u32)(y_off + 342) < 2048, "GXSetScissorBoxOffset: Invalid Y offset"); - - hx = (u32)(x_off + 342) >> 1; - hy = (u32)(y_off + 342) >> 1; - - SET_REG_FIELD(1129, reg, 10, 0, hx); - SET_REG_FIELD(1130, reg, 10, 10, hy); - SET_REG_FIELD(1131, reg, 8, 24, 0x59); - GX_WRITE_RAS_REG(reg); - __GXData->bpSentNot = 0; -} - -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/src/dolphin/gx/GXVerifRAS.c b/src/dolphin/gx/GXVerifRAS.c deleted file mode 100644 index f1aa966..0000000 --- a/src/dolphin/gx/GXVerifRAS.c +++ /dev/null @@ -1,640 +0,0 @@ -#if DEBUG - -#include - -#include - -#include "__gx.h" - -static char __data_0[] = "RGB multisample"; -static char _305[] = "GX_TEVPREV(color)"; -static char _306[] = "GX_TEVPREV(alpha)"; -static char _307[] = "GX_TEVREG0(color)"; -static char _308[] = "GX_TEVREG0(alpha)"; -static char _309[] = "GX_TEVREG1(color)"; -static char _310[] = "GX_TEVREG1(alpha)"; -static char _311[] = "GX_TEVREG2(color)"; -static char _312[] = "GX_TEVREG2(alpha)"; - -static char* TevRegNames[8] = {0}; - -#define SOME_GET_REG_MACRO(reg, size, shift) ((u32)((reg) << (shift)) & ((1 << (size)) - 2)) -#define SOME_GET_REG_MACRO2(reg, size, shift) ((u32)((reg) >> (shift)) & ((1 << (size)) - 2)) - -void __GXVerifySU(void) { - s32 scis_l; - s32 scis_r; - s32 scis_t; - s32 scis_b; - - scis_l = (u32)GET_REG_FIELD(__gxVerif->rasRegs[32], 11, 12); - scis_t = (u32)GET_REG_FIELD(__gxVerif->rasRegs[32], 11, 0); - scis_r = (u32)GET_REG_FIELD(__gxVerif->rasRegs[33], 11, 12); - scis_b = (u32)GET_REG_FIELD(__gxVerif->rasRegs[33], 11, 0); - - scis_l = scis_l - (u32)SOME_GET_REG_MACRO(__gxVerif->rasRegs[89], 11, 1); - scis_r = scis_r - (u32)SOME_GET_REG_MACRO(__gxVerif->rasRegs[89], 11, 1); - scis_t = scis_t - (u32)SOME_GET_REG_MACRO2(__gxVerif->rasRegs[89], 11, 9); - scis_b = scis_b - (u32)SOME_GET_REG_MACRO2(__gxVerif->rasRegs[89], 11, 9); - - if (scis_l < 0 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_LEFT]) { - __GX_WARNF(GXWARN_SCISSOR_RECT_LEFT, 0); - } - - if (scis_t < 0 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_TOP]) { - __GX_WARNF(GXWARN_SCISSOR_RECT_TOP, 0); - } - - switch (__gxVerif->rasRegs[67] & 7) { - case 4: - case 5: - if (scis_r > 719 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { - __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 719, "YUV"); - } - - if (scis_b > 575 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { - __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 575, "YUV"); - } - break; - case 0: - case 1: - case 3: - if (scis_r > 639 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { - __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 639, "RGB"); - } - - if (scis_b > 527 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { - __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 527, "RGB"); - } - break; - case 2: - if (scis_r > 639 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { - __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 639, __data_0); - } - - if (scis_b > 263 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { - __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 263, __data_0); - } - break; - } -} - -void __GXVerifyBUMP(void) { - u32 i; - u32 nBmp; - u32 nTev; - u32 nTex; - u32 matrix; - - nBmp = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 16); - nTex = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 0); - nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; - - for (i = 0; i < nTev; i++) { - matrix = GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 4, 9); - if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { - if ((u32)(__gxVerif->rasRegs[16 + i] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[7]) { - sprintf(__gxvDummyStr, __gxvWarnings[7], i); - __gxVerif->cb(__gxvWarnLev[7], 7U, __gxvDummyStr); - } - - if ((GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 2, 7) != 0 || matrix != 0) - && GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 2, 0) >= nBmp && __gxVerif->verifyLevel >= __gxvWarnLev[8]) { - sprintf(__gxvDummyStr, __gxvWarnings[8], i); - __gxVerif->cb(__gxvWarnLev[8], 8U, __gxvDummyStr); - } - - if (matrix != 0) { - matrix = (matrix & 3) - 1; - if (((u32)(__gxVerif->rasRegs[(matrix * 3) + 6] & 0xFF000000) + 0x01000000 == 0 - || (u32)(__gxVerif->rasRegs[(matrix * 3) + 7] & 0xFF000000) + 0x01000000 == 0U - || (u32)(__gxVerif->rasRegs[(matrix * 3) + 8] & 0xFF000000) + 0x01000000 == 0U) && __gxVerif->verifyLevel >= __gxvWarnLev[9]) { - sprintf(__gxvDummyStr, __gxvWarnings[9], matrix, i); - __gxVerif->cb(__gxvWarnLev[9], 9U, __gxvDummyStr); - } - } - } - } - - if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { - if (nBmp != 0 && (u32)(__gxVerif->rasRegs[0x27] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[10]) { - __gxVerif->cb(__gxvWarnLev[10], 0xAU, __gxvWarnings[10]); - } - - if (nBmp != 0 && (u32)(__gxVerif->rasRegs[0x25] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[11]) { - sprintf(__gxvDummyStr, __gxvWarnings[11], 0U, 1); - __gxVerif->cb(__gxvWarnLev[11], 0xBU, __gxvDummyStr); - } - - if (nBmp > 2U && (u32)(__gxVerif->rasRegs[0x26] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[11]) { - sprintf(__gxvDummyStr, __gxvWarnings[11], 2U, 3); - __gxVerif->cb(__gxvWarnLev[11], 0xBU, __gxvDummyStr); - } - - if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 3) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { - sprintf(__gxvDummyStr, __gxvWarnings[12], 0U); - __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); - } - - if (nBmp > 1U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 9) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { - sprintf(__gxvDummyStr, __gxvWarnings[12], 1U); - __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); - } - - if (nBmp > 2U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 15) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { - sprintf(__gxvDummyStr, __gxvWarnings[12], 2U); - __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); - } - - if (nBmp > 3U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 21) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { - sprintf(__gxvDummyStr, __gxvWarnings[12], 3U); - __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); - } - - if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x10], 1, 20) && __gxVerif->verifyLevel >= __gxvWarnLev[13]) { - __gxVerif->cb(__gxvWarnLev[13], 0xDU, __gxvWarnings[13]); - } - - if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x10], 2, 7) != 0 && __gxVerif->verifyLevel >= __gxvWarnLev[14]) { - __gxVerif->cb(__gxvWarnLev[14], 0xEU, __gxvWarnings[14]); - } - - if ((u32)(__gxVerif->rasRegs[0xF] & 0xFF000000) + 0x01000000 == 0 && (nTex != 0 || nBmp != 0) && __gxVerif->verifyLevel >= __gxvWarnLev[15]) { - __gxVerif->cb(__gxvWarnLev[15], 0xFU, __gxvWarnings[15]); - } - } -} - -#define SOMEINDEX(index) (index & 3) + ((index * 8) & ~0x1F) - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -void __GXVerifyTEX(void) { - u32 i; - u32 nBmp; - u32 nTev; - u32 nTex; - u32 enabled; - u32 texId; - u32 direct[8]; - u32 indirect[8]; - u32 h2; - u32 w2; - u32 nlevels; - - nBmp = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 16); - nTex = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 0); - nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; - - for (i = 0; i < 8; i++) { - direct[i] = 0; - indirect[i] = 0; - } - - for (i = 0; i < nTev + nBmp; i++) { - if (i < nTev) { - if (__gxVerif->verifyLevel >= 1) { - if ((__gxVerif->rasRegs[(i >> 1U) + 0x28] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[16]) { - sprintf(__gxvDummyStr, __gxvWarnings[16], i); - __gxVerif->cb(__gxvWarnLev[16], 16, __gxvDummyStr); - } - - if (i & 1) { - enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 18); - if (enabled && (GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 15) >= nTex) && __gxVerif->verifyLevel >= __gxvWarnLev[17]) { - sprintf(__gxvDummyStr, __gxvWarnings[17], i); - __gxVerif->cb(__gxvWarnLev[17], 17, __gxvDummyStr); - } - texId = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 12); - } else { - enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 6); - if (enabled && (GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 3) >= nTex) && __gxVerif->verifyLevel >= __gxvWarnLev[17]) { - sprintf(__gxvDummyStr, __gxvWarnings[17], i); - __gxVerif->cb(__gxvWarnLev[17], 17, __gxvDummyStr); - } - texId = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 0); - } - - if (enabled) { - direct[texId] = 1; - } - } - } else { - enabled = 1; - if ((i - nTev) == 0) { - texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 0); - } else if ((i - nTev) == 1U) { - texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 6); - } else if ((i - nTev) == 2U) { - texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 12); - } else { - texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 18); - } - - if (!indirect[texId] && direct[texId] && __gxVerif->verifyLevel >= __gxvWarnLev[18]) { - sprintf(__gxvDummyStr, __gxvWarnings[18], texId); - __gxVerif->cb(__gxvWarnLev[18], 18, __gxvDummyStr); - } - indirect[texId] = 1; - } - - if (enabled) { - if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { - if (((u32)(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 - || (u32)(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 - || (u32)(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 - || (u32)(__gxVerif->rasRegs[0x8C + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 - || (u32)(__gxVerif->rasRegs[0x90 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[19]) { - sprintf(__gxvDummyStr, __gxvWarnings[19], texId); - __gxVerif->cb(__gxvWarnLev[19], 19, __gxvDummyStr); - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x8C + SOMEINDEX(texId)], 1, 21) == 0 - && (u32)(__gxVerif->rasRegs[0x94 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[20]) { - sprintf(__gxvDummyStr, __gxvWarnings[20], texId); - __gxVerif->cb(__gxvWarnLev[20], 20, __gxvDummyStr); - } - - if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) - && (__gxVerif->rasRegs[0x98 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[21]) { - sprintf(__gxvDummyStr, __gxvWarnings[21], texId); - __gxVerif->cb(__gxvWarnLev[21], 21, __gxvDummyStr); - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1 == 0) { - w2 = 1; - } else { - w2 = 1; - while (!(w2 & (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1))) { - w2 *= 2; - } - w2 = (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1) == w2; - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1 == 0) { - h2 = 1; - } else { - h2 = 1; - while (!(h2 & (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1))) { - h2 *= 2; - } - h2 = (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1) == h2; - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) && !w2 && __gxVerif->verifyLevel >= __gxvWarnLev[22]) { - sprintf(__gxvDummyStr, __gxvWarnings[22], "Width", texId); - __gxVerif->cb(__gxvWarnLev[22], 22, __gxvDummyStr); - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) && !h2 && __gxVerif->verifyLevel >= __gxvWarnLev[22]) { - sprintf(__gxvDummyStr, __gxvWarnings[22], "Height", texId); - __gxVerif->cb(__gxvWarnLev[22], 22, __gxvDummyStr); - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 0) && !w2 && __gxVerif->verifyLevel >= __gxvWarnLev[23]) { - sprintf(__gxvDummyStr, __gxvWarnings[23], "S", texId); - __gxVerif->cb(__gxvWarnLev[23], 23, __gxvDummyStr); - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 2) && !h2 && __gxVerif->verifyLevel >= __gxvWarnLev[23]) { - sprintf(__gxvDummyStr, __gxvWarnings[23], "T", texId); - __gxVerif->cb(__gxvWarnLev[23], 23, __gxvDummyStr); - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) != 0 - && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) - && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 1 - && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 5 && __gxVerif->verifyLevel >= __gxvWarnLev[24]) { - sprintf(__gxvDummyStr, __gxvWarnings[24], texId); - __gxVerif->cb(__gxvWarnLev[24], 24, __gxvDummyStr); - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 0) > (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 8) && __gxVerif->verifyLevel >= __gxvWarnLev[25]) { - sprintf(__gxvDummyStr, __gxvWarnings[25], texId); - __gxVerif->cb(__gxvWarnLev[25], 25, __gxvDummyStr); - } - - for ( - nlevels = 0; - ( - MAX((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1, - (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1) >> nlevels - ) != 0; - nlevels++) { - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 8) > (nlevels - 1) * 16 && __gxVerif->verifyLevel >= __gxvWarnLev[26]) { - sprintf(__gxvDummyStr, __gxvWarnings[26], texId); - __gxVerif->cb(__gxvWarnLev[26], 26, __gxvDummyStr); - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 21) && GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 8) && __gxVerif->verifyLevel >= __gxvWarnLev[27]) { - sprintf(__gxvDummyStr, __gxvWarnings[27], texId); - __gxVerif->cb(__gxvWarnLev[27], 27, __gxvDummyStr); - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 19) - && (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) == 0 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 6 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 4) != 1 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 8) != 0 - || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 21)) && __gxVerif->verifyLevel >= __gxvWarnLev[28]) { - sprintf(__gxvDummyStr, __gxvWarnings[28], texId); - __gxVerif->cb(__gxvWarnLev[28], 28, __gxvDummyStr); - } - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 18) != 0) { - if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 4 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 4) != 1) && __gxVerif->verifyLevel >= __gxvWarnLev[29]) { - sprintf(__gxvDummyStr, __gxvWarnings[29], texId); - __gxVerif->cb(__gxvWarnLev[29], 29, __gxvDummyStr); - } - - if ((!GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 17) || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) != 1 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 19) != 0) && __gxVerif->verifyLevel >= __gxvWarnLev[30]) { - sprintf(__gxvDummyStr, __gxvWarnings[30], texId); - __gxVerif->cb(__gxvWarnLev[30], 30, __gxvDummyStr); - } - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 17) != 0) { - if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) && __gxVerif->verifyLevel >= __gxvWarnLev[31]) { - sprintf(__gxvDummyStr, __gxvWarnings[31], texId); - __gxVerif->cb(__gxvWarnLev[31], 31, __gxvDummyStr); - } - - if ((!GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 18) || 0) && __gxVerif->verifyLevel >= __gxvWarnLev[30]) { - sprintf(__gxvDummyStr, __gxvWarnings[30], texId); - __gxVerif->cb(__gxvWarnLev[30], 30, __gxvDummyStr); - } - } - } - } -} - -#if DEBUG -static char _521[] = "A"; -static char _522[] = "B"; -static char _523[] = "C"; -static char _524[] = "D"; -asm void __GXVerifyTEV(void) { - nofralloc -#include "../../nonmatchings/__GXVerifyTEV.s" -} -#pragma peephole on -#else -void __GXVerifyTEV(void) { - u32 i; // r31 - u32 nTev; // r29 - u32 nCol; // r28 - u32 enabled; // r30 - u32 color; // r27 - u32 Clh[4]; // r1+0x38 - u32 Alh[4]; // r1+0x28 - u32 Cwritten[4]; // r1+0x18 - u32 Awritten[4]; // r1+0x8 - - nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; - nCol = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 4); - nCol; - - for (i = 0; i < 4; i++) { - Clh[i] = 0; - Alh[i] = 0; - Cwritten[i] = 0; - Awritten[i] = 0; - } - - for (i = 0; i < nTev; i++) { - if (__gxVerif->verifyLevel >= GX_WARN_SEVERE - && (((u32) ((__gxVerif->rasRegs[(i * 2) + 0xC0] & 0xFF000000) + 0x01000000) == 0U) || ((u32) ((__gxVerif->rasRegs[(i * 2) + 0xC1] & 0xFF000000) + 0x01000000) == 0U))) { - sprintf(__gxvDummyStr, __gxvWarnings[32], i); - __gxVerif->cb(1, 0x20U, __gxvDummyStr); - } - - if (i & 1) { - color = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 19); - } else { - color = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 7); - } - - if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM && ((color == 0 && nCol < 1) || (color == 1 && nCol < 2))) { - sprintf(__gxvDummyStr, __gxvWarnings[33], i); - __gxVerif->cb(1, 0x21U, __gxvDummyStr); - } - - if (i & 1) { - enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 18); - } else { - enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 6); - } - - if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { - if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) == 9)) { - sprintf(__gxvDummyStr, __gxvWarnings[0x22], "A", i); - __gxVerif->cb(1, 0x22U, __gxvDummyStr); - } - - if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) == 9)) { - sprintf(__gxvDummyStr, __gxvWarnings[0x22], "B", i); - __gxVerif->cb(1, 0x22U, __gxvDummyStr); - } - - if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) == 9)) { - sprintf(__gxvDummyStr, __gxvWarnings[0x22], "C", i); - __gxVerif->cb(1, 0x22U, __gxvDummyStr); - } - - if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) == 9)) { - sprintf(__gxvDummyStr, __gxvWarnings[0x22], "D", i); - __gxVerif->cb(1, 0x22U, __gxvDummyStr); - } - - if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) == 4) { - sprintf(__gxvDummyStr, __gxvWarnings[0x23], "A", i); - __gxVerif->cb(1, 0x23U, __gxvDummyStr); - } - - if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) == 4) { - sprintf(__gxvDummyStr, __gxvWarnings[0x23], "B", i); - __gxVerif->cb(1, 0x23U, __gxvDummyStr); - } - - if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) == 4) { - sprintf(__gxvDummyStr, __gxvWarnings[0x23], "C", i); - __gxVerif->cb(1, 0x23U, __gxvDummyStr); - } - - if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4) == 4) { - sprintf(__gxvDummyStr, __gxvWarnings[0x23], "D", i); - __gxVerif->cb(1, 0x23U, __gxvDummyStr); - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { - if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)]) { - sprintf(__gxvDummyStr, __gxvWarnings[0x24], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 0xCU) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 0xDU) & 7); - __gxVerif->cb(1, 0x24U, __gxvDummyStr); - } - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { - if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)]) { - sprintf(__gxvDummyStr, __gxvWarnings[0x24], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8U) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 9U) & 7); - __gxVerif->cb(1, 0x24U, __gxvDummyStr); - } - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { - if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)]) { - sprintf(__gxvDummyStr, __gxvWarnings[0x24], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4U) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 5U) & 7); - __gxVerif->cb(1, 0x24U, __gxvDummyStr); - } - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { - if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 0) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 1)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 1)]) { - sprintf(__gxvDummyStr, __gxvWarnings[0x24], "D", i, (__gxVerif->rasRegs[(i * 2) + 0xC0] & 1) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 1U) & 7); - __gxVerif->cb(1, 0x24U, __gxvDummyStr); - } - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 4, 14) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)] == 0U) { - sprintf(__gxvDummyStr, __gxvWarnings[0x25], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)); - __gxVerif->cb(1, 0x25U, __gxvDummyStr); - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 11) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)] == 0U) { - sprintf(__gxvDummyStr, __gxvWarnings[0x25], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)); - __gxVerif->cb(1, 0x25U, __gxvDummyStr); - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 8) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)] == 0U) { - sprintf(__gxvDummyStr, __gxvWarnings[0x25], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)); - __gxVerif->cb(1, 0x25U, __gxvDummyStr); - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 3) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4)] == 0U) { - sprintf(__gxvDummyStr, __gxvWarnings[0x25], "D", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4)); - __gxVerif->cb(1, 0x25U, __gxvDummyStr); - } - } - - if (__gxVerif->verifyLevel >= GX_WARN_ALL) { - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) <= 7) { - if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)]) { - sprintf(__gxvDummyStr, __gxvWarnings[0x26], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)); - __gxVerif->cb(3, 0x26U, __gxvDummyStr); - } - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) <= 7) { - if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)]) { - sprintf(__gxvDummyStr, __gxvWarnings[0x26], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)); - __gxVerif->cb(3, 0x26U, __gxvDummyStr); - } - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) <= 7) { - if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)]) { - sprintf(__gxvDummyStr, __gxvWarnings[0x26], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)); - __gxVerif->cb(3, 0x26U, __gxvDummyStr); - } - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)] != 0) { - sprintf(__gxvDummyStr, __gxvWarnings[0x27], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 0xDU)); - __gxVerif->cb(3, 0x27U, __gxvDummyStr); - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)] != 0) { - sprintf(__gxvDummyStr, __gxvWarnings[0x27], "B", i, ((__gxVerif->rasRegs[(i * 2) + 0xC1] >> 0xAU) & 7)); - __gxVerif->cb(3, 0x27U, __gxvDummyStr); - } - - if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)] != 0) { - sprintf(__gxvDummyStr, __gxvWarnings[0x27], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7U)); - __gxVerif->cb(3, 0x27U, __gxvDummyStr); - } - } - Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 2, 22)] = 1; - Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 22)] = 1; - Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 2, 22)] = (!GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 19)); - Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 22)] = (!GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 1, 19)); - } - - for (i = 0; i < 4; i++) { - if (Cwritten[i] != 0U) { - __gxVerif->rasRegs[(i * 2) + 0xE1] = (__gxVerif->rasRegs[(i * 2) + 0xE1] & 0xFFFFFF) | 0xFF000000; - } - if (Awritten[i] != 0U) { - __gxVerif->rasRegs[(i * 2) + 0xE0] = (__gxVerif->rasRegs[(i * 2) + 0xE0] & 0xFFFFFF) | 0xFF000000; - } - } - - if (GET_REG_FIELD(__gxVerif->rasRegs[0xF5], 2, 2) && __gxVerif->verifyLevel >= 1) { - if ((u32) ((__gxVerif->rasRegs[0xF4] & 0xFF000000) + 0x01000000) == 0U) { - __gxVerif->cb(1, 0x28U, __gxvWarnings[0x28]); - } - if (!enabled) { - __gxVerif->cb(1, 0x29U, __gxvWarnings[0x29]); - } - } - - if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM) { - if (GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC0], 2, 22)) { - __gxVerif->cb(2, 0x2AU, __gxvWarnings[0x2A]); - } - if (GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 22)) { - __gxVerif->cb(2, 0x2BU, __gxvWarnings[0x2B]); - } - } - - if (__gxVerif->verifyLevel >= GX_WARN_ALL) { - if (!GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC0], 1, 19)) { - __gxVerif->cb(3, 0x2CU, __gxvWarnings[0x2C]); - } - if (!GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 1, 19)) { - __gxVerif->cb(3, 0x2DU, __gxvWarnings[0x2D]); - } - } - - if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM && GET_REG_FIELD(__gxVerif->rasRegs[0x43], 1, 6) && (GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 2, 22) || ((u32) GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 3, 16) != 7) || ((u32) GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 3, 19) != 7))) { - __gxVerif->cb(2, 0x2EU, __gxvWarnings[0x2E]); - } -} -#endif - -void __GXVerifyPE(void) { - u32 i; - - if (__gxVerif->verifyLevel >= GX_WARN_SEVERE && GET_REG_FIELD(__gxVerif->rasRegs[0x41], 1, 0) && GET_REG_FIELD(__gxVerif->rasRegs[0x41], 1, 1) && __gxVerif->verifyLevel >= __gxvWarnLev[0x2F]) { - __gxVerif->cb(__gxvWarnLev[0x2F], 0x2FU, __gxvWarnings[0x2F]); - } - - if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM) { - if (GET_REG_FIELD(__gxVerif->rasRegs[0], 1, 9) && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) != 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x31]) { - __gxVerif->cb(__gxvWarnLev[0x31], 0x31U, __gxvWarnings[0x31]); - } - if (!GET_REG_FIELD(__gxVerif->rasRegs[0], 1, 9) && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) == 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x32]) { - __gxVerif->cb(__gxvWarnLev[0x32], 0x32U, __gxvWarnings[0x32]); - } - } - - if (__gxVerif->verifyLevel >= GX_WARN_ALL) { - for (i = 0; i < 4; i++) { - if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 4) > GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 12) || (u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 12) > (u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 20)) - && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) == 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x33]) { - sprintf(__gxvDummyStr, __gxvWarnings[0x33], i); - __gxVerif->cb(__gxvWarnLev[0x33], 0x33U, __gxvDummyStr); - } - } - } -} - -#endif diff --git a/src/dolphin/gx/GXVerifXF.c b/src/dolphin/gx/GXVerifXF.c deleted file mode 100644 index 1e45aab..0000000 --- a/src/dolphin/gx/GXVerifXF.c +++ /dev/null @@ -1,1002 +0,0 @@ -#if DEBUG - -#include - -#include - -#include "__gx.h" - -static u8 internalDebug; -static u32 DumpCount; -static s8 XFBuf[128]; -static u32 numRegularTextures; -static u32 numBumpmapTextures; -static u32 numColor0Textures; -static u32 numColor1Textures; -static u32 numColorTextures; -static s32 XFChannel = -1; - -static GXAttr TextureEnums[8] = { - GX_VA_TEX0, - GX_VA_TEX1, - GX_VA_TEX2, - GX_VA_TEX3, - GX_VA_TEX4, - GX_VA_TEX5, - GX_VA_TEX6, - GX_VA_TEX7, -}; - -static GXAttr MtxIdxEnums[9] = { - GX_VA_PNMTXIDX, - GX_VA_TEX0MTXIDX, - GX_VA_TEX1MTXIDX, - GX_VA_TEX2MTXIDX, - GX_VA_TEX3MTXIDX, - GX_VA_TEX4MTXIDX, - GX_VA_TEX5MTXIDX, - GX_VA_TEX6MTXIDX, - GX_VA_TEX7MTXIDX, -}; - -static u8 lightRegisterNames[13][256] = { - "Light Color RGBA", - "Cosine Attenuation A0", - "Cosine Attenuation A1", - "Cosine Attenuation A2", - "Distance Attenuation K0", - "Distance Attenuation K1", - "Distance Attenuation K2", - "X Light Position / Infinite Light X Direction", - "Y Light Position / Infinite Light Y Direction", - "Z Light Position / Infinite Light Z Direction", - "X Light Direction / Half Angle X Component", - "Y Light Direction / Half Angle Y Component", - "Z Light Direction / Half Angle Z Component", -}; - -#define LOWORD(var) (((u16 *)&(var))[0]) -#define HIWORD(var) (((u16 *)&(var))[1]) - -#define BYTE0(var) (((u8 *)&(var))[0]) -#define BYTE1(var) (((u8 *)&(var))[1]) -#define BYTE2(var) (((u8 *)&(var))[2]) -#define BYTE3(var) (((u8 *)&(var))[3]) - -static void CountTextureTypes(void) { - u32 i; - u32 texgen_type; - - numRegularTextures = 0; - numBumpmapTextures = 0; - numColor0Textures = 0; - numColor1Textures = 0; - - for (i = 0; i < __gxVerif->xfRegs[0x3F]; i++) { - texgen_type = BYTE3(__gxVerif->xfRegs[i + 64]); - texgen_type = (texgen_type >> 4) & 7; - if (texgen_type == 0) { - numRegularTextures++; - } else if (texgen_type == 1) { - numBumpmapTextures++; - } else if (texgen_type == 2) { - numColor0Textures++; - } else if (texgen_type == 3) { - numColor1Textures++; - } else { - if (__gxVerif->verifyLevel >= __gxvWarnLev[52]) { - __GX_WARNF(GXWARN_INVALID_TG_TYPE, texgen_type, i); - } - } - } - numColorTextures = numColor0Textures + numColor1Textures; -} - -static void InitializeXFVerifyData(void) { - CountTextureTypes(); -} - -static void CheckDirty(u32 index, const char* name) { - if (!__gxVerif->xfRegsDirty[index - 0x1000] && __gxVerif->verifyLevel >= __gxvWarnLev[53]) { - __GX_WARNF(GXWARN_XF_CTRL_UNINIT, index, name); - } -} - -static void CheckClean(u32 index, const char* name) { - if (__gxVerif->xfRegsDirty[index - 0x1000] && __gxVerif->verifyLevel >= __gxvWarnLev[54]) { - __GX_WARNF(GXWARN_XF_CTRL_INIT, index, name); - } -} - -static void CheckCTGColors(void) { - if ((u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) > 2 && __gxVerif->verifyLevel >= __gxvWarnLev[120]) { - __GX_WARNF(120, (u8)(BYTE3(__gxVerif->xfRegs[9]) & 3)); - } -} - -static GXBool __GXVertexPacketHas(GXAttr attr) { - switch (attr) { - case GX_VA_POS: return GET_REG_FIELD(__GXData->vcdLo, 2, 9) != 0; - case GX_VA_NRM: return __GXData->hasNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) != 0 : GX_FALSE; - case GX_VA_NBT: return __GXData->hasBiNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) != 0 : GX_FALSE; - case GX_VA_CLR0: return GET_REG_FIELD(__GXData->vcdLo, 2, 13) != 0; - case GX_VA_CLR1: return GET_REG_FIELD(__GXData->vcdLo, 2, 15) != 0; - case GX_VA_TEX0: return GET_REG_FIELD(__GXData->vcdHi, 2, 0) != 0; - case GX_VA_TEX1: return GET_REG_FIELD(__GXData->vcdHi, 2, 2) != 0; - case GX_VA_TEX2: return GET_REG_FIELD(__GXData->vcdHi, 2, 4) != 0; - case GX_VA_TEX3: return GET_REG_FIELD(__GXData->vcdHi, 2, 6) != 0; - case GX_VA_TEX4: return GET_REG_FIELD(__GXData->vcdHi, 2, 8) != 0; - case GX_VA_TEX5: return GET_REG_FIELD(__GXData->vcdHi, 2, 10) != 0; - case GX_VA_TEX6: return GET_REG_FIELD(__GXData->vcdHi, 2, 12) != 0; - case GX_VA_TEX7: return GET_REG_FIELD(__GXData->vcdHi, 2, 14) != 0; - case GX_VA_PNMTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 0) != 0; - case GX_VA_TEX0MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 1) != 0; - case GX_VA_TEX1MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 2) != 0; - case GX_VA_TEX2MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 3) != 0; - case GX_VA_TEX3MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 4) != 0; - case GX_VA_TEX4MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 5) != 0; - case GX_VA_TEX5MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 6) != 0; - case GX_VA_TEX6MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 7) != 0; - case GX_VA_TEX7MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 8) != 0; - default: - return GX_FALSE; - } -} - -static void CheckVertexPacket(void) { - u32 numHostTextures; - u32 numHostTexAbsent; - u32 i; - u32 numMatrixIndices; - - if (!__GXVertexPacketHas(GX_VA_POS) && __gxVerif->verifyLevel >= __gxvWarnLev[57]) { - __GX_WARN(GXWARN_VTX_NO_GEOM); - } - - if (__GXVertexPacketHas(GX_VA_CLR1) && !__GXVertexPacketHas(GX_VA_CLR0) &&__gxVerif->verifyLevel >= __gxvWarnLev[70]) { - __GX_WARN(GXWARN_VCD_CLR_ORDER); - } - - numHostTextures = 0; - numHostTexAbsent = 0; - - for (i = 0; i < 8; i++) { - if (__GXVertexPacketHas(TextureEnums[i])) { - numHostTextures += 1; - numHostTexAbsent = 0; - } else { - numHostTexAbsent += 1; - } - } - - if (numHostTextures + numHostTexAbsent != 8 && __gxVerif->verifyLevel >= __gxvWarnLev[71]) { - __GX_WARN(GXWARN_VCD_TEX_ORDER); - } - - if ((BYTE3(__gxVerif->xfRegs[8]) & 3) == 0 && ((BYTE3(__gxVerif->xfRegs[8]) >> 2) & 3) == 0 && (u32)((BYTE3(__gxVerif->xfRegs[8]) >> 4) & 0xF) == 0) { - numMatrixIndices = 0; - - for (i = 0; i <= 8; i++) { - if (__GXVertexPacketHas(MtxIdxEnums[i])) { - numMatrixIndices += 1; - } - } - - if (numMatrixIndices != 0 && __gxVerif->verifyLevel >= __gxvWarnLev[69]) { - __GX_WARN(GXWARN_VCD_FMT_UNSUP); - } - } -} - -static void CheckSourceRows(void) { - u32 i; - - for (i = 0; i < numRegularTextures; i++) { - switch ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) { - case 0: - if (!__GXVertexPacketHas(GX_VA_POS) && __gxVerif->verifyLevel >= __gxvWarnLev[72]) { - __GX_WARNF(GXWARN_TEX_SRC_NPOS, i); - } - break; - case 1: - if (!__GXVertexPacketHas(GX_VA_NRM) && !__GXVertexPacketHas(GX_VA_NBT)&& __gxVerif->verifyLevel >= __gxvWarnLev[73]) { - __GX_WARNF(GXWARN_TEX_SRC_NNRM, i); - } - break; - case 2: - if (!__GXVertexPacketHas(GX_VA_CLR0) && __gxVerif->verifyLevel >= __gxvWarnLev[74]) { - __GX_WARNF(GXWARN_TEX_SRC_NCLR0, i); - } - if (!__GXVertexPacketHas(GX_VA_CLR1) && __gxVerif->verifyLevel >= __gxvWarnLev[75]) { - __GX_WARNF(GXWARN_TEX_SRC_NCLR1, i); - } - break; - case 3: - case 4: - if (!__GXVertexPacketHas(GX_VA_NBT) && __gxVerif->verifyLevel >= __gxvWarnLev[76]) { - __GX_WARNF(GXWARN_TEX_SRC_NNBT, i); - } - break; - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - if (!__GXVertexPacketHas(TextureEnums[((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) - 5]) && __gxVerif->verifyLevel >= __gxvWarnLev[77]) { - __GX_WARNF(GXWARN_TEX_SRC_NTEX, i, ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) - 5); - } - break; - default: - if (__gxVerif->verifyLevel >= __gxvWarnLev[78]) { - __GX_WARNF(GXWARN_INV_TEX_SRC, i, (u8)((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F)); - } - break; - } - } -} - -static void CheckTextureOrder(void) { - u8 done = 0; - u32 count = 0; - - while (!done) { - if (count == __gxVerif->xfRegs[0x3F] || ((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7)) { - done = 1; - } else { - count += 1; - } - } - - done = 0; - while (done == 0) { - if (count == __gxVerif->xfRegs[0x3F]) { - done = 1; - } else if ((u32)((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) != 1) { - if (!((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) && __gxVerif->verifyLevel >= __gxvWarnLev[79]) { - __GX_WARN(GXWARN_INV_TG_ORDER); - } - done = 1; - } else { - count += 1; - } - } - - done = 0; - while (done == 0) { - if (count == __gxVerif->xfRegs[0x3F]) { - done = 1; - } else if (!((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) || (u32)((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) == 1) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[79]) { - __GX_WARN(GXWARN_INV_TG_ORDER); - } - done = 1; - } else { - count += 1; - } - } -} - -static void CheckRAM(u8 Normal, u32 StartingAddress, u32 Count, GXWarnID WarnID, char* Str) { - u32 i; - u8 printedPreamble; - u8 dirtyBit; - - printedPreamble = 0; - - for (i = StartingAddress; i < StartingAddress + Count; i++) { - dirtyBit = Normal != 0 ? __gxVerif->xfMtxDirty[i - 0x300] : __gxVerif->xfMtxDirty[i]; - - if (dirtyBit == 0) { - if (printedPreamble == 0) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[WarnID]) { - __gxVerif->cb(__gxvWarnLev[WarnID], WarnID, Str); - } - - printedPreamble = 1; - } - } - } -} - -static void CheckBumpmapTextures(void) { - u32 i; - u32 BumpMapSource; - u32 BumpMapLight; - u32 lightRAMOffset; - char Preamble[256]; - - if (!__GXVertexPacketHas(GX_VA_PNMTXIDX)) { - if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x50]) { - __GX_WARNF(0x50, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); - } - sprintf(Preamble, __gxvWarnings[0x6A], (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); - CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9U, 0x6A, Preamble); - } - - for (i = 0; i < numBumpmapTextures; i++) { - BumpMapSource = BYTE2(__gxVerif->xfRegs[numRegularTextures + i + 64]); - BumpMapSource = (BumpMapSource >> 4) & 7; - if ((BYTE3(__gxVerif->xfRegs[BumpMapSource + 64]) >> 4) & 7 && __gxVerif->verifyLevel >= __gxvWarnLev[0x51]) { - __GX_WARNF(0x51, i + numRegularTextures, BumpMapSource); - } - - BumpMapLight = __gxVerif->xfRegs[numRegularTextures + i + 0x40]; - BumpMapLight = (BumpMapLight >> 15) & 7; - lightRAMOffset = (BumpMapLight * 0x10) + 0x60A; - if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 0] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { - __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "X"); - } - - if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 1] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { - __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "Y"); - } - - if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 2] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { - __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "Z"); - } - - if (!__GXVertexPacketHas(GX_VA_NBT) && __gxVerif->verifyLevel >= __gxvWarnLev[0x53]) { - __GX_WARNF(0x53, i); - } - } - - lightRAMOffset; lightRAMOffset; // needed to match -} - -static void CheckTextureTransformMatrices(void) { - u32 i; - u32 StartingAddress; - u32 Size; - u8 MtxIndexInVertexPacket; - char Preamble[256]; - u32 Val; - - for (i = 0; i < numRegularTextures; i++) { - MtxIndexInVertexPacket = 0; - switch (i) { - case 0: - StartingAddress = (u8)((HIWORD(__gxVerif->xfRegs[0x18]) >> 4U) & 0xFC); - Val = HIWORD(__gxVerif->xfRegs[0x18]); - Val = (Val >> 6) & 0x3F; - MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX0MTXIDX); - break; - case 1: - StartingAddress = (u8)((__gxVerif->xfRegs[0x18] >> 10) & 0xFC); - Val = __gxVerif->xfRegs[0x18]; - Val = (Val >> 12) & 0x3F; - MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX1MTXIDX); - break; - case 2: - StartingAddress = (u8)(BYTE1(__gxVerif->xfRegs[0x18]) & 0xFC); - Val = BYTE1(__gxVerif->xfRegs[0x18]); - Val = (Val >> 2) & 0x3F; - MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX2MTXIDX); - break; - case 3: - StartingAddress = (BYTE0(__gxVerif->xfRegs[0x18]) * 4) & 0xFC; - Val = BYTE0(__gxVerif->xfRegs[0x18]); - Val = Val & 0x3F; - MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX3MTXIDX); - break; - case 4: - StartingAddress = (BYTE3(__gxVerif->xfRegs[0x19]) * 4) & 0xFC; - Val = BYTE3(__gxVerif->xfRegs[0x19]); - Val = Val & 0x3F; - MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX4MTXIDX); - break; - case 5: - StartingAddress = (u8)((HIWORD(__gxVerif->xfRegs[0x19]) >> 4) & 0xFC); - Val = HIWORD(__gxVerif->xfRegs[0x19]); - Val = (Val >> 6) & 0x3F; - MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX5MTXIDX); - break; - case 6: - StartingAddress = (u8)((__gxVerif->xfRegs[0x19] >> 10) & 0xFC); - Val = __gxVerif->xfRegs[0x19]; - Val = (Val >> 12) & 0x3F; - MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX6MTXIDX); - break; - case 7: - StartingAddress = (u8)(BYTE1(__gxVerif->xfRegs[0x19]) & 0xFC); - Val = BYTE1(__gxVerif->xfRegs[0x19]); - Val = (Val >> 2) & 0x3F; - MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX7MTXIDX); - break; - default: - if (__gxVerif->verifyLevel >= __gxvWarnLev[0x54]) { - __GX_WARNF(0x54, i); - } - break; - } - - if (MtxIndexInVertexPacket == 0) { - sprintf(Preamble, __gxvWarnings[0x6B], i, i, Val); - if (!((BYTE3(__gxVerif->xfRegs[i + 64]) >> 1) & 1)) { - Size = 8; - } else { - Size = 0xC; - } - CheckRAM(0U, StartingAddress, Size, 0x6B, Preamble); - } - } - - // needed to match - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - StartingAddress; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; - MtxIndexInVertexPacket; -} - -static void CheckInputForms(void) { - u32 i; - - for (i = 0; i < numRegularTextures; i++) { - switch ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) { - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - if ((BYTE3(__gxVerif->xfRegs[i + 64]) >> 2) & 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x79]) { - __GX_WARNF(0x79, i, (u8)((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F)); - } - } - } -} - -static void CheckLight(u32 lightSource) { - u32 lightRAMOffset; - u8 printedPreamble; - u32 i; - - printedPreamble = 0; - lightRAMOffset = (lightSource * 0x10) + 0x603; - for (i = 0; i < 13; i++) { - if (!__gxVerif->xfLightDirty[lightRAMOffset + i - 0x600]) { - if (!printedPreamble) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[0x6C]) { - __GX_WARNF(0x6C, lightSource); - } - - printedPreamble = 1; - } - } - } -} - -// NONMATCHING -static void CheckColor0(void) { - char Preamble[256]; - u8 haveLight; - u32 i; - u8 lightUsed; - - if ((u8)(BYTE3(__gxVerif->xfRegs[9]) & 3) || numColorTextures != 0) { - if (!__gxVerif->xfRegsDirty[14] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { - __GX_WARNF(0x7A, 0x100E, "Color 0 control register"); - } - - if (!__gxVerif->xfRegsDirty[16] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { - __GX_WARNF(0x7A, 0x1010, "Alpha 0 control register"); - } - - if (!(BYTE3(__gxVerif->xfRegs[14]) & 1) && !__gxVerif->xfRegsDirty[12] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7B]) { - __GX_WARNF(0x7B, 0, 0, 0x100C); - } - - if (!((BYTE3(__gxVerif->xfRegs[14]) >> 6) & 1) && !__gxVerif->xfRegsDirty[10] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7C]) { - __GX_WARNF(0x7C, 0, 0, 0x100A); - } - - if ((u32)((BYTE3(__gxVerif->xfRegs[14]) >> 1) & 1) == 1 || (u32)((BYTE3(__gxVerif->xfRegs[16]) >> 1) & 1) == 1) { - haveLight = 0; - for (i = 0; i < 8; i++) { - lightUsed = 0; - switch (i) { - case 0: - if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 2) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 2) & 1)) { - lightUsed = 1; - } - break; - case 1: - if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 3) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 3) & 1)) { - lightUsed = 1; - } - break; - case 2: - if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 4) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 4) & 1)) { - lightUsed = 1; - } - break; - case 3: - if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 5) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 5) & 1)) { - lightUsed = 1; - } - break; - case 4: - if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 3) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 3) & 1)) { - lightUsed = 1; - } - break; - case 5: - if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 4) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 4) & 1)) { - lightUsed = 1; - } - break; - case 6: - if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 5) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 5) & 1)) { - lightUsed = 1; - } - break; - case 7: - if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 6) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 6) & 1)) { - lightUsed = 1; - } - break; - } - if (lightUsed != 0) { - CheckLight(i); - haveLight = 1; - } - } - - if (haveLight != 0) { - if (!((BYTE2(__gxVerif->xfRegs[14]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[14]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { - __GX_WARNF(0x59, "COLOR0", "COLOR0"); - } - - if (!((BYTE2(__gxVerif->xfRegs[16]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[16]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { - __GX_WARNF(0x59, "ALPHA0", "ALPHA0"); - } - - if (((HIWORD(__gxVerif->xfRegs[14]) >> 7) & 3) - || ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[14]) >> 2) & 1) == 1)) - || ((HIWORD(__gxVerif->xfRegs[16]) >> 7) & 3) - || ((u8)((BYTE2(__gxVerif->xfRegs[16]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[16]) >> 2) & 1) == 1))) { - if ((__GXVertexPacketHas(GX_VA_NRM) == 0) && (__GXVertexPacketHas(GX_VA_NBT) == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[0x5A]) { - __GX_WARNF(0x5A, 0); - } - if (__GXVertexPacketHas(GX_VA_PNMTXIDX) == 0) { - if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x5B]) { - __GX_WARNF(0x5B, 0, (BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); - } - sprintf(Preamble, __gxvWarnings[0x6D], 0, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); - CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9, 0x6D, Preamble); - } - } - } - } - } -} - -// NONMATCHING -static void CheckColor1(void) { - u8 usingColor1; - char Preamble[256]; - u8 haveLight; - u32 i; - u8 lightUsed; - - if (numColorTextures > 1 && ((u32)((BYTE3(__gxVerif->xfRegs[numRegularTextures + numBumpmapTextures + 1 + 64]) >> 4) & 7) == 3)) { - usingColor1 = 1; - } else { - usingColor1 = 0; - } - - if ((u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) == 2 || usingColor1) { - if (!__gxVerif->xfRegsDirty[15] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { - __GX_WARNF(0x7A, 0x100F, "Color 1 control register"); - } - - if (!__gxVerif->xfRegsDirty[17] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { - __GX_WARNF(0x7A, 0x1011, "Alpha 1 control register"); - } - - if (!(BYTE3(__gxVerif->xfRegs[15]) & 1) && !__gxVerif->xfRegsDirty[13] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7B]) { - __GX_WARNF(0x7B, 1, 1, 0x100D); - } - - if (!((BYTE3(__gxVerif->xfRegs[15]) >> 6) & 1) && !__gxVerif->xfRegsDirty[11] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7C]) { - __GX_WARNF(0x7C, 1, 1, 0x100B); - } - - if ((u32)((BYTE3(__gxVerif->xfRegs[15]) >> 1) & 1) == 1 || (u32)((BYTE3(__gxVerif->xfRegs[17]) >> 1) & 1) == 1) { - haveLight = 0; - for (i = 0; i < 8; i++) { - lightUsed = 0; - switch (i) { - case 0: - if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 2) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 2) & 1)) { - lightUsed = 1; - } - break; - case 1: - if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 3) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 3) & 1)) { - lightUsed = 1; - } - break; - case 2: - if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 4) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 4) & 1)) { - lightUsed = 1; - } - break; - case 3: - if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 5) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 5) & 1)) { - lightUsed = 1; - } - break; - case 4: - if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 3) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 3) & 1)) { - lightUsed = 1; - } - break; - case 5: - if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 4) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 4) & 1)) { - lightUsed = 1; - } - break; - case 6: - if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 5) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 5) & 1)) { - lightUsed = 1; - } - break; - case 7: - if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 6) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 6) & 1)) { - lightUsed = 1; - } - break; - } - if (lightUsed != 0) { - CheckLight(i); - haveLight = 1; - } - } - - if (haveLight != 0) { - if (!((BYTE2(__gxVerif->xfRegs[15]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[15]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { - __GX_WARNF(0x59, "COLOR1", "COLOR1"); - } - - if (!((BYTE2(__gxVerif->xfRegs[17]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[17]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { - __GX_WARNF(0x59, "ALPHA1", "ALPHA1"); - } - - if (((HIWORD(__gxVerif->xfRegs[15]) >> 7) & 3) - || ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[15]) >> 2) & 1) == 1)) - || ((HIWORD(__gxVerif->xfRegs[17]) >> 7) & 3) - || ((u8)((BYTE2(__gxVerif->xfRegs[17]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[17]) >> 2) & 1) == 1))) { - if ((__GXVertexPacketHas(GX_VA_NRM) == 0) && (__GXVertexPacketHas(GX_VA_NBT) == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[0x5A]) { - __GX_WARNF(0x5A, 1); - } - if (__GXVertexPacketHas(GX_VA_PNMTXIDX) == 0) { - if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x5B]) { - __GX_WARNF(0x5B, 1, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); - } - sprintf(Preamble, __gxvWarnings[0x6D], 1, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); - CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9, 0x6D, Preamble); - } - } - } - } - } -} - -static void CheckViewport(void) { - f32 vl; - f32 vr; - f32 vt; - f32 vb; - - vl = (*(f32*)&__gxVerif->xfRegs[29] - *(f32*)&__gxVerif->xfRegs[26]) - 342.0f; - vt = (*(f32*)&__gxVerif->xfRegs[30] + *(f32*)&__gxVerif->xfRegs[27]) - 342.0f; - vr = (*(f32*)&__gxVerif->xfRegs[29] + *(f32*)&__gxVerif->xfRegs[26]) - 342.0f; - vb = (*(f32*)&__gxVerif->xfRegs[30] - *(f32*)&__gxVerif->xfRegs[27]) - 342.0f; - - if ((vt < -0.5f || vt > 528.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x55]) { - __GX_WARNF(0x55, vt); - } - - if ((vb < 0.0f || vb > 528.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x56]) { - __GX_WARNF(0x56, vb); - } - - if ((vl < 0.0f || vl > 640.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x57]) { - __GX_WARNF(0x57, vl); - } - - if ((vr < 0.0f || vr > 640.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x58]) { - __GX_WARNF(0x58, vr); - } -} - -static void ComputeSignExponentMantissa(f32 floatVal, u32* sign, u32* exponent, u32* mantissa) { - u32 intVal = *(u32*)&floatVal; - - *sign = (intVal >> 31) & 1; - *exponent = (intVal >> 23) & 0xFF; - *mantissa = intVal & 0x7FFFFF; -} - -static void CheckFloatingPointValue(u8 dirtyBit, u32 value, char* label) { - u32 sign; - u32 exponent; - u32 mantissa; - f32 valuef; - - &valuef; - - if ((dirtyBit == 0)) { - return; - } - valuef = *(f32 *)&value; - ComputeSignExponentMantissa(valuef, &sign, &exponent, &mantissa); - - if (exponent == 0 && mantissa == 0) { - return; - } - - if (exponent == 0xFF) { - if (__gxVerif->verifyLevel >= 2) { - if (mantissa == 0) { - if (sign != 0) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5C]) { - __GX_WARNF(0x5C, label, "-", *(u32 *)&valuef); - } - } else { - if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5C]) { - __GX_WARNF(0x5C, label, "+", *(u32 *)&valuef); - } - } - } else { - if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5D]) { - __GX_WARNF(0x5D, label, *(u32 *)&valuef); - } - } - } - } else if (__gxVerif->verifyLevel >= 3) { - if (exponent < 0x6BU) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5E]) { - __GX_WARNF(0x5E, label, valuef, *(u32 *)&valuef); - } - } else if (exponent > 0x96U) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5F]) { - __GX_WARNF(0x5F, label, valuef, *(u32 *)&valuef); - } - } - } -} - -static void CheckMatrixRAMRanges(void) { - u32 i; - char label[256]; - - for (i = 0; i <= 255; i++) { - sprintf(label, "Geometry/Texture Matrix ram address 0x%04x", i); - CheckFloatingPointValue(__gxVerif->xfMtxDirty[i], __gxVerif->xfMtx[i], label); - } -} - -static void CheckNormalRAMRanges(void) { - u32 i; - char label[256]; - - for (i = 1024; i <= 1119; i++) { - sprintf(label, "Normal Matrix ram address 0x%04x", i); - CheckFloatingPointValue(__gxVerif->xfNrmDirty[i - 1024], __gxVerif->xfNrm[i - 1024], label); - } -} - -static void CheckDMatrixRAMRanges(void) { - u32 i; - char label[256]; - - for (i = 1280; i <= 1535; i++) { - sprintf(label, "Dual Texture Matrix ram address 0x%04x", i); - CheckFloatingPointValue(__gxVerif->xfDMtxDirty[i - 1280], __gxVerif->xfDMtx[i - 1280], label); - } -} - -static void CheckLightRAMRanges(void) { - u32 lightSource; - u32 lightRAMOffset; - char label[256]; - u32 i; - - for (lightSource = 0; lightSource < 8; lightSource++) { - for (i = 1; i < 13; i++) { - lightRAMOffset = (lightSource << 4) + i; - lightRAMOffset += 0x603; - sprintf(label, "Light %d %s (address 0x%04x)", lightSource, lightRegisterNames[i], lightRAMOffset); - CheckFloatingPointValue(__gxVerif->xfLightDirty[lightRAMOffset - 0x600], __gxVerif->xfLight[(s32) (lightRAMOffset - 0x600)], label); - } - - } - - i; lightSource; // needed to match -} - -static void CheckControlRAMRanges(void) { - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1A], __gxVerif->xfRegs[0x1A], "Viewport Scale X"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1B], __gxVerif->xfRegs[0x1B], "Viewport Scale Y"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1C], __gxVerif->xfRegs[0x1C], "Viewport Scale Z"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1D], __gxVerif->xfRegs[0x1D], "Viewport Offset X"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1E], __gxVerif->xfRegs[0x1E], "Viewport Offset Y"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1F], __gxVerif->xfRegs[0x1F], "Viewport Offset Z"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x20], __gxVerif->xfRegs[0x20], "Projection Matrix A Value"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x21], __gxVerif->xfRegs[0x21], "Projection Matrix B Value"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x22], __gxVerif->xfRegs[0x22], "Projection Matrix C Value"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x23], __gxVerif->xfRegs[0x23], "Projection Matrix D Value"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x24], __gxVerif->xfRegs[0x24], "Projection Matrix E Value"); - CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x25], __gxVerif->xfRegs[0x25], "Projection Matrix F Value"); -} - -static void CheckFloatingPointRanges(void) { - CheckMatrixRAMRanges(); - CheckNormalRAMRanges(); - CheckDMatrixRAMRanges(); - CheckLightRAMRanges(); - CheckControlRAMRanges(); -} - -static void CheckMatrixIndices(void) { - if (!__GXVertexPacketHas(GX_VA_PNMTXIDX) - || !__GXVertexPacketHas(GX_VA_TEX0MTXIDX) - || !__GXVertexPacketHas(GX_VA_TEX1MTXIDX) - || !__GXVertexPacketHas(GX_VA_TEX2MTXIDX) - || !__GXVertexPacketHas(GX_VA_TEX3MTXIDX)) - { - CheckDirty(0x1018U, "Geometry & Textures [0-3] transform matrix indices"); - } - - if (__gxVerif->verifyLevel >= 1 && !__GXVertexPacketHas(GX_VA_PNMTXIDX)) { - CheckRAM(0U, (BYTE3(__gxVerif->xfRegs[24]) * 4) & 0xFC, 0xCU, 0x6E, __gxvWarnings[0x6E]); - } - - if ((!__GXVertexPacketHas(GX_VA_TEX4MTXIDX) - || !__GXVertexPacketHas(GX_VA_TEX5MTXIDX) - || !__GXVertexPacketHas(GX_VA_TEX6MTXIDX) - || !__GXVertexPacketHas(GX_VA_TEX7MTXIDX)) - && numRegularTextures > 4 - && __gxVerif->verifyLevel >= 1 - && !__gxVerif->xfRegsDirty[0x19] && __gxVerif->verifyLevel >= __gxvWarnLev[0x60]) { - __GX_WARNF(0x60, numRegularTextures, 0x1019U); - } -} - -static void CheckErrors(void) { - u32 i; - char registerName[80]; - - CheckDirty(0x103FU, "Number of XF output textures"); - CheckDirty(0x1009U, "Number of XF output colors"); - CheckDirty(0x1008U, "InVertexSpec"); - CheckDirty(0x101AU, "Viewport ScaleX"); - CheckDirty(0x101BU, "Viewport ScaleY"); - CheckDirty(0x101CU, "Viewport ScaleZ"); - CheckDirty(0x101DU, "Viewport OffsetX"); - CheckDirty(0x101EU, "Viewport OffsetY"); - CheckDirty(0x101FU, "Viewport OffsetZ"); - CheckDirty(0x1020U, "Projection matrix 'A' value"); - CheckDirty(0x1021U, "Projection matrix 'B' value"); - CheckDirty(0x1022U, "Projection matrix 'C' value"); - CheckDirty(0x1023U, "Projection matrix 'D' value"); - CheckDirty(0x1024U, "Projection matrix 'E' value"); - CheckDirty(0x1025U, "Projection matrix 'F' value"); - CheckDirty(0x1026U, "Projection matrix orthographic/perspective select"); - CheckMatrixIndices(); - - if (__gxVerif->verifyLevel >= 1) { - if (!(u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) && !__gxVerif->xfRegs[0x3F] && __gxVerif->verifyLevel >= __gxvWarnLev[0x38]) { - __GX_WARN(0x38); - } - - CheckCTGColors(); - - if (__gxVerif->xfRegs[0x3F] > 8 && __gxVerif->verifyLevel >= __gxvWarnLev[0x64]) { - __GX_WARNF(0x64, __gxVerif->xfRegs[0x3F], 8); - } - if (numRegularTextures > 8 && __gxVerif->verifyLevel >= __gxvWarnLev[0x65]) { - __GX_WARNF(0x65, numRegularTextures, 8); - } - if (numBumpmapTextures > 3 && __gxVerif->verifyLevel >= __gxvWarnLev[0x66]) { - __GX_WARNF(0x66, numBumpmapTextures, 3); - } - if (numColorTextures > 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x67]) { - __GX_WARNF(0x67, numColorTextures, 2); - } - if (numColor0Textures > 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x69]) { - __GX_WARNF(0x69, 0); - } - if (numColor1Textures > 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x69]) { - __GX_WARNF(0x69, 1); - } - - CheckVertexPacket(); - - for (i = 0; i < __gxVerif->xfRegs[0x3F]; i++) { - sprintf(registerName, "Texture %d settings", i); - CheckDirty(i + 0x1040, registerName); - } - - CheckSourceRows(); - CheckTextureOrder(); - if (numBumpmapTextures != 0) { - CheckBumpmapTextures(); - } - - CheckTextureTransformMatrices(); - if (numColorTextures != 0 && (u32)((BYTE3(__gxVerif->xfRegs[numRegularTextures + numBumpmapTextures + 64]) >> 4) & 7) != 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x68]) { - __GX_WARN(0x68U); - } - - CheckColor0(); - CheckColor1(); - CheckViewport(); - } -} - -static void CheckWarnings(void) { - if (__gxVerif->verifyLevel >= 1) { - CheckInputForms(); - } - - CheckClean(0x1000U, "Internal error register"); - CheckClean(0x1001U, "Internal diagnostic register"); - CheckClean(0x1002U, "Internal state register 0"); - CheckClean(0x1003U, "Internal state register 1"); - CheckClean(0x1004U, "Power savings register"); - - if (__gxVerif->verifyLevel >= 2) { - CheckFloatingPointRanges(); - } -} - -static void DumpXFRegisters(void) { - static u8 firstTime = 1; -} - -void __GXVerifyXF(void) { - if (internalDebug) { - DumpXFRegisters(); - } - InitializeXFVerifyData(); - CheckErrors(); - CheckWarnings(); - DumpCount++; -} - -#endif diff --git a/src/dolphin/gx/GXVerify.c b/src/dolphin/gx/GXVerify.c deleted file mode 100644 index 7f07b8f..0000000 --- a/src/dolphin/gx/GXVerify.c +++ /dev/null @@ -1,368 +0,0 @@ -#if DEBUG - -#include - -#include "__gx.h" - -static __GXVerifyData __gxVerifData; -struct __GXVerifyData* __gxVerif = &__gxVerifData; - -char* __gxvWarnings[125] = { - "Invalid Vertex Format. Normal count must be set to %s.", - "Texture size %ld not initialized.", - "Left edge of scissor rectangle is less than %d.", - "Top edge of scissor rectangle is less than %d.", - "Right edge of scissor rectangle is greater than %d in %s mode.", - "Bottom edge of scissor rectangle is greater than %d in %s mode.", - "%s value for subsample %d in pixel %ld is not 6 when single-sampling.", - "Indirect texture command for stage %ld is not set.", - "Invalid indirect texture request in TEV stage %ld.", - "Indirect matrix %ld requested in stage %d not set.", - "Requested indirect textures never initialized.", - "Indirect texture coordinate scales %d and %d not set.", - "Invalid texture coordinate specified for indirect stage %d.", - "Indirect texture feedback accumulation is on in TEV stage 0.", - "Indirect bump alpha is enabled in TEV stage 0.", - "Indirect vs. direct mask byte never set.", - "Texture reference never written for TEV stage %ld.", - "Invalid texture coordinate specified for TEV stage %ld.", - "Texture %ld is used as both indirect and direct.", - "Texture %ld not configured.", - "Base pointer for cached texture %ld is not specified.", - "TLUT for indexed texture %ld was never set up.", - "%s is not a power of 2 for mipmapped texture %ld.", - "%s is not GX_CLAMP for non-power-of-2 width in texture %ld.", - "Minification filter for texture %ld is not compatible with color index texture format.", - "Minimum LOD is greater than maximum LOD in texture %ld.", - "Maximum LOD is greater than image's maximum LOD for texture %ld.", - "LOD bias clamp shold be used with edge LOD for texture %ld.", - "Texture %ld does not meet requirements for anisotropic mipmapping.", - "Filters are not linear for field prediction in texture %ld.", - "Incomplete rounding mode configuration for texture %ld.", - "Rounding color indexed texture %ld.", - "Environment for TEV stage %ld not fully set up.", - "Invalid color channel selected in TEV stage %ld.", - "Argument %s selects null texture in TEV color stage %ld.", - "Argument %s selects null texture in TEV alpha stage %ld.", - "Color arg %s in TEV stage %ld accesses register %s, which may be dirty.", - "Alpha arg %s in TEV stage %ld accesses register %s, which may be dirty.", - "Color arg %s in TEV stage %ld accesses register %s, which was last unclamped. Possible wrap-around effect.", - "Alpha arg %s in TEV stage %ld accesses register %s, which was last unclamped. Possible wrap-around effect.", - "Z texturing enabled, but no Z offset specified.", - "Z texturing enabled, but no texture specified for final TEV stage.", - "Final TEV stage doesn't write color to register GX_TEVPREV.", - "Final TEV stage doesn't write alpha to register GX_TEVPREV.", - "Final TEV color stage has no clamping. Possible color wrap-around effect.", - "Final TEV alpha stage has no clamping. Possible alpha wrap-around effect.", - "Z buffering is before texture, but alpha compare operation is active.", - "PE blend and logicop are both on.", - "Selected pixel format does not support dithering.", - "Multisample enabled but pixel type is not RGB565.", - "Pixel type is RGB565 but multisample is not enabled.", - "Multisample locations for pixel %ld are not ordered correctly for antialias filter.", - "Invalid texgen_type %d for texture %d.", - "Register address 0x%04x uninitialized (%s).", - "Register address 0x%04x modified (%s), probably should not be.", - "Invalid combination of %d output color channels and %d color texgen textures.", - "Number of color channels and number of texgens are both zero.", - "Vertex packet does not contain position values.", - "Mismatched argument setting in vertex attribute. %s should be used with %s.", - "GXSetVtxAttrFmt: Normals only support signed types.", - "GXSetVtxAttrFmt: Number of fractional bits is fixed for normals. %s uses %d. Your setting will be ignored.", - "GXSetVtxAttrFmt: GX_F32 type doesn't refer the frac argument. Your setting will be ignored.", - "GXSetVtxAttrFmt: Colors don't refer the frac argument. Your setting will be ignored.", - "Invalid value (%d) for INVERTEXSPEC_REG.host_colors.", - "XF is not expecting host normals but cp is sending them.", - "XF is not expecting host normals, binormals and tangents but cp is sending them.", - "XF is expecting host normals but cp is not sending them.", - "XF is expecting host normals but cp is sending normals, binormals, and tangents.", - "XF is expecting host normals, binormals and tangents but cp is only sending normals.", - "This vertex format (Position + Matrix Indices only) is not supported.", - "VCD for GX_VA_CLR1 is activated though GX_VA_CLR0 is set to GX_NONE. GX_VA_CLR0 should be used first.", - "VCDs for input texture coordinates are not used sequentially from smaller IDs.", - "GX_TEXCOORD%d specifies source row of position, but this is not getting sent.", - "GX_TEXCOORD%d specifies source row of normal, but this is not getting sent.", - "GX_TEXCOORD%d specifies source row of color0, but color0 is not getting sent.", - "GX_TEXCOORD%d specifies source row of color1, but color1 is not getting sent.", - "GX_TEXCOORD%d specifies source row of binormal or tangent, but this is not getting sent.", - "GX_TEXCOORD%d specifies source row of input texture coordinate %d, but this is not getting sent.", - "GX_TEXCOORD%d is specifying an invalid source row of %d.", - "TexCoordGen types are out of order. GX_TG_MTX2x4/3x4 should come first (if any), followed by GX_TG_BUMP (if any), then GX_TG_SRTG (if any).", - "Bumpmap texgen is defined, which requires that binormals and tangents be transformed by a normal matrix, but current matrix index is set to an invalid value (%d) for normal transform.", - "GX_TEXCOORD%d (texgen type bumpmap) is referencing texture %d as a source texture, which is not of texgen type regular.", - "GX_TEXCOORD%d (texgen type bumpmap) using light source %d, but light's %c position is not defined.", - "GX_TEXCOORD%d is defined as texgen type bumpmap, but binormals and tangents are not getting sent.", - "Invalid regular texture number (%d)", - "Top edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", - "Bottom edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", - "Left edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", - "Right edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", - "Channel %s uses specular function (GX_AF_SPEC), but diffuse function is not GX_DF_NONE.", - "Channel %d performs lighting which requires a normal, but this is not getting sent.", - "Channel %d performs lighting which requires the normal to be transformed by a normal matrix, but current matrix index is (%d), which may be invalid.", - "%s has a value of %sinfinity (%08x), which is probably not intended.", - "%s has a value of NaN (%08x), which is probably not intended.", - "%s has a value of (%f 0x%08x), which might be unintentionally small.", - "%s has a value of (%f 0x%08x), which might be unintentionally large.", - "%d regular textures active, but MatrixIndex1 register (0x%04x) uninitialized.", - "gen_mode register not initialized.", - "Number of XF output textures does not match what downstream units are expecting.", - "Number of XF output colors does not match what downstream units are expecting.", - "Number of all texgens (%d) > max allowed %d.", - "Number of regular(2x4/3x4) type texgens (%d) > max allowed %d.", - "Number of bumpmap type texgens (%d) > max allowed %d.", - "Number of color texgens (%d) > max allowed %d.", - "First color texgen is not referencing COLOR0.", - "Color texgen from COLOR%d is used more than once.", - "Bumpmap texgen is defined, which requires the normal matrix values pointed by current matrix index (%d) to be loaded, however it may not be loaded yet.", - "GX_TEXCOORD%d requires the matrix values pointed by current texture matrix index %d (%d), however it may not be loaded yet.", - "GX_LIGHT%d is being referenced, however it may not be loaded yet.", - "Channel %d performs lighting which requires the normal matrix values pointed to by the current matrix index (%d), however these values may not be loaded yet.", - "Position matrix values pointed to by the current matrix index must be loaded, however they may not be loaded yet.", - "Address 0x%04x is uninitialized.", - "Register (0x%04x) (%s) is not initialized.", - "Display list contains invalid command.", - "Nested display list.", - "XF is not expecting host colors but cp is sending some.", - "XF is expecting a host color but cp is not sending one.", - "XF is expecting a single host color but cp is sending two.", - "XF is expecting two host colors but cp is not sending first color.", - "XF is expecting two host colors but cp is not sending second color.", - "Invalid number of output colors, %d.", - "Regular texture %d specifying a source row of %d which only has 2 elements, but an input form of ABC1.", - "Output XF colors or color textures enabled, but register address 0x%04x uninitialized (%s).", - "Output XF colors or color textures enabled, COLOR%dCNTRL_REG.material_src == REGISTER, but Material %d register (0x%04x) is not initialized.", - "Output XF colors or color textures enabled, COLOR%dCNTRL_REG.ambient_src == REGISTER, but Ambient %d register (0x%04x) is not initialized." -}; - -GXWarningLevel __gxvWarnLev[125] = { - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - 4, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - 4, - 4, - GX_WARN_SEVERE, - GX_WARN_ALL, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - 4, - 4, - 4, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_ALL, - GX_WARN_ALL, - 4, - GX_WARN_SEVERE, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_ALL, - GX_WARN_ALL, - GX_WARN_MEDIUM, - 4, - 4, - 4, - 4, - GX_WARN_ALL, - 4, - 4, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_ALL, - GX_WARN_ALL, - GX_WARN_ALL, - 4, - 4, - 4, - 4, - 4, - 4, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - 4, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - 4, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_ALL, - GX_WARN_ALL, - GX_WARN_SEVERE, - 4, - 4, - 4, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_MEDIUM, - GX_WARN_SEVERE, - GX_WARN_SEVERE, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, -}; - -char __gxvDummyStr[256]; - -static void __GXVerifyGlobal(void) {} - -static void __GXVerifyCP(GXVtxFmt fmt) { - u32 nrmCnt = GET_REG_FIELD(__GXData->vatA[fmt], 1, 9); - - if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { - if (__GXData->hasNrms && nrmCnt != 0) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_INVALID_VTX_FMT]) { - __GX_WARNF(GXWARN_INVALID_VTX_FMT, "GX_NRM_XYZ"); - } - } - else if (__GXData->hasBiNrms && nrmCnt != 1) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_INVALID_VTX_FMT]) { - __GX_WARNF(GXWARN_INVALID_VTX_FMT, "GX_NRM_NBT or GX_NRM_NBT3"); - } - } - } -} - -void __GXVerifyState(GXVtxFmt vtxfmt) { - if (__gxVerif->verifyLevel != GX_WARN_NONE) { - __GXVerifyGlobal(); - __GXVerifyCP(vtxfmt); - __GXVerifyXF(); - __GXVerifySU(); - __GXVerifyBUMP(); - __GXVerifyTEX(); - __GXVerifyTEV(); - __GXVerifyPE(); - } -} - -void __GXVerifyVATImm(GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac) { - if (__gxVerif->verifyLevel != GX_WARN_NONE) { - if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) { - switch (type) { - case GX_RGB565: - case GX_RGB8: - case GX_RGBX8: - if (cnt != GX_CLR_RGB && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_MISMATCH]) { - __GX_WARNF(GXWARN_VAT_MISMATCH, "RGB format type", "GX_CLR_RGB"); - } - break; - case GX_RGBA4: - case GX_RGBA6: - case GX_RGBA8: - if (cnt != GX_CLR_RGBA && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_MISMATCH]) { - __GX_WARNF(GXWARN_VAT_MISMATCH, "RGBA format type", "GX_CLR_RGBA"); - } - break; - } - } - - if (frac != 0) { - if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_CLR_FRAC]) { - __GX_WARN(GXWARN_VAT_CLR_FRAC); - } - } else if (type == GX_F32) { - if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_F32_FRAC]) { - __GX_WARN(GXWARN_VAT_F32_FRAC); - } - } - } - - if (attr == GX_VA_NRM || attr == GX_VA_NBT) { - switch (type) { - case GX_S8: - if (frac != 6 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_FRAC]) { - __GX_WARNF(GXWARN_VAT_NRM_FRAC, "GX_S8", 6); - } - break; - case GX_S16: - if (frac != 14 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_FRAC]) { - __GX_WARNF(GXWARN_VAT_NRM_FRAC, "GX_S16", 14); - } - break; - case GX_F32: - break; - default: - if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_TYPE]) { - __GX_WARN(GXWARN_VAT_NRM_TYPE); - } - break; - } - } - } -} - -void GXSetVerifyLevel(GXWarningLevel level) { - __gxVerif->verifyLevel = level; -} - -GXVerifyCallback GXSetVerifyCallback(GXVerifyCallback cb) { - GXVerifyCallback old_cb = __gxVerif->cb; - - __gxVerif->cb = cb; - return old_cb; -} - -#endif // DEBUG diff --git a/src/dolphin/gx/GXVert.c b/src/dolphin/gx/GXVert.c deleted file mode 100644 index df50141..0000000 --- a/src/dolphin/gx/GXVert.c +++ /dev/null @@ -1,86 +0,0 @@ -#if DEBUG -#include - -#include "__gx.h" - -#define FUNC_1PARAM(name, T) \ -void name##1##T(T x) { GXWGFifo.T = x; } - -#define FUNC_2PARAM(name, T) \ -void name##2##T(T x, T y) { GXWGFifo.T = x; GXWGFifo.T = y; } - -#define FUNC_3PARAM(name, T) \ -void name##3##T(T x, T y, T z) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; } - -#define FUNC_4PARAM(name, T) \ -void name##4##T(T x, T y, T z, T w) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; GXWGFifo.T = w; } - -#define FUNC_INDEX8(name) \ -void name##1x8(u8 x) { GXWGFifo.u8 = x; } - -#define FUNC_INDEX16(name) \ -void name##1x16(u16 x) { GXWGFifo.u16 = x; } - -// GXCmd -FUNC_1PARAM(GXCmd, u8) -FUNC_1PARAM(GXCmd, u16) -FUNC_1PARAM(GXCmd, u32) - -// GXParam -FUNC_1PARAM(GXParam, u8) -FUNC_1PARAM(GXParam, u16) -FUNC_1PARAM(GXParam, u32) -FUNC_1PARAM(GXParam, s8) -FUNC_1PARAM(GXParam, s16) -FUNC_1PARAM(GXParam, s32) -FUNC_1PARAM(GXParam, f32) -FUNC_3PARAM(GXParam, f32) -FUNC_4PARAM(GXParam, f32) - -// GXPosition -FUNC_3PARAM(GXPosition, f32) -FUNC_3PARAM(GXPosition, u8) -FUNC_3PARAM(GXPosition, s8) -FUNC_3PARAM(GXPosition, u16) -FUNC_3PARAM(GXPosition, s16) -FUNC_2PARAM(GXPosition, f32) -FUNC_2PARAM(GXPosition, u8) -FUNC_2PARAM(GXPosition, s8) -FUNC_2PARAM(GXPosition, u16) -FUNC_2PARAM(GXPosition, s16) -FUNC_INDEX16(GXPosition) -FUNC_INDEX8(GXPosition) - -// GXNormal -FUNC_3PARAM(GXNormal, f32) -FUNC_3PARAM(GXNormal, s16) -FUNC_3PARAM(GXNormal, s8) -FUNC_INDEX16(GXNormal) -FUNC_INDEX8(GXNormal) - -// GXColor -FUNC_4PARAM(GXColor, u8) -FUNC_1PARAM(GXColor, u32) -FUNC_3PARAM(GXColor, u8) -FUNC_1PARAM(GXColor, u16) -FUNC_INDEX16(GXColor) -FUNC_INDEX8(GXColor) - -// GXTexCoord -FUNC_2PARAM(GXTexCoord, f32) -FUNC_2PARAM(GXTexCoord, s16) -FUNC_2PARAM(GXTexCoord, u16) -FUNC_2PARAM(GXTexCoord, s8) -FUNC_2PARAM(GXTexCoord, u8) -FUNC_1PARAM(GXTexCoord, f32) -FUNC_1PARAM(GXTexCoord, s16) -FUNC_1PARAM(GXTexCoord, u16) -FUNC_1PARAM(GXTexCoord, s8) -FUNC_1PARAM(GXTexCoord, u8) -FUNC_INDEX16(GXTexCoord) -FUNC_INDEX8(GXTexCoord) - -// GXMatrixIndex -FUNC_1PARAM(GXMatrixIndex, u8) - -#endif // DEBUG diff --git a/src/dolphin/gx/__gx.h b/src/dolphin/gx/__gx.h deleted file mode 100644 index 1e065bb..0000000 --- a/src/dolphin/gx/__gx.h +++ /dev/null @@ -1,592 +0,0 @@ -#ifndef _DOLPHIN_GX_INTERNAL_H_ -#define _DOLPHIN_GX_INTERNAL_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// FIFO WRITE - -#define GX_WRITE_U8(ub) \ - GXWGFifo.u8 = (u8)(ub) - -#define GX_WRITE_U16(us) \ - GXWGFifo.u16 = (u16)(us) - -#define GX_WRITE_U32(ui) \ - GXWGFifo.u32 = (u32)(ui) - -#define GX_WRITE_F32(f) \ - GXWGFifo.f32 = (f32)(f); - - -// REG VERIF - -#if DEBUG -#define VERIF_XF_REG(addr, value) \ -do { \ - s32 regAddr = (addr); \ - if (regAddr >= 0 && regAddr < 0x50) { \ - __gxVerif->xfRegs[regAddr] = (value); \ - __gxVerif->xfRegsDirty[regAddr] = 1; \ - } \ -} while (0) - -#define VERIF_XF_REG_alt(addr, value) \ -do { \ - s32 xfAddr = (addr); \ - if (xfAddr >= 0 && xfAddr < 0x50) { \ - __gxVerif->xfRegs[xfAddr] = (value); \ - __gxVerif->xfRegsDirty[xfAddr] = 1; \ - } \ -} while (0) - -#define VERIF_RAS_REG(value) (__gxVerif->rasRegs[((value) & 0xFF000000) >> 24] = value) - -#define VERIF_MTXLIGHT(addr, data) \ -do { \ - s32 xfAddr; \ - if (addr < 0x400U) { \ - __gxVerif->xfMtx[addr] = data; \ - __gxVerif->xfMtxDirty[addr] = 1; \ - } else if (addr < 0x500U) { \ - xfAddr = addr - 0x400; \ - __gxVerif->xfNrm[xfAddr] = data; \ - __gxVerif->xfNrmDirty[xfAddr] = 1; \ - } else if (addr < 0x600U) { \ - xfAddr = addr - 0x500; \ - __gxVerif->xfDMtx[xfAddr] = data; \ - __gxVerif->xfDMtxDirty[xfAddr] = 1; \ - } else if (addr < 0x680U) { \ - xfAddr = addr - 0x600; \ - __gxVerif->xfLight[xfAddr] = data; \ - __gxVerif->xfLightDirty[xfAddr] = 1; \ - } else { \ - xfAddr = addr - 0x1000; \ - if ((xfAddr >= 0) && (xfAddr < 0x50)) { \ - __gxVerif->xfRegs[xfAddr] = data; \ - __gxVerif->xfRegsDirty[xfAddr] = 1; \ - } \ - } \ -} while (0) -#else -#define VERIF_XF_REG(addr, value) ((void)0) -#define VERIF_XF_REG_alt(addr, value) ((void)0) -#define VERIF_RAS_REG(value) ((void)0) -#endif - -// WRITE REG - -#define GX_WRITE_XF_REG(addr, value) \ -do { \ - GX_WRITE_U8(0x10); \ - GX_WRITE_U32(0x1000 + (addr)); \ - GX_WRITE_U32(value); \ - VERIF_XF_REG(addr, value); \ -} while (0) - -#if DEBUG -#define GX_WRITE_XF_REG_2(addr, value) \ -do { \ - u32 xfData = (value); &xfData; \ - GX_WRITE_U32(value); \ - VERIF_XF_REG_alt(addr, xfData); \ -} while (0) - -#define GX_WRITE_XF_REG_F(addr, value) \ -do { \ - f32 xfData = (value); \ - GX_WRITE_F32(value); \ - VERIF_XF_REG_alt(addr, *(u32 *)&xfData); \ -} while (0) -#else -#define GX_WRITE_XF_REG_2(addr, value) \ -do { \ - GX_WRITE_U32(value); \ -} while (0) - -#define GX_WRITE_XF_REG_F(addr, value) \ -do { \ - GX_WRITE_F32(value); \ -} while (0) -#endif - -#define GX_WRITE_RAS_REG(value) \ -do { \ - GX_WRITE_U8(0x61); \ - GX_WRITE_U32(value); \ - VERIF_RAS_REG(value); \ -} while (0) - -#ifdef DEBUG -#define GX_WRITE_SOME_REG2(a, b, c, addr) \ -do { \ - long regAddr; \ - GX_WRITE_U8(a); \ - GX_WRITE_U8(b); \ - GX_WRITE_U32(c); \ - regAddr = addr; \ - if (regAddr >= 0 && regAddr < 4) { \ - __GXData->indexBase[regAddr] = c; \ - } \ -} while (0) -#else -#define GX_WRITE_SOME_REG2(a, b, c, addr) \ -do { \ - GX_WRITE_U8(a); \ - GX_WRITE_U8(b); \ - GX_WRITE_U32(c); \ -} while (0) -#endif - -#ifdef DEBUG -#define GX_WRITE_SOME_REG3(a, b, c, addr) \ -do { \ - long regAddr; \ - GX_WRITE_U8(a); \ - GX_WRITE_U8(b); \ - GX_WRITE_U32(c); \ - regAddr = addr; \ - if (regAddr >= 0 && regAddr < 4) { \ - __GXData->indexStride[regAddr] = c; \ - } \ -} while (0) -#else -#define GX_WRITE_SOME_REG3(a, b, c, addr) \ -do { \ - GX_WRITE_U8(a); \ - GX_WRITE_U8(b); \ - GX_WRITE_U32(c); \ -} while (0) -#endif - -#define GX_WRITE_SOME_REG4(a, b, c, addr) \ -do { \ - long regAddr; \ - GX_WRITE_U8(a); \ - GX_WRITE_U8(b); \ - GX_WRITE_U32(c); \ - regAddr = addr; \ -} while (0) - -// REG MACROS - -#define GET_REG_FIELD(reg, size, shift) ((int)((reg) >> (shift)) & ((1 << (size)) - 1)) - -// TODO: reconcile reg macro differences -// this one is needed to match non GX libs -#define OLD_SET_REG_FIELD(line, reg, size, shift, val) \ -do { \ - ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \ - (reg) = ((u32)(reg) & ~(((1 << (size)) - 1) << (shift))) | ((u32)(val) << (shift)); \ -} while (0) - -// above doesn't seem to work with GX, only can get it to work with this -#define SET_REG_FIELD(line, reg, size, shift, val) \ -do { \ - ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \ - (reg) = ((u32)__rlwimi((u32)(reg), (val), (shift), 32 - (shift) - (size), 31 - (shift))); \ -} while (0) - -#define CHECK_GXBEGIN(line, name) ASSERTMSGLINE(line, !__GXinBegin, "'" name "' is not allowed between GXBegin/GXEnd") - -/* GXAttr */ -void __GXSetVCD(void); -void __GXSetVAT(void); - -/* GXBump */ -void __GXUpdateBPMask(void); -void __GXFlushTextureState(void); - -/* GXFifo */ -// GXFifoObj private data -typedef struct __GXFifoObj { - u8* base; - u8* top; - u32 size; - u32 hiWatermark; - u32 loWatermark; - void* rdPtr; - void* wrPtr; - s32 count; - u8 bind_cpu; - u8 bind_gp; -} __GXFifoObj; - -void __GXSaveCPUFifoAux(__GXFifoObj* realFifo); -void __GXFifoInit(void); -void __GXInsaneWatermark(void); -void __GXCleanGPFifo(void); - -/* GXGeometry */ -void __GXSetDirtyState(void); -void __GXSendFlushPrim(void); -void __GXSetGenMode(void); - -/* GXInit */ -void __GXInitGX(); -void __GXInitRevisionBits(void); - -typedef struct __GXData_struct { - u16 vNumNot; - u16 bpSentNot; - u16 vNum; - u16 vLim; - u32 cpEnable; - u32 cpStatus; - u32 cpClr; - u32 vcdLo; - u32 vcdHi; - u32 vatA[8]; - u32 vatB[8]; - u32 vatC[8]; - u32 lpSize; - u32 matIdxA; - u32 matIdxB; - u32 indexBase[4]; - u32 indexStride[4]; - u32 ambColor[2]; - u32 matColor[2]; - u32 suTs0[8]; - u32 suTs1[8]; - u32 suScis0; - u32 suScis1; - u32 tref[8]; - u32 iref; - u32 bpMask; - u32 IndTexScale0; - u32 IndTexScale1; - u32 tevc[16]; - u32 teva[16]; - u32 tevKsel[8]; - u32 cmode0; - u32 cmode1; - u32 zmode; - u32 peCtrl; - u32 cpDispSrc; - u32 cpDispSize; - u32 cpDispStride; - u32 cpDisp; - u32 cpTexSrc; - u32 cpTexSize; - u32 cpTexStride; - u32 cpTex; - u8 cpTexZ; - u32 genMode; - GXTexRegion TexRegions0[8]; - GXTexRegion TexRegions1[8]; - GXTexRegion TexRegions2[8]; - GXTlutRegion TlutRegions[20]; - GXTexRegion* (*texRegionCallback)(GXTexObj*, GXTexMapID); - GXTlutRegion* (*tlutRegionCallback)(u32); - GXAttrType nrmType; - u8 hasNrms; - u8 hasBiNrms; - u32 projType; - f32 projMtx[6]; - f32 vpLeft; - f32 vpTop; - f32 vpWd; - f32 vpHt; - f32 vpNearz; - f32 vpFarz; - f32 zOffset; - f32 zScale; - u32 tImage0[8]; - u32 tMode0[8]; - u32 texmapId[16]; - u32 tcsManEnab; - u32 tevTcEnab; - GXPerf0 perf0; - GXPerf1 perf1; - u32 perfSel; - u8 inDispList; - u8 dlSaveContext; - u8 abtWaitPECopy; - u8 dirtyVAT; - u32 dirtyState; -} GXData; - -extern GXData* const __GXData; -extern void* __memReg; -extern void* __peReg; -extern void* __cpReg; -extern void* __piReg; - -#if DEBUG -extern GXBool __GXinBegin; -#endif - -#define GX_GET_MEM_REG(offset) (*(volatile u16*)((volatile u16*)(__memReg) + (offset))) -#define GX_GET_CP_REG(offset) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset))) -#define GX_GET_PE_REG(offset) (*(volatile u16*)((volatile u16*)(__peReg) + (offset))) -#define GX_GET_PI_REG(offset) (*(volatile u32*)((volatile u32*)(__piReg) + (offset))) - -#define GX_SET_MEM_REG(offset, val) (*(volatile u16*)((volatile u16*)(__memReg) + (offset)) = val) -#define GX_SET_CP_REG(offset, val) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset)) = val) -#define GX_SET_PE_REG(offset, val) (*(volatile u16*)((volatile u16*)(__peReg) + (offset)) = val) -#define GX_SET_PI_REG(offset, val) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)) = val) - -/* GXMisc */ -void __GXBypass(u32 reg); -u16 __GXReadPEReg(u32 reg); -void __GXPEInit(void); -void __GXAbort(); - -/* GXPerf */ -void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial); - -static inline u32 __GXReadCPCounterU32(u32 regAddrL, u32 regAddrH) { - u32 ctrH0; - u32 ctrH1; - u32 ctrL; - - ctrH0 = GX_GET_CP_REG(regAddrH); - - do { - ctrH1 = ctrH0; - ctrL = GX_GET_CP_REG(regAddrL); - ctrH0 = GX_GET_CP_REG(regAddrH); - } while (ctrH0 != ctrH1); - - return (ctrH0 << 0x10) | ctrL; -} - -static inline u32 __GXReadMEMCounterU32(u32 regAddrL, u32 regAddrH) { - u32 ctrH0; - u32 ctrH1; - u32 ctrL; - - ctrH0 = GX_GET_MEM_REG(regAddrH); - - do { - ctrH1 = ctrH0; - ctrL = GX_GET_MEM_REG(regAddrL); - ctrH0 = GX_GET_MEM_REG(regAddrH); - } while (ctrH0 != ctrH1); - - return (ctrH0 << 0x10) | ctrL; -} - -static inline u32 __GXReadPECounterU32(u32 regAddrL, u32 regAddrH) { - u32 ctrH0; - u32 ctrH1; - u32 ctrL; - - ctrH0 = GX_GET_PE_REG(regAddrH); - - do { - ctrH1 = ctrH0; - ctrL = GX_GET_PE_REG(regAddrL); - ctrH0 = GX_GET_PE_REG(regAddrH); - } while (ctrH0 != ctrH1); - - return (ctrH0 << 0x10) | ctrL; -} - -/* GXSave */ -void __GXShadowDispList(void* list, u32 nbytes); -void __GXShadowIndexState(u32 idx_reg, u32 reg_data); -void __GXPrintShadowState(void); - -/* GXStubs */ -void __GXSetRange(f32 nearz, f32 fgSideX); - -/* GXTexture */ -void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32* rowTiles, u32* colTiles, u32* cmpTiles); -void __GXSetSUTexRegs(void); -void __GXGetSUTexSize(GXTexCoordID coord, u16* width, u16* height); -void __GXSetTmemConfig(u32 config); - -/* GXTransform */ -void __GXSetMatrixIndex(GXAttr matIdxAttr); -void __GXSetProjection(void); -void __GXSetViewport(); - - -/* GXVerifRAS */ -void __GXVerifySU(void); -void __GXVerifyBUMP(void); -void __GXVerifyTEX(void); -void __GXVerifyTEV(void); -void __GXVerifyPE(void); - -/* GXVerif */ -typedef enum { - GXWARN_INVALID_VTX_FMT = 0, - GXWARN_TEX_SIZE_INIT = 1, - GXWARN_SCISSOR_RECT_LEFT = 2, - GXWARN_SCISSOR_RECT_TOP = 3, - GXWARN_SCISSOR_RECT_RIGHT = 4, - GXWARN_SCISSOR_RECT_BOT = 5, - GXWARN_SAMPLE_VALUE = 6, - GXWARN_BUMP_CMD = 7, - GXWARN_INVALID_INDIRECT = 8, - GXWARN_INDIRECT_MTX = 9, - GXWARN_IND_TEX_NO_INIT = 10, - GXWARN_IND_TEX_NO_SCALE = 11, - GXWARN_IND_TEX_BUMP = 12, - GXWARN_BUMP_ACCUMULATION = 13, - GXWARN_BUMP_ALPHA_EN = 14, - GXWARN_IND_DIR_MASK = 15, - GXWARN_TEV_TEX_REF = 16, - GXWARN_TEV_INV_TEX_COORD = 17, - GXWARN_IND_DIR_BOTH = 18, - GXWARN_TEX_CONFIG = 19, - GXWARN_TEX_BASE = 20, - GXWARN_TLUT_CONFIG = 21, - GXWARN_TEX_POW2 = 22, - GXWARN_TEX_CLAMP = 23, - GXWARN_TEX_MIN_FILT = 24, - GXWARN_MIN_LOD = 25, - GXWARN_MAX_LOD = 26, - GXWARN_DIAG_LOD = 27, - GXWARN_TEX_ANISO = 28, - GXWARN_TEX_FIELD = 29, - GXWARN_TEX_RND_FP = 30, - GXWARN_RND_CLR_INDX = 31, - GXWARN_TEV_ENV = 32, - GXWARN_TEV_INV_CHAN = 33, - GXWARN_TEV_NULL_TEX = 34, - GXWARN_TEV_NULL_TEX_A = 35, - GXWARN_TEV_DIRTY_REG = 36, - GXWARN_TEV_DIRTY_REG_A = 37, - GXWARN_TEV_CLR_CLAMP = 38, - GXWARN_TEV_A_CLAMP = 39, - GXWARN_ZTEX_OFFSET = 40, - GXWARN_ZTEX_INVALID = 41, - GXWARN_TEV_LAST_CLR = 42, - GXWARN_TEV_LAST_A = 43, - GXWARN_TEV_LAST_CLR_WRAP = 44, - GXWARN_TEV_LAST_A_WRAP = 45, - GXWARN_Z_BEFORE_T_A = 46, - GXWARN_BLEND_LOGICOP = 47, - GXWARN_DITHER_MODE = 48, - GXWARN_MULTISAMP0 = 49, - GXWARN_MULTISAMP1 = 50, - GXWARN_SAMP_ORDER = 51, - GXWARN_INVALID_TG_TYPE = 52, - GXWARN_XF_CTRL_UNINIT = 53, - GXWARN_XF_CTRL_INIT = 54, - GXWARN_INV_COLOR_TG_COMB = 55, - GXWARN_XF_NO_CLR_TEX = 56, - GXWARN_VTX_NO_GEOM = 57, - GXWARN_VAT_MISMATCH = 58, - GXWARN_VAT_NRM_TYPE = 59, - GXWARN_VAT_NRM_FRAC = 60, - GXWARN_VAT_F32_FRAC = 61, - GXWARN_VAT_CLR_FRAC = 62, - GXWARN_INV_IVS_CLR = 63, - GXWARN_NRM_XF0_CP1 = 64, - GXWARN_NRM_XF0_CP3 = 65, - GXWARN_NRM_XF1_CP0 = 66, - GXWARN_NRM_XF1_CP3 = 67, - GXWARN_NRM_XF3_CP1 = 68, - GXWARN_VCD_FMT_UNSUP = 69, - GXWARN_VCD_CLR_ORDER = 70, - GXWARN_VCD_TEX_ORDER = 71, - GXWARN_TEX_SRC_NPOS = 72, - GXWARN_TEX_SRC_NNRM = 73, - GXWARN_TEX_SRC_NCLR0 = 74, - GXWARN_TEX_SRC_NCLR1 = 75, - GXWARN_TEX_SRC_NNBT = 76, - GXWARN_TEX_SRC_NTEX = 77, - GXWARN_INV_TEX_SRC = 78, - GXWARN_INV_TG_ORDER = 79, - GXWARN_BM_INV_MTX_NDX = 80, - GXWARN_BM_INV_TEX = 81, - GXWARN_BM_INV_LIT_POS = 82, - GXWARN_BM_NO_NBT = 83, - GXWARN_INV_TEX_NUM = 84, - GXWARN_VIEWPORT_TOP = 85, - GXWARN_VIEWPORT_BOTTOM = 86, - GXWARN_VIEWPORT_LEFT = 87, - GXWARN_VIEWPORT_RIGHT = 88, - GXWARN_CLR_INV_SPEC = 89, - GXWARN_CLR_NO_NRM = 90, - GXWARN_CLR_INV_MTX_NDX = 91, - GXWARN_VAL_INFINITY = 92, - GXWARN_VAL_NAN = 93, - GXWARN_VAL_SMALL = 94, - GXWARN_VAL_LARGE = 95, - GXWARN_MTX1_UNINIT = 96, - GXWARN_GM_UNINIT = 97, - GXWARN_TEX_XFN_SUM = 98, - GXWARN_CLR_XFN_SUM = 99, - GXWARN_INV_NUM_ANY_TEX = 100, - GXWARN_INV_NUM_REG_TEX = 101, - GXWARN_INV_NUM_BM_TEX = 102, - GXWARN_INV_NUM_CLR_TEX = 103, - GXWARN_INV_CLR_TEX = 104, - GXWARN_DUP_CLR_TEX = 105, - GXWARN_BM_INV_MTX_VAL = 106, - GXWARN_TEX_INV_MTX_VAL = 107, - GXWARN_LIT_INV_REG = 108, - GXWARN_CLR_INV_MTX_VAL = 109, - GXWARN_INV_MTX_VAL = 110, - GXWARN_ADDR_UNINIT = 111, - GXWARN_REG_UNINIT = 112, - GXWARN_DL_INV_CMD = 113, - GXWARN_DL_NESTED = 114, - GXWARN_CLR_XF0_CP1 = 115, - GXWARN_CLR_XF1_CP0 = 116, - GXWARN_CLR_XF1_CP2 = 117, - GXWARN_CLR_XF2_CPN1 = 118, - GXWARN_CLR_XF2_CPN2 = 119, - GXWARN_INV_NUM_COLORS = 120, - GXWARN_INV_TG_SRC = 121, - GXWARN_CLR_ADDR_UNINIT = 122, - GXWARN_CLR_MAT_UNINIT = 123, - GXWARN_CLR_AMB_UNINIT = 124, - GXWARN_MAX = 125, -} GXWarnID; - -#define __GX_WARN(id) (__gxVerif->cb(__gxvWarnLev[(id)], (id), __gxvWarnings[(id)])) -#define __GX_WARNF(id, ...) \ -do { \ - sprintf(__gxvDummyStr, __gxvWarnings[(id)], __VA_ARGS__); \ - __gxVerif->cb(__gxvWarnLev[(id)], (id), __gxvDummyStr); \ -} while (0) - -#define __GX_WARN2(level, id) (__gxVerif->cb(level, (id), __gxvWarnings[(id)])) -#define __GX_WARN2F(level, id, ...) \ -do { \ - sprintf(__gxvDummyStr, __gxvWarnings[(id)], __VA_ARGS__); \ - __gxVerif->cb(level, (id), __gxvDummyStr); \ -} while (0) - -typedef struct __GXVerifyData { - GXVerifyCallback cb; - GXWarningLevel verifyLevel; - u32 xfRegs[80]; - u32 xfMtx[256]; - u32 xfNrm[96]; - u32 xfDMtx[256]; - u32 xfLight[128]; - u32 rasRegs[256]; - u8 xfRegsDirty[80]; - u8 xfMtxDirty[256]; - u8 xfNrmDirty[96]; - u8 xfDMtxDirty[256]; - u8 xfLightDirty[128]; -} __GXVerifyData; - -extern __GXVerifyData* __gxVerif; -extern char* __gxvWarnings[125]; -extern char __gxvDummyStr[256]; -extern GXWarningLevel __gxvWarnLev[]; - -void __GXVerifyGlobal(void); -void __GXVerifyCP(GXVtxFmt fmt); -void __GXVerifyState(GXVtxFmt vtxfmt); - -/* GXVerifXF */ -void __GXVerifyXF(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/dolphin/hio/hio.c b/src/dolphin/hio/hio.c deleted file mode 100644 index aa146d5..0000000 --- a/src/dolphin/hio/hio.c +++ /dev/null @@ -1,409 +0,0 @@ -#include -#include -#include -#include - -static u32 Dev; -#define HIO_DEV Dev - -#ifdef DEBUG -const char* __HIOVersion = "<< Dolphin SDK - HIO\tdebug build: Apr 5 2004 03:57:05 (0x2301) >>"; -#else -const char* __HIOVersion = "<< Dolphin SDK - HIO\trelease build: Apr 5 2004 04:15:47 (0x2301) >>"; -#endif - -static char __HIODigest1[71] = "\"HIO library - Copyright (C) 2000-2002 Nintendo. All rights reserved.\""; - -#ifdef DEBUG -static char __HIODigest2[34] = "\"HIO built: Apr 5 2004 03:57:05\""; -#else -static char __HIODigest2[34] = "\"HIO built: Apr 5 2004 04:15:47\""; -#endif - -static s32 Chan = -1; -static HIOCallback ExiCallback; -static HIOCallback TxCallback; -static HIOCallback RxCallback; - -static void ExtHandler(s32 chan, OSContext *context) { - Chan = -1; - HIO_DEV = 0; - - if (chan < 2 && HIO_DEV == 0) { - EXISetExiCallback(chan, NULL); - } else if (chan == 0 && HIO_DEV == 2) { - EXISetExiCallback(2, NULL); - } -} - -static void ExiHandler(s32 chan, OSContext* context) { - if (ExiCallback) { - ExiCallback(); - } -} - -static void DbgHandler(__OSInterrupt interrupt, OSContext *context) { - OSContext exceptionContext; - - __PIRegs[0] = 0x1000; - if (ExiCallback) { - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - ExiCallback(); - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); - } -} - -static void TxHandler(s32 chan, OSContext* context) { - EXIDeselect(Chan); - EXIUnlock(Chan); - if (TxCallback) { - TxCallback(); - } -} - -static void RxHandler(s32 chan, OSContext* context) { - EXIDeselect(Chan); - EXIUnlock(Chan); - if (RxCallback) { - RxCallback(); - } -} - -BOOL HIOEnumDevices(HIOEnumCallback callback) { - s32 chan; - u32 id; - - if (Chan != -1 || callback == NULL) { - return 0; - } - - HIO_DEV = 0; - for (chan = 0; chan <= 2; chan++) { - if (chan < 2) { - while (EXIProbeEx(chan) == 0) {} - } - - if (EXIGetID(chan, HIO_DEV, &id) != 0 && id - 0x1010000 == 0 && !callback(chan)) { - return 1; - } - } - - return 1; -} - -static inline int CheckConsoleType() { - if (__OSGetDIConfig() == 0xFF) { - if (((OSGetConsoleType() & 0xF0000000) + 0xE0000000) == 0) { - return 1; - } - - switch (__OSDeviceCode) { - case 0x8200: - return 1; - } - - return 0; - } - - return 1; -} - -BOOL HIOInit(s32 chan, HIOCallback callback) { - int err; - u32 cmd; - u32 id; - - while (__OSDeviceCode == 0) {} - - if (CheckConsoleType() == 0) { - Chan = -1; - HIO_DEV = 0; - OSReport("%s\n", __HIODigest1, __HIODigest2); - return 0; - } - - if (Chan != -1) { - return 1; - } - - Chan = chan; - ExiCallback = callback; - TxCallback = NULL; - RxCallback = NULL; - - if (chan < 2 && HIO_DEV == 0) { - while (EXIProbeEx(Chan) == 0) {} - - if (EXIAttach(Chan, ExtHandler) == 0) { - Chan = -1; - HIO_DEV = 0; - return 0; - } - } - - if (EXILock(Chan, HIO_DEV, 0) == 0) { - EXIDetach(Chan); - Chan = -1; - HIO_DEV = 0; - return 0; - } - - if (EXISelect(Chan, HIO_DEV, 0) == 0) { - EXIUnlock(Chan); - EXIDetach(Chan); - Chan = -1; - HIO_DEV = 0; - return 0; - } - - cmd = 0; - err = 0; - err |= !EXIImm(Chan, &cmd, 2, 1, 0); - err |= !EXISync(Chan); - err |= !EXIImm(Chan, &id, 4, 0, 0); - err |= !EXISync(Chan); - err |= !EXIDeselect(Chan); - EXIUnlock(Chan); - - if (err != 0 || id != 0x1010000) { - if (chan < 2 && HIO_DEV == 0) { - EXIDetach(Chan); - } - EXIUnlock(Chan); - Chan = -1; - HIO_DEV = 0; - return 0; - } - - if (ExiCallback) { - if (chan < 2) { - if (HIO_DEV == 0) { - EXISetExiCallback(Chan, ExiHandler); - } else { - ASSERTLINE(331, HIO_DEV == 2); - EXISetExiCallback(2, ExiHandler); - } - } else { - __OSSetInterruptHandler(0x19, DbgHandler); - __OSUnmaskInterrupts(0x40); - } - } - - OSRegisterVersion(__HIOVersion); - return 1; -} - -BOOL HIOInitEx(s32 chan, u32 dev, HIOCallback callback) { - ASSERTLINE(348, dev == 0 || chan == 0 && dev == 2); - - if (dev != 0 && (chan != 0 || dev != 2)) { - return 0; - } - - if (Chan != -1) { - return 1; - } - - HIO_DEV = dev; - return HIOInit(chan, callback); -} - -BOOL HIOReadMailbox(u32* word) { - int err; - u32 cmd; - - if (Chan == -1 || CheckConsoleType() == 0) { - return 0; - } - - if (EXILock(Chan, HIO_DEV, 0) == 0) { - return 0; - } - - if (EXISelect(Chan, HIO_DEV, 4) == 0) { - EXIUnlock(Chan); - return 0; - } - - cmd = 0x60000000; - err = 0; - err |= !EXIImm(Chan, &cmd, 2, 1, 0); - err |= !EXISync(Chan); - err |= !EXIImm(Chan, word, 4, 0, 0); - err |= !EXISync(Chan); - err |= !EXIDeselect(Chan); - EXIUnlock(Chan); - return !err; -} - -BOOL HIOWriteMailbox(u32 word) { - int err; - u32 cmd; - - if (Chan == -1 || CheckConsoleType() == 0) { - return 0; - } - - if (EXILock(Chan, HIO_DEV, 0) == 0) { - return 0; - } - - if (EXISelect(Chan, HIO_DEV, 4) == 0) { - EXIUnlock(Chan); - return 0; - } - - cmd = (word & 0x1FFFFFFF) | 0xC0000000; - err = 0; - err |= !EXIImm(Chan, &cmd, 4, 1, 0); - err |= !EXISync(Chan); - err |= !EXIDeselect(Chan); - EXIUnlock(Chan); - return !err; -} - -BOOL HIORead(u32 addr, void* buffer, s32 size) { - int err; - u32 cmd; - - if (Chan == -1 || CheckConsoleType() == 0) { - return 0; - } - - ASSERTLINE(436, (addr % 4) == 0); - - if (EXILock(Chan, HIO_DEV, 0) == 0) { - return 0; - } - - if (EXISelect(Chan, HIO_DEV, 4) == 0) { - EXIUnlock(Chan); - return 0; - } - - cmd = ((addr << 8) & 0x01FFFC00) | 0x20000000; - err = 0; - err |= !EXIImm(Chan, &cmd, 4, 1, 0); - err |= !EXISync(Chan); - err |= !EXIDma(Chan, buffer, size, 0, NULL); - err |= !EXISync(Chan); - err |= !EXIDeselect(Chan); - EXIUnlock(Chan); - return !err; -} - -BOOL HIOWrite(u32 addr, void* buffer, s32 size) { - int err; - u32 cmd; - - if (Chan == -1 || CheckConsoleType() == 0) { - return 0; - } - - ASSERTLINE(470, (addr % 4) == 0); - - if (EXILock(Chan, HIO_DEV, 0) == 0) { - return 0; - } - - if (EXISelect(Chan, HIO_DEV, 4) == 0) { - EXIUnlock(Chan); - return 0; - } - - cmd = ((addr << 8) & 0x01FFFC00) | 0xA0000000; - err = 0; - err |= !EXIImm(Chan, &cmd, 4, 1, 0); - err |= !EXISync(Chan); - err |= !EXIDma(Chan, buffer, size, 1, NULL); - err |= !EXISync(Chan); - err |= !EXIDeselect(Chan); - EXIUnlock(Chan); - return !err; -} - -BOOL HIOReadAsync(u32 addr, void* buffer, s32 size, HIOCallback callback) { - int err; - u32 cmd; - - if (Chan == -1 || CheckConsoleType() == 0) { - return 0; - } - - ASSERTLINE(504, (addr % 4) == 0); - RxCallback = callback; - - if (EXILock(Chan, HIO_DEV, 0) == 0) { - return 0; - } - - if (EXISelect(Chan, HIO_DEV, 4) == 0) { - EXIUnlock(Chan); - return 0; - } - - cmd = ((addr << 8) & 0x01FFFC00) | 0x20000000; - err = 0; - err |= !EXIImm(Chan, &cmd, 4, 1, 0); - err |= !EXISync(Chan); - err |= !EXIDma(Chan, buffer, size, 0, RxHandler); - return !err; -} - -BOOL HIOWriteAsync(u32 addr, void* buffer, s32 size, HIOCallback callback) { - int err; - u32 cmd; - - if (Chan == -1 || CheckConsoleType() == 0) { - return 0; - } - - ASSERTLINE(537, (addr % 4) == 0); - TxCallback = callback; - - if (EXILock(Chan, HIO_DEV, 0) == 0) { - return 0; - } - - if (EXISelect(Chan, HIO_DEV, 4) == 0) { - EXIUnlock(Chan); - return 0; - } - - cmd = ((addr << 8) & 0x01FFFC00) | 0xA0000000; - err = 0; - err |= !EXIImm(Chan, &cmd, 4, 1, 0); - err |= !EXISync(Chan); - err |= !EXIDma(Chan, buffer, size, 1, TxHandler); - return !err; -} - -BOOL HIOReadStatus(u32* status) { - int err; - u32 cmd; - - if (Chan == -1 || CheckConsoleType() == 0) { - return 0; - } - - if (EXILock(Chan, HIO_DEV, 0) == 0) { - return 0; - } - - if (EXISelect(Chan, HIO_DEV, 4) == 0) { - EXIUnlock(Chan); - return 0; - } - - cmd = 0x40000000; - err = 0; - err |= !EXIImm(Chan, &cmd, 2, 1, 0); - err |= !EXISync(Chan); - err |= !EXIImm(Chan, status, 4, 0, 0); - err |= !EXISync(Chan); - err |= !EXIDeselect(Chan); - EXIUnlock(Chan); - return !err; -} diff --git a/src/dolphin/mcc/fio.c b/src/dolphin/mcc/fio.c deleted file mode 100644 index dca9488..0000000 --- a/src/dolphin/mcc/fio.c +++ /dev/null @@ -1,1290 +0,0 @@ -#include -#include - -#ifdef DEBUG -const char* __FIOVersion = "<< Dolphin SDK - FIO\tdebug build: Apr 5 2004 03:57:07 (0x2301) >>"; -#else -const char* __FIOVersion = "<< Dolphin SDK - FIO\trelease build: Apr 5 2004 04:15:50 (0x2301) >>"; -#endif - -static u8 gBuf[0x2000]; -static u8 gPrintBuf[0x400]; - -static u8 gmSizeOfBlocks = 1; -static u8 gSizeOfBlocks = 1; -volatile static BOOL gProcDone = TRUE; - -static MCC_CHANNEL gmChID; -static MCC_CHANNEL gChID; -static int gQuery; -volatile static int gProcBusy; -volatile static u32 gStreamReady; -static u8 gLastErr; -static BOOL bAsyncIsRead; -static FIO_ASYNC_STATE bAsyncBusy; -static void* bAsyncBuffer; -static u32 gAsyncDataSize; -static u32 gRequestSequenceNumber; - -// prototypes -static BOOL fioIsInitialized(void); -static u16 EndianConvert16(u16 n); -static u32 EndianConvert32(u32 n); -static int MPDWaiting(int timeout, volatile int* flag, int value); -static void ShowChannelInfo(MCC_CHANNEL chID); -static void fioErrorReport(char* msg); -static void fioMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value); -static void* fioPacketMakeHeader(u32 fioCode, u32 dataSize, BOOL bEndianConvert); -static int fioPacketSendPacket(u8 sizeOfBlocks, void* pTopOfSecondBlockData); -static void* fioPacketReceiveResult(u32 fioCode, BOOL bDone); -static void fioPacketReceiveDone(void); -static int fioPacketRead(int fd, void* buffer, int size, int async); -static int fioPacketWrite(int fd, void* buffer, int size, int async); -static int fioPacketResultRead(void* buffer, u32 dataSize); -static int fioPacketResultWrite(void* buffer, u32 dataSize); - -static BOOL fioIsInitialized(void) { - return !!gChID; -} - -static u16 EndianConvert16(u16 n) { - return ((n & 0x00FF) << 8) | ((n & 0xFF00) >> 8); -} - -static u32 EndianConvert32(u32 n) { - return EndianConvert16((n >> 16) & 0xFFFF) | (EndianConvert16(n & 0xFFFF) << 0x10); -} - -static int MPDWaiting(int timeout, volatile int* flag, int value) { - OSTick tickStart; - OSTick tickDist; - - tickStart = OSGetTick(); - while(*flag != value) { - tickDist = OSGetTick() - tickStart; - tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; - if (OSTicksToSeconds(tickDist) >= timeout) { - OSReport("Error:Time is over.\n"); - return 0; - } - } - - return 1; -} - -static void ShowChannelInfo(MCC_CHANNEL chID) { - MCC_Info info; - - MCCGetChannelInfo(chID, &info); - OSReport("%2d: FirstBlock:%02d,BlockLength:%02d,Connect:%s,Lock:%s.\n", - chID, info.firstBlock, info.blockLength, - (info.connect == MCC_CONNECT_DISCONNECT) ? "DISCONNECT" : - (info.connect == MCC_CONNECT_HOST_OPEN) ? "HOST_OPEN" : - (info.connect == MCC_CONNECT_TARGET_OPEN) ? "TARGET_OPEN" : - (info.connect == MCC_CONNECT_CONNECTED) ? "CONNECTED" : "UNKNOWN", - (info.isLocked == FALSE) ? "UNLOCKED" : - (info.isLocked == TRUE) ? "LOCKED" : "UNKNOWN"); -} - -static void fioErrorReport(char* msg) { - OSReport("[fio] Error: %s\n", msg); -} - -static void fioMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value) { - u32 notify; - - switch(event) { - case MCC_EVENT_CONNECT: - gChID = chID; - return; - case MCC_EVENT_DISCONNECT: - gChID = 0; - return; - case MCC_EVENT_UNK_0x100: - notify = value & 0xF00000; - switch (notify) { - case 0x200000: - if ((u16)value == 0x120) { - gQuery = 1; - } - return; - case 0xF00000: - gProcDone = TRUE; - if (bAsyncBusy != 0) { - bAsyncBusy = FIO_ASYNC_STATE_DONE; - return; - } - break; - } - break; - case MCC_EVENT_READ: - gStreamReady = 0x10; - return; - case MCC_EVENT_WRITE: - gStreamReady = 0x20; - break; - } -} - -int FIOInit(MCC_EXI exiChannel, MCC_CHANNEL chID, u8 blockSize) { - OSRegisterVersion(__FIOVersion); - - if (MCCInit(exiChannel, 10, NULL) == 0) { - gLastErr = FIO_ERROR_MCC; - goto exit; - } - if (MCCOpen(chID, blockSize, fioMccChannelEvent) == 0) { - gLastErr = FIO_ERROR_MCC; - goto exit; - } - - gChID = chID; - gmChID = chID; - gSizeOfBlocks = blockSize; - gmSizeOfBlocks = blockSize; - gQuery = 0; - gProcDone = TRUE; - gProcBusy = FALSE; - gLastErr = FIO_ERROR_NONE; - bAsyncBusy = FIO_ASYNC_STATE_IDOL; - bAsyncBuffer = NULL; - bAsyncIsRead = FALSE; - return 1; - -exit:; - return 0; -} - -void FIOExit(void) { - if (MCCClose(gChID) == 0) { - gLastErr = FIO_ERROR_MCC; - return; - } - - gmChID = gChID = 0; - gmSizeOfBlocks = gSizeOfBlocks = 1; - gQuery = 0; - gProcDone = TRUE; - gProcBusy = FALSE; - gLastErr = FIO_ERROR_NONE; - bAsyncBusy = FIO_ASYNC_STATE_IDOL; - bAsyncBuffer = NULL; - bAsyncIsRead = FALSE; -} - -int FIOQuery(void) { - OSTick tick; - - if (fioIsInitialized()) { - gQuery = 0; - if (MCCNotify(gChID, 0x100120) == 0) { - gLastErr = FIO_ERROR_MCC; - goto exit; - } - if (MPDWaiting(10, &gQuery, 1) == 0) { - gLastErr = FIO_ERROR_TIMEOUT; - goto exit; - } - gLastErr = FIO_ERROR_NONE; - return 1; - } - -exit:; - tick = OSGetTick(); - do {} while(OSTicksToSeconds(OSGetTick() - tick) < 5); - return 0; -} - -u8 FIOGetLastError(void) { - return gLastErr; -} - -int FIOFopen(const char* filename, u32 mode) { - struct FIO_Code { - /* 0x00 */ u32 flag; - /* 0x04 */ s8 filename; // dynamic length - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ u32 descriptor; - } *coder; - - if (filename == NULL) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (mode & ~0xE03) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - code = fioPacketMakeHeader(0, strlen(filename) + sizeof(u32) + sizeof(s8), FALSE); - code->flag = mode; - memcpy(&code->filename, filename, strlen(filename) + 1); - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(1, TRUE); - if (coder != NULL) { - if (coder->result != 0) { - gLastErr = coder->result; - goto exit; - } - gLastErr = FIO_ERROR_NONE; - return coder->descriptor; - } - } -exit:; - return -1; -} - -int FIOFclose(int handle) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - } *coder; - - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - code = fioPacketMakeHeader(2, sizeof(struct FIO_Code), FALSE); - code->descriptor = handle; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(3, TRUE); - if (coder != NULL) { - gLastErr = coder->result; - return 1; - } - } - -exit:; - return 0; -} - -u32 FIOFread(int handle, void* data, u32 size) { - char* pBuf; - volatile int nSizeRemain; - int nResult; - int nReadSize; - - pBuf = data; - nSizeRemain = size; - nResult = -1; - - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (data == NULL || (u32)data & 0x1F) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (size == 0) { - return 0; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - nReadSize = fioPacketRead(handle, pBuf, nSizeRemain, 0); - nSizeRemain = nSizeRemain - nReadSize; - if (nReadSize < 0) { - gLastErr = FIO_ERROR_PACKET_READ; - return -1; - } - - gLastErr = FIO_ERROR_NONE; - return size - nSizeRemain; - -exit:; - return -1; -} - -u32 FIOFwrite(int handle, void* data, u32 size) { - volatile int nSizeRemain; - int nResult; - int nWriteSize; - - nSizeRemain = size; - nResult = 0; - - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (data == NULL || (u32)data & 0x1F) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (size == 0) { - return 0; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - nWriteSize = fioPacketWrite(handle, data, nSizeRemain, 0); - nSizeRemain -= nWriteSize; - if (nWriteSize < 0) { - gLastErr = FIO_ERROR_PACKET_WRITE; - return -1; - } - - gLastErr = FIO_ERROR_NONE; - return size - nSizeRemain; - -exit:; - return -1; -} - -u32 FIOFseek(int handle, s32 offset, u32 mode) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - /* 0x04 */ u32 offset; - /* 0x08 */ u32 base; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ u32 pos; - } *coder; - - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (!(mode == 0 || mode == 2 || mode == 1)) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (mode == 0 && offset < 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (mode == 2 && offset > 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - code = fioPacketMakeHeader(8, sizeof(struct FIO_Code), FALSE); - code->descriptor = handle; - code->offset = offset; - code->base = mode; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(9, TRUE); - if (coder != NULL && coder->result == 0) { - gLastErr = FIO_ERROR_NONE; - return coder->pos; - } - } - -exit: - return -1; -} - -int FIOFprintf(int handle, const char* format, ...) { - char* str; - int length; - int err; - va_list argptr; - - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (format == NULL) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - str = (char*)gPrintBuf; - va_start(argptr, format); - err = vsprintf(str, format, argptr); - if ((length = strlen(str)) < 0x100) { - str[length] = 0; - } else { - str[0xFF] = 0; - } - - length = strlen(str); - if (err < 0) { - gLastErr = FIO_ERROR_MSG_TOO_LONG; - return -1; - } - - gLastErr = FIO_ERROR_NONE; - return FIOFwrite(handle, str, length + 0); - -exit:; - va_end(argptr); - return -1; -} - -int FIOFflush(int handle) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - } *coder; - - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - code = fioPacketMakeHeader(10, 4, FALSE); - code->descriptor = handle; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(11, TRUE); - if (coder != NULL) { - if (coder->result != 0) { - gLastErr = coder->result; - goto exit; - } - gLastErr = FIO_ERROR_NONE; - return 1; - } - } - -exit: - return 0; -} - -int FIOFstat(int handle, FIO_Stat* stat) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ FIO_Stat stat; - } *coder; - - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (stat == NULL) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - code = fioPacketMakeHeader(12, 4, FALSE); - code->descriptor = handle; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(13, TRUE); - if (coder != NULL) { - if (stat) { - memcpy(stat, &coder->stat, sizeof(FIO_Stat)); - } - - if (coder->result != 0) { - gLastErr = coder->result; - goto exit; - } - - gLastErr = FIO_ERROR_NONE; - return 1; - } - } - -exit:; - return 0; -} - -int FIOFerror(int handle) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - } *coder; - - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - code = fioPacketMakeHeader(14, 4, FALSE); - code->descriptor = handle; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(15, TRUE); - if (coder != NULL) { - if (coder->result != 0) { - gLastErr = coder->result; - goto exit; - } - gLastErr = FIO_ERROR_NONE; - return gLastErr; - } - } - -exit:; - return gLastErr; -} - -int FIOFindFirst(const char* filename, FIO_Finddata* finddata) { - struct FIO_Code { - /* 0x00 */ u8 filename; // dynamic length - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ FIO_Finddata findData; - } *coder; - - if (filename == NULL) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (finddata == NULL) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - code = fioPacketMakeHeader(16, strlen(filename) + 1, FALSE); - strcpy((void*)&code->filename, filename); - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(17, TRUE); - if (coder != NULL) { - if (finddata) { - memcpy(finddata, &coder->findData, sizeof(FIO_Finddata)); - } - - if (coder->result != 0) { - gLastErr = coder->result; - goto exit; - } - - gLastErr = FIO_ERROR_NONE; - return 1; - } - } - -exit:; - return 0; -} - -int FIOFindNext(FIO_Finddata* finddata) { - struct FIO_Code { - /* 0x00 */ u32 reserved; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ FIO_Finddata findData; - } *coder; - - if (finddata == NULL) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - code = fioPacketMakeHeader(18, 4, FALSE); - code->reserved = 0; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(19, TRUE); - if (coder != NULL) { - if (finddata) { - memcpy(finddata, &coder->findData, sizeof(FIO_Finddata)); - } - - if (coder->result) { - gLastErr = coder->result; - goto exit; - } - - gLastErr = FIO_ERROR_NONE; - return 1; - } - } - -exit:; - return 0; -} - -int FIOOpenDir(const char* dirname, int* dir) { - struct FIO_Code { - /* 0x00 */ s8 filename; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ u32 descriptor; - } *coder; - - if (dirname == NULL) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - return 0; - } - if (dir == NULL) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - return 0; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - return 0; - } - - code = fioPacketMakeHeader(20, strlen(dirname) + 1, FALSE); - memcpy(&code->filename, dirname, strlen(dirname) + 1); - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(21, TRUE); - if (coder != NULL) { - if (coder->result != 0) { - gLastErr = coder->result; - goto exit; - } - - gLastErr = FIO_ERROR_NONE; - *dir = coder->descriptor; - return 1; - } - } - -exit:; - return 0; -} - -int FIOCloseDir(int dir) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - } *coder; - - if (dir == 0 || dir == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - return 0; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - return 0; - } - - code = fioPacketMakeHeader(22, 4, FALSE); - code->descriptor = dir; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(23, TRUE); - if (coder != NULL) { - gLastErr = coder->result; - return 1; - } - } - - return 0; -} - -s32 FIOGetDirSize(int dir) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ u32 size; - } *coder; - - if (dir == 0 || dir == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - return -1; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - return -1; - } - - code = fioPacketMakeHeader(24, 4, FALSE); - code->descriptor = dir; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(25, TRUE); - if (coder != NULL) { - gLastErr = coder->result; - return coder->size; - } - } - - return -1; -} - -s32 FIOReadDir(int dir, FIO_Finddata* data, s32 numOfData) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - /* 0x04 */ u32 size; - } *code; - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ u32 readsize; - } *coder; - s32 readSize; - u32 fReadSize; - - if (dir == 0 || dir == -1 || data == NULL || numOfData < 1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - return -1; - } - - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - return -1; - } - - code = fioPacketMakeHeader(26, 8, FALSE); - code->descriptor = dir; - code->size = numOfData; - - if (fioPacketSendPacket(1, NULL)) { - coder = fioPacketReceiveResult(27, TRUE); - if (coder != NULL) { - readSize = coder->readsize; - fReadSize = readSize * sizeof(FIO_Finddata); - gLastErr = coder->result; - - if (gLastErr == FIO_ERROR_NONE || gLastErr == FIO_ERROR_UNK_0x91) { - if (FIOFread(dir, data, fReadSize) == 0) { - return -1; - } - } else { - return -1; - } - - return readSize; - } - } - - return -1; -} - -u32 FIOGetAsyncBufferSize(void) { - int nPacketSize; - int nHeaderSize; - u32 nResult; - - if (gChID == 0) { - return 0; - } - - nPacketSize = gSizeOfBlocks << 0xD; - nHeaderSize = 0x18; - - nResult = nPacketSize - nHeaderSize; - return !(nResult & 0x1F) ? nResult : nResult & ~0x1F; -} - -int FIOFreadAsync(int handle, void* data, u32 size) { - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (data == NULL || (u32)data & 0x1F) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - - if (size != 0) { - if (size > FIOGetAsyncBufferSize()) { - gLastErr = FIO_ERROR_ASYNC_SIZE_TOO_BIG; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - bAsyncBusy = TRUE; - bAsyncBuffer = data; - bAsyncIsRead = TRUE; - if (fioPacketRead(handle, data, size, 1) >= 0) { - return 1; - } - } - -exit:; - return 0; -} - -int FIOFwriteAsync(int handle, void* data, u32 size) { - if (handle == 0) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (handle == -1) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - if (data == NULL || (u32)data & 0x1F) { - gLastErr = FIO_ERROR_INVALID_PARAMETERS; - goto exit; - } - - if (size != 0) { - if (size > FIOGetAsyncBufferSize()) { - gLastErr = FIO_ERROR_ASYNC_SIZE_TOO_BIG; - goto exit; - } - if (bAsyncBusy) { - gLastErr = FIO_ERROR_ASYNC_BUSY; - goto exit; - } - - bAsyncBusy = TRUE; - bAsyncBuffer = data; - bAsyncIsRead = FALSE; - if (fioPacketWrite(handle, data, size, 1) >= 0) { - return 1; - } - } - -exit: - return 0; -} - -int FIOCheckAsyncDone(u32* result) { - if (bAsyncBusy) { - if (bAsyncIsRead) { - if (result) { - *result = fioPacketResultRead(bAsyncBuffer, gAsyncDataSize); - } - } else if (result) { - *result = fioPacketResultWrite(bAsyncBuffer, gAsyncDataSize); - } - - bAsyncBusy = FALSE; - return 1; - } - - return 0; -} - -static void* fioPacketMakeHeader(u32 fioCode, u32 dataSize, BOOL bEndianConvert) { - MCC_Hdr* hdrDpci; - MCC_HdrFio* hdrFio; - char* data; - - hdrDpci = (void*)&gBuf[0]; - hdrFio = (void*)((char*)hdrDpci + 0x8); - data = (void*)((char*)hdrFio + 0x8); - - gRequestSequenceNumber += 1; - hdrFio->code = fioCode; - hdrFio->number = gRequestSequenceNumber; - hdrDpci->length = dataSize + 0x10; - hdrDpci->rsvd = 0; - hdrDpci->protocol = 0x120; - - if (bEndianConvert) { - hdrFio->code = EndianConvert32(hdrFio->code); - hdrFio->number = EndianConvert32(hdrFio->number); - hdrDpci->length = EndianConvert32(hdrDpci->length); - hdrDpci->protocol = EndianConvert16(hdrDpci->protocol); - } - return data; -} - -static int fioPacketSendPacket(u8 sizeOfBlocks, void* pTopOfSecondBlockData) { - u32 oldMaskWrite; - u8 indexOfBlocks; - - oldMaskWrite = MCCSetChannelEventMask(gChID, 0xA0); - - do {} while (gProcBusy); - do {} while (!gProcDone); - - gProcDone = FALSE; - gProcBusy = TRUE; - - for (indexOfBlocks = 0; indexOfBlocks < sizeOfBlocks; indexOfBlocks++) { - if (MCCWrite(gChID, ((u8)indexOfBlocks << 0xD), &gBuf, 0x2000, 0) == 0) { - gLastErr = FIO_ERROR_PACKET_WRITE; - MCCSetChannelEventMask(gChID, oldMaskWrite); - fioErrorReport("fioPacketSendPacket.MCCWrite.NG"); - return 0; - } - - if (sizeOfBlocks > 1) { - memcpy(&gBuf, pTopOfSecondBlockData, 0x2000); - ((char*)pTopOfSecondBlockData) += 0x2000; - } - } - - MCCSetChannelEventMask(gChID, oldMaskWrite); - if (MCCNotify(gChID, 0xF00000) == 0) { - gLastErr = FIO_ERROR_MCC; - fioErrorReport("fioPacketSendPacket.MCCNotify.NG"); - return 0; - } - - gLastErr = FIO_ERROR_NONE; - return 1; -} - -static void* fioPacketReceiveResult(u32 fioCode, BOOL bDone) { - u32 oldMaskRead; - MCC_Hdr* hdrDpci; - MCC_HdrFio* hdrFio; - char* data; - - if (MPDWaiting(10, &gProcDone, 1) == 0) { - gLastErr = FIO_ERROR_TIMEOUT; - goto exit; - } - - oldMaskRead = MCCSetChannelEventMask(gChID, 0x50); - if (MCCRead(gChID, 0, &gBuf, 0x2000, 0) == 0) { - gLastErr = FIO_ERROR_PACKET_READ; - MCCSetChannelEventMask(gChID, oldMaskRead); - goto exit; - } - - hdrDpci = (void*)((char*)&gBuf[0]); - hdrFio = (void*)((char*)hdrDpci + 0x8); - data = (void*)((char*)hdrFio + 0x8); - MCCSetChannelEventMask(gChID, oldMaskRead); - - if (hdrFio->code != fioCode) { - gLastErr = FIO_ERROR_WRONG_CODE; - goto exit; - } - if (hdrFio->number != gRequestSequenceNumber) { - gLastErr = FIO_ERROR_WRONG_SEQUENCE; - goto exit; - } - - if (bDone) { - fioPacketReceiveDone(); - } - - gLastErr = FIO_ERROR_NONE; - return data; - -exit:; - fioPacketReceiveDone(); - return NULL; -} - -static void fioPacketReceiveDone(void) { - gProcBusy = 0; -} - -static int fioPacketRead(int fd, void* buffer, int size, int async) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - /* 0x04 */ u32 nbytes; - } *code; - - code = fioPacketMakeHeader(4, sizeof(struct FIO_Code), FALSE); - code->descriptor = fd; - code->nbytes = size; - gStreamReady = 0; - - if (fioPacketSendPacket(1, NULL)) { - if (async == 0) { - return fioPacketResultRead(buffer, size); - } - gAsyncDataSize = size; - return 0; - } - - return -1; -} - -static int fioPacketWrite(int fd, void* buffer, int size, int async) { - struct FIO_Code { - /* 0x00 */ u32 descriptor; - /* 0x04 */ u32 nbytes; - } *code; - - code = fioPacketMakeHeader(6, 0xC, FALSE); - code->descriptor = fd; - code->nbytes = size; - - if (fioPacketSendPacket(1, NULL)) { - gStreamReady = 0; - if (async == 0) { - return fioPacketResultWrite(buffer, size); - } - gAsyncDataSize = size; - return 0; - } - - return -1; -} - -static int fioPacketResultRead(void* buffer, u32 dataSize) { - int bResult; - MCC_CHANNEL nChID; - u8 nChannelBlocks; - u32 dataBlockSize; - u32 readDataBlocks; - u32 nPacketSize; - u32 nDataPacketSize; - u32 nFraction; - MCC_CONNECT state; - BOOL bNeedWaitDisconnect; - u32 oldMaskWrite; - u8 err; - char msg[256]; - - bResult = 1; - nChID = gmChID; - nChannelBlocks = gmSizeOfBlocks; - dataBlockSize = (u32) (dataSize + 0x1FFF) >> 0xDU; - nPacketSize = ((u8)nChannelBlocks << 0xD); - nDataPacketSize = dataSize / nPacketSize; - nFraction = dataSize - (nDataPacketSize * nPacketSize); - nFraction = OSRoundUp32B(nFraction) & ~1; - - if (nFraction != 0) { - do {} while ((u32) gStreamReady != 0x20); - MCCRead(nChID, 0, buffer, nFraction, 0); - ((char*)buffer) += nFraction; - } - - if (nDataPacketSize != 0) { - bNeedWaitDisconnect = FALSE; - oldMaskWrite = MCCSetChannelEventMask(nChID, 0); - MCCSetChannelEventMask(nChID, oldMaskWrite); - - if (MCCClose(nChID) == 0) { - fioErrorReport("fioPacketResultRead.MCCClose.NG"); - bResult = 0; - } else { - do { - MCCGetConnectionStatus(nChID, &state); - } while (state != 0); - - if (MCCStreamOpen(nChID, nChannelBlocks) == 0) { - fioErrorReport("fioPacketResultRead.MCCStreamOpen.NG"); - bResult = 0; - } else { - do { - MCCGetConnectionStatus(nChID, &state); - } while (state != 3); - - if ((nDataPacketSize * nChannelBlocks) != (readDataBlocks = MCCStreamRead(nChID, buffer))) { - err = MCCGetLastError(); - sprintf(msg, "fioPacketResultRead.MCCStreamRead.NG(Err:%d)", err); - fioErrorReport(msg); - bResult = 0; - } - - if (MCCStreamClose(nChID) == 0) { - OSReport("MCCStream:MCCStreamClose.NG\n"); - bResult = 0; - } else { - MCC_CONNECT state; - do { - MCCGetConnectionStatus(nChID, &state); - } while (state != 0); - - if (MCCOpen(nChID, nChannelBlocks, fioMccChannelEvent) == 0) { - OSReport("MCCStream:MCCOpen.NG\n"); - bResult = 0; - } else { - do { - MCCGetConnectionStatus(nChID, &state); - } while (state != 3); - } - } - } - } - - MCCSetChannelEventMask(gChID, oldMaskWrite); - } - - // scope for variable? - { - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ u32 nbytes; - /* 0x08 */ char data; - } *coder; - - coder = fioPacketReceiveResult(5, FALSE); - if (coder == NULL) { - bResult = 0; - } else if (coder->result != 0) { - gLastErr = coder->result; - bResult = 0; - } else { - gLastErr = FIO_ERROR_NONE; - } - - fioPacketReceiveDone(); - if (bResult == 1) { - return dataSize; - } - goto exit; - } - -exit:; - return -1; -} - -static int fioPacketResultWrite(void* buffer, u32 dataSize) { - register int nResult = 0; - MCC_CHANNEL nChID; - u8 nChannelBlocks = 0; - u32 dataBlockSize; - MCC_CONNECT state; - BOOL bNeedWaitDisconnect; - u32 oldMaskWrite; - - nChID = gmChID; - nChannelBlocks = gmSizeOfBlocks; - dataBlockSize = (dataSize + 0x1FFF) >> 0xD; - bNeedWaitDisconnect = FALSE; - oldMaskWrite = MCCSetChannelEventMask(nChID, 0); - - MCCSetChannelEventMask(nChID, oldMaskWrite); - if (MCCClose(nChID) == 0) { - fioErrorReport("fioPacketResultWrite.MCCClose.NG"); - } else { -loop:; - MCCGetConnectionStatus(nChID, &state); - if (state != 0) { - goto loop; - } - - if (MCCStreamOpen(nChID, nChannelBlocks) == 0) { - fioErrorReport("fioPacketResultWrite.MCCStreamOpen.NG"); - goto loop; - } - - do { - MCCGetConnectionStatus(nChID, &state); - } while (state != 3); - - if (MCCStreamWrite(nChID, buffer, dataBlockSize) == 0) { - fioErrorReport("fioPacketResultWrite.MCCStreamWrite.NG"); - } - - { - MCC_CONNECT state; - do { - MCCGetConnectionStatus(nChID, &state); - } while (state == 3); - - if (MCCStreamClose(nChID) == 0) { - OSReport("MCCStream:MCCStreamClose.NG\n"); - } else { - do { - MCCGetConnectionStatus(nChID, &state); - } while (state == 0); - - if (MCCOpen(nChID, nChannelBlocks, fioMccChannelEvent) == 0) { - OSReport("MCCStream:MCCOpen.NG\n"); - } - } - } - goto exit_loop; - } - -exit_loop:; - { - struct FIO_Coder { - /* 0x00 */ u32 result; - /* 0x04 */ u32 nbytes; - } *coder; - - oldMaskWrite = MCCSetChannelEventMask(gChID, oldMaskWrite); - coder = fioPacketReceiveResult(7, TRUE); - - if (coder == NULL) { - (void)0; - } else { - if (coder->result) { - gLastErr = coder->result; - goto exit; - } - gLastErr = FIO_ERROR_NONE; - return coder->nbytes; - } - } - -exit: - return -1; -} diff --git a/src/dolphin/mcc/mcc.c b/src/dolphin/mcc/mcc.c deleted file mode 100644 index bed12b5..0000000 --- a/src/dolphin/mcc/mcc.c +++ /dev/null @@ -1,1417 +0,0 @@ -#include -#include - -#ifdef DEBUG -const char* __MCCVersion = "<< Dolphin SDK - MCC\tdebug build: Apr 5 2004 03:57:07 (0x2301) >>"; -#else -const char* __MCCVersion = "<< Dolphin SDK - MCC\trelease build: Apr 5 2004 04:15:49 (0x2301) >>"; -#endif - -static MCC_ChannelInfo gChannelInfo[16] ATTRIBUTE_ALIGN(32); -static char gStreamWork[32] ATTRIBUTE_ALIGN(32); -static char m_szAdapterMode[32] ATTRIBUTE_ALIGN(32); -static char m_szInitCode[32] ATTRIBUTE_ALIGN(32); -static MCC_Info channelInfo[16] ATTRIBUTE_ALIGN(32); - -volatile static BOOL gIsChannelinfoDirty = TRUE; - -static void (*volatile gCallbackSysEvent)(MCC_SYSEVENT); -static BOOL gOtherSideInitDone; -volatile static u8 gLastError; -static BOOL gMccInitialized; -static int gMccSession; -volatile static int gPingFlag; -volatile static u16 gAsyncResourceStatus; - -// prototypes -static void mccDebugPrint(char* str); -static void callbackEventStream(MCC_CHANNEL chID, u32 event, u32 value); -static int SetUsbAdapterMode(u8 mode); -static u8 GetUsbAdapterMode(void); -static int InitializeCodeClear(void); -static int InitializeCodeSet(void); -static int InitializeCodeCheck(void); -static void AsyncResourceClearState(void); -static void AsyncResourceSetState(u16 state); -static void AsyncResourceStateBusy(u8 channel, u16 mode); -static void AsyncResourceStateDone(void); -static u16 AsyncResourceGetStat(void); -static u16 AsyncResourceGetMode(void); -static u8 AsyncResourceGetChannel(void); -static int AsyncResourceIsBusy(void); -static int LoadChannelInfo(MCC_ChannelInfo* info); -static int FlushChannelInfo(MCC_ChannelInfo* info); -static void SetChannelInfoDirty(int dirty); -static void ClearChannelInfo(int i); -static void MakeMemoryMap(u8* map); -static BOOL IsChannelOpened(MCC_CHANNEL chID); -static u8 SearchFreeBlocks(MCC_MODE mode, u8* index); -static int NotifyCompulsorily(MCC_CHANNEL chID, u32 notify, u32 timeout); -static int NotifyInit(void); -static int NotifyInitDone(void); -static int NotifyChannelEvent(MCC_CHANNEL chID, u32 notify); -static int WaitAMinute(int timeout, volatile int* flag, int value); -static void MailboxCheck(void); -static void MCCExiCallback(void); -static void MCCTxCallback(void); -static void MCCRxCallback(void); -static int mccInitializeCheck(u8 timeout); - -static void mccDebugPrint(char* str) {} - -static void callbackEventStream(MCC_CHANNEL chID, u32 event, u32 value) { - value; // needed to bump registers. what? - - if (event == MCC_EVENT_READ) { - gChannelInfo[chID].isStreamDone = TRUE; - } - if (event == MCC_EVENT_WRITE) { - gChannelInfo[chID].isStreamDone = TRUE; - } - if (event == MCC_EVENT_CONNECT) { - gChannelInfo[chID].isStreamConnection = TRUE; - } - if (event == MCC_EVENT_DISCONNECT) { - gChannelInfo[chID].isStreamConnection = TRUE; - } - if (event == MCC_EVENT_UNK_0x100) { - gChannelInfo[chID].isStreamConnection = TRUE; - } -} - -BOOL MCCStreamOpen(MCC_CHANNEL chID, u8 blockSize) { - BOOL bResult; - - bResult = FALSE; - if (MCCOpen(chID, blockSize, callbackEventStream)) { - gChannelInfo[chID].isStreamOpened = 0; - gChannelInfo[chID].isStreamConnection = 0; - gChannelInfo[chID].isStreamDone = 0; - bResult = TRUE; - } - - return bResult; -} - -int MCCStreamClose(MCC_CHANNEL chID) { - gChannelInfo[chID].isStreamOpened = FALSE; - return MCCClose(chID); -} - -int MCCStreamWrite(MCC_CHANNEL chID, void* data, u32 dataBlockSize) { - MCC_Info chanInfo; - char* dataAddress; - u32 lastBlocks; - - if (!gMccInitialized) { - gLastError = 1; - } else if (chID < 1 || chID >= 16) { - gLastError = 14; - } else if (LoadChannelInfo(gChannelInfo) == 0) { - gLastError = 11; - } else { - if (gChannelInfo[chID].isStreamOpened != TRUE) { - gChannelInfo[chID].isStreamOpened = TRUE; - } else { - MCCNotify(chID, 0); - } - - if (WaitAMinute(5, &gChannelInfo[chID].isStreamConnection, 1) == 0) { - gLastError = 2; - } else { - gChannelInfo[chID].isStreamConnection = 0; - if (MCCGetChannelInfo(chID, &chanInfo) != 0) { - *(u32*)&gStreamWork = dataBlockSize; - if (MCCWrite(chID, 0, gStreamWork, 0x20, 0) != 0) { - if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { - gLastError = 2; - } else { - dataAddress = data; - lastBlocks = dataBlockSize; - gChannelInfo[chID].isStreamDone = FALSE; - while (lastBlocks) { - if (!MCCWrite(chID, 0, dataAddress, chanInfo.blockLength << 0xD, 0)) { - break; - } - - if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { - gLastError = 2; - break; - } else { - gChannelInfo[chID].isStreamDone = 0; - dataAddress += chanInfo.blockLength << 0xD; - if (lastBlocks > chanInfo.blockLength) { - lastBlocks -= chanInfo.blockLength; - } else { - lastBlocks = 0; - break; - } - } - } - - return lastBlocks == 0; - } - } - } - } - } - - return 0; -} - -u32 MCCStreamRead(MCC_CHANNEL chID, void* data) { - MCC_Info chanInfo; - char* dataAddress; - u32 allBlocks; - u32 lastBlocks; - - if (!gMccInitialized) { - gLastError = 1; - } else if (chID < 1 || chID >= 0x10) { - gLastError = 0xE; - } else if (LoadChannelInfo(gChannelInfo) == 0) { - gLastError = 0xB; - } else { - if (gChannelInfo[chID].isStreamOpened != TRUE) { - gChannelInfo[chID].isStreamOpened = TRUE; - } else { - MCCNotify(chID, 0); - } - - if (WaitAMinute(5, &gChannelInfo[chID].isStreamConnection, 1) == 0) { - gLastError = 2; - } else { - gChannelInfo[chID].isStreamConnection = FALSE; - if (MCCGetChannelInfo(chID, &chanInfo) != 0) { - if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { - gLastError = 2; - } else { - gChannelInfo[chID].isStreamDone = FALSE; - if (MCCRead(chID, 0, gStreamWork, 0x20, 0) != 0) { - dataAddress = data; - allBlocks = lastBlocks = *(u32*)&gStreamWork[0]; - while (lastBlocks) { - if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { - gLastError = 2; - break; - } - - gChannelInfo[chID].isStreamDone = FALSE; - if (MCCRead(chID, 0, dataAddress, (lastBlocks > chanInfo.blockLength) ? chanInfo.blockLength << 0xD : lastBlocks << 0xD, 0) != 0) { - dataAddress += chanInfo.blockLength << 0xD; - if (lastBlocks > chanInfo.blockLength) { - lastBlocks -= chanInfo.blockLength; - } else { - lastBlocks = 0; - break; - } - } else { - break; - } - } - return allBlocks - lastBlocks; - } - } - } - } - } - - return 0; -} - -static int SetUsbAdapterMode(u8 mode) { - int result = 0; - - if (HIORead(0x680, m_szAdapterMode, 0x20) != 0) { - DCInvalidateRange(m_szAdapterMode, 0x20); - m_szAdapterMode[0] = mode; - DCFlushRange(m_szAdapterMode, 0x20); - if (HIOWrite(0x680, m_szAdapterMode, 0x20) != 0) { - result = 1; - } - } - return result; -} - -static u8 GetUsbAdapterMode(void) { - if (HIORead(0x680, m_szAdapterMode, 0x20) != 0) { - DCInvalidateRange(m_szAdapterMode, 0x20); - return m_szAdapterMode[0]; - } - return 0; -} - -static int InitializeCodeClear(void) { - memset(m_szInitCode, 0, 0x20); - DCFlushRange(m_szInitCode, 0x20); - HIOWrite(0x600, m_szInitCode, 0x20); -} - -static int InitializeCodeSet(void) { - strcpy(m_szInitCode, "HUDSON/USB2EXI/INITCODE/TARGET"); - DCFlushRange(m_szInitCode, 0x20); - HIOWrite(0x600, m_szInitCode, 0x20); -} - -static int InitializeCodeCheck(void) { - int result; - - if ((result = HIORead(0x600, m_szInitCode, 0x20)) != 0) { - DCInvalidateRange(m_szInitCode, 0x20); - result = strcmp(m_szInitCode, "HUDSON/USB2EXI/INITCODE/HOST"); - return result == 0; - } - return result; -} - -static void AsyncResourceClearState(void) { - gAsyncResourceStatus = 0; -} - -static void AsyncResourceSetState(u16 state) { - gAsyncResourceStatus &= 0xFFFF0FFF; - gAsyncResourceStatus |= state; -} - -static void AsyncResourceStateBusy(u8 channel, u16 mode) { - AsyncResourceClearState(); - AsyncResourceSetState(0x1000); - gAsyncResourceStatus |= channel; - gAsyncResourceStatus |= mode; -} - -static void AsyncResourceStateDone(void) { - AsyncResourceSetState(0x2000); -} - -static u16 AsyncResourceGetStat(void) { - return gAsyncResourceStatus & 0xF000; -} - -static u16 AsyncResourceGetMode(void) { - return gAsyncResourceStatus & 0xF00; -} - -static u8 AsyncResourceGetChannel(void) { - return gAsyncResourceStatus; -} - -static int AsyncResourceIsBusy(void) { - return AsyncResourceGetStat() & 0x1000; -} - -static int LoadChannelInfo(MCC_ChannelInfo* info) { - volatile int result = 0; - u8 count; -#ifndef DEBUG - int unused; // this is fake, but i cant seem to find whats messing with the stack. -#endif - - if (!gIsChannelinfoDirty) { - result = 1; - } else { - count = 0; - mccDebugPrint("+++ Load channel info."); - while ((result = HIORead(0x700, channelInfo, 0x40)) != 1) { - count -= 1; - if (count == 0) { - break; - } - } - - if (result) { - DCInvalidateRange(channelInfo, 0x40); - for(count = 0; count < 16; count++) { - info[count].info = channelInfo[count]; - } - SetChannelInfoDirty(0); - } - } - - return result; -} - -static int FlushChannelInfo(MCC_ChannelInfo* info) { - volatile int result; - u8 count; - - result = 0; - for(count = 0; count < 16; count++) { - channelInfo[count] = info[count].info; - } - - DCFlushRange(channelInfo, 0x40); - while ((result = HIOWrite(0x700, channelInfo, 0x40)) != 1) { - count -= 1; - if (count == 0) { - break; - } - } - - if (result != 0) { - SetChannelInfoDirty(1); - result = NotifyCompulsorily(0, 5, 10); - } - return result; -} - -static void SetChannelInfoDirty(int dirty) { - gIsChannelinfoDirty = dirty; -} - -static void ClearChannelInfo(int i) { - gChannelInfo[i].info.firstBlock = 0; - gChannelInfo[i].info.blockLength = 0; - gChannelInfo[i].info.connect = 0; - gChannelInfo[i].info.isLocked = FALSE; - gChannelInfo[i].eventMask = 0; - gChannelInfo[i].callbackEvent = NULL; - gChannelInfo[i].isStreamDone = FALSE; - //! isStreamConnection isnt cleared. Intentional? -} - -static void MakeMemoryMap(u8* map) { - u8 iMap; - u8 jMap; - - memset(map, 0, 0x10); - for (iMap = 0; iMap < 16; iMap++) { - if (gChannelInfo[iMap].info.connect) { - for (jMap = 0; jMap < gChannelInfo[iMap].info.blockLength; jMap++) { - if (jMap + gChannelInfo[iMap].info.firstBlock < 0x10) { - map[gChannelInfo[iMap].info.firstBlock + jMap] = iMap + 1; - } else { - gLastError = 0xD; - } - } - } - } - - *map = 0xFF; -} - -static int IsChannelOpened(MCC_CHANNEL chID) { - u8 connectSide; - - if (chID <= 0 || chID >= 0x10) { - gLastError = 0xE; - goto exit; - } - connectSide = 2; - - return (connectSide & gChannelInfo[chID].info.connect) ? TRUE : FALSE; - -exit:; - return 0; -} - -static u8 SearchFreeBlocks(MCC_MODE mode, u8* index) { - u8 map[16]; - u8 iMap; - u8 fIndex; - u8 fSize; - u8 fCount; - - MakeMemoryMap(map); - fCount = 0; - fIndex = 0; - fSize = (mode == 0) ? 0x10 : 0; - - //! @bug I think this will read OOB of the map array by 1. - for (iMap = 0; iMap <= 16; iMap++) { - if (map[iMap] || iMap == 16) { - if (fCount != 0) { - if (mode == 0) { - if (fSize > fCount) { - fSize = fCount; - fIndex = iMap - fCount; - } - } else if (mode == 1) { - if (fSize < fCount) { - fSize = fCount; - fIndex = iMap - fCount; - } - } else if (mode == 2) { - fSize += fCount; - } - fCount = 0; - } - } else { - fCount += 1; - } - } - - if (index) { - *index = fIndex; - } - return fSize; -} - -static int NotifyCompulsorily(MCC_CHANNEL chID, u32 notify, u32 timeout) { - u32 status; - u32 notifyData; - volatile u32 tickStart; - volatile u32 tickCur; - volatile u32 tickSec; -#ifndef DEBUG - int unused; // fake but blah -#endif - - status = 0; - tickStart = OSGetTick(); - - notifyData = (chID << 0x18); - notifyData |= (notify & 0x10000000); - notifyData |= (notify & 0xFFFFFF); - - while (1) { - if (!HIOReadStatus(&status)) { - mccDebugPrint("ERROR:HIOReadStatus\n"); - } - - if ((status & 2) == 0) { - break; - } - - tickCur = OSGetTick(); - tickSec = (tickStart < tickCur) ? tickCur - tickStart : (-1 - tickStart) + tickCur; - tickSec = OSTicksToSeconds(tickSec); - if (timeout == 0 || tickSec > timeout) { - break; - } - } - - if (!HIOWriteMailbox(notifyData)) { - gLastError = 6; - goto exit; - } - return 1; - -exit:; - return 0; -} - -static int NotifyInit(void) { - return NotifyCompulsorily(0, 1, 0); -} - -static int NotifyInitDone(void) { - return NotifyCompulsorily(0, 2, 0); -} - -static int NotifyChannelEvent(MCC_CHANNEL chID, u32 notify) { -#ifndef DEBUG - int unused[2]; // fake but blah -#endif - - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - } else if (!IsChannelOpened(chID)) { - mccDebugPrint("Error:Channel is not opened.\n"); - gLastError = 0x12; - } else if (NotifyCompulsorily(chID, notify, 10) != 0) { - return 1; - } - - return 0; -} - -static int WaitAMinute(int timeout, volatile int* flag, int value) { - u32 tickStart; - u32 tickDist; - - tickStart = OSGetTick(); - while (*flag != value) { - tickDist = OSGetTick() - tickStart; - tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; - if (OSTicksToSeconds(tickDist) >= timeout) { - mccDebugPrint("Error:Time is over.\n"); - return 0; - } - } - return 1; -} - -static void MailboxCheck(void) { - u32 mailbox; - BOOL isNotify; - u8 chID; - u32 value; - BOOL bDoCall; -#ifndef DEBUG - int unused[3]; // fake but blah -#endif - - mailbox = 0; - if (HIOReadMailbox(&mailbox) == 0) { - mccDebugPrint("Error:Could not read mailbox.\n"); - gLastError = 5; - return; - } - - isNotify = (mailbox & 0x10000000) != 0; - chID = (mailbox >> 0x18U) & 0xF; - value = (mailbox & 0xFFFFFF); - - if (chID == 0) { - bDoCall = TRUE; - switch(value) { - case 2: - gMccInitialized = TRUE; - gMccSession = 1; - gOtherSideInitDone = TRUE; - break; - case 3: - NotifyCompulsorily(0, 4, 10); - break; - case 1: - gMccSession = 0; - break; - case 4: - if (gPingFlag == 0) { - bDoCall = FALSE; - } - gPingFlag = 0; - break; - case 5: - SetChannelInfoDirty(1); - break; - default: - if (value == 8) { - bDoCall = FALSE; - } else { - value = 0; - } - break; - } - - if (bDoCall && gCallbackSysEvent) { - gCallbackSysEvent(value); - } - } else { - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - return; - } - - if (IsChannelOpened(chID)) { - if (!!isNotify) { - if (gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, MCC_EVENT_UNK_0x100, value); - } - } else { - switch(value) { - case MCC_EVENT_READ_DONE_INSIDE: - case MCC_EVENT_WRITE_DONE_INSIDE: - mccDebugPrint("ERROR: MCC_EVENT_READ_DONE_INSIDE / MCC_EVENT_WRITE_DONE_INSIDE received."); - break; - case MCC_EVENT_CONNECT: - case MCC_EVENT_DISCONNECT: - case MCC_EVENT_LOCK: - case MCC_EVENT_UNLOCK: - case MCC_EVENT_READ: - case MCC_EVENT_WRITE: - if (gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, value, 0); - } - break; - default: - if (gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, 0, 0); - } - break; - } - } - } - } -} - -static void MCCExiCallback(void) { - MailboxCheck(); -} - -static void MCCTxCallback(void) { - AsyncResourceStateDone(); -} - -static void MCCRxCallback(void) { - AsyncResourceStateDone(); -} - -static int mccInitializeCheck(u8 timeout) { - int dmyFlag; - int i; -#ifndef DEBUG - int unused[3]; // fake but blah -#endif - - dmyFlag = 0; - if (InitializeCodeCheck() == 0) { - if (gMccInitialized) { - if (gMccSession == 0) { - SetChannelInfoDirty(1); - for (i = 0; i < 16; i++) { - ClearChannelInfo(i); - } - - if (FlushChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not flush channelInfo.\n"); - gLastError = 0xA; - return 0; - } - } - return 1; - } - - InitializeCodeSet(); - if (FlushChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not flush channelInfo.\n"); - gLastError = 0xA; - } else if (timeout != 0 && WaitAMinute(timeout, &gOtherSideInitDone, 1) == 0) { - InitializeCodeClear(); - mccDebugPrint("Error:Time is over.\n"); - gLastError = 2; - return 0; - } else { - return 1; - } - } else { - InitializeCodeClear(); - if (NotifyInitDone() == 0) { - gLastError = 4; - } else { - if (gCallbackSysEvent) { - gCallbackSysEvent(2); - } - gMccInitialized = TRUE; - gMccSession = 1; - return 1; - } - } - return 0; -} - -int MCCInit(MCC_EXI exiChannel, u8 timeout, MCC_CBSysEvent callbackSysEvent) { - int dmyFlag; - u8 adapterMode; - u32 mailbox; - u32 status; - int i; -#ifndef DEBUG - int unused[3]; // fake but blah -#endif - - OSRegisterVersion(__MCCVersion); - - mccDebugPrint("MCCInit\n"); - if (gMccInitialized) { - SetChannelInfoDirty(1); - return mccInitializeCheck(timeout); - } - - if (!(exiChannel == 0 || exiChannel == 1 || exiChannel == 2)) { - mccDebugPrint("[MCC] Error: Exi channel is out of range.\n"); - gLastError = 4; - return 0; - } - - if (HIOInit(exiChannel, MCCExiCallback) == 0) { - mccDebugPrint("Error:Initialized Host I/O\n"); - gLastError = 4; - } else { - dmyFlag = 0; - adapterMode = GetUsbAdapterMode(); - adapterMode = SetUsbAdapterMode(1); - mailbox = 0; - status = 0; - - if (HIOReadStatus(&status) != 0 && status & 1) { - HIOReadMailbox(&mailbox); - } - - WaitAMinute(1, &dmyFlag, 1); - if (NotifyInit() == 0) { - gLastError = 4; - } else { - gCallbackSysEvent = callbackSysEvent; - gLastError = 0; - SetChannelInfoDirty(1); - for (i = 0; i < 16; i++) { - ClearChannelInfo(i); - } - AsyncResourceClearState(); - return mccInitializeCheck(timeout); - } - } - - return 0; -} - -void MCCExit(void) { - u8 chID; - - if (!gMccInitialized) { - gLastError = 1; - } else { - mccDebugPrint("MCCExit\n"); - for (chID = 1; chID < 16; chID++) { - if (IsChannelOpened(chID)) { - MCCClose(chID); - } - } - gLastError = 0; - } - - gMccInitialized = FALSE; - gMccSession = 0; -} - -int MCCPing(void) { - mccDebugPrint("MCCPing\n"); - if (!gMccInitialized) { - gLastError = 1; - } else { - gPingFlag = 1; - gLastError = 0; - return NotifyCompulsorily(0, 3, 10); - } - return 0; -} - -int MCCEnumDevices(MCC_CBEnumDevices callbackEnumDevices) { - if (callbackEnumDevices == NULL) { - gLastError = 0xD; - } - - if (HIOEnumDevices(callbackEnumDevices) == 0) { - gLastError = 0xD; - } else { - gLastError = 0; - return 1; - } - - return 0; -} - -u8 MCCGetFreeBlocks(MCC_MODE mode) { -#ifndef DEBUG - int unused[3]; // fake but blah -#endif - - mccDebugPrint("MCCGetFreeBlocks\n"); - if (!gMccInitialized) { - gLastError = 1; - } else if (!(mode == 0 || mode == 1 || mode == 2)) { - gLastError = 0xD; - } else { - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - } else { - gLastError = 0; - return SearchFreeBlocks(mode, NULL); - } - } - - return 0; -} - -u8 MCCGetLastError(void) { - mccDebugPrint("MCCGetFreeBlocks\n"); //! wrong print? - return gLastError; -} - -int MCCGetChannelInfo(MCC_CHANNEL chID, MCC_Info* info) { -#ifndef DEBUG - int unused[3]; // fake but blah -#endif - - mccDebugPrint("MCCGetChannelInfo\n"); - if (!gMccInitialized) { - gLastError = 1; - } else if (chID <= 0 || chID >= 0x10) { - gLastError = 0xE; - } else if (!info) { - mccDebugPrint("Error:Bad parameter channelInfo.\n"); - gLastError = 0xD; - } else { - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - } else { - memcpy(info, &gChannelInfo[chID].info, sizeof(MCC_Info)); - gLastError = 0; - return 1; - } - } - - return 0; -} - -int MCCGetConnectionStatus(MCC_CHANNEL chID, MCC_CONNECT* connect) { - MCC_Info info; -#ifndef DEBUG - int unused[2]; // fake but blah -#endif - - mccDebugPrint("MCCGetConnectionStatus\n"); - if (!gMccInitialized) { - gLastError = 1; - return 0; - } - if (chID < 1 || chID >= 0x10) { - gLastError = 0xE; - return 0; - } - if (AsyncResourceIsBusy()) { - gLastError = 0x15; - return 0; - } - - if (!connect) { - mccDebugPrint("Error:Parameter error.\n"); - gLastError = 0xD; - } else { - if (MCCGetChannelInfo(chID, &info) != 0) { - *connect = info.connect; - gLastError = 0; - return 1; - } - } - - return 0; -} - -int MCCNotify(MCC_CHANNEL chID, u32 notify) { - MCC_CONNECT connect; -#ifndef DEBUG - int unused[3]; // fake but blah -#endif - - - mccDebugPrint("MCCNotify\n"); - if (!gMccInitialized) { - gLastError = 1; - } else if(chID <= 0 || chID >= 0x10) { - gLastError = 0xE;; - } else if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - } else if(MCCGetConnectionStatus(chID, &connect) == 0) { - gLastError = 9; - } else { - if (connect != 3) { - mccDebugPrint("Error:Channel is not opened.\n"); - gLastError = 0x12; - } else { - notify |= 0x10000000; - return NotifyCompulsorily(chID, notify, 0xAU); - } - } - - return 0; -} - -u32 MCCSetChannelEventMask(MCC_CHANNEL chID, u32 event) { - u32 oldMask; -#ifndef DEBUG - int unused[2]; // fake but blah -#endif - - oldMask = 0xFFFFFFFF; - if (!gMccInitialized) { - gLastError = 1; - } else if (chID <= 0 || chID >= 0x10) { - gLastError = 0xE; - } else if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - } else if (!IsChannelOpened(chID)) { - mccDebugPrint("Error:This channel is closed."); - gLastError = 0x12; - } else { - oldMask = gChannelInfo[chID].eventMask; - gChannelInfo[chID].eventMask = (u16)event; - } - - return oldMask; -} - -int MCCOpen(MCC_CHANNEL chID, u8 blockSize, MCC_CBEvent callbackEvent) { - u8 connectSide; - u8 blockIndex; -#ifndef DEBUG - int unused2[2]; -#endif - u8 freeBlocks; -#ifndef DEBUG - int unused[6]; // fake but blah -#endif - - mccDebugPrint("MCCOpen\n"); - if (!gMccInitialized) { - gLastError = 1; - return 0; - } - if (chID < 1 || chID >= 0x10) { - gLastError = 0xE; - return 0; - } - if (AsyncResourceIsBusy()) { - gLastError = 0x15; - return 0; - } - if (blockSize == 0) { - gLastError = 0xF; - return 0; - } - - if (chID <= 0 || chID >= 0x10) { - mccDebugPrint("Error:Invalid channel.\n"); - gLastError = 0xE; - goto exit; - } else { - connectSide = 2; - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - goto exit; - } else if (!gChannelInfo[chID].info.connect) { - freeBlocks = SearchFreeBlocks(1, &blockIndex); - if (blockSize > freeBlocks) { - mccDebugPrint("Error:Not enough free blocks.\n"); - gLastError = 0xC; - goto exit; - } else { - gChannelInfo[chID].info.firstBlock = blockIndex; - gChannelInfo[chID].info.blockLength = blockSize; - gChannelInfo[chID].info.connect = connectSide; - gChannelInfo[chID].info.isLocked = FALSE; - gChannelInfo[chID].eventMask = 0; - gChannelInfo[chID].callbackEvent = callbackEvent; - gChannelInfo[chID].isStreamDone = FALSE; - - if (FlushChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not flush channelInfo.\n"); - gLastError = 0xA; - goto exit; - } - gLastError = 0; - return 1; - } - } - } - - if (gChannelInfo[chID].info.connect & connectSide) { - mccDebugPrint("Error:Already opened.\n"); - gLastError = 0x11; - goto exit; - } else if (blockSize != gChannelInfo[chID].info.blockLength) { - mccDebugPrint("Error:Block size error.\n"); - gLastError = 0xD; - goto exit; - } - - gChannelInfo[chID].info.connect = 3; - gChannelInfo[chID].callbackEvent = callbackEvent; - - if (FlushChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not flush channelInfo.\n"); - gLastError = 0xA; - goto exit; - } - - if (~(gChannelInfo[chID].eventMask) & 1) { - NotifyCompulsorily(chID, 1, 10); - if (gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, 1, 0); - } - } - - gLastError = 0; - return 1; -exit:; - return 0; -} - -int MCCClose(MCC_CHANNEL chID) { - u8 connectSide; -#ifndef DEBUG - int unused[4]; // fake but blah -#endif - - connectSide = 2; - mccDebugPrint("MCCClose\n"); - if (!gMccInitialized) { - gLastError = 1; - return 0; - } - if (chID < 1 || chID >= 0x10) { - gLastError = 0xE; - return 0; - } - if (AsyncResourceIsBusy()) { - gLastError = 0x15; - return 0; - } - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - goto exit; - } - if (!IsChannelOpened(chID)) { - mccDebugPrint("Error:This channel is closed."); - gLastError = 0x12; - goto exit; - } - - gChannelInfo[chID].info.connect &= ~connectSide; - if (gChannelInfo[chID].info.connect == 0) { - ClearChannelInfo(chID); - } - if (FlushChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not flush channelInfo.\n"); - gLastError = 0xA; - goto exit; - } - - if (gChannelInfo[chID].info.connect != 0) { - if (~(gChannelInfo[chID].eventMask) & 2) { - NotifyCompulsorily(chID, 2, 10); - if (gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, 2, 0); - } - } - } - - gLastError = 0; - return 1; -exit:; - return 0; -} - -int MCCLock(MCC_CHANNEL chID) { -#ifndef DEBUG - int unused[7]; // fake but blah -#endif - - mccDebugPrint("MCCLock\n"); - - if (!gMccInitialized) { - gLastError = 1; - return 0; - } - if (chID < 1 || chID >= 0x10) { - gLastError = 0xE; - return 0; - } - if (AsyncResourceIsBusy()) { - gLastError = 0x15; - return 0; - } - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - goto exit; - } - if (!IsChannelOpened(chID)) { - mccDebugPrint("Error:This channel is closed."); - gLastError = 0x12; - goto exit; - } - if (gChannelInfo[chID].info.isLocked == TRUE) { - mccDebugPrint("Error:This channel is already locked."); - gLastError = 0x13; - goto exit; - } - - gChannelInfo[chID].info.isLocked = TRUE; - - if (FlushChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not flush channelInfo.\n"); - gLastError = 0xA; - goto exit; - } - - if (~(gChannelInfo[chID].eventMask) & 4) { - NotifyChannelEvent(chID, 4); - } - gLastError = 0; - return 1; - -exit:; - return 0; -} - -int MCCUnlock(MCC_CHANNEL chID) { -#ifndef DEBUG - int unused[7]; // fake but blah -#endif - - mccDebugPrint("MCCUnlock\n"); - - if (!gMccInitialized) { - gLastError = 1; - return 0; - } - if (chID < 1 || chID >= 0x10) { - gLastError = 0xE; - return 0; - } - if (AsyncResourceIsBusy()) { - gLastError = 0x15; - return 0; - } - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - goto exit; - } - if (!IsChannelOpened(chID)) { - mccDebugPrint("Error:This channel is closed."); - gLastError = 0x12; - goto exit; - } - if (gChannelInfo[chID].info.isLocked == FALSE) { - mccDebugPrint("Error:This channel is already unlocked."); - gLastError = 0x14; - goto exit; - } - - gChannelInfo[chID].info.isLocked = FALSE; - - if (FlushChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not flush channelInfo.\n"); - gLastError = 0xA; - goto exit; - } - - if (~(gChannelInfo[chID].eventMask) & 8) { - NotifyChannelEvent(chID, 8); - } - gLastError = 0; - return 1; - -exit: - return 0; -} - -int MCCRead(MCC_CHANNEL chID, u32 offset, void* data, s32 size, MCC_SYNC_STATE async) { -#ifndef DEBUG - int unused[11]; // fake but blah -#endif - - mccDebugPrint("MCCRead\n"); - if (!gMccInitialized) { - gLastError = 1; - return 0; - } - if (chID < 1 || chID >= 0x10) { - gLastError = 0xE; - return 0; - } - if (!(async == 1 || async == 0)) { - gLastError = 0xD; - return 0; - } - if ((offset & 3) || ((u32)data & 0x1F) || (size % 32) != 0) { - gLastError = 0xD; - return 0; - } - if (AsyncResourceIsBusy()) { - gLastError = 0x15; - return 0; - } - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - goto exit; - } - if (!IsChannelOpened(chID)) { - mccDebugPrint("Error:This channel is closed."); - gLastError = 0x12; - goto exit; - } - if (offset > gChannelInfo[chID].info.blockLength << 0xD) { - mccDebugPrint("Error:Invarid offset"); - gLastError = 0x10; - goto exit; - } - if ((offset + size) > gChannelInfo[chID].info.blockLength << 0xD) { - mccDebugPrint("Error:Invarid data size."); - gLastError = 0xF; - goto exit; - } - - if (async == 1) { - if (MCCCheckAsyncDone() == 0) { - mccDebugPrint("Error:Channel busy."); - gLastError = 0x15; - goto exit; - } - AsyncResourceStateBusy(chID, 0U); - if (HIOReadAsync(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size, MCCRxCallback) == 0) { - mccDebugPrint("Error:Read data error."); - gLastError = 7; - goto exit; - } - DCInvalidateRange(data, size); - gLastError = 0; - return 1; - } - - if (HIORead(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size) == 0) { - mccDebugPrint("Error:Read data error."); - gLastError = 7; - goto exit; - } - - DCInvalidateRange(data, size); - - if (~(gChannelInfo[chID].eventMask) & 0x10) { - NotifyChannelEvent(chID, 0x10); - } - - if (~(gChannelInfo[chID].eventMask) & 0x40 && gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, 0x40, 0); - } - gLastError = 0; - return 1; - -exit:; - return 0; -} - -int MCCWrite(MCC_CHANNEL chID, u32 offset, void* data, s32 size, MCC_SYNC_STATE async) { -#ifndef DEBUG - int unused[11]; // fake but blah -#endif - mccDebugPrint("MCCWrite\n"); - - if (!gMccInitialized) { - gLastError = 1; - return 0; - } - if (chID < 1 || chID >= 0x10) { - gLastError = 0xE; - return 0; - } - if (!(async == 1 || async == 0)) { - gLastError = 0xD; - return 0; - } - if ((offset & 3) || ((u32)data & 0x1F) || (size % 32) != 0) { - gLastError = 0xD; - return 0; - } - if (AsyncResourceIsBusy()) { - gLastError = 0x15; - return 0; - } - if (LoadChannelInfo(gChannelInfo) == 0) { - mccDebugPrint("Error:Could not update channelInfo.\n"); - gLastError = 0xB; - goto exit; - } - if (!IsChannelOpened(chID)) { - mccDebugPrint("Error:This channel is closed."); - gLastError = 0x12; - goto exit; - } - if (gChannelInfo[chID].info.isLocked == 1) { - mccDebugPrint("Error:This channel was locked."); - gLastError = 0x13; - goto exit; - } - if (offset > (gChannelInfo[chID].info.blockLength << 0xD)) { - mccDebugPrint("Error:Invarid offset"); - gLastError = 0x10; - goto exit; - } - if (offset + size > (gChannelInfo[chID].info.blockLength << 0xD)) { - mccDebugPrint("Error:Invarid data size."); - gLastError = 0xF; - goto exit; - } - - if (async == 1) { - if (MCCCheckAsyncDone() == 0) { - mccDebugPrint("Error:Channel busy."); - gLastError = 0x15; - goto exit; - } - AsyncResourceStateBusy(chID, 0x100); - DCFlushRange(data, size); - if (HIOWriteAsync(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size, MCCTxCallback) == 0) { - mccDebugPrint("Error:Write data error."); - gLastError = 8; - goto exit; - } - gLastError = 0; - return 1; - } - - DCFlushRange(data, size); - - if (HIOWrite(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size) == 0) { - mccDebugPrint("Error:Write data error."); - gLastError = 8; - goto exit; - } - - if (~(gChannelInfo[chID].eventMask) & 0x20) { - NotifyChannelEvent(chID, 0x20); - } - - if (~(gChannelInfo[chID].eventMask) & 0x80 && gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, 0x80, 0); - } - gLastError = 0; - return 1; - -exit: - return 0; -} - -int MCCCheckAsyncDone() { - u16 stat; - u16 mode; - u8 chID; -#ifndef DEBUG - int unused[5]; // fake but blah -#endif - - if (!gMccInitialized) { - gLastError = 1; - return 0; - } - - stat = AsyncResourceGetStat(); - - if (stat == 0x1000) { - return 0; - } else if (stat && stat == 0x2000) { - mode = AsyncResourceGetMode(); - chID = AsyncResourceGetChannel(); - AsyncResourceClearState(); - if (mode == 0) { - if (~(gChannelInfo[chID].eventMask) & 0x10) { - NotifyChannelEvent(chID, 0x10); - } - if (~(gChannelInfo[chID].eventMask) & 0x40 && gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, 0x40, 0); - } - } else { - if (~(gChannelInfo[chID].eventMask) & 0x20) { - NotifyChannelEvent(chID, 0x20); - } - if (~(gChannelInfo[chID].eventMask) & 0x80 && gChannelInfo[chID].callbackEvent) { - gChannelInfo[chID].callbackEvent(chID, 0x80, 0); - } - } - } - - return 1; -} diff --git a/src/dolphin/mcc/tty.c b/src/dolphin/mcc/tty.c deleted file mode 100644 index 1c230e4..0000000 --- a/src/dolphin/mcc/tty.c +++ /dev/null @@ -1,260 +0,0 @@ -#include -#include - -#ifdef DEBUG -const char* __TTYVersion = "<< Dolphin SDK - TTY\tdebug build: Apr 5 2004 03:57:08 (0x2301) >>"; -#else -const char* __TTYVersion = "<< Dolphin SDK - TTY\trelease build: Apr 5 2004 04:15:50 (0x2301) >>"; -#endif - -volatile static u8 gBuf[0x2000]; - -static u32 gOldEvent; -volatile static MCC_CHANNEL gChID; -volatile static int gQuery; -volatile static u32 gReadDone; -volatile static u32 gPrintfID; -volatile static u32 gBufHead; -volatile static u32 gBufTail; - -// prototypes -static int ttyIsInitialized(void); -static void ShowChannelInfo(MCC_CHANNEL chID); -static void ttyMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value); -static void ttyClearProperty(MCC_CHANNEL chID); -static int ttyWaiting(int timeout, volatile int* flag); -static int ttyWrite(u32 offset, void* data, s32 size); -static int ttyFlush(u32 msgID, BOOL waitResult); - -static int ttyIsInitialized(void) { - BOOL bResult = gChID != 0; - return bResult; -} - -static void ShowChannelInfo(MCC_CHANNEL chID) { - MCC_Info info; - - MCCGetChannelInfo(chID, &info); - OSReport("%2d: FirstBlock:%02d,BlockLength:%02d,Connect:%s,Lock:%s.\n", chID, - info.firstBlock,info.blockLength, - (info.connect == MCC_CONNECT_DISCONNECT) ? "DISCONNECT" : - (info.connect == MCC_CONNECT_HOST_OPEN) ? "HOST_OPEN" : - (info.connect == MCC_CONNECT_TARGET_OPEN) ? "TARGET_OPEN" : - (info.connect == MCC_CONNECT_CONNECTED) ? "CONNECTED" : "UNKNOWN", - (info.isLocked == FALSE) ? "UNLOCKED" : - (info.isLocked == TRUE) ? "LOCKED" : "UNKNOWN"); -} - -static void ttyMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value) { - u32 notify; - u32 size; - u32 msgID; - - switch(event) { - case MCC_EVENT_CONNECT: - gChID = chID; - return; - case MCC_EVENT_DISCONNECT: - gChID = 0; - return; - case MCC_EVENT_UNK_0x100: - notify = (value & (0xF00000)); - switch(notify) { - case 0x200000: - if ((u16)value == 0x210) { - gQuery = 1; - } - return; - case 0x400000: - size = (value >> 8) & 0xFF; - msgID = (value) & 0xFF; - if ((gBufTail - gBufHead) >= 0x2000) { - gBufHead = ((u32) gBufHead < 0x2000U) ? gBufHead : gBufHead - 0x2000; - gBufTail = ((u32) gBufTail < 0x2000U) ? gBufTail : gBufTail - 0x2000; - } - if ((u32) gBufHead >= 0x2000U) { - gBufHead -= 0x2000; - gBufTail -= 0x2000; - } - if (size == 0) { - gBufHead += size << 5; - gReadDone = (u32) msgID; - return; - } - gBufHead += size << 5; - gReadDone = (u32) msgID; - } - } -} - -int TTYInit(MCC_EXI exiChannel, MCC_CHANNEL chID) { - if (ttyIsInitialized()) { - return 0; - } - - OSRegisterVersion(__TTYVersion); - - if (MCCInit(exiChannel, 5, NULL) && MCCOpen(chID, 1, ttyMccChannelEvent)) { - gOldEvent = MCCSetChannelEventMask(chID, 0x30); - ttyClearProperty(chID); - return 1; - } - - return 0; -} - -void TTYExit(void) { - if (ttyIsInitialized()) { - MCCSetChannelEventMask(gChID, gOldEvent); - if (MCCClose(gChID) != 0) { - ttyClearProperty(0); - } - } -} - -int TTYQuery(void) { - u32 tick; - - if (ttyIsInitialized()) { - gQuery = 0; - if (MCCNotify(gChID, 0x100210)) { - return ttyWaiting(5, &gQuery); - } - } - - tick = OSGetTick(); - do {} while(OSTicksToSeconds(OSGetTick() - tick) < 5); - return 0; -} - -int TTYPrintf(const char* format, ...) { - if (ttyIsInitialized() && format != NULL) { - MCC_Hdr* hdr; - u32* id; - char* str; - u32 maxDataSize; - u32 formatLength; - u32 dataSize; - int err; - char* eof; - va_list argptr; - u32 prosecced; - - hdr = (void*)&gBuf; - id = (u32*)(hdr + 1); - str = (char*)(id + 1); - - maxDataSize = 8179; - formatLength = strlen(format); - if (formatLength > maxDataSize) { - eof = (void*)((-1 + maxDataSize + (u32)format)); - *(eof) = 0; - } - - va_start(argptr, format); - err = vsprintf(str, format, argptr); - if (strlen(str) < maxDataSize) { - str[strlen(str)] = 0; - } else { - err = -1; - } - - if (err < 0) { - return 0; - } - - hdr->length = strlen(str) + 13; - hdr->rsvd = 0; - hdr->protocol = 0x210; - dataSize = OSRoundUp32B(hdr->length) & ~1; - if ((0x2000 - (gBufTail - gBufHead)) <= dataSize) { - ttyFlush(gPrintfID, 1); - } - - gPrintfID += 1; - gPrintfID = (u8) gPrintfID; - *id = gPrintfID; - - if ((0x2000 - (gBufTail & 0x1FFF)) < dataSize) { - prosecced = 0x2000 - (gBufTail & 0x1FFF); - ttyWrite(gBufTail & 0x1FFF, (char*)&gBuf, prosecced); - ttyWrite(0, (char*)&gBuf + prosecced, dataSize - prosecced); - } else { - ttyWrite(gBufTail & 0x1FFF, (char*)&gBuf, dataSize); - } - - gBufTail += dataSize; - if (strchr(str, '\n') != 0) { - ttyFlush(gPrintfID, TRUE); - } else if (gPrintfID == 0xFF) { - ttyFlush(gPrintfID, TRUE); - } - - va_end(format); - return 1; - } - - return 0; -} - -int TTYFlush(void) { - if (!ttyIsInitialized()) { - return 0; - } - - return ttyFlush(gPrintfID, TRUE); -} - -static void ttyClearProperty(MCC_CHANNEL chID) { - gChID = chID; - gQuery = 0; - gReadDone = 0; - gPrintfID = 0; - gBufHead = 0; - gBufTail = 0; -} - -static int ttyWaiting(int timeout, volatile int* flag) { - u32 tickStart; - u32 tickDist; - - tickStart = OSGetTick(); - timeout = OSSecondsToTicks(timeout); - while(*flag == 0) { - tickDist = OSGetTick() - tickStart; - tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; - if (OSTicksToSeconds(tickDist) >= timeout) { - return 0; - } - } - - return 1; -} - -static int ttyWrite(u32 offset, void* data, s32 size) { - if (MCCWrite(gChID, offset, data, size, 0)) { - return 1; - } - return 0; -} - -static int ttyFlush(u32 msgID, BOOL waitResult) { - u32 notify; - - notify = msgID | 0x300000; - - if ((gBufTail - gBufHead) == 0) { - return 1; - } - - if (MCCNotify(gChID, notify) == 0) { - while(1) - ; - } - - if (waitResult) { - do {} while (gReadDone != msgID); - } - - return 1; -} diff --git a/src/dolphin/mtx/mtx.c b/src/dolphin/mtx/mtx.c deleted file mode 100644 index 66b850f..0000000 --- a/src/dolphin/mtx/mtx.c +++ /dev/null @@ -1,1197 +0,0 @@ -#include -#include -#include "fake_tgmath.h" - -static f32 Unit01[2] = { - 0.0f, - 1.0f -}; - -void C_MTXIdentity(Mtx m) { - ASSERTMSGLINE(189, m, "MtxIdentity(): NULL Mtx 'm' "); - m[0][0] = 1; - m[0][1] = 0; - m[0][2] = 0; - m[0][3] = 0; - m[1][0] = 0; - m[1][1] = 1; - m[1][2] = 0; - m[1][3] = 0; - m[2][0] = 0; - m[2][1] = 0; - m[2][2] = 1; - m[2][3] = 0; -} - -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 - } -} - -void C_MTXCopy(const Mtx src, Mtx dst) { - ASSERTMSGLINE(250, src, "MTXCopy(): NULL MtxPtr 'src' "); - ASSERTMSGLINE(251, dst, "MTXCopy(): NULL MtxPtr 'dst' "); - if (src != dst) { - dst[0][0] = src[0][0]; - dst[0][1] = src[0][1]; - dst[0][2] = src[0][2]; - dst[0][3] = src[0][3]; - dst[1][0] = src[1][0]; - dst[1][1] = src[1][1]; - dst[1][2] = src[1][2]; - dst[1][3] = src[1][3]; - dst[2][0] = src[2][0]; - dst[2][1] = src[2][1]; - dst[2][2] = src[2][2]; - dst[2][3] = src[2][3]; - } -} - -asm void PSMTXCopy(const register Mtx src, register Mtx dst) { - psq_l f0, 0(src), 0, 0 - psq_st f0, 0(dst), 0, 0 - psq_l f1, 8(src), 0, 0 - psq_st f1, 8(dst), 0, 0 - psq_l f2, 16(src), 0, 0 - psq_st f2, 16(dst), 0, 0 - psq_l f3, 24(src), 0, 0 - psq_st f3, 24(dst), 0, 0 - psq_l f4, 32(src), 0, 0 - psq_st f4, 32(dst), 0, 0 - psq_l f5, 40(src), 0, 0 - psq_st f5, 40(dst), 0, 0 -} - -void C_MTXConcat(const Mtx a, const Mtx b, Mtx ab) { - Mtx mTmp; - MtxPtr m; - - ASSERTMSGLINE(324, a, "MTXConcat(): NULL MtxPtr 'a' "); - ASSERTMSGLINE(325, b, "MTXConcat(): NULL MtxPtr 'b' "); - ASSERTMSGLINE(326, ab, "MTXConcat(): NULL MtxPtr 'ab' "); - - if (ab == a || ab == b) { - m = mTmp; - } else { - m = ab; - } - - m[0][0] = 0 + a[0][2] * b[2][0] + ((a[0][0] * b[0][0]) + (a[0][1] * b[1][0])); - m[0][1] = 0 + a[0][2] * b[2][1] + ((a[0][0] * b[0][1]) + (a[0][1] * b[1][1])); - m[0][2] = 0 + a[0][2] * b[2][2] + ((a[0][0] * b[0][2]) + (a[0][1] * b[1][2])); - m[0][3] = a[0][3] + (a[0][2] * b[2][3] + (a[0][0] * b[0][3] + (a[0][1] * b[1][3]))); - - m[1][0] = 0 + a[1][2] * b[2][0] + ((a[1][0] * b[0][0]) + (a[1][1] * b[1][0])); - m[1][1] = 0 + a[1][2] * b[2][1] + ((a[1][0] * b[0][1]) + (a[1][1] * b[1][1])); - m[1][2] = 0 + a[1][2] * b[2][2] + ((a[1][0] * b[0][2]) + (a[1][1] * b[1][2])); - m[1][3] = a[1][3] + (a[1][2] * b[2][3] + (a[1][0] * b[0][3] + (a[1][1] * b[1][3]))); - - m[2][0] = 0 + a[2][2] * b[2][0] + ((a[2][0] * b[0][0]) + (a[2][1] * b[1][0])); - m[2][1] = 0 + a[2][2] * b[2][1] + ((a[2][0] * b[0][1]) + (a[2][1] * b[1][1])); - m[2][2] = 0 + a[2][2] * b[2][2] + ((a[2][0] * b[0][2]) + (a[2][1] * b[1][2])); - m[2][3] = a[2][3] + (a[2][2] * b[2][3] + (a[2][0] * b[0][3] + (a[2][1] * b[1][3]))); - - if (m == mTmp) { - C_MTXCopy(mTmp, ab); - } -} - -asm void PSMTXConcat(const register Mtx a, const register Mtx b, register Mtx ab) { - nofralloc - stwu r1, -64(r1) - psq_l f0, 0(a), 0, 0 - stfd f14, 8(r1) - psq_l f6, 0(b), 0, 0 - lis r6, Unit01@ha - psq_l f7, 8(b), 0, 0 - stfd f15, 16(r1) - addi r6, r6, Unit01@l - stfd f31, 40(r1) - psq_l f8, 16(b), 0, 0 - ps_muls0 f12, f6, f0 - psq_l f2, 16(a), 0, 0 - ps_muls0 f13, f7, f0 - psq_l f31, 0(r6), 0, 0 - ps_muls0 f14, f6, f2 - psq_l f9, 24(b), 0, 0 - ps_muls0 f15, f7, f2 - psq_l f1, 8(a), 0, 0 - ps_madds1 f12, f8, f0, f12 - psq_l f3, 24(a), 0, 0 - ps_madds1 f14, f8, f2, f14 - psq_l f10, 32(b), 0, 0 - ps_madds1 f13, f9, f0, f13 - psq_l f11, 40(b), 0, 0 - ps_madds1 f15, f9, f2, f15 - psq_l f4, 32(a), 0, 0 - psq_l f5, 40(a), 0, 0 - ps_madds0 f12, f10, f1, f12 - ps_madds0 f13, f11, f1, f13 - ps_madds0 f14, f10, f3, f14 - ps_madds0 f15, f11, f3, f15 - psq_st f12, 0(ab), 0, 0 - ps_muls0 f2, f6, f4 - ps_madds1 f13, f31, f1, f13 - ps_muls0 f0, f7, f4 - psq_st f14, 16(ab), 0, 0 - ps_madds1 f15, f31, f3, f15 - psq_st f13, 8(ab), 0, 0 - ps_madds1 f2, f8, f4, f2 - ps_madds1 f0, f9, f4, f0 - ps_madds0 f2, f10, f5, f2 - lfd f14, 8(r1) - psq_st f15, 24(ab), 0, 0 - ps_madds0 f0, f11, f5, f0 - psq_st f2, 32(ab), 0, 0 - ps_madds1 f0, f31, f5, f0 - lfd f15, 16(r1) - psq_st f0, 40(ab), 0, 0 - lfd f31, 40(r1) - addi r1, r1, 64 - blr -} - -void C_MTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count) { - u32 i; - - ASSERTMSGLINE(580, a != 0, "MTXConcatArray(): NULL MtxPtr 'a' "); - ASSERTMSGLINE(581, srcBase != 0, "MTXConcatArray(): NULL MtxPtr 'srcBase' "); - ASSERTMSGLINE(582, dstBase != 0, "MTXConcatArray(): NULL MtxPtr 'dstBase' "); - ASSERTMSGLINE(583, count > 1, "MTXConcatArray(): count must be greater than 1."); - - for (i = 0; i < count; i++) { - C_MTXConcat(a, *srcBase, *dstBase); - srcBase++; - dstBase++; - } -} - -#if DEBUG -#pragma push -#pragma optimization_level 1 -// This function will not compile at optimization level 0 -#endif -void PSMTXConcatArray(const register Mtx a, const register Mtx* srcBase, register Mtx* dstBase, register u32 count) { - register f32 va0, va1, va2, va3, va4, va5; - register f32 vb0, vb1, vb2, vb3, vb4, vb5; - register f32 vd0, vd1, vd2, vd3, vd4, vd5; - register f32 u01; - register f32* u01Ptr = Unit01; - - asm { - psq_l va0, 0(a), 0, 0; - psq_l va1, 8(a), 0, 0; - psq_l va2, 16(a), 0, 0; - psq_l va3, 24(a), 0, 0; - subi count, count, 1; - psq_l va4, 32(a), 0, 0; - psq_l va5, 40(a), 0, 0; - mtctr count; - psq_l u01, 0(u01Ptr), 0, 0; - psq_l vb0, 0(srcBase), 0, 0; - psq_l vb2, 16(srcBase), 0, 0; - ps_muls0 vd0, vb0, va0; - ps_muls0 vd2, vb0, va2; - ps_muls0 vd4, vb0, va4; - psq_l vb4, 32(srcBase), 0, 0; - ps_madds1 vd0, vb2, va0, vd0; - ps_madds1 vd2, vb2, va2, vd2; - ps_madds1 vd4, vb2, va4, vd4; - psq_l vb1, 8(srcBase), 0, 0; - ps_madds0 vd0, vb4, va1, vd0; - ps_madds0 vd2, vb4, va3, vd2; - ps_madds0 vd4, vb4, va5, vd4; - psq_l vb3, 24(srcBase), 0, 0; - psq_st vd0, 0(dstBase), 0, 0; - ps_muls0 vd1, vb1, va0; - ps_muls0 vd3, vb1, va2; - ps_muls0 vd5, vb1, va4; - psq_l vb5, 40(srcBase), 0, 0; - psq_st vd2, 16(dstBase), 0, 0; - ps_madds1 vd1, vb3, va0, vd1; - ps_madds1 vd3, vb3, va2, vd3; - ps_madds1 vd5, vb3, va4, vd5; - _loop: - addi srcBase, srcBase, sizeof(Mtx); - ps_madds0 vd1, vb5, va1, vd1; - ps_madds0 vd3, vb5, va3, vd3; - ps_madds0 vd5, vb5, va5, vd5; - psq_l vb0, 0(srcBase), 0, 0; - psq_st vd4, 32(dstBase), 0, 0; - ps_madd vd1, u01, va1, vd1; - ps_madd vd3, u01, va3, vd3; - ps_madd vd5, u01, va5, vd5; - psq_l vb2, 16(srcBase), 0, 0; - psq_st vd1, 8(dstBase), 0, 0; - ps_muls0 vd0, vb0, va0; - ps_muls0 vd2, vb0, va2; - ps_muls0 vd4, vb0, va4; - psq_l vb4, 32(srcBase), 0, 0; - psq_st vd3, 24(dstBase), 0, 0; - ps_madds1 vd0, vb2, va0, vd0; - ps_madds1 vd2, vb2, va2, vd2; - ps_madds1 vd4, vb2, va4, vd4; - psq_l vb1, 8(srcBase), 0, 0; - psq_st vd5, 40(dstBase), 0, 0; - addi dstBase, dstBase, sizeof(Mtx); - ps_madds0 vd0, vb4, va1, vd0; - ps_madds0 vd2, vb4, va3, vd2; - ps_madds0 vd4, vb4, va5, vd4; - psq_l vb3, 24(srcBase), 0, 0; - psq_st vd0, 0(dstBase), 0, 0; - ps_muls0 vd1, vb1, va0; - ps_muls0 vd3, vb1, va2; - ps_muls0 vd5, vb1, va4; - psq_l vb5, 40(srcBase), 0, 0; - psq_st vd2, 16(dstBase), 0, 0; - ps_madds1 vd1, vb3, va0, vd1; - ps_madds1 vd3, vb3, va2, vd3; - ps_madds1 vd5, vb3, va4, vd5; - bdnz _loop; - psq_st vd4, 32(dstBase), 0, 0; - ps_madds0 vd1, vb5, va1, vd1; - ps_madds0 vd3, vb5, va3, vd3; - ps_madds0 vd5, vb5, va5, vd5; - ps_madd vd1, u01, va1, vd1; - ps_madd vd3, u01, va3, vd3; - ps_madd vd5, u01, va5, vd5; - psq_st vd1, 8(dstBase), 0, 0; - psq_st vd3, 24(dstBase), 0, 0; - psq_st vd5, 40(dstBase), 0, 0; - } -} -#if DEBUG -#pragma pop -#endif - -void C_MTXTranspose(const Mtx src, Mtx xPose) { - Mtx mTmp; - MtxPtr m; - - ASSERTMSGLINE(851, src, "MTXTranspose(): NULL MtxPtr 'src' "); - ASSERTMSGLINE(852, xPose, "MTXTranspose(): NULL MtxPtr 'xPose' "); - - if (src == xPose) { - m = mTmp; - } else { - m = xPose; - } - - m[0][0] = src[0][0]; - m[0][1] = src[1][0]; - m[0][2] = src[2][0]; - m[0][3] = 0; - m[1][0] = src[0][1]; - m[1][1] = src[1][1]; - m[1][2] = src[2][1]; - m[1][3] = 0; - m[2][0] = src[0][2]; - m[2][1] = src[1][2]; - m[2][2] = src[2][2]; - m[2][3] = 0; - if (m == mTmp) { - C_MTXCopy(mTmp, xPose); - } -} - -void PSMTXTranspose(const register Mtx src, register Mtx xPose) { - register f32 c_zero = 0; - register f32 row0a; - register f32 row1a; - register f32 row0b; - register f32 row1b; - register f32 trns0; - register f32 trns1; - register f32 trns2; - - asm { - psq_l row0a, 0(src), 0, 0 - } - xPose[2][3] = c_zero; - asm { - psq_l row1a, 16(src), 0, 0 - ps_merge00 trns0, row0a, row1a - psq_l row0b, 8(src), 1, 0 - ps_merge11 trns1, row0a, row1a - psq_l row1b, 24(src), 1, 0 - psq_st trns0, 0(xPose), 0, 0 - psq_l row0a, 32(src), 0, 0 - ps_merge00 trns2, row0b, row1b - psq_st trns1, 16(xPose), 0, 0 - ps_merge00 trns0, row0a, c_zero - psq_st trns2, 32(xPose), 0, 0 - ps_merge10 trns1, row0a, c_zero - psq_st trns0, 8(xPose), 0, 0 - } - row0b = src[2][2]; - asm { - psq_st trns1, 24(xPose), 0, 0 - } - xPose[2][2] = row0b; -} - -u32 C_MTXInverse(const Mtx src, Mtx inv) { - Mtx mTmp; - MtxPtr m; - f32 det; - - ASSERTMSGLINE(950, src, "MTXInverse(): NULL MtxPtr 'src' "); - ASSERTMSGLINE(951, inv, "MTXInverse(): NULL MtxPtr 'inv' "); - - if (src == inv) { - m = mTmp; - } else { - m = inv; - } - det = ((((src[2][1] * (src[0][2] * src[1][0])) - + ((src[2][2] * (src[0][0] * src[1][1])) - + (src[2][0] * (src[0][1] * src[1][2])))) - - (src[0][2] * (src[2][0] * src[1][1]))) - - (src[2][2] * (src[1][0] * src[0][1]))) - - (src[1][2] * (src[0][0] * src[2][1])); - if (0 == det) { - return 0; - } - det = 1 / det; - m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2]))); - m[0][1] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2]))); - m[0][2] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2]))); - - m[1][0] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2]))); - m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2]))); - m[1][2] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2]))); - - m[2][0] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1]))); - m[2][1] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1]))); - m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1]))); - - m[0][3] = ((-m[0][0] * src[0][3]) - (m[0][1] * src[1][3])) - (m[0][2] * src[2][3]); - m[1][3] = ((-m[1][0] * src[0][3]) - (m[1][1] * src[1][3])) - (m[1][2] * src[2][3]); - m[2][3] = ((-m[2][0] * src[0][3]) - (m[2][1] * src[1][3])) - (m[2][2] * src[2][3]); - - if (m == mTmp) { - C_MTXCopy(mTmp, inv); - } - return 1; -} - -asm u32 PSMTXInverse(const register Mtx src, register Mtx inv) { - psq_l f0, 0(src), 1, 0 - psq_l f1, 4(src), 0, 0 - psq_l f2, 16(src), 1, 0 - ps_merge10 f6, f1, f0 - psq_l f3, 20(src), 0, 0 - psq_l f4, 32(src), 1, 0 - ps_merge10 f7, f3, f2 - psq_l f5, 36(src), 0, 0 - ps_mul f11, f3, f6 - ps_mul f13, f5, f7 - ps_merge10 f8, f5, f4 - ps_msub f11, f1, f7, f11 - ps_mul f12, f1, f8 - ps_msub f13, f3, f8, f13 - ps_mul f10, f3, f4 - ps_msub f12, f5, f6, f12 - ps_mul f9, f0, f5 - ps_mul f8, f1, f2 - ps_sub f6, f6, f6 - ps_msub f10, f2, f5, f10 - ps_mul f7, f0, f13 - ps_msub f9, f1, f4, f9 - ps_madd f7, f2, f12, f7 - ps_msub f8, f0, f3, f8 - ps_madd f7, f4, f11, f7 - ps_cmpo0 cr0, f7, f6 - bne skip_return - li r3, 0 - blr -skip_return: - fres f0, f7 - ps_add f6, f0, f0 - ps_mul f5, f0, f0 - ps_nmsub f0, f7, f5, f6 - lfs f1, 12(src) - ps_muls0 f13, f13, f0 - lfs f2, 28(src) - ps_muls0 f12, f12, f0 - lfs f3, 44(src) - ps_muls0 f11, f11, f0 - ps_merge00 f5, f13, f12 - ps_muls0 f10, f10, f0 - ps_merge11 f4, f13, f12 - ps_muls0 f9, f9, f0 - psq_st f5, 0(inv), 0, 0 - ps_mul f6, f13, f1 - psq_st f4, 16(inv), 0, 0 - ps_muls0 f8, f8, f0 - ps_madd f6, f12, f2, f6 - psq_st f10, 32(inv), 1, 0 - ps_nmadd f6, f11, f3, f6 - psq_st f9, 36(inv), 1, 0 - ps_mul f7, f10, f1 - ps_merge00 f5, f11, f6 - psq_st f8, 40(inv), 1, 0 - ps_merge11 f4, f11, f6 - psq_st f5, 8(inv), 0, 0 - ps_madd f7, f9, f2, f7 - psq_st f4, 24(inv), 0, 0 - ps_nmadd f7, f8, f3, f7 - li r3, 1 - psq_st f7, 44(inv), 1, 0 -} - -u32 C_MTXInvXpose(const Mtx src, Mtx invX) { - Mtx mTmp; - MtxPtr m; - f32 det; - - ASSERTMSGLINE(1185, src, "MTXInvXpose(): NULL MtxPtr 'src' "); - ASSERTMSGLINE(1186, invX, "MTXInvXpose(): NULL MtxPtr 'invX' "); - - if (src == invX) { - m = mTmp; - } else { - m = invX; - } - det = ((((src[2][1] * (src[0][2] * src[1][0])) - + ((src[2][2] * (src[0][0] * src[1][1])) - + (src[2][0] * (src[0][1] * src[1][2])))) - - (src[0][2] * (src[2][0] * src[1][1]))) - - (src[2][2] * (src[1][0] * src[0][1]))) - - (src[1][2] * (src[0][0] * src[2][1])); - if (0 == det) { - return 0; - } - det = 1 / det; - m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2]))); - m[0][1] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2]))); - m[0][2] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1]))); - - m[1][0] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2]))); - m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2]))); - m[1][2] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1]))); - - m[2][0] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2]))); - m[2][1] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2]))); - m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1]))); - - m[0][3] = 0; - m[1][3] = 0; - m[2][3] = 0; - - if (m == mTmp) { - C_MTXCopy(mTmp, invX); - } - return 1; -} - -asm u32 PSMTXInvXpose(const register Mtx src, register Mtx invX) { - psq_l f0, 0(src), 1, 0 - psq_l f1, 4(src), 0, 0 - psq_l f2, 16(src), 1, 0 - ps_merge10 f6, f1, f0 - psq_l f3, 20(src), 0, 0 - psq_l f4, 32(src), 1, 0 - ps_merge10 f7, f3, f2 - psq_l f5, 36(src), 0, 0 - ps_mul f11, f3, f6 - ps_merge10 f8, f5, f4 - ps_mul f13, f5, f7 - ps_msub f11, f1, f7, f11 - ps_mul f12, f1, f8 - ps_msub f13, f3, f8, f13 - ps_msub f12, f5, f6, f12 - ps_mul f10, f3, f4 - ps_mul f9, f0, f5 - ps_mul f8, f1, f2 - ps_msub f10, f2, f5, f10 - ps_msub f9, f1, f4, f9 - ps_msub f8, f0, f3, f8 - ps_mul f7, f0, f13 - ps_sub f1, f1, f1 - ps_madd f7, f2, f12, f7 - ps_madd f7, f4, f11, f7 - ps_cmpo0 cr0, f7, f1 - bne skip_return - li r3, 0 - blr -skip_return: - fres f0, f7 - psq_st f1, 12(invX), 1, 0 - ps_add f6, f0, f0 - ps_mul f5, f0, f0 - psq_st f1, 28(invX), 1, 0 - ps_nmsub f0, f7, f5, f6 - psq_st f1, 44(invX), 1, 0 - ps_muls0 f13, f13, f0 - ps_muls0 f12, f12, f0 - ps_muls0 f11, f11, f0 - psq_st f13, 0(invX), 0, 0 - psq_st f12, 16(invX), 0, 0 - ps_muls0 f10, f10, f0 - ps_muls0 f9, f9, f0 - psq_st f11, 32(invX), 0, 0 - psq_st f10, 8(invX), 1, 0 - ps_muls0 f8, f8, f0 - li r3, 1 - psq_st f9, 24(invX), 1, 0 - psq_st f8, 40(invX), 1, 0 -} - -void C_MTXRotRad(Mtx m, char axis, f32 rad) { - f32 sinA; - f32 cosA; - - ASSERTMSGLINE(1447, m, "MTXRotRad(): NULL MtxPtr 'm' "); - sinA = sinf(rad); - cosA = cosf(rad); - C_MTXRotTrig(m, axis, sinA, cosA); -} - -void PSMTXRotRad(Mtx m, char axis, f32 rad) { - f32 sinA, cosA; - sinA = sinf(rad); - cosA = cosf(rad); - PSMTXRotTrig(m, axis, sinA, cosA); -} - -void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA) { - ASSERTMSGLINE(1502, m, "MTXRotTrig(): NULL MtxPtr 'm' "); - switch(axis) { - case 'x': - case 'X': - m[0][0] = 1; - m[0][1] = 0; - m[0][2] = 0; - m[0][3] = 0; - m[1][0] = 0; - m[1][1] = cosA; - m[1][2] = -sinA; - m[1][3] = 0; - m[2][0] = 0; - m[2][1] = sinA; - m[2][2] = cosA; - m[2][3] = 0; - break; - case 'y': - case 'Y': - m[0][0] = cosA; - m[0][1] = 0; - m[0][2] = sinA; - m[0][3] = 0; - m[1][0] = 0; - m[1][1] = 1; - m[1][2] = 0; - m[1][3] = 0; - m[2][0] = -sinA; - m[2][1] = 0; - m[2][2] = cosA; - m[2][3] = 0; - break; - case 'z': - case 'Z': - m[0][0] = cosA; - m[0][1] = -sinA; - m[0][2] = 0; - m[0][3] = 0; - m[1][0] = sinA; - m[1][1] = cosA; - m[1][2] = 0; - m[1][3] = 0; - m[2][0] = 0; - m[2][1] = 0; - m[2][2] = 1; - m[2][3] = 0; - break; - default: - ASSERTMSGLINE(1529, FALSE, "MTXRotTrig(): invalid 'axis' value "); - break; - } -} - -void PSMTXRotTrig(register Mtx m, register char axis, register f32 sinA, register f32 cosA) { - register f32 fc0, fc1, nsinA; - register f32 fw0, fw1, fw2, fw3; - - asm { - frsp sinA, sinA - frsp cosA, cosA - } - - fc0 = 0.0f; - fc1 = 1.0f; - - asm { - ori axis, axis, 0x20 - ps_neg nsinA, sinA - cmplwi axis, 'x' - beq _case_x - cmplwi axis, 'y' - beq _case_y - cmplwi axis, 'z' - beq _case_z - b _end - - _case_x: - psq_st fc1, 0(m), 1, 0 - psq_st fc0, 4(m), 0, 0 - ps_merge00 fw0, sinA, cosA - psq_st fc0, 12(m), 0, 0 - ps_merge00 fw1, cosA, nsinA - psq_st fc0, 28(m), 0, 0 - psq_st fc0, 44(m), 1, 0 - psq_st fw0, 36(m), 0, 0 - psq_st fw1, 20(m), 0, 0 - b _end; - - _case_y: - ps_merge00 fw0, cosA, fc0 - ps_merge00 fw1, fc0, fc1 - psq_st fc0, 24(m), 0, 0 - psq_st fw0, 0(m), 0, 0 - ps_merge00 fw2, nsinA, fc0 - ps_merge00 fw3, sinA, fc0 - psq_st fw0, 40(m), 0, 0; - psq_st fw1, 16(m), 0, 0; - psq_st fw3, 8(m), 0, 0; - psq_st fw2, 32(m), 0, 0; - b _end; - - _case_z: - psq_st fc0, 8(m), 0, 0 - ps_merge00 fw0, sinA, cosA - ps_merge00 fw2, cosA, nsinA - psq_st fc0, 24(m), 0, 0 - psq_st fc0, 32(m), 0, 0 - ps_merge00 fw1, fc1, fc0 - psq_st fw0, 16(m), 0, 0 - psq_st fw2, 0(m), 0, 0 - psq_st fw1, 40(m), 0, 0 - - _end: - } -} - -static void __PSMTXRotAxisRadInternal(register Mtx m, const register Vec* axis, register f32 sT, register f32 cT) { - register f32 tT, fc0; - register f32 tmp0, tmp1, tmp2, tmp3, tmp4; - register f32 tmp5, tmp6, tmp7, tmp8, tmp9; - tmp9 = 0.5f; - tmp8 = 3.0f; - - asm { - frsp cT, cT; - psq_l tmp0, 0(axis), 0, 0; - frsp sT, sT; - lfs tmp1, 8(axis); - ps_mul tmp2, tmp0, tmp0; - fadds tmp7, tmp9, tmp9; - ps_madd tmp3, tmp1, tmp1, tmp2; - fsubs fc0, tmp9, tmp9; - ps_sum0 tmp4, tmp3, tmp1, tmp2; - fsubs tT, tmp7, cT; - frsqrte tmp5, tmp4; - fmuls tmp2, tmp5, tmp5; - fmuls tmp3, tmp5, tmp9; - fnmsubs tmp2, tmp2, tmp4, tmp8; - fmuls tmp5, tmp2, tmp3; - ps_merge00 cT, cT, cT; - ps_muls0 tmp0, tmp0, tmp5; - ps_muls0 tmp1, tmp1, tmp5; - ps_muls0 tmp4, tmp0, tT; - ps_muls0 tmp9, tmp0, sT; - ps_muls0 tmp5, tmp1, tT; - ps_muls1 tmp3, tmp4, tmp0; - ps_muls0 tmp2, tmp4, tmp0; - ps_muls0 tmp4, tmp4, tmp1; - fnmsubs tmp6, tmp1, sT, tmp3; - fmadds tmp7, tmp1, sT, tmp3; - ps_neg tmp0, tmp9; - ps_sum0 tmp8, tmp4, fc0, tmp9; - ps_sum0 tmp2, tmp2, tmp6, cT; - ps_sum1 tmp3, cT, tmp7, tmp3; - ps_sum0 tmp6, tmp0, fc0, tmp4; - psq_st tmp8, 8(m), 0, 0; - ps_sum0 tmp0, tmp4, tmp4, tmp0; - psq_st tmp2, 0(m), 0, 0; - ps_muls0 tmp5, tmp5, tmp1; - psq_st tmp3, 16(m), 0, 0; - ps_sum1 tmp4, tmp9, tmp0, tmp4; - psq_st tmp6, 24(m), 0, 0; - ps_sum0 tmp5, tmp5, fc0, cT; - psq_st tmp4, 32(m), 0, 0; - psq_st tmp5, 40(m), 0, 0; - } -} - -void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { - f32 sinT, cosT; - - sinT = sinf(rad); - cosT = cosf(rad); - - __PSMTXRotAxisRadInternal(m, axis, sinT, cosT); -} - -void C_MTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { - Vec vN; - f32 s; - f32 c; - f32 t; - f32 x; - f32 y; - f32 z; - f32 xSq; - f32 ySq; - f32 zSq; - - ASSERTMSGLINE(1677, m, "MTXRotAxisRad(): NULL MtxPtr 'm' "); - ASSERTMSGLINE(1678, axis, "MTXRotAxisRad(): NULL VecPtr 'axis' "); - - s = sinf(rad); - c = cosf(rad); - t = 1 - c; - C_VECNormalize(axis, &vN); - x = vN.x; - y = vN.y; - z = vN.z; - xSq = (x * x); - ySq = (y * y); - zSq = (z * z); - m[0][0] = (c + (t * xSq)); - m[0][1] = (y * (t * x)) - (s * z); - m[0][2] = (z * (t * x)) + (s * y); - m[0][3] = 0; - m[1][0] = ((y * (t * x)) + (s * z)); - m[1][1] = (c + (t * ySq)); - m[1][2] = ((z * (t * y)) - (s * x)); - m[1][3] = 0; - m[2][0] = ((z * (t * x)) - (s * y)); - m[2][1] = ((z * (t * y)) + (s * x)); - m[2][2] = (c + (t * zSq)); - m[2][3] = 0; -} - -void C_MTXTrans(Mtx m, f32 xT, f32 yT, f32 zT) { - ASSERTMSGLINE(1866, m, "MTXTrans(): NULL MtxPtr 'm' "); - m[0][0] = 1; - m[0][1] = 0; - m[0][2] = 0; - m[0][3] = xT; - m[1][0] = 0; - m[1][1] = 1; - m[1][2] = 0; - m[1][3] = yT; - m[2][0] = 0; - m[2][1] = 0; - m[2][2] = 1; - m[2][3] = zT; -} - -void PSMTXTrans(register Mtx m, register f32 xT, register f32 yT, register f32 zT) { - register f32 c0 = 0.0f; - register f32 c1 = 1.0f; - - asm { - stfs xT, 12(m) - stfs yT, 28(m) - psq_st c0, 4(m), 0, 0 - psq_st c0, 32(m), 0, 0 - stfs c0, 16(m) - stfs c1, 20(m) - stfs c0, 24(m) - stfs c1, 40(m) - stfs zT, 44(m) - stfs c1, 0(m) - } -} - -void C_MTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT) { - ASSERTMSGLINE(1933, src, "MTXTransApply(): NULL MtxPtr 'src' "); - ASSERTMSGLINE(1934, dst, "MTXTransApply(): NULL MtxPtr 'src' "); //! wrong assert string - - if (src != dst) { - dst[0][0] = src[0][0]; - dst[0][1] = src[0][1]; - dst[0][2] = src[0][2]; - dst[1][0] = src[1][0]; - dst[1][1] = src[1][1]; - dst[1][2] = src[1][2]; - dst[2][0] = src[2][0]; - dst[2][1] = src[2][1]; - dst[2][2] = src[2][2]; - } - - dst[0][3] = (src[0][3] + xT); - dst[1][3] = (src[1][3] + yT); - dst[2][3] = (src[2][3] + zT); -} - -asm void PSMTXTransApply(const register Mtx src, register Mtx dst, register f32 xT, register f32 yT, register f32 zT) { - nofralloc - psq_l fp4, 0(src), 0, 0 - frsp xT, xT - psq_l fp5, 8(src), 0, 0 - frsp yT, yT - psq_l fp7, 24(src), 0, 0 - frsp zT, zT - psq_l fp8, 40(src), 0, 0 - psq_st fp4, 0(dst), 0, 0 - ps_sum1 fp5, xT, fp5, fp5 - psq_l fp6, 16(src), 0, 0 - psq_st fp5, 8(dst), 0, 0 - ps_sum1 fp7, yT, fp7, fp7 - psq_l fp9, 32(src), 0, 0 - psq_st fp6, 16(dst), 0, 0 - ps_sum1 fp8, zT, fp8, fp8 - psq_st fp7, 24(dst), 0, 0 - psq_st fp9, 32(dst), 0, 0 - psq_st fp8, 40(dst), 0, 0 - blr -} - -void C_MTXScale(Mtx m, f32 xS, f32 yS, f32 zS) { - ASSERTMSGLINE(2008, m, "MTXScale(): NULL MtxPtr 'm' "); - m[0][0] = xS; - m[0][1] = 0; - m[0][2] = 0; - m[0][3] = 0; - m[1][0] = 0; - m[1][1] = yS; - m[1][2] = 0; - m[1][3] = 0; - m[2][0] = 0; - m[2][1] = 0; - m[2][2] = zS; - m[2][3] = 0; -} - -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) - } -} - -void C_MTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS) { - ASSERTMSGLINE(2070, src, "MTXScaleApply(): NULL MtxPtr 'src' "); - ASSERTMSGLINE(2071, dst, "MTXScaleApply(): NULL MtxPtr 'dst' "); - dst[0][0] = (src[0][0] * xS); - dst[0][1] = (src[0][1] * xS); - dst[0][2] = (src[0][2] * xS); - dst[0][3] = (src[0][3] * xS); - dst[1][0] = (src[1][0] * yS); - dst[1][1] = (src[1][1] * yS); - dst[1][2] = (src[1][2] * yS); - dst[1][3] = (src[1][3] * yS); - dst[2][0] = (src[2][0] * zS); - dst[2][1] = (src[2][1] * zS); - dst[2][2] = (src[2][2] * zS); - dst[2][3] = (src[2][3] * zS); -} - -asm void PSMTXScaleApply(const register Mtx src, register Mtx dst, register f32 xS, register f32 yS, register f32 zS) { - nofralloc - frsp xS, xS - psq_l fp4, 0(src), 0, 0 - frsp yS, yS - psq_l fp5, 8(src), 0, 0 - frsp zS, zS - ps_muls0 fp4, fp4, xS - psq_l fp6, 16(src), 0, 0 - ps_muls0 fp5, fp5, xS - psq_l fp7, 24(src), 0, 0 - ps_muls0 fp6, fp6, yS - psq_l fp8, 32(src), 0, 0 - psq_st fp4, 0(dst), 0, 0 - ps_muls0 fp7, fp7, yS - psq_l fp2, 40(src), 0, 0 - psq_st fp5, 8(dst), 0, 0 - ps_muls0 fp8, fp8, zS - psq_st fp6, 16(dst), 0, 0 - ps_muls0 fp2, fp2, zS - psq_st fp7, 24(dst), 0, 0 - psq_st fp8, 32(dst), 0, 0 - psq_st fp2, 40(dst), 0, 0 - blr -} - -void C_MTXQuat(Mtx m, const Quaternion* q) { - f32 s; - f32 xs; - f32 ys; - f32 zs; - f32 wx; - f32 wy; - f32 wz; - f32 xx; - f32 xy; - f32 xz; - f32 yy; - f32 yz; - f32 zz; - - ASSERTMSGLINE(2145, m, "MTXQuat(): NULL MtxPtr 'm' "); - ASSERTMSGLINE(2146, q, "MTXQuat(): NULL QuaternionPtr 'q' "); - ASSERTMSGLINE(2147, q->x || q->y || q->z || q->w, "MTXQuat(): zero-value quaternion "); - s = 2 / ((q->w * q->w) + ((q->z * q->z) + ((q->x * q->x) + (q->y * q->y)))); - xs = q->x * s; - ys = q->y * s; - zs = q->z * s; - wx = q->w * xs; - wy = q->w * ys; - wz = q->w * zs; - xx = q->x * xs; - xy = q->x * ys; - xz = q->x * zs; - yy = q->y * ys; - yz = q->y * zs; - zz = q->z * zs; - m[0][0] = (1 - (yy + zz)); - m[0][1] = (xy - wz); - m[0][2] = (xz + wy); - m[0][3] = 0; - m[1][0] = (xy + wz); - m[1][1] = (1 - (xx + zz)); - m[1][2] = (yz - wx); - m[1][3] = 0; - m[2][0] = (xz - wy); - m[2][1] = (yz + wx); - m[2][2] = (1 - (xx + yy)); - m[2][3] = 0; -} - -void PSMTXQuat(register Mtx m, const register Quaternion* q) { - register f32 c_zero, c_one, c_two, scale; - register f32 tmp0, tmp1, tmp2, tmp3, tmp4; - register f32 tmp5, tmp6, tmp7, tmp8, tmp9; - c_one = 1.0f; - - asm { - psq_l tmp0, 0(q), 0, 0 - psq_l tmp1, 8(q), 0, 0 - fsubs c_zero, c_one, c_one - fadds c_two, c_one, c_one - ps_mul tmp2, tmp0, tmp0 - ps_merge10 tmp5, tmp0, tmp0 - ps_madd tmp4, tmp1, tmp1, tmp2 - ps_mul tmp3, tmp1, tmp1 - ps_sum0 scale, tmp4, tmp4, tmp4 - ps_muls1 tmp7, tmp5, tmp1 - fres tmp9, scale - ps_sum1 tmp4, tmp3, tmp4, tmp2 - ps_nmsub scale, scale, tmp9, c_two - ps_muls1 tmp6, tmp1, tmp1 - ps_mul scale, tmp9, scale - ps_sum0 tmp2, tmp2, tmp2, tmp2 - fmuls scale, scale, c_two - ps_madd tmp8, tmp0, tmp5, tmp6 - ps_msub tmp6, tmp0, tmp5, tmp6 - psq_st c_zero, 12(m), 1, 0 - ps_nmsub tmp2, tmp2, scale, c_one - ps_nmsub tmp4, tmp4, scale, c_one - psq_st c_zero, 44(m), 1, 0 - ps_mul tmp8, tmp8, scale - ps_mul tmp6, tmp6, scale - psq_st tmp2, 40(m), 1, 0 - ps_madds0 tmp5, tmp0, tmp1, tmp7 - ps_merge00 tmp1, tmp8, tmp4 - ps_nmsub tmp7, tmp7, c_two, tmp5 - ps_merge10 tmp0, tmp4, tmp6 - psq_st tmp1, 16(m), 0, 0 - ps_mul tmp5, tmp5, scale - ps_mul tmp7, tmp7, scale - psq_st tmp0, 0(m), 0, 0 - psq_st tmp5, 8(m), 1, 0 - ps_merge10 tmp3, tmp7, c_zero - ps_merge01 tmp9, tmp7, tmp5 - psq_st tmp3, 24(m), 0, 0 - psq_st tmp9, 32(m), 0, 0 - } -} - -void C_MTXReflect(Mtx m, const Vec* p, const Vec* n) { - f32 vxy; - f32 vxz; - f32 vyz; - f32 pdotn; - - vxy = -2 * n->x * n->y; - vxz = -2 * n->x * n->z; - vyz = -2 * n->y * n->z; - pdotn = 2 * C_VECDotProduct(p, n); - m[0][0] = (1 - (2 * n->x * n->x)); - m[0][1] = vxy; - m[0][2] = vxz; - m[0][3] = (pdotn * n->x); - m[1][0] = vxy; - m[1][1] = (1 - (2 * n->y * n->y)); - m[1][2] = vyz; - m[1][3] = (pdotn * n->y); - m[2][0] = vxz; - m[2][1] = vyz; - m[2][2] = (1 - (2 * n->z * n->z)); - m[2][3] = (pdotn * n->z); -} - -void PSMTXReflect(register Mtx m, const register Vec* p, const register Vec* n) { - register f32 c_one; - register f32 vn_xy, vn_z1; - register f32 n2vn_xy, n2vn_z1; - register f32 pdotn; - register f32 tmp0, tmp1, tmp2, tmp3; - register f32 tmp4, tmp5, tmp6, tmp7; - - c_one = 1.0f; - - asm { - psq_l vn_z1, 0x8(n), 1, 0 - psq_l vn_xy, 0x0(n), 0, 0 - psq_l tmp0, 0x0(p), 0, 0 - ps_nmadd n2vn_z1, vn_z1, c_one, vn_z1 - psq_l tmp1, 0x8(p), 1, 0 - ps_nmadd n2vn_xy, vn_xy, c_one, vn_xy - ps_muls0 tmp4, vn_xy, n2vn_z1 - ps_mul pdotn, n2vn_xy, tmp0 - ps_muls0 tmp2, vn_xy, n2vn_xy - ps_sum0 pdotn, pdotn, pdotn, pdotn - ps_muls1 tmp3, vn_xy, n2vn_xy - psq_st tmp4, 0x20(m), 0, 0 - ps_sum0 tmp2, tmp2, tmp2, c_one - ps_nmadd pdotn, n2vn_z1, tmp1, pdotn - ps_sum1 tmp3, c_one, tmp3, tmp3 - psq_st tmp2, 0x0(m), 0, 0 - ps_muls0 tmp5, vn_xy, pdotn - ps_merge00 tmp6, n2vn_z1, pdotn - psq_st tmp3, 0x10(m), 0, 0 - ps_merge00 tmp7, tmp4, tmp5 - ps_muls0 tmp6, tmp6, vn_z1 - ps_merge11 tmp5, tmp4, tmp5 - psq_st tmp7, 0x8(m), 0, 0 - ps_sum0 tmp6, tmp6, tmp6, c_one - psq_st tmp5, 0x18(m), 0, 0 - psq_st tmp6, 0x28(m), 0, 0 - } -} - -void C_MTXLookAt(Mtx m, const Point3d* camPos, const Vec* camUp, const Point3d* target) { - Vec vLook; - Vec vRight; - Vec vUp; - - ASSERTMSGLINE(2438, m, "MTXLookAt(): NULL MtxPtr 'm' "); - ASSERTMSGLINE(2439, camPos, "MTXLookAt(): NULL VecPtr 'camPos' "); - ASSERTMSGLINE(2440, camUp, "MTXLookAt(): NULL VecPtr 'camUp' "); - ASSERTMSGLINE(2441, target, "MTXLookAt(): NULL Point3dPtr 'target' "); - - vLook.x = camPos->x - target->x; - vLook.y = camPos->y - target->y; - vLook.z = camPos->z - target->z; - VECNormalize(&vLook, &vLook); - VECCrossProduct(camUp, &vLook, &vRight); - VECNormalize(&vRight, &vRight); - VECCrossProduct(&vLook, &vRight, &vUp); - m[0][0] = vRight.x; - m[0][1] = vRight.y; - m[0][2] = vRight.z; - m[0][3] = -((camPos->z * vRight.z) + ((camPos->x * vRight.x) + (camPos->y * vRight.y))); - m[1][0] = vUp.x; - m[1][1] = vUp.y; - m[1][2] = vUp.z; - m[1][3] = -((camPos->z * vUp.z) + ((camPos->x * vUp.x) + (camPos->y * vUp.y))); - m[2][0] = vLook.x; - m[2][1] = vLook.y; - m[2][2] = vLook.z; - m[2][3] = -((camPos->z * vLook.z) + ((camPos->x * vLook.x) + (camPos->y * vLook.y))); -} - -void C_MTXLightFrustum(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { - f32 tmp; - - ASSERTMSGLINE(2541, m, "MTXLightFrustum(): NULL MtxPtr 'm' "); - ASSERTMSGLINE(2542, (t != b), "MTXLightFrustum(): 't' and 'b' clipping planes are equal "); - ASSERTMSGLINE(2543, (l != r), "MTXLightFrustum(): 'l' and 'r' clipping planes are equal "); - - tmp = 1 / (r - l); - m[0][0] = (scaleS * (2 * n * tmp)); - m[0][1] = 0; - m[0][2] = (scaleS * (tmp * (r + l))) - transS; - m[0][3] = 0; - tmp = 1 / (t - b); - m[1][0] = 0; - m[1][1] = (scaleT * (2 * n * tmp)); - m[1][2] = (scaleT * (tmp * (t + b))) - transT; - m[1][3] = 0; - m[2][0] = 0; - m[2][1] = 0; - m[2][2] = -1; - m[2][3] = 0; -} - -void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { - f32 angle; - f32 cot; - - ASSERTMSGLINE(2605, m, "MTXLightPerspective(): NULL MtxPtr 'm' "); - ASSERTMSGLINE(2606, (fovY > 0.0) && (fovY < 180.0), "MTXLightPerspective(): 'fovY' out of range "); - ASSERTMSGLINE(2607, 0 != aspect, "MTXLightPerspective(): 'aspect' is 0 "); - - angle = (0.5f * fovY); - angle = MTXDegToRad(angle); - cot = 1 / tanf(angle); - m[0][0] = (scaleS * (cot / aspect)); - m[0][1] = 0; - m[0][2] = -transS; - m[0][3] = 0; - m[1][0] = 0; - m[1][1] = (cot * scaleT); - m[1][2] = -transT; - m[1][3] = 0; - m[2][0] = 0; - m[2][1] = 0; - m[2][2] = -1; - m[2][3] = 0; -} - -void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { - f32 tmp; - - ASSERTMSGLINE(2673, m, "MTXLightOrtho(): NULL MtxPtr 'm' "); - ASSERTMSGLINE(2674, (t != b), "MTXLightOrtho(): 't' and 'b' clipping planes are equal "); - ASSERTMSGLINE(2675, (l != r), "MTXLightOrtho(): 'l' and 'r' clipping planes are equal "); - tmp = 1 / (r - l); - m[0][0] = (2 * tmp * scaleS); - m[0][1] = 0; - m[0][2] = 0; - m[0][3] = (transS + (scaleS * (tmp * -(r + l)))); - tmp = 1/ (t - b); - m[1][0] = 0; - m[1][1] = (2 * tmp * scaleT); - m[1][2] = 0; - m[1][3] = (transT + (scaleT * (tmp * -(t + b)))); - m[2][0] = 0; - m[2][1] = 0; - m[2][2] = 0; - m[2][3] = 1; -} diff --git a/src/dolphin/mtx/mtx44.c b/src/dolphin/mtx/mtx44.c deleted file mode 100644 index 48a9712..0000000 --- a/src/dolphin/mtx/mtx44.c +++ /dev/null @@ -1,888 +0,0 @@ -#include -#include -#include "fake_tgmath.h" - -static f32 mtxUnit[] = {0.0f, 1.0f, 0.5f, 3.0f}; - -void C_MTXFrustum(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) { - f32 tmp; - - ASSERTMSGLINE(105, m, "MTXFrustum(): NULL Mtx44Ptr 'm' "); - ASSERTMSGLINE(106, t != b, "MTXFrustum(): 't' and 'b' clipping planes are equal "); - ASSERTMSGLINE(107, l != r, "MTXFrustum(): 'l' and 'r' clipping planes are equal "); - ASSERTMSGLINE(108, n != f, "MTXFrustum(): 'n' and 'f' clipping planes are equal "); - tmp = 1 / (r - l); - m[0][0] = (2 * n * tmp); - m[0][1] = 0; - m[0][2] = (tmp * (r + l)); - m[0][3] = 0; - tmp = 1 / (t - b); - m[1][0] = 0; - m[1][1] = (2 * n * tmp); - m[1][2] = (tmp * (t + b)); - m[1][3] = 0; - m[2][0] = 0; - m[2][1] = 0; - tmp = 1 / (f - n); - m[2][2] = (-n * tmp); - m[2][3] = (tmp * -(f * n)); - m[3][0] = 0; - m[3][1] = 0; - m[3][2] = -1; - m[3][3] = 0; -} - -void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f) { - f32 angle; - f32 cot; - f32 tmp; - - ASSERTMSGLINE(179, m, "MTXPerspective(): NULL Mtx44Ptr 'm' "); - ASSERTMSGLINE(180, (fovY > 0.0) && (fovY < 180.0), "MTXPerspective(): 'fovY' out of range "); - ASSERTMSGLINE(181, 0.0f != aspect, "MTXPerspective(): 'aspect' is 0 "); - - angle = (0.5f * fovY); - angle = MTXDegToRad(angle); - cot = 1 / tanf(angle); - m[0][0] = (cot / aspect); - m[0][1] = 0; - m[0][2] = 0; - m[0][3] = 0; - m[1][0] = 0; - m[1][1] = (cot); - m[1][2] = 0; - m[1][3] = 0; - m[2][0] = 0; - m[2][1] = 0; - tmp = 1 / (f - n); - m[2][2] = (-n * tmp); - m[2][3] = (tmp * -(f * n)); - m[3][0] = 0; - m[3][1] = 0; - m[3][2] = -1; - m[3][3] = 0; -} - -void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) { - f32 tmp; - - ASSERTMSGLINE(254, m, "MTXOrtho(): NULL Mtx44Ptr 'm' "); - ASSERTMSGLINE(255, t != b, "MTXOrtho(): 't' and 'b' clipping planes are equal "); - ASSERTMSGLINE(256, l != r, "MTXOrtho(): 'l' and 'r' clipping planes are equal "); - ASSERTMSGLINE(257, n != f, "MTXOrtho(): 'n' and 'f' clipping planes are equal "); - tmp = 1 / (r - l); - m[0][0] = 2 * tmp; - m[0][1] = 0; - m[0][2] = 0; - m[0][3] = (tmp * -(r + l)); - tmp = 1 / (t - b); - m[1][0] = 0; - m[1][1] = 2 * tmp; - m[1][2] = 0; - m[1][3] = (tmp * -(t + b)); - m[2][0] = 0; - m[2][1] = 0; - tmp = 1 / (f - n); - m[2][2] = (-1 * tmp); - m[2][3] = (-f * tmp); - m[3][0] = 0; - m[3][1] = 0; - m[3][2] = 0; - m[3][3] = 1; -} - -void C_MTX44Identity(Mtx44 m) { - ASSERTMSGLINE(324, m != 0, "MTX44Identity(): NULL Mtx44 'm' "); - - m[0][0] = 1.0f; - m[0][1] = 0.0f; - m[0][2] = 0.0f; - m[0][3] = 0.0f; - m[1][0] = 0.0f; - m[1][1] = 1.0f; - m[1][2] = 0.0f; - m[1][3] = 0.0f; - m[2][0] = 0.0f; - m[2][1] = 0.0f; - m[2][2] = 1.0f; - m[2][3] = 0.0f; - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = 0.0f; - m[3][3] = 1.0f; -} - -void PSMTX44Identity(register Mtx44 m) { - register f32 c1 = 1.0f; - register f32 c0 = 0.0f; - - asm { - stfs c1, 0x0(m) - psq_st c0, 0x4(m), 0, 0 - psq_st c0, 0xc(m), 0, 0 - stfs c1, 0x14(m) - psq_st c0, 0x18(m), 0, 0 - psq_st c0, 0x20(m), 0, 0 - stfs c1, 0x28(m) - psq_st c0, 0x2c(m), 0, 0 - psq_st c0, 0x34(m), 0, 0 - stfs c1, 0x3c(m) - } -} - -void C_MTX44Copy(const Mtx44 src, Mtx44 dst) { - ASSERTMSGLINE(382, src != 0, "MTX44Copy(): NULL Mtx44Ptr 'src' "); - ASSERTMSGLINE(383, dst != 0, "MTX44Copy(): NULL Mtx44Ptr 'dst' "); - - if (src != dst) { - dst[0][0] = src[0][0]; - dst[0][1] = src[0][1]; - dst[0][2] = src[0][2]; - dst[0][3] = src[0][3]; - dst[1][0] = src[1][0]; - dst[1][1] = src[1][1]; - dst[1][2] = src[1][2]; - dst[1][3] = src[1][3]; - dst[2][0] = src[2][0]; - dst[2][1] = src[2][1]; - dst[2][2] = src[2][2]; - dst[2][3] = src[2][3]; - dst[3][0] = src[3][0]; - dst[3][1] = src[3][1]; - dst[3][2] = src[3][2]; - dst[3][3] = src[3][3]; - } -} - -asm void PSMTX44Copy(const register Mtx44 src, register Mtx44 dst) { - nofralloc - psq_l f1, 0x0(src), 0, 0 - psq_st f1, 0x0(dst), 0, 0 - psq_l f1, 0x8(src), 0, 0 - psq_st f1, 0x8(dst), 0, 0 - psq_l f1, 0x10(src), 0, 0 - psq_st f1, 0x10(dst), 0, 0 - psq_l f1, 0x18(src), 0, 0 - psq_st f1, 0x18(dst), 0, 0 - psq_l f1, 0x20(src), 0, 0 - psq_st f1, 0x20(dst), 0, 0 - psq_l f1, 0x28(src), 0, 0 - psq_st f1, 0x28(dst), 0, 0 - psq_l f1, 0x30(src), 0, 0 - psq_st f1, 0x30(dst), 0, 0 - psq_l f1, 0x38(src), 0, 0 - psq_st f1, 0x38(dst), 0, 0 - blr -} - -void C_MTX44Concat(const Mtx44 a, const Mtx44 b, Mtx44 ab) { - Mtx44 mTmp; - Mtx44Ptr m; - - ASSERTMSGLINE(454, a, "MTX44Concat(): NULL Mtx44Ptr 'a' "); - ASSERTMSGLINE(455, b, "MTX44Concat(): NULL Mtx44Ptr 'b' "); - ASSERTMSGLINE(456, ab, "MTX44Concat(): NULL Mtx44Ptr 'ab' "); - - if (ab == a || ab == b) { - m = mTmp; - } else { - m = ab; - } - - m[0][0] = (a[0][0] * b[0][0]) + (a[0][1] * b[1][0]) + (a[0][2] * b[2][0]) + (a[0][3] * b[3][0]); - m[0][1] = (a[0][0] * b[0][1]) + (a[0][1] * b[1][1]) + (a[0][2] * b[2][1]) + (a[0][3] * b[3][1]); - m[0][2] = (a[0][0] * b[0][2]) + (a[0][1] * b[1][2]) + (a[0][2] * b[2][2]) + (a[0][3] * b[3][2]); - m[0][3] = (a[0][0] * b[0][3]) + (a[0][1] * b[1][3]) + (a[0][2] * b[2][3]) + (a[0][3] * b[3][3]); - - m[1][0] = (a[1][0] * b[0][0]) + (a[1][1] * b[1][0]) + (a[1][2] * b[2][0]) + (a[1][3] * b[3][0]); - m[1][1] = (a[1][0] * b[0][1]) + (a[1][1] * b[1][1]) + (a[1][2] * b[2][1]) + (a[1][3] * b[3][1]); - m[1][2] = (a[1][0] * b[0][2]) + (a[1][1] * b[1][2]) + (a[1][2] * b[2][2]) + (a[1][3] * b[3][2]); - m[1][3] = (a[1][0] * b[0][3]) + (a[1][1] * b[1][3]) + (a[1][2] * b[2][3]) + (a[1][3] * b[3][3]); - - m[2][0] = (a[2][0] * b[0][0]) + (a[2][1] * b[1][0]) + (a[2][2] * b[2][0]) + (a[2][3] * b[3][0]); - m[2][1] = (a[2][0] * b[0][1]) + (a[2][1] * b[1][1]) + (a[2][2] * b[2][1]) + (a[2][3] * b[3][1]); - m[2][2] = (a[2][0] * b[0][2]) + (a[2][1] * b[1][2]) + (a[2][2] * b[2][2]) + (a[2][3] * b[3][2]); - m[2][3] = (a[2][0] * b[0][3]) + (a[2][1] * b[1][3]) + (a[2][2] * b[2][3]) + (a[2][3] * b[3][3]); - - m[3][0] = (a[3][0] * b[0][0]) + (a[3][1] * b[1][0]) + (a[3][2] * b[2][0]) + (a[3][3] * b[3][0]); - m[3][1] = (a[3][0] * b[0][1]) + (a[3][1] * b[1][1]) + (a[3][2] * b[2][1]) + (a[3][3] * b[3][1]); - m[3][2] = (a[3][0] * b[0][2]) + (a[3][1] * b[1][2]) + (a[3][2] * b[2][2]) + (a[3][3] * b[3][2]); - m[3][3] = (a[3][0] * b[0][3]) + (a[3][1] * b[1][3]) + (a[3][2] * b[2][3]) + (a[3][3] * b[3][3]); - - if (m == mTmp) { - C_MTX44Copy(mTmp, ab); - } -} - -asm void PSMTX44Concat(const register Mtx44 a, const register Mtx44 b, register Mtx44 ab) { - nofralloc - psq_l f0, 0x0(a), 0, 0 - psq_l f2, 0x0(b), 0, 0 - ps_muls0 f6, f2, f0 - psq_l f3, 0x10(b), 0, 0 - psq_l f4, 0x20(b), 0, 0 - ps_madds1 f6, f3, f0, f6 - psq_l f1, 0x8(a), 0, 0 - psq_l f5, 0x30(b), 0, 0 - ps_madds0 f6, f4, f1, f6 - psq_l f0, 0x10(a), 0, 0 - ps_madds1 f6, f5, f1, f6 - psq_l f1, 0x18(a), 0, 0 - ps_muls0 f8, f2, f0 - ps_madds1 f8, f3, f0, f8 - psq_l f0, 0x20(a), 0, 0 - ps_madds0 f8, f4, f1, f8 - ps_madds1 f8, f5, f1, f8 - psq_l f1, 0x28(a), 0, 0 - ps_muls0 f10, f2, f0 - ps_madds1 f10, f3, f0, f10 - psq_l f0, 0x30(a), 0, 0 - ps_madds0 f10, f4, f1, f10 - ps_madds1 f10, f5, f1, f10 - psq_l f1, 0x38(a), 0, 0 - ps_muls0 f12, f2, f0 - psq_l f2, 0x8(b), 0, 0 - ps_madds1 f12, f3, f0, f12 - psq_l f0, 0x0(a), 0, 0 - ps_madds0 f12, f4, f1, f12 - psq_l f3, 0x18(b), 0, 0 - ps_madds1 f12, f5, f1, f12 - psq_l f1, 0x8(a), 0, 0 - ps_muls0 f7, f2, f0 - psq_l f4, 0x28(b), 0, 0 - ps_madds1 f7, f3, f0, f7 - psq_l f5, 0x38(b), 0, 0 - ps_madds0 f7, f4, f1, f7 - psq_l f0, 0x10(a), 0, 0 - ps_madds1 f7, f5, f1, f7 - psq_l f1, 0x18(a), 0, 0 - ps_muls0 f9, f2, f0 - psq_st f6, 0x0(ab), 0, 0 - ps_madds1 f9, f3, f0, f9 - psq_l f0, 0x20(a), 0, 0 - ps_madds0 f9, f4, f1, f9 - psq_st f8, 0x10(ab), 0, 0 - ps_madds1 f9, f5, f1, f9 - psq_l f1, 0x28(a), 0, 0 - ps_muls0 f11, f2, f0 - psq_st f10, 0x20(ab), 0, 0 - ps_madds1 f11, f3, f0, f11 - psq_l f0, 0x30(a), 0, 0 - ps_madds0 f11, f4, f1, f11 - psq_st f12, 0x30(ab), 0, 0 - ps_madds1 f11, f5, f1, f11 - psq_l f1, 0x38(a), 0, 0 - ps_muls0 f13, f2, f0 - psq_st f7, 0x8(ab), 0, 0 - ps_madds1 f13, f3, f0, f13 - psq_st f9, 0x18(ab), 0, 0 - ps_madds0 f13, f4, f1, f13 - psq_st f11, 0x28(ab), 0, 0 - ps_madds1 f13, f5, f1, f13 - psq_st f13, 0x38(ab), 0, 0 - blr -} - -void C_MTX44Transpose(const Mtx44 src, Mtx44 xPose) { - Mtx44 mTmp; - Mtx44Ptr m; - - ASSERTMSGLINE(637, src, "MTX44Transpose(): NULL Mtx44Ptr 'src' "); - ASSERTMSGLINE(638, xPose, "MTX44Transpose(): NULL Mtx44Ptr 'xPose' "); - - if (src == xPose) { - m = mTmp; - } else { - m = xPose; - } - - m[0][0] = src[0][0]; - m[0][1] = src[1][0]; - m[0][2] = src[2][0]; - m[0][3] = src[3][0]; - m[1][0] = src[0][1]; - m[1][1] = src[1][1]; - m[1][2] = src[2][1]; - m[1][3] = src[3][1]; - m[2][0] = src[0][2]; - m[2][1] = src[1][2]; - m[2][2] = src[2][2]; - m[2][3] = src[3][2]; - m[3][0] = src[0][3]; - m[3][1] = src[1][3]; - m[3][2] = src[2][3]; - m[3][3] = src[3][3]; - - if (m == mTmp) { - MTX44Copy(mTmp, xPose); - } -} - -asm void PSMTX44Transpose(const register Mtx44 src, register Mtx44 xPose) { - nofralloc - psq_l f0, 0x0(src), 0, 0 - psq_l f1, 0x10(src), 0, 0 - ps_merge00 f4, f0, f1 - psq_l f2, 0x8(src), 0, 0 - psq_st f4, 0x0(xPose), 0, 0 - ps_merge11 f5, f0, f1 - psq_l f3, 0x18(src), 0, 0 - psq_st f5, 0x10(xPose), 0, 0 - ps_merge00 f4, f2, f3 - psq_l f0, 0x20(src), 0, 0 - psq_st f4, 0x20(xPose), 0, 0 - ps_merge11 f5, f2, f3 - psq_l f1, 0x30(src), 0, 0 - psq_st f5, 0x30(xPose), 0, 0 - ps_merge00 f4, f0, f1 - psq_l f2, 0x28(src), 0, 0 - psq_st f4, 0x8(xPose), 0, 0 - ps_merge11 f5, f0, f1 - psq_l f3, 0x38(src), 0, 0 - psq_st f5, 0x18(xPose), 0, 0 - ps_merge00 f4, f2, f3 - psq_st f4, 0x28(xPose), 0, 0 - ps_merge11 f5, f2, f3 - psq_st f5, 0x38(xPose), 0, 0 - blr -} - -#define SWAP(a, b) \ - { \ - f32 tmp; \ - tmp = a; \ - a = b; \ - b = tmp; \ - } - -u32 C_MTX44Inverse(const Mtx44 src, Mtx44 inv) { - Mtx44 gjm; - s32 i; - s32 j; - s32 k; - f32 w; - f32 max; - s32 swp; - f32 ftmp; - - ASSERTMSGLINE(734, src, "MTX44Inverse(): NULL Mtx44Ptr 'src' "); - ASSERTMSGLINE(735, inv, "MTX44Inverse(): NULL Mtx44Ptr 'inv' "); - - MTX44Copy(src, gjm); - MTX44Identity(inv); - - for (i = 0; i < 4; i++) { - max = 0.0f; - swp = i; - - for (k = i; k < 4; k++) { - ftmp = fabsf(gjm[k][i]); - if (ftmp > max) { - max = ftmp; - swp = k; - } - } - - if (max == 0.0f) { - return 0; - } - - if (swp != i) { - for (k = 0; k < 4; k++) { - SWAP(gjm[i][k], gjm[swp][k]); - SWAP(inv[i][k], inv[swp][k]); - } - } - - w = 1.0f / gjm[i][i]; - for (j = 0; j < 4; j++) { - gjm[i][j] *= w; - inv[i][j] *= w; - } - - for (k = 0; k < 4; k++) { - if (k != i) { - w = gjm[k][i]; - for (j = 0; j < 4; j++) { - gjm[k][j] -= gjm[i][j] * w; - inv[k][j] -= inv[i][j] * w; - } - } - } - } - - return 1; -} - -void C_MTX44Trans(Mtx44 m, f32 xT, f32 yT, f32 zT) { - ASSERTMSGLINE(835, m, "MTX44Trans(): NULL Mtx44Ptr 'm' "); - - m[0][0] = 1.0f; - m[0][1] = 0.0f; - m[0][2] = 0.0f; - m[0][3] = xT; - - m[1][0] = 0.0f; - m[1][1] = 1.0f; - m[1][2] = 0.0f; - m[1][3] = yT; - - m[2][0] = 0.0f; - m[2][1] = 0.0f; - m[2][2] = 1.0f; - m[2][3] = zT; - - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = 0.0f; - m[3][3] = 1.0f; -} - -void PSMTX44Trans(register Mtx44 m, register f32 xT, register f32 yT, register f32 zT) { - register f32 c_zero = 0.0f; - register f32 c_one = 1.0f; - register f32 c_01; - - asm { - stfs xT, 0xc(m) - stfs yT, 0x1c(m) - ps_merge00 c_01, c_zero, c_one - stfs zT, 0x2c(m) - psq_st c_one, 0x0(m), 1, 0 - psq_st c_zero, 0x4(m), 0, 0 - psq_st c_01, 0x10(m), 0, 0 - psq_st c_zero, 0x18(m), 1, 0 - psq_st c_zero, 0x20(m), 0, 0 - psq_st c_one, 0x28(m), 1, 0 - psq_st c_zero, 0x30(m), 0, 0 - psq_st c_01, 0x38(m), 0, 0 - } -} - -void C_MTX44TransApply(const Mtx44 src, Mtx44 dst, f32 xT, f32 yT, f32 zT) { - ASSERTMSGLINE(899, src, "MTX44TransApply(): NULL Mtx44Ptr 'src' "); - ASSERTMSGLINE(900, dst, "MTX44TransApply(): NULL Mtx44Ptr 'src' "); //! wrong assert string - - if (src != dst) { - dst[0][0] = src[0][0]; - dst[0][1] = src[0][1]; - dst[0][2] = src[0][2]; - - dst[1][0] = src[1][0]; - dst[1][1] = src[1][1]; - dst[1][2] = src[1][2]; - - dst[2][0] = src[2][0]; - dst[2][1] = src[2][1]; - dst[2][2] = src[2][2]; - - dst[3][0] = src[3][0]; - dst[3][1] = src[3][1]; - dst[3][2] = src[3][2]; - - dst[3][3] = src[3][3]; - } - - dst[0][3] = (src[0][3] + xT); - dst[1][3] = (src[1][3] + yT); - dst[2][3] = (src[2][3] + zT); -} - -asm void PSMTX44TransApply(const register Mtx44 src, register Mtx44 dst, register f32 xT, register f32 yT, register f32 zT) { - nofralloc - psq_l f4, 0x0(src), 0, 0 - frsp xT, xT - psq_l f5, 0x8(src), 0, 0 - frsp yT, yT - psq_l f6, 0x10(src), 0, 0 - frsp zT, zT - psq_l f7, 0x18(src), 0, 0 - psq_st f4, 0x0(dst), 0, 0 - ps_sum1 f5, xT, f5, f5 - psq_l f4, 0x28(src), 0, 0 - psq_st f6, 0x10(dst), 0, 0 - ps_sum1 f7, yT, f7, f7 - psq_l f8, 0x20(src), 0, 0 - psq_st f5, 0x8(dst), 0, 0 - ps_sum1 f4, zT, f4, f4 - psq_st f7, 0x18(dst), 0, 0 - psq_st f8, 0x20(dst), 0, 0 - psq_l f5, 0x30(src), 0, 0 - psq_l f6, 0x38(src), 0, 0 - psq_st f4, 0x28(dst), 0, 0 - psq_st f5, 0x30(dst), 0, 0 - psq_st f6, 0x38(dst), 0, 0 - blr -} - -void C_MTX44Scale(Mtx44 m, f32 xS, f32 yS, f32 zS) { - ASSERTMSGLINE(976, m, "MTX44Scale(): NULL Mtx44Ptr 'm' "); - m[0][0] = xS; - m[0][1] = 0.0f; - m[0][2] = 0.0f; - m[0][3] = 0.0f; - - m[1][0] = 0.0f; - m[1][1] = yS; - m[1][2] = 0.0f; - m[1][3] = 0.0f; - - m[2][0] = 0.0f; - m[2][1] = 0.0f; - m[2][2] = zS; - m[2][3] = 0.0f; - - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = 0.0f; - m[3][3] = 1.0f; -} - -void PSMTX44Scale(register Mtx44 m, register f32 xS, register f32 yS, register f32 zS) { - register f32 c_zero = 0.0f; - register f32 c_one = 1.0f; - - asm { - stfs xS, 0x0(m) - psq_st c_zero, 0x4(m), 0, 0 - psq_st c_zero, 0xc(m), 0, 0 - stfs yS, 0x14(m) - psq_st c_zero, 0x18(m), 0, 0 - psq_st c_zero, 0x20(m), 0, 0 - stfs zS, 0x28(m) - psq_st c_zero, 0x2c(m), 0, 0 - psq_st c_zero, 0x34(m), 0, 0 - stfs c_one, 0x3c(m) - } -} - -void C_MTX44ScaleApply(const Mtx44 src, Mtx44 dst, f32 xS, f32 yS, f32 zS) { - ASSERTMSGLINE(1036, src, "MTX44ScaleApply(): NULL Mtx44Ptr 'src' "); - ASSERTMSGLINE(1037, dst, "MTX44ScaleApply(): NULL Mtx44Ptr 'dst' "); - - dst[0][0] = (src[0][0] * xS); - dst[0][1] = (src[0][1] * xS); - dst[0][2] = (src[0][2] * xS); - dst[0][3] = (src[0][3] * xS); - - dst[1][0] = (src[1][0] * yS); - dst[1][1] = (src[1][1] * yS); - dst[1][2] = (src[1][2] * yS); - dst[1][3] = (src[1][3] * yS); - - dst[2][0] = (src[2][0] * zS); - dst[2][1] = (src[2][1] * zS); - dst[2][2] = (src[2][2] * zS); - dst[2][3] = (src[2][3] * zS); - - dst[3][0] = src[3][0]; - dst[3][1] = src[3][1]; - dst[3][2] = src[3][2]; - dst[3][3] = src[3][3]; -} - -asm void PSMTX44ScaleApply(const register Mtx44 src, register Mtx44 dst, register f32 xS, register f32 yS, register f32 zS) { - nofralloc - psq_l f4, 0x0(src), 0, 0 - frsp xS, xS - psq_l f5, 0x8(src), 0, 0 - frsp yS, yS - psq_l f6, 0x10(src), 0, 0 - ps_muls0 f4, f4, xS - psq_l f7, 0x18(src), 0, 0 - ps_muls0 f5, f5, xS - psq_l f8, 0x20(src), 0, 0 - frsp zS, zS - psq_st f4, 0x0(dst), 0, 0 - ps_muls0 f6, f6, yS - psq_l f9, 0x28(src), 0, 0 - psq_st f5, 0x8(dst), 0, 0 - ps_muls0 f7, f7, yS - psq_l f10, 0x30(src), 0, 0 - psq_st f6, 0x10(dst), 0, 0 - ps_muls0 f8, f8, zS - psq_l f11, 0x38(src), 0, 0 - psq_st f7, 0x18(dst), 0, 0 - ps_muls0 f9, f9, zS - psq_st f8, 0x20(dst), 0, 0 - psq_st f9, 0x28(dst), 0, 0 - psq_st f10, 0x30(dst), 0, 0 - psq_st f11, 0x38(dst), 0, 0 - blr -} - -void C_MTX44RotRad(Mtx44 m, char axis, f32 rad) { - f32 sinA; - f32 cosA; - - ASSERTMSGLINE(1118, m, "MTX44RotRad(): NULL Mtx44Ptr 'm' "); - sinA = sinf(rad); - cosA = cosf(rad); - C_MTX44RotTrig(m, axis, sinA, cosA); -} - -void PSMTX44RotRad(Mtx44 m, char axis, f32 rad) { - f32 sinA; - f32 cosA; - - sinA = sinf(rad); - cosA = cosf(rad); - PSMTX44RotTrig(m, axis, sinA, cosA); -} - -void C_MTX44RotTrig(Mtx44 m, char axis, f32 sinA, f32 cosA) { - ASSERTMSGLINE(1163, m, "MTX44RotTrig(): NULL Mtx44Ptr 'm' "); - - axis |= 0x20; - switch(axis) { - case 'x': - m[0][0] = 1.0f; - m[0][1] = 0.0f; - m[0][2] = 0.0f; - m[0][3] = 0.0f; - m[1][0] = 0.0f; - m[1][1] = cosA; - m[1][2] = -sinA; - m[1][3] = 0.0f; - m[2][0] = 0.0f; - m[2][1] = sinA; - m[2][2] = cosA; - m[2][3] = 0.0f; - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = 0.0f; - m[3][3] = 1.0f; - break; - case 'y': - m[0][0] = cosA; - m[0][1] = 0.0f; - m[0][2] = sinA; - m[0][3] = 0.0f; - m[1][0] = 0.0f; - m[1][1] = 1.0f; - m[1][2] = 0.0f; - m[1][3] = 0.0f; - m[2][0] = -sinA; - m[2][1] = 0.0f; - m[2][2] = cosA; - m[2][3] = 0.0f; - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = 0.0f; - m[3][3] = 1.0f; - break; - case 'z': - m[0][0] = cosA; - m[0][1] = -sinA; - m[0][2] = 0.0f; - m[0][3] = 0.0f; - m[1][0] = sinA; - m[1][1] = cosA; - m[1][2] = 0.0f; - m[1][3] = 0.0f; - m[2][0] = 0.0f; - m[2][1] = 0.0f; - m[2][2] = 1.0f; - m[2][3] = 0.0f; - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = 0.0f; - m[3][3] = 1.0f; - break; - default: - ASSERTMSGLINE(1191, FALSE, "MTX44RotTrig(): invalid 'axis' value "); - break; - } -} - -void PSMTX44RotTrig(register Mtx44 m, register char axis, register f32 sinA, register f32 cosA) { - register f32 ftmp0; - register f32 ftmp1; - register f32 ftmp2; - register f32 ftmp3; - register f32 ftmp4; - - register f32 c_zero = 0.0f; - register f32 c_one = 1.0f; - - asm { - frsp sinA, sinA - ori axis, axis, 0x20 - frsp cosA, cosA - cmplwi axis, 'x' - beq L_00001AB4 - cmplwi axis, 'y' - beq L_00001AE8 - cmplwi axis, 'z' - beq L_00001B20 - b L_00001B54 - L_00001AB4: - psq_st c_one, 0x0(m), 1, 0 - psq_st c_zero, 0x4(m), 0, 0 - ps_neg ftmp0, sinA - psq_st c_zero, 0xc(m), 0, 0 - ps_merge00 ftmp1, sinA, cosA - psq_st c_zero, 0x1c(m), 0, 0 - ps_merge00 ftmp0, cosA, ftmp0 - psq_st c_zero, 0x2c(m), 0, 0 - psq_st c_zero, 0x34(m), 0, 0 - psq_st ftmp1, 0x24(m), 0, 0 - psq_st ftmp0, 0x14(m), 0, 0 - psq_st c_one, 0x3c(m), 1, 0 - b L_00001B54 - L_00001AE8: - ps_merge00 ftmp1, cosA, c_zero - psq_st c_zero, 0x30(m), 0, 0 - ps_neg ftmp0, sinA - psq_st c_zero, 0x18(m), 0, 0 - ps_merge00 ftmp3, c_zero, c_one - psq_st ftmp1, 0x0(m), 0, 0 - ps_merge00 ftmp4, ftmp0, c_zero - ps_merge00 ftmp2, sinA, c_zero - psq_st ftmp3, 0x10(m), 0, 0 - psq_st ftmp2, 0x8(m), 0, 0 - psq_st ftmp4, 0x20(m), 0, 0 - psq_st ftmp1, 0x28(m), 0, 0 - psq_st ftmp3, 0x38(m), 0, 0 - b L_00001B54 - L_00001B20: - psq_st c_zero, 0x8(m), 0, 0 - ps_neg ftmp0, sinA - psq_st c_zero, 0x18(m), 0, 0 - ps_merge00 ftmp1, sinA, cosA - psq_st c_zero, 0x20(m), 0, 0 - ps_merge00 ftmp2, c_one, c_zero - psq_st c_zero, 0x30(m), 0, 0 - ps_merge00 ftmp3, c_zero, c_one - psq_st ftmp1, 0x10(m), 0, 0 - ps_merge00 ftmp4, cosA, ftmp0 - psq_st ftmp2, 0x28(m), 0, 0 - psq_st ftmp3, 0x38(m), 0, 0 - psq_st ftmp4, 0x0(m), 0, 0 - L_00001B54: - } -} - -void C_MTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad) { - Vec vN; - f32 s; - f32 c; - f32 t; - f32 x; - f32 y; - f32 z; - f32 xSq; - f32 ySq; - f32 zSq; - - ASSERTMSGLINE(1300, m, "MTX44RotAxisRad(): NULL Mtx44Ptr 'm' "); - ASSERTMSGLINE(1301, axis, "MTX44RotAxisRad(): NULL VecPtr 'axis' "); - - s = sinf(rad); - c = cosf(rad); - t = 1 - c; - - C_VECNormalize(axis, &vN); - - x = vN.x; - y = vN.y; - z = vN.z; - - xSq = (x * x); - ySq = (y * y); - zSq = (z * z); - - m[0][0] = (c + (t * xSq)); - m[0][1] = (y * (t * x)) - (s * z); - m[0][2] = (z * (t * x)) + (s * y); - m[0][3] = 0.0f; - - m[1][0] = ((y * (t * x)) + (s * z)); - m[1][1] = (c + (t * ySq)); - m[1][2] = ((z * (t * y)) - (s * x)); - m[1][3] = 0.0f; - - m[2][0] = ((z * (t * x)) - (s * y)); - m[2][1] = ((z * (t * y)) + (s * x)); - m[2][2] = (c + (t * zSq)); - m[2][3] = 0.0f; - - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = 0.0f; - m[3][3] = 1.0f; -} - -static void __PSMTX44RotAxisRadInternal(register Mtx44 m, const register Vec* axis, register f32 sT, register f32 cT) { - register f32 tT; - register f32 fc0; - register f32 tmp0; - register f32 tmp1; - register f32 tmp2; - register f32 tmp3; - register f32 tmp4; - register f32 tmp5; - register f32 tmp6; - register f32 tmp7; - register f32 tmp8; - register f32 tmp9; - - tmp9 = 0.5f; - tmp8 = 3.0f; - - asm { - frsp cT, cT - psq_l tmp0, 0x0(axis), 0, 0 - frsp sT, sT - lfs tmp1, 0x8(axis) - ps_mul tmp2, tmp0, tmp0 - fadds tmp7, tmp9, tmp9 - ps_madd tmp3, tmp1, tmp1, tmp2 - fsubs fc0, tmp9, tmp9 - ps_sum0 tmp4, tmp3, tmp1, tmp2 - fsubs tT, tmp7, cT - frsqrte tmp5, tmp4 - ps_merge00 tmp7, fc0, tmp7 - fmuls tmp2, tmp5, tmp5 - fmuls tmp3, tmp5, tmp9 - psq_st fc0, 0x30(m), 0, 0 - fnmsubs tmp2, tmp2, tmp4, tmp8 - fmuls tmp5, tmp2, tmp3 - psq_st tmp7, 0x38(m), 0, 0 - ps_merge00 cT, cT, cT - ps_muls0 tmp0, tmp0, tmp5 - ps_muls0 tmp1, tmp1, tmp5 - ps_muls0 tmp4, tmp0, tT - ps_muls0 tmp9, tmp0, sT - ps_muls0 tmp5, tmp1, tT - ps_muls1 tmp3, tmp4, tmp0 - ps_muls0 tmp2, tmp4, tmp0 - ps_muls0 tmp4, tmp4, tmp1 - fnmsubs tmp6, tmp1, sT, tmp3 - fmadds tmp7, tmp1, sT, tmp3 - ps_neg tmp0, tmp9 - ps_sum0 tmp8, tmp4, fc0, tmp9 - ps_sum0 tmp2, tmp2, tmp6, cT - ps_sum1 tmp3, cT, tmp7, tmp3 - ps_sum0 tmp6, tmp0, fc0, tmp4 - psq_st tmp8, 0x8(m), 0, 0 - ps_sum0 tmp0, tmp4, tmp4, tmp0 - psq_st tmp2, 0x0(m), 0, 0 - ps_muls0 tmp5, tmp5, tmp1 - psq_st tmp3, 0x10(m), 0, 0 - ps_sum1 tmp4, tmp9, tmp0, tmp4 - psq_st tmp6, 0x18(m), 0, 0 - ps_sum0 tmp5, tmp5, fc0, cT - psq_st tmp4, 0x20(m), 0, 0 - psq_st tmp5, 0x28(m), 0, 0 - } -} - -void PSMTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad) { - f32 sinT, cosT; - - sinT = sinf(rad); - cosT = cosf(rad); - - __PSMTX44RotAxisRadInternal(m, axis, sinT, cosT); -} diff --git a/src/dolphin/mtx/mtx44vec.c b/src/dolphin/mtx/mtx44vec.c deleted file mode 100644 index 478c49f..0000000 --- a/src/dolphin/mtx/mtx44vec.c +++ /dev/null @@ -1,247 +0,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++; - } -} - -asm void PSMTX44MultVecArray(const register Mtx44 m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { - nofralloc - stwu r1, -0x10(r1) - subi count, count, 0x1 - psq_l f6, 0x30(m), 0, 0 - mtctr count - psq_l f8, 0x0(srcBase), 0, 0 - subi dstBase, dstBase, 0x4 - psq_l f7, 0x38(m), 0, 0 - psq_lu f9, 0x8(srcBase), 1, 0 - ps_mul f13, f6, f8 - psq_l f0, 0x0(m), 0, 0 - stfd f14, 0x8(r1) - ps_madd f13, f7, f9, f13 - psq_l f2, 0x10(m), 0, 0 - ps_merge11 f14, f9, f9 - ps_mul f10, f0, f8 - psq_l f4, 0x20(m), 0, 0 - ps_mul f11, f2, f8 - psq_l f1, 0x8(m), 0, 0 - ps_mul f12, f4, f8 - psq_l f3, 0x18(m), 0, 0 - ps_sum0 f13, f13, f13, f13 - psq_l f5, 0x28(m), 0, 0 -L_00000468: - ps_madd f10, f1, f9, f10 - ps_madd f11, f3, f9, f11 - ps_madd f12, f5, f9, f12 - ps_sum0 f10, f10, f10, f10 - ps_sum0 f11, f11, f11, f11 - ps_sum0 f12, f12, f12, f12 - ps_div f13, f14, f13 - psq_lu f8, 0x4(srcBase), 0, 0 - psq_lu f9, 0x8(srcBase), 1, 0 - ps_mul f10, f10, f13 - psq_stu f10, 0x4(dstBase), 1, 0 - ps_mul f11, f11, f13 - psq_stu f11, 0x4(dstBase), 1, 0 - ps_mul f12, f12, f13 - psq_stu f12, 0x4(dstBase), 1, 0 - ps_mul f13, f6, f8 - ps_mul f10, f0, f8 - ps_mul f11, f2, f8 - ps_madd f13, f7, f9, f13 - ps_mul f12, f4, f8 - ps_sum0 f13, f13, f13, f13 - bdnz L_00000468 - ps_madd f10, f1, f9, f10 - ps_madd f11, f3, f9, f11 - ps_madd f12, f5, f9, f12 - ps_sum0 f10, f10, f10, f10 - ps_sum0 f11, f11, f11, f11 - ps_sum0 f12, f12, f12, f12 - ps_div f13, f14, f13 - ps_mul f10, f10, f13 - psq_st f10, 0x4(dstBase), 1, 0 - ps_mul f11, f11, f13 - psq_st f11, 0x8(dstBase), 1, 0 - ps_mul f12, f12, f13 - psq_st f12, 0xc(dstBase), 1, 0 - lfd f14, 0x8(r1) - addi r1, r1, 0x10 - blr -} - -void C_MTX44MultVecSR(const Mtx44 m, const Vec* src, Vec* dst) { - Vec vTmp; - - ASSERTMSGLINE(288, m, "MTX44MultVecSR(): NULL Mtx44Ptr 'm' "); - ASSERTMSGLINE(289, src, "MTX44MultVecSR(): NULL VecPtr 'src' "); - ASSERTMSGLINE(290, dst, "MTX44MultVecSR(): NULL VecPtr 'dst' "); - vTmp.x = (m[0][2] * src->z) + ((m[0][0] * src->x) + (m[0][1] * src->y)); - vTmp.y = (m[1][2] * src->z) + ((m[1][0] * src->x) + (m[1][1] * src->y)); - vTmp.z = (m[2][2] * src->z) + ((m[2][0] * src->x) + (m[2][1] * src->y)); - dst->x = vTmp.x; - dst->y = vTmp.y; - dst->z = vTmp.z; -} - -asm void PSMTX44MultVecSR(const register Mtx m, const register Vec* src, register Vec* dst) { - nofralloc - psq_l f0, 0x0(m), 0, 0 - psq_l f6, 0x0(src), 0, 0 - psq_l f2, 0x10(m), 0, 0 - ps_mul f8, f0, f6 - psq_l f4, 0x20(m), 0, 0 - ps_mul f10, f2, f6 - psq_l f7, 0x8(src), 1, 0 - ps_mul f12, f4, f6 - psq_l f3, 0x18(m), 0, 0 - ps_sum0 f8, f8, f8, f8 - psq_l f5, 0x28(m), 0, 0 - ps_sum0 f10, f10, f10, f10 - psq_l f1, 0x8(m), 0, 0 - ps_sum0 f12, f12, f12, f12 - ps_madd f9, f1, f7, f8 - psq_st f9, 0x0(dst), 1, 0 - ps_madd f11, f3, f7, f10 - psq_st f11, 0x4(dst), 1, 0 - ps_madd f13, f5, f7, f12 - psq_st f13, 0x8(dst), 1, 0 - blr -} - -void C_MTX44MultVecArraySR(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count) { - u32 i; - Vec vTmp; - - ASSERTMSGLINE(379, m, "MTX44MultVecArraySR(): NULL Mtx44Ptr 'm' "); - ASSERTMSGLINE(380, srcBase, "MTX44MultVecArraySR(): NULL VecPtr 'srcBase' "); - ASSERTMSGLINE(381, dstBase, "MTX44MultVecArraySR(): NULL VecPtr 'dstBase' "); - - for(i = 0; i < count; i++) { - vTmp.x = (m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y)); - vTmp.y = (m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y)); - vTmp.z = (m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y)); - dstBase->x = vTmp.x; - dstBase->y = vTmp.y; - dstBase->z = vTmp.z; - srcBase++; - dstBase++; - } -} - -asm void PSMTX44MultVecArraySR(const register Mtx44 m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { - nofralloc - psq_l f0, 0x0(m), 0, 0 - subi count, count, 0x1 - psq_l f6, 0x0(srcBase), 0, 0 - ps_mul f8, f0, f6 - psq_l f2, 0x10(m), 0, 0 - ps_mul f9, f2, f6 - psq_l f4, 0x20(m), 0, 0 - psq_lu f7, 0x8(srcBase), 1, 0 - ps_mul f10, f4, f6 - psq_l f1, 0x8(m), 1, 0 - mtctr count - psq_l f3, 0x18(m), 1, 0 - subi dstBase, dstBase, 0x4 - psq_l f5, 0x28(m), 1, 0 -L_00000890: - ps_madd f11, f1, f7, f8 - psq_lu f6, 0x4(srcBase), 0, 0 - ps_madd f12, f3, f7, f9 - ps_madd f13, f5, f7, f10 - psq_lu f7, 0x8(srcBase), 1, 0 - ps_sum0 f11, f11, f8, f8 - psq_stu f11, 0x4(dstBase), 1, 0 - ps_sum0 f12, f12, f9, f9 - psq_stu f12, 0x4(dstBase), 1, 0 - ps_sum0 f13, f13, f10, f10 - psq_stu f13, 0x4(dstBase), 1, 0 - ps_mul f8, f0, f6 - ps_mul f9, f2, f6 - ps_mul f10, f4, f6 - bdnz L_00000890 - ps_madd f11, f1, f7, f8 - ps_madd f12, f3, f7, f9 - ps_madd f13, f5, f7, f10 - ps_sum0 f11, f11, f8, f8 - psq_stu f11, 0x4(dstBase), 1, 0 - ps_sum0 f12, f12, f9, f9 - psq_stu f12, 0x4(dstBase), 1, 0 - ps_sum0 f13, f13, f10, f10 - psq_stu f13, 0x4(dstBase), 1, 0 - blr -} diff --git a/src/dolphin/mtx/mtxstack.c b/src/dolphin/mtx/mtxstack.c deleted file mode 100644 index 475175c..0000000 --- a/src/dolphin/mtx/mtxstack.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include "fake_tgmath.h" - -void MTXInitStack(MTXStack* sPtr, u32 numMtx) { - ASSERTMSGLINE(74, sPtr, "MTXInitStack(): NULL MtxStackPtr 'sPtr' "); - ASSERTMSGLINE(75, sPtr->stackBase, "MTXInitStack(): 'sPtr' contains a NULL ptr to stack memory "); - ASSERTMSGLINE(76, numMtx, "MTXInitStack(): 'numMtx' is 0 "); - - sPtr->numMtx = numMtx; - sPtr->stackPtr = 0; -} - -MtxPtr MTXPush(MTXStack* sPtr, const Mtx m) { - ASSERTMSGLINE(104, sPtr, "MTXPush(): NULL MtxStackPtr 'sPtr' "); - ASSERTMSGLINE(105, sPtr->stackBase, "MTXPush(): 'sPtr' contains a NULL ptr to stack memory "); - ASSERTMSGLINE(106, m, "MTXPush(): NULL MtxPtr 'm' "); - - if (sPtr->stackPtr == NULL) { - sPtr->stackPtr = sPtr->stackBase; - MTXCopy(m, sPtr->stackPtr); - } else { - ASSERTMSGLINE(121, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPush(): stack overflow "); - MTXCopy(m, sPtr->stackPtr + 3); - sPtr->stackPtr += 3; - } - - return sPtr->stackPtr; -} - -MtxPtr MTXPushFwd(MTXStack* sPtr, const Mtx m) { - ASSERTMSGLINE(157, sPtr, "MTXPushFwd(): NULL MtxStackPtr 'sPtr' "); - ASSERTMSGLINE(158, sPtr->stackBase, "MTXPushFwd(): 'sPtr' contains a NULL ptr to stack memory "); - ASSERTMSGLINE(159, m, "MTXPushFwd(): NULL MtxPtr 'm' "); - - if (sPtr->stackPtr == NULL) { - sPtr->stackPtr = sPtr->stackBase; - MTXCopy(m, sPtr->stackPtr); - } else { - ASSERTMSGLINE(174, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushFwd(): stack overflow"); - MTXConcat(sPtr->stackPtr, m, sPtr->stackPtr + 3); - sPtr->stackPtr += 3; - } - - return sPtr->stackPtr; -} - -MtxPtr MTXPushInv(MTXStack* sPtr, const Mtx m) { - Mtx mInv; - ASSERTMSGLINE(216, sPtr, "MTXPushInv(): NULL MtxStackPtr 'sPtr' "); - ASSERTMSGLINE(217, sPtr->stackBase, "MTXPushInv(): 'sPtr' contains a NULL ptr to stack memory "); - ASSERTMSGLINE(218, m, "MTXPushInv(): NULL MtxPtr 'm' "); - - MTXInverse(m, mInv); - if (sPtr->stackPtr == NULL) { - sPtr->stackPtr = sPtr->stackBase; - MTXCopy(mInv, sPtr->stackPtr); - } else { - ASSERTMSGLINE(236, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushInv(): stack overflow"); - MTXConcat(mInv, sPtr->stackPtr, sPtr->stackPtr + 3); - sPtr->stackPtr += 3; - } - - return sPtr->stackPtr; -} - -MtxPtr MTXPushInvXpose(MTXStack* sPtr, const Mtx m) { - Mtx mIT; - ASSERTMSGLINE(279, sPtr, "MTXPushInvXpose(): NULL MtxStackPtr 'sPtr' "); - ASSERTMSGLINE(280, sPtr->stackBase, "MTXPushInvXpose(): 'sPtr' contains a NULL ptr to stack memory "); - ASSERTMSGLINE(281, m, "MTXPushInvXpose(): NULL MtxPtr 'm' "); - - MTXInverse(m, mIT); - MTXTranspose(mIT, mIT); - if (sPtr->stackPtr == NULL) { - sPtr->stackPtr = sPtr->stackBase; - MTXCopy(mIT, sPtr->stackPtr); - } else { - ASSERTMSGLINE(300, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushInvXpose(): stack overflow "); - MTXConcat(sPtr->stackPtr, mIT, sPtr->stackPtr + 3); - sPtr->stackPtr += 3; - } - - return sPtr->stackPtr; -} - -MtxPtr MTXPop(MTXStack* sPtr) { - ASSERTMSGLINE(328, sPtr, "MTXPop(): NULL MtxStackPtr 'sPtr' "); - ASSERTMSGLINE(329, sPtr->stackBase, "MTXPop(): 'sPtr' contains a NULL ptr to stack memory "); - - if (sPtr->stackPtr == NULL) { - return NULL; - } - - if (sPtr->stackBase == sPtr->stackPtr) { - sPtr->stackPtr = NULL; - return NULL; - } - - sPtr->stackPtr -= 3; - return sPtr->stackPtr; -} - -MtxPtr MTXGetStackPtr(const MTXStack* sPtr) { - ASSERTMSGLINE(366, sPtr, "MTXGetStackPtr(): NULL MtxStackPtr 'sPtr' "); - ASSERTMSGLINE(367, sPtr->stackBase, "MTXGetStackPtr(): 'sPtr' contains a NULL ptr to stack memory "); - return sPtr->stackPtr; -} diff --git a/src/dolphin/mtx/mtxvec.c b/src/dolphin/mtx/mtxvec.c deleted file mode 100644 index 47146ee..0000000 --- a/src/dolphin/mtx/mtxvec.c +++ /dev/null @@ -1,204 +0,0 @@ -#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/src/dolphin/mtx/psmtx.c b/src/dolphin/mtx/psmtx.c deleted file mode 100644 index 6ec6c29..0000000 --- a/src/dolphin/mtx/psmtx.c +++ /dev/null @@ -1,336 +0,0 @@ -#include -#include -#include "fake_tgmath.h" - -asm void PSMTXReorder(const register Mtx src, register ROMtx dest) { - psq_l f0, 0(src), 0, 0 - psq_l f2, 16(src), 0, 0 - psq_l f4, 32(src), 0, 0 - psq_l f1, 8(src), 0, 0 - ps_merge00 f6, f0, f2 - psq_l f3, 24(src), 0, 0 - ps_merge01 f12, f4, f0 - psq_l f5, 40(src), 0, 0 - ps_merge11 f7, f2, f4 - psq_st f6, 0(dest), 0, 0 - ps_merge00 f8, f1, f3 - psq_st f12, 8(dest), 0, 0 - ps_merge01 f9, f5, f1 - psq_st f7, 16(dest), 0, 0 - ps_merge11 f10, f3, f5 - psq_st f8, 24(dest), 0, 0 - psq_st f9, 32(dest), 0, 0 - psq_st f10, 40(dest), 0, 0 -} - -asm void PSMTXROMultVecArray(const register ROMtx m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { - nofralloc - stwu r1, -64(r1) - stfd f14, 8(r1) - subi r7, count, 1 - stfd f15, 16(r1) - srwi r7, r7, 1 - stfd f16, 24(r1) - stfd f17, 32(r1) - stfd f18, 40(r1) - mtctr r7 - psq_l f0, 0(m), 0, 0 - subi srcBase, srcBase, 8 - psq_l f1, 8(m), 1, 0 - subi dstBase, dstBase, 4 - psq_l f6, 36(m), 0, 0 - psq_lu f8, 8(srcBase), 0, 0 - psq_l f7, 44(m), 1, 0 - psq_lu f9, 8(srcBase), 0, 0 - ps_madds0 f11, f0, f8, f6 - psq_l f2, 12(m), 0, 0 - ps_madds0 f12, f1, f8, f7 - psq_l f3, 20(m), 1, 0 - ps_madds1 f13, f0, f9, f6 - psq_lu f10, 8(srcBase), 0, 0 - ps_madds1 f14, f1, f9, f7 - psq_l f5, 32(m), 1, 0 - ps_madds1 f11, f2, f8, f11 - ps_madds1 f12, f3, f8, f12 - psq_l f4, 24(m), 0, 0 - ps_madds0 f13, f2, f10, f13 - psq_lu f8, 8(srcBase), 0, 0 - ps_madds0 f14, f3, f10, f14 - ps_madds0 f15, f4, f9, f11 - ps_madds0 f16, f5, f9, f12 - psq_lu f9, 8(srcBase), 0, 0 - ps_madds1 f17, f4, f10, f13 - ps_madds1 f18, f5, f10, f14 - psq_lu f10, 8(srcBase), 0, 0 -loop: - ps_madds0 f11, f0, f8, f6 - psq_stu f15, 4(dstBase), 0, 0 - ps_madds0 f12, f1, f8, f7 - psq_stu f16, 8(dstBase), 1, 0 - ps_madds1 f13, f0, f9, f6 - psq_stu f17, 4(dstBase), 0, 0 - ps_madds1 f14, f1, f9, f7 - psq_stu f18, 8(dstBase), 1, 0 - ps_madds1 f11, f2, f8, f11 - ps_madds1 f12, f3, f8, f12 - psq_lu f8, 8(srcBase), 0, 0 - ps_madds0 f13, f2, f10, f13 - ps_madds0 f14, f3, f10, f14 - ps_madds0 f15, f4, f9, f11 - ps_madds0 f16, f5, f9, f12 - psq_lu f9, 8(srcBase), 0, 0 - ps_madds1 f17, f4, f10, f13 - ps_madds1 f18, f5, f10, f14 - psq_lu f10, 8(srcBase), 0, 0 - bdnz loop - psq_stu f15, 4(dstBase), 0, 0 - clrlwi. r7, count, 31 - psq_stu f16, 8(dstBase), 1, 0 - bne exit - psq_stu f17, 4(dstBase), 0, 0 - psq_stu f18, 8(dstBase), 1, 0 -exit: - lfd f14, 8(r1) - lfd f15, 16(r1) - lfd f16, 24(r1) - lfd f17, 32(r1) - lfd f18, 40(r1) - addi r1, r1, 64 - blr -} - -asm void PSMTXROSkin2VecArray(const register ROMtx m0, const register ROMtx m1, const register f32* wtBase, const register Vec* srcBase, register Vec* dstBase, register u32 count) { - nofralloc - stwu r1, -160(r1) - stfd f14, 8(r1) - stfd f15, 16(r1) - stfd f16, 24(r1) - stfd f17, 32(r1) - stfd f18, 40(r1) - stfd f19, 48(r1) - stfd f20, 56(r1) - stfd f21, 64(r1) - stfd f22, 72(r1) - stfd f23, 80(r1) - stfd f24, 88(r1) - stfd f25, 96(r1) - stfd f26, 104(r1) - stfd f27, 112(r1) - stfd f28, 120(r1) - stfd f29, 128(r1) - stfd f30, 136(r1) - subi r9, r8, 1 - mtctr r9 - subi srcBase, srcBase, 4 - subi dstBase, dstBase, 4 - subi wtBase, wtBase, 4 - psq_l f14, 0(m0), 0, 0 - psq_l f22, 0(m1), 0, 0 - psq_l f15, 8(m0), 1, 0 - psq_l f23, 8(m1), 1, 0 - psq_l f16, 12(m0), 0, 0 - psq_l f24, 12(m1), 0, 0 - ps_sub f22, f22, f14 - psq_l f17, 20(m0), 1, 0 - psq_l f25, 20(m1), 1, 0 - ps_sub f23, f23, f15 - psq_l f18, 24(m0), 0, 0 - psq_l f26, 24(m1), 0, 0 - ps_sub f24, f24, f16 - psq_l f19, 32(m0), 1, 0 - psq_l f27, 32(m1), 1, 0 - ps_sub f25, f25, f17 - psq_l f20, 36(m0), 0, 0 - psq_l f28, 36(m1), 0, 0 - ps_sub f26, f26, f18 - psq_l f21, 44(m0), 1, 0 - psq_l f29, 44(m1), 1, 0 - ps_sub f27, f27, f19 - ps_sub f28, f28, f20 - ps_sub f29, f29, f21 - psq_lu f30, 4(wtBase), 1, 0 - psq_lu f8, 4(srcBase), 0, 0 - psq_lu f9, 8(srcBase), 1, 0 - ps_madds0 f0, f22, f30, f14 - ps_madds0 f1, f23, f30, f15 - ps_madds0 f2, f24, f30, f16 - ps_madds0 f3, f25, f30, f17 - ps_madds0 f4, f26, f30, f18 - ps_madds0 f5, f27, f30, f19 - ps_madds0 f6, f28, f30, f20 - ps_madds0 f7, f29, f30, f21 - ps_madds0 f12, f0, f8, f6 - ps_madds0 f13, f1, f8, f7 - psq_lu f30, 4(wtBase), 1, 0 -loop: - ps_madds1 f12, f2, f8, f12 - ps_madds1 f13, f3, f8, f13 - psq_lu f8, 4(srcBase), 0, 0 - ps_madds0 f10, f4, f9, f12 - ps_madds0 f11, f5, f9, f13 - psq_lu f9, 8(srcBase), 1, 0 - ps_madds0 f0, f22, f30, f14 - ps_madds0 f1, f23, f30, f15 - ps_madds0 f2, f24, f30, f16 - ps_madds0 f3, f25, f30, f17 - ps_madds0 f4, f26, f30, f18 - ps_madds0 f5, f27, f30, f19 - ps_madds0 f6, f28, f30, f20 - ps_madds0 f7, f29, f30, f21 - psq_stu f10, 4(dstBase), 0, 0 - ps_madds0 f12, f0, f8, f6 - ps_madds0 f13, f1, f8, f7 - psq_stu f11, 8(dstBase), 1, 0 - psq_lu f30, 4(wtBase), 1, 0 - bdnz loop - ps_madds1 f12, f2, f8, f12 - ps_madds1 f13, f3, f8, f13 - ps_madds0 f10, f4, f9, f12 - psq_stu f10, 4(dstBase), 0, 0 - ps_madds0 f11, f5, f9, f13 - psq_stu f11, 8(dstBase), 1, 0 - lfd f14, 8(r1) - lfd f15, 16(r1) - lfd f16, 24(r1) - lfd f17, 32(r1) - lfd f18, 40(r1) - lfd f19, 48(r1) - lfd f20, 56(r1) - lfd f21, 64(r1) - lfd f22, 72(r1) - lfd f23, 80(r1) - lfd f24, 88(r1) - lfd f25, 96(r1) - lfd f26, 104(r1) - lfd f27, 112(r1) - lfd f28, 120(r1) - lfd f29, 128(r1) - lfd f30, 136(r1) - addi r1, r1, 160 - blr -} - -asm void PSMTXROMultS16VecArray(const register Mtx m, const register S16Vec* srcBase, register Vec* dstBase, register u32 count) { - nofralloc - stwu r1, -64(r1) - stfd f14, 8(r1) - subi r7, count, 1 - stfd f15, 16(r1) - srwi r7, r7, 1 - stfd f16, 24(r1) - lis r8, 7 - stfd f17, 32(r1) - mtspr GQR6, r8 - stfd f18, 40(r1) - mtctr r7 - psq_l f0, 0(m), 0, 0 - subi srcBase, srcBase, 4 - psq_l f1, 8(m), 1, 0 - subi dstBase, dstBase, 4 - psq_l f6, 36(m), 0, 0 - psq_lu f8, 4(srcBase), 0, 6 - psq_l f7, 44(m), 1, 0 - psq_lu f9, 4(srcBase), 0, 6 - ps_madds0 f11, f0, f8, f6 - psq_l f2, 12(m), 0, 0 - ps_madds0 f12, f1, f8, f7 - psq_l f3, 20(m), 1, 0 - ps_madds1 f13, f0, f9, f6 - psq_lu f10, 4(srcBase), 0, 6 - ps_madds1 f14, f1, f9, f7 - psq_l f5, 32(m), 1, 0 - ps_madds1 f11, f2, f8, f11 - ps_madds1 f12, f3, f8, f12 - psq_l f4, 24(m), 0, 0 - ps_madds0 f13, f2, f10, f13 - psq_lu f8, 4(srcBase), 0, 6 - ps_madds0 f14, f3, f10, f14 - ps_madds0 f15, f4, f9, f11 - ps_madds0 f16, f5, f9, f12 - psq_lu f9, 4(srcBase), 0, 6 - ps_madds1 f17, f4, f10, f13 - ps_madds1 f18, f5, f10, f14 - psq_lu f10, 4(srcBase), 0, 6 -loop: - ps_madds0 f11, f0, f8, f6 - psq_stu f15, 4(dstBase), 0, 0 - ps_madds0 f12, f1, f8, f7 - psq_stu f16, 8(dstBase), 1, 0 - ps_madds1 f13, f0, f9, f6 - psq_stu f17, 4(dstBase), 0, 0 - ps_madds1 f14, f1, f9, f7 - psq_stu f18, 8(dstBase), 1, 0 - ps_madds1 f11, f2, f8, f11 - ps_madds1 f12, f3, f8, f12 - psq_lu f8, 4(srcBase), 0, 6 - ps_madds0 f13, f2, f10, f13 - ps_madds0 f14, f3, f10, f14 - ps_madds0 f15, f4, f9, f11 - ps_madds0 f16, f5, f9, f12 - psq_lu f9, 4(srcBase), 0, 6 - ps_madds1 f17, f4, f10, f13 - ps_madds1 f18, f5, f10, f14 - psq_lu f10, 4(srcBase), 0, 6 - bdnz loop - psq_stu f15, 4(dstBase), 0, 0 - clrlwi. r7, count, 31 - psq_stu f16, 8(dstBase), 1, 0 - bne exit - psq_stu f17, 4(dstBase), 0, 0 - psq_stu f18, 8(dstBase), 1, 0 -exit: - lfd f14, 8(r1) - lfd f15, 16(r1) - lfd f16, 24(r1) - lfd f17, 32(r1) - lfd f18, 40(r1) - addi r1, r1, 64 - blr -} - -asm void PSMTXMultS16VecArray(const register ROMtx* m, const register S16Vec* srcBase, register Vec* dstBase, register u32 count) { - psq_l f0, 0(m), 0, 0 - lis r7, 7 - mtspr GQR6, r7 - psq_l f6, 0(srcBase), 0, 6 - subi count, count, 1 - psq_l f7, 4(srcBase), 1, 6 - mtctr count - psq_l f1, 8(m), 0, 0 - addi srcBase, srcBase, 4 - psq_l f2, 16(m), 0, 0 - subi dstBase, dstBase, 4 - psq_l f3, 24(m), 0, 0 - ps_mul f8, f0, f6 - psq_l f4, 32(m), 0, 0 - ps_mul f10, f2, f6 - psq_l f5, 40(m), 0, 0 - ps_mul f12, f4, f6 - psq_lu f6, 2(srcBase), 0, 6 - ps_madd f8, f1, f7, f8 - ps_madd f10, f3, f7, f10 - ps_madd f12, f5, f7, f12 - psq_lu f7, 4(srcBase), 1, 6 - ps_sum0 f9, f8, f8, f8 -loop: - ps_sum0 f11, f10, f10, f10 - ps_mul f8, f0, f6 - ps_sum0 f13, f12, f12, f12 - ps_mul f10, f2, f6 - psq_stu f9, 4(dstBase), 1, 0 - ps_mul f12, f4, f6 - psq_stu f11, 4(dstBase), 1, 0 - ps_madd f8, f1, f7, f8 - psq_stu f13, 4(dstBase), 1, 0 - ps_madd f10, f3, f7, f10 - psq_lu f6, 2(srcBase), 0, 6 - ps_madd f12, f5, f7, f12 - psq_lu f7, 4(srcBase), 1, 6 - ps_sum0 f9, f8, f8, f8 - bdnz loop - ps_sum0 f11, f10, f10, f10 - ps_sum0 f13, f12, f12, f12 - psq_stu f9, 4(dstBase), 1, 0 - psq_stu f11, 4(dstBase), 1, 0 - psq_stu f13, 4(dstBase), 1, 0 -} diff --git a/src/dolphin/mtx/quat.c b/src/dolphin/mtx/quat.c deleted file mode 100644 index 79687f0..0000000 --- a/src/dolphin/mtx/quat.c +++ /dev/null @@ -1,486 +0,0 @@ -#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/src/dolphin/mtx/vec.c b/src/dolphin/mtx/vec.c deleted file mode 100644 index 994ee18..0000000 --- a/src/dolphin/mtx/vec.c +++ /dev/null @@ -1,344 +0,0 @@ -#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* 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(const Vec* a, const Vec* b, Vec* a_b) { - ASSERTMSGLINE(177, a, "VECSubtract(): NULL VecPtr 'a' "); - ASSERTMSGLINE(178, b, "VECSubtract(): NULL VecPtr 'b' "); - ASSERTMSGLINE(179, a_b, "VECSubtract(): NULL VecPtr 'a_b' "); - a_b->x = a->x - b->x; - a_b->y = a->y - b->y; - a_b->z = a->z - b->z; -} - -asm void PSVECSubtract(const register Vec* a, const register Vec* b, register Vec* a_b) { - psq_l f2, Vec.x(a), 0, 0 - psq_l f4, Vec.x(b), 0, 0 - ps_sub f6, f2, f4 - psq_st f6, Vec.x(a_b), 0, 0 - psq_l f3, Vec.z(a), 1, 0 - psq_l f5, Vec.z(b), 1, 0 - ps_sub f7, f3, f5 - psq_st f7, Vec.z(a_b), 1, 0 -} - -void C_VECScale(const Vec* src, Vec* dst, f32 scale) { - 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(const register Vec* src, register Vec* dst, register f32 scale) { - register f32 vxy, vz, rxy, rz; - - 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 - } -} - -void C_VECNormalize(const Vec* src, Vec* unit) { - f32 mag; - - ASSERTMSGLINE(315, src, "VECNormalize(): NULL VecPtr 'src' "); - ASSERTMSGLINE(316, unit, "VECNormalize(): NULL VecPtr 'unit' "); - - mag = (src->z * src->z) + ((src->x * src->x) + (src->y * src->y)); - ASSERTMSGLINE(321, 0.0f != mag, "VECNormalize(): zero magnitude vector "); - - mag = 1.0f/ sqrtf(mag); - unit->x = src->x * mag; - unit->y = src->y * mag; - unit->z = src->z * mag; -} - -void PSVECNormalize(const register Vec* src, register Vec* unit) { - register float c_half = 0.5f; - register float c_three = 3.0f; - register float v1_xy; - register float v1_z; - register float xx_zz; - register float xx_yy; - register float sqsum; - register float rsqrt; - register float nwork0; - register float nwork1; - - asm { - psq_l v1_xy, 0x0(src), 0, 0 - ps_mul xx_yy, v1_xy, v1_xy - psq_l v1_z, 0x8(src), 1, 0 - ps_madd xx_zz, v1_z, v1_z, xx_yy - ps_sum0 sqsum, xx_zz, v1_z, xx_yy - frsqrte rsqrt, sqsum - fmuls nwork0, rsqrt, rsqrt - fmuls nwork1, rsqrt, c_half - fnmsubs nwork0, nwork0, sqsum, c_three - fmuls rsqrt, nwork0, nwork1 - ps_muls0 v1_xy, v1_xy, rsqrt - psq_st v1_xy, 0x0(unit), 0, 0 - ps_muls0 v1_z, v1_z, rsqrt - psq_st v1_z, 0x8(unit), 1, 0 - } -} - -f32 C_VECSquareMag(const Vec* v) { - f32 sqmag; - - ASSERTMSGLINE(405, v, "VECMag(): NULL VecPtr 'v' "); - - sqmag = v->z * v->z + ((v->x * v->x) + (v->y * v->y)); - return sqmag; -} - -f32 PSVECSquareMag(const register Vec* v) { - register f32 vxy, vzz, sqmag; - - asm { - psq_l vxy, 0x0(v), 0, 0 - ps_mul vxy, vxy, vxy - lfs vzz, 0x8(v) - ps_madd sqmag, vzz, vzz, vxy - ps_sum0 sqmag, sqmag, vxy, vxy - } - - return sqmag; -} - -f32 C_VECMag(const Vec* v) { - return sqrtf(C_VECSquareMag(v)); -} - -f32 PSVECMag(const register Vec* v) { - register f32 vxy, vzz; - register f32 sqmag, rmag; - register f32 nwork0, nwork1; - register f32 c_three, c_half, c_zero; - - c_half = 0.5f; - - asm { - psq_l vxy, 0x0(v), 0, 0 - ps_mul vxy, vxy, vxy - lfs vzz, 0x8(v) - fsubs c_zero, c_half, c_half - ps_madd sqmag, vzz, vzz, vxy - ps_sum0 sqmag, sqmag, vxy, vxy - fcmpu cr0, sqmag, c_zero - beq L_000005F0 - frsqrte rmag, sqmag - } - - c_three = 3.0f; - - asm { - fmuls nwork0, rmag, rmag - fmuls nwork1, rmag, c_half - fnmsubs nwork0, nwork0, sqmag, c_three - fmuls rmag, nwork0, nwork1 - fmuls sqmag, sqmag, rmag - L_000005F0: - } - - return sqmag; -} - -f32 C_VECDotProduct(const Vec* a, const Vec* b) { - f32 dot; - - 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(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(const Vec* a, const Vec* b, Vec* axb) { - Vec vTmp; - - ASSERTMSGLINE(602, a, "VECCrossProduct(): NULL VecPtr 'a' "); - ASSERTMSGLINE(603, b, "VECCrossProduct(): NULL VecPtr 'b' "); - ASSERTMSGLINE(604, axb, "VECCrossProduct(): NULL VecPtr 'axb' "); - - vTmp.x = (a->y * b->z) - (a->z * b->y); - vTmp.y = (a->z * b->x) - (a->x * b->z); - vTmp.z = (a->x * b->y) - (a->y * b->x); - axb->x = vTmp.x; - axb->y = vTmp.y; - axb->z = vTmp.z; -} - -asm void PSVECCrossProduct(const register Vec* a, const register Vec* b, register Vec* axb) { - psq_l f1, Vec.x(b), 0, 0 - lfs f2, Vec.z(a) - psq_l f0, Vec.x(a), 0, 0 - ps_merge10 f6, f1, f1 - lfs f3, Vec.z(b) - ps_mul f4, f1, f2 - ps_muls0 f7, f1, f0 - ps_msub f5, f0, f3, f4 - ps_msub f8, f0, f6, f7 - ps_merge11 f9, f5, f5 - ps_merge01 f10, f5, f8 - psq_st f9, Vec.x(axb), 1, 0 - ps_neg f10, f10 - psq_st f10, Vec.y(axb), 0, 0 -} - -void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half) { - Vec aTmp; - Vec bTmp; - Vec hTmp; - - ASSERTMSGLINE(707, a, "VECHalfAngle(): NULL VecPtr 'a' "); - ASSERTMSGLINE(708, b, "VECHalfAngle(): NULL VecPtr 'b' "); - ASSERTMSGLINE(709, half, "VECHalfAngle(): NULL VecPtr 'half' "); - - aTmp.x = -a->x; - aTmp.y = -a->y; - aTmp.z = -a->z; - bTmp.x = -b->x; - bTmp.y = -b->y; - bTmp.z = -b->z; - - VECNormalize(&aTmp, &aTmp); - VECNormalize(&bTmp, &bTmp); - VECAdd(&aTmp, &bTmp, &hTmp); - - if (VECDotProduct(&hTmp, &hTmp) > 0.0f) { - VECNormalize(&hTmp, half); - return; - } - *half = hTmp; -} - -void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst) { - f32 cosA; - Vec uI; - Vec uN; - - ASSERTMSGLINE(763, src, "VECReflect(): NULL VecPtr 'src' "); - ASSERTMSGLINE(764, normal, "VECReflect(): NULL VecPtr 'normal' "); - ASSERTMSGLINE(765, dst, "VECReflect(): NULL VecPtr 'dst' "); - - uI.x = -src->x; - uI.y = -src->y; - uI.z = -src->z; - - VECNormalize(&uI, &uI); - VECNormalize(normal, &uN); - - cosA = VECDotProduct(&uI, &uN); - dst->x = (2.0f * uN.x * cosA) - uI.x; - dst->y = (2.0f * uN.y * cosA) - uI.y; - dst->z = (2.0f * uN.z * cosA) - uI.z; - VECNormalize(dst, dst); -} - -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 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; -} - -f32 C_VECDistance(const Vec* a, const Vec* b) { - return sqrtf(C_VECSquareDistance(a, b)); -} - -f32 PSVECDistance(const register Vec* a, const register Vec* b) { - register f32 v0yz, v1yz, v0xy, v1xy, dyz, dxy; - register f32 sqdist, rdist; - register f32 nwork0, nwork1; - register f32 c_half, c_three, c_zero; - - asm { - 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/src/dolphin/odemustubs/odemustubs.c b/src/dolphin/odemustubs/odemustubs.c deleted file mode 100644 index 1014fc3..0000000 --- a/src/dolphin/odemustubs/odemustubs.c +++ /dev/null @@ -1,34 +0,0 @@ -#include - -// prototypes -__declspec(weak) int Hu_IsStub(); -void DBInitInterrupts(); -s32 DBQueryData(); -u32 DBRead(); -u32 DBWrite(); -void DBOpen(); -void DBClose(); - -__declspec(weak) int Hu_IsStub() { - return 1; -} - -void DBInitComm(int* inputFlagPtr, int* mtrCallback) {} - -void DBInitInterrupts() {} - -s32 DBQueryData() { - return 0; -} - -u32 DBRead() { - return 0; -} - -u32 DBWrite() { - return 0; -} - -void DBOpen() {} - -void DBClose() {} diff --git a/src/dolphin/odenotstub/odenotstub.c b/src/dolphin/odenotstub/odenotstub.c deleted file mode 100644 index fd35d7a..0000000 --- a/src/dolphin/odenotstub/odenotstub.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -// prototypes -__declspec(weak) int Hu_IsStub(); - -__declspec(weak) int Hu_IsStub() { - return 0; -} diff --git a/src/dolphin/os/OS.c b/src/dolphin/os/OS.c deleted file mode 100644 index 67fe545..0000000 --- a/src/dolphin/os/OS.c +++ /dev/null @@ -1,631 +0,0 @@ -#include -#include -#include -#include -#include - -#include "__os.h" - -#define NOP 0x60000000 - -// external functions -extern void EnableMetroTRKInterrupts(void); -extern void __OSInitMemoryProtection(void); - -#define DB_EXCEPTIONRET_OFFSET 0xC -#define DB_EXCEPTIONDEST_OFFSET 0x8 -#define OS_CURRENTCONTEXT_PADDR 0x00C0 -#define OS_EXCEPTIONTABLE_ADDR 0x3000 -#define OS_DBJUMPPOINT_ADDR 0x60 - -#if SDK_REVISION < 1 -#define BUILD_DATE "Apr 5 2004" -#define DBUILD_TIME "03:55:13" -#define RBUILD_TIME "04:13:58" -#elif SDK_REVISION < 2 -#define BUILD_DATE "May 21 2004" -#define DBUILD_TIME "09:15:32" -#define RBUILD_TIME "09:28:09" -#else -#define BUILD_DATE "Nov 10 2004" -#define DBUILD_TIME "06:08:19" -#define RBUILD_TIME "06:26:41" -#endif - -#ifdef DEBUG -const char* __OSVersion = "<< Dolphin SDK - OS\tdebug build: "BUILD_DATE" "DBUILD_TIME" (0x2301) >>"; -#else -const char* __OSVersion = "<< Dolphin SDK - OS\trelease build: "BUILD_DATE" "RBUILD_TIME" (0x2301) >>"; -#endif - -static DVDDriveInfo DriveInfo; -static DVDCommandBlock DriveBlock; -OSExecParams __OSRebootParams; - -extern u32 __DVDLongFileNameFlag; -extern u32 __PADSpec; - -// defined in link script -extern u8 __ArenaLo[]; -extern char _stack_addr[]; -extern u8 __ArenaHi[]; - -static OSBootInfo* BootInfo; -static u32* BI2DebugFlag; -static u32 BI2DebugFlagHolder; - -OSTime __OSStartTime; -BOOL __OSInIPL; -void (**OSExceptionTable)(u8, OSContext*); -BOOL AreWeInitialized; -f32 ZeroPS[2]; -f64 ZeroF; -BOOL __OSIsGcam; - -// prototypes -static void __OSInitFPRs(void); -static void OSExceptionInit(void); - -// dummy entry points to the OS Exception vector -void __OSEVStart(void); -void __OSEVEnd(void); -void __OSEVSetNumber(void); -void __OSExceptionVector(void); -void __DBVECTOR(void); -void __OSDBINTSTART(void); -void __OSDBINTEND(void); -void __OSDBJUMPSTART(void); -void __OSDBJUMPEND(void); - -u32 __OSIsDebuggerPresent(void) { - return *(u32*)OSPhysicalToCached(0x40); -} - -/* clang-format off */ -#ifdef __GEKKO__ -asm void __OSFPRInit(void) { - // clang-format off - nofralloc - - mfmsr r3 - ori r3, r3, 0x2000 - mtmsr r3 - - mfspr r3, 0x398 - rlwinm. r3, r3, 3, 0x1f, 0x1f - beq skip_ps_init - - lis r3, ZeroPS@ha - addi r3, r3, ZeroPS@l - psq_l f0, 0(r3), 0, 0 - ps_mr f1, f0 - ps_mr f2, f0 - ps_mr f3, f0 - ps_mr f4, f0 - ps_mr f5, f0 - ps_mr f6, f0 - ps_mr f7, f0 - ps_mr f8, f0 - ps_mr f9, f0 - ps_mr f10, f0 - ps_mr f11, f0 - ps_mr f12, f0 - ps_mr f13, f0 - ps_mr f14, f0 - ps_mr f15, f0 - ps_mr f16, f0 - ps_mr f17, f0 - ps_mr f18, f0 - ps_mr f19, f0 - ps_mr f20, f0 - ps_mr f21, f0 - ps_mr f22, f0 - ps_mr f23, f0 - ps_mr f24, f0 - ps_mr f25, f0 - ps_mr f26, f0 - ps_mr f27, f0 - ps_mr f28, f0 - ps_mr f29, f0 - ps_mr f30, f0 - ps_mr f31, f0 - -skip_ps_init: - lfd f0, ZeroF(r13) - fmr f1, f0 - fmr f2, f0 - fmr f3, f0 - fmr f4, f0 - fmr f5, f0 - fmr f6, f0 - fmr f7, f0 - fmr f8, f0 - fmr f9, f0 - fmr f10, f0 - fmr f11, f0 - fmr f12, f0 - fmr f13, f0 - fmr f14, f0 - fmr f15, f0 - fmr f16, f0 - fmr f17, f0 - fmr f18, f0 - fmr f19, f0 - fmr f20, f0 - fmr f21, f0 - fmr f22, f0 - fmr f23, f0 - fmr f24, f0 - fmr f25, f0 - fmr f26, f0 - fmr f27, f0 - fmr f28, f0 - fmr f29, f0 - fmr f30, f0 - fmr f31, f0 - - mtfsf 0xff, f0 - blr - // clang-format on -} -#endif - -static void DisableWriteGatherPipe(void) { - u32 hid2; - - hid2 = PPCMfhid2(); - hid2 &= ~0x40000000; - PPCMthid2(hid2); -} - -u32 OSGetConsoleType(void) { - if (!BootInfo || BootInfo->consoleType == 0) { - return OS_CONSOLE_ARTHUR; - } - return BootInfo->consoleType; -} - -// needed for assert -#undef NULL -#define NULL 0 - -static void ClearArena(void) { - if (!((OSGetResetCode() & 0x80000000) ? TRUE : FALSE)) { - memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); - return; - } - - if (*(u32*)&__OSRebootParams.regionStart == 0) { - memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); - return; - } - - ASSERTLINE(683, __OSRebootParams.regionEnd != NULL); - - if ((u32)OSGetArenaLo() < *(u32*)&__OSRebootParams.regionStart) { - if ((u32)OSGetArenaHi() <= *(u32*)&__OSRebootParams.regionStart) { - memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); - return; - } - - memset(OSGetArenaLo(), 0, *(u32*)&__OSRebootParams.regionStart - (u32)OSGetArenaLo()); - - if ((u32)OSGetArenaHi() > (u32)__OSRebootParams.regionEnd) { - memset(__OSRebootParams.regionEnd, 0, (u32)OSGetArenaHi() - (u32)__OSRebootParams.regionEnd); - } - } -} - -static void InquiryCallback(s32, DVDCommandBlock* block) { - switch (block->state) { - case 0: - __OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode); - break; - default: - __OSDeviceCode = 1; - break; - } -} - -void OSInit(void) { - u32 consoleType; - void* bi2StartAddr; - - if (AreWeInitialized == FALSE) { - AreWeInitialized = TRUE; - - __OSStartTime = __OSGetSystemTime(); - OSDisableInterrupts(); - - __OSGetExecParams(&__OSRebootParams); - PPCMtmmcr0(0); - PPCMtmmcr1(0); - PPCMtpmc1(0); - PPCMtpmc2(0); - PPCMtpmc3(0); - PPCMtpmc4(0); - PPCDisableSpeculation(); - PPCSetFpNonIEEEMode(); - - BootInfo = (OSBootInfo*)OSPhysicalToCached(0); - BI2DebugFlag = 0; - __DVDLongFileNameFlag = 0; - - bi2StartAddr = (void*)(*(u32*)OSPhysicalToCached(0xF4)); - if (bi2StartAddr) { - BI2DebugFlag = (void*)((char*)bi2StartAddr + 0xC); - __PADSpec = ((u32*)bi2StartAddr)[9]; - *(u8*)OSPhysicalToCached(0x30E8) = *BI2DebugFlag; - *(u8*)OSPhysicalToCached(0x30E9) = __PADSpec; - } else if (BootInfo->arenaHi) { - BI2DebugFlagHolder = *(u8*)OSPhysicalToCached(0x30E8); - BI2DebugFlag = &BI2DebugFlagHolder; - __PADSpec = *(u8*)OSPhysicalToCached(0x30E9); - } - - __DVDLongFileNameFlag = 1; - - OSSetArenaLo((!BootInfo->arenaLo) ? &__ArenaLo : BootInfo->arenaLo); - if ((!BootInfo->arenaLo) && (BI2DebugFlag) && (*(u32*)BI2DebugFlag < 2)) { - OSSetArenaLo((void*)(((u32)(char*)&_stack_addr + 0x1F) & 0xFFFFFFE0)); - } - OSSetArenaHi((!BootInfo->arenaHi) ? &__ArenaHi : BootInfo->arenaHi); - - OSExceptionInit(); - __OSInitSystemCall(); - OSInitAlarm(); - __OSModuleInit(); - __OSInterruptInit(); - __OSSetInterruptHandler(0x16, &__OSResetSWInterruptHandler); - __OSContextInit(); - __OSCacheInit(); - EXIInit(); - SIInit(); - __OSInitSram(); - __OSThreadInit(); - __OSInitAudioSystem(); - - DisableWriteGatherPipe(); - - if (!__OSInIPL) { - __OSInitMemoryProtection(); - } - - OSReport("\nDolphin OS\n"); -#if DEBUG - OSReport("Kernel built : %s %s\n", BUILD_DATE, DBUILD_TIME); -#else - OSReport("Kernel built : %s %s\n", BUILD_DATE, RBUILD_TIME); -#endif - OSReport("Console Type : "); - - consoleType = OSGetConsoleType(); - switch (consoleType & 0xF0000000) { - case OS_CONSOLE_RETAIL: - OSReport("Retail %d\n", consoleType); - break; - case OS_CONSOLE_DEVELOPMENT: - case OS_CONSOLE_TDEV: - switch (consoleType & 0x0FFFFFFF) { - 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: - OSReport("Development HW%d (%08x)\n", (consoleType & 0xFFFFFFF) - 3, consoleType); - break; - } - break; - default: - OSReport("%08x\n", consoleType); - break; - } - - OSReport("Memory %d MB\n", (u32)BootInfo->memorySize >> 0x14U); - OSReport("Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi()); - OSRegisterVersion(__OSVersion); - - // if location of debug flag exists, and flag is >= 2, enable MetroTRKInterrupts - if (BI2DebugFlag && ((*BI2DebugFlag) >= 2)) { - EnableMetroTRKInterrupts(); - } - - ClearArena(); - OSEnableInterrupts(); - - if (!__OSInIPL) { - DVDInit(); - - if (__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, -}; - -#if DEBUG -char * __OSExceptionNames[17] = { - "System reset", - "MachineCheck", - "DSI", - "ISI", - "External Int.", - "Alignment", - "Program", - "FP Unavailable", - "Decrementer", - "System call", - "Trace", - "Perf mon", - "IABR", - "SMI", - "Thermal Int.", - "Protection error", - "FP Exception", -}; -#endif - -static void OSExceptionInit(void) { - __OSException exception; - void* destAddr; - - // These two vars help us change the exception number embedded - // in the exception handler code. - u32* opCodeAddr; - u32 oldOpCode; - - // Address range of the actual code to be copied. - u8* handlerStart; - u32 handlerSize; - - ASSERTMSGLINE(1063, ((u32)&__OSEVEnd - (u32)&__OSEVStart) <= 0x100, "OSExceptionInit(): too big exception vector code."); - - // Install the first level exception vector. - opCodeAddr = (u32*)__OSEVSetNumber; - oldOpCode = *opCodeAddr; - handlerStart = (u8*)__OSEVStart; - handlerSize = (u32)((u8*)__OSEVEnd - (u8*)__OSEVStart); - - // Install the DB integrator, only if we are the first OSInit to be run - destAddr = (void*)OSPhysicalToCached(OS_DBJUMPPOINT_ADDR); - if (*(u32*)destAddr == 0) // Lomem should be zero cleared only once by BS2 - { - 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 = (void*)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"); -} - -#ifdef __GEKKO__ -static asm void __OSDBIntegrator(void) { - 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 -} -#endif - -#ifdef __GEKKO__ -static asm void __OSDBJump(void) { - nofralloc -entry __OSDBJUMPSTART - bla OS_DBJUMPPOINT_ADDR -entry __OSDBJUMPEND -} -#endif - -__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) { - __OSExceptionHandler oldHandler; - - ASSERTMSGLINE(1205, exception < __OS_EXCEPTION_MAX, "__OSSetExceptionHandler(): unknown exception."); - - oldHandler = OSExceptionTable[exception]; - OSExceptionTable[exception] = handler; - return oldHandler; -} - -__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) { - ASSERTMSGLINE(1228, exception < __OS_EXCEPTION_MAX, "__OSGetExceptionHandler(): unknown exception."); - return OSExceptionTable[exception]; -} - -#ifdef __GEKKO__ -static asm void OSExceptionVector(void) { - 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 -} -#endif - -void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); - -#ifdef __GEKKO__ -asm void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) { - nofralloc - OS_EXCEPTION_SAVE_GPRS(context) - mfdsisr r5 - mfdar r6 - - stwu r1, -8(r1) - b __OSUnhandledException -} -#endif - -#ifdef __GEKKO__ -void __OSPSInit(void) { - PPCMthid2(PPCMfhid2() | 0x80000000 | 0x20000000); - ICFlashInvalidate(); - __sync(); - - asm - { - li r3, 0 - mtspr GQR0, r3 - mtspr GQR1, r3 - mtspr GQR2, r3 - mtspr GQR3, r3 - mtspr GQR4, r3 - mtspr GQR5, r3 - mtspr GQR6, r3 - mtspr GQR7, r3 - } -} -#endif - -u32 __OSGetDIConfig(void) { - return (__DIRegs[9] & 0xFF); -} - -void OSRegisterVersion(const char* id) { - OSReport("%s\n", id); -} diff --git a/src/dolphin/os/OSAddress.c b/src/dolphin/os/OSAddress.c deleted file mode 100644 index 4445c5a..0000000 --- a/src/dolphin/os/OSAddress.c +++ /dev/null @@ -1,39 +0,0 @@ -#include - -// undefine the macros so they do not error the file. -#undef OSPhysicalToCached -#undef OSPhysicalToUncached -#undef OSCachedToPhysical -#undef OSUncachedToPhysical -#undef OSCachedToUncached -#undef OSUncachedToCached - -void* OSPhysicalToCached(u32 paddr) { - ASSERTMSGLINE(47, paddr < 0x10000000U, "OSPhysicalToCached(): illegal address."); - return (void*)(paddr + 0x80000000); -} - -void* OSPhysicalToUncached(u32 paddr) { - ASSERTMSGLINE(62, paddr < 0x10000000U, "OSPhysicalToUncached(): illegal address."); - return (void*)(paddr - 0x40000000); -} - -u32 OSCachedToPhysical(void* caddr) { - ASSERTMSGLINE(77, 0x80000000U <= (u32)caddr && (u32)caddr < 0x90000000U, "OSCachedToPhysical(): illegal address."); - return (u32)caddr + 0x80000000; -} - -u32 OSUncachedToPhysical(void* ucaddr) { - ASSERTMSGLINE(92, 0xC0000000U <= (u32)ucaddr && (u32)ucaddr < 0xD0000000U, "OSUncachedToPhysical(): illegal address."); - return (u32)ucaddr + 0x40000000; -} - -void* OSCachedToUncached(void* caddr) { - ASSERTMSGLINE(107, 0x80000000U <= (u32)caddr && (u32)caddr < 0x90000000U, "OSCachedToUncached(): illegal address."); - return (void*)((u32)caddr + 0x40000000); -} - -void* OSUncachedToCached(void* ucaddr) { - ASSERTMSGLINE(122, 0xC0000000U <= (u32)ucaddr && (u32)ucaddr < 0xD0000000U, "OSUncachedToCached(): illegal address."); - return (void*)((u32)ucaddr - 0x40000000); -} diff --git a/src/dolphin/os/OSAlarm.c b/src/dolphin/os/OSAlarm.c deleted file mode 100644 index 9a0d0d6..0000000 --- a/src/dolphin/os/OSAlarm.c +++ /dev/null @@ -1,297 +0,0 @@ -#include -#include - -#include "__os.h" -#include "__dvd.h" - -typedef struct { - OSAlarm* head; - OSAlarm* tail; -} OSAlarmQueue; - -// prototypes -static void SetTimer(OSAlarm * alarm); -static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler); -static void DecrementerExceptionCallback(register __OSException exception, register OSContext* context); -static void DecrementerExceptionHandler(__OSException exception, OSContext* context); -static BOOL OnReset(BOOL final); - -static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 0xFFFFFFFF, NULL, NULL}; -static OSAlarmQueue AlarmQueue; - -#define ASSERTREPORT(line, cond) \ - if (!(cond)) { OSReport("OSCheckAlarmQueue: Failed " #cond " in %d", line); return 0; } - -BOOL OSCheckAlarmQueue(void) { - OSAlarm* alarm; - - ASSERTREPORT(146, AlarmQueue.head == NULL && AlarmQueue.tail == NULL || AlarmQueue.head != NULL && AlarmQueue.tail != NULL); - ASSERTREPORT(147, AlarmQueue.head == NULL || AlarmQueue.head->prev == NULL); - ASSERTREPORT(148, AlarmQueue.tail == NULL || AlarmQueue.tail->next == NULL); - - for(alarm = AlarmQueue.head; alarm; alarm = alarm->next) { - ASSERTREPORT(151, alarm->next == NULL || alarm->next->prev == alarm); - ASSERTREPORT(152, alarm->next != NULL || AlarmQueue.tail == alarm); - } - return TRUE; -} - -static void SetTimer(OSAlarm* alarm) { - OSTime 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); - } - } - - ASSERTLINE(251, alarm->handler == 0); - - 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; - } - - ASSERTLINE(280, next == 0); - - 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; - ASSERTMSGLINE(313, tick > 0, "OSSetAlarm(): tick was less than zero."); - ASSERTMSGLINE(314, handler, "OSSetAlarm(): null handler was specified."); - enabled = OSDisableInterrupts(); - alarm->period = 0; - InsertAlarm(alarm, __OSGetSystemTime() + tick, handler); - ASSERTLINE(321, OSCheckAlarmQueue()); - OSRestoreInterrupts(enabled); -} - -void OSSetAbsAlarm(OSAlarm* alarm, OSTime time, OSAlarmHandler handler) { - BOOL enabled; - - ASSERTMSGLINE(343, handler, "OSSetAbsAlarm(): null handler was specified."); - enabled = OSDisableInterrupts(); - alarm->period = 0; - InsertAlarm(alarm, __OSTimeToSystemTime(time), handler); - ASSERTLINE(350, OSCheckAlarmQueue()); - OSRestoreInterrupts(enabled); -} - -void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler) { - BOOL enabled; - ASSERTMSGLINE(374, period > 0, "OSSetPeriodicAlarm(): period was less than zero."); - ASSERTMSGLINE(375, handler, "OSSetPeriodicAlarm(): null handler was specified."); - enabled = OSDisableInterrupts(); - alarm->period = period; - alarm->start = __OSTimeToSystemTime(start); - InsertAlarm(alarm, 0, handler); - ASSERTLINE(383, OSCheckAlarmQueue()); - 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; - ASSERTLINE(434, OSCheckAlarmQueue()); - 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; - } - - ASSERTLINE(492, OSCheckAlarmQueue()); - - handler = alarm->handler; - alarm->handler = 0; - if (0 < alarm->period) { - InsertAlarm(alarm, 0, handler); - ASSERTLINE(502, OSCheckAlarmQueue()); - } - - if (AlarmQueue.head) { - SetTimer(AlarmQueue.head); - } - - OSDisableScheduler(); - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - handler(alarm, context); - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); - OSEnableScheduler(); - __OSReschedule(); - OSLoadContext(context); -} - -#ifdef __GEKKO__ -static asm void DecrementerExceptionHandler(register __OSException exception, - register OSContext* context) { - nofralloc - OS_EXCEPTION_SAVE_GPRS(context) - stwu r1, -8(r1) - b DecrementerExceptionCallback -} -#endif - -void OSSetAlarmTag(OSAlarm* alarm, u32 tag) { - alarm->tag = tag; -} - -void OSCancelAlarms(u32 tag) { - BOOL enabled; - OSAlarm* alarm; - OSAlarm* next; - - ASSERTMSGLINE(569, tag != 0, "OSCancelAlarms(): invalid tag. (tag zero is used by the operating system.)"); - - if (tag != 0) { - enabled = OSDisableInterrupts(); - ASSERTLINE(575, OSCheckAlarmQueue()); - - alarm = AlarmQueue.head; - next = (alarm) ? alarm->next : NULL; - - while (alarm != 0) { - if (alarm->tag == tag) { - OSCancelAlarm(alarm); - } - - alarm = next; - next = (alarm) ? alarm->next : NULL; - } - - ASSERTLINE(585, OSCheckAlarmQueue()); - OSRestoreInterrupts(enabled); - } -} - -static BOOL OnReset(BOOL final) { - OSAlarm* alarm; - OSAlarm* next; - - if (final != FALSE) { - ASSERTLINE(606, OSCheckAlarmQueue()); - - alarm = AlarmQueue.head; - next = (alarm) ? alarm->next : NULL; - - while (alarm != 0) { - if (__DVDTestAlarm(alarm) == FALSE) { - OSCancelAlarm(alarm); - } - - alarm = next; - next = (alarm) ? alarm->next : NULL; - } - - ASSERTLINE(616, OSCheckAlarmQueue()); - } - - return TRUE; -} diff --git a/src/dolphin/os/OSAlloc.c b/src/dolphin/os/OSAlloc.c deleted file mode 100644 index 2ad58e3..0000000 --- a/src/dolphin/os/OSAlloc.c +++ /dev/null @@ -1,609 +0,0 @@ -#include -#include - -#define ALIGNMENT 32 - -#define InRange(cell, arenaStart, arenaEnd) \ - ((u32) arenaStart <= (u32) cell) && ((u32) cell < (u32) arenaEnd) - -#define HEADERSIZE 32u -#define MINOBJSIZE 64u - -#ifdef DEBUG -#define ENABLE_HEAPDESC -#endif - -typedef struct Cell Cell; -typedef struct HeapDesc HeapDesc; -struct Cell { - Cell* prev; - Cell* next; - s32 size; -#ifdef ENABLE_HEAPDESC - HeapDesc* hd; - s32 requested; -#endif -}; - -struct HeapDesc { - s32 size; - Cell* free; - Cell* allocated; -#ifdef ENABLE_HEAPDESC - u32 paddingBytes; - u32 headerBytes; - u32 payloadBytes; -#endif -}; - -volatile int __OSCurrHeap = -1; - -static HeapDesc* HeapArray; -static int NumHeaps; -static void* ArenaStart; -static void* ArenaEnd; - -// prototypes -static Cell* DLAddFront(Cell* list, Cell* cell); -static Cell* DLLookup(Cell* list, Cell* cell); -static Cell* DLExtract(Cell* list, Cell* cell); -static Cell* DLInsert(Cell* list, Cell* cell); -static int DLOverlap(Cell* list, void* start, void* end); -static s32 DLSize(Cell* list); - -static Cell* DLAddFront(Cell* list, Cell* cell) { - cell->next = list; - cell->prev = 0; - if (list) { - list->prev = cell; - } - return cell; -} - -static Cell* DLLookup(Cell* list, Cell* cell) { - for(; list; list = list->next) { - if (list == cell) { - return list; - } - } - return NULL; -} - -static Cell* DLExtract(Cell* list, Cell* cell) { - if (cell->next) { - cell->next->prev = cell->prev; - } - if (cell->prev == NULL) { - return cell->next; - } - cell->prev->next = cell->next; - return list; -} - -static Cell* DLInsert(Cell* list, Cell* cell) { - Cell* prev; - Cell* next; - - for(next = list, prev = NULL; next != 0; prev = next, next = next->next) { - if (cell <= next) { - break; - } - } - - cell->next = next; - cell->prev = prev; - if (next) { - next->prev = cell; - if ((u8*)cell + cell->size == (u8*)next) { - cell->size += next->size; - next = next->next; - cell->next = next; - if (next) { - next->prev = cell; - } - } - } - if (prev) { - prev->next = cell; - if ((u8*)prev + prev->size == (u8*)cell) { - prev->size += cell->size; - prev->next = next; - if (next) { - next->prev = prev; - } - } - return list; - } - return cell; -} - -static int DLOverlap(Cell* list, void* start, void* end) { - Cell* cell = list; - - while(cell) { - if (((start <= cell) - && (cell < end)) - || ((start < (void* ) ((u8*)cell + cell->size)) - && ((void* ) ((u8*)cell + cell->size) <= end))) { - return 1; - } - cell = cell->next; - } - return 0; -} - -static s32 DLSize(Cell* list) { - Cell* cell; - s32 size; - - size = 0; - cell = list; - - while(cell) { - size += cell->size; - cell = cell->next; - } - - return size; -} - -void* OSAllocFromHeap(int heap, u32 size) { - HeapDesc* hd; - Cell* cell; - Cell* newCell; - s32 leftoverSize; - s32 requested; - - requested = size; - ASSERTMSGLINE(337, HeapArray, "OSAllocFromHeap(): heap is not initialized."); - ASSERTMSGLINE(338, (s32)size > 0, "OSAllocFromHeap(): invalid size."); - ASSERTMSGLINE(339, heap >= 0 && heap < NumHeaps, "OSAllocFromHeap(): invalid heap handle."); - ASSERTMSGLINE(340, HeapArray[heap].size >= 0, "OSAllocFromHeap(): invalid heap handle."); - - hd = &HeapArray[heap]; - size += 0x20; - size = (size + 0x1F) & 0xFFFFFFE0; - - for(cell = hd->free; cell != NULL; cell = cell->next) { - if ((signed)size <= (signed)cell->size) { - break; - } - } - - if (cell == NULL) { -#if DEBUG - OSReport("OSAllocFromHeap: Warning- failed to allocate %d bytes\n", size); -#endif - return NULL; - } - ASSERTMSGLINE(364, !((s32)cell & 0x1F), "OSAllocFromHeap(): heap is broken."); - ASSERTMSGLINE(365, cell->hd == NULL, "OSAllocFromHeap(): heap is broken."); - - leftoverSize = cell->size - size; - if (leftoverSize < 0x40U) { - hd->free = DLExtract(hd->free, cell); - } else { - cell->size = size; - newCell = (void*)((u8*)cell + size); - newCell->size = leftoverSize; -#ifdef ENABLE_HEAPDESC - newCell->hd = 0; -#endif - newCell->prev = cell->prev; - newCell->next = cell->next; - if (newCell->next != NULL) { - newCell->next->prev = newCell; - } - if (newCell->prev != NULL) { - newCell->prev->next = newCell; - } else { - ASSERTMSGLINE(394, hd->free == cell, "OSAllocFromHeap(): heap is broken."); - hd->free = newCell; - } - } - - hd->allocated = DLAddFront(hd->allocated, cell); -#ifdef ENABLE_HEAPDESC - cell->hd = hd; - cell->requested = requested; - hd->headerBytes += 0x20; - hd->paddingBytes += (cell->size - (requested + 0x20)); - hd->payloadBytes += requested; -#endif - return (u8*)cell + 0x20; -} - -void* OSAllocFixed(void* rstart, void* rend) { - int i; - Cell* cell; - Cell* newCell; - HeapDesc* hd; - void* start; - void* end; - void* cellEnd; - - start = (void*)((*(u32*)rstart) & ~((32)-1)); - end = (void*)((*(u32*)rend + 0x1FU) & ~((32)-1)); - - ASSERTMSGLINE(436, HeapArray, "OSAllocFixed(): heap is not initialized."); - ASSERTMSGLINE(437, (u32)start < (u32)end, "OSAllocFixed(): invalid range."); - ASSERTMSGLINE(439, ((u32) ArenaStart <= (u32) start) && ((u32) end <= (u32) ArenaEnd), "OSAllocFixed(): invalid range."); - - for(i = 0; i < NumHeaps; i++) { - hd = &HeapArray[i]; - if(hd->size >= 0) { - if (DLOverlap(hd->allocated, start, end)) { -#if DEBUG - OSReport("OSAllocFixed: Warning - failed to allocate from %p to %p\n", start, end); -#endif - return NULL; - } - } - } - - for(i = 0; i < NumHeaps; i++) { - hd = &HeapArray[i]; - if (hd->size >= 0) { - for(cell = hd->free; cell; cell = cell->next) { - cellEnd = ((u8*)cell + cell->size); - if(cellEnd > start) { - if (end <= cell) { - break; - } - if ((char*)start-0x20 <= (char*)cell && cell < end && (start <= cellEnd) && (cellEnd < ((char*)end + 0x40))) { - if (cell < start) { - start = cell; - } - if (end < cellEnd) { - end = cellEnd; - } - hd->free = DLExtract(hd->free, cell); - hd->size -= cell->size; - } else if((char*)start-0x20 <= (char*)cell && cell < end) { - if (cell < start) { - start = cell; - } - ASSERTLINE(503, MINOBJSIZE <= (char*) cellEnd - (char*) end); - newCell = (Cell*)end; - - newCell->size = (s32) ((char*)cellEnd - (char*)end); -#ifdef ENABLE_HEAPDESC - newCell->hd = 0; -#endif - newCell->next = cell->next; - if (newCell->next) { - newCell->next->prev = newCell; - } - newCell->prev = cell->prev; - if (newCell->prev) { - newCell->prev->next = newCell; - } else { - hd->free = newCell; - } - hd->size -= ((char*)end - (char*)cell); - break; - } else { - if ((start <= cellEnd) && (cellEnd < ((char*)end + 0x40U))) { - if (end < cellEnd) { - end = cellEnd; - } - ASSERTLINE(528, MINOBJSIZE <= (char*) start - (char*) cell); - hd->size -= ((char*)cellEnd - (char*)start); - cell->size = ((char*)start - (char*)cell); - } else { - ASSERTLINE(535, MINOBJSIZE <= (char*) cellEnd - (char*) end); - newCell = (Cell*)end; - newCell->size = ((char*)cellEnd - (char*)end); -#ifdef ENABLE_HEAPDESC - newCell->hd = 0; -#endif - newCell->next = cell->next; - if (newCell->next) { - newCell->next->prev = newCell; - } - newCell->prev = cell; - cell->next = newCell; - cell->size = ((char*)start - (char*)cell); - hd->size -= ((char*)end - (char*)start); - break; - } - } - } - } - ASSERTLINE(550, 0 <= hd->size); - } - } - ASSERTLINE(553, OFFSET(start, ALIGNMENT) == 0); - ASSERTLINE(554, OFFSET(end, ALIGNMENT) == 0); - ASSERTLINE(555, start < end); - *(u32*)rstart = (u32)start; - *(u32*)rend = (u32)end; - return (void*)*(u32*)rstart; -} - -void OSFreeToHeap(int heap, void* ptr) { - HeapDesc* hd; - Cell* cell; - - ASSERTMSGLINE(577, HeapArray, "OSFreeToHeap(): heap is not initialized."); - ASSERTMSGLINE(579, ((u32)ArenaStart+0x20) <= (u32)ptr && (u32)ptr < (u32)ArenaEnd, "OSFreeToHeap(): invalid pointer."); - ASSERTMSGLINE(580, OFFSET(ptr, ALIGNMENT) == 0, "OSFreeToHeap(): invalid pointer."); - ASSERTMSGLINE(581, HeapArray[heap].size >= 0, "OSFreeToHeap(): invalid heap handle."); - cell = (void*)((u32)ptr-0x20); - hd = &HeapArray[heap]; - ASSERTMSGLINE(586, cell->hd == hd, "OSFreeToHeap(): invalid pointer."); - ASSERTMSGLINE(587, DLLookup(hd->allocated, cell), "OSFreeToHeap(): invalid pointer."); -#ifdef ENABLE_HEAPDESC - cell->hd = 0; - hd->headerBytes -= 0x20; - hd->paddingBytes -= (cell->size - (cell->requested + 0x20)); - hd->payloadBytes -= cell->requested; -#endif - hd->allocated = DLExtract(hd->allocated, cell); - hd->free = DLInsert(hd->free, cell); -} - -int OSSetCurrentHeap(int heap) { - int prev; - - ASSERTMSGLINE(619, HeapArray, "OSSetCurrentHeap(): heap is not initialized."); - ASSERTMSGLINE(620, (heap >= 0) && (heap < NumHeaps), "OSSetCurrentHeap(): invalid heap handle."); - ASSERTMSGLINE(621, HeapArray[heap].size >= 0, "OSSetCurrentHeap(): invalid heap handle."); - prev = __OSCurrHeap; - __OSCurrHeap = heap; - return prev; -} - -void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps) { - u32 arraySize; - int i; - HeapDesc* hd; - - ASSERTMSGLINE(647, maxHeaps > 0, "OSInitAlloc(): invalid number of heaps."); - ASSERTMSGLINE(649, (u32)arenaStart < (u32)arenaEnd, "OSInitAlloc(): invalid range."); - ASSERTMSGLINE(652, maxHeaps <= (((u32)arenaEnd - (u32)arenaStart) / 24U), "OSInitAlloc(): too small range."); - arraySize = maxHeaps * sizeof(HeapDesc); - HeapArray = arenaStart; - NumHeaps = maxHeaps; - - for(i = 0; i < NumHeaps; i++) { - hd = &HeapArray[i]; - hd->size = -1; - hd->free = hd->allocated = 0; -#ifdef ENABLE_HEAPDESC - hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; -#endif - } - __OSCurrHeap = -1; - arenaStart = (void*) ((u32)((char*)HeapArray + arraySize)); - arenaStart = (void*) (((u32)arenaStart + 0x1F) & 0xFFFFFFE0); - ArenaStart = arenaStart; - ArenaEnd = (void*) ((u32)arenaEnd & 0xFFFFFFE0); - ASSERTMSGLINE(680, ((u32)ArenaEnd - (u32)ArenaStart) >= 0x40U, "OSInitAlloc(): too small range."); - return arenaStart; -} - -int OSCreateHeap(void* start, void* end) { - int heap; - HeapDesc* hd; - Cell* cell; - - ASSERTMSGLINE(705, HeapArray, "OSCreateHeap(): heap is not initialized."); - ASSERTMSGLINE(706, (u32)start < (u32)end, "OSCreateHeap(): invalid range."); - - start = (void*)(((u32)start + 0x1FU) & ~((32)-1)); - end = (void*)(((u32)end) & ~((32)-1)); - - ASSERTMSGLINE(709, (u32)start < (u32)end, "OSCreateHeap(): invalid range."); - ASSERTMSGLINE(711, (u32)ArenaStart <= (u32)start && (u32)end <= (u32)ArenaEnd, "OSCreateHeap(): invalid range."); - ASSERTMSGLINE(713, ((u32)end - (u32)start) >= 0x40U, "OSCreateHeap(): too small range."); - -#if DEBUG - for(heap = 0; heap < NumHeaps; heap++) { - if (HeapArray[heap].size >= 0) { - ASSERTMSGLINE(723, !DLOverlap(HeapArray[heap].free, start, end), "OSCreateHeap(): invalid range."); - ASSERTMSGLINE(725, !DLOverlap(HeapArray[heap].allocated, start, end), "OSCreateHeap(): invalid range."); - } - } -#endif - - for(heap = 0; heap < NumHeaps; heap++) { - hd = &HeapArray[heap]; - if (hd->size < 0) { - hd->size = (u32)end - (u32)start; - cell = start; - cell->prev = 0; - cell->next = 0; - cell->size = hd->size; -#ifdef ENABLE_HEAPDESC - cell->hd = 0; -#endif - hd->free = cell; - hd->allocated = 0; -#ifdef ENABLE_HEAPDESC - hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; -#endif - return heap; - } - } -#if DEBUG - OSReport("OSCreateHeap: Warning - Failed to find free heap descriptor."); -#endif - return -1; -} - -void OSDestroyHeap(int heap) { - HeapDesc* hd; - s32 size; - - ASSERTMSGLINE(782, HeapArray, "OSDestroyHeap(): heap is not initialized."); - ASSERTMSGLINE(783, (heap >= 0) && (heap < NumHeaps), "OSDestroyHeap(): invalid heap handle."); - ASSERTMSGLINE(784, HeapArray[heap].size >= 0, "OSDestroyHeap(): invalid heap handle."); - - hd = &HeapArray[heap]; -#if DEBUG - size = DLSize(hd->free); - - if (hd->size != size) { - OSReport("OSDestroyHeap(%d): Warning - free list size %d, heap size %d\n", heap, size, hd->size); - } -#endif - - hd->size = -1; - hd->free = hd->allocated = 0; -#ifdef ENABLE_HEAPDESC - hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; - if (__OSCurrHeap == heap) { - __OSCurrHeap = -1; - } -#endif -} - -void OSAddToHeap(int heap, void* start, void* end) { - HeapDesc* hd; - Cell* cell; - int i; - - ASSERTMSGLINE(830, HeapArray, "OSAddToHeap(): heap is not initialized."); - ASSERTMSGLINE(831, (heap >= 0) && (heap < NumHeaps), "OSAddToHeap(): invalid heap handle."); - ASSERTMSGLINE(832, HeapArray[heap].size >= 0, "OSAddToHeap(): invalid heap handle."); - - hd = &HeapArray[heap]; - - ASSERTMSGLINE(836, (u32)start < (u32)end, "OSAddToHeap(): invalid range."); - - start = (void*)(((u32)start + 0x1F) & ~((32)-1)); - end = (void*)(((u32)end) & ~((32)-1)); - - ASSERTMSGLINE(840, ((u32)end - (u32)start) >= 0x40U, "OSAddToHeap(): too small range."); - ASSERTMSGLINE(842, (u32)ArenaStart <= (u32)start && (u32)end <= (u32)ArenaEnd, "OSAddToHeap(): invalid range."); - -#if DEBUG - for(i = 0; i < NumHeaps; i++) { - if (HeapArray[i].size >= 0) { - ASSERTMSGLINE(852, !DLOverlap(HeapArray[i].free, start, end), "OSAddToHeap(): invalid range."); - ASSERTMSGLINE(854, !DLOverlap(HeapArray[i].allocated, start, end), "OSAddToHeap(): invalid range."); - } - } -#endif - cell = (Cell*)start; - cell->size = ((char*)end - (char*)start); -#ifdef ENABLE_HEAPDESC - cell->hd = 0; -#endif - hd->size += cell->size; - hd->free = DLInsert(hd->free, cell); -} - -// custom macro for OSCheckHeap -#define ASSERTREPORT(line, cond) \ - if (!(cond)) { OSReport("OSCheckHeap: Failed " #cond " in %d", line); return -1; } - -s32 OSCheckHeap(int heap) { - HeapDesc* hd; - Cell* cell; - s32 total = 0; - s32 free = 0; - - ASSERTREPORT(898, HeapArray); - ASSERTREPORT(899, 0 <= heap && heap < NumHeaps); - hd = &HeapArray[heap]; - ASSERTREPORT(902, 0 <= hd->size); - - ASSERTREPORT(0x388, hd->allocated == NULL || hd->allocated->prev == NULL); - - for(cell = hd->allocated; cell; cell = cell->next) { - ASSERTREPORT(907, InRange(cell, ArenaStart, ArenaEnd)); - ASSERTREPORT(908, OFFSET(cell, ALIGNMENT) == 0); - ASSERTREPORT(909, cell->next == NULL || cell->next->prev == cell); - ASSERTREPORT(910, MINOBJSIZE <= cell->size); - ASSERTREPORT(911, OFFSET(cell->size, ALIGNMENT) == 0); - total += cell->size; - ASSERTREPORT(914, 0 < total && total <= hd->size); -#ifdef ENABLE_HEAPDESC - ASSERTREPORT(917, cell->hd == hd); - ASSERTREPORT(918, HEADERSIZE + cell->requested <= cell->size); -#endif - } - - - ASSERTREPORT(922, hd->free == NULL || hd->free->prev == NULL); - - for(cell = hd->free; cell; cell = cell->next) { - ASSERTREPORT(925, InRange(cell, ArenaStart, ArenaEnd)); - ASSERTREPORT(926, OFFSET(cell, ALIGNMENT) == 0); - ASSERTREPORT(927, cell->next == NULL || cell->next->prev == cell); - ASSERTREPORT(928, MINOBJSIZE <= cell->size); - ASSERTREPORT(929, OFFSET(cell->size, ALIGNMENT) == 0); - ASSERTREPORT(930, cell->next == NULL || (char*) cell + cell->size < (char*) cell->next); - total += cell->size; - free = (cell->size + free); - free -= HEADERSIZE; - ASSERTREPORT(934, 0 < total && total <= hd->size); -#ifdef ENABLE_HEAPDESC - ASSERTREPORT(937, cell->hd == NULL); -#endif - } - ASSERTREPORT(941, total == hd->size); - return free; -} - -u32 OSReferentSize(void* ptr) { - Cell* cell; - - ASSERTMSGLINE(960, HeapArray, "OSReferentSize(): heap is not initialized."); - ASSERTMSGLINE(962, InRange(ptr, ArenaStart+HEADERSIZE, ArenaEnd), "OSReferentSize(): invalid pointer."); - ASSERTMSGLINE(963, !OFFSET(ptr, 32), "OSReferentSize(): invalid pointer."); - cell = (void*)((u32)ptr-HEADERSIZE); - ASSERTMSGLINE(967, cell->hd, "OSReferentSize(): invalid pointer."); - ASSERTMSGLINE(969, !(((u32)cell->hd - (u32)HeapArray) % 24), "OSReferentSize(): invalid pointer."); - ASSERTMSGLINE(971, ((u32)HeapArray <= (u32)cell->hd) && ((u32)cell->hd < (u32)((u32)HeapArray + (NumHeaps * 0x18))), "OSReferentSize(): invalid pointer."); - ASSERTMSGLINE(972, cell->hd->size >= 0, "OSReferentSize(): invalid pointer."); - ASSERTMSGLINE(974, DLLookup(cell->hd->allocated, cell), "OSReferentSize(): invalid pointer."); - return (s32)((u32)cell->size-HEADERSIZE); -} - -void OSDumpHeap(int heap) { - HeapDesc* hd; - Cell* cell; - - OSReport("\nOSDumpHeap(%d):\n", heap); - ASSERTMSGLINE(995, HeapArray, "OSDumpHeap(): heap is not initialized."); - ASSERTMSGLINE(996, (heap >= 0) && (heap < NumHeaps), "OSDumpHeap(): invalid heap handle."); - hd = &HeapArray[heap]; - if (hd->size < 0) { - OSReport("--------Inactive\n"); - return; - } - ASSERTMSGLINE(1005, OSCheckHeap(heap) >= 0, "OSDumpHeap(): heap is broken."); -#ifdef ENABLE_HEAPDESC - OSReport("padding %d/(%f%%) header %d/(%f%%) payload %d/(%f%%)\n", - hd->paddingBytes, (100.0 * hd->paddingBytes / hd->size), hd->headerBytes, (100.0 * hd->headerBytes / hd->size), hd->payloadBytes, - (100.0 * hd->payloadBytes / hd->size)); -#endif - OSReport("addr size end prev next\n"); - OSReport("--------Allocated\n"); - - ASSERTMSGLINE(1018, hd->allocated == NULL || hd->allocated->prev == NULL, "OSDumpHeap(): heap is broken."); - - for(cell = hd->allocated; cell; cell = cell->next) { - OSReport("%x %d %x %x %x\n", cell, cell->size, (char*)cell + cell->size, cell->prev, cell->next); - } - OSReport("--------Free\n"); - for(cell = hd->free; cell; cell = cell->next) { - OSReport("%x %d %x %x %x\n", cell, cell->size, (char*)cell + cell->size, cell->prev, cell->next); - } -} - -void OSVisitAllocated(void (*visitor)(void*, u32)) { - u32 heap; - Cell* cell; - - for(heap = 0; heap < NumHeaps; heap++) { - if (HeapArray[heap].size >= 0) { - for(cell = HeapArray[heap].allocated; cell; cell = cell->next) { - visitor((char*)cell+HEADERSIZE, cell->size); - } - } - } -} diff --git a/src/dolphin/os/OSArena.c b/src/dolphin/os/OSArena.c deleted file mode 100644 index ab7b5fe..0000000 --- a/src/dolphin/os/OSArena.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) -#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) - -static void* __OSArenaHi; -static void* __OSArenaLo = (void*)-1; - -void* OSGetArenaHi(void) { - ASSERTMSGLINE(55, (u32)__OSArenaLo != -1, "OSGetArenaHi(): OSInit() must be called in advance."); - ASSERTMSGLINE(57, (u32)__OSArenaLo <= (u32)__OSArenaHi, "OSGetArenaHi(): invalid arena (hi < lo)."); - return __OSArenaHi; -} - -void* OSGetArenaLo(void) { - ASSERTMSGLINE(73, (u32)__OSArenaLo != -1, "OSGetArenaLo(): OSInit() must be called in advance."); - ASSERTMSGLINE(75, (u32)__OSArenaLo <= (u32)__OSArenaHi, "OSGetArenaLo(): invalid arena (hi < lo)."); - return __OSArenaLo; -} - -void OSSetArenaHi(void* newHi) { - __OSArenaHi = newHi; -} - -void OSSetArenaLo(void* newLo) { - __OSArenaLo = newLo; -} - -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; -} diff --git a/src/dolphin/os/OSAudioSystem.c b/src/dolphin/os/OSAudioSystem.c deleted file mode 100644 index 3ffd440..0000000 --- a/src/dolphin/os/OSAudioSystem.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include - -#include "__os.h" - -static u8 DSPInitCode[128] = { - 0x02, 0x9F, 0x00, 0x10, 0x02, 0x9F, 0x00, 0x33, 0x02, 0x9F, 0x00, 0x34, 0x02, 0x9F, 0x00, 0x35, - 0x02, 0x9F, 0x00, 0x36, 0x02, 0x9F, 0x00, 0x37, 0x02, 0x9F, 0x00, 0x38, 0x02, 0x9F, 0x00, 0x39, - 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 -}; - -#define __DSPWorkBuffer (void*)0x81000000 - -void __OSInitAudioSystem(void) { - u8 errFlag; - u16 reg16; - u32 start_tick; - - memcpy((void*)((u32)OSGetArenaHi() - 0x80), __DSPWorkBuffer, sizeof(DSPInitCode)); - memcpy(__DSPWorkBuffer, (void*)DSPInitCode, sizeof(DSPInitCode)); - DCFlushRange(__DSPWorkBuffer, sizeof(DSPInitCode)); - - __DSPRegs[9] = 0x43; - ASSERTMSGLINE(113, !(__DSPRegs[5] & 0x200), "__OSInitAudioSystem(): ARAM DMA already in progress"); - ASSERTMSGLINE(117, !(__DSPRegs[5] & 0x400), "__OSInitAudioSystem(): DSP DMA already in progress"); - ASSERTMSGLINE(121, (__DSPRegs[5] & 0x004), "__OSInitAudioSystem(): DSP already working"); - - __DSPRegs[5] = 0x8AC; - __DSPRegs[5] |= 1; - - while (__DSPRegs[5] & 1); - __DSPRegs[0] = 0; - - while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000); - - *(u32*)&__DSPRegs[16] = 0x1000000; - *(u32*)&__DSPRegs[18] = 0; - *(u32*)&__DSPRegs[20] = 0x20; - - reg16 = __DSPRegs[5]; - while (!(reg16 & 0x20)) - reg16 = __DSPRegs[5]; - - __DSPRegs[5] = reg16; - - start_tick = OSGetTick(); - while ((s32)(OSGetTick() - start_tick) < 0x892); - - *(u32*)&__DSPRegs[16] = 0x1000000; - *(u32*)&__DSPRegs[18] = 0; - *(u32*)&__DSPRegs[20] = 0x20; - - reg16 = __DSPRegs[5]; - while (!(reg16 & 0x20)) { - reg16 = __DSPRegs[5]; - } - __DSPRegs[5] = reg16; - - __DSPRegs[5] &= ~0x800; - while ((__DSPRegs[5]) & 0x400); - - __DSPRegs[5] &= ~4; - errFlag = 0; - - reg16 = __DSPRegs[2]; - - while (!(reg16 & 0x8000)) { - reg16 = __DSPRegs[2]; - } - - if(((u32)((reg16 << 16) | __DSPRegs[3]) + 0x7FAC0000U) != 0x4348) { - ASSERTMSGLINE(193, 0, "__OSInitAudioSystem(): DSP returns invalid message"); - } - - reg16 != 0x81800; // fake but fixes reg alloc on retail - __DSPRegs[5] |= 4; - __DSPRegs[5] = 0x8AC; - __DSPRegs[5] |= 1; - while (__DSPRegs[5] & 1); - - memcpy(__DSPWorkBuffer, (void*)((u32)OSGetArenaHi() - 0x80), sizeof(DSPInitCode)); -} - -void __OSStopAudioSystem(void) { - u16 reg16; - u32 start_tick; - - #define waitUntil(load, mask) \ - reg16 = (load); \ - while (reg16 & (mask)) { \ - reg16 = (load); \ - } - - __DSPRegs[5] = 0x804; - reg16 = __DSPRegs[27]; - __DSPRegs[27] = reg16 & ~0x8000; - waitUntil(__DSPRegs[5], 0x400); - waitUntil(__DSPRegs[5], 0x200); - __DSPRegs[5] = 0x8ac; - __DSPRegs[0] = 0; - - while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000); - - start_tick = OSGetTick(); - while ((s32)(OSGetTick() - start_tick) < 0x2c); - - reg16 = __DSPRegs[5]; - __DSPRegs[5] = reg16 | 1; - waitUntil(__DSPRegs[5], 0x001); - - #undef waitUntil -} diff --git a/src/dolphin/os/OSCache.c b/src/dolphin/os/OSCache.c deleted file mode 100644 index b09cfbb..0000000 --- a/src/dolphin/os/OSCache.c +++ /dev/null @@ -1,643 +0,0 @@ -#include -#include -#include - -#include "__os.h" - -#define HID2 920 - -// prototypes -void DMAErrorHandler(OSError error, OSContext* context, ...); - -#ifdef __GEKKO__ -asm void DCFlashInvalidate(void) { - nofralloc - mfspr r3, HID0 - ori r3, r3, 0x400 - mtspr HID0, r3 - blr -} - -asm void DCEnable(void) { - nofralloc - sync - mfspr r3, HID0 - ori r3, r3, 0x4000 - mtspr HID0, r3 - blr -} - -asm void DCDisable(void) { - nofralloc - sync - mfspr r3, HID0 - rlwinm r3, r3, 0, 18, 16 - mtspr HID0, r3 - blr -} - -asm void DCFreeze(void) { - nofralloc - sync - mfspr r3, HID0 - ori r3, r3, 0x1000 - mtspr HID0, r3 - blr -} - -asm void DCUnfreeze(void) { - nofralloc - mfspr r3, HID0 - rlwinm r3, r3, 0, 20, 18 - mtspr HID0, r3 - blr -} - -asm void DCTouchLoad(register void* addr) { - nofralloc - dcbt r0, addr - blr -} - -asm void DCBlockZero(register void* addr) { - nofralloc - dcbz r0, addr - blr -} - -asm void DCBlockStore(register void* addr) { - nofralloc - dcbst r0, addr - blr -} - -asm void DCBlockFlush(register void* addr) { - nofralloc - dcbf r0, addr - blr -} - -asm void DCBlockInvalidate(register void* addr) { - nofralloc - dcbi r0, addr - blr -} - -asm void DCInvalidateRange(register void* addr, register u32 nBytes) { - nofralloc - cmplwi nBytes, 0 - blelr - clrlwi r5, addr, 27 - add nBytes, nBytes, r5 - addi nBytes, nBytes, 31 - srwi nBytes, nBytes, 5 - mtctr nBytes - -@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 DCTouchRange(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 - dcbt r0, addr - addi addr, addr, 32 - bdnz @1 - - blr -} - -asm void ICInvalidateRange(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 - icbi r0, addr - addi addr, addr, 32 - bdnz @1 - sync - isync - - blr -} - -asm void ICFlashInvalidate(void) { - nofralloc - mfspr r3, HID0 - ori r3, r3, 0x800 - mtspr HID0, r3 - blr -} - -asm void ICEnable(void) { - nofralloc - isync - mfspr r3, HID0 - ori r3, r3, 0x8000 - mtspr HID0, r3 - blr -} - -asm void ICDisable(void) { - nofralloc - isync - mfspr r3, HID0 - rlwinm r3, r3, 0, 17, 15 - mtspr HID0, r3 - blr -} - -asm void ICFreeze(void) { - nofralloc - isync - mfspr r3, HID0 - ori r3, r3, 0x2000 - mtspr HID0, r3 - blr -} - -asm void ICUnfreeze(void) { - nofralloc - mfspr r3, HID0 - rlwinm r3, r3, 0, 19, 17 - mtspr HID0, r3 - blr -} - -asm void ICBlockInvalidate(register void* addr) { - nofralloc - icbi r0, addr - blr -} - -asm void ICSync(void) { - nofralloc - isync - blr -} - -#define LC_LINES 512 -#define CACHE_LINES 1024 - -static asm void __LCEnable(void) { - nofralloc - mfmsr r5 - ori r5, r5, 0x1000 - mtmsr r5 - - lis r3, OS_CACHED_REGION_PREFIX - li r4, CACHE_LINES - mtctr r4 -_touchloop: - dcbt 0,r3 - dcbst 0,r3 - addi r3,r3,32 - bdnz _touchloop - mfspr r4, HID2 - oris r4, r4, 0x100F - mtspr HID2, r4 - - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - lis r3, LC_BASE_PREFIX - ori r3, r3, 0x0002 - mtspr DBAT3L, r3 - ori r3, r3, 0x01fe - mtspr DBAT3U, r3 - isync - lis r3, LC_BASE_PREFIX - li r6, LC_LINES - mtctr r6 - li r6, 0 - -_lockloop: - dcbz_l r6, r3 - addi r3, r3, 32 - bdnz+ _lockloop - - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - - blr -} - -void LCEnable(void) { - BOOL enabled; - - enabled = OSDisableInterrupts(); - __LCEnable(); - OSRestoreInterrupts(enabled); -} - -asm void LCDisable(void) { - 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 LCAllocOneTag(register BOOL invalidate, register void* tag) { - nofralloc - cmpwi invalidate, 0 - beq @1 - dcbi r0, tag -@1 - dcbz_l r0, tag - blr -} - -asm void LCAllocTags(register BOOL invalidate, register void* startTag, register u32 numBlocks) { - nofralloc - mflr r6 - cmplwi numBlocks, 0 - ble @3 - mtctr numBlocks - cmpwi invalidate, 0 - beq @2 -@1 - dcbi r0, startTag - dcbz_l r0, startTag - addi startTag, startTag, 32 - bdnz @1 - b @3 -@2 - dcbz_l r0, startTag - addi startTag, startTag, 32 - bdnz @2 -@3 - mtlr r6 - blr -} - -asm void LCLoadBlocks(register void* destTag, register void* srcAddr, register u32 numBlocks) { - nofralloc - rlwinm r6, numBlocks, 30, 27, 31 - rlwinm srcAddr, srcAddr, 0, 4, 31 - or r6, r6, srcAddr - mtspr DMA_U, r6 - rlwinm r6, numBlocks, 2, 28, 29 - or r6, r6, destTag - ori r6, r6, 0x12 - mtspr DMA_L, r6 - blr -} - -asm void LCStoreBlocks(register void* destAddr, register void* srcTag, register u32 numBlocks) { - nofralloc - rlwinm r6, numBlocks, 30, 27, 31 - rlwinm destAddr, destAddr, 0, 4, 31 - or r6, r6, destAddr - mtspr DMA_U, r6 - rlwinm r6, numBlocks, 2, 28, 29 - or r6, r6, srcTag - ori r6, r6, 0x2 - mtspr DMA_L, r6 - blr -} -#endif - -void LCAlloc(void* addr, u32 nBytes) { - u32 numBlocks = nBytes >> 5; - u32 hid2 = PPCMfhid2(); - - ASSERTMSGLINE(1319, !((u32)addr & 31), "LCAlloc(): addr must be 32 byte aligned"); - ASSERTMSGLINE(1321, !((u32)nBytes & 31), "LCAlloc(): nBytes must be 32 byte aligned"); - - if ((hid2 & 0x10000000) == 0) { - LCEnable(); - } - LCAllocTags(TRUE, addr, numBlocks); -} - -void LCAllocNoInvalidate(void* addr, u32 nBytes) { - u32 numBlocks = nBytes >> 5; - u32 hid2 = PPCMfhid2(); - - ASSERTMSGLINE(1366, !((u32)addr & 31), "LCAllocNoFlush(): addr must be 32 byte aligned"); - ASSERTMSGLINE(1368, !((u32)nBytes & 31), "LCAllocNoFlush(): nBytes must be 32 byte aligned"); - - if ((hid2 & 0x10000000) == 0) { - LCEnable(); - } - LCAllocTags(FALSE, addr, numBlocks); -} - -u32 LCLoadData(void* destAddr, void* srcAddr, u32 nBytes) { - u32 numBlocks = (nBytes + 31) / 32; - u32 numTransactions = (numBlocks + 128 - 1) / 128; - - ASSERTMSGLINE(1426, !((u32)srcAddr & 31), "LCLoadData(): srcAddr not 32 byte aligned"); - ASSERTMSGLINE(1428, !((u32)destAddr & 31), "LCLoadData(): destAddr not 32 byte aligned"); - - while (numBlocks > 0) { - if (numBlocks < 128) { - LCLoadBlocks(destAddr, srcAddr, numBlocks); - numBlocks = 0; - } else { - 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; - - ASSERTMSGLINE(1494, !((u32)srcAddr & 31), "LCStoreData(): srcAddr not 32 byte aligned"); - ASSERTMSGLINE(1496, !((u32)destAddr & 31), "LCStoreData(): destAddr not 32 byte aligned"); - - while (numBlocks > 0) { - if (numBlocks < 128) { - LCStoreBlocks(destAddr, srcAddr, numBlocks); - numBlocks = 0; - } else { - LCStoreBlocks(destAddr, srcAddr, 0); - numBlocks -= 128; - destAddr = (void*)((u32)destAddr + 4096); - srcAddr = (void*)((u32)srcAddr + 4096); - } - } - - return numTransactions; -} - -#ifdef __GEKKO__ -asm u32 LCQueueLength(void) { - nofralloc - mfspr r4, HID2 - rlwinm r3, r4, 8, 28, 31 - blr -} - -asm void LCQueueWait(register u32 len) { - nofralloc -@1 - mfspr r4, HID2 - rlwinm r4, r4, 8, 28, 31 - cmpw r4, r3 - bgt @1 - blr -} -#endif - -void LCFlushQueue() { - union { - u32 val; - struct { - u32 lcAddr : 27; - u32 dmaLd : 1; - u32 dmaLenL : 2; - u32 dmaTrigger : 1; - u32 dmaFlush : 1; - } f; - } dmaL; - - dmaL.val = 0; - dmaL.f.dmaFlush = 1; - PPCMtdmaU(0); - PPCMtdmaL(dmaL.val); - PPCSync(); -} - -static void L2Init(void) { - u32 oldMSR; - oldMSR = PPCMfmsr(); - __sync(); - PPCMtmsr(MSR_IR | MSR_DR); - __sync(); - L2Disable(); - L2GlobalInvalidate(); - PPCMtmsr(oldMSR); -} - -void L2Enable(void) { - PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); -} - -void L2Disable(void) { - __sync(); - PPCMtl2cr(PPCMfl2cr() & ~0x80000000); - __sync(); -} - -void L2GlobalInvalidate(void) { - L2Disable(); - PPCMtl2cr(PPCMfl2cr() | 0x00200000); - while (PPCMfl2cr() & 0x00000001u); - - PPCMtl2cr(PPCMfl2cr() & ~0x00200000); - while (PPCMfl2cr() & 0x00000001u) { - DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); - } -} - -void L2SetDataOnly(BOOL dataOnly) { - if (dataOnly) { - PPCMtl2cr(PPCMfl2cr() | 0x400000); - return; - } - PPCMtl2cr(PPCMfl2cr() & 0xFFBFFFFF); -} - -void L2SetWriteThrough(BOOL writeThrough) { - if (writeThrough) { - PPCMtl2cr(PPCMfl2cr() | 0x80000); - return; - } - PPCMtl2cr(PPCMfl2cr() & 0xFFF7FFFF); -} - -void DMAErrorHandler(OSError error, OSContext* context, ...) { - u32 hid2 = PPCMfhid2(); - - OSReport("Machine check received\n"); - OSReport("HID2 = 0x%x SRR1 = 0x%x\n", hid2, context->srr1); - if (!(hid2 & (HID2_DCHERR | HID2_DNCERR | HID2_DCMERR | HID2_DQOERR)) || !(context->srr1 & SRR1_DMA_BIT)) { - 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/src/dolphin/os/OSContext.c b/src/dolphin/os/OSContext.c deleted file mode 100644 index a0c49b8..0000000 --- a/src/dolphin/os/OSContext.c +++ /dev/null @@ -1,626 +0,0 @@ -#include -#include - -#include "__os.h" - -// external functions -extern void __RAS_OSDisableInterrupts_begin(); -extern void __RAS_OSDisableInterrupts_end(); -extern void DBPrintf(char*, ...); - -#define HID2 920 - -volatile OSContext* __OSCurrentContext AT_ADDRESS(OS_BASE_CACHED | 0x00D4); -volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED | 0x00D8); - -#ifdef __GEKKO__ -static asm void __OSLoadFPUContext(register u32 dummy, register OSContext* fpucontext) { - nofralloc - lhz r5, fpucontext->state; - clrlwi. r5, r5, 31 - beq _return - - 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 -} - -static asm void __OSSaveFPUContext(register u32 dummy1, register u32 dummy2, register OSContext* fpucontext) { - 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 -} - -asm void OSLoadFPUContext(register OSContext* fpucontext) { - nofralloc - addi r4, fpucontext, 0 - b __OSLoadFPUContext -} - -asm void OSSaveFPUContext(register OSContext* fpucontext) { - nofralloc - addi r5, fpucontext, 0 - b __OSSaveFPUContext -} - -asm void OSSetCurrentContext(register OSContext* context){ - 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 -} -#endif - -OSContext* OSGetCurrentContext(void) { - return (OSContext*)__OSCurrentContext; -} - -#ifdef __GEKKO__ -asm u32 OSSaveContext(register OSContext* context) { - 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 -} - -asm void OSLoadContext(register OSContext* context) { - 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 -} - -asm u32 OSGetStackPointer() { - nofralloc - mr r3, r1 - blr -} - -asm u32 OSSwitchStack(register u32 newsp) { - nofralloc - mr r5, r1 - mr r1, newsp - mr r3, r5 - blr -} - -asm int OSSwitchFiber(register u32 pc, register u32 newsp) { - nofralloc - mflr r0 - mr r5, r1 - stwu r5, -8(newsp) - mr r1, newsp - stw r0, 4(r5) - mtlr pc - blrl - lwz r5, 0(r1) - lwz r0, 4(r5) - mtlr r0 - mr r1, r5 - blr -} -#endif - -void OSClearContext(register OSContext* context) { - context->mode = 0; - context->state = 0; - if (context == __OSFPUContext) - __OSFPUContext = NULL; -} - -#ifdef __GEKKO__ -asm void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) { - nofralloc - - stw pc, OS_CONTEXT_SRR0(context) - stw newsp, OS_CONTEXT_R1(context) - li r11, 0 - ori r11, r11, 0x00008000 | 0x00000020 | 0x00000010 | 0x00000002 | 0x00001000 - stw r11, OS_CONTEXT_SRR1(context) - li r0, 0x0 - stw r0, OS_CONTEXT_CR(context) - stw r0, OS_CONTEXT_XER(context) - - - stw r2, OS_CONTEXT_R2(context) - stw r13, OS_CONTEXT_R13(context) - - stw r0, OS_CONTEXT_R3(context) - stw r0, OS_CONTEXT_R4(context) - stw r0, OS_CONTEXT_R5(context) - stw r0, OS_CONTEXT_R6(context) - stw r0, OS_CONTEXT_R7(context) - stw r0, OS_CONTEXT_R8(context) - stw r0, OS_CONTEXT_R9(context) - stw r0, OS_CONTEXT_R10(context) - stw r0, OS_CONTEXT_R11(context) - stw r0, OS_CONTEXT_R12(context) - - stw r0, OS_CONTEXT_R14(context) - stw r0, OS_CONTEXT_R15(context) - stw r0, OS_CONTEXT_R16(context) - stw r0, OS_CONTEXT_R17(context) - stw r0, OS_CONTEXT_R18(context) - stw r0, OS_CONTEXT_R19(context) - stw r0, OS_CONTEXT_R20(context) - stw r0, OS_CONTEXT_R21(context) - stw r0, OS_CONTEXT_R22(context) - stw r0, OS_CONTEXT_R23(context) - stw r0, OS_CONTEXT_R24(context) - stw r0, OS_CONTEXT_R25(context) - stw r0, OS_CONTEXT_R26(context) - stw r0, OS_CONTEXT_R27(context) - stw r0, OS_CONTEXT_R28(context) - stw r0, OS_CONTEXT_R29(context) - stw r0, OS_CONTEXT_R30(context) - stw r0, OS_CONTEXT_R31(context) - - stw r0, OS_CONTEXT_GQR0(context) - stw r0, OS_CONTEXT_GQR1(context) - stw r0, OS_CONTEXT_GQR2(context) - stw r0, OS_CONTEXT_GQR3(context) - stw r0, OS_CONTEXT_GQR4(context) - stw r0, OS_CONTEXT_GQR5(context) - stw r0, OS_CONTEXT_GQR6(context) - stw r0, OS_CONTEXT_GQR7(context) - - b OSClearContext -} -#endif - -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]); - } -} - -#ifdef __GEKKO__ -static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) { - 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 -} -#endif - -void __OSContextInit(void) { - __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); - __OSFPUContext = NULL; - DBPrintf("FPU-unavailable handler installed\n"); -} - -#ifdef __GEKKO__ -asm void OSFillFPUContext(register OSContext* context) { - nofralloc - mfmsr r5 - ori r5, r5, 0x2000 - mtmsr r5 - isync - - stfd fp0, context->fpr[0] - stfd fp1, context->fpr[1] - stfd fp2, context->fpr[2] - stfd fp3, context->fpr[3] - stfd fp4, context->fpr[4] - stfd fp5, context->fpr[5] - stfd fp6, context->fpr[6] - stfd fp7, context->fpr[7] - stfd fp8, context->fpr[8] - stfd fp9, context->fpr[9] - stfd fp10, context->fpr[10] - stfd fp11, context->fpr[11] - stfd fp12, context->fpr[12] - stfd fp13, context->fpr[13] - stfd fp14, context->fpr[14] - stfd fp15, context->fpr[15] - stfd fp16, context->fpr[16] - stfd fp17, context->fpr[17] - stfd fp18, context->fpr[18] - stfd fp19, context->fpr[19] - stfd fp20, context->fpr[20] - stfd fp21, context->fpr[21] - stfd fp22, context->fpr[22] - stfd fp23, context->fpr[23] - stfd fp24, context->fpr[24] - stfd fp25, context->fpr[25] - stfd fp26, context->fpr[26] - stfd fp27, context->fpr[27] - stfd fp28, context->fpr[28] - stfd fp29, context->fpr[29] - stfd fp30, context->fpr[30] - stfd fp31, context->fpr[31] - - mffs fp0 - stfd fp0, OS_CONTEXT_FPSCR(context) - - lfd fp0, context->fpr[0] - - mfspr r5, HID2 - rlwinm. r5, r5, 3, 31, 31 - bc 12, 2, _return - - psq_st fp0, OS_CONTEXT_PSF0(context), 0, 0 - psq_st fp1, OS_CONTEXT_PSF1(context), 0, 0 - psq_st fp2, OS_CONTEXT_PSF2(context), 0, 0 - psq_st fp3, OS_CONTEXT_PSF3(context), 0, 0 - psq_st fp4, OS_CONTEXT_PSF4(context), 0, 0 - psq_st fp5, OS_CONTEXT_PSF5(context), 0, 0 - psq_st fp6, OS_CONTEXT_PSF6(context), 0, 0 - psq_st fp7, OS_CONTEXT_PSF7(context), 0, 0 - psq_st fp8, OS_CONTEXT_PSF8(context), 0, 0 - psq_st fp9, OS_CONTEXT_PSF9(context), 0, 0 - psq_st fp10, OS_CONTEXT_PSF10(context), 0, 0 - psq_st fp11, OS_CONTEXT_PSF11(context), 0, 0 - psq_st fp12, OS_CONTEXT_PSF12(context), 0, 0 - psq_st fp13, OS_CONTEXT_PSF13(context), 0, 0 - psq_st fp14, OS_CONTEXT_PSF14(context), 0, 0 - psq_st fp15, OS_CONTEXT_PSF15(context), 0, 0 - psq_st fp16, OS_CONTEXT_PSF16(context), 0, 0 - psq_st fp17, OS_CONTEXT_PSF17(context), 0, 0 - psq_st fp18, OS_CONTEXT_PSF18(context), 0, 0 - psq_st fp19, OS_CONTEXT_PSF19(context), 0, 0 - psq_st fp20, OS_CONTEXT_PSF20(context), 0, 0 - psq_st fp21, OS_CONTEXT_PSF21(context), 0, 0 - psq_st fp22, OS_CONTEXT_PSF22(context), 0, 0 - psq_st fp23, OS_CONTEXT_PSF23(context), 0, 0 - psq_st fp24, OS_CONTEXT_PSF24(context), 0, 0 - psq_st fp25, OS_CONTEXT_PSF25(context), 0, 0 - psq_st fp26, OS_CONTEXT_PSF26(context), 0, 0 - psq_st fp27, OS_CONTEXT_PSF27(context), 0, 0 - psq_st fp28, OS_CONTEXT_PSF28(context), 0, 0 - psq_st fp29, OS_CONTEXT_PSF29(context), 0, 0 - psq_st fp30, OS_CONTEXT_PSF30(context), 0, 0 - psq_st fp31, OS_CONTEXT_PSF31(context), 0, 0 - -_return: - blr -} -#endif diff --git a/src/dolphin/os/OSError.c b/src/dolphin/os/OSError.c deleted file mode 100644 index 5a54539..0000000 --- a/src/dolphin/os/OSError.c +++ /dev/null @@ -1,215 +0,0 @@ -#include -#include -#include - -#include "__os.h" - -OSErrorHandler __OSErrorTable[17]; - -#define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) -u32 __OSFpscrEnableBits = FPSCR_ENABLE; - -void OSReport(const char* msg, ...) { - va_list marker; - va_start(marker, msg); - vprintf(msg, marker); - va_end(marker); -} - -void OSVReport(const char* msg, va_list list) { - vprintf(msg, list); -} - -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; - int enabled; - u32 msr; - u32 fpscr; - OSThread* thread; - int i; - - ASSERTMSGLINE(209, error < 17, "OSSetErrorHandler(): unknown error."); - - enabled = OSDisableInterrupts(); - oldHandler = __OSErrorTable[error]; - __OSErrorTable[error] = handler; - - if (error == __OS_EXCEPTION_FLOATING_POINT_EXCEPTION) { - msr = PPCMfmsr(); - PPCMtmsr(msr | MSR_FP); - fpscr = PPCMffpscr(); - - if (handler) { - for (thread = __OSActiveThreadQueue.head; thread; - thread = thread->linkActive.next) - { - thread->context.srr1 |= MSR_FE0 | MSR_FE1; - if ((thread->context.state & OS_CONTEXT_STATE_FPSAVED) == 0) { - 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; -} - -volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED | 0x00D8); - -void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) { - OSTime now; - u32 fpscr; - u32 msr; - - now = OSGetTime(); - - if (!(context->srr1 & MSR_RI)) { - OSReport("Non-recoverable Exception %d", exception); - } else { - if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && - __OSErrorTable[__OS_EXCEPTION_FLOATING_POINT_EXCEPTION] != 0) - { - exception = __OS_EXCEPTION_FLOATING_POINT_EXCEPTION; - - msr = PPCMfmsr(); - PPCMtmsr(msr | 0x2000); - - 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 &= ~0x2000; - __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 &= ~0x2000; - __OSFPUContext = NULL; - } - - OSLoadContext(context); - } - - if (__OSErrorTable[exception]) { - OSDisableScheduler(); - __OSErrorTable[exception](exception, context, dsisr, dar); - OSEnableScheduler(); - __OSReschedule(); - OSLoadContext(context); - } - if (exception == __OS_EXCEPTION_DECREMENTER) { - OSLoadContext(context); - } - OSReport("Unhandled Exception %d", exception); - } -#if DEBUG - OSReport("(%s)", __OSExceptionNames[exception]); -#endif - OSReport("\n"); - OSDumpContext(context); - OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); - OSReport("TB = 0x%016llx\n", now); - - switch(exception) { - case __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_EXCEPTION_MEMORY_PROTECTION: - OSReport("\n"); - OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[DSP_DMA_START_HI], - __DSPRegs[DSP_DMA_START_LO]); - OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[DSP_ARAM_DMA_MM_HI], - __DSPRegs[DSP_ARAM_DMA_MM_LO]); - OSReport("DI DMA Address = 0x%08x\n", __DIRegs[5]); - break; - } - - OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, - __OSLastInterruptSrr0, __OSLastInterruptTime); - PPCHalt(); -} diff --git a/src/dolphin/os/OSFatal.c b/src/dolphin/os/OSFatal.c deleted file mode 100644 index 673ddf9..0000000 --- a/src/dolphin/os/OSFatal.c +++ /dev/null @@ -1,246 +0,0 @@ -#include -#include -#include -#include - -#include "__os.h" - -typedef struct OSFatalParam { - GXColor fg; - GXColor bg; - const char* msg; -} OSFatalParam; - -static OSFatalParam FatalParam; -static OSContext FatalContext; - -// prototypes -static void Halt(); - -static void ScreenClear(void* xfb, u16 xfbW, u16 xfbH, GXColor yuv) { - int i; - int j; - u8* ptr; - - ptr = xfb; - for (i = 0; i < xfbH; i++) { - for (j = 0; j < xfbW; j += 2) { - *ptr++ = yuv.r; - *ptr++ = yuv.g; - *ptr++ = yuv.r; - *ptr++ = yuv.b; - } - } -} - -static void ScreenReport(void* xfb, u16 xfbW, u16 xfbH, GXColor yuv, s32 x, s32 y, s32 leading, const char* string) { - u8* ptr; - s32 width; - u32 i; - u32 j; - u32 image[72]; - u32 k; - u32 l; - u8 Y; - u32 pixel; - s32 col; - -loop_1: - if (xfbH - 24 >= y) { - ptr = (u8*)xfb + ((x + (y * xfbW)) * 2); - col = x; - - while ((s8)*string != 0) { - if ((s8)*string == '\n') { - string++; - y += leading; - goto loop_1; - } - - if (xfbW - 48 < col) { - y += leading; - goto loop_1; - } - - for (i = 0; i < 24; i++) { - j = (i & 7) + ((i >> 3) * 24); - image[j + 0 ] = 0; - image[j + 8 ] = 0; - image[j + 16] = 0; - } - - string = OSGetFontTexel((char*)string, image, 0, 6, &width); - - for (i = 0; i < 24; i++) { - j = (i & 7) + ((i >> 3) * 24); - - for (k = 0; k < 24; k++) { - l = j + (k & 0xFFFFFFF8); - - Y = (image[l] >> ((7 - (k & 7)) * 4)) & 0xF; - if (Y != 0) { - Y = (((yuv.r * (Y * 0xEF)) / 255) / 15) + 0x10; - pixel = k + (i * xfbW); - ptr[pixel * 2] = Y; - - if ((col + k) & 1) { - ptr[(pixel * 2) - 1] = yuv.g; - ptr[(pixel * 2) + 1] = yuv.b; - } else { - ptr[(pixel * 2) - 1] = yuv.b; - ptr[(pixel * 2) + 1] = yuv.g; - } - } - } - } - - ptr += width * 2; - col += width; - } - } -} - -static void ConfigureVideo(u16 xfbW, u16 xfbH) { - GXRenderModeObj mode; - mode.fbWidth = xfbW; - mode.efbHeight = 480; - mode.xfbHeight = xfbH; - mode.viXOrigin = 40; - mode.viWidth = 640; - mode.viHeight = xfbH; - - switch (VIGetTvFormat()) { - case 2: - case 0: - if (__VIRegs[54] & 1) { - mode.viTVmode = 2; - mode.viYOrigin = 0; - mode.xFBmode = 0; - } else { - mode.viTVmode = 0; - mode.viYOrigin = 0; - mode.xFBmode = 1; - } - break; - case 5: - mode.viTVmode = 20; - mode.viYOrigin = 0; - mode.xFBmode = 1; - break; - case 1: - mode.viTVmode = 4; - mode.viYOrigin = 47; - mode.xFBmode = 1; - break; - } - - VIConfigure(&mode); - VIConfigurePan(0, 0, 640, 480); -} - -static GXColor RGB2YUV(GXColor rgb) { - f32 Y; - f32 Cb; - f32 Cr; - GXColor yuv; - - Y = 0.5f + (16.0f + ((0.098f * (f32) rgb.b) + ((0.257f * (f32) rgb.r) + (0.504f * (f32) rgb.g)))); - Cb = 0.5f + (128.0f + ((0.439f * (f32) rgb.b) + ((-0.148f * (f32) rgb.r) - (0.291f * (f32) rgb.g)))); - Cr = 0.5f + (128.0f + (((0.439f * (f32) rgb.r) - (0.368f * (f32) rgb.g)) - (0.071f * (f32) rgb.b))); - - yuv.r = (Y > 235.0f) ? 235.0f : (Y < 16.0f) ? 16.0f : Y; - yuv.g = (Cb > 240.0f) ? 240.0f : (Cb < 16.0f) ? 16.0f : Cb; - yuv.b = (Cr > 240.0f) ? 240.0f : (Cr < 16.0f) ? 16.0f : Cr; - yuv.a = 0; - - return yuv; -} - -void OSFatal(GXColor fg, GXColor bg, const char* msg) { - OSBootInfo* bootInfo; - u32 count; - OSTime t; - - bootInfo = (OSBootInfo*)OSPhysicalToCached(0); - OSDisableInterrupts(); - OSDisableScheduler(); - OSClearContext(&FatalContext); - OSSetCurrentContext(&FatalContext); - __OSStopAudioSystem(); - AISetStreamVolLeft(0); - AISetStreamVolRight(0); - VIInit(); - __OSUnmaskInterrupts(0x80); - VISetBlack(TRUE); - VIFlush(); - VISetPreRetraceCallback(NULL); - VISetPostRetraceCallback(NULL); - OSEnableInterrupts(); - - count = VIGetRetraceCount(); - do {} while ((s32)(VIGetRetraceCount() - count) < 1); - - t = OSGetTime(); - while (!__OSCallResetFunctions(FALSE) && OSGetTime() - t < OSMillisecondsToTicks(1000)) {} - - OSDisableInterrupts(); - __OSCallResetFunctions(TRUE); - EXISetExiCallback(0, NULL); - EXISetExiCallback(2, NULL); - - while (!EXILock(0, 1, NULL)) { - EXISync(0); - EXIDeselect(0); - EXIUnlock(0); - } - EXIUnlock(0); - - do {} while ((__EXIRegs[3] & 1) == 1); - - __OSSetExceptionHandler(8, &OSDefaultExceptionHandler); - GXAbortFrame(); - OSSetArenaLo((void*)0x81400000); - OSSetArenaHi(bootInfo->FSTLocation); - - FatalParam.fg = fg; - FatalParam.bg = bg; - FatalParam.msg = msg; - OSSwitchFiber((u32)&Halt, (u32)OSGetArenaHi()); -} - -static void Halt() { - u32 count; - OSFontHeader* fontData; - void* xfb; - u32 len; - OSFatalParam* fp; - - OSEnableInterrupts(); - fp = &FatalParam; - len = strlen(fp->msg) + 1; - fp->msg = memmove(OSAllocFromArenaLo(len, DOLPHIN_ALIGNMENT), fp->msg, len); - - fontData = OSAllocFromArenaLo(0xA1004, DOLPHIN_ALIGNMENT); - OSLoadFont(fontData, OSGetArenaLo()); - - xfb = OSAllocFromArenaLo(0x96000, DOLPHIN_ALIGNMENT); - ScreenClear(xfb, 640, 480, RGB2YUV(fp->bg)); - VISetNextFrameBuffer(xfb); - ConfigureVideo(640, 480); - VIFlush(); - - count = VIGetRetraceCount(); - do {} while ((s32)(VIGetRetraceCount() - count) < 2); - - ScreenReport(xfb, 640, 480, RGB2YUV(fp->fg), 48, 100, fontData->leading, fp->msg); - DCFlushRange(xfb, 0x96000); - VISetBlack(FALSE); - VIFlush(); - - count = VIGetRetraceCount(); - do {} while ((s32)(VIGetRetraceCount() - count) < 1); - - OSDisableInterrupts(); - OSReport("%s\n", fp->msg); - PPCHalt(); -} diff --git a/src/dolphin/os/OSFont.c b/src/dolphin/os/OSFont.c deleted file mode 100644 index 4e6738b..0000000 --- a/src/dolphin/os/OSFont.c +++ /dev/null @@ -1,751 +0,0 @@ -#include -#include - -#include "__os.h" - -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) { - 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; - - do { - // Get next mask - if (flag == 0) { - code = *(u32*)(s + p); - p += sizeof(u32); - flag = sizeof(u32) * 8; - } - - // Non-linked chunk - if (code & 0x80000000) { - d[q++] = s[r25++]; - } - // Linked chunk - else { - // Read offset from link table - j = s[r7] << 8 | s[r7 + 1]; - r7 += sizeof(u16); - - // Apply offset - k = q - (j & 0x0FFF); - cnt = j >> 12; - if (cnt == 0) { - cnt = s[r25++] + 0x12; - } else { - cnt += 2; - } - - // Copy chunk - for (i = 0; i < cnt; i++, q++, k++) { - d[q] = d[k - 1]; - } - } - - // Prepare next mask bit - code <<= 1; - flag--; - } while (q < os); -} - -static u32 GetFontSize(u8* buf) { - if (buf[0] == 'Y' && buf[1] == 'a' && buf[2] == 'y') { - return *(u32*)(buf + 0x4); - } - - return 0; -} - -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; - break; - case VI_PAL: - case VI_MPAL: - case VI_DEBUG: - case VI_DEBUG_PAL: - case VI_EURGB60: - default: - 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); - - if (width != 0) { - *width = ((u8*)font + font->widthTable)[fontCode]; - } - - return (char*)string; -} - -int OSSetFontWidth(int fixed) { - int prev = FixedPitch; - FixedPitch = fixed; - return prev; -} diff --git a/src/dolphin/os/OSInterrupt.c b/src/dolphin/os/OSInterrupt.c deleted file mode 100644 index 77d92bb..0000000 --- a/src/dolphin/os/OSInterrupt.c +++ /dev/null @@ -1,509 +0,0 @@ -#include -#include - -#include "__os.h" - -#if DEBUG -u64 __OSSpuriousInterrupts = 0; -#endif -static __OSInterruptHandler* InterruptHandlerTable; - -volatile OSTime __OSLastInterruptTime; -volatile __OSInterrupt __OSLastInterrupt; -volatile u32 __OSLastInterruptSrr0; - -static OSInterruptMask InterruptPrioTable[] = { - OS_INTERRUPTMASK_PI_ERROR, - OS_INTERRUPTMASK_PI_DEBUG, - OS_INTERRUPTMASK_MEM, - OS_INTERRUPTMASK_PI_RSW, - OS_INTERRUPTMASK_PI_VI, - OS_INTERRUPTMASK_PI_PE, - OS_INTERRUPTMASK_PI_HSP, - OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP | OS_INTERRUPTMASK_AI | - OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI, - OS_INTERRUPTMASK_DSP_AI, - OS_INTERRUPTMASK_PI_CP, - 0xFFFFFFFF, -}; - -#if DEBUG -char* __OSInterruptNames[33] = { - "MEM_0", - "MEM_1", - "MEM_2", - "MEM_3", - "MEM_ADDRESS", - "DSP_AI", - "DSP_ARAM", - "DSP_DSP", - "AI_AI", - "EXI_0_EXI", - "EXI_0_TC", - "EXI_0_EXT", - "EXI_1_EXI", - "EXI_1_TC", - "EXI_1_EXT", - "EXI_2_EXI", - "EXI_2_TC", - "PI_CP", - "PI_PE_TOKEN", - "PI_PE_FINISH", - "PI_SI", - "PI_DI", - "PI_RSW", - "PI_ERROR", - "PI_VI", - "PI_DEBUG", - "PI_HSP", - "unknown", - "unknown", - "unknown", - "unknown", - "unknown", - "unknown" -}; - -char* __OSPIErrors[8] = { - "No Error", - "Misaligned address for CPU request", - "Incorrect transfer type (tt) from CPU", - "Unsupported transfer size", - "Address out of range", - "Write to ROM address space", - "Read from GX Fifo", - "Reserved error code", -}; -#endif - -// prototypes -static void ExternalInterruptHandler(register __OSException exception, register OSContext* context); -extern void __RAS_OSDisableInterrupts_begin(void); -extern void __RAS_OSDisableInterrupts_end(void); - -#ifdef __GEKKO__ -asm BOOL OSDisableInterrupts(void) { - nofralloc -entry __RAS_OSDisableInterrupts_begin - mfmsr r3 - rlwinm r4, r3, 0, 17, 15 - mtmsr r4 -entry __RAS_OSDisableInterrupts_end - rlwinm r3, r3, 17, 31, 31 - blr -} - -asm BOOL OSEnableInterrupts(void) { - nofralloc - - mfmsr r3 - ori r4, r3, 0x8000 - mtmsr r4 - rlwinm r3, r3, 17, 31, 31 - blr -} - -asm BOOL OSRestoreInterrupts(register BOOL level) { - nofralloc - - cmpwi level, 0 - mfmsr r4 - beq _disable - ori r5, r4, 0x8000 - b _restore -_disable: - rlwinm r5, r4, 0, 17, 15 -_restore: - mtmsr r5 - rlwinm r3, r4, 17, 31, 31 - blr -} -#endif - -__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) { - __OSInterruptHandler oldHandler; - - ASSERTMSGLINE(411, InterruptHandlerTable, "__OSSetInterruptHandler(): OSInit() must be called in advance."); - ASSERTMSGLINE(413, interrupt < 0x20, "__OSSetInterruptHandler(): unknown interrupt."); - - oldHandler = InterruptHandlerTable[interrupt]; - InterruptHandlerTable[interrupt] = handler; - return oldHandler; -} - -__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { - ASSERTMSGLINE(433, InterruptHandlerTable, "__OSGetInterruptHandler(): OSInit() must be called in advance."); - ASSERTMSGLINE(435, interrupt < 0x20, "__OSGetInterruptHandler(): unknown interrupt."); - return InterruptHandlerTable[interrupt]; -} - -void __OSInterruptInit(void) { - InterruptHandlerTable = (void*)OSPhysicalToCached(0x3040); - - memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); - - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0; - *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0; - - __PIRegs[1] = 0xf0; - - __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | - OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); - - __OSSetExceptionHandler(4, ExternalInterruptHandler); - #if DEBUG - __PIRegs[0] = 1; - __OSUnmaskInterrupts(0x100); - #endif -} - -static 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; -} - -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) { - #if DEBUG - __OSSpuriousInterrupts++; - #endif - 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; - - #if DEBUG - if (cause & OS_INTERRUPTMASK_PI_ERROR) { - OSReport("PI ERROR\n"); - OSDumpContext(context); - OSReport("\nPIESR = 0x%08x PIEAR = 0x%08x\n", __PIRegs[7], __PIRegs[8]); - __PIRegs[0] = 1; - OSReport("PI Error = %s\n", __OSPIErrors[__PIRegs[7]]); - OSReport("Offending address = 0x%x (from PIEAR)\n", __PIRegs[8]); - } - #endif - - unmasked = cause & ~(*(OSInterruptMask *)OSPhysicalToCached(0x00C4) | - *(OSInterruptMask *)OSPhysicalToCached(0x00C8)); - if (unmasked) { - for (prio = InterruptPrioTable;; ++prio) { - if (unmasked & *prio) { - 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); - } - } - - #if DEBUG - OSReport("Unhandled Interrupt(s): cause %08x intsr %08x\n", cause, intsr); - while (cause) { - interrupt = __cntlzw(cause); - cause &= ~(1 << (0x1F - __cntlzw(cause))); - OSReport(" %s\n", __OSInterruptNames[interrupt]); - } - #endif - - OSLoadContext(context); -} - -#ifdef __GEKKO__ -static asm void ExternalInterruptHandler(register __OSException exception, - register OSContext* context) { -#pragma unused(exception) - nofralloc - OS_EXCEPTION_SAVE_GPRS(context) - - stwu r1, -0x8(r1) - b __OSDispatchInterrupt -} -#endif diff --git a/src/dolphin/os/OSLink.c b/src/dolphin/os/OSLink.c deleted file mode 100644 index fbe11fe..0000000 --- a/src/dolphin/os/OSLink.c +++ /dev/null @@ -1,528 +0,0 @@ -#include -#include - -#include "__os.h" - -#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 AT_ADDRESS(OS_BASE_CACHED | 0x30C8); -const void* __OSStringTable AT_ADDRESS(OS_BASE_CACHED | 0x30D0); - -#define ENQUEUE_INFO(queue, info, link) \ - do { \ - OSModuleInfo* __prev; \ - \ - __prev = (queue)->tail; \ - if (__prev == NULL) \ - (queue)->head = (info); \ - else \ - __prev->link.next = (info); \ - (info)->link.prev = __prev; \ - (info)->link.next = NULL; \ - (queue)->tail = (info); \ - } while (0) - -#define DEQUEUE_INFO(info, queue, link) \ - do { \ - OSModuleInfo* __next; \ - OSModuleInfo* __prev; \ - \ - __next = (info)->link.next; \ - __prev = (info)->link.prev; \ - \ - if (__next == NULL) \ - (queue)->tail = __prev; \ - else \ - __next->link.prev = __prev; \ - \ - if (__prev == NULL) \ - (queue)->head = __next; \ - else \ - __prev->link.next = __next; \ - } while (0) - -#pragma dont_inline on -void OSNotifyLink(OSModuleInfo* module) {} - -void OSNotifyUnlink(OSModuleInfo* module) {} -#pragma dont_inline reset - -void OSSetStringTable(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; -} - -static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { - u32 i; - OSSectionInfo* si; - OSModuleHeader* moduleHeader; - OSModuleInfo* moduleInfo; - OSImportInfo* imp; - - ASSERTLINE(282, newModule->version <= OS_MODULE_VERSION); - - moduleHeader = (OSModuleHeader*)newModule; - moduleHeader->bssSection = 0; - - ASSERTLINE(290, newModule->version < 2 || moduleHeader->align == 0 || (u32) newModule % moduleHeader->align == 0); - ASSERTLINE(293, newModule->version < 2 || moduleHeader->bssAlign == 0 || (u32) bss % moduleHeader->bssAlign == 0); - - if (OS_MODULE_VERSION < newModule->version || - 2 <= newModule->version && - (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || - moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) - { - return FALSE; - } - - ENQUEUE_INFO(&__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) { - ASSERTLINE(326, moduleHeader->bssSection == 0); - moduleHeader->bssSection = (u8)i; - si->offset = (u32)bss; - } - } - - 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) { - ASSERTLINE(400, newModule->version <= OS_MODULE_VERSION && 3 <= newModule->version); - - if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) { - return FALSE; - } - return Link(newModule, bss, TRUE); -} - -static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) { - OSModuleID idNew; - OSImportInfo* imp; - OSRel* rel; - OSSectionInfo* si; - OSSectionInfo* siFlush; - u32* p; - u32 offset; - u32 x; - - ASSERTLINE(434, newModule); - - idNew = newModule->info.id; - ASSERTLINE(436, idNew); - - for (imp = (OSImportInfo*)module->impOffset; - imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) - { - 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; - - ASSERTLINE(546, oldModule->version <= OS_MODULE_VERSION); - - moduleHeader = (OSModuleHeader*)oldModule; - - DEQUEUE_INFO(oldModule, &__OSModuleInfoList, 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) { - ASSERTLINE(589, si->size != 0); - 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; - } - - moduleInfo = __OSModuleInfoList.head; - while (moduleInfo != 0) { - sectionInfo = (OSSectionInfo*)moduleInfo->sectionInfoOffset; - for (i = 0; i < moduleInfo->numSections; i++) { - if (sectionInfo->size != 0) { - baseSection = sectionInfo->offset & 0xFFFFFFFE; - if (baseSection <= (u32)ptr && (u32)ptr < baseSection + sectionInfo->size) { - if (section != 0) { - *section = i; - } - - if (offset != 0) { - *offset = (u32)ptr - baseSection; - } - - return moduleInfo; - } - } - sectionInfo++; - } - moduleInfo = moduleInfo->link.next; - } - - return NULL; -} diff --git a/src/dolphin/os/OSMemory.c b/src/dolphin/os/OSMemory.c deleted file mode 100644 index defbad9..0000000 --- a/src/dolphin/os/OSMemory.c +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include -#include - -#include "__os.h" - -#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) -#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) - -static BOOL OnReset(BOOL final); - -static OSResetFunctionInfo ResetFunctionInfo = { - OnReset, - 0x7F, - NULL, - NULL -}; - -u32 OSGetPhysicalMemSize(void) { -#if DEBUG - OSBootInfo* BootInfo = (OSBootInfo*)OSPhysicalToCached(0); - - return BootInfo->memorySize; -#else - return __OSPhysicalMemSize; -#endif -} - -u32 OSGetConsoleSimulatedMemSize(void) { -#if DEBUG - u32* memSize = (u32*)OSPhysicalToCached(0xF0); - - return *memSize; -#else - return __OSSimulatedMemSize; -#endif -} - -static BOOL OnReset(BOOL final) { - if (final != FALSE) { - __MEMRegs[8] = 0xFF; - __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_RESET); - } - return TRUE; -} - -void (*__OSErrorTable[])(u16, OSContext*, ...); - -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_EXCEPTION_MEMORY_PROTECTION]) { - __OSErrorTable[__OS_EXCEPTION_MEMORY_PROTECTION](__OS_EXCEPTION_MEMORY_PROTECTION, context, cause, addr); - return; - } - - __OSUnhandledException(__OS_EXCEPTION_MEMORY_PROTECTION, context, cause, addr); -} - -void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) { - BOOL enabled; - u32 start; - u32 end; - u16 reg; - - ASSERTLINE(206, chan < 4); - ASSERTLINE(207, (control & ~(OS_PROTECT_CONTROL_RDWR)) == 0); - - if (4 <= chan) { - return; - } - - control &= 3; - - 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 &= ~(3 << 2 * chan); - reg |= control << 2 * chan; - __MEMRegs[8] = reg; - - if (control != 3) { - __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan)); - } - - OSRestoreInterrupts(enabled); -} - -#ifdef __GEKKO__ -static asm void Config24MB(void) { - nofralloc - li r7, 0x0 - lis r4, 0x0 - addi r4, r4, 0x2 - lis r3, 0x8000 - addi r3, r3, 0x1ff - lis r6, 0x100 - addi r6, r6, 0x2 - lis r5, 0x8100 - addi r5, r5, 0xff - isync - mtdbatu 0, r7 - mtdbatl 0, r4 - mtdbatu 0, r3 - isync - mtibatu 0, r7 - mtibatl 0, r4 - mtibatu 0, r3 - isync - mtdbatu 2, r7 - mtdbatl 2, r6 - mtdbatu 2, r5 - isync - mtibatu 2, r7 - mtibatl 2, r6 - mtibatu 2, r5 - isync - mfmsr r3 - ori r3, r3, 0x30 - mtsrr1 r3 - mflr r3 - mtsrr0 r3 - rfi -} -#endif - -#ifdef __GEKKO__ -static asm void Config48MB(void) { - nofralloc - li r7, 0x0 - lis r4, 0x0 - addi r4, r4, 0x2 - lis r3, 0x8000 - addi r3, r3, 0x3ff - lis r6, 0x200 - addi r6, r6, 0x2 - lis r5, 0x8200 - addi r5, r5, 0x1ff - isync - mtdbatu 0, r7 - mtdbatl 0, r4 - mtdbatu 0, r3 - isync - mtibatu 0, r7 - mtibatl 0, r4 - mtibatu 0, r3 - isync - mtdbatu 2, r7 - mtdbatl 2, r6 - mtdbatu 2, r5 - isync - mtibatu 2, r7 - mtibatl 2, r6 - mtibatu 2, r5 - isync - mfmsr r3 - ori r3, r3, 0x30 - mtsrr1 r3 - mflr r3 - mtsrr0 r3 - rfi -} -#endif - -#ifdef __GEKKO__ -static asm void RealMode(register u32 addr) { - nofralloc - clrlwi addr, addr, 2 - mtsrr0 addr - mfmsr addr - rlwinm addr, addr, 0, 28, 25 - mtsrr1 addr - rfi -} -#endif - -void __OSInitMemoryProtection(void) { -#ifndef DEBUG - u32 padding[9]; - u32 temp; -#endif - BOOL enabled; - u32 size; - - size = 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); - -#ifdef DEBUG - if (OSGetConsoleSimulatedMemSize() < OSGetPhysicalMemSize() && OSGetConsoleSimulatedMemSize() == 0x1800000) -#else - temp = OSGetConsoleSimulatedMemSize(); // not sure how else to get the order right on retail - if (temp < OSGetPhysicalMemSize() && temp == 0x1800000) -#endif - { - DCInvalidateRange((void*)0x81800000, 0x1800000); - __MEMRegs[20] = 2; - } - - if (size <= 0x1800000) { - RealMode((u32)&Config24MB); - } else if (size <= 0x3000000) { - RealMode((u32)&Config48MB); - } - - __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); - OSRestoreInterrupts(enabled); -} diff --git a/src/dolphin/os/OSMessage.c b/src/dolphin/os/OSMessage.c deleted file mode 100644 index 476891b..0000000 --- a/src/dolphin/os/OSMessage.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include - -void OSInitMessageQueue(OSMessageQueue* mq, void* msgArray, s32 msgCount) { - OSInitThreadQueue(&mq->queueSend); - OSInitThreadQueue(&mq->queueReceive); - mq->msgArray = msgArray; - mq->msgCount = msgCount; - mq->firstIndex = 0; - mq->usedCount = 0; -} - -int OSSendMessage(OSMessageQueue* mq, void* msg, s32 flags) { - BOOL enabled; - s32 lastIndex; - - enabled = OSDisableInterrupts(); - while(mq->msgCount <= mq->usedCount) { - if (!(flags & 1)) { - OSRestoreInterrupts(enabled); - return 0; - } - OSSleepThread(&mq->queueSend); - } - lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; - ((u32*)mq->msgArray)[lastIndex] = (u32)msg; - mq->usedCount++; - OSWakeupThread(&mq->queueReceive); - OSRestoreInterrupts(enabled); - return 1; -} - -int OSReceiveMessage(OSMessageQueue* mq, void* msg, s32 flags) { - BOOL enabled = OSDisableInterrupts(); - - while(mq->usedCount == 0) { - if (!(flags & 1)) { - OSRestoreInterrupts(enabled); - return 0; - } - OSSleepThread(&mq->queueReceive); - } - if(msg != NULL) { - *(u32*)msg = ((u32*)mq->msgArray)[mq->firstIndex]; - } - - mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; - mq->usedCount--; - OSWakeupThread(&mq->queueSend); - OSRestoreInterrupts(enabled); - return 1; -} - -int OSJamMessage(OSMessageQueue* mq, void* msg, s32 flags) { - BOOL enabled = OSDisableInterrupts(); - - while(mq->msgCount <= mq->usedCount) { - if(!(flags & 1)) { - OSRestoreInterrupts(enabled); - return 0; - } - OSSleepThread(&mq->queueSend); - } - mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; - ((u32*)mq->msgArray)[mq->firstIndex] = (u32)msg; - mq->usedCount++; - OSWakeupThread(&mq->queueReceive); - OSRestoreInterrupts(enabled); - return 1; -} diff --git a/src/dolphin/os/OSMutex.c b/src/dolphin/os/OSMutex.c deleted file mode 100644 index 66b4abd..0000000 --- a/src/dolphin/os/OSMutex.c +++ /dev/null @@ -1,256 +0,0 @@ -#include -#include - -#include "__os.h" - -#define ENQUEUE_MUTEX(mutex, queue, link) \ - do { \ - OSMutex* __prev = (queue)->tail; \ - if (__prev == NULL) { \ - (queue)->head = (mutex); \ - } else { \ - __prev->link.next = (mutex); \ - } \ - (mutex)->link.prev = __prev; \ - (mutex)->link.next = 0; \ - (queue)->tail = (mutex); \ - } while(0); - -#define DEQUEUE_MUTEX(mutex, queue, link) \ - do { \ - OSMutex* __next = (mutex)->link.next; \ - OSMutex* __prev = (mutex)->link.prev; \ - if (__next == NULL) { \ - (queue)->tail = __prev; \ - } else { \ - __next->link.prev = __prev; \ - } \ - if (__prev == NULL) { \ - (queue)->head = __next; \ - } else { \ - __prev->link.next = __next; \ - } \ - } while(0); - -#define DEQUEUE_HEAD(mutex, queue, link) \ - do { \ - OSMutex* __next = mutex->link.next; \ - if (__next == NULL) { \ - (queue)->tail = 0; \ - } else { \ - __next->link.prev = 0; \ - } \ - (queue)->head = __next; \ - } while(0); - -// prototypes -static int IsMember(OSMutexQueue* queue, OSMutex* mutex); -int __OSCheckMutex(OSMutex* mutex); -int __OSCheckDeadLock(OSThread* thread); -int __OSCheckMutexes(OSThread* thread); - -void OSInitMutex(OSMutex* mutex) { - OSInitThreadQueue(&mutex->queue); - mutex->thread = 0; - mutex->count = 0; -} - -void OSLockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - - ASSERTMSGLINE(140, currentThread, "OSLockMutex(): current thread does not exist."); - ASSERTMSGLINE(142, currentThread->state == 2, "OSLockMutex(): current thread is not running."); - - while (1) { - OSThread* ownerThread = mutex->thread; - if (ownerThread == 0) { - mutex->thread = currentThread; - mutex->count++; - ENQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); - break; - } else if (ownerThread == currentThread) { - mutex->count++; - break; - } else { - currentThread->mutex = mutex; - __OSPromoteThread(mutex->thread, currentThread->priority); - ASSERTMSG2LINE(164, __OSCheckDeadLock(currentThread) == 0, "OSLockMutex(): detected deadlock: current thread %p, mutex %p.", currentThread, mutex); - OSSleepThread(&mutex->queue); - currentThread->mutex = NULL; - } - } - OSRestoreInterrupts(enabled); -} - -void OSUnlockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - - ASSERTMSGLINE(189, currentThread, "OSUnlockMutex(): current thread does not exist."); - ASSERTMSGLINE(191, currentThread->state == 2, "OSUnlockMutex(): current thread is not running."); - ASSERTMSG2LINE(194, mutex->thread == currentThread, "OSUnlockMutex(): current thread %p is not the owner of mutex %p.", currentThread, mutex); - - if (mutex->thread == currentThread) { - if (!--mutex->count) { - DEQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); - mutex->thread = 0; - - if (currentThread->priority < currentThread->base) { - currentThread->priority = __OSGetEffectivePriority(currentThread); - } - OSWakeupThread(&mutex->queue); - } - } - OSRestoreInterrupts(enabled); -} - -void __OSUnlockAllMutex(OSThread* thread) { - OSMutex* mutex; - - while (thread->queueMutex.head) { - mutex = thread->queueMutex.head; - DEQUEUE_HEAD(mutex, &thread->queueMutex, link); - ASSERTLINE(229, mutex->thread == thread); - mutex->count = 0; - mutex->thread = 0; - OSWakeupThread(&mutex->queue); - } -} - -BOOL OSTryLockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - BOOL locked; - - ASSERTMSGLINE(255, currentThread, "OSTryLockMutex(): current thread does not exist."); - ASSERTMSGLINE(257, currentThread->state == 2, "OSTryLockMutex(): current thread is not running."); - - if (!mutex->thread) { - mutex->thread = currentThread; - mutex->count++; - ENQUEUE_MUTEX(mutex, ¤tThread->queueMutex, 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(); - - ASSERTMSGLINE(313, currentThread, "OSWaitCond(): current thread does not exist."); - ASSERTMSGLINE(315, currentThread->state == 2, "OSWaitCond(): current thread is not running."); - ASSERTMSG2LINE(318, mutex->thread == currentThread, "OSWaitCond(): current thread %p is not the owner of mutex %p.", currentThread, mutex); - - if (mutex->thread == currentThread) { - s32 count = mutex->count; - mutex->count = 0; - DEQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); - mutex->thread = 0; - 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 int IsMember(OSMutexQueue* queue, OSMutex* mutex) { - OSMutex* member = queue->head; - - while (member) { - if (mutex == member) { - return 1; - } - member = member->link.next; - } - return 0; -} - -int __OSCheckMutex(OSMutex* mutex) { - OSThread* thread; - OSThreadQueue* queue; - s32 priority; - - priority = 0; - queue = &mutex->queue; - - if (queue->head != NULL && queue->head->link.prev != NULL) { - return 0; - } - if (queue->tail != NULL && queue->tail->link.next != NULL) { - return 0; - } - thread = queue->head; - while (thread) { - if (thread->link.next != NULL && (thread != thread->link.next->link.prev)) { - return 0; - } - if (thread->link.prev != NULL && (thread != thread->link.prev->link.next)) { - return 0; - } - if (thread->state != 4) { - return 0; - } - if (thread->priority < priority) { - return 0; - } - priority = thread->priority; - thread = thread->link.next; - } - if (mutex->thread) { - if (mutex->count <= 0) { - return 0; - } - } else if (mutex->count != 0) { - return 0; - } - return 1; -} - -int __OSCheckDeadLock(OSThread* thread) { - OSMutex* mutex = thread->mutex; - - while (mutex && mutex->thread) { - if (mutex->thread == thread) { - return 1; - } - mutex = mutex->thread->mutex; - } - return 0; -} - -int __OSCheckMutexes(OSThread* thread) { - OSMutex* mutex = thread->queueMutex.head; - - while (mutex) { - if (mutex->thread != thread) { - return 0; - } - if (__OSCheckMutex(mutex) == 0) { - return 0; - } - mutex = mutex->link.next; - } - return 1; -} diff --git a/src/dolphin/os/OSReboot.c b/src/dolphin/os/OSReboot.c deleted file mode 100644 index c921b4d..0000000 --- a/src/dolphin/os/OSReboot.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include - -#include "__os.h" - -static void* SaveStart; -static void* SaveEnd; - -void __OSReboot(u32 resetCode, u32 bootDol) { - OSContext exceptionContext; - char* argvToPass; - - OSDisableInterrupts(); - OSSetArenaLo((void*)0x81280000); - OSSetArenaHi((void*)0x812f0000); - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - argvToPass = NULL; - __OSBootDol(bootDol, resetCode | 0x80000000, &argvToPass); -} - -void OSSetSaveRegion(void* start, void* end) { - ASSERTMSGLINE(134, (u32)start >= 0x80700000 || start == NULL, "OSSetSaveRegion(): start address should be NULL or higher than 0x80700000\n"); - ASSERTMSGLINE(135, 0x81200000 >= (u32)end || end == NULL, "OSSetSaveRegion(): end address should be NULL or lower than 0x81200000\n"); - ASSERTMSGLINE(136, ((start == NULL) ^ (end == NULL)) == 0, "OSSetSaveRegion(): if either start or end is NULL, both should be NULL\n"); - - SaveStart = start; - SaveEnd = end; -} - -void OSGetSaveRegion(void** start, void** end) { - *start = SaveStart; - *end = SaveEnd; -} - -void OSGetSavedRegion(void** start, void** end) { - *start = __OSRebootParams.regionStart; - *end = __OSRebootParams.regionEnd; -} diff --git a/src/dolphin/os/OSReset.c b/src/dolphin/os/OSReset.c deleted file mode 100644 index 21953da..0000000 --- a/src/dolphin/os/OSReset.c +++ /dev/null @@ -1,248 +0,0 @@ -#include -#include - -#include "__os.h" - -// These macros are copied from OSThread.c. Or ARE they the same -// macros? They dont seem to be in the SDK headers. -#define ENQUEUE_INFO(info, queue) \ - do { \ - OSResetFunctionInfo* __prev = (queue)->tail; \ - if (__prev == 0) { \ - (queue)->head = (info); \ - } else { \ - __prev->next = (info); \ - } \ - (info)->prev = __prev; \ - (info)->next = 0; \ - (queue)->tail = (info); \ - } while(0); - -#define DEQUEUE_INFO(info, queue) \ - do { \ - OSResetFunctionInfo* __next = (info)->next; \ - OSResetFunctionInfo* __prev = (info)->prev; \ - if (__next == 0) { \ - (queue)->tail = __prev; \ - } else { \ - __next->prev = __prev; \ - } \ - if (__prev == 0) { \ - (queue)->head = __next; \ - } else { \ - __prev->next = __next; \ - } \ - } while(0); - -#define ENQUEUE_INFO_PRIO(info, queue) \ - do { \ - OSResetFunctionInfo* __prev; \ - OSResetFunctionInfo* __next; \ - for(__next = (queue)->head; __next \ - && (__next->priority <= (info)->priority); \ - __next = __next->next) ; \ - \ - if (__next == 0) { \ - ENQUEUE_INFO(info, queue); \ - } else { \ - (info)->next = __next; \ - __prev = __next->prev; \ - __next->prev = (info); \ - (info)->prev = __prev; \ - if (__prev == 0) { \ - (queue)->head = (info); \ - } else { \ - __prev->next = (info); \ - } \ - } \ - } while(0); - -static OSResetFunctionQueue ResetFunctionQueue; -static u32 bootThisDol; - -// prototypes -static int CallResetFunctions(int final); -static void Reset(u32 resetCode); - -void OSRegisterResetFunction(OSResetFunctionInfo* info) { - ASSERTLINE(208, info->func); - - ENQUEUE_INFO_PRIO(info, &ResetFunctionQueue); -} - -void OSUnregisterResetFunction(OSResetFunctionInfo* info) { - DEQUEUE_INFO(info, &ResetFunctionQueue); -} - -int __OSCallResetFunctions(BOOL final) { - OSResetFunctionInfo* info; - int err; - u32 priority; - - priority = 0; - err = 0; - - for (info = ResetFunctionQueue.head; info != 0;) { - if (err != 0 && priority != info->priority) - break; - err |= !info->func(final); - priority = info->priority; - info = info->next; - } - - err |= !__OSSyncSram(); - if (err) { - return 0; - } - return 1; -} - -#ifdef __GEKKO__ -static asm void Reset(u32 resetCode) { - nofralloc - b L_000001BC -L_000001A0: - mfspr r8, HID0 - ori r8, r8, 0x8 - mtspr HID0, r8 - isync - sync - nop - b L_000001C0 -L_000001BC: - b L_000001DC -L_000001C0: - mftb r5, 268 -L_000001C4: - mftb r6, 268 - subf r7, r5, r6 - cmplwi r7, 0x1124 - blt L_000001C4 - nop - b L_000001E0 -L_000001DC: - b L_000001FC -L_000001E0: - lis r8, 0xcc00 - ori r8, r8, 0x3000 - li r4, 0x3 - stw r4, 0x24(r8) - stw r3, 0x24(r8) - nop - b L_00000200 -L_000001FC: - b L_00000208 -L_00000200: - nop - b L_00000200 -L_00000208: - b L_000001A0 -} -#endif - -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); - continue; - default: - continue; - } - } -} - -void __OSDoHotReset(u32 resetCode) { - OSDisableInterrupts(); - __VIRegs[1] = 0; - ICFlashInvalidate(); - Reset(resetCode * 8); -} - -void __OSShutdownDevices(BOOL doRecal) { - int rc; - BOOL disableRecalibration; - - __OSStopAudioSystem(); - - if (!doRecal) { - disableRecalibration = __PADDisableRecalibration(TRUE); - } - - do {} while (!__OSCallResetFunctions(FALSE)); - do {} while (!__OSSyncSram()); - - OSDisableInterrupts(); - - rc = __OSCallResetFunctions(TRUE); - ASSERTLINE(408, rc); - - LCDisable(); - if (!doRecal) { - __PADDisableRecalibration(disableRecalibration); - } - - KillThreads(); -} - -void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu) { - OSSram* sram; - - OSDisableScheduler(); - - if (reset == TRUE && forceMenu) { - sram = __OSLockSram(); - sram->flags |= 0x40; - __OSUnlockSram(1); - - resetCode = 0; - } - - if (reset == OS_RESET_SHUTDOWN || - (reset == OS_RESET_RESTART && (bootThisDol || resetCode + 0x3fff0000 == 0))) - { - __OSShutdownDevices(FALSE); - } else { - __OSShutdownDevices(TRUE); - } - - if (reset == OS_RESET_HOTRESET) { - __OSDoHotReset(resetCode); - } else if (reset == OS_RESET_RESTART) { - if (forceMenu == TRUE) { - OSReport("OSResetSystem(): You can't specify TRUE to forceMenu if you restart. Ignored\n"); - } - OSEnableScheduler(); - __OSReboot(resetCode, bootThisDol); - } - - 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); -} - -u32 OSGetResetCode() { - u32 resetCode; - if (__OSRebootParams.valid) - resetCode = 0x80000000 | __OSRebootParams.restartCode; - else - resetCode = (__PIRegs[9] & 0xFFFFFFF8) / 8; - - return resetCode; -} - -u32 OSSetBootDol(u32 dolOffset) { - u32 oldDol; - - oldDol = bootThisDol; - bootThisDol = dolOffset; - return oldDol; -} diff --git a/src/dolphin/os/OSResetSW.c b/src/dolphin/os/OSResetSW.c deleted file mode 100644 index bbc5d2d..0000000 --- a/src/dolphin/os/OSResetSW.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include - -#include "__os.h" - -static OSResetCallback ResetCallback; -static BOOL Down; -static BOOL LastState; -static OSTime HoldUp; -static OSTime HoldDown; - -void __OSResetSWInterruptHandler(s16 exception, 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; -} - -OSResetCallback OSSetResetCallback(OSResetCallback callback) { - BOOL enabled; - OSResetCallback prevCallback; - - enabled = OSDisableInterrupts(); - prevCallback = ResetCallback; - ResetCallback = callback; - - if (callback) { - __PIRegs[0] = 2; - __OSUnmaskInterrupts(0x200); - } else { - __OSMaskInterrupts(0x200); - } - OSRestoreInterrupts(enabled); - return prevCallback; -} - -BOOL OSGetResetButtonState(void) { - BOOL enabled = OSDisableInterrupts(); - int state; - u32 reg; - OSTime now; - - now = __OSGetSystemTime(); - ASSERTLINE(158, 0 <= now); - ASSERTLINE(159, HoldUp == 0 || HoldUp < now); - ASSERTLINE(160, HoldDown == 0 || HoldDown < now); - - reg = __PIRegs[0]; - if (!(reg & 0x00010000)) { - if (!Down) { - Down = TRUE; - 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 (__gUnknown800030E3 & 0x1F) { - OSTime fire = (__gUnknown800030E3 & 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; -} - -int OSGetResetSwitchState(void) { - return OSGetResetButtonState(); -} - -void __OSSetResetButtonTimer(u8 min) { - BOOL enabled = OSDisableInterrupts(); - if (min > 0x1F) { - min = 0x1F; - } - - __gUnknown800030E3 &= ~0x1F; - __gUnknown800030E3 |= min; - OSRestoreInterrupts(enabled); -} diff --git a/src/dolphin/os/OSRtc.c b/src/dolphin/os/OSRtc.c deleted file mode 100644 index 7b37b4c..0000000 --- a/src/dolphin/os/OSRtc.c +++ /dev/null @@ -1,513 +0,0 @@ -#include -#include - -#include "__os.h" - -static SramControl Scb ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT); - -// prototypes -static int GetRTC(u32* rtc); -static int ReadSram(void* buffer); -static void WriteSramCallback(s32, OSContext*); -static int WriteSram(void* buffer, u32 offset, u32 size); -static void* LockSram(u32 offset); -static int UnlockSram(int commit, u32 offset); -static void __OSReadROMCallback(s32 chan); - -static int GetRTC(u32* rtc) { - int err; - u32 cmd; - - if (EXILock(0, 1, NULL) == 0) { - return 0; - } - if (EXISelect(0, 1, 3) == 0) { - EXIUnlock(0); - return 0; - } - cmd = 0x20000000; - err = 0; - err |= !EXIImm(0, &cmd, 4, 1, 0); - err |= !EXISync(0); - err |= !EXIImm(0, &cmd, 4, 0, 0); - err |= !EXISync(0); - err |= !EXIDeselect(0); - EXIUnlock(0); - rtc[0] = cmd; - return !err; -} - -int __OSGetRTC(u32* rtc) { - int err; - u32 t0; - u32 t1; - int i; - - for(i = 0; i < 16; i++) { - err = 0; - err |= !GetRTC(&t0); - err |= !GetRTC(&t1); - if (err) { - break; - } - if (t0 == t1) { - rtc[0] = t0; - return 1; - } - } - return 0; -} - -int __OSSetRTC(u32 rtc) { - int err; - u32 cmd; - - if (EXILock(0, 1, NULL) == 0) { - return 0; - } - if (EXISelect(0, 1, 3) == 0) { - EXIUnlock(0); - return 0; - } - cmd = 0xA0000000; - err = 0; - err |= !EXIImm(0, &cmd, 4, 1, 0); - err |= !EXISync(0); - err |= !EXIImm(0, &rtc, 4, 1, 0); - err |= !EXISync(0); - err |= !EXIDeselect(0); - EXIUnlock(0); - return !err; -} - -static int ReadSram(void* buffer) { - int err; - u32 cmd; - - DCInvalidateRange(buffer, SRAM_SIZE); - if (!EXILock(0, 1, NULL) ) { - return 0; - } - if (!EXISelect(0, 1, 3)) { - EXIUnlock(0); - return 0; - } - cmd = 0x20000100; - err = 0; - err |= !EXIImm(0, &cmd, 4, 1, 0); - err |= !EXISync(0); - err |= !EXIDma(0, buffer, SRAM_SIZE, 0, NULL); - err |= !EXISync(0); - err |= !EXIDeselect(0); - EXIUnlock(0); - return !err; -} - -static void WriteSramCallback(s32, OSContext*) { - ASSERTLINE(258, !Scb.locked); - Scb.sync = WriteSram(&Scb.sram[Scb.offset], Scb.offset, SRAM_SIZE - Scb.offset); - if (Scb.sync != 0) { - Scb.offset = SRAM_SIZE; - } - ASSERTLINE(264, Scb.sync); -} - -static int WriteSram(void* buffer, u32 offset, u32 size) { - int err; - u32 cmd; - - if (!EXILock(0, 1, WriteSramCallback)) { - return 0; - } - if (!EXISelect(0, 1, 3)) { - EXIUnlock(0); - return 0; - } - offset <<= 6; - cmd = ((offset + 0x100) | 0xA0000000); - err = 0; - err |= !EXIImm(0, &cmd, 4, 1, 0); - err |= !EXISync(0); - err |= !EXIImmEx(0, buffer, size, 1); - err |= !EXIDeselect(0); - EXIUnlock(0); - return !err; -} - -void __OSInitSram(void) { - Scb.locked = Scb.enabled = FALSE; - Scb.sync = ReadSram(&Scb); - ASSERTLINE(318, Scb.sync); - Scb.offset = SRAM_SIZE; - - OSSetGbsMode(OSGetGbsMode()); -} - -static void* LockSram(u32 offset) { - BOOL enabled; - - enabled = OSDisableInterrupts(); - ASSERTLINE(341, !Scb.locked); - if (Scb.locked) { - OSRestoreInterrupts(enabled); - return NULL; - } - Scb.enabled = enabled; - Scb.locked = TRUE; - return &Scb.sram[offset]; -} - -OSSram* __OSLockSram(void) { - return (OSSram*)LockSram(0); -} - -OSSramEx* __OSLockSramEx(void) { - return (OSSramEx*)LockSram(sizeof(OSSram)); -} - -static int UnlockSram(int commit, u32 offset) { - u16* p; - - ASSERTLINE(375, Scb.locked); - if (commit != 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[0x14]); p++) { - sram->checkSum += *p; - sram->checkSumInv += ~(*p); - } - } - if (offset < Scb.offset) { - Scb.offset = offset; - } - - if (Scb.offset <= 0x14) { - OSSramEx* sram = (OSSramEx*)(Scb.sram + sizeof(OSSram)); - if (((u32)sram->gbs & 0x7c00) == 0x5000 || ((u32)sram->gbs & 0xc0) == 0xc0) { - sram->gbs = 0; - } - } - - Scb.sync = WriteSram(&Scb.sram[Scb.offset], Scb.offset, SRAM_SIZE - Scb.offset); - if (Scb.sync != 0) { - Scb.offset = SRAM_SIZE; - } - } - Scb.locked = FALSE; - OSRestoreInterrupts(Scb.enabled); - return Scb.sync; -} - -int __OSUnlockSram(int commit) { - UnlockSram(commit, 0); -} - -int __OSUnlockSramEx(int commit) { - UnlockSram(commit, sizeof(OSSram)); -} - -int __OSSyncSram(void) { - return Scb.sync; -} - -int __OSCheckSram(void) { - u16* p; - u16 checkSum; - u16 checkSumInv; - OSSram* sram; - int unused; - - ASSERTLINE(466, Scb.locked); - - checkSum = checkSumInv = 0; - - sram = (OSSram*)Scb.sram; - - for (p = (void*)&sram->counterBias; p < (u16*)&Scb.sram[0x14]; p++) { - checkSum += *p; - checkSumInv += ~(*p); - } - - return (sram->checkSum == checkSum && sram->checkSumInv == checkSumInv); -} - -int __OSReadROM(void * buffer, s32 length, s32 offset) { - int err; - u32 cmd; - - ASSERTLINE(497, length <= 1024); - DCInvalidateRange(buffer, length); - if (EXILock(0, 1, NULL) == 0) { - return 0; - } - if (EXISelect(0, 1, 3) == 0) { - EXIUnlock(0); - return 0; - } - cmd = offset << 6; - err = 0; - err |= !EXIImm(0, &cmd, 4, 1, 0); - err |= !EXISync(0); - err |= !EXIDma(0, buffer, length, 0, NULL); - err |= !EXISync(0); - err |= !EXIDeselect(0); - EXIUnlock(0); - return !err; -} - -static void __OSReadROMCallback(s32 chan) { - void (*callback)(); - - EXIDeselect(chan); - EXIUnlock(chan); - callback = Scb.callback; - if (callback) { - Scb.callback = NULL; - callback(); - } -} - -int __OSReadROMAsync(void* buffer, s32 length, s32 offset, void (*callback)()) { - int err; - u32 cmd; - - ASSERTLINE(556, length <= 1024); - ASSERTLINE(557, callback); - DCInvalidateRange(buffer, length); - Scb.callback = callback; - if (EXILock(0, 1, NULL) == 0) { - return 0; - } - if (EXISelect(0, 1, 3) == 0) { - EXIUnlock(0); - return 0; - } - cmd = offset << 6; - err = 0; - err |= !EXIImm(0, &cmd, 4, 1, 0); - err |= !EXISync(0); - err |= !EXIDma(0, buffer, length, 0, (void*)__OSReadROMCallback); - return !err; -} - -u32 OSGetSoundMode(void) { - OSSram* sram = __OSLockSram(); - u32 mode = (sram->flags & 4) ? 1 : 0; - - __OSUnlockSram(0); - return mode; -} - -void OSSetSoundMode(u32 mode) { - OSSram* sram; - int unused; - - ASSERTLINE(617, mode == OS_SOUND_MODE_MONO || mode == OS_SOUND_MODE_STEREO); - mode *= 4; - mode &= 4; - sram = __OSLockSram(); - if (mode == (sram->flags & 4)) { - __OSUnlockSram(0); - return; - } - sram->flags &= 0xFFFFFFFB; - sram->flags |= mode; - __OSUnlockSram(1); -} - -u32 OSGetProgressiveMode(void) { - OSSram* sram; - u32 on; - - sram = __OSLockSram(); - on = (sram->flags & 0x80) >> 7; - __OSUnlockSram(FALSE); - return on; -} - -void OSSetProgressiveMode(u32 on) { -#ifndef DEBUG - u32 padding[1]; -#endif - OSSram* sram; - - ASSERTLINE(670, on == OS_PROGRESSIVE_MODE_OFF || on == OS_PROGRESSIVE_MODE_ON); - - on <<= 7; - on &= 0x80; - - sram = __OSLockSram(); - if (on == (sram->flags & 0x80)) { - __OSUnlockSram(FALSE); - return; - } - - sram->flags &= ~0x80; - sram->flags |= on; - __OSUnlockSram(TRUE); -} - -u32 OSGetVideoMode(void) { - OSSram* sram = __OSLockSram(); - u32 mode = sram->flags & 3; - - __OSUnlockSram(0); - - if (mode > 2) { - mode = 0; - } - - return mode; -} - -void OSSetVideoMode(u32 mode) { - OSSram* sram; - int unused; - - ASSERTLINE(731, OS_VIDEO_MODE_NTSC <= mode && mode <= OS_VIDEO_MODE_MPAL); - - if (mode > 2) { - mode = 0; - } - - sram = __OSLockSram(); - - if (mode == (sram->flags & 3)) { - __OSUnlockSram(0); - return; - } - sram->flags &= 0xFFFFFFFC; - sram->flags |= mode; - __OSUnlockSram(1); -} - -u8 OSGetLanguage(void) { - OSSram* sram = __OSLockSram(); - u8 language = sram->language; - - __OSUnlockSram(0); - return language; -} - -void OSSetLanguage(u8 language) { - OSSram* sram = __OSLockSram(); - int unused; - - if (language == sram->language) { - __OSUnlockSram(0); - return; - } - sram->language = language; - __OSUnlockSram(1); -} - -u8 __OSGetBootMode(void) { - OSSram* sram = __OSLockSram(); - u8 ntd = sram->ntd; - __OSUnlockSram(0); - return ntd & 0x80; -} - -void __OSSetBootMode(u8 ntd) { - OSSram* sram; - int unused; - - ntd &= 0x80; - sram = __OSLockSram(); - if (ntd == (sram->ntd & 0x80U)) { - __OSUnlockSram(0); - return; - } - sram->ntd &= 0xFFFFFF7F; - sram->ntd |= ntd; - __OSUnlockSram(1); -} - -u32 OSGetEuRgb60Mode(void) { - OSSram* sram; - u32 on; - - sram = __OSLockSram(); - on = (sram->ntd & 0x40) >> 6; - __OSUnlockSram(0); - return on; -} - -void OSSetEuRgb60Mode(u32 on) { -#ifndef DEBUG - u32 padding[1]; -#endif - OSSram* sram; - - ASSERTLINE(895, on == OS_EURGB60_OFF || on == OS_EURGB60_ON); - on <<= 6; - on &= 0x40; - - sram = __OSLockSram(); - if (on == (sram->ntd & 0x40)) { - __OSUnlockSram(0); - } else { - sram->ntd &= ~0x40; - sram->ntd |= on; - __OSUnlockSram(1); - } -} - -u16 OSGetWirelessID(s32 chan) { - OSSramEx* sram; - u16 id; - - sram = __OSLockSramEx(); - id = sram->wirelessPadID[chan]; - __OSUnlockSramEx(FALSE); - return id; -} - -void OSSetWirelessID(s32 chan, u16 id) { - OSSramEx* sram; - - sram = __OSLockSramEx(); - if (sram->wirelessPadID[chan] != id) { - sram->wirelessPadID[chan] = id; - __OSUnlockSramEx(TRUE); - return; - } - - __OSUnlockSramEx(FALSE); -} - -u16 OSGetGbsMode(void) { - OSSramEx* sram; - u16 mode; - - sram = __OSLockSramEx(); - mode = sram->gbs; - __OSUnlockSramEx(FALSE); - return mode; -} - -void OSSetGbsMode(u16 mode) { -#ifndef DEBUG - u32 padding[1]; -#endif - OSSramEx* sram; - - 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); -} diff --git a/src/dolphin/os/OSStopwatch.c b/src/dolphin/os/OSStopwatch.c deleted file mode 100644 index c53c168..0000000 --- a/src/dolphin/os/OSStopwatch.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include - -void OSInitStopwatch(OSStopwatch* sw, char* name) { - sw->name = name; - sw->total = 0; - sw->hits = 0; - sw->min = 0x00000000FFFFFFFF; - sw->max = 0; -} - -void OSStartStopwatch(OSStopwatch* sw) { - sw->running = TRUE; - sw->last = OSGetTime(); -} - -void OSStopStopwatch(OSStopwatch* sw) { - OSTime interval; - - if (sw->running) { - interval = OSGetTime() - sw->last; - sw->total += interval; - sw->running = FALSE; - sw->hits++; - if (sw->max < interval) { - sw->max = interval; - } - if (interval < sw->min) { - sw->min = interval; - } - } -} - -OSTime OSCheckStopwatch(OSStopwatch* sw) { - OSTime currTotal; - - currTotal = sw->total; - if (sw->running) { - currTotal += OSGetTime() - sw->last; - } - return currTotal; -} - -void OSResetStopwatch(OSStopwatch* sw) { - OSInitStopwatch(sw, sw->name); -} - -void OSDumpStopwatch(OSStopwatch* sw) { - OSReport("Stopwatch [%s] :\n", sw->name); - OSReport("\tTotal= %lld us\n", OSTicksToMicroseconds(sw->total)); - OSReport("\tHits = %d \n", sw->hits); - OSReport("\tMin = %lld us\n", OSTicksToMicroseconds(sw->min)); - OSReport("\tMax = %lld us\n", OSTicksToMicroseconds(sw->max)); - OSReport("\tMean = %lld us\n", OSTicksToMicroseconds(sw->total/sw->hits)); -} diff --git a/src/dolphin/os/OSSync.c b/src/dolphin/os/OSSync.c deleted file mode 100644 index 0f91a19..0000000 --- a/src/dolphin/os/OSSync.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "__os.h" - -// prototypes -void __OSSystemCallVectorStart(void); -void __OSSystemCallVectorEnd(void); - -#ifdef __GEKKO__ -static asm void SystemCallVector(void) { -entry __OSSystemCallVectorStart - nofralloc - mfspr r9, HID0 - ori r10, r9, 0x8 - mtspr HID0, r10 - isync - sync - mtspr HID0, r9 - rfi -entry __OSSystemCallVectorEnd - nop -} -#endif - -void __OSInitSystemCall(void) { - void* addr = (void*)OSPhysicalToCached(0xC00); - - memcpy(addr, __OSSystemCallVectorStart, (u32)&__OSSystemCallVectorEnd - (u32)&__OSSystemCallVectorStart); - DCFlushRangeNoSync(addr, 0x100); - __sync(); - ICInvalidateRange(addr, 0x100); -} diff --git a/src/dolphin/os/OSThread.c b/src/dolphin/os/OSThread.c deleted file mode 100644 index 6f709ec..0000000 --- a/src/dolphin/os/OSThread.c +++ /dev/null @@ -1,875 +0,0 @@ -#include -#include - -#include "__os.h" - -#define ENQUEUE_THREAD(thread, queue, link) \ - do { \ - OSThread* __prev = (queue)->tail; \ - if (__prev == NULL) { \ - (queue)->head = (thread); \ - } else { \ - __prev->link.next = (thread); \ - } \ - (thread)->link.prev = __prev; \ - (thread)->link.next = 0; \ - (queue)->tail = (thread); \ - } while(0); - -#define DEQUEUE_THREAD(thread, queue, link) \ - do { \ - OSThread* __next = (thread)->link.next; \ - OSThread* __prev = (thread)->link.prev; \ - if (__next == NULL) { \ - (queue)->tail = __prev; \ - } else { \ - __next->link.prev = __prev; \ - } \ - if (__prev == NULL) { \ - (queue)->head = __next; \ - } else { \ - __prev->link.next = __next; \ - } \ - } while(0); - -#define ENQUEUE_THREAD_PRIO(thread, queue, link) \ - do { \ - OSThread* __prev; \ - OSThread* __next; \ - for(__next = (queue)->head; __next \ - && (__next->priority <= (thread)->priority); \ - __next = __next->link.next) ; \ - \ - if (__next == NULL) { \ - ENQUEUE_THREAD(thread, queue, link); \ - } else { \ - (thread)->link.next = __next; \ - __prev = __next->link.prev; \ - __next->link.prev = (thread); \ - (thread)->link.prev = __prev; \ - if (__prev == NULL) { \ - (queue)->head = (thread); \ - } else { \ - __prev->link.next = (thread); \ - } \ - } \ - } while(0); - -#define DEQUEUE_HEAD(thread, queue, link) \ - do { \ - OSThread* __next = thread->link.next; \ - if (__next == NULL) { \ - (queue)->tail = 0; \ - } else { \ - __next->link.prev = 0; \ - } \ - (queue)->head = __next; \ - } while(0); - -// defined in linkscript -extern u8 _stack_end[]; -extern u8 _stack_addr[]; - -static OSThreadQueue RunQueue[32]; -static OSThread IdleThread; -static OSThread DefaultThread; -static OSContext IdleContext; -static volatile u32 RunQueueBits; -static volatile int RunQueueHint; -static s32 Reschedule; - -#define ALIGN4(val) (((val) + 0x3) & ~0x3) -#define ALIGN8(val) (((val) + 0x7) & ~0x7) - -// prototypes -static void OSInitMutexQueue(OSMutexQueue* queue); -static void __OSSwitchThread(OSThread* nextThread); -static int __OSIsThreadActive(OSThread* thread); -static void SetRun(OSThread* thread); -static void UnsetRun(OSThread* thread); -static OSThread* SetEffectivePriority(OSThread* thread, s32 priority); -static void UpdatePriority(OSThread* thread); -static OSThread* SelectThread(int yield); -static int CheckThreadQueue(OSThreadQueue* queue); -static int IsMember(OSThreadQueue* queue, OSThread* thread); -static void OSSetCurrentThread(OSThread* thread); - -static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {} -static OSSwitchThreadCallback SwitchThreadCallback = DefaultSwitchThreadCallback; - -OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback callback) { - OSSwitchThreadCallback prev; - BOOL enabled; - - enabled = OSDisableInterrupts(); - prev = SwitchThreadCallback; - - SwitchThreadCallback = callback ? callback : DefaultSwitchThreadCallback; - OSRestoreInterrupts(enabled); - - if (prev == DefaultSwitchThreadCallback) { - return NULL; - } - - return prev; -} - -static inline void OSSetCurrentThread(OSThread* thread) { - SwitchThreadCallback(__OSCurrentThread, thread); - __OSCurrentThread = thread; -} - -void __OSThreadInit() { - OSThread* thread = &DefaultThread; - OSPriority prio; - - thread->state = OS_THREAD_STATE_RUNNING; - thread->attr = 1; - thread->priority = thread->base = 0x10; - thread->suspend = 0; - thread->val = (void*)-1; // wut - thread->mutex = 0; - - OSInitThreadQueue(&thread->queueJoin); -#ifdef DEBUG - OSInitMutexQueue(&thread->queueMutex); -#else - thread->queueMutex.head = thread->queueMutex.tail = 0; // it got inlined? cant reproduce the inline... -#endif - - ASSERTLINE(LINE(348, 357, 357), PPCMfmsr() & MSR_FP); - - __gUnkThread1 = thread; - OSClearContext(&thread->context); - OSSetCurrentContext(&thread->context); - thread->stackBase = (u8*)&_stack_addr; - thread->stackEnd = (u32*)&_stack_end; - *(u32*)thread->stackEnd = OS_THREAD_STACK_MAGIC; - OSSetCurrentThread(thread); - OSClearStack(0); - RunQueueBits = 0; - RunQueueHint = 0; - - for (prio = 0; prio <= 31; prio++) { - OSInitThreadQueue(&RunQueue[prio]); - } - OSInitThreadQueue(&__OSActiveThreadQueue); - - ENQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); - - OSClearContext(&IdleContext); - Reschedule = 0; -} - -#if DEBUG -static void OSInitMutexQueue(OSMutexQueue* queue) { - queue->head = queue->tail = 0; -} -#endif - -void OSInitThreadQueue(OSThreadQueue* queue) { - queue->head = queue->tail = 0; -} - -OSThread* OSGetCurrentThread() { - return __OSCurrentThread; -} - -static void __OSSwitchThread(OSThread* nextThread) { - OSSetCurrentThread(nextThread); - OSSetCurrentContext(&nextThread->context); - OSLoadContext(&nextThread->context); -} - -BOOL OSIsThreadSuspended(OSThread* thread) { - if (thread->suspend > 0) { - return TRUE; - } - return FALSE; -} - -BOOL OSIsThreadTerminated(OSThread* thread) { - return (thread->state == OS_THREAD_STATE_MORIBUND || thread->state == 0) ? TRUE : FALSE; -} - -static BOOL __OSIsThreadActive(OSThread* thread) { - OSThread* active; - - if (thread->state == 0) { - return FALSE; - } - - for (active = __OSActiveThreadQueue.head; active; active = active->linkActive.next) { - if (thread == active) { - return TRUE; - } - } - return FALSE; -} - -s32 OSDisableScheduler(void) { - register BOOL enabled; - s32 count; - - enabled = OSDisableInterrupts(); - count = Reschedule; - Reschedule = count + 1; - OSRestoreInterrupts(enabled); - return count; -} - -s32 OSEnableScheduler(void) { - register BOOL enabled; - s32 count; - - enabled = OSDisableInterrupts(); - count = Reschedule; - Reschedule = count - 1; - OSRestoreInterrupts(enabled); - return count; -} - -static void SetRun(OSThread* thread) { - ASSERTLINE(LINE(536, 554, 554), !IsSuspended(thread->suspend)); - ASSERTLINE(LINE(537, 555, 555), thread->state == OS_THREAD_STATE_READY); - - ASSERTLINE(LINE(539, 557, 557), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX); - - thread->queue = &RunQueue[thread->priority]; - - ENQUEUE_THREAD(thread, thread->queue, link); - - RunQueueBits |= 1 << (OS_PRIORITY_MAX - thread->priority); - RunQueueHint = 1; -} - -static void UnsetRun(OSThread* thread) { - OSThreadQueue* queue; - - ASSERTLINE(LINE(560, 578, 578), thread->state == OS_THREAD_STATE_READY); - - ASSERTLINE(LINE(562, 580, 580), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX); - ASSERTLINE(LINE(563, 581, 581), thread->queue == &RunQueue[thread->priority]); - - queue = thread->queue; - - DEQUEUE_THREAD(thread, queue, link); - - if (!queue->head) { - RunQueueBits &= ~(1 << (OS_PRIORITY_MAX - thread->priority)); - } - thread->queue = NULL; -} - -s32 __OSGetEffectivePriority(OSThread* thread) { - s32 priority = thread->base; - OSMutex* mutex; - - for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { - OSThread* blocked = mutex->queue.head; - if (blocked && blocked->priority < priority) { - priority = blocked->priority; - } - } - return priority; -} - -static OSThread* SetEffectivePriority(OSThread* thread, s32 priority) { - ASSERTLINE(LINE(614, 632, 632), !IsSuspended(thread->suspend)); - - switch(thread->state) { - case OS_THREAD_STATE_READY: - UnsetRun(thread); - thread->priority = priority; - SetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - DEQUEUE_THREAD(thread, thread->queue, link); - thread->priority = priority; - - ENQUEUE_THREAD_PRIO(thread, thread->queue, link); - - if (thread->mutex) { - ASSERTLINE(LINE(629, 647, 647), thread->mutex->thread); - return thread->mutex->thread; - } - break; - case OS_THREAD_STATE_RUNNING: - RunQueueHint = 1; - thread->priority = priority; - break; - } - return 0; -} - -static void UpdatePriority(OSThread* thread) { - s32 priority; - - while (1) { - if(thread->suspend > 0) { - break; - } - priority = __OSGetEffectivePriority(thread); - if (thread->priority == priority) { - break; - } - thread = SetEffectivePriority(thread, priority); - if (thread == 0) { - break; - } - } -} - -void __OSPromoteThread(OSThread* thread, s32 priority) { - while (1) { - if (thread->suspend > 0 || thread->priority <= priority) { - break; - } - thread = SetEffectivePriority(thread, priority); - if (thread == 0) { - break; - } - } -} - -static OSThread* SelectThread(int yield) { - OSContext* currentContext; - OSThread* currentThread; - OSThread* nextThread; - OSPriority priority; - OSThreadQueue* queue; - - if (Reschedule > 0) { - return NULL; - } - - currentContext = OSGetCurrentContext(); - currentThread = OSGetCurrentThread(); - - if (currentContext != ¤tThread->context) { - return NULL; - } - - if (currentThread) { - if (currentThread->state == 2) { - if (yield == 0) { - priority = __cntlzw(RunQueueBits); - if (currentThread->priority <= priority) - return NULL; - } - currentThread->state = OS_THREAD_STATE_READY; - SetRun(currentThread); - } - if (!(currentThread->context.state & 2) && (OSSaveContext(¤tThread->context) != 0)) { - return NULL; - } - } - - if (RunQueueBits == 0) { - OSSetCurrentThread(NULL); - OSSetCurrentContext(&IdleContext); - do { - OSEnableInterrupts(); - while (RunQueueBits == 0) ; - OSDisableInterrupts(); - } while (RunQueueBits == 0); - OSClearContext(&IdleContext); - } - - RunQueueHint = 0; - priority = __cntlzw(RunQueueBits); - - ASSERTLINE(LINE(777, 808, 808), OS_PRIORITY_MIN <= priority && priority <= OS_PRIORITY_MAX); - - queue = &RunQueue[priority]; - nextThread = queue->head; - - DEQUEUE_HEAD(nextThread, queue, link); - - ASSERTLINE(LINE(780, 811, 811), nextThread->priority == priority); - - if (!queue->head) { - RunQueueBits &= ~(1 << (OS_PRIORITY_MAX - priority)); - } - nextThread->queue = 0; - nextThread->state = OS_THREAD_STATE_RUNNING; - __OSSwitchThread(nextThread); - return nextThread; -} - -void __OSReschedule(void) { - if (RunQueueHint != 0) { - SelectThread(0); - } -} - -void OSYieldThread(void) { - BOOL enabled = OSDisableInterrupts(); - - SelectThread(1); - OSRestoreInterrupts(enabled); -} - -int OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, void* stack, u32 stackSize, OSPriority priority, u16 attr) { - BOOL enabled; - u32 sp; - int i; - - ASSERTMSGLINE(LINE(864, 895, 895), ((priority >= OS_PRIORITY_MIN) && (priority <= OS_PRIORITY_MAX)), "OSCreateThread(): priority out of range (0 <= priority <= 31)."); - - // why check this for an assert just to check it again right after? - if ((priority < OS_PRIORITY_MIN) || (priority > OS_PRIORITY_MAX)) { - return 0; - } - - thread->state = OS_THREAD_STATE_READY; - thread->attr = attr & 1U; - thread->base = priority; - thread->priority = priority; - thread->suspend = 1; - thread->val = (void*)-1; - thread->mutex = 0; - OSInitThreadQueue(&thread->queueJoin); -#ifdef DEBUG - OSInitMutexQueue(&thread->queueMutex); -#else - OSInitThreadQueue((void*)&thread->queueMutex); // why -#endif - sp = (u32)stack; - sp &= ~7; - sp -= 8; - ((u32*)sp)[0] = 0; - ((u32*)sp)[1] = 0; - OSInitContext(&thread->context, (u32)func, sp); - thread->context.lr = (u32)&OSExitThread; - thread->context.gpr[3] = (u32)param; - thread->stackBase = stack; - thread->stackEnd = (void*)((unsigned int)stack - stackSize); - *thread->stackEnd = OS_THREAD_STACK_MAGIC; - thread->error = 0; - for (i = 0; i < 2; i++) { - thread->specific[i] = NULL; - } - enabled = OSDisableInterrupts(); - - if (__OSErrorTable[16] != NULL) { - thread->context.srr1 |= 0x900; - thread->context.state |= 1; - thread->context.fpscr = (__OSFpscrEnableBits & 0xf8) | 4; - for (i = 0; i < 32; ++i) { - *(u64*)&thread->context.fpr[i] = (u64)0xffffffffffffffffLL; - *(u64*)&thread->context.psf[i] = (u64)0xffffffffffffffffLL; - } - } - - ASSERTMSG1LINE(LINE(918, 949, 949), __OSIsThreadActive(thread) == 0L, "OSCreateThread(): thread %p is still active.", thread); - - ENQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); - - OSRestoreInterrupts(enabled); - return 1; -} - -void OSExitThread(void* val) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - - ASSERTMSGLINE(LINE(943, 974, 974), currentThread, - "OSExitThread(): current thread does not exist."); - ASSERTMSGLINE(LINE(945, 976, 976), currentThread->state == OS_THREAD_STATE_RUNNING, - "OSExitThread(): current thread is not running."); - ASSERTMSGLINE(LINE(947, 978, 978), __OSIsThreadActive(currentThread) != 0, - "OSExitThread(): current thread is not active."); - - OSClearContext(¤tThread->context); - if (currentThread->attr & 1) { - DEQUEUE_THREAD(currentThread, &__OSActiveThreadQueue, linkActive); - currentThread->state = 0; - } else { - currentThread->state = 8; - currentThread->val = val; - } - __OSUnlockAllMutex(currentThread); - OSWakeupThread(¤tThread->queueJoin); - RunQueueHint = 1; -#ifdef DEBUG - __OSReschedule(); -#else - if (RunQueueHint != 0) { - SelectThread(0); - } -#endif - OSRestoreInterrupts(enabled); -} - -void OSCancelThread(OSThread* thread) { - BOOL enabled = OSDisableInterrupts(); - - ASSERTMSG1LINE(LINE(985, 1016, 1016), __OSIsThreadActive(thread) != 0, - "OSExitThread(): thread %p is not active.", thread); - - switch(thread->state) { - case OS_THREAD_STATE_READY: - if (thread->suspend <= 0) { - UnsetRun(thread); - } - break; - case OS_THREAD_STATE_RUNNING: - RunQueueHint = 1; - break; - case OS_THREAD_STATE_WAITING: - DEQUEUE_THREAD(thread, thread->queue, link); - thread->queue = 0; - if ((thread->suspend <= 0) && (thread->mutex)) { - ASSERTLINE(LINE(1004, 1035, 1035), thread->mutex->thread); - UpdatePriority(thread->mutex->thread); - } - break; - default: - OSRestoreInterrupts(enabled); - return; - } - OSClearContext(&thread->context); - if (thread->attr & 1) { - DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); - thread->state = 0; - } else { - thread->state = 8; - } - __OSUnlockAllMutex(thread); - OSWakeupThread(&thread->queueJoin); - __OSReschedule(); - OSRestoreInterrupts(enabled); -} - -int OSJoinThread(OSThread* thread, void* val) { - BOOL enabled = OSDisableInterrupts(); - - ASSERTMSG1LINE(LINE(1061, 1092, 1092), __OSIsThreadActive(thread) != 0, "OSJoinThread(): thread %p is not active.", thread); - - if (!(thread->attr & 1) && (thread->state != OS_THREAD_STATE_MORIBUND) && (thread->queueJoin.head == NULL)) { - OSSleepThread(&thread->queueJoin); - if (__OSIsThreadActive(thread) == 0) { - OSRestoreInterrupts(enabled); - return 0; - } - } - if (thread->state == OS_THREAD_STATE_MORIBUND) { - if (val) { - *(s32*)val = (s32)thread->val; - } - DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); - thread->state = 0; - OSRestoreInterrupts(enabled); - return 1; - } - OSRestoreInterrupts(enabled); - return 0; -} - -void OSDetachThread(OSThread* thread) { - BOOL enabled = OSDisableInterrupts(); - - ASSERTMSG1LINE(LINE(1111, 1142, 1142), __OSIsThreadActive(thread) != 0, "OSDetachThread(): thread %p is not active.", thread); - - thread->attr |= 1; - if (thread->state == OS_THREAD_STATE_MORIBUND) { - DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); - thread->state = 0; - } - OSWakeupThread(&thread->queueJoin); - OSRestoreInterrupts(enabled); -} - -s32 OSResumeThread(OSThread* thread) { - BOOL enabled = OSDisableInterrupts(); - s32 suspendCount; - - ASSERTMSG1LINE(LINE(1140, 1171, 1171), __OSIsThreadActive(thread) != 0, "OSResumeThread(): thread %p is not active.", thread); - ASSERTMSG1LINE(LINE(1142, 1173, 1173), thread->state != OS_THREAD_STATE_MORIBUND, "OSResumeThread(): thread %p is terminated.", thread); - - suspendCount = thread->suspend--; - if (thread->suspend < 0) { - thread->suspend = 0; - } else if (thread->suspend == 0) { - switch(thread->state) { - case OS_THREAD_STATE_READY: - thread->priority = __OSGetEffectivePriority(thread); - SetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - ASSERTLINE(LINE(1157, 1188, 1188), thread->queue); - DEQUEUE_THREAD(thread, thread->queue, link); - thread->priority = __OSGetEffectivePriority(thread); - ENQUEUE_THREAD_PRIO(thread, thread->queue, link); - if (thread->mutex) { - UpdatePriority(thread->mutex->thread); - } - } - __OSReschedule(); - } - OSRestoreInterrupts(enabled); - return suspendCount; -} - -s32 OSSuspendThread(OSThread* thread) { - BOOL enabled = OSDisableInterrupts(); - s32 suspendCount; - - ASSERTMSG1LINE(LINE(1191, 1222, 1222), __OSIsThreadActive(thread) != 0, "OSSuspendThread(): thread %p is not active.", thread); - ASSERTMSG1LINE(LINE(1193, 1224, 1224), thread->state != OS_THREAD_STATE_MORIBUND, "OSSuspendThread(): thread %p is terminated.", thread); - - suspendCount = thread->suspend++; - if (suspendCount == 0) { - switch(thread->state) { - case OS_THREAD_STATE_RUNNING: - RunQueueHint = 1; - thread->state = 1; - break; - case OS_THREAD_STATE_READY: - UnsetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - DEQUEUE_THREAD(thread, thread->queue, link); - thread->priority = 0x20; - ENQUEUE_THREAD(thread, thread->queue, link); - if (thread->mutex) { - ASSERTLINE(LINE(1214, 1245, 1245), thread->mutex->thread); - UpdatePriority(thread->mutex->thread); - } - break; - } - __OSReschedule(); - } - OSRestoreInterrupts(enabled); - return suspendCount; -} - -void OSSleepThread(OSThreadQueue* queue) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - - ASSERTMSGLINE(LINE(1247, 1278, 1278), currentThread, "OSSleepThread(): current thread does not exist."); - ASSERTMSG1LINE(LINE(1249, 1280, 1280), __OSIsThreadActive(currentThread) != 0, "OSSleepThread(): current thread %p is not active.", currentThread); - ASSERTMSG1LINE(LINE(1251, 1282, 1282), currentThread->state == OS_THREAD_STATE_RUNNING, "OSSleepThread(): current thread %p is not running.", currentThread); - ASSERTMSG1LINE(LINE(1253, 1284, 1284), currentThread->suspend <= 0, "OSSleepThread(): current thread %p is suspended.", currentThread); - - currentThread->state = OS_THREAD_STATE_WAITING; - currentThread->queue = queue; - ENQUEUE_THREAD_PRIO(currentThread, queue, link); - RunQueueHint = 1; - __OSReschedule(); - OSRestoreInterrupts(enabled); -} - -void OSWakeupThread(OSThreadQueue* queue) { - BOOL enabled = OSDisableInterrupts(); - - while (queue->head) { - OSThread* thread = queue->head; - - DEQUEUE_HEAD(thread, queue, link); - - ASSERTLINE(LINE(1282, 1313, 1313), __OSIsThreadActive(thread)); - ASSERTLINE(LINE(1283, 1314, 1314), thread->state != OS_THREAD_STATE_MORIBUND); - ASSERTLINE(LINE(1284, 1315, 1315), thread->queue == queue); - thread->state = OS_THREAD_STATE_READY; - if (thread->suspend <= 0) { - SetRun(thread); - } - } - __OSReschedule(); - OSRestoreInterrupts(enabled); -} - -int OSSetThreadPriority(OSThread* thread, s32 priority) { - BOOL enabled; - - ASSERTMSGLINE(LINE(1310, 1341, 1341), (priority >= OS_PRIORITY_MIN) && (priority <= OS_PRIORITY_MAX), "OSSetThreadPriority(): priority out of range (0 <= priority <= 31)."); - - if ((priority < OS_PRIORITY_MIN) || (priority > OS_PRIORITY_MAX)) { - return 0; - } - enabled = OSDisableInterrupts(); - - ASSERTMSG1LINE(LINE(1317, 1348, 1348), __OSIsThreadActive(thread) != 0, "OSSetThreadPriority(): thread %p is not active.", thread); - ASSERTMSG1LINE(LINE(1319, 1350, 1350), thread->state != 8, "OSSetThreadPriority(): thread %p is terminated.", thread); - - if (thread->base != priority) { - thread->base = priority; - UpdatePriority(thread); - __OSReschedule(); - } - OSRestoreInterrupts(enabled); - return 1; -} - -s32 OSGetThreadPriority(OSThread* thread) { - return thread->base; -} - -OSThread* OSSetIdleFunction(OSIdleFunction idleFunction, void* param, void* stack, u32 stackSize) { - if (idleFunction) { - if (IdleThread.state == 0) { - OSCreateThread(&IdleThread, (void*)idleFunction, param, stack, stackSize, OS_PRIORITY_MAX, 1); - OSResumeThread(&IdleThread); - return &IdleThread; - } - } else if (IdleThread.state != 0) { - OSCancelThread(&IdleThread); - } - return NULL; -} - -OSThread* OSGetIdleFunction(void) { - if (IdleThread.state != 0) { - return &IdleThread; - } - return NULL; -} - -static int CheckThreadQueue(OSThreadQueue* queue) { - OSThread* thread; - - if ((queue->head != NULL) && (queue->head->link.prev != NULL)) { - return 0; - } - if ((queue->tail != NULL) && (queue->tail->link.next != NULL)) { - return 0; - } - thread = queue->head; - while (thread) { - if ((thread->link.next != NULL) && (thread != thread->link.next->link.prev)) { - return 0; - } - if ((thread->link.prev != NULL) && (thread != thread->link.prev->link.next)) { - return 0; - } - thread = thread->link.next; - } - return 1; -} - -static BOOL IsMember(OSThreadQueue* queue, OSThread* thread) { - OSThread* member = queue->head; - - while (member) { - if (thread == member) { - return TRUE; - } - member = member->link.next; - } - return FALSE; -} - -// custom macro for OSCheckActiveThreads? -#define ASSERTREPORT(line, cond) \ - if (!(cond)) { \ - OSReport("OSCheckActiveThreads: Failed " #cond " in %d\n", line); \ - OSPanic(__FILE__, line, ""); \ - } - -s32 OSCheckActiveThreads(void) { - OSThread* thread; - s32 prio; - s32 cThread; - BOOL enabled; - - cThread = 0; - enabled = OSDisableInterrupts(); - - for (prio = 0; prio <= OS_PRIORITY_MAX; prio++) { - if (RunQueueBits & (1 << (OS_PRIORITY_MAX - prio))) { - ASSERTREPORT(LINE(1473, 1504, 1504), RunQueue[prio].head != NULL && RunQueue[prio].tail != NULL); - } else { - ASSERTREPORT(LINE(1478, 1509, 1509), RunQueue[prio].head == NULL && RunQueue[prio].tail == NULL); - } - ASSERTREPORT(LINE(1480, 1511, 1511), CheckThreadQueue(&RunQueue[prio])); - } - - ASSERTREPORT(LINE(1485, 1516, 1516), __OSActiveThreadQueue.head == NULL || __OSActiveThreadQueue.head->linkActive.prev == NULL); - ASSERTREPORT(LINE(1487, 1518, 1518), __OSActiveThreadQueue.tail == NULL || __OSActiveThreadQueue.tail->linkActive.next == NULL); - - thread = __OSActiveThreadQueue.head; - while (thread) { - cThread++; - ASSERTREPORT(LINE(1495, 1526, 1526), thread->linkActive.next == NULL || thread == thread->linkActive.next->linkActive.prev); - ASSERTREPORT(LINE(1497, 1528, 1528), thread->linkActive.prev == NULL || thread == thread->linkActive.prev->linkActive.next); - ASSERTREPORT(LINE(1500, 1531, 1531), *(thread->stackEnd) == OS_THREAD_STACK_MAGIC); - ASSERTREPORT(LINE(1503, 1534, 1534), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX+1); - ASSERTREPORT(LINE(1504, 1535, 1535), 0 <= thread->suspend); - ASSERTREPORT(LINE(1505, 1536, 1536), CheckThreadQueue(&thread->queueJoin)); - - switch(thread->state) { - case OS_THREAD_STATE_READY: - if (thread->suspend <= 0) { - ASSERTREPORT(LINE(1511, 1542, 1542), thread->queue == &RunQueue[thread->priority]); - ASSERTREPORT(LINE(1512, 1543, 1543), IsMember(&RunQueue[thread->priority], thread)); - ASSERTREPORT(LINE(1513, 1544, 1544), thread->priority == __OSGetEffectivePriority(thread)); - } - break; - case OS_THREAD_STATE_RUNNING: - ASSERTREPORT(LINE(1517, 1548, 1548), !IsSuspended(thread->suspend)); - ASSERTREPORT(LINE(1518, 1549, 1549), thread->queue == NULL); - ASSERTREPORT(LINE(1519, 1550, 1550), thread->priority == __OSGetEffectivePriority(thread)); - break; - case OS_THREAD_STATE_WAITING: - ASSERTREPORT(LINE(1522, 1553, 1553), thread->queue != NULL); - ASSERTREPORT(LINE(1523, 1554, 1554), CheckThreadQueue(thread->queue)); - ASSERTREPORT(LINE(1524, 1555, 1555), IsMember(thread->queue, thread)); - if (thread->suspend <= 0) { - ASSERTREPORT(LINE(1527, 1558, 1558), thread->priority == __OSGetEffectivePriority(thread)); - } else { - ASSERTREPORT(LINE(1531, 1562, 1562), thread->priority == 32); - } - ASSERTREPORT(LINE(1533, 1564, 1564), !__OSCheckDeadLock(thread)); - break; - case OS_THREAD_STATE_MORIBUND: - ASSERTREPORT(LINE(1537, 1568, 1568), thread->queueMutex.head == NULL && thread->queueMutex.tail == NULL); - break; - default: - OSReport("OSCheckActiveThreads: Failed. unkown thread state (%d) of thread %p\n", thread->state, thread); - OSPanic(__FILE__, LINE(1543, 1574, 1574), ""); - } - ASSERTREPORT(LINE(1548, 1579, 1579), __OSCheckMutexes(thread)); - thread = thread->linkActive.next; - } - OSRestoreInterrupts(enabled); - return cThread; -} - -void OSClearStack(u8 val) { - register u32 sp; - register u32* p; - register u32 pattern; - - pattern = (val << 24) | (val << 16) | (val << 8) | val; - sp = OSGetStackPointer(); - for (p = __OSCurrentThread->stackEnd + 1; (u32)p < sp; ++p) { - *p = pattern; - } -} - -void OSSetThreadSpecific(s32 index, void* ptr) { - OSThread* thread; - - thread = __OSCurrentThread; - ASSERTLINE(LINE(1573, 1604, 1604), 0 <= index && index < OS_THREAD_SPECIFIC_MAX); - - if (thread != 0 && index >= 0 && index < OS_THREAD_SPECIFIC_MAX) { - thread->specific[index] = ptr; - } -} - -void* OSGetThreadSpecific(s32 index) { - OSThread* thread; - - thread = __OSCurrentThread; - ASSERTLINE(LINE(1584, 1615, 1615), 0 <= index && index < OS_THREAD_SPECIFIC_MAX); - - if (thread != 0 && index >= 0 && index < OS_THREAD_SPECIFIC_MAX) { - return thread->specific[index]; - } - - return NULL; -} diff --git a/src/dolphin/os/OSTime.c b/src/dolphin/os/OSTime.c deleted file mode 100644 index 5813615..0000000 --- a/src/dolphin/os/OSTime.c +++ /dev/null @@ -1,200 +0,0 @@ -#include -#include - -#include "__os.h" - -// End of each month in standard year -static int YearDays[MONTH_MAX] = {0, 31, 59, 90, 120, 151, - 181, 212, 243, 273, 304, 334}; -// End of each month in leap year -static int LeapYearDays[MONTH_MAX] = {0, 31, 60, 91, 121, 152, - 182, 213, 244, 274, 305, 335}; - -#ifdef __GEKKO__ -asm OSTime OSGetTime(void) { -jump: - nofralloc - - mftbu r3 - mftb r4 - - // Check for possible carry from TBL to TBU - mftbu r5 - cmpw r3, r5 - bne jump - - blr -} - -asm OSTick OSGetTick(void){ - nofralloc - - mftb r3 - blr -} - -asm static void __SetTime(OSTime time) { - nofralloc - li r5, 0 - mttbl r5 - mttbu r3 - mttbl r4 - blr -} -#endif - -void __OSSetTime(OSTime time) { - BOOL enabled; - OSTime * timeAdjustAddr; - - timeAdjustAddr = __OSSystemTime; - enabled = OSDisableInterrupts(); - - *timeAdjustAddr += OSGetTime() - time; - __SetTime(time); - EXIProbeReset(); - OSRestoreInterrupts(enabled); -} - -OSTime __OSGetSystemTime() { - BOOL enabled; - OSTime* timeAdjustAddr; - OSTime result; - - timeAdjustAddr = __OSSystemTime; - enabled = OSDisableInterrupts(); - - result = OSGetTime() + *timeAdjustAddr; - OSRestoreInterrupts(enabled); - return result; -} - -OSTime __OSTimeToSystemTime(OSTime time) { - BOOL enabled; - OSTime* timeAdjustAddr = __OSSystemTime; - OSTime result; - - enabled = OSDisableInterrupts(); - result = *timeAdjustAddr + time; - OSRestoreInterrupts(enabled); - return result; -} - -#ifdef __GEKKO__ -asm void __OSSetTick(register OSTick newTicks) { - nofralloc - mttbl newTicks - blr -} -#endif - -static int IsLeapYear(int year) { - return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); -} - -static int GetYearDays(int year, int mon) { - int* md = (IsLeapYear(year)) ? LeapYearDays : YearDays; - - return md[mon]; -} - -static int GetLeapDays(int year) { - ASSERTLINE(286, 0 <= year); - - if (year < 1) { - return 0; - } - return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; -} - -static void GetDates(int days, OSCalendarTime* td) { - int year; - int n; - int month; - int * md; - - ASSERTLINE(311, 0 <= days); - - td->wday = (days + 6) % WEEK_DAY_MAX; - - for (year = days / YEAR_DAY_MAX; - days < (n = year * YEAR_DAY_MAX + GetLeapDays(year)); year--) { - ; - } - - days -= n; - td->year = year; - td->yday = days; - - md = IsLeapYear(year) ? LeapYearDays : YearDays; - for (month = MONTH_MAX; days < md[--month];) { - ; - } - td->mon = month; - td->mday = days - md[month] + 1; -} - -void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) { - int days; - int secs; - OSTime d; - - d = ticks % OS_SEC_TO_TICKS(1); - if (d < 0) { - d += OS_SEC_TO_TICKS(1); - ASSERTLINE(356, 0 <= d); - } - - td->usec = OS_TICKS_TO_USEC(d) % USEC_MAX; - td->msec = OS_TICKS_TO_MSEC(d) % MSEC_MAX; - - ASSERTLINE(360, 0 <= td->usec); - ASSERTLINE(361, 0 <= td->msec); - - ticks -= d; - - ASSERTLINE(364, ticks % OSSecondsToTicks(1) == 0); - ASSERTLINE(368, 0 <= OSTicksToSeconds(ticks) / 86400 + BIAS && OSTicksToSeconds(ticks) / 86400 + BIAS <= INT_MAX); - - days = (OS_TICKS_TO_SEC(ticks) / SECS_IN_DAY) + BIAS; - secs = OS_TICKS_TO_SEC(ticks) % SECS_IN_DAY; - if (secs < 0) { - days -= 1; - secs += SECS_IN_DAY; - ASSERTLINE(375, 0 <= secs); - } - - GetDates(days, td); - td->hour = secs / 60 / 60; - td->min = secs / 60 % 60; - td->sec = secs % 60; -} - -OSTime OSCalendarTimeToTicks(OSCalendarTime* td) { - OSTime secs; - int ov_mon; - int mon; - int year; - - ov_mon = td->mon / MONTH_MAX; - mon = td->mon - (ov_mon * MONTH_MAX); - - if (mon < 0) { - mon += MONTH_MAX; - ov_mon--; - } - - ASSERTLINE(412, (ov_mon <= 0 && 0 <= td->year + ov_mon) || (0 < ov_mon && td->year <= INT_MAX - ov_mon)); - - year = td->year + ov_mon; - - secs = (OSTime)SECS_IN_YEAR * year + - (OSTime)SECS_IN_DAY * (GetLeapDays(year) + GetYearDays(year, mon) + td->mday - 1) + - (OSTime)SECS_IN_HOUR * td->hour + - (OSTime)SECS_IN_MIN * td->min + - td->sec - - (OSTime)0xEB1E1BF80ULL; - - return OS_SEC_TO_TICKS(secs) + OS_MSEC_TO_TICKS((OSTime)td->msec) + - OS_USEC_TO_TICKS((OSTime)td->usec); -} diff --git a/src/dolphin/os/OSTimer.c b/src/dolphin/os/OSTimer.c deleted file mode 100644 index 99c13a6..0000000 --- a/src/dolphin/os/OSTimer.c +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include - -#include "__os.h" - -struct Timer { - OSTimerCallback callback; - u32 currval; - u32 startval; - u32 mode; - BOOL stopped; - BOOL initialized; -}; -static struct Timer Timer; - -// prototypes -static void DecrementerExceptionHandler(__OSException exception, OSContext* context); - -OSTimerCallback OSSetTimerCallback(OSTimerCallback callback) { - OSTimerCallback prevCallback; - -#if DEBUG - if(!Timer.initialized) { - OSPanic(__FILE__, 135, "OSSetTimerCallback(): timer is not initialized."); - } -#endif - - Timer.stopped = TRUE; - prevCallback = Timer.callback; - Timer.callback = callback; - return prevCallback; -} - -void OSInitTimer(u32 time, u32 mode) { -#if DEBUG - if (time >= 0x80000000) { - OSPanic(__FILE__, 159, "OSInitTimer(): time param must be less than 0x80000000."); - } -#endif - - Timer.stopped = TRUE; - Timer.currval = time; - Timer.startval = time; - Timer.mode = mode; - - if (!Timer.initialized) { - __OSSetExceptionHandler(8, &DecrementerExceptionHandler); - Timer.initialized = TRUE; - Timer.callback = 0; -#if DEBUG - OSReport("Timer initialized\n"); -#endif - } -} - -void OSStartTimer(void) { - BOOL enabled; - -#if DEBUG - if (!Timer.initialized) { - OSPanic(__FILE__, 192, "OSStartTimer(): timer is not initialized."); - } -#endif - enabled = OSDisableInterrupts(); - PPCMtdec(Timer.currval); - Timer.stopped = FALSE; - OSRestoreInterrupts(enabled); -} - -void OSStopTimer(void) { - BOOL enabled; - -#if DEBUG - if (!Timer.initialized) { - OSPanic(__FILE__, 216, "OSStopTimer(): timer is not initialized."); - } -#endif - - enabled = OSDisableInterrupts(); - if (!Timer.stopped) { - Timer.stopped = TRUE; - Timer.currval = PPCMfdec(); - if (Timer.currval & 0x80000000) { - Timer.currval = 0; - } - } - OSRestoreInterrupts(enabled); -} - -static void DecrementerExceptionCallback(__OSException exception, OSContext* context) { - OSContext exceptionContext; - - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - - if (!Timer.stopped) { - if (Timer.mode == 1) { - PPCMtdec(Timer.startval); - } - if (Timer.mode == 2) { - Timer.stopped = TRUE; - } - if (Timer.callback) { - Timer.callback(); - } - } - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); - OSLoadContext(context); -} - -#ifdef __GEKKO__ -static asm void DecrementerExceptionHandler(__OSException exception, - register OSContext* context) { - nofralloc - - stw r0, context->gpr[0] - stw r1, context->gpr[1] - stw r2, context->gpr[2] - stmw r6, context->gpr[6] - - mfspr r0, GQR1 - stw r0, context->gqr[1] - mfspr r0, GQR2 - stw r0, context->gqr[2] - mfspr r0, GQR3 - stw r0, context->gqr[3] - mfspr r0, GQR4 - stw r0, context->gqr[4] - mfspr r0, GQR5 - stw r0, context->gqr[5] - mfspr r0, GQR6 - stw r0, context->gqr[6] - mfspr r0, GQR7 - stw r0, context->gqr[7] - - stwu r1, -0x8(r1) - b DecrementerExceptionCallback -} -#endif diff --git a/src/dolphin/os/OSUtf.c b/src/dolphin/os/OSUtf.c deleted file mode 100644 index ddfa23d..0000000 --- a/src/dolphin/os/OSUtf.c +++ /dev/null @@ -1,6341 +0,0 @@ -#include -#include - -char* OSUTF8to32(const char* utf8, u32* utf32) { - u32 u; - u8 c; - unsigned int len; - unsigned int i; - - c = *utf8; - if (c != 0) { - utf8++; - } - - if ((c & 0x80) == 0) { - u = c; - len = 0; - } else if ((c & 0xE0) == 0xC0u) { - u = c & 0x1F; - len = 1; - } else if ((c & 0xF0) == 0xE0u) { - u = c & 0xF; - len = 2; - } else if ((c & 0xF8) == 0xF0u) { - u = c & 0x7; - len = 3; - } else { - return NULL; - } - - for (i = 0; i < len; i++) { - u = u << 6; - c = *utf8++; - if ((c & 0xC0) != 0x80u) { - return NULL; - } - - u |= (c & 0x3F); - } - - if (u <= 0x7Fu) { - if (len != 0) { - return NULL; - } - } else if (u <= 0x7FFu) { - if (len != 1) { - return NULL; - } - } else if (u <= 0xFFFFu) { - if (len != 2) { - return NULL; - } - } - - if (u >= 0xD800u && u <= 0xDFFFu) { - return NULL; - } - - *utf32 = u; - return (char*)utf8; -} - -char* OSUTF32to8(u32 utf32, char* utf8) { - int len; - - if (utf32 >= 0xD800u && utf32 <= 0xDFFFu) { - return NULL; - } - - if (utf32 < 0x80u) { - *utf8 = (s8)utf32; - utf8++; - } else if (utf32 < 0x800u) { - *utf8 = (utf32 >> 6) | 0xC0; - utf8++; - len = 1; - } else if (utf32 < 0x10000u) { - *utf8 = (utf32 >> 0xC) | 0xE0; - utf8++; - len = 2; - } else if (utf32 < 0x110000u) { - *utf8 = (utf32 >> 0x12) | 0xF0; - utf8++; - len = 3; - } else { - return NULL; - } - - while (len-- > 0) { - *utf8 = ((utf32 >> (len * 6)) & 0x3F) | 0x80; - utf8++; - } - - return utf8; -} - -u16* OSUTF16to32(const u16* utf16, u32* utf32) { - u16 w1; - u16 w2; - u32 u; - - w1 = *utf16; - if (w1 != 0) { - utf16++; - } - - if (w1 < 0xD800 || w1 > 0xDFFF) { - u = w1; - } else if (w1 <= 0xDBFF) { - w2 = *utf16; - utf16++; - - if (w2 >= 0xDC00 && w2 <= 0xDFFF) { - u = ((w1 << 10) & 0xFFC00) | ((w2 & 0x3FF) & ~0xFFC00); - u = u + 0x10000; - } else { - return NULL; - } - } else { - return NULL; - } - - *utf32 = u; - return (u16*)utf16; -} - -u16* OSUTF32to16(u32 utf32, u16* utf16) { - u16 w1; - u16 w2; - - if (utf32 >= 0xD800u && utf32 <= 0xDFFFu) { - return NULL; - } - - if (utf32 < 0x10000u) { - *utf16 = utf32; - utf16++; - } else if (utf32 <= 0x10FFFFu) { - w1 = -0x122800; - w2 = -0x122400; - utf32 -= 0x10000; - ASSERTLINE(0xD1, utf32 <= 0xFFFFF); - - w1 |= utf32 >> 10; - w2 |= utf32 & 0x3FF; - - *utf16++ = w1; - *utf16++ = w2; - } else { - return NULL; - } - - return utf16; -} - -static u16 UcsAnsiTable[32] = { - 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, - 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, - 0x0152, 0x0000, 0x017D, 0x0000, 0x0000, 0x2018, - 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, - 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, - 0x017E, 0x0178, -}; - -u8 OSUTF32toANSI(u32 utf32) { - int i; - - if (utf32 > 0xFF) { - return 0; - } - - if (utf32 < 0x80 || utf32 > 0x9F) { - return utf32; - } - - if (utf32 >= 0x152 && utf32 <= 0x2122) { - for (i = 0; i <= 31; i++) { - if (utf32 == UcsAnsiTable[i]) { - return i + 0x80; - } - } - } - - return 0; -} - -u32 OSANSItoUTF32(u8 ansi) { - if (ansi >= 0x80 && ansi <= 0x9F) { - return UcsAnsiTable[ansi - 0x80]; - } - - return ansi; -} - -static u16 Ucs00[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, - 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, - 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, - 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, - 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, - 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005A, 0x005B, 0x815F, 0x005D, 0x005E, 0x005F, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, - 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, - 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, - 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, - 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8191, 0x8192, 0x0000, 0x005C, 0x0000, 0x8198, - 0x814E, 0x0000, 0x0000, 0x0000, 0x81CA, 0x0000, - 0x0000, 0x0000, 0x818B, 0x817D, 0x0000, 0x0000, - 0x814C, 0x0000, 0x81F7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x817E, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8180, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs03[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x839F, 0x83A0, 0x83A1, 0x83A2, 0x83A3, - 0x83A4, 0x83A5, 0x83A6, 0x83A7, 0x83A8, 0x83A9, - 0x83AA, 0x83AB, 0x83AC, 0x83AD, 0x83AE, 0x83AF, - 0x0000, 0x83B0, 0x83B1, 0x83B2, 0x83B3, 0x83B4, - 0x83B5, 0x83B6, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x83BF, 0x83C0, 0x83C1, - 0x83C2, 0x83C3, 0x83C4, 0x83C5, 0x83C6, 0x83C7, - 0x83C8, 0x83C9, 0x83CA, 0x83CB, 0x83CC, 0x83CD, - 0x83CE, 0x83CF, 0x0000, 0x83D0, 0x83D1, 0x83D2, - 0x83D3, 0x83D4, 0x83D5, 0x83D6, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs04[256] = { - 0x0000, 0x8446, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8440, 0x8441, - 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, - 0x8449, 0x844A, 0x844B, 0x844C, 0x844D, 0x844E, - 0x844F, 0x8450, 0x8451, 0x8452, 0x8453, 0x8454, - 0x8455, 0x8456, 0x8457, 0x8458, 0x8459, 0x845A, - 0x845B, 0x845C, 0x845D, 0x845E, 0x845F, 0x8460, - 0x8470, 0x8471, 0x8472, 0x8473, 0x8474, 0x8475, - 0x8477, 0x8478, 0x8479, 0x847A, 0x847B, 0x847C, - 0x847D, 0x847E, 0x8480, 0x8481, 0x8482, 0x8483, - 0x8484, 0x8485, 0x8486, 0x8487, 0x8488, 0x8489, - 0x848A, 0x848B, 0x848C, 0x848D, 0x848E, 0x848F, - 0x8490, 0x8491, 0x0000, 0x8476, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs20[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x815D, 0x0000, - 0x0000, 0x0000, 0x0000, 0x815C, 0x8161, 0x0000, - 0x8165, 0x8166, 0x0000, 0x0000, 0x8167, 0x8168, - 0x0000, 0x0000, 0x81F5, 0x81F6, 0x0000, 0x0000, - 0x0000, 0x8164, 0x8163, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x81F1, 0x0000, 0x818C, 0x818D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x81A6, - 0x0000, 0x0000, 0x007E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs21[256] = { - 0x0000, 0x0000, 0x0000, 0x818E, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x81F0, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x81A9, 0x81AA, 0x81A8, 0x81AB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x81CB, 0x0000, 0x81CC, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs22[256] = { - 0x81CD, 0x0000, 0x81DD, 0x81CE, 0x0000, 0x0000, - 0x0000, 0x81DE, 0x81B8, 0x0000, 0x0000, 0x81B9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x817C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x81E3, 0x0000, 0x0000, 0x81E5, - 0x8187, 0x0000, 0x81DA, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x81C8, 0x81C9, 0x81BF, - 0x81BE, 0x81E7, 0x81E8, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8188, 0x81E6, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x81E4, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x81E0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8182, 0x81DF, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8185, 0x8186, 0x0000, 0x0000, 0x81E1, 0x81E2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x81BC, 0x81BD, - 0x0000, 0x0000, 0x81BA, 0x81BB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x81DB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs23[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x81DC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs25[256] = { - 0x849F, 0x84AA, 0x84A0, 0x84AB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x84A1, 0x0000, 0x0000, 0x84AC, 0x84A2, 0x0000, - 0x0000, 0x84AD, 0x84A4, 0x0000, 0x0000, 0x84AF, - 0x84A3, 0x0000, 0x0000, 0x84AE, 0x84A5, 0x84BA, - 0x0000, 0x0000, 0x84B5, 0x0000, 0x0000, 0x84B0, - 0x84A7, 0x84BC, 0x0000, 0x0000, 0x84B7, 0x0000, - 0x0000, 0x84B2, 0x84A6, 0x0000, 0x0000, 0x84B6, - 0x84BB, 0x0000, 0x0000, 0x84B1, 0x84A8, 0x0000, - 0x0000, 0x84B8, 0x84BD, 0x0000, 0x0000, 0x84B3, - 0x84A9, 0x0000, 0x0000, 0x84B9, 0x0000, 0x0000, - 0x84BE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x84B4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x81A1, 0x81A0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x81A3, 0x81A2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x81A5, 0x81A4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x819F, 0x819E, 0x0000, 0x0000, 0x0000, 0x819B, - 0x0000, 0x0000, 0x819D, 0x819C, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x81FC, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs26[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x819A, - 0x8199, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x818A, 0x0000, - 0x8189, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x81F4, 0x0000, - 0x0000, 0x81F3, 0x0000, 0x81F2, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs30[256] = { - 0x8140, 0x8141, 0x8142, 0x8156, 0x0000, 0x8158, - 0x8159, 0x815A, 0x8171, 0x8172, 0x8173, 0x8174, - 0x8175, 0x8176, 0x8177, 0x8178, 0x8179, 0x817A, - 0x81A7, 0x81AC, 0x816B, 0x816C, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8160, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x829F, - 0x82A0, 0x82A1, 0x82A2, 0x82A3, 0x82A4, 0x82A5, - 0x82A6, 0x82A7, 0x82A8, 0x82A9, 0x82AA, 0x82AB, - 0x82AC, 0x82AD, 0x82AE, 0x82AF, 0x82B0, 0x82B1, - 0x82B2, 0x82B3, 0x82B4, 0x82B5, 0x82B6, 0x82B7, - 0x82B8, 0x82B9, 0x82BA, 0x82BB, 0x82BC, 0x82BD, - 0x82BE, 0x82BF, 0x82C0, 0x82C1, 0x82C2, 0x82C3, - 0x82C4, 0x82C5, 0x82C6, 0x82C7, 0x82C8, 0x82C9, - 0x82CA, 0x82CB, 0x82CC, 0x82CD, 0x82CE, 0x82CF, - 0x82D0, 0x82D1, 0x82D2, 0x82D3, 0x82D4, 0x82D5, - 0x82D6, 0x82D7, 0x82D8, 0x82D9, 0x82DA, 0x82DB, - 0x82DC, 0x82DD, 0x82DE, 0x82DF, 0x82E0, 0x82E1, - 0x82E2, 0x82E3, 0x82E4, 0x82E5, 0x82E6, 0x82E7, - 0x82E8, 0x82E9, 0x82EA, 0x82EB, 0x82EC, 0x82ED, - 0x82EE, 0x82EF, 0x82F0, 0x82F1, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x814A, - 0x814B, 0x8154, 0x8155, 0x0000, 0x0000, 0x8340, - 0x8341, 0x8342, 0x8343, 0x8344, 0x8345, 0x8346, - 0x8347, 0x8348, 0x8349, 0x834A, 0x834B, 0x834C, - 0x834D, 0x834E, 0x834F, 0x8350, 0x8351, 0x8352, - 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0x8358, - 0x8359, 0x835A, 0x835B, 0x835C, 0x835D, 0x835E, - 0x835F, 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, - 0x8365, 0x8366, 0x8367, 0x8368, 0x8369, 0x836A, - 0x836B, 0x836C, 0x836D, 0x836E, 0x836F, 0x8370, - 0x8371, 0x8372, 0x8373, 0x8374, 0x8375, 0x8376, - 0x8377, 0x8378, 0x8379, 0x837A, 0x837B, 0x837C, - 0x837D, 0x837E, 0x8380, 0x8381, 0x8382, 0x8383, - 0x8384, 0x8385, 0x8386, 0x8387, 0x8388, 0x8389, - 0x838A, 0x838B, 0x838C, 0x838D, 0x838E, 0x838F, - 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, 0x8395, - 0x8396, 0x0000, 0x0000, 0x0000, 0x0000, 0x8145, - 0x815B, 0x8152, 0x8153, 0x0000 -}; - -static u16 Ucs4E[256] = { - 0x88EA, 0x929A, 0x0000, 0x8EB5, 0x0000, 0x0000, - 0x0000, 0x969C, 0x8FE4, 0x8E4F, 0x8FE3, 0x89BA, - 0x0000, 0x9573, 0x975E, 0x0000, 0x98A0, 0x894E, - 0x0000, 0x0000, 0x8A8E, 0x98A1, 0x90A2, 0x99C0, - 0x8B75, 0x95B8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8FE5, 0x0000, 0x0000, 0x97BC, 0x0000, 0x0000, - 0x0000, 0x0000, 0x95C0, 0x0000, 0x0000, 0x0000, - 0x98A2, 0x0000, 0x0000, 0x9286, 0x0000, 0x0000, - 0x0000, 0x98A3, 0x8BF8, 0x0000, 0x0000, 0x0000, - 0x98A4, 0x0000, 0x8ADB, 0x924F, 0x0000, 0x8EE5, - 0x98A5, 0x0000, 0x0000, 0x98A6, 0x0000, 0x0000, - 0x98A7, 0x9454, 0x0000, 0x8B76, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9456, 0x0000, 0x93E1, - 0x8CC1, 0x9652, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE568, 0x98A8, 0x8FE6, 0x98A9, 0x89B3, - 0x0000, 0x0000, 0x0000, 0x8BE3, 0x8CEE, 0x96E7, - 0x0000, 0x0000, 0x9BA4, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9790, - 0x0000, 0x93FB, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8AA3, 0x0000, 0x8B54, 0x0000, 0x98AA, 0x0000, - 0x0000, 0x98AB, 0x97B9, 0x0000, 0x975C, 0x9188, - 0x98AD, 0x8E96, 0x93F1, 0x0000, 0x98B0, 0x0000, - 0x0000, 0x895D, 0x8CDD, 0x0000, 0x8CDC, 0x88E4, - 0x0000, 0x0000, 0x986A, 0x9869, 0x0000, 0x8DB1, - 0x889F, 0x0000, 0x98B1, 0x98B2, 0x98B3, 0x9653, - 0x98B4, 0x0000, 0x8CF0, 0x88E5, 0x9692, 0x0000, - 0x8B9C, 0x0000, 0x0000, 0x8B9D, 0x8B9E, 0x92E0, - 0x97BA, 0x0000, 0x98B5, 0x0000, 0x0000, 0x98B6, - 0x0000, 0x0000, 0x98B7, 0x0000, 0x0000, 0x0000, - 0x906C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8F59, 0x906D, 0x98BC, 0x0000, 0x98BA, 0x0000, - 0x98BB, 0x8B77, 0x0000, 0x0000, 0x8DA1, 0x89EE, - 0x0000, 0x98B9, 0x98B8, 0x95A7, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8E65, 0x8E64, 0x91BC, 0x98BD, - 0x9574, 0x90E5, 0x0000, 0x0000, 0x0000, 0x8157, - 0x98BE, 0x98C0, 0x0000, 0x0000, 0x0000, 0x91E3, - 0x97DF, 0x88C8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x98BF, 0x89BC, 0x0000, - 0x8BC2, 0x0000, 0x9287, 0x0000, 0x0000, 0x0000, - 0x8C8F, 0x98C1, 0x0000, 0x0000, 0x0000, 0x9443, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs4F[256] = { - 0x0000, 0x8AE9, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x98C2, 0x88C9, 0x0000, - 0x0000, 0x8CDE, 0x8AEA, 0x959A, 0x94B0, 0x8B78, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x89EF, 0x0000, 0x98E5, 0x9360, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x948C, - 0x98C4, 0x0000, 0x0000, 0x0000, 0x94BA, 0x0000, - 0x97E0, 0x0000, 0x904C, 0x0000, 0x8E66, 0x0000, - 0x8E97, 0x89BE, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x92CF, 0x0000, 0x0000, 0x9241, 0x98C8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x88CA, - 0x92E1, 0x8F5A, 0x8DB2, 0x9743, 0x0000, 0x91CC, - 0x0000, 0x89BD, 0x0000, 0x98C7, 0x0000, 0x975D, - 0x98C3, 0x98C5, 0x8DEC, 0x98C6, 0x9B43, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x98CE, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x98D1, 0x98CF, 0x0000, - 0x0000, 0x89C0, 0x0000, 0x95B9, 0x98C9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x98CD, 0x8CF1, 0x0000, - 0x0000, 0x8E67, 0x0000, 0x0000, 0x0000, 0x8AA4, - 0x0000, 0x0000, 0x98D2, 0x0000, 0x98CA, 0x0000, - 0x0000, 0x97E1, 0x0000, 0x8E98, 0x0000, 0x98CB, - 0x0000, 0x98D0, 0x0000, 0x0000, 0x0000, 0x0000, - 0x98D3, 0x0000, 0x98CC, 0x0000, 0x0000, 0x8B9F, - 0x0000, 0x88CB, 0x0000, 0x0000, 0x8BA0, 0x89BF, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9B44, 0x0000, 0x9699, - 0x958E, 0x8CF2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x904E, 0x97B5, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95D6, - 0x0000, 0x0000, 0x8C57, 0x91A3, 0x89E2, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8F72, 0x0000, - 0x0000, 0x0000, 0x98D7, 0x0000, 0x98DC, 0x98DA, - 0x0000, 0x0000, 0x98D5, 0x0000, 0x0000, 0x91AD, - 0x98D8, 0x0000, 0x98DB, 0x98D9, 0x0000, 0x95DB, - 0x0000, 0x98D6, 0x0000, 0x904D, 0x0000, 0x9693, - 0x98DD, 0x98DE, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8F43, 0x98EB, - 0x0000, 0x0000, 0x0000, 0x946F, 0x0000, 0x9555, - 0x98E6, 0x0000, 0x95EE, 0x0000, 0x89B4, 0x0000, - 0x0000, 0x0000, 0x98EA, 0x0000 -}; - -static u16 Ucs50[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x98E4, - 0x98ED, 0x0000, 0x0000, 0x9171, 0x0000, 0x8CC2, - 0x0000, 0x947B, 0x0000, 0xE0C5, 0x0000, 0x98EC, - 0x937C, 0x0000, 0x98E1, 0x0000, 0x8CF4, 0x0000, - 0x0000, 0x8CF3, 0x98DF, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8ED8, 0x0000, 0x98E7, 0x0000, 0x95ED, - 0x926C, 0x98E3, 0x8C91, 0x0000, 0x98E0, 0x98E8, - 0x98E2, 0x97CF, 0x98E9, 0x9860, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8BE4, 0x0000, 0x0000, 0x8C90, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x98EE, 0x0000, 0x0000, 0x0000, 0x98EF, - 0x98F3, 0x88CC, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x95CE, 0x98F2, 0x0000, 0x0000, 0x0000, - 0x0000, 0x98F1, 0x98F5, 0x0000, 0x0000, 0x0000, - 0x98F4, 0x0000, 0x92E2, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C92, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x98F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8EC3, 0x0000, 0x91A4, 0x92E3, 0x8BF4, 0x0000, - 0x98F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B55, - 0x0000, 0x0000, 0x98F8, 0x0000, 0x0000, 0x0000, - 0x0000, 0x98FA, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9654, 0x0000, 0x0000, - 0x0000, 0x8C86, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8E50, 0x94F5, 0x98F9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8DC3, 0x9762, - 0x0000, 0x0000, 0x0000, 0x0000, 0x98FC, 0x9942, - 0x98FB, 0x8DC2, 0x0000, 0x8F9D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8C58, 0x0000, - 0x0000, 0x0000, 0x9943, 0x0000, 0x0000, 0x8BCD, - 0x0000, 0x0000, 0x0000, 0x9940, 0x9941, 0x0000, - 0x0000, 0x93AD, 0x0000, 0x919C, 0x0000, 0x8BA1, - 0x0000, 0x0000, 0x0000, 0x966C, 0x9944, 0x0000, - 0x0000, 0x0000, 0x97BB, 0x0000, 0x0000, 0x0000, - 0x9945, 0x0000, 0x0000, 0x0000, 0x0000, 0x9948, - 0x0000, 0x9946, 0x0000, 0x916D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9947, 0x9949, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x994B, - 0x0000, 0x0000, 0x0000, 0x994A, 0x0000, 0x95C6, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs51[256] = { - 0x8B56, 0x994D, 0x994E, 0x0000, 0x89AD, 0x0000, - 0x0000, 0x0000, 0x0000, 0x994C, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8EF2, 0x0000, 0x9951, 0x9950, 0x994F, 0x0000, - 0x98D4, 0x0000, 0x9952, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8F9E, 0x0000, 0x9953, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9744, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x96D7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9955, 0x0000, 0x0000, 0x9954, 0x9957, - 0x9956, 0x0000, 0x0000, 0x9958, 0x9959, 0x88F2, - 0x0000, 0x8CB3, 0x8C5A, 0x8F5B, 0x929B, 0x8BA2, - 0x90E6, 0x8CF5, 0x0000, 0x8D8E, 0x995B, 0x96C6, - 0x9365, 0x0000, 0x8E99, 0x0000, 0x995A, 0x0000, - 0x995C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x937D, 0x0000, 0x8A95, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x995D, 0x0000, 0x0000, 0x93FC, - 0x0000, 0x0000, 0x9153, 0x995F, 0x9960, 0x94AA, - 0x8CF6, 0x985A, 0x9961, 0x0000, 0x0000, 0x8BA4, - 0x0000, 0x0000, 0x0000, 0x95BA, 0x91B4, 0x8BEF, - 0x9354, 0x0000, 0x0000, 0x0000, 0x8C93, 0x0000, - 0x0000, 0x0000, 0x9962, 0x0000, 0x9963, 0x0000, - 0x0000, 0x93E0, 0x897E, 0x0000, 0x0000, 0x9966, - 0x8DFB, 0x0000, 0x9965, 0x8DC4, 0x0000, 0x9967, - 0xE3EC, 0x9968, 0x9660, 0x9969, 0x0000, 0x996A, - 0x996B, 0x8FE7, 0x0000, 0x8ECA, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8AA5, 0x0000, - 0x996E, 0x0000, 0x996C, 0x96BB, 0x996D, 0x0000, - 0x9579, 0x996F, 0x9970, 0x9971, 0x937E, 0x0000, - 0x0000, 0x0000, 0x9975, 0x9973, 0x9974, 0x9972, - 0x8DE1, 0x9976, 0x96E8, 0x97E2, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9977, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x90A6, 0x9978, - 0x8F79, 0x0000, 0x0000, 0x9979, 0x0000, 0x929C, - 0x97BD, 0x9380, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x99C3, 0x0000, - 0x0000, 0x0000, 0x0000, 0x997A, 0xEAA3, 0x8BC3, - 0x0000, 0x0000, 0x997B, 0x967D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8F88, 0x91FA, 0x0000, 0x997D, - 0x93E2, 0x0000, 0x0000, 0x997E, 0x0000, 0x0000, - 0x9980, 0x8A4D, 0x0000, 0x0000, 0x0000, 0x9981, - 0x8BA5, 0x0000, 0x93CA, 0x899A, 0x8F6F, 0x0000, - 0x0000, 0x949F, 0x9982, 0x0000 -}; - -static u16 Ucs52[256] = { - 0x9381, 0x0000, 0x0000, 0x906E, 0x9983, 0x0000, - 0x95AA, 0x90D8, 0x8AA0, 0x0000, 0x8AA7, 0x9984, - 0x0000, 0x0000, 0x9986, 0x0000, 0x0000, 0x8C59, - 0x0000, 0x0000, 0x9985, 0x0000, 0x0000, 0x97F1, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F89, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x94BB, 0x95CA, 0x0000, 0x9987, 0x0000, 0x9798, - 0x9988, 0x0000, 0x0000, 0x0000, 0x9989, 0x0000, - 0x939E, 0x0000, 0x0000, 0x998A, 0x0000, 0x0000, - 0x90A7, 0x8DFC, 0x8C94, 0x998B, 0x8E68, 0x8D8F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x92E4, 0x998D, 0x0000, 0x0000, 0x91A5, - 0x0000, 0x0000, 0x8DED, 0x998E, 0x998F, 0x914F, - 0x0000, 0x998C, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9991, 0x0000, 0x9655, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8D84, 0x0000, 0x0000, 0x9990, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8C95, 0x8DDC, 0x948D, - 0x0000, 0x0000, 0x0000, 0x9994, 0x9992, 0x0000, - 0x0000, 0x0000, 0x0000, 0x959B, 0x8FE8, 0x999B, - 0x8A84, 0x9995, 0x9993, 0x916E, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9997, - 0x0000, 0x9996, 0x0000, 0x0000, 0x0000, 0x8A63, - 0x0000, 0x0000, 0x0000, 0x8C80, 0x999C, 0x97AB, - 0x0000, 0x0000, 0x0000, 0x9998, 0x0000, 0x0000, - 0x0000, 0x999D, 0x999A, 0x0000, 0x9999, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x97CD, - 0x0000, 0x0000, 0x0000, 0x8CF7, 0x89C1, 0x0000, - 0x0000, 0x97F2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8F95, 0x9377, 0x8D85, 0x99A0, 0x99A1, - 0x0000, 0x0000, 0x0000, 0x97E3, 0x0000, 0x0000, - 0x984A, 0x99A3, 0x0000, 0x0000, 0x0000, 0x8CF8, - 0x0000, 0x0000, 0x99A2, 0x0000, 0x8A4E, 0x0000, - 0x0000, 0x99A4, 0x0000, 0x9675, 0x0000, 0x92BA, - 0x0000, 0x9745, 0x0000, 0x95D7, 0x0000, 0x0000, - 0x0000, 0x99A5, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE8D3, 0x0000, 0x0000, 0x93AE, 0x0000, 0x99A6, - 0x8AA8, 0x96B1, 0x0000, 0x0000, 0x0000, 0x8F9F, - 0x99A7, 0x95E5, 0x99AB, 0x0000, 0x90A8, 0x99A8, - 0x8BCE, 0x0000, 0x99A9, 0x8AA9, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8C4D, 0x99AC, 0x0000, 0x99AD, - 0x0000, 0x0000, 0x99AE, 0x99AF, 0x8ED9, 0x0000, - 0x0000, 0x0000, 0x8CF9, 0x96DC -}; - -static u16 Ucs53[256] = { - 0x0000, 0x96E6, 0x93F5, 0x0000, 0x0000, 0x95EF, - 0x99B0, 0x0000, 0x99B1, 0x0000, 0x0000, 0x0000, - 0x0000, 0x99B3, 0x0000, 0x99B5, 0x99B4, 0x0000, - 0x0000, 0x0000, 0x0000, 0x99B6, 0x89BB, 0x966B, - 0x0000, 0x8DFA, 0x99B7, 0x0000, 0x0000, 0x9178, - 0x0000, 0x0000, 0x8FA0, 0x8BA7, 0x0000, 0x99B8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x94D9, 0x0000, 0x0000, 0x0000, 0x0000, 0x99B9, - 0x0000, 0x99BA, 0x0000, 0x99BB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x99BC, 0x9543, 0x8BE6, 0x88E3, - 0x0000, 0x0000, 0x0000, 0x93BD, 0x99BD, 0x8F5C, - 0x0000, 0x90E7, 0x0000, 0x99BF, 0x99BE, 0x8FA1, - 0x8CDF, 0x99C1, 0x94BC, 0x0000, 0x0000, 0x99C2, - 0x0000, 0x0000, 0x0000, 0x94DA, 0x91B2, 0x91EC, - 0x8BA6, 0x0000, 0x0000, 0x93EC, 0x9250, 0x0000, - 0x948E, 0x0000, 0x966D, 0x0000, 0x99C4, 0x0000, - 0x90E8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8C54, 0x0000, 0x0000, 0x99C5, 0x0000, 0x0000, - 0x0000, 0x0000, 0x99C6, 0x894B, 0x88F3, 0x8AEB, - 0x0000, 0x91A6, 0x8B70, 0x9791, 0x0000, 0x99C9, - 0x89B5, 0x0000, 0x0000, 0x99C8, 0x0000, 0x0000, - 0x0000, 0x8BA8, 0x0000, 0x0000, 0x99CA, 0x0000, - 0x96EF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x99CB, 0x0000, 0x97D0, 0x0000, 0x8CFA, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8CB4, 0x99CC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x99CE, 0x99CD, 0x0000, - 0x907E, 0x8958, 0x0000, 0x0000, 0x0000, 0x897D, - 0x99CF, 0x0000, 0x99D0, 0x0000, 0x0000, 0x8CB5, - 0x0000, 0x0000, 0x99D1, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8B8E, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8E51, 0x99D2, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9694, 0x8DB3, 0x8B79, 0x9746, - 0x916F, 0x94BD, 0x8EFB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8F66, 0x0000, 0x8EE6, 0x8EF3, - 0x0000, 0x8F96, 0x0000, 0x94BE, 0x0000, 0x0000, - 0x0000, 0x99D5, 0x0000, 0x8962, 0x9170, 0x8CFB, - 0x8CC3, 0x8BE5, 0x0000, 0x0000, 0x99D9, 0x9240, - 0x91FC, 0x8BA9, 0x8FA2, 0x99DA, 0x99D8, 0x89C2, - 0x91E4, 0x8EB6, 0x8E6A, 0x8945, 0x0000, 0x0000, - 0x8A90, 0x8D86, 0x8E69, 0x0000, 0x99DB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs54[256] = { - 0x0000, 0x99DC, 0x0000, 0x8B68, 0x8A65, 0x0000, - 0x0000, 0x0000, 0x8D87, 0x8B67, 0x92DD, 0x8944, - 0x93AF, 0x96BC, 0x8D40, 0x9799, 0x9366, 0x8CFC, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8C4E, 0x0000, 0x99E5, - 0x0000, 0x8BE1, 0x9669, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x94DB, 0x0000, 0x0000, 0x99E4, - 0x0000, 0x8ADC, 0x99DF, 0x99E0, 0x99E2, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x99E3, 0x0000, 0x8B7A, 0x9081, 0x0000, 0x95AB, - 0x99E1, 0x99DD, 0x8CE1, 0x0000, 0x99DE, 0x0000, - 0x9843, 0x0000, 0x0000, 0x0000, 0x95F0, 0x0000, - 0x92E6, 0x8CE0, 0x8D90, 0x0000, 0x0000, 0x0000, - 0x99E6, 0x0000, 0x0000, 0x93DB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x99EA, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8EFC, 0x0000, 0x8EF4, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x99ED, 0x99EB, - 0x0000, 0x96A1, 0x0000, 0x99E8, 0x99F1, 0x99EC, - 0x0000, 0x0000, 0x0000, 0x99EF, 0x8CC4, 0x96BD, - 0x0000, 0x0000, 0x99F0, 0x0000, 0x0000, 0x0000, - 0x99F2, 0x0000, 0x99F4, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8DEE, 0x9861, 0x0000, 0x99E9, 0x99E7, - 0x99F3, 0x0000, 0x99EE, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x99F6, 0x0000, 0x9A42, 0x99F8, 0x0000, 0x0000, - 0x99FC, 0x0000, 0x0000, 0x9A40, 0x99F9, 0x0000, - 0x0000, 0x9A5D, 0x0000, 0x0000, 0x8DE7, 0x8A50, - 0x0000, 0x0000, 0x0000, 0x0000, 0x99F7, 0x0000, - 0x0000, 0x0000, 0x9A44, 0x88F4, 0x9A43, 0x0000, - 0x88A3, 0x9569, 0x9A41, 0x0000, 0x99FA, 0x0000, - 0x0000, 0x99F5, 0x99FB, 0x8DC6, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9A45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x88F5, 0x9A4E, 0x0000, - 0x0000, 0x9A46, 0x9A47, 0x0000, 0x8FA3, 0x9689, - 0x0000, 0x0000, 0x0000, 0x9A4C, 0x9A4B, 0x0000, - 0x0000, 0x0000, 0x934E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9A4D, 0x0000, - 0x0000, 0x9A4A, 0x0000, 0x0000 -}; - -static u16 Ucs55[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x8953, 0x0000, - 0x8DB4, 0x904F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9A48, 0x9382, 0x0000, - 0x0000, 0x0000, 0x9A49, 0x0000, 0x88A0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9A53, 0x9742, - 0x0000, 0x8FA5, 0x0000, 0x9A59, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A58, 0x9A4F, 0x0000, 0x0000, - 0x0000, 0x0000, 0x91C1, 0x0000, 0x9A50, 0x0000, - 0x0000, 0x0000, 0x91ED, 0x9A55, 0x8FA4, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9A52, 0x0000, - 0x0000, 0x96E2, 0x0000, 0x0000, 0x0000, 0x8C5B, - 0x0000, 0x0000, 0x9A56, 0x9A57, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A54, 0x9A5A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9A51, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9A60, 0x9A65, 0x0000, - 0x9A61, 0x0000, 0x9A5C, 0x0000, 0x0000, 0x9A66, - 0x9150, 0x0000, 0x0000, 0x9A68, 0x0000, 0x8D41, - 0x9A5E, 0x929D, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A62, 0x9A5B, 0x8AAB, 0x0000, - 0x8AEC, 0x8A85, 0x9A63, 0x9A5F, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C96, - 0x9A69, 0x9A67, 0x9172, 0x8B69, 0x8BAA, 0x0000, - 0x9A64, 0x0000, 0x8BF2, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8963, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9A6D, 0x9A6B, - 0x0000, 0x9AA5, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A70, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A6A, 0x0000, 0x9A6E, 0x0000, - 0x0000, 0x9A6C, 0x0000, 0x0000, 0x0000, 0x8E6B, - 0x9A6F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9A72, 0x0000, 0x9A77, 0x0000, 0x0000, - 0x0000, 0x9A75, 0x9A74, 0x0000 -}; - -static u16 Ucs56[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9251, 0x0000, 0x0000, 0x89C3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A71, 0x0000, 0x9A73, 0x8FA6, - 0x8952, 0x0000, 0x0000, 0x9A76, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89DC, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9A82, - 0x0000, 0x8FFA, 0x9A7D, 0x0000, 0x9A7B, 0x0000, - 0x9A7C, 0x0000, 0x9A7E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x895C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9158, 0x0000, - 0x9A78, 0x0000, 0x9A79, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8A9A, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9A81, 0x0000, - 0x0000, 0x0000, 0x8AED, 0x0000, 0x9A84, 0x9A80, - 0x9A83, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x95AC, 0x0000, 0x0000, 0x0000, - 0x93D3, 0x0000, 0x94B6, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A86, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A85, 0x8A64, 0x0000, 0x0000, - 0x9A87, 0x0000, 0x0000, 0x0000, 0x0000, 0x9A8A, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9A89, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9A88, 0x0000, - 0x9458, 0x0000, 0x0000, 0x9A8B, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9A8C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9A8E, 0x0000, 0x9A8D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A90, 0x0000, 0x0000, 0x0000, - 0x9A93, 0x9A91, 0x9A8F, 0x9A92, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A94, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9A95, 0x0000, 0x0000, 0x9A96, - 0x0000, 0x9A97, 0x0000, 0x0000, 0x0000, 0x9A98, - 0x9964, 0x0000, 0x8EFA, 0x8E6C, 0x0000, 0x0000, - 0x89F1, 0x0000, 0x88F6, 0x0000, 0x0000, 0x9263, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9A99, 0x0000, - 0x8DA2, 0x0000, 0x88CD, 0x907D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9A9A, 0x8CC5, 0x0000, - 0x0000, 0x8D91, 0x0000, 0x9A9C -}; - -static u16 Ucs57[256] = { - 0x9A9B, 0x0000, 0x0000, 0x95DE, 0x9A9D, 0x0000, - 0x0000, 0x0000, 0x9A9F, 0x9A9E, 0x0000, 0x9AA0, - 0x0000, 0x9AA1, 0x0000, 0x8C97, 0x0000, 0x0000, - 0x8980, 0x9AA2, 0x0000, 0x0000, 0x9AA4, 0x0000, - 0x9AA3, 0x0000, 0x0000, 0x0000, 0x9AA6, 0x0000, - 0x0000, 0x9379, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9AA7, 0x88B3, 0x8DDD, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8C5C, 0x0000, 0x0000, - 0x926E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9AA8, 0x9AA9, 0x0000, 0x0000, 0x9AAB, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9AAC, 0x0000, - 0x8DE2, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BCF, - 0x0000, 0x0000, 0x9656, 0x0000, 0x0000, 0x0000, - 0x9AAA, 0x9AAD, 0x8DBF, 0x8D42, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9AB1, 0x0000, 0x0000, 0x8DA3, 0x0000, - 0x9252, 0x0000, 0x0000, 0x9AAE, 0x92D8, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9AB2, 0x0000, 0x0000, 0x9082, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9AB0, 0x9AB3, - 0x0000, 0x8C5E, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9AB4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9AB5, 0x0000, - 0x8D43, 0x8A5F, 0x9AB7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9AB8, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9AB9, 0x0000, 0x0000, 0x9AB6, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9AAF, 0x0000, 0x0000, 0x9ABA, 0x0000, 0x0000, - 0x9ABB, 0x0000, 0x0000, 0x0000, 0x0000, 0x9684, - 0x0000, 0x0000, 0x8FE9, 0x0000, 0x0000, 0x0000, - 0x9ABD, 0x9ABE, 0x9ABC, 0x0000, 0x9AC0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9457, 0x0000, - 0x0000, 0x88E6, 0x9575, 0x0000, 0x0000, 0x9AC1, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8FFB, 0x0000, - 0x0000, 0x8EB7, 0x0000, 0x947C, 0x8AEE, 0x0000, - 0x8DE9, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs58[256] = { - 0x9678, 0x0000, 0x93B0, 0x0000, 0x0000, 0x8C98, - 0x91CD, 0x0000, 0x0000, 0x0000, 0x9ABF, 0x9AC2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x91C2, 0x0000, 0x0000, - 0x0000, 0x9AC3, 0x0000, 0x0000, 0x0000, 0x9AC4, - 0x0000, 0x0000, 0x0000, 0x9AC6, 0x0000, 0x0000, - 0x92E7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8AAC, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA9F, - 0x8981, 0x95F1, 0x0000, 0x0000, 0x8FEA, 0x9367, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8DE4, 0x0000, - 0x0000, 0x9ACC, 0x0000, 0x0000, 0x95BB, 0x97DB, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x89F2, 0x9AC8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9159, 0x9ACB, 0x0000, - 0x9383, 0x0000, 0x0000, 0x9368, 0x9384, 0x94B7, - 0x92CB, 0x0000, 0x0000, 0x0000, 0x8DC7, 0x0000, - 0x0000, 0x0000, 0x9AC7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8996, 0x0000, 0x9355, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9AC9, 0x0000, - 0x9AC5, 0x0000, 0x0000, 0x906F, 0x0000, 0x0000, - 0x0000, 0x9ACD, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8F6D, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BAB, - 0x0000, 0x9ACE, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x95E6, 0x0000, 0x0000, - 0x0000, 0x919D, 0x0000, 0x0000, 0x0000, 0x0000, - 0x92C4, 0x0000, 0x0000, 0x9AD0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x966E, 0x0000, 0x0000, 0x9AD1, 0x0000, 0x0000, - 0x9AD6, 0x0000, 0x0000, 0x0000, 0x0000, 0x95AD, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9AD5, 0x9ACF, - 0x9AD2, 0x9AD4, 0x0000, 0x0000, 0x8DA4, 0x0000, - 0x0000, 0x95C7, 0x0000, 0x0000, 0x0000, 0x9AD7, - 0x0000, 0x9264, 0x0000, 0x0000, 0x89F3, 0x0000, - 0x8FEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x9AD9, - 0x0000, 0x9AD8, 0x0000, 0x8D88, 0x0000, 0x9ADA, - 0x9ADC, 0x9ADB, 0x0000, 0x0000, 0x9ADE, 0x0000, - 0x9AD3, 0x9AE0, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9ADF, 0x9ADD, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8E6D, 0x9070, 0x0000, 0x9173, 0x9AE1, - 0x90BA, 0x88EB, 0x9484, 0x0000, 0x0000, 0x0000, - 0x0000, 0x92D9, 0x0000, 0x9AE3, 0x9AE2, 0x9AE4, - 0x9AE5, 0x9AE6, 0x0000, 0x0000 -}; - -static u16 Ucs59[256] = { - 0x0000, 0x0000, 0x9AE7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x95CF, 0x9AE8, 0x0000, - 0x0000, 0x0000, 0x0000, 0x89C4, 0x9AE9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x975B, 0x8A4F, 0x0000, - 0x99C7, 0x8F67, 0x91BD, 0x9AEA, 0x96E9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x96B2, 0x0000, - 0x0000, 0x9AEC, 0x0000, 0x91E5, 0x0000, 0x9356, - 0x91BE, 0x9576, 0x9AED, 0x9AEE, 0x899B, 0x0000, - 0x0000, 0x8EB8, 0x9AEF, 0x0000, 0x0000, 0x0000, - 0x0000, 0x88CE, 0x9AF0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9AF1, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8982, 0x0000, 0x0000, 0x8AEF, - 0x93DE, 0x95F2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9AF5, 0x9174, 0x9AF4, 0x8C5F, 0x0000, 0x0000, - 0x967A, 0x9AF3, 0x0000, 0x9385, 0x9AF7, 0x0000, - 0x9AF6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9AF9, 0x0000, 0x9AF8, 0x0000, 0x0000, 0x899C, - 0x0000, 0x9AFA, 0x8FA7, 0x9AFC, 0x9244, 0x0000, - 0x9AFB, 0x0000, 0x95B1, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8F97, 0x937A, 0x0000, 0x0000, 0x0000, - 0x9B40, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D44, - 0x0000, 0x0000, 0x0000, 0x9B41, 0x9440, 0x94DC, - 0x96CF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9444, 0x0000, 0x0000, 0x9B4A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8B57, 0x0000, 0x0000, - 0x9764, 0x0000, 0x0000, 0x96AD, 0x0000, 0x9BAA, - 0x0000, 0x9B42, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9B45, 0x0000, 0x91C3, 0x0000, 0x0000, - 0x9657, 0x0000, 0x0000, 0x0000, 0x9369, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9B46, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9685, - 0x0000, 0x8DC8, 0x0000, 0x0000, 0x8FA8, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9B47, 0x0000, 0x0000, 0x8E6F, 0x0000, 0x8E6E, - 0x0000, 0x0000, 0x0000, 0x0000, 0x88B7, 0x8CC6, - 0x0000, 0x90A9, 0x88CF, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9B4B, 0x9B4C, 0x0000, 0x9B49, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8957, 0x8AAD, 0x0000, 0x9B48, 0x0000, - 0x96C3, 0x9550, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x88A6, 0x0000, 0x0000, 0x0000, 0x0000, 0x88F7, - 0x0000, 0x0000, 0x0000, 0x8E70 -}; - -static u16 Ucs5A[256] = { - 0x0000, 0x88D0, 0x0000, 0x88A1, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9B51, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9B4F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x96BA, 0x0000, 0x9B52, 0x0000, 0x9B50, 0x0000, - 0x0000, 0x9B4E, 0x9050, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9B4D, 0x0000, 0x0000, 0x0000, 0x95D8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8CE2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9B56, - 0x9B57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8FA9, 0x0000, 0x0000, 0x0000, 0x9B53, 0x984B, - 0x0000, 0x0000, 0x0000, 0x0000, 0x946B, 0x0000, - 0x0000, 0x9B55, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8DA5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9B58, 0x0000, 0x0000, 0x0000, - 0x9577, 0x0000, 0x0000, 0x0000, 0x9B59, 0x0000, - 0x9B54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x96B9, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x947D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9B5A, 0x9551, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9B5B, 0x9B5F, 0x9B5C, 0x0000, - 0x0000, 0x89C5, 0x9B5E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8EB9, 0x0000, 0x9B5D, - 0x8C99, 0x0000, 0x0000, 0x0000, 0x9B6B, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9B64, 0x9B61, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9284, 0x0000, 0x9B60, - 0x0000, 0x0000, 0x9B62, 0x0000, 0x0000, 0x9B63, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9B65, 0x9B66, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs5B[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8AF0, 0x0000, 0x9B68, - 0x9B67, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9B69, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8FEC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9B6C, 0x0000, 0x92DA, 0x0000, 0x0000, 0x0000, - 0x8964, 0x0000, 0x9B6A, 0x0000, 0x0000, 0x0000, - 0x9B6D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9B6E, 0x0000, 0x9B71, 0x0000, - 0x0000, 0x9B6F, 0x0000, 0x9B70, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8E71, 0x9B72, 0x0000, 0x0000, - 0x8D45, 0x9B73, 0x0000, 0x8E9A, 0x91B6, 0x0000, - 0x9B74, 0x9B75, 0x8E79, 0x8D46, 0x0000, 0x96D0, - 0x0000, 0x0000, 0x0000, 0x8B47, 0x8CC7, 0x9B76, - 0x8A77, 0x0000, 0x0000, 0x9B77, 0x0000, 0x91B7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9B78, 0x9BA1, - 0x0000, 0x9B79, 0x0000, 0x9B7A, 0x0000, 0x0000, - 0x9B7B, 0x0000, 0x9B7D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9B7E, 0x0000, 0x0000, 0x9B80, - 0x0000, 0x91EE, 0x0000, 0x8946, 0x8EE7, 0x88C0, - 0x0000, 0x9176, 0x8AAE, 0x8EB3, 0x0000, 0x8D47, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9386, - 0x0000, 0x8F40, 0x8AAF, 0x9288, 0x92E8, 0x88B6, - 0x8B58, 0x95F3, 0x0000, 0x8EC0, 0x0000, 0x0000, - 0x8B71, 0x90E9, 0x8EBA, 0x9747, 0x9B81, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8B7B, 0x0000, 0x8DC9, 0x0000, 0x0000, 0x8A51, - 0x8983, 0x8FAA, 0x89C6, 0x0000, 0x9B82, 0x9765, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F68, - 0x0000, 0x0000, 0x8EE2, 0x9B83, 0x8AF1, 0x93D0, - 0x96A7, 0x9B84, 0x0000, 0x9B85, 0x0000, 0x0000, - 0x9578, 0x0000, 0x0000, 0x0000, 0x9B87, 0x0000, - 0x8AA6, 0x8BF5, 0x9B86, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8AB0, 0x0000, 0x9051, - 0x9B8B, 0x8E40, 0x0000, 0x89C7, 0x9B8A, 0x0000, - 0x9B88, 0x9B8C, 0x9B89, 0x944A, 0x9ECB, 0x9052, - 0x0000, 0x9B8D, 0x0000, 0x0000, 0x97BE, 0x0000, - 0x9B8E, 0x0000, 0x0000, 0x9B90, 0x0000, 0x929E, - 0x9B8F, 0x0000, 0x90A1, 0x0000, 0x8E9B, 0x0000, - 0x0000, 0x0000, 0x91CE, 0x8EF5 -}; - -static u16 Ucs5C[256] = { - 0x0000, 0x9595, 0x90EA, 0x0000, 0x8ECB, 0x9B91, - 0x8FAB, 0x9B92, 0x9B93, 0x88D1, 0x91B8, 0x9071, - 0x0000, 0x9B94, 0x93B1, 0x8FAC, 0x0000, 0x8FAD, - 0x0000, 0x9B95, 0x0000, 0x0000, 0x90EB, 0x0000, - 0x0000, 0x0000, 0x8FAE, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9B96, 0x0000, 0x9B97, 0x0000, - 0x96DE, 0x0000, 0x0000, 0x0000, 0x9B98, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8BC4, 0x0000, 0x0000, - 0x0000, 0x8F41, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9B99, 0x9B9A, 0x8EDA, 0x904B, - 0x93F2, 0x9073, 0x94F6, 0x9441, 0x8BC7, 0x9B9B, - 0x0000, 0x0000, 0x0000, 0x8B8F, 0x9B9C, 0x0000, - 0x8BFC, 0x0000, 0x93CD, 0x89AE, 0x0000, 0x8E72, - 0x9B9D, 0x9BA0, 0x9B9F, 0x8BFB, 0x0000, 0x9B9E, - 0x0000, 0x9357, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x91AE, 0x0000, - 0x936A, 0x8EC6, 0x0000, 0x0000, 0x9177, 0x979A, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9BA2, 0x0000, 0x9BA3, 0x93D4, 0x0000, 0x8E52, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9BA5, 0x0000, - 0x0000, 0x9BA6, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9BA7, 0x0000, 0x0000, 0x0000, - 0x8AF2, 0x9BA8, 0x0000, 0x0000, 0x9BA9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89AA, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x915A, 0x8AE2, 0x0000, 0x9BAB, 0x96A6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x91D0, 0x0000, 0x8A78, - 0x0000, 0x0000, 0x9BAD, 0x9BAF, 0x8ADD, 0x0000, - 0x0000, 0x9BAC, 0x9BAE, 0x0000, 0x9BB1, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BB0, - 0x0000, 0x9BB2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9BB3, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x93BB, 0x8BAC, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x89E3, 0x9BB4, - 0x9BB9, 0x0000, 0x0000, 0x9BB7, 0x0000, 0x95F5, - 0x95F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9387, 0x0000, 0x0000, 0x0000, 0x9BB6, 0x8F73, - 0x0000, 0x9BB5, 0x0000, 0x0000 -}; - -static u16 Ucs5D[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9092, 0x0000, 0x0000, 0x0000, 0x9BBA, - 0x0000, 0x0000, 0x8DE8, 0x0000, 0x0000, 0x9BC0, - 0x0000, 0x0000, 0x9BC1, 0x9BBB, 0x8A52, 0x9BBC, - 0x9BC5, 0x9BC4, 0x9BC3, 0x9BBF, 0x0000, 0x0000, - 0x0000, 0x9BBE, 0x0000, 0x0000, 0x9BC2, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95F6, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9BC9, 0x9BC6, 0x0000, - 0x9BC8, 0x0000, 0x9792, 0x0000, 0x9BC7, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9BBD, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9093, 0x0000, 0x0000, - 0x9BCA, 0x0000, 0x0000, 0x8DB5, 0x0000, 0x0000, - 0x0000, 0x9BCB, 0x0000, 0x0000, 0x9BCC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9BCF, 0x0000, - 0x9BCE, 0x0000, 0x0000, 0x9BCD, 0x0000, 0x0000, - 0x0000, 0x9388, 0x9BB8, 0x0000, 0x0000, 0x0000, - 0x9BD5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9BD1, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9BD0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9BD2, 0x0000, - 0x9BD3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9BD6, 0x0000, 0x0000, - 0x97E4, 0x0000, 0x9BD7, 0x9BD4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9BD8, 0x0000, 0x0000, - 0x8ADE, 0x9BD9, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9BDB, 0x9BDA, 0x0000, 0x0000, 0x9BDC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9BDD, 0x0000, 0x90EC, - 0x8F42, 0x0000, 0x0000, 0x8F84, 0x0000, 0x9183, - 0x0000, 0x8D48, 0x8DB6, 0x8D49, 0x8B90, 0x0000, - 0x0000, 0x9BDE, 0x0000, 0x0000, 0x8DB7, 0x0000, - 0x0000, 0x8CC8, 0x9BDF, 0x96A4, 0x9462, 0x9BE0, - 0x0000, 0x8D4A, 0x0000, 0x0000, 0x0000, 0x8AAA, - 0x0000, 0x9246, 0x8BD0, 0x0000 -}; - -static u16 Ucs5E[256] = { - 0x0000, 0x0000, 0x8E73, 0x957A, 0x0000, 0x0000, - 0x94BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BE1, - 0x8AF3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BE4, - 0x0000, 0x0000, 0x0000, 0x0000, 0x929F, 0x0000, - 0x0000, 0x9BE3, 0x9BE2, 0x9BE5, 0x0000, 0x92E9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9083, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8E74, 0x0000, 0x90C8, 0x0000, 0x91D1, - 0x8B41, 0x0000, 0x0000, 0x92A0, 0x0000, 0x0000, - 0x9BE6, 0x9BE7, 0x8FED, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9658, 0x0000, 0x0000, 0x9BEA, 0x0000, - 0x0000, 0x9BE9, 0x9BE8, 0x959D, 0x0000, 0x9BF1, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9679, 0x0000, - 0x9BEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9BED, 0x968B, 0x0000, 0x9BEC, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BEE, - 0x0000, 0x94A6, 0x9BEF, 0x95BC, 0x9BF0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8AB1, 0x95BD, 0x944E, 0x9BF2, 0x9BF3, 0x0000, - 0x8D4B, 0x8AB2, 0x9BF4, 0x8CB6, 0x9763, 0x9748, - 0x8AF4, 0x9BF6, 0x0000, 0x92A1, 0x0000, 0x8D4C, - 0x8FAF, 0x0000, 0x0000, 0x94DD, 0x0000, 0x0000, - 0x8FB0, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F98, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92EA, - 0x95F7, 0x9358, 0x0000, 0x0000, 0x8D4D, 0x0000, - 0x957B, 0x0000, 0x0000, 0x0000, 0x9BF7, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9378, 0x8DC0, - 0x0000, 0x0000, 0x0000, 0x8CC9, 0x0000, 0x92EB, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x88C1, 0x8F8E, 0x8D4E, 0x9766, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9BF8, 0x9BF9, 0x9470, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9BFA, 0x97F5, 0x984C, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9BFC, 0x9BFB, 0x0000, - 0x0000, 0x8A66, 0x0000, 0x0000, 0x9C40, 0x0000, - 0x0000, 0x0000, 0x9C43, 0x9C44, 0x0000, 0x9C42, - 0x0000, 0x955F, 0x8FB1, 0x9C46, 0x9C45, 0x9C41, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9C47, 0x9C48, - 0x0000, 0x0000, 0x9C49, 0x0000, 0x0000, 0x0000, - 0x9C4C, 0x9C4A, 0x0000, 0x9C4B, 0x9C4D, 0x0000, - 0x8984, 0x92EC, 0x9C4E, 0x0000, 0x8C9A, 0x89F4, - 0x9455, 0x0000, 0x9C4F, 0x93F9 -}; - -static u16 Ucs5F[256] = { - 0x0000, 0x95D9, 0x0000, 0x9C50, 0x984D, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9C51, 0x95BE, 0x9C54, - 0x989F, 0x98AF, 0x0000, 0x8EAE, 0x93F3, 0x9C55, - 0x0000, 0x8B7C, 0x92A2, 0x88F8, 0x9C56, 0x95A4, - 0x8D4F, 0x0000, 0x0000, 0x926F, 0x0000, 0x0000, - 0x0000, 0x92ED, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x96ED, 0x8CB7, 0x8CCA, 0x0000, 0x9C57, - 0x0000, 0x0000, 0x0000, 0x9C58, 0x0000, 0x9C5E, - 0x0000, 0x8EE3, 0x0000, 0x0000, 0x0000, 0x92A3, - 0x0000, 0x8BAD, 0x9C59, 0x0000, 0x0000, 0x0000, - 0x954A, 0x0000, 0x9265, 0x0000, 0x0000, 0x9C5A, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9C5B, 0x0000, 0x8BAE, 0x0000, 0x9C5C, 0x0000, - 0x9C5D, 0x0000, 0x0000, 0x9C5F, 0x0000, 0x9396, - 0x0000, 0x0000, 0x9C60, 0x9C61, 0x0000, 0x9C62, - 0x0000, 0x0000, 0x9C53, 0x9C52, 0x0000, 0x0000, - 0x0000, 0x9C63, 0x8C60, 0x0000, 0x0000, 0x0000, - 0x9546, 0x0000, 0x0000, 0x8DCA, 0x9556, 0x92A4, - 0x956A, 0x9C64, 0x0000, 0x0000, 0x8FB2, 0x8965, - 0x0000, 0x9C65, 0x0000, 0x0000, 0x0000, 0x9C66, - 0x0000, 0x96F0, 0x0000, 0x0000, 0x94DE, 0x0000, - 0x0000, 0x9C69, 0x899D, 0x90AA, 0x9C68, 0x9C67, - 0x8C61, 0x91D2, 0x0000, 0x9C6D, 0x9C6B, 0x0000, - 0x9C6A, 0x97A5, 0x8CE3, 0x0000, 0x0000, 0x0000, - 0x8F99, 0x9C6C, 0x936B, 0x8F5D, 0x0000, 0x0000, - 0x0000, 0x93BE, 0x9C70, 0x9C6F, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9C6E, 0x0000, 0x9C71, 0x8CE4, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9C72, 0x959C, 0x8F7A, 0x0000, 0x0000, 0x9C73, - 0x94F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x93BF, - 0x92A5, 0x0000, 0x0000, 0x0000, 0x0000, 0x934F, - 0x0000, 0x0000, 0x9C74, 0x8B4A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9053, 0x0000, 0x954B, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8AF5, 0x9445, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9C75, 0x8E75, - 0x9659, 0x965A, 0x0000, 0x0000, 0x899E, 0x9C7A, - 0x0000, 0x0000, 0x9289, 0x0000, 0x0000, 0x0000, - 0x9C77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x89F5, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9CAB, 0x9C79, 0x0000, 0x0000, 0x0000, 0x944F, - 0x0000, 0x0000, 0x9C78, 0x0000, 0x0000, 0x9C76, - 0x0000, 0x8D9A, 0x0000, 0x9C7C -}; - -static u16 Ucs60[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9C83, 0x9C89, 0x9C81, 0x0000, - 0x937B, 0x0000, 0x0000, 0x9C86, 0x957C, 0x0000, - 0x0000, 0x9C80, 0x0000, 0x9C85, 0x97E5, 0x8E76, - 0x0000, 0x0000, 0x91D3, 0x9C7D, 0x0000, 0x0000, - 0x0000, 0x8B7D, 0x9C88, 0x90AB, 0x8985, 0x9C82, - 0x89F6, 0x9C87, 0x0000, 0x0000, 0x0000, 0x8BAF, - 0x0000, 0x9C84, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8A, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8C, - 0x9C96, 0x9C94, 0x0000, 0x0000, 0x9C91, 0x0000, - 0x0000, 0x0000, 0x9C90, 0x97F6, 0x0000, 0x9C92, - 0x0000, 0x0000, 0x8BB0, 0x0000, 0x8D50, 0x0000, - 0x0000, 0x8F9A, 0x0000, 0x0000, 0x0000, 0x9C99, - 0x9C8B, 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8F, - 0x9C7E, 0x0000, 0x89F8, 0x9C93, 0x9C95, 0x9270, - 0x0000, 0x0000, 0x8DA6, 0x89B6, 0x9C8D, 0x9C98, - 0x9C97, 0x8BB1, 0x0000, 0x91A7, 0x8A86, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8C62, 0x0000, 0x9C8E, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9C9A, 0x0000, 0x9C9D, - 0x9C9F, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EBB, - 0x0000, 0x9CA5, 0x92EE, 0x9C9B, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9CA3, 0x0000, 0x89F7, 0x0000, - 0x9CA1, 0x9CA2, 0x0000, 0x0000, 0x9C9E, 0x9CA0, - 0x0000, 0x0000, 0x0000, 0x8CE5, 0x9749, 0x0000, - 0x0000, 0x8AB3, 0x0000, 0x0000, 0x8978, 0x9CA4, - 0x0000, 0x9459, 0x88AB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x94DF, 0x9C7B, - 0x9CAA, 0x9CAE, 0x96E3, 0x0000, 0x9CA7, 0x0000, - 0x0000, 0x0000, 0x9389, 0x9CAC, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8FEE, - 0x9CAD, 0x93D5, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9866, - 0x0000, 0x9CA9, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9CAF, 0x0000, 0x8D9B, 0x0000, 0x90C9, 0x0000, - 0x0000, 0x88D2, 0x9CA8, 0x9CA6, 0x0000, 0x9179, - 0x0000, 0x0000, 0x0000, 0x9C9C, 0x8E53, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x91C4, 0x9CBB, 0x0000, 0x917A, 0x9CB6, 0x0000, - 0x9CB3, 0x9CB4, 0x0000, 0x8EE4, 0x9CB7, 0x9CBA, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs61[256] = { - 0x9CB5, 0x8F44, 0x0000, 0x9CB8, 0x0000, 0x0000, - 0x9CB2, 0x0000, 0x96FA, 0x96F9, 0x0000, 0x0000, - 0x0000, 0x9CBC, 0x9CBD, 0x88D3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9CB1, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8BF0, 0x88A4, 0x0000, 0x0000, - 0x0000, 0x8AB4, 0x0000, 0x9CB9, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9CC1, 0x9CC0, 0x0000, - 0x0000, 0x0000, 0x9CC5, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9CC6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9CC4, 0x9CC7, 0x9CBF, 0x9CC3, 0x0000, 0x0000, - 0x9CC8, 0x0000, 0x9CC9, 0x0000, 0x0000, 0x9CBE, - 0x8E9C, 0x0000, 0x9CC2, 0x91D4, 0x8D51, 0x9CB0, - 0x9054, 0x0000, 0x0000, 0x0000, 0x0000, 0x9CD6, - 0x0000, 0x95E7, 0x0000, 0x0000, 0x9CCC, 0x9CCD, - 0x9CCE, 0x0000, 0x0000, 0x9CD5, 0x0000, 0x9CD4, - 0x0000, 0x0000, 0x969D, 0x8AB5, 0x0000, 0x9CD2, - 0x0000, 0x8C64, 0x8A53, 0x0000, 0x0000, 0x9CCF, - 0x0000, 0x0000, 0x97B6, 0x9CD1, 0x88D4, 0x9CD3, - 0x0000, 0x9CCA, 0x9CD0, 0x9CD7, 0x8C63, 0x9CCB, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x977C, 0x0000, 0x0000, 0x0000, 0x974A, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9CDA, 0x0000, 0x0000, - 0x9CDE, 0x0000, 0x0000, 0x0000, 0x919E, 0x0000, - 0x97F7, 0x9CDF, 0x0000, 0x0000, 0x9CDC, 0x0000, - 0x9CD9, 0x0000, 0x0000, 0x9CD8, 0x9CDD, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x95AE, 0x0000, 0x0000, 0x93B2, - 0x0000, 0x8C65, 0x0000, 0x9CE0, 0x9CDB, 0x0000, - 0x9CE1, 0x0000, 0x0000, 0x0000, 0x8C9B, 0x0000, - 0x0000, 0x0000, 0x89AF, 0x0000, 0x0000, 0x0000, - 0x9CE9, 0x0000, 0x0000, 0x0000, 0x8AB6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9CE7, 0x0000, 0x0000, - 0x9CE8, 0x8DA7, 0x9CE6, 0x9CE4, 0x9CE3, 0x9CEA, - 0x9CE2, 0x9CEC, 0x0000, 0x0000, 0x89F9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9CEE, - 0x0000, 0x0000, 0x9CED, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x92A6, 0x0000, 0x9CF1, 0x0000, - 0x9CEF, 0x9CE5, 0x8C9C, 0x0000, 0x9CF0, 0x0000, - 0x9CF4, 0x9CF3, 0x9CF5, 0x9CF2 -}; - -static u16 Ucs62[256] = { - 0x9CF6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9CF7, 0x9CF8, 0x95E8, 0x0000, - 0x9CFA, 0x9CF9, 0x8F5E, 0x0000, 0x90AC, 0x89E4, - 0x89FA, 0x0000, 0x9CFB, 0x0000, 0x88BD, 0x0000, - 0x0000, 0x0000, 0x90CA, 0x9CFC, 0x0000, 0xE6C1, - 0x9D40, 0x8C81, 0x0000, 0x9D41, 0x0000, 0x0000, - 0x0000, 0x0000, 0x90ED, 0x0000, 0x0000, 0x0000, - 0x9D42, 0x0000, 0x0000, 0x0000, 0x9D43, 0x8B59, - 0x9D44, 0x0000, 0x9D45, 0x9D46, 0x91D5, 0x0000, - 0x0000, 0x0000, 0x8CCB, 0x0000, 0x0000, 0x96DF, - 0x0000, 0x0000, 0x0000, 0x965B, 0x8F8A, 0x9D47, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90EE, - 0xE7BB, 0x94E0, 0x0000, 0x8EE8, 0x0000, 0x8DCB, - 0x9D48, 0x0000, 0x0000, 0x0000, 0x0000, 0x91C5, - 0x0000, 0x95A5, 0x0000, 0x0000, 0x91EF, 0x0000, - 0x0000, 0x9D4B, 0x0000, 0x0000, 0x9D49, 0x0000, - 0x9D4C, 0x0000, 0x0000, 0x9D4A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9D4D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x95AF, 0x0000, 0x0000, 0x88B5, - 0x0000, 0x0000, 0x0000, 0x0000, 0x957D, 0x0000, - 0x0000, 0x94E1, 0x0000, 0x0000, 0x9D4E, 0x0000, - 0x9D51, 0x8FB3, 0x8B5A, 0x0000, 0x9D4F, 0x9D56, - 0x8FB4, 0x0000, 0x0000, 0x0000, 0x0000, 0x9D50, - 0x9463, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x977D, 0x9D52, 0x9D53, 0x9D57, 0x938A, - 0x9D54, 0x8D52, 0x90DC, 0x0000, 0x0000, 0x9D65, - 0x94B2, 0x0000, 0x91F0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x94E2, 0x9DAB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x95F8, 0x0000, 0x0000, - 0x0000, 0x92EF, 0x0000, 0x0000, 0x0000, 0x9695, - 0x0000, 0x9D5A, 0x899F, 0x928A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9D63, 0x0000, 0x0000, 0x9253, - 0x9D5D, 0x9D64, 0x9D5F, 0x9D66, 0x9D62, 0x0000, - 0x9D61, 0x948F, 0x0000, 0x9D5B, 0x89FB, 0x9D59, - 0x8B91, 0x91F1, 0x9D55, 0x0000, 0x0000, 0x9D58, - 0x8D53, 0x90D9, 0x0000, 0x8FB5, 0x9D60, 0x9471, - 0x0000, 0x0000, 0x8B92, 0x8A67, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8A87, 0x9040, 0x9D68, 0x9D6D, - 0x0000, 0x9D69, 0x0000, 0x8C9D, 0x0000, 0x9D6E, - 0x8E41, 0x8D89, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8F45, 0x9D5C -}; - -static u16 Ucs63[256] = { - 0x0000, 0x8E9D, 0x9D6B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8E77, 0x9D6C, 0x88C2, 0x0000, 0x0000, - 0x9D67, 0x0000, 0x0000, 0x0000, 0x0000, 0x92A7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8B93, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8BB2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9D6A, 0x88A5, 0x0000, - 0x0000, 0x8DC1, 0x0000, 0x0000, 0x0000, 0x9055, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x92F0, 0x0000, - 0x0000, 0x94D2, 0x9D70, 0x917D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x91A8, 0x0000, 0x0000, 0x8E4A, 0x9D71, - 0x0000, 0x9D73, 0x9D6F, 0x0000, 0x0000, 0x0000, - 0x0000, 0x95DF, 0x0000, 0x92BB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x917B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x95F9, 0x8ECC, 0x9D80, 0x0000, 0x9D7E, - 0x0000, 0x0000, 0x9098, 0x0000, 0x0000, 0x0000, - 0x8C9E, 0x0000, 0x0000, 0x0000, 0x9D78, 0x8FB7, - 0x0000, 0x0000, 0x93E6, 0x9450, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9D76, 0x0000, 0x0000, 0x917C, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8EF6, 0x9D7B, - 0x0000, 0x0000, 0x8FB6, 0x0000, 0x9D75, 0x9D7A, - 0x0000, 0x0000, 0x9472, 0x0000, 0x0000, 0x0000, - 0x9D74, 0x0000, 0x8C40, 0x0000, 0x0000, 0x8A7C, - 0x0000, 0x0000, 0x0000, 0x9D7C, 0x97A9, 0x8DCC, - 0x9254, 0x9D79, 0x0000, 0x90DA, 0x0000, 0x8D54, - 0x9084, 0x8986, 0x915B, 0x9D77, 0x8B64, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8C66, 0x0000, - 0x92CD, 0x9D7D, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x917E, 0x0000, 0x0000, 0x9D81, 0x0000, - 0x9D83, 0x0000, 0x0000, 0x91B5, 0x9D89, 0x0000, - 0x9D84, 0x0000, 0x0000, 0x9D86, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9560, 0x92F1, 0x0000, - 0x9D87, 0x0000, 0x0000, 0x0000, 0x974B, 0x0000, - 0x0000, 0x0000, 0x9767, 0x8AB7, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x88AC, 0x0000, 0x9D85, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9D82, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8AF6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8987, 0x0000, - 0x9D88, 0x0000, 0x0000, 0x0000, 0x9768, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs64[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9D8C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x91B9, 0x0000, 0x9D93, 0x0000, 0x0000, - 0x0000, 0x9D8D, 0x0000, 0x0000, 0x9D8A, 0x9D91, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9D72, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9D8E, 0x0000, 0x9D92, 0x0000, - 0x0000, 0x0000, 0x94C0, 0x938B, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9D8B, 0x0000, - 0x9D8F, 0x0000, 0x0000, 0x0000, 0x8C67, 0x0000, - 0x0000, 0x0000, 0x8DEF, 0x0000, 0x0000, 0x0000, - 0x90DB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9D97, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9345, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9D94, 0x0000, 0x9680, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9D95, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9D96, 0x0000, - 0x96CC, 0x0000, 0x90A0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C82, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9D9D, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8E54, 0x9D9A, 0x0000, 0x9D99, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9451, 0x0000, - 0x0000, 0x0000, 0x93B3, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9350, 0x9D9B, 0x0000, 0x0000, - 0x0000, 0x9D9C, 0x0000, 0x958F, 0x0000, 0x9464, - 0x8E42, 0x0000, 0x90EF, 0x0000, 0x966F, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A68, - 0x0000, 0x9DA3, 0x9D9E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9769, 0x9DA5, 0x0000, 0x0000, 0x9DA1, - 0x0000, 0x9DA2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9180, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9DA0, 0x0000, 0x9D5E, 0x0000, 0x0000, 0x0000, - 0x9DA4, 0x0000, 0x9D9F, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9DA9, 0x9DAA, 0x9346, 0x9DAC, - 0x0000, 0x0000, 0x8E43, 0x9DA7, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8B5B, 0x0000, 0x0000, 0x9DAD, - 0x0000, 0x9DA6, 0x9DB1, 0x0000, 0x9DB0, 0x0000, - 0x9DAF, 0x0000, 0x0000, 0x0000, 0x9DB2, 0x0000, - 0x0000, 0x9DB4, 0x8FEF, 0x0000 -}; - -static u16 Ucs65[256] = { - 0x9DB3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DB7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9DB5, 0x0000, 0x0000, 0x0000, 0x9DB6, 0x9D90, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DB9, - 0x9DB8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9D98, 0x9DBA, 0x9DAE, 0x0000, 0x0000, 0x8E78, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9DBB, 0x9DBC, - 0x9DBE, 0x9DBD, 0x9DBF, 0x89FC, 0x0000, 0x8D55, - 0x0000, 0x0000, 0x95FA, 0x90AD, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8CCC, 0x0000, 0x0000, - 0x9DC1, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DC4, - 0x0000, 0x9571, 0x0000, 0x8B7E, 0x0000, 0x0000, - 0x0000, 0x9DC3, 0x9DC2, 0x9473, 0x9DC5, 0x8BB3, - 0x0000, 0x0000, 0x0000, 0x9DC7, 0x9DC6, 0x0000, - 0x0000, 0x0000, 0x8AB8, 0x8E55, 0x0000, 0x0000, - 0x93D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8C68, 0x0000, 0x0000, 0x0000, 0x9094, 0x0000, - 0x9DC8, 0x0000, 0x90AE, 0x9347, 0x0000, 0x957E, - 0x9DC9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9DCA, 0x9DCB, - 0x0000, 0x0000, 0x0000, 0x95B6, 0x9B7C, 0x90C4, - 0x0000, 0x0000, 0x956B, 0x0000, 0x8DD6, 0x0000, - 0x94E3, 0x94C1, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x936C, 0x0000, 0x97BF, 0x0000, 0x9DCD, - 0x8ECE, 0x0000, 0x0000, 0x9DCE, 0x0000, 0x88B4, - 0x0000, 0x0000, 0x8BD2, 0x90CB, 0x0000, 0x9580, - 0x0000, 0x0000, 0x0000, 0x9DCF, 0x8E61, 0x9266, - 0x0000, 0x8E7A, 0x9056, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9DD0, 0x0000, 0x95FB, - 0x0000, 0x0000, 0x8997, 0x8E7B, 0x0000, 0x0000, - 0x0000, 0x9DD3, 0x0000, 0x9DD1, 0x9DD4, 0x97B7, - 0x9DD2, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F9, - 0x9DD5, 0x0000, 0x0000, 0x91B0, 0x0000, 0x0000, - 0x9DD6, 0x0000, 0x0000, 0x0000, 0x0000, 0x8AF8, - 0x0000, 0x9DD8, 0x0000, 0x9DD7, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9DD9, 0x9DDA, 0x8AF9, 0x0000, - 0x0000, 0x93FA, 0x9255, 0x8B8C, 0x8E7C, 0x9181, - 0x0000, 0x0000, 0x8F7B, 0x88AE, 0x0000, 0x0000, - 0x0000, 0x9DDB, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x89A0, 0x9DDF, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs66[256] = { - 0x0000, 0x0000, 0x8D56, 0x9DDE, 0x0000, 0x0000, - 0x8DA9, 0x8FB8, 0x0000, 0x0000, 0x9DDD, 0x0000, - 0x8FB9, 0x0000, 0x96BE, 0x8DA8, 0x0000, 0x0000, - 0x0000, 0x88D5, 0x90CC, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9DE4, 0x0000, - 0x0000, 0x90AF, 0x8966, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8F74, 0x0000, 0x9686, 0x8DF0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8FBA, 0x0000, 0x90A5, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9DE3, 0x9DE1, - 0x9DE2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x928B, 0x0000, 0x0000, 0x9E45, 0x0000, 0x9DE8, - 0x8E9E, 0x8D57, 0x9DE6, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9DE7, 0x0000, 0x9057, 0x0000, 0x0000, - 0x0000, 0x9DE5, 0x0000, 0x0000, 0x8E4E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9DEA, 0x9DE9, 0x9DEE, - 0x0000, 0x0000, 0x9DEF, 0x0000, 0x9DEB, 0x0000, - 0x8A41, 0x9DEC, 0x9DED, 0x94D3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9581, 0x8C69, 0x9DF0, 0x0000, - 0x0000, 0x0000, 0x90B0, 0x0000, 0x8FBB, 0x0000, - 0x0000, 0x0000, 0x9271, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8BC5, 0x0000, 0x9DF1, - 0x9DF5, 0x0000, 0x0000, 0x89C9, 0x9DF2, 0x9DF4, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9DF3, 0x0000, - 0x0000, 0x8F8B, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9267, 0x88C3, 0x9DF6, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9DF7, 0x0000, 0x0000, 0x0000, 0x0000, - 0x92A8, 0x0000, 0x0000, 0x0000, 0x97EF, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8E62, 0x0000, 0x0000, - 0x95E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x965C, 0x0000, 0x0000, 0x0000, 0x9E41, 0x9DF9, - 0x0000, 0x0000, 0x9DFC, 0x0000, 0x9DFB, 0x0000, - 0x0000, 0x9DF8, 0x0000, 0x0000, 0x9E40, 0x0000, - 0x0000, 0x93DC, 0x0000, 0x9DFA, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9E42, 0x0000, - 0x0000, 0x8F8C, 0x9E43, 0x0000, 0x976A, 0x9498, - 0x0000, 0x0000, 0x9E44, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9E46, 0x0000, 0x0000, 0x9E47, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9E48, 0x0000, 0x8BC8, 0x8967, 0x8D58, 0x9E49, - 0x0000, 0x9E4A, 0x8F91, 0x9182, 0x0000, 0x0000, - 0x99D6, 0x915D, 0x915C, 0x91D6 -}; - -static u16 Ucs67[256] = { - 0x8DC5, 0x0000, 0x0000, 0x98F0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8C8E, 0x974C, 0x0000, 0x95FC, - 0x0000, 0x959E, 0x0000, 0x9E4B, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8DF1, 0x92BD, 0x9E4C, 0x984E, - 0x0000, 0x0000, 0x0000, 0x965D, 0x0000, 0x92A9, - 0x9E4D, 0x8AFA, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9E4E, 0x9E4F, 0x96D8, 0x0000, - 0x96A2, 0x9696, 0x967B, 0x8E44, 0x9E51, 0x0000, - 0x0000, 0x8EE9, 0x0000, 0x0000, 0x9670, 0x0000, - 0x9E53, 0x9E56, 0x9E55, 0x0000, 0x8AF7, 0x0000, - 0x0000, 0x8B80, 0x0000, 0x9E52, 0x0000, 0x9E54, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9E57, 0x0000, - 0x0000, 0x9099, 0x0000, 0x0000, 0x0000, 0x0000, - 0x979B, 0x88C7, 0x8DDE, 0x91BA, 0x0000, 0x8EDB, - 0x0000, 0x0000, 0x8FF1, 0x0000, 0x0000, 0x9E5A, - 0x0000, 0x0000, 0x936D, 0x0000, 0x9E58, 0x91A9, - 0x9E59, 0x8FF0, 0x96DB, 0x9E5B, 0x9E5C, 0x9788, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9E61, 0x0000, - 0x0000, 0x8D59, 0x0000, 0x9474, 0x9E5E, 0x938C, - 0x9DDC, 0x9DE0, 0x0000, 0x8B6E, 0x0000, 0x9466, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9E60, 0x0000, - 0x8FBC, 0x94C2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9E66, 0x0000, 0x94F8, 0x0000, 0x9E5D, - 0x0000, 0x9E63, 0x9E62, 0x0000, 0x0000, 0x0000, - 0x90CD, 0x0000, 0x0000, 0x0000, 0x0000, 0x968D, - 0x0000, 0x97D1, 0x0000, 0x0000, 0x9687, 0x0000, - 0x89CA, 0x8E7D, 0x0000, 0x0000, 0x9867, 0x9E65, - 0x9095, 0x0000, 0x0000, 0x0000, 0x9E64, 0x0000, - 0x0000, 0x9E5F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8CCD, 0x0000, 0x0000, 0x0000, 0x9E6B, - 0x9E69, 0x0000, 0x89CB, 0x9E67, 0x9E6D, 0x9E73, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x91C6, 0x0000, 0x0000, 0x95BF, 0x0000, - 0x9E75, 0x0000, 0x0000, 0x0000, 0x9541, 0x0000, - 0x0000, 0x0000, 0x9E74, 0x9490, 0x965E, 0x8AB9, - 0x0000, 0x90F5, 0x8F5F, 0x0000, 0x0000, 0x0000, - 0x92D1, 0x0000, 0x974D, 0x0000, 0x0000, 0x9E70, - 0x9E6F, 0x0000, 0x0000, 0x0000, 0x9E71, 0x0000, - 0x9E6E, 0x0000, 0x0000, 0x9E76, 0x0000, 0x9E6C, - 0x0000, 0x0000, 0x9E6A, 0x0000, 0x9E72, 0x9E68, - 0x0000, 0x928C, 0x0000, 0x96F6, 0x8EC4, 0x8DF2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8DB8, - 0x0000, 0x0000, 0x968F, 0x8A60 -}; - -static u16 Ucs68[256] = { - 0x0000, 0x0000, 0x92CC, 0x93C8, 0x8968, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x90F0, 0x0000, 0x0000, 0x90B2, 0x8C49, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9E78, 0x0000, 0x0000, 0x8D5A, 0x8A9C, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E7A, - 0x8A94, 0x9E81, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9E7D, 0x0000, 0x90F1, 0x0000, - 0x0000, 0x0000, 0x8A6A, 0x8DAA, 0x0000, 0x0000, - 0x8A69, 0x8DCD, 0x0000, 0x0000, 0x9E7B, 0x8C85, - 0x8C6A, 0x938D, 0x0000, 0x0000, 0x9E79, 0x0000, - 0x88C4, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E7C, - 0x9E7E, 0x0000, 0x8BCB, 0x8C4B, 0x0000, 0x8ABA, - 0x8B6A, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E82, - 0x0000, 0x0000, 0x8DF7, 0x9691, 0x0000, 0x8E56, - 0x0000, 0x0000, 0x0000, 0x9E83, 0x0000, 0x0000, - 0x0000, 0x954F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9E8F, 0x0000, 0x89B1, 0x9E84, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9E95, 0x9E85, 0x0000, 0x97C0, 0x0000, 0x9E8C, - 0x0000, 0x947E, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9E94, 0x0000, 0x9E87, - 0x0000, 0x0000, 0x0000, 0x88B2, 0x9E89, 0x0000, - 0x0000, 0x8D5B, 0x0000, 0x0000, 0x0000, 0x9E8B, - 0x0000, 0x9E8A, 0x0000, 0x9E86, 0x9E91, 0x0000, - 0x8FBD, 0x0000, 0x0000, 0x0000, 0x9AEB, 0x8CE6, - 0x979C, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E88, - 0x0000, 0x92F2, 0x8A42, 0x8DAB, 0x0000, 0x9E80, - 0x0000, 0x9E90, 0x8A81, 0x0000, 0x0000, 0x9E8E, - 0x9E92, 0x0000, 0x938E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8AFC, 0x0000, - 0x9EB0, 0x0000, 0x0000, 0x96C7, 0x9E97, 0x8AFB, - 0x0000, 0x9E9E, 0x0000, 0x0000, 0x0000, 0x0000, - 0x965F, 0x0000, 0x9E9F, 0x9EA1, 0x0000, 0x9EA5, - 0x9E99, 0x0000, 0x9249, 0x0000, 0x0000, 0x0000, - 0x0000, 0x938F, 0x9EA9, 0x9E9C, 0x0000, 0x9EA6, - 0x0000, 0x0000, 0x0000, 0x9EA0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9058, 0x9EAA, - 0x0000, 0x0000, 0x90B1, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9EA8, 0x8ABB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs69[256] = { - 0x986F, 0x9E96, 0x0000, 0x0000, 0x9EA4, 0x88D6, - 0x0000, 0x0000, 0x9E98, 0x0000, 0x0000, 0x96B8, - 0x9E9D, 0x9041, 0x92C5, 0x9E93, 0x0000, 0x0000, - 0x9EA3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x909A, 0x9EAD, 0x8A91, 0x8C9F, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9EAF, 0x9E9A, 0x9EAE, - 0x0000, 0x9EA7, 0x9E9B, 0x0000, 0x9EAB, 0x0000, - 0x9EAC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9EBD, 0x0000, 0x0000, 0x0000, 0x93CC, 0x0000, - 0x9EA2, 0x0000, 0x0000, 0x9EB9, 0x0000, 0x0000, - 0x0000, 0x9EBB, 0x0000, 0x92D6, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x976B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9596, - 0x9EB6, 0x91C8, 0x0000, 0x0000, 0x0000, 0x9EBC, - 0x915E, 0x0000, 0x9EB3, 0x9EC0, 0x9EBF, 0x0000, - 0x93ED, 0x9EBE, 0x93E8, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9EC2, 0x9EB5, - 0x0000, 0x8BC6, 0x9EB8, 0x8F7C, 0x0000, 0x0000, - 0x0000, 0x9480, 0x9EBA, 0x8BC9, 0x0000, 0x9EB2, - 0x9EB4, 0x9EB1, 0x0000, 0x0000, 0x984F, 0x8A79, - 0x9EB7, 0x0000, 0x0000, 0x9EC1, 0x8A54, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8DE5, 0x0000, 0x0000, 0x0000, 0x897C, 0x0000, - 0x0000, 0x9ED2, 0x0000, 0x0000, 0x9850, 0x9ED5, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9059, - 0x9ED4, 0x0000, 0x0000, 0x0000, 0x9ED3, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9ED0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9EC4, 0x0000, 0x0000, 0x9EE1, 0x9EC3, 0x0000, - 0x9ED6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9ECE, 0x0000, 0x0000, 0x9EC9, 0x9EC6, - 0x0000, 0x9EC7, 0x0000, 0x9ECF, 0x0000, 0x0000, - 0x0000, 0xEAA0, 0x0000, 0x0000, 0x9ECC, 0x8D5C, - 0x92C6, 0x9184, 0x9ECA, 0x0000, 0x9EC5, 0x0000, - 0x0000, 0x9EC8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x976C, 0x968A, 0x0000, 0x0000, 0x0000, 0x9ECD, - 0x9ED7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9EDF, 0x9ED8, 0x0000, - 0x0000, 0x9EE5, 0x0000, 0x9EE3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9EDE, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9EDD, 0x0000, 0x92CE, - 0x0000, 0x9185, 0x0000, 0x9EDB -}; - -static u16 Ucs6A[256] = { - 0x0000, 0x0000, 0x9ED9, 0x0000, 0x0000, 0x9EE0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9EE6, 0x94F3, - 0x9EEC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9EE7, 0x9EEA, 0x9EE4, 0x0000, 0x0000, 0x9294, - 0x0000, 0x9557, 0x0000, 0x9EDA, 0x0000, 0x0000, - 0x9EE2, 0x8FBE, 0x0000, 0x96CD, 0x9EF6, 0x9EE9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8CA0, - 0x89A1, 0x8A7E, 0x0000, 0x0000, 0x9ED1, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8FBF, - 0x9EEE, 0x0000, 0x9EF5, 0x8EF7, 0x8A92, 0x0000, - 0x0000, 0x924D, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9EEB, 0x0000, 0x0000, 0x9EF0, - 0x9EF4, 0x0000, 0x0000, 0x8BB4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8B6B, 0x9EF2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B40, - 0x0000, 0x93C9, 0x9EF1, 0x0000, 0x0000, 0x0000, - 0x9EF3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9EED, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9EEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8A80, 0x9268, 0x0000, 0x0000, 0x0000, - 0x9EFA, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9EF8, 0x8CE7, 0x0000, - 0x9EF7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9F40, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9E77, 0x0000, 0x0000, 0x0000, 0x9EF9, 0x0000, - 0x9EFB, 0x9EFC, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9F4B, 0x0000, 0x9F47, 0x0000, - 0x9E8D, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F46, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9F45, 0x0000, - 0x0000, 0x9F42, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9EE8, 0x9F44, 0x9F43, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F49, - 0x0000, 0x9845, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9F4C, 0x8BF9, 0x0000, 0x0000, - 0x9F48, 0x9F4A, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x94A5, 0x0000, - 0x9F4D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9F51, 0x9F4E, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs6B[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x9793, 0x9F4F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9EDC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9F52, 0x0000, 0x0000, 0x0000, 0x9F53, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8954, - 0x0000, 0x9F55, 0x8C87, 0x8E9F, 0x0000, 0x8BD3, - 0x0000, 0x0000, 0x0000, 0x89A2, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x977E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9F57, 0x9F56, 0x9F59, 0x8B5C, 0x0000, - 0x0000, 0x8BD4, 0x8ABC, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9F5C, 0x0000, 0x0000, 0x0000, 0x9F5B, - 0x0000, 0x9F5D, 0x0000, 0x0000, 0x89CC, 0x0000, - 0x9256, 0x0000, 0x9F5E, 0x0000, 0x0000, 0x8ABD, - 0x9F60, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F5F, - 0x0000, 0x9F61, 0x0000, 0x0000, 0x0000, 0x9F62, - 0x0000, 0x9F63, 0x8E7E, 0x90B3, 0x8D9F, 0x0000, - 0x9590, 0x0000, 0x0000, 0x95E0, 0x9863, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8E95, 0x0000, 0x0000, - 0x0000, 0x8DCE, 0x97F0, 0x0000, 0x0000, 0x0000, - 0x9F64, 0x9F65, 0x0000, 0x8E80, 0x0000, 0x0000, - 0x0000, 0x9F66, 0x9F67, 0x0000, 0x0000, 0x9F69, - 0x9F68, 0x0000, 0x9677, 0x0000, 0x0000, 0x8F7D, - 0x8EEA, 0x8E63, 0x0000, 0x9F6A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F6C, - 0x9042, 0x0000, 0x9F6B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9F6D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9F6E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9F6F, 0x9F70, 0x0000, 0x0000, - 0x0000, 0x9F71, 0x0000, 0x9F73, 0x9F72, 0x9F74, - 0x89A3, 0x9269, 0x0000, 0x9F75, 0x0000, 0x0000, - 0x8E45, 0x8A6B, 0x9F76, 0x0000, 0x0000, 0x9361, - 0x9ACA, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B42, - 0x9F77, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F78, - 0x0000, 0x95EA, 0x9688, 0x0000, 0x0000, 0x0000, - 0x93C5, 0x9F79, 0x94E4, 0x0000, 0x0000, 0x0000, - 0x94F9, 0x0000, 0x0000, 0x96D1, 0x0000, 0x0000, - 0x0000, 0x9F7A, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9F7C, 0x9F7B, 0x0000, 0x0000, 0x9F7E, - 0x0000, 0x0000, 0x0000, 0x9F7D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs6C[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9F81, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8E81, 0x0000, 0x96AF, - 0x0000, 0x9F82, 0x9F83, 0x0000, 0x0000, 0x8B43, - 0x0000, 0x0000, 0x0000, 0x9F84, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F86, - 0x9F85, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9085, 0x0000, - 0x0000, 0x9558, 0x8969, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x94C3, 0x0000, 0x92F3, 0x8F60, - 0x8B81, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x94C4, 0x0000, 0x8EAC, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9F88, 0x0000, 0x8ABE, 0x0000, 0x0000, - 0x8998, 0x0000, 0x0000, 0x93F0, 0x9F87, 0x8D5D, - 0x9272, 0x0000, 0x9F89, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9F91, 0x0000, 0x9F8A, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x91BF, 0x0000, - 0x8B82, 0x9F92, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8C88, 0x0000, 0x0000, 0x8B44, - 0x9F90, 0x0000, 0x0000, 0x9F8E, 0x9F8B, 0x9780, - 0x0000, 0x0000, 0x0000, 0x0000, 0x92BE, 0x0000, - 0x0000, 0x0000, 0x93D7, 0x9F8C, 0x0000, 0x0000, - 0x9F94, 0x0000, 0x9F93, 0x8C42, 0x0000, 0x0000, - 0x89AB, 0x0000, 0x0000, 0x8DB9, 0x9F8D, 0x9F8F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9676, - 0x91F2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9697, 0x0000, 0x0000, - 0x9F9C, 0x0000, 0x0000, 0x9F9D, 0x0000, 0x89CD, - 0x0000, 0x0000, 0x0000, 0x0000, 0x95A6, 0x96FB, - 0x9F9F, 0x8EA1, 0x8FC0, 0x9F98, 0x9F9E, 0x8988, - 0x0000, 0x8BB5, 0x0000, 0x0000, 0x9F95, 0x9F9A, - 0x0000, 0x0000, 0x0000, 0x90F2, 0x9491, 0x0000, - 0x94E5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9F97, 0x0000, 0x9640, 0x0000, 0x9F99, - 0x0000, 0x9FA2, 0x0000, 0x9FA0, 0x0000, 0x9F9B, - 0x0000, 0x0000, 0x0000, 0x9641, 0x9467, 0x8B83, - 0x0000, 0x9344, 0x0000, 0x0000, 0x928D, 0x0000, - 0x9FA3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FA1, - 0x91D7, 0x9F96, 0x0000, 0x896A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs6D[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x976D, - 0x9FAE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9FAD, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F4, - 0x0000, 0x9FAA, 0x0000, 0x978C, 0x0000, 0x0000, - 0x93B4, 0x9FA4, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x92C3, 0x0000, 0x0000, 0x0000, 0x896B, - 0x8D5E, 0x9FA7, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8F46, 0x9FAC, 0x0000, 0x9FAB, - 0x9FA6, 0x0000, 0x9FA9, 0x0000, 0x0000, 0x8A88, - 0x0000, 0x9FA8, 0x9468, 0x0000, 0x0000, 0x97AC, - 0x0000, 0x0000, 0x8FF2, 0x90F3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FB4, - 0x9FB2, 0x0000, 0x956C, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9FAF, 0x9FB1, 0x0000, - 0x8959, 0x0000, 0x0000, 0x8D5F, 0x9851, 0x0000, - 0x8A5C, 0x0000, 0x9582, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9781, 0x0000, 0x0000, 0x8A43, - 0x905A, 0x9FB3, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9FB8, 0x0000, 0x0000, 0x8FC1, 0x0000, - 0x0000, 0x0000, 0x974F, 0x0000, 0x9FB5, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9FB0, 0x0000, 0x9FB6, - 0x0000, 0x0000, 0x0000, 0x97DC, 0x0000, 0x9393, - 0x93C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8A55, 0x0000, 0x0000, 0x8974, 0x0000, - 0x0000, 0x9FBC, 0x0000, 0x0000, 0x9FBF, 0x0000, - 0x0000, 0x0000, 0x97C1, 0x0000, 0x0000, 0x0000, - 0x9784, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FC6, - 0x9FC0, 0x9FBD, 0x0000, 0x0000, 0x0000, 0x97D2, - 0x9FC3, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F69, - 0x9FC5, 0x0000, 0x0000, 0x9FCA, 0x0000, 0x0000, - 0x9391, 0x9FC8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9FC2, 0x0000, 0x0000, 0x9257, 0x0000, 0x0000, - 0x9FC9, 0x0000, 0x9FBE, 0x0000, 0x9FC4, 0x0000, - 0x9FCB, 0x88FA, 0x9FC1, 0x0000, 0x9FCC, 0x0000, - 0x0000, 0x905B, 0x0000, 0x8F7E, 0x0000, 0x95A3, - 0x0000, 0x8DAC, 0x0000, 0x9FB9, 0x9FC7, 0x9359, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs6E[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90B4, - 0x0000, 0x8A89, 0x8DCF, 0x8FC2, 0x9FBB, 0x8F61, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8C6B, 0x0000, 0x9FBA, 0x0000, 0x0000, - 0x0000, 0x9FD0, 0x8F8D, 0x8CB8, 0x0000, 0x9FDF, - 0x0000, 0x9FD9, 0x8B94, 0x936E, 0x0000, 0x9FD4, - 0x9FDD, 0x88AD, 0x8951, 0x0000, 0x0000, 0x89B7, - 0x0000, 0x9FD6, 0x91AA, 0x9FCD, 0x9FCF, 0x8D60, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9FE0, 0x0000, 0x9FDB, 0x0000, - 0x0000, 0x0000, 0x9FD3, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9FDA, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x96A9, 0x0000, 0x0000, 0x9FD8, - 0x9FDC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8CCE, 0x0000, 0x8FC3, 0x0000, - 0x0000, 0x9258, 0x0000, 0x0000, 0x0000, 0x9FD2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x974E, 0x0000, 0x0000, 0x0000, 0x9FD5, - 0x0000, 0x0000, 0x9FCE, 0x9392, 0x0000, 0x0000, - 0x9FD1, 0x0000, 0x0000, 0x0000, 0x9FD7, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9870, 0x8EBC, 0x969E, 0x0000, 0x9FE1, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x94AC, 0x0000, 0x0000, 0x9FED, - 0x8CB9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8F80, 0x0000, 0x9FE3, 0x0000, 0x0000, 0x0000, - 0x97AD, 0x8D61, 0x0000, 0x9FF0, 0x0000, 0x0000, - 0x88EC, 0x0000, 0x0000, 0x9FEE, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9FE2, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9FE8, 0x0000, 0x0000, 0x9FEA, 0x0000, - 0x0000, 0x0000, 0x976E, 0x9FE5, 0x0000, 0x0000, - 0x934D, 0x0000, 0x0000, 0x9FE7, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9FEF, 0x0000, 0x9FE9, 0x96C5, - 0x0000, 0x0000, 0x0000, 0x9FE4, 0x0000, 0x8EA0, - 0x9FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A8A, - 0x0000, 0x9FE6, 0x9FEB, 0x9FEC, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91EA, - 0x91D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9FF4, 0x0000, 0x0000, 0x9FFA, - 0x0000, 0x0000, 0x9FF8, 0x0000, 0x9348, 0x0000, - 0x0000, 0xE042, 0x9FF5, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9FF6, 0x9FDE -}; - -static u16 Ucs6F[256] = { - 0x0000, 0x8B99, 0x9559, 0x0000, 0x0000, 0x0000, - 0x8EBD, 0x0000, 0x0000, 0x8D97, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9852, 0x0000, 0x9FF2, - 0x0000, 0xE041, 0x8989, 0x9186, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9499, 0x0000, 0x8ABF, 0x97F8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x969F, 0x92D0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9FF9, 0x9FFB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9151, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE040, 0x9FF7, 0x0000, 0x9FF1, - 0x0000, 0x0000, 0x0000, 0x8AC1, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8C89, 0x0000, 0x0000, 0x0000, 0xE04E, 0x0000, - 0x0000, 0xE049, 0x90F6, 0x0000, 0x0000, 0x8A83, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8F81, 0x0000, - 0xE052, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE04B, 0x92AA, 0xE048, 0x92D7, 0x0000, - 0x0000, 0x0000, 0xE06B, 0x0000, 0x0000, 0x0000, - 0xE045, 0x0000, 0xE044, 0x0000, 0xE04D, 0x0000, - 0x0000, 0x0000, 0xE047, 0xE046, 0xE04C, 0x0000, - 0x909F, 0x0000, 0xE043, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE04F, 0x0000, - 0x0000, 0xE050, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8AC0, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE055, - 0x0000, 0xE054, 0xE056, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE059, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9362, 0x0000, 0xE053, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE057, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8C83, 0x91F7, 0xE051, 0x945A, 0x0000, 0x0000, - 0xE058, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE05D, 0xE05B, 0x0000, 0x0000, - 0xE05E, 0x0000, 0x0000, 0xE061, 0x0000, 0x0000, - 0x0000, 0xE05A, 0x8D8A, 0x9447, 0x0000, 0x0000, - 0x9FB7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9794, 0xE05C, 0x0000, 0xE060, 0x91F3, - 0x0000, 0xE05F, 0x0000, 0xE04A, 0x0000, 0x0000, - 0xE889, 0x0000, 0x0000, 0x0000, 0xE064, 0x0000, - 0x0000, 0x0000, 0xE068, 0x0000 -}; - -static u16 Ucs70[256] = { - 0x0000, 0xE066, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE062, 0x0000, 0xE063, - 0x0000, 0x0000, 0x0000, 0xE067, 0x0000, 0xE065, - 0x0000, 0x0000, 0x0000, 0x956D, 0x0000, 0x0000, - 0xE06D, 0x0000, 0xE06A, 0xE069, 0x0000, 0xE06C, - 0x93D2, 0xE06E, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9295, 0x91EB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x90A3, 0x0000, 0x0000, 0x0000, - 0xE06F, 0x0000, 0xE071, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE070, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9FF3, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE072, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x93E5, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE073, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89CE, - 0x0000, 0x0000, 0x0000, 0x9394, 0x8A44, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8B84, 0x0000, 0x0000, 0x0000, 0x8EDC, 0x8DD0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9846, - 0x9086, 0x0000, 0x0000, 0x0000, 0x898A, 0x0000, - 0x0000, 0x0000, 0xE075, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE074, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE078, 0x9259, - 0xE07B, 0xE076, 0x0000, 0x0000, 0x0000, 0xE07A, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE079, 0x935F, - 0x88D7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x97F3, 0x0000, 0x0000, 0xE07D, - 0x0000, 0x0000, 0x0000, 0x8947, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE080, 0x0000, 0x0000, 0x0000, 0xE07E, - 0x0000, 0xE07C, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE077, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9642, 0x0000, 0x0000, - 0x0000, 0xE082, 0x0000, 0x0000 -}; - -static u16 Ucs71[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE081, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x898B, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE084, 0x95B0, 0x0000, 0xE083, 0x0000, - 0x0000, 0x0000, 0x0000, 0x96B3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8FC5, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9152, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8FC4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x97F9, 0x0000, 0x0000, 0xE08A, 0x0000, - 0x90F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE086, 0xE08B, 0x0000, 0x0000, 0x898C, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE089, 0x0000, 0x9481, 0xE085, - 0xE088, 0x8FC6, 0x0000, 0x94CF, 0x0000, 0x0000, - 0xE08C, 0x0000, 0x8ECF, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE08F, 0x0000, 0x0000, 0x0000, 0xE087, 0x0000, - 0x8C46, 0x0000, 0x0000, 0x0000, 0x0000, 0xE08D, - 0x0000, 0x0000, 0x0000, 0x0000, 0x976F, 0xE090, - 0x0000, 0x0000, 0x0000, 0xEAA4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8F6E, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE091, 0x0000, 0x0000, 0x0000, 0xE092, 0x0000, - 0x0000, 0x0000, 0x0000, 0x944D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE094, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE095, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9452, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9395, 0xE097, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE099, 0x0000, 0x97D3, 0x0000, - 0xE096, 0x0000, 0xE098, 0x898D, 0x0000, 0xE093, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9A7A, 0xE09A, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9187, 0x8E57, 0xE09C, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE09B, 0x9043, 0x99D7, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE09D, - 0x0000, 0x0000, 0x0000, 0xE09F, 0x0000, 0xE08E, - 0xE09E, 0x0000, 0x0000, 0xE0A0 -}; - -static u16 Ucs72[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x949A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE0A1, 0x0000, 0x0000, 0xE0A2, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE0A3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE0A4, 0x0000, - 0x92DC, 0x0000, 0xE0A6, 0xE0A5, 0x0000, 0x0000, - 0xE0A7, 0x0000, 0xE0A8, 0x0000, 0x0000, 0x8EDD, - 0x9583, 0x0000, 0x0000, 0x0000, 0x96EA, 0xE0A9, - 0xE0AA, 0x9175, 0x8EA2, 0xE0AB, 0xE0AC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE0AD, 0x95D0, - 0x94C5, 0x0000, 0x0000, 0xE0AE, 0x9476, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x92AB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE0AF, 0x89E5, - 0x0000, 0x8B8D, 0x0000, 0x96C4, 0x0000, 0x96B4, - 0x0000, 0x89B2, 0x9853, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9671, 0x0000, 0x95A8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x90B5, 0x0000, 0xE0B0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x93C1, 0x0000, 0x0000, 0x0000, 0x8CA1, - 0xE0B1, 0x0000, 0x8DD2, 0xE0B3, 0xE0B2, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE0B4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0B5, 0x0000, 0x0000, 0x0000, - 0xE0B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8B5D, 0x0000, - 0xE0B7, 0x0000, 0x0000, 0x0000, 0x0000, 0xE0B8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8CA2, 0x0000, - 0x0000, 0x94C6, 0x0000, 0x0000, 0xE0BA, 0x0000, - 0x0000, 0x0000, 0x8FF3, 0x0000, 0x0000, 0xE0B9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8BB6, 0xE0BB, 0xE0BD, 0x0000, - 0xE0BC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0BE, 0x0000, 0x8CCF, 0x0000, - 0xE0BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BE7, - 0x0000, 0x915F, 0x0000, 0x8D9D, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0C1, 0xE0C2, 0xE0C0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EEB, - 0x0000, 0x0000, 0x93C6, 0x8BB7, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE0C4, 0x924B, 0xE0C3, 0x0000, 0x0000, - 0x9854, 0x9482, 0x0000, 0x0000 -}; - -static u16 Ucs73[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE0C7, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE0C9, 0xE0C6, - 0x0000, 0x0000, 0x0000, 0x96D2, 0xE0C8, 0xE0CA, - 0x0000, 0x97C2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE0CE, 0x0000, 0x0000, 0x0000, 0xE0CD, - 0x9296, 0x944C, 0x0000, 0x0000, 0x8CA3, 0xE0CC, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE0CB, 0x0000, - 0x9750, 0x9751, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0CF, 0x898E, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8D96, 0x8E82, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE0D0, 0xE0D1, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE0D3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8F62, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0D5, 0x0000, 0xE0D4, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE0D6, 0x0000, - 0x8A6C, 0x0000, 0x0000, 0xE0D8, 0x0000, 0x0000, - 0xE0D7, 0x0000, 0xE0DA, 0xE0D9, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8CBA, 0x0000, 0x0000, 0x97A6, 0x0000, 0x8BCA, - 0x0000, 0x89A4, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8BE8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8ADF, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x97E6, 0xE0DC, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE0DE, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE0DF, 0x0000, 0x89CF, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0DB, 0x0000, 0x8E58, 0x0000, - 0x0000, 0x92BF, 0xE0DD, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE0E2, 0x0000, 0x8EEC, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE0E0, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8C5D, 0x0000, 0x0000, 0x94C7, 0xE0E1, 0x0000, - 0x0000, 0xE0FC, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0E7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8CBB, 0x0000 -}; - -static u16 Ucs74[256] = { - 0x0000, 0x0000, 0x0000, 0x8B85, 0x0000, 0xE0E4, - 0x979D, 0x0000, 0x0000, 0x97AE, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x91F4, 0x0000, - 0x0000, 0xE0E6, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0E8, 0x97D4, 0x8BD5, 0x94FA, - 0x9469, 0x0000, 0x0000, 0x0000, 0xE0E9, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE0EB, 0x0000, 0xE0EE, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE0EA, 0x0000, 0x0000, 0x0000, 0xE0ED, - 0x8CE8, 0x896C, 0xE0EF, 0x0000, 0x9090, 0xE0EC, - 0x97DA, 0x0000, 0x0000, 0xE0F2, 0xEAA2, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE0F0, 0xE0F3, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE0E5, 0xE0F1, 0x0000, - 0x0000, 0x8DBA, 0x0000, 0x0000, 0xE0F4, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE0F5, 0x0000, 0x0000, 0x0000, 0x0000, 0x979E, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE0F6, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0F7, 0x0000, 0x0000, 0x0000, - 0xE0E3, 0x0000, 0x0000, 0x0000, 0x0000, 0xE0F8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8AC2, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8EA3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE0F9, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE0FA, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE0FB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x895A, 0x0000, - 0x0000, 0x0000, 0xE140, 0x0000, 0x955A, 0xE141, - 0x0000, 0x0000, 0x8AA2, 0xE142, 0x0000, 0xE143, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE144, 0x0000, - 0xE146, 0xE147, 0xE145, 0x0000, 0x0000, 0x0000, - 0x9572, 0xE149, 0xE148, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs75[256] = { - 0x0000, 0x0000, 0x0000, 0xE14B, 0xE14A, 0xE14C, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE14D, 0xE14F, 0xE14E, 0x0000, 0x0000, 0x8D99, - 0x0000, 0xE151, 0x0000, 0xE150, 0x0000, 0x0000, - 0x8AC3, 0x0000, 0x9072, 0x0000, 0x935B, 0x0000, - 0xE152, 0x90B6, 0x0000, 0x0000, 0x0000, 0x8E59, - 0x0000, 0x8999, 0xE153, 0x0000, 0x9770, 0x0000, - 0x0000, 0x95E1, 0xE154, 0x0000, 0x0000, 0x0000, - 0x9363, 0x9752, 0x8D62, 0x905C, 0x0000, 0x0000, - 0x0000, 0x926A, 0x99B2, 0x0000, 0x92AC, 0x89E6, - 0xE155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE156, 0x0000, 0xE15B, 0x0000, - 0x0000, 0xE159, 0xE158, 0x9DC0, 0x8A45, 0xE157, - 0x0000, 0x88D8, 0x0000, 0x94A8, 0x0000, 0x0000, - 0x94C8, 0x0000, 0x0000, 0x0000, 0x0000, 0x97AF, - 0xE15C, 0xE15A, 0x927B, 0x90A4, 0x0000, 0x0000, - 0x94A9, 0x0000, 0x954C, 0x0000, 0xE15E, 0x97AA, - 0x8C6C, 0xE15F, 0x0000, 0xE15D, 0x94D4, 0xE160, - 0x0000, 0xE161, 0x0000, 0x0000, 0x88D9, 0x0000, - 0x0000, 0x8FF4, 0xE166, 0x0000, 0xE163, 0x93EB, - 0xE162, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8B45, 0x0000, 0x0000, 0xE169, 0x0000, - 0x0000, 0x0000, 0xE164, 0xE165, 0x0000, 0xE168, - 0xE167, 0x9544, 0x0000, 0x0000, 0x9161, 0x9160, - 0x0000, 0x8B5E, 0x0000, 0x0000, 0xE16A, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE16B, 0x0000, - 0x0000, 0xE16C, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE16E, 0x0000, 0xE16D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8975, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE176, 0x94E6, 0xE170, - 0x0000, 0xE172, 0x0000, 0x0000, 0xE174, 0x905D, - 0x0000, 0x0000, 0xE175, 0xE173, 0x8EBE, 0x0000, - 0x0000, 0x0000, 0xE16F, 0xE171, 0x0000, 0x9561, - 0x0000, 0x8FC7, 0x0000, 0x0000, 0xE178, 0x0000, - 0x0000, 0xE177, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE179, 0x0000, 0x8EA4, 0x8DAD, 0x0000, 0x0000, - 0x9397, 0xE17A, 0x0000, 0x92C9, 0x0000, 0x0000, - 0xE17C, 0x0000, 0x0000, 0x0000, 0x979F, 0xE17B, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9189, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE182, 0x0000, 0xE184, 0xE185, 0x9273, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE183, 0x0000, - 0xE180, 0x0000, 0xE17D, 0xE17E -}; - -static u16 Ucs76[256] = { - 0x0000, 0xE181, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE188, 0x0000, 0xE186, - 0x0000, 0xE187, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE189, 0xE18B, 0xE18C, 0xE18D, 0x0000, - 0xE18E, 0x0000, 0x0000, 0xE18A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE190, 0x0000, 0x0000, 0x0000, 0xE18F, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE191, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x97C3, 0x0000, 0x0000, 0x0000, 0xE194, 0xE192, - 0xE193, 0x0000, 0x0000, 0x0000, 0x8AE0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x96FC, 0x0000, - 0x0000, 0x0000, 0x95C8, 0x0000, 0xE196, 0x0000, - 0x0000, 0x0000, 0xE195, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE197, 0xE198, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE19C, 0xE199, 0xE19A, 0xE19B, 0x0000, - 0xE19D, 0x0000, 0x0000, 0x0000, 0xE19E, 0x0000, - 0xE19F, 0x0000, 0x0000, 0x0000, 0xE1A0, 0x0000, - 0xE1A1, 0x0000, 0x94AD, 0x936F, 0xE1A2, 0x9492, - 0x9553, 0x0000, 0xE1A3, 0x0000, 0x0000, 0xE1A4, - 0x9349, 0x0000, 0x8A46, 0x8D63, 0xE1A5, 0x0000, - 0x0000, 0xE1A6, 0x0000, 0x0000, 0xE1A7, 0x0000, - 0x8E48, 0x0000, 0x0000, 0xE1A9, 0x0000, 0x0000, - 0xE1A8, 0x0000, 0x0000, 0xE1AA, 0xE1AB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x94E7, 0x0000, 0xE1AC, 0x0000, 0x0000, 0x0000, - 0xE1AD, 0x0000, 0x0000, 0xEA89, 0xE1AE, 0xE1AF, - 0xE1B0, 0x0000, 0x0000, 0x0000, 0x0000, 0x8E4D, - 0x0000, 0x0000, 0xE1B1, 0x9475, 0x0000, 0x0000, - 0x967E, 0x0000, 0x896D, 0x0000, 0x8976, 0x0000, - 0x0000, 0xE1B2, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE1B4, 0x0000, 0x0000, 0x0000, 0xE1B3, 0x9390, - 0x0000, 0x0000, 0x0000, 0x90B7, 0x9F58, 0x0000, - 0xE1B5, 0x96BF, 0x0000, 0xE1B6, 0x0000, 0x8AC4, - 0x94D5, 0xE1B7, 0x0000, 0xE1B8, 0x0000, 0x0000, - 0xE1B9, 0x0000, 0x0000, 0x0000, 0x96DA, 0x0000, - 0x0000, 0x0000, 0x96D3, 0x0000, 0x92BC, 0x0000, - 0x0000, 0x0000, 0x918A, 0x0000, 0x0000, 0xE1BB, - 0x0000, 0x0000, 0x8F82, 0x0000 -}; - -static u16 Ucs77[256] = { - 0x0000, 0x8FC8, 0x0000, 0x0000, 0xE1BE, 0x0000, - 0x0000, 0xE1BD, 0xE1BC, 0x94FB, 0x0000, 0x8AC5, - 0x8CA7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE1C4, 0x0000, 0x0000, - 0xE1C1, 0x905E, 0x96B0, 0x0000, 0x0000, 0x0000, - 0xE1C0, 0xE1C2, 0xE1C3, 0x0000, 0x0000, 0xE1BF, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE1C5, 0xE1C6, 0x0000, 0x92AD, 0x0000, - 0x8AE1, 0x0000, 0x0000, 0x0000, 0x9285, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE1C7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE1C8, 0xE1CB, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9087, 0x0000, 0x93C2, 0x0000, 0xE1CC, - 0x9672, 0x0000, 0xE1C9, 0x0000, 0x0000, 0xE1CA, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE1CF, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE1CE, 0xE1CD, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE1D1, 0x0000, 0x0000, 0xE1D0, 0x0000, - 0x0000, 0xE1D2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE1D4, 0x0000, 0xE1D3, 0x0000, - 0x0000, 0x0000, 0x0000, 0x95CB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8F75, 0x97C4, - 0x0000, 0x0000, 0xE1D5, 0x0000, 0x0000, 0x93B5, - 0x0000, 0x0000, 0xE1D6, 0x0000, 0x0000, 0xE1D7, - 0x0000, 0xE1DB, 0xE1D9, 0xE1DA, 0x0000, 0xE1D8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE1DC, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE1DD, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE1DE, - 0x0000, 0x0000, 0xE1DF, 0x96B5, 0xE1E0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x96EE, 0xE1E1, - 0x0000, 0x926D, 0x0000, 0x948A, 0x0000, 0x8BE9, - 0x0000, 0x0000, 0x0000, 0x925A, 0xE1E2, 0x8BB8, - 0x0000, 0x0000, 0x0000, 0x90CE, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE1E3, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs78[256] = { - 0x0000, 0x0000, 0x8DBB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE1E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE1E5, 0x0000, 0x8CA4, 0x8DD3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE1E7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9375, 0x8DD4, 0x8B6D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9643, 0x0000, 0x946A, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9376, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8D7B, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE1E9, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8FC9, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x97B0, - 0x8D64, 0x0000, 0x0000, 0x8CA5, 0x0000, 0x0000, - 0x94A1, 0x0000, 0xE1EB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE1ED, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8CE9, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE1EC, 0x92F4, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE1EF, 0x8A56, 0xE1EA, 0x0000, - 0x0000, 0x94E8, 0x0000, 0x894F, 0x0000, 0x8DEA, - 0x0000, 0x9871, 0x0000, 0x0000, 0xE1EE, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE1F0, 0x0000, 0x0000, 0x0000, 0x95C9, - 0x0000, 0x90D7, 0xE1F2, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE1F3, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE1F1, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8A6D, 0x0000, 0xE1F9, 0x0000, 0xE1F8, 0x0000, - 0x0000, 0x8EA5, 0x0000, 0x0000, 0x0000, 0xE1FA, - 0xE1F5, 0x0000, 0x0000, 0x0000, 0xE1FB, 0xE1F6, - 0x0000, 0x0000, 0x0000, 0x0000, 0x94D6, 0xE1F4, - 0x0000, 0x0000, 0xE1F7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE241, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE240, 0x9681, 0x0000, - 0x0000, 0x0000, 0xE1FC, 0x0000, 0x0000, 0x88E9, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE243, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE242, 0x0000, 0x0000 -}; - -static u16 Ucs79[256] = { - 0x0000, 0x8FCA, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE244, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9162, 0x0000, 0x0000, 0xE246, - 0xE245, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE247, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE1E6, 0x0000, 0x0000, 0x0000, - 0xE1E8, 0xE249, 0xE248, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8EA6, 0x0000, - 0x97E7, 0x0000, 0x8ED0, 0x0000, 0xE24A, 0x8C56, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B5F, - 0x8B46, 0x8E83, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9753, 0x0000, 0x0000, 0xE250, - 0x0000, 0xE24F, 0x9163, 0xE24C, 0x0000, 0x0000, - 0xE24E, 0x0000, 0x0000, 0x8F6A, 0x905F, 0xE24D, - 0xE24B, 0x0000, 0x9449, 0x0000, 0x0000, 0x8FCB, - 0x0000, 0x0000, 0x955B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8DD5, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9398, - 0x0000, 0x0000, 0xE251, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE252, 0xE268, 0x8BD6, 0x0000, 0x0000, - 0x985C, 0x9154, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE253, 0x0000, 0x0000, 0x89D0, 0x92F5, 0x959F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE254, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8B9A, 0xE255, - 0x0000, 0x0000, 0xE257, 0x0000, 0x0000, 0x0000, - 0xE258, 0x0000, 0x9448, 0x0000, 0x0000, 0xE259, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE25A, - 0xE25B, 0x0000, 0x0000, 0x8BD7, 0x89D1, 0x93C3, - 0x8F47, 0x8E84, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE25C, 0x0000, 0x8F48, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89C8, - 0x9562, 0x0000, 0x0000, 0xE25D, 0x0000, 0x0000, - 0x94E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9164, 0x0000, 0xE260, 0x0000, 0xE261, - 0x9489, 0x0000, 0x9060, 0xE25E, 0x0000, 0x9281, - 0x0000, 0x0000, 0xE25F, 0x0000, 0x0000, 0x0000, - 0x8FCC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x88DA, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs7A[256] = { - 0x8B48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE262, 0x0000, 0x0000, 0x92F6, - 0x0000, 0xE263, 0x90C5, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x96AB, 0x0000, 0x0000, 0x9542, - 0xE264, 0xE265, 0x9274, 0x0000, 0x97C5, 0x0000, - 0x0000, 0xE267, 0xE266, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8EED, 0x0000, - 0x0000, 0xE269, 0x88EE, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE26C, 0x0000, 0x0000, 0x0000, 0xE26A, - 0x89D2, 0x8C6D, 0xE26B, 0x8D65, 0x8D92, 0x0000, - 0x95E4, 0xE26D, 0x0000, 0x0000, 0x9673, 0x0000, - 0x0000, 0xE26F, 0x0000, 0x0000, 0x0000, 0x90CF, - 0x896E, 0x89B8, 0x88AA, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE26E, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE270, 0xE271, 0x8FF5, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE272, 0x0000, 0x8A6E, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE274, 0x0000, - 0x0000, 0x0000, 0x8C8A, 0x0000, 0x8B86, 0x0000, - 0x0000, 0xE275, 0x8BF3, 0x0000, 0x0000, 0xE276, - 0x0000, 0x90FA, 0x0000, 0x93CB, 0x0000, 0x90DE, - 0x8DF3, 0x0000, 0x0000, 0x0000, 0xE277, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9282, 0x918B, 0x0000, 0xE279, - 0xE27B, 0xE278, 0xE27A, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8C41, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE27C, 0x8C45, 0x0000, 0x0000, 0x0000, - 0x8B87, 0x9771, 0xE27E, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE280, 0x0000, 0x0000, 0x0000, - 0x894D, 0x0000, 0x0000, 0x0000, 0x0000, 0xE283, - 0x0000, 0x0000, 0x0000, 0x8A96, 0xE282, 0xE281, - 0x0000, 0xE285, 0xE27D, 0x0000, 0xE286, 0x97A7, - 0x0000, 0xE287, 0x0000, 0xE288, 0x0000, 0x0000, - 0x9AF2, 0xE28A, 0x0000, 0xE289, 0x0000, 0x0000, - 0x0000, 0xE28B, 0xE28C, 0x0000, 0x97B3, 0xE28D, - 0x0000, 0xE8ED, 0x8FCD, 0xE28E, 0xE28F, 0x8F76, - 0x0000, 0x93B6, 0xE290, 0x0000, 0x0000, 0x0000, - 0x9247, 0x0000, 0x0000, 0xE291, 0x0000, 0x925B, - 0xE292, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8BA3, 0x0000, 0x995E, 0x927C, 0x8EB1, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8AC6 -}; - -static u16 Ucs7B[256] = { - 0x0000, 0x0000, 0xE293, 0x0000, 0xE2A0, 0x0000, - 0xE296, 0x0000, 0x8B88, 0x0000, 0xE295, 0xE2A2, - 0x0000, 0x0000, 0x0000, 0xE294, 0x0000, 0x8FCE, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE298, 0xE299, 0x0000, 0x934A, 0x0000, 0x0000, - 0xE29A, 0x0000, 0x8A7D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9079, 0x9584, 0x0000, 0xE29C, 0x0000, - 0x0000, 0x0000, 0x91E6, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE297, 0x0000, 0xE29B, - 0xE29D, 0x0000, 0x0000, 0x8DF9, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE2A4, 0x954D, 0x0000, - 0x94A4, 0x9399, 0x0000, 0x8BD8, 0xE2A3, 0xE2A1, - 0x0000, 0x94B3, 0xE29E, 0x927D, 0x939B, 0x0000, - 0x939A, 0x0000, 0x8DF4, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE2B6, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2A6, - 0x0000, 0xE2A8, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE2AB, 0x0000, 0xE2AC, 0x0000, 0xE2A9, 0xE2AA, - 0x0000, 0x0000, 0xE2A7, 0xE2A5, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE29F, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x95CD, 0x89D3, 0x0000, 0x0000, - 0x0000, 0xE2B3, 0x0000, 0xE2B0, 0x0000, 0xE2B5, - 0x0000, 0x0000, 0xE2B4, 0x0000, 0x9493, 0x96A5, - 0x0000, 0x8E5A, 0xE2AE, 0xE2B7, 0xE2B2, 0x0000, - 0xE2B1, 0xE2AD, 0x0000, 0xE2AF, 0x0000, 0x8AC7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x925C, 0x0000, 0x0000, 0x90FB, - 0x0000, 0x0000, 0x0000, 0x94A0, 0x0000, 0x0000, - 0xE2BC, 0x0000, 0x0000, 0x0000, 0x94A2, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x90DF, 0xE2B9, 0x0000, 0x0000, 0x94CD, 0x0000, - 0xE2BD, 0x95D1, 0x0000, 0x927A, 0x0000, 0xE2B8, - 0xE2BA, 0x0000, 0x0000, 0xE2BB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2BE, - 0x0000, 0x0000, 0x8EC2, 0x0000, 0x0000, 0x0000, - 0x93C4, 0xE2C3, 0xE2C2, 0x0000, 0x0000, 0xE2BF, - 0x0000, 0x0000, 0x0000, 0x9855, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE2C8, 0x0000, 0x0000, - 0xE2CC, 0xE2C9, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs7C[256] = { - 0xE2C5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE2C6, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE2CB, 0x0000, 0x0000, 0x0000, 0xE2C0, - 0x99D3, 0xE2C7, 0xE2C1, 0x0000, 0x0000, 0xE2CA, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE2D0, 0x0000, 0x8AC8, 0x0000, 0xE2CD, - 0x0000, 0x0000, 0x0000, 0xE2CE, 0x0000, 0x0000, - 0xE2CF, 0xE2D2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE2D1, 0x94F4, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE2D3, 0x97FA, 0x95EB, 0xE2D8, 0x0000, - 0x0000, 0xE2D5, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE2D4, 0x90D0, - 0x0000, 0xE2D7, 0xE2D9, 0x0000, 0x0000, 0x0000, - 0xE2D6, 0x0000, 0xE2DD, 0x0000, 0xE2DA, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2DB, - 0xE2C4, 0x0000, 0x0000, 0x0000, 0xE2DC, 0xE2DE, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE2DF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x95C4, 0x0000, 0xE2E0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x96E0, 0x0000, 0x0000, 0x8BCC, 0x8C48, 0xE2E1, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95B2, - 0x0000, 0x9088, 0x0000, 0x96AE, 0x0000, 0x0000, - 0xE2E2, 0x0000, 0x97B1, 0x0000, 0x0000, 0x9494, - 0x0000, 0x9165, 0x9453, 0x0000, 0x0000, 0x8F6C, - 0x0000, 0x0000, 0x0000, 0x88BE, 0x0000, 0xE2E7, - 0xE2E5, 0x0000, 0xE2E3, 0x8A9F, 0x0000, 0x8FCF, - 0xE2E8, 0x0000, 0x0000, 0xE2E6, 0x0000, 0xE2E4, - 0xE2EC, 0x0000, 0x0000, 0xE2EB, 0xE2EA, 0xE2E9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2ED, - 0x0000, 0x0000, 0x0000, 0xE2EE, 0x90B8, 0x0000, - 0xE2EF, 0x0000, 0xE2F1, 0x0000, 0x0000, 0xE2F0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8CD0, 0x0000, - 0x0000, 0x0000, 0x9157, 0x0000, 0x0000, 0x0000, - 0xE2F3, 0x0000, 0x0000, 0x0000, 0x939C, 0x0000, - 0xE2F2, 0x0000, 0x0000, 0x0000, 0xE2F4, 0x0000, - 0x95B3, 0x918C, 0x8D66, 0x0000, 0xE2F5, 0x0000, - 0x0000, 0x0000, 0x0000, 0x97C6, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2F7, - 0x0000, 0x0000, 0xE2F8, 0x0000, 0xE2F9, 0x0000, - 0xE2FA, 0x0000, 0x8E85, 0x0000, 0xE2FB, 0x8C6E, - 0x0000, 0x0000, 0x8B8A, 0x0000 -}; - -static u16 Ucs7D[256] = { - 0x8B49, 0x0000, 0xE340, 0x0000, 0x96F1, 0x8D67, - 0xE2FC, 0x0000, 0x0000, 0x0000, 0xE343, 0x96E4, - 0x0000, 0x945B, 0x0000, 0x0000, 0x9552, 0x0000, - 0x0000, 0x0000, 0x8F83, 0xE342, 0x0000, 0x8ED1, - 0x8D68, 0x8E86, 0x8B89, 0x95B4, 0xE341, 0x0000, - 0x0000, 0x0000, 0x9166, 0x9661, 0x8DF5, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8E87, 0x92DB, 0x0000, 0xE346, 0x97DD, - 0x8DD7, 0x0000, 0xE347, 0x9061, 0x0000, 0xE349, - 0x0000, 0x0000, 0x0000, 0x8FD0, 0x8DAE, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE348, 0x0000, 0x0000, - 0x8F49, 0x8CBC, 0x9167, 0xE344, 0xE34A, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE345, 0x8C6F, 0x0000, - 0xE34D, 0xE351, 0x8C8B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE34C, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE355, 0x0000, 0x0000, 0x8D69, 0x0000, - 0x0000, 0x978D, 0x88BA, 0xE352, 0x0000, 0x0000, - 0x8B8B, 0x0000, 0xE34F, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE350, 0x0000, 0x0000, 0x939D, - 0xE34E, 0xE34B, 0x0000, 0x8A47, 0x90E2, 0x0000, - 0x0000, 0x8CA6, 0x0000, 0x0000, 0x0000, 0xE357, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE354, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE356, - 0x0000, 0x0000, 0x0000, 0xE353, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8C70, 0x91B1, 0xE358, - 0x918E, 0x0000, 0x0000, 0xE365, 0x0000, 0x0000, - 0xE361, 0xE35B, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE35F, 0x8EF8, 0x88DB, - 0xE35A, 0xE362, 0xE366, 0x8D6A, 0x96D4, 0x0000, - 0x92D4, 0xE35C, 0x0000, 0x0000, 0xE364, 0x0000, - 0xE359, 0x925D, 0x0000, 0xE35E, 0x88BB, 0x96C8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE35D, 0x0000, 0x0000, 0x8BD9, 0x94EA, - 0x0000, 0x0000, 0x0000, 0x918D, 0x0000, 0x97CE, - 0x8F8F, 0x0000, 0x0000, 0xE38E, 0x0000, 0x0000, - 0xE367, 0x0000, 0x90FC, 0x0000, 0xE363, 0xE368, - 0xE36A, 0x0000, 0x92F7, 0xE36D, 0x0000, 0x0000, - 0xE369, 0x0000, 0x0000, 0x0000, 0x95D2, 0x8AC9, - 0x0000, 0x0000, 0x96C9, 0x0000, 0x0000, 0x88DC, - 0x0000, 0x0000, 0xE36C, 0x0000, 0x97FB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE36B, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs7E[256] = { - 0x0000, 0x898F, 0x0000, 0x0000, 0x93EA, 0xE36E, - 0x0000, 0x0000, 0x0000, 0xE375, 0xE36F, 0xE376, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE372, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x949B, 0x0000, 0x0000, - 0x8EC8, 0xE374, 0x0000, 0xE371, 0xE377, 0xE370, - 0x0000, 0x0000, 0x8F63, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9644, 0x0000, 0x0000, 0x8F6B, 0x0000, - 0x0000, 0xE373, 0xE380, 0x0000, 0x0000, 0xE37B, - 0x0000, 0xE37E, 0x0000, 0xE37C, 0xE381, 0xE37A, - 0x0000, 0xE360, 0x90D1, 0x0000, 0x0000, 0x94C9, - 0x0000, 0xE37D, 0x0000, 0x0000, 0xE378, 0x0000, - 0x0000, 0x0000, 0x9140, 0x8C71, 0x0000, 0x8F4A, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9044, 0x9155, 0xE384, 0x0000, 0x0000, 0xE386, - 0xE387, 0x0000, 0x0000, 0xE383, 0xE385, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE379, 0xE382, 0x0000, 0xE38A, 0xE389, 0x0000, - 0x0000, 0x969A, 0x0000, 0x0000, 0x8C4A, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE388, 0x0000, 0xE38C, 0xE38B, 0xE38F, - 0x0000, 0xE391, 0x0000, 0x0000, 0x8E5B, 0xE38D, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE392, 0xE393, - 0x0000, 0x0000, 0xE394, 0x0000, 0xE39A, 0x935A, - 0xE396, 0x0000, 0xE395, 0xE397, 0xE398, 0x0000, - 0xE399, 0x0000, 0x0000, 0x0000, 0x0000, 0xE39B, - 0xE39C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs7F[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8ACA, 0x0000, 0xE39D, 0x0000, 0xE39E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE39F, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE3A0, 0xE3A1, - 0xE3A2, 0x0000, 0xE3A3, 0xE3A4, 0x0000, 0x0000, - 0xE3A6, 0xE3A5, 0x0000, 0x0000, 0xE3A7, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3A8, - 0xE3A9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE3AC, 0xE3AA, 0xE3AB, 0x8DDF, 0x8C72, - 0x0000, 0x0000, 0x9275, 0x0000, 0x94B1, 0x0000, - 0x8F90, 0x0000, 0x0000, 0x946C, 0x0000, 0x94EB, - 0xE3AD, 0x9CEB, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE3AE, 0xE3B0, - 0x0000, 0x9785, 0xE3AF, 0xE3B2, 0xE3B1, 0x0000, - 0x9772, 0x0000, 0xE3B3, 0x0000, 0x94FC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE3B4, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE3B7, 0x0000, - 0x0000, 0xE3B6, 0xE3B5, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE3B8, 0x8C51, 0x0000, 0x0000, 0x0000, - 0x9141, 0x8B60, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE3BC, 0xE3B9, 0x0000, 0x0000, 0xE3BA, 0x0000, - 0x0000, 0x0000, 0xE3BD, 0x0000, 0xE3BE, 0xE3BB, - 0x0000, 0x0000, 0x0000, 0x8948, 0x0000, 0x0000, - 0x0000, 0x89A5, 0x0000, 0x0000, 0x0000, 0xE3C0, - 0xE3C1, 0x0000, 0x0000, 0x0000, 0xE3C2, 0x0000, - 0x9782, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8F4B, 0x0000, 0xE3C4, 0xE3C3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9089, 0xE3C5, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE3C6, 0x0000, 0x0000, 0xE3C7, - 0x0000, 0x8AE3, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8ACB, 0x0000, 0x0000, 0xE3C8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE3C9, 0x0000, 0x967C, - 0x9783, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs80[256] = { - 0x9773, 0x9856, 0x0000, 0x8D6C, 0xE3CC, 0x8ED2, - 0xE3CB, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3CD, - 0x8EA7, 0x0000, 0x0000, 0x0000, 0x91CF, 0x0000, - 0xE3CE, 0x0000, 0x0000, 0x8D6B, 0x0000, 0x96D5, - 0xE3CF, 0xE3D0, 0x0000, 0x0000, 0xE3D1, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE3D2, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D3, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8EA8, 0x0000, 0x0000, - 0x96EB, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D5, - 0x0000, 0x925E, 0x0000, 0xE3D4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D7, 0x0000, - 0x0000, 0x0000, 0xE3D6, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D8, 0x0000, - 0x0000, 0x0000, 0x90B9, 0x0000, 0xE3D9, 0x0000, - 0xE3DA, 0x0000, 0x0000, 0x0000, 0x95B7, 0xE3DB, - 0x0000, 0x918F, 0xE3DC, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE3DD, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x97FC, 0xE3E0, 0x0000, - 0xE3DF, 0xE3DE, 0x92AE, 0x0000, 0xE3E1, 0x9045, - 0x0000, 0xE3E2, 0x0000, 0x0000, 0x0000, 0xE3E3, - 0x9857, 0xE3E4, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE3E5, 0xE3E7, 0xE3E6, 0x94A3, 0x0000, 0x93F7, - 0x0000, 0x985D, 0x94A7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE3E9, 0x0000, 0x0000, - 0x8FD1, 0x0000, 0x9549, 0x0000, 0xE3EA, 0xE3E8, - 0x0000, 0x8ACC, 0x0000, 0x0000, 0x0000, 0x8CD2, - 0x8E88, 0x0000, 0x0000, 0x94EC, 0x0000, 0x0000, - 0x0000, 0x8CA8, 0x9662, 0x0000, 0xE3ED, 0xE3EB, - 0x0000, 0x8D6D, 0x0000, 0x8D6E, 0x88E7, 0x0000, - 0x8DE6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9478, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x88DD, 0xE3F2, 0x0000, - 0x925F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9477, 0x0000, 0x91D9, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F4, 0x0000, - 0x0000, 0xE3F0, 0xE3F3, 0xE3EE, 0x0000, 0xE3F1, - 0x9645, 0x0000, 0x0000, 0x8CD3, 0x0000, 0x0000, - 0x88FB, 0xE3EF, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F6, - 0x0000, 0xE3F7, 0x0000, 0x0000, 0x93B7, 0x0000, - 0x0000, 0x0000, 0x8BB9, 0x0000, 0x0000, 0x0000, - 0xE445, 0x945C, 0x0000, 0x0000 -}; - -static u16 Ucs81[256] = { - 0x0000, 0x0000, 0x8E89, 0x0000, 0x0000, 0x8BBA, - 0x90C6, 0x9865, 0x96AC, 0xE3F5, 0x90D2, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8B72, 0xE3F8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3FA, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3FB, - 0x0000, 0x9245, 0x0000, 0x945D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x92AF, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE442, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE441, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE3FC, 0x0000, 0x0000, - 0x9074, 0x0000, 0x9585, 0xE444, 0x0000, 0xE443, - 0x8D6F, 0x9872, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE454, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE448, - 0xE449, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EEE, - 0x0000, 0x0000, 0xE447, 0x0000, 0x8D98, 0xE446, - 0x0000, 0x0000, 0xE44A, 0x0000, 0x0000, 0x0000, - 0x92B0, 0x95A0, 0x9142, 0x0000, 0x0000, 0x0000, - 0x0000, 0x91DA, 0xE44E, 0x0000, 0xE44F, 0xE44B, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE44C, 0x0000, - 0xE44D, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D70, - 0x0000, 0x0000, 0x0000, 0xE455, 0x0000, 0xE451, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9586, 0x0000, - 0x968C, 0x9547, 0x0000, 0x0000, 0xE450, 0x0000, - 0x0000, 0xE453, 0xE452, 0x0000, 0x0000, 0x0000, - 0x9663, 0xE456, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE457, 0x0000, 0x0000, 0x9156, - 0x0000, 0xE458, 0x0000, 0x0000, 0xE45A, 0x0000, - 0xE45E, 0x0000, 0x0000, 0xE45B, 0xE459, 0x945E, - 0xE45C, 0x0000, 0xE45D, 0x0000, 0x0000, 0x0000, - 0x89B0, 0x0000, 0xE464, 0xE45F, 0x0000, 0x0000, - 0x0000, 0xE460, 0x0000, 0x0000, 0x0000, 0xE461, - 0x0000, 0x919F, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE463, 0xE462, 0xE465, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE466, 0xE467, 0x0000, 0x0000, 0x9062, - 0x0000, 0x89E7, 0x0000, 0xE468, 0x97D5, 0x0000, - 0x8EA9, 0x0000, 0x0000, 0x8F4C, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8E8A, 0x9276, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE469, 0xE46A, - 0x8950, 0x0000, 0xE46B, 0x0000 -}; - -static u16 Ucs82[256] = { - 0x0000, 0xE46C, 0xE46D, 0x0000, 0x0000, 0xE46E, - 0x0000, 0xE46F, 0x8BBB, 0x9DA8, 0xE470, 0x0000, - 0x90E3, 0xE471, 0x8EC9, 0x0000, 0xE472, 0x0000, - 0x98AE, 0x0000, 0x0000, 0x0000, 0xE473, 0x95DC, - 0x8ADA, 0x0000, 0x0000, 0x9143, 0x8F77, 0x0000, - 0x9591, 0x8F4D, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE474, - 0x8D71, 0xE475, 0x94CA, 0x0000, 0xE484, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE477, 0x0000, 0x91C7, - 0x9495, 0x8CBD, 0xE476, 0x9144, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE478, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92F8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE47A, 0xE479, - 0xE47C, 0x0000, 0x0000, 0xE47B, 0x0000, 0xE47D, - 0x0000, 0x0000, 0xE480, 0x0000, 0xE47E, 0x0000, - 0x8ACD, 0x0000, 0xE481, 0x0000, 0xE482, 0xE483, - 0x0000, 0x0000, 0x8DAF, 0x97C7, 0x0000, 0xE485, - 0x9046, 0x0000, 0x0000, 0x0000, 0x8990, 0xE486, - 0xE487, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE488, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x88F0, 0x0000, 0xE489, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE48A, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9587, 0x0000, 0x0000, - 0x0000, 0x8EC5, 0x0000, 0xE48C, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8A48, 0x88B0, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE48B, 0xE48E, 0x946D, - 0x0000, 0x9063, 0x0000, 0x89D4, 0x0000, 0x9646, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8C7C, 0x8BDA, - 0x0000, 0xE48D, 0x0000, 0x89E8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8AA1, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8991, - 0xE492, 0x97E8, 0x91DB, 0x0000, 0x0000, 0x9563, - 0x0000, 0xE49E, 0x0000, 0x89D5, 0xE49C, 0x0000, - 0xE49A, 0xE491, 0x0000, 0xE48F, 0x0000, 0xE490, - 0x0000, 0x8EE1, 0x8BEA, 0x9297, 0x0000, 0x0000, - 0x0000, 0x93CF, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8970, 0x0000, 0xE494, 0xE493, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE499, 0xE495, 0xE498, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs83[256] = { - 0x0000, 0x0000, 0x96CE, 0xE497, 0x89D6, 0x8A9D, - 0xE49B, 0x0000, 0x0000, 0xE49D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8C73, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE4A1, 0xE4AA, - 0xE4AB, 0x0000, 0x0000, 0x0000, 0x88A9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE4B2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x88EF, 0x0000, - 0x0000, 0xE4A9, 0x0000, 0x0000, 0x0000, 0xE4A8, - 0x0000, 0xE4A3, 0xE4A2, 0x0000, 0xE4A0, 0xE49F, - 0x9283, 0x0000, 0x91F9, 0xE4A5, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE4A4, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE4A7, 0x0000, 0x0000, - 0x0000, 0x9190, 0x8C74, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8960, 0xE4A6, 0x0000, 0x8D72, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9191, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE4B8, 0x0000, 0xE4B9, 0x0000, 0x89D7, - 0x0000, 0x0000, 0x0000, 0x89AC, 0xE4B6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE4AC, 0x0000, 0xE4B4, 0x0000, 0xE4BB, - 0xE4B5, 0x0000, 0x0000, 0x0000, 0xE4B3, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE496, 0x0000, 0x0000, - 0xE4B1, 0x0000, 0x0000, 0x0000, 0xE4AD, 0x0000, - 0x0000, 0x0000, 0x8ACE, 0xE4AF, 0xE4BA, 0x0000, - 0xE4B0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE4BC, 0x0000, 0xE4AE, 0x949C, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9789, 0x0000, 0x0000, - 0x0000, 0xE4B7, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE4CD, 0x0000, 0x0000, - 0x0000, 0xE4C5, 0x0000, 0x0000, 0x0000, 0x909B, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8B65, 0x0000, - 0x8BDB, 0x0000, 0xE4C0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x89D9, 0x0000, 0x0000, 0x8FD2, 0x0000, - 0xE4C3, 0x0000, 0x0000, 0x0000, 0x8DD8, 0x0000, - 0x0000, 0x9370, 0xE4C8, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95EC, - 0x0000, 0xE4BF, 0x0000, 0x0000, 0x0000, 0x89D8, - 0x8CD4, 0x9548, 0xE4C9, 0x0000, 0xE4BD, 0x0000, - 0x0000, 0xE4C6, 0x0000, 0x0000, 0x0000, 0xE4D0, - 0x0000, 0xE4C1, 0x0000, 0x0000 -}; - -static u16 Ucs84[256] = { - 0x0000, 0x0000, 0x0000, 0xE4C2, 0x93B8, 0x0000, - 0x0000, 0xE4C7, 0x0000, 0x0000, 0x0000, 0xE4C4, - 0x9647, 0xE4CA, 0x88DE, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE4BE, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE4CC, 0x0000, 0xE4CB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x948B, - 0xE4D2, 0x0000, 0xE4DD, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8A9E, 0x0000, 0x0000, 0x0000, 0xE4E0, - 0x0000, 0x0000, 0xE4CE, 0x0000, 0x0000, 0x0000, - 0xE4D3, 0x978E, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE4DC, 0x0000, - 0x0000, 0x9774, 0x0000, 0x0000, 0x0000, 0x0000, - 0x97A8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9298, 0x0000, 0x0000, - 0x0000, 0x8A8B, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9592, 0xE4E2, 0x939F, 0x0000, 0x0000, - 0x88AF, 0x0000, 0x0000, 0xE4DB, 0x0000, 0xE4D7, - 0x9192, 0xE4D1, 0xE4D9, 0xE4DE, 0x0000, 0x944B, - 0x0000, 0x0000, 0x0000, 0x88A8, 0x0000, 0xE4D6, - 0x0000, 0xE4DF, 0x9598, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE4DA, 0x0000, - 0xE4D5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8FD3, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8F4E, 0x0000, 0x0000, 0x0000, 0x8EAA, 0x0000, - 0x0000, 0x0000, 0x0000, 0x96D6, 0x0000, 0x0000, - 0x9566, 0x0000, 0x0000, 0xE4E5, 0x0000, 0xE4EE, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE4D8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8A97, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8FF6, 0xE4E3, - 0x0000, 0xE4E8, 0x9193, 0x0000, 0x0000, 0xE4E4, - 0x0000, 0xE4EB, 0x0000, 0x0000, 0x927E, 0x0000, - 0xE4EC, 0x0000, 0x0000, 0x9775, 0xE4E1, 0x8A57, - 0x0000, 0xE4E7, 0x0000, 0x0000, 0xE4EA, 0x96AA, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE4ED, 0x0000, - 0x0000, 0xE4E6, 0xE4E9, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9648, 0x0000, 0x9840, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE4F1, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE4F8, 0x0000, 0x0000, 0xE4F0 -}; - -static u16 Ucs85[256] = { - 0x8EC1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE4CF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95CC, - 0x0000, 0x96A0, 0xE4F7, 0xE4F6, 0x0000, 0xE4F2, - 0xE4F3, 0x0000, 0x8955, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE4F5, 0x0000, 0xE4EF, 0x0000, 0x0000, - 0x0000, 0x0000, 0x92D3, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE4F4, 0x88FC, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91A0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x95C1, 0x0000, 0x0000, 0xE4F9, 0xE540, - 0x0000, 0x94D7, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE4FC, 0x8FD4, 0x8EC7, 0xE542, 0x0000, 0x0000, - 0x8BBC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE543, 0x0000, 0x9599, 0xE4FB, 0x0000, - 0xE4D4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE4FA, 0x0000, 0x0000, - 0x0000, 0x0000, 0x986E, 0x93A0, 0x9593, 0x0000, - 0x0000, 0xE54A, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE550, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE551, 0x0000, 0xE544, 0x0000, 0x0000, 0x0000, - 0x9496, 0x0000, 0x0000, 0xE54E, 0xE546, 0x0000, - 0xE548, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE552, 0xE547, 0x0000, 0x0000, 0xE54B, 0x0000, - 0x0000, 0x8992, 0x0000, 0x93E3, 0x0000, 0xE54C, - 0xE54F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE545, 0x0000, 0x9145, 0x0000, - 0xE549, 0x8E46, 0x9064, 0x8C4F, 0x96F2, 0x0000, - 0x96F7, 0x8F92, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE556, - 0xE554, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x986D, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE553, 0x0000, 0x0000, - 0x0000, 0x9795, 0x0000, 0xE555, 0xE557, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE558, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE55B, 0xE559, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x93A1, 0xE55A, 0x0000, 0x0000, 0x0000, 0x94CB, - 0xE54D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8F93, 0x0000, 0xE55C, 0xE561, 0x9194, - 0x0000, 0x0000, 0xE560, 0x0000 -}; - -static u16 Ucs86[256] = { - 0x0000, 0x0000, 0xE541, 0x0000, 0x0000, 0x0000, - 0xE562, 0x9168, 0x0000, 0x0000, 0xE55D, 0xE55F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE55E, 0x0000, 0x0000, 0x9F50, 0x9F41, - 0x0000, 0x0000, 0xE564, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE563, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9796, 0x0000, 0xE1BA, - 0xE565, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE566, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE567, - 0x8CD5, 0x0000, 0x8B73, 0x0000, 0x0000, 0x0000, - 0xE569, 0x997C, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8B95, 0x0000, 0x97B8, 0x0000, 0x8BF1, 0xE56A, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE56B, 0x0000, 0x0000, 0x0000, 0x928E, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE56C, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x93F8, 0x0000, 0x88B8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x89E1, 0xE571, 0xE572, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE56D, 0x0000, 0x8E5C, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE56E, 0x9461, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE56F, 0xE570, 0xE57A, 0x0000, 0x0000, - 0x0000, 0xE574, 0xE577, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE573, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE575, 0x0000, - 0xE576, 0x8ED6, 0x0000, 0xE578, 0x0000, 0x9260, - 0x0000, 0x8C75, 0x8A61, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE57B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8A5E, 0x0000, 0xE581, 0x0000, 0x0000, - 0xE57C, 0xE580, 0x0000, 0x0000, 0x0000, 0x0000, - 0x94B8, 0x0000, 0x0000, 0x0000, 0x0000, 0xE57D, - 0x0000, 0x0000, 0xE57E, 0x9567, 0x94D8, 0xE582, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x91FB, 0xE58C, 0x0000, 0xE588, - 0x0000, 0x0000, 0x89E9, 0x0000 -}; - -static u16 Ucs87[256] = { - 0xE586, 0x0000, 0x9649, 0xE587, 0x0000, 0x0000, - 0xE584, 0x0000, 0xE585, 0xE58A, 0xE58D, 0x0000, - 0x0000, 0xE58B, 0x0000, 0x0000, 0x0000, 0xE589, - 0xE583, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9277, 0x0000, 0xE594, 0x0000, 0x96A8, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE592, 0x0000, 0x0000, 0x0000, 0xE593, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE58E, 0x0000, - 0x0000, 0xE590, 0x0000, 0x0000, 0x0000, 0xE591, - 0x0000, 0x0000, 0x0000, 0xE58F, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x90E4, 0x0000, 0x9858, 0xE598, 0x0000, - 0xE599, 0x0000, 0x0000, 0x0000, 0x0000, 0xE59F, - 0x0000, 0x9049, 0x0000, 0xE59B, 0x0000, 0xE59E, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE596, - 0xE595, 0x0000, 0x0000, 0xE5A0, 0x0000, 0x0000, - 0x89DA, 0x0000, 0xE59C, 0x0000, 0xE5A1, 0x0000, - 0x0000, 0x0000, 0xE59D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE59A, 0x0000, 0x92B1, 0x0000, - 0xE597, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9488, 0x0000, 0x0000, 0xE5A5, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x975A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE5A4, 0x0000, 0x0000, - 0xE5A3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE5AC, 0x0000, 0x0000, - 0x0000, 0xE5A6, 0x0000, 0x0000, 0x0000, 0xE5AE, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9786, 0xE5B1, 0x0000, 0xE5A8, 0x0000, 0x0000, - 0xE5A9, 0x0000, 0x0000, 0x0000, 0xE5AD, 0x0000, - 0xE5B0, 0xE5AF, 0x0000, 0x0000, 0x0000, 0xE5A7, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE5AA, 0x0000, - 0xE5BB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE5B4, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5B2, - 0x0000, 0x0000, 0xE5B3, 0x0000, 0x0000, 0x0000, - 0xE5B8, 0xE5B9, 0x0000, 0x8A49, 0x0000, 0x8B61, - 0x0000, 0x0000, 0xE5B7, 0x0000 -}; - -static u16 Ucs88[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5A2, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE5B6, 0xE5BA, 0xE5B5, 0x0000, 0xE5BC, - 0x0000, 0x0000, 0x0000, 0xE5BE, 0xE5BD, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE5C0, 0xE5BF, 0xE579, - 0x0000, 0x0000, 0x0000, 0xE5C4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE5C1, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE5C2, 0x0000, 0x0000, 0xE5C3, 0x0000, 0xE5C5, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8C8C, 0x0000, - 0xE5C7, 0x0000, 0xE5C6, 0x0000, 0x8F4F, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8D73, 0x9FA5, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE5C8, 0x8F70, - 0x0000, 0x0000, 0x0000, 0x8A58, 0x0000, 0xE5C9, - 0x0000, 0x8971, 0x0000, 0x8FD5, 0xE5CA, 0x0000, - 0x0000, 0x8D74, 0xE5CB, 0x88DF, 0x0000, 0x0000, - 0x0000, 0x0000, 0x955C, 0x0000, 0x0000, 0xE5CC, - 0x0000, 0x0000, 0x0000, 0x0000, 0x908A, 0x0000, - 0xE5D3, 0x0000, 0x0000, 0xE5D0, 0x0000, 0x928F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5D1, - 0xE5CE, 0x8BDC, 0x0000, 0xE5CD, 0xE5D4, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8C55, 0x0000, - 0x0000, 0x91DC, 0x0000, 0xE5DA, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE5D6, 0x0000, 0x0000, 0x0000, - 0x91B3, 0xE5D5, 0x0000, 0xE5D8, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE5CF, 0x0000, 0x0000, 0x0000, - 0xE5D9, 0x0000, 0xE5DB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x94ED, 0x0000, 0x0000, - 0xE5D7, 0x0000, 0xE5DC, 0xE5DE, 0x0000, 0x0000, - 0x8CD1, 0xE5D2, 0x0000, 0x88BF, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5DD, - 0x0000, 0x8DD9, 0x97F4, 0xE5DF, 0xE5E0, 0x9195, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x97A0, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE5E1, 0x9754, 0x0000, 0x0000, - 0xE5E2, 0xE5E3, 0x0000, 0x0000, 0x95E2, 0xE5E4, - 0x0000, 0x8DBE, 0x0000, 0x97A1, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE5E9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE5EA, 0x8FD6, 0xE5E8, 0x0000, - 0x0000, 0x0000, 0x9787, 0xE5E5, 0x0000, 0x0000, - 0xE5E7, 0x90BB, 0x909E, 0x0000 -}; - -static u16 Ucs89[256] = { - 0x0000, 0x0000, 0xE5E6, 0x0000, 0xE5EB, 0x0000, - 0x0000, 0x95A1, 0x0000, 0x0000, 0xE5ED, 0x0000, - 0xE5EC, 0x0000, 0x0000, 0x0000, 0x8A8C, 0x0000, - 0x964A, 0xE5EE, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5FA, - 0xE5F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE5F1, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE5F2, 0xE5F3, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE5F7, 0x0000, 0xE5F8, 0x0000, 0x0000, 0xE5F6, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5F4, - 0x0000, 0xE5EF, 0xE5F5, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE5F9, 0xE8B5, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x89A6, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE5FC, 0x8BDD, - 0xE5FB, 0x0000, 0x0000, 0x0000, 0xE641, 0x0000, - 0xE640, 0x0000, 0x0000, 0x0000, 0xE643, 0x0000, - 0x0000, 0xE642, 0x0000, 0xE644, 0x0000, 0x0000, - 0x8F50, 0x0000, 0xE645, 0x0000, 0x0000, 0xE646, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE647, 0x90BC, 0x0000, 0x9776, 0x0000, 0xE648, - 0x0000, 0x0000, 0x95A2, 0x9465, 0xE649, 0x0000, - 0xE64A, 0x8CA9, 0x0000, 0x0000, 0x0000, 0x8B4B, - 0x0000, 0x0000, 0x0000, 0xE64B, 0x0000, 0x0000, - 0x8E8B, 0x9460, 0xE64C, 0x0000, 0x8A6F, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE64D, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE64F, 0x9797, - 0x0000, 0xE64E, 0x9065, 0x0000, 0xE650, 0x0000, - 0x0000, 0xE651, 0x0000, 0x0000, 0xE652, 0x8ACF, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE653, 0x0000, 0x0000, 0xE654, 0x0000, 0xE655, - 0xE656, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8A70, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE657, 0x0000, 0xE658, 0xE659, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89F0, - 0x0000, 0x0000, 0x9047, 0xE65A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE65B, 0x0000, - 0x0000, 0x0000, 0xE65C, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs8A[256] = { - 0x8CBE, 0x0000, 0x92F9, 0xE65D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8C76, 0x0000, 0x9075, 0x0000, - 0xE660, 0x0000, 0x93A2, 0x0000, 0xE65F, 0x0000, - 0x0000, 0x8C50, 0x0000, 0x0000, 0xE65E, 0x91F5, - 0x8B4C, 0x0000, 0x0000, 0xE661, 0x0000, 0xE662, - 0x0000, 0x8FD7, 0x0000, 0x0000, 0x0000, 0x8C8D, - 0x0000, 0xE663, 0x0000, 0x0000, 0x0000, 0x0000, - 0x964B, 0x0000, 0x0000, 0x90DD, 0x0000, 0x0000, - 0x0000, 0x8B96, 0x0000, 0x96F3, 0x9169, 0x0000, - 0xE664, 0x0000, 0x0000, 0x0000, 0x9066, 0x9290, - 0x8FD8, 0x0000, 0x0000, 0x0000, 0x0000, 0xE665, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE668, 0x0000, - 0xE669, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8DBC, 0x91C0, 0xE667, 0x0000, - 0x8FD9, 0x955D, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE666, 0x0000, 0x0000, 0x8E8C, 0x0000, - 0x8972, 0x0000, 0xE66D, 0x8C77, 0x0000, 0x0000, - 0x8E8E, 0x0000, 0x0000, 0x8E8D, 0x0000, 0x986C, - 0xE66C, 0xE66B, 0x9146, 0x0000, 0x8B6C, 0x9862, - 0x8A59, 0x8FDA, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE66A, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE66F, 0x0000, - 0xE670, 0xE66E, 0x0000, 0x8CD6, 0x0000, 0x975F, - 0x0000, 0x0000, 0x8E8F, 0x9446, 0x0000, 0x0000, - 0x0000, 0xE673, 0x0000, 0x90BE, 0x0000, 0x9261, - 0x0000, 0x0000, 0x9755, 0x0000, 0xE676, 0x0000, - 0x0000, 0x0000, 0x8CEA, 0x0000, 0x90BD, 0xE672, - 0x0000, 0xE677, 0x8CEB, 0xE674, 0xE675, 0x0000, - 0xE671, 0x0000, 0x0000, 0x0000, 0x90E0, 0x93C7, - 0x0000, 0x0000, 0x924E, 0x0000, 0x89DB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x94EE, - 0x0000, 0x0000, 0x8B62, 0x0000, 0x0000, 0x92B2, - 0x0000, 0x0000, 0xE67A, 0x0000, 0xE678, 0x0000, - 0x0000, 0x926B, 0x0000, 0x0000, 0x0000, 0x90BF, - 0x8AD0, 0xE679, 0x0000, 0x907A, 0x0000, 0x0000, - 0x97C8, 0x0000, 0x0000, 0x0000, 0x985F, 0x0000, - 0x0000, 0x0000, 0xE67B, 0xE687, 0x92B3, 0x0000, - 0xE686, 0x0000, 0xE683, 0xE68B, 0xE684, 0x0000, - 0xE680, 0x0000, 0x92FA, 0xE67E, 0x0000, 0x0000, - 0x0000, 0xE67C, 0x0000, 0x9740, 0x8E90, 0x0000, - 0x0000, 0xE681, 0x0000, 0xE67D, 0x0000, 0x0000, - 0x0000, 0xE685, 0x8F94, 0x0000, 0x8CBF, 0x0000, - 0x0000, 0x0000, 0x91F8, 0x0000 -}; - -static u16 Ucs8B[256] = { - 0x9664, 0x8979, 0x88E0, 0x0000, 0x93A3, 0x0000, - 0x0000, 0xE689, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE688, 0x0000, 0x93E4, 0x0000, 0xE68D, 0x0000, - 0x0000, 0x0000, 0xE682, 0x0000, 0xE68C, 0xE68E, - 0x0000, 0x8CAA, 0xE68A, 0x8D75, 0x0000, 0x8ED3, - 0x0000, 0x0000, 0xE68F, 0x9777, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE692, 0x0000, 0xE695, 0x0000, - 0x0000, 0xE693, 0x9554, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE690, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8BDE, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE694, 0x0000, 0x0000, 0xE696, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE69A, 0x0000, 0x0000, 0xE697, 0x0000, - 0xE699, 0xE698, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE69B, 0x0000, 0x8EAF, 0x0000, - 0xE69D, 0xE69C, 0x9588, 0x0000, 0x0000, 0xE69F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8C78, 0x0000, 0x0000, 0x0000, 0x0000, 0xE69E, - 0xE6A0, 0x0000, 0x0000, 0xE6A1, 0x8B63, 0xE3BF, - 0x8FF7, 0x0000, 0xE6A2, 0x0000, 0x0000, 0x8CEC, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6A3, - 0x0000, 0x0000, 0xE6A4, 0x0000, 0x0000, 0x8E5D, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9DCC, 0x0000, 0xE6A5, 0x0000, 0xE6A6, 0x0000, - 0x8F51, 0x0000, 0xE6A7, 0xE6A8, 0x0000, 0x0000, - 0xE6A9, 0x0000, 0x0000, 0xE6AA, 0xE6AB, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs8C[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x924A, 0x0000, 0x0000, 0xE6AC, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE6AE, 0x0000, 0xE6AD, - 0x0000, 0x0000, 0x0000, 0x0000, 0x93A4, 0x0000, - 0xE6AF, 0x0000, 0x964C, 0x0000, 0xE6B0, 0x0000, - 0xE6B1, 0x0000, 0xE6B2, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE6B3, 0x0000, 0x0000, 0x0000, 0x0000, - 0x93D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8FDB, 0xE6B4, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8D8B, 0x98AC, - 0xE6B5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE6B6, 0x955E, 0xE6B7, 0x0000, 0xE6BF, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE6B8, 0x0000, - 0x0000, 0xE6BA, 0x0000, 0x0000, 0x0000, 0xE6B9, - 0xE6BB, 0x0000, 0x9665, 0xE6BC, 0xE6BD, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE6BE, 0x0000, - 0x0000, 0x0000, 0xE6C0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8A4C, 0x92E5, 0x0000, 0x9589, 0x8DE0, - 0x8D76, 0x0000, 0x0000, 0x0000, 0x0000, 0x956E, - 0x89DD, 0x94CC, 0xE6C3, 0x8AD1, 0x90D3, 0xE6C2, - 0xE6C7, 0x9299, 0x96E1, 0x0000, 0xE6C5, 0xE6C6, - 0x8B4D, 0x0000, 0xE6C8, 0x9483, 0x91DD, 0x0000, - 0x0000, 0x94EF, 0x935C, 0xE6C4, 0x0000, 0x9666, - 0x89EA, 0xE6CA, 0x9847, 0x92C0, 0x9864, 0x0000, - 0x0000, 0x8E91, 0xE6C9, 0x0000, 0x91AF, 0x0000, - 0x0000, 0xE6DA, 0x9147, 0x0000, 0x0000, 0x93F6, - 0x0000, 0x956F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE6CD, 0x8E5E, 0x8E92, 0x0000, - 0x8FDC, 0x0000, 0x9485, 0x0000, 0x8CAB, 0xE6CC, - 0xE6CB, 0x0000, 0x958A, 0x0000, 0x0000, 0x0000, - 0x8EBF, 0x0000, 0x0000, 0x9371, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE6CF, 0xE6D0, - 0x8D77, 0xE6CE, 0x0000, 0x0000 -}; - -static u16 Ucs8D[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0xE6D1, 0xE6D2, - 0x0000, 0xE6D4, 0x91A1, 0x0000, 0xE6D3, 0x8AE4, - 0x0000, 0xE6D6, 0x0000, 0xE6D5, 0xE6D7, 0x0000, - 0x0000, 0xE6D9, 0xE6DB, 0x0000, 0xE6DC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x90D4, 0x0000, - 0x8ECD, 0xE6DD, 0x0000, 0x0000, 0x0000, 0x8A71, - 0x0000, 0xE6DE, 0x0000, 0x0000, 0x9196, 0xE6DF, - 0x0000, 0xE6E0, 0x958B, 0x0000, 0x0000, 0x8B4E, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE6E1, 0x0000, 0x0000, - 0x0000, 0x92B4, 0x0000, 0x0000, 0x0000, 0x0000, - 0x897A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE6E2, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8EEF, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9096, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91AB, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE6E5, 0x0000, 0x0000, 0x0000, 0xE6E4, 0x0000, - 0x0000, 0x0000, 0xE6E3, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6EB, - 0xE6E9, 0x0000, 0x0000, 0xE6E6, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE6E8, 0x0000, - 0x0000, 0x0000, 0xE6E7, 0xE6EA, 0x0000, 0x8B97, - 0x0000, 0xE6EE, 0x0000, 0x90D5, 0x0000, 0xE6EF, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8CD7, 0x0000, - 0xE6EC, 0xE6ED, 0x0000, 0x0000, 0x0000, 0x9848, - 0x0000, 0x0000, 0x0000, 0x92B5, 0x0000, 0x9148, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE6F0, 0x0000, 0x0000, 0xE6F3 -}; - -static u16 Ucs8E[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE6F1, 0xE6F2, 0x9778, 0x0000, - 0x0000, 0x0000, 0x0000, 0x93A5, 0xE6F6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6F4, - 0xE6F5, 0xE6F7, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE748, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE6FA, 0x0000, 0x0000, 0x0000, 0xE6FB, 0xE6F9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE6F8, 0x0000, 0x92FB, 0x0000, 0x0000, 0xE740, - 0xE744, 0xE741, 0xE6FC, 0x0000, 0xE742, 0x0000, - 0x0000, 0x0000, 0xE743, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE74A, 0x0000, 0x0000, 0x0000, 0xE745, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90D6, - 0xE747, 0x0000, 0x0000, 0xE749, 0xE746, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE74C, 0x0000, 0x8F52, 0x0000, 0xE74B, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE74D, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE74E, 0x0000, 0x0000, - 0xE751, 0xE750, 0x0000, 0xE74F, 0x0000, 0x0000, - 0xE753, 0xE752, 0x0000, 0x96F4, 0x0000, 0x0000, - 0x0000, 0xE755, 0x0000, 0xE754, 0xE756, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE757, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE759, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE758, 0x9067, 0xE75A, 0x0000, - 0x0000, 0x8BEB, 0xE75B, 0xE75D, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE75E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE75F, - 0xE75C, 0x0000, 0xE760, 0x0000, 0x8ED4, 0xE761, - 0x8B4F, 0x8C52, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8CAC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE762, 0x0000, 0x0000, - 0x0000, 0x93EE, 0x0000, 0x0000, 0x935D, 0xE763, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE766, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8EB2, 0x0000, 0x0000, 0xE765, - 0xE764, 0x8C79, 0xE767, 0x0000 -}; - -static u16 Ucs8F[256] = { - 0x0000, 0x0000, 0x0000, 0x8A72, 0x0000, 0xE769, - 0x0000, 0x0000, 0x0000, 0x8DDA, 0xE768, 0x0000, - 0xE771, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE76B, 0xE76D, 0x95E3, 0xE76A, 0x0000, 0x0000, - 0x0000, 0xE76C, 0x0000, 0xE770, 0xE76E, 0x8B50, - 0x0000, 0xE76F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE772, 0x0000, 0x0000, 0x9479, - 0x97D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F53, - 0x0000, 0x0000, 0x0000, 0xE773, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9741, 0xE775, 0x0000, 0xE774, - 0x0000, 0x0000, 0xE778, 0x9760, 0x0000, 0x0000, - 0xE777, 0x0000, 0x8A8D, 0xE776, 0xE77B, 0x0000, - 0x0000, 0xE77A, 0x0000, 0x0000, 0xE779, 0x9351, - 0xE77C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE77D, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE77E, 0x0000, 0x0000, 0x8D8C, - 0x0000, 0x8C44, 0xE780, 0xE781, 0xE782, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9068, - 0xE783, 0x0000, 0x8EAB, 0xE784, 0x0000, 0x0000, - 0x0000, 0xE785, 0x0000, 0x0000, 0x0000, 0x999F, - 0x999E, 0x0000, 0x0000, 0x0000, 0x0000, 0xE786, - 0xE390, 0xE787, 0x9243, 0x904A, 0x945F, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE788, 0x0000, 0x0000, - 0x95D3, 0x92D2, 0x8D9E, 0x0000, 0x0000, 0x9248, - 0x0000, 0x0000, 0x8949, 0x0000, 0x9698, 0x9076, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8C7D, 0x0000, 0x0000, 0x8BDF, - 0x0000, 0x0000, 0x95D4, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE789, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE78B, 0x0000, - 0x0000, 0xE78A, 0x89DE, 0x0000, 0x0000, 0x93F4, - 0xE78C, 0x9497, 0x0000, 0x9352, 0x0000, 0xE78D, - 0x8F71, 0x0000, 0x0000, 0x0000, 0xE78F, 0x0000, - 0x0000, 0x96C0, 0xE79E, 0xE791, 0xE792, 0x0000, - 0x0000, 0x92C7, 0x0000, 0x0000 -}; - -static u16 Ucs90[256] = { - 0x91DE, 0x9197, 0x0000, 0x93A6, 0x0000, 0xE790, - 0x8B74, 0x0000, 0x0000, 0x0000, 0x0000, 0xE799, - 0x0000, 0xE796, 0xE7A3, 0x93A7, 0x9280, 0xE793, - 0x0000, 0x92FC, 0x9372, 0xE794, 0xE798, 0x9080, - 0x0000, 0x9487, 0x92CA, 0x0000, 0x0000, 0x90C0, - 0xE797, 0x91AC, 0x91A2, 0xE795, 0x88A7, 0x9841, - 0x0000, 0x0000, 0x0000, 0xE79A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x91DF, 0x0000, - 0x0000, 0x8F54, 0x9069, 0x0000, 0x0000, 0xE79C, - 0xE79B, 0x0000, 0x88ED, 0xE79D, 0x0000, 0x0000, - 0x954E, 0x0000, 0xE7A5, 0x0000, 0x0000, 0x93D9, - 0x908B, 0x0000, 0x0000, 0x9278, 0x0000, 0x8BF6, - 0x0000, 0xE7A4, 0x9756, 0x895E, 0x0000, 0x95D5, - 0x89DF, 0xE79F, 0xE7A0, 0xE7A1, 0xE7A2, 0x93B9, - 0x9242, 0x88E1, 0xE7A6, 0x0000, 0xE7A7, 0xEAA1, - 0x0000, 0x0000, 0x91BB, 0x0000, 0xE7A8, 0x0000, - 0x8993, 0x916B, 0x0000, 0x8CAD, 0x0000, 0x9779, - 0x0000, 0x0000, 0xE7A9, 0x934B, 0x0000, 0x0000, - 0x0000, 0x9198, 0x8ED5, 0xE7AA, 0x0000, 0x0000, - 0xE7AD, 0x0000, 0x0000, 0x8F85, 0xE7AB, 0x914A, - 0x9149, 0x0000, 0x88E2, 0x0000, 0x97C9, 0xE7AF, - 0x0000, 0x94F0, 0xE7B1, 0xE7B0, 0xE7AE, 0xE284, - 0x8AD2, 0x0000, 0x0000, 0xE78E, 0x0000, 0xE7B3, - 0xE7B2, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7B4, - 0x0000, 0x9757, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x93DF, 0x0000, 0x0000, 0x964D, 0x0000, - 0xE7B5, 0x0000, 0x8ED7, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE7B6, 0x0000, 0xE7B7, 0x0000, 0x0000, - 0x0000, 0xE7B8, 0x0000, 0x0000, 0x9340, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x88E8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8D78, 0x0000, - 0x0000, 0x0000, 0x9859, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE7BC, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8C53, 0xE7B9, 0x0000, - 0xE7BA, 0x0000, 0x0000, 0x0000, 0x9594, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8A73, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9758, - 0x0000, 0x8BBD, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9373, 0x0000, 0x0000 -}; - -static u16 Ucs91[256] = { - 0x0000, 0x0000, 0xE7BD, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE7BE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE7BF, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9341, 0x0000, 0x0000, - 0xE7C1, 0x0000, 0xE7C0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x93D1, 0xE7C2, 0x8F55, 0x8EDE, 0x947A, - 0x9291, 0x0000, 0x0000, 0x0000, 0x8EF0, 0x0000, - 0x908C, 0x0000, 0xE7C3, 0x0000, 0xE7C4, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x907C, 0xE7C5, 0x0000, 0xE7C6, - 0x0000, 0x0000, 0x0000, 0xE7C7, 0x978F, 0x0000, - 0x8F56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE7C9, 0xE7C8, 0x0000, 0x8D79, 0x0000, 0x8D93, - 0x8E5F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE7CC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8F86, 0x0000, 0xE7CB, - 0x0000, 0xE7CA, 0x0000, 0x91E7, 0x0000, 0x0000, - 0x8CED, 0x0000, 0x90C1, 0x0000, 0x0000, 0x0000, - 0x0000, 0x94AE, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8F58, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE7CD, 0x0000, 0x8FDD, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE7D0, 0xE7CE, 0x0000, 0x0000, - 0x0000, 0xE7CF, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE7D2, 0xE7D1, 0x0000, 0x0000, 0x8FF8, 0x0000, - 0xE7D3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE7D4, 0xE7D5, 0x0000, 0x0000, 0x0000, 0x0000, - 0x94CE, 0x8DD1, 0x8EDF, 0xE7D6, 0x0000, 0xE7D7, - 0x97A2, 0x8F64, 0x96EC, 0x97CA, 0xE7D8, 0x8BE0, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE7D9, 0x0000, - 0x9342, 0x0000, 0x0000, 0xE7DC, 0x8A98, 0x906A, - 0x0000, 0xE7DA, 0x0000, 0xE7DB, 0x0000, 0x92DE, - 0x0000, 0x0000, 0x9674, 0x8BFA, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7DE, - 0xE7DF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE7DD, 0x0000, 0x0000, 0xE7E1 -}; - -static u16 Ucs92[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x93DD, 0x8A62, 0x0000, 0x0000, 0xE7E5, - 0x0000, 0x0000, 0xE7E2, 0xE7E4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE7E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE86E, - 0x0000, 0x0000, 0xE7E3, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x97E9, 0x0000, - 0x0000, 0x8CD8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE7ED, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9353, 0xE7E8, 0x0000, 0x0000, - 0xE7EB, 0xE7E9, 0x0000, 0xE7EE, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE7EF, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE7E7, 0x0000, 0x0000, - 0xE7F4, 0x8994, 0x0000, 0x0000, 0xE7E6, 0x0000, - 0x0000, 0x0000, 0x94AB, 0x0000, 0xE7EA, 0x0000, - 0x8FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D7A, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9667, 0x0000, 0x8BE2, 0x0000, 0x0000, 0x8F65, - 0x0000, 0x93BA, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x914C, 0x0000, 0xE7F2, 0x0000, 0xE7EC, - 0xE7F1, 0x0000, 0x96C1, 0x0000, 0x92B6, 0xE7F3, - 0xE7F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x914B, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE7F7, 0x0000, 0xE7F6, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE7F5, 0x0000, 0x0000, - 0x964E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8F9B, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7F8, - 0x95DD, 0x0000, 0x0000, 0x8973, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9565, 0x9292, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8B98, 0x0000, 0xE7FA, 0x0000, - 0x8D7C, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs93[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8E4B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE7F9, 0x908D, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x908E, 0xE840, 0xE842, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8FF9, 0x0000, 0xE841, 0xE843, - 0x0000, 0x0000, 0x8BD1, 0x0000, 0x9564, 0x0000, - 0x0000, 0x8EE0, 0x9842, 0x0000, 0xE7FC, 0x8DF6, - 0x0000, 0x0000, 0x985E, 0x0000, 0x0000, 0xE845, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE844, 0xE846, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE7FB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x93E7, 0x0000, 0x9374, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x92D5, 0x0000, 0xE84B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x9262, 0xE847, 0x0000, 0x0000, 0x0000, - 0xE848, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8C4C, 0x0000, 0xE84A, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8CAE, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE849, 0x0000, - 0x8FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8A99, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE84F, 0x0000, - 0x8DBD, 0x9199, 0x0000, 0x0000, 0x92C8, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A5A, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE84D, 0xE84E, - 0x92C1, 0x0000, 0xE84C, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE850, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE856, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE859, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE858, 0x934C, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE851, 0xE852, - 0xE855, 0x0000, 0x0000, 0x0000, 0x0000, 0xE857, - 0x0000, 0x0000, 0x0000, 0x8BBE, 0x0000, 0x0000, - 0xE85A, 0xE854, 0x0000, 0x0000, 0xE853, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs94[256] = { - 0x0000, 0x0000, 0x0000, 0xE85E, 0x0000, 0x0000, - 0x0000, 0xE85F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE860, 0x0000, - 0x0000, 0xE85D, 0xE85C, 0x0000, 0x0000, 0x0000, - 0x8FE0, 0x93A8, 0xE85B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE864, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE862, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE863, - 0xE861, 0x0000, 0x91F6, 0x0000, 0xE865, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE866, - 0x0000, 0x0000, 0xE868, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8AD3, 0xE867, 0x96F8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE873, 0xE869, 0x0000, 0x0000, 0xE86C, 0x0000, - 0xE86A, 0x0000, 0xE86B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE86D, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE86F, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE870, 0x0000, 0xE871, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE874, 0xE872, - 0xE875, 0xE877, 0x0000, 0xE876, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs95[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92B7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x96E5, 0x0000, 0xE878, 0x914D, - 0x0000, 0x0000, 0x0000, 0xE879, 0x0000, 0x95C2, - 0xE87A, 0x8A4A, 0x0000, 0x0000, 0x0000, 0x895B, - 0x0000, 0x8AD5, 0x0000, 0x8AD4, 0xE87B, 0x0000, - 0xE87C, 0x0000, 0xE87D, 0xE87E, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE880, 0x0000, - 0x8AD6, 0x8A74, 0x8D7D, 0x94B4, 0x0000, 0xE882, - 0xE881, 0x0000, 0x0000, 0x0000, 0x0000, 0xE883, - 0x0000, 0x0000, 0x0000, 0x0000, 0x897B, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE886, - 0x0000, 0xE885, 0xE884, 0x0000, 0xE887, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE88A, 0x0000, 0x0000, - 0x0000, 0x88C5, 0x0000, 0x0000, 0xE888, 0x0000, - 0xE88C, 0xE88B, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE88E, 0xE88D, 0xE88F, 0x0000, - 0x93AC, 0x0000, 0x0000, 0x0000, 0xE890, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE891, 0xE893, 0x0000, - 0x0000, 0xE892, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs96[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x958C, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE894, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE895, 0x0000, - 0x8DE3, 0x0000, 0x0000, 0x0000, 0xE896, 0xE897, - 0x0000, 0x0000, 0x9668, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x916A, - 0x0000, 0x0000, 0x0000, 0x88A2, 0x91C9, 0x0000, - 0xE898, 0x0000, 0x958D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE89B, 0xE899, 0x8D7E, - 0x0000, 0xE89A, 0x8CC0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x95C3, 0xE89D, 0xE89F, 0xE89E, 0xE8A0, - 0x0000, 0x0000, 0x8940, 0x9077, 0x8F9C, 0x8AD7, - 0xE8A1, 0x0000, 0x0000, 0x0000, 0x9486, 0x0000, - 0xE8A3, 0x0000, 0x0000, 0x0000, 0x8941, 0x0000, - 0xE8A2, 0x92C2, 0x0000, 0x97CB, 0x93A9, 0xE89C, - 0x97A4, 0x0000, 0x8CAF, 0x0000, 0x0000, 0x977A, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8BF7, 0x97B2, 0x0000, 0x8C47, 0x0000, - 0x91E0, 0xE440, 0x0000, 0xE8A4, 0x8A4B, 0x908F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8A75, 0xE8A6, - 0x0000, 0xE8A7, 0xE8A5, 0x8C84, 0x0000, 0x8DDB, - 0x8FE1, 0x0000, 0x0000, 0x0000, 0x8942, 0x0000, - 0x0000, 0x97D7, 0x0000, 0x0000, 0x0000, 0xE8A9, - 0xE7AC, 0x0000, 0xE8A8, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE8AC, 0xE8AA, 0xE8AB, 0x0000, - 0xE8AD, 0x0000, 0xE8AE, 0x97EA, 0xE8AF, 0xE8B0, - 0x0000, 0x90C7, 0x94B9, 0x0000, 0x0000, 0x0000, - 0x909D, 0x8AE5, 0x0000, 0x0000, 0x9759, 0x89EB, - 0x8F57, 0x8CD9, 0x0000, 0xE8B3, 0x0000, 0xE8B2, - 0x8E93, 0xE8B4, 0xE8B1, 0x0000, 0x0000, 0x8E47, - 0x0000, 0x0000, 0x0000, 0xE8B8, 0xE5AB, 0x0000, - 0x0000, 0x99D4, 0x0000, 0x9097, 0xE8B6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x97A3, 0x93EF, - 0x0000, 0x0000, 0x0000, 0x0000, 0x894A, 0x0000, - 0x90E1, 0x8EB4, 0x0000, 0x0000, 0x0000, 0x0000, - 0x95B5, 0x0000, 0x895F, 0x0000, 0x0000, 0x0000, - 0x97EB, 0x978B, 0x0000, 0xE8B9, 0x0000, 0x9364, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs97[256] = { - 0x8EF9, 0x0000, 0x0000, 0x0000, 0xE8BA, 0x0000, - 0xE8BB, 0x906B, 0xE8BC, 0x0000, 0x97EC, 0x0000, - 0x0000, 0xE8B7, 0xE8BE, 0xE8C0, 0x0000, 0xE8BF, - 0x0000, 0xE8BD, 0x0000, 0x0000, 0xE8C1, 0x0000, - 0x0000, 0xE8C2, 0x0000, 0x0000, 0x919A, 0x0000, - 0x89E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE8C3, 0x0000, 0x0000, 0x96B6, 0x0000, 0x0000, - 0xE8C4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE8C5, 0x0000, 0x9849, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9E50, 0xE8C6, 0x0000, 0x0000, - 0x0000, 0xE8C7, 0xE8C8, 0x0000, 0x0000, 0x0000, - 0xE8CC, 0x0000, 0xE8C9, 0x0000, 0xE8CA, 0x0000, - 0xE8CB, 0xE8CD, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x90C2, 0x0000, - 0x0000, 0x0000, 0x96F5, 0x0000, 0x0000, 0x90C3, - 0x0000, 0x0000, 0xE8CE, 0x0000, 0x94F1, 0x0000, - 0xE8CF, 0xEA72, 0x96CA, 0x0000, 0xE8D0, 0x0000, - 0xE8D1, 0x0000, 0xE8D2, 0x8A76, 0x0000, 0xE8D4, - 0x0000, 0x9078, 0x0000, 0x0000, 0x0000, 0xE8D5, - 0x0000, 0x0000, 0x8C43, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE8D6, 0xE8DA, 0x0000, 0xE8D8, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE8D9, 0x0000, 0x0000, - 0x8A93, 0xE8D7, 0xE8DB, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE8DC, 0x0000, 0x88C6, 0x0000, 0xE8DD, - 0xE8DE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8FE2, 0x0000, 0x0000, 0x0000, - 0xE8DF, 0x0000, 0x0000, 0x0000, 0x8B66, 0x0000, - 0x0000, 0xE8E2, 0x0000, 0x0000, 0xE8E1, 0x0000, - 0xE8E0, 0x0000, 0x0000, 0xE691, 0x0000, 0x95DA, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE8E3, - 0xE8E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE8E5, 0x0000, 0x0000, - 0xE8E6, 0x0000, 0xE8E7, 0x0000, 0x0000, 0xE8E8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8AD8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE8E9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE8EA, 0x9442, 0x0000, - 0x0000, 0x0000, 0xE8EC, 0x89B9, 0x0000, 0xE8EF, - 0xE8EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x8943, - 0x0000, 0x0000, 0x0000, 0x8BBF -}; - -static u16 Ucs98[256] = { - 0x0000, 0x95C5, 0x92B8, 0x8DA0, 0x0000, 0x8D80, - 0x8F87, 0x0000, 0x907B, 0x0000, 0x0000, 0x0000, - 0xE8F1, 0x0000, 0x0000, 0xE8F0, 0x9761, 0x8AE6, - 0x94D0, 0x93DA, 0x0000, 0x0000, 0x0000, 0x909C, - 0x97CC, 0x0000, 0x8C7A, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE8F4, 0x0000, 0x0000, - 0xE8F3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x966A, 0x93AA, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x896F, 0x0000, - 0x0000, 0xE8F5, 0xE8F2, 0x0000, 0x0000, 0x9570, - 0x978A, 0xE8F6, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE8F7, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE8F9, 0x91E8, 0x8A7A, - 0x8A7B, 0xE8F8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8AE7, 0x8CB0, 0x0000, 0x0000, 0x8AE8, 0x0000, - 0x0000, 0x935E, 0x0000, 0x0000, 0x97DE, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8CDA, 0x0000, 0x0000, 0x0000, 0xE8FA, - 0x0000, 0x0000, 0x0000, 0xE8FB, 0xE8FC, 0xE940, - 0x0000, 0xE942, 0xE941, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9597, 0x0000, 0xE943, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE944, 0x0000, 0xE945, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE946, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE948, 0xE947, 0x0000, - 0xE949, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x94F2, 0xE3CA, 0x0000, - 0x0000, 0x9048, 0x0000, 0x0000, 0x8B51, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE94A, - 0x0000, 0xE94B, 0x0000, 0x99AA, 0x9F5A, 0x94D1, - 0x0000, 0x0000, 0x88F9, 0x0000, 0x88B9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8E94, 0x964F, 0x8FFC, 0x0000 -}; - -static u16 Ucs99[256] = { - 0x0000, 0x0000, 0x0000, 0xE94C, 0x0000, 0x96DD, - 0x0000, 0x0000, 0x0000, 0xE94D, 0x977B, 0x0000, - 0x8961, 0x0000, 0x0000, 0x0000, 0x8E60, 0x0000, - 0xE94E, 0x89EC, 0xE94F, 0x0000, 0x0000, 0x0000, - 0xE950, 0x0000, 0x0000, 0x0000, 0x0000, 0xE952, - 0xE953, 0x0000, 0xE955, 0xE951, 0x0000, 0x0000, - 0xE954, 0x0000, 0x0000, 0x0000, 0x8AD9, 0x0000, - 0x0000, 0x0000, 0xE956, 0x0000, 0xE957, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE958, 0xE959, 0x0000, 0x0000, 0x0000, - 0xE95A, 0x0000, 0x0000, 0xE95C, 0x0000, 0x0000, - 0x0000, 0xE95B, 0x0000, 0xE95E, 0xE961, 0x0000, - 0x0000, 0x0000, 0xE95D, 0xE95F, 0xE960, 0x0000, - 0x0000, 0xE962, 0x0000, 0x8BC0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8EF1, 0xE963, 0xE964, 0x8D81, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE965, 0x0000, 0x0000, - 0x8A5D, 0x0000, 0x0000, 0x0000, 0x946E, 0xE966, - 0xE967, 0x0000, 0x0000, 0x0000, 0x0000, 0x9279, - 0x93E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE968, 0x0000, 0x0000, 0x0000, - 0x0000, 0x949D, 0x0000, 0x0000, 0x91CA, 0x8977, - 0x8BEC, 0x0000, 0x8BED, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9293, 0xE96D, - 0x8BEE, 0x0000, 0x0000, 0x89ED, 0x0000, 0x0000, - 0xE96C, 0x0000, 0x0000, 0xE96A, 0x0000, 0xE96B, - 0x0000, 0xE969, 0x0000, 0x0000, 0xE977, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE96E, 0xE96F, 0x0000, - 0x0000, 0xE970, 0xE971, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE973, 0x0000, 0x0000, 0xE972, - 0x0000, 0x0000, 0x0000, 0x8F78 -}; - -static u16 Ucs9A[256] = { - 0x0000, 0xE974, 0x0000, 0x0000, 0x0000, 0xE976, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8B52, 0xE975, 0x0000, 0x0000, - 0x919B, 0x8CB1, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE978, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x91CB, 0x0000, - 0x0000, 0xE979, 0x0000, 0x0000, 0x0000, 0x0000, - 0x93AB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE97A, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE980, 0x0000, 0xE97D, 0x0000, - 0xE97C, 0xE97E, 0x0000, 0xE97B, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE982, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE981, 0x0000, 0xE984, 0x0000, 0x0000, - 0x8BC1, 0xE983, 0x0000, 0x0000, 0x0000, 0xE985, - 0x0000, 0x0000, 0xE986, 0x0000, 0xE988, 0xE987, - 0x0000, 0x0000, 0x0000, 0xE989, 0xE98B, 0xE98A, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x8D9C, 0x0000, 0x0000, 0x0000, 0x0000, 0xE98C, - 0x0000, 0x0000, 0xE98D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8A5B, 0x0000, - 0x0000, 0x0000, 0xE98E, 0x0000, 0x0000, 0x0000, - 0xE98F, 0x0000, 0x0000, 0x0000, 0x9091, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE990, 0x0000, 0xE991, - 0x0000, 0xE992, 0xE993, 0x0000, 0x0000, 0x0000, - 0x8D82, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE994, 0xE995, 0x0000, 0x0000, 0xE996, 0xE997, - 0x0000, 0x0000, 0xE998, 0x0000, 0x0000, 0x0000, - 0x94AF, 0xE99A, 0x0000, 0x9545, 0xE99B, 0xE999, - 0x0000, 0xE99D, 0x0000, 0x0000, 0xE99C, 0x0000, - 0x0000, 0xE99E, 0x0000, 0x0000, 0x0000, 0xE99F, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs9B[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE9A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE9A1, 0x0000, 0xE9A2, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE9A3, 0x0000, 0x0000, 0xE9A4, 0xE9A5, - 0x0000, 0xE9A6, 0x0000, 0xE9A7, 0xE9A8, 0xE9A9, - 0xE9AA, 0x0000, 0x0000, 0x0000, 0xE9AB, 0xE9AC, - 0x0000, 0x9F54, 0xE9AD, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2F6, - 0x8B53, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A40, - 0x8DB0, 0xE9AF, 0xE9AE, 0x96A3, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9B1, - 0xE9B2, 0xE9B0, 0x0000, 0xE9B3, 0x0000, 0x0000, - 0x9682, 0x0000, 0x0000, 0x0000, 0xE9B4, 0x0000, - 0x8B9B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9844, 0x0000, 0x0000, - 0x0000, 0x0000, 0xE9B5, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9B7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x88BC, 0x0000, - 0x0000, 0xE9B8, 0x95A9, 0xE9B6, 0x0000, 0x0000, - 0xE9B9, 0xE9BA, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE9BB, 0xE9BC, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE9BD, 0x0000, 0x968E, 0x8E4C, 0x0000, 0x8DF8, - 0x914E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE9BE, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9C1, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE9BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE9C2, 0x0000, 0x0000, 0x8CEF, 0xE9C0, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE9C3, 0x0000, 0xE9C4, - 0xE9C5, 0x0000, 0xE9C9, 0x0000, 0x8E49, 0x0000, - 0x0000, 0x0000, 0x0000, 0x91E2, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE9CA, 0xE9C7, 0xE9C6, - 0xE9C8, 0x0000, 0x0000, 0x0000, 0x8C7E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE9CE, 0xE9CD, 0xE9CC, 0x0000, 0x0000, 0x88B1, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs9C[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0xE9D8, 0x0000, - 0xE9D4, 0x0000, 0xE9D5, 0xE9D1, 0xE9D7, 0x0000, - 0xE9D3, 0x8A82, 0x0000, 0x0000, 0x986B, 0x0000, - 0xE9D6, 0xE9D2, 0xE9D0, 0xE9CF, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE9DA, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xE9DD, 0x0000, 0x0000, - 0xE9DC, 0xE9DB, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x9568, 0xE9D9, 0x88F1, - 0xE9DE, 0x0000, 0xE9E0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8A8F, 0xE9CB, 0x8956, - 0x0000, 0x0000, 0xE9E2, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE9E1, 0xE9DF, - 0x924C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9690, 0x0000, - 0x0000, 0x0000, 0x0000, 0x97D8, 0x0000, 0x0000, - 0xE9E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xE9E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xE9E5, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xE9E6, 0x0000, - 0xE9E7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x92B9, 0x0000, 0xE9E8, 0x0000, 0x94B5, - 0x0000, 0xE9ED, 0xE9E9, 0x0000, 0x0000, 0x0000, - 0xE9EA, 0x0000, 0x0000, 0x9650, 0x96C2, 0x0000, - 0x93CE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Ucs9D[256] = { - 0x0000, 0x0000, 0x0000, 0xE9EE, 0x0000, 0x0000, - 0xE9EF, 0x93BC, 0xE9EC, 0xE9EB, 0x0000, 0x0000, - 0x0000, 0x0000, 0x89A8, 0x0000, 0x0000, 0x0000, - 0xE9F7, 0x0000, 0x0000, 0xE9F6, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x8995, 0x0000, 0x0000, - 0x0000, 0xE9F4, 0x0000, 0x0000, 0x0000, 0xE9F3, - 0x0000, 0x0000, 0xE9F1, 0x0000, 0x8A9B, 0x0000, - 0xE9F0, 0x8EB0, 0x89A7, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D83, - 0x0000, 0x0000, 0xE9FA, 0xE9F9, 0x0000, 0xE9F8, - 0x0000, 0x0000, 0xE9F5, 0x0000, 0xE9FB, 0x0000, - 0xE9FC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xEA44, 0xEA43, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA45, - 0x0000, 0x0000, 0x894C, 0xEA40, 0xEA41, 0x0000, - 0x8D94, 0x96B7, 0x0000, 0x0000, 0xEA42, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x9651, 0x0000, 0x0000, 0xEA4A, 0x0000, 0x0000, - 0xEA46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xEA4B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xEA48, 0x0000, 0xEA47, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C7B, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xEA4C, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xEA4D, 0x0000, 0x0000, 0x0000, - 0x0000, 0xEA4E, 0x0000, 0xEA49, 0x0000, 0x0000, - 0x0000, 0xE9F2, 0x0000, 0x0000, 0xEA4F, 0x0000, - 0x92DF, 0x0000, 0x0000, 0x0000, 0xEA53, 0x0000, - 0xEA54, 0xEA52, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xEA51, 0xEA57, 0x0000, 0xEA50, 0x0000, - 0xEA55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xEA56, 0x0000, 0x0000, - 0x0000, 0xEA59, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xEA58, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xEA5B, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xEA5C, 0x0000, 0xEA5D, - 0x0000, 0x0000, 0x9868, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xEA5A, 0x91E9, 0x8DEB, 0x0000, - 0x0000, 0xEA5E, 0x0000, 0x0000 -}; - -static u16 Ucs9E[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xEA5F, 0xEA60, 0x0000, 0x0000, - 0xEA61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xEA62, 0x0000, 0x0000, - 0x8CB2, 0xEA63, 0x0000, 0x0000, 0x0000, 0xEA64, - 0x0000, 0x8EAD, 0x0000, 0xEA65, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xEA66, 0x0000, - 0x0000, 0xEA67, 0xEA68, 0x0000, 0x0000, 0x0000, - 0x0000, 0xEA6B, 0xEA69, 0x985B, 0x0000, 0xEA6A, - 0x0000, 0x97ED, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xEA6C, 0x0000, 0x97D9, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xEA6D, 0x949E, 0x0000, - 0x0000, 0xEA6E, 0xEA70, 0x0000, 0x0000, 0xEA71, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xEA6F, 0x8D8D, - 0x96CB, 0x9683, 0x9BF5, 0x0000, 0x9F80, 0x969B, - 0x0000, 0x0000, 0x0000, 0x0000, 0x89A9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xEA73, 0x8B6F, 0xEA74, 0xEA75, 0xEA76, 0x0000, - 0x8D95, 0x0000, 0xEA77, 0x0000, 0x0000, 0x0000, - 0xE0D2, 0x96D9, 0x0000, 0x91E1, 0xEA78, 0xEA7A, - 0xEA79, 0x0000, 0xEA7B, 0x0000, 0x0000, 0x0000, - 0x0000, 0xEA7C, 0x0000, 0x0000, 0xEA7D, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA7E, - 0x0000, 0x0000, 0x0000, 0x0000, 0xEA80, 0x0000, - 0xEA81, 0xEA82, 0x0000, 0xEA83, 0x0000, 0xEA84, - 0xEA85, 0xEA86, 0x0000, 0x0000 -}; - -static u16 Ucs9F[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xEA87, 0xEA88, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x9343, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8CDB, 0x0000, 0xEA8A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x916C, 0xEA8B, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xEA8C, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9540, - 0x0000, 0x0000, 0xEA8D, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0xEA8E, 0xE256, 0x0000, 0x0000, - 0xE6D8, 0xE8EB, 0x0000, 0x0000, 0xEA8F, 0x0000, - 0xEA90, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA92, - 0xEA93, 0xEA94, 0x97EE, 0xEA91, 0x0000, 0x0000, - 0xEA95, 0xEA96, 0x0000, 0x0000, 0xEA98, 0x0000, - 0xEA97, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xEA9A, 0x0000, 0x0000, 0x0000, 0xEA9B, 0xEA99, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x97B4, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA9C, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xEA9D, 0xE273, 0x0000, 0x0000, 0xEA9E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 UcsFF[256] = { - 0x0000, 0x8149, 0x0000, 0x8194, 0x8190, 0x8193, - 0x8195, 0x0000, 0x8169, 0x816A, 0x8196, 0x817B, - 0x8143, 0x0000, 0x8144, 0x815E, 0x824F, 0x8250, - 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256, - 0x8257, 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, - 0x8184, 0x8148, 0x8197, 0x8260, 0x8261, 0x8262, - 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8268, - 0x8269, 0x826A, 0x826B, 0x826C, 0x826D, 0x826E, - 0x826F, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, - 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x816D, - 0x0000, 0x816E, 0x814F, 0x8151, 0x814D, 0x8281, - 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287, - 0x8288, 0x8289, 0x828A, 0x828B, 0x828C, 0x828D, - 0x828E, 0x828F, 0x8290, 0x8291, 0x8292, 0x8293, - 0x8294, 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, - 0x829A, 0x816F, 0x8162, 0x8170, 0x0000, 0x0000, - 0x0000, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, - 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, - 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, - 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, - 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, - 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, - 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, - 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, - 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, - 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8150, - 0x0000, 0x818F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16* UcsSjisTable[256] = {0}; - -u16 OSUTF32toSJIS(u32 utf32) { - u16* table; - - if (0x10000 <= utf32) { - return 0; - } - - table = UcsSjisTable[(utf32 >> 8) & 0xFF]; - if (table != 0) { - return table[utf32 & 0xFF]; - } - - return 0; -} - -static u16 Sjis00[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, - 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, - 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, - 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, - 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, - 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005A, 0x005B, 0x00A5, 0x005D, 0x005E, 0x005F, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, - 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, - 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, - 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, - 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, - 0x203E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF61, - 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, - 0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, - 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0xFF72, 0xFF73, - 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, - 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, - 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, - 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, - 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90, 0xFF91, - 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97, - 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, - 0xFF9E, 0xFF9F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis81[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3001, - 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B, - 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, - 0x00A8, 0xFF3E, 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, - 0x309D, 0x309E, 0x3003, 0x4EDD, 0x3005, 0x3006, - 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0x005C, - 0x301C, 0x2016, 0xFF5C, 0x2026, 0x2025, 0x2018, - 0x2019, 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, - 0x3015, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D, 0x3008, - 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, - 0x300F, 0x3010, 0x3011, 0xFF0B, 0x2212, 0x00B1, - 0x00D7, 0x0000, 0x00F7, 0xFF1D, 0x2260, 0xFF1C, - 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234, 0x2642, - 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, - 0xFF04, 0x00A2, 0x00A3, 0xFF05, 0xFF03, 0xFF06, - 0xFF0A, 0xFF20, 0x00A7, 0x2606, 0x2605, 0x25CB, - 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1, 0x25A0, - 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B, 0x3012, - 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2208, 0x220B, - 0x2286, 0x2287, 0x2282, 0x2283, 0x222A, 0x2229, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2227, 0x2228, 0x00AC, 0x21D2, - 0x21D4, 0x2200, 0x2203, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2220, 0x22A5, 0x2312, 0x2202, - 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, - 0x223D, 0x221D, 0x2235, 0x222B, 0x222C, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, - 0x2021, 0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, - 0x25EF, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis82[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, - 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, - 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, - 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, - 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, - 0xFF39, 0xFF3A, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xFF41, 0xFF42, 0xFF43, - 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, - 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, - 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, - 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3041, 0x3042, 0x3043, - 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, - 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, - 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, - 0x3056, 0x3057, 0x3058, 0x3059, 0x305A, 0x305B, - 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, - 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, - 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, - 0x306E, 0x306F, 0x3070, 0x3071, 0x3072, 0x3073, - 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, - 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, - 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, - 0x3086, 0x3087, 0x3088, 0x3089, 0x308A, 0x308B, - 0x308C, 0x308D, 0x308E, 0x308F, 0x3090, 0x3091, - 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis83[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x30A1, 0x30A2, - 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, - 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, - 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, - 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, - 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, - 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, - 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, - 0x30CD, 0x30CE, 0x30CF, 0x30D0, 0x30D1, 0x30D2, - 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, - 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, - 0x30DF, 0x0000, 0x30E0, 0x30E1, 0x30E2, 0x30E3, - 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, - 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, - 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, - 0x30F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0391, 0x0392, 0x0393, - 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, - 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, - 0x03A7, 0x03A8, 0x03A9, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03B1, - 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, - 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, - 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis84[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0410, 0x0411, - 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, - 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, - 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, - 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, - 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, - 0x042F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0430, 0x0431, - 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, - 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, - 0x043D, 0x0000, 0x043E, 0x043F, 0x0440, 0x0441, - 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, - 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, - 0x044E, 0x044F, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x2500, 0x2502, 0x250C, - 0x2510, 0x2518, 0x2514, 0x251C, 0x252C, 0x2524, - 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513, - 0x251B, 0x2517, 0x2523, 0x2533, 0x252B, 0x253B, - 0x254B, 0x2520, 0x252F, 0x2528, 0x2537, 0x253F, - 0x251D, 0x2530, 0x2525, 0x2538, 0x2542, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis88[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4E9C, 0x5516, 0x5A03, - 0x963F, 0x54C0, 0x611B, 0x6328, 0x59F6, 0x9022, - 0x8475, 0x831C, 0x7A50, 0x60AA, 0x63E1, 0x6E25, - 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, - 0x65A1, 0x6271, 0x5B9B, 0x59D0, 0x867B, 0x98F4, - 0x7D62, 0x7DBE, 0x9B8E, 0x6216, 0x7C9F, 0x88B7, - 0x5B89, 0x5EB5, 0x6309, 0x6697, 0x6848, 0x95C7, - 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, - 0x5049, 0x56F2, 0x5937, 0x59D4, 0x5A01, 0x5C09, - 0x60DF, 0x610F, 0x6170, 0x6613, 0x6905, 0x70BA, - 0x754F, 0x7570, 0x79FB, 0x7DAD, 0x7DEF, 0x80C3, - 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, - 0x4E95, 0x4EA5, 0x57DF, 0x80B2, 0x90C1, 0x78EF, - 0x4E00, 0x58F1, 0x6EA2, 0x9038, 0x7A32, 0x8328, - 0x828B, 0x9C2F, 0x5141, 0x5370, 0x54BD, 0x54E1, - 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, - 0x852D, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis89[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9662, 0x9670, - 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87, 0x70CF, - 0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, - 0x4E11, 0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, - 0x6B1D, 0x851A, 0x9C3B, 0x59E5, 0x53A9, 0x6D66, - 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B, 0x96F2, - 0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, - 0x6620, 0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, - 0x745B, 0x76C8, 0x7A4E, 0x9834, 0x82F1, 0x885B, - 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA, 0x99C5, - 0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, - 0x5186, 0x0000, 0x5712, 0x5830, 0x5944, 0x5BB4, - 0x5EF6, 0x6028, 0x63A9, 0x63F4, 0x6CBF, 0x6F14, - 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01, - 0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, - 0x5869, 0x65BC, 0x6C5A, 0x7525, 0x51F9, 0x592E, - 0x5965, 0x5F80, 0x5FDC, 0x62BC, 0x65FA, 0x6A2A, - 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956, 0x9D2C, - 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, - 0x5C4B, 0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, - 0x4FFA, 0x5378, 0x6069, 0x6E29, 0x7A4F, 0x97F3, - 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D, 0x4FA1, - 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, - 0x5BB6, 0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, - 0x6B4C, 0x6CB3, 0x706B, 0x73C2, 0x798D, 0x79BE, - 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304, 0x8377, - 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, - 0x8FE6, 0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, - 0x6211, 0x7259, 0x753B, 0x81E5, 0x82BD, 0x86FE, - 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB, 0x4F1A, - 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, - 0x602A, 0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, - 0x6539, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis8A[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9B41, 0x6666, - 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75, - 0x82A5, 0x87F9, 0x958B, 0x968E, 0x8C9D, 0x51F1, - 0x52BE, 0x5916, 0x54B3, 0x5BB3, 0x5D16, 0x6168, - 0x6982, 0x6DAF, 0x788D, 0x84CB, 0x8857, 0x8A72, - 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3, - 0x67FF, 0x86CE, 0x920E, 0x5283, 0x5687, 0x5404, - 0x5ED3, 0x62E1, 0x64B9, 0x683C, 0x6838, 0x6BBB, - 0x7372, 0x78BA, 0x7A6B, 0x899A, 0x89D2, 0x8D6B, - 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66, - 0x5CB3, 0x697D, 0x984D, 0x984E, 0x639B, 0x7B20, - 0x6A2B, 0x0000, 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F, - 0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B, 0x6E07, - 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39, - 0x53F6, 0x691B, 0x6A3A, 0x9784, 0x682A, 0x515C, - 0x7AC3, 0x84B2, 0x91DC, 0x938C, 0x565B, 0x9D28, - 0x6822, 0x8305, 0x8431, 0x7CA5, 0x5208, 0x82C5, - 0x74E6, 0x4E7E, 0x4F83, 0x51A0, 0x5BD2, 0x520A, - 0x52D8, 0x52E7, 0x5DFB, 0x559A, 0x582A, 0x59E6, - 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, - 0x611F, 0x6163, 0x61BE, 0x63DB, 0x6562, 0x67D1, - 0x6853, 0x68FA, 0x6B3E, 0x6B53, 0x6C57, 0x6F22, - 0x6F97, 0x6F45, 0x74B0, 0x7518, 0x76E3, 0x770B, - 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, - 0x809D, 0x8266, 0x839E, 0x89B3, 0x8ACC, 0x8CAB, - 0x9084, 0x9451, 0x9593, 0x9591, 0x95A2, 0x9665, - 0x97D3, 0x9928, 0x8218, 0x4E38, 0x542B, 0x5CB8, - 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, - 0x8D0B, 0x96C1, 0x9811, 0x9854, 0x9858, 0x4F01, - 0x4F0E, 0x5371, 0x559C, 0x5668, 0x57FA, 0x5947, - 0x5B09, 0x5BC4, 0x5C90, 0x5E0C, 0x5E7E, 0x5FCC, - 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, - 0x68C4, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis8B[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6A5F, 0x5E30, - 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948, 0x5B63, - 0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, - 0x8D77, 0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, - 0x4E80, 0x507D, 0x5100, 0x5993, 0x5B9C, 0x622F, - 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591, 0x7947, - 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, - 0x97A0, 0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, - 0x8A70, 0x7827, 0x6775, 0x9ECD, 0x5374, 0x5BA2, - 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45, 0x4EC7, - 0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, - 0x6551, 0x0000, 0x673D, 0x6C42, 0x6C72, 0x6CE3, - 0x7078, 0x7403, 0x7A76, 0x7AAE, 0x7B08, 0x7D1A, - 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45, - 0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, - 0x8A31, 0x8DDD, 0x92F8, 0x6F01, 0x79A6, 0x9B5A, - 0x4EA8, 0x4EAB, 0x4EAC, 0x4F9B, 0x4FA0, 0x50D1, - 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354, 0x5321, - 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, - 0x5F4A, 0x602F, 0x6050, 0x606D, 0x631F, 0x6559, - 0x6A4B, 0x6CC1, 0x72C2, 0x72ED, 0x77EF, 0x80F8, - 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1, 0x97FF, - 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, - 0x696D, 0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, - 0x7C81, 0x50C5, 0x52E4, 0x5747, 0x5DFE, 0x9326, - 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981, 0x79BD, - 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, - 0x8B39, 0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, - 0x5036, 0x53E5, 0x533A, 0x72D7, 0x7396, 0x77E9, - 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2, 0x5177, - 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, - 0x9047, 0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, - 0x5C48, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis8C[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6398, 0x7A9F, - 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688, - 0x7C82, 0x6817, 0x7E70, 0x6851, 0x936C, 0x52F2, - 0x541B, 0x85AB, 0x8A13, 0x7FA4, 0x8ECD, 0x90E1, - 0x5366, 0x8888, 0x7941, 0x4FC2, 0x50BE, 0x5211, - 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B, 0x5951, - 0x5F62, 0x5F84, 0x6075, 0x6176, 0x6167, 0x61A9, - 0x63B2, 0x643A, 0x656C, 0x666F, 0x6842, 0x6E13, - 0x7566, 0x7A3D, 0x7CFB, 0x7D4C, 0x7D99, 0x7E4B, - 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63, - 0x8B66, 0x8EFD, 0x981A, 0x9D8F, 0x82B8, 0x8FCE, - 0x9BE8, 0x0000, 0x5287, 0x621F, 0x6483, 0x6FC0, - 0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A, 0x6F54, - 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6, - 0x5039, 0x5026, 0x5065, 0x517C, 0x5238, 0x5263, - 0x55A7, 0x570F, 0x5805, 0x5ACC, 0x5EFA, 0x61B2, - 0x61F8, 0x62F3, 0x6372, 0x691C, 0x6A29, 0x727D, - 0x72AC, 0x732E, 0x7814, 0x786F, 0x7D79, 0x770C, - 0x80A9, 0x898B, 0x8B19, 0x8CE2, 0x8ED2, 0x9063, - 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, - 0x539F, 0x53B3, 0x5E7B, 0x5F26, 0x6E1B, 0x6E90, - 0x7384, 0x73FE, 0x7D43, 0x8237, 0x8A00, 0x8AFA, - 0x9650, 0x4E4E, 0x500B, 0x53E4, 0x547C, 0x56FA, - 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, - 0x6545, 0x67AF, 0x6E56, 0x72D0, 0x7CCA, 0x88B4, - 0x80A1, 0x80E1, 0x83F0, 0x864E, 0x8A87, 0x8DE8, - 0x9237, 0x96C7, 0x9867, 0x9F13, 0x4E94, 0x4E92, - 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, - 0x5FA1, 0x609F, 0x68A7, 0x6A8E, 0x745A, 0x7881, - 0x8A9E, 0x8AA4, 0x8B77, 0x9190, 0x4E5E, 0x9BC9, - 0x4EA4, 0x4F7C, 0x4FAF, 0x5019, 0x5016, 0x5149, - 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, - 0x5411, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis8D[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x540E, 0x5589, - 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D, 0x5B8F, - 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, - 0x5EB7, 0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, - 0x63A7, 0x653B, 0x6602, 0x6643, 0x66F4, 0x676D, - 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A, 0x6D69, - 0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, - 0x7CE0, 0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, - 0x8003, 0x80AF, 0x80B1, 0x8154, 0x818F, 0x822A, - 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2, 0x8CFC, - 0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, - 0x964D, 0x0000, 0x9805, 0x9999, 0x9AD8, 0x9D3B, - 0x525B, 0x52AB, 0x53F7, 0x5408, 0x58D5, 0x62F7, - 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B, - 0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, - 0x7344, 0x6F09, 0x8170, 0x7511, 0x5FFD, 0x60DA, - 0x9AA8, 0x72DB, 0x8FBC, 0x6B64, 0x9803, 0x4ECA, - 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068, 0x61C7, - 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, - 0x7D3A, 0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, - 0x5506, 0x5D6F, 0x5DE6, 0x5DEE, 0x67FB, 0x6C99, - 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF, 0x5750, - 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, - 0x54C9, 0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, - 0x63A1, 0x683D, 0x6B73, 0x6E08, 0x707D, 0x91C7, - 0x7280, 0x7815, 0x7826, 0x796D, 0x658E, 0x7D30, - 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, - 0x6750, 0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, - 0x583A, 0x698A, 0x80B4, 0x54B2, 0x5D0E, 0x57FC, - 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B, 0x643E, - 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, - 0x932F, 0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, - 0x5237, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis8E[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5BDF, 0x62F6, - 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1, - 0x7690, 0x9BD6, 0x634C, 0x9306, 0x9BAB, 0x76BF, - 0x6652, 0x4E09, 0x5098, 0x53C2, 0x5C71, 0x60E8, - 0x6492, 0x6563, 0x685F, 0x71E6, 0x73CA, 0x7523, - 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178, - 0x9910, 0x65AC, 0x66AB, 0x6B8B, 0x4ED5, 0x4ED4, - 0x4F3A, 0x4F7F, 0x523A, 0x53F8, 0x53F2, 0x55E3, - 0x56DB, 0x58EB, 0x59CB, 0x59C9, 0x59FF, 0x5B50, - 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307, - 0x652F, 0x5B5C, 0x65AF, 0x65BD, 0x65E8, 0x679D, - 0x6B62, 0x0000, 0x6B7B, 0x6C0F, 0x7345, 0x7949, - 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2, 0x8102, - 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, - 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC, 0x98FC, 0x6B6F, - 0x4E8B, 0x4F3C, 0x4F8D, 0x5150, 0x5B57, 0x5BFA, - 0x6148, 0x6301, 0x6642, 0x6B21, 0x6ECB, 0x6CBB, - 0x723E, 0x74BD, 0x75D4, 0x78C1, 0x793A, 0x800C, - 0x8033, 0x81EA, 0x8494, 0x8F9E, 0x6C50, 0x9E7F, - 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, - 0x96EB, 0x4E03, 0x53F1, 0x57F7, 0x5931, 0x5AC9, - 0x5BA4, 0x6089, 0x6E7F, 0x6F06, 0x75BE, 0x8CEA, - 0x5B9F, 0x8500, 0x7BE0, 0x5072, 0x67F4, 0x829D, - 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, - 0x6368, 0x8D66, 0x659C, 0x716E, 0x793E, 0x7D17, - 0x8005, 0x8B1D, 0x8ECA, 0x906E, 0x86C7, 0x90AA, - 0x501F, 0x52FA, 0x5C3A, 0x6753, 0x707C, 0x7235, - 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, - 0x60F9, 0x4E3B, 0x53D6, 0x5B88, 0x624B, 0x6731, - 0x6B8A, 0x72E9, 0x73E0, 0x7A2E, 0x816B, 0x8DA3, - 0x9152, 0x9996, 0x5112, 0x53D7, 0x546A, 0x5BFF, - 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, - 0x5468, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis8F[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5B97, 0x5C31, - 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32, 0x79C0, - 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, - 0x8490, 0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, - 0x9031, 0x914B, 0x916C, 0x96C6, 0x919C, 0x4EC0, - 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E, 0x67D4, - 0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, - 0x53D4, 0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, - 0x7C9B, 0x587E, 0x719F, 0x51FA, 0x8853, 0x8FF0, - 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3, 0x821C, - 0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, - 0x6DF3, 0x0000, 0x6E96, 0x6F64, 0x76FE, 0x7D14, - 0x5DE1, 0x9075, 0x9187, 0x9806, 0x51E6, 0x521D, - 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2, - 0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, - 0x53D9, 0x5973, 0x5E8F, 0x5F90, 0x6055, 0x92E4, - 0x9664, 0x50B7, 0x511F, 0x52DD, 0x5320, 0x5347, - 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617, 0x5968, - 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, - 0x5C1A, 0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, - 0x6284, 0x62DB, 0x638C, 0x6377, 0x6607, 0x660C, - 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F, 0x6A35, - 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, - 0x7167, 0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, - 0x79F0, 0x7AE0, 0x7B11, 0x7CA7, 0x7D39, 0x8096, - 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3, 0x8A1F, - 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, - 0x9266, 0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, - 0x4E08, 0x4E1E, 0x4E57, 0x5197, 0x5270, 0x57CE, - 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5, 0x64FE, - 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, - 0x84B8, 0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, - 0x98FE, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis90[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x62ED, 0x690D, - 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6, - 0x98DF, 0x8755, 0x8FB1, 0x5C3B, 0x4F38, 0x4FE1, - 0x4FB5, 0x5507, 0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, - 0x614E, 0x632F, 0x65B0, 0x664B, 0x68EE, 0x699B, - 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E, - 0x79E6, 0x7D33, 0x81E3, 0x82AF, 0x85AA, 0x89AA, - 0x8A3A, 0x8EAB, 0x8F9B, 0x9032, 0x91DD, 0x9707, - 0x4EBA, 0x4EC1, 0x5203, 0x5875, 0x58EC, 0x5C0B, - 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663, - 0x976D, 0x7B25, 0x8ACF, 0x9808, 0x9162, 0x56F3, - 0x53A8, 0x0000, 0x9017, 0x5439, 0x5782, 0x5E25, - 0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B, 0x7FE0, - 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F, - 0x745E, 0x9AC4, 0x5D07, 0x5D69, 0x6570, 0x67A2, - 0x8DA8, 0x96DB, 0x636E, 0x6749, 0x6919, 0x83C5, - 0x9817, 0x96C0, 0x88FE, 0x6F84, 0x647A, 0x5BF8, - 0x4E16, 0x702C, 0x755D, 0x662F, 0x51C4, 0x5236, - 0x52E2, 0x59D3, 0x5F81, 0x6027, 0x6210, 0x653F, - 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, - 0x6E05, 0x7272, 0x751F, 0x76DB, 0x7CBE, 0x8056, - 0x58F0, 0x88FD, 0x897F, 0x8AA0, 0x8A93, 0x8ACB, - 0x901D, 0x9192, 0x9752, 0x9759, 0x6589, 0x7A0E, - 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, - 0x6614, 0x6790, 0x77F3, 0x7A4D, 0x7C4D, 0x7E3E, - 0x810A, 0x8CAC, 0x8D64, 0x8DE1, 0x8E5F, 0x78A9, - 0x5207, 0x62D9, 0x63A5, 0x6442, 0x6298, 0x8A2D, - 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, - 0x8749, 0x4ED9, 0x5148, 0x5343, 0x5360, 0x5BA3, - 0x5C02, 0x5C16, 0x5DDD, 0x6226, 0x6247, 0x64B0, - 0x6813, 0x6834, 0x6CC9, 0x6D45, 0x6D17, 0x67D3, - 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, - 0x7DDA, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis91[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x7E4A, 0x7FA8, - 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E, 0x8CCE, - 0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, - 0x9BAE, 0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, - 0x7985, 0x7E55, 0x81B3, 0x7CCE, 0x564C, 0x5851, - 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A, 0x72D9, - 0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, - 0x7D20, 0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, - 0x9F20, 0x50E7, 0x5275, 0x53CC, 0x53E2, 0x5009, - 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B, 0x5C64, - 0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, - 0x63BB, 0x0000, 0x64CD, 0x65E9, 0x66F9, 0x5DE3, - 0x69CD, 0x69FD, 0x6F15, 0x71E5, 0x4E89, 0x75E9, - 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061, - 0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, - 0x8D70, 0x9001, 0x906D, 0x9397, 0x971C, 0x9A12, - 0x50CF, 0x5897, 0x618E, 0x81D3, 0x8535, 0x8D08, - 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373, 0x606F, - 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, - 0x5C5E, 0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, - 0x5176, 0x63C3, 0x5B58, 0x5B6B, 0x5C0A, 0x640D, - 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A, 0x6C70, - 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, - 0x67C1, 0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, - 0x4F53, 0x5806, 0x5BFE, 0x8010, 0x5CB1, 0x5E2F, - 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF, 0x6CF0, - 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, - 0x9000, 0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, - 0x53F0, 0x5927, 0x7B2C, 0x918D, 0x984C, 0x9DF9, - 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85, 0x6258, - 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, - 0x9438, 0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, - 0x53EA, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis92[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x53E9, 0x4F46, - 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA, - 0x8FBF, 0x68DA, 0x8C37, 0x72F8, 0x9C48, 0x6A3D, - 0x8AB0, 0x4E39, 0x5358, 0x5606, 0x5766, 0x62C5, - 0x63A2, 0x65E6, 0x6B4E, 0x6DE1, 0x6E5B, 0x70AD, - 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6, - 0x86CB, 0x8A95, 0x935B, 0x56E3, 0x58C7, 0x5F3E, - 0x65AD, 0x6696, 0x6A80, 0x6BB5, 0x7537, 0x8AC7, - 0x5024, 0x77E5, 0x5730, 0x5F1B, 0x6065, 0x667A, - 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718, - 0x9045, 0x99B3, 0x7BC9, 0x755C, 0x7AF9, 0x7B51, - 0x84C4, 0x0000, 0x9010, 0x79E9, 0x7A92, 0x8336, - 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99, 0x5FE0, - 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877, - 0x8A3B, 0x914E, 0x92F3, 0x99D0, 0x6A17, 0x7026, - 0x732A, 0x82E7, 0x8457, 0x8CAF, 0x4E01, 0x5146, - 0x51CB, 0x558B, 0x5BF5, 0x5E16, 0x5E33, 0x5E81, - 0x5F14, 0x5F35, 0x5F6B, 0x5FB4, 0x61F2, 0x6311, - 0x66A2, 0x671D, 0x6F6E, 0x7252, 0x753A, 0x773A, - 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, - 0x8D85, 0x8DF3, 0x929A, 0x9577, 0x9802, 0x9CE5, - 0x52C5, 0x6357, 0x76F4, 0x6715, 0x6C88, 0x73CD, - 0x8CC3, 0x93AE, 0x9673, 0x6D25, 0x589C, 0x690E, - 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, - 0x6802, 0x63B4, 0x69FB, 0x4F43, 0x6F2C, 0x67D8, - 0x8FBB, 0x8526, 0x7DB4, 0x9354, 0x693F, 0x6F70, - 0x576A, 0x58F7, 0x5B2C, 0x7D2C, 0x722A, 0x540A, - 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, - 0x5243, 0x8C9E, 0x5448, 0x5824, 0x5B9A, 0x5E1D, - 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F, 0x608C, 0x62B5, - 0x633A, 0x63D0, 0x68AF, 0x6C40, 0x7887, 0x798E, - 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, - 0x9013, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis93[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x90B8, 0x912D, - 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2, 0x6575, - 0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, - 0x54F2, 0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, - 0x5178, 0x586B, 0x5929, 0x5C55, 0x5E97, 0x6DFB, - 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B, 0x70B9, - 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, - 0x5410, 0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, - 0x6597, 0x675C, 0x6E21, 0x767B, 0x83DF, 0x8CED, - 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A, 0x52AA, - 0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, - 0x51AC, 0x0000, 0x51CD, 0x5200, 0x5510, 0x5854, - 0x5858, 0x5957, 0x5B95, 0x5CF6, 0x5D8B, 0x60BC, - 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF, - 0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, - 0x5F53, 0x75D8, 0x7977, 0x7B49, 0x7B54, 0x7B52, - 0x7CD6, 0x7D71, 0x5230, 0x8463, 0x8569, 0x85E4, - 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003, 0x900F, - 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, - 0x52D5, 0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, - 0x6D1E, 0x77B3, 0x7AE5, 0x80F4, 0x8404, 0x9053, - 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97, 0x5FB3, - 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, - 0x72EC, 0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, - 0x6934, 0x5C4A, 0x9CF6, 0x82EB, 0x5BC5, 0x9149, - 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566, 0x6C8C, - 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, - 0x5948, 0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, - 0x8B0E, 0x7058, 0x637A, 0x934B, 0x6962, 0x99B4, - 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF, 0x96E3, - 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, - 0x8CD1, 0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, - 0x5165, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis94[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5982, 0x5C3F, - 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1, - 0x79B0, 0x7962, 0x5BE7, 0x8471, 0x732B, 0x71B1, - 0x5E74, 0x5FF5, 0x637B, 0x649A, 0x71C3, 0x7C98, - 0x4E43, 0x5EFC, 0x4E4B, 0x57DC, 0x56A2, 0x60A9, - 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2, - 0x8997, 0x86A4, 0x5DF4, 0x628A, 0x64AD, 0x8987, - 0x6777, 0x6CE2, 0x6D3E, 0x7436, 0x7834, 0x5A46, - 0x7F75, 0x82AD, 0x99AC, 0x4FF3, 0x5EC3, 0x62DD, - 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC, - 0x80BA, 0x8F29, 0x914D, 0x500D, 0x57F9, 0x5A92, - 0x6885, 0x0000, 0x6973, 0x7164, 0x72FD, 0x8CB7, - 0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F, 0x79E4, - 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD, - 0x67CF, 0x6CCA, 0x767D, 0x7B94, 0x7C95, 0x8236, - 0x8584, 0x8FEB, 0x66DD, 0x6F20, 0x7206, 0x7E1B, - 0x83AB, 0x99C1, 0x9EA6, 0x51FD, 0x7BB1, 0x7872, - 0x7BB8, 0x8087, 0x7B48, 0x6AE8, 0x5E61, 0x808C, - 0x7551, 0x7560, 0x516B, 0x9262, 0x6E8C, 0x767A, - 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, - 0x95A5, 0x9CE9, 0x567A, 0x5859, 0x86E4, 0x96BC, - 0x4F34, 0x5224, 0x534A, 0x53CD, 0x53DB, 0x5E06, - 0x642C, 0x6591, 0x677F, 0x6C3E, 0x6C4E, 0x7248, - 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, - 0x8CA9, 0x7BC4, 0x91C6, 0x7169, 0x9812, 0x98EF, - 0x633D, 0x6669, 0x756A, 0x76E4, 0x78D0, 0x8543, - 0x86EE, 0x532A, 0x5351, 0x5426, 0x5983, 0x5E87, - 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, - 0x6BD4, 0x6CCC, 0x75B2, 0x76AE, 0x7891, 0x79D8, - 0x7DCB, 0x7F77, 0x80A5, 0x88AB, 0x8AB9, 0x8CBB, - 0x907F, 0x975E, 0x98DB, 0x6A0B, 0x7C38, 0x5099, - 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, - 0x7F8E, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis95[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9F3B, 0x67CA, - 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66, 0x819D, - 0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, - 0x903C, 0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, - 0x8B2C, 0x4FF5, 0x5F6A, 0x6A19, 0x6C37, 0x6F02, - 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79, 0x5EDF, - 0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, - 0x849C, 0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, - 0x6D5C, 0x7015, 0x8CA7, 0x8CD3, 0x983B, 0x654F, - 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B, 0x5A66, - 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, - 0x6577, 0x0000, 0x65A7, 0x666E, 0x6D6E, 0x7236, - 0x7B26, 0x8150, 0x819A, 0x8299, 0x8B5C, 0x8CA0, - 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB, - 0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, - 0x6953, 0x98A8, 0x847A, 0x8557, 0x4F0F, 0x526F, - 0x5FA9, 0x5E45, 0x670D, 0x798F, 0x8179, 0x8907, - 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8, 0x4ECF, - 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, - 0x61A4, 0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, - 0x7D1B, 0x96F0, 0x6587, 0x805E, 0x4E19, 0x4F75, - 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A, 0x67C4, - 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, - 0x50FB, 0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, - 0x8511, 0x7B86, 0x504F, 0x5909, 0x7247, 0x7BC7, - 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF, 0x52C9, - 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, - 0x5703, 0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, - 0x7A42, 0x52DF, 0x5893, 0x6155, 0x620A, 0x66AE, - 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8, 0x5305, - 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, - 0x5D29, 0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, - 0x670B, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis96[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6CD5, 0x6CE1, - 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C, - 0x84EC, 0x8702, 0x8912, 0x8A2A, 0x8C4A, 0x90A6, - 0x92D2, 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, - 0x508D, 0x5256, 0x574A, 0x59A8, 0x5E3D, 0x5FD8, - 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2, - 0x5192, 0x7D21, 0x80AA, 0x81A8, 0x8B00, 0x8C8C, - 0x8CBF, 0x927E, 0x9632, 0x5420, 0x982C, 0x5317, - 0x50D5, 0x535C, 0x58A8, 0x64B2, 0x6734, 0x7267, - 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86, - 0x5800, 0x5E4C, 0x5954, 0x672C, 0x7FFB, 0x51E1, - 0x76C6, 0x0000, 0x6469, 0x78E8, 0x9B54, 0x9EBB, - 0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE, 0x54E9, - 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE, - 0x9C52, 0x685D, 0x4EA6, 0x4FE3, 0x53C8, 0x62B9, - 0x672B, 0x6CAB, 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF, - 0x4E07, 0x6162, 0x6E80, 0x6F2B, 0x8513, 0x5473, - 0x672A, 0x9B45, 0x5DF3, 0x7B95, 0x5CAC, 0x5BC6, - 0x871C, 0x6E4A, 0x84D1, 0x7A14, 0x8108, 0x5999, - 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, - 0x725F, 0x77DB, 0x9727, 0x9D61, 0x690B, 0x5A7F, - 0x5A18, 0x51A5, 0x540D, 0x547D, 0x660E, 0x76DF, - 0x8FF7, 0x9298, 0x9CF4, 0x59EA, 0x725D, 0x6EC5, - 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, - 0x6478, 0x6A21, 0x8302, 0x5984, 0x5B5F, 0x6BDB, - 0x731B, 0x76F2, 0x7DB2, 0x8017, 0x8499, 0x5132, - 0x6728, 0x9ED9, 0x76EE, 0x6762, 0x52FF, 0x9905, - 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, - 0x7D0B, 0x9580, 0x5301, 0x4E5F, 0x51B6, 0x591C, - 0x723A, 0x8036, 0x91CE, 0x5F25, 0x77E2, 0x5384, - 0x5F79, 0x7D04, 0x85AC, 0x8A33, 0x8E8D, 0x9756, - 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, - 0x7652, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis97[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8AED, 0x8F38, - 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB, 0x5BA5, - 0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, - 0x6E67, 0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, - 0x88D5, 0x8A98, 0x904A, 0x9091, 0x90F5, 0x96C4, - 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E, 0x8A89, - 0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, - 0x5EB8, 0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, - 0x69D8, 0x6D0B, 0x6EB6, 0x7194, 0x7528, 0x7AAF, - 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981, 0x8B21, - 0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, - 0x6B32, 0x0000, 0x6C83, 0x6D74, 0x7FCC, 0x7FFC, - 0x6DC0, 0x7F85, 0x87BA, 0x88F8, 0x6765, 0x83B1, - 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A, - 0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, - 0x862D, 0x89A7, 0x5229, 0x540F, 0x5C65, 0x674E, - 0x68A8, 0x7406, 0x7483, 0x75E2, 0x88CF, 0x88E1, - 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387, 0x7ACB, - 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, - 0x7409, 0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, - 0x9F8D, 0x4FB6, 0x616E, 0x65C5, 0x865C, 0x4E86, - 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE, 0x6599, - 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, - 0x7CE7, 0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, - 0x9818, 0x529B, 0x7DD1, 0x502B, 0x5398, 0x6797, - 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A, 0x96A3, - 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, - 0x985E, 0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, - 0x5DBA, 0x601C, 0x73B2, 0x793C, 0x82D3, 0x9234, - 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62, 0x66A6, - 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, - 0x604B, 0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, - 0x806F, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis98[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x84EE, 0x9023, - 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2, - 0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, - 0x6717, 0x697C, 0x6994, 0x6D6A, 0x6F0F, 0x7262, - 0x72FC, 0x7BED, 0x8001, 0x807E, 0x874B, 0x90CE, - 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6, - 0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, - 0x60D1, 0x67A0, 0x9DF2, 0x4E99, 0x4E98, 0x9C10, - 0x8A6B, 0x85C1, 0x8568, 0x6900, 0x6E7E, 0x7897, - 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x5F0C, 0x4E10, 0x4E15, - 0x4E2A, 0x4E31, 0x4E36, 0x4E3C, 0x4E3F, 0x4E42, - 0x4E56, 0x4E58, 0x4E82, 0x4E85, 0x8C6B, 0x4E8A, - 0x8212, 0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, - 0x4EA2, 0x4EB0, 0x4EB3, 0x4EB6, 0x4ECE, 0x4ECD, - 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7, 0x4EDE, 0x4EED, - 0x4EDF, 0x4EF7, 0x4F09, 0x4F5A, 0x4F30, 0x4F5B, - 0x4F5D, 0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, - 0x4F98, 0x4F7B, 0x4F69, 0x4F70, 0x4F91, 0x4F6F, - 0x4F86, 0x4F96, 0x5118, 0x4FD4, 0x4FDF, 0x4FCE, - 0x4FD8, 0x4FDB, 0x4FD1, 0x4FDA, 0x4FD0, 0x4FE4, - 0x4FE5, 0x501A, 0x5028, 0x5014, 0x502A, 0x5025, - 0x5005, 0x4F1C, 0x4FF6, 0x5021, 0x5029, 0x502C, - 0x4FFE, 0x4FEF, 0x5011, 0x5006, 0x5043, 0x5047, - 0x6703, 0x5055, 0x5050, 0x5048, 0x505A, 0x5056, - 0x506C, 0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, - 0x50B2, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis99[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x50C9, 0x50CA, - 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5, 0x50ED, - 0x50E3, 0x50EE, 0x50F9, 0x50F5, 0x5109, 0x5101, - 0x5102, 0x5116, 0x5115, 0x5114, 0x511A, 0x5121, - 0x513A, 0x5137, 0x513C, 0x513B, 0x513F, 0x5140, - 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8, 0x5169, - 0x516A, 0x516E, 0x5180, 0x5182, 0x56D8, 0x518C, - 0x5189, 0x518F, 0x5191, 0x5193, 0x5195, 0x5196, - 0x51A4, 0x51A6, 0x51A2, 0x51A9, 0x51AA, 0x51AB, - 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5, 0x51BD, - 0x51C5, 0x51C9, 0x51DB, 0x51E0, 0x8655, 0x51E9, - 0x51ED, 0x0000, 0x51F0, 0x51F5, 0x51FE, 0x5204, - 0x520B, 0x5214, 0x520E, 0x5227, 0x522A, 0x522E, - 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C, - 0x525E, 0x5254, 0x526A, 0x5274, 0x5269, 0x5273, - 0x527F, 0x527D, 0x528D, 0x5294, 0x5292, 0x5271, - 0x5288, 0x5291, 0x8FA8, 0x8FA7, 0x52AC, 0x52AD, - 0x52BC, 0x52B5, 0x52C1, 0x52CD, 0x52D7, 0x52DE, - 0x52E3, 0x52E6, 0x98ED, 0x52E0, 0x52F3, 0x52F5, - 0x52F8, 0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, - 0x5310, 0x530F, 0x5315, 0x531A, 0x5323, 0x532F, - 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, 0x5345, - 0x4E17, 0x5349, 0x534D, 0x51D6, 0x535E, 0x5369, - 0x536E, 0x5918, 0x537B, 0x5377, 0x5382, 0x5396, - 0x53A0, 0x53A6, 0x53A5, 0x53AE, 0x53B0, 0x53B6, - 0x53C3, 0x7C12, 0x96D9, 0x53DF, 0x66FC, 0x71EE, - 0x53EE, 0x53E8, 0x53ED, 0x53FA, 0x5401, 0x543D, - 0x5440, 0x542C, 0x542D, 0x543C, 0x542E, 0x5436, - 0x5429, 0x541D, 0x544E, 0x548F, 0x5475, 0x548E, - 0x545F, 0x5471, 0x5477, 0x5470, 0x5492, 0x547B, - 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54C7, - 0x54A2, 0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, - 0x54A8, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis9A[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x54AB, 0x54C2, - 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5, 0x54E6, - 0x550F, 0x5514, 0x54FD, 0x54EE, 0x54ED, 0x54FA, - 0x54E2, 0x5539, 0x5540, 0x5563, 0x554C, 0x552E, - 0x555C, 0x5545, 0x5556, 0x5557, 0x5538, 0x5533, - 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A, 0x559F, - 0x557B, 0x557E, 0x5598, 0x559E, 0x55AE, 0x557C, - 0x5583, 0x55A9, 0x5587, 0x55A8, 0x55DA, 0x55C5, - 0x55DF, 0x55C4, 0x55DC, 0x55E4, 0x55D4, 0x5614, - 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B, 0x55F9, - 0x564E, 0x5650, 0x71DF, 0x5634, 0x5636, 0x5632, - 0x5638, 0x0000, 0x566B, 0x5664, 0x562F, 0x566C, - 0x566A, 0x5686, 0x5680, 0x568A, 0x56A0, 0x5694, - 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2, - 0x56BC, 0x56C1, 0x56C3, 0x56C0, 0x56C8, 0x56CE, - 0x56D1, 0x56D3, 0x56D7, 0x56EE, 0x56F9, 0x5700, - 0x56FF, 0x5704, 0x5709, 0x5708, 0x570B, 0x570D, - 0x5713, 0x5718, 0x5716, 0x55C7, 0x571C, 0x5726, - 0x5737, 0x5738, 0x574E, 0x573B, 0x5740, 0x574F, - 0x5769, 0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, - 0x5793, 0x57A0, 0x57B3, 0x57A4, 0x57AA, 0x57B0, - 0x57C3, 0x57C6, 0x57D4, 0x57D2, 0x57D3, 0x580A, - 0x57D6, 0x57E3, 0x580B, 0x5819, 0x581D, 0x5872, - 0x5821, 0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, - 0x583D, 0x5879, 0x5885, 0x58B9, 0x589F, 0x58AB, - 0x58BA, 0x58DE, 0x58BB, 0x58B8, 0x58AE, 0x58C5, - 0x58D3, 0x58D1, 0x58D7, 0x58D9, 0x58D8, 0x58E5, - 0x58DC, 0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, - 0x58FB, 0x58FC, 0x58FD, 0x5902, 0x590A, 0x5910, - 0x591B, 0x68A6, 0x5925, 0x592C, 0x592D, 0x5932, - 0x5938, 0x593E, 0x7AD2, 0x5955, 0x5950, 0x594E, - 0x595A, 0x5958, 0x5962, 0x5960, 0x5967, 0x596C, - 0x5969, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis9B[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5978, 0x5981, - 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2, 0x59C6, - 0x59E8, 0x59DC, 0x598D, 0x59D9, 0x59DA, 0x5A25, - 0x5A1F, 0x5A11, 0x5A1C, 0x5A09, 0x5A1A, 0x5A40, - 0x5A6C, 0x5A49, 0x5A35, 0x5A36, 0x5A62, 0x5A6A, - 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2, 0x5ABD, - 0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, 0x5AD6, 0x5AFA, - 0x5AFB, 0x5B0C, 0x5B0B, 0x5B16, 0x5B32, 0x5AD0, - 0x5B2A, 0x5B36, 0x5B3E, 0x5B43, 0x5B45, 0x5B40, - 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65, 0x5B69, - 0x5B70, 0x5B73, 0x5B75, 0x5B78, 0x6588, 0x5B7A, - 0x5B80, 0x0000, 0x5B83, 0x5BA6, 0x5BB8, 0x5BC3, - 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0, 0x5BE4, 0x5BE6, - 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6, - 0x5BF3, 0x5C05, 0x5C07, 0x5C08, 0x5C0D, 0x5C13, - 0x5C20, 0x5C22, 0x5C28, 0x5C38, 0x5C39, 0x5C41, - 0x5C46, 0x5C4E, 0x5C53, 0x5C50, 0x5C4F, 0x5B71, - 0x5C6C, 0x5C6E, 0x4E62, 0x5C76, 0x5C79, 0x5C8C, - 0x5C91, 0x5C94, 0x599B, 0x5CAB, 0x5CBB, 0x5CB6, - 0x5CBC, 0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, - 0x5CE9, 0x5CFD, 0x5CFA, 0x5CED, 0x5D8C, 0x5CEA, - 0x5D0B, 0x5D15, 0x5D17, 0x5D5C, 0x5D1F, 0x5D1B, - 0x5D11, 0x5D14, 0x5D22, 0x5D1A, 0x5D19, 0x5D18, - 0x5D4C, 0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, - 0x5D76, 0x5D87, 0x5D84, 0x5D82, 0x5DA2, 0x5D9D, - 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90, 0x5DB7, 0x5DBC, - 0x5DC9, 0x5DCD, 0x5DD3, 0x5DD2, 0x5DD6, 0x5DDB, - 0x5DEB, 0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, - 0x5E11, 0x5E1B, 0x5E36, 0x5E37, 0x5E44, 0x5E43, - 0x5E40, 0x5E4E, 0x5E57, 0x5E54, 0x5E5F, 0x5E62, - 0x5E64, 0x5E47, 0x5E75, 0x5E76, 0x5E7A, 0x9EBC, - 0x5E7F, 0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, - 0x5ECF, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis9C[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x5ED6, 0x5EE3, - 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1, 0x5EE8, - 0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, 0x5EF0, 0x5EF4, - 0x5EF8, 0x5EFE, 0x5F03, 0x5F09, 0x5F5D, 0x5F5C, - 0x5F0B, 0x5F11, 0x5F16, 0x5F29, 0x5F2D, 0x5F38, - 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F, 0x5F51, - 0x5F56, 0x5F57, 0x5F59, 0x5F61, 0x5F6D, 0x5F73, - 0x5F77, 0x5F83, 0x5F82, 0x5F7F, 0x5F8A, 0x5F88, - 0x5F91, 0x5F87, 0x5F9E, 0x5F99, 0x5F98, 0x5FA0, - 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB, 0x5FE4, - 0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, 0x5FFF, 0x6021, - 0x6060, 0x0000, 0x6019, 0x6010, 0x6029, 0x600E, - 0x6031, 0x601B, 0x6015, 0x602B, 0x6026, 0x600F, - 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F, - 0x604A, 0x6046, 0x604D, 0x6063, 0x6043, 0x6064, - 0x6042, 0x606C, 0x606B, 0x6059, 0x6081, 0x608D, - 0x60E7, 0x6083, 0x609A, 0x6084, 0x609B, 0x6096, - 0x6097, 0x6092, 0x60A7, 0x608B, 0x60E1, 0x60B8, - 0x60E0, 0x60D3, 0x60B4, 0x5FF0, 0x60BD, 0x60C6, - 0x60B5, 0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, - 0x60F7, 0x6100, 0x60F4, 0x60FA, 0x6103, 0x6121, - 0x60FB, 0x60F1, 0x610D, 0x610E, 0x6147, 0x613E, - 0x6128, 0x6127, 0x614A, 0x613F, 0x613C, 0x612C, - 0x6134, 0x613D, 0x6142, 0x6144, 0x6173, 0x6177, - 0x6158, 0x6159, 0x615A, 0x616B, 0x6174, 0x616F, - 0x6165, 0x6171, 0x615F, 0x615D, 0x6153, 0x6175, - 0x6199, 0x6196, 0x6187, 0x61AC, 0x6194, 0x619A, - 0x618A, 0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, - 0x61C9, 0x61F7, 0x61C8, 0x61C3, 0x61C6, 0x61BA, - 0x61CB, 0x7F79, 0x61CD, 0x61E6, 0x61E3, 0x61F6, - 0x61FA, 0x61F4, 0x61FF, 0x61FD, 0x61FC, 0x61FE, - 0x6200, 0x6208, 0x6209, 0x620D, 0x620C, 0x6214, - 0x621B, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis9D[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x621E, 0x6221, - 0x622A, 0x622E, 0x6230, 0x6232, 0x6233, 0x6241, - 0x624E, 0x625E, 0x6263, 0x625B, 0x6260, 0x6268, - 0x627C, 0x6282, 0x6289, 0x627E, 0x6292, 0x6293, - 0x6296, 0x62D4, 0x6283, 0x6294, 0x62D7, 0x62D1, - 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4, 0x62C8, - 0x62DC, 0x62CC, 0x62CA, 0x62C2, 0x62C7, 0x629B, - 0x62C9, 0x630C, 0x62EE, 0x62F1, 0x6327, 0x6302, - 0x6308, 0x62EF, 0x62F5, 0x6350, 0x633E, 0x634D, - 0x641C, 0x634F, 0x6396, 0x638E, 0x6380, 0x63AB, - 0x6376, 0x63A3, 0x638F, 0x6389, 0x639F, 0x63B5, - 0x636B, 0x0000, 0x6369, 0x63BE, 0x63E9, 0x63C0, - 0x63C6, 0x63E3, 0x63C9, 0x63D2, 0x63F6, 0x63C4, - 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, - 0x651D, 0x6417, 0x6428, 0x640F, 0x6467, 0x646F, - 0x6476, 0x644E, 0x652A, 0x6495, 0x6493, 0x64A5, - 0x64A9, 0x6488, 0x64BC, 0x64DA, 0x64D2, 0x64C5, - 0x64C7, 0x64BB, 0x64D8, 0x64C2, 0x64F1, 0x64E7, - 0x8209, 0x64E0, 0x64E1, 0x62AC, 0x64E3, 0x64EF, - 0x652C, 0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, - 0x64FD, 0x6518, 0x651C, 0x6505, 0x6524, 0x6523, - 0x652B, 0x6534, 0x6535, 0x6537, 0x6536, 0x6538, - 0x754B, 0x6548, 0x6556, 0x6555, 0x654D, 0x6558, - 0x655E, 0x655D, 0x6572, 0x6578, 0x6582, 0x6583, - 0x8B8A, 0x659B, 0x659F, 0x65AB, 0x65B7, 0x65C3, - 0x65C6, 0x65C1, 0x65C4, 0x65CC, 0x65D2, 0x65DB, - 0x65D9, 0x65E0, 0x65E1, 0x65F1, 0x6772, 0x660A, - 0x6603, 0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, - 0x661C, 0x664F, 0x6644, 0x6649, 0x6641, 0x665E, - 0x665D, 0x6664, 0x6667, 0x6668, 0x665F, 0x6662, - 0x6670, 0x6683, 0x6688, 0x668E, 0x6689, 0x6684, - 0x6698, 0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, - 0x66BC, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis9E[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x66C4, 0x66B8, - 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6, 0x66E9, - 0x66F0, 0x66F5, 0x66F7, 0x670F, 0x6716, 0x671E, - 0x6726, 0x6727, 0x9738, 0x672E, 0x673F, 0x6736, - 0x6741, 0x6738, 0x6737, 0x6746, 0x675E, 0x6760, - 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67A9, - 0x677C, 0x676A, 0x678C, 0x678B, 0x67A6, 0x67A1, - 0x6785, 0x67B7, 0x67EF, 0x67B4, 0x67EC, 0x67B3, - 0x67E9, 0x67B8, 0x67E4, 0x67DE, 0x67DD, 0x67E2, - 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7, 0x6A9C, - 0x681E, 0x6846, 0x6829, 0x6840, 0x684D, 0x6832, - 0x684E, 0x0000, 0x68B3, 0x682B, 0x6859, 0x6863, - 0x6877, 0x687F, 0x689F, 0x688F, 0x68AD, 0x6894, - 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874, - 0x68B5, 0x68A0, 0x68BA, 0x690F, 0x688D, 0x687E, - 0x6901, 0x68CA, 0x6908, 0x68D8, 0x6922, 0x6926, - 0x68E1, 0x690C, 0x68CD, 0x68D4, 0x68E7, 0x68D5, - 0x6936, 0x6912, 0x6904, 0x68D7, 0x68E3, 0x6925, - 0x68F9, 0x68E0, 0x68EF, 0x6928, 0x692A, 0x691A, - 0x6923, 0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, - 0x6978, 0x696B, 0x6954, 0x697E, 0x696E, 0x6939, - 0x6974, 0x693D, 0x6959, 0x6930, 0x6961, 0x695E, - 0x695D, 0x6981, 0x696A, 0x69B2, 0x69AE, 0x69D0, - 0x69BF, 0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, - 0x69CA, 0x69DD, 0x69BB, 0x69C3, 0x69A7, 0x6A2E, - 0x6991, 0x69A0, 0x699C, 0x6995, 0x69B4, 0x69DE, - 0x69E8, 0x6A02, 0x6A1B, 0x69FF, 0x6B0A, 0x69F9, - 0x69F2, 0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, - 0x6A14, 0x69EB, 0x6A0A, 0x6A12, 0x6AC1, 0x6A23, - 0x6A13, 0x6A44, 0x6A0C, 0x6A72, 0x6A36, 0x6A78, - 0x6A47, 0x6A62, 0x6A59, 0x6A66, 0x6A48, 0x6A38, - 0x6A22, 0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, - 0x6AA3, 0x0000, 0x0000, 0x0000 -}; - -static u16 Sjis9F[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6A97, 0x8617, - 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3, 0x6AAC, - 0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, 0x6ADA, 0x6AEA, - 0x6AFB, 0x6B05, 0x8616, 0x6AFA, 0x6B12, 0x6B16, - 0x9B31, 0x6B1F, 0x6B38, 0x6B37, 0x76DC, 0x6B39, - 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50, 0x6B59, - 0x6B54, 0x6B5B, 0x6B5F, 0x6B61, 0x6B78, 0x6B79, - 0x6B7F, 0x6B80, 0x6B84, 0x6B83, 0x6B8D, 0x6B98, - 0x6B95, 0x6B9E, 0x6BA4, 0x6BAA, 0x6BAB, 0x6BAF, - 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC, 0x6BC6, - 0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, 0x6BEB, 0x6BF3, - 0x6BEF, 0x0000, 0x9EBE, 0x6C08, 0x6C13, 0x6C14, - 0x6C1B, 0x6C24, 0x6C23, 0x6C5E, 0x6C55, 0x6C62, - 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B, - 0x6C7E, 0x6C68, 0x6C73, 0x6C92, 0x6C90, 0x6CC4, - 0x6CF1, 0x6CD3, 0x6CBD, 0x6CD7, 0x6CC5, 0x6CDD, - 0x6CAE, 0x6CB1, 0x6CBE, 0x6CBA, 0x6CDB, 0x6CEF, - 0x6CD9, 0x6CEA, 0x6D1F, 0x884D, 0x6D36, 0x6D2B, - 0x6D3D, 0x6D38, 0x6D19, 0x6D35, 0x6D33, 0x6D12, - 0x6D0C, 0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, - 0x6D59, 0x6D8E, 0x6D95, 0x6FE4, 0x6D85, 0x6DF9, - 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7, 0x6DE6, 0x6DB8, - 0x6DC6, 0x6DEC, 0x6DDE, 0x6DCC, 0x6DE8, 0x6DD2, - 0x6DC5, 0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, - 0x6DEE, 0x6E2D, 0x6E6E, 0x6E2E, 0x6E19, 0x6E72, - 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B, 0x6E2B, 0x6E76, - 0x6E4D, 0x6E1F, 0x6E43, 0x6E3A, 0x6E4E, 0x6E24, - 0x6EFF, 0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, - 0x6EC9, 0x6EB7, 0x6ED3, 0x6EBD, 0x6EAF, 0x6EC4, - 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F, 0x6EA5, 0x6EC2, - 0x6E9F, 0x6F41, 0x6F11, 0x704C, 0x6EEC, 0x6EF8, - 0x6EFE, 0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, - 0x6ECC, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE0[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x6F3E, 0x6F13, - 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81, 0x6F80, - 0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, 0x6F82, 0x6F7C, - 0x6F58, 0x6F8E, 0x6F91, 0x6FC2, 0x6F66, 0x6FB3, - 0x6FA3, 0x6FA1, 0x6FA4, 0x6FB9, 0x6FC6, 0x6FAA, - 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8, 0x6FF1, - 0x6FEE, 0x6FDB, 0x7009, 0x700B, 0x6FFA, 0x7011, - 0x7001, 0x700F, 0x6FFE, 0x701B, 0x701A, 0x6F74, - 0x701D, 0x7018, 0x701F, 0x7030, 0x703E, 0x7032, - 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF, 0x70F1, - 0x70AC, 0x70B8, 0x70B3, 0x70AE, 0x70DF, 0x70CB, - 0x70DD, 0x0000, 0x70D9, 0x7109, 0x70FD, 0x711C, - 0x7119, 0x7165, 0x7155, 0x7188, 0x7166, 0x7162, - 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184, - 0x7195, 0x71A8, 0x71AC, 0x71D7, 0x71B9, 0x71BE, - 0x71D2, 0x71C9, 0x71D4, 0x71CE, 0x71E0, 0x71EC, - 0x71E7, 0x71F5, 0x71FC, 0x71F9, 0x71FF, 0x720D, - 0x7210, 0x721B, 0x7228, 0x722D, 0x722C, 0x7230, - 0x7232, 0x723B, 0x723C, 0x723F, 0x7240, 0x7246, - 0x724B, 0x7258, 0x7274, 0x727E, 0x7282, 0x7281, - 0x7287, 0x7292, 0x7296, 0x72A2, 0x72A7, 0x72B9, - 0x72B2, 0x72C3, 0x72C6, 0x72C4, 0x72CE, 0x72D2, - 0x72E2, 0x72E0, 0x72E1, 0x72F9, 0x72F7, 0x500F, - 0x7317, 0x730A, 0x731C, 0x7316, 0x731D, 0x7334, - 0x732F, 0x7329, 0x7325, 0x733E, 0x734E, 0x734F, - 0x9ED8, 0x7357, 0x736A, 0x7368, 0x7370, 0x7378, - 0x7375, 0x737B, 0x737A, 0x73C8, 0x73B3, 0x73CE, - 0x73BB, 0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, - 0x7405, 0x746F, 0x7425, 0x73F8, 0x7432, 0x743A, - 0x7455, 0x743F, 0x745F, 0x7459, 0x7441, 0x745C, - 0x7469, 0x7470, 0x7463, 0x746A, 0x7476, 0x747E, - 0x748B, 0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, - 0x73F1, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE1[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x74E0, 0x74E3, - 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0, 0x74F1, - 0x74F8, 0x74F7, 0x7504, 0x7503, 0x7505, 0x750C, - 0x750E, 0x750D, 0x7515, 0x7513, 0x751E, 0x7526, - 0x752C, 0x753C, 0x7544, 0x754D, 0x754A, 0x7549, - 0x755B, 0x7546, 0x755A, 0x7569, 0x7564, 0x7567, - 0x756B, 0x756D, 0x7578, 0x7576, 0x7586, 0x7587, - 0x7574, 0x758A, 0x7589, 0x7582, 0x7594, 0x759A, - 0x759D, 0x75A5, 0x75A3, 0x75C2, 0x75B3, 0x75C3, - 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1, 0x75CD, - 0x75CA, 0x75D2, 0x75D9, 0x75E3, 0x75DE, 0x75FE, - 0x75FF, 0x0000, 0x75FC, 0x7601, 0x75F0, 0x75FA, - 0x75F2, 0x75F3, 0x760B, 0x760D, 0x7609, 0x761F, - 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, - 0x7630, 0x763B, 0x7647, 0x7648, 0x7646, 0x765C, - 0x7658, 0x7661, 0x7662, 0x7668, 0x7669, 0x766A, - 0x7667, 0x766C, 0x7670, 0x7672, 0x7676, 0x7678, - 0x767C, 0x7680, 0x7683, 0x7688, 0x768B, 0x768E, - 0x7696, 0x7693, 0x7699, 0x769A, 0x76B0, 0x76B4, - 0x76B8, 0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, - 0x76D2, 0x76DE, 0x76E1, 0x76E5, 0x76E7, 0x76EA, - 0x862F, 0x76FB, 0x7708, 0x7707, 0x7704, 0x7729, - 0x7724, 0x771E, 0x7725, 0x7726, 0x771B, 0x7737, - 0x7738, 0x7747, 0x775A, 0x7768, 0x776B, 0x775B, - 0x7765, 0x777F, 0x777E, 0x7779, 0x778E, 0x778B, - 0x7791, 0x77A0, 0x779E, 0x77B0, 0x77B6, 0x77B9, - 0x77BF, 0x77BC, 0x77BD, 0x77BB, 0x77C7, 0x77CD, - 0x77D7, 0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, - 0x780C, 0x7812, 0x7926, 0x7820, 0x792A, 0x7845, - 0x788E, 0x7874, 0x7886, 0x787C, 0x789A, 0x788C, - 0x78A3, 0x78B5, 0x78AA, 0x78AF, 0x78D1, 0x78C6, - 0x78CB, 0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, - 0x78EC, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE2[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x78E7, 0x78DA, - 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911, 0x7919, - 0x792C, 0x792B, 0x7940, 0x7960, 0x7957, 0x795F, - 0x795A, 0x7955, 0x7953, 0x797A, 0x797F, 0x798A, - 0x799D, 0x79A7, 0x9F4B, 0x79AA, 0x79AE, 0x79B3, - 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7, 0x79EC, - 0x79E1, 0x79E3, 0x7A08, 0x7A0D, 0x7A18, 0x7A19, - 0x7A20, 0x7A1F, 0x7980, 0x7A31, 0x7A3B, 0x7A3E, - 0x7A37, 0x7A43, 0x7A57, 0x7A49, 0x7A61, 0x7A62, - 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D, 0x7A88, - 0x7A97, 0x7A95, 0x7A98, 0x7A96, 0x7AA9, 0x7AC8, - 0x7AB0, 0x0000, 0x7AB6, 0x7AC5, 0x7AC4, 0x7ABF, - 0x9083, 0x7AC7, 0x7ACA, 0x7ACD, 0x7ACF, 0x7AD5, - 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2, - 0x7AE6, 0x7AED, 0x7AF0, 0x7B02, 0x7B0F, 0x7B0A, - 0x7B06, 0x7B33, 0x7B18, 0x7B19, 0x7B1E, 0x7B35, - 0x7B28, 0x7B36, 0x7B50, 0x7B7A, 0x7B04, 0x7B4D, - 0x7B0B, 0x7B4C, 0x7B45, 0x7B75, 0x7B65, 0x7B74, - 0x7B67, 0x7B70, 0x7B71, 0x7B6C, 0x7B6E, 0x7B9D, - 0x7B98, 0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, - 0x7B92, 0x7B8F, 0x7B5D, 0x7B99, 0x7BCB, 0x7BC1, - 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6, 0x7BDD, 0x7BE9, - 0x7C11, 0x7C14, 0x7BE6, 0x7BE5, 0x7C60, 0x7C00, - 0x7C07, 0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, - 0x7BF6, 0x7C23, 0x7C27, 0x7C2A, 0x7C1F, 0x7C37, - 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43, 0x7C54, 0x7C4F, - 0x7C40, 0x7C50, 0x7C58, 0x7C5F, 0x7C64, 0x7C56, - 0x7C65, 0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, - 0x7CAD, 0x7CA2, 0x7CAB, 0x7CA1, 0x7CA8, 0x7CB3, - 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9, 0x7CBD, 0x7CC0, - 0x7CC5, 0x7CC2, 0x7CD8, 0x7CD2, 0x7CDC, 0x7CE2, - 0x9B3B, 0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, - 0x7D06, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE3[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x7D02, 0x7D1C, - 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E, 0x7D32, - 0x7D3F, 0x7D35, 0x7D46, 0x7D73, 0x7D56, 0x7D4E, - 0x7D72, 0x7D68, 0x7D6E, 0x7D4F, 0x7D63, 0x7D93, - 0x7D89, 0x7D5B, 0x7D8F, 0x7D7D, 0x7D9B, 0x7DBA, - 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD, 0x7DAB, - 0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, 0x7DB8, 0x7D9F, - 0x7DB0, 0x7DD8, 0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, - 0x7DF2, 0x7DE1, 0x7E05, 0x7E0A, 0x7E23, 0x7E21, - 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B, 0x7E22, - 0x7E46, 0x7E66, 0x7E3B, 0x7E35, 0x7E39, 0x7E43, - 0x7E37, 0x0000, 0x7E32, 0x7E3A, 0x7E67, 0x7E5D, - 0x7E56, 0x7E5E, 0x7E59, 0x7E5A, 0x7E79, 0x7E6A, - 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D, - 0x8FAE, 0x7E7F, 0x7E88, 0x7E89, 0x7E8C, 0x7E92, - 0x7E90, 0x7E93, 0x7E94, 0x7E96, 0x7E8E, 0x7E9B, - 0x7E9C, 0x7F38, 0x7F3A, 0x7F45, 0x7F4C, 0x7F4D, - 0x7F4E, 0x7F50, 0x7F51, 0x7F55, 0x7F54, 0x7F58, - 0x7F5F, 0x7F60, 0x7F68, 0x7F69, 0x7F67, 0x7F78, - 0x7F82, 0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, - 0x7F94, 0x7F9E, 0x7F9D, 0x7F9A, 0x7FA3, 0x7FAF, - 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6, 0x7FB8, 0x8B71, - 0x7FC5, 0x7FC6, 0x7FCA, 0x7FD5, 0x7FD4, 0x7FE1, - 0x7FE6, 0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, - 0x8004, 0x800B, 0x8012, 0x8018, 0x8019, 0x801C, - 0x8021, 0x8028, 0x803F, 0x803B, 0x804A, 0x8046, - 0x8052, 0x8058, 0x805A, 0x805F, 0x8062, 0x8068, - 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807D, - 0x807F, 0x8084, 0x8086, 0x8085, 0x809B, 0x8093, - 0x809A, 0x80AD, 0x5190, 0x80AC, 0x80DB, 0x80E5, - 0x80D9, 0x80DD, 0x80C4, 0x80DA, 0x80D6, 0x8109, - 0x80EF, 0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, - 0x814B, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE4[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x968B, 0x8146, - 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171, 0x816E, - 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818A, - 0x8180, 0x8182, 0x81A0, 0x8195, 0x81A4, 0x81A3, - 0x815F, 0x8193, 0x81A9, 0x81B0, 0x81B5, 0x81BE, - 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA, 0x81C9, - 0x81CD, 0x81D1, 0x81D9, 0x81D8, 0x81C8, 0x81DA, - 0x81DF, 0x81E0, 0x81E7, 0x81FA, 0x81FB, 0x81FE, - 0x8201, 0x8202, 0x8205, 0x8207, 0x820A, 0x820D, - 0x8210, 0x8216, 0x8229, 0x822B, 0x8238, 0x8233, - 0x8240, 0x8259, 0x8258, 0x825D, 0x825A, 0x825F, - 0x8264, 0x0000, 0x8262, 0x8268, 0x826A, 0x826B, - 0x822E, 0x8271, 0x8277, 0x8278, 0x827E, 0x828D, - 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1, - 0x82E3, 0x82DF, 0x82D2, 0x82F4, 0x82F3, 0x82FA, - 0x8393, 0x8303, 0x82FB, 0x82F9, 0x82DE, 0x8306, - 0x82DC, 0x8309, 0x82D9, 0x8335, 0x8334, 0x8316, - 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, 0x8345, - 0x832F, 0x832B, 0x8317, 0x8318, 0x8385, 0x839A, - 0x83AA, 0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, - 0x8387, 0x838A, 0x837C, 0x83B5, 0x8373, 0x8375, - 0x83A0, 0x8389, 0x83A8, 0x83F4, 0x8413, 0x83EB, - 0x83CE, 0x83FD, 0x8403, 0x83D8, 0x840B, 0x83C1, - 0x83F7, 0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, - 0x8420, 0x83BD, 0x8438, 0x8506, 0x83FB, 0x846D, - 0x842A, 0x843C, 0x855A, 0x8484, 0x8477, 0x846B, - 0x84AD, 0x846E, 0x8482, 0x8469, 0x8446, 0x842C, - 0x846F, 0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, - 0x84BF, 0x849F, 0x84D9, 0x84CD, 0x84BB, 0x84DA, - 0x84D0, 0x84C1, 0x84C6, 0x84D6, 0x84A1, 0x8521, - 0x84FF, 0x84F4, 0x8517, 0x8518, 0x852C, 0x851F, - 0x8515, 0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, - 0x8548, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE5[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8541, 0x8602, - 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588, 0x8591, - 0x858A, 0x85A8, 0x856D, 0x8594, 0x859B, 0x85EA, - 0x8587, 0x859C, 0x8577, 0x857E, 0x8590, 0x85C9, - 0x85BA, 0x85CF, 0x85B9, 0x85D0, 0x85D5, 0x85DD, - 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613, 0x860B, - 0x85FE, 0x85FA, 0x8606, 0x8622, 0x861A, 0x8630, - 0x863F, 0x864D, 0x4E55, 0x8654, 0x865F, 0x8667, - 0x8671, 0x8693, 0x86A3, 0x86A9, 0x86AA, 0x868B, - 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6, 0x86B0, - 0x86C9, 0x8823, 0x86AB, 0x86D4, 0x86DE, 0x86E9, - 0x86EC, 0x0000, 0x86DF, 0x86DB, 0x86EF, 0x8712, - 0x8706, 0x8708, 0x8700, 0x8703, 0x86FB, 0x8711, - 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F, - 0x8737, 0x873B, 0x8725, 0x8729, 0x871A, 0x8760, - 0x875F, 0x8778, 0x874C, 0x874E, 0x8774, 0x8757, - 0x8768, 0x876E, 0x8759, 0x8753, 0x8763, 0x876A, - 0x8805, 0x87A2, 0x879F, 0x8782, 0x87AF, 0x87CB, - 0x87BD, 0x87C0, 0x87D0, 0x96D6, 0x87AB, 0x87C4, - 0x87B3, 0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, - 0x87E0, 0x880F, 0x880D, 0x87FE, 0x87F6, 0x87F7, - 0x880E, 0x87D2, 0x8811, 0x8816, 0x8815, 0x8822, - 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883B, - 0x8844, 0x8842, 0x8852, 0x8859, 0x885E, 0x8862, - 0x886B, 0x8881, 0x887E, 0x889E, 0x8875, 0x887D, - 0x88B5, 0x8872, 0x8882, 0x8897, 0x8892, 0x88AE, - 0x8899, 0x88A2, 0x888D, 0x88A4, 0x88B0, 0x88BF, - 0x88B1, 0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, - 0x88DD, 0x88F9, 0x8902, 0x88FC, 0x88F4, 0x88E8, - 0x88F2, 0x8904, 0x890C, 0x890A, 0x8913, 0x8943, - 0x891E, 0x8925, 0x892A, 0x892B, 0x8941, 0x8944, - 0x893B, 0x8936, 0x8938, 0x894C, 0x891D, 0x8960, - 0x895E, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE6[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8966, 0x8964, - 0x896D, 0x896A, 0x896F, 0x8974, 0x8977, 0x897E, - 0x8983, 0x8988, 0x898A, 0x8993, 0x8998, 0x89A1, - 0x89A9, 0x89A6, 0x89AC, 0x89AF, 0x89B2, 0x89BA, - 0x89BD, 0x89BF, 0x89C0, 0x89DA, 0x89DC, 0x89DD, - 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16, 0x8A10, - 0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, 0x8A36, 0x8A41, - 0x8A5B, 0x8A52, 0x8A46, 0x8A48, 0x8A7C, 0x8A6D, - 0x8A6C, 0x8A62, 0x8A85, 0x8A82, 0x8A84, 0x8AA8, - 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A, 0x8AA3, - 0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, 0x8AEB, 0x8AF3, - 0x8AE7, 0x0000, 0x8AE4, 0x8AF1, 0x8B14, 0x8AE0, - 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB, 0x8B0C, 0x8B07, - 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20, - 0x8B33, 0x97AB, 0x8B26, 0x8B2B, 0x8B3E, 0x8B28, - 0x8B41, 0x8B4C, 0x8B4F, 0x8B4E, 0x8B49, 0x8B56, - 0x8B5B, 0x8B5A, 0x8B6B, 0x8B5F, 0x8B6C, 0x8B6F, - 0x8B74, 0x8B7D, 0x8B80, 0x8B8C, 0x8B8E, 0x8B92, - 0x8B93, 0x8B96, 0x8B99, 0x8B9A, 0x8C3A, 0x8C41, - 0x8C3F, 0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, - 0x8C62, 0x8C6C, 0x8C78, 0x8C7A, 0x8C82, 0x8C89, - 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E, 0x8C94, 0x8C7C, - 0x8C98, 0x621D, 0x8CAD, 0x8CAA, 0x8CBD, 0x8CB2, - 0x8CB3, 0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, - 0x8CE3, 0x8CDA, 0x8CFD, 0x8CFA, 0x8CFB, 0x8D04, - 0x8D05, 0x8D0A, 0x8D07, 0x8D0F, 0x8D0D, 0x8D10, - 0x9F4E, 0x8D13, 0x8CCD, 0x8D14, 0x8D16, 0x8D67, - 0x8D6D, 0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, - 0x8DBE, 0x8DBA, 0x8DCF, 0x8DDA, 0x8DD6, 0x8DCC, - 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB, 0x8DDF, 0x8DE3, - 0x8DFC, 0x8E08, 0x8E09, 0x8DFF, 0x8E1D, 0x8E1E, - 0x8E10, 0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, - 0x8E4A, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE7[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8E47, 0x8E49, - 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64, 0x8E60, - 0x8E2A, 0x8E63, 0x8E55, 0x8E76, 0x8E72, 0x8E7C, - 0x8E81, 0x8E87, 0x8E85, 0x8E84, 0x8E8B, 0x8E8A, - 0x8E93, 0x8E91, 0x8E94, 0x8E99, 0x8EAA, 0x8EA1, - 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE, 0x8EC5, - 0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, 0x8EFC, 0x8EFB, - 0x8EEB, 0x8EFE, 0x8F0A, 0x8F05, 0x8F15, 0x8F12, - 0x8F19, 0x8F13, 0x8F1C, 0x8F1F, 0x8F1B, 0x8F0C, - 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45, 0x8F42, - 0x8F3E, 0x8F4C, 0x8F49, 0x8F46, 0x8F4E, 0x8F57, - 0x8F5C, 0x0000, 0x8F62, 0x8F63, 0x8F64, 0x8F9C, - 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF, 0x8FB7, 0x8FDA, - 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4, - 0x9005, 0x8FF9, 0x8FFA, 0x9011, 0x9015, 0x9021, - 0x900D, 0x901E, 0x9016, 0x900B, 0x9027, 0x9036, - 0x9035, 0x9039, 0x8FF8, 0x904F, 0x9050, 0x9051, - 0x9052, 0x900E, 0x9049, 0x903E, 0x9056, 0x9058, - 0x905E, 0x9068, 0x906F, 0x9076, 0x96A8, 0x9072, - 0x9082, 0x907D, 0x9081, 0x9080, 0x908A, 0x9089, - 0x908F, 0x90A8, 0x90AF, 0x90B1, 0x90B5, 0x90E2, - 0x90E4, 0x6248, 0x90DB, 0x9102, 0x9112, 0x9119, - 0x9132, 0x9130, 0x914A, 0x9156, 0x9158, 0x9163, - 0x9165, 0x9169, 0x9173, 0x9172, 0x918B, 0x9189, - 0x9182, 0x91A2, 0x91AB, 0x91AF, 0x91AA, 0x91B5, - 0x91B4, 0x91BA, 0x91C0, 0x91C1, 0x91C9, 0x91CB, - 0x91D0, 0x91D6, 0x91DF, 0x91E1, 0x91DB, 0x91FC, - 0x91F5, 0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, - 0x9215, 0x9211, 0x925E, 0x9257, 0x9245, 0x9249, - 0x9264, 0x9248, 0x9295, 0x923F, 0x924B, 0x9250, - 0x929C, 0x9296, 0x9293, 0x929B, 0x925A, 0x92CF, - 0x92B9, 0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, - 0x932E, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE8[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9319, 0x9322, - 0x931A, 0x9323, 0x933A, 0x9335, 0x933B, 0x935C, - 0x9360, 0x937C, 0x936E, 0x9356, 0x93B0, 0x93AC, - 0x93AD, 0x9394, 0x93B9, 0x93D6, 0x93D7, 0x93E8, - 0x93E5, 0x93D8, 0x93C3, 0x93DD, 0x93D0, 0x93C8, - 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403, 0x9407, - 0x9410, 0x9436, 0x942B, 0x9435, 0x9421, 0x943A, - 0x9441, 0x9452, 0x9444, 0x945B, 0x9460, 0x9462, - 0x945E, 0x946A, 0x9229, 0x9470, 0x9475, 0x9477, - 0x947D, 0x945A, 0x947C, 0x947E, 0x9481, 0x947F, - 0x9582, 0x9587, 0x958A, 0x9594, 0x9596, 0x9598, - 0x9599, 0x0000, 0x95A0, 0x95A8, 0x95A7, 0x95AD, - 0x95BC, 0x95BB, 0x95B9, 0x95BE, 0x95CA, 0x6FF6, - 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6, - 0x95DC, 0x95E1, 0x95E5, 0x95E2, 0x9621, 0x9628, - 0x962E, 0x962F, 0x9642, 0x964C, 0x964F, 0x964B, - 0x9677, 0x965C, 0x965E, 0x965D, 0x965F, 0x9666, - 0x9672, 0x966C, 0x968D, 0x9698, 0x9695, 0x9697, - 0x96AA, 0x96A7, 0x96B1, 0x96B2, 0x96B0, 0x96B4, - 0x96B6, 0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, - 0x96CD, 0x894D, 0x96DC, 0x970D, 0x96D5, 0x96F9, - 0x9704, 0x9706, 0x9708, 0x9713, 0x970E, 0x9711, - 0x970F, 0x9716, 0x9719, 0x9724, 0x972A, 0x9730, - 0x9739, 0x973D, 0x973E, 0x9744, 0x9746, 0x9748, - 0x9742, 0x9749, 0x975C, 0x9760, 0x9764, 0x9766, - 0x9768, 0x52D2, 0x976B, 0x9771, 0x9779, 0x9785, - 0x977C, 0x9781, 0x977A, 0x9786, 0x978B, 0x978F, - 0x9790, 0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, - 0x97B4, 0x97C3, 0x97C6, 0x97C8, 0x97CB, 0x97DC, - 0x97ED, 0x9F4F, 0x97F2, 0x7ADF, 0x97F6, 0x97F5, - 0x980F, 0x980C, 0x9838, 0x9824, 0x9821, 0x9837, - 0x983D, 0x9846, 0x984F, 0x984B, 0x986B, 0x986F, - 0x9870, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisE9[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9871, 0x9874, - 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6, 0x98C4, - 0x98C3, 0x98C6, 0x98E9, 0x98EB, 0x9903, 0x9909, - 0x9912, 0x9914, 0x9918, 0x9921, 0x991D, 0x991E, - 0x9924, 0x9920, 0x992C, 0x992E, 0x993D, 0x993E, - 0x9942, 0x9949, 0x9945, 0x9950, 0x994B, 0x9951, - 0x9952, 0x994C, 0x9955, 0x9997, 0x9998, 0x99A5, - 0x99AD, 0x99AE, 0x99BC, 0x99DF, 0x99DB, 0x99DD, - 0x99D8, 0x99D1, 0x99ED, 0x99EE, 0x99F1, 0x99F2, - 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05, 0x99E2, - 0x9A19, 0x9A2B, 0x9A37, 0x9A45, 0x9A42, 0x9A40, - 0x9A43, 0x0000, 0x9A3E, 0x9A55, 0x9A4D, 0x9A5B, - 0x9A57, 0x9A5F, 0x9A62, 0x9A65, 0x9A64, 0x9A69, - 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0, - 0x9ACF, 0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, 0x9ADF, - 0x9AE2, 0x9AE3, 0x9AE6, 0x9AEF, 0x9AEB, 0x9AEE, - 0x9AF4, 0x9AF1, 0x9AF7, 0x9AFB, 0x9B06, 0x9B18, - 0x9B1A, 0x9B1F, 0x9B22, 0x9B23, 0x9B25, 0x9B27, - 0x9B28, 0x9B29, 0x9B2A, 0x9B2E, 0x9B2F, 0x9B32, - 0x9B44, 0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, - 0x9B58, 0x9B74, 0x9B93, 0x9B83, 0x9B91, 0x9B96, - 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8, 0x9BB4, 0x9BC0, - 0x9BCA, 0x9BB9, 0x9BC6, 0x9BCF, 0x9BD1, 0x9BD2, - 0x9BE3, 0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, - 0x9BF2, 0x9BF1, 0x9BF0, 0x9C15, 0x9C14, 0x9C09, - 0x9C13, 0x9C0C, 0x9C06, 0x9C08, 0x9C12, 0x9C0A, - 0x9C04, 0x9C2E, 0x9C1B, 0x9C25, 0x9C24, 0x9C21, - 0x9C30, 0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, - 0x9C60, 0x9C67, 0x9C76, 0x9C78, 0x9CE7, 0x9CEC, - 0x9CF0, 0x9D09, 0x9D08, 0x9CEB, 0x9D03, 0x9D06, - 0x9D2A, 0x9D26, 0x9DAF, 0x9D23, 0x9D1F, 0x9D44, - 0x9D15, 0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, - 0x9D48, 0x0000, 0x0000, 0x0000 -}; - -static u16 SjisEA[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9D5D, 0x9D5E, - 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72, 0x9D89, - 0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, 0x9D9A, 0x9DA4, - 0x9DA9, 0x9DB2, 0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, - 0x9DBA, 0x9DC6, 0x9DCF, 0x9DC2, 0x9DD9, 0x9DD3, - 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD, 0x9E1A, - 0x9E1B, 0x9E1E, 0x9E75, 0x9E79, 0x9E7D, 0x9E81, - 0x9E88, 0x9E8B, 0x9E8C, 0x9E92, 0x9E95, 0x9E91, - 0x9E9D, 0x9EA5, 0x9EA9, 0x9EB8, 0x9EAA, 0x9EAD, - 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0, 0x9ED4, - 0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, 0x9EE5, 0x9EE8, - 0x9EEF, 0x0000, 0x9EF4, 0x9EF6, 0x9EF7, 0x9EF9, - 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07, 0x9F08, 0x76B7, - 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52, - 0x9F54, 0x9F63, 0x9F5F, 0x9F60, 0x9F61, 0x9F66, - 0x9F67, 0x9F6C, 0x9F6A, 0x9F77, 0x9F72, 0x9F76, - 0x9F95, 0x9F9C, 0x9FA0, 0x582F, 0x69C7, 0x9059, - 0x7464, 0x51DC, 0x7199, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 -}; - -static u16* SjisUcsTable[256] = {0}; - -u32 OSSJIStoUTF32(u16 sjis) { - u16* table; - - table = SjisUcsTable[(sjis >> 8) & 0xFF]; - if (table != 0) { - return table[sjis & 0xFF]; - } - - return 0; -} diff --git a/src/dolphin/os/__os.h b/src/dolphin/os/__os.h deleted file mode 100644 index 452dd20..0000000 --- a/src/dolphin/os/__os.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef _DOLPHIN_OS_INTERNAL_H_ -#define _DOLPHIN_OS_INTERNAL_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// OS -extern char* __OSExceptionNames[17]; // D ONLY - -u32 __OSIsDebuggerPresent(void); -void __OSPSInit(void); - -// OSAlloc -extern volatile int __OSCurrHeap; - -// OSAudioSystem -void __OSInitAudioSystem(void); -void __OSStopAudioSystem(void); - -// OSCache -void __OSCacheInit(void); - -// OSContext -void __OSContextInit(void); - -// OSError -void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); - -// OSExec -void __OSGetExecParams(OSExecParams* params); -void __OSSetExecParams(const OSExecParams* params, OSExecParams* addr); -void __OSBootDolSimple(u32 doloffset, u32 restartCode, void* regionStart, void* regionEnd, BOOL argsUseDefault, s32 argc, char** argv); -void __OSBootDol(u32 doloffset, u32 restartCode, const char** argv); - -// OSInterrupt -extern void __RAS_OSDisableInterrupts_begin(void); -extern void __RAS_OSDisableInterrupts_end(void); - -extern u64 __OSSpuriousInterrupts; // D ONLY -extern char* __OSInterruptNames[33]; // D ONLY -extern char* __OSPIErrors[8]; // D ONLY - -__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler); -__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt); -void __OSInterruptInit(void); -OSInterruptMask __OSMaskInterrupts(OSInterruptMask global); -OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global); -void __OSDispatchInterrupt(__OSException exception, OSContext* context); -void __OSModuleInit(void); - -// OSMemory -void __OSInitMemoryProtection(void); - -// OSMutex -void __OSUnlockAllMutex(OSThread* thread); -int __OSCheckDeadLock(OSThread* thread); -int __OSCheckMutexes(OSThread* thread); - -// OSReset -void __OSDoHotReset(u32 resetCode); -void __OSShutdownDevices(BOOL doRecal); -int __OSCallResetFunctions(BOOL final); - -// OSResetSW -void __OSResetSWInterruptHandler(s16 exception, OSContext* context); -void __OSSetResetButtonTimer(u8 min); - -// OSRtc -int __OSGetRTC(u32* rtc); -int __OSSetRTC(u32 rtc); -void __OSInitSram(void); -OSSram* __OSLockSram(void); -OSSramEx* __OSLockSramEx(void); -int __OSUnlockSram(BOOL commit); -int __OSUnlockSramEx(BOOL commit); -int __OSSyncSram(void); -int __OSCheckSram(void); -int __OSReadROM(void* buffer, s32 length, s32 offset); -int __OSReadROMAsync(void* buffer, s32 length, s32 offset, void (*callback)()); -u8 __OSGetBootMode(void); -void __OSSetBootMode(u8 ntd); - -// OSSync -extern void __OSSystemCallVectorStart(); -extern void __OSSystemCallVectorEnd(); - -void __OSInitSystemCall(void); - -// OSThread -void __OSThreadInit(void); -s32 __OSGetEffectivePriority(OSThread* thread); -void __OSPromoteThread(OSThread* thread, s32 priority); -void __OSReschedule(void); - -// OSTime -void __OSSetTime(OSTime time); -OSTime __OSGetSystemTime(); -void __OSSetTick(register OSTick newTicks); -OSTime __OSTimeToSystemTime(OSTime time); - -// ppc_eabi_init -__declspec(section ".init") asm void __init_hardware(void); -__declspec(section ".init") asm void __flush_cache(void* address, unsigned int size); -void __init_user(void); -void _ExitProcess(void); - -// start -__declspec(weak) void InitMetroTRK_BBA(); - -__declspec(section ".init") void __start(void); - -__declspec(section ".init") extern void __start(void); -__declspec(section ".init") void __copy_rom_section(void* dst, const void* src, u32 size); -__declspec(section ".init") void __init_bss_section(void* dst, u32 size); -__declspec(section ".init") extern void __init_registers(void); -__declspec(section ".init") extern void __init_data(void); - -// time.dolphin -OSTime __get_clock(void); -u32 __get_time(void); -int __to_gm_time(void); - -#ifdef __cplusplus -} -#endif - -#endif // _DOLPHIN_OS_INTERNAL_H_ diff --git a/src/dolphin/os/src/init/__ppc_eabi_init.c b/src/dolphin/os/src/init/__ppc_eabi_init.c deleted file mode 100644 index 1a90be2..0000000 --- a/src/dolphin/os/src/init/__ppc_eabi_init.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include - -#include "__os.h" - -__declspec(section ".ctors") extern void (* _ctors[])(); -__declspec(section ".dtors") extern void (* _dtors[])(); - -static void __init_cpp(void); -static void __fini_cpp(void); - -__declspec(section ".init") asm void __init_hardware(void) -{ // clang-format off - nofralloc - mfmsr r0 - ori r0,r0,MSR_FP - mtmsr r0 - mflr r31 - bl __OSPSInit - bl __OSFPRInit - bl __OSCacheInit - mtlr r31 - blr -} - -__declspec(section ".init") asm void __flush_cache(void *address, unsigned int size) -{ // clang-format off - nofralloc - lis r5, 0xffff - ori r5, r5, 0xfff1 - and r5, r5, r3 - subf r3, r5, r3 - add r4, r4, r3 -rept: - dcbst 0,r5 - sync - icbi 0,r5 - addic r5,r5,0x8 - subic. r4,r4,0x8 - bge rept - isync - blr -} - -void __init_user(void) { - __init_cpp(); -} - -static void __init_cpp(void) { - void (* * constructor)(); - - /* - * call static initializers - */ - for (constructor = _ctors; *constructor; constructor++) { - (*constructor)(); - } -} - -static void __fini_cpp(void) { - void (* * destructor)(); - - /* - * call destructors - */ - for (destructor = _dtors; *destructor; destructor++) { - (*destructor)(); - } -} - -__declspec(weak) -void abort(void) { - _ExitProcess(); -} - -__declspec(weak) -void exit(int status) { - __fini_cpp(); - _ExitProcess(); -} - -void _ExitProcess(void) { - PPCHalt(); -} diff --git a/src/dolphin/os/src/init/__start.c b/src/dolphin/os/src/init/__start.c deleted file mode 100644 index 736cae0..0000000 --- a/src/dolphin/os/src/init/__start.c +++ /dev/null @@ -1,265 +0,0 @@ -#include -#include - -#include "__os.h" - -#define PAD3_BUTTON_ADDR 0x800030E4 -#define OS_RESET_RESTART 0 -#define FALSE 0 -#define TRUE 1 -#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 DOL_ADDR_LIMIT 0x80700000 - -u16 Pad3Button AT_ADDRESS(PAD3_BUTTON_ADDR); -static u8 Debug_BBA = 0; - -extern void InitMetroTRK(); - -__declspec(weak) void InitMetroTRK_BBA() {} - -__declspec(section ".init") extern char _stack_addr[]; -__declspec(section ".init") extern char _SDA_BASE_[]; -__declspec(section ".init") extern char _SDA2_BASE_[]; - -typedef struct __rom_copy_info { - char* rom; - char* addr; - unsigned int size; -} __rom_copy_info; - -__declspec(section ".init") extern __rom_copy_info _rom_copy_info[]; - -typedef struct __bss_init_info { - char* addr; - unsigned int size; -} __bss_init_info; - -__declspec(section ".init") extern __bss_init_info _bss_init_info[]; -extern int main(int argc, char* argv[]); -extern void exit(int); - -__declspec(section ".init") extern void __init_hardware(void); -__declspec(section ".init") extern void __flush_cache(void* address, unsigned int size); - -__declspec(section ".init") static void __check_pad3(void); -__declspec(section ".init") static void __set_debug_bba(void); -__declspec(section ".init") static u8 __get_debug_bba(void); - -static void __init_registers(void); -static void __init_data(void); - -static void __check_pad3(void) { - if ((Pad3Button & 0xEEF) == 0xEEF) { - OSResetSystem(OS_RESET_RESTART, 0, FALSE); - } -} - -static void __set_debug_bba(void) { - Debug_BBA = 1; -} - -static u8 __get_debug_bba(void) { - return Debug_BBA; -} - -#ifdef __GEKKO__ -__declspec(section ".init") -__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 -} -#endif - -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); - } -} - -static void __init_bss_section(void* dst, unsigned long size) { - if (size) { - memset(dst, 0, size); - } -} - -#ifdef __GEKKO__ -asm static void __init_registers(void) { - 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 -} -#endif - -static 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/src/dolphin/os/time.dolphin.c b/src/dolphin/os/time.dolphin.c deleted file mode 100644 index 5e9d20a..0000000 --- a/src/dolphin/os/time.dolphin.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -#include "__os.h" - -OSTime __get_clock(void) { - return __OSGetSystemTime(); -} - -u32 __get_time(void) { - return OSTicksToSeconds(OSGetTime()) - 0x43E83E00; -} - -int __to_gm_time(void) { - return 0; -} diff --git a/src/dolphin/pad/Pad.c b/src/dolphin/pad/Pad.c deleted file mode 100644 index 27c5545..0000000 --- a/src/dolphin/pad/Pad.c +++ /dev/null @@ -1,841 +0,0 @@ -#include -#include -#include - -#include "__si.h" - -#if DEBUG -const char* __PADVersion = "<< Dolphin SDK - PAD\tdebug build: Apr 5 2004 03:56:05 (0x2301) >>"; -#else -const char* __PADVersion = "<< Dolphin SDK - PAD\trelease build: Apr 5 2004 04:14:49 (0x2301) >>"; -#endif - -#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 s32 ResettingChan = 0x20; -static u32 XPatchBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT; -static u32 AnalogMode = 0x300; -static u32 Spec = PAD_SPEC_5; - -static BOOL Initialized; -static u32 EnabledBits; -static u32 ResettingBits; -static u32 RecalibrateBits; -static u32 WaitingBits; -static u32 CheckingBits; -static u32 PendingBits; -static u32 BarrelBits; - -static u32 Type[4]; -static PADStatus Origin[4]; - -u32 __PADSpec; - -// prototypes -static void PADTypeAndStatusCallback(s32 chan, u32 type); -static u16 GetWirelessID(s32 chan); -static void SetWirelessID(s32 chan, u16 id); -static void DoReset(); -static void PADEnable(s32 chan); -static void ProbeWireless(s32 chan); -static void PADProbeCallback(s32 chan, u32 error, OSContext *context); -static void PADDisable(s32 chan); -static void UpdateOrigin(s32 chan); -static void PADOriginCallback(s32 chan, u32 error, OSContext *context); -static void PADFixCallback(s32 unused, u32 error, struct OSContext *context); -static void PADResetCallback(s32 unused, u32 error, struct OSContext *context); -static void PADReceiveCheckCallback(s32 chan, u32 error); -static void SPEC0_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); -static void SPEC1_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); -static s8 ClampS8(s8 var, s8 org); -static u8 ClampU8(u8 var, u8 org); -static void SPEC2_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); -static BOOL OnReset(BOOL f); -void __PADDisableXPatch(void); -BOOL __PADDisableRumble(BOOL disable); - -typedef void (*SPECCallback)(s32, PADStatus*, u32*); -static SPECCallback MakeStatus = SPEC2_MakeStatus; - -static u32 CmdTypeAndStatus; -static u32 CmdReadOrigin = 0x41000000; -static u32 CmdCalibrate = 0x42000000; -static u32 CmdProbeDevice[4]; - -static OSResetFunctionInfo ResetFunctionInfo = { - OnReset, - 127, - NULL, - NULL, -}; - -static void PADEnable(s32 chan) { - u32 cmd; - u32 chanBit; - u32 data[2]; - - chanBit = PAD_CHAN0_BIT >> chan; - EnabledBits |= chanBit; - SIGetResponse(chan, &data); - cmd = (AnalogMode | 0x400000); - 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() { - u32 chanBit; - - ResettingChan = __cntlzw(ResettingBits); - if (ResettingChan != 32) { - ASSERTLINE(559, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); - chanBit = (PAD_CHAN0_BIT >> ResettingChan); - ResettingBits &= ~chanBit; - - memset(&Origin[ResettingChan], 0, sizeof(PADStatus)); - SIGetTypeAsync(ResettingChan, PADTypeAndStatusCallback); - } -} - -static void UpdateOrigin(s32 chan) { - PADStatus* origin; - u32 chanBit = PAD_CHAN0_BIT >> chan; - - origin = &Origin[chan]; - switch (AnalogMode & 0x00000700u) { - case 0x00000000u: - case 0x00000500u: - case 0x00000600u: - case 0x00000700u: - origin->triggerLeft &= ~15; - origin->triggerRight &= ~15; - origin->analogA &= ~15; - origin->analogB &= ~15; - break; - case 0x00000100u: - origin->substickX &= ~15; - origin->substickY &= ~15; - origin->analogA &= ~15; - origin->analogB &= ~15; - break; - case 0x00000200u: - origin->substickX &= ~15; - origin->substickY &= ~15; - origin->triggerLeft &= ~15; - origin->triggerRight &= ~15; - break; - case 0x00000300u: break; - case 0x00000400u: break; - } - - origin->stickX -= 128; - origin->stickY -= 128; - origin->substickX -= 128; - origin->substickY -= 128; - - if (XPatchBits & chanBit) { - if (64 < origin->stickX && (SIGetType(chan) & 0xFFFF0000) == SI_GC_CONTROLLER) { - origin->stickX = 0; - } - } -} - -static void PADOriginCallback(s32 chan, u32 error, OSContext* context) { - ASSERTLINE(641, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); - ASSERTLINE(642, chan == ResettingChan); - - if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) - { - UpdateOrigin(ResettingChan); - PADEnable(ResettingChan); - } - - DoReset(); -} - -static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context) { - ASSERTLINE(671, 0 <= chan && chan < SI_MAX_CHAN); - if (!(EnabledBits & (PAD_CHAN0_BIT >> chan))) - return; - if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) - UpdateOrigin(chan); - if (error & SI_ERROR_NO_RESPONSE) { - PADDisable(chan); - } -} - -static void PADProbeCallback(s32 chan, u32 error, OSContext* context) { - u32 type; - ASSERTLINE(710, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); - ASSERTLINE(711, chan == ResettingChan); - ASSERTLINE(713, (Type[chan] & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && !(Type[chan] & SI_WIRELESS_LITE)); - - if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) - { - PADEnable(ResettingChan); - WaitingBits |= PAD_CHAN0_BIT >> ResettingChan; - } - - DoReset(); -} - -static void PADTypeAndStatusCallback(s32 chan, u32 type) { - u32 chanBit; - u32 recalibrate; - BOOL rc = TRUE; - u32 error; - - ASSERTLINE(746, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); - ASSERTLINE(747, chan == ResettingChan); - - chanBit = PAD_CHAN0_BIT >> ResettingChan; - error = type & 0xFF; - ASSERTLINE(756, !(error & SI_ERROR_BUSY)); - - recalibrate = RecalibrateBits & chanBit; - RecalibrateBits &= ~chanBit; - - if (error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) - { - 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) { - 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); - } - } -} - -int PADReset(u32 mask) { - BOOL enabled; - u32 disableBits; - - ASSERTMSGLINE(0x381, !(mask & 0x0FFFFFFF), "PADReset(): invalid mask"); - - enabled = OSDisableInterrupts(); - mask |= PendingBits; - PendingBits = 0; - mask &= ~(WaitingBits | CheckingBits); - ResettingBits |= mask; - disableBits = ResettingBits & EnabledBits; - EnabledBits &= ~mask; - BarrelBits &= ~mask; - - if (Spec == 4) { - RecalibrateBits |= mask; - } - - SIDisablePolling(disableBits); - - if (ResettingChan == 0x20) { - DoReset(); - } - - OSRestoreInterrupts(enabled); - return 1; -} - -BOOL PADRecalibrate(u32 mask) { - BOOL enabled; - u32 disableBits; - - ASSERTMSGLINE(939, !(mask & 0x0FFFFFFF), "PADReset(): invalid mask"); - enabled = OSDisableInterrupts(); - - mask |= PendingBits; - PendingBits = 0; - mask &= ~(WaitingBits | CheckingBits); - ResettingBits |= mask; - disableBits = ResettingBits & EnabledBits; - EnabledBits &= ~mask; - BarrelBits &= ~mask; - - if (!(__gUnknown800030E3 & 0x40)) { - RecalibrateBits |= mask; - } - - SIDisablePolling(disableBits); - if (ResettingChan == 32) - DoReset(); - - OSRestoreInterrupts(enabled); - return 1; -} - -BOOL PADInit() { - s32 chan; - if (Initialized) { - return 1; - } - - 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); -} - -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 < 4; 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)); - } else if ((ResettingBits & chanBit) || ResettingChan == chan) { - status->err = PAD_ERR_NOT_READY; - memset(status, 0, offsetof(PADStatus, err)); - } else if (!(EnabledBits & chanBit)) { - status->err = PAD_ERR_NO_CONTROLLER; - memset(status, 0, offsetof(PADStatus, err)); - } else if (SIIsChanBusy(chan)) { - status->err = PAD_ERR_TRANSFER; - memset(status, 0, offsetof(PADStatus, err)); - } else { - sr = SIGetStatus(chan); - if (sr & SI_ERROR_NO_RESPONSE) { - SIGetResponse(chan, data); - - if (WaitingBits & chanBit) { - status->err = PAD_ERR_NONE; - memset(status, 0, offsetof(PADStatus, err)); - - if (!(CheckingBits & chanBit)) { - CheckingBits |= chanBit; - SIGetTypeAsync(chan, PADReceiveCheckCallback); - } - } else { - PADDisable(chan); - status->err = PAD_ERR_NO_CONTROLLER; - memset(status, 0, offsetof(PADStatus, err)); - } - } else { - if (!(SIGetType(chan) & SI_GC_NOMOTOR)) { - motor |= chanBit; - } - - if (!SIGetResponse(chan, &data)) { - status->err = PAD_ERR_TRANSFER; - memset(status, 0, offsetof(PADStatus, err)); - } else if (data[0] & 0x80000000) { - status->err = PAD_ERR_TRANSFER; - memset(status, 0, offsetof(PADStatus, err)); - } else { - MakeStatus(chan, status, data); - - // Check and clear PAD_ORIGIN bit - if (status->button & 0x2000) { - status->err = PAD_ERR_TRANSFER; - memset(status, 0, offsetof(PADStatus, err)); - - // Get origin. It is okay if the following transfer fails - // since the PAD_ORIGIN bit remains until the read origin - // command complete. - SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0); - } else { - status->err = PAD_ERR_NONE; - - // Clear PAD_INTERFERE bit - status->button &= ~0x0080; - } - } - } - } - } - - OSRestoreInterrupts(enabled); - return motor; -} - -typedef struct XY { - u8 line; - u8 count; -} XY; - -void PADSetSamplingRate(u32 msec) { - SISetSamplingRate(msec); -} - -#if DEBUG -void __PADTestSamplingRate(u32 tvmode) { - __SITestSamplingRate(tvmode); -} -#endif - -void PADControlAllMotors(const u32* commandArray) { - BOOL enabled; - int chan; - u32 command; - BOOL commit; - u32 chanBit; - - enabled = OSDisableInterrupts(); - commit = FALSE; - - for (chan = 0; chan < SI_MAX_CHAN; chan++, commandArray++) { - chanBit = PAD_CHAN0_BIT >> chan; - if ((EnabledBits & chanBit) && !(SIGetType(chan) & 0x20000000)) { - command = *commandArray; - ASSERTMSGLINE(0x4B5, !(command & 0xFFFFFFFC), "PADControlAllMotors(): invalid command"); - if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) - command = PAD_MOTOR_STOP; - if (__gUnknown800030E3 & 0x20) - command = PAD_MOTOR_STOP; - SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); - commit = TRUE; - } - } - - if (commit) - SITransferCommands(); - - OSRestoreInterrupts(enabled); -} - -void PADControlMotor(s32 chan, u32 command) { - BOOL enabled; - u32 chanBit; - - ASSERTMSGLINE(1244, !(command & 0xFFFFFFFC), "PADControlMotor(): invalid command"); - - enabled = OSDisableInterrupts(); - chanBit = 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 (__gUnknown800030E3 & 0x20) - command = PAD_MOTOR_STOP; - SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); - SITransferCommands(); - } - - OSRestoreInterrupts(enabled); -} - -void PADSetSpec(u32 spec) { - ASSERTLINE(1282, !Initialized); - __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; -} - -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; - return; - } 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); -} - -int PADGetType(s32 chan, u32* type) { - u32 chanBit; - - *type = SIGetType(chan); - chanBit = PAD_CHAN0_BIT >> chan; - if (ResettingBits & chanBit || ResettingChan == chan || !(EnabledBits & chanBit)) { - return 0; - } - return 1; -} - -BOOL PADSync(void) { - return ResettingBits == 0 && (s32)ResettingChan == 32 && !SIBusy(); -} - -void PADSetAnalogMode(u32 mode) { - BOOL enabled; - u32 mask; - - ASSERTMSGLINE(1615, (mode < 8), "PADSetAnalogMode(): invalid mode"); - - enabled = OSDisableInterrupts(); - AnalogMode = mode << 8; - mask = EnabledBits; - - EnabledBits &= ~mask; - WaitingBits &= ~mask; - CheckingBits &= ~mask; - - SIDisablePolling(mask); - OSRestoreInterrupts(enabled); -} - -static void (*SamplingCallback)(); - -static BOOL OnReset(BOOL final) { - BOOL sync; - static BOOL recalibrated = FALSE; - - if (SamplingCallback) - PADSetSamplingCallback(NULL); - - if (!final) { - 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 = (__gUnknown800030E3 & 0x40) ? TRUE : FALSE; - __gUnknown800030E3 &= ~0x40; - if (disable) { - __gUnknown800030E3 |= 0x40; - } - - OSRestoreInterrupts(enabled); - return prev; -} - -BOOL __PADDisableRumble(BOOL disable) { - BOOL enabled; - BOOL prev; - - enabled = OSDisableInterrupts(); - prev = (__gUnknown800030E3 & 0x20) ? TRUE : FALSE; - __gUnknown800030E3 &= ~0x20; - if (disable) { - __gUnknown800030E3 |= 0x20; - } - OSRestoreInterrupts(enabled); - return prev; -} - -BOOL PADIsBarrel(s32 chan) { - if (chan < 0 || chan >= 4) { - return FALSE; - } - - if (BarrelBits & (PAD_CHAN0_BIT >> chan)) { - return TRUE; - } - - return FALSE; -} diff --git a/src/dolphin/pad/Padclamp.c b/src/dolphin/pad/Padclamp.c deleted file mode 100644 index edc31dc..0000000 --- a/src/dolphin/pad/Padclamp.c +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include -#include - -static const PADClampRegion ClampRegion = { - // Triggers - 30, - 180, - - // Left stick - 15, - 72, - 40, - - // Right stick - 15, - 59, - 31, - - // Stick radii - 56, - 44, -}; - -// prototypes -static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min); -static void ClampCircle(s8* px, s8* py, s8 radius, s8 min); -static void ClampTrigger(u8* trigger, u8 min, u8 max); - -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; - } else { - if (max < *trigger) { - *trigger = max; - } - *trigger -= min; - } -} - -void PADClamp(PADStatus * status) { - int i; - - for (i = 0; i < 4; i++, status++) { - if (status->err == PAD_ERR_NONE) { - ClampStick(&status->stickX, &status->stickY, ClampRegion.maxStick, ClampRegion.xyStick, ClampRegion.minStick); - ClampStick(&status->substickX, &status->substickY, ClampRegion.maxSubstick, ClampRegion.xySubstick, ClampRegion.minSubstick); - ClampTrigger(&status->triggerLeft, ClampRegion.minTrigger, ClampRegion.maxTrigger); - ClampTrigger(&status->triggerRight, ClampRegion.minTrigger, ClampRegion.maxTrigger); - } - } -} - -void PADClampCircle(PADStatus* status) { - int i; - for (i = 0; i < 4; ++i, status++) { - if (status->err == PAD_ERR_NONE) { - ClampCircle(&status->stickX, &status->stickY, ClampRegion.radStick, ClampRegion.minStick); - ClampCircle(&status->substickX, &status->substickY, ClampRegion.radSubstick, ClampRegion.minSubstick); - ClampTrigger(&status->triggerLeft, ClampRegion.minTrigger, ClampRegion.maxTrigger); - ClampTrigger(&status->triggerRight, ClampRegion.minTrigger, ClampRegion.maxTrigger); - } - } -} diff --git a/src/dolphin/perf/__perf.h b/src/dolphin/perf/__perf.h deleted file mode 100644 index 0257b57..0000000 --- a/src/dolphin/perf/__perf.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _DOLPHIN_PERF_INTERNAL_H_ -#define _DOLPHIN_PERF_INTERNAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void __PERFDrawInit(void (*id)()); - -#ifdef __cplusplus -} -#endif - -#endif // _DOLPHIN_PERF_INTERNAL_H_ diff --git a/src/dolphin/perf/perf.c b/src/dolphin/perf/perf.c deleted file mode 100644 index 7ad66a7..0000000 --- a/src/dolphin/perf/perf.c +++ /dev/null @@ -1,467 +0,0 @@ -#include -#include -#include -#include "fake_tgmath.h" - -#include "__perf.h" -#include "../gx/__gx.h" - -#if DEBUG -const char* __PERFVersion = "<< Dolphin SDK - PERF\tdebug build: Apr 5 2004 03:57:10 (0x2301) >>"; -#else -const char* __PERFVersion = "<< Dolphin SDK - PERF\trelease build: Apr 5 2004 04:15:51 (0x2301) >>"; -#endif - -#define TOKEN_MAX 0xFFFF - -static OSAlarm PERFAlarm; - -static volatile s32 CurrAutoSample = 0xFFFFFFFF; -static volatile u32 CurrToken = 0x0000FFFF; - -static volatile u8 magic; -static void* (*PerfAlloc)(u32); -static void (*PerfFree)(void*); -static void (*DSCB)(u16); -u32 PERFNumFrames; -u32 PERFNumEvents; -u32 PERFNumSamples; -Frame* PERFFrames; -PerfEvent* PERFEvents; -u32 PERFCurrFrame; -volatile s32 PERFCurrSample; - -// prototypes -static void PERFResetAllMemMetrics(void); -static void PERFGetAllMemMetrics(PerfSample* s, u32 i); -void PERFSetDrawSyncCallback(void (*cb)(u16)); -static void PERFTokenCallback(u16 token); -u32 PERFInit(u32 numSamples, u32 numFramesHistory, u32 numTypes, PERFAllocator allocator, PERFDeallocator deallocator, void (*initDraw)()); -void PERFSetEvent(u8 id, char* name, PerfType type); -void PERFSetEventColor(u8 id, GXColor color); -void PERFStartFrame(void); -void PERFEndFrame(void); -void PERFEventStart(u8 id); -__declspec(weak) s32 PERFGetNewSample(void); -void PERFEventEnd(u8 id); -static void PERFStartAutoSample(void); -static void PERFEndAutoSample(void); -static void PERFTimerCallback(OSAlarm* alarm, OSContext* context); -void PERFStartAutoSampling(f32 msInterval); -void PERFStopAutoSampling(void); - -#ifndef DEBUG -inline s32 PERFGetNewSample(void) { - if (PERFCurrSample >= (PERFNumSamples - 1)) { - PERFCurrSample = PERFNumSamples - 1; - return PERFCurrSample; - } - return PERFCurrSample++; -} -#endif - -static void PERFResetAllMemMetrics(void) { - ((u16*)__memReg)[25] = 0; - ((u16*)__memReg)[26] = 0; - ((u16*)__memReg)[27] = 0; - ((u16*)__memReg)[28] = 0; - ((u16*)__memReg)[30] = 0; - ((u16*)__memReg)[29] = 0; - ((u16*)__memReg)[32] = 0; - ((u16*)__memReg)[31] = 0; - ((u16*)__memReg)[34] = 0; - ((u16*)__memReg)[33] = 0; - ((u16*)__memReg)[36] = 0; - ((u16*)__memReg)[35] = 0; - ((u16*)__memReg)[38] = 0; - ((u16*)__memReg)[37] = 0; - ((u16*)__memReg)[40] = 0; - ((u16*)__memReg)[39] = 0; - ((u16*)__memReg)[42] = 0; - ((u16*)__memReg)[41] = 0; - ((u16*)__memReg)[44] = 0; - ((u16*)__memReg)[43] = 0; -} - -static void PERFGetAllMemMetrics(PerfSample* s, u32 i) { - u32 ctrl; - u32 ctrh; - - GXReadXfRasMetric(&s->xfWaitIn[i], &s->xfWaitOut[i], &s->rasBusy[i], &s->rasClocks[i]); - - ctrl = ((u16*)__memReg)[26]; - ctrh = ((u16*)__memReg)[25]; - s->cpReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[28]; - ctrh = ((u16*)__memReg)[27]; - s->tcReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[30]; - ctrh = ((u16*)__memReg)[29]; - s->cpuRdReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[32]; - ctrh = ((u16*)__memReg)[31]; - s->cpuWrReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[34]; - ctrh = ((u16*)__memReg)[33]; - s->dspReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[36]; - ctrh = ((u16*)__memReg)[35]; - s->ioReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[38]; - ctrh = ((u16*)__memReg)[37]; - s->viReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[40]; - ctrh = ((u16*)__memReg)[39]; - s->peReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[42]; - ctrh = ((u16*)__memReg)[41]; - s->rfReq[i] = ((ctrh << 0x10) | ctrl); - - ctrl = ((u16*)__memReg)[44]; - ctrh = ((u16*)__memReg)[43]; - s->fiReq[i] = ((ctrh << 0x10) | ctrl); -} - -void PERFSetDrawSyncCallback(void (*cb)(u16)) { - DSCB = cb; -} - -static void PERFTokenCallback(u16 token) { - s32 sample; - - if ((token < 0xE000) || (((int)((u32)token >> 8) & 0xF) != magic) || (PERFCurrSample == 0)) { - if (DSCB) { - DSCB(token); - } - } else { - if (token >= 0xF000) { - if (CurrToken == TOKEN_MAX) { - ASSERTLINE(341, CurrAutoSample >= 0); - PERFEndAutoSample(); - PERFStartAutoSample(); - return; - } - - sample = (u8)(u32)token; - if ((u8)(u16)CurrToken != sample) { - sample = (u8)(u16)CurrToken; - } - - ASSERTLINE(357, sample < PERFCurrSample); - - PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = PPCMfpmc4(); - PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[1] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[sample].instructions[1] = PPCMfpmc1(); - PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 1); - if (CurrAutoSample >= 0) { - ASSERTLINE(369, CurrToken == TOKEN_MAX); - PERFEndAutoSample(); - } - CurrToken = 0xFFFF; - PERFStartAutoSample(); - return; - } - - if (CurrToken < 0xFFFF) { - ASSERTLINE(384, CurrAutoSample < 0); - sample = (u8)(u16)CurrToken; - PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = PPCMfpmc4(); - PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[1] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[sample].instructions[1] = PPCMfpmc1(); - PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 1); - } else { - ASSERTLINE(394, CurrAutoSample >= 0); - PERFEndAutoSample(); - } - - sample = (u8)(u32)token; - PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); - PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = PERFFrames[PERFCurrFrame].samples[sample].origgpStart = PPCMfpmc4(); - PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 0); - CurrToken = (u32)(u16)token; - } -} - -u32 PERFInit(u32 numSamples, u32 numFramesHistory, u32 numTypes, PERFAllocator allocator, PERFDeallocator deallocator, void (*initDraw)()) { - u32 i; - u32 size; - - OSRegisterVersion(__PERFVersion); - - PerfAlloc = allocator; - PerfFree = deallocator; - PERFNumFrames = numFramesHistory; - PERFNumEvents = numTypes; - PERFNumSamples = numSamples; - - size = (numFramesHistory * 0x10); - size += (numFramesHistory * (numSamples * 0xB0)); - size += (numTypes* 0x10); - - PERFFrames = (Frame*)PerfAlloc(numFramesHistory * 0x10); - - for (i = 0; i < PERFNumFrames; i++) { - PERFFrames[i].samples = (PerfSample *)PerfAlloc(numSamples* 0xB0); - PERFFrames[i].lastSample = 0; - } - - PERFEvents = (PerfEvent *)PerfAlloc(numTypes* 0x10); - - for (i = 0; i < numTypes; i++) { - PERFEvents[i].name = 0; - PERFEvents[i].currSample = -1; - } - - __PERFDrawInit(initDraw); - GXSetDrawSyncCallback(PERFTokenCallback); - GXInitXfRasMetric(); - return size; -} - -void PERFSetEvent(u8 id, char* name, PerfType type) { - GXColor def = {0xFF, 0x19, 0x00, 0xC8}; - - PERFEvents[id].name = name; - PERFEvents[id].type = type; - PERFEvents[id].currSample = -1; - PERFEvents[id].color = def; -} - -void PERFSetEventColor(u8 id, GXColor color) { - PERFEvents[id].color = color; -} - -void PERFStartFrame(void) { - BOOL enabled = OSDisableInterrupts(); - - PERFCurrSample = 0; - CurrToken = 0xFFFF; - GXSetDrawSyncCallback(PERFTokenCallback); - PERFFrames[PERFCurrFrame].lastSample = 0; - PERFResetAllMemMetrics(); - GXClearGPMetric(); - PPCMtpmc1(0); - PPCMtpmc2(0); - PPCMtpmc3(0); - PPCMtpmc4(0); - PPCMtmmcr0(0x8B); - PPCMtmmcr1(0x78400000); - PERFStartAutoSample(); - OSRestoreInterrupts(enabled); -} - -void PERFEndFrame(void) { - u32 i; - BOOL enabled; - - enabled = OSDisableInterrupts(); - PERFEndAutoSample(); - GXSetDrawSyncCallback(DSCB); - PERFFrames[PERFCurrFrame].end = PPCMfpmc4(); - PERFFrames[PERFCurrFrame].lastSample = PERFCurrSample; - PERFFrames[PERFCurrFrame].cachemisscycles = PPCMfpmc3(); - PERFCurrFrame = (PERFCurrFrame + 1) % PERFNumFrames; - PERFCurrSample = 0; - - for (i = 0; i < PERFNumEvents; i++) { - PERFEvents[i].currSample = -1; - } - - magic += 1; - - if ((u8)magic >= 0x10) { - magic = 0; - } - - OSRestoreInterrupts(enabled); -} - -void PERFEventStart(u8 id) { - BOOL enabled; - s32 sample; - - enabled = OSDisableInterrupts(); - - sample = PERFEvents[id].currSample; - if (sample < 0) { - sample = PERFGetNewSample(); - PERFEvents[id].currSample = sample; - PERFFrames[PERFCurrFrame].samples[sample].id = id; - PERFFrames[PERFCurrFrame].samples[sample].interrupted = 0; - - switch(PERFEvents[id].type) { - case PERF_GP_EVENT: - PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = 0; - PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = 0; - PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = 0; - PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = 0; - GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x2000); - break; - case PERF_CPU_GP_EVENT: - PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = 0; - PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = 0; - PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); - GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x2000); - // fallthrough - case PERF_CPU_EVENT: - PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[2] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[sample].instructions[2] = PPCMfpmc1(); - PERFFrames[PERFCurrFrame].samples[sample].origcpuStart = PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampStart = PPCMfpmc4(); - PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampEnd = 0; - break; - default: - OSReport("PERF : Unknown event type for ID %d - possibly out of memory\n", id); - break; - } - } else { - OSReport("PERF : event is still open for CPU!\n"); - } - - OSRestoreInterrupts(enabled); -} - -#if DEBUG -__declspec(weak) s32 PERFGetNewSample(void) { - if (PERFCurrSample >= (PERFNumSamples - 1)) { - PERFCurrSample = PERFNumSamples - 1; - return PERFCurrSample; - } - return PERFCurrSample++; -} -#endif - -void PERFEventEnd(u8 id) { - BOOL enabled; - s32 sample; - - enabled = OSDisableInterrupts(); - sample = PERFEvents[id].currSample; - if (sample < 0) { - OSReport("PERF : ending an event that never started!\n"); - OSRestoreInterrupts(enabled); - return; - } - - switch(PERFEvents[id].type) { - case PERF_GP_EVENT: - GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x1000); - break; - case PERF_CPU_GP_EVENT: - GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x1000); - case PERF_CPU_EVENT: - PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampEnd = PPCMfpmc4(); - PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[3] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[sample].instructions[3] = PPCMfpmc1(); - break; - } - - PERFEvents[id].currSample = -1; - OSRestoreInterrupts(enabled); -} - -static void PERFStartAutoSample(void) { - CurrAutoSample = PERFGetNewSample(); - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].id = 0xFF; - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].interrupted = 0; - PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 0); - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampStart = PPCMfpmc4(); - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = 0; - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].cacheMisses[0] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].instructions[0] = PPCMfpmc1(); -} - -static void PERFEndAutoSample(void) { - if (CurrAutoSample >= 0) { - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = PPCMfpmc4(); - PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 1); - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].cacheMisses[1] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].instructions[1] = PPCMfpmc1(); - } - CurrAutoSample = -1; -} - -static void PERFTimerCallback(OSAlarm* alarm, OSContext* context) { - s32 sample; - s32 newsample; - - if (PERFCurrSample != 0) { - if (CurrToken < 0xFFFF) { - sample = (u8)(u16)CurrToken; - // stupid CurrToken loading AGAIN - if ((u8)((CurrToken >> 8) & 0xF) != (s32)magic) { - PERFEndAutoSample(); - PERFStartAutoSample(); - return; - } - - ASSERTLINE(884, CurrAutoSample < 0); - - newsample = PERFGetNewSample(); - memcpy(&PERFFrames[PERFCurrFrame].samples[newsample], &PERFFrames[PERFCurrFrame].samples[sample], 0xB0); - PERFFrames[PERFCurrFrame].samples[newsample].gpTimeStampEnd = PPCMfpmc4(); - PERFFrames[PERFCurrFrame].samples[newsample].cacheMisses[1] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[newsample].instructions[1] = PPCMfpmc1(); - PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[newsample], 1); - PERFFrames[PERFCurrFrame].samples[newsample].id = 0xFF; - PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = PPCMfpmc4(); - PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); - PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); - PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 0); - PERFFrames[PERFCurrFrame].samples[sample].interrupted = 1; - CurrAutoSample = -1; - return; - } - - if (CurrAutoSample < 0) { - OSReport("PERF : AUTOSAMPLE < 0!!!! SHOULD NEVER HAPPEN!\n"); - return; - } - - PERFEndAutoSample(); - PERFStartAutoSample(); - } -} - -void PERFStartAutoSampling(f32 msInterval) { - OSSetPeriodicAlarm(&PERFAlarm, OSGetTime(), (u32)OSMillisecondsToTicks(msInterval), PERFTimerCallback); -} - -void PERFStopAutoSampling(void) { - BOOL enabled = OSDisableInterrupts(); - - if (CurrAutoSample >= 0) { - PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = PPCMfpmc4(); - PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 1); - } - - OSCancelAlarm(&PERFAlarm); - OSRestoreInterrupts(enabled); -} - -void PERFShutDown(void) { - BOOL enabled; - u32 i; - - enabled = OSDisableInterrupts(); - PERFStopAutoSampling(); - PERFEndAutoSample(); - GXSetDrawSyncCallback(DSCB); - - for (i = 0; i < PERFNumFrames; i++) { - PerfFree(PERFFrames[i].samples); - } - - PerfFree(PERFEvents); - PerfFree(PERFFrames); - OSRestoreInterrupts(enabled); -} diff --git a/src/dolphin/perf/perfdraw.c b/src/dolphin/perf/perfdraw.c deleted file mode 100644 index 036e918..0000000 --- a/src/dolphin/perf/perfdraw.c +++ /dev/null @@ -1,695 +0,0 @@ -#include -#include -#include "fake_tgmath.h" - -#include "__perf.h" - -__declspec(weak) f32 HEIGHT(u32 a, f32 f); -__declspec(weak) f32 COORD(u32 a); - -// internal macro for Perfdraw. -#define DRAW_RECT(x1, x2, y1, y2, color) \ - do { \ - GXSetChanMatColor(GX_COLOR0A0, color); \ - GXBegin(GX_QUADS, GX_VTXFMT0, 4); \ - GXPosition3f32((x1), (y1), -1.0f); \ - GXPosition3f32((x1), (y2), -1.0f); \ - GXPosition3f32((x2), (y2), -1.0f); \ - GXPosition3f32((x2), (y1), -1.0f); \ - GXEnd(); \ - } while(0) - -static u32 DrawFrameMax; -static f32 DrawFrameH; -static u32 MaxBusTransactions; - -static u32 DrawNumFrames = 3; -static f32 DrawFrameW = 205.33333f; -static GXColor DrawFrameBGColor = { 0xC8, 0xC8, 0xC8, 0xC8 }; -static GXColor DrawFrameColor = { 0x19, 0x19, 0x19, 0xC8 }; -static GXColor DrawCPUColor = { 0xFF, 0x19, 0x00, 0xC8 }; -static GXColor DrawFullColor = { 0xFF, 0x00, 0xFF, 0xC8 }; -static GXColor DrawGPColor = { 0x00, 0x64, 0xFF, 0xC8 }; -static GXColor DrawCPUCacheColor = { 0x00, 0x96, 0x00, 0xC8 }; -static GXColor DrawConnectColor = { 0x00, 0x00, 0x00, 0xC8 }; -static GXColor DrawBWBarColor = { 0x32, 0x32, 0x32, 0xC8 }; -static GXColor DrawIPCBarColor = { 0x00, 0x00, 0x5A, 0xAA }; -static GXColor DrawGPUBarColor = { 0x5A, 0x00, 0x00, 0xAA }; -static GXColor DrawIPCColor = { 0xC8, 0x64, 0x00, 0xAA }; -static GXColor DrawCPColor = { 0xC8, 0x00, 0xC8, 0xC8 }; -static GXColor DrawTCColor = { 0x00, 0xC8, 0x00, 0xC8 }; -static GXColor DrawCPURDColor = { 0xFF, 0xFF, 0x00, 0xC8 }; -static GXColor DrawCPUWRColor = { 0x00, 0x64, 0x64, 0xC8 }; -static GXColor DrawDSPColor = { 0xC8, 0x00, 0x00, 0xC8 }; -static GXColor DrawIOColor = { 0x96, 0x96, 0x32, 0xC8 }; -static GXColor DrawVIColor = { 0xFF, 0xFF, 0xFF, 0xC8 }; -static GXColor DrawPEColor = { 0x00, 0x00, 0xC8, 0xC8 }; -static GXColor DrawRFColor = { 0x00, 0xFF, 0xFF, 0xC8 }; -static GXColor DrawFIColor = { 0xC8, 0x64, 0x64, 0xC8 }; -static GXColor DrawGPXFIColor = { 0x00, 0xC8, 0x00, 0xAA }; -static GXColor DrawGPXFOColor = { 0x00, 0x00, 0xC8, 0xAA }; -static GXColor DrawGPRASIDLEColor = { 0xC8, 0xC8, 0x00, 0xAA }; - -static BOOL bDrawBWBar = TRUE; -static BOOL bDrawCPUBar = TRUE; -static BOOL bDrawXFBars = TRUE; -static BOOL bDrawRASBar = TRUE; -static BOOL bAutoScale = TRUE; - -static BOOL bDrawBWBarKey; -static f32 lastx; - -static f32 FramePts[28] = { - 0.0f, - 0.0f, - 0.0f, - 10.0f, - 0.0f, - 0.0f, - 616.0f, - 0.0f, - 616.0f, - 0.0f, - 616.0f, - 10.0f, - 0.0f, - 10.0f, - 616.0f, - 10.0f, - 205.33333f, - 0.0f, - 205.33333f, - 10.0f, - 410.66666f, - 0.0f, - 410.66666f, - 10.0f, - 616.0f, - 0.0f, - 616.0f, - 10.0f, -}; - -static f32 CPUPts[4] = { - 0.0f, - 0.0f, - 616.0f, - 0.0f, -}; - -static f32 GPPts[4] = { - 0.0f, - 0.0f, - 616.0f, - 0.0f, -}; - -void (*GameDrawInit)(); -Mtx mID; - -#ifndef DEBUG -inline f32 HEIGHT(u32 a, f32 f) { - return 140.0f * ((f32) a / ((f32) MaxBusTransactions * f)); -} - -inline f32 COORD(u32 a) { - return 616.0f * ((f32) a / (f32) DrawFrameMax); -} -#endif - -void __PERFDrawInit(void (*id)()) { - MTXIdentity(mID); - GameDrawInit = id; - DrawFrameMax = (OS_CORE_CLOCK / 60) * 3; - DrawFrameH = (PERFNumEvents + 1) * 7; - MaxBusTransactions = (OS_BUS_CLOCK / 120); - FramePts[3] = FramePts[11] = FramePts[13] = FramePts[15] = FramePts[19] = FramePts[23] = DrawFrameH; - FramePts[6] = FramePts[8] = FramePts[10] = FramePts[14] = 616.0f; - GPPts[1] = (PERFNumEvents + 2) * 19; - GPPts[3] = GPPts[1]; -} - -static Mtx44 mProj; -f32 pSave[7]; - -void PERFPreDraw(void) { - u32 i; - u32 j; - - GXGetProjectionv(pSave); - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - mProj[i][j] = 0.0f; - } - } - - mProj[0][0] = 0.003125f; - mProj[1][1] = 0.004166667f; - mProj[2][2] = 1.0f; - mProj[3][3] = 1.0f; - mProj[0][3] = -0.95f; - mProj[1][3] = -0.87500005f; - - GXSetProjection(mProj, GX_ORTHOGRAPHIC); - GXClearVtxDesc(); - GXInvalidateVtxCache(); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); - GXSetZCompLoc(GX_FALSE); - GXSetNumChans(1); - GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); - GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GXSetNumTexGens(0); - GXSetNumTevStages(1); - GXSetZMode(GX_DISABLE, GX_ALWAYS, GX_DISABLE); - GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_TEX_ST, GX_RGBA6, 0); -} - -static void DrawBWBar(PerfSample* s) { - u32 delta; - u32 interval; - f32 bwscale; - f32 lastY; - f32 x1; - f32 x2; - f32 height; - u32 rasclocks; - u32 rasBusy; - u32 xfI; - u32 xfO; - u32 instructions; - f32 ipc; - f32 ipcscale; - u32 misses; - - interval = s->gpTimeStampEnd - s->gpTimeStampStart; - bwscale = (f32)interval / (OS_CORE_CLOCK / 60); - lastY = 7.0f + DrawFrameH; - x1 = COORD(s->gpTimeStampStart); - x2 = COORD(s->gpTimeStampEnd); - if (fabs(lastx - x1) < 1.0f) { - x1 = lastx; - } - lastx = x2; - - // Draw BW Bars if toggled - if (bDrawBWBar) { - delta = s->cpReq[1] - s->cpReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPColor); - lastY += height; - } - delta = s->tcReq[1] - s->tcReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawTCColor); - lastY += height; - } - delta = s->cpuRdReq[1] - s->cpuRdReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPURDColor); - lastY += height; - } - delta = s->cpuWrReq[1] - s->cpuWrReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPUWRColor); - lastY += height; - } - delta = s->dspReq[1] - s->dspReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawDSPColor); - lastY += height; - } - delta = s->ioReq[1] - s->ioReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawIOColor); - lastY += height; - } - delta = s->viReq[1] - s->viReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawVIColor); - lastY += height; - } - delta = s->peReq[1] - s->peReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawPEColor); - lastY += height; - } - delta = s->rfReq[1] - s->rfReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawRFColor); - lastY += height; - } - s->fiReq[0] /= 2; - s->fiReq[1] /= 2; - delta = s->fiReq[1] - s->fiReq[0]; - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawFIColor); - } - } - - if (bDrawCPUBar) { - instructions = s->instructions[1] - s->instructions[0]; - ipc = (f32)instructions / (f32) interval; - ipcscale = ipc / 2.0f; - misses = s->cacheMisses[1] - s->cacheMisses[0]; - lastY = 7.0f + (140.0f + (7.0f + DrawFrameH)); - height = ipcscale * 50.0f; - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawIPCColor); - } - height = (50.0f * (f32) misses) / (f32) interval; - DRAW_RECT(x1, x2, (50.0f + lastY) - height, (50.0f + lastY), DrawCPUCacheColor); - } - - rasclocks = s->rasClocks[1] - s->rasClocks[0]; - - if (bDrawXFBars) { - lastY = 14.0f + (50.0f + (140.0f + (7.0f + DrawFrameH))); - xfI = s->xfWaitIn[1] - s->xfWaitIn[0]; - xfO = s->xfWaitOut[1] - s->xfWaitOut[0]; - if (rasclocks >= (u32) (xfO + xfI)) { - xfI = rasclocks - (xfO + xfI); - height = (50.0f * xfI) / rasclocks; - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawGPXFIColor); - } - } - } - - if (bDrawRASBar) { - lastY = 50.0f + (21.0f + (50.0f + (140.0f + (7.0f + DrawFrameH)))); - rasBusy = s->rasBusy[1] - s->rasBusy[0]; - height = (50.0f * (f32)rasBusy) / rasclocks; - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawGPRASIDLEColor); - } - } -} - -#if DEBUG -__declspec(weak) f32 HEIGHT(u32 a, f32 f) { - return 140.0f * ((f32) a / ((f32) MaxBusTransactions * f)); -} - -__declspec(weak) f32 COORD(u32 a) { - return 616.0f * ((f32) a / (f32) DrawFrameMax); -} -#endif - -static void DrawKey(void) { - u32 delta; - u32 foo[2]; - f32 bwscale; - f32 lastY; - f32 x1; - f32 x2; - f32 height; - - x1 = 595.4667f; - x2 = 616.0f; - lastY = 7.0f + DrawFrameH; - bwscale = 1.0f; - foo[0] = 0; - foo[1] = MaxBusTransactions / 10; - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawTCColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPURDColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPUWRColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawDSPColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawIOColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawVIColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawPEColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawRFColor); - lastY += height; - } - - delta = (foo[1] - foo[0]); - height = HEIGHT(delta, bwscale); - if (height > 1.0f) { - DRAW_RECT(x1, x2, lastY, lastY + height, DrawFIColor); - lastY += height; - } -} - -void PERFDumpScreen(void) { - PerfSample* samples; - u32 s; - u32 id; - u32 i; - u32 delta; - u32 e; - f32 c; - f32 lastY; - f32 allX; - f32 xcoord; - - if (GameDrawInit) { - samples = PERFFrames[PERFCurrFrame].samples; - - if (bAutoScale) { - DrawNumFrames = PERFFrames[PERFCurrFrame].end / (OS_CORE_CLOCK / 60) + 1; - } - - DrawFrameMax = (OS_CORE_CLOCK / 60) * DrawNumFrames; - DrawFrameW = 616.0f / DrawNumFrames; - allX = COORD(PERFFrames[PERFCurrFrame].end); - GXLoadPosMtxImm(mID, 0); - DRAW_RECT(0.0f, 616.0f, 0.0f, DrawFrameH, DrawFrameBGColor); - GXSetChanMatColor(GX_COLOR0A0, DrawFrameColor); - GXSetLineWidth(0xCU, GX_TO_ZERO); - - // different draw shape? Consider other forms of this draw macro that may work. If anything will work. - GXBegin(GX_LINES, GX_VTXFMT0, 8); - GXPosition3f32(FramePts[0], FramePts[1], -1.0f); - GXPosition3f32(FramePts[2], FramePts[3], -1.0f); - GXPosition3f32(FramePts[4], FramePts[5], -1.0f); - GXPosition3f32(FramePts[6], FramePts[7], -1.0f); - GXPosition3f32(FramePts[8], FramePts[9], -1.0f); - GXPosition3f32(FramePts[10], FramePts[11], -1.0f); - GXPosition3f32(FramePts[12], FramePts[13], -1.0f); - GXPosition3f32(FramePts[14], FramePts[15], -1.0f); - GXEnd(); - - if (DrawNumFrames > 1) { - GXBegin(GX_LINES, GX_VTXFMT0, (DrawNumFrames - 1) * 2); - for(i = 1; i < DrawNumFrames; i++) { - xcoord = COORD(i * (OS_CORE_CLOCK / 60)); - GXPosition3f32(xcoord, FramePts[17], -1.0f); - GXPosition3f32(xcoord, FramePts[19], -1.0f); - } - GXEnd(); - } - - GXSetChanMatColor(GX_COLOR0A0, DrawFullColor); - GXSetLineWidth(0x20U, GX_TO_ZERO); - - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(0.0f, 0.0f, -1.0f); - GXPosition3f32(allX, 0.0f, -1.0f); - GXEnd(); - - GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); - - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(0.0f, 0.0f, -1.0f); - GXPosition3f32(COORD(PERFFrames[PERFCurrFrame].cachemisscycles), 0.0f, -1.0f); - GXEnd(); - - if (bDrawBWBar) { - lastY = 7.0f + DrawFrameH; - GXSetChanMatColor(GX_COLOR0A0, DrawBWBarColor); - - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - GXPosition3f32(0.0f, lastY, -1.0f); - GXPosition3f32(0.0f, 140.0f + lastY, -1.0f); - GXPosition3f32(allX, 140.0f + lastY, -1.0f); - GXPosition3f32(allX, lastY, -1.0f); - GXEnd(); - } - - if (bDrawCPUBar) { - lastY = 7.0f + (140.0f + (7.0f + DrawFrameH)); - GXSetChanMatColor(GX_COLOR0A0, DrawIPCBarColor); - - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - GXPosition3f32(0.0f, lastY, -1.0f); - GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); - GXPosition3f32(allX, 50.0f + lastY, -1.0f); - GXPosition3f32(allX, lastY, -1.0f); - GXEnd(); - GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); - GXSetLineWidth(6, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(0.0f, 25.0f + lastY, -1.0f); - GXPosition3f32(allX, 25.0f + lastY, -1.0f); - GXEnd(); - } - - if (bDrawXFBars) { - lastY = 14.0f + (50.0f + (140.0f + (7.0f + DrawFrameH))); - GXSetChanMatColor(GX_COLOR0A0, DrawGPUBarColor); - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - GXPosition3f32(0.0f, lastY, -1.0f); - GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); - GXPosition3f32(allX, 50.0f + lastY, -1.0f); - GXPosition3f32(allX, lastY, -1.0f); - GXEnd(); - } - - if (bDrawRASBar) { - lastY = 50.0f + (21.0f + (50.0f + (140.0f + (7.0f + DrawFrameH)))); - GXSetChanMatColor(GX_COLOR0A0, DrawGPUBarColor); - GXBegin(GX_QUADS, GX_VTXFMT0, 4); - GXPosition3f32(0.0f, lastY, -1.0f); - GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); - GXPosition3f32(allX, 50.0f + lastY, -1.0f); - GXPosition3f32(allX, lastY, -1.0f); - GXEnd(); - } - - for (s = 0; s < PERFFrames[PERFCurrFrame].lastSample; s++) { - id = samples[s].id; - if (id == 0xFF) { - DrawBWBar(&samples[s]); - } else { - switch(PERFEvents[id].type) { - case PERF_CPU_GP_EVENT: - GXSetChanMatColor(GX_COLOR0A0, PERFEvents[id].color); - GXSetLineWidth(32, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); - GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); - GXEnd(); - delta = samples[s].cacheMisses[3] - samples[s].cacheMisses[2]; - if (delta) { - e = delta + samples[s].cpuTimeStampStart; - c = COORD(e); - GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); - GXPosition3f32(c, (f32) ((id + 1) * 7), -1.0f); - GXEnd(); - } - - if (samples[s].gpTimeStampEnd != 0) { - if (!samples[s].interrupted) { - GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); - GXSetLineWidth(32, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); - GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); - GXEnd(); - - DrawBWBar(&samples[s]); - - GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); - GXSetLineWidth(6, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 4); - GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); - GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); - GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); - GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); - GXEnd(); - } else { - GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); - GXSetLineWidth(32, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); - GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); - GXEnd(); - - DrawBWBar(&samples[s]); - - GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); - GXSetLineWidth(6, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 4); - GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); - GXPosition3f32(COORD(samples[s].origcpuStart), (f32) ((id + 1) * 7), -1.0f); - GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); - GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); - GXEnd(); - } - } - break; - case PERF_CPU_EVENT: - GXSetChanMatColor(GX_COLOR0A0, PERFEvents[id].color); - GXSetLineWidth(32, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - !samples[s].cpuTimeStampStart; // needed to match - GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); - GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); - GXEnd(); - - delta = samples[s].cacheMisses[3] - samples[s].cacheMisses[2]; - if (delta != 0) { - e = delta + samples[s].cpuTimeStampStart; - c = COORD(e); - GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); - GXPosition3f32(c, (f32) ((id + 1) * 7), -1.0f); - GXEnd(); - } - break; - case PERF_GP_EVENT: - if (samples[s].interrupted == 0) { - GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); - GXSetLineWidth(32, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); - GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); - GXEnd(); - DrawBWBar(&samples[s]); - } else { - GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); - GXSetLineWidth(32, GX_TO_ZERO); - GXBegin(GX_LINES, GX_VTXFMT0, 2); - GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); - GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); - GXEnd(); - DrawBWBar(&samples[s]); - } - break; - } - } - } - - if (bDrawBWBarKey) { - DrawKey(); - } - } -} - -void PERFPostDraw(void) { - u32 i; - u32 j; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - mProj[i][j] = 0.0f; - } - } - - mProj[0][0] = pSave[1]; - mProj[0][2] = pSave[2]; - mProj[1][1] = pSave[3]; - mProj[1][2] = pSave[4]; - mProj[2][2] = pSave[5]; - mProj[2][3] = pSave[6]; - mProj[3][2] = -1.0f; - GXSetProjection(mProj, GX_PERSPECTIVE); - GameDrawInit(); -} - -void PERFSetDrawBWBarKey(BOOL tf) { - bDrawBWBarKey = tf; -} - -void PERFSetDrawBWBar(BOOL tf) { - bDrawBWBar = tf; -} - -void PERFSetDrawCPUBar(BOOL tf) { - bDrawCPUBar = tf; -} - -void PERFSetDrawXFBars(BOOL tf) { - bDrawXFBars = tf; -} - -void PERFSetDrawRASBar(BOOL tf) { - bDrawRASBar = tf; -} - -void PERFToggleDrawBWBarKey(void) { - bDrawBWBarKey = (bDrawBWBarKey) ? FALSE : TRUE; -} - -void PERFToggleDrawBWBar(void) { - bDrawBWBar = (bDrawBWBar) ? FALSE : TRUE; -} - -void PERFToggleDrawCPUBar(void) { - bDrawCPUBar = (bDrawCPUBar) ? FALSE : TRUE; -} - -void PERFToggleDrawXFBars(void) { - bDrawXFBars = (bDrawXFBars) ? FALSE : TRUE; -} - -void PERFToggleDrawRASBar(void) { - bDrawRASBar = (bDrawRASBar) ? FALSE : TRUE; -} - -void PERFSetDrawFrames(u32 frames) { - if (frames != 0) { - DrawNumFrames = frames; - bAutoScale = FALSE; - } else { - bAutoScale = TRUE; - } -} diff --git a/src/dolphin/seq/seq.c b/src/dolphin/seq/seq.c deleted file mode 100644 index 582a323..0000000 --- a/src/dolphin/seq/seq.c +++ /dev/null @@ -1,468 +0,0 @@ -#include -#include - -static u8 __SEQMidiEventLength[128] = { - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - 0x00, 0x00, 0x02, 0x01, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -static SEQSEQUENCE* __SEQSequenceList; - -// prototypes -static void __SEQPushSequenceList(SEQSEQUENCE* sequence); -static void __SEQRemoveSequenceFromList(SEQSEQUENCE* sequence); -static u32 __SEQGetIntTrack(SEQTRACK* track); -static void __SEQHandleSysExEvent(SEQTRACK* track); -static void __SEQSetTicksPerFrame(SEQTRACK* track, f32 bps); -static void __SEQTempoMetaEvent(SEQTRACK* track); -static void __SEQTrackEnd(SEQTRACK* track); -static void __SEQHandleMetaEvent(SEQTRACK* track); -static void __SEQHandleSynthEvent(SYNSYNTH* synth, SEQTRACK* track); -static void __SEQRunEvent(SYNSYNTH* synth, SEQTRACK* track); -static void __SEQInitTracks(SEQSEQUENCE* sequence, u8* read, int tracks); -static void __SEQReadHeader(SEQSEQUENCE* sequence, u8* midiStream); - -static void __SEQPushSequenceList(SEQSEQUENCE* sequence) { - BOOL old; - - old = OSDisableInterrupts(); - if (__SEQSequenceList) { - sequence->next = __SEQSequenceList; - } else { - sequence->next = NULL; - } - - __SEQSequenceList = sequence; - OSRestoreInterrupts(old); -} - -static void __SEQRemoveSequenceFromList(SEQSEQUENCE* sequence) { - BOOL old; - SEQSEQUENCE* thisSequence; - SEQSEQUENCE* next; - - old = OSDisableInterrupts(); - thisSequence = __SEQSequenceList; - __SEQSequenceList = NULL; - - while(thisSequence) { - next = thisSequence->next; - if (thisSequence != sequence) { - __SEQPushSequenceList(thisSequence); - } - thisSequence = next; - } - - OSRestoreInterrupts(old); -} - -static u32 __SEQGetIntTrack(SEQTRACK* track) { - u32 value; - - ASSERTLINE(120, track); - for (value = *track->current & 0x7F; *track->current & 0x80; value = (value << 7) + (*track->current & 0x7F)) { - track->current++; - } - track->current++; - return value; -} - -static void __SEQHandleSysExEvent(SEQTRACK* track) { - u32 length; - - ASSERTLINE(143, track); - length = __SEQGetIntTrack(track); - track->current += length; -} - -static void __SEQSetTicksPerFrame(SEQTRACK* track, f32 bps) { - SEQSEQUENCE* sequence; - - ASSERTLINE(157, track); - sequence = track->sequence; - track->beatsPerSec = bps; - track->ticksPerFrame = (65536.0f * (160.0f / ((32000.0f / bps) / sequence->timeFormat))); -} - -static void __SEQTempoMetaEvent(SEQTRACK* track) { - u32 data; - f32 beatsPerSec; - - data = *track->current; - track->current++; - - data = (data << 8) + *track->current; - track->current++; - - data = (data << 8) + *track->current; - track->current++; - - beatsPerSec = 1000000 / (f32)data; - __SEQSetTicksPerFrame(track, beatsPerSec); -} - -static void __SEQTrackEnd(SEQTRACK* track) { - SEQSEQUENCE* sequence; - ASSERTLINE(199, track); - - sequence = track->sequence; - sequence->tracksRunning--; - track->state = 0; - if (sequence->tracksRunning == 0) { - sequence->end = 1; - } -} - -static void __SEQHandleMetaEvent(SEQTRACK* track) { - u8 type; - u32 length; - - ASSERTLINE(218, track); - type = *track->current; - track->current++; - - switch(type) { - case 0x2F: - __SEQTrackEnd(track); - return; - case 0x51: - length = __SEQGetIntTrack(track); - __SEQTempoMetaEvent(track); - return; - default: - length = __SEQGetIntTrack(track); - track->current += length; - return; - } -} - -static void __SEQHandleSynthEvent(SYNSYNTH* synth, SEQTRACK* track) { - u8 ch[3]; - u32 bytes; - void (*callback)(void *, u8); - - bytes = __SEQMidiEventLength[track->status - 0x80]; - ch[0] = track->status; - - switch(bytes) { - case 0: - break; - case 1: - ch[1] = *track->current; track->current++; - break; - case 2: - ch[1] = *track->current; track->current++; - ch[2] = *track->current; track->current++; - break; - } - - if ((ch[0] & 0xF0) == 0xB0) { - callback = ((SEQSEQUENCE*)track->sequence)->callback[ch[1]]; - if (callback) { - callback(track, ch[1]); - } - } - - SYNMidiInput(synth, ch); -} - -static void __SEQRunEvent(SYNSYNTH* synth, SEQTRACK* track) { - u8 event; - - ASSERTLINE(303, synth); - ASSERTLINE(304, track); - - event = *track->current; - if (event >= 0x80) { - track->status = event; track->current++; - } - - switch(track->status) { - case 0xF7: - case 0xF0: - __SEQHandleSysExEvent(track); - break; - case 0xFF: - __SEQHandleMetaEvent(track); - break; - default: - __SEQHandleSynthEvent(synth, track); - break; - } - - if (track->current >= track->end) { - __SEQTrackEnd(track); - } -} - -static void __SEQInitTracks(SEQSEQUENCE* sequence, u8* read, int tracks) { - int i; - u8* p; - u32 chunk; - u32 bytes; - SEQTRACK* track; - - i = 0; - p = read; - - while (tracks) { - while (1) { - chunk = *(u32*)p; - p += 4; - bytes = *(u32*)p; - p += 4; - if (chunk == 'MTrk') { - track = &sequence->track[i]; - track->sequence = sequence; - track->start = p; - track->end = &p[bytes]; - track->current = p; - track->defaultTicksPerFrame = (u32)(65536.0f * (160.0f / (16000.0f / (f32)sequence->timeFormat))); - track->state = 0; - p += bytes; - break; - } - p += bytes; - } - tracks--; - i++; - } -} - -static void __SEQReadHeader(SEQSEQUENCE* sequence, u8* midiStream) { - u8* read; - u32 bytes; - u32 fileType; - - read = midiStream; - ASSERTMSGLINE(401, *(u32*)read == 'MThd', "!!!midiStream is not a valid MIDI file\n!!!"); - read += 4; - - bytes = *(u32*)read; - read += 4; - - fileType = *(u16*)read; - read+=2; - - sequence->nTracks = *(u16*)read; - read+=2; - - sequence->timeFormat = *(s16*)read; - read+=2; - - ASSERTMSGLINE(416, sequence->timeFormat >= 0, "!!!SEQ does not support SMPTE time!!!\n"); - bytes -= 6; - read += bytes; - - switch(fileType) { - case 0: - sequence->nTracks = 1; - __SEQInitTracks(sequence, read, 1); - break; - case 1: - ASSERTMSGLINE(438, sequence->nTracks < 0x40, "exceeded SEQ_MAX_TRACKS, please increase SEQ_MAX_TRACKS\n"); - __SEQInitTracks(sequence, read, sequence->nTracks); - break; - default: - ASSERTMSGLINE(446, 0, "!!!Invalid MIDI file type\n!!!"); - break; - } - - sequence->tracksRunning = sequence->nTracks; -} - -void SEQInit(void) { - __SEQSequenceList = NULL; -} - -void SEQQuit(void) { - __SEQSequenceList = NULL; -} - -void SEQRunAudioFrame(void) { - SEQSEQUENCE* sequence; - u32 i; - SEQTRACK* track; - u32 ticks; - - for (sequence = __SEQSequenceList; sequence; sequence = sequence->next) { - if ((sequence->state == 1) || (sequence->state == 2)) { - for (i = 0; i < sequence->nTracks; i++) { - track = &sequence->track[i]; - if ((track->state == 1) || (track->state == 2)) { - ticks = track->ticksPerFrame; - if (track->delay > ticks) { - track->delay -= ticks; - } else { - while (ticks >= track->delay) { - ticks -= track->delay; - __SEQRunEvent(&sequence->synth, track); - if (track->state != 0) { - track->delay = __SEQGetIntTrack(track) << 0x10; - } else { - break; - } - } - - track->delay -= ticks; - } - } - } - } - - if (sequence->end != 0) { - if (sequence->state == 2) { - SEQSetState(sequence, 0); - SEQSetState(sequence, 2); - } else { - SEQSetState(sequence, 0); - } - } - } -} - -void SEQAddSequence(SEQSEQUENCE* sequence, u8* midiStream, void* wt, u32 aramBase, u32 zeroBase, u32 priorityVoiceAlloc, u32 priorityNoteOn, u32 priorityNoteRelease) { - int i; - - ASSERTLINE(559, sequence); - ASSERTLINE(560, midiStream); - ASSERTLINE(561, wt); - ASSERTLINE(562, aramBase); - ASSERTLINE(563, (priorityVoiceAlloc < 32) && (priorityVoiceAlloc > 0)); - ASSERTLINE(564, (priorityNoteOn < 32) && (priorityNoteOn > 0)); - ASSERTLINE(565, (priorityNoteRelease < 32) && (priorityNoteRelease > 0)); - - SYNInitSynth(&sequence->synth, wt, aramBase, zeroBase, priorityVoiceAlloc, priorityNoteOn, priorityNoteRelease); - sequence->state = 0; - - for(i = 0; i < 0x80; i++) { - sequence->callback[i] = 0; - } - - __SEQReadHeader(sequence, midiStream); - __SEQPushSequenceList(sequence); -} - -void SEQRemoveSequence(SEQSEQUENCE* sequence) { - ASSERTLINE(598, sequence); - __SEQRemoveSequenceFromList(sequence); - SYNQuitSynth(&sequence->synth); -} - -void SEQRegisterControllerCallback(SEQSEQUENCE* sequence, u8 controller, void (*callback)(void*, u8)) { - ASSERTLINE(617, sequence); - ASSERTLINE(618, controller < 128); - ASSERTLINE(619, callback); - sequence->callback[controller] = callback; -} - -void SEQSetState(SEQSEQUENCE* sequence, u32 state) { - int i; - - ASSERTLINE(632, sequence); - - switch(state) { - case 1: - case 2: - if (sequence->state == 0) { - int old; - - old = OSDisableInterrupts(); - for (i = 0; i < sequence->nTracks; i++) { - SEQTRACK* track = &sequence->track[i]; - track->current = track->start; - track->ticksPerFrame = track->defaultTicksPerFrame; - track->delay = __SEQGetIntTrack(track) << 0x10; - track->state = 1; - } - sequence->tracksRunning = sequence->nTracks; - OSRestoreInterrupts(old); - } - sequence->end = 0; - break; - case 0: - case 3: { - int old; - u8 ch[3]; - - for (i = 0; i < 16; i++) { - old = OSDisableInterrupts(); - ch[0] = (i | 0xB0); - ch[1] = 0x7B; - ch[2] = 0; - SYNMidiInput(&sequence->synth, ch); - OSRestoreInterrupts(old); - } - break; - } - } - - sequence->state = state; -} - -u32 SEQGetState(SEQSEQUENCE* sequence) { - ASSERTLINE(700, sequence); - return sequence->state; -} - -void SEQSetTempo(SEQSEQUENCE* sequence, u32 trackIndex, f32 bpm) { - int i; - - ASSERTLINE(711, sequence); - ASSERTLINE(712, (trackIndex < sequence->nTracks) || (trackIndex == SEQ_ALL_TRACKS)); - - if (trackIndex == -1) { - for (i = 0; i < sequence->nTracks; i++) { - __SEQSetTicksPerFrame(&sequence->track[i], bpm / 60.0f); - } - return; - } - - __SEQSetTicksPerFrame(&sequence->track[trackIndex], bpm / 60.0f); -} - -f32 SEQGetTempo(SEQSEQUENCE* sequence, u32 trackIndex) { - ASSERTLINE(733, sequence); - ASSERTLINE(734, trackIndex < sequence->nTracks); - return 60.0f* sequence->track[trackIndex].beatsPerSec; -} - -void SEQSetVolume(SEQSEQUENCE* sequence, s32 dB) { - ASSERTLINE(745, sequence); - SYNSetMasterVolume(&sequence->synth, dB); -} - -long SEQGetVolume(SEQSEQUENCE* sequence) { - ASSERTLINE(756, sequence); - SYNGetMasterVolume(&sequence->synth); -} diff --git a/src/dolphin/si/SIBios.c b/src/dolphin/si/SIBios.c deleted file mode 100644 index cc7164e..0000000 --- a/src/dolphin/si/SIBios.c +++ /dev/null @@ -1,798 +0,0 @@ -#include -#include - -#include "__os.h" - -#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) - -#ifdef DEBUG -const char* __SIVersion = "<< Dolphin SDK - SI\tdebug build: Apr 5 2004 03:55:31 (0x2301) >>"; -#else -const char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Apr 5 2004 04:14:16 (0x2301) >>"; -#endif - -static SIControl Si = { - /* chan */ -1, - /* poll */ 0, - /* inputBytes */ 0, - /* input */ NULL, - /* callback */ NULL -}; - -static SIPacket Packet[4]; -static OSAlarm Alarm[4]; -static u32 Type[4] = { SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE }; -static OSTime TypeTime[4]; -static OSTime XferTime[4]; -static SITypeCallback TypeCallback[4][4]; -static __OSInterruptHandler RDSTHandler[4]; -static BOOL InputBufferValid[4]; -static u32 InputBuffer[4][2]; -static volatile u32 InputBufferVcount[4]; - -u32 __PADFixBits; - -// prototypes -static u32 CompleteTransfer(); -static void SITransferNext(s32 chan); -static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context); -static int __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback); -static void AlarmHandler(OSAlarm* alarm, OSContext* context); -static void GetTypeCallback(s32 chan, u32 error, OSContext* context); -static int SIGetResponseRaw(s32 chan); - -BOOL SIBusy(void) { - return (Si.chan != -1) ? TRUE : FALSE; -} - -BOOL SIIsChanBusy(s32 chan) { - return Packet[chan].chan != -1 || Si.chan == chan; -} - -static void SIClearTCInterrupt(void) { - u32 reg; - - reg = __SIRegs[SI_COMCSR_IDX]; - reg |= SI_COMCSR_TCINT_MASK; - reg &= ~SI_COMCSR_TSTART_MASK; - __SIRegs[SI_COMCSR_IDX] = reg; -} - -static u32 CompleteTransfer(void) { - u32 sr; - u32 i; - u32 rLen; - u8* input; - u32 temp; - - sr = __SIRegs[SI_STATUS_IDX]; - SIClearTCInterrupt(); - - if (Si.chan != -1) { - XferTime[Si.chan] = __OSGetSystemTime(); - input = Si.input; - rLen = Si.inputBytes / sizeof(u32); - for (i = 0; i < rLen; i++) { - *((u32*)input)++ = __SIRegs[i+0x20]; - } - - rLen = Si.inputBytes & 3; - if (rLen != 0) { - temp = __SIRegs[i + 32]; - for (i = 0; i < rLen; i++) { - *(input++) = temp >> ((3 - i) * 8); - } - } - - if (__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_COMERR_MASK) { - sr >>= (3 - Si.chan) * 8; - sr &= 0xF; - if ((sr & 8) != 0 && (Type[Si.chan] & 0x80) == 0) { - Type[Si.chan] = 8; - } - - if (sr == 0) { - sr = 4; - } - } 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 < 4; i++) { - chan++; - chan %= 4; - packet = &Packet[chan]; - - if (packet->chan != -1) { - if (packet->fire <= __OSGetSystemTime()) { - if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, packet->inputBytes, packet->callback) != 0) { - OSCancelAlarm(&Alarm[chan]); - packet->chan = -1; - } - return; - } - } - } -} - -#define CHAN_NONE -1 - -static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) { - u32 reg; - s32 chan; - u32 sr; - SICallback callback; - int i; - u32 vcount; - u32 x; - - reg = __SIRegs[SI_COMCSR_IDX]; - if ((reg & (SI_COMCSR_TCINT_MASK | SI_COMCSR_TCINTMSK_MASK)) == (SI_COMCSR_TCINT_MASK | SI_COMCSR_TCINTMSK_MASK)) { - ASSERTLINE(376, Si.chan != CHAN_NONE); - - chan = Si.chan; - sr = CompleteTransfer(); - callback = Si.callback; - Si.callback = NULL; - SITransferNext(chan); - - if (callback) { - callback(chan, sr, context); - } - - sr = __SIRegs[SI_STATUS_IDX]; - sr &= 0x0F000000 >> (chan << 3); - __SIRegs[SI_STATUS_IDX] = sr; - - if (Type[chan] == SI_ERROR_BUSY && !SIIsChanBusy(chan)) { - static u32 cmdTypeAndStatus; - - SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, &GetTypeCallback, OSMicrosecondsToTicks(65)); - } - } - - if ((reg & (SI_COMCSR_RDSTINT_MASK | SI_COMCSR_RDSTINTMSK_MASK)) == (SI_COMCSR_RDSTINT_MASK | SI_COMCSR_RDSTINTMSK_MASK)) { - vcount = 1 + VIGetCurrentLine(); - x = (Si.poll & (0x3FF << 16)) >> 16; - - for (i = 0; i < 4; i++) { - if (SIGetResponseRaw(i)) { - InputBufferVcount[i] = vcount; - } - } - - for (i = 0; i < 4; i++) { - if ((Si.poll & (0x80000000 >> (24 + i))) != 0) { - if (InputBufferVcount[i] == 0 || ((x >> 1) + InputBufferVcount[i]) < vcount) { - return; - } - } - } - - for (i = 0; i < 4; i++) { - InputBufferVcount[i] = 0; - } - - for (i = 0; i < 4; i++) { - if (RDSTHandler[i] != 0) { - (*RDSTHandler[i])(interrupt, context); - } - } - } -} - -static BOOL SIEnablePollingInterrupt(BOOL enable) { - BOOL enabled; - BOOL rc; - u32 reg; - int i; - - enabled = OSDisableInterrupts(); - reg = __SIRegs[SI_COMCSR_IDX]; - rc = ((reg & SI_COMCSR_RDSTINTMSK_MASK) != 0) ? TRUE : FALSE; - - if (enable) { - reg |= SI_COMCSR_RDSTINTMSK_MASK; - - for (i = 0; i < 4; i++) { - InputBufferVcount[i] = 0; - } - } else { - reg &= ~SI_COMCSR_RDSTINTMSK_MASK; - } - - reg &= ~(SI_COMCSR_TCINT_MASK | SI_COMCSR_TSTART_MASK); - __SIRegs[SI_COMCSR_IDX] = 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] != 0) { - break; - } - } - - if (i == 4) { - SIEnablePollingInterrupt(FALSE); - } - - OSRestoreInterrupts(enabled); - return TRUE; - } - } - - 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); - - do {} while(__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_TSTART_MASK); - - __SIRegs[SI_COMCSR_IDX] = SI_COMCSR_TCINT_MASK; - __OSSetInterruptHandler(0x14, SIInterruptHandler); - __OSUnmaskInterrupts(0x800); - - SIGetType(0); - SIGetType(1); - SIGetType(2); - SIGetType(3); -} - -static int __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback) { - BOOL enabled; - u32 rLen; - u32 i; - u32 sr; - union { - u32 val; - struct { - u32 tcint : 1; - u32 tcintmsk : 1; - u32 comerr : 1; - u32 rdstint : 1; - u32 rdstintmsk : 1; - u32 pad2 : 4; - u32 outlngth : 7; - u32 pad1 : 1; - u32 inlngth : 7; - u32 pad0 : 5; - u32 channel : 2; - u32 tstart : 1; - } f; - } comcsr; - - ASSERTMSGLINE(627, (chan >= 0) && (chan < 4), "SITransfer(): invalid channel."); - ASSERTMSGLINE(629, (outputBytes != 0) && (outputBytes <= 128), "SITransfer(): output size is out of range (must be 1 to 128)."); - ASSERTMSGLINE(631, (inputBytes != 0) && (inputBytes <= 128), "SITransfer(): input size is out of range (must be 1 to 128)."); - - enabled = OSDisableInterrupts(); - if (Si.chan != -1) { - OSRestoreInterrupts(enabled); - return 0; - } - - ASSERTLINE(641, (__SIRegs[SI_COMCSR_IDX] & (SI_COMCSR_TSTART_MASK | SI_COMCSR_TCINT_MASK)) == 0); - sr = __SIRegs[SI_STATUS_IDX]; - sr &= (0x0F000000 >> (chan* 8)); - __SIRegs[SI_STATUS_IDX] = sr; - - Si.chan = chan; - Si.callback = callback; - Si.inputBytes = inputBytes; - Si.input = input; - - rLen = ROUND(outputBytes, 4) / 4; - for (i = 0; i < rLen; i++) { - __SIRegs[i + 0x20] = ((u32*)output)[i]; - } - - comcsr.val = __SIRegs[SI_COMCSR_IDX]; - comcsr.f.tcint = 1; - comcsr.f.tcintmsk = callback ? 1 : 0; - comcsr.f.outlngth = outputBytes == 0x80 ? 0 : outputBytes; - comcsr.f.inlngth = inputBytes == 0x80 ? 0 : inputBytes; - comcsr.f.channel = chan; - comcsr.f.tstart = 1; - - __SIRegs[SI_COMCSR_IDX] = comcsr.val; - OSRestoreInterrupts(enabled); - return 1; -} - -u32 SISync(void) { - BOOL enabled; - u32 sr; - - do {} while(__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_TSTART_MASK); - - enabled = OSDisableInterrupts(); - sr = CompleteTransfer(); - SITransferNext(4); - OSRestoreInterrupts(enabled); - return sr; -} - -u32 SIGetStatus(s32 chan) { - BOOL enabled; - u32 sr; - int chanShift; - - enabled = OSDisableInterrupts(); - sr = __SIRegs[SI_STATUS_IDX]; - chanShift = (3 - chan) * 8; - sr >>= chanShift; - - if ((sr & 8) != 0) { - if ((Type[chan] & SI_ERROR_BUSY) == 0) { - Type[chan] = 8; - } - } - - OSRestoreInterrupts(enabled); - return sr; -} - -void SISetCommand(s32 chan, u32 command) { - ASSERTMSGLINE(752, (chan >= 0) && (chan < 4), "SISetCommand(): invalid channel."); - __SIRegs[chan* 3] = command; -} - -u32 SIGetCommand(s32 chan) { - ASSERTMSGLINE(770, (chan >= 0) && (chan < 4), "SIGetCommand(): invalid channel."); - return __SIRegs[chan* 3]; -} - -void SITransferCommands(void) { - __SIRegs[SI_STATUS_IDX] = SI_COMCSR_TCINT_MASK; -} - -u32 SISetXY(u32 x, u32 y) { - u32 poll; - BOOL enabled; - - ASSERTMSGLINE(803, x >= 8, "SISetXY(): x is out of range (8 <= x <= 1023)."); - ASSERTMSGLINE(804, x <= 1023, "SISetXY(): x is out of range (8 <= x <= 1023)."); - ASSERTMSGLINE(805, y <= 255, "SISetXY(): y is out of range (0 <= y <= 255)."); - - poll = x << 0x10; - poll |= y << 8; - enabled = OSDisableInterrupts(); - Si.poll &= 0xFC0000FF; - Si.poll |= poll; - poll = Si.poll; - __SIRegs[0x30 / 4] = poll; - OSRestoreInterrupts(enabled); - return poll; -} - -u32 SIEnablePolling(u32 poll) { - BOOL enabled; - u32 en; - - ASSERTMSGLINE(834, (poll & 0x0FFFFFFF) == 0, "SIEnablePolling(): invalid chan bit(s)."); - if (poll == 0) { - return Si.poll; - } - - enabled = OSDisableInterrupts(); - poll = poll >> 24; - en = poll & 0xF0; - ASSERTLINE(865, en); - poll &= ((en >> 4) | 0x03FFFFF0); - poll &= 0xFC0000FF; - - Si.poll &= ~(en >> 4); - Si.poll |= poll; - poll = Si.poll; - SITransferCommands(); - __SIRegs[0x30 / 4] = poll; - OSRestoreInterrupts(enabled); - return poll; -} - -u32 SIDisablePolling(u32 poll) { - BOOL enabled; - - ASSERTMSGLINE(908, (poll & 0x0FFFFFFF) == 0, "SIDisablePolling(): invalid chan bit(s)."); - if (poll == 0) { - return Si.poll; - } - - enabled = OSDisableInterrupts(); - poll = poll >> 24; - poll &= 0xF0; - ASSERTLINE(921, poll); - poll = Si.poll & ~poll; - __SIRegs[0x30 / 4] = poll; - Si.poll = poll; - OSRestoreInterrupts(enabled); - return poll; -} - -static BOOL SIGetResponseRaw(s32 chan) { - u32 sr; - - sr = SIGetStatus(chan); - if (sr & 0x20) { - InputBuffer[chan][0] = __SIRegs[1 + chan * 3]; - InputBuffer[chan][1] = __SIRegs[2 + chan * 3]; - InputBufferValid[chan] = TRUE; - return TRUE; - } - - return FALSE; -} - -BOOL SIGetResponse(s32 chan, void* data) { - BOOL rc; - BOOL enabled; - - ASSERTMSGLINE(971, ((chan >= 0) && (chan < 4)), "SIGetResponse(): invalid channel."); - enabled = OSDisableInterrupts(); - SIGetResponseRaw(chan); - rc = InputBufferValid[chan]; - InputBufferValid[chan] = FALSE; - - if (rc) { - ((u32*)data)[0] = InputBuffer[chan][0]; - ((u32*)data)[1] = InputBuffer[chan][1]; - } - - OSRestoreInterrupts(enabled); - return rc; -} - -static void AlarmHandler(OSAlarm* alarm, OSContext* context) { - s32 chan; - SIPacket* packet; - - chan = (s32)(alarm - Alarm); - ASSERTLINE(1002, 0 <= chan && chan < SI_MAX_CHAN); - - packet = &Packet[chan]; - if (packet->chan != -1) { - ASSERTLINE(1006, packet->fire <= __OSGetSystemTime()); - - 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; - OSTime now; - OSTime fire; - - packet = &Packet[chan]; - enabled = OSDisableInterrupts(); - - if (packet->chan != -1 || Si.chan == chan) { - OSRestoreInterrupts(enabled); - return FALSE; - } - - now = __OSGetSystemTime(); - if (delay == 0) { - fire = now; - } else { - fire = delay + XferTime[chan]; - } - - 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) { - SITypeCallback callback; - int i; - - for (i = 0; i < 4; i++) { - callback = TypeCallback[chan][i]; - - if (callback != 0) { - TypeCallback[chan][i] = 0; - (*callback)(chan, type); - } - } -} - -static void GetTypeCallback(s32 chan, u32 error, OSContext* context) { - u32 type; - u32 chanBit; - int fix; - u32 id; - - ASSERTLINE(1137, 0 <= chan && chan < SI_MAX_CHAN); - - ASSERTLINE(1139, (Type[chan] & 0xff) == SI_ERROR_BUSY); - Type[chan] &= ~SI_ERROR_BUSY; - Type[chan] |= error; - TypeTime[chan] = __OSGetSystemTime(); - - type = Type[chan]; - chanBit = 0x80000000 >> chan; - fix = __PADFixBits & chanBit; - __PADFixBits &= ~chanBit; - - if ((error & 0xF) != 0 || (type & 0x18000000) != 0x08000000 || (type & 0x80000000) == 0 || (type & 0x04000000) != 0) { - OSSetWirelessID(chan, 0); - CallTypeAndStatusCallback(chan, Type[chan]); - } else { - static u32 cmdFixDevice[4]; - - id = OSGetWirelessID(chan) << 8; - - if (fix != 0 && (id & 0x100000) != 0) { - cmdFixDevice[chan] = 0x4E000000 | (id & 0xCFFF00) | 0x100000; - Type[chan] = SI_ERROR_BUSY; - SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); - return; - } - - if ((type & 0x00100000) != 0) { - if ((id & 0xCFFF00) != (type & 0xCFFF00)) { - if ((id & 0x100000) == 0) { - id = type & 0xCFFF00; - id |= 0x100000; - OSSetWirelessID(chan, id >> 8); - } - - cmdFixDevice[chan] = 0x4E000000 | id; - Type[chan] = SI_ERROR_BUSY; - SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); - return; - } - } else { - if ((type & 0x40000000) != 0) { - id = type & 0xCFFF00; - id |= 0x100000; - OSSetWirelessID(chan, id >> 8); - - cmdFixDevice[chan] = 0x4E000000 | id; - Type[chan] = SI_ERROR_BUSY; - SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); - return; - } - - OSSetWirelessID(chan, 0); - } - - CallTypeAndStatusCallback(chan, Type[chan]); - } -} - -u32 SIGetType(s32 chan) { - static u32 cmdTypeAndStatus; - BOOL enabled; - u32 type; - OSTime diff; - - enabled = OSDisableInterrupts(); - ASSERTLINE(1243, 0 <= chan && chan < SI_MAX_CHAN); - type = Type[chan]; - diff = __OSGetSystemTime() - TypeTime[chan]; - if ((Si.poll & (0x80 >> chan)) != 0) { - if (type != 8) { - TypeTime[chan] = __OSGetSystemTime(); - OSRestoreInterrupts(enabled); - return type; - } - - type = Type[chan] = SI_ERROR_BUSY; - } else { - if (diff <= OSMillisecondsToTicks(50) && type != 8) { - OSRestoreInterrupts(enabled); - return type; - } - - if (diff <= OSMillisecondsToTicks(75)) { - Type[chan] = SI_ERROR_BUSY; - } else { - type = Type[chan] = SI_ERROR_BUSY; - } - } - - TypeTime[chan] = __OSGetSystemTime(); - SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, &GetTypeCallback, OSMicrosecondsToTicks(65)); - OSRestoreInterrupts(enabled); - return type; -} - -u32 SIGetTypeAsync(s32 chan, SITypeCallback callback) { - BOOL enabled; - u32 type; - int i; - - enabled = OSDisableInterrupts(); - type = SIGetType(chan); - - if ((Type[chan] & SI_ERROR_BUSY) != 0) { - for (i = 0; i < SI_MAX_TYPE; i++) { - if (TypeCallback[chan][i] == callback) { - break; - } - - if (TypeCallback[chan][i] == 0) { - TypeCallback[chan][i] = callback; - break; - } - } - - ASSERTLINE(1324, i < SI_MAX_TYPE); - } else { - (*callback)(chan, type); - } - - OSRestoreInterrupts(enabled); - return type; -} - -u32 SIDecodeType(u32 type) { - u32 error; - - error = type & 0xFF; - type &= ~0xFF; - - if (error & SI_ERROR_NO_RESPONSE) { - return SI_ERROR_NO_RESPONSE; - } - - if (error & (SI_ERROR_UNKNOWN | SI_ERROR_COLLISION | SI_ERROR_OVER_RUN | SI_ERROR_UNDER_RUN)) { - return SI_ERROR_UNKNOWN; - } - - if (error != 0) { - ASSERTLINE(1371, error == SI_ERROR_BUSY); - return SI_ERROR_BUSY; - } - - if ((type & SI_TYPE_MASK) == SI_TYPE_N64) { - switch (type & 0xFFFF0000) { - case SI_N64_MIC: - case SI_N64_KEYBOARD: - case SI_GBA: - case SI_N64_MOUSE: - case SI_N64_CONTROLLER: - return type & 0xFFFF0000; - default: - return SI_ERROR_UNKNOWN; - } - } - - if ((type & SI_TYPE_MASK) != SI_TYPE_DOLPHIN) { - return SI_ERROR_UNKNOWN; - } - - switch (type & 0xFFFF0000) { - case SI_GC_STEERING: - case SI_GC_CONTROLLER: - return type & 0xFFFF0000; - } - - if ((type & 0xFFE00000) == SI_GC_KEYBOARD) { - return SI_GC_KEYBOARD; - } - - if ((type & SI_GC_WIRELESS) != 0 && (type & SI_WIRELESS_IR) == 0) { - if ((type & SI_GC_WAVEBIRD) == SI_GC_WAVEBIRD) { - return SI_GC_WAVEBIRD; - } - - if ((type & SI_WIRELESS_STATE) == 0) { - return SI_GC_RECEIVER; - } - } - - if ((type & SI_GC_CONTROLLER) == SI_GC_CONTROLLER) { - return SI_GC_CONTROLLER; - } - - return SI_ERROR_UNKNOWN; -} - -u32 SIProbe(s32 chan) { - return SIDecodeType(SIGetType(chan)); -} - -char* SIGetTypeString(u32 type) { - switch (SIDecodeType(type)) { - case SI_ERROR_NO_RESPONSE: - return "No response"; - case SI_ERROR_BUSY: - return "Busy"; - case SI_N64_CONTROLLER: - return "N64 controller"; - case SI_N64_MIC: - 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"; - case SI_ERROR_UNKNOWN: - default: - return "Unknown"; - } -} diff --git a/src/dolphin/si/SISamplingRate.c b/src/dolphin/si/SISamplingRate.c deleted file mode 100644 index b1a6f60..0000000 --- a/src/dolphin/si/SISamplingRate.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include - -#include "__os.h" - -#define LATENCY 8 - -static u32 SamplingRate = 0; - -typedef struct XY { - u16 line; - u8 count; -} XY; - -static XY XYNTSC[12] = { - {0x00F6, 0x02}, - {0x000E, 0x13}, - {0x001E, 0x09}, - {0x002C, 0x06}, - {0x0034, 0x05}, - {0x0041, 0x04}, - {0x0057, 0x03}, - {0x0057, 0x03}, - {0x0057, 0x03}, - {0x0083, 0x02}, - {0x0083, 0x02}, - {0x0083, 0x02}, -}; - -static XY XYPAL[12] = { - {0x0128, 0x02}, - {0x000F, 0x15}, - {0x001D, 0x0B}, - {0x002D, 0x07}, - {0x0034, 0x06}, - {0x003F, 0x05}, - {0x004E, 0x04}, - {0x0068, 0x03}, - {0x0068, 0x03}, - {0x0068, 0x03}, - {0x0068, 0x03}, - {0x009C, 0x02}, -}; - -void SISetSamplingRate(u32 msec) { - XY* xy; - BOOL progressive; - BOOL enabled; - - ASSERTMSGLINE(377, 0 <= msec && msec <= 11, "SISetSamplingRate(): out of rage (0 <= msec <= 11)"); - if (msec > 11) { - msec = 11; - } - enabled = OSDisableInterrupts(); - SamplingRate = msec; - - switch (VIGetTvFormat()) { - 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; - } - - progressive = __VIRegs[VI_CLOCK_SEL] & 1; - SISetXY((progressive ? 2 : 1) * xy[msec].line, xy[msec].count); - OSRestoreInterrupts(enabled); -} - -void SIRefreshSamplingRate(void) { - SISetSamplingRate(SamplingRate); -} - -#if DEBUG -void __SITestSamplingRate(u32 tvmode) { - u32 msec; - u32 line; - u32 count; - XY* xy; - - switch (tvmode) { - case VI_NTSC: - case VI_MPAL: - xy = XYNTSC; - for (msec = 0; msec <= 11; msec++) { - line = xy[msec].line; - count = xy[msec].count; - OSReport("%2d[msec]: count %3d, line %3d, last %3d, diff0 %2d.%03d, diff1 %2d.%03d\n", - msec, count, line, line * (count - 1) + LATENCY, (line * 636) / 10000, (line * 636) % 10000, - ((263 - line * (count - 1)) * 636) / 10000, ((263 - line * (count - 1)) * 636) % 10000); - ASSERTLINE(446, line * (count - 1) + LATENCY < 263); - - if (msec != 0) { - ASSERTLINE(449, 636 * line < msec * 10000); - ASSERTLINE(450, 636 * (263 - line * (count - 1)) < msec * 10000); - } - } - break; - case VI_PAL: - xy = XYPAL; - for (msec = 0; msec <= 11; msec++) { - line = xy[msec].line; - count = xy[msec].count; - OSReport("%2d[msec]: count %3d, line %3d, last %3d, diff0 %2d.%03d, diff1 %2d.%03d\n", - msec, count, line, line * (count - 1) + LATENCY, (line * 640) / 10000, (line * 640) % 10000, - ((313 - line * (count - 1)) * 640) / 10000, ((313 - line * (count - 1)) * 640) % 10000); - ASSERTLINE(470, line * (count - 1) + LATENCY < 313); - - if (msec != 0) { - ASSERTLINE(473, 640 * line < msec * 10000); - ASSERTLINE(474, 640 * (313 - line * (count - 1)) < msec * 10000); - } - } - break; - } -} -#endif diff --git a/src/dolphin/si/SISteering.c b/src/dolphin/si/SISteering.c deleted file mode 100644 index c0d6c66..0000000 --- a/src/dolphin/si/SISteering.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include - -#include "__si.h" - -// prototypes -static void DefaultCallback(s32, s32); -static s32 SISteeringBegin(SISteeringControl* sc, SISteeringCallback callback); -static void ResetProc(s32 chan); -static int OnReset(BOOL final); - -SISteeringControl __SISteering[4]; -BOOL __SIResetSteering; - -static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127}; - -void SIInitSteering(void) { - static BOOL initialized; - SISteeringControl* sc; - s32 chan; - - if (!initialized) { - initialized = TRUE; - - for (chan = 0; chan < 4; chan++) { - sc = &__SISteering[chan]; - sc->ret = 0; - OSInitThreadQueue(&sc->threadQueue); - } - - SIRefreshSamplingRate(); - __SIResetSteering = 0; - OSRegisterResetFunction(&ResetFunctionInfo); - } -} - -static void DefaultCallback(s32, s32) {} - -static s32 SISteeringBegin(SISteeringControl* sc, SISteeringCallback callback) { - BOOL enabled; - s32 ret; - - callback = callback != 0 ? callback : DefaultCallback; - - enabled = OSDisableInterrupts(); - if (sc->callback) { - ret = -2; - } else { - sc->callback = callback; - ret = 0; - } - - OSRestoreInterrupts(enabled); - return ret; -} - -static void ResetProc(s32 chan) { - SISteeringControl* sc = &__SISteering[chan]; - - if (sc->ret == 0 && __SIResetSteering == 0) { - __SISteeringEnable(chan); - } -} - -s32 SIResetSteeringAsync(s32 chan, SISteeringCallback callback) { - SISteeringControl* sc; - s32 ret; - - sc = &__SISteering[chan]; - ret = SISteeringBegin(sc, callback); - if (ret != 0) { - return ret; - } - - sc->output[0] = 0xFF; - return __SISteeringTransfer(chan, 1, 3, ResetProc); -} - -s32 SIResetSteering(s32 chan) { - SISteeringControl* sc; - s32 ret; - -#ifndef DEBUG - u32 padding; -#endif - - sc = &__SISteering[chan]; - ret = SIResetSteeringAsync(chan, __SISteeringSyncCallback); - if (ret != 0) { - return ret; - } - - return __SISteeringSync(chan); -} - -static int OnReset(BOOL final) { - static s32 count; - s32 chan; - - if (!__SIResetSteering) { - __SIResetSteering = TRUE; - - for (chan = 0; chan < 4; chan++) { - if ((0x80000000 >> chan) & __SISteeringEnableBits) { - SIControlSteering(chan, 0x400, 0); - } - } - - count = VIGetRetraceCount(); - } - - if ((s32)VIGetRetraceCount() - count > 2) { - while (__SISteeringEnableBits != 0) { - __SISteeringDisable(__cntlzw(__SISteeringEnableBits)); - } - return 1; - } - - return 0; -} diff --git a/src/dolphin/si/SISteeringAuto.c b/src/dolphin/si/SISteeringAuto.c deleted file mode 100644 index b8e23e9..0000000 --- a/src/dolphin/si/SISteeringAuto.c +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include - -static void (*SamplingCallback)(); -u32 __SISteeringEnableBits; - -void __SISteeringEnable(s32 chan) { - u32 cmd; - u32 chanBit; - u32 data[2]; - - chanBit = 0x80000000 >> chan; - if (!(__SISteeringEnableBits & chanBit)) { - __SISteeringEnableBits |= chanBit; - SIGetResponse(chan, &data); - - cmd = 0x300680; - SISetCommand(chan, cmd); - SIEnablePolling(__SISteeringEnableBits); - } -} - -void __SISteeringDisable(s32 chan) { - u32 chanBit; - - chanBit = 0x80000000 >> chan; - SIDisablePolling(chanBit); - __SISteeringEnableBits &= ~chanBit; -} - -s32 SIReadSteering(s32 chan, SISteeringStatus* status) { - BOOL enabled; - SISteeringControl* sc; - u32 data[2]; - u32 chanBit; - u32 sr; - s32 ret; - - enabled = OSDisableInterrupts(); - sc = &__SISteering[chan]; - chanBit = 0x80000000 >> chan; - - if (SIIsChanBusy(chan)) { - sc->ret = -2; - } else if (!(__SISteeringEnableBits & chanBit)) { - sc->ret = -1; - } else { - sr = SIGetStatus(chan); - if (sr & 8) { - SIGetResponse(chan, &data); - __SISteeringDisable(chan); - sc->ret = -1; - } else if ((SIGetResponse(chan, &data) == 0) || (data[0] & 0x80000000)) { - sc->ret = -3; - } else { - sc->ret = 0; - if (status != 0) { - status->button = data[0] >> 0x10; - status->misc = data[0] >> 8; - status->steering = (data[0] & 0xFF) - 0x80; - status->gas = data[1] >> 0x18; - status->brake = data[1] >> 0x10; - status->left = data[1] >> 8; - status->right = data[1]; - } - } - } - - if (status != 0) { - status->err = sc->ret; - } - - ret = sc->ret; - OSRestoreInterrupts(enabled); - return ret; -} - -static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) { - OSContext exceptionContext; - - if (SamplingCallback != 0) { - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - SamplingCallback(); - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); - } -} - -void (* SISetSteeringSamplingCallback(void (*callback)()))() { - void (*prev)() = SamplingCallback; - SamplingCallback = callback; - - if (callback != 0) { - SIRegisterPollingHandler(SamplingHandler); - } else { - SIUnregisterPollingHandler(SamplingHandler); - } - - return prev; -} - -void SIControlSteering(s32 chan, u32 control, s32 level) { - BOOL enabled; - u32 chanBit; - u32 command; - - control &= 0x600; - - if (level <= -0x80) { - command = 0; - } else if (level >= 0x80) { - command = 0x100; - } else { - command = level + 0x80; - } - - command |= control; - command &= 0x7FF; - - enabled = OSDisableInterrupts(); - chanBit = 0x80000000 >> chan; - if (__SISteeringEnableBits & chanBit) { - command |= 0x300000; - SISetCommand(chan, command); - SITransferCommands(); - } - - OSRestoreInterrupts(enabled); -} diff --git a/src/dolphin/si/SISteeringXfer.c b/src/dolphin/si/SISteeringXfer.c deleted file mode 100644 index 3bb8abd..0000000 --- a/src/dolphin/si/SISteeringXfer.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include - -#include "__os.h" - -static void __SISteeringHandler(s32 chan, u32 error, OSContext* context) { - SISteeringControl* sc; - void (*proc)(s32); - SISteeringCallback callback; - OSContext exceptionContext; - - sc = &__SISteering[chan]; - if (!__SIResetSteering) { - if (error & 8) { - sc->ret = -1; - } else if (error & 7) { - sc->ret = -3; - } else { - sc->ret = 0; - } - - if (sc->proc != 0) { - proc = sc->proc; - sc->proc = NULL; - proc(chan); - } - - if (sc->callback != 0) { - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - callback = sc->callback; - sc->callback = NULL; - callback(chan, sc->ret); - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); - } - } -} - -void __SISteeringSyncCallback(s32 chan) { - SISteeringControl* sc; - - sc = &__SISteering[chan]; - OSWakeupThread(&sc->threadQueue); -} - -s32 __SISteeringSync(s32 chan) { - SISteeringControl* sc; - s32 ret; - BOOL enabled; - - sc = &__SISteering[chan]; - enabled = OSDisableInterrupts(); - - while (sc->callback != 0) { - OSSleepThread(&sc->threadQueue); - } - - ret = sc->ret; - OSRestoreInterrupts(enabled); - return ret; -} - -static void TypeAndStatusCallback(s32 chan, u32 type) { - SISteeringControl* sc; - void (*proc)(s32); - SISteeringCallback callback; - OSContext exceptionContext; - OSContext* context; - - sc = &__SISteering[chan]; - if (!__SIResetSteering) { - ASSERTLINE(127, !(type & SI_ERROR_BUSY)); - - if ((u32)((type & 0xFFFF0000) + 0xF8000000) == 0) { - if (SITransfer(chan, sc, sc->outputBytes, sc->input, sc->inputBytes, __SISteeringHandler, 0)) { - return; - } - sc->ret = -2; - } else { - sc->ret = -1; - } - - if (sc->proc != 0) { - proc = sc->proc; - sc->proc = NULL; - proc(chan); - } - - if (sc->callback != 0) { - context = OSGetCurrentContext(); - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - callback = sc->callback; - sc->callback = NULL; - callback(chan, sc->ret); - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); - __OSReschedule(); - } - } -} - -s32 __SISteeringTransfer(s32 chan, u32 outputBytes, u32 inputBytes, void (*proc)(s32)) { - BOOL enabled; - SISteeringControl* sc; - - sc = &__SISteering[chan]; - enabled = OSDisableInterrupts(); - - sc->proc = proc; - sc->outputBytes = outputBytes; - sc->inputBytes = inputBytes; - SIGetTypeAsync(chan, &TypeAndStatusCallback); - - OSRestoreInterrupts(enabled); - return 0; -} diff --git a/src/dolphin/si/__si.h b/src/dolphin/si/__si.h deleted file mode 100644 index d609f90..0000000 --- a/src/dolphin/si/__si.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _DOLPHIN_SI_INTERNAL_H_ -#define _DOLPHIN_SI_INTERNAL_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void __SISteeringEnable(s32 chan); -s32 __SISteeringTransfer(s32 chan, u32 outputBytes, u32 inputBytes, void (*proc)(s32)); -void __SISteeringSyncCallback(s32 chan, s32); -s32 __SISteeringSync(s32 chan); -void __SISteeringDisable(s32 chan); -void __SITestSamplingRate(u32 tvmode); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/dolphin/sp/sp.c b/src/dolphin/sp/sp.c deleted file mode 100644 index b934423..0000000 --- a/src/dolphin/sp/sp.c +++ /dev/null @@ -1,404 +0,0 @@ -#include -#include - -void SPInitSoundTable(SPSoundTable* table, u32 aramBase, u32 zeroBase) { - int i; - SPSoundEntry* sound; - SPADPCM* adpcm; - u32 aramBase4, aramBase8, aramBase16; - u32 zeroBase4, zeroBase8, zeroBase16; - - ASSERTLINE(34, table); - - aramBase4 = aramBase << 1; - zeroBase4 = (zeroBase << 1) + 2; - aramBase8 = aramBase; - - zeroBase8 = zeroBase; - aramBase16 = aramBase >> 1; - zeroBase16 = zeroBase >> 1; - - sound = &table->sound[0]; - adpcm = (SPADPCM*)&table->sound[table->entries]; - - for (i = 0; i < table->entries; i++) { - switch (sound->type) { - case 0: - sound->loopAddr = zeroBase4; - sound->loopEndAddr = 0; - sound->endAddr = aramBase4 + sound->endAddr; - sound->currentAddr = aramBase4 + sound->currentAddr; - sound->adpcm = adpcm; - adpcm++; - break; - case 1: - sound->loopAddr = aramBase4 + sound->loopAddr; - sound->loopEndAddr = aramBase4 + sound->loopEndAddr; - sound->endAddr = aramBase4 + sound->endAddr; - sound->currentAddr = aramBase4 + sound->currentAddr; - sound->adpcm = adpcm; - adpcm++; - break; - case 2: - sound->loopAddr = zeroBase16; - sound->loopEndAddr = 0; - sound->endAddr = aramBase16 + sound->endAddr; - sound->currentAddr = aramBase16 + sound->currentAddr; - break; - case 3: - sound->loopAddr = aramBase16 + sound->loopAddr; - sound->loopEndAddr = aramBase16 + sound->loopEndAddr; - sound->endAddr = aramBase16 + sound->endAddr; - sound->currentAddr = aramBase16 + sound->currentAddr; - break; - case 4: - sound->loopAddr = zeroBase8; - sound->loopEndAddr = 0; - sound->endAddr = aramBase8 + sound->endAddr; - sound->currentAddr = aramBase8 + sound->currentAddr; - break; - case 5: - sound->loopAddr = aramBase8 + sound->loopAddr; - sound->loopEndAddr = aramBase8 + sound->loopEndAddr; - sound->endAddr = aramBase8 + sound->endAddr; - sound->currentAddr = aramBase8 + sound->currentAddr; - break; - } - sound++; - } -} - -SPSoundEntry* SPGetSoundEntry(SPSoundTable* table, u32 index) { - ASSERTLINE(123, table); - - if (table->entries > index) { - return &table->sound[index]; - } - - return NULL; -} - -void SPPrepareSound(SPSoundEntry* sound, AXVPB* axvpb, u32 sampleRate) { - BOOL old; - u32 srcBits; - u32 loopAddr, endAddr, currentAddr; - u16* p; - u16* p1; - - ASSERTLINE(140, sound); - ASSERTLINE(141, axvpb); - - srcBits = 0x10000 * ((f32)sampleRate / 32000); - - switch (sound->type) { - case 0: - loopAddr = sound->loopAddr; - endAddr = sound->endAddr; - currentAddr = sound->currentAddr; - - p = (u16*)&axvpb->pb.addr; - p1 = (u16*)sound->adpcm; - - old = OSDisableInterrupts(); - - *p++ = 0; - *p++ = 0; - *p++ = (u16)(loopAddr >> 0x10); - *p++ = (u16)(loopAddr & 0xFFFF); - *p++ = (u16)(endAddr >> 0x10); - *p++ = (u16)(endAddr & 0xFFFF); - *p++ = (u16)(currentAddr >> 0x10); - *p++ = (u16)(currentAddr & 0xFFFF); - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = (u16)(srcBits >> 0x10); - *p++ = (u16)(srcBits & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - - axvpb->sync |= 0x61000; - OSRestoreInterrupts(old); - break; - case 1: - loopAddr = sound->loopAddr; - endAddr = sound->loopEndAddr; - currentAddr = sound->currentAddr; - - p = (u16*)&axvpb->pb.addr; - p1 = (u16*)sound->adpcm; - - old = OSDisableInterrupts(); - - *p++ = 1; - *p++ = 0; - *p++ = (u16)(loopAddr >> 0x10); - *p++ = (u16)(loopAddr & 0xFFFF); - *p++ = (u16)(endAddr >> 0x10); - *p++ = (u16)(endAddr & 0xFFFF); - *p++ = (u16)(currentAddr >> 0x10); - *p++ = (u16)(currentAddr & 0xFFFF); - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - *p++ = (u16)(srcBits >> 0x10); - *p++ = (u16)(srcBits & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = *p1++; - *p++ = *p1++; - *p++ = *p1++; - - axvpb->sync |= 0x161000; - OSRestoreInterrupts(old); - break; - case 2: - loopAddr = sound->loopAddr; - endAddr = sound->endAddr; - currentAddr = sound->currentAddr; - - p = (u16*)&axvpb->pb.addr; - - old = OSDisableInterrupts(); - - *p++ = 0; - *p++ = 10; - *p++ = (u16)(loopAddr >> 0x10); - *p++ = (u16)(loopAddr & 0xFFFF); - *p++ = (u16)(endAddr >> 0x10); - *p++ = (u16)(endAddr & 0xFFFF); - *p++ = (u16)(currentAddr >> 0x10); - *p++ = (u16)(currentAddr & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0x800; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = (u16)(srcBits >> 0x10); - *p++ = (u16)(srcBits & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - - axvpb->sync |= 0x61000; - OSRestoreInterrupts(old); - break; - case 3: - loopAddr = sound->loopAddr; - endAddr = sound->loopEndAddr; - currentAddr = sound->currentAddr; - - p = (u16*)&axvpb->pb.addr; - - old = OSDisableInterrupts(); - - *p++ = 1; - *p++ = 10; - *p++ = (u16)(loopAddr >> 0x10); - *p++ = (u16)(loopAddr & 0xFFFF); - *p++ = (u16)(endAddr >> 0x10); - *p++ = (u16)(endAddr & 0xFFFF); - *p++ = (u16)(currentAddr >> 0x10); - *p++ = (u16)(currentAddr & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0x800; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = (u16)(srcBits >> 0x10); - *p++ = (u16)(srcBits & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - - axvpb->sync |= 0x61000; - OSRestoreInterrupts(old); - break; - case 4: - loopAddr = sound->loopAddr; - endAddr = sound->endAddr; - currentAddr = sound->currentAddr; - - p = (u16*)&axvpb->pb.addr; - - old = OSDisableInterrupts(); - - *p++ = 0; - *p++ = 0x19; - *p++ = (u16)(loopAddr >> 0x10); - *p++ = (u16)(loopAddr & 0xFFFF); - *p++ = (u16)(endAddr >> 0x10); - *p++ = (u16)(endAddr & 0xFFFF); - *p++ = (u16)(currentAddr >> 0x10); - *p++ = (u16)(currentAddr & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0x100; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = (u16)(srcBits >> 0x10); - *p++ = (u16)(srcBits & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - - axvpb->sync |= 0x61000; - OSRestoreInterrupts(old); - break; - case 5: - loopAddr = sound->loopAddr; - endAddr = sound->loopEndAddr; - currentAddr = sound->currentAddr; - - p = (u16*)&axvpb->pb.addr; - - old = OSDisableInterrupts(); - - *p++ = 1; - *p++ = 0x19; - *p++ = (u16)(loopAddr >> 0x10); - *p++ = (u16)(loopAddr & 0xFFFF); - *p++ = (u16)(endAddr >> 0x10); - *p++ = (u16)(endAddr & 0xFFFF); - *p++ = (u16)(currentAddr >> 0x10); - *p++ = (u16)(currentAddr & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0x100; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = (u16)(srcBits >> 0x10); - *p++ = (u16)(srcBits & 0xFFFF); - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - - axvpb->sync |= 0x61000; - OSRestoreInterrupts(old); - break; - } -} - -void SPPrepareEnd(SPSoundEntry* sound, AXVPB* axvpb) { - BOOL old; - - ASSERTLINE(497, sound); - ASSERTLINE(498, axvpb); - - old = OSDisableInterrupts(); - - axvpb->pb.addr.loopFlag = 0; - axvpb->pb.addr.endAddressHi = sound->endAddr >> 0x10; - axvpb->pb.addr.endAddressLo = sound->endAddr & 0xFFFF; - - axvpb->sync |= 0xA000; - OSRestoreInterrupts(old); -} diff --git a/src/dolphin/stub.c b/src/dolphin/stub.c deleted file mode 100644 index 63edf6b..0000000 --- a/src/dolphin/stub.c +++ /dev/null @@ -1,80 +0,0 @@ -/* symbols just to satisfy the linker*/ -#define TEXT_STUB(name) void name(void) {} -#define DATA_STUB(name) int name; - -TEXT_STUB(_start) - -TEXT_STUB(__ArenaHi) -TEXT_STUB(__ArenaLo) -TEXT_STUB(__cvt_fp2unsigned) -TEXT_STUB(__div2i) -TEXT_STUB(__init_registers) -TEXT_STUB(__mod2i) -TEXT_STUB(__shl2i) -TEXT_STUB(__shr2i) -TEXT_STUB(__shr2u) -TEXT_STUB(_ctors) -TEXT_STUB(_dtors) -TEXT_STUB(_bss_init_info) -TEXT_STUB(_restfpr_18) -TEXT_STUB(_restfpr_19) -TEXT_STUB(_restfpr_20) -TEXT_STUB(_restfpr_21) -TEXT_STUB(_restfpr_22) -TEXT_STUB(_restfpr_23) -TEXT_STUB(_restfpr_24) -TEXT_STUB(_restfpr_25) -TEXT_STUB(_restfpr_26) -TEXT_STUB(_restfpr_27) -TEXT_STUB(_restfpr_28) -TEXT_STUB(_restfpr_29) -TEXT_STUB(_restfpr_30) -TEXT_STUB(_rom_copy_info) -TEXT_STUB(_savefpr_18) -TEXT_STUB(_savefpr_19) -TEXT_STUB(_savefpr_20) -TEXT_STUB(_savefpr_21) -TEXT_STUB(_savefpr_22) -TEXT_STUB(_savefpr_23) -TEXT_STUB(_savefpr_24) -TEXT_STUB(_savefpr_25) -TEXT_STUB(_savefpr_26) -TEXT_STUB(_savefpr_27) -TEXT_STUB(_savefpr_28) -TEXT_STUB(_savefpr_29) -TEXT_STUB(_savefpr_30) -TEXT_STUB(_stack_addr) -TEXT_STUB(_stack_end) -TEXT_STUB(DSPAddTask) -TEXT_STUB(DSPAssertTask) -TEXT_STUB(DSPCheckInit) -TEXT_STUB(DSPCheckMailToDSP) -TEXT_STUB(DSPGetDMAStatus) -TEXT_STUB(DSPHalt) -TEXT_STUB(DSPInit) -TEXT_STUB(DSPReset) -TEXT_STUB(DSPSendMailToDSP) -TEXT_STUB(EnableMetroTRKInterrupts) -TEXT_STUB(InitMetroTRK) -TEXT_STUB(cosf) -TEXT_STUB(main) -TEXT_STUB(memcmp) -TEXT_STUB(memcpy) -TEXT_STUB(memmove) -TEXT_STUB(memset) -TEXT_STUB(powf) -TEXT_STUB(rand) -TEXT_STUB(sinf) -TEXT_STUB(sprintf) -TEXT_STUB(srand) -TEXT_STUB(strchr) -TEXT_STUB(strcmp) -TEXT_STUB(strcpy) -TEXT_STUB(strlen) -TEXT_STUB(strncpy) -TEXT_STUB(tanf) -TEXT_STUB(tolower) -TEXT_STUB(vprintf) -TEXT_STUB(vsprintf) -TEXT_STUB(atan2f) -TEXT_STUB(acosf) diff --git a/src/dolphin/support/HTable.c b/src/dolphin/support/HTable.c deleted file mode 100644 index 6cee989..0000000 --- a/src/dolphin/support/HTable.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include - -void DSInitHTable(DSHashTable* hTable, u16 size, DSList* listArray, DSHashFunc* hashFunc, Ptr obj, DSLinkPtr link) { - u16 i; - - hTable->table = listArray; - hTable->tableSize = size; - hTable->hash = hashFunc; - for (i = 0; i < size; i++) { - DSInitList(&listArray[i], obj, link); - } -} - -void DSInsertHTableObj(DSHashTable* hTable, Ptr obj) { - DSList* list = &hTable->table[hTable->hash(obj)]; - DSInsertListObject(list, 0, obj); -} - -void DSHTableToList(DSHashTable* hTable, DSList* list) { - DSLink* link = NULL; - u16 i = 0; - - list->Offset = hTable->table[i].Offset; - for (i = 0; i < hTable->tableSize; i++) { - DSAttachList(list, &hTable->table[i]); - } -} - -void* DSNextHTableObj(DSHashTable* hTable, Ptr obj) { - s32 currentIndex; - void* cursor; - - if (!hTable) { - return NULL; - } - - if (!obj) { - currentIndex = 0; - cursor = DSNextListObj(&hTable->table[currentIndex], NULL); - } else { - currentIndex = DSHTableIndex(hTable, obj); - if (currentIndex == -1) { - return NULL; - } - cursor = DSNextListObj(&hTable->table[currentIndex], obj); - } - - while (cursor == NULL && currentIndex < hTable->tableSize - 1) { - currentIndex++; - cursor = DSNextListObj(&hTable->table[currentIndex], NULL); - } - return cursor; -} - -s32 DSHTableIndex(DSHashTable* hTable, Ptr obj) { - if (!hTable || !obj) { - return -1; - } - return hTable->hash(obj); -} - -void* DSHTableHead(DSHashTable* hTable, s32 index) { - if (index < 0 || index >= hTable->tableSize) { - return NULL; - } - return DSNextListObj(&hTable->table[index], NULL); -} diff --git a/src/dolphin/support/List.c b/src/dolphin/support/List.c deleted file mode 100644 index 34b6bc8..0000000 --- a/src/dolphin/support/List.c +++ /dev/null @@ -1,92 +0,0 @@ -#include - -void DSInitList(DSListPtr list, Ptr obj, DSLinkPtr link) { - list->Head = NULL; - list->Tail = NULL; - list->Offset = (Ptr)link - obj; -} - -void DSInsertListObject(DSListPtr list, Ptr cursor, Ptr obj) { - DSLinkPtr link; - DSLinkPtr linkNext; - DSLinkPtr linkPrev; - - link = (DSLinkPtr)(obj + list->Offset); - if (list->Head) { - if (!cursor) { - linkPrev = (DSLinkPtr)(list->Tail + list->Offset); - linkPrev->Next = obj; - link->Prev = list->Tail; - link->Next = NULL; - list->Tail = obj; - } else { - linkNext = (DSLinkPtr)(cursor + list->Offset); - if (cursor == list->Head) { - list->Head = obj; - link->Next = cursor; - linkNext->Prev = obj; - } else { - linkPrev = (DSLinkPtr)(linkNext->Prev + list->Offset); - link->Next = cursor; - link->Prev = linkNext->Prev; - linkNext->Prev = obj; - linkPrev->Next = obj; - } - } - } else { - list->Tail = obj; - list->Head = obj; - link->Next = link->Prev = NULL; - } -} - -void DSRemoveListObject(DSListPtr list, Ptr obj) { - DSLinkPtr link = (DSLinkPtr)(obj + list->Offset); - - if (obj) { - if (link->Prev) { - ((DSLinkPtr)(link->Prev + list->Offset))->Next = link->Next; - } else { - list->Head = link->Next; - } - - if (link->Next) { - ((DSLinkPtr)(link->Next + list->Offset))->Prev = link->Prev; - } else { - list->Tail = link->Prev; - } - - link->Prev = NULL; - link->Next = NULL; - } -} - -void DSAttachList(DSListPtr baseList, DSListPtr attachList) { - DSLinkPtr link; - DSLinkPtr linkPrev; - - if (baseList->Offset == attachList->Offset && (attachList->Head || attachList->Tail)) { - linkPrev = (DSLinkPtr)(attachList->Head + attachList->Offset); - if (baseList->Head) { - link = (DSLinkPtr)(baseList->Tail + baseList->Offset); - link->Next = attachList->Head; - linkPrev->Prev = baseList->Tail; - baseList->Tail = attachList->Tail; - return; - } - baseList->Head = attachList->Head; - baseList->Tail = attachList->Tail; - linkPrev; // needed to match - } -} - -void* DSNextListObj(DSListPtr list, Ptr obj) { - if (!list) { - return NULL; - } - if (!obj) { - return list->Head; - } - - return ((DSLinkPtr)(obj + list->Offset))->Next; -} diff --git a/src/dolphin/support/Tree.c b/src/dolphin/support/Tree.c deleted file mode 100644 index 34ced45..0000000 --- a/src/dolphin/support/Tree.c +++ /dev/null @@ -1,106 +0,0 @@ -#include - -void DSExtractBranch(DSTreePtr tree, Ptr obj) { - DSBranchPtr branch = (DSBranchPtr)(obj + tree->Offset); - Ptr cursor = branch->Children; - Ptr next; - - while (cursor) { - next = ((DSBranchPtr)(cursor + tree->Offset))->Next; - DSInsertBranchBelow(tree, branch->Parent, cursor); - cursor = next; - } - DSRemoveBranch(tree, obj); -} - -void DSInitTree(DSTreePtr tree, Ptr obj, DSBranchPtr branch) { - tree->Root = NULL; - tree->Offset = (Ptr)branch - obj; -} - -void DSInsertBranchBelow(DSTreePtr tree, Ptr cursor, Ptr obj) { - DSBranchPtr branch; - DSBranchPtr objBranch = (DSBranchPtr)(obj + tree->Offset); - Ptr tail = NULL; - - if (cursor) { - branch = (DSBranchPtr)(cursor + tree->Offset); - if (branch->Children) { - tail = branch->Children; - } else { - branch->Children = obj; - } - } else if (tree->Root) { - tail = tree->Root; - } else { - tree->Root = obj; - } - - if (tail) { - while (((DSBranchPtr)(tail + tree->Offset))->Next) { - tail = ((DSBranchPtr)(tail + tree->Offset))->Next; - } - ((DSBranchPtr)(tail + tree->Offset))->Next = obj; - objBranch->Prev = tail; - } else { - objBranch->Prev = NULL; - } - - objBranch->Next = NULL; - objBranch->Parent = cursor; -} - -void DSInsertBranchBeside(DSTreePtr tree, Ptr cursor, Ptr obj) { - DSBranchPtr parent; - DSBranchPtr branch; - - branch = (DSBranchPtr)(obj + tree->Offset); - if (!cursor) { - if (!tree->Root) { - tree->Root = obj; - branch->Next = NULL; - branch->Prev = NULL; - branch->Children = NULL; - branch->Parent = NULL; - return; - } - cursor = tree->Root; - } - - while (((DSBranchPtr)(cursor + tree->Offset))->Next) { - cursor = ((DSBranchPtr)(cursor + tree->Offset))->Next; - } - - parent = (DSBranchPtr)(cursor + tree->Offset); - parent->Next = obj; - branch->Prev = cursor; - branch->Next = NULL; - branch->Parent = parent->Parent; -} - -void DSRemoveBranch(DSTreePtr tree, Ptr obj) { - DSBranchPtr branch; - DSBranchPtr parent; - - branch = (DSBranchPtr)(obj + tree->Offset); - if (branch->Parent) { - parent = (DSBranchPtr)(branch->Parent + tree->Offset); - if (parent->Children == obj) { - parent->Children = branch->Next; - } - } else if (tree->Root == obj) { - tree->Root = branch->Next; - } - - if (branch->Prev) { - ((DSBranchPtr)(branch->Prev + tree->Offset))->Next = branch->Next; - } - - if (branch->Next) { - ((DSBranchPtr)(branch->Next + tree->Offset))->Prev = branch->Prev; - } - - branch->Prev = NULL; - branch->Next = NULL; - branch->Parent = NULL; -} diff --git a/src/dolphin/support/string.c b/src/dolphin/support/string.c deleted file mode 100644 index f55ec79..0000000 --- a/src/dolphin/support/string.c +++ /dev/null @@ -1,74 +0,0 @@ -#include - -u8 Strcat(char* str1, char* str2, char* dst) { - char* srcCursor = str1; - char* dstCursor = dst;; - - if (!dst) { - return 0; - } - if (!str1) { - return 0; - } - if (!str2) { - return 0; - } - - while ((s8)*srcCursor != 0) { - *dstCursor = *srcCursor; - dstCursor++; - srcCursor++; - } - - srcCursor = str2; - while ((s8)*srcCursor != 0) { - *dstCursor = *srcCursor; - dstCursor++; - srcCursor++; - } - - *dstCursor = 0; - return 1; -} - -void Strcpy(char* dst, char* src) { - do { - *dst = *src; - dst++; - src++; - } while ((s8)*src != 0); -} - -s8 Strcmp(char* str1, char* str2) { - char* cursor1 = str1; - char* cursor2 = str2; - while (1) { - if ((s8)*cursor1 < (s8)*cursor2) { - return 1; - } - if ((s8)*cursor1 > (s8)*cursor2) { - return -1; - } - cursor1++; - cursor2++; - if ((s8)*cursor1 == 0 || (s8)*cursor2 == 0) { - return 0; - } - } -} - -u32 Strlen(char* str) { - char* cursor = str; - u32 counter = 0; - - if (!str) { - return 0; - } - - while ((s8)*cursor != 0) { - cursor++; - counter++; - } - - return counter; -} diff --git a/src/dolphin/syn/__syn.h b/src/dolphin/syn/__syn.h deleted file mode 100644 index ce2e970..0000000 --- a/src/dolphin/syn/__syn.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _DOLPHIN_SYN_INTERNAL_H_ -#define _DOLPHIN_SYN_INTERNAL_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// syn -extern SYNSYNTH* __SYNSynthList; - -// synctrl -extern f32 __SYNn128[128]; - -void __SYNClearAllNotes(SYNSYNTH* synth); -void __SYNSetController(SYNSYNTH* synth, u8 midiChannel, u8 function, u8 value); -void __SYNResetController0(SYNSYNTH* synth, u8 midiChannel); -void __SYNResetController(SYNSYNTH* synth, u8 midiChannel); -void __SYNResetAllControllers(SYNSYNTH* synth); -void __SYNRunInputBufferEvents(SYNSYNTH* synth); - -// synenv -s32 __SYNGetEnvelopeTime(s32 scale, s32 mod, u8 key); -void __SYNSetupVolumeEnvelope(SYNVOICE* voice); -void __SYNSetupPitchEnvelope(SYNVOICE* voice); -void __SYNRunVolumeEnvelope(SYNVOICE* voice); -void __SYNRunPitchEnvelope(SYNVOICE* voice); - -// synlfo -void __SYNSetupLfo(SYNVOICE* voice); -void __SYNRunLfo(SYNVOICE* voice); - -// synmix -extern s32 __SYNVolumeAttenuation[128]; -extern s32 __SYNAttackAttnTable[100]; - -void __SYNSetupVolume(SYNVOICE* voice); -void __SYNSetupPan(SYNVOICE* voice); -s32 __SYNGetVoiceInput(SYNVOICE* voice); -s32 __SYNGetVoiceFader(SYNVOICE* voice); -void __SYNUpdateMix(SYNVOICE* voice); - -// synpitch -f32 __SYNGetRelativePitch(SYNVOICE* voice); -void __SYNSetupPitch(SYNVOICE* voice); -void __SYNSetupSrc(SYNVOICE* voice); -void __SYNUpdateSrc(SYNVOICE* voice); - -// synsample -void __SYNSetupSample(SYNVOICE* voice); - -// synvoice -extern SYNVOICE __SYNVoice[64]; - -void __SYNClearVoiceReferences(void* p); -void __SYNSetVoiceToRelease(SYNVOICE* voice, u32 priority); -void __SYNServiceVoice(int i); - -// synwt -int __SYNGetWavetableData(SYNVOICE* voice); - -#ifdef __cplusplus -} -#endif - -#endif // _DOLPHIN_SYN_INTERNAL_H_ diff --git a/src/dolphin/syn/syn.c b/src/dolphin/syn/syn.c deleted file mode 100644 index 17bdebc..0000000 --- a/src/dolphin/syn/syn.c +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include -#include -#include -#include -#include "fake_tgmath.h" - -#include "__syn.h" - -SYNSYNTH* __SYNSynthList; - -// prototypes -static void __SYNAddSynthToList(SYNSYNTH* synth); -static void __SYNRemoveSynthFromList(SYNSYNTH* synth); - -static void __SYNAddSynthToList(SYNSYNTH* synth) { - BOOL old = OSDisableInterrupts(); - - if (__SYNSynthList) { - synth->next = __SYNSynthList; - } else { - synth->next = NULL; - } - __SYNSynthList = synth; - OSRestoreInterrupts(old); -} - -static void __SYNRemoveSynthFromList(SYNSYNTH* synth) { - SYNSYNTH* tempHead; - SYNSYNTH* tempTail; - SYNSYNTH* tempSynth; - BOOL old; - - old = OSDisableInterrupts(); - tempHead = NULL; - tempTail = NULL; - - for (tempSynth = __SYNSynthList; tempSynth; tempSynth = tempSynth->next) { - if (tempSynth != synth) { - if (tempHead) { - tempTail->next = tempSynth; - tempTail = tempSynth; - } else { - tempHead = tempTail = tempSynth; - } - } - } - - if (tempTail) { - tempTail->next = NULL; - } - - __SYNSynthList = tempHead; - OSRestoreInterrupts(old); -} - -void SYNInit(void) { - int i; - - for (i = 0; i < 64; i++) { - __SYNVoice[i].synth = 0; - } - __SYNSynthList = NULL; -} - -void SYNQuit(void) { - SYNInit(); -} - -void SYNRunAudioFrame(void) { - int i; - SYNSYNTH* synth; - - for (i = 0; i < 64; i++) { - __SYNServiceVoice(i); - } - - for (synth = __SYNSynthList; synth; synth = synth->next) { - __SYNRunInputBufferEvents(synth); - } -} - -void SYNInitSynth(SYNSYNTH* synth, void* wavetable, u32 aramBase, u32 zeroBase, u32 priorityVoiceAlloc, u32 priorityNoteOn, u32 priorityNoteRelease) { - u32* p; - u32 midiChannel; - u32 noteNumber; - - ASSERTLINE(158, synth); - ASSERTLINE(159, wavetable); - ASSERTLINE(160, aramBase); - - p = wavetable; - synth->percussiveInst = (void*)((u32)wavetable + *(p)); p += 1; - synth->melodicInst = (void*)((u32)wavetable + *(p)); p += 1; - synth->region = (void*)((u32)wavetable + *(p)); p += 1; - synth->art = (void*)((u32)wavetable + *(p)); p += 1; - synth->sample = (void*)((u32)wavetable + *(p)); p += 1; - synth->adpcm = (void*)((u32)wavetable + *(p)); p += 1; - synth->aramBaseWord = (aramBase >> 1); - synth->aramBaseByte = aramBase; - synth->aramBaseNibble = (aramBase << 1); - synth->zeroBaseWord = zeroBase >> 1; - synth->zeroBaseByte = zeroBase; - synth->zeroBaseNibble = (zeroBase << 1); - synth->priorityVoiceAlloc = priorityVoiceAlloc; - synth->priorityNoteOn = priorityNoteOn; - synth->priorityNoteRelease = priorityNoteRelease; - synth->masterVolume = 0; - __SYNResetAllControllers(synth); - synth->inputPosition = &synth->input[0][0]; - synth->inputCounter = 0; - synth->notes = 0; - - for (midiChannel = 0; midiChannel < 16; midiChannel++) { - for (noteNumber = 0; noteNumber < 16; noteNumber++) { - synth->keyGroup[midiChannel][noteNumber] = 0; - } - } - - for (midiChannel = 0; midiChannel < 16; midiChannel++) { - for (noteNumber = 0; noteNumber < 128; noteNumber++) { - synth->voice[midiChannel][noteNumber] = 0; - } - } - - __SYNAddSynthToList(synth); -} - -void SYNQuitSynth(SYNSYNTH* synth) { - int i; - BOOL old; - SYNVOICE* voice; - - old = OSDisableInterrupts(); - if (synth->notes) { - for (i = 0; i < 64; i++) { - voice = &__SYNVoice[i]; - if (voice->synth == synth) { - MIXReleaseChannel(voice->axvpb); - AXFreeVoice(voice->axvpb); - voice->synth = 0; - } - } - } - - __SYNRemoveSynthFromList(synth); - OSRestoreInterrupts(old); -} - -void SYNMidiInput(SYNSYNTH* synth, u8* input) { - u8* src; - - ASSERTLINE(244, synth); - ASSERTLINE(245, input); - - src = input; - *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; - *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; - *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; - synth->inputCounter++; - - if (synth->inputCounter >= SYN_INPUT_BUFFER_SIZE) { - ASSERTMSGLINE(258, FALSE, "synth input buffer exceeded, increase SYN_INPUT_BUFFER_SIZE"); - } -} - -void SYNSetMasterVolume(SYNSYNTH* synth, s32 dB) { - ASSERTLINE(267, synth); - synth->masterVolume = (dB << 0x10); -} - -s32 SYNGetMasterVolume(SYNSYNTH* synth) { - ASSERTLINE(278, synth); - return synth->masterVolume >> 0x10; -} - -u32 SYNGetActiveNotes(SYNSYNTH* synth) { - ASSERTLINE(289, synth); - return synth->notes; -} diff --git a/src/dolphin/syn/synctrl.c b/src/dolphin/syn/synctrl.c deleted file mode 100644 index cfae4ec..0000000 --- a/src/dolphin/syn/synctrl.c +++ /dev/null @@ -1,510 +0,0 @@ -#include -#include -#include -#include -#include "fake_tgmath.h" - -#include "__syn.h" - -f32 __SYNn128[128] = { - 0.000000f, - 0.007813f, - 0.015625f, - 0.023438f, - 0.031250f, - 0.039063f, - 0.046875f, - 0.054688f, - 0.062500f, - 0.070313f, - 0.078125f, - 0.085938f, - 0.093750f, - 0.101563f, - 0.109375f, - 0.117188f, - 0.125000f, - 0.132813f, - 0.140625f, - 0.148438f, - 0.156250f, - 0.164063f, - 0.171875f, - 0.179688f, - 0.187500f, - 0.195313f, - 0.203125f, - 0.210938f, - 0.218750f, - 0.226563f, - 0.234375f, - 0.242188f, - 0.250000f, - 0.257813f, - 0.265625f, - 0.273438f, - 0.281250f, - 0.289063f, - 0.296875f, - 0.304688f, - 0.312500f, - 0.320313f, - 0.328125f, - 0.335938f, - 0.343750f, - 0.351563f, - 0.359375f, - 0.367188f, - 0.375000f, - 0.382813f, - 0.390625f, - 0.398438f, - 0.406250f, - 0.414063f, - 0.421875f, - 0.429688f, - 0.437500f, - 0.445313f, - 0.453125f, - 0.460938f, - 0.468750f, - 0.476563f, - 0.484375f, - 0.492188f, - 0.500000f, - 0.507813f, - 0.515625f, - 0.523438f, - 0.531250f, - 0.539063f, - 0.546875f, - 0.554688f, - 0.562500f, - 0.570313f, - 0.578125f, - 0.585938f, - 0.593750f, - 0.601563f, - 0.609375f, - 0.617188f, - 0.625000f, - 0.632813f, - 0.640625f, - 0.648438f, - 0.656250f, - 0.664063f, - 0.671875f, - 0.679688f, - 0.687500f, - 0.695313f, - 0.703125f, - 0.710938f, - 0.718750f, - 0.726563f, - 0.734375f, - 0.742188f, - 0.750000f, - 0.757813f, - 0.765625f, - 0.773438f, - 0.781250f, - 0.789063f, - 0.796875f, - 0.804688f, - 0.812500f, - 0.820313f, - 0.828125f, - 0.835938f, - 0.843750f, - 0.851563f, - 0.859375f, - 0.867188f, - 0.875000f, - 0.882813f, - 0.890625f, - 0.898438f, - 0.906250f, - 0.914063f, - 0.921875f, - 0.929688f, - 0.937500f, - 0.945313f, - 0.953125f, - 0.960938f, - 0.968750f, - 0.976563f, - 0.984375f, - 0.992188f -}; - -// prototypes -static void __SYNSetData(SYNSYNTH* synth, u8 midiChannel); -static void __SYNSetSustainPedal(SYNSYNTH* synth, u8 midiChannel, u8 data); -static void __SYNProgramChange(SYNSYNTH* synth, u8 midiChannel, u8 program); -static void __SYNReleaseChannelNotes(SYNSYNTH* synth, u8 midiChannel); -static void __SYNNoteOff(SYNSYNTH* synth, u8 midiChannel, u8 keyNum); -static void __SYNNoteOn(SYNSYNTH* synth, u8 midiChannel, u8 keyNum, u8 keyVel); -static void __SYNPitchWheel(SYNSYNTH* synth, u8 midiChannel, u8 lsb, u8 msb); -static void __SYNMidiIn(SYNSYNTH* synth, u8* input); - -static void __SYNSetData(SYNSYNTH* synth, u8 midiChannel) { - ASSERTLINE(59, synth); - ASSERTLINE(60, midiChannel < 16); - - if (synth->rpn[midiChannel]) { - u16 param = (synth->controller[midiChannel][0x65] << 8) + synth->controller[midiChannel][0x64]; - switch(param) { - case 0: - synth->pwMaxCents[midiChannel] = (synth->controller[midiChannel][0x26] + (synth->controller[midiChannel][0x6] * 100)) << 0x10; - break; - case 1: - ASSERTMSGLINE(80, FALSE, "RPN 0001 not supported\n"); - break; - case 2: - ASSERTMSGLINE(86, FALSE, "RPN 0002 not supported\n"); - break; - case 3: - ASSERTMSGLINE(92, FALSE, "RPN 0003 not supported\n"); - break; - case 4: - ASSERTMSGLINE(98, FALSE, "RPN 0004 not supported\n"); - break; - } - } -} - -static void __SYNSetSustainPedal(SYNSYNTH* synth, u8 midiChannel, u8 data) { - int i; - SYNVOICE* voice; - - ASSERTLINE(111, synth); - ASSERTLINE(112, midiChannel < 16); - ASSERTLINE(113, data < 128); - - // check if you're below 0x80 only to check if you're below 0x40. ok then. - if (data < 64) { - for (i = 0; i < 128; i++) { - voice = synth->voice[midiChannel][i]; - if (voice && voice->hold) { - __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); - voice->synth->voice[voice->midiChannel][voice->keyNum] = 0; - } - } - } -} - -static void __SYNProgramChange(SYNSYNTH* synth, u8 midiChannel, u8 program) { - ASSERTLINE(142, synth); - ASSERTLINE(143, midiChannel < 16); - ASSERTLINE(144, program < 128); - - if (midiChannel == 9) { - synth->inst[midiChannel] = synth->percussiveInst; - } else { - synth->inst[midiChannel] = synth->melodicInst; - } - - synth->inst[midiChannel] += program; -} - -static void __SYNReleaseChannelNotes(SYNSYNTH* synth, u8 midiChannel) { - int i; - SYNVOICE* voice; - - ASSERTLINE(162, synth); - ASSERTLINE(163, midiChannel < 16); - - for (i = 0; i < 128; i++) { - voice = synth->voice[midiChannel][i]; - if (voice) { - __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); - synth->voice[midiChannel][i] = 0; - } - } -} - -void __SYNClearAllNotes(SYNSYNTH* synth) { - u8 i; - - ASSERTLINE(189, synth); - - for (i = 0; i < 16; i++) { - __SYNReleaseChannelNotes(synth, i); - } -} - -void __SYNSetController(SYNSYNTH* synth, u8 midiChannel, u8 function, u8 value) { - ASSERTLINE(201, synth); - ASSERTLINE(202, midiChannel < 16); - ASSERTLINE(203, function < 128); - ASSERTLINE(204, value < 128); - - synth->controller[midiChannel][function] = value; - switch(function) { - case 6: - __SYNSetData(synth, midiChannel); - break; - case 7: - synth->volAttn[midiChannel] = __SYNVolumeAttenuation[value]; - break; - case 11: - synth->expAttn[midiChannel] = __SYNVolumeAttenuation[value]; - break; - case 0x26: - __SYNSetData(synth, midiChannel); - break; - case 0x40: - __SYNSetSustainPedal(synth, midiChannel, value); - break; - case 0x5B: - synth->auxAAttn[midiChannel] = __SYNVolumeAttenuation[value]; - break; - case 0x5C: - synth->auxBAttn[midiChannel] = __SYNVolumeAttenuation[value]; - break; - case 0x5D: - break; - case 0x62: - case 0x63: - synth->rpn[midiChannel] = 0; - break; - case 0x64: - case 0x65: - synth->rpn[midiChannel] = 1; - break; - case 0x78: - __SYNReleaseChannelNotes(synth, midiChannel); - break; - case 0x79: - if (value == 0) { - __SYNResetController0(synth, midiChannel); - } else { - __SYNResetController(synth, midiChannel); - } - break; - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - __SYNReleaseChannelNotes(synth, midiChannel); - break; - default: - break; - } -} - -void __SYNResetController0(SYNSYNTH* synth, u8 midiChannel) { - u8 volume; - u8 pan; - u8 expression; - int i; - - ASSERTLINE(315, synth); - ASSERTLINE(316, midiChannel < 16); - - synth->pwMaxCents[midiChannel] = 0xC80000; - synth->pwCents[midiChannel] = 0; - volume = synth->controller[midiChannel][7]; - pan = synth->controller[midiChannel][10]; - expression = synth->controller[midiChannel][11]; - - for (i = 0; i < 128; i++) { - synth->controller[midiChannel][i] = 0; - } - - __SYNSetController(synth, midiChannel, 7, volume); - __SYNSetController(synth, midiChannel, 0xA, pan); - __SYNSetController(synth, midiChannel, 0xB, expression); - __SYNSetController(synth, midiChannel, 0x5B, 0); - __SYNSetController(synth, midiChannel, 0x5C, 0); -} - -void __SYNResetController(SYNSYNTH* synth, u8 midiChannel) { - int i; - - ASSERTLINE(345, synth); - ASSERTLINE(346, midiChannel < 16); - - synth->pwMaxCents[midiChannel] = 0xC80000; - synth->pwCents[midiChannel] = 0; - - for (i = 0; i < 128; i++) { - synth->controller[midiChannel][i] = 0; - } - - __SYNSetController(synth, midiChannel, 7, 0x64); - __SYNSetController(synth, midiChannel, 0xA, 0x40); - __SYNSetController(synth, midiChannel, 0xB, 0x7F); - __SYNSetController(synth, midiChannel, 0x5B, 0); - __SYNSetController(synth, midiChannel, 0x5C, 0); -} - -void __SYNResetAllControllers(SYNSYNTH* synth) { - u8 midiChannel; - - ASSERTLINE(372, synth); - - for (midiChannel = 0; midiChannel < 16; midiChannel++) { - __SYNProgramChange(synth, midiChannel, 0); - __SYNResetController(synth, midiChannel); - } -} - -static void __SYNNoteOff(SYNSYNTH* synth, u8 midiChannel, u8 keyNum) { - SYNVOICE* voice; - - ASSERTLINE(389, synth); - ASSERTLINE(390, midiChannel < 16); - ASSERTLINE(391, keyNum < 128); - - voice = synth->voice[midiChannel][keyNum]; - if (voice) { - if (synth->controller[midiChannel][64] > 64) { - voice->hold = 1; - return; - } - __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); - synth->voice[midiChannel][keyNum] = 0; - } -} - -static void __SYNNoteOn(SYNSYNTH* synth, u8 midiChannel, u8 keyNum, u8 keyVel) { - AXVPB* axvpb; - SYNVOICE* voice; - SYNVOICE* oldVoice; - - ASSERTLINE(420, synth); - ASSERTLINE(421, midiChannel < 16); - ASSERTLINE(422, keyNum < 128); - ASSERTLINE(423, keyVel < 128); - - if (keyVel) { - if (synth->voice[midiChannel][keyNum]) { - __SYNSetVoiceToRelease(synth->voice[midiChannel][keyNum], synth->priorityNoteRelease); - synth->voice[midiChannel][keyNum] = 0; - } - - axvpb = AXAcquireVoice(synth->priorityVoiceAlloc, &__SYNClearVoiceReferences, (u32)synth); - - if (axvpb) { - voice = &__SYNVoice[axvpb->index]; - voice->axvpb = axvpb; - voice->synth = synth; - voice->midiChannel = midiChannel; - voice->keyNum = keyNum; - voice->keyVel = keyVel; - voice->hold = 0; - - if (__SYNGetWavetableData(voice) != 0) { - synth->voice[midiChannel][keyNum] = voice; - synth->notes++; - voice->keyGroup = voice->region->keyGroup; - if (voice->keyGroup != 0) { - oldVoice = synth->keyGroup[midiChannel][voice->keyGroup]; - if (oldVoice) { - oldVoice->synth = 0; - MIXReleaseChannel(oldVoice->axvpb); - AXFreeVoice(oldVoice->axvpb); - synth->voice[midiChannel][oldVoice->keyNum] = 0; - synth->notes--; - } - synth->keyGroup[midiChannel][voice->keyGroup] = voice; - } - - __SYNSetupPitch(voice); - __SYNSetupVolume(voice); - __SYNSetupPan(voice); - __SYNSetupLfo(voice); - __SYNSetupVolumeEnvelope(voice); - __SYNSetupPitchEnvelope(voice); - - if (midiChannel == 9) { - MIXInitChannel(axvpb, 0, __SYNGetVoiceInput(voice), synth->auxAAttn[midiChannel] >> 0x10, synth->auxBAttn[midiChannel] >> 0x10, voice->pan, 0x7F, __SYNGetVoiceFader(voice)); - } else { - MIXInitChannel(axvpb, 0, __SYNGetVoiceInput(voice), synth->auxAAttn[midiChannel] >> 0x10, synth->auxBAttn[midiChannel] >> 0x10, synth->controller[midiChannel][10], 0x7F, __SYNGetVoiceFader(voice)); - } - - __SYNSetupSample(voice); - __SYNSetupSrc(voice); - axvpb->pb.state = 1; - axvpb->sync = (axvpb->sync | 4); - AXSetVoicePriority(axvpb, synth->priorityNoteOn); - return; - } - - voice->synth = NULL; - MIXReleaseChannel(axvpb); - AXFreeVoice(axvpb); - } - } else { - __SYNNoteOff(synth, midiChannel, keyNum); - } -} - -static void __SYNPitchWheel(SYNSYNTH* synth, u8 midiChannel, u8 lsb, u8 msb) { - s32 position; - - ASSERTLINE(565, synth); - ASSERTLINE(566, midiChannel < 16); - ASSERTLINE(567, lsb < 128); - ASSERTLINE(568, msb < 128); - - position = lsb + (msb << 7) - 0x2000; - synth->pwCents[midiChannel] = (synth->pwMaxCents[midiChannel] * ((f32)position / 8192.0f)); -} - -static void __SYNMidiIn(SYNSYNTH* synth, u8* input) { - u8* ch; - u8 midiFunction; - u8 midiChannel; - u8 _2ndByte; - u8 _3rdByte; - - ASSERTLINE(589, synth); - ASSERTLINE(590, input); - - ch = input; - midiFunction = (*(ch) >> 4); ch += 0; - midiChannel = (*(ch) & 0xF); ch += 1; - _2ndByte = *(ch); ch += 1; - - switch(midiFunction) { - case 8: - __SYNNoteOff(synth, midiChannel, _2ndByte); - return; - case 9: - _3rdByte = *(ch); ch += 1; - __SYNNoteOn(synth, midiChannel, _2ndByte, _3rdByte); - return; - case 11: - _3rdByte = *(ch); ch += 1; - __SYNSetController(synth, midiChannel, _2ndByte, _3rdByte); - return; - case 12: - __SYNProgramChange(synth, midiChannel, _2ndByte); - return; - case 14: - _3rdByte = *(ch); ch+=1; - __SYNPitchWheel(synth, midiChannel, _2ndByte, _3rdByte); - return; - } -} - -void __SYNRunInputBufferEvents(SYNSYNTH* synth) { - u8* input; - - for (input = &synth->input[0][0]; synth->inputCounter; synth->inputCounter--) { - __SYNMidiIn(synth, input); - input+=3; - } - - synth->inputPosition = &synth->input[0][0]; -} - -u8 SYNGetMidiController(SYNSYNTH* synth, u8 midiChannel, u8 function) { - ASSERTLINE(678, synth); - ASSERTLINE(679, midiChannel < 16); - ASSERTLINE(680, function < 128); - return synth->controller[midiChannel][function]; -} diff --git a/src/dolphin/syn/synenv.c b/src/dolphin/syn/synenv.c deleted file mode 100644 index caafb5e..0000000 --- a/src/dolphin/syn/synenv.c +++ /dev/null @@ -1,185 +0,0 @@ -#include -#include -#include -#include "fake_tgmath.h" -#include "cmath.h" - -#include "__syn.h" - -s32 __SYNGetEnvelopeTime(s32 scale, s32 mod, u8 key) { - if (scale == 0x80000000) { - return 0; - } - - if (mod == 0x80000000) { - return (1000.0f* powf(2.0f, (f32)scale / (65536* 1200))); - } - - return (1000.0f* powf(2.0f, ((f32)scale + (mod* __SYNn128[key])) / (65535* 1200))); -} - -void __SYNSetupVolumeEnvelope(SYNVOICE* voice) { - ASSERTLINE(46, voice); - - if (voice->art->eg1Attack + 0x80000000 == 0) { - voice->veState = 1; - voice->veAttn = 0; - if (voice->art->eg1Decay + 0x80000000 == 0) { - voice->veState = 2; - voice->veAttn = voice->art->eg1Sustain; - } - } else { - s32 frames = __SYNGetEnvelopeTime(voice->art->eg1Attack, voice->art->eg1Vel2Attack, voice->keyVel) / 5; - if (frames != 0) { - voice->veAttack = 0; - voice->veAttackDelta = 0x640000 / frames; - voice->veAttn = 0xFC400000; - voice->veState = 0; - } else { - voice->veAttack = 0; - voice->veAttackDelta = 0x640000; - voice->veAttn = 0xFC400000; - voice->veState = 0; - } - } - - if (voice->veState < 2) { - s32 frames = __SYNGetEnvelopeTime(voice->art->eg1Decay, voice->art->eg1Key2Decay, voice->keyNum) / 5; - if (frames != 0) { - voice->veDecay = -0x03C00000 / frames; - } else { - voice->veDecay = -0x03C00000; - } - } - - voice->veSustain = voice->art->eg1Sustain; - voice->veRelease = voice->art->eg1Release; -} - -void __SYNSetupPitchEnvelope(SYNVOICE* voice) { - ASSERTLINE(110, voice); - - voice->peCents = 0; - voice->pePitch = voice->art->eg2Pitch; - if (voice->pePitch != 0) { - if (voice->art->eg2Attack + 0x80000000 == 0) { - voice->peState = 1; - voice->peCents = voice->pePitch; - if (voice->art->eg2Decay + 0x80000000 == 0) { - voice->peState = 2; - voice->peCents = voice->art->eg2Sustain; - } - } else { - s32 frames = __SYNGetEnvelopeTime(voice->art->eg2Attack, voice->art->eg2Vel2Attack, voice->keyVel) / 5; - if (frames != 0) { - voice->peAttack = voice->pePitch / frames; - voice->peState = 0; - } else { - voice->peAttack = voice->pePitch; - voice->peState = 0; - } - } - - if (voice->peState < 2) { - s32 frames = __SYNGetEnvelopeTime(voice->art->eg2Decay, voice->art->eg2Key2Decay, voice->keyNum) / 5; - if (frames != 0) { - voice->peDecay = voice->pePitch / frames; - } else { - voice->peDecay = voice->pePitch; - } - voice->peDecay = voice->peDecay * -1; - } - voice->peSustain = voice->art->eg2Sustain; - voice->peRelease = voice->art->eg2Release; - } -} - -void __SYNRunVolumeEnvelope(SYNVOICE* voice) { - ASSERTLINE(178, voice); - - switch(voice->veState) { - case 0: - voice->veAttack = (voice->veAttack + voice->veAttackDelta); - if (voice->veAttack >= 0x630000) { - voice->veAttn = 0; - } else { - voice->veAttn = __SYNAttackAttnTable[voice->veAttack >> 0x10]; - } - if (voice->veAttn == 0) { - voice->veState = 1; - } - case 2: - return; - case 1: - voice->veAttn = (voice->veAttn + voice->veDecay); - if (voice->veAttn <= voice->veSustain) { - voice->veAttn = voice->veSustain; - voice->veState = 2; - } - if (voice->veAttn <= -0x02D00000) { - voice->veState = 4; - voice->synth->voice[voice->midiChannel][voice->keyNum] = 0; - } - return; - case 3: - if (voice->veAttn <= -0x02D00000) { - voice->veState = 4; - } else { - voice->veAttn = (voice->veAttn + voice->veRelease); - } - return; - } -} - -void __SYNRunPitchEnvelope(SYNVOICE* voice) { - ASSERTLINE(243, voice); - - if (voice->pePitch != 0) { - switch(voice->peState) { - case 0: - voice->peCents = (voice->peCents + voice->peAttack); - if (voice->pePitch > 0) { - if (voice->peCents >= voice->pePitch) { - voice->pePitch = voice->peCents; - voice->peState = 1; - } - } else if (voice->peCents <= voice->pePitch) { - voice->pePitch = voice->peCents; - voice->peState = 1; - } - case 2: - return; - case 1: - voice->peCents = (voice->peCents + voice->peDecay); - if (voice->pePitch > 0) { - if (voice->peCents <= 0) { - voice->peCents = 0; - voice->pePitch = 0; - } else if (voice->peCents <= voice->peSustain) { - voice->peCents = voice->peSustain; - voice->peState = 2; - } - } else { - if (voice->peCents >= 0) { - voice->peCents = 0; - voice->pePitch = 0; - } else if (voice->peCents >= voice->peSustain) { - voice->peCents = voice->peSustain; - voice->peState = 2; - } - } - break; - case 3: - voice->peCents = (voice->peCents + voice->peRelease); - if (voice->pePitch > 0) { - if (voice->peCents <= 0) { - voice->peCents = 0; - voice->pePitch = 0; - } - } else if (voice->peCents >= 0) { - voice->peCents = 0; - voice->pePitch = 0; - } - } - } -} diff --git a/src/dolphin/syn/synlfo.c b/src/dolphin/syn/synlfo.c deleted file mode 100644 index 22ace20..0000000 --- a/src/dolphin/syn/synlfo.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include "fake_tgmath.h" - -#include "__syn.h" - -static f32 __SYNLfo[64] = { - 0.000000f, - 0.098020f, - 0.195090f, - 0.290280f, - 0.382680f, - 0.471400f, - 0.555570f, - 0.634390f, - 0.707110f, - 0.773010f, - 0.831470f, - 0.881920f, - 0.923880f, - 0.956940f, - 0.980790f, - 0.995180f, - 1.000000f, - 0.995180f, - 0.980790f, - 0.956940f, - 0.923880f, - 0.881920f, - 0.831470f, - 0.773010f, - 0.707110f, - 0.634390f, - 0.555570f, - 0.471400f, - 0.382680f, - 0.290280f, - 0.195090f, - 0.098020f, - 0.000000f, - -0.098020f, - -0.195090f, - -0.290280f, - -0.382680f, - -0.471400f, - -0.555570f, - -0.634390f, - -0.707110f, - -0.773010f, - -0.831470f, - -0.881920f, - -0.923880f, - -0.956940f, - -0.980790f, - -0.995180f, - -1.000000f, - -0.995180f, - -0.980790f, - -0.956940f, - -0.923880f, - -0.881920f, - -0.831470f, - -0.773010f, - -0.707110f, - -0.634390f, - -0.555570f, - -0.471400f, - -0.382680f, - -0.290280f, - -0.195090f, - -0.098020f, -}; - -void __SYNSetupLfo(SYNVOICE* voice) { - ASSERTLINE(47, voice); - - voice->lfoState = voice->lfoAttn = voice->lfoCents = 0; - voice->lfoFreq = voice->art->lfoFreq; - voice->lfoDelay = voice->art->lfoDelay; - voice->lfoAttn_ = voice->art->lfoAtten; - voice->lfoCents = voice->art->lfoPitch; - voice->lfoModAttn = voice->art->lfoMod2Atten; - voice->lfoModCents = voice->art->lfoMod2Pitch; -} - -void __SYNRunLfo(SYNVOICE* voice) { - f32 lfoAmplitude; - f32 lfoModWheel; - - ASSERTLINE(66, voice); - - if (voice->lfoDelay != 0) { - voice->lfoDelay--; - } else { - voice->lfoState += voice->lfoFreq; - lfoAmplitude = __SYNLfo[(voice->lfoState >> 0x10) % 64]; - lfoModWheel = __SYNn128[voice->synth->controller[voice->midiChannel][1]]; - voice->lfoAttn = (lfoAmplitude * (voice->lfoAttn_ + (voice->lfoModAttn* lfoModWheel))); - voice->lfoCents = (lfoAmplitude * (voice->lfoCents_ + (voice->lfoModCents* lfoModWheel))); - } -} diff --git a/src/dolphin/syn/synmix.c b/src/dolphin/syn/synmix.c deleted file mode 100644 index 56dc0ac..0000000 --- a/src/dolphin/syn/synmix.c +++ /dev/null @@ -1,274 +0,0 @@ -#include -#include -#include -#include -#include "fake_tgmath.h" - -#include "__syn.h" - -s32 __SYNVolumeAttenuation[128] = { - 0xFC400000, - 0xFCB67A80, - 0xFD2EE3F9, - 0xFD7553B8, - 0xFDA74D72, - 0xFDCE1108, - 0xFDEDBD30, - 0xFE08848A, - 0xFE1FB6EA, - 0xFE342CEF, - 0xFE467A80, - 0xFE57091D, - 0xFE6626A9, - 0xFE740E4D, - 0xFE80EE03, - 0xFE8CEA3F, - 0xFE982063, - 0xFEA2A878, - 0xFEAC9668, - 0xFEB5FADF, - 0xFEBEE3F9, - 0xFEC75DC2, - 0xFECF7295, - 0xFED72B6E, - 0xFEDE9022, - 0xFEE5A78F, - 0xFEEC77C6, - 0xFEF30626, - 0xFEF9577C, - 0xFEFF700E, - 0xFF0553B8, - 0xFF0B05F0, - 0xFF1089DC, - 0xFF15E254, - 0xFF1B11F1, - 0xFF201B12, - 0xFF24FFE1, - 0xFF29C25C, - 0xFF2E6457, - 0xFF32E784, - 0xFF374D72, - 0xFF3B9791, - 0xFF3FC73A, - 0xFF43DDAC, - 0xFF47DC0E, - 0xFF4BC376, - 0xFF4F94E7, - 0xFF535152, - 0xFF56F99B, - 0xFF5A8E94, - 0xFF5E1108, - 0xFF6181B0, - 0xFF64E13E, - 0xFF68305A, - 0xFF6B6F9F, - 0xFF6E9FA4, - 0xFF71C0F4, - 0xFF74D416, - 0xFF77D987, - 0xFF7AD1BF, - 0xFF7DBD30, - 0xFF809C47, - 0xFF836F69, - 0xFF8636F9, - 0xFF88F355, - 0xFF8BA4D4, - 0xFF8E4BCD, - 0xFF90E890, - 0xFF937B6A, - 0xFF9604A6, - 0xFF98848A, - 0xFF9AFB5B, - 0xFF9D6959, - 0xFF9FCEC3, - 0xFFA22BD4, - 0xFFA480C6, - 0xFFA6CDD0, - 0xFFA91327, - 0xFFAB50FD, - 0xFFAD8784, - 0xFFAFB6EA, - 0xFFB1DF5E, - 0xFFB4010A, - 0xFFB61C19, - 0xFFB830B3, - 0xFFBA3F00, - 0xFFBC4724, - 0xFFBE4946, - 0xFFC04587, - 0xFFC23C0A, - 0xFFC42CEF, - 0xFFC61857, - 0xFFC7FE60, - 0xFFC9DF28, - 0xFFCBBACB, - 0xFFCD9166, - 0xFFCF6313, - 0xFFD12FED, - 0xFFD2F80D, - 0xFFD4BB8B, - 0xFFD67A80, - 0xFFD83502, - 0xFFD9EB29, - 0xFFDB9D08, - 0xFFDD4AB7, - 0xFFDEF449, - 0xFFE099D2, - 0xFFE23B66, - 0xFFE3D918, - 0xFFE572F9, - 0xFFE7091D, - 0xFFE89B93, - 0xFFEA2A6D, - 0xFFEBB5BC, - 0xFFED3D8F, - 0xFFEEC1F6, - 0xFFF04300, - 0xFFF1C0BC, - 0xFFF33B38, - 0xFFF4B283, - 0xFFF626A9, - 0xFFF797B9, - 0xFFF905BF, - 0xFFFA70C9, - 0xFFFBD8E2, - 0xFFFD3E16, - 0xFFFEA072, - 0x00000000 -}; - -s32 __SYNAttackAttnTable[100] = { - 0xFC400000, - 0xFE70DF7B, - 0xFEAD1437, - 0xFED04C17, - 0xFEE948F4, - 0xFEFCAABF, - 0xFF0C80D3, - 0xFF19E480, - 0xFF257DB0, - 0xFF2FB8B2, - 0xFF38DF7B, - 0xFF4126C9, - 0xFF48B58F, - 0xFF4FA961, - 0xFF56193C, - 0xFF5C175A, - 0xFF61B26C, - 0xFF66F677, - 0xFF6BED6F, - 0xFF709FAA, - 0xFF751437, - 0xFF79511C, - 0xFF7D5B85, - 0xFF8137F2, - 0xFF84EA4C, - 0xFF887602, - 0xFF8BDE1E, - 0xFF8F254E, - 0xFF924DF9, - 0xFF955A42, - 0xFF984C17, - 0xFF9B2533, - 0xFF9DE729, - 0xFFA09365, - 0xFFA32B33, - 0xFFA5AFC4, - 0xFFA8222B, - 0xFFAA8369, - 0xFFACD466, - 0xFFAF15FD, - 0xFFB148F4, - 0xFFB36E03, - 0xFFB585D8, - 0xFFB79111, - 0xFFB99042, - 0xFFBB83F6, - 0xFFBD6CAE, - 0xFFBF4AE4, - 0xFFC11F08, - 0xFFC2E985, - 0xFFC4AABF, - 0xFFC66313, - 0xFFC812DA, - 0xFFC9BA68, - 0xFFCB5A0A, - 0xFFCCF20D, - 0xFFCE82B5, - 0xFFD00C46, - 0xFFD18EFE, - 0xFFD30B1A, - 0xFFD480D3, - 0xFFD5F05E, - 0xFFD759EF, - 0xFFD8BDB7, - 0xFFDA1BE5, - 0xFFDB74A5, - 0xFFDCC821, - 0xFFDE1683, - 0xFFDF5FF0, - 0xFFE0A48E, - 0xFFE1E480, - 0xFFE31FE8, - 0xFFE456E7, - 0xFFE5899C, - 0xFFE6B825, - 0xFFE7E29E, - 0xFFE90923, - 0xFFEA2BCE, - 0xFFEB4AB9, - 0xFFEC65FD, - 0xFFED7DB0, - 0xFFEE91EA, - 0xFFEFA2C0, - 0xFFF0B047, - 0xFFF1BA94, - 0xFFF2C1BB, - 0xFFF3C5CD, - 0xFFF4C6DE, - 0xFFF5C4FE, - 0xFFF6C040, - 0xFFF7B8B2, - 0xFFF8AE66, - 0xFFF9A16B, - 0xFFFA91CF, - 0xFFFB7FA0, - 0xFFFC6AEE, - 0xFFFD53C4, - 0xFFFE3A31, - 0xFFFF1E41, - 0x00000000 -}; - -void __SYNSetupVolume(SYNVOICE* voice) { - ASSERTLINE(85, voice); - voice->attn = (voice->region->attn + __SYNVolumeAttenuation[voice->keyVel]); -} - -void __SYNSetupPan(SYNVOICE* voice) { - ASSERTLINE(98, voice); - if (voice->midiChannel == 9) { - voice->pan = voice->art->pan; - } else { - voice->pan = voice->synth->controller[voice->midiChannel][10]; - } -} - -s32 __SYNGetVoiceInput(SYNVOICE* voice) { - return (voice->attn + voice->lfoAttn + voice->veAttn) >> 0x10; -} - -s32 __SYNGetVoiceFader(SYNVOICE* voice) { - return (voice->synth->volAttn[voice->midiChannel] + voice->synth->expAttn[voice->midiChannel] + voice->synth->masterVolume) >> 0x10; -} - -void __SYNUpdateMix(SYNVOICE* voice) { - MIXSetInput(voice->axvpb, __SYNGetVoiceInput(voice)); - MIXSetAuxA(voice->axvpb, voice->synth->auxAAttn[voice->midiChannel] >> 0x10); - MIXSetAuxB(voice->axvpb, voice->synth->auxBAttn[voice->midiChannel] >> 0x10); - MIXSetFader(voice->axvpb, __SYNGetVoiceFader(voice)); - - if (voice->midiChannel != 9) { - MIXSetPan(voice->axvpb, voice->synth->controller[voice->midiChannel][10]); - } -} diff --git a/src/dolphin/syn/synpitch.c b/src/dolphin/syn/synpitch.c deleted file mode 100644 index ed1d543..0000000 --- a/src/dolphin/syn/synpitch.c +++ /dev/null @@ -1,340 +0,0 @@ -#include -#include -#include "fake_tgmath.h" - -#include "__syn.h" - -static f32 __SYNCentsTable[100] = { - 1.000000f, - 1.000578f, - 1.001156f, - 1.001734f, - 1.002313f, - 1.002892f, - 1.003472f, - 1.004052f, - 1.004632f, - 1.005212f, - 1.005793f, - 1.006374f, - 1.006956f, - 1.007537f, - 1.008120f, - 1.008702f, - 1.009285f, - 1.009868f, - 1.010451f, - 1.011035f, - 1.011619f, - 1.012204f, - 1.012789f, - 1.013374f, - 1.013959f, - 1.014545f, - 1.015132f, - 1.015718f, - 1.016305f, - 1.016892f, - 1.017480f, - 1.018068f, - 1.018656f, - 1.019244f, - 1.019833f, - 1.020423f, - 1.021012f, - 1.021602f, - 1.022192f, - 1.022783f, - 1.023374f, - 1.023965f, - 1.024557f, - 1.025149f, - 1.025741f, - 1.026334f, - 1.026927f, - 1.027520f, - 1.028114f, - 1.028708f, - 1.029302f, - 1.029897f, - 1.030492f, - 1.031087f, - 1.031683f, - 1.032279f, - 1.032876f, - 1.033472f, - 1.034070f, - 1.034667f, - 1.035265f, - 1.035863f, - 1.036462f, - 1.037060f, - 1.037660f, - 1.038259f, - 1.038859f, - 1.039459f, - 1.040060f, - 1.040661f, - 1.041262f, - 1.041864f, - 1.042466f, - 1.043068f, - 1.043671f, - 1.044274f, - 1.044877f, - 1.045481f, - 1.046085f, - 1.046689f, - 1.047294f, - 1.047899f, - 1.048505f, - 1.049111f, - 1.049717f, - 1.050323f, - 1.050930f, - 1.051537f, - 1.052145f, - 1.052753f, - 1.053361f, - 1.053970f, - 1.054579f, - 1.055188f, - 1.055798f, - 1.056408f, - 1.057018f, - 1.057629f, - 1.058240f, - 1.058851f, -}; - -static f32 __SYNOctavesTableUp[12] = { - 1.000000f, - 2.000000f, - 4.000000f, - 8.000000f, - 16.000000f, - 32.000000f, - 64.000000f, - 128.000000f, - 256.000000f, - 512.000000f, - 1024.000000f, - 2048.000000f, -}; - -static f32 __SYNSemitonesTableUp[12] = { - 1.000000f, - 1.059463f, - 1.122462f, - 1.189207f, - 1.259921f, - 1.334840f, - 1.414214f, - 1.498307f, - 1.587401f, - 1.681793f, - 1.781797f, - 1.887749f, -}; - -static f32 __SYNSemitonesTableDown[128] = { - 1.000000f, - 0.943874f, - 0.890899f, - 0.840896f, - 0.793701f, - 0.749154f, - 0.707107f, - 0.667420f, - 0.629961f, - 0.594604f, - 0.561231f, - 0.529732f, - 0.500000f, - 0.471937f, - 0.445449f, - 0.420448f, - 0.396850f, - 0.374577f, - 0.353553f, - 0.333710f, - 0.314980f, - 0.297302f, - 0.280616f, - 0.264866f, - 0.250000f, - 0.235969f, - 0.222725f, - 0.210224f, - 0.198425f, - 0.187288f, - 0.176777f, - 0.166855f, - 0.157490f, - 0.148651f, - 0.140308f, - 0.132433f, - 0.125000f, - 0.117984f, - 0.111362f, - 0.105112f, - 0.099213f, - 0.093644f, - 0.088388f, - 0.083427f, - 0.078745f, - 0.074325f, - 0.070154f, - 0.066216f, - 0.062500f, - 0.058992f, - 0.055681f, - 0.052556f, - 0.049606f, - 0.046822f, - 0.044194f, - 0.041714f, - 0.039373f, - 0.037163f, - 0.035077f, - 0.033108f, - 0.031250f, - 0.029496f, - 0.027841f, - 0.026278f, - 0.024803f, - 0.023411f, - 0.022097f, - 0.020857f, - 0.019686f, - 0.018581f, - 0.017538f, - 0.016554f, - 0.015625f, - 0.014748f, - 0.013920f, - 0.013139f, - 0.012402f, - 0.011706f, - 0.011049f, - 0.010428f, - 0.009843f, - 0.009291f, - 0.008769f, - 0.008277f, - 0.007813f, - 0.007374f, - 0.006960f, - 0.006570f, - 0.006201f, - 0.005853f, - 0.005524f, - 0.005214f, - 0.004922f, - 0.004645f, - 0.004385f, - 0.004139f, - 0.003906f, - 0.003687f, - 0.003480f, - 0.003285f, - 0.003100f, - 0.002926f, - 0.002762f, - 0.002607f, - 0.002461f, - 0.002323f, - 0.002192f, - 0.002069f, - 0.001953f, - 0.001844f, - 0.001740f, - 0.001642f, - 0.001550f, - 0.001463f, - 0.001381f, - 0.001304f, - 0.001230f, - 0.001161f, - 0.001096f, - 0.001035f, - 0.000977f, - 0.000922f, - 0.000870f, - 0.000821f, - 0.000775f, - 0.000732f, - 0.000691f, - 0.000652f, -}; - -f32 __SYNGetRelativePitch(SYNVOICE* voice) { - s32 cents; - - cents = voice->cents + voice->lfoCents + voice->peCents + voice->synth->pwCents[voice->midiChannel]; - cents = cents / 65536; - - if (cents > 0) { - s32 octaves = (cents / 1200); - s32 semitones = (cents % 1200) / 100; - cents = (cents % 100); - return __SYNOctavesTableUp[octaves] * __SYNSemitonesTableUp[semitones] * __SYNCentsTable[cents]; - } - - if (cents < 0) { - s32 semitones = cents / 100; - cents = (cents % 100); - if (cents != 0) { - cents += 100; - semitones-=1; - } - semitones *= -1; - return __SYNSemitonesTableDown[semitones] * __SYNCentsTable[cents]; - } - - return 1.0f; -} - -void __SYNSetupPitch(SYNVOICE* voice) { - voice->srcRatio = (voice->sample->sampleRate / 32000.0f); - voice->cents = (voice->keyNum - voice->region->unityNote) * 100; - voice->cents = (voice->cents + voice->region->fineTune); - voice->cents = (voice->cents << 0x10); -} - -void __SYNSetupSrc(SYNVOICE* voice) { - f32 srcRatio; - u32 value; - u16* p; - - srcRatio = voice->srcRatio* __SYNGetRelativePitch(voice); - if (srcRatio > 4.0f) { - value = 0x40000; - } else { - value = (65536.0f* srcRatio); - } - - voice->axvpb->pb.srcSelect = 1; - p = (void*)&voice->axvpb->pb.src; - *(p) = (value >> 0x10); p += 1; - *(p) = (value); p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - - voice->axvpb->sync &= 0xFFF7FFFF; - voice->axvpb->sync |= 0x40001; -} - -void __SYNUpdateSrc(SYNVOICE* voice) { - u32 ratio = (65536.0f * (voice->srcRatio * __SYNGetRelativePitch(voice))); - - if (ratio > 0x40000) { - ratio = 0x40000; - } - - *(u32*)&voice->axvpb->pb.src.ratioHi = ratio; - voice->axvpb->sync |= 0x80000; -} diff --git a/src/dolphin/syn/synsample.c b/src/dolphin/syn/synsample.c deleted file mode 100644 index 8419c57..0000000 --- a/src/dolphin/syn/synsample.c +++ /dev/null @@ -1,241 +0,0 @@ -#include -#include -#include -#include "fake_tgmath.h" - -#include "__syn.h" - -// prototypes -static u32 __SYNGetNibbleAddress(u32 count); -static void __SYNSetupAdpcm(SYNVOICE* voice); -static void __SYNSetupPcm16(SYNVOICE* voice); -static void __SYNSetupPcm8(SYNVOICE* voice); - -static u32 __SYNGetNibbleAddress(u32 count) { - u32 samples = count; - u32 frames = (samples / 14); - u32 samplesLeft = (samples % 14); - - return (frames * 0x10) + 2 + samplesLeft; -} - -static void __SYNSetupAdpcm(SYNVOICE* voice) { - AXVPB* axvpb = voice->axvpb; - - if ((voice->region->loopStart + voice->region->loopLength) != 0) { - u32 sampleStart; - u32 sampleLoop; - u32 sampleEnd; - u32* p; - u32* adpcm; - u16* adpcmloop; - - adpcm = (void*)&voice->adpcm->a; - voice->type = 1; - sampleStart = voice->synth->aramBaseNibble + voice->sample->offset; - sampleLoop = sampleStart + __SYNGetNibbleAddress(voice->region->loopStart); - sampleEnd = sampleStart + __SYNGetNibbleAddress(voice->region->loopStart + voice->region->loopLength - 1); - ASSERTLINE(79, (sampleStart & 0x000f) == 0); - ASSERTLINE(80, (sampleLoop & 0x000f) > 1); - ASSERTLINE(81, (sampleEnd & 0x000f) > 1); - - // the hell? why not just write the members??? what is this doing??? - // why not just write to the members directly? - sampleStart = sampleStart + 2; - p = (u32*)&axvpb->pb.addr; - *(p) = 0x10000; p += 1; - *(p) = sampleLoop; p += 1; - *(p) = sampleEnd; p += 1; - *(p) = sampleStart; p += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - adpcmloop = (void*)(adpcm); - axvpb->pb.adpcmLoop.loop_pred_scale = *(adpcmloop); adpcmloop += 1; - axvpb->pb.adpcmLoop.loop_yn1 = *(adpcmloop); adpcmloop += 1; - axvpb->pb.adpcmLoop.loop_yn2 = *(adpcmloop); adpcmloop += 1; - axvpb->sync &= 0xFFFE1FFF; - axvpb->sync |= 0x121000; - } else { - u32 sampleStart; - u32 sampleLoop; - u32 sampleEnd; - u32* p; - u32* adpcm; - - adpcm = (void*)&voice->adpcm->a; - voice->type = 0; - sampleStart = voice->synth->aramBaseNibble + voice->sample->offset; - sampleLoop = sampleStart + __SYNGetNibbleAddress(voice->synth->zeroBaseNibble); - sampleEnd = sampleStart + __SYNGetNibbleAddress(voice->sample->length - 1); - - ASSERTLINE(135, (sampleStart & 0x000f) == 0); - ASSERTLINE(136, (sampleEnd & 0x000f) > 1); - - // same wtf writes here - sampleStart = sampleStart + 2; - p = (void*)&axvpb->pb.addr; - *(p) = 0; p += 1; - *(p) = sampleLoop; p += 1; - *(p) = sampleEnd; p += 1; - *(p) = sampleStart; p += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - *(p) = *(adpcm); p += 1, adpcm += 1; - axvpb->sync &= 0xFFFE1FFF; - axvpb->sync |= 0x21000; - } -} - -static void __SYNSetupPcm16(SYNVOICE* voice) { - AXVPB* axvpb = voice->axvpb; - - if ((voice->region->loopStart + voice->region->loopLength) != 0) { - u32 sampleStart; - u32 sampleLoop; - u32 sampleEnd; - u32* p; - - voice->type = 1; - sampleStart = voice->synth->aramBaseWord + voice->sample->offset; - sampleLoop = sampleStart + voice->region->loopStart; - sampleEnd = sampleLoop + voice->region->loopLength - 1; - - p = (u32*)&axvpb->pb.addr; - *(p) = 0x1000A; p += 1; - *(p) = sampleLoop; p += 1; - *(p) = sampleEnd; p += 1; - *(p) = sampleStart; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0x08000000; p += 1; - *(p) = 0; p += 1; - } else { - u32 sampleStart; - u32 sampleLoop; - u32 sampleEnd; - u32* p; - - voice->type = 0; - sampleStart = voice->synth->aramBaseWord + voice->sample->offset; - sampleLoop = voice->synth->zeroBaseWord; - sampleEnd = sampleStart + voice->sample->length - 1; - - p = (u32*)&axvpb->pb.addr; - *(p) = 0x0000A; p += 1; - *(p) = sampleLoop; p += 1; - *(p) = sampleEnd; p += 1; - *(p) = sampleStart; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0x08000000; p += 1; - *(p) = 0; p += 1; - } - axvpb->sync &= 0xFFFE1FFF; - axvpb->sync |= 0x21000; -} - -static void __SYNSetupPcm8(SYNVOICE* voice) { - AXVPB* axvpb = voice->axvpb; - - if ((voice->region->loopStart + voice->region->loopLength) != 0) { - u32 sampleStart; - u32 sampleLoop; - u32 sampleEnd; - u32* p; - - voice->type = 1; - sampleStart = voice->synth->aramBaseByte + voice->sample->offset; - sampleLoop = sampleStart + voice->region->loopStart; - sampleEnd = sampleLoop + voice->region->loopLength - 1; - p = (u32*)&axvpb->pb.addr; - *(p) = 0x10019; p += 1; - *(p) = sampleLoop; p += 1; - *(p) = sampleEnd; p += 1; - *(p) = sampleStart; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0x01000000; p += 1; - *(p) = 0; p += 1; - } else { - u32 sampleStart; - u32 sampleLoop; - u32 sampleEnd; - u32* p; - - voice->type = 0; - sampleStart = voice->synth->aramBaseByte + voice->sample->offset; - sampleLoop = voice->synth->zeroBaseByte; - sampleEnd = sampleStart + voice->sample->length - 1; - - p = (u32*)&axvpb->pb.addr; - *(p) = 0x19; p += 1; - *(p) = sampleLoop; p += 1; - *(p) = sampleEnd; p += 1; - *(p) = sampleStart; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0; p += 1; - *(p) = 0x01000000; p += 1; - *(p) = 0; p += 1; - } - - axvpb->sync &= 0xFFFE1FFF; - axvpb->sync |= 0x21000; -} - -void __SYNSetupSample(SYNVOICE* voice) { - ASSERTLINE(361, voice); - - switch(voice->sample->format) { - case SYN_SAMPLE_FORMAT_ADPCM: - __SYNSetupAdpcm(voice); - return; - case SYN_SAMPLE_FORMAT_PCM16: - __SYNSetupPcm16(voice); - return; - case SYN_SAMPLE_FORMAT_PCM8: - __SYNSetupPcm8(voice); - return; - default: - ASSERTMSGLINE(385, FALSE, "unknown sample format\n"); - return; - } -} diff --git a/src/dolphin/syn/synvoice.c b/src/dolphin/syn/synvoice.c deleted file mode 100644 index ea5e66d..0000000 --- a/src/dolphin/syn/synvoice.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include "fake_tgmath.h" - -#include "__syn.h" - -#define AX_MAX_VOICES 64 - -SYNVOICE __SYNVoice[64]; - -void __SYNClearVoiceReferences(void* p) { - AXVPB* axvpb; - SYNSYNTH* synth; - SYNVOICE* voice; - - ASSERTLINE(33, p); - - axvpb = p; - synth = (void*)axvpb->userContext; - voice = &__SYNVoice[axvpb->index]; - - ASSERTLINE(38, synth); - ASSERTLINE(39, axvpb->index < AX_MAX_VOICES); - MIXReleaseChannel(axvpb); - - if (voice->keyGroup) { - synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; - } - if (synth->voice[voice->midiChannel][voice->keyNum] == voice) { - synth->voice[voice->midiChannel][voice->keyNum] = 0; - } - - voice->synth = 0; - synth->notes--; -} - -void __SYNSetVoiceToRelease(SYNVOICE* voice, u32 priority) { - ASSERTLINE(63, voice); - voice->veState = 3; - voice->peState = 3; - AXSetVoicePriority(voice->axvpb, priority); -} - -void __SYNServiceVoice(int i) { - SYNVOICE* voice; - SYNSYNTH* synth; - - voice = &__SYNVoice[i]; - synth = voice->synth; - - if (synth != NULL) { - if ((voice->type == 0) && (voice->axvpb->pb.state == 0)) { - if (voice->keyGroup != 0) { - voice->synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; - } - if (synth->voice[voice->midiChannel][voice->keyNum] == voice) { - synth->voice[voice->midiChannel][voice->keyNum] = 0; - } - voice->veState = 4; - } - - __SYNRunVolumeEnvelope(voice); - - if (voice->veState == 4) { - if (voice->keyGroup != 0) { - voice->synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; - } - voice->synth = NULL; - MIXReleaseChannel(voice->axvpb); - AXFreeVoice(voice->axvpb); - synth->notes--; - return; - } - - __SYNRunLfo(voice); - __SYNRunPitchEnvelope(voice); - __SYNUpdateMix(voice); - __SYNUpdateSrc(voice); - } -} diff --git a/src/dolphin/syn/synwt.c b/src/dolphin/syn/synwt.c deleted file mode 100644 index 6a03e03..0000000 --- a/src/dolphin/syn/synwt.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include "fake_tgmath.h" - -#include "__syn.h" - -int __SYNGetWavetableData(SYNVOICE* voice) { - u32 regionIndex; - SYNSYNTH* synth; - - synth = voice->synth; - regionIndex = synth->inst[voice->midiChannel]->keyRegion[voice->keyNum]; - if (regionIndex == 0xFFFF) { - return 0; - } - voice->region = &synth->region[regionIndex]; - voice->art = &synth->art[voice->region->articulationIndex]; - voice->sample = &synth->sample[voice->region->sampleIndex]; - voice->adpcm = &synth->adpcm[voice->sample->adpcmIndex]; - return 1; -} diff --git a/src/dolphin/texPalette/texPalette.c b/src/dolphin/texPalette/texPalette.c deleted file mode 100644 index 7f3a87f..0000000 --- a/src/dolphin/texPalette/texPalette.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -#include - -static void LoadTexPalette(TEXPalettePtr* pal, char* name); -static void UnpackTexPalette(TEXPalettePtr pal); -static void TexFreeFunc(TEXPalettePtr* pal); - -void TEXGetPalette(TEXPalettePtr* pal, char* name) { - void* p = TexFreeFunc; - - if (DOCacheInitialized) { - *pal = (TEXPalettePtr)DSGetCacheObj(&DODisplayCache, name); - } - - if (!*pal) { - LoadTexPalette(pal, name); - if (DOCacheInitialized) { - DSAddCacheNode(&DODisplayCache, name, (Ptr)*pal, p); - DSGetCacheObj(&DODisplayCache, name); - } - } -} - -static void LoadTexPalette(TEXPalettePtr* pal, char* name) { - DVDFileInfo dfi; - - DVDOpen(name, &dfi); - *pal = OSAlloc(OSRoundUp32B(dfi.length)); - DVDReadPrio(&dfi, *pal, OSRoundUp32B(dfi.length), 0, 2); - DVDClose(&dfi); - UnpackTexPalette(*pal); -} - -#define PALETTE_VERSION 0x20AF30 - -static void UnpackTexPalette(TEXPalettePtr pal) { - u16 i; - - if (pal->versionNumber != PALETTE_VERSION) { - OSPanic(__FILE__, 86, "invalid version number for texture palette"); - } - - pal->descriptorArray = (TEXDescriptorPtr)((Ptr)pal->descriptorArray + (u32)pal); - for (i = 0; i < pal->numDescriptors; i++) { - if (pal->descriptorArray[i].textureHeader) { - pal->descriptorArray[i].textureHeader = (TEXHeaderPtr)((Ptr)pal + (u32)pal->descriptorArray[i].textureHeader); - if (!pal->descriptorArray[i].textureHeader->unpacked) { - pal->descriptorArray[i].textureHeader->data = (Ptr)pal + (u32)pal->descriptorArray[i].textureHeader->data; - pal->descriptorArray[i].textureHeader->unpacked = TRUE; - } - } - - if (pal->descriptorArray[i].CLUTHeader) { - pal->descriptorArray[i].CLUTHeader = (CLUTHeaderPtr)((u8 *)pal + (u32)pal->descriptorArray[i].CLUTHeader); - if (!pal->descriptorArray[i].CLUTHeader->unpacked) { - pal->descriptorArray[i].CLUTHeader->data = (Ptr)pal + (u32)pal->descriptorArray[i].CLUTHeader->data; - pal->descriptorArray[i].CLUTHeader->unpacked = TRUE; - } - } - } -} - -TEXDescriptorPtr TEXGet(TEXPalettePtr pal, u32 id) { - ASSERTMSGLINE(147, id < pal->numDescriptors, "GetTexture(): Texture Not Found "); - return &pal->descriptorArray[id]; -} - -static void TexFreeFunc(TEXPalettePtr* pal) { - OSFree(*pal); - *pal = NULL; -} - -void TEXReleasePalette(TEXPalettePtr* pal) { - if (DOCacheInitialized) { - DSReleaseCacheObj(&DODisplayCache, (Ptr)*pal); - } else { - OSFree(*pal); - *pal = NULL; - } -} - -void TEXGetGXTexObjFromPalette(TEXPalettePtr pal, GXTexObj* to, u32 id) { - TEXDescriptorPtr tdp; - GXBool mipMap; - - tdp = TEXGet(pal, id); - if (tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD) { - mipMap = GX_FALSE; - } else { - mipMap = GX_TRUE; - } - GXInitTexObj(to, tdp->textureHeader->data, tdp->textureHeader->width, tdp->textureHeader->height, tdp->textureHeader->format, tdp->textureHeader->wrapS, tdp->textureHeader->wrapT, mipMap); - GXInitTexObjLOD(to, tdp->textureHeader->minFilter, tdp->textureHeader->magFilter, tdp->textureHeader->minLOD, tdp->textureHeader->maxLOD, tdp->textureHeader->LODBias, GX_DISABLE, tdp->textureHeader->edgeLODEnable, GX_ANISO_1); -} - -void TEXGetGXTexObjFromPaletteCI(TEXPalettePtr pal, GXTexObj* to, GXTlutObj* tlo, GXTlut tluts, u32 id) { - GXBool mipMap; - TEXDescriptorPtr tdp; - - tdp = TEXGet(pal, id); - if (tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD) { - mipMap = GX_FALSE; - } else { - mipMap = GX_TRUE; - } - GXInitTlutObj(tlo, tdp->CLUTHeader->data, tdp->CLUTHeader->format, tdp->CLUTHeader->numEntries); - GXInitTexObjCI(to, tdp->textureHeader->data, tdp->textureHeader->width, tdp->textureHeader->height, tdp->textureHeader->format, tdp->textureHeader->wrapS, tdp->textureHeader->wrapT, mipMap, tluts); - GXInitTexObjLOD(to, tdp->textureHeader->minFilter, tdp->textureHeader->magFilter, tdp->textureHeader->minLOD, tdp->textureHeader->maxLOD, tdp->textureHeader->LODBias, GX_DISABLE, tdp->textureHeader->edgeLODEnable, GX_ANISO_1); -} diff --git a/src/dolphin/vi/__vi.h b/src/dolphin/vi/__vi.h deleted file mode 100644 index 1132f8c..0000000 --- a/src/dolphin/vi/__vi.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _DOLPHIN_VI_INTERNAL_H_ -#define _DOLPHIN_VI_INTERNAL_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* gpioexi.c */ - -void __VIInitI2C(void); -void __VISetSCL(int value); -int __VIGetSCL(void); -void __VISetSDA(int value); -int __VIGetSDA(void); - -/* i2c.c */ - -int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes); - -/* initphilips.c */ - -void __VIInitPhilips(void); - -/* vi.c */ - -void __VIInit(VITVMode mode); -void __VISetAdjustingValues(s16 x, s16 y); -void __VIGetAdjustingValues(s16* x, s16* y); -void __VIGetCurrentPosition(s16* x, s16* y); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/dolphin/vi/gpioexi.c b/src/dolphin/vi/gpioexi.c deleted file mode 100644 index db3c8f3..0000000 --- a/src/dolphin/vi/gpioexi.c +++ /dev/null @@ -1,146 +0,0 @@ -#include -#include -#include - -#include "__vi.h" - -static u8 shadowGPIOOE; -static u8 shadowGPIOData; - -// prototypes -static void initGpioExi(void); -static void setVideoReset(int value); -static void setI2CEnable(int value); -static int gpioOutput(u8 value); -static int gpioOE(u8 value); -static int gpioOut(u32 addr, u8 value); -static int gpioInput(u8* p); - -void __VIInitI2C(void) { - OSTime time; - - initGpioExi(); - setVideoReset(0); - time = OSGetTime(); - while (OSGetTime() - time < OS_USEC_TO_TICKS(100)) {} - setVideoReset(1); - setI2CEnable(1); -} - -static void initGpioExi(void) { - shadowGPIOOE = 0; - shadowGPIOData = 0; - gpioOutput(shadowGPIOData); - gpioOE(shadowGPIOOE); -} - -void __VISetSCL(int value) { - shadowGPIOOE &= ~2; - if (value == 0) { - shadowGPIOOE |= 2; - } - gpioOE(shadowGPIOOE); -} - -int __VIGetSCL(void) { - u8 value; - - gpioInput(&value); - if (value & 2) { - return 1; - } else { - return 0; - } -} - -void __VISetSDA(int value) { - shadowGPIOOE &= ~1; - if (value == 0) { - shadowGPIOOE |= 1; - } - gpioOE(shadowGPIOOE); -} - -int __VIGetSDA(void) { - u8 value; - - gpioInput(&value); - if (value & 1) { - return 1; - } else { - return 0; - } -} - -static void setVideoReset(int value) { - if (value != 0) { - shadowGPIOData |= 4; - } else { - shadowGPIOData &= ~4; - } - shadowGPIOOE |= 4; - gpioOutput(shadowGPIOData); - gpioOE(shadowGPIOOE); -} - -static void setI2CEnable(int value) { - if (value != 0) { - shadowGPIOData &= ~0x10; - } else { - shadowGPIOData |= 0x10; - } - shadowGPIOOE |= 0x10; - gpioOutput(shadowGPIOData); - gpioOE(shadowGPIOOE); -} - -static int gpioOutput(u8 value) { - return gpioOut(0x800404U, value); -} - -static int gpioOE(u8 value) { - return gpioOut(0x800408U, value); -} - -static int gpioOut(u32 addr, u8 value) { - u32 cmd; - - cmd = (addr | 0x02000000) << 6; - if (EXILock(0, 1, 0) == 0) { - return 0; - } - if (EXISelect(0, 1, 4) == 0) { - EXIUnlock(0); - return 0; - } - - EXIImm(0, &cmd, 4, EXI_WRITE, 0); - EXISync(0); - cmd = value << 24; - EXIImm(0, &cmd, 1, EXI_WRITE, 0); - EXISync(0); - EXIDeselect(0); - EXIUnlock(0); - return 1; -} - -static int gpioInput(u8* p) { - u32 cmd; - - if (EXILock(0, 1, 0) == 0) { - return 0; - } - if (EXISelect(0, 1, 4) == 0) { - EXIUnlock(0); - return 0; - } - cmd = 0x20010100; - EXIImm(0, &cmd, 4, EXI_WRITE, 0); - EXISync(0); - EXIImm(0, &cmd, 1, EXI_READ, 0); - EXISync(0); - EXIDeselect(0); - EXIUnlock(0); - *p = cmd >> 24; - return 1; -} diff --git a/src/dolphin/vi/i2c.c b/src/dolphin/vi/i2c.c deleted file mode 100644 index af048c6..0000000 --- a/src/dolphin/vi/i2c.c +++ /dev/null @@ -1,105 +0,0 @@ -#include - -#include "__vi.h" - -static int lastError; - -static int wait4ClkHigh(void) { - int n; - - for (n = 0; n < 1000; n++) { - if (__VIGetSCL() != 0) { - return 1; - } - } - - lastError = 2; - return 0; -} - -static int sendSlaveAddr(u8 slaveAddr) { - int i; - - __VISetSDA(0); - __VISetSCL(0); - - for (i = 0; i < 8; i++) { - if (slaveAddr & 0x80) { - __VISetSDA(1); - } else { - __VISetSDA(0); - } - - __VISetSCL(1); - if (wait4ClkHigh() == 0) { - return 0; - } - - __VISetSCL(0); - slaveAddr <<= 1; - } - - __VISetSDA(1); - __VISetSCL(1); - - if (wait4ClkHigh() == 0) { - return 0; - } - - if (__VIGetSDA() != 0) { - lastError = 1; - return 0; - } - - __VISetSCL(0); - return 1; -} - -int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes) { - s32 i; - u8 data; - - if (sendSlaveAddr(slaveAddr) == 0) { - return 0; - } - - while (nBytes != 0) { - data = *pData++; - for (i = 0; i < 8; i++) { - if (data & 0x80) { - __VISetSDA(1); - } else { - __VISetSDA(0); - } - - __VISetSCL(1); - - if (wait4ClkHigh() == 0) { - return 0; - } - - __VISetSCL(0); - data <<= 1; - } - - __VISetSDA(1); - __VISetSCL(1); - - if (wait4ClkHigh() == 0) { - return 0; - } - - if (nBytes != 1 && __VIGetSDA() != 0) { - lastError = 1; - return 0; - } - - __VISetSCL(0); - nBytes--; - } - - __VISetSDA(0); - __VISetSCL(1); - __VISetSDA(1); - return 1; -} diff --git a/src/dolphin/vi/initphilips.c b/src/dolphin/vi/initphilips.c deleted file mode 100644 index 81358ad..0000000 --- a/src/dolphin/vi/initphilips.c +++ /dev/null @@ -1,73 +0,0 @@ -#include - -#include "__vi.h" - -static u8 ntscRange0[4] = { 0x00, 0x00, 0x19, 0x1D }; - -static u8 ntscRange1[38] = { - 0x2D, 0x76, 0xA5, 0x2A, - 0x2E, 0x2E, 0x00, 0x15, - 0x3F, 0x1F, 0x7C, 0xF0, - 0x21, 0x55, 0x56, 0x67, - 0x58, 0x20, 0xF9, 0x00, - 0xB0, 0x14, 0x80, 0xE8, - 0x10, 0x42, 0x03, 0x03, - 0x05, 0x16, 0x04, 0x16, - 0x18, 0x38, 0x40, 0x00, - 0x00, 0x00 -}; - -static u8 palRange0[4] = { 0x00, 0x00, 0x21, 0x1D }; - -static u8 palRange1[38] = { - 0x0C, 0x7D, 0xAF, 0x23, - 0x35, 0x35, 0x00, 0x06, - 0x2F, 0xCB, 0x8A, 0x09, - 0x2A, 0x55, 0x56, 0x67, - 0x58, 0x20, 0x05, 0x20, - 0xA0, 0x14, 0x80, 0xE8, - 0x10, 0x42, 0x03, 0x03, - 0x05, 0x16, 0x04, 0x16, - 0x18, 0x38, 0x40, 0x00, - 0x00, 0x00 -}; - -static u8 value3a = 19; - -static void send7120Data(u8 *range0, u8 *range1) { - u8 i; - u8 buffer[2]; - - for (i = 0; i < 38; i++) { - buffer[0] = i; - buffer[1] = 0; - __VISendI2CData(0x88, buffer, 2); - } - - for (i = 38; i < 42; i++) { - buffer[0] = i; - buffer[1] = range0[i - 38]; - __VISendI2CData(0x88, buffer, 2); - } - - for (i = 42; i < 58; i++) { - buffer[0] = i; - buffer[1] = 0; - __VISendI2CData(0x88, buffer, 2); - } - - buffer[0] = 0x3A; - buffer[1] = value3a; - __VISendI2CData(0x88, buffer, 2); - - for (i = 90; i < 128; i++) { - buffer[0] = i; - buffer[1] = range1[i - 90]; - __VISendI2CData(0x88, buffer, 2); - } -} - -void __VIInitPhilips(void) { - __VIInitI2C(); - send7120Data(ntscRange0, ntscRange1); -} diff --git a/src/dolphin/vi/vi.c b/src/dolphin/vi/vi.c deleted file mode 100644 index c28ed1c..0000000 --- a/src/dolphin/vi/vi.c +++ /dev/null @@ -1,1307 +0,0 @@ -#include -#include -#include -#include -#include - -#include "__gx.h" -#include "__os.h" -#include "__vi.h" - -#ifdef DEBUG -const char* __VIVersion = "<< Dolphin SDK - VI\tdebug build: Apr 7 2004 03:55:59 (0x2301) >>"; -#else -const char* __VIVersion = "<< Dolphin SDK - VI\trelease build: Apr 7 2004 04:13:59 (0x2301) >>"; -#endif - -typedef struct { - u8 equ; - u16 acv; - u16 prbOdd; - u16 prbEven; - u16 psbOdd; - u16 psbEven; - u8 bs1; - u8 bs2; - u8 bs3; - u8 bs4; - u16 be1; - u16 be2; - u16 be3; - u16 be4; - u16 nhlines; - u16 hlw; - u8 hsy; - u8 hcs; - u8 hce; - u8 hbe640; - u16 hbs640; - u8 hbeCCIR656; - u16 hbsCCIR656; -} VITiming; - -typedef struct { - u16 DispPosX; - u16 DispPosY; - u16 DispSizeX; - u16 DispSizeY; - u16 AdjustedDispPosX; - u16 AdjustedDispPosY; - u16 AdjustedDispSizeY; - u16 AdjustedPanPosY; - u16 AdjustedPanSizeY; - u16 FBSizeX; - u16 FBSizeY; - u16 PanPosX; - u16 PanPosY; - u16 PanSizeX; - u16 PanSizeY; - VIXFBMode FBMode; - u32 nonInter; - u32 tv; - u8 wordPerLine; - u8 std; - u8 wpl; - u32 bufAddr; - u32 tfbb; - u32 bfbb; - u8 xof; - BOOL black; - BOOL threeD; - u32 rbufAddr; - u32 rtfbb; - u32 rbfbb; - VITiming* timing; -} SomeVIStruct; - -static BOOL IsInitialized; -static volatile u32 retraceCount; - -static volatile u32 flushFlag; -static OSThreadQueue retraceQueue; -static void (*PreCB)(u32); -static void (*PostCB)(u32); -static void (*PositionCallback)(s16, s16); -static u32 encoderType; -static s16 displayOffsetH; -static s16 displayOffsetV; -static volatile u32 changeMode; -static volatile u64 changed; -static volatile u32 shdwChangeMode; -static volatile u16 regs[59]; -static volatile u64 shdwChanged; -static VITiming* CurrTiming; -static u32 CurrTvMode; -static u32 NextBufAddr; -static u32 CurrBufAddr; -static volatile u16 shdwRegs[59]; - -#define MARK_CHANGED(index) (changed |= 1LL << (63 - (index))) - -static VITiming timing[10] = { - { 6, 240, 24, 25, 3, 2, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 162, 373, 122, 412 }, - { 6, 240, 24, 24, 4, 4, 12, 12, 12, 12, 520, 520, 520, 520, 526, 429, 64, 71, 105, 162, 373, 122, 412 }, - { 5, 287, 35, 36, 1, 0, 13, 12, 11, 10, 619, 618, 617, 620, 625, 432, 64, 75, 106, 172, 380, 133, 420 }, - { 5, 287, 33, 33, 2, 2, 13, 11, 13, 11, 619, 621, 619, 621, 624, 432, 64, 75, 106, 172, 380, 133, 420 }, - { 6, 240, 24, 25, 3, 2, 16, 15, 14, 13, 518, 517, 516, 519, 525, 429, 64, 78, 112, 162, 373, 122, 412 }, - { 6, 240, 24, 24, 4, 4, 16, 14, 16, 14, 518, 520, 518, 520, 526, 429, 64, 78, 112, 162, 373, 122, 412 }, - { 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 162, 373, 122, 412 }, - { 12, 480, 44, 44, 10, 10, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 168, 379, 122, 412 }, - { 6, 241, 24, 25, 1, 0, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 159, 370, 122, 412 }, - { 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 180, 391, 122, 412 } -}; - -static u16 taps[25] = { - 0x01F0, 0x01DC, - 0x01AE, 0x0174, - 0x0129, 0x00DB, - 0x008E, 0x0046, - 0x000C, 0x00E2, - 0x00CB, 0x00C0, - 0x00C4, 0x00CF, - 0x00DE, 0x00EC, - 0x00FC, 0x0008, - 0x000F, 0x0013, - 0x0013, 0x000F, - 0x000C, 0x0008, - 0x0001 -}; - -static SomeVIStruct HorVer; -static u32 FBSet; -static VITiming* timingExtra; - -// prototypes -static u32 getCurrentFieldEvenOdd(void); -VITiming* __VISetExtraTiming(VITiming* t); -void __VIEnableRawPositionInterrupt(s16 x, s16 y, void (*callback)(s16, s16)); -void (*__VIDisableRawPositionInterrupt())(s16, s16); -void __VIDisplayPositionToXY(u32 hct, u32 vct, s16* x, s16* y); -void __VISetLatchMode(u32 mode); -int __VIGetLatch0Position(s16* px, s16* py); -int __VIGetLatch1Position(s16* px, s16* py); -int __VIGetLatchPosition(u32 port, s16* px, s16* py); - - -static u32 getEncoderType(void) { - return 1; -} - -static s32 cntlzd(u64 bit) { - u32 hi; - u32 lo; - s32 value; - - hi = bit >> 32; - lo = bit & 0xFFFFFFFF; - value = __cntlzw(hi); - if (value < 32) { - return value; - } - return __cntlzw(lo) + 32; -} - -static int VISetRegs(void) { - s32 regIndex; - - if (shdwChangeMode != 1 || getCurrentFieldEvenOdd() != 0) { - while (shdwChanged != 0) { - regIndex = cntlzd(shdwChanged); - __VIRegs[regIndex] = shdwRegs[regIndex]; - shdwChanged &= ~((u64)1 << (63 - regIndex)); - } - - shdwChangeMode = 0; - CurrTiming = HorVer.timing; - CurrTvMode = HorVer.tv; - CurrBufAddr = NextBufAddr; - return 1; - } - - return 0; -} - -static void __VIRetraceHandler(__OSInterrupt unused, OSContext* context) { - OSContext exceptionContext; - u16 reg; - u32 inter; -#if DEBUG - static u32 dbgCount; -#endif - - inter = 0; - reg = __VIRegs[0x18]; - if (reg & 0x8000) { - __VIRegs[0x18] = reg & ~0x8000; - inter |= 1; - } - reg = __VIRegs[0x1A]; - if (reg & 0x8000) { - __VIRegs[0x1A] = reg & ~0x8000; - inter |= 2; - } - reg = __VIRegs[0x1C]; - if (reg & 0x8000) { - __VIRegs[0x1C] = reg & ~0x8000; - inter |= 4; - } - reg = __VIRegs[0x1E]; - if (reg & 0x8000) { - __VIRegs[0x1E] = reg & ~0x8000; - inter |= 8; - } - reg = __VIRegs[0x1E]; - - if ((inter & 4) || (inter & 8)) { - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - - if (PositionCallback != 0) { - s16 x, y; - __VIGetCurrentPosition(&x, &y); - (*PositionCallback)(x, y); - } - - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); - return; - } - - if (inter == 0) { - ASSERTLINE(955, FALSE); - } - - retraceCount += 1; - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - - if (PreCB) { - PreCB(retraceCount); - } - - if (flushFlag != 0) { -#if DEBUG - dbgCount = 0; -#endif - if (VISetRegs() != 0) { - flushFlag = 0; - SIRefreshSamplingRate(); - } - } -#if DEBUG - else if (changed != 0) { - dbgCount++; - if (dbgCount > 60) { - OSReport("Warning: VIFlush() was not called for 60 frames although VI settings were changed\n"); - dbgCount = 0; - } - } -#endif - - if (PostCB) { - OSClearContext(&exceptionContext); - PostCB(retraceCount); - } - - OSWakeupThread(&retraceQueue); - OSClearContext(&exceptionContext); - OSSetCurrentContext(context); -} - -VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback cb) { - BOOL enabled; - VIRetraceCallback oldcb; - - oldcb = PreCB; - enabled = OSDisableInterrupts(); - PreCB = cb; - OSRestoreInterrupts(enabled); - return oldcb; -} - -VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback cb) { - BOOL enabled; - VIRetraceCallback oldcb; - - oldcb = PostCB; - enabled = OSDisableInterrupts(); - PostCB = cb; - OSRestoreInterrupts(enabled); - return oldcb; -} - -VITiming* __VISetExtraTiming(VITiming* t) { - VITiming* old = timingExtra; - - timingExtra = t; - return old; -} - -#pragma dont_inline on -static VITiming* getTiming(VITVMode mode) { - switch (mode) { - case VI_TVMODE_NTSC_INT: return &timing[0]; - case VI_TVMODE_NTSC_DS: return &timing[1]; - case VI_TVMODE_PAL_INT: return &timing[2]; - case VI_TVMODE_PAL_DS: return &timing[3]; - case VI_TVMODE_EURGB60_INT: return &timing[0]; - case VI_TVMODE_EURGB60_DS: return &timing[1]; - case VI_TVMODE_MPAL_INT: return &timing[4]; - case VI_TVMODE_MPAL_DS: return &timing[5]; - case VI_TVMODE_NTSC_PROG: return &timing[6]; - case 3: return &timing[7]; - case VI_TVMODE_DEBUG_PAL_INT: return &timing[2]; - case VI_TVMODE_DEBUG_PAL_DS: return &timing[3]; - case 24: return &timing[8]; - case 26: return &timing[9]; - case 29: - case 30: - case 28: - return timingExtra; - default: - return NULL; - } -} -#pragma dont_inline reset - -void __VIInit(VITVMode mode) { - VITiming* tm; - u32 nonInter; - u32 tv; - u32 tvForReg; - volatile u32 a; - u16 hct; - u16 vct; - u32 encoderType; - - encoderType = getEncoderType(); - if (encoderType == 0) { - __VIInitPhilips(); - } - - nonInter = mode & 3; - tv = (u32)mode >> 2; - *(u32*)OSPhysicalToCached(0xCC) = tv; - if (encoderType == 0) { - tv = 3; - } - tm = getTiming(mode); - __VIRegs[1] = 2; - - // why? - for (a = 0; a < 1000; a++) {} - - __VIRegs[1] = 0; - __VIRegs[3] = (u32)tm->hlw; - __VIRegs[2] = tm->hce | (tm->hcs << 8); - __VIRegs[5] = tm->hsy | ((tm->hbe640 & 0x1FF) << 7); - __VIRegs[4] = (tm->hbe640 >> 9) | ((tm->hbs640 & 0xFFFF) << 1); - if (encoderType == 0) { - __VIRegs[0x39] = tm->hbeCCIR656 | 0x8000; - __VIRegs[0x3A] = (u32)tm->hbsCCIR656; - } - __VIRegs[0] = (u32)tm->equ; - __VIRegs[7] = (u32)(tm->prbOdd + (tm->acv * 2) - 2); - __VIRegs[6] = (u32)(tm->psbOdd + 2); - __VIRegs[9] = (u32)(tm->prbEven + (tm->acv * 2) - 2); - __VIRegs[8] = (u32)(tm->psbEven + 2); - __VIRegs[11] = tm->bs1 | (tm->be1 << 5); - __VIRegs[10] = tm->bs3 | (tm->be3 << 5); - __VIRegs[13] = tm->bs2 | (tm->be2 << 5); - __VIRegs[12] = tm->bs4 | (tm->be4 << 5); - __VIRegs[36] = 0x2828; - __VIRegs[27] = 1; - __VIRegs[26] = 0x1001; - hct = tm->hlw + 1; - vct = (tm->nhlines / 2) + 1; - __VIRegs[25] = (u16)(u32)hct; - __VIRegs[24] = vct | 0x1000; - - switch (tv) { - case 1: - case 2: - case 3: - tvForReg = tv; - break; - default: - tvForReg = 0; - } - - if (nonInter == 0 || nonInter == 1) { - __VIRegs[1] = ((nonInter << 2) & 4) | 1 | (tvForReg << 8); - __VIRegs[54] = 0; - return; - } - - __VIRegs[1] = (tvForReg << 8) | 5; - __VIRegs[54] = 1; -} - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define CLAMP(val, min, max) ((val) > (max) ? (max) : (val) < (min) ? (min) : (val)) - -static void AdjustPosition(u16 acv) { - s32 coeff; - s32 frac; - - HorVer.AdjustedDispPosX = CLAMP((s16)HorVer.DispPosX + displayOffsetH, 0, 0x2D0 - HorVer.DispSizeX); - coeff = (HorVer.FBMode == VI_XFBMODE_SF) ? 2 : 1; - frac = HorVer.DispPosY & 1; - HorVer.AdjustedDispPosY = MAX((s16)HorVer.DispPosY + displayOffsetV, frac); - HorVer.AdjustedDispSizeY = HorVer.DispSizeY - + MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) - - MAX((s16)HorVer.DispPosY + (s16)HorVer.DispSizeY + displayOffsetV - (((s16)acv * 2) - frac), 0); - HorVer.AdjustedPanPosY = HorVer.PanPosY - - (MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) / coeff); - HorVer.AdjustedPanSizeY = HorVer.PanSizeY - + (MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) / coeff) - - (MAX((s16)HorVer.DispPosY + (s16)HorVer.DispSizeY + displayOffsetV - (((s16)acv * 2) - frac), 0) / coeff); -} - -static void ImportAdjustingValues(void) { - OSSram* sram = __OSLockSram(); - - ASSERTLINE(1322, sram); - displayOffsetH = sram->displayOffsetH; - displayOffsetV = 0; - __OSUnlockSram(0); -} - -void VIInit(void) { - u16 dspCfg; - u32 value; - u32 tv; - u32 tvInBootrom; - - if (IsInitialized) { - return; - } - - OSRegisterVersion(__VIVersion); - IsInitialized = TRUE; - - encoderType = getEncoderType(); - if (!(__VIRegs[1] & 1)) { - __VIInit(VI_TVMODE_NTSC_INT); - } - - retraceCount = 0; - changed = 0; - shdwChanged = 0; - changeMode = 0; - shdwChangeMode = 0; - flushFlag = 0; - - __VIRegs[39] = taps[0] | ((taps[1] & 0x3F) << 10); - __VIRegs[38] = (taps[1] >> 6) | (taps[2] << 4); - __VIRegs[41] = taps[3] | ((taps[4] & 0x3F) << 10); - __VIRegs[40] = (taps[4] >> 6) | (taps[5] << 4); - __VIRegs[43] = taps[6] | ((taps[7] & 0x3F) << 10); - __VIRegs[42] = (taps[7] >> 6) | (taps[8] << 4); - __VIRegs[45] = taps[9] | (taps[10] << 8); - __VIRegs[44] = taps[11] | (taps[12] << 8); - __VIRegs[47] = taps[13] | (taps[14] << 8); - __VIRegs[46] = taps[15] | (taps[16] << 8); - __VIRegs[49] = taps[17] | (taps[18] << 8); - __VIRegs[48] = taps[19] | (taps[20] << 8); - __VIRegs[51] = taps[21] | (taps[22] << 8); - __VIRegs[50] = taps[23] | (taps[24] << 8); - __VIRegs[56] = 0x280; - ImportAdjustingValues(); - - tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); - dspCfg = __VIRegs[1]; - HorVer.nonInter = (s32) ((dspCfg >> 2U) & 1); - HorVer.tv = ((u32)(dspCfg) & 0x300) >> 8; - - if (tvInBootrom == VI_PAL && HorVer.tv == VI_NTSC) { - HorVer.tv = VI_EURGB60; - } - - tv = (HorVer.tv == 3) ? 0 : HorVer.tv; - HorVer.timing = getTiming((tv << 2) + HorVer.nonInter); - regs[1] = dspCfg; - - CurrTiming = HorVer.timing; - CurrTvMode = HorVer.tv; - - HorVer.DispSizeX = 640; - HorVer.DispSizeY = CurrTiming->acv * 2; - HorVer.DispPosX = (720 - HorVer.DispSizeX) / 2; - HorVer.DispPosY = 0; - AdjustPosition(CurrTiming->acv); - HorVer.FBSizeX = 640; - HorVer.FBSizeY = CurrTiming->acv * 2; - HorVer.PanPosX = 0; - HorVer.PanPosY = 0; - HorVer.PanSizeX = 640; - HorVer.PanSizeY = CurrTiming->acv * 2; - HorVer.FBMode = 0; - - HorVer.wordPerLine = 40; - HorVer.std = 40; - HorVer.wpl = 40; - HorVer.xof = 0; - HorVer.black = 1; - HorVer.threeD = 0; - OSInitThreadQueue(&retraceQueue); - value = __VIRegs[24]; - value &= ~0x8000; -#if !DEBUG - value = (u16)value; -#endif - __VIRegs[24] = value; - value = __VIRegs[26]; - value = value & ~0x8000; -#if !DEBUG - value = (u16)value; -#endif - __VIRegs[26] = value; - PreCB = NULL; - PostCB = NULL; - __OSSetInterruptHandler(0x18, __VIRetraceHandler); - __OSUnmaskInterrupts(0x80); -} - -void VIWaitForRetrace(void) { - BOOL enabled; - u32 count; - - enabled = OSDisableInterrupts(); - count = retraceCount; - do { - OSSleepThread(&retraceQueue); - } while (count == retraceCount); - OSRestoreInterrupts(enabled); -} - -static void setInterruptRegs(VITiming* tm) { -#if DEBUG - u16 vct, hct; -#else - u16 hct, vct; -#endif - u16 borrow; - - vct = tm->nhlines / 2; - borrow = tm->nhlines % 2; - if (borrow != 0) { - hct = tm->hlw; - } else { - hct = 0; - } - vct++; - hct++; - regs[25] = (u16)(u32)hct; - MARK_CHANGED(25); - regs[24] = vct | 0x1000; - MARK_CHANGED(24); - - vct; // fixes regalloc -} - -static void setPicConfig(u16 fbSizeX, VIXFBMode xfbMode, u16 panPosX, u16 panSizeX, u8* wordPerLine, u8* std, u8* wpl, u8* xof) { - *wordPerLine = (fbSizeX + 15) / 16; - *std = (xfbMode == VI_XFBMODE_SF) ? *wordPerLine : (u8)(*wordPerLine * 2); - *xof = panPosX % 16; - *wpl = (*xof + panSizeX + 15) / 16; - regs[0x24] = *std | (*wpl << 8); - changed |= 0x8000000; -} - -static void setBBIntervalRegs(VITiming* tm) { - u16 val; - - val = tm->bs1 | (tm->be1 << 5); - regs[11] = val; - changed |= 0x10000000000000; - - val = tm->bs3 | (tm->be3 << 5); - regs[10] = val; - changed |= 0x20000000000000; - - val = tm->bs2 | (tm->be2 << 5); - regs[13] = val; - changed |= 0x4000000000000; - - val = tm->bs4 | (tm->be4 << 5); - regs[12] = val; - changed |= (1LL << (63-12)); -} - -static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL threeD) { - u32 scale; - - panSizeX = threeD ? (panSizeX << 1) : panSizeX; - if (panSizeX < dispSizeX) { - scale = (u32)(dispSizeX + (panSizeX << 8) - 1) / dispSizeX; - regs[37] = scale | 0x1000; - changed |= 0x04000000; - regs[56] = (u32)panSizeX; - changed |= 0x80; - } else { - regs[37] = 0x100; - changed |= 0x04000000; - } -} - -static void calcFbbs(u32 bufAddr, u16 panPosX, u16 panPosY, u8 wordPerLine, VIXFBMode xfbMode, u16 dispPosY, u32* tfbb, u32* bfbb) { - u32 bytesPerLine; - u32 xoffInWords; - u32 tmp; - - xoffInWords = (panPosX & ~0xF) >> 4; - bytesPerLine = (wordPerLine & 0xFF) << 5; - *tfbb = bufAddr + (xoffInWords << 5) + (bytesPerLine * panPosY); - *bfbb = (xfbMode == VI_XFBMODE_SF) ? *tfbb : *tfbb + bytesPerLine; - if (dispPosY % 2 == 1) { - tmp = *tfbb; - *tfbb = *bfbb; - *bfbb = tmp; - } - *tfbb &= 0x3FFFFFFF; - *bfbb &= 0x3FFFFFFF; -} - -static void setFbbRegs(SomeVIStruct* HorVer, u32* tfbb, u32* bfbb, u32* rtfbb, u32* rbfbb) { - u32 shifted; - - calcFbbs(HorVer->bufAddr, HorVer->PanPosX, HorVer->AdjustedPanPosY, HorVer->wordPerLine, HorVer->FBMode, HorVer->AdjustedDispPosY, tfbb, bfbb); - if (HorVer->threeD) { - calcFbbs(HorVer->rbufAddr, HorVer->PanPosX, HorVer->AdjustedPanPosY, HorVer->wordPerLine, HorVer->FBMode, HorVer->AdjustedDispPosY, rtfbb, rbfbb); - } - - if (*tfbb < 0x01000000U && *bfbb < 0x01000000U && *rtfbb < 0x01000000U && *rbfbb < 0x01000000U) { - shifted = 0; - } else { - shifted = 1; - } - - if (shifted) { - *tfbb >>= 5; - *bfbb >>= 5; - *rtfbb >>= 5; - *rbfbb >>= 5; - } - - regs[15] = (u16)*tfbb & 0xFFFF; - MARK_CHANGED(15); - regs[14] = (shifted << 12) | ((*tfbb >> 16) | (HorVer->xof << 8)); - MARK_CHANGED(14); - regs[19] = (u16)*bfbb & 0xFFFF; - MARK_CHANGED(19); - regs[18] = (*bfbb >> 16); - MARK_CHANGED(18); - - if (HorVer->threeD) { - regs[17] = (u16)*rtfbb & 0xFFFF; - MARK_CHANGED(17); - regs[16] = *rtfbb >> 16; - MARK_CHANGED(16); - regs[21] = (u16)*rbfbb & 0xFFFF; - MARK_CHANGED(21); - regs[20] = *rbfbb >> 16; - MARK_CHANGED(20); - } -} - -static void setHorizontalRegs(VITiming* tm, u16 dispPosX, u16 dispSizeX) { - u32 hbe; - u32 hbs; - u32 hbeLo; - u32 hbeHi; - - regs[3] = (u16)(u32)tm->hlw; - MARK_CHANGED(3); - regs[2] = tm->hce | (tm->hcs << 8); - MARK_CHANGED(2); - hbe = tm->hbe640 - 40 + dispPosX; - hbs = tm->hbs640 + 40 + dispPosX - (720 - dispSizeX); - hbeLo = hbe & 0x1FF; - hbeHi = hbe >> 9; - regs[5] = tm->hsy | (hbeLo << 7); - MARK_CHANGED(5); - regs[4] = hbeHi | (hbs * 2); - MARK_CHANGED(4); -} - -static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 prbOdd, u16 prbEven, u16 psbOdd, u16 psbEven, BOOL black) { - u16 actualPrbOdd; - u16 actualPrbEven; - u16 actualPsbOdd; - u16 actualPsbEven; - u16 actualAcv; - u16 c; - u16 d; - - if (regs[54] & 1) { - c = 1; - d = 2; - } else { - c = 2; - d = 1; - } - - if ((dispPosY % 2) == 0) { - actualPrbOdd = prbOdd + (d * dispPosY); - actualPsbOdd = psbOdd + (d * (((c * acv) - dispSizeY) - dispPosY)); - actualPrbEven = prbEven + (d * dispPosY); - actualPsbEven = psbEven + (d * (((c * acv) - dispSizeY) - dispPosY)); - } else { - actualPrbOdd = prbEven + (d * dispPosY); - actualPsbOdd = psbEven + (d * (((c * acv) - dispSizeY) - dispPosY)); - actualPrbEven = prbOdd + (d * dispPosY); - actualPsbEven = psbOdd + (d * (((c * acv) - dispSizeY) - dispPosY)); - } - - actualAcv = dispSizeY / c; - - if (black) { - actualPrbOdd += 2 * actualAcv - 2; - actualPsbOdd += 2; - actualPrbEven += 2 * actualAcv - 2; - actualPsbEven += 2; - actualAcv = 0; - } - - regs[0] = equ | (actualAcv << 4); - MARK_CHANGED(0); - regs[7] = (u16)(u32)actualPrbOdd; - MARK_CHANGED(7); - regs[6] = (u16)(u32)actualPsbOdd; - MARK_CHANGED(6); - regs[9] = (u16)(u32)actualPrbEven; - MARK_CHANGED(9); - regs[8] = (u16)(u32)actualPsbEven; - MARK_CHANGED(8); -} - -static void PrintDebugPalCaution(void) { - static u32 message; - - 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* rm) { - VITiming* tm; - u32 regDspCfg; - u32 regClksel; - BOOL enabled; - u32 newNonInter; - u32 tvInBootrom; - u32 tvInGame; - - enabled = OSDisableInterrupts(); - newNonInter = rm->viTVmode & 3; - - if (HorVer.nonInter != newNonInter) { - changeMode = 1; - HorVer.nonInter = newNonInter; - } - - ASSERTMSGLINEV(1926, (rm->viHeight & 1) == 0, - "VIConfigure(): Odd number(%d) is specified to viHeight\n", - rm->viHeight); - -#ifdef DEBUG - if (rm->xFBmode == VI_XFBMODE_DF || newNonInter == VI_TVMODE_NTSC_PROG || newNonInter == 3) { - ASSERTMSGLINEV(1933, rm->xfbHeight == rm->viHeight, - "VIConfigure(): xfbHeight(%d) is not equal to viHeight(%d) when DF XFB mode or progressive mode is specified\n", - rm->xfbHeight, rm->viHeight); - } - - if (rm->xFBmode == VI_XFBMODE_SF && newNonInter != VI_TVMODE_NTSC_PROG && newNonInter != 3) { - ASSERTMSGLINEV(1941, rm->viHeight == rm->xfbHeight * 2, - "VIConfigure(): xfbHeight(%d) is not as twice as viHeight(%d) when SF XFB mode is specified\n", - rm->xfbHeight, rm->viHeight); - } -#endif - - tvInGame = (u32)rm->viTVmode >> 2; - tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); - - if (tvInGame == VI_DEBUG_PAL) { - PrintDebugPalCaution(); - } - - switch (tvInBootrom) { - case VI_MPAL: - case VI_NTSC: - case 6: - case 7: - if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == 6 || tvInGame == 7) { - break; - } - goto panic; - case VI_PAL: - case VI_EURGB60: - if (tvInGame == VI_PAL || tvInGame == VI_EURGB60) { - break; - } - default: - panic: - OSPanic(__FILE__, 1979, - "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 = rm->viXOrigin; - HorVer.DispPosY = (HorVer.nonInter == 1) ? (u16)(rm->viYOrigin * 2) : rm->viYOrigin; - HorVer.DispSizeX = rm->viWidth; - HorVer.FBSizeX = rm->fbWidth; - HorVer.FBSizeY = rm->xfbHeight; - HorVer.FBMode = rm->xFBmode; - HorVer.PanSizeX = HorVer.FBSizeX; - HorVer.PanSizeY = HorVer.FBSizeY; - HorVer.PanPosX = 0; - HorVer.PanPosY = 0; - HorVer.DispSizeY = (HorVer.nonInter == 2) ? HorVer.PanSizeY : - (HorVer.nonInter == 3) ? HorVer.PanSizeY : - (HorVer.FBMode == VI_XFBMODE_SF) ? (u16)(HorVer.PanSizeY * 2) : - HorVer.PanSizeY; - HorVer.threeD = (HorVer.nonInter == 3) ? TRUE : FALSE; - - tm = getTiming((HorVer.tv << 2) + HorVer.nonInter); - HorVer.timing = tm; - - AdjustPosition(tm->acv); - ASSERTMSGLINEV(2022, rm->viXOrigin <= tm->hlw + 40 - tm->hbe640, - "VIConfigure(): viXOrigin(%d) cannot be greater than %d in this TV mode\n", - rm->viXOrigin, tm->hlw + 40 - tm->hbe640); - ASSERTMSGLINEV(2027, rm->viXOrigin + rm->viWidth >= 680 - tm->hbs640, - "VIConfigure(): viXOrigin + viWidth (%d) cannot be less than %d in this TV mode\n", - rm->viXOrigin + rm->viWidth, 680 - tm->hbs640); - - if (encoderType == 0) { - HorVer.tv = 3; - } - setInterruptRegs(tm); - - regDspCfg = regs[1]; - regClksel = regs[54]; - if (HorVer.nonInter == VI_PROGRESSIVE || HorVer.nonInter == 3) { - regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(1)) << 2); - regClksel = (((u32)(regClksel)) & ~0x00000001) | (((u32)(1)) << 0); - } else { - OLD_SET_REG_FIELD(2052, regDspCfg, 1, 2, HorVer.nonInter & 1); - regClksel = (((u32)(regClksel)) & ~0x00000001); - } - - OLD_SET_REG_FIELD(2056, regDspCfg, 1, 3, HorVer.threeD); - - if ((HorVer.tv == VI_PAL) || (HorVer.tv == VI_MPAL) || (HorVer.tv == 3)) { - OLD_SET_REG_FIELD(2060, regDspCfg, 2, 8, HorVer.tv); - } else { - regDspCfg = (((u32)(regDspCfg)) & ~0x00000300); - } - - regs[1] = regDspCfg; - regs[54] = (u16)regClksel; - - MARK_CHANGED(1); - MARK_CHANGED(54); - - setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); - setHorizontalRegs(tm, HorVer.AdjustedDispPosX, HorVer.DispSizeX); - setBBIntervalRegs(tm); - setPicConfig(HorVer.FBSizeX, HorVer.FBMode, HorVer.PanPosX, HorVer.PanSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); - if (FBSet != 0) { - setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); - } - setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.AdjustedDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); - OSRestoreInterrupts(enabled); -} - -void VIConfigurePan(u16 xOrg, u16 yOrg, u16 width, u16 height) { - BOOL enabled; - VITiming* tm; - -#if DEBUG - ASSERTMSGLINEV(2118, (xOrg & 1) == 0, - "VIConfigurePan(): Odd number(%d) is specified to xOrg\n", - xOrg); - if (HorVer.FBMode == VI_XFBMODE_DF) { - ASSERTMSGLINEV(2123, (height & 1) == 0, - "VIConfigurePan(): Odd number(%d) is specified to height when DF XFB mode\n", - height); - } -#endif - enabled = OSDisableInterrupts(); - HorVer.PanPosX = xOrg; - HorVer.PanPosY = yOrg; - HorVer.PanSizeX = width; - HorVer.PanSizeY = height; - HorVer.DispSizeY = (HorVer.nonInter == 2) ? HorVer.PanSizeY : - (HorVer.nonInter == 3) ? HorVer.PanSizeY : - (HorVer.FBMode == VI_XFBMODE_SF) ? (u16)(HorVer.PanSizeY * 2) : - HorVer.PanSizeY; - tm = HorVer.timing; - AdjustPosition(tm->acv); - setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); - setPicConfig(HorVer.FBSizeX, HorVer.FBMode, HorVer.PanPosX, HorVer.PanSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); - if (FBSet != 0) { - setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); - } - setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.DispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); - OSRestoreInterrupts(enabled); -} - -void VIFlush(void) { - BOOL enabled; - s32 regIndex; - - enabled = OSDisableInterrupts(); - shdwChangeMode |= changeMode; - changeMode = 0; - shdwChanged |= changed; - - while (changed != 0) { - regIndex = cntlzd(changed); - shdwRegs[regIndex] = regs[regIndex]; - changed &= ~((u64)1 << (63 - regIndex)); - } - - flushFlag = 1; - NextBufAddr = HorVer.bufAddr; - OSRestoreInterrupts(enabled); -} - -void VISetNextFrameBuffer(void* fb) { - BOOL enabled; - - ASSERTMSGLINEV(2216, ((u32)fb & 0x1F) == 0, - "VISetNextFrameBuffer(): Frame buffer address(0x%08x) is not 32byte aligned\n", - fb); - enabled = OSDisableInterrupts(); - HorVer.bufAddr = (u32)fb; - FBSet = 1; - setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); - OSRestoreInterrupts(enabled); -} - -void* VIGetNextFrameBuffer(void) { - return *(void**)(&NextBufAddr); -} - -void* VIGetCurrentFrameBuffer(void) { - return *(void**)(&CurrBufAddr); -} - -void VISetNextRightFrameBuffer(void* fb) { - BOOL enabled; - - ASSERTMSGLINEV(2284, ((u32)fb & 0x1F) == 0, - "VISetNextFrameBuffer(): Frame buffer address(0x%08x) is not 32byte aligned\n", - fb); - enabled = OSDisableInterrupts(); - HorVer.rbufAddr = (u32)fb; - FBSet = 1; - setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); - OSRestoreInterrupts(enabled); -} - -void VISetBlack(BOOL black) { - BOOL enabled; - VITiming* tm; - - enabled = OSDisableInterrupts(); - HorVer.black = black; - tm = HorVer.timing; - setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.DispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); - OSRestoreInterrupts(enabled); -} - -void VISet3D(BOOL threeD) { - BOOL enabled; - u32 reg; - - enabled = OSDisableInterrupts(); - HorVer.threeD = threeD; - reg = regs[1]; - OLD_SET_REG_FIELD(2355, reg, 1, 3, HorVer.threeD); - regs[1] = reg; - MARK_CHANGED(1); - setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); - OSRestoreInterrupts(enabled); -} - -u32 VIGetRetraceCount(void) { - return retraceCount; -} - -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(void) { - return (getCurrentHalfLine() < CurrTiming->nhlines) ? 1 : 0; -} - -u32 VIGetNextField(void) { - s32 nextField; - BOOL enabled; -#if !DEBUG - u8 unused[4]; -#endif - - enabled = OSDisableInterrupts(); - nextField = getCurrentFieldEvenOdd() ^ 1; - OSRestoreInterrupts(enabled); - return nextField ^ (HorVer.AdjustedDispPosY & 1); -} - -u32 VIGetCurrentLine(void) { - u32 halfLine; - VITiming* tm; - BOOL enabled; - - tm = CurrTiming; - enabled = OSDisableInterrupts(); - halfLine = getCurrentHalfLine(); - OSRestoreInterrupts(enabled); - if (halfLine >= tm->nhlines) { - halfLine -= tm->nhlines; - } - return halfLine >> 1U; -} - -u32 VIGetTvFormat(void) { - u32 format; - BOOL enabled; - - enabled = OSDisableInterrupts(); - - switch (CurrTvMode) { - case VI_NTSC: - case VI_DEBUG: - case 6: - case 7: - format = VI_NTSC; - break; - case VI_PAL: - case VI_DEBUG_PAL: - format = VI_PAL; - break; - case VI_EURGB60: - case VI_MPAL: - format = CurrTvMode; - break; - default: - ASSERTLINE(2527, FALSE); - } - - OSRestoreInterrupts(enabled); - return format; -} - -u32 VIGetScanMode(void) { - u32 scanMode; - BOOL enabled = OSDisableInterrupts(); - - if ((u32)(__VIRegs[54] & 1) == 1) { - scanMode = 2; - } else if (!((__VIRegs[1] & (1 << 2)) >> 2)) { - scanMode = 0; - } else { - scanMode = 1; - } - - OSRestoreInterrupts(enabled); - return scanMode; -} - -u32 VIGetDTVStatus(void) { - u32 dtvStatus; - BOOL enabled = OSDisableInterrupts(); - - dtvStatus = __VIRegs[55] & 3; - OSRestoreInterrupts(enabled); - return dtvStatus & 1; -} - -void __VISetAdjustingValues(s16 x, s16 y) { - BOOL enabled; - VITiming* tm; - - ASSERTMSGLINE(2611, (y & 1) == 0, "__VISetAdjustValues(): y offset should be an even number"); - enabled = OSDisableInterrupts(); - displayOffsetH = x; - displayOffsetV = y; - tm = HorVer.timing; - AdjustPosition(tm->acv); - setHorizontalRegs(tm, HorVer.AdjustedDispPosX, HorVer.DispSizeX); - if (FBSet != 0) { - setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); - } - setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.AdjustedDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); - OSRestoreInterrupts(enabled); -} - -void __VIGetAdjustingValues(s16* x, s16* y) { - BOOL enabled; - - enabled = OSDisableInterrupts(); - *x = displayOffsetH; - *y = displayOffsetV; - OSRestoreInterrupts(enabled); -} - -// DEBUG NONMATCHING - wrong reg use, equivalent -void __VIEnableRawPositionInterrupt(s16 x, s16 y, void (*callback)(s16, s16)) { - BOOL enabled; - u32 halfLine; - u32 halfLineOff; - - enabled = OSDisableInterrupts(); - __VIRegs[29] = x + 1U; - __VIRegs[31] = x + 1U; - - if (HorVer.nonInter == 0) { - if (y & 1) { - halfLineOff = CurrTiming->prbEven + ((CurrTiming->equ * 3) + CurrTiming->nhlines); - __VIRegs[30] = (((halfLineOff / 2) + (y / 2)) + 1) | 0x1000; - } else { - halfLineOff = CurrTiming->prbOdd + (CurrTiming->equ * 3); - __VIRegs[28] = (((halfLineOff / 2) + (y / 2)) + 1) | 0x1000; - } - } else if (HorVer.nonInter == 1) { - ASSERTLINE(2702, (y & 1) == 0); - halfLine = CurrTiming->prbOdd + ((CurrTiming->equ * 3)) + y; - __VIRegs[28] = ((halfLine / 2) + 1) | 0x1000; - __VIRegs[30] = (((halfLine + CurrTiming->nhlines) / 2) + 1) | 0x1000; - } else if (HorVer.nonInter == 2) { - halfLine = CurrTiming->prbOdd + ((CurrTiming->equ * 3)) + y; - __VIRegs[28] = (halfLine + 1) | 0x1000; - __VIRegs[30] = 0; - } - - PositionCallback = callback; - OSRestoreInterrupts(enabled); -} - -void (*__VIDisableRawPositionInterrupt())(s16, s16) { - BOOL enabled; - void (*old)(s16, s16); - - enabled = OSDisableInterrupts(); - __VIRegs[28] = 0; - __VIRegs[30] = 0; - - old = PositionCallback; - PositionCallback = 0; - OSRestoreInterrupts(enabled); - return old; -} - -void __VIDisplayPositionToXY(u32 hct, u32 vct, s16* x, s16* y) { - u32 halfLine = ((vct - 1) << 1) + ((hct - 1) / CurrTiming->hlw); - - if (HorVer.nonInter == VI_INTERLACE) { - if (halfLine < CurrTiming->nhlines) { - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { - *y = -1; - } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { - *y = -1; - } else { - *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); - } - } else { - halfLine -= CurrTiming->nhlines; - - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { - *y = -1; - } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbEven) { - *y = -1; - } else { - *y = (s16)(((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1) + 1); - } - } - } else if (HorVer.nonInter == VI_NON_INTERLACE) { - if (halfLine >= CurrTiming->nhlines) { - halfLine -= CurrTiming->nhlines; - } - - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { - *y = -1; - } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { - *y = -1; - } else { - *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); - } - } else if (HorVer.nonInter == VI_PROGRESSIVE) { - if (halfLine < CurrTiming->nhlines) { - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { - *y = -1; - } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { - *y = -1; - } else { - *y = (s16)(halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd); - } - } else { - halfLine -= CurrTiming->nhlines; - - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { - *y = -1; - } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbEven) { - *y = -1; - } else - *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1); - } - } - - *x = (s16)(hct - 1); -} - -void __VIGetCurrentPosition(s16* x, s16* y) { - u32 hcount, vcount; - GetCurrentDisplayPosition(&hcount, &vcount); - __VIDisplayPositionToXY(hcount, vcount, x, y); -} - -void __VISetLatchMode(u32 mode) { - u32 reg; - - reg = __VIRegs[1]; - OLD_SET_REG_FIELD(2834, reg, 2, 4, mode); - OLD_SET_REG_FIELD(2835, reg, 2, 6, mode); - __VIRegs[1] = reg; -} - -#pragma dont_inline on -int __VIGetLatch0Position(s16* px, s16* py) { - u32 hcount; - u32 vcount; - - if (((__VIRegs[32] & 0x8000) >> 15) != 0) { - vcount = __VIRegs[32] & 0x7FF; - hcount = __VIRegs[33] & 0x7FF; - __VIRegs[32] = 0; - __VIRegs[33] = 0; - __VIDisplayPositionToXY(hcount, vcount, px, py); - return 1; - } - - *px = *py = -1; - return 0; -} -#pragma dont_inline reset - -#pragma dont_inline on -int __VIGetLatch1Position(s16* px, s16* py) { - u32 hcount; - u32 vcount; - - if (((__VIRegs[34] & 0x8000) >> 15) != 0) { - vcount = __VIRegs[34] & 0x7FF; - hcount = __VIRegs[35] & 0x7FF; - __VIRegs[34] = 0; - __VIRegs[35] = 0; - __VIDisplayPositionToXY(hcount, vcount, px, py); - return 1; - } - - *px = *py = -1; - return 0; -} -#pragma dont_inline reset - -int __VIGetLatchPosition(u32 port, s16* px, s16* py) { - if (port == 0) { - return __VIGetLatch0Position(px, py); - } else { - return __VIGetLatch1Position(px, py); - } -}