summaryrefslogtreecommitdiff
path: root/arm9/lib/NitroSDK/src
diff options
context:
space:
mode:
authorred031000 <rubenru09@aol.com>2021-07-23 01:11:15 +0100
committerred031000 <rubenru09@aol.com>2021-07-23 01:12:27 +0100
commit5bf13c7f48fe91c7902ce50250bc1a5a2398a2ae (patch)
tree2e91e60bdb7a9174b16d8ca1b532809d4ae2e5b6 /arm9/lib/NitroSDK/src
parentc2d91a2d997afd01fa4f40e1e16d5ee85557c9a8 (diff)
separate out libs to libc, libnns and NitroSDK
Diffstat (limited to 'arm9/lib/NitroSDK/src')
-rw-r--r--arm9/lib/NitroSDK/src/CARD_backup.c159
-rw-r--r--arm9/lib/NitroSDK/src/CARD_common.c181
-rw-r--r--arm9/lib/NitroSDK/src/CARD_pullOut.c105
-rw-r--r--arm9/lib/NitroSDK/src/CARD_request.c76
-rw-r--r--arm9/lib/NitroSDK/src/CARD_rom.c280
-rw-r--r--arm9/lib/NitroSDK/src/CARD_spi.c123
-rw-r--r--arm9/lib/NitroSDK/src/CP_context.c48
-rw-r--r--arm9/lib/NitroSDK/src/CTRDG_backup.c94
-rw-r--r--arm9/lib/NitroSDK/src/CTRDG_common.c350
-rw-r--r--arm9/lib/NitroSDK/src/CTRDG_flash_AT29LV512.c327
-rw-r--r--arm9/lib/NitroSDK/src/FS_archive.c445
-rw-r--r--arm9/lib/NitroSDK/src/FS_command.c77
-rw-r--r--arm9/lib/NitroSDK/src/FS_command_default.c453
-rw-r--r--arm9/lib/NitroSDK/src/FS_file.c244
-rw-r--r--arm9/lib/NitroSDK/src/FS_overlay.c320
-rw-r--r--arm9/lib/NitroSDK/src/FS_rom.c126
-rw-r--r--arm9/lib/NitroSDK/src/FX.c19
-rw-r--r--arm9/lib/NitroSDK/src/FX_atan.c289
-rw-r--r--arm9/lib/NitroSDK/src/FX_cp.c71
-rw-r--r--arm9/lib/NitroSDK/src/FX_mtx22.c28
-rw-r--r--arm9/lib/NitroSDK/src/FX_mtx33.c129
-rw-r--r--arm9/lib/NitroSDK/src/FX_mtx43.c200
-rw-r--r--arm9/lib/NitroSDK/src/FX_mtx44.c166
-rw-r--r--arm9/lib/NitroSDK/src/FX_sincos.c4105
-rw-r--r--arm9/lib/NitroSDK/src/FX_vec.c109
-rw-r--r--arm9/lib/NitroSDK/src/GX.c126
-rw-r--r--arm9/lib/NitroSDK/src/GX_asm.c16
-rw-r--r--arm9/lib/NitroSDK/src/GX_bgcnt.c194
-rw-r--r--arm9/lib/NitroSDK/src/GX_g2.c65
-rw-r--r--arm9/lib/NitroSDK/src/GX_g3.c35
-rw-r--r--arm9/lib/NitroSDK/src/GX_g3_util.c259
-rw-r--r--arm9/lib/NitroSDK/src/GX_g3b.c119
-rw-r--r--arm9/lib/NitroSDK/src/GX_g3imm.c17
-rw-r--r--arm9/lib/NitroSDK/src/GX_g3x.c235
-rw-r--r--arm9/lib/NitroSDK/src/GX_load2d.c223
-rw-r--r--arm9/lib/NitroSDK/src/GX_load3d.c150
-rw-r--r--arm9/lib/NitroSDK/src/GX_state.c25
-rw-r--r--arm9/lib/NitroSDK/src/GX_vramcnt.c578
-rw-r--r--arm9/lib/NitroSDK/src/MATH_crc.c150
-rw-r--r--arm9/lib/NitroSDK/src/MATH_dgt.c16
-rw-r--r--arm9/lib/NitroSDK/src/MATH_pop.c12
-rw-r--r--arm9/lib/NitroSDK/src/MI_dma.c307
-rw-r--r--arm9/lib/NitroSDK/src/MI_dma_card.c24
-rw-r--r--arm9/lib/NitroSDK/src/MI_dma_gxcommand.c155
-rw-r--r--arm9/lib/NitroSDK/src/MI_dma_hblank.c31
-rw-r--r--arm9/lib/NitroSDK/src/MI_init.c11
-rw-r--r--arm9/lib/NitroSDK/src/MI_memory.c339
-rw-r--r--arm9/lib/NitroSDK/src/MI_swap.c16
-rw-r--r--arm9/lib/NitroSDK/src/MI_uncompress.c59
-rw-r--r--arm9/lib/NitroSDK/src/MI_wram.c9
-rw-r--r--arm9/lib/NitroSDK/src/OS_alarm.c254
-rw-r--r--arm9/lib/NitroSDK/src/OS_alloc.c167
-rw-r--r--arm9/lib/NitroSDK/src/OS_arena.c168
-rw-r--r--arm9/lib/NitroSDK/src/OS_cache.c126
-rw-r--r--arm9/lib/NitroSDK/src/OS_context.c92
-rw-r--r--arm9/lib/NitroSDK/src/OS_emulator.c18
-rw-r--r--arm9/lib/NitroSDK/src/OS_entropy.c25
-rw-r--r--arm9/lib/NitroSDK/src/OS_exception.c164
-rw-r--r--arm9/lib/NitroSDK/src/OS_init.c26
-rw-r--r--arm9/lib/NitroSDK/src/OS_interrupt.c141
-rw-r--r--arm9/lib/NitroSDK/src/OS_irqHandler.c143
-rw-r--r--arm9/lib/NitroSDK/src/OS_irqTable.c110
-rw-r--r--arm9/lib/NitroSDK/src/OS_message.c124
-rw-r--r--arm9/lib/NitroSDK/src/OS_mutex.c142
-rw-r--r--arm9/lib/NitroSDK/src/OS_ownerInfo.c29
-rw-r--r--arm9/lib/NitroSDK/src/OS_printf.c492
-rw-r--r--arm9/lib/NitroSDK/src/OS_protectionRegion.c23
-rw-r--r--arm9/lib/NitroSDK/src/OS_protectionUnit.c18
-rw-r--r--arm9/lib/NitroSDK/src/OS_reset.c239
-rw-r--r--arm9/lib/NitroSDK/src/OS_spinLock.c218
-rw-r--r--arm9/lib/NitroSDK/src/OS_system.c77
-rw-r--r--arm9/lib/NitroSDK/src/OS_tcm.c9
-rw-r--r--arm9/lib/NitroSDK/src/OS_terminate_proc.c19
-rw-r--r--arm9/lib/NitroSDK/src/OS_thread.c734
-rw-r--r--arm9/lib/NitroSDK/src/OS_tick.c70
-rw-r--r--arm9/lib/NitroSDK/src/OS_timer.c9
-rw-r--r--arm9/lib/NitroSDK/src/OS_valarm.c30
-rw-r--r--arm9/lib/NitroSDK/src/OS_vramExclusive.c88
-rw-r--r--arm9/lib/NitroSDK/src/PXI_fifo.c185
-rw-r--r--arm9/lib/NitroSDK/src/PXI_init.c8
-rw-r--r--arm9/lib/NitroSDK/src/RTC_convert.c164
-rw-r--r--arm9/lib/NitroSDK/src/RTC_internal.c31
-rw-r--r--arm9/lib/NitroSDK/src/SND_alarm.c40
-rw-r--r--arm9/lib/NitroSDK/src/SND_bank.c174
-rw-r--r--arm9/lib/NitroSDK/src/SND_command.c333
-rw-r--r--arm9/lib/NitroSDK/src/SND_interface.c172
-rw-r--r--arm9/lib/NitroSDK/src/SND_main.c26
-rw-r--r--arm9/lib/NitroSDK/src/SND_util.c238
-rw-r--r--arm9/lib/NitroSDK/src/SND_work.c113
-rw-r--r--arm9/lib/NitroSDK/src/WM_ks.c15
-rw-r--r--arm9/lib/NitroSDK/src/crt0.c378
-rw-r--r--arm9/lib/NitroSDK/src/custom_allocator.c32
-rw-r--r--arm9/lib/NitroSDK/src/version_1_dwc.c5
-rw-r--r--arm9/lib/NitroSDK/src/version_2_wifi.c5
-rw-r--r--arm9/lib/NitroSDK/src/version_3_cps.c5
-rw-r--r--arm9/lib/NitroSDK/src/version_4_ssl.c5
-rw-r--r--arm9/lib/NitroSDK/src/version_5_vct.c5
-rw-r--r--arm9/lib/NitroSDK/src/version_6_backup.c5
98 files changed, 17389 insertions, 0 deletions
diff --git a/arm9/lib/NitroSDK/src/CARD_backup.c b/arm9/lib/NitroSDK/src/CARD_backup.c
new file mode 100644
index 00000000..714ac479
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CARD_backup.c
@@ -0,0 +1,159 @@
+#include "CARD_backup.h"
+#include "function_target.h"
+#include "CARD_common.h"
+#include "CARD_request.h"
+#include "CARD_spi.h"
+#include "OS_cache.h"
+#include "MI_memory.h"
+#include "OS_terminate_proc.h"
+#include "OS_system.h"
+
+extern void OSi_ReferSymbol(void *symbol);
+extern char _SDK_NintendoBackup[];
+
+extern CARDiCommon cardi_common;
+
+static void CARDi_RequestStreamCommandCore(CARDiCommon *p);
+
+ARM_FUNC static void CARDi_RequestStreamCommandCore(CARDiCommon *p)
+{
+ const int req_type = p->req_type;
+ const int req_mode = p->req_mode;
+ const int retry_count = p->req_retry;
+ u32 size = sizeof(p->backup_cache_page_buf);
+
+ OSi_ReferSymbol((void *)_SDK_NintendoBackup);
+
+ if (req_type == CARD_REQ_ERASE_SECTOR_BACKUP)
+ {
+ size = CARD_GetBackupSectorSize();
+ }
+ do
+ {
+ const u32 len = (size < p->len) ? size : p->len;
+ p->cmd->len = len;
+
+ if ((p->flag & CARD_STAT_CANCEL) != 0)
+ {
+ p->flag &= ~CARD_STAT_CANCEL;
+ p->cmd->result = CARD_RESULT_CANCELED;
+ break;
+ }
+ switch (req_mode)
+ {
+ case CARD_REQUEST_MODE_RECV:
+ DC_InvalidateRange(p->backup_cache_page_buf, len);
+ p->cmd->src = (u32)p->src;
+ p->cmd->dest = (u32)p->backup_cache_page_buf;
+ break;
+ case CARD_REQUEST_MODE_SEND:
+ case CARD_REQUEST_MODE_SEND_VERIFY:
+ MI_CpuCopy8((const void *)p->src, p->backup_cache_page_buf, len);
+ DC_FlushRange(p->backup_cache_page_buf, len);
+ DC_WaitWriteBufferEmpty();
+ p->cmd->src = (u32)p->backup_cache_page_buf;
+ p->cmd->dest = (u32)p->dst;
+ break;
+ case CARD_REQUEST_MODE_SPECIAL:
+ p->cmd->src = (u32)p->src;
+ p->cmd->dest = (u32)p->dst;
+ break;
+ }
+
+ if (!CARDi_Request(p, req_type, retry_count))
+ {
+ break;
+ }
+
+ if (req_mode == CARD_REQUEST_MODE_SEND_VERIFY)
+ {
+ if (!CARDi_Request(p, CARD_REQ_VERIFY_BACKUP, 1))
+ {
+ break;
+ }
+ }
+ else if (req_mode == CARD_REQUEST_MODE_RECV)
+ {
+ MI_CpuCopy8(p->backup_cache_page_buf, (void *)p->dst, len);
+ }
+ p->src += len;
+ p->dst += len;
+ p->len -= len;
+ }
+ while (p->len > 0);
+ CARDi_EndTask(p, TRUE);
+}
+
+ARM_FUNC BOOL CARDi_RequestStreamCommand(u32 src, u32 dst, u32 len, MIDmaCallback callback, void *arg, BOOL is_async,
+ CARDRequest req_type, int req_retry, CARDRequestMode req_mode)
+{
+ CARDiCommon *const p = &cardi_common;
+
+ OSi_ReferSymbol((void *)_SDK_NintendoBackup);
+
+ CARDi_WaitTask(p, callback, arg);
+ p->src = src;
+ p->dst = dst;
+ p->len = len;
+ p->req_type = req_type;
+ p->req_retry = req_retry;
+ p->req_mode = req_mode;
+ if (is_async)
+ {
+ CARDi_SetTask(CARDi_RequestStreamCommandCore);
+ return TRUE;
+ }
+ else
+ {
+ cardi_common.cur_th = OS_GetCurrentThread();
+ CARDi_RequestStreamCommandCore(p);
+ return (p->cmd->result == CARD_RESULT_SUCCESS);
+ }
+}
+
+ARM_FUNC u32 CARD_GetBackupSectorSize(void)
+{
+ return cardi_common.cmd->spec.sect_size;
+}
+
+ARM_FUNC BOOL CARD_IdentifyBackup(CARDBackupType type)
+{
+ CARDiCommon *const p = &cardi_common;
+
+ OSi_ReferSymbol((void *)_SDK_NintendoBackup);
+ if (type == CARD_BACKUP_TYPE_NOT_USE)
+ {
+ OS_Terminate();
+ }
+
+ CARD_CheckEnabled();
+
+ CARDi_WaitTask(p, NULL, NULL);
+ CARDi_IdentifyBackupCore(type);
+ cardi_common.cur_th = OS_GetCurrentThread();
+ (void)CARDi_Request(p, CARD_REQ_IDENTIFY, 1);
+
+ p->cmd->src = 0;
+ p->cmd->dest = (u32)p->backup_cache_page_buf;
+ p->cmd->len = 1;
+ (void)CARDi_Request(p, CARD_REQ_READ_BACKUP, 1);
+ CARDi_EndTask(p, TRUE);
+ return (p->cmd->result == CARD_RESULT_SUCCESS);
+}
+
+ARM_FUNC BOOL CARD_WaitBackupAsync(void)
+{
+ return CARDi_WaitAsync();
+}
+
+ARM_FUNC BOOL CARD_TryWaitBackupAsync(void)
+{
+ return CARDi_TryWaitAsync();
+}
+
+ARM_FUNC void CARD_CancelBackupAsync(void)
+{
+ OSIntrMode bak_cpsr = OS_DisableInterrupts();
+ cardi_common.flag |= CARD_STAT_CANCEL;
+ (void)OS_RestoreInterrupts(bak_cpsr);
+}
diff --git a/arm9/lib/NitroSDK/src/CARD_common.c b/arm9/lib/NitroSDK/src/CARD_common.c
new file mode 100644
index 00000000..fd66c7ce
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CARD_common.c
@@ -0,0 +1,181 @@
+#include "CARD_common.h"
+#include "CARD_request.h"
+#include "consts.h"
+#include "function_target.h"
+#include "MI_memory.h"
+#include "OS_terminate_proc.h"
+#include "OS_spinLock.h"
+#include "OS_cache.h"
+#include "MB_mb.h"
+#include "PXI_fifo.h"
+#include "mmap.h"
+
+CARDiCommon cardi_common ALIGN(32);
+static CARDiCommandArg cardi_arg ALIGN(32);
+
+u8 cardi_thread_stack[0x400] ALIGN(4);
+
+static void CARDi_LockResource(CARDiOwner owner, CARDTargetMode target);
+static void CARDi_UnlockResource(CARDiOwner owner, CARDTargetMode target);
+
+ARM_FUNC void CARDi_SetTask(void (*task) (CARDiCommon *))
+{
+ CARDiCommon *const p = &cardi_common;
+
+ (void)OS_SetThreadPriority(p->thread, p->priority);
+
+ p->cur_th = p->thread;
+ p->task_func = task;
+ p->flag |= CARD_STAT_TASK;
+ OS_WakeupThreadDirect(p->thread);
+}
+
+ARM_FUNC static void CARDi_LockResource(CARDiOwner owner, CARDTargetMode target)
+{
+ CARDiCommon *const p = &cardi_common;
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (p->lock_owner == owner)
+ {
+ if (p->lock_target != target)
+ {
+ OS_Terminate();
+ }
+ }
+ else
+ {
+ while (p->lock_owner != OS_LOCK_ID_ERROR)
+ {
+ OS_SleepThread(p->lock_queue);
+ }
+ p->lock_owner = owner;
+ p->lock_target = target;
+ }
+ ++p->lock_ref;
+ p->cmd->result = CARD_RESULT_SUCCESS;
+ (void)OS_RestoreInterrupts(bak_psr);
+}
+
+ARM_FUNC static void CARDi_UnlockResource(CARDiOwner owner, CARDTargetMode target)
+{
+ CARDiCommon *p = &cardi_common;
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if ((p->lock_owner != owner) || !p->lock_ref)
+ {
+ OS_Terminate();
+ }
+ else
+ {
+ if (p->lock_target != target)
+ {
+ OS_Terminate();
+ }
+ if (!--p->lock_ref)
+ {
+ p->lock_owner = OS_LOCK_ID_ERROR;
+ p->lock_target = CARD_TARGET_NONE;
+ OS_WakeupThread(p->lock_queue);
+ }
+ }
+ p->cmd->result = CARD_RESULT_SUCCESS;
+ (void)OS_RestoreInterrupts(bak_psr);
+}
+
+ARM_FUNC void CARDi_InitCommon(void)
+{
+ CARDiCommon *p = &cardi_common;
+
+ p->lock_owner = OS_LOCK_ID_ERROR;
+ p->lock_ref = 0;
+ p->lock_target = CARD_TARGET_NONE;
+
+ p->cmd = &cardi_arg;
+ MI_CpuFillFast(&cardi_arg, 0x00, sizeof(cardi_arg));
+ DC_FlushRange(&cardi_arg, sizeof(cardi_arg));
+
+ if (!MB_IsMultiBootChild())
+ {
+ MI_CpuCopy8((const void *)HW_ROM_HEADER_BUF, (void *)HW_CARD_ROM_HEADER, HW_CARD_ROM_HEADER_SIZE);
+ }
+ OS_InitThreadQueue(p->lock_queue);
+ OS_InitThreadQueue(p->busy_q);
+ p->priority = CARD_THREAD_PRIORITY_DEFAULT;
+ OS_CreateThread(p->thread, CARDi_TaskThread, NULL, cardi_thread_stack + sizeof(cardi_thread_stack),
+ sizeof(cardi_thread_stack), p->priority);
+ OS_WakeupThreadDirect(p->thread);
+
+ PXI_SetFifoRecvCallback(PXI_FIFO_TAG_FS, CARDi_OnFifoRecv);
+
+ if (!MB_IsMultiBootChild())
+ {
+ CARD_Enable(TRUE);
+ }
+}
+
+static BOOL CARDi_EnableFlag = FALSE;
+
+ARM_FUNC BOOL CARD_IsEnabled(void)
+{
+ return CARDi_EnableFlag;
+}
+
+ARM_FUNC void CARD_CheckEnabled(void)
+{
+ if (!CARD_IsEnabled())
+ {
+ OS_Terminate();
+ }
+}
+
+ARM_FUNC void CARD_Enable(BOOL enable)
+{
+ CARDi_EnableFlag = enable;
+}
+
+ARM_FUNC BOOL CARDi_WaitAsync(void)
+{
+ CARDiCommon *const p = &cardi_common;
+
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ while ((p->flag & CARD_STAT_BUSY) != 0)
+ {
+ OS_SleepThread(p->busy_q);
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ return (p->cmd->result == CARD_RESULT_SUCCESS);
+}
+
+ARM_FUNC BOOL CARDi_TryWaitAsync(void)
+{
+ CARDiCommon *const p = &cardi_common;
+
+ return !(p->flag & CARD_STAT_BUSY);
+}
+
+ARM_FUNC CARDResult CARD_GetResultCode(void)
+{
+ CARDiCommon *const p = &cardi_common;
+
+ return p->cmd->result;
+}
+
+ARM_FUNC void CARD_LockRom(u16 lock_id)
+{
+ CARDi_LockResource(lock_id, CARD_TARGET_ROM);
+ (void)OS_TryLockCard(lock_id);
+}
+
+ARM_FUNC void CARD_UnlockRom(u16 lock_id)
+{
+ (void)OS_UnlockCard(lock_id);
+ CARDi_UnlockResource(lock_id, CARD_TARGET_ROM);
+}
+
+ARM_FUNC void CARD_LockBackup(u16 lock_id)
+{
+ CARDi_LockResource(lock_id, CARD_TARGET_BACKUP);
+}
+
+ARM_FUNC void CARD_UnlockBackup(u16 lock_id)
+{
+ CARDi_UnlockResource(lock_id, CARD_TARGET_BACKUP);
+}
diff --git a/arm9/lib/NitroSDK/src/CARD_pullOut.c b/arm9/lib/NitroSDK/src/CARD_pullOut.c
new file mode 100644
index 00000000..d5c7737f
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CARD_pullOut.c
@@ -0,0 +1,105 @@
+#include "function_target.h"
+#include "CARD_common.h"
+#include "CARD_pullOut.h"
+#include "PXI_init.h"
+#include "PXI_fifo.h"
+#include "OS_terminate_proc.h"
+#include "OS_system.h"
+#include "PAD_pad.h"
+#include "SPI_pm.h"
+#include "syscall.h"
+#include "mmap.h"
+
+static CARDPulledOutCallback CARD_UserCallback;
+static BOOL CARDi_IsPulledOutFlag = FALSE;
+
+static void CARDi_PulledOutCallback(PXIFifoTag tag, u32 data, BOOL err);
+static void CARDi_SendtoPxi(u32 data, u32 wait);
+
+ARM_FUNC void CARD_InitPulledOutCallback(void)
+{
+ PXI_Init();
+
+ PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CARD, CARDi_PulledOutCallback);
+
+ CARD_UserCallback = NULL;
+}
+
+ARM_FUNC static void CARDi_PulledOutCallback(PXIFifoTag tag, u32 data, BOOL err)
+{
+#pragma unused(tag, err)
+ u32 command = data & CARD_PXI_COMMAND_MASK;
+
+ if (command == CARD_PXI_COMMAND_PULLED_OUT)
+ {
+ if (!CARDi_IsPulledOutFlag)
+ {
+ BOOL isTerminateImm = TRUE;
+ CARDi_IsPulledOutFlag = TRUE;
+
+ if (CARD_UserCallback)
+ {
+ isTerminateImm = CARD_UserCallback();
+ }
+
+ if (isTerminateImm)
+ {
+ CARD_TerminateForPulledOut();
+ }
+ }
+ }
+ else
+ {
+ OS_Terminate();
+ }
+}
+
+ARM_FUNC BOOL CARD_IsPulledOut(void)
+{
+ return CARDi_IsPulledOutFlag;
+}
+
+ARM_FUNC void CARD_TerminateForPulledOut(void)
+{
+ BOOL should_be_halt = TRUE;
+
+ if (PAD_DetectFold())
+ {
+ u32 res;
+ while ((res = PM_ForceToPowerOff()) == 0x04)
+ {
+ OS_SpinWait(HW_CPU_CLOCK_ARM9 / 100);
+ }
+ if (res == 0)
+ {
+ should_be_halt = FALSE;
+ }
+ }
+
+ if (should_be_halt)
+ {
+ CARDi_SendtoPxi(CARD_PXI_COMMAND_TERMINATE, 1);
+ }
+
+ OS_Terminate();
+}
+
+ARM_FUNC void CARDi_CheckPulledOutCore(u32 id)
+{
+ vu32 iplCardID = *(vu32 *)((*(u16 *)HW_CHECK_DEBUGGER_SW == 0) ? HW_RED_RESERVED : HW_BOOT_CHECK_INFO_BUF);
+
+ if (id != (u32)iplCardID)
+ {
+ OSIntrMode bak_cpsr = OS_DisableInterrupts();
+ CARDi_PulledOutCallback(PXI_FIFO_TAG_CARD, CARD_PXI_COMMAND_PULLED_OUT, FALSE);
+ (void)OS_RestoreInterrupts(bak_cpsr);
+ }
+}
+
+ARM_FUNC static void CARDi_SendtoPxi(u32 data, u32 wait)
+{
+ while (PXI_SendWordByFifo(PXI_FIFO_TAG_CARD, data, FALSE) != PXI_FIFO_SUCCESS)
+ {
+ SVC_WaitByLoop((u32)wait);
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/CARD_request.c b/arm9/lib/NitroSDK/src/CARD_request.c
new file mode 100644
index 00000000..098fe7a5
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CARD_request.c
@@ -0,0 +1,76 @@
+#include "function_target.h"
+#include "CARD_request.h"
+#include "OS_cache.h"
+#include "OS_system.h"
+#include "OS_thread.h"
+
+extern CARDiCommon cardi_common;
+
+ARM_FUNC void CARDi_OnFifoRecv(PXIFifoTag tag, u32 data, BOOL err)
+{
+#pragma unused (data)
+ if ((tag == PXI_FIFO_TAG_FS) && err)
+ {
+ CARDiCommon *const p = &cardi_common;
+ p->flag &= ~CARD_STAT_REQ;
+ OS_WakeupThreadDirect(p->cur_th);
+ }
+}
+
+ARM_FUNC void CARDi_TaskThread(void *arg)
+{
+#pragma unused (arg)
+ CARDiCommon *const p = &cardi_common;
+
+ while (TRUE)
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ while ((p->flag & CARD_STAT_TASK) == 0)
+ {
+ p->cur_th = p->thread;
+ OS_SleepThread(NULL);
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ (*p->task_func)(p);
+ }
+}
+
+ARM_FUNC BOOL CARDi_Request(CARDiCommon *p, s32 req_type, s32 retry_count)
+{
+ if ((p->flag & CARD_STAT_INIT_CMD) == 0)
+ {
+ p->flag |= CARD_STAT_INIT_CMD;
+ while (!PXI_IsCallbackReady(PXI_FIFO_TAG_FS, PXI_PROC_ARM7))
+ {
+ OS_SpinWait(100);
+ }
+
+ (void)CARDi_Request(p, CARD_REQ_INIT, 1);
+ }
+ DC_FlushRange(p->cmd, sizeof(*p->cmd));
+ DC_WaitWriteBufferEmpty();
+
+ do
+ {
+ p->command = req_type;
+ p->flag |= CARD_STAT_REQ;
+ CARDi_SendPxi((u32)req_type);
+
+ switch (req_type)
+ {
+ case CARD_REQ_INIT:
+ CARDi_SendPxi((u32)p->cmd);
+ break;
+ }
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ while ((p->flag & CARD_STAT_REQ) != 0)
+ {
+ OS_SleepThread(NULL);
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ DC_InvalidateRange(p->cmd, sizeof(*p->cmd));
+ }
+ while ((p->cmd->result == CARD_RESULT_TIMEOUT) && (--retry_count > 0));
+
+ return (p->cmd->result == CARD_RESULT_SUCCESS);
+}
diff --git a/arm9/lib/NitroSDK/src/CARD_rom.c b/arm9/lib/NitroSDK/src/CARD_rom.c
new file mode 100644
index 00000000..6d6b1ff8
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CARD_rom.c
@@ -0,0 +1,280 @@
+#include "function_target.h"
+#include "nitro/types.h"
+#include "CARD_pullOut.h"
+#include "CARD_rom.h"
+#include "MI_dma_card.h"
+#include "MI_memory.h"
+#include "OS_cache.h"
+#include "OS_interrupt.h"
+
+extern u32 cardi_rom_base;
+u32 cardi_rom_base;
+u32 cardi_rom_header_addr = HW_ROM_HEADER_BUF;
+
+CARDRomStat rom_stat ALIGN(32);
+
+static BOOL CARDi_ReadFromCache(CARDRomStat *p);
+static void CARDi_SetRomOp(u32 cmd1, u32 cmd2);
+static void CARDi_SetCardDma(void);
+static void CARDi_OnReadCard(void);
+static void CARDi_ReadRomSyncCore(CARDiCommon *c);
+
+static inline BOOL CARDi_OnReadPageDirect(CARDRomStat *arg)
+{
+#pragma unused(arg)
+ CARDiCommon *p = &cardi_common;
+ p->src += CARD_ROM_PAGE_SIZE;
+ p->dst += CARD_ROM_PAGE_SIZE;
+ p->len -= CARD_ROM_PAGE_SIZE;
+ return (p->len > 0);
+}
+
+ARM_FUNC static BOOL CARDi_ReadFromCache(CARDRomStat *p)
+{
+ CARDiCommon *c = &cardi_common;
+ const u32 cur_page = CARD_ALIGN_HI_BIT(c->src);
+ if (cur_page == (u32)p->cache_page)
+ {
+ const u32 mod = c->src - cur_page;
+ u32 len = CARD_ROM_PAGE_SIZE - mod;
+ if (len > c->len)
+ {
+ len = c->len;
+ }
+ MI_CpuCopy8(p->cache_buf + mod, (void *)c->dst, len);
+ c->src += len;
+ c->dst += len;
+ c->len -= len;
+ }
+ return (c->len > 0);
+}
+
+ARM_FUNC static void CARDi_SetRomOp(u32 cmd1, u32 cmd2)
+{
+ while ((reg_CARD_CNT & CARD_START) != 0) {}
+
+ reg_CARD_MASTERCNT = CARDMST_SEL_ROM | CARDMST_ENABLE | CARDMST_IF_ENABLE;
+ {
+ vu8 *const p_cmd = &reg_CARD_CMD;
+ p_cmd[0] = (u8)(cmd1 >> (8 * 3));
+ p_cmd[1] = (u8)(cmd1 >> (8 * 2));
+ p_cmd[2] = (u8)(cmd1 >> (8 * 1));
+ p_cmd[3] = (u8)(cmd1 >> (8 * 0));
+ p_cmd[4] = (u8)(cmd2 >> (8 * 3));
+ p_cmd[5] = (u8)(cmd2 >> (8 * 2));
+ p_cmd[6] = (u8)(cmd2 >> (8 * 1));
+ p_cmd[7] = (u8)(cmd2 >> (8 * 0));
+ }
+}
+
+static inline void CARDi_SetRomOpReadPage1(u32 src)
+{
+ CARDi_SetRomOp((u32)(MROMOP_G_READ_PAGE | (src >> 8)), (u32)(src << 24));
+}
+
+ARM_FUNC static void CARDi_SetCardDma(void)
+{
+ CARDiCommon *const c = &cardi_common;
+ CARDRomStat *const p = &rom_stat;
+ MIi_CardDmaCopy32(c->dma, (const void *)&reg_CARD_DATA, (void *)c->dst, CARD_ROM_PAGE_SIZE);
+ CARDi_SetRomOpReadPage1(c->src);
+ reg_CARD_CNT = p->ctrl;
+}
+
+ARM_FUNC static void CARDi_OnReadCard(void)
+{
+ CARDRomStat *const p = &rom_stat;
+ CARDiCommon *const c = &cardi_common;
+ MI_StopDma(c->dma);
+ if (!CARDi_OnReadPageDirect(p))
+ {
+ (void)OS_DisableIrqMask(OS_IE_CARD_DATA);
+ (void)OS_ResetRequestIrqMask(OS_IE_CARD_DATA);
+ CARDi_ReadEnd();
+ }
+ else
+ {
+ CARDi_SetCardDma();
+ }
+}
+
+ARM_FUNC BOOL CARDi_TryReadCardDma(CARDRomStat *p)
+{
+ CARDiCommon *const c = &cardi_common;
+ const u32 dst = c->dst;
+ u32 len = c->len;
+ const BOOL is_async = !(dst & 31) &&
+ (c->dma <= MI_DMA_MAX_NUM) &&
+ !CARDi_IsInTcm(dst, len) &&
+ !CARD_ALIGN_LO_BIT(c->src | len) &&
+ (len > 0);
+ p->ctrl = CARDi_GetRomFlag(CARD_COMMAND_PAGE);
+ if (is_async)
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ IC_InvalidateRange((void *)dst, len);
+ {
+ u32 pos = dst;
+ u32 mod = (dst & (HW_CACHE_LINE_SIZE - 1));
+ if (mod)
+ {
+ pos -= mod;
+ DC_StoreRange((void *)(pos), HW_CACHE_LINE_SIZE);
+ DC_StoreRange((void *)(pos + len), HW_CACHE_LINE_SIZE);
+ len += HW_CACHE_LINE_SIZE;
+ }
+ DC_InvalidateRange((void *)pos, len);
+ DC_WaitWriteBufferEmpty();
+ }
+ (void)OS_SetIrqFunction(OS_IE_CARD_DATA, CARDi_OnReadCard);
+ (void)OS_ResetRequestIrqMask(OS_IE_CARD_DATA);
+ (void)OS_EnableIrqMask(OS_IE_CARD_DATA);
+ (void)OS_RestoreInterrupts(bak_psr);
+ CARDi_SetCardDma();
+ }
+ return is_async;
+}
+
+ARM_FUNC void CARDi_ReadCard(CARDRomStat *p)
+{
+ CARDiCommon *const c = &cardi_common;
+ while (TRUE)
+ {
+ const u32 len = CARD_ROM_PAGE_SIZE;
+ u32 src = CARD_ALIGN_HI_BIT(c->src);
+ u32 dst;
+ if ((src != c->src) || ((c->dst & 3) != 0) || (c->len < len))
+ {
+ dst = (u32)p->cache_buf;
+ p->cache_page = (void *)src;
+ }
+ else
+ {
+ dst = c->dst;
+ }
+
+ CARDi_SetRomOpReadPage1(src);
+ {
+ u32 pos = 0;
+ reg_CARD_CNT = p->ctrl;
+ while (TRUE)
+ {
+ const u32 ctrl = reg_CARD_CNT;
+ if ((ctrl & CARD_DATA_READY) != 0)
+ {
+ u32 data = reg_CARD_DATA;
+ if (pos < len)
+ {
+ ((u32 *)dst)[pos++] = data;
+ }
+ }
+ if (!(ctrl & CARD_START))
+ {
+ break;
+ }
+ }
+ }
+ if (dst == c->dst)
+ {
+ if (!CARDi_OnReadPageDirect(p))
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (!CARDi_ReadFromCache(p))
+ {
+ break;
+ }
+ }
+ }
+}
+
+ARM_FUNC u32 CARDi_ReadRomIDCore(void)
+{
+ CARDi_SetRomOp(MROMOP_G_READ_ID, 0);
+ reg_CARD_CNT = (u32)(CARDi_GetRomFlag(CARD_COMMAND_ID) & ~CARD_LATENCY1_MASK);
+ while (!(reg_CARD_CNT & CARD_DATA_READY)) {}
+ return reg_CARD_DATA;
+}
+
+ARM_FUNC static void CARDi_ReadRomSyncCore(CARDiCommon *c)
+{
+#pragma unused(c)
+ CARDRomStat *const p = &rom_stat;
+
+ if (CARDi_ReadFromCache(p))
+ {
+ (*p->read_func) (p);
+ }
+ CARDi_ReadEnd();
+}
+
+ARM_FUNC void CARDi_ReadRom(u32 dma, const void *src, void *dst, u32 len, MIDmaCallback callback, void *arg, BOOL is_async)
+{
+ CARDRomStat *const p = &rom_stat;
+ CARDiCommon *const c = &cardi_common;
+
+ CARD_CheckEnabled();
+
+ CARDi_WaitTask(c, callback, arg);
+
+ c->dma = dma;
+ c->src = (u32)((u32)src + cardi_rom_base);
+ c->dst = (u32)dst;
+ c->len = (u32)len;
+ if (dma <= MI_DMA_MAX_NUM)
+ {
+ MI_StopDma(dma);
+ }
+
+ if (CARDi_TryReadCardDma(p))
+ {
+ if (!is_async)
+ {
+ CARD_WaitRomAsync();
+ }
+ }
+ else if (is_async)
+ {
+ CARDi_SetTask(CARDi_ReadRomSyncCore);
+ }
+ else
+ {
+ c->cur_th = OS_GetCurrentThread();
+ CARDi_ReadRomSyncCore(c);
+ }
+}
+
+ARM_FUNC void CARD_Init(void)
+{
+ CARDiCommon *const p = &cardi_common;
+
+ if (!p->flag)
+ {
+ p->flag = CARD_STAT_INIT;
+ p->src = p->dst = p->len = 0;
+ p->dma = (u32)~0;
+ p->callback = NULL;
+ p->callback_arg = NULL;
+
+ cardi_rom_base = 0;
+
+ CARDi_InitCommon();
+
+ rom_stat.read_func = CARDi_GetRomAccessor();
+
+ CARD_InitPulledOutCallback();
+ }
+}
+
+ARM_FUNC void CARD_WaitRomAsync(void)
+{
+ (void)CARDi_WaitAsync();
+}
+
+ARM_FUNC void (*CARDi_GetRomAccessor(void)) (CARDRomStat *)
+{
+ return CARDi_ReadCard;
+}
diff --git a/arm9/lib/NitroSDK/src/CARD_spi.c b/arm9/lib/NitroSDK/src/CARD_spi.c
new file mode 100644
index 00000000..5f02b276
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CARD_spi.c
@@ -0,0 +1,123 @@
+#include "function_target.h"
+#include "nitro/types.h"
+#include "CARD_common.h"
+#include "CARD_spi.h"
+#include "MI_memory.h"
+
+extern CARDiCommon cardi_common;
+
+ARM_FUNC void CARDi_IdentifyBackupCore(CARDBackupType type)
+{
+ CARDiCommandArg *const p = cardi_common.cmd;
+
+ MI_CpuFill8(&p->spec, 0, sizeof(p->spec));
+ p->type = type;
+ p->spec.caps = CARD_BACKUP_CAPS_AVAILABLE;
+ if (type != CARD_BACKUP_TYPE_NOT_USE)
+ {
+ const u32 size = (u32)(1 << ((type >> CARD_BACKUP_TYPE_SIZEBIT_SHIFT) & CARD_BACKUP_TYPE_SIZEBIT_MASK));
+
+ const s32 device = ((type >> CARD_BACKUP_TYPE_DEVICE_SHIFT) & CARD_BACKUP_TYPE_DEVICE_MASK);
+
+ p->spec.total_size = size;
+ p->spec.initial_status = 0xFF;
+ if (device == CARD_BACKUP_TYPE_DEVICE_EEPROM)
+ {
+ switch (size)
+ {
+ default:
+ goto invalid_type;
+ case 0x000200: //CARD_BACKUP_TYPE_EEPROM_4KBITS
+ p->spec.page_size = 0x10;
+ p->spec.addr_width = 1;
+ p->spec.program_page = 5;
+ p->spec.initial_status = 0xF0;
+ break;
+ case 0x002000: //CARD_BACKUP_TYPE_EEPROM_64KIBTS
+ p->spec.page_size = 0x0020;
+ p->spec.addr_width = 2;
+ p->spec.program_page = 5;
+ p->spec.initial_status = 0x00;
+ break;
+ case 0x010000: //CARD_BACKUP_TYPE_EEPROM_512KBITS
+ p->spec.page_size = 0x0080;
+ p->spec.addr_width = 2;
+ p->spec.program_page = 10;
+ p->spec.initial_status = 0x00;
+ break;
+ }
+ p->spec.sect_size = p->spec.page_size;
+ p->spec.caps |= CARD_BACKUP_CAPS_READ;
+ p->spec.caps |= CARD_BACKUP_CAPS_PROGRAM;
+ p->spec.caps |= CARD_BACKUP_CAPS_VERIFY;
+ }
+ else if (device == CARD_BACKUP_TYPE_DEVICE_FLASH)
+ {
+ switch (size)
+ {
+ default:
+ goto invalid_type;
+ case 0x040000: //CARD_BACKUP_TYPE_FLASH_2MBITS
+ case 0x080000: //CARD_BACKUP_TYPE_FLASH_4MBITS
+ case 0x100000: //CARD_BACKUP_TYPE_FLASH_8MBITS
+ p->spec.write_page = 25;
+ p->spec.write_page_total = 300;
+ p->spec.erase_page = 300;
+ p->spec.erase_sector = 5000;
+ p->spec.caps |= CARD_BACKUP_CAPS_WRITE;
+ p->spec.caps |= CARD_BACKUP_CAPS_ERASE_PAGE;
+ break;
+ case 0x200000: //CARD_BACKUP_TYPE_FLASH_16MBITS
+ p->spec.erase_sector = 1000;
+ p->spec.erase_sector_total = 3000;
+ p->spec.erase_chip = 17000;
+ p->spec.erase_chip_total = 40000;
+ p->spec.initial_status = 0x00;
+ p->spec.caps |= CARD_BACKUP_CAPS_ERASE_CHIP;
+ break;
+ case 0x800000: //CARD_BACKUP_TYPE_FLASH_64MBITS
+ p->spec.erase_sector = 1000;
+ p->spec.erase_sector_total = 3000;
+ p->spec.erase_chip = 68000;
+ p->spec.erase_chip_total = 160000;
+ p->spec.initial_status = 0x00;
+ p->spec.caps |= CARD_BACKUP_CAPS_ERASE_CHIP;
+ break;
+ }
+ p->spec.sect_size = 0x010000;
+ p->spec.page_size = 0x0100;
+ p->spec.addr_width = 3;
+ p->spec.program_page = 5;
+ p->spec.caps |= CARD_BACKUP_CAPS_READ;
+ p->spec.caps |= CARD_BACKUP_CAPS_PROGRAM;
+ p->spec.caps |= CARD_BACKUP_CAPS_VERIFY;
+ p->spec.caps |= CARD_BACKUP_CAPS_ERASE_SECTOR;
+ }
+ else if (device == CARD_BACKUP_TYPE_DEVICE_FRAM)
+ {
+ switch (size)
+ {
+ default:
+ goto invalid_type;
+ case 0x002000: //CARD_BACKUP_TYPE_FRAM_64KBITS
+ case 0x008000: //CARD_BACKUP_TYPE_FRAM_64KBITS
+ break;
+ }
+ p->spec.page_size = size;
+ p->spec.sect_size = size;
+ p->spec.addr_width = 2;
+ p->spec.initial_status = 0x00;
+ p->spec.caps |= CARD_BACKUP_CAPS_READ;
+ p->spec.caps |= CARD_BACKUP_CAPS_PROGRAM;
+ p->spec.caps |= CARD_BACKUP_CAPS_VERIFY;
+ }
+ else
+ {
+ invalid_type:
+ p->type = CARD_BACKUP_TYPE_NOT_USE;
+ p->spec.total_size = 0;
+ cardi_common.cmd->result = CARD_RESULT_UNSUPPORTED;
+ return;
+ }
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/CP_context.c b/arm9/lib/NitroSDK/src/CP_context.c
new file mode 100644
index 00000000..6567f516
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CP_context.c
@@ -0,0 +1,48 @@
+#include "CP_context.h"
+#include "function_target.h"
+#include "registers.h"
+
+ARM_FUNC asm void CP_SaveContext(register CPContext *context)
+{
+ ldr r1, =REG_DIV_NUMER_ADDR
+ stmfd sp!, {r4}
+ ldmia r1, {r2-r4, r12}
+ stmia r0!, {r2-r4, r12}
+ ldrh r12, [r1, #-16]
+
+ add r1, r1, #40
+ ldmia r1, {r2-r3}
+ stmia r0!, {r2-r3}
+
+ and r12, r12, #3
+ ldrh r2, [r1, #-8]
+ strh r12, [r0]
+ and r2, r2, #1
+ strh r2, [r0, #2]
+ ldmfd sp!, {r4}
+
+ bx lr
+}
+
+ARM_FUNC asm void CPi_RestoreContext(register const CPContext *context)
+{
+ stmfd sp!, {r4}
+ ldr r1, =REG_DIV_NUMER_ADDR
+ ldmia r0, {r2-r4, r12}
+ stmia r1, {r2-r4, r12}
+ ldrh r2, [r0, #24] //CPContext.div_mode
+ ldrh r3, [r0, #26] //CPContext.sqrt_mode
+
+ strh r2, [r1, #-16]
+ strh r3, [r1, #32]
+
+ add r0, r0, #16 //CPContext.sqrt
+ add r1, r1, #40
+
+ ldmia r0, {r2-r3}
+ stmia r1, {r2-r3}
+
+ ldmfd sp!, {r4}
+
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/CTRDG_backup.c b/arm9/lib/NitroSDK/src/CTRDG_backup.c
new file mode 100644
index 00000000..dc1a3f4b
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CTRDG_backup.c
@@ -0,0 +1,94 @@
+#include "CTRDG_backup.h"
+#include "function_target.h"
+#include "OS_spinLock.h"
+
+extern u16 ctrdgi_flash_lock_id;
+extern u16 ctrdgi_sram_lock_id;
+
+extern u16 CTRDGi_ReadFlashID(void);
+
+extern const CTRDGiFlashTypePlus defaultFlash1M;
+extern const CTRDGiFlashTypePlus MX29L010;
+extern const CTRDGiFlashTypePlus LE26FV10N1TS_10;
+
+extern const CTRDGiFlashTypePlus defaultFlash512;
+extern const CTRDGiFlashTypePlus LE39FW512;
+extern const CTRDGiFlashTypePlus AT29LV512_lib;
+extern const CTRDGiFlashTypePlus MN63F805MNP;
+
+static const CTRDGiFlashTypePlus *const flash1M_list[] = {
+ &MX29L010,
+ &LE26FV10N1TS_10,
+ &defaultFlash1M
+};
+
+static const CTRDGiFlashTypePlus *const flash512_list[] = {
+ &LE39FW512,
+ &AT29LV512_lib,
+ &MN63F805MNP,
+ &defaultFlash512
+};
+
+static const u16 readidtime[] = {
+ 20
+};
+
+ARM_FUNC u16 CTRDG_IdentifyAgbBackup(CTRDGBackupType type)
+{
+ u16 result = 1;
+ u16 flashID;
+ const CTRDGiFlashTypePlus *const *flp;
+ MICartridgeRamCycle ram_cycle;
+
+ if (type == CTRDG_BACKUP_TYPE_FLASH_512K || type == CTRDG_BACKUP_TYPE_FLASH_1M)
+ {
+ ctrdgi_flash_lock_id = (u16)OS_GetLockID();
+
+ (void)OS_LockCartridge(ctrdgi_flash_lock_id);
+
+ ram_cycle = MI_GetCartridgeRamCycle();
+ MI_SetCartridgeRamCycle(MI_CTRDG_RAMCYCLE_18);
+
+ ctrdgi_fl_maxtime = readidtime;
+ flashID = CTRDGi_ReadFlashID();
+
+ if (type == CTRDG_BACKUP_TYPE_FLASH_512K)
+ {
+ flp = flash512_list;
+ }
+
+ if (type == CTRDG_BACKUP_TYPE_FLASH_1M)
+ {
+ flp = flash1M_list;
+ }
+
+ MI_SetCartridgeRamCycle(ram_cycle);
+ (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
+
+ result = 1;
+ while ((*flp)->type.makerID != 0)
+ {
+ if ((flashID & 0xff) == *(u16 *)&((*flp)->type.makerID))
+ {
+ result = 0;
+ break;
+ }
+ flp++;
+ }
+ CTRDGi_WriteAgbFlashSector = (*flp)->CTRDGi_WriteAgbFlashSector;
+ CTRDGi_EraseAgbFlashChip = (*flp)->CTRDGi_EraseAgbFlashChip;
+ CTRDGi_EraseAgbFlashSector = (*flp)->CTRDGi_EraseAgbFlashSector;
+ CTRDGi_WriteAgbFlashSectorAsync = (*flp)->CTRDGi_WriteAgbFlashSectorAsync;
+ CTRDGi_EraseAgbFlashChipAsync = (*flp)->CTRDGi_EraseAgbFlashChipAsync;
+ CTRDGi_EraseAgbFlashSectorAsync = (*flp)->CTRDGi_EraseAgbFlashSectorAsync;
+ CTRDGi_PollingSR = (*flp)->CTRDGi_PollingSR;
+ ctrdgi_fl_maxtime = (*flp)->maxtime;
+ AgbFlash = &(*flp)->type;
+ }
+ else if (type == CTRDG_BACKUP_TYPE_SRAM)
+ {
+ ctrdgi_sram_lock_id = (u16)OS_GetLockID();
+ result = 0;
+ }
+ return result;
+}
diff --git a/arm9/lib/NitroSDK/src/CTRDG_common.c b/arm9/lib/NitroSDK/src/CTRDG_common.c
new file mode 100644
index 00000000..df3ec0b6
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CTRDG_common.c
@@ -0,0 +1,350 @@
+#include "CTRDG_common.h"
+#include "function_target.h"
+#include "syscall.h"
+#include "OS_cache.h"
+#include "OS_protectionRegion.h"
+#include "OS_terminate_proc.h"
+#include "PXI_fifo.h"
+#include "MI_dma.h"
+#include "MI_memory.h"
+#include "mmap.h"
+
+CTRDGWork CTRDGi_Work;
+
+static BOOL CTRDGi_EnableFlag = FALSE;
+
+ARM_FUNC void CTRDGi_InitCommon(void)
+{
+ SVC_CpuClear(0, &CTRDGi_Work, sizeof(CTRDGi_Work), 32);
+
+ CTRDGi_Work.lockID = (u16)OS_GetLockID();
+}
+
+ARM_FUNC BOOL CTRDG_IsAgbCartridge(void)
+{
+ return (CTRDG_IsExisting() && CTRDGi_IsAgbCartridgeAtInit());
+}
+
+ARM_FUNC BOOL CTRDG_IsOptionCartridge(void)
+{
+ return (CTRDG_IsExisting() && !CTRDGi_IsAgbCartridgeAtInit());
+}
+
+ARM_FUNC BOOL CTRDGi_IsAgbCartridgeAtInit(void)
+{
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+
+ return cip->isAgbCartridge;
+}
+
+ARM_FUNC u32 CTRDG_GetAgbGameCode(void)
+{
+ u32 ret = 0;
+
+ if (CTRDG_IsExisting())
+ {
+ ret = CTRDGi_GetAgbGameCodeAtInit();
+ }
+
+ return ret;
+}
+
+ARM_FUNC u32 CTRDGi_GetAgbGameCodeAtInit(void)
+{
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+ u32 ret = 0;
+
+ if (CTRDGi_IsAgbCartridgeAtInit())
+ {
+ ret = cip->gameCode;
+ }
+
+ return ret;
+}
+
+ARM_FUNC u16 CTRDG_GetAgbMakerCode(void)
+{
+ u16 ret = 0;
+
+ if (CTRDG_IsExisting())
+ {
+ ret = CTRDGi_GetAgbMakerCodeAtInit();
+ }
+
+ return ret;
+}
+
+ARM_FUNC u16 CTRDGi_GetAgbMakerCodeAtInit(void)
+{
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+ u16 ret = 0;
+
+ if (CTRDGi_IsAgbCartridgeAtInit())
+ {
+ ret = cip->makerCode;
+ }
+
+ return ret;
+}
+
+ARM_FUNC BOOL CTRDG_IsPulledOut(void)
+{
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+
+ if (cip->moduleID.raw == 0xffff)
+ {
+ return FALSE;
+ }
+
+ if (!cip->detectPullOut)
+ {
+ (void)CTRDG_IsExisting();
+ }
+
+ return cip->detectPullOut;
+}
+
+ARM_FUNC BOOL CTRDG_IsExisting(void)
+{
+ BOOL ret = TRUE;
+ CTRDGLockByProc lockInfo;
+
+ CTRDGHeader *chp = CTRDGi_GetHeaderAddr();
+ CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
+
+ if (cip->moduleID.raw == 0xffff)
+ {
+ return FALSE;
+ }
+
+ if (cip->detectPullOut == TRUE)
+ {
+ return FALSE;
+ }
+
+ CTRDGi_LockByProcessor(CTRDGi_Work.lockID, &lockInfo);
+
+ CTRDGRomCycle rc;
+
+ CTRDGi_ChangeLatestAccessCycle(&rc);
+ u8 isRomCode = chp->isRomCode;
+
+ if ((isRomCode == CTRDG_IS_ROM_CODE && cip->moduleID.raw != chp->moduleID)
+ || (isRomCode != CTRDG_IS_ROM_CODE && cip->moduleID.raw != *CTRDGi_GetModuleIDImageAddr())
+ || ((cip->gameCode != chp->gameCode) && cip->isAgbCartridge))
+ {
+ cip->detectPullOut = TRUE;
+ ret = FALSE;
+ }
+
+ CTRDGi_RestoreAccessCycle(&rc);
+
+ CTRDGi_UnlockByProcessor(CTRDGi_Work.lockID, &lockInfo);
+
+ return ret;
+}
+
+ARM_FUNC void CTRDGi_ChangeLatestAccessCycle(CTRDGRomCycle *r)
+{
+ r->c1 = MI_GetCartridgeRomCycle1st();
+ r->c2 = MI_GetCartridgeRomCycle2nd();
+
+ MI_SetCartridgeRomCycle1st(MI_CTRDG_ROMCYCLE1_18);
+ MI_SetCartridgeRomCycle2nd(MI_CTRDG_ROMCYCLE2_6);
+}
+
+ARM_FUNC void CTRDGi_RestoreAccessCycle(CTRDGRomCycle *r)
+{
+ MI_SetCartridgeRomCycle1st(r->c1);
+ MI_SetCartridgeRomCycle2nd(r->c2);
+}
+
+ARM_FUNC void CTRDGi_LockByProcessor(u16 lockID, CTRDGLockByProc *info)
+{
+ while (TRUE)
+ {
+ info->irq = OS_DisableInterrupts();
+ if (((info->locked = OS_ReadOwnerOfLockCartridge() & CTRDG_LOCKED_BY_MYPROC_FLAG) != 0)
+ || (OS_TryLockCartridge(lockID) == OS_LOCK_SUCCESS))
+ {
+ break;
+ }
+ (void)OS_RestoreInterrupts(info->irq);
+
+ SVC_WaitByLoop(1);
+ }
+}
+
+ARM_FUNC void CTRDGi_UnlockByProcessor(u16 lockID, CTRDGLockByProc *info)
+{
+ if (!info->locked)
+ {
+ (void)OS_UnLockCartridge(lockID);
+ }
+
+ (void)OS_RestoreInterrupts(info->irq);
+}
+
+ARM_FUNC void CTRDGi_SendtoPxi(u32 data)
+{
+ while (PXI_SendWordByFifo(PXI_FIFO_TAG_CTRDG, data, FALSE) != PXI_FIFO_SUCCESS)
+ {
+ SVC_WaitByLoop(1);
+ }
+}
+
+ARM_FUNC BOOL CTRDG_CpuCopy8(const void *src, void *dest, u32 size)
+{
+ if (HW_CTRDG_ROM <= (u32)dest && (u32)dest < HW_CTRDG_RAM_END)
+ {
+ return CTRDGi_CopyCommon(0, (const void *)dest, (void *)src, size, CTRDGi_FORWARD_CPU8);
+ }
+ else
+ {
+ return CTRDGi_CopyCommon(0, src, dest, size, CTRDGi_FORWARD_CPU8);
+ }
+}
+
+ARM_FUNC BOOL CTRDG_CpuCopy16(const void *src, void *dest, u32 size)
+{
+ return CTRDGi_CopyCommon(0, src, dest, size, CTRDGi_FORWARD_CPU16);
+}
+
+ARM_FUNC BOOL CTRDG_CpuCopy32(const void *src, void *dest, u32 size)
+{
+ return CTRDGi_CopyCommon(0, src, dest, size, CTRDGi_FORWARD_CPU32);
+}
+
+ARM_FUNC BOOL CTRDGi_CopyCommon(u32 dmaNo, const void *src, void *dest, u32 size, u32 forwardType)
+{
+ if (!CTRDG_IsExisting())
+ {
+ return FALSE;
+ }
+
+ CTRDG_CheckEnabled();
+
+ (void)OS_LockCartridge(CTRDGi_Work.lockID);
+
+ if ((forwardType & CTRDGi_FORWARD_TYPE_MASK) == CTRDGi_FORWARD_TYPE_DMA)
+ {
+ MI_StopDma(dmaNo);
+ DC_FlushRange(dest, size);
+ }
+
+ switch (forwardType)
+ {
+ case CTRDGi_FORWARD_DMA16:
+ MI_DmaCopy16(dmaNo, src, dest, size);
+ break;
+ case CTRDGi_FORWARD_DMA32:
+ MI_DmaCopy32(dmaNo, src, dest, size);
+ break;
+ case CTRDGi_FORWARD_CPU16:
+ MI_CpuCopy16(src, dest, size);
+ break;
+ case CTRDGi_FORWARD_CPU32:
+ MI_CpuCopy32(src, dest, size);
+ break;
+
+ case CTRDGi_FORWARD_CPU8:
+ u8 *dest8 = (u8 *)dest;
+ u8 *src8 = (u8 *)src;
+ for (s32 n = 0; n < size; n++)
+ {
+ *dest8++ = *src8++;
+ }
+ break;
+ }
+
+ (void)OS_UnLockCartridge(CTRDGi_Work.lockID);
+
+ if (!CTRDG_IsExisting())
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+ARM_FUNC BOOL CTRDG_Read32(const u32 *address, u32 *rdata)
+{
+ return CTRDGi_AccessCommon((void *)address, 0, rdata, CTRDGi_ACCESS_READ32);
+}
+
+ARM_FUNC BOOL CTRDGi_AccessCommon(void *address, u32 data, void *rdata, u32 accessType)
+{
+ if (!CTRDG_IsExisting())
+ {
+ return FALSE;
+ }
+
+ CTRDG_CheckEnabled();
+
+ (void)OS_LockCartridge(CTRDGi_Work.lockID);
+
+ switch (accessType)
+ {
+ case CTRDGi_ACCESS_READ8:
+ if (rdata)
+ {
+ *(u8 *)rdata = *(u8 *)address;
+ }
+ break;
+ case CTRDGi_ACCESS_READ16:
+ if (rdata)
+ {
+ *(u16 *)rdata = *(u16 *)address;
+ }
+ break;
+ case CTRDGi_ACCESS_READ32:
+ if (rdata)
+ {
+ *(u32 *)rdata = *(u32 *)address;
+ }
+ break;
+ case CTRDGi_ACCESS_WRITE8:
+ *(u8 *)address = (u8)data;
+ break;
+ case CTRDGi_ACCESS_WRITE16:
+ *(u16 *)address = (u16)data;
+ break;
+ case CTRDGi_ACCESS_WRITE32:
+ *(u32 *)address = (u32)data;
+ break;
+ }
+
+ (void)OS_UnLockCartridge(CTRDGi_Work.lockID);
+
+ if (!CTRDG_IsExisting())
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+ARM_FUNC BOOL CTRDG_IsEnabled(void)
+{
+ return CTRDGi_EnableFlag;
+}
+
+ARM_FUNC void CTRDG_Enable(BOOL enable)
+{
+ OSIntrMode bak_cpsr = OS_DisableInterrupts();
+ CTRDGi_EnableFlag = enable;
+ if (!CTRDG_IsOptionCartridge())
+ {
+ u32 acc = (u32)(enable ? OS_PR3_ACCESS_RW : OS_PR3_ACCESS_RO);
+ (void)OS_SetDPermissionsForProtectionRegion(OS_PR3_ACCESS_MASK, acc);
+ }
+ (void)OS_RestoreInterrupts(bak_cpsr);
+}
+
+ARM_FUNC void CTRDG_CheckEnabled(void)
+{
+ if (!CTRDG_IsOptionCartridge() && !CTRDG_IsEnabled())
+ {
+ OS_Terminate();
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/CTRDG_flash_AT29LV512.c b/arm9/lib/NitroSDK/src/CTRDG_flash_AT29LV512.c
new file mode 100644
index 00000000..b1d09738
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/CTRDG_flash_AT29LV512.c
@@ -0,0 +1,327 @@
+#include "CTRDG_flash_AT29LV512.h"
+#include "function_target.h"
+#include "CTRDG_backup.h"
+#include "CTRDG_flash.h"
+#include "MI_exMemory.h"
+#include "OS_interrupt.h"
+#include "OS_spinLock.h"
+
+#define CTRDG_BACKUP_COM_ADR1 (CTRDG_AGB_FLASH_ADR+0x00005555)
+#define CTRDG_BACKUP_COM_ADR2 (CTRDG_AGB_FLASH_ADR+0x00002aaa)
+
+#define FLASH_LOG_SECTOR_COUNT 16
+#define FLASH_SECTOR_LOG_TO_PHYS 32
+#define FLASH_SECTOR_LOG_TO_PHYS_SHIFT 5
+
+extern u16 ctrdgi_flash_lock_id;
+extern BOOL ctrdgi_backup_irq;
+
+extern void CTRDGi_SetTask(CTRDGTaskInfo * pt, CTRDG_TASK_FUNC task, CTRDG_TASK_FUNC callback);
+
+extern u16 CTRDGi_PollingSR512kCOMMON(u16 phase, u8 *adr, u16 lastData);
+
+static const u16 atMaxTime[] = {
+ 10, 40, 0, 40
+};
+
+const CTRDGiFlashTypePlus AT29LV512_lib = {
+ CTRDGi_WriteFlash4KBAT,
+ CTRDGi_EraseFlashChipAT,
+ CTRDGi_EraseFlash4KBAT,
+ CTRDGi_WriteFlash4KBAsyncAT,
+ CTRDGi_EraseFlashChipAsyncAT,
+ CTRDGi_EraseFlash4KBAsyncAT,
+ CTRDGi_PollingSR512kCOMMON,
+ atMaxTime,
+ {
+ 0x00010000, //ROM size
+ {0x00001000, 12, 16, 0}, //sector
+ {MI_CTRDG_RAMCYCLE_18, MI_CTRDG_RAMCYCLE_18}, //read cycle and write cycle
+ 0x1f, //maker ID
+ 0x3d, //device ID
+ }
+};
+
+const CTRDGiFlashTypePlus AT29LV512_org = {
+ CTRDGi_WriteFlashSectorAT,
+ CTRDGi_EraseFlashChipAT,
+ CTRDGi_EraseFlashSectorAT,
+ CTRDGi_WriteFlashSectorAsyncAT,
+ CTRDGi_EraseFlashChipAsyncAT,
+ CTRDGi_EraseFlashSectorAsyncAT,
+ CTRDGi_PollingSR512kCOMMON,
+ atMaxTime,
+ {
+ 0x00010000, //ROM size
+ {0x00000080, 7, 512, 0}, //sector
+ {MI_CTRDG_RAMCYCLE_18, MI_CTRDG_RAMCYCLE_18}, //read cycle and write cycle
+ 0x1f, //maker ID
+ 0x3d, //device ID
+ }
+};
+
+ARM_FUNC u32 CTRDGi_EraseFlashChipCoreAT(CTRDGTaskInfo *arg)
+{
+ MICartridgeRamCycle ram_cycle;
+ u32 result;
+ (void)arg;
+
+ (void)OS_LockCartridge(ctrdgi_flash_lock_id);
+
+ ram_cycle = MI_GetCartridgeRamCycle();
+ MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
+
+ ctrdgi_backup_irq = OS_DisableIrq();
+
+ *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x80;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x10;
+
+ (void)OS_RestoreIrq(ctrdgi_backup_irq);
+
+ result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_CHIP_ERASE, (u8 *)CTRDG_AGB_FLASH_ADR, 0xff);
+
+ MI_SetCartridgeRamCycle(ram_cycle);
+
+ (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
+
+ return result;
+}
+
+ARM_FUNC u32 CTRDGi_EraseFlashSectorCoreAT(CTRDGTaskInfo *arg)
+{
+ u32 i;
+ u8 *dst;
+ BOOL shlet_ime;
+ MICartridgeRamCycle ram_cycle;
+ u32 result;
+ CTRDGTaskInfo p = *arg;
+ u16 p_secNo = p.sec_num;
+
+ dst = (u8 *)(CTRDG_AGB_FLASH_ADR + (p_secNo << AT29LV512_org.type.sector.shift));
+
+ (void)OS_LockCartridge(ctrdgi_flash_lock_id);
+
+ ram_cycle = MI_GetCartridgeRamCycle();
+ MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
+
+ shlet_ime = OS_DisableIrq();
+
+ *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xa0;
+
+ for (i = AT29LV512_org.type.sector.size; i > 0; i--)
+ {
+ *dst++ = 0xff;
+ }
+ dst--;
+
+ (void)OS_RestoreIrq(shlet_ime);
+
+ result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_PROGRAM, dst, 0xff);
+
+ if (result)
+ {
+ result = (u16)((result & 0xff00) | CTRDG_BACKUP_PHASE_SECTOR_ERASE);
+ }
+
+ MI_SetCartridgeRamCycle(ram_cycle);
+
+ (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
+
+ return result;
+}
+
+ARM_FUNC u32 CTRDGi_EraseFlash4KBCoreAT(CTRDGTaskInfo *arg)
+{
+ u32 result;
+ u16 i, p_secNo, retry;
+ CTRDGTaskInfo p = *arg;
+ u16 l_secNo = p.sec_num;
+
+ if (l_secNo >= FLASH_LOG_SECTOR_COUNT)
+ {
+ return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK;
+ }
+
+ p_secNo = (u16)(l_secNo << FLASH_SECTOR_LOG_TO_PHYS_SHIFT);
+ for (i = 0; i < FLASH_SECTOR_LOG_TO_PHYS; i++)
+ {
+ for (retry = 2; retry > 0; retry--)
+ {
+ result = CTRDGi_EraseFlashSectorAT(p_secNo);
+ if (result == 0)
+ {
+ break;
+ }
+ }
+ p_secNo++;
+ if (result)
+ {
+ break;
+ }
+ }
+
+ return result;
+}
+
+ARM_FUNC u32 CTRDGi_WriteFlashSectorCoreAT(CTRDGTaskInfo *arg)
+{
+ u32 i;
+ u8 *dst;
+ BOOL shlet_ime;
+ MICartridgeRamCycle ram_cycle;
+ u32 result;
+ CTRDGTaskInfo p = *arg;
+ u16 p_secNo = p.sec_num;
+ u8 *src = p.data;
+
+ (void)OS_LockCartridge(ctrdgi_flash_lock_id);
+
+ ram_cycle = MI_GetCartridgeRamCycle();
+ MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
+
+ dst = (u8 *)(CTRDG_AGB_FLASH_ADR + (p_secNo << AT29LV512_org.type.sector.shift));
+
+ shlet_ime = OS_DisableIrq();
+
+ *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
+ *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xa0;
+
+ for (i = AT29LV512_org.type.sector.size; i > 0; i--)
+ {
+ *dst++ = *src++;
+ }
+ dst--;
+ src--;
+
+ (void)OS_RestoreIrq(shlet_ime);
+
+ result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_PROGRAM, dst, *src);
+
+ MI_SetCartridgeRamCycle(ram_cycle);
+
+ (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
+
+ return result;
+}
+
+ARM_FUNC u32 CTRDGi_WriteFlash4KBCoreAT(CTRDGTaskInfo *arg)
+{
+ u32 result;
+ u16 p_secNo, retry;
+ CTRDGTaskInfo p = *arg;
+ u16 l_secNo = p.sec_num;
+ u8 *src = p.data;
+
+ if (l_secNo >= FLASH_LOG_SECTOR_COUNT)
+ {
+ return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK;
+ }
+
+ p_secNo = (u16)(l_secNo << FLASH_SECTOR_LOG_TO_PHYS_SHIFT);
+ ctrdg_flash_remainder = (u16)(AT29LV512_lib.type.sector.size);
+ while (ctrdg_flash_remainder)
+ {
+ for (retry = 2; retry > 0; retry--)
+ {
+ result = CTRDGi_WriteFlashSectorAT(p_secNo, src);
+ if (result == 0)
+ {
+ break;
+ }
+ }
+ if (result)
+ {
+ break;
+ }
+ ctrdg_flash_remainder -= AT29LV512_org.type.sector.size;
+ src += AT29LV512_org.type.sector.size;
+ p_secNo++;
+ }
+
+ return result;
+}
+
+ARM_FUNC u16 CTRDGi_EraseFlashChipAT(void)
+{
+ CTRDGTaskInfo p;
+ return (u16)CTRDGi_EraseFlashChipCoreAT(&p);
+}
+
+ARM_FUNC u16 CTRDGi_EraseFlash4KBAT(u16 l_secNo)
+{
+ CTRDGTaskInfo p;
+ p.sec_num = l_secNo;
+ return (u16)CTRDGi_EraseFlash4KBCoreAT(&p);
+}
+
+ARM_FUNC u16 CTRDGi_WriteFlash4KBAT(u16 l_secNo, u8 *src)
+{
+ CTRDGTaskInfo p;
+ p.sec_num = l_secNo;
+ p.data = src;
+ return (u16)CTRDGi_WriteFlash4KBCoreAT(&p);
+}
+
+ARM_FUNC void CTRDGi_EraseFlashChipAsyncAT(CTRDG_TASK_FUNC callback)
+{
+ CTRDGTaskInfo p;
+
+ CTRDGi_SetTask(&p, CTRDGi_EraseFlashChipCoreAT, callback);
+}
+
+ARM_FUNC void CTRDGi_EraseFlash4KBAsyncAT(u16 l_secNo, CTRDG_TASK_FUNC callback)
+{
+ CTRDGTaskInfo p;
+
+ p.sec_num = l_secNo;
+ CTRDGi_SetTask(&p, CTRDGi_EraseFlash4KBCoreAT, callback);
+}
+
+ARM_FUNC void CTRDGi_WriteFlash4KBAsyncAT(u16 l_secNo, u8 *src, CTRDG_TASK_FUNC callback)
+{
+ CTRDGTaskInfo p;
+
+ p.sec_num = l_secNo;
+ p.data = src;
+ CTRDGi_SetTask(&p, CTRDGi_WriteFlash4KBCoreAT, callback);
+}
+
+ARM_FUNC u16 CTRDGi_EraseFlashSectorAT(u16 p_secNo)
+{
+ CTRDGTaskInfo p;
+ p.sec_num = p_secNo;
+ return (u16)CTRDGi_EraseFlashSectorCoreAT(&p);
+}
+
+ARM_FUNC u16 CTRDGi_WriteFlashSectorAT(u16 p_secNo, u8 *src)
+{
+ CTRDGTaskInfo p;
+
+ p.sec_num = p_secNo;
+ p.data = src;
+ return (u16)CTRDGi_WriteFlashSectorCoreAT(&p);
+}
+
+ARM_FUNC void CTRDGi_EraseFlashSectorAsyncAT(u16 p_secNo, CTRDG_TASK_FUNC callback)
+{
+ CTRDGTaskInfo p;
+
+ p.sec_num = p_secNo;
+ CTRDGi_SetTask(&p, CTRDGi_EraseFlashSectorCoreAT, callback);
+}
+
+ARM_FUNC void CTRDGi_WriteFlashSectorAsyncAT(u16 p_secNo, u8 *src, CTRDG_TASK_FUNC callback)
+{
+ CTRDGTaskInfo p;
+
+ p.sec_num = p_secNo;
+ p.data = src;
+ CTRDGi_SetTask(&p, CTRDGi_WriteFlashSectorCoreAT, callback);
+}
diff --git a/arm9/lib/NitroSDK/src/FS_archive.c b/arm9/lib/NitroSDK/src/FS_archive.c
new file mode 100644
index 00000000..01f794f8
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FS_archive.c
@@ -0,0 +1,445 @@
+#include "FS_archive.h"
+#include "FS_command.h"
+#include "FSi_util.h"
+#include "MI_memory.h"
+#include "MI_byteAccess.h"
+#include "OS_printf.h"
+
+FSArchive * arc_list = NULL;
+FSDirPos current_dir_pos;
+
+ARM_FUNC u32 FSi_GetPackedName(const char * name, int name_len)
+{
+ u32 ret = 0;
+ if (name_len <= FS_ARCHIVE_NAME_LEN_MAX)
+ {
+ int i = 0;
+ for (; i < name_len; i++)
+ {
+ u32 c = MI_ReadByte(name + i);
+ if (!c)
+ break;
+ c = (u32)(c - 'A');
+ if (c <= (u32)('Z' - 'A'))
+ c = (u32)(c + 'a');
+ else
+ c = (u32)(c + 'A');
+ ret |= (u32)(c << (i * 8));
+ }
+ }
+ return ret;
+}
+
+ARM_FUNC FSResult FSi_ReadMemCallback(struct FSArchive * p_arc, void * dest, u32 pos, u32 size)
+{
+ MI_CpuCopy8((const void *)FS_GetArchiveOffset(p_arc, pos), dest, size);
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_WriteMemCallback(struct FSArchive * p_arc, const void * src, u32 pos, u32 size)
+{
+ MI_CpuCopy8(src, (void *)FS_GetArchiveOffset(p_arc, pos), size);
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_ReadMemoryCore(FSArchive * p_arc, void * dest, u32 pos, u32 size)
+{
+#pragma unused(p_arc)
+ MI_CpuCopy8((const void *)pos, dest, size);
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSFile * FSi_NextCommand(FSArchive * p_arc)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (FSi_IsArchiveCanceling(p_arc))
+ {
+ FSFile *p, *q;
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_CANCELING;
+ for (p = p_arc->list.next; p; p = q)
+ {
+ q = p->link.next;
+ if (FS_IsCanceling(p))
+ {
+ if (p_arc->list.next == p)
+ p_arc->list.next = q;
+ FSi_ReleaseCommand(p, FS_RESULT_CANCELED);
+ if (!q)
+ q = p_arc->list.next;
+ }
+ }
+ }
+ if (!FSi_IsArchiveSuspending(p_arc) && !FS_IsArchiveSuspended(p_arc))
+ {
+ FSFile * p_file = p_arc->list.next;
+ if (p_file != NULL)
+ {
+ const BOOL is_start = !FSi_IsArchiveRunning(p_arc);
+ if (is_start)
+ p_arc->flag |= FS_ARCHIVE_FLAG_RUNNING;
+ (void)OS_RestoreInterrupts(bak_psr);
+ if (is_start)
+ {
+ if ((p_arc->proc_flag & FS_ARCHIVE_PROC_ACTIVATE) != 0)
+ (void)((*p_arc->proc) (p_file, FS_COMMAND_ACTIVATE));
+ }
+ bak_psr = OS_DisableInterrupts();
+ p_file->stat |= FS_FILE_STATUS_OPERATING;
+ if (FS_IsFileSyncMode(p_file))
+ {
+ OS_WakeupThread(p_file->queue);
+ (void)OS_RestoreInterrupts(bak_psr);
+ return NULL;
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ return p_file;
+ }
+ }
+ if (FSi_IsArchiveRunning(p_arc))
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_RUNNING;
+ if (p_arc->proc_flag & FS_ARCHIVE_PROC_IDLE)
+ {
+ FSFile tmp;
+ FS_InitFile(&tmp);
+ tmp.arc = p_arc;
+ (void)((*p_arc->proc)(&tmp, FS_COMMAND_IDLE));
+ }
+ }
+ if (FSi_IsArchiveSuspending(p_arc))
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_SUSPENDING;
+ p_arc->flag |= FS_ARCHIVE_FLAG_SUSPEND;
+ OS_WakeupThread(&p_arc->stat_q);
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ return NULL;
+}
+
+ARM_FUNC void FSi_ExecuteAsyncCommand(FSFile * p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+ while (p_file)
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ p_file->stat |= FS_FILE_STATUS_OPERATING;
+ if (FS_IsFileSyncMode(p_file))
+ {
+ OS_WakeupThread(p_file->queue);
+ (void)OS_RestoreInterrupts(bak_psr);
+ break;
+ }
+ p_file->stat |= FS_FILE_STATUS_ASYNC;
+ (void)OS_RestoreInterrupts(bak_psr);
+ if (FSi_TranslateCommand(p_file, p_file->command) == FS_RESULT_PROC_ASYNC)
+ break;
+ p_file = FSi_NextCommand(p_arc);
+ }
+}
+
+ARM_FUNC BOOL FSi_ExecuteSyncCommand(FSFile * p_file)
+{
+ FSFile * p_target;
+ FSResult ret = FSi_TranslateCommand(p_file, p_file->command);
+ FSi_ReleaseCommand(p_file, ret);
+ p_target = FSi_NextCommand(p_file->arc);
+ if (p_target)
+ FSi_ExecuteAsyncCommand(p_target);
+ return FS_IsSucceeded(p_file);
+}
+
+ARM_FUNC BOOL FSi_SendCommand(FSFile * p_file, FSCommandType command)
+{
+ FSArchive * p_arc = p_file->arc;
+ const int bit = 1 << command;
+ p_file->command = command;
+ p_file->error = FS_RESULT_BUSY;
+ p_file->stat |= FS_FILE_STATUS_BUSY;
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (FSi_IsArchiveUnloading(p_arc))
+ {
+ FSi_ReleaseCommand(p_file, FS_RESULT_CANCELLED);
+ (void)OS_RestoreInterrupts(bak_psr);
+ return FALSE;
+ }
+ if ((bit & FS_ARCHIVE_PROC_SYNC) != 0)
+ p_file->stat |= FS_FILE_STATUS_SYNC;
+ FSi_AppendToList(p_file, (FSFile *)&p_arc->list);
+ if (!FS_IsArchiveSuspended(p_arc) && !FSi_IsArchiveRunning(p_arc))
+ {
+ p_arc->flag |= FS_ARCHIVE_FLAG_RUNNING;
+ (void)OS_RestoreInterrupts(bak_psr);
+ if ((p_arc->proc_flag & FS_ARCHIVE_PROC_ACTIVATE))
+ (void)((*p_arc->proc)(p_file, FS_COMMAND_ACTIVATE));
+ bak_psr = OS_DisableInterrupts();
+ p_file->stat |= FS_FILE_STATUS_OPERATING;
+ if (!FS_IsFileSyncMode(p_file))
+ {
+ (void)OS_RestoreInterrupts(bak_psr);
+ FSi_ExecuteAsyncCommand(p_file);
+ return TRUE;
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ }
+ else if (!FS_IsFileSyncMode(p_file))
+ {
+ (void)OS_RestoreInterrupts(bak_psr);
+ return TRUE;
+ }
+ else
+ {
+ do
+ {
+ OS_SleepThread(p_file->queue);
+ } while (!(p_file->stat & FS_FILE_STATUS_OPERATING));
+ (void)OS_RestoreInterrupts(bak_psr);
+ }
+ }
+ return FSi_ExecuteSyncCommand(p_file);
+}
+
+ARM_FUNC void FS_InitArchive(FSArchive * p_arc)
+{
+ MI_CpuClear8(p_arc, sizeof(FSArchive));
+ p_arc->sync_q.head = p_arc->sync_q.tail = NULL;
+ p_arc->stat_q.head = p_arc->stat_q.tail = NULL;
+}
+
+ARM_FUNC FSArchive * const FS_FindArchive(const char * name, int name_len)
+{
+ u32 pack = FSi_GetPackedName(name, name_len);
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ FSArchive * p_arc = arc_list;
+ while (p_arc && (p_arc->name.pack != pack))
+ p_arc = p_arc->next;
+ (void)OS_RestoreInterrupts(bak_psr);
+ return p_arc;
+}
+
+ARM_FUNC BOOL FS_RegisterArchiveName(FSArchive * p_arc, const char * name, int name_len)
+{
+ BOOL ret = FALSE;
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (!FS_FindArchive(name, name_len))
+ {
+ FSArchive * p_tail = arc_list;
+ if (!p_tail)
+ {
+ arc_list = p_arc;
+ current_dir_pos.arc = p_arc;
+ current_dir_pos.pos = 0;
+ current_dir_pos.index = 0;
+ current_dir_pos.own_id = 0;
+ }
+ else
+ {
+ while (p_tail->next)
+ p_tail = p_tail->next;
+ p_tail->next = p_arc;
+ p_arc->prev = p_tail;
+ }
+ p_arc->name.pack = FSi_GetPackedName(name, name_len);
+ p_arc->flag |= FS_ARCHIVE_FLAG_REGISTER;
+ ret = TRUE;
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ return ret;
+}
+
+ARM_FUNC void FS_ReleaseArchiveName(FSArchive * p_arc)
+{
+ if (p_arc->name.pack)
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (p_arc->next)
+ p_arc->next->prev = p_arc->prev;
+ if (p_arc->prev)
+ p_arc->prev->next = p_arc->next;
+ p_arc->name.pack = 0;
+ p_arc->next = p_arc->prev = NULL;
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_REGISTER;
+ if (current_dir_pos.arc == p_arc)
+ {
+ current_dir_pos.arc = arc_list;
+ current_dir_pos.pos = 0;
+ current_dir_pos.index = 0;
+ current_dir_pos.own_id = 0;
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ }
+}
+
+ARM_FUNC BOOL FS_LoadArchive(FSArchive * p_arc, u32 base, u32 fat, u32 fat_size, u32 fnt, u32 fnt_size, FS_ARCHIVE_READ_FUNC read_func, FS_ARCHIVE_WRITE_FUNC write_func)
+{
+ p_arc->base = base;
+ p_arc->fat_size = fat_size;
+ p_arc->fat = p_arc->fat_bak = fat;
+ p_arc->fnt_size = fnt_size;
+ p_arc->fnt = p_arc->fnt_bak = fnt;
+ p_arc->read_func = (read_func != NULL) ? read_func : FSi_ReadMemCallback;
+ p_arc->write_func = (write_func != NULL) ? write_func : FSi_WriteMemCallback;
+ p_arc->table_func = p_arc->read_func;
+ p_arc->load_mem = NULL;
+ p_arc->flag |= FS_ARCHIVE_FLAG_LOADED;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_UnloadArchive(FSArchive * p_arc)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (FS_IsArchiveLoaded(p_arc))
+ {
+ if (FS_IsArchiveTableLoaded(p_arc))
+ {
+ OS_TWarning("memory may leak. preloaded-table of archive \"%s\" (0x%08X)", p_arc->name.ptr, p_arc->load_mem);
+ }
+ {
+ FSFile *p, *q;
+ BOOL bak_state = FS_SuspendArchive(p_arc);
+ p_arc->flag |= FS_ARCHIVE_FLAG_UNLOADING;
+ for (p = p_arc->list.next; p; p = q)
+ {
+ q = p->link.next;
+ FSi_ReleaseCommand(p, FS_RESULT_CANCELED);
+ }
+ p_arc->list.next = NULL;
+ if (bak_state)
+ (void)FS_ResumeArchive(p_arc);
+ }
+ p_arc->base = 0;
+ p_arc->fat = 0;
+ p_arc->fat_size = 0;
+ p_arc->fnt = 0;
+ p_arc->fnt_size = 0;
+ p_arc->fat_bak = p_arc->fnt_bak = 0;
+ p_arc->flag &= ~(FS_ARCHIVE_FLAG_CANCELING | FS_ARCHIVE_FLAG_LOADED | FS_ARCHIVE_FLAG_UNLOADING);
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ return TRUE;
+}
+
+ARM_FUNC u32 FS_LoadArchiveTables(FSArchive *p_arc, void *p_mem, u32 max_size)
+{
+ u32 total_size = ALIGN_BYTE(p_arc->fat_size + p_arc->fnt_size + 32, 32);
+ if (total_size <= max_size)
+ {
+ u8 *p_cache = (u8 *)ALIGN_BYTE((u32)p_mem, 32);
+ FSFile tmp;
+ FS_InitFile(&tmp);
+ if (FS_OpenFileDirect(&tmp, p_arc, p_arc->fat, p_arc->fat + p_arc->fat_size, (u32)~0))
+ {
+ if (FS_ReadFile(&tmp, p_cache, (s32)p_arc->fat_size) < 0)
+ {
+ MI_CpuFill8(p_cache, 0x00, p_arc->fat_size);
+ }
+ (void)FS_CloseFile(&tmp);
+ }
+ p_arc->fat = (u32)p_cache;
+ p_cache += p_arc->fat_size;
+ if (FS_OpenFileDirect(&tmp, p_arc, p_arc->fnt, p_arc->fnt + p_arc->fnt_size, (u32)~0))
+ {
+ if (FS_ReadFile(&tmp, p_cache, (s32)p_arc->fnt_size) < 0)
+ {
+ MI_CpuFill8(p_cache, 0x00, p_arc->fnt_size);
+ }
+ (void)FS_CloseFile(&tmp);
+ }
+ p_arc->fnt = (u32)p_cache;
+ p_arc->load_mem = p_mem;
+ p_arc->table_func = FSi_ReadMemoryCore;
+ p_arc->flag |= FS_ARCHIVE_FLAG_TABLE_LOAD;
+ }
+ return total_size;
+}
+
+ARM_FUNC void * FS_UnloadArchiveTables(FSArchive * p_arc)
+{
+ void *ret = NULL;
+ if (FS_IsArchiveLoaded(p_arc))
+ {
+ BOOL bak_stat = FS_SuspendArchive(p_arc);
+ if (FS_IsArchiveTableLoaded(p_arc))
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_TABLE_LOAD;
+ ret = p_arc->load_mem;
+ p_arc->load_mem = NULL;
+ p_arc->fat = p_arc->fat_bak;
+ p_arc->fnt = p_arc->fnt_bak;
+ p_arc->table_func = p_arc->read_func;
+ }
+ if (bak_stat)
+ (void)FS_ResumeArchive(p_arc);
+ }
+ return ret;
+}
+
+ARM_FUNC BOOL FS_SuspendArchive(FSArchive * p_arc)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ const BOOL bak_stat = !FS_IsArchiveSuspended(p_arc);
+ if (bak_stat)
+ {
+ if (FSi_IsArchiveRunning(p_arc))
+ {
+ p_arc->flag |= FS_ARCHIVE_FLAG_SUSPENDING;
+ do {
+ OS_SleepThread(&p_arc->stat_q);
+ } while (FSi_IsArchiveSuspending(p_arc));
+ }
+ else
+ {
+ p_arc->flag |= FS_ARCHIVE_FLAG_SUSPEND;
+ }
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ return bak_stat;
+}
+
+ARM_FUNC BOOL FS_ResumeArchive(FSArchive * p_arc)
+{
+ FSFile * p_target = NULL;
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ const BOOL bak_stat = !FS_IsArchiveSuspended(p_arc);
+ if (!bak_stat)
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_SUSPEND;
+ p_target = FSi_NextCommand(p_arc);
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ if (p_target)
+ FSi_ExecuteAsyncCommand(p_target);
+ return bak_stat;
+}
+
+ARM_FUNC void FS_SetArchiveProc(struct FSArchive * p_arc, FS_ARCHIVE_PROC_FUNC proc, u32 flags)
+{
+ if (!flags)
+ proc = NULL;
+ else if (!proc)
+ flags = 0;
+ p_arc->proc = proc;
+ p_arc->proc_flag = flags;
+}
+
+ARM_FUNC void FS_NotifyArchiveAsyncEnd(FSArchive *p_arc, FSResult ret)
+{
+ if (FSi_IsArchiveAsync(p_arc))
+ {
+ FSFile *p_file = p_arc->list.next;
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_ASYNC;
+ FSi_ReleaseCommand(p_file, ret);
+ p_file = FSi_NextCommand(p_arc);
+ if (p_file)
+ FSi_ExecuteAsyncCommand(p_file);
+ }
+ else
+ {
+ FSFile *p_file = p_arc->list.next;
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ p_file->error = ret;
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_SYNC;
+ OS_WakeupThread(&p_arc->sync_q);
+ (void)OS_RestoreInterrupts(bak_psr);
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/FS_command.c b/arm9/lib/NitroSDK/src/FS_command.c
new file mode 100644
index 00000000..e677f6c6
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FS_command.c
@@ -0,0 +1,77 @@
+#include "FS_file.h"
+#include "FS_archive.h"
+#include "FSi_util.h"
+#include "FS_command.h"
+
+ARM_FUNC void FSi_ReleaseCommand(FSFile * p_file, FSResult ret)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ FSi_CutFromList(p_file);
+ p_file->stat &= ~(FS_FILE_STATUS_CANCEL | FS_FILE_STATUS_BUSY | FS_FILE_STATUS_SYNC | FS_FILE_STATUS_ASYNC | FS_FILE_STATUS_OPERATING);
+ p_file->error = ret;
+ OS_WakeupThread(p_file->queue);
+ (void)OS_RestoreInterrupts(bak_psr);
+}
+
+ARM_FUNC FSResult FSi_TranslateCommand(FSFile *p_file, FSCommandType command)
+{
+ FSResult ret;
+
+ FSArchive *const p_arc = p_file->arc;
+ const int bit = (1 << command);
+
+ if (FS_IsFileSyncMode(p_file))
+ p_arc->flag |= FS_ARCHIVE_FLAG_IS_SYNC;
+ else
+ p_arc->flag |= FS_ARCHIVE_FLAG_IS_ASYNC;
+
+ if ((p_arc->proc_flag & bit) != 0)
+ {
+ switch (ret = (*p_arc->proc) (p_file, command))
+ {
+ case FS_RESULT_SUCCESS:
+ case FS_RESULT_FAILURE:
+ case FS_RESULT_UNSUPPORTED:
+ p_file->error = ret;
+ break;
+ case FS_RESULT_PROC_ASYNC:
+ break;
+ case FS_RESULT_PROC_UNKNOWN:
+ ret = FS_RESULT_PROC_DEFAULT;
+ p_arc->proc_flag &= ~bit;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ ret = FS_RESULT_PROC_DEFAULT;
+ }
+ if (ret == FS_RESULT_PROC_DEFAULT)
+ {
+ ret = (*fsi_default_command[command]) (p_file);
+ }
+ if (ret == FS_RESULT_PROC_ASYNC)
+ {
+ if (FS_IsFileSyncMode(p_file))
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ while (FSi_IsArchiveSync(p_arc))
+ OS_SleepThread(&p_arc->sync_q);
+ ret = p_file->error;
+ (void)OS_RestoreInterrupts(bak_psr);
+ }
+ }
+ else if (!FS_IsFileSyncMode(p_file))
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_ASYNC;
+ FSi_ReleaseCommand(p_file, ret);
+ }
+ else
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_SYNC;
+ p_file->error = ret;
+ }
+ return ret;
+}
diff --git a/arm9/lib/NitroSDK/src/FS_command_default.c b/arm9/lib/NitroSDK/src/FS_command_default.c
new file mode 100644
index 00000000..0cdc91fc
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FS_command_default.c
@@ -0,0 +1,453 @@
+#include "nitro.h"
+#include "FS_file.h"
+#include "FS_command.h"
+#include "MI_byteAccess.h"
+#include "MI_memory.h"
+#include "FSi_util.h"
+#include "FS_command_default.h"
+
+FSResult (*const fsi_default_command[])(FSFile *) = {
+ [FS_COMMAND_READFILE] = FSi_ReadFileCommand,
+ [FS_COMMAND_WRITEFILE] = FSi_WriteFileCommand,
+ [FS_COMMAND_SEEKDIR] = FSi_SeekDirCommand,
+ [FS_COMMAND_READDIR] = FSi_ReadDirCommand,
+ [FS_COMMAND_FINDPATH] = FSi_FindPathCommand,
+ [FS_COMMAND_GETPATH] = FSi_GetPathCommand,
+ [FS_COMMAND_OPENFILEFAST] = FSi_OpenFileFastCommand,
+ [FS_COMMAND_OPENFILEDIRECT] = FSi_OpenFileDirectCommand,
+ [FS_COMMAND_CLOSEFILE] = FSi_CloseFileCommand,
+};
+
+// Case-insensitive string comparison
+ARM_FUNC u32 FSi_StrNICmp(const char * str1, const char * str2, u32 len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ u32 c = (u32)(MI_ReadByte(str1 + i) - 'A');
+ u32 d = (u32)(MI_ReadByte(str2 + i) - 'A');
+ if (c <= 'Z' - 'A')
+ c += 'a' - 'A';
+ if (d <= 'Z' - 'A')
+ d += 'a' - 'A';
+ if (c != d)
+ return c - d;
+ }
+ return 0;
+}
+
+ARM_FUNC FSResult FSi_ReadTable(FSiSyncReadParam * p, void * dst, u32 len)
+{
+ FSResult ret;
+ FSArchive * const p_arc = p->arc;
+ p_arc->flag |= FS_ARCHIVE_FLAG_IS_SYNC;
+ switch (ret = (*p_arc->table_func)(p_arc, dst, p->pos, len))
+ {
+ case FS_RESULT_SUCCESS:
+ case FS_RESULT_FAILURE:
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_SYNC;
+ break;
+ case FS_RESULT_PROC_ASYNC:
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ while (FSi_IsArchiveSync(p_arc))
+ OS_SleepThread(&p_arc->sync_q);
+ (void)OS_RestoreInterrupts(bak_psr);
+ ret = p_arc->list.next->error;
+ }
+ default:
+ break;
+ }
+ p->pos += len;
+ return ret;
+}
+
+ARM_FUNC FSResult FSi_SeekDirDirect(FSFile * p_dir, u32 id)
+{
+ p_dir->stat |= FS_FILE_STATUS_SYNC;
+ p_dir->arg.seekdir.pos.arc = p_dir->arc;
+ p_dir->arg.seekdir.pos.pos = 0;
+ p_dir->arg.seekdir.pos.index = 0;
+ p_dir->arg.seekdir.pos.own_id = (u16)id;
+ return FSi_TranslateCommand(p_dir, FS_COMMAND_SEEKDIR);
+}
+
+// The actual commands
+ARM_FUNC FSResult FSi_ReadFileCommand(FSFile * p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+ const u32 pos = p_file->prop.file.pos;
+ const u32 len = p_file->arg.readfile.len;
+ void *const dst = p_file->arg.readfile.dst;
+ p_file->prop.file.pos += len;
+ return (*p_arc->read_func)(p_arc, dst, pos, len);
+}
+
+ARM_FUNC FSResult FSi_WriteFileCommand(FSFile * p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+ const u32 pos = p_file->prop.file.pos;
+ const u32 len = p_file->arg.writefile.len;
+ const void *const src = p_file->arg.writefile.src;
+ p_file->prop.file.pos += len;
+ return (*p_arc->write_func)(p_arc, src, pos, len);
+}
+
+ARM_FUNC FSResult FSi_SeekDirCommand(FSFile * p_dir)
+{
+ FSResult ret;
+ FSArchive *const p_arc = p_dir->arc;
+ const FSDirPos *const arg = &p_dir->arg.seekdir.pos;
+
+ FSArchiveFNT fnt_entry;
+ FSiSyncReadParam param;
+ param.arc = p_arc;
+ param.pos = p_arc->fnt + arg->own_id * sizeof(fnt_entry);
+ ret = FSi_ReadTable(&param, &fnt_entry, sizeof(fnt_entry));
+ if (ret == FS_RESULT_SUCCESS)
+ {
+ p_dir->prop.dir.pos = *arg;
+ if ((arg->index == 0) && (arg->pos == 0))
+ {
+ p_dir->prop.dir.pos.index = fnt_entry.index;
+ p_dir->prop.dir.pos.pos = p_arc->fnt + fnt_entry.start;
+ }
+ p_dir->prop.dir.parent = (u32) (fnt_entry.parent & BIT_MASK(12));
+ }
+ return ret;
+}
+
+ARM_FUNC FSResult FSi_ReadDirCommand(FSFile *p_dir)
+{
+ FSDirEntry *p_entry = p_dir->arg.readdir.p_entry;
+ FSResult ret;
+
+ FSiSyncReadParam param;
+ param.arc = p_dir->arc;
+ param.pos = p_dir->prop.dir.pos.pos;
+
+ {
+ u8 len;
+ ret = FSi_ReadTable(&param, &len, sizeof(len));
+ if (ret != FS_RESULT_SUCCESS)
+ return ret;
+ p_entry->name_len = (u32)(len & BIT_MASK(7));
+ p_entry->is_directory = (u32)((len >> 7) & 1);
+ }
+ if (p_entry->name_len == 0)
+ return FS_RESULT_FAILURE;
+
+ if (!p_dir->arg.readdir.skip_string)
+ {
+ ret = FSi_ReadTable(&param, p_entry->name, p_entry->name_len);
+ if (ret != FS_RESULT_SUCCESS)
+ return ret;
+ MI_WriteByte((u8 *)p_entry->name + p_entry->name_len, (u8)'\0');
+ }
+ else
+ {
+ param.pos += p_entry->name_len;
+ }
+
+ if (p_entry->is_directory)
+ {
+ u16 id;
+ ret = FSi_ReadTable(&param, &id, sizeof(id));
+ if (ret != FS_RESULT_SUCCESS)
+ return ret;
+ p_entry->dir_id.arc = p_dir->arc;
+ p_entry->dir_id.own_id = (u16)(id & BIT_MASK(12));
+ p_entry->dir_id.index = 0;
+ p_entry->dir_id.pos = 0;
+ }
+ else
+ {
+ p_entry->file_id.arc = p_dir->arc;
+ p_entry->file_id.file_id = p_dir->prop.dir.pos.index;
+ ++p_dir->prop.dir.pos.index;
+ }
+ p_dir->prop.dir.pos.pos = param.pos;
+
+ return ret;
+}
+
+ARM_FUNC FSResult FSi_FindPathCommand(FSFile *p_dir)
+{
+ const char *path = p_dir->arg.findpath.path;
+ const BOOL is_dir = p_dir->arg.findpath.find_directory;
+ p_dir->arg.seekdir.pos = p_dir->arg.findpath.pos;
+ (void)FSi_TranslateCommand(p_dir, FS_COMMAND_SEEKDIR);
+ for (; MI_ReadByte(path); path += (MI_ReadByte(path) ? 1 : 0))
+ {
+ u32 is_directory;
+ int name_len = 0;
+ while ((is_directory = MI_ReadByte(path + name_len)),
+ (is_directory && !FSi_IsSlash(is_directory)))
+ ++name_len;
+ if (is_directory || is_dir)
+ is_directory = 1;
+ if (name_len == 0)
+ {
+ return FS_RESULT_FAILURE;
+ }
+ else if (MI_ReadByte(path) == '.')
+ {
+ if (name_len == 1)
+ {
+ path += 1;
+ continue;
+ }
+ else if ((name_len == 2) & (MI_ReadByte(path + 1) == '.'))
+ {
+ if (p_dir->prop.dir.pos.own_id != 0)
+ (void)FSi_SeekDirDirect(p_dir, p_dir->prop.dir.parent);
+ path += 2;
+ continue;
+ }
+ }
+ if (name_len > FS_FILE_NAME_MAX)
+ {
+ return FS_RESULT_FAILURE;
+ }
+ else
+ {
+ FSDirEntry etr;
+ p_dir->arg.readdir.p_entry = &etr;
+ p_dir->arg.readdir.skip_string = FALSE;
+ for (;;)
+ {
+ if (FSi_TranslateCommand(p_dir, FS_COMMAND_READDIR) != FS_RESULT_SUCCESS)
+ return FS_RESULT_FAILURE;
+ if ((is_directory != etr.is_directory) ||
+ (name_len != etr.name_len) || FSi_StrNICmp(path, etr.name, (u32)name_len))
+ continue;
+ if (is_directory)
+ {
+ path += name_len;
+ p_dir->arg.seekdir.pos = etr.dir_id;
+ (void)FSi_TranslateCommand(p_dir, FS_COMMAND_SEEKDIR);
+ break;
+ }
+ else if (is_dir)
+ {
+ return FS_RESULT_FAILURE;
+ }
+ else
+ {
+ *p_dir->arg.findpath.result.file = etr.file_id;
+ return FS_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ if (!is_dir)
+ return FS_RESULT_FAILURE;
+ *p_dir->arg.findpath.result.dir = p_dir->prop.dir.pos;
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_GetPathCommand(FSFile *p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+
+ FSGetPathInfo *p_info = &p_file->arg.getpath;
+
+ FSDirEntry entry;
+ FSFile tmp;
+ u32 dir_id;
+ u32 file_id;
+ u32 id;
+ u32 len;
+
+ enum
+ { INVALID_ID = 0x10000 };
+
+ FS_InitFile(&tmp);
+ tmp.arc = p_file->arc;
+
+ if (FS_IsDir(p_file))
+ {
+ dir_id = p_file->prop.dir.pos.own_id;
+ file_id = INVALID_ID;
+ }
+ else
+ {
+ file_id = p_file->prop.file.own_id;
+ if (p_info->total_len != 0)
+ {
+ dir_id = p_info->dir_id;
+ }
+ else
+ {
+ u32 pos = 0;
+ u32 num_dir = 0;
+ dir_id = INVALID_ID;
+ do
+ {
+ (void)FSi_SeekDirDirect(&tmp, pos);
+ if (!pos)
+ num_dir = tmp.prop.dir.parent;
+ tmp.arg.readdir.p_entry = &entry;
+ tmp.arg.readdir.skip_string = TRUE;
+ while (FSi_TranslateCommand(&tmp, FS_COMMAND_READDIR) == FS_RESULT_SUCCESS)
+ {
+ if (!entry.is_directory && (entry.file_id.file_id == file_id))
+ {
+ dir_id = tmp.prop.dir.pos.own_id;
+ break;
+ }
+ }
+ }
+ while ((dir_id == INVALID_ID) && (++pos < num_dir));
+ }
+ }
+ if (dir_id == INVALID_ID)
+ {
+ p_info->total_len = 0;
+ return FS_RESULT_FAILURE;
+ }
+ if (p_info->total_len == 0)
+ {
+ len = 0;
+ if (p_arc->name.pack <= 0x000000FF)
+ len += 1;
+ else if (p_arc->name.pack <= 0x0000FF00)
+ len += 2;
+ else
+ len += 3;
+ len += 1 + 1;
+ if (file_id != INVALID_ID)
+ len += entry.name_len;
+ id = dir_id;
+ if (id != 0)
+ {
+ (void)FSi_SeekDirDirect(&tmp, id);
+ do
+ {
+ (void)FSi_SeekDirDirect(&tmp, tmp.prop.dir.parent);
+ tmp.arg.readdir.p_entry = &entry;
+ tmp.arg.readdir.skip_string = TRUE;
+ while (FSi_TranslateCommand(&tmp, FS_COMMAND_READDIR) == FS_RESULT_SUCCESS)
+ {
+ if (entry.is_directory && (entry.dir_id.own_id == id))
+ {
+ len += entry.name_len + 1;
+ break;
+ }
+ }
+ id = tmp.prop.dir.pos.own_id;
+ }
+ while (id != 0);
+ }
+ p_info->total_len = (u16)(len + 1);
+ p_info->dir_id = (u16)dir_id;
+ }
+ if (!p_info->buf)
+ return FS_RESULT_SUCCESS;
+ if (p_info->buf_len < p_info->total_len)
+ return FS_RESULT_FAILURE;
+ else
+ {
+ u8 *dst = p_info->buf;
+ u32 total = p_info->total_len;
+ u32 pos = 0;
+ if (p_arc->name.pack <= 0x000000FF)
+ len = 1;
+ else if (p_arc->name.pack <= 0x0000FF00)
+ len = 2;
+ else
+ len = 3;
+ MI_CpuCopy8(p_arc->name.ptr, dst + pos, len);
+ pos += len;
+ MI_CpuCopy8(":/", dst + pos, 2);
+ pos += 2;
+ id = dir_id;
+ (void)FSi_SeekDirDirect(&tmp, id);
+ if (file_id != INVALID_ID)
+ {
+ tmp.arg.readdir.p_entry = &entry;
+ tmp.arg.readdir.skip_string = FALSE;
+ while (FSi_TranslateCommand(&tmp, FS_COMMAND_READDIR) == FS_RESULT_SUCCESS)
+ {
+ if (!entry.is_directory && (entry.file_id.file_id == file_id))
+ break;
+ }
+ len = entry.name_len + 1;
+ MI_CpuCopy8(entry.name, dst + total - len, len);
+ total -= len;
+ }
+ else
+ {
+ MI_WriteByte(dst + total - 1, '\0');
+ total -= 1;
+ }
+ if (id != 0)
+ {
+ do
+ {
+ (void)FSi_SeekDirDirect(&tmp, tmp.prop.dir.parent);
+ tmp.arg.readdir.p_entry = &entry;
+ tmp.arg.readdir.skip_string = FALSE;
+ MI_WriteByte(dst + total - 1, '/');
+ total -= 1;
+ while (FSi_TranslateCommand(&tmp, FS_COMMAND_READDIR) == FS_RESULT_SUCCESS)
+ {
+ if (entry.is_directory && (entry.dir_id.own_id == id))
+ {
+ len = entry.name_len;
+ MI_CpuCopy8(entry.name, dst + total - len, len);
+ total -= len;
+ break;
+ }
+ }
+ id = tmp.prop.dir.pos.own_id;
+ }
+ while (id != 0);
+ }
+ }
+
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_OpenFileFastCommand(FSFile * p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+ const FSFileID *p_id = &p_file->arg.openfilefast.id;
+ const u32 index = p_id->file_id;
+ FSResult ret;
+
+ {
+ u32 pos = (u32)(index * sizeof(FSArchiveFAT));
+ if (pos >= p_arc->fat_size)
+ return FS_RESULT_FAILURE;
+ else
+ {
+ FSArchiveFAT fat;
+ FSiSyncReadParam param;
+ param.arc = p_arc;
+ param.pos = p_arc->fat + pos;
+ ret = FSi_ReadTable(&param, &fat, sizeof(fat));
+ if (ret != FS_RESULT_SUCCESS)
+ return ret;
+ p_file->arg.openfiledirect.top = fat.top;
+ p_file->arg.openfiledirect.bottom = fat.bottom;
+ p_file->arg.openfiledirect.index = index;
+ return FSi_TranslateCommand(p_file, FS_COMMAND_OPENFILEDIRECT);
+ }
+ }
+}
+
+ARM_FUNC FSResult FSi_OpenFileDirectCommand(FSFile * p_file)
+{
+ p_file->prop.file.top = p_file->arg.openfiledirect.top;
+ p_file->prop.file.pos = p_file->arg.openfiledirect.top;
+ p_file->prop.file.bottom = p_file->arg.openfiledirect.bottom;
+ p_file->prop.file.own_id = p_file->arg.openfiledirect.index;
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_CloseFileCommand(FSFile * p_file)
+{
+#pragma unused (p_file)
+ return FS_RESULT_SUCCESS;
+}
diff --git a/arm9/lib/NitroSDK/src/FS_file.c b/arm9/lib/NitroSDK/src/FS_file.c
new file mode 100644
index 00000000..11595c02
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FS_file.c
@@ -0,0 +1,244 @@
+#include "nitro.h"
+#include "MI_byteAccess.h"
+#include "FS_rom.h"
+#include "FS_file.h"
+#include "FSi_util.h"
+
+extern FSDirPos current_dir_pos;
+BOOL is_init = FALSE;
+
+static BOOL FSi_FindPath(FSFile * p_dir, const char * path, FSFileID * p_file_id, FSDirPos * p_dir_pos);
+
+ARM_FUNC void FS_Init(u32 default_dma_no)
+{
+ if (!is_init)
+ {
+ is_init = TRUE;
+ FSi_InitRom(default_dma_no);
+ }
+}
+
+ARM_FUNC BOOL FS_IsAvailable(void)
+{
+ return is_init;
+}
+
+ARM_FUNC void FS_InitFile(FSFile * p_file)
+{
+ p_file->link.next = p_file->link.prev = NULL;
+ OS_InitThreadQueue(p_file->queue);
+ p_file->arc = NULL;
+ p_file->command = FS_COMMAND_INVALID;
+ p_file->stat = 0;
+}
+
+static BOOL FSi_FindPath(FSFile * p_dir, const char * path, FSFileID * p_file_id, FSDirPos * p_dir_pos)
+{
+ FSDirPos pos;
+ if (FSi_IsSlash(MI_ReadByte(path)))
+ {
+ pos.arc = current_dir_pos.arc;
+ pos.own_id = 0;
+ pos.pos = 0;
+ pos.index = 0;
+ path++;
+ }
+ else
+ {
+ int i;
+ pos = current_dir_pos;
+ for (i = 0; i <= FS_ARCHIVE_NAME_LEN_MAX; ++i)
+ {
+ u32 c = MI_ReadByte(path + i);
+ if (!c || FSi_IsSlash(c))
+ break;
+ else if (c == ':')
+ {
+ FSArchive * const p_arc = FS_FindArchive(path, i);
+ if (!p_arc)
+ {
+ return FALSE;
+ }
+ else if (!FS_IsArchiveLoaded(p_arc))
+ {
+ return FALSE;
+ }
+ pos.arc = p_arc;
+ pos.pos = 0;
+ pos.index = 0;
+ pos.own_id = 0;
+ path += i + 1;
+ if (FSi_IsSlash(MI_ReadByte(path)))
+ ++path;
+ break;
+ }
+ }
+ }
+ p_dir->arc = pos.arc;
+ p_dir->arg.findpath.path = path;
+ p_dir->arg.findpath.pos = pos;
+ if (p_dir_pos)
+ {
+ p_dir->arg.findpath.find_directory = TRUE;
+ p_dir->arg.findpath.result.dir = p_dir_pos;
+ }
+ else
+ {
+ p_dir->arg.findpath.find_directory = FALSE;
+ p_dir->arg.findpath.result.file = p_file_id;
+ }
+ return FSi_SendCommand(p_dir, FS_COMMAND_FINDPATH);
+}
+
+ARM_FUNC int FSi_ReadFileCore(FSFile * p_file, void * dst, s32 len, BOOL async)
+{
+ const s32 pos = (s32)p_file->prop.file.pos;
+ const s32 rest = (s32)(p_file->prop.file.bottom - pos);
+ const u32 org = (u32)len;
+ if (len > rest)
+ len = rest;
+ if (len < 0)
+ len = 0;
+ p_file->arg.readfile.dst = dst;
+ p_file->arg.readfile.len_org = org;
+ p_file->arg.readfile.len = (u32)len;
+ if (!async)
+ p_file->stat |= FS_FILE_STATUS_SYNC;
+ (void)FSi_SendCommand(p_file, FS_COMMAND_READFILE);
+ if (!async)
+ {
+ if (FS_WaitAsync(p_file))
+ len = (s32)(p_file->prop.file.pos - pos);
+ else
+ len = -1;
+ }
+ return len;
+}
+
+ARM_FUNC BOOL FS_ConvertPathToFileID(FSFileID * p_file_id, const char * path)
+{
+ FSFile dir;
+ FS_InitFile(&dir);
+ if (!FSi_FindPath(&dir, path, p_file_id, NULL))
+ return FALSE;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_OpenFileDirect(FSFile * p_file, FSArchive * p_arc, u32 image_top, u32 image_bottom, u32 file_index)
+{
+ p_file->arc = p_arc;
+ p_file->arg.openfiledirect.index = file_index;
+ p_file->arg.openfiledirect.top = image_top;
+ p_file->arg.openfiledirect.bottom = image_bottom;
+ if (!FSi_SendCommand(p_file, FS_COMMAND_OPENFILEDIRECT))
+ return FALSE;
+ p_file->stat |= FS_FILE_STATUS_IS_FILE;
+ p_file->stat &= ~FS_FILE_STATUS_IS_DIR;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_OpenFileFast(FSFile * p_file, FSFileID file_id)
+{
+ if (!file_id.arc)
+ return FALSE;
+ p_file->arc = file_id.arc;
+ p_file->arg.openfilefast.id = file_id;
+ if (!FSi_SendCommand(p_file, FS_COMMAND_OPENFILEFAST))
+ return FALSE;
+ p_file->stat |= FS_FILE_STATUS_IS_FILE;
+ p_file->stat &= ~FS_FILE_STATUS_IS_DIR;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_OpenFile(FSFile * p_file, const char * path)
+{
+ FSFileID file_id;
+ return FS_ConvertPathToFileID(&file_id, path) && FS_OpenFileFast(p_file, file_id);
+}
+
+ARM_FUNC BOOL FS_CloseFile(FSFile * p_file)
+{
+ if (!FSi_SendCommand(p_file, FS_COMMAND_CLOSEFILE))
+ return FALSE;
+ p_file->arc = NULL;
+ p_file->command = FS_COMMAND_INVALID;
+ p_file->stat &= ~(FS_FILE_STATUS_IS_FILE | FS_FILE_STATUS_IS_DIR);
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_WaitAsync(FSFile * p_file)
+{
+ BOOL is_owner = FALSE;
+ OSIntrMode bak_par = OS_DisableInterrupts();
+ if (FS_IsBusy(p_file))
+ {
+ is_owner = !(p_file->stat & (FS_FILE_STATUS_SYNC | FS_FILE_STATUS_OPERATING));
+ if (is_owner)
+ {
+ p_file->stat |= FS_FILE_STATUS_SYNC;
+ do
+ {
+ OS_SleepThread(p_file->queue);
+ } while (!(p_file->stat & FS_FILE_STATUS_OPERATING));
+ }
+ else
+ {
+ do
+ {
+ OS_SleepThread(p_file->queue);
+ } while (FS_IsBusy(p_file));
+ }
+ }
+ (void)OS_RestoreInterrupts(bak_par);
+ if (is_owner)
+ {
+ return FSi_ExecuteSyncCommand(p_file);
+ }
+
+ return FS_IsSucceeded(p_file);
+}
+
+ARM_FUNC int FS_ReadFileAsync(FSFile * p_file, void * dst, s32 len)
+{
+ return FSi_ReadFileCore(p_file, dst, len, TRUE);
+}
+
+ARM_FUNC int FS_ReadFile(FSFile * p_file, void * dst, s32 len)
+{
+ return FSi_ReadFileCore(p_file, dst, len, FALSE);
+}
+
+ARM_FUNC BOOL FS_SeekFile(FSFile * p_file, s32 offset, FSSeekFileMode origin)
+{
+ switch (origin)
+ {
+ case FS_SEEK_SET:
+ offset += p_file->prop.file.top;
+ break;
+ case FS_SEEK_CUR:
+ offset += p_file->prop.file.pos;
+ break;
+ case FS_SEEK_END:
+ offset += p_file->prop.file.bottom;
+ break;
+ default:
+ return FALSE;
+ }
+ if (offset < (s32)p_file->prop.file.top)
+ offset = (s32)p_file->prop.file.top;
+ if (offset > (s32)p_file->prop.file.bottom)
+ offset = (s32)p_file->prop.file.bottom;
+ p_file->prop.file.pos = (u32)offset;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_ChangeDir(const char * path)
+{
+ FSDirPos pos;
+ FSFile dir;
+ FS_InitFile(&dir);
+ if (!FSi_FindPath(&dir, path, NULL, &pos))
+ return FALSE;
+ current_dir_pos = pos;
+ return TRUE;
+}
diff --git a/arm9/lib/NitroSDK/src/FS_overlay.c b/arm9/lib/NitroSDK/src/FS_overlay.c
new file mode 100644
index 00000000..de64d97d
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FS_overlay.c
@@ -0,0 +1,320 @@
+#include "nitro.h"
+#include "DGT_common.h"
+#include "DGT_dgt.h"
+#include "OS_cache.h"
+#include "OS_system.h"
+#include "OS_printf.h"
+#include "MI_memory.h"
+#include "MI_uncompress.h"
+#include "FS_rom.h"
+#include "FS_overlay.h"
+#include "FS_mw_dtor.h"
+#include "MB_mb.h"
+
+#define FS_OVERLAY_FLAG_COMP 0x0001
+#define FS_OVERLAY_FLAG_AUTH 0x0002
+#define FS_OVERLAY_DIGEST_SIZE DGT_HASH2_DIGEST_SIZE
+
+ARM_FUNC u32 FSi_GetOverlayBinarySize(FSOverlayInfo * p_ovi)
+{
+ u32 size = (p_ovi->header.flag & FS_OVERLAY_FLAG_COMP)
+ ? p_ovi->header.compressed
+ : p_ovi->header.ram_size;
+ return size;
+}
+
+ARM_FUNC void FS_ClearOverlayImage(FSOverlayInfo * p_ovi)
+{
+ u8 * const im_start = FS_GetOverlayAddress(p_ovi);
+ u32 const ram_size = FS_GetOverlayImageSize(p_ovi);
+ u32 const total_size = FS_GetOverlayTotalSize(p_ovi);
+
+ IC_InvalidateRange(im_start, total_size);
+ DC_InvalidateRange(im_start, total_size);
+ MI_CpuFill8(im_start + ram_size, 0, total_size - ram_size);
+}
+
+ARM_FUNC FSFileID FS_GetOverlayFileID(FSOverlayInfo * p_ovi)
+{
+ FSFileID ret;
+ ret.arc = &fsi_arc_rom;
+ ret.file_id = p_ovi->header.file_id;
+ return ret;
+}
+
+ARM_FUNC BOOL FSi_LoadOverlayInfoCore(FSOverlayInfo * p_ovi, MIProcessor target, FSOverlayID id, FSArchive * arc, u32 offset_arm9, u32 len_arm9, u32 offset_arm7, u32 len_arm7)
+{
+ CARDRomRegion pr[1];
+ u32 pos;
+ if (target == MI_PROCESSOR_ARM9)
+ {
+ pr->offset = offset_arm9;
+ pr->length = len_arm9;
+ }
+ else
+ {
+ pr->offset = offset_arm7;
+ pr->length = len_arm7;
+ }
+ pos = (u32) id * sizeof(FSOverlayInfoHeader);
+ if (pos >= pr->length)
+ return FALSE;
+
+ FSFile file[1];
+ FS_InitFile(file);
+ // BOOL FS_OpenFileDirect(FSFile * p_file, FSArchive * p_arc, u32 image_top, u32 image_bottom, u32 file_index)
+ if (!FS_OpenFileDirect(file, arc, pr->offset + pos, pr->offset + pr->length, (u32)~0))
+ return FALSE;
+ if (FS_ReadFile(file, p_ovi, sizeof(FSOverlayInfoHeader)) != sizeof(FSOverlayInfoHeader))
+ {
+ (void)FS_CloseFile(file);
+ return FALSE;
+ }
+ (void)FS_CloseFile(file);
+ p_ovi->target = target;
+ if (!FS_OpenFileFast(file, FS_GetOverlayFileID(p_ovi)))
+ return FALSE;
+ p_ovi->file_pos.offset = FS_GetFileImageTop(file);
+ p_ovi->file_pos.length = FS_GetLength(file);
+ (void)FS_CloseFile(file);
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_LoadOverlayInfo(FSOverlayInfo * p_ovi, MIProcessor target, FSOverlayID id)
+{
+ CARDRomRegion * const pr = (target == MI_PROCESSOR_ARM9) ? &fsi_ovt9 : &fsi_ovt7;
+ if (pr->offset)
+ {
+ FSFile file[1];
+ const u32 pos = id * sizeof(FSOverlayInfoHeader);
+ if (pos >= pr->length)
+ return FALSE;
+ MI_CpuCopy8((const void *)(pr->offset + pos), p_ovi, sizeof(FSOverlayInfoHeader));
+ p_ovi->target = target;
+ FS_InitFile(file);
+ if (!FS_OpenFileFast(file, FS_GetOverlayFileID(p_ovi)))
+ return FALSE;
+ p_ovi->file_pos.offset = FS_GetFileImageTop(file);
+ p_ovi->file_pos.length = FS_GetLength(file);
+ (void)FS_CloseFile(file);
+ return TRUE;
+ }
+ else
+ {
+ const CARDRomRegion * const p_ovt9 = CARD_GetRomRegionOVT(MI_PROCESSOR_ARM9);
+ const CARDRomRegion * const p_ovt7 = CARD_GetRomRegionOVT(MI_PROCESSOR_ARM7);
+ return FSi_LoadOverlayInfoCore(p_ovi, target, id, &fsi_arc_rom, p_ovt9->offset, p_ovt9->length, p_ovt7->offset, p_ovt7->length);
+ }
+}
+
+ARM_FUNC BOOL FS_LoadOverlayImageAsync(FSOverlayInfo * p_ovi, FSFile * p_file)
+{
+ FS_InitFile(p_file);
+ if (!FS_OpenFileFast(p_file, FS_GetOverlayFileID(p_ovi)))
+ return FALSE;
+ else
+ {
+ s32 size = (s32)FSi_GetOverlayBinarySize(p_ovi);
+ FS_ClearOverlayImage(p_ovi);
+ if (FS_ReadFileAsync(p_file, FS_GetOverlayAddress(p_ovi), size) != size)
+ {
+ (void)FS_CloseFile(p_file);
+ return FALSE;
+ }
+ return TRUE;
+ }
+}
+
+ARM_FUNC BOOL FS_LoadOverlayImage(FSOverlayInfo * p_ovi)
+{
+ FSFile file[1];
+ FS_InitFile(file);
+ if (!FS_OpenFileFast(file, FS_GetOverlayFileID(p_ovi)))
+ return FALSE;
+ else
+ {
+ s32 size = (s32)FSi_GetOverlayBinarySize(p_ovi);
+ FS_ClearOverlayImage(p_ovi);
+ if (FS_ReadFile(file, FS_GetOverlayAddress(p_ovi), size) != size)
+ {
+ (void)FS_CloseFile(file);
+ return FALSE;
+ }
+ (void)FS_CloseFile(file);
+ return TRUE;
+ }
+}
+
+static const u8 fsi_def_digest_key[64] = {
+ 0x21, 0x06, 0xc0, 0xde,
+ 0xba, 0x98, 0xce, 0x3f,
+ 0xa6, 0x92, 0xe3, 0x9d,
+ 0x46, 0xf2, 0xed, 0x01,
+
+ 0x76, 0xe3, 0xcc, 0x08,
+ 0x56, 0x23, 0x63, 0xfa,
+ 0xca, 0xd4, 0xec, 0xdf,
+ 0x9a, 0x62, 0x78, 0x34,
+
+ 0x8f, 0x6d, 0x63, 0x3c,
+ 0xfe, 0x22, 0xca, 0x92,
+ 0x20, 0x88, 0x97, 0x23,
+ 0xd2, 0xcf, 0xae, 0xc2,
+
+ 0x32, 0x67, 0x8d, 0xfe,
+ 0xca, 0x83, 0x64, 0x98,
+ 0xac, 0xfd, 0x3e, 0x37,
+ 0x87, 0x46, 0x58, 0x24,
+};
+
+static const void *fsi_digest_key_ptr = fsi_def_digest_key;
+static u32 fsi_digest_key_len = sizeof(fsi_def_digest_key);
+
+ARM_FUNC BOOL FSi_CompareDigest(const u8 *spec_digest, void *src, u32 len)
+{
+ int i;
+ u8 digest[FS_OVERLAY_DIGEST_SIZE];
+ u8 digest_key[64];
+
+ MI_CpuClear8(digest, sizeof(digest));
+ MI_CpuCopy8(fsi_digest_key_ptr, digest_key, fsi_digest_key_len);
+ DGT_Hash2CalcHmac(digest, src, len, digest_key, fsi_digest_key_len);
+ for (i = 0; i < sizeof(digest); i += sizeof(u32))
+ {
+ if (*(const u32 *)(digest + i) != *(const u32 *)(spec_digest + i))
+ break;
+ }
+ return i == sizeof(digest);
+}
+
+extern u8 SDK_OVERLAY_DIGEST[];
+extern u8 SDK_OVERLAY_DIGEST_END[];
+
+ARM_FUNC void FS_StartOverlay(FSOverlayInfo * p_ovi)
+{
+ u32 rare_size = FSi_GetOverlayBinarySize(p_ovi);
+ if (MB_IsMultiBootChild())
+ {
+ BOOL ret = FALSE;
+
+ if (p_ovi->header.flag & FS_OVERLAY_FLAG_AUTH)
+ {
+ const u32 odt_max = (u32)((SDK_OVERLAY_DIGEST_END - SDK_OVERLAY_DIGEST) / FS_OVERLAY_DIGEST_SIZE);
+ if (p_ovi->header.id < odt_max)
+ {
+ const u8 * spec_digest = SDK_OVERLAY_DIGEST + FS_OVERLAY_DIGEST_SIZE * p_ovi->header.id;
+ ret = FSi_CompareDigest(spec_digest, p_ovi->header.ram_address, rare_size);
+ }
+ }
+ if (!ret)
+ {
+ MI_CpuClear8(p_ovi->header.ram_address, rare_size);
+ OS_TPanic("FS_StartOverlay() failed! (invalid overlay-segment data)");
+ return;
+ }
+ }
+ if (p_ovi->header.flag & FS_OVERLAY_FLAG_COMP)
+ {
+ MIi_UncompressBackward(p_ovi->header.ram_address + rare_size);
+ }
+ DC_FlushRange(p_ovi->header.ram_address, p_ovi->header.ram_size);
+
+ {
+ FSOverlayInitFunc *p = p_ovi->header.sinit_init;
+ FSOverlayInitFunc *q = p_ovi->header.sinit_init_end;
+ for (; p < q; ++p)
+ {
+ if (*p)
+ (**p)();
+ }
+ }
+}
+
+ARM_FUNC void FS_EndOverlay(FSOverlayInfo *p_ovi)
+{
+ for (;;)
+ {
+ MWiDestructorChain *head = NULL, *tail = NULL;
+ const u32 region_top = (u32)FS_GetOverlayAddress(p_ovi);
+ const u32 region_bottom = region_top + FS_GetOverlayTotalSize(p_ovi);
+
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ MWiDestructorChain *prev = NULL;
+ MWiDestructorChain *base = __global_destructor_chain;
+ MWiDestructorChain *p = base;
+ while (p)
+ {
+ MWiDestructorChain *next = p->next;
+ const u32 dtor = (u32)p->dtor;
+ const u32 obj = (u32)p->obj;
+ if (((obj == 0) && (dtor >= region_top) && (dtor < region_bottom)) ||
+ ((obj >= region_top) && (obj < region_bottom)))
+ {
+ /* If appropriate, extract*/
+ if (!tail)
+ {
+ head = p;
+ }
+ else
+ {
+ tail->next = p;
+ }
+ if (base == p)
+ {
+ base = __global_destructor_chain = next;
+ }
+ tail = p, p->next = NULL;
+ if (prev)
+ {
+ prev->next = next;
+ }
+ }
+ else
+ {
+ prev = p;
+ }
+ p = next;
+ }
+ (void)OS_RestoreInterrupts(bak_psr);
+ }
+
+ if (!head)
+ {
+ break;
+ }
+ do
+ {
+ MWiDestructorChain *next = head->next;
+ if (head->dtor)
+ {
+ (*head->dtor) (head->obj);
+ }
+ head = next;
+ }
+ while (head);
+ }
+}
+
+ARM_FUNC BOOL FS_UnloadOverlayImage(FSOverlayInfo * p_ovi)
+{
+ FS_EndOverlay(p_ovi);
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_LoadOverlay(MIProcessor target, FSOverlayID id)
+{
+ FSOverlayInfo ovi;
+ if (!FS_LoadOverlayInfo(&ovi, target, id) || !FS_LoadOverlayImage(&ovi))
+ return FALSE;
+ FS_StartOverlay(&ovi);
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_UnloadOverlay(MIProcessor target, FSOverlayID id)
+{
+ FSOverlayInfo ovi;
+ if (!FS_LoadOverlayInfo(&ovi, target, id) || !FS_UnloadOverlayImage(&ovi))
+ return FALSE;
+ return TRUE;
+}
diff --git a/arm9/lib/NitroSDK/src/FS_rom.c b/arm9/lib/NitroSDK/src/FS_rom.c
new file mode 100644
index 00000000..09098dfe
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FS_rom.c
@@ -0,0 +1,126 @@
+#include "FS_rom.h"
+#include "FS_archive.h"
+#include "FS_file.h"
+#include "CARD_pullOut.h"
+#include "CARD_rom.h"
+#include "CARD_common.h"
+#include "MB_mb.h"
+#include "OS_printf.h"
+
+static u32 fsi_default_dma_no;
+s32 fsi_card_lock_id;
+CARDRomRegion fsi_ovt9;
+CARDRomRegion fsi_ovt7;
+FSArchive fsi_arc_rom;
+
+ARM_FUNC void FSi_OnRomReadDone(void * p_arc)
+{
+ FS_NotifyArchiveAsyncEnd(p_arc, CARD_IsPulledOut() ? FS_RESULT_ERROR : FS_RESULT_SUCCESS);
+}
+
+ARM_FUNC FSResult FSi_ReadRomCallback(FSArchive * p_arc, void * dst, u32 src, u32 len)
+{
+ CARD_ReadRomAsync(fsi_default_dma_no, (const void *)src, dst, len, FSi_OnRomReadDone, p_arc);
+ return FS_RESULT_PROC_ASYNC;
+}
+
+ARM_FUNC FSResult FSi_WriteDummyCallback(FSArchive * p_arc, const void *src, u32 dst, u32 len)
+{
+#pragma unused(p_arc, src, dst, len)
+ return FS_RESULT_FAILURE;
+}
+
+ARM_FUNC FSResult FSi_RomArchiveProc(FSFile * p_arc, FSCommandType cmd)
+{
+#pragma unused(p_arc)
+ switch (cmd)
+ {
+ case FS_COMMAND_ACTIVATE:
+ CARD_LockRom((u16)fsi_card_lock_id);
+ return FS_RESULT_SUCCESS;
+ case FS_COMMAND_IDLE:
+ CARD_UnlockRom((u16)fsi_card_lock_id);
+ return FS_RESULT_SUCCESS;
+ case FS_COMMAND_WRITEFILE:
+ return FS_RESULT_UNSUPPORTED;
+ default:
+ return FS_RESULT_PROC_UNKNOWN;
+ }
+}
+
+ARM_FUNC FSResult FSi_ReadDummyCallback(FSArchive *p_arc, void *dst, u32 src, u32 len)
+{
+#pragma unused (p_arc, dst, src, len)
+ return FS_RESULT_FAILURE;
+}
+
+ARM_FUNC FSResult FSi_EmptyArchiveProc(FSFile *p_file, FSCommandType cmd)
+{
+#pragma unused(p_file, cmd)
+ return FS_RESULT_UNSUPPORTED;
+}
+
+ARM_FUNC void FSi_InitRom(u32 default_dma_no)
+{
+ fsi_default_dma_no = default_dma_no;
+ fsi_card_lock_id = OS_GetLockID();
+ fsi_ovt9.offset = 0;
+ fsi_ovt9.length = 0;
+ fsi_ovt7.offset = 0;
+ fsi_ovt7.length = 0;
+
+ CARD_Init();
+
+ FS_InitArchive(&fsi_arc_rom);
+ (void)FS_RegisterArchiveName(&fsi_arc_rom, "rom", 3);
+
+ if (MB_IsMultiBootChild())
+ {
+ fsi_ovt9.offset = (u32)~0;
+ fsi_ovt9.length = 0;
+ fsi_ovt7.offset = (u32)~0;
+ fsi_ovt7.length = 0;
+ FS_SetArchiveProc(&fsi_arc_rom, FSi_EmptyArchiveProc, (u32)FS_ARCHIVE_PROC_ALL);
+ (void)FS_LoadArchive(&fsi_arc_rom, 0x00000000, 0, 0, 0, 0, FSi_ReadDummyCallback, FSi_WriteDummyCallback);
+ }
+ else
+ {
+ const CARDRomRegion *const fnt = CARD_GetRomRegionFNT();
+ const CARDRomRegion *const fat = CARD_GetRomRegionFAT();
+
+ FS_SetArchiveProc(&fsi_arc_rom, FSi_RomArchiveProc,
+ FS_ARCHIVE_PROC_WRITEFILE |
+ FS_ARCHIVE_PROC_ACTIVATE | FS_ARCHIVE_PROC_IDLE);
+
+ if ((fnt->offset == 0xFFFFFFFF) || (fnt->offset == 0x00000000) ||
+ (fat->offset == 0xFFFFFFFF) || (fat->offset == 0x00000000))
+ {
+ OS_Warning("file-system : no MAKEROM-information in rom header.");
+ }
+ else
+ {
+ (void)FS_LoadArchive(&fsi_arc_rom, 0x00000000,
+ fat->offset, fat->length,
+ fnt->offset, fnt->length,
+ FSi_ReadRomCallback, FSi_WriteDummyCallback);
+ }
+ }
+}
+
+ARM_FUNC u32 FS_SetDefaultDMA(u32 dma_no)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ u32 bak_dma_no = fsi_default_dma_no;
+ BOOL bak_stat = FS_SuspendArchive(&fsi_arc_rom);
+ fsi_default_dma_no = dma_no;
+ if (bak_stat)
+ (void)FS_ResumeArchive(&fsi_arc_rom);
+ (void)OS_RestoreInterrupts(bak_psr);
+ return bak_dma_no;
+}
+
+ARM_FUNC u32 FS_TryLoadTable(void * p_mem, u32 size)
+{
+ return FS_LoadArchiveTables(&fsi_arc_rom, p_mem, size);
+}
+
diff --git a/arm9/lib/NitroSDK/src/FX.c b/arm9/lib/NitroSDK/src/FX.c
new file mode 100644
index 00000000..ea730538
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX.c
@@ -0,0 +1,19 @@
+#include "global.h"
+#include "fx.h"
+
+ARM_FUNC void FX_Init(){
+ return;
+}
+
+ARM_FUNC fx32 FX_Modf(fx32 x, fx32 *iptr){
+ if (x >= 0)
+ {
+ *iptr = x & 0x7FFFF000;
+ return x & 0xFFF;
+ }
+ else
+ {
+ *iptr = -(-x & 0x7FFFF000);
+ return -(-x & 0xFFF);
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/FX_atan.c b/arm9/lib/NitroSDK/src/FX_atan.c
new file mode 100644
index 00000000..ef2a662d
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX_atan.c
@@ -0,0 +1,289 @@
+#include "global.h"
+#include "fx.h"
+
+const fx16 FX_AtanTable_[] = {
+ FX16_CONST(0.0),
+ FX16_CONST(0.019775390625),
+ FX16_CONST(0.039794921875),
+ FX16_CONST(0.0595703125),
+ FX16_CONST(0.07958984375),
+ FX16_CONST(0.099365234375),
+ FX16_CONST(0.119384765625),
+ FX16_CONST(0.13916015625),
+ FX16_CONST(0.158935546875),
+ FX16_CONST(0.1787109375),
+ FX16_CONST(0.198486328125),
+ FX16_CONST(0.21826171875),
+ FX16_CONST(0.238037109375),
+ FX16_CONST(0.2578125),
+ FX16_CONST(0.27734375),
+ FX16_CONST(0.297119140625),
+ FX16_CONST(0.316650390625),
+ FX16_CONST(0.336181640625),
+ FX16_CONST(0.355712890625),
+ FX16_CONST(0.375244140625),
+ FX16_CONST(0.394775390625),
+ FX16_CONST(0.4140625),
+ FX16_CONST(0.433349609375),
+ FX16_CONST(0.45263671875),
+ FX16_CONST(0.471923828125),
+ FX16_CONST(0.4912109375),
+ FX16_CONST(0.51025390625),
+ FX16_CONST(0.529296875),
+ FX16_CONST(0.54833984375),
+ FX16_CONST(0.5673828125),
+ FX16_CONST(0.586181640625),
+ FX16_CONST(0.60498046875),
+ FX16_CONST(0.623779296875),
+ FX16_CONST(0.642578125),
+ FX16_CONST(0.6611328125),
+ FX16_CONST(0.6796875),
+ FX16_CONST(0.6982421875),
+ FX16_CONST(0.716552734375),
+ FX16_CONST(0.73486328125),
+ FX16_CONST(0.753173828125),
+ FX16_CONST(0.771240234375),
+ FX16_CONST(0.789306640625),
+ FX16_CONST(0.807373046875),
+ FX16_CONST(0.8251953125),
+ FX16_CONST(0.843017578125),
+ FX16_CONST(0.86083984375),
+ FX16_CONST(0.878662109375),
+ FX16_CONST(0.89599609375),
+ FX16_CONST(0.91357421875),
+ FX16_CONST(0.930908203125),
+ FX16_CONST(0.9482421875),
+ FX16_CONST(0.965576171875),
+ FX16_CONST(0.982666015625),
+ FX16_CONST(0.999755859375),
+ FX16_CONST(1.0166015625),
+ FX16_CONST(1.033447265625),
+ FX16_CONST(1.05029296875),
+ FX16_CONST(1.06689453125),
+ FX16_CONST(1.08349609375),
+ FX16_CONST(1.099853515625),
+ FX16_CONST(1.1162109375),
+ FX16_CONST(1.132568359375),
+ FX16_CONST(1.148681640625),
+ FX16_CONST(1.164794921875),
+ FX16_CONST(1.1806640625),
+ FX16_CONST(1.196533203125),
+ FX16_CONST(1.21240234375),
+ FX16_CONST(1.22802734375),
+ FX16_CONST(1.24365234375),
+ FX16_CONST(1.259033203125),
+ FX16_CONST(1.2744140625),
+ FX16_CONST(1.28955078125),
+ FX16_CONST(1.3046875),
+ FX16_CONST(1.31982421875),
+ FX16_CONST(1.334716796875),
+ FX16_CONST(1.349609375),
+ FX16_CONST(1.364501953125),
+ FX16_CONST(1.379150390625),
+ FX16_CONST(1.3935546875),
+ FX16_CONST(1.408203125),
+ FX16_CONST(1.42236328125),
+ FX16_CONST(1.436767578125),
+ FX16_CONST(1.450927734375),
+ FX16_CONST(1.46484375),
+ FX16_CONST(1.47900390625),
+ FX16_CONST(1.49267578125),
+ FX16_CONST(1.506591796875),
+ FX16_CONST(1.520263671875),
+ FX16_CONST(1.53369140625),
+ FX16_CONST(1.547119140625),
+ FX16_CONST(1.560546875),
+ FX16_CONST(1.57373046875),
+ FX16_CONST(1.5869140625),
+ FX16_CONST(1.60009765625),
+ FX16_CONST(1.613037109375),
+ FX16_CONST(1.6259765625),
+ FX16_CONST(1.638671875),
+ FX16_CONST(1.6513671875),
+ FX16_CONST(1.663818359375),
+ FX16_CONST(1.676513671875),
+ FX16_CONST(1.688720703125),
+ FX16_CONST(1.701171875),
+ FX16_CONST(1.71337890625),
+ FX16_CONST(1.7255859375),
+ FX16_CONST(1.737548828125),
+ FX16_CONST(1.74951171875),
+ FX16_CONST(1.76123046875),
+ FX16_CONST(1.77294921875),
+ FX16_CONST(1.78466796875),
+ FX16_CONST(1.79638671875),
+ FX16_CONST(1.807861328125),
+ FX16_CONST(1.819091796875),
+ FX16_CONST(1.83056640625),
+ FX16_CONST(1.841796875),
+ FX16_CONST(1.852783203125),
+ FX16_CONST(1.864013671875),
+ FX16_CONST(1.874755859375),
+ FX16_CONST(1.8857421875),
+ FX16_CONST(1.896484375),
+ FX16_CONST(1.9072265625),
+ FX16_CONST(1.91796875),
+ FX16_CONST(1.928466796875),
+ FX16_CONST(1.93896484375),
+ FX16_CONST(1.94921875),
+ FX16_CONST(1.95947265625),
+ FX16_CONST(1.9697265625),
+ FX16_CONST(1.97998046875),
+ FX16_CONST(1.989990234375),
+ FX16_CONST(2.0),
+};
+
+ARM_FUNC u16 FX_Atan(fx32 x){
+ if (x >= 0)
+ {
+ if (x > 0x1000)
+ {
+ x = FX_Inv(x);
+ fx16 y = FX_AtanTable_[x >> 5];
+ return (u16)(0x4000 - y);
+ }
+ else if (x < 0x1000)
+ {
+ return (u16)FX_AtanTable_[x >> 5];
+ }
+ else
+ {
+ return 0x2000;
+ }
+ }
+ else
+ {
+ if (x < -0x1000)
+ {
+ x = FX_Inv(-x);
+ fx16 y = FX_AtanTable_[x >> 5];
+ return (u16)(y - 0x4000);
+ }
+ else if (x > -0x1000)
+ {
+ return (u16)(-FX_AtanTable_[-x >> 5]);
+ }
+ else
+ {
+ return (u16)(-0x2000);
+ }
+ }
+}
+
+ARM_FUNC u16 FX_Atan2(fx32 x, fx32 y){
+ u32 positive, bias, denominator, numerator;
+ if (x > 0)
+ {
+ if (y > 0)
+ {
+ if (y > x)
+ {
+ numerator = (u32)x;
+ denominator = (u32)y;
+ bias = 0;
+ positive = TRUE;
+ }
+ else if (y < x)
+ {
+ numerator = (u32)y;
+ denominator = (u32)x;
+ bias = 0x4000;
+ positive = FALSE;
+ }
+ else
+ {
+ return 0x2000;
+ }
+ }
+ else if (y < 0)
+ {
+ y = -y;
+ if (y < x)
+ {
+ numerator = (u32)y;
+ denominator = (u32)x;
+ bias = 0x4000;
+ positive = TRUE;
+ }
+ else if (y > x)
+ {
+ numerator = (u32)x;
+ denominator = (u32)y;
+ bias = 0x8000;
+ positive = FALSE;
+ }
+ else
+ {
+ return 0x6000;
+ }
+ }
+ else
+ {
+ return 0x4000;
+ }
+ }
+ else if (x < 0)
+ {
+ x = -x;
+ if (y < 0)
+ {
+ y = -y;
+ if (y > x)
+ {
+ numerator = (u32)x;
+ denominator = (u32)y;
+ bias = (u32)(-0x8000);
+ positive = TRUE;
+ }
+ else if (y < x)
+ {
+ numerator = (u32)y;
+ denominator = (u32)x;
+ bias = (u32)(-0x4000);
+ positive = FALSE;
+ }
+ else
+ {
+ return 0xA000;
+ }
+ }
+ else if (y > 0)
+ {
+ if (y < x)
+ {
+ numerator = (u32)y;
+ denominator = (u32)x;
+ bias = (u32)(-0x4000);
+ positive = TRUE;
+ }
+ else if (y > x)
+ {
+ numerator = (u32)x;
+ denominator = (u32)y;
+ bias = 0x0;
+ positive = FALSE;
+ }
+ else
+ {
+ return 0xE000;
+ }
+ }
+ else
+ {
+ return 0xC000;
+ }
+ }
+ else
+ {
+ if (y >= 0)
+ return 0x0;
+ else
+ return 0x8000;
+ }
+ if (denominator == 0x0)
+ return 0x0;
+ if (positive)
+ return (u16)(bias + FX_AtanTable_[FX_Div((fx32)numerator, (fx32)denominator) >> 5]);
+ else
+ return (u16)(bias - FX_AtanTable_[FX_Div((fx32)numerator, (fx32)denominator) >> 5]);
+}
diff --git a/arm9/lib/NitroSDK/src/FX_cp.c b/arm9/lib/NitroSDK/src/FX_cp.c
new file mode 100644
index 00000000..0c5d4ff8
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX_cp.c
@@ -0,0 +1,71 @@
+#include "fx.h"
+
+#include "global.h"
+#include "registers.h"
+
+
+ARM_FUNC fx32 FX_Div(fx32 numerator, fx32 denominator){
+ FX_DivAsync(numerator, denominator);
+ return FX_GetDivResult();
+}
+
+ARM_FUNC fx32 FX_Inv(fx32 x){
+ FX_InvAsync(x);
+ return FX_GetDivResult();
+}
+
+ARM_FUNC fx32 FX_Sqrt(fx32 x){
+ if (x > 0)
+ {
+ reg_CP_SQRTCNT = 0x1;
+ reg_CP_SQRT_PARAM = (u64)((fx64)x << 32);
+ return FX_GetSqrtResult();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+ARM_FUNC fx64c FX_GetDivResultFx64c(){
+ while (reg_CP_DIVCNT & 0x8000) {}
+ return (fx64c)reg_CP_DIV_RESULT;
+}
+
+ARM_FUNC fx32 FX_GetDivResult(){
+ while (reg_CP_DIVCNT & 0x8000) {}
+ return (fx32)((reg_CP_DIV_RESULT + (1 << (0x14 - 1))) >> 0x14);
+}
+
+ARM_FUNC void FX_InvAsync(fx32 x){
+ reg_CP_DIVCNT = 0x1;
+ reg_CP_DIV_NUMER = (fx64)0x00001000 << 32;
+ reg_CP_DIV_DENOM = (u32)x;
+}
+
+ARM_FUNC fx32 FX_GetSqrtResult(){
+ while (reg_CP_SQRTCNT & 0x8000) {}
+ return (fx32)((reg_CP_SQRT_RESULT + (1 << (0xA - 1))) >> 0xA);
+}
+
+ARM_FUNC void FX_DivAsync(fx32 numerator, fx32 denominator){
+ reg_CP_DIVCNT = 0x1;
+ reg_CP_DIV_NUMER = (u64)((fx64)numerator << 32);
+ reg_CP_DIV_DENOM = (u32)denominator;
+}
+
+ARM_FUNC fx32 FX_DivS32(fx32 numerator, fx32 denominator){
+ reg_CP_DIVCNT = 0x0;
+ *(REGType32v *)&reg_CP_DIV_NUMER = (u32)numerator; //32bit write for some reason
+ reg_CP_DIV_DENOM = (u32)denominator;
+ while (reg_CP_DIVCNT & 0x8000) {}
+ return (fx32)(*(REGType32v *)&reg_CP_DIV_RESULT);
+}
+
+ARM_FUNC fx32 FX_ModS32(fx32 num, fx32 mod){
+ reg_CP_DIVCNT = 0x0;
+ *(REGType32v *)&reg_CP_DIV_NUMER = (u32)num; //32bit write for some reason
+ reg_CP_DIV_DENOM = (u32)mod;
+ while (reg_CP_DIVCNT & 0x8000) {}
+ return (fx32)(*(REGType32v *)&reg_CP_DIVREM_RESULT);
+}
diff --git a/arm9/lib/NitroSDK/src/FX_mtx22.c b/arm9/lib/NitroSDK/src/FX_mtx22.c
new file mode 100644
index 00000000..a74bb25c
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX_mtx22.c
@@ -0,0 +1,28 @@
+#include "global.h"
+#include "main.h"
+#include "fx.h"
+
+ARM_FUNC void MTX_ScaleApply22(struct Mtx22 *mtx, struct Mtx22 *dst, fx32 x, fx32 y){
+ dst->_[0] = (fx32)(((fx64)x * mtx->_[0]) >> FX32_INT_SHIFT);
+ dst->_[1] = (fx32)(((fx64)x * mtx->_[1]) >> FX32_INT_SHIFT);
+ dst->_[2] = (fx32)(((fx64)y * mtx->_[2]) >> FX32_INT_SHIFT);
+ dst->_[3] = (fx32)(((fx64)y * mtx->_[3]) >> FX32_INT_SHIFT);
+}
+
+ARM_FUNC asm void MTX_Identity22_(struct Mtx22 *mtx){
+ mov r1, #0x0
+ mov r2, #0x1000
+ mov r3, #0x0
+ stmia r0!, {r2-r3}
+ stmia r0!, {r1-r2}
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_Rot22_(struct Mtx22 *mtx, fx32 sinphi, fx32 cosphi){
+ str r2, [r0, #0x0]
+ str r1, [r0, #0x4]
+ neg r1, r1
+ str r1, [r0, #0x8]
+ str r2, [r0, #0xc]
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/FX_mtx33.c b/arm9/lib/NitroSDK/src/FX_mtx33.c
new file mode 100644
index 00000000..86169ea0
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX_mtx33.c
@@ -0,0 +1,129 @@
+#include "global.h"
+#include "main.h"
+#include "fx.h"
+
+ARM_FUNC void MTX_ScaleApply33(struct Mtx33 *mtx, struct Mtx33 *dst, fx32 x, fx32 y, fx32 z){
+ dst->_[0] = (fx32)(((fx64)x * mtx->_[0]) >> FX32_INT_SHIFT);
+ dst->_[1] = (fx32)(((fx64)x * mtx->_[1]) >> FX32_INT_SHIFT);
+ dst->_[2] = (fx32)(((fx64)x * mtx->_[2]) >> FX32_INT_SHIFT);
+ dst->_[3] = (fx32)(((fx64)y * mtx->_[3]) >> FX32_INT_SHIFT);
+ dst->_[4] = (fx32)(((fx64)y * mtx->_[4]) >> FX32_INT_SHIFT);
+ dst->_[5] = (fx32)(((fx64)y * mtx->_[5]) >> FX32_INT_SHIFT);
+ dst->_[6] = (fx32)(((fx64)z * mtx->_[6]) >> FX32_INT_SHIFT);
+ dst->_[7] = (fx32)(((fx64)z * mtx->_[7]) >> FX32_INT_SHIFT);
+ dst->_[8] = (fx32)(((fx64)z * mtx->_[8]) >> FX32_INT_SHIFT);
+}
+
+ARM_FUNC void MTX_Concat33(struct Mtx33 *a, struct Mtx33 *b, struct Mtx33 *c){
+ struct Mtx33 temp;
+ struct Mtx33 *dst;
+ fx32 a0, a1, a2;
+ fx32 b0, b1, b2;
+
+ if (c == b)
+ dst = &temp;
+ else
+ dst = c;
+
+ a0 = a->_[0];
+ a1 = a->_[1];
+ a2 = a->_[2];
+ dst->_[0] = (fx32)(((fx64)a0 * b->_[0] + (fx64)a1 * b->_[3] + (fx64)a2 * b->_[6] ) >> FX32_INT_SHIFT);
+ dst->_[1] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[7] ) >> FX32_INT_SHIFT);
+ b0 = b->_[2];
+ b1 = b->_[5];
+ b2 = b->_[8];
+ dst->_[2] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ a0 = a->_[3];
+ a1 = a->_[4];
+ a2 = a->_[5];
+ dst->_[5] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ dst->_[4] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[7] ) >> FX32_INT_SHIFT);
+ b0 = b->_[0];
+ b1 = b->_[3];
+ b2 = b->_[6];
+ dst->_[3] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ a0 = a->_[6];
+ a1 = a->_[7];
+ a2 = a->_[8];
+ dst->_[6] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ dst->_[7] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[7] ) >> FX32_INT_SHIFT);
+ b0 = b->_[2];
+ b1 = b->_[5];
+ b2 = b->_[8];
+ dst->_[8] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+
+ if (dst == &temp)
+ *c = temp;
+}
+
+ARM_FUNC void MTX_MultVec33(struct Vecx32 *vec, struct Mtx33 *mtx, struct Vecx32 *dst){
+ fx32 x, y, z;
+ x = vec->x;
+ y = vec->y;
+ z = vec->z;
+ dst->x = (fx32)(((fx64)x * mtx->_[0] + (fx64)y * mtx->_[3] + (fx64)z * mtx->_[6]) >> FX32_INT_SHIFT);
+ dst->y = (fx32)(((fx64)x * mtx->_[1] + (fx64)y * mtx->_[4] + (fx64)z * mtx->_[7]) >> FX32_INT_SHIFT);
+ dst->z = (fx32)(((fx64)x * mtx->_[2] + (fx64)y * mtx->_[5] + (fx64)z * mtx->_[8]) >> FX32_INT_SHIFT);
+}
+
+ARM_FUNC asm void MTX_Identity33_(struct Mtx33 *mtx){
+ mov r2, #0x1000
+ str r2, [r0, #0x20]
+ mov r3, #0x0
+ stmia r0!, {r2-r3}
+ mov r1, #0x0
+ stmia r0!, {r1,r3}
+ stmia r0!, {r2-r3}
+ stmia r0!, {r1,r3}
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_RotX33_(struct Mtx33 *mtx, fx32 sinphi, fx32 cosphi){
+ mov r3, #0x1
+ lsl r3, r3, #0xc
+ str r3, [r0, #0x0]
+ mov r3, #0x0
+ str r3, [r0, #0x4]
+ str r3, [r0, #0x8]
+ str r3, [r0, #0xc]
+ str r2, [r0, #0x10]
+ str r1, [r0, #0x14]
+ str r3, [r0, #0x18]
+ neg r1, r1
+ str r1, [r0, #0x1c]
+ str r2, [r0, #0x20]
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_RotY33_(struct Mtx33 *mtx, fx32 sinphi, fx32 cosphi){
+ str r2, [r0, #0x0]
+ str r2, [r0, #0x20]
+ mov r3, #0x0
+ str r3, [r0, #0x4]
+ str r3, [r0, #0xc]
+ str r3, [r0, #0x14]
+ str r3, [r0, #0x1c]
+ neg r2, r1
+ mov r3, #0x1
+ lsl r3, r3, #0xc
+ str r1, [r0, #0x18]
+ str r2, [r0, #0x8]
+ str r3, [r0, #0x10]
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_RotZ33_(struct Mtx33 *mtx, fx32 sinphi, fx32 cosphi){
+ stmia r0!, {r2}
+ mov r3, #0x0
+ stmia r0!, {r1,r3}
+ neg r1, r1
+ stmia r0!, {r1-r2}
+ mov r1, #0x1
+ lsl r1, r1, #0xc
+ str r3, [r0, #0x0]
+ str r3, [r0, #0x4]
+ str r3, [r0, #0x8]
+ str r1, [r0, #0xc]
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/FX_mtx43.c b/arm9/lib/NitroSDK/src/FX_mtx43.c
new file mode 100644
index 00000000..693dddff
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX_mtx43.c
@@ -0,0 +1,200 @@
+#include "global.h"
+#include "main.h"
+#include "fx.h"
+
+void MI_Copy48B(void *src, void *dst);
+
+
+ARM_FUNC void MTX_ScaleApply43(struct Mtx43 *mtx, struct Mtx43 *dst, fx32 x, fx32 y, fx32 z){
+ //this works because matrices are indexed columns first
+ MTX_ScaleApply33((struct Mtx33 *)mtx, (struct Mtx33 *)dst, x, y, z);
+ dst->_[9] = mtx->_[9];
+ dst->_[10] = mtx->_[10];
+ dst->_[11] = mtx->_[11];
+}
+
+ARM_FUNC fx32 MTX_Inverse43(struct Mtx43 *mtx, struct Mtx43 *inv){
+ struct Mtx43 tempmat;
+ struct Mtx43 *dst;
+ fx32 det0, det1, det2, det;
+ fx32 var0, var1, var2, var3;
+ if (mtx == inv)
+ dst = &tempmat;
+ else
+ dst = inv;
+ //subdeterminants
+ det0 = (fx32)(((fx64)mtx->_[4] * mtx->_[8] - (fx64)mtx->_[5] * mtx->_[7] + (fx64)(1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT);
+ det1 = (fx32)(((fx64)mtx->_[3] * mtx->_[8] - (fx64)mtx->_[5] * mtx->_[6] + (fx64)(1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT);
+ det2 = (fx32)(((fx64)mtx->_[3] * mtx->_[7] - (fx64)mtx->_[4] * mtx->_[6] + (fx64)(1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT);
+ //matrix determinant
+ det = (fx32)(((fx64)mtx->_[0] * det0 - (fx64)mtx->_[1] * det1 + (fx64)mtx->_[2] * det2 + (fx64)(1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT);
+
+ if (det == 0)
+ return -1; //not invertible
+
+ FX_InvAsync(det);
+
+ var0 = (fx32)(((fx64)mtx->_[1] * mtx->_[8] - (fx64)mtx->_[7] * mtx->_[2]) >> FX32_INT_SHIFT);
+ var1 = (fx32)(((fx64)mtx->_[1] * mtx->_[5] - (fx64)mtx->_[4] * mtx->_[2]) >> FX32_INT_SHIFT);
+ var2 = (fx32)(((fx64)mtx->_[0] * mtx->_[8] - (fx64)mtx->_[6] * mtx->_[2]) >> FX32_INT_SHIFT);
+ var3 = (fx32)(((fx64)mtx->_[0] * mtx->_[5] - (fx64)mtx->_[3] * mtx->_[2]) >> FX32_INT_SHIFT);
+
+ fx32 ret = FX_GetDivResult();
+ dst->_[0] = (fx32)(((fx64)ret * det0) >> FX32_INT_SHIFT);
+ dst->_[1] = -(fx32)(((fx64)ret * var0) >> FX32_INT_SHIFT);
+ dst->_[2] = (fx32)(((fx64)ret * var1) >> FX32_INT_SHIFT);
+ dst->_[3] = -(fx32)(((fx64)ret * det1) >> FX32_INT_SHIFT);
+ dst->_[4] = (fx32)(((fx64)ret * var2) >> FX32_INT_SHIFT);
+ dst->_[5] = -(fx32)(((fx64)ret * var3) >> FX32_INT_SHIFT);
+
+ dst->_[6] = (fx32)(((fx64)ret * det2) >> FX32_INT_SHIFT);
+ fx32 temp = (fx32)(((fx64)mtx->_[0] * mtx->_[7] - (fx64)mtx->_[6] * mtx->_[1]) >> FX32_INT_SHIFT);
+ dst->_[7] = -(fx32)(((fx64)ret * temp) >> FX32_INT_SHIFT);
+ fx32 temp1 = (fx32)(((fx64)mtx->_[0] * mtx->_[4] - (fx64)mtx->_[3] * mtx->_[1]) >> FX32_INT_SHIFT);
+ dst->_[8] = (fx32)(((fx64)ret * temp1) >> FX32_INT_SHIFT);
+ dst->_[9] = -(fx32)(((fx64)dst->_[0] * mtx->_[9] + (fx64)dst->_[3] * mtx->_[10] + (fx64)dst->_[6] * mtx->_[11]) >> FX32_INT_SHIFT);
+ dst->_[10] = -(fx32)(((fx64)dst->_[1] * mtx->_[9] + (fx64)dst->_[4] * mtx->_[10] + (fx64)dst->_[7] * mtx->_[11]) >> FX32_INT_SHIFT);
+ dst->_[11] = -(fx32)(((fx64)dst->_[2] * mtx->_[9] + (fx64)dst->_[5] * mtx->_[10] + (fx64)dst->_[8] * mtx->_[11]) >> FX32_INT_SHIFT);
+
+ if (dst == &tempmat)
+ MI_Copy48B(&tempmat, inv);
+ return 0;
+}
+
+ARM_FUNC void MTX_Concat43(struct Mtx43 *a, struct Mtx43 *b, struct Mtx43 *c){
+ struct Mtx43 temp;
+ struct Mtx43 *dst;
+ fx32 a0, a1, a2;
+ fx32 b0, b1, b2;
+
+ if (c == b)
+ dst = &temp;
+ else
+ dst = c;
+
+ a0 = a->_[0];
+ a1 = a->_[1];
+ a2 = a->_[2];
+ dst->_[0] = (fx32)(((fx64)a0 * b->_[0] + (fx64)a1 * b->_[3] + (fx64)a2 * b->_[6] ) >> FX32_INT_SHIFT);
+ dst->_[1] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[7] ) >> FX32_INT_SHIFT);
+ b0 = b->_[2];
+ b1 = b->_[5];
+ b2 = b->_[8];
+ dst->_[2] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ a0 = a->_[3];
+ a1 = a->_[4];
+ a2 = a->_[5];
+ dst->_[5] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ dst->_[4] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[7] ) >> FX32_INT_SHIFT);
+ b0 = b->_[0];
+ b1 = b->_[3];
+ b2 = b->_[6];
+ dst->_[3] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ a0 = a->_[6];
+ a1 = a->_[7];
+ a2 = a->_[8];
+ dst->_[6] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ dst->_[7] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[7] ) >> FX32_INT_SHIFT);
+ b0 = b->_[2];
+ b1 = b->_[5];
+ b2 = b->_[8];
+ dst->_[8] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT);
+ a0 = a->_[9];
+ a1 = a->_[10];
+ a2 = a->_[11];
+ dst->_[11] = (fx32)((((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2) >> FX32_INT_SHIFT) + b->_[11]);
+ dst->_[10] = (fx32)((((fx64)a0 * b->_[1] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[7]) >> FX32_INT_SHIFT) + b->_[10]);
+ dst->_[9] = (fx32)((((fx64)a0 * b->_[0] + (fx64)a1 * b->_[3] + (fx64)a2 * b->_[6]) >> FX32_INT_SHIFT) + b->_[9]);
+ if (dst == &temp)
+ *c = temp;
+}
+
+ARM_FUNC void MTX_MultVec43(struct Vecx32 *vec, struct Mtx43 *mtx, struct Vecx32 *dst){
+ fx32 x, y, z;
+ x = vec->x;
+ y = vec->y;
+ z = vec->z;
+ dst->x = (fx32)(((fx64)x * mtx->_[0] + (fx64)y * mtx->_[3] + (fx64)z * mtx->_[6]) >> FX32_INT_SHIFT);
+ dst->x += mtx->_[9];
+ dst->y = (fx32)(((fx64)x * mtx->_[1] + (fx64)y * mtx->_[4] + (fx64)z * mtx->_[7]) >> FX32_INT_SHIFT);
+ dst->y += mtx->_[10];
+ dst->z = (fx32)(((fx64)x * mtx->_[2] + (fx64)y * mtx->_[5] + (fx64)z * mtx->_[8]) >> FX32_INT_SHIFT);
+ dst->z += mtx->_[11];
+}
+
+ARM_FUNC asm void MTX_Identity43_(struct Mtx43 *mtx){
+ mov r2, #0x1000
+ mov r3, #0x0
+ stmia r0!, {r2-r3}
+ mov r1, #0x0
+ stmia r0!, {r1,r3}
+ stmia r0!, {r2-r3}
+ stmia r0!, {r1,r3}
+ stmia r0!, {r2-r3}
+ stmia r0!, {r1,r3}
+ bx lr
+}
+
+ARM_FUNC asm void MTX_Copy43To44_(struct Mtx43 *src, struct Mtx44 *dst){
+ stmdb sp!, {r4}
+ mov r12, #0x0
+ ldmia r0!, {r2-r4}
+ stmia r1!, {r2-r4,r12}
+ ldmia r0!, {r2-r4}
+ stmia r1!, {r2-r4,r12}
+ ldmia r0!, {r2-r4}
+ stmia r1!, {r2-r4,r12}
+ mov r12, #0x1000
+ ldmia r0!, {r2-r4}
+ stmia r1!, {r2-r4,r12}
+ ldmia sp!, {r4}
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_Scale43_(struct Mtx43 *dst, fx32 x, fx32 y, fx32 z){
+ stmia r0!, {r1}
+ mov r1, #0x0
+ str r3, [r0, #0x1c]
+ mov r3, #0x0
+ stmia r0!, {r1,r3}
+ stmia r0!, {r1-r3}
+ mov r2, #0x0
+ stmia r0!, {r1,r3}
+ add r0, #0x4
+ stmia r0!, {r1-r3}
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_RotX43_(struct Mtx43 *mtx, fx32 sinphi, fx32 cosphi){
+ str r1, [r0, #0x14]
+ neg r1, r1
+ str r1, [r0, #0x1c]
+ mov r1, #0x1
+ lsl r1, r1, #0xc
+ stmia r0!, {r1}
+ mov r3, #0x0
+ mov r1, #0x0
+ stmia r0!, {r1,r3}
+ stmia r0!, {r1-r2}
+ str r1, [r0, #0x4]
+ add r0, #0xc
+ stmia r0!, {r2-r3}
+ stmia r0!, {r1,r3}
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_RotY43_(struct Mtx43 *mtx, fx32 sinphi, fx32 cosphi){
+ str r1, [r0, #0x18]
+ mov r3, #0x0
+ stmia r0!, {r2-r3}
+ neg r1, r1
+ stmia r0!, {r1,r3}
+ mov r1, #0x1
+ lsl r1, r1, #0xc
+ stmia r0!, {r1,r3}
+ add r0, #0x4
+ mov r1, #0x0
+ stmia r0!, {r1-r3}
+ stmia r0!, {r1,r3}
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/FX_mtx44.c b/arm9/lib/NitroSDK/src/FX_mtx44.c
new file mode 100644
index 00000000..c72f6158
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX_mtx44.c
@@ -0,0 +1,166 @@
+#include "global.h"
+#include "main.h"
+#include "fx.h"
+
+void MI_Copy48B(void *src, void *dst);
+
+
+ARM_FUNC void MTX_TransApply44(struct Mtx44 *mtx, struct Mtx44 *dst, fx32 x, fx32 y, fx32 z){
+ if(mtx != dst)
+ MI_Copy48B(mtx, dst);
+ dst->_[12] = mtx->_[12] + (fx32)(((fx64)x * mtx->_[0] + (fx64)y * mtx->_[4] + (fx64)z * mtx->_[8] ) >> FX32_INT_SHIFT);
+ dst->_[13] = mtx->_[13] + (fx32)(((fx64)x * mtx->_[1] + (fx64)y * mtx->_[5] + (fx64)z * mtx->_[9] ) >> FX32_INT_SHIFT);
+ dst->_[14] = mtx->_[14] + (fx32)(((fx64)x * mtx->_[2] + (fx64)y * mtx->_[6] + (fx64)z * mtx->_[10]) >> FX32_INT_SHIFT);
+ dst->_[15] = mtx->_[15] + (fx32)(((fx64)x * mtx->_[3] + (fx64)y * mtx->_[7] + (fx64)z * mtx->_[11]) >> FX32_INT_SHIFT);
+}
+
+ARM_FUNC void MTX_Concat44(struct Mtx44 *a, struct Mtx44 *b, struct Mtx44 *c){
+ struct Mtx44 temp;
+ struct Mtx44 *dst;
+ fx32 a0, a1, a2, a3;
+ fx32 b0, b1, b2, b3;
+
+ if (c == b)
+ dst = &temp;
+ else
+ dst = c;
+
+ a0 = a->_[0];
+ a1 = a->_[1];
+ a2 = a->_[2];
+ a3 = a->_[3];
+ dst->_[0] = (fx32)(((fx64)a0 * b->_[0] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[8] + (fx64)a3 * b->_[12]) >> FX32_INT_SHIFT);
+ dst->_[1] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[5] + (fx64)a2 * b->_[9] + (fx64)a3 * b->_[13]) >> FX32_INT_SHIFT);
+ dst->_[3] = (fx32)(((fx64)a0 * b->_[3] + (fx64)a1 * b->_[7] + (fx64)a2 * b->_[11] + (fx64)a3 * b->_[15]) >> FX32_INT_SHIFT);
+ b0 = b->_[2];
+ b1 = b->_[6];
+ b2 = b->_[10];
+ b3 = b->_[14];
+ dst->_[2] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2 + (fx64)a3 * b3) >> FX32_INT_SHIFT);
+ a0 = a->_[4];
+ a1 = a->_[5];
+ a2 = a->_[6];
+ a3 = a->_[7];
+ dst->_[6] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2 + (fx64)a3 * b3) >> FX32_INT_SHIFT);
+ dst->_[5] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[5] + (fx64)a2 * b->_[9] + (fx64)a3 * b->_[13]) >> FX32_INT_SHIFT);
+ dst->_[7] = (fx32)(((fx64)a0 * b->_[3] + (fx64)a1 * b->_[7] + (fx64)a2 * b->_[11] + (fx64)a3 * b->_[15]) >> FX32_INT_SHIFT);
+ b0 = b->_[0];
+ b1 = b->_[4];
+ b2 = b->_[8];
+ b3 = b->_[12];
+ dst->_[4] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2 + (fx64)a3 * b3) >> FX32_INT_SHIFT);
+ a0 = a->_[8];
+ a1 = a->_[9];
+ a2 = a->_[10];
+ a3 = a->_[11];
+ dst->_[8] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2 + (fx64)a3 * b3) >> FX32_INT_SHIFT);
+ dst->_[9] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[5] + (fx64)a2 * b->_[9] + (fx64)a3 * b->_[13]) >> FX32_INT_SHIFT);
+ dst->_[11] = (fx32)(((fx64)a0 * b->_[3] + (fx64)a1 * b->_[7] + (fx64)a2 * b->_[11] + (fx64)a3 * b->_[15]) >> FX32_INT_SHIFT);
+ b0 = b->_[2];
+ b1 = b->_[6];
+ b2 = b->_[10];
+ b3 = b->_[14];
+ dst->_[10] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2 + (fx64)a3 * b3) >> FX32_INT_SHIFT);
+ a0 = a->_[12];
+ a1 = a->_[13];
+ a2 = a->_[14];
+ a3 = a->_[15];
+ dst->_[14] = (fx32)(((fx64)a0 * b0 + (fx64)a1 * b1 + (fx64)a2 * b2 + (fx64)a3 * b3) >> FX32_INT_SHIFT);
+ dst->_[13] = (fx32)(((fx64)a0 * b->_[1] + (fx64)a1 * b->_[5] + (fx64)a2 * b->_[9] + (fx64)a3 * b->_[13]) >> FX32_INT_SHIFT);
+ dst->_[12] = (fx32)(((fx64)a0 * b->_[0] + (fx64)a1 * b->_[4] + (fx64)a2 * b->_[8] + (fx64)a3 * b->_[12]) >> FX32_INT_SHIFT);
+ dst->_[15] = (fx32)(((fx64)a0 * b->_[3] + (fx64)a1 * b->_[7] + (fx64)a2 * b->_[11] + (fx64)a3 * b->_[15]) >> FX32_INT_SHIFT);
+ if (dst == &temp)
+ *c = temp;
+}
+
+ARM_FUNC asm void MTX_Identity44_(struct Mtx44 *dst){
+ mov r2, #0x1000
+ mov r3, #0x0
+ stmia r0!, {r2-r3}
+ mov r1, #0x0
+ stmia r0!, {r1,r3}
+ stmia r0!, {r1-r3}
+ stmia r0!, {r1,r3}
+ stmia r0!, {r1-r3}
+ stmia r0!, {r1,r3}
+ stmia r0!, {r1-r2}
+ bx lr
+}
+
+ARM_FUNC asm void MTX_Copy44To43_(struct Mtx44 *src, struct Mtx43 *dst){
+ ldmia r0!, {r2-r3,r12}
+ add r0, r0, #0x4
+ stmia r1!, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ add r0, r0, #0x4
+ stmia r1!, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ add r0, r0, #0x4
+ stmia r1!, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ add r0, r0, #0x4
+ stmia r1!, {r2-r3,r12}
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_RotX44_(struct Mtx44 *mtx, fx32 sinphi, fx32 cosphi){
+ str r2, [r0, #0x14]
+ str r2, [r0, #0x28]
+ str r1, [r0, #0x18]
+ neg r1, r1
+ str r1, [r0, #0x24]
+ mov r1, #0x1
+ mov r2, #0x0
+ lsl r1, r1, #0xc
+ mov r3, #0x0
+ stmia r0!, {r1-r3}
+ stmia r0!, {r2-r3}
+ add r0, #0x8
+ stmia r0!, {r2-r3}
+ add r0, #0x8
+ stmia r0!, {r2-r3}
+ stmia r0!, {r2-r3}
+ str r1, [r0, #0x0]
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_RotY44_(struct Mtx44 *mtx, fx32 sinphi, fx32 cosphi){
+ str r2, [r0, #0x0]
+ str r2, [r0, #0x28]
+ str r1, [r0, #0x20]
+ neg r1, r1
+ str r1, [r0, #0x8]
+ mov r3, #0x1
+ mov r1, #0x0
+ lsl r3, r3, #0xc
+ mov r2, #0x0
+ str r2, [r0, #0x4]
+ add r0, #0xc
+ stmia r0!, {r1-r3}
+ stmia r0!, {r1-r2}
+ str r2, [r0, #0x4]
+ add r0, #0xc
+ stmia r0!, {r1-r2}
+ stmia r0!, {r1-r3}
+ bx lr
+}
+
+THUMB_FUNC asm void MTX_RotZ44_(struct Mtx44 *mtx, fx32 sinphi, fx32 cosphi){
+ str r2, [r0, #0x0]
+ str r2, [r0, #0x14]
+ str r1, [r0, #0x4]
+ neg r1, r1
+ str r1, [r0, #0x10]
+ mov r3, #0x1
+ mov r1, #0x0
+ lsl r3, r3, #0xc
+ mov r2, #0x0
+ add r0, #0x8
+ stmia r0!, {r1-r2}
+ add r0, #0x8
+ stmia r0!, {r1-r2}
+ stmia r0!, {r1-r3}
+ stmia r0!, {r1-r2}
+ stmia r0!, {r1-r3}
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/FX_sincos.c b/arm9/lib/NitroSDK/src/FX_sincos.c
new file mode 100644
index 00000000..89c8fc78
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX_sincos.c
@@ -0,0 +1,4105 @@
+#include "global.h"
+#include "fx.h"
+
+/*
+ * [2 * idx + 0] <- sin(idx * 2pi / 4096)
+ * [2 * idx + 1] <- cos(idx * 2pi / 4096)
+ */
+const fx16 FX_SinCosTable_[4096 * 2] = {
+ FX16_CONST(0.0), FX16_CONST(1.0),
+ FX16_CONST(0.0015339801862847655), FX16_CONST(0.9999988234517019),
+ FX16_CONST(0.003067956762965976), FX16_CONST(0.9999952938095762),
+ FX16_CONST(0.0046019261204485705), FX16_CONST(0.9999894110819284),
+ FX16_CONST(0.006135884649154475), FX16_CONST(0.9999811752826011),
+ FX16_CONST(0.007669828739531097), FX16_CONST(0.9999705864309741),
+ FX16_CONST(0.00920375478205982), FX16_CONST(0.9999576445519639),
+ FX16_CONST(0.01073765916726449), FX16_CONST(0.9999423496760239),
+ FX16_CONST(0.012271538285719925), FX16_CONST(0.9999247018391445),
+ FX16_CONST(0.01380538852806039), FX16_CONST(0.9999047010828529),
+ FX16_CONST(0.0153392062849881), FX16_CONST(0.9998823474542126),
+ FX16_CONST(0.01687298794728171), FX16_CONST(0.9998576410058239),
+ FX16_CONST(0.01840672990580482), FX16_CONST(0.9998305817958234),
+ FX16_CONST(0.01994042855151444), FX16_CONST(0.9998011698878843),
+ FX16_CONST(0.021474080275469508), FX16_CONST(0.9997694053512153),
+ FX16_CONST(0.02300768146883937), FX16_CONST(0.9997352882605617),
+ FX16_CONST(0.024541228522912288), FX16_CONST(0.9996988186962042),
+ FX16_CONST(0.0260747178291039), FX16_CONST(0.9996599967439592),
+ FX16_CONST(0.02760814577896574), FX16_CONST(0.9996188224951786),
+ FX16_CONST(0.029141508764193722), FX16_CONST(0.9995752960467492),
+ FX16_CONST(0.030674803176636626), FX16_CONST(0.9995294175010931),
+ FX16_CONST(0.032208025408304586), FX16_CONST(0.999481186966167),
+ FX16_CONST(0.03374117185137758), FX16_CONST(0.9994306045554617),
+ FX16_CONST(0.03527423889821395), FX16_CONST(0.9993776703880028),
+ FX16_CONST(0.03680722294135883), FX16_CONST(0.9993223845883495),
+ FX16_CONST(0.038340120373552694), FX16_CONST(0.9992647472865944),
+ FX16_CONST(0.03987292758773981), FX16_CONST(0.9992047586183639),
+ FX16_CONST(0.04140564097707674), FX16_CONST(0.9991424187248169),
+ FX16_CONST(0.04293825693494082), FX16_CONST(0.9990777277526454),
+ FX16_CONST(0.04447077185493867), FX16_CONST(0.9990106858540734),
+ FX16_CONST(0.04600318213091462), FX16_CONST(0.9989412931868569),
+ FX16_CONST(0.0475354841569593), FX16_CONST(0.9988695499142836),
+ FX16_CONST(0.049067674327418015), FX16_CONST(0.9987954562051724),
+ FX16_CONST(0.05059974903689928), FX16_CONST(0.9987190122338729),
+ FX16_CONST(0.052131704680283324), FX16_CONST(0.9986402181802653),
+ FX16_CONST(0.05366353765273052), FX16_CONST(0.9985590742297593),
+ FX16_CONST(0.055195244349689934), FX16_CONST(0.9984755805732948),
+ FX16_CONST(0.05672682116690775), FX16_CONST(0.9983897374073402),
+ FX16_CONST(0.05825826450043575), FX16_CONST(0.9983015449338929),
+ FX16_CONST(0.05978957074663987), FX16_CONST(0.9982110033604782),
+ FX16_CONST(0.06132073630220858), FX16_CONST(0.9981181129001492),
+ FX16_CONST(0.0628517575641614), FX16_CONST(0.9980228737714862),
+ FX16_CONST(0.06438263092985747), FX16_CONST(0.997925286198596),
+ FX16_CONST(0.0659133527970038), FX16_CONST(0.9978253504111116),
+ FX16_CONST(0.06744391956366405), FX16_CONST(0.9977230666441916),
+ FX16_CONST(0.06897432762826675), FX16_CONST(0.9976184351385196),
+ FX16_CONST(0.07050457338961386), FX16_CONST(0.9975114561403035),
+ FX16_CONST(0.07203465324688933), FX16_CONST(0.9974021299012753),
+ FX16_CONST(0.07356456359966743), FX16_CONST(0.9972904566786902),
+ FX16_CONST(0.0750943008479213), FX16_CONST(0.9971764367353262),
+ FX16_CONST(0.07662386139203149), FX16_CONST(0.997060070339483),
+ FX16_CONST(0.07815324163279423), FX16_CONST(0.9969413577649822),
+ FX16_CONST(0.07968243797143013), FX16_CONST(0.9968202992911657),
+ FX16_CONST(0.08121144680959244), FX16_CONST(0.9966968952028961),
+ FX16_CONST(0.08274026454937569), FX16_CONST(0.9965711457905548),
+ FX16_CONST(0.08426888759332407), FX16_CONST(0.9964430513500426),
+ FX16_CONST(0.0857973123444399), FX16_CONST(0.996312612182778),
+ FX16_CONST(0.08732553520619206), FX16_CONST(0.996179828595697),
+ FX16_CONST(0.0888535525825246), FX16_CONST(0.996044700901252),
+ FX16_CONST(0.09038136087786498), FX16_CONST(0.9959072294174117),
+ FX16_CONST(0.09190895649713272), FX16_CONST(0.9957674144676598),
+ FX16_CONST(0.09343633584574779), FX16_CONST(0.9956252563809943),
+ FX16_CONST(0.09496349532963899), FX16_CONST(0.9954807554919269),
+ FX16_CONST(0.09649043135525259), FX16_CONST(0.9953339121404823),
+ FX16_CONST(0.0980171403295606), FX16_CONST(0.9951847266721969),
+ FX16_CONST(0.09954361866006932), FX16_CONST(0.9950331994381186),
+ FX16_CONST(0.10106986275482782), FX16_CONST(0.9948793307948056),
+ FX16_CONST(0.10259586902243628), FX16_CONST(0.9947231211043257),
+ FX16_CONST(0.10412163387205459), FX16_CONST(0.9945645707342554),
+ FX16_CONST(0.10564715371341062), FX16_CONST(0.9944036800576791),
+ FX16_CONST(0.10717242495680884), FX16_CONST(0.9942404494531879),
+ FX16_CONST(0.10869744401313872), FX16_CONST(0.9940748793048794),
+ FX16_CONST(0.11022220729388306), FX16_CONST(0.9939069700023561),
+ FX16_CONST(0.11174671121112659), FX16_CONST(0.9937367219407246),
+ FX16_CONST(0.11327095217756435), FX16_CONST(0.9935641355205953),
+ FX16_CONST(0.11479492660651008), FX16_CONST(0.9933892111480807),
+ FX16_CONST(0.11631863091190475), FX16_CONST(0.9932119492347945),
+ FX16_CONST(0.11784206150832498), FX16_CONST(0.9930323501978514),
+ FX16_CONST(0.11936521481099135), FX16_CONST(0.9928504144598651),
+ FX16_CONST(0.12088808723577708), FX16_CONST(0.992666142448948),
+ FX16_CONST(0.1224106751992162), FX16_CONST(0.99247953459871),
+ FX16_CONST(0.12393297511851216), FX16_CONST(0.9922905913482574),
+ FX16_CONST(0.12545498341154623), FX16_CONST(0.9920993131421918),
+ FX16_CONST(0.12697669649688587), FX16_CONST(0.9919057004306093),
+ FX16_CONST(0.12849811079379317), FX16_CONST(0.9917097536690995),
+ FX16_CONST(0.13001922272223335), FX16_CONST(0.9915114733187439),
+ FX16_CONST(0.13154002870288312), FX16_CONST(0.9913108598461154),
+ FX16_CONST(0.13306052515713906), FX16_CONST(0.9911079137232769),
+ FX16_CONST(0.13458070850712617), FX16_CONST(0.99090263542778),
+ FX16_CONST(0.1361005751757062), FX16_CONST(0.9906950254426646),
+ FX16_CONST(0.13762012158648604), FX16_CONST(0.9904850842564571),
+ FX16_CONST(0.1391393441638262), FX16_CONST(0.9902728123631691),
+ FX16_CONST(0.1406582393328492), FX16_CONST(0.9900582102622971),
+ FX16_CONST(0.14217680351944803), FX16_CONST(0.9898412784588205),
+ FX16_CONST(0.14369503315029447), FX16_CONST(0.9896220174632009),
+ FX16_CONST(0.14521292465284746), FX16_CONST(0.9894004277913804),
+ FX16_CONST(0.14673047445536175), FX16_CONST(0.989176509964781),
+ FX16_CONST(0.14824767898689603), FX16_CONST(0.988950264510303),
+ FX16_CONST(0.1497645346773215), FX16_CONST(0.9887216919603238),
+ FX16_CONST(0.15128103795733022), FX16_CONST(0.9884907928526966),
+ FX16_CONST(0.15279718525844344), FX16_CONST(0.9882575677307495),
+ FX16_CONST(0.1543129730130201), FX16_CONST(0.9880220171432835),
+ FX16_CONST(0.15582839765426523), FX16_CONST(0.9877841416445722),
+ FX16_CONST(0.15734345561623825), FX16_CONST(0.9875439417943592),
+ FX16_CONST(0.15885814333386145), FX16_CONST(0.9873014181578584),
+ FX16_CONST(0.16037245724292828), FX16_CONST(0.987056571305751),
+ FX16_CONST(0.16188639378011183), FX16_CONST(0.9868094018141855),
+ FX16_CONST(0.16339994938297323), FX16_CONST(0.9865599102647754),
+ FX16_CONST(0.1649131204899699), FX16_CONST(0.9863080972445987),
+ FX16_CONST(0.1664259035404641), FX16_CONST(0.9860539633461954),
+ FX16_CONST(0.16793829497473117), FX16_CONST(0.9857975091675675),
+ FX16_CONST(0.16945029123396796), FX16_CONST(0.9855387353121761),
+ FX16_CONST(0.17096188876030122), FX16_CONST(0.9852776423889412),
+ FX16_CONST(0.17247308399679595), FX16_CONST(0.9850142310122398),
+ FX16_CONST(0.17398387338746382), FX16_CONST(0.9847485018019042),
+ FX16_CONST(0.17549425337727143), FX16_CONST(0.9844804553832209),
+ FX16_CONST(0.17700422041214875), FX16_CONST(0.984210092386929),
+ FX16_CONST(0.1785137709389975), FX16_CONST(0.9839374134492189),
+ FX16_CONST(0.18002290140569951), FX16_CONST(0.9836624192117303),
+ FX16_CONST(0.18153160826112497), FX16_CONST(0.9833851103215512),
+ FX16_CONST(0.18303988795514095), FX16_CONST(0.9831054874312163),
+ FX16_CONST(0.18454773693861962), FX16_CONST(0.9828235511987052),
+ FX16_CONST(0.18605515166344663), FX16_CONST(0.9825393022874412),
+ FX16_CONST(0.1875621285825296), FX16_CONST(0.9822527413662894),
+ FX16_CONST(0.1890686641498062), FX16_CONST(0.9819638691095552),
+ FX16_CONST(0.19057475482025274), FX16_CONST(0.9816726861969831),
+ FX16_CONST(0.19208039704989244), FX16_CONST(0.9813791933137546),
+ FX16_CONST(0.1935855872958036), FX16_CONST(0.9810833911504867),
+ FX16_CONST(0.19509032201612825), FX16_CONST(0.9807852804032304),
+ FX16_CONST(0.19659459767008022), FX16_CONST(0.9804848617734694),
+ FX16_CONST(0.19809841071795356), FX16_CONST(0.9801821359681174),
+ FX16_CONST(0.19960175762113097), FX16_CONST(0.9798771036995176),
+ FX16_CONST(0.2011046348420919), FX16_CONST(0.9795697656854405),
+ FX16_CONST(0.20260703884442113), FX16_CONST(0.979260122649082),
+ FX16_CONST(0.20410896609281687), FX16_CONST(0.9789481753190622),
+ FX16_CONST(0.20561041305309924), FX16_CONST(0.9786339244294232),
+ FX16_CONST(0.20711137619221856), FX16_CONST(0.9783173707196277),
+ FX16_CONST(0.20861185197826349), FX16_CONST(0.9779985149345571),
+ FX16_CONST(0.2101118368804696), FX16_CONST(0.9776773578245099),
+ FX16_CONST(0.21161132736922755), FX16_CONST(0.9773539001452),
+ FX16_CONST(0.21311031991609136), FX16_CONST(0.9770281426577544),
+ FX16_CONST(0.21460881099378676), FX16_CONST(0.9767000861287118),
+ FX16_CONST(0.21610679707621952), FX16_CONST(0.9763697313300211),
+ FX16_CONST(0.21760427463848364), FX16_CONST(0.976037079039039),
+ FX16_CONST(0.2191012401568698), FX16_CONST(0.9757021300385286),
+ FX16_CONST(0.2205976901088735), FX16_CONST(0.975364885116657),
+ FX16_CONST(0.2220936209732035), FX16_CONST(0.9750253450669941),
+ FX16_CONST(0.22358902922979), FX16_CONST(0.9746835106885107),
+ FX16_CONST(0.22508391135979283), FX16_CONST(0.9743393827855759),
+ FX16_CONST(0.22657826384561), FX16_CONST(0.9739929621679558),
+ FX16_CONST(0.22807208317088573), FX16_CONST(0.973644249650812),
+ FX16_CONST(0.22956536582051887), FX16_CONST(0.9732932460546982),
+ FX16_CONST(0.2310581082806711), FX16_CONST(0.9729399522055602),
+ FX16_CONST(0.23255030703877524), FX16_CONST(0.9725843689347322),
+ FX16_CONST(0.23404195858354343), FX16_CONST(0.9722264970789363),
+ FX16_CONST(0.2355330594049755), FX16_CONST(0.9718663374802794),
+ FX16_CONST(0.2370236059943672), FX16_CONST(0.9715038909862518),
+ FX16_CONST(0.23851359484431842), FX16_CONST(0.9711391584497251),
+ FX16_CONST(0.2400030224487415), FX16_CONST(0.9707721407289504),
+ FX16_CONST(0.24149188530286933), FX16_CONST(0.9704028386875555),
+ FX16_CONST(0.24298017990326387), FX16_CONST(0.970031253194544),
+ FX16_CONST(0.24446790274782415), FX16_CONST(0.9696573851242924),
+ FX16_CONST(0.2459550503357946), FX16_CONST(0.9692812353565485),
+ FX16_CONST(0.24744161916777327), FX16_CONST(0.9689028047764289),
+ FX16_CONST(0.24892760574572015), FX16_CONST(0.9685220942744174),
+ FX16_CONST(0.2504130065729652), FX16_CONST(0.9681391047463624),
+ FX16_CONST(0.25189781815421697), FX16_CONST(0.9677538370934755),
+ FX16_CONST(0.25338203699557016), FX16_CONST(0.9673662922223285),
+ FX16_CONST(0.25486565960451457), FX16_CONST(0.9669764710448521),
+ FX16_CONST(0.2563486824899429), FX16_CONST(0.9665843744783331),
+ FX16_CONST(0.257831102162159), FX16_CONST(0.9661900034454125),
+ FX16_CONST(0.25931291513288623), FX16_CONST(0.9657933588740837),
+ FX16_CONST(0.2607941179152755), FX16_CONST(0.9653944416976894),
+ FX16_CONST(0.2622747070239136), FX16_CONST(0.9649932528549203),
+ FX16_CONST(0.26375467897483135), FX16_CONST(0.9645897932898128),
+ FX16_CONST(0.2652340302855118), FX16_CONST(0.9641840639517458),
+ FX16_CONST(0.26671275747489837), FX16_CONST(0.9637760657954398),
+ FX16_CONST(0.2681908570634032), FX16_CONST(0.963365799780954),
+ FX16_CONST(0.2696683255729151), FX16_CONST(0.9629532668736839),
+ FX16_CONST(0.271145159526808), FX16_CONST(0.9625384680443592),
+ FX16_CONST(0.272621355449949), FX16_CONST(0.9621214042690416),
+ FX16_CONST(0.2740969098687064), FX16_CONST(0.9617020765291225),
+ FX16_CONST(0.27557181931095814), FX16_CONST(0.9612804858113206),
+ FX16_CONST(0.2770460803060999), FX16_CONST(0.9608566331076797),
+ FX16_CONST(0.27851968938505306), FX16_CONST(0.9604305194155658),
+ FX16_CONST(0.2799926430802732), FX16_CONST(0.960002145737666),
+ FX16_CONST(0.28146493792575794), FX16_CONST(0.9595715130819845),
+ FX16_CONST(0.2829365704570554), FX16_CONST(0.9591386224618419),
+ FX16_CONST(0.2844075372112719), FX16_CONST(0.9587034748958716),
+ FX16_CONST(0.2858778347270806), FX16_CONST(0.9582660714080177),
+ FX16_CONST(0.2873474595447295), FX16_CONST(0.9578264130275329),
+ FX16_CONST(0.2888164082060495), FX16_CONST(0.9573845007889759),
+ FX16_CONST(0.29028467725446233), FX16_CONST(0.9569403357322088),
+ FX16_CONST(0.29175226323498926), FX16_CONST(0.9564939189023951),
+ FX16_CONST(0.29321916269425863), FX16_CONST(0.9560452513499964),
+ FX16_CONST(0.2946853721805143), FX16_CONST(0.9555943341307711),
+ FX16_CONST(0.2961508882436238), FX16_CONST(0.9551411683057708),
+ FX16_CONST(0.2976157074350862), FX16_CONST(0.9546857549413383),
+ FX16_CONST(0.2990798263080405), FX16_CONST(0.9542280951091057),
+ FX16_CONST(0.30054324141727345), FX16_CONST(0.9537681898859903),
+ FX16_CONST(0.3020059493192281), FX16_CONST(0.9533060403541939),
+ FX16_CONST(0.3034679465720113), FX16_CONST(0.9528416476011987),
+ FX16_CONST(0.3049292297354024), FX16_CONST(0.9523750127197659),
+ FX16_CONST(0.3063897953708609), FX16_CONST(0.9519061368079323),
+ FX16_CONST(0.30784964004153487), FX16_CONST(0.9514350209690083),
+ FX16_CONST(0.3093087603122687), FX16_CONST(0.9509616663115751),
+ FX16_CONST(0.3107671527496115), FX16_CONST(0.9504860739494817),
+ FX16_CONST(0.3122248139218249), FX16_CONST(0.950008245001843),
+ FX16_CONST(0.3136817403988915), FX16_CONST(0.9495281805930367),
+ FX16_CONST(0.31513792875252244), FX16_CONST(0.9490458818527006),
+ FX16_CONST(0.31659337555616585), FX16_CONST(0.9485613499157303),
+ FX16_CONST(0.31804807738501495), FX16_CONST(0.9480745859222762),
+ FX16_CONST(0.3195020308160157), FX16_CONST(0.9475855910177411),
+ FX16_CONST(0.3209552324278752), FX16_CONST(0.9470943663527772),
+ FX16_CONST(0.32240767880106985), FX16_CONST(0.9466009130832835),
+ FX16_CONST(0.32385936651785285), FX16_CONST(0.9461052323704034),
+ FX16_CONST(0.3253102921622629), FX16_CONST(0.9456073253805213),
+ FX16_CONST(0.32676045232013173), FX16_CONST(0.9451071932852606),
+ FX16_CONST(0.3282098435790925), FX16_CONST(0.9446048372614803),
+ FX16_CONST(0.3296584625285875), FX16_CONST(0.9441002584912727),
+ FX16_CONST(0.33110630575987643), FX16_CONST(0.9435934581619604),
+ FX16_CONST(0.3325533698660442), FX16_CONST(0.9430844374660935),
+ FX16_CONST(0.3339996514420094), FX16_CONST(0.9425731976014469),
+ FX16_CONST(0.3354451470845316), FX16_CONST(0.9420597397710173),
+ FX16_CONST(0.33688985339222005), FX16_CONST(0.9415440651830208),
+ FX16_CONST(0.3383337669655411), FX16_CONST(0.9410261750508893),
+ FX16_CONST(0.33977688440682685), FX16_CONST(0.9405060705932683),
+ FX16_CONST(0.34121920232028236), FX16_CONST(0.939983753034014),
+ FX16_CONST(0.3426607173119944), FX16_CONST(0.9394592236021899),
+ FX16_CONST(0.3441014259899388), FX16_CONST(0.9389324835320646),
+ FX16_CONST(0.3455413249639891), FX16_CONST(0.9384035340631081),
+ FX16_CONST(0.3469804108459237), FX16_CONST(0.9378723764399899),
+ FX16_CONST(0.34841868024943456), FX16_CONST(0.937339011912575),
+ FX16_CONST(0.3498561297901349), FX16_CONST(0.9368034417359216),
+ FX16_CONST(0.3512927560855671), FX16_CONST(0.9362656671702783),
+ FX16_CONST(0.3527285557552107), FX16_CONST(0.9357256894810804),
+ FX16_CONST(0.35416352542049034), FX16_CONST(0.9351835099389476),
+ FX16_CONST(0.35559766170478385), FX16_CONST(0.9346391298196808),
+ FX16_CONST(0.35703096123343), FX16_CONST(0.9340925504042589),
+ FX16_CONST(0.35846342063373654), FX16_CONST(0.9335437729788362),
+ FX16_CONST(0.3598950365349881), FX16_CONST(0.932992798834739),
+ FX16_CONST(0.3613258055684543), FX16_CONST(0.9324396292684624),
+ FX16_CONST(0.3627557243673972), FX16_CONST(0.9318842655816681),
+ FX16_CONST(0.3641847895670799), FX16_CONST(0.9313267090811804),
+ FX16_CONST(0.36561299780477385), FX16_CONST(0.9307669610789837),
+ FX16_CONST(0.3670403457197672), FX16_CONST(0.9302050228922191),
+ FX16_CONST(0.3684668299533723), FX16_CONST(0.9296408958431812),
+ FX16_CONST(0.3698924471489341), FX16_CONST(0.9290745812593159),
+ FX16_CONST(0.37131719395183754), FX16_CONST(0.9285060804732156),
+ FX16_CONST(0.37274106700951576), FX16_CONST(0.9279353948226179),
+ FX16_CONST(0.37416406297145793), FX16_CONST(0.9273625256504011),
+ FX16_CONST(0.3755861784892172), FX16_CONST(0.9267874743045817),
+ FX16_CONST(0.37700741021641826), FX16_CONST(0.9262102421383114),
+ FX16_CONST(0.37842775480876556), FX16_CONST(0.9256308305098727),
+ FX16_CONST(0.37984720892405116), FX16_CONST(0.9250492407826776),
+ FX16_CONST(0.3812657692221624), FX16_CONST(0.9244654743252626),
+ FX16_CONST(0.3826834323650898), FX16_CONST(0.9238795325112867),
+ FX16_CONST(0.38410019501693504), FX16_CONST(0.9232914167195276),
+ FX16_CONST(0.38551605384391885), FX16_CONST(0.9227011283338786),
+ FX16_CONST(0.3869310055143886), FX16_CONST(0.9221086687433452),
+ FX16_CONST(0.38834504669882625), FX16_CONST(0.9215140393420419),
+ FX16_CONST(0.3897581740698564), FX16_CONST(0.9209172415291894),
+ FX16_CONST(0.39117038430225387), FX16_CONST(0.9203182767091106),
+ FX16_CONST(0.39258167407295147), FX16_CONST(0.9197171462912274),
+ FX16_CONST(0.3939920400610481), FX16_CONST(0.9191138516900578),
+ FX16_CONST(0.39540147894781635), FX16_CONST(0.9185083943252123),
+ FX16_CONST(0.3968099874167103), FX16_CONST(0.9179007756213905),
+ FX16_CONST(0.39821756215337356), FX16_CONST(0.9172909970083779),
+ FX16_CONST(0.3996241998456468), FX16_CONST(0.9166790599210427),
+ FX16_CONST(0.4010298971835756), FX16_CONST(0.9160649657993317),
+ FX16_CONST(0.40243465085941843), FX16_CONST(0.9154487160882678),
+ FX16_CONST(0.4038384575676541), FX16_CONST(0.9148303122379462),
+ FX16_CONST(0.40524131400498986), FX16_CONST(0.9142097557035307),
+ FX16_CONST(0.40664321687036903), FX16_CONST(0.9135870479452508),
+ FX16_CONST(0.4080441628649787), FX16_CONST(0.9129621904283982),
+ FX16_CONST(0.4094441486922576), FX16_CONST(0.9123351846233227),
+ FX16_CONST(0.4108431710579039), FX16_CONST(0.9117060320054299),
+ FX16_CONST(0.4122412266698829), FX16_CONST(0.9110747340551764),
+ FX16_CONST(0.4136383122384345), FX16_CONST(0.9104412922580672),
+ FX16_CONST(0.41503442447608163), FX16_CONST(0.9098057081046522),
+ FX16_CONST(0.41642956009763715), FX16_CONST(0.9091679830905224),
+ FX16_CONST(0.41782371582021227), FX16_CONST(0.9085281187163061),
+ FX16_CONST(0.4192168883632239), FX16_CONST(0.9078861164876663),
+ FX16_CONST(0.4206090744484025), FX16_CONST(0.9072419779152958),
+ FX16_CONST(0.4220002707997997), FX16_CONST(0.9065957045149153),
+ FX16_CONST(0.42339047414379605), FX16_CONST(0.9059472978072685),
+ FX16_CONST(0.4247796812091088), FX16_CONST(0.9052967593181188),
+ FX16_CONST(0.4261678887267996), FX16_CONST(0.9046440905782462),
+ FX16_CONST(0.4275550934302821), FX16_CONST(0.9039892931234433),
+ FX16_CONST(0.4289412920553295), FX16_CONST(0.9033323684945118),
+ FX16_CONST(0.4303264813400826), FX16_CONST(0.9026733182372588),
+ FX16_CONST(0.43171065802505726), FX16_CONST(0.9020121439024932),
+ FX16_CONST(0.43309381885315196), FX16_CONST(0.901348847046022),
+ FX16_CONST(0.43447596056965565), FX16_CONST(0.9006834292286469),
+ FX16_CONST(0.4358570799222555), FX16_CONST(0.9000158920161602),
+ FX16_CONST(0.4372371736610441), FX16_CONST(0.8993462369793416),
+ FX16_CONST(0.43861623853852766), FX16_CONST(0.8986744656939538),
+ FX16_CONST(0.43999427130963326), FX16_CONST(0.8980005797407399),
+ FX16_CONST(0.44137126873171667), FX16_CONST(0.8973245807054183),
+ FX16_CONST(0.44274722756457), FX16_CONST(0.8966464701786802),
+ FX16_CONST(0.4441221445704292), FX16_CONST(0.8959662497561852),
+ FX16_CONST(0.44549601651398174), FX16_CONST(0.8952839210385576),
+ FX16_CONST(0.44686884016237416), FX16_CONST(0.8945994856313827),
+ FX16_CONST(0.4482406122852199), FX16_CONST(0.8939129451452033),
+ FX16_CONST(0.44961132965460654), FX16_CONST(0.8932243011955153),
+ FX16_CONST(0.45098098904510386), FX16_CONST(0.8925335554027646),
+ FX16_CONST(0.4523495872337709), FX16_CONST(0.8918407093923427),
+ FX16_CONST(0.45371712100016387), FX16_CONST(0.8911457647945832),
+ FX16_CONST(0.45508358712634384), FX16_CONST(0.8904487232447579),
+ FX16_CONST(0.4564489823968839), FX16_CONST(0.8897495863830728),
+ FX16_CONST(0.4578133035988772), FX16_CONST(0.8890483558546646),
+ FX16_CONST(0.4591765475219441), FX16_CONST(0.8883450333095964),
+ FX16_CONST(0.46053871095824), FX16_CONST(0.8876396204028539),
+ FX16_CONST(0.46189979070246273), FX16_CONST(0.8869321187943422),
+ FX16_CONST(0.46325978355186015), FX16_CONST(0.8862225301488806),
+ FX16_CONST(0.4646186863062378), FX16_CONST(0.8855108561362),
+ FX16_CONST(0.4659764957679662), FX16_CONST(0.8847970984309378),
+ FX16_CONST(0.4673332087419884), FX16_CONST(0.884081258712635),
+ FX16_CONST(0.4686888220358279), FX16_CONST(0.8833633386657316),
+ FX16_CONST(0.4700433324595956), FX16_CONST(0.8826433399795628),
+ FX16_CONST(0.47139673682599764), FX16_CONST(0.881921264348355),
+ FX16_CONST(0.4727490319503428), FX16_CONST(0.8811971134712221),
+ FX16_CONST(0.47410021465054997), FX16_CONST(0.8804708890521608),
+ FX16_CONST(0.47545028174715587), FX16_CONST(0.8797425928000474),
+ FX16_CONST(0.4767992300633221), FX16_CONST(0.8790122264286335),
+ FX16_CONST(0.478147056424843), FX16_CONST(0.8782797916565416),
+ FX16_CONST(0.47949375766015295), FX16_CONST(0.8775452902072614),
+ FX16_CONST(0.48083933060033396), FX16_CONST(0.8768087238091457),
+ FX16_CONST(0.4821837720791227), FX16_CONST(0.8760700941954066),
+ FX16_CONST(0.4835270789329187), FX16_CONST(0.8753294031041109),
+ FX16_CONST(0.48486924800079106), FX16_CONST(0.8745866522781761),
+ FX16_CONST(0.4862102761244864), FX16_CONST(0.8738418434653669),
+ FX16_CONST(0.487550160148436), FX16_CONST(0.8730949784182901),
+ FX16_CONST(0.48888889691976317), FX16_CONST(0.8723460588943915),
+ FX16_CONST(0.49022648328829116), FX16_CONST(0.871595086655951),
+ FX16_CONST(0.4915629161065499), FX16_CONST(0.870842063470079),
+ FX16_CONST(0.49289819222978404), FX16_CONST(0.8700869911087115),
+ FX16_CONST(0.4942323085159597), FX16_CONST(0.8693298713486068),
+ FX16_CONST(0.49556526182577254), FX16_CONST(0.8685707059713409),
+ FX16_CONST(0.49689704902265447), FX16_CONST(0.8678094967633033),
+ FX16_CONST(0.4982276669727818), FX16_CONST(0.8670462455156926),
+ FX16_CONST(0.49955711254508184), FX16_CONST(0.866280954024513),
+ FX16_CONST(0.5008853826112407), FX16_CONST(0.8655136240905691),
+ FX16_CONST(0.5022124740457108), FX16_CONST(0.8647442575194624),
+ FX16_CONST(0.5035383837257176), FX16_CONST(0.8639728561215867),
+ FX16_CONST(0.5048631085312676), FX16_CONST(0.8631994217121242),
+ FX16_CONST(0.5061866453451552), FX16_CONST(0.8624239561110405),
+ FX16_CONST(0.5075089910529709), FX16_CONST(0.8616464611430813),
+ FX16_CONST(0.508830142543107), FX16_CONST(0.8608669386377673),
+ FX16_CONST(0.5101500967067668), FX16_CONST(0.8600853904293901),
+ FX16_CONST(0.5114688504379703), FX16_CONST(0.8593018183570085),
+ FX16_CONST(0.512786400633563), FX16_CONST(0.8585162242644427),
+ FX16_CONST(0.5141027441932217), FX16_CONST(0.8577286100002721),
+ FX16_CONST(0.5154178780194629), FX16_CONST(0.8569389774178288),
+ FX16_CONST(0.5167317990176499), FX16_CONST(0.8561473283751945),
+ FX16_CONST(0.5180445040959993), FX16_CONST(0.855353664735196),
+ FX16_CONST(0.5193559901655896), FX16_CONST(0.8545579883654005),
+ FX16_CONST(0.5206662541403672), FX16_CONST(0.8537603011381114),
+ FX16_CONST(0.5219752929371544), FX16_CONST(0.8529606049303636),
+ FX16_CONST(0.5232831034756564), FX16_CONST(0.8521589016239198),
+ FX16_CONST(0.524589682678469), FX16_CONST(0.8513551931052652),
+ FX16_CONST(0.5258950274710846), FX16_CONST(0.8505494812656035),
+ FX16_CONST(0.5271991347819013), FX16_CONST(0.8497417680008525),
+ FX16_CONST(0.5285020015422285), FX16_CONST(0.8489320552116396),
+ FX16_CONST(0.5298036246862946), FX16_CONST(0.8481203448032972),
+ FX16_CONST(0.531104001151255), FX16_CONST(0.8473066386858583),
+ FX16_CONST(0.5324031278771979), FX16_CONST(0.8464909387740521),
+ FX16_CONST(0.533701001807153), FX16_CONST(0.8456732469872991),
+ FX16_CONST(0.5349976198870972), FX16_CONST(0.8448535652497071),
+ FX16_CONST(0.5362929790659632), FX16_CONST(0.8440318954900664),
+ FX16_CONST(0.5375870762956454), FX16_CONST(0.8432082396418454),
+ FX16_CONST(0.5388799085310084), FX16_CONST(0.8423825996431858),
+ FX16_CONST(0.5401714727298929), FX16_CONST(0.8415549774368984),
+ FX16_CONST(0.5414617658531234), FX16_CONST(0.8407253749704581),
+ FX16_CONST(0.5427507848645159), FX16_CONST(0.8398937941959995),
+ FX16_CONST(0.5440385267308838), FX16_CONST(0.8390602370703127),
+ FX16_CONST(0.5453249884220465), FX16_CONST(0.8382247055548381),
+ FX16_CONST(0.5466101669108349), FX16_CONST(0.8373872016156619),
+ FX16_CONST(0.5478940591731002), FX16_CONST(0.836547727223512),
+ FX16_CONST(0.5491766621877197), FX16_CONST(0.8357062843537526),
+ FX16_CONST(0.5504579729366048), FX16_CONST(0.83486287498638),
+ FX16_CONST(0.5517379884047073), FX16_CONST(0.8340175011060181),
+ FX16_CONST(0.5530167055800275), FX16_CONST(0.8331701647019132),
+ FX16_CONST(0.55429412145362), FX16_CONST(0.8323208677679297),
+ FX16_CONST(0.5555702330196022), FX16_CONST(0.8314696123025452),
+ FX16_CONST(0.5568450372751601), FX16_CONST(0.8306164003088463),
+ FX16_CONST(0.5581185312205561), FX16_CONST(0.829761233794523),
+ FX16_CONST(0.5593907118591361), FX16_CONST(0.8289041147718649),
+ FX16_CONST(0.560661576197336), FX16_CONST(0.8280450452577558),
+ FX16_CONST(0.5619311212446894), FX16_CONST(0.8271840272736691),
+ FX16_CONST(0.5631993440138341), FX16_CONST(0.8263210628456635),
+ FX16_CONST(0.5644662415205194), FX16_CONST(0.8254561540043776),
+ FX16_CONST(0.5657318107836131), FX16_CONST(0.8245893027850253),
+ FX16_CONST(0.5669960488251087), FX16_CONST(0.8237205112273914),
+ FX16_CONST(0.5682589526701315), FX16_CONST(0.8228497813758264),
+ FX16_CONST(0.5695205193469471), FX16_CONST(0.8219771152792416),
+ FX16_CONST(0.5707807458869673), FX16_CONST(0.8211025149911046),
+ FX16_CONST(0.572039629324757), FX16_CONST(0.8202259825694347),
+ FX16_CONST(0.5732971666980422), FX16_CONST(0.819347520076797),
+ FX16_CONST(0.5745533550477158), FX16_CONST(0.8184671295802987),
+ FX16_CONST(0.5758081914178453), FX16_CONST(0.8175848131515837),
+ FX16_CONST(0.5770616728556794), FX16_CONST(0.8167005728668278),
+ FX16_CONST(0.5783137964116556), FX16_CONST(0.8158144108067338),
+ FX16_CONST(0.5795645591394056), FX16_CONST(0.8149263290565266),
+ FX16_CONST(0.5808139580957645), FX16_CONST(0.8140363297059484),
+ FX16_CONST(0.5820619903407754), FX16_CONST(0.8131444148492536),
+ FX16_CONST(0.5833086529376983), FX16_CONST(0.812250586585204),
+ FX16_CONST(0.5845539429530153), FX16_CONST(0.8113548470170637),
+ FX16_CONST(0.5857978574564389), FX16_CONST(0.8104571982525948),
+ FX16_CONST(0.587040393520918), FX16_CONST(0.8095576424040513),
+ FX16_CONST(0.5882815482226452), FX16_CONST(0.808656181588175),
+ FX16_CONST(0.5895213186410639), FX16_CONST(0.8077528179261904),
+ FX16_CONST(0.5907597018588742), FX16_CONST(0.8068475535437993),
+ FX16_CONST(0.591996694962041), FX16_CONST(0.8059403905711763),
+ FX16_CONST(0.5932322950397998), FX16_CONST(0.8050313311429637),
+ FX16_CONST(0.5944664991846644), FX16_CONST(0.8041203773982657),
+ FX16_CONST(0.5956993044924334), FX16_CONST(0.8032075314806449),
+ FX16_CONST(0.5969307080621964), FX16_CONST(0.8022927955381157),
+ FX16_CONST(0.5981607069963424), FX16_CONST(0.8013761717231402),
+ FX16_CONST(0.5993892984005645), FX16_CONST(0.8004576621926228),
+ FX16_CONST(0.600616479383869), FX16_CONST(0.799537269107905),
+ FX16_CONST(0.60184224705858), FX16_CONST(0.7986149946347609),
+ FX16_CONST(0.6030665985403482), FX16_CONST(0.7976908409433912),
+ FX16_CONST(0.604289530948156), FX16_CONST(0.7967648102084188),
+ FX16_CONST(0.6055110414043255), FX16_CONST(0.7958369046088836),
+ FX16_CONST(0.6067311270345245), FX16_CONST(0.794907126328237),
+ FX16_CONST(0.6079497849677736), FX16_CONST(0.7939754775543372),
+ FX16_CONST(0.6091670123364532), FX16_CONST(0.7930419604794436),
+ FX16_CONST(0.6103828062763095), FX16_CONST(0.7921065773002124),
+ FX16_CONST(0.6115971639264619), FX16_CONST(0.7911693302176902),
+ FX16_CONST(0.6128100824294097), FX16_CONST(0.79023022143731),
+ FX16_CONST(0.6140215589310385), FX16_CONST(0.7892892531688857),
+ FX16_CONST(0.6152315905806268), FX16_CONST(0.7883464276266062),
+ FX16_CONST(0.6164401745308536), FX16_CONST(0.7874017470290314),
+ FX16_CONST(0.6176473079378039), FX16_CONST(0.7864552135990858),
+ FX16_CONST(0.6188529879609763), FX16_CONST(0.7855068295640539),
+ FX16_CONST(0.6200572117632891), FX16_CONST(0.7845565971555752),
+ FX16_CONST(0.6212599765110876), FX16_CONST(0.7836045186096382),
+ FX16_CONST(0.62246127937415), FX16_CONST(0.7826505961665757),
+ FX16_CONST(0.6236611175256945), FX16_CONST(0.7816948320710594),
+ FX16_CONST(0.6248594881423863), FX16_CONST(0.7807372285720945),
+ FX16_CONST(0.6260563884043435), FX16_CONST(0.7797777879230146),
+ FX16_CONST(0.6272518154951441), FX16_CONST(0.778816512381476),
+ FX16_CONST(0.6284457666018327), FX16_CONST(0.7778534042094531),
+ FX16_CONST(0.629638238914927), FX16_CONST(0.7768884656732324),
+ FX16_CONST(0.6308292296284245), FX16_CONST(0.7759216990434077),
+ FX16_CONST(0.6320187359398091), FX16_CONST(0.7749531065948739),
+ FX16_CONST(0.6332067550500572), FX16_CONST(0.7739826906068229),
+ FX16_CONST(0.6343932841636455), FX16_CONST(0.773010453362737),
+ FX16_CONST(0.6355783204885561), FX16_CONST(0.7720363971503845),
+ FX16_CONST(0.6367618612362842), FX16_CONST(0.7710605242618138),
+ FX16_CONST(0.637943903621844), FX16_CONST(0.7700828369933479),
+ FX16_CONST(0.6391244448637757), FX16_CONST(0.7691033376455797),
+ FX16_CONST(0.6403034821841517), FX16_CONST(0.7681220285233654),
+ FX16_CONST(0.641481012808583), FX16_CONST(0.7671389119358204),
+ FX16_CONST(0.6426570339662269), FX16_CONST(0.7661539901963129),
+ FX16_CONST(0.6438315428897914), FX16_CONST(0.765167265622459),
+ FX16_CONST(0.6450045368155439), FX16_CONST(0.7641787405361167),
+ FX16_CONST(0.6461760129833163), FX16_CONST(0.7631884172633814),
+ FX16_CONST(0.6473459686365121), FX16_CONST(0.762196298134579),
+ FX16_CONST(0.6485144010221124), FX16_CONST(0.7612023854842618),
+ FX16_CONST(0.6496813073906832), FX16_CONST(0.7602066816512024),
+ FX16_CONST(0.6508466849963809), FX16_CONST(0.759209188978388),
+ FX16_CONST(0.6520105310969595), FX16_CONST(0.7582099098130153),
+ FX16_CONST(0.6531728429537768), FX16_CONST(0.7572088465064846),
+ FX16_CONST(0.6543336178318004), FX16_CONST(0.7562060014143945),
+ FX16_CONST(0.6554928529996153), FX16_CONST(0.7552013768965365),
+ FX16_CONST(0.6566505457294289), FX16_CONST(0.7541949753168892),
+ FX16_CONST(0.6578066932970786), FX16_CONST(0.7531867990436125),
+ FX16_CONST(0.6589612929820373), FX16_CONST(0.7521768504490427),
+ FX16_CONST(0.6601143420674205), FX16_CONST(0.7511651319096864),
+ FX16_CONST(0.6612658378399923), FX16_CONST(0.7501516458062151),
+ FX16_CONST(0.6624157775901718), FX16_CONST(0.7491363945234594),
+ FX16_CONST(0.6635641586120398), FX16_CONST(0.7481193804504036),
+ FX16_CONST(0.6647109782033448), FX16_CONST(0.7471006059801801),
+ FX16_CONST(0.6658562336655097), FX16_CONST(0.7460800735100638),
+ FX16_CONST(0.6669999223036375), FX16_CONST(0.745057785441466),
+ FX16_CONST(0.6681420414265185), FX16_CONST(0.7440337441799293),
+ FX16_CONST(0.669282588346636), FX16_CONST(0.7430079521351217),
+ FX16_CONST(0.6704215603801731), FX16_CONST(0.7419804117208311),
+ FX16_CONST(0.6715589548470183), FX16_CONST(0.7409511253549592),
+ FX16_CONST(0.6726947690707729), FX16_CONST(0.7399200954595162),
+ FX16_CONST(0.673829000378756), FX16_CONST(0.7388873244606151),
+ FX16_CONST(0.6749616461020119), FX16_CONST(0.737852814788466),
+ FX16_CONST(0.6760927035753159), FX16_CONST(0.7368165688773698),
+ FX16_CONST(0.6772221701371803), FX16_CONST(0.7357785891657136),
+ FX16_CONST(0.6783500431298615), FX16_CONST(0.7347388780959635),
+ FX16_CONST(0.679476319899365), FX16_CONST(0.7336974381146603),
+ FX16_CONST(0.680600997795453), FX16_CONST(0.7326542716724128),
+ FX16_CONST(0.6817240741716497), FX16_CONST(0.7316093812238926),
+ FX16_CONST(0.6828455463852481), FX16_CONST(0.7305627692278276),
+ FX16_CONST(0.6839654117973154), FX16_CONST(0.729514438146997),
+ FX16_CONST(0.6850836677727004), FX16_CONST(0.7284643904482252),
+ FX16_CONST(0.6862003116800386), FX16_CONST(0.7274126286023758),
+ FX16_CONST(0.687315340891759), FX16_CONST(0.726359155084346),
+ FX16_CONST(0.6884287527840904), FX16_CONST(0.7253039723730608),
+ FX16_CONST(0.6895405447370668), FX16_CONST(0.724247082951467),
+ FX16_CONST(0.6906507141345346), FX16_CONST(0.7231884893065275),
+ FX16_CONST(0.6917592583641577), FX16_CONST(0.7221281939292153),
+ FX16_CONST(0.6928661748174246), FX16_CONST(0.7210661993145081),
+ FX16_CONST(0.6939714608896539), FX16_CONST(0.7200025079613817),
+ FX16_CONST(0.6950751139800009), FX16_CONST(0.7189371223728045),
+ FX16_CONST(0.696177131491463), FX16_CONST(0.7178700450557317),
+ FX16_CONST(0.6972775108308865), FX16_CONST(0.7168012785210995),
+ FX16_CONST(0.6983762494089728), FX16_CONST(0.7157308252838187),
+ FX16_CONST(0.6994733446402838), FX16_CONST(0.7146586878627691),
+ FX16_CONST(0.7005687939432483), FX16_CONST(0.7135848687807935),
+ FX16_CONST(0.7016625947401685), FX16_CONST(0.7125093705646924),
+ FX16_CONST(0.7027547444572253), FX16_CONST(0.7114321957452164),
+ FX16_CONST(0.7038452405244849), FX16_CONST(0.7103533468570624),
+ FX16_CONST(0.7049340803759049), FX16_CONST(0.7092728264388657),
+ FX16_CONST(0.7060212614493397), FX16_CONST(0.7081906370331954),
+ FX16_CONST(0.7071067811865476), FX16_CONST(0.7071067811865476),
+ FX16_CONST(0.7081906370331954), FX16_CONST(0.7060212614493397),
+ FX16_CONST(0.7092728264388657), FX16_CONST(0.704934080375905),
+ FX16_CONST(0.7103533468570624), FX16_CONST(0.7038452405244849),
+ FX16_CONST(0.7114321957452164), FX16_CONST(0.7027547444572253),
+ FX16_CONST(0.7125093705646923), FX16_CONST(0.7016625947401685),
+ FX16_CONST(0.7135848687807935), FX16_CONST(0.7005687939432484),
+ FX16_CONST(0.7146586878627691), FX16_CONST(0.6994733446402838),
+ FX16_CONST(0.7157308252838186), FX16_CONST(0.6983762494089729),
+ FX16_CONST(0.7168012785210994), FX16_CONST(0.6972775108308866),
+ FX16_CONST(0.7178700450557317), FX16_CONST(0.696177131491463),
+ FX16_CONST(0.7189371223728044), FX16_CONST(0.6950751139800009),
+ FX16_CONST(0.7200025079613817), FX16_CONST(0.693971460889654),
+ FX16_CONST(0.7210661993145081), FX16_CONST(0.6928661748174247),
+ FX16_CONST(0.7221281939292153), FX16_CONST(0.6917592583641577),
+ FX16_CONST(0.7231884893065273), FX16_CONST(0.6906507141345346),
+ FX16_CONST(0.7242470829514669), FX16_CONST(0.6895405447370669),
+ FX16_CONST(0.7253039723730608), FX16_CONST(0.6884287527840904),
+ FX16_CONST(0.726359155084346), FX16_CONST(0.687315340891759),
+ FX16_CONST(0.7274126286023758), FX16_CONST(0.6862003116800386),
+ FX16_CONST(0.7284643904482252), FX16_CONST(0.6850836677727004),
+ FX16_CONST(0.7295144381469969), FX16_CONST(0.6839654117973155),
+ FX16_CONST(0.7305627692278276), FX16_CONST(0.6828455463852481),
+ FX16_CONST(0.7316093812238926), FX16_CONST(0.6817240741716498),
+ FX16_CONST(0.7326542716724128), FX16_CONST(0.680600997795453),
+ FX16_CONST(0.7336974381146603), FX16_CONST(0.679476319899365),
+ FX16_CONST(0.7347388780959635), FX16_CONST(0.6783500431298615),
+ FX16_CONST(0.7357785891657135), FX16_CONST(0.6772221701371804),
+ FX16_CONST(0.7368165688773698), FX16_CONST(0.676092703575316),
+ FX16_CONST(0.737852814788466), FX16_CONST(0.674961646102012),
+ FX16_CONST(0.7388873244606151), FX16_CONST(0.6738290003787561),
+ FX16_CONST(0.7399200954595161), FX16_CONST(0.672694769070773),
+ FX16_CONST(0.7409511253549591), FX16_CONST(0.6715589548470183),
+ FX16_CONST(0.741980411720831), FX16_CONST(0.6704215603801731),
+ FX16_CONST(0.7430079521351217), FX16_CONST(0.669282588346636),
+ FX16_CONST(0.7440337441799293), FX16_CONST(0.6681420414265186),
+ FX16_CONST(0.745057785441466), FX16_CONST(0.6669999223036375),
+ FX16_CONST(0.7460800735100637), FX16_CONST(0.6658562336655097),
+ FX16_CONST(0.7471006059801801), FX16_CONST(0.6647109782033449),
+ FX16_CONST(0.7481193804504035), FX16_CONST(0.6635641586120399),
+ FX16_CONST(0.7491363945234593), FX16_CONST(0.6624157775901718),
+ FX16_CONST(0.750151645806215), FX16_CONST(0.6612658378399923),
+ FX16_CONST(0.7511651319096864), FX16_CONST(0.6601143420674205),
+ FX16_CONST(0.7521768504490427), FX16_CONST(0.6589612929820373),
+ FX16_CONST(0.7531867990436125), FX16_CONST(0.6578066932970787),
+ FX16_CONST(0.7541949753168892), FX16_CONST(0.656650545729429),
+ FX16_CONST(0.7552013768965365), FX16_CONST(0.6554928529996155),
+ FX16_CONST(0.7562060014143945), FX16_CONST(0.6543336178318006),
+ FX16_CONST(0.7572088465064846), FX16_CONST(0.6531728429537769),
+ FX16_CONST(0.7582099098130153), FX16_CONST(0.6520105310969595),
+ FX16_CONST(0.759209188978388), FX16_CONST(0.650846684996381),
+ FX16_CONST(0.7602066816512024), FX16_CONST(0.6496813073906832),
+ FX16_CONST(0.7612023854842618), FX16_CONST(0.6485144010221126),
+ FX16_CONST(0.7621962981345789), FX16_CONST(0.6473459686365121),
+ FX16_CONST(0.7631884172633813), FX16_CONST(0.6461760129833164),
+ FX16_CONST(0.7641787405361167), FX16_CONST(0.645004536815544),
+ FX16_CONST(0.765167265622459), FX16_CONST(0.6438315428897915),
+ FX16_CONST(0.7661539901963128), FX16_CONST(0.6426570339662269),
+ FX16_CONST(0.7671389119358204), FX16_CONST(0.6414810128085832),
+ FX16_CONST(0.7681220285233653), FX16_CONST(0.6403034821841517),
+ FX16_CONST(0.7691033376455796), FX16_CONST(0.6391244448637757),
+ FX16_CONST(0.7700828369933479), FX16_CONST(0.6379439036218442),
+ FX16_CONST(0.7710605242618138), FX16_CONST(0.6367618612362842),
+ FX16_CONST(0.7720363971503844), FX16_CONST(0.6355783204885562),
+ FX16_CONST(0.7730104533627369), FX16_CONST(0.6343932841636455),
+ FX16_CONST(0.7739826906068228), FX16_CONST(0.6332067550500572),
+ FX16_CONST(0.7749531065948738), FX16_CONST(0.6320187359398091),
+ FX16_CONST(0.7759216990434076), FX16_CONST(0.6308292296284246),
+ FX16_CONST(0.7768884656732324), FX16_CONST(0.6296382389149271),
+ FX16_CONST(0.777853404209453), FX16_CONST(0.6284457666018327),
+ FX16_CONST(0.7788165123814759), FX16_CONST(0.6272518154951442),
+ FX16_CONST(0.7797777879230144), FX16_CONST(0.6260563884043435),
+ FX16_CONST(0.7807372285720945), FX16_CONST(0.6248594881423865),
+ FX16_CONST(0.7816948320710594), FX16_CONST(0.6236611175256946),
+ FX16_CONST(0.7826505961665757), FX16_CONST(0.6224612793741501),
+ FX16_CONST(0.7836045186096382), FX16_CONST(0.6212599765110877),
+ FX16_CONST(0.7845565971555752), FX16_CONST(0.6200572117632892),
+ FX16_CONST(0.7855068295640539), FX16_CONST(0.6188529879609763),
+ FX16_CONST(0.7864552135990858), FX16_CONST(0.617647307937804),
+ FX16_CONST(0.7874017470290313), FX16_CONST(0.6164401745308536),
+ FX16_CONST(0.7883464276266062), FX16_CONST(0.6152315905806268),
+ FX16_CONST(0.7892892531688857), FX16_CONST(0.6140215589310385),
+ FX16_CONST(0.79023022143731), FX16_CONST(0.6128100824294097),
+ FX16_CONST(0.7911693302176901), FX16_CONST(0.611597163926462),
+ FX16_CONST(0.7921065773002123), FX16_CONST(0.6103828062763095),
+ FX16_CONST(0.7930419604794436), FX16_CONST(0.6091670123364532),
+ FX16_CONST(0.7939754775543372), FX16_CONST(0.6079497849677737),
+ FX16_CONST(0.794907126328237), FX16_CONST(0.6067311270345245),
+ FX16_CONST(0.7958369046088835), FX16_CONST(0.6055110414043255),
+ FX16_CONST(0.7967648102084187), FX16_CONST(0.6042895309481561),
+ FX16_CONST(0.797690840943391), FX16_CONST(0.6030665985403483),
+ FX16_CONST(0.7986149946347608), FX16_CONST(0.60184224705858),
+ FX16_CONST(0.799537269107905), FX16_CONST(0.600616479383869),
+ FX16_CONST(0.8004576621926227), FX16_CONST(0.5993892984005645),
+ FX16_CONST(0.8013761717231401), FX16_CONST(0.5981607069963424),
+ FX16_CONST(0.8022927955381157), FX16_CONST(0.5969307080621965),
+ FX16_CONST(0.8032075314806448), FX16_CONST(0.5956993044924335),
+ FX16_CONST(0.8041203773982657), FX16_CONST(0.5944664991846645),
+ FX16_CONST(0.8050313311429637), FX16_CONST(0.5932322950397998),
+ FX16_CONST(0.8059403905711763), FX16_CONST(0.591996694962041),
+ FX16_CONST(0.8068475535437992), FX16_CONST(0.5907597018588743),
+ FX16_CONST(0.8077528179261902), FX16_CONST(0.5895213186410639),
+ FX16_CONST(0.808656181588175), FX16_CONST(0.5882815482226453),
+ FX16_CONST(0.8095576424040513), FX16_CONST(0.5870403935209181),
+ FX16_CONST(0.8104571982525948), FX16_CONST(0.5857978574564389),
+ FX16_CONST(0.8113548470170637), FX16_CONST(0.5845539429530153),
+ FX16_CONST(0.8122505865852039), FX16_CONST(0.5833086529376983),
+ FX16_CONST(0.8131444148492536), FX16_CONST(0.5820619903407755),
+ FX16_CONST(0.8140363297059483), FX16_CONST(0.5808139580957645),
+ FX16_CONST(0.8149263290565266), FX16_CONST(0.5795645591394057),
+ FX16_CONST(0.8158144108067338), FX16_CONST(0.5783137964116556),
+ FX16_CONST(0.8167005728668278), FX16_CONST(0.5770616728556796),
+ FX16_CONST(0.8175848131515837), FX16_CONST(0.5758081914178453),
+ FX16_CONST(0.8184671295802987), FX16_CONST(0.5745533550477158),
+ FX16_CONST(0.8193475200767969), FX16_CONST(0.5732971666980423),
+ FX16_CONST(0.8202259825694347), FX16_CONST(0.572039629324757),
+ FX16_CONST(0.8211025149911046), FX16_CONST(0.5707807458869674),
+ FX16_CONST(0.8219771152792416), FX16_CONST(0.5695205193469473),
+ FX16_CONST(0.8228497813758263), FX16_CONST(0.5682589526701315),
+ FX16_CONST(0.8237205112273913), FX16_CONST(0.5669960488251087),
+ FX16_CONST(0.8245893027850253), FX16_CONST(0.5657318107836132),
+ FX16_CONST(0.8254561540043774), FX16_CONST(0.5644662415205195),
+ FX16_CONST(0.8263210628456635), FX16_CONST(0.5631993440138341),
+ FX16_CONST(0.8271840272736691), FX16_CONST(0.5619311212446895),
+ FX16_CONST(0.8280450452577558), FX16_CONST(0.560661576197336),
+ FX16_CONST(0.8289041147718649), FX16_CONST(0.5593907118591361),
+ FX16_CONST(0.829761233794523), FX16_CONST(0.5581185312205561),
+ FX16_CONST(0.8306164003088462), FX16_CONST(0.5568450372751601),
+ FX16_CONST(0.8314696123025452), FX16_CONST(0.5555702330196023),
+ FX16_CONST(0.8323208677679297), FX16_CONST(0.5542941214536201),
+ FX16_CONST(0.8331701647019132), FX16_CONST(0.5530167055800276),
+ FX16_CONST(0.8340175011060181), FX16_CONST(0.5517379884047074),
+ FX16_CONST(0.83486287498638), FX16_CONST(0.5504579729366048),
+ FX16_CONST(0.8357062843537526), FX16_CONST(0.5491766621877198),
+ FX16_CONST(0.8365477272235119), FX16_CONST(0.5478940591731002),
+ FX16_CONST(0.8373872016156619), FX16_CONST(0.5466101669108349),
+ FX16_CONST(0.838224705554838), FX16_CONST(0.5453249884220465),
+ FX16_CONST(0.8390602370703126), FX16_CONST(0.5440385267308839),
+ FX16_CONST(0.8398937941959994), FX16_CONST(0.542750784864516),
+ FX16_CONST(0.840725374970458), FX16_CONST(0.5414617658531236),
+ FX16_CONST(0.8415549774368983), FX16_CONST(0.540171472729893),
+ FX16_CONST(0.8423825996431858), FX16_CONST(0.5388799085310084),
+ FX16_CONST(0.8432082396418454), FX16_CONST(0.5375870762956455),
+ FX16_CONST(0.8440318954900664), FX16_CONST(0.5362929790659632),
+ FX16_CONST(0.844853565249707), FX16_CONST(0.5349976198870973),
+ FX16_CONST(0.8456732469872991), FX16_CONST(0.533701001807153),
+ FX16_CONST(0.8464909387740521), FX16_CONST(0.532403127877198),
+ FX16_CONST(0.8473066386858583), FX16_CONST(0.531104001151255),
+ FX16_CONST(0.8481203448032971), FX16_CONST(0.5298036246862948),
+ FX16_CONST(0.8489320552116396), FX16_CONST(0.5285020015422285),
+ FX16_CONST(0.8497417680008524), FX16_CONST(0.5271991347819014),
+ FX16_CONST(0.8505494812656034), FX16_CONST(0.5258950274710847),
+ FX16_CONST(0.8513551931052652), FX16_CONST(0.5245896826784688),
+ FX16_CONST(0.8521589016239198), FX16_CONST(0.5232831034756564),
+ FX16_CONST(0.8529606049303636), FX16_CONST(0.5219752929371544),
+ FX16_CONST(0.8537603011381113), FX16_CONST(0.5206662541403673),
+ FX16_CONST(0.8545579883654005), FX16_CONST(0.5193559901655895),
+ FX16_CONST(0.855353664735196), FX16_CONST(0.5180445040959993),
+ FX16_CONST(0.8561473283751945), FX16_CONST(0.51673179901765),
+ FX16_CONST(0.8569389774178287), FX16_CONST(0.5154178780194631),
+ FX16_CONST(0.8577286100002721), FX16_CONST(0.5141027441932217),
+ FX16_CONST(0.8585162242644427), FX16_CONST(0.5127864006335631),
+ FX16_CONST(0.8593018183570084), FX16_CONST(0.5114688504379705),
+ FX16_CONST(0.8600853904293903), FX16_CONST(0.5101500967067667),
+ FX16_CONST(0.8608669386377673), FX16_CONST(0.508830142543107),
+ FX16_CONST(0.8616464611430813), FX16_CONST(0.5075089910529709),
+ FX16_CONST(0.8624239561110405), FX16_CONST(0.5061866453451553),
+ FX16_CONST(0.8631994217121242), FX16_CONST(0.5048631085312675),
+ FX16_CONST(0.8639728561215867), FX16_CONST(0.5035383837257176),
+ FX16_CONST(0.8647442575194624), FX16_CONST(0.5022124740457109),
+ FX16_CONST(0.865513624090569), FX16_CONST(0.5008853826112409),
+ FX16_CONST(0.866280954024513), FX16_CONST(0.49955711254508184),
+ FX16_CONST(0.8670462455156926), FX16_CONST(0.49822766697278187),
+ FX16_CONST(0.8678094967633032), FX16_CONST(0.49689704902265464),
+ FX16_CONST(0.8685707059713409), FX16_CONST(0.4955652618257725),
+ FX16_CONST(0.8693298713486067), FX16_CONST(0.49423230851595973),
+ FX16_CONST(0.8700869911087113), FX16_CONST(0.4928981922297841),
+ FX16_CONST(0.8708420634700789), FX16_CONST(0.49156291610655006),
+ FX16_CONST(0.8715950866559511), FX16_CONST(0.4902264832882911),
+ FX16_CONST(0.8723460588943914), FX16_CONST(0.4888888969197632),
+ FX16_CONST(0.8730949784182901), FX16_CONST(0.48755016014843605),
+ FX16_CONST(0.8738418434653668), FX16_CONST(0.48621027612448653),
+ FX16_CONST(0.8745866522781761), FX16_CONST(0.4848692480007911),
+ FX16_CONST(0.8753294031041108), FX16_CONST(0.48352707893291874),
+ FX16_CONST(0.8760700941954066), FX16_CONST(0.48218377207912283),
+ FX16_CONST(0.8768087238091458), FX16_CONST(0.4808393306003339),
+ FX16_CONST(0.8775452902072612), FX16_CONST(0.479493757660153),
+ FX16_CONST(0.8782797916565415), FX16_CONST(0.4781470564248431),
+ FX16_CONST(0.8790122264286334), FX16_CONST(0.47679923006332225),
+ FX16_CONST(0.8797425928000474), FX16_CONST(0.47545028174715587),
+ FX16_CONST(0.8804708890521608), FX16_CONST(0.47410021465055),
+ FX16_CONST(0.881197113471222), FX16_CONST(0.4727490319503429),
+ FX16_CONST(0.8819212643483549), FX16_CONST(0.4713967368259978),
+ FX16_CONST(0.8826433399795628), FX16_CONST(0.4700433324595956),
+ FX16_CONST(0.8833633386657316), FX16_CONST(0.46868882203582796),
+ FX16_CONST(0.884081258712635), FX16_CONST(0.4673332087419885),
+ FX16_CONST(0.8847970984309378), FX16_CONST(0.4659764957679661),
+ FX16_CONST(0.8855108561362), FX16_CONST(0.4646186863062378),
+ FX16_CONST(0.8862225301488806), FX16_CONST(0.46325978355186026),
+ FX16_CONST(0.8869321187943421), FX16_CONST(0.46189979070246284),
+ FX16_CONST(0.8876396204028539), FX16_CONST(0.46053871095824),
+ FX16_CONST(0.8883450333095964), FX16_CONST(0.45917654752194415),
+ FX16_CONST(0.8890483558546646), FX16_CONST(0.4578133035988773),
+ FX16_CONST(0.8897495863830729), FX16_CONST(0.45644898239688386),
+ FX16_CONST(0.8904487232447579), FX16_CONST(0.45508358712634384),
+ FX16_CONST(0.8911457647945832), FX16_CONST(0.4537171210001639),
+ FX16_CONST(0.8918407093923427), FX16_CONST(0.452349587233771),
+ FX16_CONST(0.8925335554027647), FX16_CONST(0.4509809890451038),
+ FX16_CONST(0.8932243011955153), FX16_CONST(0.4496113296546066),
+ FX16_CONST(0.8939129451452033), FX16_CONST(0.44824061228522),
+ FX16_CONST(0.8945994856313826), FX16_CONST(0.4468688401623743),
+ FX16_CONST(0.8952839210385576), FX16_CONST(0.44549601651398174),
+ FX16_CONST(0.8959662497561851), FX16_CONST(0.44412214457042926),
+ FX16_CONST(0.8966464701786802), FX16_CONST(0.44274722756457013),
+ FX16_CONST(0.8973245807054183), FX16_CONST(0.4413712687317166),
+ FX16_CONST(0.8980005797407399), FX16_CONST(0.43999427130963326),
+ FX16_CONST(0.8986744656939538), FX16_CONST(0.4386162385385277),
+ FX16_CONST(0.8993462369793415), FX16_CONST(0.4372371736610442),
+ FX16_CONST(0.9000158920161603), FX16_CONST(0.4358570799222555),
+ FX16_CONST(0.9006834292286469), FX16_CONST(0.4344759605696557),
+ FX16_CONST(0.901348847046022), FX16_CONST(0.433093818853152),
+ FX16_CONST(0.9020121439024931), FX16_CONST(0.43171065802505737),
+ FX16_CONST(0.9026733182372588), FX16_CONST(0.4303264813400826),
+ FX16_CONST(0.9033323684945118), FX16_CONST(0.42894129205532955),
+ FX16_CONST(0.9039892931234433), FX16_CONST(0.4275550934302822),
+ FX16_CONST(0.9046440905782462), FX16_CONST(0.4261678887267996),
+ FX16_CONST(0.9052967593181188), FX16_CONST(0.4247796812091088),
+ FX16_CONST(0.9059472978072685), FX16_CONST(0.4233904741437961),
+ FX16_CONST(0.9065957045149153), FX16_CONST(0.4220002707997998),
+ FX16_CONST(0.9072419779152959), FX16_CONST(0.4206090744484025),
+ FX16_CONST(0.9078861164876663), FX16_CONST(0.41921688836322396),
+ FX16_CONST(0.9085281187163061), FX16_CONST(0.4178237158202124),
+ FX16_CONST(0.9091679830905223), FX16_CONST(0.4164295600976373),
+ FX16_CONST(0.9098057081046522), FX16_CONST(0.41503442447608163),
+ FX16_CONST(0.9104412922580671), FX16_CONST(0.41363831223843456),
+ FX16_CONST(0.9110747340551762), FX16_CONST(0.412241226669883),
+ FX16_CONST(0.9117060320054299), FX16_CONST(0.4108431710579039),
+ FX16_CONST(0.9123351846233227), FX16_CONST(0.40944414869225765),
+ FX16_CONST(0.9129621904283981), FX16_CONST(0.40804416286497874),
+ FX16_CONST(0.9135870479452508), FX16_CONST(0.40664321687036914),
+ FX16_CONST(0.9142097557035307), FX16_CONST(0.40524131400498986),
+ FX16_CONST(0.9148303122379461), FX16_CONST(0.40383845756765413),
+ FX16_CONST(0.9154487160882678), FX16_CONST(0.40243465085941854),
+ FX16_CONST(0.9160649657993316), FX16_CONST(0.4010298971835758),
+ FX16_CONST(0.9166790599210427), FX16_CONST(0.3996241998456468),
+ FX16_CONST(0.9172909970083779), FX16_CONST(0.3982175621533736),
+ FX16_CONST(0.9179007756213904), FX16_CONST(0.3968099874167104),
+ FX16_CONST(0.9185083943252123), FX16_CONST(0.3954014789478163),
+ FX16_CONST(0.9191138516900578), FX16_CONST(0.3939920400610481),
+ FX16_CONST(0.9197171462912274), FX16_CONST(0.3925816740729515),
+ FX16_CONST(0.9203182767091105), FX16_CONST(0.391170384302254),
+ FX16_CONST(0.9209172415291894), FX16_CONST(0.3897581740698564),
+ FX16_CONST(0.9215140393420419), FX16_CONST(0.3883450466988263),
+ FX16_CONST(0.9221086687433451), FX16_CONST(0.3869310055143887),
+ FX16_CONST(0.9227011283338785), FX16_CONST(0.385516053843919),
+ FX16_CONST(0.9232914167195276), FX16_CONST(0.38410019501693504),
+ FX16_CONST(0.9238795325112867), FX16_CONST(0.38268343236508984),
+ FX16_CONST(0.9244654743252626), FX16_CONST(0.3812657692221625),
+ FX16_CONST(0.9250492407826776), FX16_CONST(0.3798472089240511),
+ FX16_CONST(0.9256308305098727), FX16_CONST(0.3784277548087656),
+ FX16_CONST(0.9262102421383113), FX16_CONST(0.3770074102164183),
+ FX16_CONST(0.9267874743045817), FX16_CONST(0.3755861784892173),
+ FX16_CONST(0.9273625256504011), FX16_CONST(0.374164062971458),
+ FX16_CONST(0.9279353948226179), FX16_CONST(0.3727410670095158),
+ FX16_CONST(0.9285060804732156), FX16_CONST(0.3713171939518376),
+ FX16_CONST(0.9290745812593157), FX16_CONST(0.36989244714893427),
+ FX16_CONST(0.9296408958431812), FX16_CONST(0.3684668299533723),
+ FX16_CONST(0.9302050228922191), FX16_CONST(0.36704034571976724),
+ FX16_CONST(0.9307669610789837), FX16_CONST(0.36561299780477396),
+ FX16_CONST(0.9313267090811804), FX16_CONST(0.36418478956707984),
+ FX16_CONST(0.9318842655816681), FX16_CONST(0.3627557243673972),
+ FX16_CONST(0.9324396292684624), FX16_CONST(0.36132580556845434),
+ FX16_CONST(0.9329927988347388), FX16_CONST(0.3598950365349883),
+ FX16_CONST(0.9335437729788362), FX16_CONST(0.35846342063373654),
+ FX16_CONST(0.9340925504042589), FX16_CONST(0.35703096123343003),
+ FX16_CONST(0.9346391298196808), FX16_CONST(0.35559766170478396),
+ FX16_CONST(0.9351835099389475), FX16_CONST(0.3541635254204905),
+ FX16_CONST(0.9357256894810804), FX16_CONST(0.3527285557552107),
+ FX16_CONST(0.9362656671702783), FX16_CONST(0.35129275608556715),
+ FX16_CONST(0.9368034417359216), FX16_CONST(0.34985612979013503),
+ FX16_CONST(0.937339011912575), FX16_CONST(0.3484186802494345),
+ FX16_CONST(0.9378723764399899), FX16_CONST(0.3469804108459237),
+ FX16_CONST(0.9384035340631081), FX16_CONST(0.34554132496398915),
+ FX16_CONST(0.9389324835320645), FX16_CONST(0.344101425989939),
+ FX16_CONST(0.9394592236021899), FX16_CONST(0.3426607173119944),
+ FX16_CONST(0.9399837530340139), FX16_CONST(0.3412192023202824),
+ FX16_CONST(0.9405060705932683), FX16_CONST(0.33977688440682696),
+ FX16_CONST(0.9410261750508893), FX16_CONST(0.3383337669655413),
+ FX16_CONST(0.9415440651830208), FX16_CONST(0.33688985339222005),
+ FX16_CONST(0.9420597397710173), FX16_CONST(0.33544514708453166),
+ FX16_CONST(0.9425731976014469), FX16_CONST(0.3339996514420095),
+ FX16_CONST(0.9430844374660935), FX16_CONST(0.3325533698660442),
+ FX16_CONST(0.9435934581619604), FX16_CONST(0.33110630575987643),
+ FX16_CONST(0.9441002584912727), FX16_CONST(0.32965846252858755),
+ FX16_CONST(0.9446048372614803), FX16_CONST(0.32820984357909266),
+ FX16_CONST(0.9451071932852606), FX16_CONST(0.3267604523201318),
+ FX16_CONST(0.9456073253805213), FX16_CONST(0.325310292162263),
+ FX16_CONST(0.9461052323704033), FX16_CONST(0.32385936651785296),
+ FX16_CONST(0.9466009130832835), FX16_CONST(0.32240767880107),
+ FX16_CONST(0.9470943663527772), FX16_CONST(0.3209552324278752),
+ FX16_CONST(0.9475855910177411), FX16_CONST(0.31950203081601575),
+ FX16_CONST(0.9480745859222762), FX16_CONST(0.31804807738501506),
+ FX16_CONST(0.9485613499157303), FX16_CONST(0.31659337555616585),
+ FX16_CONST(0.9490458818527006), FX16_CONST(0.31513792875252244),
+ FX16_CONST(0.9495281805930367), FX16_CONST(0.3136817403988916),
+ FX16_CONST(0.950008245001843), FX16_CONST(0.31222481392182505),
+ FX16_CONST(0.9504860739494817), FX16_CONST(0.3107671527496115),
+ FX16_CONST(0.9509616663115751), FX16_CONST(0.3093087603122688),
+ FX16_CONST(0.9514350209690083), FX16_CONST(0.307849640041535),
+ FX16_CONST(0.9519061368079322), FX16_CONST(0.3063897953708611),
+ FX16_CONST(0.9523750127197659), FX16_CONST(0.30492922973540243),
+ FX16_CONST(0.9528416476011987), FX16_CONST(0.30346794657201137),
+ FX16_CONST(0.9533060403541938), FX16_CONST(0.3020059493192282),
+ FX16_CONST(0.9537681898859903), FX16_CONST(0.3005432414172734),
+ FX16_CONST(0.9542280951091057), FX16_CONST(0.2990798263080405),
+ FX16_CONST(0.9546857549413383), FX16_CONST(0.2976157074350863),
+ FX16_CONST(0.9551411683057707), FX16_CONST(0.29615088824362396),
+ FX16_CONST(0.9555943341307711), FX16_CONST(0.2946853721805143),
+ FX16_CONST(0.9560452513499964), FX16_CONST(0.2932191626942587),
+ FX16_CONST(0.956493918902395), FX16_CONST(0.2917522632349894),
+ FX16_CONST(0.9569403357322089), FX16_CONST(0.29028467725446233),
+ FX16_CONST(0.9573845007889759), FX16_CONST(0.2888164082060495),
+ FX16_CONST(0.9578264130275329), FX16_CONST(0.28734745954472957),
+ FX16_CONST(0.9582660714080177), FX16_CONST(0.2858778347270807),
+ FX16_CONST(0.9587034748958716), FX16_CONST(0.2844075372112718),
+ FX16_CONST(0.9591386224618419), FX16_CONST(0.2829365704570554),
+ FX16_CONST(0.9595715130819845), FX16_CONST(0.28146493792575805),
+ FX16_CONST(0.9600021457376658), FX16_CONST(0.2799926430802734),
+ FX16_CONST(0.9604305194155658), FX16_CONST(0.27851968938505306),
+ FX16_CONST(0.9608566331076797), FX16_CONST(0.27704608030609995),
+ FX16_CONST(0.9612804858113206), FX16_CONST(0.27557181931095825),
+ FX16_CONST(0.9617020765291225), FX16_CONST(0.27409690986870633),
+ FX16_CONST(0.9621214042690416), FX16_CONST(0.272621355449949),
+ FX16_CONST(0.9625384680443592), FX16_CONST(0.27114515952680807),
+ FX16_CONST(0.9629532668736839), FX16_CONST(0.2696683255729152),
+ FX16_CONST(0.963365799780954), FX16_CONST(0.2681908570634032),
+ FX16_CONST(0.9637760657954398), FX16_CONST(0.2667127574748984),
+ FX16_CONST(0.9641840639517457), FX16_CONST(0.2652340302855119),
+ FX16_CONST(0.9645897932898126), FX16_CONST(0.2637546789748315),
+ FX16_CONST(0.9649932528549203), FX16_CONST(0.2622747070239136),
+ FX16_CONST(0.9653944416976894), FX16_CONST(0.26079411791527557),
+ FX16_CONST(0.9657933588740836), FX16_CONST(0.25931291513288635),
+ FX16_CONST(0.9661900034454126), FX16_CONST(0.25783110216215893),
+ FX16_CONST(0.9665843744783331), FX16_CONST(0.2563486824899429),
+ FX16_CONST(0.9669764710448521), FX16_CONST(0.2548656596045146),
+ FX16_CONST(0.9673662922223285), FX16_CONST(0.25338203699557027),
+ FX16_CONST(0.9677538370934755), FX16_CONST(0.2518978181542169),
+ FX16_CONST(0.9681391047463624), FX16_CONST(0.2504130065729653),
+ FX16_CONST(0.9685220942744173), FX16_CONST(0.24892760574572026),
+ FX16_CONST(0.9689028047764289), FX16_CONST(0.24744161916777344),
+ FX16_CONST(0.9692812353565485), FX16_CONST(0.2459550503357946),
+ FX16_CONST(0.9696573851242924), FX16_CONST(0.2444679027478242),
+ FX16_CONST(0.970031253194544), FX16_CONST(0.24298017990326398),
+ FX16_CONST(0.9704028386875555), FX16_CONST(0.2414918853028693),
+ FX16_CONST(0.9707721407289504), FX16_CONST(0.2400030224487415),
+ FX16_CONST(0.9711391584497251), FX16_CONST(0.2385135948443185),
+ FX16_CONST(0.9715038909862518), FX16_CONST(0.23702360599436734),
+ FX16_CONST(0.9718663374802794), FX16_CONST(0.23553305940497546),
+ FX16_CONST(0.9722264970789363), FX16_CONST(0.23404195858354346),
+ FX16_CONST(0.9725843689347322), FX16_CONST(0.23255030703877533),
+ FX16_CONST(0.9729399522055601), FX16_CONST(0.23105810828067128),
+ FX16_CONST(0.9732932460546982), FX16_CONST(0.22956536582051887),
+ FX16_CONST(0.9736442496508119), FX16_CONST(0.2280720831708858),
+ FX16_CONST(0.9739929621679558), FX16_CONST(0.2265782638456101),
+ FX16_CONST(0.9743393827855759), FX16_CONST(0.22508391135979278),
+ FX16_CONST(0.9746835106885107), FX16_CONST(0.22358902922979002),
+ FX16_CONST(0.9750253450669941), FX16_CONST(0.2220936209732036),
+ FX16_CONST(0.9753648851166569), FX16_CONST(0.22059769010887365),
+ FX16_CONST(0.9757021300385286), FX16_CONST(0.21910124015686977),
+ FX16_CONST(0.976037079039039), FX16_CONST(0.21760427463848367),
+ FX16_CONST(0.9763697313300211), FX16_CONST(0.2161067970762196),
+ FX16_CONST(0.9767000861287118), FX16_CONST(0.21460881099378692),
+ FX16_CONST(0.9770281426577544), FX16_CONST(0.21311031991609136),
+ FX16_CONST(0.9773539001452), FX16_CONST(0.2116113273692276),
+ FX16_CONST(0.9776773578245099), FX16_CONST(0.21011183688046972),
+ FX16_CONST(0.9779985149345571), FX16_CONST(0.20861185197826346),
+ FX16_CONST(0.9783173707196277), FX16_CONST(0.20711137619221856),
+ FX16_CONST(0.9786339244294231), FX16_CONST(0.20561041305309932),
+ FX16_CONST(0.9789481753190622), FX16_CONST(0.204108966092817),
+ FX16_CONST(0.979260122649082), FX16_CONST(0.2026070388444211),
+ FX16_CONST(0.9795697656854405), FX16_CONST(0.20110463484209196),
+ FX16_CONST(0.9798771036995176), FX16_CONST(0.19960175762113105),
+ FX16_CONST(0.9801821359681173), FX16_CONST(0.19809841071795373),
+ FX16_CONST(0.9804848617734694), FX16_CONST(0.19659459767008022),
+ FX16_CONST(0.9807852804032304), FX16_CONST(0.19509032201612833),
+ FX16_CONST(0.9810833911504866), FX16_CONST(0.19358558729580375),
+ FX16_CONST(0.9813791933137546), FX16_CONST(0.19208039704989238),
+ FX16_CONST(0.9816726861969831), FX16_CONST(0.1905747548202528),
+ FX16_CONST(0.9819638691095552), FX16_CONST(0.18906866414980628),
+ FX16_CONST(0.9822527413662894), FX16_CONST(0.18756212858252974),
+ FX16_CONST(0.9825393022874412), FX16_CONST(0.18605515166344663),
+ FX16_CONST(0.9828235511987052), FX16_CONST(0.18454773693861964),
+ FX16_CONST(0.9831054874312163), FX16_CONST(0.18303988795514106),
+ FX16_CONST(0.9833851103215512), FX16_CONST(0.18153160826112513),
+ FX16_CONST(0.9836624192117303), FX16_CONST(0.18002290140569951),
+ FX16_CONST(0.9839374134492189), FX16_CONST(0.1785137709389976),
+ FX16_CONST(0.984210092386929), FX16_CONST(0.17700422041214886),
+ FX16_CONST(0.9844804553832209), FX16_CONST(0.1754942533772714),
+ FX16_CONST(0.9847485018019042), FX16_CONST(0.17398387338746385),
+ FX16_CONST(0.9850142310122398), FX16_CONST(0.17247308399679603),
+ FX16_CONST(0.9852776423889412), FX16_CONST(0.17096188876030136),
+ FX16_CONST(0.9855387353121761), FX16_CONST(0.16945029123396793),
+ FX16_CONST(0.9857975091675674), FX16_CONST(0.16793829497473123),
+ FX16_CONST(0.9860539633461954), FX16_CONST(0.16642590354046422),
+ FX16_CONST(0.9863080972445987), FX16_CONST(0.1649131204899701),
+ FX16_CONST(0.9865599102647754), FX16_CONST(0.16339994938297323),
+ FX16_CONST(0.9868094018141854), FX16_CONST(0.16188639378011188),
+ FX16_CONST(0.987056571305751), FX16_CONST(0.1603724572429284),
+ FX16_CONST(0.9873014181578584), FX16_CONST(0.1588581433338614),
+ FX16_CONST(0.9875439417943592), FX16_CONST(0.15734345561623828),
+ FX16_CONST(0.9877841416445722), FX16_CONST(0.15582839765426532),
+ FX16_CONST(0.9880220171432835), FX16_CONST(0.15431297301302024),
+ FX16_CONST(0.9882575677307495), FX16_CONST(0.1527971852584434),
+ FX16_CONST(0.9884907928526966), FX16_CONST(0.15128103795733025),
+ FX16_CONST(0.9887216919603238), FX16_CONST(0.14976453467732162),
+ FX16_CONST(0.988950264510303), FX16_CONST(0.1482476789868962),
+ FX16_CONST(0.989176509964781), FX16_CONST(0.14673047445536175),
+ FX16_CONST(0.9894004277913804), FX16_CONST(0.14521292465284752),
+ FX16_CONST(0.9896220174632008), FX16_CONST(0.14369503315029458),
+ FX16_CONST(0.9898412784588205), FX16_CONST(0.142176803519448),
+ FX16_CONST(0.9900582102622971), FX16_CONST(0.14065823933284924),
+ FX16_CONST(0.9902728123631691), FX16_CONST(0.13913934416382628),
+ FX16_CONST(0.990485084256457), FX16_CONST(0.13762012158648618),
+ FX16_CONST(0.9906950254426646), FX16_CONST(0.1361005751757062),
+ FX16_CONST(0.99090263542778), FX16_CONST(0.13458070850712622),
+ FX16_CONST(0.9911079137232768), FX16_CONST(0.13306052515713918),
+ FX16_CONST(0.9913108598461154), FX16_CONST(0.13154002870288328),
+ FX16_CONST(0.9915114733187439), FX16_CONST(0.13001922272223335),
+ FX16_CONST(0.9917097536690995), FX16_CONST(0.12849811079379322),
+ FX16_CONST(0.9919057004306093), FX16_CONST(0.12697669649688598),
+ FX16_CONST(0.9920993131421918), FX16_CONST(0.1254549834115462),
+ FX16_CONST(0.9922905913482574), FX16_CONST(0.1239329751185122),
+ FX16_CONST(0.99247953459871), FX16_CONST(0.12241067519921628),
+ FX16_CONST(0.992666142448948), FX16_CONST(0.12088808723577722),
+ FX16_CONST(0.9928504144598651), FX16_CONST(0.11936521481099135),
+ FX16_CONST(0.9930323501978514), FX16_CONST(0.11784206150832502),
+ FX16_CONST(0.9932119492347945), FX16_CONST(0.11631863091190488),
+ FX16_CONST(0.9933892111480807), FX16_CONST(0.11479492660651025),
+ FX16_CONST(0.9935641355205953), FX16_CONST(0.11327095217756436),
+ FX16_CONST(0.9937367219407246), FX16_CONST(0.11174671121112666),
+ FX16_CONST(0.9939069700023561), FX16_CONST(0.11022220729388318),
+ FX16_CONST(0.9940748793048794), FX16_CONST(0.10869744401313867),
+ FX16_CONST(0.9942404494531879), FX16_CONST(0.10717242495680887),
+ FX16_CONST(0.9944036800576791), FX16_CONST(0.1056471537134107),
+ FX16_CONST(0.9945645707342554), FX16_CONST(0.10412163387205473),
+ FX16_CONST(0.9947231211043257), FX16_CONST(0.10259586902243628),
+ FX16_CONST(0.9948793307948056), FX16_CONST(0.10106986275482788),
+ FX16_CONST(0.9950331994381186), FX16_CONST(0.09954361866006944),
+ FX16_CONST(0.9951847266721968), FX16_CONST(0.09801714032956077),
+ FX16_CONST(0.9953339121404823), FX16_CONST(0.0964904313552526),
+ FX16_CONST(0.9954807554919269), FX16_CONST(0.09496349532963906),
+ FX16_CONST(0.9956252563809943), FX16_CONST(0.09343633584574791),
+ FX16_CONST(0.9957674144676598), FX16_CONST(0.0919089564971327),
+ FX16_CONST(0.9959072294174117), FX16_CONST(0.09038136087786501),
+ FX16_CONST(0.996044700901252), FX16_CONST(0.08885355258252468),
+ FX16_CONST(0.9961798285956969), FX16_CONST(0.08732553520619223),
+ FX16_CONST(0.996312612182778), FX16_CONST(0.08579731234443988),
+ FX16_CONST(0.9964430513500426), FX16_CONST(0.08426888759332413),
+ FX16_CONST(0.9965711457905548), FX16_CONST(0.0827402645493758),
+ FX16_CONST(0.9966968952028961), FX16_CONST(0.08121144680959239),
+ FX16_CONST(0.9968202992911657), FX16_CONST(0.07968243797143013),
+ FX16_CONST(0.9969413577649822), FX16_CONST(0.07815324163279432),
+ FX16_CONST(0.997060070339483), FX16_CONST(0.07662386139203162),
+ FX16_CONST(0.9971764367353262), FX16_CONST(0.07509430084792129),
+ FX16_CONST(0.9972904566786902), FX16_CONST(0.07356456359966745),
+ FX16_CONST(0.9974021299012753), FX16_CONST(0.07203465324688942),
+ FX16_CONST(0.9975114561403035), FX16_CONST(0.07050457338961401),
+ FX16_CONST(0.9976184351385196), FX16_CONST(0.06897432762826673),
+ FX16_CONST(0.9977230666441916), FX16_CONST(0.0674439195636641),
+ FX16_CONST(0.9978253504111116), FX16_CONST(0.06591335279700393),
+ FX16_CONST(0.997925286198596), FX16_CONST(0.06438263092985741),
+ FX16_CONST(0.9980228737714862), FX16_CONST(0.06285175756416142),
+ FX16_CONST(0.9981181129001492), FX16_CONST(0.06132073630220865),
+ FX16_CONST(0.9982110033604782), FX16_CONST(0.05978957074664001),
+ FX16_CONST(0.9983015449338929), FX16_CONST(0.05825826450043573),
+ FX16_CONST(0.9983897374073402), FX16_CONST(0.05672682116690778),
+ FX16_CONST(0.9984755805732948), FX16_CONST(0.05519524434969003),
+ FX16_CONST(0.9985590742297593), FX16_CONST(0.05366353765273068),
+ FX16_CONST(0.9986402181802653), FX16_CONST(0.05213170468028332),
+ FX16_CONST(0.9987190122338729), FX16_CONST(0.05059974903689934),
+ FX16_CONST(0.9987954562051724), FX16_CONST(0.049067674327418126),
+ FX16_CONST(0.9988695499142836), FX16_CONST(0.04753548415695926),
+ FX16_CONST(0.9989412931868569), FX16_CONST(0.046003182130914644),
+ FX16_CONST(0.9990106858540734), FX16_CONST(0.044470771854938744),
+ FX16_CONST(0.9990777277526454), FX16_CONST(0.04293825693494096),
+ FX16_CONST(0.9991424187248169), FX16_CONST(0.04140564097707671),
+ FX16_CONST(0.9992047586183639), FX16_CONST(0.039872927587739845),
+ FX16_CONST(0.9992647472865944), FX16_CONST(0.03834012037355279),
+ FX16_CONST(0.9993223845883495), FX16_CONST(0.03680722294135899),
+ FX16_CONST(0.9993776703880028), FX16_CONST(0.03527423889821395),
+ FX16_CONST(0.9994306045554617), FX16_CONST(0.03374117185137764),
+ FX16_CONST(0.999481186966167), FX16_CONST(0.032208025408304704),
+ FX16_CONST(0.9995294175010931), FX16_CONST(0.03067480317663658),
+ FX16_CONST(0.9995752960467492), FX16_CONST(0.02914150876419374),
+ FX16_CONST(0.9996188224951786), FX16_CONST(0.02760814577896582),
+ FX16_CONST(0.9996599967439592), FX16_CONST(0.02607471782910404),
+ FX16_CONST(0.9996988186962042), FX16_CONST(0.024541228522912264),
+ FX16_CONST(0.9997352882605617), FX16_CONST(0.02300768146883941),
+ FX16_CONST(0.9997694053512153), FX16_CONST(0.021474080275469605),
+ FX16_CONST(0.9998011698878843), FX16_CONST(0.019940428551514598),
+ FX16_CONST(0.9998305817958234), FX16_CONST(0.01840672990580482),
+ FX16_CONST(0.9998576410058239), FX16_CONST(0.016872987947281773),
+ FX16_CONST(0.9998823474542126), FX16_CONST(0.01533920628498822),
+ FX16_CONST(0.9999047010828529), FX16_CONST(0.013805388528060349),
+ FX16_CONST(0.9999247018391445), FX16_CONST(0.012271538285719944),
+ FX16_CONST(0.9999423496760239), FX16_CONST(0.010737659167264572),
+ FX16_CONST(0.9999576445519639), FX16_CONST(0.00920375478205996),
+ FX16_CONST(0.9999705864309741), FX16_CONST(0.007669828739531077),
+ FX16_CONST(0.9999811752826011), FX16_CONST(0.006135884649154515),
+ FX16_CONST(0.9999894110819284), FX16_CONST(0.004601926120448672),
+ FX16_CONST(0.9999952938095762), FX16_CONST(0.003067956762966138),
+ FX16_CONST(0.9999988234517019), FX16_CONST(0.0015339801862847662),
+ FX16_CONST(1.0), FX16_CONST(6.123233995736766e-17),
+ FX16_CONST(0.9999988234517019), FX16_CONST(-0.0015339801862846436),
+ FX16_CONST(0.9999952938095762), FX16_CONST(-0.0030679567629660156),
+ FX16_CONST(0.9999894110819284), FX16_CONST(-0.00460192612044855),
+ FX16_CONST(0.9999811752826011), FX16_CONST(-0.006135884649154393),
+ FX16_CONST(0.9999705864309741), FX16_CONST(-0.007669828739530955),
+ FX16_CONST(0.9999576445519639), FX16_CONST(-0.009203754782059837),
+ FX16_CONST(0.9999423496760239), FX16_CONST(-0.010737659167264449),
+ FX16_CONST(0.9999247018391445), FX16_CONST(-0.012271538285719823),
+ FX16_CONST(0.9999047010828529), FX16_CONST(-0.013805388528060226),
+ FX16_CONST(0.9998823474542126), FX16_CONST(-0.015339206284988098),
+ FX16_CONST(0.9998576410058239), FX16_CONST(-0.01687298794728165),
+ FX16_CONST(0.9998305817958234), FX16_CONST(-0.018406729905804695),
+ FX16_CONST(0.9998011698878843), FX16_CONST(-0.019940428551514476),
+ FX16_CONST(0.9997694053512153), FX16_CONST(-0.021474080275469484),
+ FX16_CONST(0.9997352882605617), FX16_CONST(-0.02300768146883929),
+ FX16_CONST(0.9996988186962042), FX16_CONST(-0.024541228522912142),
+ FX16_CONST(0.9996599967439592), FX16_CONST(-0.026074717829103915),
+ FX16_CONST(0.9996188224951786), FX16_CONST(-0.027608145778965698),
+ FX16_CONST(0.9995752960467492), FX16_CONST(-0.029141508764193618),
+ FX16_CONST(0.9995294175010931), FX16_CONST(-0.03067480317663646),
+ FX16_CONST(0.999481186966167), FX16_CONST(-0.03220802540830458),
+ FX16_CONST(0.9994306045554617), FX16_CONST(-0.03374117185137752),
+ FX16_CONST(0.9993776703880028), FX16_CONST(-0.03527423889821382),
+ FX16_CONST(0.9993223845883495), FX16_CONST(-0.036807222941358866),
+ FX16_CONST(0.9992647472865944), FX16_CONST(-0.038340120373552666),
+ FX16_CONST(0.9992047586183639), FX16_CONST(-0.03987292758773973),
+ FX16_CONST(0.9991424187248169), FX16_CONST(-0.041405640977076594),
+ FX16_CONST(0.9990777277526454), FX16_CONST(-0.042938256934940834),
+ FX16_CONST(0.9990106858540734), FX16_CONST(-0.04447077185493862),
+ FX16_CONST(0.9989412931868569), FX16_CONST(-0.04600318213091452),
+ FX16_CONST(0.9988695499142836), FX16_CONST(-0.047535484156959136),
+ FX16_CONST(0.9987954562051724), FX16_CONST(-0.04906767432741801),
+ FX16_CONST(0.9987190122338729), FX16_CONST(-0.05059974903689921),
+ FX16_CONST(0.9986402181802653), FX16_CONST(-0.05213170468028319),
+ FX16_CONST(0.9985590742297593), FX16_CONST(-0.053663537652730554),
+ FX16_CONST(0.9984755805732948), FX16_CONST(-0.05519524434968991),
+ FX16_CONST(0.9983897374073402), FX16_CONST(-0.05672682116690766),
+ FX16_CONST(0.9983015449338929), FX16_CONST(-0.05825826450043561),
+ FX16_CONST(0.9982110033604782), FX16_CONST(-0.05978957074663988),
+ FX16_CONST(0.9981181129001492), FX16_CONST(-0.06132073630220853),
+ FX16_CONST(0.9980228737714862), FX16_CONST(-0.06285175756416131),
+ FX16_CONST(0.997925286198596), FX16_CONST(-0.06438263092985728),
+ FX16_CONST(0.9978253504111116), FX16_CONST(-0.0659133527970038),
+ FX16_CONST(0.9977230666441916), FX16_CONST(-0.06744391956366398),
+ FX16_CONST(0.9976184351385196), FX16_CONST(-0.06897432762826661),
+ FX16_CONST(0.9975114561403035), FX16_CONST(-0.0705045733896139),
+ FX16_CONST(0.9974021299012753), FX16_CONST(-0.07203465324688929),
+ FX16_CONST(0.9972904566786902), FX16_CONST(-0.07356456359966733),
+ FX16_CONST(0.9971764367353262), FX16_CONST(-0.07509430084792117),
+ FX16_CONST(0.997060070339483), FX16_CONST(-0.0766238613920315),
+ FX16_CONST(0.9969413577649822), FX16_CONST(-0.07815324163279419),
+ FX16_CONST(0.9968202992911658), FX16_CONST(-0.07968243797143001),
+ FX16_CONST(0.9966968952028961), FX16_CONST(-0.08121144680959226),
+ FX16_CONST(0.9965711457905548), FX16_CONST(-0.08274026454937568),
+ FX16_CONST(0.9964430513500426), FX16_CONST(-0.084268887593324),
+ FX16_CONST(0.996312612182778), FX16_CONST(-0.08579731234443976),
+ FX16_CONST(0.9961798285956969), FX16_CONST(-0.0873255352061921),
+ FX16_CONST(0.996044700901252), FX16_CONST(-0.08885355258252456),
+ FX16_CONST(0.9959072294174117), FX16_CONST(-0.09038136087786489),
+ FX16_CONST(0.9957674144676598), FX16_CONST(-0.09190895649713257),
+ FX16_CONST(0.9956252563809943), FX16_CONST(-0.09343633584574779),
+ FX16_CONST(0.9954807554919269), FX16_CONST(-0.09496349532963895),
+ FX16_CONST(0.9953339121404823), FX16_CONST(-0.09649043135525248),
+ FX16_CONST(0.9951847266721969), FX16_CONST(-0.09801714032956065),
+ FX16_CONST(0.9950331994381186), FX16_CONST(-0.09954361866006932),
+ FX16_CONST(0.9948793307948056), FX16_CONST(-0.10106986275482775),
+ FX16_CONST(0.9947231211043257), FX16_CONST(-0.10259586902243616),
+ FX16_CONST(0.9945645707342554), FX16_CONST(-0.1041216338720546),
+ FX16_CONST(0.9944036800576791), FX16_CONST(-0.10564715371341057),
+ FX16_CONST(0.9942404494531879), FX16_CONST(-0.10717242495680876),
+ FX16_CONST(0.9940748793048795), FX16_CONST(-0.10869744401313856),
+ FX16_CONST(0.9939069700023561), FX16_CONST(-0.11022220729388306),
+ FX16_CONST(0.9937367219407246), FX16_CONST(-0.11174671121112655),
+ FX16_CONST(0.9935641355205953), FX16_CONST(-0.11327095217756424),
+ FX16_CONST(0.9933892111480807), FX16_CONST(-0.11479492660651013),
+ FX16_CONST(0.9932119492347945), FX16_CONST(-0.11631863091190475),
+ FX16_CONST(0.9930323501978514), FX16_CONST(-0.1178420615083249),
+ FX16_CONST(0.9928504144598651), FX16_CONST(-0.11936521481099123),
+ FX16_CONST(0.992666142448948), FX16_CONST(-0.1208880872357771),
+ FX16_CONST(0.99247953459871), FX16_CONST(-0.12241067519921615),
+ FX16_CONST(0.9922905913482574), FX16_CONST(-0.12393297511851208),
+ FX16_CONST(0.9920993131421918), FX16_CONST(-0.12545498341154607),
+ FX16_CONST(0.9919057004306093), FX16_CONST(-0.12697669649688587),
+ FX16_CONST(0.9917097536690995), FX16_CONST(-0.1284981107937931),
+ FX16_CONST(0.991511473318744), FX16_CONST(-0.13001922272223324),
+ FX16_CONST(0.9913108598461154), FX16_CONST(-0.13154002870288314),
+ FX16_CONST(0.9911079137232769), FX16_CONST(-0.13306052515713904),
+ FX16_CONST(0.99090263542778), FX16_CONST(-0.1345807085071261),
+ FX16_CONST(0.9906950254426646), FX16_CONST(-0.13610057517570606),
+ FX16_CONST(0.990485084256457), FX16_CONST(-0.13762012158648607),
+ FX16_CONST(0.9902728123631691), FX16_CONST(-0.13913934416382617),
+ FX16_CONST(0.9900582102622971), FX16_CONST(-0.14065823933284913),
+ FX16_CONST(0.9898412784588205), FX16_CONST(-0.1421768035194479),
+ FX16_CONST(0.9896220174632009), FX16_CONST(-0.14369503315029444),
+ FX16_CONST(0.9894004277913804), FX16_CONST(-0.1452129246528474),
+ FX16_CONST(0.989176509964781), FX16_CONST(-0.14673047445536164),
+ FX16_CONST(0.988950264510303), FX16_CONST(-0.1482476789868961),
+ FX16_CONST(0.9887216919603238), FX16_CONST(-0.1497645346773215),
+ FX16_CONST(0.9884907928526967), FX16_CONST(-0.15128103795733014),
+ FX16_CONST(0.9882575677307495), FX16_CONST(-0.1527971852584433),
+ FX16_CONST(0.9880220171432835), FX16_CONST(-0.15431297301302013),
+ FX16_CONST(0.9877841416445722), FX16_CONST(-0.1558283976542652),
+ FX16_CONST(0.9875439417943593), FX16_CONST(-0.15734345561623816),
+ FX16_CONST(0.9873014181578584), FX16_CONST(-0.15885814333386128),
+ FX16_CONST(0.987056571305751), FX16_CONST(-0.16037245724292826),
+ FX16_CONST(0.9868094018141855), FX16_CONST(-0.16188639378011177),
+ FX16_CONST(0.9865599102647755), FX16_CONST(-0.16339994938297311),
+ FX16_CONST(0.9863080972445987), FX16_CONST(-0.16491312048996995),
+ FX16_CONST(0.9860539633461954), FX16_CONST(-0.1664259035404641),
+ FX16_CONST(0.9857975091675675), FX16_CONST(-0.1679382949747311),
+ FX16_CONST(0.9855387353121761), FX16_CONST(-0.16945029123396782),
+ FX16_CONST(0.9852776423889412), FX16_CONST(-0.17096188876030124),
+ FX16_CONST(0.9850142310122398), FX16_CONST(-0.17247308399679592),
+ FX16_CONST(0.9847485018019042), FX16_CONST(-0.1739838733874637),
+ FX16_CONST(0.9844804553832209), FX16_CONST(-0.17549425337727126),
+ FX16_CONST(0.984210092386929), FX16_CONST(-0.17700422041214875),
+ FX16_CONST(0.9839374134492189), FX16_CONST(-0.17851377093899745),
+ FX16_CONST(0.9836624192117303), FX16_CONST(-0.1800229014056994),
+ FX16_CONST(0.9833851103215512), FX16_CONST(-0.18153160826112502),
+ FX16_CONST(0.9831054874312163), FX16_CONST(-0.18303988795514092),
+ FX16_CONST(0.9828235511987053), FX16_CONST(-0.18454773693861953),
+ FX16_CONST(0.9825393022874412), FX16_CONST(-0.1860551516634465),
+ FX16_CONST(0.9822527413662894), FX16_CONST(-0.1875621285825296),
+ FX16_CONST(0.9819638691095552), FX16_CONST(-0.18906866414980616),
+ FX16_CONST(0.9816726861969831), FX16_CONST(-0.19057475482025266),
+ FX16_CONST(0.9813791933137546), FX16_CONST(-0.19208039704989227),
+ FX16_CONST(0.9810833911504867), FX16_CONST(-0.1935855872958036),
+ FX16_CONST(0.9807852804032304), FX16_CONST(-0.1950903220161282),
+ FX16_CONST(0.9804848617734694), FX16_CONST(-0.1965945976700801),
+ FX16_CONST(0.9801821359681174), FX16_CONST(-0.19809841071795362),
+ FX16_CONST(0.9798771036995176), FX16_CONST(-0.19960175762113094),
+ FX16_CONST(0.9795697656854405), FX16_CONST(-0.20110463484209182),
+ FX16_CONST(0.9792601226490821), FX16_CONST(-0.20260703884442097),
+ FX16_CONST(0.9789481753190622), FX16_CONST(-0.2041089660928169),
+ FX16_CONST(0.9786339244294232), FX16_CONST(-0.2056104130530992),
+ FX16_CONST(0.9783173707196277), FX16_CONST(-0.20711137619221845),
+ FX16_CONST(0.9779985149345571), FX16_CONST(-0.20861185197826332),
+ FX16_CONST(0.9776773578245099), FX16_CONST(-0.2101118368804696),
+ FX16_CONST(0.9773539001452001), FX16_CONST(-0.2116113273692275),
+ FX16_CONST(0.9770281426577544), FX16_CONST(-0.21311031991609125),
+ FX16_CONST(0.9767000861287118), FX16_CONST(-0.2146088109937868),
+ FX16_CONST(0.9763697313300211), FX16_CONST(-0.2161067970762195),
+ FX16_CONST(0.9760370790390391), FX16_CONST(-0.21760427463848356),
+ FX16_CONST(0.9757021300385286), FX16_CONST(-0.21910124015686966),
+ FX16_CONST(0.975364885116657), FX16_CONST(-0.22059769010887353),
+ FX16_CONST(0.9750253450669941), FX16_CONST(-0.22209362097320348),
+ FX16_CONST(0.9746835106885107), FX16_CONST(-0.22358902922978988),
+ FX16_CONST(0.9743393827855759), FX16_CONST(-0.22508391135979267),
+ FX16_CONST(0.9739929621679558), FX16_CONST(-0.22657826384560997),
+ FX16_CONST(0.973644249650812), FX16_CONST(-0.22807208317088568),
+ FX16_CONST(0.9732932460546982), FX16_CONST(-0.22956536582051876),
+ FX16_CONST(0.9729399522055602), FX16_CONST(-0.23105810828067114),
+ FX16_CONST(0.9725843689347322), FX16_CONST(-0.23255030703877522),
+ FX16_CONST(0.9722264970789364), FX16_CONST(-0.23404195858354332),
+ FX16_CONST(0.9718663374802794), FX16_CONST(-0.23553305940497535),
+ FX16_CONST(0.9715038909862518), FX16_CONST(-0.23702360599436723),
+ FX16_CONST(0.9711391584497251), FX16_CONST(-0.2385135948443184),
+ FX16_CONST(0.9707721407289504), FX16_CONST(-0.2400030224487414),
+ FX16_CONST(0.9704028386875555), FX16_CONST(-0.24149188530286916),
+ FX16_CONST(0.970031253194544), FX16_CONST(-0.24298017990326387),
+ FX16_CONST(0.9696573851242924), FX16_CONST(-0.2444679027478241),
+ FX16_CONST(0.9692812353565485), FX16_CONST(-0.24595505033579448),
+ FX16_CONST(0.9689028047764289), FX16_CONST(-0.24744161916777332),
+ FX16_CONST(0.9685220942744174), FX16_CONST(-0.24892760574572012),
+ FX16_CONST(0.9681391047463624), FX16_CONST(-0.25041300657296517),
+ FX16_CONST(0.9677538370934755), FX16_CONST(-0.2518978181542168),
+ FX16_CONST(0.9673662922223285), FX16_CONST(-0.25338203699557016),
+ FX16_CONST(0.9669764710448521), FX16_CONST(-0.2548656596045145),
+ FX16_CONST(0.9665843744783331), FX16_CONST(-0.25634868248994275),
+ FX16_CONST(0.9661900034454126), FX16_CONST(-0.2578311021621588),
+ FX16_CONST(0.9657933588740837), FX16_CONST(-0.25931291513288623),
+ FX16_CONST(0.9653944416976894), FX16_CONST(-0.26079411791527546),
+ FX16_CONST(0.9649932528549204), FX16_CONST(-0.2622747070239135),
+ FX16_CONST(0.9645897932898128), FX16_CONST(-0.2637546789748314),
+ FX16_CONST(0.9641840639517458), FX16_CONST(-0.2652340302855118),
+ FX16_CONST(0.9637760657954398), FX16_CONST(-0.2667127574748983),
+ FX16_CONST(0.963365799780954), FX16_CONST(-0.268190857063403),
+ FX16_CONST(0.9629532668736839), FX16_CONST(-0.2696683255729151),
+ FX16_CONST(0.9625384680443592), FX16_CONST(-0.27114515952680796),
+ FX16_CONST(0.9621214042690416), FX16_CONST(-0.27262135544994887),
+ FX16_CONST(0.9617020765291225), FX16_CONST(-0.2740969098687062),
+ FX16_CONST(0.9612804858113206), FX16_CONST(-0.27557181931095814),
+ FX16_CONST(0.9608566331076797), FX16_CONST(-0.27704608030609984),
+ FX16_CONST(0.9604305194155659), FX16_CONST(-0.27851968938505295),
+ FX16_CONST(0.9600021457376658), FX16_CONST(-0.2799926430802733),
+ FX16_CONST(0.9595715130819845), FX16_CONST(-0.28146493792575794),
+ FX16_CONST(0.959138622461842), FX16_CONST(-0.2829365704570553),
+ FX16_CONST(0.9587034748958716), FX16_CONST(-0.2844075372112717),
+ FX16_CONST(0.9582660714080177), FX16_CONST(-0.2858778347270806),
+ FX16_CONST(0.9578264130275329), FX16_CONST(-0.28734745954472946),
+ FX16_CONST(0.957384500788976), FX16_CONST(-0.28881640820604937),
+ FX16_CONST(0.9569403357322089), FX16_CONST(-0.29028467725446216),
+ FX16_CONST(0.9564939189023951), FX16_CONST(-0.29175226323498926),
+ FX16_CONST(0.9560452513499965), FX16_CONST(-0.2932191626942586),
+ FX16_CONST(0.9555943341307711), FX16_CONST(-0.2946853721805142),
+ FX16_CONST(0.9551411683057707), FX16_CONST(-0.29615088824362384),
+ FX16_CONST(0.9546857549413383), FX16_CONST(-0.2976157074350862),
+ FX16_CONST(0.9542280951091057), FX16_CONST(-0.29907982630804036),
+ FX16_CONST(0.9537681898859903), FX16_CONST(-0.3005432414172733),
+ FX16_CONST(0.9533060403541939), FX16_CONST(-0.3020059493192281),
+ FX16_CONST(0.9528416476011987), FX16_CONST(-0.30346794657201126),
+ FX16_CONST(0.9523750127197659), FX16_CONST(-0.30492922973540226),
+ FX16_CONST(0.9519061368079323), FX16_CONST(-0.306389795370861),
+ FX16_CONST(0.9514350209690083), FX16_CONST(-0.30784964004153487),
+ FX16_CONST(0.9509616663115751), FX16_CONST(-0.3093087603122686),
+ FX16_CONST(0.9504860739494818), FX16_CONST(-0.31076715274961136),
+ FX16_CONST(0.950008245001843), FX16_CONST(-0.31222481392182494),
+ FX16_CONST(0.9495281805930367), FX16_CONST(-0.3136817403988914),
+ FX16_CONST(0.9490458818527006), FX16_CONST(-0.31513792875252233),
+ FX16_CONST(0.9485613499157304), FX16_CONST(-0.31659337555616573),
+ FX16_CONST(0.9480745859222762), FX16_CONST(-0.31804807738501495),
+ FX16_CONST(0.9475855910177412), FX16_CONST(-0.31950203081601564),
+ FX16_CONST(0.9470943663527772), FX16_CONST(-0.3209552324278751),
+ FX16_CONST(0.9466009130832835), FX16_CONST(-0.32240767880106985),
+ FX16_CONST(0.9461052323704034), FX16_CONST(-0.32385936651785285),
+ FX16_CONST(0.9456073253805214), FX16_CONST(-0.32531029216226287),
+ FX16_CONST(0.9451071932852606), FX16_CONST(-0.3267604523201316),
+ FX16_CONST(0.9446048372614803), FX16_CONST(-0.32820984357909255),
+ FX16_CONST(0.9441002584912727), FX16_CONST(-0.32965846252858744),
+ FX16_CONST(0.9435934581619604), FX16_CONST(-0.3311063057598763),
+ FX16_CONST(0.9430844374660935), FX16_CONST(-0.33255336986604406),
+ FX16_CONST(0.9425731976014469), FX16_CONST(-0.3339996514420094),
+ FX16_CONST(0.9420597397710174), FX16_CONST(-0.33544514708453155),
+ FX16_CONST(0.9415440651830208), FX16_CONST(-0.33688985339221994),
+ FX16_CONST(0.9410261750508893), FX16_CONST(-0.3383337669655412),
+ FX16_CONST(0.9405060705932683), FX16_CONST(-0.33977688440682685),
+ FX16_CONST(0.939983753034014), FX16_CONST(-0.3412192023202823),
+ FX16_CONST(0.9394592236021899), FX16_CONST(-0.34266071731199427),
+ FX16_CONST(0.9389324835320645), FX16_CONST(-0.34410142598993887),
+ FX16_CONST(0.9384035340631082), FX16_CONST(-0.34554132496398904),
+ FX16_CONST(0.9378723764399899), FX16_CONST(-0.34698041084592357),
+ FX16_CONST(0.937339011912575), FX16_CONST(-0.3484186802494344),
+ FX16_CONST(0.9368034417359216), FX16_CONST(-0.3498561297901349),
+ FX16_CONST(0.9362656671702783), FX16_CONST(-0.35129275608556704),
+ FX16_CONST(0.9357256894810804), FX16_CONST(-0.3527285557552106),
+ FX16_CONST(0.9351835099389476), FX16_CONST(-0.3541635254204904),
+ FX16_CONST(0.9346391298196808), FX16_CONST(-0.35559766170478385),
+ FX16_CONST(0.934092550404259), FX16_CONST(-0.3570309612334299),
+ FX16_CONST(0.9335437729788363), FX16_CONST(-0.35846342063373643),
+ FX16_CONST(0.9329927988347388), FX16_CONST(-0.35989503653498817),
+ FX16_CONST(0.9324396292684624), FX16_CONST(-0.36132580556845423),
+ FX16_CONST(0.9318842655816681), FX16_CONST(-0.3627557243673971),
+ FX16_CONST(0.9313267090811805), FX16_CONST(-0.3641847895670797),
+ FX16_CONST(0.9307669610789837), FX16_CONST(-0.36561299780477385),
+ FX16_CONST(0.9302050228922191), FX16_CONST(-0.3670403457197671),
+ FX16_CONST(0.9296408958431813), FX16_CONST(-0.3684668299533722),
+ FX16_CONST(0.9290745812593157), FX16_CONST(-0.36989244714893416),
+ FX16_CONST(0.9285060804732156), FX16_CONST(-0.3713171939518375),
+ FX16_CONST(0.9279353948226179), FX16_CONST(-0.3727410670095157),
+ FX16_CONST(0.9273625256504011), FX16_CONST(-0.3741640629714579),
+ FX16_CONST(0.9267874743045817), FX16_CONST(-0.3755861784892172),
+ FX16_CONST(0.9262102421383114), FX16_CONST(-0.3770074102164182),
+ FX16_CONST(0.9256308305098728), FX16_CONST(-0.37842775480876545),
+ FX16_CONST(0.9250492407826777), FX16_CONST(-0.379847208924051),
+ FX16_CONST(0.9244654743252626), FX16_CONST(-0.3812657692221624),
+ FX16_CONST(0.9238795325112867), FX16_CONST(-0.3826834323650897),
+ FX16_CONST(0.9232914167195277), FX16_CONST(-0.38410019501693493),
+ FX16_CONST(0.9227011283338785), FX16_CONST(-0.3855160538439189),
+ FX16_CONST(0.9221086687433452), FX16_CONST(-0.3869310055143886),
+ FX16_CONST(0.921514039342042), FX16_CONST(-0.3883450466988262),
+ FX16_CONST(0.9209172415291895), FX16_CONST(-0.3897581740698563),
+ FX16_CONST(0.9203182767091106), FX16_CONST(-0.39117038430225387),
+ FX16_CONST(0.9197171462912274), FX16_CONST(-0.3925816740729514),
+ FX16_CONST(0.9191138516900578), FX16_CONST(-0.393992040061048),
+ FX16_CONST(0.9185083943252123), FX16_CONST(-0.3954014789478162),
+ FX16_CONST(0.9179007756213905), FX16_CONST(-0.3968099874167103),
+ FX16_CONST(0.917290997008378), FX16_CONST(-0.3982175621533735),
+ FX16_CONST(0.9166790599210427), FX16_CONST(-0.3996241998456467),
+ FX16_CONST(0.9160649657993317), FX16_CONST(-0.4010298971835757),
+ FX16_CONST(0.9154487160882678), FX16_CONST(-0.40243465085941843),
+ FX16_CONST(0.9148303122379462), FX16_CONST(-0.403838457567654),
+ FX16_CONST(0.9142097557035307), FX16_CONST(-0.40524131400498975),
+ FX16_CONST(0.9135870479452508), FX16_CONST(-0.40664321687036903),
+ FX16_CONST(0.9129621904283982), FX16_CONST(-0.40804416286497863),
+ FX16_CONST(0.9123351846233229), FX16_CONST(-0.40944414869225754),
+ FX16_CONST(0.9117060320054299), FX16_CONST(-0.4108431710579038),
+ FX16_CONST(0.9110747340551764), FX16_CONST(-0.4122412266698829),
+ FX16_CONST(0.9104412922580672), FX16_CONST(-0.4136383122384345),
+ FX16_CONST(0.9098057081046523), FX16_CONST(-0.4150344244760815),
+ FX16_CONST(0.9091679830905225), FX16_CONST(-0.416429560097637),
+ FX16_CONST(0.9085281187163061), FX16_CONST(-0.41782371582021227),
+ FX16_CONST(0.9078861164876662), FX16_CONST(-0.41921688836322407),
+ FX16_CONST(0.9072419779152959), FX16_CONST(-0.4206090744484024),
+ FX16_CONST(0.9065957045149153), FX16_CONST(-0.4220002707997997),
+ FX16_CONST(0.9059472978072686), FX16_CONST(-0.42339047414379577),
+ FX16_CONST(0.9052967593181188), FX16_CONST(-0.4247796812091087),
+ FX16_CONST(0.9046440905782461), FX16_CONST(-0.42616788872679967),
+ FX16_CONST(0.9039892931234434), FX16_CONST(-0.42755509343028186),
+ FX16_CONST(0.9033323684945118), FX16_CONST(-0.42894129205532944),
+ FX16_CONST(0.9026733182372587), FX16_CONST(-0.4303264813400827),
+ FX16_CONST(0.9020121439024933), FX16_CONST(-0.4317106580250571),
+ FX16_CONST(0.901348847046022), FX16_CONST(-0.4330938188531519),
+ FX16_CONST(0.9006834292286469), FX16_CONST(-0.4344759605696558),
+ FX16_CONST(0.9000158920161603), FX16_CONST(-0.43585707992225536),
+ FX16_CONST(0.8993462369793416), FX16_CONST(-0.4372371736610441),
+ FX16_CONST(0.8986744656939539), FX16_CONST(-0.4386162385385274),
+ FX16_CONST(0.8980005797407399), FX16_CONST(-0.43999427130963314),
+ FX16_CONST(0.8973245807054183), FX16_CONST(-0.4413712687317167),
+ FX16_CONST(0.8966464701786803), FX16_CONST(-0.4427472275645698),
+ FX16_CONST(0.8959662497561852), FX16_CONST(-0.44412214457042914),
+ FX16_CONST(0.8952839210385575), FX16_CONST(-0.4454960165139818),
+ FX16_CONST(0.8945994856313828), FX16_CONST(-0.446868840162374),
+ FX16_CONST(0.8939129451452033), FX16_CONST(-0.4482406122852199),
+ FX16_CONST(0.8932243011955152), FX16_CONST(-0.4496113296546067),
+ FX16_CONST(0.8925335554027647), FX16_CONST(-0.4509809890451037),
+ FX16_CONST(0.8918407093923427), FX16_CONST(-0.4523495872337709),
+ FX16_CONST(0.8911457647945834), FX16_CONST(-0.4537171210001636),
+ FX16_CONST(0.890448723244758), FX16_CONST(-0.4550835871263437),
+ FX16_CONST(0.8897495863830728), FX16_CONST(-0.456448982396884),
+ FX16_CONST(0.8890483558546647), FX16_CONST(-0.457813303598877),
+ FX16_CONST(0.8883450333095964), FX16_CONST(-0.45917654752194403),
+ FX16_CONST(0.8876396204028539), FX16_CONST(-0.46053871095824006),
+ FX16_CONST(0.8869321187943423), FX16_CONST(-0.46189979070246256),
+ FX16_CONST(0.8862225301488806), FX16_CONST(-0.46325978355186015),
+ FX16_CONST(0.8855108561361998), FX16_CONST(-0.4646186863062379),
+ FX16_CONST(0.8847970984309379), FX16_CONST(-0.465976495767966),
+ FX16_CONST(0.884081258712635), FX16_CONST(-0.4673332087419884),
+ FX16_CONST(0.8833633386657317), FX16_CONST(-0.4686888220358277),
+ FX16_CONST(0.8826433399795628), FX16_CONST(-0.4700433324595955),
+ FX16_CONST(0.881921264348355), FX16_CONST(-0.4713967368259977),
+ FX16_CONST(0.8811971134712222), FX16_CONST(-0.47274903195034257),
+ FX16_CONST(0.8804708890521609), FX16_CONST(-0.4741002146505499),
+ FX16_CONST(0.8797425928000474), FX16_CONST(-0.4754502817471559),
+ FX16_CONST(0.8790122264286335), FX16_CONST(-0.4767992300633219),
+ FX16_CONST(0.8782797916565416), FX16_CONST(-0.478147056424843),
+ FX16_CONST(0.8775452902072612), FX16_CONST(-0.4794937576601531),
+ FX16_CONST(0.8768087238091458), FX16_CONST(-0.4808393306003338),
+ FX16_CONST(0.8760700941954066), FX16_CONST(-0.4821837720791227),
+ FX16_CONST(0.875329403104111), FX16_CONST(-0.48352707893291846),
+ FX16_CONST(0.8745866522781762), FX16_CONST(-0.484869248000791),
+ FX16_CONST(0.8738418434653668), FX16_CONST(-0.4862102761244864),
+ FX16_CONST(0.8730949784182902), FX16_CONST(-0.4875501601484357),
+ FX16_CONST(0.8723460588943915), FX16_CONST(-0.4888888969197631),
+ FX16_CONST(0.871595086655951), FX16_CONST(-0.4902264832882912),
+ FX16_CONST(0.870842063470079), FX16_CONST(-0.49156291610654973),
+ FX16_CONST(0.8700869911087115), FX16_CONST(-0.492898192229784),
+ FX16_CONST(0.8693298713486067), FX16_CONST(-0.49423230851595984),
+ FX16_CONST(0.868570705971341), FX16_CONST(-0.4955652618257724),
+ FX16_CONST(0.8678094967633032), FX16_CONST(-0.4968970490226545),
+ FX16_CONST(0.8670462455156928), FX16_CONST(-0.4982276669727816),
+ FX16_CONST(0.8662809540245131), FX16_CONST(-0.4995571125450818),
+ FX16_CONST(0.8655136240905691), FX16_CONST(-0.5008853826112408),
+ FX16_CONST(0.8647442575194625), FX16_CONST(-0.5022124740457106),
+ FX16_CONST(0.8639728561215868), FX16_CONST(-0.5035383837257175),
+ FX16_CONST(0.8631994217121242), FX16_CONST(-0.5048631085312676),
+ FX16_CONST(0.8624239561110406), FX16_CONST(-0.5061866453451551),
+ FX16_CONST(0.8616464611430814), FX16_CONST(-0.5075089910529708),
+ FX16_CONST(0.8608669386377672), FX16_CONST(-0.5088301425431071),
+ FX16_CONST(0.8600853904293903), FX16_CONST(-0.5101500967067666),
+ FX16_CONST(0.8593018183570085), FX16_CONST(-0.5114688504379704),
+ FX16_CONST(0.858516224264443), FX16_CONST(-0.5127864006335627),
+ FX16_CONST(0.8577286100002721), FX16_CONST(-0.5141027441932216),
+ FX16_CONST(0.8569389774178287), FX16_CONST(-0.515417878019463),
+ FX16_CONST(0.8561473283751946), FX16_CONST(-0.5167317990176497),
+ FX16_CONST(0.855353664735196), FX16_CONST(-0.5180445040959992),
+ FX16_CONST(0.8545579883654005), FX16_CONST(-0.5193559901655896),
+ FX16_CONST(0.8537603011381115), FX16_CONST(-0.5206662541403669),
+ FX16_CONST(0.8529606049303637), FX16_CONST(-0.5219752929371543),
+ FX16_CONST(0.8521589016239197), FX16_CONST(-0.5232831034756565),
+ FX16_CONST(0.8513551931052652), FX16_CONST(-0.5245896826784687),
+ FX16_CONST(0.8505494812656035), FX16_CONST(-0.5258950274710846),
+ FX16_CONST(0.8497417680008527), FX16_CONST(-0.5271991347819011),
+ FX16_CONST(0.8489320552116397), FX16_CONST(-0.5285020015422284),
+ FX16_CONST(0.8481203448032972), FX16_CONST(-0.5298036246862947),
+ FX16_CONST(0.8473066386858585), FX16_CONST(-0.5311040011512548),
+ FX16_CONST(0.8464909387740521), FX16_CONST(-0.5324031278771979),
+ FX16_CONST(0.8456732469872991), FX16_CONST(-0.533701001807153),
+ FX16_CONST(0.8448535652497072), FX16_CONST(-0.534997619887097),
+ FX16_CONST(0.8440318954900664), FX16_CONST(-0.5362929790659631),
+ FX16_CONST(0.8432082396418453), FX16_CONST(-0.5375870762956456),
+ FX16_CONST(0.842382599643186), FX16_CONST(-0.5388799085310083),
+ FX16_CONST(0.8415549774368984), FX16_CONST(-0.5401714727298929),
+ FX16_CONST(0.8407253749704582), FX16_CONST(-0.5414617658531232),
+ FX16_CONST(0.8398937941959995), FX16_CONST(-0.5427507848645158),
+ FX16_CONST(0.8390602370703127), FX16_CONST(-0.5440385267308839),
+ FX16_CONST(0.8382247055548382), FX16_CONST(-0.5453249884220462),
+ FX16_CONST(0.8373872016156619), FX16_CONST(-0.5466101669108347),
+ FX16_CONST(0.836547727223512), FX16_CONST(-0.5478940591731002),
+ FX16_CONST(0.8357062843537527), FX16_CONST(-0.5491766621877195),
+ FX16_CONST(0.8348628749863801), FX16_CONST(-0.5504579729366047),
+ FX16_CONST(0.834017501106018), FX16_CONST(-0.5517379884047074),
+ FX16_CONST(0.8331701647019133), FX16_CONST(-0.5530167055800274),
+ FX16_CONST(0.8323208677679297), FX16_CONST(-0.5542941214536201),
+ FX16_CONST(0.8314696123025453), FX16_CONST(-0.555570233019602),
+ FX16_CONST(0.8306164003088463), FX16_CONST(-0.55684503727516),
+ FX16_CONST(0.829761233794523), FX16_CONST(-0.5581185312205561),
+ FX16_CONST(0.8289041147718651), FX16_CONST(-0.5593907118591358),
+ FX16_CONST(0.8280450452577558), FX16_CONST(-0.5606615761973359),
+ FX16_CONST(0.827184027273669), FX16_CONST(-0.5619311212446895),
+ FX16_CONST(0.8263210628456636), FX16_CONST(-0.5631993440138339),
+ FX16_CONST(0.8254561540043776), FX16_CONST(-0.5644662415205194),
+ FX16_CONST(0.8245893027850252), FX16_CONST(-0.5657318107836132),
+ FX16_CONST(0.8237205112273915), FX16_CONST(-0.5669960488251085),
+ FX16_CONST(0.8228497813758263), FX16_CONST(-0.5682589526701315),
+ FX16_CONST(0.8219771152792414), FX16_CONST(-0.5695205193469473),
+ FX16_CONST(0.8211025149911048), FX16_CONST(-0.5707807458869671),
+ FX16_CONST(0.8202259825694347), FX16_CONST(-0.572039629324757),
+ FX16_CONST(0.8193475200767971), FX16_CONST(-0.573297166698042),
+ FX16_CONST(0.8184671295802988), FX16_CONST(-0.5745533550477158),
+ FX16_CONST(0.8175848131515837), FX16_CONST(-0.5758081914178453),
+ FX16_CONST(0.816700572866828), FX16_CONST(-0.5770616728556793),
+ FX16_CONST(0.8158144108067338), FX16_CONST(-0.5783137964116555),
+ FX16_CONST(0.8149263290565265), FX16_CONST(-0.5795645591394059),
+ FX16_CONST(0.8140363297059485), FX16_CONST(-0.5808139580957644),
+ FX16_CONST(0.8131444148492536), FX16_CONST(-0.5820619903407755),
+ FX16_CONST(0.8122505865852039), FX16_CONST(-0.5833086529376984),
+ FX16_CONST(0.8113548470170638), FX16_CONST(-0.5845539429530152),
+ FX16_CONST(0.8104571982525948), FX16_CONST(-0.5857978574564389),
+ FX16_CONST(0.8095576424040515), FX16_CONST(-0.5870403935209177),
+ FX16_CONST(0.8086561815881751), FX16_CONST(-0.5882815482226452),
+ FX16_CONST(0.8077528179261904), FX16_CONST(-0.5895213186410639),
+ FX16_CONST(0.8068475535437994), FX16_CONST(-0.590759701858874),
+ FX16_CONST(0.8059403905711764), FX16_CONST(-0.5919966949620409),
+ FX16_CONST(0.8050313311429635), FX16_CONST(-0.5932322950397999),
+ FX16_CONST(0.8041203773982658), FX16_CONST(-0.5944664991846643),
+ FX16_CONST(0.8032075314806449), FX16_CONST(-0.5956993044924334),
+ FX16_CONST(0.8022927955381156), FX16_CONST(-0.5969307080621966),
+ FX16_CONST(0.8013761717231402), FX16_CONST(-0.5981607069963422),
+ FX16_CONST(0.8004576621926228), FX16_CONST(-0.5993892984005645),
+ FX16_CONST(0.7995372691079052), FX16_CONST(-0.6006164793838688),
+ FX16_CONST(0.7986149946347609), FX16_CONST(-0.60184224705858),
+ FX16_CONST(0.797690840943391), FX16_CONST(-0.6030665985403483),
+ FX16_CONST(0.7967648102084189), FX16_CONST(-0.6042895309481559),
+ FX16_CONST(0.7958369046088836), FX16_CONST(-0.6055110414043254),
+ FX16_CONST(0.7949071263282369), FX16_CONST(-0.6067311270345246),
+ FX16_CONST(0.7939754775543373), FX16_CONST(-0.6079497849677735),
+ FX16_CONST(0.7930419604794436), FX16_CONST(-0.6091670123364532),
+ FX16_CONST(0.7921065773002123), FX16_CONST(-0.6103828062763096),
+ FX16_CONST(0.7911693302176903), FX16_CONST(-0.6115971639264618),
+ FX16_CONST(0.79023022143731), FX16_CONST(-0.6128100824294097),
+ FX16_CONST(0.7892892531688859), FX16_CONST(-0.6140215589310382),
+ FX16_CONST(0.7883464276266063), FX16_CONST(-0.6152315905806267),
+ FX16_CONST(0.7874017470290313), FX16_CONST(-0.6164401745308536),
+ FX16_CONST(0.7864552135990859), FX16_CONST(-0.6176473079378038),
+ FX16_CONST(0.785506829564054), FX16_CONST(-0.6188529879609762),
+ FX16_CONST(0.7845565971555751), FX16_CONST(-0.6200572117632892),
+ FX16_CONST(0.7836045186096383), FX16_CONST(-0.6212599765110874),
+ FX16_CONST(0.7826505961665757), FX16_CONST(-0.62246127937415),
+ FX16_CONST(0.7816948320710593), FX16_CONST(-0.6236611175256946),
+ FX16_CONST(0.7807372285720946), FX16_CONST(-0.6248594881423862),
+ FX16_CONST(0.7797777879230144), FX16_CONST(-0.6260563884043435),
+ FX16_CONST(0.7788165123814761), FX16_CONST(-0.6272518154951439),
+ FX16_CONST(0.7778534042094531), FX16_CONST(-0.6284457666018326),
+ FX16_CONST(0.7768884656732324), FX16_CONST(-0.6296382389149271),
+ FX16_CONST(0.7759216990434078), FX16_CONST(-0.6308292296284244),
+ FX16_CONST(0.7749531065948739), FX16_CONST(-0.632018735939809),
+ FX16_CONST(0.7739826906068228), FX16_CONST(-0.6332067550500573),
+ FX16_CONST(0.7730104533627371), FX16_CONST(-0.6343932841636454),
+ FX16_CONST(0.7720363971503845), FX16_CONST(-0.6355783204885561),
+ FX16_CONST(0.7710605242618137), FX16_CONST(-0.6367618612362843),
+ FX16_CONST(0.7700828369933481), FX16_CONST(-0.6379439036218439),
+ FX16_CONST(0.7691033376455796), FX16_CONST(-0.6391244448637757),
+ FX16_CONST(0.7681220285233655), FX16_CONST(-0.6403034821841515),
+ FX16_CONST(0.7671389119358204), FX16_CONST(-0.641481012808583),
+ FX16_CONST(0.7661539901963128), FX16_CONST(-0.6426570339662269),
+ FX16_CONST(0.7651672656224591), FX16_CONST(-0.6438315428897913),
+ FX16_CONST(0.7641787405361168), FX16_CONST(-0.6450045368155439),
+ FX16_CONST(0.7631884172633812), FX16_CONST(-0.6461760129833164),
+ FX16_CONST(0.762196298134579), FX16_CONST(-0.647345968636512),
+ FX16_CONST(0.7612023854842619), FX16_CONST(-0.6485144010221124),
+ FX16_CONST(0.7602066816512023), FX16_CONST(-0.6496813073906833),
+ FX16_CONST(0.7592091889783881), FX16_CONST(-0.6508466849963808),
+ FX16_CONST(0.7582099098130153), FX16_CONST(-0.6520105310969595),
+ FX16_CONST(0.7572088465064847), FX16_CONST(-0.6531728429537765),
+ FX16_CONST(0.7562060014143945), FX16_CONST(-0.6543336178318004),
+ FX16_CONST(0.7552013768965364), FX16_CONST(-0.6554928529996155),
+ FX16_CONST(0.7541949753168893), FX16_CONST(-0.6566505457294288),
+ FX16_CONST(0.7531867990436125), FX16_CONST(-0.6578066932970785),
+ FX16_CONST(0.7521768504490427), FX16_CONST(-0.6589612929820374),
+ FX16_CONST(0.7511651319096866), FX16_CONST(-0.6601143420674204),
+ FX16_CONST(0.7501516458062151), FX16_CONST(-0.6612658378399922),
+ FX16_CONST(0.7491363945234593), FX16_CONST(-0.6624157775901719),
+ FX16_CONST(0.7481193804504037), FX16_CONST(-0.6635641586120397),
+ FX16_CONST(0.7471006059801801), FX16_CONST(-0.6647109782033449),
+ FX16_CONST(0.746080073510064), FX16_CONST(-0.6658562336655095),
+ FX16_CONST(0.7450577854414661), FX16_CONST(-0.6669999223036374),
+ FX16_CONST(0.7440337441799292), FX16_CONST(-0.6681420414265186),
+ FX16_CONST(0.7430079521351218), FX16_CONST(-0.6692825883466359),
+ FX16_CONST(0.7419804117208311), FX16_CONST(-0.6704215603801731),
+ FX16_CONST(0.740951125354959), FX16_CONST(-0.6715589548470184),
+ FX16_CONST(0.7399200954595163), FX16_CONST(-0.6726947690707727),
+ FX16_CONST(0.7388873244606152), FX16_CONST(-0.673829000378756),
+ FX16_CONST(0.7378528147884659), FX16_CONST(-0.674961646102012),
+ FX16_CONST(0.73681656887737), FX16_CONST(-0.6760927035753158),
+ FX16_CONST(0.7357785891657136), FX16_CONST(-0.6772221701371804),
+ FX16_CONST(0.7347388780959637), FX16_CONST(-0.6783500431298612),
+ FX16_CONST(0.7336974381146604), FX16_CONST(-0.679476319899365),
+ FX16_CONST(0.7326542716724128), FX16_CONST(-0.680600997795453),
+ FX16_CONST(0.7316093812238927), FX16_CONST(-0.6817240741716496),
+ FX16_CONST(0.7305627692278276), FX16_CONST(-0.682845546385248),
+ FX16_CONST(0.729514438146997), FX16_CONST(-0.6839654117973155),
+ FX16_CONST(0.7284643904482253), FX16_CONST(-0.6850836677727002),
+ FX16_CONST(0.7274126286023758), FX16_CONST(-0.6862003116800386),
+ FX16_CONST(0.7263591550843459), FX16_CONST(-0.6873153408917592),
+ FX16_CONST(0.7253039723730609), FX16_CONST(-0.6884287527840903),
+ FX16_CONST(0.7242470829514669), FX16_CONST(-0.6895405447370669),
+ FX16_CONST(0.7231884893065276), FX16_CONST(-0.6906507141345344),
+ FX16_CONST(0.7221281939292155), FX16_CONST(-0.6917592583641576),
+ FX16_CONST(0.7210661993145081), FX16_CONST(-0.6928661748174247),
+ FX16_CONST(0.7200025079613818), FX16_CONST(-0.6939714608896538),
+ FX16_CONST(0.7189371223728045), FX16_CONST(-0.6950751139800008),
+ FX16_CONST(0.7178700450557317), FX16_CONST(-0.696177131491463),
+ FX16_CONST(0.7168012785210996), FX16_CONST(-0.6972775108308864),
+ FX16_CONST(0.7157308252838187), FX16_CONST(-0.6983762494089728),
+ FX16_CONST(0.714658687862769), FX16_CONST(-0.6994733446402839),
+ FX16_CONST(0.7135848687807936), FX16_CONST(-0.7005687939432482),
+ FX16_CONST(0.7125093705646923), FX16_CONST(-0.7016625947401685),
+ FX16_CONST(0.7114321957452167), FX16_CONST(-0.7027547444572251),
+ FX16_CONST(0.7103533468570624), FX16_CONST(-0.7038452405244848),
+ FX16_CONST(0.7092728264388656), FX16_CONST(-0.7049340803759049),
+ FX16_CONST(0.7081906370331955), FX16_CONST(-0.7060212614493396),
+ FX16_CONST(0.7071067811865476), FX16_CONST(-0.7071067811865475),
+ FX16_CONST(0.7060212614493397), FX16_CONST(-0.7081906370331954),
+ FX16_CONST(0.7049340803759051), FX16_CONST(-0.7092728264388655),
+ FX16_CONST(0.703845240524485), FX16_CONST(-0.7103533468570623),
+ FX16_CONST(0.7027547444572252), FX16_CONST(-0.7114321957452165),
+ FX16_CONST(0.7016625947401687), FX16_CONST(-0.7125093705646922),
+ FX16_CONST(0.7005687939432483), FX16_CONST(-0.7135848687807935),
+ FX16_CONST(0.699473344640284), FX16_CONST(-0.7146586878627689),
+ FX16_CONST(0.6983762494089729), FX16_CONST(-0.7157308252838186),
+ FX16_CONST(0.6972775108308865), FX16_CONST(-0.7168012785210995),
+ FX16_CONST(0.6961771314914631), FX16_CONST(-0.7178700450557316),
+ FX16_CONST(0.6950751139800009), FX16_CONST(-0.7189371223728044),
+ FX16_CONST(0.6939714608896539), FX16_CONST(-0.7200025079613817),
+ FX16_CONST(0.6928661748174249), FX16_CONST(-0.7210661993145079),
+ FX16_CONST(0.6917592583641579), FX16_CONST(-0.7221281939292152),
+ FX16_CONST(0.6906507141345346), FX16_CONST(-0.7231884893065275),
+ FX16_CONST(0.689540544737067), FX16_CONST(-0.7242470829514668),
+ FX16_CONST(0.6884287527840904), FX16_CONST(-0.7253039723730608),
+ FX16_CONST(0.6873153408917593), FX16_CONST(-0.7263591550843458),
+ FX16_CONST(0.6862003116800387), FX16_CONST(-0.7274126286023757),
+ FX16_CONST(0.6850836677727004), FX16_CONST(-0.7284643904482252),
+ FX16_CONST(0.6839654117973156), FX16_CONST(-0.7295144381469968),
+ FX16_CONST(0.6828455463852481), FX16_CONST(-0.7305627692278275),
+ FX16_CONST(0.6817240741716497), FX16_CONST(-0.7316093812238926),
+ FX16_CONST(0.6806009977954532), FX16_CONST(-0.7326542716724127),
+ FX16_CONST(0.6794763198993651), FX16_CONST(-0.7336974381146603),
+ FX16_CONST(0.6783500431298614), FX16_CONST(-0.7347388780959635),
+ FX16_CONST(0.6772221701371806), FX16_CONST(-0.7357785891657134),
+ FX16_CONST(0.6760927035753159), FX16_CONST(-0.7368165688773698),
+ FX16_CONST(0.6749616461020123), FX16_CONST(-0.7378528147884658),
+ FX16_CONST(0.6738290003787561), FX16_CONST(-0.7388873244606151),
+ FX16_CONST(0.6726947690707729), FX16_CONST(-0.7399200954595162),
+ FX16_CONST(0.6715589548470186), FX16_CONST(-0.7409511253549589),
+ FX16_CONST(0.6704215603801732), FX16_CONST(-0.741980411720831),
+ FX16_CONST(0.669282588346636), FX16_CONST(-0.7430079521351217),
+ FX16_CONST(0.6681420414265187), FX16_CONST(-0.7440337441799291),
+ FX16_CONST(0.6669999223036376), FX16_CONST(-0.745057785441466),
+ FX16_CONST(0.6658562336655096), FX16_CONST(-0.7460800735100638),
+ FX16_CONST(0.664710978203345), FX16_CONST(-0.74710060598018),
+ FX16_CONST(0.6635641586120398), FX16_CONST(-0.7481193804504036),
+ FX16_CONST(0.662415777590172), FX16_CONST(-0.7491363945234591),
+ FX16_CONST(0.6612658378399923), FX16_CONST(-0.750151645806215),
+ FX16_CONST(0.6601143420674205), FX16_CONST(-0.7511651319096864),
+ FX16_CONST(0.6589612929820375), FX16_CONST(-0.7521768504490425),
+ FX16_CONST(0.6578066932970787), FX16_CONST(-0.7531867990436124),
+ FX16_CONST(0.656650545729429), FX16_CONST(-0.7541949753168892),
+ FX16_CONST(0.6554928529996156), FX16_CONST(-0.7552013768965364),
+ FX16_CONST(0.6543336178318006), FX16_CONST(-0.7562060014143945),
+ FX16_CONST(0.6531728429537766), FX16_CONST(-0.7572088465064847),
+ FX16_CONST(0.6520105310969597), FX16_CONST(-0.7582099098130152),
+ FX16_CONST(0.650846684996381), FX16_CONST(-0.759209188978388),
+ FX16_CONST(0.6496813073906834), FX16_CONST(-0.7602066816512022),
+ FX16_CONST(0.6485144010221126), FX16_CONST(-0.7612023854842617),
+ FX16_CONST(0.6473459686365121), FX16_CONST(-0.7621962981345789),
+ FX16_CONST(0.6461760129833166), FX16_CONST(-0.7631884172633812),
+ FX16_CONST(0.645004536815544), FX16_CONST(-0.7641787405361167),
+ FX16_CONST(0.6438315428897914), FX16_CONST(-0.765167265622459),
+ FX16_CONST(0.6426570339662271), FX16_CONST(-0.7661539901963128),
+ FX16_CONST(0.6414810128085832), FX16_CONST(-0.7671389119358204),
+ FX16_CONST(0.6403034821841516), FX16_CONST(-0.7681220285233654),
+ FX16_CONST(0.6391244448637758), FX16_CONST(-0.7691033376455795),
+ FX16_CONST(0.637943903621844), FX16_CONST(-0.7700828369933479),
+ FX16_CONST(0.6367618612362844), FX16_CONST(-0.7710605242618136),
+ FX16_CONST(0.6355783204885562), FX16_CONST(-0.7720363971503844),
+ FX16_CONST(0.6343932841636455), FX16_CONST(-0.773010453362737),
+ FX16_CONST(0.6332067550500574), FX16_CONST(-0.7739826906068227),
+ FX16_CONST(0.6320187359398091), FX16_CONST(-0.7749531065948738),
+ FX16_CONST(0.6308292296284245), FX16_CONST(-0.7759216990434077),
+ FX16_CONST(0.6296382389149272), FX16_CONST(-0.7768884656732323),
+ FX16_CONST(0.6284457666018327), FX16_CONST(-0.777853404209453),
+ FX16_CONST(0.6272518154951441), FX16_CONST(-0.778816512381476),
+ FX16_CONST(0.6260563884043436), FX16_CONST(-0.7797777879230143),
+ FX16_CONST(0.6248594881423863), FX16_CONST(-0.7807372285720945),
+ FX16_CONST(0.6236611175256949), FX16_CONST(-0.7816948320710593),
+ FX16_CONST(0.6224612793741501), FX16_CONST(-0.7826505961665756),
+ FX16_CONST(0.6212599765110876), FX16_CONST(-0.7836045186096382),
+ FX16_CONST(0.6200572117632894), FX16_CONST(-0.784556597155575),
+ FX16_CONST(0.6188529879609764), FX16_CONST(-0.7855068295640539),
+ FX16_CONST(0.6176473079378039), FX16_CONST(-0.7864552135990858),
+ FX16_CONST(0.6164401745308538), FX16_CONST(-0.7874017470290312),
+ FX16_CONST(0.6152315905806269), FX16_CONST(-0.7883464276266062),
+ FX16_CONST(0.6140215589310384), FX16_CONST(-0.7892892531688858),
+ FX16_CONST(0.6128100824294098), FX16_CONST(-0.7902302214373099),
+ FX16_CONST(0.6115971639264619), FX16_CONST(-0.7911693302176902),
+ FX16_CONST(0.6103828062763097), FX16_CONST(-0.7921065773002122),
+ FX16_CONST(0.6091670123364533), FX16_CONST(-0.7930419604794436),
+ FX16_CONST(0.6079497849677736), FX16_CONST(-0.7939754775543372),
+ FX16_CONST(0.6067311270345247), FX16_CONST(-0.7949071263282368),
+ FX16_CONST(0.6055110414043257), FX16_CONST(-0.7958369046088835),
+ FX16_CONST(0.604289530948156), FX16_CONST(-0.7967648102084187),
+ FX16_CONST(0.6030665985403484), FX16_CONST(-0.7976908409433909),
+ FX16_CONST(0.6018422470585801), FX16_CONST(-0.7986149946347608),
+ FX16_CONST(0.6006164793838689), FX16_CONST(-0.7995372691079051),
+ FX16_CONST(0.5993892984005647), FX16_CONST(-0.8004576621926226),
+ FX16_CONST(0.5981607069963424), FX16_CONST(-0.8013761717231402),
+ FX16_CONST(0.5969307080621967), FX16_CONST(-0.8022927955381155),
+ FX16_CONST(0.5956993044924335), FX16_CONST(-0.8032075314806448),
+ FX16_CONST(0.5944664991846644), FX16_CONST(-0.8041203773982657),
+ FX16_CONST(0.5932322950398), FX16_CONST(-0.8050313311429634),
+ FX16_CONST(0.591996694962041), FX16_CONST(-0.8059403905711763),
+ FX16_CONST(0.5907597018588742), FX16_CONST(-0.8068475535437993),
+ FX16_CONST(0.589521318641064), FX16_CONST(-0.8077528179261902),
+ FX16_CONST(0.5882815482226453), FX16_CONST(-0.808656181588175),
+ FX16_CONST(0.5870403935209179), FX16_CONST(-0.8095576424040514),
+ FX16_CONST(0.585797857456439), FX16_CONST(-0.8104571982525947),
+ FX16_CONST(0.5845539429530153), FX16_CONST(-0.8113548470170637),
+ FX16_CONST(0.5833086529376985), FX16_CONST(-0.8122505865852038),
+ FX16_CONST(0.5820619903407757), FX16_CONST(-0.8131444148492535),
+ FX16_CONST(0.5808139580957645), FX16_CONST(-0.8140363297059484),
+ FX16_CONST(0.579564559139406), FX16_CONST(-0.8149263290565264),
+ FX16_CONST(0.5783137964116557), FX16_CONST(-0.8158144108067338),
+ FX16_CONST(0.5770616728556794), FX16_CONST(-0.8167005728668278),
+ FX16_CONST(0.5758081914178454), FX16_CONST(-0.8175848131515836),
+ FX16_CONST(0.5745533550477159), FX16_CONST(-0.8184671295802987),
+ FX16_CONST(0.5732971666980421), FX16_CONST(-0.819347520076797),
+ FX16_CONST(0.5720396293247573), FX16_CONST(-0.8202259825694346),
+ FX16_CONST(0.5707807458869673), FX16_CONST(-0.8211025149911046),
+ FX16_CONST(0.5695205193469475), FX16_CONST(-0.8219771152792413),
+ FX16_CONST(0.5682589526701317), FX16_CONST(-0.8228497813758262),
+ FX16_CONST(0.5669960488251087), FX16_CONST(-0.8237205112273914),
+ FX16_CONST(0.5657318107836135), FX16_CONST(-0.8245893027850251),
+ FX16_CONST(0.5644662415205195), FX16_CONST(-0.8254561540043774),
+ FX16_CONST(0.5631993440138341), FX16_CONST(-0.8263210628456635),
+ FX16_CONST(0.5619311212446896), FX16_CONST(-0.827184027273669),
+ FX16_CONST(0.5606615761973361), FX16_CONST(-0.8280450452577557),
+ FX16_CONST(0.559390711859136), FX16_CONST(-0.828904114771865),
+ FX16_CONST(0.5581185312205563), FX16_CONST(-0.8297612337945229),
+ FX16_CONST(0.5568450372751601), FX16_CONST(-0.8306164003088462),
+ FX16_CONST(0.5555702330196022), FX16_CONST(-0.8314696123025453),
+ FX16_CONST(0.5542941214536202), FX16_CONST(-0.8323208677679296),
+ FX16_CONST(0.5530167055800275), FX16_CONST(-0.8331701647019132),
+ FX16_CONST(0.5517379884047077), FX16_CONST(-0.8340175011060179),
+ FX16_CONST(0.5504579729366049), FX16_CONST(-0.83486287498638),
+ FX16_CONST(0.5491766621877197), FX16_CONST(-0.8357062843537526),
+ FX16_CONST(0.5478940591731004), FX16_CONST(-0.8365477272235119),
+ FX16_CONST(0.546610166910835), FX16_CONST(-0.8373872016156618),
+ FX16_CONST(0.5453249884220464), FX16_CONST(-0.8382247055548381),
+ FX16_CONST(0.544038526730884), FX16_CONST(-0.8390602370703126),
+ FX16_CONST(0.5427507848645159), FX16_CONST(-0.8398937941959995),
+ FX16_CONST(0.5414617658531233), FX16_CONST(-0.8407253749704581),
+ FX16_CONST(0.540171472729893), FX16_CONST(-0.8415549774368983),
+ FX16_CONST(0.5388799085310084), FX16_CONST(-0.8423825996431858),
+ FX16_CONST(0.5375870762956457), FX16_CONST(-0.8432082396418453),
+ FX16_CONST(0.5362929790659633), FX16_CONST(-0.8440318954900664),
+ FX16_CONST(0.5349976198870972), FX16_CONST(-0.8448535652497071),
+ FX16_CONST(0.5337010018071532), FX16_CONST(-0.845673246987299),
+ FX16_CONST(0.532403127877198), FX16_CONST(-0.846490938774052),
+ FX16_CONST(0.5311040011512549), FX16_CONST(-0.8473066386858584),
+ FX16_CONST(0.5298036246862948), FX16_CONST(-0.8481203448032971),
+ FX16_CONST(0.5285020015422285), FX16_CONST(-0.8489320552116396),
+ FX16_CONST(0.5271991347819013), FX16_CONST(-0.8497417680008525),
+ FX16_CONST(0.5258950274710849), FX16_CONST(-0.8505494812656034),
+ FX16_CONST(0.524589682678469), FX16_CONST(-0.8513551931052652),
+ FX16_CONST(0.5232831034756567), FX16_CONST(-0.8521589016239196),
+ FX16_CONST(0.5219752929371544), FX16_CONST(-0.8529606049303636),
+ FX16_CONST(0.5206662541403672), FX16_CONST(-0.8537603011381114),
+ FX16_CONST(0.5193559901655898), FX16_CONST(-0.8545579883654004),
+ FX16_CONST(0.5180445040959994), FX16_CONST(-0.8553536647351959),
+ FX16_CONST(0.5167317990176498), FX16_CONST(-0.8561473283751945),
+ FX16_CONST(0.5154178780194631), FX16_CONST(-0.8569389774178287),
+ FX16_CONST(0.5141027441932218), FX16_CONST(-0.857728610000272),
+ FX16_CONST(0.512786400633563), FX16_CONST(-0.8585162242644429),
+ FX16_CONST(0.5114688504379705), FX16_CONST(-0.8593018183570084),
+ FX16_CONST(0.5101500967067668), FX16_CONST(-0.8600853904293901),
+ FX16_CONST(0.5088301425431073), FX16_CONST(-0.8608669386377672),
+ FX16_CONST(0.507508991052971), FX16_CONST(-0.8616464611430813),
+ FX16_CONST(0.5061866453451552), FX16_CONST(-0.8624239561110405),
+ FX16_CONST(0.5048631085312677), FX16_CONST(-0.863199421712124),
+ FX16_CONST(0.5035383837257176), FX16_CONST(-0.8639728561215867),
+ FX16_CONST(0.5022124740457107), FX16_CONST(-0.8647442575194624),
+ FX16_CONST(0.5008853826112409), FX16_CONST(-0.865513624090569),
+ FX16_CONST(0.4995571125450819), FX16_CONST(-0.866280954024513),
+ FX16_CONST(0.49822766697278176), FX16_CONST(-0.8670462455156926),
+ FX16_CONST(0.4968970490226547), FX16_CONST(-0.8678094967633032),
+ FX16_CONST(0.49556526182577254), FX16_CONST(-0.8685707059713409),
+ FX16_CONST(0.49423230851596), FX16_CONST(-0.8693298713486066),
+ FX16_CONST(0.49289819222978415), FX16_CONST(-0.8700869911087113),
+ FX16_CONST(0.4915629161065499), FX16_CONST(-0.8708420634700789),
+ FX16_CONST(0.4902264832882914), FX16_CONST(-0.8715950866559509),
+ FX16_CONST(0.4888888969197632), FX16_CONST(-0.8723460588943914),
+ FX16_CONST(0.4875501601484359), FX16_CONST(-0.8730949784182901),
+ FX16_CONST(0.4862102761244866), FX16_CONST(-0.8738418434653668),
+ FX16_CONST(0.4848692480007911), FX16_CONST(-0.8745866522781761),
+ FX16_CONST(0.48352707893291863), FX16_CONST(-0.8753294031041109),
+ FX16_CONST(0.4821837720791229), FX16_CONST(-0.8760700941954065),
+ FX16_CONST(0.48083933060033396), FX16_CONST(-0.8768087238091457),
+ FX16_CONST(0.4794937576601533), FX16_CONST(-0.8775452902072611),
+ FX16_CONST(0.4781470564248432), FX16_CONST(-0.8782797916565415),
+ FX16_CONST(0.4767992300633221), FX16_CONST(-0.8790122264286335),
+ FX16_CONST(0.4754502817471561), FX16_CONST(-0.8797425928000473),
+ FX16_CONST(0.4741002146505501), FX16_CONST(-0.8804708890521608),
+ FX16_CONST(0.47274903195034274), FX16_CONST(-0.8811971134712221),
+ FX16_CONST(0.4713967368259978), FX16_CONST(-0.8819212643483549),
+ FX16_CONST(0.4700433324595957), FX16_CONST(-0.8826433399795628),
+ FX16_CONST(0.46868882203582785), FX16_CONST(-0.8833633386657317),
+ FX16_CONST(0.4673332087419886), FX16_CONST(-0.8840812587126349),
+ FX16_CONST(0.4659764957679662), FX16_CONST(-0.8847970984309378),
+ FX16_CONST(0.4646186863062381), FX16_CONST(-0.8855108561361998),
+ FX16_CONST(0.4632597835518603), FX16_CONST(-0.8862225301488805),
+ FX16_CONST(0.46189979070246273), FX16_CONST(-0.8869321187943422),
+ FX16_CONST(0.4605387109582402), FX16_CONST(-0.8876396204028538),
+ FX16_CONST(0.4591765475219442), FX16_CONST(-0.8883450333095962),
+ FX16_CONST(0.4578133035988772), FX16_CONST(-0.8890483558546646),
+ FX16_CONST(0.45644898239688414), FX16_CONST(-0.8897495863830727),
+ FX16_CONST(0.4550835871263439), FX16_CONST(-0.8904487232447579),
+ FX16_CONST(0.45371712100016376), FX16_CONST(-0.8911457647945833),
+ FX16_CONST(0.45234958723377106), FX16_CONST(-0.8918407093923426),
+ FX16_CONST(0.45098098904510386), FX16_CONST(-0.8925335554027646),
+ FX16_CONST(0.4496113296546069), FX16_CONST(-0.8932243011955152),
+ FX16_CONST(0.44824061228522005), FX16_CONST(-0.8939129451452031),
+ FX16_CONST(0.44686884016237416), FX16_CONST(-0.8945994856313827),
+ FX16_CONST(0.44549601651398196), FX16_CONST(-0.8952839210385574),
+ FX16_CONST(0.4441221445704293), FX16_CONST(-0.8959662497561851),
+ FX16_CONST(0.44274722756456997), FX16_CONST(-0.8966464701786803),
+ FX16_CONST(0.4413712687317169), FX16_CONST(-0.8973245807054182),
+ FX16_CONST(0.4399942713096333), FX16_CONST(-0.8980005797407398),
+ FX16_CONST(0.43861623853852755), FX16_CONST(-0.8986744656939539),
+ FX16_CONST(0.43723717366104425), FX16_CONST(-0.8993462369793415),
+ FX16_CONST(0.43585707992225553), FX16_CONST(-0.9000158920161602),
+ FX16_CONST(0.434475960569656), FX16_CONST(-0.9006834292286467),
+ FX16_CONST(0.43309381885315207), FX16_CONST(-0.9013488470460219),
+ FX16_CONST(0.43171065802505726), FX16_CONST(-0.9020121439024932),
+ FX16_CONST(0.4303264813400829), FX16_CONST(-0.9026733182372587),
+ FX16_CONST(0.4289412920553296), FX16_CONST(-0.9033323684945118),
+ FX16_CONST(0.42755509343028203), FX16_CONST(-0.9039892931234433),
+ FX16_CONST(0.42616788872679984), FX16_CONST(-0.9046440905782461),
+ FX16_CONST(0.42477968120910886), FX16_CONST(-0.9052967593181187),
+ FX16_CONST(0.42339047414379594), FX16_CONST(-0.9059472978072685),
+ FX16_CONST(0.42200027079979985), FX16_CONST(-0.9065957045149153),
+ FX16_CONST(0.42060907444840256), FX16_CONST(-0.9072419779152958),
+ FX16_CONST(0.41921688836322424), FX16_CONST(-0.907886116487666),
+ FX16_CONST(0.41782371582021244), FX16_CONST(-0.9085281187163061),
+ FX16_CONST(0.41642956009763715), FX16_CONST(-0.9091679830905224),
+ FX16_CONST(0.41503442447608185), FX16_CONST(-0.9098057081046521),
+ FX16_CONST(0.41363831223843467), FX16_CONST(-0.9104412922580671),
+ FX16_CONST(0.41224122666988283), FX16_CONST(-0.9110747340551764),
+ FX16_CONST(0.41084317105790413), FX16_CONST(-0.9117060320054298),
+ FX16_CONST(0.4094441486922577), FX16_CONST(-0.9123351846233227),
+ FX16_CONST(0.4080441628649786), FX16_CONST(-0.9129621904283982),
+ FX16_CONST(0.4066432168703692), FX16_CONST(-0.9135870479452507),
+ FX16_CONST(0.4052413140049899), FX16_CONST(-0.9142097557035307),
+ FX16_CONST(0.4038384575676544), FX16_CONST(-0.914830312237946),
+ FX16_CONST(0.4024346508594186), FX16_CONST(-0.9154487160882677),
+ FX16_CONST(0.4010298971835756), FX16_CONST(-0.9160649657993317),
+ FX16_CONST(0.39962419984564707), FX16_CONST(-0.9166790599210426),
+ FX16_CONST(0.39821756215337367), FX16_CONST(-0.9172909970083779),
+ FX16_CONST(0.39680998741671025), FX16_CONST(-0.9179007756213905),
+ FX16_CONST(0.3954014789478165), FX16_CONST(-0.9185083943252121),
+ FX16_CONST(0.39399204006104815), FX16_CONST(-0.9191138516900578),
+ FX16_CONST(0.3925816740729514), FX16_CONST(-0.9197171462912274),
+ FX16_CONST(0.39117038430225404), FX16_CONST(-0.9203182767091105),
+ FX16_CONST(0.38975817406985647), FX16_CONST(-0.9209172415291894),
+ FX16_CONST(0.3883450466988266), FX16_CONST(-0.9215140393420418),
+ FX16_CONST(0.38693100551438875), FX16_CONST(-0.9221086687433451),
+ FX16_CONST(0.38551605384391885), FX16_CONST(-0.9227011283338786),
+ FX16_CONST(0.3841001950169353), FX16_CONST(-0.9232914167195275),
+ FX16_CONST(0.3826834323650899), FX16_CONST(-0.9238795325112867),
+ FX16_CONST(0.3812657692221623), FX16_CONST(-0.9244654743252626),
+ FX16_CONST(0.3798472089240514), FX16_CONST(-0.9250492407826775),
+ FX16_CONST(0.37842775480876567), FX16_CONST(-0.9256308305098727),
+ FX16_CONST(0.37700741021641815), FX16_CONST(-0.9262102421383114),
+ FX16_CONST(0.3755861784892174), FX16_CONST(-0.9267874743045817),
+ FX16_CONST(0.37416406297145804), FX16_CONST(-0.9273625256504011),
+ FX16_CONST(0.3727410670095161), FX16_CONST(-0.9279353948226178),
+ FX16_CONST(0.3713171939518377), FX16_CONST(-0.9285060804732155),
+ FX16_CONST(0.3698924471489341), FX16_CONST(-0.9290745812593159),
+ FX16_CONST(0.3684668299533726), FX16_CONST(-0.9296408958431812),
+ FX16_CONST(0.3670403457197673), FX16_CONST(-0.9302050228922191),
+ FX16_CONST(0.3656129978047738), FX16_CONST(-0.9307669610789837),
+ FX16_CONST(0.3641847895670801), FX16_CONST(-0.9313267090811803),
+ FX16_CONST(0.3627557243673973), FX16_CONST(-0.931884265581668),
+ FX16_CONST(0.3613258055684542), FX16_CONST(-0.9324396292684625),
+ FX16_CONST(0.35989503653498833), FX16_CONST(-0.9329927988347388),
+ FX16_CONST(0.3584634206337366), FX16_CONST(-0.9335437729788362),
+ FX16_CONST(0.3570309612334303), FX16_CONST(-0.9340925504042588),
+ FX16_CONST(0.355597661704784), FX16_CONST(-0.9346391298196807),
+ FX16_CONST(0.3541635254204904), FX16_CONST(-0.9351835099389476),
+ FX16_CONST(0.35272855575521095), FX16_CONST(-0.9357256894810803),
+ FX16_CONST(0.3512927560855672), FX16_CONST(-0.9362656671702783),
+ FX16_CONST(0.34985612979013486), FX16_CONST(-0.9368034417359217),
+ FX16_CONST(0.3484186802494348), FX16_CONST(-0.9373390119125748),
+ FX16_CONST(0.34698041084592374), FX16_CONST(-0.9378723764399898),
+ FX16_CONST(0.345541324963989), FX16_CONST(-0.9384035340631082),
+ FX16_CONST(0.34410142598993904), FX16_CONST(-0.9389324835320645),
+ FX16_CONST(0.34266071731199443), FX16_CONST(-0.9394592236021899),
+ FX16_CONST(0.3412192023202827), FX16_CONST(-0.9399837530340138),
+ FX16_CONST(0.339776884406827), FX16_CONST(-0.9405060705932683),
+ FX16_CONST(0.3383337669655412), FX16_CONST(-0.9410261750508893),
+ FX16_CONST(0.33688985339222033), FX16_CONST(-0.9415440651830207),
+ FX16_CONST(0.3354451470845317), FX16_CONST(-0.9420597397710173),
+ FX16_CONST(0.3339996514420094), FX16_CONST(-0.9425731976014469),
+ FX16_CONST(0.33255336986604445), FX16_CONST(-0.9430844374660934),
+ FX16_CONST(0.3311063057598765), FX16_CONST(-0.9435934581619604),
+ FX16_CONST(0.32965846252858744), FX16_CONST(-0.9441002584912727),
+ FX16_CONST(0.3282098435790927), FX16_CONST(-0.9446048372614801),
+ FX16_CONST(0.32676045232013184), FX16_CONST(-0.9451071932852606),
+ FX16_CONST(0.32531029216226326), FX16_CONST(-0.9456073253805212),
+ FX16_CONST(0.323859366517853), FX16_CONST(-0.9461052323704033),
+ FX16_CONST(0.32240767880106985), FX16_CONST(-0.9466009130832835),
+ FX16_CONST(0.3209552324278755), FX16_CONST(-0.9470943663527771),
+ FX16_CONST(0.3195020308160158), FX16_CONST(-0.9475855910177411),
+ FX16_CONST(0.3180480773850149), FX16_CONST(-0.9480745859222762),
+ FX16_CONST(0.31659337555616607), FX16_CONST(-0.9485613499157303),
+ FX16_CONST(0.3151379287525225), FX16_CONST(-0.9490458818527006),
+ FX16_CONST(0.3136817403988914), FX16_CONST(-0.9495281805930367),
+ FX16_CONST(0.3122248139218251), FX16_CONST(-0.950008245001843),
+ FX16_CONST(0.31076715274961153), FX16_CONST(-0.9504860739494817),
+ FX16_CONST(0.309308760312269), FX16_CONST(-0.950961666311575),
+ FX16_CONST(0.30784964004153503), FX16_CONST(-0.9514350209690083),
+ FX16_CONST(0.3063897953708609), FX16_CONST(-0.9519061368079323),
+ FX16_CONST(0.30492922973540265), FX16_CONST(-0.9523750127197658),
+ FX16_CONST(0.3034679465720114), FX16_CONST(-0.9528416476011986),
+ FX16_CONST(0.30200594931922803), FX16_CONST(-0.9533060403541939),
+ FX16_CONST(0.3005432414172737), FX16_CONST(-0.9537681898859902),
+ FX16_CONST(0.29907982630804053), FX16_CONST(-0.9542280951091056),
+ FX16_CONST(0.29761570743508614), FX16_CONST(-0.9546857549413383),
+ FX16_CONST(0.296150888243624), FX16_CONST(-0.9551411683057707),
+ FX16_CONST(0.2946853721805144), FX16_CONST(-0.9555943341307711),
+ FX16_CONST(0.29321916269425896), FX16_CONST(-0.9560452513499963),
+ FX16_CONST(0.29175226323498943), FX16_CONST(-0.956493918902395),
+ FX16_CONST(0.2902846772544624), FX16_CONST(-0.9569403357322088),
+ FX16_CONST(0.28881640820604976), FX16_CONST(-0.9573845007889759),
+ FX16_CONST(0.2873474595447296), FX16_CONST(-0.9578264130275329),
+ FX16_CONST(0.28587783472708056), FX16_CONST(-0.9582660714080177),
+ FX16_CONST(0.2844075372112721), FX16_CONST(-0.9587034748958715),
+ FX16_CONST(0.28293657045705545), FX16_CONST(-0.9591386224618419),
+ FX16_CONST(0.2814649379257579), FX16_CONST(-0.9595715130819845),
+ FX16_CONST(0.27999264308027344), FX16_CONST(-0.9600021457376658),
+ FX16_CONST(0.27851968938505317), FX16_CONST(-0.9604305194155658),
+ FX16_CONST(0.27704608030610023), FX16_CONST(-0.9608566331076795),
+ FX16_CONST(0.2755718193109583), FX16_CONST(-0.9612804858113206),
+ FX16_CONST(0.2740969098687064), FX16_CONST(-0.9617020765291225),
+ FX16_CONST(0.27262135544994925), FX16_CONST(-0.9621214042690415),
+ FX16_CONST(0.2711451595268081), FX16_CONST(-0.9625384680443592),
+ FX16_CONST(0.2696683255729151), FX16_CONST(-0.9629532668736839),
+ FX16_CONST(0.2681908570634034), FX16_CONST(-0.9633657997809539),
+ FX16_CONST(0.2667127574748985), FX16_CONST(-0.9637760657954398),
+ FX16_CONST(0.26523403028551173), FX16_CONST(-0.9641840639517458),
+ FX16_CONST(0.26375467897483157), FX16_CONST(-0.9645897932898126),
+ FX16_CONST(0.2622747070239137), FX16_CONST(-0.9649932528549203),
+ FX16_CONST(0.26079411791527585), FX16_CONST(-0.9653944416976893),
+ FX16_CONST(0.2593129151328864), FX16_CONST(-0.9657933588740836),
+ FX16_CONST(0.257831102162159), FX16_CONST(-0.9661900034454125),
+ FX16_CONST(0.2563486824899432), FX16_CONST(-0.966584374478333),
+ FX16_CONST(0.2548656596045147), FX16_CONST(-0.9669764710448521),
+ FX16_CONST(0.2533820369955701), FX16_CONST(-0.9673662922223285),
+ FX16_CONST(0.2518978181542172), FX16_CONST(-0.9677538370934754),
+ FX16_CONST(0.25041300657296534), FX16_CONST(-0.9681391047463623),
+ FX16_CONST(0.2489276057457201), FX16_CONST(-0.9685220942744174),
+ FX16_CONST(0.2474416191677735), FX16_CONST(-0.9689028047764289),
+ FX16_CONST(0.24595505033579465), FX16_CONST(-0.9692812353565484),
+ FX16_CONST(0.24446790274782448), FX16_CONST(-0.9696573851242923),
+ FX16_CONST(0.24298017990326407), FX16_CONST(-0.970031253194544),
+ FX16_CONST(0.24149188530286936), FX16_CONST(-0.9704028386875555),
+ FX16_CONST(0.24000302244874178), FX16_CONST(-0.9707721407289502),
+ FX16_CONST(0.23851359484431855), FX16_CONST(-0.9711391584497251),
+ FX16_CONST(0.23702360599436717), FX16_CONST(-0.9715038909862518),
+ FX16_CONST(0.23553305940497574), FX16_CONST(-0.9718663374802793),
+ FX16_CONST(0.2340419585835435), FX16_CONST(-0.9722264970789363),
+ FX16_CONST(0.23255030703877516), FX16_CONST(-0.9725843689347322),
+ FX16_CONST(0.23105810828067133), FX16_CONST(-0.9729399522055601),
+ FX16_CONST(0.22956536582051892), FX16_CONST(-0.9732932460546982),
+ FX16_CONST(0.22807208317088606), FX16_CONST(-0.9736442496508119),
+ FX16_CONST(0.22657826384561017), FX16_CONST(-0.9739929621679558),
+ FX16_CONST(0.22508391135979283), FX16_CONST(-0.9743393827855759),
+ FX16_CONST(0.2235890292297903), FX16_CONST(-0.9746835106885107),
+ FX16_CONST(0.22209362097320365), FX16_CONST(-0.9750253450669941),
+ FX16_CONST(0.2205976901088735), FX16_CONST(-0.975364885116657),
+ FX16_CONST(0.21910124015687005), FX16_CONST(-0.9757021300385285),
+ FX16_CONST(0.21760427463848372), FX16_CONST(-0.976037079039039),
+ FX16_CONST(0.21610679707621944), FX16_CONST(-0.9763697313300211),
+ FX16_CONST(0.21460881099378698), FX16_CONST(-0.9767000861287117),
+ FX16_CONST(0.21311031991609142), FX16_CONST(-0.9770281426577544),
+ FX16_CONST(0.2116113273692279), FX16_CONST(-0.9773539001452),
+ FX16_CONST(0.2101118368804698), FX16_CONST(-0.9776773578245099),
+ FX16_CONST(0.2086118519782635), FX16_CONST(-0.9779985149345571),
+ FX16_CONST(0.20711137619221884), FX16_CONST(-0.9783173707196275),
+ FX16_CONST(0.20561041305309938), FX16_CONST(-0.9786339244294231),
+ FX16_CONST(0.20410896609281684), FX16_CONST(-0.9789481753190622),
+ FX16_CONST(0.20260703884442138), FX16_CONST(-0.979260122649082),
+ FX16_CONST(0.201104634842092), FX16_CONST(-0.9795697656854405),
+ FX16_CONST(0.19960175762113092), FX16_CONST(-0.9798771036995176),
+ FX16_CONST(0.1980984107179538), FX16_CONST(-0.9801821359681173),
+ FX16_CONST(0.19659459767008028), FX16_CONST(-0.9804848617734694),
+ FX16_CONST(0.1950903220161286), FX16_CONST(-0.9807852804032304),
+ FX16_CONST(0.1935855872958038), FX16_CONST(-0.9810833911504866),
+ FX16_CONST(0.19208039704989247), FX16_CONST(-0.9813791933137546),
+ FX16_CONST(0.19057475482025307), FX16_CONST(-0.9816726861969831),
+ FX16_CONST(0.18906866414980636), FX16_CONST(-0.9819638691095552),
+ FX16_CONST(0.18756212858252957), FX16_CONST(-0.9822527413662894),
+ FX16_CONST(0.1860551516634469), FX16_CONST(-0.9825393022874412),
+ FX16_CONST(0.1845477369386197), FX16_CONST(-0.9828235511987052),
+ FX16_CONST(0.1830398879551409), FX16_CONST(-0.9831054874312163),
+ FX16_CONST(0.18153160826112522), FX16_CONST(-0.9833851103215512),
+ FX16_CONST(0.18002290140569957), FX16_CONST(-0.9836624192117303),
+ FX16_CONST(0.17851377093899742), FX16_CONST(-0.9839374134492189),
+ FX16_CONST(0.17700422041214894), FX16_CONST(-0.984210092386929),
+ FX16_CONST(0.17549425337727145), FX16_CONST(-0.9844804553832209),
+ FX16_CONST(0.17398387338746413), FX16_CONST(-0.9847485018019042),
+ FX16_CONST(0.17247308399679612), FX16_CONST(-0.9850142310122398),
+ FX16_CONST(0.17096188876030122), FX16_CONST(-0.9852776423889412),
+ FX16_CONST(0.1694502912339682), FX16_CONST(-0.9855387353121761),
+ FX16_CONST(0.16793829497473128), FX16_CONST(-0.9857975091675674),
+ FX16_CONST(0.16642590354046405), FX16_CONST(-0.9860539633461954),
+ FX16_CONST(0.16491312048997014), FX16_CONST(-0.9863080972445986),
+ FX16_CONST(0.16339994938297328), FX16_CONST(-0.9865599102647754),
+ FX16_CONST(0.16188639378011174), FX16_CONST(-0.9868094018141855),
+ FX16_CONST(0.16037245724292845), FX16_CONST(-0.987056571305751),
+ FX16_CONST(0.15885814333386147), FX16_CONST(-0.9873014181578584),
+ FX16_CONST(0.15734345561623855), FX16_CONST(-0.9875439417943592),
+ FX16_CONST(0.15582839765426537), FX16_CONST(-0.9877841416445722),
+ FX16_CONST(0.15431297301302008), FX16_CONST(-0.9880220171432835),
+ FX16_CONST(0.15279718525844369), FX16_CONST(-0.9882575677307495),
+ FX16_CONST(0.1512810379573303), FX16_CONST(-0.9884907928526966),
+ FX16_CONST(0.14976453467732145), FX16_CONST(-0.9887216919603238),
+ FX16_CONST(0.14824767898689625), FX16_CONST(-0.988950264510303),
+ FX16_CONST(0.1467304744553618), FX16_CONST(-0.989176509964781),
+ FX16_CONST(0.14521292465284735), FX16_CONST(-0.9894004277913804),
+ FX16_CONST(0.14369503315029464), FX16_CONST(-0.9896220174632008),
+ FX16_CONST(0.1421768035194481), FX16_CONST(-0.9898412784588205),
+ FX16_CONST(0.14065823933284954), FX16_CONST(-0.990058210262297),
+ FX16_CONST(0.13913934416382634), FX16_CONST(-0.9902728123631691),
+ FX16_CONST(0.13762012158648604), FX16_CONST(-0.9904850842564571),
+ FX16_CONST(0.13610057517570648), FX16_CONST(-0.9906950254426646),
+ FX16_CONST(0.13458070850712628), FX16_CONST(-0.99090263542778),
+ FX16_CONST(0.133060525157139), FX16_CONST(-0.9911079137232769),
+ FX16_CONST(0.13154002870288334), FX16_CONST(-0.9913108598461154),
+ FX16_CONST(0.13001922272223343), FX16_CONST(-0.9915114733187439),
+ FX16_CONST(0.12849811079379309), FX16_CONST(-0.9917097536690995),
+ FX16_CONST(0.12697669649688606), FX16_CONST(-0.9919057004306093),
+ FX16_CONST(0.12545498341154626), FX16_CONST(-0.9920993131421918),
+ FX16_CONST(0.12393297511851248), FX16_CONST(-0.9922905913482573),
+ FX16_CONST(0.12241067519921635), FX16_CONST(-0.99247953459871),
+ FX16_CONST(0.12088808723577706), FX16_CONST(-0.992666142448948),
+ FX16_CONST(0.11936521481099163), FX16_CONST(-0.9928504144598651),
+ FX16_CONST(0.11784206150832509), FX16_CONST(-0.9930323501978514),
+ FX16_CONST(0.11631863091190471), FX16_CONST(-0.9932119492347945),
+ FX16_CONST(0.1147949266065103), FX16_CONST(-0.9933892111480807),
+ FX16_CONST(0.11327095217756442), FX16_CONST(-0.9935641355205953),
+ FX16_CONST(0.1117467112111265), FX16_CONST(-0.9937367219407246),
+ FX16_CONST(0.11022220729388324), FX16_CONST(-0.9939069700023561),
+ FX16_CONST(0.10869744401313874), FX16_CONST(-0.9940748793048794),
+ FX16_CONST(0.10717242495680916), FX16_CONST(-0.9942404494531879),
+ FX16_CONST(0.10564715371341075), FX16_CONST(-0.9944036800576791),
+ FX16_CONST(0.10412163387205457), FX16_CONST(-0.9945645707342554),
+ FX16_CONST(0.10259586902243656), FX16_CONST(-0.9947231211043257),
+ FX16_CONST(0.10106986275482793), FX16_CONST(-0.9948793307948056),
+ FX16_CONST(0.09954361866006928), FX16_CONST(-0.9950331994381186),
+ FX16_CONST(0.09801714032956083), FX16_CONST(-0.9951847266721968),
+ FX16_CONST(0.09649043135525266), FX16_CONST(-0.9953339121404823),
+ FX16_CONST(0.09496349532963891), FX16_CONST(-0.9954807554919269),
+ FX16_CONST(0.09343633584574797), FX16_CONST(-0.9956252563809943),
+ FX16_CONST(0.09190895649713275), FX16_CONST(-0.9957674144676598),
+ FX16_CONST(0.09038136087786529), FX16_CONST(-0.9959072294174117),
+ FX16_CONST(0.08885355258252475), FX16_CONST(-0.996044700901252),
+ FX16_CONST(0.08732553520619206), FX16_CONST(-0.996179828595697),
+ FX16_CONST(0.08579731234444016), FX16_CONST(-0.996312612182778),
+ FX16_CONST(0.08426888759332418), FX16_CONST(-0.9964430513500426),
+ FX16_CONST(0.08274026454937564), FX16_CONST(-0.9965711457905548),
+ FX16_CONST(0.08121144680959266), FX16_CONST(-0.9966968952028961),
+ FX16_CONST(0.0796824379714302), FX16_CONST(-0.9968202992911657),
+ FX16_CONST(0.07815324163279415), FX16_CONST(-0.9969413577649822),
+ FX16_CONST(0.07662386139203169), FX16_CONST(-0.997060070339483),
+ FX16_CONST(0.07509430084792135), FX16_CONST(-0.9971764367353261),
+ FX16_CONST(0.07356456359966773), FX16_CONST(-0.9972904566786902),
+ FX16_CONST(0.07203465324688947), FX16_CONST(-0.9974021299012753),
+ FX16_CONST(0.07050457338961386), FX16_CONST(-0.9975114561403035),
+ FX16_CONST(0.06897432762826702), FX16_CONST(-0.9976184351385196),
+ FX16_CONST(0.06744391956366418), FX16_CONST(-0.9977230666441916),
+ FX16_CONST(0.06591335279700376), FX16_CONST(-0.9978253504111116),
+ FX16_CONST(0.0643826309298577), FX16_CONST(-0.997925286198596),
+ FX16_CONST(0.06285175756416149), FX16_CONST(-0.9980228737714862),
+ FX16_CONST(0.06132073630220849), FX16_CONST(-0.9981181129001492),
+ FX16_CONST(0.05978957074664007), FX16_CONST(-0.9982110033604782),
+ FX16_CONST(0.058258264500435794), FX16_CONST(-0.9983015449338929),
+ FX16_CONST(0.05672682116690807), FX16_CONST(-0.9983897374073402),
+ FX16_CONST(0.055195244349690094), FX16_CONST(-0.9984755805732948),
+ FX16_CONST(0.05366353765273052), FX16_CONST(-0.9985590742297593),
+ FX16_CONST(0.052131704680283594), FX16_CONST(-0.9986402181802652),
+ FX16_CONST(0.05059974903689939), FX16_CONST(-0.9987190122338729),
+ FX16_CONST(0.049067674327417966), FX16_CONST(-0.9987954562051724),
+ FX16_CONST(0.04753548415695954), FX16_CONST(-0.9988695499142836),
+ FX16_CONST(0.046003182130914706), FX16_CONST(-0.9989412931868569),
+ FX16_CONST(0.044470771854938584), FX16_CONST(-0.9990106858540734),
+ FX16_CONST(0.04293825693494102), FX16_CONST(-0.9990777277526454),
+ FX16_CONST(0.041405640977076774), FX16_CONST(-0.9991424187248169),
+ FX16_CONST(0.03987292758774013), FX16_CONST(-0.9992047586183639),
+ FX16_CONST(0.038340120373552854), FX16_CONST(-0.9992647472865944),
+ FX16_CONST(0.03680722294135883), FX16_CONST(-0.9993223845883495),
+ FX16_CONST(0.03527423889821423), FX16_CONST(-0.9993776703880028),
+ FX16_CONST(0.033741171851377705), FX16_CONST(-0.9994306045554617),
+ FX16_CONST(0.032208025408304544), FX16_CONST(-0.999481186966167),
+ FX16_CONST(0.030674803176636865), FX16_CONST(-0.9995294175010931),
+ FX16_CONST(0.029141508764193802), FX16_CONST(-0.9995752960467492),
+ FX16_CONST(0.02760814577896566), FX16_CONST(-0.9996188224951786),
+ FX16_CONST(0.0260747178291041), FX16_CONST(-0.9996599967439592),
+ FX16_CONST(0.024541228522912326), FX16_CONST(-0.9996988186962042),
+ FX16_CONST(0.023007681468839695), FX16_CONST(-0.9997352882605617),
+ FX16_CONST(0.021474080275469667), FX16_CONST(-0.9997694053512153),
+ FX16_CONST(0.019940428551514438), FX16_CONST(-0.9998011698878843),
+ FX16_CONST(0.0184067299058051), FX16_CONST(-0.9998305817958234),
+ FX16_CONST(0.016872987947281835), FX16_CONST(-0.9998576410058239),
+ FX16_CONST(0.01533920628498806), FX16_CONST(-0.9998823474542126),
+ FX16_CONST(0.013805388528060632), FX16_CONST(-0.9999047010828528),
+ FX16_CONST(0.012271538285720007), FX16_CONST(-0.9999247018391445),
+ FX16_CONST(0.01073765916726441), FX16_CONST(-0.9999423496760239),
+ FX16_CONST(0.00920375478206002), FX16_CONST(-0.9999576445519639),
+ FX16_CONST(0.007669828739531138), FX16_CONST(-0.9999705864309741),
+ FX16_CONST(0.006135884649154799), FX16_CONST(-0.9999811752826011),
+ FX16_CONST(0.004601926120448733), FX16_CONST(-0.9999894110819284),
+ FX16_CONST(0.003067956762965977), FX16_CONST(-0.9999952938095762),
+ FX16_CONST(0.0015339801862850493), FX16_CONST(-0.9999988234517019),
+ FX16_CONST(1.2246467991473532e-16), FX16_CONST(-1.0),
+ FX16_CONST(-0.0015339801862848043), FX16_CONST(-0.9999988234517019),
+ FX16_CONST(-0.0030679567629657324), FX16_CONST(-0.9999952938095762),
+ FX16_CONST(-0.004601926120448488), FX16_CONST(-0.9999894110819284),
+ FX16_CONST(-0.006135884649154554), FX16_CONST(-0.9999811752826011),
+ FX16_CONST(-0.007669828739530893), FX16_CONST(-0.9999705864309741),
+ FX16_CONST(-0.009203754782059776), FX16_CONST(-0.9999576445519639),
+ FX16_CONST(-0.010737659167264166), FX16_CONST(-0.9999423496760239),
+ FX16_CONST(-0.012271538285719762), FX16_CONST(-0.9999247018391445),
+ FX16_CONST(-0.013805388528060387), FX16_CONST(-0.9999047010828529),
+ FX16_CONST(-0.015339206284987816), FX16_CONST(-0.9998823474542126),
+ FX16_CONST(-0.01687298794728159), FX16_CONST(-0.9998576410058239),
+ FX16_CONST(-0.01840672990580486), FX16_CONST(-0.9998305817958234),
+ FX16_CONST(-0.01994042855151419), FX16_CONST(-0.9998011698878843),
+ FX16_CONST(-0.02147408027546942), FX16_CONST(-0.9997694053512153),
+ FX16_CONST(-0.02300768146883945), FX16_CONST(-0.9997352882605617),
+ FX16_CONST(-0.02454122852291208), FX16_CONST(-0.9996988186962042),
+ FX16_CONST(-0.026074717829103856), FX16_CONST(-0.9996599967439592),
+ FX16_CONST(-0.027608145778965414), FX16_CONST(-0.9996188224951786),
+ FX16_CONST(-0.029141508764193556), FX16_CONST(-0.9995752960467492),
+ FX16_CONST(-0.03067480317663662), FX16_CONST(-0.9995294175010931),
+ FX16_CONST(-0.032208025408304294), FX16_CONST(-0.999481186966167),
+ FX16_CONST(-0.033741171851377455), FX16_CONST(-0.9994306045554617),
+ FX16_CONST(-0.03527423889821398), FX16_CONST(-0.9993776703880028),
+ FX16_CONST(-0.03680722294135858), FX16_CONST(-0.9993223845883495),
+ FX16_CONST(-0.03834012037355261), FX16_CONST(-0.9992647472865944),
+ FX16_CONST(-0.03987292758773989), FX16_CONST(-0.9992047586183639),
+ FX16_CONST(-0.04140564097707653), FX16_CONST(-0.9991424187248169),
+ FX16_CONST(-0.04293825693494078), FX16_CONST(-0.9990777277526454),
+ FX16_CONST(-0.044470771854938335), FX16_CONST(-0.9990106858540734),
+ FX16_CONST(-0.046003182130914456), FX16_CONST(-0.9989412931868569),
+ FX16_CONST(-0.047535484156959296), FX16_CONST(-0.9988695499142836),
+ FX16_CONST(-0.049067674327417724), FX16_CONST(-0.9987954562051724),
+ FX16_CONST(-0.05059974903689915), FX16_CONST(-0.9987190122338729),
+ FX16_CONST(-0.05213170468028335), FX16_CONST(-0.9986402181802653),
+ FX16_CONST(-0.05366353765273028), FX16_CONST(-0.9985590742297593),
+ FX16_CONST(-0.05519524434968985), FX16_CONST(-0.9984755805732948),
+ FX16_CONST(-0.05672682116690782), FX16_CONST(-0.9983897374073402),
+ FX16_CONST(-0.05825826450043555), FX16_CONST(-0.9983015449338929),
+ FX16_CONST(-0.05978957074663983), FX16_CONST(-0.9982110033604782),
+ FX16_CONST(-0.061320736302208245), FX16_CONST(-0.9981181129001492),
+ FX16_CONST(-0.06285175756416124), FX16_CONST(-0.9980228737714862),
+ FX16_CONST(-0.06438263092985745), FX16_CONST(-0.997925286198596),
+ FX16_CONST(-0.06591335279700353), FX16_CONST(-0.9978253504111116),
+ FX16_CONST(-0.06744391956366393), FX16_CONST(-0.9977230666441916),
+ FX16_CONST(-0.06897432762826677), FX16_CONST(-0.9976184351385196),
+ FX16_CONST(-0.0705045733896136), FX16_CONST(-0.9975114561403035),
+ FX16_CONST(-0.07203465324688924), FX16_CONST(-0.9974021299012753),
+ FX16_CONST(-0.0735645635996675), FX16_CONST(-0.9972904566786902),
+ FX16_CONST(-0.0750943008479211), FX16_CONST(-0.9971764367353262),
+ FX16_CONST(-0.07662386139203144), FX16_CONST(-0.997060070339483),
+ FX16_CONST(-0.0781532416327939), FX16_CONST(-0.9969413577649822),
+ FX16_CONST(-0.07968243797142995), FX16_CONST(-0.9968202992911658),
+ FX16_CONST(-0.08121144680959243), FX16_CONST(-0.9966968952028961),
+ FX16_CONST(-0.0827402645493754), FX16_CONST(-0.9965711457905548),
+ FX16_CONST(-0.08426888759332393), FX16_CONST(-0.9964430513500426),
+ FX16_CONST(-0.08579731234443992), FX16_CONST(-0.996312612182778),
+ FX16_CONST(-0.08732553520619181), FX16_CONST(-0.996179828595697),
+ FX16_CONST(-0.0888535525825245), FX16_CONST(-0.996044700901252),
+ FX16_CONST(-0.09038136087786505), FX16_CONST(-0.9959072294174117),
+ FX16_CONST(-0.09190895649713252), FX16_CONST(-0.9957674144676598),
+ FX16_CONST(-0.09343633584574773), FX16_CONST(-0.9956252563809943),
+ FX16_CONST(-0.09496349532963866), FX16_CONST(-0.9954807554919269),
+ FX16_CONST(-0.09649043135525241), FX16_CONST(-0.9953339121404823),
+ FX16_CONST(-0.09801714032956059), FX16_CONST(-0.9951847266721969),
+ FX16_CONST(-0.09954361866006904), FX16_CONST(-0.9950331994381186),
+ FX16_CONST(-0.10106986275482768), FX16_CONST(-0.9948793307948056),
+ FX16_CONST(-0.10259586902243631), FX16_CONST(-0.9947231211043257),
+ FX16_CONST(-0.10412163387205432), FX16_CONST(-0.9945645707342555),
+ FX16_CONST(-0.10564715371341052), FX16_CONST(-0.9944036800576791),
+ FX16_CONST(-0.10717242495680891), FX16_CONST(-0.9942404494531879),
+ FX16_CONST(-0.1086974440131385), FX16_CONST(-0.9940748793048795),
+ FX16_CONST(-0.110222207293883), FX16_CONST(-0.9939069700023561),
+ FX16_CONST(-0.11174671121112625), FX16_CONST(-0.9937367219407247),
+ FX16_CONST(-0.11327095217756417), FX16_CONST(-0.9935641355205953),
+ FX16_CONST(-0.11479492660651007), FX16_CONST(-0.9933892111480807),
+ FX16_CONST(-0.11631863091190447), FX16_CONST(-0.9932119492347946),
+ FX16_CONST(-0.11784206150832484), FX16_CONST(-0.9930323501978514),
+ FX16_CONST(-0.11936521481099138), FX16_CONST(-0.9928504144598651),
+ FX16_CONST(-0.12088808723577682), FX16_CONST(-0.992666142448948),
+ FX16_CONST(-0.1224106751992161), FX16_CONST(-0.99247953459871),
+ FX16_CONST(-0.12393297511851223), FX16_CONST(-0.9922905913482574),
+ FX16_CONST(-0.125454983411546), FX16_CONST(-0.9920993131421918),
+ FX16_CONST(-0.1269766964968858), FX16_CONST(-0.9919057004306093),
+ FX16_CONST(-0.12849811079379284), FX16_CONST(-0.9917097536690995),
+ FX16_CONST(-0.13001922272223318), FX16_CONST(-0.991511473318744),
+ FX16_CONST(-0.1315400287028831), FX16_CONST(-0.9913108598461154),
+ FX16_CONST(-0.13306052515713876), FX16_CONST(-0.9911079137232769),
+ FX16_CONST(-0.13458070850712606), FX16_CONST(-0.99090263542778),
+ FX16_CONST(-0.13610057517570623), FX16_CONST(-0.9906950254426646),
+ FX16_CONST(-0.1376201215864858), FX16_CONST(-0.9904850842564571),
+ FX16_CONST(-0.13913934416382612), FX16_CONST(-0.9902728123631691),
+ FX16_CONST(-0.1406582393328493), FX16_CONST(-0.9900582102622971),
+ FX16_CONST(-0.14217680351944784), FX16_CONST(-0.9898412784588205),
+ FX16_CONST(-0.1436950331502944), FX16_CONST(-0.9896220174632009),
+ FX16_CONST(-0.14521292465284713), FX16_CONST(-0.9894004277913804),
+ FX16_CONST(-0.14673047445536158), FX16_CONST(-0.989176509964781),
+ FX16_CONST(-0.14824767898689603), FX16_CONST(-0.988950264510303),
+ FX16_CONST(-0.1497645346773212), FX16_CONST(-0.9887216919603238),
+ FX16_CONST(-0.15128103795733008), FX16_CONST(-0.9884907928526967),
+ FX16_CONST(-0.15279718525844344), FX16_CONST(-0.9882575677307495),
+ FX16_CONST(-0.15431297301301983), FX16_CONST(-0.9880220171432836),
+ FX16_CONST(-0.15582839765426512), FX16_CONST(-0.9877841416445722),
+ FX16_CONST(-0.1573434556162383), FX16_CONST(-0.9875439417943592),
+ FX16_CONST(-0.15885814333386122), FX16_CONST(-0.9873014181578584),
+ FX16_CONST(-0.1603724572429282), FX16_CONST(-0.987056571305751),
+ FX16_CONST(-0.1618863937801115), FX16_CONST(-0.9868094018141855),
+ FX16_CONST(-0.16339994938297306), FX16_CONST(-0.9865599102647755),
+ FX16_CONST(-0.1649131204899699), FX16_CONST(-0.9863080972445987),
+ FX16_CONST(-0.16642590354046383), FX16_CONST(-0.9860539633461954),
+ FX16_CONST(-0.16793829497473103), FX16_CONST(-0.9857975091675675),
+ FX16_CONST(-0.169450291233968), FX16_CONST(-0.9855387353121761),
+ FX16_CONST(-0.17096188876030097), FX16_CONST(-0.9852776423889413),
+ FX16_CONST(-0.17247308399679587), FX16_CONST(-0.9850142310122398),
+ FX16_CONST(-0.17398387338746388), FX16_CONST(-0.9847485018019042),
+ FX16_CONST(-0.1754942533772712), FX16_CONST(-0.9844804553832209),
+ FX16_CONST(-0.1770042204121487), FX16_CONST(-0.9842100923869291),
+ FX16_CONST(-0.17851377093899717), FX16_CONST(-0.9839374134492189),
+ FX16_CONST(-0.18002290140569935), FX16_CONST(-0.9836624192117303),
+ FX16_CONST(-0.18153160826112497), FX16_CONST(-0.9833851103215512),
+ FX16_CONST(-0.18303988795514065), FX16_CONST(-0.9831054874312164),
+ FX16_CONST(-0.18454773693861948), FX16_CONST(-0.9828235511987053),
+ FX16_CONST(-0.18605515166344666), FX16_CONST(-0.9825393022874412),
+ FX16_CONST(-0.18756212858252932), FX16_CONST(-0.9822527413662895),
+ FX16_CONST(-0.1890686641498061), FX16_CONST(-0.9819638691095552),
+ FX16_CONST(-0.19057475482025282), FX16_CONST(-0.9816726861969831),
+ FX16_CONST(-0.19208039704989222), FX16_CONST(-0.9813791933137547),
+ FX16_CONST(-0.19358558729580355), FX16_CONST(-0.9810833911504867),
+ FX16_CONST(-0.19509032201612836), FX16_CONST(-0.9807852804032304),
+ FX16_CONST(-0.19659459767008003), FX16_CONST(-0.9804848617734694),
+ FX16_CONST(-0.19809841071795356), FX16_CONST(-0.9801821359681174),
+ FX16_CONST(-0.19960175762113067), FX16_CONST(-0.9798771036995177),
+ FX16_CONST(-0.20110463484209176), FX16_CONST(-0.9795697656854405),
+ FX16_CONST(-0.20260703884442113), FX16_CONST(-0.979260122649082),
+ FX16_CONST(-0.20410896609281662), FX16_CONST(-0.9789481753190622),
+ FX16_CONST(-0.20561041305309916), FX16_CONST(-0.9786339244294232),
+ FX16_CONST(-0.2071113761922186), FX16_CONST(-0.9783173707196277),
+ FX16_CONST(-0.20861185197826326), FX16_CONST(-0.9779985149345571),
+ FX16_CONST(-0.21011183688046955), FX16_CONST(-0.97767735782451),
+ FX16_CONST(-0.21161132736922766), FX16_CONST(-0.9773539001452),
+ FX16_CONST(-0.2131103199160912), FX16_CONST(-0.9770281426577544),
+ FX16_CONST(-0.21460881099378673), FX16_CONST(-0.9767000861287118),
+ FX16_CONST(-0.21610679707621921), FX16_CONST(-0.9763697313300213),
+ FX16_CONST(-0.21760427463848347), FX16_CONST(-0.9760370790390391),
+ FX16_CONST(-0.2191012401568698), FX16_CONST(-0.9757021300385286),
+ FX16_CONST(-0.22059769010887326), FX16_CONST(-0.975364885116657),
+ FX16_CONST(-0.22209362097320343), FX16_CONST(-0.9750253450669941),
+ FX16_CONST(-0.22358902922979004), FX16_CONST(-0.9746835106885107),
+ FX16_CONST(-0.2250839113597926), FX16_CONST(-0.9743393827855759),
+ FX16_CONST(-0.22657826384560992), FX16_CONST(-0.973992962167956),
+ FX16_CONST(-0.22807208317088581), FX16_CONST(-0.9736442496508119),
+ FX16_CONST(-0.2295653658205187), FX16_CONST(-0.9732932460546982),
+ FX16_CONST(-0.23105810828067108), FX16_CONST(-0.9729399522055602),
+ FX16_CONST(-0.23255030703877494), FX16_CONST(-0.9725843689347323),
+ FX16_CONST(-0.23404195858354326), FX16_CONST(-0.9722264970789364),
+ FX16_CONST(-0.23553305940497551), FX16_CONST(-0.9718663374802794),
+ FX16_CONST(-0.23702360599436695), FX16_CONST(-0.9715038909862519),
+ FX16_CONST(-0.2385135948443183), FX16_CONST(-0.9711391584497252),
+ FX16_CONST(-0.24000302244874153), FX16_CONST(-0.9707721407289502),
+ FX16_CONST(-0.2414918853028691), FX16_CONST(-0.9704028386875555),
+ FX16_CONST(-0.24298017990326382), FX16_CONST(-0.970031253194544),
+ FX16_CONST(-0.24446790274782426), FX16_CONST(-0.9696573851242924),
+ FX16_CONST(-0.24595505033579443), FX16_CONST(-0.9692812353565485),
+ FX16_CONST(-0.24744161916777327), FX16_CONST(-0.9689028047764289),
+ FX16_CONST(-0.24892760574571987), FX16_CONST(-0.9685220942744174),
+ FX16_CONST(-0.2504130065729651), FX16_CONST(-0.9681391047463624),
+ FX16_CONST(-0.25189781815421697), FX16_CONST(-0.9677538370934755),
+ FX16_CONST(-0.2533820369955699), FX16_CONST(-0.9673662922223286),
+ FX16_CONST(-0.25486565960451446), FX16_CONST(-0.9669764710448522),
+ FX16_CONST(-0.2563486824899429), FX16_CONST(-0.9665843744783331),
+ FX16_CONST(-0.25783110216215877), FX16_CONST(-0.9661900034454126),
+ FX16_CONST(-0.2593129151328862), FX16_CONST(-0.9657933588740837),
+ FX16_CONST(-0.2607941179152756), FX16_CONST(-0.9653944416976894),
+ FX16_CONST(-0.2622747070239134), FX16_CONST(-0.9649932528549204),
+ FX16_CONST(-0.26375467897483135), FX16_CONST(-0.9645897932898128),
+ FX16_CONST(-0.2652340302855115), FX16_CONST(-0.9641840639517458),
+ FX16_CONST(-0.26671275747489825), FX16_CONST(-0.96377606579544),
+ FX16_CONST(-0.2681908570634032), FX16_CONST(-0.963365799780954),
+ FX16_CONST(-0.2696683255729148), FX16_CONST(-0.962953266873684),
+ FX16_CONST(-0.2711451595268079), FX16_CONST(-0.9625384680443592),
+ FX16_CONST(-0.27262135544994903), FX16_CONST(-0.9621214042690416),
+ FX16_CONST(-0.27409690986870616), FX16_CONST(-0.9617020765291227),
+ FX16_CONST(-0.2755718193109581), FX16_CONST(-0.9612804858113206),
+ FX16_CONST(-0.2770460803061), FX16_CONST(-0.9608566331076795),
+ FX16_CONST(-0.2785196893850529), FX16_CONST(-0.9604305194155659),
+ FX16_CONST(-0.2799926430802732), FX16_CONST(-0.960002145737666),
+ FX16_CONST(-0.28146493792575766), FX16_CONST(-0.9595715130819846),
+ FX16_CONST(-0.28293657045705517), FX16_CONST(-0.959138622461842),
+ FX16_CONST(-0.2844075372112718), FX16_CONST(-0.9587034748958716),
+ FX16_CONST(-0.28587783472708034), FX16_CONST(-0.9582660714080178),
+ FX16_CONST(-0.2873474595447294), FX16_CONST(-0.9578264130275329),
+ FX16_CONST(-0.28881640820604954), FX16_CONST(-0.9573845007889759),
+ FX16_CONST(-0.2902846772544621), FX16_CONST(-0.9569403357322089),
+ FX16_CONST(-0.2917522632349892), FX16_CONST(-0.9564939189023951),
+ FX16_CONST(-0.29321916269425874), FX16_CONST(-0.9560452513499964),
+ FX16_CONST(-0.29468537218051416), FX16_CONST(-0.9555943341307711),
+ FX16_CONST(-0.2961508882436238), FX16_CONST(-0.9551411683057708),
+ FX16_CONST(-0.2976157074350859), FX16_CONST(-0.9546857549413384),
+ FX16_CONST(-0.2990798263080403), FX16_CONST(-0.9542280951091057),
+ FX16_CONST(-0.30054324141727345), FX16_CONST(-0.9537681898859903),
+ FX16_CONST(-0.3020059493192278), FX16_CONST(-0.953306040354194),
+ FX16_CONST(-0.3034679465720112), FX16_CONST(-0.9528416476011987),
+ FX16_CONST(-0.30492922973540243), FX16_CONST(-0.9523750127197659),
+ FX16_CONST(-0.3063897953708607), FX16_CONST(-0.9519061368079323),
+ FX16_CONST(-0.3078496400415348), FX16_CONST(-0.9514350209690083),
+ FX16_CONST(-0.3093087603122688), FX16_CONST(-0.9509616663115751),
+ FX16_CONST(-0.3107671527496113), FX16_CONST(-0.9504860739494818),
+ FX16_CONST(-0.3122248139218249), FX16_CONST(-0.950008245001843),
+ FX16_CONST(-0.3136817403988912), FX16_CONST(-0.9495281805930368),
+ FX16_CONST(-0.3151379287525222), FX16_CONST(-0.9490458818527007),
+ FX16_CONST(-0.31659337555616585), FX16_CONST(-0.9485613499157303),
+ FX16_CONST(-0.31804807738501467), FX16_CONST(-0.9480745859222763),
+ FX16_CONST(-0.3195020308160156), FX16_CONST(-0.9475855910177412),
+ FX16_CONST(-0.32095523242787527), FX16_CONST(-0.9470943663527772),
+ FX16_CONST(-0.32240767880106963), FX16_CONST(-0.9466009130832836),
+ FX16_CONST(-0.3238593665178528), FX16_CONST(-0.9461052323704034),
+ FX16_CONST(-0.325310292162263), FX16_CONST(-0.9456073253805213),
+ FX16_CONST(-0.32676045232013157), FX16_CONST(-0.9451071932852606),
+ FX16_CONST(-0.3282098435790925), FX16_CONST(-0.9446048372614803),
+ FX16_CONST(-0.3296584625285872), FX16_CONST(-0.9441002584912728),
+ FX16_CONST(-0.33110630575987626), FX16_CONST(-0.9435934581619604),
+ FX16_CONST(-0.3325533698660442), FX16_CONST(-0.9430844374660935),
+ FX16_CONST(-0.3339996514420091), FX16_CONST(-0.942573197601447),
+ FX16_CONST(-0.3354451470845315), FX16_CONST(-0.9420597397710174),
+ FX16_CONST(-0.3368898533922201), FX16_CONST(-0.9415440651830208),
+ FX16_CONST(-0.3383337669655409), FX16_CONST(-0.9410261750508894),
+ FX16_CONST(-0.3397768844068268), FX16_CONST(-0.9405060705932684),
+ FX16_CONST(-0.34121920232028247), FX16_CONST(-0.9399837530340139),
+ FX16_CONST(-0.3426607173119942), FX16_CONST(-0.93945922360219),
+ FX16_CONST(-0.3441014259899388), FX16_CONST(-0.9389324835320646),
+ FX16_CONST(-0.34554132496398876), FX16_CONST(-0.9384035340631083),
+ FX16_CONST(-0.3469804108459235), FX16_CONST(-0.9378723764399899),
+ FX16_CONST(-0.34841868024943456), FX16_CONST(-0.937339011912575),
+ FX16_CONST(-0.34985612979013464), FX16_CONST(-0.9368034417359217),
+ FX16_CONST(-0.351292756085567), FX16_CONST(-0.9362656671702783),
+ FX16_CONST(-0.3527285557552107), FX16_CONST(-0.9357256894810804),
+ FX16_CONST(-0.3541635254204901), FX16_CONST(-0.9351835099389477),
+ FX16_CONST(-0.3555976617047838), FX16_CONST(-0.9346391298196808),
+ FX16_CONST(-0.3570309612334301), FX16_CONST(-0.9340925504042589),
+ FX16_CONST(-0.3584634206337364), FX16_CONST(-0.9335437729788363),
+ FX16_CONST(-0.3598950365349881), FX16_CONST(-0.932992798834739),
+ FX16_CONST(-0.36132580556845395), FX16_CONST(-0.9324396292684625),
+ FX16_CONST(-0.36275572436739706), FX16_CONST(-0.9318842655816681),
+ FX16_CONST(-0.3641847895670799), FX16_CONST(-0.9313267090811804),
+ FX16_CONST(-0.3656129978047736), FX16_CONST(-0.9307669610789838),
+ FX16_CONST(-0.36704034571976707), FX16_CONST(-0.9302050228922191),
+ FX16_CONST(-0.3684668299533724), FX16_CONST(-0.9296408958431812),
+ FX16_CONST(-0.3698924471489339), FX16_CONST(-0.9290745812593159),
+ FX16_CONST(-0.37131719395183743), FX16_CONST(-0.9285060804732156),
+ FX16_CONST(-0.37274106700951587), FX16_CONST(-0.9279353948226178),
+ FX16_CONST(-0.3741640629714578), FX16_CONST(-0.9273625256504011),
+ FX16_CONST(-0.37558617848921716), FX16_CONST(-0.9267874743045819),
+ FX16_CONST(-0.3770074102164179), FX16_CONST(-0.9262102421383115),
+ FX16_CONST(-0.3784277548087654), FX16_CONST(-0.9256308305098728),
+ FX16_CONST(-0.37984720892405116), FX16_CONST(-0.9250492407826776),
+ FX16_CONST(-0.3812657692221621), FX16_CONST(-0.9244654743252627),
+ FX16_CONST(-0.38268343236508967), FX16_CONST(-0.9238795325112868),
+ FX16_CONST(-0.3841001950169351), FX16_CONST(-0.9232914167195276),
+ FX16_CONST(-0.3855160538439186), FX16_CONST(-0.9227011283338786),
+ FX16_CONST(-0.3869310055143885), FX16_CONST(-0.9221086687433452),
+ FX16_CONST(-0.38834504669882636), FX16_CONST(-0.9215140393420419),
+ FX16_CONST(-0.38975817406985624), FX16_CONST(-0.9209172415291895),
+ FX16_CONST(-0.3911703843022538), FX16_CONST(-0.9203182767091106),
+ FX16_CONST(-0.3925816740729512), FX16_CONST(-0.9197171462912275),
+ FX16_CONST(-0.39399204006104793), FX16_CONST(-0.9191138516900578),
+ FX16_CONST(-0.3954014789478163), FX16_CONST(-0.9185083943252123),
+ FX16_CONST(-0.39680998741671003), FX16_CONST(-0.9179007756213906),
+ FX16_CONST(-0.39821756215337345), FX16_CONST(-0.917290997008378),
+ FX16_CONST(-0.39962419984564684), FX16_CONST(-0.9166790599210427),
+ FX16_CONST(-0.4010298971835754), FX16_CONST(-0.9160649657993318),
+ FX16_CONST(-0.4024346508594184), FX16_CONST(-0.9154487160882678),
+ FX16_CONST(-0.4038384575676542), FX16_CONST(-0.9148303122379461),
+ FX16_CONST(-0.4052413140049897), FX16_CONST(-0.9142097557035307),
+ FX16_CONST(-0.406643216870369), FX16_CONST(-0.9135870479452508),
+ FX16_CONST(-0.40804416286497835), FX16_CONST(-0.9129621904283983),
+ FX16_CONST(-0.4094441486922574), FX16_CONST(-0.9123351846233229),
+ FX16_CONST(-0.4108431710579039), FX16_CONST(-0.9117060320054299),
+ FX16_CONST(-0.4122412266698826), FX16_CONST(-0.9110747340551765),
+ FX16_CONST(-0.4136383122384344), FX16_CONST(-0.9104412922580672),
+ FX16_CONST(-0.41503442447608163), FX16_CONST(-0.9098057081046522),
+ FX16_CONST(-0.41642956009763693), FX16_CONST(-0.9091679830905225),
+ FX16_CONST(-0.4178237158202122), FX16_CONST(-0.9085281187163061),
+ FX16_CONST(-0.419216888363224), FX16_CONST(-0.9078861164876662),
+ FX16_CONST(-0.42060907444840234), FX16_CONST(-0.9072419779152959),
+ FX16_CONST(-0.4220002707997996), FX16_CONST(-0.9065957045149154),
+ FX16_CONST(-0.4233904741437957), FX16_CONST(-0.9059472978072686),
+ FX16_CONST(-0.42477968120910864), FX16_CONST(-0.9052967593181188),
+ FX16_CONST(-0.4261678887267996), FX16_CONST(-0.9046440905782462),
+ FX16_CONST(-0.4275550934302818), FX16_CONST(-0.9039892931234434),
+ FX16_CONST(-0.4289412920553294), FX16_CONST(-0.9033323684945119),
+ FX16_CONST(-0.43032648134008267), FX16_CONST(-0.9026733182372588),
+ FX16_CONST(-0.43171065802505704), FX16_CONST(-0.9020121439024933),
+ FX16_CONST(-0.43309381885315185), FX16_CONST(-0.901348847046022),
+ FX16_CONST(-0.43447596056965576), FX16_CONST(-0.9006834292286469),
+ FX16_CONST(-0.4358570799222553), FX16_CONST(-0.9000158920161603),
+ FX16_CONST(-0.43723717366104403), FX16_CONST(-0.8993462369793416),
+ FX16_CONST(-0.4386162385385273), FX16_CONST(-0.898674465693954),
+ FX16_CONST(-0.4399942713096331), FX16_CONST(-0.8980005797407399),
+ FX16_CONST(-0.44137126873171667), FX16_CONST(-0.8973245807054183),
+ FX16_CONST(-0.44274722756456975), FX16_CONST(-0.8966464701786804),
+ FX16_CONST(-0.4441221445704291), FX16_CONST(-0.8959662497561852),
+ FX16_CONST(-0.44549601651398174), FX16_CONST(-0.8952839210385575),
+ FX16_CONST(-0.44686884016237394), FX16_CONST(-0.8945994856313828),
+ FX16_CONST(-0.44824061228521983), FX16_CONST(-0.8939129451452033),
+ FX16_CONST(-0.44961132965460665), FX16_CONST(-0.8932243011955153),
+ FX16_CONST(-0.45098098904510364), FX16_CONST(-0.8925335554027647),
+ FX16_CONST(-0.45234958723377083), FX16_CONST(-0.8918407093923427),
+ FX16_CONST(-0.45371712100016354), FX16_CONST(-0.8911457647945834),
+ FX16_CONST(-0.45508358712634367), FX16_CONST(-0.890448723244758),
+ FX16_CONST(-0.4564489823968839), FX16_CONST(-0.8897495863830728),
+ FX16_CONST(-0.45781330359887695), FX16_CONST(-0.8890483558546647),
+ FX16_CONST(-0.459176547521944), FX16_CONST(-0.8883450333095964),
+ FX16_CONST(-0.46053871095824006), FX16_CONST(-0.8876396204028539),
+ FX16_CONST(-0.4618997907024625), FX16_CONST(-0.8869321187943423),
+ FX16_CONST(-0.4632597835518601), FX16_CONST(-0.8862225301488806),
+ FX16_CONST(-0.46461868630623787), FX16_CONST(-0.8855108561362),
+ FX16_CONST(-0.46597649576796596), FX16_CONST(-0.8847970984309379),
+ FX16_CONST(-0.46733320874198836), FX16_CONST(-0.884081258712635),
+ FX16_CONST(-0.4686888220358276), FX16_CONST(-0.8833633386657318),
+ FX16_CONST(-0.47004333245959545), FX16_CONST(-0.8826433399795629),
+ FX16_CONST(-0.47139673682599764), FX16_CONST(-0.881921264348355),
+ FX16_CONST(-0.4727490319503425), FX16_CONST(-0.8811971134712222),
+ FX16_CONST(-0.47410021465054986), FX16_CONST(-0.8804708890521609),
+ FX16_CONST(-0.47545028174715587), FX16_CONST(-0.8797425928000474),
+ FX16_CONST(-0.47679923006332187), FX16_CONST(-0.8790122264286336),
+ FX16_CONST(-0.47814705642484295), FX16_CONST(-0.8782797916565416),
+ FX16_CONST(-0.47949375766015306), FX16_CONST(-0.8775452902072612),
+ FX16_CONST(-0.48083933060033374), FX16_CONST(-0.8768087238091458),
+ FX16_CONST(-0.48218377207912266), FX16_CONST(-0.8760700941954066),
+ FX16_CONST(-0.4835270789329184), FX16_CONST(-0.875329403104111),
+ FX16_CONST(-0.48486924800079095), FX16_CONST(-0.8745866522781762),
+ FX16_CONST(-0.48621027612448636), FX16_CONST(-0.8738418434653669),
+ FX16_CONST(-0.48755016014843566), FX16_CONST(-0.8730949784182902),
+ FX16_CONST(-0.48888889691976306), FX16_CONST(-0.8723460588943915),
+ FX16_CONST(-0.49022648328829116), FX16_CONST(-0.8715950866559511),
+ FX16_CONST(-0.4915629161065497), FX16_CONST(-0.8708420634700791),
+ FX16_CONST(-0.4928981922297839), FX16_CONST(-0.8700869911087115),
+ FX16_CONST(-0.4942323085159598), FX16_CONST(-0.8693298713486067),
+ FX16_CONST(-0.4955652618257723), FX16_CONST(-0.868570705971341),
+ FX16_CONST(-0.49689704902265447), FX16_CONST(-0.8678094967633033),
+ FX16_CONST(-0.49822766697278154), FX16_CONST(-0.8670462455156929),
+ FX16_CONST(-0.4995571125450817), FX16_CONST(-0.8662809540245131),
+ FX16_CONST(-0.5008853826112407), FX16_CONST(-0.8655136240905691),
+ FX16_CONST(-0.5022124740457106), FX16_CONST(-0.8647442575194625),
+ FX16_CONST(-0.5035383837257175), FX16_CONST(-0.8639728561215868),
+ FX16_CONST(-0.5048631085312676), FX16_CONST(-0.8631994217121242),
+ FX16_CONST(-0.506186645345155), FX16_CONST(-0.8624239561110407),
+ FX16_CONST(-0.5075089910529708), FX16_CONST(-0.8616464611430814),
+ FX16_CONST(-0.5088301425431071), FX16_CONST(-0.8608669386377673),
+ FX16_CONST(-0.5101500967067666), FX16_CONST(-0.8600853904293903),
+ FX16_CONST(-0.5114688504379703), FX16_CONST(-0.8593018183570085),
+ FX16_CONST(-0.5127864006335627), FX16_CONST(-0.858516224264443),
+ FX16_CONST(-0.5141027441932216), FX16_CONST(-0.8577286100002721),
+ FX16_CONST(-0.5154178780194629), FX16_CONST(-0.8569389774178288),
+ FX16_CONST(-0.5167317990176497), FX16_CONST(-0.8561473283751947),
+ FX16_CONST(-0.5180445040959992), FX16_CONST(-0.8553536647351961),
+ FX16_CONST(-0.5193559901655895), FX16_CONST(-0.8545579883654005),
+ FX16_CONST(-0.5206662541403669), FX16_CONST(-0.8537603011381115),
+ FX16_CONST(-0.5219752929371543), FX16_CONST(-0.8529606049303637),
+ FX16_CONST(-0.5232831034756564), FX16_CONST(-0.8521589016239198),
+ FX16_CONST(-0.5245896826784687), FX16_CONST(-0.8513551931052653),
+ FX16_CONST(-0.5258950274710846), FX16_CONST(-0.8505494812656035),
+ FX16_CONST(-0.5271991347819011), FX16_CONST(-0.8497417680008527),
+ FX16_CONST(-0.5285020015422283), FX16_CONST(-0.8489320552116397),
+ FX16_CONST(-0.5298036246862946), FX16_CONST(-0.8481203448032972),
+ FX16_CONST(-0.5311040011512547), FX16_CONST(-0.8473066386858585),
+ FX16_CONST(-0.5324031278771978), FX16_CONST(-0.8464909387740521),
+ FX16_CONST(-0.533701001807153), FX16_CONST(-0.8456732469872991),
+ FX16_CONST(-0.5349976198870969), FX16_CONST(-0.8448535652497072),
+ FX16_CONST(-0.5362929790659631), FX16_CONST(-0.8440318954900665),
+ FX16_CONST(-0.5375870762956455), FX16_CONST(-0.8432082396418454),
+ FX16_CONST(-0.5388799085310082), FX16_CONST(-0.842382599643186),
+ FX16_CONST(-0.5401714727298929), FX16_CONST(-0.8415549774368984),
+ FX16_CONST(-0.5414617658531232), FX16_CONST(-0.8407253749704582),
+ FX16_CONST(-0.5427507848645158), FX16_CONST(-0.8398937941959996),
+ FX16_CONST(-0.5440385267308838), FX16_CONST(-0.8390602370703127),
+ FX16_CONST(-0.5453249884220461), FX16_CONST(-0.8382247055548382),
+ FX16_CONST(-0.5466101669108347), FX16_CONST(-0.837387201615662),
+ FX16_CONST(-0.5478940591731002), FX16_CONST(-0.836547727223512),
+ FX16_CONST(-0.5491766621877194), FX16_CONST(-0.8357062843537527),
+ FX16_CONST(-0.5504579729366047), FX16_CONST(-0.8348628749863801),
+ FX16_CONST(-0.5517379884047074), FX16_CONST(-0.8340175011060181),
+ FX16_CONST(-0.5530167055800274), FX16_CONST(-0.8331701647019133),
+ FX16_CONST(-0.55429412145362), FX16_CONST(-0.8323208677679297),
+ FX16_CONST(-0.555570233019602), FX16_CONST(-0.8314696123025455),
+ FX16_CONST(-0.5568450372751599), FX16_CONST(-0.8306164003088464),
+ FX16_CONST(-0.5581185312205561), FX16_CONST(-0.829761233794523),
+ FX16_CONST(-0.5593907118591358), FX16_CONST(-0.8289041147718651),
+ FX16_CONST(-0.5606615761973359), FX16_CONST(-0.8280450452577559),
+ FX16_CONST(-0.5619311212446894), FX16_CONST(-0.8271840272736691),
+ FX16_CONST(-0.5631993440138339), FX16_CONST(-0.8263210628456636),
+ FX16_CONST(-0.5644662415205194), FX16_CONST(-0.8254561540043776),
+ FX16_CONST(-0.5657318107836132), FX16_CONST(-0.8245893027850253),
+ FX16_CONST(-0.5669960488251085), FX16_CONST(-0.8237205112273915),
+ FX16_CONST(-0.5682589526701315), FX16_CONST(-0.8228497813758264),
+ FX16_CONST(-0.5695205193469473), FX16_CONST(-0.8219771152792416),
+ FX16_CONST(-0.5707807458869671), FX16_CONST(-0.8211025149911048),
+ FX16_CONST(-0.572039629324757), FX16_CONST(-0.8202259825694347),
+ FX16_CONST(-0.573297166698042), FX16_CONST(-0.8193475200767971),
+ FX16_CONST(-0.5745533550477157), FX16_CONST(-0.8184671295802988),
+ FX16_CONST(-0.5758081914178453), FX16_CONST(-0.8175848131515837),
+ FX16_CONST(-0.5770616728556793), FX16_CONST(-0.816700572866828),
+ FX16_CONST(-0.5783137964116555), FX16_CONST(-0.8158144108067339),
+ FX16_CONST(-0.5795645591394057), FX16_CONST(-0.8149263290565266),
+ FX16_CONST(-0.5808139580957643), FX16_CONST(-0.8140363297059485),
+ FX16_CONST(-0.5820619903407754), FX16_CONST(-0.8131444148492536),
+ FX16_CONST(-0.5833086529376983), FX16_CONST(-0.8122505865852039),
+ FX16_CONST(-0.5845539429530151), FX16_CONST(-0.8113548470170638),
+ FX16_CONST(-0.5857978574564389), FX16_CONST(-0.8104571982525949),
+ FX16_CONST(-0.5870403935209177), FX16_CONST(-0.8095576424040515),
+ FX16_CONST(-0.5882815482226451), FX16_CONST(-0.8086561815881751),
+ FX16_CONST(-0.5895213186410639), FX16_CONST(-0.8077528179261904),
+ FX16_CONST(-0.5907597018588739), FX16_CONST(-0.8068475535437994),
+ FX16_CONST(-0.5919966949620409), FX16_CONST(-0.8059403905711764),
+ FX16_CONST(-0.5932322950397998), FX16_CONST(-0.8050313311429635),
+ FX16_CONST(-0.5944664991846642), FX16_CONST(-0.8041203773982659),
+ FX16_CONST(-0.5956993044924332), FX16_CONST(-0.8032075314806449),
+ FX16_CONST(-0.5969307080621965), FX16_CONST(-0.8022927955381157),
+ FX16_CONST(-0.5981607069963422), FX16_CONST(-0.8013761717231404),
+ FX16_CONST(-0.5993892984005645), FX16_CONST(-0.8004576621926228),
+ FX16_CONST(-0.6006164793838686), FX16_CONST(-0.7995372691079052),
+ FX16_CONST(-0.6018422470585799), FX16_CONST(-0.7986149946347609),
+ FX16_CONST(-0.6030665985403482), FX16_CONST(-0.7976908409433912),
+ FX16_CONST(-0.6042895309481559), FX16_CONST(-0.7967648102084189),
+ FX16_CONST(-0.6055110414043254), FX16_CONST(-0.7958369046088836),
+ FX16_CONST(-0.6067311270345245), FX16_CONST(-0.794907126328237),
+ FX16_CONST(-0.6079497849677735), FX16_CONST(-0.7939754775543373),
+ FX16_CONST(-0.6091670123364531), FX16_CONST(-0.7930419604794438),
+ FX16_CONST(-0.6103828062763095), FX16_CONST(-0.7921065773002123),
+ FX16_CONST(-0.6115971639264618), FX16_CONST(-0.7911693302176903),
+ FX16_CONST(-0.6128100824294097), FX16_CONST(-0.79023022143731),
+ FX16_CONST(-0.6140215589310382), FX16_CONST(-0.7892892531688859),
+ FX16_CONST(-0.6152315905806267), FX16_CONST(-0.7883464276266063),
+ FX16_CONST(-0.6164401745308536), FX16_CONST(-0.7874017470290314),
+ FX16_CONST(-0.6176473079378038), FX16_CONST(-0.7864552135990859),
+ FX16_CONST(-0.6188529879609762), FX16_CONST(-0.785506829564054),
+ FX16_CONST(-0.6200572117632892), FX16_CONST(-0.7845565971555752),
+ FX16_CONST(-0.6212599765110874), FX16_CONST(-0.7836045186096384),
+ FX16_CONST(-0.6224612793741499), FX16_CONST(-0.7826505961665758),
+ FX16_CONST(-0.6236611175256946), FX16_CONST(-0.7816948320710594),
+ FX16_CONST(-0.6248594881423862), FX16_CONST(-0.7807372285720946),
+ FX16_CONST(-0.6260563884043435), FX16_CONST(-0.7797777879230146),
+ FX16_CONST(-0.6272518154951439), FX16_CONST(-0.7788165123814762),
+ FX16_CONST(-0.6284457666018326), FX16_CONST(-0.7778534042094533),
+ FX16_CONST(-0.629638238914927), FX16_CONST(-0.7768884656732324),
+ FX16_CONST(-0.6308292296284242), FX16_CONST(-0.7759216990434078),
+ FX16_CONST(-0.632018735939809), FX16_CONST(-0.7749531065948739),
+ FX16_CONST(-0.6332067550500573), FX16_CONST(-0.7739826906068228),
+ FX16_CONST(-0.6343932841636453), FX16_CONST(-0.7730104533627371),
+ FX16_CONST(-0.6355783204885561), FX16_CONST(-0.7720363971503845),
+ FX16_CONST(-0.6367618612362843), FX16_CONST(-0.7710605242618137),
+ FX16_CONST(-0.6379439036218439), FX16_CONST(-0.7700828369933481),
+ FX16_CONST(-0.6391244448637757), FX16_CONST(-0.7691033376455797),
+ FX16_CONST(-0.6403034821841515), FX16_CONST(-0.7681220285233656),
+ FX16_CONST(-0.641481012808583), FX16_CONST(-0.7671389119358205),
+ FX16_CONST(-0.6426570339662269), FX16_CONST(-0.7661539901963129),
+ FX16_CONST(-0.6438315428897913), FX16_CONST(-0.7651672656224591),
+ FX16_CONST(-0.6450045368155438), FX16_CONST(-0.7641787405361168),
+ FX16_CONST(-0.6461760129833164), FX16_CONST(-0.7631884172633813),
+ FX16_CONST(-0.6473459686365118), FX16_CONST(-0.7621962981345791),
+ FX16_CONST(-0.6485144010221123), FX16_CONST(-0.7612023854842619),
+ FX16_CONST(-0.6496813073906832), FX16_CONST(-0.7602066816512024),
+ FX16_CONST(-0.6508466849963808), FX16_CONST(-0.7592091889783882),
+ FX16_CONST(-0.6520105310969595), FX16_CONST(-0.7582099098130154),
+ FX16_CONST(-0.6531728429537765), FX16_CONST(-0.7572088465064848),
+ FX16_CONST(-0.6543336178318003), FX16_CONST(-0.7562060014143946),
+ FX16_CONST(-0.6554928529996153), FX16_CONST(-0.7552013768965365),
+ FX16_CONST(-0.6566505457294288), FX16_CONST(-0.7541949753168894),
+ FX16_CONST(-0.6578066932970785), FX16_CONST(-0.7531867990436125),
+ FX16_CONST(-0.6589612929820373), FX16_CONST(-0.7521768504490427),
+ FX16_CONST(-0.6601143420674203), FX16_CONST(-0.7511651319096866),
+ FX16_CONST(-0.6612658378399922), FX16_CONST(-0.7501516458062151),
+ FX16_CONST(-0.6624157775901718), FX16_CONST(-0.7491363945234593),
+ FX16_CONST(-0.6635641586120397), FX16_CONST(-0.7481193804504037),
+ FX16_CONST(-0.6647109782033448), FX16_CONST(-0.7471006059801802),
+ FX16_CONST(-0.6658562336655094), FX16_CONST(-0.746080073510064),
+ FX16_CONST(-0.6669999223036374), FX16_CONST(-0.7450577854414661),
+ FX16_CONST(-0.6681420414265185), FX16_CONST(-0.7440337441799293),
+ FX16_CONST(-0.6692825883466358), FX16_CONST(-0.7430079521351219),
+ FX16_CONST(-0.670421560380173), FX16_CONST(-0.7419804117208311),
+ FX16_CONST(-0.6715589548470184), FX16_CONST(-0.7409511253549591),
+ FX16_CONST(-0.6726947690707727), FX16_CONST(-0.7399200954595163),
+ FX16_CONST(-0.6738290003787559), FX16_CONST(-0.7388873244606152),
+ FX16_CONST(-0.674961646102012), FX16_CONST(-0.737852814788466),
+ FX16_CONST(-0.6760927035753158), FX16_CONST(-0.73681656887737),
+ FX16_CONST(-0.6772221701371803), FX16_CONST(-0.7357785891657136),
+ FX16_CONST(-0.6783500431298612), FX16_CONST(-0.7347388780959637),
+ FX16_CONST(-0.6794763198993649), FX16_CONST(-0.7336974381146604),
+ FX16_CONST(-0.680600997795453), FX16_CONST(-0.7326542716724128),
+ FX16_CONST(-0.6817240741716496), FX16_CONST(-0.7316093812238927),
+ FX16_CONST(-0.682845546385248), FX16_CONST(-0.7305627692278277),
+ FX16_CONST(-0.6839654117973154), FX16_CONST(-0.729514438146997),
+ FX16_CONST(-0.6850836677727001), FX16_CONST(-0.7284643904482254),
+ FX16_CONST(-0.6862003116800385), FX16_CONST(-0.7274126286023759),
+ FX16_CONST(-0.6873153408917592), FX16_CONST(-0.7263591550843459),
+ FX16_CONST(-0.6884287527840903), FX16_CONST(-0.7253039723730609),
+ FX16_CONST(-0.6895405447370668), FX16_CONST(-0.724247082951467),
+ FX16_CONST(-0.6906507141345344), FX16_CONST(-0.7231884893065277),
+ FX16_CONST(-0.6917592583641576), FX16_CONST(-0.7221281939292155),
+ FX16_CONST(-0.6928661748174246), FX16_CONST(-0.7210661993145081),
+ FX16_CONST(-0.6939714608896538), FX16_CONST(-0.7200025079613819),
+ FX16_CONST(-0.6950751139800008), FX16_CONST(-0.7189371223728045),
+ FX16_CONST(-0.696177131491463), FX16_CONST(-0.7178700450557317),
+ FX16_CONST(-0.6972775108308864), FX16_CONST(-0.7168012785210996),
+ FX16_CONST(-0.6983762494089728), FX16_CONST(-0.7157308252838187),
+ FX16_CONST(-0.6994733446402839), FX16_CONST(-0.714658687862769),
+ FX16_CONST(-0.7005687939432482), FX16_CONST(-0.7135848687807937),
+ FX16_CONST(-0.7016625947401685), FX16_CONST(-0.7125093705646924),
+ FX16_CONST(-0.7027547444572251), FX16_CONST(-0.7114321957452167),
+ FX16_CONST(-0.7038452405244848), FX16_CONST(-0.7103533468570625),
+ FX16_CONST(-0.7049340803759049), FX16_CONST(-0.7092728264388657),
+ FX16_CONST(-0.7060212614493395), FX16_CONST(-0.7081906370331955),
+ FX16_CONST(-0.7071067811865475), FX16_CONST(-0.7071067811865477),
+ FX16_CONST(-0.7081906370331953), FX16_CONST(-0.7060212614493397),
+ FX16_CONST(-0.7092728264388655), FX16_CONST(-0.7049340803759051),
+ FX16_CONST(-0.7103533468570623), FX16_CONST(-0.703845240524485),
+ FX16_CONST(-0.7114321957452164), FX16_CONST(-0.7027547444572253),
+ FX16_CONST(-0.7125093705646922), FX16_CONST(-0.7016625947401687),
+ FX16_CONST(-0.7135848687807935), FX16_CONST(-0.7005687939432484),
+ FX16_CONST(-0.7146586878627688), FX16_CONST(-0.6994733446402841),
+ FX16_CONST(-0.7157308252838185), FX16_CONST(-0.698376249408973),
+ FX16_CONST(-0.7168012785210994), FX16_CONST(-0.6972775108308866),
+ FX16_CONST(-0.7178700450557315), FX16_CONST(-0.6961771314914632),
+ FX16_CONST(-0.7189371223728044), FX16_CONST(-0.695075113980001),
+ FX16_CONST(-0.7200025079613817), FX16_CONST(-0.693971460889654),
+ FX16_CONST(-0.7210661993145079), FX16_CONST(-0.6928661748174249),
+ FX16_CONST(-0.7221281939292152), FX16_CONST(-0.6917592583641579),
+ FX16_CONST(-0.7231884893065275), FX16_CONST(-0.6906507141345346),
+ FX16_CONST(-0.7242470829514668), FX16_CONST(-0.689540544737067),
+ FX16_CONST(-0.7253039723730607), FX16_CONST(-0.6884287527840905),
+ FX16_CONST(-0.7263591550843458), FX16_CONST(-0.6873153408917594),
+ FX16_CONST(-0.7274126286023757), FX16_CONST(-0.6862003116800387),
+ FX16_CONST(-0.7284643904482252), FX16_CONST(-0.6850836677727004),
+ FX16_CONST(-0.7295144381469968), FX16_CONST(-0.6839654117973156),
+ FX16_CONST(-0.7305627692278275), FX16_CONST(-0.6828455463852482),
+ FX16_CONST(-0.7316093812238925), FX16_CONST(-0.6817240741716498),
+ FX16_CONST(-0.7326542716724127), FX16_CONST(-0.6806009977954532),
+ FX16_CONST(-0.7336974381146601), FX16_CONST(-0.6794763198993651),
+ FX16_CONST(-0.7347388780959635), FX16_CONST(-0.6783500431298615),
+ FX16_CONST(-0.7357785891657134), FX16_CONST(-0.6772221701371806),
+ FX16_CONST(-0.7368165688773698), FX16_CONST(-0.676092703575316),
+ FX16_CONST(-0.7378528147884658), FX16_CONST(-0.6749616461020123),
+ FX16_CONST(-0.738887324460615), FX16_CONST(-0.6738290003787561),
+ FX16_CONST(-0.7399200954595161), FX16_CONST(-0.672694769070773),
+ FX16_CONST(-0.7409511253549589), FX16_CONST(-0.6715589548470187),
+ FX16_CONST(-0.741980411720831), FX16_CONST(-0.6704215603801732),
+ FX16_CONST(-0.7430079521351217), FX16_CONST(-0.669282588346636),
+ FX16_CONST(-0.7440337441799291), FX16_CONST(-0.6681420414265187),
+ FX16_CONST(-0.7450577854414658), FX16_CONST(-0.6669999223036376),
+ FX16_CONST(-0.7460800735100638), FX16_CONST(-0.6658562336655096),
+ FX16_CONST(-0.7471006059801799), FX16_CONST(-0.664710978203345),
+ FX16_CONST(-0.7481193804504035), FX16_CONST(-0.6635641586120399),
+ FX16_CONST(-0.749136394523459), FX16_CONST(-0.662415777590172),
+ FX16_CONST(-0.750151645806215), FX16_CONST(-0.6612658378399924),
+ FX16_CONST(-0.7511651319096864), FX16_CONST(-0.6601143420674205),
+ FX16_CONST(-0.7521768504490425), FX16_CONST(-0.6589612929820375),
+ FX16_CONST(-0.7531867990436124), FX16_CONST(-0.6578066932970787),
+ FX16_CONST(-0.7541949753168892), FX16_CONST(-0.656650545729429),
+ FX16_CONST(-0.7552013768965363), FX16_CONST(-0.6554928529996156),
+ FX16_CONST(-0.7562060014143944), FX16_CONST(-0.6543336178318007),
+ FX16_CONST(-0.7572088465064842), FX16_CONST(-0.6531728429537771),
+ FX16_CONST(-0.7582099098130151), FX16_CONST(-0.6520105310969597),
+ FX16_CONST(-0.759209188978388), FX16_CONST(-0.650846684996381),
+ FX16_CONST(-0.7602066816512024), FX16_CONST(-0.6496813073906831),
+ FX16_CONST(-0.761202385484262), FX16_CONST(-0.6485144010221122),
+ FX16_CONST(-0.7621962981345786), FX16_CONST(-0.6473459686365125),
+ FX16_CONST(-0.763188417263381), FX16_CONST(-0.6461760129833166),
+ FX16_CONST(-0.7641787405361166), FX16_CONST(-0.6450045368155441),
+ FX16_CONST(-0.765167265622459), FX16_CONST(-0.6438315428897915),
+ FX16_CONST(-0.766153990196313), FX16_CONST(-0.6426570339662268),
+ FX16_CONST(-0.7671389119358201), FX16_CONST(-0.6414810128085836),
+ FX16_CONST(-0.7681220285233652), FX16_CONST(-0.640303482184152),
+ FX16_CONST(-0.7691033376455795), FX16_CONST(-0.639124444863776),
+ FX16_CONST(-0.7700828369933479), FX16_CONST(-0.6379439036218442),
+ FX16_CONST(-0.7710605242618138), FX16_CONST(-0.6367618612362842),
+ FX16_CONST(-0.7720363971503846), FX16_CONST(-0.635578320488556),
+ FX16_CONST(-0.7730104533627367), FX16_CONST(-0.6343932841636459),
+ FX16_CONST(-0.7739826906068226), FX16_CONST(-0.6332067550500575),
+ FX16_CONST(-0.7749531065948738), FX16_CONST(-0.6320187359398092),
+ FX16_CONST(-0.7759216990434076), FX16_CONST(-0.6308292296284246),
+ FX16_CONST(-0.7768884656732326), FX16_CONST(-0.6296382389149269),
+ FX16_CONST(-0.7778534042094527), FX16_CONST(-0.6284457666018332),
+ FX16_CONST(-0.7788165123814756), FX16_CONST(-0.6272518154951444),
+ FX16_CONST(-0.7797777879230143), FX16_CONST(-0.6260563884043437),
+ FX16_CONST(-0.7807372285720944), FX16_CONST(-0.6248594881423865),
+ FX16_CONST(-0.7816948320710595), FX16_CONST(-0.6236611175256945),
+ FX16_CONST(-0.7826505961665758), FX16_CONST(-0.6224612793741497),
+ FX16_CONST(-0.7836045186096379), FX16_CONST(-0.621259976511088),
+ FX16_CONST(-0.784556597155575), FX16_CONST(-0.6200572117632894),
+ FX16_CONST(-0.7855068295640538), FX16_CONST(-0.6188529879609764),
+ FX16_CONST(-0.7864552135990858), FX16_CONST(-0.617647307937804),
+ FX16_CONST(-0.7874017470290315), FX16_CONST(-0.6164401745308535),
+ FX16_CONST(-0.7883464276266059), FX16_CONST(-0.6152315905806273),
+ FX16_CONST(-0.7892892531688854), FX16_CONST(-0.6140215589310387),
+ FX16_CONST(-0.7902302214373099), FX16_CONST(-0.6128100824294099),
+ FX16_CONST(-0.7911693302176901), FX16_CONST(-0.611597163926462),
+ FX16_CONST(-0.7921065773002124), FX16_CONST(-0.6103828062763094),
+ FX16_CONST(-0.7930419604794439), FX16_CONST(-0.609167012336453),
+ FX16_CONST(-0.7939754775543368), FX16_CONST(-0.6079497849677741),
+ FX16_CONST(-0.7949071263282368), FX16_CONST(-0.6067311270345248),
+ FX16_CONST(-0.7958369046088835), FX16_CONST(-0.6055110414043257),
+ FX16_CONST(-0.7967648102084187), FX16_CONST(-0.6042895309481561),
+ FX16_CONST(-0.7976908409433912), FX16_CONST(-0.603066598540348),
+ FX16_CONST(-0.7986149946347605), FX16_CONST(-0.6018422470585805),
+ FX16_CONST(-0.7995372691079048), FX16_CONST(-0.6006164793838693),
+ FX16_CONST(-0.8004576621926226), FX16_CONST(-0.5993892984005648),
+ FX16_CONST(-0.8013761717231401), FX16_CONST(-0.5981607069963424),
+ FX16_CONST(-0.8022927955381157), FX16_CONST(-0.5969307080621964),
+ FX16_CONST(-0.803207531480645), FX16_CONST(-0.5956993044924331),
+ FX16_CONST(-0.8041203773982655), FX16_CONST(-0.5944664991846649),
+ FX16_CONST(-0.8050313311429634), FX16_CONST(-0.5932322950398001),
+ FX16_CONST(-0.8059403905711762), FX16_CONST(-0.5919966949620411),
+ FX16_CONST(-0.8068475535437992), FX16_CONST(-0.5907597018588743),
+ FX16_CONST(-0.8077528179261905), FX16_CONST(-0.5895213186410638),
+ FX16_CONST(-0.8086561815881746), FX16_CONST(-0.5882815482226458),
+ FX16_CONST(-0.809557642404051), FX16_CONST(-0.5870403935209183),
+ FX16_CONST(-0.8104571982525947), FX16_CONST(-0.5857978574564391),
+ FX16_CONST(-0.8113548470170637), FX16_CONST(-0.5845539429530153),
+ FX16_CONST(-0.812250586585204), FX16_CONST(-0.5833086529376983),
+ FX16_CONST(-0.8131444148492537), FX16_CONST(-0.5820619903407753),
+ FX16_CONST(-0.8140363297059481), FX16_CONST(-0.580813958095765),
+ FX16_CONST(-0.8149263290565264), FX16_CONST(-0.579564559139406),
+ FX16_CONST(-0.8158144108067337), FX16_CONST(-0.5783137964116557),
+ FX16_CONST(-0.8167005728668278), FX16_CONST(-0.5770616728556796),
+ FX16_CONST(-0.8175848131515838), FX16_CONST(-0.5758081914178452),
+ FX16_CONST(-0.8184671295802983), FX16_CONST(-0.5745533550477163),
+ FX16_CONST(-0.8193475200767967), FX16_CONST(-0.5732971666980425),
+ FX16_CONST(-0.8202259825694345), FX16_CONST(-0.5720396293247573),
+ FX16_CONST(-0.8211025149911046), FX16_CONST(-0.5707807458869674),
+ FX16_CONST(-0.8219771152792416), FX16_CONST(-0.5695205193469471),
+ FX16_CONST(-0.8228497813758264), FX16_CONST(-0.5682589526701314),
+ FX16_CONST(-0.8237205112273911), FX16_CONST(-0.566996048825109),
+ FX16_CONST(-0.8245893027850251), FX16_CONST(-0.5657318107836135),
+ FX16_CONST(-0.8254561540043774), FX16_CONST(-0.5644662415205196),
+ FX16_CONST(-0.8263210628456634), FX16_CONST(-0.5631993440138341),
+ FX16_CONST(-0.8271840272736692), FX16_CONST(-0.5619311212446892),
+ FX16_CONST(-0.8280450452577555), FX16_CONST(-0.5606615761973365),
+ FX16_CONST(-0.8289041147718647), FX16_CONST(-0.5593907118591365),
+ FX16_CONST(-0.8297612337945229), FX16_CONST(-0.5581185312205563),
+ FX16_CONST(-0.8306164003088462), FX16_CONST(-0.5568450372751601),
+ FX16_CONST(-0.8314696123025452), FX16_CONST(-0.5555702330196022),
+ FX16_CONST(-0.8323208677679298), FX16_CONST(-0.5542941214536199),
+ FX16_CONST(-0.8331701647019129), FX16_CONST(-0.5530167055800279),
+ FX16_CONST(-0.8340175011060179), FX16_CONST(-0.5517379884047077),
+ FX16_CONST(-0.8348628749863799), FX16_CONST(-0.5504579729366049),
+ FX16_CONST(-0.8357062843537526), FX16_CONST(-0.5491766621877198),
+ FX16_CONST(-0.8365477272235121), FX16_CONST(-0.5478940591731001),
+ FX16_CONST(-0.8373872016156616), FX16_CONST(-0.5466101669108354),
+ FX16_CONST(-0.8382247055548379), FX16_CONST(-0.5453249884220468),
+ FX16_CONST(-0.8390602370703125), FX16_CONST(-0.5440385267308842),
+ FX16_CONST(-0.8398937941959994), FX16_CONST(-0.542750784864516),
+ FX16_CONST(-0.8407253749704581), FX16_CONST(-0.5414617658531234),
+ FX16_CONST(-0.8415549774368986), FX16_CONST(-0.5401714727298927),
+ FX16_CONST(-0.8423825996431856), FX16_CONST(-0.5388799085310089),
+ FX16_CONST(-0.8432082396418452), FX16_CONST(-0.5375870762956457),
+ FX16_CONST(-0.8440318954900663), FX16_CONST(-0.5362929790659633),
+ FX16_CONST(-0.8448535652497071), FX16_CONST(-0.5349976198870973),
+ FX16_CONST(-0.8456732469872992), FX16_CONST(-0.5337010018071529),
+ FX16_CONST(-0.8464909387740518), FX16_CONST(-0.5324031278771985),
+ FX16_CONST(-0.8473066386858581), FX16_CONST(-0.5311040011512553),
+ FX16_CONST(-0.8481203448032971), FX16_CONST(-0.5298036246862949),
+ FX16_CONST(-0.8489320552116396), FX16_CONST(-0.5285020015422286),
+ FX16_CONST(-0.8497417680008525), FX16_CONST(-0.5271991347819013),
+ FX16_CONST(-0.8505494812656036), FX16_CONST(-0.5258950274710845),
+ FX16_CONST(-0.8513551931052649), FX16_CONST(-0.5245896826784693),
+ FX16_CONST(-0.8521589016239196), FX16_CONST(-0.5232831034756568),
+ FX16_CONST(-0.8529606049303635), FX16_CONST(-0.5219752929371545),
+ FX16_CONST(-0.8537603011381114), FX16_CONST(-0.5206662541403672),
+ FX16_CONST(-0.8545579883654005), FX16_CONST(-0.5193559901655894),
+ FX16_CONST(-0.8553536647351957), FX16_CONST(-0.5180445040959999),
+ FX16_CONST(-0.8561473283751942), FX16_CONST(-0.5167317990176502),
+ FX16_CONST(-0.8569389774178287), FX16_CONST(-0.5154178780194633),
+ FX16_CONST(-0.857728610000272), FX16_CONST(-0.5141027441932218),
+ FX16_CONST(-0.8585162242644429), FX16_CONST(-0.512786400633563),
+ FX16_CONST(-0.8593018183570085), FX16_CONST(-0.5114688504379702),
+ FX16_CONST(-0.8600853904293899), FX16_CONST(-0.5101500967067673),
+ FX16_CONST(-0.8608669386377671), FX16_CONST(-0.5088301425431073),
+ FX16_CONST(-0.8616464611430812), FX16_CONST(-0.507508991052971),
+ FX16_CONST(-0.8624239561110405), FX16_CONST(-0.5061866453451553),
+ FX16_CONST(-0.8631994217121243), FX16_CONST(-0.5048631085312674),
+ FX16_CONST(-0.8639728561215865), FX16_CONST(-0.503538383725718),
+ FX16_CONST(-0.8647442575194622), FX16_CONST(-0.5022124740457111),
+ FX16_CONST(-0.865513624090569), FX16_CONST(-0.500885382611241),
+ FX16_CONST(-0.8662809540245129), FX16_CONST(-0.49955711254508195),
+ FX16_CONST(-0.8670462455156926), FX16_CONST(-0.4982276669727818),
+ FX16_CONST(-0.8678094967633033), FX16_CONST(-0.49689704902265436),
+ FX16_CONST(-0.8685707059713407), FX16_CONST(-0.495565261825773),
+ FX16_CONST(-0.8693298713486066), FX16_CONST(-0.49423230851596),
+ FX16_CONST(-0.8700869911087113), FX16_CONST(-0.4928981922297842),
+ FX16_CONST(-0.8708420634700789), FX16_CONST(-0.49156291610654995),
+ FX16_CONST(-0.8715950866559511), FX16_CONST(-0.49022648328829105),
+ FX16_CONST(-0.8723460588943912), FX16_CONST(-0.48888889691976367),
+ FX16_CONST(-0.8730949784182899), FX16_CONST(-0.48755016014843633),
+ FX16_CONST(-0.8738418434653666), FX16_CONST(-0.48621027612448664),
+ FX16_CONST(-0.8745866522781761), FX16_CONST(-0.4848692480007912),
+ FX16_CONST(-0.8753294031041109), FX16_CONST(-0.4835270789329187),
+ FX16_CONST(-0.8760700941954067), FX16_CONST(-0.48218377207912255),
+ FX16_CONST(-0.8768087238091454), FX16_CONST(-0.4808393306003344),
+ FX16_CONST(-0.8775452902072611), FX16_CONST(-0.47949375766015334),
+ FX16_CONST(-0.8782797916565415), FX16_CONST(-0.47814705642484323),
+ FX16_CONST(-0.8790122264286334), FX16_CONST(-0.47679923006332214),
+ FX16_CONST(-0.8797425928000475), FX16_CONST(-0.47545028174715576),
+ FX16_CONST(-0.8804708890521605), FX16_CONST(-0.4741002146505505),
+ FX16_CONST(-0.8811971134712219), FX16_CONST(-0.4727490319503432),
+ FX16_CONST(-0.8819212643483549), FX16_CONST(-0.47139673682599786),
+ FX16_CONST(-0.8826433399795628), FX16_CONST(-0.47004333245959573),
+ FX16_CONST(-0.8833633386657316), FX16_CONST(-0.4686888220358279),
+ FX16_CONST(-0.8840812587126351), FX16_CONST(-0.46733320874198825),
+ FX16_CONST(-0.8847970984309376), FX16_CONST(-0.4659764957679666),
+ FX16_CONST(-0.8855108561361997), FX16_CONST(-0.46461868630623815),
+ FX16_CONST(-0.8862225301488805), FX16_CONST(-0.46325978355186037),
+ FX16_CONST(-0.8869321187943422), FX16_CONST(-0.4618997907024628),
+ FX16_CONST(-0.887639620402854), FX16_CONST(-0.4605387109582399),
+ FX16_CONST(-0.888345033309596), FX16_CONST(-0.45917654752194464),
+ FX16_CONST(-0.8890483558546644), FX16_CONST(-0.4578133035988776),
+ FX16_CONST(-0.8897495863830727), FX16_CONST(-0.4564489823968842),
+ FX16_CONST(-0.8904487232447579), FX16_CONST(-0.45508358712634395),
+ FX16_CONST(-0.8911457647945833), FX16_CONST(-0.4537171210001638),
+ FX16_CONST(-0.8918407093923428), FX16_CONST(-0.45234958723377067),
+ FX16_CONST(-0.8925335554027644), FX16_CONST(-0.4509809890451043),
+ FX16_CONST(-0.8932243011955152), FX16_CONST(-0.44961132965460693),
+ FX16_CONST(-0.8939129451452031), FX16_CONST(-0.4482406122852201),
+ FX16_CONST(-0.8945994856313827), FX16_CONST(-0.4468688401623742),
+ FX16_CONST(-0.8952839210385576), FX16_CONST(-0.44549601651398163),
+ FX16_CONST(-0.8959662497561849), FX16_CONST(-0.44412214457042976),
+ FX16_CONST(-0.89664647017868), FX16_CONST(-0.4427472275645704),
+ FX16_CONST(-0.8973245807054182), FX16_CONST(-0.44137126873171695),
+ FX16_CONST(-0.8980005797407398), FX16_CONST(-0.43999427130963337),
+ FX16_CONST(-0.8986744656939538), FX16_CONST(-0.4386162385385276),
+ FX16_CONST(-0.8993462369793417), FX16_CONST(-0.4372371736610439),
+ FX16_CONST(-0.90001589201616), FX16_CONST(-0.435857079922256),
+ FX16_CONST(-0.9006834292286467), FX16_CONST(-0.43447596056965604),
+ FX16_CONST(-0.9013488470460219), FX16_CONST(-0.4330938188531521),
+ FX16_CONST(-0.9020121439024932), FX16_CONST(-0.4317106580250573),
+ FX16_CONST(-0.9026733182372588), FX16_CONST(-0.4303264813400825),
+ FX16_CONST(-0.9033323684945116), FX16_CONST(-0.42894129205533005),
+ FX16_CONST(-0.9039892931234431), FX16_CONST(-0.4275550934302825),
+ FX16_CONST(-0.9046440905782461), FX16_CONST(-0.4261678887267999),
+ FX16_CONST(-0.9052967593181187), FX16_CONST(-0.4247796812091089),
+ FX16_CONST(-0.9059472978072685), FX16_CONST(-0.423390474143796),
+ FX16_CONST(-0.9065957045149154), FX16_CONST(-0.4220002707997995),
+ FX16_CONST(-0.9072419779152956), FX16_CONST(-0.420609074448403),
+ FX16_CONST(-0.907886116487666), FX16_CONST(-0.4192168883632243),
+ FX16_CONST(-0.908528118716306), FX16_CONST(-0.4178237158202125),
+ FX16_CONST(-0.9091679830905224), FX16_CONST(-0.4164295600976372),
+ FX16_CONST(-0.9098057081046523), FX16_CONST(-0.4150344244760815),
+ FX16_CONST(-0.9104412922580669), FX16_CONST(-0.4136383122384351),
+ FX16_CONST(-0.9110747340551761), FX16_CONST(-0.4122412266698833),
+ FX16_CONST(-0.9117060320054298), FX16_CONST(-0.4108431710579042),
+ FX16_CONST(-0.9123351846233227), FX16_CONST(-0.40944414869225776),
+ FX16_CONST(-0.9129621904283982), FX16_CONST(-0.40804416286497863),
+ FX16_CONST(-0.9135870479452509), FX16_CONST(-0.40664321687036886),
+ FX16_CONST(-0.9142097557035305), FX16_CONST(-0.40524131400499036),
+ FX16_CONST(-0.914830312237946), FX16_CONST(-0.40383845756765446),
+ FX16_CONST(-0.9154487160882677), FX16_CONST(-0.40243465085941865),
+ FX16_CONST(-0.9160649657993317), FX16_CONST(-0.4010298971835757),
+ FX16_CONST(-0.9166790599210427), FX16_CONST(-0.39962419984564673),
+ FX16_CONST(-0.9172909970083777), FX16_CONST(-0.39821756215337417),
+ FX16_CONST(-0.9179007756213903), FX16_CONST(-0.39680998741671075),
+ FX16_CONST(-0.9185083943252121), FX16_CONST(-0.3954014789478166),
+ FX16_CONST(-0.9191138516900577), FX16_CONST(-0.3939920400610482),
+ FX16_CONST(-0.9197171462912274), FX16_CONST(-0.39258167407295147),
+ FX16_CONST(-0.9203182767091106), FX16_CONST(-0.3911703843022537),
+ FX16_CONST(-0.9209172415291893), FX16_CONST(-0.38975817406985697),
+ FX16_CONST(-0.9215140393420418), FX16_CONST(-0.38834504669882663),
+ FX16_CONST(-0.9221086687433451), FX16_CONST(-0.3869310055143888),
+ FX16_CONST(-0.9227011283338785), FX16_CONST(-0.3855160538439189),
+ FX16_CONST(-0.9232914167195276), FX16_CONST(-0.38410019501693493),
+ FX16_CONST(-0.9238795325112865), FX16_CONST(-0.38268343236509034),
+ FX16_CONST(-0.9244654743252625), FX16_CONST(-0.38126576922216276),
+ FX16_CONST(-0.9250492407826775), FX16_CONST(-0.37984720892405144),
+ FX16_CONST(-0.9256308305098727), FX16_CONST(-0.3784277548087657),
+ FX16_CONST(-0.9262102421383114), FX16_CONST(-0.3770074102164182),
+ FX16_CONST(-0.9267874743045819), FX16_CONST(-0.37558617848921705),
+ FX16_CONST(-0.9273625256504009), FX16_CONST(-0.3741640629714585),
+ FX16_CONST(-0.9279353948226177), FX16_CONST(-0.37274106700951615),
+ FX16_CONST(-0.9285060804732155), FX16_CONST(-0.37131719395183777),
+ FX16_CONST(-0.9290745812593157), FX16_CONST(-0.36989244714893416),
+ FX16_CONST(-0.9296408958431813), FX16_CONST(-0.3684668299533722),
+ FX16_CONST(-0.9302050228922192), FX16_CONST(-0.36704034571976696),
+ FX16_CONST(-0.9307669610789836), FX16_CONST(-0.3656129978047743),
+ FX16_CONST(-0.9313267090811803), FX16_CONST(-0.36418478956708017),
+ FX16_CONST(-0.931884265581668), FX16_CONST(-0.36275572436739734),
+ FX16_CONST(-0.9324396292684624), FX16_CONST(-0.36132580556845423),
+ FX16_CONST(-0.932992798834739), FX16_CONST(-0.35989503653498794),
+ FX16_CONST(-0.933543772978836), FX16_CONST(-0.35846342063373704),
+ FX16_CONST(-0.9340925504042588), FX16_CONST(-0.35703096123343037),
+ FX16_CONST(-0.9346391298196807), FX16_CONST(-0.3555976617047841),
+ FX16_CONST(-0.9351835099389476), FX16_CONST(-0.35416352542049045),
+ FX16_CONST(-0.9357256894810804), FX16_CONST(-0.3527285557552106),
+ FX16_CONST(-0.9362656671702784), FX16_CONST(-0.35129275608556687),
+ FX16_CONST(-0.9368034417359214), FX16_CONST(-0.34985612979013536),
+ FX16_CONST(-0.9373390119125748), FX16_CONST(-0.34841868024943484),
+ FX16_CONST(-0.9378723764399898), FX16_CONST(-0.3469804108459238),
+ FX16_CONST(-0.9384035340631082), FX16_CONST(-0.34554132496398904),
+ FX16_CONST(-0.9389324835320646), FX16_CONST(-0.34410142598993865),
+ FX16_CONST(-0.9394592236021897), FX16_CONST(-0.3426607173119949),
+ FX16_CONST(-0.9399837530340138), FX16_CONST(-0.34121920232028274),
+ FX16_CONST(-0.9405060705932683), FX16_CONST(-0.3397768844068271),
+ FX16_CONST(-0.9410261750508893), FX16_CONST(-0.33833376696554124),
+ FX16_CONST(-0.9415440651830208), FX16_CONST(-0.33688985339221994),
+ FX16_CONST(-0.9420597397710174), FX16_CONST(-0.3354451470845314),
+ FX16_CONST(-0.9425731976014468), FX16_CONST(-0.3339996514420098),
+ FX16_CONST(-0.9430844374660934), FX16_CONST(-0.3325533698660445),
+ FX16_CONST(-0.9435934581619603), FX16_CONST(-0.33110630575987654),
+ FX16_CONST(-0.9441002584912727), FX16_CONST(-0.3296584625285875),
+ FX16_CONST(-0.9446048372614804), FX16_CONST(-0.32820984357909233),
+ FX16_CONST(-0.9451071932852604), FX16_CONST(-0.3267604523201323),
+ FX16_CONST(-0.9456073253805212), FX16_CONST(-0.3253102921622633),
+ FX16_CONST(-0.9461052323704033), FX16_CONST(-0.3238593665178531),
+ FX16_CONST(-0.9466009130832835), FX16_CONST(-0.3224076788010699),
+ FX16_CONST(-0.9470943663527772), FX16_CONST(-0.32095523242787516),
+ FX16_CONST(-0.9475855910177412), FX16_CONST(-0.3195020308160154),
+ FX16_CONST(-0.9480745859222761), FX16_CONST(-0.3180480773850154),
+ FX16_CONST(-0.9485613499157302), FX16_CONST(-0.3165933755561662),
+ FX16_CONST(-0.9490458818527006), FX16_CONST(-0.31513792875252256),
+ FX16_CONST(-0.9495281805930367), FX16_CONST(-0.31368174039889146),
+ FX16_CONST(-0.9500082450018431), FX16_CONST(-0.3122248139218248),
+ FX16_CONST(-0.9504860739494816), FX16_CONST(-0.31076715274961203),
+ FX16_CONST(-0.950961666311575), FX16_CONST(-0.30930876031226906),
+ FX16_CONST(-0.9514350209690083), FX16_CONST(-0.3078496400415351),
+ FX16_CONST(-0.9519061368079323), FX16_CONST(-0.306389795370861),
+ FX16_CONST(-0.9523750127197659), FX16_CONST(-0.3049292297354023),
+ FX16_CONST(-0.9528416476011987), FX16_CONST(-0.30346794657201104),
+ FX16_CONST(-0.9533060403541936), FX16_CONST(-0.30200594931922853),
+ FX16_CONST(-0.9537681898859902), FX16_CONST(-0.30054324141727373),
+ FX16_CONST(-0.9542280951091056), FX16_CONST(-0.2990798263080406),
+ FX16_CONST(-0.9546857549413383), FX16_CONST(-0.2976157074350862),
+ FX16_CONST(-0.9551411683057708), FX16_CONST(-0.2961508882436237),
+ FX16_CONST(-0.9555943341307709), FX16_CONST(-0.2946853721805149),
+ FX16_CONST(-0.9560452513499963), FX16_CONST(-0.293219162694259),
+ FX16_CONST(-0.956493918902395), FX16_CONST(-0.2917522632349895),
+ FX16_CONST(-0.9569403357322088), FX16_CONST(-0.29028467725446244),
+ FX16_CONST(-0.957384500788976), FX16_CONST(-0.28881640820604937),
+ FX16_CONST(-0.957826413027533), FX16_CONST(-0.2873474595447293),
+ FX16_CONST(-0.9582660714080176), FX16_CONST(-0.28587783472708106),
+ FX16_CONST(-0.9587034748958715), FX16_CONST(-0.28440753721127215),
+ FX16_CONST(-0.9591386224618419), FX16_CONST(-0.2829365704570555),
+ FX16_CONST(-0.9595715130819845), FX16_CONST(-0.28146493792575794),
+ FX16_CONST(-0.960002145737666), FX16_CONST(-0.27999264308027305),
+ FX16_CONST(-0.9604305194155657), FX16_CONST(-0.2785196893850536),
+ FX16_CONST(-0.9608566331076795), FX16_CONST(-0.2770460803061003),
+ FX16_CONST(-0.9612804858113205), FX16_CONST(-0.27557181931095837),
+ FX16_CONST(-0.9617020765291225), FX16_CONST(-0.27409690986870644),
+ FX16_CONST(-0.9621214042690416), FX16_CONST(-0.27262135544994887),
+ FX16_CONST(-0.9625384680443593), FX16_CONST(-0.2711451595268078),
+ FX16_CONST(-0.9629532668736838), FX16_CONST(-0.26966832557291553),
+ FX16_CONST(-0.9633657997809539), FX16_CONST(-0.2681908570634035),
+ FX16_CONST(-0.9637760657954398), FX16_CONST(-0.26671275747489853),
+ FX16_CONST(-0.9641840639517458), FX16_CONST(-0.2652340302855118),
+ FX16_CONST(-0.9645897932898128), FX16_CONST(-0.26375467897483124),
+ FX16_CONST(-0.9649932528549202), FX16_CONST(-0.26227470702391414),
+ FX16_CONST(-0.9653944416976893), FX16_CONST(-0.2607941179152759),
+ FX16_CONST(-0.9657933588740836), FX16_CONST(-0.25931291513288646),
+ FX16_CONST(-0.9661900034454125), FX16_CONST(-0.25783110216215904),
+ FX16_CONST(-0.9665843744783331), FX16_CONST(-0.2563486824899428),
+ FX16_CONST(-0.9669764710448522), FX16_CONST(-0.25486565960451435),
+ FX16_CONST(-0.9673662922223284), FX16_CONST(-0.2533820369955706),
+ FX16_CONST(-0.9677538370934754), FX16_CONST(-0.25189781815421725),
+ FX16_CONST(-0.9681391047463623), FX16_CONST(-0.2504130065729654),
+ FX16_CONST(-0.9685220942744173), FX16_CONST(-0.24892760574572015),
+ FX16_CONST(-0.9689028047764289), FX16_CONST(-0.24744161916777313),
+ FX16_CONST(-0.9692812353565483), FX16_CONST(-0.24595505033579515),
+ FX16_CONST(-0.9696573851242923), FX16_CONST(-0.24446790274782454),
+ FX16_CONST(-0.970031253194544), FX16_CONST(-0.24298017990326412),
+ FX16_CONST(-0.9704028386875555), FX16_CONST(-0.2414918853028694),
+ FX16_CONST(-0.9707721407289504), FX16_CONST(-0.2400030224487414),
+ FX16_CONST(-0.9711391584497252), FX16_CONST(-0.2385135948443182),
+ FX16_CONST(-0.9715038909862517), FX16_CONST(-0.23702360599436767),
+ FX16_CONST(-0.9718663374802793), FX16_CONST(-0.2355330594049758),
+ FX16_CONST(-0.9722264970789363), FX16_CONST(-0.23404195858354357),
+ FX16_CONST(-0.9725843689347322), FX16_CONST(-0.23255030703877522),
+ FX16_CONST(-0.9729399522055602), FX16_CONST(-0.23105810828067094),
+ FX16_CONST(-0.9732932460546981), FX16_CONST(-0.22956536582051942),
+ FX16_CONST(-0.9736442496508119), FX16_CONST(-0.22807208317088612),
+ FX16_CONST(-0.9739929621679558), FX16_CONST(-0.22657826384561022),
+ FX16_CONST(-0.9743393827855759), FX16_CONST(-0.22508391135979292),
+ FX16_CONST(-0.9746835106885107), FX16_CONST(-0.2235890292297899),
+ FX16_CONST(-0.9750253450669942), FX16_CONST(-0.2220936209732033),
+ FX16_CONST(-0.9753648851166569), FX16_CONST(-0.22059769010887398),
+ FX16_CONST(-0.9757021300385285), FX16_CONST(-0.2191012401568701),
+ FX16_CONST(-0.976037079039039), FX16_CONST(-0.21760427463848378),
+ FX16_CONST(-0.9763697313300211), FX16_CONST(-0.2161067970762195),
+ FX16_CONST(-0.9767000861287118), FX16_CONST(-0.2146088109937866),
+ FX16_CONST(-0.9770281426577543), FX16_CONST(-0.21311031991609192),
+ FX16_CONST(-0.9773539001452), FX16_CONST(-0.21161132736922797),
+ FX16_CONST(-0.9776773578245099), FX16_CONST(-0.21011183688046986),
+ FX16_CONST(-0.977998514934557), FX16_CONST(-0.20861185197826357),
+ FX16_CONST(-0.9783173707196277), FX16_CONST(-0.20711137619221848),
+ FX16_CONST(-0.9786339244294232), FX16_CONST(-0.20561041305309902),
+ FX16_CONST(-0.9789481753190621), FX16_CONST(-0.20410896609281734),
+ FX16_CONST(-0.979260122649082), FX16_CONST(-0.20260703884442144),
+ FX16_CONST(-0.9795697656854405), FX16_CONST(-0.20110463484209207),
+ FX16_CONST(-0.9798771036995176), FX16_CONST(-0.19960175762113097),
+ FX16_CONST(-0.9801821359681174), FX16_CONST(-0.19809841071795342),
+ FX16_CONST(-0.9804848617734693), FX16_CONST(-0.19659459767008078),
+ FX16_CONST(-0.9807852804032303), FX16_CONST(-0.19509032201612866),
+ FX16_CONST(-0.9810833911504866), FX16_CONST(-0.19358558729580386),
+ FX16_CONST(-0.9813791933137546), FX16_CONST(-0.19208039704989252),
+ FX16_CONST(-0.9816726861969831), FX16_CONST(-0.19057475482025268),
+ FX16_CONST(-0.9819638691095554), FX16_CONST(-0.18906866414980597),
+ FX16_CONST(-0.9822527413662894), FX16_CONST(-0.18756212858253007),
+ FX16_CONST(-0.9825393022874412), FX16_CONST(-0.18605515166344697),
+ FX16_CONST(-0.9828235511987052), FX16_CONST(-0.18454773693861978),
+ FX16_CONST(-0.9831054874312163), FX16_CONST(-0.18303988795514095),
+ FX16_CONST(-0.9833851103215513), FX16_CONST(-0.18153160826112483),
+ FX16_CONST(-0.9836624192117301), FX16_CONST(-0.18002290140570007),
+ FX16_CONST(-0.9839374134492188), FX16_CONST(-0.17851377093899792),
+ FX16_CONST(-0.984210092386929), FX16_CONST(-0.177004220412149),
+ FX16_CONST(-0.9844804553832209), FX16_CONST(-0.1754942533772715),
+ FX16_CONST(-0.9847485018019042), FX16_CONST(-0.17398387338746374),
+ FX16_CONST(-0.9850142310122398), FX16_CONST(-0.17247308399679573),
+ FX16_CONST(-0.9852776423889411), FX16_CONST(-0.1709618887603017),
+ FX16_CONST(-0.9855387353121761), FX16_CONST(-0.1694502912339683),
+ FX16_CONST(-0.9857975091675674), FX16_CONST(-0.16793829497473134),
+ FX16_CONST(-0.9860539633461954), FX16_CONST(-0.1664259035404641),
+ FX16_CONST(-0.9863080972445987), FX16_CONST(-0.16491312048996976),
+ FX16_CONST(-0.9865599102647754), FX16_CONST(-0.16339994938297378),
+ FX16_CONST(-0.9868094018141854), FX16_CONST(-0.16188639378011224),
+ FX16_CONST(-0.987056571305751), FX16_CONST(-0.1603724572429285),
+ FX16_CONST(-0.9873014181578583), FX16_CONST(-0.15885814333386153),
+ FX16_CONST(-0.9875439417943593), FX16_CONST(-0.1573434556162382),
+ FX16_CONST(-0.9877841416445722), FX16_CONST(-0.15582839765426498),
+ FX16_CONST(-0.9880220171432835), FX16_CONST(-0.15431297301302058),
+ FX16_CONST(-0.9882575677307495), FX16_CONST(-0.15279718525844374),
+ FX16_CONST(-0.9884907928526966), FX16_CONST(-0.15128103795733036),
+ FX16_CONST(-0.9887216919603238), FX16_CONST(-0.1497645346773215),
+ FX16_CONST(-0.988950264510303), FX16_CONST(-0.1482476789868959),
+ FX16_CONST(-0.9891765099647809), FX16_CONST(-0.1467304744553623),
+ FX16_CONST(-0.9894004277913803), FX16_CONST(-0.14521292465284785),
+ FX16_CONST(-0.9896220174632008), FX16_CONST(-0.1436950331502947),
+ FX16_CONST(-0.9898412784588205), FX16_CONST(-0.14217680351944814),
+ FX16_CONST(-0.9900582102622971), FX16_CONST(-0.14065823933284916),
+ FX16_CONST(-0.9902728123631691), FX16_CONST(-0.13913934416382598),
+ FX16_CONST(-0.990485084256457), FX16_CONST(-0.13762012158648654),
+ FX16_CONST(-0.9906950254426646), FX16_CONST(-0.13610057517570653),
+ FX16_CONST(-0.99090263542778), FX16_CONST(-0.13458070850712636),
+ FX16_CONST(-0.9911079137232769), FX16_CONST(-0.13306052515713906),
+ FX16_CONST(-0.9913108598461154), FX16_CONST(-0.13154002870288295),
+ FX16_CONST(-0.9915114733187439), FX16_CONST(-0.13001922272223393),
+ FX16_CONST(-0.9917097536690995), FX16_CONST(-0.12849811079379359),
+ FX16_CONST(-0.9919057004306093), FX16_CONST(-0.12697669649688612),
+ FX16_CONST(-0.9920993131421918), FX16_CONST(-0.12545498341154632),
+ FX16_CONST(-0.9922905913482574), FX16_CONST(-0.12393297511851209),
+ FX16_CONST(-0.9924795345987101), FX16_CONST(-0.12241067519921596),
+ FX16_CONST(-0.9926661424489479), FX16_CONST(-0.12088808723577757),
+ FX16_CONST(-0.9928504144598651), FX16_CONST(-0.11936521481099169),
+ FX16_CONST(-0.9930323501978514), FX16_CONST(-0.11784206150832514),
+ FX16_CONST(-0.9932119492347945), FX16_CONST(-0.11631863091190477),
+ FX16_CONST(-0.9933892111480807), FX16_CONST(-0.11479492660650993),
+ FX16_CONST(-0.9935641355205953), FX16_CONST(-0.11327095217756492),
+ FX16_CONST(-0.9937367219407246), FX16_CONST(-0.111746711211127),
+ FX16_CONST(-0.9939069700023561), FX16_CONST(-0.11022220729388331),
+ FX16_CONST(-0.9940748793048794), FX16_CONST(-0.1086974440131388),
+ FX16_CONST(-0.9942404494531879), FX16_CONST(-0.10717242495680877),
+ FX16_CONST(-0.9944036800576791), FX16_CONST(-0.10564715371341038),
+ FX16_CONST(-0.9945645707342554), FX16_CONST(-0.10412163387205507),
+ FX16_CONST(-0.9947231211043257), FX16_CONST(-0.10259586902243661),
+ FX16_CONST(-0.9948793307948056), FX16_CONST(-0.10106986275482799),
+ FX16_CONST(-0.9950331994381186), FX16_CONST(-0.09954361866006935),
+ FX16_CONST(-0.9951847266721969), FX16_CONST(-0.09801714032956045),
+ FX16_CONST(-0.9953339121404822), FX16_CONST(-0.09649043135525316),
+ FX16_CONST(-0.9954807554919269), FX16_CONST(-0.09496349532963941),
+ FX16_CONST(-0.9956252563809943), FX16_CONST(-0.09343633584574804),
+ FX16_CONST(-0.9957674144676598), FX16_CONST(-0.09190895649713282),
+ FX16_CONST(-0.9959072294174117), FX16_CONST(-0.09038136087786491),
+ FX16_CONST(-0.996044700901252), FX16_CONST(-0.08885355258252436),
+ FX16_CONST(-0.9961798285956969), FX16_CONST(-0.08732553520619256),
+ FX16_CONST(-0.996312612182778), FX16_CONST(-0.08579731234444023),
+ FX16_CONST(-0.9964430513500426), FX16_CONST(-0.08426888759332424),
+ FX16_CONST(-0.9965711457905548), FX16_CONST(-0.0827402645493757),
+ FX16_CONST(-0.9966968952028961), FX16_CONST(-0.08121144680959229),
+ FX16_CONST(-0.9968202992911657), FX16_CONST(-0.0796824379714307),
+ FX16_CONST(-0.996941357764982), FX16_CONST(-0.07815324163279465),
+ FX16_CONST(-0.997060070339483), FX16_CONST(-0.07662386139203174),
+ FX16_CONST(-0.9971764367353261), FX16_CONST(-0.0750943008479214),
+ FX16_CONST(-0.9972904566786902), FX16_CONST(-0.07356456359966736),
+ FX16_CONST(-0.9974021299012753), FX16_CONST(-0.0720346532468891),
+ FX16_CONST(-0.9975114561403035), FX16_CONST(-0.07050457338961436),
+ FX16_CONST(-0.9976184351385196), FX16_CONST(-0.06897432762826708),
+ FX16_CONST(-0.9977230666441916), FX16_CONST(-0.06744391956366423),
+ FX16_CONST(-0.9978253504111116), FX16_CONST(-0.06591335279700383),
+ FX16_CONST(-0.997925286198596), FX16_CONST(-0.06438263092985731),
+ FX16_CONST(-0.9980228737714861), FX16_CONST(-0.06285175756416199),
+ FX16_CONST(-0.9981181129001492), FX16_CONST(-0.061320736302208995),
+ FX16_CONST(-0.9982110033604782), FX16_CONST(-0.05978957074664013),
+ FX16_CONST(-0.9983015449338928), FX16_CONST(-0.058258264500435857),
+ FX16_CONST(-0.9983897374073402), FX16_CONST(-0.056726821166907686),
+ FX16_CONST(-0.9984755805732948), FX16_CONST(-0.05519524434968971),
+ FX16_CONST(-0.9985590742297593), FX16_CONST(-0.053663537652731026),
+ FX16_CONST(-0.9986402181802652), FX16_CONST(-0.05213170468028366),
+ FX16_CONST(-0.9987190122338729), FX16_CONST(-0.050599749036899455),
+ FX16_CONST(-0.9987954562051724), FX16_CONST(-0.04906767432741803),
+ FX16_CONST(-0.9988695499142836), FX16_CONST(-0.04753548415695916),
+ FX16_CONST(-0.9989412931868569), FX16_CONST(-0.046003182130915206),
+ FX16_CONST(-0.9990106858540733), FX16_CONST(-0.044470771854939084),
+ FX16_CONST(-0.9990777277526454), FX16_CONST(-0.042938256934941084),
+ FX16_CONST(-0.9991424187248169), FX16_CONST(-0.04140564097707684),
+ FX16_CONST(-0.9992047586183639), FX16_CONST(-0.03987292758773975),
+ FX16_CONST(-0.9992647472865944), FX16_CONST(-0.03834012037355247),
+ FX16_CONST(-0.9993223845883494), FX16_CONST(-0.03680722294135933),
+ FX16_CONST(-0.9993776703880028), FX16_CONST(-0.035274238898214294),
+ FX16_CONST(-0.9994306045554617), FX16_CONST(-0.03374117185137776),
+ FX16_CONST(-0.999481186966167), FX16_CONST(-0.0322080254083046),
+ FX16_CONST(-0.9995294175010931), FX16_CONST(-0.030674803176636484),
+ FX16_CONST(-0.9995752960467492), FX16_CONST(-0.02914150876419431),
+ FX16_CONST(-0.9996188224951786), FX16_CONST(-0.027608145778966163),
+ FX16_CONST(-0.9996599967439592), FX16_CONST(-0.02607471782910416),
+ FX16_CONST(-0.9996988186962042), FX16_CONST(-0.02454122852291239),
+ FX16_CONST(-0.9997352882605617), FX16_CONST(-0.02300768146883931),
+ FX16_CONST(-0.9997694053512153), FX16_CONST(-0.021474080275469286),
+ FX16_CONST(-0.9998011698878843), FX16_CONST(-0.019940428551514944),
+ FX16_CONST(-0.9998305817958234), FX16_CONST(-0.018406729905805164),
+ FX16_CONST(-0.9998576410058239), FX16_CONST(-0.016872987947281894),
+ FX16_CONST(-0.9998823474542126), FX16_CONST(-0.015339206284988121),
+ FX16_CONST(-0.9999047010828529), FX16_CONST(-0.01380538852806025),
+ FX16_CONST(-0.9999247018391445), FX16_CONST(-0.012271538285720512),
+ FX16_CONST(-0.9999423496760239), FX16_CONST(-0.010737659167264916),
+ FX16_CONST(-0.9999576445519639), FX16_CONST(-0.009203754782060083),
+ FX16_CONST(-0.9999705864309741), FX16_CONST(-0.007669828739531199),
+ FX16_CONST(-0.9999811752826011), FX16_CONST(-0.006135884649154416),
+ FX16_CONST(-0.9999894110819284), FX16_CONST(-0.00460192612044835),
+ FX16_CONST(-0.9999952938095762), FX16_CONST(-0.0030679567629664827),
+ FX16_CONST(-0.9999988234517019), FX16_CONST(-0.0015339801862851105),
+ FX16_CONST(-1.0), FX16_CONST(-1.8369701987210297e-16),
+ FX16_CONST(-0.9999988234517019), FX16_CONST(0.0015339801862847432),
+ FX16_CONST(-0.9999952938095762), FX16_CONST(0.003067956762966115),
+ FX16_CONST(-0.9999894110819284), FX16_CONST(0.004601926120447982),
+ FX16_CONST(-0.9999811752826011), FX16_CONST(0.0061358846491540485),
+ FX16_CONST(-0.9999705864309741), FX16_CONST(0.007669828739530832),
+ FX16_CONST(-0.9999576445519639), FX16_CONST(0.009203754782059715),
+ FX16_CONST(-0.9999423496760239), FX16_CONST(0.010737659167264548),
+ FX16_CONST(-0.9999247018391445), FX16_CONST(0.012271538285720144),
+ FX16_CONST(-0.9999047010828529), FX16_CONST(0.013805388528059882),
+ FX16_CONST(-0.9998823474542126), FX16_CONST(0.015339206284987753),
+ FX16_CONST(-0.9998576410058239), FX16_CONST(0.016872987947281527),
+ FX16_CONST(-0.9998305817958234), FX16_CONST(0.018406729905804796),
+ FX16_CONST(-0.9998011698878843), FX16_CONST(0.019940428551514577),
+ FX16_CONST(-0.9997694053512153), FX16_CONST(0.021474080275468918),
+ FX16_CONST(-0.9997352882605617), FX16_CONST(0.023007681468838945),
+ FX16_CONST(-0.9996988186962042), FX16_CONST(0.02454122852291202),
+ FX16_CONST(-0.9996599967439592), FX16_CONST(0.026074717829103793),
+ FX16_CONST(-0.9996188224951786), FX16_CONST(0.027608145778965795),
+ FX16_CONST(-0.9995752960467492), FX16_CONST(0.02914150876419394),
+ FX16_CONST(-0.9995294175010931), FX16_CONST(0.030674803176636116),
+ FX16_CONST(-0.999481186966167), FX16_CONST(0.03220802540830423),
+ FX16_CONST(-0.9994306045554617), FX16_CONST(0.0337411718513774),
+ FX16_CONST(-0.9993776703880028), FX16_CONST(0.035274238898213926),
+ FX16_CONST(-0.9993223845883495), FX16_CONST(0.036807222941358964),
+ FX16_CONST(-0.9992647472865945), FX16_CONST(0.038340120373552104),
+ FX16_CONST(-0.9992047586183639), FX16_CONST(0.03987292758773938),
+ FX16_CONST(-0.9991424187248169), FX16_CONST(0.04140564097707647),
+ FX16_CONST(-0.9990777277526454), FX16_CONST(0.042938256934940716),
+ FX16_CONST(-0.9990106858540734), FX16_CONST(0.044470771854938716),
+ FX16_CONST(-0.9989412931868569), FX16_CONST(0.046003182130914845),
+ FX16_CONST(-0.9988695499142836), FX16_CONST(0.04753548415695879),
+ FX16_CONST(-0.9987954562051724), FX16_CONST(0.04906767432741766),
+ FX16_CONST(-0.9987190122338729), FX16_CONST(0.05059974903689909),
+ FX16_CONST(-0.9986402181802653), FX16_CONST(0.05213170468028329),
+ FX16_CONST(-0.9985590742297593), FX16_CONST(0.05366353765273066),
+ FX16_CONST(-0.9984755805732948), FX16_CONST(0.055195244349689344),
+ FX16_CONST(-0.9983897374073402), FX16_CONST(0.05672682116690732),
+ FX16_CONST(-0.9983015449338929), FX16_CONST(0.05825826450043549),
+ FX16_CONST(-0.9982110033604782), FX16_CONST(0.059789570746639764),
+ FX16_CONST(-0.9981181129001492), FX16_CONST(0.06132073630220863),
+ FX16_CONST(-0.9980228737714862), FX16_CONST(0.06285175756416163),
+ FX16_CONST(-0.997925286198596), FX16_CONST(0.06438263092985695),
+ FX16_CONST(-0.9978253504111116), FX16_CONST(0.06591335279700346),
+ FX16_CONST(-0.9977230666441916), FX16_CONST(0.06744391956366387),
+ FX16_CONST(-0.9976184351385196), FX16_CONST(0.06897432762826672),
+ FX16_CONST(-0.9975114561403035), FX16_CONST(0.070504573389614),
+ FX16_CONST(-0.9974021299012753), FX16_CONST(0.07203465324688872),
+ FX16_CONST(-0.9972904566786902), FX16_CONST(0.07356456359966698),
+ FX16_CONST(-0.9971764367353262), FX16_CONST(0.07509430084792104),
+ FX16_CONST(-0.997060070339483), FX16_CONST(0.07662386139203138),
+ FX16_CONST(-0.9969413577649822), FX16_CONST(0.07815324163279429),
+ FX16_CONST(-0.9968202992911657), FX16_CONST(0.07968243797143033),
+ FX16_CONST(-0.9966968952028961), FX16_CONST(0.08121144680959191),
+ FX16_CONST(-0.9965711457905548), FX16_CONST(0.08274026454937533),
+ FX16_CONST(-0.9964430513500426), FX16_CONST(0.08426888759332388),
+ FX16_CONST(-0.996312612182778), FX16_CONST(0.08579731234443985),
+ FX16_CONST(-0.9961798285956969), FX16_CONST(0.0873255352061922),
+ FX16_CONST(-0.9960447009012521), FX16_CONST(0.088853552582524),
+ FX16_CONST(-0.9959072294174117), FX16_CONST(0.09038136087786454),
+ FX16_CONST(-0.9957674144676598), FX16_CONST(0.09190895649713245),
+ FX16_CONST(-0.9956252563809943), FX16_CONST(0.09343633584574766),
+ FX16_CONST(-0.9954807554919269), FX16_CONST(0.09496349532963905),
+ FX16_CONST(-0.9953339121404823), FX16_CONST(0.0964904313552528),
+ FX16_CONST(-0.9951847266721969), FX16_CONST(0.09801714032956009),
+ FX16_CONST(-0.9950331994381186), FX16_CONST(0.09954361866006897),
+ FX16_CONST(-0.9948793307948056), FX16_CONST(0.10106986275482763),
+ FX16_CONST(-0.9947231211043257), FX16_CONST(0.10259586902243625),
+ FX16_CONST(-0.9945645707342554), FX16_CONST(0.1041216338720547),
+ FX16_CONST(-0.9944036800576791), FX16_CONST(0.10564715371341002),
+ FX16_CONST(-0.994240449453188), FX16_CONST(0.10717242495680841),
+ FX16_CONST(-0.9940748793048795), FX16_CONST(0.10869744401313844),
+ FX16_CONST(-0.9939069700023561), FX16_CONST(0.11022220729388293),
+ FX16_CONST(-0.9937367219407246), FX16_CONST(0.11174671121112664),
+ FX16_CONST(-0.9935641355205953), FX16_CONST(0.11327095217756455),
+ FX16_CONST(-0.9933892111480808), FX16_CONST(0.11479492660650957),
+ FX16_CONST(-0.9932119492347946), FX16_CONST(0.1163186309119044),
+ FX16_CONST(-0.9930323501978514), FX16_CONST(0.11784206150832478),
+ FX16_CONST(-0.9928504144598651), FX16_CONST(0.11936521481099133),
+ FX16_CONST(-0.992666142448948), FX16_CONST(0.1208880872357772),
+ FX16_CONST(-0.9924795345987101), FX16_CONST(0.1224106751992156),
+ FX16_CONST(-0.9922905913482574), FX16_CONST(0.12393297511851173),
+ FX16_CONST(-0.9920993131421918), FX16_CONST(0.12545498341154596),
+ FX16_CONST(-0.9919057004306093), FX16_CONST(0.12697669649688575),
+ FX16_CONST(-0.9917097536690995), FX16_CONST(0.12849811079379322),
+ FX16_CONST(-0.9915114733187439), FX16_CONST(0.13001922272223354),
+ FX16_CONST(-0.9913108598461154), FX16_CONST(0.1315400287028826),
+ FX16_CONST(-0.9911079137232769), FX16_CONST(0.1330605251571387),
+ FX16_CONST(-0.99090263542778), FX16_CONST(0.13458070850712597),
+ FX16_CONST(-0.9906950254426646), FX16_CONST(0.13610057517570617),
+ FX16_CONST(-0.990485084256457), FX16_CONST(0.13762012158648618),
+ FX16_CONST(-0.9902728123631692), FX16_CONST(0.13913934416382562),
+ FX16_CONST(-0.9900582102622971), FX16_CONST(0.1406582393328488),
+ FX16_CONST(-0.9898412784588205), FX16_CONST(0.14217680351944778),
+ FX16_CONST(-0.9896220174632009), FX16_CONST(0.14369503315029433),
+ FX16_CONST(-0.9894004277913804), FX16_CONST(0.1452129246528475),
+ FX16_CONST(-0.9891765099647809), FX16_CONST(0.14673047445536194),
+ FX16_CONST(-0.9889502645103031), FX16_CONST(0.14824767898689553),
+ FX16_CONST(-0.9887216919603238), FX16_CONST(0.14976453467732115),
+ FX16_CONST(-0.9884907928526967), FX16_CONST(0.15128103795733),
+ FX16_CONST(-0.9882575677307495), FX16_CONST(0.15279718525844338),
+ FX16_CONST(-0.9880220171432835), FX16_CONST(0.15431297301302022),
+ FX16_CONST(-0.9877841416445723), FX16_CONST(0.15582839765426462),
+ FX16_CONST(-0.9875439417943593), FX16_CONST(0.1573434556162378),
+ FX16_CONST(-0.9873014181578584), FX16_CONST(0.15885814333386117),
+ FX16_CONST(-0.9870565713057511), FX16_CONST(0.16037245724292815),
+ FX16_CONST(-0.9868094018141854), FX16_CONST(0.16188639378011188),
+ FX16_CONST(-0.9865599102647754), FX16_CONST(0.16339994938297342),
+ FX16_CONST(-0.9863080972445988), FX16_CONST(0.1649131204899694),
+ FX16_CONST(-0.9860539633461955), FX16_CONST(0.16642590354046374),
+ FX16_CONST(-0.9857975091675675), FX16_CONST(0.16793829497473098),
+ FX16_CONST(-0.9855387353121761), FX16_CONST(0.16945029123396793),
+ FX16_CONST(-0.9852776423889412), FX16_CONST(0.17096188876030133),
+ FX16_CONST(-0.98501423101224), FX16_CONST(0.17247308399679537),
+ FX16_CONST(-0.9847485018019043), FX16_CONST(0.17398387338746338),
+ FX16_CONST(-0.9844804553832209), FX16_CONST(0.17549425337727115),
+ FX16_CONST(-0.9842100923869291), FX16_CONST(0.17700422041214864),
+ FX16_CONST(-0.9839374134492189), FX16_CONST(0.17851377093899756),
+ FX16_CONST(-0.9836624192117303), FX16_CONST(0.1800229014056997),
+ FX16_CONST(-0.9833851103215513), FX16_CONST(0.18153160826112447),
+ FX16_CONST(-0.9831054874312164), FX16_CONST(0.1830398879551406),
+ FX16_CONST(-0.9828235511987053), FX16_CONST(0.1845477369386194),
+ FX16_CONST(-0.9825393022874412), FX16_CONST(0.1860551516634466),
+ FX16_CONST(-0.9822527413662894), FX16_CONST(0.1875621285825297),
+ FX16_CONST(-0.9819638691095554), FX16_CONST(0.1890686641498056),
+ FX16_CONST(-0.9816726861969832), FX16_CONST(0.19057475482025232),
+ FX16_CONST(-0.9813791933137547), FX16_CONST(0.19208039704989216),
+ FX16_CONST(-0.9810833911504867), FX16_CONST(0.1935855872958035),
+ FX16_CONST(-0.9807852804032304), FX16_CONST(0.1950903220161283),
+ FX16_CONST(-0.9804848617734693), FX16_CONST(0.19659459767008042),
+ FX16_CONST(-0.9801821359681175), FX16_CONST(0.19809841071795306),
+ FX16_CONST(-0.9798771036995177), FX16_CONST(0.1996017576211306),
+ FX16_CONST(-0.9795697656854406), FX16_CONST(0.2011046348420917),
+ FX16_CONST(-0.979260122649082), FX16_CONST(0.20260703884442108),
+ FX16_CONST(-0.9789481753190622), FX16_CONST(0.20410896609281698),
+ FX16_CONST(-0.9786339244294233), FX16_CONST(0.20561041305309866),
+ FX16_CONST(-0.9783173707196278), FX16_CONST(0.20711137619221812),
+ FX16_CONST(-0.9779985149345571), FX16_CONST(0.2086118519782632),
+ FX16_CONST(-0.97767735782451), FX16_CONST(0.2101118368804695),
+ FX16_CONST(-0.9773539001452), FX16_CONST(0.2116113273692276),
+ FX16_CONST(-0.9770281426577543), FX16_CONST(0.21311031991609156),
+ FX16_CONST(-0.976700086128712), FX16_CONST(0.21460881099378626),
+ FX16_CONST(-0.9763697313300213), FX16_CONST(0.21610679707621913),
+ FX16_CONST(-0.9760370790390391), FX16_CONST(0.21760427463848342),
+ FX16_CONST(-0.9757021300385286), FX16_CONST(0.21910124015686974),
+ FX16_CONST(-0.975364885116657), FX16_CONST(0.22059769010887362),
+ FX16_CONST(-0.9750253450669942), FX16_CONST(0.22209362097320293),
+ FX16_CONST(-0.9746835106885108), FX16_CONST(0.22358902922978954),
+ FX16_CONST(-0.974339382785576), FX16_CONST(0.22508391135979255),
+ FX16_CONST(-0.973992962167956), FX16_CONST(0.22657826384560986),
+ FX16_CONST(-0.9736442496508119), FX16_CONST(0.22807208317088576),
+ FX16_CONST(-0.9732932460546981), FX16_CONST(0.22956536582051906),
+ FX16_CONST(-0.9729399522055603), FX16_CONST(0.23105810828067058),
+ FX16_CONST(-0.9725843689347323), FX16_CONST(0.23255030703877488),
+ FX16_CONST(-0.9722264970789364), FX16_CONST(0.2340419585835432),
+ FX16_CONST(-0.9718663374802794), FX16_CONST(0.23553305940497546),
+ FX16_CONST(-0.9715038909862518), FX16_CONST(0.2370236059943673),
+ FX16_CONST(-0.9711391584497253), FX16_CONST(0.23851359484431783),
+ FX16_CONST(-0.9707721407289505), FX16_CONST(0.24000302244874103),
+ FX16_CONST(-0.9704028386875555), FX16_CONST(0.24149188530286905),
+ FX16_CONST(-0.970031253194544), FX16_CONST(0.24298017990326376),
+ FX16_CONST(-0.9696573851242924), FX16_CONST(0.24446790274782418),
+ FX16_CONST(-0.9692812353565484), FX16_CONST(0.2459550503357948),
+ FX16_CONST(-0.968902804776429), FX16_CONST(0.24744161916777277),
+ FX16_CONST(-0.9685220942744174), FX16_CONST(0.2489276057457198),
+ FX16_CONST(-0.9681391047463624), FX16_CONST(0.25041300657296506),
+ FX16_CONST(-0.9677538370934755), FX16_CONST(0.2518978181542169),
+ FX16_CONST(-0.9673662922223285), FX16_CONST(0.25338203699557027),
+ FX16_CONST(-0.9669764710448523), FX16_CONST(0.25486565960451396),
+ FX16_CONST(-0.9665843744783332), FX16_CONST(0.25634868248994247),
+ FX16_CONST(-0.9661900034454126), FX16_CONST(0.2578311021621587),
+ FX16_CONST(-0.9657933588740837), FX16_CONST(0.2593129151328861),
+ FX16_CONST(-0.9653944416976894), FX16_CONST(0.2607941179152755),
+ FX16_CONST(-0.9649932528549203), FX16_CONST(0.2622747070239138),
+ FX16_CONST(-0.9645897932898129), FX16_CONST(0.26375467897483085),
+ FX16_CONST(-0.9641840639517459), FX16_CONST(0.26523403028551146),
+ FX16_CONST(-0.96377606579544), FX16_CONST(0.2667127574748982),
+ FX16_CONST(-0.963365799780954), FX16_CONST(0.2681908570634031),
+ FX16_CONST(-0.9629532668736839), FX16_CONST(0.2696683255729152),
+ FX16_CONST(-0.9625384680443594), FX16_CONST(0.2711451595268074),
+ FX16_CONST(-0.9621214042690417), FX16_CONST(0.27262135544994853),
+ FX16_CONST(-0.9617020765291227), FX16_CONST(0.2740969098687061),
+ FX16_CONST(-0.9612804858113206), FX16_CONST(0.27557181931095803),
+ FX16_CONST(-0.9608566331076797), FX16_CONST(0.27704608030609995),
+ FX16_CONST(-0.9604305194155658), FX16_CONST(0.2785196893850533),
+ FX16_CONST(-0.9600021457376661), FX16_CONST(0.2799926430802727),
+ FX16_CONST(-0.9595715130819846), FX16_CONST(0.2814649379257576),
+ FX16_CONST(-0.959138622461842), FX16_CONST(0.2829365704570551),
+ FX16_CONST(-0.9587034748958716), FX16_CONST(0.28440753721127177),
+ FX16_CONST(-0.9582660714080177), FX16_CONST(0.28587783472708067),
+ FX16_CONST(-0.957826413027533), FX16_CONST(0.2873474595447289),
+ FX16_CONST(-0.9573845007889761), FX16_CONST(0.28881640820604904),
+ FX16_CONST(-0.9569403357322089), FX16_CONST(0.29028467725446205),
+ FX16_CONST(-0.9564939189023951), FX16_CONST(0.29175226323498915),
+ FX16_CONST(-0.9560452513499964), FX16_CONST(0.2932191626942587),
+ FX16_CONST(-0.955594334130771), FX16_CONST(0.2946853721805145),
+ FX16_CONST(-0.9551411683057709), FX16_CONST(0.2961508882436233),
+ FX16_CONST(-0.9546857549413384), FX16_CONST(0.29761570743508586),
+ FX16_CONST(-0.9542280951091057), FX16_CONST(0.29907982630804025),
+ FX16_CONST(-0.9537681898859903), FX16_CONST(0.3005432414172734),
+ FX16_CONST(-0.9533060403541939), FX16_CONST(0.30200594931922814),
+ FX16_CONST(-0.9528416476011988), FX16_CONST(0.3034679465720107),
+ FX16_CONST(-0.952375012719766), FX16_CONST(0.304929229735402),
+ FX16_CONST(-0.9519061368079325), FX16_CONST(0.30638979537086064),
+ FX16_CONST(-0.9514350209690084), FX16_CONST(0.30784964004153476),
+ FX16_CONST(-0.9509616663115751), FX16_CONST(0.3093087603122687),
+ FX16_CONST(-0.9504860739494817), FX16_CONST(0.31076715274961164),
+ FX16_CONST(-0.9500082450018432), FX16_CONST(0.3122248139218244),
+ FX16_CONST(-0.9495281805930368), FX16_CONST(0.31368174039889113),
+ FX16_CONST(-0.9490458818527007), FX16_CONST(0.31513792875252217),
+ FX16_CONST(-0.9485613499157303), FX16_CONST(0.3165933755561658),
+ FX16_CONST(-0.9480745859222762), FX16_CONST(0.318048077385015),
+ FX16_CONST(-0.9475855910177413), FX16_CONST(0.3195020308160151),
+ FX16_CONST(-0.9470943663527773), FX16_CONST(0.32095523242787477),
+ FX16_CONST(-0.9466009130832836), FX16_CONST(0.3224076788010696),
+ FX16_CONST(-0.9461052323704034), FX16_CONST(0.32385936651785274),
+ FX16_CONST(-0.9456073253805213), FX16_CONST(0.3253102921622629),
+ FX16_CONST(-0.9451071932852605), FX16_CONST(0.32676045232013196),
+ FX16_CONST(-0.9446048372614805), FX16_CONST(0.328209843579092),
+ FX16_CONST(-0.9441002584912728), FX16_CONST(0.32965846252858716),
+ FX16_CONST(-0.9435934581619604), FX16_CONST(0.3311063057598762),
+ FX16_CONST(-0.9430844374660935), FX16_CONST(0.33255336986604417),
+ FX16_CONST(-0.9425731976014469), FX16_CONST(0.3339996514420095),
+ FX16_CONST(-0.9420597397710175), FX16_CONST(0.33544514708453105),
+ FX16_CONST(-0.9415440651830209), FX16_CONST(0.3368898533922196),
+ FX16_CONST(-0.9410261750508894), FX16_CONST(0.33833376696554085),
+ FX16_CONST(-0.9405060705932684), FX16_CONST(0.33977688440682674),
+ FX16_CONST(-0.9399837530340139), FX16_CONST(0.3412192023202824),
+ FX16_CONST(-0.9394592236021898), FX16_CONST(0.34266071731199454),
+ FX16_CONST(-0.9389324835320647), FX16_CONST(0.3441014259899383),
+ FX16_CONST(-0.9384035340631083), FX16_CONST(0.3455413249639887),
+ FX16_CONST(-0.9378723764399899), FX16_CONST(0.34698041084592346),
+ FX16_CONST(-0.937339011912575), FX16_CONST(0.3484186802494345),
+ FX16_CONST(-0.9368034417359216), FX16_CONST(0.34985612979013503),
+ FX16_CONST(-0.9362656671702785), FX16_CONST(0.35129275608556654),
+ FX16_CONST(-0.9357256894810805), FX16_CONST(0.3527285557552103),
+ FX16_CONST(-0.9351835099389477), FX16_CONST(0.35416352542049007),
+ FX16_CONST(-0.9346391298196808), FX16_CONST(0.35559766170478374),
+ FX16_CONST(-0.9340925504042589), FX16_CONST(0.35703096123343003),
+ FX16_CONST(-0.9335437729788362), FX16_CONST(0.3584634206337367),
+ FX16_CONST(-0.9329927988347391), FX16_CONST(0.3598950365349876),
+ FX16_CONST(-0.9324396292684626), FX16_CONST(0.3613258055684539),
+ FX16_CONST(-0.9318842655816681), FX16_CONST(0.362755724367397),
+ FX16_CONST(-0.9313267090811805), FX16_CONST(0.36418478956707984),
+ FX16_CONST(-0.9307669610789837), FX16_CONST(0.36561299780477396),
+ FX16_CONST(-0.9302050228922193), FX16_CONST(0.36704034571976657),
+ FX16_CONST(-0.9296408958431814), FX16_CONST(0.3684668299533719),
+ FX16_CONST(-0.9290745812593159), FX16_CONST(0.3698924471489338),
+ FX16_CONST(-0.9285060804732156), FX16_CONST(0.3713171939518374),
+ FX16_CONST(-0.9279353948226179), FX16_CONST(0.3727410670095158),
+ FX16_CONST(-0.927362525650401), FX16_CONST(0.37416406297145816),
+ FX16_CONST(-0.926787474304582), FX16_CONST(0.3755861784892167),
+ FX16_CONST(-0.9262102421383115), FX16_CONST(0.37700741021641787),
+ FX16_CONST(-0.9256308305098728), FX16_CONST(0.37842775480876534),
+ FX16_CONST(-0.9250492407826776), FX16_CONST(0.3798472089240511),
+ FX16_CONST(-0.9244654743252626), FX16_CONST(0.38126576922216243),
+ FX16_CONST(-0.9238795325112866), FX16_CONST(0.38268343236509),
+ FX16_CONST(-0.9232914167195279), FX16_CONST(0.3841001950169346),
+ FX16_CONST(-0.9227011283338787), FX16_CONST(0.38551605384391857),
+ FX16_CONST(-0.9221086687433452), FX16_CONST(0.38693100551438847),
+ FX16_CONST(-0.9215140393420419), FX16_CONST(0.3883450466988263),
+ FX16_CONST(-0.9209172415291894), FX16_CONST(0.38975817406985663),
+ FX16_CONST(-0.9203182767091108), FX16_CONST(0.39117038430225337),
+ FX16_CONST(-0.9197171462912275), FX16_CONST(0.39258167407295114),
+ FX16_CONST(-0.9191138516900579), FX16_CONST(0.3939920400610479),
+ FX16_CONST(-0.9185083943252123), FX16_CONST(0.39540147894781624),
+ FX16_CONST(-0.9179007756213904), FX16_CONST(0.3968099874167104),
+ FX16_CONST(-0.9172909970083778), FX16_CONST(0.39821756215337384),
+ FX16_CONST(-0.9166790599210428), FX16_CONST(0.3996241998456464),
+ FX16_CONST(-0.9160649657993318), FX16_CONST(0.40102989718357535),
+ FX16_CONST(-0.9154487160882678), FX16_CONST(0.4024346508594183),
+ FX16_CONST(-0.9148303122379462), FX16_CONST(0.40383845756765413),
+ FX16_CONST(-0.9142097557035306), FX16_CONST(0.40524131400499),
+ FX16_CONST(-0.913587047945251), FX16_CONST(0.4066432168703685),
+ FX16_CONST(-0.9129621904283983), FX16_CONST(0.4080441628649783),
+ FX16_CONST(-0.9123351846233229), FX16_CONST(0.40944414869225737),
+ FX16_CONST(-0.9117060320054299), FX16_CONST(0.41084317105790386),
+ FX16_CONST(-0.9110747340551762), FX16_CONST(0.41224122666988294),
+ FX16_CONST(-0.9104412922580671), FX16_CONST(0.4136383122384348),
+ FX16_CONST(-0.9098057081046524), FX16_CONST(0.4150344244760812),
+ FX16_CONST(-0.9091679830905225), FX16_CONST(0.4164295600976369),
+ FX16_CONST(-0.9085281187163062), FX16_CONST(0.41782371582021216),
+ FX16_CONST(-0.9078861164876663), FX16_CONST(0.41921688836322396),
+ FX16_CONST(-0.9072419779152958), FX16_CONST(0.4206090744484027),
+ FX16_CONST(-0.9065957045149156), FX16_CONST(0.4220002707997992),
+ FX16_CONST(-0.9059472978072687), FX16_CONST(0.42339047414379566),
+ FX16_CONST(-0.9052967593181189), FX16_CONST(0.4247796812091086),
+ FX16_CONST(-0.9046440905782462), FX16_CONST(0.42616788872679956),
+ FX16_CONST(-0.9039892931234433), FX16_CONST(0.42755509343028214),
+ FX16_CONST(-0.9033323684945117), FX16_CONST(0.4289412920553297),
+ FX16_CONST(-0.902673318237259), FX16_CONST(0.43032648134008217),
+ FX16_CONST(-0.9020121439024933), FX16_CONST(0.431710658025057),
+ FX16_CONST(-0.9013488470460221), FX16_CONST(0.4330938188531518),
+ FX16_CONST(-0.9006834292286469), FX16_CONST(0.4344759605696557),
+ FX16_CONST(-0.9000158920161602), FX16_CONST(0.43585707992225564),
+ FX16_CONST(-0.8993462369793418), FX16_CONST(0.4372371736610436),
+ FX16_CONST(-0.898674465693954), FX16_CONST(0.43861623853852727),
+ FX16_CONST(-0.89800057974074), FX16_CONST(0.43999427130963303),
+ FX16_CONST(-0.8973245807054183), FX16_CONST(0.4413712687317166),
+ FX16_CONST(-0.8966464701786802), FX16_CONST(0.4427472275645701),
+ FX16_CONST(-0.895966249756185), FX16_CONST(0.4441221445704294),
+ FX16_CONST(-0.8952839210385577), FX16_CONST(0.4454960165139813),
+ FX16_CONST(-0.8945994856313828), FX16_CONST(0.4468688401623739),
+ FX16_CONST(-0.8939129451452034), FX16_CONST(0.4482406122852198),
+ FX16_CONST(-0.8932243011955153), FX16_CONST(0.4496113296546066),
+ FX16_CONST(-0.8925335554027646), FX16_CONST(0.45098098904510403),
+ FX16_CONST(-0.891840709392343), FX16_CONST(0.4523495872337704),
+ FX16_CONST(-0.8911457647945834), FX16_CONST(0.4537171210001635),
+ FX16_CONST(-0.890448723244758), FX16_CONST(0.4550835871263436),
+ FX16_CONST(-0.8897495863830729), FX16_CONST(0.45644898239688386),
+ FX16_CONST(-0.8890483558546646), FX16_CONST(0.4578133035988773),
+ FX16_CONST(-0.8883450333095962), FX16_CONST(0.45917654752194437),
+ FX16_CONST(-0.8876396204028542), FX16_CONST(0.46053871095823956),
+ FX16_CONST(-0.8869321187943423), FX16_CONST(0.46189979070246245),
+ FX16_CONST(-0.8862225301488807), FX16_CONST(0.46325978355186004),
+ FX16_CONST(-0.8855108561362), FX16_CONST(0.4646186863062378),
+ FX16_CONST(-0.8847970984309377), FX16_CONST(0.4659764957679663),
+ FX16_CONST(-0.8840812587126353), FX16_CONST(0.4673332087419879),
+ FX16_CONST(-0.8833633386657318), FX16_CONST(0.46868882203582757),
+ FX16_CONST(-0.8826433399795629), FX16_CONST(0.4700433324595954),
+ FX16_CONST(-0.881921264348355), FX16_CONST(0.4713967368259976),
+ FX16_CONST(-0.881197113471222), FX16_CONST(0.47274903195034285),
+ FX16_CONST(-0.8804708890521606), FX16_CONST(0.4741002146505502),
+ FX16_CONST(-0.8797425928000476), FX16_CONST(0.4754502817471554),
+ FX16_CONST(-0.8790122264286336), FX16_CONST(0.4767992300633218),
+ FX16_CONST(-0.8782797916565416), FX16_CONST(0.4781470564248429),
+ FX16_CONST(-0.8775452902072612), FX16_CONST(0.479493757660153),
+ FX16_CONST(-0.8768087238091457), FX16_CONST(0.48083933060033407),
+ FX16_CONST(-0.8760700941954069), FX16_CONST(0.4821837720791222),
+ FX16_CONST(-0.875329403104111), FX16_CONST(0.48352707893291835),
+ FX16_CONST(-0.8745866522781762), FX16_CONST(0.4848692480007909),
+ FX16_CONST(-0.8738418434653669), FX16_CONST(0.4862102761244863),
+ FX16_CONST(-0.8730949784182901), FX16_CONST(0.487550160148436),
+ FX16_CONST(-0.8723460588943914), FX16_CONST(0.4888888969197634),
+ FX16_CONST(-0.8715950866559513), FX16_CONST(0.4902264832882907),
+ FX16_CONST(-0.8708420634700791), FX16_CONST(0.4915629161065497),
+ FX16_CONST(-0.8700869911087115), FX16_CONST(0.49289819222978387),
+ FX16_CONST(-0.8693298713486067), FX16_CONST(0.49423230851595973),
+ FX16_CONST(-0.8685707059713408), FX16_CONST(0.49556526182577265),
+ FX16_CONST(-0.8678094967633035), FX16_CONST(0.496897049022654),
+ FX16_CONST(-0.8670462455156929), FX16_CONST(0.4982276669727815),
+ FX16_CONST(-0.8662809540245131), FX16_CONST(0.49955711254508167),
+ FX16_CONST(-0.8655136240905691), FX16_CONST(0.5008853826112407),
+ FX16_CONST(-0.8647442575194624), FX16_CONST(0.5022124740457108),
+ FX16_CONST(-0.8639728561215866), FX16_CONST(0.5035383837257178),
+ FX16_CONST(-0.8631994217121244), FX16_CONST(0.5048631085312671),
+ FX16_CONST(-0.8624239561110407), FX16_CONST(0.506186645345155),
+ FX16_CONST(-0.8616464611430814), FX16_CONST(0.5075089910529706),
+ FX16_CONST(-0.8608669386377673), FX16_CONST(0.508830142543107),
+ FX16_CONST(-0.8600853904293901), FX16_CONST(0.5101500967067669),
+ FX16_CONST(-0.8593018183570087), FX16_CONST(0.5114688504379699),
+ FX16_CONST(-0.858516224264443), FX16_CONST(0.5127864006335626),
+ FX16_CONST(-0.8577286100002722), FX16_CONST(0.5141027441932216),
+ FX16_CONST(-0.8569389774178288), FX16_CONST(0.5154178780194629),
+ FX16_CONST(-0.8561473283751945), FX16_CONST(0.5167317990176499),
+ FX16_CONST(-0.8553536647351959), FX16_CONST(0.5180445040959996),
+ FX16_CONST(-0.8545579883654008), FX16_CONST(0.5193559901655892),
+ FX16_CONST(-0.8537603011381115), FX16_CONST(0.5206662541403668),
+ FX16_CONST(-0.8529606049303637), FX16_CONST(0.5219752929371542),
+ FX16_CONST(-0.8521589016239198), FX16_CONST(0.5232831034756564),
+ FX16_CONST(-0.8513551931052651), FX16_CONST(0.5245896826784691),
+ FX16_CONST(-0.8505494812656038), FX16_CONST(0.5258950274710842),
+ FX16_CONST(-0.8497417680008528), FX16_CONST(0.527199134781901),
+ FX16_CONST(-0.8489320552116397), FX16_CONST(0.5285020015422283),
+ FX16_CONST(-0.8481203448032973), FX16_CONST(0.5298036246862946),
+ FX16_CONST(-0.8473066386858583), FX16_CONST(0.531104001151255),
+ FX16_CONST(-0.8464909387740519), FX16_CONST(0.5324031278771981),
+ FX16_CONST(-0.8456732469872993), FX16_CONST(0.5337010018071525),
+ FX16_CONST(-0.8448535652497072), FX16_CONST(0.5349976198870969),
+ FX16_CONST(-0.8440318954900665), FX16_CONST(0.536292979065963),
+ FX16_CONST(-0.8432082396418454), FX16_CONST(0.5375870762956455),
+ FX16_CONST(-0.8423825996431858), FX16_CONST(0.5388799085310085),
+ FX16_CONST(-0.8415549774368988), FX16_CONST(0.5401714727298924),
+ FX16_CONST(-0.8407253749704583), FX16_CONST(0.5414617658531231),
+ FX16_CONST(-0.8398937941959996), FX16_CONST(0.5427507848645157),
+ FX16_CONST(-0.8390602370703127), FX16_CONST(0.5440385267308838),
+ FX16_CONST(-0.838224705554838), FX16_CONST(0.5453249884220465),
+ FX16_CONST(-0.8373872016156618), FX16_CONST(0.5466101669108351),
+ FX16_CONST(-0.8365477272235122), FX16_CONST(0.5478940591730997),
+ FX16_CONST(-0.8357062843537528), FX16_CONST(0.5491766621877194),
+ FX16_CONST(-0.8348628749863801), FX16_CONST(0.5504579729366046),
+ FX16_CONST(-0.8340175011060181), FX16_CONST(0.5517379884047073),
+ FX16_CONST(-0.8331701647019131), FX16_CONST(0.5530167055800277),
+ FX16_CONST(-0.83232086776793), FX16_CONST(0.5542941214536197),
+ FX16_CONST(-0.8314696123025455), FX16_CONST(0.5555702330196018),
+ FX16_CONST(-0.8306164003088464), FX16_CONST(0.5568450372751599),
+ FX16_CONST(-0.8297612337945232), FX16_CONST(0.558118531220556),
+ FX16_CONST(-0.8289041147718649), FX16_CONST(0.5593907118591361),
+ FX16_CONST(-0.8280450452577557), FX16_CONST(0.5606615761973361),
+ FX16_CONST(-0.8271840272736694), FX16_CONST(0.561931121244689),
+ FX16_CONST(-0.8263210628456636), FX16_CONST(0.5631993440138339),
+ FX16_CONST(-0.8254561540043777), FX16_CONST(0.5644662415205193),
+ FX16_CONST(-0.8245893027850253), FX16_CONST(0.5657318107836131),
+ FX16_CONST(-0.8237205112273913), FX16_CONST(0.5669960488251088),
+ FX16_CONST(-0.8228497813758266), FX16_CONST(0.568258952670131),
+ FX16_CONST(-0.8219771152792418), FX16_CONST(0.5695205193469468),
+ FX16_CONST(-0.8211025149911049), FX16_CONST(0.570780745886967),
+ FX16_CONST(-0.8202259825694347), FX16_CONST(0.5720396293247569),
+ FX16_CONST(-0.8193475200767969), FX16_CONST(0.5732971666980422),
+ FX16_CONST(-0.8184671295802985), FX16_CONST(0.574553355047716),
+ FX16_CONST(-0.8175848131515839), FX16_CONST(0.5758081914178449),
+ FX16_CONST(-0.816700572866828), FX16_CONST(0.5770616728556792),
+ FX16_CONST(-0.8158144108067339), FX16_CONST(0.5783137964116554),
+ FX16_CONST(-0.8149263290565266), FX16_CONST(0.5795645591394057),
+ FX16_CONST(-0.8140363297059483), FX16_CONST(0.5808139580957646),
+ FX16_CONST(-0.8131444148492539), FX16_CONST(0.5820619903407751),
+ FX16_CONST(-0.8122505865852042), FX16_CONST(0.583308652937698),
+ FX16_CONST(-0.811354847017064), FX16_CONST(0.5845539429530151),
+ FX16_CONST(-0.8104571982525949), FX16_CONST(0.5857978574564388),
+ FX16_CONST(-0.8095576424040513), FX16_CONST(0.5870403935209181),
+ FX16_CONST(-0.8086561815881749), FX16_CONST(0.5882815482226454),
+ FX16_CONST(-0.8077528179261906), FX16_CONST(0.5895213186410635),
+ FX16_CONST(-0.8068475535437994), FX16_CONST(0.5907597018588739),
+ FX16_CONST(-0.8059403905711764), FX16_CONST(0.5919966949620408),
+ FX16_CONST(-0.8050313311429637), FX16_CONST(0.5932322950397998),
+ FX16_CONST(-0.8041203773982657), FX16_CONST(0.5944664991846645),
+ FX16_CONST(-0.8032075314806453), FX16_CONST(0.5956993044924328),
+ FX16_CONST(-0.8022927955381159), FX16_CONST(0.5969307080621962),
+ FX16_CONST(-0.8013761717231404), FX16_CONST(0.598160706996342),
+ FX16_CONST(-0.8004576621926228), FX16_CONST(0.5993892984005644),
+ FX16_CONST(-0.799537269107905), FX16_CONST(0.600616479383869),
+ FX16_CONST(-0.7986149946347607), FX16_CONST(0.6018422470585802),
+ FX16_CONST(-0.7976908409433914), FX16_CONST(0.6030665985403478),
+ FX16_CONST(-0.7967648102084189), FX16_CONST(0.6042895309481557),
+ FX16_CONST(-0.7958369046088837), FX16_CONST(0.6055110414043253),
+ FX16_CONST(-0.794907126328237), FX16_CONST(0.6067311270345245),
+ FX16_CONST(-0.7939754775543371), FX16_CONST(0.6079497849677737),
+ FX16_CONST(-0.7930419604794441), FX16_CONST(0.6091670123364527),
+ FX16_CONST(-0.7921065773002126), FX16_CONST(0.6103828062763091),
+ FX16_CONST(-0.7911693302176903), FX16_CONST(0.6115971639264617),
+ FX16_CONST(-0.7902302214373101), FX16_CONST(0.6128100824294096),
+ FX16_CONST(-0.7892892531688857), FX16_CONST(0.6140215589310385),
+ FX16_CONST(-0.7883464276266061), FX16_CONST(0.615231590580627),
+ FX16_CONST(-0.7874017470290317), FX16_CONST(0.6164401745308532),
+ FX16_CONST(-0.786455213599086), FX16_CONST(0.6176473079378036),
+ FX16_CONST(-0.785506829564054), FX16_CONST(0.6188529879609762),
+ FX16_CONST(-0.7845565971555752), FX16_CONST(0.6200572117632892),
+ FX16_CONST(-0.7836045186096382), FX16_CONST(0.6212599765110877),
+ FX16_CONST(-0.7826505961665761), FX16_CONST(0.6224612793741495),
+ FX16_CONST(-0.7816948320710597), FX16_CONST(0.6236611175256942),
+ FX16_CONST(-0.7807372285720947), FX16_CONST(0.6248594881423861),
+ FX16_CONST(-0.7797777879230146), FX16_CONST(0.6260563884043434),
+ FX16_CONST(-0.7788165123814759), FX16_CONST(0.6272518154951442),
+ FX16_CONST(-0.7778534042094529), FX16_CONST(0.6284457666018328),
+ FX16_CONST(-0.7768884656732328), FX16_CONST(0.6296382389149267),
+ FX16_CONST(-0.7759216990434078), FX16_CONST(0.6308292296284242),
+ FX16_CONST(-0.774953106594874), FX16_CONST(0.6320187359398088),
+ FX16_CONST(-0.7739826906068228), FX16_CONST(0.6332067550500572),
+ FX16_CONST(-0.7730104533627369), FX16_CONST(0.6343932841636456),
+ FX16_CONST(-0.7720363971503849), FX16_CONST(0.6355783204885557),
+ FX16_CONST(-0.771060524261814), FX16_CONST(0.6367618612362839),
+ FX16_CONST(-0.7700828369933481), FX16_CONST(0.6379439036218438),
+ FX16_CONST(-0.7691033376455797), FX16_CONST(0.6391244448637756),
+ FX16_CONST(-0.7681220285233654), FX16_CONST(0.6403034821841517),
+ FX16_CONST(-0.7671389119358203), FX16_CONST(0.6414810128085833),
+ FX16_CONST(-0.7661539901963133), FX16_CONST(0.6426570339662265),
+ FX16_CONST(-0.7651672656224592), FX16_CONST(0.6438315428897912),
+ FX16_CONST(-0.7641787405361168), FX16_CONST(0.6450045368155438),
+ FX16_CONST(-0.7631884172633813), FX16_CONST(0.6461760129833163),
+ FX16_CONST(-0.7621962981345789), FX16_CONST(0.6473459686365122),
+ FX16_CONST(-0.7612023854842622), FX16_CONST(0.648514401022112),
+ FX16_CONST(-0.7602066816512026), FX16_CONST(0.6496813073906829),
+ FX16_CONST(-0.7592091889783882), FX16_CONST(0.6508466849963808),
+ FX16_CONST(-0.7582099098130154), FX16_CONST(0.6520105310969595),
+ FX16_CONST(-0.7572088465064846), FX16_CONST(0.6531728429537768),
+ FX16_CONST(-0.7562060014143943), FX16_CONST(0.6543336178318007),
+ FX16_CONST(-0.7552013768965369), FX16_CONST(0.655492852999615),
+ FX16_CONST(-0.7541949753168894), FX16_CONST(0.6566505457294287),
+ FX16_CONST(-0.7531867990436126), FX16_CONST(0.6578066932970785),
+ FX16_CONST(-0.7521768504490427), FX16_CONST(0.6589612929820373),
+ FX16_CONST(-0.7511651319096864), FX16_CONST(0.6601143420674206),
+ FX16_CONST(-0.7501516458062154), FX16_CONST(0.6612658378399917),
+ FX16_CONST(-0.7491363945234596), FX16_CONST(0.6624157775901715),
+ FX16_CONST(-0.7481193804504037), FX16_CONST(0.6635641586120395),
+ FX16_CONST(-0.7471006059801802), FX16_CONST(0.6647109782033448),
+ FX16_CONST(-0.7460800735100638), FX16_CONST(0.6658562336655097),
+ FX16_CONST(-0.7450577854414658), FX16_CONST(0.6669999223036377),
+ FX16_CONST(-0.7440337441799296), FX16_CONST(0.6681420414265181),
+ FX16_CONST(-0.7430079521351219), FX16_CONST(0.6692825883466358),
+ FX16_CONST(-0.7419804117208312), FX16_CONST(0.670421560380173),
+ FX16_CONST(-0.7409511253549591), FX16_CONST(0.6715589548470183),
+ FX16_CONST(-0.7399200954595161), FX16_CONST(0.672694769070773),
+ FX16_CONST(-0.7388873244606156), FX16_CONST(0.6738290003787556),
+ FX16_CONST(-0.7378528147884663), FX16_CONST(0.6749616461020117),
+ FX16_CONST(-0.7368165688773701), FX16_CONST(0.6760927035753157),
+ FX16_CONST(-0.7357785891657136), FX16_CONST(0.6772221701371803),
+ FX16_CONST(-0.7347388780959634), FX16_CONST(0.6783500431298615),
+ FX16_CONST(-0.7336974381146601), FX16_CONST(0.6794763198993652),
+ FX16_CONST(-0.7326542716724131), FX16_CONST(0.6806009977954527),
+ FX16_CONST(-0.7316093812238929), FX16_CONST(0.6817240741716495),
+ FX16_CONST(-0.7305627692278277), FX16_CONST(0.6828455463852479),
+ FX16_CONST(-0.729514438146997), FX16_CONST(0.6839654117973154),
+ FX16_CONST(-0.7284643904482251), FX16_CONST(0.6850836677727005),
+ FX16_CONST(-0.7274126286023762), FX16_CONST(0.6862003116800381),
+ FX16_CONST(-0.7263591550843463), FX16_CONST(0.6873153408917587),
+ FX16_CONST(-0.725303972373061), FX16_CONST(0.6884287527840902),
+ FX16_CONST(-0.724247082951467), FX16_CONST(0.6895405447370668),
+ FX16_CONST(-0.7231884893065273), FX16_CONST(0.6906507141345346),
+ FX16_CONST(-0.7221281939292151), FX16_CONST(0.6917592583641579),
+ FX16_CONST(-0.7210661993145084), FX16_CONST(0.6928661748174243),
+ FX16_CONST(-0.7200025079613819), FX16_CONST(0.6939714608896537),
+ FX16_CONST(-0.7189371223728046), FX16_CONST(0.6950751139800007),
+ FX16_CONST(-0.7178700450557318), FX16_CONST(0.6961771314914629),
+ FX16_CONST(-0.7168012785210994), FX16_CONST(0.6972775108308866),
+ FX16_CONST(-0.715730825283819), FX16_CONST(0.6983762494089724),
+ FX16_CONST(-0.7146586878627694), FX16_CONST(0.6994733446402834),
+ FX16_CONST(-0.7135848687807937), FX16_CONST(0.7005687939432481),
+ FX16_CONST(-0.7125093705646924), FX16_CONST(0.7016625947401685),
+ FX16_CONST(-0.7114321957452164), FX16_CONST(0.7027547444572253),
+ FX16_CONST(-0.7103533468570622), FX16_CONST(0.703845240524485),
+ FX16_CONST(-0.709272826438866), FX16_CONST(0.7049340803759045),
+ FX16_CONST(-0.7081906370331956), FX16_CONST(0.7060212614493395),
+ FX16_CONST(-0.7071067811865477), FX16_CONST(0.7071067811865474),
+ FX16_CONST(-0.7060212614493399), FX16_CONST(0.7081906370331953),
+ FX16_CONST(-0.7049340803759048), FX16_CONST(0.7092728264388657),
+ FX16_CONST(-0.7038452405244854), FX16_CONST(0.7103533468570619),
+ FX16_CONST(-0.7027547444572256), FX16_CONST(0.7114321957452161),
+ FX16_CONST(-0.7016625947401687), FX16_CONST(0.7125093705646921),
+ FX16_CONST(-0.7005687939432484), FX16_CONST(0.7135848687807935),
+ FX16_CONST(-0.6994733446402838), FX16_CONST(0.7146586878627691),
+ FX16_CONST(-0.6983762494089727), FX16_CONST(0.7157308252838188),
+ FX16_CONST(-0.697277510830887), FX16_CONST(0.7168012785210991),
+ FX16_CONST(-0.6961771314914632), FX16_CONST(0.7178700450557315),
+ FX16_CONST(-0.695075113980001), FX16_CONST(0.7189371223728043),
+ FX16_CONST(-0.693971460889654), FX16_CONST(0.7200025079613817),
+ FX16_CONST(-0.6928661748174246), FX16_CONST(0.7210661993145082),
+ FX16_CONST(-0.6917592583641582), FX16_CONST(0.7221281939292149),
+ FX16_CONST(-0.6906507141345349), FX16_CONST(0.7231884893065271),
+ FX16_CONST(-0.6895405447370672), FX16_CONST(0.7242470829514667),
+ FX16_CONST(-0.6884287527840905), FX16_CONST(0.7253039723730607),
+ FX16_CONST(-0.687315340891759), FX16_CONST(0.726359155084346),
+ FX16_CONST(-0.6862003116800385), FX16_CONST(0.7274126286023759),
+ FX16_CONST(-0.6850836677727008), FX16_CONST(0.7284643904482249),
+ FX16_CONST(-0.6839654117973157), FX16_CONST(0.7295144381469967),
+ FX16_CONST(-0.6828455463852482), FX16_CONST(0.7305627692278274),
+ FX16_CONST(-0.6817240741716498), FX16_CONST(0.7316093812238925),
+ FX16_CONST(-0.680600997795453), FX16_CONST(0.7326542716724129),
+ FX16_CONST(-0.6794763198993655), FX16_CONST(0.7336974381146598),
+ FX16_CONST(-0.6783500431298618), FX16_CONST(0.7347388780959632),
+ FX16_CONST(-0.6772221701371807), FX16_CONST(0.7357785891657133),
+ FX16_CONST(-0.676092703575316), FX16_CONST(0.7368165688773698),
+ FX16_CONST(-0.674961646102012), FX16_CONST(0.737852814788466),
+ FX16_CONST(-0.6738290003787559), FX16_CONST(0.7388873244606152),
+ FX16_CONST(-0.6726947690707733), FX16_CONST(0.7399200954595158),
+ FX16_CONST(-0.6715589548470187), FX16_CONST(0.7409511253549589),
+ FX16_CONST(-0.6704215603801733), FX16_CONST(0.7419804117208308),
+ FX16_CONST(-0.6692825883466361), FX16_CONST(0.7430079521351216),
+ FX16_CONST(-0.6681420414265185), FX16_CONST(0.7440337441799294),
+ FX16_CONST(-0.666999922303638), FX16_CONST(0.7450577854414656),
+ FX16_CONST(-0.6658562336655101), FX16_CONST(0.7460800735100634),
+ FX16_CONST(-0.6647109782033451), FX16_CONST(0.7471006059801799),
+ FX16_CONST(-0.6635641586120399), FX16_CONST(0.7481193804504035),
+ FX16_CONST(-0.6624157775901718), FX16_CONST(0.7491363945234594),
+ FX16_CONST(-0.661265837839992), FX16_CONST(0.7501516458062152),
+ FX16_CONST(-0.6601143420674209), FX16_CONST(0.751165131909686),
+ FX16_CONST(-0.6589612929820376), FX16_CONST(0.7521768504490425),
+ FX16_CONST(-0.6578066932970789), FX16_CONST(0.7531867990436123),
+ FX16_CONST(-0.656650545729429), FX16_CONST(0.7541949753168892),
+ FX16_CONST(-0.6554928529996153), FX16_CONST(0.7552013768965365),
+ FX16_CONST(-0.654333617831801), FX16_CONST(0.7562060014143941),
+ FX16_CONST(-0.6531728429537771), FX16_CONST(0.7572088465064842),
+ FX16_CONST(-0.6520105310969597), FX16_CONST(0.7582099098130151),
+ FX16_CONST(-0.650846684996381), FX16_CONST(0.759209188978388),
+ FX16_CONST(-0.6496813073906832), FX16_CONST(0.7602066816512024),
+ FX16_CONST(-0.6485144010221123), FX16_CONST(0.7612023854842619),
+ FX16_CONST(-0.6473459686365125), FX16_CONST(0.7621962981345786),
+ FX16_CONST(-0.6461760129833166), FX16_CONST(0.763188417263381),
+ FX16_CONST(-0.6450045368155441), FX16_CONST(0.7641787405361166),
+ FX16_CONST(-0.6438315428897915), FX16_CONST(0.7651672656224588),
+ FX16_CONST(-0.6426570339662268), FX16_CONST(0.7661539901963129),
+ FX16_CONST(-0.6414810128085836), FX16_CONST(0.76713891193582),
+ FX16_CONST(-0.640303482184152), FX16_CONST(0.7681220285233651),
+ FX16_CONST(-0.639124444863776), FX16_CONST(0.7691033376455795),
+ FX16_CONST(-0.6379439036218442), FX16_CONST(0.7700828369933479),
+ FX16_CONST(-0.6367618612362842), FX16_CONST(0.7710605242618138),
+ FX16_CONST(-0.635578320488556), FX16_CONST(0.7720363971503846),
+ FX16_CONST(-0.6343932841636459), FX16_CONST(0.7730104533627365),
+ FX16_CONST(-0.6332067550500575), FX16_CONST(0.7739826906068226),
+ FX16_CONST(-0.6320187359398092), FX16_CONST(0.7749531065948737),
+ FX16_CONST(-0.6308292296284246), FX16_CONST(0.7759216990434076),
+ FX16_CONST(-0.629638238914927), FX16_CONST(0.7768884656732326),
+ FX16_CONST(-0.6284457666018332), FX16_CONST(0.7778534042094527),
+ FX16_CONST(-0.6272518154951445), FX16_CONST(0.7788165123814756),
+ FX16_CONST(-0.6260563884043437), FX16_CONST(0.7797777879230143),
+ FX16_CONST(-0.6248594881423865), FX16_CONST(0.7807372285720944),
+ FX16_CONST(-0.6236611175256945), FX16_CONST(0.7816948320710594),
+ FX16_CONST(-0.6224612793741499), FX16_CONST(0.7826505961665758),
+ FX16_CONST(-0.621259976511088), FX16_CONST(0.7836045186096379),
+ FX16_CONST(-0.6200572117632894), FX16_CONST(0.784556597155575),
+ FX16_CONST(-0.6188529879609765), FX16_CONST(0.7855068295640538),
+ FX16_CONST(-0.617647307937804), FX16_CONST(0.7864552135990857),
+ FX16_CONST(-0.6164401745308535), FX16_CONST(0.7874017470290314),
+ FX16_CONST(-0.6152315905806274), FX16_CONST(0.7883464276266059),
+ FX16_CONST(-0.6140215589310388), FX16_CONST(0.7892892531688854),
+ FX16_CONST(-0.6128100824294099), FX16_CONST(0.7902302214373098),
+ FX16_CONST(-0.611597163926462), FX16_CONST(0.7911693302176901),
+ FX16_CONST(-0.6103828062763095), FX16_CONST(0.7921065773002124),
+ FX16_CONST(-0.6091670123364531), FX16_CONST(0.7930419604794438),
+ FX16_CONST(-0.6079497849677741), FX16_CONST(0.7939754775543368),
+ FX16_CONST(-0.6067311270345248), FX16_CONST(0.7949071263282368),
+ FX16_CONST(-0.6055110414043257), FX16_CONST(0.7958369046088833),
+ FX16_CONST(-0.6042895309481561), FX16_CONST(0.7967648102084187),
+ FX16_CONST(-0.6030665985403482), FX16_CONST(0.7976908409433912),
+ FX16_CONST(-0.6018422470585806), FX16_CONST(0.7986149946347605),
+ FX16_CONST(-0.6006164793838693), FX16_CONST(0.7995372691079048),
+ FX16_CONST(-0.5993892984005648), FX16_CONST(0.8004576621926226),
+ FX16_CONST(-0.5981607069963424), FX16_CONST(0.8013761717231401),
+ FX16_CONST(-0.5969307080621965), FX16_CONST(0.8022927955381157),
+ FX16_CONST(-0.5956993044924332), FX16_CONST(0.803207531480645),
+ FX16_CONST(-0.5944664991846649), FX16_CONST(0.8041203773982655),
+ FX16_CONST(-0.5932322950398001), FX16_CONST(0.8050313311429633),
+ FX16_CONST(-0.5919966949620411), FX16_CONST(0.8059403905711762),
+ FX16_CONST(-0.5907597018588743), FX16_CONST(0.8068475535437992),
+ FX16_CONST(-0.5895213186410638), FX16_CONST(0.8077528179261904),
+ FX16_CONST(-0.5882815482226458), FX16_CONST(0.8086561815881746),
+ FX16_CONST(-0.5870403935209184), FX16_CONST(0.8095576424040509),
+ FX16_CONST(-0.5857978574564391), FX16_CONST(0.8104571982525945),
+ FX16_CONST(-0.5845539429530154), FX16_CONST(0.8113548470170636),
+ FX16_CONST(-0.5833086529376983), FX16_CONST(0.8122505865852039),
+ FX16_CONST(-0.5820619903407754), FX16_CONST(0.8131444148492536),
+ FX16_CONST(-0.580813958095765), FX16_CONST(0.8140363297059481),
+ FX16_CONST(-0.5795645591394061), FX16_CONST(0.8149263290565264),
+ FX16_CONST(-0.5783137964116558), FX16_CONST(0.8158144108067337),
+ FX16_CONST(-0.5770616728556796), FX16_CONST(0.8167005728668277),
+ FX16_CONST(-0.5758081914178452), FX16_CONST(0.8175848131515837),
+ FX16_CONST(-0.5745533550477163), FX16_CONST(0.8184671295802983),
+ FX16_CONST(-0.5732971666980426), FX16_CONST(0.8193475200767967),
+ FX16_CONST(-0.5720396293247574), FX16_CONST(0.8202259825694345),
+ FX16_CONST(-0.5707807458869674), FX16_CONST(0.8211025149911046),
+ FX16_CONST(-0.5695205193469471), FX16_CONST(0.8219771152792416),
+ FX16_CONST(-0.5682589526701314), FX16_CONST(0.8228497813758264),
+ FX16_CONST(-0.5669960488251091), FX16_CONST(0.8237205112273911),
+ FX16_CONST(-0.5657318107836136), FX16_CONST(0.8245893027850251),
+ FX16_CONST(-0.5644662415205196), FX16_CONST(0.8254561540043773),
+ FX16_CONST(-0.5631993440138342), FX16_CONST(0.8263210628456634),
+ FX16_CONST(-0.5619311212446894), FX16_CONST(0.8271840272736691),
+ FX16_CONST(-0.5606615761973366), FX16_CONST(0.8280450452577554),
+ FX16_CONST(-0.5593907118591365), FX16_CONST(0.8289041147718647),
+ FX16_CONST(-0.5581185312205563), FX16_CONST(0.8297612337945228),
+ FX16_CONST(-0.5568450372751602), FX16_CONST(0.8306164003088462),
+ FX16_CONST(-0.5555702330196022), FX16_CONST(0.8314696123025452),
+ FX16_CONST(-0.55429412145362), FX16_CONST(0.8323208677679297),
+ FX16_CONST(-0.553016705580028), FX16_CONST(0.8331701647019129),
+ FX16_CONST(-0.5517379884047078), FX16_CONST(0.8340175011060179),
+ FX16_CONST(-0.550457972936605), FX16_CONST(0.8348628749863799),
+ FX16_CONST(-0.5491766621877198), FX16_CONST(0.8357062843537525),
+ FX16_CONST(-0.5478940591731001), FX16_CONST(0.836547727223512),
+ FX16_CONST(-0.5466101669108354), FX16_CONST(0.8373872016156616),
+ FX16_CONST(-0.5453249884220468), FX16_CONST(0.8382247055548377),
+ FX16_CONST(-0.5440385267308842), FX16_CONST(0.8390602370703125),
+ FX16_CONST(-0.542750784864516), FX16_CONST(0.8398937941959994),
+ FX16_CONST(-0.5414617658531234), FX16_CONST(0.8407253749704581),
+ FX16_CONST(-0.5401714727298927), FX16_CONST(0.8415549774368986),
+ FX16_CONST(-0.5388799085310089), FX16_CONST(0.8423825996431855),
+ FX16_CONST(-0.5375870762956458), FX16_CONST(0.8432082396418452),
+ FX16_CONST(-0.5362929790659634), FX16_CONST(0.8440318954900663),
+ FX16_CONST(-0.5349976198870973), FX16_CONST(0.844853565249707),
+ FX16_CONST(-0.5337010018071529), FX16_CONST(0.8456732469872991),
+ FX16_CONST(-0.5324031278771986), FX16_CONST(0.8464909387740517),
+ FX16_CONST(-0.5311040011512553), FX16_CONST(0.8473066386858581),
+ FX16_CONST(-0.5298036246862949), FX16_CONST(0.8481203448032971),
+ FX16_CONST(-0.5285020015422286), FX16_CONST(0.8489320552116395),
+ FX16_CONST(-0.5271991347819014), FX16_CONST(0.8497417680008524),
+ FX16_CONST(-0.5258950274710845), FX16_CONST(0.8505494812656035),
+ FX16_CONST(-0.5245896826784694), FX16_CONST(0.8513551931052649),
+ FX16_CONST(-0.5232831034756568), FX16_CONST(0.8521589016239196),
+ FX16_CONST(-0.5219752929371545), FX16_CONST(0.8529606049303635),
+ FX16_CONST(-0.5206662541403673), FX16_CONST(0.8537603011381113),
+ FX16_CONST(-0.5193559901655895), FX16_CONST(0.8545579883654005),
+ FX16_CONST(-0.5180445040959999), FX16_CONST(0.8553536647351957),
+ FX16_CONST(-0.5167317990176503), FX16_CONST(0.8561473283751942),
+ FX16_CONST(-0.5154178780194633), FX16_CONST(0.8569389774178285),
+ FX16_CONST(-0.5141027441932219), FX16_CONST(0.857728610000272),
+ FX16_CONST(-0.512786400633563), FX16_CONST(0.8585162242644427),
+ FX16_CONST(-0.5114688504379703), FX16_CONST(0.8593018183570085),
+ FX16_CONST(-0.5101500967067673), FX16_CONST(0.8600853904293899),
+ FX16_CONST(-0.5088301425431074), FX16_CONST(0.8608669386377671),
+ FX16_CONST(-0.5075089910529711), FX16_CONST(0.8616464611430812),
+ FX16_CONST(-0.5061866453451553), FX16_CONST(0.8624239561110405),
+ FX16_CONST(-0.5048631085312675), FX16_CONST(0.8631994217121242),
+ FX16_CONST(-0.5035383837257181), FX16_CONST(0.8639728561215864),
+ FX16_CONST(-0.5022124740457112), FX16_CONST(0.8647442575194622),
+ FX16_CONST(-0.500885382611241), FX16_CONST(0.8655136240905689),
+ FX16_CONST(-0.499557112545082), FX16_CONST(0.8662809540245129),
+ FX16_CONST(-0.49822766697278187), FX16_CONST(0.8670462455156926),
+ FX16_CONST(-0.4968970490226544), FX16_CONST(0.8678094967633033),
+ FX16_CONST(-0.49556526182577304), FX16_CONST(0.8685707059713406),
+ FX16_CONST(-0.49423230851596006), FX16_CONST(0.8693298713486066),
+ FX16_CONST(-0.49289819222978426), FX16_CONST(0.8700869911087113),
+ FX16_CONST(-0.49156291610655), FX16_CONST(0.8708420634700789),
+ FX16_CONST(-0.4902264832882911), FX16_CONST(0.8715950866559511),
+ FX16_CONST(-0.4888888969197637), FX16_CONST(0.8723460588943912),
+ FX16_CONST(-0.4875501601484364), FX16_CONST(0.8730949784182899),
+ FX16_CONST(-0.4862102761244867), FX16_CONST(0.8738418434653666),
+ FX16_CONST(-0.48486924800079123), FX16_CONST(0.874586652278176),
+ FX16_CONST(-0.48352707893291874), FX16_CONST(0.8753294031041108),
+ FX16_CONST(-0.4821837720791226), FX16_CONST(0.8760700941954067),
+ FX16_CONST(-0.48083933060033446), FX16_CONST(0.8768087238091454),
+ FX16_CONST(-0.4794937576601534), FX16_CONST(0.8775452902072611),
+ FX16_CONST(-0.4781470564248433), FX16_CONST(0.8782797916565414),
+ FX16_CONST(-0.4767992300633222), FX16_CONST(0.8790122264286334),
+ FX16_CONST(-0.4754502817471558), FX16_CONST(0.8797425928000475),
+ FX16_CONST(-0.4741002146505506), FX16_CONST(0.8804708890521604),
+ FX16_CONST(-0.47274903195034323), FX16_CONST(0.8811971134712218),
+ FX16_CONST(-0.4713967368259979), FX16_CONST(0.8819212643483548),
+ FX16_CONST(-0.4700433324595958), FX16_CONST(0.8826433399795627),
+ FX16_CONST(-0.46868882203582796), FX16_CONST(0.8833633386657316),
+ FX16_CONST(-0.4673332087419883), FX16_CONST(0.8840812587126351),
+ FX16_CONST(-0.4659764957679667), FX16_CONST(0.8847970984309375),
+ FX16_CONST(-0.4646186863062382), FX16_CONST(0.8855108561361997),
+ FX16_CONST(-0.4632597835518604), FX16_CONST(0.8862225301488805),
+ FX16_CONST(-0.46189979070246284), FX16_CONST(0.8869321187943421),
+ FX16_CONST(-0.46053871095823995), FX16_CONST(0.8876396204028539),
+ FX16_CONST(-0.4591765475219447), FX16_CONST(0.888345033309596),
+ FX16_CONST(-0.4578133035988777), FX16_CONST(0.8890483558546644),
+ FX16_CONST(-0.45644898239688425), FX16_CONST(0.8897495863830727),
+ FX16_CONST(-0.455083587126344), FX16_CONST(0.8904487232447578),
+ FX16_CONST(-0.45371712100016387), FX16_CONST(0.8911457647945832),
+ FX16_CONST(-0.4523495872337707), FX16_CONST(0.8918407093923428),
+ FX16_CONST(-0.45098098904510436), FX16_CONST(0.8925335554027644),
+ FX16_CONST(-0.449611329654607), FX16_CONST(0.8932243011955151),
+ FX16_CONST(-0.44824061228522016), FX16_CONST(0.8939129451452031),
+ FX16_CONST(-0.44686884016237427), FX16_CONST(0.8945994856313826),
+ FX16_CONST(-0.4454960165139817), FX16_CONST(0.8952839210385576),
+ FX16_CONST(-0.4441221445704298), FX16_CONST(0.8959662497561849),
+ FX16_CONST(-0.44274722756457047), FX16_CONST(0.8966464701786799),
+ FX16_CONST(-0.441371268731717), FX16_CONST(0.8973245807054181),
+ FX16_CONST(-0.4399942713096334), FX16_CONST(0.8980005797407398),
+ FX16_CONST(-0.43861623853852766), FX16_CONST(0.8986744656939538),
+ FX16_CONST(-0.437237173661044), FX16_CONST(0.8993462369793416),
+ FX16_CONST(-0.43585707992225603), FX16_CONST(0.90001589201616),
+ FX16_CONST(-0.4344759605696561), FX16_CONST(0.9006834292286467),
+ FX16_CONST(-0.4330938188531522), FX16_CONST(0.9013488470460219),
+ FX16_CONST(-0.43171065802505737), FX16_CONST(0.9020121439024932),
+ FX16_CONST(-0.43032648134008256), FX16_CONST(0.9026733182372588),
+ FX16_CONST(-0.4289412920553301), FX16_CONST(0.9033323684945116),
+ FX16_CONST(-0.42755509343028253), FX16_CONST(0.9039892931234431),
+ FX16_CONST(-0.42616788872679995), FX16_CONST(0.904644090578246),
+ FX16_CONST(-0.42477968120910903), FX16_CONST(0.9052967593181187),
+ FX16_CONST(-0.42339047414379605), FX16_CONST(0.9059472978072685),
+ FX16_CONST(-0.42200027079979957), FX16_CONST(0.9065957045149154),
+ FX16_CONST(-0.42060907444840306), FX16_CONST(0.9072419779152956),
+ FX16_CONST(-0.41921688836322435), FX16_CONST(0.907886116487666),
+ FX16_CONST(-0.41782371582021255), FX16_CONST(0.908528118716306),
+ FX16_CONST(-0.41642956009763726), FX16_CONST(0.9091679830905224),
+ FX16_CONST(-0.4150344244760816), FX16_CONST(0.9098057081046522),
+ FX16_CONST(-0.41363831223843517), FX16_CONST(0.9104412922580669),
+ FX16_CONST(-0.41224122666988333), FX16_CONST(0.9110747340551761),
+ FX16_CONST(-0.41084317105790424), FX16_CONST(0.9117060320054297),
+ FX16_CONST(-0.40944414869225776), FX16_CONST(0.9123351846233226),
+ FX16_CONST(-0.4080441628649787), FX16_CONST(0.9129621904283981),
+ FX16_CONST(-0.40664321687036886), FX16_CONST(0.9135870479452509),
+ FX16_CONST(-0.4052413140049904), FX16_CONST(0.9142097557035305),
+ FX16_CONST(-0.4038384575676545), FX16_CONST(0.914830312237946),
+ FX16_CONST(-0.4024346508594187), FX16_CONST(0.9154487160882677),
+ FX16_CONST(-0.40102989718357573), FX16_CONST(0.9160649657993316),
+ FX16_CONST(-0.3996241998456468), FX16_CONST(0.9166790599210427),
+ FX16_CONST(-0.3982175621533742), FX16_CONST(0.9172909970083777),
+ FX16_CONST(-0.3968099874167108), FX16_CONST(0.9179007756213903),
+ FX16_CONST(-0.39540147894781663), FX16_CONST(0.918508394325212),
+ FX16_CONST(-0.39399204006104827), FX16_CONST(0.9191138516900577),
+ FX16_CONST(-0.3925816740729515), FX16_CONST(0.9197171462912274),
+ FX16_CONST(-0.39117038430225376), FX16_CONST(0.9203182767091106),
+ FX16_CONST(-0.389758174069857), FX16_CONST(0.9209172415291892),
+ FX16_CONST(-0.3883450466988267), FX16_CONST(0.9215140393420418),
+ FX16_CONST(-0.38693100551438886), FX16_CONST(0.9221086687433451),
+ FX16_CONST(-0.38551605384391896), FX16_CONST(0.9227011283338785),
+ FX16_CONST(-0.384100195016935), FX16_CONST(0.9232914167195276),
+ FX16_CONST(-0.3826834323650904), FX16_CONST(0.9238795325112865),
+ FX16_CONST(-0.3812657692221628), FX16_CONST(0.9244654743252624),
+ FX16_CONST(-0.3798472089240515), FX16_CONST(0.9250492407826775),
+ FX16_CONST(-0.3784277548087658), FX16_CONST(0.9256308305098727),
+ FX16_CONST(-0.37700741021641826), FX16_CONST(0.9262102421383114),
+ FX16_CONST(-0.3755861784892171), FX16_CONST(0.9267874743045819),
+ FX16_CONST(-0.37416406297145854), FX16_CONST(0.9273625256504009),
+ FX16_CONST(-0.3727410670095162), FX16_CONST(0.9279353948226177),
+ FX16_CONST(-0.3713171939518378), FX16_CONST(0.9285060804732155),
+ FX16_CONST(-0.3698924471489342), FX16_CONST(0.9290745812593157),
+ FX16_CONST(-0.36846682995337227), FX16_CONST(0.9296408958431813),
+ FX16_CONST(-0.367040345719767), FX16_CONST(0.9302050228922192),
+ FX16_CONST(-0.36561299780477435), FX16_CONST(0.9307669610789835),
+ FX16_CONST(-0.3641847895670802), FX16_CONST(0.9313267090811803),
+ FX16_CONST(-0.3627557243673974), FX16_CONST(0.931884265581668),
+ FX16_CONST(-0.3613258055684543), FX16_CONST(0.9324396292684624),
+ FX16_CONST(-0.359895036534988), FX16_CONST(0.932992798834739),
+ FX16_CONST(-0.3584634206337371), FX16_CONST(0.933543772978836),
+ FX16_CONST(-0.3570309612334304), FX16_CONST(0.9340925504042588),
+ FX16_CONST(-0.35559766170478413), FX16_CONST(0.9346391298196807),
+ FX16_CONST(-0.3541635254204905), FX16_CONST(0.9351835099389475),
+ FX16_CONST(-0.35272855575521067), FX16_CONST(0.9357256894810804),
+ FX16_CONST(-0.3512927560855669), FX16_CONST(0.9362656671702784),
+ FX16_CONST(-0.3498561297901354), FX16_CONST(0.9368034417359214),
+ FX16_CONST(-0.3484186802494349), FX16_CONST(0.9373390119125748),
+ FX16_CONST(-0.34698041084592385), FX16_CONST(0.9378723764399898),
+ FX16_CONST(-0.3455413249639891), FX16_CONST(0.9384035340631081),
+ FX16_CONST(-0.34410142598993876), FX16_CONST(0.9389324835320646),
+ FX16_CONST(-0.34266071731199493), FX16_CONST(0.9394592236021897),
+ FX16_CONST(-0.3412192023202828), FX16_CONST(0.9399837530340138),
+ FX16_CONST(-0.33977688440682713), FX16_CONST(0.9405060705932682),
+ FX16_CONST(-0.3383337669655413), FX16_CONST(0.9410261750508893),
+ FX16_CONST(-0.33688985339222), FX16_CONST(0.9415440651830208),
+ FX16_CONST(-0.33544514708453144), FX16_CONST(0.9420597397710174),
+ FX16_CONST(-0.3339996514420099), FX16_CONST(0.9425731976014468),
+ FX16_CONST(-0.33255336986604456), FX16_CONST(0.9430844374660934),
+ FX16_CONST(-0.3311063057598766), FX16_CONST(0.9435934581619603),
+ FX16_CONST(-0.32965846252858755), FX16_CONST(0.9441002584912727),
+ FX16_CONST(-0.3282098435790924), FX16_CONST(0.9446048372614803),
+ FX16_CONST(-0.32676045232013234), FX16_CONST(0.9451071932852604),
+ FX16_CONST(-0.32531029216226337), FX16_CONST(0.9456073253805212),
+ FX16_CONST(-0.32385936651785313), FX16_CONST(0.9461052323704033),
+ FX16_CONST(-0.32240767880106996), FX16_CONST(0.9466009130832835),
+ FX16_CONST(-0.3209552324278752), FX16_CONST(0.9470943663527772),
+ FX16_CONST(-0.31950203081601547), FX16_CONST(0.9475855910177412),
+ FX16_CONST(-0.31804807738501545), FX16_CONST(0.9480745859222761),
+ FX16_CONST(-0.31659337555616623), FX16_CONST(0.9485613499157302),
+ FX16_CONST(-0.3151379287525226), FX16_CONST(0.9490458818527006),
+ FX16_CONST(-0.3136817403988915), FX16_CONST(0.9495281805930367),
+ FX16_CONST(-0.31222481392182483), FX16_CONST(0.9500082450018431),
+ FX16_CONST(-0.3107671527496121), FX16_CONST(0.9504860739494815),
+ FX16_CONST(-0.30930876031226917), FX16_CONST(0.950961666311575),
+ FX16_CONST(-0.30784964004153514), FX16_CONST(0.9514350209690082),
+ FX16_CONST(-0.3063897953708611), FX16_CONST(0.9519061368079322),
+ FX16_CONST(-0.3049292297354024), FX16_CONST(0.9523750127197659),
+ FX16_CONST(-0.3034679465720111), FX16_CONST(0.9528416476011987),
+ FX16_CONST(-0.3020059493192286), FX16_CONST(0.9533060403541936),
+ FX16_CONST(-0.3005432414172738), FX16_CONST(0.9537681898859902),
+ FX16_CONST(-0.29907982630804064), FX16_CONST(0.9542280951091056),
+ FX16_CONST(-0.29761570743508625), FX16_CONST(0.9546857549413383),
+ FX16_CONST(-0.29615088824362373), FX16_CONST(0.9551411683057708),
+ FX16_CONST(-0.29468537218051494), FX16_CONST(0.9555943341307709),
+ FX16_CONST(-0.2932191626942591), FX16_CONST(0.9560452513499963),
+ FX16_CONST(-0.29175226323498954), FX16_CONST(0.956493918902395),
+ FX16_CONST(-0.2902846772544625), FX16_CONST(0.9569403357322088),
+ FX16_CONST(-0.2888164082060494), FX16_CONST(0.957384500788976),
+ FX16_CONST(-0.28734745954472934), FX16_CONST(0.9578264130275329),
+ FX16_CONST(-0.2858778347270811), FX16_CONST(0.9582660714080176),
+ FX16_CONST(-0.2844075372112722), FX16_CONST(0.9587034748958715),
+ FX16_CONST(-0.28293657045705556), FX16_CONST(0.9591386224618419),
+ FX16_CONST(-0.28146493792575805), FX16_CONST(0.9595715130819845),
+ FX16_CONST(-0.2799926430802731), FX16_CONST(0.960002145737666),
+ FX16_CONST(-0.27851968938505367), FX16_CONST(0.9604305194155657),
+ FX16_CONST(-0.27704608030610034), FX16_CONST(0.9608566331076795),
+ FX16_CONST(-0.2755718193109584), FX16_CONST(0.9612804858113205),
+ FX16_CONST(-0.2740969098687065), FX16_CONST(0.9617020765291225),
+ FX16_CONST(-0.2726213554499489), FX16_CONST(0.9621214042690416),
+ FX16_CONST(-0.27114515952680784), FX16_CONST(0.9625384680443592),
+ FX16_CONST(-0.2696683255729156), FX16_CONST(0.9629532668736838),
+ FX16_CONST(-0.26819085706340356), FX16_CONST(0.9633657997809539),
+ FX16_CONST(-0.2667127574748986), FX16_CONST(0.9637760657954398),
+ FX16_CONST(-0.26523403028551185), FX16_CONST(0.9641840639517458),
+ FX16_CONST(-0.2637546789748313), FX16_CONST(0.9645897932898128),
+ FX16_CONST(-0.2622747070239142), FX16_CONST(0.9649932528549202),
+ FX16_CONST(-0.26079411791527596), FX16_CONST(0.9653944416976893),
+ FX16_CONST(-0.2593129151328865), FX16_CONST(0.9657933588740836),
+ FX16_CONST(-0.25783110216215915), FX16_CONST(0.9661900034454125),
+ FX16_CONST(-0.25634868248994286), FX16_CONST(0.9665843744783331),
+ FX16_CONST(-0.2548656596045144), FX16_CONST(0.9669764710448522),
+ FX16_CONST(-0.25338203699557066), FX16_CONST(0.9673662922223284),
+ FX16_CONST(-0.2518978181542173), FX16_CONST(0.9677538370934754),
+ FX16_CONST(-0.25041300657296545), FX16_CONST(0.9681391047463623),
+ FX16_CONST(-0.2489276057457202), FX16_CONST(0.9685220942744173),
+ FX16_CONST(-0.24744161916777319), FX16_CONST(0.9689028047764289),
+ FX16_CONST(-0.2459550503357952), FX16_CONST(0.9692812353565483),
+ FX16_CONST(-0.2444679027478246), FX16_CONST(0.9696573851242923),
+ FX16_CONST(-0.24298017990326418), FX16_CONST(0.970031253194544),
+ FX16_CONST(-0.24149188530286947), FX16_CONST(0.9704028386875554),
+ FX16_CONST(-0.24000302244874144), FX16_CONST(0.9707721407289504),
+ FX16_CONST(-0.23851359484431825), FX16_CONST(0.9711391584497252),
+ FX16_CONST(-0.23702360599436773), FX16_CONST(0.9715038909862517),
+ FX16_CONST(-0.23553305940497588), FX16_CONST(0.9718663374802793),
+ FX16_CONST(-0.23404195858354362), FX16_CONST(0.9722264970789363),
+ FX16_CONST(-0.2325503070387753), FX16_CONST(0.9725843689347322),
+ FX16_CONST(-0.231058108280671), FX16_CONST(0.9729399522055602),
+ FX16_CONST(-0.22956536582051948), FX16_CONST(0.9732932460546981),
+ FX16_CONST(-0.22807208317088618), FX16_CONST(0.9736442496508119),
+ FX16_CONST(-0.22657826384561028), FX16_CONST(0.9739929621679558),
+ FX16_CONST(-0.22508391135979297), FX16_CONST(0.9743393827855759),
+ FX16_CONST(-0.22358902922978996), FX16_CONST(0.9746835106885107),
+ FX16_CONST(-0.22209362097320334), FX16_CONST(0.9750253450669942),
+ FX16_CONST(-0.22059769010887406), FX16_CONST(0.9753648851166569),
+ FX16_CONST(-0.21910124015687016), FX16_CONST(0.9757021300385285),
+ FX16_CONST(-0.21760427463848384), FX16_CONST(0.976037079039039),
+ FX16_CONST(-0.21610679707621955), FX16_CONST(0.9763697313300211),
+ FX16_CONST(-0.21460881099378668), FX16_CONST(0.9767000861287118),
+ FX16_CONST(-0.21311031991609197), FX16_CONST(0.9770281426577542),
+ FX16_CONST(-0.21161132736922802), FX16_CONST(0.9773539001452),
+ FX16_CONST(-0.21011183688046992), FX16_CONST(0.9776773578245099),
+ FX16_CONST(-0.20861185197826362), FX16_CONST(0.977998514934557),
+ FX16_CONST(-0.20711137619221853), FX16_CONST(0.9783173707196277),
+ FX16_CONST(-0.20561041305309907), FX16_CONST(0.9786339244294232),
+ FX16_CONST(-0.2041089660928174), FX16_CONST(0.9789481753190621),
+ FX16_CONST(-0.2026070388444215), FX16_CONST(0.979260122649082),
+ FX16_CONST(-0.20110463484209212), FX16_CONST(0.9795697656854405),
+ FX16_CONST(-0.19960175762113103), FX16_CONST(0.9798771036995176),
+ FX16_CONST(-0.19809841071795348), FX16_CONST(0.9801821359681174),
+ FX16_CONST(-0.19659459767008083), FX16_CONST(0.9804848617734693),
+ FX16_CONST(-0.19509032201612872), FX16_CONST(0.9807852804032303),
+ FX16_CONST(-0.1935855872958039), FX16_CONST(0.9810833911504866),
+ FX16_CONST(-0.19208039704989258), FX16_CONST(0.9813791933137546),
+ FX16_CONST(-0.19057475482025274), FX16_CONST(0.9816726861969831),
+ FX16_CONST(-0.18906866414980603), FX16_CONST(0.9819638691095554),
+ FX16_CONST(-0.18756212858253013), FX16_CONST(0.9822527413662893),
+ FX16_CONST(-0.18605515166344702), FX16_CONST(0.9825393022874411),
+ FX16_CONST(-0.18454773693861984), FX16_CONST(0.9828235511987052),
+ FX16_CONST(-0.183039887955141), FX16_CONST(0.9831054874312163),
+ FX16_CONST(-0.18153160826112488), FX16_CONST(0.9833851103215512),
+ FX16_CONST(-0.18002290140570013), FX16_CONST(0.9836624192117301),
+ FX16_CONST(-0.17851377093899798), FX16_CONST(0.9839374134492188),
+ FX16_CONST(-0.17700422041214905), FX16_CONST(0.984210092386929),
+ FX16_CONST(-0.17549425337727156), FX16_CONST(0.9844804553832209),
+ FX16_CONST(-0.1739838733874638), FX16_CONST(0.9847485018019042),
+ FX16_CONST(-0.17247308399679578), FX16_CONST(0.9850142310122398),
+ FX16_CONST(-0.17096188876030177), FX16_CONST(0.9852776423889411),
+ FX16_CONST(-0.16945029123396835), FX16_CONST(0.985538735312176),
+ FX16_CONST(-0.1679382949747314), FX16_CONST(0.9857975091675674),
+ FX16_CONST(-0.1664259035404642), FX16_CONST(0.9860539633461954),
+ FX16_CONST(-0.1649131204899698), FX16_CONST(0.9863080972445987),
+ FX16_CONST(-0.16339994938297386), FX16_CONST(0.9865599102647753),
+ FX16_CONST(-0.1618863937801123), FX16_CONST(0.9868094018141854),
+ FX16_CONST(-0.16037245724292856), FX16_CONST(0.987056571305751),
+ FX16_CONST(-0.15885814333386158), FX16_CONST(0.9873014181578583),
+ FX16_CONST(-0.15734345561623825), FX16_CONST(0.9875439417943592),
+ FX16_CONST(-0.15582839765426507), FX16_CONST(0.9877841416445722),
+ FX16_CONST(-0.15431297301302063), FX16_CONST(0.9880220171432835),
+ FX16_CONST(-0.1527971852584438), FX16_CONST(0.9882575677307495),
+ FX16_CONST(-0.15128103795733044), FX16_CONST(0.9884907928526966),
+ FX16_CONST(-0.1497645346773216), FX16_CONST(0.9887216919603238),
+ FX16_CONST(-0.14824767898689595), FX16_CONST(0.988950264510303),
+ FX16_CONST(-0.1467304744553624), FX16_CONST(0.9891765099647809),
+ FX16_CONST(-0.14521292465284794), FX16_CONST(0.9894004277913803),
+ FX16_CONST(-0.14369503315029475), FX16_CONST(0.9896220174632008),
+ FX16_CONST(-0.1421768035194482), FX16_CONST(0.9898412784588205),
+ FX16_CONST(-0.1406582393328492), FX16_CONST(0.9900582102622971),
+ FX16_CONST(-0.13913934416382603), FX16_CONST(0.9902728123631691),
+ FX16_CONST(-0.1376201215864866), FX16_CONST(0.990485084256457),
+ FX16_CONST(-0.1361005751757066), FX16_CONST(0.9906950254426646),
+ FX16_CONST(-0.13458070850712642), FX16_CONST(0.99090263542778),
+ FX16_CONST(-0.13306052515713912), FX16_CONST(0.9911079137232768),
+ FX16_CONST(-0.131540028702883), FX16_CONST(0.9913108598461154),
+ FX16_CONST(-0.13001922272223398), FX16_CONST(0.9915114733187439),
+ FX16_CONST(-0.12849811079379364), FX16_CONST(0.9917097536690994),
+ FX16_CONST(-0.12697669649688617), FX16_CONST(0.9919057004306093),
+ FX16_CONST(-0.12545498341154637), FX16_CONST(0.9920993131421917),
+ FX16_CONST(-0.12393297511851216), FX16_CONST(0.9922905913482574),
+ FX16_CONST(-0.12241067519921603), FX16_CONST(0.99247953459871),
+ FX16_CONST(-0.12088808723577762), FX16_CONST(0.9926661424489479),
+ FX16_CONST(-0.11936521481099176), FX16_CONST(0.992850414459865),
+ FX16_CONST(-0.1178420615083252), FX16_CONST(0.9930323501978514),
+ FX16_CONST(-0.11631863091190484), FX16_CONST(0.9932119492347945),
+ FX16_CONST(-0.11479492660650999), FX16_CONST(0.9933892111480807),
+ FX16_CONST(-0.11327095217756497), FX16_CONST(0.9935641355205953),
+ FX16_CONST(-0.11174671121112706), FX16_CONST(0.9937367219407246),
+ FX16_CONST(-0.11022220729388336), FX16_CONST(0.9939069700023561),
+ FX16_CONST(-0.10869744401313887), FX16_CONST(0.9940748793048794),
+ FX16_CONST(-0.10717242495680884), FX16_CONST(0.9942404494531879),
+ FX16_CONST(-0.10564715371341044), FX16_CONST(0.9944036800576791),
+ FX16_CONST(-0.10412163387205513), FX16_CONST(0.9945645707342554),
+ FX16_CONST(-0.10259586902243668), FX16_CONST(0.9947231211043257),
+ FX16_CONST(-0.10106986275482806), FX16_CONST(0.9948793307948056),
+ FX16_CONST(-0.0995436186600694), FX16_CONST(0.9950331994381186),
+ FX16_CONST(-0.0980171403295605), FX16_CONST(0.9951847266721969),
+ FX16_CONST(-0.09649043135525323), FX16_CONST(0.9953339121404822),
+ FX16_CONST(-0.09496349532963948), FX16_CONST(0.9954807554919269),
+ FX16_CONST(-0.09343633584574809), FX16_CONST(0.9956252563809943),
+ FX16_CONST(-0.09190895649713288), FX16_CONST(0.9957674144676598),
+ FX16_CONST(-0.09038136087786497), FX16_CONST(0.9959072294174117),
+ FX16_CONST(-0.08885355258252442), FX16_CONST(0.996044700901252),
+ FX16_CONST(-0.08732553520619263), FX16_CONST(0.9961798285956969),
+ FX16_CONST(-0.08579731234444028), FX16_CONST(0.996312612182778),
+ FX16_CONST(-0.08426888759332431), FX16_CONST(0.9964430513500426),
+ FX16_CONST(-0.08274026454937576), FX16_CONST(0.9965711457905548),
+ FX16_CONST(-0.08121144680959234), FX16_CONST(0.9966968952028961),
+ FX16_CONST(-0.07968243797143075), FX16_CONST(0.9968202992911657),
+ FX16_CONST(-0.07815324163279472), FX16_CONST(0.996941357764982),
+ FX16_CONST(-0.07662386139203181), FX16_CONST(0.997060070339483),
+ FX16_CONST(-0.07509430084792147), FX16_CONST(0.9971764367353261),
+ FX16_CONST(-0.07356456359966741), FX16_CONST(0.9972904566786902),
+ FX16_CONST(-0.07203465324688915), FX16_CONST(0.9974021299012753),
+ FX16_CONST(-0.07050457338961442), FX16_CONST(0.9975114561403035),
+ FX16_CONST(-0.06897432762826713), FX16_CONST(0.9976184351385196),
+ FX16_CONST(-0.06744391956366429), FX16_CONST(0.9977230666441916),
+ FX16_CONST(-0.06591335279700389), FX16_CONST(0.9978253504111116),
+ FX16_CONST(-0.06438263092985737), FX16_CONST(0.997925286198596),
+ FX16_CONST(-0.06285175756416206), FX16_CONST(0.9980228737714861),
+ FX16_CONST(-0.06132073630220906), FX16_CONST(0.9981181129001492),
+ FX16_CONST(-0.05978957074664019), FX16_CONST(0.9982110033604782),
+ FX16_CONST(-0.05825826450043591), FX16_CONST(0.9983015449338928),
+ FX16_CONST(-0.05672682116690774), FX16_CONST(0.9983897374073402),
+ FX16_CONST(-0.055195244349689775), FX16_CONST(0.9984755805732948),
+ FX16_CONST(-0.05366353765273108), FX16_CONST(0.9985590742297593),
+ FX16_CONST(-0.05213170468028372), FX16_CONST(0.9986402181802652),
+ FX16_CONST(-0.05059974903689952), FX16_CONST(0.9987190122338729),
+ FX16_CONST(-0.04906767432741809), FX16_CONST(0.9987954562051724),
+ FX16_CONST(-0.04753548415695922), FX16_CONST(0.9988695499142836),
+ FX16_CONST(-0.04600318213091527), FX16_CONST(0.9989412931868569),
+ FX16_CONST(-0.044470771854939146), FX16_CONST(0.9990106858540733),
+ FX16_CONST(-0.04293825693494114), FX16_CONST(0.9990777277526454),
+ FX16_CONST(-0.0414056409770769), FX16_CONST(0.9991424187248169),
+ FX16_CONST(-0.03987292758773981), FX16_CONST(0.9992047586183639),
+ FX16_CONST(-0.038340120373552534), FX16_CONST(0.9992647472865944),
+ FX16_CONST(-0.036807222941359394), FX16_CONST(0.9993223845883494),
+ FX16_CONST(-0.03527423889821435), FX16_CONST(0.9993776703880028),
+ FX16_CONST(-0.03374117185137782), FX16_CONST(0.9994306045554617),
+ FX16_CONST(-0.03220802540830466), FX16_CONST(0.999481186966167),
+ FX16_CONST(-0.030674803176636543), FX16_CONST(0.9995294175010931),
+ FX16_CONST(-0.029141508764194368), FX16_CONST(0.9995752960467492),
+ FX16_CONST(-0.027608145778966225), FX16_CONST(0.9996188224951786),
+ FX16_CONST(-0.02607471782910422), FX16_CONST(0.9996599967439592),
+ FX16_CONST(-0.024541228522912448), FX16_CONST(0.9996988186962042),
+ FX16_CONST(-0.023007681468839372), FX16_CONST(0.9997352882605617),
+ FX16_CONST(-0.021474080275469345), FX16_CONST(0.9997694053512153),
+ FX16_CONST(-0.019940428551515003), FX16_CONST(0.9998011698878843),
+ FX16_CONST(-0.018406729905805226), FX16_CONST(0.9998305817958234),
+ FX16_CONST(-0.016872987947281957), FX16_CONST(0.9998576410058239),
+ FX16_CONST(-0.015339206284988182), FX16_CONST(0.9998823474542126),
+ FX16_CONST(-0.01380538852806031), FX16_CONST(0.9999047010828529),
+ FX16_CONST(-0.012271538285720572), FX16_CONST(0.9999247018391445),
+ FX16_CONST(-0.010737659167264976), FX16_CONST(0.9999423496760239),
+ FX16_CONST(-0.009203754782060144), FX16_CONST(0.9999576445519639),
+ FX16_CONST(-0.007669828739531261), FX16_CONST(0.9999705864309741),
+ FX16_CONST(-0.006135884649154477), FX16_CONST(0.9999811752826011),
+ FX16_CONST(-0.004601926120448411), FX16_CONST(0.9999894110819284),
+ FX16_CONST(-0.003067956762966544), FX16_CONST(0.9999952938095762),
+ FX16_CONST(-0.0015339801862851719), FX16_CONST(0.9999988234517019)
+};
diff --git a/arm9/lib/NitroSDK/src/FX_vec.c b/arm9/lib/NitroSDK/src/FX_vec.c
new file mode 100644
index 00000000..005872ac
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/FX_vec.c
@@ -0,0 +1,109 @@
+#include "fx.h"
+
+#include "global.h"
+#include "registers.h"
+
+ARM_FUNC void VEC_Add(struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *dst){
+ dst->x = a->x + b->x;
+ dst->y = a->y + b->y;
+ dst->z = a->z + b->z;
+}
+
+ARM_FUNC void VEC_Subtract(struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *dst){
+ dst->x = a->x - b->x;
+ dst->y = a->y - b->y;
+ dst->z = a->z - b->z;
+}
+
+ARM_FUNC void VEC_Fx16Add(struct Vecx16 *a, struct Vecx16 *b, struct Vecx16 *dst){
+ dst->x = (s16)(a->x + b->x);
+ dst->y = (s16)(a->y + b->y);
+ dst->z = (s16)(a->z + b->z);
+}
+
+ARM_FUNC fx32 VEC_DotProduct(struct Vecx32 *a, struct Vecx32 *b){
+ return (fx32)(((fx64)a->x * b->x + (fx64)a->y * b->y + (fx64)a->z * b->z + (1 << (FX64_INT_SHIFT - 1))) >> FX64_INT_SHIFT);
+}
+
+ARM_FUNC fx32 VEC_Fx16DotProduct(struct Vecx16 *a, struct Vecx16 *b){
+ fx32 temp1, temp2;
+ temp1 = (a->x * b->x) + (a->y * b->y);
+ temp2 = (a->z * b->z) + (1 << (FX64_INT_SHIFT - 1));
+ return (fx32)(((fx64)temp1 + temp2) >> FX64_INT_SHIFT);
+}
+
+ARM_FUNC void VEC_CrossProduct(struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *dst){
+ fx32 x, y, z;
+ x = (fx32)(((fx64)a->y * b->z - (fx64)a->z * b->y + (1 << (FX64_INT_SHIFT - 1))) >> FX64_INT_SHIFT);
+ y = (fx32)(((fx64)a->z * b->x - (fx64)a->x * b->z + (1 << (FX64_INT_SHIFT - 1))) >> FX64_INT_SHIFT);
+ z = (fx32)(((fx64)a->x * b->y - (fx64)a->y * b->x + (1 << (FX64_INT_SHIFT - 1))) >> FX64_INT_SHIFT);
+ dst->x = x;
+ dst->y = y;
+ dst->z = z;
+}
+
+ARM_FUNC void VEC_Fx16CrossProduct(struct Vecx16 *a, struct Vecx16 *b, struct Vecx16 *dst){
+ fx32 x, y, z;
+ x = ((a->y * b->z - a->z * b->y + (1 << (FX64_INT_SHIFT - 1))) >> FX64_INT_SHIFT);
+ y = ((a->z * b->x - a->x * b->z + (1 << (FX64_INT_SHIFT - 1))) >> FX64_INT_SHIFT);
+ z = ((a->x * b->y - a->y * b->x + (1 << (FX64_INT_SHIFT - 1))) >> FX64_INT_SHIFT);
+ dst->x = (fx16)x;
+ dst->y = (fx16)y;
+ dst->z = (fx16)z;
+}
+
+ARM_FUNC fx32 VEC_Mag(struct Vecx32 *a){
+ fx64 l2 = (fx64)a->x * a->x;
+ l2 += (fx64)a->y * a->y;
+ l2 += (fx64)a->z * a->z;
+ reg_CP_SQRTCNT = 0x1;
+ reg_CP_SQRT_PARAM = (u64)(l2 * 4);
+ while (reg_CP_SQRTCNT & 0x8000) {} //wait for coprocessor to finish
+ return ((fx32)reg_CP_SQRT_RESULT + 1) >> 1;
+}
+
+ARM_FUNC void VEC_Normalize(struct Vecx32 *a, struct Vecx32 *dst){
+ fx64 l2 = (fx64)a->x * a->x;
+ l2 += (fx64)a->y * a->y;
+ l2 += (fx64)a->z * a->z;
+ //1/sqrt(l) is computed by calculating sqrt(l)*(1/l)
+ reg_CP_DIVCNT = 0x2;
+ reg_CP_DIV_NUMER = 0x0100000000000000;
+ reg_CP_DIV_DENOM = (u64)l2;
+ reg_CP_SQRTCNT = 0x1;
+ reg_CP_SQRT_PARAM = (u64)(l2 * 4);
+ while (reg_CP_SQRTCNT & 0x8000) {} //wait for sqrt to finish
+ fx32 sqrtresult = (fx32)reg_CP_SQRT_RESULT;
+ while (reg_CP_DIVCNT & 0x8000) {} //wait for division to finish
+ l2 = (fx64)reg_CP_DIV_RESULT;
+ l2 = sqrtresult * l2;
+ dst->x = (fx32)((l2 * a->x + (1LL << (0x2D - 1))) >> 0x2D);
+ dst->y = (fx32)((l2 * a->y + (1LL << (0x2D - 1))) >> 0x2D);
+ dst->z = (fx32)((l2 * a->z + (1LL << (0x2D - 1))) >> 0x2D);
+}
+
+ARM_FUNC void VEC_Fx16Normalize(struct Vecx16 *a, struct Vecx16 *dst){
+ fx64 l2 = a->x * a->x;
+ l2 += a->y * a->y;
+ l2 += a->z * a->z;
+ //1/sqrt(l) is computed by calculating sqrt(l)*(1/l)
+ reg_CP_DIVCNT = 0x2;
+ reg_CP_DIV_NUMER = 0x0100000000000000;
+ reg_CP_DIV_DENOM = (u64)l2;
+ reg_CP_SQRTCNT = 0x1;
+ reg_CP_SQRT_PARAM = (u64)(l2 * 4);
+ while (reg_CP_SQRTCNT & 0x8000) {} //wait for sqrt to finish
+ fx32 sqrtresult = (fx32)reg_CP_SQRT_RESULT;
+ while (reg_CP_DIVCNT & 0x8000) {} //wait for division to finish
+ l2 = (fx64)reg_CP_DIV_RESULT;
+ l2 = sqrtresult * l2;
+ dst->x = (fx16)((l2 * a->x + (1LL << (0x2D - 1))) >> 0x2D);
+ dst->y = (fx16)((l2 * a->y + (1LL << (0x2D - 1))) >> 0x2D);
+ dst->z = (fx16)((l2 * a->z + (1LL << (0x2D - 1))) >> 0x2D);
+}
+
+ARM_FUNC void VEC_MultAdd(fx32 factor, struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *dst){
+ dst->x = (fx32)(((fx64)factor * a->x) >> FX32_INT_SHIFT) + b->x;
+ dst->y = (fx32)(((fx64)factor * a->y) >> FX32_INT_SHIFT) + b->y;
+ dst->z = (fx32)(((fx64)factor * a->z) >> FX32_INT_SHIFT) + b->z;
+}
diff --git a/arm9/lib/NitroSDK/src/GX.c b/arm9/lib/NitroSDK/src/GX.c
new file mode 100644
index 00000000..f47c0131
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX.c
@@ -0,0 +1,126 @@
+#include "gx.h"
+
+#include "global.h"
+#include "OS_spinLock.h"
+#include "OS_terminate_proc.h"
+
+u32 GXi_DmaId = 3;
+vu16 GXi_VRamLockId = 0;
+
+static u16 sDispMode = 0;
+static u16 sIsDispOn = TRUE;
+
+#define _powcnt_init_mask (REG_GX_POWCNT_E2DGB_MASK | REG_GX_POWCNT_E2DG_MASK | REG_GX_POWCNT_RE_MASK | REG_GX_POWCNT_GE_MASK)
+
+ARM_FUNC void GX_Init(){
+ reg_GX_POWCNT |= REG_GX_POWCNT_DSEL_MASK;
+ reg_GX_POWCNT = (u16)((reg_GX_POWCNT & ~_powcnt_init_mask) | _powcnt_init_mask);
+ reg_GX_POWCNT = (u16)(reg_GX_POWCNT | REG_GX_POWCNT_LCD_MASK);
+ GX_InitGXState();
+ s32 temp;
+ while (GXi_VRamLockId == 0)
+ {
+ temp = OS_GetLockID();
+ if (temp == OS_LOCK_ID_ERROR)
+ {
+ OS_Terminate();
+ }
+ GXi_VRamLockId = (vu16)temp;
+ }
+ reg_GX_DISPSTAT = 0x0;
+ reg_GX_DISPCNT = 0x0;
+ if (GXi_DmaId != -1)
+ {
+ MI_DmaFill32(GXi_DmaId, (void *)&reg_G2_BG0CNT, 0x0, 0x60);
+ reg_GX_MASTER_BRIGHT = 0x0;
+ MI_DmaFill32(GXi_DmaId, (void *)&reg_GXS_DB_DISPCNT, 0x0, 0x70);
+ }
+ else
+ {
+ MIi_CpuClear32(0x0, (void *)&reg_G2_BG0CNT, 0x60);
+ reg_GX_MASTER_BRIGHT = 0x0;
+ MIi_CpuClear32(0x0, (void *)&reg_GXS_DB_DISPCNT, 0x70);
+ }
+ reg_G2_BG2PA = 0x100;
+ reg_G2_BG2PD = 0x100;
+ reg_G2_BG3PA = 0x100;
+ reg_G2_BG3PD = 0x100;
+ reg_G2S_DB_BG2PA = 0x100;
+ reg_G2S_DB_BG2PD = 0x100;
+ reg_G2S_DB_BG3PA = 0x100;
+ reg_G2S_DB_BG3PD = 0x100;
+}
+
+ARM_FUNC u32 GX_HBlankIntr(u32 enable){
+ u32 temp = (u32)(reg_GX_DISPSTAT & REG_GX_DISPSTAT_HBI_MASK);
+ if (enable)
+ {
+ reg_GX_DISPSTAT |= REG_GX_DISPSTAT_HBI_MASK;
+ }
+ else
+ {
+ reg_GX_DISPSTAT &= ~REG_GX_DISPSTAT_HBI_MASK;
+ }
+ return temp;
+}
+
+ARM_FUNC u32 GX_VBlankIntr(u32 enable){
+ u32 temp = (u32)(reg_GX_DISPSTAT & REG_GX_DISPSTAT_VBI_MASK);
+ if (enable)
+ {
+ reg_GX_DISPSTAT |= REG_GX_DISPSTAT_VBI_MASK;
+ }
+ else
+ {
+ reg_GX_DISPSTAT &= ~REG_GX_DISPSTAT_VBI_MASK;
+ }
+ return temp;
+}
+
+ARM_FUNC void GX_DispOff(){
+ u32 temp = reg_GX_DISPCNT;
+ sIsDispOn = FALSE;
+ sDispMode = (u16)((temp & REG_GX_DISPCNT_MODE_MASK) >> REG_GX_DISPCNT_MODE_SHIFT);
+ reg_GX_DISPCNT = temp & ~REG_GX_DISPCNT_MODE_MASK;
+}
+
+ARM_FUNC void GX_DispOn(){
+ sIsDispOn = TRUE;
+ if (sDispMode)
+ {
+ reg_GX_DISPCNT = (reg_GX_DISPCNT & ~REG_GX_DISPCNT_MODE_MASK) | (sDispMode << REG_GX_DISPCNT_MODE_SHIFT);
+ }
+ else
+ {
+ reg_GX_DISPCNT = reg_GX_DISPCNT | (GX_DISPMODE_GRAPHICS << REG_GX_DISPCNT_MODE_SHIFT);
+ }
+}
+
+ARM_FUNC void GX_SetGraphicsMode(GXDispMode dispMode, GXBGMode bgMode, GXBG0As bg0_2d3d){
+ u32 temp2 = reg_GX_DISPCNT;
+ sDispMode = (u16)dispMode;
+ if (!sIsDispOn)
+ dispMode = 0;
+ reg_GX_DISPCNT = ((bgMode << REG_GX_DISPCNT_BGMODE_SHIFT) | ((temp2 & ~(REG_GX_DISPCNT_BGMODE_MASK | REG_GX_DISPCNT_MODE_MASK | REG_GX_DISPCNT_BG02D3D_MASK | REG_GX_DISPCNT_VRAM_MASK)) | (dispMode << REG_GX_DISPCNT_MODE_SHIFT))) | (bg0_2d3d << REG_GX_DISPCNT_BG02D3D_SHIFT);
+ if (!sDispMode)
+ sIsDispOn = FALSE;
+}
+
+ARM_FUNC void GXS_SetGraphicsMode(GXBGMode mode){
+ reg_GXS_DB_DISPCNT = (reg_GXS_DB_DISPCNT & ~REG_GXS_DB_DISPCNT_BGMODE_MASK) | mode;
+}
+
+ARM_FUNC void GXx_SetMasterBrightness_(vu16 *dst, s32 brightness){
+ if (!brightness)
+ {
+ *dst = 0x0;
+ }
+ else if (brightness > 0)
+ {
+ *dst = (u16)((1 << REG_GX_MASTER_BRIGHT_E_MOD_SHIFT) | brightness);
+ }
+ else
+ {
+ *dst = (u16)((2 << REG_GX_MASTER_BRIGHT_E_MOD_SHIFT) | -brightness);
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/GX_asm.c b/arm9/lib/NitroSDK/src/GX_asm.c
new file mode 100644
index 00000000..1eb0a011
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_asm.c
@@ -0,0 +1,16 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+//looks like asm and says asm on the tin...
+ARM_FUNC asm void GX_SendFifo48B(void *src, void *dst){
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/GX_bgcnt.c b/arm9/lib/NitroSDK/src/GX_bgcnt.c
new file mode 100644
index 00000000..91a67655
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_bgcnt.c
@@ -0,0 +1,194 @@
+#include "global.h"
+#include "gx.h"
+
+ARM_FUNC void *G2_GetBG0ScrPtr(){
+ u32 temp = (u32)(((reg_G2_BG0CNT & 0x1F00) >> 0x8) << 0xB);
+ return (void *)(0x6000000 + (((reg_GX_DISPCNT & 0x38000000) >> 0x1B) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG0ScrPtr(){
+ return (void *)(0x6200000 + (((reg_G2S_DB_BG0CNT & 0x1F00) >> 0x8) << 0xB));
+}
+
+ARM_FUNC void *G2_GetBG1ScrPtr(){
+ u32 temp = (u32)(((reg_G2_BG1CNT & 0x1F00) >> 0x8) << 0xB);
+ return (void *)(0x6000000 + (((reg_GX_DISPCNT & 0x38000000) >> 0x1B) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG1ScrPtr(){
+ return (void *)(0x6200000 + (((reg_G2S_DB_BG1CNT & 0x1F00) >> 0x8) << 0xB));
+}
+
+ARM_FUNC void *G2_GetBG2ScrPtr(){
+ u32 temp12 = (reg_GX_DISPCNT & 0x7);
+ u32 temp3 = reg_G2_BG2CNT;
+ u32 temp2 = (((reg_GX_DISPCNT & 0x38000000) >> 0x1B) << 0x10);
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6000000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 6:
+ return (void *)0x6000000;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG2ScrPtr(){
+ u32 temp12 = (reg_GXS_DB_DISPCNT & 0x7);
+ u32 temp3 = reg_G2S_DB_BG2CNT;
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6200000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG3ScrPtr(){
+ u32 temp12 = (reg_GX_DISPCNT & 0x7);
+ u32 temp3 = reg_G2_BG3CNT;
+ u32 temp2 = (((reg_GX_DISPCNT & 0x38000000) >> 0x1B) << 0x10);
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 3:
+ case 4:
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6000000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG3ScrPtr(){
+ u32 temp12 = (reg_GXS_DB_DISPCNT & 0x7);
+ u32 temp3 = reg_G2S_DB_BG3CNT;
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 3:
+ case 4:
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6200000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG0CharPtr(){
+ u32 temp = (u32)(((reg_G2_BG0CNT & 0x3C) >> 0x2) << 0xE);
+ return (void *)(0x6000000 + (((reg_GX_DISPCNT & 0x7000000) >> 0x18) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG0CharPtr(){
+ return (void *)(0x6200000 + (((reg_G2S_DB_BG0CNT & 0x3C) >> 0x2) << 0xE));
+}
+
+ARM_FUNC void *G2_GetBG1CharPtr(){
+ u32 temp = (u32)(((reg_G2_BG1CNT & 0x3C) >> 0x2) << 0xE);
+ return (void *)(0x6000000 + (((reg_GX_DISPCNT & 0x7000000) >> 0x18) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG1CharPtr(){
+ return (void *)(0x6200000 + (((reg_G2S_DB_BG1CNT & 0x3C) >> 0x2) << 0xE));
+}
+
+ARM_FUNC void *G2_GetBG2CharPtr(){
+ s32 temp1 = (s32)(reg_GX_DISPCNT & 0x7);
+ u32 temp = reg_G2_BG2CNT;
+ if (temp1 < 5 || !(temp & 0x80))
+ {
+ u32 temp1 = (((reg_GX_DISPCNT & 0x7000000) >> 0x18) << 0x10);
+ u32 temp2 = (temp & 0x3C) >> 2;
+ return (void *)(0x6000000 + temp1 + (temp2 << 0xE));
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG2CharPtr(){
+ s32 temp1 = (s32)(reg_GXS_DB_DISPCNT & 0x7);
+ u32 temp = reg_G2S_DB_BG2CNT;
+ if (temp1 < 5 || !(temp & 0x80))
+ {
+ u32 temp2 = ((temp & 0x3C) >> 2) << 0xE;
+ return (void *)(0x6200000 + temp2);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG3CharPtr(){
+ s32 temp1 = (s32)(reg_GX_DISPCNT & 0x7);
+ u32 temp = reg_G2_BG3CNT;
+ if (temp1 < 3 || (temp1 < 6 && !(temp & 0x80)))
+ {
+ u32 temp1 = (((reg_GX_DISPCNT & 0x7000000) >> 0x18) << 0x10);
+ u32 temp2 = (temp & 0x3C) >> 2;
+ return (void *)(0x6000000 + temp1 + (temp2 << 0xE));
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG3CharPtr(){
+ s32 temp1 = (s32)(reg_GXS_DB_DISPCNT & 0x7);
+ u32 temp = reg_G2S_DB_BG3CNT;
+ if (temp1 < 3 || (temp1 < 6 && !(temp & 0x80)))
+ {
+ u32 temp2 = ((temp & 0x3C) >> 2) << 0xE;
+ return (void *)(0x6200000 + temp2);
+ }
+ else
+ {
+ return NULL;
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/GX_g2.c b/arm9/lib/NitroSDK/src/GX_g2.c
new file mode 100644
index 00000000..39b8bff4
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_g2.c
@@ -0,0 +1,65 @@
+#include "global.h"
+#include "gx.h"
+
+ARM_FUNC void G2x_SetBGyAffine_(u32 ptr, const struct Mtx22 *mtx, fx32 a, fx32 b, fx32 c, fx32 d){
+ fx32 temp0, temp1, temp2, temp3;
+ *((vu32 *)ptr + 0) = (u32)((u16)(fx16)(mtx->_[0] >> 4) | (u16)(fx16)(mtx->_[1] >> 4)<< 0x10);
+ *((vu32 *)ptr + 1) = (u32)((u16)(fx16)(mtx->_[2] >> 4) | (u16)(fx16)(mtx->_[3] >> 4)<< 0x10);
+ temp0 = c - a;
+ temp1 = d - b;
+ temp2 = mtx->_[0] * temp0 + mtx->_[1] * temp1 + (a << 0xC);
+ temp3 = mtx->_[2] * temp0 + mtx->_[3] * temp1 + (b << 0xC);
+ *((vu32 *)ptr + 2) = (u32)(temp2 >> 4);
+ *((vu32 *)ptr + 3) = (u32)(temp3 >> 4);
+}
+
+ARM_FUNC void G2x_SetBlendAlpha_(u32 *ptr, fx32 a, fx32 b, fx32 c, fx32 d){
+ *ptr = (u32)(((a | 0x40) | (b << 0x8)) | ((c | (d << 0x8)) << 0x10));
+}
+
+ARM_FUNC void G2x_SetBlendBrightness_(u16 *ptr, fx32 a, fx32 brightness){
+ if (brightness < 0)
+ {
+ ptr[0] = (u16)(a | 0xC0);
+ ptr[2] = (u16)(-brightness);
+ }
+ else
+ {
+ ptr[0] = (u16)(a | 0x80);
+ ptr[2] = (u16)brightness;
+ }
+}
+
+ARM_FUNC void G2x_SetBlendBrightnessExt_(u16 *ptr, fx32 a, fx32 b, fx32 c, fx32 d, fx32 brightness){
+ ptr[1] = (u16)(c | (d << 0x8));
+ if (brightness < 0)
+ {
+ ptr[0] = (u16)(0xC0 | a | (b << 0x8));
+ ptr[2] = (u16)(-brightness);
+ }
+ else
+ {
+ ptr[0] = (u16)(0x80 | a | (b << 0x8));
+ ptr[2] = (u16)brightness;
+ }
+}
+
+ARM_FUNC void G2x_ChangeBlendBrightness_(u16 *ptr, fx32 brightness){
+ u32 temp = *ptr;
+ if (brightness < 0)
+ {
+ if ((temp & 0xC0) == 0x80)
+ {
+ ptr[0] = (u16)((temp & ~0xC0) | 0xC0);
+ }
+ ptr[2] = (u16)(-brightness);
+ }
+ else
+ {
+ if ((temp & 0xC0) == 0xC0)
+ {
+ ptr[0] = (u16)((temp & ~0xC0) | 0x80);
+ }
+ ptr[2] = (u16)brightness;
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/GX_g3.c b/arm9/lib/NitroSDK/src/GX_g3.c
new file mode 100644
index 00000000..45b6b11b
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_g3.c
@@ -0,0 +1,35 @@
+#include "global.h"
+#include "gx.h"
+
+
+ARM_FUNC void G3_BeginMakeDL(struct GXDLInfo *displaylist, void *r1, u32 r2){
+ displaylist->length = r2;
+ displaylist->bottom = r1;
+ displaylist->curr_cmd = r1;
+ displaylist->curr_param = (u32 *)r1 + 1;
+ displaylist->param0_cmd_flg = 0x0;
+}
+
+ARM_FUNC s32 G3_EndMakeDL(struct GXDLInfo *displaylist){
+ if (displaylist->bottom == (u32 *)displaylist->curr_cmd)
+ return 0;
+ //pads the buffer with 0 to 4byte alignment if needed
+ switch((u32)displaylist->curr_cmd & 0x3)
+ {
+ case 0:
+ return displaylist->curr_cmd - (u8 *)displaylist->bottom;
+ case 1:
+ *displaylist->curr_cmd++ = 0x0;
+ case 2:
+ *displaylist->curr_cmd++ = 0x0;
+ case 3:
+ *displaylist->curr_cmd++ = 0x0;
+ }
+ if (displaylist->param0_cmd_flg)
+ {
+ *displaylist->curr_param++ = 0x0;
+ displaylist->param0_cmd_flg = 0x0;
+ }
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param;
+ return displaylist->curr_cmd - (u8 *)displaylist->bottom;
+}
diff --git a/arm9/lib/NitroSDK/src/GX_g3_util.c b/arm9/lib/NitroSDK/src/GX_g3_util.c
new file mode 100644
index 00000000..e647f1c7
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_g3_util.c
@@ -0,0 +1,259 @@
+#include "global.h"
+#include "gx.h"
+
+
+ARM_FUNC void G3i_PerspectiveW_(fx32 fovsin, fx32 fovcos, fx32 ratio, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx){
+ fx32 fovcot, temp1, temp2;
+ fx64c temp0;
+ vu32 *reg_ptr;
+
+ fovcot = FX_Div(fovcos, fovsin);
+ if (scale != 0x1000) //!= 1.0
+ fovcot = (fovcot * scale) / 0x1000;
+ reg_CP_DIV_NUMER = (u64)((s64)fovcot << 0x20);
+ reg_CP_DIV_DENOM = (u32)ratio;
+ if (load)
+ {
+ reg_G3_MTX_MODE = 0x0;
+ reg_ptr = (vu32 *)&reg_G3_MTX_LOAD_4x4;
+ }
+ if (mtx)
+ {
+ mtx->_[1] = 0x0;
+ mtx->_[2] = 0x0;
+ mtx->_[3] = 0x0;
+ mtx->_[4] = 0x0;
+ mtx->_[6] = 0x0;
+ mtx->_[7] = 0x0;
+ mtx->_[8] = 0x0;
+ mtx->_[9] = 0x0;
+ mtx->_[11] = -scale;
+ mtx->_[12] = 0x0;
+ mtx->_[13] = 0x0;
+ mtx->_[15] = 0x0;
+ }
+ temp1 = FX_GetDivResult();
+ reg_CP_DIV_NUMER = (s64)0x1000 << 0x20;
+ reg_CP_DIV_DENOM = (u32)(near - far);
+ if (load)
+ {
+ *reg_ptr = (vu32)temp1;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = (vu32)fovcot;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp1;
+ mtx->_[5] = fovcot;
+ }
+ temp0 = FX_GetDivResultFx64c();
+ if (scale != 0x1000)
+ temp0 = (temp0 * scale) / 0x1000;
+ temp1 = (fx32)(((far + near) * temp0 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT);
+ temp2 = (fx32)((((fx32)(((fx64)(near << 1) * far + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT)) * temp0 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT);
+ if (load)
+ {
+ *reg_ptr = (vu32)temp1;
+ *reg_ptr = (vu32)(-scale);
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = (vu32)temp2;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[10] = temp1;
+ mtx->_[14] = temp2;
+ }
+}
+
+ARM_FUNC void G3i_OrthoW_(fx32 top, fx32 bottom, fx32 left, fx32 right, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx){
+ fx64c temp1, temp2, temp3;
+ fx32 temp0, temp4, temp5;
+ vu32 *reg_ptr;
+
+ FX_InvAsync(right - left);
+ if (load)
+ {
+ reg_G3_MTX_MODE = 0x0;
+ reg_ptr = (vu32 *)&reg_G3_MTX_LOAD_4x4;
+ }
+ if (mtx)
+ {
+ mtx->_[1] = 0x0;
+ mtx->_[2] = 0x0;
+ mtx->_[3] = 0x0;
+ mtx->_[4] = 0x0;
+ mtx->_[6] = 0x0;
+ mtx->_[7] = 0x0;
+ mtx->_[8] = 0x0;
+ mtx->_[9] = 0x0;
+ mtx->_[11] = 0x0;
+ mtx->_[15] = scale;
+ }
+ temp1 = FX_GetDivResultFx64c();
+ reg_CP_DIV_NUMER = (s64)0x1000 << 0x20;
+ reg_CP_DIV_DENOM = (u32)(top - bottom);
+ if (scale != 0x1000)
+ temp1 = (temp1 * scale) / 0x1000;
+ temp0 = (fx32)((0x2000 * temp1 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT);
+ if (load)
+ {
+ *reg_ptr = (vu32)temp0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp0;
+ }
+ temp2 = FX_GetDivResultFx64c();
+ reg_CP_DIV_NUMER = (s64)0x1000 << 0x20;
+ reg_CP_DIV_DENOM = (u32)(near - far);
+ if (scale != 0x1000)
+ temp2 = (temp2 * scale) / 0x1000;
+ temp0 = (fx32)((0x2000 * temp2 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT);
+ if (load)
+ {
+ *reg_ptr = (vu32)temp0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[5] = temp0;
+ }
+ temp3 = FX_GetDivResultFx64c();
+ if (scale != 0x1000)
+ temp3 = (temp3 * scale) / 0x1000;
+ temp0 = (fx32)((0x2000 * temp3 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT);
+ if (load)
+ {
+ *reg_ptr = (vu32)temp0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[10] = temp0;
+ }
+ temp0 = (fx32)(((-(right + left)) * temp1 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT);
+ temp4 = (fx32)(((-(top + bottom)) * temp2 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT);
+ temp5 = (fx32)(((far + near) * temp3 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT);
+ if (load)
+ {
+ *reg_ptr = (vu32)temp0;
+ *reg_ptr = (vu32)temp4;
+ *reg_ptr = (vu32)temp5;
+ *reg_ptr = (vu32)scale;
+ }
+ if (mtx)
+ {
+ mtx->_[12] = temp0;
+ mtx->_[13] = temp4;
+ mtx->_[14] = temp5;
+ }
+}
+
+ARM_FUNC void G3i_LookAt_(struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *c, u32 load, struct Mtx44 *mtx){
+ struct Vecx32 temp, temp1, temp2;
+ fx32 c1, c2, c3;
+ vu32 *reg_ptr;
+ temp.x = a->x - c->x;
+ temp.y = a->y - c->y;
+ temp.z = a->z - c->z;
+ VEC_Normalize(&temp, &temp);
+ VEC_CrossProduct(b, &temp, &temp1);
+ VEC_Normalize(&temp1, &temp1);
+ VEC_CrossProduct(&temp, &temp1, &temp2);
+ if (load)
+ {
+ reg_G3_MTX_MODE = 0x2;
+ reg_ptr = (vu32 *)&reg_G3_MTX_LOAD_4x3;
+ *reg_ptr = (vu32)temp1.x;
+ *reg_ptr = (vu32)temp2.x;
+ *reg_ptr = (vu32)temp.x;
+ *reg_ptr = (vu32)temp1.y;
+ *reg_ptr = (vu32)temp2.y;
+ *reg_ptr = (vu32)temp.y;
+ *reg_ptr = (vu32)temp1.z;
+ *reg_ptr = (vu32)temp2.z;
+ *reg_ptr = (vu32)temp.z;
+ }
+ c1 = -VEC_DotProduct(a, &temp1);
+ c2 = -VEC_DotProduct(a, &temp2);
+ c3 = -VEC_DotProduct(a, &temp);
+ if (load)
+ {
+ *reg_ptr = (vu32)c1;
+ *reg_ptr = (vu32)c2;
+ *reg_ptr = (vu32)c3;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp1.x;
+ mtx->_[1] = temp2.x;
+ mtx->_[2] = temp.x;
+ mtx->_[3] = temp1.y;
+ mtx->_[4] = temp2.y;
+ mtx->_[5] = temp.y;
+ mtx->_[6] = temp1.z;
+ mtx->_[7] = temp2.z;
+ mtx->_[8] = temp.z;
+ mtx->_[9] = c1;
+ mtx->_[10] = c2;
+ mtx->_[11] = c3;
+ }
+}
+
+ARM_FUNC void G3_RotX(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)&reg_G3_MTX_MULT_3x3;
+ *reg_ptr = 0x1000;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = (vu32)cosphi;
+ *reg_ptr = (vu32)sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = (vu32)(-sinphi);
+ *reg_ptr = (vu32)cosphi;
+}
+
+ARM_FUNC void G3_RotY(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)&reg_G3_MTX_MULT_3x3;
+ *reg_ptr = (vu32)cosphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = (vu32)(-sinphi);
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x1000;
+ *reg_ptr = 0x0;
+ *reg_ptr = (vu32)sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = (vu32)cosphi;
+}
+
+ARM_FUNC void G3_RotZ(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)&reg_G3_MTX_MULT_3x3;
+ *reg_ptr = (vu32)cosphi;
+ *reg_ptr = (vu32)sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = (vu32)(-sinphi);
+ *reg_ptr = (vu32)cosphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x1000;
+}
diff --git a/arm9/lib/NitroSDK/src/GX_g3b.c b/arm9/lib/NitroSDK/src/GX_g3b.c
new file mode 100644
index 00000000..a3b96a0b
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_g3b.c
@@ -0,0 +1,119 @@
+#include "global.h"
+#include "gx.h"
+
+
+ARM_FUNC void G3BS_LoadMtx44(struct GXDLInfo *displaylist, struct Mtx44 *mtx){
+ *(u32 *)displaylist->curr_cmd = 0x16;
+ MI_Copy64B(mtx, displaylist->curr_param);
+}
+
+ARM_FUNC void G3B_PushMtx(struct GXDLInfo *displaylist){
+ *(u32 *)displaylist->curr_cmd = 0x11;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_PopMtx(struct GXDLInfo *displaylist, void *mtx){
+ *(u32 *)displaylist->curr_cmd = 0x12;
+ *displaylist->curr_param = (u32)mtx;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_LoadMtx44(struct GXDLInfo *displaylist, struct Mtx44 *mtx){
+ G3BS_LoadMtx44(displaylist, mtx);
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + sizeof(struct Mtx44);
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+//color format is RGB555, stored in the lower bits
+ARM_FUNC void G3B_Color(struct GXDLInfo * displaylist, u32 vtx_col){
+ *(u32 *)displaylist->curr_cmd = 0x20;
+ *displaylist->curr_param = vtx_col;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+/*
+Only feed normalized Vectors
+only the fractional part and the sign, which is in the first nonfraction bit
+since the vector is assumed to be normalized, are used
+*/
+ARM_FUNC void G3B_Normal(struct GXDLInfo * displaylist, fx16 x, fx16 y, fx16 z){
+ *(u32 *)displaylist->curr_cmd = 0x21;
+ *displaylist->curr_param = (u32)(((x >> 3) & 0x3FF) | (((y >> 3) & 0x3FF) << 0xA) | (((z >> 3) & 0x3FF) << 0x14));
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_Vtx(struct GXDLInfo * displaylist, fx32 x, fx32 y, fx32 z){
+ *(u32 *)displaylist->curr_cmd = 0x23;
+ displaylist->curr_param[0] = (u32)(u16)x | (u32)(u16)y << 0x10;
+ displaylist->curr_param[1] = (u32)(u16)z;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x8;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+//TODO: name arguments
+ARM_FUNC void G3B_PolygonAttr(struct GXDLInfo *displaylist, u32 r1, u32 r2, u32 r3, u32 r4, u32 r5, u32 r6){
+ *(u32 *)displaylist->curr_cmd = 0x29;
+ *displaylist->curr_param = r1 | r2 << 0x4 | r3 << 0x6 | r6 | r4 << 0x18 | r5 << 0x10;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_MaterialColorDiffAmb(struct GXDLInfo *displaylist, u32 diffuse_col, u32 ambient_col, u32 replace){
+ *(u32 *)displaylist->curr_cmd = 0x30;
+ u32 replace_vtx_color_with_diffuse;
+ if (replace)
+ replace_vtx_color_with_diffuse = TRUE;
+ else
+ replace_vtx_color_with_diffuse = FALSE;
+ *displaylist->curr_param = diffuse_col | ambient_col << 0x10 | replace_vtx_color_with_diffuse << 0xF;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_MaterialColorSpecEmi(struct GXDLInfo *displaylist, u32 specular_col, u32 emission_col, u32 shiny_table){
+ *(u32 *)displaylist->curr_cmd = 0x31;
+ u32 enable_shininess_table;
+ if (shiny_table)
+ enable_shininess_table = TRUE;
+ else
+ enable_shininess_table = FALSE;
+ *displaylist->curr_param = specular_col | emission_col << 0x10 | enable_shininess_table << 0xF;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+/*
+Only feed normalized Vectors
+only the fractional part and the sign, which is in the first nonfraction bit
+since the vector is assumed to be normalized, are used
+*/
+ARM_FUNC void G3B_LightVector(struct GXDLInfo * displaylist, u32 light_num, fx16 x, fx16 y, fx16 z){
+ *(u32 *)displaylist->curr_cmd = 0x32;
+ *displaylist->curr_param = ((x >> 3) & 0x3FF) | (((y >> 3) & 0x3FF) << 0xA) | (((z >> 3) & 0x3FF) << 0x14) | light_num << 0x1E;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_LightColor(struct GXDLInfo * displaylist, u32 light_num, u32 col){
+ *(u32 *)displaylist->curr_cmd = 0x33;
+ *displaylist->curr_param = col | light_num << 0x1E;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_Begin(struct GXDLInfo * displaylist, u32 type){
+ *(u32 *)displaylist->curr_cmd = 0x40;
+ *displaylist->curr_param = type;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_End(struct GXDLInfo * displaylist){
+ *(u32 *)displaylist->curr_cmd = 0x41;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
diff --git a/arm9/lib/NitroSDK/src/GX_g3imm.c b/arm9/lib/NitroSDK/src/GX_g3imm.c
new file mode 100644
index 00000000..1798338e
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_g3imm.c
@@ -0,0 +1,17 @@
+#include "global.h"
+#include "gx.h"
+
+ARM_FUNC void G3_LoadMtx43(struct Mtx43 *mtx){
+ reg_G3X_GXFIFO = 0x17;
+ GX_SendFifo48B(mtx, (void *)&reg_G3X_GXFIFO);
+}
+
+ARM_FUNC void G3_MultMtx43(struct Mtx43 *mtx){
+ reg_G3X_GXFIFO = 0x19;
+ GX_SendFifo48B(mtx, (void *)&reg_G3X_GXFIFO);
+}
+
+ARM_FUNC void G3_MultMtx33(struct Mtx33 *mtx){
+ reg_G3X_GXFIFO = 0x1A;
+ MI_Copy36B(mtx, (void *)&reg_G3X_GXFIFO);
+}
diff --git a/arm9/lib/NitroSDK/src/GX_g3x.c b/arm9/lib/NitroSDK/src/GX_g3x.c
new file mode 100644
index 00000000..9954c4cb
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_g3x.c
@@ -0,0 +1,235 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern u32 GXi_DmaId;
+
+ARM_FUNC asm void GXi_NopClearFifo128_(void *reg){
+ mov r1, #0x0
+ mov r2, #0x0
+ mov r3, #0x0
+ mov r12, #0x0
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ bx lr
+}
+
+ARM_FUNC void G3X_Init(){
+ G3X_ClearFifo();
+ reg_G3_END_VTXS = 0x0;
+ while (reg_G3X_GXSTAT & 0x8000000) {} //wait for geometry engine to not be busy
+ reg_G3X_DISP3DCNT = 0x0;
+ reg_G3X_GXSTAT = 0x0;
+ reg_G2_BG0OFS = 0x0;
+ reg_G3X_DISP3DCNT |= 0x2000;
+ reg_G3X_DISP3DCNT |= 0x1000;
+ reg_G3X_DISP3DCNT &= ~0x3002;
+ reg_G3X_DISP3DCNT = (u16)((reg_G3X_DISP3DCNT & ~0x3000) | 0x10);
+ reg_G3X_DISP3DCNT = (u16)(reg_G3X_DISP3DCNT & (u16)~0x3004);
+ reg_G3X_GXSTAT |= 0x8000;
+ reg_G3X_GXSTAT = (reg_G3X_GXSTAT & ~0xC0000000) | 0x80000000;
+ G3X_InitMtxStack();
+ reg_G3X_CLEAR_COLOR = 0x0;
+ reg_G3X_CLEAR_DEPTH = 0x7FFF;
+ reg_G3X_CLRIMAGE_OFFSET = 0x0;
+ reg_G3X_FOG_COLOR = 0x0;
+ reg_G3X_FOG_OFFSET = 0x0;
+ reg_G2_BG0CNT &= ~0x3;
+ G3X_InitTable();
+ reg_G3_POLYGON_ATTR = 0x1F0080;
+ reg_G3_TEXIMAGE_PARAM = 0x0;
+ reg_G3_TEXPLTT_BASE = 0x0;
+}
+
+ARM_FUNC void G3X_ResetMtxStack(){
+ while (reg_G3X_GXSTAT & 0x8000000) {}
+ reg_G3X_GXSTAT |= 0x8000;
+ reg_G3X_DISP3DCNT |= 0x2000;
+ reg_G3X_DISP3DCNT |= 0x1000;
+ G3X_ResetMtxStack_2();
+ reg_G3_POLYGON_ATTR = 0x1F0080;
+ reg_G3_TEXIMAGE_PARAM = 0x0;
+ reg_G3_TEXPLTT_BASE = 0x0;
+}
+
+ARM_FUNC void G3X_ClearFifo(){
+ GXi_NopClearFifo128_((void *)&reg_G3X_GXFIFO);
+ while (reg_G3X_GXSTAT & 0x8000000) {}
+}
+
+ARM_FUNC void G3X_InitMtxStack(){
+ u32 PV_level, PJ_level;
+ reg_G3X_GXSTAT |= 0x8000;
+ while (G3X_GetMtxStackLevelPV(&PV_level)) {}
+ while (G3X_GetMtxStackLevelPJ(&PJ_level)) {}
+ reg_G3_MTX_MODE = 0x3;
+ reg_G3_MTX_IDENTITY = 0x0;
+ reg_G3_MTX_MODE = 0x0;
+ if (PJ_level)
+ {
+ reg_G3_MTX_POP = PJ_level;
+ }
+ reg_G3_MTX_IDENTITY = 0x0;
+ reg_G3_MTX_MODE = 0x2;
+ reg_G3_MTX_POP = PV_level;
+ reg_G3_MTX_IDENTITY = 0x0;
+}
+
+ARM_FUNC void G3X_ResetMtxStack_2(){
+ u32 PV_level, PJ_level;
+ reg_G3X_GXSTAT |= 0x8000;
+ while (G3X_GetMtxStackLevelPV(&PV_level)) {}
+ while (G3X_GetMtxStackLevelPJ(&PJ_level)) {}
+ reg_G3_MTX_MODE = 0x3;
+ reg_G3_MTX_IDENTITY = 0x0;
+ reg_G3_MTX_MODE = 0x0;
+ if (PJ_level)
+ {
+ reg_G3_MTX_POP = PJ_level;
+ }
+
+ reg_G3_MTX_MODE = 0x2;
+ reg_G3_MTX_POP = PV_level;
+ reg_G3_MTX_IDENTITY = 0x0;
+
+}
+
+ARM_FUNC void G3X_SetFog(u32 enable, u32 alphamode, u32 depth, s32 offset){
+ if (enable)
+ {
+ reg_G3X_FOG_OFFSET = (u16)offset;
+ reg_G3X_DISP3DCNT = (u16)((reg_G3X_DISP3DCNT &~0x3f40) | (((depth << 0x8)| (alphamode << 0x6)|0x80 )));
+
+ }
+ else
+ {
+ reg_G3X_DISP3DCNT = (u16)(reg_G3X_DISP3DCNT & (u16)~0x3080);
+ }
+}
+
+ARM_FUNC u32 G3X_GetClipMtx(struct Mtx44 *dst){
+ if (reg_G3X_GXSTAT & 0x8000000)
+ {
+ return (u32)-1;
+ }
+ else
+ {
+ MI_Copy64B((void *)&reg_G3X_CLIPMTX_RESULT_0, dst);
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetVectorMtx(struct Mtx33 *dst){
+ if (reg_G3X_GXSTAT & 0x8000000)
+ {
+ return (u32)-1;
+ }
+ else
+ {
+ MI_Copy36B((void *)&reg_G3X_VECMTX_RESULT_0, dst);
+ return 0;
+ }
+}
+
+ARM_FUNC void G3X_SetEdgeColorTable(void *tbl_ptr){
+ MIi_CpuCopy16(tbl_ptr, (void *)&reg_G3X_EDGE_COLOR_0, 0x10);
+}
+
+ARM_FUNC void G3X_SetFogTable(void *tbl_ptr){
+ MI_Copy32B(tbl_ptr, (void *)&reg_G3X_FOG_TABLE_0);
+}
+
+ARM_FUNC void G3X_SetClearColor(u32 col, u32 alpha, u32 depth, u32 polygon_id, u32 enable_fog){
+ u32 temp = col | (alpha << 0x10) | (polygon_id << 0x18);
+ if (enable_fog)
+ temp |= 0x8000;
+ reg_G3X_CLEAR_COLOR = temp;
+ reg_G3X_CLEAR_DEPTH = (u16)depth;
+}
+
+ARM_FUNC void G3X_InitTable(){
+ if (GXi_DmaId != -1)
+ {
+ MI_DmaFill32Async(GXi_DmaId, (void *)&reg_G3X_EDGE_COLOR_0, 0x0, 0x10, 0x0, 0x0);
+ MI_DmaFill32(GXi_DmaId, (void *)&reg_G3X_FOG_TABLE_0, 0x0, 0x60);
+ }
+ else
+ {
+ MIi_CpuClear32(0x0, (void *)&reg_G3X_EDGE_COLOR_0, 0x10);
+ MIi_CpuClear32(0x0, (void *)&reg_G3X_FOG_TABLE_0, 0x60);
+ }
+ for (int i = 0; i < 0x20; i++)
+ {
+ reg_G3_SHININESS = 0x0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetMtxStackLevelPV(u32 *level){
+ if (reg_G3X_GXSTAT & 0x4000)
+ {
+ return (u32)-1;
+ }
+ else
+ {
+ *level = (reg_G3X_GXSTAT & 0x1F00) >> 0x8;
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetMtxStackLevelPJ(u32 *level){
+ if (reg_G3X_GXSTAT & 0x4000)
+ {
+ return (u32)-1;
+ }
+ else
+ {
+ *level = (reg_G3X_GXSTAT & 0x2000) >> 0xD;
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetBoxTestResult(u32 *result){
+ if (reg_G3X_GXSTAT & 0x1)
+ {
+ return (u32)-1;
+ }
+ else
+ {
+ *result = (reg_G3X_GXSTAT & 0x2);
+ return 0;
+ }
+}
+
+ARM_FUNC void G3X_SetHOffset(u32 offset){
+ reg_G2_BG0OFS = offset;
+}
diff --git a/arm9/lib/NitroSDK/src/GX_load2d.c b/arm9/lib/NitroSDK/src/GX_load2d.c
new file mode 100644
index 00000000..6bff54be
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_load2d.c
@@ -0,0 +1,223 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern u32 GXi_DmaId;
+
+static s32 sBGExtPltt = 0;
+static u32 sBGExtPlttLCDCBlk = 0;
+static u32 sBGExtPlttLCDCOffset = 0;
+static s32 sOBJExtPltt = 0;
+static u32 sOBJExtPlttLCDCBlk = 0;
+static s32 sSubBGExtPltt = 0;
+static s32 sSubOBJExtPltt = 0;
+
+
+static inline void *_GX_OBJ_PTR(){
+ return (void *)0x6400000;
+}
+static inline void *_GXS_OBJ_PTR(){
+ return (void *)0x6600000;
+}
+
+ARM_FUNC void GX_LoadBGPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(0x5000000 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBGPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(0x5000400 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOBJPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(0x5000200 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOBJPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(0x5000600 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOAM(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(0x7000000 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOAM(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(0x7000400 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOBJ(void *src, u32 offset, u32 size){
+ u32 base = (u32)_GX_OBJ_PTR();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOBJ(void *src, u32 offset, u32 size){
+ u32 base = (u32)_GXS_OBJ_PTR();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG0Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG0ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG0Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG0ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG1Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG1ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG1Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG1ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG2Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG2ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG2Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG2ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG3Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG3ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG3Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG3ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG0Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG0CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG0Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG0CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG1Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG1CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG1Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG1CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG2Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG2CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG2Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG2CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG3Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG3CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG3Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG3CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_BeginLoadBGExtPltt(){
+ sBGExtPltt = (s32)GX_ResetBankForBGExtPltt();
+ switch (sBGExtPltt)
+ {
+ case 0: //needed to match
+ break;
+ case 0x10:
+ sBGExtPlttLCDCBlk = 0x06880000;
+ sBGExtPlttLCDCOffset = 0x0;
+ break;
+ case 0x40:
+ sBGExtPlttLCDCBlk = 0x06894000;
+ sBGExtPlttLCDCOffset = 0x4000;
+ break;
+ case 0x20:
+ case 0x60:
+ sBGExtPlttLCDCBlk = 0x06890000;
+ sBGExtPlttLCDCOffset = 0x0;
+ break;
+ }
+}
+
+ARM_FUNC void GX_LoadBGExtPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sBGExtPlttLCDCBlk + offset - sBGExtPlttLCDCOffset), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadBGExtPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForBGExtPltt(sBGExtPltt);
+ sBGExtPltt = 0x0;
+ sBGExtPlttLCDCBlk = 0x0;
+ sBGExtPlttLCDCOffset = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadOBJExtPltt(){
+ sOBJExtPltt = (s32)GX_ResetBankForOBJExtPltt();
+ switch (sOBJExtPltt)
+ {
+ case 0: //needed to match
+ break;
+ case 0x40:
+ sOBJExtPlttLCDCBlk = 0x06894000;
+ break;
+ case 0x20:
+ sOBJExtPlttLCDCBlk = 0x06890000;
+ break;
+ }
+}
+
+ARM_FUNC void GX_LoadOBJExtPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sOBJExtPlttLCDCBlk + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadOBJExtPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForOBJExtPltt(sOBJExtPltt);
+ sOBJExtPltt = 0x0;
+ sOBJExtPlttLCDCBlk = 0x0;
+}
+
+ARM_FUNC void GXS_BeginLoadBGExtPltt(){
+ sSubBGExtPltt = (s32)GX_ResetBankForSubBGExtPltt();
+}
+
+ARM_FUNC void GXS_LoadBGExtPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(0x06898000 + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GXS_EndLoadBGExtPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForSubBGExtPltt(sSubBGExtPltt);
+ sSubBGExtPltt = 0x0;
+}
+
+ARM_FUNC void GXS_BeginLoadOBJExtPltt(){
+ sSubOBJExtPltt = (s32)GX_ResetBankForSubOBJExtPltt();
+}
+
+ARM_FUNC void GXS_LoadOBJExtPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(0x068A0000 + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GXS_EndLoadOBJExtPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForSubOBJExtPltt(sSubOBJExtPltt);
+ sSubOBJExtPltt = 0x0;
+}
diff --git a/arm9/lib/NitroSDK/src/GX_load3d.c b/arm9/lib/NitroSDK/src/GX_load3d.c
new file mode 100644
index 00000000..ae15f32e
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_load3d.c
@@ -0,0 +1,150 @@
+#include "global.h"
+#include "main.h"
+#include "gx.h"
+
+extern u32 GXi_DmaId;
+
+static u32 sTexLCDCBlk1 = 0;
+static u32 sSzTexBlk1 = 0;
+static u32 sTexLCDCBlk2 = 0;
+static s32 sTex = 0;
+
+static const struct
+{
+ u16 blk1; // 12 bit shift
+ u16 blk2; // 12 bit shift
+ u16 szBlk1; // 12 bit shift
+} sTexStartAddrTable[16] = {
+ {0, 0, 0},
+ {0x06800000 >> 12, 0, 0},
+ {0x06820000 >> 12, 0, 0},
+ {0x06800000 >> 12, 0, 0},
+ {0x06840000 >> 12, 0, 0},
+ {0x06800000 >> 12, 0x06840000 >> 12, 0x00020000 >> 12},
+ {0x06820000 >> 12, 0, 0},
+ {0x06800000 >> 12, 0, 0},
+ {0x06860000 >> 12, 0, 0},
+ {0x06800000 >> 12, 0x06860000 >> 12, 0x00020000 >> 12},
+ {0x06820000 >> 12, 0x06860000 >> 12, 0x00020000 >> 12},
+ {0x06800000 >> 12, 0x06860000 >> 12, 0x00040000 >> 12},
+ {0x06840000 >> 12, 0, 0},
+ {0x06800000 >> 12, 0x06840000 >> 12, 0x00020000 >> 12},
+ {0x06820000 >> 12, 0, 0},
+ {0x06800000 >> 12, 0, 0},
+};
+
+static s32 sTexPltt = 0;
+static u32 sTexPlttLCDCBlk = 0;
+
+static const u16 sTexPlttStartAddrTable[8] = {
+ 0,
+ 0x06880000 >> 12,
+ 0x06890000 >> 12,
+ 0x06880000 >> 12,
+ 0x06894000 >> 12,
+ 0,
+ 0x06890000 >> 12,
+ 0x06880000 >> 12
+};
+
+static s32 sClrImg = 0;
+static u32 sClrImgLCDCBlk = 0;
+
+ARM_FUNC void GX_BeginLoadTex(){
+ u32 temp = GX_ResetBankForTex();
+ sTex = (s32)temp;
+ sTexLCDCBlk1 = (u32)(sTexStartAddrTable[temp].blk1 << 0xC);
+ sTexLCDCBlk2 = (u32)(sTexStartAddrTable[temp].blk2 << 0xC);
+ sSzTexBlk1 = (u32)(sTexStartAddrTable[temp].szBlk1 << 0xC);
+}
+
+ARM_FUNC void GX_LoadTex(void *src, u32 offset, u32 size){
+ void *temp;
+ if (!sTexLCDCBlk2)
+ {
+ temp = (void *)(sTexLCDCBlk1 + offset);
+ }
+ else
+ {
+ if ((offset + size) < sSzTexBlk1)
+ {
+ temp = (void *)(sTexLCDCBlk1 + offset);
+ }
+ else if (offset >= sSzTexBlk1)
+ {
+ temp = (void *)(sTexLCDCBlk2 + offset - sSzTexBlk1);
+ }
+ else
+ {
+ void *temp2 = (void *)sTexLCDCBlk2;
+ u32 temp1 = sSzTexBlk1 - offset;
+ temp = (void *)(sTexLCDCBlk1 + offset);
+ GXi_DmaCopy32(GXi_DmaId, src, temp, temp1);
+ GXi_DmaCopy32Async(GXi_DmaId, (void *)((u8 *)src + temp1), temp2, (size - temp1), NULL, NULL);
+ return;
+ }
+ }
+ GXi_DmaCopy32Async(GXi_DmaId, src, temp, size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadTex(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForTex(sTex);
+ sSzTexBlk1 = 0x0;
+ sTexLCDCBlk2 = 0x0;
+ sTexLCDCBlk1 = 0x0;
+ sTex = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadTexPltt(){
+ s32 temp = (s32)GX_ResetBankForTexPltt();
+ sTexPltt = temp;
+ sTexPlttLCDCBlk = (u32)(sTexPlttStartAddrTable[temp >> 4] << 0xC);
+}
+
+ARM_FUNC void GX_LoadTexPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sTexPlttLCDCBlk + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadTexPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForTexPltt(sTexPltt);
+ sTexPltt = 0x0;
+ sTexPlttLCDCBlk = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadClearImage(){
+ u32 temp = GX_ResetBankForClearImage();
+ sClrImg = (s32)temp;
+ switch (temp)
+ {
+ case 2:
+ case 3:
+ sClrImgLCDCBlk = 0x6800000;
+ return;
+ case 8:
+ case 12:
+ sClrImgLCDCBlk = 0x6840000;
+ return;
+ case 1:
+ sClrImgLCDCBlk = 0x67E0000;
+ return;
+ case 4:
+ sClrImgLCDCBlk = 0x6820000;
+ }
+}
+
+ARM_FUNC void GX_LoadClearImageColor(void *src, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sClrImgLCDCBlk), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_LoadClearImageDepth(void *src, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sClrImgLCDCBlk + 0x20000), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadClearImage(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForClearImage(sClrImg);
+ sClrImg = 0x0;
+ sClrImgLCDCBlk = 0x0;
+}
diff --git a/arm9/lib/NitroSDK/src/GX_state.c b/arm9/lib/NitroSDK/src/GX_state.c
new file mode 100644
index 00000000..003e42b5
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_state.c
@@ -0,0 +1,25 @@
+#include "global.h"
+#include "gx.h"
+
+struct GX_State gGXState;
+
+ARM_FUNC void GX_InitGXState(){
+ gGXState.lcdc = 0x0;
+ gGXState.bg = 0x0;
+ gGXState.obj = 0x0;
+ gGXState.arm7 = 0x0;
+ gGXState.tex = 0x0;
+ gGXState.texPltt = 0x0;
+ gGXState.clrImg = 0x0;
+ gGXState.bgExtPltt = 0x0;
+ gGXState.objExtPltt = 0x0;
+ gGXState.sub_bg = 0x0;
+ gGXState.sub_obj = 0x0;
+ gGXState.sub_bgExtPltt = 0x0;
+ gGXState.sub_objExtPltt = 0x0;
+ reg_GX_VRAMCNT = 0x0;
+ reg_GX_VRAMCNT_E = 0x0;
+ reg_GX_VRAMCNT_F = 0x0;
+ reg_GX_VRAMCNT_G = 0x0;
+ reg_GX_VRAM_HI_CNT = 0x0;
+}
diff --git a/arm9/lib/NitroSDK/src/GX_vramcnt.c b/arm9/lib/NitroSDK/src/GX_vramcnt.c
new file mode 100644
index 00000000..abfcd77e
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/GX_vramcnt.c
@@ -0,0 +1,578 @@
+#include "global.h"
+#include "gx.h"
+
+extern u16 GXi_VRamLockId;
+extern struct GX_State gGXState;
+
+ARM_FUNC void GX_VRAMCNT_SetLCDC_(u32 mask){
+ if (mask & (0x1 << 0))
+ reg_GX_VRAMCNT_A = 0x80;
+ if (mask & (0x1 << 1))
+ reg_GX_VRAMCNT_B = 0x80;
+ if (mask & (0x1 << 2))
+ reg_GX_VRAMCNT_C = 0x80;
+ if (mask & (0x1 << 3))
+ reg_GX_VRAMCNT_D = 0x80;
+ if (mask & (0x1 << 4))
+ reg_GX_VRAMCNT_E = 0x80;
+ if (mask & (0x1 << 5))
+ reg_GX_VRAMCNT_F = 0x80;
+ if (mask & (0x1 << 6))
+ reg_GX_VRAMCNT_G = 0x80;
+ if (mask & (0x1 << 7))
+ reg_GX_VRAMCNT_H = 0x80;
+ if (mask & (0x1 << 8))
+ reg_GX_VRAMCNT_I = 0x80;
+}
+
+ARM_FUNC void GX_SetBankForBG(s32 bg){
+ gGXState.lcdc = (u16)(~bg & (gGXState.lcdc | gGXState.bg));
+ gGXState.bg = (u16)bg;
+ switch (bg)
+ {
+ case 8:
+ reg_GX_VRAMCNT_D = 0x81;
+ break;
+ case 12:
+ reg_GX_VRAMCNT_D = 0x89;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x81;
+ break;
+ case 14:
+ reg_GX_VRAMCNT_D = 0x91;
+ case 6:
+ reg_GX_VRAMCNT_C = 0x89;
+ case 2:
+ reg_GX_VRAMCNT_B = 0x81;
+ break;
+ case 15:
+ reg_GX_VRAMCNT_D = 0x99;
+ case 7:
+ reg_GX_VRAMCNT_C = 0x91;
+ case 3:
+ reg_GX_VRAMCNT_B = 0x89;
+ case 1:
+ reg_GX_VRAMCNT_A = 0x81;
+ break;
+ case 11:
+ reg_GX_VRAMCNT_A = 0x81;
+ reg_GX_VRAMCNT_B = 0x89;
+ reg_GX_VRAMCNT_D = 0x91;
+ break;
+ case 13:
+ reg_GX_VRAMCNT_D = 0x91;
+ case 5:
+ reg_GX_VRAMCNT_A = 0x81;
+ reg_GX_VRAMCNT_C = 0x89;
+ break;
+ case 9:
+ reg_GX_VRAMCNT_A = 0x81;
+ reg_GX_VRAMCNT_D = 0x89;
+ break;
+ case 10:
+ reg_GX_VRAMCNT_B = 0x81;
+ reg_GX_VRAMCNT_D = 0x89;
+ break;
+ case 112:
+ reg_GX_VRAMCNT_G = 0x99;
+ case 48:
+ reg_GX_VRAMCNT_F = 0x91;
+ case 16:
+ reg_GX_VRAMCNT_E = 0x81;
+ break;
+ case 80:
+ reg_GX_VRAMCNT_G = 0x91;
+ reg_GX_VRAMCNT_E = 0x81;
+ break;
+ case 96:
+ reg_GX_VRAMCNT_G = 0x89;
+ case 32:
+ reg_GX_VRAMCNT_F = 0x81;
+ break;
+ case 64:
+ reg_GX_VRAMCNT_G = 0x81;
+ break;
+ default:
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForOBJ(s32 obj){
+ gGXState.lcdc = (u16)(~obj & (gGXState.lcdc | gGXState.obj));
+ gGXState.obj = (u16)obj;
+ switch (obj)
+ {
+ case 3:
+ reg_GX_VRAMCNT_B = 0x8A;
+ case 1:
+ reg_GX_VRAMCNT_A = 0x82;
+ case 0: //needed to match
+ break;
+ case 2:
+ reg_GX_VRAMCNT_B = 0x82;
+ break;
+ case 112:
+ reg_GX_VRAMCNT_G = 0x9A;
+ case 48:
+ reg_GX_VRAMCNT_F = 0x92;
+ case 16:
+ reg_GX_VRAMCNT_E = 0x82;
+ break;
+ case 80:
+ reg_GX_VRAMCNT_G = 0x92;
+ reg_GX_VRAMCNT_E = 0x82;
+ break;
+ case 96:
+ reg_GX_VRAMCNT_G = 0x8A;
+ case 32:
+ reg_GX_VRAMCNT_F = 0x82;
+ break;
+ case 64:
+ reg_GX_VRAMCNT_G = 0x82;
+ break;
+ default:
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForBGExtPltt(s32 bgextpltt){
+ gGXState.lcdc = (u16)(~bgextpltt & (gGXState.lcdc | gGXState.bgExtPltt));
+ gGXState.bgExtPltt = (u16)bgextpltt;
+ switch (bgextpltt)
+ {
+ case 0x10:
+ reg_GX_DISPCNT |= 0x40000000;
+ reg_GX_VRAMCNT_E = 0x84;
+ break;
+ case 0x40:
+ reg_GX_DISPCNT |= 0x40000000;
+ reg_GX_VRAMCNT_G = 0x8C;
+ break;
+ case 0x60:
+ reg_GX_VRAMCNT_G = 0x8C;
+ case 0x20:
+ reg_GX_VRAMCNT_F = 0x84;
+ reg_GX_DISPCNT |= 0x40000000;
+ break;
+ case 0:
+ reg_GX_DISPCNT &= ~0x40000000;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForOBJExtPltt(s32 objextpltt){
+ gGXState.lcdc = (u16)(~objextpltt & (gGXState.lcdc | gGXState.objExtPltt));
+ gGXState.objExtPltt = (u16)objextpltt;
+ switch (objextpltt)
+ {
+ case 32:
+ reg_GX_DISPCNT |= 0x80000000;
+ reg_GX_VRAMCNT_F = 0x85;
+ break;
+ case 64:
+ reg_GX_DISPCNT |= 0x80000000;
+ reg_GX_VRAMCNT_G = 0x85;
+ break;
+ case 0:
+ reg_GX_DISPCNT &= ~0x80000000;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForTex(s32 tex){
+ gGXState.lcdc = (u16)(~tex & (gGXState.lcdc | gGXState.tex));
+ gGXState.tex = (u16)tex;
+ if (tex == 0)
+ {
+ reg_G3X_DISP3DCNT &= 0x0000CFFE;
+ }
+ else
+ {
+ reg_G3X_DISP3DCNT = (u16)((reg_G3X_DISP3DCNT & ~0x3000) | 0x1);
+ switch (tex)
+ {
+ case 5:
+ reg_GX_VRAMCNT_A = 0x83;
+ reg_GX_VRAMCNT_C = 0x8B;
+ break;
+ case 9:
+ reg_GX_VRAMCNT_A = 0x83;
+ reg_GX_VRAMCNT_D = 0x8B;
+ break;
+ case 10:
+ reg_GX_VRAMCNT_B = 0x83;
+ reg_GX_VRAMCNT_D = 0x8B;
+ break;
+ case 11:
+ reg_GX_VRAMCNT_A = 0x83;
+ reg_GX_VRAMCNT_B = 0x8B;
+ reg_GX_VRAMCNT_D = 0x93;
+ break;
+ case 13:
+ reg_GX_VRAMCNT_A = 0x83;
+ reg_GX_VRAMCNT_C = 0x8B;
+ reg_GX_VRAMCNT_D = 0x93;
+ break;
+ case 8:
+ reg_GX_VRAMCNT_D = 0x83;
+ break;
+ case 12:
+ reg_GX_VRAMCNT_D = 0x8B;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x83;
+ break;
+ case 14:
+ reg_GX_VRAMCNT_D = 0x93;
+ case 6:
+ reg_GX_VRAMCNT_C = 0x8B;
+ case 2:
+ reg_GX_VRAMCNT_B = 0x83;
+ break;
+ case 15:
+ reg_GX_VRAMCNT_D = 0x9B;
+ case 7:
+ reg_GX_VRAMCNT_C = 0x93;
+ case 3:
+ reg_GX_VRAMCNT_B = 0x8B;
+ case 1:
+ reg_GX_VRAMCNT_A = 0x83;
+ break;
+ }
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForTexPltt(s32 texpltt){
+ gGXState.lcdc = (u16)(~texpltt & (gGXState.lcdc | gGXState.texPltt));
+ gGXState.texPltt = (u16)texpltt;
+ switch (texpltt)
+ {
+ case 0: //needed to match
+ break;
+ case 96:
+ reg_GX_VRAMCNT_G = 0x8B;
+ case 32:
+ reg_GX_VRAMCNT_F = 0x83;
+ break;
+ case 112:
+ reg_GX_VRAMCNT_G = 0x9B;
+ case 48:
+ reg_GX_VRAMCNT_F = 0x93;
+ case 16:
+ reg_GX_VRAMCNT_E = 0x83;
+ break;
+ case 64:
+ reg_GX_VRAMCNT_G = 0x83;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForClearImage(s32 clearimage){
+ gGXState.lcdc = (u16)(~clearimage & (gGXState.lcdc | gGXState.clrImg));
+ gGXState.clrImg = (u16)clearimage;
+ switch (clearimage)
+ {
+ case 3:
+ reg_GX_VRAMCNT_A = 0x93;
+ case 2:
+ reg_GX_VRAMCNT_B = 0x9B;
+ reg_G3X_DISP3DCNT |= 0x4000;
+ break;
+ case 12:
+ reg_GX_VRAMCNT_C = 0x93;
+ case 8:
+ reg_GX_VRAMCNT_D = 0x9B;
+ reg_G3X_DISP3DCNT |= 0x4000;
+ break;
+ case 0:
+ reg_G3X_DISP3DCNT &= ~0x4000;
+ break;
+ case 1:
+ reg_GX_VRAMCNT_A = 0x9B;
+ reg_G3X_DISP3DCNT |= 0x4000;
+ break;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x9B;
+ reg_G3X_DISP3DCNT |= 0x4000;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForARM7(s32 arm7){
+ gGXState.lcdc = (u16)(~arm7 & (gGXState.lcdc | gGXState.arm7));
+ gGXState.arm7 = (u16)arm7;
+ switch (arm7)
+ {
+ case 0: //needed to match
+ break;
+ case 12:
+ reg_GX_VRAMCNT_D = 0x8A;
+ reg_GX_VRAMCNT_C = 0x82;
+ break;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x82;
+ break;
+ case 8:
+ reg_GX_VRAMCNT_D = 0x82;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForLCDC(s32 lcdc){
+ gGXState.lcdc |= lcdc;
+ GX_VRAMCNT_SetLCDC_((u32)lcdc);
+}
+
+ARM_FUNC void GX_SetBankForSubBG(s32 subbg){
+ gGXState.lcdc = (u16)(~subbg & (gGXState.lcdc | gGXState.sub_bg));
+ gGXState.sub_bg = (u16)subbg;
+ switch (subbg)
+ {
+ case 0: //needed to match
+ break;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x84;
+ break;
+ case 384:
+ reg_GX_VRAMCNT_I = 0x81;
+ case 128:
+ reg_GX_VRAMCNT_H = 0x81;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+
+ARM_FUNC void GX_SetBankForSubOBJ(s32 subobj){
+ gGXState.lcdc = (u16)(~subobj & (gGXState.lcdc | gGXState.sub_obj));
+ gGXState.sub_obj = (u16)subobj;
+ switch (subobj)
+ {
+ case 8:
+ reg_GX_VRAMCNT_D = 0x84;
+ break;
+ case 256:
+ reg_GX_VRAMCNT_I = 0x82;
+ break;
+ case 0: //needed to match
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForSubBGExtPltt(s32 subbgextpltt){
+ gGXState.lcdc = (u16)(~subbgextpltt & (gGXState.lcdc | gGXState.sub_bgExtPltt));
+ gGXState.sub_bgExtPltt = (u16)subbgextpltt;
+ switch (subbgextpltt)
+ {
+ case 128:
+ reg_GXS_DB_DISPCNT |= 0x40000000;
+ reg_GX_VRAMCNT_H = 0x82;
+ break;
+ case 0:
+ reg_GXS_DB_DISPCNT &= ~0x40000000;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForSubOBJExtPltt(s32 subobjextpltt){
+ gGXState.lcdc = (u16)(~subobjextpltt & (gGXState.lcdc | gGXState.sub_objExtPltt));
+ gGXState.sub_objExtPltt = (u16)subobjextpltt;
+ switch (subobjextpltt)
+ {
+ case 256:
+ reg_GXS_DB_DISPCNT |= 0x80000000;
+ reg_GX_VRAMCNT_I = 0x83;
+ break;
+ case 0:
+ reg_GXS_DB_DISPCNT &= ~0x80000000;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC u32 resetBankForX_(u16 *ptr){
+ u16 temp = *ptr;
+ *ptr = 0;
+ gGXState.lcdc |= temp;
+ GX_VRAMCNT_SetLCDC_(temp);
+ return temp;
+}
+
+ARM_FUNC u32 GX_ResetBankForBG(){
+ return resetBankForX_(&gGXState.bg);
+}
+
+ARM_FUNC u32 GX_ResetBankForOBJ(){
+ return resetBankForX_(&gGXState.obj);
+}
+
+ARM_FUNC u32 GX_ResetBankForBGExtPltt(){
+ reg_GX_DISPCNT &= ~0x40000000;
+ return resetBankForX_(&gGXState.bgExtPltt);
+}
+
+ARM_FUNC u32 GX_ResetBankForOBJExtPltt(){
+ reg_GX_DISPCNT &= ~0x80000000;
+ return resetBankForX_(&gGXState.objExtPltt);
+}
+
+ARM_FUNC u32 GX_ResetBankForTex(){
+ return resetBankForX_(&gGXState.tex);
+}
+
+ARM_FUNC u32 GX_ResetBankForTexPltt(){
+ return resetBankForX_(&gGXState.texPltt);
+}
+
+ARM_FUNC u32 GX_ResetBankForClearImage(){
+ return resetBankForX_(&gGXState.clrImg);
+}
+
+ARM_FUNC u32 GX_ResetBankForSubBG(){
+ return resetBankForX_(&gGXState.sub_bg);
+}
+
+ARM_FUNC u32 GX_ResetBankForSubOBJ(){
+ return resetBankForX_(&gGXState.sub_obj);
+}
+
+ARM_FUNC u32 GX_ResetBankForSubBGExtPltt(){
+ reg_GXS_DB_DISPCNT &= ~REG_GXS_DB_DISPCNT_BG_MASK;
+ return resetBankForX_(&gGXState.sub_bgExtPltt);
+}
+
+ARM_FUNC u32 GX_ResetBankForSubOBJExtPltt(){
+ reg_GXS_DB_DISPCNT &= ~REG_GXS_DB_DISPCNT_O_MASK;
+ return resetBankForX_(&gGXState.sub_objExtPltt);
+}
+
+ARM_FUNC u32 disableBankForX_(u16 *ptr){
+ u32 temp = *ptr;
+ *ptr = 0;
+ if (temp & (0x1 << 0))
+ reg_GX_VRAMCNT_A = 0x0;
+ if (temp & (0x1 << 1))
+ reg_GX_VRAMCNT_B = 0x0;
+ if (temp & (0x1 << 2))
+ reg_GX_VRAMCNT_C = 0x0;
+ if (temp & (0x1 << 3))
+ reg_GX_VRAMCNT_D = 0x0;
+ if (temp & (0x1 << 4))
+ reg_GX_VRAMCNT_E = 0x0;
+ if (temp & (0x1 << 5))
+ reg_GX_VRAMCNT_F = 0x0;
+ if (temp & (0x1 << 6))
+ reg_GX_VRAMCNT_G = 0x0;
+ if (temp & (0x1 << 7))
+ reg_GX_VRAMCNT_H = 0x0;
+ if (temp & (0x1 << 8))
+ reg_GX_VRAMCNT_I = 0x0;
+ OSi_UnlockVram((u16)temp, GXi_VRamLockId);
+ return temp;
+}
+
+ARM_FUNC u32 GX_DisableBankForBG(){
+ return disableBankForX_(&gGXState.bg);
+}
+
+ARM_FUNC u32 GX_DisableBankForOBJ(){
+ return disableBankForX_(&gGXState.obj);
+}
+
+ARM_FUNC u32 GX_DisableBankForBGExtPltt(){
+ reg_GX_DISPCNT &= ~REG_GX_DISPCNT_BG_MASK;
+ return disableBankForX_(&gGXState.bgExtPltt);
+}
+
+ARM_FUNC u32 GX_DisableBankForOBJExtPltt(){
+ reg_GX_DISPCNT &= ~REG_GX_DISPCNT_O_MASK;
+ return disableBankForX_(&gGXState.objExtPltt);
+}
+
+ARM_FUNC u32 GX_DisableBankForTex(){
+ return disableBankForX_(&gGXState.tex);
+}
+
+ARM_FUNC u32 GX_DisableBankForTexPltt(){
+ return disableBankForX_(&gGXState.texPltt);
+}
+
+ARM_FUNC u32 GX_DisableBankForClearImage(){
+ return disableBankForX_(&gGXState.clrImg);
+}
+
+ARM_FUNC u32 GX_DisableBankForARM7(){
+ return disableBankForX_(&gGXState.arm7);
+}
+
+ARM_FUNC u32 GX_DisableBankForLCDC(){
+ return disableBankForX_(&gGXState.lcdc);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubBG(){
+ return disableBankForX_(&gGXState.sub_bg);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubOBJ(){
+ return disableBankForX_(&gGXState.sub_obj);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubBGExtPltt(){
+ reg_GXS_DB_DISPCNT &= ~REG_GX_DISPCNT_BG_MASK;
+ return disableBankForX_(&gGXState.sub_bgExtPltt);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubOBJExtPltt(){
+ reg_GXS_DB_DISPCNT &= ~REG_GX_DISPCNT_O_MASK;
+ return disableBankForX_(&gGXState.sub_objExtPltt);
+}
+
+ARM_FUNC u32 GX_GetBankForBG(){
+ return gGXState.bg;
+}
+
+ARM_FUNC u32 GX_GetBankForOBJ(){
+ return gGXState.obj;
+}
+
+ARM_FUNC u32 GX_GetBankForBGExtPltt(){
+ return gGXState.bgExtPltt;
+}
+
+ARM_FUNC u32 GX_GetBankForOBJExtPltt(){
+ return gGXState.objExtPltt;
+}
+
+ARM_FUNC u32 GX_GetBankForTex(){
+ return gGXState.tex;
+}
+
+ARM_FUNC u32 GX_GetBankForTexPltt(){
+ return gGXState.texPltt;
+}
+
+ARM_FUNC u32 GX_GetBankForLCDC(){
+ return gGXState.lcdc;
+}
+
+ARM_FUNC u32 GX_GetBankForSubBG(){
+ return gGXState.sub_bg;
+}
+
+ARM_FUNC u32 GX_GetBankForSubOBJ(){
+ return gGXState.sub_obj;
+}
+
+ARM_FUNC u32 GX_GetBankForSubBGExtPltt(){
+ return gGXState.sub_bgExtPltt;
+}
+
+ARM_FUNC u32 GX_GetBankForSubOBJExtPltt(){
+ return gGXState.sub_objExtPltt;
+}
diff --git a/arm9/lib/NitroSDK/src/MATH_crc.c b/arm9/lib/NitroSDK/src/MATH_crc.c
new file mode 100644
index 00000000..cf8cc64c
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MATH_crc.c
@@ -0,0 +1,150 @@
+#include "global.h"
+#include "MATH_crc.h"
+
+ARM_FUNC void MATHi_CRC8InitTable(struct MATHCRC8Table *table, u8 poly) {
+ u32 r, i, j;
+ u8 *t = table->table;
+
+ for (i = 0; i < 256; i++) {
+ r = i;
+ for (j = 0; j < 8; j++) {
+ if (r & 0x80) {
+ r = (r << 1) ^ poly;
+ }
+ else {
+ r <<= 1;
+ }
+ }
+ t[i] = (u8)r;
+ }
+}
+
+ARM_FUNC void MATHi_CRC8Update(const struct MATHCRC8Table *table, MATHCRC8Context *context, const void *input, u32 length) {
+ u32 r, i;
+ const u8* t = table->table;
+ u8* data = (u8*)input;
+
+ r = *context;
+ for (i = 0; i < length; i++) {
+ r = t[(r ^ *data) & 0xff];
+ data++;
+ }
+ *context = (MATHCRC8Context)r;
+}
+
+ARM_FUNC void MATHi_CRC16InitTable(struct MATHCRC16Table *table, u16 poly) {
+ u32 r, i, j;
+ u16 *t = table->table;
+
+ for (i = 0; i < 256; i++) {
+ r = i << 8;
+ for (j = 0; j < 8; j++) {
+ if (r & 0x8000) {
+ r = (r << 1) ^ poly;
+ }
+ else {
+ r <<= 1;
+ }
+ }
+ t[i] = (u16)r;
+ }
+}
+
+ARM_FUNC void MATHi_CRC16InitTableRev(struct MATHCRC16Table *table, u16 poly) {
+ u32 r, i, j;
+ u16 *t = table->table;
+
+ for (i = 0; i < 256; i++) {
+ r = i;
+ for (j = 0; j < 8; j++) {
+ if (r & 1) {
+ r = (r >> 1) ^ poly;
+ }
+ else {
+ r >>= 1;
+ }
+ }
+ t[i] = (u16)r;
+ }
+}
+
+ARM_FUNC void MATHi_CRC16Update(const struct MATHCRC16Table *table, MATHCRC16Context *context, const void *input, u32 length) {
+ u32 r, i;
+ const u16* t = table->table;
+ u8* data = (u8*)input;
+
+ r = *context;
+ for (i = 0; i < length; i++) {
+ r = (r << 8) ^ t[((r >> 8) ^ *data) & 0xff];
+ data++;
+ }
+ *context = (MATHCRC16Context)r;
+}
+
+ARM_FUNC void MATHi_CRC16UpdateRev(const struct MATHCRC16Table *table, MATHCRC16Context *context, const void *input, u32 length) {
+ u32 r, i;
+ const u16* t = table->table;
+ u8* data = (u8*)input;
+
+ r = *context;
+ for (i = 0; i < length; i++) {
+ r = (r >> 8) ^ t[(r ^ *data) & 0xff];
+ data++;
+ }
+ *context = (MATHCRC16Context)r;
+}
+
+ARM_FUNC void MATHi_CRC32InitTableRev(struct MATHCRC32Table *table, u32 poly) {
+ u32 r, i, j;
+ u32 *t = table->table;
+
+ for (i = 0; i < 256; i++) {
+ r = i;
+ for (j = 0; j < 8; j++) {
+ if (r & 1) {
+ r = (r >> 1) ^ poly;
+ }
+ else {
+ r >>= 1;
+ }
+ }
+ t[i] = r;
+ }
+}
+
+ARM_FUNC void MATHi_CRC32UpdateRev(const struct MATHCRC32Table *table, MATHCRC32Context *context, const void *input, u32 length) {
+ u32 r, i;
+ const u32* t = table->table;
+ u8* data = (u8*)input;
+
+ r = *context;
+ for (i = 0; i < length; i++) {
+ r = (r >> 8) ^ t[(r ^ *data) & 0xff];
+ data++;
+ }
+ *context = r;
+}
+
+ARM_FUNC u8 MATH_CalcCRC8(const struct MATHCRC8Table *table, const void *data, u32 dataLength) {
+ MATHCRC8Context ctx = 0;
+ MATHi_CRC8Update(table, &ctx, data, dataLength);
+ return ctx;
+}
+
+ARM_FUNC u16 MATH_CalcCRC16(const struct MATHCRC16Table *table, const void *data, u32 dataLength) {
+ MATHCRC16Context ctx = 0;
+ MATHi_CRC16UpdateRev(table, &ctx, data, dataLength);
+ return ctx;
+}
+
+ARM_FUNC u16 MATH_CalcCRC16CCITT(const struct MATHCRC16Table *table, const void *data, u32 dataLength) {
+ MATHCRC16Context ctx = 0xffff;
+ MATHi_CRC16Update(table, &ctx, data, dataLength);
+ return ctx;
+}
+
+ARM_FUNC u32 MATH_CalcCRC32(const struct MATHCRC32Table *table, const void *data, u32 dataLength) {
+ MATHCRC32Context ctx = (MATHCRC32Context)(~0);
+ MATHi_CRC32UpdateRev(table, &ctx, data, dataLength);
+ return ~ctx;
+}
diff --git a/arm9/lib/NitroSDK/src/MATH_dgt.c b/arm9/lib/NitroSDK/src/MATH_dgt.c
new file mode 100644
index 00000000..6bb90d99
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MATH_dgt.c
@@ -0,0 +1,16 @@
+#include "global.h"
+#include "MATH_dgt.h"
+
+ARM_FUNC void MATH_CalcMD5(void *digest, const void *data, u32 dataLength) {
+ MATHMD5Context context;
+ MATH_MD5Init(&context);
+ MATH_MD5Update(&context, data, dataLength);
+ MATH_MD5GetHash(&context, digest);
+}
+
+ARM_FUNC void MATH_CalcSHA1(void *digest, const void *data, u32 dataLength) {
+ MATHSHA1Context context;
+ MATH_SHA1Init(&context);
+ MATH_SHA1Update(&context, data, dataLength);
+ MATH_SHA1GetHash(&context, digest);
+}
diff --git a/arm9/lib/NitroSDK/src/MATH_pop.c b/arm9/lib/NitroSDK/src/MATH_pop.c
new file mode 100644
index 00000000..18582494
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MATH_pop.c
@@ -0,0 +1,12 @@
+#include "global.h"
+#include "MATH_pop.h"
+
+ARM_FUNC u8 MATH_CountPopulation(u32 x) {
+ x -= (x >> 1) & 0x55555555;
+ x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+ x += x >> 4;
+ x &= 0x0f0f0f0f;
+ x += x >> 8;
+ x += x >> 16;
+ return (u8)x;
+}
diff --git a/arm9/lib/NitroSDK/src/MI_dma.c b/arm9/lib/NitroSDK/src/MI_dma.c
new file mode 100644
index 00000000..f322f87f
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_dma.c
@@ -0,0 +1,307 @@
+#include "MI_dma.h"
+#include "function_target.h"
+#include "OS_interrupt.h"
+#include "OS_terminate_proc.h"
+#include "sections.h"
+
+#pragma section ITCM begin
+ARM_FUNC void MIi_DmaSetParams(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
+{
+ OSIntrMode lastIntrMode = OS_DisableInterrupts();
+ vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
+ *p = (vu32)src;
+ *(p + 1) = (vu32)dest;
+ *(p + 2) = (vu32)ctrl;
+ (void)OS_RestoreInterrupts(lastIntrMode);
+}
+
+ARM_FUNC void MIi_DmaSetParams_wait(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+ vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
+ *p = (vu32)src;
+ *(p + 1) = (vu32)dest;
+ *(p + 2) = (vu32)ctrl;
+
+ //delay cycles
+ {
+ u32 delay = reg_MI_DMA0SAD;
+ }
+ {
+ u32 delay = reg_MI_DMA0SAD;
+ }
+
+ if (!dmaNo)
+ {
+ *p = (vu32)0;
+ *(p + 1) = (vu32)0;
+ *(p + 2) = (vu32)0x81400001;
+ }
+
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC void MIi_DmaSetParams_noInt(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
+{
+ vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
+ *p = (vu32)src;
+ *(p + 1) = (vu32)dest;
+ *(p + 2) = (vu32)ctrl;
+}
+
+ARM_FUNC void MIi_DmaSetParams_wait_noInt(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
+{
+ vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
+ *p = (vu32)src;
+ *(p + 1) = (vu32)dest;
+ *(p + 2) = (vu32)ctrl;
+
+ //delay cycles
+ {
+ u32 delay = reg_MI_DMA0SAD;
+ }
+ {
+ u32 delay = reg_MI_DMA0SAD;
+ }
+
+ if (!dmaNo)
+ {
+ *p = (vu32)0;
+ *(p + 1) = (vu32)0;
+ *(p + 2) = (vu32)0x81400001;
+ }
+
+ //delay cycles
+ {
+ u32 delay = reg_MI_DMA0SAD;
+ }
+ {
+ u32 delay = reg_MI_DMA0SAD;
+ }
+}
+#pragma section ITCM end
+
+ARM_FUNC void MI_DmaFill32(u32 dmaNo, void *dest, u32 data, u32 size)
+{
+ vu32 *dmaCntp;
+ if (!size)
+ {
+ return;
+ }
+
+ do
+ {
+ dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+
+ MIi_DmaSetParams_wait_src32(dmaNo, data, (u32)dest, MI_CNT_CLEAR32(size));
+
+ do
+ {
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+}
+
+ARM_FUNC void MI_DmaCopy32(u32 dmaNo, const void *src, void *dest, u32 size)
+{
+ vu32 *dmaCntp;
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, DMA_SRC_INC);
+
+ if (!size)
+ {
+ return;
+ }
+
+ do
+ {
+ dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+
+ MIi_DmaSetParams_wait(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32(size));
+
+ do
+ {
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+}
+
+ARM_FUNC void MI_DmaCopy16(u32 dmaNo, const void *src, void *dest, u32 size)
+{
+ vu32 *dmaCntp;
+
+ if (!size)
+ {
+ return;
+ }
+
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, DMA_SRC_INC);
+
+ do
+ {
+ dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+
+ MIi_DmaSetParams_wait(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY16(size));
+
+ do
+ {
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+}
+
+ARM_FUNC void MI_DmaFill32Async(u32 dmaNo, void *dest, u32 data, u32 size, MIDmaCallback callback, void *arg)
+{
+ if (!size)
+ {
+ MIi_CallCallback(callback, arg);
+ }
+ else
+ {
+ MI_WaitDma(dmaNo);
+
+ if (callback)
+ {
+ OSi_EnterDmaCallback(dmaNo, callback, arg);
+ MIi_DmaSetParams_src32(dmaNo, data, (u32)dest, MI_CNT_CLEAR32_IF(size));
+ }
+ else
+ {
+ MIi_DmaSetParams_src32(dmaNo, data, (u32)dest, MI_CNT_CLEAR32(size));
+ }
+ }
+}
+
+ARM_FUNC void MI_DmaCopy32Async(u32 dmaNo, const void *src, void *dest, u32 size, MIDmaCallback callback, void *arg)
+{
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, DMA_SRC_INC);
+
+ if (!size)
+ {
+ MIi_CallCallback(callback, arg);
+ }
+ else
+ {
+ MI_WaitDma(dmaNo);
+
+ if (callback)
+ {
+ OSi_EnterDmaCallback(dmaNo, callback, arg);
+ MIi_DmaSetParams(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32_IF(size));
+ }
+ else
+ {
+ MIi_DmaSetParams(dmaNo, (u32)src, (u32)dest, MI_CNT_COPY32(size));
+ }
+ }
+}
+
+ARM_FUNC void MI_WaitDma(u32 dmaNo)
+{
+ OSIntrMode lastIntrMode = OS_DisableInterrupts();
+ vu32 *dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
+
+ while (*dmaCntp & 0x80000000) {}
+
+ if (!dmaNo)
+ {
+ vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
+ *p = (vu32)0;
+ *(p + 1) = (vu32)0;
+ *(p + 2) = (vu32)0x81400001;
+ }
+
+ (void)OS_RestoreInterrupts(lastIntrMode);
+}
+
+ARM_FUNC void MI_StopDma(u32 dmaNo)
+{
+ OSIntrMode lastIntrMode = OS_DisableInterrupts();
+ vu16 *dmaCntp = &((vu16 *)REG_ADDR_DMA0SAD)[dmaNo * 6 + 5];
+
+ *dmaCntp &= ~0x3a00;
+ *dmaCntp &= ~0x8000;
+
+ //delay cycles
+ {
+ s32 delay = dmaCntp[0];
+ }
+ {
+ s32 delay = dmaCntp[0];
+ }
+
+ if (!dmaNo)
+ {
+ vu32 *p = (vu32 *)((u32)REG_ADDR_DMA0SAD + dmaNo * 12);
+ *p = (vu32)0;
+ *(p + 1) = (vu32)0;
+ *(p + 2) = (vu32)0x81400001;
+ }
+
+ (void)OS_RestoreInterrupts(lastIntrMode);
+}
+
+ARM_FUNC void MIi_CheckAnotherAutoDMA(u32 dmaNo, u32 dmaType)
+{
+ u32 dmaCnt;
+ u32 timing;
+ for (int i = 0; i < 3; i++)
+ {
+ if (i == dmaNo) continue;
+
+ dmaCnt = *(REGType32v *)(REG_ADDR_DMA0CNT + i * 12);
+
+ if (!(dmaCnt & 0x80000000)) continue;
+
+ timing = dmaCnt & 0x38000000;
+
+ if (timing == dmaType
+ || (timing == 0x8000000 && dmaType == MI_DMA_TIMING_H_BLANK)
+ || (timing == MI_DMA_TIMING_H_BLANK && dmaType == 0x8000000))
+ {
+ continue;
+ }
+
+ if (timing == 0x18000000
+ || timing == 0x20000000
+ || timing == 0x28000000
+ || timing == 0x30000000
+ || timing == 0x38000000
+ || timing == 0x8000000
+ || timing == 0x10000000)
+ {
+ OS_Terminate();
+ }
+ }
+}
+
+ARM_FUNC void MIi_CheckDma0SourceAddress(u32 dmaNo, u32 src, u32 size, u32 dir)
+{
+ if (!dmaNo)
+ {
+ u32 addStart = src & 0xff000000;
+ u32 addEnd;
+
+ switch (dir)
+ {
+ case 0: //dma_src_inc
+ addEnd = src + size;
+ break;
+ case 0x800000: //dma_src_dec
+ addEnd = src - size;
+ break;
+ default:
+ addEnd = src;
+ break;
+ }
+ addEnd &= 0xff000000;
+
+ if (addStart == 0x04000000 || addStart >= 0x08000000 ||
+ addEnd == 0x04000000 || addEnd >= 0x08000000)
+ {
+ OS_Terminate();
+ }
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/MI_dma_card.c b/arm9/lib/NitroSDK/src/MI_dma_card.c
new file mode 100644
index 00000000..c3b8b897
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_dma_card.c
@@ -0,0 +1,24 @@
+#include "MI_dma_card.h"
+#include "MI_dma.h"
+#include "function_target.h"
+
+ARM_FUNC void MIi_CardDmaCopy32(u32 dmaNo, const void *src, void *dest, u32 size)
+{
+ MIi_CheckAnotherAutoDMA(dmaNo, MIi_DMA_TIMING_ANY);
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_FIX);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ vu32 *dmaCntp;
+
+ do
+ {
+ dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+
+ MIi_DmaSetParams(dmaNo, (u32)src, (u32)dest, (u32)(0xaf000001));
+}
diff --git a/arm9/lib/NitroSDK/src/MI_dma_gxcommand.c b/arm9/lib/NitroSDK/src/MI_dma_gxcommand.c
new file mode 100644
index 00000000..26231999
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_dma_gxcommand.c
@@ -0,0 +1,155 @@
+#include "MI_dma_gxcommand.h"
+#include "function_target.h"
+#include "OS_interrupt.h"
+#include "OS_reset.h"
+#include "sections.h"
+
+static MIiGXDmaParams MIi_GXDmaParams = { FALSE };
+
+static void MIi_FIFOCallback(void);
+static void MIi_DMACallback(void *arg);
+static void MIi_DMAFastCallback(void *arg);
+
+#pragma section ITCM begin
+ARM_FUNC void MI_SendGXCommand(u32 dmaNo, const void *src, u32 commandLength)
+{
+ vu32 *dmaCntp;
+ u32 leftLength = commandLength;
+ u32 currentSrc = (u32)src;
+ if (!leftLength)
+ {
+ return;
+ }
+
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, commandLength, DMA_SRC_INC);
+
+ do
+ {
+ dmaCntp = &((vu32 *)REG_ADDR_DMA0SAD)[dmaNo * 3 + 2];
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+
+ while (leftLength > 0)
+ {
+ u32 length = (leftLength > MIi_GX_LENGTH_ONCE) ? MIi_GX_LENGTH_ONCE : leftLength;
+ MIi_DmaSetParams(dmaNo, currentSrc, (u32)REG_GXFIFO_ADDR, MI_CNT_SEND32(length));
+ leftLength -= length;
+ currentSrc += length;
+ }
+
+ do
+ {
+ while (*dmaCntp & 0x80000000) {}
+ } while(0);
+}
+#pragma section ITCM end
+
+ARM_FUNC void MI_SendGXCommandAsync(u32 dmaNo, const void *src, u32 commandLength, MIDmaCallback callback, void *arg)
+{
+ if (!commandLength)
+ {
+ MIi_CallCallback(callback, arg);
+ return;
+ }
+
+ while (MIi_GXDmaParams.isBusy) {}
+
+ while (!(G3X_GetCommandFifoStatus() & GX_FIFOSTAT_UNDERHALF)) {}
+
+ MIi_GXDmaParams.isBusy = TRUE;
+ MIi_GXDmaParams.dmaNo = dmaNo;
+ MIi_GXDmaParams.src = (u32)src;
+ MIi_GXDmaParams.length = commandLength;
+ MIi_GXDmaParams.callback = callback;
+ MIi_GXDmaParams.arg = arg;
+
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, commandLength, DMA_SRC_INC);
+
+ MI_WaitDma(dmaNo);
+ {
+ OSIntrMode lastIntrMode = OS_DisableInterrupts();
+
+ MIi_GXDmaParams.fifoCond = (GXFifoIntrCond)((reg_G3X_GXSTAT & 0xc0000000) >> 30);
+ MIi_GXDmaParams.fifoFunc = OS_GetIrqFunction(OS_IE_GXFIFO);
+
+ G3X_SetFifoIntrCond(GX_FIFOINTR_COND_UNDERHALF);
+ OS_SetIrqFunction(OS_IE_GXFIFO, MIi_FIFOCallback);
+ (void)OS_EnableIrqMask(OS_IE_GXFIFO);
+
+ MIi_FIFOCallback();
+
+ (void)OS_RestoreInterrupts(lastIntrMode);
+ }
+}
+
+ARM_FUNC static void MIi_FIFOCallback(void)
+{
+ if (!MIi_GXDmaParams.length)
+ {
+ return;
+ }
+
+ u32 length = (MIi_GXDmaParams.length >= MIi_GX_LENGTH_ONCE) ? MIi_GX_LENGTH_ONCE : MIi_GXDmaParams.length;
+ u32 src = MIi_GXDmaParams.src;
+
+ MIi_GXDmaParams.length -= length;
+ MIi_GXDmaParams.src += length;
+
+ if (!MIi_GXDmaParams.length)
+ {
+ OSi_EnterDmaCallback(MIi_GXDmaParams.dmaNo, MIi_DMACallback, NULL);
+ MIi_DmaSetParams(MIi_GXDmaParams.dmaNo, src, (u32)REG_GXFIFO_ADDR, MI_CNT_SEND32_IF(length));
+ (void)OS_ResetRequestIrqMask(OS_IE_GXFIFO);
+ }
+ else
+ {
+ MIi_DmaSetParams(MIi_GXDmaParams.dmaNo, src, (u32)REG_GXFIFO_ADDR, MI_CNT_SEND32(length));
+ (void)OS_ResetRequestIrqMask(OS_IE_GXFIFO);
+ }
+}
+
+ARM_FUNC static void MIi_DMACallback(void *arg)
+{
+#pragma unused(arg)
+ (void)OS_DisableIrqMask(OS_IE_GXFIFO);
+
+ G3X_SetFifoIntrCond(MIi_GXDmaParams.fifoCond);
+ OS_SetIrqFunction(OS_IE_GXFIFO, MIi_GXDmaParams.fifoFunc);
+
+ MIi_GXDmaParams.isBusy = FALSE;
+
+ MIi_CallCallback(MIi_GXDmaParams.callback, MIi_GXDmaParams.arg);
+}
+
+ARM_FUNC void MI_SendGXCommandAsyncFast(u32 dmaNo, const void *src, u32 commandLength, MIDmaCallback callback, void *arg)
+{
+ if (!commandLength)
+ {
+ MIi_CallCallback(callback, arg);
+ return;
+ }
+
+ while (MIi_GXDmaParams.isBusy) {}
+
+ MIi_GXDmaParams.isBusy = TRUE;
+ MIi_GXDmaParams.dmaNo = dmaNo;
+ MIi_GXDmaParams.callback = callback;
+ MIi_GXDmaParams.arg = arg;
+
+ MIi_CheckAnotherAutoDMA(dmaNo, 0x38000000);
+
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, commandLength, DMA_SRC_INC);
+
+ MI_WaitDma(dmaNo);
+
+ OSi_EnterDmaCallback(dmaNo, MIi_DMAFastCallback, NULL);
+ MIi_DmaSetParams(dmaNo, (u32)src, (u32)REG_GXFIFO_ADDR, MI_CNT_GXCOPY_IF(commandLength));
+}
+
+ARM_FUNC static void MIi_DMAFastCallback(void *arg)
+{
+#pragma unused(arg)
+ MIi_GXDmaParams.isBusy = FALSE;
+
+ MIi_CallCallback(MIi_GXDmaParams.callback, MIi_GXDmaParams.arg);
+}
diff --git a/arm9/lib/NitroSDK/src/MI_dma_hblank.c b/arm9/lib/NitroSDK/src/MI_dma_hblank.c
new file mode 100644
index 00000000..67e579fe
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_dma_hblank.c
@@ -0,0 +1,31 @@
+#include "MI_dma_hblank.h"
+#include "MI_dma.h"
+#include "function_target.h"
+
+ARM_FUNC void MI_HBlankDmaCopy32(u32 dmaNo, const void *src, void *dest, u32 size)
+{
+ MIi_CheckAnotherAutoDMA(dmaNo, MI_DMA_TIMING_H_BLANK);
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ MI_WaitDma(dmaNo);
+ MIi_DmaSetParams(dmaNo, (u32)src, (u32)dest, (u32)(0x96600000 | (size / 4)));
+}
+
+ARM_FUNC void MI_HBlankDmaCopy16(u32 dmaNo, const void *src, void *dest, u32 size)
+{
+ MIi_CheckAnotherAutoDMA(dmaNo, MI_DMA_TIMING_H_BLANK);
+ MIi_CheckDma0SourceAddress(dmaNo, (u32)src, size, MI_DMA_SRC_INC);
+
+ if (size == 0)
+ {
+ return;
+ }
+
+ MI_WaitDma(dmaNo);
+ MIi_DmaSetParams(dmaNo, (u32)src, (u32)dest, (u32)(0x92600000 | (size / 2)));
+}
diff --git a/arm9/lib/NitroSDK/src/MI_init.c b/arm9/lib/NitroSDK/src/MI_init.c
new file mode 100644
index 00000000..4c861286
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_init.c
@@ -0,0 +1,11 @@
+#include "MI_init.h"
+#include "nitro/types.h"
+#include "function_target.h"
+#include "MI_dma.h"
+#include "MI_wram.h"
+
+ARM_FUNC void MI_Init(void)
+{
+ MI_SetWramBank(MI_WRAM_ARM7_ALL);
+ MI_StopDma(0);
+}
diff --git a/arm9/lib/NitroSDK/src/MI_memory.c b/arm9/lib/NitroSDK/src/MI_memory.c
new file mode 100644
index 00000000..a97ff167
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_memory.c
@@ -0,0 +1,339 @@
+#include "MI_memory.h"
+#include "function_target.h"
+
+ARM_FUNC asm void MIi_CpuClear16(register u16 data, register void *destp, register u32 size)
+{
+ mov r3, #0
+
+_020CE1CC:
+ cmp r3, r2
+ strlth r0, [r1, r3]
+ addlt r3, r3, #2
+ blt _020CE1CC
+
+ bx lr
+}
+
+ARM_FUNC asm void MIi_CpuCopy16(register const void *srcp, register void *destp, register u32 size)
+{
+ mov r12, #0
+
+_020CE1CC:
+ cmp r12, r2
+ ldrlth r3, [r0, r12]
+ strlth r3, [r1, r12]
+ addlt r12, r12, #2
+ blt _020CE1CC
+
+ bx lr
+}
+
+ARM_FUNC asm void MIi_CpuClear32(register u32 data, register void *destp, register u32 size)
+{
+ add r12, r1, r2
+
+_020CE200:
+ cmp r1, r12
+ stmltia r1!, {r0}
+ blt _020CE200
+ bx lr
+}
+
+ARM_FUNC asm void MIi_CpuCopy32(register const void *srcp, register void *destp, register u32 size)
+{
+ add r12, r1, r2
+
+_020CE214:
+ cmp r1, r12
+ ldmltia r0!, {r2}
+ stmltia r1!, {r2}
+ blt _020CE214
+ bx lr
+}
+
+ARM_FUNC asm void MIi_CpuSend32(register const void *srcp, volatile void *destp, u32 size)
+{
+ add r12, r0, r2
+
+_020CE22C:
+ cmp r0, r12
+ ldmltia r0!, {r2}
+ strlt r2, [r1]
+ blt _020CE22C
+
+ bx lr
+}
+
+ARM_FUNC asm void MIi_CpuClearFast(register u32 data, register void *destp, register u32 size)
+{
+ stmfd sp!, {r4-r9}
+
+ add r9, r1, r2
+ mov r12, r2, lsr #5
+ add r12, r1, r12, lsl #5
+
+ mov r2, r0
+ mov r3, r2
+ mov r4, r2
+ mov r5, r2
+ mov r6, r2
+ mov r7, r2
+ mov r8, r2
+
+_020CE26C:
+ cmp r1, r12
+ stmltia r1!, {r0, r2-r8}
+ blt _020CE26C
+_020CE278:
+ cmp r1, r9
+ stmltia r1!, {r0}
+ blt _020CE278
+
+ ldmfd sp!, {r4-r9}
+ bx lr
+}
+
+ARM_FUNC asm void MIi_CpuCopyFast(register const void *srcp, register void *destp, register u32 size)
+{
+ stmfd sp!, {r4-r10}
+
+ add r10, r1, r2
+ mov r12, r2, lsr #5
+ add r12, r1, r12, lsl #5
+
+_020CE29C:
+ cmp r1, r12
+ ldmltia r0!, {r2-r9}
+ stmltia r1!, {r2-r9}
+ blt _020CE29C
+_020CE2AC:
+ cmp r1, r10
+ ldmltia r0!, {r2}
+ stmltia r1!, {r2}
+ blt _020CE2AC
+
+ ldmfd sp!, {r4-r10}
+ bx lr
+}
+
+ARM_FUNC asm void MI_Copy32B(register const void *pSrc, register void *pDest)
+{
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3}
+ stmia r1!, {r2, r3}
+
+ bx lr
+}
+
+ARM_FUNC asm void MI_Copy36B(register const void *pSrc, register void *pDest)
+{
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+
+ bx lr
+}
+
+ARM_FUNC asm void MI_Copy48B(register const void *pSrc, register void *pDest)
+{
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+
+ bx lr
+}
+
+ARM_FUNC asm void MI_Copy64B(register const void *pSrc, register void *pDest)
+{
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0!, {r2, r3, r12}
+ stmia r1!, {r2, r3, r12}
+ ldmia r0, {r0, r2, r3, r12}
+ stmia r1!, {r0, r2, r3, r12}
+
+ bx lr
+}
+
+ARM_FUNC asm void MI_CpuFill8(register void *dstp, register u8 data, register u32 size)
+{
+ cmp r2, #0
+ bxeq lr
+
+ tst r0, #1
+ beq _020CE378
+ ldrh r12, [r0, #-1]
+ and r12, r12, #0x00ff
+ orr r3, r12, r1, lsl #8
+ strh r3, [r0, #-1]
+ add r0, r0, #1
+ subs r2, r2, #1
+ bxeq lr
+
+_020CE378:
+ cmp r2, #2
+ bcc _020CE3C0
+ orr r1, r1, r1, lsl #8
+ tst r0, #2
+ beq _020CE398
+ strh r1, [r0], #2
+ subs r2, r2, #2
+ bxeq lr
+
+_020CE398:
+ orr r1, r1, r1, lsl #16
+ bics r3, r2, #3
+ beq _020CE3B8
+ sub r2, r2, r3
+ add r12, r3, r0
+
+_020CE3AC:
+ str r1, [r0], #4
+ cmp r0, r12
+ bcc _020CE3AC
+
+_020CE3B8:
+ tst r2, #2
+ strneh r1, [r0], #2
+
+_020CE3C0:
+ tst r2, #1
+ bxeq lr
+ ldrh r3, [r0]
+ and r3, r3, #0xff00
+ and r1, r1, #0x00ff
+ orr r1, r1, r3
+ strh r1, [r0]
+ bx lr
+}
+
+ARM_FUNC asm void MI_CpuCopy8(register const void *srcp, register void *dstp, register u32 size)
+{
+ cmp r2, #0
+ bxeq lr
+
+ tst r1, #1
+ beq _020CE420
+ ldrh r12, [r1, #-1]
+ and r12, r12, #0x00ff
+ tst r0, #1
+ ldrneh r3, [r0, #-1]
+ movne r3, r3, lsr #8
+ ldreqh r3, [r0]
+ orr r3, r12, r3, lsl #8
+ strh r3, [r1, #-1]
+ add r0, r0, #1
+ add r1, r1, #1
+ subs r2, r2, #1
+ bxeq lr
+
+_020CE420:
+ eor r12, r1, r0
+ tst r12, #1
+ beq _020CE474
+
+ bic r0, r0, #1
+ ldrh r12, [r0], #2
+ mov r3, r12, lsr #8
+ subs r2, r2, #2
+ bcc _020CE458
+
+_020CE440:
+ ldrh r12, [r0], #2
+ orr r12, r3, r12, lsl #8
+ strh r12, [r1], #2
+ mov r3, r12, lsr #16
+ subs r2, r2, #2
+ bcs _020CE440
+
+_020CE458:
+ tst r2, #1
+ bxeq lr
+ ldrh r12, [r1]
+ and r12, r12, #0xff00
+ orr r12, r12, r3
+ strh r12, [r1]
+ bx lr
+
+_020CE474:
+ tst r12, #2
+ beq _020CE4A0
+
+ bics r3, r2, #1
+ beq _020CE4EC
+ sub r2, r2, r3
+ add r12, r3, r1
+
+_020CE48C:
+ ldrh r3, [r0], #2
+ strh r3, [r1], #2
+ cmp r1, r12
+ bcc _020CE48C
+ b _020CE4EC
+
+_020CE4A0:
+ cmp r2, #2
+ bcc _020CE4EC
+ tst r1, #2
+ beq _020CE4C0
+ ldrh r3, [r0], #2
+ strh r3, [r1], #2
+ subs r2, r2, #2
+ bxeq lr
+
+_020CE4C0:
+ bics r3, r2, #3
+ beq _020CE4E0
+ sub r2, r2, r3
+ add r12, r3, r1
+
+_020CE4D0:
+ ldr r3, [r0], #4
+ str r3, [r1], #4
+ cmp r1, r12
+ bcc _020CE4D0
+
+_020CE4E0:
+ tst r2, #2
+ ldrneh r3, [r0], #2
+ strneh r3, [r1], #2
+
+_020CE4EC:
+ tst r2, #1
+ bxeq lr
+ ldrh r2, [r1]
+ ldrh r0, [r0]
+ and r2, r2, #0xff00
+ and r0, r0, #0x00ff
+ orr r0, r2, r0
+ strh r0, [r1]
+
+ bx lr
+}
+
+THUMB_FUNC asm void MI_Zero36B(register void *pDest)
+{
+ mov r1, #0
+ mov r2, #0
+ mov r3, #0
+ stmia r0!, {r1, r2, r3}
+ stmia r0!, {r1, r2, r3}
+ stmia r0!, {r1, r2, r3}
+
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/MI_swap.c b/arm9/lib/NitroSDK/src/MI_swap.c
new file mode 100644
index 00000000..b72e1386
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_swap.c
@@ -0,0 +1,16 @@
+#include "global.h"
+#include "MI_swap.h"
+
+/*
+ * Exchange 32 bits of data between register and memory.
+ *
+ * The SDK also defines an 8-bit version of this routine,
+ * but it is not linked in pokediamond.
+ */
+
+asm
+u32 MI_SwapWord(register u32 setData, register vu32 * destp)
+{
+ swp setData, setData, [destp]
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/MI_uncompress.c b/arm9/lib/NitroSDK/src/MI_uncompress.c
new file mode 100644
index 00000000..c6ad7e4e
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_uncompress.c
@@ -0,0 +1,59 @@
+#include "function_target.h"
+#include "MI_uncompress.h"
+
+ARM_FUNC asm void MI_UncompressLZ8(register const void *srcp, register void *destp)
+{
+ stmfd sp!, {r4-r6, lr}
+
+ ldr r5, [r0], #4
+ mov r2, r5, lsr #8
+
+_020CE534:
+ cmp r2, #0
+ ble _020CE5B4
+
+ ldrb lr, [r0], #1
+ mov r4, #8
+
+_020CE544:
+ subs r4, r4, #1
+ blt _020CE534
+
+ tst lr, #0x80
+ bne _020CE568
+
+ ldrb r6, [r0], #1
+ swpb r6, r6, [r1]
+ add r1, r1, #1
+ sub r2, r2, #1
+ b _020CE5A4
+
+_020CE568:
+ ldrb r5, [r0, #0]
+ mov r6, #3
+ add r3, r6, r5, asr #4
+ ldrb r6, [r0], #1
+ and r5, r6, #0xf
+ mov r12, r5, lsl #8
+ ldrb r6, [r0], #1
+ orr r5, r6, r12
+ add r12, r5, #1
+ sub r2, r2, r3
+
+_020CE590:
+ ldrb r5, [r1, -r12]
+ swpb r5, r5, [r1]
+ add r1, r1, #1
+ subs r3, r3, #1
+ bgt _020CE590
+
+_020CE5A4:
+ cmp r2, #0
+ movgt lr, lr, lsl #1
+ bgt _020CE544
+ b _020CE534
+
+_020CE5B4:
+ ldmfd sp!, {r4-r6, lr}
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/MI_wram.c b/arm9/lib/NitroSDK/src/MI_wram.c
new file mode 100644
index 00000000..c1433f07
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/MI_wram.c
@@ -0,0 +1,9 @@
+#include "MI_wram.h"
+
+#include "global.h"
+#include "registers.h"
+
+ARM_FUNC void MI_SetWramBank(MIWram cnt)
+{
+ reg_GX_VRAMCNT_WRAM = (u8)cnt;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_alarm.c b/arm9/lib/NitroSDK/src/OS_alarm.c
new file mode 100644
index 00000000..a8c1fedd
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_alarm.c
@@ -0,0 +1,254 @@
+#include "function_target.h"
+#include "consts.h"
+#include "OS_alarm.h"
+#include "OS_interrupt.h"
+#include "OS_irqTable.h"
+#include "OS_terminate_proc.h"
+#include "OS_system.h"
+
+static struct OSiAlarmQueue OSi_AlarmQueue;
+
+static u16 OSi_UseAlarm = FALSE;
+
+static void OSi_SetTimer(OSAlarm *alarm);
+static void OSi_InsertAlarm(OSAlarm *alarm, OSTick fire);
+static void OSi_ArrangeTimer(void);
+
+ARM_FUNC static void OSi_SetTimer(OSAlarm *alarm)
+{
+ OSTick tick = OS_GetTick();
+
+ OS_SetTimerControl(OS_TIMER_1, 0);
+
+ s64 delta = (s64)(alarm->fire - tick);
+
+ OSi_EnterTimerCallback(OS_TIMER_1, OSi_AlarmHandler, NULL);
+
+ u16 timerCount;
+ if (delta < 0)
+ {
+ timerCount = (u16)~1;
+ }
+ else if (delta < 0x10000)
+ {
+ timerCount = (u16)(~delta);
+ }
+ else
+ {
+ timerCount = 0;
+ }
+
+ OS_SetTimerCount((OSTimer)OS_TIMER_1, timerCount);
+ OS_SetTimerControl(OS_TIMER_1, (u16)OSi_TICK_TIMERCONTROL);
+
+ (void)OS_EnableIrqMask(OS_IE_TIMER1);
+}
+
+ARM_FUNC void OS_InitAlarm(void)
+{
+ if (!OSi_UseAlarm)
+ {
+ OSi_UseAlarm = TRUE;
+
+ OSi_SetTimerReserved(OS_TIMER_1);
+
+ OSi_AlarmQueue.head = NULL;
+ OSi_AlarmQueue.tail = NULL;
+
+ (void)OS_DisableIrqMask(OS_IE_TIMER1);
+ }
+}
+
+ARM_FUNC BOOL OS_IsAlarmAvailable(void)
+{
+ return OSi_UseAlarm;
+}
+
+ARM_FUNC void OS_CreateAlarm(OSAlarm *alarm)
+{
+ alarm->handler = 0;
+ alarm->tag = 0;
+}
+
+ARM_FUNC static void OSi_InsertAlarm(OSAlarm *alarm, OSTick fire)
+{
+ if (alarm->period > 0)
+ {
+ OSTick tick = OS_GetTick();
+
+ fire = alarm->start;
+ if (alarm->start < tick)
+ {
+ fire += alarm->period * ((tick - alarm->start) / alarm->period + 1);
+ }
+ }
+
+ alarm->fire = fire;
+
+ OSAlarm *prev;
+ OSAlarm *next;
+
+ for (next = OSi_AlarmQueue.head; next; next = next->next)
+ {
+ if ((s64)(fire - next->fire) >= 0)
+ {
+ continue;
+ }
+
+ alarm->prev = next->prev;
+ next->prev = alarm;
+ alarm->next = next;
+ prev = alarm->prev;
+ if (prev)
+ {
+ prev->next = alarm;
+ }
+ else
+ {
+ OSi_AlarmQueue.head = alarm;
+ OSi_SetTimer(alarm);
+ }
+
+ return;
+ }
+
+ alarm->next = 0;
+ prev = OSi_AlarmQueue.tail;
+ OSi_AlarmQueue.tail = alarm;
+ alarm->prev = prev;
+ if (prev)
+ {
+ prev->next = alarm;
+ }
+ else
+ {
+ OSi_AlarmQueue.head = OSi_AlarmQueue.tail = alarm;
+ OSi_SetTimer(alarm);
+ }
+}
+
+ARM_FUNC void OS_SetAlarm(OSAlarm * alarm, OSTick tick, OSAlarmHandler handler, void *arg)
+{
+ if (!alarm || alarm->handler)
+ {
+ OS_Terminate();
+ }
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ alarm->period = 0;
+
+ alarm->handler = handler;
+ alarm->arg = arg;
+
+ OSi_InsertAlarm(alarm, OS_GetTick() + tick);
+
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC void OS_CancelAlarm(OSAlarm *alarm)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ if (!alarm->handler)
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return;
+ }
+
+ OSAlarm *next = alarm->next;
+
+ if (!next)
+ {
+ OSi_AlarmQueue.tail = alarm->prev;
+ }
+ else
+ {
+ next->prev = alarm->prev;
+ }
+
+ if (alarm->prev)
+ {
+ alarm->prev->next = next;
+ }
+ else
+ {
+ OSi_AlarmQueue.head = next;
+ if (next)
+ {
+ OSi_SetTimer(next);
+ }
+ }
+
+ alarm->handler = NULL;
+ alarm->period = 0;
+
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC asm void OSi_AlarmHandler(void *arg)
+{
+ stmfd sp!, {r0, lr}
+ bl OSi_ArrangeTimer
+ ldmfd sp!, {r0, lr}
+ bx lr
+}
+
+ARM_FUNC static void OSi_ArrangeTimer(void)
+{
+ OS_SetTimerControl(OS_TIMER_1, 0);
+
+ (void)OS_DisableIrqMask(OS_IE_TIMER1);
+
+ OS_SetIrqCheckFlag(OS_IE_TIMER1);
+
+ OSTick tick = OS_GetTick();
+
+ OSAlarm *alarm = OSi_AlarmQueue.head;
+
+ if (!alarm)
+ {
+ return;
+ }
+
+ if (tick < alarm->fire)
+ {
+ OSi_SetTimer(alarm);
+ return;
+ }
+
+ OSAlarm *next = alarm->next;
+ OSi_AlarmQueue.head = next;
+
+ if (!next)
+ {
+ OSi_AlarmQueue.tail = NULL;
+ }
+ else
+ {
+ next->prev = NULL;
+ }
+
+ OSAlarmHandler handler = alarm->handler;
+
+ if (!alarm->period)
+ {
+ alarm->handler = NULL;
+ }
+
+ if (handler)
+ {
+ (handler)(alarm->arg);
+ }
+
+ if (alarm->period > 0)
+ {
+ alarm->handler = handler;
+ OSi_InsertAlarm(alarm, 0);
+ }
+
+ if (OSi_AlarmQueue.head)
+ {
+ OSi_SetTimer(OSi_AlarmQueue.head);
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/OS_alloc.c b/arm9/lib/NitroSDK/src/OS_alloc.c
new file mode 100644
index 00000000..dc84151b
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_alloc.c
@@ -0,0 +1,167 @@
+//
+// Created by mart on 4/23/20.
+//
+#include "function_target.h"
+#include "OS_alloc.h"
+#include "consts.h"
+#include "OS_system.h"
+
+void* OSiHeapInfo[OS_ARENA_MAX];
+
+ARM_FUNC Cell* DLAddFront(Cell* list, Cell* cell)
+{
+ cell->next = list;
+ cell->prev = NULL;
+
+ if (list != NULL)
+ list->prev = cell;
+ return cell;
+}
+
+ARM_FUNC Cell* DLExtract(Cell* list, Cell* cell)
+{
+ if (cell->next) {
+ cell->next->prev = cell->prev;
+ }
+ if (cell->prev == NULL) {
+ list = cell->next;
+ } else {
+ cell->prev->next = cell->next;
+ }
+ return list;
+}
+
+ARM_FUNC Cell *DLInsert(Cell *original, Cell *inserted)
+{
+ Cell *prevCell = NULL;
+ Cell *nextCell = original;
+
+
+ for (nextCell = original, prevCell = NULL; nextCell; prevCell = nextCell, nextCell = nextCell->next)
+ {
+ if (inserted <= nextCell)
+ break;
+ }
+
+ inserted->next = nextCell;
+ inserted->prev = prevCell;
+
+ if (nextCell != NULL)
+ {
+ nextCell->prev = inserted;
+ Cell * temp = (Cell *)((char *)inserted + inserted->size);
+ if (temp == nextCell)
+ {
+ inserted->size += nextCell->size;
+ nextCell = nextCell->next;
+ inserted->next = nextCell;
+ if (nextCell != NULL)
+ nextCell->prev = inserted;
+ }
+ }
+
+ if (prevCell != NULL)
+ {
+ prevCell->next = inserted;
+ Cell * temp = (Cell *)((char *)prevCell + prevCell->size);
+
+ if (temp != inserted)
+ return original;
+
+ prevCell->size += inserted->size;
+ prevCell->next = nextCell;
+ if (nextCell != NULL)
+ nextCell->prev = prevCell;
+
+ return original;
+ }
+
+ return inserted;
+}
+
+#define HEADERSIZE OSi_ROUND(sizeof(Cell), 32)
+#define MINOBJSIZE (HEADERSIZE+32)
+
+ARM_FUNC void* OS_AllocFromHeap(OSArenaId id, OSHeapHandle heap, u32 size) {
+ OSHeapInfo* heapInfo;
+ HeapDesc* hd;
+ Cell* cell;
+ Cell* newCell;
+ long leftoverSize;
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+ heapInfo = OSiHeapInfo[id];
+ if (!heapInfo) {
+ (void)OS_RestoreInterrupts(enabled);
+ return NULL;
+ }
+
+ if (heap < 0) {
+ heap = heapInfo->currentHeap;
+ }
+
+ hd = &heapInfo->heapArray[heap];
+
+ size += HEADERSIZE;
+ size = OSi_ROUND(size, 32);
+
+ for (cell = hd->free; cell != NULL; cell = cell->next) {
+ if ((long)size <= cell->size) {
+ break;
+ }
+ }
+
+ if (cell == NULL) {
+ (void)OS_RestoreInterrupts(enabled);
+ return NULL;
+ }
+
+ leftoverSize = cell->size - (long)size;
+ if (leftoverSize < MINOBJSIZE) {
+ hd->free = DLExtract(hd->free, cell);
+ } else {
+ cell->size = (long)size;
+
+ newCell = (Cell *) ((char *)cell + size);
+ newCell->size = leftoverSize;
+
+ 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;
+ }
+ }
+
+ hd->allocated = DLAddFront(hd->allocated, cell);
+
+ (void)OS_RestoreInterrupts(enabled);
+ return (void *)((char *)cell + HEADERSIZE);
+}
+
+ARM_FUNC void OS_FreeToHeap(OSArenaId id, OSHeapHandle heap, void* ptr) {
+ OSHeapInfo *heapInfo;
+ HeapDesc *hd;
+ Cell *cell;
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+ heapInfo = OSiHeapInfo[id];
+
+ if (heap < 0) {
+ heap = heapInfo->currentHeap;
+ }
+
+ cell = (Cell *) ((char *)ptr - HEADERSIZE);
+ hd = &heapInfo->heapArray[heap];
+
+ hd->allocated = DLExtract(hd->allocated, cell);
+ hd->free = DLInsert(hd->free, cell);
+
+ (void)OS_RestoreInterrupts(enabled);
+}
diff --git a/arm9/lib/NitroSDK/src/OS_arena.c b/arm9/lib/NitroSDK/src/OS_arena.c
new file mode 100644
index 00000000..cc9694c2
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_arena.c
@@ -0,0 +1,168 @@
+#include "OS_arena.h"
+
+#include "global.h"
+#include "OS_protectionRegion.h"
+#include "OS_emulator.h"
+#include "mmap.h"
+
+static BOOL OSi_Initialized = FALSE;
+static BOOL OSi_MainExArenaEnabled = FALSE;
+
+void SDK_MAIN_ARENA_LO(); // TODO: technically this should be defined in the lcf
+extern void SDK_SECTION_ARENA_EX_START(); // TODO: technically this should be defined in the lcf
+extern void SDK_SECTION_ARENA_ITCM_START(); // TODO: technically this should be defined in the lcf
+extern void SDK_SECTION_ARENA_DTCM_START(); // TODO: technically this should be defined in the lcf
+extern void SDK_IRQ_STACKSIZE(); // TODO: technically this should be defined in the lcf
+extern void SDK_SYS_STACKSIZE(); // TODO: technically this should be defined in the lcf
+
+ARM_FUNC void OS_InitArena(void) {
+ if (OSi_Initialized) {
+ return;
+ }
+ OSi_Initialized = TRUE;
+
+ OS_SetArenaHi(OS_ARENA_MAIN, OS_GetInitArenaHi(OS_ARENA_MAIN));
+ OS_SetArenaLo(OS_ARENA_MAIN, OS_GetInitArenaLo(OS_ARENA_MAIN));
+
+ OS_SetArenaLo(OS_ARENA_MAINEX, (void *)0);
+ OS_SetArenaHi(OS_ARENA_MAINEX, (void *)0);
+
+ OS_SetArenaHi(OS_ARENA_ITCM, OS_GetInitArenaHi(OS_ARENA_ITCM));
+ OS_SetArenaLo(OS_ARENA_ITCM, OS_GetInitArenaLo(OS_ARENA_ITCM));
+
+ OS_SetArenaHi(OS_ARENA_DTCM, OS_GetInitArenaHi(OS_ARENA_DTCM));
+ OS_SetArenaLo(OS_ARENA_DTCM, OS_GetInitArenaLo(OS_ARENA_DTCM));
+
+ OS_SetArenaHi(OS_ARENA_SHARED, OS_GetInitArenaHi(OS_ARENA_SHARED));
+ OS_SetArenaLo(OS_ARENA_SHARED, OS_GetInitArenaLo(OS_ARENA_SHARED));
+
+ OS_SetArenaHi(OS_ARENA_WRAM_MAIN, OS_GetInitArenaHi(OS_ARENA_WRAM_MAIN));
+ OS_SetArenaLo(OS_ARENA_WRAM_MAIN, OS_GetInitArenaLo(OS_ARENA_WRAM_MAIN));
+}
+
+ARM_FUNC void OS_InitArenaEx(void) {
+ OS_SetArenaHi(OS_ARENA_MAINEX, OS_GetInitArenaHi(OS_ARENA_MAINEX));
+ OS_SetArenaLo(OS_ARENA_MAINEX, OS_GetInitArenaLo(OS_ARENA_MAINEX));
+
+ if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) {
+ OS_SetProtectionRegion(1, HW_MAIN_MEM, 4MB);
+ OS_SetProtectionRegion(2, HW_MAIN_MEM_MAIN_END, 128KB);
+ }
+}
+
+ARM_FUNC void* OS_GetArenaHi(OSArenaId id) {
+ return OSi_GetArenaInfo().hi[id];
+}
+
+ARM_FUNC void* OS_GetArenaLo(OSArenaId id) {
+ return OSi_GetArenaInfo().lo[id];
+}
+
+ARM_FUNC void* OS_GetInitArenaHi(OSArenaId id) {
+ switch (id) {
+ case OS_ARENA_MAIN:
+ return (void *)OSi_MAIN_ARENA_HI_DEFAULT;
+ case OS_ARENA_MAINEX:
+ if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) {
+ return (void *)0;
+ } else {
+ return (void *)OSi_MAINEX_ARENA_HI_DEFAULT;
+ }
+ case OS_ARENA_ITCM:
+ return (void *)HW_ITCM_ARENA_HI_DEFAULT;
+ case OS_ARENA_DTCM:
+ {
+ u32 irqStackLo = (u32) HW_DTCM_IRQ_STACK_END - (s32) SDK_IRQ_STACKSIZE;
+ u32 sysStackLo;
+
+ if (!(s32) SDK_SYS_STACKSIZE) {
+ sysStackLo = HW_DTCM;
+ if (sysStackLo < (u32) SDK_SECTION_ARENA_DTCM_START) {
+ sysStackLo = (u32) SDK_SECTION_ARENA_DTCM_START;
+ }
+ } else if ((s32) SDK_SYS_STACKSIZE < 0) {
+ sysStackLo = (u32) SDK_SECTION_ARENA_DTCM_START - (s32) SDK_SYS_STACKSIZE;
+ } else {
+ sysStackLo = irqStackLo - (s32) SDK_SYS_STACKSIZE;
+ }
+ return (void *) sysStackLo;
+ }
+ case OS_ARENA_SHARED:
+ return (void *)HW_SHARED_ARENA_HI_DEFAULT;
+ case OS_ARENA_WRAM_MAIN:
+ return (void *)OSi_WRAM_MAIN_ARENA_HI_DEFAULT;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void* OS_GetInitArenaLo(OSArenaId id) {
+ switch (id) {
+ case OS_ARENA_MAIN:
+ return (void *)SDK_MAIN_ARENA_LO;
+ case OS_ARENA_MAINEX:
+ if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) {
+ return NULL;
+ } else {
+ return (void *)SDK_SECTION_ARENA_EX_START;
+ }
+ case OS_ARENA_ITCM:
+ return (void *)SDK_SECTION_ARENA_ITCM_START;
+ case OS_ARENA_DTCM:
+ return (void *)SDK_SECTION_ARENA_DTCM_START;
+ case OS_ARENA_SHARED:
+ return (void *)HW_SHARED_ARENA_LO_DEFAULT;
+ case OS_ARENA_WRAM_MAIN:
+ return (void *)OSi_WRAM_MAIN_ARENA_LO_DEFAULT;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void OS_SetArenaHi(OSArenaId id, void* newHi) {
+ OSi_GetArenaInfo().hi[id] = newHi;
+}
+
+ARM_FUNC void OS_SetArenaLo(OSArenaId id, void* newLo) {
+ OSi_GetArenaInfo().lo[id] = newLo;
+}
+
+ARM_FUNC void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) {
+ void* ptr;
+ u8* arenaLo;
+ ptr = OS_GetArenaLo(id);
+ if (!ptr) {
+ return NULL;
+ }
+ arenaLo = ptr = (void *)OSi_ROUND(ptr, align);
+ arenaLo += size;
+ arenaLo = (u8 *)OSi_ROUND(arenaLo, align);
+ if (arenaLo > (u8*)OS_GetArenaHi(id)) {
+ return NULL;
+ }
+ OS_SetArenaLo(id, arenaLo);
+
+ return ptr;
+}
+
+ARM_FUNC void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) {
+ void* ptr;
+ u8* arenaHi;
+
+ arenaHi = OS_GetArenaHi(id);
+ if (!arenaHi) {
+ return NULL;
+ }
+
+ arenaHi = (u8 *)OSi_TRUNC(arenaHi, align);
+ arenaHi -= size;
+ arenaHi = ptr = (void *)OSi_TRUNC(arenaHi, align);
+
+ if (arenaHi < (u8*)OS_GetArenaLo(id)) {
+ return NULL;
+ }
+
+ OS_SetArenaHi(id, arenaHi);
+
+ return ptr;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_cache.c b/arm9/lib/NitroSDK/src/OS_cache.c
new file mode 100644
index 00000000..8b202fda
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_cache.c
@@ -0,0 +1,126 @@
+#include "OS_cache.h"
+#include "nitro/types.h"
+#include "function_target.h"
+
+ARM_FUNC asm void DC_InvalidateAll(void)
+{
+ mov r0, #0
+ mcr p15, 0, r0, c7, c6, 0 //Invalidate Entire Data Cache
+ bx lr
+}
+
+ARM_FUNC asm void DC_StoreAll(void)
+{
+ mov r1, #0
+
+_020CC0C8:
+ mov r0, #0
+
+_020CC0CC:
+ orr r2, r1, r0
+ mcr p15, 0, r2, c7, c10, 2 //Clean Data Cache Line Set/Index
+ add r0, r0, #32
+ cmp r0, #0x400
+ blt _020CC0CC
+
+ add r1, r1, #0x40000000
+ cmp r1, #0
+ bne _020CC0C8
+
+ bx lr
+}
+
+ARM_FUNC asm void DC_FlushAll(void)
+{
+ mov r12, #0
+ mov r1, #0
+
+_020CC0F8:
+ mov r0, #0
+
+_020CC0FC:
+ orr r2, r1, r0
+ mcr p15, 0, r12, c7, c10, 4 //Drain Write Buffer
+ mcr p15, 0, r2, c7, c14, 2 //Clean and Invalidate Data Cache Line Set/Index
+ add r0, r0, #32
+ cmp r0, #0x400
+ blt _020CC0FC
+
+ add r1, r1, #0x40000000
+ cmp r1, #0
+ bne _020CC0F8
+
+ bx lr
+}
+
+ARM_FUNC asm void DC_InvalidateRange(register void *startAddr, register u32 nBytes)
+{
+ add r1, r1, r0
+ bic r0, r0, #31
+
+_020CC12C:
+ mcr p15, 0, r0, c7, c6, 1 //Invalidated Data Cache Line Virtual Address
+ add r0, r0, #32
+ cmp r0, r1
+ blt _020CC12C
+
+ bx lr
+}
+
+ARM_FUNC asm void DC_StoreRange(register void *startAddr, register u32 nBytes)
+{
+ add r1, r1, r0
+ bic r0, r0, #31
+
+_020CC148:
+ mcr p15, 0, r0, c7, c10, 1 //Clean Data Cache Line Virtual Address
+ add r0, r0, #32
+ cmp r0, r1
+ blt _020CC148
+
+ bx lr
+}
+
+ARM_FUNC asm void DC_FlushRange(register const void *startAddr, register u32 nBytes)
+{
+ mov r12, #0
+ add r1, r1, r0
+ bic r0, r0, #31
+
+_020CC168:
+ mcr p15, 0, r12, c7, c10, 4 //Drain Write Buffer
+ mcr p15, 0, r0, c7, c14, 1 //Clean and Invalidate Data Cache Line Virtual Address
+ add r0, r0, #32
+ cmp r0, r1
+ blt _020CC168
+
+ bx lr
+}
+
+ARM_FUNC asm void DC_WaitWriteBufferEmpty(void)
+{
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 //Drain Write Buffer
+ bx lr
+}
+
+ARM_FUNC asm void IC_InvalidateAll(void)
+{
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 //Invalidate Entire Instruction Cache
+ bx lr
+}
+
+ARM_FUNC asm void IC_InvalidateRange(register void *startAddr, register u32 nBytes)
+{
+ add r1, r1, r0
+ bic r0, r0, #31
+
+_020CC1A0:
+ mcr p15, 0, r0, c7, c5, 1 //Invalidate Instruction Cache Line Virtual Address
+ add r0, r0, #32
+ cmp r0, r1
+ blt _020CC1A0
+
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/OS_context.c b/arm9/lib/NitroSDK/src/OS_context.c
new file mode 100644
index 00000000..38b722ba
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_context.c
@@ -0,0 +1,92 @@
+#include "OS_context.h"
+#include "consts.h"
+#include "function_target.h"
+
+ARM_FUNC asm void OS_InitContext(register OSContext *context, register u32 newpc, register u32 newsp)
+{
+ add newpc, newpc, #4
+ str newpc, [context, #0x40]
+
+ str newsp, [context, #0x44]
+ sub newsp, newsp, #HW_SVC_STACK_SIZE
+
+ tst newsp, #4
+ subne newsp, newsp, #4
+ str newsp, [context, #0x38]
+
+ ands r1, newpc, #1
+ movne r1, #0x3f
+ moveq r1, #0x1f
+ str r1, [context]
+
+ mov r1, #0
+ str r1, [context, #0x4]
+ str r1, [context, #0x8]
+ str r1, [context, #0xc]
+ str r1, [context, #0x10]
+ str r1, [context, #0x14]
+ str r1, [context, #0x18]
+ str r1, [context, #0x1c]
+ str r1, [context, #0x20]
+ str r1, [context, #0x24]
+ str r1, [context, #0x28]
+ str r1, [context, #0x2c]
+ str r1, [context, #0x30]
+ str r1, [context, #0x34]
+ str r1, [context, #0x3c]
+
+ bx lr
+}
+
+ARM_FUNC asm BOOL OS_SaveContext(register OSContext* context)
+{
+ stmfd sp!, {lr, r0}
+ add r0, r0, #0x48
+ ldr r1, =CP_SaveContext
+ blx r1
+ ldmfd sp!, {lr, r0}
+
+ add r1, r0, #0
+
+ mrs r2, cpsr
+ str r2, [r1], #0x4
+
+ mov r0, #0xd3
+ msr cpsr_c, r0
+ str sp, [r1, #0x40]
+ msr cpsr_c, r2
+
+ mov r0, #1
+ stmia r1, {r0-r14}
+ add r0, pc, #8
+ str r0, [r1, #0x3c]
+
+ mov r0, #0
+ bx lr
+}
+
+ARM_FUNC asm void OS_LoadContext(register OSContext* context)
+{
+ stmfd sp!, {lr, r0}
+ add r0, r0, #0x48
+
+ ldr r1, =CPi_RestoreContext
+ blx r1
+ ldmfd sp!, {lr, r0}
+
+ mrs r1, cpsr
+ bic r1, r1, #HW_PSR_CPU_MODE_MASK
+ orr r1, r1, #0xd3
+ msr cpsr_c, r1
+
+ ldr r1, [r0], #0x4
+ msr spsr_fsxc, r1
+
+ ldr sp, [r0, #0x40]
+
+ ldr lr, [r0, #0x3c]
+ ldmia r0, {r0-r14}^
+ nop
+
+ subs pc, lr, #4
+}
diff --git a/arm9/lib/NitroSDK/src/OS_emulator.c b/arm9/lib/NitroSDK/src/OS_emulator.c
new file mode 100644
index 00000000..e92a7d9d
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_emulator.c
@@ -0,0 +1,18 @@
+//
+// Created by red031000 on 2020-05-05.
+//
+
+#include "OS_emulator.h"
+#include "function_target.h"
+
+u32 OSi_ConsoleTypeCache = -1u;
+
+ARM_FUNC BOOL OS_IsRunOnEmulator(void) {
+ return FALSE;
+}
+
+ARM_FUNC u32 OS_GetConsoleType(void) {
+ OSi_ConsoleTypeCache = OS_CONSOLE_NITRO | OS_CONSOLE_DEV_CARD | OS_CONSOLE_SIZE_4MB;
+
+ return OSi_ConsoleTypeCache;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_entropy.c b/arm9/lib/NitroSDK/src/OS_entropy.c
new file mode 100644
index 00000000..5d466f82
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_entropy.c
@@ -0,0 +1,25 @@
+//
+// Created by red031000 on 2020-05-03.
+//
+
+#include "OS_entropy.h"
+
+#include "global.h"
+#include "registers.h"
+#include "systemWork.h"
+#include "userInfo.h"
+
+ARM_FUNC void OS_GetLowEntropyData(u32 * arr)
+{
+ const OSSystemWork* work = OS_GetSystemWork();
+ const u8 * macAddress = (u8 *)((u32)(work->nvramUserInfo) + ((sizeof(NVRAMConfig) + 3) & ~3));
+ arr[0] = (u32)((GX_GetVCount() << 16) | OS_GetTickLo());
+ arr[1] = (u32)(*(u16 *)(macAddress + 4) << 16) ^ (u32)(OSi_TickCounter);
+ arr[2] = (u32)(OSi_TickCounter >> 32) ^ *(u32 *)macAddress ^ work->vblankCount;
+ arr[2] ^= reg_G3X_GXSTAT;
+ arr[3] = *(u32 *)(&work->real_time_clock[0]);
+ arr[4] = *(u32 *)(&work->real_time_clock[4]);
+ arr[5] = (((u32)work->mic_sampling_data) << 16) ^ work->mic_last_address;
+ arr[6] = (u32) ((*(u16 *)(&work->touch_panel[0]) << 16) | *(u16 *)(&work->touch_panel[2]));
+ arr[7] = (u32)((work->wm_rssi_pool << 16) | (reg_PAD_KEYINPUT | *(vu16 *)HW_BUTTON_XY_BUF));
+}
diff --git a/arm9/lib/NitroSDK/src/OS_exception.c b/arm9/lib/NitroSDK/src/OS_exception.c
new file mode 100644
index 00000000..63cd6d58
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_exception.c
@@ -0,0 +1,164 @@
+#include "OS_exception.h"
+
+#include "global.h"
+#include "OS_protectionUnit.h"
+#include "mmap.h"
+
+static OSiExContext OSi_ExContext;
+
+static OSExceptionHandler OSi_UserExceptionHandler;
+static void *OSi_UserExceptionHandlerArg;
+
+static void *OSi_DebuggerHandler = NULL;
+
+#define HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER 0x027ffd9c
+
+static void OSi_GetAndDisplayContext(void);
+static void OSi_SetExContext(void);
+static void OSi_DisplayExContext(void);
+
+ARM_FUNC void OS_InitException(void)
+{
+ if (0x2600000 <= *(u32 *)HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER
+ && *(u32 *)HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER < 0x2800000)
+ {
+ OSi_DebuggerHandler = *(void **)HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER;
+ }
+ else
+ {
+ OSi_DebuggerHandler = NULL;
+ }
+
+ if (!OSi_DebuggerHandler)
+ {
+ *(u32 *)(HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER) = (u32)OSi_ExceptionHandler;
+
+ *(u32 *)(HW_EXCP_VECTOR_BUF) = (u32)OSi_ExceptionHandler;
+ }
+
+ OSi_UserExceptionHandler = NULL;
+}
+
+ARM_FUNC asm void OSi_ExceptionHandler(void)
+{
+ ldr r12, =OSi_DebuggerHandler
+ ldr r12, [r12]
+ cmp r12, #0
+ movne lr, pc
+ bxne r12
+
+ ldr r12, =HW_ITCM_END
+ stmfd r12!, {r0-r3, sp, lr}
+
+ and r0, sp, #1
+ mov sp, r12
+
+ mrs r1, cpsr
+ and r1, r1, #0x1f
+
+ teq r1, #0x17
+ bne _020CCA38
+ bl OSi_GetAndDisplayContext
+ b _020CCA44
+
+_020CCA38:
+ teq r1, #0x1b
+ bne _020CCA44
+ bl OSi_GetAndDisplayContext
+
+_020CCA44:
+ ldr r12, =OSi_DebuggerHandler
+ ldr r12, [r12]
+ cmp r12, #0
+
+_020CCA50:
+ beq _020CCA50
+
+_020CCA54:
+ mov r0, r0
+ b _020CCA54
+
+ ldmfd sp!, {r0-r3, r12, lr}
+ mov sp, r12
+ bx lr
+}
+
+ARM_FUNC static asm void OSi_GetAndDisplayContext(void)
+{
+ stmfd sp!, {r0, lr}
+
+ bl OSi_SetExContext
+ bl OSi_DisplayExContext
+
+ ldmfd sp!, {r0, lr}
+ bx lr
+}
+
+ARM_FUNC static asm void OSi_SetExContext(void)
+{
+ ldr r1, =OSi_ExContext;
+
+ mrs r2, cpsr
+ str r2, [r1, #OSiExContext.debug[1]]
+
+ str r0, [r1, #OSiExContext.exinfo]
+
+ ldr r0, [r12, #0]
+ str r0, [r1, #4]
+ ldr r0, [r12, #4]
+ str r0, [r1, #8]
+ ldr r0, [r12, #8]
+ str r0, [r1, #12]
+ ldr r0, [r12, #12]
+ str r0, [r1, #16]
+ ldr r2, [r12, #16]
+ bic r2, r2, #1
+
+ add r0, r1, #20
+ stmia r0, {r4-r11}
+
+ str r12, [r1, #OSiExContext.debug[0]]
+
+ ldr r0, [r2, #0]
+ str r0, [r1, #OSiExContext.cp15]
+ ldr r3, [r2, #4]
+ str r3, [r1, #0]
+ ldr r0, [r2, #8]
+ str r0, [r1, #52]
+ ldr r0, [r2, #12]
+ str r0, [r1, #64]
+
+ mrs r0, cpsr
+ orr r3, r3, #0x80
+ bic r3, r3, #0x20
+ msr cpsr_cxsf, r3
+
+ str sp, [r1, #56]
+ str lr, [r1, #60]
+ mrs r2, spsr
+
+ str r2, [r1, #OSiExContext.debug[3]]
+
+ msr cpsr_cxsf, r0
+ bx lr
+}
+
+ARM_FUNC static void OSi_DisplayExContext(void)
+{
+ if (OSi_UserExceptionHandler)
+ {
+ asm
+ {
+ mov r0, sp
+ ldr r1, =0x9f
+ msr CPSR_cxsf, r1
+ mov sp, r0
+ }
+
+ OS_EnableProtectionUnit();
+
+ ((void (*)(u32, void *))OSi_UserExceptionHandler)((u32)&OSi_ExContext, OSi_UserExceptionHandlerArg);
+
+ OS_DisableProtectionUnit();
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/OS_init.c b/arm9/lib/NitroSDK/src/OS_init.c
new file mode 100644
index 00000000..d1465625
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_init.c
@@ -0,0 +1,26 @@
+#include "function_target.h"
+#include "OS_init.h"
+#include "MI_init.h"
+#include "PXI_init.h"
+#include "CARD_rom.h"
+
+extern void CTRDG_Init(void);
+extern void PM_Init(void);
+
+ARM_FUNC void OS_Init(void) {
+ OS_InitArena();
+ PXI_Init();
+ OS_InitLock();
+ OS_InitArenaEx();
+ OS_InitIrqTable();
+ OS_SetIrqStackChecker();
+ OS_InitException();
+ MI_Init();
+ OS_InitVAlarm();
+ OSi_InitVramExclusive();
+ OS_InitThread();
+ OS_InitReset();
+ CTRDG_Init();
+ CARD_Init();
+ PM_Init();
+}
diff --git a/arm9/lib/NitroSDK/src/OS_interrupt.c b/arm9/lib/NitroSDK/src/OS_interrupt.c
new file mode 100644
index 00000000..699c7929
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_interrupt.c
@@ -0,0 +1,141 @@
+#include "OS_interrupt.h"
+
+#include "global.h"
+#include "registers.h"
+#include "mmap.h"
+#include "OS_thread.h"
+
+#pragma optimize_for_size on
+
+extern OSThreadQueue OSi_IrqThreadQueue;
+
+ARM_FUNC void OS_InitIrqTable(void) {
+ OS_InitThreadQueue(&OSi_IrqThreadQueue);
+}
+
+ARM_FUNC void OS_SetIrqFunction(OSIrqMask intrBit, OSIrqFunction function) {
+ s32 i;
+ OSIrqCallbackInfo *info;
+
+ for (i = 0; i < 0x16; i++) {
+ if (intrBit & 1) {
+ info = NULL;
+
+ if (8 <= i && i <= 11) {
+ info = &OSi_IrqCallbackInfo[i - 8];
+ }
+ else if (3 <= i && i <= 6) {
+ info = &OSi_IrqCallbackInfo[i - 3 + 4];
+ }
+ else {
+ OS_IRQTable[i] = function;
+ }
+
+ if (info) {
+ info->func = (void (*)(void *))function;
+ info->arg = 0;
+ info->enable = TRUE;
+ }
+ }
+ intrBit >>= 1;
+ }
+}
+
+ARM_FUNC OSIrqFunction OS_GetIrqFunction(OSIrqMask intrBit) {
+ s32 i = 0;
+ OSIrqFunction *funcPtr = &OS_IRQTable[0];
+
+ do {
+ if (intrBit & 1)
+ {
+ if (8 <= i && i <= 11) {
+ i = i - 8;
+ return (void (*)(void))OSi_IrqCallbackInfo[i].func;
+ }
+ else if (3 <= i && i <= 6) {
+ i++;
+ return (void (*)(void))OSi_IrqCallbackInfo[i].func;
+ }
+
+ return *funcPtr;
+ }
+ intrBit >>= 1;
+ funcPtr++;
+ i++;
+ } while (i < 0x16);
+ return 0;
+}
+
+ARM_FUNC void OSi_EnterDmaCallback(u32 dmaNo, void (*callback) (void *), void *arg)
+{
+ OSIrqMask mask = 1UL << (dmaNo + 8);
+ OSi_IrqCallbackInfo[dmaNo].func = callback;
+ OSi_IrqCallbackInfo[dmaNo].arg = arg;
+
+ OSi_IrqCallbackInfo[dmaNo].enable = OS_EnableIrqMask(mask) & mask;
+}
+
+ARM_FUNC void OSi_EnterTimerCallback(u32 timerNo, void (*callback) (void *), void *arg)
+{
+ OSIrqMask mask = 1UL << (timerNo + 3);
+ OSi_IrqCallbackInfo[timerNo + 4].func = callback;
+ OSi_IrqCallbackInfo[timerNo + 4].arg = arg;
+
+ (void)OS_EnableIrqMask(mask);
+ OSi_IrqCallbackInfo[timerNo + 4].enable = TRUE;
+}
+
+ARM_FUNC OSIrqMask OS_SetIrqMask(OSIrqMask mask)
+{
+ u16 regIme = reg_OS_IME;
+ reg_OS_IME = 0;
+ OSIrqMask regIe = reg_OS_IE;
+ reg_OS_IE = mask;
+ u16 unused = reg_OS_IME; //needed because otherwise it doesn't match
+ reg_OS_IME = regIme;
+ return regIe;
+}
+
+ARM_FUNC OSIrqMask OS_EnableIrqMask(OSIrqMask mask)
+{
+ u16 regIme = reg_OS_IME;
+ reg_OS_IME = 0;
+ OSIrqMask regIe = reg_OS_IE;
+ reg_OS_IE = regIe | mask;
+ u16 unused = reg_OS_IME;
+ reg_OS_IME = regIme;
+ return regIe;
+}
+
+ARM_FUNC OSIrqMask OS_DisableIrqMask(OSIrqMask mask)
+{
+ u16 regIme = reg_OS_IME;
+ reg_OS_IME = 0;
+ OSIrqMask regIe = reg_OS_IE;
+ reg_OS_IE = regIe & ~mask;
+ u16 unused = reg_OS_IME;
+ reg_OS_IME = regIme;
+ return regIe;
+}
+
+ARM_FUNC OSIrqMask OS_ResetRequestIrqMask(OSIrqMask mask)
+{
+ u16 regIme = reg_OS_IME;
+ reg_OS_IME = 0;
+ OSIrqMask regIf = reg_OS_IF;
+ reg_OS_IF = mask;
+ u16 unused = reg_OS_IME;
+ reg_OS_IME = regIme;
+ return regIf;
+}
+
+extern void SDK_IRQ_STACKSIZE(void);
+
+#define OSi_IRQ_STACK_TOP (HW_DTCM_SVC_STACK - ((s32)SDK_IRQ_STACKSIZE))
+#define OSi_IRQ_STACK_BOTTOM HW_DTCM_SVC_STACK
+
+ARM_FUNC void OS_SetIrqStackChecker(void)
+{
+ *(u32 *)(OSi_IRQ_STACK_BOTTOM - sizeof(u32)) = 0xfddb597dUL;
+ *(u32 *)(OSi_IRQ_STACK_TOP) = 0x7bf9dd5bUL;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_irqHandler.c b/arm9/lib/NitroSDK/src/OS_irqHandler.c
new file mode 100644
index 00000000..b4e2d232
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_irqHandler.c
@@ -0,0 +1,143 @@
+#include "function_target.h"
+#include "OS_irqHandler.h"
+#include "OS_system.h"
+#include "OS_thread.h"
+#include "sections.h"
+#include "CP_context.h"
+
+OSThreadQueue OSi_IrqThreadQueue = { NULL, NULL };
+
+#pragma section ITCM begin
+ARM_FUNC asm void OS_IrqHandler(void)
+{
+ stmfd sp!, {lr}
+ mov ip, #0x04000000
+ add ip, ip, #0x210
+ ldr r1, [ip, #-8]
+ cmp r1, #0
+ ldmeqfd sp!, {pc}
+ ldmia ip, {r1, r2}
+ ands r1, r1, r2
+ ldmeqfd sp!, {pc}
+ mov r3, #0x80000000
+_01FF8028:
+ clz r0, r1
+ bics r1, r1, r3, lsr r0
+ bne _01FF8028
+ mov r1, r3, lsr r0
+ str r1, [ip, #0x4]
+ rsbs r0, r0, #0x1f
+ ldr r1, =OS_IRQTable
+ ldr r0, [r1, r0, lsl #2]
+ ldr lr, =OS_IrqHandler_ThreadSwitch
+ bx r0
+}
+
+ARM_FUNC asm void OS_IrqHandler_ThreadSwitch(void)
+{
+ ldr ip, =OSi_IrqThreadQueue
+ mov r3, #0x0
+ ldr ip, [ip]
+ mov r2, #0x1
+ cmp ip, #0x0
+ beq _01FF80A8
+_01FF8070:
+ str r2, [ip, #0x64]
+ str r3, [ip, #0x78]
+ str r3, [ip, #0x7c]
+ ldr r0, [ip, #0x80]
+ str r3, [ip, #0x80]
+ mov ip, r0
+ cmp ip, #0x0
+ bne _01FF8070
+ ldr ip, =OSi_IrqThreadQueue
+ str r3, [ip]
+ str r3, [ip, #0x4]
+ ldr ip, =OSi_ThreadInfo
+ mov r1, #0x1
+ strh r1, [ip]
+_01FF80A8:
+ ldr ip, =OSi_ThreadInfo
+ ldrh r1, [ip]
+ cmp r1, #0x0
+ ldreq pc, [sp], #0x4
+ mov r1, #0x0
+ strh r1, [ip]
+ mov r3, #0xd2
+ msr CPSR_c, r3
+ add r2, ip, #0x8
+ ldr r1, [r2]
+_01FF80D0:
+ cmp r1, #0x0
+ ldrneh r0, [r1, #0x64]
+ cmpne r0, #0x1
+ ldrne r1, [r1, #0x68]
+ bne _01FF80D0
+ cmp r1, #0x0
+ bne _01FF80F8
+_01FF80EC:
+ mov r3, #0x92
+ msr CPSR_c, r3
+ ldr pc, [sp], #0x4
+_01FF80F8:
+ ldr r0, [ip, #0x4]
+ cmp r1, r0
+ beq _01FF80EC
+ ldr r3, [ip, #0xC]
+ cmp r3, #0x0
+ beq _01FF8120
+ stmdb sp!, {r0, r1, ip}
+ mov lr, pc
+ bx r3
+ ldmia sp!, {r0, r1, ip}
+_01FF8120:
+ str r1, [ip, #0x4]
+ mrs r2, SPSR
+ str r2, [r0, #0x0]!
+ stmdb sp!, {r0, r1}
+ add r0, r0, #0x0
+ add r0, r0, #0x48
+ ldr r1, =CP_SaveContext
+ blx r1
+ ldmia sp!, {r0, r1}
+ ldmib sp!, {r2, r3}
+ stmib r0!, {r2, r3}
+ ldmib sp!, {r2, r3, ip, lr}
+ stmib r0!, {r2-r14}^
+ stmib r0!, {lr}
+ mov r3, #0xd3
+ msr CPSR_c, r3
+ stmib r0!, {sp}
+ stmfd sp!, {r1}
+ add r0, r1, #0x0
+ add r0, r0, #0x48
+ ldr r1, =CPi_RestoreContext
+ blx r1
+ ldmfd sp!, {r1}
+ ldr sp, [r1, #0x44]
+ mov r3, #0xd2
+ msr CPSR_c, r3
+ ldr r2, [r1, #0x0]!
+ msr SPSR_fc, r2
+ ldr lr, [r1, #0x40]
+ ldmib r1!, {r0-r14}^
+ nop
+ stmda sp!, {r0, r1, r2, r3, ip, lr}
+ ldmfd sp!, {pc}
+}
+#pragma section ITCM end
+
+ARM_FUNC void OS_WaitIrq(BOOL clear, OSIrqMask irqFlags)
+{
+ OSIntrMode lastIntrMode = OS_DisableInterrupts();
+ if (clear)
+ {
+ OS_ClearIrqCheckFlag(irqFlags);
+ }
+ (void)OS_RestoreInterrupts(lastIntrMode);
+
+ while (!(OS_GetIrqCheckFlag() & irqFlags))
+ {
+ OS_SleepThread(&OSi_IrqThreadQueue);
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/OS_irqTable.c b/arm9/lib/NitroSDK/src/OS_irqTable.c
new file mode 100644
index 00000000..cc2a3a55
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_irqTable.c
@@ -0,0 +1,110 @@
+#include "function_target.h"
+#include "sections.h"
+#include "OS_irqTable.h"
+
+#pragma section DTCM begin
+OSIrqFunction OS_IRQTable[22] = {
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OSi_IrqTimer0,
+ OSi_IrqTimer1,
+ OSi_IrqTimer2,
+ OSi_IrqTimer3,
+ OS_IrqDummy,
+ OSi_IrqDma0,
+ OSi_IrqDma1,
+ OSi_IrqDma2,
+ OSi_IrqDma3,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy,
+ OS_IrqDummy
+};
+#pragma section DTCM end
+
+OSIrqCallbackInfo OSi_IrqCallbackInfo[8] = {
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+ {NULL, 0, 0},
+};
+
+static u16 OSi_IrqCallbackInfoIndex[8] = {
+ 8, 9, 10, 11, 3, 4, 5, 6
+};
+
+ARM_FUNC void OS_IrqDummy(void)
+{
+ //noop
+}
+
+ARM_FUNC void OSi_IrqCallback(s32 index)
+{
+ OSIrqMask mask = (1UL << OSi_IrqCallbackInfoIndex[index]);
+ void (*callback)(void *) = OSi_IrqCallbackInfo[index].func;
+
+ OSi_IrqCallbackInfo[index].func = NULL;
+
+ if (callback)
+ {
+ (callback)(OSi_IrqCallbackInfo[index].arg);
+ }
+
+ OS_SetIrqCheckFlag(mask);
+
+ if (!OSi_IrqCallbackInfo[index].enable)
+ {
+ (void)OS_DisableIrqMask(mask);
+ }
+}
+
+ARM_FUNC void OSi_IrqDma0(void)
+{
+ OSi_IrqCallback(0);
+}
+
+ARM_FUNC void OSi_IrqDma1(void)
+{
+ OSi_IrqCallback(1);
+}
+
+ARM_FUNC void OSi_IrqDma2(void)
+{
+ OSi_IrqCallback(2);
+}
+
+ARM_FUNC void OSi_IrqDma3(void)
+{
+ OSi_IrqCallback(3);
+}
+
+ARM_FUNC void OSi_IrqTimer0(void)
+{
+ OSi_IrqCallback(4);
+}
+
+ARM_FUNC void OSi_IrqTimer1(void)
+{
+ OSi_IrqCallback(5);
+}
+
+ARM_FUNC void OSi_IrqTimer2(void)
+{
+ OSi_IrqCallback(6);
+}
+
+ARM_FUNC void OSi_IrqTimer3(void)
+{
+ OSi_IrqCallback(7);
+}
diff --git a/arm9/lib/NitroSDK/src/OS_message.c b/arm9/lib/NitroSDK/src/OS_message.c
new file mode 100644
index 00000000..3b5c33b0
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_message.c
@@ -0,0 +1,124 @@
+#include "OS_message.h"
+#include "function_target.h"
+#include "OS_system.h"
+#include "OS_thread.h"
+
+ARM_FUNC void OS_InitMessageQueue(OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount)
+{
+ OS_InitThreadQueue(&mq->queueSend);
+ OS_InitThreadQueue(&mq->queueReceive);
+ mq->msgArray = msgArray;
+ mq->msgCount = msgCount;
+ mq->firstIndex = 0;
+ mq->usedCount = 0;
+}
+
+ARM_FUNC BOOL OS_SendMessage(OSMessageQueue *mq, OSMessage msg, s32 flags)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ while (mq->msgCount <= mq->usedCount)
+ {
+ if (!(flags & OS_MESSAGE_BLOCK))
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return FALSE;
+ }
+ else
+ {
+ OS_SleepThread(&mq->queueSend);
+ }
+ }
+
+ s32 lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount;
+ mq->msgArray[lastIndex] = msg;
+ mq->usedCount++;
+
+ OS_WakeupThread(&mq->queueReceive);
+
+ (void)OS_RestoreInterrupts(enabled);
+ return TRUE;
+}
+
+ARM_FUNC BOOL OS_ReceiveMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ while (mq->usedCount == 0)
+ {
+ if (!(flags & OS_MESSAGE_BLOCK))
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return FALSE;
+ }
+ else
+ {
+ OS_SleepThread(&mq->queueReceive);
+ }
+ }
+
+ if (msg != NULL)
+ {
+ *msg = mq->msgArray[mq->firstIndex];
+ }
+ mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount;
+ mq->usedCount--;
+
+ OS_WakeupThread(&mq->queueSend);
+
+ (void)OS_RestoreInterrupts(enabled);
+ return TRUE;
+}
+
+ARM_FUNC BOOL OS_JamMessage(OSMessageQueue *mq, OSMessage msg, s32 flags)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ while (mq->msgCount <= mq->usedCount)
+ {
+ if (!(flags & OS_MESSAGE_BLOCK))
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return FALSE;
+ }
+ else
+ {
+ OS_SleepThread(&mq->queueSend);
+ }
+ }
+
+ mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount;
+ mq->msgArray[mq->firstIndex] = msg;
+ mq->usedCount++;
+
+ OS_WakeupThread(&mq->queueReceive);
+
+ (void)OS_RestoreInterrupts(enabled);
+ return TRUE;
+}
+
+ARM_FUNC BOOL OS_ReadMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ while (mq->usedCount == 0)
+ {
+ if (!(flags & OS_MESSAGE_BLOCK))
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return FALSE;
+ }
+ else
+ {
+ OS_SleepThread(&mq->queueReceive);
+ }
+ }
+
+ if (msg != NULL)
+ {
+ *msg = mq->msgArray[mq->firstIndex];
+ }
+
+ (void)OS_RestoreInterrupts(enabled);
+ return TRUE;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_mutex.c b/arm9/lib/NitroSDK/src/OS_mutex.c
new file mode 100644
index 00000000..5eb999a9
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_mutex.c
@@ -0,0 +1,142 @@
+#include "nitro/types.h"
+#include "function_target.h"
+#include "OS_mutex.h"
+#include "OS_system.h"
+
+ARM_FUNC void OS_InitMutex(OSMutex *mutex)
+{
+ OS_InitThreadQueue(&mutex->queue);
+ mutex->thread = NULL;
+ mutex->count = 0;
+}
+
+ARM_FUNC void OS_LockMutex(OSMutex *mutex)
+{
+ OSIntrMode prevIntrMode = OS_DisableInterrupts();
+ OSThread *currentThread = OS_GetCurrentThread();
+
+ OSThread *ownerThread;
+ for (;;)
+ {
+ ownerThread = ((volatile OSMutex *)mutex)->thread;
+
+ if (ownerThread == NULL)
+ {
+ mutex->thread = currentThread;
+ mutex->count++;
+ OSi_EnqueueTail(currentThread, mutex);
+ break;
+ }
+ else if (ownerThread == currentThread)
+ {
+ mutex->count++;
+ break;
+ }
+ else
+ {
+ currentThread->mutex = mutex;
+ OS_SleepThread(&mutex->queue);
+ currentThread->mutex = NULL;
+ }
+ }
+
+ (void)OS_RestoreInterrupts(prevIntrMode);
+}
+
+ARM_FUNC void OS_UnlockMutex(OSMutex *mutex)
+{
+ OSIntrMode prevIntrMode = OS_DisableInterrupts();
+ OSThread *currentThread = OS_GetCurrentThread();
+
+ if (mutex->thread == currentThread && --mutex->count == 0)
+ {
+ OSi_DequeueItem(currentThread, mutex);
+ mutex->thread = NULL;
+
+ OS_WakeupThread(&mutex->queue);
+ }
+
+ (void)OS_RestoreInterrupts(prevIntrMode);
+}
+
+ARM_FUNC void OSi_UnlockAllMutex(OSThread *thread)
+{
+ OSMutex *mutex;
+ while (thread->mutexQueue.head)
+ {
+ mutex = OSi_RemoveMutexLinkFromQueue(&thread->mutexQueue);
+
+ mutex->count = 0;
+ mutex->thread = NULL;
+ OS_WakeupThread(&mutex->queue);
+ }
+}
+
+ARM_FUNC BOOL OS_TryLockMutex(OSMutex *mutex)
+{
+ OSIntrMode prevIntrMode = OS_DisableInterrupts();
+ OSThread *currentThread = OS_GetCurrentThread();
+ BOOL locked;
+
+ if (mutex->thread == NULL)
+ {
+ mutex->thread = currentThread;
+ mutex->count++;
+ OSi_EnqueueTail(currentThread, mutex);
+ locked = TRUE;
+ }
+ else if (mutex->thread == currentThread)
+ {
+ mutex->count++;
+ locked = TRUE;
+ }
+ else
+ {
+ locked = FALSE;
+ }
+
+ (void)OS_RestoreInterrupts(prevIntrMode);
+ return locked;
+}
+
+ARM_FUNC void OSi_EnqueueTail(OSThread *thread, OSMutex *mutex)
+{
+ OSMutex *prev = thread->mutexQueue.tail;
+
+ if (!prev)
+ {
+ thread->mutexQueue.head = mutex;
+ }
+ else
+ {
+ prev->link.next = mutex;
+ }
+
+ mutex->link.prev = prev;
+ mutex->link.next = NULL;
+ thread->mutexQueue.tail = mutex;
+}
+
+ARM_FUNC void OSi_DequeueItem(OSThread *thread, OSMutex *mutex)
+{
+ OSMutex *next = mutex->link.next;
+ OSMutex *prev = mutex->link.prev;
+
+ if (!next)
+ {
+ thread->mutexQueue.tail = prev;
+ }
+ else
+ {
+ next->link.prev = prev;
+ }
+
+ if(!prev)
+ {
+ thread->mutexQueue.head = next;
+ }
+ else
+ {
+ prev->link.next = next;
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/OS_ownerInfo.c b/arm9/lib/NitroSDK/src/OS_ownerInfo.c
new file mode 100644
index 00000000..6693f73f
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_ownerInfo.c
@@ -0,0 +1,29 @@
+#include "OS_ownerInfo.h"
+
+#include "global.h"
+#include "systemWork.h"
+#include "MI_memory.h"
+
+ARM_FUNC void OS_GetMacAddress(u8 *macAddress)
+{
+ MI_CpuCopy8((void *)0x027FFCF4, macAddress, 0x6);
+}
+
+ARM_FUNC void OS_GetOwnerInfo(OSOwnerInfo* info)
+{
+ NVRAMConfig *src = (NVRAMConfig *)OS_GetSystemWork()->nvramUserInfo;
+ info->language = (u8)src->ncd.option.language;
+ info->favoriteColour = (u8)src->ncd.owner.favouriteColour;
+ info->birthday.month = (u8)src->ncd.owner.birthday.month;
+ info->birthday.day = (u8)src->ncd.owner.birthday.day;
+ info->nickNameLength = (u16)src->ncd.owner.nickname.length;
+ info->commentLength = (u16)src->ncd.owner.comment.length;
+ MIi_CpuCopy16(src->ncd.owner.nickname.str, info->nickName, 10 * sizeof(u16));
+ MIi_CpuCopy16(src->ncd.owner.comment.str, info->comment, 26 * sizeof(u16));
+}
+
+ARM_FUNC s64 OS_GetOwnerRtcOffset(void)
+{
+ NVRAMConfig *src = (NVRAMConfig *)OS_GetSystemWork()->nvramUserInfo;
+ return src->ncd.option.rtcOffset;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_printf.c b/arm9/lib/NitroSDK/src/OS_printf.c
new file mode 100644
index 00000000..414f0db9
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_printf.c
@@ -0,0 +1,492 @@
+#include "global.h"
+#include "OS_printf.h"
+
+typedef struct printfStr
+{
+ s32 spaceLeft;
+ s8 *stringEnd;
+ s8 *stringStart;
+} printfStr;
+
+void string_put_char(struct printfStr *dest, s8 value);
+void string_fill_char(struct printfStr *dest, s8 value, s32 count);
+void string_put_string(struct printfStr *dest, const s8 *src, s32 count);
+
+ARM_FUNC void string_put_char(struct printfStr *dest, s8 value)
+{
+ if (dest->spaceLeft != 0)
+ {
+ dest->stringEnd[0] = value;
+ dest->spaceLeft--;
+ }
+ dest->stringEnd++;
+}
+
+ARM_FUNC void string_fill_char(struct printfStr *dest, s8 value, s32 count)
+{
+ if (count <= 0)
+ return;
+
+ u32 written = 0;
+ u32 spaceLeft = (u32)dest->spaceLeft;
+ u32 toWrite = spaceLeft > (u32)count ? count : spaceLeft;
+
+ while (written < toWrite)
+ {
+ dest->stringEnd[written] = value;
+ written++;
+ }
+
+ dest->spaceLeft -= toWrite;
+ dest->stringEnd += count; // this is wrong but matching...
+}
+
+ARM_FUNC void string_put_string(struct printfStr *dest, const s8 *src, s32 count)
+{
+ if (count <= 0)
+ return;
+
+ u32 written = 0;
+ u32 spaceLeft = (u32)dest->spaceLeft;
+ u32 toWrite = spaceLeft > (u32)count ? count : spaceLeft;
+
+ while (written < toWrite)
+ {
+ dest->stringEnd[written] = src[written];
+ written++;
+ }
+
+ dest->spaceLeft -= toWrite;
+ dest->stringEnd += count; // this is wrong but matching...
+}
+
+ARM_FUNC s32 OS_SPrintf(s8 *buffer, const s8 *format, ...)
+{
+ void *args = (void *)((u32 *)((u32)&format & ~0x3) + 1); // hack since mwccarm doesn't have <stdarg.h> apparently
+ return OS_VSPrintf(buffer, format, args);
+}
+
+ARM_FUNC s32 OS_VSPrintf(s8 *buffer, const s8 *format, void *args)
+{
+ return OS_VSNPrintf(buffer, 0x7FFFFFFF, format, args);
+}
+
+ARM_FUNC s32 OS_SNPrintf(s8 *buffer, s32 bufsz, const s8 *format, ...)
+{
+ void *args = (void *)((u32 *)((u32)&format & ~0x3) + 1); // hack since mwccarm doesn't have <stdarg.h> apparently
+ return OS_VSNPrintf(buffer, bufsz, format, args);
+}
+
+#define va_arg(list, ty) *(ty *)((u32 *)(list = (void *)((u32 *)(list) + 1)) - 1)
+#define va_arg_64(list, sgn) *((sgn##64 *)(list = (void *)((sgn##64 *)(list) + 1)) - 1)
+
+ARM_FUNC s32 OS_VSNPrintf(s8 *buffer, s32 bufsz, const s8 *format, void *args)
+{
+ s8 buf[24];
+ s32 n_buf;
+ s8 prefix[2];
+ s32 n_prefix;
+
+ const s8 *s = format;
+
+ printfStr str;
+ str.spaceLeft = bufsz;
+ str.stringStart = buffer;
+ str.stringEnd = buffer;
+
+ while (*s)
+ {
+ // matches:
+ // binary range (hex range) [dec range]
+ // 1000 0001-1001 1111 (0x81-0x9F) [129-159]
+ // 1110 0000-1111 1100 (0xE0-0xFC) [224-252]
+ if ((u32)(((u8)*s ^ 0x20) - 0xa1) < 0x3c)
+ {
+ string_put_char(&str, *s++);
+ if (*s)
+ {
+ string_put_char(&str, *s++);
+ }
+ }
+ else if (*s != '%')
+ {
+ string_put_char(&str, *s++);
+ }
+ else
+ {
+ enum {
+ blank = 000001,
+ plus = 000002,
+ sharp = 000004,
+ minus = 000010,
+ zero = 000020,
+ l1 = 000040,
+ h1 = 000100,
+ l2 = 000200,
+ h2 = 000400,
+ usigned = 010000,
+ end
+ };
+ s32 flag = 0, width = 0, precision = -1, radix = 10;
+ s8 hex = 'a' - 10;
+ const s8 *p_start = s;
+ for (;;)
+ {
+ switch (*++s)
+ {
+ case '+':
+ if (s[-1] != ' ')
+ break;
+ flag |= plus;
+ continue;
+ case ' ':
+ flag |= blank;
+ continue;
+ case '-':
+ flag |= minus;
+ continue;
+ case '0':
+ flag |= zero;
+ continue;
+ }
+ break;
+ }
+ if (*s == '*')
+ {
+ ++s, width = va_arg(args, s32);
+ if (width < 0)
+ {
+ width = -width, flag |= minus;
+ }
+ }
+ else
+ {
+ while ((*s >= '0') && (*s <= '9'))
+ {
+ width = (width * 10) + *s++ - '0';
+ }
+ }
+
+ if (*s == '.')
+ {
+ ++s, precision = 0;
+ if (*s == '*')
+ {
+ ++s, precision = va_arg(args, s32);
+ if (precision < 0)
+ {
+ precision = -1;
+ }
+ }
+ else
+ {
+ while ((*s >= '0') && (*s <= '9'))
+ {
+ precision = (precision * 10) + *s++ - '0';
+ }
+ }
+ }
+
+ switch (*s)
+ {
+ case 'h':
+ if (*++s != 'h') {
+ flag |= h1;
+ }
+ else {
+ ++s, flag |= h2;
+ }
+ break;
+ case 'l':
+ if (*++s != 'l') {
+ flag |= l1;
+ }
+ else {
+ ++s, flag |= l2;
+ }
+ break;
+ }
+
+ switch (*s)
+ {
+ case 'd':
+ case 'i':
+ goto put_int;
+ case 'o':
+ radix = 8;
+ flag |= usigned;
+ goto put_int;
+ case 'u':
+ flag |= usigned;
+ goto put_int;
+ case 'X':
+ hex = 'A' - 10;
+ goto put_hex;
+ case 'x':
+ goto put_hex;
+ case 'p':
+ flag |= sharp;
+ precision = 8;
+ goto put_hex;
+ case 'c':
+ if (precision >= 0)
+ goto put_invalid;
+ {
+ s32 v = va_arg(args, s32);
+ width -= 1;
+ if (flag & minus)
+ {
+ string_put_char(&str, (s8)v);
+ string_fill_char(&str, ' ', width);
+ }
+ else
+ {
+ s8 pad = (s8)((flag & zero) ? '0' : ' ');
+ string_fill_char(&str, pad, width);
+ string_put_char(&str, (s8)v);
+ }
+ ++s;
+ }
+ break;
+ case 's':
+ {
+ s32 n_bufs = 0;
+ const s8 *p_bufs = va_arg(args, const s8 *);
+ if (precision < 0)
+ {
+ while (p_bufs[n_bufs])
+ {
+ ++n_bufs;
+ }
+ }
+ else
+ {
+ while (n_bufs < precision && p_bufs[n_bufs])
+ {
+ ++n_bufs;
+ }
+ }
+ width -= n_bufs;
+ if (flag & minus)
+ {
+ string_put_string(&str, p_bufs, n_bufs);
+ string_fill_char(&str, ' ', width);
+ }
+ else
+ {
+ s8 pad = (s8)((flag & zero) ? '0' : ' ');
+ string_fill_char(&str, pad, width);
+ string_put_string(&str, p_bufs, n_bufs);
+ }
+ ++s;
+ }
+ break;
+ case 'n':
+ {
+ s32 count = str.stringEnd - str.stringStart;
+ if (!(flag & h2))
+ {
+ if (flag & h1)
+ {
+ *va_arg(args, s16 *) = (s16)count;
+ }
+ else if (flag & l2)
+ {
+ *va_arg(args, u64 *) = (u64)count;
+ }
+ else
+ {
+ *va_arg(args, s32 *) = count;
+ }
+ }
+ }
+ ++s;
+ break;
+ case '%':
+ if (p_start + 1 != s)
+ goto put_invalid;
+ string_put_char(&str, *s++);
+ break;
+
+ default:
+ goto put_invalid;
+
+ put_invalid:
+ string_put_string(&str, p_start, s - p_start);
+ break;
+
+ put_hex:
+ radix = 16;
+ flag |= usigned;
+ put_int:
+ {
+ u64 value = 0;
+ n_prefix = 0;
+ if (flag & minus)
+ {
+ flag &= ~zero;
+ }
+ if (precision < 0)
+ {
+ precision = 1;
+ }
+ else
+ {
+ flag &= ~zero;
+ }
+ if (flag & usigned)
+ {
+ if (flag & h2)
+ {
+ value = va_arg(args, u8);
+ }
+ else if (flag & h1)
+ {
+ value = va_arg(args, u16);
+ }
+ else if (flag & l2)
+ {
+ value = va_arg_64(args, u);
+ }
+ else
+ {
+ value = va_arg(args, u32);
+ }
+ flag &= ~(plus | blank);
+ if (flag & sharp)
+ {
+ if (radix == 16)
+ {
+ if (value != 0)
+ {
+ prefix[0] = (s8)(hex + (10 + 'x' - 'a'));
+ prefix[1] = '0';
+ n_prefix = 2;
+ }
+ }
+ else if (radix == 8)
+ {
+ prefix[0] = '0';
+ n_prefix = 1;
+ }
+ }
+ }
+ else {
+ if (flag & h2) {
+ value = va_arg(args, s8);
+ } else if (flag & h1) {
+ value = va_arg(args, s16);
+ } else if (flag & l2) {
+ value = va_arg_64(args, u);
+ } else {
+ value = va_arg(args, s32);
+ }
+
+ if ((value >> 32) & 0x80000000) {
+ value = ~value + 1;
+ prefix[0] = '-';
+ n_prefix = 1;
+ } else {
+ if (value || precision) {
+ if (flag & plus) {
+ prefix[0] = '+';
+ n_prefix = 1;
+ } else if (flag & blank) {
+ prefix[0] = ' ';
+ n_prefix = 1;
+ }
+ }
+ }
+ }
+ n_buf = 0;
+ switch (radix) {
+ case 8:
+ while (value != 0) {
+ s32 octDig = (s32) (value & 0x7);
+ value >>= 3;
+ buf[n_buf++] = (s8) (octDig + '0');
+ }
+ break;
+ case 10:
+ if ((value >> 32) == 0) {
+ u32 v = (u32) value;
+ while (v) {
+ u32 div10 = v / 10;
+ s32 dig = (s32) (v - (div10 * 10));
+ v = div10;
+ buf[n_buf++] = (s8) (dig + '0');
+ }
+ } else {
+ while (value) {
+ u64 div10 = value / 10;
+ s32 dig = (s32) (value - (div10 * 10));
+ value = div10;
+ buf[n_buf++] = (s8) (dig + '0');
+ }
+ }
+ break;
+ case 16:
+ while (value != 0) {
+ s32 hexDig = (s32) (value & 0xf);
+ value >>= 4;
+ buf[n_buf++] = (s8) ((hexDig < 10) ? (hexDig + '0') : (hexDig + hex));
+ }
+ break;
+ }
+ if (n_prefix > 0 && prefix[0] == '0') {
+ n_prefix = 0;
+ buf[n_buf++] = '0';
+ }
+ }
+ goto put_to_stream;
+
+ put_to_stream:
+ {
+ s32 n_pad = (s32)(precision - n_buf);
+ if (flag & zero)
+ {
+ if (n_pad < width - n_buf - n_prefix)
+ {
+ n_pad = (s32)(width - n_buf - n_prefix);
+ }
+ }
+ if (n_pad > 0)
+ {
+ width -= n_pad;
+ }
+
+ width -= n_prefix + n_buf;
+ if (!(flag & minus))
+ {
+ string_fill_char(&str, ' ', width);
+ }
+ while (n_prefix > 0)
+ {
+ string_put_char(&str, prefix[--n_prefix]);
+ }
+ string_fill_char(&str, '0', n_pad);
+ while (n_buf > 0)
+ {
+ string_put_char(&str, buf[--n_buf]);
+ }
+ if (flag & minus)
+ {
+ string_fill_char(&str, ' ', width);
+ }
+ ++s;
+ }
+ break;
+ }
+ }
+ }
+
+ if (str.spaceLeft != 0)
+ {
+ *str.stringEnd = '\0';
+ }
+ else if (bufsz != 0)
+ {
+ str.stringStart[bufsz - 1] = '\0';
+ }
+ return str.stringEnd - str.stringStart;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_protectionRegion.c b/arm9/lib/NitroSDK/src/OS_protectionRegion.c
new file mode 100644
index 00000000..4b8d8297
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_protectionRegion.c
@@ -0,0 +1,23 @@
+#include "function_target.h"
+#include "OS_protectionRegion.h"
+
+ARM_FUNC asm void OS_SetDPermissionsForProtectionRegion(register u32 setMask, register u32 flags)
+{
+ mrc p15, 0x0, r2, c5, c0, 0x2 //Extended Access Permission Data Protection Region
+ bic r2, r2, r0
+ orr r2, r2, r1
+ mcr p15, 0x0, r2, c5, c0, 0x2 //Extended Access Permission Data Protection Region
+ bx lr
+}
+
+ARM_FUNC asm void OS_SetProtectionRegion1(u32 param)
+{
+ mcr p15, 0x0, r0, c6, c1, 0x0 //Protection Unit Data Region 1
+ bx lr
+}
+
+ARM_FUNC asm void OS_SetProtectionRegion2(u32 param)
+{
+ mcr p15, 0x0, r0, c6, c2, 0x0 //Protection Unit Data Region 2
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/OS_protectionUnit.c b/arm9/lib/NitroSDK/src/OS_protectionUnit.c
new file mode 100644
index 00000000..66811a1e
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_protectionUnit.c
@@ -0,0 +1,18 @@
+#include "function_target.h"
+#include "OS_protectionUnit.h"
+
+ARM_FUNC asm void OS_EnableProtectionUnit(void)
+{
+ mrc p15, 0x0, r0, c1, c0, 0x0 //Control Register
+ orr r0, r0, #0x1
+ mcr p15, 0x0, r0, c1, c0, 0x0 //Control Register
+ bx lr
+}
+
+ARM_FUNC asm void OS_DisableProtectionUnit(void)
+{
+ mrc p15, 0x0, r0, c1, c0, 0x0 //Control Register
+ bic r0, r0, #0x1
+ mcr p15, 0x0, r0, c1, c0, 0x0 //Control Register
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/OS_reset.c b/arm9/lib/NitroSDK/src/OS_reset.c
new file mode 100644
index 00000000..083f2321
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_reset.c
@@ -0,0 +1,239 @@
+#include "OS_reset.h"
+
+#include "global.h"
+#include "MB_mb.h"
+#include "OS_terminate_proc.h"
+#include "OS_interrupt.h"
+#include "OS_system.h"
+#include "OS_spinLock.h"
+#include "OS_cache.h"
+#include "sections.h"
+#include "MI_dma.h"
+#include "CARD_common.h"
+#include "PXI_init.h"
+#include "PXI_fifo.h"
+
+static u16 OSi_IsInitReset = 0;
+vu16 OSi_IsResetOccurred = 0;
+
+static void OSi_CommonCallback(PXIFifoTag tag, u32 data, BOOL err);
+static void OSi_SendToPxi(u16 data);
+static void OSi_DoResetSystem(void);
+static void OSi_CpuClear32(register u32 data, register void *destp, register u32 size);
+static void OSi_ReloadRomData(void);
+static void OSi_ReadCardRom32(u32 src, void *dst, s32 len);
+
+ARM_FUNC void OS_InitReset(void) {
+ if (OSi_IsInitReset) {
+ return;
+ }
+ OSi_IsInitReset = TRUE;
+ PXI_Init();
+ while (!PXI_IsCallbackReady(PXI_FIFO_TAG_OS, PXI_PROC_ARM7)) { }
+
+ PXI_SetFifoRecvCallback(PXI_FIFO_TAG_OS, OSi_CommonCallback);
+}
+
+ARM_FUNC static void OSi_CommonCallback(PXIFifoTag tag, u32 data, BOOL err) {
+#pragma unused(tag, err) //needed because otherwise -W all errors
+ u16 command = (u16)((data & OS_PXI_COMMAND_MASK) >> OS_PXI_COMMAND_SHIFT);
+ if (command == OS_PXI_COMMAND_RESET)
+ {
+ OSi_IsResetOccurred = TRUE;
+ return;
+ }
+ OS_Terminate();
+}
+
+ARM_FUNC static void OSi_SendToPxi(u16 data) {
+ while (PXI_SendWordByFifo(PXI_FIFO_TAG_OS, (u32)data << 0x8, FALSE)) {}
+}
+
+ARM_FUNC void OS_ResetSystem(u32 parameter) {
+ if (MB_IsMultiBootChild()) {
+ OS_Terminate();
+ }
+ CARD_LockRom((u16)OS_GetLockID());
+ MI_StopDma(0);
+ MI_StopDma(1);
+ MI_StopDma(2);
+ MI_StopDma(3);
+ (void)OS_SetIrqMask(0x40000);
+ (void)OS_ResetRequestIrqMask((u32)~0);
+ *(u32 *)HW_RESET_PARAMETER_BUF = parameter;
+ OSi_SendToPxi(OS_PXI_COMMAND_RESET);
+ OSi_DoResetSystem();
+}
+
+#pragma section ITCM begin
+ARM_FUNC static void OSi_DoResetSystem(void)
+{
+ while (!OSi_IsResetOccurred) { }
+
+ reg_OS_IME = 0;
+ OSi_ReloadRomData();
+ OSi_DoBoot();
+}
+
+ARM_FUNC asm void OSi_DoBoot(void)
+{
+ mov ip, #0x04000000
+ str ip, [ip, #0x208]
+ ldr r1, =SDK_AUTOLOAD_DTCM_START
+ add r1, r1, #0x3fc0
+ add r1, r1, #0x3c
+ mov r0, #0x0
+ str r0, [r1]
+ ldr r1, =REG_SUBPINTF_ADDR
+_01FF81D4:
+ ldrh r0, [r1]
+ and r0, r0, #0xf
+ cmp r0, #0x1
+ bne _01FF81D4
+ mov r0, #0x100
+ strh r0, [r1]
+ mov r0, #0x0
+ ldr r3, =HW_EXCP_VECTOR_MAIN
+ ldr r4, [r3]
+ ldr r1, =HW_BIOS_EXCP_STACK_MAIN
+ mov r2, #0x80
+ bl OSi_CpuClear32
+ str r4, [r3]
+ ldr r1, =HW_PXI_SIGNAL_PARAM_ARM9
+ mov r2, #0x18
+ bl OSi_CpuClear32
+ ldr r1, =HW_WM_RSSI_POOL
+ strh r0, [r1]
+ ldr r1, =HW_COMPONENT_PARAM
+ mov r2, #0x64
+ bl OSi_CpuClear32
+ ldr r1, =REG_SUBPINTF_ADDR
+_01FF822C:
+ ldrh r0, [r1]
+ and r0, r0, #0xf
+ cmp r0, #0x1
+ beq _01FF822C
+ mov r0, #0x0
+ strh r0, [r1]
+ ldr r3, =HW_ROM_HEADER_BUF
+ ldr ip, [r3, #0x24]
+ mov lr, ip
+ ldr r11, =HW_PXI_SIGNAL_PARAM_ARM9
+ ldmia r11, {r0-r10}
+ mov r11, #0x0
+ bx ip
+}
+
+ARM_FUNC static asm void OSi_CpuClear32(register u32 data, register void *destp, register u32 size)
+{
+ add ip, r1, r2
+_01FF8284:
+ cmp r1, ip
+ stmltia r1!, {r0}
+ blt _01FF8284
+ bx lr
+}
+
+ARM_FUNC static void OSi_ReloadRomData(void)
+{
+ u32 header = (u32)HW_ROM_HEADER_BUF;
+ const u32 rom_base = *(u32 *)HW_ROM_BASE_OFFSET_BUF;
+
+ if (rom_base >= 0x8000)
+ {
+ OSi_ReadCardRom32(rom_base, (void *)header, 0x160);
+ }
+
+ u32 src_arm9 = *(u32 *)(header + 0x20);
+ u32 dst_arm9 = *(u32 *)(header + 0x28);
+ u32 len_arm9 = *(u32 *)(header + 0x2c);
+ u32 src_arm7 = *(u32 *)(header + 0x30);
+ u32 dst_arm7 = *(u32 *)(header + 0x38);
+ u32 len_arm7 = *(u32 *)(header + 0x3c);
+
+ OSIntrMode prevIntrMode = OS_DisableInterrupts();
+ DC_StoreAll();
+ DC_InvalidateAll();
+ (void)OS_RestoreInterrupts(prevIntrMode);
+
+ IC_InvalidateAll();
+ DC_WaitWriteBufferEmpty();
+
+ src_arm9 += rom_base;
+ src_arm7 += rom_base;
+
+ if (src_arm9 < 0x8000)
+ {
+ u32 diff = 0x8000 - src_arm9;
+ src_arm9 = 0x8000;
+ dst_arm9 += diff;
+ len_arm9 -= diff;
+ }
+ OSi_ReadCardRom32(src_arm9, (void *)dst_arm9, (s32)len_arm9);
+
+ OSi_ReadCardRom32(src_arm7, (void *)dst_arm7, (s32)len_arm7);
+}
+
+enum
+{
+ CARD_MASTER_SELECT_ROM = 0x0,
+ CARD_MASTER_ENABLE = 0x80,
+ CARD_CMD_READ_PAGE = 0xb7,
+ CARD_CTRL_CMD_MASK = 0x07000000,
+ CARD_CTRL_CMD_PAGE = 0x01000000,
+ CARD_CTRL_READ = 0x00000000,
+ CARD_CTRL_RESET_HI = 0x20000000,
+ CARD_CTRL_START = 0x80000000,
+ CARD_CTRL_READY = 0x00800000,
+ CARD_ENUM_END
+};
+
+ARM_FUNC static void OSi_ReadCardRom32(u32 src, void *dst, s32 len)
+{
+ vu32 *const hdr_GAME_BUF = (vu32 *)(HW_ROM_HEADER_BUF + 0x60);
+
+ const u32 ctrl_start = (u32)((*hdr_GAME_BUF &~CARD_CTRL_CMD_MASK)
+ | (CARD_CTRL_CMD_PAGE | CARD_CTRL_READ
+ | CARD_CTRL_START | CARD_CTRL_RESET_HI));
+
+ s32 pos = -(s32)(src & 511);
+
+ while (reg_CARD_CNT & CARD_CTRL_START) {}
+ reg_CARD_MASTERCNT = (u32)(CARD_MASTER_SELECT_ROM | CARD_MASTER_ENABLE);
+
+ for (src = (u32)(src + pos); pos < len; src += 512)
+ {
+ (&reg_CARD_CMD)[0] = (u8)(CARD_CMD_READ_PAGE);
+ (&reg_CARD_CMD)[1] = (u8)(src >> 24);
+ (&reg_CARD_CMD)[2] = (u8)(src >> 16);
+ (&reg_CARD_CMD)[3] = (u8)(src >> 8);
+ (&reg_CARD_CMD)[4] = (u8)(src >> 0);
+ (&reg_CARD_CMD)[5] = 0;
+ (&reg_CARD_CMD)[6] = 0;
+ (&reg_CARD_CMD)[7] = 0;
+
+ reg_CARD_CNT = ctrl_start;
+ for (;;)
+ {
+ u32 ctrl = reg_CARD_CNT;
+
+ if ((ctrl & CARD_CTRL_READY))
+ {
+ const u32 data = reg_CARD_DATA;
+
+ if ((pos >= 0) && (pos < len))
+ {
+ *(u32 *)((u32)dst + pos) = data;
+ }
+
+ pos += sizeof(u32);
+ }
+
+ if (!(ctrl & CARD_CTRL_START))
+ {
+ break;
+ }
+ }
+ }
+}
+#pragma section ITCM end
diff --git a/arm9/lib/NitroSDK/src/OS_spinLock.c b/arm9/lib/NitroSDK/src/OS_spinLock.c
new file mode 100644
index 00000000..576e03ad
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_spinLock.c
@@ -0,0 +1,218 @@
+//
+// Created by red031000 on 2020-05-21.
+//
+
+#include "OS_spinLock.h"
+
+#include "OS_system.h"
+#include "function_target.h"
+#include "mmap.h"
+#include "MI_exMemory.h"
+
+extern void MIi_CpuClear32(u32 param1, void * addr, u32 length); //not too sure about names
+extern u32 MI_SwapWord(u32 data, volatile u32* destp);
+
+ARM_FUNC void OS_InitLock(void)
+{
+ static BOOL isInitialized = FALSE;
+
+ if (isInitialized)
+ {
+ return;
+ }
+ isInitialized = TRUE;
+
+ OSLockWord* lockp = (OSLockWord *)HW_INIT_LOCK_BUF;
+
+ lockp->lockFlag = 0;
+
+ (void)OS_TryLockByWord(0x7e, lockp, NULL);
+
+ while (lockp->extension)
+ {
+ OSi_WaitByLoop();
+ }
+
+ ((u32 *)HW_LOCK_ID_FLAG_MAIN)[0] = 0xffffffff;
+ ((u32 *)HW_LOCK_ID_FLAG_MAIN)[1] = 0xffff0000;
+
+ MIi_CpuClear32(0x0, (void *)HW_SHARED_LOCK_BUF, 0x28);
+
+ MIi_SetCardProcessor(MI_PROCESSOR_ARM7);
+
+ MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM7);
+
+ (void)OS_UnlockByWord(0x7e, lockp, NULL);
+ (void)OS_TryLockByWord(0x7f, lockp, NULL);
+}
+
+ARM_FUNC s32 OSi_DoLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void),
+ BOOL disableFiq)
+{
+ s32 lastLockFlag;
+ while ((lastLockFlag = OSi_DoTryLockByWord(lockId, lockp, ctrlFuncp, disableFiq)) > 0) {
+ OSi_WaitByLoop();
+ }
+
+ return lastLockFlag;
+}
+
+ARM_FUNC s32 OS_TryLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void))
+{
+ return OSi_DoLockByWord(lockId, lockp, ctrlFuncp, FALSE);
+}
+
+ARM_FUNC s32 OSi_DoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
+ BOOL disableFIQ)
+{
+ if (lockID != lockp->ownerID)
+ {
+ return -2;
+ }
+
+ OSIntrMode lastIntrMode = (disableFIQ) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts();
+ lockp->ownerID = 0;
+ if (ctrlFuncp)
+ {
+ ctrlFuncp();
+ }
+ lockp->lockFlag = 0;
+ if (disableFIQ)
+ {
+ (void)OS_RestoreInterrupts_IrqAndFiq(lastIntrMode);
+ }
+ else
+ {
+ (void)OS_RestoreInterrupts(lastIntrMode);
+ }
+ return 0;
+}
+
+ARM_FUNC s32 OS_UnlockByWord(u16 lockID, OSLockWord* lockp, void (*ctrlFuncp) (void))
+{
+ return OSi_DoUnlockByWord(lockID, lockp, ctrlFuncp, FALSE);
+}
+
+ARM_FUNC s32 OSi_DoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
+ BOOL disableFiq)
+{
+ OSIntrMode lastIntrMode = (disableFiq) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts();
+
+ s32 lastLockFlag = (s32)MI_SwapWord(lockID, &lockp->lockFlag);
+
+ if (!lastLockFlag)
+ {
+ if (ctrlFuncp)
+ {
+ ctrlFuncp();
+ }
+ lockp->ownerID = lockID;
+ }
+
+ if (disableFiq)
+ {
+ (void)OS_RestoreInterrupts_IrqAndFiq(lastIntrMode);
+ }
+ else
+ {
+ (void)OS_RestoreInterrupts(lastIntrMode);
+ }
+
+ return lastLockFlag;
+}
+
+ARM_FUNC s32 OS_LockCartridge(u16 lockID)
+{
+ return OSi_DoLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, TRUE);
+}
+
+ARM_FUNC s32 OS_UnlockCartridge(u16 lockID)
+{
+ return OSi_DoUnlockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_FreeCartridgeBus, TRUE);
+}
+
+ARM_FUNC s32 OS_TryLockCartridge(u16 lockID)
+{
+ return OSi_DoTryLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, TRUE);
+}
+
+ARM_FUNC void OSi_AllocateCartridgeBus(void)
+{
+ MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM9);
+}
+
+ARM_FUNC void OSi_FreeCartridgeBus(void)
+{
+ MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM7);
+}
+
+ARM_FUNC s32 OS_TryLockCard(u16 lockID)
+{
+ return OS_TryLockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_AllocateCardBus);
+}
+
+ARM_FUNC s32 OS_UnlockCard(u16 lockID)
+{
+ return OS_UnlockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_FreeCardBus);
+}
+
+ARM_FUNC void OSi_AllocateCardBus(void)
+{
+ MIi_SetCardProcessor(MI_PROCESSOR_ARM9);
+}
+
+ARM_FUNC void OSi_FreeCardBus(void)
+{
+ MIi_SetCardProcessor(MI_PROCESSOR_ARM7);
+}
+
+ARM_FUNC u16 OS_ReadOwnerOfLockWord(OSLockWord * lock)
+{
+ return lock->ownerID;
+}
+
+ARM_FUNC asm s32 OS_UnLockCartridge(u16 lockID)
+{
+ ldr r1, =OS_UnlockCartridge
+ bx r1
+}
+
+ARM_FUNC asm s32 OS_GetLockID(void)
+{
+ ldr r3, =HW_LOCK_ID_FLAG_MAIN
+ ldr r1, [r3, #0x0]
+ clz r2, r1
+ cmp r2, #0x20
+ movne r0, #0x40
+ bne _020CA0D4
+ add r3, r3, #0x4
+ ldr r1, [r3, #0x0]
+ clz r2, r1
+ cmp r2, #0x20
+ ldr r0, =0xFFFFFFFD
+ bxeq lr
+ mov r0, #0x60
+_020CA0D4:
+ add r0, r0, r2
+ mov r1, #0x80000000
+ mov r1, r1, lsr r2
+ ldr r2, [r3, #0x0]
+ bic r2, r2, r1
+ str r2, [r3, #0x0]
+ bx lr
+}
+
+ARM_FUNC asm void OS_ReleaseLockID(register u16 lockID)
+{
+ ldr r3, =HW_LOCK_ID_FLAG_MAIN
+ cmp r0, #0x60
+ addpl r3, r3, #0x4
+ subpl r0, r0, #0x60
+ submi r0, r0, #0x40
+ mov r1, #0x80000000
+ mov r1, r1, lsr r0
+ ldr r2, [r3, #0x0]
+ orr r2, r2, r1
+ str r2, [r3, #0x0]
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/OS_system.c b/arm9/lib/NitroSDK/src/OS_system.c
new file mode 100644
index 00000000..f5f5faba
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_system.c
@@ -0,0 +1,77 @@
+#include "OS_system.h"
+#include "OS_irqHandler.h"
+#include "syscall.h"
+
+ARM_FUNC asm OSIntrMode OS_EnableInterrupts(void)
+{
+ mrs r0, cpsr
+ bic r1, r0, #HW_PSR_DISABLE_IRQ
+ msr cpsr_c, r1
+ and r0, r0, #HW_PSR_DISABLE_IRQ
+ bx lr
+}
+
+ARM_FUNC asm OSIntrMode OS_DisableInterrupts(void)
+{
+ mrs r0, cpsr
+ orr r1, r0, #HW_PSR_DISABLE_IRQ
+ msr cpsr_c, r1
+ and r0, r0, #HW_PSR_DISABLE_IRQ
+ bx lr
+}
+
+ARM_FUNC asm OSIntrMode OS_RestoreInterrupts(OSIntrMode state)
+{
+ mrs r1, cpsr
+ bic r2, r1, #HW_PSR_DISABLE_IRQ
+ orr r2, r2, r0
+ msr cpsr_c, r2
+ and r0, r1, #HW_PSR_DISABLE_IRQ
+ bx lr
+}
+
+ARM_FUNC asm OSIntrMode OS_DisableInterrupts_IrqAndFiq(void)
+{
+ mrs r0, cpsr
+ orr r1, r0, #HW_PSR_DISABLE_IRQ_FIQ
+ msr cpsr_c, r1
+ and r0, r0, #HW_PSR_DISABLE_IRQ_FIQ
+ bx lr
+}
+
+ARM_FUNC asm OSIntrMode OS_RestoreInterrupts_IrqAndFiq(OSIntrMode state)
+{
+ mrs r1, cpsr
+ bic r2, r1, #HW_PSR_DISABLE_IRQ_FIQ
+ orr r2, r2, r0
+ msr cpsr_c, r2
+ and r0, r1, #HW_PSR_DISABLE_IRQ_FIQ
+ bx lr
+}
+
+ARM_FUNC asm OSIntrMode OS_GetCpsrIrq(void)
+{
+ mrs r0, cpsr
+ and r0, r0, #HW_PSR_DISABLE_IRQ
+ bx lr
+}
+
+ARM_FUNC asm OSProcMode OS_GetProcMode(void)
+{
+ mrs r0, cpsr
+ and r0, r0, #HW_PSR_CPU_MODE_MASK
+ bx lr
+}
+
+ARM_FUNC asm void OS_SpinWait(u32 cycles)
+{
+ subs r0, r0, #0x4
+ bhs OS_SpinWait
+ bx lr
+}
+
+ARM_FUNC void OS_WaitVBlankIntr(void)
+{
+ SVC_WaitByLoop(0x1);
+ OS_WaitIrq(TRUE, OS_IE_V_BLANK);
+}
diff --git a/arm9/lib/NitroSDK/src/OS_tcm.c b/arm9/lib/NitroSDK/src/OS_tcm.c
new file mode 100644
index 00000000..5b6ab552
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_tcm.c
@@ -0,0 +1,9 @@
+#include "OS_tcm.h"
+#include "function_target.h"
+
+ARM_FUNC asm u32 OS_GetDTCMAddress(void) {
+ mrc p15, 0x0, r0, c9, c1, 0x0 //Data TCM Base
+ ldr r1, =OSi_TCM_REGION_BASE_MASK
+ and r0, r0, r1
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/OS_terminate_proc.c b/arm9/lib/NitroSDK/src/OS_terminate_proc.c
new file mode 100644
index 00000000..fdc4dbff
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_terminate_proc.c
@@ -0,0 +1,19 @@
+#include "OS_terminate_proc.h"
+#include "function_target.h"
+#include "OS_system.h"
+
+ARM_FUNC void OS_Terminate(void)
+{
+ while (TRUE)
+ {
+ (void)OS_DisableInterrupts();
+ OS_Halt();
+ }
+}
+
+ARM_FUNC asm void OS_Halt(void)
+{
+ mov r0, #0x0
+ mcr p15, 0x0, r0, c7, c0, 0x4 //Wait For Interrupt (Halt)
+ bx lr
+}
diff --git a/arm9/lib/NitroSDK/src/OS_thread.c b/arm9/lib/NitroSDK/src/OS_thread.c
new file mode 100644
index 00000000..a52b1f6d
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_thread.c
@@ -0,0 +1,734 @@
+#include "function_target.h"
+#include "MI_memory.h"
+#include "OS_thread.h"
+#include "OS_mutex.h"
+#include "OS_alarm.h"
+#include "OS_system.h"
+#include "OS_context.h"
+#include "OS_terminate_proc.h"
+#include "systemWork.h"
+#include "mmap.h"
+
+extern void SDK_SYS_STACKSIZE(void);
+extern void SDK_IRQ_STACKSIZE(void);
+
+extern void SDK_SECTION_ARENA_DTCM_START(void);
+
+static s32 OSi_ThreadIdCount = 0;
+
+u32 OSi_RescheduleCount = 0;
+
+void *OSi_StackForDestructor = NULL;
+
+BOOL OSi_IsThreadInitialized = FALSE;
+
+OSThreadInfo OSi_ThreadInfo;
+
+OSThread **OSi_CurrentThreadPtr = NULL;
+
+void *OSi_SystemCallbackInSwitchThread = NULL;
+
+OSThread OSi_LauncherThread;
+OSThread OSi_IdleThread;
+
+u32 OSi_IdleThreadStack[50];
+
+static s32 OSi_GetUnusedThreadId(void);
+static void OSi_InsertLinkToQueue(OSThreadQueue *queue, OSThread *thread);
+static OSThread *OSi_RemoveLinkFromQueue(OSThreadQueue *queue);
+static OSThread *OSi_RemoveSpecifiedLinkFromQueue(OSThreadQueue *queue, OSThread *thread);
+static void OSi_InsertThreadToList(OSThread *thread);
+static void OSi_RemoveThreadFromList(OSThread *thread);
+static void OSi_ExitThread_ArgSpecified(OSThread *thread, void *arg);
+static void OSi_ExitThread(void *arg);
+static void OSi_ExitThread_Destroy(void);
+static void OSi_CancelThreadAlarmForSleep(OSThread *thread);
+static void OSi_SleepAlarmCallback(void *arg);
+static void OSi_IdleThreadProc(void *);
+
+ARM_FUNC static s32 OSi_GetUnusedThreadId(void)
+{
+ return ++OSi_ThreadIdCount;
+}
+
+ARM_FUNC static void OSi_InsertLinkToQueue(OSThreadQueue *queue, OSThread *thread)
+{
+ OSThread *next = queue->head;
+
+ while (next && next->priority <= thread->priority)
+ {
+ if (next == thread)
+ return;
+ next = next->link.next;
+ }
+
+ if (!next)
+ {
+ OSThread *prev = queue->tail;
+
+ if (!prev)
+ {
+ queue->head = thread;
+ }
+ else
+ {
+ prev->link.next = thread;
+ }
+
+ thread->link.prev = prev;
+ thread->link.next = NULL;
+ queue->tail = thread;
+ }
+ else
+ {
+ OSThread *prev = next->link.prev;
+
+ if (!prev)
+ {
+ queue->head = thread;
+ }
+ else
+ {
+ prev->link.next = thread;
+ }
+
+ thread->link.prev = prev;
+ thread->link.next = next;
+ next->link.prev = thread;
+ }
+}
+
+ARM_FUNC static OSThread *OSi_RemoveLinkFromQueue(OSThreadQueue *queue)
+{
+ OSThread *thread = queue->head;
+
+ if (thread)
+ {
+ OSThread *next = thread->link.next;
+
+ queue->head = next;
+
+ if (next)
+ {
+ next->link.prev = NULL;
+ }
+ else
+ {
+ queue->tail = NULL;
+ thread->queue = NULL;
+ }
+ }
+
+ return thread;
+}
+
+ARM_FUNC static OSThread *OSi_RemoveSpecifiedLinkFromQueue(OSThreadQueue *queue, OSThread *thread)
+{
+ OSThread *queueHead = queue->head;
+
+ while (queueHead)
+ {
+ OSThread *next = queueHead->link.next;
+
+ if (queueHead == thread)
+ {
+ OSThread *prev = queueHead->link.prev;
+
+ if (queue->head == queueHead)
+ {
+ queue->head = next;
+ }
+ else
+ {
+ prev->link.next = next;
+ }
+
+ if (queue->tail == queueHead)
+ {
+ queue->tail = prev;
+ }
+ else
+ {
+ next->link.prev = prev;
+ }
+
+ break;
+ }
+
+ queueHead = next;
+ }
+
+ return queueHead;
+}
+
+ARM_FUNC OSMutex *OSi_RemoveMutexLinkFromQueue(OSMutexQueue *queue)
+{
+ OSMutex *mutexHead = queue->head;
+
+ if (mutexHead)
+ {
+ OSMutex *next = mutexHead->link.next;
+
+ queue->head = next;
+
+ if (next)
+ {
+ next->link.prev = NULL;
+ }
+ else
+ {
+ queue->tail = NULL;
+ }
+ }
+
+ return mutexHead;
+}
+
+ARM_FUNC static void OSi_InsertThreadToList(OSThread *thread)
+{
+ OSThread *t = OSi_ThreadInfo.list;
+ OSThread *pre = NULL;
+
+ while(t && t->priority < thread->priority)
+ {
+ pre = t;
+ t = t->next;
+ }
+
+ if (!pre)
+ {
+ thread->next = OSi_ThreadInfo.list;
+ OSi_ThreadInfo.list = thread;
+ }
+ else
+ {
+ thread->next = pre->next;
+ pre->next = thread;
+ }
+}
+
+ARM_FUNC static void OSi_RemoveThreadFromList(OSThread *thread)
+{
+ OSThread *t = OSi_ThreadInfo.list;
+ OSThread *pre = NULL;
+
+ while (t && t != thread)
+ {
+ pre = t;
+ t = t-> next;
+ }
+
+ if (!pre)
+ {
+ OSi_ThreadInfo.list = thread->next;
+ }
+ else
+ {
+ pre->next = thread->next;
+ }
+}
+
+ARM_FUNC static void OSi_RescheduleThread(void)
+{
+ if (OSi_RescheduleCount <= 0)
+ {
+ OSThreadInfo *info = &OSi_ThreadInfo;
+ if (info->irqDepth > 0 || OS_GetProcMode() == OS_PROCMODE_IRQ)
+ {
+ info->isNeedRescheduling = TRUE;
+ }
+ else
+ {
+ OSThread *currentThread = OSi_GetCurrentThread();
+ OSThread *nextThread = OS_SelectThread();
+
+ if (currentThread == nextThread || !nextThread)
+ return;
+
+ if (currentThread->state != OS_THREAD_STATE_TERMINATED
+ && OS_SaveContext(&currentThread->context))
+ return;
+
+ if (OSi_SystemCallbackInSwitchThread)
+ {
+ ((OSSwitchThreadCallback)OSi_SystemCallbackInSwitchThread) (currentThread, nextThread);
+ }
+
+ if (info->switchCallback)
+ {
+ ((OSSwitchThreadCallback)info->switchCallback) (currentThread, nextThread);
+ }
+
+ OS_SetCurrentThread(nextThread);
+
+ OS_LoadContext(&nextThread->context);
+ }
+ }
+}
+
+ARM_FUNC void OS_InitThread(void)
+{
+ if (OSi_IsThreadInitialized)
+ return;
+ OSi_IsThreadInitialized = TRUE;
+
+ OSi_CurrentThreadPtr = &(OSi_ThreadInfo.current);
+
+ OSi_LauncherThread.priority = OS_THREAD_LAUNCHER_PRIORITY;
+ OSi_LauncherThread.id = 0;
+ OSi_LauncherThread.state = OS_THREAD_STATE_READY;
+ OSi_LauncherThread.next = NULL;
+
+ OSi_LauncherThread.profiler = NULL;
+
+ OSi_ThreadInfo.list = &OSi_LauncherThread;
+
+ OS_SetCurrentThread(&OSi_LauncherThread);
+
+ void *stackLo = (((s32)SDK_SYS_STACKSIZE) <= 0) ?
+ (void *)((u32)SDK_SECTION_ARENA_DTCM_START - (s32)SDK_SYS_STACKSIZE) :
+ (void *)((u32)(HW_DTCM_SVC_STACK - (s32)SDK_IRQ_STACKSIZE) - (s32)SDK_SYS_STACKSIZE);
+
+ OSi_LauncherThread.stackBottom = (u32)(HW_DTCM_SVC_STACK - (s32)SDK_IRQ_STACKSIZE);
+ OSi_LauncherThread.stackTop = (u32)stackLo;
+ OSi_LauncherThread.stackWarningOffset = 0;
+
+ //checksums
+ *(u32 *)(OSi_LauncherThread.stackBottom - sizeof(u32)) = 0xfddb597dUL;
+ *(u32 *)OSi_LauncherThread.stackTop = 0x7bf9dd5bUL;
+
+ OS_InitThreadQueue(&OSi_LauncherThread.joinQueue);
+
+ OSi_ThreadInfo.isNeedRescheduling = FALSE;
+ OSi_ThreadInfo.irqDepth = 0;
+
+ OS_GetSystemWork()->threadinfo_mainp = &OSi_ThreadInfo;
+
+ (void)OS_SetSwitchThreadCallback(NULL);
+
+ OS_CreateThread(&OSi_IdleThread, OSi_IdleThreadProc, NULL,
+ OSi_IdleThreadStack + 50, 200, OS_THREAD_PRIORITY_MAX);
+
+ OSi_IdleThread.priority = OS_THREAD_PRIORITY_MAX + 1;
+ OSi_IdleThread.state = OS_THREAD_STATE_READY;
+}
+
+ARM_FUNC asm BOOL OS_IsThreadAvailable(void)
+{
+ ldr r0, =OSi_IsThreadInitialized
+ ldr r0, [r0, #0]
+ bx lr
+}
+
+ARM_FUNC void OS_CreateThread(OSThread *thread, void (*func) (void *), void *arg, void *stack, u32 stackSize, u32 prio)
+{
+ OSIntrMode enable = OS_DisableInterrupts();
+
+ s32 index = OSi_GetUnusedThreadId();
+
+ thread->priority = prio;
+ thread->id = (u32)index;
+ thread->state = OS_THREAD_STATE_WAITING;
+
+ thread->profiler = NULL;
+
+ OSi_InsertThreadToList(thread);
+
+ thread->stackBottom = (u32)stack;
+ thread->stackTop = (u32)stack - stackSize;
+ thread->stackWarningOffset = 0;
+
+ *(u32 *)(thread->stackBottom - sizeof(u32)) = 0xfddb597dUL;
+ *(u32 *)thread->stackTop = 0x7bf9dd5bUL;
+
+ OS_InitThreadQueue(&thread->joinQueue);
+
+ OS_InitContext(&thread->context, (u32)func, (u32)stack - 4);
+
+ thread->context.r[0] = (u32)arg;
+ thread->context.lr = (u32)OS_ExitThread;
+
+ MI_CpuClear32((void *)((u32)stack - stackSize + 4), stackSize - 8);
+
+ thread->mutex = NULL;
+ thread->mutexQueue.head = NULL;
+ thread->mutexQueue.tail = NULL;
+
+ OS_SetThreadDestructor(thread, NULL);
+
+ thread->queue = NULL;
+ thread->link.prev = thread->link.next = NULL;
+
+ MI_CpuClear32(&thread->specific[0], sizeof(void *) * OS_THREAD_SPECIFIC_MAX);
+
+ thread->alarmForSleep = NULL;
+
+ (void)OS_RestoreInterrupts(enable);
+}
+
+ARM_FUNC void OS_ExitThread(void)
+{
+ (void)OS_DisableInterrupts();
+ OSi_ExitThread_ArgSpecified(OS_GetCurrentThread(), 0);
+}
+
+ARM_FUNC static void OSi_ExitThread_ArgSpecified(OSThread *thread, void *arg)
+{
+ if (OSi_StackForDestructor)
+ {
+ OS_InitContext(&thread->context, (u32)OSi_ExitThread, (u32)OSi_StackForDestructor);
+ thread->context.r[0] = (u32)arg;
+ thread->context.cpsr |= HW_PSR_DISABLE_IRQ;
+ thread->state = OS_THREAD_STATE_READY;
+ OS_LoadContext(&thread->context);
+ }
+ else
+ {
+ OSi_ExitThread(arg);
+ }
+}
+
+ARM_FUNC static void OSi_ExitThread(void *arg)
+{
+ OSThread *currentThread = OSi_GetCurrentThread();
+ OSThreadDestructor destructor = currentThread->destructor;
+
+ if (destructor)
+ {
+ currentThread->destructor = NULL;
+ destructor(arg);
+ (void)OS_DisableInterrupts();
+ }
+
+ OSi_ExitThread_Destroy();
+}
+
+ARM_FUNC static void OSi_ExitThread_Destroy(void)
+{
+ OSThread *currentThread = OSi_GetCurrentThread();
+ (void)OS_DisableScheduler();
+
+ OSi_UnlockAllMutex(currentThread);
+
+ if (currentThread->queue)
+ {
+ (void)OSi_RemoveSpecifiedLinkFromQueue(currentThread->queue, currentThread);
+ }
+
+ OSi_RemoveThreadFromList(currentThread);
+
+ currentThread->state = OS_THREAD_STATE_TERMINATED;
+
+ OS_WakeupThread(&currentThread->joinQueue);
+
+ (void)OS_EnableScheduler();
+
+ OS_RescheduleThread();
+
+ OS_Terminate();
+}
+
+ARM_FUNC void OS_DestroyThread(OSThread *thread)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ if (OS_GetCurrentThread() == thread)
+ {
+ OSi_ExitThread_Destroy();
+ }
+
+ (void)OS_DisableScheduler();
+
+ OSi_UnlockAllMutex(thread);
+
+ OSi_CancelThreadAlarmForSleep(thread);
+
+ if (thread->queue)
+ {
+ (void)OSi_RemoveSpecifiedLinkFromQueue(thread->queue, thread);
+ }
+
+ OSi_RemoveThreadFromList(thread);
+
+ thread->state = OS_THREAD_STATE_TERMINATED;
+
+ OS_WakeupThread(&thread->joinQueue);
+
+ (void)OS_EnableScheduler();
+ (void)OS_RestoreInterrupts(enabled);
+
+ OS_RescheduleThread();
+}
+
+ARM_FUNC static void OSi_CancelThreadAlarmForSleep(OSThread *thread)
+{
+ OSAlarm *alarm = thread->alarmForSleep;
+
+ if (alarm)
+ {
+ OS_CancelAlarm(alarm);
+ }
+}
+
+ARM_FUNC void OS_JoinThread(OSThread *thread)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ if (thread->state != OS_THREAD_STATE_TERMINATED)
+ {
+ OS_SleepThread(&thread->joinQueue);
+ }
+
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC BOOL OS_IsThreadTerminated(const OSThread *thread)
+{
+ return (thread->state == OS_THREAD_STATE_TERMINATED) ? TRUE : FALSE;
+}
+
+ARM_FUNC void OS_SleepThread(OSThreadQueue *queue)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+ OSThread *currentThread = OSi_GetCurrentThread();
+
+ if (queue)
+ {
+ currentThread->queue = queue;
+ OSi_InsertLinkToQueue(queue, currentThread);
+ }
+
+ currentThread->state = OS_THREAD_STATE_WAITING;
+ OSi_RescheduleThread();
+
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC void OS_WakeupThread(OSThreadQueue *queue)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ if (queue->head)
+ {
+ while (queue->head)
+ {
+ OSThread *thread = OSi_RemoveLinkFromQueue(queue);
+
+ thread->state = OS_THREAD_STATE_READY;
+ thread->queue = NULL;
+ thread->link.prev = thread->link.next = NULL;
+ }
+
+ OS_InitThreadQueue(queue);
+ OSi_RescheduleThread();
+ }
+
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC void OS_WakeupThreadDirect(OSThread *thread)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ thread->state = OS_THREAD_STATE_READY;
+ OSi_RescheduleThread();
+
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC OSThread *OS_SelectThread(void)
+{
+ OSThread *thread = OSi_ThreadInfo.list;
+
+ while (thread && !OS_IsThreadRunnable(thread))
+ {
+ thread = thread->next;
+ }
+
+ return thread;
+}
+
+ARM_FUNC void OS_RescheduleThread(void)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+ OSi_RescheduleThread();
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC void OS_YieldThread(void)
+{
+ OSThread *current = OS_GetCurrentThread();
+ OSThread *pre = NULL;
+ OSThread *lastThread = NULL;
+ s32 samePriorityThread = 0;
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ OSThread *t = OSi_ThreadInfo.list;
+ OSThread *tPre = NULL;
+
+ while (t)
+ {
+ if (t == current)
+ {
+ pre = tPre;
+ }
+
+ if (current->priority == t->priority)
+ {
+ lastThread = t;
+ samePriorityThread++;
+ }
+
+ tPre = t;
+ t = t->next;
+ }
+
+ if (samePriorityThread <= 1 || lastThread == current)
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return;
+ }
+
+ if (!pre)
+ {
+ OSi_ThreadInfo.list = current->next;
+ }
+ else
+ {
+ pre->next = current->next;
+ }
+
+ current->next = lastThread->next;
+ lastThread->next = current;
+
+ OSi_RescheduleThread();
+
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC BOOL OS_SetThreadPriority(OSThread *thread, u32 prio)
+{
+ OSThread *t = OSi_ThreadInfo.list;
+ OSThread *pre = NULL;
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ while (t && t != thread)
+ {
+ pre = t;
+ t = t->next;
+ }
+
+ if (!t || t == &OSi_IdleThread)
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ if (t->priority != prio)
+ {
+ if (!pre)
+ {
+ OSi_ThreadInfo.list = thread->next;
+ }
+ else
+ {
+ pre->next = thread->next;
+ }
+
+ thread->priority = prio;
+ OSi_InsertThreadToList(thread);
+
+ OSi_RescheduleThread();
+ }
+
+ (void)OS_RestoreInterrupts(enabled);
+
+ return TRUE;
+}
+
+ARM_FUNC u32 OS_GetThreadPriority(const OSThread *thread)
+{
+ return thread->priority;
+}
+
+ARM_FUNC void OS_Sleep(u32 msec)
+{
+ OSAlarm alarm;
+
+ OS_CreateAlarm(&alarm);
+ OSThread *volatile p_thread = OSi_GetCurrentThread();
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ p_thread->alarmForSleep = &alarm;
+
+ OS_SetAlarm(&alarm, OS_MilliSecondsToTicks(msec), &OSi_SleepAlarmCallback,
+ (void*)&p_thread);
+ while (p_thread != NULL)
+ {
+ OS_SleepThread(NULL);
+ }
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC static void OSi_SleepAlarmCallback(void *arg)
+{
+ OSThread **pp_thread = (OSThread **)arg;
+ OSThread *p_thread = *pp_thread;
+ *pp_thread = NULL;
+
+ p_thread->alarmForSleep = NULL;
+
+ OS_WakeupThreadDirect(p_thread);
+}
+
+ARM_FUNC OSSwitchThreadCallback OS_SetSwitchThreadCallback(OSSwitchThreadCallback callback)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+ OSSwitchThreadCallback prev = OSi_ThreadInfo.switchCallback;
+ OSi_ThreadInfo.switchCallback = callback;
+
+ (void)OS_RestoreInterrupts(enabled);
+ return prev;
+}
+
+ARM_FUNC static void OSi_IdleThreadProc(void *)
+{
+ (void)OS_EnableInterrupts();
+ while (1)
+ {
+ OS_Halt();
+ }
+}
+
+ARM_FUNC u32 OS_DisableScheduler(void)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+ u32 count;
+
+ if (OSi_RescheduleCount < (u32)-1)
+ {
+ count = OSi_RescheduleCount++;
+ }
+ (void)OS_RestoreInterrupts(enabled);
+
+ return count;
+}
+
+ARM_FUNC u32 OS_EnableScheduler(void)
+{
+ OSIntrMode enabled = OS_DisableInterrupts();
+ u32 count = 0;
+
+ if (OSi_RescheduleCount > 0)
+ {
+ count = OSi_RescheduleCount--;
+ }
+ (void)OS_RestoreInterrupts(enabled);
+
+ return count;
+}
+
+ARM_FUNC void OS_SetThreadDestructor(OSThread *thread, OSThreadDestructor dtor)
+{
+ thread->destructor = dtor;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_tick.c b/arm9/lib/NitroSDK/src/OS_tick.c
new file mode 100644
index 00000000..b0e81054
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_tick.c
@@ -0,0 +1,70 @@
+#include "function_target.h"
+#include "OS_tick.h"
+#include "OS_interrupt.h"
+#include "OS_timer.h"
+#include "OS_system.h"
+
+static u16 OSi_UseTick = FALSE;
+vu64 OSi_TickCounter;
+BOOL OSi_NeedResetTimer = FALSE;
+
+static void OSi_CountUpTick(void);
+
+ARM_FUNC void OS_InitTick(void)
+{
+ if (OSi_UseTick)
+ {
+ return;
+ }
+ OSi_UseTick = 1;
+ OSi_SetTimerReserved(0);
+ OSi_TickCounter = 0;
+ reg_OS_TM0CNT_H = 0;
+ reg_OS_TM0CNT_L = 0;
+ reg_OS_TM0CNT_H = 0xc1;
+ OS_SetIrqFunction(8, OSi_CountUpTick);
+ (void)OS_EnableIrqMask(8);
+ OSi_NeedResetTimer = FALSE;
+}
+
+ARM_FUNC BOOL OS_IsTickAvailable(void)
+{
+ return OSi_UseTick;
+}
+
+ARM_FUNC static void OSi_CountUpTick(void)
+{
+ OSi_TickCounter++;
+
+ if (OSi_NeedResetTimer)
+ {
+ OS_SetTimerControl(OS_TIMER_0, 0);
+ OS_SetTimerCount(OS_TIMER_0, 0);
+ OS_SetTimerControl(OS_TIMER_0, OSi_TICK_TIMERCONTROL);
+
+ OSi_NeedResetTimer = FALSE;
+ }
+
+ OSi_EnterTimerCallback(OS_TIMER_0, (void (*)(void *))OSi_CountUpTick, 0);
+}
+
+ARM_FUNC OSTick OS_GetTick(void)
+{
+ OSIntrMode prev = OS_DisableInterrupts();
+ vu16 countL = *(REGType16 *)((u32)&reg_OS_TM0CNT_L + OS_TIMER_0 * 4);
+ vu64 countH = OSi_TickCounter & 0xffffffffffffULL;
+
+ if (reg_OS_IF & OS_IE_TIMER0 && !(countL & 0x8000))
+ {
+ countH++;
+ }
+
+ (void)OS_RestoreInterrupts(prev);
+
+ return (countH << 16) | countL;
+}
+
+ARM_FUNC u16 OS_GetTickLo(void)
+{
+ return reg_OS_TM0CNT_L;
+}
diff --git a/arm9/lib/NitroSDK/src/OS_timer.c b/arm9/lib/NitroSDK/src/OS_timer.c
new file mode 100644
index 00000000..69a1a6cd
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_timer.c
@@ -0,0 +1,9 @@
+#include "OS_timer.h"
+#include "function_target.h"
+
+static u16 OSi_TimerReserved = 0;
+
+ARM_FUNC void OSi_SetTimerReserved(s32 timerNum)
+{
+ OSi_TimerReserved |= (1 << timerNum);
+}
diff --git a/arm9/lib/NitroSDK/src/OS_valarm.c b/arm9/lib/NitroSDK/src/OS_valarm.c
new file mode 100644
index 00000000..37329147
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_valarm.c
@@ -0,0 +1,30 @@
+#include "OS_valarm.h"
+#include "function_target.h"
+#include "OS_interrupt.h"
+
+static struct OSiVAlarmQueue
+{
+ OSVAlarm *head;
+ OSVAlarm *tail;
+} OSi_VAlarmQueue;
+
+static u16 OSi_UseVAlarm = FALSE;
+
+static s32 OSi_VFrameCount;
+static s32 OSi_PreviousVCount;
+
+ARM_FUNC void OS_InitVAlarm(void)
+{
+ if (!OSi_UseVAlarm)
+ {
+ OSi_UseVAlarm = TRUE;
+
+ OSi_VAlarmQueue.head = NULL;
+ OSi_VAlarmQueue.tail = NULL;
+
+ (void)OS_DisableIrqMask(OS_IE_V_COUNT);
+
+ OSi_VFrameCount = 0;
+ OSi_PreviousVCount = 0;
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/OS_vramExclusive.c b/arm9/lib/NitroSDK/src/OS_vramExclusive.c
new file mode 100644
index 00000000..5ce10f4a
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/OS_vramExclusive.c
@@ -0,0 +1,88 @@
+#include "OS_vramExclusive.h"
+#include "function_target.h"
+#include "OS_system.h"
+
+static u32 OSi_vramExclusive;
+static u16 OSi_vramLockId[9];
+
+static u32 OsCountZeroBits(register u32 bitmap);
+
+ARM_FUNC static asm u32 OsCountZeroBits(register u32 bitmap)
+{
+ clz r0, r0
+ bx lr
+}
+
+ARM_FUNC void OSi_InitVramExclusive(void)
+{
+ OSi_vramExclusive = 0x0000;
+
+ for (s32 i = 0; i < 9; i++)
+ {
+ OSi_vramLockId[i] = 0;
+ }
+}
+
+ARM_FUNC BOOL OSi_TryLockVram(u16 bank, u16 lockId)
+{
+ u32 workMap;
+ s32 zeroBits;
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ workMap = (u32)(bank & OSi_vramExclusive);
+ while (TRUE)
+ {
+ zeroBits = (s32)(31 - OsCountZeroBits(workMap));
+ if (zeroBits < 0)
+ {
+ break;
+ }
+ workMap &= ~(0x00000001 << zeroBits);
+ if (OSi_vramLockId[zeroBits] != lockId)
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return FALSE;
+ }
+ }
+
+ workMap = (u32)(bank & 0x01ff);
+ while (TRUE)
+ {
+ zeroBits = (s32)(31 - OsCountZeroBits(workMap));
+ if (zeroBits < 0)
+ {
+ break;
+ }
+ workMap &= ~(0x00000001 << zeroBits);
+ OSi_vramLockId[zeroBits] = lockId;
+ OSi_vramExclusive |= (0x00000001 << zeroBits);
+ }
+
+ (void)OS_RestoreInterrupts(enabled);
+ return TRUE;
+}
+
+ARM_FUNC void OSi_UnlockVram(u16 bank, u16 lockId)
+{
+ u32 workMap;
+ s32 zeroBits;
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ workMap = (u32)(bank & OSi_vramExclusive & 0x01ff);
+ while (TRUE)
+ {
+ zeroBits = (s32)(31- OsCountZeroBits((u32)workMap));
+ if (zeroBits < 0)
+ {
+ break;
+ }
+ workMap &= ~(0x00000001 << zeroBits);
+ if (OSi_vramLockId[zeroBits] == lockId)
+ {
+ OSi_vramLockId[zeroBits] = 0;
+ OSi_vramExclusive &= ~(0x00000001 << zeroBits);
+ }
+ }
+
+ (void)OS_RestoreInterrupts(enabled);
+}
diff --git a/arm9/lib/NitroSDK/src/PXI_fifo.c b/arm9/lib/NitroSDK/src/PXI_fifo.c
new file mode 100644
index 00000000..35db1c7f
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/PXI_fifo.c
@@ -0,0 +1,185 @@
+#include "function_target.h"
+#include "consts.h"
+#include "OS_interrupt.h"
+#include "OS_system.h"
+#include "PXI_fifo.h"
+#include "systemWork.h"
+
+static u16 FifoCtrlInit = 0;
+static PXIFifoCallback FifoRecvCallbackTable[PXI_MAX_FIFO_TAG];
+
+static inline PXIFifoStatus PXIi_SetToFifo(u32 data);
+
+ARM_FUNC void PXI_InitFifo(void)
+{
+ OSSystemWork *p = OS_GetSystemWork();
+ OSIntrMode enabled = OS_DisableInterrupts();
+ s32 i;
+
+ if (!FifoCtrlInit)
+ {
+ FifoCtrlInit = TRUE;
+
+ p->pxiHandleChecker[PXI_PROC_ARM9] = 0UL;
+
+ for (i = 0; i < PXI_MAX_FIFO_TAG; i++)
+ {
+ FifoRecvCallbackTable[i] = NULL;
+ }
+
+ reg_PXI_SUBP_FIFO_CNT = (REG_PXI_SUBP_FIFO_CNT_SEND_CL_MASK
+ | REG_PXI_SUBP_FIFO_CNT_RECV_RI_MASK | REG_PXI_SUBP_FIFO_CNT_E_MASK | REG_PXI_SUBP_FIFO_CNT_ERR_MASK);
+
+ (void)OS_ResetRequestIrqMask(OS_IE_SPFIFO_RECV);
+ (void)OS_SetIrqFunction(OS_IE_SPFIFO_RECV, PXIi_HandlerRecvFifoNotEmpty);
+ (void)OS_EnableIrqMask(OS_IE_SPFIFO_RECV);
+
+ {
+ s32 timeout;
+ s32 c;
+
+ for (i = 0; ; i++)
+ {
+ c = reg_PXI_SUBPINTF & 15;
+ reg_PXI_SUBPINTF = (u16)(c << 8);
+
+ if (c == 0 && i > 4)
+ {
+ break;
+ }
+
+ for (timeout = 1000; (reg_PXI_SUBPINTF & 15) == c; timeout--)
+ {
+ if (timeout == 0)
+ {
+ i = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC void PXI_SetFifoRecvCallback(s32 fifotag, PXIFifoCallback callback)
+{
+ OSSystemWork *p = OS_GetSystemWork();
+ OSIntrMode enabled = OS_DisableInterrupts();
+
+ FifoRecvCallbackTable[fifotag] = callback;
+ if (callback)
+ {
+ p->pxiHandleChecker[PXI_PROC_ARM9] |= (1UL << fifotag);
+ }
+ else
+ {
+ p->pxiHandleChecker[PXI_PROC_ARM9] &= ~(1UL << fifotag);
+ }
+ (void)OS_RestoreInterrupts(enabled);
+}
+
+ARM_FUNC BOOL PXI_IsCallbackReady(s32 fifotag, PXIProc proc)
+{
+ OSSystemWork *p = OS_GetSystemWork();
+
+ return (p->pxiHandleChecker[proc] & (1UL << fifotag)) ? TRUE : FALSE;
+}
+
+ARM_FUNC s32 PXI_SendWordByFifo(s32 fifotag, u32 data, BOOL err)
+{
+ PXIFifoMessage fifomsg;
+
+ fifomsg.e.tag = (PXIFifoTag)fifotag;
+ fifomsg.e.err = (u32)err;
+ fifomsg.e.data = data;
+
+ return PXIi_SetToFifo(fifomsg.raw);
+}
+
+static inline PXIFifoStatus PXIi_SetToFifo(u32 data)
+{
+ if (reg_PXI_SUBP_FIFO_CNT & REG_PXI_SUBP_FIFO_CNT_ERR_MASK)
+ {
+ reg_PXI_SUBP_FIFO_CNT |= (REG_PXI_SUBP_FIFO_CNT_E_MASK | REG_PXI_SUBP_FIFO_CNT_ERR_MASK);
+ return PXI_FIFO_FAIL_SEND_ERR;
+ }
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+ if (reg_PXI_SUBP_FIFO_CNT & REG_PXI_SUBP_FIFO_CNT_SEND_FULL_MASK)
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return PXI_FIFO_FAIL_SEND_FULL;
+ }
+
+ reg_PXI_SEND_FIFO = data;
+ (void)OS_RestoreInterrupts(enabled);
+ return PXI_FIFO_SUCCESS;
+}
+
+static inline PXIFifoStatus PXIi_GetFromFifo(u32 *data_buf)
+{
+ if (reg_PXI_SUBP_FIFO_CNT & REG_PXI_SUBP_FIFO_CNT_ERR_MASK)
+ {
+ reg_PXI_SUBP_FIFO_CNT |= (REG_PXI_SUBP_FIFO_CNT_E_MASK | REG_PXI_SUBP_FIFO_CNT_ERR_MASK);
+ return PXI_FIFO_FAIL_RECV_ERR;
+ }
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+ if (reg_PXI_SUBP_FIFO_CNT & REG_PXI_SUBP_FIFO_CNT_RECV_EMP_MASK)
+ {
+ (void)OS_RestoreInterrupts(enabled);
+ return PXI_FIFO_FAIL_RECV_EMPTY;
+ }
+
+
+ *data_buf = reg_PXI_RECV_FIFO;
+ (void)OS_RestoreInterrupts(enabled);
+
+ return PXI_FIFO_SUCCESS;
+}
+
+ARM_FUNC void PXIi_HandlerRecvFifoNotEmpty(void)
+{
+ PXIFifoMessage fifomsg;
+ PXIFifoStatus ret_code;
+ PXIFifoTag tag;
+
+ while (TRUE)
+ {
+ ret_code = PXIi_GetFromFifo(&fifomsg.raw);
+
+ if (ret_code == PXI_FIFO_FAIL_RECV_EMPTY)
+ {
+ break;
+ }
+ if (ret_code == PXI_FIFO_FAIL_RECV_ERR)
+ {
+ continue;
+ }
+
+ tag = (PXIFifoTag)fifomsg.e.tag;
+
+ if (tag)
+ {
+ if (FifoRecvCallbackTable[tag])
+ {
+ (FifoRecvCallbackTable[tag])(tag, fifomsg.e.data, (BOOL)fifomsg.e.err);
+ }
+ else
+ {
+ if (fifomsg.e.err)
+ {
+ }
+ else
+ {
+ fifomsg.e.err = TRUE;
+ (void)PXIi_SetToFifo(fifomsg.raw);
+ }
+ }
+ }
+ else
+ {
+ }
+ }
+}
diff --git a/arm9/lib/NitroSDK/src/PXI_init.c b/arm9/lib/NitroSDK/src/PXI_init.c
new file mode 100644
index 00000000..d70ca3b0
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/PXI_init.c
@@ -0,0 +1,8 @@
+#include "PXI_init.h"
+#include "PXI_fifo.h"
+#include "function_target.h"
+
+ARM_FUNC void PXI_Init(void)
+{
+ PXI_InitFifo();
+}
diff --git a/arm9/lib/NitroSDK/src/RTC_convert.c b/arm9/lib/NitroSDK/src/RTC_convert.c
new file mode 100644
index 00000000..3d0bb2ce
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/RTC_convert.c
@@ -0,0 +1,164 @@
+#include "global.h"
+#include "RTC_api.h"
+#include "RTC_convert.h"
+
+static s32 sDayOfYear[12] = {
+ 0, // Jan
+ 31, // Feb
+ 59, // Mar
+ 90, // Apr
+ 120, // May
+ 151, // Jun
+ 181, // Jul
+ 212, // Aug
+ 243, // Sep
+ 273, // Oct
+ 304, // Nov
+ 334, // Dec
+};
+
+static inline BOOL RTCi_IsLeapYear(u32 year)
+{
+ return !((year & 0x03));
+}
+
+s32 RTC_ConvertDateToDay(const RTCDate * date)
+{
+ if (date->year >= 100
+ || date->month < 1
+ || date->month > 12
+ || date->day < 1
+ || date->day > 31
+ || date->week >= RTC_WEEK_MAX
+ || date->month < 1 // can't be
+ || date->month > 12 // too sure
+ )
+ return -1;
+ s32 dayNum = (s32)(date->day - 1);
+ dayNum += sDayOfYear[date->month - 1];
+ if (date->month >= 3 && RTCi_IsLeapYear(date->year))
+ dayNum++;
+ dayNum += date->year * 365;
+ dayNum += (date->year + 3) / 4;
+ return dayNum;
+}
+
+s32 RTCi_ConvertTimeToSecond(const RTCTime * time)
+{
+ return (s32)((time->hour * 60 + time->minute) * 60 + time->second);
+}
+
+s64 RTC_ConvertDateTimeToSecond(const RTCDate * date, const RTCTime * time)
+{
+ s32 day = RTC_ConvertDateToDay(date);
+ if (day == -1)
+ return -1;
+ s32 second = RTCi_ConvertTimeToSecond(time);
+ if (second == -1)
+ return -1;
+ return ((s64)day) * (60 * 60 * 24) + second;
+}
+
+void RTC_ConvertDayToDate(RTCDate * date, s32 day)
+{
+ u32 year;
+ s32 month;
+
+ if (day < 0)
+ {
+ day = 0;
+ }
+ if (day > 36524) // max number of days that can be recorded
+ {
+ day = 36524;
+ }
+ date->week = (RTCWeek)((day + 6) % 7);
+ for (year = 0; year < 99; year++)
+ {
+ s32 prev = day;
+ day -= (RTCi_IsLeapYear(year)) ? 366 : 365;
+ if (day < 0)
+ {
+ day = prev;
+ break;
+ }
+ }
+ if (day > 365)
+ {
+ day = 365;
+ }
+ date->year = year;
+ if (RTCi_IsLeapYear(year))
+ {
+ if (day < 31 + 29)
+ {
+ if (day < 31)
+ {
+ month = 1;
+ }
+ else
+ {
+ month = 2;
+ day -= 31;
+ }
+ date->month = (u32)month;
+ date->day = (u32)(day + 1);
+ return;
+ }
+ else
+ {
+ day--;
+ }
+ }
+ for (month = 11; month >= 0; month--)
+ {
+ if (day >= sDayOfYear[month])
+ {
+ date->month = (u32)(month + 1);
+ date->day = (u32)(day - sDayOfYear[month] + 1);
+ return;
+ }
+ }
+ // Internal Error.
+}
+
+void RTCi_ConvertSecondToTime(RTCTime * time, s32 sec)
+{
+ if (sec < 0)
+ sec = 0;
+ if (sec > 86399)
+ sec = 86399;
+ time->second = (u32)(sec % 60);
+ sec /= 60;
+ time->minute = (u32)(sec % 60);
+ sec /= 60;
+ time->hour = (u32)sec;
+}
+
+void RTC_ConvertSecondToDateTime(RTCDate * date, RTCTime * time, s64 sec)
+{
+ if (sec < 0)
+ sec = 0;
+ else if (sec > 3155759999)
+ sec = 3155759999;
+ RTCi_ConvertSecondToTime(time, (s32)(sec % 86400));
+ RTC_ConvertDayToDate(date, (s32)(sec / 86400));
+}
+
+RTCWeek RTC_GetDayOfWeek(RTCDate * date)
+{
+ int cent;
+ int year = (int)(2000 + date->year);
+ int month = (int)date->month;
+ int day = (int)date->day;
+
+ month -= 2;
+ if (month < 1)
+ {
+ month += 12;
+ --year;
+ }
+ cent = year / 100;
+ year %= 100;
+ return (RTCWeek)(((26 * month - 2) / 10 + day + year + year / 4 + cent / 4 + 5 * cent) % 7);
+}
diff --git a/arm9/lib/NitroSDK/src/RTC_internal.c b/arm9/lib/NitroSDK/src/RTC_internal.c
new file mode 100644
index 00000000..e3a132ab
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/RTC_internal.c
@@ -0,0 +1,31 @@
+#include "function_target.h"
+#include "PXI_fifo.h"
+#include "RTC_internal.h"
+
+static BOOL RtcSendPxiCommand(u8 command);
+
+ARM_FUNC BOOL RTCi_ReadRawDateTimeAsync(void)
+{
+ return RtcSendPxiCommand(16);
+}
+
+ARM_FUNC BOOL RTCi_ReadRawDateAsync(void)
+{
+ return RtcSendPxiCommand(17);
+}
+
+ARM_FUNC BOOL RTCi_ReadRawTimeAsync(void)
+{
+ return RtcSendPxiCommand(18);
+}
+
+ARM_FUNC BOOL RTCi_WriteRawStatus2Async(void)
+{
+ return RtcSendPxiCommand(39);
+}
+
+ARM_FUNC static BOOL RtcSendPxiCommand(u8 command)
+{
+ s32 data = command << 8 & 0x7f00;
+ return PXI_SendWordByFifo(PXI_FIFO_TAG_RTC, (u32)data, FALSE) >= 0;
+}
diff --git a/arm9/lib/NitroSDK/src/SND_alarm.c b/arm9/lib/NitroSDK/src/SND_alarm.c
new file mode 100644
index 00000000..e216c02c
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/SND_alarm.c
@@ -0,0 +1,40 @@
+#include "SND_alarm.h"
+
+struct AlarmCallback {
+ SNDAlarmCallback cb;
+ void *data;
+ u8 id;
+ u8 padding[3];
+};
+
+static struct AlarmCallback sCallbackTable[SND_ALARM_COUNT];
+
+ARM_FUNC void SND_AlarmInit(void) {
+ for (s32 i = 0; i < SND_ALARM_COUNT; i++) {
+ sCallbackTable[i].cb = NULL;
+ sCallbackTable[i].data = NULL;
+ sCallbackTable[i].id = 0;
+ }
+}
+
+ARM_FUNC void SNDi_IncAlarmId(u32 idx) {
+ struct AlarmCallback *ac = &sCallbackTable[idx];
+ ac->id++;
+}
+
+ARM_FUNC u8 SNDi_SetAlarmHandler(u32 idx, SNDAlarmCallback cb, void *data) {
+ struct AlarmCallback *ac = &sCallbackTable[idx];
+ ac->cb = cb;
+ ac->data = data;
+ ac->id++;
+ return ac->id;
+}
+
+ARM_FUNC void SNDi_CallAlarmHandler(s32 idx) {
+ struct AlarmCallback *ac = &sCallbackTable[idx & 0xFF];
+ if (((idx >> 8) & 0xFF) != ac->id)
+ return;
+ if (ac->cb == NULL)
+ return;
+ ac->cb(ac->data);
+}
diff --git a/arm9/lib/NitroSDK/src/SND_bank.c b/arm9/lib/NitroSDK/src/SND_bank.c
new file mode 100644
index 00000000..44075454
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/SND_bank.c
@@ -0,0 +1,174 @@
+#include "SND_bank.h"
+#include "OS_mutex.h"
+
+void DC_StoreRange(const void *, u32);
+
+/*
+ * WaveArc linking seems to work like the following:
+ *
+ * Each SNDBankData can have up to 4 WaveArcs assigned.
+ * To avoid loading the same WaveArc by multiple banks,
+ * a linked list using WaveArcLinks is chained through all banks
+ * which use a WaveArc.
+ *
+ * That WaveArc has a head pointer, which points to the first
+ * WaveArcLink in that chain of banks.
+ */
+
+/*
+ * Set bank's wavearc link at index to specified wavearc
+ */
+ARM_FUNC void SND_AssignWaveArc(struct SNDBankData *bankData, s32 index, struct SNDWaveArc *waveArc) {
+ SNDi_LockMutex();
+ struct SNDWaveArc *selectedWaveArc = bankData->waveArcLinks[index].waveArc;
+ if (selectedWaveArc != NULL) {
+ if (waveArc == selectedWaveArc) {
+ SNDi_UnlockMutex();
+ return;
+ }
+
+ if (&bankData->waveArcLinks[index] == selectedWaveArc->waveArcLLHead) {
+ selectedWaveArc->waveArcLLHead = bankData->waveArcLinks[index].waveArcLLnext;
+ DC_StoreRange(bankData->waveArcLinks[index].waveArc, sizeof(struct SNDWaveArc));
+ } else {
+ struct SNDWaveArcLink *cur;
+ for (cur = selectedWaveArc->waveArcLLHead; cur != NULL; cur = cur->waveArcLLnext) {
+ if (&bankData->waveArcLinks[index] == cur->waveArcLLnext)
+ break;
+ }
+ cur->waveArcLLnext = bankData->waveArcLinks[index].waveArcLLnext;
+ DC_StoreRange(cur, sizeof(*cur));
+ }
+ }
+ struct SNDWaveArcLink *oldHead = waveArc->waveArcLLHead;
+ waveArc->waveArcLLHead = &bankData->waveArcLinks[index];
+ bankData->waveArcLinks[index].waveArcLLnext = oldHead;
+ bankData->waveArcLinks[index].waveArc = waveArc;
+ // BUG: Shouldn't the mutex unlock be after writing to cache?
+ SNDi_UnlockMutex();
+ DC_StoreRange(bankData, sizeof(*bankData));
+ DC_StoreRange(waveArc, sizeof(*waveArc));
+}
+
+ARM_FUNC void SND_DestroyBank(struct SNDBankData *bankData) {
+ SNDi_LockMutex();
+
+ for (s32 i = 0; i < SND_BANK_MAX_WAVEARC; i++) {
+ struct SNDWaveArcLink *curWaveArcLink = &bankData->waveArcLinks[i];
+ struct SNDWaveArc *curWaveArc = bankData->waveArcLinks[i].waveArc;
+
+ if (curWaveArc == NULL)
+ continue;
+
+ if (curWaveArcLink == curWaveArc->waveArcLLHead) {
+ curWaveArc->waveArcLLHead = bankData->waveArcLinks[i].waveArcLLnext;
+ DC_StoreRange(curWaveArc, sizeof(*curWaveArc));
+ } else {
+ struct SNDWaveArcLink *cur;
+ for (cur = curWaveArc->waveArcLLHead; cur != NULL; cur = cur->waveArcLLnext) {
+ if (&bankData->waveArcLinks[i] == cur->waveArcLLnext)
+ break;
+ }
+ cur->waveArcLLnext = bankData->waveArcLinks[i].waveArcLLnext;
+ DC_StoreRange(cur, sizeof(*cur));
+ }
+ }
+
+ SNDi_UnlockMutex();
+}
+
+ARM_FUNC void SND_DestroyWaveArc(struct SNDWaveArc *waveArc) {
+ SNDi_LockMutex();
+ struct SNDWaveArcLink *cur = waveArc->waveArcLLHead;
+
+ while (cur != NULL) {
+ struct SNDWaveArcLink *newCur = cur->waveArcLLnext;
+ cur->waveArc = NULL;
+ cur->waveArcLLnext = NULL;
+ DC_StoreRange(cur, sizeof(*cur));
+ cur = newCur;
+ }
+
+ SNDi_UnlockMutex();
+}
+
+ARM_FUNC struct SNDInstPos SND_GetFirstInstDataPos(const struct SNDBankData *bankData) {
+#pragma unused (bankData)
+ struct SNDInstPos retval;
+ retval.program = 0;
+ retval.index = 0;
+ return retval;
+}
+
+ARM_FUNC static inline struct SNDDrumSet *test(const struct SNDBankData *bank, u32 off) {
+ return (struct SNDDrumSet *)((u8 *)bank + (off >> 8));
+}
+
+ARM_FUNC BOOL SND_GetNextInstData(const struct SNDBankData *bankData, struct SNDInstData *instData, struct SNDInstPos *instPos) {
+ while (instPos->program < bankData->instCount) {
+ struct SNDDrumSet *drums;
+ struct SNDKeySplit *keySplit;
+
+ u32 instOffset = bankData->instOffsets[instPos->program];
+ instData->type = SND_INST_OFFSET_TYPE(instOffset);
+
+ switch (instData->type) {
+ case SND_INST_PCM:
+ case SND_INST_PSG:
+ case SND_INST_NOISE:
+ case SND_INST_DIRECTPCM:
+ case SND_INST_DUMMY:
+ instData->param = *SND_INST_OFFSET_NORMAL(bankData, instOffset);
+ instPos->program++;
+ return TRUE;
+ case SND_INST_DRUM_TABLE:
+ drums = SND_INST_OFFSET_DRUMS(bankData, instOffset);
+ // silly programming 101: put a loop in a place that never loops
+ for (; instPos->index < drums->maxKey - drums->minKey + 1;) {
+ *instData = drums->instruments[instPos->index];
+ instPos->index++;
+ return TRUE;
+ }
+ break;
+ case SND_INST_KEY_SPLIT:
+ keySplit = SND_INST_OFFSET_KEYSPL(bankData, instOffset);
+ for (; instPos->index < SND_INST_MAX_KEYSPLIT;) {
+ if (keySplit->key[instPos->index] == 0)
+ break;
+ *instData = keySplit->instruments[instPos->index];
+ instPos->index++;
+ return TRUE;
+ }
+ break;
+ }
+
+ instPos->program++;
+ instPos->index = 0;
+ }
+ return FALSE;
+}
+
+ARM_FUNC u32 SND_GetWaveDataCount(const struct SNDWaveArc *waveArc) {
+ return waveArc->waveCount;
+}
+
+ARM_FUNC void SND_SetWaveDataAddress(struct SNDWaveArc *waveArc, s32 index, const struct SNDWaveData *waveData) {
+ SNDi_LockMutex();
+ waveArc->waveOffsets[index] = (u32)waveData;
+ DC_StoreRange(&waveArc->waveOffsets[index], sizeof(u32));
+ SNDi_UnlockMutex();
+}
+
+ARM_FUNC const struct SNDWaveData *SND_GetWaveDataAddress(const struct SNDWaveArc *waveArc, s32 index) {
+ SNDi_LockMutex();
+ u32 retval = waveArc->waveOffsets[index];
+ if (retval != 0) {
+ // < 0x2000000 aka, not a pointer to main RAM
+ if (retval < 0x2000000)
+ retval = (u32)&((u8 *)waveArc)[retval];
+ } else {
+ retval = 0;
+ }
+ SNDi_UnlockMutex();
+ return (struct SNDWaveData *)retval;
+}
diff --git a/arm9/lib/NitroSDK/src/SND_command.c b/arm9/lib/NitroSDK/src/SND_command.c
new file mode 100644
index 00000000..044d960f
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/SND_command.c
@@ -0,0 +1,333 @@
+#include "SND_alarm.h"
+#include "SND_command.h"
+#include "SND_work.h"
+#include "OS_emulator.h"
+#include "OS_system.h"
+#include "OS_cache.h"
+#include "PXI_fifo.h"
+
+#define SND_CMD_WAIT_QUEUE_COUNT 8
+
+static struct SNDCommand sCommandArray[SND_CMD_COUNT];
+static struct SNDSharedWork sSharedWork;
+static struct SNDCommand *sWaitingCommandListQueue[SND_CMD_WAIT_QUEUE_COUNT + 1]; // not sure why this is one element to large
+static struct SNDCommand *sReserveList;
+static struct SNDCommand *sReserveListEnd;
+static struct SNDCommand *sFreeListEnd;
+static s32 sWaitingCommandListQueueRead;
+static s32 sWaitingCommandListQueueWrite;
+static s32 sWaitingCommandListCount;
+static u32 sCurrentTag;
+static u32 sFinishedTag;
+static struct SNDCommand *sFreeList;
+
+static void InitPXI(void);
+static void RequestCommandProc(void);
+static struct SNDCommand *AllocCommand(void);
+static BOOL IsCommandAvailable(void);
+
+ARM_FUNC void SND_CommandInit(void) {
+ InitPXI();
+ sFreeList = sCommandArray;
+ for (int i = 0; i < SND_CMD_COUNT - 1; i++) {
+ sCommandArray[i].llNext = &sCommandArray[i+1];
+ }
+ sCommandArray[SND_CMD_COUNT - 1].llNext = NULL;
+ sFreeListEnd = &sCommandArray[SND_CMD_COUNT - 1];
+ sReserveList = NULL;
+ sReserveListEnd = NULL;
+ sWaitingCommandListCount = 0;
+ sWaitingCommandListQueueRead = 0;
+ sWaitingCommandListQueueWrite = 0;
+ sCurrentTag = 1;
+ sFinishedTag = 0;
+ SNDi_SharedWork = &sSharedWork;
+ SNDi_InitSharedWork(SNDi_SharedWork);
+
+ struct SNDCommand *cmd = SND_AllocCommand(SND_CMD_FLAG_BLOCK);
+ if (cmd == NULL)
+ return;
+
+ cmd->id = SND_CMD_SET_SHARED_WORK;
+ cmd->arg[0] = (u32)SNDi_SharedWork;
+ SND_PushCommand(cmd);
+ (void)SND_FlushCommand(SND_CMD_FLAG_BLOCK);
+}
+
+ARM_FUNC const struct SNDCommand *SND_RecvCommandReply(u32 flags) {
+ OSIntrMode oldirq = OS_DisableInterrupts();
+
+ if (flags & SND_CMD_FLAG_BLOCK) {
+ u32 tag = SNDi_GetFinishedCommandTag();
+ while (sFinishedTag == tag) {
+ (void)OS_RestoreInterrupts(oldirq);
+ OS_SpinWait(100);
+ oldirq = OS_DisableInterrupts();
+ tag = SNDi_GetFinishedCommandTag();
+ }
+ } else {
+ u32 tag = SNDi_GetFinishedCommandTag();
+ if (sFinishedTag == tag) {
+ (void)OS_RestoreInterrupts(oldirq);
+ return NULL;
+ }
+ }
+
+ struct SNDCommand *queueRead = sWaitingCommandListQueue[sWaitingCommandListQueueRead];
+
+ if (++sWaitingCommandListQueueRead > SND_CMD_WAIT_QUEUE_COUNT)
+ sWaitingCommandListQueueRead = 0;
+
+ struct SNDCommand *cur = queueRead;
+ while (cur->llNext != NULL)
+ cur = cur->llNext;
+
+ if (sFreeListEnd != NULL) {
+ sFreeListEnd->llNext = queueRead;
+ } else {
+ sFreeList = queueRead;
+ }
+
+ sFreeListEnd = cur;
+ sWaitingCommandListCount--;
+ sFinishedTag++;
+
+ (void)OS_RestoreInterrupts(oldirq);
+ return queueRead;
+}
+
+ARM_FUNC struct SNDCommand *SND_AllocCommand(u32 flags) {
+ struct SNDCommand *cmd;
+ if (!IsCommandAvailable())
+ return NULL;
+
+ cmd = AllocCommand();
+ if (cmd != NULL)
+ return cmd;
+
+ if ((flags & SND_CMD_FLAG_BLOCK) == 0)
+ return NULL;
+
+ if (SND_CountWaitingCommand() > 0) {
+ while (SND_RecvCommandReply(SND_CMD_FLAG_NOBLOCK) != NULL) { }
+
+ cmd = AllocCommand();
+ if (cmd != NULL)
+ return cmd;
+ } else {
+ (void)SND_FlushCommand(SND_CMD_FLAG_BLOCK);
+ }
+
+ RequestCommandProc();
+
+ do {
+ (void)SND_RecvCommandReply(SND_CMD_FLAG_BLOCK);
+ cmd = AllocCommand();
+ } while (cmd == NULL);
+ return cmd;
+}
+
+ARM_FUNC void SND_PushCommand(struct SNDCommand *cmd) {
+ OSIntrMode oldirq = OS_DisableInterrupts();
+
+ struct SNDCommand *newend = cmd;
+ if (sReserveListEnd == NULL) {
+ sReserveList = cmd;
+ sReserveListEnd = cmd;
+ } else {
+ sReserveListEnd->llNext = cmd;
+ sReserveListEnd = cmd;
+ }
+
+ cmd->llNext = NULL;
+
+ (void)OS_RestoreInterrupts(oldirq);
+}
+
+ARM_FUNC BOOL SND_FlushCommand(u32 flags) {
+ OSIntrMode oldirq = OS_DisableInterrupts();
+
+ if (sReserveList == NULL) {
+ (void)OS_RestoreInterrupts(oldirq);
+ return TRUE;
+ }
+
+ if (sWaitingCommandListCount >= SND_CMD_WAIT_QUEUE_COUNT) {
+ if ((flags & SND_CMD_FLAG_BLOCK) == 0) {
+ (void)OS_RestoreInterrupts(oldirq);
+ return FALSE;
+ }
+
+ do {
+ (void)SND_RecvCommandReply(SND_CMD_FLAG_BLOCK);
+ } while (sWaitingCommandListCount >= SND_CMD_WAIT_QUEUE_COUNT);
+ }
+
+ DC_FlushRange(sCommandArray, sizeof(sCommandArray));
+
+ s32 result = PXI_SendWordByFifo(7, (u32)sReserveList, 0);
+ if (result < 0) {
+ if ((flags & SND_CMD_FLAG_BLOCK) == 0) {
+ (void)OS_RestoreInterrupts(oldirq);
+ return FALSE;
+ }
+
+ result = PXI_SendWordByFifo(7, (u32)sReserveList, 0);
+ while (result < 0) {
+ (void)OS_RestoreInterrupts(oldirq);
+ OS_SpinWait(100);
+ oldirq = OS_DisableInterrupts();
+ result = PXI_SendWordByFifo(7, (u32)sReserveList, 0);
+ }
+ }
+
+ if ((flags & SND_CMD_FLAG_IMMEDIATE) != 0) {
+ RequestCommandProc();
+ }
+
+ sWaitingCommandListQueue[sWaitingCommandListQueueWrite] = sReserveList;
+
+ if (++sWaitingCommandListQueueWrite > SND_CMD_WAIT_QUEUE_COUNT) {
+ sWaitingCommandListQueueWrite = 0;
+ }
+
+ sReserveList = NULL;
+ sReserveListEnd = NULL;
+ sWaitingCommandListCount++;
+ sCurrentTag++;
+
+ (void)OS_RestoreInterrupts(oldirq);
+ return TRUE;
+}
+
+ARM_FUNC void SND_WaitForCommandProc(u32 tag) {
+ if (SND_IsFinishedCommandTag(tag))
+ return;
+
+ while (SND_RecvCommandReply(SND_CMD_FLAG_NOBLOCK) != NULL) { }
+
+ if (SND_IsFinishedCommandTag(tag))
+ return;
+
+ RequestCommandProc();
+
+ if (SND_IsFinishedCommandTag(tag))
+ return;
+
+ do {
+ (void)SND_RecvCommandReply(SND_CMD_FLAG_BLOCK);
+ } while (SND_IsFinishedCommandTag(tag) == 0);
+}
+
+ARM_FUNC u32 SND_GetCurrentCommandTag(void) {
+ OSIntrMode oldirq = OS_DisableInterrupts();
+
+ u32 retval;
+ if (sReserveList == NULL)
+ retval = sFinishedTag;
+ else
+ retval = sCurrentTag;
+
+ (void)OS_RestoreInterrupts(oldirq);
+ return retval;
+}
+
+ARM_FUNC BOOL SND_IsFinishedCommandTag(u32 tag) {
+ OSIntrMode oldirq = OS_DisableInterrupts();
+
+ BOOL result;
+ if (tag > sFinishedTag) {
+ if (tag - sFinishedTag < 0x80000000)
+ result = FALSE;
+ else
+ result = TRUE;
+ } else {
+ if (sFinishedTag - tag < 0x80000000)
+ result = TRUE;
+ else
+ result = FALSE;
+ }
+
+ (void)OS_RestoreInterrupts(oldirq);
+ return result;
+}
+
+ARM_FUNC s32 SND_CountFreeCommand(void) {
+ OSIntrMode oldirq = OS_DisableInterrupts();
+
+ s32 count = 0;
+ for (struct SNDCommand *cmd = sFreeList; cmd != NULL; cmd = cmd->llNext)
+ count++;
+
+ (void)OS_RestoreInterrupts(oldirq);
+ return count;
+}
+
+ARM_FUNC s32 SND_CountReservedCommand(void) {
+ OSIntrMode oldirq = OS_DisableInterrupts();
+
+ s32 count = 0;
+ for (struct SNDCommand *cmd = sReserveList; cmd != NULL; cmd = cmd->llNext)
+ count++;
+
+ (void)OS_RestoreInterrupts(oldirq);
+ return count;
+}
+
+ARM_FUNC s32 SND_CountWaitingCommand(void) {
+ return SND_CMD_COUNT - SND_CountFreeCommand() - SND_CountReservedCommand();
+}
+
+ARM_FUNC static void PxiFifoCallback(PXIFifoTag tag, u32 data, BOOL) {
+#pragma unused (tag)
+ OSIntrMode oldirq = OS_DisableInterrupts();
+ SNDi_CallAlarmHandler((s32)data);
+ (void)OS_RestoreInterrupts(oldirq);
+}
+
+ARM_FUNC static void InitPXI(void) {
+ PXI_SetFifoRecvCallback(PXI_FIFO_TAG_SOUND, PxiFifoCallback);
+
+ if (!IsCommandAvailable())
+ return;
+
+ if (PXI_IsCallbackReady(PXI_FIFO_TAG_SOUND, PXI_PROC_ARM7))
+ return;
+
+ do {
+ OS_SpinWait(100);
+ } while (!PXI_IsCallbackReady(PXI_FIFO_TAG_SOUND, PXI_PROC_ARM7));
+}
+
+ARM_FUNC static void RequestCommandProc(void) {
+ while (PXI_SendWordByFifo(7, 0, 0) < 0) { }
+}
+
+ARM_FUNC static struct SNDCommand *AllocCommand(void) {
+ OSIntrMode oldirq = OS_DisableInterrupts();
+ if (sFreeList == NULL) {
+ (void)OS_RestoreInterrupts(oldirq);
+ return NULL;
+ }
+
+ struct SNDCommand *retval = sFreeList;
+
+ sFreeList = sFreeList->llNext;
+ if (sFreeList == NULL)
+ sFreeListEnd = NULL;
+ (void)OS_RestoreInterrupts(oldirq);
+ return retval;
+}
+
+ARM_FUNC static BOOL IsCommandAvailable(void) {
+ if (!OS_IsRunOnEmulator())
+ return TRUE;
+
+ OSIntrMode oldirq = OS_DisableInterrupts();
+ // TODO use proper register names here
+ // is this some kind of debug or ensata register?
+ *(vu32 *)0x4FFF200 = 0x10;
+ u32 resp = *(vu32 *)0x4FFF200;
+ (void)OS_RestoreInterrupts(oldirq);
+ return resp != 0;
+}
diff --git a/arm9/lib/NitroSDK/src/SND_interface.c b/arm9/lib/NitroSDK/src/SND_interface.c
new file mode 100644
index 00000000..42b5ff42
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/SND_interface.c
@@ -0,0 +1,172 @@
+#include "SND_interface.h"
+#include "SND_command.h"
+
+static void PushCommand_impl(s32 id, u32 par1, u32 par2, u32 par3, u32 par4);
+#define PushCmd1(id, a) PushCommand_impl(id, (u32)(a), 0, 0, 0)
+#define PushCmd2(id, a, b) PushCommand_impl(id, (u32)(a), (u32)(b), 0, 0)
+#define PushCmd3(id, a, b, c) PushCommand_impl(id, (u32)(a), (u32)(b), (u32)(c), 0)
+#define PushCmd4(id, a, b, c, d) PushCommand_impl(id, (u32)(a), (u32)(b), (u32)(c), (u32)(d))
+
+// TODO fill in "random" constants with macros
+
+// ARM_FUNC void SND_StartSeq(s32 player, const void *seqBasePtr, u32 seqOffset, struct SNDBankData *bankData) { }
+
+ARM_FUNC void SND_StopSeq(s32 player) {
+ PushCmd1(SND_CMD_STOP_SEQ, player);
+}
+
+ARM_FUNC void SND_PrepareSeq(s32 player, const void *seqBasePtr, u32 seqOffset, struct SNDBankData *bankData) {
+ PushCmd4(SND_CMD_PREPARE_SEQ, player, seqBasePtr, seqOffset, bankData);
+}
+
+ARM_FUNC void SND_StartPreparedSeq(s32 player) {
+ PushCmd1(SND_CMD_START_PREPARED_SEQ, player);
+}
+
+ARM_FUNC void SND_PauseSeq(s32 player, BOOL flag) {
+ PushCmd2(SND_CMD_PAUSE_SEQ, player, flag);
+}
+
+// ARM_FUNC void SND_SetPlayerTempoRatio(s32 player, s32 ratio) { }
+
+ARM_FUNC void SND_SetPlayerVolume(s32 player, s32 volume) {
+ SNDi_SetPlayerParam(player, 6, (u32)volume, 2);
+}
+
+ARM_FUNC void SND_SetPlayerChannelPriority(s32 player, s32 prio) {
+ SNDi_SetPlayerParam(player, 4, (u32)prio, 1);
+}
+
+// ARM_FUNC void SND_SetPlayerLocalVariable(s32 player, s32 varNo, s16 var) { }
+
+// ARM_FUNC void SND_SetPlayerGlobalVariable(s32 varNo, s16 var) { }
+
+// ARM_FUNC void SND_SetTrackVolume(s32 player, u32 trackBitMask, s32 volume) { }
+
+ARM_FUNC void SND_SetTrackPitch(s32 player, u32 trackBitMask, s32 pitch) {
+ SNDi_SetTrackParam(player, trackBitMask, 12, (u32)pitch, 2);
+}
+
+ARM_FUNC void SND_SetTrackPan(s32 player, u32 trackBitMask, s32 pan) {
+ SNDi_SetTrackParam(player, trackBitMask, 9, (u32)pan, 1);
+}
+
+ARM_FUNC void SND_SetTrackAllocatableChannel(s32 player, u32 trackBitMask, u32 chnBitMask) {
+ PushCmd3(SND_CMD_ALLOCATABLE_CHANNEL, player, trackBitMask, chnBitMask);
+}
+
+ARM_FUNC void SND_StartTimer(u32 chnBitMask, u32 capBitMask, u32 alarmBitMask, u32 flags) {
+ PushCmd4(SND_CMD_START_TIMER, chnBitMask, capBitMask, alarmBitMask, flags);
+}
+
+ARM_FUNC void SND_StopTimer(u32 chnBitMask, u32 capBitMask, u32 alarmBitMask, u32 flags) {
+ s32 i = 0;
+ u32 tmpMask = alarmBitMask;
+
+ while (i < SND_ALARM_COUNT && tmpMask != 0) {
+ if (tmpMask & 1)
+ SNDi_IncAlarmId((u32)i);
+ i++;
+ tmpMask >>= 1;
+ }
+
+ PushCmd4(SND_CMD_STOP_TIMER, chnBitMask, capBitMask, alarmBitMask, flags);
+}
+
+ARM_FUNC void SND_SetupCapture(s32 capture, s32 format, void *bufferPtr, u32 length, BOOL loopFlag, s32 in, s32 out) {
+ PushCmd3(SND_CMD_SETUP_CAPTURE, bufferPtr, length,
+ (capture << 31) | (format << 30) | (loopFlag << 29) | (in << 28) | (out << 27));
+}
+
+ARM_FUNC void SND_SetupAlarm(s32 alarm, u32 tick, u32 period, SNDAlarmCallback cb, void *userData) {
+ PushCmd4(SND_CMD_SETUP_ALARM, alarm, tick, period, SNDi_SetAlarmHandler((u32)alarm, cb, userData));
+}
+
+// ARM_FUNC void SND_SetTrackMute(s32 player, u32 trackBitMask, BOOL flag) { }
+
+// ARM_FUNC void SND_StopUnlockedChannel(u32 chnBitMask, u32 flags) { }
+
+ARM_FUNC void SND_LockChannel(u32 chnBitMask, u32 flags) {
+ PushCmd2(SND_CMD_LOCK_CHANNEL, chnBitMask, flags);
+}
+
+ARM_FUNC void SND_UnlockChannel(u32 chnBitMask, u32 flags) {
+ PushCmd2(SND_CMD_UNLOCK_CHANNEL, chnBitMask, flags);
+}
+
+ARM_FUNC void SND_SetChannelTimer(u32 chnBitMask, s32 timer) {
+ PushCmd2(SND_CMD_CHANNEL_TIMER, chnBitMask, timer);
+}
+
+ARM_FUNC void SND_SetChannelVolume(u32 chnBitMask, s32 volume, s32 chnDataShift) {
+ PushCmd3(SND_CMD_CHANNEL_VOLUME, chnBitMask, volume, chnDataShift);
+}
+
+ARM_FUNC void SND_SetChannelPan(u32 chnBitMask, s32 pan) {
+ PushCmd2(SND_CMD_CHANNEL_PAN, chnBitMask, pan);
+}
+
+ARM_FUNC void SND_SetupChannelPcm(s32 chn, s32 waveFormat, const void *dataAddr, s32 loopMode, s32 loopStart, s32 dataLen, s32 volume, s32 chnDataShift, s32 timer, s32 pan) {
+ PushCmd4(SND_CMD_SETUP_CHANNEL_PCM,
+ chn | (timer << 16),
+ dataAddr,
+ (volume << 24) | (chnDataShift << 22) | dataLen,
+ (loopMode << 26) | (waveFormat << 24) | (pan << 16) | loopStart);
+}
+
+// ARM_FUNC void SND_SetupChannelPsg(s32 chn, s32 sndDuty, s32 volume, s32 chnDataShift, s32 timer, s32 pan) { }
+
+// ARM_FUNC void SND_SetupChannelNoise(s32 chn, s32 volume, s32 chnDataShift, s32 timer, s32 pan) { }
+
+ARM_FUNC void SND_InvalidateSeqData(const void *start, const void *end) {
+ PushCmd2(SND_CMD_INVALIDATE_SEQ, start, end);
+}
+
+ARM_FUNC void SND_InvalidateBankData(const void *start, const void *end) {
+ PushCmd2(SND_CMD_INVALIDATE_BANK, start, end);
+}
+
+ARM_FUNC void SND_InvalidateWaveData(const void *start, const void *end) {
+ PushCmd2(SND_CMD_INVALIDATE_WAVE, start, end);
+}
+
+// ARM_FUNC void SND_SetMasterVolume(s32 volume) { }
+
+ARM_FUNC void SND_SetOutputSelector(s32 left, s32 right, s32 channel1, s32 channel3) {
+ PushCmd4(SND_CMD_OUTPUT_SELECTOR, left, right, channel1, channel3);
+}
+
+ARM_FUNC void SND_SetMasterPan(s32 pan) {
+ PushCmd1(SND_CMD_MASTER_PAN, pan);
+}
+
+ARM_FUNC void SND_ResetMasterPan(void) {
+ PushCmd1(SND_CMD_MASTER_PAN, -1);
+}
+
+// ARM_FUNC void SND_ReadDriverInfo(struct SNDDriverInfo *info) { }
+
+ARM_FUNC void SNDi_SetPlayerParam(s32 player, u32 offset, u32 data, s32 size) {
+ PushCmd4(SND_CMD_PLAYER_PARAM, player, offset, data, size);
+}
+
+ARM_FUNC void SNDi_SetTrackParam(s32 player, u32 trackBitMask, u32 offset, u32 data, s32 size) {
+ PushCmd4(SND_CMD_TRACK_PARAM, player | (size << 24), trackBitMask, offset, data);
+}
+
+// ARM_FUNC void SNDi_SetSurroundDecay(s32 decay) { }
+
+// ARM_FUNC void SNDi_SkipSeq(s32 player, u32 tick) { }
+
+ARM_FUNC static void PushCommand_impl(s32 id, u32 par1, u32 par2, u32 par3, u32 par4) {
+ struct SNDCommand *cmd = SND_AllocCommand(SND_CMD_FLAG_BLOCK);
+ if (cmd == NULL)
+ return;
+
+ cmd->id = id;
+ cmd->arg[0] = par1;
+ cmd->arg[1] = par2;
+ cmd->arg[2] = par3;
+ cmd->arg[3] = par4;
+ SND_PushCommand(cmd);
+}
diff --git a/arm9/lib/NitroSDK/src/SND_main.c b/arm9/lib/NitroSDK/src/SND_main.c
new file mode 100644
index 00000000..f97b0873
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/SND_main.c
@@ -0,0 +1,26 @@
+#include "SND_main.h"
+#include "SND_command.h"
+#include "SND_alarm.h"
+
+#include "global.h"
+#include "OS_mutex.h"
+
+static struct OSMutex sSndMutex;
+static s32 sSndInitialized;
+
+ARM_FUNC void SND_Init(void) {
+ if (sSndInitialized)
+ return;
+ sSndInitialized = 1;
+ OS_InitMutex(&sSndMutex);
+ SND_CommandInit();
+ SND_AlarmInit();
+}
+
+ARM_FUNC void SNDi_LockMutex(void) {
+ OS_LockMutex(&sSndMutex);
+}
+
+ARM_FUNC void SNDi_UnlockMutex(void) {
+ OS_UnlockMutex(&sSndMutex);
+}
diff --git a/arm9/lib/NitroSDK/src/SND_util.c b/arm9/lib/NitroSDK/src/SND_util.c
new file mode 100644
index 00000000..6ff8cb14
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/SND_util.c
@@ -0,0 +1,238 @@
+#include "SND_util.h"
+
+// not used in pokediamond
+//static const u16 sPitchTable[0x600] = {
+// 0x0000, 0x003B, 0x0076, 0x00B2, 0x00ED, 0x0128, 0x0164, 0x019f,
+// 0x01DB, 0x0217, 0x0252, 0x028E, 0x02CA, 0x0305, 0x0341, 0x037D,
+// 0x03B9, 0x03F5, 0x0431, 0x046E, 0x04AA, 0x04E6, 0x0522, 0x055F,
+// 0x059B, 0x05D8, 0x0614, 0x0651, 0x068D, 0x06CA, 0x0707, 0x0743,
+// 0x0780, 0x07BD, 0x07FA, 0x0837, 0x0874, 0x08B1, 0x08EF, 0x092C,
+// 0x0969, 0x09A7, 0x09E4, 0x0A21, 0x0A5F, 0x0A9C, 0x0ADA, 0x0B18,
+// 0x0B56, 0x0B93, 0x0BD1, 0x0C0F, 0x0C4D, 0x0C8B, 0x0CC9, 0x0D07,
+// 0x0D45, 0x0D84, 0x0DC2, 0x0E00, 0x0E3F, 0x0E7D, 0x0EBC, 0x0EFA,
+// 0x0F39, 0x0F78, 0x0FB6, 0x0FF5, 0x1034, 0x1073, 0x10B2, 0x10F1,
+// 0x1130, 0x116F, 0x11AE, 0x11EE, 0x122D, 0x126C, 0x12AC, 0x12EB,
+// 0x132B, 0x136B, 0x13AA, 0x13EA, 0x142A, 0x146A, 0x14A9, 0x14E9,
+// 0x1529, 0x1569, 0x15AA, 0x15EA, 0x162A, 0x166A, 0x16AB, 0x16EB,
+// 0x172C, 0x176C, 0x17AD, 0x17ED, 0x182E, 0x186F, 0x18B0, 0x18F0,
+// 0x1931, 0x1972, 0x19B3, 0x19F5, 0x1A36, 0x1A77, 0x1AB8, 0x1AFA,
+// 0x1B3B, 0x1B7D, 0x1BBE, 0x1C00, 0x1C41, 0x1C83, 0x1CC5, 0x1D07,
+// 0x1D48, 0x1D8A, 0x1DCC, 0x1E0E, 0x1E51, 0x1E93, 0x1ED5, 0x1F17,
+// 0x1F5A, 0x1F9C, 0x1FDF, 0x2021, 0x2064, 0x20A6, 0x20E9, 0x212C,
+// 0x216F, 0x21B2, 0x21F5, 0x2238, 0x227B, 0x22BE, 0x2301, 0x2344,
+// 0x2388, 0x23CB, 0x240E, 0x2452, 0x2496, 0x24D9, 0x251D, 0x2561,
+// 0x25A4, 0x25E8, 0x262C, 0x2670, 0x26B4, 0x26F8, 0x273D, 0x2781,
+// 0x27C5, 0x280A, 0x284E, 0x2892, 0x28D7, 0x291C, 0x2960, 0x29A5,
+// 0x29EA, 0x2A2F, 0x2A74, 0x2AB9, 0x2AFE, 0x2B43, 0x2B88, 0x2BCD,
+// 0x2C13, 0x2C58, 0x2C9D, 0x2CE3, 0x2D28, 0x2D6E, 0x2DB4, 0x2DF9,
+// 0x2E3F, 0x2E85, 0x2ECB, 0x2F11, 0x2F57, 0x2F9D, 0x2FE3, 0x302A,
+// 0x3070, 0x30B6, 0x30FD, 0x3143, 0x318A, 0x31D0, 0x3217, 0x325E,
+// 0x32A5, 0x32EC, 0x3332, 0x3379, 0x33C1, 0x3408, 0x344F, 0x3496,
+// 0x34DD, 0x3525, 0x356C, 0x35B4, 0x35FB, 0x3643, 0x368B, 0x36D3,
+// 0x371A, 0x3762, 0x37AA, 0x37F2, 0x383A, 0x3883, 0x38CB, 0x3913,
+// 0x395C, 0x39A4, 0x39ED, 0x3A35, 0x3A7E, 0x3AC6, 0x3B0F, 0x3B58,
+// 0x3BA1, 0x3BEA, 0x3C33, 0x3C7C, 0x3CC5, 0x3D0E, 0x3D58, 0x3DA1,
+// 0x3DEA, 0x3E34, 0x3E7D, 0x3EC7, 0x3F11, 0x3F5A, 0x3FA4, 0x3FEE,
+// 0x4038, 0x4082, 0x40CC, 0x4116, 0x4161, 0x41AB, 0x41F5, 0x4240,
+// 0x428A, 0x42D5, 0x431F, 0x436A, 0x43B5, 0x4400, 0x444B, 0x4495,
+// 0x44E1, 0x452C, 0x4577, 0x45C2, 0x460D, 0x4659, 0x46A4, 0x46F0,
+// 0x473B, 0x4787, 0x47D3, 0x481E, 0x486A, 0x48B6, 0x4902, 0x494E,
+// 0x499A, 0x49E6, 0x4A33, 0x4A7F, 0x4ACB, 0x4B18, 0x4B64, 0x4BB1,
+// 0x4BFE, 0x4C4A, 0x4C97, 0x4CE4, 0x4D31, 0x4D7E, 0x4DCB, 0x4E18,
+// 0x4E66, 0x4EB3, 0x4F00, 0x4F4E, 0x4F9B, 0x4FE9, 0x5036, 0x5084,
+// 0x50D2, 0x5120, 0x516E, 0x51BC, 0x520A, 0x5258, 0x52A6, 0x52F4,
+// 0x5343, 0x5391, 0x53E0, 0x542E, 0x547D, 0x54CC, 0x551A, 0x5569,
+// 0x55B8, 0x5607, 0x5656, 0x56A5, 0x56F4, 0x5744, 0x5793, 0x57E2,
+// 0x5832, 0x5882, 0x58D1, 0x5921, 0x5971, 0x59C1, 0x5A10, 0x5A60,
+// 0x5AB0, 0x5B01, 0x5B51, 0x5BA1, 0x5BF1, 0x5C42, 0x5C92, 0x5CE3,
+// 0x5D34, 0x5D84, 0x5DD5, 0x5E26, 0x5E77, 0x5EC8, 0x5F19, 0x5F6A,
+// 0x5FBB, 0x600D, 0x605E, 0x60B0, 0x6101, 0x6153, 0x61A4, 0x61F6,
+// 0x6248, 0x629A, 0x62EC, 0x633E, 0x6390, 0x63E2, 0x6434, 0x6487,
+// 0x64D9, 0x652C, 0x657E, 0x65D1, 0x6624, 0x6676, 0x66C9, 0x671C,
+// 0x676F, 0x67C2, 0x6815, 0x6869, 0x68BC, 0x690F, 0x6963, 0x69B6,
+// 0x6A0A, 0x6A5E, 0x6AB1, 0x6B05, 0x6B59, 0x6BAD, 0x6C01, 0x6C55,
+// 0x6CAA, 0x6CFE, 0x6D52, 0x6DA7, 0x6DFB, 0x6E50, 0x6EA4, 0x6EF9,
+// 0x6F4E, 0x6FA3, 0x6FF8, 0x704D, 0x70A2, 0x70F7, 0x714D, 0x71A2,
+// 0x71F7, 0x724D, 0x72A2, 0x72F8, 0x734E, 0x73A4, 0x73FA, 0x7450,
+// 0x74A6, 0x74FC, 0x7552, 0x75A8, 0x75FF, 0x7655, 0x76AC, 0x7702,
+// 0x7759, 0x77B0, 0x7807, 0x785E, 0x78B4, 0x790C, 0x7963, 0x79BA,
+// 0x7A11, 0x7A69, 0x7AC0, 0x7B18, 0x7B6F, 0x7BC7, 0x7C1F, 0x7C77,
+// 0x7CCF, 0x7D27, 0x7D7F, 0x7DD7, 0x7E2F, 0x7E88, 0x7EE0, 0x7F38,
+// 0x7F91, 0x7FEA, 0x8042, 0x809B, 0x80F4, 0x814D, 0x81A6, 0x81FF,
+// 0x8259, 0x82B2, 0x830B, 0x8365, 0x83BE, 0x8418, 0x8472, 0x84CB,
+// 0x8525, 0x857F, 0x85D9, 0x8633, 0x868E, 0x86E8, 0x8742, 0x879D,
+// 0x87F7, 0x8852, 0x88AC, 0x8907, 0x8962, 0x89BD, 0x8A18, 0x8A73,
+// 0x8ACE, 0x8B2A, 0x8B85, 0x8BE0, 0x8C3C, 0x8C97, 0x8CF3, 0x8D4F,
+// 0x8DAB, 0x8E07, 0x8E63, 0x8EBF, 0x8F1B, 0x8F77, 0x8FD4, 0x9030,
+// 0x908C, 0x90E9, 0x9146, 0x91A2, 0x91FF, 0x925C, 0x92B9, 0x9316,
+// 0x9373, 0x93D1, 0x942E, 0x948C, 0x94E9, 0x9547, 0x95A4, 0x9602,
+// 0x9660, 0x96BE, 0x971C, 0x977A, 0x97D8, 0x9836, 0x9895, 0x98F3,
+// 0x9952, 0x99B0, 0x9A0F, 0x9A6E, 0x9ACD, 0x9B2C, 0x9B8B, 0x9BEA,
+// 0x9C49, 0x9CA8, 0x9D08, 0x9D67, 0x9DC7, 0x9E26, 0x9E86, 0x9EE6,
+// 0x9F46, 0x9FA6, 0xA006, 0xA066, 0xA0C6, 0xA127, 0xA187, 0xA1E8,
+// 0xA248, 0xA2A9, 0xA30A, 0xA36B, 0xA3CC, 0xA42D, 0xA48E, 0xA4EF,
+// 0xA550, 0xA5B2, 0xA613, 0xA675, 0xA6D6, 0xA738, 0xA79A, 0xA7FC,
+// 0xA85E, 0xA8C0, 0xA922, 0xA984, 0xA9E7, 0xAA49, 0xAAAC, 0xAB0E,
+// 0xAB71, 0xABD4, 0xAC37, 0xAC9A, 0xACFD, 0xAD60, 0xADC3, 0xAE27,
+// 0xAE8A, 0xAEED, 0xAF51, 0xAFB5, 0xB019, 0xB07C, 0xB0E0, 0xB145,
+// 0xB1A9, 0xB20D, 0xB271, 0xB2D6, 0xB33A, 0xB39F, 0xB403, 0xB468,
+// 0xB4CD, 0xB532, 0xB597, 0xB5FC, 0xB662, 0xB6C7, 0xB72C, 0xB792,
+// 0xB7F7, 0xB85D, 0xB8C3, 0xB929, 0xB98F, 0xB9F5, 0xBA5B, 0xBAC1,
+// 0xBB28, 0xBB8E, 0xBBF5, 0xBC5B, 0xBCC2, 0xBD29, 0xBD90, 0xBDF7,
+// 0xBE5E, 0xBEC5, 0xBF2C, 0xBF94, 0xBFFB, 0xC063, 0xC0CA, 0xC132,
+// 0xC19A, 0xC202, 0xC26A, 0xC2D2, 0xC33A, 0xC3A2, 0xC40B, 0xC473,
+// 0xC4DC, 0xC544, 0xC5AD, 0xC616, 0xC67F, 0xC6E8, 0xC751, 0xC7BB,
+// 0xC824, 0xC88D, 0xC8F7, 0xC960, 0xC9CA, 0xCA34, 0xCA9E, 0xCB08,
+// 0xCB72, 0xCBDC, 0xCC47, 0xCCB1, 0xCD1B, 0xCD86, 0xCDF1, 0xCE5B,
+// 0xCEC6, 0xCF31, 0xCF9C, 0xD008, 0xD073, 0xD0DE, 0xD14A, 0xD1B5,
+// 0xD221, 0xD28D, 0xD2F8, 0xD364, 0xD3D0, 0xD43D, 0xD4A9, 0xD515,
+// 0xD582, 0xD5EE, 0xD65B, 0xD6C7, 0xD734, 0xD7A1, 0xD80E, 0xD87B,
+// 0xD8E9, 0xD956, 0xD9C3, 0xDA31, 0xDA9E, 0xDB0C, 0xDB7A, 0xDBE8,
+// 0xDC56, 0xDCC4, 0xDD32, 0xDDA0, 0xDE0F, 0xDE7D, 0xDEEC, 0xDF5B,
+// 0xDFC9, 0xE038, 0xE0A7, 0xE116, 0xE186, 0xE1F5, 0xE264, 0xE2D4,
+// 0xE343, 0xE3B3, 0xE423, 0xE493, 0xE503, 0xE573, 0xE5E3, 0xE654,
+// 0xE6C4, 0xE735, 0xE7A5, 0xE816, 0xE887, 0xE8F8, 0xE969, 0xE9DA,
+// 0xEA4B, 0xEABC, 0xEB2E, 0xEB9F, 0xEC11, 0xEC83, 0xECF5, 0xED66,
+// 0xEDD9, 0xEE4B, 0xEEBD, 0xEF2F, 0xEFA2, 0xF014, 0xF087, 0xF0FA,
+// 0xF16D, 0xF1E0, 0xF253, 0xF2C6, 0xF339, 0xF3AD, 0xF420, 0xF494,
+// 0xF507, 0xF57B, 0xF5EF, 0xF663, 0xF6D7, 0xF74C, 0xF7C0, 0xF834,
+// 0xF8A9, 0xF91E, 0xF992, 0xFA07, 0xFA7C, 0xFAF1, 0xFB66, 0xFBDC,
+// 0xFC51, 0xFCC7, 0xFD3C, 0xFDB2, 0xFE28, 0xFE9E, 0xFF14, 0xFF8A,
+//};
+
+static const u8 sVolumeTable[724] = {
+ 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, 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, 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, 3, 3, 3, 3,
+ 4, 4, 4, 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, 5, 6, 6, 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, 8, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xB,
+ 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xC, 0xC, 0xC, 0xC,
+ 0xC, 0xC, 0xC, 0xC, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xE,
+ 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0xF, 0xF, 0xF, 0xF, 0xF,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13,
+ 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15,
+ 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17,
+ 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1A,
+ 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C, 0x1D,
+ 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x20,
+ 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23,
+ 0x24, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
+ 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
+ 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30,
+ 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x35, 0x35,
+ 0x36, 0x36, 0x37, 0x38, 0x38, 0x39, 0x3A, 0x3A, 0x3B,
+ 0x3C, 0x3C, 0x3D, 0x3E, 0x3F, 0x3F, 0x40, 0x41, 0x42,
+ 0x42, 0x43, 0x44, 0x45, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4A, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
+ 0x52, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5A, 0x5B, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63,
+ 0x64, 0x65, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6D, 0x6E,
+ 0x6F, 0x71, 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A,
+ 0x7B, 0x7D, 0x7E, 0x7F, 0x20, 0x21, 0x21, 0x21, 0x22,
+ 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x26,
+ 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A,
+ 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E,
+ 0x2F, 0x2F, 0x30, 0x30, 0x31, 0x31, 0x32, 0x33, 0x33,
+ 0x34, 0x34, 0x35, 0x36, 0x36, 0x37, 0x37, 0x38, 0x39,
+ 0x39, 0x3A, 0x3B, 0x3B, 0x3C, 0x3D, 0x3E, 0x3E, 0x3F,
+ 0x40, 0x40, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46,
+ 0x47, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4D,
+ 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
+ 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6A,
+ 0x6B, 0x6C, 0x6D, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x75,
+ 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7E, 0x7E, 0x40, 0x41,
+ 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x48,
+ 0x49, 0x4A, 0x4B, 0x4C, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
+ 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62,
+ 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
+ 0x6E, 0x70, 0x71, 0x72, 0x74, 0x75, 0x76, 0x78, 0x79,
+ 0x7B, 0x7C, 0x7D, 0x7E, 0x40, 0x41, 0x42, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+ 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C,
+ 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x65, 0x66,
+ 0x67, 0x68, 0x69, 0x6A, 0x6C, 0x6D, 0x6E, 0x6F, 0x71,
+ 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A, 0x7C, 0x7D,
+ 0x7E, 0x7F,
+};
+
+const s16 SNDi_DecibelTable[0x80] = {
+ -32768,-421,-361, -325, -300, -281, -265, -252,
+ -240, -230, -221, -212, -205, -198, -192, -186,
+ -180, -175, -170, -165, -161, -156, -152, -148,
+ -145, -141, -138, -134, -131, -128, -125, -122,
+ -120, -117, -114, -112, -110, -107, -105, -103,
+ -100, -98, -96, -94, -92, -90, -88, -86,
+ -85, -83, -81, -79, -78, -76, -74, -73,
+ -71, -70, -68, -67, -65, -64, -62, -61,
+ -60, -58, -57, -56, -54, -53, -52, -51,
+ -49, -48, -47, -46, -45, -43, -42, -41,
+ -40, -39, -38, -37, -36, -35, -34, -33,
+ -32, -31, -30, -29, -28, -27, -26, -25,
+ -24, -23, -23, -22, -21, -20, -19, -18,
+ -17, -17, -16, -15, -14, -13, -12, -12,
+ -11, -10, -9, -9, -8, -7, -6, -6,
+ -5, -4, -3, -3, -2, -1, -1, 0,
+};
+
+// not used in pokediamond
+//const s16 SNDi_DecibelSquareTable[0x80] = {
+// -32768,-722,-721, -651, -601, -562, -530, -503,
+// -480, -460, -442, -425, -410, -396, -383, -371,
+// -360, -349, -339, -330, -321, -313, -305, -297,
+// -289, -282, -276, -269, -263, -257, -251, -245,
+// -239, -234, -229, -224, -219, -214, -210, -205,
+// -201, -196, -192, -188, -184, -180, -176, -173,
+// -169, -165, -162, -158, -155, -152, -149, -145,
+// -142, -139, -136, -133, -130, -127, -125, -122,
+// -119, -116, -114, -111, -109, -106, -103, -101,
+// -99, -96, -94, -91, -89, -87, -85, -82,
+// -80, -78, -76, -74, -72, -70, -68, -66,
+// -64, -62, -60, -58, -56, -54, -52, -50,
+// -49, -47, -45, -43, -42, -40, -38, -36,
+// -35, -33, -31, -30, -28, -27, -25, -23,
+// -22, -20, -19, -17, -16, -14, -13, -11,
+// -10, -8, -7, -6, -4, -3, -1, 0,
+//};
+
+ARM_FUNC u16 SND_CalcChannelVolume(s32 x) {
+ // directly using s32 doesn't match
+ int decibels = (int)x;
+ if (decibels < -723)
+ decibels = -723;
+ else if (decibels > 0)
+ decibels = 0;
+
+ u32 resultLo = sVolumeTable[decibels + 723];
+ u32 resultHi;
+
+ if (decibels < -240) {
+ resultHi = 3;
+ } else {
+ if (decibels < -120) {
+ resultHi = 2;
+ } else {
+ if (decibels < -60) {
+ resultHi = 1;
+ } else {
+ resultHi = 0;
+ }
+ }
+ }
+
+ return (u16)((resultHi << 8u) | resultLo);
+}
diff --git a/arm9/lib/NitroSDK/src/SND_work.c b/arm9/lib/NitroSDK/src/SND_work.c
new file mode 100644
index 00000000..ca9208d6
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/SND_work.c
@@ -0,0 +1,113 @@
+#include "SND_work.h"
+#include "SND_alarm.h"
+#include "SND_main.h"
+#include "OS_cache.h"
+
+struct SNDSharedWork *SNDi_SharedWork;
+
+u32 SND_GetPlayerStatus(void) {
+ DC_InvalidateRange(&SNDi_SharedWork->playerStatus, 4);
+ return SNDi_SharedWork->playerStatus;
+}
+
+u16 SND_GetChannelStatus(void) {
+ DC_InvalidateRange(&SNDi_SharedWork->channelStatus, 2);
+ return SNDi_SharedWork->channelStatus;
+}
+
+//u16 SND_GetCaptureStatus(void) {
+// DC_InvalidateRange(&SNDi_SharedWork->captureStatus, 2);
+// return SNDi_SharedWork->captureStatus;
+//}
+
+u32 SND_GetPlayerTickCounter(u32 playerId) {
+ DC_InvalidateRange(&SNDi_SharedWork->players[playerId].tickCounter, 4);
+ return SNDi_SharedWork->players[playerId].tickCounter;
+}
+
+//s16 SND_GetPlayerLocalVariable(u32 playerId, u32 var) {
+// DC_InvalidateRange(&SNDi_SharedWork->players[playerId].localVars[var], 2);
+// return SNDi_SharedWork->players[playerId].localVars[var];
+//}
+//
+//s16 SND_GetPlayerLocalVariable(u32 var) {
+// DC_InvalidateRange(&SNDi_SharedWork->globalVars[var], 2);
+// return SNDi_SharedWork->globalVars[var];
+//}
+//
+//BOOL SND_ReadChannelInfo(const SNDDriverInfo *driverInfo, s32 chnId, SNDChannelInfo *chnInfo) {
+// // T O D O, implement if it's actually used
+//}
+//
+//BOOL SND_ReadPlayerInfo(const SNDDriverInfo *driverInfo, s32 playerId, SNDPlayerInfo *playerInfo) {
+// if (playerId < 0 || playerId >= SND_PLAYER_COUNT)
+// return FALSE;
+// SNDPlayer *player = &driverInfo->work.players[playerId];
+// playerInfo->trackBitMask = 0;
+// for (s32 i = 0; i < SND_TRACK_COUNT; i++) {
+// if (player->tracks[i] != SND_INVALID_TRACK_INDEX) {
+// playerInfo->trackBitMask |= (1 << i);
+// }
+// }
+// playerInfo->flags.active = player->flags.active;
+// playerInfo->flags.paused = player->flags.paused;
+// playerInfo->tempo = player->tempo;
+// playerInfo->volume = player->volume;
+// return TRUE;
+//}
+//
+//
+//BOOL SND_ReadTrackInfo(const SNDDriverInfo *driverInfo s32 playerId, s32 trackId, SNDTrackInfo *trackInfo) {
+// if (playerId < 0 || playerId >= SND_PLAYER_COUNT)
+// return FALSE;
+// if (trackId < 0 || trackId >= SND_TRACK_COUNT)
+// return FALSE;
+// SNDPlayer *player = &driverInfo->work.players[playerId];
+// if (player->tracks[trackId] == SND_INVALID_TRACK_INDEX)
+// return FALSE;
+// SNDTrack *track = &driverInfo->work.tracks[trackId];
+// trackInfo->program = track->program;
+// trackInfo->volume = track->volume;
+// trackInfo->expression = track->expression;
+// trackInfo->pitchBend = track->pitchBend;
+// trackInfo->bendRange = track->bendRange;
+// trackInfo->pan = track->pan + 0x40; // 0x40 == MIDI center pan
+// trackInfo->transpose = track->transpose;
+// trackInfo->chnCount = 0;
+//
+// //#define LL_READ_PTR(ptr, basePtr, base) (ptr ? ((typeof(ptr))(s32)(ptr) - (s32)(basePtr) + (s32)&(base)) : NULL)
+// //for (SNDExChannel *exChn = LL_READ_PTR(track->channelLLHead, driverInfo->workPtr, driverInfo->work);
+// // exChn != NULL; exChn = LL_READ_PTR(exChn->channelLLNext, driverInfo->workPtr, driverInfo->work))
+// //{
+// // trackInfo->channel[trackInfo->chnCount] = exChn->id;
+// // trackInfo->chnCount++;
+// //}
+// //#undef LL_READ_PTR
+//
+// return TRUE;
+//}
+
+ARM_FUNC u32 SNDi_GetFinishedCommandTag(void) {
+ DC_InvalidateRange(&SNDi_SharedWork->finishedCommandTag, 4);
+ return SNDi_SharedWork->finishedCommandTag;
+}
+
+ARM_FUNC void SNDi_InitSharedWork(struct SNDSharedWork *sw) {
+ sw->playerStatus = 0;
+ sw->channelStatus = 0;
+ sw->captureStatus = 0;
+ sw->finishedCommandTag = 0;
+
+ for (s32 i = 0; i < SND_PLAYER_COUNT; i++) {
+ sw->players[i].tickCounter = 0;
+ for (s32 j = 0; j < 16; j++) {
+ sw->players[i].localVars[j] = -1;
+ }
+ }
+
+ for (s32 i = 0; i < 16; i++) {
+ sw->globalVars[i] = -1;
+ }
+
+ DC_FlushRange(sw, sizeof(*sw));
+}
diff --git a/arm9/lib/NitroSDK/src/WM_ks.c b/arm9/lib/NitroSDK/src/WM_ks.c
new file mode 100644
index 00000000..93e96f89
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/WM_ks.c
@@ -0,0 +1,15 @@
+#include "WM_ks.h"
+#include "function_target.h"
+
+extern WMErrCode WM_StartDataSharing(WMKeySetBuf *buf, u16 port, u16 aidBitmap, u16 dataLength, BOOL doubleMode);
+extern WMErrCode WM_EndDataSharing(WMKeySetBuf *buf);
+
+ARM_FUNC WMErrCode WM_StartKeySharing(WMKeySetBuf *buf, u16 port)
+{
+ return WM_StartDataSharing(buf, port, 0xffff, 2, TRUE);
+}
+
+ARM_FUNC WMErrCode WM_EndKeySharing(WMKeySetBuf *buf)
+{
+ return WM_EndDataSharing(buf);
+}
diff --git a/arm9/lib/NitroSDK/src/crt0.c b/arm9/lib/NitroSDK/src/crt0.c
new file mode 100644
index 00000000..4e46cb63
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/crt0.c
@@ -0,0 +1,378 @@
+#include "nitro.h"
+#include "MI_uncompress.h"
+
+extern void NitroMain(void);
+extern void SDK_IRQ_STACKSIZE(void);
+extern void SDK_AUTOLOAD_START(void);
+extern void SDK_AUTOLOAD_LIST(void);
+extern void SDK_AUTOLOAD_LIST_END(void);
+extern void SDK_STATIC_BSS_START(void);
+extern void SDK_STATIC_BSS_END(void);
+extern void OS_IrqHandler(void);
+
+extern void *const _start_ModuleParams[];
+
+static void init_cp15(void);
+static void do_autoload(void);
+static void INITi_CpuClear32(register u32 data, register void *destp, register u32 size);
+void _start_AutoloadDoneCallback(void *argv[]);
+
+extern void __call_static_initializers(void);
+extern void _fp_init(void);
+void NitroStartUp(void);
+void _start(void);
+
+#define SDK_VERSION_ID ((3 << 24) | (2 << 16) | 30001)
+#define SDK_NITROCODE_LE 0x2106c0de
+#define SDK_NITROCODE_BE 0xdec00621
+
+ARM_FUNC asm void _start(void)
+{
+ //set IME to 0
+ mov r12, #0x4000000
+ str r12, [r12, #0x208]
+
+ //adjust VCOUNT
+_02000808:
+ ldrh r0, [r12, #6]
+ cmp r0, #0
+ bne _02000808
+
+ //init cp15
+ bl init_cp15
+
+ //init stack pointer
+ //SVC mode
+ mov r0, #OS_PROCMODE_SVC
+ msr CPSR_c, r0
+ ldr r0, =SDK_AUTOLOAD_DTCM_START
+ add r0, r0, #0x3fc0
+ mov sp, r0
+
+ //IRQ mode
+ mov r0, #OS_PROCMODE_IRQ
+ msr CPSR_c, r0
+ ldr r0, =SDK_AUTOLOAD_DTCM_START
+ add r0, r0, #0x3fc0
+ sub r0, r0, #HW_SVC_STACK_SIZE
+ sub sp, r0, #4
+ tst sp, #4
+ subeq sp, sp, #4
+
+ //system mode
+ ldr r1, =SDK_IRQ_STACKSIZE
+ sub r1, r0, r1
+ mov r0, #OS_PROCMODE_SYS
+ msr CPSR_csfx, r0
+ sub sp, r1, #4
+
+ //clear memory
+ //DTCM
+ mov r0, #0
+ ldr r1, =SDK_AUTOLOAD_DTCM_START
+ mov r2, #HW_DTCM_SIZE
+ bl INITi_CpuClear32
+
+ //BG/OBJ palette
+ mov r0, #0
+ ldr r1, =HW_PLTT
+ mov r2, #HW_PLTT_SIZE
+ bl INITi_CpuClear32
+
+ //OAM
+ mov r0, #0x0200
+ ldr r1, =HW_OAM
+ mov r2, #HW_OAM_SIZE
+ bl INITi_CpuClear32
+
+ //load autoload block and init bss
+ ldr r1, =_start_ModuleParams
+ ldr r0, [r1, #20]
+ bl MIi_UncompressBackward
+ bl do_autoload
+
+ //fill static bss with 0
+ ldr r0, =_start_ModuleParams
+ ldr r1, [r0, #12]
+ ldr r2, [r0, #16]
+ mov r3, r1
+ mov r0, #0
+_020008B4:
+ cmp r1, r2
+ strcc r0, [r1], #4
+ bcc _020008B4
+
+ //flush static bss region
+ bic r1, r3, #HW_CACHE_LINE_SIZE - 1
+_020008C4:
+ mcr p15, 0, r0, c7, c10, 4 //Drain Write Buffer
+ mcr p15, 0, r1, c7, c5, 1 //Invalidate Instruction Cache Line VA
+ mcr p15, 0, r1, c7, c14, 1 //Clean and Invalidate Data Cache Line VA
+ add r1, r1, #HW_CACHE_LINE_SIZE
+ cmp r1, r2
+ blt _020008C4
+
+ //print buffer
+ ldr r1, =HW_COMPONENT_PARAM
+ str r0, [r1, #0]
+
+ //set interrput vector
+ ldr r1, =SDK_AUTOLOAD_DTCM_START
+ add r1, r1, #0x3fc0
+ add r1, r1, #HW_DTCM_SYSRV_OFS_INTR_VECTOR
+ ldr r0, =OS_IrqHandler
+ str r0, [r1, #0]
+
+ bl _fp_init
+ bl NitroStartUp
+ bl __call_static_initializers
+
+ //start
+ ldr r1, =NitroMain
+ ldr lr, =HW_RESET_VECTOR
+
+ tst sp, #4
+ subne sp, sp, #4
+ bx r1
+}
+
+ARM_FUNC static asm void INITi_CpuClear32(register u32 data, register void *destp, register u32 size)
+{
+ add r12, r1, r2
+_02000940:
+ cmp r1, r12
+ stmltia r1!, {r0}
+ blt _02000940
+ bx lr
+}
+
+void *const _start_ModuleParams[] = {
+ (void *)SDK_AUTOLOAD_LIST,
+ (void *)SDK_AUTOLOAD_LIST_END,
+ (void *)SDK_AUTOLOAD_START,
+ (void *)SDK_STATIC_BSS_START,
+ (void *)SDK_STATIC_BSS_END,
+ (void *)0, // CompressedStaticEnd
+ (void *)SDK_VERSION_ID, // SDK version info
+ (void *)SDK_NITROCODE_BE, // Checker 1
+ (void *)SDK_NITROCODE_LE, // Checker 2
+};
+
+ARM_FUNC asm void MIi_UncompressBackward(register void *bottom)
+{
+ cmp r0, #0
+ beq _020009F8
+ stmfd sp!, {r4-r7}
+ ldmdb r0, {r1-r2}
+ add r2, r0, r2
+ sub r3, r0, r1, lsr #24
+ bic r1, r1, #0xff000000
+ sub r1, r0, r1
+ mov r4, r2
+_02000974:
+ cmp r3, r1
+ ble _020009D4
+ ldrb r5, [r3, #-1]!
+ mov r6, #8
+_02000984:
+ subs r6, r6, #1
+ blt _02000974
+ tst r5, #0x80
+ bne _020009A0
+
+ ldrb r0, [r3, #-1]!
+ strb r0, [r2, #-1]!
+ b _020009C8
+_020009A0:
+ ldrb r12, [r3, #-1]!
+ ldrb r7, [r3, #-1]!
+ orr r7, r7, r12, lsl #8
+ bic r7, r7, #0xf000
+ add r7, r7, #0x0002
+ add r12, r12, #0x0020
+_020009B8:
+ ldrb r0, [r2, r7]
+ strb r0, [r2, #-1]!
+ subs r12, r12, #0x0010
+ bge _020009B8
+_020009C8:
+ cmp r3, r1
+ mov r5, r5, lsl #1
+ bgt _02000984
+_020009D4:
+ mov r0, #0
+ bic r3, r1, #HW_CACHE_LINE_SIZE - 1
+_020009DC:
+ mcr p15, 0, r0, c7, c10, 4 //Drain Write Buffer
+ mcr p15, 0, r3, c7, c5, 1 //Invalidate Instruction Cache Line VA
+ mcr p15, 0, r3, c7, c14, 1 //Clean and Invalidate Data Cache Line VA
+ add r3, r3, #HW_CACHE_LINE_SIZE
+ cmp r3, r4
+ blt _020009DC
+
+ ldmfd sp!, {r4-r7}
+_020009F8:
+ bx lr
+}
+
+ARM_FUNC static asm void do_autoload(void)
+{
+ ldr r0, =_start_ModuleParams
+ ldr r1, [r0, #0]
+ ldr r2, [r0, #4]
+ ldr r3, [r0, #8]
+
+_02000A0C:
+ cmp r1, r2
+ beq _02000A6C
+
+ ldr r5, [r1], #4
+ ldr r7, [r1], #4
+ add r6, r5, r7
+ mov r4, r5
+_02000A24:
+ cmp r4, r6
+ ldrmi r7, [r3], #4
+ strmi r7, [r4], #4
+ bmi _02000A24
+
+ //fill bss with 0
+ ldr r7, [r1], #4
+ add r6, r4, r7
+ mov r7, #0
+_02000A40:
+ cmp r4, r6
+ strcc r7, [r4], #4
+ bcc _02000A40
+
+ bic r4, r5, #HW_CACHE_LINE_SIZE - 1
+_02000A50:
+ mcr p15, 0, r7, c7, c10, 4 //Drain Write Buffer
+ mcr p15, 0, r4, c7, c5, 1 //Invalidate Instruction Cache Line VA
+ mcr p15, 0, r4, c7, c14, 1 //Clean and Invalidate Data Cache Line VA
+ add r4, r4, #HW_CACHE_LINE_SIZE
+ cmp r4, r6
+ blt _02000A50
+
+ b _02000A0C
+
+_02000A6C:
+ b _start_AutoloadDoneCallback
+}
+
+ARM_FUNC asm void _start_AutoloadDoneCallback(void *argv[])
+{
+ bx lr
+}
+
+#define SET_PROTECTION_A(id, addr, size) ldr r0, =(addr|HW_C6_PR_##size|HW_C6_PR_ENABLE)
+#define SET_PROTECTION_B(id, addr, size) mcr p15, 0, r0, c6, id, 0
+#define REGION_BIT(a,b,c,d,e,f,g,h) (((a)<<0)|((b)<<1)|((c)<<2)|((d)<<3)|((e)<<4)|((f)<<5)|((g)<<6)|((h)<<7))
+#define REGION_ACC(a,b,c,d,e,f,g,h) (((a)<<0)|((b)<<4)|((c)<<8)|((d)<<12)|((e)<<16)|((f)<<20)|((g)<<24)|((h)<<28))
+ARM_FUNC static asm void init_cp15(void)
+{
+ //Disable TCM/Cache/Protection Unit
+ mrc p15, 0, r0, c1, c0, 0 //Save Control Register
+
+ /*
+ * The following bits are disabled
+ * * Instruction Cache
+ * * Data/Unified Cache
+ * * ITCM
+ * * DTCM
+ * * ITCM Load Mode
+ * * DTCM Load Mode
+ * * LD Interwork Disable
+ * * Protection Unit Enable
+ */
+ ldr r1, =0x000f9005
+ bic r0, r0, r1
+ mcr p15, 0, r0, c1, c0, 0 //Set Control Register
+
+ //Disable Cache
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 //Invalidate Entire Instruction Cache
+ mcr p15, 0, r0, c7, c6, 0 //Invalidate Entire Data Cache
+
+ mcr p15, 0, r0, c7, c10, 4 //Drain Write Buffer
+
+ SET_PROTECTION_A(c0, HW_IOREG, 64MB) //Protection Unit Unified Region
+ SET_PROTECTION_B(c0, HW_IOREG, 64MB)
+
+ SET_PROTECTION_A(c1, HW_MAIN_MEM, 8MB)
+ SET_PROTECTION_B(c1, HW_MAIN_MEM, 8MB)
+
+ SET_PROTECTION_A(c2, HW_MAIN_MEM_SUB, 128KB)
+ SET_PROTECTION_B(c2, HW_MAIN_MEM_SUB, 128KB)
+
+ SET_PROTECTION_A(c3, HW_CTRDG_ROM, 128MB)
+ SET_PROTECTION_B(c3, HW_CTRDG_ROM, 128MB)
+
+ ldr r0, =SDK_AUTOLOAD_DTCM_START
+ orr r0, r0, #0x1a
+ orr r0, r0, #1
+ SET_PROTECTION_B(c4, HW_DTCM, 16KB)
+
+ SET_PROTECTION_A(c5, HW_ITCM_IMAGE, 16MB)
+ SET_PROTECTION_B(c5, HW_ITCM_IMAGE, 16MB)
+
+ SET_PROTECTION_A(c6, HW_BIOS, 32KB)
+ SET_PROTECTION_B(c6, HW_BIOS, 32KB)
+
+ SET_PROTECTION_A(c7, HW_MAIN_MEM_SHARED, 4KB)
+ SET_PROTECTION_B(c7, HW_MAIN_MEM_SHARED, 4KB)
+
+ mov r0, #HW_C9_TCMR_32MB
+ mcr p15, 0, r0, c9, c1, 1 //ITCM Size/Base
+
+ ldr r0, =SDK_AUTOLOAD_DTCM_START
+ orr r0, r0, #HW_C9_TCMR_16KB
+ mcr p15, 0, r0, c9, c1, 0 //DTCM Size/Base
+
+ mov r0, #REGION_BIT(0,1,0,0,0,0,1,0)
+ mcr p15, 0, r0, c2, c0, 1 //Cache Bits for Instruction Protection Region
+
+ mov r0, #REGION_BIT(0,1,0,0,0,0,1,0)
+ mcr p15, 0, r0, c2, c0, 0 //Cache Bits for Data Protection Region
+
+ mov r0, #REGION_BIT(0,1,0,0,0,0,0,0)
+ mcr p15, 0, r0, c3, c0, 0 //Cache Write Buffer Bits for Data Protection Region
+
+ ldr r0, =REGION_ACC(1,1,0,0,0,1,5,0)
+ mcr p15, 0, r0, c5, c0, 3 //Extended Access Permission Instruction Protection Region
+
+ ldr r0, =REGION_ACC(1,1,0,1,1,1,5,1)
+ mcr p15, 0, r0, c5, c0, 2 //Extended Access Permission Data Protection Region
+
+ mrc p15, 0, r0, c1, c0, 0 //Save Control Register
+
+ /*
+ * The following bits are enabled
+ * * Instruction Cache
+ * * Data Cache
+ * * Cache Replacement - Round Robin
+ * * ITCM
+ * * DTCM
+ * * SB1 Bit Set
+ * * Exception Vectors
+ * * Protection Unit
+ */
+ ldr r1, =0x0005707D
+ orr r0, r0, r1
+ mcr p15, 0, r0, c1, c0, 0 //Set Control Register
+
+ bx lr
+}
+#undef SET_PROTECTION_A
+#undef SET_PROTECTION_B
+#undef REGION_BIT
+#undef REGION_ACC
+
+ARM_FUNC void NitroStartUp(void)
+{
+}
+
+ARM_FUNC void OSi_ReferSymbol(void *symbol)
+{
+#pragma unused(symbol)
+}
diff --git a/arm9/lib/NitroSDK/src/custom_allocator.c b/arm9/lib/NitroSDK/src/custom_allocator.c
new file mode 100644
index 00000000..283c3500
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/custom_allocator.c
@@ -0,0 +1,32 @@
+#include "custom_allocator.h"
+
+#include "global.h"
+#include "OS_alloc.h"
+
+static FreeFunc sDestructor;
+static AllocFunc sAllocator;
+
+// Custom allocator
+ARM_FUNC void* CallCustomAllocator(u32 size)
+{
+ if (sAllocator != NULL)
+ return sAllocator(size);
+ else
+ return OS_AllocFromHeap(OS_ARENA_MAIN, -1, size);
+}
+
+// Custom destructor
+ARM_FUNC void CallCustomDestructor(void * ptr)
+{
+ if (sDestructor != NULL)
+ sDestructor(ptr);
+ else
+ OS_FreeToHeap(OS_ARENA_MAIN, -1, ptr);
+}
+
+// Custom alloc/free setter
+ARM_FUNC void SetCustomAllocatorAndDestructor(AllocFunc allocator, FreeFunc destructor)
+{
+ sAllocator = allocator;
+ sDestructor = destructor;
+}
diff --git a/arm9/lib/NitroSDK/src/version_1_dwc.c b/arm9/lib/NitroSDK/src/version_1_dwc.c
new file mode 100644
index 00000000..713aed0d
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/version_1_dwc.c
@@ -0,0 +1,5 @@
+#include "sections.h"
+
+#pragma section VERSION begin
+char _SDK_NintendoDWC[] = "[SDK+NINTENDO:DWC1.2.30006.061019.2254_DWC_1_2_PLUS6]";
+#pragma section VERSION end
diff --git a/arm9/lib/NitroSDK/src/version_2_wifi.c b/arm9/lib/NitroSDK/src/version_2_wifi.c
new file mode 100644
index 00000000..e5db89e4
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/version_2_wifi.c
@@ -0,0 +1,5 @@
+#include "sections.h"
+
+#pragma section VERSION begin
+char _SDK_NintendoWiFi[] = "[SDK+NINTENDO:WiFi1.2.30000.0609050341]";
+#pragma section VERSION end
diff --git a/arm9/lib/NitroSDK/src/version_3_cps.c b/arm9/lib/NitroSDK/src/version_3_cps.c
new file mode 100644
index 00000000..5918341e
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/version_3_cps.c
@@ -0,0 +1,5 @@
+#include "sections.h"
+
+#pragma section VERSION begin
+char _SDK_UbiquitousCPS[] = "[SDK+UBIQUITOUS:CPS]";
+#pragma section VERSION end
diff --git a/arm9/lib/NitroSDK/src/version_4_ssl.c b/arm9/lib/NitroSDK/src/version_4_ssl.c
new file mode 100644
index 00000000..f1bf08ce
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/version_4_ssl.c
@@ -0,0 +1,5 @@
+#include "sections.h"
+
+#pragma section VERSION begin
+char _SDK_UbiquitousSSL[] = "[SDK+UBIQUITOUS:SSL]";
+#pragma section VERSION end
diff --git a/arm9/lib/NitroSDK/src/version_5_vct.c b/arm9/lib/NitroSDK/src/version_5_vct.c
new file mode 100644
index 00000000..a13caf88
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/version_5_vct.c
@@ -0,0 +1,5 @@
+#include "sections.h"
+
+#pragma section VERSION begin
+char _SDK_AbiossolibVCT[] = "[SDK+Abiosso:libVCT 1.0.1_ec]";
+#pragma section VERSION end
diff --git a/arm9/lib/NitroSDK/src/version_6_backup.c b/arm9/lib/NitroSDK/src/version_6_backup.c
new file mode 100644
index 00000000..3cbe3e37
--- /dev/null
+++ b/arm9/lib/NitroSDK/src/version_6_backup.c
@@ -0,0 +1,5 @@
+#include "sections.h"
+
+#pragma section VERSION begin
+char _SDK_NintendoBackup[] = "[SDK+NINTENDO:BACKUP]";
+#pragma section VERSION end