Add game specific gbaframe support ...

* Can now use gbaframes specific to a gba rom being loaded to ram/flash.
Have a bmp file with filename matching the game rom being flashed in
GBA_SIGN path. If it finds a matching BMP it will use that before
falling back to the default gbaframe.bmp paths.
* nds-bootstrap now used for booting retail NDS roms from file browser.
Note that currently GBA-Exploader does not create new save files so only
games with existing save files (currently hardcoded to GBA_SAV path like
with GBA games) can be booted with this.
This commit is contained in:
ApacheThunder 2024-11-17 15:44:06 -06:00
parent b0e0250f0d
commit 540515c7fc
164 changed files with 29537 additions and 76 deletions

View File

@ -9,7 +9,7 @@ export TARGET := GBA_ExpLoader
export TOPDIR := $(CURDIR)
export VERSION_MAJOR := 0
export VERSION_MINOR := 65
export VERSION_MINOR := 66
export VERSTRING := $(VERSION_MAJOR).$(VERSION_MINOR)
# GMAE_ICON is the image used to create the game icon, leave blank to use default rule

View File

@ -40,6 +40,7 @@ LIBS := -lfat -lnds329
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS) $(PORTLIBS)
LIBDIRS32 := $(CURDIR)/../libraries/libnds32
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
@ -87,7 +88,8 @@ export HFILES := $(BMPFILES:.bmp=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
$(foreach dir,$(LIBDIRS32),-L$(dir)/lib)
.PHONY: $(BUILD) clean

View File

@ -47,7 +47,8 @@ typedef bool BOOL;
#define PSRAMBase_S98 0x08800000 // EZ Flash Omega PSRAM location while in Kernal mode. (only writable in Kernal mode)
#define FlashBase_S98 0x09000000
#define SRAM_ADDR 0x0A000000
#define SRAM_ADDR_OMEGA 0x0E000000
// #define SRAM_ADDR_OMEGA 0x0E000000 // SRAM address changes in DS mode. Use 0x0A000000 instead.
#define SRAM_ADDR_OMEGA 0x0A000000
#define RTC_ENABLE ((vu16*)0x080000C8)
#define OMEGA_NOSAVE 0

View File

@ -158,7 +158,8 @@ void Omega_InitFatBuffer(BYTE saveMODE, u32 saveSize, u32 gameSize) {
FAT_table_buffer[0x1F8/4] = 0x40; // secort of cluster
FAT_table_buffer[0x1FC/4] = ((saveMODE << 24) | saveSize); // save mode and save file size
// FAT_table_buffer[0x204/4] = 0x363100; // Save file sector location
FAT_table_buffer[0x204/4] = 0x00C07644;
// FAT_table_buffer[0x204/4] = 0x00C07644;
FAT_table_buffer[0x204/4] = 0xFFFFFFFF;
FAT_table_buffer[0x208/4] = 0xFFFFFFFF;
// FAT_table_buffer[0x308/4] = 0x100; // RTS?
// FAT_table_buffer[0x320/4] = 0xFFFFFFFF; // RTS?
@ -171,7 +172,7 @@ void Omega_InitFatBuffer(BYTE saveMODE, u32 saveSize, u32 gameSize) {
}*/
SetbufferControl(1);
// dmaCopy(FAT_table_buffer, (void*)0x9E00000, 0x400);
tonccpy((u16*)0x9E00000, (u32*)FAT_table_buffer, 0x400);
tonccpy((void*)0x9E00000, &FAT_table_buffer, 0x400);
SetbufferControl(3);
SetbufferControl(0);
/*SetbufferControl(0);

370
arm9/include/inifile.cpp Normal file
View File

@ -0,0 +1,370 @@
/*
inifile.cpp
Copyright (C) 2007 Acekard, www.acekard.com
Copyright (C) 2007-2009 somebody
Copyright (C) 2009 yellow wood goblin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "inifile.h"
#include "stringtool.h"
#include <cstdio>
#include <cstdlib>
bool gbar2Fix = false;
static bool freadLine(FILE *f, std::string &str)
{
str.clear();
__read:
char p = 0;
size_t readed = fread(&p, 1, 1, f);
if (0 == readed) {
str = "";
return false;
}
if ('\n' == p || '\r' == p) {
str = "";
return true;
}
while (p != '\n' && p != '\r' && readed) {
str += p;
readed = fread(&p, 1, 1, f);
}
if (str.empty() || "" == str) {
goto __read;
}
return true;
}
static void trimString(std::string &str)
{
size_t first = str.find_first_not_of(" \t"), last;
if (first == str.npos) {
str = "";
} else {
last = str.find_last_not_of(" \t");
if (first > 0 || (last + 1) < str.length())
str = str.substr(first, last - first + 1);
}
}
CIniFile::CIniFile()
{
m_bLastResult = false;
m_bModified = false;
m_bReadOnly = false;
}
CIniFile::CIniFile(const std::string &filename)
{
m_sFileName = filename;
m_bLastResult = false;
m_bModified = false;
m_bReadOnly = false;
LoadIniFile(m_sFileName);
}
CIniFile::~CIniFile()
{
if (m_FileContainer.size() > 0) {
m_FileContainer.clear();
}
}
void CIniFile::SetString(const std::string &Section, const std::string &Item, const std::string &Value)
{
if (GetFileString(Section, Item) != Value) {
SetFileString(Section, Item, Value);
m_bModified = true;
}
}
void CIniFile::SetInt(const std::string &Section, const std::string &Item, int Value)
{
std::string strtemp = formatString("%d", Value);
if (GetFileString(Section, Item) != strtemp) {
SetFileString(Section, Item, strtemp);
m_bModified = true;
}
}
std::string CIniFile::GetString(const std::string &Section, const std::string &Item)
{
return GetFileString(Section, Item);
}
std::string CIniFile::GetString(const std::string &Section, const std::string &Item, const std::string &DefaultValue)
{
std::string temp = GetString(Section, Item);
if (!m_bLastResult) {
SetString(Section, Item, DefaultValue);
temp = DefaultValue;
}
return temp;
}
void CIniFile::GetStringVector(const std::string &Section, const std::string &Item, std::vector<std::string> &strings, char delimiter)
{
std::string strValue = GetFileString(Section, Item);
strings.clear();
size_t pos;
while ((pos = strValue.find(delimiter), strValue.npos != pos)) {
const std::string string = strValue.substr(0, pos);
if (string.length()) {
strings.push_back(string);
}
strValue = strValue.substr(pos + 1, strValue.npos);
}
if (strValue.length()) {
strings.push_back(strValue);
}
}
void CIniFile::SetStringVector(const std::string &Section, const std::string &Item, std::vector<std::string> &strings, char delimiter)
{
std::string strValue;
for (size_t ii = 0; ii < strings.size(); ++ii) {
if (ii)
strValue += delimiter;
strValue += strings[ii];
}
SetString(Section, Item, strValue);
}
int CIniFile::GetInt(const std::string &Section, const std::string &Item)
{
std::string value = GetFileString(Section, Item);
if (value.size() > 2 && '0' == value[0] && ('x' == value[1] || 'X' == value[1]))
return strtol(value.c_str(), NULL, 16);
else
return strtol(value.c_str(), NULL, 10);
}
int CIniFile::GetInt(const std::string &Section, const std::string &Item, int DefaultValue)
{
int temp;
temp = GetInt(Section, Item);
if (!m_bLastResult) {
SetInt(Section, Item, DefaultValue);
temp = DefaultValue;
}
return temp;
}
bool CIniFile::LoadIniFile(const std::string &FileName)
{
//dbg_printf("load %s\n",FileName.c_str());
if (FileName != "")
m_sFileName = FileName;
FILE *f = fopen(FileName.c_str(), "rb");
if (NULL == f)
return false;
//check for utf8 bom.
char bom[3];
if (fread(bom, 3, 1, f) == 1 && bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf)
;
else
fseek(f, 0, SEEK_SET);
std::string strline("");
m_FileContainer.clear();
while (freadLine(f, strline)) {
trimString(strline);
if (strline != "" && ';' != strline[0] && '/' != strline[0] && '!' != strline[0])
m_FileContainer.push_back(strline);
}
fclose(f);
m_bLastResult = false;
m_bModified = false;
return true;
}
bool CIniFile::SaveIniFileModified(const std::string &FileName)
{
if (m_bModified == true) {
return SaveIniFile(FileName);
}
return true;
}
bool CIniFile::SaveIniFile(const std::string &FileName)
{
if (FileName != "")
m_sFileName = FileName;
FILE *f = fopen(m_sFileName.c_str(), "wb");
if (NULL == f) {
return false;
}
for (size_t ii = 0; ii < m_FileContainer.size(); ii++) {
std::string &strline = m_FileContainer[ii];
size_t notSpace = strline.find_first_not_of(' ');
strline = strline.substr(notSpace);
if (strline.find('[') == 0 && ii > 0) {
if (!m_FileContainer[ii - 1].empty() && m_FileContainer[ii - 1] != "")
fwrite((gbar2Fix ? "\n" : "\r\n"), 1, 2-gbar2Fix, f);
}
if (!strline.empty() && strline != "") {
fwrite(strline.c_str(), 1, strline.length(), f);
fwrite((gbar2Fix ? "\n" : "\r\n"), 1, 2-gbar2Fix, f);
}
}
fclose(f);
m_bModified = false;
return true;
}
std::string CIniFile::GetFileString(const std::string &Section, const std::string &Item)
{
std::string strline;
std::string strSection;
std::string strItem;
std::string strValue;
size_t ii = 0;
size_t iFileLines = m_FileContainer.size();
if (m_bReadOnly) {
SectionCache::iterator it = m_Cache.find(Section);
if ((it != m_Cache.end()))
ii = it->second;
}
m_bLastResult = false;
if (iFileLines >= 0) {
while (ii < iFileLines) {
strline = m_FileContainer[ii++];
size_t rBracketPos = 0;
if ('[' == strline[0])
rBracketPos = strline.find(']');
if (rBracketPos > 0 && rBracketPos != std::string::npos) {
strSection = strline.substr(1, rBracketPos - 1);
if (m_bReadOnly)
m_Cache.insert(std::make_pair(strSection, ii - 1));
if (strSection == Section) {
while (ii < iFileLines) {
strline = m_FileContainer[ii++];
size_t equalsignPos = strline.find('=');
if (equalsignPos != strline.npos) {
size_t last = equalsignPos ? strline.find_last_not_of(" \t", equalsignPos - 1) : strline.npos;
if (last == strline.npos)
strItem = "";
else
strItem = strline.substr(0, last + 1);
if (strItem == Item) {
size_t first = strline.find_first_not_of(" \t", equalsignPos + 1);
if (first == strline.npos)
strValue = "";
else
strValue = strline.substr(first);
m_bLastResult = true;
return strValue;
}
} else if ('[' == strline[0]) {
break;
}
}
break;
}
}
}
}
return std::string("");
}
void CIniFile::SetFileString(const std::string &Section, const std::string &Item, const std::string &Value)
{
std::string strline;
std::string strSection;
std::string strItem;
if (m_bReadOnly)
return;
size_t ii = 0;
size_t iFileLines = m_FileContainer.size();
while (ii < iFileLines) {
strline = m_FileContainer[ii++];
size_t rBracketPos = 0;
if ('[' == strline[0])
rBracketPos = strline.find(']');
if (rBracketPos > 0 && rBracketPos != std::string::npos) {
strSection = strline.substr(1, rBracketPos - 1);
if (strSection == Section) {
while (ii < iFileLines) {
strline = m_FileContainer[ii++];
size_t equalsignPos = strline.find('=');
if (equalsignPos != strline.npos) {
size_t last = equalsignPos ? strline.find_last_not_of(" \t", equalsignPos - 1) : strline.npos;
if (last == strline.npos)
strItem = "";
else
strItem = strline.substr(0, last + 1);
if (Item == strItem) {
ReplaceLine(ii - 1, Item + (gbar2Fix ? "=" : " = ") + Value);
return;
}
} else if ('[' == strline[0]) {
InsertLine(ii - 1, Item + (gbar2Fix ? "=" : " = ") + Value);
return;
}
}
InsertLine(ii, Item + (gbar2Fix ? "=" : " = ") + Value);
return;
}
}
}
InsertLine(ii, "[" + Section + "]");
InsertLine(ii + 1, Item + (gbar2Fix ? "=" : " = ") + Value);
return;
}
bool CIniFile::InsertLine(size_t line, const std::string &str)
{
m_FileContainer.insert(m_FileContainer.begin() + line, str);
return true;
}
bool CIniFile::ReplaceLine(size_t line, const std::string &str)
{
m_FileContainer[line] = str;
return true;
}

69
arm9/include/inifile.h Normal file
View File

@ -0,0 +1,69 @@
/*
common/inifile.h
Copyright (C) 2007 Acekard, www.acekard.com
Copyright (C) 2007-2009 somebody
Copyright (C) 2009-2010 yellow wood goblin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INIFILE_H_
#define _INIFILE_H_
#include <string>
#include <vector>
#include <map>
extern bool gbar2Fix;
class CIniFile
{
public:
CIniFile();
CIniFile(const std::string& filename);
virtual ~CIniFile();
public:
bool LoadIniFile(const std::string& FileName);
bool SaveIniFile(const std::string& FileName);
bool SaveIniFileModified(const std::string& FileName);
std::string GetString(const std::string& Section,const std::string& Item,const std::string& DefaultValue);
void SetString(const std::string& Section,const std::string& Item,const std::string& Value);
int GetInt(const std::string& Section,const std::string& Item,int DefaultValue);
void SetInt(const std::string& Section,const std::string& Item,int Value);
void GetStringVector(const std::string& Section,const std::string& Item,std::vector<std::string>& strings,char delimiter=',');
void SetStringVector(const std::string& Section,const std::string& Item,std::vector<std::string>& strings,char delimiter=',');
protected:
std::string m_sFileName;
typedef std::vector<std::string> StringArray;
StringArray m_FileContainer;
bool m_bLastResult;
bool m_bModified;
bool m_bReadOnly;
typedef std::map<std::string,size_t> SectionCache;
SectionCache m_Cache;
bool InsertLine(size_t line,const std::string& str);
bool ReplaceLine(size_t line,const std::string& str);
void SetFileString(const std::string& Section,const std::string& Item,const std::string& Value);
std::string GetFileString(const std::string& Section,const std::string& Item);
std::string GetString(const std::string& Section,const std::string& Item);
int GetInt(const std::string& Section,const std::string& Item);
};
#endif // _INIFILE_H_

View File

@ -0,0 +1,75 @@
#include <nds.h>
#include <stddef.h>
#include "inifile.h"
#include "tonccpy.h"
#include "nds_loader_arm9.h"
#ifdef __cplusplus
extern "C" {
#endif
using namespace std;
volatile char currentNDSFilePath[256];
volatile char iniNDSFilePath[261];
volatile char iniSAVFilePath[261];
const char* bootstrapPath = "/_nds/nds-bootstrap-release.nds";
const char* bootstrapINIPath = "/_nds/nds-bootstrap.ini";
const char* fatString = "fat:";
volatile int bootstrapPathLength = 0;
volatile int ndsPathLength = 0;
volatile int savPathLength = 0;
int runNDSFile (char tbuf[], char* iniPath, char* curPathName, char* ndsName, char* savName, bool isHomebrew) {
bool usebootstrap = true;
if (isHomebrew || (access(bootstrapPath, F_OK) != 0) || (access(bootstrapINIPath, F_OK) != 0))usebootstrap = false;
sprintf(tbuf, "%s%s", curPathName, ndsName);
ndsPathLength = (strlen((const char*)tbuf) + 1);
if (ndsPathLength > 256)return 9;
tonccpy((char*)currentNDSFilePath, (char*)tbuf, ndsPathLength);
if (!usebootstrap || ((ndsPathLength + 4) > 261)) {
const char *ndsARGArray1[] = { (char*)currentNDSFilePath };
return runNdsFile(ndsARGArray1[0], 1, ndsARGArray1);
}
sprintf(tbuf, "%s%s", fatString, currentNDSFilePath);
tonccpy((char*)iniNDSFilePath, (char*)tbuf, (ndsPathLength + 4));
sprintf(tbuf, "%s%s%s%s", fatString, iniPath, "/", savName);
savPathLength = (strlen((const char*)tbuf) + 1);
if (savPathLength > 262) {
const char *ndsARGArray2[] = { (char*)currentNDSFilePath };
return runNdsFile(ndsARGArray2[0], 1, ndsARGArray2);
}
tonccpy((char*)iniSAVFilePath, (char*)tbuf, savPathLength);
CIniFile bootstrapini(bootstrapINIPath);
bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", (char*)iniNDSFilePath);
bootstrapini.SetString("NDS-BOOTSTRAP", "SAV_PATH", (char*)iniSAVFilePath);
bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", "");
bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", "");
bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 0);
bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
bootstrapini.SaveIniFile(bootstrapINIPath);
swiWaitForVBlank();
const char* ndsARGArrayBootstrap[] = { bootstrapPath };
return runNdsFile(bootstrapPath, 1, ndsARGArrayBootstrap);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2007 Acekard, www.acekard.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---------------------------------------------------------------------------------*/
#include "stringtool.h"
#include <cstdarg>
#include <cstdio>
#include <malloc.h>
std::string formatString(const char *fmt, ...)
{
const char *f = fmt;
va_list argList;
va_start(argList, fmt);
char *ptempStr = NULL;
size_t max_len = vasiprintf( &ptempStr, f, argList);
std::string str( ptempStr );
str.resize( max_len );
free( ptempStr );
va_end(argList);
return str;
}
std::string replaceAll(std::string str, const std::string &from, const std::string &to)
{
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
}
return str;
}

37
arm9/include/stringtool.h Normal file
View File

@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2007 Acekard, www.acekard.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---------------------------------------------------------------------------------*/
#ifndef _STRINGTOOL_H_
#define _STRINGTOOL_H_
#include <string>
std::string formatString(const char *fmt, ...);
std::string replaceAll(std::string str, const std::string &from, const std::string &to);
#endif //_STRINGTOOL_H_

View File

@ -5,6 +5,8 @@ struct GBA_File {
u32 type;
u32 filesize;
int isNDSFile;
int isHomebrewNDS;
char ndssavfilename[512];
};

View File

@ -37,12 +37,14 @@
#define SRAM_PAGE_SIZE 0x10000 // SRAM Page Size
#define MAX_SRAM 0x80000 // 4MBit/512KByte total SRAM
#define USE_SRAM 0x20000 // 128KByte
#define USE_SRAM 0x20000 // 128KByte
#define USE_SRAM_PG 48 // 0x0A030000-0A031FFF
#define USE_SRAM_PG_EZ4 11 // 0x0A008000-0A00FFFF
#define USE_SRAM_PG_EWN 10 // 0x0A020000-0A02FFFF
#define USE_SRAM_PG_EWN128 9 // 0x0A010000-0A01FFFF
#define USE_SRAM_PG_M3 6
#define USE_SRAM_PG_OMEGA 96
#define USE_SRAM_PG_OMEGA_DE 16
#define USE_SRAM_NOR 16 // 0x0A010000-0A02FFFF
#define USE_SRAM_PSR 50 // 0x0A032000-0A051FFF
@ -78,11 +80,7 @@ extern int GBAmode;
static u32 savesize;
static const char *validExtensions[3] = {
".GBA",
".BIN",
".NDS"
};
static const char *validExtensions[3] = { ".GBA", ".BIN", ".NDS" };
int carttype = 0;
bool isSuperCard = false;
@ -502,10 +500,10 @@ void _RamPG() {
}
if (isOmega) {
if (isOmegaDE) {
SetRampage(16);
SetRampage(USE_SRAM_PG_OMEGA_DE);
return;
}
SetRampage(96);
SetRampage(USE_SRAM_PG_OMEGA);
} else {
SetRampage(USE_SRAM_PG);
}
@ -591,7 +589,7 @@ int checkSRAM(char *name) {
ctrl.save_siz[GBAmode] = savesize;
}
if (isOmega && (savesize > 0x10000))savesize = 0x10000;
// if (isOmega && (savesize > 0x10000))savesize = 0x10000;
strcpy(name, (char *)ctrl.sav_nam[GBAmode]);
ln = strlen(name) - 3;
@ -704,7 +702,9 @@ void SRAMdump(int cmd) {
mx = 8;
switch (carttype) {
case 1: if (isOmega)mx = 2; break;
case 1:
if (isOmega)mx = 2;
break;
case 4: mx = 4; break;
case 5: mx = 2; break;
case 6:
@ -761,7 +761,7 @@ void SRAMdump(int cmd) {
dmp = fopen(name, "rb");
// if((carttype < 4) && !isSuperCard && !isOmega && !is3in1Plus)OpenNorWrite();
if (isOmega)Omega_Bank_Switching(0);
// if (isOmega)Omega_Bank_Switching(0);
for(i = 0; i < mx; i++) {
memset(rwbuf, 0, USE_SRAM / 2);
@ -815,7 +815,7 @@ void blankSRAM(char *savename) {
// if((carttype < 4) && !isSuperCard && !isOmega && !is3in1Plus)OpenNorWrite();
if (isOmega)Omega_Bank_Switching(0);
// if (isOmega)Omega_Bank_Switching(0);
_RamSave(0);
@ -901,7 +901,7 @@ void writeSramFromFile(char *savename) {
// OpenNorWrite();
if (isOmega)Omega_Bank_Switching(0);
// if (isOmega)Omega_Bank_Switching(0);
_RamSave(0);
@ -1306,7 +1306,16 @@ void FileListGBA() {
// strcpy(fs[numFiles].Alias, pent->d_name);
fs[numFiles].type = st.st_mode;
fs[numFiles].isNDSFile = 0;
if (nameEndsWith(pent->d_name, validExtensions[2]))fs[numFiles].isNDSFile = 1;
fs[numFiles].isHomebrewNDS = 0;
if (nameEndsWith(pent->d_name, validExtensions[2])) {
fs[numFiles].isNDSFile = 1;
strcpy(fs[numFiles].ndssavfilename, pent->d_name);
// int filenameLength = (strlen((const char*)fs[numFiles].ndssavfilename) + 1);
int filenameLength = strlen((const char*)fs[numFiles].ndssavfilename);
fs[numFiles].ndssavfilename[filenameLength - 3] = 'S';
fs[numFiles].ndssavfilename[filenameLength - 2] = 'A';
fs[numFiles].ndssavfilename[filenameLength - 1] = 'V';
}
if ((((string)pent->d_name).compare(".") != 0) && (((string)pent->d_name).compare("..") != 0) && ((st.st_mode & S_IFMT) != S_IFDIR)) {
FILE *file = fopen(pent->d_name, "rb");
if (file) {
@ -1338,6 +1347,11 @@ void FileListGBA() {
strcpy(fs[i].gamecode, tbuf + 0x0C);
tbuf[0x0C] = 0;
strcpy(fs[i].gametitle, tbuf); // 0x0
if (((fs[i].gamecode[0] == '#') && (fs[i].gamecode[1] == '#') &&
(fs[i].gamecode[2] == '#') && (fs[i].gamecode[3] == '#')) || (tbuf[0x85] == 0x02))
{
fs[i].isHomebrewNDS = 1;
}
} else {
fread(tbuf, 1, 256, gbaFile);
tbuf[0xB0] = 0;

View File

@ -43,20 +43,19 @@
#include "skin.h"
#include "message.h"
#include "tonccpy.h"
#include "nds_loader_arm9.h"
extern uint16* MainScreen;
extern uint16* SubScreen;
#define BG_256_COLOR (BIT(7))
#define VERSTRING "v0.65"
#define VERSTRING "v0.66"
int numFiles = 0;
int numGames = 0;
char curpath[256];
char* currentNDSFilePath[256];
int sortfile[200];
struct GBA_File fs[200];
@ -68,6 +67,12 @@ u8 *rwbuf;
int GBAmode;
bool softReset;
u16 *gbar = NULL;
int oldper;
// extern u32 _io_dldi;
extern bool checkSRAM_cnf();
extern int checkSRAM(char *name);
extern int carttype;
extern bool isSuperCard;
extern bool is3in1Plus;
@ -75,6 +80,28 @@ extern bool isOmega;
extern bool isOmegaDE;
extern u16 gl_ingame_RTC_open_status;
extern void SetSDControl(u16 control);
extern bool ret_menu_chk(void);
extern void setGBAmode(int sel);
extern void getGBAmode(void);
extern int writeFileToNor(int sel);
extern int writeFileToRam(int sel);
extern void writeSramToFile(char *name);
extern void writeSramFromFile(char *name);
extern void SRAMdump(int cmd);
extern bool checkBackup(void);
extern bool checkFlashID(void);
extern u32 SaveType;
extern u32 SaveSize;
extern u8 SaveVer[];
extern int PatchCnt;
extern u32 PatchType[];
extern u32 PatchAddr[];
extern void setcurpath(void);
extern void getcurpath(void);
extern void FileListGBA(void);
extern int save_sel(int mod, char *name);
extern void setLang(void);
extern int runNDSFile (char tbuf[], char* iniPath, char* curPathName, char* ndsName, char* savName, bool isHomebrew);
u32 inp_key() {
u32 ky;
@ -95,12 +122,6 @@ u32 inp_key() {
}
extern bool ret_menu_chk(void);
extern void setGBAmode(void);
extern void getGBAmode(void);
void turn_off(bool softReset) {
if (softReset) {
if (!ret_menu9_Gen())systemShutDown();
@ -111,13 +132,42 @@ void turn_off(bool softReset) {
}
void gba_frame() {
void gba_frame(int Sel) {
int ret;
int mode = 3; // old mode == 2
// int x = 0, y = 0;
// u16 *pDstBuf1;
// u16 *pDstBuf2;
// fs[sel].filename
if (Sel != -1) {
int nameLength = strlen(fs[Sel].filename);
if (nameLength > 4) {
if (( (fs[Sel].filename[(nameLength - 4)] == '.') &&
(fs[Sel].filename[(nameLength - 3)] == 'G') &&
(fs[Sel].filename[(nameLength - 2)] == 'B') &&
(fs[Sel].filename[(nameLength - 1)] == 'A')
) || (
(fs[Sel].filename[(nameLength - 4)] == '.') &&
(fs[Sel].filename[(nameLength - 3)] == 'g') &&
(fs[Sel].filename[(nameLength - 2)] == 'b') &&
(fs[Sel].filename[(nameLength - 1)] == 'a')
)
) {
fs[Sel].filename[(nameLength - 3)] = 'b';
fs[Sel].filename[(nameLength - 2)] = 'm';
fs[Sel].filename[(nameLength - 1)] = 'p';
// if((fname[ln - 4] != '.') || (fname[ln - 3] != 'S') || (fname[ln - 2] != 'A') || (fname[ln - 1] != 'V'))
sprintf(tbuf, "%s/%s", ini.sign_dir, fs[Sel].filename);
if (access(tbuf, F_OK) == 0) {
ret = LoadSkin(mode, tbuf);
if(ret)return;
}
}
}
}
if (access("/gbaframe.bmp", F_OK) == 0) {
ret = LoadSkin(mode, "/gbaframe.bmp");
if(ret)return;
@ -169,7 +219,7 @@ static void resetToSlot2() {
swiSoftReset();
}
void gbaMode() {
void gbaMode(int sel) {
if(strncmp(GBA_HEADER.gamecode, "PASS", 4) == 0)resetToSlot2();
@ -198,7 +248,7 @@ void gbaMode() {
if(PersonalData->gbaScreen) { lcdMainOnBottom(); } else { lcdMainOnTop(); }
gba_frame();
gba_frame(sel);
sysSetBusOwners(ARM7_OWNS_CARD, ARM7_OWNS_ROM);
fifoSendValue32(FIFO_USER_01, 1);
@ -349,10 +399,6 @@ int cnf_inp2(int n1, int n2) {
}
u16 *gbar = NULL;
int oldper;
void dsp_bar(int mod, int per) {
int x1, x2;
int y1, y2;
@ -425,7 +471,6 @@ void RamClear() {
}
void _dsp_clear() { DrawBox_SUB(SubScreen, 0, 28, 255, 114, 0, 1); }
@ -506,7 +551,7 @@ int rumble_cmd() {
if(ky & KEY_L) {
GBAmode = 1;
if (isOmega)GBAmode = 0;
setGBAmode();
setGBAmode(-1);
cmd = -1;
break;
}
@ -599,9 +644,6 @@ void _gba_dsp2(char *name)
}
***************/
extern bool checkSRAM_cnf();
extern int checkSRAM(char *name);
void _gba_sel_dsp(int no, int yc, int mod) {
int x, y;
@ -699,13 +741,6 @@ void _gba_sel_dsp(int no, int yc, int mod) {
}
}
extern int writeFileToNor(int sel);
extern int writeFileToRam(int sel);
extern void writeSramToFile(char *name);
extern void writeSramFromFile(char *name);
extern void SRAMdump(int cmd);
extern bool checkBackup(void);
extern bool checkFlashID(void);
/***************************
int gba_sel0()
@ -767,20 +802,6 @@ int gba_sel0()
****************/
extern u32 SaveType;
extern u32 SaveSize;
extern u8 SaveVer[];
extern int PatchCnt;
extern u32 PatchType[];
extern u32 PatchAddr[];
extern void setcurpath(void);
extern void getcurpath(void);
extern void FileListGBA(void);
extern int save_sel(int mod, char *name);
int gba_sel() {
// u32 i;
@ -884,7 +905,7 @@ int gba_sel() {
if(GBAmode > 0) {
GBAmode--;
if ((GBAmode == 1) && isOmega)GBAmode--;
setGBAmode();
setGBAmode(-1);
_gba_sel_dsp(sel, yc, 0);
// cmd = -1;
// break;
@ -897,7 +918,7 @@ int gba_sel() {
} else if(GBAmode < cn && carttype <= 2) {
GBAmode++;
if ((GBAmode == 1) && isOmega)GBAmode++;
setGBAmode();
setGBAmode(-1);
if(GBAmode == 2) {
_gba_dsp(sel, 0, x, y+yc);
cmd = -1;
@ -919,7 +940,7 @@ int gba_sel() {
break;
} else if (isOmega && (GBAmode == 0)) {
SetRompage(0x8002);
gbaMode();
gbaMode(-1);
}
}
if(ky & KEY_SELECT) {
@ -942,7 +963,7 @@ int gba_sel() {
// if (!is3in1Plus)SetRompage(0);
SetRompage(0);
SetRampage(16);
gbaMode();
gbaMode(-1);
} else {
if(cnf_inp(7, 8) & KEY_A)SRAMdump(0);
}
@ -992,12 +1013,8 @@ int gba_sel() {
break;
}
if (fs[sortfile[sel]].isNDSFile == 1) {
sprintf(tbuf, "%s%s", curpath, fs[sortfile[sel]].filename);
tonccpy((char*)currentNDSFilePath, (char*)tbuf, (strlen((const char*)tbuf) + 1));
const char *ndsARGArray[] = { (char*)currentNDSFilePath };
runNdsFile(tbuf, 1, ndsARGArray);
runNDSFile(tbuf, ini.save_dir, curpath, fs[sortfile[sel]].filename, fs[sortfile[sel]].ndssavfilename, (fs[sortfile[sel]].isHomebrewNDS == 1));
cmd = -1;
// sortfile[sel]
break;
}
if(GBAmode == 0) { ret = writeFileToRam(sortfile[sel]); } else { ret = writeFileToNor(sortfile[sel]); }
@ -1011,7 +1028,7 @@ int gba_sel() {
if(GBAmode == 0) {
// if (is3in1Plus)SetRompage(0x100);
// SetRompage(384);
gbaMode();
gbaMode(sortfile[sel]);
}
}
_gba_sel_dsp(sel, yc, 0);
@ -1038,11 +1055,6 @@ int gba_sel() {
}
// extern u32 _io_dldi;
extern void setLang(void);
void mainloop(void) {
// vu16 reg;

View File

@ -0,0 +1,16 @@
name: C/C++ CI
on: [push, pull_request]
jobs:
build:
name: ubuntu-latest
runs-on: ubuntu-latest
container: devkitpro/devkitarm:latest
steps:
- uses: actions/checkout@v4
- name: Build
run: |
make -j

9
libraries/libnds32/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
arm7/debug
arm7/release
arm9/debug
arm9/release
include/nds/libversion.h
lib
docs
warn.log
*.bz2

2327
libraries/libnds32/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
endif
export TOPDIR := $(CURDIR)
export LIBNDS_MAJOR := 1
export LIBNDS_MINOR := 8
export LIBNDS_PATCH := 0
VERSION := $(LIBNDS_MAJOR).$(LIBNDS_MINOR).$(LIBNDS_PATCH)
.PHONY: release debug clean all docs
all: include/nds/libversion.h release debug
#-------------------------------------------------------------------------------
release: lib
#-------------------------------------------------------------------------------
$(MAKE) -C arm9 BUILD=release || { exit 1;}
$(MAKE) -C arm7 BUILD=release || { exit 1;}
#-------------------------------------------------------------------------------
debug: lib
#-------------------------------------------------------------------------------
$(MAKE) -C arm9 BUILD=debug || { exit 1;}
$(MAKE) -C arm7 BUILD=debug || { exit 1;}
#-------------------------------------------------------------------------------
lib:
#-------------------------------------------------------------------------------
mkdir lib
#-------------------------------------------------------------------------------
clean:
#-------------------------------------------------------------------------------
@$(MAKE) -C arm9 clean
@$(MAKE) -C arm7 clean
#-------------------------------------------------------------------------------
dist-src:
#-------------------------------------------------------------------------------
@tar --exclude=*CVS* --exclude=.svn -cjf libnds-src-$(VERSION).tar.bz2 arm7/Makefile arm9/Makefile source include icon.bmp Makefile libnds_license.txt Doxyfile
#-------------------------------------------------------------------------------
dist-bin: all
#-------------------------------------------------------------------------------
@tar --exclude=*CVS* --exclude=.svn -cjf libnds-$(VERSION).tar.bz2 include lib icon.bmp libnds_license.txt
dist: dist-bin dist-src
#-------------------------------------------------------------------------------
install: dist-bin
#-------------------------------------------------------------------------------
mkdir -p $(DESTDIR)$(DEVKITPRO)/libnds
bzip2 -cd libnds-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/libnds
#---------------------------------------------------------------------------------
docs:
#---------------------------------------------------------------------------------
doxygen Doxyfile
cat warn.log
#---------------------------------------------------------------------------------
include/nds/libversion.h : Makefile
#---------------------------------------------------------------------------------
@echo "#ifndef __LIBNDSVERSION_H__" > $@
@echo "#define __LIBNDSVERSION_H__" >> $@
@echo >> $@
@echo "#define _LIBNDS_MAJOR_ $(LIBNDS_MAJOR)" >> $@
@echo "#define _LIBNDS_MINOR_ $(LIBNDS_MINOR)" >> $@
@echo "#define _LIBNDS_PATCH_ $(LIBNDS_PATCH)" >> $@
@echo >> $@
@echo '#define _LIBNDS_STRING "libNDS Release '$(LIBNDS_MAJOR).$(LIBNDS_MINOR).$(LIBNDS_PATCH)'"' >> $@
@echo >> $@
@echo "#endif // __LIBNDSVERSION_H__" >> $@

View File

@ -0,0 +1,2 @@
[![Build Status](https://travis-ci.org/devkitPro/libnds.svg?branch=master)](https://travis-ci.org/devkitPro/libnds)

View File

@ -0,0 +1,130 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM)
endif
include $(DEVKITARM)/ds_rules
TOPDIR ?= $(CURDIR)/..
#---------------------------------------------------------------------------------
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files
# all directories are relative to this makefile
#---------------------------------------------------------------------------------
BUILD ?= release
SOURCES := ../source/arm7 ../source/common
INCLUDES := ../include ../source/common
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -mthumb -mthumb-interwork -mcpu=arm7tdmi -mtune=arm7tdmi -DARM7
CFLAGS := -g -Wall -Os \
-ffunction-sections -fdata-sections \
-fomit-frame-pointer\
-ffast-math \
$(ARCH)
CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS)
ASFLAGS := -g $(ARCH)
ASFLAGS += $(INCLUDE)
ifneq ($(BUILD),debug)
export ARM7BIN := $(TOPDIR)/lib/libnds7.a
CFLAGS += -DNDEBUG
else
export ARM7BIN := $(TOPDIR)/lib/libnds7d.a
CFLAGS += -DDEBUG
endif
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS :=
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr debug release
@rm -f $(TOPDIR)/lib/libnds7*
all: $(ARM7BIN)
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(ARM7BIN) : $(OFILES)
@rm -f "$(ARM7BIN)"
@$(AR) rcs "$(ARM7BIN)" $(OFILES)
@echo built ... $(notdir $@)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -0,0 +1,158 @@
.SECONDARY:
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM)
endif
include $(DEVKITARM)/ds_rules
TOPDIR ?= $(CURDIR)/..
#---------------------------------------------------------------------------------
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files
# all directories are relative to this makefile
#---------------------------------------------------------------------------------
BUILD ?= release
SOURCES := ../source/arm9 ../source/arm9/dldi ../source/arm9/system ../source/common
INCLUDES := ../include ../source/common
GRAPHICS := ../source/arm9/gfx
DATA := ../source/arm9
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -mthumb -mthumb-interwork -march=armv5te -mtune=arm946e-s -DARM9
CFLAGS := -g -Wall -O2\
-ffunction-sections -fdata-sections \
-fomit-frame-pointer\
$(ARCH)
CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS)
ASFLAGS = -g $(ARCH)
ASFLAGS += $(INCLUDE)
ifneq ($(BUILD),debug)
export ARM9BIN := $(TOPDIR)/lib/libnds329.a
CFLAGS += -DNDEBUG
else
export ARM9BIN := $(TOPDIR)/lib/libnds329d.a
CFLAGS += -DDEBUG
endif
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS :=
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.bin)))
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES)) $(PNGFILES:.png=.o)
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES := $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr debug release
@rm -f $(TOPDIR)/lib/libnds9*
all: $(ARM9BIN)
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(ARM9BIN) : $(OFILES)
@rm -f "$(ARM9BIN)"
@$(AR) rcs "$(ARM9BIN)" $(OFILES)
@echo built ... $(notdir $@)
$(OFILES_SRC) : $(HFILES)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
%.s %.h : %.png %.grit
#---------------------------------------------------------------------------------
grit $< -fts -o$*
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

443
libraries/libnds32/docs.css Normal file
View File

@ -0,0 +1,443 @@
BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
font-family: Geneva, Arial, Helvetica, sans-serif;
}
BODY,TD {
font-size: 90%;
}
H1 {
text-align: center;
font-size: 160%;
}
H2 {
font-size: 120%;
}
H3 {
font-size: 100%;
}
CAPTION {
font-weight: bold
}
DIV.qindex {
width: 100%;
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
padding: 2px;
line-height: 140%;
}
DIV.navpath {
width: 100%;
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
padding: 2px;
line-height: 140%;
}
DIV.navtab {
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}
DIV.fileHeader
{
width:600px;
}
.fixedFont
{
font-family: Courier New;
white-space:pre;
}
TD.navtab {
font-size: 70%;
}
A.qindex {
text-decoration: none;
font-weight: bold;
color: #1A419D;
}
A.qindex:visited {
text-decoration: none;
font-weight: bold;
color: #1A419D
}
A.qindex:hover {
text-decoration: none;
background-color: #ddddff;
}
A.qindexHL {
text-decoration: none;
font-weight: bold;
background-color: #6666cc;
color: #ffffff;
border: 1px double #9295C2;
}
A.qindexHL:hover {
text-decoration: none;
background-color: #6666cc;
color: #ffffff;
}
A.qindexHL:visited {
text-decoration: none;
background-color: #6666cc;
color: #ffffff
}
A.el {
text-decoration: none;
font-weight: bold
}
A.elRef {
font-weight: bold
}
A.code:link {
text-decoration: none;
font-weight: normal;
color: #0000FF
}
A.code:visited {
text-decoration: none;
font-weight: normal;
color: #0000FF
}
A.codeRef:link {
font-weight: normal;
color: #0000FF
}
A.codeRef:visited {
font-weight: normal;
color: #0000FF
}
A:hover {
text-decoration: none;
background-color: #f2f2ff
}
DL.el {
margin-left: -1cm
}
.fragment {
font-family: monospace, fixed;
font-size: 95%;
}
PRE.fragment {
border: 1px solid #CCCCCC;
background-color: #f5f5f5;
margin-top: 4px;
margin-bottom: 4px;
margin-left: 2px;
margin-right: 8px;
padding-left: 6px;
padding-right: 6px;
padding-top: 4px;
padding-bottom: 4px;
}
DIV.ah {
background-color: black;
font-weight: bold;
color: #ffffff;
margin-bottom: 3px;
margin-top: 3px
}
DIV.groupHeader {
margin-left: 16px;
margin-top: 12px;
margin-bottom: 6px;
font-weight: bold;
}
DIV.groupText {
margin-left: 16px;
font-style: italic;
font-size: 90%
}
BODY {
background: white;
color: black;
margin-right: 20px;
margin-left: 20px;
}
TD.indexkey {
background-color: #e8eef2;
font-weight: bold;
padding-right : 10px;
padding-top : 2px;
padding-left : 10px;
padding-bottom : 2px;
margin-left : 0px;
margin-right : 0px;
margin-top : 2px;
margin-bottom : 2px;
border: 1px solid #CCCCCC;
}
TD.indexvalue {
background-color: #e8eef2;
font-style: italic;
padding-right : 10px;
padding-top : 2px;
padding-left : 10px;
padding-bottom : 2px;
margin-left : 0px;
margin-right : 0px;
margin-top : 2px;
margin-bottom : 2px;
border: 1px solid #CCCCCC;
}
TR.memlist {
background-color: #f0f0f0;
}
P.formulaDsp {
text-align: center;
}
IMG.formulaDsp {
}
IMG.formulaInl {
vertical-align: middle;
}
SPAN.keyword { color: #008000 }
SPAN.keywordtype { color: #604020 }
SPAN.keywordflow { color: #e08000 }
SPAN.comment { color: #800000 }
SPAN.preprocessor { color: #806020 }
SPAN.stringliteral { color: #002080 }
SPAN.charliteral { color: #008080 }
SPAN.vhdldigit { color: #ff00ff }
SPAN.vhdlchar { color: #000000 }
SPAN.vhdlkeyword { color: #700070 }
SPAN.vhdllogic { color: #ff0000 }
.mdescLeft {
padding: 0px 8px 4px 8px;
font-size: 80%;
font-style: italic;
background-color: #FAFAFA;
border-top: 1px none #E0E0E0;
border-right: 1px none #E0E0E0;
border-bottom: 1px none #E0E0E0;
border-left: 1px none #E0E0E0;
margin: 0px;
}
.mdescRight {
padding: 0px 8px 4px 8px;
font-size: 80%;
font-style: italic;
background-color: #FAFAFA;
border-top: 1px none #E0E0E0;
border-right: 1px none #E0E0E0;
border-bottom: 1px none #E0E0E0;
border-left: 1px none #E0E0E0;
margin: 0px;
}
.memItemLeft {
padding: 1px 0px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: solid;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
background-color: #FAFAFA;
font-size: 80%;
}
.memItemRight {
padding: 1px 8px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: solid;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
background-color: #FAFAFA;
font-size: 80%;
}
.memTemplItemLeft {
padding: 1px 0px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: none;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
background-color: #FAFAFA;
font-size: 80%;
}
.memTemplItemRight {
padding: 1px 8px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: none;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
background-color: #FAFAFA;
font-size: 80%;
}
.memTemplParams {
padding: 1px 0px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: solid;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
color: #606060;
background-color: #FAFAFA;
font-size: 80%;
}
.search {
color: #003399;
font-weight: bold;
}
FORM.search {
margin-bottom: 0px;
margin-top: 0px;
}
INPUT.search {
font-size: 75%;
color: #000080;
font-weight: normal;
background-color: #e8eef2;
}
TD.tiny {
font-size: 75%;
}
a {
color: #1A41A8;
}
a:visited {
color: #2A3798;
}
.dirtab {
padding: 4px;
border-collapse: collapse;
border: 1px solid #84b0c7;
}
TH.dirtab {
background: #e8eef2;
font-weight: bold;
}
HR {
height: 1px;
border: none;
border-top: 1px solid black;
}
/* Style for detailed member documentation */
.memtemplate {
font-size: 80%;
color: #606060;
font-weight: normal;
margin-left: 3px;
}
.memnav {
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}
.memitem {
padding: 4px;
background-color: #eef3f5;
border-width: 1px;
border-style: solid;
border-color: #dedeee;
-moz-border-radius: 8px 8px 8px 8px;
}
.memname {
white-space: nowrap;
font-weight: bold;
}
.memdoc{
padding-left: 10px;
}
.memproto {
background-color: #d5e1e8;
width: 100%;
border-width: 1px;
border-style: solid;
border-color: #84b0c7;
font-weight: bold;
-moz-border-radius: 8px 8px 8px 8px;
}
.paramkey {
text-align: right;
}
.paramtype {
white-space: nowrap;
}
.paramname {
color: #602020;
font-style: italic;
white-space: nowrap;
}
/* End Styling for detailed member documentation */
/* for the tree view */
.ftvtree {
font-family: sans-serif;
margin:0.5em;
}
.directory {
font-size: 9pt;
font-weight: bold;
}
.directory h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
.directory > h3 {
margin-top: 0;
}
.directory p {
margin: 0px;
white-space: nowrap;
}
.directory div {
display: none;
margin: 0px;
}
.directory img {
vertical-align: -30%;
}

BIN
libraries/libnds32/icon.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
#error gbfs is no longer supported on nds

View File

@ -0,0 +1,384 @@
/*---------------------------------------------------------------------------------
Easy GL2D
Relminator 2010
Richard Eric M. Lope BSN RN
http://rel.betterwebber.com
A very small and simple DS rendering lib using the 3d core to render 2D stuff
---------------------------------------------------------------------------------*/
/*! \file gl2d.h
\brief A very small and simple DS rendering lib using the 3d core to render 2D stuff.
\section gl2d API
- \ref gl2d.h "Reference"
*/
#include <nds/arm9/videoGL.h>
#ifndef GL2D__H
#define GL2D__H
/*! \brief Enums selecting flipping mode.
*
* These enums are bits for flipping the sprites. <Br>
* You can <b>"|"</b> (or) GL_FLIP_V and GL_FLIP_H to flip
* both ways. <Br><Br>
* <ul>
* <li> Related functions:
* <ol>
* <li>glSprite()
* <li>glSpriteScale()
* <li>glSpriteRotate()
* <li>glSpriteScaleXY(()
* <li>glSpriteRotateScale()
* <li>glSpriteRotateScaleXY()
* <li>glSpriteOnQuad()
* </ol>
* </ul>
*/
typedef enum
{
GL_FLIP_NONE = (1 << 0), /*!< No flipping */
GL_FLIP_V = (1 << 1), /*!< Sprite is rendered vertically flipped */
GL_FLIP_H = (1 << 2), /*!< Sprite is rendered horizontally flipped */
} GL_FLIP_MODE;
/*! \brief Struct for our GL-Based Images<BR>
This is our struct to hold our image
attributes. You don't need to worry about this
if you use the texture packer. */
/*! \brief Struct for out GL-Based Images.
*
* This is our struct to hold our image attributes. <Br>
* You don't need to worry about this if you use the texture packer. <Br><Br>
* <ul>
* <li> Related functions:
* <ol>
* <li>glSprite()
* <li>glSpriteScale()
* <li>glSpriteRotate()
* <li>glSpriteScaleXY(()
* <li>glSpriteRotateScale()
* <li>glSpriteRotateScaleXY()
* <li>glSpriteOnQuad()
* </ol>
* </ul>
*/
typedef struct
{
int width; /*!< Width of the Sprite */
int height; /*!< Height of the Sprite */
int u_off; /*!< S texture offset */
int v_off; /*!< T texture offset */
int textureID; /*!< Texture handle ( used in glDeleteTextures() ) <Br>
The texture handle in VRAM (returned by glGenTextures()) <Br>
ie. This references the actual texture stored in VRAM */
} glImage;
#ifdef __cplusplus
extern "C"
{
#endif
extern int gCurrentTexture;
/******************************************************************************
Function Prototypes
******************************************************************************/
/*! \brief Initializes GL in 2D mode */
void glScreen2D( void );
/*! \brief Sets up OpenGL for 2d rendering. <Br>
Call this before drawing any of GL2D's drawing or sprite functions.
*/
void glBegin2D( void );
/*! \brief Issue this after drawing 2d so that we don't mess the matrix stack. <Br>
The compliment of glBegin2D().
*/
void glEnd2D( void );
/*! \brief Returns the active texture. Use with care. <Br>
Needed to achieve some effects since libnds 1.5.0.
*/
static inline int glGetActiveTexture()
{
return gCurrentTexture;
}
/*! \brief Set the active texture. Use with care. <Br>
Needed to achieve some effects since libnds 1.5.0.
*/
static inline void glSetActiveTexture( int TextureID )
{
glBindTexture(0, TextureID );
gCurrentTexture = TextureID;
}
/*! \brief Draws a Pixel
\param x X position of the pixel.
\param y Y position of the pixel.
\param color RGB15/ARGB16 color.
*/
void glPutPixel( int x, int y, int color );
/*! \brief Draws a Line
\param x1,y1 Top-Left coordinate of the line.
\param x2,y2 Bottom-Right coordinate of the line.
\param color RGB15/ARGB16 color.
*/
void glLine( int x1, int y1, int x2, int y2, int color );
/*! \brief Draws a Box
\param x1,y1 Top-Left coordinate of the box.
\param x2,y2 Bottom-Right coordinate of the box.
\param color RGB15/ARGB16 color.
*/
void glBox( int x1, int y1, int x2, int y2, int color );
/*! \brief Draws a Filled Box
\param x1,y1 Top-Left coordinate of the box.
\param x2,y2 Bottom-Right coordinate of the box.
\param color RGB15/ARGB16 color.
*/
void glBoxFilled( int x1, int y1, int x2, int y2, int color );
/*! \brief Draws a Filled Box in gradient colors
\param x1,y1 Top-Left coordinate of the box.
\param x2,y2 Bottom-Right coordinate of the box.
\param color1 RGB15/ARGB16 color of the Top-Left corner.
\param color2 RGB15/ARGB16 color of the Bottom-Left corner.
\param color3 RGB15/ARGB16 color of the Bottom-Right corner.
\param color4 RGB15/ARGB16 color of the Top-Right corner.
*/
void glBoxFilledGradient( int x1, int y1, int x2, int y2,
int color1, int color2, int color3, int color4
);
/*! \brief Draws a Triangle
\param x1,y1 Vertex 1 of the triangle.
\param x2,y2 Vertex 2 of the triangle.
\param x3,y3 Vertex 3 of the triangle.
\param color RGB15/ARGB16 color of the triangle.
*/
void glTriangle( int x1, int y1, int x2, int y2, int x3, int y3, int color );
/*! \brief Draws a Filled Triangle
\param x1,y1 Vertex 1 of the triangle.
\param x2,y2 Vertex 2 of the triangle.
\param x3,y3 Vertex 3 of the triangle.
\param color RGB15/ARGB16 color of the triangle.
*/
void glTriangleFilled( int x1, int y1, int x2, int y2, int x3, int y3, int color );
/*! \brief Draws a Triangle in gradient colors
\param x1,y1 Vertex 1 of the triangle.
\param x2,y2 Vertex 2 of the triangle.
\param x3,y3 Vertex 3 of the triangle.
\param color1 RGB15/ARGB16 color of the vertex 1.
\param color2 RGB15/ARGB16 color of the vertex 2.
\param color3 RGB15/ARGB16 color of the vertex 3.
*/
void glTriangleFilledGradient( int x1, int y1, int x2, int y2, int x3, int y3,
int color1, int color2, int color3
);
/*! \brief Draws a Sprite
\param x X position of the sprite.
\param y Y position of the sprite.
\param flipmode mode for flipping (see GL_FLIP_MODE enum).
\param *spr pointer to a glImage.
*/
void glSprite( int x, int y, int flipmode, const glImage *spr );
/*! \brief Draws a Scaled Sprite
\param x X position of the sprite.
\param y Y position of the sprite.
\param scale 20.12 fixed-point scale value (1 << 12 is normal).
\param flipmode mode for flipping (see GL_FLIP_MODE enum).
\param *spr pointer to a glImage.
*/
void glSpriteScale( int x, int y, s32 scale, int flipmode, const glImage *spr );
/*! \brief Draws an Axis Exclusive Scaled Sprite
\param x X position of the sprite.
\param y Y position of the sprite.
\param scaleX 20.12 fixed-point X-Axis scale value (1 << 12 is normal).
\param scaleY 20.12 fixed-point Y-Axis scale value (1 << 12 is normal).
\param flipmode mode for flipping (see GL_FLIP_MODE enum).
\param *spr pointer to a glImage.
*/
void glSpriteScaleXY( int x, int y, s32 scaleX, s32 scaleY, int flipmode, const glImage *spr );
/*! \brief Draws a Center Rotated Sprite
\param x X position of the sprite center.
\param y Y position of the sprite center.
\param angle Binary Radian Angle(-32768 to 32767) to rotate the sprite.
\param flipmode mode for flipping (see GL_FLIP_MODE enum).
\param *spr pointer to a glImage.
*/
void glSpriteRotate( int x, int y, s32 angle, int flipmode, const glImage *spr );
/*! \brief Draws a Center Rotated Scaled Sprite
\param x X position of the sprite center.
\param y Y position of the sprite center.
\param angle Binary Radian Angle(-32768 to 32767) to rotate the sprite.
\param scale 20.12 fixed-point scale value (1 << 12 is normal).
\param flipmode mode for flipping (see GL_FLIP_MODE enum).
\param *spr pointer to a glImage.
*/
void glSpriteRotateScale( int x, int y, s32 angle, s32 scale, int flipmode, const glImage *spr);
/*! \brief Draws a Center Rotated Axis-Exclusive Scaled Sprite
\param x X position of the sprite center.
\param y Y position of the sprite center.
\param angle Binary Radian Angle(-32768 to 32767) to rotate the sprite.
\param scaleX 20.12 fixed-point X-Axis scale value (1 << 12 is normal).
\param scaleY 20.12 fixed-point Y-Axis scale value (1 << 12 is normal).
\param flipmode mode for flipping (see GL_FLIP_MODE enum).
\param *spr pointer to a glImage.
*/
void glSpriteRotateScaleXY( int x, int y, s32 angle, s32 scaleX, s32 scaleY, int flipmode, const glImage *spr);
/*! \brief Draws a Horizontaly Stretched Sprite (Clean Stretching) <Br>
Useful for "Laser Effects".
\param x X position of the sprite center.
\param y Y position of the sprite center.
\param length_x The length(in pixels) to stretch the sprite.
\param *spr pointer to a glImage.
*/
void glSpriteStretchHorizontal(int x, int y, int length_x, const glImage *spr );
/*! \brief Draws a Horizontaly Stretched Sprite (Clean Stretching) <Br>
Useful for "Shrearing Effects".
\param x1,y1 First corner of the sprite.
\param x2,y2 Second corner of the sprite.
\param x3,y3 Third corner of the sprite.
\param x4,y4 Fourth corner of the sprite.
\param uoff,voff texture offsets.
\param flipmode mode for flipping (see GL_FLIP_MODE enum).
\param *spr pointer to a glImage.
*/
void glSpriteOnQuad( int x1, int y1,
int x2, int y2,
int x3, int y3,
int x4, int y4,
int uoff, int voff,
int flipmode, const glImage *spr
);
/*! \brief Initializes our spriteset with Texture Packer generated UV coordinates <Br>
Very safe and easy to use..
\param *sprite Pointer to an array of glImage.
\param numframes number of frames in a spriteset (auto-generated by Texture Packer).
\param *texcoords Texture Packer auto-generated array of UV coords.
\param type The format of the texture ( see glTexImage2d() ).
\param sizeX The horizontal size of the texture; valid sizes are enumerated in GL_TEXTURE_TYPE_ENUM ( see glTexImage2d() ).
\param sizeY The vertical size of the texture; valid sizes are enumerated in GL_TEXTURE_TYPE_ENUM ( see glTexImage2d() ).
\param param parameters for the texture ( see glTexImage2d() ).
\param pallette_width Length of the palette. Valid values are <b>4, 16, 32, 256</b> (if <b>0</b>, then palette is removed from currently bound texture).
\param *palette Pointer to the palette data to load (if NULL, then palette is removed from currently bound texture).
\param *texture Pointer to the texture data to load.
*/
int glLoadSpriteSet( glImage *sprite,
const unsigned int numframes,
const unsigned int *texcoords,
GL_TEXTURE_TYPE_ENUM type,
int sizeX,
int sizeY,
int param,
int pallette_width,
const u16 *palette,
const uint8 *texture
);
/*! \brief Initializes our Tileset (like glInitSpriteset()) but without the use of Texture Packer auto-generated files. <Br>
Can only be used when tiles in a tilset are of the same dimensions.
\param *sprite Pointer to an array of glImage.
\param tile_wid Width of each tile in the texture.
\param tile_hei Height of each tile in the texture.
\param bmp_wid Width of of the texture or tileset.
\param bmp_hei height of of the texture or tileset.
\param type The format of the texture ( see glTexImage2d() ).
\param sizeX The horizontal size of the texture; valid sizes are enumerated in GL_TEXTURE_TYPE_ENUM ( see glTexImage2d() ).
\param sizeY The vertical size of the texture; valid sizes are enumerated in GL_TEXTURE_TYPE_ENUM ( see glTexImage2d() ).
\param param parameters for the texture ( see glTexImage2d() ).
\param pallette_width Length of the palette. Valid values are <b>4, 16, 32, 256</b> (if <b>0</b>, then palette is removed from currently bound texture).
\param *palette Pointer to the palette data to load (if NULL, then palette is removed from currently bound texture).
\param *texture Pointer to the texture data to load.
*/
int glLoadTileSet( glImage *sprite,
int tile_wid,
int tile_hei,
int bmp_wid,
int bmp_hei,
GL_TEXTURE_TYPE_ENUM type,
int sizeX,
int sizeY,
int param,
int pallette_width,
const u16 *palette,
const uint8 *texture
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,308 @@
/*---------------------------------------------------------------------------------
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.
---------------------------------------------------------------------------------*/
/*! \file nds.h
\brief the master include file for nds applications.
*/
/*!
\mainpage Libnds Documentation
\section intro Introduction
Welcome to the libnds reference documentation.
\section video_2D_api 2D engine API
- \ref video.h "General video"
- \ref background.h "2D Background Layers"
- \ref sprite.h "2D Sprites"
\section video_3D_api 3D engine API
- \ref videoGL.h "OpenGL (ish)"
- \ref boxtest.h "Box Test"
- \ref postest.h "Position test"
- \ref gl2d.h "Simple DS 2D rendering using the 3d core"
\section audio_api Audio API
- \ref sound.h "Simple Sound Engine"
- <a href="https://maxmod.devkitpro.org/ref">Maxmod</a>
\section math_api Math
- \ref math.h "Hardware Assisted Math"
- \ref trig_lut.h "Fixed point trigenometry functions"
\section memory_api Memory
- \ref memory.h "General memory definitions"
- \ref memory.h "nds and gba header structure"
- \ref dma.h "Direct Memory Access"
\section system_api System
- \ref ndstypes.h "Custom DS types"
- \ref system.h "Hardware Initilization"
- \ref bios.h "Bios"
- \ref cache.h "ARM 9 Cache"
- \ref interrupts.h "Interrupts"
- \ref fifocommon.h "Fifo"
- \ref timers.h "Timers"
\section user_io_api User Input/ouput
- \ref arm9/input.h "Keypad and Touch pad"
- \ref keyboard.h "Keyboard"
- \ref console.h "Console and Debug Printing"
\section utility_api Utility
- \ref decompress.h "Decompression"
- \ref image.h "Image Manipulation"
- \ref pcx.h "PCX file loader"
- \ref dynamicArray.h "General Purpose dynamic array implementation"
- \ref linkedlist.h "General purpose linked list implementation"
\section peripheral_api Custom Peripherals
- \ref rumble.h "Rumble Pack"
- \ref ndsmotion.h "DS Motion Pack"
- \ref piano.h "DS Easy Piano Controller"
\section debug_api Debugging
- \ref console.h "Debug via printf to DS screen or NO$GBA"
- \ref debug.h "Send message to NO$GBA"
- \ref sassert.h "simple assert"
\section external_links Usefull links
- <a href="http://www.devkitpro.org/">devkitPro</a>
- <a href="https://github.com/devkitPro/">devkitPro github</a>
\section games Example Games
- <a href="http://rel.phatcode.net/index.php?action=contents&item=Bubble_Fight_EX_DS">Bubble Fight EX</a>
- <a href="http://rel.phatcode.net/index.php?action=contents&item=Space-Impakto-DS">Space Impakto DS</a>
*/
//adding the example page.
/*!
<!-- EXAMPLES -->
<!-- hello world -->
\example hello_world/source/main.cpp
<!-- backgrounds -->
\example Graphics/Backgrounds/all_in_one/source/main.cpp
\example Graphics/Backgrounds/all_in_one/source/advanced.cpp
\example Graphics/Backgrounds/all_in_one/source/basic.cpp
\example Graphics/Backgrounds/all_in_one/source/scrolling.cpp
\example Graphics/Backgrounds/all_in_one/source/handmade.cpp
\example Graphics/Backgrounds/16bit_color_bmp/source/template.cpp
\example Graphics/Backgrounds/256_color_bmp/source/main.cpp
\example Graphics/Backgrounds/Double_Buffer/source/main.cpp
\example Graphics/Backgrounds/rotation/source/main.cpp
<!-- sprites -->
\example Graphics/Sprites/allocation_test/source/main.c
\example Graphics/Sprites/animate_simple/source/template.c
\example Graphics/Sprites/bitmap_sprites/source/main.cpp
\example Graphics/Sprites/fire_and_sprites/source/main.cpp
\example Graphics/Sprites/simple/source/template.c
\example Graphics/Sprites/sprite_extended_palettes/source/template.c
\example Graphics/Sprites/sprite_rotate/source/template.c
<!-- Graphics Effects -->
\example Graphics/Effects/windows/source/template.c
<!-- keyboard -->
\example input/keyboard/keyboard_stdin/source/keymain.c
\example input/keyboard/keyboard_async/source/template.c
<!-- touchpad -->
\example input/Touch_Pad/touch_area/source/template.c
\example input/Touch_Pad/touch_look/source/main.cpp
\example input/Touch_Pad/touch_test/source/main.c
<!-- 3D -->
\example Graphics/3D/nehe/lesson01/source/nehe1.cpp
\example Graphics/3D/nehe/lesson02/source/nehe2.cpp
\example Graphics/3D/nehe/lesson03/source/nehe3.cpp
\example Graphics/3D/nehe/lesson04/source/nehe4.cpp
\example Graphics/3D/nehe/lesson05/source/nehe5.cpp
\example Graphics/3D/nehe/lesson06/source/nehe6.cpp
\example Graphics/3D/nehe/lesson07/source/nehe7.cpp
\example Graphics/3D/nehe/lesson08/source/nehe8.cpp
\example Graphics/3D/nehe/lesson09/source/nehe9.cpp
\example Graphics/3D/nehe/lesson10/source/nehe10.cpp
\example Graphics/3D/nehe/lesson10b/source/nehe10b.cpp
\example Graphics/3D/nehe/lesson11/source/nehe11.cpp
\example Graphics/3D/3D_Both_Screens/source/template.c
\example Graphics/3D/Display_List/source/main.cpp
\example Graphics/3D/Display_List_2/source/main.cpp
\example Graphics/3D/Env_Mapping/source/main.cpp
\example Graphics/3D/BoxTest/source/main.cpp
\example Graphics/3D/Ortho/source/main.cpp
\example Graphics/3D/Paletted_Cube/source/main.cpp
\example Graphics/3D/Picking/source/main.cpp
\example Graphics/3D/Simple_Quad/source/main.cpp
\example Graphics/3D/Simple_Tri/source/main.cpp
\example Graphics/3D/Textured_Cube/source/main.cpp
\example Graphics/3D/Textured_Quad/source/main.cpp
\example Graphics/3D/Toon_Shading/source/main.cpp
<!-- RTC -->
\example time/RealTimeClock/source/main.c
<!-- Timers -->
\example time/stopwatch/source/main.c
\example time/timercallback/source/main.c
<!-- capture -->
\example capture/ScreenShot/source/main.cpp
\example capture/ScreenShot/source/screenshot.cpp
<!-- sound api -->
\example audio/micrecord/source/micrecord.c
\example audio/maxmod/audio_modes/source/main.c
\example audio/maxmod/basic_sound/source/MaxModExample.c
\example audio/maxmod/reverb/source/main.c
\example audio/maxmod/song_events_example/source/template.c
\example audio/maxmod/song_events_example2/source/template.c
\example audio/maxmod/streaming/source/main.c
<!-- debugging -->
\example debugging/exceptionTest/source/exceptionTest.c
<!-- printing -->
\example Graphics/Printing/ansi_console/source/main.c
\example Graphics/Printing/console_windows/source/main.c
\example Graphics/Printing/custom_font/source/main.c
\example Graphics/Printing/print_both_screens/source/template.c
\example Graphics/Printing/rotscale_text/source/main.c
<!-- filesystem -->
\example filesystem/libfat/libfatdir/source/directory.c
\example filesystem/nitrofs/nitrodir/source/directory.c
<!-- dswifi -->
\example dswifi/ap_search/source/template.c
\example dswifi/autoconnect/source/autoconnect.c
\example dswifi/httpget/source/httpget.c
<!-- card -->
\example card/eeprom/source/main.cpp
<!-- ds_motion -->
\example ds_motion/source/main.c
*/
#ifndef NDS_INCLUDE
#define NDS_INCLUDE
#ifndef ARM7
#ifndef ARM9
#error Either ARM7 or ARM9 must be defined
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "nds/libversion.h"
#include "nds/ndstypes.h"
#include "nds/bios.h"
#include "nds/card.h"
#include "nds/debug.h"
#include "nds/dma.h"
#include "nds/interrupts.h"
#include "nds/ipc.h"
#include "nds/memory.h"
#include "nds/system.h"
#include "nds/timers.h"
#include "nds/fifocommon.h"
#include "nds/touch.h"
#include "nds/input.h"
#include "nds/sha1.h"
//---------------------------------------------------------------------------------
#ifdef ARM9
//---------------------------------------------------------------------------------
#include "nds/arm9/dynamicArray.h"
#include "nds/arm9/linkedlist.h"
#include "nds/arm9/background.h"
#include "nds/arm9/boxtest.h"
#include "nds/arm9/cache.h"
#include "nds/arm9/console.h"
#include "nds/arm9/decompress.h"
#include "nds/arm9/exceptions.h"
#include "nds/arm9/guitarGrip.h"
#include "nds/arm9/image.h"
#include "nds/arm9/input.h"
#include "nds/arm9/keyboard.h"
#include "nds/arm9/math.h"
#include "nds/arm9/paddle.h"
#include "nds/arm9/pcx.h"
#include "nds/arm9/piano.h"
#include "nds/arm9/rumble.h"
#include "nds/arm9/sassert.h"
#include "nds/arm9/sound.h"
#include "nds/arm9/sprite.h"
#include "nds/arm9/window.h"
#include "nds/arm9/trig_lut.h"
#include "nds/arm9/video.h"
#include "nds/arm9/videoGL.h"
#include "nds/arm9/nand.h"
//---------------------------------------------------------------------------------
#endif // #ifdef ARM9
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
#ifdef ARM7
//---------------------------------------------------------------------------------
#include "nds/arm7/aes.h"
#include "nds/arm7/audio.h"
#include "nds/arm7/clock.h"
#include "nds/arm7/codec.h"
#include "nds/arm7/input.h"
#include "nds/arm7/i2c.h"
#include "nds/arm7/sdmmc.h"
#include "nds/arm7/serial.h"
#include "nds/arm7/touch.h"
//---------------------------------------------------------------------------------
#endif // #ifdef ARM7
//---------------------------------------------------------------------------------
#ifdef __cplusplus
}
#endif
#endif // NDS_INCLUDE

View File

@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------------
ARM7 AES
Copyright (C) 2017
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.
---------------------------------------------------------------------------------*/
#ifndef AES_ARM7_INCLUDE
#define AES_ARM7_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#include <nds/ndstypes.h>
typedef struct aes_keyslot {
vu8 normalkey[16];
vu8 key_x[16];
vu8 key_y[16];
} aes_keyslot_t;
#define REG_AES_CNT (*(vu32*)0x04004400)
#define AES_WRFIFO_FLUSH (1<<10)
#define AES_RDFIFO_FLUSH (1<<11)
#define AES_CNT_DMA_WRITE_SIZE(size) ((size & 3) << 12)
#define AES_CNT_DMA_READ_SIZE(size) ((size & 3) << 14)
#define AES_CNT_CCM_SIZE(size) ((size & 3) << 16)
#define AES_CCM_PASSTRHOUGH (1<<19)
#define AES_CNT_KEY_APPLY (1<<24)
#define AES_CNT_KEYSLOT(slot) ((slot & 3) << 26)
#define AES_CNT_MODE(mode) ((mode & 3) << 28)
#define AES_CNT_IRQ (1<<30)
#define AES_CNT_ENABLE (1<<31)
#define REG_AES_BLKCNT (*(vu32*)0x4004404)
#define REG_AES_WRFIFO (*(vu32*)0x4004408)
#define REG_AES_RDFIFO (*(vu32*)0x400440c)
#define REG_AES_IV ((vu8*)0x4004420)
#define REG_AES_MAC ((vu8*)0x4004430)
#define AES_KEYSLOT ((aes_keyslot_t *)0x4004440)
#define AES_KEYSLOT0 (*(aes_keyslot_t *)0x4004440)
#define AES_KEYSLOT1 (*(aes_keyslot_t *)0x4004470)
#define AES_KEYSLOT2 (*(aes_keyslot_t *)0x40044A0)
#define AES_KEYSLOT3 (*(aes_keyslot_t *)0x40044D0)
#ifdef __cplusplus
}
#endif
#endif // AES_ARM7_INCLUDE

View File

@ -0,0 +1,173 @@
/*---------------------------------------------------------------------------------
ARM7 audio control
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.
---------------------------------------------------------------------------------*/
#ifndef AUDIO_ARM7_INCLUDE
#define AUDIO_ARM7_INCLUDE
//---------------------------------------------------------------------------------
// Sound (ARM7 only)
//---------------------------------------------------------------------------------
#ifndef ARM7
#error Audio is only available on the ARM7
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <nds/arm7/serial.h>
#include <nds/system.h>
#define SOUND_VOL(n) (n)
#define SOUND_FREQ(n) ((-0x1000000 / (n)))
#define SOUND_ENABLE BIT(15)
#define SOUND_REPEAT BIT(27)
#define SOUND_ONE_SHOT BIT(28)
#define SOUND_FORMAT_16BIT (1<<29)
#define SOUND_FORMAT_8BIT (0<<29)
#define SOUND_FORMAT_PSG (3<<29)
#define SOUND_FORMAT_ADPCM (2<<29)
#define SOUND_PAN(n) ((n) << 16)
#define SCHANNEL_ENABLE BIT(31)
//---------------------------------------------------------------------------------
// registers
//---------------------------------------------------------------------------------
#define REG_MASTER_VOLUME (*(vu8*)0x4000500)
#define REG_SOUNDCNT (*(vu16*)0x4000500)
#define REG_SOUNDBIAS (*(vu32*)0x4000504)
#define SCHANNEL_CR(n) (*(vu32*)(0x04000400 + ((n)<<4)))
#define SCHANNEL_VOL(n) (*(vu8*)(0x04000400 + ((n)<<4)))
#define SCHANNEL_PAN(n) (*(vu8*)(0x04000402 + ((n)<<4)))
#define SCHANNEL_SOURCE(n) (*(vu32*)(0x04000404 + ((n)<<4)))
#define SCHANNEL_TIMER(n) (*(vu16*)(0x04000408 + ((n)<<4)))
#define SCHANNEL_REPEAT_POINT(n) (*(vu16*)(0x0400040A + ((n)<<4)))
#define SCHANNEL_LENGTH(n) (*(vu32*)(0x0400040C + ((n)<<4)))
//---------------------------------------------------------------------------------
// Sound Capture Registers
//---------------------------------------------------------------------------------
#define REG_SNDCAP0CNT (*(vu8*)0x04000508)
#define REG_SNDCAP1CNT (*(vu8*)0x04000509)
#define REG_SNDCAP0DAD (*(vu32*)0x04000510)
#define REG_SNDCAP0LEN (*(vu16*)0x04000514)
#define REG_SNDCAP1DAD (*(vu32*)0x04000518)
#define REG_SNDCAP1LEN (*(vu16*)0x0400051C)
typedef void (*MIC_BUF_SWAP_CB)(u8* completedBuffer, int length);
//---------------------------------------------------------------------------------
// DSi Registers
//---------------------------------------------------------------------------------
#define REG_SNDEXTCNT (*(vu16*)0x04004700)
#define REG_MICCNT (*(vu16*)0x04004600)
#define REG_MICDATA (*(vu32*)0x04004604)
#define SNDEXTCNT_RATIO(n) ((n)&0xF)
#define SNDEXTCNT_FREQ_32KHZ (0<<13) // output freq 32.73kHz
#define SNDEXTCNT_FREQ_47KHZ (1<<13) // output freq 47.61kHz
#define SNDEXTCNT_MUTE BIT(14)
#define SNDEXTCNT_ENABLE BIT(15)
#define MICCNT_FORMAT(n) ((n)&3) // unknown, always set to '2'
#define MICCNT_FREQ_DIV(n) (((n)&3)<<2) // F/(n+1) where F is SNDEXTCNT output freq
#define MICCNT_EMPTY BIT(8)
#define MICCNT_NOT_EMPTY BIT(9)
#define MICCNT_MORE_DATA BIT(10)
#define MICCNT_OVERRUN BIT(11)
#define MICCNT_CLEAR_FIFO BIT(12)
#define MICCNT_ENABLE_IRQ BIT(13)
#define MICCNT_ENABLE_IRQ2 BIT(14)
#define MICCNT_ENABLE BIT(15)
/*---------------------------------------------------------------------------------
microphone code based on neimod's microphone example.
See: http://neimod.com/dstek/
Chris Double (chris.double@double.co.nz)
http://www.double.co.nz/nintendo_ds
---------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------
Read a byte from the microphone
---------------------------------------------------------------------------------*/
u8 micReadData8();
u16 micReadData12();
/*---------------------------------------------------------------------------------
Fill the buffer with data from the microphone. The buffer will be
signed sound data at 16kHz. Once the length of the buffer is
reached, no more data will be stored. Uses ARM7 timer 0.
---------------------------------------------------------------------------------*/
void micStartRecording(u8* buffer, int length, int freq, int timer, bool eightBitSample, MIC_BUF_SWAP_CB bufferSwapCallback);
/*---------------------------------------------------------------------------------
Stop recording data, and return the length of data recorded.
---------------------------------------------------------------------------------*/
int micStopRecording(void);
/* This must be called during IRQ_TIMER0 */
void micTimerHandler(void);
void micSetAmp(u8 control, u8 gain);
//---------------------------------------------------------------------------------
// Turn the microphone on
//---------------------------------------------------------------------------------
static inline void micOn(void) {
//---------------------------------------------------------------------------------
micSetAmp(PM_AMP_ON, PM_GAIN_160);
}
//---------------------------------------------------------------------------------
// Turn the microphone off
//---------------------------------------------------------------------------------
static inline void micOff(void) {
//---------------------------------------------------------------------------------
micSetAmp(PM_AMP_OFF, 0);
}
void installSoundFIFO(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------------
ARM7 realtime clock
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.
---------------------------------------------------------------------------------*/
#ifndef ARM7_CLOCK_INCLUDE
#define ARM7_CLOCK_INCLUDE
#ifndef ARM7
#error The clock is only available on the ARM7
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <nds/arm7/serial.h>
// RTC registers
#define WRITE_STATUS_REG1 0x60
#define READ_STATUS_REG1 0x61
/*
Status Register 1
0 W Reset (0=Normal, 1=Reset)
1 R/W 12/24 hour mode (0=12 hour, 1=24 hour)
2-3 R/W General purpose bits
4 R Interrupt 1 Flag (1=Yes) ;auto-cleared on read
5 R Interrupt 2 Flag (1=Yes) ;auto-cleared on read
6 R Power Low Flag (0=Normal, 1=Power is/was low) ;auto-cleared on read
7 R Power Off Flag (0=Normal, 1=Power was off) ;auto-cleared on read
Power off indicates that the battery was removed or fully discharged,
all registers are reset to 00h (or 01h), and must be re-initialized.
*/
#define STATUS_POC (1<<7) // read-only, cleared by reading (1 if just powered on)
#define STATUS_BLD (1<<6) // read-only, cleared by reading (1 if power dropped below the safety threshold)
#define STATUS_INT2 (1<<5) // read-only, INT2 has occured
#define STATUS_INT1 (1<<4) // read-only, INT1 has occured
#define STATUS_SC1 (1<<3) // R/W scratch bit
#define STATUS_SC0 (1<<2) // R/W scratch bit
#define STATUS_24HRS (1<<1) // 24 hour mode when 1, 12 hour mode when 0
#define STATUS_RESET (1<<0) // write-only, reset when 1 written
#define WRITE_STATUS_REG2 0x62
#define READ_STATUS_REG2 0x63
/*
Status Register 2
0-3 R/W INT1 Mode/Enable
0000b Disable
0x01b Selected Frequency steady interrupt
0x10b Per-minute edge interrupt
0011b Per-minute steady interrupt 1 (duty 30.0 secomds)
0100b Alarm 1 interrupt
0111b Per-minute steady interrupt 2 (duty 0.0079 secomds)
1xxxb 32kHz output
4-5 R/W General purpose bits
6 R/W INT2 Enable
0b Disable
1b Alarm 2 interrupt
7 R/W Test Mode (0=Normal, 1=Test, don't use) (cleared on Reset)
*/
#define STATUS_TEST (1<<7) //
#define STATUS_INT2AE (1<<6) //
#define STATUS_SC3 (1<<5) // R/W scratch bit
#define STATUS_SC2 (1<<4) // R/W scratch bit
#define STATUS_32kE (1<<3) // Interrupt mode bits
#define STATUS_INT1AE (1<<2) //
#define STATUS_INT1ME (1<<1) //
#define STATUS_INT1FE (1<<0) //
// full 7 bytes for time and date
#define WRITE_TIME_AND_DATE 0x64
#define READ_TIME_AND_DATE 0x65
// last 3 bytes of current time
#define WRITE_TIME 0x66
#define READ_TIME 0x67
#define WRITE_INT_REG1 0x68
#define READ_INT_REG1 0x69
#define WRITE_INT_REG2 0x6A
#define READ_INT_REG2 0x6B
#define READ_CLOCK_ADJUST_REG 0x6C
#define WRITE_CLOCK_ADJUST_REG 0x6D
// clock-adjustment register
#define READ_FREE_REG 0x6E
#define WRITE_FREE_REG 0x6F
void rtcReset(void);
void rtcTransaction(uint8 * command, uint32 commandLength, uint8 * result, uint32 resultLength);
void rtcGetTime(uint8 * time);
void rtcSetTime(uint8 * time);
void rtcGetTimeAndDate(uint8 * time);
void rtcSetTimeAndDate(uint8 * time);
void rtcGetData(uint8 * data, uint32 size);
void BCDToInteger(uint8 * data, uint32 length);
void integerToBCD(uint8 * data, uint32 length);
void initClockIRQ();
void resyncClock();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------------
DSi "codec" Touchscreen/Sound Controller control for ARM7
Copyright (C) 2017
fincs
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.
---------------------------------------------------------------------------------*/
#ifndef ARM7_CODEC_INCLUDE
#define ARM7_CODEC_INCLUDE
//---------------------------------------------------------------------------------
#ifndef ARM7
#error DSi TSC is only available on the ARM7
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <nds/arm7/serial.h>
#include <nds/memory.h>
#include <nds/system.h>
#include <nds/touch.h>
static inline bool cdcIsAvailable(void) {
return isDSiMode() && (__DSiHeader->appflags & 0x01);
}
enum cdcBanks {
CDC_CONTROL = 0x00, // Chip control
CDC_SOUND = 0x01, // ADC/DAC control
CDC_TOUCHCNT = 0x03, // TSC control
CDC_TOUCHDATA = 0xFC, // TSC data buffer
};
// Direct register functions
u8 cdcReadReg(u8 bank, u8 reg);
void cdcReadRegArray(u8 bank, u8 reg, void* data, u8 size);
void cdcWriteReg(u8 bank, u8 reg, u8 value);
void cdcWriteRegMask(u8 bank, u8 reg, u8 mask, u8 value);
void cdcWriteRegArray(u8 bank, u8 reg, const void* data, u8 size);
// Touchscreen functions
void cdcTouchInit(void);
bool cdcTouchPenDown(void);
bool cdcTouchRead(touchPosition* pos);
#ifdef __cplusplus
}
#endif
//---------------------------------------------------------------------------------
#endif // ARM7_CODEC_INCLUDE
//---------------------------------------------------------------------------------

View File

@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------------
I2C control for the ARM7
Copyright (C) 2011
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.
---------------------------------------------------------------------------------*/
#ifndef I2C_ARM7_INCLUDE
#define I2C_ARM7_INCLUDE
#ifndef ARM7
#error i2c header is for ARM7 only
#endif
#include <nds/ndstypes.h>
#define REG_I2CDATA (*(vu8 *)0x4004500)
#define REG_I2CCNT (*(vu8 *)0x4004501)
static inline void i2cWaitBusy() {
while(REG_I2CCNT & 0x80);
}
enum i2cDevices {
I2C_CAM0 = 0x7A,
I2C_CAM1 = 0x78,
I2C_UNK1 = 0xA0,
I2C_UNK2 = 0xE0,
I2C_PM = 0x4A,
I2C_UNK3 = 0x40,
I2C_GPIO = 0x90
};
// Registers for Power Management (I2C_PM)
#define I2CREGPM_BATUNK 0x00
#define I2CREGPM_PWRIF 0x10
#define I2CREGPM_PWRCNT 0x11
#define I2CREGPM_MMCPWR 0x12
#define I2CREGPM_BATTERY 0x20
#define I2CREGPM_CAMLED 0x31
#define I2CREGPM_VOL 0x40
#define I2CREGPM_RESETFLAG 0x70
u8 i2cWriteRegister(u8 device, u8 reg, u8 data);
u8 i2cReadRegister(u8 device, u8 reg);
#endif // I2C_ARM7_INCLUDE

View File

@ -0,0 +1,14 @@
#ifndef __INPUT_H__
#define __INPUT_H__
#ifdef __cplusplus
extern "C" {
#endif
void inputGetAndSend(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,194 @@
#ifndef __SDMMC_H__
#define __SDMMC_H__
#include <nds/ndstypes.h>
#define DATA32_SUPPORT
#define SDMMC_BASE 0x04004800
#define REG_SDCMD 0x00
#define REG_SDPORTSEL 0x02
#define REG_SDCMDARG 0x04
#define REG_SDCMDARG0 0x04
#define REG_SDCMDARG1 0x06
#define REG_SDSTOP 0x08
#define REG_SDRESP 0x0c
#define REG_SDBLKCOUNT 0x0a
#define REG_SDRESP0 0x0c
#define REG_SDRESP1 0x0e
#define REG_SDRESP2 0x10
#define REG_SDRESP3 0x12
#define REG_SDRESP4 0x14
#define REG_SDRESP5 0x16
#define REG_SDRESP6 0x18
#define REG_SDRESP7 0x1a
#define REG_SDSTATUS0 0x1c
#define REG_SDSTATUS1 0x1e
#define REG_SDIRMASK0 0x20
#define REG_SDIRMASK1 0x22
#define REG_SDCLKCTL 0x24
#define REG_SDBLKLEN 0x26
#define REG_SDOPT 0x28
#define REG_SDFIFO 0x30
#define REG_SDDATACTL 0xd8
#define REG_SDRESET 0xe0
#define REG_SDPROTECTED 0xf6 //bit 0 determines if sd is protected or not?
#define REG_SDDATACTL32 0x100
#define REG_SDBLKLEN32 0x104
#define REG_SDBLKCOUNT32 0x108
#define REG_SDFIFO32 0x10C
#define REG_CLK_AND_WAIT_CTL 0x138
#define REG_RESET_SDIO 0x1e0
//The below defines are from linux kernel drivers/mmc tmio_mmc.h.
/* Definitions for values the CTRL_STATUS register can take. */
#define TMIO_STAT0_CMDRESPEND 0x0001
#define TMIO_STAT0_DATAEND 0x0004
#define TMIO_STAT0_CARD_REMOVE 0x0008
#define TMIO_STAT0_CARD_INSERT 0x0010
#define TMIO_STAT0_SIGSTATE 0x0020
#define TMIO_STAT0_WRPROTECT 0x0080
#define TMIO_STAT0_CARD_REMOVE_A 0x0100
#define TMIO_STAT0_CARD_INSERT_A 0x0200
#define TMIO_STAT0_SIGSTATE_A 0x0400
#define TMIO_STAT1_CMD_IDX_ERR 0x0001
#define TMIO_STAT1_CRCFAIL 0x0002
#define TMIO_STAT1_STOPBIT_ERR 0x0004
#define TMIO_STAT1_DATATIMEOUT 0x0008
#define TMIO_STAT1_RXOVERFLOW 0x0010
#define TMIO_STAT1_TXUNDERRUN 0x0020
#define TMIO_STAT1_CMDTIMEOUT 0x0040
#define TMIO_STAT1_RXRDY 0x0100
#define TMIO_STAT1_TXRQ 0x0200
#define TMIO_STAT1_ILL_FUNC 0x2000
#define TMIO_STAT1_CMD_BUSY 0x4000
#define TMIO_STAT1_ILL_ACCESS 0x8000
#define SDMC_NORMAL 0x00000000
#define SDMC_ERR_COMMAND 0x00000001
#define SDMC_ERR_CRC 0x00000002
#define SDMC_ERR_END 0x00000004
#define SDMC_ERR_TIMEOUT 0x00000008
#define SDMC_ERR_FIFO_OVF 0x00000010
#define SDMC_ERR_FIFO_UDF 0x00000020
#define SDMC_ERR_WP 0x00000040
#define SDMC_ERR_ABORT 0x00000080
#define SDMC_ERR_FPGA_TIMEOUT 0x00000100
#define SDMC_ERR_PARAM 0x00000200
#define SDMC_ERR_R1_STATUS 0x00000800
#define SDMC_ERR_NUM_WR_SECTORS 0x00001000
#define SDMC_ERR_RESET 0x00002000
#define SDMC_ERR_ILA 0x00004000
#define SDMC_ERR_INFO_DETECT 0x00008000
#define SDMC_STAT_ERR_UNKNOWN 0x00080000
#define SDMC_STAT_ERR_CC 0x00100000
#define SDMC_STAT_ERR_ECC_FAILED 0x00200000
#define SDMC_STAT_ERR_CRC 0x00800000
#define SDMC_STAT_ERR_OTHER 0xf9c70008
#define TMIO_MASK_ALL 0x837f031d
#define TMIO_MASK_GW (TMIO_STAT1_ILL_ACCESS | TMIO_STAT1_CMDTIMEOUT | TMIO_STAT1_TXUNDERRUN | TMIO_STAT1_RXOVERFLOW | \
TMIO_STAT1_DATATIMEOUT | TMIO_STAT1_STOPBIT_ERR | TMIO_STAT1_CRCFAIL | TMIO_STAT1_CMD_IDX_ERR)
#define TMIO_MASK_READOP (TMIO_STAT1_RXRDY | TMIO_STAT1_DATAEND)
#define TMIO_MASK_WRITEOP (TMIO_STAT1_TXRQ | TMIO_STAT1_DATAEND)
typedef struct mmcdevice {
u8* data;
u32 size;
u32 error;
u16 stat0;
u16 stat1;
u32 ret[4];
u32 initarg;
u32 isSDHC;
u32 clk;
u32 SDOPT;
u32 devicenumber;
u32 total_size; //size in sectors of the device
u32 res;
} mmcdevice;
enum {
MMC_DEVICE_SDCARD,
MMC_DEVICE_NAND,
};
void sdmmc_controller_init(bool force_init);
void sdmmc_initirq();
int sdmmc_cardinserted();
int sdmmc_sdcard_init();
int sdmmc_nand_init();
void sdmmc_get_cid(int devicenumber, u32 *cid);
static inline void sdmmc_nand_cid( u32 *cid) {
sdmmc_get_cid(MMC_DEVICE_NAND,cid);
}
static inline void sdmmc_sdcard_cid( u32 *cid) {
sdmmc_get_cid(MMC_DEVICE_SDCARD,cid);
}
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, void *out);
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, void *in);
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, void *out);
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, void *in);
extern u32 sdmmc_cid[];
extern int sdmmc_curdevice;
//---------------------------------------------------------------------------------
static inline u16 sdmmc_read16(u16 reg) {
//---------------------------------------------------------------------------------
return *(vu16*)(SDMMC_BASE + reg);
}
//---------------------------------------------------------------------------------
static inline void sdmmc_write16(u16 reg, u16 val) {
//---------------------------------------------------------------------------------
*(vu16*)(SDMMC_BASE + reg) = val;
}
//---------------------------------------------------------------------------------
static inline u32 sdmmc_read32(u16 reg) {
//---------------------------------------------------------------------------------
return *(vu32*)(SDMMC_BASE + reg);
}
//---------------------------------------------------------------------------------
static inline void sdmmc_write32(u16 reg, u32 val) {
//---------------------------------------------------------------------------------
*(vu32*)(SDMMC_BASE + reg) = val;
}
//---------------------------------------------------------------------------------
static inline void sdmmc_mask16(u16 reg, u16 clear, u16 set) {
//---------------------------------------------------------------------------------
u16 val = sdmmc_read16(reg);
val &= ~clear;
val |= set;
sdmmc_write16(reg, val);
}
//---------------------------------------------------------------------------------
static inline void setckl(u32 data) {
//---------------------------------------------------------------------------------
sdmmc_mask16(REG_SDCLKCTL, 0x100, 0);
sdmmc_mask16(REG_SDCLKCTL, 0x2FF, data & 0x2FF);
sdmmc_mask16(REG_SDCLKCTL, 0x0, 0x100);
}
#endif

View File

@ -0,0 +1,120 @@
/*---------------------------------------------------------------------------------
SPI control for the ARM7
Copyright (C) 2005 - 2011
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.
---------------------------------------------------------------------------------*/
#ifndef SERIAL_ARM7_INCLUDE
#define SERIAL_ARM7_INCLUDE
#ifndef ARM7
#error Serial header is for ARM7 only
#endif
#include <nds/bios.h>
// 'Networking'
#define REG_RCNT (*(vu16*)0x04000134)
#define REG_KEYXY (*(vu16*)0x04000136)
#define RTC_CR (*(vu16*)0x04000138)
#define RTC_CR8 (*( vu8*)0x04000138)
#define REG_SIOCNT (*(vu16*)0x04000128)
#define SIO_DATA8 (*(vu8*)0x0400012A)
#define SIO_DATA32 (*(vu32*)0x04000120)
// Fixme: Does the hardware still support 16 bit comms mode?
// BIOS makes use of 32 bit mode, so some regs still exist
#define SIO_MULTI_0 (*(vu16*)0x04000120)
#define SIO_MULTI_1 (*(vu16*)0x04000122)
#define SIO_MULTI_2 (*(vu16*)0x04000124)
#define SIO_MULTI_3 (*(vu16*)0x04000126)
#define SIO_MULTI_SEND (*(vu16*)0x0400012A)
// SPI chain registers
#define REG_SPICNT (*(vu16*)0x040001C0)
#define REG_SPIDATA (*(vu16*)0x040001C2)
#define SPI_ENABLE BIT(15)
#define SPI_IRQ BIT(14)
#define SPI_BUSY BIT(7)
// meh
#define SPI_BAUD_4MHz 0
#define SPI_BAUD_2MHz 1
#define SPI_BAUD_1MHz 2
#define SPI_BAUD_512KHz 3
// Pick the SPI transfer length
#define SPI_BYTE_MODE (0<<10)
#define SPI_HWORD_MODE (1<<10)
// Pick the SPI device
#define SPI_DEVICE_POWER (0 << 8)
#define SPI_DEVICE_FIRMWARE (1 << 8)
#define SPI_DEVICE_NVRAM (1 << 8)
#define SPI_DEVICE_TOUCH (2 << 8)
#define SPI_DEVICE_MICROPHONE (2 << 8)
// When used, the /CS line will stay low after the transfer ends
// i.e. when we're part of a continuous transfer
#define SPI_CONTINUOUS BIT(11)
// Fixme: does this stuff really belong in serial.h?
// Fixme: does this stuff really belong in serial.h?
// Firmware commands
#define FIRMWARE_WREN 0x06
#define FIRMWARE_WRDI 0x04
#define FIRMWARE_RDID 0x9F
#define FIRMWARE_RDSR 0x05
#define FIRMWARE_READ 0x03
#define FIRMWARE_PW 0x0A
#define FIRMWARE_PP 0x02
#define FIRMWARE_FAST 0x0B
#define FIRMWARE_PE 0xDB
#define FIRMWARE_SE 0xD8
#define FIRMWARE_DP 0xB9
#define FIRMWARE_RDP 0xAB
static inline
void SerialWaitBusy() {
while (REG_SPICNT & SPI_BUSY);
}
// Read the firmware
void readFirmware(u32 address, void * destination, u32 size);
#endif

View File

@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------------
Microphone 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.
---------------------------------------------------------------------------------*/
#ifndef ARM7_TOUCH_INCLUDE
#define ARM7_TOUCH_INCLUDE
//---------------------------------------------------------------------------------
#ifndef ARM7
#error Touch screen is only available on the ARM7
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <nds/arm7/serial.h>
#include <nds/touch.h>
#define SCREEN_WIDTH 256
#define SCREEN_HEIGHT 192
#define TSC_MEASURE_TEMP1 0x84
#define TSC_MEASURE_Y 0x90
#define TSC_MEASURE_BATTERY 0xA4
#define TSC_MEASURE_Z1 0xB4
#define TSC_MEASURE_Z2 0xC4
#define TSC_MEASURE_X 0xD0
#define TSC_MEASURE_AUX 0xE4
#define TSC_MEASURE_TEMP2 0xF4
void touchInit();
void touchReadXY(touchPosition *touchPos);
uint16 touchRead(uint32 command);
uint32 touchReadTemperature(int * t1, int * t2);
bool touchPenDown();
#ifdef __cplusplus
}
#endif
//---------------------------------------------------------------------------------
#endif // ARM7_TOUCH_INCLUDE
//---------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------------
BoxTest.h -- Code for performing hardware box test against viewing frustrum
Copyright (C) 2005
Michael Noland (joat)
Jason Rogers (dovoto)
Dave Murphy (WinterMute)
Mike Parks (BigRedPimp)
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.
---------------------------------------------------------------------------------*/
#ifndef BOX_TEST_INCLUDE
#define BOX_TEST_INCLUDE
#include "nds/arm9/video.h"
#include "nds/arm9/videoGL.h"
/*! \file boxtest.h
\brief Box Test Functions.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*! \brief Performs a test to determine if the provided box is in the view frustrum.
\param x (x, y, z) point of a vertex on the box
\param y (x, y, z) point of a vertex on the box
\param z (x, y, z) point of a vertex on the box
\param height (height, width, depth) describe the size of the box referenced from (x, y, z)
\param width (height, width, depth) describe the size of the box referenced from (x, y, z)
\param depth (height, width, depth) describe the size of the box referenced from (x, y, z)
\return non zero if any or all of the box is in the view frustum.
*/
int BoxTest(v16 x, v16 y, v16 z, v16 width, v16 height, v16 depth);
/*! \brief Performs a test to determine if the provided box is in the view frustum.
\param x (x, y, z) point of a vertex on the box
\param y (x, y, z) point of a vertex on the box
\param z (x, y, z) point of a vertex on the box
\param width (width, height, depth) describe the size of the box referenced from (x, y, z)
\param height (width, height, depth) describe the size of the box referenced from (x, y, z)
\param depth (width, height, depth) describe the size of the box referenced from (x, y, z)
\return non zero if any or all of the box is in the view frustum.
*/
int BoxTestf(float x, float y, float z, float width, float height, float depth);
/*! \brief Performs a test to determine if the provided box is in the view frustum.
Performs a test to determine if the provided box is in the view frustum.
BoxTestResult must be called to get the result of this operation.
\param x (x, y, z) point of a vertex on the box
\param y (x, y, z) point of a vertex on the box
\param z (x, y, z) point of a vertex on the box
\param width (width, height, depth) describe the size of the box referenced from (x, y, z)
\param height (width, height, depth) describe the size of the box referenced from (x, y, z)
\param depth (width, height, depth) describe the size of the box referenced from (x, y, z)
*/
void BoxTest_Asynch(v16 x, v16 y, v16 z, v16 height, v16 width, v16 depth);
/*! \brief Performs a test to determine if the provided box is in the view frustum.
Performs a test to determine if the provided box is in the view frustum.
BoxTestResult must be called to get the result of this operation.
\param x (x, y, z) point of a vertex on the box
\param y (x, y, z) point of a vertex on the box
\param z (x, y, z) point of a vertex on the box
\param width (width, height, depth) describe the size of the box referenced from (x, y, z)
\param height (width, height, depth) describe the size of the box referenced from (x, y, z)
\param depth (width, height, depth) describe the size of the box referenced from (x, y, z)
*/
void BoxTestf_Asynch(float x, float y, float z, float width, float height, float depth);
/*! \brief Gets the result of the last box test. Needed for asynch box test calls.
\return non zero if any or all of the box is in the view frustum.
*/
int BoxTestResult(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------
$Id: cache.h,v 1.8 2008-02-12 00:45:58 wntrmute Exp $
key input code -- provides slightly higher level input forming
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.
---------------------------------------------------------------------------------*/
/*! \file cache.h
\brief ARM9 cache control functions.
*/
#ifndef _cache_h_
#define _cache_h_
#ifdef __cplusplus
extern "C" {
#endif
#include "nds/ndstypes.h"
/*! \fn IC_InvalidateAll()
\brief invalidate entire instruction cache.
*/
void IC_InvalidateAll();
/*! \fn IC_InvalidateRange(const void *base, u32 size)
\brief invalidate the instruction cache for a range of addresses.
\param base base address of the region to invalidate
\param size size of the region to invalidate.
*/
void IC_InvalidateRange(const void *base, u32 size);
/*! \fn DC_FlushAll()
\brief flush the entire data cache to memory.
*/
void DC_FlushAll();
/*! \fn DC_FlushRange(const void *base, u32 size)
\brief flush the data cache for a range of addresses to memory.
\param base base address of the region to flush.
\param size size of the region to flush.
*/
void DC_FlushRange(const void *base, u32 size);
/*! \fn DC_InvalidateAll()
\brief invalidate the entire data cache.
*/
void DC_InvalidateAll();
/*! \fn DC_InvalidateRange(const void *base, u32 size)
\brief invalidate the data cache for a range of addresses.
\param base base address of the region to invalidate
\param size size of the region to invalidate.
*/
void DC_InvalidateRange(const void *base, u32 size);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2016
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.
---------------------------------------------------------------------------------*/
/*! \file cache.h
\brief ARM9 cache defines.
*/
#ifndef _cache_asm_h_
#define _cache_asm_h_
#define PAGE_4K (0b01011 << 1)
#define PAGE_8K (0b01100 << 1)
#define PAGE_16K (0b01101 << 1)
#define PAGE_32K (0b01110 << 1)
#define PAGE_64K (0b01111 << 1)
#define PAGE_128K (0b10000 << 1)
#define PAGE_256K (0b10001 << 1)
#define PAGE_512K (0b10010 << 1)
#define PAGE_1M (0b10011 << 1)
#define PAGE_2M (0b10100 << 1)
#define PAGE_4M (0b10101 << 1)
#define PAGE_8M (0b10110 << 1)
#define PAGE_16M (0b10111 << 1)
#define PAGE_32M (0b11000 << 1)
#define PAGE_64M (0b11001 << 1)
#define PAGE_128M (0b11010 << 1)
#define PAGE_256M (0b11011 << 1)
#define PAGE_512M (0b11100 << 1)
#define PAGE_1G (0b11101 << 1)
#define PAGE_2G (0b11110 << 1)
#define PAGE_4G (0b11111 << 1)
#define ITCM_LOAD (1<<19)
#define ITCM_ENABLE (1<<18)
#define DTCM_LOAD (1<<17)
#define DTCM_ENABLE (1<<16)
#define DISABLE_TBIT (1<<15)
#define ROUND_ROBIN (1<<14)
#define ALT_VECTORS (1<<13)
#define ICACHE_ENABLE (1<<12)
#define BIG_ENDIAN (1<<7)
#define DCACHE_ENABLE (1<<2)
#define PROTECT_ENABLE (1<<0)
#endif

View File

@ -0,0 +1,242 @@
/*---------------------------------------------------------------------------------
console functions
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.
---------------------------------------------------------------------------------*/
/*! \file console.h
\brief nds stdio support.
<div class="fileHeader">
Provides stdio integration for printing to the DS screen as well as debug print
functionality provided by stderr.
General usage is to initialize the console by:
consoleDemoInit()
or to customize the console usage by:
consoleInit()
The default instance utilizes the sub display, approximatly 15KiB of vram C starting
at tile base 0 and 2KiB of map at map base 30.
Debug printing is performed by initializing the debug console via consoleDebugInit() as
follows:
<pre>
consoleDebugInit(DebugDevice_NOCASH);
fprintf(stderr, "debug message in no$gba window %i", stuff);
OR
consoleDebugInit(DebugDevice_CONSOLE);
fprintf(stderr, "debug message on DS console screen");
</pre>
The print console must be initialized to use DB_CONSOLE
</div>
*/
#ifndef CONSOLE_H
#define CONSOLE_H
#include <nds/ndstypes.h>
#include <nds/arm9/background.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef bool(* ConsolePrint)(void* con, char c);
//! a font struct for the console.
typedef struct ConsoleFont
{
u16* gfx; //!< A pointer to the font graphics (will be loaded by consoleInit() if loadGraphics is true
u16* pal; //!< A pointer to the font palette (will be loaded by consoleInit() if loadGraphics is true
u16 numColors; //!< Number of colors in the font palette
u8 bpp; //!< Bits per pixel in the font graphics
u16 asciiOffset; //!< Offset to the first valid character in the font table
u16 numChars; //!< Number of characters in the font graphics
bool convertSingleColor; /*!< If true font is treated as a single color font where all non zero pixels are set to
a value of 15 or 255 (4bpp / 8bpp respectivly).
This ensures only one palette entry is utilized for font rendering.*/
}ConsoleFont;
/** \brief console structure used to store the state of a console render context.
Default values from consoleGetDefault();
<div class="fixedFont"><pre>
PrintConsole defaultConsole =
{
//Font:
{
(u16*)default_font_bin, //font gfx
0, //font palette
0, //font color count
4, //bpp
0, //first ascii character in the set
128, //number of characters in the font set
true, //convert to single color
},
0, //font background map
0, //font background gfx
31, //map base
0, //char base
0, //bg layer in use
-1, //bg id
0,0, //cursorX cursorY
0,0, //prevcursorX prevcursorY
32, //console width
24, //console height
0, //window x
0, //window y
32, //window width
24, //window height
3, //tab size
0, //font character offset
0, //selected palette
0, //print callback
false, //console initialized
true, //load graphics
};
</pre></div>
*/
typedef struct PrintConsole
{
ConsoleFont font; //!< font of the console.
u16* fontBgMap; /*!< Pointer to the bg layer map if used. Is set by bgInit if bgId is valid*/
u16* fontBgGfx; /*!< Pointer to the bg layer graphics if used. Is set by bgInit if bgId is valid*/
u8 mapBase; /*!< Map base set by console init based on background setup */
u8 gfxBase; /*!< Tile graphics base set by console init based on background setup */
u8 bgLayer; /*!< Bg layer used by the background */
int bgId; /*!< bgId, should be set with a call to bgInit() or bgInitSub()*/
int cursorX; /*!< Current X location of the cursor (as a tile offset by default) */
int cursorY; /*!< Current Y location of the cursor (as a tile offset by default) */
int prevCursorX; /*!< Internal state */
int prevCursorY; /*!< Internal state */
int consoleWidth; /*!< Width of the console hardware layer in tiles */
int consoleHeight; /*!< Height of the console hardware layer in tiles */
int windowX; /*!< Window X location in tiles (not implemented) */
int windowY; /*!< Window Y location in tiles (not implemented) */
int windowWidth; /*!< Window width in tiles (not implemented) */
int windowHeight; /*!< Window height in tiles (not implemented) */
int tabSize; /*!< Size of a tab*/
u16 fontCharOffset; /*!< Offset to the first graphics tile in background memory (in case your font is not loaded at a graphics base boundary)*/
u16 fontCurPal; /*!< The current palette used by the engine (only applies to 4bpp text backgrounds) */
ConsolePrint PrintChar; /*!< callback for printing a character. Should return true if it has handled rendering the graphics
(else the print engine will attempt to render via tiles) */
bool consoleInitialised; /*!< True if the console is initialized */
bool loadGraphics; /*!< True if consoleInit should attempt to load font graphics into background memory */
}PrintConsole;
//! Console debug devices supported by libnds.
typedef enum
{
DebugDevice_NULL = 0x0, //!< swallows prints to stderr
DebugDevice_NOCASH = 0x1, //!< Directs stderr debug statements to no$gba debug window
DebugDevice_CONSOLE = 0x02 //!< Directs stderr debug statements to DS console window
}DebugDevice;
/*! \brief Loads the font into the console
\param console pointer to the console to update, if NULL it will update the current console
\param font the font to load
*/
void consoleSetFont(PrintConsole* console, ConsoleFont* font);
/*! \brief Sets the print window
\param console console to set, if NULL it will set the current console window
\param x x location of the window
\param y y location of the window
\param width width of the window
\param height height of the window
*/
void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height);
/*! \brief Gets a pointer to the console with the default values
this should only be used when using a single console or without changing the console that is returned, other wise use consoleInit()
\return A pointer to the console with the default values
*/
PrintConsole* consoleGetDefault(void);
/*! \brief Make the specified console the render target
\param console A pointer to the console struct (must have been initialized with consoleInit(PrintConsole* console)
\return a pointer to the previous console
*/
PrintConsole *consoleSelect(PrintConsole* console);
/*! \brief Initialise the console.
\param console A pointer to the console data to initialze (if it's NULL, the default console will be used)
\param layer background layer to use
\param type the type of the background
\param size the size of the background
\param mapBase the map base
\param tileBase the tile graphics base
\param mainDisplay if true main engine is used, otherwise false
\param loadGraphics if true the default font graphics will be loaded into the layer
\return A pointer to the current console.
*/
PrintConsole* consoleInit(PrintConsole* console, int layer, BgType type, BgSize size, int mapBase, int tileBase, bool mainDisplay, bool loadGraphics);
/*! \brief Initialize the console to a default state for prototyping.
This function sets the console to use sub display, VRAM_C, and BG0 and enables MODE_0_2D on the
sub display. It is intended for use in prototyping applications which need print ability and not actual
game use. Print functionality can be utilized with just this call.
\return A pointer to the current PrintConsole.
*/
PrintConsole* consoleDemoInit(void);
//! Clears the screan by using iprintf("\x1b[2J");
void consoleClear(void);
/*! \brief Initializes debug console output on stderr to the specified device
\param device The debug device (or devices) to output debug print statements to
*/
void consoleDebugInit(DebugDevice device);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2005
Jason Rogers (dovoto)
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.
---------------------------------------------------------------------------------*/
/*! \file decompress.h
\brief wraps the bios decompress functionality into something a bit easier to deal with.
*/
#ifndef NDS_DECOMPRESS
#define NDS_DECOMPRESS
#include <nds/ndstypes.h>
#include <nds/bios.h>
//! the types of decompression available.
typedef enum
{
LZ77, //!< LZ77 decompression.
LZ77Vram, //!< vram safe LZ77 decompression.
HUFF, //!< vram safe huff decompression.
RLE, //!< run length encoded decompression.
RLEVram //!< vram safe run length encoded decompression.
}DecompressType;
#ifdef __cplusplus
extern "C" {
#endif
/*!
\brief decompresses data using the suported type
\param dst the destination to decompress to
\param data the data to decompress
\param type the type of data to decompress
*/
void decompress(const void* data, void* dst, DecompressType type);
/*!
\brief decompresses data using the suported type (only LZ77Vram, HUFF, and RLEVram support streaming)
\param dst the destination to decompress to.
\param data the data to decompress.
\param type the type of data to decompress.
\param readCB a callback to read the next byte of data.
\param getHeaderCB a callback to read the 32 byte header.
*/
void decompressStream(const void* data, void* dst, DecompressType type, getByteCallback readCB, getHeaderCallback getHeaderCB);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,119 @@
/*
dldi.h
Copyright (c) 2006 Michael "Chishm" Chisholm
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NDS_DLDI_INCLUDE
#define NDS_DLDI_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#include "../disc_io.h"
#include "dldi_asm.h"
#define FIX_ALL 0x01
#define FIX_GLUE 0x02
#define FIX_GOT 0x04
#define FIX_BSS 0x08
#define DLDI_MAGIC_STRING_LEN 8
#define DLDI_FRIENDLY_NAME_LEN 48
extern const u32 DLDI_MAGIC_NUMBER;
// I/O interface with DLDI extensions
typedef struct DLDI_INTERFACE {
u32 magicNumber;
char magicString [DLDI_MAGIC_STRING_LEN];
u8 versionNumber;
u8 driverSize; // log-2 of driver size in bytes
u8 fixSectionsFlags;
u8 allocatedSize; // log-2 of the allocated space in bytes
char friendlyName [DLDI_FRIENDLY_NAME_LEN];
// Pointers to sections that need address fixing
void* dldiStart;
void* dldiEnd;
void* interworkStart;
void* interworkEnd;
void* gotStart;
void* gotEnd;
void* bssStart;
void* bssEnd;
// Original I/O interface data
DISC_INTERFACE ioInterface;
} DLDI_INTERFACE;
/*
Pointer to the internal DLDI, not directly usable by libfat.
You'll need to set the bus permissions appropriately before using.
*/
extern const DLDI_INTERFACE* io_dldi_data;
/*
Return a pointer to the internal IO interface,
setting up bus permissions in the process.
*/
extern const DISC_INTERFACE* dldiGetInternal (void);
/*
Determines if an IO driver is a valid DLDI driver
*/
extern bool dldiIsValid (const DLDI_INTERFACE* io);
/*
Adjust the pointer addresses within a DLDI driver
*/
extern void dldiFixDriverAddresses (DLDI_INTERFACE* io);
/*
Load a DLDI from disc and set up the bus permissions.
This returns a type not directly usable in libfat,
but it does give extra information, such as a friendly name.
To use in libfat:
const DLDI_INTERFACE* loadedDldi = dldi_loadFromFile ("file");
loadedDldi->ioInterface.startup();
fatMount(&loadedDldi->ioInterface, "devname", 0);
*/
extern DLDI_INTERFACE* dldiLoadFromFile (const char* path);
/*
Free resources used by a loaded DLDI.
Remember to unmount and shutdown first:
fatUnmount("devname");
loadedDldi->ioInterface.shutdown();
dldiFree(loadedDldi);
*/
extern void dldiFree (DLDI_INTERFACE* dldi);
#ifdef __cplusplus
}
#endif
#endif // NDS_DLDI_INCLUDE

View File

@ -0,0 +1,15 @@
#define FEATURE_MEDIUM_CANREAD 0x00000001
#define FEATURE_MEDIUM_CANWRITE 0x00000002
#define FEATURE_SLOT_GBA 0x00000010
#define FEATURE_SLOT_NDS 0x00000020
#define FIX_ALL 0x01
#define FIX_GLUE 0x02
#define FIX_GOT 0x04
#define FIX_BSS 0x08
#define DLDI_SIZE_32KB 0x0f
#define DLDI_SIZE_16KB 0x0e
#define DLDI_SIZE_8KB 0x0d
#define DLDI_SIZE_4KB 0x0c
#define DLDI_SIZE_1KB 0x0a

View File

@ -0,0 +1,80 @@
/*---------------------------------------------------------------------------------
A simple vector like dynamic data structure
Copyright (C) 2005
Jason Rogers (dovoto)
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.
---------------------------------------------------------------------------------*/
/*! \file dynamicArray.h
\brief A dynamically resizing array for general use.
*/
#ifndef __DYNAMICARRAY_H__
#define __DYNAMICARRAY_H__
#include <stdlib.h>
#include <string.h>
#include <nds/ndstypes.h>
//! A resizable array
typedef struct DynamicArray
{
void** data; //!< pointer to array of void pointers
unsigned int cur_size; //!< currently allocated size of the array
}DynamicArray;
/*! \brief Initializes an array with the supplied initial size
\param v the array to initialize
\param initialSize the initial size to allocate
\return a pointer to the data, or NULL on error.
*/
void* DynamicArrayInit(DynamicArray* v, unsigned int initialSize);
/*! \brief Frees memory allocated by the dynamic array
\param v The array to delete
*/
void DynamicArrayDelete(DynamicArray* v);
/*! \brief Gets the entry at the supplied index
\param v The array to get from.
\param index The index of the data to get.
\return The data or NULL if v is NULL or the index is out of range.
*/
void* DynamicArrayGet(DynamicArray* v, unsigned int index);
/*! \brief Sets the entry to the supplied value
\param v The array to set
\param index The index of the data to set (array will be resized to fit the index).
\param item The data to set.
\return false if v is NULL or there isn't enough memory, true otherwise
*/
bool DynamicArraySet(DynamicArray *v, unsigned int index, void* item);
#endif

View File

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------------
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.
---------------------------------------------------------------------------------*/
#ifndef _exceptions_h_
#define _exceptions_h_
//---------------------------------------------------------------------------------
/** \file
\brief functions to handle hardware exceptions.
*/
#define EXCEPTION_VECTOR (*(VoidFn *)(0x2FFFD9C))
#ifdef __cplusplus
extern "C" {
#endif
extern VoidFn exceptionC[];//shouldn't this be a pointer instead of an array?
extern u32 exceptionStack;
//! an array with a copy of all the registers of when the exception occured.
extern s32 exceptionRegisters[];
void enterException(void);
//! sets a custom hardware exception handler.
void setExceptionHandler(VoidFn handler);
//! sets the default hardware exception handler.
void defaultExceptionHandler();
//! returns the cpu status register.
u32 getCPSR();
#ifdef __cplusplus
}
#endif
//---------------------------------------------------------------------------------
#endif // _exceptions_h_
//---------------------------------------------------------------------------------

View File

@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------------
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.
---------------------------------------------------------------------------------*/
/*! \file guitarGrip.h
\brief guitar grip device slot-2 addon support.
*/
#ifndef GUITARGRIP_HEADER_INCLUDE
#define GUITARGRIP_HEADER_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#define GUITARGRIP_GREEN BIT(6)
#define GUITARGRIP_RED BIT(5)
#define GUITARGRIP_YELLOW BIT(4)
#define GUITARGRIP_BLUE BIT(3)
/*! \fn bool guitarGripIsInserted()
\brief Check for the guitar grip
\return true if that's what is in the slot-2
*/
bool guitarGripIsInserted();
/*! \fn void guitarGripScanKeys()
\brief Obtain the current guitar grip state.
Call this function once per main loop to use the guitarGrip functions.
*/
void guitarGripScanKeys();
//! Obtains the current guitar grip keys held state
u8 guitarGripKeysHeld();
//! Obtains the current guitar grip keys pressed state
u16 guitarGripKeysDown();
//! Obtains the current guitar grip keys released state
u16 guitarGripKeysUp();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2005
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.
---------------------------------------------------------------------------------*/
/*! \file image.h
\brief An image abstraction for working with image data.
<div class="fileHeader">
Image data buffers must be allocated using malloc() rather than pointing to stack data, as the conversion
routines will free() the argument's image buffer and allocate a new block for the replacement data.
As such, any loader implemented utilizing this structure must use malloc() to allocate the image
buffer.
</div>
*/
#ifndef IMAGE_H
#define IMAGE_H
#include <nds/arm9/video.h>
//! \brief holds a red green blue triplet
typedef struct RGB_24
{
unsigned char r; //!< 8 bits for the red value.
unsigned char g; //!< 8 bits for the green value.
unsigned char b; //!< 8 bits for the blue value.
} __attribute__ ((packed)) RGB_24;
//! A generic image structure.
typedef struct sImage
{
short height; /*!< \brief The height of the image in pixels */
short width; /*!< \brief The width of the image in pixels */
int bpp; /*!< \brief Bits per pixel (should be 4 8 16 or 24) */
unsigned short* palette; /*!< \brief A pointer to the palette data */
//! A union of data pointers to the pixel data.
union
{
u8* data8; //!< pointer to 8 bit data.
u16* data16; //!< pointer to 16 bit data.
u32* data32; //!< pointer to 32 bit data.
} image;
} sImage, *psImage;
#ifdef __cplusplus
extern "C" {
#endif
/*! \brief Destructively converts a 24-bit image to 16-bit
\param img a pointer to image to manipulate
*/
void image24to16(sImage* img);
/*! \brief Destructively converts an 8-bit image to 16 bit setting the alpha bit
\param img a pointer to image to manipulate
*/
void image8to16(sImage* img);
/*! \brief Destructively converts an 8-bit image to 16-bit with alpha bit cleared for the supplied palette index
\param img a pointer to image to manipulate
\param transparentColor Color indexes equal to this value will have the alpha bit clear
*/
void image8to16trans(sImage* img, u8 transparentColor);
/*! \brief frees the image data. Only call if the image data was returned from an image loader
\param img a pointer to image to manipulate (the image data will be free() )
*/
void imageDestroy(sImage* img);
/*! \brief Tiles 8-bit image data into a sequence of 8x8 tiles
\param img a pointer to image to manipulate
*/
void imageTileData(sImage* img);
#ifdef __cplusplus
}
#endif
//why is this included here?
#include <nds/arm9/pcx.h>
#endif

View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------------
key input code -- provides slightly higher level input forming
Copyright (C) 2005
Michael Noland (joat)
Jason Rogers (dovoto)
Christian Auby (DesktopMan)
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.
---------------------------------------------------------------------------------*/
/*! \file
\brief NDS button and touchscreen input support.
The state of the keypad must be read from hardware into memory using scanKeys() whenever
you want an updated input state. After reading, call one of the associated "keys" functions to see
what event was triggered. These events are computed as the difference between the current and previous
key state you read. It's generally a good idea to scan keys frequently to insure your application's input system
is responsive.\n
After reading the key state, you will be given an integer representing which keys are in the requested state,
to mask of specific buttons, use the key masks described in nds/input.h .
\see nds/input.h available key masks on the Nintendo DS
*/
//---------------------------------------------------------------------------------
#ifndef INPUT_HEADER_INCLUDE
#define INPUT_HEADER_INCLUDE
//---------------------------------------------------------------------------------
#include <nds/touch.h>
#include <nds/input.h>
#ifdef __cplusplus
extern "C" {
#endif
/*! \brief Obtains the current keypad state.
Call this function once per main loop in order to use the keypad functions.
*/
void scanKeys(void);
/*! \brief Obtains the current keypad state.
Call this function to get keypad state without affecting state of other key functions (keysUp keysHeld etc...)
*/
uint32 keysCurrent(void);
//! Obtains the current keypad held state.
uint32 keysHeld(void);
//! Obtains the current keypad pressed state.
uint32 keysDown(void);
//! Obtains the current keypad pressed or repeating state.
uint32 keysDownRepeat(void);
/*! \brief Sets the key repeat parameters.
\param setDelay Number of %scanKeys calls before keys start to repeat.
\param setRepeat Number of %scanKeys calls before keys repeat.
*/
void keysSetRepeat( u8 setDelay, u8 setRepeat );
//! Obtains the current keypad released state.
uint32 keysUp(void);
__attribute__ ((deprecated)) touchPosition touchReadXY() ;
/*!
\brief Obtains the current touchpad state.
\param data a touchPosition ptr which will be filled by the function.
*/
void touchRead(touchPosition *data);
#ifdef __cplusplus
}
#endif
//---------------------------------------------------------------------------------
#endif // INPUT_HEADER_INCLUDE
//---------------------------------------------------------------------------------

View File

@ -0,0 +1,188 @@
/*---------------------------------------------------------------------------------
keyboard.h -- stdin integration for a simple keyboard
Copyright (C) 2007
Jason Rogers (Dovoto)
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.
---------------------------------------------------------------------------------*/
/*! \file keyboard.h
\brief nds stdio keyboard integration.
<div class="fileHeader">The keyboard component allows the use of a default keyboard via stdin as well as
direct via the functions exposed below. The default behavior is a hidden keyboard
that shows on a call to scanf(stdin, ...).
By default the keyboard uses background 3 of the sub display, consumes approximatly 40KiB
of background vram begining at tile base 1 and 2KB of map stored at map base 30. The default
is designed to function along side a default instance of the console print functionality.
To customize keyboard behavior and resource usage modify the keyboard structure returned by
keyboardGetDefault() or create your own keyboard.
</div>
*/
#ifndef __KEYBOARD_H__
#define __KEYBOARD_H__
#include <nds/ndstypes.h>
#include <nds/arm9/background.h>
//!callback function pointer for a key changed.
typedef void (*KeyChangeCallback)(int key);
//! States the keyboard can be in, currently only Lower and Upper supported.
typedef enum
{
Lower = 0, /*!< Normal keyboard display (lowercase letters) */
Upper = 1, /*!< Caps lock Held */
Numeric = 2, /*!< Numeric only keypad (not provided by the default keyboard) */
Reduced = 3 /*!< Reduced footprint keyboard (not provided by the default keyboard) */
}KeyboardState;
//! defines a key mapping.
typedef struct KeyMap {
const u16* mapDataPressed; /*!< the map for keys pressed*/
const u16* mapDataReleased; /*!< the map for keys released */
const int* keymap; /*!< the lookup table for x y grid location to corresponding key */
int width; /*!< width of the keyboard in grid spaces */
int height; /*!< height of the keyboard in grid spaces*/
}KeyMap;
//! describes a keyboard.
typedef struct Keyboard {
int background; /*!< Background number to use, after init() this contains the background ID */
int keyboardOnSub; /*!< boolean to determine if keyboard is on sub screen or main */
int offset_x; /*!< x offset of the map, can be used to center a custom keyboard */
int offset_y; /*!< y offset of the map, can be used to center a custom keyboard */
int grid_width; /*!< the grid width, this size will be used to translate x coordinate of touch to x coordinate in keymap */
int grid_height; /*!< the grid height, this size will be used to translate y coordinate of touch to y coordinate in keymap */
KeyboardState state; /*!< the state of the keyboard*/
int shifted; /*!< true if shifted*/
int visible; /*!< true if visible*/
KeyMap* mappings[4]; //!< array of 4 keymap pointers, one for every keyboard state.
//KeyMap* lower; /*!< keymapping for lower case normal keyboard*/
//KeyMap* upper; /*!< keymapping for shifted upper case normal keyboard*/
//KeyMap* numeric; /*!< keymapping for numeric keypad*/
//KeyMap* reduced; /*!< keymapping for reduced footprint keyboard*/
const u16* tiles; /*!< pointer to graphics tiles, cannot exceed 44KB with default base*/
u32 tileLen; /*!< length in bytes of graphics data*/
const u16* palette; /*!< pointer to the palette*/
u32 paletteLen; /*!< length in bytes of the palette data*/
int mapBase; /*!< map base to be used by the keyboard*/
int tileBase; /*!< tile base to be used by keyboard graphics*/
int tileOffset; /*!< tile offset (in bytes) to load graphics (map must be preadjusted)*/
u32 scrollSpeed; /*!<keyboard scroll speed on hide and show in pixels per frame (must be positive and 0 == instant on) */
KeyChangeCallback OnKeyPressed; /*!< will be called on key press*/
KeyChangeCallback OnKeyReleased; /*!< will be called on key release */
}Keyboard;
/*! \brief enum values for the keyboard control keys.
negative values are keys with no sensible ascii representation.
numbers are chosen to mimic ascii control sequences.
*/
typedef enum
{
NOKEY = -1, //!< will be returned if no key was pressed.
DVK_FOLD = -23, //!< will be returned if the fold key was pressed (topleft on the default keyboard).
DVK_TAB = 9, //!< will be returned if the tab key was pressed.
DVK_BACKSPACE = 8, //!< will be returned if the backspace key was pressed.
DVK_CAPS = -15, //!< will be returned if the caps key was pressed.
DVK_SHIFT = -14, //!< will be returned if the shift key was pressed.
DVK_SPACE = 32, //!< will be returned if the space key was pressed.
DVK_MENU = -5, //!< will be returned if the menu key was pressed.
DVK_ENTER = 10, //!< will be returned if the enter key was pressed.
DVK_CTRL = -16, //!< will be returned if the ctrl key was pressed.
DVK_UP = -17, //!< will be returned if the up key was pressed.
DVK_RIGHT = -18, //!< will be returned if the right key was pressed.
DVK_DOWN = -19, //!< will be returned if the down key was pressed.
DVK_LEFT = -20, //!< will be returned if the left key was pressed.
DVK_ALT = -26 //!< will be returned if the alt key was pressed.
} Keys;
#ifdef __cplusplus
extern "C" {
#endif
//! Gets the default keyboard.
Keyboard* keyboardGetDefault(void);
/*! \brief initializes the keyboard system with the supplied keyboard
\param keyboard the keyboard struct to initialize (can be NULL)
\param layer the background layer to use
\param type the background type to initialize
\param size the background size to initialize
\param mapBase the map base to use for the background
\param tileBase the graphics tile base to use for the background
\param mainDisplay if true the keyboard will render on the main display
\param loadGraphics if true the keyboard graphics will be loaded
\return returns the initialized keyboard struct
*/
Keyboard* keyboardInit(Keyboard* keyboard, int layer, BgType type, BgSize size, int mapBase, int tileBase, bool mainDisplay, bool loadGraphics);
/*! \brief initializes the keyboard with default options.
Same as calling keyboardInit(NULL, 3, BgType_Text4bpp, BgSize_T_256x512, 20, 0, false, true)
\return a pointer to the current keyboard.
*/
Keyboard* keyboardDemoInit(void);
/*! \brief Displays the keyboard.
*/
void keyboardShow(void);
/*! \brief Hides the keyboard
*/
void keyboardHide(void);
/*! \brief returns the ascii code for the key located at the supplied x and y.
Will not effect keyboard shift state.
\param x the pixel x location
\param y the pixel y location
\return the key pressed or NOKEY if user pressed outside the keypad
*/
int keyboardGetKey(int x, int y);
/*! \brief reads the input until a the return key is pressed or the maxLen is exceeded.
\param buffer a buffer to hold the input string
\param maxLen the maximum length to read
*/
void keyboardGetString(char * buffer, int maxLen);
/*! \brief Waits for user to press a key and returns the key pressed.
Use keyboardUpdate instead for async operation.
*/
int keyboardGetChar(void);
/*! \brief Processes the keyboard.
Should be called once per frame when using the keyboard in an async manner.
\return the ascii code of the key pressed or -1 if no key was pressed.
*/
int keyboardUpdate(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------------
A simple linked list data structure
Copyright (C) 2008
Jason Rogers (dovoto)
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.
---------------------------------------------------------------------------------*/
/*! \file
\brief A simple doubly linked, unsorted list implementation.
*/
#ifndef __LINKEDLIST_H__
#define __LINKEDLIST_H__
#include <malloc.h>
//! A node for the linked list.
typedef struct LinkedList{
struct LinkedList *next; //!< A pointer to the next node.
struct LinkedList *prev; //!< A pointer to the previous node.
void *data; //!< A pointer to some data.
}LinkedList;
/*!
\brief Adds data to a linked list.
This will only store the pointer to the data, so you have to make sure that the pointer stays valid.
\param front A pointer to a pointer to the front of the linked list (or a pointer to NULL if you don't have a linked list yet).
\param data A pointer to the data you want to store.
\return A pointer to the new node, which is also the new front, or NULL if there is not enough memory.
*/
LinkedList* linkedlistAdd(LinkedList **front, void* data);
/*!
\brief Removes a node from a linked list.
The data pointer of the node will be lost after this, so make sure you don't need it anymore.
\param node The node you want to remove.
*/
void linkedlistRemove(LinkedList *node);
#endif

View File

@ -0,0 +1,313 @@
/*---------------------------------------------------------------------------------
math functions
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.
---------------------------------------------------------------------------------*/
/*! \file math.h
\brief hardware coprocessor math instructions.
*/
#ifndef MATH_ARM9_INCLUDE
#define MATH_ARM9_INCLUDE
#include "nds/ndstypes.h"
#define REG_DIVCNT (*(vu16*)(0x04000280))
#define REG_DIV_NUMER (*(vs64*) (0x04000290))
#define REG_DIV_NUMER_L (*(vs32*) (0x04000290))
#define REG_DIV_NUMER_H (*(vs32*) (0x04000294))
#define REG_DIV_DENOM (*(vs64*) (0x04000298))
#define REG_DIV_DENOM_L (*(vs32*) (0x04000298))
#define REG_DIV_DENOM_H (*(vs32*) (0x0400029C))
#define REG_DIV_RESULT (*(vs64*) (0x040002A0))
#define REG_DIV_RESULT_L (*(vs32*) (0x040002A0))
#define REG_DIV_RESULT_H (*(vs32*) (0x040002A4))
#define REG_DIVREM_RESULT (*(vs64*) (0x040002A8))
#define REG_DIVREM_RESULT_L (*(vs32*) (0x040002A8))
#define REG_DIVREM_RESULT_H (*(vs32*) (0x040002AC))
#define REG_SQRTCNT (*(vu16*)(0x040002B0))
#define REG_SQRT_PARAM (*(vs64*) (0x040002B8))
#define REG_SQRT_PARAM_L (*(vs32*) (0x040002B8))
#define REG_SQRT_PARAM_H (*(vs32*) (0x040002BC))
#define REG_SQRT_RESULT (*(vu32*) (0x040002B4))
// Math coprocessor modes
#define DIV_64_64 2
#define DIV_64_32 1
#define DIV_32_32 0
#define DIV_BUSY (1<<15)
#define SQRT_64 1
#define SQRT_32 0
#define SQRT_BUSY (1<<15)
// Fixed point conversion macros
#define inttof32(n) ((n) * (1 << 12)) /*!< \brief convert int to f32 */
#define f32toint(n) ((n) / (1 << 12)) /*!< \brief convert f32 to int */
#define floattof32(n) ((int)((n) * (1 << 12))) /*!< \brief convert float to f32 */
#define f32tofloat(n) (((float)(n)) / (float)(1<<12)) /*!< \brief convert f32 to float */
// Fixed Point versions
static inline
/**
* \brief Fixed point divide
* \param num Takes 20.12 numerator.
* \param den Takes 20.12 denominator.
* \return returns 20.12 result.
*/
int32 divf32(int32 num, int32 den)
{
REG_DIVCNT = DIV_64_32;
while(REG_DIVCNT & DIV_BUSY);
REG_DIV_NUMER = ((int64)num) << 12;
REG_DIV_DENOM_L = den;
while(REG_DIVCNT & DIV_BUSY);
return (REG_DIV_RESULT_L);
}
static inline
/**
* \brief Fixed point multiply
* \param a Takes 20.12
* \param b Takes 20.12
* \return returns 20.12 result
*/
int32 mulf32(int32 a, int32 b)
{
long long result = (long long)a * (long long)b;
return (int32)(result >> 12);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
static inline
/**
* \brief Fixed point sqrt
* \param a Takes 20.12
* \return returns 20.12 result
*/
int32 sqrtf32(int32 a)
{
REG_SQRTCNT = SQRT_64;
while(REG_SQRTCNT & SQRT_BUSY);
REG_SQRT_PARAM = ((int64)a) << 12;
while(REG_SQRTCNT & SQRT_BUSY);
return REG_SQRT_RESULT;
}
#pragma GCC diagnostic pop
// Integer versions
static inline
/**
* \brief integer divide
* \param num numerator
* \param den denominator
* \return returns 32 bit integer result
*/
int32 div32(int32 num, int32 den)
{
REG_DIVCNT = DIV_32_32;
while(REG_DIVCNT & DIV_BUSY);
REG_DIV_NUMER_L = num;
REG_DIV_DENOM_L = den;
while(REG_DIVCNT & DIV_BUSY);
return (REG_DIV_RESULT_L);
}
static inline
/**
* \brief integer modulous
* \param num numerator
* \param den denominator
* \return returns 32 bit integer remainder
*/
int32 mod32(int32 num, int32 den)
{
REG_DIVCNT = DIV_32_32;
while(REG_DIVCNT & DIV_BUSY);
REG_DIV_NUMER_L = num;
REG_DIV_DENOM_L = den;
while(REG_DIVCNT & DIV_BUSY);
return (REG_DIVREM_RESULT_L);
}
static inline
/**
* \brief integer 64 bit divide
* \param num 64 bit numerator
* \param den 32 bit denominator
* \return returns 32 bit integer result
*/
int32 div64(int64 num, int32 den)
{
REG_DIVCNT = DIV_64_32;
while(REG_DIVCNT & DIV_BUSY);
REG_DIV_NUMER = num;
REG_DIV_DENOM_L = den;
while(REG_DIVCNT & DIV_BUSY);
return (REG_DIV_RESULT_L);
}
static inline
/**
* \brief integer 64 bit modulous
* \param num 64 bit numerator
* \param den 32 bit denominator
* \return returns 32 bit integer remainder
*/
int32 mod64(int64 num, int32 den)
{
REG_DIVCNT = DIV_64_32;
while(REG_DIVCNT & DIV_BUSY);
REG_DIV_NUMER = num;
REG_DIV_DENOM_L = den;
while(REG_DIVCNT & DIV_BUSY);
return (REG_DIVREM_RESULT_L);
}
static inline
/**
* \brief integer sqrt
* \param a 32 bit integer argument
* \return returns 32 bit integer result
*/
u32 sqrt32(int a)
{
REG_SQRTCNT = SQRT_32;
while(REG_SQRTCNT & SQRT_BUSY);
REG_SQRT_PARAM_L = a;
while(REG_SQRTCNT & SQRT_BUSY);
return REG_SQRT_RESULT;
}
static inline
/**
* \brief integer sqrt
* \param a 64 bit integer argument
* \return returns 32 bit integer result
*/
u32 sqrt64(long long a)
{
REG_SQRTCNT = SQRT_64;
while(REG_SQRTCNT & SQRT_BUSY);
REG_SQRT_PARAM = a;
while(REG_SQRTCNT & SQRT_BUSY);
return REG_SQRT_RESULT;
}
static inline
/**
* \brief 20.12 fixed point cross product function result = AxB
* \param a pointer to fixed 3x3 matrix
* \param b pointer to fixed 3x3 matrix
* \param result pointer to fixed 3x3 matrix
* Cross product\n
* x = Ay * Bz - By * Az\n
* y = Az * Bx - Bz * Ax\n
* z = Ax * By - Bx * Ay\n
*/
void crossf32(int32 *a, int32 *b, int32 *result)
{
result[0] = mulf32(a[1], b[2]) - mulf32(b[1], a[2]);
result[1] = mulf32(a[2], b[0]) - mulf32(b[2], a[0]);
result[2] = mulf32(a[0], b[1]) - mulf32(b[0], a[1]);
}
static inline
/**
* \brief 20.12 fixed point dot product function result = A dot B
* \param a pointer to fixed 3x3 matrix
* \param b pointer to fixed 3x3 matrix
* \return 32 bit integer result
* Dot Product
* result = Ax * Bx + Ay * By + Az * Bz
*/
int32 dotf32(int32 *a, int32 *b)
{
return mulf32(a[0], b[0]) + mulf32(a[1], b[1]) + mulf32(a[2], b[2]);
}
static inline
/**
* \brief 20.12 fixed point normalize function A = A / |A|
* \param a pointer to fixed 3x3 matrix
* Normalize\n
* Ax = Ax / mag\n
* Ay = Ay / mag\n
* Az = Az / mag\n
*/
void normalizef32(int32* a)
{
// magnitude = sqrt ( Ax^2 + Ay^2 + Az^2 )
int32 magnitude = sqrtf32( mulf32(a[0], a[0]) + mulf32(a[1], a[1]) + mulf32(a[2], a[2]) );
a[0] = divf32(a[0], magnitude);
a[1] = divf32(a[1], magnitude);
a[2] = divf32(a[2], magnitude);
}
#endif

View File

@ -0,0 +1,45 @@
/*
nand.h
Copyright (c) 2016 Dave "WinterMute" Murphy
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NDS_NAND_INCLUDE
#define NDS_NAND_INCLUDE
#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
bool nand_ReadSectors(sec_t sector, sec_t numSectors,void* buffer);
bool nand_WriteSectors(sec_t sector, sec_t numSectors,const void* buffer);
ssize_t nand_GetSize();
#ifdef __cplusplus
}
#endif
#endif // NDS_NAND_INCLUDE

View File

@ -0,0 +1,196 @@
/*---------------------------------------------------------------------------------
$Id: ndsmotion.h,v 1.9 2008-04-07 03:54:56 dovoto Exp $
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.
---------------------------------------------------------------------------------*/
/*! \file ndsmotion.h
\brief interface code for the ds motion card, ds motion pak, MK6.
*/
#ifndef NDS_MOTION_INCLUDE
#define NDS_MOTION_INCLUDE
//---------------------------------------------------------------------------------
typedef struct MotionCalibration
{
short xoff, yoff, zoff, goff;
short xsens, ysens, zsens, gsens;
}MotionCalibration;
#ifdef __cplusplus
extern "C" {
#endif
/*!
\brief Initializes the DS Motion Sensor.
Run this before using any of the DS Motion Sensor functions
save the return value and pass it to the other motion_ functions
\return
*/
int motion_init(void);
/*!
\brief Deinitializes the DS Motion Sensor
*/
void motion_deinit(void);
/*!
\brief read the X acceleration
\return
*/
signed int motion_read_x(void);
/*!
\brief read the Y acceleration
\return
*/
signed int motion_read_y(void);
/*!
\brief read the Z acceleration
\return
*/
signed int motion_read_z(void);
/*!
\brief read the Z rotational speed
\return
*/
signed int motion_read_gyro(void);
/*!
\brief gets acceleration value to mili G (where g is 9.8 m/s*s)
*/
int motion_acceleration_x(void);
/*!
\brief gets acceleration value to mili G (where g is 9.8 m/s*s)
*/
int motion_acceleration_y(void);
/*!
\brief gets acceleration value to mili G (where g is 9.8 m/s*s)
*/
int motion_acceleration_z(void);
/*!
\brief this should be passed the raw reading at 1g for accurate acceleration calculations. Default is 819
\param sens the raw reading at 1g for accurate acceleration calculations
*/
void motion_set_sens_x(int sens);
/*!
\brief this should be passed the raw reading at 1g for accurate acceleration calculations. Default is 819
\param sens the raw reading at 1g for accurate acceleration calculations
*/
void motion_set_sens_y(int sens);
/*!
\brief this should be passed the raw reading at 1g for accurate acceleration calculations. Default is 819
\param sens the raw reading at 1g for accurate acceleration calculations
*/
void motion_set_sens_z(int sens);
/*!
\brief this should be passed the raw reading at 1g for accurate acceleration calculations. Default is 825
\param sens the raw reading at 1g for accurate acceleration calculations
*/
void motion_set_sens_gyro(int sens);
/*!
\brief this should be called when the axis is under no acceleration.
Default is 2048
*/
void motion_set_offs_x(void);
/*!
\brief this should be called when the axis is under no acceleration
Default is 2048
*/
void motion_set_offs_y(void);
/*!
\brief this should be called when the axis is under no acceleration
Default is 2048
*/
void motion_set_offs_z(void);
/*!
\brief this should be called when the axis is under no rotation
Default is 1680
*/
void motion_set_offs_gyro(void);
/*!
\brief converts raw rotation value to degrees per second
*/
int motion_rotation(void);
/*!
\brief This returns the current calibration settings for saving
*/
MotionCalibration* motion_get_calibration(void);
/*!
\brief This sets the calibration settings. Intended to restore saved calibration settings
\param cal the calibration settings
*/
void motion_set_calibration(MotionCalibration* cal);
/*!
\brief This enables the analog input number 1.
Required before reading analog input number 1.
*/
void motion_enable_ain_1(void);
/*!
\brief This enables the analog input number 2.
Required before reading analog input number 2.
*/
void motion_enable_ain_2(void);
/*!
\brief This reads the analog input number 1.
analog input number 1 needs to be enabled before reading.
*/
int motion_read_ain_1(void);
/*!
\brief This reads the analog input number 2.
analog input number 2 needs to be enabled before reading.
*/
int motion_read_ain_2(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------
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.
---------------------------------------------------------------------------------*/
/*! \file paddle.h
\brief paddle device slot-2 addon support.
*/
#ifndef PADDLE_HEADER_INCLUDE
#define PADDLE_HEADER_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
/*! \fn bool paddleIsInserted()
\brief Check for the paddle
\return true if that's what is in the slot-2
*/
bool paddleIsInserted();
/*! \fn void paddleRead()
\brief Obtain the current paddle state
\return a u16 containing a 12bit number (fixed point fraction), incrementing for clockwise rotations and decrementing for counterclockwise
*/
u16 paddleRead();
//! Resets the paddle device. May change the current value to 0xFFF, 0x000, or 0x001. May perform other unknown internal reset operations. Normally not needed.
void paddleReset();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------------
$Id: pcx.h,v 1.4 2008-04-15 02:18:41 dovoto Exp $
Copyright (C) 2005
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.
---------------------------------------------------------------------------------*/
/*! \file pcx.h
\brief A simple 256 color pcx file loader.
*/
#ifndef PCX_H
#define PCX_H
typedef struct PCXHeader
{
char manufacturer; //should be 0
char version; //should be 5
char encoding; //should be 1
char bitsPerPixel; //should be 8
short int xmin,ymin; //coordinates for top left,bottom right
short int xmax,ymax;
short int hres; //resolution
short int vres;
char palette16[48]; //16 color palette if 16 color image
char reserved; //ignore
char colorPlanes; //ignore
short int bytesPerLine;
short int paletteYype; //should be 2
char filler[58]; //ignore
}__attribute__ ((packed)) PCXHeader, *pPCXHeader;
#ifdef __cplusplus
extern "C" {
#endif
/*! \brief Loads an image structure with data from PCX formatted data
\param pcx a pointer to the pcx file loaded into memory
\param image the image structure to fill in (the loader will allocate room for the palette and pixel data)
\return 1 on success, 0 on failure
*/
int loadPCX(const unsigned char* pcx, sImage* image);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2011
Tobias Weyand (0xtob)
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.
---------------------------------------------------------------------------------*/
/*! \file piano.h
\brief NDS Easy Piano option pack support.
*/
#ifndef PIANO_HEADER_INCLUDE
#define PIANO_HEADER_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#define PIANO_PAK (*(vu16 *)0x09FFFFFE)
#define PIANO_C BIT(0)
#define PIANO_CS BIT(1)
#define PIANO_D BIT(2)
#define PIANO_DS BIT(3)
#define PIANO_E BIT(4)
#define PIANO_F BIT(5)
#define PIANO_FS BIT(6)
#define PIANO_G BIT(7)
#define PIANO_GS BIT(8)
#define PIANO_A BIT(9)
#define PIANO_AS BIT(10)
#define PIANO_B BIT(13)
#define PIANO_C2 BIT(14)
/*! \fn bool pianoIsInserted()
\brief Check for piano option pack.
\return true if the cart in the GBA slot is the piano option pack.
*/
bool pianoIsInserted();
/*! \fn void pianoScanKeys()
\brief Obtain the current piano state.
Call this function once per main loop to use the piano functions.
*/
void pianoScanKeys();
//! Obtains the current piano keys held state
u16 pianoKeysHeld();
//! Obtains the current piano keys pressed state
u16 pianoKeysDown();
//! Obtains the current piano keys released state
u16 pianoKeysUp();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,115 @@
/*---------------------------------------------------------------------------------
PosTest.c -- Code for performing hardware position testing
Copyright (C) 2007
Gabe Ghearing (gabebear)
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.
---------------------------------------------------------------------------------*/
/*! \file postest.h
\brief Position Test Functions.<BR>
<div class="fileHeader">
The position test multiplies a given vector by the position matrix and returns the coords(x,y,z,w). The position test is really quick, about 10x faster than a box test.
</div>
*/
#ifndef POS_TEST_INCLUDE
#define POS_TEST_INCLUDE
#include <nds/arm9/video.h>
#include <nds/arm9/videoGL.h>
GL_STATIC_INL
/*! \brief true if the hardware is currently performing a position/vertex/box test.
\return whether a test is being performed
*/
bool PosTestBusy()
{
return (GFX_STATUS & BIT(0))!=0;
}
GL_STATIC_INL
/*! \brief Starts a position test asynchronously
\param x specifies x offset from the current modelview matrix
\param y specifies y offset from the current modelview matrix
\param z specifies z offset from the current modelview matrix
*/
void PosTest_Asynch(v16 x, v16 y, v16 z)
{
GFX_POS_TEST = VERTEX_PACK(x, y);
GFX_POS_TEST = z;
}
GL_STATIC_INL
/*! \brief Performs a position test
\param x specifies x offset from the current modelview matrix
\param y specifies y offset from the current modelview matrix
\param z specifies z offset from the current modelview matrix
*/
void PosTest(v16 x, v16 y, v16 z)
{
PosTest_Asynch(x,y,z);
while(PosTestBusy());
}
GL_STATIC_INL
/*! \brief Returns the distance from the camera of the last position test, pretty darn useful.
\return W magnitude
*/
int32 PosTestWresult()
{
return GFX_POS_RESULT[3];
}
GL_STATIC_INL
/*! \brief Returns absolute X position of the last position test (location if the modelview matrix was identity)
\return Absolute X position
*/
int32 PosTestXresult()
{
return GFX_POS_RESULT[0];
}
GL_STATIC_INL
/*! \brief Returns absolute Y position of the last position test (location if the modelview matrix was identity)
\return Absolute Y position
*/
int32 PosTestYresult()
{
return GFX_POS_RESULT[1];
}
GL_STATIC_INL
/*! \brief Returns absolute Z position of the last position test (location if the modelview matrix was identity)
\return Absolute Z position
*/
int32 PosTestZresult()
{
return GFX_POS_RESULT[2];
}
#endif // ifndef POS_TEST_INCLUDE

View File

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2005
Michael Noland (joat)
Jason Rogers (dovoto)
Dave Murphy (WinterMute)
Mike Parks (BigRedPimp)
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.
---------------------------------------------------------------------------------*/
/*! \file rumble.h
\brief nds rumble option pak support.
*/
#ifndef RUMBLE_HEADER_INCLUDE
#define RUMBLE_HEADER_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#define RUMBLE_PAK (*(vuint16 *)0x08000000)
#define WARIOWARE_PAK (*(vuint16 *)0x080000C4)
#define WARIOWARE_ENABLE (*(vuint16 *)0x080000C6)
typedef enum {
RUMBLE,
WARIOWARE
}RUMBLE_TYPE;
/*! \fn bool isRumbleInserted(void);
\brief Check for rumble option pak.
\return true if the cart in the GBA slot is a Rumble option pak.
*/
bool isRumbleInserted(void);
/*! \fn void setRumble(bool position);
\param position Alternates position of the actuator in the pak
\brief Fires the rumble actuator.
*/
void setRumble(bool position);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------
sassert.h -- definitons for DS assertions
Copyright (C) 2013
Dave Murphy (WinterMute)
Jason Rogers (Dovoto)
Michael Theall (mtheall)
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.
---------------------------------------------------------------------------------*/
/*! \file sassert.h
\brief Simple assertion with a message conplies to nop if NDEBUG is defined
*/
#ifndef _sassert_h_
#define _sassert_h_
#ifdef __cplusplus
extern "C" {
#endif
#include "_ansi.h"
#undef sassert
#ifdef NDEBUG /* required by ANSI standard */
#define sassert(e, ...) ((void)0)
#else
//! Causes a blue screen of death if e is not true with the msg "msg" displayed
#define sassert(e,...) ((e) ? (void)0 : __sassert (__FILE__, __LINE__, #e, __VA_ARGS__))
#endif /* NDEBUG */
void __sassert(const char *fileName, int lineNumber, const char* conditionString, const char* format, ...)
__attribute__((format(printf,4,5)));
#ifdef __cplusplus
}
#endif
#endif // _sassert_h_

View File

@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------------
Sound Functions
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.
---------------------------------------------------------------------------------*/
#ifndef _sound_h_
#define _sound_h_
/*! \file sound.h
\brief A simple sound playback library for the DS. Provides functionality
for starting and stopping sound effects from the ARM9 side as well as access
to PSG and noise hardware. Maxmod should be used in most music and sound effect
situations.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <nds/ndstypes.h>
typedef void (* MicCallback)(void* completedBuffer, int length);
/*! \brief Sound formats used by the DS */
typedef enum {
SoundFormat_16Bit = 1, /*!< 16-bit PCM */
SoundFormat_8Bit = 0, /*!< 8-bit PCM */
SoundFormat_PSG = 3, /*!< PSG (programmable sound generator?) */
SoundFormat_ADPCM = 2 /*!< IMA ADPCM compressed audio */
}SoundFormat;
/*! \brief Microphone recording formats DS */
typedef enum {
MicFormat_8Bit = 1, /*!< 8-bit PCM */
MicFormat_12Bit = 0 /*!< 12-bit PCM */
}MicFormat;
/*! \brief PSG Duty cycles used by the PSG hardware */
typedef enum {
DutyCycle_0 = 7, /*!< 0.0% duty cycle */
DutyCycle_12 = 0, /*!< 12.5% duty cycle */
DutyCycle_25 = 1, /*!< 25.0% duty cycle */
DutyCycle_37 = 2, /*!< 37.5% duty cycle */
DutyCycle_50 = 3, /*!< 50.0% duty cycle */
DutyCycle_62 = 4, /*!< 62.5% duty cycle */
DutyCycle_75 = 5, /*!< 75.0% duty cycle */
DutyCycle_87 = 6 /*!< 87.5% duty cycle */
}DutyCycle;
/*! \fn void soundEnable(void)
\brief Enables Sound on the DS. Should be called prior to
attempting sound playback
*/
void soundEnable(void);
/*! \fn void soundDisable(void)
\brief Disables Sound on the DS.
*/
void soundDisable(void);
/*! \fn int soundPlaySample(const void* data, SoundFormat format, u32 dataSize, u16 freq, u8 volume, u8 pan, bool loop, u16 loopPoint);
\brief Plays a sound in the specified format at the specified frequency.
\param data A pointer to the sound data
\param format The format of the data (only 16-bit and 8-bit pcm and ADPCM formats are supported by this function)
\param dataSize The size in bytes of the sound data
\param freq The frequency in Hz of the sample
\param volume The channel volume. 0 to 127 (min to max)
\param pan The channel pan 0 to 127 (left to right with 64 being centered)
\param loop If true, the sample will loop playing once then repeating starting at the offset stored in loopPoint
\param loopPoint The offset for the sample loop to restart when repeating
\return An integer id coresponding to the channel of playback. This value can be used to pause, resume, or kill the sound
as well as adjust volume, pan, and frequency
*/
int soundPlaySample(const void* data, SoundFormat format, u32 dataSize, u16 freq, u8 volume, u8 pan, bool loop, u16 loopPoint);
/*! \fn int soundPlayPSG(DutyCycle cycle, u16 freq, u8 volume, u8 pan);
\brief Pause a tone with the specified properties
\param cycle The DutyCycle of the sound wave
\param freq The frequency in Hz of the sample
\param volume The channel volume. 0 to 127 (min to max)
\param pan The channel pan 0 to 127 (left to right with 64 being centered)
\return An integer id coresponding to the channel of playback. This value can be used to pause, resume, or kill the sound
as well as adjust volume, pan, and frequency
*/
int soundPlayPSG(DutyCycle cycle, u16 freq, u8 volume, u8 pan);
/*! \fn int soundPlayNoise(u16 freq, u8 volume, u8 pan);
\brief Plays white noise with the specified parameters
\param freq The frequency in Hz of the sample
\param volume The channel volume. 0 to 127 (min to max)
\param pan The channel pan 0 to 127 (left to right with 64 being centered)
\return An integer id coresponding to the channel of playback. This value can be used to pause, resume, or kill the sound
as well as adjust volume, pan, and frequency
*/
int soundPlayNoise(u16 freq, u8 volume, u8 pan);
/*! \fn void soundPause(int soundId)
\brief Pause the sound specified by soundId
\param soundId The sound ID returned by play sound
*/
void soundPause(int soundId);
/*! \fn void soundSetWaveDuty(int soundId, DutyCycle cycle)
\brief Sets the Wave Duty of a PSG sound
\param soundId The sound ID returned by play sound
\param cycle The DutyCycle of the sound wave
*/
void soundSetWaveDuty(int soundId, DutyCycle cycle);
/*! \fn void soundKill(int soundId)
\brief Stops the sound specified by soundId and frees any resources allocated
\param soundId The sound ID returned by play sound
*/
void soundKill(int soundId);
/*! \fn void soundResume(int soundId)
\brief Resumes a paused sound
\param soundId The sound ID returned by play sound
*/
void soundResume(int soundId);
/*! \fn void soundSetVolume(int soundId, u8 volume)
\brief Sets the sound volume
\param soundId The sound ID returned by play sound
\param volume The new volume (0 to 127 min to max)
*/
void soundSetVolume(int soundId, u8 volume);
/*! \fn void soundSetPan(int soundId, u8 pan)
\brief Sets the sound pan
\param soundId The sound ID returned by play sound
\param pan The new pan value (0 to 127 left to right (64 = center))
*/
void soundSetPan(int soundId, u8 pan);
/*! \fn void soundSetFreq(int soundId, u16 freq)
\brief Sets the sound frequency
\param soundId The sound ID returned by play sound
\param freq The frequency in Hz
*/
void soundSetFreq(int soundId, u16 freq);
/*! \fn int soundMicRecord(void *buffer, u32 bufferLength, MicFormat format, int freq, MicCallback callback);
\brief Starts a microphone recording to a double buffer specified by buffer
\param buffer A pointer to the start of the double buffer
\param bufferLength The length of the buffer in bytes (both halfs of the double buffer)
\param format Microphone can record in 8 or 12 bit format. 12 bit is shifted up to 16 bit pcm
\param freq The sample frequency
\param callback This will be called every time the buffer is full or half full
\return Returns non zero for success.
*/
int soundMicRecord(void *buffer, u32 bufferLength, MicFormat format, int freq, MicCallback callback);
/*! \fn void soundMicOff(void)
\brief Stops the microphone from recording
*/
void soundMicOff(void);
#ifdef __cplusplus
}
#endif
#endif // _sound_h_

View File

@ -0,0 +1,646 @@
/*---------------------------------------------------------------------------------
sprite.h -- definitions for DS sprites
Copyright (C) 2007
Liran Nuna (LiraNuna)
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.
---------------------------------------------------------------------------------*/
/*! \file sprite.h
\brief nds sprite functionality.
*/
#ifndef _libnds_sprite_h_
#define _libnds_sprite_h_
#ifndef ARM9
#error Sprites are only available on the ARM9
#endif
#include "nds/ndstypes.h"
#include "nds/arm9/video.h"
#include "nds/memory.h"
#include "nds/system.h"
// Sprite control defines
// Attribute 0 consists of 8 bits of Y plus the following flags:
#define ATTR0_NORMAL (0<<8)
#define ATTR0_ROTSCALE (1<<8)
#define ATTR0_DISABLED (2<<8)
#define ATTR0_ROTSCALE_DOUBLE (3<<8)
#define ATTR0_TYPE_NORMAL (0<<10)
#define ATTR0_TYPE_BLENDED (1<<10)
#define ATTR0_TYPE_WINDOWED (2<<10)
#define ATTR0_BMP (3<<10)
#define ATTR0_MOSAIC (1<<12)
#define ATTR0_COLOR_16 (0<<13) //16 color in tile mode...16 bit in bitmap mode
#define ATTR0_COLOR_256 (1<<13)
#define ATTR0_SQUARE (0<<14)
#define ATTR0_WIDE (1<<14)
#define ATTR0_TALL (2<<14)
#define OBJ_Y(m) ((m)&0x00ff)
// Atribute 1 consists of 9 bits of X plus the following flags:
#define ATTR1_ROTDATA(n) ((n)<<9) // note: overlaps with flip flags
#define ATTR1_FLIP_X (1<<12)
#define ATTR1_FLIP_Y (1<<13)
#define ATTR1_SIZE_8 (0<<14)
#define ATTR1_SIZE_16 (1<<14)
#define ATTR1_SIZE_32 (2<<14)
#define ATTR1_SIZE_64 (3<<14)
#define OBJ_X(m) ((m)&0x01ff)
// Atribute 2 consists of the following:
#define ATTR2_PRIORITY(n) ((n)<<10)
#define ATTR2_PALETTE(n) ((n)<<12)
#define ATTR2_ALPHA(n) ((n)<<12)
/** \brief The blending mode of the sprite */
typedef enum
{
OBJMODE_NORMAL, /**< No special mode is on - Normal sprite state. */
OBJMODE_BLENDED, /**< Color blending is on - Sprite can use HW blending features. */
OBJMODE_WINDOWED, /**< Sprite can be seen only inside the sprite window. */
OBJMODE_BITMAP, /**< Sprite is not using tiles - per pixel image data. */
} ObjBlendMode;
/** \brief The shape of the sprite */
typedef enum {
OBJSHAPE_SQUARE, /**< Sprite shape is NxN (Height == Width). */
OBJSHAPE_WIDE, /**< Sprite shape is NxM with N > M (Height < Width). */
OBJSHAPE_TALL, /**< Sprite shape is NxM with N < M (Height > Width). */
OBJSHAPE_FORBIDDEN, /**< Sprite shape is undefined. */
} ObjShape;
/** \brief The size of the sprite */
typedef enum {
OBJSIZE_8, /**< Major sprite size is 8px. */
OBJSIZE_16, /**< Major sprite size is 16px. */
OBJSIZE_32, /**< Major sprite size is 32px. */
OBJSIZE_64, /**< Major sprite size is 64px. */
} ObjSize;
/** \brief The color mode of the sprite */
typedef enum {
OBJCOLOR_16, /**< sprite has 16 colors. */
OBJCOLOR_256, /**< sprite has 256 colors. */
} ObjColMode;
/** \brief The priority of the sprite */
typedef enum {
OBJPRIORITY_0, /**< sprite priority level 0 - highest. */
OBJPRIORITY_1, /**< sprite priority level 1. */
OBJPRIORITY_2, /**< sprite priority level 2. */
OBJPRIORITY_3, /**< sprite priority level 3 - lowest. */
} ObjPriority;
//! A bitfield of sprite attribute goodness...ugly to look at but not so bad to use.
typedef union SpriteEntry
{
struct
{
struct
{
u16 y :8; /**< Sprite Y position. */
union
{
struct
{
u8 :1;
bool isHidden :1; /**< Sprite is hidden (isRotoscale cleared). */
u8 :6;
};
struct
{
bool isRotateScale :1; /**< Sprite uses affine parameters if set. */
bool isSizeDouble :1; /**< Sprite bounds is doubled (isRotoscale set). */
ObjBlendMode blendMode :2; /**< Sprite object mode. */
bool isMosaic :1; /**< Enables mosaic effect if set. */
ObjColMode colorMode :1; /**< Sprite color mode. */
ObjShape shape :2; /**< Sprite shape. */
};
};
};
union {
struct {
u16 x :9; /**< Sprite X position. */
u8 :7;
};
struct {
u8 :8;
union {
struct {
u8 :4;
bool hFlip :1; /**< Flip sprite horizontally (isRotoscale cleared). */
bool vFlip :1; /**< Flip sprite vertically (isRotoscale cleared).*/
u8 :2;
};
struct {
u8 :1;
u8 rotationIndex :5; /**< Affine parameter number to use (isRotoscale set). */
ObjSize size :2; /**< Sprite size. */
};
};
};
};
struct
{
u16 gfxIndex :10;/**< Upper-left tile index. */
ObjPriority priority :2; /**< Sprite priority. */
u8 palette :4; /**< Sprite palette to use in paletted color modes. */
};
u16 attribute3; /* Unused! Four of those are used as a sprite rotation matrice */
};
struct {
uint16 attribute[3];
uint16 filler;
};
} SpriteEntry, * pSpriteEntry;
//! A sprite rotation entry.
typedef struct SpriteRotation
{
uint16 filler1[3]; /* Unused! Filler for the sprite entry attributes which overlap these */
int16 hdx; /**< The change in x per horizontal pixel */
uint16 filler2[3]; /* Unused! Filler for the sprite entry attributes which overlap these */
int16 vdx; /**< The change in y per horizontal pixel */
uint16 filler3[3]; /* Unused! Filler for the sprite entry attributes which overlap these */
int16 hdy; /**< The change in x per vertical pixel */
uint16 filler4[3]; /* Unused! Filler for the sprite entry attributes which overlap these */
int16 vdy; /**< The change in y per vertical pixel */
} SpriteRotation, * pSpriteRotation;
//! maximum number of sprites per engine available.
#define SPRITE_COUNT 128
//! maximum number of affine matrices per engine available.
#define MATRIX_COUNT 32
//is this union still used?
typedef union OAMTable {
SpriteEntry oamBuffer[SPRITE_COUNT];
SpriteRotation matrixBuffer[MATRIX_COUNT];
} OAMTable;
//! Enumerates all sizes supported by the 2D engine.
typedef enum {
SpriteSize_8x8 = (OBJSIZE_8 << 14) | (OBJSHAPE_SQUARE << 12) | (8*8>>5), //!< 8x8
SpriteSize_16x16 = (OBJSIZE_16 << 14) | (OBJSHAPE_SQUARE << 12) | (16*16>>5), //!< 16x16
SpriteSize_32x32 = (OBJSIZE_32 << 14) | (OBJSHAPE_SQUARE << 12) | (32*32>>5), //!< 32x32
SpriteSize_64x64 = (OBJSIZE_64 << 14) | (OBJSHAPE_SQUARE << 12) | (64*64>>5), //!< 64x64
SpriteSize_16x8 = (OBJSIZE_8 << 14) | (OBJSHAPE_WIDE << 12) | (16*8>>5), //!< 16x8
SpriteSize_32x8 = (OBJSIZE_16 << 14) | (OBJSHAPE_WIDE << 12) | (32*8>>5), //!< 32x8
SpriteSize_32x16 = (OBJSIZE_32 << 14) | (OBJSHAPE_WIDE << 12) | (32*16>>5), //!< 32x16
SpriteSize_64x32 = (OBJSIZE_64 << 14) | (OBJSHAPE_WIDE << 12) | (64*32>>5), //!< 64x32
SpriteSize_8x16 = (OBJSIZE_8 << 14) | (OBJSHAPE_TALL << 12) | (8*16>>5), //!< 8x16
SpriteSize_8x32 = (OBJSIZE_16 << 14) | (OBJSHAPE_TALL << 12) | (8*32>>5), //!< 8x32
SpriteSize_16x32 = (OBJSIZE_32 << 14) | (OBJSHAPE_TALL << 12) | (16*32>>5), //!< 16x32
SpriteSize_32x64 = (OBJSIZE_64 << 14) | (OBJSHAPE_TALL << 12) | (32*64>>5) //!< 32x64
}SpriteSize;
#define SPRITE_SIZE_SHAPE(size) (((size) >> 12) & 0x3)
#define SPRITE_SIZE_SIZE(size) (((size) >> 14) & 0x3)
#define SPRITE_SIZE_PIXELS(size) (((size) & 0xFFF) << 5)
//! Graphics memory layout options.
typedef enum{
SpriteMapping_1D_32 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_32 | (0 << 28) | 0, /**< 1D tile mapping 32 byte boundary between offset */
SpriteMapping_1D_64 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_64 | (1 << 28) | 1, /**< 1D tile mapping 64 byte boundary between offset */
SpriteMapping_1D_128 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_128 | (2 << 28) | 2, /**< 1D tile mapping 128 byte boundary between offset */
SpriteMapping_1D_256 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_256 | (3 << 28) | 3, /**< 1D tile mapping 256 byte boundary between offset */
SpriteMapping_2D = DISPLAY_SPR_2D | (4 << 28), /**< 2D tile mapping 32 byte boundary between offset */
SpriteMapping_Bmp_1D_128 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_128 | DISPLAY_SPR_1D_BMP |DISPLAY_SPR_1D_BMP_SIZE_128 | (5 << 28) | 2,/**< 1D bitmap mapping 128 byte boundary between offset */
SpriteMapping_Bmp_1D_256 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_256 | DISPLAY_SPR_1D_BMP |DISPLAY_SPR_1D_BMP_SIZE_256 | (6 << 28) | 3,/**< 1D bitmap mapping 256 byte boundary between offset */
SpriteMapping_Bmp_2D_128 = DISPLAY_SPR_2D | DISPLAY_SPR_2D_BMP_128 | (7 << 28) | 2, /**< 2D bitmap mapping 128 pixels wide bitmap */
SpriteMapping_Bmp_2D_256 = DISPLAY_SPR_2D | DISPLAY_SPR_2D_BMP_256 | (int)(8U << 28) | 3 /**< 2D bitmap mapping 256 pixels wide bitmap */
}SpriteMapping;
//! Color formats for sprite graphics.
typedef enum{
SpriteColorFormat_16Color = OBJCOLOR_16,/**< 16 colors per sprite*/
SpriteColorFormat_256Color = OBJCOLOR_256,/**< 256 colors per sprite*/
SpriteColorFormat_Bmp = OBJMODE_BITMAP/**< 16-bit sprites*/
}SpriteColorFormat;
typedef struct AllocHeader
{
u16 nextFree;
u16 size;
}AllocHeader;
//this struct can be made smaller by rearanging the members.
/** \brief Holds the state for a 2D sprite engine.
There are two of these objects, oamMain and oamSub and these must be passed in to all oam functions.
*/
typedef struct OamState
{
int gfxOffsetStep; /**< The distance between tiles as 2^gfxOffsetStep */
s16 firstFree; /**< pointer to the first free block of tiles */
AllocHeader *allocBuffer; /**< array, allocation buffer for graphics allocation */
s16 allocBufferSize; /**< current size of the allocation buffer */
union
{
SpriteEntry *oamMemory; /**< pointer to shadow oam memory */
SpriteRotation *oamRotationMemory; /**< pointer to shadow oam memory for rotation */
};
SpriteMapping spriteMapping; //!< the mapping of the oam.
}OamState;
#ifdef __cplusplus
extern "C" {
#endif
//!oamMain an object representing the main 2D engine
extern OamState oamMain;
//!oamSub an object representing the sub 2D engine
extern OamState oamSub;
/**
* \brief convert a VRAM address to an oam offset
* \param oam must be: &oamMain or &oamSub
* \param offset the video memory address of the sprite graphics (not an offset)
*/
unsigned int oamGfxPtrToOffset(OamState *oam, const void* offset);
/**
* \brief Initializes the 2D sprite engine In order to mix tiled and bitmap sprites
use SpriteMapping_Bmp_1D_128 or SpriteMapping_Bmp_1D_256. This will set mapping for both
to 1D and give same sized boundaries so the sprite gfx allocation will function. VBlank IRQ must
be enabled for this function to work.
* \param oam must be: &oamMain or &oamSub
* \param mapping the mapping mode
* \param extPalette if true the engine sets up extended palettes for 8bpp sprites
*/
void oamInit(OamState* oam, SpriteMapping mapping, bool extPalette);
/**
* \brief Disables sprite rendering
* \param oam must be: &oamMain or &oamSub
*/
void oamDisable(OamState* oam );
/**
* \brief Enables sprite rendering
* \param oam must be: &oamMain or &oamSub
*/
void oamEnable(OamState* oam );
/**
* \brief translates an oam offset into a video ram address
* \param oam must be: &oamMain or &oamSub
* \param gfxOffsetIndex the index to compute
* \return the address in vram corresponding to the supplied offset
*/
u16* oamGetGfxPtr(OamState* oam, int gfxOffsetIndex);
/**
* \brief Allocates graphics memory for the supplied sprite attributes
* \param oam must be: &oamMain or &oamSub
* \param size the size of the sprite to allocate
* \param colorFormat the color format of the sprite
* \return the address in vram of the allocated sprite
*/
u16* oamAllocateGfx(OamState *oam, SpriteSize size, SpriteColorFormat colorFormat);
/**
* \brief free vram memory obtained with oamAllocateGfx.
* \param oam must be: &oamMain or &oamSub
* \param gfxOffset a vram offset obtained from oamAllocateGfx
*/
void oamFreeGfx(OamState *oam, const void* gfxOffset);
static inline
/**
* \brief sets engine A global sprite mosaic
* \param dx (0-15) horizontal mosaic value
* \param dy (0-15) horizontal mosaic value
*/
void oamSetMosaic(unsigned int dx, unsigned int dy) {
sassert(dx < 16 && dy < 16, "Mosaic range must be 0 to 15");
mosaicShadow = ( mosaicShadow & 0x00ff) | (dx << 8)| (dy << 12);
REG_MOSAIC = mosaicShadow;
}
static inline
/**
* \brief sets engine B global sprite mosaic
* \param dx (0-15) horizontal mosaic value
* \param dy (0-15) horizontal mosaic value
*/
void oamSetMosaicSub(unsigned int dx, unsigned int dy){
sassert(dx < 16 && dy < 16, "Mosaic range must be 0 to 15");
mosaicShadowSub = ( mosaicShadowSub & 0x00ff) | (dx << 8)| (dy << 12);
REG_MOSAIC_SUB = mosaicShadowSub;
}
/**
* \brief sets an oam entry to the supplied values
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0 - 127]
* \param x the x location of the sprite in pixels
* \param y the y location of the sprite in pixels
* \param priority The sprite priority (0 to 3)
* \param palette_alpha the palette number for 4bpp and 8bpp (extended palette mode), or the alpha value for bitmap sprites (bitmap sprites must specify a value > 0 to display) [0-15]
* \param size the size of the sprite
* \param format the color format of the sprite
* \param gfxOffset the video memory address of the sprite graphics (not an offset)
* \param affineIndex affine index to use (if < 0 or > 31 the sprite will be unrotated)
* \param sizeDouble if affineIndex >= 0 this will be used to double the sprite size for rotation
* \param hide if non zero (true) the sprite will be hidden
* \param vflip flip the sprite vertically
* \param hflip flip the sprite horizontally
* \param mosaic if true mosaic will be applied to the sprite
*/
void oamSet(OamState* oam, int id, int x, int y, int priority, int palette_alpha, SpriteSize size, SpriteColorFormat format, const void* gfxOffset, int affineIndex, bool sizeDouble, bool hide, bool hflip, bool vflip, bool mosaic);
static inline
/**
* \brief sets an oam entry to the supplied x,y position
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param x the x location of the sprite in pixels
* \param y the y location of the sprite in pixels
*/
void oamSetXY(OamState* oam, int id, int x, int y)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetXY() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetXY() index is out of bounds, must be 0-127");
oam->oamMemory[id].x = x;
oam->oamMemory[id].y = y;
}
static inline
/**
* \brief sets an oam entry to the supplied priority
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param priority The sprite priority [0-3]
*/
void oamSetPriority(OamState* oam, int id, int priority)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetPriority() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetPriority() index is out of bounds, must be 0-127");
sassert(priority >= 0 && priority < 4, "oamSetPriority() priority is out of bounds, must be 0-3");
oam->oamMemory[id].priority = (ObjPriority)priority;
}
static inline
/**
* \brief sets a paletted oam entry to the supplied palette
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param palette the palette number for 4bpp and 8bpp (extended palette mode) sprites [0-15]
*/
void oamSetPalette(OamState* oam, int id, int palette)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetPalette() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetPalette() index is out of bounds, must be 0-127");
sassert(palette >= 0 && palette < 16, "oamSetPalette() palette is out of bounds, must be 0-15");
sassert(oam->oamMemory[id].blendMode != (ObjBlendMode)SpriteColorFormat_Bmp,
"oamSetPalette() cannot set palette on a bitmapped sprite");
oam->oamMemory[id].palette = palette;
}
static inline
/**
* \brief sets a bitmapped oam entry to the supplied transparency
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param alpha the alpha value for bitmap sprites (bitmap sprites must specify a value > 0 to display) [0-15]
*/
void oamSetAlpha(OamState* oam, int id, int alpha)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetAlpha() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetAlpha() index is out of bounds, must be 0-127");
sassert(alpha >= 0 && alpha < 16, "oamSetAlpha() alpha is out of bounds, must be 0-15");
sassert(oam->oamMemory[id].blendMode == (ObjBlendMode)SpriteColorFormat_Bmp,
"oamSetAlpha() cannot set alpha on a paletted sprite");
oam->oamMemory[id].palette = alpha;
}
static inline
/**
* \brief sets an oam entry to the supplied shape/size/pointer
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param size the size of the sprite
* \param format the color format of the sprite
* \param gfxOffset the video memory address of the sprite graphics (not an offset)
*/
void oamSetGfx(OamState* oam, int id, SpriteSize size, SpriteColorFormat format, const void* gfxOffset)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetGfx() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetGfx() index is out of bounds, must be 0-127");
oam->oamMemory[id].shape = (ObjShape)SPRITE_SIZE_SHAPE(size);
oam->oamMemory[id].size = (ObjSize)SPRITE_SIZE_SIZE(size);
oam->oamMemory[id].gfxIndex = oamGfxPtrToOffset(oam, gfxOffset);
if(format != SpriteColorFormat_Bmp)
oam->oamMemory[id].colorMode = (ObjColMode)format;
else
{
oam->oamMemory[id].blendMode = (ObjBlendMode)format;
oam->oamMemory[id].colorMode = (ObjColMode)0;
}
}
static inline
/**
* \brief sets an oam entry to the supplied affine index
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param affineIndex affine index to use (if < 0 or > 31 the sprite will be unrotated)
* \param sizeDouble if affineIndex >= 0 and < 32 this will be used to double the sprite size for rotation
*/
void oamSetAffineIndex(OamState* oam, int id, int affineIndex, bool sizeDouble)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetAffineIndex() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetAffineIndex() index is out of bounds, must be 0-127");
if(affineIndex >= 0 && affineIndex < 32)
{
oam->oamMemory[id].rotationIndex = affineIndex;
oam->oamMemory[id].isSizeDouble = sizeDouble;
oam->oamMemory[id].isRotateScale = true;
}
else
{
oam->oamMemory[id].isSizeDouble = false;
oam->oamMemory[id].isRotateScale = false;
}
}
static inline
/**
* \brief sets an oam entry to the supplied hidden state
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param hide if non zero (true) the sprite will be hidden
*/
void oamSetHidden(OamState* oam, int id, bool hide)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetHidden() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetHidden() index is out of bounds, must be 0-127");
sassert(!oam->oamMemory[id].isRotateScale, "oamSetHidden() cannot set hide on a RotateScale sprite");
oam->oamMemory[id].isHidden = hide ? true : false;
}
static inline
/**
* \brief sets an oam entry to the supplied flipping
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param hflip flip the sprite horizontally
* \param vflip flip the sprite vertically
*/
void oamSetFlip(OamState* oam, int id, bool hflip, bool vflip)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetFlip() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetFlip() index is out of bounds, must be 0-127");
sassert(!oam->oamMemory[id].isRotateScale, "oamSetFlip() cannot set flip on a RotateScale sprite");
oam->oamMemory[id].hFlip = hflip ? true : false;
oam->oamMemory[id].vFlip = vflip ? true : false;
}
static inline
/**
* \brief sets an oam entry to enable or disable mosaic
* \param oam must be: &oamMain or &oamSub
* \param id the oam number to be set [0-127]
* \param mosaic if true mosaic will be applied to the sprite
*/
void oamSetMosaicEnabled(OamState* oam, int id, bool mosaic)
{
sassert(oam == &oamMain || oam == &oamSub, "oamSetMosaicEnabled() oam must be &oamMain or &oamSub");
sassert(id >= 0 && id < SPRITE_COUNT, "oamSetMosaicEnabled() index is out of bounds, must be 0-127");
oam->oamMemory[id].isMosaic = mosaic ? true : false;
}
/**
* \brief Hides the sprites in the supplied range: if count is zero all 128 sprites will be hidden
* \param oam must be: &oamMain or &oamSub
* \param start The first index to clear
* \param count The number of sprites to clear
*/
void oamClear(OamState *oam, int start, int count);
static inline
/**
\brief Hides a single sprite.
\param oam the oam engine, must be &oamMain or &oamSub.
\param index the index of the sprite, must be 0-127.
*/
void oamClearSprite(OamState *oam, int index)
{
sassert(index >= 0 && index < SPRITE_COUNT, "oamClearSprite() index is out of bounds, must be 0-127");
oam->oamMemory[index].attribute[0] = ATTR0_DISABLED;
}
/**
* \brief causes oam memory to be updated...must be called during vblank if using oam api
* \param oam must be: &oamMain or &oamSub
*/
void oamUpdate(OamState* oam);
/**
* \brief sets the specified rotation scale entry
* \param oam must be: &oamMain or &oamSub
* \param rotId the rotation entry to set
* \param angle the ccw angle to rotate [-32768 - 32767]
* \param sx the inverse scale factor in the x direction
* \param sy the inverse scale factor in the y direction
*/
void oamRotateScale(OamState* oam, int rotId, int angle, int sx, int sy);
static inline
/**
* \brief allows you to directly sets the affine transformation matrix.
*
* with this, you have more freedom to set the matrix, but it might be more difficult to use if
* you're not used to affine transformation matrix. this will erase the previous matrix stored at rotId.
*
* \param oam The oam engine, must be &oamMain or &oamSub.
* \param rotId The id of the rotscale item you want to change, must be 0-31.
* \param hdx The change in x per horizontal pixel.
* \param hdy The change in y per horizontal pixel.
* \param vdx The change in x per vertical pixel.
* \param vdy The change in y per vertical pixel.
*/
void oamAffineTransformation(OamState* oam, int rotId, int hdx, int hdy, int vdx, int vdy)
{
sassert(rotId >= 0 && rotId < 32, "oamAffineTransformation() rotId is out of bounds, must be 0-31");
oam->oamRotationMemory[rotId].hdx = hdx;
oam->oamRotationMemory[rotId].vdx = vdx;
oam->oamRotationMemory[rotId].hdy = hdy;
oam->oamRotationMemory[rotId].vdy = vdy;
}
/**
\brief determines the number of fragments in the allocation engine
\param oam must be: &oamMain or &oamSub
\return the number of fragments.
*/
int oamCountFragments(OamState *oam);
void oamAllocReset(OamState *oam);
#ifdef __cplusplus
}
#endif
#endif // _libnds_sprite_h_

View File

@ -0,0 +1,144 @@
/*---------------------------------------------------------------------------------
Trig_lut.h provides access to external precompiled trig look up tables
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.
---------------------------------------------------------------------------------*/
#ifndef TRIG_LUT_H
#define TRIG_LUT_H
#include <nds/ndstypes.h>
/*! \file trig_lut.h
\brief fixed point trig functions. Angle can be in the range of -32768 to
32767. There are 32768 degrees in the unit circle used by nds. To convert
between standard degrees (360 per circle):
angle = degreesToAngle(angleInDegrees);
or
angle = angleInDegrees * 32768 / 360;
This unit of measure is sometimes refered to as a binary radian (brad) or binary
degree. It allows for more precise representation of angle and faster calculation
as the DS has no floating point processor.
*/
#ifdef __cplusplus
extern "C" {
#endif
//! number of degrees in a circle.
#define DEGREES_IN_CIRCLE (1 << 15)
/*! \brief convert a fixed point number to an integer.
\param n the number the number to convert.
\param bits the number of bits used for the decimal part.
\return the integer part.
*/
#define fixedToInt(n, bits) ((int)((n)>>(bits)))
/*! \brief converts an integer to a fixed point number.
\param n the integer to convert.
\param bits the number of bits used for the decimal part.
\return the fixed point number.
*/
#define intToFixed(n, bits) ((int)((n)<<(bits)))
/*! \brief converts a floating point number to a fixed point number.
\param n the floating point number to convert.
\param bits the number of bits used for the decimal part.
\return the fixed point number.
*/
#define floatToFixed(n, bits) ((int)((n) * (float)(1<<(bits))))
/*! \brief converts a fixed point number to a floating point number.
\param n the fixed point number to convert.
\param bits the number of bits used for the decimal part.
\return the floating point number.
*/
#define fixedToFloat(n, bits) (((float)(n)) / (float)(1<<(bits)))
/*! \brief removes the decimal part of a fixed point number.
\param n the fixed point number.
\param bits the number of bits used for the decimal part.
\return a fixed point number with 0 as a decimal part.
*/
#define floorFixed(n, bits) ((int)((n) & ~(((1 << (bits)) - 1))))
//! convert an angle in 360 degree format to the format used by libnds.
#define degreesToAngle(degrees) ((degrees) * DEGREES_IN_CIRCLE / 360)
//! converts an angle in the format used by libnds in the 360 degree format.
#define angleToDegrees(angle) ((angle) * 360 / DEGREES_IN_CIRCLE)
/*! \brief fixed point sine
\param angle (-32768 to 32767)
\return 4.12 fixed point number with the range [-1, 1]
*/
s16 sinLerp(s16 angle);
/*! \brief fixed point cosine
\param angle (-32768 to 32767)
\return 4.12 fixed point number with the range [-1, 1]
*/
s16 cosLerp(s16 angle);
/*! \brief fixed point tangent
\param angle (-32768 to 32767)
\return 20.12 fixed point number with the range [-81.483, 524287.999]
*/
s32 tanLerp(s16 angle);
/*! \brief fixed point arcsin
\param par 4.12 fixed point number with the range [-1, 1]
\return s16 angle (-32768 to 32767)
*/
s16 asinLerp(s16 par);
/*! \brief fixed point arccos
\param par 4.12 fixed point number with the range [-1, 1]
\return s16 angle (-32768 to 32767)
*/
s16 acosLerp(s16 par);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,811 @@
/*---------------------------------------------------------------------------------
Video registers and defines
Copyright (C) 2005 - 2010
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.
---------------------------------------------------------------------------------*/
/*! \file video.h
\brief contains the basic defnitions for controlling the video hardware.
\section Intro Intro
Video.h contains the basic defnitions for controlling the video hardware.
\section VideoRAM Video Ram Banks
The Nintendo DS has nine banks of video memory which may be put to a variety of
uses. They can hold the graphics for your sprites, the textures for your 3D
space ships, the tiles for your 2D platformer, or a direct map of pixels to
render to the screen. Figuring out how to effectively utilize this flexible but
limited amount of memory will be one the most challenging endeavors you will
face early homebrew development.
The nine banks can be utilized as enumerated by the VRAM types. Banks are labeled
A-I. In order to utilize 2D or 3D texture graphics, memory must be mapped for
these purposes.
For instance: If you initialize a 2D background on the main engine you will be
expected to define both an offset for its map data and an offset for its tile
graphics (bitmapped backgrounds differ slightly). These offsets are referenced
from the start of 2D background graphics memory. On the main display 2D background
graphics begin at 0x6000000.
Without mapping a VRAM bank to this location data written to your background
tile and map offsets will be lost.
VRAM banks can be mapped to specific addresses for specific purposes. In our
case, any of the 4 main banks and several of the smaller ones can be mapped to
the main 2D background engine.(A B C and D banks are referred to collectivly as main
because they are 128KB and flexible in usage)
<pre>
vramSetBankA(VRAM_A_MAIN_BG);
</pre>
The above would map the 128KB of VRAM_A to 0x6000000 for use as main background
graphics and maps (you can offset the mapping as well and the available offsets
are defined in the VRAM_A_TYPE enumeration)
\section VRAMSizes Video Ram Bank sizes
- VRAM A: 128kb
- VRAM B: 128kb
- VRAM C: 128kb
- VRAM D: 128kb
- VRAM E: 64kb
- VRAM F: 16kb
- VRAM G: 16kb
- VRAM H: 32kb
- VRAM I: 16kb
*/
#ifndef VIDEO_ARM9_INCLUDE
#define VIDEO_ARM9_INCLUDE
#ifndef ARM9
#error Video is only available on the ARM9
#endif
#include <nds/ndstypes.h>
#include <nds/arm9/sassert.h>
#ifdef __cplusplus
extern "C" {
#endif
extern u16 mosaicShadow;
extern u16 mosaicShadowSub;
#define BG_PALETTE ((u16*)0x05000000) /**< \brief background palette memory*/
#define BG_PALETTE_SUB ((u16*)0x05000400) /**< \brief background palette memory (sub engine)*/
#define SPRITE_PALETTE ((u16*)0x05000200) /**< \brief sprite palette memory*/
#define SPRITE_PALETTE_SUB ((u16*)0x05000600) /**< \brief sprite palette memory (sub engine)*/
#define BG_GFX ((u16*)0x6000000) /**< \brief background graphics memory*/
#define BG_GFX_SUB ((u16*)0x6200000) /**< \brief background graphics memory (sub engine)*/
#define SPRITE_GFX ((u16*)0x6400000) /**< \brief sprite graphics memory*/
#define SPRITE_GFX_SUB ((u16*)0x6600000) /**< \brief sprite graphics memory (sub engine)*/
#define VRAM_0 ((u16*)0x6000000)
#define VRAM ((u16*)0x6800000)
#define VRAM_A ((u16*)0x6800000)/*!< \brief pointer to vram bank A mapped as LCD*/
#define VRAM_B ((u16*)0x6820000)/*!< \brief pointer to vram bank B mapped as LCD*/
#define VRAM_C ((u16*)0x6840000)/*!< \brief pointer to vram bank C mapped as LCD*/
#define VRAM_D ((u16*)0x6860000)/*!< \brief pointer to vram bank D mapped as LCD*/
#define VRAM_E ((u16*)0x6880000)/*!< \brief pointer to vram bank E mapped as LCD*/
#define VRAM_F ((u16*)0x6890000)/*!< \brief pointer to vram bank F mapped as LCD*/
#define VRAM_G ((u16*)0x6894000)/*!< \brief pointer to vram bank G mapped as LCD*/
#define VRAM_H ((u16*)0x6898000)/*!< \brief pointer to vram bank H mapped as LCD*/
#define VRAM_I ((u16*)0x68A0000)/*!< \brief pointer to vram bank I mapped as LCD*/
#define OAM ((u16*)0x07000000)/*!< \brief pointer to Object Attribute Memory*/
#define OAM_SUB ((u16*)0x07000400)/*!< \brief pointer to Object Attribute Memory (Sub engine)*/
// macro creates a 15 bit color from 3x5 bit components
/** \brief Macro to convert 5 bit r g b components into a single 15 bit RGB triplet */
#define RGB15(r,g,b) ((r)|((g)<<5)|((b)<<10))
#define RGB5(r,g,b) ((r)|((g)<<5)|((b)<<10))
#define RGB8(r,g,b) (((r)>>3)|(((g)>>3)<<5)|(((b)>>3)<<10))
/** \brief Macro to convert 5 bit r g b components plus 1 bit alpha into a single 16 bit ARGB triplet */
#define ARGB16(a, r, g, b) ( ((a) << 15) | (r)|((g)<<5)|((b)<<10))
/** \brief Screen height in pixels */
#define SCREEN_HEIGHT 192
/** \brief Screen width in pixels */
#define SCREEN_WIDTH 256
// Vram Control
#define VRAM_CR (*(vu32*)0x04000240)
#define VRAM_A_CR (*(vu8*)0x04000240)
#define VRAM_B_CR (*(vu8*)0x04000241)
#define VRAM_C_CR (*(vu8*)0x04000242)
#define VRAM_D_CR (*(vu8*)0x04000243)
#define VRAM_EFG_CR (*(vu32*)0x04000244)
#define VRAM_E_CR (*(vu8*)0x04000244)
#define VRAM_F_CR (*(vu8*)0x04000245)
#define VRAM_G_CR (*(vu8*)0x04000246)
#define WRAM_CR (*(vu8*)0x04000247)
#define VRAM_H_CR (*(vu8*)0x04000248)
#define VRAM_I_CR (*(vu8*)0x04000249)
#define VRAM_ENABLE (1<<7)
#define VRAM_OFFSET(n) ((n)<<3)
//! Allowed VRAM bank A modes
typedef enum {
VRAM_A_LCD = 0, //!< maps vram a to lcd.
VRAM_A_MAIN_BG = 1, //!< maps vram a to main engine background slot 0.
VRAM_A_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0), //!< maps vram a to main engine background slot 0.
VRAM_A_MAIN_BG_0x06020000 = 1 | VRAM_OFFSET(1), //!< maps vram a to main engine background slot 1.
VRAM_A_MAIN_BG_0x06040000 = 1 | VRAM_OFFSET(2), //!< maps vram a to main engine background slot 2.
VRAM_A_MAIN_BG_0x06060000 = 1 | VRAM_OFFSET(3), //!< maps vram a to main engine background slot 3.
VRAM_A_MAIN_SPRITE = 2, //!< maps vram a to main engine sprites slot 0.
VRAM_A_MAIN_SPRITE_0x06400000 = 2 | VRAM_OFFSET(0), //!< maps vram a to main engine sprites slot 0.
VRAM_A_MAIN_SPRITE_0x06420000 = 2 | VRAM_OFFSET(1), //!< maps vram a to main engine sprites slot 1.
VRAM_A_TEXTURE = 3, //!< maps vram a to 3d texture slot 0.
VRAM_A_TEXTURE_SLOT0 = 3 | VRAM_OFFSET(0), //!< maps vram a to 3d texture slot 0.
VRAM_A_TEXTURE_SLOT1 = 3 | VRAM_OFFSET(1), //!< maps vram a to 3d texture slot 1.
VRAM_A_TEXTURE_SLOT2 = 3 | VRAM_OFFSET(2), //!< maps vram a to 3d texture slot 2.
VRAM_A_TEXTURE_SLOT3 = 3 | VRAM_OFFSET(3) //!< maps vram a to 3d texture slot 3.
} VRAM_A_TYPE;
//! Allowed VRAM bank B modes
typedef enum {
VRAM_B_LCD = 0, //!< maps vram b to lcd.
VRAM_B_MAIN_BG = 1 | VRAM_OFFSET(1), //!< maps vram b to main engine background slot 1.
VRAM_B_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0), //!< maps vram b to main engine background slot 0.
VRAM_B_MAIN_BG_0x06020000 = 1 | VRAM_OFFSET(1), //!< maps vram b to main engine background slot 1.
VRAM_B_MAIN_BG_0x06040000 = 1 | VRAM_OFFSET(2), //!< maps vram b to main engine background slot 2.
VRAM_B_MAIN_BG_0x06060000 = 1 | VRAM_OFFSET(3), //!< maps vram b to main engine background slot 3.
VRAM_B_MAIN_SPRITE = 2, //!< maps vram b to main engine sprites slot 0.
VRAM_B_MAIN_SPRITE_0x06400000 = 2 | VRAM_OFFSET(0), //!< maps vram b to main engine sprites slot 0.
VRAM_B_MAIN_SPRITE_0x06420000 = 2 | VRAM_OFFSET(1), //!< maps vram b to main engine sprites slot 1.
VRAM_B_TEXTURE = 3 | VRAM_OFFSET(1), //!< maps vram b to 3d texture slot 1.
VRAM_B_TEXTURE_SLOT0 = 3 | VRAM_OFFSET(0), //!< maps vram b to 3d texture slot 0.
VRAM_B_TEXTURE_SLOT1 = 3 | VRAM_OFFSET(1), //!< maps vram b to 3d texture slot 1.
VRAM_B_TEXTURE_SLOT2 = 3 | VRAM_OFFSET(2), //!< maps vram b to 3d texture slot 2.
VRAM_B_TEXTURE_SLOT3 = 3 | VRAM_OFFSET(3) //!< maps vram b to 3d texture slot 3.
} VRAM_B_TYPE;
//! Allowed VRAM bank C modes
typedef enum {
VRAM_C_LCD = 0, //!< maps vram c to lcd.
VRAM_C_MAIN_BG = 1 | VRAM_OFFSET(2), //!< maps vram c to main engine background slot 2.
VRAM_C_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0), //!< maps vram c to main engine background slot 0.
VRAM_C_MAIN_BG_0x06020000 = 1 | VRAM_OFFSET(1), //!< maps vram c to main engine background slot 1.
VRAM_C_MAIN_BG_0x06040000 = 1 | VRAM_OFFSET(2), //!< maps vram c to main engine background slot 2.
VRAM_C_MAIN_BG_0x06060000 = 1 | VRAM_OFFSET(3), //!< maps vram c to main engine background slot 3.
VRAM_C_ARM7 = 2, //!< maps vram c to ARM7 workram slot 0.
VRAM_C_ARM7_0x06000000 = 2 | VRAM_OFFSET(0), //!< maps vram c to ARM7 workram slot 0.
VRAM_C_ARM7_0x06020000 = 2 | VRAM_OFFSET(1), //!< maps vram c to ARM7 workram slot 1.
VRAM_C_SUB_BG = 4, //!< maps vram c to sub engine background slot 0.
VRAM_C_SUB_BG_0x06200000 = 4 | VRAM_OFFSET(0), //!< maps vram c to sub engine background slot 0.
VRAM_C_TEXTURE = 3 | VRAM_OFFSET(2), //!< maps vram c to 3d texture slot 2.
VRAM_C_TEXTURE_SLOT0 = 3 | VRAM_OFFSET(0), //!< maps vram c to 3d texture slot 0.
VRAM_C_TEXTURE_SLOT1 = 3 | VRAM_OFFSET(1), //!< maps vram c to 3d texture slot 1.
VRAM_C_TEXTURE_SLOT2 = 3 | VRAM_OFFSET(2), //!< maps vram c to 3d texture slot 2.
VRAM_C_TEXTURE_SLOT3 = 3 | VRAM_OFFSET(3) //!< maps vram c to 3d texture slot 3.
} VRAM_C_TYPE;
//! Allowed VRAM bank D modes
typedef enum {
VRAM_D_LCD = 0, //!< maps vram d to lcd.
VRAM_D_MAIN_BG = 1 | VRAM_OFFSET(3), //!< maps vram d to main engine background slot 3.
VRAM_D_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0), //!< maps vram d to main engine background slot 0.
VRAM_D_MAIN_BG_0x06020000 = 1 | VRAM_OFFSET(1), //!< maps vram d to main engine background slot 1.
VRAM_D_MAIN_BG_0x06040000 = 1 | VRAM_OFFSET(2), //!< maps vram d to main engine background slot 2.
VRAM_D_MAIN_BG_0x06060000 = 1 | VRAM_OFFSET(3), //!< maps vram d to main engine background slot 3.
VRAM_D_ARM7 = 2 | VRAM_OFFSET(1), //!< maps vram d to ARM7 workram slot 1.
VRAM_D_ARM7_0x06000000 = 2 | VRAM_OFFSET(0), //!< maps vram d to ARM7 workram slot 0.
VRAM_D_ARM7_0x06020000 = 2 | VRAM_OFFSET(1), //!< maps vram d to ARM7 workram slot 1.
VRAM_D_SUB_SPRITE = 4, //!< maps vram d to sub engine sprites slot 0.
VRAM_D_TEXTURE = 3 | VRAM_OFFSET(3), //!< maps vram d to 3d texture slot 3.
VRAM_D_TEXTURE_SLOT0 = 3 | VRAM_OFFSET(0), //!< maps vram d to 3d texture slot 0.
VRAM_D_TEXTURE_SLOT1 = 3 | VRAM_OFFSET(1), //!< maps vram d to 3d texture slot 1.
VRAM_D_TEXTURE_SLOT2 = 3 | VRAM_OFFSET(2), //!< maps vram d to 3d texture slot 2.
VRAM_D_TEXTURE_SLOT3 = 3 | VRAM_OFFSET(3) //!< maps vram d to 3d texture slot 3.
} VRAM_D_TYPE;
//! Allowed VRAM bank E modes
typedef enum {
VRAM_E_LCD = 0, //!< maps vram e to lcd.
VRAM_E_MAIN_BG = 1, //!< maps vram e to main engine background first half of slot 0.
VRAM_E_MAIN_SPRITE = 2, //!< maps vram e to main engine sprites first half of slot 0.
VRAM_E_TEX_PALETTE = 3, //!< maps vram e to 3d texture palette slot 0-3.
VRAM_E_BG_EXT_PALETTE = 4, //!< maps vram e to main engine background extended palette.
} VRAM_E_TYPE;
//! Allowed VRAM bank F modes
typedef enum {
VRAM_F_LCD = 0, //!< maps vram f to lcd.
VRAM_F_MAIN_BG = 1, //!< maps vram f to main engine background first part of slot 0.
VRAM_F_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0), //!< maps vram f to main engine background first part of slot 0.
VRAM_F_MAIN_BG_0x06004000 = 1 | VRAM_OFFSET(1), //!< maps vram f to main engine background second part of slot 0.
VRAM_F_MAIN_BG_0x06010000 = 1 | VRAM_OFFSET(2), //!< maps vram f to main engine background second half of slot 0.
VRAM_F_MAIN_BG_0x06014000 = 1 | VRAM_OFFSET(3), //!< maps vram f to main engine background second part of second half of slot 0.
VRAM_F_MAIN_SPRITE = 2, //!< maps vram f to main engine sprites first part of slot 0.
VRAM_F_MAIN_SPRITE_0x06400000 = 2 | VRAM_OFFSET(0), //!< maps vram f to main engine sprites first part of slot 0.
VRAM_F_MAIN_SPRITE_0x06404000 = 2 | VRAM_OFFSET(1), //!< maps vram f to main engine sprites second part of slot 0.
VRAM_F_MAIN_SPRITE_0x06410000 = 2 | VRAM_OFFSET(2), //!< maps vram f to main engine sprites second half of slot 0.
VRAM_F_MAIN_SPRITE_0x06414000 = 2 | VRAM_OFFSET(3), //!< maps vram f to main engine sprites second part of second half of slot 0.
VRAM_F_TEX_PALETTE = 3, //!< maps vram f to 3d texture palette slot 0.
VRAM_F_TEX_PALETTE_SLOT0 = 3 | VRAM_OFFSET(0), //!< maps vram f to 3d texture palette slot 0.
VRAM_F_TEX_PALETTE_SLOT1 = 3 | VRAM_OFFSET(1), //!< maps vram f to 3d texture palette slot 1.
VRAM_F_TEX_PALETTE_SLOT4 = 3 | VRAM_OFFSET(2), //!< maps vram f to 3d texture palette slot 4.
VRAM_F_TEX_PALETTE_SLOT5 = 3 | VRAM_OFFSET(3), //!< maps vram f to 3d texture palette slot 5.
VRAM_F_BG_EXT_PALETTE = 4, //!< maps vram f to main engine background extended palette slot 0 and 1.
VRAM_F_BG_EXT_PALETTE_SLOT01 = 4 | VRAM_OFFSET(0), //!< maps vram f to main engine background extended palette slot 0 and 1.
VRAM_F_BG_EXT_PALETTE_SLOT23 = 4 | VRAM_OFFSET(1), //!< maps vram f to main engine background extended palette slot 2 and 3.
VRAM_F_SPRITE_EXT_PALETTE = 5, //!< maps vram f to main engine sprites extended palette.
} VRAM_F_TYPE;
//! Allowed VRAM bank G modes
typedef enum {
VRAM_G_LCD = 0, //!< maps vram g to lcd.
VRAM_G_MAIN_BG = 1, //!< maps vram g to main engine background first part of slot 0.
VRAM_G_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0), //!< maps vram g to main engine background first part of slot 0.
VRAM_G_MAIN_BG_0x06004000 = 1 | VRAM_OFFSET(1), //!< maps vram g to main engine background second part of slot 0.
VRAM_G_MAIN_BG_0x06010000 = 1 | VRAM_OFFSET(2), //!< maps vram g to main engine background second half of slot 0.
VRAM_G_MAIN_BG_0x06014000 = 1 | VRAM_OFFSET(3), //!< maps vram g to main engine background second part of second half of slot 0.
VRAM_G_MAIN_SPRITE = 2, //!< maps vram g to main engine sprites first part of slot 0.
VRAM_G_MAIN_SPRITE_0x06400000 = 2 | VRAM_OFFSET(0), //!< maps vram g to main engine sprites first part of slot 0.
VRAM_G_MAIN_SPRITE_0x06404000 = 2 | VRAM_OFFSET(1), //!< maps vram g to main engine sprites second part of slot 0.
VRAM_G_MAIN_SPRITE_0x06410000 = 2 | VRAM_OFFSET(2), //!< maps vram g to main engine sprites second half of slot 0.
VRAM_G_MAIN_SPRITE_0x06414000 = 2 | VRAM_OFFSET(3), //!< maps vram g to main engine sprites second part of second half of slot 0.
VRAM_G_TEX_PALETTE = 3, //!< maps vram g to 3d texture palette slot 0.
VRAM_G_TEX_PALETTE_SLOT0 = 3 | VRAM_OFFSET(0), //!< maps vram g to 3d texture palette slot 0.
VRAM_G_TEX_PALETTE_SLOT1 = 3 | VRAM_OFFSET(1), //!< maps vram g to 3d texture palette slot 1.
VRAM_G_TEX_PALETTE_SLOT4 = 3 | VRAM_OFFSET(2), //!< maps vram g to 3d texture palette slot 4.
VRAM_G_TEX_PALETTE_SLOT5 = 3 | VRAM_OFFSET(3), //!< maps vram g to 3d texture palette slot 5.
VRAM_G_BG_EXT_PALETTE = 4, //!< maps vram g to main engine background extended palette slot 0 and 1.
VRAM_G_BG_EXT_PALETTE_SLOT01 = 4 | VRAM_OFFSET(0), //!< maps vram g to main engine background extended palette slot 0 and 1.
VRAM_G_BG_EXT_PALETTE_SLOT23 = 4 | VRAM_OFFSET(1), //!< maps vram g to main engine background extended palette slot 2 and 3.
VRAM_G_SPRITE_EXT_PALETTE = 5, //!< maps vram g to main engine sprites extended palette.
} VRAM_G_TYPE;
//! Allowed VRAM bank H modes
typedef enum {
VRAM_H_LCD = 0, //!< maps vram h to lcd.
VRAM_H_SUB_BG = 1, //!< maps vram h to sub engine background first 2 parts of slot 0.
VRAM_H_SUB_BG_EXT_PALETTE = 2, //!< maps vram h to sub engine background extended palette.
} VRAM_H_TYPE;
//! Allowed VRAM bank I modes
typedef enum {
VRAM_I_LCD = 0, //!< maps vram i to lcd.
VRAM_I_SUB_BG_0x06208000 = 1, //!< maps vram i to sub engine background thirth part of slot 0.
VRAM_I_SUB_SPRITE = 2, //!< maps vram i to sub engine sprites.
VRAM_I_SUB_SPRITE_EXT_PALETTE = 3, //!< maps vram i to sub engine sprites extended palette.
}VRAM_I_TYPE;
/** \brief an array of 256 15-bit RGB values*/
typedef u16 _palette[256];
/** \brief An array of 16 256-color palettes */
typedef _palette _ext_palette[16];
/** \brief Used for accessing vram E as an extended palette */
#define VRAM_E_EXT_PALETTE ((_ext_palette *)VRAM_E)
/** \brief Used for accessing vram F as an extended palette */
#define VRAM_F_EXT_PALETTE ((_ext_palette *)VRAM_F)
/** \brief Used for accessing vram G as an extended palette */
#define VRAM_G_EXT_PALETTE ((_ext_palette *)VRAM_G)
/** \brief Used for accessing vram H as an extended palette */
#define VRAM_H_EXT_PALETTE ((_ext_palette *)VRAM_H)
/** \brief Used for accessing vram F as an extended sprite palette */
#define VRAM_F_EXT_SPR_PALETTE ((_palette *)VRAM_F)
/** \brief Used for accessing vram G as an extended sprite palette */
#define VRAM_G_EXT_SPR_PALETTE ((_palette *)VRAM_G)
/** \brief Used for accessing vram I as an extended sprite palette */
#define VRAM_I_EXT_SPR_PALETTE ((_palette *)VRAM_I)
/** \brief Set the main 4 bank modes.
* \param a mapping mode of VRAM_A
* \param b mapping mode of VRAM_B
* \param c mapping mode of VRAM_C
* \param d mapping mode of VRAM_D
* \return the previous mode
*/
u32 vramSetPrimaryBanks(VRAM_A_TYPE a, VRAM_B_TYPE b, VRAM_C_TYPE c, VRAM_D_TYPE d);
__attribute__ ((deprecated)) u32 vramSetMainBanks(VRAM_A_TYPE a, VRAM_B_TYPE b, VRAM_C_TYPE c, VRAM_D_TYPE d);
/** \brief Set E,F,G bank modes.
* \param e mapping mode of VRAM_E
* \param f mapping mode of VRAM_F
* \param g mapping mode of VRAM_G
* \return the previous mode
*/
u32 vramSetBanks_EFG(VRAM_E_TYPE e, VRAM_F_TYPE f, VRAM_G_TYPE g);
/** \brief Set VRAM banks to basic default.
\return the previous settings
*/
u32 vramDefault();
/** \brief Restore the main 4 bank modes.
\param vramTemp restores the main 4 banks to the value encoded in vramTemp (returned from vramSetMainBanks)
*/
void vramRestorePrimaryBanks(u32 vramTemp);
__attribute__ ((deprecated)) void vramRestoreMainBanks(u32 vramTemp);
/** \brief Restore the E,F,G bank modes.
\param vramTemp restores the E,F,G bank modes to the value encoded in vramTemp (returned from vramSetBanks_EFG)
*/
void vramRestoreBanks_EFG(u32 vramTemp);
static inline
/** \brief Set bank A to the indicated mapping.
\param a the mapping of the bank
*/
void vramSetBankA(VRAM_A_TYPE a) { VRAM_A_CR = VRAM_ENABLE | a; }
static inline
/** \brief Set bank B to the indicated mapping.
\param b the mapping of the bank
*/
void vramSetBankB(VRAM_B_TYPE b) { VRAM_B_CR = VRAM_ENABLE | b; }
static inline
/** \brief Set bank C to the indicated mapping.
\param c the mapping of the bank
*/
void vramSetBankC(VRAM_C_TYPE c) { VRAM_C_CR = VRAM_ENABLE | c; }
static inline
/** \brief Set bank D to the indicated mapping.
\param d the mapping of the bank
*/
void vramSetBankD(VRAM_D_TYPE d) { VRAM_D_CR = VRAM_ENABLE | d; }
static inline
/** \brief Set bank E to the indicated mapping.
\param e the mapping of the bank
*/
void vramSetBankE(VRAM_E_TYPE e) { VRAM_E_CR = VRAM_ENABLE | e; }
static inline
/** \brief Set bank F to the indicated mapping.
\param f the mapping of the bank
*/
void vramSetBankF(VRAM_F_TYPE f) { VRAM_F_CR = VRAM_ENABLE | f; }
static inline
/** \brief Set bank G to the indicated mapping.
\param g the mapping of the bank
*/
void vramSetBankG(VRAM_G_TYPE g) { VRAM_G_CR = VRAM_ENABLE | g; }
static inline
/** \brief Set bank H to the indicated mapping.
\param h the mapping of the bank
*/
void vramSetBankH(VRAM_H_TYPE h) { VRAM_H_CR = VRAM_ENABLE | h; }
static inline
/** \brief Set bank I to the indicated mapping.
\param i the mapping of the bank
*/
void vramSetBankI(VRAM_I_TYPE i) { VRAM_I_CR = VRAM_ENABLE | i; }
// Display control registers
#define REG_DISPCNT (*(vu32*)0x04000000)
#define REG_DISPCNT_SUB (*(vu32*)0x04001000)
#define ENABLE_3D (1<<3)
#define DISPLAY_ENABLE_SHIFT 8
#define DISPLAY_BG0_ACTIVE (1 << 8)
#define DISPLAY_BG1_ACTIVE (1 << 9)
#define DISPLAY_BG2_ACTIVE (1 << 10)
#define DISPLAY_BG3_ACTIVE (1 << 11)
#define DISPLAY_SPR_ACTIVE (1 << 12)
#define DISPLAY_WIN0_ON (1 << 13)
#define DISPLAY_WIN1_ON (1 << 14)
#define DISPLAY_SPR_WIN_ON (1 << 15)
/** \enum VideoMode
* \brief The allowed video modes of the 2D processors <br>
*
<div class="fixedFont"><pre>
Main 2D engine
______________________________
|Mode | BG0 | BG1 | BG2 |BG3 | T = Text
| 0 | T | T | T | T | R = Rotation
| 1 | T | T | T | R | E = Extended Rotation
| 2 | T | T | R | R | L = Large Bitmap background
| 3 | T | T | T | E |
| 4 | T | T | R | E |
| 5 | T | T | E | E |
| 6 | | L | | |
-----------------------------
Sub 2D engine
______________________________
|Mode | BG0 | BG1 | BG2 |BG3 |
| 0 | T | T | T | T |
| 1 | T | T | T | R |
| 2 | T | T | R | R |
| 3 | T | T | T | E |
| 4 | T | T | R | E |
| 5 | T | T | E | E |
-----------------------------
</pre></div>
*/
typedef enum
{
MODE_0_2D = 0x10000, /**< \brief 4 2D backgrounds */
MODE_1_2D = 0x10001, /**< \brief 4 2D backgrounds */
MODE_2_2D = 0x10002, /**< \brief 4 2D backgrounds */
MODE_3_2D = 0x10003, /**< \brief 4 2D backgrounds */
MODE_4_2D = 0x10004, /**< \brief 4 2D backgrounds */
MODE_5_2D = 0x10005, /**< \brief 4 2D backgrounds */
MODE_6_2D = 0x10006, /**< \brief 4 2D backgrounds */
MODE_0_3D = (0x10000 | DISPLAY_BG0_ACTIVE | ENABLE_3D), /**< \brief 3 2D backgrounds 1 3D background (Main engine only)*/
MODE_1_3D = (0x10001 | DISPLAY_BG0_ACTIVE | ENABLE_3D), /**< \brief 3 2D backgrounds 1 3D background (Main engine only)*/
MODE_2_3D = (0x10002 | DISPLAY_BG0_ACTIVE | ENABLE_3D), /**< \brief 3 2D backgrounds 1 3D background (Main engine only)*/
MODE_3_3D = (0x10003 | DISPLAY_BG0_ACTIVE | ENABLE_3D), /**< \brief 3 2D backgrounds 1 3D background (Main engine only)*/
MODE_4_3D = (0x10004 | DISPLAY_BG0_ACTIVE | ENABLE_3D), /**< \brief 3 2D backgrounds 1 3D background (Main engine only)*/
MODE_5_3D = (0x10005 | DISPLAY_BG0_ACTIVE | ENABLE_3D), /**< \brief 3 2D backgrounds 1 3D background (Main engine only)*/
MODE_6_3D = (0x10006 | DISPLAY_BG0_ACTIVE | ENABLE_3D), /**< \brief 3 2D backgrounds 1 3D background (Main engine only)*/
MODE_FIFO = (3<<16), /**< \brief video display from main memory */
MODE_FB0 = (0x00020000), /**< \brief video display directly from VRAM_A in LCD mode */
MODE_FB1 = (0x00060000), /**< \brief video display directly from VRAM_B in LCD mode */
MODE_FB2 = (0x000A0000), /**< \brief video display directly from VRAM_C in LCD mode */
MODE_FB3 = (0x000E0000) /**< \brief video display directly from VRAM_D in LCD mode */
}VideoMode;
// main display only
#define DISPLAY_SPR_HBLANK (1 << 23)
#define DISPLAY_SPR_1D_LAYOUT (1 << 4)
#define DISPLAY_SPR_1D (1 << 4)
#define DISPLAY_SPR_2D (0 << 4)
#define DISPLAY_SPR_1D_BMP (4 << 4)
#define DISPLAY_SPR_2D_BMP_128 (0 << 4)
#define DISPLAY_SPR_2D_BMP_256 (2 << 4)
#define DISPLAY_SPR_1D_SIZE_32 (0 << 20)
#define DISPLAY_SPR_1D_SIZE_64 (1 << 20)
#define DISPLAY_SPR_1D_SIZE_128 (2 << 20)
#define DISPLAY_SPR_1D_SIZE_256 (3 << 20)
#define DISPLAY_SPR_1D_BMP_SIZE_128 (0 << 22)
#define DISPLAY_SPR_1D_BMP_SIZE_256 (1 << 22)
//mask to clear all attributes related to sprites from display control
#define DISPLAY_SPRITE_ATTR_MASK ((7 << 4) | (7 << 20) | (1 << 31))
#define DISPLAY_SPR_EXT_PALETTE (1 << 31)
#define DISPLAY_BG_EXT_PALETTE (1 << 30)
#define DISPLAY_SCREEN_OFF (1 << 7)
// The next two defines only apply to MAIN 2d engine
// In tile modes, this is multiplied by 64KB and added to BG_TILE_BASE
// In all bitmap modes, it is not used.
#define DISPLAY_CHAR_BASE(n) (((n)&7)<<24)
// In tile modes, this is multiplied by 64KB and added to BG_MAP_BASE
// In bitmap modes, this is multiplied by 64KB and added to BG_BMP_BASE
// In large bitmap modes, this is not used
#define DISPLAY_SCREEN_BASE(n) (((n)&7)<<27)
static inline
/** \brief the main 2D engine video mode
* \param mode the video mode to set
*/
void videoSetMode( u32 mode) { REG_DISPCNT = mode; }
static inline
/** \brief the sub 2D engine video mode
* \param mode the video mode to set
*/
void videoSetModeSub( u32 mode) { REG_DISPCNT_SUB = mode; }
static inline
/** \brief return the main 2D engine video mode
* \return the video mode
*/
int videoGetMode() {return (REG_DISPCNT & 0x30007);}
static inline
/** \brief return the main 2D engine video mode
* \return the video mode
*/
int videoGetModeSub() {return (REG_DISPCNT_SUB & 0x30007);}
static inline
/** \brief determine if 3D is enabled
* \return true if 3D is enabled
*/
bool video3DEnabled() {return (REG_DISPCNT & ENABLE_3D) ? true : false;}
static inline
/** \brief enables the specified background on the main engine
* \param number the background number (0-3)
*/
void videoBgEnable(int number) {REG_DISPCNT |= 1 << (DISPLAY_ENABLE_SHIFT + number);}
static inline
/** \brief enables the specified background on the sub engine
* \param number the background number (0-3)
*/
void videoBgEnableSub(int number) {REG_DISPCNT_SUB |= 1 << (DISPLAY_ENABLE_SHIFT + number);}
static inline
/** \brief disables the specified background on the main engine
* \param number the background number (0-3)
*/
void videoBgDisable(int number) {REG_DISPCNT &= ~(1 << (DISPLAY_ENABLE_SHIFT + number));}
static inline
/** \brief disables the specified background on the sub engine
* \param number the background number (0-3)
*/
void videoBgDisableSub(int number) {REG_DISPCNT_SUB &= ~(1 << (DISPLAY_ENABLE_SHIFT + number));}
/** \brief sets the screens brightness.
\param screen 1 = main screen, 2 = subscreen, 3 = both
\param level -16 = black, 0 = full brightness, 16 = white
*/
void setBrightness(int screen, int level);
static inline
/**
\brief sets the backdrop color of the main engine.
the backdrop color is displayed when all pixels at a given location are transparent
(no sprite or background is visible there).
\param color the color that the backdrop of the main engine should display.
*/
void setBackdropColor(const u16 color)
{
BG_PALETTE[0] = color;
}
static inline
/**
\brief sets the backdrop color of the sub engine.
the backdrop color is displayed when all pixels at a given location are transparent
(no sprite or background is visible there).
\param color the color that the backdrop of the sub engine should display.
*/
void setBackdropColorSub(const u16 color)
{
BG_PALETTE_SUB[0] = color;
}
#define REG_MASTER_BRIGHT (*(vu16*)0x0400006C)
#define REG_MASTER_BRIGHT_SUB (*(vu16*)0x0400106C)
// Window 0
#define WIN0_X0 (*(vu8*)0x04000041)
#define WIN0_X1 (*(vu8*)0x04000040)
#define WIN0_Y0 (*(vu8*)0x04000045)
#define WIN0_Y1 (*(vu8*)0x04000044)
// Window 1
#define WIN1_X0 (*(vu8*)0x04000043)
#define WIN1_X1 (*(vu8*)0x04000042)
#define WIN1_Y0 (*(vu8*)0x04000047)
#define WIN1_Y1 (*(vu8*)0x04000046)
#define WIN_IN (*(vu16*)0x04000048)
#define WIN_OUT (*(vu16*)0x0400004A)
// Window 0
#define SUB_WIN0_X0 (*(vu8*)0x04001041)
#define SUB_WIN0_X1 (*(vu8*)0x04001040)
#define SUB_WIN0_Y0 (*(vu8*)0x04001045)
#define SUB_WIN0_Y1 (*(vu8*)0x04001044)
// Window 1
#define SUB_WIN1_X0 (*(vu8*)0x04001043)
#define SUB_WIN1_X1 (*(vu8*)0x04001042)
#define SUB_WIN1_Y0 (*(vu8*)0x04001047)
#define SUB_WIN1_Y1 (*(vu8*)0x04001046)
#define SUB_WIN_IN (*(vu16*)0x04001048)
#define SUB_WIN_OUT (*(vu16*)0x0400104A)
#define REG_MOSAIC (*(vu16*)0x0400004C)
#define REG_MOSAIC_SUB (*(vu16*)0x0400104C)
#define REG_BLDCNT (*(vu16*)0x04000050)
#define REG_BLDY (*(vu16*)0x04000054)
#define REG_BLDALPHA (*(vu16*)0x04000052)
#define REG_BLDCNT_SUB (*(vu16*)0x04001050)
#define REG_BLDALPHA_SUB (*(vu16*)0x04001052)
#define REG_BLDY_SUB (*(vu16*)0x04001054)
#define BLEND_NONE (0<<6)
#define BLEND_ALPHA (1<<6)
#define BLEND_FADE_WHITE (2<<6)
#define BLEND_FADE_BLACK (3<<6)
#define BLEND_SRC_BG0 (1<<0)
#define BLEND_SRC_BG1 (1<<1)
#define BLEND_SRC_BG2 (1<<2)
#define BLEND_SRC_BG3 (1<<3)
#define BLEND_SRC_SPRITE (1<<4)
#define BLEND_SRC_BACKDROP (1<<5)
#define BLEND_DST_BG0 (1<<8)
#define BLEND_DST_BG1 (1<<9)
#define BLEND_DST_BG2 (1<<10)
#define BLEND_DST_BG3 (1<<11)
#define BLEND_DST_SPRITE (1<<12)
#define BLEND_DST_BACKDROP (1<<13)
// Display capture control
#define REG_DISPCAPCNT (*(vu32*)0x04000064)
#define REG_DISP_MMEM_FIFO (*(vu32*)0x04000068)
#define DCAP_ENABLE BIT(31)
#define DCAP_MODE(n) (((n) & 3) << 29)
#define DCAP_SRC_ADDR(n) (((n) & 3) << 26)
#define DCAP_SRC(n) (((n) & 3) << 24)
#define DCAP_SRC_A(n) (((n) & 1) << 24)
#define DCAP_SRC_B(n) (((n) & 1) << 25)
#define DCAP_SIZE(n) (((n) & 3) << 20)
#define DCAP_OFFSET(n) (((n) & 3) << 18)
#define DCAP_BANK(n) (((n) & 3) << 16)
#define DCAP_B(n) (((n) & 0x1F) << 8)
#define DCAP_A(n) (((n) & 0x1F) << 0)
#define DCAP_MODE_A (0)
#define DCAP_MODE_B (1)
#define DCAP_MODE_BLEND (2)
#define DCAP_SRC_A_COMPOSITED (0)
#define DCAP_SRC_A_3DONLY (1)
#define DCAP_SRC_B_VRAM (0)
#define DCAP_SRC_B_DISPFIFO (1)
#define DCAP_SIZE_128x128 (0)
#define DCAP_SIZE_256x64 (1)
#define DCAP_SIZE_256x128 (2)
#define DCAP_SIZE_256x192 (3)
#define DCAP_BANK_VRAM_A (0)
#define DCAP_BANK_VRAM_B (1)
#define DCAP_BANK_VRAM_C (2)
#define DCAP_BANK_VRAM_D (3)
// 3D core control
#define GFX_CONTROL (*(vu16*) 0x04000060)
#define GFX_RDLINES_COUNT (*(vu32*) 0x04000320)
#define GFX_FIFO (*(vu32*) 0x04000400)
#define GFX_STATUS (*(vu32*) 0x04000600)
#define GFX_COLOR (*(vu32*) 0x04000480)
#define GFX_VERTEX10 (*(vu32*) 0x04000490)
#define GFX_VERTEX_XY (*(vu32*) 0x04000494)
#define GFX_VERTEX_XZ (*(vu32*) 0x04000498)
#define GFX_VERTEX_YZ (*(vu32*) 0x0400049C)
#define GFX_VERTEX_DIFF (*(vu32*) 0x040004A0)
#define GFX_VERTEX16 (*(vu32*) 0x0400048C)
#define GFX_TEX_COORD (*(vu32*) 0x04000488)
#define GFX_TEX_FORMAT (*(vu32*) 0x040004A8)
#define GFX_PAL_FORMAT (*(vu32*) 0x040004AC)
#define GFX_CLEAR_COLOR (*(vu32*) 0x04000350)
#define GFX_CLEAR_DEPTH (*(vu16*) 0x04000354)
#define GFX_CLRIMAGE_OFFSET (*(vu16*) 0x04000356)
#define GFX_LIGHT_VECTOR (*(vu32*) 0x040004C8)
#define GFX_LIGHT_COLOR (*(vu32*) 0x040004CC)
#define GFX_NORMAL (*(vu32*) 0x04000484)
#define GFX_DIFFUSE_AMBIENT (*(vu32*) 0x040004C0)
#define GFX_SPECULAR_EMISSION (*(vu32*) 0x040004C4)
#define GFX_SHININESS (*(vu32*) 0x040004D0)
#define GFX_POLY_FORMAT (*(vu32*) 0x040004A4)
#define GFX_ALPHA_TEST (*(vu16*) 0x04000340)
#define GFX_BEGIN (*(vu32*) 0x04000500)
#define GFX_END (*(vu32*) 0x04000504)
#define GFX_FLUSH (*(vu32*) 0x04000540)
#define GFX_VIEWPORT (*(vu32*) 0x04000580)
#define GFX_TOON_TABLE ((vu16*) 0x04000380)
#define GFX_EDGE_TABLE ((vu16*) 0x04000330)
#define GFX_FOG_COLOR (*(vu32*) 0x04000358)
#define GFX_FOG_OFFSET (*(vu32*) 0x0400035C)
#define GFX_FOG_TABLE ((vu8*) 0x04000360)
#define GFX_BOX_TEST (*(vs32*) 0x040005C0)
#define GFX_POS_TEST (*(vu32*) 0x040005C4)
#define GFX_POS_RESULT ((vs32*) 0x04000620)
#define GFX_VEC_TEST (*(vu32*) 0x040005C8)
#define GFX_VEC_RESULT ((vs16*) 0x04000630)
#define GFX_BUSY (GFX_STATUS & BIT(27))
#define GFX_VERTEX_RAM_USAGE (*(vu16*) 0x04000606)
#define GFX_POLYGON_RAM_USAGE (*(vu16*) 0x04000604)
#define GFX_CUTOFF_DEPTH (*(vu16*)0x04000610)
// Matrix processor control
#define MATRIX_CONTROL (*(vu32*)0x04000440)
#define MATRIX_PUSH (*(vu32*)0x04000444)
#define MATRIX_POP (*(vu32*)0x04000448)
#define MATRIX_SCALE (*(vs32*) 0x0400046C)
#define MATRIX_TRANSLATE (*(vs32*) 0x04000470)
#define MATRIX_RESTORE (*(vu32*)0x04000450)
#define MATRIX_STORE (*(vu32*)0x0400044C)
#define MATRIX_IDENTITY (*(vu32*)0x04000454)
#define MATRIX_LOAD4x4 (*(vs32*) 0x04000458)
#define MATRIX_LOAD4x3 (*(vs32*) 0x0400045C)
#define MATRIX_MULT4x4 (*(vs32*) 0x04000460)
#define MATRIX_MULT4x3 (*(vs32*) 0x04000464)
#define MATRIX_MULT3x3 (*(vs32*) 0x04000468)
//matrix operation results
#define MATRIX_READ_CLIP ((vs32*) (0x04000640))
#define MATRIX_READ_VECTOR ((vs32*) (0x04000680))
#define POINT_RESULT ((vs32*) (0x04000620))
#define VECTOR_RESULT ((vu16*)(0x04000630))
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------------
window.h -- definitions for object and background windowing
Copyright (C) 2007
Dave Murphy (WinterMute)
Jason Rogers (Dovoto)
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.
---------------------------------------------------------------------------------*/
/*! \file window.h
\brief windowing support functions for objects and backgrounds
*/
#include <nds/ndstypes.h>
#include <nds/arm9/video.h>
#include <nds/arm9/sprite.h>
#include <nds/arm9/background.h>
#include <nds/arm9/sassert.h>
#include <nds/memory.h>
#include <nds/dma.h>
/*! \brief the supported windows*/
typedef enum {
WINDOW_0 = DISPLAY_WIN0_ON, //!< Window 0.
WINDOW_1 = DISPLAY_WIN1_ON, //!< Window 1
WINDOW_OBJ = DISPLAY_SPR_WIN_ON, //!< Object window
WINDOW_OUT = BIT(16), //!< Area outside all windows
}WINDOW;
#define WINDOW_MASK (WINDOW_0|WINDOW_1|WINDOW_OBJ)
static inline
/**
* \brief Enable the specified window(s)
* \param window The window to set bounds on (may be ORed together)
*/
void windowEnable(WINDOW w) { REG_DISPCNT |= w & WINDOW_MASK; }
static inline
/**
* \brief Enable the specified window(s)
* \param window The window to set bounds on (may be ORed together)
*/
void windowDisable(WINDOW w) { REG_DISPCNT &= ~(w & WINDOW_MASK); }
static inline
/**
* \brief Enable the specified window(s)
* \param window The window to set bounds on (may be ORed together)
*/
void windowEnableSub(WINDOW w) { REG_DISPCNT_SUB |= w & WINDOW_MASK; }
static inline
/**
* \brief Enable the specified window(s)
* \param window The window to set bounds on (may be ORed together)
*/
void windowDisableSub(WINDOW w) { REG_DISPCNT_SUB &= ~(w & WINDOW_MASK); }
/**
* \brief Set the windows bounds
* \param window The window to set bounds on
* \param left The X coordinate of the left hand side of the rectangle
* \param top The Y coordinate of the top of the rectangle
* \param right The X coordinate of the right hand side of the rectangle
* \param bottom The Y coordinate of the bottom of the rectangle
*/
void windowSetBounds(WINDOW window, u8 left, u8 top, u8 right, u8 bottom);
/**
* \brief Set the windows bounds (Sub engine)
* \param window The window to set bounds on
* \param left The X coordinate of the left hand side of the rectangle
* \param top The Y coordinate of the top of the rectangle
* \param right The X coordinate of the right hand side of the rectangle
* \param bottom The Y coordinate of the bottom of the rectangle
*/
void windowSetBoundsSub(WINDOW window, u8 left, u8 top, u8 right, u8 bottom);
/*! \brief Enables the window on the supplied background.
\param id
background id returned from bgInit or bgInitSub
\param window
the the window to enable
*/
void bgWindowEnable(int id, WINDOW window);
/*! \brief Disables the window on the supplied background.
\param id
background id returned from bgInit or bgInitSub
\param window
the the window to disable
*/
void bgWindowDisable(int id, WINDOW window);
/**
* \brief Enables the specified window.
* \param oam must be: &oamMain or &oamSub
* \param the window to enable
*/
void oamWindowEnable(OamState* oam, WINDOW w);
/**
* \brief Disables the specified window.
* \param oam must be: &oamMain or &oamSub
* \param the window to disable
*/
void oamWindowDisable(OamState* oam, WINDOW w);

View File

@ -0,0 +1,21 @@
#ifndef _ASMINC_H_
#define _ASMINC_H_
#if !__ASSEMBLER__
#error This header file is only for use in assembly files!
#endif // !__ASSEMBLER__
.macro BEGIN_ASM_FUNC name section=text
.section .\section\().\name\(), "ax", %progbits
.global \name
.type \name, %function
.align 2
\name:
.endm
#define ICACHE_SIZE 0x2000
#define DCACHE_SIZE 0x1000
#define CACHE_LINE_SIZE 32
#endif // _ASMINC_H_

View File

@ -0,0 +1,398 @@
/*---------------------------------------------------------------------------------
BIOS functions
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.
---------------------------------------------------------------------------------*/
#ifndef BIOS_H_INCLUDE
#define BIOS_H_INCLUDE
/*! \file bios.h
\brief Nintendo DS Bios functions
See gbatek for more information.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "nds/ndstypes.h"
/*! \brief Should return the header of a compressed stream of bytes.
The result is a word, with the size of decompressed data in bits 8-31,
and bits 0-7 are ignored. This value is also returned by the bios function, unless getResult is non-NULL and returns a negative value.
This useally returns the 4 bytes that source points to.
\param source A pointer to the compressed data.
\param dest A pointer to the space where the decompressed data should be copied to.
\param arg A callback value that gets passed to the bios function.
\return The header of the compressed data containing the length of the data and the compression type.
*/
typedef int (*getHeaderCallback)(u8 *source, u16 *dest, u32 arg);
/*! \brief Should verify the result after data got decompressed.
getResult is used to provide a result for the bios function, given the source pointer after all data has been read
(or if getSize < 0). Its value is only returned if negative, otherwise the typical result is used, so it is likely
some sort of error-checking procedure.
\param source The current source address.
\return 0 if it went right, or a negative number if something went wrong. value will be returned from bios function if value is negative.
*/
typedef int (*getResultCallback)(u8 * source);
/*! \brief Should returns a raw byte of the stream.
\param source A pointer to the byte.
\return A byte.
*/
typedef u8 (*getByteCallback)(u8 *source);
//! A struct that contains callback function pointers used by the decompression functions.
typedef struct DecompressionStream
{
getHeaderCallback getSize; //!< gets called to get the header of the stream.
getResultCallback getResult; //!< gets called to verify the result afterwards, can be NULL (no callback).
getByteCallback readByte; //!< gets called to get a byte of the compressed data.
//according to gbatek, there are 2 more callback pointers here.
} PACKED TDecompressionStream;
//! A struct and struct pointer with information about unpacking data.
typedef struct UnpackStruct
{
uint16 sourceSize; //!< in bytes
uint8 sourceWidth; //!< 1,2,4 or 8 bits.
uint8 destWidth; //!< 1,2,4,8,16 or 32 bits.
uint32 dataOffset; //!< bits 0-30 are added to all non-zero destination writes, unless bit 31 is set, which does it for zeros too.
} PACKED TUnpackStruct, * PUnpackStruct;
/*!
\brief resets the DS.
*/
void swiSoftReset(void);
/*!
\brief delays the code.
Delays for for a period X + Y*duration where X is the swi overhead and Y is a cycle of
<CODE><PRE>
loop:
sub r0, #1
bgt loop
</PRE></CODE>
of thumb fetches in BIOS memory
\param duration length of delay
\note Duration should be 1 or more, a duration of 0 is a huge delay.
*/
void swiDelay(uint32 duration);
/*!
\brief divides 2 numbers.
\param numerator signed integer to divide
\param divisor signed integer to divide by
\return numerator / divisor
*/
int swiDivide(int numerator, int divisor);
/*!
\brief calculate the remainder of an division.
\param numerator signed integer to divide
\param divisor signed integer to divide by
\return numerator % divisor
*/
int swiRemainder(int numerator, int divisor);
/*!
\brief divides 2 numbers and stores both the result and the remainder.
\param numerator signed integer to divide
\param divisor signed integer to divide by
\param result pointer to integer set to numerator / divisor
\param remainder pointer to integer set to numerator % divisor
*/
void swiDivMod(int numerator, int divisor, int * result, int * remainder);
//! copy in chunks of halfword size.
#define COPY_MODE_HWORD (0)
//! copy in chunks of word size.
#define COPY_MODE_WORD BIT(26)
//! copy a range of memory to another piece of memory
#define COPY_MODE_COPY (0)
//! fill a piece of memory with a value.
#define COPY_MODE_FILL BIT(24)
/*! \brief copies or fills some memory.
\param source pointer to transfer source or pointer to value to fill the memory with.
\param dest pointer to transfer destination.
\param flags bits(0-20): size of data to copy/fill in words,
or'd with the copy mode size (word or halfword) and type (copy or fill).
*/
void swiCopy(const void * source, void * dest, int flags);
/*! \brief copies or fills some memory.
can only copy in word chunks.
\param source pointer to transfer source or pointer to value to fill the memory with.
\param dest pointer to transfer destination.
\param flags bits(0-20): size of data to copy/fill in words,
or'd with the type (copy or fill).
\note Transfers more quickly than swiCopy, but has higher interrupt latency.
*/
void swiFastCopy(const void * source, void * dest, int flags);
/*! \brief calculates the square root.
\param value the value to calculate.
\return the square root of the value as an integer.
\note use fixed point math if you want more accuracy.
*/
int swiSqrt(int value);
/*! \brief calculates a CRC-16 checksum.
\param crc starting CRC-16 value.
\param data pointer to data (processed nibble by nibble)
\param size size in bytes.
\return the CRC-16 after the data has been processed.
*/
uint16 swiCRC16(uint16 crc, void * data, uint32 size);
/*! \brief returns 0 if running on a nintendo hardware debugger.
\return 0 if running on a debugger (8 MB of ram instead of 4 MB), else some other number.
*/
int swiIsDebugger(void);
/*! \brief Unpack data stored in multiple elements in a byte to a larger space.
i.e. 8 elements per byte (i.e. b/w font), into 1 element per byte.
\param source Source address.
\param destination destination address (word aligned).
\param params pointer to an UnpackStruct.
*/
void swiUnpackBits(uint8 * source, uint32 * destination, PUnpackStruct params);
/*! \brief Decompresses LZSS compressed data.
\param source pointer to a header word, followed by compressed data.
bit 0-7 of header is ignored.
bit 8-31 of header is size of uncompressed data in bytes.
\param destination destination address.
\note Writes data a byte at a time.
\see decompress.h
*/
void swiDecompressLZSSWram(void * source, void * destination);
/*! \brief Decompresses LZSS compressed data vram safe.
\param source Pointer to source data (always goes through the function pointers, so could just be an offset).
\param destination Pointer to destination.
\param toGetSize Callback value that is passed to getHeaderCallback function pointer.
\param stream Pointer to struct with callback function pointers.
\return The length of the decompressed data, or a signed errorcode from the Open/Close functions.
\note Writes data a halfword at a time.
\see decompress.h
*/
int swiDecompressLZSSVram(void * source, void * destination, uint32 toGetSize, TDecompressionStream * stream);
int swiDecompressLZSSVramNTR(void * source, void * destination, uint32 toGetSize, TDecompressionStream * stream);
int swiDecompressLZSSVramTWL(void * source, void * destination, uint32 toGetSize, TDecompressionStream * stream);
/*! \brief Decompresses Huffman compressed data.
\param source Pointer to source data (always goes through the function pointers, so could just be an offset).
\param destination Pointer to destination.
\param toGetSize Callback value that is passed to getHeaderCallback function pointer.
\param stream Pointer to struct with callback function pointers.
\return The length of the decompressed data, or a signed errorcode from the Open/Close functions.
\see decompress.h
*/
int swiDecompressHuffman(void * source, void * destination, uint32 toGetSize, TDecompressionStream * stream);
/*! \brief Decompresses RLE compressed data.
compressed data format:
bit(7): 0= uncompressed, 1= compressed.
bit(0-6) when uncompressed: run length - 1, followed by run_length bytes of true data.
bit(0-6) when compressed: run length - 3, followed by one byte of true data, to be repeated.
\param source pointer to a header word, followed by compressed data.
bit 0-7 of header is ignored.
bit 8-31 of header is size of uncompressed data in bytes.
\param destination destination address.
\note Writes data a byte at a time.
\see decompress.h
*/
void swiDecompressRLEWram(void * source, void * destination);
/*! \brief Decompresses RLE compressed data vram safe.
compressed data format:
bit(7): 0= uncompressed, 1= compressed.
bit(0-6) when uncompressed: run length - 1, followed by run_length bytes of true data.
bit(0-6) when compressed: run length - 3, followed by one byte of true data, to be repeated.
\param source Pointer to source data (always goes through the function pointers, so could just be an offset).
\param destination Pointer to destination.
\param toGetSize Callback value that is passed to getHeaderCallback function pointer.
\param stream Pointer to struct with callback function pointers.
\return The length of the decompressed data, or a signed errorcode from the Open/Close functions.
\note Writes data a halfword at a time.
\see decompress.h
*/
int swiDecompressRLEVram(void * source, void * destination, uint32 toGetSize, TDecompressionStream * stream);
#ifdef ARM9
/*! \brief wait for any interrupt.
\note ARM9 exclusive.
*/
void swiWaitForIRQ(void);
/*! \brief Writes a word of the data to 0x04000300:32
\param data the word to write.
\note This is on the ARM9, but works differently then the ARM7 function!
*/
void swiSetHaltCR(uint32 data);
/*! \brief Decodes a stream of bytes based on the difference of the bytes.
\param source Pointer to a header word, followed by encoded data.
word(31..8) = size of data (in bytes).
word(7..0) = ignored.
\param destination Destination address.
\note Writes data a byte at a time.
\note ARM9 exclusive.
*/
void swiDecodeDelta8(void * source, void * destination);
/*! \brief Decodes a stream of bytes based on the difference of the bytes.
\param source Pointer to a header word, followed by encoded data.
word(31..8) = size of data (in bytes).
word(7..0) = ignored.
\param destination Destination address.
\note Writes data a halfword at a time.
\note ARM9 exclusive.
*/
void swiDecodeDelta16(void * source, void * destination);
#endif
#ifdef ARM7
/*! \brief Writes a byte of the data to 0x04000301:8
\param data The byte to write.
\note ARM7 exclusive.
*/
void swiSetHaltCR(uint8 data);
/*! \brief Halts the CPU untill an interupt occures.
\note ARM7 exclusive.
*/
void swiHalt(void);
/*! \brief Halts the CPU and most of the hardware untill an interupt occures.
\note ARM7 exclusive.
*/
void swiSleep(void);
/*! \brief Switches the DS to GBA mode.
\note ARM7 exclusive.
*/
void swiSwitchToGBAMode(void);
/*! \brief Returns an entry in the sine table.
\param index The index of the sine table (0-63).
\return The entry.
\note ARM7 exclusive.
*/
uint16 swiGetSineTable(int index);
/*! \brief Returns an entry in the pitch table.
\param index The index of the pitch table (0-767).
\return The entry.
\note ARM7 exclusive.
*/
uint16 swiGetPitchTable(int index);
/*! \brief Returns an entry in the volume table.
\param index The index of the volume table (0-723).
\return The entry.
\note ARM7 exclusive.
*/
uint8 swiGetVolumeTable(int index);
/*! \brief increments or decrements the sound bias once per delay.
\param enabled 0 to decrement it until it reaches 0x000, 1 to increment it until it reaches 0x200.
\param delay Is in the same units of time as swiDelay.
\note ARM7 exclusive.
*/
void swiChangeSoundBias(int enabled, int delay);
#endif //ARM7
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------------
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.
---------------------------------------------------------------------------------*/
#ifndef NDS_CARD_INCLUDE
#define NDS_CARD_INCLUDE
#include "ndstypes.h"
// Card bus
#define REG_CARD_DATA_RD (*(vu32*)0x04100010)
#define REG_AUXSPICNT (*(vu16*)0x040001A0)
#define REG_AUXSPICNTH (*(vu8*)0x040001A1)
#define REG_AUXSPIDATA (*(vu8*)0x040001A2)
#define REG_ROMCTRL (*(vu32*)0x040001A4)
#define REG_CARD_COMMAND ((vu8*)0x040001A8)
#define REG_CARD_1B0 (*(vu32*)0x040001B0)
#define REG_CARD_1B4 (*(vu32*)0x040001B4)
#define REG_CARD_1B8 (*(vu16*)0x040001B8)
#define REG_CARD_1BA (*(vu16*)0x040001BA)
#define CARD_CR1_ENABLE 0x80 // in byte 1, i.e. 0x8000
#define CARD_CR1_IRQ 0x40 // in byte 1, i.e. 0x4000
// SPI EEPROM COMMANDS
#define SPI_EEPROM_WRSR 0x01
#define SPI_EEPROM_PP 0x02 // Page Program
#define SPI_EEPROM_READ 0x03
#define SPI_EEPROM_WRDI 0x04 // Write disable
#define SPI_EEPROM_RDSR 0x05 // Read status register
#define SPI_EEPROM_WREN 0x06 // Write enable
#define SPI_EEPROM_PW 0x0a // Page Write
#define SPI_EEPROM_FAST 0x0b // Fast Read
#define SPI_EEPROM_RDID 0x9f
#define SPI_EEPROM_RDP 0xab // Release from deep power down
#define SPI_EEPROM_DPD 0xb9 // Deep power down
#define CARD_ACTIVATE (1<<31) // when writing, get the ball rolling
#define CARD_WR (1<<30) // Card write enable
#define CARD_nRESET (1<<29) // value on the /reset pin (1 = high out, not a reset state, 0 = low out = in reset)
#define CARD_SEC_LARGE (1<<28) // Use "other" secure area mode, which tranfers blocks of 0x1000 bytes at a time
#define CARD_CLK_SLOW (1<<27) // Transfer clock rate (0 = 6.7MHz, 1 = 4.2MHz)
#define CARD_BLK_SIZE(n) (((n)&0x7)<<24) // Transfer block size, (0 = None, 1..6 = (0x100 << n) bytes, 7 = 4 bytes)
#define CARD_SEC_CMD (1<<22) // The command transfer will be hardware encrypted (KEY2)
#define CARD_DELAY2(n) (((n)&0x3F)<<16) // Transfer delay length part 2
#define CARD_SEC_SEED (1<<15) // Apply encryption (KEY2) seed to hardware registers
#define CARD_SEC_EN (1<<14) // Security enable
#define CARD_SEC_DAT (1<<13) // The data transfer will be hardware encrypted (KEY2)
#define CARD_DELAY1(n) ((n)&0x1FFF) // Transfer delay length part 1
// 3 bits in b10..b8 indicate something
// read bits
#define CARD_BUSY (1<<31) // when reading, still expecting incomming data?
#define CARD_DATA_READY (1<<23) // when reading, CARD_DATA_RD or CARD_DATA has another word of data and is good to go
// Card commands
#define CARD_CMD_DUMMY 0x9F
#define CARD_CMD_HEADER_READ 0x00
#define CARD_CMD_HEADER_CHIPID 0x90
#define CARD_CMD_ACTIVATE_BF 0x3C // Go into blowfish (KEY1) encryption mode
#define CARD_CMD_ACTIVATE_SEC 0x40 // Go into hardware (KEY2) encryption mode
#define CARD_CMD_SECURE_CHIPID 0x10
#define CARD_CMD_SECURE_READ 0x20
#define CARD_CMD_DISABLE_SEC 0x60 // Leave hardware (KEY2) encryption mode
#define CARD_CMD_DATA_MODE 0xA0
#define CARD_CMD_DATA_READ 0xB7
#define CARD_CMD_DATA_CHIPID 0xB8
//REG_AUXSPICNT
#define CARD_ENABLE (1<<15)
#define CARD_SPI_ENABLE (1<<13)
#define CARD_SPI_BUSY (1<<7)
#define CARD_SPI_HOLD (1<<6)
#define CARD_SPICNTH_ENABLE (1<<7) // in byte 1, i.e. 0x8000
#define CARD_SPICNTH_IRQ (1<<6) // in byte 1, i.e. 0x4000
#ifdef __cplusplus
extern "C" {
#endif
void enableSlot1();
void disableSlot1();
void cardWriteCommand(const u8 *command);
void cardPolledTransfer(u32 flags, u32 *destination, u32 length, const u8 *command);
void cardStartTransfer(const u8 *command, u32 *destination, int channel, u32 flags);
uint32 cardWriteAndRead(const u8 *command, u32 flags);
void cardParamCommand (u8 command, u32 parameter, u32 flags, u32 *destination, u32 length);
// These commands require the cart to not be initialized yet, which may mean the user
// needs to eject and reinsert the cart or they will return random data.
void cardReadHeader(u8 *header);
u32 cardReadID(u32 flags);
void cardReset();
//---------------------------------------------------------------------------------
static inline void eepromWaitBusy() {
//---------------------------------------------------------------------------------
while (REG_AUXSPICNT & CARD_SPI_BUSY);
}
// Reads from the EEPROM
void cardReadEeprom(u32 address, u8 *data, u32 length, u32 addrtype);
// Writes to the EEPROM. TYPE 3 EEPROM must be erased first (I think?)
void cardWriteEeprom(u32 address, u8 *data, u32 length, u32 addrtype);
// Returns the ID of the EEPROM chip? Doesn't work well, most chips give ff,ff
// i = 0 or 1
u32 cardEepromReadID();
// Sends a command to the EEPROM
u8 cardEepromCommand(u8 command);
/*
* -1:no card or no EEPROM
* 0:unknown PassMe?
* 1:TYPE 1 4Kbit(512Byte) EEPROM
* 2:TYPE 2 64Kbit(8KByte)or 512kbit(64Kbyte) EEPROM
* 3:TYPE 3 2Mbit(256KByte) FLASH MEMORY (some rare 4Mbit and 8Mbit chips also)
*/
int cardEepromGetType(void);
// Returns the size in bytes of EEPROM
u32 cardEepromGetSize();
// Erases the entire chip. TYPE 3 chips MUST be erased before writing to them. (I think?)
void cardEepromChipErase(void);
// Erases a single sector of the TYPE 3 chip
void cardEepromSectorErase(u32 address);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,48 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2005
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.
---------------------------------------------------------------------------------*/
/*! \file debug.h
\brief Currently only used to send debug messages to NO$GBA debug window
<div class="fileHeader">
On the ARM 9 this functionality is best accessed via the console studio integration.
- \ref console.h "Debug Messages via stdio"
</div>
*/
#ifndef NDS_DEBUG_INCLUDE
#define NDS_DEBUG_INCLUDE
void nocashWrite(const char *message, int len);
/*! \brief Send a message to the no$gba debug window
\param message The message to send
*/
void nocashMessage(const char *message);
#endif // NDS_DEBUG_INCLUDE

View File

@ -0,0 +1,65 @@
/*
disc_io.h
Interface template for low level disc functions.
Copyright (c) 2006 Michael "Chishm" Chisholm
Based on code originally written by MightyMax
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NDS_DISC_IO_INCLUDE
#define NDS_DISC_IO_INCLUDE
#include "ndstypes.h"
#define FEATURE_MEDIUM_CANREAD 0x00000001
#define FEATURE_MEDIUM_CANWRITE 0x00000002
#define FEATURE_SLOT_GBA 0x00000010
#define FEATURE_SLOT_NDS 0x00000020
#define DEVICE_TYPE_DSI_SD ('_') | ('S' << 8) | ('D' << 16) | ('_' << 24)
typedef bool (* FN_MEDIUM_STARTUP)(void) ;
typedef bool (* FN_MEDIUM_ISINSERTED)(void) ;
typedef bool (* FN_MEDIUM_READSECTORS)(sec_t sector, sec_t numSectors, void* buffer) ;
typedef bool (* FN_MEDIUM_WRITESECTORS)(sec_t sector, sec_t numSectors, const void* buffer) ;
typedef bool (* FN_MEDIUM_CLEARSTATUS)(void) ;
typedef bool (* FN_MEDIUM_SHUTDOWN)(void) ;
struct DISC_INTERFACE_STRUCT {
unsigned long ioType ;
unsigned long features ;
FN_MEDIUM_STARTUP startup ;
FN_MEDIUM_ISINSERTED isInserted ;
FN_MEDIUM_READSECTORS readSectors ;
FN_MEDIUM_WRITESECTORS writeSectors ;
FN_MEDIUM_CLEARSTATUS clearStatus ;
FN_MEDIUM_SHUTDOWN shutdown ;
} ;
typedef struct DISC_INTERFACE_STRUCT DISC_INTERFACE ;
const DISC_INTERFACE* get_io_dsisd (void);
#endif // define NDS_DISC_IO_INCLUDE

View File

@ -0,0 +1,259 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2005
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.
---------------------------------------------------------------------------------*/
/*! \file dma.h
\brief Wrapper functions for direct memory access hardware
<div class="fileHeader">
The DS has 4 hardware direct memory access devices per CPU which can be used to transfer or fill chunks of memeory without
CPU intervention. Utilizing DMA is generaly faster than CPU copies (memcpy, swiCopy, for loops, etc..).
DMA has no access to data caches on the DS and as such will give unexpected results when DMAing data from main memory. The cache must
be flushed as follows when using DMA to ensure proper opertion on the arm9:
<pre>
DC_FlushRange(source, sizeof(dataToCopy));
dmaCopy(source, destination, sizeof(dataToCopy));
</pre>
</div>
*/
#ifndef NDS_DMA_INCLUDE
#define NDS_DMA_INCLUDE
#include "nds/ndstypes.h"
#define DMA0_SRC (*(vuint32*)0x040000B0)
#define DMA0_DEST (*(vuint32*)0x040000B4)
#define DMA0_CR (*(vuint32*)0x040000B8)
#define DMA1_SRC (*(vuint32*)0x040000BC)
#define DMA1_DEST (*(vuint32*)0x040000C0)
#define DMA1_CR (*(vuint32*)0x040000C4)
#define DMA2_SRC (*(vuint32*)0x040000C8)
#define DMA2_DEST (*(vuint32*)0x040000CC)
#define DMA2_CR (*(vuint32*)0x040000D0)
#define DMA3_SRC (*(vuint32*)0x040000D4)
#define DMA3_DEST (*(vuint32*)0x040000D8)
#define DMA3_CR (*(vuint32*)0x040000DC)
#define DMA_SRC(n) (*(vuint32*)(0x040000B0+(n*12)))
#define DMA_DEST(n) (*(vuint32*)(0x040000B4+(n*12)))
#define DMA_CR(n) (*(vuint32*)(0x040000B8+(n*12)))
#ifdef ARM9
#define DMA_FILL(n) (*(vuint32*)(0x040000E0+(n*4)))
#endif
// DMA control register contents
// The defaults are 16-bit, increment source/dest addresses, no irq
#define DMA_ENABLE BIT(31)
#define DMA_BUSY BIT(31)
#define DMA_IRQ_REQ BIT(30)
#define DMA_START_NOW 0
#define DMA_START_CARD (5<<27)
#ifdef ARM7
#define DMA_START_VBL BIT(27)
#endif
#ifdef ARM9
#define DMA_START_HBL BIT(28)
#define DMA_START_VBL BIT(27)
#define DMA_START_FIFO (7<<27)
#define DMA_DISP_FIFO (4<<27)
#endif
#define DMA_16_BIT 0
#define DMA_32_BIT BIT(26)
#define DMA_REPEAT BIT(25)
#define DMA_SRC_INC (0)
#define DMA_SRC_DEC BIT(23)
#define DMA_SRC_FIX BIT(24)
#define DMA_DST_INC (0)
#define DMA_DST_DEC BIT(21)
#define DMA_DST_FIX BIT(22)
#define DMA_DST_RESET (3<<21)
#define DMA_COPY_WORDS (DMA_ENABLE | DMA_32_BIT | DMA_START_NOW)
#define DMA_COPY_HALFWORDS (DMA_ENABLE | DMA_16_BIT | DMA_START_NOW)
#define DMA_FIFO (DMA_ENABLE | DMA_32_BIT | DMA_DST_FIX | DMA_START_FIFO)
static inline
/*! \fn void dmaCopyWords(uint8 channel, const void* src, void* dest, uint32 size)
\brief copies from source to destination on one of the 4 available channels in words
\param channel the dma channel to use (0 - 3).
\param src the source to copy from
\param dest the destination to copy to
\param size the size in bytes of the data to copy. Will be truncated to the nearest word (4 bytes)
*/
void dmaCopyWords(uint8 channel, const void* src, void* dest, uint32 size) {
DMA_SRC(channel) = (uint32)src;
DMA_DEST(channel) = (uint32)dest;
DMA_CR(channel) = DMA_COPY_WORDS | (size>>2);
while(DMA_CR(channel) & DMA_BUSY);
}
static inline
/*! \fn void dmaCopyHalfWords(uint8 channel, const void* src, void* dest, uint32 size)
\brief copies from source to destination on one of the 4 available channels in half words
\param channel the dma channel to use (0 - 3).
\param src the source to copy from
\param dest the destination to copy to
\param size the size in bytes of the data to copy. Will be truncated to the nearest half word (2 bytes)
*/
void dmaCopyHalfWords(uint8 channel, const void* src, void* dest, uint32 size) {
DMA_SRC(channel) = (uint32)src;
DMA_DEST(channel) = (uint32)dest;
DMA_CR(channel) = DMA_COPY_HALFWORDS | (size>>1);
while(DMA_CR(channel) & DMA_BUSY);
}
static inline
/*! \fn void dmaCopy(const void * source, void * dest, uint32 size)
\brief copies from source to destination using channel 3 of DMA available channels in half words
\param source the source to copy from
\param dest the destination to copy to
\param size the size in bytes of the data to copy. Will be truncated to the nearest half word (2 bytes)
*/
void dmaCopy(const void * source, void * dest, uint32 size) {
DMA_SRC(3) = (uint32)source;
DMA_DEST(3) = (uint32)dest;
DMA_CR(3) = DMA_COPY_HALFWORDS | (size>>1);
while(DMA_CR(3) & DMA_BUSY);
}
static inline
/*! \fn void dmaCopyWordsAsynch(uint8 channel, const void* src, void* dest, uint32 size)
\brief copies from source to destination on one of the 4 available channels in half words.
This function returns immediately after starting the transfer.
\param channel the dma channel to use (0 - 3).
\param src the source to copy from
\param dest the destination to copy to
\param size the size in bytes of the data to copy. Will be truncated to the nearest word (4 bytes)
*/
void dmaCopyWordsAsynch(uint8 channel, const void* src, void* dest, uint32 size) {
DMA_SRC(channel) = (uint32)src;
DMA_DEST(channel) = (uint32)dest;
DMA_CR(channel) = DMA_COPY_WORDS | (size>>2);
}
static inline
/*! \fn void dmaCopyHalfWordsAsynch(uint8 channel, const void* src, void* dest, uint32 size)
\brief copies from source to destination on one of the 4 available channels in half words.
This function returns immediately after starting the transfer.
\param channel the dma channel to use (0 - 3).
\param src the source to copy from
\param dest the destination to copy to
\param size the size in bytes of the data to copy. Will be truncated to the nearest half word (2 bytes)
*/
void dmaCopyHalfWordsAsynch(uint8 channel, const void* src, void* dest, uint32 size) {
DMA_SRC(channel) = (uint32)src;
DMA_DEST(channel) = (uint32)dest;
DMA_CR(channel) = DMA_COPY_HALFWORDS | (size>>1);
}
static inline
/*! \fn void dmaCopyAsynch(const void* src, void* dest, uint32 size)
\brief copies from source to destination using channel 3 of DMA available channels in half words.
This function returns immediately after starting the transfer.
\param src the source to copy from
\param dest the destination to copy to
\param size the size in bytes of the data to copy. Will be truncated to the nearest half word (2 bytes)
*/
void dmaCopyAsynch(const void * source, void * dest, uint32 size) {
DMA_SRC(3) = (uint32)source;
DMA_DEST(3) = (uint32)dest;
DMA_CR(3) = DMA_COPY_HALFWORDS | (size>>1);
}
static inline
/*! \fn void dmaFillWords( u32 value, void* dest, uint32 size)
\brief fills the source with the supplied value using DMA channel 3
\param value the 32 byte value to fill memory with
\param dest the destination to copy to
\param size the size in bytes of the area to fill. Will be truncated to the nearest word (4 bytes)
*/
void dmaFillWords(u32 value, void* dest, uint32 size) {
#ifdef ARM7
(*(vu32*)0x027FFE04) = value;
DMA_SRC(3) = 0x027FFE04;
#else
DMA_FILL(3) = value;
DMA_SRC(3) = (uint32)&DMA_FILL(3);
#endif
DMA_DEST(3) = (uint32)dest;
DMA_CR(3) = DMA_SRC_FIX | DMA_COPY_WORDS | (size>>2);
while(DMA_CR(3) & DMA_BUSY);
}
static inline
/*! \fn void dmaFillHalfWords( u16 value, void* dest, uint32 size)
\brief fills the source with the supplied value using DMA channel 3
\param value the 16 byte value to fill memory with
\param dest the destination to copy to
\param size the size in bytes of the area to fill. Will be truncated to the nearest half word (2 bytes)
*/
void dmaFillHalfWords(u16 value, void* dest, uint32 size) {
#ifdef ARM7
(*(vu32*)0x027FFE04) = (u32)value;
DMA_SRC(3) = 0x027FFE04;
#else
DMA_FILL(3) = (uint32)value;
DMA_SRC(3) = (uint32)&DMA_FILL(3);
#endif
DMA_DEST(3) = (uint32)dest;
DMA_CR(3) = DMA_SRC_FIX | DMA_COPY_HALFWORDS | (size>>1);
while(DMA_CR(3) & DMA_BUSY);
}
static inline
/*! \fn dmaBusy(uint8 channel)
\brief determines if the specified channel is busy
\param channel the dma channel to check (0 - 3).
\return non zero if busy, 0 if channel is free
*/
int dmaBusy(uint8 channel) {
return (DMA_CR(channel) & DMA_BUSY)>>31;
}
#endif

View File

@ -0,0 +1,344 @@
#ifndef FIFOCOMMON_H
#define FIFOCOMMON_H
#include "ndstypes.h"
#include "interrupts.h"
/*! \file fifocommon.h
\brief low level FIFO API.
*/
//! Enum values for the different fifo channels.
typedef enum {
FIFO_PM = 0, /*!< \brief fifo channel reserved for power management. */
FIFO_SOUND = 1, /*!< \brief fifo channel reserved for sound access. */
FIFO_SYSTEM = 2, /*!< \brief fifo channel reserved for system functions. */
FIFO_MAXMOD = 3, /*!< \brief fifo channel reserved for the maxmod library. */
FIFO_DSWIFI = 4, /*!< \brief fifo channel reserved for the dswifi library. */
FIFO_SDMMC = 5, /*!< \brief fifo channel reserved for dsi sdmmc control. */
FIFO_FIRMWARE = 6, /*!< \brief fifo channel reserved for firmware access. */
FIFO_RSVD_01 = 7, /*!< \brief fifo channel reserved for future use. */
FIFO_USER_01 = 8, /*!< \brief fifo channel available for users. */
FIFO_USER_02 = 9, /*!< \brief fifo channel available for users. */
FIFO_USER_03 = 10, /*!< \brief fifo channel available for users. */
FIFO_USER_04 = 11, /*!< \brief fifo channel available for users. */
FIFO_USER_05 = 12, /*!< \brief fifo channel available for users. */
FIFO_USER_06 = 13, /*!< \brief fifo channel available for users. */
FIFO_USER_07 = 14, /*!< \brief fifo channel available for users. */
FIFO_USER_08 = 15, /*!< \brief fifo channel available for users. */
} FifoChannels;
//! Enum values for the fifo sound commands.
typedef enum {
SOUND_SET_PAN = 0 << 20,
SOUND_SET_VOLUME = 1 << 20,
SOUND_SET_FREQ = 2 << 20,
SOUND_SET_WAVEDUTY = 3 << 20,
SOUND_MASTER_ENABLE = 4 << 20,
SOUND_MASTER_DISABLE = 5 << 20,
SOUND_PAUSE = 6 << 20,
SOUND_RESUME = 7 << 20,
SOUND_KILL = 8 << 20,
SOUND_SET_MASTER_VOL = 9 << 20,
MIC_STOP = 10 << 20
} FifoSoundCommand;
//! Enum values for the fifo system commands.
typedef enum {
SYS_REQ_TOUCH,
SYS_REQ_KEYS,
SYS_REQ_TIME,
SYS_SET_TIME,
SDMMC_INSERT,
SDMMC_REMOVE
} FifoSystemCommands;
typedef enum {
SDMMC_HAVE_SD,
SDMMC_SD_START,
SDMMC_SD_IS_INSERTED,
SDMMC_SD_STOP,
SDMMC_NAND_START,
SDMMC_NAND_STOP,
SDMMC_NAND_SIZE
} FifoSdmmcCommands;
typedef enum {
FW_READ,
FW_WRITE
} FifoFirmwareCommands;
//! Enum values for the fifo power management commands.
typedef enum {
PM_REQ_ON = (1<<16),
PM_REQ_OFF = (2<<16),
PM_REQ_LED = (3<<16),
PM_REQ_SLEEP = (4<<16),
PM_REQ_SLEEP_DISABLE = (5<<16),
PM_REQ_SLEEP_ENABLE = (6<<16),
PM_REQ_BATTERY = (7<<16),
PM_REQ_SLOT1_DISABLE = (8<<16),
PM_REQ_SLOT1_ENABLE = (9<<16),
}FifoPMCommands;
//! Enum values for the fifo wifi commands.
typedef enum {
WIFI_ENABLE,
WIFI_DISABLE,
WIFI_SYNC,
WIFI_STARTUP
} FifoWifiCommands;
//! Power Management LED blink mode control bits.
typedef enum {
PM_LED_ON = 0, /*!< \brief Steady on */
PM_LED_SLEEP = 1, /*!< \brief Blinking, mostly off */
PM_LED_BLINK = 3, /*!< \brief Blinking, mostly on */
}PM_LedBlinkMode;
#ifdef __cplusplus
extern "C" {
#endif
#if FIFO_RIGOROUS_ERROR_CHECKING
int fifoError(char *, ...); // expected to be defined externally.
#endif
/*!
\brief fifo callback function pointer with the sent address and the callback's user data.
The handler is called when new data arrives.
\note callback functions are called from interrupt level, but are well secured. not too much caution is necessary,
but don't call alloc, free or printf from within them, just to be safe.
*/
typedef void (*FifoAddressHandlerFunc)(void * address, void * userdata);
/*!
\brief fifo callback function pointer with the sent value and the callback's user data.
The handler is called when new data arrives.
\note callback functions are called from interrupt level, but are well secured. not too much caution is necessary,
but don't call alloc, free or printf from within them, just to be safe.
*/
typedef void (*FifoValue32HandlerFunc)(u32 value32, void * userdata);
/*!
\brief fifo callback function pointer with the number of bytes sent and the callback's user data
The handler is called when new data arrives.
This callback must call fifoGetData to actually retrieve the data. If it doesn't, the data will be destroyed on return.
\note callback functions are called from interrupt level, but are well secured. not too much caution is necessary,
but don't call alloc, free or printf from within them, just to be safe.
*/
typedef void (*FifoDatamsgHandlerFunc)(int num_bytes, void * userdata);
/*!
\brief Initializes the fifo system.
Attempts to sync with the other CPU, if it fails, fifo services won't be provided.
\note call irqInit() before calling this function.
\return true if syncing worked, false if something went wrong.
*/
bool fifoInit();
/*!
\brief Send an address to an channel.
Transmits an address in the range 0x02000000-0x023FFFFF to the other CPU.
\param channel channel number to send to.
\param address address to send.
\return true if the address has been send, false if something went wrong.
*/
bool fifoSendAddress(int channel, void *address);
/*!
\brief Send a 32bit value.
Transmits a 32bit value to the other CPU.
\param channel channel number to send to
\param value32 32bit value to send
\return true if the value has been send, false if something went wrong.
\note Transfer is more efficient if the top 8 bits are zero. So sending smaller values or bitmasks that don't include the top bits is preferred.
*/
bool fifoSendValue32(int channel, u32 value32);
/*!
\brief Send a sequence of bytes to the other CPU.
num_bytes can be between 0 and FIFO_MAX_DATA_BYTES - sending 0 bytes can be useful sometimes...
\param channel channel number to send to
\param num_bytes number of bytes to send
\param data_array pointer to data array
\return true if the data message has been send, false if something went wrong.
*/
bool fifoSendDatamsg(int channel, int num_bytes, u8 * data_array);
/*!
\brief Set user address message callback.
Set a callback to receive incoming address messages on a specific channel.
\param channel channel number to send to.
\param newhandler a function pointer to the new handler function.
\param userdata a pointer that will be passed on to the handler when it will be called.
\return true if the handler has been set, false if something went wrong.
\note Setting the handler for a channel feeds the queue of buffered messages to the new handler, if there are any unread messages.
*/
bool fifoSetAddressHandler(int channel, FifoAddressHandlerFunc newhandler, void * userdata);
/*!
\brief Set user value32 message callback.
Set a callback to receive incoming value32 messages on a specific channel.
\param channel channel number to send to.
\param newhandler a function pointer to the new handler function.
\param userdata a pointer that will be passed on to the handler when it will be called.
\return true if the handler has been set, false if something went wrong.
\note Setting the handler for a channel feeds the queue of buffered messages to the new handler, if there are any unread messages.
*/
bool fifoSetValue32Handler(int channel, FifoValue32HandlerFunc newhandler, void * userdata);
/*!
\brief Set user data message callback.
Set a callback to receive incoming data messages on a specific channel.
\param channel channel number to send to.
\param newhandler a function pointer to the new handler function.
\param userdata a pointer that will be passed on to the handler when it will be called.
\return true if the handler has been set, false if something went wrong.
\note Setting the handler for a channel feeds the queue of buffered messages to the new handler, if there are any unread messages.
*/
bool fifoSetDatamsgHandler(int channel, FifoDatamsgHandlerFunc newhandler, void * userdata);
/*!
\brief checks if there is any addresses in the fifo queue.
\param channel the channel to check.
\return true if there is any addresses in the queue and if there isn't an address handler in place for the channel.
*/
bool fifoCheckAddress(int channel);
/*!
\brief checks if there is any values in the fifo queue.
\param channel the channel to check.
\return true if there is any values in the queue and if there isn't a value handler in place for the channel.
*/
bool fifoCheckValue32(int channel);
/*!
\brief checks if there is any data messages in the fifo queue.
\param channel the channel to check.
\return true if there is any data messages in the queue and if there isn't a data message handler in place for the channel.
*/
bool fifoCheckDatamsg(int channel);
/*!
\brief gets the number of bytes in the queue for the first data entry.
\param channel the channel to check.
\return the number of bytes in the queue for the first data entry, or -1 if there are no entries.
*/
int fifoCheckDatamsgLength(int channel);
/*!
\brief Get the first address in queue for a specific channel.
\param channel the channel to check.
\return the first address in queue, or NULL if there is none.
*/
void * fifoGetAddress(int channel);
/*!
\brief Get the first value32 in queue for a specific channel.
\param channel the channel to check.
\return the first value32 in queue, or 0 if there is no message.
*/
u32 fifoGetValue32(int channel);
/*!
\brief Reads a data message in a given buffer and returns the number of bytes written.
\param channel the channel to check.
\param buffersize the size of the buffer where the message will be copied to.
\param destbuffer a pointer to the buffer where the message will be copied to.
\return the number of bytes written, or -1 if there is no message.
\warning If your buffer is not big enough, you may lose data! Check the data length first if you're not sure what the size is.
*/
int fifoGetDatamsg(int channel, int buffersize, u8 * destbuffer);
/*!
\brief waits for any data messages in the fifo queue.
\param channel the channel to check.
*/
//---------------------------------------------------------------------------------
static inline void fifoWaitValue32(int channel) {
//---------------------------------------------------------------------------------
while(!fifoCheckValue32(channel)) {
swiIntrWait(1,IRQ_FIFO_NOT_EMPTY);
}
}
#ifdef __cplusplus
};
#endif
#endif

View File

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------------
Sound Functions
Copyright (C) 2008
Jason Rogers (Dovoto)
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.
---------------------------------------------------------------------------------*/
#ifndef FIFOMESSAGE_H
#define FIFOMESSAGE_H
#include "ndstypes.h"
#include <nds/touch.h>
/* internal fifo messages utilized by libnds. */
typedef enum {
SOUND_PLAY_MESSAGE = 0x1234,
SOUND_PSG_MESSAGE,
SOUND_NOISE_MESSAGE,
MIC_RECORD_MESSAGE,
MIC_BUFFER_FULL_MESSAGE,
SYS_INPUT_MESSAGE,
SDMMC_SD_READ_SECTORS,
SDMMC_SD_WRITE_SECTORS,
SDMMC_NAND_READ_SECTORS,
SDMMC_NAND_WRITE_SECTORS
} FifoMessageType;
typedef struct FifoMessage {
u16 type;
union {
struct {
const void* data;
u32 dataSize;
u16 loopPoint;
u16 freq;
u8 volume;
u8 pan;
bool loop;
u8 format;
u8 channel;
} SoundPlay;
struct{
u16 freq;
u8 dutyCycle;
u8 volume;
u8 pan;
u8 channel;
} SoundPsg;
struct{
void* buffer;
u32 bufferLength;
u16 freq;
u8 format;
} MicRecord;
struct{
void* buffer;
u32 length;
} MicBufferFull;
struct{
touchPosition touch;
u16 keys;
} SystemInput;
struct{
void *buffer;
u32 startsector;
u32 numsectors;
} sdParams;
struct{
void *buffer;
u32 address;
u32 length;
} blockParams;
};
} ALIGN(4) FifoMessage;
#endif

View File

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2010
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.
---------------------------------------------------------------------------------*/
#ifndef _INPUT_H_
#define _INPUT_H_
/*! \file
\brief common values for keypad input.
common values that can be used on both the arm9 and arm7.
*/
//! enum values for the keypad buttons.
typedef enum KEYPAD_BITS {
KEY_A = BIT(0), //!< Keypad A button.
KEY_B = BIT(1), //!< Keypad B button.
KEY_SELECT = BIT(2), //!< Keypad SELECT button.
KEY_START = BIT(3), //!< Keypad START button.
KEY_RIGHT = BIT(4), //!< Keypad RIGHT button.
KEY_LEFT = BIT(5), //!< Keypad LEFT button.
KEY_UP = BIT(6), //!< Keypad UP button.
KEY_DOWN = BIT(7), //!< Keypad DOWN button.
KEY_R = BIT(8), //!< Right shoulder button.
KEY_L = BIT(9), //!< Left shoulder button.
KEY_X = BIT(10), //!< Keypad X button.
KEY_Y = BIT(11), //!< Keypad Y button.
KEY_TOUCH = BIT(12), //!< Touchscreen pendown.
KEY_LID = BIT(13) //!< Lid state.
} KEYPAD_BITS;
/*! \brief Key input register.
On the ARM9, the hinge "button", the touch status, and the
X and Y buttons cannot be accessed directly.
*/
#define REG_KEYINPUT (*(vuint16*)0x04000130)
//! Key input control register.
#define REG_KEYCNT (*(vuint16*)0x04000132)
#endif

View File

@ -0,0 +1,257 @@
/*---------------------------------------------------------------------------------
Interrupt registers and vector pointers
Copyright (C) 2005
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.
---------------------------------------------------------------------------------*/
/*! \file interrupts.h
\brief nds interrupt support.
*/
#ifndef NDS_INTERRUPTS_INCLUDE
#define NDS_INTERRUPTS_INCLUDE
#include <nds/ndstypes.h>
//! values allowed for REG_IE and REG_IF
enum IRQ_MASKS {
IRQ_VBLANK = BIT(0), /*!< vertical blank interrupt mask */
IRQ_HBLANK = BIT(1), /*!< horizontal blank interrupt mask */
IRQ_VCOUNT = BIT(2), /*!< vcount match interrupt mask */
IRQ_TIMER0 = BIT(3), /*!< timer 0 interrupt mask */
IRQ_TIMER1 = BIT(4), /*!< timer 1 interrupt mask */
IRQ_TIMER2 = BIT(5), /*!< timer 2 interrupt mask */
IRQ_TIMER3 = BIT(6), /*!< timer 3 interrupt mask */
IRQ_NETWORK = BIT(7), /*!< serial interrupt mask */
IRQ_DMA0 = BIT(8), /*!< DMA 0 interrupt mask */
IRQ_DMA1 = BIT(9), /*!< DMA 1 interrupt mask */
IRQ_DMA2 = BIT(10), /*!< DMA 2 interrupt mask */
IRQ_DMA3 = BIT(11), /*!< DMA 3 interrupt mask */
IRQ_KEYS = BIT(12), /*!< Keypad interrupt mask */
IRQ_CART = BIT(13), /*!< GBA cartridge interrupt mask */
IRQ_IPC_SYNC = BIT(16), /*!< IPC sync interrupt mask */
IRQ_FIFO_EMPTY = BIT(17), /*!< Send FIFO empty interrupt mask */
IRQ_FIFO_NOT_EMPTY = BIT(18), /*!< Receive FIFO not empty interrupt mask */
IRQ_CARD = BIT(19), /*!< interrupt mask DS Card Slot*/
IRQ_CARD_LINE = BIT(20), /*!< interrupt mask */
IRQ_GEOMETRY_FIFO = BIT(21), /*!< geometry FIFO interrupt mask */
IRQ_LID = BIT(22), /*!< interrupt mask DS hinge*/
IRQ_SPI = BIT(23), /*!< SPI interrupt mask */
IRQ_WIFI = BIT(24), /*!< WIFI interrupt mask (ARM7)*/
IRQ_ALL = (~0) /*!< 'mask' for all interrupt */
};
typedef enum IRQ_MASKS IRQ_MASK;
//! values allowed for REG_AUXIE and REG_AUXIF
enum IRQ_MASKSAUX {
IRQ_I2C = BIT(6), /*!< I2C interrupt mask (DSi ARM7)*/
IRQ_SDMMC = BIT(8) /*!< Sdmmc interrupt mask (DSi ARM7)*/
};
/*!
\brief returns the mask for a given timer.
\param n the timer.
\return the bitmask.
*/
#define IRQ_TIMER(n) (1 << ((n) + 3))
//! maximum number of interrupts.
#define MAX_INTERRUPTS 25
/*! \def REG_IE
\brief Interrupt Enable Register.
This is the activation mask for the internal interrupts. Unless
the corresponding bit is set, the IRQ will be masked out.
*/
#define REG_IE (*(vuint32*)0x04000210)
#define REG_AUXIE (*(vuint32*)0x04000218)
/*! \def REG_IF
\brief Interrupt Flag Register.
Since there is only one hardware interrupt vector, the IF register
contains flags to indicate when a particular of interrupt has occured.
To acknowledge processing interrupts, set IF to the value of the
interrupt handled.
*/
#define REG_IF (*(vuint32*)0x04000214)
#define REG_AUXIF (*(vuint32*)0x0400021C)
/*! \def REG_IME
\brief Interrupt Master Enable Register.
When bit 0 is clear, all interrupts are masked. When it is 1,
interrupts will occur if not masked out in REG_IE.
*/
#define REG_IME (*(vuint32*)0x04000208)
//! values allowed for REG_IME
enum IME_VALUE {
IME_DISABLE = 0, /*!< Disable all interrupts. */
IME_ENABLE = 1, /*!< Enable all interrupts not masked out in REG_IE */
};
#ifdef __cplusplus
extern "C" {
#endif
extern VoidFn __irq_vector[];
extern vuint32 __irq_flags[];
extern vuint32 __irq_flagsaux[];
#define INTR_WAIT_FLAGS *(__irq_flags)
#define INTR_WAIT_FLAGSAUX *(__irq_flagsaux)
#define IRQ_HANDLER *(__irq_vector)
struct IntTable{IntFn handler; u32 mask;};
/*! \fn irqInit()
\brief Initialise the libnds interrupt system.
This function is called internally (prior to main()) to set up irqs
on the ARM9. It must be called on the ARM7 prior to installing irq
handlers.
*/
void irqInit();
/*! \fn irqSet(u32 irq, VoidFn handler)
\brief Add a handler for the given interrupt mask.
Specify the handler to use for the given interrupt. This only works with
the default interrupt handler, do not mix the use of this routine with a
user-installed IRQ handler.
\param irq Mask associated with the interrupt.
\param handler Address of the function to use as an interrupt service routine
\note
When any handler specifies using IRQ_VBLANK or IRQ_HBLANK, DISP_SR
is automatically updated to include the corresponding DISP_VBLANK_IRQ or DISP_HBLANK_IRQ.
\warning Only one IRQ_MASK can be specified with this function.
*/
void irqSet(u32 irq, VoidFn handler);
void irqSetAUX(u32 irq, VoidFn handler);
/*! \fn irqClear(u32 irq)
\brief remove the handler associated with the interrupt mask irq.
\param irq Mask associated with the interrupt.
*/
void irqClear(u32 irq);
void irqClearAUX(u32 irq);
/*! \fn irqInitHandler(VoidFn handler)
\brief Install a user interrupt dispatcher.
This function installs the main interrupt function, all interrupts are serviced through this routine. For most
purposes the libnds interrupt dispacther should be used in preference to user code unless you know *exactly* what you're doing.
\param handler Address of the function to use as an interrupt dispatcher
\note the function *must* be ARM code
*/
void irqInitHandler(VoidFn handler);
/*! \fn irqEnable(u32 irq)
\brief Allow the given interrupt to occur.
\param irq The set of interrupt masks to enable.
\note Specify multiple interrupts to enable by ORing several IRQ_MASKS.
*/
void irqEnable(u32 irq);
void irqEnableAUX(u32 irq);
/*! \fn irqDisable(u32 irq)
\brief Prevent the given interrupt from occuring.
\param irq The set of interrupt masks to disable.
\note Specify multiple interrupts to disable by ORing several IRQ_MASKS.
*/
void irqDisable(u32 irq);
void irqDisableAUX(u32 irq);
/*! \fn swiIntrWait(u32 waitForSet, uint32 flags)
\brief wait for interrupt(s) to occur
\param waitForSet
0: Return if the interrupt has already occured
1: Wait until the interrupt has been set since the call
\param flags
interrupt mask to wait for
*/
void swiIntrWait(u32 waitForSet, uint32 flags);
/*! \fn swiWaitForVBlank()
\brief Wait for vblank interrupt
Waits for a vertical blank interrupt
\note Identical to calling swiIntrWait(1, 1)
*/
void swiWaitForVBlank(void);
/*! \fn VoidFn setPowerButtonCB(VoidFn CB);
\brief set callback for DSi Powerbutton press
\param CB
function to call when power button pressed
\return
the previously set callback
*/
VoidFn setPowerButtonCB(VoidFn CB);
static inline int enterCriticalSection() {
int oldIME = REG_IME;
REG_IME = 0;
return oldIME;
}
static inline void leaveCriticalSection(int oldIME) {
REG_IME = oldIME;
}
#ifdef __cplusplus
}
#endif
#endif //NDS_INTERRUPTS_INCLUDE

View File

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------------
Inter Processor Communication
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.
---------------------------------------------------------------------------------*/
#ifndef NDS_IPC_INCLUDE
#define NDS_IPC_INCLUDE
#include "ndstypes.h"
//---------------------------------------------------------------------------------
// Synchronization register
//---------------------------------------------------------------------------------
#define REG_IPC_SYNC (*(vuint16*)0x04000180)
enum IPC_SYNC_BITS {
IPC_SYNC_IRQ_ENABLE = BIT(14),
IPC_SYNC_IRQ_REQUEST = BIT(13)
};
//---------------------------------------------------------------------------------
static inline void IPC_SendSync(unsigned int sync) {
//---------------------------------------------------------------------------------
REG_IPC_SYNC = (REG_IPC_SYNC & 0xf0ff) | (((sync) & 0x0f) << 8) | IPC_SYNC_IRQ_REQUEST;
}
//---------------------------------------------------------------------------------
static inline int IPC_GetSync() {
//---------------------------------------------------------------------------------
return REG_IPC_SYNC & 0x0f;
}
//---------------------------------------------------------------------------------
// fifo
//---------------------------------------------------------------------------------
#define REG_IPC_FIFO_TX (*(vu32*)0x4000188)
#define REG_IPC_FIFO_RX (*(vu32*)0x4100000)
#define REG_IPC_FIFO_CR (*(vu16*)0x4000184)
enum IPC_CONTROL_BITS {
IPC_FIFO_SEND_EMPTY = (1<<0),
IPC_FIFO_SEND_FULL = (1<<1),
IPC_FIFO_SEND_IRQ = (1<<2),
IPC_FIFO_SEND_CLEAR = (1<<3),
IPC_FIFO_RECV_EMPTY = (1<<8),
IPC_FIFO_RECV_FULL = (1<<9),
IPC_FIFO_RECV_IRQ = (1<<10),
IPC_FIFO_ERROR = (1<<14),
IPC_FIFO_ENABLE = (1<<15)
};
#endif // NDS_IPC_INCLUDE

View File

@ -0,0 +1,3 @@
#error "jtypes.h is a deprecated header, use ndstypes.h"
#include "ndstypes.h"

View File

@ -0,0 +1,309 @@
/*---------------------------------------------------------------------------------
memory.h -- Declaration of memory regions
Copyright (C) 2005 Michael Noland (joat) and Jason Rogers (dovoto)
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.
---------------------------------------------------------------------------------*/
/*! \file memory.h
\brief Defines for many of the regions of memory on the DS as well as a few control functions for memory bus access
*/
#ifndef NDS_MEMORY_INCLUDE
#define NDS_MEMORY_INCLUDE
#include "ndstypes.h"
#include <assert.h>
#ifdef ARM9
#define REG_EXMEMCNT (*(vu16*)0x04000204)
#else
#define REG_EXMEMSTAT (*(vu16*)0x04000204)
#endif
#define ARM7_MAIN_RAM_PRIORITY BIT(15)
#define ARM7_OWNS_CARD BIT(11)
#define ARM7_OWNS_ROM BIT(7)
#define REG_MBK1 ((vu8*)0x04004040) /* WRAM_A 0..3 */
#define REG_MBK2 ((vu8*)0x04004044) /* WRAM_B 0..3 */
#define REG_MBK3 ((vu8*)0x04004048) /* WRAM_B 4..7 */
#define REG_MBK4 ((vu8*)0x0400404C) /* WRAM_C 0..3 */
#define REG_MBK5 ((vu8*)0x04004050) /* WRAM_C 4..7 */
#define REG_MBK6 (*(vu32*)0x04004054)
#define REG_MBK7 (*(vu32*)0x04004058)
#define REG_MBK8 (*(vu32*)0x0400405C)
#define REG_MBK9 (*(vu32*)0x04004060)
// Protection register (write-once sadly)
#ifdef ARM7
#define PROTECTION (*(vu32*)0x04000308)
#endif
//! 8 bit pointer to the start of all the ram.
#define ALLRAM ((u8*)0x00000000)
//! 8 bit pointer to main ram.
#define MAINRAM8 ((u8*)0x02000000)
//! 16 bit pointer to main ram.
#define MAINRAM16 ((u16*)0x02000000)
//! 32 bit pointer to main ram.
#define MAINRAM32 ((u32*)0x02000000)
// TODO: fixme: shared RAM
// GBA_BUS is volatile, while GBAROM is not
//! 16 bit volatile pointer to the GBA slot bus.
#define GBA_BUS ((vu16 *)(0x08000000))
//! 16 bit pointer to the GBA slot ROM.
#define GBAROM ((u16*)0x08000000)
//! 8 bit pointer to GBA slot Save ram.
#define SRAM ((u8*)0x0A000000)
#ifdef ARM7
#define VRAM ((u16*)0x06000000)
#endif
/*!
\brief the GBA file header format.
See gbatek for more info.
*/
typedef struct sGBAHeader {
u32 entryPoint; //!< 32 bits arm opcode to jump to executable code.
u8 logo[156]; //!< nintendo logo needed for booting the game.
char title[0xC]; //!< 12 characters for the game title.
char gamecode[0x4]; //!< 4 characters for the game code. first character is usally A or B, next 2 characters is a short title
//!< and last character is for destination/language.
u16 makercode; //!< identifies the (commercial) developer.
u8 is96h; //!< fixed value that is always 96h.
u8 unitcode; //!< identifies the required hardware.
u8 devicecode; //!< used by nintedo's hardware debuggers. normally 0.
u8 unused[7];
u8 version; //!< the version of the game.
u8 complement; //!< complement checksum of the gba header.
u16 checksum; //!< a 16 bit checksum? (gbatek says its unused/reserved).
} tGBAHeader;
#define GBA_HEADER (*(tGBAHeader *)0x08000000)
/*!
\brief the NDS file header format
See gbatek for more info.
*/
typedef struct sNDSHeader {
char gameTitle[12]; //!< 12 characters for the game title.
char gameCode[4]; //!< 4 characters for the game code.
char makercode[2]; //!< identifies the (commercial) developer.
u8 unitCode; //!< identifies the required hardware.
u8 deviceType; //!< type of device in the game card
u8 deviceSize; //!< capacity of the device (1 << n Mbit)
u8 reserved1[9];
u8 romversion; //!< version of the ROM.
u8 flags; //!< bit 2: auto-boot flag.
u32 arm9romOffset; //!< offset of the arm9 binary in the nds file.
void *arm9executeAddress; //!< adress that should be executed after the binary has been copied.
void *arm9destination; //!< destination address to where the arm9 binary should be copied.
u32 arm9binarySize; //!< size of the arm9 binary.
u32 arm7romOffset; //!< offset of the arm7 binary in the nds file.
void *arm7executeAddress; //!< adress that should be executed after the binary has been copied.
void *arm7destination; //!< destination address to where the arm7 binary should be copied.
u32 arm7binarySize; //!< size of the arm7 binary.
u32 filenameOffset; //!< File Name Table (FNT) offset.
u32 filenameSize; //!< File Name Table (FNT) size.
u32 fatOffset; //!< File Allocation Table (FAT) offset.
u32 fatSize; //!< File Allocation Table (FAT) size.
u32 arm9overlaySource; //!< File arm9 overlay offset.
u32 arm9overlaySize; //!< File arm9 overlay size.
u32 arm7overlaySource; //!< File arm7 overlay offset.
u32 arm7overlaySize; //!< File arm7 overlay size.
u32 cardControl13; //!< Port 40001A4h setting for normal commands (used in modes 1 and 3)
u32 cardControlBF; //!< Port 40001A4h setting for KEY1 commands (used in mode 2)
u32 bannerOffset; //!< offset to the banner with icon and titles etc.
u16 secureCRC16; //!< Secure Area Checksum, CRC-16.
u16 readTimeout; //!< Secure Area Loading Timeout.
u32 unknownRAM1; //!< ARM9 Auto Load List RAM Address (?)
u32 unknownRAM2; //!< ARM7 Auto Load List RAM Address (?)
u32 bfPrime1; //!< Secure Area Disable part 1.
u32 bfPrime2; //!< Secure Area Disable part 2.
u32 romSize; //!< total size of the ROM.
u32 headerSize; //!< ROM header size.
u32 zeros88[14];
u8 gbaLogo[156]; //!< Nintendo logo needed for booting the game.
u16 logoCRC16; //!< Nintendo Logo Checksum, CRC-16.
u16 headerCRC16; //!< header checksum, CRC-16.
} tNDSHeader;
typedef struct __DSiHeader {
tNDSHeader ndshdr;
u32 debugRomSource; //!< debug ROM offset.
u32 debugRomSize; //!< debug size.
u32 debugRomDestination; //!< debug RAM destination.
u32 offset_0x16C; //reserved?
u8 zero[0x10];
u8 global_mbk_setting[5][4];
u32 arm9_mbk_setting[3];
u32 arm7_mbk_setting[3];
u32 mbk9_wramcnt_setting;
u32 region_flags;
u32 access_control;
u32 scfg_ext_mask;
u8 offset_0x1BC[3];
u8 appflags;
void *arm9iromOffset;
u32 offset_0x1C4;
void *arm9idestination;
u32 arm9ibinarySize;
void *arm7iromOffset;
u32 offset_0x1D4;
void *arm7idestination;
u32 arm7ibinarySize;
u32 digest_ntr_start;
u32 digest_ntr_size;
u32 digest_twl_start;
u32 digest_twl_size;
u32 sector_hashtable_start;
u32 sector_hashtable_size;
u32 block_hashtable_start;
u32 block_hashtable_size;
u32 digest_sector_size;
u32 digest_block_sectorcount;
u32 banner_size;
u32 offset_0x20C;
u32 total_rom_size;
u32 offset_0x214;
u32 offset_0x218;
u32 offset_0x21C;
u32 modcrypt1_start;
u32 modcrypt1_size;
u32 modcrypt2_start;
u32 modcrypt2_size;
u32 tid_low;
u32 tid_high;
u32 public_sav_size;
u32 private_sav_size;
u8 reserved3[176];
u8 age_ratings[0x10];
u8 hmac_arm9[20];
u8 hmac_arm7[20];
u8 hmac_digest_master[20];
u8 hmac_icon_title[20];
u8 hmac_arm9i[20];
u8 hmac_arm7i[20];
u8 reserved4[40];
u8 hmac_arm9_no_secure[20];
u8 reserved5[2636];
u8 debug_args[0x180];
u8 rsa_signature[0x80];
} tDSiHeader;
#define __NDSHeader ((tNDSHeader *)0x02FFFE00)
#define __DSiHeader ((tDSiHeader *)0x02FFE000)
/*!
\brief the NDS banner format.
See gbatek for more information.
*/
typedef struct sNDSBanner {
u16 version; //!< version of the banner.
u16 crc; //!< 16 bit crc/checksum of the banner.
u8 reserved[28];
u8 icon[512]; //!< 32*32 icon of the game with 4 bit per pixel.
u16 palette[16]; //!< the pallete of the icon.
u16 titles[6][128]; //!< title of the game in 6 different languages.
} tNDSBanner;
#ifdef __cplusplus
extern "C" {
#endif
#ifdef ARM9
#define BUS_OWNER_ARM9 true
#define BUS_OWNER_ARM7 false
static inline
/*! \fn void sysSetCartOwner(bool arm9)
\brief Sets the owner of the GBA cart. Both CPUs cannot have access to the gba cart (slot 2).
\param arm9 if true the arm9 is the owner, otherwise the arm7
*/
void sysSetCartOwner(bool arm9) {
REG_EXMEMCNT = (REG_EXMEMCNT & ~ARM7_OWNS_ROM) | (arm9 ? 0 : ARM7_OWNS_ROM);
}
static inline
/*! \fn void sysSetCardOwner(bool arm9)
\brief Sets the owner of the DS card bus. Both CPUs cannot have access to the DS card bus (slot 1).
* \param arm9 if true the arm9 is the owner, otherwise the arm7
*/
void sysSetCardOwner(bool arm9) {
REG_EXMEMCNT = (REG_EXMEMCNT & ~ARM7_OWNS_CARD) | (arm9 ? 0 : ARM7_OWNS_CARD);
}
static inline
/*! \fn void sysSetBusOwners(bool arm9rom, bool arm9card)
\brief Sets the owner of the DS card bus (slot 1) and gba cart bus (slot 2). Only one cpu may access the device at a time.
* \param arm9rom if true the arm9 is the owner of slot 2, otherwise the arm7
* \param arm9card if true the arm9 is the owner of slot 1, otherwise the arm7
*/
void sysSetBusOwners(bool arm9rom, bool arm9card) {
REG_EXMEMCNT = (REG_EXMEMCNT & ~(ARM7_OWNS_CARD|ARM7_OWNS_ROM)) |
(arm9card ? 0: ARM7_OWNS_CARD) |
(arm9rom ? 0: ARM7_OWNS_ROM );
}
#endif //ARM9
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,175 @@
/*---------------------------------------------------------------------------------
ndstypes.h -- Common types (and a few useful macros)
Copyright (C) 2005 - 2008
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.
---------------------------------------------------------------------------------*/
/*! \file ndstypes.h
\brief Custom types employed by libnds
*/
#ifndef _NDSTYPES_INCLUDE
#define _NDSTYPES_INCLUDE
//---------------------------------------------------------------------------------
// define libnds types in terms of stdint
#include <stdint.h>
#include <stdbool.h>
//---------------------------------------------------------------------------------
// libgba compatible section macros
//---------------------------------------------------------------------------------
#define ITCM_CODE __attribute__((section(".itcm"), long_call))
#define DTCM_DATA __attribute__((section(".dtcm")))
#define DTCM_BSS __attribute__((section(".sbss")))
#define TWL_CODE __attribute__((section(".twl")))
#define TWL_DATA __attribute__((section(".twl")))
#define TWL_BSS __attribute__((section(".twl_bss")))
//! aligns a struct (and other types?) to m, making sure that the size of the struct is a multiple of m.
#define ALIGN(m) __attribute__((aligned (m)))
//! packs a struct (and other types?) so it won't include padding bytes.
#define PACKED __attribute__ ((packed))
#define packed_struct struct PACKED
//---------------------------------------------------------------------------------
// These are linked to the bin2o macro in the Makefile
//---------------------------------------------------------------------------------
#define GETRAW(name) (name)
#define GETRAWSIZE(name) ((int)name##_size)
#define GETRAWEND(name) ((int)name##_end)
/*!
\brief returns a number with the nth bit set.
*/
#define BIT(n) (1 << (n))
//! 8 bit unsigned integer.
typedef uint8_t uint8;
//! 16 bit unsigned integer.
typedef uint16_t uint16;
//! 32 bit unsigned integer.
typedef uint32_t uint32;
//! 64 bit unsigned integer.
typedef uint64_t uint64;
//! 8 bit signed integer.
typedef int8_t int8;
//! 16 bit signed integer.
typedef int16_t int16;
//! 32 bit signed integer.
typedef int32_t int32;
//! 64 bit signed integer.
typedef int64_t int64;
//! 32 bit signed floating point number.
typedef float float32;
//! 64 bit signed floating point number.
typedef double float64;
//! 8 bit volatile unsigned integer.
typedef volatile uint8_t vuint8;
//! 16 bit volatile unsigned integer.
typedef volatile uint16_t vuint16;
//! 32 bit volatile unsigned integer.
typedef volatile uint32_t vuint32;
//! 64 bit volatile unsigned integer.
typedef volatile uint64_t vuint64;
//! 8 bit volatile signed integer.
typedef volatile int8_t vint8;
//! 16 bit volatile signed integer.
typedef volatile int16_t vint16;
//! 32 bit volatile signed integer.
typedef volatile int32_t vint32;
//! 64 bit volatile signed integer.
typedef volatile int64_t vint64;
//! 32 bit volatile signed floating point number.
typedef volatile float32 vfloat32;
//! 64 bit volatile signed floating point number.
typedef volatile float64 vfloat64;
//! 8 bit unsigned integer.
typedef uint8_t byte;
//! 8 bit unsigned integer.
typedef uint8_t u8;
//! 16 bit unsigned integer.
typedef uint16_t u16;
//! 32 bit unsigned integer.
typedef uint32_t u32;
//! 64 bit unsigned integer.
typedef uint64_t u64;
//! 8 bit signed integer.
typedef int8_t s8;
//! 16 bit signed integer.
typedef int16_t s16;
//! 32 bit signed integer.
typedef int32_t s32;
//! 64 bit signed integer.
typedef int64_t s64;
//! 8 bit volatile unsigned integer.
typedef volatile u8 vu8;
//! 16 bit volatile unsigned integer.
typedef volatile u16 vu16;
//! 32 bit volatile unsigned integer.
typedef volatile u32 vu32;
//! 64 bit volatile unsigned integer.
typedef volatile u64 vu64;
//! 8 bit volatile signed integer.
typedef volatile s8 vs8;
//! 16 bit volatile signed integer.
typedef volatile s16 vs16;
//! 32 bit volatile signed integer.
typedef volatile s32 vs32;
//! 64 bit volatile signed integer.
typedef volatile s64 vs64;
typedef uint32_t sec_t;
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
// Handy function pointer typedefs
//! a function pointer that takes no arguments and doesn't return anything.
typedef void (* VoidFn)(void);
typedef void (* IntFn)(void);
typedef void (* fp)(void);
//---------------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------------

View File

@ -0,0 +1,329 @@
/*---------------------------------------------------------------------------------
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.
---------------------------------------------------------------------------------*/
/*
This file should be deprecated.
All hardware register defines should be replaced with REG_ for consistency and namespacing
http://forum.gbadev.org/viewtopic.php?t=4993
*/
#ifndef NDS_REGISTERS_H
#define NDS_REGISTERS_H
#warning "header provided for assistance in porting to new register names, do not use for release code"
#include <nds/ndstypes.h>
// math registers
#define DIV_CR REG_DIVCNT
#define DIV_NUMERATOR64 REG_DIV_NUMER
#define DIV_NUMERATOR32 REG_DIV_NUMER_L
#define DIV_DENOMINATOR64 REG_DIV_DENOM
#define DIV_DENOMINATOR32 REG_DIV_DENOM_L
#define DIV_RESULT64 REG_DIV_RESULT
#define DIV_RESULT32 REG_DIV_RESULT_L
#define DIV_REMAINDER64 REG_DIVREM_RESULT
#define DIV_REMAINDER32 REG_DIVREM_RESULT_L
#define SQRT_CR REG_SQRTCNT
#define SQRT_PARAM64 REG_SQRT_PARAM
#define SQRT_PARAM32 REG_SQRT_PARAM_L
#define SQRT_RESULT32 REG_SQRT_RESULT
// graphics registers
#define DISPLAY_CR REG_DISPCNT
#ifdef ARM9
#define WAIT_CR REG_EXMEMCNT
#else
#define WAIT_CR REG_EXMEMSTAT
#endif
#define DISP_SR REG_DISPSTAT
#define DISP_Y REG_VCOUNT
#define BG0_CR REG_BG0CNT
#define BG1_CR REG_BG1CNT
#define BG2_CR REG_BG2CNT
#define BG3_CR REG_BG3CNT
#define BG0_X0 REG_BG0HOFS
#define BG0_Y0 REG_BG0VOFS
#define BG1_X0 REG_BG1HOFS
#define BG1_Y0 REG_BG1VOFS
#define BG2_X0 REG_BG2HOFS
#define BG2_Y0 REG_BG2VOFS
#define BG3_X0 REG_BG3HOFS
#define BG3_Y0 REG_BG3VOFS
#define BG2_XDX REG_BG2PA
#define BG2_XDY REG_BG2PB
#define BG2_YDX REG_BG2PC
#define BG2_YDY REG_BG2PD
#define BG2_CX REG_BG2X
#define BG2_CY REG_BG2Y
#define BG3_XDX REG_BG3PA
#define BG3_XDY REG_BG3PB
#define BG3_YDX REG_BG3PC
#define BG3_YDY REG_BG3PD
#define BG3_CX REG_BG3X
#define BG3_CY REG_BG3Y
#define REG_WIN0H (*(vu16*)0x4000040)
#define REG_WIN1H (*(vu16*)0x4000042)
#define REG_WIN0V (*(vu16*)0x4000044)
#define REG_WIN1V (*(vu16*)0x4000046)
#define REG_WININ (*(vu16*)0x4000048)
#define REG_WINOUT (*(vu16*)0x400004A)
#define MOSAIC_CR REG_MOSAIC
#define BLEND_CR REG_BLDCNT
#define BLEND_AB REG_BLDALPHA
#define BLEND_Y REG_BLDY
#define SUB_BLEND_CR REG_BLDCNT_SUB
#define SUB_BLEND_AB REG_BLDALPHA_SUB
#define SUB_BLEND_Y REG_BLDY_SUB
#define SERIAL_CR REG_SPICNT
#define SERIAL_DATA REG_SPIDATA
#define SIO_CR REG_SIOCNT
#define R_CR REG_RCNT
#define DISP_CAPTURE REG_DISPCAPCNT
#define BRIGHTNESS REG_MASTER_BRIGHT
#define SUB_BRIGHTNESS REG_MASTER_BRIGHT_SUB
/* secondary screen */
#define SUB_DISPLAY_CR REG_DISPCNT_SUB
#define SUB_BG0_CR REG_BG0CNT_SUB
#define SUB_BG1_CR REG_BG1CNT_SUB
#define SUB_BG2_CR REG_BG2CNT_SUB
#define SUB_BG3_CR REG_BG3CNT_SUB
#define SUB_BG0_X0 REG_BG0HOFS_SUB
#define SUB_BG0_Y0 REG_BG0VOFS_SUB
#define SUB_BG1_X0 REG_BG1HOFS_SUB
#define SUB_BG1_Y0 REG_BG1VOFS_SUB
#define SUB_BG2_X0 REG_BG2HOFS_SUB
#define SUB_BG2_Y0 REG_BG2VOFS_SUB
#define SUB_BG3_X0 REG_BG3HOFS_SUB
#define SUB_BG3_Y0 REG_BG3VOFS_SUB
#define SUB_BG2_XDX REG_BG2PA_SUB
#define SUB_BG2_XDY REG_BG2PB_SUB
#define SUB_BG2_YDX REG_BG2PC_SUB
#define SUB_BG2_YDY REG_BG2PD_SUB
#define SUB_BG2_CX REG_BG2X_SUB
#define SUB_BG2_CY REG_BG2Y_SUB
#define SUB_BG3_XDX REG_BG3PA_SUB
#define SUB_BG3_XDY REG_BG3PB_SUB
#define SUB_BG3_YDX REG_BG3PC_SUB
#define SUB_BG3_YDY REG_BG3PD_SUB
#define SUB_BG3_CX REG_BG3X_SUB
#define SUB_BG3_CY REG_BG3Y_SUB
#define REG_WIN0H_SUB (*(vu16*)0x4001040)
#define REG_WIN1H_SUB (*(vu16*)0x4001042)
#define REG_WIN0V_SUB (*(vu16*)0x4001044)
#define REG_WIN1V_SUB (*(vu16*)0x4001046)
#define REG_WININ_SUB (*(vu16*)0x4001048)
#define REG_WINOUT_SUB (*(vu16*)0x400104A)
#define SUB_MOSAIC_CR REG_MOSAIC_SUB
#define REG_BLDMOD_SUB (*(vu16*)0x4001050)
#define REG_COLV_SUB (*(vu16*)0x4001052)
#define REG_COLY_SUB (*(vu16*)0x4001054)
/*common*/
#define REG_DMA0SAD (*(vu32*)0x40000B0)
#define REG_DMA0SAD_L (*(vu16*)0x40000B0)
#define REG_DMA0SAD_H (*(vu16*)0x40000B2)
#define REG_DMA0DAD (*(vu32*)0x40000B4)
#define REG_DMA0DAD_L (*(vu16*)0x40000B4)
#define REG_DMA0DAD_H (*(vu16*)0x40000B6)
#define REG_DMA0CNT (*(vu32*)0x40000B8)
#define REG_DMA0CNT_L (*(vu16*)0x40000B8)
#define REG_DMA0CNT_H (*(vu16*)0x40000BA)
#define REG_DMA1SAD (*(vu32*)0x40000BC)
#define REG_DMA1SAD_L (*(vu16*)0x40000BC)
#define REG_DMA1SAD_H (*(vu16*)0x40000BE)
#define REG_DMA1DAD (*(vu32*)0x40000C0)
#define REG_DMA1DAD_L (*(vu16*)0x40000C0)
#define REG_DMA1DAD_H (*(vu16*)0x40000C2)
#define REG_DMA1CNT (*(vu32*)0x40000C4)
#define REG_DMA1CNT_L (*(vu16*)0x40000C4)
#define REG_DMA1CNT_H (*(vu16*)0x40000C6)
#define REG_DMA2SAD (*(vu32*)0x40000C8)
#define REG_DMA2SAD_L (*(vu16*)0x40000C8)
#define REG_DMA2SAD_H (*(vu16*)0x40000CA)
#define REG_DMA2DAD (*(vu32*)0x40000CC)
#define REG_DMA2DAD_L (*(vu16*)0x40000CC)
#define REG_DMA2DAD_H (*(vu16*)0x40000CE)
#define REG_DMA2CNT (*(vu32*)0x40000D0)
#define REG_DMA2CNT_L (*(vu16*)0x40000D0)
#define REG_DMA2CNT_H (*(vu16*)0x40000D2)
#define REG_DMA3SAD (*(vu32*)0x40000D4)
#define REG_DMA3SAD_L (*(vu16*)0x40000D4)
#define REG_DMA3SAD_H (*(vu16*)0x40000D6)
#define REG_DMA3DAD (*(vu32*)0x40000D8)
#define REG_DMA3DAD_L (*(vu16*)0x40000D8)
#define REG_DMA3DAD_H (*(vu16*)0x40000DA)
#define REG_DMA3CNT (*(vu32*)0x40000DC)
#define REG_DMA3CNT_L (*(vu16*)0x40000DC)
#define REG_DMA3CNT_H (*(vu16*)0x40000DE)
#define REG_TIME ( (vu16*)0x4000100)
#define REG_TM0D (*(vu16*)0x4000100)
#define REG_TM0CNT (*(vu16*)0x4000102)
#define REG_TM1D (*(vu16*)0x4000106)
#define REG_TM2D (*(vu16*)0x4000108)
#define REG_TM2CNT (*(vu16*)0x400010A)
#define REG_TM3D (*(vu16*)0x400010C)
#define REG_TM3CNT (*(vu16*)0x400010E)
#define REG_SIOCNT (*(vu16*)0x4000128)
#define REG_SIOMLT_SEND (*(vu16*)0x400012A)
#define KEYS REG_KEYINPUT
#define KEYS_CR REG_KEYCNT
//??? (sio defines, no link port though)
#define REG_RCNT (*(vu16*)0x4000134)
#define REG_HS_CTRL (*(vu16*)0x4000140)
/* Interupt enable registers */
#define IE REG_IE
#define IF REG_IF
#define IME REG_IME
/*controls power 0x30f is all on */
#define POWER_CR REG_POWERCNT
/* ram controllers 0x8 is enabled, other bits have to do with mapping */
#define REG_VRAM_A_CR (*(vu8*) 0x4000240)
#define REG_VRAM_B_CR (*(vu8*) 0x4000241)
#define REG_VRAM_C_CR (*(vu8*) 0x4000242)
#define REG_VRAM_D_CR (*(vu8*) 0x4000243)
#define REG_VRAM_E_CR (*(vu8*) 0x4000244)
#define REG_VRAM_F_CR (*(vu8*) 0x4000245)
#define REG_VRAM_G_CR (*(vu8*) 0x4000246)
#define REG_VRAM_H_CR (*(vu8*) 0x4000248)
#define REG_VRAM_I_CR (*(vu8*) 0x4000249)
#define REG_WRAM_CNT (*(vu8*) 0x4000247)
/*3D graphics stuff*/
#define REG_GFX_FIFO (*(vu32*) 0x4000400)
#define REG_GFX_STATUS (*(vu32*) 0x4000600)
#define REG_GFX_CONTROL (*(vu16*) 0x4000060)
#define REG_COLOR (*(vu32*) 0x4000480)
#define REG_VERTEX16 (*(vu32*) 0x400048C)
#define REG_TEXT_COORD (*(vu32*) 0x4000488)
#define REG_TEXT_FORMAT (*(vu32*) 0x40004A8)
#define REG_CLEAR_COLOR (*(vu32*) 0x4000350)
#define REG_CLEAR_DEPTH (*(vu16*) 0x4000354)
#define REG_LIGHT_VECTOR (*(vu32*) 0x40004C8)
#define REG_LIGHT_COLOR (*(vu32*) 0x40004CC)
#define REG_NORMAL (*(vu32*) 0x4000484)
#define REG_DIFFUSE_AMBIENT (*(vu32*) 0x40004C0)
#define REG_SPECULAR_EMISSION (*(vu32*) 0x40004C4)
#define REG_SHININESS (*(vu32*) 0x40004D0)
#define REG_POLY_FORMAT (*(vu32*) 0x40004A4)
#define REG_GFX_BEGIN (*(vu32*) 0x4000500)
#define REG_GFX_END (*(vu32*) 0x4000504)
#define REG_GFX_FLUSH (*(vu32*) 0x4000540)
#define REG_GFX_VIEWPORT (*(vu32*) 0x4000580)
#define REG_MTX_CONTROL (*(vu32*) 0x4000440)
#define REG_MTX_PUSH (*(vu32*) 0x4000444)
#define REG_MTX_POP (*(vu32*) 0x4000448)
#define REG_MTX_SCALE (*(vint32*) 0x400046C)
#define REG_MTX_TRANSLATE (*(vint32*) 0x4000470)
#define REG_MTX_RESTORE (*(vu32*) 0x4000450)
#define REG_MTX_STORE (*(vu32*) 0x400044C)
#define REG_MTX_IDENTITY (*(vu32*) 0x4000454)
#define REG_MTX_LOAD4x4 (*(volatile f32*) 0x4000458)
#define REG_MTX_LOAD4x3 (*(volatile f32*) 0x400045C)
#define REG_MTX_MULT4x4 (*(volatile f32*) 0x4000460)
#define REG_MTX_MULT4x3 (*(volatile f32*) 0x4000464)
#define REG_MTX_MULT3x3 (*(volatile f32*) 0x4000468)
// Card bus
#define CARD_CR1 REG_AUXSPICNT
#define CARD_CR1H REG_AUXSPICNTH
#define CARD_CR2 REG_ROMCTRL
#define CARD_EEPDATA REG_AUXSPIDATA
#define CARD_COMMAND REG_CARD_COMMAND
#define CARD_DATA_RD REG_CARD_DATA_RD
#define CARD_1B0 REG_CARD_1B0
#define CARD_1B4 REG_CARD_1B4
#define CARD_1B8 REG_CARD_1B8
#define CARD_1BA REG_CARD_1BA
// sound
#define SOUND_CR REG_SOUNDCNT
#define SOUND_MASTER_VOL REG_MASTER_VOLUME
#define SOUND_BIAS REG_SOUNDBIAS
#endif

View File

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2017
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.
---------------------------------------------------------------------------------*/
#ifndef RSA_H_INCLUDE
#define RSA_H_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#include "nds/ndstypes.h"
#include <stddef.h>
typedef struct swiRSAHeapContext {
void *heapStart;
void *heapEnd;
size_t heapSize;
} swiRSAHeapContext_t;
typedef struct swiRSAbuffers {
void *dst;
const void *sig;
const void *key;
} swiRSAbuffers_t;
int swiRSAInitHeap(swiRSAHeapContext_t *ctx, void *heapStart, size_t heapSize);
int swiRSADecryptRAW(swiRSAHeapContext_t *ctx, swiRSAbuffers_t *rsabuffers, size_t len);
int swiRSADecrypt(swiRSAHeapContext_t *ctx, void *dst, const void *sig, const void *key);
int swiRSADecryptPGP(swiRSAHeapContext_t *ctx, void *dst, const void *sig, const void *key);
#ifdef __cplusplus
}
#endif
#endif // RSA_H_INCLUDE

View File

@ -0,0 +1,94 @@
/*---------------------------------------------------------------------------------
DSi sha1 functions
Copyright (C) 2017
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.
---------------------------------------------------------------------------------*/
/*! \file sha1.h
\brief DSi SHA1 functions.
*/
#ifndef SHA1_H_INCLUDE
#define SHA1_H_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#include "nds/ndstypes.h"
#include <stddef.h>
typedef struct swiSHA1context {
u32 state[5]; /*!< intermediate digest state */
u32 total[2]; /*!< number of bytes processed */
u8 buffer[64]; /*!< data block being processed */
u32 fragment_size;
void (*sha_block)(struct swiSHA1context *ctx, const void *src, size_t len); /*!< data block being processed */
} swiSHA1context_t;
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void swiSHA1Init(swiSHA1context_t *ctx);
/**
* \brief SHA-1 process buffer
*
* \param ctx SHA-1 context
* \param data buffer to process
* \param len length of data
*/
void swiSHA1Update(swiSHA1context_t *ctx, const void *data, size_t len);
/**
* \brief SHA-1 final digest
*
* \param digest buffer to hold SHA-1 checksum result
* \param ctx SHA-1 context
*/
void swiSHA1Final(void *digest, swiSHA1context_t *ctx);
/**
* \brief SHA-1 checksum
*
* \param digest buffer to hold SHA-1 checksum result
* \param data buffer to process
* \param len length of data
*/
void swiSHA1Calc(void *digest, const void *data, size_t len);
/**
* \brief SHA-1 verify
*
* \param digest1 buffer containing hash to verify
* \param digest2 buffer containing hash to verify
*/
void swiSHA1Verify(const void *digest1, const void *digest2);
#ifdef __cplusplus
}
#endif
#endif // SHA1_H_INCLUDE

View File

@ -0,0 +1,451 @@
/*---------------------------------------------------------------------------------
Power control, keys, and HV clock registers
Copyright (C) 2005
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.
---------------------------------------------------------------------------------*/
/*! \file system.h
\brief NDS hardware definitions.
These definitions are usually only touched during
the initialization of the program.
*/
#ifndef NDS_SYSTEM_INCLUDE
#define NDS_SYSTEM_INCLUDE
#include "ndstypes.h"
//! LCD status register.
#define REG_DISPSTAT (*(vu16*)0x04000004)
//! LCD Status register bitdefines
typedef enum
{
DISP_IN_VBLANK = BIT(0), //!< The display currently in a vertical blank.
DISP_IN_HBLANK = BIT(1), //!< The display currently in a horizontal blank.
DISP_YTRIGGERED = BIT(2), //!< Current scanline and %DISP_Y match.
DISP_VBLANK_IRQ = BIT(3), //!< Interrupt on vertical blank.
DISP_HBLANK_IRQ = BIT(4), //!< Interrupt on horizontal blank.
DISP_YTRIGGER_IRQ = BIT(5) //!< Interrupt when current scanline and %DISP_Y match.
}DISP_BITS;
//! Current display scanline.
#define REG_VCOUNT (*(vu16*)0x4000006)
//! Halt control register.
/*! Writing 0x40 to HALT_CR activates GBA mode.
%HALT_CR can only be accessed via the BIOS.
*/
#define HALT_CR (*(vu16*)0x04000300)
//! Power control register.
/*! This register controls what hardware should
be turned on or off.
*/
#define REG_POWERCNT *(vu16*)0x4000304
#define REG_SCFG_ROM *(vu16*)0x4004000
#ifdef ARM7
#define REG_SCFG_A9ROM *(vu8*)0x4004000
#define REG_SCFG_A7ROM *(vu8*)0x4004001 // ??
#endif
#define REG_SCFG_CLK *(vu16*)0x4004004
#define REG_SCFG_RST *(vu16*)0x4004006
#define REG_SCFG_EXT *(vu32*)0x4004008
#define REG_SCFG_MC *(vu16*)0x4004010
static inline
/*!
\brief sets the Y trigger(?)
\param Yvalue the value for the Y trigger.
*/
void SetYtrigger(int Yvalue) {
REG_DISPSTAT = (REG_DISPSTAT & 0x007F ) | (Yvalue << 8) | (( Yvalue & 0x100 ) >> 1) ;
}
#define PM_ARM9_DIRECT BIT(16)
//! Power Management control bits
typedef enum
{
PM_SOUND_AMP = BIT(0), //!< Power the sound hardware (needed to hear stuff in GBA mode too).
PM_SOUND_MUTE = BIT(1), //!< Mute the main speakers, headphone output will still work.
PM_BACKLIGHT_BOTTOM = BIT(2), //!< Enable the bottom backlight if set.
PM_BACKLIGHT_TOP = BIT(3), //!< Enable the top backlight if set.
PM_SYSTEM_PWR = BIT(6), //!< Turn the power *off* if set.
POWER_LCD = PM_ARM9_DIRECT | BIT(0), //!< Controls the power for both LCD screens.
POWER_2D_A = PM_ARM9_DIRECT | BIT(1), //!< Controls the power for the main 2D core.
POWER_MATRIX = PM_ARM9_DIRECT | BIT(2), //!< Controls the power for the 3D matrix.
POWER_3D_CORE = PM_ARM9_DIRECT | BIT(3), //!< Controls the power for the main 3D core.
POWER_2D_B = PM_ARM9_DIRECT | BIT(9), //!< Controls the power for the sub 2D core.
POWER_SWAP_LCDS = PM_ARM9_DIRECT | BIT(15), //!< Controls which screen should use the main core.
POWER_ALL_2D = PM_ARM9_DIRECT | POWER_LCD | POWER_2D_A | POWER_2D_B, //!< power just 2D hardware.
POWER_ALL = PM_ARM9_DIRECT | POWER_ALL_2D | POWER_3D_CORE | POWER_MATRIX //!< power everything.
}PM_Bits;
/*! \brief Causes the nds to go to sleep.
The nds will be reawakened when the lid is opened.
\note By default, this is automatically called when closing the lid.
*/
void systemSleep(void);
/*! Set the LED blink mode
\param bm What to power on.
*/
void ledBlink(int bm);
//! Checks whether the application is running in DSi mode.
static inline bool isDSiMode() {
extern bool __dsimode;
return __dsimode;
}
//--------------------------------------------------------------
// ARM9 section
//--------------------------------------------------------------
#ifdef ARM9
//! Turns on specified hardware.
/*! May be called from arm7 or arm9 (arm9 power bits will be ignored by arm7, arm7 power bits
will be passed to the arm7 from the arm9).
\param bits What to power on.
*/
void powerOn(int bits);
//! Turns off specified hardware.
/*! May be called from arm7 or arm9 (arm9 power bits will be ignored by arm7, arm7 power bits
will be passed to the arm7 from the arm9).
\param bits What to power on.
*/
void powerOff(int bits);
//internal fifo handlers
void systemMsgHandler(int bytes, void* user_data);
void systemValueHandler(u32 value, void* data);
//! Switches the screens.
static inline void lcdSwap(void) { REG_POWERCNT ^= POWER_SWAP_LCDS; }
//! Forces the main core to display on the top.
static inline void lcdMainOnTop(void) { REG_POWERCNT |= POWER_SWAP_LCDS; }
//! Forces the main core to display on the bottom.
static inline void lcdMainOnBottom(void) { REG_POWERCNT &= ~POWER_SWAP_LCDS; }
//! Powers down the DS
static inline
void systemShutDown(void) {
powerOn(PM_SYSTEM_PWR);
}
void readFirmware(u32 address, void *buffer, u32 length);
int writeFirmware(u32 address, void *buffer, u32 length);
//! gets the DS Battery level
u32 getBatteryLevel();
//! Set the arm9 vector base
/*! Arm9 only
\param highVector high vector
*/
void setVectorBase(int highVector);
/*! \brief A struct with all the CPU exeption vectors.
each member contains an ARM instuction that will be executed when an exeption occured.
See gbatek for more information.
*/
typedef struct sysVectors_t {
VoidFn reset; //!< CPU reset.
VoidFn undefined; //!< undefined instruction.
VoidFn swi; //!< software interrupt.
VoidFn prefetch_abort; //!< prefetch abort.
VoidFn data_abort; //!< data abort.
VoidFn fiq; //!< fast interrupt.
} sysVectors;
extern sysVectors SystemVectors;
void setSDcallback(void(*callback)(int));
/*!
\brief Sets the ARM9 clock speed, only possible in DSi mode
\param speed CPU speed (false = 67.03MHz, true = 134.06MHz)
\return The old CPU speed value
*/
bool setCpuClock(bool speed);
// Helper functions for heap size
//! returns current start of heap space
u8* getHeapStart();
//! returns current end of heap space
u8* getHeapEnd();
//! returns current heap limit
u8* getHeapLimit();
#endif //ARM9
//--------------------------------------------------------------
// ARM7 section
//--------------------------------------------------------------
#ifdef ARM7
#define REG_CONSOLEID (*(vu64*)0x04004D00)
//! Power-controlled hardware devices accessable to the ARM7.
/*! Note that these should only be used when programming for
the ARM7. Trying to boot up these hardware devices via
the ARM9 would lead to unexpected results.
ARM7 only.
*/
typedef enum {
POWER_SOUND = BIT(0), //!< Controls the power for the sound controller.
PM_CONTROL_REG = 0, //!< Selects the PM control register
PM_BATTERY_REG = 1, //!< Selects the PM battery register
PM_AMPLIFIER_REG = 2, //!< Selects the PM amplifier register
PM_READ_REGISTER = (1<<7), //!< Selects the PM read register
PM_AMP_OFFSET = 2, //!< Selects the PM amp register
PM_GAIN_OFFSET = 3, //!< Selects the PM gain register
PM_BACKLIGHT_LEVEL = 4, //!< Selects the DS Lite backlight register
PM_GAIN_20 = 0, //!< Sets the mic gain to 20db
PM_GAIN_40 = 1, //!< Sets the mic gain to 40db
PM_GAIN_80 = 2, //!< Sets the mic gain to 80db
PM_GAIN_160 = 3, //!< Sets the mic gain to 160db
PM_AMP_ON = 1, //!< Turns the sound amp on
PM_AMP_OFF = 0 //!< Turns the sound amp off
} ARM7_power;
//!< PM control register bits - LED control
#define PM_LED_CONTROL(m) ((m)<<4)
//install the fifo power handler
void installSystemFIFO(void);
//cause the ds to enter low power mode
void systemSleep(void);
//internal can check if sleep mode is enabled
int sleepEnabled(void);
// Warning: These functions use the SPI chain, and are thus 'critical'
// sections, make sure to disable interrupts during the call if you've
// got a VBlank IRQ polling the touch screen, etc...
// Read/write a power management register
int writePowerManagement(int reg, int command);
static inline
int readPowerManagement(int reg) {
return writePowerManagement((reg)|PM_READ_REGISTER, 0);
}
static inline
void powerOn(int bits) {
REG_POWERCNT |= bits;
}
static inline
void powerOff(PM_Bits bits) {
REG_POWERCNT &= ~bits;
}
void readUserSettings();
void systemShutDown();
#endif /* ARM7 */
/*! \brief Backlight level settings.
Note, these are only available on DS Lite.
*/
typedef enum {
BACKLIGHT_LOW, //!< low backlight setting.
BACKLIGHT_MED, //!< medium backlight setting.
BACKLIGHT_HIGH, //!< high backlight setting.
BACKLIGHT_MAX //!< max backlight setting.
} BACKLIGHT_LEVELS;
// Common functions
/*!
\brief User's DS settings.
Defines the structure the DS firmware uses for transfer
of the user's settings to the booted program.
Theme/Color values:
- 0 = Gray
- 1 = Brown
- 2 = Red
- 3 = Pink
- 4 = Orange
- 5 = Yellow
- 6 = Yellow/Green-ish
- 7 = Green
- 8 = Dark Green
- 9 = Green/Blue-ish
- 10 = Light Blue
- 11 = Blue
- 12 = Dark Blue
- 13 = Dark Purple
- 14 = Purple
- 15 = Purple/Red-ish
Language values:
- 0 = Japanese
- 1 = English
- 2 = French
- 3 = German
- 4 = Italian
- 5 = Spanish
- 6 = Chinese(?)
- 7 = Unknown/Reserved
*/
typedef struct tPERSONAL_DATA
{
u8 RESERVED0[2]; // ??? (0x05 0x00). (version according to gbatek)
u8 theme; //!< The user's theme color (0-15).
u8 birthMonth; //!< The user's birth month (1-12).
u8 birthDay; //!< The user's birth day (1-31).
u8 RESERVED1[1]; // ???
s16 name[10]; //!< The user's name in UTF-16 format.
u16 nameLen; //!< The length of the user's name in characters.
s16 message[26]; //!< The user's message.
u16 messageLen; //!< The length of the user's message in characters.
u8 alarmHour; //!< What hour the alarm clock is set to (0-23).
u8 alarmMinute; //!< What minute the alarm clock is set to (0-59).
//0x02FFFCD3 alarm minute
u8 RESERVED2[4]; // ??? 0x02FFFCD4 ??
u16 calX1; //!< Touchscreen calibration: first X touch
u16 calY1; //!< Touchscreen calibration: first Y touch
u8 calX1px; //!< Touchscreen calibration: first X touch pixel
u8 calY1px; //!< Touchscreen calibration: first X touch pixel
u16 calX2; //!< Touchscreen calibration: second X touch
u16 calY2; //!< Touchscreen calibration: second Y touch
u8 calX2px; //!< Touchscreen calibration: second X touch pixel
u8 calY2px; //!< Touchscreen calibration: second Y touch pixel
struct {
unsigned int language : 3; //!< User's language.
unsigned int gbaScreen : 1; //!< GBA screen selection (lower screen if set, otherwise upper screen).
unsigned int defaultBrightness : 2; //!< Brightness level at power on, dslite.
unsigned int autoMode : 1; //!< The DS should boot from the DS cart or GBA cart automatically if one is inserted.
unsigned int RESERVED5 : 2; // ???
unsigned int settingsLost : 1; //!< User Settings Lost (0=Normal, 1=Prompt/Settings Lost)
unsigned int RESERVED6 : 6; // ???
} PACKED;
u16 RESERVED3; // ???
u32 rtcOffset; //!< Real Time Clock offset.
u32 RESERVED4; // ???
} PACKED PERSONAL_DATA ;
//! Default location for the user's personal data (see %PERSONAL_DATA).
#define PersonalData ((PERSONAL_DATA*)0x2FFFC80)
//! struct containing time and day of the real time clock.
typedef struct {
u8 year; //!< add 2000 to get 4 digit year
u8 month; //!< 1 to 12
u8 day; //!< 1 to (days in month)
u8 weekday; //!< day of week
u8 hours; //!< 0 to 11 for AM, 52 to 63 for PM
u8 minutes; //!< 0 to 59
u8 seconds; //!< 0 to 59
} RTCtime;
// argv struct magic number
#define ARGV_MAGIC 0x5f617267
//structure used to set up argc/argv on the DS
struct __argv {
int argvMagic; // argv magic number, set to 0x5f617267 ('_arg') if valid
char *commandLine; // base address of command line, set of null terminated strings
int length; // total length of command line
int argc; // internal use, number of arguments
char **argv; // internal use, argv pointer
int dummy; // internal use
u32 host; // internal use, host ip for dslink
};
#define __system_argv ((struct __argv *)0x02FFFE70)
#define BOOTSIG 0x62757473746F6F62ULL // 'bootstub'
struct __bootstub {
u64 bootsig;
VoidFn arm9reboot;
VoidFn arm7reboot;
u32 bootsize;
};
#ifdef ARM9
/*!
\brief returns a cached mirror of an address.
\param address an address.
\return a pointer to the cached mirror of that address.
*/
void *memCached(void *address);
/*!
\brief returns an uncached mirror of an address.
\param address an address.
\return a pointer to the uncached mirror of that address.
*/
void *memUncached(void *address);
void resetARM7(u32 address);
#endif
#ifdef ARM7
void resetARM9(u32 address);
#endif
#endif

View File

@ -0,0 +1,290 @@
/*---------------------------------------------------------------------------------
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.
---------------------------------------------------------------------------------*/
/*! \file timers.h
\brief Contains defines, macros and functions for ARM7 and ARM9 timer operation.
It also contains a simplified API for timer use and some cpu timing functions.
The timers are fed with a 33.513982 MHz source on the ARM9 and ARM7.
\note that dswifi will use timer 3 on the arm9, so don't use that if you use dswifi.
*/
#ifndef NDS_TIMERS_INCLUDE
#define NDS_TIMERS_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#include <nds/ndstypes.h>
//! Returns a dereferenced pointer to the data register for timer control Register.
/*! <b>Example Usage:</b> %TIMER_CR(x) = %TIMER_ENABLE | %ClockDivider_64;
Possible bit defines:
\see TIMER_ENABLE
\see TIMER_IRQ_REQ
\see TIMER_CASCADE
\see ClockDivider
*/
#define TIMER_CR(n) (*(vu16*)(0x04000102+((n)<<2)))
//! Same as %TIMER_CR(0).
#define TIMER0_CR (*(vu16*)0x04000102)
//! Same as %TIMER_CR(1).
#define TIMER1_CR (*(vu16*)0x04000106)
//! Same as %TIMER_CR(2).
#define TIMER2_CR (*(vu16*)0x0400010A)
//! Same as %TIMER_CR(3).
#define TIMER3_CR (*(vu16*)0x0400010E)
//! Returns a dereferenced pointer to the data register for timer number "n".
/*! \see TIMER_CR(n)
\see TIMER_FREQ(n)
%TIMER_DATA(n) when set will latch that value into the counter. Every time the
counter rolls over, %TIMER_DATA(0) will return to the latched value. This allows
you to control the frequency of the timer using the following formula:\n
%TIMER_DATA(x) = -(BUS_CLOCK/(freq * divider));
<b>Example Usage:</b>
%TIMER_DATA(0) = value; were 0 can be 0 through 3 and value is 16 bits.
*/
#define TIMER_DATA(n) (*(vu16*)(0x04000100+((n)<<2)))
//! Same as %TIMER_DATA(0).
#define TIMER0_DATA (*(vu16*)0x04000100)
//! Same as %TIMER_DATA(1).
#define TIMER1_DATA (*(vu16*)0x04000104)
//! Same as %TIMER_DATA(2).
#define TIMER2_DATA (*(vu16*)0x04000108)
//! Same as %TIMER_DATA(3).
#define TIMER3_DATA (*(vu16*)0x0400010C)
//! the speed in which the timer ticks in hertz.
#define BUS_CLOCK (33513982)
//! Enables the timer.
#define TIMER_ENABLE (1<<7)
//! Causes the timer to request an Interrupt on overflow.
#define TIMER_IRQ_REQ (1<<6)
//! When set will cause the timer to count when the timer below overflows (unavailable for timer 0).
#define TIMER_CASCADE (1<<2)
//! allowable timer clock dividers.
typedef enum {
ClockDivider_1 = 0, //!< divides the timer clock by 1 (~33513.982 kHz)
ClockDivider_64 = 1, //!< divides the timer clock by 64 (~523.657 kHz)
ClockDivider_256 = 2, //!< divides the timer clock by 256 (~130.914 kHz)
ClockDivider_1024 = 3 //!< divides the timer clock by 1024 (~32.7284 kHz)
}ClockDivider;
//use the ClockDivider enum.
// Causes the timer to count at 33.514 MHz.
#define TIMER_DIV_1 (0)
// Causes the timer to count at (33.514 / 64) MHz.
#define TIMER_DIV_64 (1)
// Causes the timer to count at (33.514 / 256) MHz.
#define TIMER_DIV_256 (2)
// Causes the timer to count at (33.514 / 1024) MHz.
#define TIMER_DIV_1024 (3)
/*! \brief A macro that calculates %TIMER_DATA(n) settings for a given frequency of n.
will calculate the correct value for %TIMER_DATA(n) given the frequency in hertz
(number of times the timer should overflow per second).
<b>Example Usage:</b>
<pre>
//calls the timerCallBack function 5 times per second.
timerStart(0, ClockDivider_1024, TIMER_FREQ_1024(5), timerCallBack);
</pre>
Max frequency is: 33554432Hz
Min frequency is: 512Hz
\note Use the appropriate macro depending on the used clock divider.
*/
#define TIMER_FREQ(n) (-BUS_CLOCK/(n))
/*! \brief A macro that calculates %TIMER_DATA(n) settings for a given frequency of n.
will calculate the correct value for %TIMER_DATA(n) given the frequency in hertz
(number of times the timer should overflow per second).
<b>Example Usage:</b>
<pre>
//calls the timerCallBack function 5 times per second.
timerStart(0, ClockDivider_1024, TIMER_FREQ_1024(5), timerCallBack);
</pre>
Max frequency is: 524288Hz
Min frequency is: 8Hz
\note Use the appropriate macro depending on the used clock divider.
*/
#define TIMER_FREQ_64(n) (-(BUS_CLOCK>>6)/(n))
/*! \brief A macro that calculates %TIMER_DATA(n) settings for a given frequency of n.
will calculate the correct value for %TIMER_DATA(n) given the frequency in hertz
(number of times the timer should overflow per second).
<b>Example Usage:</b>
<pre>
//calls the timerCallBack function 5 times per second.
timerStart(0, ClockDivider_1024, TIMER_FREQ_1024(5), timerCallBack);
</pre>
Max frequency is: 131072Hz
Min frequency is: 2Hz
\note Use the appropriate macro depending on the used clock divider.
*/
#define TIMER_FREQ_256(n) (-(BUS_CLOCK>>8)/(n))
/*! \brief A macro that calculates %TIMER_DATA(n) settings for a given frequency of n.
will calculate the correct value for %TIMER_DATA(n) given the frequency in hertz
(number of times the timer should overflow per second).
<b>Example Usage:</b>
<pre>
//calls the timerCallBack function 5 times per second.
timerStart(0, ClockDivider_1024, TIMER_FREQ_1024(5), timerCallBack);
</pre>
Max frequency is: 32768Hz
Min frequency is: 0.5Hz
\note Use the appropriate macro depending on the used clock divider.
*/
#define TIMER_FREQ_1024(n) (-(BUS_CLOCK>>10)/(n))
/*! \brief start a hardware timer.
Callback is tied directly to interrupt table and called directly, resulting in less latency than the attached timer.
\param timer The hardware timer to use (0 - 3).
\param divider The timer channel clock divider (clock will tick at 33.513982 MHz / divider)
\param ticks The number of ticks which must elapse before the timer overflows
\param callback The callback to be called when the timer expires (if null, no IRQ will be generated by the timer)
*/
void timerStart(int timer, ClockDivider divider, u16 ticks, VoidFn callback);
/*! \brief returns the ticks elapsed since the last call to timerElapsed().
\param timer The hardware timer to use (0 - 3).
\return The number of ticks which have elapsed since the last call to timerElapsed().
*/
u16 timerElapsed(int timer);
static inline
/*! \brief returns the raw ticks of the specified timer.
\param timer The hardware timer to use (0 - 3).
\return the raw ticks of the specified timer data register.
*/
u16 timerTick(int timer) {
return TIMER_DATA(timer);
}
/*! \brief pauses the specified timer.
\param timer The hardware timer to use (0 - 3).
\return The number of ticks which have elapsed since the last call to timerElapsed().
*/
u16 timerPause(int timer);
static inline
/*! \brief unpauses the specified timer.
\param timer The hardware timer to use (0 - 3).
*/
void timerUnpause(int timer) {
TIMER_CR(timer) |= TIMER_ENABLE;
}
/*! \brief Stops the specified timer.
\param timer The hardware timer to use (0 - 3).
\return The number of ticks which have elapsed since the last call to timerElapsed().
*/
u16 timerStop(int timer);
/*! \brief begins cpu Timing using two timers for 32bit resolution.
\param timer The base hardware timer to use (0 - 2).
*/
void cpuStartTiming(int timer);
/*! \brief returns the number of ticks which have elapsed since cpuStartTiming.
\return The number of ticks which have elapsed since cpuStartTiming.
*/
u32 cpuGetTiming();
/*! \brief ends cpu Timing.
\return The number of ticks which have elapsed since cpuStartTiming.
*/
u32 cpuEndTiming();
static inline
u32 timerTicks2usec(u32 ticks) {
return (((u64)ticks)*1000000)/BUS_CLOCK;
}
static inline
u32 timerTicks2msec(u32 ticks) {
return (((u64)ticks)*1000)/BUS_CLOCK;
}
//use the macro versions...
static inline u16 timerFreqToTicks_1(int freq) {return -BUS_CLOCK / freq;}
static inline u16 timerFreqToTicks_64(int freq) {return (-BUS_CLOCK >> 6) / freq;}
static inline u16 timerFreqToTicks_256(int freq) {return (-BUS_CLOCK >> 8) / freq;}
static inline u16 timerFreqToTicks_1024(int freq) {return (-BUS_CLOCK >> 10) / freq;}
#ifdef __cplusplus
}
#endif
#endif //NDS_TIMERS_INCLUDE

View File

@ -0,0 +1,18 @@
#ifndef __TOUCH_H__
#define __TOUCH_H__
/*! \file
\brief contains a struct with touch screen data.
*/
//! holds data related to the touch screen.
typedef struct touchPosition {
u16 rawx; //!< Raw x value from the A2D
u16 rawy; //!< Raw y value from the A2D
u16 px; //!< Processes pixel X value
u16 py; //!< Processes pixel Y value
u16 z1; //!< Raw cross panel resistance
u16 z2; //!< Raw cross panel resistance
} touchPosition;
#endif

View File

@ -0,0 +1,21 @@
Copyright (C) 2005 - 2008
Michael Noland (joat)
Jason Rogers (dovoto)
Dave Murpy (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.

View File

@ -0,0 +1,209 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2008 - 2010
Dave Murphy (WinterMute)
Jason Rogers (Dovoto)
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/ipc.h>
#include <nds/fifocommon.h>
#include <nds/fifomessages.h>
#include <nds/system.h>
//---------------------------------------------------------------------------------
int getFreeChannel(void) {
//---------------------------------------------------------------------------------
int i;
for(i = 0; i < 16; i++)
if(!(SCHANNEL_CR(i) & SCHANNEL_ENABLE))
return i;
return -1;
}
//---------------------------------------------------------------------------------
int getFreePSGChannel(void) {
//---------------------------------------------------------------------------------
int i;
for(i = 8; i < 14; i++)
if(!(SCHANNEL_CR(i) & SCHANNEL_ENABLE))
return i;
return -1;
}
//---------------------------------------------------------------------------------
int getFreeNoiseChannel(void) {
//---------------------------------------------------------------------------------
int i;
for(i = 14; i < 16; i++)
if(!(SCHANNEL_CR(i) & SCHANNEL_ENABLE))
return i;
return -1;
}
//---------------------------------------------------------------------------------
void micSwapHandler(u8* buffer, int length) {
//---------------------------------------------------------------------------------
FifoMessage msg;
msg.type = MIC_BUFFER_FULL_MESSAGE;
msg.MicBufferFull.buffer = (void*)buffer;
msg.MicBufferFull.length = (u32)length;
fifoSendDatamsg(FIFO_SOUND, sizeof(msg) , (u8*)&msg);
}
//---------------------------------------------------------------------------------
void soundDataHandler(int bytes, void *user_data) {
//---------------------------------------------------------------------------------
int channel = -1;
FifoMessage msg;
fifoGetDatamsg(FIFO_SOUND, bytes, (u8*)&msg);
if(msg.type == SOUND_PLAY_MESSAGE) {
channel = getFreeChannel();
if(channel >= 0) {
SCHANNEL_SOURCE(channel) = (u32)msg.SoundPlay.data;
SCHANNEL_REPEAT_POINT(channel) = msg.SoundPlay.loopPoint;
SCHANNEL_LENGTH(channel) = msg.SoundPlay.dataSize;
SCHANNEL_TIMER(channel) = SOUND_FREQ(msg.SoundPlay.freq);
SCHANNEL_CR(channel) = SCHANNEL_ENABLE | SOUND_VOL(msg.SoundPlay.volume) | SOUND_PAN(msg.SoundPlay.pan) | (msg.SoundPlay.format << 29) | (msg.SoundPlay.loop ? SOUND_REPEAT : SOUND_ONE_SHOT);
}
} else if(msg.type == SOUND_PSG_MESSAGE) {
channel = getFreePSGChannel();
if(channel >= 0)
{
SCHANNEL_CR(channel) = SCHANNEL_ENABLE | msg.SoundPsg.volume | SOUND_PAN(msg.SoundPsg.pan) | (3 << 29) | (msg.SoundPsg.dutyCycle << 24);
SCHANNEL_TIMER(channel) = SOUND_FREQ(msg.SoundPsg.freq);
}
} else if(msg.type == SOUND_NOISE_MESSAGE) {
channel = getFreeNoiseChannel();
if(channel >= 0) {
SCHANNEL_CR(channel) = SCHANNEL_ENABLE | msg.SoundPsg.volume | SOUND_PAN(msg.SoundPsg.pan) | (3 << 29);
SCHANNEL_TIMER(channel) = SOUND_FREQ(msg.SoundPsg.freq);
}
} else if(msg.type == MIC_RECORD_MESSAGE) {
micStartRecording(msg.MicRecord.buffer, msg.MicRecord.bufferLength, msg.MicRecord.freq, 1, msg.MicRecord.format, micSwapHandler);
channel = 17;
}
fifoSendValue32(FIFO_SOUND, (u32)channel);
}
//---------------------------------------------------------------------------------
void enableSound() {
//---------------------------------------------------------------------------------
powerOn(POWER_SOUND);
writePowerManagement(PM_CONTROL_REG, ( readPowerManagement(PM_CONTROL_REG) & ~PM_SOUND_MUTE ) | PM_SOUND_AMP );
REG_SOUNDCNT = SOUND_ENABLE;
REG_MASTER_VOLUME = 127;
}
//---------------------------------------------------------------------------------
void disableSound() {
//---------------------------------------------------------------------------------
REG_SOUNDCNT &= ~SOUND_ENABLE;
writePowerManagement(PM_CONTROL_REG, ( readPowerManagement(PM_CONTROL_REG) & ~PM_SOUND_AMP ) | PM_SOUND_MUTE );
powerOff(POWER_SOUND);
}
//---------------------------------------------------------------------------------
void soundCommandHandler(u32 command, void* userdata) {
//---------------------------------------------------------------------------------
int cmd = (command ) & 0x00F00000;
int data = command & 0xFFFF;
int channel = (command >> 16) & 0xF;
switch(cmd) {
case SOUND_MASTER_ENABLE:
enableSound();
break;
case SOUND_MASTER_DISABLE:
disableSound();
break;
case SOUND_SET_VOLUME:
SCHANNEL_CR(channel) &= ~0xFF;
SCHANNEL_CR(channel) |= data;
break;
case SOUND_SET_PAN:
SCHANNEL_CR(channel) &= ~SOUND_PAN(0xFF);
SCHANNEL_CR(channel) |= SOUND_PAN(data);
break;
case SOUND_SET_FREQ:
SCHANNEL_TIMER(channel) = SOUND_FREQ(data);
break;
case SOUND_SET_WAVEDUTY:
SCHANNEL_CR(channel) &= ~(7 << 24);
SCHANNEL_CR(channel) |= (data) << 24;
break;
case SOUND_KILL:
SCHANNEL_CR(channel) &= ~SCHANNEL_ENABLE;
break;
case SOUND_PAUSE:
SCHANNEL_CR(channel) &= ~SCHANNEL_ENABLE;
break;
case SOUND_RESUME:
SCHANNEL_CR(channel) |= SCHANNEL_ENABLE;
break;
case MIC_STOP:
micStopRecording();
break;
default: break;
}
}
//---------------------------------------------------------------------------------
void installSoundFIFO(void) {
//---------------------------------------------------------------------------------
fifoSetDatamsgHandler(FIFO_SOUND, soundDataHandler, 0);
fifoSetValue32Handler(FIFO_SOUND, soundCommandHandler, 0);
}

View File

@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2017
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/system.h>
#include <nds/interrupts.h>
#include <nds/bios.h>
#define BASE_DELAY (100)
void twlEnableSlot1() {
int oldIME = enterCriticalSection();
while((REG_SCFG_MC & 0x0c) == 0x0c) swiDelay(1 * BASE_DELAY);
if(!(REG_SCFG_MC & 0x0c)) {
REG_SCFG_MC = (REG_SCFG_MC & ~0x0c) | 4;
swiDelay(10 * BASE_DELAY);
REG_SCFG_MC = (REG_SCFG_MC & ~0x0c) | 8;
swiDelay(10 * BASE_DELAY);
}
leaveCriticalSection(oldIME);
}
void twlDisableSlot1() {
int oldIME = enterCriticalSection();
while((REG_SCFG_MC & 0x0c) == 0x0c) swiDelay(1 * BASE_DELAY);
if((REG_SCFG_MC & 0x0c) == 8) {
REG_SCFG_MC = (REG_SCFG_MC & ~0x0c) | 0x0c;
while((REG_SCFG_MC & 0x0c) != 0) swiDelay(1 * BASE_DELAY);
}
leaveCriticalSection(oldIME);
}

View File

@ -0,0 +1,303 @@
/*---------------------------------------------------------------------------------
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 "nds/system.h"
#include "libnds_internal.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< 7; 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() {
//---------------------------------------------------------------------------------
__transferRegion()->unixTime++;
}
/* Nonzero if `y' is a leap year, else zero. */
#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
/* Number of leap years from 1970 to `y' (not including `y' itself). */
#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
/* Additional leapday in February of leap years. */
#define leapday(m, y) ((m) == 1 && leap (y))
/* Accumulated number of days from 01-Jan up to start of current month. */
static const short ydays[] = {
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
};
/* Length of month `m' (0 .. 11) */
#define monthlen(m, y) (ydays[(m)+1] - ydays[m] + leapday (m, y))
//---------------------------------------------------------------------------------
static time_t __mktime( RTCtime *dstime ) {
//---------------------------------------------------------------------------------
int years, months, days, hours, minutes, seconds;
years = dstime->year + 2000; /* year - 2000 -> year */
months = dstime->month -1; /* 0..11 */
days = dstime->day - 1; /* 1..31 -> 0..30 */
hours = dstime->hours; /* 0..23 */
minutes = dstime->minutes; /* 0..59 */
seconds = dstime->seconds; /* 0..61 in ANSI C. */
/* Set `days' to the number of days into the year. */
days += ydays[months] + (months > 1 && leap (years));
/* Now calculate `days' to the number of days since Jan 1, 1970. */
days = (unsigned)days + 365 * (unsigned)(years - 1970) + (unsigned)(nleap (years));
return (time_t)(86400L * (unsigned long)days +
3600L * (unsigned long)hours +
(unsigned long)(60 * minutes + seconds));
}
//---------------------------------------------------------------------------------
void resyncClock() {
//---------------------------------------------------------------------------------
RTCtime dstime;
rtcGetTimeAndDate((uint8 *)&dstime);
__transferRegion()->unixTime = __mktime(&dstime);
}
//---------------------------------------------------------------------------------
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
resyncClock();
}

View File

@ -0,0 +1,204 @@
/*---------------------------------------------------------------------------------
DSi "codec" Touchscreen/Sound Controller control for ARM7
Copyright (C) 2017
fincs
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/codec.h>
//---------------------------------------------------------------------------------
static u8 readTSC(u8 reg) {
//---------------------------------------------------------------------------------
while (REG_SPICNT & 0x80);
REG_SPICNT = SPI_ENABLE | SPI_BAUD_4MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
REG_SPIDATA = 1 | (reg << 1);
while (REG_SPICNT & 0x80);
REG_SPICNT = SPI_ENABLE | SPI_BAUD_4MHz | SPI_DEVICE_TOUCH;
REG_SPIDATA = 0;
while (REG_SPICNT & 0x80);
return REG_SPIDATA;
}
//---------------------------------------------------------------------------------
static void writeTSC(u8 reg, u8 value) {
//---------------------------------------------------------------------------------
while (REG_SPICNT & 0x80);
REG_SPICNT = SPI_ENABLE | SPI_BAUD_4MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
REG_SPIDATA = reg << 1;
while (REG_SPICNT & 0x80);
REG_SPICNT = SPI_ENABLE | SPI_BAUD_4MHz | SPI_DEVICE_TOUCH;
REG_SPIDATA = value;
}
//---------------------------------------------------------------------------------
static void bankSwitchTSC(u8 bank) {
//---------------------------------------------------------------------------------
static u8 curBank = 0x63;
if (bank != curBank) {
writeTSC(curBank == 0xFF ? 0x7F : 0x00, bank);
curBank = bank;
}
}
//---------------------------------------------------------------------------------
u8 cdcReadReg(u8 bank, u8 reg) {
//---------------------------------------------------------------------------------
bankSwitchTSC(bank);
return readTSC(reg);
}
//---------------------------------------------------------------------------------
void cdcReadRegArray(u8 bank, u8 reg, void* data, u8 size) {
//---------------------------------------------------------------------------------
u8* out = (u8*)data;
bankSwitchTSC(bank);
while (REG_SPICNT & 0x80);
REG_SPICNT = SPI_ENABLE | SPI_BAUD_4MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
REG_SPIDATA = 1 | (reg << 1);
while (REG_SPICNT & 0x80);
for (; size > 1; size--) {
REG_SPIDATA = 0;
while (REG_SPICNT & 0x80);
*out++ = REG_SPIDATA;
}
REG_SPICNT = SPI_ENABLE | SPI_BAUD_4MHz | SPI_DEVICE_TOUCH;
REG_SPIDATA = 0;
while (REG_SPICNT & 0x80);
*out++ = REG_SPIDATA;
}
//---------------------------------------------------------------------------------
void cdcWriteReg(u8 bank, u8 reg, u8 value) {
//---------------------------------------------------------------------------------
bankSwitchTSC(bank);
writeTSC(reg, value);
}
//---------------------------------------------------------------------------------
void cdcWriteRegMask(u8 bank, u8 reg, u8 mask, u8 value) {
//---------------------------------------------------------------------------------
bankSwitchTSC(bank);
writeTSC(reg, (readTSC(reg) &~ mask) | (value & mask));
}
//---------------------------------------------------------------------------------
void cdcWriteRegArray(u8 bank, u8 reg, const void* data, u8 size) {
//---------------------------------------------------------------------------------
const u8* in = (u8*)data;
bankSwitchTSC(bank);
while (REG_SPICNT & 0x80);
REG_SPICNT = SPI_ENABLE | SPI_BAUD_4MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS;
REG_SPIDATA = reg << 1;
while (REG_SPICNT & 0x80);
for (; size > 1; size--) {
REG_SPIDATA = *in++;
while (REG_SPICNT & 0x80);
}
REG_SPICNT = SPI_ENABLE | SPI_BAUD_4MHz | SPI_DEVICE_TOUCH;
REG_SPIDATA = *in++;
}
//---------------------------------------------------------------------------------
void cdcTouchInit(void) {
//---------------------------------------------------------------------------------
cdcWriteRegMask(CDC_TOUCHCNT, 0x0E, 0x80, 0<<7);
cdcWriteRegMask(CDC_TOUCHCNT, 0x02, 0x18, 3<<3);
cdcWriteReg (CDC_TOUCHCNT, 0x0F, 0xA0);
cdcWriteRegMask(CDC_TOUCHCNT, 0x0E, 0x38, 5<<3);
cdcWriteRegMask(CDC_TOUCHCNT, 0x0E, 0x40, 0<<6);
cdcWriteReg (CDC_TOUCHCNT, 0x03, 0x87);
cdcWriteRegMask(CDC_TOUCHCNT, 0x05, 0x07, 4<<0);
cdcWriteRegMask(CDC_TOUCHCNT, 0x04, 0x07, 6<<0);
cdcWriteRegMask(CDC_TOUCHCNT, 0x04, 0x70, 4<<4);
cdcWriteRegMask(CDC_TOUCHCNT, 0x12, 0x07, 0<<0);
cdcWriteRegMask(CDC_TOUCHCNT, 0x0E, 0x80, 1<<7);
}
//---------------------------------------------------------------------------------
bool cdcTouchPenDown(void) {
//---------------------------------------------------------------------------------
return (cdcReadReg(CDC_TOUCHCNT, 0x09) & 0xC0) != 0x40 && !(cdcReadReg(CDC_TOUCHCNT, 0x0E) & 0x02);
}
//---------------------------------------------------------------------------------
bool cdcTouchRead(touchPosition* pos) {
//---------------------------------------------------------------------------------
u8 raw[2*2*5];
u16 arrayX[5], arrayY[5];
u32 sumX, sumY;
int i;
cdcReadRegArray(CDC_TOUCHDATA, 0x01, raw, sizeof(raw));
for (i = 0; i < 5; i ++) {
arrayX[i] = (raw[i*2+ 0]<<8) | raw[i*2+ 1];
arrayY[i] = (raw[i*2+10]<<8) | raw[i*2+11];
if ((arrayX[i] & 0xF000) || (arrayY[i] & 0xF000)) {
pos->rawx = 0;
pos->rawy = 0;
return false;
}
}
// TODO: For now we just average all values without removing inaccurate values
sumX = 0;
sumY = 0;
for (i = 0; i < 5; i ++) {
sumX += arrayX[i];
sumY += arrayY[i];
}
pos->rawx = sumX / 5;
pos->rawy = sumY / 5;
return true;
}

View File

@ -0,0 +1,152 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2014
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/interrupts.h>
#include <nds/system.h>
#include <nds/fifocommon.h>
#include <nds/fifomessages.h>
#include <string.h>
static u8 readwriteSPI(u8 data) {
REG_SPIDATA = data;
SerialWaitBusy();
return REG_SPIDATA;
}
//---------------------------------------------------------------------------------
void readFirmware(u32 address, void * destination, u32 size) {
//---------------------------------------------------------------------------------
int oldIME=enterCriticalSection();
u8 *buffer = destination;
// Read command
REG_SPICNT = SPI_ENABLE | SPI_BYTE_MODE | SPI_CONTINUOUS | SPI_DEVICE_FIRMWARE;
readwriteSPI(FIRMWARE_READ);
// Set the address
readwriteSPI((address>>16) & 0xFF);
readwriteSPI((address>> 8) & 0xFF);
readwriteSPI((address) & 0xFF);
u32 i;
// Read the data
for(i=0;i<size;i++) {
buffer[i] = readwriteSPI(0);
}
REG_SPICNT = 0;
leaveCriticalSection(oldIME);
}
//---------------------------------------------------------------------------------
static int writeFirmwarePage(u32 address,u8 *buffer) {
//---------------------------------------------------------------------------------
int i;
u8 pagebuffer[256];
readFirmware(address, pagebuffer, 256);
if (memcmp(pagebuffer,buffer,256) == 0) return 0;
int oldIME=enterCriticalSection();
//write enable
REG_SPICNT = SPI_ENABLE|SPI_CONTINUOUS|SPI_DEVICE_NVRAM;
readwriteSPI(FIRMWARE_WREN);
REG_SPICNT = 0;
//Wait for Write Enable Latch to be set
REG_SPICNT = SPI_ENABLE|SPI_CONTINUOUS|SPI_DEVICE_NVRAM;
readwriteSPI(FIRMWARE_RDSR);
while((readwriteSPI(0)&0x02)==0); //Write Enable Latch
REG_SPICNT = 0;
//page write
REG_SPICNT = SPI_ENABLE|SPI_CONTINUOUS|SPI_DEVICE_NVRAM;
readwriteSPI(FIRMWARE_PW);
// Set the address
readwriteSPI((address>>16) & 0xFF);
readwriteSPI((address>> 8) & 0xFF);
readwriteSPI((address) & 0xFF);
for (i=0; i<256; i++) {
readwriteSPI(buffer[i]);
}
REG_SPICNT = 0;
// wait for programming to finish
REG_SPICNT = SPI_ENABLE|SPI_CONTINUOUS|SPI_DEVICE_NVRAM;
readwriteSPI(FIRMWARE_RDSR);
while(readwriteSPI(0)&0x01); //Write In Progress
REG_SPICNT = 0;
leaveCriticalSection(oldIME);
// read it back & verify
readFirmware(address, pagebuffer, 256);
if (memcmp(pagebuffer,buffer,256) == 0) return 0;
return -1;
}
//---------------------------------------------------------------------------------
int writeFirmware(u32 address, void * source, u32 size) {
//---------------------------------------------------------------------------------
if( ((address & 0xff) != 0) || ((size & 0xff) != 0)) return -1;
u8 *buffer = source;
int response = -1;
while (size >0 ) {
size -= 256;
if (writeFirmwarePage(address+size,buffer+size )) break;
}
if (size == 0 ) response = 0;
return response;
}
//---------------------------------------------------------------------------------
void firmwareMsgHandler(int bytes, void *user_data) {
//---------------------------------------------------------------------------------
FifoMessage msg;
int response = -1;
fifoGetDatamsg(FIFO_FIRMWARE, bytes, (u8*)&msg);
switch(msg.type) {
case FW_READ:
readFirmware(msg.blockParams.address, msg.blockParams.buffer, msg.blockParams.length);
response = 0;
break;
case FW_WRITE:
response = writeFirmware(msg.blockParams.address, msg.blockParams.buffer, msg.blockParams.length);
break;
}
fifoSendValue32(FIFO_FIRMWARE,response);
}

View File

@ -0,0 +1,132 @@
/*---------------------------------------------------------------------------------
I2C control for the ARM7
Copyright (C) 2011
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/i2c.h>
#include <nds/bios.h>
static u32 i2cCurrentDelay = 0;
//---------------------------------------------------------------------------------
void i2cDelay() {
//---------------------------------------------------------------------------------
i2cWaitBusy();
swiDelay(i2cCurrentDelay);
}
//---------------------------------------------------------------------------------
void i2cStop(u8 arg0) {
//---------------------------------------------------------------------------------
if(i2cCurrentDelay) {
REG_I2CCNT = (arg0 << 5) | 0xC0;
i2cDelay();
REG_I2CCNT = 0xC5;
} else REG_I2CCNT = (arg0 << 5) | 0xC1;
}
//---------------------------------------------------------------------------------
u8 i2cGetResult() {
//---------------------------------------------------------------------------------
i2cWaitBusy();
return (REG_I2CCNT >> 4) & 0x01;
}
//---------------------------------------------------------------------------------
u8 i2cGetData() {
//---------------------------------------------------------------------------------
i2cWaitBusy();
return REG_I2CDATA;
}
//---------------------------------------------------------------------------------
void i2cSetDelay(u8 device) {
//---------------------------------------------------------------------------------
if (device == I2C_PM ) {
i2cCurrentDelay = 0x180;
} else {
i2cCurrentDelay = 0;
}
}
//---------------------------------------------------------------------------------
u8 i2cSelectDevice(u8 device) {
//---------------------------------------------------------------------------------
i2cWaitBusy();
REG_I2CDATA = device;
REG_I2CCNT = 0xC2;
return i2cGetResult();
}
//---------------------------------------------------------------------------------
u8 i2cSelectRegister(u8 reg) {
//---------------------------------------------------------------------------------
i2cDelay();
REG_I2CDATA = reg;
REG_I2CCNT = 0xC0;
return i2cGetResult();
}
//---------------------------------------------------------------------------------
u8 i2cWriteRegister(u8 device, u8 reg, u8 data) {
//---------------------------------------------------------------------------------
i2cSetDelay(device);
int i;
for(i = 0; i < 8; i++) {
if((i2cSelectDevice(device) != 0) && (i2cSelectRegister(reg) != 0)) {
i2cDelay();
REG_I2CDATA = data;
i2cStop(0);
if(i2cGetResult() != 0) return 1;
}
REG_I2CCNT = 0xC5;
}
return 0;
}
//---------------------------------------------------------------------------------
u8 i2cReadRegister(u8 device, u8 reg) {
//---------------------------------------------------------------------------------
i2cSetDelay(device);
int i;
for(i = 0; i < 8; i++) {
if((i2cSelectDevice(device) != 0) && (i2cSelectRegister(reg) != 0)) {
i2cDelay();
if(i2cSelectDevice(device | 1)) {
i2cDelay();
i2cStop(1);
return i2cGetData();
}
}
REG_I2CCNT = 0xC5;
}
return 0xff;
}

View File

@ -0,0 +1,68 @@
#include <nds/arm7/input.h>
#include <nds/arm7/touch.h>
#include <nds/system.h>
#include <nds/touch.h>
#include <nds/fifocommon.h>
#include <nds/fifomessages.h>
#include <nds/ipc.h>
#include <nds/ndstypes.h>
enum{
KEY_TOUCH = (1<<6),
KEY_LID = (1<<7)
}Keys;
void inputGetAndSend(void){
static bool penDown = false;
static int sleepCounter = 0;
touchPosition tempPos = {0};
FifoMessage msg = {0};
u16 keys= REG_KEYXY;
if(!touchPenDown()) {
keys |= KEY_TOUCH;
} else {
keys &= ~KEY_TOUCH;
}
msg.SystemInput.keys = keys;
if(keys & KEY_TOUCH) {
penDown = false;
} else {
msg.SystemInput.keys |= KEY_TOUCH;
if(penDown) {
touchReadXY(&tempPos);
if(tempPos.rawx && tempPos.rawy) {
msg.SystemInput.keys &= ~KEY_TOUCH;
msg.SystemInput.touch = tempPos;
} else {
penDown = false;
}
} else {
penDown = true;
}
}
if(keys & KEY_LID)
sleepCounter++;
else
sleepCounter = 0;
//sleep if lid has been closed for 20 frames
if(sleepCounter >= 20)
{
systemSleep();
sleepCounter = 0;
}
msg.type = SYS_INPUT_MESSAGE; //set message type
fifoSendDatamsg(FIFO_SYSTEM, sizeof(msg), (u8*)&msg);
}

View File

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2006 - 2016
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/asminc.h>
.arm
.cpu arm7tdmi
.text
@---------------------------------------------------------------------------------
BEGIN_ASM_FUNC swiWaitForVBlank
@---------------------------------------------------------------------------------
mov r0, #1
mov r1, #1
mov r2, #0
nop
@---------------------------------------------------------------------------------
BEGIN_ASM_FUNC swiIntrWait
@---------------------------------------------------------------------------------
stmfd sp!, {lr}
cmp r0, #0
blne testirq
wait_irq:
swi #(6<<16)
bl testirq
beq wait_irq
ldmfd sp!, {lr}
bx lr
testirq:
mov r12, #0x4000000
strb r12, [r12,#0x208]
ldr r3, [r12,#-8]
ands r0, r1, r3
eorne r3, r3, r0
strne r3, [r12,#-8]
mov r0, #1
strb r0, [r12,#0x208]
bx lr

View File

@ -0,0 +1,248 @@
/*---------------------------------------------------------------------------------
$Id: microphone.c,v 1.8 2008-11-12 17:47:12 dovoto Exp $
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/interrupts.h>
#include <nds/fifocommon.h>
#include <nds/timers.h>
#include <nds/arm7/audio.h>
#include <nds/arm7/codec.h>
void micSetAmp_TWL(u8 control, u8 gain);
u16 micReadData16_TWL();
//---------------------------------------------------------------------------------
// Turn on the Microphone Amp. Code based on neimod's example.
//---------------------------------------------------------------------------------
void micSetAmp_NTR(u8 control, u8 gain) {
//---------------------------------------------------------------------------------
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;
SerialWaitBusy();
REG_SPICNT = SPI_ENABLE | SPI_DEVICE_POWER | SPI_BAUD_1MHz | SPI_CONTINUOUS;
REG_SPIDATA = PM_GAIN_OFFSET;
SerialWaitBusy();
REG_SPICNT = SPI_ENABLE | SPI_DEVICE_POWER | SPI_BAUD_1MHz;
REG_SPIDATA = gain;
}
//---------------------------------------------------------------------------------
// Read a byte from the microphone. Code based on neimod's example.
//---------------------------------------------------------------------------------
u8 micReadData8_NTR() {
//---------------------------------------------------------------------------------
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));
}
//---------------------------------------------------------------------------------
// Read a short from the microphone. Code based on neimod's example.
//---------------------------------------------------------------------------------
u16 micReadData12_NTR() {
//---------------------------------------------------------------------------------
u16 result, result2;
SerialWaitBusy();
REG_SPICNT = SPI_ENABLE | SPI_DEVICE_MICROPHONE | SPI_BAUD_2MHz | SPI_CONTINUOUS;
REG_SPIDATA = 0xE4; // Touchscreen command format for AUX, 12bit
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) << 5) | ((result2>>3)&0x1F));
}
//---------------------------------------------------------------------------------
void micSetAmp(u8 control, u8 gain) {
//---------------------------------------------------------------------------------
int oldIME = enterCriticalSection();
if (cdcIsAvailable()) {
micSetAmp_TWL(control, gain);
} else {
micSetAmp_NTR(control, gain);
}
leaveCriticalSection(oldIME);
}
//---------------------------------------------------------------------------------
u8 micReadData8() {
//---------------------------------------------------------------------------------
u8 smp;
int oldIME = enterCriticalSection();
if (cdcIsAvailable()) {
smp = micReadData16_TWL() >> 8;
} else {
smp = micReadData8_NTR();
}
leaveCriticalSection(oldIME);
return smp;
}
//---------------------------------------------------------------------------------
u16 micReadData12() {
//---------------------------------------------------------------------------------
u16 smp;
int oldIME = enterCriticalSection();
if (cdcIsAvailable()) {
smp = micReadData16_TWL() >> 4;
} else {
smp = micReadData12_NTR();
}
leaveCriticalSection(oldIME);
return smp;
}
static u8* microphone_front_buffer;
static u8* microphone_back_buffer;
static int microphone_buffer_length = 0;
static int sampleCount = 0;
static bool eightBit = true;
static int micTimer = 0;
static MIC_BUF_SWAP_CB swapCallback;
//---------------------------------------------------------------------------------
void micStartRecording(u8* buffer, int length, int freq, int timer, bool eightBitSample, MIC_BUF_SWAP_CB bufferSwapCallback ) {
//---------------------------------------------------------------------------------
microphone_front_buffer = buffer + length / 2;
microphone_back_buffer = buffer;
microphone_buffer_length = length / 2;
swapCallback = bufferSwapCallback;
sampleCount = 0;
micTimer = timer;
eightBit = eightBitSample;
micOn();
irqSet(BIT(3 + timer), micTimerHandler);
irqEnable(BIT(3 + timer));
// Setup a timer
TIMER_DATA(timer) = TIMER_FREQ(freq);
TIMER_CR(timer) = TIMER_ENABLE |TIMER_IRQ_REQ;
//irqSet(IRQ_TIMER2, micTimerHandler);
//irqEnable(IRQ_TIMER2);
//// Setup a timer
//TIMER_DATA(2) = TIMER_FREQ(freq);
//TIMER_CR(2) = TIMER_ENABLE | TIMER_DIV_1 | TIMER_IRQ_REQ;
}
//---------------------------------------------------------------------------------
int micStopRecording(void) {
//---------------------------------------------------------------------------------
TIMER_CR(micTimer) &= ~TIMER_ENABLE;
micOff();
if(swapCallback)
swapCallback(microphone_back_buffer, eightBit ? sampleCount : (sampleCount << 1));
microphone_front_buffer = microphone_back_buffer = 0;
return sampleCount;
}
//---------------------------------------------------------------------------------
void micTimerHandler(void) {
//---------------------------------------------------------------------------------
int len = 0;
// Read data from the microphone. Data from the Mic is unsigned, flipping
// the highest bit makes it signed.
if(eightBit)
{
*(microphone_back_buffer+sampleCount) = micReadData8() ^ 0x80;
}
else
{
*(u16*)(microphone_back_buffer + sampleCount * 2) = (micReadData12() - 2048) << 4; // ^ 0x8000;
}
sampleCount++;
len = eightBit ? sampleCount : (sampleCount << 1);
if(len >= microphone_buffer_length)
{
sampleCount = 0;
u8* temp = microphone_back_buffer;
microphone_back_buffer = microphone_front_buffer;
microphone_front_buffer = temp;
if(swapCallback)
swapCallback(microphone_front_buffer, microphone_buffer_length);
}
}

View File

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------------
DSi microphone control
Copyright (C) 2017
fincs
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/interrupts.h>
#include <nds/fifocommon.h>
#include <nds/timers.h>
#include <nds/arm7/audio.h>
#include <nds/arm7/codec.h>
//---------------------------------------------------------------------------------
void micSetAmp_TWL(u8 control, u8 gain) {
//---------------------------------------------------------------------------------
static const u8 gaintbl[] = { 0x1F, 0x2B, 0x37, 0x43 };
if (control == PM_AMP_ON) {
cdcWriteReg(CDC_SOUND, 0x2E, 0x03); // set adc bias
bool adcOn = cdcReadReg(CDC_CONTROL, 0x51) & 0x80;
bool dacOn = cdcReadReg(CDC_CONTROL, 0x3F) & 0xC0;
cdcWriteReg(CDC_CONTROL, 0x51, 0x80); // turn on adc
if (!adcOn || !dacOn) {
swiDelay(0x28E91F); // 20ms
}
cdcWriteReg(CDC_CONTROL, 0x52, 0x00); // unmute adc
cdcWriteReg(CDC_SOUND, 0x2F, gaintbl[gain&3]); // set gain
} else if (control == PM_AMP_OFF) {
cdcWriteReg(CDC_CONTROL, 0x52, 0x80); // mute adc
cdcWriteReg(CDC_CONTROL, 0x51, 0x00); // turn off adc
cdcWriteReg(CDC_SOUND, 0x2E, 0x00); // set adc bias
}
}
//---------------------------------------------------------------------------------
u16 micReadData16_TWL() {
//---------------------------------------------------------------------------------
u16 data = 0x8000;
int timeout = 0;
REG_MICCNT &= ~MICCNT_ENABLE;
REG_MICCNT &= ~( (3<<13) | 0xF );
REG_MICCNT |= MICCNT_CLEAR_FIFO | MICCNT_FORMAT(2);
REG_MICCNT |= MICCNT_ENABLE;
while (timeout++ < 200) {
if (!(REG_MICCNT & MICCNT_EMPTY)) {
data = REG_MICDATA;
break;
}
}
return data ^ 0x8000; // convert to unsigned
}

View File

@ -0,0 +1,576 @@
#include <nds/system.h>
#include <nds/bios.h>
#include <nds/arm7/sdmmc.h>
#include <nds/interrupts.h>
#include <nds/fifocommon.h>
#include <nds/fifomessages.h>
#include <stddef.h>
static struct mmcdevice deviceSD;
static struct mmcdevice deviceNAND;
/*mmcdevice *getMMCDevice(int drive) {
if(drive==0) return &deviceNAND;
return &deviceSD;
}
*/
//---------------------------------------------------------------------------------
int geterror(struct mmcdevice *ctx) {
//---------------------------------------------------------------------------------
//if(ctx->error == 0x4) return -1;
//else return 0;
return (ctx->error << 29) >> 31;
}
//---------------------------------------------------------------------------------
void setTarget(struct mmcdevice *ctx) {
//---------------------------------------------------------------------------------
sdmmc_mask16(REG_SDPORTSEL,0x3,(u16)ctx->devicenumber);
setckl(ctx->clk);
if (ctx->SDOPT == 0) {
sdmmc_mask16(REG_SDOPT, 0, 0x8000);
} else {
sdmmc_mask16(REG_SDOPT, 0x8000, 0);
}
}
//---------------------------------------------------------------------------------
void sdmmc_send_command(struct mmcdevice *ctx, uint32_t cmd, uint32_t args) {
//---------------------------------------------------------------------------------
int i;
bool getSDRESP = (cmd << 15) >> 31;
uint16_t flags = (cmd << 15) >> 31;
const bool readdata = cmd & 0x20000;
const bool writedata = cmd & 0x40000;
if(readdata || writedata)
{
flags |= TMIO_STAT0_DATAEND;
}
ctx->error = 0;
while((sdmmc_read16(REG_SDSTATUS1) & TMIO_STAT1_CMD_BUSY)); //mmc working?
sdmmc_write16(REG_SDIRMASK0,0);
sdmmc_write16(REG_SDIRMASK1,0);
sdmmc_write16(REG_SDSTATUS0,0);
sdmmc_write16(REG_SDSTATUS1,0);
#ifdef DATA32_SUPPORT
// if(readdata)sdmmc_mask16(REG_DATACTL32, 0x1000, 0x800);
// if(writedata)sdmmc_mask16(REG_DATACTL32, 0x800, 0x1000);
// sdmmc_mask16(REG_DATACTL32,0x1800,2);
#else
sdmmc_mask16(REG_DATACTL32,0x1800,0);
#endif
sdmmc_write16(REG_SDCMDARG0,args &0xFFFF);
sdmmc_write16(REG_SDCMDARG1,args >> 16);
sdmmc_write16(REG_SDCMD,cmd &0xFFFF);
uint32_t size = ctx->size;
uint16_t *dataPtr = (uint16_t*)ctx->data;
uint32_t *dataPtr32 = (uint32_t*)ctx->data;
bool useBuf = ( NULL != dataPtr );
bool useBuf32 = (useBuf && (0 == (3 & ((uint32_t)dataPtr))));
uint16_t status0 = 0;
while(1) {
volatile uint16_t status1 = sdmmc_read16(REG_SDSTATUS1);
#ifdef DATA32_SUPPORT
volatile uint16_t ctl32 = sdmmc_read16(REG_SDDATACTL32);
if((ctl32 & 0x100))
#else
if((status1 & TMIO_STAT1_RXRDY))
#endif
{
if(readdata) {
if(useBuf) {
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0);
if(size > 0x1FF) {
#ifdef DATA32_SUPPORT
if(useBuf32) {
for(i = 0; i<0x200; i+=4) {
*dataPtr32++ = sdmmc_read32(REG_SDFIFO32);
}
} else {
#endif
for(i = 0; i<0x200; i+=2) {
*dataPtr++ = sdmmc_read16(REG_SDFIFO);
}
#ifdef DATA32_SUPPORT
}
#endif
size -= 0x200;
}
}
sdmmc_mask16(REG_SDDATACTL32, 0x800, 0);
}
}
#ifdef DATA32_SUPPORT
if(!(ctl32 & 0x200))
#else
if((status1 & TMIO_STAT1_TXRQ))
#endif
{
if(writedata) {
if(useBuf) {
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_TXRQ, 0);
//sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_TXRQ);
if(size > 0x1FF) {
#ifdef DATA32_SUPPORT
for(i = 0; i<0x200; i+=4) {
sdmmc_write32(REG_SDFIFO32,*dataPtr32++);
}
#else
for(i = 0; i<0x200; i+=2) {
sdmmc_write16(REG_SDFIFO,*dataPtr++);
}
#endif
size -= 0x200;
}
}
sdmmc_mask16(REG_SDDATACTL32, 0x1000, 0);
}
}
if(status1 & TMIO_MASK_GW) {
ctx->error |= 4;
break;
}
if(!(status1 & TMIO_STAT1_CMD_BUSY)) {
status0 = sdmmc_read16(REG_SDSTATUS0);
if(sdmmc_read16(REG_SDSTATUS0) & TMIO_STAT0_CMDRESPEND) {
ctx->error |= 0x1;
}
if(status0 & TMIO_STAT0_DATAEND) {
ctx->error |= 0x2;
}
if((status0 & flags) == flags)
break;
}
}
ctx->stat0 = sdmmc_read16(REG_SDSTATUS0);
ctx->stat1 = sdmmc_read16(REG_SDSTATUS1);
sdmmc_write16(REG_SDSTATUS0,0);
sdmmc_write16(REG_SDSTATUS1,0);
if(getSDRESP != 0) {
ctx->ret[0] = sdmmc_read16(REG_SDRESP0) | (sdmmc_read16(REG_SDRESP1) << 16);
ctx->ret[1] = sdmmc_read16(REG_SDRESP2) | (sdmmc_read16(REG_SDRESP3) << 16);
ctx->ret[2] = sdmmc_read16(REG_SDRESP4) | (sdmmc_read16(REG_SDRESP5) << 16);
ctx->ret[3] = sdmmc_read16(REG_SDRESP6) | (sdmmc_read16(REG_SDRESP7) << 16);
}
}
//---------------------------------------------------------------------------------
int sdmmc_cardinserted() {
//---------------------------------------------------------------------------------
return 1; //sdmmc_cardready;
}
static bool sdmmc_controller_initialised = false;
//---------------------------------------------------------------------------------
void sdmmc_controller_init( bool force_init ) {
//---------------------------------------------------------------------------------
if (!force_init && sdmmc_controller_initialised) return;
deviceSD.isSDHC = 0;
deviceSD.SDOPT = 0;
deviceSD.res = 0;
deviceSD.initarg = 0;
deviceSD.clk = 0x80;
deviceSD.devicenumber = 0;
deviceNAND.isSDHC = 0;
deviceNAND.SDOPT = 0;
deviceNAND.res = 0;
deviceNAND.initarg = 1;
deviceNAND.clk = 0x80;
deviceNAND.devicenumber = 1;
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xF7FFu;
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xEFFFu;
#ifdef DATA32_SUPPORT
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u;
#else
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u;
#endif
*(vu16*)(SDMMC_BASE + REG_SDDATACTL) = (*(vu16*)(SDMMC_BASE + REG_SDDATACTL) & 0xFFDD) | 2;
#ifdef DATA32_SUPPORT
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFFu;
*(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDFu;
*(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 512;
#else
*(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFDu;
*(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDDu;
*(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 0;
#endif
*(vu16*)(SDMMC_BASE + REG_SDBLKCOUNT32) = 1;
*(vu16*)(SDMMC_BASE + REG_SDRESET) &= 0xFFFEu;
*(vu16*)(SDMMC_BASE + REG_SDRESET) |= 1u;
*(vu16*)(SDMMC_BASE + REG_SDIRMASK0) |= TMIO_MASK_ALL;
*(vu16*)(SDMMC_BASE + REG_SDIRMASK1) |= TMIO_MASK_ALL>>16;
*(vu16*)(SDMMC_BASE + 0x0fc) |= 0xDBu; //SDCTL_RESERVED7
*(vu16*)(SDMMC_BASE + 0x0fe) |= 0xDBu; //SDCTL_RESERVED8
*(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu;
#ifdef DATA32_SUPPORT
*(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x20;
*(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EE;
#else
*(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x40; //Nintendo sets this to 0x20
*(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EB; //Nintendo sets this to 0x40EE
#endif
*(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu;
*(vu16*)(SDMMC_BASE + REG_SDBLKLEN) = 512;
*(vu16*)(SDMMC_BASE + REG_SDSTOP) = 0;
sdmmc_controller_initialised = true;
setTarget(&deviceSD);
}
//---------------------------------------------------------------------------------
static u32 calcSDSize(u8* csd, int type) {
//---------------------------------------------------------------------------------
u32 result = 0;
if (type == -1) type = csd[14] >> 6;
switch (type) {
case 0:
{
u32 block_len = csd[9] & 0xf;
block_len = 1 << block_len;
u32 mult = (csd[4] >> 7) | ((csd[5] & 3) << 1);
mult = 1 << (mult + 2);
result = csd[8] & 3;
result = (result << 8) | csd[7];
result = (result << 2) | (csd[6] >> 6);
result = (result + 1) * mult * block_len / 512;
}
break;
case 1:
result = csd[7] & 0x3f;
result = (result << 8) | csd[6];
result = (result << 8) | csd[5];
result = (result + 1) * 1024;
break;
}
return result;
}
//---------------------------------------------------------------------------------
int sdmmc_sdcard_init() {
//---------------------------------------------------------------------------------
setTarget(&deviceSD);
swiDelay(0xF000);
// card reset
sdmmc_send_command(&deviceSD,0,0);
// CMD8 0x1AA
sdmmc_send_command(&deviceSD,0x10408,0x1AA);
u32 temp = (deviceSD.error & 0x1) << 0x1E;
u32 temp2 = 0;
do {
do {
// CMD55
sdmmc_send_command(&deviceSD,0x10437,deviceSD.initarg << 0x10);
// ACMD41
sdmmc_send_command(&deviceSD,0x10769,0x00FF8000 | temp);
temp2 = 1;
} while ( !(deviceSD.error & 1) );
} while((deviceSD.ret[0] & 0x80000000) == 0);
if(!((deviceSD.ret[0] >> 30) & 1) || !temp)
temp2 = 0;
deviceSD.isSDHC = temp2;
sdmmc_send_command(&deviceSD,0x10602,0);
if (deviceSD.error & 0x4) return -1;
sdmmc_send_command(&deviceSD,0x10403,0);
if (deviceSD.error & 0x4) return -1;
deviceSD.initarg = deviceSD.ret[0] >> 0x10;
sdmmc_send_command(&deviceSD,0x10609,deviceSD.initarg << 0x10);
if (deviceSD.error & 0x4) return -1;
deviceSD.total_size = calcSDSize((u8*)&deviceSD.ret[0],-1);
deviceSD.clk = 1;
setckl(1);
sdmmc_send_command(&deviceSD,0x10507,deviceSD.initarg << 0x10);
if (deviceSD.error & 0x4) return -1;
// CMD55
sdmmc_send_command(&deviceSD,0x10437,deviceSD.initarg << 0x10);
if (deviceSD.error & 0x4) return -1;
// ACMD42
sdmmc_send_command(&deviceSD,0x1076A,0x0);
if (deviceSD.error & 0x4) return -1;
// CMD55
sdmmc_send_command(&deviceSD,0x10437,deviceSD.initarg << 0x10);
if (deviceSD.error & 0x4) return -1;
deviceSD.SDOPT = 1;
sdmmc_send_command(&deviceSD,0x10446,0x2);
if (deviceSD.error & 0x4) return -1;
sdmmc_send_command(&deviceSD,0x1040D,deviceSD.initarg << 0x10);
if (deviceSD.error & 0x4) return -1;
sdmmc_send_command(&deviceSD,0x10410,0x200);
if (deviceSD.error & 0x4) return -1;
deviceSD.clk |= 0x200;
return 0;
}
//---------------------------------------------------------------------------------
int sdmmc_nand_init() {
//---------------------------------------------------------------------------------
setTarget(&deviceNAND);
swiDelay(0xF000);
sdmmc_send_command(&deviceNAND,0,0);
do {
do {
sdmmc_send_command(&deviceNAND,0x10701,0x100000);
} while ( !(deviceNAND.error & 1) );
}
while((deviceNAND.ret[0] & 0x80000000) == 0);
sdmmc_send_command(&deviceNAND,0x10602,0x0);
if((deviceNAND.error & 0x4))return -1;
sdmmc_send_command(&deviceNAND,0x10403,deviceNAND.initarg << 0x10);
if((deviceNAND.error & 0x4))return -1;
sdmmc_send_command(&deviceNAND,0x10609,deviceNAND.initarg << 0x10);
if((deviceNAND.error & 0x4))return -1;
deviceNAND.total_size = calcSDSize((uint8_t*)&deviceNAND.ret[0],0);
deviceNAND.clk = 1;
setckl(1);
sdmmc_send_command(&deviceNAND,0x10407,deviceNAND.initarg << 0x10);
if((deviceNAND.error & 0x4))return -1;
deviceNAND.SDOPT = 1;
sdmmc_send_command(&deviceNAND,0x10506,0x3B70100);
if((deviceNAND.error & 0x4))return -1;
sdmmc_send_command(&deviceNAND,0x10506,0x3B90100);
if((deviceNAND.error & 0x4))return -1;
sdmmc_send_command(&deviceNAND,0x1040D,deviceNAND.initarg << 0x10);
if((deviceNAND.error & 0x4))return -1;
sdmmc_send_command(&deviceNAND,0x10410,0x200);
if((deviceNAND.error & 0x4))return -1;
deviceNAND.clk |= 0x200;
setTarget(&deviceSD);
return 0;
}
//---------------------------------------------------------------------------------
int sdmmc_readsectors(struct mmcdevice *device, u32 sector_no, u32 numsectors, void *out) {
//---------------------------------------------------------------------------------
if (device->isSDHC == 0) sector_no <<= 9;
setTarget(device);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
sdmmc_write16(REG_SDBLKLEN32,0x200);
#endif
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
device->data = out;
device->size = numsectors << 9;
sdmmc_send_command(device,0x33C12,sector_no);
setTarget(&deviceSD);
return geterror(device);
}
//---------------------------------------------------------------------------------
int sdmmc_writesectors(struct mmcdevice *device, u32 sector_no, u32 numsectors, void *in) {
//---------------------------------------------------------------------------------
if (device->isSDHC == 0)
sector_no <<= 9;
setTarget(device);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
sdmmc_write16(REG_SDBLKLEN32,0x200);
#endif
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
device->data = in;
device->size = numsectors << 9;
sdmmc_send_command(device,0x52C19,sector_no);
setTarget(&deviceSD);
return geterror(device);
}
//---------------------------------------------------------------------------------
void sdmmc_get_cid(int devicenumber, u32 *cid) {
//---------------------------------------------------------------------------------
struct mmcdevice *device = (devicenumber == 1 ? &deviceNAND : &deviceSD);
int oldIME = enterCriticalSection();
setTarget(device);
// use cmd7 to put sd card in standby mode
// CMD7
sdmmc_send_command(device, 0x10507, 0);
// get sd card info
// use cmd10 to read CID
sdmmc_send_command(device, 0x1060A, device->initarg << 0x10);
for(int i = 0; i < 4; ++i)
cid[i] = device->ret[i];
// put sd card back to transfer mode
// CMD7
sdmmc_send_command(device, 0x10507, device->initarg << 0x10);
leaveCriticalSection(oldIME);
}
//---------------------------------------------------------------------------------
void sdmmcMsgHandler(int bytes, void *user_data) {
//---------------------------------------------------------------------------------
FifoMessage msg;
int retval = 0;
fifoGetDatamsg(FIFO_SDMMC, bytes, (u8*)&msg);
int oldIME = enterCriticalSection();
switch (msg.type) {
case SDMMC_SD_READ_SECTORS:
retval = sdmmc_readsectors(&deviceSD, msg.sdParams.startsector, msg.sdParams.numsectors, msg.sdParams.buffer);
break;
case SDMMC_SD_WRITE_SECTORS:
retval = sdmmc_writesectors(&deviceSD, msg.sdParams.startsector, msg.sdParams.numsectors, msg.sdParams.buffer);
break;
case SDMMC_NAND_READ_SECTORS:
retval = sdmmc_readsectors(&deviceNAND, msg.sdParams.startsector, msg.sdParams.numsectors, msg.sdParams.buffer);
break;
case SDMMC_NAND_WRITE_SECTORS:
retval = sdmmc_writesectors(&deviceNAND, msg.sdParams.startsector, msg.sdParams.numsectors, msg.sdParams.buffer);
break;
}
leaveCriticalSection(oldIME);
fifoSendValue32(FIFO_SDMMC, retval);
}
//---------------------------------------------------------------------------------
int sdmmc_nand_startup() {
//---------------------------------------------------------------------------------
sdmmc_controller_init(false);
return sdmmc_nand_init();
}
//---------------------------------------------------------------------------------
int sdmmc_sd_startup() {
//---------------------------------------------------------------------------------
sdmmc_controller_init(false);
return sdmmc_sdcard_init();
}
//---------------------------------------------------------------------------------
void sdmmcValueHandler(u32 value, void* user_data) {
//---------------------------------------------------------------------------------
int result = 0;
int sdflag = 0;
int oldIME = enterCriticalSection();
switch(value) {
case SDMMC_HAVE_SD:
result = sdmmc_read16(REG_SDSTATUS0);
break;
case SDMMC_SD_START:
sdflag = 1;
/* Falls through. */
case SDMMC_NAND_START:
if (sdmmc_read16(REG_SDSTATUS0) == 0) {
result = 1;
} else {
result = (sdflag == 1 ) ? sdmmc_sd_startup() : sdmmc_nand_startup();
}
break;
case SDMMC_SD_IS_INSERTED:
result = sdmmc_cardinserted();
break;
case SDMMC_SD_STOP:
break;
case SDMMC_NAND_SIZE:
result = deviceNAND.total_size;
break;
}
leaveCriticalSection(oldIME);
fifoSendValue32(FIFO_SDMMC, result);
}
//---------------------------------------------------------------------------------
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, void *out) {
//---------------------------------------------------------------------------------
return sdmmc_readsectors(&deviceSD, sector_no, numsectors, out);
}
//---------------------------------------------------------------------------------
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, void *in) {
//---------------------------------------------------------------------------------
return sdmmc_writesectors(&deviceSD, sector_no, numsectors, in);
}
//---------------------------------------------------------------------------------
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, void *out) {
//---------------------------------------------------------------------------------
return sdmmc_readsectors(&deviceNAND, sector_no, numsectors, out);
}
//---------------------------------------------------------------------------------
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, void *in) {
//---------------------------------------------------------------------------------
return sdmmc_writesectors(&deviceNAND, sector_no, numsectors, in);
}

View File

@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2005 - 2010
Michael Noland (joat)
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/interrupts.h>
#include <nds/system.h>
//---------------------------------------------------------------------------------
int writePowerManagement(int reg, int command) {
//---------------------------------------------------------------------------------
int oldIME=enterCriticalSection();
// Write the register / access mode (bit 7 sets access mode)
while (REG_SPICNT & SPI_BUSY);
REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | SPI_BYTE_MODE | SPI_CONTINUOUS | SPI_DEVICE_POWER;
REG_SPIDATA = reg;
// Write the command / start a read
while (REG_SPICNT & SPI_BUSY);
REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | SPI_BYTE_MODE | SPI_DEVICE_POWER;
REG_SPIDATA = command;
// Read the result
while (REG_SPICNT & SPI_BUSY);
leaveCriticalSection(oldIME);
return REG_SPIDATA & 0xFF;
}
//---------------------------------------------------------------------------------
void ledBlink(int value) {
//---------------------------------------------------------------------------------
u32 temp = readPowerManagement(PM_CONTROL_REG);
temp &= ~(3 << 4); //clear led bits
temp |= ((value & 3)<<4);
writePowerManagement(PM_CONTROL_REG, temp);
}

View File

@ -0,0 +1,168 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2005 - 2010
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/ndstypes.h>
#include <nds/system.h>
#include <nds/fifocommon.h>
#include <nds/fifomessages.h>
#include <nds/interrupts.h>
#include <nds/bios.h>
#include <nds/arm7/clock.h>
#include <nds/arm7/sdmmc.h>
#include <nds/arm7/i2c.h>
bool sleepIsEnabled = true;
bool __dsimode = false; // set in crt0
void twlEnableSlot1();
void twlDisableSlot1();
//---------------------------------------------------------------------------------
void enableSlot1() {
//---------------------------------------------------------------------------------
if(isDSiMode()) twlEnableSlot1();
}
//---------------------------------------------------------------------------------
void disableSlot1() {
//---------------------------------------------------------------------------------
if(isDSiMode()) twlDisableSlot1();
}
//---------------------------------------------------------------------------------
void powerValueHandler(u32 value, void* user_data) {
//---------------------------------------------------------------------------------
u32 temp;
u32 ie_save;
int battery, backlight, power;
switch(value & 0xFFFF0000) {
//power control
case PM_REQ_LED:
ledBlink(value);
break;
case PM_REQ_ON:
temp = readPowerManagement(PM_CONTROL_REG);
writePowerManagement(PM_CONTROL_REG, temp | (value & 0xFFFF));
break;
case PM_REQ_OFF:
temp = readPowerManagement(PM_CONTROL_REG) & (~(value & 0xFFFF));
writePowerManagement(PM_CONTROL_REG, temp);
break;
case PM_REQ_SLEEP:
ie_save = REG_IE;
// Turn the speaker down.
if (REG_POWERCNT & 1) swiChangeSoundBias(0,0x400);
// Save current power state.
power = readPowerManagement(PM_CONTROL_REG);
// Set sleep LED.
writePowerManagement(PM_CONTROL_REG, PM_LED_CONTROL(1));
// Register for the lid interrupt.
REG_IE = IRQ_LID;
// Power down till we get our interrupt.
swiSleep(); //waits for PM (lid open) interrupt
//100ms
swiDelay(838000);
// Restore the interrupt state.
REG_IE = ie_save;
// Restore power state.
writePowerManagement(PM_CONTROL_REG, power);
// Turn the speaker up.
if (REG_POWERCNT & 1) swiChangeSoundBias(1,0x400);
// update clock tracking
resyncClock();
break;
case PM_REQ_SLEEP_DISABLE:
sleepIsEnabled = false;
break;
case PM_REQ_SLEEP_ENABLE:
sleepIsEnabled = true;
break;
case PM_REQ_BATTERY:
if (!isDSiMode()) {
battery = (readPowerManagement(PM_BATTERY_REG) & 1)?3:15;
backlight = readPowerManagement(PM_BACKLIGHT_LEVEL);
if (backlight & (1<<6)) battery += (backlight & (1<<3))<<4;
} else {
battery = i2cReadRegister(I2C_PM,I2CREGPM_BATTERY);
}
fifoSendValue32(FIFO_PM, battery);
break;
case PM_REQ_SLOT1_DISABLE:
disableSlot1();
break;
case PM_REQ_SLOT1_ENABLE:
enableSlot1();
break;
}
}
//---------------------------------------------------------------------------------
void systemSleep(void) {
//---------------------------------------------------------------------------------
if(!sleepIsEnabled) return;
//puts arm9 to sleep which then notifies arm7 above (which causes arm7 to sleep)
fifoSendValue32(FIFO_SYSTEM, PM_REQ_SLEEP);
}
//---------------------------------------------------------------------------------
int sleepEnabled(void) {
//---------------------------------------------------------------------------------
return sleepIsEnabled;
}
void sdmmcMsgHandler(int bytes, void *user_data);
void sdmmcValueHandler(u32 value, void* user_data);
void firmwareMsgHandler(int bytes, void *user_data);
//---------------------------------------------------------------------------------
void installSystemFIFO(void) {
//---------------------------------------------------------------------------------
fifoSetValue32Handler(FIFO_PM, powerValueHandler, 0);
if (isDSiMode()) {
fifoSetValue32Handler(FIFO_SDMMC, sdmmcValueHandler, 0);
fifoSetDatamsgHandler(FIFO_SDMMC, sdmmcMsgHandler, 0);
}
fifoSetDatamsgHandler(FIFO_FIRMWARE, firmwareMsgHandler, 0);
}

View File

@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------------
Copyright (C) 2005 - 2011
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/ndstypes.h>
#include <nds/system.h>
#include <nds/arm7/i2c.h>
//---------------------------------------------------------------------------------
void systemShutDown() {
//---------------------------------------------------------------------------------
if (!isDSiMode()) {
writePowerManagement(PM_CONTROL_REG,PM_SYSTEM_PWR);
} else {
i2cWriteRegister(I2C_PM, I2CREGPM_RESETFLAG, 1);
i2cWriteRegister(I2C_PM, I2CREGPM_PWRCNT, 1);
}
}

View File

@ -0,0 +1,393 @@
/*---------------------------------------------------------------------------------
Touch screen control for the ARM7
Copyright (C) 2005 - 2010
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/ndstypes.h>
#include <nds/system.h>
#include <nds/arm7/codec.h>
#include <nds/arm7/touch.h>
#include <nds/arm7/input.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;
//---------------------------------------------------------------------------------
static 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;
}
//---------------------------------------------------------------------------------
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;
}
}
//---------------------------------------------------------------------------------
static void touchReadDSMode(touchPosition *touchPos) {
//---------------------------------------------------------------------------------
int16 dist_max_y, dist_max_x, dist_max;
u8 error, error_where, first_check, i;
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->rawx = readTouchValue(TSC_MEASURE_X | 1, &dist_max_x, &error);
if(error==1) error_where += 1;
touchPos->rawy = 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;
}
}else{
error_where = 3;
touchPos->rawx = 0;
touchPos->rawy = 0;
last_time_touched = 0;
}
UpdateRange(&range, dist_max, error_where, last_time_touched);
}
static s32 xscale, yscale;
static s32 xoffset, yoffset;
//---------------------------------------------------------------------------------
void 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;
if (cdcIsAvailable()) {
int oldIME = enterCriticalSection();
cdcTouchInit();
leaveCriticalSection(oldIME);
}
}
//---------------------------------------------------------------------------------
bool touchPenDown() {
//---------------------------------------------------------------------------------
bool down;
int oldIME = enterCriticalSection();
if (cdcIsAvailable()) {
down = cdcTouchPenDown();
} else {
down = !(REG_KEYXY & (1<<6));
}
leaveCriticalSection(oldIME);
return down;
}
//---------------------------------------------------------------------------------
// reading pixel position:
//---------------------------------------------------------------------------------
void touchReadXY(touchPosition *touchPos) {
//---------------------------------------------------------------------------------
int oldIME = enterCriticalSection();
if (cdcIsAvailable()) {
cdcTouchRead(touchPos);
} else {
touchReadDSMode(touchPos);
}
leaveCriticalSection(oldIME);
s16 px = ( touchPos->rawx * xscale - xoffset + xscale/2 ) >>19;
s16 py = ( touchPos->rawy * 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;
}

View File

@ -0,0 +1,69 @@
/*---------------------------------------------------------------------------------
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 slots[2];
short slot1count, slot2count;
short slot1CRC, slot2CRC;
uint32 userSettingsBase;
readFirmware( 0x20, &userSettingsBase,2);
uint32 slot1Address = userSettingsBase * 8;
uint32 slot2Address = userSettingsBase * 8 + 0x100;
readFirmware( slot1Address , &slots[0], sizeof(PERSONAL_DATA));
readFirmware( slot2Address , &slots[1], 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
int currentSettingsSlot = 0;
short calc1CRC = swiCRC16( 0xffff, &slots[0], sizeof(PERSONAL_DATA));
short calc2CRC = swiCRC16( 0xffff, &slots[1], 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 ) {
currentSettingsSlot = (slot2count == (( slot1count + 1 ) & 0x7f) ? 1 : 0);
} else {
if ( calc2CRC == slot2CRC )
currentSettingsSlot = 1;
}
*PersonalData = slots[currentSettingsSlot];
}

Some files were not shown because too many files have changed in this diff Show More