diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a550ce..4743809 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,7 +18,37 @@ "*.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", + "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 672da6d..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 -reverb_hi.c: +Dolphin/axfx/reverb_hi.c: .text start:0x802D8ECC end:0x802D9D10 .data start:0x803BF6C0 end:0x803BF6E0 .sdata2 start:0x804B4990 end:0x804B49D0 -reverb_std.c: +Dolphin/axfx/reverb_std.c: .text start:0x802D9D10 end:0x802D9E58 -chorus.c: +Dolphin/axfx/chorus.c: .text start:0x802D9E58 end:0x802D9EA8 -delay.c: +Dolphin/axfx/delay.c: .text start:0x802D9EA8 end:0x802D9F38 -axfx.c: +Dolphin/axfx/axfx.c: .text start:0x802D9F38 end:0x802D9F88 .sdata start:0x804B0610 end:0x804B0618 -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 -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 -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 -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/init/__start.c: +Dolphin/os/__start.c: .init start:0x800051EC end:0x800054EC .sbss start:0x804B20D8 end:0x804B20E0 -dolphin/os/src/init/__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 1575602..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,19 +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", - "-i include/bink", - "-i include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include", - "-i include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include", + "-i include/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", ] @@ -379,299 +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( - "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"), + { + "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( - "db", - [ - Object(NonMatching, "dolphin/db/src/db.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( - "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": "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( - "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": "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( - "exi", - [ - Object(NonMatching, "dolphin/exi/src/EXIBios.c"), - Object(NonMatching, "dolphin/exi/src/EXIUart.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( - "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": "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/OSFont.c"), - Object(NonMatching, "dolphin/os/src/OSInterrupt.c"), - Object(NonMatching, "dolphin/os/src/OSLink.c"), - Object(NonMatching, "dolphin/os/src/OSMemory.c"), - Object(NonMatching, "dolphin/os/src/OSMutex.c"), - Object(NonMatching, "dolphin/os/src/OSReboot.c"), - Object(NonMatching, "dolphin/os/src/OSReset.c"), - Object(NonMatching, "dolphin/os/src/OSResetSW.c"), - Object(NonMatching, "dolphin/os/src/OSRtc.c"), - Object(NonMatching, "dolphin/os/src/OSSync.c"), - Object(NonMatching, "dolphin/os/src/OSThread.c"), - Object(NonMatching, "dolphin/os/src/OSTime.c"), - Object(NonMatching, "dolphin/os/src/init/__start.c"), - Object(NonMatching, "dolphin/os/src/init/__ppc_eabi_init.cpp"), + }, + { + "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/dolphin sdk not yet linked/src/ax/AX.c b/dolphin sdk not yet linked/src/ax/AX.c new file mode 100644 index 0000000..bc57946 --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AX.c @@ -0,0 +1,40 @@ +#include +#include + +#include "__ax.h" + +#ifdef DEBUG +const char* __AXVersion = "<< Dolphin SDK - AX\tdebug build: Apr 5 2004 03:56:21 (0x2301) >>"; +#else +const char* __AXVersion = "<< Dolphin SDK - AX\trelease build: Apr 5 2004 04:15:05 (0x2301) >>"; +#endif + +void AXInit(void) { + AXInitEx(0); +} + +void AXInitEx(u32 outputBufferMode) { +#ifdef DEBUG + OSReport("Initializing AX\n"); +#endif + OSRegisterVersion(__AXVersion); + + __AXAllocInit(); + __AXVPBInit(); + __AXSPBInit(); + __AXAuxInit(); + __AXClInit(); + __AXOutInit(outputBufferMode); +} + +void AXQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AX\n"); +#endif + __AXAllocQuit(); + __AXVPBQuit(); + __AXSPBQuit(); + __AXAuxQuit(); + __AXClQuit(); + __AXOutQuit(); +} diff --git a/dolphin sdk not yet linked/src/ax/AXAlloc.c b/dolphin sdk not yet linked/src/ax/AXAlloc.c new file mode 100644 index 0000000..66b3f03 --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AXAlloc.c @@ -0,0 +1,248 @@ +#include +#include + +#include "__ax.h" + +static AXVPB* __AXStackHead[AX_PRIORITY_STACKS]; +static AXVPB* __AXStackTail[AX_PRIORITY_STACKS]; + +static AXVPB* __AXCallbackStack; + +static u32 __AXCheckStacks(void) { + u32 i; + u32 voices; + AXVPB* voice; + + voices = 0; + for (i = 0; i < 32; i++) { + voice = __AXStackHead[i]; + while (voice != 0) { + voices++; + if (voices > 64) { + return 0; + } + + voice = voice->next; + } + } + + return 1; +} + +AXVPB* __AXGetStackHead(u32 priority) { + ASSERTLINE(97, priority < AX_PRIORITY_STACKS); + return __AXStackHead[priority]; +} + +void __AXServiceCallbackStack(void) { + AXVPB* p; + + for (p = __AXPopCallbackStack(); p; p = __AXPopCallbackStack()) { + if (p->priority != 0) { + if (p->callback) { + p->callback(p); + } + + __AXRemoveFromStack(p); + __AXPushFreeStack(p); + } + } +} + +void __AXInitVoiceStacks(void) { + u32 i; + + __AXCallbackStack = NULL; + for (i = 0; i < AX_PRIORITY_STACKS; i++) { + __AXStackHead[i] = __AXStackTail[i] = 0; + } +} + +void __AXAllocInit(void) { +#ifdef DEBUG + OSReport("Initializing AXAlloc code module\n"); +#endif + __AXInitVoiceStacks(); +} + +void __AXAllocQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXAlloc code module\n"); +#endif + __AXInitVoiceStacks(); +} + +void __AXPushFreeStack(AXVPB* p) { + ASSERTLINE(168, p->priority); + p->next = __AXStackHead[0]; + __AXStackHead[0] = p; + p->priority = 0; +} + +AXVPB* __AXPopFreeStack(void) { + AXVPB* p; + + p = (void*)(u32)&__AXStackHead[0]->next; + if (p) { + __AXStackHead[0] = p->next; + } + return p; +} + +void __AXPushCallbackStack(AXVPB* p) { + p->next1 = __AXCallbackStack; + __AXCallbackStack = p; +} + +AXVPB* __AXPopCallbackStack(void) { + AXVPB* p; + + p = (void*)(u32)&__AXCallbackStack[0]; + if (p) { + __AXCallbackStack = p->next1; + } + return p; +} + +void __AXRemoveFromStack(AXVPB* p) { + u32 i; + AXVPB* head; + AXVPB* tail; + + ASSERTLINE(219, p->priority); + + i = p->priority; + head = __AXStackHead[i]; + tail = __AXStackTail[i]; + if (head == tail) { + __AXStackHead[i] = __AXStackTail[i] = 0; + return; + } + + if (p == head) { + __AXStackHead[i] = p->next; + __AXStackHead[i]->prev = 0; + return; + } + + if (p == tail) { + __AXStackTail[i] = p->prev; + __AXStackTail[i]->next = 0; + return; + } + + head = p->prev; + tail = p->next; + head->next = tail; + tail->prev = head; +} + +void __AXPushStackHead(AXVPB* p, u32 priority) { + ASSERTLINE(261, priority); + ASSERTLINE(262, priority < AX_PRIORITY_STACKS); + + p->next = __AXStackHead[priority]; + p->prev = 0; + + if (p->next) { + __AXStackHead[priority]->prev = p; + __AXStackHead[priority] = p; + } else { + __AXStackTail[priority] = p; + __AXStackHead[priority] = p; + } + + p->priority = priority; +} + +AXVPB* __AXPopStackFromBottom(u32 priority) { + AXVPB* p; + + ASSERTLINE(287, priority); + ASSERTLINE(288, priority < AX_PRIORITY_STACKS); + + p = NULL; + if (__AXStackHead[priority]) { + if (__AXStackHead[priority] == __AXStackTail[priority]) { + p = __AXStackHead[priority]; + __AXStackHead[priority] = __AXStackTail[priority] = 0; + } else if (__AXStackTail[priority]) { + p = __AXStackTail[priority]; + __AXStackTail[priority] = p->prev; + __AXStackTail[priority]->next = 0; + } + } + + return p; +} + +void AXFreeVoice(AXVPB* p) { + BOOL old; + + ASSERTLINE(322, p); + ASSERTMSGLINE(326, p->priority != 0, "Calling AXFreeVoice() for voice that is already free\n"); + + old = OSDisableInterrupts(); + __AXRemoveFromStack(p); + if (p->pb.state == 1) { + p->depop = 1; + } + __AXSetPBDefault(p); + __AXPushFreeStack(p); + + ASSERTMSGLINE(343, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); +} + +AXVPB* AXAcquireVoice(u32 priority, void (*callback)(void*), u32 userContext) { + BOOL old; + AXVPB* p; + u32 i; + + ASSERTLINE(361, priority); + ASSERTLINE(362, priority < AX_PRIORITY_STACKS); + + old = OSDisableInterrupts(); + p = __AXPopFreeStack(); + if (p == 0) { + for (i = 1; i < priority; i++) { + p = __AXPopStackFromBottom(i); + if (p) { + if (p->pb.state == 1) { + p->depop = 1; + } + if (p->callback != 0) { + p->callback(p); + } + break; + } + } + } + + if (p) { + __AXPushStackHead(p, priority); + p->callback = callback; + p->userContext = userContext; + __AXSetPBDefault(p); + } + + ASSERTMSGLINE(410, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); + return p; +} + +void AXSetVoicePriority(AXVPB* p, u32 priority) { + BOOL old; + + ASSERTLINE(424, p); + ASSERTMSGLINE(428, p->priority != 0, "Calling AXSetVoicePriority() for voice that is already free\n"); + ASSERTMSGLINE(433, priority, "Do not set voice priority to 0, use AXFreeVoice() to free voice\n"); + ASSERTLINE(435, priority < AX_PRIORITY_STACKS); + + old = OSDisableInterrupts(); + __AXRemoveFromStack(p); + __AXPushStackHead(p, priority); + + ASSERTMSGLINE(442, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); +} diff --git a/dolphin sdk not yet linked/src/ax/AXAux.c b/dolphin sdk not yet linked/src/ax/AXAux.c new file mode 100644 index 0000000..094dac4 --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AXAux.c @@ -0,0 +1,167 @@ +#include +#include + +#include "__ax.h" + +static s32 __AXBufferAuxA[3][480] ATTRIBUTE_ALIGN(32); +static s32 __AXBufferAuxB[3][480] ATTRIBUTE_ALIGN(32); + +static void (* __AXCallbackAuxA)(void*, void*); +static void (* __AXCallbackAuxB)(void*, void*); +static void* __AXContextAuxA; +static void* __AXContextAuxB; +static s32* __AXAuxADspWrite; +static s32* __AXAuxADspRead; +static s32* __AXAuxBDspWrite; +static s32* __AXAuxBDspRead; +static u32 __AXAuxDspWritePosition; +static u32 __AXAuxDspReadPosition; +static u32 __AXAuxDspWritePositionDpl2; +static u32 __AXAuxDspReadPositionDpl2; +static u32 __AXAuxCpuReadWritePosition; + +void __AXAuxInit(void) { + int i; + s32* pA; + s32* pB; + +#ifdef DEBUG + OSReport("Initializing AXAux code module\n"); +#endif + __AXCallbackAuxA = NULL; + __AXCallbackAuxB = NULL; + __AXContextAuxA = 0; + __AXContextAuxB = 0; + __AXAuxDspWritePosition = 0; + __AXAuxDspReadPosition = 1; + __AXAuxDspWritePositionDpl2 = 0; + __AXAuxDspReadPositionDpl2 = 1; + __AXAuxCpuReadWritePosition = 2; + + pA = (s32*)&__AXBufferAuxA; + pB = (s32*)&__AXBufferAuxB; + + for (i = 0; i < 480; i++) { + *(pA) = 0; pA++; + *(pB) = 0; pB++; + } +} + +void __AXAuxQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXAux code module\n"); +#endif + __AXCallbackAuxA = NULL; + __AXCallbackAuxB = NULL; +} + +void __AXGetAuxAInput(u32* p) { + if (__AXCallbackAuxA) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspWritePosition][0]; + } else { + *p = 0; + } +} + +void __AXGetAuxAInputDpl2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePosition][320]; +} + +void __AXGetAuxAOutput(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][0]; +} + +void __AXGetAuxAOutputDpl2R(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][160]; +} + +void __AXGetAuxAOutputDpl2Ls(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][320]; +} + +void __AXGetAuxAOutputDpl2Rs(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPosition][320]; +} + +void __AXGetAuxBInput(u32* p) { + if (__AXCallbackAuxB) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePosition][0]; + } else { + *p = 0; + } +} + +void __AXGetAuxBOutput(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPosition][0]; +} + +void __AXGetAuxBForDPL2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePositionDpl2][0]; +} + +void __AXGetAuxBOutputDPL2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPositionDpl2][0]; +} + +void __AXProcessAux(void) { + __AXAuxADspWrite = &__AXBufferAuxA[__AXAuxDspWritePosition][0]; + __AXAuxADspRead = &__AXBufferAuxA[__AXAuxDspReadPosition][0]; + __AXAuxBDspWrite = &__AXBufferAuxB[__AXAuxDspWritePosition][0]; + __AXAuxBDspRead = &__AXBufferAuxB[__AXAuxDspReadPosition][0]; + + if (__AXCallbackAuxA) { + if (__AXClMode == 2) { + AX_AUX_DATA_DPL2 auxData; + auxData.l = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][160]; + auxData.ls = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][320]; + auxData.rs = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + DCInvalidateRange(auxData.rs, 0x280); + __AXCallbackAuxA(&auxData.l, __AXContextAuxA); + DCFlushRangeNoSync(auxData.l, 0x780); + DCFlushRangeNoSync(auxData.rs, 0x280); + } else { + AX_AUX_DATA auxData; + auxData.l = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][160]; + auxData.s = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + __AXCallbackAuxA(&auxData.l, __AXContextAuxA); + DCFlushRangeNoSync(auxData.l, 0x780); + } + } + + if (__AXCallbackAuxB && __AXClMode != 2) { + AX_AUX_DATA auxData; + auxData.l = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][160]; + auxData.s = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + __AXCallbackAuxB(&auxData.l, __AXContextAuxB); + DCFlushRangeNoSync(auxData.l, 0x780); + } + + __AXAuxDspWritePosition += 1; + __AXAuxDspWritePosition %= 3; + __AXAuxDspReadPosition += 1; + __AXAuxDspReadPosition %= 3; + + __AXAuxDspWritePositionDpl2 += 1; + __AXAuxDspWritePositionDpl2 &= 1; + __AXAuxDspReadPositionDpl2 += 1; + __AXAuxDspReadPositionDpl2 &= 1; + + __AXAuxCpuReadWritePosition += 1; + __AXAuxCpuReadWritePosition %= 3; +} + +void AXRegisterAuxACallback(void (*callback)(void*, void*), void* context) { + __AXCallbackAuxA = callback; + __AXContextAuxA = context; +} + +void AXRegisterAuxBCallback(void (*callback)(void*, void*), void* context) { + __AXCallbackAuxB = callback; + __AXContextAuxB = context; +} diff --git a/dolphin sdk not yet linked/src/ax/AXCL.c b/dolphin sdk not yet linked/src/ax/AXCL.c new file mode 100644 index 0000000..05107a5 --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AXCL.c @@ -0,0 +1,176 @@ +#include +#include + +#include "__ax.h" + +static u16 __AXCommandList[2][384]; + +static u32 __AXCommandListPosition; +static u16* __AXClWrite; +static u32 __AXCommandListCycles; +static u32 __AXCompressor; +u32 __AXClMode; + +u32 __AXGetCommandListCycles(void) { + return __AXCommandListCycles; +} + +u32 __AXGetCommandListAddress(void) { + u32 address; + + address = (u32)&__AXCommandList[__AXCommandListPosition][0]; + __AXCommandListPosition += 1; + __AXCommandListPosition &= 1; + __AXClWrite = (void*)&__AXCommandList[__AXCommandListPosition][0]; + return address; +} + +void __AXWriteToCommandList(u16 data) { + *__AXClWrite = data; + __AXClWrite++; +} + +void __AXNextFrame(void* sbuffer, void* buffer) { + u32 data; + u16* pCommandList; + + __AXCommandListCycles = 0x1A9; + pCommandList = __AXClWrite; + data = __AXGetStudio(); + __AXWriteToCommandList(0); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)(data)); + __AXCommandListCycles += 0x2E44; + + switch (__AXClMode) { + case 0: + __AXWriteToCommandList(7); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXCommandListCycles += 0x546; + break; + case 1: + __AXWriteToCommandList(0x11); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXCommandListCycles += 0x5E6; + break; + case 2: + break; + default: + ASSERTMSGLINE(193, 0, "Unknown AX mode!"); + } + + data = (u32)__AXGetPBs(); + __AXWriteToCommandList(2); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXWriteToCommandList(3); + + if (__AXClMode == 2) { + __AXGetAuxAInput(&data); + if (data != 0) { + __AXWriteToCommandList(0x13); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAInputDpl2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutput(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2R(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2Ls(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2Rs(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } + __AXWriteToCommandList(0x10); + __AXGetAuxBForDPL2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxBOutputDPL2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } else { + __AXGetAuxAInput(&data); + + if (data != 0) { + __AXWriteToCommandList(4); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutput(&data); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } + + __AXGetAuxBInput(&data); + if (data != 0) { + __AXWriteToCommandList(5); + __AXCommandListCycles += 0xDED; + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXGetAuxBOutput(&data); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + } + } + + if (__AXCompressor) { + __AXWriteToCommandList(0x12); + __AXWriteToCommandList(0x8000); + __AXWriteToCommandList(0xA); + __AXWriteToCommandList((u32)__AXCompressorTable >> 0x10); + __AXWriteToCommandList((u32)__AXCompressorTable); + __AXCommandListCycles += 0xBB8; + } + + __AXWriteToCommandList(0xE); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXWriteToCommandList((u16)((u32)buffer >> 0x10)); + __AXWriteToCommandList((u32)buffer); + __AXCommandListCycles += 0x2710; + __AXWriteToCommandList(0xF); + __AXCommandListCycles += 2; + DCFlushRange(pCommandList, 0x300); +} + +void __AXClInit(void) { +#ifdef DEBUG + OSReport("Initializing AXCL code module\n"); +#endif + ASSERTLINE(338, ((u32)&__AXCommandList[0][0] & 0x1F) == 0); + ASSERTLINE(339, ((u32)&__AXCommandList[1][0] & 0x1F) == 0); + __AXClMode = 0; + __AXCommandListPosition = 0; + __AXClWrite = (void*)&__AXCommandList; + __AXCompressor = 1; +} + +void __AXClQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXCL code module\n"); +#endif +} + +void AXSetMode(u32 mode) { + if (__AXClMode != mode) { + __AXClMode = mode; + } +} + +u32 AXGetMode(void) { + return __AXClMode; +} + +void AXSetCompressor(u32 i) { + __AXCompressor = i; +} diff --git a/dolphin sdk not yet linked/src/ax/AXComp.c b/dolphin sdk not yet linked/src/ax/AXComp.c new file mode 100644 index 0000000..bc0eb97 --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AXComp.c @@ -0,0 +1,567 @@ +#include +#include + +#include "__ax.h" + +u16 __AXCompressorTable[3360] = { + 0x7FA1, 0x7F43, 0x7EE6, 0x7E88, 0x7E2B, 0x7DCE, + 0x7D72, 0x7D16, 0x7CBA, 0x7C5E, 0x7C02, 0x7BA7, + 0x7B4C, 0x7AF1, 0x7A97, 0x7A3D, 0x79E3, 0x7989, + 0x7930, 0x78D6, 0x787E, 0x7825, 0x77CD, 0x7774, + 0x771C, 0x76C5, 0x766D, 0x7616, 0x75BF, 0x7569, + 0x7512, 0x74BC, 0x7466, 0x7411, 0x73BB, 0x7366, + 0x7311, 0x72BD, 0x7268, 0x7214, 0x71C0, 0x716C, + 0x7119, 0x70C6, 0x7073, 0x7020, 0x6FCD, 0x6F7B, + 0x6F29, 0x6ED7, 0x6E86, 0x6E35, 0x6DE3, 0x6D93, + 0x6D42, 0x6CF2, 0x6CA1, 0x6C52, 0x6C02, 0x6BB2, + 0x6B63, 0x6B14, 0x6AC5, 0x6A77, 0x6A28, 0x69DA, + 0x698C, 0x693F, 0x68F1, 0x68A4, 0x6857, 0x680A, + 0x67BE, 0x6771, 0x6725, 0x66D9, 0x668E, 0x6642, + 0x65F7, 0x65AC, 0x6561, 0x6517, 0x64CC, 0x6482, + 0x6438, 0x63EE, 0x63A5, 0x635C, 0x6312, 0x62CA, + 0x6281, 0x6238, 0x61F0, 0x61A8, 0x6160, 0x6119, + 0x60D1, 0x608A, 0x6043, 0x5FFC, 0x5FB5, 0x5F6F, + 0x5F29, 0x5EE3, 0x5E9D, 0x5E57, 0x5E12, 0x5DCD, + 0x5D88, 0x5D43, 0x5CFE, 0x5CBA, 0x5C76, 0x5C32, + 0x5BEE, 0x5BAA, 0x5B67, 0x5B23, 0x5AE0, 0x5A9D, + 0x5A5B, 0x5A18, 0x59D6, 0x5994, 0x5952, 0x5910, + 0x58CF, 0x588D, 0x584C, 0x580B, 0x57CB, 0x578A, + 0x574A, 0x5709, 0x56C9, 0x5689, 0x564A, 0x560A, + 0x55CB, 0x558C, 0x554D, 0x550E, 0x54D0, 0x5491, + 0x5453, 0x5415, 0x53D7, 0x5399, 0x535C, 0x531E, + 0x52E1, 0x52A4, 0x5267, 0x522B, 0x51EE, 0x51B2, + 0x5176, 0x513A, 0x50FE, 0x50C3, 0x79EC, 0x799B, + 0x794A, 0x78FA, 0x78AA, 0x785A, 0x780A, 0x77BB, + 0x776C, 0x771C, 0x76CE, 0x767F, 0x7630, 0x75E2, + 0x7594, 0x7546, 0x74F9, 0x74AB, 0x745E, 0x7411, + 0x73C4, 0x7377, 0x732B, 0x72DE, 0x7292, 0x7246, + 0x71FB, 0x71AF, 0x7164, 0x7119, 0x70CE, 0x7083, + 0x7039, 0x6FEE, 0x6FA4, 0x6F5A, 0x6F11, 0x6EC7, + 0x6E7E, 0x6E35, 0x6DEC, 0x6DA3, 0x6D5A, 0x6D12, + 0x6CC9, 0x6C81, 0x6C3A, 0x6BF2, 0x6BAA, 0x6B63, + 0x6B1C, 0x6AD5, 0x6A8E, 0x6A48, 0x6A01, 0x69BB, + 0x6975, 0x692F, 0x68EA, 0x68A4, 0x685F, 0x681A, + 0x67D5, 0x6790, 0x674B, 0x6707, 0x66C3, 0x667F, + 0x663B, 0x65F7, 0x65B4, 0x6570, 0x652D, 0x64EA, + 0x64A7, 0x6464, 0x6422, 0x63E0, 0x639E, 0x635C, + 0x631A, 0x62D8, 0x6297, 0x6255, 0x6214, 0x61D3, + 0x6192, 0x6152, 0x6111, 0x60D1, 0x6091, 0x6051, + 0x6011, 0x5FD2, 0x5F92, 0x5F53, 0x5F14, 0x5ED5, + 0x5E96, 0x5E57, 0x5E19, 0x5DDB, 0x5D9C, 0x5D5E, + 0x5D21, 0x5CE3, 0x5CA5, 0x5C68, 0x5C2B, 0x5BEE, + 0x5BB1, 0x5B74, 0x5B38, 0x5AFB, 0x5ABF, 0x5A83, + 0x5A47, 0x5A0B, 0x59CF, 0x5994, 0x5959, 0x591D, + 0x58E2, 0x58A8, 0x586D, 0x5832, 0x57F8, 0x57BE, + 0x5783, 0x574A, 0x5710, 0x56D6, 0x569D, 0x5663, + 0x562A, 0x55F1, 0x55B8, 0x557F, 0x5547, 0x550E, + 0x54D6, 0x549E, 0x5466, 0x542E, 0x53F6, 0x53BE, + 0x5387, 0x534F, 0x5318, 0x52E1, 0x52AA, 0x5274, + 0x523D, 0x5207, 0x51D0, 0x519A, 0x5164, 0x512E, + 0x50F8, 0x50C3, 0x7478, 0x7433, 0x73EF, 0x73AA, + 0x7366, 0x7322, 0x72DE, 0x729B, 0x7257, 0x7214, + 0x71D1, 0x718E, 0x714B, 0x7108, 0x70C6, 0x7083, + 0x7041, 0x6FFF, 0x6FBD, 0x6F7B, 0x6F3A, 0x6EF8, + 0x6EB7, 0x6E76, 0x6E35, 0x6DF4, 0x6DB3, 0x6D72, + 0x6D32, 0x6CF2, 0x6CB1, 0x6C71, 0x6C32, 0x6BF2, + 0x6BB2, 0x6B73, 0x6B34, 0x6AF5, 0x6AB6, 0x6A77, + 0x6A38, 0x69FA, 0x69BB, 0x697D, 0x693F, 0x6901, + 0x68C3, 0x6885, 0x6848, 0x680A, 0x67CD, 0x6790, + 0x6753, 0x6716, 0x66D9, 0x669D, 0x6660, 0x6624, + 0x65E8, 0x65AC, 0x6570, 0x6534, 0x64F9, 0x64BD, + 0x6482, 0x6447, 0x640C, 0x63D1, 0x6396, 0x635C, + 0x6321, 0x62E7, 0x62AC, 0x6272, 0x6238, 0x61FF, + 0x61C5, 0x618B, 0x6152, 0x6119, 0x60DF, 0x60A6, + 0x606D, 0x6035, 0x5FFC, 0x5FC4, 0x5F8B, 0x5F53, + 0x5F1B, 0x5EE3, 0x5EAB, 0x5E73, 0x5E3C, 0x5E04, + 0x5DCD, 0x5D95, 0x5D5E, 0x5D27, 0x5CF1, 0x5CBA, + 0x5C83, 0x5C4D, 0x5C16, 0x5BE0, 0x5BAA, 0x5B74, + 0x5B3E, 0x5B09, 0x5AD3, 0x5A9D, 0x5A68, 0x5A33, + 0x59FE, 0x59C9, 0x5994, 0x595F, 0x592B, 0x58F6, + 0x58C2, 0x588D, 0x5859, 0x5825, 0x57F1, 0x57BE, + 0x578A, 0x5756, 0x5723, 0x56F0, 0x56BC, 0x5689, + 0x5656, 0x5624, 0x55F1, 0x55BE, 0x558C, 0x5559, + 0x5527, 0x54F5, 0x54C3, 0x5491, 0x545F, 0x542E, + 0x53FC, 0x53CB, 0x5399, 0x5368, 0x5337, 0x5306, + 0x52D5, 0x52A4, 0x5274, 0x5243, 0x5213, 0x51E2, + 0x51B2, 0x5182, 0x5152, 0x5122, 0x50F2, 0x50C3, + 0x6F42, 0x6F08, 0x6ECF, 0x6E96, 0x6E5D, 0x6E24, + 0x6DEC, 0x6DB3, 0x6D7A, 0x6D42, 0x6D0A, 0x6CD2, + 0x6C99, 0x6C61, 0x6C2A, 0x6BF2, 0x6BBA, 0x6B83, + 0x6B4B, 0x6B14, 0x6ADD, 0x6AA6, 0x6A6F, 0x6A38, + 0x6A01, 0x69CB, 0x6994, 0x695E, 0x6927, 0x68F1, + 0x68BB, 0x6885, 0x684F, 0x681A, 0x67E4, 0x67AE, + 0x6779, 0x6744, 0x670F, 0x66D9, 0x66A4, 0x6670, + 0x663B, 0x6606, 0x65D2, 0x659D, 0x6569, 0x6534, + 0x6500, 0x64CC, 0x6498, 0x6464, 0x6431, 0x63FD, + 0x63CA, 0x6396, 0x6363, 0x6330, 0x62FD, 0x62CA, + 0x6297, 0x6264, 0x6231, 0x61FF, 0x61CC, 0x619A, + 0x6167, 0x6135, 0x6103, 0x60D1, 0x609F, 0x606D, + 0x603C, 0x600A, 0x5FD9, 0x5FA7, 0x5F76, 0x5F45, + 0x5F14, 0x5EE3, 0x5EB2, 0x5E81, 0x5E50, 0x5E20, + 0x5DEF, 0x5DBF, 0x5D8F, 0x5D5E, 0x5D2E, 0x5CFE, + 0x5CCE, 0x5C9F, 0x5C6F, 0x5C3F, 0x5C10, 0x5BE0, + 0x5BB1, 0x5B82, 0x5B52, 0x5B23, 0x5AF4, 0x5AC6, + 0x5A97, 0x5A68, 0x5A3A, 0x5A0B, 0x59DD, 0x59AE, + 0x5980, 0x5952, 0x5924, 0x58F6, 0x58C8, 0x589A, + 0x586D, 0x583F, 0x5812, 0x57E4, 0x57B7, 0x578A, + 0x575D, 0x5730, 0x5703, 0x56D6, 0x56A9, 0x567D, + 0x5650, 0x5624, 0x55F7, 0x55CB, 0x559F, 0x5573, + 0x5547, 0x551B, 0x54EF, 0x54C3, 0x5497, 0x546C, + 0x5440, 0x5415, 0x53EA, 0x53BE, 0x5393, 0x5368, + 0x533D, 0x5312, 0x52E7, 0x52BD, 0x5292, 0x5267, + 0x523D, 0x5213, 0x51E8, 0x51BE, 0x5194, 0x516A, + 0x5140, 0x5116, 0x50EC, 0x50C3, 0x6A48, 0x6A19, + 0x69EA, 0x69BB, 0x698C, 0x695E, 0x692F, 0x6901, + 0x68D2, 0x68A4, 0x6876, 0x6848, 0x681A, 0x67EC, + 0x67BE, 0x6790, 0x6762, 0x6735, 0x6707, 0x66D9, + 0x66AC, 0x667F, 0x6651, 0x6624, 0x65F7, 0x65CA, + 0x659D, 0x6570, 0x6543, 0x6517, 0x64EA, 0x64BD, + 0x6491, 0x6464, 0x6438, 0x640C, 0x63E0, 0x63B4, + 0x6388, 0x635C, 0x6330, 0x6304, 0x62D8, 0x62AC, + 0x6281, 0x6255, 0x622A, 0x61FF, 0x61D3, 0x61A8, + 0x617D, 0x6152, 0x6127, 0x60FC, 0x60D1, 0x60A6, + 0x607C, 0x6051, 0x6027, 0x5FFC, 0x5FD2, 0x5FA7, + 0x5F7D, 0x5F53, 0x5F29, 0x5EFF, 0x5ED5, 0x5EAB, + 0x5E81, 0x5E57, 0x5E2E, 0x5E04, 0x5DDB, 0x5DB1, + 0x5D88, 0x5D5E, 0x5D35, 0x5D0C, 0x5CE3, 0x5CBA, + 0x5C91, 0x5C68, 0x5C3F, 0x5C16, 0x5BEE, 0x5BC5, + 0x5B9D, 0x5B74, 0x5B4C, 0x5B23, 0x5AFB, 0x5AD3, + 0x5AAB, 0x5A83, 0x5A5B, 0x5A33, 0x5A0B, 0x59E3, + 0x59BC, 0x5994, 0x596C, 0x5945, 0x591D, 0x58F6, + 0x58CF, 0x58A8, 0x5880, 0x5859, 0x5832, 0x580B, + 0x57E4, 0x57BE, 0x5797, 0x5770, 0x574A, 0x5723, + 0x56FC, 0x56D6, 0x56B0, 0x5689, 0x5663, 0x563D, + 0x5617, 0x55F1, 0x55CB, 0x55A5, 0x557F, 0x5559, + 0x5534, 0x550E, 0x54E9, 0x54C3, 0x549E, 0x5478, + 0x5453, 0x542E, 0x5408, 0x53E3, 0x53BE, 0x5399, + 0x5374, 0x534F, 0x532B, 0x5306, 0x52E1, 0x52BD, + 0x5298, 0x5274, 0x524F, 0x522B, 0x5207, 0x51E2, + 0x51BE, 0x519A, 0x5176, 0x5152, 0x512E, 0x510A, + 0x50E6, 0x50C3, 0x6587, 0x6561, 0x653C, 0x6517, + 0x64F1, 0x64CC, 0x64A7, 0x6482, 0x645D, 0x6438, + 0x6413, 0x63EE, 0x63CA, 0x63A5, 0x6380, 0x635C, + 0x6337, 0x6312, 0x62EE, 0x62CA, 0x62A5, 0x6281, + 0x625D, 0x6238, 0x6214, 0x61F0, 0x61CC, 0x61A8, + 0x6184, 0x6160, 0x613C, 0x6119, 0x60F5, 0x60D1, + 0x60AD, 0x608A, 0x6066, 0x6043, 0x601F, 0x5FFC, + 0x5FD9, 0x5FB5, 0x5F92, 0x5F6F, 0x5F4C, 0x5F29, + 0x5F06, 0x5EE3, 0x5EC0, 0x5E9D, 0x5E7A, 0x5E57, + 0x5E35, 0x5E12, 0x5DEF, 0x5DCD, 0x5DAA, 0x5D88, + 0x5D65, 0x5D43, 0x5D21, 0x5CFE, 0x5CDC, 0x5CBA, + 0x5C98, 0x5C76, 0x5C54, 0x5C32, 0x5C10, 0x5BEE, + 0x5BCC, 0x5BAA, 0x5B88, 0x5B67, 0x5B45, 0x5B23, + 0x5B02, 0x5AE0, 0x5ABF, 0x5A9D, 0x5A7C, 0x5A5B, + 0x5A3A, 0x5A18, 0x59F7, 0x59D6, 0x59B5, 0x5994, + 0x5973, 0x5952, 0x5931, 0x5910, 0x58F0, 0x58CF, + 0x58AE, 0x588D, 0x586D, 0x584C, 0x582C, 0x580B, + 0x57EB, 0x57CB, 0x57AA, 0x578A, 0x576A, 0x574A, + 0x5729, 0x5709, 0x56E9, 0x56C9, 0x56A9, 0x5689, + 0x566A, 0x564A, 0x562A, 0x560A, 0x55EB, 0x55CB, + 0x55AB, 0x558C, 0x556C, 0x554D, 0x552D, 0x550E, + 0x54EF, 0x54D0, 0x54B0, 0x5491, 0x5472, 0x5453, + 0x5434, 0x5415, 0x53F6, 0x53D7, 0x53B8, 0x5399, + 0x537B, 0x535C, 0x533D, 0x531E, 0x5300, 0x52E1, + 0x52C3, 0x52A4, 0x5286, 0x5267, 0x5249, 0x522B, + 0x520D, 0x51EE, 0x51D0, 0x51B2, 0x5194, 0x5176, + 0x5158, 0x513A, 0x511C, 0x50FE, 0x50E0, 0x50C3, + 0x60FC, 0x60DF, 0x60C3, 0x60A6, 0x608A, 0x606D, + 0x6051, 0x6035, 0x6018, 0x5FFC, 0x5FE0, 0x5FC4, + 0x5FA7, 0x5F8B, 0x5F6F, 0x5F53, 0x5F37, 0x5F1B, + 0x5EFF, 0x5EE3, 0x5EC7, 0x5EAB, 0x5E8F, 0x5E73, + 0x5E57, 0x5E3C, 0x5E20, 0x5E04, 0x5DE8, 0x5DCD, + 0x5DB1, 0x5D95, 0x5D7A, 0x5D5E, 0x5D43, 0x5D27, + 0x5D0C, 0x5CF1, 0x5CD5, 0x5CBA, 0x5C9F, 0x5C83, + 0x5C68, 0x5C4D, 0x5C32, 0x5C16, 0x5BFB, 0x5BE0, + 0x5BC5, 0x5BAA, 0x5B8F, 0x5B74, 0x5B59, 0x5B3E, + 0x5B23, 0x5B09, 0x5AEE, 0x5AD3, 0x5AB8, 0x5A9D, + 0x5A83, 0x5A68, 0x5A4D, 0x5A33, 0x5A18, 0x59FE, + 0x59E3, 0x59C9, 0x59AE, 0x5994, 0x597A, 0x595F, + 0x5945, 0x592B, 0x5910, 0x58F6, 0x58DC, 0x58C2, + 0x58A8, 0x588D, 0x5873, 0x5859, 0x583F, 0x5825, + 0x580B, 0x57F1, 0x57D7, 0x57BE, 0x57A4, 0x578A, + 0x5770, 0x5756, 0x573D, 0x5723, 0x5709, 0x56F0, + 0x56D6, 0x56BC, 0x56A3, 0x5689, 0x5670, 0x5656, + 0x563D, 0x5624, 0x560A, 0x55F1, 0x55D8, 0x55BE, + 0x55A5, 0x558C, 0x5573, 0x5559, 0x5540, 0x5527, + 0x550E, 0x54F5, 0x54DC, 0x54C3, 0x54AA, 0x5491, + 0x5478, 0x545F, 0x5446, 0x542E, 0x5415, 0x53FC, + 0x53E3, 0x53CB, 0x53B2, 0x5399, 0x5381, 0x5368, + 0x534F, 0x5337, 0x531E, 0x5306, 0x52ED, 0x52D5, + 0x52BD, 0x52A4, 0x528C, 0x5274, 0x525B, 0x5243, + 0x522B, 0x5213, 0x51FA, 0x51E2, 0x51CA, 0x51B2, + 0x519A, 0x5182, 0x516A, 0x5152, 0x513A, 0x5122, + 0x510A, 0x50F2, 0x50DB, 0x50C3, 0x5CA5, 0x5C91, + 0x5C7C, 0x5C68, 0x5C54, 0x5C3F, 0x5C2B, 0x5C16, + 0x5C02, 0x5BEE, 0x5BD9, 0x5BC5, 0x5BB1, 0x5B9D, + 0x5B88, 0x5B74, 0x5B60, 0x5B4C, 0x5B38, 0x5B23, + 0x5B0F, 0x5AFB, 0x5AE7, 0x5AD3, 0x5ABF, 0x5AAB, + 0x5A97, 0x5A83, 0x5A6F, 0x5A5B, 0x5A47, 0x5A33, + 0x5A1F, 0x5A0B, 0x59F7, 0x59E3, 0x59CF, 0x59BC, + 0x59A8, 0x5994, 0x5980, 0x596C, 0x5959, 0x5945, + 0x5931, 0x591D, 0x590A, 0x58F6, 0x58E2, 0x58CF, + 0x58BB, 0x58A8, 0x5894, 0x5880, 0x586D, 0x5859, + 0x5846, 0x5832, 0x581F, 0x580B, 0x57F8, 0x57E4, + 0x57D1, 0x57BE, 0x57AA, 0x5797, 0x5783, 0x5770, + 0x575D, 0x574A, 0x5736, 0x5723, 0x5710, 0x56FC, + 0x56E9, 0x56D6, 0x56C3, 0x56B0, 0x569D, 0x5689, + 0x5676, 0x5663, 0x5650, 0x563D, 0x562A, 0x5617, + 0x5604, 0x55F1, 0x55DE, 0x55CB, 0x55B8, 0x55A5, + 0x5592, 0x557F, 0x556C, 0x5559, 0x5547, 0x5534, + 0x5521, 0x550E, 0x54FB, 0x54E9, 0x54D6, 0x54C3, + 0x54B0, 0x549E, 0x548B, 0x5478, 0x5466, 0x5453, + 0x5440, 0x542E, 0x541B, 0x5408, 0x53F6, 0x53E3, + 0x53D1, 0x53BE, 0x53AC, 0x5399, 0x5387, 0x5374, + 0x5362, 0x534F, 0x533D, 0x532B, 0x5318, 0x5306, + 0x52F4, 0x52E1, 0x52CF, 0x52BD, 0x52AA, 0x5298, + 0x5286, 0x5274, 0x5261, 0x524F, 0x523D, 0x522B, + 0x5219, 0x5207, 0x51F4, 0x51E2, 0x51D0, 0x51BE, + 0x51AC, 0x519A, 0x5188, 0x5176, 0x5164, 0x5152, + 0x5140, 0x512E, 0x511C, 0x510A, 0x50F8, 0x50E6, + 0x50D5, 0x50C3, 0x5880, 0x5873, 0x5866, 0x5859, + 0x584C, 0x583F, 0x5832, 0x5825, 0x5818, 0x580B, + 0x57FE, 0x57F1, 0x57E4, 0x57D7, 0x57CB, 0x57BE, + 0x57B1, 0x57A4, 0x5797, 0x578A, 0x577D, 0x5770, + 0x5763, 0x5756, 0x574A, 0x573D, 0x5730, 0x5723, + 0x5716, 0x5709, 0x56FC, 0x56F0, 0x56E3, 0x56D6, + 0x56C9, 0x56BC, 0x56B0, 0x56A3, 0x5696, 0x5689, + 0x567D, 0x5670, 0x5663, 0x5656, 0x564A, 0x563D, + 0x5630, 0x5624, 0x5617, 0x560A, 0x55FE, 0x55F1, + 0x55E4, 0x55D8, 0x55CB, 0x55BE, 0x55B2, 0x55A5, + 0x5598, 0x558C, 0x557F, 0x5573, 0x5566, 0x5559, + 0x554D, 0x5540, 0x5534, 0x5527, 0x551B, 0x550E, + 0x5502, 0x54F5, 0x54E9, 0x54DC, 0x54D0, 0x54C3, + 0x54B7, 0x54AA, 0x549E, 0x5491, 0x5485, 0x5478, + 0x546C, 0x545F, 0x5453, 0x5446, 0x543A, 0x542E, + 0x5421, 0x5415, 0x5408, 0x53FC, 0x53F0, 0x53E3, + 0x53D7, 0x53CB, 0x53BE, 0x53B2, 0x53A6, 0x5399, + 0x538D, 0x5381, 0x5374, 0x5368, 0x535C, 0x534F, + 0x5343, 0x5337, 0x532B, 0x531E, 0x5312, 0x5306, + 0x52FA, 0x52ED, 0x52E1, 0x52D5, 0x52C9, 0x52BD, + 0x52B0, 0x52A4, 0x5298, 0x528C, 0x5280, 0x5274, + 0x5267, 0x525B, 0x524F, 0x5243, 0x5237, 0x522B, + 0x521F, 0x5213, 0x5207, 0x51FA, 0x51EE, 0x51E2, + 0x51D6, 0x51CA, 0x51BE, 0x51B2, 0x51A6, 0x519A, + 0x518E, 0x5182, 0x5176, 0x516A, 0x515E, 0x5152, + 0x5146, 0x513A, 0x512E, 0x5122, 0x5116, 0x510A, + 0x50FE, 0x50F2, 0x50E6, 0x50DB, 0x50CF, 0x50C3, + 0x548B, 0x5485, 0x547E, 0x5478, 0x5472, 0x546C, + 0x5466, 0x545F, 0x5459, 0x5453, 0x544D, 0x5446, + 0x5440, 0x543A, 0x5434, 0x542E, 0x5427, 0x5421, + 0x541B, 0x5415, 0x540F, 0x5408, 0x5402, 0x53FC, + 0x53F6, 0x53F0, 0x53EA, 0x53E3, 0x53DD, 0x53D7, + 0x53D1, 0x53CB, 0x53C4, 0x53BE, 0x53B8, 0x53B2, + 0x53AC, 0x53A6, 0x539F, 0x5399, 0x5393, 0x538D, + 0x5387, 0x5381, 0x537B, 0x5374, 0x536E, 0x5368, + 0x5362, 0x535C, 0x5356, 0x534F, 0x5349, 0x5343, + 0x533D, 0x5337, 0x5331, 0x532B, 0x5325, 0x531E, + 0x5318, 0x5312, 0x530C, 0x5306, 0x5300, 0x52FA, + 0x52F4, 0x52ED, 0x52E7, 0x52E1, 0x52DB, 0x52D5, + 0x52CF, 0x52C9, 0x52C3, 0x52BD, 0x52B7, 0x52B0, + 0x52AA, 0x52A4, 0x529E, 0x5298, 0x5292, 0x528C, + 0x5286, 0x5280, 0x527A, 0x5274, 0x526E, 0x5267, + 0x5261, 0x525B, 0x5255, 0x524F, 0x5249, 0x5243, + 0x523D, 0x5237, 0x5231, 0x522B, 0x5225, 0x521F, + 0x5219, 0x5213, 0x520D, 0x5207, 0x5201, 0x51FA, + 0x51F4, 0x51EE, 0x51E8, 0x51E2, 0x51DC, 0x51D6, + 0x51D0, 0x51CA, 0x51C4, 0x51BE, 0x51B8, 0x51B2, + 0x51AC, 0x51A6, 0x51A0, 0x519A, 0x5194, 0x518E, + 0x5188, 0x5182, 0x517C, 0x5176, 0x5170, 0x516A, + 0x5164, 0x515E, 0x5158, 0x5152, 0x514C, 0x5146, + 0x5140, 0x513A, 0x5134, 0x512E, 0x5128, 0x5122, + 0x511C, 0x5116, 0x5110, 0x510A, 0x5104, 0x50FE, + 0x50F8, 0x50F2, 0x50EC, 0x50E6, 0x50E0, 0x50DB, + 0x50D5, 0x50CF, 0x50C9, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x7A46, 0x7A4F, 0x7A58, 0x7A61, + 0x7A6A, 0x7A73, 0x7A7C, 0x7A85, 0x7A8E, 0x7A97, + 0x7AA0, 0x7AA9, 0x7AB2, 0x7ABB, 0x7AC4, 0x7ACD, + 0x7AD6, 0x7ADF, 0x7AE8, 0x7AF1, 0x7AFA, 0x7B03, + 0x7B0D, 0x7B16, 0x7B1F, 0x7B28, 0x7B31, 0x7B3A, + 0x7B43, 0x7B4C, 0x7B55, 0x7B5E, 0x7B67, 0x7B70, + 0x7B7A, 0x7B83, 0x7B8C, 0x7B95, 0x7B9E, 0x7BA7, + 0x7BB0, 0x7BB9, 0x7BC2, 0x7BCC, 0x7BD5, 0x7BDE, + 0x7BE7, 0x7BF0, 0x7BF9, 0x7C02, 0x7C0B, 0x7C15, + 0x7C1E, 0x7C27, 0x7C30, 0x7C39, 0x7C42, 0x7C4B, + 0x7C55, 0x7C5E, 0x7C67, 0x7C70, 0x7C79, 0x7C82, + 0x7C8C, 0x7C95, 0x7C9E, 0x7CA7, 0x7CB0, 0x7CBA, + 0x7CC3, 0x7CCC, 0x7CD5, 0x7CDE, 0x7CE8, 0x7CF1, + 0x7CFA, 0x7D03, 0x7D0C, 0x7D16, 0x7D1F, 0x7D28, + 0x7D31, 0x7D3A, 0x7D44, 0x7D4D, 0x7D56, 0x7D5F, + 0x7D69, 0x7D72, 0x7D7B, 0x7D84, 0x7D8E, 0x7D97, + 0x7DA0, 0x7DA9, 0x7DB3, 0x7DBC, 0x7DC5, 0x7DCE, + 0x7DD8, 0x7DE1, 0x7DEA, 0x7DF4, 0x7DFD, 0x7E06, + 0x7E0F, 0x7E19, 0x7E22, 0x7E2B, 0x7E35, 0x7E3E, + 0x7E47, 0x7E51, 0x7E5A, 0x7E63, 0x7E6C, 0x7E76, + 0x7E7F, 0x7E88, 0x7E92, 0x7E9B, 0x7EA4, 0x7EAE, + 0x7EB7, 0x7EC0, 0x7ECA, 0x7ED3, 0x7EDC, 0x7EE6, + 0x7EEF, 0x7EF8, 0x7F02, 0x7F0B, 0x7F15, 0x7F1E, + 0x7F27, 0x7F31, 0x7F3A, 0x7F43, 0x7F4D, 0x7F56, + 0x7F60, 0x7F69, 0x7F72, 0x7F7C, 0x7F85, 0x7F8F, + 0x7F98, 0x7FA1, 0x7FAB, 0x7FB4, 0x7FBE, 0x7FC7, + 0x7FD0, 0x7FDA, 0x7FE3, 0x7FED, 0x7FF6, 0x8000, + 0x74C5, 0x74CD, 0x74D6, 0x74DF, 0x74E7, 0x74F0, + 0x74F9, 0x7501, 0x750A, 0x7512, 0x751B, 0x7524, + 0x752C, 0x7535, 0x753E, 0x7546, 0x754F, 0x7558, + 0x7560, 0x7569, 0x7571, 0x757A, 0x7583, 0x758B, + 0x7594, 0x759D, 0x75A5, 0x75AE, 0x75B7, 0x75BF, + 0x75C8, 0x75D1, 0x75D9, 0x75E2, 0x75EB, 0x75F4, + 0x75FC, 0x7605, 0x760E, 0x7616, 0x761F, 0x7628, + 0x7630, 0x7639, 0x7642, 0x764B, 0x7653, 0x765C, + 0x7665, 0x766D, 0x7676, 0x767F, 0x7688, 0x7690, + 0x7699, 0x76A2, 0x76AB, 0x76B3, 0x76BC, 0x76C5, + 0x76CE, 0x76D6, 0x76DF, 0x76E8, 0x76F1, 0x76F9, + 0x7702, 0x770B, 0x7714, 0x771C, 0x7725, 0x772E, + 0x7737, 0x7740, 0x7748, 0x7751, 0x775A, 0x7763, + 0x776C, 0x7774, 0x777D, 0x7786, 0x778F, 0x7798, + 0x77A0, 0x77A9, 0x77B2, 0x77BB, 0x77C4, 0x77CD, + 0x77D5, 0x77DE, 0x77E7, 0x77F0, 0x77F9, 0x7802, + 0x780A, 0x7813, 0x781C, 0x7825, 0x782E, 0x7837, + 0x783F, 0x7848, 0x7851, 0x785A, 0x7863, 0x786C, + 0x7875, 0x787E, 0x7886, 0x788F, 0x7898, 0x78A1, + 0x78AA, 0x78B3, 0x78BC, 0x78C5, 0x78CE, 0x78D6, + 0x78DF, 0x78E8, 0x78F1, 0x78FA, 0x7903, 0x790C, + 0x7915, 0x791E, 0x7927, 0x7930, 0x7939, 0x7942, + 0x794A, 0x7953, 0x795C, 0x7965, 0x796E, 0x7977, + 0x7980, 0x7989, 0x7992, 0x799B, 0x79A4, 0x79AD, + 0x79B6, 0x79BF, 0x79C8, 0x79D1, 0x79DA, 0x79E3, + 0x79EC, 0x79F5, 0x79FE, 0x7A07, 0x7A10, 0x7A19, + 0x7A22, 0x7A2B, 0x7A34, 0x7A3D, 0x6F83, 0x6F8C, + 0x6F94, 0x6F9C, 0x6FA4, 0x6FAD, 0x6FB5, 0x6FBD, + 0x6FC5, 0x6FCD, 0x6FD6, 0x6FDE, 0x6FE6, 0x6FEE, + 0x6FF7, 0x6FFF, 0x7007, 0x700F, 0x7018, 0x7020, + 0x7028, 0x7031, 0x7039, 0x7041, 0x7049, 0x7052, + 0x705A, 0x7062, 0x706A, 0x7073, 0x707B, 0x7083, + 0x708C, 0x7094, 0x709C, 0x70A4, 0x70AD, 0x70B5, + 0x70BD, 0x70C6, 0x70CE, 0x70D6, 0x70DF, 0x70E7, + 0x70EF, 0x70F8, 0x7100, 0x7108, 0x7111, 0x7119, + 0x7121, 0x712A, 0x7132, 0x713A, 0x7143, 0x714B, + 0x7153, 0x715C, 0x7164, 0x716C, 0x7175, 0x717D, + 0x7185, 0x718E, 0x7196, 0x719F, 0x71A7, 0x71AF, + 0x71B8, 0x71C0, 0x71C8, 0x71D1, 0x71D9, 0x71E2, + 0x71EA, 0x71F2, 0x71FB, 0x7203, 0x720C, 0x7214, + 0x721C, 0x7225, 0x722D, 0x7236, 0x723E, 0x7246, + 0x724F, 0x7257, 0x7260, 0x7268, 0x7271, 0x7279, + 0x7281, 0x728A, 0x7292, 0x729B, 0x72A3, 0x72AC, + 0x72B4, 0x72BD, 0x72C5, 0x72CE, 0x72D6, 0x72DE, + 0x72E7, 0x72EF, 0x72F8, 0x7300, 0x7309, 0x7311, + 0x731A, 0x7322, 0x732B, 0x7333, 0x733C, 0x7344, + 0x734D, 0x7355, 0x735E, 0x7366, 0x736F, 0x7377, + 0x7380, 0x7388, 0x7391, 0x7399, 0x73A2, 0x73AA, + 0x73B3, 0x73BB, 0x73C4, 0x73CC, 0x73D5, 0x73DD, + 0x73E6, 0x73EF, 0x73F7, 0x7400, 0x7408, 0x7411, + 0x7419, 0x7422, 0x742A, 0x7433, 0x743C, 0x7444, + 0x744D, 0x7455, 0x745E, 0x7466, 0x746F, 0x7478, + 0x7480, 0x7489, 0x7491, 0x749A, 0x74A2, 0x74AB, + 0x74B4, 0x74BC, 0x6A7F, 0x6A86, 0x6A8E, 0x6A96, + 0x6A9E, 0x6AA6, 0x6AAE, 0x6AB6, 0x6ABD, 0x6AC5, + 0x6ACD, 0x6AD5, 0x6ADD, 0x6AE5, 0x6AED, 0x6AF5, + 0x6AFC, 0x6B04, 0x6B0C, 0x6B14, 0x6B1C, 0x6B24, + 0x6B2C, 0x6B34, 0x6B3C, 0x6B43, 0x6B4B, 0x6B53, + 0x6B5B, 0x6B63, 0x6B6B, 0x6B73, 0x6B7B, 0x6B83, + 0x6B8B, 0x6B93, 0x6B9B, 0x6BA2, 0x6BAA, 0x6BB2, + 0x6BBA, 0x6BC2, 0x6BCA, 0x6BD2, 0x6BDA, 0x6BE2, + 0x6BEA, 0x6BF2, 0x6BFA, 0x6C02, 0x6C0A, 0x6C12, + 0x6C1A, 0x6C22, 0x6C2A, 0x6C32, 0x6C3A, 0x6C42, + 0x6C4A, 0x6C52, 0x6C59, 0x6C61, 0x6C69, 0x6C71, + 0x6C79, 0x6C81, 0x6C89, 0x6C91, 0x6C99, 0x6CA1, + 0x6CA9, 0x6CB1, 0x6CB9, 0x6CC1, 0x6CC9, 0x6CD2, + 0x6CDA, 0x6CE2, 0x6CEA, 0x6CF2, 0x6CFA, 0x6D02, + 0x6D0A, 0x6D12, 0x6D1A, 0x6D22, 0x6D2A, 0x6D32, + 0x6D3A, 0x6D42, 0x6D4A, 0x6D52, 0x6D5A, 0x6D62, + 0x6D6A, 0x6D72, 0x6D7A, 0x6D82, 0x6D8B, 0x6D93, + 0x6D9B, 0x6DA3, 0x6DAB, 0x6DB3, 0x6DBB, 0x6DC3, + 0x6DCB, 0x6DD3, 0x6DDB, 0x6DE3, 0x6DEC, 0x6DF4, + 0x6DFC, 0x6E04, 0x6E0C, 0x6E14, 0x6E1C, 0x6E24, + 0x6E2C, 0x6E35, 0x6E3D, 0x6E45, 0x6E4D, 0x6E55, + 0x6E5D, 0x6E65, 0x6E6D, 0x6E76, 0x6E7E, 0x6E86, + 0x6E8E, 0x6E96, 0x6E9E, 0x6EA6, 0x6EAF, 0x6EB7, + 0x6EBF, 0x6EC7, 0x6ECF, 0x6ED7, 0x6EE0, 0x6EE8, + 0x6EF0, 0x6EF8, 0x6F00, 0x6F08, 0x6F11, 0x6F19, + 0x6F21, 0x6F29, 0x6F31, 0x6F3A, 0x6F42, 0x6F4A, + 0x6F52, 0x6F5A, 0x6F63, 0x6F6B, 0x6F73, 0x6F7B, + 0x65B4, 0x65BB, 0x65C3, 0x65CA, 0x65D2, 0x65D9, + 0x65E1, 0x65E8, 0x65F0, 0x65F7, 0x65FF, 0x6606, + 0x660E, 0x6615, 0x661D, 0x6624, 0x662C, 0x6633, + 0x663B, 0x6642, 0x664A, 0x6651, 0x6659, 0x6660, + 0x6668, 0x6670, 0x6677, 0x667F, 0x6686, 0x668E, + 0x6695, 0x669D, 0x66A4, 0x66AC, 0x66B4, 0x66BB, + 0x66C3, 0x66CA, 0x66D2, 0x66D9, 0x66E1, 0x66E9, + 0x66F0, 0x66F8, 0x66FF, 0x6707, 0x670F, 0x6716, + 0x671E, 0x6725, 0x672D, 0x6735, 0x673C, 0x6744, + 0x674B, 0x6753, 0x675B, 0x6762, 0x676A, 0x6771, + 0x6779, 0x6781, 0x6788, 0x6790, 0x6798, 0x679F, + 0x67A7, 0x67AE, 0x67B6, 0x67BE, 0x67C5, 0x67CD, + 0x67D5, 0x67DC, 0x67E4, 0x67EC, 0x67F3, 0x67FB, + 0x6803, 0x680A, 0x6812, 0x681A, 0x6821, 0x6829, + 0x6831, 0x6838, 0x6840, 0x6848, 0x684F, 0x6857, + 0x685F, 0x6866, 0x686E, 0x6876, 0x687E, 0x6885, + 0x688D, 0x6895, 0x689C, 0x68A4, 0x68AC, 0x68B4, + 0x68BB, 0x68C3, 0x68CB, 0x68D2, 0x68DA, 0x68E2, + 0x68EA, 0x68F1, 0x68F9, 0x6901, 0x6909, 0x6910, + 0x6918, 0x6920, 0x6927, 0x692F, 0x6937, 0x693F, + 0x6947, 0x694E, 0x6956, 0x695E, 0x6966, 0x696D, + 0x6975, 0x697D, 0x6985, 0x698C, 0x6994, 0x699C, + 0x69A4, 0x69AC, 0x69B3, 0x69BB, 0x69C3, 0x69CB, + 0x69D2, 0x69DA, 0x69E2, 0x69EA, 0x69F2, 0x69FA, + 0x6A01, 0x6A09, 0x6A11, 0x6A19, 0x6A21, 0x6A28, + 0x6A30, 0x6A38, 0x6A40, 0x6A48, 0x6A50, 0x6A57, + 0x6A5F, 0x6A67, 0x6A6F, 0x6A77, 0x6120, 0x6127, + 0x612E, 0x6135, 0x613C, 0x6144, 0x614B, 0x6152, + 0x6159, 0x6160, 0x6167, 0x616F, 0x6176, 0x617D, + 0x6184, 0x618B, 0x6192, 0x619A, 0x61A1, 0x61A8, + 0x61AF, 0x61B6, 0x61BE, 0x61C5, 0x61CC, 0x61D3, + 0x61DA, 0x61E2, 0x61E9, 0x61F0, 0x61F7, 0x61FF, + 0x6206, 0x620D, 0x6214, 0x621B, 0x6223, 0x622A, + 0x6231, 0x6238, 0x6240, 0x6247, 0x624E, 0x6255, + 0x625D, 0x6264, 0x626B, 0x6272, 0x627A, 0x6281, + 0x6288, 0x628F, 0x6297, 0x629E, 0x62A5, 0x62AC, + 0x62B4, 0x62BB, 0x62C2, 0x62CA, 0x62D1, 0x62D8, + 0x62DF, 0x62E7, 0x62EE, 0x62F5, 0x62FD, 0x6304, + 0x630B, 0x6312, 0x631A, 0x6321, 0x6328, 0x6330, + 0x6337, 0x633E, 0x6346, 0x634D, 0x6354, 0x635C, + 0x6363, 0x636A, 0x6372, 0x6379, 0x6380, 0x6388, + 0x638F, 0x6396, 0x639E, 0x63A5, 0x63AC, 0x63B4, + 0x63BB, 0x63C2, 0x63CA, 0x63D1, 0x63D8, 0x63E0, + 0x63E7, 0x63EE, 0x63F6, 0x63FD, 0x6405, 0x640C, + 0x6413, 0x641B, 0x6422, 0x6429, 0x6431, 0x6438, + 0x6440, 0x6447, 0x644E, 0x6456, 0x645D, 0x6464, + 0x646C, 0x6473, 0x647B, 0x6482, 0x648A, 0x6491, + 0x6498, 0x64A0, 0x64A7, 0x64AF, 0x64B6, 0x64BD, + 0x64C5, 0x64CC, 0x64D4, 0x64DB, 0x64E3, 0x64EA, + 0x64F1, 0x64F9, 0x6500, 0x6508, 0x650F, 0x6517, + 0x651E, 0x6526, 0x652D, 0x6534, 0x653C, 0x6543, + 0x654B, 0x6552, 0x655A, 0x6561, 0x6569, 0x6570, + 0x6578, 0x657F, 0x6587, 0x658E, 0x6596, 0x659D, + 0x65A5, 0x65AC, 0x5CC1, 0x5CC7, 0x5CCE, 0x5CD5, + 0x5CDC, 0x5CE3, 0x5CEA, 0x5CF1, 0x5CF7, 0x5CFE, + 0x5D05, 0x5D0C, 0x5D13, 0x5D1A, 0x5D21, 0x5D27, + 0x5D2E, 0x5D35, 0x5D3C, 0x5D43, 0x5D4A, 0x5D51, + 0x5D57, 0x5D5E, 0x5D65, 0x5D6C, 0x5D73, 0x5D7A, + 0x5D81, 0x5D88, 0x5D8F, 0x5D95, 0x5D9C, 0x5DA3, + 0x5DAA, 0x5DB1, 0x5DB8, 0x5DBF, 0x5DC6, 0x5DCD, + 0x5DD4, 0x5DDB, 0x5DE1, 0x5DE8, 0x5DEF, 0x5DF6, + 0x5DFD, 0x5E04, 0x5E0B, 0x5E12, 0x5E19, 0x5E20, + 0x5E27, 0x5E2E, 0x5E35, 0x5E3C, 0x5E42, 0x5E49, + 0x5E50, 0x5E57, 0x5E5E, 0x5E65, 0x5E6C, 0x5E73, + 0x5E7A, 0x5E81, 0x5E88, 0x5E8F, 0x5E96, 0x5E9D, + 0x5EA4, 0x5EAB, 0x5EB2, 0x5EB9, 0x5EC0, 0x5EC7, + 0x5ECE, 0x5ED5, 0x5EDC, 0x5EE3, 0x5EEA, 0x5EF1, + 0x5EF8, 0x5EFF, 0x5F06, 0x5F0D, 0x5F14, 0x5F1B, + 0x5F22, 0x5F29, 0x5F30, 0x5F37, 0x5F3E, 0x5F45, + 0x5F4C, 0x5F53, 0x5F5A, 0x5F61, 0x5F68, 0x5F6F, + 0x5F76, 0x5F7D, 0x5F84, 0x5F8B, 0x5F92, 0x5F99, + 0x5FA0, 0x5FA7, 0x5FAE, 0x5FB5, 0x5FBC, 0x5FC4, + 0x5FCB, 0x5FD2, 0x5FD9, 0x5FE0, 0x5FE7, 0x5FEE, + 0x5FF5, 0x5FFC, 0x6003, 0x600A, 0x6011, 0x6018, + 0x601F, 0x6027, 0x602E, 0x6035, 0x603C, 0x6043, + 0x604A, 0x6051, 0x6058, 0x605F, 0x6066, 0x606D, + 0x6075, 0x607C, 0x6083, 0x608A, 0x6091, 0x6098, + 0x609F, 0x60A6, 0x60AD, 0x60B5, 0x60BC, 0x60C3, + 0x60CA, 0x60D1, 0x60D8, 0x60DF, 0x60E7, 0x60EE, + 0x60F5, 0x60FC, 0x6103, 0x610A, 0x6111, 0x6119, + 0x5894, 0x589A, 0x58A1, 0x58A8, 0x58AE, 0x58B5, + 0x58BB, 0x58C2, 0x58C8, 0x58CF, 0x58D5, 0x58DC, + 0x58E2, 0x58E9, 0x58F0, 0x58F6, 0x58FD, 0x5903, + 0x590A, 0x5910, 0x5917, 0x591D, 0x5924, 0x592B, + 0x5931, 0x5938, 0x593E, 0x5945, 0x594B, 0x5952, + 0x5959, 0x595F, 0x5966, 0x596C, 0x5973, 0x597A, + 0x5980, 0x5987, 0x598D, 0x5994, 0x599B, 0x59A1, + 0x59A8, 0x59AE, 0x59B5, 0x59BC, 0x59C2, 0x59C9, + 0x59CF, 0x59D6, 0x59DD, 0x59E3, 0x59EA, 0x59F1, + 0x59F7, 0x59FE, 0x5A04, 0x5A0B, 0x5A12, 0x5A18, + 0x5A1F, 0x5A26, 0x5A2C, 0x5A33, 0x5A3A, 0x5A40, + 0x5A47, 0x5A4D, 0x5A54, 0x5A5B, 0x5A61, 0x5A68, + 0x5A6F, 0x5A75, 0x5A7C, 0x5A83, 0x5A89, 0x5A90, + 0x5A97, 0x5A9D, 0x5AA4, 0x5AAB, 0x5AB2, 0x5AB8, + 0x5ABF, 0x5AC6, 0x5ACC, 0x5AD3, 0x5ADA, 0x5AE0, + 0x5AE7, 0x5AEE, 0x5AF4, 0x5AFB, 0x5B02, 0x5B09, + 0x5B0F, 0x5B16, 0x5B1D, 0x5B23, 0x5B2A, 0x5B31, + 0x5B38, 0x5B3E, 0x5B45, 0x5B4C, 0x5B52, 0x5B59, + 0x5B60, 0x5B67, 0x5B6D, 0x5B74, 0x5B7B, 0x5B82, + 0x5B88, 0x5B8F, 0x5B96, 0x5B9D, 0x5BA3, 0x5BAA, + 0x5BB1, 0x5BB8, 0x5BBE, 0x5BC5, 0x5BCC, 0x5BD3, + 0x5BD9, 0x5BE0, 0x5BE7, 0x5BEE, 0x5BF5, 0x5BFB, + 0x5C02, 0x5C09, 0x5C10, 0x5C16, 0x5C1D, 0x5C24, + 0x5C2B, 0x5C32, 0x5C38, 0x5C3F, 0x5C46, 0x5C4D, + 0x5C54, 0x5C5A, 0x5C61, 0x5C68, 0x5C6F, 0x5C76, + 0x5C7C, 0x5C83, 0x5C8A, 0x5C91, 0x5C98, 0x5C9F, + 0x5CA5, 0x5CAC, 0x5CB3, 0x5CBA, 0x5497, 0x549E, + 0x54A4, 0x54AA, 0x54B0, 0x54B7, 0x54BD, 0x54C3, + 0x54C9, 0x54D0, 0x54D6, 0x54DC, 0x54E2, 0x54E9, + 0x54EF, 0x54F5, 0x54FB, 0x5502, 0x5508, 0x550E, + 0x5514, 0x551B, 0x5521, 0x5527, 0x552D, 0x5534, + 0x553A, 0x5540, 0x5547, 0x554D, 0x5553, 0x5559, + 0x5560, 0x5566, 0x556C, 0x5573, 0x5579, 0x557F, + 0x5585, 0x558C, 0x5592, 0x5598, 0x559F, 0x55A5, + 0x55AB, 0x55B2, 0x55B8, 0x55BE, 0x55C5, 0x55CB, + 0x55D1, 0x55D8, 0x55DE, 0x55E4, 0x55EB, 0x55F1, + 0x55F7, 0x55FE, 0x5604, 0x560A, 0x5611, 0x5617, + 0x561D, 0x5624, 0x562A, 0x5630, 0x5637, 0x563D, + 0x5643, 0x564A, 0x5650, 0x5656, 0x565D, 0x5663, + 0x566A, 0x5670, 0x5676, 0x567D, 0x5683, 0x5689, + 0x5690, 0x5696, 0x569D, 0x56A3, 0x56A9, 0x56B0, + 0x56B6, 0x56BC, 0x56C3, 0x56C9, 0x56D0, 0x56D6, + 0x56DC, 0x56E3, 0x56E9, 0x56F0, 0x56F6, 0x56FC, + 0x5703, 0x5709, 0x5710, 0x5716, 0x571D, 0x5723, + 0x5729, 0x5730, 0x5736, 0x573D, 0x5743, 0x574A, + 0x5750, 0x5756, 0x575D, 0x5763, 0x576A, 0x5770, + 0x5777, 0x577D, 0x5783, 0x578A, 0x5790, 0x5797, + 0x579D, 0x57A4, 0x57AA, 0x57B1, 0x57B7, 0x57BE, + 0x57C4, 0x57CB, 0x57D1, 0x57D7, 0x57DE, 0x57E4, + 0x57EB, 0x57F1, 0x57F8, 0x57FE, 0x5805, 0x580B, + 0x5812, 0x5818, 0x581F, 0x5825, 0x582C, 0x5832, + 0x5839, 0x583F, 0x5846, 0x584C, 0x5853, 0x5859, + 0x5860, 0x5866, 0x586D, 0x5873, 0x587A, 0x5880, + 0x5887, 0x588D, 0x50C9, 0x50CF, 0x50D5, 0x50DB, + 0x50E0, 0x50E6, 0x50EC, 0x50F2, 0x50F8, 0x50FE, + 0x5104, 0x510A, 0x5110, 0x5116, 0x511C, 0x5122, + 0x5128, 0x512E, 0x5134, 0x513A, 0x5140, 0x5146, + 0x514C, 0x5152, 0x5158, 0x515E, 0x5164, 0x516A, + 0x5170, 0x5176, 0x517C, 0x5182, 0x5188, 0x518E, + 0x5194, 0x519A, 0x51A0, 0x51A6, 0x51AC, 0x51B2, + 0x51B8, 0x51BE, 0x51C4, 0x51CA, 0x51D0, 0x51D6, + 0x51DC, 0x51E2, 0x51E8, 0x51EE, 0x51F4, 0x51FA, + 0x5201, 0x5207, 0x520D, 0x5213, 0x5219, 0x521F, + 0x5225, 0x522B, 0x5231, 0x5237, 0x523D, 0x5243, + 0x5249, 0x524F, 0x5255, 0x525B, 0x5261, 0x5267, + 0x526E, 0x5274, 0x527A, 0x5280, 0x5286, 0x528C, + 0x5292, 0x5298, 0x529E, 0x52A4, 0x52AA, 0x52B0, + 0x52B7, 0x52BD, 0x52C3, 0x52C9, 0x52CF, 0x52D5, + 0x52DB, 0x52E1, 0x52E7, 0x52ED, 0x52F4, 0x52FA, + 0x5300, 0x5306, 0x530C, 0x5312, 0x5318, 0x531E, + 0x5325, 0x532B, 0x5331, 0x5337, 0x533D, 0x5343, + 0x5349, 0x534F, 0x5356, 0x535C, 0x5362, 0x5368, + 0x536E, 0x5374, 0x537B, 0x5381, 0x5387, 0x538D, + 0x5393, 0x5399, 0x539F, 0x53A6, 0x53AC, 0x53B2, + 0x53B8, 0x53BE, 0x53C4, 0x53CB, 0x53D1, 0x53D7, + 0x53DD, 0x53E3, 0x53EA, 0x53F0, 0x53F6, 0x53FC, + 0x5402, 0x5408, 0x540F, 0x5415, 0x541B, 0x5421, + 0x5427, 0x542E, 0x5434, 0x543A, 0x5440, 0x5446, + 0x544D, 0x5453, 0x5459, 0x545F, 0x5466, 0x546C, + 0x5472, 0x5478, 0x547E, 0x5485, 0x548B, 0x5491 +}; diff --git a/dolphin sdk not yet linked/src/ax/AXOut.c b/dolphin sdk not yet linked/src/ax/AXOut.c new file mode 100644 index 0000000..e0649ba --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AXOut.c @@ -0,0 +1,238 @@ +#include +#include +#include + +#include "__ax.h" + +static s16 __AXOutBuffer[3][320]; +static s32 __AXOutSBuffer[160]; +static u16 __AXDramImage[8192]; +static DSPTaskInfo __AXDSPTask; +AXPROFILE __AXLocalProfile; + +volatile static u32 __AXOutFrame; +volatile static u32 __AXAiDmaFrame; +volatile static u32 __AXOutDspReady; +volatile static OSTime __AXOsTime; +static void (*__AXUserFrameCallback)(); +volatile static int __AXDSPInitFlag; +static int __AXDSPDoneFlag; + +static volatile u32 __AXDebugSteppingMode; +static OSThreadQueue __AXOutThreadQueue; +static u32 __AXOutputBufferMode; + +// prototypes +static void __AXDSPInitCallback(void* task); +static void __AXDSPResumeCallback(void* task); +static void __AXDSPDoneCallback(void* task); + +void __AXOutNewFrame(u32 lessDspCycles) { + u32 cl; + AXPROFILE* profile; + u8* src; + u8* dest; + u32 i; + + __AXLocalProfile.axFrameStart = OSGetTime(); + __AXSyncPBs(lessDspCycles); + __AXPrintStudio(); + cl = __AXGetCommandListAddress(); + + DSPSendMailToDSP(0xBABE0180); + do {} while (DSPCheckMailToDSP() != 0); + + DSPSendMailToDSP(cl); + do {} while (DSPCheckMailToDSP() != 0); + + __AXServiceCallbackStack(); + __AXLocalProfile.auxProcessingStart = OSGetTime(); + __AXProcessAux(); + __AXLocalProfile.auxProcessingEnd = OSGetTime(); + __AXLocalProfile.userCallbackStart = OSGetTime(); + + if (__AXUserFrameCallback) { + __AXUserFrameCallback(); + } + + __AXLocalProfile.userCallbackEnd = OSGetTime(); + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[__AXOutFrame][0]); + __AXOutFrame += 1; + + if (__AXOutputBufferMode == 1) { + __AXOutFrame %= 3; + } else { + __AXOutFrame &= 1; + AIInitDMA((u32)&__AXOutBuffer[__AXOutFrame][0], 0x280); + } + + __AXLocalProfile.axFrameEnd = OSGetTime(); + __AXLocalProfile.axNumVoices = __AXGetNumVoices(); + profile = (void*)__AXGetCurrentProfile(); + + if (profile) { + i = 56; + dest = (u8*)profile; + src = (u8*)&__AXLocalProfile; + + while (i != 0) { + *dest = *src; + dest++; + src++; + i--; + } + } +} + +void __AXOutAiCallback(void) { + if (__AXOutDspReady == 0) { + __AXOsTime = OSGetTime(); + } + + if (__AXOutDspReady == 1) { + __AXOutDspReady = 0; + __AXOutNewFrame(0); + } else { + __AXOutDspReady = 2; + DSPAssertTask(&__AXDSPTask); + } + + if (__AXOutputBufferMode == 1) { + AIInitDMA((u32)__AXOutBuffer[__AXAiDmaFrame], 0x280); + __AXAiDmaFrame++; + __AXAiDmaFrame %= 3; + } +} + +static void __AXDSPInitCallback(void* task) { + __AXDSPInitFlag = 1; +} + +void AXSetStepMode(u32 i) { + __AXDebugSteppingMode = i; +} + +static void __AXDSPResumeCallback(void* task) { +#if DEBUG + if (__AXDebugSteppingMode != 0) { + __AXOutDspReady = 1; + return; + } +#endif + + if (__AXOutDspReady == 2) { + __AXOutDspReady = 0; + __AXOutNewFrame((u32)(OSGetTime() - __AXOsTime) / 4); + return; + } + __AXOutDspReady = 1; +} + +static void __AXDSPDoneCallback(void* task) { + __AXDSPDoneFlag = 1; + OSWakeupThread(&__AXOutThreadQueue); +} + +#define BUFFER_MEMSET(buffer, size) \ + { \ + u32* p = (u32*)&buffer; \ + int i; \ + for (i = 0; i < size; i++) { \ + *p = 0; \ + p++; \ + } \ + } + +void __AXOutInitDSP(void) { + __AXDSPTask.iram_mmem_addr = axDspSlave; + __AXDSPTask.iram_length = axDspSlaveLength; + __AXDSPTask.iram_addr = 0; + __AXDSPTask.dram_mmem_addr = __AXDramImage; + __AXDSPTask.dram_length = 0x2000; + __AXDSPTask.dram_addr = 0; + __AXDSPTask.dsp_init_vector = 0x10; + __AXDSPTask.dsp_resume_vector = 0x30; + __AXDSPTask.init_cb = __AXDSPInitCallback; + __AXDSPTask.res_cb = __AXDSPResumeCallback; + __AXDSPTask.done_cb = __AXDSPDoneCallback; + __AXDSPTask.req_cb = NULL; + __AXDSPTask.priority = 0; + __AXDSPInitFlag = 0; + __AXDSPDoneFlag = 0; + + OSInitThreadQueue(&__AXOutThreadQueue); + if (DSPCheckInit() == 0) { + DSPInit(); + } + + DSPAddTask(&__AXDSPTask); + do {} while (__AXDSPInitFlag == 0); +} + +void __AXOutInit(u32 outputBufferMode) { +#ifdef DEBUG + OSReport("Initializing AXOut code module\n"); +#endif + ASSERTLINE(404, ((u32)&__AXOutBuffer[0][0] & 0x1F) == 0); + ASSERTLINE(405, ((u32)&__AXOutBuffer[1][0] & 0x1F) == 0); + ASSERTLINE(406, ((u32)&__AXOutBuffer[2][0] & 0x1F) == 0); + ASSERTLINE(407, ((u32)&__AXOutSBuffer[0] & 0x1F) == 0); + + __AXOutputBufferMode = outputBufferMode; + __AXOutFrame = 0; + __AXAiDmaFrame = 0; + __AXDebugSteppingMode = 0; + + BUFFER_MEMSET(__AXOutBuffer, 0x1E0); + DCFlushRange(__AXOutBuffer, sizeof(__AXOutBuffer)); + + BUFFER_MEMSET(__AXOutSBuffer, 0xA0); + DCFlushRange(__AXOutSBuffer, sizeof(__AXOutSBuffer)); + + __AXOutInitDSP(); + AIRegisterDMACallback(__AXOutAiCallback); + + if (__AXOutputBufferMode == 1) { + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[2][0]); + } else { + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[1][0]); + } + + __AXOutDspReady = 1; + __AXUserFrameCallback = NULL; + + if (__AXOutputBufferMode == 1) { + AIInitDMA((u32)&__AXOutBuffer[__AXAiDmaFrame][0], sizeof(__AXOutBuffer[0])); + __AXAiDmaFrame++; + __AXAiDmaFrame &= 1; + } else { + AIInitDMA((u32)&__AXOutBuffer[__AXOutFrame][0], sizeof(__AXOutBuffer[0])); + } + + AIStartDMA(); +} + +void __AXOutQuit(void) { + BOOL old; +#ifdef DEBUG + OSReport("Shutting down AXOut code module\n"); +#endif + old = OSDisableInterrupts(); + __AXUserFrameCallback = NULL; + DSPCancelTask(&__AXDSPTask); + OSSleepThread(&__AXOutThreadQueue); + AIStopDMA(); + OSRestoreInterrupts(old); +} + +AXCallback AXRegisterCallback(AXCallback callback) { + BOOL enabled; + AXCallback oldCB; + + oldCB = __AXUserFrameCallback; + enabled = OSDisableInterrupts(); + __AXUserFrameCallback = callback; + + OSRestoreInterrupts(enabled); + return oldCB; +} diff --git a/dolphin sdk not yet linked/src/ax/AXProf.c b/dolphin sdk not yet linked/src/ax/AXProf.c new file mode 100644 index 0000000..316cadf --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AXProf.c @@ -0,0 +1,47 @@ +#include +#include + +#include "__ax.h" + +static AXPROFILE* __AXProfile; +static u32 __AXMaxProfiles; +static u32 __AXCurrentProfile; +static u32 __AXProfileInitialized; + +AXPROFILE* __AXGetCurrentProfile(void) { + AXPROFILE* profile; + + if (__AXProfileInitialized != 0) { + profile = &__AXProfile[__AXCurrentProfile]; + __AXCurrentProfile += 1; + __AXCurrentProfile %= __AXMaxProfiles; + return profile; + } + + return 0; +} + +void AXInitProfile(AXPROFILE* profile, u32 maxProfiles) { + ASSERTLINE(60, profile); + ASSERTLINE(61, maxProfiles); + + __AXProfile = profile; + __AXMaxProfiles = maxProfiles; + __AXCurrentProfile = 0; + __AXProfileInitialized = 1; +} + +u32 AXGetProfile(void) { + BOOL old; + u32 n; + + old = OSDisableInterrupts(); + n = __AXCurrentProfile; + if (n != 0) { + n -= 1; + } + + __AXCurrentProfile = 0; + OSRestoreInterrupts(old); + return n; +} diff --git a/dolphin sdk not yet linked/src/ax/AXSPB.c b/dolphin sdk not yet linked/src/ax/AXSPB.c new file mode 100644 index 0000000..3ff765d --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/AXSPB.c @@ -0,0 +1,91 @@ +#include +#include + +#include "__ax.h" + +static AXSPB __AXStudio ATTRIBUTE_ALIGN(32); + +static s32 __AXSpbAL; +static s32 __AXSpbAR; +static s32 __AXSpbAS; +static s32 __AXSpbAAL; +static s32 __AXSpbAAR; +static s32 __AXSpbAAS; +static s32 __AXSpbABL; +static s32 __AXSpbABR; +static s32 __AXSpbABS; + +u32 __AXGetStudio(void) { + return (u32)&__AXStudio; +} + +void __AXDepopFade(s32* hostSum, s32* dspVolume, s16* dspDelta) { + int frames; + s32 delta; + + frames = *hostSum / 160; + + if (frames) { + delta = *hostSum / 160; + if (delta > 0x14) { + delta = 0x14; + } + if (delta < -0x14) { + delta = -0x14; + } + *dspVolume = *hostSum; + *hostSum -= delta* 0xA0; + *dspDelta = delta * -1; + return; + } + + *hostSum = 0; + *dspVolume = 0; + *dspDelta = 0; +} + +void __AXPrintStudio(void) { + __AXDepopFade(&__AXSpbAL, (void*)&__AXStudio.dpopLHi, &__AXStudio.dpopLDelta); + __AXDepopFade(&__AXSpbAR, (void*)&__AXStudio.dpopRHi, &__AXStudio.dpopRDelta); + __AXDepopFade(&__AXSpbAS, (void*)&__AXStudio.dpopSHi, &__AXStudio.dpopSDelta); + __AXDepopFade(&__AXSpbAAL, (void*)&__AXStudio.dpopALHi, &__AXStudio.dpopALDelta); + __AXDepopFade(&__AXSpbAAR, (void*)&__AXStudio.dpopARHi, &__AXStudio.dpopARDelta); + __AXDepopFade(&__AXSpbAAS, (void*)&__AXStudio.dpopASHi, &__AXStudio.dpopASDelta); + __AXDepopFade(&__AXSpbABL, (void*)&__AXStudio.dpopBLHi, &__AXStudio.dpopBLDelta); + __AXDepopFade(&__AXSpbABR, (void*)&__AXStudio.dpopBRHi, &__AXStudio.dpopBRDelta); + __AXDepopFade(&__AXSpbABS, (void*)&__AXStudio.dpopBSHi, &__AXStudio.dpopBSDelta); + DCFlushRange(&__AXStudio, sizeof(__AXStudio)); +} + +void __AXSPBInit(void) { +#ifdef DEBUG + OSReport("Initializing AXSPB code module\n"); +#endif + __AXSpbAL = + __AXSpbAR = + __AXSpbAS = + __AXSpbAAL = + __AXSpbAAR = + __AXSpbAAS = + __AXSpbABL = + __AXSpbABR = + __AXSpbABS = 0; +} + +void __AXSPBQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXSPB code module\n"); +#endif +} + +void __AXDepopVoice(AXPB* p) { + __AXSpbAL += p->dpop.aL; + __AXSpbAAL += p->dpop.aAuxAL; + __AXSpbABL += p->dpop.aAuxBL; + __AXSpbAR += p->dpop.aR; + __AXSpbAAR += p->dpop.aAuxAR; + __AXSpbABR += p->dpop.aAuxBR; + __AXSpbAS += p->dpop.aS; + __AXSpbAAS += p->dpop.aAuxAS; + __AXSpbABS += p->dpop.aAuxBS; +} diff --git a/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/dolphin sdk not yet linked/src/ax/DSPCode.c b/dolphin sdk not yet linked/src/ax/DSPCode.c new file mode 100644 index 0000000..d54b0de --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/DSPCode.c @@ -0,0 +1,669 @@ +#include +#include + +u16 axDspSlaveLength = (AX_DSP_SLAVE_LENGTH * 2); + +u16 axDspSlave[AX_DSP_SLAVE_LENGTH] ATTRIBUTE_ALIGN(32) = { + 0x0000, 0x0000, 0x029F, 0x0E88, 0x029F, 0x0E97, + 0x029F, 0x0EB3, 0x029F, 0x0ED3, 0x029F, 0x0ED9, + 0x029F, 0x0F0B, 0x029F, 0x0F11, 0x1302, 0x1303, + 0x1204, 0x1305, 0x1306, 0x8E00, 0x8C00, 0x8B00, + 0x0092, 0x00FF, 0x8100, 0x8900, 0x009E, 0x0E80, + 0x00FE, 0x0E1B, 0x8100, 0x00FE, 0x0E31, 0x16FC, + 0xDCD1, 0x16FD, 0x0000, 0x16FB, 0x0001, 0x26FC, + 0x02A0, 0x8000, 0x029C, 0x0029, 0x029F, 0x0045, + 0x1302, 0x1303, 0x1204, 0x1305, 0x1306, 0x8E00, + 0x8C00, 0x8B00, 0x0092, 0x00FF, 0x16FC, 0xDCD1, + 0x16FD, 0x0001, 0x16FB, 0x0001, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x0040, 0x8E00, 0x8100, 0x8900, + 0x009F, 0xBABE, 0x26FE, 0x02C0, 0x8000, 0x029C, + 0x004A, 0x8200, 0x0294, 0x004A, 0x23FF, 0x8100, + 0x26FE, 0x02C0, 0x8000, 0x029C, 0x0054, 0x27FF, + 0x0240, 0x7FFF, 0x2ECE, 0x2FCF, 0x16CD, 0x0C00, + 0x8100, 0x2EC9, 0x1FFB, 0x2FCB, 0x02BF, 0x0652, + 0x0080, 0x0C00, 0x8E00, 0x8100, 0x8970, 0xB100, + 0x0291, 0x007E, 0x0A13, 0xC100, 0x0292, 0x007E, + 0x009F, 0x0C9D, 0x4C00, 0x1C7E, 0x0213, 0x1C7E, + 0x176F, 0x16FC, 0xFBAD, 0x16FD, 0x8080, 0x0021, + 0x16FC, 0xBAAD, 0x2EFD, 0x0021, 0x8D00, 0x8F00, + 0x8A00, 0x8900, 0x8168, 0x0098, 0x0000, 0x0099, + 0x0001, 0x0081, 0x0000, 0x193E, 0x193C, 0x11A0, + 0x009A, 0xA100, 0x8271, 0x0277, 0x1F19, 0x193C, + 0xA100, 0x8271, 0x0277, 0x1F19, 0x193C, 0x1FD8, + 0xB100, 0x0294, 0x00CB, 0x00DE, 0x0E44, 0xB100, + 0x0294, 0x00AB, 0x191C, 0x191C, 0x191C, 0x00E0, + 0x0E45, 0x029F, 0x0114, 0x8B00, 0x7A00, 0x00FE, + 0x0E44, 0x8400, 0x0099, 0x0140, 0x1F1E, 0xA000, + 0x191E, 0x191E, 0x191C, 0x00E0, 0x0E45, 0x009A, + 0x0000, 0x0098, 0x0DC0, 0x4E00, 0x4800, 0x2ECE, + 0x2CCF, 0x009E, 0x0E48, 0x2ECD, 0x0E00, 0x2EC9, + 0x009E, 0x0140, 0x2ECB, 0x029F, 0x00E3, 0x8B00, + 0x00D8, 0x0E44, 0x0099, 0x0140, 0xA000, 0x191E, + 0x00FE, 0x0E44, 0x191E, 0x191C, 0x00E0, 0x0E45, + 0x4E00, 0x2ECE, 0x2CCF, 0x009E, 0x0E48, 0x2ECD, + 0x0E00, 0x2EC9, 0x009E, 0x0140, 0x2ECB, 0x02BF, + 0x0652, 0x8A48, 0x0083, 0x0E48, 0x0080, 0x0000, + 0x0081, 0x0000, 0x1979, 0x193A, 0xB041, 0xA64B, + 0xF051, 0xB441, 0x9100, 0x1150, 0x00FC, 0xA792, + 0xF151, 0xB520, 0x9941, 0xA693, 0xF051, 0xB428, + 0x9141, 0x0083, 0x0E48, 0x0080, 0x0140, 0x0081, + 0x0140, 0x1979, 0x193A, 0xB041, 0xA64B, 0xF051, + 0xB441, 0x9100, 0x1150, 0x0113, 0xA792, 0xF151, + 0xB520, 0x9941, 0xA693, 0xF051, 0xB428, 0x9141, + 0x00C0, 0x0E45, 0x029F, 0x0068, 0x8100, 0x8970, + 0x8E78, 0x2ECE, 0x2FCF, 0x009E, 0x0E48, 0x2ECD, + 0x0E00, 0x2EC9, 0x009E, 0x0040, 0x2ECB, 0x0081, + 0x0E48, 0x0082, 0x0000, 0x009B, 0x009F, 0x009A, + 0x0140, 0x8100, 0x8900, 0x8F00, 0x02BF, 0x0652, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x013C, + 0x005A, 0x1B5E, 0x029F, 0x0144, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0143, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x014E, + 0x005A, 0x1B5E, 0x029F, 0x0156, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0155, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x0160, + 0x005A, 0x1B5E, 0x029F, 0x0168, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0167, 0x4C00, 0x1B5E, 0x1B5C, + 0x0082, 0x0400, 0x193E, 0x193C, 0xB179, 0x0294, + 0x0173, 0x005A, 0x1B5E, 0x029F, 0x017B, 0x9900, + 0x1B5E, 0x1B5C, 0x007B, 0x017A, 0x4C00, 0x1B5E, + 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x0184, + 0x005A, 0x1B5E, 0x029F, 0x018C, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x018B, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB179, 0x0294, 0x0195, 0x005A, + 0x1B5E, 0x029F, 0x019D, 0x9900, 0x1B5E, 0x1B5C, + 0x007B, 0x019C, 0x4C00, 0x1B5E, 0x1B5C, 0x0082, + 0x07C0, 0x193E, 0x193C, 0xB179, 0x0294, 0x01A8, + 0x005A, 0x1B5E, 0x029F, 0x01B0, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x01AF, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB179, 0x0294, 0x01B9, 0x005A, + 0x1B5E, 0x029F, 0x01C1, 0x9900, 0x1B5E, 0x1B5C, + 0x007B, 0x01C0, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, + 0x193C, 0xB179, 0x0294, 0x01CA, 0x005A, 0x1B5E, + 0x029F, 0x01D2, 0x9900, 0x1B5E, 0x1B5C, 0x007B, + 0x01D1, 0x4C00, 0x1B5E, 0x1B5C, 0x029F, 0x0068, + 0x0085, 0xFFFF, 0x8150, 0x8940, 0x8E48, 0x00FA, + 0x0E17, 0x00F8, 0x0E18, 0x0081, 0x0000, 0x02BF, + 0x05E7, 0x00DA, 0x0E17, 0x00D8, 0x0E18, 0x8948, + 0x0081, 0x0400, 0x02BF, 0x05E7, 0x00DA, 0x0E17, + 0x00D8, 0x0E18, 0x8948, 0x0081, 0x07C0, 0x02BF, + 0x05E7, 0x029F, 0x0068, 0x0086, 0x07C0, 0x02BF, + 0x057A, 0x029F, 0x0068, 0x8100, 0x8E00, 0x191E, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0000, 0x16C9, + 0x0001, 0x16CB, 0x0780, 0x02BF, 0x0652, 0x029F, + 0x0068, 0x8100, 0x8970, 0x8E60, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x8900, 0x0D20, + 0x2DCB, 0x4C00, 0x1C80, 0x0080, 0x0280, 0x0081, + 0x0000, 0x0082, 0x0140, 0x0083, 0x0E48, 0x0A00, + 0x27C9, 0x03A0, 0x0004, 0x029C, 0x0222, 0x2ECE, + 0x2CCF, 0x16CD, 0x0E58, 0x16C9, 0x0000, 0x16CB, + 0x0260, 0x009F, 0x00A0, 0x8F00, 0x007F, 0x023B, + 0x197E, 0x1B1A, 0x197C, 0x1B1A, 0x1B5E, 0x7C22, + 0x1B3E, 0x1B3C, 0x1C04, 0x029F, 0x0068, 0x8E70, + 0x8960, 0x191F, 0x2ECE, 0x2CCF, 0x16CD, 0x0C00, + 0x16C9, 0x0000, 0x0503, 0x0340, 0xFFF0, 0x2FCB, + 0x02BF, 0x0652, 0x0080, 0x0C00, 0x029F, 0x0068, + 0x8100, 0x8970, 0x8E78, 0x2ECE, 0x2FCF, 0x16CD, + 0x0B80, 0x16C9, 0x0000, 0x16CB, 0x00C4, 0x0082, + 0x0E08, 0x009F, 0x0000, 0x1B5F, 0x009F, 0x0140, + 0x1B5F, 0x009F, 0x0280, 0x1B5F, 0x009F, 0x0400, + 0x1B5F, 0x009F, 0x0540, 0x1B5F, 0x009F, 0x0680, + 0x1B5F, 0x009F, 0x07C0, 0x1B5F, 0x009F, 0x0900, + 0x1B5F, 0x009F, 0x0A40, 0x1B5F, 0x02BF, 0x0652, + 0x00DE, 0x0BA7, 0x00DF, 0x0BA8, 0x2ECE, 0x2FCF, + 0x16CD, 0x03C0, 0x16C9, 0x0000, 0x16CB, 0x0080, + 0x8100, 0x8900, 0x00DE, 0x0B84, 0x009F, 0x0D21, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E15, 0x00DE, + 0x0B85, 0x009F, 0x0D24, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E16, 0x00DE, 0x0B86, 0x009A, 0x000F, + 0x009F, 0x0CB1, 0x3400, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E14, 0x00DE, 0x0B86, 0x009A, 0x001F, + 0x009F, 0x0CC1, 0x14FC, 0x3400, 0x4C00, 0x1C7E, + 0x0213, 0x00FE, 0x0E46, 0x00DE, 0x0B86, 0x009F, + 0x0CE1, 0x14F7, 0x4C00, 0x1C7E, 0x0213, 0x00FE, + 0x0E47, 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, + 0x02EA, 0x8900, 0x00DF, 0x0B9E, 0x0300, 0x0CC0, + 0x00FF, 0x0E40, 0x00DF, 0x0B9F, 0x0300, 0x0CC0, + 0x00FF, 0x0E41, 0x009F, 0x0CE0, 0x00FF, 0x0E42, + 0x00FF, 0x0E43, 0x02BF, 0x0652, 0x00DE, 0x0B9C, + 0x2ECE, 0x00DE, 0x0B9D, 0x2ECF, 0x16CD, 0x0CC0, + 0x16C9, 0x0000, 0x16CB, 0x0040, 0x02BF, 0x0652, + 0x029F, 0x0068, 0x009F, 0x0CE0, 0x00FF, 0x0E42, + 0x00FF, 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, + 0x02BF, 0x0652, 0x029F, 0x0068, 0x8E00, 0x00E0, + 0x0E07, 0x0080, 0x0BA2, 0x0081, 0x03C0, 0x0E05, + 0x00FE, 0x0E04, 0x8900, 0x8150, 0x009F, 0x0B80, + 0x007A, 0x030B, 0x193E, 0x4C49, 0x1C5E, 0x1A59, + 0x0083, 0x0E05, 0x1B61, 0x1B60, 0x00DE, 0x0B87, + 0x0601, 0x0295, 0x0317, 0x029F, 0x040E, 0x00DE, + 0x0E42, 0x00FE, 0x0E1C, 0x00C3, 0x0E15, 0x177F, + 0x8E00, 0x8A00, 0x8100, 0x8900, 0x00DE, 0x0BB3, + 0x00DF, 0x0BB2, 0x1F1F, 0x4D00, 0x1481, 0x8D1E, + 0x1FD8, 0x0098, 0x8000, 0x0080, 0x0E48, 0xA830, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0x00FE, 0x0BB2, 0x8F00, 0x0080, 0x0E48, + 0x00C1, 0x0E43, 0x1C61, 0x193A, 0x1918, 0x9059, + 0x1919, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E00, 0x6F33, 0x1B7F, 0x8100, 0x00DE, + 0x0BDD, 0xB100, 0x0295, 0x03C0, 0x8D00, 0x8F00, + 0x8A00, 0x00C0, 0x0E43, 0x00C1, 0x0E43, 0x0083, + 0x0BDF, 0x0087, 0xFFFF, 0x00DE, 0x0BDE, 0x80E1, + 0xB04F, 0x1F5E, 0xE2E1, 0xB64F, 0x1F5E, 0xE2E1, + 0x110F, 0x03BB, 0xB79A, 0x1F5F, 0xE2E1, 0xB69B, + 0x1F5E, 0xE2E1, 0xB79A, 0x1B1F, 0x00FF, 0x0BDE, + 0x00C3, 0x0E14, 0x8A00, 0x177F, 0x00C3, 0x0E46, + 0x8A00, 0x177F, 0x00C3, 0x0E47, 0x8A00, 0x177F, + 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x0406, + 0x00DE, 0x0E42, 0x00FE, 0x0E43, 0x8100, 0x8900, + 0x00DE, 0x0B9E, 0x00DF, 0x0BA0, 0x8200, 0x0293, + 0x03E2, 0x7800, 0x029F, 0x03E5, 0x0295, 0x03E5, + 0x7400, 0x00FE, 0x0B9E, 0x00DF, 0x0E43, 0x05E0, + 0x4C00, 0x00FE, 0x0E40, 0x8100, 0x8900, 0x00DE, + 0x0B9F, 0x00DF, 0x0BA1, 0x8200, 0x0293, 0x03F9, + 0x7800, 0x029F, 0x03FC, 0x0295, 0x03FC, 0x7400, + 0x00FE, 0x0B9F, 0x00DF, 0x0E43, 0x05E0, 0x4C00, + 0x00FE, 0x0E41, 0x029F, 0x040E, 0x00DE, 0x0E42, + 0x00FE, 0x0E40, 0x00FE, 0x0E41, 0x00FE, 0x0E43, + 0x8100, 0x8E00, 0x8400, 0x8900, 0x1EFE, 0x0E40, + 0x1EBE, 0x0083, 0x0E08, 0x1C03, 0x1FF5, 0x191A, + 0xF858, 0xFBA0, 0xF8B1, 0xFBA0, 0xF8B1, 0xFBA0, + 0xF8B1, 0xFBA0, 0xF83B, 0x1B7E, 0x0083, 0x0E04, + 0x8100, 0x8973, 0x1961, 0x1960, 0x7800, 0x00FE, + 0x0E04, 0x0294, 0x0303, 0x8E00, 0x8100, 0x00DE, + 0x0B9B, 0xB100, 0x0295, 0x0446, 0x00DE, 0x0B9C, + 0x00DC, 0x0B9D, 0x2ECE, 0x2CCF, 0x8100, 0x00DE, + 0x0E1C, 0x2ECD, 0x16C9, 0x0001, 0x16CB, 0x0040, + 0x02BF, 0x0652, 0x8100, 0x8900, 0x00DE, 0x0B82, + 0x00DF, 0x0B83, 0x2ECE, 0x2FCF, 0x16CD, 0x0B80, + 0x16C9, 0x0001, 0x16CB, 0x00C4, 0x02BF, 0x0652, + 0x8100, 0x00DE, 0x0B80, 0x00DC, 0x0B81, 0xB100, + 0x0294, 0x0462, 0x00C0, 0x0E07, 0x029F, 0x0068, + 0x2ECE, 0x2CCF, 0x16CD, 0x0B80, 0x16C9, 0x0000, + 0x16CB, 0x00C4, 0x0082, 0x0E08, 0x009F, 0x0000, + 0x1B5F, 0x009F, 0x0140, 0x1B5F, 0x009F, 0x0280, + 0x1B5F, 0x009F, 0x0400, 0x1B5F, 0x009F, 0x0540, + 0x1B5F, 0x009F, 0x0680, 0x1B5F, 0x009F, 0x07C0, + 0x1B5F, 0x009F, 0x0900, 0x1B5F, 0x009F, 0x0A40, + 0x1B5F, 0x02BF, 0x0652, 0x00DE, 0x0BA7, 0x00DF, + 0x0BA8, 0x2ECE, 0x2FCF, 0x16CD, 0x03C0, 0x16C9, + 0x0000, 0x16CB, 0x0080, 0x8100, 0x8900, 0x00DE, + 0x0B84, 0x009F, 0x0D21, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E15, 0x00DE, 0x0B85, 0x009F, 0x0D24, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E16, 0x00DE, + 0x0B86, 0x009A, 0x000F, 0x009F, 0x0CB1, 0x3400, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E14, 0x00DE, + 0x0B86, 0x009A, 0x001F, 0x009F, 0x0CC1, 0x14FC, + 0x3400, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E46, + 0x00DE, 0x0B86, 0x009F, 0x0CE1, 0x14F7, 0x4C00, + 0x1C7E, 0x0213, 0x00FE, 0x0E47, 0x8100, 0x00DE, + 0x0B9B, 0xB100, 0x0295, 0x04F9, 0x8900, 0x00DF, + 0x0B9E, 0x0300, 0x0CC0, 0x00FF, 0x0E40, 0x00DF, + 0x0B9F, 0x0300, 0x0CC0, 0x00FF, 0x0E41, 0x009F, + 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E43, 0x02BF, + 0x0652, 0x00DE, 0x0B9C, 0x2ECE, 0x00DE, 0x0B9D, + 0x2ECF, 0x16CD, 0x0CC0, 0x16C9, 0x0000, 0x16CB, + 0x0040, 0x02BF, 0x0652, 0x00C0, 0x0E07, 0x029F, + 0x02F8, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, + 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, 0x02BF, + 0x0652, 0x00C0, 0x0E07, 0x029F, 0x02F8, 0x8E00, + 0x0086, 0x0400, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x1FC6, 0x2ECD, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x0652, 0x02BF, 0x057A, 0x029F, + 0x0068, 0x8E00, 0x0086, 0x07C0, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x1FC6, 0x2ECD, 0x16C9, + 0x0001, 0x16CB, 0x0780, 0x02BF, 0x0652, 0x02BF, + 0x057A, 0x029F, 0x0068, 0x8C00, 0x8A00, 0x8100, + 0x8970, 0x191F, 0x2ECE, 0x2FCF, 0x16CD, 0x0280, + 0x16C9, 0x0001, 0x16CB, 0x0280, 0x8F50, 0x8140, + 0x0081, 0x0400, 0x0083, 0x0000, 0x0082, 0x0140, + 0x0099, 0x0080, 0x02BF, 0x0652, 0x1105, 0x0562, + 0x1F61, 0x1120, 0x0554, 0x8972, 0x195C, 0xF07B, + 0x197D, 0xF131, 0x8139, 0x8900, 0x6800, 0x2ECE, + 0x2CCF, 0x1FFB, 0x2FCD, 0x0F01, 0x2FC9, 0x1FF9, + 0x2FCB, 0x7200, 0x1F5E, 0x1F1C, 0x8100, 0x26C9, + 0x02A0, 0x0004, 0x029C, 0x0563, 0x029F, 0x0068, + 0x029F, 0x0068, 0x029F, 0x0068, 0x029F, 0x0068, + 0x16FC, 0xDCD1, 0x16FD, 0x0002, 0x16FB, 0x0001, + 0x029F, 0x0F1A, 0x029F, 0x0045, 0x8E00, 0x191F, + 0x191D, 0x1F5F, 0x1F1D, 0x2FCE, 0x2DCF, 0x8900, + 0x1FA6, 0x2DCD, 0x0E00, 0x2EC9, 0x8100, 0x009C, + 0x00C0, 0x2CCB, 0x1CA0, 0x0081, 0x0E48, 0x4800, + 0x1B3E, 0x1B3C, 0x0B00, 0x0099, 0x0060, 0x4B00, + 0x1B3D, 0x0081, 0x0E48, 0x1C06, 0x0083, 0x0000, + 0x1C43, 0x27C9, 0x03A0, 0x0004, 0x029C, 0x059B, + 0x1109, 0x05D0, 0x8E00, 0x193A, 0x1938, 0x6900, + 0x2FCE, 0x2DCF, 0x8900, 0x193D, 0x2DCD, 0x16C9, + 0x0000, 0x8100, 0x009C, 0x00C0, 0x2CCB, 0x0081, + 0x0E48, 0x4800, 0x1B3E, 0x1B3C, 0x0B00, 0x0960, + 0x4B00, 0x1B3D, 0x0081, 0x0E48, 0x8F00, 0x80F0, + 0x80C0, 0x6A00, 0x4800, 0x1117, 0x05CA, 0x80F0, + 0x80C0, 0x6B32, 0x4922, 0x80F0, 0x80C0, 0x6A3A, + 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, + 0x1B5D, 0x80F0, 0x80C0, 0x6A00, 0x4800, 0x1117, + 0x05DE, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x80F0, + 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, + 0x4922, 0x1B5F, 0x1B5D, 0x1C05, 0x02DF, 0x8E00, + 0x009B, 0x0E48, 0x009D, 0x00C0, 0x02BF, 0x0637, + 0x4900, 0x00FF, 0x0E1D, 0x00FD, 0x0E1E, 0x8900, + 0x02BF, 0x0652, 0x1104, 0x0622, 0x00DA, 0x0E1D, + 0x00D8, 0x0E1E, 0x009B, 0x0EA8, 0x009D, 0x00C0, + 0x02BF, 0x0637, 0x4900, 0x00FF, 0x0E1D, 0x00FD, + 0x0E1E, 0x0083, 0x0E48, 0x02BF, 0x0642, 0x8900, + 0x00DA, 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0E48, + 0x009D, 0x00C0, 0x02BF, 0x0637, 0x4900, 0x00FF, + 0x0E1D, 0x00FD, 0x0E1E, 0x0083, 0x0EA8, 0x02BF, + 0x0642, 0x0000, 0x0000, 0x8E00, 0x8900, 0x00DA, + 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0EA8, 0x009D, + 0x00C0, 0x02BF, 0x0637, 0x4900, 0x0083, 0x0E48, + 0x02BF, 0x0642, 0x0083, 0x0EA8, 0x02BF, 0x0642, + 0x02DF, 0x8E00, 0x00FA, 0xFFCE, 0x00F8, 0xFFCF, + 0x00FB, 0xFFCD, 0x16C9, 0x0000, 0x2DCB, 0x02DF, + 0x8F00, 0x8D00, 0x8A00, 0x197A, 0x1978, 0xA000, + 0xB600, 0x1130, 0x0650, 0x9179, 0x4E6D, 0x197A, + 0x4D43, 0xA039, 0xB629, 0x02DF, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0652, 0x02DF, 0x26FE, 0x02C0, + 0x8000, 0x029C, 0x0658, 0x02DF, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x065E, 0x02DF, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x0664, 0x02DF, 0x8100, 0x8970, + 0x8E60, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x8900, 0x0D20, 0x2DCB, 0x4C00, 0x1C80, + 0x0080, 0x0280, 0x0081, 0x0000, 0x0082, 0x0140, + 0x0083, 0x0E48, 0x0A00, 0x27C9, 0x03A0, 0x0004, + 0x029C, 0x0681, 0x2ECE, 0x2CCF, 0x16CD, 0x0E58, + 0x16C9, 0x0000, 0x16CB, 0x0260, 0x009F, 0x00A0, + 0x8F00, 0x007F, 0x069A, 0x197E, 0x1B1A, 0x197C, + 0x1B1A, 0x1B5E, 0x1B5C, 0x1B3E, 0x1B3C, 0x1C04, + 0x029F, 0x0068, 0x0082, 0x0BB8, 0x195E, 0x2ED1, + 0x195E, 0x2ED4, 0x195E, 0x2ED5, 0x195E, 0x2ED6, + 0x195E, 0x2ED7, 0x195E, 0x2ED8, 0x195E, 0x2ED9, + 0x195E, 0x2EA0, 0x195E, 0x2EA1, 0x195E, 0x2EA2, + 0x195E, 0x2EA3, 0x195E, 0x2EA4, 0x195E, 0x2EA5, + 0x195E, 0x2EA6, 0x195E, 0x2EA7, 0x195E, 0x2EA8, + 0x195E, 0x2EA9, 0x195E, 0x2EAA, 0x195E, 0x2EAB, + 0x195E, 0x2EAC, 0x195E, 0x2EAD, 0x195E, 0x2EAE, + 0x195E, 0x2EAF, 0x195E, 0x2EDE, 0x195E, 0x2EDA, + 0x195E, 0x2EDB, 0x195E, 0x2EDC, 0x8C00, 0x8A00, + 0x8E00, 0x00D8, 0x0E16, 0x195B, 0x1959, 0x8100, + 0x195C, 0x0080, 0x0E48, 0x195F, 0x1B1F, 0x195F, + 0x1B1F, 0x195F, 0x1B1F, 0x185F, 0x1B1F, 0x6B00, + 0x1505, 0x4D00, 0x157E, 0x1C9F, 0x1CBD, 0x05E0, + 0x9900, 0x7D00, 0x1CDD, 0x8900, 0x1FA5, 0x1502, + 0x1CBF, 0x009A, 0x01FC, 0x009E, 0x0E48, 0x0081, + 0xFFDD, 0x0083, 0x0D80, 0x0064, 0x0710, 0x1827, + 0x1B07, 0x4A00, 0x1FFC, 0x1827, 0x1B07, 0x1579, + 0x3500, 0x1827, 0x1B07, 0x4100, 0x1B7E, 0x1827, + 0x1B07, 0x1B7F, 0x0000, 0x0065, 0x0716, 0x1827, + 0x1B07, 0x0000, 0x0000, 0x0007, 0x187F, 0x0066, + 0x071F, 0x4A3B, 0x1FFC, 0x1579, 0x3533, 0x4100, + 0x1B7F, 0x0004, 0x189F, 0x1ADF, 0x189F, 0x1ADF, + 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x1ADC, 0x0082, + 0x0BD2, 0x27DC, 0x1ADF, 0x27DB, 0x1ADF, 0x27DA, + 0x1ADF, 0x0082, 0x0BBE, 0x27D9, 0x1ADF, 0x27D8, + 0x1ADF, 0x8F00, 0x00C1, 0x0E42, 0x0082, 0x0D80, + 0x1940, 0x1943, 0x80F0, 0xB8C0, 0x111F, 0x074A, + 0xA6F0, 0xBCF0, 0x1940, 0x1943, 0xBCF0, 0x4EC0, + 0xB831, 0xA6F0, 0xBCF0, 0xBC00, 0x4E00, 0x1B3E, + 0x00E1, 0x0E42, 0x02DF, 0x0082, 0x0BB8, 0x195E, + 0x2ED1, 0x195E, 0x2ED4, 0x195E, 0x2ED5, 0x195E, + 0x2ED6, 0x195E, 0x2ED7, 0x195E, 0x2ED8, 0x195E, + 0x2ED9, 0x195E, 0x2EA0, 0x195E, 0x2EA1, 0x195E, + 0x2EA2, 0x195E, 0x2EA3, 0x195E, 0x2EA4, 0x195E, + 0x2EA5, 0x195E, 0x2EA6, 0x195E, 0x2EA7, 0x195E, + 0x2EA8, 0x195E, 0x2EA9, 0x195E, 0x2EAA, 0x195E, + 0x2EAB, 0x195E, 0x2EAC, 0x195E, 0x2EAD, 0x195E, + 0x2EAE, 0x195E, 0x2EAF, 0x195E, 0x2EDE, 0x195E, + 0x2EDA, 0x195E, 0x2EDB, 0x195E, 0x2EDC, 0x8C00, + 0x8A00, 0x8F00, 0x195B, 0x1959, 0x1958, 0x0080, + 0x0E48, 0x195F, 0x1B1F, 0x195F, 0x1B1F, 0x195F, + 0x1B1F, 0x185F, 0x1B1F, 0x6B00, 0x1505, 0x7100, + 0x157E, 0x03A0, 0xFFFF, 0x029C, 0x07AB, 0x0085, + 0x0000, 0x1502, 0x1C9F, 0x0086, 0x0020, 0x029F, + 0x07B7, 0x7900, 0x1CBF, 0x1C9D, 0x05E0, 0x9900, + 0x7D00, 0x1CDD, 0x8900, 0x1FA4, 0x1502, 0x0504, + 0x1C9F, 0x009E, 0x0E4A, 0x7000, 0x0081, 0xFFDD, + 0x0083, 0x0D80, 0x1F42, 0x0064, 0x07C4, 0x1827, + 0x1B07, 0x0000, 0x0000, 0x0065, 0x07D6, 0x1827, + 0x1B07, 0x4A00, 0x1C5E, 0x1827, 0x1B07, 0x1958, + 0x195F, 0x1827, 0x1B07, 0x5100, 0x1B7F, 0x1827, + 0x1B07, 0x1B7C, 0x1B78, 0x0066, 0x07E0, 0x4A00, + 0x1C5E, 0x1958, 0x195F, 0x5100, 0x1B7F, 0x1B7C, + 0x1B78, 0x0004, 0x1C5A, 0x189F, 0x1ADF, 0x189F, + 0x1ADF, 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x1ADC, + 0x0082, 0x0BD2, 0x27DC, 0x1ADF, 0x27DB, 0x1ADF, + 0x27DA, 0x1ADF, 0x0082, 0x0BBE, 0x27D9, 0x1ADF, + 0x27D8, 0x1ADF, 0x8D00, 0x8B00, 0x8F00, 0x0080, + 0x0D80, 0x00C3, 0x0E42, 0x191A, 0x1919, 0xB058, + 0xFB50, 0x1919, 0x110F, 0x080D, 0xB058, 0xFAA1, + 0x1919, 0xB058, 0xFBA0, 0x1919, 0xB058, 0xFA3B, + 0x1B7E, 0x00E3, 0x0E42, 0x02DF, 0x0082, 0x0BB8, + 0x195E, 0x2ED1, 0x195E, 0x2ED4, 0x195E, 0x2ED5, + 0x195E, 0x2ED6, 0x195E, 0x2ED7, 0x195E, 0x2ED8, + 0x195E, 0x2ED9, 0x195E, 0x2EA0, 0x195E, 0x2EA1, + 0x195E, 0x2EA2, 0x195E, 0x2EA3, 0x195E, 0x2EA4, + 0x195E, 0x2EA5, 0x195E, 0x2EA6, 0x195E, 0x2EA7, + 0x195E, 0x2EA8, 0x195E, 0x2EA9, 0x195E, 0x2EAA, + 0x195E, 0x2EAB, 0x195E, 0x2EAC, 0x195E, 0x2EAD, + 0x195E, 0x2EAE, 0x195E, 0x2EAF, 0x195E, 0x2EDE, + 0x195E, 0x2EDA, 0x195E, 0x2EDB, 0x195E, 0x2EDC, + 0x00C0, 0x0E42, 0x0081, 0xFFDD, 0x1120, 0x0855, + 0x1824, 0x1B04, 0x0000, 0x0000, 0x00E0, 0x0E42, + 0x0082, 0x0BD9, 0x0004, 0x189F, 0x1ADF, 0x189F, + 0x1ADF, 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x8900, + 0x1ADC, 0x27DC, 0x00FF, 0x0BD2, 0x27DB, 0x00FF, + 0x0BD1, 0x27DA, 0x00FF, 0x0BD0, 0x27D9, 0x00FF, + 0x0BBE, 0x27D8, 0x00FF, 0x0BBD, 0x02DF, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BA9, 0x02DF, + 0x00C0, 0x0E41, 0x0081, 0x0B8B, 0x00C2, 0x0E09, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BAC, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, + 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BAF, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BA9, 0x00C0, + 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, + 0x0E41, 0x0081, 0x0B8B, 0x00C2, 0x0E09, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BAC, 0x00C0, 0x0E43, + 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, + 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, + 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, + 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, + 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BA9, 0x02DF, 0x00C0, 0x0E41, + 0x0081, 0x0B8B, 0x00C2, 0x0E09, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAC, 0x02DF, 0x00C0, + 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, + 0x0E48, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, + 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAF, + 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, + 0x0E08, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BA9, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, + 0x0E0A, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BAF, 0x02DF, 0x00C0, 0x0E41, 0x0081, 0x0B8B, + 0x00C2, 0x0E09, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B97, + 0x00C2, 0x0E0A, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, + 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E48, 0x00C4, + 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, + 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, + 0x0B97, 0x00C2, 0x0E0A, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAA, 0x02DF, 0x00C0, 0x0E41, + 0x0081, 0x0B8F, 0x00C2, 0x0E0C, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, + 0x0BAA, 0x00FB, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAA, 0x02DF, 0x00C0, + 0x0E41, 0x0081, 0x0B8F, 0x00C2, 0x0E0C, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAD, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, + 0x0083, 0x0E48, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, + 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, + 0x029F, 0x0982, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB0, 0x029F, 0x098E, 0x00C0, 0x0E43, 0x0081, + 0x0B99, 0x00C2, 0x0E0D, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB0, 0x029F, 0x099A, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB0, 0x029F, 0x09AC, 0x00C0, + 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB0, 0x029F, 0x09B9, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, 0x029F, + 0x09C6, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB0, 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB0, 0x029F, 0x0982, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB0, 0x029F, 0x098E, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB0, + 0x029F, 0x099A, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB0, 0x029F, 0x09AC, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB0, 0x029F, 0x09B9, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB0, + 0x029F, 0x09C6, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BAB, 0x02DF, 0x00C0, 0x0E41, 0x0081, 0x0B93, + 0x00C2, 0x0E0F, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, + 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, + 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAB, 0x02DF, 0x00C0, 0x0E41, 0x0081, + 0x0B93, 0x00C2, 0x0E0F, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E48, + 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x8282, + 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0A94, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, + 0x0AA0, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, + 0x029F, 0x0AAC, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB1, 0x029F, 0x0ABE, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB1, 0x029F, 0x0ACB, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0AD8, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0A94, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, + 0x029F, 0x0AA0, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB1, 0x029F, 0x0AAC, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0ABE, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, + 0x029F, 0x0ACB, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB1, 0x029F, 0x0AD8, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAB, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B93, 0x00C2, 0x0E0F, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAE, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, + 0x0E43, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, + 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAB, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B93, 0x00C2, 0x0E0F, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAE, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, + 0x0083, 0x0E48, 0x00C4, 0x0E43, 0x00C5, 0x0E0F, + 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, + 0x029F, 0x0BA4, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB1, 0x029F, 0x0BB0, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB1, 0x029F, 0x0BBC, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0BCE, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0BDB, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, + 0x0BE8, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB1, 0x029F, 0x0BA4, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0BB0, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, + 0x0BBC, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB1, 0x029F, 0x0BCE, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0BDB, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, + 0x0BE8, 0x0118, 0x01D4, 0x0252, 0x02F8, 0x0509, + 0x051D, 0x01FB, 0x066A, 0x0D27, 0x01F5, 0x056E, + 0x056A, 0x056C, 0x023F, 0x0531, 0x0570, 0x0DA1, + 0x020B, 0x0082, 0x0E17, 0x0875, 0x0876, 0x0882, + 0x088E, 0x08A0, 0x08AC, 0x08C3, 0x08DA, 0x0875, + 0x08F7, 0x0904, 0x0911, 0x0924, 0x0931, 0x094A, + 0x0963, 0x0875, 0x0982, 0x098E, 0x099A, 0x0875, + 0x09AC, 0x09B9, 0x09C6, 0x09D9, 0x09E5, 0x09F2, + 0x09FF, 0x09D9, 0x0A0C, 0x0A19, 0x0A26, 0x0875, + 0x0982, 0x098E, 0x099A, 0x0875, 0x09AC, 0x09B9, + 0x09C6, 0x0A33, 0x0A40, 0x0A4E, 0x0A5C, 0x0A33, + 0x0A6A, 0x0A78, 0x0A86, 0x0875, 0x0A94, 0x0AA0, + 0x0AAC, 0x0875, 0x0ABE, 0x0ACB, 0x0AD8, 0x0AEB, + 0x0AF7, 0x0B04, 0x0B11, 0x0AEB, 0x0B1E, 0x0B2B, + 0x0B38, 0x0875, 0x0A94, 0x0AA0, 0x0AAC, 0x0875, + 0x0ABE, 0x0ACB, 0x0AD8, 0x0B45, 0x0B50, 0x0B5E, + 0x0B6C, 0x0B45, 0x0B7A, 0x0B88, 0x0B96, 0x0875, + 0x0BA4, 0x0BB0, 0x0BBC, 0x0875, 0x0BCE, 0x0BDB, + 0x0BE8, 0x0AEB, 0x0BFB, 0x0C08, 0x0C15, 0x0AEB, + 0x0C22, 0x0C2F, 0x0C3C, 0x0875, 0x0BA4, 0x0BB0, + 0x0BBC, 0x0875, 0x0BCE, 0x0BDB, 0x0BE8, 0x0B45, + 0x0C49, 0x0C57, 0x0C65, 0x0B45, 0x0C73, 0x0C81, + 0x0C8F, 0x069E, 0x0753, 0x0814, 0x1000, 0x1200, + 0x1400, 0x8E00, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0E80, 0x16C9, 0x0000, 0x16CB, + 0x0100, 0x1F7E, 0x1F3C, 0x8100, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0D36, 0x191E, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0280, 0x16C9, 0x0000, 0x16CB, + 0x0280, 0x1C80, 0x0080, 0x0280, 0x00C1, 0x0E1B, + 0x0085, 0x0000, 0x0089, 0x007F, 0x0082, 0x0F00, + 0x0083, 0x16B4, 0x1CE3, 0x8100, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0D54, 0x8F00, 0x8A78, 0x8C68, + 0xF100, 0x1A3F, 0x84E3, 0x107E, 0xF2E3, 0xF2E7, + 0xF278, 0x6E68, 0xF132, 0x1A3F, 0x119E, 0x0D70, + 0x1C67, 0x84E3, 0x107E, 0xF2E3, 0xF2E7, 0xF278, + 0x6E68, 0xF132, 0x1A3F, 0x1C67, 0x84E3, 0x107E, + 0xF2E3, 0xF2E7, 0xF200, 0x6E00, 0x1B5E, 0x00E1, + 0x0E1B, 0x0080, 0x0280, 0x0083, 0x0F00, 0x0081, + 0x0000, 0x0082, 0x0140, 0x0089, 0xFFFF, 0x8900, + 0x8100, 0x8F00, 0x11A0, 0x0D90, 0x197F, 0x9930, + 0x1B1E, 0x1B3F, 0x7D29, 0x1B5F, 0x1B5D, 0x8E00, + 0x1FDB, 0x1F99, 0x2ECE, 0x2CCF, 0x16CD, 0x0E80, + 0x16C9, 0x0001, 0x16CB, 0x0100, 0x02BF, 0x0652, + 0x1C04, 0x029F, 0x0068, 0x8E00, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x07C0, 0x16C9, + 0x0001, 0x16CB, 0x0500, 0x02BF, 0x0652, 0x8100, + 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x07C0, + 0x16C9, 0x0000, 0x8900, 0x0D20, 0x2DCB, 0x4C00, + 0x1C80, 0x0080, 0x07C0, 0x0083, 0x0000, 0x1C43, + 0x0A00, 0x27C9, 0x03A0, 0x0004, 0x029C, 0x0DC3, + 0x2ECE, 0x2CCF, 0x16CD, 0x07D0, 0x16C9, 0x0000, + 0x16CB, 0x04E0, 0x8F00, 0x80F0, 0x80C0, 0x6A00, + 0x4800, 0x114F, 0x0DDE, 0x80F0, 0x80C0, 0x6B32, + 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, + 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x80F0, + 0x80C0, 0x6800, 0x7C00, 0x4A00, 0x114F, 0x0DF5, + 0x80F0, 0x80C0, 0x6932, 0x7D00, 0x4B22, 0x80F0, + 0x80C0, 0x683A, 0x7C00, 0x4A2A, 0x80F0, 0x80C0, + 0x6932, 0x7D00, 0x4B22, 0x1B5F, 0x1B5D, 0x1C04, + 0x029F, 0x0068, 0x8F00, 0x80F1, 0x80C1, 0x6A00, + 0x4800, 0x114F, 0x0E0E, 0x80F1, 0x80C1, 0x6B32, + 0x4922, 0x80F1, 0x80C1, 0x6A3A, 0x482A, 0x80F1, + 0x80C1, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x8E00, + 0x02DF, 0x8E00, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0400, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x0652, 0x8100, 0x8970, 0x191C, + 0x2ECE, 0x2CCF, 0x16CD, 0x0A40, 0x16C9, 0x0001, + 0x16CB, 0x0280, 0x02BF, 0x0652, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x16CB, 0x0280, 0x0081, 0x0E48, 0x0082, + 0x0000, 0x0083, 0x0000, 0x02BF, 0x0652, 0x02BF, + 0x0E00, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x16CB, 0x0280, + 0x0081, 0x0E48, 0x0082, 0x0140, 0x0083, 0x0140, + 0x02BF, 0x0652, 0x02BF, 0x0E00, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x16CB, 0x0280, 0x0081, 0x0E48, 0x0082, + 0x07C0, 0x0083, 0x07C0, 0x02BF, 0x0652, 0x02BF, + 0x0E00, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x16CB, 0x0280, + 0x0081, 0x0E48, 0x0082, 0x0900, 0x0083, 0x0900, + 0x02BF, 0x0652, 0x02BF, 0x0E00, 0x029F, 0x0068, + 0x8E00, 0x16FC, 0xECC0, 0x1FCC, 0x1D9E, 0x2EFD, + 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0E8E, 0x0000, + 0x0000, 0x0000, 0x02FF, 0x8E00, 0x00F0, 0x0E17, + 0x00FE, 0x0E18, 0x00FC, 0x0E19, 0x1FCC, 0x1D9E, + 0x16FC, 0xFEED, 0x2EFD, 0x26FC, 0x02A0, 0x8000, + 0x029C, 0x0EA3, 0x00D0, 0x0E17, 0x00DE, 0x0E18, + 0x00DC, 0x0E19, 0x0000, 0x0000, 0x0000, 0x0000, + 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, 0x8100, 0x00DE, + 0x0BB7, 0x0601, 0x0295, 0x0EBF, 0x0E00, 0x00FE, + 0x0B87, 0x8100, 0x00DE, 0x0B88, 0x0601, 0x0295, + 0x0EC9, 0x8100, 0x1FCD, 0x1F8D, 0x02FF, 0x8100, + 0x00DC, 0x0BE1, 0x7600, 0x00FC, 0x0BE1, 0x8100, + 0x1FCD, 0x1F8D, 0x02FF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, + 0x8100, 0x00DE, 0x0BB7, 0x0601, 0x0295, 0x0EE8, + 0x0E00, 0x00FE, 0x0B87, 0x1FCD, 0x1F8D, 0x02FF, + 0x8100, 0x00DE, 0x0B88, 0x0601, 0x0295, 0x0EFA, + 0x00DE, 0x0BDA, 0x2EDA, 0x00DE, 0x0BDB, 0x2EDB, + 0x00DE, 0x0BDC, 0x2EDC, 0x1FCD, 0x1F8D, 0x02FF, + 0x00DE, 0x0BDA, 0x2EDA, 0x26DB, 0x2EDB, 0x26DC, + 0x2EDC, 0x8100, 0x00DC, 0x0BE1, 0x7600, 0x00FC, + 0x0BE1, 0x8100, 0x1FCD, 0x1F8D, 0x02FF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x02FF, 0x0F28, 0x0F2B, + 0x0F63, 0x0F66, 0x8E00, 0x8100, 0x8900, 0x02BF, + 0x0F69, 0x27FF, 0x009E, 0x0F16, 0x4C00, 0x1C7E, + 0x0313, 0x1C7F, 0x176F, 0x0021, 0x029F, 0x0030, + 0x0021, 0x8100, 0x8900, 0x02BF, 0x0F69, 0x24FF, + 0x02BF, 0x0F6F, 0x25FF, 0x02BF, 0x0F6F, 0x27FF, + 0x2ECE, 0x2CCF, 0x16C9, 0x0001, 0x2FCD, 0x2DCB, + 0x8100, 0x8900, 0x02BF, 0x0F69, 0x24FF, 0x1C9E, + 0x1CBC, 0x02BF, 0x0F6F, 0x25FF, 0x02BF, 0x0F6F, + 0x27FF, 0x1CDF, 0x1CFD, 0x8100, 0x02BF, 0x0F69, + 0x26FF, 0x1C1E, 0x8900, 0x02BF, 0x0F6F, 0x20FF, + 0x1F5F, 0x02BF, 0x0F69, 0x21FF, 0x02BF, 0x0F69, + 0x23FF, 0x26C9, 0x02A0, 0x0004, 0x029C, 0x0F5B, + 0x029F, 0x80B5, 0x0021, 0x029F, 0x8000, 0x0021, + 0x029F, 0x0045, 0x0021, 0x26FE, 0x02C0, 0x8000, + 0x029C, 0x0F69, 0x02DF, 0x27FE, 0x03C0, 0x8000, + 0x029C, 0x0F6F, 0x02DF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000 +}; diff --git a/dolphin sdk not yet linked/src/ax/__ax.h b/dolphin sdk not yet linked/src/ax/__ax.h new file mode 100644 index 0000000..7e0c6e7 --- /dev/null +++ b/dolphin sdk not yet linked/src/ax/__ax.h @@ -0,0 +1,84 @@ +#ifndef _DOLPHIN_AX_INTERNAL_H_ +#define _DOLPHIN_AX_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// AXAlloc +AXVPB* __AXGetStackHead(u32 priority); +void __AXServiceCallbackStack(void); +void __AXInitVoiceStacks(void); +void __AXAllocInit(void); +void __AXAllocQuit(void); +void __AXPushFreeStack(AXVPB* p); +AXVPB* __AXPopFreeStack(void); +void __AXPushCallbackStack(AXVPB* p); +AXVPB* __AXPopCallbackStack(void); +void __AXRemoveFromStack(AXVPB* p); +void __AXPushStackHead(AXVPB* p, u32 priority); +AXVPB* __AXPopStackFromBottom(u32 priority); + +// AXAux +void __AXAuxInit(void); +void __AXAuxQuit(void); +void __AXGetAuxAInput(u32* p); +void __AXGetAuxAOutput(u32* p); +void __AXGetAuxBInput(u32* p); +void __AXGetAuxBOutput(u32* p); +void __AXProcessAux(void); +void __AXGetAuxAInputDpl2(u32* p); +void __AXGetAuxAOutputDpl2R(u32* p); +void __AXGetAuxAOutputDpl2Ls(u32* p); +void __AXGetAuxAOutputDpl2Rs(u32* p); +void __AXGetAuxBForDPL2(u32* p); +void __AXGetAuxBOutputDPL2(u32* p); + +// AXCL +extern u32 __AXClMode; + +// AXComp +extern u16 __AXCompressorTable[3360]; + +u32 __AXGetCommandListCycles(void); +u32 __AXGetCommandListAddress(void); +void __AXWriteToCommandList(u16 data); +void __AXNextFrame(void* sbuffer, void* buffer); +void __AXClInit(void); +void __AXClQuit(void); + +// AXOut +void __AXOutNewFrame(u32 lessDspCycles); +void __AXOutAiCallback(void); +void __AXOutInitDSP(void); +void __AXOutInit(u32 outputBufferMode); +void __AXOutQuit(void); + +// AXProf +AXPROFILE* __AXGetCurrentProfile(void); + +// AXSPB +u32 __AXGetStudio(void); +void __AXDepopFade(s32* hostSum, s32* dspVolume, s16* dspDelta); +void __AXPrintStudio(void); +void __AXSPBInit(void); +void __AXSPBQuit(void); +void __AXDepopVoice(AXPB* p); + +// AXVPB +u32 __AXGetNumVoices(void); +void __AXServiceVPB(AXVPB *pvpb); +void __AXDumpVPB(AXVPB* pvpb); +void __AXSyncPBs(u32 lessDspCycles); +AXPB* __AXGetPBs(void); +void __AXSetPBDefault(AXVPB* p); +void __AXVPBInit(void); +void __AXVPBQuit(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AX_INTERNAL_H_ diff --git a/dolphin sdk not yet linked/src/axfx/__axfx.h b/dolphin sdk not yet linked/src/axfx/__axfx.h new file mode 100644 index 0000000..17ac09f --- /dev/null +++ b/dolphin sdk not yet linked/src/axfx/__axfx.h @@ -0,0 +1,17 @@ +#ifndef _DOLPHIN_AX_INTERNAL_H_ +#define _DOLPHIN_AX_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void* (*__AXFXAlloc)(u32); +extern void (*__AXFXFree)(void*); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/dolphin sdk not yet linked/src/axfx/axfx.c b/dolphin sdk not yet linked/src/axfx/axfx.c new file mode 100644 index 0000000..64c25fc --- /dev/null +++ b/dolphin sdk not yet linked/src/axfx/axfx.c @@ -0,0 +1,20 @@ +#include +#include + +static void* __AXFXAllocFunction(u32 bytes) { + return OSAlloc(bytes); +} + +static void __AXFXFreeFunction(void* p) { + OSFree(p); +} + +void* (*__AXFXAlloc)(u32) = __AXFXAllocFunction; +void (*__AXFXFree)(void*) = __AXFXFreeFunction; + +void AXFXSetHooks(void* (*alloc)(u32), void (*free)(void*)) { + ASSERTLINE(46, alloc && free); + + __AXFXAlloc = alloc; + __AXFXFree = free; +} diff --git a/dolphin sdk not yet linked/src/axfx/chorus.c b/dolphin sdk not yet linked/src/axfx/chorus.c new file mode 100644 index 0000000..56bcffc --- /dev/null +++ b/dolphin sdk not yet linked/src/axfx/chorus.c @@ -0,0 +1,507 @@ +#include +#include +#include + +#include "__axfx.h" + +static f32 rsmpTab12khz[512] = { + 0.097503662109f, 0.802215576172f, 0.101593017578f, -0.000976562500f, 0.093505859375f, + 0.802032470703f, 0.105804443359f, -0.001037597656f, 0.089599609375f, 0.801696777344f, + 0.110107421875f, -0.001159667969f, 0.085784912109f, 0.801177978516f, 0.114471435547f, + -0.001281738281f, 0.082031250000f, 0.800476074219f, 0.118927001953f, -0.001403808594f, + 0.078369140625f, 0.799621582031f, 0.123474121094f, -0.001525878906f, 0.074798583984f, + 0.798614501953f, 0.128143310547f, -0.001647949219f, 0.071350097656f, 0.797424316406f, + 0.132873535156f, -0.001770019531f, 0.067962646484f, 0.796051025391f, 0.137695312500f, + -0.001922607422f, 0.064697265625f, 0.794525146484f, 0.142608642578f, -0.002044677734f, + 0.061492919922f, 0.792846679688f, 0.147613525391f, -0.002197265625f, 0.058349609375f, + 0.790985107422f, 0.152709960938f, -0.002319335938f, 0.055328369141f, 0.788940429688f, + 0.157897949219f, -0.002471923828f, 0.052368164062f, 0.786743164062f, 0.163177490234f, + -0.002655029297f, 0.049499511719f, 0.784423828125f, 0.168518066406f, -0.002807617188f, + 0.046722412109f, 0.781890869141f, 0.173980712891f, -0.002990722656f, 0.044006347656f, + 0.779205322266f, 0.179504394531f, -0.003143310547f, 0.041412353516f, 0.776367187500f, + 0.185119628906f, -0.003326416016f, 0.038879394531f, 0.773376464844f, 0.190826416016f, + -0.003509521484f, 0.036407470703f, 0.770233154297f, 0.196594238281f, -0.003692626953f, + 0.034027099609f, 0.766937255859f, 0.202484130859f, -0.003875732422f, 0.031738281250f, + 0.763488769531f, 0.208435058594f, -0.004058837891f, 0.029510498047f, 0.759857177734f, + 0.214447021484f, -0.004272460938f, 0.027374267578f, 0.756103515625f, 0.220550537109f, + -0.004455566406f, 0.025299072266f, 0.752197265625f, 0.226745605469f, -0.004669189453f, + 0.023315429688f, 0.748168945312f, 0.233001708984f, -0.004852294922f, 0.021392822266f, + 0.743988037109f, 0.239318847656f, -0.005065917969f, 0.019561767578f, 0.739654541016f, + 0.245727539062f, -0.005310058594f, 0.017791748047f, 0.735198974609f, 0.252197265625f, + -0.005523681641f, 0.016052246094f, 0.730590820312f, 0.258728027344f, -0.005706787109f, + 0.014404296875f, 0.725860595703f, 0.265350341797f, -0.005920410156f, 0.012817382812f, + 0.721008300781f, 0.272033691406f, -0.006164550781f, 0.011322021484f, 0.716003417969f, + 0.278778076172f, -0.006378173828f, 0.009887695312f, 0.710906982422f, 0.285583496094f, + -0.006561279297f, 0.008514404297f, 0.705657958984f, 0.292449951172f, -0.006774902344f, + 0.007202148438f, 0.700317382812f, 0.299346923828f, -0.007019042969f, 0.005920410156f, + 0.694854736328f, 0.306335449219f, -0.007232666016f, 0.004699707031f, 0.689270019531f, + 0.313385009766f, -0.007415771484f, 0.003570556641f, 0.683563232422f, 0.320465087891f, + -0.007629394531f, 0.002471923828f, 0.677734375000f, 0.327606201172f, -0.007873535156f, + 0.001434326172f, 0.671844482422f, 0.334777832031f, -0.008087158203f, 0.000457763672f, + 0.665832519531f, 0.341979980469f, -0.008270263672f, -0.000488281250f, 0.659729003906f, + 0.349243164062f, -0.008453369141f, -0.001342773438f, 0.653533935547f, 0.356567382812f, + -0.008636474609f, -0.002166748047f, 0.647216796875f, 0.363891601562f, -0.008850097656f, + -0.002960205078f, 0.640838623047f, 0.371276855469f, -0.009033203125f, -0.003692626953f, + 0.634338378906f, 0.378692626953f, -0.009216308594f, -0.004364013672f, 0.627777099609f, + 0.386138916016f, -0.009338378906f, -0.004974365234f, 0.621154785156f, 0.393615722656f, + -0.009490966797f, -0.005584716797f, 0.614440917969f, 0.401092529297f, -0.009643554688f, + -0.006134033203f, 0.607635498047f, 0.408599853516f, -0.009796142578f, -0.006652832031f, + 0.600769042969f, 0.416107177734f, -0.009918212891f, -0.007141113281f, 0.593841552734f, + 0.423645019531f, -0.010009765625f, -0.007568359375f, 0.586853027344f, 0.431213378906f, + -0.010131835938f, -0.007965087891f, 0.579772949219f, 0.438751220703f, -0.010223388672f, + -0.008331298828f, 0.572662353516f, 0.446319580078f, -0.010284423828f, -0.008666992188f, + 0.565521240234f, 0.453887939453f, -0.010345458984f, -0.008972167969f, 0.558319091797f, + 0.461456298828f, -0.010406494141f, -0.009216308594f, 0.551055908203f, 0.469024658203f, + -0.010406494141f, -0.009460449219f, 0.543731689453f, 0.476593017578f, -0.010406494141f, + -0.009674072266f, 0.536407470703f, 0.484130859375f, -0.010375976562f, -0.009857177734f, + 0.529022216797f, 0.491668701172f, -0.010375976562f, -0.010009765625f, 0.521606445312f, + 0.499176025391f, -0.010314941406f, -0.010131835938f, 0.514160156250f, 0.506683349609f, + -0.010253906250f, -0.010253906250f, 0.506683349609f, 0.514160156250f, -0.010131835938f, + -0.010314941406f, 0.499176025391f, 0.521606445312f, -0.010009765625f, -0.010375976562f, + 0.491668701172f, 0.529022216797f, -0.009857177734f, -0.010375976562f, 0.484130859375f, + 0.536407470703f, -0.009674072266f, -0.010406494141f, 0.476593017578f, 0.543731689453f, + -0.009460449219f, -0.010406494141f, 0.469024658203f, 0.551055908203f, -0.009216308594f, + -0.010406494141f, 0.461456298828f, 0.558319091797f, -0.008972167969f, -0.010345458984f, + 0.453887939453f, 0.565521240234f, -0.008666992188f, -0.010284423828f, 0.446319580078f, + 0.572662353516f, -0.008331298828f, -0.010223388672f, 0.438751220703f, 0.579772949219f, + -0.007965087891f, -0.010131835938f, 0.431213378906f, 0.586853027344f, -0.007568359375f, + -0.010009765625f, 0.423645019531f, 0.593841552734f, -0.007141113281f, -0.009918212891f, + 0.416107177734f, 0.600769042969f, -0.006652832031f, -0.009796142578f, 0.408599853516f, + 0.607635498047f, -0.006134033203f, -0.009643554688f, 0.401092529297f, 0.614440917969f, + -0.005584716797f, -0.009490966797f, 0.393615722656f, 0.621154785156f, -0.004974365234f, + -0.009338378906f, 0.386138916016f, 0.627777099609f, -0.004364013672f, -0.009216308594f, + 0.378692626953f, 0.634338378906f, -0.003692626953f, -0.009033203125f, 0.371276855469f, + 0.640838623047f, -0.002960205078f, -0.008850097656f, 0.363891601562f, 0.647216796875f, + -0.002166748047f, -0.008636474609f, 0.356567382812f, 0.653533935547f, -0.001342773438f, + -0.008453369141f, 0.349243164062f, 0.659729003906f, -0.000488281250f, -0.008270263672f, + 0.341979980469f, 0.665832519531f, 0.000457763672f, -0.008087158203f, 0.334777832031f, + 0.671844482422f, 0.001434326172f, -0.007873535156f, 0.327606201172f, 0.677734375000f, + 0.002471923828f, -0.007629394531f, 0.320465087891f, 0.683563232422f, 0.003570556641f, + -0.007415771484f, 0.313385009766f, 0.689270019531f, 0.004699707031f, -0.007232666016f, + 0.306335449219f, 0.694854736328f, 0.005920410156f, -0.007019042969f, 0.299346923828f, + 0.700317382812f, 0.007202148438f, -0.006774902344f, 0.292449951172f, 0.705657958984f, + 0.008514404297f, -0.006561279297f, 0.285583496094f, 0.710906982422f, 0.009887695312f, + -0.006378173828f, 0.278778076172f, 0.716003417969f, 0.011322021484f, -0.006164550781f, + 0.272033691406f, 0.721008300781f, 0.012817382812f, -0.005920410156f, 0.265350341797f, + 0.725860595703f, 0.014404296875f, -0.005706787109f, 0.258728027344f, 0.730590820312f, + 0.016052246094f, -0.005523681641f, 0.252197265625f, 0.735198974609f, 0.017791748047f, + -0.005310058594f, 0.245727539062f, 0.739654541016f, 0.019561767578f, -0.005065917969f, + 0.239318847656f, 0.743988037109f, 0.021392822266f, -0.004852294922f, 0.233001708984f, + 0.748168945312f, 0.023315429688f, -0.004669189453f, 0.226745605469f, 0.752197265625f, + 0.025299072266f, -0.004455566406f, 0.220550537109f, 0.756103515625f, 0.027374267578f, + -0.004272460938f, 0.214447021484f, 0.759857177734f, 0.029510498047f, -0.004058837891f, + 0.208435058594f, 0.763488769531f, 0.031738281250f, -0.003875732422f, 0.202484130859f, + 0.766937255859f, 0.034027099609f, -0.003692626953f, 0.196594238281f, 0.770233154297f, + 0.036407470703f, -0.003509521484f, 0.190826416016f, 0.773376464844f, 0.038879394531f, + -0.003326416016f, 0.185119628906f, 0.776367187500f, 0.041412353516f, -0.003143310547f, + 0.179504394531f, 0.779205322266f, 0.044006347656f, -0.002990722656f, 0.173980712891f, + 0.781890869141f, 0.046722412109f, -0.002807617188f, 0.168518066406f, 0.784423828125f, + 0.049499511719f, -0.002655029297f, 0.163177490234f, 0.786743164062f, 0.052368164062f, + -0.002471923828f, 0.157897949219f, 0.788940429688f, 0.055328369141f, -0.002319335938f, + 0.152709960938f, 0.790985107422f, 0.058349609375f, -0.002197265625f, 0.147613525391f, + 0.792846679688f, 0.061492919922f, -0.002044677734f, 0.142608642578f, 0.794525146484f, + 0.064697265625f, -0.001922607422f, 0.137695312500f, 0.796051025391f, 0.067962646484f, + -0.001770019531f, 0.132873535156f, 0.797424316406f, 0.071350097656f, -0.001647949219f, + 0.128143310547f, 0.798614501953f, 0.074798583984f, -0.001525878906f, 0.123474121094f, + 0.799621582031f, 0.078369140625f, -0.001403808594f, 0.118927001953f, 0.800476074219f, + 0.082031250000f, -0.001281738281f, 0.114471435547f, 0.801177978516f, 0.085784912109f, + -0.001159667969f, 0.110107421875f, 0.801696777344f, 0.089599609375f, -0.001037597656f, + 0.105804443359f, 0.802032470703f, 0.093505859375f, -0.000976562500f, 0.101593017578f, + 0.802215576172f, 0.097503662109f, +}; + +const static double i2fMagic = 4503601774854144.0; + +// prototypes +static void do_src1(AXFX_CHORUS_SRCINFO* src); +static void do_src2(AXFX_CHORUS_SRCINFO* src); + +asm static void do_src1(register AXFX_CHORUS_SRCINFO* src) { + nofralloc + stwu r1, -64(r1) + stmw r26, 40(r1) + lwz r4, AXFX_CHORUS_SRCINFO.posLo(src) + lwz r5, AXFX_CHORUS_SRCINFO.posHi(src) + lwz r6, AXFX_CHORUS_SRCINFO.pitchLo(src) + lwz r8, AXFX_CHORUS_SRCINFO.trigger(src) + lwz r7, AXFX_CHORUS_SRCINFO.target(src) + lwz r31, AXFX_CHORUS_SRCINFO.smpBase(src) + lwz r30, AXFX_CHORUS_SRCINFO.dest(src) + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + lis r10, 0x4330 + stw r10, 8(r1) + stw r10, 16(r1) + stw r10, 24(r1) + stw r10, 32(r1) + lis r10, i2fMagic@ha + lfd f9, i2fMagic@l(r10) + slwi r10, r5, 2 + lwz r11, 0(r9) + lwz r29, 4(r9) + lwz r28, 8(r9) + lwzx r27, r31, r10 + xoris r11, r11, 0x8000 + xoris r29, r29, 0x8000 + stw r11, 12(r1) + xoris r28, r28, 0x8000 + stw r29, 20(r1) + xoris r27, r27, 0x8000 + stw r28, 28(r1) + lfd f1, 8(r1) + stw r27, 36(r1) + lfd f2, 16(r1) + fsubs f1, f1, f9 + lfd f3, 24(r1) + fsubs f2, f2, f9 + lfd f4, 32(r1) + fsubs f3, f3, f9 + fsubs f4, f4, f9 + li r26, -4 + lis r12, rsmpTab12khz@ha + addi r12, r12, rsmpTab12khz@l + li r9, 160 + mtctr r9 +L_000000AC: + rlwinm r10, r4, 7, 21, 27 + addc r4, r4, r6 + add r10, r10, r12 + mcrxr cr0 + lfs f5, 0(r10) + beq L_000000F4 + lfs f6, 4(r10) + fmuls f10, f1, f5 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmadds f10, f4, f8, f10 + fctiwz f10, f10 + stfiwx f10, r26, r30 + bdnz L_000000AC + b L_00000160 +L_000000F4: + addi r5, r5, 1 + lfs f6, 4(r10) + fmuls f10, f1, f5 + cmpw r5, r8 + fmr f1, f2 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + fmr f2, f3 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmr f3, f4 + bne+ L_0000012C + mr r5, r7 +L_0000012C: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000158 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_000000AC +L_00000158: + fctiwz f10, f10 + stfiwx f10, r26, r30 +L_00000160: + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + fctiwz f1, f1 + fctiwz f2, f2 + fctiwz f3, f3 + stfiwx f1, r0, r9 + addi r10, r9, 4 + stfiwx f2, r0, r10 + addi r10, r9, 8 + stfiwx f3, r0, r10 + stw r4, AXFX_CHORUS_SRCINFO.posLo(src) + stw r5, AXFX_CHORUS_SRCINFO.posHi(src) + lmw r26, 40(r1) + addi r1, r1, 64 + blr +} + +asm static void do_src2(register AXFX_CHORUS_SRCINFO* src) { + nofralloc + stwu r1, -64(r1) + stmw r26, 40(r1) + lwz r4, AXFX_CHORUS_SRCINFO.posLo(src) + lwz r5, AXFX_CHORUS_SRCINFO.posHi(src) + lwz r6, AXFX_CHORUS_SRCINFO.pitchLo(src) + lwz r8, AXFX_CHORUS_SRCINFO.trigger(src) + lwz r7, AXFX_CHORUS_SRCINFO.target(src) + lwz r31, AXFX_CHORUS_SRCINFO.smpBase(src) + lwz r30, AXFX_CHORUS_SRCINFO.dest(src) + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + lis r10, 0x4330 + stw r10, 8(r1) + stw r10, 16(r1) + stw r10, 24(r1) + stw r10, 32(r1) + lis r10, i2fMagic@ha + lfd f9, i2fMagic@l(r10) + slwi r10, r5, 2 + lwz r11, 0(r9) + lwz r29, 4(r9) + lwz r28, 8(r9) + lwzx r27, r31, r10 + xoris r11, r11, 0x8000 + xoris r29, r29, 0x8000 + stw r11, 12(r1) + xoris r28, r28, 0x8000 + stw r29, 20(r1) + xoris r27, r27, 0x8000 + stw r28, 28(r1) + lfd f1, 8(r1) + stw r27, 36(r1) + lfd f2, 16(r1) + fsubs f1, f1, f9 + lfd f3, 24(r1) + fsubs f2, f2, f9 + lfd f4, 32(r1) + fsubs f3, f3, f9 + fsubs f4, f4, f9 + li r26, -4 + lis r12, rsmpTab12khz@ha + addi r12, r12, rsmpTab12khz@l + li r9, 160 + mtctr r9 +L_00000244: + rlwinm r10, r4, 7, 21, 27 + addc r4, r4, r6 + add r10, r10, r12 + mcrxr cr0 + addi r5, r5, 1 + lfs f5, 0(r10) + beq L_000002C0 + lfs f6, 4(r10) + fmuls f10, f1, f5 + cmpw r5, r8 + fmr f1, f2 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + fmr f2, f3 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmr f3, f4 + bne+ L_00000294 + mr r5, r7 +L_00000294: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000344 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_00000244 +L_000002C0: + cmpw r5, r8 + lfs f6, 4(r10) + bne+ L_000002D0 + mr r5, r7 +L_000002D0: + slwi r11, r5, 2 + addi r5, r5, 1 + lwzx r29, r11, r31 + fmuls f10, f1, f5 + cmpw r5, r8 + xoris r29, r29, 0x8000 + fmr f1, f3 + lfs f7, 8(r10) + stw r29, 12(r1) + fmadds f10, f2, f6, f10 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + lfd f3, 8(r1) + fmr f2, f4 + addi r30, r30, 4 + fsubs f3, f3, f9 + bne+ L_00000318 + mr r5, r7 +L_00000318: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000344 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_00000244 +L_00000344: + fctiwz f10, f10 + stfiwx f10, r26, r30 + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + fctiwz f1, f1 + fctiwz f2, f2 + fctiwz f3, f3 + stfiwx f1, r0, r9 + addi r10, r9, 4 + stfiwx f2, r0, r10 + addi r10, r9, 8 + stfiwx f3, r0, r10 + stw r4, AXFX_CHORUS_SRCINFO.posLo(src) + stw r5, AXFX_CHORUS_SRCINFO.posHi(src) + lmw r26, 40(r1) + addi r1, r1, 64 + blr +} + +int AXFXChorusInit(AXFX_CHORUS* c) { + s32* left; + s32* right; + s32* sur; + u32 i; + BOOL old; + + ASSERTMSGLINE(1074, c->baseDelay >= 5 && c->baseDelay <= 15 && c->variation >= 0 && c->variation <= 5 && c->period >= 500 && c->period <= 10000, "The value of specified parameter is out of range."); + + if (c->baseDelay < 5 || c->baseDelay > 15 || c->variation < 0 || c->variation > 5 || c->period < 500 || c->period > 10000) { + return 0; + } + + old = OSDisableInterrupts(); + c->work.lastLeft[0] = __AXFXAlloc(0x1680); + ASSERTMSGLINE(0x442, c->work.lastLeft[0], "Can't allocate the memory."); + + if (c->work.lastLeft[0] != NULL) { + c->work.lastRight[0] = (void*)(c->work.lastLeft[0] + 0x1E0); + c->work.lastSur[0] = (void*)(c->work.lastRight[0] + 0x1E0); + + for (i = 1; i < 3; i++) { + c->work.lastLeft[i] = (void*)&c->work.lastLeft[0][i * 0xA0]; + c->work.lastRight[i] = (void*)&c->work.lastRight[0][i * 0xA0]; + c->work.lastSur[i] = (void*)&c->work.lastSur[0][i * 0xA0]; + } + + left = c->work.lastLeft[0]; + right = c->work.lastRight[0]; + sur = c->work.lastSur[0]; + + for (i = 0; i < 0x140; i++) { + *left++ = 0; + *right++ = 0; + *sur++ = 0; + } + + c->work.currentLast = 1; + c->work.oldLeft[0] = c->work.oldLeft[1] = c->work.oldLeft[2] = c->work.oldLeft[3] = 0; + c->work.oldRight[0] = c->work.oldRight[1] = c->work.oldRight[2] = c->work.oldRight[3] = 0; + c->work.oldSur[0] = c->work.oldSur[1] = c->work.oldSur[2] = c->work.oldSur[3] = 0; + c->work.src.trigger = 0x1E0; + c->work.src.target = 0; + OSRestoreInterrupts(old); + return AXFXChorusSettings(c); + } + + OSRestoreInterrupts(old); + return 0; +} + +int AXFXChorusShutdown(AXFX_CHORUS* c) { + BOOL old; + + old = OSDisableInterrupts(); + __AXFXFree(c->work.lastLeft[0]); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXChorusSettings(AXFX_CHORUS* c) { + BOOL old; + + ASSERTMSGLINE(1159, c->baseDelay >= 5 && c->baseDelay <= 15 && c->variation >= 0 && c->variation <= 5 && c->period >= 500 && c->period <= 10000, "The value of specified parameter is out of range."); + if (c->baseDelay < 5 || c->baseDelay > 15 || c->variation < 0 || c->variation > 5 || c->period < 500 || c->period > 10000) { + return 0; + } + + old = OSDisableInterrupts(); + c->work.currentPosHi = 0x140 - ((c->baseDelay - 5) << 5); + c->work.currentPosLo = 0; + c->work.currentPosHi = (c->work.currentPosHi + ((c->work.currentLast - 1) * 0xA0/1)) % 480; + c->work.pitchOffsetPeriod = ((c->period / 5) + 1) & ~(1); + c->work.pitchOffsetPeriodCount = c->work.pitchOffsetPeriod >> 1; + c->work.pitchOffset = (c->variation << 0x10) / (c->work.pitchOffsetPeriod * 5); + OSRestoreInterrupts(old); + return 1; +} + +void AXFXChorusCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_CHORUS* chorus) { + s32* leftD; + s32* rightD; + s32* surD; + s32* leftS; + s32* rightS; + s32* surS; + u32 i; + u8 nextCurrentLast; + + nextCurrentLast = (chorus->work.currentLast + 1) % 3; + leftD = chorus->work.lastLeft[nextCurrentLast]; + rightD = chorus->work.lastRight[nextCurrentLast]; + surD = chorus->work.lastSur[nextCurrentLast]; + leftS = bufferUpdate->left; + rightS = bufferUpdate->right; + surS = bufferUpdate->surround; + + for (i = 0; i < 0xA0; i++) { + *leftD++ = *leftS++; + *rightD++ = *rightS++; + *surD++ = *surS++; + } + + chorus->work.src.pitchHi = (chorus->work.pitchOffset >> 0x10) + 1; + chorus->work.src.pitchLo = (chorus->work.pitchOffset & 0xFFFF) << 0x10; + + if (--chorus->work.pitchOffsetPeriodCount == 0) { + chorus->work.pitchOffsetPeriodCount = chorus->work.pitchOffsetPeriod; + chorus->work.pitchOffset = -chorus->work.pitchOffset; + } + + for (i = 0; i < 3; i++) { + chorus->work.src.posHi = chorus->work.currentPosHi; + chorus->work.src.posLo = chorus->work.currentPosLo; + switch (i) { + case 0: + chorus->work.src.smpBase = chorus->work.lastLeft[0]; + chorus->work.src.dest = bufferUpdate->left; + chorus->work.src.old = &chorus->work.oldLeft[0]; + break; + case 1: + chorus->work.src.smpBase = chorus->work.lastRight[0]; + chorus->work.src.dest = bufferUpdate->right; + chorus->work.src.old = &chorus->work.oldRight[0]; + break; + case 2: + chorus->work.src.smpBase = chorus->work.lastSur[0]; + chorus->work.src.dest = bufferUpdate->surround; + chorus->work.src.old = &chorus->work.oldSur[0]; + break; + } + switch(chorus->work.src.pitchHi) { + case 0: + do_src1(&chorus->work.src); + break; + case 1: + do_src2(&chorus->work.src); + break; + } + } + + chorus->work.currentPosHi = (chorus->work.src.posHi % 480); + chorus->work.currentPosLo = chorus->work.src.posLo; + chorus->work.currentLast = nextCurrentLast; +} diff --git a/dolphin sdk not yet linked/src/axfx/delay.c b/dolphin sdk not yet linked/src/axfx/delay.c new file mode 100644 index 0000000..5c26e59 --- /dev/null +++ b/dolphin sdk not yet linked/src/axfx/delay.c @@ -0,0 +1,148 @@ +#include +#include +#include + +#include "__axfx.h" + +void AXFXDelayCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_DELAY* delay) { + s32 l; + s32 r; + s32 s; + s32* lBuf; + s32* rBuf; + s32* sBuf; + u32 i; + s32* left; + s32* right; + s32* sur; + + left = bufferUpdate->left; + right = bufferUpdate->right; + sur = bufferUpdate->surround; + lBuf = delay->left + (delay->currentPos[0] * 0xA0); + rBuf = delay->right + (delay->currentPos[1] * 0xA0); + sBuf = delay->sur + (delay->currentPos[2] * 0xA0); + + for (i = 0; i < 160; i++) { + l = *lBuf; + r = *rBuf; + s = *sBuf; + *lBuf++ = *left + ((s32)(l* delay->currentFeedback[0]) >> 7); + *rBuf++ = *right + ((s32)(r* delay->currentFeedback[1]) >> 7); + *sBuf++ = *sur + ((s32)(s* delay->currentFeedback[2]) >> 7); + *left++ = (s32)(l* delay->currentOutput[0]) >> 7; + *right++ = (s32)(r* delay->currentOutput[1]) >> 7; + *sur++ = (s32)(s* delay->currentOutput[2]) >> 7; + } + + delay->currentPos[0] = (s32) ((delay->currentPos[0] + 1) % delay->currentSize[0]); + delay->currentPos[1] = (s32) ((delay->currentPos[1] + 1) % delay->currentSize[1]); + delay->currentPos[2] = (s32) ((delay->currentPos[2] + 1) % delay->currentSize[2]); +} + +int AXFXDelaySettings(AXFX_DELAY* delay) { + u32 i; + s32* l; + s32* r; + s32* s; + BOOL old; + + ASSERTMSGLINE(67, delay->delay[0] >= 10 && delay->delay[0] <= 5000 && + delay->delay[1] >= 10 && delay->delay[1] <= 5000 && + delay->delay[2] >= 10 && delay->delay[2] <= 5000 && + delay->feedback[0] >= 0 && delay->feedback[0] <= 100 && + delay->feedback[1] >= 0 && delay->feedback[1] <= 100 && + delay->feedback[2] >= 0 && delay->feedback[2] <= 100 && + delay->output[0] >= 0 && delay->output[0] <= 100 && + delay->output[1] >= 0 && delay->output[1] <= 100 && + delay->output[2] >= 0 && delay->output[2] <= 100, + "The value of specified parameter is out of range."); + + if (delay->delay[0] < 10 || delay->delay[0] > 5000 || + delay->delay[1] < 10 || delay->delay[1] > 5000 || + delay->delay[2] < 10 || delay->delay[2] > 5000 || + delay->feedback[0] < 0 || delay->feedback[0] > 100 || + delay->feedback[1] < 0 || delay->feedback[1] > 100 || + delay->feedback[2] < 0 || delay->feedback[2] > 100 || + delay->output[0] < 0 || delay->output[0] > 100 || + delay->output[1] < 0 || delay->output[1] > 100 || + delay->output[2] < 0 || delay->output[2] > 100) + { + return 0; + } + + AXFXDelayShutdown(delay); + old = OSDisableInterrupts(); + + for (i = 0; i < 3; i++) { + delay->currentSize[i] = (((delay->delay[i] - 5) << 5) + 0x9F) / 160U; + delay->currentPos[i] = 0; + delay->currentFeedback[i] = (delay->feedback[i] << 7) / 100U; + delay->currentOutput[i] = (delay->output[i] << 7) / 100U; + } + + delay->left = __AXFXAlloc(delay->currentSize[0] * 0xA0 * 4); + delay->right = __AXFXAlloc(delay->currentSize[1] * 0xA0 * 4); + delay->sur = __AXFXAlloc(delay->currentSize[2] * 0xA0 * 4); + + ASSERTMSGLINE(98, delay->left && delay->right && delay->sur, "Can't allocate the memory."); + + if (delay->left == NULL || delay->right == NULL || delay->sur == NULL) { + AXFXDelayShutdown(delay); + return 0; + } + + l = delay->left; + r = delay->right; + s = delay->sur; + + for (i = 0; i < delay->currentSize[0] * 0xA0; i++) { + *l++ = 0; + } + + for (i = 0; i < delay->currentSize[1] * 0xA0; i++) { + *r++ = 0; + } + + for (i = 0; i < delay->currentSize[2] * 0xA0; i++) { + *s++ = 0; + } + + OSRestoreInterrupts(old); + return 1; +} + +int AXFXDelayInit(AXFX_DELAY* delay) { + BOOL old; + + old = OSDisableInterrupts(); + delay->left = NULL; + delay->right = NULL; + delay->sur = NULL; + OSRestoreInterrupts(old); + AXFXDelaySettings(delay); +} + +int AXFXDelayShutdown(AXFX_DELAY* delay) { + BOOL old; + + old = OSDisableInterrupts(); + if (delay->left) { + __AXFXFree(delay->left); + } + + if (delay->right) { + __AXFXFree(delay->right); + } + + if (delay->sur) { + __AXFXFree(delay->sur); + } + + delay->left = NULL; + delay->right = NULL; + delay->sur = NULL; + + OSRestoreInterrupts(old); + return 1; +} diff --git a/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/dolphin sdk not yet linked/src/axfx/reverb_hi_4ch.c b/dolphin sdk not yet linked/src/axfx/reverb_hi_4ch.c new file mode 100644 index 0000000..df10073 --- /dev/null +++ b/dolphin sdk not yet linked/src/axfx/reverb_hi_4ch.c @@ -0,0 +1,611 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__axfx.h" + +static void ReverbHIDpl2Free(AXFX_REVHI_WORK_DPL2* rv); + +static void DLsetdelayDpl2(AXFX_REVHI_DELAYLINE* dl, s32 lag) { + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) { + dl->outPoint += dl->length; + } +} + +static int DLcreateDpl2(AXFX_REVHI_DELAYLINE* dl, s32 max_length) { + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length << 2); + ASSERTMSGLINE(62, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) { + return 0; + } + + memset(dl->inputs, 0, max_length << 2); + dl->lastOutput = 0.0f; + DLsetdelayDpl2(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdeleteDpl2(AXFX_REVHI_DELAYLINE* dl) { + __AXFXFree(dl->inputs); +} + +static int ReverbHICreateDpl2(AXFX_REVHI_WORK_DPL2* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay) { + u8 i; + u8 k; + + static s32 lens[9] = { + 0x000006FD, + 0x000007CF, + 0x0000091D, + 0x000001B1, + 0x00000095, + 0x0000002F, + 0x00000049, + 0x00000043, + 0x00000047 + }; + + ASSERTMSGLINE(117, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f )) { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVHI_WORK_DPL2)); + + for (k = 0; k < 4; k++) { + for (i = 0; i < 3; i++) { + if (DLcreateDpl2(&rv->C[i + (k * 3)], lens[i] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->C[i + (k * 3)], lens[i]); + rv->combCoef[i + (k * 3)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) { + if (DLcreateDpl2(&rv->AP[i + (k * 3)], lens[i + 3] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->AP[i + (k * 3)], lens[i + 3]); + } + + if (DLcreateDpl2(&rv->AP[2 + (k * 3)], lens[k + 5] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->AP[2 + (k * 3)], lens[k + 5]); + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + if (0.0f != preDelay) { + rv->preDelayTime = (32000.0f * preDelay); + for (i = 0; i < 4; i++) { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(188, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) { + ReverbHIDpl2Free(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } else { + rv->preDelayTime = 0; + for (i = 0; i < 4; i++) { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbHIModifyDpl2(AXFX_REVHI_WORK_DPL2* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay) { + u8 i; + + ASSERTMSGLINE(222, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f ) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f)) { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 12; i++) { + DLdeleteDpl2(&rv->AP[i]); + } + + for (i = 0; i < 12; i++) { + DLdeleteDpl2(&rv->C[i]); + } + + if (rv->preDelayTime) { + for (i = 0; i < 4; i++) { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbHICreateDpl2(rv, coloration, time, mix, damping, preDelay); +} + + +const static f32 value0_6 = 0.6f; +const static f32 value0_3 = 0.3f; +const static double i2fMagic = 4503601774854144.0; + +asm static void HandleReverbDpl2(register s32* sptr, register AXFX_REVHI_WORK_DPL2* rv, register s32 k) { + nofralloc + stwu r1, -0xc0(r1) + stmw r14, 0x8(r1) + stfd f14, 0x60(r1) + stfd f15, 0x68(r1) + stfd f16, 0x70(r1) + stfd f17, 0x78(r1) + stfd f18, 0x80(r1) + stfd f19, 0x88(r1) + stfd f20, 0x90(r1) + stfd f21, 0x98(r1) + stfd f22, 0xa0(r1) + stfd f23, 0xa8(r1) + stfd f24, 0xb0(r1) + stfd f25, 0xb8(r1) + stw k, 0x50(r1) + stw rv, 0x54(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, AXFX_REVHI_WORK_DPL2.allPassCoeff(rv) + lfs f15, AXFX_REVHI_WORK_DPL2.damping(rv) + lfs f8, AXFX_REVHI_WORK_DPL2.level(rv) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 + addi r29, rv, AXFX_REVHI_WORK_DPL2.C + add r29, r29, r31 + addi r27, rv, AXFX_REVHI_WORK_DPL2.AP + add r27, r27, r31 + slwi r31, r30, 2 + add r31, r31, rv + lfs f22, AXFX_REVHI_WORK_DPL2.combCoef[0](r31) + lfs f23, AXFX_REVHI_WORK_DPL2.combCoef[1](r31) + lfs f24, AXFX_REVHI_WORK_DPL2.combCoef[2](r31) + slwi r31, k, 2 + add r31, r31, rv + lfs f25, AXFX_REVHI_WORK_DPL2.lpLastout[0](r31) + lwz r31, AXFX_REVHI_WORK_DPL2.preDelayTime(rv) + lis r30, 0x4330 + stw r30, 0x58(r1) + subi r22, r31, 1 + slwi r22, r22, 2 + slwi r28, k, 2 + add r28, r28, rv + cmpwi cr7, r31, 0 + lwz r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + lwz r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + lwz r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + lwz r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + lwz r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + lwz r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + lfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + lfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + lfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + lwz r25, AXFX_REVHI_DELAYLINE.length + 0x00(r29) // C[0] + lwz r24, AXFX_REVHI_DELAYLINE.length + 0x14(r29) // C[1] + lwz r23, AXFX_REVHI_DELAYLINE.length + 0x28(r29) // C[2] + lwz r4, AXFX_REVHI_DELAYLINE.inputs + 0x00(r29) // C[0] + lwz r5, AXFX_REVHI_DELAYLINE.inputs + 0x14(r29) // C[1] + lwz r6, AXFX_REVHI_DELAYLINE.inputs + 0x28(r29) // C[2] + lwz r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + lwz r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + lwz r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + lwz r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + lwz r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + lwz r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + lfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + lfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + lfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + lwz r15, AXFX_REVHI_DELAYLINE.length + 0x00(r27) // AP[0] + lwz r14, AXFX_REVHI_DELAYLINE.length + 0x14(r27) // AP[1] + //? missing load for length of AP[3]? Maybe intentional? + lwz r30, 0(r3) + xoris r30, r30, 0x8000 + stw r30, 0x5c(r1) + lfd f12, 0x58(r1) + fsubs f12, f12, f5 + li r31, 159 + mtctr r31 +L_00000964: + fmr f13, f12 + beq cr7, L_00000994 + lwz r30, AXFX_REVHI_WORK_DPL2.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000990 + mr r29, r30 +L_00000990: + stw r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r30) +L_00000994: + fmadds f8, f22, f16, f13 + lwzu r29, 4(r3) + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_000009E0 + li r21, 0 +L_000009E0: + fmadds f8, f24, f18, f13 + bne+ cr1, L_000009EC + li r20, 0 +L_000009EC: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_000009FC + li r19, 0 +L_000009FC: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000A10 + li r18, 0 +L_00000A10: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000A28 + li r17, 0 +L_00000A28: + bne+ cr1, L_00000A30 + li r16, 0 +L_00000A30: + xoris r29, r29, 0x8000 + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000A60 + li r12, 0x0 +L_00000A60: + stw r29, 0x5c(r1) + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000A78 + li r11, 0 +L_00000A78: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + lfd f10, 0x58(r1) + fmadds f14, f15, f25, f14 + bne+ L_00000A9C + li r10, 0 +L_00000A9C: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000AB0 + li r9, 0 +L_00000AB0: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r31, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r31 + cmpw cr6, r7, r31 + fctiwz f14, f14 + bne+ cr5, L_00000AE4 + li r8, 0 +L_00000AE4: + bne+ cr6, L_00000AEC + li r7, 0 +L_00000AEC: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, sptr, r31 + bdnz L_00000964 + fmr f13, f12 + beq cr7, L_00000B2C + lwz r30, AXFX_REVHI_WORK_DPL2.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000B28 + mr r29, r30 +L_00000B28: + stw r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r30) +L_00000B2C: + fmadds f8, f22, f16, f13 + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_00000B74 + li r21, 0 +L_00000B74: + fmadds f8, f24, f18, f13 + bne+ cr1, L_00000B80 + li r20, 0 +L_00000B80: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_00000B90 + li r19, 0 +L_00000B90: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000BA4 + li r18, 0 +L_00000BA4: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000BBC + li r17, 0 +L_00000BBC: + bne+ cr1, L_00000BC4 + li r16, 0 +L_00000BC4: + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000BF0 + li r12, 0 +L_00000BF0: + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000C04 + li r11, 0 +L_00000C04: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + fmadds f14, f15, f25, f14 + bne+ L_00000C24 + li r10, 0 +L_00000C24: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + lwz k, 0x50(r1) + lwz rv, 0x54(r1) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000C40 + li r9, 0 +L_00000C40: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r29, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r29 + cmpw cr6, r7, r29 + fctiwz f14, f14 + bne+ cr5, L_00000C74 + li r8, 0 +L_00000C74: + bne+ cr6, L_00000C7C + li r7, 0 +L_00000C7C: + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 // sizeof AXFX_REVHI_DELAYLINE + stfiwx f14, r0, sptr + addi r29, rv, AXFX_REVHI_WORK_DPL2.C + add r29, r29, r31 + stw r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + stw r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + stw r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + stw r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + stw r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + stw r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + stfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + stfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + stfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + stw r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + stw r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + stw r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + stw r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + stw r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + stw r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + stfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + stfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + stfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + slwi r31, k, 2 + add r31, r31, rv + stfs f25, AXFX_REVHI_WORK_DPL2.lpLastout(r31) + lfd f14, 0x60(r1) + lfd f15, 0x68(r1) + lfd f16, 0x70(r1) + lfd f17, 0x78(r1) + lfd f18, 0x80(r1) + lfd f19, 0x88(r1) + lfd f20, 0x90(r1) + lfd f21, 0x98(r1) + lfd f22, 0xa0(r1) + lfd f23, 0xa8(r1) + lfd f24, 0xb0(r1) + lfd f25, 0xb8(r1) + lmw r14, 0x8(r1) + addi r1, r1, 0xc0 + blr +} + +static void ReverbHICallbackDpl2(s32* l, s32* r, s32* ls, s32* rs, AXFX_REVHI_WORK_DPL2* rv) { + HandleReverbDpl2(l, rv, 0); + HandleReverbDpl2(r, rv, 1); + HandleReverbDpl2(ls, rv, 2); + HandleReverbDpl2(rs, rv, 3); +} + +static void ReverbHIDpl2Free(AXFX_REVHI_WORK_DPL2* rv) { + u8 i; + + for (i = 0; i < 12; i++) { + if (rv->AP[i].inputs != 0) { + DLdeleteDpl2(&rv->AP[i]); + rv->AP[i].inputs = 0; + } + } + + for (i = 0; i < 12; i++) { + if (rv->C[i].inputs != 0) { + DLdeleteDpl2(&rv->C[i]); + rv->C[i].inputs = 0; + } + } + + if (rv->preDelayTime) { + for (i = 0; i < 4; i++) { + if (rv->preDelayLine[i] != 0) { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = 0; + } + } + } +} + +int AXFXReverbHiInitDpl2(AXFX_REVERBHI_DPL2* reverb) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + reverb->tempDisableFX = 0; + ret = ReverbHICreateDpl2(&reverb->rv, reverb->coloration, reverb->time, reverb->mix, reverb->damping, reverb->preDelay); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbHiShutdownDpl2(AXFX_REVERBHI_DPL2* reverb) { + BOOL old; + + old = OSDisableInterrupts(); + ReverbHIDpl2Free(&reverb->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbHiSettingsDpl2(AXFX_REVERBHI_DPL2* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbHIModifyDpl2(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbHiCallbackDpl2(AXFX_BUFFERUPDATE_DPL2* bufferUpdate, AXFX_REVERBHI_DPL2* reverb) { + ASSERTMSGLINE(1399, AXGetMode() == 2, "AX mode isn't AX_MODE_DPL2. AX mode must be AX_MODE_DPL2 for using AXFXReverbHiCallbackDpl2"); + + if (reverb->tempDisableFX == 0) { + HandleReverbDpl2(bufferUpdate->L, &reverb->rv, 0); + HandleReverbDpl2(bufferUpdate->R, &reverb->rv, 1); + HandleReverbDpl2(bufferUpdate->Ls, &reverb->rv, 2); + HandleReverbDpl2(bufferUpdate->Rs, &reverb->rv, 3); + } +} diff --git a/dolphin sdk not yet linked/src/axfx/reverb_std.c b/dolphin sdk not yet linked/src/axfx/reverb_std.c new file mode 100644 index 0000000..6703890 --- /dev/null +++ b/dolphin sdk not yet linked/src/axfx/reverb_std.c @@ -0,0 +1,501 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__axfx.h" + +// prototypes +static void DLsetdelay(AXFX_REVSTD_DELAYLINE* dl, s32 lag); +static int DLcreate(AXFX_REVSTD_DELAYLINE* dl, s32 max_length); +static void DLdelete(AXFX_REVSTD_DELAYLINE* dl); +static int ReverbSTDCreate(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay); +static int ReverbSTDModify(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay); +static void HandleReverb(s32* sptr, AXFX_REVSTD_WORK* rv); +static void ReverbSTDCallback(s32* left, s32* right, s32* surround, AXFX_REVSTD_WORK* rv); +static void ReverbSTDFree(AXFX_REVSTD_WORK* rv); + +static void DLsetdelay(AXFX_REVSTD_DELAYLINE* dl, s32 lag) { + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) { + dl->outPoint += dl->length; + } +} + +static int DLcreate(AXFX_REVSTD_DELAYLINE* dl, s32 max_length) { + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length * 4); + ASSERTMSGLINE(49, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) { + return 0; + } + + memset(dl->inputs, 0, max_length * 4); + dl->lastOutput = 0.0f; + DLsetdelay(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdelete(AXFX_REVSTD_DELAYLINE* dl) { + __AXFXFree(dl->inputs); +} + +// NONMATCHING RELEASE - regalloc +static int ReverbSTDCreate(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay) { + u8 i; + u8 k; + static s32 lens[4] = { + 0x000006FD, + 0x000007CF, + 0x000001B1, + 0x00000095, + }; + + ASSERTMSGLINE(109, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + predelay >= 0.0f && predelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (predelay < 0.0f ) || (predelay > 0.1f )) { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVSTD_WORK)); + + for (k = 0; k < 3; k++) { + for (i = 0; i < 2; i++) { + if (DLcreate(&rv->C[i + (k * 2)], lens[i] + 2) == 0) { + ReverbSTDFree(rv); + return 0; + } + DLsetdelay(&rv->C[i + (k * 2)], lens[i]); + rv->combCoef[i + (k * 2)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) { + if (DLcreate(&rv->AP[i + (k * 2)], lens[i + 2] + 2) == 0) { + ReverbSTDFree(rv); + return 0; + } + DLsetdelay(&rv->AP[i + (k * 2)], lens[i + 2]); + } + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + if (0.0f != predelay) { + rv->preDelayTime = (32000.0f * predelay); + for (i = 0; i < 3; i++) { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(162, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) { + ReverbSTDFree(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } else { + rv->preDelayTime = 0; + for (i = 0; i < 3; i++) { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbSTDModify(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay) { + u8 i; + + ASSERTMSGLINE(196, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + predelay >= 0.0f && predelay <= 0.1f, + "The value of specified parameter is out of range."); + + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (predelay < 0.0f ) || (predelay > 0.1f )) { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 6; i++) { + DLdelete(&rv->AP[i]); + } + + for (i = 0; i < 6; i++) { + DLdelete(&rv->C[i]); + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbSTDCreate(rv, coloration, time, mix, damping, predelay); +} + +const static f32 value0_3 = 0.3f; +const static f32 value0_6 = 0.6f; +const static double i2fMagic = 4503601774854144.0; + +asm static void HandleReverb(register s32* sptr, register AXFX_REVSTD_WORK* rv) { + nofralloc + stwu r1, -144(r1) + stmw r17, 8(r1) + stfd f14, 88(r1) + stfd f15, 96(r1) + stfd f16, 104(r1) + stfd f17, 112(r1) + stfd f18, 120(r1) + stfd f19, 128(r1) + stfd f20, 136(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, AXFX_REVSTD_WORK.allPassCoeff(rv) + lfs f11, AXFX_REVSTD_WORK.damping(rv) + lfs f8, AXFX_REVSTD_WORK.level(rv) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + lis r30, 0x4330 // 176.0f (0x43300000) + stw r30, 80(r1) + li r5, 0 +L_00000638: + slwi r31, r5, 3 + add r31, r31, rv + lfs f19, AXFX_REVSTD_WORK.combCoef[0](r31) + lfs f20, AXFX_REVSTD_WORK.combCoef[1](r31) + slwi r31, r5, 2 + add r31, r31, rv + lfs f7, AXFX_REVSTD_WORK.lpLastout[0](r31) + lwz r27, AXFX_REVSTD_WORK.preDelayLine[0](r31) + lwz r28, AXFX_REVSTD_WORK.preDelayPtr[0](r31) + lwz r31, AXFX_REVSTD_WORK.preDelayTime(rv) + subi r22, r31, 1 + slwi r22, r22, 2 + add r22, r22, r27 + cmpwi cr7, r31, 0 + mulli r31, r5, 0x28 // sizeof(AXFX_REVSTD_DELAYLINE * 2) + addi r29, rv, AXFX_REVSTD_WORK.C + add r29, r29, r31 + addi r30, rv, AXFX_REVSTD_WORK.AP + add r30, r30, r31 + lwz r21, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r29) // C array + 0 + lwz r20, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r29) // C array + 0 + lwz r19, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r29) // C array + 1 + lwz r18, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r29) // C array + 1 + lfs f15, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r29) // C array + 0 + lfs f16, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r29) // C array + 1 + lwz r26, AXFX_REVSTD_DELAYLINE.length + 0x00(r29) // C array + 0 + lwz r25, AXFX_REVSTD_DELAYLINE.length + 0x14(r29) // C array + 1 + lwz r7, AXFX_REVSTD_DELAYLINE.inputs + 0x00(r29) // C array + 0 + lwz r8, AXFX_REVSTD_DELAYLINE.inputs + 0x14(r29) // C array + 1 + lwz r12, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r30) // AP array + 0 + lwz r11, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r30) // AP array + 0 + lwz r10, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r30) // AP array + 1 + lwz r9, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r30) // AP array + 1 + lfs f17, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r30) // AP array + 0 + lfs f18, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r30) // AP array + 1 + lwz r24, AXFX_REVSTD_DELAYLINE.length + 0x00(r30) // AP array + 0 + lwz r23, AXFX_REVSTD_DELAYLINE.length + 0x14(r30) // AP array + 1 + lwz r17, AXFX_REVSTD_DELAYLINE.inputs + 0x00(r30) // AP array + 0 + lwz r6, AXFX_REVSTD_DELAYLINE.inputs + 0x14(r30) // AP array + 1 + lwz r30, 0(sptr) + xoris r30, r30, 0x8000 + stw r30, 84(r1) + lfd f12, 80(r1) + fsubs f12, f12, f5 + li r31, 159 + mtctr r31 +L_000006F0: + fmr f13, f12 + beq cr7, L_00000710 + lfs f13, 0(r28) + addi r28, r28, 4 + cmpw r28, r22 + stfs f12, -4(r28) + bne+ L_00000710 + mr r28, r27 +L_00000710: + fmadds f8, f19, f15, f13 + lwzu r29, 4(sptr) + fmadds f9, f20, f16, f13 + stfsx f8, r7, r21 + addi r21, r21, 4 + stfsx f9, r8, r19 + lfsx f14, r7, r20 + addi r20, r20, 4 + lfsx f16, r8, r18 + cmpw r21, r26 + cmpw cr1, r20, r26 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f15, f14 + cmpw cr5, r19, r25 + fadds f14, f14, f16 + cmpw cr6, r18, r25 + bne+ L_0000075C + li r21, 0 +L_0000075C: + xoris r29, r29, 0x8000 + fmadds f9, f2, f17, f14 + bne+ cr1, L_0000076C + li r20, 0 +L_0000076C: + stw r29, 84(r1) + bne+ cr5, L_00000778 + li r19, 0 +L_00000778: + stfsx f9, r17, r12 + fnmsubs f14, f2, f9, f17 + addi r12, r12, 4 + bne+ cr6, L_0000078C + li r18, 0 +L_0000078C: + lfsx f17, r17, r11 + cmpw cr5, r12, r24 + addi r11, r11, 4 + cmpw cr6, r11, r24 + bne+ cr5, L_000007A4 + li r12, 0 +L_000007A4: + bne+ cr6, L_000007AC + li r11, 0 +L_000007AC: + fmuls f14, f14, f6 + lfd f10, 80(r1) + fmadds f14, f11, f7, f14 + fmadds f9, f2, f18, f14 + fmr f7, f14 + stfsx f9, r6, r10 + fnmsubs f14, f2, f9, f18 + fmuls f8, f4, f12 + lfsx f18, r6, r9 + addi r10, r10, 4 + addi r9, r9, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r10, r23 + cmpw cr6, r9, r23 + fctiwz f14, f14 + bne+ cr5, L_000007F0 + li r10, 0 +L_000007F0: + bne+ cr6, L_000007F8 + li r9, 0 +L_000007F8: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, sptr, r31 + bdnz L_000006F0 + fmr f13, f12 + beq cr7, L_00000828 + lfs f13, 0(r28) + addi r28, r28, 4 + cmpw r28, r22 + stfs f12, -4(r28) + bne+ L_00000828 + mr r28, r27 +L_00000828: + fmadds f8, f19, f15, f13 + fmadds f9, f20, f16, f13 + stfsx f8, r7, r21 + addi r21, r21, 4 + stfsx f9, r8, r19 + lfsx f14, r7, r20 + addi r20, r20, 4 + lfsx f16, r8, r18 + cmpw r21, r26 + cmpw cr1, r20, r26 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f15, f14 + cmpw cr5, r19, r25 + fadds f14, f14, f16 + cmpw cr6, r18, r25 + bne+ L_00000870 + li r21, 0 +L_00000870: + fmadds f9, f2, f17, f14 + bne+ cr1, L_0000087C + li r20, 0 +L_0000087C: + bne+ cr5, L_00000884 + li r19, 0 +L_00000884: + stfsx f9, r17, r12 + fnmsubs f14, f2, f9, f17 + addi r12, r12, 4 + bne+ cr6, L_00000898 + li r18, 0 +L_00000898: + lfsx f17, r17, r11 + cmpw cr5, r12, r24 + addi r11, r11, 4 + cmpw cr6, r11, r24 + bne+ cr5, L_000008B0 + li r12, 0 +L_000008B0: + bne+ cr6, L_000008B8 + li r11, 0 +L_000008B8: + fmuls f14, f14, f6 + fmadds f14, f11, f7, f14 + mulli r31, r5, 0x28 // sizeof(AXFX_REVSTD_DELAYLINE * 2) + fmadds f9, f2, f18, f14 + fmr f7, f14 + addi r29, rv, AXFX_REVSTD_WORK.C + add r29, r29, r31 + stfsx f9, r6, r10 + fnmsubs f14, f2, f9, f18 + fmuls f8, f4, f12 + lfsx f18, r6, r9 + addi r10, r10, 4 + addi r9, r9, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r10, r23 + cmpw cr6, r9, r23 + fctiwz f14, f14 + bne+ cr5, L_00000904 + li r10, 0 +L_00000904: + bne+ cr6, L_0000090C + li r9, 0 +L_0000090C: + addi r30, rv, AXFX_REVSTD_WORK.AP + add r30, r30, r31 + stfiwx f14, r0, sptr + stw r21, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r29) // C array + 0 + stw r20, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r29) // C array + 0 + stw r19, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r29) // C array + 1 + stw r18, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r29) // C array + 1 + addi sptr, sptr, 4 + stfs f15, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r29) // C array + 0 + stfs f16, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r29) // C array + 1 + slwi r31, r5, 2 + add r31, r31, rv + addi r5, r5, 1 + stw r12, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r30) // AP array + 0 + stw r11, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r30) // AP array + 0 + stw r10, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r30) // AP array + 1 + stw r9, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r30) // AP array + 1 + cmpwi r5, 3 + stfs f17, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r30) // AP array + 0 + stfs f18, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r30) // AP array + 1 + stfs f7, AXFX_REVSTD_WORK.lpLastout(r31) + stw r28, AXFX_REVSTD_WORK.preDelayPtr(r31) + bne L_00000638 + lfd f14, 88(r1) + lfd f15, 96(r1) + lfd f16, 104(r1) + lfd f17, 112(r1) + lfd f18, 120(r1) + lfd f19, 128(r1) + lfd f20, 136(r1) + lmw r17, 8(r1) + addi r1, r1, 144 + blr +} + +static void ReverbSTDCallback(s32* left, s32* right, s32* surround, AXFX_REVSTD_WORK* rv) { + HandleReverb(left, rv); +} + +static void ReverbSTDFree(AXFX_REVSTD_WORK* rv) { + u8 i; + + for (i = 0; i < 6; i++) { + if (rv->AP[i].inputs != 0) { + DLdelete(&rv->AP[i]); + rv->AP[i].inputs = NULL; + } + } + + for (i = 0; i < 6; i++) { + if (rv->C[i].inputs != 0) { + DLdelete(&rv->C[i]); + rv->C[i].inputs = NULL; + } + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + if (rv->preDelayLine[i] != 0) { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = NULL; + } + } + } +} + +int AXFXReverbStdInit(AXFX_REVERBSTD* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 0; + ret = ReverbSTDCreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbStdShutdown(AXFX_REVERBSTD* rev) { + BOOL old; + + old = OSDisableInterrupts(); + ReverbSTDFree(&rev->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbStdSettings(AXFX_REVERBSTD* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbSTDModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbStdCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBSTD* reverb) { + if (reverb->tempDisableFX == 0) { + ReverbSTDCallback(bufferUpdate->left, bufferUpdate->right, bufferUpdate->surround, &reverb->rv); + } +} diff --git a/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/dolphin sdk not yet linked/src/card/CARDDelete.c b/dolphin sdk not yet linked/src/card/CARDDelete.c new file mode 100644 index 0000000..0acf24b --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDDelete.c @@ -0,0 +1,108 @@ +#include + +#include "__card.h" + +// prototypes +static void DeleteCallback(s32 chan, s32 result); + +static void DeleteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = NULL; + + if (result < 0) + goto error; + + result = __CARDFreeBlock(chan, card->startBlock, callback); + if (result < 0) + goto error; + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) + callback(chan, result); +} + +s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + + ASSERTLINE(133, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(134, 0 <= chan && chan < 2); + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo) + return CARD_RESULT_FATAL_ERROR; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) + return __CARDPutControlBlock(card, result); + + if (__CARDIsOpened(card, fileNo)) + return __CARDPutControlBlock(card, CARD_RESULT_BUSY); + + card->startBlock = ent->startBlock; + memset(ent, 0xff, sizeof(CARDDir)); + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + result = __CARDUpdateDir(chan, DeleteCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; +} + +s32 CARDFastDelete(s32 chan, s32 fileNo) { + s32 result = CARDFastDeleteAsync(chan, fileNo, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} + +s32 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback) { + CARDControl* card; + s32 fileNo; + s32 result; + CARDDir* dir; + CARDDir* ent; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + result = __CARDGetFileNo(card, fileName, &fileNo); + if (result < 0) + return __CARDPutControlBlock(card, result); + if (__CARDIsOpened(card, fileNo)) + return __CARDPutControlBlock(card, CARD_RESULT_BUSY); + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + card->startBlock = ent->startBlock; + memset(ent, 0xff, sizeof(CARDDir)); + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + result = __CARDUpdateDir(chan, DeleteCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; +} + +s32 CARDDelete(s32 chan, const char* fileName) { + s32 result = CARDDeleteAsync(chan, fileName, __CARDSyncCallback); + if (result < 0) + return result; + + return __CARDSync(chan); +} diff --git a/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/dolphin sdk not yet linked/src/card/CARDStatEx.c b/dolphin sdk not yet linked/src/card/CARDStatEx.c new file mode 100644 index 0000000..681dbd5 --- /dev/null +++ b/dolphin sdk not yet linked/src/card/CARDStatEx.c @@ -0,0 +1,124 @@ +#include +#include + +#include "__card.h" + +s32 __CARDGetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent) { + ASSERTLINE(85, 0 <= chan && chan < 2); + ASSERTLINE(86, 0 <= fileNo && fileNo < CARD_MAX_FILE); + + if ((fileNo < 0) || (fileNo >= CARD_MAX_FILE)) { + return CARD_RESULT_FATAL_ERROR; + } + + { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result = __CARDGetControlBlock(chan, &card); + + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsReadable(card, ent); + if (result >= 0) { + memcpy(dirent, ent, 0x40); + } + return __CARDPutControlBlock(card, result); + } +} + +s32 __CARDSetStatusExAsync(s32 chan, s32 fileNo, CARDDir* dirent, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u8* p; + s32 i; + + ASSERTLINE(142, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(143, 0 <= chan && chan < 2); + ASSERTLINE(144, *dirent->fileName != 0xff && *dirent->fileName != 0x00); + + ASSERTMSGLINE(152, dirent->iconAddr == 0xffffffff || dirent->iconAddr < CARD_READ_SIZE, "CARDSetStatus[Async](): stat->iconAddr must be 0xffffffff or less than CARD_READ_SIZE."); + ASSERTMSGLINE(155, dirent->commentAddr == 0xffffffff || (dirent->commentAddr & 0x1FFF) <= 8128, "CARDSetStatus[Async](): comment strings (set by stat->commentAddr) must not cross 8KB byte boundary."); + + if ((fileNo < 0) || (fileNo >= CARD_MAX_FILE) || ((u8) dirent->fileName[0] == 0xFF) || ((u8) dirent->fileName[0] == 0)) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + for (p = dirent->fileName; p < (u8*)&dirent->time; p++) { + if (*p != 0) { + continue; + } + while ((++p) < (u8*)&dirent->time) { + *p = 0; + } + break; + } + + if (dirent->permission & 0x20) { + memset(dirent->gameName, 0, sizeof(dirent->gameName)); + memset(dirent->company, 0, sizeof(dirent->company)); + } + + if (dirent->permission & 0x40) { + memset(dirent->gameName, 0, sizeof(dirent->gameName)); + } + + if ((memcmp(&ent->fileName, &dirent->fileName, 32) != 0) || (memcmp(ent->gameName, dirent->gameName, 4) != 0) || (memcmp(ent->company, dirent->company, 2) != 0)) { + for(i = 0; i < CARD_MAX_FILE; i++) { + if (i != fileNo) { + CARDDir* ent = &dir[i]; // sure, just redeclare ent again... + if (((u8) ent->gameName[0] != 0xFF) + && (memcmp(&ent->gameName, &dirent->gameName, 4) == 0) + && (memcmp(&ent->company, &dirent->company, 2) == 0) + && (memcmp(&ent->fileName, &dirent->fileName, 0x20) == 0)) { + return __CARDPutControlBlock(card, -7); + } + } + } + memcpy(&ent->fileName, &dirent->fileName, 0x20); + memcpy(&ent->gameName, &dirent->gameName, 4); + memcpy(&ent->company, &dirent->company, 2); + } + + ent->time = dirent->time; + ent->bannerFormat = dirent->bannerFormat; + ent->iconAddr = dirent->iconAddr; + ent->iconFormat = dirent->iconFormat; + ent->iconSpeed = dirent->iconSpeed; + ent->commentAddr = dirent->commentAddr; + ent->permission = dirent->permission; + ent->copyTimes = dirent->copyTimes; + + result = __CARDUpdateDir(chan, callback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 __CARDSetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent) { + s32 result = __CARDSetStatusExAsync(chan, fileNo, dirent, &__CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/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/dolphin sdk not yet linked/src/mix/mix.c b/dolphin sdk not yet linked/src/mix/mix.c new file mode 100644 index 0000000..1ec6539 --- /dev/null +++ b/dolphin sdk not yet linked/src/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/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/dolphin sdk not yet linked/src/os/OSExec.c b/dolphin sdk not yet linked/src/os/OSExec.c new file mode 100644 index 0000000..9033bc4 --- /dev/null +++ b/dolphin sdk not yet linked/src/os/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/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/dolphin sdk not yet linked/src/os/OSSemaphore.c b/dolphin sdk not yet linked/src/os/OSSemaphore.c new file mode 100644 index 0000000..c58e20d --- /dev/null +++ b/dolphin sdk not yet linked/src/os/OSSemaphore.c @@ -0,0 +1,56 @@ +#include +#include + +void OSInitSemaphore(OSSemaphore* sem, s32 count) { + BOOL enabled = OSDisableInterrupts(); + + OSInitThreadQueue(&sem->queue); + sem->count = count; + OSRestoreInterrupts(enabled); +} + +s32 OSWaitSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + + while((sem->count = (count = sem->count)) <= 0) { + OSSleepThread(&sem->queue); + } + + sem->count--; + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSTryWaitSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = sem->count; + if (sem->count > 0) { + sem->count = sem->count - 1; + } + + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSSignalSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = sem->count; + sem->count++; + + OSWakeupThread(&sem->queue); + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSGetSemaphoreCount(OSSemaphore* sem) { + return sem->count; +} diff --git a/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 a347550..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 - -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 \ No newline at end of file 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 003fd15..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _MSL_CMATH -#define _MSL_CMATH - -#include - -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 5c1ed6e..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 \ No newline at end of file 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 68e31d1..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 \ No newline at end of file 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/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 deleted file mode 100644 index ff5a515..0000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h +++ /dev/null @@ -1,26 +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 c5dfcbd..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 - -#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 47118e3..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 \ No newline at end of file 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/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/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 b77602b..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 @@ -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 "cmath.h" #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..b7917e5 --- /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 long 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..8ddcb0d --- /dev/null +++ b/include/libc/stdio.h @@ -0,0 +1,34 @@ +#ifndef _STDIO_H_ +#define _STDIO_H_ + +#include + +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..ea14475 --- /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..6d76046 --- /dev/null +++ b/include/libc/string.h @@ -0,0 +1,27 @@ +#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..08bc6c8 --- /dev/null +++ b/include/libc/wchar.h @@ -0,0 +1,10 @@ +#ifndef _WCHAR_H_ +#define _WCHAR_H_ + +#include + +//typedef U8 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..599942a 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 @@ -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/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/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 8ceaf92..8f8be6a 100644 --- a/src/SB/Core/x/xString.h +++ b/src/SB/Core/x/xString.h @@ -2,7 +2,7 @@ #define XSTRING_H #include -#include +#include <../src/dolphin/support/string.c> struct substr { diff --git a/src/SB/Core/x/xWad1.cpp b/src/SB/Core/x/xWad1.cpp index b99666b..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]); @@ -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/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 a630ba3..367b1e8 100644 --- a/src/SB/Core/x/xWad3.h +++ b/src/SB/Core/x/xWad3.h @@ -1,8 +1,9 @@ #ifndef XWAD3_H #define XWAD3_H -#include "stdlib.h" +#include #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/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 ab90cbc..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/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/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