summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/nds/libnds/source
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2008-08-19 15:47:14 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2008-08-19 15:47:14 +0000
commit49a4016507e6239ca313bafff5dcaf37cd6647fd (patch)
tree076c0ba4437083f66b3093465071a53af8e513d2 /c/src/lib/libbsp/arm/nds/libnds/source
parent2008-08-19 Joel Sherrill <joel.sherrill@OARcorp.com> (diff)
downloadrtems-49a4016507e6239ca313bafff5dcaf37cd6647fd.tar.bz2
2008-08-19 Joel Sherrill <joel.sherrill@OARcorp.com>
* dswifi/arm7/makefile, dswifi/include/netinet/in.h, libnds/basicARM7/source/defaultARM7.c, libnds/include/gbfs.h, libnds/include/nds/bios.h, libnds/include/nds/card.h, libnds/include/nds/dma.h, libnds/include/nds/interrupts.h, libnds/include/nds/ipc.h, libnds/include/nds/jtypes.h, libnds/include/nds/registers_alt.h, libnds/include/nds/system.h, libnds/include/nds/timers.h, libnds/include/nds/arm7/audio.h, libnds/include/nds/arm7/clock.h, libnds/include/nds/arm7/serial.h, libnds/include/nds/arm7/touch.h, libnds/include/nds/arm9/boxtest.h, libnds/include/nds/arm9/cache.h, libnds/include/nds/arm9/console.h, libnds/include/nds/arm9/ndsmotion.h, libnds/include/nds/arm9/video.h, libnds/include/nds/arm9/videoGL.h, libnds/source/arm7/audio.c, libnds/source/arm7/clock.c, libnds/source/arm7/microphone.c, libnds/source/arm7/touch.c, libnds/source/arm7/userSettings.c, libnds/source/arm9/boxtest.c, libnds/source/arm9/gurumeditation.c, libnds/source/arm9/ndsmotion.c, libnds/source/arm9/videoGL.c, libnds/source/common/card.c, libnds/source/common/interruptDispatcher.S, touchscreen/reco.c: Fix various warnings by fixing prototypes. Remove unused .bin files. Convert all files to UNIX CF/LF. * libnds/source/arm9/COS.bin, libnds/source/arm9/SIN.bin, libnds/source/arm9/TAN.bin, libnds/source/arm9/default_font.bin: Removed.
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm7/audio.c54
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm7/clock.c556
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm7/microphone.c230
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm7/touch.c746
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm7/userSettings.c142
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm9/COS.binbin1024 -> 0 bytes
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm9/SIN.binbin1024 -> 0 bytes
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm9/TAN.binbin1024 -> 0 bytes
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm9/boxtest.c176
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm9/default_font.binbin8192 -> 0 bytes
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm9/gurumeditation.c540
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm9/ndsmotion.c976
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/arm9/videoGL.c852
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/common/card.c788
-rw-r--r--c/src/lib/libbsp/arm/nds/libnds/source/common/interruptDispatcher.S322
15 files changed, 2700 insertions, 2682 deletions
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/audio.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/audio.c
index 365ac688fe..7a32b1b618 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/audio.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/audio.c
@@ -1,27 +1,27 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
-
- Copyright (C) 2005
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
----------------------------------------------------------------------------------*/
-
-#include "nds/arm7/audio.h"
+/*---------------------------------------------------------------------------------
+ $Id$
+
+
+ Copyright (C) 2005
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+---------------------------------------------------------------------------------*/
+
+#include "nds/arm7/audio.h"
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/clock.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/clock.c
index eb27824ad0..78727af35c 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/clock.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/clock.c
@@ -1,278 +1,278 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- Copyright (C) 2005
- Michael Noland (Joat)
- Jason Rogers (Dovoto)
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
----------------------------------------------------------------------------------*/
-
-#include "nds/bios.h"
-#include "nds/arm7/clock.h"
-#include "nds/interrupts.h"
-#include "nds/ipc.h"
-
-#include <time.h>
-
-
-
-// Delay (in swiDelay units) for each bit transfer
-#define RTC_DELAY 48
-
-// Pin defines on RTC_CR
-#define CS_0 (1<<6)
-#define CS_1 ((1<<6) | (1<<2))
-#define SCK_0 (1<<5)
-#define SCK_1 ((1<<5) | (1<<1))
-#define SIO_0 (1<<4)
-#define SIO_1 ((1<<4) | (1<<0))
-#define SIO_out (1<<4)
-#define SIO_in (1)
-
-//---------------------------------------------------------------------------------
-void BCDToInteger(uint8 * data, uint32 length) {
-//---------------------------------------------------------------------------------
- u32 i;
- for (i = 0; i < length; i++) {
- data[i] = (data[i] & 0xF) + ((data[i] & 0xF0)>>4)*10;
- }
-}
-
-
-//---------------------------------------------------------------------------------
-void integerToBCD(uint8 * data, uint32 length) {
-//---------------------------------------------------------------------------------
- u32 i;
- for (i = 0; i < length; i++) {
- int high, low;
- swiDivMod(data[i], 10, &high, &low);
- data[i] = (high<<4) | low;
- }
-}
-
-//---------------------------------------------------------------------------------
-void rtcTransaction(uint8 * command, uint32 commandLength, uint8 * result, uint32 resultLength) {
-//---------------------------------------------------------------------------------
- uint32 bit;
- uint8 data;
-
- // Raise CS
- RTC_CR8 = CS_0 | SCK_1 | SIO_1;
- swiDelay(RTC_DELAY);
- RTC_CR8 = CS_1 | SCK_1 | SIO_1;
- swiDelay(RTC_DELAY);
-
- // Write command byte (high bit first)
- data = *command++;
-
- for (bit = 0; bit < 8; bit++) {
- RTC_CR8 = CS_1 | SCK_0 | SIO_out | (data>>7);
- swiDelay(RTC_DELAY);
-
- RTC_CR8 = CS_1 | SCK_1 | SIO_out | (data>>7);
- swiDelay(RTC_DELAY);
-
- data = data << 1;
- }
- // Write parameter bytes (low bit first)
- for ( ; commandLength > 1; commandLength--) {
- data = *command++;
-
- for (bit = 0; bit < 8; bit++) {
- RTC_CR8 = CS_1 | SCK_0 | SIO_out | (data & 1);
- swiDelay(RTC_DELAY);
-
- RTC_CR8 = CS_1 | SCK_1 | SIO_out | (data & 1);
- swiDelay(RTC_DELAY);
-
- data = data >> 1;
- }
- }
-
- // Read result bytes (low bit first)
- for ( ; resultLength > 0; resultLength--) {
- data = 0;
-
- for (bit = 0; bit < 8; bit++) {
- RTC_CR8 = CS_1 | SCK_0;
- swiDelay(RTC_DELAY);
-
- RTC_CR8 = CS_1 | SCK_1;
- swiDelay(RTC_DELAY);
-
- if (RTC_CR8 & SIO_in) data |= (1 << bit);
- }
- *result++ = data;
- }
-
- // Finish up by dropping CS low
- RTC_CR8 = CS_0 | SCK_1;
- swiDelay(RTC_DELAY);
-}
-
-
-//---------------------------------------------------------------------------------
-void rtcReset(void) {
-//---------------------------------------------------------------------------------
- uint8 status;
- uint8 command[2];
-
- // Read the first status register
- command[0] = READ_STATUS_REG1;
- rtcTransaction(command, 1, &status, 1);
-
- // Reset the RTC if needed
- if (status & (STATUS_POC | STATUS_BLD)) {
- command[0] = WRITE_STATUS_REG1;
- command[1] = status | STATUS_RESET;
- rtcTransaction(command, 2, 0, 0);
- }
-}
-
-
-//---------------------------------------------------------------------------------
-void rtcGetTimeAndDate(uint8 * time) {
-//---------------------------------------------------------------------------------
- uint8 command, status;
-
- command = READ_TIME_AND_DATE;
- rtcTransaction(&command, 1, time, 7);
-
- command = READ_STATUS_REG1;
- rtcTransaction(&command, 1, &status, 1);
-
- if ( status & STATUS_24HRS ) {
- time[4] &= 0x3f;
- } else {
-
- }
- BCDToInteger(time,7);
-}
-
-//---------------------------------------------------------------------------------
-void rtcSetTimeAndDate(uint8 * time) {
-//---------------------------------------------------------------------------------
- uint8 command[8];
-
- int i;
- for ( i=0; i< 8; i++ ) {
- command[i+1] = time[i];
- }
- command[0] = WRITE_TIME_AND_DATE;
- // fixme: range checking on the data we tell it
- rtcTransaction(command, 8, 0, 0);
-}
-
-//---------------------------------------------------------------------------------
-void rtcGetTime(uint8 * time) {
-//---------------------------------------------------------------------------------
- uint8 command, status;
-
- command = READ_TIME;
- rtcTransaction(&command, 1, time, 3);
-
- command = READ_STATUS_REG1;
- rtcTransaction(&command, 1, &status, 1);
- if ( status & STATUS_24HRS ) {
- time[0] &= 0x3f;
- } else {
-
- }
- BCDToInteger(time,3);
-
-}
-
-//---------------------------------------------------------------------------------
-void rtcSetTime(uint8 * time) {
-//---------------------------------------------------------------------------------
- uint8 command[4];
-
- int i;
- for ( i=0; i< 3; i++ ) {
- command[i+1] = time[i];
- }
- command[0] = WRITE_TIME;
- // fixme: range checking on the data we tell it
- rtcTransaction(command, 4, 0, 0);
-}
-
-//---------------------------------------------------------------------------------
-void syncRTC() {
-//---------------------------------------------------------------------------------
- if (++IPC->time.rtc.seconds == 60 ) {
- IPC->time.rtc.seconds = 0;
- if (++IPC->time.rtc.minutes == 60) {
- IPC->time.rtc.minutes = 0;
- if (++IPC->time.rtc.hours == 24) {
- rtcGetTimeAndDate((uint8 *)&(IPC->time.rtc.year));
- }
- }
- }
-
- IPC->unixTime++;
-}
-
-//---------------------------------------------------------------------------------
-void initClockIRQ() {
-//---------------------------------------------------------------------------------
-
- REG_RCNT = 0x8100;
- irqSet(IRQ_NETWORK, syncRTC);
- // Reset the clock if needed
- rtcReset();
-
- uint8 command[4];
- command[0] = READ_STATUS_REG2;
- rtcTransaction(command, 1, &command[1], 1);
-
- command[0] = WRITE_STATUS_REG2;
- command[1] = 0x41;
- rtcTransaction(command, 2, 0, 0);
-
- command[0] = WRITE_INT_REG1;
- command[1] = 0x01;
- rtcTransaction(command, 2, 0, 0);
-
- command[0] = WRITE_INT_REG2;
- command[1] = 0x00;
- command[2] = 0x21;
- command[3] = 0x35;
- rtcTransaction(command, 4, 0, 0);
-
- // Read all time settings on first start
- rtcGetTimeAndDate((uint8 *)&(IPC->time.rtc.year));
-
-
- struct tm currentTime;
-
- currentTime.tm_sec = IPC->time.rtc.seconds;
- currentTime.tm_min = IPC->time.rtc.minutes;
- currentTime.tm_hour = IPC->time.rtc.hours;
-
- currentTime.tm_mday = IPC->time.rtc.day;
- currentTime.tm_mon = IPC->time.rtc.month - 1;
- currentTime.tm_year = IPC->time.rtc.year + 100;
-
- currentTime.tm_isdst = -1;
-
- IPC->unixTime = mktime(&currentTime);
-}
-
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ Copyright (C) 2005
+ Michael Noland (Joat)
+ Jason Rogers (Dovoto)
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+---------------------------------------------------------------------------------*/
+
+#include "nds/bios.h"
+#include "nds/arm7/clock.h"
+#include "nds/interrupts.h"
+#include "nds/ipc.h"
+
+#include <time.h>
+
+
+
+// Delay (in swiDelay units) for each bit transfer
+#define RTC_DELAY 48
+
+// Pin defines on RTC_CR
+#define CS_0 (1<<6)
+#define CS_1 ((1<<6) | (1<<2))
+#define SCK_0 (1<<5)
+#define SCK_1 ((1<<5) | (1<<1))
+#define SIO_0 (1<<4)
+#define SIO_1 ((1<<4) | (1<<0))
+#define SIO_out (1<<4)
+#define SIO_in (1)
+
+//---------------------------------------------------------------------------------
+void BCDToInteger(uint8 * data, uint32 length) {
+//---------------------------------------------------------------------------------
+ u32 i;
+ for (i = 0; i < length; i++) {
+ data[i] = (data[i] & 0xF) + ((data[i] & 0xF0)>>4)*10;
+ }
+}
+
+
+//---------------------------------------------------------------------------------
+void integerToBCD(uint8 * data, uint32 length) {
+//---------------------------------------------------------------------------------
+ u32 i;
+ for (i = 0; i < length; i++) {
+ int high, low;
+ swiDivMod(data[i], 10, &high, &low);
+ data[i] = (high<<4) | low;
+ }
+}
+
+//---------------------------------------------------------------------------------
+void rtcTransaction(uint8 * command, uint32 commandLength, uint8 * result, uint32 resultLength) {
+//---------------------------------------------------------------------------------
+ uint32 bit;
+ uint8 data;
+
+ // Raise CS
+ RTC_CR8 = CS_0 | SCK_1 | SIO_1;
+ swiDelay(RTC_DELAY);
+ RTC_CR8 = CS_1 | SCK_1 | SIO_1;
+ swiDelay(RTC_DELAY);
+
+ // Write command byte (high bit first)
+ data = *command++;
+
+ for (bit = 0; bit < 8; bit++) {
+ RTC_CR8 = CS_1 | SCK_0 | SIO_out | (data>>7);
+ swiDelay(RTC_DELAY);
+
+ RTC_CR8 = CS_1 | SCK_1 | SIO_out | (data>>7);
+ swiDelay(RTC_DELAY);
+
+ data = data << 1;
+ }
+ // Write parameter bytes (low bit first)
+ for ( ; commandLength > 1; commandLength--) {
+ data = *command++;
+
+ for (bit = 0; bit < 8; bit++) {
+ RTC_CR8 = CS_1 | SCK_0 | SIO_out | (data & 1);
+ swiDelay(RTC_DELAY);
+
+ RTC_CR8 = CS_1 | SCK_1 | SIO_out | (data & 1);
+ swiDelay(RTC_DELAY);
+
+ data = data >> 1;
+ }
+ }
+
+ // Read result bytes (low bit first)
+ for ( ; resultLength > 0; resultLength--) {
+ data = 0;
+
+ for (bit = 0; bit < 8; bit++) {
+ RTC_CR8 = CS_1 | SCK_0;
+ swiDelay(RTC_DELAY);
+
+ RTC_CR8 = CS_1 | SCK_1;
+ swiDelay(RTC_DELAY);
+
+ if (RTC_CR8 & SIO_in) data |= (1 << bit);
+ }
+ *result++ = data;
+ }
+
+ // Finish up by dropping CS low
+ RTC_CR8 = CS_0 | SCK_1;
+ swiDelay(RTC_DELAY);
+}
+
+
+//---------------------------------------------------------------------------------
+void rtcReset(void) {
+//---------------------------------------------------------------------------------
+ uint8 status;
+ uint8 command[2];
+
+ // Read the first status register
+ command[0] = READ_STATUS_REG1;
+ rtcTransaction(command, 1, &status, 1);
+
+ // Reset the RTC if needed
+ if (status & (STATUS_POC | STATUS_BLD)) {
+ command[0] = WRITE_STATUS_REG1;
+ command[1] = status | STATUS_RESET;
+ rtcTransaction(command, 2, 0, 0);
+ }
+}
+
+
+//---------------------------------------------------------------------------------
+void rtcGetTimeAndDate(uint8 * time) {
+//---------------------------------------------------------------------------------
+ uint8 command, status;
+
+ command = READ_TIME_AND_DATE;
+ rtcTransaction(&command, 1, time, 7);
+
+ command = READ_STATUS_REG1;
+ rtcTransaction(&command, 1, &status, 1);
+
+ if ( status & STATUS_24HRS ) {
+ time[4] &= 0x3f;
+ } else {
+
+ }
+ BCDToInteger(time,7);
+}
+
+//---------------------------------------------------------------------------------
+void rtcSetTimeAndDate(uint8 * time) {
+//---------------------------------------------------------------------------------
+ uint8 command[8];
+
+ int i;
+ for ( i=0; i< 8; i++ ) {
+ command[i+1] = time[i];
+ }
+ command[0] = WRITE_TIME_AND_DATE;
+ // fixme: range checking on the data we tell it
+ rtcTransaction(command, 8, 0, 0);
+}
+
+//---------------------------------------------------------------------------------
+void rtcGetTime(uint8 * time) {
+//---------------------------------------------------------------------------------
+ uint8 command, status;
+
+ command = READ_TIME;
+ rtcTransaction(&command, 1, time, 3);
+
+ command = READ_STATUS_REG1;
+ rtcTransaction(&command, 1, &status, 1);
+ if ( status & STATUS_24HRS ) {
+ time[0] &= 0x3f;
+ } else {
+
+ }
+ BCDToInteger(time,3);
+
+}
+
+//---------------------------------------------------------------------------------
+void rtcSetTime(uint8 * time) {
+//---------------------------------------------------------------------------------
+ uint8 command[4];
+
+ int i;
+ for ( i=0; i< 3; i++ ) {
+ command[i+1] = time[i];
+ }
+ command[0] = WRITE_TIME;
+ // fixme: range checking on the data we tell it
+ rtcTransaction(command, 4, 0, 0);
+}
+
+//---------------------------------------------------------------------------------
+void syncRTC() {
+//---------------------------------------------------------------------------------
+ if (++IPC->time.rtc.seconds == 60 ) {
+ IPC->time.rtc.seconds = 0;
+ if (++IPC->time.rtc.minutes == 60) {
+ IPC->time.rtc.minutes = 0;
+ if (++IPC->time.rtc.hours == 24) {
+ rtcGetTimeAndDate((uint8 *)&(IPC->time.rtc.year));
+ }
+ }
+ }
+
+ IPC->unixTime++;
+}
+
+//---------------------------------------------------------------------------------
+void initClockIRQ() {
+//---------------------------------------------------------------------------------
+
+ REG_RCNT = 0x8100;
+ irqSet(IRQ_NETWORK, syncRTC);
+ // Reset the clock if needed
+ rtcReset();
+
+ uint8 command[4];
+ command[0] = READ_STATUS_REG2;
+ rtcTransaction(command, 1, &command[1], 1);
+
+ command[0] = WRITE_STATUS_REG2;
+ command[1] = 0x41;
+ rtcTransaction(command, 2, 0, 0);
+
+ command[0] = WRITE_INT_REG1;
+ command[1] = 0x01;
+ rtcTransaction(command, 2, 0, 0);
+
+ command[0] = WRITE_INT_REG2;
+ command[1] = 0x00;
+ command[2] = 0x21;
+ command[3] = 0x35;
+ rtcTransaction(command, 4, 0, 0);
+
+ // Read all time settings on first start
+ rtcGetTimeAndDate((uint8 *)&(IPC->time.rtc.year));
+
+
+ struct tm currentTime;
+
+ currentTime.tm_sec = IPC->time.rtc.seconds;
+ currentTime.tm_min = IPC->time.rtc.minutes;
+ currentTime.tm_hour = IPC->time.rtc.hours;
+
+ currentTime.tm_mday = IPC->time.rtc.day;
+ currentTime.tm_mon = IPC->time.rtc.month - 1;
+ currentTime.tm_year = IPC->time.rtc.year + 100;
+
+ currentTime.tm_isdst = -1;
+
+ IPC->unixTime = mktime(&currentTime);
+}
+
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/microphone.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/microphone.c
index e5e29db24b..df04527e48 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/microphone.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/microphone.c
@@ -1,115 +1,115 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- Microphone control for the ARM7
-
- Copyright (C) 2005
- Michael Noland (joat)
- Jason Rogers (dovoto)
- Dave Murphy (WinterMute)
- Chris Double (doublec)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
----------------------------------------------------------------------------------*/
-#include <nds/arm7/audio.h>
-#include <nds/timers.h>
-
-//---------------------------------------------------------------------------------
-// Turn on the Microphone Amp. Code based on neimod's example.
-//---------------------------------------------------------------------------------
-void PM_SetAmp(u8 control) {
-//---------------------------------------------------------------------------------
- SerialWaitBusy();
- REG_SPICNT = SPI_ENABLE | SPI_DEVICE_POWER | SPI_BAUD_1MHz | SPI_CONTINUOUS;
- REG_SPIDATA = PM_AMP_OFFSET;
-
- SerialWaitBusy();
-
- REG_SPICNT = SPI_ENABLE | SPI_DEVICE_POWER | SPI_BAUD_1MHz;
- REG_SPIDATA = control;
-}
-
-//---------------------------------------------------------------------------------
-// Read a byte from the microphone. Code based on neimod's example.
-//---------------------------------------------------------------------------------
-u8 MIC_ReadData() {
-//---------------------------------------------------------------------------------
- u16 result, result2;
-
- SerialWaitBusy();
-
- REG_SPICNT = SPI_ENABLE | SPI_DEVICE_MICROPHONE | SPI_BAUD_2MHz | SPI_CONTINUOUS;
- REG_SPIDATA = 0xEC; // Touchscreen command format for AUX
-
- SerialWaitBusy();
-
- REG_SPIDATA = 0x00;
-
- SerialWaitBusy();
-
- result = REG_SPIDATA;
- REG_SPICNT = SPI_ENABLE | SPI_DEVICE_TOUCH | SPI_BAUD_2MHz;
- REG_SPIDATA = 0x00;
-
- SerialWaitBusy();
-
- result2 = REG_SPIDATA;
-
- return (((result & 0x7F) << 1) | ((result2>>7)&1));
-}
-
-static u8* microphone_buffer = 0;
-static int microphone_buffer_length = 0;
-static int current_length = 0;
-
-
-//---------------------------------------------------------------------------------
-void StartRecording(u8* buffer, int length) {
-//---------------------------------------------------------------------------------
- microphone_buffer = buffer;
- microphone_buffer_length = length;
- current_length = 0;
-
- MIC_On();
-
- // Setup a 16kHz timer
- TIMER0_DATA = 0xF7CF;
- TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1 | TIMER_IRQ_REQ;
-}
-
-//---------------------------------------------------------------------------------
-int StopRecording() {
-//---------------------------------------------------------------------------------
- TIMER0_CR &= ~TIMER_ENABLE;
- MIC_Off();
- microphone_buffer = 0;
- return current_length;
-}
-
-//---------------------------------------------------------------------------------
-void ProcessMicrophoneTimerIRQ() {
-//---------------------------------------------------------------------------------
- if(microphone_buffer && microphone_buffer_length > 0) {
- // Read data from the microphone. Data from the Mic is unsigned, flipping
- // the highest bit makes it signed.
- *microphone_buffer++ = MIC_ReadData() ^ 0x80;
- --microphone_buffer_length;
- current_length++;
- }
-}
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ Microphone control for the ARM7
+
+ Copyright (C) 2005
+ Michael Noland (joat)
+ Jason Rogers (dovoto)
+ Dave Murphy (WinterMute)
+ Chris Double (doublec)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+---------------------------------------------------------------------------------*/
+#include <nds/arm7/audio.h>
+#include <nds/timers.h>
+
+//---------------------------------------------------------------------------------
+// Turn on the Microphone Amp. Code based on neimod's example.
+//---------------------------------------------------------------------------------
+void PM_SetAmp(u8 control) {
+//---------------------------------------------------------------------------------
+ SerialWaitBusy();
+ REG_SPICNT = SPI_ENABLE | SPI_DEVICE_POWER | SPI_BAUD_1MHz | SPI_CONTINUOUS;
+ REG_SPIDATA = PM_AMP_OFFSET;
+
+ SerialWaitBusy();
+
+ REG_SPICNT = SPI_ENABLE | SPI_DEVICE_POWER | SPI_BAUD_1MHz;
+ REG_SPIDATA = control;
+}
+
+//---------------------------------------------------------------------------------
+// Read a byte from the microphone. Code based on neimod's example.
+//---------------------------------------------------------------------------------
+u8 MIC_ReadData() {
+//---------------------------------------------------------------------------------
+ u16 result, result2;
+
+ SerialWaitBusy();
+
+ REG_SPICNT = SPI_ENABLE | SPI_DEVICE_MICROPHONE | SPI_BAUD_2MHz | SPI_CONTINUOUS;
+ REG_SPIDATA = 0xEC; // Touchscreen command format for AUX
+
+ SerialWaitBusy();
+
+ REG_SPIDATA = 0x00;
+
+ SerialWaitBusy();
+
+ result = REG_SPIDATA;
+ REG_SPICNT = SPI_ENABLE | SPI_DEVICE_TOUCH | SPI_BAUD_2MHz;
+ REG_SPIDATA = 0x00;
+
+ SerialWaitBusy();
+
+ result2 = REG_SPIDATA;
+
+ return (((result & 0x7F) << 1) | ((result2>>7)&1));
+}
+
+static u8* microphone_buffer = 0;
+static int microphone_buffer_length = 0;
+static int current_length = 0;
+
+
+//---------------------------------------------------------------------------------
+void StartRecording(u8* buffer, int length) {
+//---------------------------------------------------------------------------------
+ microphone_buffer = buffer;
+ microphone_buffer_length = length;
+ current_length = 0;
+
+ MIC_On();
+
+ // Setup a 16kHz timer
+ TIMER0_DATA = 0xF7CF;
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1 | TIMER_IRQ_REQ;
+}
+
+//---------------------------------------------------------------------------------
+int StopRecording() {
+//---------------------------------------------------------------------------------
+ TIMER0_CR &= ~TIMER_ENABLE;
+ MIC_Off();
+ microphone_buffer = 0;
+ return current_length;
+}
+
+//---------------------------------------------------------------------------------
+void ProcessMicrophoneTimerIRQ() {
+//---------------------------------------------------------------------------------
+ if(microphone_buffer && microphone_buffer_length > 0) {
+ // Read data from the microphone. Data from the Mic is unsigned, flipping
+ // the highest bit makes it signed.
+ *microphone_buffer++ = MIC_ReadData() ^ 0x80;
+ --microphone_buffer_length;
+ current_length++;
+ }
+}
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/touch.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/touch.c
index a6cdd6b07f..11c25cb03c 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/touch.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/touch.c
@@ -1,373 +1,373 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- Touch screen control for the ARM7
-
- Copyright (C) 2005
- Michael Noland (joat)
- Jason Rogers (dovoto)
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
----------------------------------------------------------------------------------*/
-
-#include <nds/jtypes.h>
-#include <nds/system.h>
-#include <nds/arm7/touch.h>
-#include <nds/interrupts.h>
-
-#include <stdlib.h>
-
-static u8 last_time_touched = 0;
-
-static u8 range_counter_1 = 0;
-static u8 range_counter_2 = 0;
-static u8 range = 20;
-static u8 min_range = 20;
-
-//---------------------------------------------------------------------------------
-u8 CheckStylus(){
-//---------------------------------------------------------------------------------
-
- SerialWaitBusy();
-
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS; //0x8A01;
- REG_SPIDATA = TSC_MEASURE_TEMP1;
-
- SerialWaitBusy();
-
- REG_SPIDATA = 0;
-
- SerialWaitBusy();
-
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;// 0x8201;
- REG_SPIDATA = 0;
-
- SerialWaitBusy();
-
- if(last_time_touched == 1){
- if( !(REG_KEYXY & 0x40) )
- return 1;
- else{
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
- REG_SPIDATA = TSC_MEASURE_TEMP1;
-
- SerialWaitBusy();
-
- REG_SPIDATA = 0;
-
- SerialWaitBusy();
-
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
- REG_SPIDATA = 0;
-
- SerialWaitBusy();
-
- return !(REG_KEYXY & 0x40) ? 2 : 0;
- }
- }else{
- return !(REG_KEYXY & 0x40) ? 1 : 0;
- }
-}
-
-//---------------------------------------------------------------------------------
-uint16 touchRead(uint32 command) {
-//---------------------------------------------------------------------------------
- uint16 result, result2;
-
- uint32 oldIME = REG_IME;
-
- REG_IME = 0;
-
- SerialWaitBusy();
-
- // Write the command and wait for it to complete
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS; //0x8A01;
- REG_SPIDATA = command;
- SerialWaitBusy();
-
- // Write the second command and clock in part of the data
- REG_SPIDATA = 0;
- SerialWaitBusy();
- result = REG_SPIDATA;
-
- // Clock in the rest of the data (last transfer)
- REG_SPICNT = SPI_ENABLE | 0x201;
- REG_SPIDATA = 0;
- SerialWaitBusy();
-
- result2 = REG_SPIDATA >>3;
-
- REG_IME = oldIME;
-
- // Return the result
- return ((result & 0x7F) << 5) | result2;
-}
-
-
-//---------------------------------------------------------------------------------
-uint32 touchReadTemperature(int * t1, int * t2) {
-//---------------------------------------------------------------------------------
- *t1 = touchRead(TSC_MEASURE_TEMP1);
- *t2 = touchRead(TSC_MEASURE_TEMP2);
- return 8490 * (*t2 - *t1) - 273*4096;
-}
-
-
-static bool touchInit = false;
-static s32 xscale, yscale;
-static s32 xoffset, yoffset;
-
-//---------------------------------------------------------------------------------
-int16 readTouchValue(uint32 command, int16 *dist_max, u8 *err){
-//---------------------------------------------------------------------------------
- int16 values[5];
- int32 aux1, aux2, aux3, dist, dist2, result = 0;
- u8 i, j, k;
-
- *err = 1;
-
- SerialWaitBusy();
-
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
- REG_SPIDATA = command;
-
- SerialWaitBusy();
-
- for(i=0; i<5; i++){
- REG_SPIDATA = 0;
- SerialWaitBusy();
-
- aux1 = REG_SPIDATA;
- aux1 = aux1 & 0xFF;
- aux1 = aux1 << 16;
- aux1 = aux1 >> 8;
-
- values[4-i] = aux1;
-
- REG_SPIDATA = command;
- SerialWaitBusy();
-
- aux1 = REG_SPIDATA;
- aux1 = aux1 & 0xFF;
- aux1 = aux1 << 16;
-
- aux1 = values[4-i] | (aux1 >> 16);
- values[4-i] = ((aux1 & 0x7FF8) >> 3);
- }
-
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
- REG_SPIDATA = 0;
- SerialWaitBusy();
-
- dist = 0;
- for(i=0; i<4; i++){
- aux1 = values[i];
-
- for(j=i+1; j<5; j++){
- aux2 = values[j];
- aux2 = abs(aux1 - aux2);
- if(aux2>dist) dist = aux2;
- }
- }
-
- *dist_max = dist;
-
- for(i=0; i<3; i++){
- aux1 = values[i];
-
- for(j=i+1; j<4; j++){
- aux2 = values[j];
- dist = abs(aux1 - aux2);
-
- if( dist <= range ){
- for(k=j+1; k<5; k++){
- aux3 = values[k];
- dist2 = abs(aux1 - aux3);
-
- if( dist2 <= range ){
- result = aux2 + (aux1 << 1);
- result = result + aux3;
- result = result >> 2;
- result = result & (~7);
-
- *err = 0;
-
- break;
- }
- }
- }
- }
- }
-
- if((*err) == 1){
- result = values[0] + values[4];
- result = result >> 1;
- result = result & (~7);
- }
-
- return (result & 0xFFF);
-}
-
-//---------------------------------------------------------------------------------
-void UpdateRange(uint8 *this_range, int16 last_dist_max, u8 data_error, u8 tsc_touched){
-//---------------------------------------------------------------------------------
- //range_counter_1 = counter_0x380A98C
- //range_counter_2 = counter_0x380A990
- //Initial values:
- // range = 20
- // min_range = 20
-
- if(tsc_touched != 0){
- if( data_error == 0){
- range_counter_2 = 0;
-
- if( last_dist_max >= ((*this_range) >> 1)){
- range_counter_1 = 0;
- }else{
- range_counter_1++;
-
- if(range_counter_1 >= 4){
- range_counter_1 = 0;
-
- if((*this_range) > min_range){
- (*this_range)--;
- range_counter_2 = 3;
- }
- }
- }
- }else{
- range_counter_1 = 0;
- range_counter_2++;
-
- if(range_counter_2 >= 4){
-
- range_counter_2 = 0;
-
- if((*this_range) < 35){ //0x23 = 35
- *this_range = (*this_range) + 1;
- }
- }
- }
- }else{
- range_counter_2 = 0;
- range_counter_1 = 0;
- }
-}
-
-//---------------------------------------------------------------------------------
-// reading pixel position:
-//---------------------------------------------------------------------------------
-touchPosition touchReadXY() {
-//---------------------------------------------------------------------------------
-
- int16 dist_max_y, dist_max_x, dist_max;
- u8 error, error_where, first_check, i;
-
- touchPosition touchPos = { 0, 0, 0, 0, 0, 0 };
-
- if ( !touchInit ) {
-
- xscale = ((PersonalData->calX2px - PersonalData->calX1px) << 19) / ((PersonalData->calX2) - (PersonalData->calX1));
- yscale = ((PersonalData->calY2px - PersonalData->calY1px) << 19) / ((PersonalData->calY2) - (PersonalData->calY1));
-
- xoffset = ((PersonalData->calX1 + PersonalData->calX2) * xscale - ((PersonalData->calX1px + PersonalData->calX2px) << 19) ) / 2;
- yoffset = ((PersonalData->calY1 + PersonalData->calY2) * yscale - ((PersonalData->calY1px + PersonalData->calY2px) << 19) ) / 2;
- touchInit = true;
- }
-
- uint32 oldIME = REG_IME;
-
- REG_IME = 0;
-
- first_check = CheckStylus();
- if(first_check != 0){
- error_where = 0;
-
- touchPos.z1 = readTouchValue(TSC_MEASURE_Z1 | 1, &dist_max, &error);
- touchPos.z2 = readTouchValue(TSC_MEASURE_Z2 | 1, &dist_max, &error);
-
- touchPos.x = readTouchValue(TSC_MEASURE_X | 1, &dist_max_x, &error);
- if(error==1) error_where += 1;
-
- touchPos.y = readTouchValue(TSC_MEASURE_Y | 1, &dist_max_y, &error);
- if(error==1) error_where += 2;
-
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
- for(i=0; i<12; i++){
- REG_SPIDATA = 0;
-
- SerialWaitBusy();
- }
-
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
- REG_SPIDATA = 0;
-
- SerialWaitBusy();
-
- if(first_check == 2) error_where = 3;
-
- switch( CheckStylus() ){
- case 0:
- last_time_touched = 0;
- break;
- case 1:
- last_time_touched = 1;
-
- if(dist_max_x > dist_max_y)
- dist_max = dist_max_x;
- else
- dist_max = dist_max_y;
-
- break;
- case 2:
- last_time_touched = 0;
- error_where = 3;
-
- break;
- }
-
- s16 px = ( touchPos.x * xscale - xoffset + xscale/2 ) >>19;
- s16 py = ( touchPos.y * yscale - yoffset + yscale/2 ) >>19;
-
- if ( px < 0) px = 0;
- if ( py < 0) py = 0;
- if ( px > (SCREEN_WIDTH -1)) px = SCREEN_WIDTH -1;
- if ( py > (SCREEN_HEIGHT -1)) py = SCREEN_HEIGHT -1;
-
- touchPos.px = px;
- touchPos.py = py;
-
-
- }else{
- error_where = 3;
- touchPos.x = 0;
- touchPos.y = 0;
- last_time_touched = 0;
- }
-
- UpdateRange(&range, dist_max, error_where, last_time_touched);
-
- REG_IME = oldIME;
-
-
- return touchPos;
-
-}
-
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ Touch screen control for the ARM7
+
+ Copyright (C) 2005
+ Michael Noland (joat)
+ Jason Rogers (dovoto)
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+---------------------------------------------------------------------------------*/
+
+#include <nds/jtypes.h>
+#include <nds/system.h>
+#include <nds/arm7/touch.h>
+#include <nds/interrupts.h>
+
+#include <stdlib.h>
+
+static u8 last_time_touched = 0;
+
+static u8 range_counter_1 = 0;
+static u8 range_counter_2 = 0;
+static u8 range = 20;
+static u8 min_range = 20;
+
+//---------------------------------------------------------------------------------
+u8 CheckStylus(){
+//---------------------------------------------------------------------------------
+
+ SerialWaitBusy();
+
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS; //0x8A01;
+ REG_SPIDATA = TSC_MEASURE_TEMP1;
+
+ SerialWaitBusy();
+
+ REG_SPIDATA = 0;
+
+ SerialWaitBusy();
+
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;// 0x8201;
+ REG_SPIDATA = 0;
+
+ SerialWaitBusy();
+
+ if(last_time_touched == 1){
+ if( !(REG_KEYXY & 0x40) )
+ return 1;
+ else{
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
+ REG_SPIDATA = TSC_MEASURE_TEMP1;
+
+ SerialWaitBusy();
+
+ REG_SPIDATA = 0;
+
+ SerialWaitBusy();
+
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
+ REG_SPIDATA = 0;
+
+ SerialWaitBusy();
+
+ return !(REG_KEYXY & 0x40) ? 2 : 0;
+ }
+ }else{
+ return !(REG_KEYXY & 0x40) ? 1 : 0;
+ }
+}
+
+//---------------------------------------------------------------------------------
+uint16 touchRead(uint32 command) {
+//---------------------------------------------------------------------------------
+ uint16 result, result2;
+
+ uint32 oldIME = REG_IME;
+
+ REG_IME = 0;
+
+ SerialWaitBusy();
+
+ // Write the command and wait for it to complete
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS; //0x8A01;
+ REG_SPIDATA = command;
+ SerialWaitBusy();
+
+ // Write the second command and clock in part of the data
+ REG_SPIDATA = 0;
+ SerialWaitBusy();
+ result = REG_SPIDATA;
+
+ // Clock in the rest of the data (last transfer)
+ REG_SPICNT = SPI_ENABLE | 0x201;
+ REG_SPIDATA = 0;
+ SerialWaitBusy();
+
+ result2 = REG_SPIDATA >>3;
+
+ REG_IME = oldIME;
+
+ // Return the result
+ return ((result & 0x7F) << 5) | result2;
+}
+
+
+//---------------------------------------------------------------------------------
+uint32 touchReadTemperature(int * t1, int * t2) {
+//---------------------------------------------------------------------------------
+ *t1 = touchRead(TSC_MEASURE_TEMP1);
+ *t2 = touchRead(TSC_MEASURE_TEMP2);
+ return 8490 * (*t2 - *t1) - 273*4096;
+}
+
+
+static bool touchInit = false;
+static s32 xscale, yscale;
+static s32 xoffset, yoffset;
+
+//---------------------------------------------------------------------------------
+int16 readTouchValue(uint32 command, int16 *dist_max, u8 *err){
+//---------------------------------------------------------------------------------
+ int16 values[5];
+ int32 aux1, aux2, aux3, dist, dist2, result = 0;
+ u8 i, j, k;
+
+ *err = 1;
+
+ SerialWaitBusy();
+
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
+ REG_SPIDATA = command;
+
+ SerialWaitBusy();
+
+ for(i=0; i<5; i++){
+ REG_SPIDATA = 0;
+ SerialWaitBusy();
+
+ aux1 = REG_SPIDATA;
+ aux1 = aux1 & 0xFF;
+ aux1 = aux1 << 16;
+ aux1 = aux1 >> 8;
+
+ values[4-i] = aux1;
+
+ REG_SPIDATA = command;
+ SerialWaitBusy();
+
+ aux1 = REG_SPIDATA;
+ aux1 = aux1 & 0xFF;
+ aux1 = aux1 << 16;
+
+ aux1 = values[4-i] | (aux1 >> 16);
+ values[4-i] = ((aux1 & 0x7FF8) >> 3);
+ }
+
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
+ REG_SPIDATA = 0;
+ SerialWaitBusy();
+
+ dist = 0;
+ for(i=0; i<4; i++){
+ aux1 = values[i];
+
+ for(j=i+1; j<5; j++){
+ aux2 = values[j];
+ aux2 = abs(aux1 - aux2);
+ if(aux2>dist) dist = aux2;
+ }
+ }
+
+ *dist_max = dist;
+
+ for(i=0; i<3; i++){
+ aux1 = values[i];
+
+ for(j=i+1; j<4; j++){
+ aux2 = values[j];
+ dist = abs(aux1 - aux2);
+
+ if( dist <= range ){
+ for(k=j+1; k<5; k++){
+ aux3 = values[k];
+ dist2 = abs(aux1 - aux3);
+
+ if( dist2 <= range ){
+ result = aux2 + (aux1 << 1);
+ result = result + aux3;
+ result = result >> 2;
+ result = result & (~7);
+
+ *err = 0;
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if((*err) == 1){
+ result = values[0] + values[4];
+ result = result >> 1;
+ result = result & (~7);
+ }
+
+ return (result & 0xFFF);
+}
+
+//---------------------------------------------------------------------------------
+void UpdateRange(uint8 *this_range, int16 last_dist_max, u8 data_error, u8 tsc_touched){
+//---------------------------------------------------------------------------------
+ //range_counter_1 = counter_0x380A98C
+ //range_counter_2 = counter_0x380A990
+ //Initial values:
+ // range = 20
+ // min_range = 20
+
+ if(tsc_touched != 0){
+ if( data_error == 0){
+ range_counter_2 = 0;
+
+ if( last_dist_max >= ((*this_range) >> 1)){
+ range_counter_1 = 0;
+ }else{
+ range_counter_1++;
+
+ if(range_counter_1 >= 4){
+ range_counter_1 = 0;
+
+ if((*this_range) > min_range){
+ (*this_range)--;
+ range_counter_2 = 3;
+ }
+ }
+ }
+ }else{
+ range_counter_1 = 0;
+ range_counter_2++;
+
+ if(range_counter_2 >= 4){
+
+ range_counter_2 = 0;
+
+ if((*this_range) < 35){ //0x23 = 35
+ *this_range = (*this_range) + 1;
+ }
+ }
+ }
+ }else{
+ range_counter_2 = 0;
+ range_counter_1 = 0;
+ }
+}
+
+//---------------------------------------------------------------------------------
+// reading pixel position:
+//---------------------------------------------------------------------------------
+touchPosition touchReadXY() {
+//---------------------------------------------------------------------------------
+
+ int16 dist_max_y, dist_max_x, dist_max;
+ u8 error, error_where, first_check, i;
+
+ touchPosition touchPos = { 0, 0, 0, 0, 0, 0 };
+
+ if ( !touchInit ) {
+
+ xscale = ((PersonalData->calX2px - PersonalData->calX1px) << 19) / ((PersonalData->calX2) - (PersonalData->calX1));
+ yscale = ((PersonalData->calY2px - PersonalData->calY1px) << 19) / ((PersonalData->calY2) - (PersonalData->calY1));
+
+ xoffset = ((PersonalData->calX1 + PersonalData->calX2) * xscale - ((PersonalData->calX1px + PersonalData->calX2px) << 19) ) / 2;
+ yoffset = ((PersonalData->calY1 + PersonalData->calY2) * yscale - ((PersonalData->calY1px + PersonalData->calY2px) << 19) ) / 2;
+ touchInit = true;
+ }
+
+ uint32 oldIME = REG_IME;
+
+ REG_IME = 0;
+
+ first_check = CheckStylus();
+ if(first_check != 0){
+ error_where = 0;
+
+ touchPos.z1 = readTouchValue(TSC_MEASURE_Z1 | 1, &dist_max, &error);
+ touchPos.z2 = readTouchValue(TSC_MEASURE_Z2 | 1, &dist_max, &error);
+
+ touchPos.x = readTouchValue(TSC_MEASURE_X | 1, &dist_max_x, &error);
+ if(error==1) error_where += 1;
+
+ touchPos.y = readTouchValue(TSC_MEASURE_Y | 1, &dist_max_y, &error);
+ if(error==1) error_where += 2;
+
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
+ for(i=0; i<12; i++){
+ REG_SPIDATA = 0;
+
+ SerialWaitBusy();
+ }
+
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH;
+ REG_SPIDATA = 0;
+
+ SerialWaitBusy();
+
+ if(first_check == 2) error_where = 3;
+
+ switch( CheckStylus() ){
+ case 0:
+ last_time_touched = 0;
+ break;
+ case 1:
+ last_time_touched = 1;
+
+ if(dist_max_x > dist_max_y)
+ dist_max = dist_max_x;
+ else
+ dist_max = dist_max_y;
+
+ break;
+ case 2:
+ last_time_touched = 0;
+ error_where = 3;
+
+ break;
+ }
+
+ s16 px = ( touchPos.x * xscale - xoffset + xscale/2 ) >>19;
+ s16 py = ( touchPos.y * yscale - yoffset + yscale/2 ) >>19;
+
+ if ( px < 0) px = 0;
+ if ( py < 0) py = 0;
+ if ( px > (SCREEN_WIDTH -1)) px = SCREEN_WIDTH -1;
+ if ( py > (SCREEN_HEIGHT -1)) py = SCREEN_HEIGHT -1;
+
+ touchPos.px = px;
+ touchPos.py = py;
+
+
+ }else{
+ error_where = 3;
+ touchPos.x = 0;
+ touchPos.y = 0;
+ last_time_touched = 0;
+ }
+
+ UpdateRange(&range, dist_max, error_where, last_time_touched);
+
+ REG_IME = oldIME;
+
+
+ return touchPos;
+
+}
+
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/userSettings.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/userSettings.c
index eb546c7ddc..8e92cb2b79 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm7/userSettings.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm7/userSettings.c
@@ -1,71 +1,71 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- Copyright (C) 2005
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
----------------------------------------------------------------------------------*/
-
-#include <nds/arm7/serial.h>
-#include <nds/system.h>
-#include <string.h>
-
-//---------------------------------------------------------------------------------
-void readUserSettings() {
-//---------------------------------------------------------------------------------
-
- PERSONAL_DATA slot1;
- PERSONAL_DATA slot2;
-
- short slot1count, slot2count;
- short slot1CRC, slot2CRC;
-
- uint32 userSettingsBase;
- readFirmware( 0x20, &userSettingsBase,2);
-
- uint32 slot1Address = userSettingsBase * 8;
- uint32 slot2Address = userSettingsBase * 8 + 0x100;
-
- readFirmware( slot1Address , &slot1, sizeof(PERSONAL_DATA));
- readFirmware( slot2Address , &slot2, sizeof(PERSONAL_DATA));
- readFirmware( slot1Address + 0x70, &slot1count, 2);
- readFirmware( slot2Address + 0x70, &slot2count, 2);
- readFirmware( slot1Address + 0x72, &slot1CRC, 2);
- readFirmware( slot2Address + 0x72, &slot2CRC, 2);
-
- // default to slot 1 user Settings
- void *currentSettings = &slot1;
-
- short calc1CRC = swiCRC16( 0xffff, &slot1, sizeof(PERSONAL_DATA));
- short calc2CRC = swiCRC16( 0xffff, &slot2, sizeof(PERSONAL_DATA));
-
- // bail out if neither slot is valid
- if ( calc1CRC != slot1CRC && calc2CRC != slot2CRC) return;
-
- // if both slots are valid pick the most recent
- if ( calc1CRC == slot1CRC && calc2CRC == slot2CRC ) {
- currentSettings = (slot2count == (( slot2count + 1 ) & 0x7f) ? &slot2 : &slot1);
- } else {
- if ( calc2CRC == slot2CRC )
- currentSettings = &slot2;
- }
- memcpy ( PersonalData, currentSettings, sizeof(PERSONAL_DATA));
-
-}
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ Copyright (C) 2005
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+---------------------------------------------------------------------------------*/
+
+#include <nds/arm7/serial.h>
+#include <nds/system.h>
+#include <string.h>
+
+//---------------------------------------------------------------------------------
+void readUserSettings() {
+//---------------------------------------------------------------------------------
+
+ PERSONAL_DATA slot1;
+ PERSONAL_DATA slot2;
+
+ short slot1count, slot2count;
+ short slot1CRC, slot2CRC;
+
+ uint32 userSettingsBase;
+ readFirmware( 0x20, &userSettingsBase,2);
+
+ uint32 slot1Address = userSettingsBase * 8;
+ uint32 slot2Address = userSettingsBase * 8 + 0x100;
+
+ readFirmware( slot1Address , &slot1, sizeof(PERSONAL_DATA));
+ readFirmware( slot2Address , &slot2, sizeof(PERSONAL_DATA));
+ readFirmware( slot1Address + 0x70, &slot1count, 2);
+ readFirmware( slot2Address + 0x70, &slot2count, 2);
+ readFirmware( slot1Address + 0x72, &slot1CRC, 2);
+ readFirmware( slot2Address + 0x72, &slot2CRC, 2);
+
+ // default to slot 1 user Settings
+ void *currentSettings = &slot1;
+
+ short calc1CRC = swiCRC16( 0xffff, &slot1, sizeof(PERSONAL_DATA));
+ short calc2CRC = swiCRC16( 0xffff, &slot2, sizeof(PERSONAL_DATA));
+
+ // bail out if neither slot is valid
+ if ( calc1CRC != slot1CRC && calc2CRC != slot2CRC) return;
+
+ // if both slots are valid pick the most recent
+ if ( calc1CRC == slot1CRC && calc2CRC == slot2CRC ) {
+ currentSettings = (slot2count == (( slot2count + 1 ) & 0x7f) ? &slot2 : &slot1);
+ } else {
+ if ( calc2CRC == slot2CRC )
+ currentSettings = &slot2;
+ }
+ memcpy ( PersonalData, currentSettings, sizeof(PERSONAL_DATA));
+
+}
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/COS.bin b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/COS.bin
deleted file mode 100644
index fa384d6e1d..0000000000
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/COS.bin
+++ /dev/null
Binary files differ
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/SIN.bin b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/SIN.bin
deleted file mode 100644
index 6526dc10e2..0000000000
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/SIN.bin
+++ /dev/null
Binary files differ
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/TAN.bin b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/TAN.bin
deleted file mode 100644
index 2187f6d8a9..0000000000
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/TAN.bin
+++ /dev/null
Binary files differ
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/boxtest.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/boxtest.c
index caa26f74d5..47b44369c3 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/boxtest.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/boxtest.c
@@ -1,88 +1,88 @@
-/*---------------------------------------------------------------------------------
-$Id$
-
- BoxTest.c -- Code for performing hardware box test against viewing frustrum
-
- Copyright (C) 2005
- Michael Noland (joat)
- Jason Rogers (dovoto)
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
-
- 3. This notice may not be removed or altered from any source
- distribution.
-
----------------------------------------------------------------------------------*/
-
-#include <nds/arm9/video.h>
-#include <nds/arm9/videoGL.h>
-
-//---------------------------------------------------------------------------------
-void BoxTest_Asynch(v16 x, v16 y, v16 z, v16 width, v16 height, v16 depth)
-//---------------------------------------------------------------------------------
-{
- glPolyFmt(BIT(12) | BIT(13));
- glBegin(GL_TRIANGLES);
- glEnd();
-
- GFX_BOX_TEST = VERTEX_PACK(x, y);
- GFX_BOX_TEST = VERTEX_PACK(z, width);
- GFX_BOX_TEST = VERTEX_PACK(height, depth);
-}
-
-//---------------------------------------------------------------------------------
-void BoxTestf_Asynch(float x, float y, float z, float width, float height, float depth)
-//---------------------------------------------------------------------------------
-{
- BoxTest_Asynch(floattov16(x), floattov16(y), floattov16(z),
- floattov16(width), floattov16(height), floattov16(depth));
-}
-
-//---------------------------------------------------------------------------------
-int BoxTestResult(void)
-//---------------------------------------------------------------------------------
-{
- while(GFX_STATUS & BIT(0));
-
- return (GFX_STATUS & BIT(1));
-}
-
-//---------------------------------------------------------------------------------
-int BoxTest(v16 x, v16 y, v16 z, v16 width, v16 height, v16 depth)
-//---------------------------------------------------------------------------------
-{
- glPolyFmt(BIT(12) | BIT(13));
- glBegin(GL_TRIANGLES);
- glEnd();
-
- GFX_BOX_TEST = VERTEX_PACK(x, y);
- GFX_BOX_TEST = VERTEX_PACK(z, width);
- GFX_BOX_TEST = VERTEX_PACK(height, depth);
-
- while(GFX_STATUS & BIT(0));
-
- return (GFX_STATUS & BIT(1));
-}
-
-//---------------------------------------------------------------------------------
-int BoxTestf(float x, float y, float z, float width, float height, float depth)
-//---------------------------------------------------------------------------------
-{
- return BoxTest(floattov16(x), floattov16(y), floattov16(z),
- floattov16(width), floattov16(height), floattov16(depth));
-}
+/*---------------------------------------------------------------------------------
+$Id$
+
+ BoxTest.c -- Code for performing hardware box test against viewing frustrum
+
+ Copyright (C) 2005
+ Michael Noland (joat)
+ Jason Rogers (dovoto)
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+---------------------------------------------------------------------------------*/
+
+#include <nds/arm9/video.h>
+#include <nds/arm9/videoGL.h>
+
+//---------------------------------------------------------------------------------
+void BoxTest_Asynch(v16 x, v16 y, v16 z, v16 width, v16 height, v16 depth)
+//---------------------------------------------------------------------------------
+{
+ glPolyFmt(BIT(12) | BIT(13));
+ glBegin(GL_TRIANGLES);
+ glEnd();
+
+ GFX_BOX_TEST = VERTEX_PACK(x, y);
+ GFX_BOX_TEST = VERTEX_PACK(z, width);
+ GFX_BOX_TEST = VERTEX_PACK(height, depth);
+}
+
+//---------------------------------------------------------------------------------
+void BoxTestf_Asynch(float x, float y, float z, float width, float height, float depth)
+//---------------------------------------------------------------------------------
+{
+ BoxTest_Asynch(floattov16(x), floattov16(y), floattov16(z),
+ floattov16(width), floattov16(height), floattov16(depth));
+}
+
+//---------------------------------------------------------------------------------
+int BoxTestResult(void)
+//---------------------------------------------------------------------------------
+{
+ while(GFX_STATUS & BIT(0));
+
+ return (GFX_STATUS & BIT(1));
+}
+
+//---------------------------------------------------------------------------------
+int BoxTest(v16 x, v16 y, v16 z, v16 width, v16 height, v16 depth)
+//---------------------------------------------------------------------------------
+{
+ glPolyFmt(BIT(12) | BIT(13));
+ glBegin(GL_TRIANGLES);
+ glEnd();
+
+ GFX_BOX_TEST = VERTEX_PACK(x, y);
+ GFX_BOX_TEST = VERTEX_PACK(z, width);
+ GFX_BOX_TEST = VERTEX_PACK(height, depth);
+
+ while(GFX_STATUS & BIT(0));
+
+ return (GFX_STATUS & BIT(1));
+}
+
+//---------------------------------------------------------------------------------
+int BoxTestf(float x, float y, float z, float width, float height, float depth)
+//---------------------------------------------------------------------------------
+{
+ return BoxTest(floattov16(x), floattov16(y), floattov16(z),
+ floattov16(width), floattov16(height), floattov16(depth));
+}
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/default_font.bin b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/default_font.bin
deleted file mode 100644
index 112e78b336..0000000000
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/default_font.bin
+++ /dev/null
Binary files differ
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/gurumeditation.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/gurumeditation.c
index 3eef28ea31..8209be6fa1 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/gurumeditation.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/gurumeditation.c
@@ -1,270 +1,270 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- Copyright (C) 2005
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
----------------------------------------------------------------------------------*/
-
-#include <nds/jtypes.h>
-#include <nds/memory.h>
-
-#include <nds/arm9/video.h>
-#include <nds/arm9/console.h>
-#include <nds/arm9/exceptions.h>
-#include <nds/arm9/background.h>
-
-#include <stdio.h>
-
-//---------------------------------------------------------------------------------
-unsigned long ARMShift(unsigned long value,unsigned char shift) {
-//---------------------------------------------------------------------------------
- // no shift at all
- if (shift == 0x0B) return value ;
- int index ;
- if (shift & 0x01) {
- // shift index is a register
- index = exceptionRegisters[(shift >> 4) & 0x0F];
- } else {
- // constant shift index
- index = ((shift >> 3) & 0x1F) ;
- } ;
- int i ;
- bool isN ;
- switch (shift & 0x06) {
- case 0x00:
- // logical left
- return (value << index) ;
- case 0x02:
- // logical right
- return (value >> index) ;
- case 0x04:
- // arithmetical right
- isN = (value & 0x80000000) ;
- value = value >> index ;
- if (isN) {
- for (i=31;i>31-index;i--) {
- value = value | (1 << i) ;
- } ;
- } ;
- return value ;
- case 0x06:
- // rotate right
- index = index & 0x1F;
- value = (value >> index) | (value << (32-index));
- return value;
- };
- return value;
-}
-
-
-//---------------------------------------------------------------------------------
-u32 getExceptionAddress( u32 opcodeAddress, u32 thumbState) {
-//---------------------------------------------------------------------------------
-
- int Rf, Rb, Rd, Rn, Rm;
-
- if (thumbState) {
- // Thumb
-
- unsigned short opcode = *(unsigned short *)opcodeAddress ;
- // ldr r,[pc,###] 01001ddd ffffffff
- // ldr r,[r,r] 0101xx0f ffbbbddd
- // ldrsh 0101xx1f ffbbbddd
- // ldr r,[r,imm] 011xxfff ffbbbddd
- // ldrh 1000xfff ffbbbddd
- // ldr r,[sp,###] 1001xddd ffffffff
- // push 1011x10l llllllll
- // ldm 1100xbbb llllllll
-
-
- if ((opcode & 0xF800) == 0x4800) {
- // ldr r,[pc,###]
- s8 offset = opcode & 0xff;
- return exceptionRegisters[15] + offset;
- } else if ((opcode & 0xF200) == 0x5000) {
- // ldr r,[r,r]
- Rb = (opcode >> 3) & 0x07 ;
- Rf = (opcode >> 6) & 0x07 ;
- return exceptionRegisters[Rb] + exceptionRegisters[Rf];
-
- } else if ((opcode & 0xF200) == 0x5200) {
- // ldrsh
- Rb = (opcode >> 3) & 0x07;
- Rf = (opcode >> 6) & 0x03;
- return exceptionRegisters[Rb] + exceptionRegisters[Rf];
-
- } else if ((opcode & 0xE000) == 0x6000) {
- // ldr r,[r,imm]
- Rb = (opcode >> 3) & 0x07;
- Rf = (opcode >> 6) & 0x1F ;
- return exceptionRegisters[Rb] + (Rf << 2);
- } else if ((opcode & 0xF000) == 0x8000) {
- // ldrh
- Rb = (opcode >> 3) & 0x07 ;
- Rf = (opcode >> 6) & 0x1F ;
- return exceptionRegisters[Rb] + (Rf << 2);
- } else if ((opcode & 0xF000) == 0x9000) {
- // ldr r,[sp,#imm]
- s8 offset = opcode & 0xff;
- return exceptionRegisters[13] + offset;
- } else if ((opcode & 0xF700) == 0xB500) {
- // push/pop
- return exceptionRegisters[13];
- } else if ((opcode & 0xF000) == 0xC000) {
- // ldm/stm
- Rd = (opcode >> 8) & 0x07;
- return exceptionRegisters[Rd];
- }
- } else {
- // arm32
- unsigned long opcode = *(unsigned long *)opcodeAddress ;
-
- // SWP xxxx0001 0x00nnnn dddd0000 1001mmmm
- // STR/LDR xxxx01xx xxxxnnnn ddddffff ffffffff
- // STRH/LDRH xxxx000x x0xxnnnn dddd0000 1xx1mmmm
- // STRH/LDRH xxxx000x x1xxnnnn ddddffff 1xx1ffff
- // STM/LDM xxxx100x xxxxnnnn llllllll llllllll
-
- if ((opcode & 0x0FB00FF0) == 0x01000090) {
- // SWP
- Rn = (opcode >> 16) & 0x0F;
- return exceptionRegisters[Rn];
- } else if ((opcode & 0x0C000000) == 0x04000000) {
- // STR/LDR
- Rn = (opcode >> 16) & 0x0F;
- if (opcode & 0x02000000) {
- // Register offset
- Rm = opcode & 0x0F;
- if (opcode & 0x01000000) {
- unsigned short shift = (unsigned short)((opcode >> 4) & 0xFF) ;
- // pre indexing
- long Offset = ARMShift(exceptionRegisters[Rm],shift);
- // add or sub the offset depending on the U-Bit
- return exceptionRegisters[Rn] + ((opcode & 0x00800000)?Offset:-Offset);
- } else {
- // post indexing
- return exceptionRegisters[Rn];
- }
- } else {
- // Immediate offset
- unsigned long Offset = (opcode & 0xFFF) ;
- if (opcode & 0x01000000) {
- // pre indexing
- // add or sub the offset depending on the U-Bit
- return exceptionRegisters[Rn] + ((opcode & 0x00800000)?Offset:-Offset);
- } else {
- // post indexing
- return exceptionRegisters[Rn];
- }
- }
- } else if ((opcode & 0x0E400F90) == 0x00000090) {
- // LDRH/STRH with register Rm
- Rn = (opcode >> 16) & 0x0F;
- Rd = (opcode >> 12) & 0x0F;
- Rm = opcode & 0x0F;
- unsigned short shift = (unsigned short)((opcode >> 4) & 0xFF);
- long Offset = ARMShift(exceptionRegisters[Rm],shift);
- // add or sub the offset depending on the U-Bit
- return exceptionRegisters[Rn] + ((opcode & 0x00800000)?Offset:-Offset);
- } else if ((opcode & 0x0E400F90) == 0x00400090) {
- // LDRH/STRH with immediate offset
- Rn = (opcode >> 16) & 0x0F;
- Rd = (opcode >> 12) & 0x0F;
- unsigned long Offset = (opcode & 0xF) | ((opcode & 0xF00)>>8) ;
- // add or sub the offset depending on the U-Bit
- return exceptionRegisters[Rn] + ((opcode & 0x00800000)?Offset:-Offset) ;
- } else if ((opcode & 0x0E000000) == 0x08000000) {
- // LDM/STM
- Rn = (opcode >> 16) & 0x0F;
- return exceptionRegisters[Rn];
- }
- }
- return 0;
-}
-
-static const char *registerNames[] =
- { "r0","r1","r2","r3","r4","r5","r6","r7",
- "r8 ","r9 ","r10","r11","r12","sp ","lr ","pc " };
-
-extern const char __itcm_start[];
-//---------------------------------------------------------------------------------
-static void defaultHandler() {
-//---------------------------------------------------------------------------------
- videoSetMode(0);
- videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
- vramSetBankC(VRAM_C_SUB_BG);
-
- SUB_BG0_CR = BG_MAP_BASE(31);
-
- BG_PALETTE_SUB[0] = RGB15(31,0,0);
- BG_PALETTE_SUB[255] = RGB15(31,31,31);
-
- consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
-
- iprintf("\x1b[5CGuru Meditation Error!\n");
- u32 currentMode = getCPSR() & 0x1f;
- u32 thumbState = ((*(u32*)0x027FFD90) & 0x20);
-
- u32 codeAddress, exceptionAddress = 0;
-
- int offset = 8;
-
- if ( currentMode == 0x17 ) {
- iprintf ("\x1b[10Cdata abort!\n\n");
- codeAddress = exceptionRegisters[15] - offset;
- if ( (codeAddress > 0x02000000 && codeAddress < 0x02400000) ||
- (codeAddress > (u32)__itcm_start && codeAddress < (u32)(__itcm_start + 32768)) )
- exceptionAddress = getExceptionAddress( codeAddress, thumbState);
- else
- exceptionAddress = codeAddress;
-
- } else {
- if (thumbState)
- offset = 2;
- else
- offset = 4;
- iprintf("\x1b[5Cundefined instruction!\n\n");
- codeAddress = exceptionRegisters[15] - offset;
- exceptionAddress = codeAddress;
- }
-
- iprintf(" pc: %08X addr: %08X\n\n",codeAddress,exceptionAddress);
-
- int i;
- for ( i=0; i < 8; i++ ) {
- iprintf( " %s: %08X %s: %08X\n",
- registerNames[i], exceptionRegisters[i],
- registerNames[i+8],exceptionRegisters[i+8]);
- }
- iprintf("\n");
- u32 *stack = (u32 *)exceptionRegisters[13];
- for ( i=0; i<10; i++ ) {
- iprintf( "\x1b[%d;2H%08X: %08X %08X", i + 14, (u32)&stack[i*2],stack[i*2], stack[(i*2)+1] );
- }
- while(1);
-
-}
-
-//---------------------------------------------------------------------------------
-void defaultExceptionHandler() {
-//---------------------------------------------------------------------------------
- setExceptionHandler(defaultHandler) ;
-}
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ Copyright (C) 2005
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+---------------------------------------------------------------------------------*/
+
+#include <nds/jtypes.h>
+#include <nds/memory.h>
+
+#include <nds/arm9/video.h>
+#include <nds/arm9/console.h>
+#include <nds/arm9/exceptions.h>
+#include <nds/arm9/background.h>
+
+#include <stdio.h>
+
+//---------------------------------------------------------------------------------
+unsigned long ARMShift(unsigned long value,unsigned char shift) {
+//---------------------------------------------------------------------------------
+ // no shift at all
+ if (shift == 0x0B) return value ;
+ int index ;
+ if (shift & 0x01) {
+ // shift index is a register
+ index = exceptionRegisters[(shift >> 4) & 0x0F];
+ } else {
+ // constant shift index
+ index = ((shift >> 3) & 0x1F) ;
+ } ;
+ int i ;
+ bool isN ;
+ switch (shift & 0x06) {
+ case 0x00:
+ // logical left
+ return (value << index) ;
+ case 0x02:
+ // logical right
+ return (value >> index) ;
+ case 0x04:
+ // arithmetical right
+ isN = (value & 0x80000000) ;
+ value = value >> index ;
+ if (isN) {
+ for (i=31;i>31-index;i--) {
+ value = value | (1 << i) ;
+ } ;
+ } ;
+ return value ;
+ case 0x06:
+ // rotate right
+ index = index & 0x1F;
+ value = (value >> index) | (value << (32-index));
+ return value;
+ };
+ return value;
+}
+
+
+//---------------------------------------------------------------------------------
+u32 getExceptionAddress( u32 opcodeAddress, u32 thumbState) {
+//---------------------------------------------------------------------------------
+
+ int Rf, Rb, Rd, Rn, Rm;
+
+ if (thumbState) {
+ // Thumb
+
+ unsigned short opcode = *(unsigned short *)opcodeAddress ;
+ // ldr r,[pc,###] 01001ddd ffffffff
+ // ldr r,[r,r] 0101xx0f ffbbbddd
+ // ldrsh 0101xx1f ffbbbddd
+ // ldr r,[r,imm] 011xxfff ffbbbddd
+ // ldrh 1000xfff ffbbbddd
+ // ldr r,[sp,###] 1001xddd ffffffff
+ // push 1011x10l llllllll
+ // ldm 1100xbbb llllllll
+
+
+ if ((opcode & 0xF800) == 0x4800) {
+ // ldr r,[pc,###]
+ s8 offset = opcode & 0xff;
+ return exceptionRegisters[15] + offset;
+ } else if ((opcode & 0xF200) == 0x5000) {
+ // ldr r,[r,r]
+ Rb = (opcode >> 3) & 0x07 ;
+ Rf = (opcode >> 6) & 0x07 ;
+ return exceptionRegisters[Rb] + exceptionRegisters[Rf];
+
+ } else if ((opcode & 0xF200) == 0x5200) {
+ // ldrsh
+ Rb = (opcode >> 3) & 0x07;
+ Rf = (opcode >> 6) & 0x03;
+ return exceptionRegisters[Rb] + exceptionRegisters[Rf];
+
+ } else if ((opcode & 0xE000) == 0x6000) {
+ // ldr r,[r,imm]
+ Rb = (opcode >> 3) & 0x07;
+ Rf = (opcode >> 6) & 0x1F ;
+ return exceptionRegisters[Rb] + (Rf << 2);
+ } else if ((opcode & 0xF000) == 0x8000) {
+ // ldrh
+ Rb = (opcode >> 3) & 0x07 ;
+ Rf = (opcode >> 6) & 0x1F ;
+ return exceptionRegisters[Rb] + (Rf << 2);
+ } else if ((opcode & 0xF000) == 0x9000) {
+ // ldr r,[sp,#imm]
+ s8 offset = opcode & 0xff;
+ return exceptionRegisters[13] + offset;
+ } else if ((opcode & 0xF700) == 0xB500) {
+ // push/pop
+ return exceptionRegisters[13];
+ } else if ((opcode & 0xF000) == 0xC000) {
+ // ldm/stm
+ Rd = (opcode >> 8) & 0x07;
+ return exceptionRegisters[Rd];
+ }
+ } else {
+ // arm32
+ unsigned long opcode = *(unsigned long *)opcodeAddress ;
+
+ // SWP xxxx0001 0x00nnnn dddd0000 1001mmmm
+ // STR/LDR xxxx01xx xxxxnnnn ddddffff ffffffff
+ // STRH/LDRH xxxx000x x0xxnnnn dddd0000 1xx1mmmm
+ // STRH/LDRH xxxx000x x1xxnnnn ddddffff 1xx1ffff
+ // STM/LDM xxxx100x xxxxnnnn llllllll llllllll
+
+ if ((opcode & 0x0FB00FF0) == 0x01000090) {
+ // SWP
+ Rn = (opcode >> 16) & 0x0F;
+ return exceptionRegisters[Rn];
+ } else if ((opcode & 0x0C000000) == 0x04000000) {
+ // STR/LDR
+ Rn = (opcode >> 16) & 0x0F;
+ if (opcode & 0x02000000) {
+ // Register offset
+ Rm = opcode & 0x0F;
+ if (opcode & 0x01000000) {
+ unsigned short shift = (unsigned short)((opcode >> 4) & 0xFF) ;
+ // pre indexing
+ long Offset = ARMShift(exceptionRegisters[Rm],shift);
+ // add or sub the offset depending on the U-Bit
+ return exceptionRegisters[Rn] + ((opcode & 0x00800000)?Offset:-Offset);
+ } else {
+ // post indexing
+ return exceptionRegisters[Rn];
+ }
+ } else {
+ // Immediate offset
+ unsigned long Offset = (opcode & 0xFFF) ;
+ if (opcode & 0x01000000) {
+ // pre indexing
+ // add or sub the offset depending on the U-Bit
+ return exceptionRegisters[Rn] + ((opcode & 0x00800000)?Offset:-Offset);
+ } else {
+ // post indexing
+ return exceptionRegisters[Rn];
+ }
+ }
+ } else if ((opcode & 0x0E400F90) == 0x00000090) {
+ // LDRH/STRH with register Rm
+ Rn = (opcode >> 16) & 0x0F;
+ Rd = (opcode >> 12) & 0x0F;
+ Rm = opcode & 0x0F;
+ unsigned short shift = (unsigned short)((opcode >> 4) & 0xFF);
+ long Offset = ARMShift(exceptionRegisters[Rm],shift);
+ // add or sub the offset depending on the U-Bit
+ return exceptionRegisters[Rn] + ((opcode & 0x00800000)?Offset:-Offset);
+ } else if ((opcode & 0x0E400F90) == 0x00400090) {
+ // LDRH/STRH with immediate offset
+ Rn = (opcode >> 16) & 0x0F;
+ Rd = (opcode >> 12) & 0x0F;
+ unsigned long Offset = (opcode & 0xF) | ((opcode & 0xF00)>>8) ;
+ // add or sub the offset depending on the U-Bit
+ return exceptionRegisters[Rn] + ((opcode & 0x00800000)?Offset:-Offset) ;
+ } else if ((opcode & 0x0E000000) == 0x08000000) {
+ // LDM/STM
+ Rn = (opcode >> 16) & 0x0F;
+ return exceptionRegisters[Rn];
+ }
+ }
+ return 0;
+}
+
+static const char *registerNames[] =
+ { "r0","r1","r2","r3","r4","r5","r6","r7",
+ "r8 ","r9 ","r10","r11","r12","sp ","lr ","pc " };
+
+extern const char __itcm_start[];
+//---------------------------------------------------------------------------------
+static void defaultHandler() {
+//---------------------------------------------------------------------------------
+ videoSetMode(0);
+ videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
+ vramSetBankC(VRAM_C_SUB_BG);
+
+ SUB_BG0_CR = BG_MAP_BASE(31);
+
+ BG_PALETTE_SUB[0] = RGB15(31,0,0);
+ BG_PALETTE_SUB[255] = RGB15(31,31,31);
+
+ consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
+
+ iprintf("\x1b[5CGuru Meditation Error!\n");
+ u32 currentMode = getCPSR() & 0x1f;
+ u32 thumbState = ((*(u32*)0x027FFD90) & 0x20);
+
+ u32 codeAddress, exceptionAddress = 0;
+
+ int offset = 8;
+
+ if ( currentMode == 0x17 ) {
+ iprintf ("\x1b[10Cdata abort!\n\n");
+ codeAddress = exceptionRegisters[15] - offset;
+ if ( (codeAddress > 0x02000000 && codeAddress < 0x02400000) ||
+ (codeAddress > (u32)__itcm_start && codeAddress < (u32)(__itcm_start + 32768)) )
+ exceptionAddress = getExceptionAddress( codeAddress, thumbState);
+ else
+ exceptionAddress = codeAddress;
+
+ } else {
+ if (thumbState)
+ offset = 2;
+ else
+ offset = 4;
+ iprintf("\x1b[5Cundefined instruction!\n\n");
+ codeAddress = exceptionRegisters[15] - offset;
+ exceptionAddress = codeAddress;
+ }
+
+ iprintf(" pc: %08X addr: %08X\n\n",codeAddress,exceptionAddress);
+
+ int i;
+ for ( i=0; i < 8; i++ ) {
+ iprintf( " %s: %08X %s: %08X\n",
+ registerNames[i], exceptionRegisters[i],
+ registerNames[i+8],exceptionRegisters[i+8]);
+ }
+ iprintf("\n");
+ u32 *stack = (u32 *)exceptionRegisters[13];
+ for ( i=0; i<10; i++ ) {
+ iprintf( "\x1b[%d;2H%08X: %08X %08X", i + 14, (u32)&stack[i*2],stack[i*2], stack[(i*2)+1] );
+ }
+ while(1);
+
+}
+
+//---------------------------------------------------------------------------------
+void defaultExceptionHandler() {
+//---------------------------------------------------------------------------------
+ setExceptionHandler(defaultHandler) ;
+}
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/ndsmotion.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/ndsmotion.c
index 7a31e1cfbc..830329fe11 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/ndsmotion.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/ndsmotion.c
@@ -1,488 +1,488 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- DS Motion Card/DS Motion Pak functionality
-
- Copyright (C) 2007
- Michael Noland (joat)
- Jason Rogers (dovoto)
- Dave Murphy (WinterMute)
- Keith Epstein (KeithE)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
----------------------------------------------------------------------------------*/
-
-#include <nds/card.h>
-#include <nds/system.h>
-#include <nds/memory.h>
-#include <nds/bios.h>
-#include <nds/arm9/ndsmotion.h>
-
-#define WAIT_CYCLES 185
-
-#define CARD_WaitBusy() while (CARD_CR1 & /*BUSY*/0x80);
-
-// enables SPI bus at 4.19 MHz
-#define SPI_On() CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40 | 0;
-
-// disables SPI bus
-#define SPI_Off() CARD_CR1 = 0;
-
-// Volatile GBA bus SRAM for reading from DS Motion Pak
-#define V_SRAM ((volatile unsigned char*)0x0A000000)
-
-
-int card_type = -1;
-
-//these are the default calibration values for sensitivity and offset
-MotionCalibration calibration = {2048, 2048, 2048, 1680, 819, 819, 819, 825};
-
-// sends and receives 1 byte on the SPI bus
-unsigned char motion_spi(unsigned char in_byte){
-
- unsigned char out_byte;
- CARD_EEPDATA = in_byte; // send the output byte to the SPI bus
- CARD_WaitBusy(); // wait for transmission to complete
- out_byte=CARD_EEPDATA; // read the input byte from the SPI bus
- return out_byte;
-}
-
-
-void motion_MK6_sensor_mode() {
- // send some commands on the SPI bus
- SPI_On()
- motion_spi(0xFE);
- SPI_Off()
- SPI_On()
- motion_spi(0xFD);
- SPI_Off()
- SPI_On()
- motion_spi(0xFB);
- SPI_Off()
- SPI_On()
- motion_spi(0xF8);
- SPI_Off()
-}
-
-void motion_MK6_EEPROM_mode() {
- // send some commands on the SPI bus
- SPI_On()
- motion_spi(0xFE);
- SPI_Off()
- SPI_On()
- motion_spi(0xFD);
- SPI_Off()
- SPI_On()
- motion_spi(0xFB);
- SPI_Off()
- SPI_On()
- motion_spi(0xF9);
- SPI_Off()
-}
-
-// checks whether a DS Motion Pak is plugged in
-int motion_pak_is_inserted(){
- int motion_pak = 0;
- unsigned char return_byte = V_SRAM[10]; // read first byte of DS Motion Pak check
- swiDelay(WAIT_CYCLES);
- return_byte = V_SRAM[0];
- swiDelay(WAIT_CYCLES);
- if (return_byte==0xF0) { // DS Motion Pak returns 0xF0
- return_byte = V_SRAM[0]; // read second byte of DS Motion Pak check
- swiDelay(WAIT_CYCLES);
- if(return_byte==0x0F) { // DS Motion Pak returns 0x0F
- motion_pak = 1;
- }
- }
- return motion_pak;
-}
-
-// checks whether a DS Motion Card is plugged in
-// this only works after motion_init()
-// it will return false if it is run before motion_init()
-int motion_card_is_inserted(){
- // send 0x03 to read from DS Motion Card control register
- SPI_On()
- motion_spi(0x03); // command to read from control register
- // if the control register is 0x04 then the enable was successful
- if( motion_spi(0x00) == 0x04)
- {
- SPI_Off()
- return 1;
- }
- SPI_Off();
- return 0;
-}
-
-// turn on the DS Motion Sensor (DS Motion Pak or DS Motion Card)
-// Requires knowing which type is present (can be found by using motion_init)
-int motion_enable(int card_type) {
- switch (card_type)
- {
- case 1: // DS Motion Pak - automatically enabled on powerup
- // check to see whether Motion Pak is alive
- return motion_pak_is_inserted();
- break;
- case 2: // DS Motion Card
- // send 0x04, 0x04 to enable
- SPI_On()
- motion_spi(0x04); // command to write to control register
- motion_spi(0x04); // enable
- SPI_Off()
- // check to see whether Motion Card is alive
- return motion_card_is_inserted();
- break;
- case 3: // MK6 - same command as DS Motion Card
- // send 0x04, 0x04 to enable
- SPI_On()
- motion_spi(0x04); // command to write to control register
- motion_spi(0x04); // enable
- SPI_Off()
- // check to see whether Motion Card is alive
- return motion_card_is_inserted();
- break;
- default: // if input parameter is not recognized, return 0
- return 0;
- break;
- }
-}
-
-// Initialize the DS Motion Sensor
-// Determines which DS Motion Sensor is present
-// Turns it on
-// Does not require knowing which type is present
-int motion_init() {
- sysSetBusOwners(true, true);
- // first, check for the DS Motion Pak - type 1
- if( motion_pak_is_inserted() == 1 )
- {
- card_type = 1;
- return 1;
- }// next, check for DS Motion Card - type 2
- if( motion_enable(2) == 1 )
- {
- card_type = 2;
- return 2;
- }
-
- motion_MK6_sensor_mode(); // send command to switch MK6 to sensor mode
-
- if( motion_enable(3) == 1 )
- {
- card_type = 3;
- return 3;
- }// if neither cases are true, then return 0 to indicate no DS Motion Sensor
- return 0;
-}
-
-// Deinitialize the DS Motion Sensor
-// In the case of a DS Motion Pak, do nothing - there is nothing to de-init
-// In the case of a DS Motion Card, turns off the accelerometer
-// In the case of an MK6, turns off accelerometer and switches out of sensor mode into EEPROM mode
-void motion_deinit() {
- // DS Motion Card - turn off accelerometer
- SPI_On()
- motion_spi(0x04); // command to write to control register
- motion_spi(0x00); // turn it off
- SPI_Off()
- // MK6 - switch to EEPROM mode
- motion_MK6_EEPROM_mode(); // switch MK6 to EEPROM mode
-}
-
-// read the X acceleration
-signed int motion_read_x(void) {
- unsigned char High_byte = 0;
- unsigned char Low_byte = 0;
- signed int output = 0;
- switch(card_type)
- {
- case 1: // DS Motion Pak
- High_byte = V_SRAM[2]; // Command to load X High onto bus
- swiDelay(WAIT_CYCLES); // wait for data ready
- High_byte = V_SRAM[0]; // get the high byte
- swiDelay(WAIT_CYCLES); // wait for data ready
- Low_byte = V_SRAM[0]; // get the low byte
- swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
- output = (signed int)( (High_byte<<8 | Low_byte)>>4);
- return output;
- break;
- case 2: // DS Motion Card
- SPI_On()
- motion_spi(0x00); // command to convert X axis
- swiDelay(625); // wait at least 40 microseconds for the A-D conversion
- output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
- SPI_Off()
- return output;
- break;
- case 3: // MK6 - same command as DS Motion Card
- SPI_On()
- motion_spi(0x00); // command to convert X axis
- swiDelay(625); // wait at least 40 microseconds for the A-D conversion
- output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
- SPI_Off()
- return output;
- break;
- default:
- return 0;
- break;
- }
-}
-
-// read the Y acceleration
-signed int motion_read_y() {
- unsigned char High_byte = 0;
- unsigned char Low_byte = 0;
- signed int output = 0;
- switch (card_type)
- {
- case 1: // DS Motion Pak
- High_byte = V_SRAM[4]; // Command to load Y High onto bus
- swiDelay(WAIT_CYCLES); // wait for data ready
- High_byte = V_SRAM[0]; // get the high byte
- swiDelay(WAIT_CYCLES); // wait for data ready
- Low_byte = V_SRAM[0]; // get the low byte
- swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
- output = (signed int)( (High_byte<<8 | Low_byte)>>4);
- return output;
- break;
- case 2: // DS Motion Card
- SPI_On()
- motion_spi(0x02); // command to convert Y axis
- swiDelay(625); // wait at least 40 microseconds for the A-D conversion
- output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
- SPI_Off()
- return output;
- break;
- case 3: // MK6 - same command as DS Motion Card
- SPI_On()
- motion_spi(0x02); // command to convert Y axis
- swiDelay(625); // wait at least 40 microseconds for the A-D conversion
- output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
- SPI_Off()
- return output;
- break;
- default:
- return 0;
- break;
- }
-}
-
-// read the Z acceleration
-signed int motion_read_z(void) {
- unsigned char High_byte = 0;
- unsigned char Low_byte = 0;
- signed int output = 0;
- switch (card_type)
- {
- case 1: // DS Motion Pak
- High_byte = V_SRAM[6]; // Command to load Z High onto bus
- swiDelay(WAIT_CYCLES); // wait for data ready
- High_byte = V_SRAM[0]; // get the high byte
- swiDelay(WAIT_CYCLES); // wait for data ready
- Low_byte = V_SRAM[0]; // get the low byte
- swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
- output = (signed int)( (High_byte<<8 | Low_byte)>>4);
- return output;
- break;
- case 2: // DS Motion Card
- SPI_On()
- motion_spi(0x01); // command to convert Z axis
- swiDelay(625); // wait at least 40 microseconds for the A-D conversion
- output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
- SPI_Off()
- return output;
- break;
- case 3: // MK6 - same command as DS Motion Card
- SPI_On()
- motion_spi(0x01); // command to convert Z axis
- swiDelay(625); // wait at least 40 microseconds for the A-D conversion
- output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
- SPI_Off()
- return output;
- break;
- default:
- return 0;
- break;
- }
-}
-
-// read the Z rotation (gyro)
-signed int motion_read_gyro(void) {
- unsigned char High_byte = 0;
- unsigned char Low_byte = 0;
- signed int output = 0;
- switch (card_type)
- {
- case 1: // DS Motion Pak
- High_byte = V_SRAM[8]; // Command to load Gyro High onto bus
- swiDelay(WAIT_CYCLES); // wait for data ready
- High_byte = V_SRAM[0]; // get the high byte
- swiDelay(WAIT_CYCLES); // wait for data ready
- Low_byte = V_SRAM[0]; // get the low byte
- swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
- output = (signed int)( (High_byte<<8 | Low_byte)>>4);
- return output;
- break;
- case 2: // DS Motion Card
- SPI_On()
- motion_spi(0x07); // command to convert Gyro axis
- swiDelay(625); // wait at least 40 microseconds for the A-D conversion
- output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
- SPI_Off()
- return output;
- break;
- case 3: // MK6 - same command as DS Motion Card
- SPI_On()
- motion_spi(0x07); // command to convert Gyro axis
- swiDelay(625); // wait at least 40 microseconds for the A-D conversion
- output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
- SPI_Off()
- return output;
- break;
- default:
- return 0;
- break;
- }
-}
-
-//gets acceleration value in mili G (where g is 9.8 m/s*s)
-int motion_acceleration_x(void){
- int accel = motion_read_x();
- return (accel - calibration.xoff) * 1000 / calibration.xsens;
-}
-
-//gets acceleration value in mili G (where g is 9.8 m/s*s)
-int motion_acceleration_y(void){
- int accel = motion_read_y();
- return (accel - calibration.yoff) * 1000 / calibration.ysens;
-}
-//gets acceleration value in mili G (where g is 9.8 m/s*s)
-int motion_acceleration_z(void){
- int accel = motion_read_z();
- return (accel - calibration.zoff) * 1000 / calibration.zsens;
-}
-
-//converts raw rotation value to degrees per second
-int motion_rotation(void){
- int rotation = motion_read_gyro();
- return (rotation - calibration.goff) * 1000 / calibration.gsens;
-}
-
-//this should be passed the raw reading at 1g for accurate
-//acceleration calculations. Default is 819
-void motion_set_sens_x(int sens){
- calibration.xsens = sens - calibration.xoff;
-}
-
-//this should be passed the raw reading at 1g for accurate
-//acceleration calculations. Default is 819
-void motion_set_sens_y(int sens){
- calibration.ysens = sens - calibration.yoff;
-}
-
-//this should be passed the raw reading at 1g for accurate
-//acceleration calculations. Default is 819
-void motion_set_sens_z(int sens){
- calibration.zsens = sens - calibration.zoff;
-}
-
-//this should be passed the raw reading at 1g for accurate
-//acceleration calculations. Default is 825
-void motion_set_sens_gyro(int sens){
- calibration.gsens = sens;
-}
-
-//this should be called when the axis is under no acceleration
-//default is 2048
-void motion_set_offs_x(void){
- calibration.xoff = motion_read_x();
-}
-
-//this should be called when the axis is under no acceleration
-//default is 2048
-void motion_set_offs_y(void){
- calibration.yoff = motion_read_y();
-}
-
-//this should be called when the axis is under no acceleration
-//default is 2048
-void motion_set_offs_z(void){
- calibration.zoff = motion_read_z();
-}
-
-//this should be called when the axis is under no acceleration
-//default is 1680
-void motion_set_offs_gyro(void){
- calibration.goff = motion_read_gyro();
-}
-
-MotionCalibration* motion_get_calibration(){
- return &calibration;
-}
-
-void motion_set_calibration(MotionCalibration* cal){
- calibration.xsens = cal->xsens;
- calibration.ysens = cal->ysens;
- calibration.zsens = cal->zsens;
- calibration.gsens = cal->gsens;
- calibration.xoff = cal->xoff;
- calibration.yoff = cal->yoff;
- calibration.zoff = cal->zoff;
- calibration.goff = cal->goff;
-}
-
-// enable analog input number 1 (ain_1)
-void motion_enable_ain_1(){
- unsigned char return_byte;
- return_byte = V_SRAM[16];
- swiDelay(WAIT_CYCLES);
-}
-
-// enable analog input number 2 (ain_2)
-void motion_enable_ain_2(){
- unsigned char return_byte;
- return_byte = V_SRAM[18];
- swiDelay(WAIT_CYCLES);
-}
-
-// read from the analog input number 1 - requires enabling ain_1 first
-int motion_read_ain_1(){
- unsigned char High_byte = V_SRAM[12]; // Command to load AIN_1 High onto bus
- swiDelay(WAIT_CYCLES); // wait for data ready
- High_byte = V_SRAM[0]; // get the high byte
- swiDelay(WAIT_CYCLES); // wait for data ready
- unsigned char Low_byte = V_SRAM[0]; // get the low byte
- swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
- signed int output = (signed int)( (High_byte<<8 | Low_byte)>>4);
- return output;
-}
-
-// read from the analog input number 2 - requires enabling ain_2 first
-int motion_read_ain_2(){
- unsigned char High_byte = V_SRAM[14]; // Command to load AIN_1 High onto bus
- swiDelay(WAIT_CYCLES); // wait for data ready
- High_byte = V_SRAM[0]; // get the high byte
- swiDelay(WAIT_CYCLES); // wait for data ready
- unsigned char Low_byte = V_SRAM[0]; // get the low byte
- swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
- signed int output = (signed int)( (High_byte<<8 | Low_byte)>>4);
- return output;
-}
-
-
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ DS Motion Card/DS Motion Pak functionality
+
+ Copyright (C) 2007
+ Michael Noland (joat)
+ Jason Rogers (dovoto)
+ Dave Murphy (WinterMute)
+ Keith Epstein (KeithE)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+---------------------------------------------------------------------------------*/
+
+#include <nds/card.h>
+#include <nds/system.h>
+#include <nds/memory.h>
+#include <nds/bios.h>
+#include <nds/arm9/ndsmotion.h>
+
+#define WAIT_CYCLES 185
+
+#define CARD_WaitBusy() while (CARD_CR1 & /*BUSY*/0x80);
+
+// enables SPI bus at 4.19 MHz
+#define SPI_On() CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40 | 0;
+
+// disables SPI bus
+#define SPI_Off() CARD_CR1 = 0;
+
+// Volatile GBA bus SRAM for reading from DS Motion Pak
+#define V_SRAM ((volatile unsigned char*)0x0A000000)
+
+
+int card_type = -1;
+
+//these are the default calibration values for sensitivity and offset
+MotionCalibration calibration = {2048, 2048, 2048, 1680, 819, 819, 819, 825};
+
+// sends and receives 1 byte on the SPI bus
+unsigned char motion_spi(unsigned char in_byte){
+
+ unsigned char out_byte;
+ CARD_EEPDATA = in_byte; // send the output byte to the SPI bus
+ CARD_WaitBusy(); // wait for transmission to complete
+ out_byte=CARD_EEPDATA; // read the input byte from the SPI bus
+ return out_byte;
+}
+
+
+void motion_MK6_sensor_mode() {
+ // send some commands on the SPI bus
+ SPI_On()
+ motion_spi(0xFE);
+ SPI_Off()
+ SPI_On()
+ motion_spi(0xFD);
+ SPI_Off()
+ SPI_On()
+ motion_spi(0xFB);
+ SPI_Off()
+ SPI_On()
+ motion_spi(0xF8);
+ SPI_Off()
+}
+
+void motion_MK6_EEPROM_mode() {
+ // send some commands on the SPI bus
+ SPI_On()
+ motion_spi(0xFE);
+ SPI_Off()
+ SPI_On()
+ motion_spi(0xFD);
+ SPI_Off()
+ SPI_On()
+ motion_spi(0xFB);
+ SPI_Off()
+ SPI_On()
+ motion_spi(0xF9);
+ SPI_Off()
+}
+
+// checks whether a DS Motion Pak is plugged in
+int motion_pak_is_inserted(){
+ int motion_pak = 0;
+ unsigned char return_byte = V_SRAM[10]; // read first byte of DS Motion Pak check
+ swiDelay(WAIT_CYCLES);
+ return_byte = V_SRAM[0];
+ swiDelay(WAIT_CYCLES);
+ if (return_byte==0xF0) { // DS Motion Pak returns 0xF0
+ return_byte = V_SRAM[0]; // read second byte of DS Motion Pak check
+ swiDelay(WAIT_CYCLES);
+ if(return_byte==0x0F) { // DS Motion Pak returns 0x0F
+ motion_pak = 1;
+ }
+ }
+ return motion_pak;
+}
+
+// checks whether a DS Motion Card is plugged in
+// this only works after motion_init()
+// it will return false if it is run before motion_init()
+int motion_card_is_inserted(){
+ // send 0x03 to read from DS Motion Card control register
+ SPI_On()
+ motion_spi(0x03); // command to read from control register
+ // if the control register is 0x04 then the enable was successful
+ if( motion_spi(0x00) == 0x04)
+ {
+ SPI_Off()
+ return 1;
+ }
+ SPI_Off();
+ return 0;
+}
+
+// turn on the DS Motion Sensor (DS Motion Pak or DS Motion Card)
+// Requires knowing which type is present (can be found by using motion_init)
+int motion_enable(int card_type) {
+ switch (card_type)
+ {
+ case 1: // DS Motion Pak - automatically enabled on powerup
+ // check to see whether Motion Pak is alive
+ return motion_pak_is_inserted();
+ break;
+ case 2: // DS Motion Card
+ // send 0x04, 0x04 to enable
+ SPI_On()
+ motion_spi(0x04); // command to write to control register
+ motion_spi(0x04); // enable
+ SPI_Off()
+ // check to see whether Motion Card is alive
+ return motion_card_is_inserted();
+ break;
+ case 3: // MK6 - same command as DS Motion Card
+ // send 0x04, 0x04 to enable
+ SPI_On()
+ motion_spi(0x04); // command to write to control register
+ motion_spi(0x04); // enable
+ SPI_Off()
+ // check to see whether Motion Card is alive
+ return motion_card_is_inserted();
+ break;
+ default: // if input parameter is not recognized, return 0
+ return 0;
+ break;
+ }
+}
+
+// Initialize the DS Motion Sensor
+// Determines which DS Motion Sensor is present
+// Turns it on
+// Does not require knowing which type is present
+int motion_init() {
+ sysSetBusOwners(true, true);
+ // first, check for the DS Motion Pak - type 1
+ if( motion_pak_is_inserted() == 1 )
+ {
+ card_type = 1;
+ return 1;
+ }// next, check for DS Motion Card - type 2
+ if( motion_enable(2) == 1 )
+ {
+ card_type = 2;
+ return 2;
+ }
+
+ motion_MK6_sensor_mode(); // send command to switch MK6 to sensor mode
+
+ if( motion_enable(3) == 1 )
+ {
+ card_type = 3;
+ return 3;
+ }// if neither cases are true, then return 0 to indicate no DS Motion Sensor
+ return 0;
+}
+
+// Deinitialize the DS Motion Sensor
+// In the case of a DS Motion Pak, do nothing - there is nothing to de-init
+// In the case of a DS Motion Card, turns off the accelerometer
+// In the case of an MK6, turns off accelerometer and switches out of sensor mode into EEPROM mode
+void motion_deinit() {
+ // DS Motion Card - turn off accelerometer
+ SPI_On()
+ motion_spi(0x04); // command to write to control register
+ motion_spi(0x00); // turn it off
+ SPI_Off()
+ // MK6 - switch to EEPROM mode
+ motion_MK6_EEPROM_mode(); // switch MK6 to EEPROM mode
+}
+
+// read the X acceleration
+signed int motion_read_x(void) {
+ unsigned char High_byte = 0;
+ unsigned char Low_byte = 0;
+ signed int output = 0;
+ switch(card_type)
+ {
+ case 1: // DS Motion Pak
+ High_byte = V_SRAM[2]; // Command to load X High onto bus
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ High_byte = V_SRAM[0]; // get the high byte
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ Low_byte = V_SRAM[0]; // get the low byte
+ swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
+ output = (signed int)( (High_byte<<8 | Low_byte)>>4);
+ return output;
+ break;
+ case 2: // DS Motion Card
+ SPI_On()
+ motion_spi(0x00); // command to convert X axis
+ swiDelay(625); // wait at least 40 microseconds for the A-D conversion
+ output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
+ SPI_Off()
+ return output;
+ break;
+ case 3: // MK6 - same command as DS Motion Card
+ SPI_On()
+ motion_spi(0x00); // command to convert X axis
+ swiDelay(625); // wait at least 40 microseconds for the A-D conversion
+ output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
+ SPI_Off()
+ return output;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+// read the Y acceleration
+signed int motion_read_y() {
+ unsigned char High_byte = 0;
+ unsigned char Low_byte = 0;
+ signed int output = 0;
+ switch (card_type)
+ {
+ case 1: // DS Motion Pak
+ High_byte = V_SRAM[4]; // Command to load Y High onto bus
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ High_byte = V_SRAM[0]; // get the high byte
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ Low_byte = V_SRAM[0]; // get the low byte
+ swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
+ output = (signed int)( (High_byte<<8 | Low_byte)>>4);
+ return output;
+ break;
+ case 2: // DS Motion Card
+ SPI_On()
+ motion_spi(0x02); // command to convert Y axis
+ swiDelay(625); // wait at least 40 microseconds for the A-D conversion
+ output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
+ SPI_Off()
+ return output;
+ break;
+ case 3: // MK6 - same command as DS Motion Card
+ SPI_On()
+ motion_spi(0x02); // command to convert Y axis
+ swiDelay(625); // wait at least 40 microseconds for the A-D conversion
+ output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
+ SPI_Off()
+ return output;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+// read the Z acceleration
+signed int motion_read_z(void) {
+ unsigned char High_byte = 0;
+ unsigned char Low_byte = 0;
+ signed int output = 0;
+ switch (card_type)
+ {
+ case 1: // DS Motion Pak
+ High_byte = V_SRAM[6]; // Command to load Z High onto bus
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ High_byte = V_SRAM[0]; // get the high byte
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ Low_byte = V_SRAM[0]; // get the low byte
+ swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
+ output = (signed int)( (High_byte<<8 | Low_byte)>>4);
+ return output;
+ break;
+ case 2: // DS Motion Card
+ SPI_On()
+ motion_spi(0x01); // command to convert Z axis
+ swiDelay(625); // wait at least 40 microseconds for the A-D conversion
+ output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
+ SPI_Off()
+ return output;
+ break;
+ case 3: // MK6 - same command as DS Motion Card
+ SPI_On()
+ motion_spi(0x01); // command to convert Z axis
+ swiDelay(625); // wait at least 40 microseconds for the A-D conversion
+ output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
+ SPI_Off()
+ return output;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+// read the Z rotation (gyro)
+signed int motion_read_gyro(void) {
+ unsigned char High_byte = 0;
+ unsigned char Low_byte = 0;
+ signed int output = 0;
+ switch (card_type)
+ {
+ case 1: // DS Motion Pak
+ High_byte = V_SRAM[8]; // Command to load Gyro High onto bus
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ High_byte = V_SRAM[0]; // get the high byte
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ Low_byte = V_SRAM[0]; // get the low byte
+ swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
+ output = (signed int)( (High_byte<<8 | Low_byte)>>4);
+ return output;
+ break;
+ case 2: // DS Motion Card
+ SPI_On()
+ motion_spi(0x07); // command to convert Gyro axis
+ swiDelay(625); // wait at least 40 microseconds for the A-D conversion
+ output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
+ SPI_Off()
+ return output;
+ break;
+ case 3: // MK6 - same command as DS Motion Card
+ SPI_On()
+ motion_spi(0x07); // command to convert Gyro axis
+ swiDelay(625); // wait at least 40 microseconds for the A-D conversion
+ output = ( (motion_spi(0x00)<<8)|motion_spi(0x00) )>>4; // read 16 bits and store as a 12 bit number
+ SPI_Off()
+ return output;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+//gets acceleration value in mili G (where g is 9.8 m/s*s)
+int motion_acceleration_x(void){
+ int accel = motion_read_x();
+ return (accel - calibration.xoff) * 1000 / calibration.xsens;
+}
+
+//gets acceleration value in mili G (where g is 9.8 m/s*s)
+int motion_acceleration_y(void){
+ int accel = motion_read_y();
+ return (accel - calibration.yoff) * 1000 / calibration.ysens;
+}
+//gets acceleration value in mili G (where g is 9.8 m/s*s)
+int motion_acceleration_z(void){
+ int accel = motion_read_z();
+ return (accel - calibration.zoff) * 1000 / calibration.zsens;
+}
+
+//converts raw rotation value to degrees per second
+int motion_rotation(void){
+ int rotation = motion_read_gyro();
+ return (rotation - calibration.goff) * 1000 / calibration.gsens;
+}
+
+//this should be passed the raw reading at 1g for accurate
+//acceleration calculations. Default is 819
+void motion_set_sens_x(int sens){
+ calibration.xsens = sens - calibration.xoff;
+}
+
+//this should be passed the raw reading at 1g for accurate
+//acceleration calculations. Default is 819
+void motion_set_sens_y(int sens){
+ calibration.ysens = sens - calibration.yoff;
+}
+
+//this should be passed the raw reading at 1g for accurate
+//acceleration calculations. Default is 819
+void motion_set_sens_z(int sens){
+ calibration.zsens = sens - calibration.zoff;
+}
+
+//this should be passed the raw reading at 1g for accurate
+//acceleration calculations. Default is 825
+void motion_set_sens_gyro(int sens){
+ calibration.gsens = sens;
+}
+
+//this should be called when the axis is under no acceleration
+//default is 2048
+void motion_set_offs_x(void){
+ calibration.xoff = motion_read_x();
+}
+
+//this should be called when the axis is under no acceleration
+//default is 2048
+void motion_set_offs_y(void){
+ calibration.yoff = motion_read_y();
+}
+
+//this should be called when the axis is under no acceleration
+//default is 2048
+void motion_set_offs_z(void){
+ calibration.zoff = motion_read_z();
+}
+
+//this should be called when the axis is under no acceleration
+//default is 1680
+void motion_set_offs_gyro(void){
+ calibration.goff = motion_read_gyro();
+}
+
+MotionCalibration* motion_get_calibration(){
+ return &calibration;
+}
+
+void motion_set_calibration(MotionCalibration* cal){
+ calibration.xsens = cal->xsens;
+ calibration.ysens = cal->ysens;
+ calibration.zsens = cal->zsens;
+ calibration.gsens = cal->gsens;
+ calibration.xoff = cal->xoff;
+ calibration.yoff = cal->yoff;
+ calibration.zoff = cal->zoff;
+ calibration.goff = cal->goff;
+}
+
+// enable analog input number 1 (ain_1)
+void motion_enable_ain_1(){
+ unsigned char return_byte;
+ return_byte = V_SRAM[16];
+ swiDelay(WAIT_CYCLES);
+}
+
+// enable analog input number 2 (ain_2)
+void motion_enable_ain_2(){
+ unsigned char return_byte;
+ return_byte = V_SRAM[18];
+ swiDelay(WAIT_CYCLES);
+}
+
+// read from the analog input number 1 - requires enabling ain_1 first
+int motion_read_ain_1(){
+ unsigned char High_byte = V_SRAM[12]; // Command to load AIN_1 High onto bus
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ High_byte = V_SRAM[0]; // get the high byte
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ unsigned char Low_byte = V_SRAM[0]; // get the low byte
+ swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
+ signed int output = (signed int)( (High_byte<<8 | Low_byte)>>4);
+ return output;
+}
+
+// read from the analog input number 2 - requires enabling ain_2 first
+int motion_read_ain_2(){
+ unsigned char High_byte = V_SRAM[14]; // Command to load AIN_1 High onto bus
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ High_byte = V_SRAM[0]; // get the high byte
+ swiDelay(WAIT_CYCLES); // wait for data ready
+ unsigned char Low_byte = V_SRAM[0]; // get the low byte
+ swiDelay(WAIT_CYCLES); // wait after for Motion Pak to be ready for next command
+ signed int output = (signed int)( (High_byte<<8 | Low_byte)>>4);
+ return output;
+}
+
+
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/videoGL.c b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/videoGL.c
index 167748294e..217beb0582 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/arm9/videoGL.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/arm9/videoGL.c
@@ -1,426 +1,426 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- Video API vaguely similar to OpenGL
-
- Copyright (C) 2005
- Michael Noland (joat)
- Jason Rogers (dovoto)
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
-
----------------------------------------------------------------------------------*/
-
-#include <nds/jtypes.h>
-#include <nds/memory.h>
-#include <nds/bios.h>
-#include <nds/arm9/math.h>
-#include <nds/arm9/video.h>
-#include <nds/arm9/videoGL.h>
-#include <nds/arm9/trig_lut.h>
-
-// this is the actual data of the globals for videoGL
-// Please use the glGlob pointer to access this data since that makes it easier to move stuff in/out of the header.
-static gl_hidden_globals glGlobalData;
-
-// This returns the pointer to the globals for videoGL
-gl_hidden_globals* glGetGlobals() {
- return &glGlobalData;
-}
-
-//---------------------------------------------------------------------------------
-void glRotatef32i(int angle, int32 x, int32 y, int32 z) {
-//---------------------------------------------------------------------------------
- int32 axis[3];
- int32 sine = SIN[angle & LUT_MASK];
- int32 cosine = COS[angle & LUT_MASK];
- int32 one_minus_cosine = inttof32(1) - cosine;
-
- axis[0]=x;
- axis[1]=y;
- axis[2]=z;
-
- normalizef32(axis); // should require passed in normalized?
-
- MATRIX_MULT3x3 = cosine + mulf32(one_minus_cosine, mulf32(axis[0], axis[0]));
- MATRIX_MULT3x3 = mulf32(one_minus_cosine, mulf32(axis[0], axis[1])) - mulf32(axis[2], sine);
- MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[0]), axis[2]) + mulf32(axis[1], sine);
-
- MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[0]), axis[1]) + mulf32(axis[2], sine);
- MATRIX_MULT3x3 = cosine + mulf32(mulf32(one_minus_cosine, axis[1]), axis[1]);
- MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[1]), axis[2]) - mulf32(axis[0], sine);
-
- MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[0]), axis[2]) - mulf32(axis[1], sine);
- MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[1]), axis[2]) + mulf32(axis[0], sine);
- MATRIX_MULT3x3 = cosine + mulf32(mulf32(one_minus_cosine, axis[2]), axis[2]);
-}
-
-
-
-
-//---------------------------------------------------------------------------------
-void glMaterialf(GL_MATERIALS_ENUM mode, rgb color) {
-//---------------------------------------------------------------------------------
- static uint32 diffuse_ambient = 0;
- static uint32 specular_emission = 0;
-
- switch(mode) {
- case GL_AMBIENT:
- diffuse_ambient = (color << 16) | (diffuse_ambient & 0xFFFF);
- break;
- case GL_DIFFUSE:
- diffuse_ambient = color | (diffuse_ambient & 0xFFFF0000);
- break;
- case GL_AMBIENT_AND_DIFFUSE:
- diffuse_ambient= color + (color << 16);
- break;
- case GL_SPECULAR:
- specular_emission = color | (specular_emission & 0xFFFF0000);
- break;
- case GL_SHININESS:
- break;
- case GL_EMISSION:
- specular_emission = (color << 16) | (specular_emission & 0xFFFF);
- break;
- }
-
- GFX_DIFFUSE_AMBIENT = diffuse_ambient;
- GFX_SPECULAR_EMISSION = specular_emission;
-}
-
-//---------------------------------------------------------------------------------
-void glInit_C(void) {
-//---------------------------------------------------------------------------------
- glGlob = glGetGlobals();
-
- glGlob->clearColor = 0;
-
- // init texture globals
- glGlob->activeTexture = 0;
- glGlob->nextBlock = (uint32*)0x06800000;
- glGlob->nextPBlock = 0;
- glGlob->nameCount = 1;
-
- while (GFX_STATUS & (1<<27)); // wait till gfx engine is not busy
-
- // Clear the FIFO
- GFX_STATUS |= (1<<29);
-
- // Clear overflows from list memory
- glResetMatrixStack();
-
- // prime the vertex/polygon buffers
- glFlush(0);
-
- // reset the control bits
- GFX_CONTROL = 0;
-
- // reset the rear-plane(a.k.a. clear color) to black, ID=0, and opaque
- glClearColor(0,0,0,31);
- glClearPolyID(0);
-
- // reset stored texture locations
- glResetTextures();
-
- // reset the depth to it's max
- glClearDepth(GL_MAX_DEPTH);
-
- GFX_TEX_FORMAT = 0;
- GFX_POLY_FORMAT = 0;
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
-}
-
-//---------------------------------------------------------------------------------
-void glResetTextures(void) {
-//---------------------------------------------------------------------------------
- glGlob->activeTexture = 0;
- glGlob->nextBlock = (uint32*)0x06800000;
- glGlob->nextPBlock = 0;
- glGlob->nameCount = 1;
-}
-
-//---------------------------------------------------------------------------------
-// glGenTextures creates integer names for your table
-// takes n as the number of textures to generate and
-// a pointer to the names array that it needs to fill.
-// Returns 1 if succesful and 0 if out of texture names
-//---------------------------------------------------------------------------------
-
-int glGenTextures(int n, int *names) {
-//---------------------------------------------------------------------------------
- int index = 0;
- for(index = 0; index < n; index++) {
- if(glGlob->nameCount >= MAX_TEXTURES)
- return 0;
- else
- names[index] = glGlob->nameCount++;
- }
- return 1;
-}
-
-//---------------------------------------------------------------------------------
-// glBindTexure sets the current named
-// texture to the active texture. Target
-// is ignored as all DS textures are 2D
-//---------------------------------------------------------------------------------
-void glBindTexture(int target, int name) {
-//---------------------------------------------------------------------------------
- if (name == 0)
- GFX_TEX_FORMAT = 0;
- else
- GFX_TEX_FORMAT = glGlob->textures[name];
-
-
- glGlob->activeTexture = name;
-}
-//---------------------------------------------------------------------------------
-// glColorTable establishes the location of the current palette.
-// Roughly follows glColorTableEXT. Association of palettes with
-// named textures is left to the application.
-//---------------------------------------------------------------------------------
-void glColorTable( uint8 format, uint32 addr ) {
-//---------------------------------------------------------------------------------
- GFX_PAL_FORMAT = addr>>(4-(format==GL_RGB4));
-}
-
-//---------------------------------------------------------------------------------
-//---------------------------------------------------------------------------------
-void glTexCoord2f32(int32 u, int32 v) {
-//---------------------------------------------------------------------------------
- int x, y;
-
- x = ((glGlob->textures[glGlob->activeTexture]) >> 20) & 7;
- y = ((glGlob->textures[glGlob->activeTexture]) >> 23) & 7;
-
- glTexCoord2t16(f32tot16 (mulf32(u,inttof32(8<<x))), f32tot16 (mulf32(v,inttof32(8<<y))));
-}
-
-//---------------------------------------------------------------------------------
-// glTexParameter although named the same
-// as its gl counterpart it is not compatible
-// Effort may be made in the future to make it so.
-//---------------------------------------------------------------------------------
-void glTexParameter( uint8 sizeX, uint8 sizeY,
- const uint32* addr,
- GL_TEXTURE_TYPE_ENUM mode,
- uint32 param) {
-//---------------------------------------------------------------------------------
- glGlob->textures[glGlob->activeTexture] = param | (sizeX << 20) | (sizeY << 23) | (((uint32)addr >> 3) & 0xFFFF) | (mode << 26);
-}
-//---------------------------------------------------------------------------------
-//glGetTexturePointer gets a pointer to vram which contains the texture
-//
-//---------------------------------------------------------------------------------
-void* glGetTexturePointer( int name) {
-//---------------------------------------------------------------------------------
- return (void*) ((glGlob->textures[name] & 0xFFFF) << 3);
-}
-
-//---------------------------------------------------------------------------------
-u32 glGetTexParameter(){
-//---------------------------------------------------------------------------------
- return glGlob->textures[glGlob->activeTexture];
-}
-
-
-//---------------------------------------------------------------------------------
-inline uint32 alignVal( uint32 val, uint32 to ) {
- return (val & (to-1))? (val & ~(to-1)) + to : val;
-}
-
-//---------------------------------------------------------------------------------
-int getNextPaletteSlot(u16 count, uint8 format) {
-//---------------------------------------------------------------------------------
- // ensure the result aligns on a palette block for this format
- uint32 result = alignVal(glGlob->nextPBlock, 1<<(4-(format==GL_RGB4)));
-
- // convert count to bytes and align to next (smallest format) palette block
- count = alignVal( count<<1, 1<<3 );
-
- // ensure that end is within palette video mem
- if( result+count > 0x10000 ) // VRAM_F - VRAM_E
- return -1;
-
- glGlob->nextPBlock = result+count;
- return (int)result;
-}
-
-//---------------------------------------------------------------------------------
-uint16* vramGetBank(uint16 *addr) {
-//---------------------------------------------------------------------------------
- if(addr >= VRAM_A && addr < VRAM_B)
- return VRAM_A;
- else if(addr >= VRAM_B && addr < VRAM_C)
- return VRAM_B;
- else if(addr >= VRAM_C && addr < VRAM_D)
- return VRAM_C;
- else if(addr >= VRAM_D && addr < VRAM_E)
- return VRAM_D;
- else if(addr >= VRAM_E && addr < VRAM_F)
- return VRAM_E;
- else if(addr >= VRAM_F && addr < VRAM_G)
- return VRAM_F;
- else if(addr >= VRAM_G && addr < VRAM_H)
- return VRAM_H;
- else if(addr >= VRAM_H && addr < VRAM_I)
- return VRAM_H;
- else return VRAM_I;
-}
-
-
-//---------------------------------------------------------------------------------
-int vramIsTextureBank(uint16 *addr) {
-//---------------------------------------------------------------------------------
- uint16* vram = vramGetBank(addr);
-
- if(vram == VRAM_A)
- {
- if((VRAM_A_CR & 3) == ((VRAM_A_TEXTURE) & 3))
- return 1;
- else return 0;
- }
- else if(vram == VRAM_B)
- {
- if((VRAM_B_CR & 3) == ((VRAM_B_TEXTURE) & 3))
- return 1;
- else return 0;
- }
- else if(vram == VRAM_C)
- {
- if((VRAM_C_CR & 3) == ((VRAM_C_TEXTURE) & 3))
- return 1;
- else return 0;
- }
- else if(vram == VRAM_D)
- {
- if((VRAM_D_CR & 3) == ((VRAM_D_TEXTURE) & 3))
- return 1;
- else return 0;
- }
- else
- return 0;
-}
-//---------------------------------------------------------------------------------
-uint32* getNextTextureSlot(int size) {
-//---------------------------------------------------------------------------------
- uint32* result = glGlob->nextBlock;
- glGlob->nextBlock += size >> 2;
-
- //uh-oh...out of texture memory in this bank...find next one assigned to textures
- while(!vramIsTextureBank((uint16*)glGlob->nextBlock - 1) && glGlob->nextBlock <= (uint32*)VRAM_E)
- {
- glGlob->nextBlock = (uint32*)vramGetBank((uint16*)result) + (0x20000 >> 2); //next bank
- result = glGlob->nextBlock;
- glGlob->nextBlock += size >> 2;
- }
-
- if(glGlob->nextBlock > (uint32*)VRAM_E) {
- result = 0;
- }
- return result;
-}
-
-//---------------------------------------------------------------------------------
-// Similer to glTextImage2D from gl it takes a pointer to data
-// Empty fields and target are unused but provided for code compatibility.
-// type is simply the texture type (GL_RGB, GL_RGB8 ect...)
-//---------------------------------------------------------------------------------
-int glTexImage2D(int target, int empty1, GL_TEXTURE_TYPE_ENUM type, int sizeX, int sizeY, int empty2, int param, const uint8* texture) {
-//---------------------------------------------------------------------------------
- uint32 size = 0;
- uint32* addr;
- uint32 vramTemp;
-
- size = 1 << (sizeX + sizeY + 6);
-
-
- switch (type) {
- case GL_RGB:
- case GL_RGBA:
- size = size << 1;
- break;
- case GL_RGB4:
- size = size >> 2;
- break;
- case GL_RGB16:
- size = size >> 1;
- break;
- default:
- break;
- }
-
- addr = getNextTextureSlot(size);
-
- if(!addr)
- return 0;
-
- // unlock texture memory
- vramTemp = vramSetMainBanks(VRAM_A_LCD,VRAM_B_LCD,VRAM_C_LCD,VRAM_D_LCD);
-
- if (type == GL_RGB) {
- // We do GL_RGB as GL_RGBA, but we set each alpha bit to 1 during the copy
- u16 * src = (u16*)texture;
- u16 * dest = (u16*)addr;
-
- glTexParameter(sizeX, sizeY, addr, GL_RGBA, param);
-
- while (size--) {
- *dest++ = *src | (1 << 15);
- src++;
- }
- } else {
- // For everything else, we do a straight copy
- glTexParameter(sizeX, sizeY, addr, type, param);
- swiCopy((uint32*)texture, addr , size / 4 | COPY_MODE_WORD);
- }
- vramRestoreMainBanks(vramTemp);
- return 1;
-}
-
-//---------------------------------------------------------------------------------
-void glTexLoadPal(const u16* pal, u16 count, u32 addr) {
-//---------------------------------------------------------------------------------
- vramSetBankE(VRAM_E_LCD);
- swiCopy( pal, &VRAM_E[addr>>1] , count / 2 | COPY_MODE_WORD);
- vramSetBankE(VRAM_E_TEX_PALETTE);
-}
-
-//---------------------------------------------------------------------------------
-int gluTexLoadPal(const u16* pal, u16 count, uint8 format) {
-//---------------------------------------------------------------------------------
- int addr = getNextPaletteSlot(count, format);
- if( addr>=0 )
- glTexLoadPal(pal, count, (u32) addr);
-
- return addr;
-}
-
-
-
-
-
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ Video API vaguely similar to OpenGL
+
+ Copyright (C) 2005
+ Michael Noland (joat)
+ Jason Rogers (dovoto)
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+
+---------------------------------------------------------------------------------*/
+
+#include <nds/jtypes.h>
+#include <nds/memory.h>
+#include <nds/bios.h>
+#include <nds/arm9/math.h>
+#include <nds/arm9/video.h>
+#include <nds/arm9/videoGL.h>
+#include <nds/arm9/trig_lut.h>
+
+// this is the actual data of the globals for videoGL
+// Please use the glGlob pointer to access this data since that makes it easier to move stuff in/out of the header.
+static gl_hidden_globals glGlobalData;
+
+// This returns the pointer to the globals for videoGL
+gl_hidden_globals* glGetGlobals() {
+ return &glGlobalData;
+}
+
+//---------------------------------------------------------------------------------
+void glRotatef32i(int angle, int32 x, int32 y, int32 z) {
+//---------------------------------------------------------------------------------
+ int32 axis[3];
+ int32 sine = SIN[angle & LUT_MASK];
+ int32 cosine = COS[angle & LUT_MASK];
+ int32 one_minus_cosine = inttof32(1) - cosine;
+
+ axis[0]=x;
+ axis[1]=y;
+ axis[2]=z;
+
+ normalizef32(axis); // should require passed in normalized?
+
+ MATRIX_MULT3x3 = cosine + mulf32(one_minus_cosine, mulf32(axis[0], axis[0]));
+ MATRIX_MULT3x3 = mulf32(one_minus_cosine, mulf32(axis[0], axis[1])) - mulf32(axis[2], sine);
+ MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[0]), axis[2]) + mulf32(axis[1], sine);
+
+ MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[0]), axis[1]) + mulf32(axis[2], sine);
+ MATRIX_MULT3x3 = cosine + mulf32(mulf32(one_minus_cosine, axis[1]), axis[1]);
+ MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[1]), axis[2]) - mulf32(axis[0], sine);
+
+ MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[0]), axis[2]) - mulf32(axis[1], sine);
+ MATRIX_MULT3x3 = mulf32(mulf32(one_minus_cosine, axis[1]), axis[2]) + mulf32(axis[0], sine);
+ MATRIX_MULT3x3 = cosine + mulf32(mulf32(one_minus_cosine, axis[2]), axis[2]);
+}
+
+
+
+
+//---------------------------------------------------------------------------------
+void glMaterialf(GL_MATERIALS_ENUM mode, rgb color) {
+//---------------------------------------------------------------------------------
+ static uint32 diffuse_ambient = 0;
+ static uint32 specular_emission = 0;
+
+ switch(mode) {
+ case GL_AMBIENT:
+ diffuse_ambient = (color << 16) | (diffuse_ambient & 0xFFFF);
+ break;
+ case GL_DIFFUSE:
+ diffuse_ambient = color | (diffuse_ambient & 0xFFFF0000);
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ diffuse_ambient= color + (color << 16);
+ break;
+ case GL_SPECULAR:
+ specular_emission = color | (specular_emission & 0xFFFF0000);
+ break;
+ case GL_SHININESS:
+ break;
+ case GL_EMISSION:
+ specular_emission = (color << 16) | (specular_emission & 0xFFFF);
+ break;
+ }
+
+ GFX_DIFFUSE_AMBIENT = diffuse_ambient;
+ GFX_SPECULAR_EMISSION = specular_emission;
+}
+
+//---------------------------------------------------------------------------------
+void glInit_C(void) {
+//---------------------------------------------------------------------------------
+ glGlob = glGetGlobals();
+
+ glGlob->clearColor = 0;
+
+ // init texture globals
+ glGlob->activeTexture = 0;
+ glGlob->nextBlock = (uint32*)0x06800000;
+ glGlob->nextPBlock = 0;
+ glGlob->nameCount = 1;
+
+ while (GFX_STATUS & (1<<27)); // wait till gfx engine is not busy
+
+ // Clear the FIFO
+ GFX_STATUS |= (1<<29);
+
+ // Clear overflows from list memory
+ glResetMatrixStack();
+
+ // prime the vertex/polygon buffers
+ glFlush(0);
+
+ // reset the control bits
+ GFX_CONTROL = 0;
+
+ // reset the rear-plane(a.k.a. clear color) to black, ID=0, and opaque
+ glClearColor(0,0,0,31);
+ glClearPolyID(0);
+
+ // reset stored texture locations
+ glResetTextures();
+
+ // reset the depth to it's max
+ glClearDepth(GL_MAX_DEPTH);
+
+ GFX_TEX_FORMAT = 0;
+ GFX_POLY_FORMAT = 0;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+}
+
+//---------------------------------------------------------------------------------
+void glResetTextures(void) {
+//---------------------------------------------------------------------------------
+ glGlob->activeTexture = 0;
+ glGlob->nextBlock = (uint32*)0x06800000;
+ glGlob->nextPBlock = 0;
+ glGlob->nameCount = 1;
+}
+
+//---------------------------------------------------------------------------------
+// glGenTextures creates integer names for your table
+// takes n as the number of textures to generate and
+// a pointer to the names array that it needs to fill.
+// Returns 1 if succesful and 0 if out of texture names
+//---------------------------------------------------------------------------------
+
+int glGenTextures(int n, int *names) {
+//---------------------------------------------------------------------------------
+ int index = 0;
+ for(index = 0; index < n; index++) {
+ if(glGlob->nameCount >= MAX_TEXTURES)
+ return 0;
+ else
+ names[index] = glGlob->nameCount++;
+ }
+ return 1;
+}
+
+//---------------------------------------------------------------------------------
+// glBindTexure sets the current named
+// texture to the active texture. Target
+// is ignored as all DS textures are 2D
+//---------------------------------------------------------------------------------
+void glBindTexture(int target, int name) {
+//---------------------------------------------------------------------------------
+ if (name == 0)
+ GFX_TEX_FORMAT = 0;
+ else
+ GFX_TEX_FORMAT = glGlob->textures[name];
+
+
+ glGlob->activeTexture = name;
+}
+//---------------------------------------------------------------------------------
+// glColorTable establishes the location of the current palette.
+// Roughly follows glColorTableEXT. Association of palettes with
+// named textures is left to the application.
+//---------------------------------------------------------------------------------
+void glColorTable( uint8 format, uint32 addr ) {
+//---------------------------------------------------------------------------------
+ GFX_PAL_FORMAT = addr>>(4-(format==GL_RGB4));
+}
+
+//---------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------
+void glTexCoord2f32(int32 u, int32 v) {
+//---------------------------------------------------------------------------------
+ int x, y;
+
+ x = ((glGlob->textures[glGlob->activeTexture]) >> 20) & 7;
+ y = ((glGlob->textures[glGlob->activeTexture]) >> 23) & 7;
+
+ glTexCoord2t16(f32tot16 (mulf32(u,inttof32(8<<x))), f32tot16 (mulf32(v,inttof32(8<<y))));
+}
+
+//---------------------------------------------------------------------------------
+// glTexParameter although named the same
+// as its gl counterpart it is not compatible
+// Effort may be made in the future to make it so.
+//---------------------------------------------------------------------------------
+void glTexParameter( uint8 sizeX, uint8 sizeY,
+ const uint32* addr,
+ GL_TEXTURE_TYPE_ENUM mode,
+ uint32 param) {
+//---------------------------------------------------------------------------------
+ glGlob->textures[glGlob->activeTexture] = param | (sizeX << 20) | (sizeY << 23) | (((uint32)addr >> 3) & 0xFFFF) | (mode << 26);
+}
+//---------------------------------------------------------------------------------
+//glGetTexturePointer gets a pointer to vram which contains the texture
+//
+//---------------------------------------------------------------------------------
+void* glGetTexturePointer( int name) {
+//---------------------------------------------------------------------------------
+ return (void*) ((glGlob->textures[name] & 0xFFFF) << 3);
+}
+
+//---------------------------------------------------------------------------------
+u32 glGetTexParameter(){
+//---------------------------------------------------------------------------------
+ return glGlob->textures[glGlob->activeTexture];
+}
+
+
+//---------------------------------------------------------------------------------
+inline uint32 alignVal( uint32 val, uint32 to ) {
+ return (val & (to-1))? (val & ~(to-1)) + to : val;
+}
+
+//---------------------------------------------------------------------------------
+int getNextPaletteSlot(u16 count, uint8 format) {
+//---------------------------------------------------------------------------------
+ // ensure the result aligns on a palette block for this format
+ uint32 result = alignVal(glGlob->nextPBlock, 1<<(4-(format==GL_RGB4)));
+
+ // convert count to bytes and align to next (smallest format) palette block
+ count = alignVal( count<<1, 1<<3 );
+
+ // ensure that end is within palette video mem
+ if( result+count > 0x10000 ) // VRAM_F - VRAM_E
+ return -1;
+
+ glGlob->nextPBlock = result+count;
+ return (int)result;
+}
+
+//---------------------------------------------------------------------------------
+uint16* vramGetBank(uint16 *addr) {
+//---------------------------------------------------------------------------------
+ if(addr >= VRAM_A && addr < VRAM_B)
+ return VRAM_A;
+ else if(addr >= VRAM_B && addr < VRAM_C)
+ return VRAM_B;
+ else if(addr >= VRAM_C && addr < VRAM_D)
+ return VRAM_C;
+ else if(addr >= VRAM_D && addr < VRAM_E)
+ return VRAM_D;
+ else if(addr >= VRAM_E && addr < VRAM_F)
+ return VRAM_E;
+ else if(addr >= VRAM_F && addr < VRAM_G)
+ return VRAM_F;
+ else if(addr >= VRAM_G && addr < VRAM_H)
+ return VRAM_H;
+ else if(addr >= VRAM_H && addr < VRAM_I)
+ return VRAM_H;
+ else return VRAM_I;
+}
+
+
+//---------------------------------------------------------------------------------
+int vramIsTextureBank(uint16 *addr) {
+//---------------------------------------------------------------------------------
+ uint16* vram = vramGetBank(addr);
+
+ if(vram == VRAM_A)
+ {
+ if((VRAM_A_CR & 3) == ((VRAM_A_TEXTURE) & 3))
+ return 1;
+ else return 0;
+ }
+ else if(vram == VRAM_B)
+ {
+ if((VRAM_B_CR & 3) == ((VRAM_B_TEXTURE) & 3))
+ return 1;
+ else return 0;
+ }
+ else if(vram == VRAM_C)
+ {
+ if((VRAM_C_CR & 3) == ((VRAM_C_TEXTURE) & 3))
+ return 1;
+ else return 0;
+ }
+ else if(vram == VRAM_D)
+ {
+ if((VRAM_D_CR & 3) == ((VRAM_D_TEXTURE) & 3))
+ return 1;
+ else return 0;
+ }
+ else
+ return 0;
+}
+//---------------------------------------------------------------------------------
+uint32* getNextTextureSlot(int size) {
+//---------------------------------------------------------------------------------
+ uint32* result = glGlob->nextBlock;
+ glGlob->nextBlock += size >> 2;
+
+ //uh-oh...out of texture memory in this bank...find next one assigned to textures
+ while(!vramIsTextureBank((uint16*)glGlob->nextBlock - 1) && glGlob->nextBlock <= (uint32*)VRAM_E)
+ {
+ glGlob->nextBlock = (uint32*)vramGetBank((uint16*)result) + (0x20000 >> 2); //next bank
+ result = glGlob->nextBlock;
+ glGlob->nextBlock += size >> 2;
+ }
+
+ if(glGlob->nextBlock > (uint32*)VRAM_E) {
+ result = 0;
+ }
+ return result;
+}
+
+//---------------------------------------------------------------------------------
+// Similer to glTextImage2D from gl it takes a pointer to data
+// Empty fields and target are unused but provided for code compatibility.
+// type is simply the texture type (GL_RGB, GL_RGB8 ect...)
+//---------------------------------------------------------------------------------
+int glTexImage2D(int target, int empty1, GL_TEXTURE_TYPE_ENUM type, int sizeX, int sizeY, int empty2, int param, const uint8* texture) {
+//---------------------------------------------------------------------------------
+ uint32 size = 0;
+ uint32* addr;
+ uint32 vramTemp;
+
+ size = 1 << (sizeX + sizeY + 6);
+
+
+ switch (type) {
+ case GL_RGB:
+ case GL_RGBA:
+ size = size << 1;
+ break;
+ case GL_RGB4:
+ size = size >> 2;
+ break;
+ case GL_RGB16:
+ size = size >> 1;
+ break;
+ default:
+ break;
+ }
+
+ addr = getNextTextureSlot(size);
+
+ if(!addr)
+ return 0;
+
+ // unlock texture memory
+ vramTemp = vramSetMainBanks(VRAM_A_LCD,VRAM_B_LCD,VRAM_C_LCD,VRAM_D_LCD);
+
+ if (type == GL_RGB) {
+ // We do GL_RGB as GL_RGBA, but we set each alpha bit to 1 during the copy
+ u16 * src = (u16*)texture;
+ u16 * dest = (u16*)addr;
+
+ glTexParameter(sizeX, sizeY, addr, GL_RGBA, param);
+
+ while (size--) {
+ *dest++ = *src | (1 << 15);
+ src++;
+ }
+ } else {
+ // For everything else, we do a straight copy
+ glTexParameter(sizeX, sizeY, addr, type, param);
+ swiCopy((uint32*)texture, addr , size / 4 | COPY_MODE_WORD);
+ }
+ vramRestoreMainBanks(vramTemp);
+ return 1;
+}
+
+//---------------------------------------------------------------------------------
+void glTexLoadPal(const u16* pal, u16 count, u32 addr) {
+//---------------------------------------------------------------------------------
+ vramSetBankE(VRAM_E_LCD);
+ swiCopy( pal, &VRAM_E[addr>>1] , count / 2 | COPY_MODE_WORD);
+ vramSetBankE(VRAM_E_TEX_PALETTE);
+}
+
+//---------------------------------------------------------------------------------
+int gluTexLoadPal(const u16* pal, u16 count, uint8 format) {
+//---------------------------------------------------------------------------------
+ int addr = getNextPaletteSlot(count, format);
+ if( addr>=0 )
+ glTexLoadPal(pal, count, (u32) addr);
+
+ return addr;
+}
+
+
+
+
+
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/common/card.c b/c/src/lib/libbsp/arm/nds/libnds/source/common/card.c
index 8aad2d93aa..6990380471 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/common/card.c
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/common/card.c
@@ -1,394 +1,394 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- Copyright (C) 2005
- Michael Noland (joat)
- Jason Rogers (dovoto)
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
-
----------------------------------------------------------------------------------*/
-#include "nds/card.h"
-#include "nds/dma.h"
-#include "nds/memory.h"
-
-
-//---------------------------------------------------------------------------------
-void cardWriteCommand(const uint8 * command) {
-//---------------------------------------------------------------------------------
- int index;
-
- CARD_CR1H = CARD_CR1_ENABLE | CARD_CR1_IRQ;
-
- for (index = 0; index < 8; index++) {
- CARD_COMMAND[7-index] = command[index];
- }
-}
-
-
-//---------------------------------------------------------------------------------
-void cardPolledTransfer(uint32 flags, uint32 * destination, uint32 length, const uint8 * command) {
-//---------------------------------------------------------------------------------
- u32 data;;
- cardWriteCommand(command);
- CARD_CR2 = flags;
- uint32 * target = destination + length;
- do {
- // Read data if available
- if (CARD_CR2 & CARD_DATA_READY) {
- data=CARD_DATA_RD;
- if (destination < target)
- *destination = data;
- destination++;
- }
- } while (CARD_CR2 & CARD_BUSY);
-}
-
-
-//---------------------------------------------------------------------------------
-void cardStartTransfer(const uint8 * command, uint32 * destination, int channel, uint32 flags) {
-//---------------------------------------------------------------------------------
- cardWriteCommand(command);
-
- // Set up a DMA channel to transfer a word every time the card makes one
- DMA_SRC(channel) = (uint32)&CARD_DATA_RD;
- DMA_DEST(channel) = (uint32)destination;
- DMA_CR(channel) = DMA_ENABLE | DMA_START_CARD | DMA_32_BIT | DMA_REPEAT | DMA_SRC_FIX | 0x0001;;
-
- CARD_CR2 = flags;
-}
-
-
-//---------------------------------------------------------------------------------
-uint32 cardWriteAndRead(const uint8 * command, uint32 flags) {
-//---------------------------------------------------------------------------------
- cardWriteCommand(command);
- CARD_CR2 = flags | CARD_ACTIVATE | CARD_nRESET | 0x07000000;
- while (!(CARD_CR2 & CARD_DATA_READY)) ;
- return CARD_DATA_RD;
-}
-
-
-//---------------------------------------------------------------------------------
-void cardRead00(uint32 address, uint32 * destination, uint32 length, uint32 flags) {
-//---------------------------------------------------------------------------------f
- uint8 command[8];
- command[7] = 0;
- command[6] = (address >> 24) & 0xff;
- command[5] = (address >> 16) & 0xff;
- command[4] = (address >> 8) & 0xff;
- command[3] = address & 0xff;
- command[2] = 0;
- command[1] = 0;
- command[0] = 0;
- cardPolledTransfer(flags, destination, length, command);
-}
-
-
-//---------------------------------------------------------------------------------
-void cardReadHeader(uint8 * header) {
-//---------------------------------------------------------------------------------
- cardRead00(0, (uint32 *)header, 512, 0xA93F1FFF);
-}
-
-
-//---------------------------------------------------------------------------------
-int cardReadID(uint32 flags) {
-//---------------------------------------------------------------------------------
- uint8 command[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90};
- return cardWriteAndRead(command, flags);
-}
-
-
-//---------------------------------------------------------------------------------
-static inline void EepromWaitBusy() {
-//---------------------------------------------------------------------------------
- while (CARD_CR1 & /*BUSY*/0x80);
-}
-
-//---------------------------------------------------------------------------------
-uint8 cardEepromReadID(uint8 i) {
-//---------------------------------------------------------------------------------
- return cardEepromCommand(/*READID*/0xAB, i&1);
-}
-
-//---------------------------------------------------------------------------------
-uint8 cardEepromCommand(uint8 command, uint32 address) {
-//---------------------------------------------------------------------------------
- uint8 retval;
- int k;
- CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
-
- CARD_CR1 = 0xFFFF;
- CARD_EEPDATA = command;
-
- EepromWaitBusy();
-
- CARD_EEPDATA = (address >> 16) & 0xFF;
- EepromWaitBusy();
-
- CARD_EEPDATA = (address >> 8) & 0xFF;
- EepromWaitBusy();
-
- CARD_EEPDATA = (address) & 0xFF;
- EepromWaitBusy();
-
- for(k=0;k<256;k++)
- {
- retval = CARD_EEPDATA;
- if(retval!=0xFF)
- break;
- EepromWaitBusy();
- }
-
- CARD_CR1 = /*MODE*/0x40;
- return retval;
-}
-
-//---------------------------------------------------------------------------------
-int cardEepromGetType(void)
-//---------------------------------------------------------------------------------
-{
- uint8 c00;
- uint8 c05;
- uint8 c9f;
- uint8 c03;
-
-#ifdef ARM9
- sysSetBusOwners(BUS_OWNER_ARM9, BUS_OWNER_ARM9);
-#endif
-
- c03=cardEepromCommand(0x03,0);
- c05=cardEepromCommand(0x05,0);
- c9f=cardEepromCommand(0x9f,0);
- c00=cardEepromCommand(0x00,0);
-
- if((c00==0x00) && (c9f==0x00)) return 0; // PassMe?
- if((c00==0xff) && (c05==0xff) && (c9f==0xff))return -1;
-
- if((c00==0xff) && (c05 & 0xFD) == 0xF0 && (c9f==0xff))return 1;
- if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0xff))return 2;
- if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x00))return 3;
- if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x12))return 3; // NEW TYPE 3
- if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x13))return 3; // NEW TYPE 3+ 4Mbit
- if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x14))return 3; // NEW TYPE 3++ 8Mbit MK4-FLASH Memory
-
- return 0;
-}
-
-//---------------------------------------------------------------------------------
-uint32 cardEepromGetSize() {
-//---------------------------------------------------------------------------------
-
- int type = cardEepromGetType();
-
- if(type == -1)
- return 0;
- if(type == 0)
- return 8192;
- if(type == 1)
- return 512;
- if(type == 2) {
- static const uint32 offset0 = (8*1024-1); // 8KB
- static const uint32 offset1 = (2*8*1024-1); // 16KB
- u8 buf1; // +0k data read -> write
- u8 buf2; // +8k data read -> read
- u8 buf3; // +0k ~data write
- u8 buf4; // +8k data new comp buf2
- cardReadEeprom(offset0,&buf1,1,type);
- cardReadEeprom(offset1,&buf2,1,type);
- buf3=~buf1;
- cardWriteEeprom(offset0,&buf3,1,type);
- cardReadEeprom (offset1,&buf4,1,type);
- cardWriteEeprom(offset0,&buf1,1,type);
- if(buf4!=buf2) // +8k
- return 8*1024; // 8KB(64kbit)
- else
- return 64*1024; // 64KB(512kbit)
- }
- if(type == 3) {
- uint8 c9f;
- c9f=cardEepromCommand(0x9f,0);
-
- if(c9f==0x14)
- return 1024*1024; // NEW TYPE 3++ 8Mbit(1024KByte)
-
- if(c9f==0x13)
- return 512*1024; // NEW TYPE 3+ 4Mbit(512KByte)
-
- return 256*1024; // TYPE 3 2Mbit(256KByte)
- }
-
- return 0;
-}
-
-
-//---------------------------------------------------------------------------------
-void cardReadEeprom(uint32 address, uint8 *data, uint32 length, uint32 addrtype) {
-//---------------------------------------------------------------------------------
-
- CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
- CARD_EEPDATA = 0x03 | ((addrtype == 1) ? address>>8<<3 : 0);
- EepromWaitBusy();
-
- if (addrtype == 3) {
- CARD_EEPDATA = (address >> 16) & 0xFF;
- EepromWaitBusy();
- }
-
- if (addrtype >= 2) {
- CARD_EEPDATA = (address >> 8) & 0xFF;
- EepromWaitBusy();
- }
-
-
- CARD_EEPDATA = (address) & 0xFF;
- EepromWaitBusy();
-
- while (length > 0) {
- CARD_EEPDATA = 0;
- EepromWaitBusy();
- *data++ = CARD_EEPDATA;
- length--;
- }
-
- EepromWaitBusy();
- CARD_CR1 = /*MODE*/0x40;
-}
-
-
-//---------------------------------------------------------------------------------
-void cardWriteEeprom(uint32 address, uint8 *data, uint32 length, uint32 addrtype) {
-//---------------------------------------------------------------------------------
-
- uint32 address_end = address + length;
- int i;
- int maxblocks = 32;
- if(addrtype == 1) maxblocks = 16;
- if(addrtype == 2) maxblocks = 32;
- if(addrtype == 3) maxblocks = 256;
-
- while (address < address_end) {
- // set WEL (Write Enable Latch)
- CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
- CARD_EEPDATA = 0x06; EepromWaitBusy();
- CARD_CR1 = /*MODE*/0x40;
-
- // program maximum of 32 bytes
- CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
-
- if(addrtype == 1) {
- // WRITE COMMAND 0x02 + A8 << 3
- CARD_EEPDATA = 0x02 | (address & BIT(8)) >> (8-3) ;
- EepromWaitBusy();
- CARD_EEPDATA = address & 0xFF;
- EepromWaitBusy();
- }
- else if(addrtype == 2) {
- CARD_EEPDATA = 0x02;
- EepromWaitBusy();
- CARD_EEPDATA = address >> 8;
- EepromWaitBusy();
- CARD_EEPDATA = address & 0xFF;
- EepromWaitBusy();
- }
- else if(addrtype == 3) {
- CARD_EEPDATA = 0x02;
- EepromWaitBusy();
- CARD_EEPDATA = (address >> 16) & 0xFF;
- EepromWaitBusy();
- CARD_EEPDATA = (address >> 8) & 0xFF;
- EepromWaitBusy();
- CARD_EEPDATA = address & 0xFF;
- EepromWaitBusy();
- }
-
- for (i=0; address<address_end && i<maxblocks; i++, address++) {
- CARD_EEPDATA = *data++;
- EepromWaitBusy();
- }
- CARD_CR1 = /*MODE*/0x40;
-
- // wait programming to finish
- CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
- CARD_EEPDATA = 0x05; EepromWaitBusy();
- do { CARD_EEPDATA = 0; EepromWaitBusy(); } while (CARD_EEPDATA & 0x01); // WIP (Write In Progress) ?
- EepromWaitBusy();
- CARD_CR1 = /*MODE*/0x40;
- }
-}
-
-
-// Chip Erase : clear FLASH MEMORY (TYPE 3 ONLY)
-//---------------------------------------------------------------------------------
-void cardEepromChipErase(void) {
-//---------------------------------------------------------------------------------
- int sz;
- sz=cardEepromGetSize();
- cardEepromSectorErase(0x00000);
- cardEepromSectorErase(0x10000);
- cardEepromSectorErase(0x20000);
- cardEepromSectorErase(0x30000);
- if(sz==512*1024)
- {
- cardEepromSectorErase(0x40000);
- cardEepromSectorErase(0x50000);
- cardEepromSectorErase(0x60000);
- cardEepromSectorErase(0x70000);
- }
-}
-
-// COMMAND Sec.erase 0xD8
-void cardEepromSectorErase(uint32 address)
-{
- // set WEL (Write Enable Latch)
- CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
- CARD_EEPDATA = 0x06;
- EepromWaitBusy();
-
- CARD_CR1 = /*MODE*/0x40;
-
- // SectorErase 0xD8
- CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
- CARD_EEPDATA = 0xD8;
- EepromWaitBusy();
- CARD_EEPDATA = (address >> 16) & 0xFF;
- EepromWaitBusy();
- CARD_EEPDATA = (address >> 8) & 0xFF;
- EepromWaitBusy();
- CARD_EEPDATA = address & 0xFF;
- EepromWaitBusy();
-
- CARD_CR1 = /*MODE*/0x40;
-
- // wait erase to finish
- CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
- CARD_EEPDATA = 0x05;
- EepromWaitBusy();
-
- do
- {
- CARD_EEPDATA = 0;
- EepromWaitBusy();
- } while (CARD_EEPDATA & 0x01); // WIP (Write In Progress) ?
- CARD_CR1 = /*MODE*/0x40;
-}
-
-
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ Copyright (C) 2005
+ Michael Noland (joat)
+ Jason Rogers (dovoto)
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+
+---------------------------------------------------------------------------------*/
+#include "nds/card.h"
+#include "nds/dma.h"
+#include "nds/memory.h"
+
+
+//---------------------------------------------------------------------------------
+void cardWriteCommand(const uint8 * command) {
+//---------------------------------------------------------------------------------
+ int index;
+
+ CARD_CR1H = CARD_CR1_ENABLE | CARD_CR1_IRQ;
+
+ for (index = 0; index < 8; index++) {
+ CARD_COMMAND[7-index] = command[index];
+ }
+}
+
+
+//---------------------------------------------------------------------------------
+void cardPolledTransfer(uint32 flags, uint32 * destination, uint32 length, const uint8 * command) {
+//---------------------------------------------------------------------------------
+ u32 data;;
+ cardWriteCommand(command);
+ CARD_CR2 = flags;
+ uint32 * target = destination + length;
+ do {
+ // Read data if available
+ if (CARD_CR2 & CARD_DATA_READY) {
+ data=CARD_DATA_RD;
+ if (destination < target)
+ *destination = data;
+ destination++;
+ }
+ } while (CARD_CR2 & CARD_BUSY);
+}
+
+
+//---------------------------------------------------------------------------------
+void cardStartTransfer(const uint8 * command, uint32 * destination, int channel, uint32 flags) {
+//---------------------------------------------------------------------------------
+ cardWriteCommand(command);
+
+ // Set up a DMA channel to transfer a word every time the card makes one
+ DMA_SRC(channel) = (uint32)&CARD_DATA_RD;
+ DMA_DEST(channel) = (uint32)destination;
+ DMA_CR(channel) = DMA_ENABLE | DMA_START_CARD | DMA_32_BIT | DMA_REPEAT | DMA_SRC_FIX | 0x0001;;
+
+ CARD_CR2 = flags;
+}
+
+
+//---------------------------------------------------------------------------------
+uint32 cardWriteAndRead(const uint8 * command, uint32 flags) {
+//---------------------------------------------------------------------------------
+ cardWriteCommand(command);
+ CARD_CR2 = flags | CARD_ACTIVATE | CARD_nRESET | 0x07000000;
+ while (!(CARD_CR2 & CARD_DATA_READY)) ;
+ return CARD_DATA_RD;
+}
+
+
+//---------------------------------------------------------------------------------
+void cardRead00(uint32 address, uint32 * destination, uint32 length, uint32 flags) {
+//---------------------------------------------------------------------------------f
+ uint8 command[8];
+ command[7] = 0;
+ command[6] = (address >> 24) & 0xff;
+ command[5] = (address >> 16) & 0xff;
+ command[4] = (address >> 8) & 0xff;
+ command[3] = address & 0xff;
+ command[2] = 0;
+ command[1] = 0;
+ command[0] = 0;
+ cardPolledTransfer(flags, destination, length, command);
+}
+
+
+//---------------------------------------------------------------------------------
+void cardReadHeader(uint8 * header) {
+//---------------------------------------------------------------------------------
+ cardRead00(0, (uint32 *)header, 512, 0xA93F1FFF);
+}
+
+
+//---------------------------------------------------------------------------------
+int cardReadID(uint32 flags) {
+//---------------------------------------------------------------------------------
+ uint8 command[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90};
+ return cardWriteAndRead(command, flags);
+}
+
+
+//---------------------------------------------------------------------------------
+static inline void EepromWaitBusy() {
+//---------------------------------------------------------------------------------
+ while (CARD_CR1 & /*BUSY*/0x80);
+}
+
+//---------------------------------------------------------------------------------
+uint8 cardEepromReadID(uint8 i) {
+//---------------------------------------------------------------------------------
+ return cardEepromCommand(/*READID*/0xAB, i&1);
+}
+
+//---------------------------------------------------------------------------------
+uint8 cardEepromCommand(uint8 command, uint32 address) {
+//---------------------------------------------------------------------------------
+ uint8 retval;
+ int k;
+ CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
+
+ CARD_CR1 = 0xFFFF;
+ CARD_EEPDATA = command;
+
+ EepromWaitBusy();
+
+ CARD_EEPDATA = (address >> 16) & 0xFF;
+ EepromWaitBusy();
+
+ CARD_EEPDATA = (address >> 8) & 0xFF;
+ EepromWaitBusy();
+
+ CARD_EEPDATA = (address) & 0xFF;
+ EepromWaitBusy();
+
+ for(k=0;k<256;k++)
+ {
+ retval = CARD_EEPDATA;
+ if(retval!=0xFF)
+ break;
+ EepromWaitBusy();
+ }
+
+ CARD_CR1 = /*MODE*/0x40;
+ return retval;
+}
+
+//---------------------------------------------------------------------------------
+int cardEepromGetType(void)
+//---------------------------------------------------------------------------------
+{
+ uint8 c00;
+ uint8 c05;
+ uint8 c9f;
+ uint8 c03;
+
+#ifdef ARM9
+ sysSetBusOwners(BUS_OWNER_ARM9, BUS_OWNER_ARM9);
+#endif
+
+ c03=cardEepromCommand(0x03,0);
+ c05=cardEepromCommand(0x05,0);
+ c9f=cardEepromCommand(0x9f,0);
+ c00=cardEepromCommand(0x00,0);
+
+ if((c00==0x00) && (c9f==0x00)) return 0; // PassMe?
+ if((c00==0xff) && (c05==0xff) && (c9f==0xff))return -1;
+
+ if((c00==0xff) && (c05 & 0xFD) == 0xF0 && (c9f==0xff))return 1;
+ if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0xff))return 2;
+ if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x00))return 3;
+ if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x12))return 3; // NEW TYPE 3
+ if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x13))return 3; // NEW TYPE 3+ 4Mbit
+ if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x14))return 3; // NEW TYPE 3++ 8Mbit MK4-FLASH Memory
+
+ return 0;
+}
+
+//---------------------------------------------------------------------------------
+uint32 cardEepromGetSize() {
+//---------------------------------------------------------------------------------
+
+ int type = cardEepromGetType();
+
+ if(type == -1)
+ return 0;
+ if(type == 0)
+ return 8192;
+ if(type == 1)
+ return 512;
+ if(type == 2) {
+ static const uint32 offset0 = (8*1024-1); // 8KB
+ static const uint32 offset1 = (2*8*1024-1); // 16KB
+ u8 buf1; // +0k data read -> write
+ u8 buf2; // +8k data read -> read
+ u8 buf3; // +0k ~data write
+ u8 buf4; // +8k data new comp buf2
+ cardReadEeprom(offset0,&buf1,1,type);
+ cardReadEeprom(offset1,&buf2,1,type);
+ buf3=~buf1;
+ cardWriteEeprom(offset0,&buf3,1,type);
+ cardReadEeprom (offset1,&buf4,1,type);
+ cardWriteEeprom(offset0,&buf1,1,type);
+ if(buf4!=buf2) // +8k
+ return 8*1024; // 8KB(64kbit)
+ else
+ return 64*1024; // 64KB(512kbit)
+ }
+ if(type == 3) {
+ uint8 c9f;
+ c9f=cardEepromCommand(0x9f,0);
+
+ if(c9f==0x14)
+ return 1024*1024; // NEW TYPE 3++ 8Mbit(1024KByte)
+
+ if(c9f==0x13)
+ return 512*1024; // NEW TYPE 3+ 4Mbit(512KByte)
+
+ return 256*1024; // TYPE 3 2Mbit(256KByte)
+ }
+
+ return 0;
+}
+
+
+//---------------------------------------------------------------------------------
+void cardReadEeprom(uint32 address, uint8 *data, uint32 length, uint32 addrtype) {
+//---------------------------------------------------------------------------------
+
+ CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
+ CARD_EEPDATA = 0x03 | ((addrtype == 1) ? address>>8<<3 : 0);
+ EepromWaitBusy();
+
+ if (addrtype == 3) {
+ CARD_EEPDATA = (address >> 16) & 0xFF;
+ EepromWaitBusy();
+ }
+
+ if (addrtype >= 2) {
+ CARD_EEPDATA = (address >> 8) & 0xFF;
+ EepromWaitBusy();
+ }
+
+
+ CARD_EEPDATA = (address) & 0xFF;
+ EepromWaitBusy();
+
+ while (length > 0) {
+ CARD_EEPDATA = 0;
+ EepromWaitBusy();
+ *data++ = CARD_EEPDATA;
+ length--;
+ }
+
+ EepromWaitBusy();
+ CARD_CR1 = /*MODE*/0x40;
+}
+
+
+//---------------------------------------------------------------------------------
+void cardWriteEeprom(uint32 address, uint8 *data, uint32 length, uint32 addrtype) {
+//---------------------------------------------------------------------------------
+
+ uint32 address_end = address + length;
+ int i;
+ int maxblocks = 32;
+ if(addrtype == 1) maxblocks = 16;
+ if(addrtype == 2) maxblocks = 32;
+ if(addrtype == 3) maxblocks = 256;
+
+ while (address < address_end) {
+ // set WEL (Write Enable Latch)
+ CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
+ CARD_EEPDATA = 0x06; EepromWaitBusy();
+ CARD_CR1 = /*MODE*/0x40;
+
+ // program maximum of 32 bytes
+ CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
+
+ if(addrtype == 1) {
+ // WRITE COMMAND 0x02 + A8 << 3
+ CARD_EEPDATA = 0x02 | (address & BIT(8)) >> (8-3) ;
+ EepromWaitBusy();
+ CARD_EEPDATA = address & 0xFF;
+ EepromWaitBusy();
+ }
+ else if(addrtype == 2) {
+ CARD_EEPDATA = 0x02;
+ EepromWaitBusy();
+ CARD_EEPDATA = address >> 8;
+ EepromWaitBusy();
+ CARD_EEPDATA = address & 0xFF;
+ EepromWaitBusy();
+ }
+ else if(addrtype == 3) {
+ CARD_EEPDATA = 0x02;
+ EepromWaitBusy();
+ CARD_EEPDATA = (address >> 16) & 0xFF;
+ EepromWaitBusy();
+ CARD_EEPDATA = (address >> 8) & 0xFF;
+ EepromWaitBusy();
+ CARD_EEPDATA = address & 0xFF;
+ EepromWaitBusy();
+ }
+
+ for (i=0; address<address_end && i<maxblocks; i++, address++) {
+ CARD_EEPDATA = *data++;
+ EepromWaitBusy();
+ }
+ CARD_CR1 = /*MODE*/0x40;
+
+ // wait programming to finish
+ CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
+ CARD_EEPDATA = 0x05; EepromWaitBusy();
+ do { CARD_EEPDATA = 0; EepromWaitBusy(); } while (CARD_EEPDATA & 0x01); // WIP (Write In Progress) ?
+ EepromWaitBusy();
+ CARD_CR1 = /*MODE*/0x40;
+ }
+}
+
+
+// Chip Erase : clear FLASH MEMORY (TYPE 3 ONLY)
+//---------------------------------------------------------------------------------
+void cardEepromChipErase(void) {
+//---------------------------------------------------------------------------------
+ int sz;
+ sz=cardEepromGetSize();
+ cardEepromSectorErase(0x00000);
+ cardEepromSectorErase(0x10000);
+ cardEepromSectorErase(0x20000);
+ cardEepromSectorErase(0x30000);
+ if(sz==512*1024)
+ {
+ cardEepromSectorErase(0x40000);
+ cardEepromSectorErase(0x50000);
+ cardEepromSectorErase(0x60000);
+ cardEepromSectorErase(0x70000);
+ }
+}
+
+// COMMAND Sec.erase 0xD8
+void cardEepromSectorErase(uint32 address)
+{
+ // set WEL (Write Enable Latch)
+ CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
+ CARD_EEPDATA = 0x06;
+ EepromWaitBusy();
+
+ CARD_CR1 = /*MODE*/0x40;
+
+ // SectorErase 0xD8
+ CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
+ CARD_EEPDATA = 0xD8;
+ EepromWaitBusy();
+ CARD_EEPDATA = (address >> 16) & 0xFF;
+ EepromWaitBusy();
+ CARD_EEPDATA = (address >> 8) & 0xFF;
+ EepromWaitBusy();
+ CARD_EEPDATA = address & 0xFF;
+ EepromWaitBusy();
+
+ CARD_CR1 = /*MODE*/0x40;
+
+ // wait erase to finish
+ CARD_CR1 = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
+ CARD_EEPDATA = 0x05;
+ EepromWaitBusy();
+
+ do
+ {
+ CARD_EEPDATA = 0;
+ EepromWaitBusy();
+ } while (CARD_EEPDATA & 0x01); // WIP (Write In Progress) ?
+ CARD_CR1 = /*MODE*/0x40;
+}
+
+
diff --git a/c/src/lib/libbsp/arm/nds/libnds/source/common/interruptDispatcher.S b/c/src/lib/libbsp/arm/nds/libnds/source/common/interruptDispatcher.S
index 4ef656f132..c971bb3b20 100644
--- a/c/src/lib/libbsp/arm/nds/libnds/source/common/interruptDispatcher.S
+++ b/c/src/lib/libbsp/arm/nds/libnds/source/common/interruptDispatcher.S
@@ -1,27 +1,45 @@
-/*---------------------------------------------------------------------------------
- $Id$
-
- Copyright (C) 2005
- Dave Murphy (WinterMute)
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
-
+/*---------------------------------------------------------------------------------
+ $Id$
+
+ Copyright (C) 2005
+ Dave Murphy (WinterMute)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any
+ damages arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any
+ purpose, including commercial applications, and to alter it and
+ redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you
+ must not claim that you wrote the original software. If you use
+ this software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and
+ must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
$Log$
+ Revision 1.1 2008/04/17 23:09:41 joel
+ 2008-04-17 Joel Sherrill <joel.sherrill@OARcorp.com>
+
+ * Makefile.am: Move .s files to .S
+ * dswifi/common/source/spinlock.S, libfat/source/disc_io/io_dldi.S,
+ libfat/source/disc_io/io_scsd_s.S, libnds/source/arm9/COS.S,
+ libnds/source/arm9/SIN.S, libnds/source/arm9/TAN.S,
+ libnds/source/arm9/dcache.S, libnds/source/arm9/default_font.S,
+ libnds/source/arm9/icache.S, libnds/source/common/biosCalls.S,
+ libnds/source/common/interruptDispatcher.S: New files.
+ * dswifi/common/source/spinlock.s, libfat/source/disc_io/io_dldi.s,
+ libfat/source/disc_io/io_scsd_s.s, libnds/source/arm9/COS.s,
+ libnds/source/arm9/SIN.s, libnds/source/arm9/TAN.s,
+ libnds/source/arm9/dcache.s, libnds/source/arm9/default_font.s,
+ libnds/source/arm9/exceptionHandler.s, libnds/source/arm9/icache.s,
+ libnds/source/common/biosCalls.s,
+ libnds/source/common/interruptDispatcher.s: Removed.
+
Revision 1.1 2008/04/16 18:37:33 joel
2008-04-16 Matthieu Bucchianeri <mbucchia@gmail.com>
@@ -159,132 +177,132 @@
touchscreen/reco.h, touchscreen/touchscreen.c,
touchscreen/touchscreen.h, wifi/compat.c, wifi/compat.h, wifi/wifi.c:
New files.
-
- Revision 1.10 2007/08/11 06:00:23 wntrmute
- make nesting really work
-
- Revision 1.9 2007/01/10 15:48:27 wntrmute
- remove unused code
-
- Revision 1.8 2006/12/16 09:10:02 wntrmute
- acknowledge interrupt before calling handler
-
- Revision 1.7 2006/04/26 05:11:31 wntrmute
- rebase dtcm, take __irq_flags and __irq_vector from linker script
- move arm7 irq vector & irq flags to actual locations
-
- Revision 1.6 2006/04/23 18:19:15 wntrmute
- reworked interrupt code to allow dtcm moving
-
- Revision 1.5 2005/12/12 13:01:55 wntrmute
- disable interrupts on return from user handler
-
- Revision 1.4 2005/10/21 22:43:42 wntrmute
- restore REG_IME on exit from null handler
-
- Revision 1.3 2005/09/27 18:21:53 wntrmute
- safer nested interrupt support
-
- Revision 1.2 2005/09/04 16:37:01 wntrmute
- check for NULL handler
-
- Revision 1.1 2005/09/03 17:09:35 wntrmute
- added interworking aware interrupt dispatcher
-
-
----------------------------------------------------------------------------------*/
-
-#ifdef ARM7
- .text
-#endif
-
-#ifdef ARM9
- .section .itcm,"ax",%progbits
-#endif
-
- .extern irqTable
- .code 32
-
- .global IntrMain
-@---------------------------------------------------------------------------------
-IntrMain:
-@---------------------------------------------------------------------------------
- mov r3, #0x4000000 @ REG_BASE
-
- ldr r1, [r3, #0x208] @ r1 = IME
- str r3, [r3, #0x208] @ disable IME
- mrs r0, spsr
- stmfd sp!, {r0-r1,r3,lr} @ {spsr, IME, REG_BASE, lr_irq}
-
- ldr r1, [r3,#0x210] @ REG_IE
- ldr r2, [r3,#0x214] @ REG_IF
- and r1,r1,r2
-
- ldr r0,=__irq_flags @ defined by linker script
-
- ldr r2,[r0]
- orr r2,r2,r1
- str r2,[r0]
-
- ldr r2,=irqTable
-@---------------------------------------------------------------------------------
-findIRQ:
-@---------------------------------------------------------------------------------
- ldr r0, [r2, #4]
- cmp r0,#0
- beq no_handler
- ands r0, r0, r1
- bne jump_intr
- add r2, r2, #8
- b findIRQ
-
-@---------------------------------------------------------------------------------
-no_handler:
-@---------------------------------------------------------------------------------
- str r1, [r3, #0x0214] @ IF Clear
- ldmfd sp!, {r0-r1,r3,lr} @ {spsr, IME, REG_BASE, lr_irq}
- str r1, [r3, #0x208] @ restore REG_IME
- mov pc,lr
-
-@---------------------------------------------------------------------------------
-jump_intr:
-@---------------------------------------------------------------------------------
- ldr r1, [r2] @ user IRQ handler address
- cmp r1, #0
- bne got_handler
- mov r1, r0
- b no_handler
-@---------------------------------------------------------------------------------
-got_handler:
-@---------------------------------------------------------------------------------
-
- mrs r2, cpsr
- bic r2, r2, #0xdf @ \__
- orr r2, r2, #0x1f @ / --> Enable IRQ & FIQ. Set CPU mode to System.
- msr cpsr,r2
-
- str r0, [r3, #0x0214] @ IF Clear
-
- push {lr}
- adr lr, IntrRet
- bx r1
-
-@---------------------------------------------------------------------------------
-IntrRet:
-@---------------------------------------------------------------------------------
- mov r3, #0x4000000 @ REG_BASE
- str r3, [r3, #0x208] @ disable IME
- pop {lr}
-
- mrs r3, cpsr
- bic r3, r3, #0xdf @ \__
- orr r3, r3, #0x92 @ / --> Disable IRQ. Enable FIQ. Set CPU mode to IRQ.
- msr cpsr, r3
-
- ldmfd sp!, {r0-r1,r3,lr} @ {spsr, IME, REG_BASE, lr_irq}
- msr spsr, r0 @ restore spsr
- str r1, [r3, #0x208] @ restore REG_IME
- mov pc,lr
-
- .pool
- .end
+
+ Revision 1.10 2007/08/11 06:00:23 wntrmute
+ make nesting really work
+
+ Revision 1.9 2007/01/10 15:48:27 wntrmute
+ remove unused code
+
+ Revision 1.8 2006/12/16 09:10:02 wntrmute
+ acknowledge interrupt before calling handler
+
+ Revision 1.7 2006/04/26 05:11:31 wntrmute
+ rebase dtcm, take __irq_flags and __irq_vector from linker script
+ move arm7 irq vector & irq flags to actual locations
+
+ Revision 1.6 2006/04/23 18:19:15 wntrmute
+ reworked interrupt code to allow dtcm moving
+
+ Revision 1.5 2005/12/12 13:01:55 wntrmute
+ disable interrupts on return from user handler
+
+ Revision 1.4 2005/10/21 22:43:42 wntrmute
+ restore REG_IME on exit from null handler
+
+ Revision 1.3 2005/09/27 18:21:53 wntrmute
+ safer nested interrupt support
+
+ Revision 1.2 2005/09/04 16:37:01 wntrmute
+ check for NULL handler
+
+ Revision 1.1 2005/09/03 17:09:35 wntrmute
+ added interworking aware interrupt dispatcher
+
+
+---------------------------------------------------------------------------------*/
+
+#ifdef ARM7
+ .text
+#endif
+
+#ifdef ARM9
+ .section .itcm,"ax",%progbits
+#endif
+
+ .extern irqTable
+ .code 32
+
+ .global IntrMain
+@---------------------------------------------------------------------------------
+IntrMain:
+@---------------------------------------------------------------------------------
+ mov r3, #0x4000000 @ REG_BASE
+
+ ldr r1, [r3, #0x208] @ r1 = IME
+ str r3, [r3, #0x208] @ disable IME
+ mrs r0, spsr
+ stmfd sp!, {r0-r1,r3,lr} @ {spsr, IME, REG_BASE, lr_irq}
+
+ ldr r1, [r3,#0x210] @ REG_IE
+ ldr r2, [r3,#0x214] @ REG_IF
+ and r1,r1,r2
+
+ ldr r0,=__irq_flags @ defined by linker script
+
+ ldr r2,[r0]
+ orr r2,r2,r1
+ str r2,[r0]
+
+ ldr r2,=irqTable
+@---------------------------------------------------------------------------------
+findIRQ:
+@---------------------------------------------------------------------------------
+ ldr r0, [r2, #4]
+ cmp r0,#0
+ beq no_handler
+ ands r0, r0, r1
+ bne jump_intr
+ add r2, r2, #8
+ b findIRQ
+
+@---------------------------------------------------------------------------------
+no_handler:
+@---------------------------------------------------------------------------------
+ str r1, [r3, #0x0214] @ IF Clear
+ ldmfd sp!, {r0-r1,r3,lr} @ {spsr, IME, REG_BASE, lr_irq}
+ str r1, [r3, #0x208] @ restore REG_IME
+ mov pc,lr
+
+@---------------------------------------------------------------------------------
+jump_intr:
+@---------------------------------------------------------------------------------
+ ldr r1, [r2] @ user IRQ handler address
+ cmp r1, #0
+ bne got_handler
+ mov r1, r0
+ b no_handler
+@---------------------------------------------------------------------------------
+got_handler:
+@---------------------------------------------------------------------------------
+
+ mrs r2, cpsr
+ bic r2, r2, #0xdf @ \__
+ orr r2, r2, #0x1f @ / --> Enable IRQ & FIQ. Set CPU mode to System.
+ msr cpsr,r2
+
+ str r0, [r3, #0x0214] @ IF Clear
+
+ push {lr}
+ adr lr, IntrRet
+ bx r1
+
+@---------------------------------------------------------------------------------
+IntrRet:
+@---------------------------------------------------------------------------------
+ mov r3, #0x4000000 @ REG_BASE
+ str r3, [r3, #0x208] @ disable IME
+ pop {lr}
+
+ mrs r3, cpsr
+ bic r3, r3, #0xdf @ \__
+ orr r3, r3, #0x92 @ / --> Disable IRQ. Enable FIQ. Set CPU mode to IRQ.
+ msr cpsr, r3
+
+ ldmfd sp!, {r0-r1,r3,lr} @ {spsr, IME, REG_BASE, lr_irq}
+ msr spsr, r0 @ restore spsr
+ str r1, [r3, #0x208] @ restore REG_IME
+ mov pc,lr
+
+ .pool
+ .end