[Scummvm-git-logs] scummvm master -> 4300571cf8f8a6d66237f7a24240e227ca1fe264

sev- sev at scummvm.org
Thu Feb 4 00:59:42 UTC 2021


This automated email contains information about 42 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
28086f4f8a DS: Replace outdated filesystem code
ab577c7930 DS: Bundle the engine data files in romfs
8c9eb8edc8 DS: List all available devices in the file browser
e23e809086 DS: Update compile flags
bfba7f3e41 DS: Use libnds functionality for reading the touchscreen and buttons
95ec266795 DS: Remove dead code
aa3b16e88e DS: Remove old audio code
bf63cd76ea DS: Get rid of consolePrintf
f405be230e DS: Clean up the main() function
1f8dc4d204 DS: Replace some deprecated APIs
438c2d8714 DS: Rewrite event handling
704deec031 DS: Improve text console support
926ec07532 DS: Simplify the framebuffer code
37774cd578 DS: Allow the game screen and the overlay to be shown at the same time
266e21de10 DS: Clean up the sprite code
3c306f33ed DS: Simplify the directory structure
9ca7845590 DS: Replace the options dialog
66472abf1a DS: Move timer code into OSystem_DS
fe05ae75cd DS: Support detecting the system language
8b55134547 DS: Re-add audio support using MaxMod
a900337952 DS: Fix default search paths
d614f3ce2c AUDIO: Disable Paula filtering on the DS
6fa77b3429 DS: Remove optimization of individual files for speed
1c40d79732 DS: Begin modularizing the DS backend
626b6ac4e9 DS: Move graphics code into a separate file
f802c2e88a DS: Add support for RGB cursors
2ca80f8c86 DS: Add -mthumb to the linker flags
4ac5421c6d DS: Add a generic dmaBlit function and use it in updateScreen
0c776013f7 DS: Add RGB colour support
cd7ae99f0b GIT: Ignore the romfs directory
a642279e5d DS: Add a Background class for the overlay
b37843f10d DS: Fix setGraphicsMode signature
7ddd7e4931 DS: Use the Background class for the game screen
e3fabc803b DS: Only update the palette and cursor when updateScreen() is called
521303b2ef DS: Handle scaling and scrolling in the Background class
f50b472840 DS: Load the selected theme on startup
2c1148791f DS: Replace the default assert function with sassert
ebb1306630 DS: Update configure
78015cbd04 TESTBED: Centre the rectangle on screen in the overlay test
2ea22a451c DS: Ensure that a mouse move event is sent before a mouse down event
72703a8d0a DS: Disable the ARM assembler code for now
4300571cf8 DOCS: First draft DS page


Commit: 28086f4f8aab0dc65f3a1c57ce26137328948bd7
    https://github.com/scummvm/scummvm/commit/28086f4f8aab0dc65f3a1c57ce26137328948bd7
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Replace outdated filesystem code

Changed paths:
  R backends/fs/ds/ds-fs-factory.cpp
  R backends/fs/ds/ds-fs-factory.h
  R backends/fs/ds/ds-fs.cpp
  R backends/fs/ds/ds-fs.h
  R backends/platform/ds/arm9/source/adpcm_arm.s
  R backends/platform/ds/arm9/source/cdaudio.cpp
  R backends/platform/ds/arm9/source/cdaudio.h
  R backends/platform/ds/arm9/source/fat/disc_io.c
  R backends/platform/ds/arm9/source/fat/disc_io.h
  R backends/platform/ds/arm9/source/fat/gba_nds_fat.c
  R backends/platform/ds/arm9/source/fat/gba_nds_fat.h
  R backends/platform/ds/arm9/source/fat/io_dldi.h
  R backends/platform/ds/arm9/source/fat/io_dldi.s
  R backends/platform/ds/arm9/source/fat/io_efa2.c
  R backends/platform/ds/arm9/source/fat/io_efa2.h
  R backends/platform/ds/arm9/source/fat/io_fcsr.c
  R backends/platform/ds/arm9/source/fat/io_fcsr.h
  R backends/platform/ds/arm9/source/fat/io_m3_common.c
  R backends/platform/ds/arm9/source/fat/io_m3_common.h
  R backends/platform/ds/arm9/source/fat/io_m3cf.c
  R backends/platform/ds/arm9/source/fat/io_m3cf.h
  R backends/platform/ds/arm9/source/fat/io_m3sd.c
  R backends/platform/ds/arm9/source/fat/io_m3sd.h
  R backends/platform/ds/arm9/source/fat/io_m3sd_asm.s
  R backends/platform/ds/arm9/source/fat/io_mmcf.c
  R backends/platform/ds/arm9/source/fat/io_mmcf.h
  R backends/platform/ds/arm9/source/fat/io_mpcf.c
  R backends/platform/ds/arm9/source/fat/io_mpcf.h
  R backends/platform/ds/arm9/source/fat/io_njsd.c
  R backends/platform/ds/arm9/source/fat/io_njsd.h
  R backends/platform/ds/arm9/source/fat/io_nmmc.c
  R backends/platform/ds/arm9/source/fat/io_nmmc.h
  R backends/platform/ds/arm9/source/fat/io_sccf.c
  R backends/platform/ds/arm9/source/fat/io_sccf.h
  R backends/platform/ds/arm9/source/fat/io_scsd.c
  R backends/platform/ds/arm9/source/fat/io_scsd.h
  R backends/platform/ds/arm9/source/fat/io_scsd_asm.s
  R backends/platform/ds/arm9/source/fat/io_sd_common.c
  R backends/platform/ds/arm9/source/fat/io_sd_common.h
  R backends/platform/ds/arm9/source/fat/m3sd.s
  R backends/platform/ds/arm9/source/gbampsave.cpp
  R backends/platform/ds/arm9/source/gbampsave.h
  R backends/platform/ds/arm9/source/zipreader.cpp
  R backends/platform/ds/arm9/source/zipreader.h
    backends/fs/posix/posix-fs-factory.cpp
    backends/fs/posix/posix-fs.cpp
    backends/module.mk
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsmain.h
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/osystem_ds.h
    backends/platform/ds/module.mk
    common/system.cpp
    configure


diff --git a/backends/fs/ds/ds-fs-factory.cpp b/backends/fs/ds/ds-fs-factory.cpp
deleted file mode 100644
index 3ec4a40bd8..0000000000
--- a/backends/fs/ds/ds-fs-factory.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// Disable symbol overrides for FILE as that is used in FLAC headers
-#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
-
-#if defined(__DS__)
-#include "dsmain.h" //for the isGBAMPAvailable() function
-#include "backends/fs/ds/ds-fs-factory.h"
-#include "backends/fs/ds/ds-fs.h"
-
-namespace Common {
-DECLARE_SINGLETON(DSFilesystemFactory);
-}
-
-AbstractFSNode *DSFilesystemFactory::makeRootFileNode() const {
-	if (DS::isGBAMPAvailable()) {
-		return new DS::GBAMPFileSystemNode();
-	} else {
-		return new DS::DSFileSystemNode();
-	}
-}
-
-AbstractFSNode *DSFilesystemFactory::makeCurrentDirectoryFileNode() const {
-	if (DS::isGBAMPAvailable()) {
-		return new DS::GBAMPFileSystemNode();
-	} else {
-		return new DS::DSFileSystemNode();
-	}
-}
-
-AbstractFSNode *DSFilesystemFactory::makeFileNodePath(const Common::String &path) const {
-	if (DS::isGBAMPAvailable()) {
-		return new DS::GBAMPFileSystemNode(path);
-	} else {
-		return new DS::DSFileSystemNode(path);
-	}
-}
-#endif
diff --git a/backends/fs/ds/ds-fs-factory.h b/backends/fs/ds/ds-fs-factory.h
deleted file mode 100644
index 7c42145518..0000000000
--- a/backends/fs/ds/ds-fs-factory.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef DS_FILESYSTEM_FACTORY_H
-#define DS_FILESYSTEM_FACTORY_H
-
-#include "common/singleton.h"
-#include "backends/fs/fs-factory.h"
-
-/**
- * Creates DSFilesystemNode objects.
- *
- * Parts of this class are documented in the base interface class, FilesystemFactory.
- */
-class DSFilesystemFactory : public FilesystemFactory, public Common::Singleton<DSFilesystemFactory> {
-public:
-	virtual AbstractFSNode *makeRootFileNode() const;
-	virtual AbstractFSNode *makeCurrentDirectoryFileNode() const;
-	virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const;
-
-private:
-	friend class Common::Singleton<SingletonBaseType>;
-};
-
-#endif /*DS_FILESYSTEM_FACTORY_H*/
diff --git a/backends/fs/ds/ds-fs.cpp b/backends/fs/ds/ds-fs.cpp
deleted file mode 100644
index 64430f3fe5..0000000000
--- a/backends/fs/ds/ds-fs.cpp
+++ /dev/null
@@ -1,687 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// Disable symbol overrides for FILE as that is used in FLAC headers
-#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
-
-#include "dsmain.h"
-#include "common/str.h"
-#include "common/util.h"
-//#include <NDS/ARM9/console.h> //basic print funcionality
-#include "backends/fs/ds/ds-fs.h"
-#include "backends/fs/stdiostream.h"
-#include "fat/gba_nds_fat.h"
-#include "common/bufferedstream.h"
-
-namespace DS {
-
-//////////////////////////////////////////////////////////////
-// DSFileSystemNode - Flash ROM file system using Zip files //
-//////////////////////////////////////////////////////////////
-
-ZipFile*	DSFileSystemNode::_zipFile = NULL;	// FIXME: Avoid non-const global vars
-char		currentDir[128];	// FIXME: Avoid non-const global vars
-bool		readPastEndOfFile = false;	// FIXME: Avoid non-const global vars
-
-enum {
-	WRITE_BUFFER_SIZE = 512
-};
-
-DSFileSystemNode::DSFileSystemNode() {
-	_displayName = "ds:/";
-	_path = "ds:/";
-	_isValid = true;
-	_isDirectory = true;
-	_path = "ds:/";
-
-/*	if (!_archive) {
-		_archive = (GBFS_FILE *) find_first_gbfs_file(scummdata);
-		if (!_archive) consolePrintf("No GBFS archive found!\n");
-	}*/
-
-	if (!_zipFile) {
-		_zipFile = new ZipFile();
-	}
-}
-
-DSFileSystemNode::DSFileSystemNode(const Common::String& path) {
-//	consolePrintf("--%s ",path.c_str());
-
-	int lastSlash = 3;
-	for (int r = 0; r < (int) path.size() - 1; r++) {
-		if (path[r] == '\\') {
-			lastSlash = r;
-		}
-	}
-
-	_displayName = Common::String(path.c_str() + lastSlash + 1);
-	_path = path;
-//	_isValid = true;
-//	_isDirectory = false;
-
-	const char *pathStr = path.c_str();
-
-	if (path.hasPrefix("ds:/")) {
-		pathStr += 4;
-	}
-
-	if (*pathStr == '\0') {
-		_isValid = true;
-		_isDirectory = true;
-		return;
-	}
-
-	_zipFile->setAllFilesVisible(true);
-	if (_zipFile->findFile(pathStr)) {
-		_isValid = true;
-		_isDirectory = _zipFile->isDirectory();
-	} else {
-		_isValid = false;
-		_isDirectory = false;
-	}
-	_zipFile->setAllFilesVisible(false);
-
-//	consolePrintf("%s - Found: %d, Dir: %d\n", pathStr, _isValid, _isDirectory);
-}
-
-DSFileSystemNode::DSFileSystemNode(const Common::String& path, bool isDir) {
-//	consolePrintf("--%s ",path.c_str());
-
-	int lastSlash = 3;
-	for (int r = 0; r < (int) path.size() - 1; r++) {
-		if (path[r] == '\\') {
-			lastSlash = r;
-		}
-	}
-
-	_displayName = Common::String(path.c_str() + lastSlash + 1);
-	_path = path;
-	_isValid = true;
-	_isDirectory = isDir;
-
-//	consolePrintf("Found: %d, Dir: %d\n", _isValid, _isDirectory);
-}
-
-DSFileSystemNode::DSFileSystemNode(const DSFileSystemNode *node) {
-	//TODO: not implemented?
-}
-
-AbstractFSNode *DSFileSystemNode::getChild(const Common::String& n) const {
-	if (_path.lastChar() == '\\') {
-		return new DSFileSystemNode(_path + n);
-	} else {
-		return new DSFileSystemNode(_path + "\\" + n);
-	}
-
-	return NULL;
-}
-
-bool DSFileSystemNode::getChildren(AbstractFSList &dirList, ListMode mode, bool hidden) const {
-//	consolePrintf("Listdir\n");
-//	consolePrintf("Directory\n");
-
-	//TODO: honor the hidden flag
-
-//	consolePrintf("This dir: %s\n", _path.c_str());
-
-	if (_path.hasPrefix("ds:/")) {
-		if (_path.size() > 4) {
-			_zipFile->changeDirectory(_path.c_str() + 4);
-		} else {
-			_zipFile->changeToRoot();
-
-/*			// This is the root dir, so add the RAM folder
-			DSFileSystemNode *dsfsn = new DSFileSystemNode("ds:/ram");
-			dsfsn->_isDirectory = true;
-			dirList->push_back(wrap(dsfsn));
-*/
-		}
-	} else {
-		_zipFile->changeDirectory(_path.c_str());
-	}
-
-	if (_zipFile->restartFile()) {
-		do {
-			char n[128];
-			_zipFile->getFileName(n);
-
-//			consolePrintf("file: %s\n", n);
-			if ( (_zipFile->isDirectory() && ((mode == Common::FSNode::kListDirectoriesOnly) || (mode == Common::FSNode::kListAll)) )
-				|| (!_zipFile->isDirectory() && ((mode == Common::FSNode::kListFilesOnly) || (mode == Common::FSNode::kListAll)) ) )
-			{
-				DSFileSystemNode *dsfsn = new DSFileSystemNode("ds:/" + Common::String(n), _zipFile->isDirectory());
-				dsfsn->_isDirectory = _zipFile->isDirectory();
-				dirList.push_back((dsfsn));
-			}
-
-		} while (_zipFile->skipFile());
-	}
-
-	return true;
-}
-
-AbstractFSNode *DSFileSystemNode::getParent() const {
-//	consolePrintf("parent\n");
-	DSFileSystemNode *p;
-
-	if (_path != "ds:/") {
-		const char *path = (const char *)_path.c_str();
-		int lastSlash = 4;
-
-		for (uint r = 4; r < _path.size(); r++) {
-			if (path[r] == '\\') {
-				lastSlash = r;
-			}
-		}
-
-		p = new DSFileSystemNode(Common::String(path, lastSlash));
-		p->_isDirectory = true;
-	} else {
-		p = new DSFileSystemNode();
-	}
-
-	return p;
-}
-
-Common::SeekableReadStream *DSFileSystemNode::createReadStream() {
-	return DSFileStream::makeFromPath(getPath(), false);
-}
-
-Common::WriteStream *DSFileSystemNode::createWriteStream() {
-	Common::WriteStream *stream = DSFileStream::makeFromPath(getPath(), true);
-	return Common::wrapBufferedWriteStream(stream, WRITE_BUFFER_SIZE);
-}
-
-bool DSFileSystemNode::createDirectory() {
-	return _isValid && _isDirectory;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// GBAMPFileSystemNode - File system using GBA Movie Player and CF card //
-//////////////////////////////////////////////////////////////////////////
-
-GBAMPFileSystemNode::GBAMPFileSystemNode() {
-	_displayName = "mp:/";
-	_path = "mp:/";
-	_isValid = false;
-	_isDirectory = true;
-}
-
-GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path) {
-//	consolePrintf("'%s'",path.c_str());
-
-	int lastSlash = 3;
-	for (int r = 0; r < (int) path.size() - 1; r++) {
-		if ((path[r] == '\\') || (path[r] == '/')) {
-			lastSlash = r;
-		}
-	}
-
-	if (path == "mp:/") {
-		// This is the root directory
-		_isDirectory = true;
-		_isValid = false;		// Old code returned false here, but I'm not sure why
-	} else {
-		char check[128];
-		memset(check, 0, 128);
-
-		if (path.size() > 4 && path.hasPrefix("mp:/")) {
-			// Files which start with mp:/
-			// Clear the filename to 128 bytes, because a libfat bug occasionally tries to read in this area.
-			strcpy(check, path.c_str() + 3);
-		} else {
-			// Clear the filename to 128 bytes, because a libfat bug occationally tries to read in this area.
-			strcpy(check, path.c_str());
-		}
-
-		// Remove terminating slash - FileExists fails without this
-		if (check[strlen(check) - 1] == '/') {
-			check[strlen(check) - 1] = 0;
-		}
-		int fileOrDir = FAT_FileExists(check);
-
-		_isDirectory = fileOrDir == FT_DIR;
-		_isValid = fileOrDir == FT_FILE;
-	}
-
-
-//	consolePrintf("Path: %s \n", check);
-
-	_displayName = Common::String(path.c_str() + lastSlash + 1);
-	_path = path;
-}
-
-GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path, bool isDirectoryFlag) {
-	//consolePrintf("'%s'",path.c_str());
-
-	int lastSlash = 3;
-	for (int r = 0; r < (int) path.size() - 1; r++) {
-		if ((path[r] == '\\') || (path[r] == '/')) {
-			lastSlash = r;
-		}
-	}
-
-	_displayName = Common::String(path.c_str() + lastSlash + 1);
-	_path = path;
-	_isValid = true;
-	_isDirectory = isDirectoryFlag;
-}
-
-
-GBAMPFileSystemNode::GBAMPFileSystemNode(const GBAMPFileSystemNode *node) {
-	//TODO: not implemented?
-}
-
-AbstractFSNode *GBAMPFileSystemNode::getChild(const Common::String& n) const {
-	if (_path.lastChar() == '\\') {
-		return new GBAMPFileSystemNode(_path + n);
-	} else {
-		return new GBAMPFileSystemNode(_path + "\\" + n);
-	}
-
-	return NULL;
-}
-
-bool GBAMPFileSystemNode::getChildren(AbstractFSList& dirList, ListMode mode, bool hidden) const {
-//	consolePrintf("Listdir\n");
-
-	//TODO: honor the hidden flag
-
-	enum { TYPE_NO_MORE = 0, TYPE_FILE = 1, TYPE_DIR = 2 };
-
-	char temp[128], fname[256], *path, *pathTemp;
-	strcpy(temp, _path.c_str());
-
-	path = temp + 3;
-
-	pathTemp = path;
-	while (*pathTemp) {
-		if (*pathTemp == '\\') {
-			*pathTemp = '/';
-		}
-		pathTemp++;
-	}
-
-	// consolePrintf("This dir: %s\n", path);
-	FAT_chdir(path);
-
-	int entryType = FAT_FindFirstFileLFN(fname);
-
-	while (entryType != TYPE_NO_MORE) {
-
-		if ( ((entryType == TYPE_DIR) && ((mode == Common::FSNode::kListDirectoriesOnly) || (mode == Common::FSNode::kListAll)))
-		||   ((entryType == TYPE_FILE) && ((mode == Common::FSNode::kListFilesOnly) || (mode == Common::FSNode::kListAll))) ) {
-			GBAMPFileSystemNode *dsfsn;
-
-			//consolePrintf("Fname: %s\n", fname);
-
-			if (strcmp(fname, ".") && strcmp(fname, "..")) {
-
-				if (!strcmp(path, "/")) {
-					dsfsn = new GBAMPFileSystemNode("mp:" + Common::String(path) + Common::String(fname), entryType == TYPE_DIR);
-				} else {
-					dsfsn = new GBAMPFileSystemNode("mp:" + Common::String(path) + Common::String("/") + Common::String(fname), entryType == TYPE_DIR);
-				}
-
-//				dsfsn->_isDirectory = entryType == DIR;
-				dirList.push_back((dsfsn));
-			}
-		} else {
-//			consolePrintf("Skipping %s\n", fname);
-		}
-
-		entryType = FAT_FindNextFileLFN(fname);
-	}
-
-//	consolePrintf("No more");
-
-	FAT_chdir("/");
-
-	return true;
-}
-
-AbstractFSNode *GBAMPFileSystemNode::getParent() const {
-//	consolePrintf("parent\n");
-	GBAMPFileSystemNode *p;
-
-	if (_path != "mp:/") {
-		const char *path = (const char *)_path.c_str();
-		int lastSlash = 4;
-
-		for (uint r = 4; r < strlen(path); r++) {
-			if (path[r] == '/') {
-				lastSlash = r;
-			}
-		}
-
-		p = new GBAMPFileSystemNode(Common::String(path, lastSlash));
-		p->_isDirectory = true;
-	} else {
-		p = new GBAMPFileSystemNode();
-	}
-
-	return p;
-}
-
-Common::SeekableReadStream *GBAMPFileSystemNode::createReadStream() {
-//	consolePrintf("Opening: %s\n", getPath().c_str());
-
-	if (!strncmp(getPath().c_str(), "mp:/", 4)) {
-		return DSFileStream::makeFromPath(getPath().c_str() + 3, false);
-	} else {
-		return DSFileStream::makeFromPath(getPath(), false);
-	}
-}
-
-Common::WriteStream *GBAMPFileSystemNode::createWriteStream() {
-	Common::WriteStream *stream = DSFileStream::makeFromPath(getPath(), true);
-	return Common::wrapBufferedWriteStream(stream, WRITE_BUFFER_SIZE);
-}
-
-bool GBAMPFileSystemNode::createDirectory() {
-	warning("GBAMPFileSystemNode::createDirectory(): Not supported");
-	return _isValid && _isDirectory;
-}
-
-
-
-DSFileStream::DSFileStream(void *handle) : _handle(handle) {
-	assert(handle);
-}
-
-DSFileStream::~DSFileStream() {
-	std_fclose((FILE *)_handle);
-}
-
-bool DSFileStream::err() const {
-	return std_ferror((FILE *)_handle) != 0;
-}
-
-void DSFileStream::clearErr() {
-	std_clearerr((FILE *)_handle);
-}
-
-bool DSFileStream::eos() const {
-	return std_feof((FILE *)_handle) != 0;
-}
-
-int32 DSFileStream::pos() const {
-	return std_ftell((FILE *)_handle);
-}
-
-int32 DSFileStream::size() const {
-	int32 oldPos = std_ftell((FILE *)_handle);
-	std_fseek((FILE *)_handle, 0, SEEK_END);
-	int32 length = std_ftell((FILE *)_handle);
-	std_fseek((FILE *)_handle, oldPos, SEEK_SET);
-
-	return length;
-}
-
-bool DSFileStream::seek(int32 offs, int whence) {
-	return std_fseek((FILE *)_handle, offs, whence) == 0;
-}
-
-uint32 DSFileStream::read(void *ptr, uint32 len) {
-	return std_fread(ptr, 1, len, (FILE *)_handle);
-}
-
-uint32 DSFileStream::write(const void *ptr, uint32 len) {
-	return std_fwrite(ptr, 1, len, (FILE *)_handle);
-}
-
-bool DSFileStream::flush() {
-	return std_fflush((FILE *)_handle) == 0;
-}
-
-DSFileStream *DSFileStream::makeFromPath(const Common::String &path, bool writeMode) {
-	FILE *handle = std_fopen(path.c_str(), writeMode ? "wb" : "rb");
-
-	if (handle)
-		return new DSFileStream(handle);
-	return 0;
-}
-
-
-// Stdio replacements
-enum {
-	MAX_FILE_HANDLES = 32
-};
-
-static bool inited = false;	// FIXME: Avoid non-const global vars
-static DS::fileHandle s_handle[MAX_FILE_HANDLES];	// FIXME: Avoid non-const global vars
-
-FILE *std_fopen(const char *name, const char *mode) {
-	if (!inited) {
-		for (int r = 0; r < MAX_FILE_HANDLES; r++) {
-			s_handle[r].used = false;
-		}
-		inited = true;
-		currentDir[0] = '\0';
-	}
-
-	char realName[MAXPATHLEN];
-
-	// Remove file system prefix
-	if ((name[0] == 'd') && (name[1] == 's') && (name[2] == ':') && (name[3] == '/')) {
-		Common::strlcpy(realName, name + 4, MAXPATHLEN);
-	} else if ((name[0] == 'm') && (name[1] == 'p') && (name[2] == ':') && (name[3] == '/')) {
-		Common::strlcpy(realName, name + 4, MAXPATHLEN);
-	} else {
-		Common::strlcpy(realName, name, MAXPATHLEN);
-	}
-
-//	consolePrintf("Open file:");
-//	consolePrintf("'%s', [%s]", name, realName);
-
-	if (DS::isGBAMPAvailable()) {
-		FAT_chdir("/");
-
-		// Turn all back slashes into forward slashes for gba_nds_fat
-		char *p = realName;
-		while (*p) {
-			if (*p == '\\')
-				*p = '/';
-			p++;
-		}
-
-		FAT_FILE *result = FAT_fopen(realName, mode);
-
-		if (result == 0) {
-//			consolePrintf("Error code %d\n", result);
-			//consolePrintf("Opening file %s\n", realName);
-		} else {
-//			consolePrintf("Opened file %d\n", result);
-		}
-//		MT_memoryReport();
-
-		return (FILE *)result;
-	}
-
-	// Fail to open file for writing.  It's in ROM!
-
-	// Allocate a file handle
-	int r = 0;
-	while (s_handle[r].used) {
-		r++;
-		assert(r < MAX_FILE_HANDLES);
-	}
-
-	char *data;
-
-	ZipFile *zip = DSFileSystemNode::getZip();
-	if (!zip) {
-//		consolePrintf("No zip yet!");
-		return NULL;
-	}
-
-	// Grab the data if it exists
-
-	zip->setAllFilesVisible(true);
-
-	if (currentDir[0] != 0) {
-		char nameWithPath[128];
-		sprintf(nameWithPath, "%s\\%s", currentDir, realName);
-		strcpy(realName, nameWithPath);
-	}
-
-//	consolePrintf("fopen(%s, %s)\n", realName, name);
-
-	if (zip->findFile(realName)) {
-		data = zip->getFile();
-		zip->setAllFilesVisible(false);
-
-		// Allocate a file handle
-		r = 0;
-		while (s_handle[r].used)
-			r++;
-
-
-		s_handle[r].used = true;
-		s_handle[r].pos = 0;
-		s_handle[r].data = data;
-		s_handle[r].size = zip->getFileSize();
-
-//		consolePrintf("Opened file %d: %s (%s)   ", r, realName, name);
-		return &s_handle[r];
-	} else {
-		zip->setAllFilesVisible(false);
-//		consolePrintf("Not found: %s (%s)  ", realName, name);
-		return NULL;
-	}
-}
-
-void std_fclose(FILE *handle) {
-
-	if (DS::isGBAMPAvailable()) {
-		FAT_fclose((FAT_FILE *) handle);
-		return;
-	}
-
-	handle->used = false;
-}
-
-size_t std_fread(void *ptr, size_t size, size_t numItems, FILE *handle) {
-//	consolePrintf("fread %d,%d %d ", size, numItems, ptr);
-
-	if (DS::isGBAMPAvailable()) {
-		readPastEndOfFile = false;
-
-		int bytes = FAT_fread(ptr, size, numItems, (FAT_FILE *) handle);
-		if (!FAT_feof((FAT_FILE *) handle)) {
-			return numItems;
-		} else {
-//			consolePrintf("Read past end of file: %d read out of %d\n", bytes / size, numItems);
-			if ((size_t)bytes != size * numItems) readPastEndOfFile = true;
-			return bytes / size;
-		}
-		return numItems;
-	}
-
-	if (handle->pos > handle->size)
-		numItems = 0;
-	else if ((int)(handle->pos + size * numItems) > handle->size)
-		numItems = (handle->size - handle->pos) / size;
-
-//	consolePrintf("read %d  ", size * numItems);
-
-	memcpy(ptr, handle->data + handle->pos, size * numItems);
-	handle->pos += size * numItems;
-
-	return numItems;
-}
-
-size_t std_fwrite(const void *ptr, size_t size, size_t numItems, FILE *handle) {
-	//consolePrintf("fwrite size=%d\n", size * numItems);
-
-	if (DS::isGBAMPAvailable()) {
-		FAT_fwrite(ptr, size, numItems, (FAT_FILE *) handle);
-		return numItems;
-	}
-
-	return 0;
-}
-
-bool std_feof(FILE *handle) {
-//	consolePrintf("feof ");
-
-	if (DS::isGBAMPAvailable()) {
-		return readPastEndOfFile && FAT_feof((FAT_FILE *) handle);
-	}
-
-//	consolePrintf("feof %s", handle->pos >= handle->size? "true": "false");
-	return handle->pos >= handle->size;
-}
-
-int std_fflush(FILE *handle) {
-	//FIXME: not implemented?
-//	consolePrintf("fflush ");
-	return 0;
-}
-
-long int std_ftell(FILE *handle) {
-	if (DS::isGBAMPAvailable()) {
-		return FAT_ftell((FAT_FILE *) handle);
-	}
-
-	return handle->pos;
-}
-
-int std_fseek(FILE *handle, long int offset, int whence) {
-//	consolePrintf("fseek %d %d ", offset, whence);
-
-	if (DS::isGBAMPAvailable()) {
-		return FAT_fseek((FAT_FILE *) handle, offset, whence);
-	}
-
-	switch (whence) {
-	case SEEK_CUR:
-		handle->pos += offset;
-		break;
-	case SEEK_SET:
-		handle->pos = offset;
-		break;
-	case SEEK_END:
-		handle->pos = handle->size + offset;
-		break;
-	default:
-		handle->pos = offset;
-		break;
-	}
-
-	return 0;
-}
-
-int std_ferror(FILE *handle) {
-	//FIXME: not implemented?
-//	consolePrintf("ferror ");
-
-	return readPastEndOfFile;
-}
-
-void std_clearerr(FILE *handle) {
-	//FIXME: not implemented?
-	readPastEndOfFile = false;
-//	consolePrintf("clearerr ");
-}
-
-} // namespace DS
diff --git a/backends/fs/ds/ds-fs.h b/backends/fs/ds/ds-fs.h
deleted file mode 100644
index 37708478de..0000000000
--- a/backends/fs/ds/ds-fs.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef _DS_FS_H
-#define _DS_FS_H
-
-#include "common/fs.h"
-#include "common/stream.h"
-#include "backends/fs/abstract-fs.h"
-
-#include "zipreader.h"
-#include "fat/gba_nds_fat.h"
-
-namespace DS {
-
-/**
- * Implementation of the ScummVM file system API.
- * This class is used when a Flash cart is in use.
- *
- * Parts of this class are documented in the base interface class, AbstractFSNode.
- */
-class DSFileSystemNode : public AbstractFSNode {
-protected:
-	static ZipFile *_zipFile;
-
-	Common::String _displayName;
-	Common::String _path;
-	bool _isDirectory;
-	bool _isValid;
-
-public:
-	/**
-	 * Creates a DSFilesystemNode with the root node as path.
-	 */
-	DSFileSystemNode();
-
-	/**
-	 * Creates a DSFilesystemNode for a given path.
-	 *
-	 * @param path String with the path the new node should point to.
-	 */
-	DSFileSystemNode(const Common::String &path);
-
-	/**
-	 * Creates a DSFilesystemNode for a given path.
-	 *
-	 * @param path String with the path the new node should point to.
-	 * @param path true if path is a directory, false otherwise.
-	 */
-	DSFileSystemNode(const Common::String& path, bool isDir);
-
-	/**
-	 * Copy constructor.
-	 */
-	DSFileSystemNode(const DSFileSystemNode *node);
-
-	virtual bool exists() const { return true; }		//FIXME: this is just a stub
-	virtual Common::String getDisplayName() const {  return _displayName; }
-	virtual Common::String getName() const {  return _displayName; }
-	virtual Common::String getPath() const { return _path; }
-	virtual bool isDirectory() const { return _isDirectory; }
-	virtual bool isReadable() const { return true; }	//FIXME: this is just a stub
-	virtual bool isWritable() const { return true; }	//FIXME: this is just a stub
-
-	/**
-	 * Returns a copy of this node.
-	 */
-	virtual AbstractFSNode *clone() const { return new DSFileSystemNode(this); }
-	virtual AbstractFSNode *getChild(const Common::String& name) const;
-	virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
-	virtual AbstractFSNode *getParent() const;
-
-	virtual Common::SeekableReadStream *createReadStream();
-	virtual Common::WriteStream *createWriteStream();
-	virtual bool createDirectory();
-
-	/**
-	 * Returns the zip file this node points to.
-	 * TODO: check this documentation.
-	 */
-	static ZipFile *getZip() { return _zipFile; }
-};
-
- /**
- * Implementation of the ScummVM file system API.
- * This class is used when the GBAMP (GBA Movie Player) is used with a CompactFlash card.
- *
- * Parts of this class are documented in the base interface class, AbstractFSNode.
- */
-class GBAMPFileSystemNode : public AbstractFSNode {
-protected:
-	Common::String _displayName;
-	Common::String _path;
-	bool _isDirectory;
-	bool _isValid;
-
-public:
-	/**
-	 * Creates a GBAMPFilesystemNode with the root node as path.
-	 */
-	GBAMPFileSystemNode();
-
-	/**
-	 * Creates a GBAMPFilesystemNode for a given path.
-	 *
-	 * @param path String with the path the new node should point to.
-	 */
-	GBAMPFileSystemNode(const Common::String &path);
-
-	/**
-	 * Creates a DSFilesystemNode for a given path.
-	 *
-	 * @param path String with the path the new node should point to.
-	 * @param path true if path is a directory, false otherwise.
-	 */
-	GBAMPFileSystemNode(const Common::String &path, bool isDirectoryFlag);
-
-	/**
-	 * Copy constructor.
-	 */
-	GBAMPFileSystemNode(const GBAMPFileSystemNode *node);
-
-	virtual bool exists() const { return _isValid || _isDirectory; }
-	virtual Common::String getDisplayName() const {  return _displayName; }
-	virtual Common::String getName() const {  return _displayName; }
-	virtual Common::String getPath() const { return _path; }
-	virtual bool isDirectory() const { return _isDirectory; }
-	virtual bool isReadable() const { return true; }	//FIXME: this is just a stub
-	virtual bool isWritable() const { return true; }	//FIXME: this is just a stub
-
-	/**
-	 * Returns a copy of this node.
-	 */
-	virtual AbstractFSNode *clone() const { return new GBAMPFileSystemNode(this); }
-	virtual AbstractFSNode *getChild(const Common::String& name) const;
-	virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
-	virtual AbstractFSNode *getParent() const;
-
-	virtual Common::SeekableReadStream *createReadStream();
-	virtual Common::WriteStream *createWriteStream();
-	virtual bool createDirectory();
-};
-
-struct fileHandle {
-	int pos;
-	bool used;
-	char *data;
-	int size;
-};
-
-
-class DSFileStream : public Common::SeekableReadStream, public Common::WriteStream, public Common::NonCopyable {
-protected:
-
-	/** File handle to the actual file. */
-	void 	*_handle;
-
-public:
-	/**
-	 * Given a path, invokes fopen on that path and wrap the result in a
-	 * StdioStream instance.
-	 */
-	static DSFileStream *makeFromPath(const Common::String &path, bool writeMode);
-
-	DSFileStream(void *handle);
-	virtual ~DSFileStream();
-
-	bool err() const;
-	void clearErr();
-	bool eos() const;
-
-	virtual uint32 write(const void *dataPtr, uint32 dataSize);
-	virtual bool flush();
-
-	virtual int32 pos() const;
-	virtual int32 size() const;
-	bool seek(int32 offs, int whence = SEEK_SET);
-	uint32 read(void *dataPtr, uint32 dataSize);
-};
-
-
-// FIXME/TODO: Get rid of the following hacks. Top priority: Get rid of
-// the 'FILE' (re)definition. Simply calling it STD_FILE or so wold already
-// suffice (need to adjust affected code, of course).
-// Once the OSystem::logMessage() patch is in SVN, we should also be
-// able to get rid of stderr, stdout, stdin.
-// Moreover, the std_FOO() functions could then be moved to a private
-// header, or even completely merged into DSFileStream, and all other
-// DS code switch to use that.
-#undef stderr
-#undef stdout
-#undef stdin
-
-#define stdout ((DS::fileHandle *) -1)
-#define stderr ((DS::fileHandle *) -2)
-#define stdin ((DS::fileHandle *) -3)
-
-#define FILE DS::fileHandle
-
-// Please do not remove any of these prototypes that appear not to be required.
-FILE*	std_fopen(const char *name, const char *mode);
-void	std_fclose(FILE *handle);
-size_t	std_fread(void *ptr, size_t size, size_t numItems, FILE *handle);
-size_t	std_fwrite(const void *ptr, size_t size, size_t numItems, FILE *handle);
-bool	std_feof(FILE *handle);
-long int std_ftell(FILE *handle);
-int		std_fseek(FILE *handle, long int offset, int whence);
-void	std_clearerr(FILE *handle);
-int		std_fflush(FILE *handle);
-int		std_ferror(FILE *handle);
-
-} // End of namespace DS
-
-#endif //_DS_FS_H
diff --git a/backends/fs/posix/posix-fs-factory.cpp b/backends/fs/posix/posix-fs-factory.cpp
index cd6c4bb7dd..98550198f1 100644
--- a/backends/fs/posix/posix-fs-factory.cpp
+++ b/backends/fs/posix/posix-fs-factory.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#if defined(POSIX) || defined(PLAYSTATION3)
+#if defined(POSIX) || defined(PLAYSTATION3) || defined(__DS__)
 
 // Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h.
 // Also with clock() in sys/time.h in some Mac OS X SDKs.
diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp
index 7fcc7cf990..df3af43f63 100644
--- a/backends/fs/posix/posix-fs.cpp
+++ b/backends/fs/posix/posix-fs.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#if defined(POSIX) || defined(PLAYSTATION3) || defined(PSP2)
+#if defined(POSIX) || defined(PLAYSTATION3) || defined(PSP2) || defined(__DS__)
 
 // Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h.
 // Also with clock() in sys/time.h in some Mac OS X SDKs.
diff --git a/backends/module.mk b/backends/module.mk
index e80a4f643b..dbd4d524fa 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -284,8 +284,9 @@ endif
 
 ifeq ($(BACKEND),ds)
 MODULE_OBJS += \
-	fs/ds/ds-fs.o \
-	fs/ds/ds-fs-factory.o \
+	fs/posix/posix-fs.o \
+	fs/posix/posix-fs-factory.o \
+	fs/posix/posix-iostream.o \
 	plugins/ds/ds-provider.o
 endif
 
diff --git a/backends/platform/ds/arm9/source/adpcm_arm.s b/backends/platform/ds/arm9/source/adpcm_arm.s
deleted file mode 100644
index 4715346cb9..0000000000
--- a/backends/platform/ds/arm9/source/adpcm_arm.s
+++ /dev/null
@@ -1,108 +0,0 @@
-@ ScummVM - Graphic Adventure Engine
-@
-@ ScummVM is the legal property of its developers, whose names
-@ are too numerous to list here. Please refer to the COPYRIGHT
-@ file distributed with this source distribution.
-@
-@ 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 2
-@ 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, write to the Free Software
-@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-@
-@ @author Robin Watts (robin at wss.co.uk)
-
-	.global	ARM_adpcm
-	.section .itcm,"ax", %progbits
-	.align 2
-	.code 32
-
-	@ ARM implementation of inner ADPCM decoding loop
-	@
-	@ C prototype would be:
-	@
-	@ extern "C" void ARM_adpcm(int *block,
-	@                           int  len,
-	@                           int  stepTableIndex,
-	@                           int  firstSample,
-	@                           s16 *decompressionBuffer)
-ARM_adpcm
-	@ r0 = block
-	@ r1 = len
-	@ r2 = stepTableIndex
-	@ r3 = firstSample
-	@ <> = decompressionBuffer
-	STMFD	r13!,{r4-r11,r14}
-	LDR	r4,[r13,#4*9]
-
-	LDR	r12,[r0],#4	@ r12 = word = block[r>>3]
-	MOV	r14,#0
-	ADR	r11,stepTab
-	ADR	r7, indexTab
-	MOV	r2, r2, LSL #1	@ r2 = stepTableIndex*2 - hold it doubled
-	STR	r3, [r4],#2	@ decompBuff[0] = firstSample
-	MOV	r3, r3, LSL #16	@ r3 = firstSample<<16 (for saturated maths)
-	SUBS	r1, r1, #1
-	BLE	end
-loop:
-	LDRH	r10,[r11,r2]	@ r10 = stepTab[stepTableIndex]
-	TST	r12,#4		@ if ((offset & 4) == 0)
-	MOVEQ	r9, #0		@ 	r9 = diff = 0
-	MOVNE	r9, r10		@ else	r9 = diff = stepTab[stepTableIndex]
-
-	TST	r12,#2		@ if (offset & 2)
-	ADDNE	r9, r9, r10,ASR #1	@ 	diff += r10>>1
-
-	TST	r12,#1		@ if (offset & 1)
-	ADDNE	r9, r9, r10,ASR #2	@ 	diff += r10>>2
-
-	ADD	r9, r9, r10,ASR #3	@ diff += r10>>3
-
-	TST	r12,#8		@ if (offset & 8
-	RSBNE	r9, r9, r10
-
-	ADDS	r3, r3, r9	@ r3 = newSample = prevSample+diff
-	RSCVS	r3, r3, #1<<31	@ r3 = clip(newSample)
-	MOV	r8, r3, LSR #16
-
-	AND	r6, r12,#4	@ r6 = offset
-	LDRB	r6, [r7,r6]	@ r6 = indexTab[offset]
-	MOV	r12,r12,LSR #4
-	STRH	r8, [r4],#2
-
-	ADDS	r2,r2,r6,LSL #1	@ r2 = stepTableIndex += indexTab[offset]
-	MOVLT	r2,#0
-	CMP	r2,#88*2
-	MOVGT	r2,#88*2
-	SUBS	r1,r1,#1
-	BEQ	end
-	SUBS	r14,r14,#0x10000000
-	LDREQ	r12,[r0],#4
-	B	loop
-
-end:
-	LDMFD	r13!,{r4-r11,PC}
-
-stepTab:
-	DCW	7, 8, 9, 10, 11, 12, 13, 14,
-	DCW	16, 17, 19, 21, 23, 25, 28, 31,
-	DCW	34, 37, 41, 45, 50, 55, 60, 66,
-	DCW	73, 80, 88, 97, 107, 118, 130, 143,
-	DCW	157, 173, 190, 209, 230, 253, 279, 307,
-	DCW	337, 371, 408, 449, 494, 544, 598, 658,
-	DCW	724, 796, 876, 963, 1060, 1166, 1282, 1411,
-	DCW	1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
-	DCW	3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
-	DCW	7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
-	DCW	15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
-	DCW	32767
-indexTab:
-	DCB -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8
diff --git a/backends/platform/ds/arm9/source/cdaudio.cpp b/backends/platform/ds/arm9/source/cdaudio.cpp
deleted file mode 100644
index 3952eeb6ab..0000000000
--- a/backends/platform/ds/arm9/source/cdaudio.cpp
+++ /dev/null
@@ -1,539 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// Disable symbol overrides for FILE as that is used in FLAC headers
-#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
-
-#include "dsmain.h"
-#include "cdaudio.h"
-#include "backends/fs/ds/ds-fs.h"
-#include "common/config-manager.h"
-#include "NDS/scummvm_ipc.h"
-
-#define WAV_FORMAT_IMA_ADPCM 0x14
-#define BUFFER_SIZE 8192
-#define BUFFER_CHUNK_SIZE (BUFFER_SIZE >> 2)
-
-namespace DS {
-namespace CD {
-
-struct WaveHeader {
-
-	char		riff[4];		// 'RIFF'
-	u32			size;			// Size of the file
-	char		wave[4];		// 'WAVE'
-
-	// fmt chunk
-	char		fmt[4];			// 'fmt '
-	u32			fmtSize;		// Chunk size
-	u16			fmtFormatTag;	// Format of this file
-	u16			fmtChannels;	// Num channels
-	u32			fmtSamPerSec;	// Samples per second
-	u32			fmtBytesPerSec; // Bytes per second
-	u16			fmtBlockAlign;	// Block alignment
-	u16			fmtBitsPerSam;	// Bits per sample
-
-	u16			fmtExtraData;	// Number of extra fmt bytes
-	u16			fmtExtra;		// Samples per block (only for IMA-ADPCM files)
-} __attribute__ ((packed));
-
-struct chunkHeader {
-	char 		name[4];
-	u32			size;
-} __attribute__ ((packed));
-
-struct Header {
-	s16 		firstSample;
-	char		stepTableIndex;
-	char		reserved;
-} __attribute__ ((packed));
-
-struct decoderFormat {
-	s16 initial;
-	unsigned char tableIndex;
-	unsigned char test;
-	unsigned char	sample[1024];
-} __attribute__ ((packed));
-
-static bool s_started = false;
-static bool s_active = false;
-static WaveHeader waveHeader;
-static Header blockHeader;
-static FILE *s_file;
-static int fillPos;
-static bool isPlayingFlag = false;
-
-static s16 *audioBuffer;
-static u32 sampleNum;
-static s16 *decompressionBuffer;
-static int s_numLoops;
-static int blockCount;
-static int dataChunkStart;
-static int blocksLeft;
-static bool trackStartsAt2 = false;
-
-
-// These are from Microsoft's document on DVI ADPCM
-static const int stepTab[ 89 ] = {
-7, 8, 9, 10, 11, 12, 13, 14,
-16, 17, 19, 21, 23, 25, 28, 31,
-34, 37, 41, 45, 50, 55, 60, 66,
-73, 80, 88, 97, 107, 118, 130, 143,
-157, 173, 190, 209, 230, 253, 279, 307,
-337, 371, 408, 449, 494, 544, 598, 658,
-724, 796, 876, 963, 1060, 1166, 1282, 1411,
-1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
-3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
-7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
-15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
-32767 };
-
-static const int indexTab[ 16 ] = { -1, -1, -1, -1, 2, 4, 6, 8,
--1, -1, -1, -1, 2, 4, 6, 8 };
-
-void playNextBlock();
-void decompressBlock();
-
-
-void allocBuffers() {
-
-}
-
-void setActive(bool active) {
-	s_active = active;
-}
-
-bool getActive() {
-	return s_active;
-}
-
-void playTrack(int track, int numLoops, int startFrame, int duration) {
-	Common::String path = ConfMan.get("path");
-
-	if (isPlayingFlag) {
-		stopTrack();
-	}
-
-	if (trackStartsAt2) {
-		track++;
-	}
-
-
-
-	char str[100];
-
-	if (path.lastChar() != '/')
-		path += '/';
-
-	Common::String fname;
-
-	sprintf(str, "track%d.wav", track);
-	fname = path + str;
-	s_file = DS::std_fopen(fname.c_str(), "rb");
-
-	if (!s_file) {
-		sprintf(str, "track%02d.wav", track);
-		fname = path + str;
-		s_file = DS::std_fopen(fname.c_str(), "rb");
-	}
-
-	if (!s_file) {
-		consolePrintf("Failed to open %s!\n", path.c_str());
-		return;
-	}
-
-
-	DS::std_fread(&waveHeader, sizeof(waveHeader), 1, s_file);
-
-	consolePrintf("File: %s\n", fname.c_str());
-
-	consolePrintf("Playing track %d\n", track);
-	consolePrintf("Format: %d\n", waveHeader.fmtFormatTag);
-	consolePrintf("Rate  : %d\n", waveHeader.fmtSamPerSec);
-	consolePrintf("Bits  : %d\n", waveHeader.fmtBitsPerSam);
-	consolePrintf("BlkSz : %d\n", waveHeader.fmtExtra);
-
-	if ((waveHeader.fmtFormatTag != 17) && (waveHeader.fmtFormatTag != 20)) {
-		consolePrintf("Wave file is in the wrong format!  You must use IMA-ADPCM 4-bit mono.\n");
-		DS::std_fclose(s_file);
-		return;
-	}
-
-	for (int r = 0; r < 8; r++) {
-		IPC->adpcm.buffer[r] = (u8 * volatile) (decoderFormat *) malloc(waveHeader.fmtBlockAlign);
-		IPC->adpcm.filled[r] = false;
-		IPC->adpcm.arm7Dirty[r] = false;
-	}
-
-	// Skip chunks until we reach the data chunk
-	chunkHeader chunk;
-	DS::std_fread(&chunk, sizeof(chunkHeader), 1, s_file);
-
-	while (!((chunk.name[0] == 'd') && (chunk.name[1] == 'a') && (chunk.name[2] == 't') && (chunk.name[3] == 'a'))) {
-		DS::std_fseek(s_file, chunk.size, SEEK_CUR);
-		DS::std_fread(&chunk, sizeof(chunkHeader), 1, s_file);
-	}
-
-	dataChunkStart = DS::std_ftell(s_file);
-
-
-	sampleNum = 0;
-	blockCount = 0;
-
-	IPC->streamFillNeeded[0] = true;
-	IPC->streamFillNeeded[1] = true;
-	IPC->streamFillNeeded[2] = true;
-	IPC->streamFillNeeded[3] = true;
-	if (!s_started) {
-		fillPos = 0;
-		audioBuffer = (s16 *) malloc(BUFFER_SIZE * 2);
-		decompressionBuffer = (s16 *) malloc(waveHeader.fmtExtra * 2);
-		s_started = true;
-//		consolePrintf("****Starting buffer*****\n");
-		memset(audioBuffer, 0, BUFFER_SIZE * 2);
-		memset(decompressionBuffer, 0, waveHeader.fmtExtra * 2);
-		DS::playSound(audioBuffer, BUFFER_SIZE * 2, false, false, waveHeader.fmtSamPerSec);
-
-	}
-	fillPos = (IPC->streamPlayingSection + 1) & 3;
-	isPlayingFlag = true;
-
-
-	// Startframe is a 75Hz timer.  Dunno why, since nothing else
-	// seems to run at that rate.
-	int tenths = (startFrame * 10) / 75;
-
-	// Seek to the nearest block start to the start time
-	int samples = (tenths * waveHeader.fmtSamPerSec) / 10;
-	int block = samples / waveHeader.fmtExtra;
-
-
-	if (duration == 0) {
-		blocksLeft = 0;
-	} else {
-		blocksLeft = ((((duration * 100) / 75) * (waveHeader.fmtSamPerSec)) / (waveHeader.fmtExtra) / 100) + 10;
-	}
-//	consolePrintf("Playing %d blocks (%d)\n\n", blocksLeft, duration);
-
-	// No need to seek if we're starting from the beginning
-	if (block != 0) {
-		DS::std_fseek(s_file, dataChunkStart + block * waveHeader.fmtBlockAlign, SEEK_SET);
-//		consolePrintf("Startframe: %d  msec: %d (%d,%d)\n", startFrame, tenthssec, samples, block);
-	}
-
-
-	//decompressBlock();
-	playNextBlock();
-	s_numLoops = numLoops;
-}
-
-void update() {
-	playNextBlock();
-}
-
-#ifdef ARM_ADPCM
-// FIXME: This code, as well as the source file adpcm_arm.s, are
-// apparently unused. Maybe that is a mistake? Or maybe there is a bug
-// in ARM_adpcm (then this should be reported and fixed). Or maybe there
-// are other good reasons to prefer the C code, but then this as well as
-// the assembler source file should be removed.
-extern "C" void ARM_adpcm(int *block, int len, int stepTableIndex,
-                          int firstSample, s16 *decompressionBuffer);
-#endif
-
-void decompressBlock() {
-	int block[2048];
-	bool loop = false;
-
-	blockCount++;
-
-	if (blockCount < 10) return;
-
-
-	do {
-		DS::std_fread(&blockHeader, sizeof(blockHeader), 1, s_file);
-
-		DS::std_fread(&block[0], waveHeader.fmtBlockAlign - sizeof(blockHeader), 1, s_file);
-
-		if (DS::std_feof(s_file)) {
-			// Reached end of file, so loop
-
-
-			if ((s_numLoops == -1) || (s_numLoops > 1)) {
-				// Seek file to first packet
-				if (s_numLoops != -1) {
-					s_numLoops--;
-				}
-				DS::std_fseek(s_file, dataChunkStart, SEEK_SET);
-				loop = true;
-			} else {
-				// Fill decompression buffer with zeros to prevent glitching
-				for (int r = 0; r < waveHeader.fmtExtra; r++) {
-					decompressionBuffer[r] = 0;
-				}
-//				consolePrintf("Stopping music\n");
-				stopTrack();
-				return;
-			}
-
-		} else {
-			loop = false;
-		}
-
-	} while (loop);
-
-
-	if (blocksLeft > 0) {
-		blocksLeft--;
-	//	consolePrintf("%d ", blocksLeft);
-		if (blocksLeft == 0) {
-			stopTrack();
-			return;
-		}
-	}
-
-#ifdef ARM_ADPCM
-	ARM_adpcm(block, waveHeader.fmtExtra,
-	          blockHeader.stepTableIndex,
-	          blockHeader.firstSample,
-	          decompressionBuffer);
-#else
-	// First sample is in header
-	decompressionBuffer[0] = blockHeader.firstSample;
-
-	// Set up initial table indeces
-	int stepTableIndex = blockHeader.stepTableIndex;
-	int prevSample = blockHeader.firstSample;
-
-//	consolePrintf("Decompressing block step=%d fs=%d\n", stepTableIndex, prevSample);
-
-	for (int r = 0; r < waveHeader.fmtExtra - 1; r++) {
-
-		int word = block[r >> 3];
-		int offset = 0;
-
-		switch (7 - (r & 0x0007)) {
-		case 0:
-			offset = (word & 0xF0000000) >> 28;
-			break;
-		case 1:
-			offset = (word & 0x0F000000) >> 24;
-			break;
-		case 2:
-			offset = (word & 0x00F00000) >> 20;
-			break;
-		case 3:
-			offset = (word & 0x000F0000) >> 16;
-			break;
-		case 4:
-			offset = (word & 0x0000F000) >> 12;
-			break;
-		case 5:
-			offset = (word & 0x00000F00) >> 8;
-			break;
-		case 6:
-			offset = (word & 0x000000F0) >> 4;
-			break;
-		case 7:
-			offset = (word & 0x0000000F);
-			break;
-		}
-
-		int diff = 0;
-
-		if (offset & 4) {
-			diff = diff + stepTab[stepTableIndex];
-		}
-
-		if (offset & 2) {
-			diff = diff + (stepTab[stepTableIndex] >> 1);
-		}
-
-		if (offset & 1) {
-			diff = diff + (stepTab[stepTableIndex] >> 2);
-		}
-
-		diff = diff + (stepTab[stepTableIndex] >> 3);
-
-		if (offset & 8) {
-			diff = -diff;
-		}
-
-		int newSample = prevSample + diff;
-
-		if (newSample > 32767) newSample = 32767;
-		if (newSample < -32768) newSample = -32768;
-
-		decompressionBuffer[r + 1] = newSample;
-
-		prevSample = newSample;
-
-		stepTableIndex += indexTab[offset];
-
-		if (stepTableIndex > 88) stepTableIndex = 88;
-		if (stepTableIndex < 0) stepTableIndex = 0;
-
-
-	}
-#endif
-}
-
-void playNextBlock() {
-	if (!isPlayingFlag)
-		return;
-	int lastBlockId = -1;
-
-	while (IPC->adpcm.semaphore);		// Wait for buffer to become free if needed
-	IPC->adpcm.semaphore = true;		// Lock the buffer structure to prevent clashing with the ARM7
-//	DC_FlushAll();
-
-	//-8644, 25088
-	for (int block = fillPos + 1; block < fillPos + 4; block++) {
-
-		int blockId = block & 3;
-
-		if (IPC->streamFillNeeded[blockId]) {
-
-			IPC->streamFillNeeded[blockId] = false;
-//			DC_FlushAll();
-
-/*			if (!(REG_KEYINPUT & KEY_R)) {
-				//consolePrintf("Align: %d First: %d  Step:%d  Res:%d\n", waveHeader.fmtBlockAlign, blockHeader.firstSample, blockHeader.stepTableIndex, blockHeader.reserved);
-				consolePrintf("Filling buffer %d\n", blockId);
-			}*/
-			for (int r = blockId * BUFFER_CHUNK_SIZE; r < (blockId + 1) * BUFFER_CHUNK_SIZE; r++) {
-				if (isPlayingFlag) {
-					audioBuffer[r] = decompressionBuffer[sampleNum++];
-					if (sampleNum >= waveHeader.fmtExtra) {
-						decompressBlock();
-						sampleNum = 0;
-					}
-				}
-			}
-
-			lastBlockId = blockId;
-			IPC->streamFillNeeded[blockId] = false;
-//			DC_FlushAll();
-
-		}
-	}
-
-
-
-	if (lastBlockId != -1) {
-		fillPos = lastBlockId;
-/*		if (!(REG_KEYINPUT & KEY_R)) {
-			consolePrintf("Frame fill done\n");
-		}*/
-	}
-	IPC->adpcm.semaphore = false;		// Release the buffer structure
-//	DC_FlushAll();
-}
-
-void stopTrack() {
-	if (!isPlayingFlag)
-		return;
-
-	DS::std_fclose(s_file);
-
-	isPlayingFlag = false;
-
-	for (int r = 0; r < BUFFER_SIZE; r++) {
-		audioBuffer[r] = 0;
-	}
-
-	for (int r = 0; r < waveHeader.fmtExtra; r++) {
-		decompressionBuffer[r] = 0;
-	}
-//	DS::stopSound(1);
-
-//	free(audioBuffer);
-//	free(decompressionBuffer);
-
-	DC_FlushAll();
-}
-
-bool trackExists(int num) {
-	Common::String path;
-	char fname[128];
-	FILE *file;
-
-	sprintf(fname, "track%d.wav", num);
-
-	path = ConfMan.get("path");
-	if (path.lastChar() != '/')
-		path += '/';
-	path += fname;
-
-	consolePrintf("Looking for %s...", path.c_str());
-
-	file = DS::std_fopen(path.c_str(), "r");
-	if (file) {
-		consolePrintf("Success!\n");
-		setActive(true);
-		DS::std_fclose(file);
-		return true;
-	}
-
-	sprintf(fname, "track%02d.wav", num);
-
-	path = ConfMan.get("path");
-	if (path.lastChar() != '/')
-		path += '/';
-	path += fname;
-
-	consolePrintf("Looking for %s...", path.c_str());
-
-	file = DS::std_fopen(path.c_str(), "r");
-	if (file) {
-		consolePrintf("Success!\n");
-		setActive(true);
-		DS::std_fclose(file);
-		return true;
-	}
-
-	setActive(false);
-	consolePrintf("Failed!\n");
-	return false;
-}
-
-bool checkCD() {
-	// Need to check whethe CD audio files are present - do this by trying to open Track1.wav.
-	consolePrintf("Attempted to open cd drive\n");
-
-	if (trackExists(1)) {
-		trackStartsAt2 = false;
-		return true;
-	} else if (trackExists(2)) {
-		trackStartsAt2 = true;
-		return true;
-	} else {
-		return false;
-	}
-}
-
-bool isPlaying() {
-	return isPlayingFlag;
-}
-
-}
-} // End of namespace DS
diff --git a/backends/platform/ds/arm9/source/cdaudio.h b/backends/platform/ds/arm9/source/cdaudio.h
deleted file mode 100644
index 77766bae8e..0000000000
--- a/backends/platform/ds/arm9/source/cdaudio.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef _CDAUDIO_H_
-#define _CDAUDIO_H_
-
-namespace DS {
-namespace CD {
-
-// FIXME/TODO: The code in this file should be turned into a custom
-// AudioCDManager subclass, see backends/audiocd/ and common/system.h
-
-void setActive(bool active);
-void playTrack(int track, int numLoops, int startFrame, int duration);
-void stopTrack();
-bool checkCD();
-bool getActive();
-bool isPlaying();
-void update();
-
-}
-} // End of namespace DS
-
-#endif
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 68cd3a24a7..45323467d1 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -23,13 +23,11 @@
 
 // - Remove scummconsole.c
 // - Delete files
-// - Fatlib conversion?
 
 // - libcartreset
 // - Alternative controls - tap for left click, double for right
 // - Inherit the Earth?
 // - Stereo audio?
-// - Delete saves?
 // - Software scaler?
 // - 100% scale
 
@@ -77,6 +75,7 @@
 #include <nds/registers_alt.h>
 #include <nds/arm9/exceptions.h>
 #include <nds/arm9/console.h>
+#include <filesystem.h>
 
 //#include <ARM9/console.h> //basic print funcionality
 
@@ -87,8 +86,6 @@
 #include "dsmain.h"
 #include "osystem_ds.h"
 #include "icons_raw.h"
-#include "fat/gba_nds_fat.h"
-#include "fat/disc_io.h"
 #include "keyboard_raw.h"
 #include "keyboard_pal_raw.h"
 #define V16(a, b) ((a << 12) | b)
@@ -106,7 +103,6 @@
 #include "engines/engine.h"
 
 #include "backends/plugins/ds/ds-provider.h"
-#include "backends/fs/ds/ds-fs.h"
 #include "base/version.h"
 #include "common/util.h"
 
@@ -2800,31 +2796,6 @@ void fastRamReset() {
 }
 
 
-/////////////////
-// GBAMP
-/////////////////
-
-bool GBAMPAvail = false;
-
-bool initGBAMP(int mode) {
-	if (FAT_InitFiles()) {
-		if (mode == 2)	{
-			disc_IsInserted();
-		}
-		GBAMPAvail = true;
-//		consolePrintf("Found flash card reader!\n");
-		return true;
-	} else {
-		GBAMPAvail = false;
-//		consolePrintf("Flash card reader not found!\n");
-		return false;
-	}
-}
-
-bool isGBAMPAvailable() {
-	return GBAMPAvail;
-}
-
 
 #ifdef USE_DEBUGGER
 void initDebugger() {
@@ -3080,91 +3051,11 @@ int main(void) {
 #endif
 
 
-#ifdef USE_BUILT_IN_DRIVER_SELECTION
-	// Do M3 detection selectioon
-	int extraData = DSSaveFileManager::getExtraData();
-	bool present = DSSaveFileManager::isExtraDataPresent();
-
-	for (int r = 0; r < 30; r++) {
-		swiWaitForVBlank();
-	}
-
-	int mode = extraData & 0x03;
-
-	if (mode == 0) {
-		if ((keysHeld() & KEY_L) && !(keysHeld() & KEY_R)) {
-			mode = 1;
-		} else if (!(keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
-			mode = 2;
-		}
-	} else {
-		if ((keysHeld() & KEY_L) && !(keysHeld() & KEY_R)) {
-			mode = 0;
-		}
-	}
-
-
-	if (mode == 0) {
-		consolePrintf("On startup hold L if you have\n");
-		consolePrintf("an M3 SD or R for an SC SD\n");
-	} else if (mode == 1) {
-		consolePrintf("Using M3 SD Mode.\n");
-		consolePrintf("Hold L on startup to disable.\n");
-	} else if (mode == 2) {
-		consolePrintf("Using SC SD Mode.\n");
-		consolePrintf("Hold L on startup to disable.\n");
-	}
-
-	disc_setEnable(mode);
-	DSSaveFileManager::setExtraData(mode);
-#else
-
-	int mode = 0;
-
-#endif
-
-
-/*
-	if ((present) && (extraData & 0x00000001)) {
-
-		if (keysHeld() & KEY_L) {
-			extraData &= ~0x00000001;
-			consolePrintf("M3 SD Detection: OFF\n");
-			DSSaveFileManager::setExtraData(extraData);
-		} else {
-			consolePrintf("M3 SD Detection: ON\n");
-			consolePrintf("Hold L on startup to disable.\n");
-		}
-
-	} else if (keysHeld() & KEY_L) {
-		consolePrintf("M3 SD Detection: ON\n");
-		extraData |= 0x00000001;
-		DSSaveFileManager::setExtraData(extraData);
-	} else {
-		consolePrintf("M3 SD Detection: OFF\n");
-		consolePrintf("Hold L on startup to enable.\n");
+	if (!nitroFSInit(NULL)) {
+		consolePrintf("nitroFSInit failure: terminating\n");
+		return(1);
 	}
 
-	disc_setM3SDEnable(extraData & 0x00000001);
-*/
-	// Create a file system node to force search for a zip file in GBA rom space
-
-	DSFileSystemNode *node = new DSFileSystemNode();
-	if (!node->getZip() || (!node->getZip()->isReady())) {
-		// If not found, init CF/SD driver
-		initGBAMP(mode);
-
-		if (!initGBAMP(mode)) {
-			consolePrintf("\nNo file system was found.\n");
-			consolePrintf("View the readme file\n");
-			consolePrintf("for more information.\n");
-
-			while (1);
-		}
-	}
-	delete node;
-
-
 
 	updateStatus();
 
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index b413c70763..151b88d671 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -117,9 +117,6 @@ void 	setShakePos(int shakeXOffset, int shakeYOffset);
 // Reports
 void 	memoryReport();
 
-// GBAMP
-bool 	isGBAMPAvailable();
-
 // Sleep (I'd like some of that right now)
 void 	checkSleepMode();
 
diff --git a/backends/platform/ds/arm9/source/fat/disc_io.c b/backends/platform/ds/arm9/source/fat/disc_io.c
deleted file mode 100644
index 74fc8fb09b..0000000000
--- a/backends/platform/ds/arm9/source/fat/disc_io.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
-
-	disc_io.c
-
-	uniformed io-interface to work with Chishm's FAT library
-
-	Written by MightyMax
-
-	Modified by Chishm:
-	2005-11-06
-		* Added WAIT_CR modifications for NDS
-
-	Modified by www.neoflash.com:
-	2006-02-03
-		* Added SUPPORT_* defines, comment out any of the SUPPORT_* defines in disc_io.h to remove support
-		  for the given interface and stop code being linked to the binary
-
-	    * Added support for MK2 MMC interface
-
-		* Added disc_Cache* functions
-
-	Modified by Chishm:
-	2006-02-05
-		* Added Supercard SD support
-
-	Modified by CyteX:
-	2006-02-26
-		* Added EFA2 support
-*/
-
-#ifdef NDS
-	#include <nds.h>
-#endif
-
-#include "disc_io.h"
-
-
-// Include known io-interfaces:
-#ifdef SUPPORT_MPCF
- #include "io_mpcf.h"
-#endif
-
-#ifdef SUPPORT_M3CF
- #include "io_m3cf.h"
-#endif
-
-#ifdef SUPPORT_M3SD
- #include "io_m3sd.h"
-#endif
-
-#ifdef SUPPORT_SCCF
- #include "io_sccf.h"
-#endif
-
-#ifdef SUPPORT_SCSD
- #include "io_scsd.h"
-#endif
-
-#ifdef SUPPORT_FCSR
- #include "io_fcsr.h"
-#endif
-
-#ifdef SUPPORT_NMMC
- #include "io_nmmc.h"
-#endif
-
-#ifdef SUPPORT_EFA2
- #include "io_efa2.h"
-#endif
-
-#ifdef SUPPORT_NJSD
- #include "io_njsd.h"
-#endif
-
-#ifdef SUPPORT_MMCF
- #include "io_mmcf.h"
-#endif
-
-#include "io_dldi.h"
-
-// Keep a pointer to the active interface
-LPIO_INTERFACE active_interface = 0;
-
-
-/*
-
-	Disc Cache functions
-	2006-02-03:
-		Added by www.neoflash.com
-
-*/
-int discDetect = 0;
-
-int dldiFound = FALSE;
-
-#ifdef DISC_CACHE
-
-#include <string.h>
-
-#define CACHE_FREE 0xFFFFFFFF
-
-static u8 cacheBuffer[ DISC_CACHE_COUNT * 512 ];
-
-static struct {
-	u32 sector;
-	u32 dirty;
-	u32 count;
-} cache[ DISC_CACHE_COUNT ];
-
-FATDevice currentDevice;
-
-static u32 disc_CacheFind(u32 sector) {
-	u32 i;
-
-	for( i = 0; i < DISC_CACHE_COUNT; i++ )	{
-		if( cache[ i ].sector == sector )
-			return i;
-	}
-
-	return CACHE_FREE;
-}
-
-static u32 disc_CacheFindFree(void) {
-
-	u32 i = 0, j;
-	u32 count = -1;
-
-	for( j = 0; j < DISC_CACHE_COUNT; j++ )	{
-
-		if( cache[ j ].sector == CACHE_FREE ) {
-			i = j;
-			break;
-		}
-
-		if( cache[ j ].count < count ) {
-			count = cache[ j ].count;
-			i = j;
-		}
-	}
-	/*
-	if( cache[ i ].sector != CACHE_FREE && cache[i].dirty != 0 ) {
-
-		active_interface->fn_WriteSectors( cache[ i ].sector, 1, &cacheBuffer[ i * 512 ] );
-		// todo: handle write error here
-
-		cache[ i ].sector = CACHE_FREE;
-		cache[ i ].dirty = 0;
-		cache[ i ].count = 0;
-	}*/
-
-	return i;
-}
-
-void disc_CacheInit(void)	{
-
-	u32 i;
-
-	for( i = 0; i < DISC_CACHE_COUNT; i++ )	{
-		cache[ i ].sector = CACHE_FREE;
-		cache[ i ].dirty = 0;
-		cache[ i ].count = 0;
-	}
-
-}
-
-bool disc_CacheFlush(void)	{
-
-	u32 i;
-
-	if( !active_interface )	return false;
-
-	for( i = 0; i < DISC_CACHE_COUNT; i++ )	{
-		if( cache[ i ].sector != CACHE_FREE && cache[ i ].dirty != 0 )	{
-			if( active_interface->fn_WriteSectors( cache[ i ].sector, 1, &cacheBuffer[ i * 512 ] ) == false )
-				return false;
-
-			cache[ i ].dirty = 0;
-		}
-	}
-	return true;
-}
-
-bool disc_CacheReadSector( void *buffer, u32 sector) {
-	u32 i = disc_CacheFind( sector );
-	if( i == CACHE_FREE ) {
-		i = disc_CacheFindFree();
-		cache[ i ].sector = sector;
-		if( active_interface->fn_ReadSectors( sector, 1, &cacheBuffer[ i * 512 ] ) == false )
-			return false;
-	}
-#ifdef DISK_CACHE_DMA
-		DMA3_SRC = (u32)&cacheBuffer[ i * 512 ]
-		DMA3_DEST = (u32)buffer;
-		DMA3_CR = 128 | DMA_COPY_WORDS;
-#else
-	memcpy( buffer, &cacheBuffer[ i * 512 ], 512 );
-#endif
-	cache[ i ].count++;
-	return true;
-}
-
-bool disc_CacheWriteSector( void *buffer, u32 sector ) {
-	u32 i = disc_CacheFind( sector );
-	if( i == CACHE_FREE ) {
-		i = disc_CacheFindFree();
-		cache [ i ].sector = sector;
-	}
-#ifdef DISK_CACHE_DMA
-		DMA3_SRC = (u32)buffer;
-		DMA3_DEST = (u32)&cacheBuffer[ i * 512 ];
-		DMA3_CR = 128 | DMA_COPY_WORDS;
-#else
-	memcpy( &cacheBuffer[ i * 512 ], buffer, 512 );
-#endif
-	cache[ i ].dirty=1;
-	cache[ i ].count++;
-	return true;
-}
-
-#endif
-
-/*
-
-	Hardware level disc funtions
-
-*/
-
-void disc_setEnable(int disc) {
-	discDetect = disc;
-}
-
-bool disc_setGbaSlotInterface (void)
-{
-	// If running on an NDS, make sure the correct CPU can access
-	// the GBA cart. First implemented by SaTa.
-#ifdef NDS
- #ifdef ARM9
-//	WAIT_CR &= ~(0x8080);
- #endif
- #ifdef ARM7
-//	WAIT_CR |= (0x8080);
- #endif
-#endif
-
-
-#ifdef SUPPORT_M3SD
-	if (discDetect == 1)	{
-		// check if we have a M3 perfect SD plugged in
-		active_interface = M3SD_GetInterface() ;
-		if (active_interface->fn_StartUp())
-		{
-			// set M3 SD as default IO
-			currentDevice = DEVICE_M3SD;
-			return true ;
-		} ;
-	}
-#endif
-
-
-
-
-#ifdef SUPPORT_MMCF
-	// check if we have a GBA Flash Cart plugged in
-	active_interface = MMCF_GetInterface() ;
-	if (active_interface->fn_StartUp())
-	{
-		// set MMCF as default IO
-		currentDevice = DEVICE_MMCF;
-		return true ;
-	} ;
-#endif
-
-
-
-#ifdef SUPPORT_M3CF
-	// check if we have a M3 perfect CF plugged in
-	active_interface = M3CF_GetInterface() ;
-	if (active_interface->fn_StartUp())
-	{
-		// set M3 CF as default IO
-		currentDevice = DEVICE_M3CF;
-		return true ;
-	} ;
-#endif
-
-
-#ifdef SUPPORT_MPCF
-	// check if we have a GBA Movie Player plugged in
-	active_interface = MPCF_GetInterface() ;
-	if (active_interface->fn_StartUp())
-	{
-		// set GBAMP as default IO
-		currentDevice = DEVICE_MPCF;
-		return true ;
-	} ;
-#endif
-
-
-#ifdef SUPPORT_SCCF
-	// check if we have a SuperCard CF plugged in
-	active_interface = SCCF_GetInterface() ;
-	if (active_interface->fn_StartUp())
-	{
-		// set SC CF as default IO
-		currentDevice = DEVICE_SCCF;
-		return true ;
-	} ;
-#endif
-
-
-
-#ifdef SUPPORT_EFA2
-	// check if we have a EFA2 plugged in
-	active_interface = EFA2_GetInterface() ;
-	if (active_interface->fn_StartUp())
-	{
-		return true ;
-	} ;
-#endif
-
-
-#ifdef SUPPORT_FCSR
-	// check if we have a GBA Flash Cart plugged in
-	active_interface = FCSR_GetInterface() ;
-	if (active_interface->fn_StartUp())
-	{
-		// set FC as default IO
-		return true ;
-	} ;
-#endif
-
-
-
-
-	return false;
-}
-
-
-FATDevice disc_getDeviceId() {
-	return currentDevice;
-}
-
-void disc_getDldiId(char* id) {
-	char* driverId = (char *) &_io_dldi;
-	id[0] = driverId[0];
-	id[1] = driverId[1];
-	id[2] = driverId[2];
-	id[3] = driverId[3];
-	id[4] = '\0';
-}
-
-#ifdef NDS
-// Check the DS card slot for a valid memory card interface
-// If an interface is found, it is set as the default interace
-// and it returns true. Otherwise the default interface is left
-// untouched and it returns false.
-
-
-bool disc_setDsSlotInterface (void)
-{
-#ifdef ARM9
-	REG_EXEMEMCNT &= ~(1<<11);
-#endif
-#ifdef ARM7
-	REG_EXEMEMCNT |= (1<<11);
-#endif
-
-	active_interface = DLDI_GetInterface();
-
-	if (strcasecmp((char *)(&_dldi_driver_name), "Default (No interface)")) {
-		char name[48];
-		memcpy(name, &_dldi_driver_name, 48);
-		name[47] = '\0';
-		consolePrintf("DLDI Device:\n'%s'\n", name);
-		dldiFound = TRUE;
-	} else {
-		consolePrintf("DLDI Driver not patched!\n");
-		dldiFound = FALSE;
-	}
-
-	if (active_interface->fn_StartUp()) {
-		consolePrintf("DLDI Driver Initialised OK!\n");
-		currentDevice = DEVICE_DLDI;
-		return true;
-	} else {
-		consolePrintf("DLDI Initialise failed.\n");
-	}
-
-#ifdef SUPPORT_SCSD
-	// check if we have a SuperCard SD plugged in
-	if (discDetect == 2) {
-		active_interface = SCSD_GetInterface() ;
-		consolePrintf("SCSD!");
-		if (active_interface->fn_StartUp())
-		{
-			// set SC SD as default IO
-			currentDevice = DEVICE_SCSD;
-			return true ;
-		} ;
-	}
-#endif
-
-#ifdef SUPPORT_NJSD
-	// check if we have a GBA Flash Cart plugged in
-	active_interface = NJSD_GetInterface() ;
-	if (active_interface->fn_StartUp())
-	{
-		// set NJSD as default IO
-		currentDevice = DEVICE_NJSD;
-		return true ;
-	} ;
-#endif
-
-#ifdef SUPPORT_NMMC
-	// check if we have a Neoflash MK2 / MK3 plugged in
-	active_interface = NMMC_GetInterface() ;
-	if (active_interface->fn_StartUp())
-	{
-		// set Neoflash MK2 / MK3 as default IO
-		currentDevice = DEVICE_NMMC;
-		return true ;
-	} ;
-#endif
-
-
-
-
-	return false;
-}
-#endif
-
-
-bool disc_Init(void)
-{
-#ifdef DISC_CACHE
-	disc_CacheInit();
-#endif
-
-
-	if (active_interface != 0) {
-		return true;
-	}
-
-#ifdef NDS
-	if (disc_setDsSlotInterface()) {
-		return true;
-	}
-#endif
-
-	if (disc_setGbaSlotInterface()) {
-		return true;
-	}
-
-	// could not find a working IO Interface
-	active_interface = 0 ;
-	return false ;
-}
-
-bool disc_IsInserted(void)
-{
-	if (active_interface) return active_interface->fn_IsInserted() ;
-	return false ;
-}
-
-bool disc_ReadSectors(u32 sector, u8 numSecs, void* buffer)
-{
-#ifdef DISC_CACHE
-	u8 *p=(u8*)buffer;
-	u32 i;
-	u32 inumSecs=numSecs;
-	if(numSecs==0)
-		inumSecs=256;
-	for( i = 0; i<inumSecs; i++)	{
-		if( disc_CacheReadSector( &p[i*512], sector + i ) == false )
-			return false;
-	}
-	return true;
-#else
-	if (active_interface) return active_interface->fn_ReadSectors(sector,numSecs,buffer) ;
-	return false ;
-#endif
-}
-
-bool disc_WriteSectors(u32 sector, u8 numSecs, void* buffer)
-{
-/*#ifdef DISC_CACHE
-	u8 *p=(u8*)buffer;
-	u32 i;
-	u32 inumSecs=numSecs;
-	if(numSecs==0)
-		inumSecs=256;
-	for( i = 0; i<inumSecs; i++)	{
-		if( disc_CacheWriteSector( &p[i*512], sector + i ) == false )
-			return false;
-	}
-	return true;
-#else*/
-#ifdef DISC_CACHE
-	disc_CacheInit();
-#endif
-
-#define MISALIGNMENT_BODGE
-
-#ifdef MISALIGNMENT_BODGE
-	// This bodge works around problems with some card reader drivers which require data to be
-	// aligned to 2- or 4-byte boundaries it varies which one they require.  This bodge sorts
-	// it but also reduces write speed as it doesn't use the multi-sector write capability any
-	// more.  A better fix will be written for a future version.
-
-	if (active_interface) {
-		u8 sectorBuffer[512];
-		int r;
-
-		for (r = 0; r < numSecs; r++) {
-			memcpy(sectorBuffer, &((char *)buffer)[r * 512], 512);
-
-			if (!active_interface->fn_WriteSectors(sector + r, 1, sectorBuffer))
-			{
-				return false;
-			}
-		}
-
-
-		return true;
-	}
-
-#else
-	if (active_interface) return active_interface->fn_WriteSectors(sector,numSecs,buffer) ;
-#endif
-//#endif
-	return false ;
-}
-
-bool disc_ClearStatus(void)
-{
-	if (active_interface) return active_interface->fn_ClearStatus() ;
-	return false ;
-}
-
-bool disc_Shutdown(void)
-{
-#ifdef DISC_CACHE
-	disc_CacheFlush();
-#endif
-	if (active_interface) active_interface->fn_Shutdown() ;
-	active_interface = 0 ;
-	return true ;
-}
-
-u32	disc_HostType (void)
-{
-	if (active_interface) {
-		return active_interface->ul_ioType;
-	} else {
-		return 0;
-	}
-}
diff --git a/backends/platform/ds/arm9/source/fat/disc_io.h b/backends/platform/ds/arm9/source/fat/disc_io.h
deleted file mode 100644
index cd930ba454..0000000000
--- a/backends/platform/ds/arm9/source/fat/disc_io.h
+++ /dev/null
@@ -1,220 +0,0 @@
-#ifndef DISC_IO_H
-#define DISC_IO_H
-
-//----------------------------------------------------------------------
-// Customisable features
-
-// Use DMA to read the card, remove this line to use normal reads/writes
-// #define _CF_USE_DMA
-
-// Allow buffers not aligned to 16 bits when reading files.
-// Note that this will slow down access speed, so only use if you have to.
-// It is also incompatible with DMA
-#define _CF_ALLOW_UNALIGNED
-#define _IO_ALLOW_UNALIGNED
-
-// Device support options, added by www.neoflash.com
-
-//#define SUPPORT_MPCF		// comment out this line to remove GBA Movie Player support
-//#define SUPPORT_M3CF		// comment out this line to remove M3 Perfect CF support
-//#define SUPPORT_M3SD		// comment out this line to remove M3 Perfect SD support
-//#define SUPPORT_SCCF		// comment out this line to remove Supercard CF support
-//#define SUPPORT_SCSD		// comment out this line to remove Supercard SD support
-//#define SUPPORT_NJSD
-//#define SUPPORT_MMCF
-
-//#define SUPPORT_EFA2		// comment out this line to remove EFA2 linker support
-//#define SUPPORT_FCSR		// comment out this line to remove GBA Flash Cart support
-//#define SUPPORT_NMMC		// comment out this line to remove Neoflash MK2 MMC Card support
-
-
-// Disk caching options, added by www.neoflash.com
-// Each additional sector cache uses 512 bytes of memory
-// Disk caching is disabled on GBA to conserve memory
-
-#define DISC_CACHE				// uncomment this line to enable disc caching
-#ifdef DS_BUILD_F
-#define DISC_CACHE_COUNT	128	// maximum number of sectors to cache (512 bytes per sector)
-#else
-#define DISC_CACHE_COUNT	32	// maximum number of sectors to cache (512 bytes per sector)
-#endif
-//#define DISK_CACHE_DMA		// use DMA for cache copies. If this is enabled, the data buffers must be word aligned
-
-
-// This allows the code to build on an earlier version of libnds, before the register was renamed
-#ifndef REG_EXMEMCNT
-#define REG_EXMEMCNT REG_EXEMEMCNT
-#endif
-
-#ifndef REG_EXEMEMCNT
-#define REG_EXEMEMCNT REG_EXMEMCNT
-#endif
-
-//----------------------------------------------------------------------
-
-#if defined _CF_USE_DMA && defined _CF_ALLOW_UNALIGNED
- #error You can not use both DMA and unaligned memory
-#endif
-
-// When compiling for NDS, make sure NDS is defined
-#ifndef NDS
- #if defined ARM9 || defined ARM7
-  #define NDS
- #endif
-#endif
-
-#ifdef NDS
- #include <nds/ndstypes.h>
-#else
- #include "gba_types.h"
-#endif
-
-// Disable NDS specific hardware and features if running on a GBA
-#ifndef NDS
- #undef SUPPORT_NMMC
- #undef DISC_CACHE
-#endif
-
-/*
-
-	Interface for host program
-
-*/
-
-#define BYTE_PER_READ 512
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef enum {
-	DEVICE_NONE = 0,
-	DEVICE_M3SD,
-	DEVICE_MMCF,
-	DEVICE_M3CF,
-	DEVICE_MPCF,
-	DEVICE_SCCF,
-	DEVICE_NJSD,
-	DEVICE_SCSD,
-	DEVICE_NMMC,
-	DEVICE_DLDI
-} FATDevice;
-
-/*-----------------------------------------------------------------
-disc_Init
-Detects the inserted hardware and initialises it if necessary
-bool return OUT:  true if a suitable device was found
------------------------------------------------------------------*/
-extern bool disc_Init(void) ;
-
-/*-----------------------------------------------------------------
-disc_IsInserted
-Is a usable disc inserted?
-bool return OUT:  true if a disc is inserted
------------------------------------------------------------------*/
-extern bool disc_IsInserted(void) ;
-
-
-extern void disc_setEnable(int en);
-extern FATDevice disc_getDeviceId();
-void disc_getDldiId(char* id);
-
-/*-----------------------------------------------------------------
-disc_ReadSectors
-Read 512 byte sector numbered "sector" into "buffer"
-u32 sector IN: address of first 512 byte sector on disc to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer OUT: pointer to 512 byte buffer to store data in
-bool return OUT: true if successful
------------------------------------------------------------------*/
-extern bool disc_ReadSectors(u32 sector, u8 numSecs, void* buffer) ;
-#define disc_ReadSector(sector,buffer)	disc_ReadSectors(sector,1,buffer)
-
-/*-----------------------------------------------------------------
-disc_WriteSectors
-Write 512 byte sector numbered "sector" from "buffer"
-u32 sector IN: address of 512 byte sector on disc to write
-u8 numSecs IN: number of 512 byte sectors to write	,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer IN: pointer to 512 byte buffer to read data from
-bool return OUT: true if successful
------------------------------------------------------------------*/
-extern bool disc_WriteSectors(u32 sector, u8 numSecs, void* buffer) ;
-#define disc_WriteSector(sector,buffer)	disc_WriteSectors(sector,1,buffer)
-
-/*-----------------------------------------------------------------
-disc_ClearStatus
-Tries to make the disc go back to idle mode
-bool return OUT:  true if the disc is idle
------------------------------------------------------------------*/
-extern bool disc_ClearStatus(void) ;
-
-/*-----------------------------------------------------------------
-disc_Shutdown
-unload the disc interface
-bool return OUT: true if successful
------------------------------------------------------------------*/
-extern bool disc_Shutdown(void) ;
-
-/*-----------------------------------------------------------------
-disc_HostType
-Returns a unique u32 number identifying the host type
-u32 return OUT: 0 if no host initialised, else the identifier of
-	the host
------------------------------------------------------------------*/
-extern u32 disc_HostType(void);
-
-/*-----------------------------------------------------------------
-disc_CacheFlush
-Flushes any cache writes to disc
-bool return OUT: true if successful, false if an error occurs
-Added by www.neoflash.com
------------------------------------------------------------------*/
-#ifdef DISC_CACHE
-extern bool disc_CacheFlush(void);
-#else
-static inline bool disc_CacheFlush(void)
-{
-	return true;
-}
-#endif // DISC_CACHE
-
-
-/*
-
-	Interface for IO libs
-
-*/
-
-#define FEATURE_MEDIUM_CANREAD		0x00000001
-#define FEATURE_MEDIUM_CANWRITE		0x00000002
-#define FEATURE_SLOT_GBA			0x00000010
-#define FEATURE_SLOT_NDS			0x00000020
-
-
-typedef bool (* FN_MEDIUM_STARTUP)(void) ;
-typedef bool (* FN_MEDIUM_ISINSERTED)(void) ;
-typedef bool (* FN_MEDIUM_READSECTORS)(u32 sector, u8 numSecs, void* buffer) ;
-typedef bool (* FN_MEDIUM_WRITESECTORS)(u32 sector, u8 numSecs, void* buffer) ;
-typedef bool (* FN_MEDIUM_CLEARSTATUS)(void) ;
-typedef bool (* FN_MEDIUM_SHUTDOWN)(void) ;
-
-
-typedef struct {
-	unsigned long			ul_ioType ;
-	unsigned long			ul_Features ;
-	FN_MEDIUM_STARTUP		fn_StartUp ;
-	FN_MEDIUM_ISINSERTED	fn_IsInserted ;
-	FN_MEDIUM_READSECTORS	fn_ReadSectors ;
-	FN_MEDIUM_WRITESECTORS	fn_WriteSectors ;
-	FN_MEDIUM_CLEARSTATUS	fn_ClearStatus ;
-	FN_MEDIUM_SHUTDOWN		fn_Shutdown ;
-} IO_INTERFACE, *LPIO_INTERFACE ;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif	// define DISC_IO_H
diff --git a/backends/platform/ds/arm9/source/fat/gba_nds_fat.c b/backends/platform/ds/arm9/source/fat/gba_nds_fat.c
deleted file mode 100644
index ddae087c94..0000000000
--- a/backends/platform/ds/arm9/source/fat/gba_nds_fat.c
+++ /dev/null
@@ -1,3345 +0,0 @@
-/*
-	gba_nds_fat.c
-	By chishm (Michael Chisholm)
-
-	Routines for reading a compact flash card
-	using the GBA Movie Player or M3.
-
-	Some FAT routines are based on those in fat.c, which
-	is part of avrlib by Pascal Stang.
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-//---------------------------------------------------------------
-// Includes
-
-// Allow use of stuff in <time.h>
-#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
-
-#include "gba_nds_fat.h"
-#include "disc_io.h"
-#include <string.h>
-#ifdef NDS
-// #include <nds/ipc.h>	// Time on the NDS
- #include <NDS/scummvm_ipc.h>
-#endif
-//----------------------------------------------------------------
-// Data	types
-#ifndef	NULL
- #define	NULL	0
-#endif
-
-//----------------------------------------------------------------
-// NDS memory access control register
-#ifdef NDS
- #ifndef WAIT_CR
-  #define WAIT_CR (*(vu16*)0x04000204)
- #endif
-#endif
-
-//---------------------------------------------------------------
-// Appropriate placement of CF functions and data
-#ifdef NDS
- #define _VARS_IN_RAM
-#else
- #define _VARS_IN_RAM __attribute__ ((section (".sbss")))
-#endif
-
-
-//-----------------------------------------------------------------
-// FAT constants
-#define CLUSTER_EOF_16	0xFFFF
-#define	CLUSTER_EOF	0x0FFFFFFF
-#define CLUSTER_FREE	0x0000
-#define CLUSTER_FIRST	0x0002
-
-#define FILE_LAST 0x00
-#define FILE_FREE 0xE5
-
-#define FAT16_ROOT_DIR_CLUSTER 0x00
-
-
-//-----------------------------------------------------------------
-// long file name constants
-#define LFN_END 0x40
-#define LFN_DEL 0x80
-
-//-----------------------------------------------------------------
-// Data Structures
-
-// Take care of packing for GCC - it doesn't obey pragma pack()
-// properly for ARM targets.
-#ifdef __GNUC__
- #define __PACKED __attribute__ ((__packed__))
-#else
- #define __PACKED
- #pragma pack(1)
-#endif
-
-// Boot Sector - must be packed
-typedef struct
-{
-	u8	jmpBoot[3];
-	u8	OEMName[8];
-	// BIOS Parameter Block
-	u16	bytesPerSector;
-	u8	sectorsPerCluster;
-	u16	reservedSectors;
-	u8	numFATs;
-	u16	rootEntries;
-	u16	numSectorsSmall;
-	u8	mediaDesc;
-	u16	sectorsPerFAT;
-	u16	sectorsPerTrk;
-	u16	numHeads;
-	u32	numHiddenSectors;
-	u32	numSectors;
-	union	// Different types of extended BIOS Parameter Block for FAT16 and FAT32
-	{
-		struct
-		{
-			// Ext BIOS Parameter Block for FAT16
-			u8	driveNumber;
-			u8	reserved1;
-			u8	extBootSig;
-			u32	volumeID;
-			u8	volumeLabel[11];
-			u8	fileSysType[8];
-			// Bootcode
-			u8	bootCode[448];
-		}	__PACKED fat16;
-		struct
-		{
-			// FAT32 extended block
-			u32	sectorsPerFAT32;
-			u16	extFlags;
-			u16	fsVer;
-			u32	rootClus;
-			u16	fsInfo;
-			u16	bkBootSec;
-			u8	reserved[12];
-			// Ext BIOS Parameter Block for FAT16
-			u8	driveNumber;
-			u8	reserved1;
-			u8	extBootSig;
-			u32	volumeID;
-			u8	volumeLabel[11];
-			u8	fileSysType[8];
-			// Bootcode
-			u8	bootCode[420];
-		}	__PACKED fat32;
-	}	__PACKED extBlock;
-
-	u16	bootSig;
-
-}	__PACKED BOOT_SEC;
-
-// Directory entry - must be packed
-typedef struct
-{
-	u8	name[8];
-	u8	ext[3];
-	u8	attrib;
-	u8	reserved;
-	u8	cTime_ms;
-	u16	cTime;
-	u16	cDate;
-	u16	aDate;
-	u16	startClusterHigh;
-	u16	mTime;
-	u16	mDate;
-	u16	startCluster;
-	u32	fileSize;
-}	__PACKED DIR_ENT;
-
-// Long file name directory entry - must be packed
-typedef struct
-{
-	u8 ordinal;	// Position within LFN
-	u16 char0;
-	u16 char1;
-	u16 char2;
-	u16 char3;
-	u16 char4;
-	u8 flag;	// Should be equal to ATTRIB_LFN
-	u8 reserved1;	// Always 0x00
-	u8 checkSum;	// Checksum of short file name (alias)
-	u16 char5;
-	u16 char6;
-	u16 char7;
-	u16 char8;
-	u16 char9;
-	u16 char10;
-	u16 reserved2;	// Always 0x0000
-	u16 char11;
-	u16 char12;
-}	__PACKED DIR_ENT_LFN;
-
-const char lfn_offset_table[13]={0x01,0x03,0x05,0x07,0x09,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E};
-
-// End of packed structs
-#ifdef __PACKED
- #undef __PACKED
-#endif
-#ifndef __GNUC__
- #pragma pack()
-#endif
-
-//-----------------------------------------------------------------
-// Global Variables
-
-// _VARS_IN_RAM variables are stored in the largest section of WRAM
-// available: IWRAM on NDS ARM7, EWRAM on NDS ARM9 and GBA
-
-// Files
-FAT_FILE openFiles[MAX_FILES_OPEN] __attribute__((section(".itcm")));
-//_VARS_IN_RAM
-
-// Long File names
-_VARS_IN_RAM char lfnName[MAX_FILENAME_LENGTH];
-bool lfnExists;
-
-// Locations on card
-int filesysRootDir;
-int filesysRootDirClus;
-int filesysFAT;
-int filesysSecPerFAT;
-int filesysNumSec;
-int filesysData;
-int filesysBytePerSec;
-int filesysSecPerClus;
-int filesysBytePerClus;
-
-FS_TYPE filesysType = FS_UNKNOWN;
-u32 filesysTotalSize;
-
-// Info about FAT
-u32 fatLastCluster;
-u32 fatFirstFree;
-
-// fatBuffer used to reduce wear on the CF card from multiple writes
-_VARS_IN_RAM char fatBuffer[BYTE_PER_READ];
-u32 fatBufferCurSector;
-
-// Current working directory
-u32 curWorkDirCluster;
-
-// Position of the directory entry last retreived with FAT_GetDirEntry
-u32 wrkDirCluster;
-int wrkDirSector;
-int wrkDirOffset;
-
-// Global sector buffer to save on stack space
-_VARS_IN_RAM unsigned char globalBuffer[BYTE_PER_READ];
-
-//-----------------------------------------------------------------
-// Functions contained in this file - predeclarations
-char ucase (char character);
-u16 getRTCtoFileTime (void);
-u16 getRTCtoFileDate (void);
-
-bool FAT_AddDirEntry (const char* path, DIR_ENT newDirEntry);
-bool FAT_ClearLinks (u32 cluster);
-DIR_ENT FAT_DirEntFromPath (const char* path);
-u32 FAT_FirstFreeCluster(void);
-DIR_ENT FAT_GetDirEntry ( u32 dirCluster, int entry, int origin);
-u32 FAT_LinkFreeCluster(u32 cluster);
-u32 FAT_NextCluster(u32 cluster);
-bool FAT_WriteFatEntry (u32 cluster, u32 value);
-bool FAT_GetFilename (DIR_ENT dirEntry, char* alias);
-
-bool FAT_InitFiles (void);
-bool FAT_FreeFiles (void);
-int FAT_remove (const char* path);
-bool FAT_chdir (const char* path);
-FILE_TYPE FAT_FindFirstFile (char* filename);
-FILE_TYPE FAT_FindNextFile (char* filename);
-FILE_TYPE FAT_FileExists (const char* filename);
-bool FAT_GetAlias (char* alias);
-bool FAT_GetLongFilename (char* filename);
-u32 FAT_GetFileSize (void);
-u32 FAT_GetFileCluster (void);
-
-FAT_FILE* FAT_fopen(const char* path, const char* mode);
-bool FAT_fclose (FAT_FILE* file);
-bool FAT_feof(FAT_FILE* file);
-int FAT_fseek(FAT_FILE* file, s32 offset, int origin);
-u32 FAT_ftell (FAT_FILE* file);
-u32 FAT_fread (void* buffer, u32 size, u32 count, FAT_FILE* file);
-u32 FAT_fwrite (const void* buffer, u32 size, u32 count, FAT_FILE* file);
-char FAT_fgetc (FAT_FILE* file);
-char FAT_fputc (char c, FAT_FILE* file);
-
-/*-----------------------------------------------------------------
-ucase
-Returns the uppercase version of the given char
-char IN: a character
-char return OUT: uppercase version of character
------------------------------------------------------------------*/
-char ucase (char character)
-{
-	if ((character > 0x60) && (character < 0x7B))
-		character = character - 0x20;
-	return (character);
-}
-
-
-/*-----------------------------------------------------------------
-getRTCtoFileTime and getRTCtoFileDate
-Returns the time / date in Dir Entry styled format
-u16 return OUT: time / date in Dir Entry styled format
------------------------------------------------------------------*/
-u16 getRTCtoFileTime (void)
-{
-#ifdef NDS
-	return (
-		( ( (IPC->rtc.hours > 11 ? IPC->rtc.hours - 40 : IPC->rtc.hours) & 0x1F) << 11) |
-		( (IPC->rtc.minutes & 0x3F) << 5) |
-		( (IPC->rtc.seconds >> 1) & 0x1F) );
-#else
-	return 0;
-#endif
-}
-
-u16 getRTCtoFileDate (void)
-{
-#ifdef NDS
-	return (
-		( ((IPC->rtc.year + 20) & 0x7F) <<9) |
-		( (IPC->rtc.month & 0xF) << 5) |
-		(IPC->rtc.day & 0x1F) );
-#else
-	return 0;
-#endif
-}
-
-
-/*-----------------------------------------------------------------
-Disc level FAT routines
------------------------------------------------------------------*/
-#define FAT_ClustToSect(m) \
-	(((m-2) * filesysSecPerClus) + filesysData)
-
-/*-----------------------------------------------------------------
-FAT_NextCluster
-Internal function - gets the cluster linked from input cluster
------------------------------------------------------------------*/
-u32 FAT_NextCluster(u32 cluster)
-{
-	u32 nextCluster = CLUSTER_FREE;
-	u32 sector;
-	int offset;
-
-	switch (filesysType)
-	{
-		case FS_UNKNOWN:
-			nextCluster = CLUSTER_FREE;
-			break;
-
-		case FS_FAT12:
-			sector = filesysFAT + (((cluster * 3) / 2) / BYTE_PER_READ);
-			offset = ((cluster * 3) / 2) % BYTE_PER_READ;
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			nextCluster = ((u8*)fatBuffer)[offset];
-			offset++;
-
-			if (offset >= BYTE_PER_READ) {
-				offset = 0;
-				fatBufferCurSector++;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			nextCluster |= (((u8*)fatBuffer)[offset]) << 8;
-
-			if (cluster & 0x01) {
-				nextCluster = nextCluster >> 4;
-			} else 	{
-				nextCluster &= 0x0FFF;
-			}
-
-			if (nextCluster >= 0x0FF7)
-			{
-				nextCluster = CLUSTER_EOF;
-			}
-
-			break;
-
-		case FS_FAT16:
-			sector = filesysFAT + ((cluster << 1) / BYTE_PER_READ);
-			offset = cluster % (BYTE_PER_READ >> 1);
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			// read the nextCluster value
-			nextCluster = ((u16*)fatBuffer)[offset];
-
-			if (nextCluster >= 0xFFF7)
-			{
-				nextCluster = CLUSTER_EOF;
-			}
-			break;
-
-		case FS_FAT32:
-			sector = filesysFAT + ((cluster << 2) / BYTE_PER_READ);
-			offset = cluster % (BYTE_PER_READ >> 2);
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			// read the nextCluster value
-			nextCluster = (((u32*)fatBuffer)[offset]) & 0x0FFFFFFF;
-
-			if (nextCluster >= 0x0FFFFFF7)
-			{
-				nextCluster = CLUSTER_EOF;
-			}
-			break;
-
-		default:
-			nextCluster = CLUSTER_FREE;
-			break;
-	}
-
-	return nextCluster;
-}
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_WriteFatEntry
-Internal function - writes FAT information about a cluster
------------------------------------------------------------------*/
-bool FAT_WriteFatEntry (u32 cluster, u32 value)
-{
-	u32 sector;
-	int offset;
-
-	if ((cluster < 0x0002) || (cluster > fatLastCluster))
-	{
-		return false;
-	}
-
-	switch (filesysType)
-	{
-		case FS_UNKNOWN:
-			return false;
-			break;
-
-		case FS_FAT12:
-			sector = filesysFAT + (((cluster * 3) / 2) / BYTE_PER_READ);
-			offset = ((cluster * 3) / 2) % BYTE_PER_READ;
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			if (cluster & 0x01) {
-
-				((u8*)fatBuffer)[offset] = (((u8*)fatBuffer)[offset] & 0x0F) | ((value & 0x0F) << 4);
-
-				offset++;
-				if (offset >= BYTE_PER_READ) {
-					offset = 0;
-					// write the buffer back to disc
-					disc_WriteSector(fatBufferCurSector, fatBuffer);
-					// read the next sector
-					fatBufferCurSector++;
-					disc_ReadSector(fatBufferCurSector, fatBuffer);
-				}
-
-				((u8*)fatBuffer)[offset] =  (value & 0x0FF0) >> 4;
-
-			} else {
-
-				((u8*)fatBuffer)[offset] = value & 0xFF;
-
-				offset++;
-				if (offset >= BYTE_PER_READ) {
-					offset = 0;
-					// write the buffer back to disc
-					disc_WriteSector(fatBufferCurSector, fatBuffer);
-					// read the next sector
-					fatBufferCurSector++;
-					disc_ReadSector(fatBufferCurSector, fatBuffer);
-				}
-
-				((u8*)fatBuffer)[offset] = (((u8*)fatBuffer)[offset] & 0xF0) | ((value >> 8) & 0x0F);
-			}
-
-			break;
-
-		case FS_FAT16:
-			sector = filesysFAT + ((cluster << 1) / BYTE_PER_READ);
-			offset = cluster % (BYTE_PER_READ >> 1);
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			// write the value to the FAT buffer
-			((u16*)fatBuffer)[offset] = (value & 0xFFFF);
-
-			break;
-
-		case FS_FAT32:
-			sector = filesysFAT + ((cluster << 2) / BYTE_PER_READ);
-			offset = cluster % (BYTE_PER_READ >> 2);
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			// write the value to the FAT buffer
-			(((u32*)fatBuffer)[offset]) =  value;
-
-			break;
-
-		default:
-			return false;
-			break;
-	}
-
-	// write the buffer back to disc
-	disc_WriteSector(fatBufferCurSector, fatBuffer);
-
-	return true;
-}
-#endif
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_ReadWriteFatEntryBuffered
-Internal function - writes FAT information about a cluster to a
- buffer that should then be flushed to disc using
- FAT_WriteFatEntryFlushBuffer()
- Call FAT_WriteFatEntry first so as not to ruin the disc.
- Also returns the entry being replaced
------------------------------------------------------------------*/
-u32 FAT_ReadWriteFatEntryBuffered (u32 cluster, u32 value)
-{
-	u32 sector;
-	int offset;
-	u32 oldValue;
-
-	if ((cluster < 0x0002) || (cluster > fatLastCluster))
-		return CLUSTER_FREE;
-
-
-	switch (filesysType)
-	{
-		case FS_UNKNOWN:
-			oldValue = CLUSTER_FREE;
-			break;
-
-		case FS_FAT12:
-			sector = filesysFAT + (((cluster * 3) / 2) / BYTE_PER_READ);
-			offset = ((cluster * 3) / 2) % BYTE_PER_READ;
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// write the old buffer to disc
-				if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
-					disc_WriteSector(fatBufferCurSector, fatBuffer);
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			if (cluster & 0x01) {
-
-				oldValue = (((u8*)fatBuffer)[offset] & 0xF0) >> 4;
-				((u8*)fatBuffer)[offset] = (((u8*)fatBuffer)[offset] & 0x0F) | ((value & 0x0F) << 4);
-
-				offset++;
-				if (offset >= BYTE_PER_READ) {
-					offset = 0;
-					// write the buffer back to disc
-					disc_WriteSector(fatBufferCurSector, fatBuffer);
-					// read the next sector
-					fatBufferCurSector++;
-					disc_ReadSector(fatBufferCurSector, fatBuffer);
-				}
-
-				oldValue |= ((((u8*)fatBuffer)[offset]) << 4) & 0x0FF0;
-				((u8*)fatBuffer)[offset] =  (value & 0x0FF0) >> 4;
-
-			} else {
-
-				oldValue = ((u8*)fatBuffer)[offset] & 0xFF;
-				((u8*)fatBuffer)[offset] = value & 0xFF;
-
-				offset++;
-				if (offset >= BYTE_PER_READ) {
-					offset = 0;
-					// write the buffer back to disc
-					disc_WriteSector(fatBufferCurSector, fatBuffer);
-					// read the next sector
-					fatBufferCurSector++;
-					disc_ReadSector(fatBufferCurSector, fatBuffer);
-				}
-
-				oldValue |= (((u8*)fatBuffer)[offset] & 0x0F) << 8;
-				((u8*)fatBuffer)[offset] = (((u8*)fatBuffer)[offset] & 0xF0) | ((value >> 8) & 0x0F);
-			}
-
-			if (oldValue >= 0x0FF7)
-			{
-				oldValue = CLUSTER_EOF;
-			}
-
-			break;
-
-		case FS_FAT16:
-			sector = filesysFAT + ((cluster << 1) / BYTE_PER_READ);
-			offset = cluster % (BYTE_PER_READ >> 1);
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// write the old buffer to disc
-				if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
-					disc_WriteSector(fatBufferCurSector, fatBuffer);
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			// write the value to the FAT buffer
-			oldValue = ((u16*)fatBuffer)[offset];
-			((u16*)fatBuffer)[offset] = value;
-
-			if (oldValue >= 0xFFF7)
-			{
-				oldValue = CLUSTER_EOF;
-			}
-
-			break;
-
-		case FS_FAT32:
-			sector = filesysFAT + ((cluster << 2) / BYTE_PER_READ);
-			offset = cluster % (BYTE_PER_READ >> 2);
-
-			// If FAT buffer contains wrong sector
-			if (sector != fatBufferCurSector)
-			{
-				// write the old buffer to disc
-				if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
-					disc_WriteSector(fatBufferCurSector, fatBuffer);
-				// Load correct sector to buffer
-				fatBufferCurSector = sector;
-				disc_ReadSector(fatBufferCurSector, fatBuffer);
-			}
-
-			// write the value to the FAT buffer
-			oldValue = ((u32*)fatBuffer)[offset];
-			((u32*)fatBuffer)[offset] =  value;
-
-			if (oldValue >= 0x0FFFFFF7)
-			{
-				oldValue = CLUSTER_EOF;
-			}
-
-			break;
-
-		default:
-			oldValue = CLUSTER_FREE;
-			break;
-	}
-
-	return oldValue;
-}
-#endif
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_WriteFatEntryFlushBuffer
-Flush the FAT buffer back to the disc
------------------------------------------------------------------*/
-bool FAT_WriteFatEntryFlushBuffer (void)
-{
-	// write the buffer disc
-	if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
-	{
-		disc_WriteSector(fatBufferCurSector, fatBuffer);
-		return true;
-	} else {
-		return false;
-	}
-}
-#endif
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_FirstFreeCluster
-Internal function - gets the first available free cluster
------------------------------------------------------------------*/
-u32 FAT_FirstFreeCluster(void)
-{
-	// Start at first valid cluster
-	if (fatFirstFree < CLUSTER_FIRST)
-		fatFirstFree = CLUSTER_FIRST;
-
-	while ((FAT_NextCluster(fatFirstFree) != CLUSTER_FREE) && (fatFirstFree <= fatLastCluster))
-	{
-		fatFirstFree++;
-	}
-	if (fatFirstFree > fatLastCluster)
-	{
-		return CLUSTER_EOF;
-	}
-	return fatFirstFree;
-}
-#endif
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_LinkFreeCluster
-Internal function - gets the first available free cluster, sets it
-to end of file, links the input cluster to it then returns the
-cluster number
------------------------------------------------------------------*/
-u32 FAT_LinkFreeCluster(u32 cluster)
-{
-	u32 firstFree;
-	u32 curLink;
-
-	if (cluster > fatLastCluster)
-	{
-		return CLUSTER_FREE;
-	}
-
-	// Check if the cluster already has a link, and return it if so
-	curLink = FAT_NextCluster (cluster);
-	if ((curLink >= CLUSTER_FIRST) && (curLink < fatLastCluster))
-	{
-		return curLink;	// Return the current link - don't allocate a new one
-	}
-
-	// Get a free cluster
-	firstFree = FAT_FirstFreeCluster();
-
-	// If couldn't get a free cluster then return
-	if (firstFree == CLUSTER_EOF)
-	{
-		return CLUSTER_FREE;
-	}
-
-	if ((cluster >= CLUSTER_FIRST) && (cluster < fatLastCluster))
-	{
-		// Update the linked from FAT entry
-		FAT_WriteFatEntry (cluster, firstFree);
-	}
-	// Create the linked to FAT entry
-	FAT_WriteFatEntry (firstFree, CLUSTER_EOF);
-
-	return firstFree;
-}
-#endif
-
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_ClearLinks
-Internal function - frees any cluster used by a file
------------------------------------------------------------------*/
-bool FAT_ClearLinks (u32 cluster)
-{
-	u32 nextCluster;
-
-	if ((cluster < 0x0002) || (cluster > fatLastCluster))
-		return false;
-
-	// Store next cluster before erasing the link
-	nextCluster = FAT_NextCluster (cluster);
-
-	// Erase the link
-	FAT_WriteFatEntry (cluster, CLUSTER_FREE);
-
-	// Move onto next cluster
-	cluster = nextCluster;
-
-	while ((cluster != CLUSTER_EOF) && (cluster != CLUSTER_FREE))
-	{
-		cluster = FAT_ReadWriteFatEntryBuffered (cluster, CLUSTER_FREE);
-	}
-
-	// Flush fat write buffer
-	FAT_WriteFatEntryFlushBuffer ();
-
-	return true;
-}
-#endif
-
-
-/*-----------------------------------------------------------------
-FAT_InitFiles
-Reads the FAT information from the CF card.
-You need to call this before reading any files.
-bool return OUT: true if successful.
------------------------------------------------------------------*/
-bool FAT_InitFiles (void)
-{
-	int i;
-	int bootSector;
-	BOOT_SEC* bootSec;
-
-	if (!disc_Init())
-	{
-		return (false);
-	}
-	// Read first sector of CF card
-	if ( !disc_ReadSector(0, globalBuffer)) {
-		return false;
-	}
-
-
-	// Make sure it is a valid MBR or boot sector
-/*	if ( (globalBuffer[0x1FE] != 0x55) || (globalBuffer[0x1FF] != 0xAA)) {
-		return false;
-	}*/
-
-
-
-	// Check if there is a FAT string, which indicates this is a boot sector
-	if ((globalBuffer[0x36] == 'F') && (globalBuffer[0x37] == 'A') && (globalBuffer[0x38] == 'T'))
-	{
-		bootSector = 0;
-	}
-	// Check for FAT32
-	else if ((globalBuffer[0x52] == 'F') && (globalBuffer[0x53] == 'A') && (globalBuffer[0x54] == 'T'))
-	{
-		bootSector = 0;
-	}
-	else	// This is an MBR
-	{
-		// Find first valid partition from MBR
-		// First check for an active partition
-		for (i=0x1BE; (i < 0x1FE) && (globalBuffer[i] != 0x80); i+= 0x10);
-		// If it didn't find an active partition, search for any valid partition
-		if (i == 0x1FE)
-			for (i=0x1BE; (i < 0x1FE) && (globalBuffer[i+0x04] == 0x00); i+= 0x10);
-
-		// Go to first valid partition
-		if ( i != 0x1FE)	// Make sure it found a partition
-		{
-			bootSector = globalBuffer[0x8 + i] + (globalBuffer[0x9 + i] << 8) + (globalBuffer[0xA + i] << 16) + ((globalBuffer[0xB + i] << 24) & 0x0F);
-		} else {
-			bootSector = 0;	// No partition found, assume this is a MBR free disk
-		}
-	}
-
-	// Read in boot sector
-	bootSec = (BOOT_SEC*) globalBuffer;
-	if (!disc_ReadSector (bootSector,  bootSec)) {
-		return false;
-	}
-
-	// Store required information about the file system
-	if (bootSec->sectorsPerFAT != 0)
-	{
-		filesysSecPerFAT = bootSec->sectorsPerFAT;
-	}
-	else
-	{
-		filesysSecPerFAT = bootSec->extBlock.fat32.sectorsPerFAT32;
-	}
-
-	if (bootSec->numSectorsSmall != 0)
-	{
-		filesysNumSec = bootSec->numSectorsSmall;
-	}
-	else
-	{
-		filesysNumSec = bootSec->numSectors;
-	}
-
-	filesysBytePerSec = BYTE_PER_READ;	// Sector size is redefined to be 512 bytes
-	filesysSecPerClus = bootSec->sectorsPerCluster * bootSec->bytesPerSector / BYTE_PER_READ;
-	filesysBytePerClus = filesysBytePerSec * filesysSecPerClus;
-	filesysFAT = bootSector + bootSec->reservedSectors;
-
-	filesysRootDir = filesysFAT + (bootSec->numFATs * filesysSecPerFAT);
-	filesysData = filesysRootDir + ((bootSec->rootEntries * sizeof(DIR_ENT)) / filesysBytePerSec);
-
-	filesysTotalSize = (filesysNumSec - filesysData) * filesysBytePerSec;
-
-	// Store info about FAT
-	fatLastCluster = (filesysNumSec - filesysData) / bootSec->sectorsPerCluster;
-	fatFirstFree = CLUSTER_FIRST;
-	fatBufferCurSector = 0;
-	disc_ReadSector(fatBufferCurSector, fatBuffer);
-
-	if (fatLastCluster < 4085)
-	{
-		filesysType = FS_FAT12;	// FAT12 volume - unsupported
-	}
-	else if (fatLastCluster < 65525)
-	{
-		filesysType = FS_FAT16;	// FAT16 volume
-	}
-	else
-	{
-		filesysType = FS_FAT32;	// FAT32 volume
-	}
-
-	if (filesysType != FS_FAT32)
-	{
-		filesysRootDirClus = FAT16_ROOT_DIR_CLUSTER;
-	}
-	else	// Set up for the FAT32 way
-	{
-		filesysRootDirClus = bootSec->extBlock.fat32.rootClus;
-		// Check if FAT mirroring is enabled
-		if (!(bootSec->extBlock.fat32.extFlags & 0x80))
-		{
-			// Use the active FAT
-			filesysFAT = filesysFAT + ( filesysSecPerFAT * (bootSec->extBlock.fat32.extFlags & 0x0F));
-		}
-	}
-
-	// Set current directory to the root
-	curWorkDirCluster = filesysRootDirClus;
-	wrkDirCluster = filesysRootDirClus;
-	wrkDirSector = 0;
-	wrkDirOffset = 0;
-
-	// Set all files to free
-	for (i=0; i < MAX_FILES_OPEN; i++)
-	{
-		openFiles[i].inUse = false;
-	}
-
-	// No long filenames so far
-	lfnExists = false;
-	for (i = 0; i < MAX_FILENAME_LENGTH; i++)
-	{
-		lfnName[i] = '\0';
-	}
-
-	return (true);
-}
-
-/*-----------------------------------------------------------------
-FAT_FreeFiles
-Closes all open files then resets the CF card.
-Call this before exiting back to the GBAMP
-bool return OUT: true if successful.
------------------------------------------------------------------*/
-bool FAT_FreeFiles (void)
-{
-	int i;
-
-	// Close all open files
-	for (i=0; i < MAX_FILES_OPEN; i++)
-	{
-		if (openFiles[i].inUse == true)
-		{
-			FAT_fclose(&openFiles[i]);
-		}
-	}
-
-	// Flush any sectors in disc cache
-	disc_CacheFlush();
-
-	// Clear card status
-	disc_ClearStatus();
-
-	// Return status of card
-	return disc_IsInserted();
-}
-
-
-/*-----------------------------------------------------------------
-FAT_GetDirEntry
-Return the file info structure of the next valid file entry
-u32 dirCluster: IN cluster of subdirectory table
-int entry: IN the desired file entry
-int origin IN: relative position of the entry
-DIR_ENT return OUT: desired dirEntry. First char will be FILE_FREE if
-	the entry does not exist.
------------------------------------------------------------------*/
-DIR_ENT FAT_GetDirEntry ( u32 dirCluster, int entry, int origin)
-{
-	DIR_ENT dir;
-	DIR_ENT_LFN lfn;
-	int firstSector = 0;
-	bool notFound = false;
-	bool found = false;
-	int maxSectors;
-	int lfnPos, aliasPos;
-	u8 lfnChkSum, chkSum;
-
-	int i;
-
-	dir.name[0] = FILE_FREE; // default to no file found
-	dir.attrib = 0x00;
-
-	// Check if fat has been initialized
-	if (filesysBytePerSec == 0)
-	{
-		return (dir);
-	}
-
-	switch (origin)
-	{
-	case SEEK_SET:
-		wrkDirCluster = dirCluster;
-		wrkDirSector = 0;
-		wrkDirOffset = -1;
-		break;
-	case SEEK_CUR:	// Don't change anything
-		break;
-	case SEEK_END:	// Find entry signifying end of directory
-		// Subtraction will never reach 0, so it keeps going
-		// until reaches end of directory
-		wrkDirCluster = dirCluster;
-		wrkDirSector = 0;
-		wrkDirOffset = -1;
-		entry = -1;
-		break;
-	default:
-		return dir;
-	}
-
-	lfnChkSum = 0;
-	maxSectors = (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? (filesysData - filesysRootDir) : filesysSecPerClus);
-
-	// Scan Dir for correct entry
-	firstSector = (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster));
-	disc_ReadSector (firstSector + wrkDirSector, globalBuffer);
-	found = false;
-	notFound = false;
-	do {
-		wrkDirOffset++;
-		if (wrkDirOffset == BYTE_PER_READ / sizeof (DIR_ENT))
-		{
-			wrkDirOffset = 0;
-			wrkDirSector++;
-			if ((wrkDirSector == filesysSecPerClus) && (wrkDirCluster != FAT16_ROOT_DIR_CLUSTER))
-			{
-				wrkDirSector = 0;
-				wrkDirCluster = FAT_NextCluster(wrkDirCluster);
-				if (wrkDirCluster == CLUSTER_EOF)
-				{
-					notFound = true;
-				}
-				firstSector = FAT_ClustToSect(wrkDirCluster);
-			}
-			else if ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER) && (wrkDirSector == (filesysData - filesysRootDir)))
-			{
-				notFound = true;	// Got to end of root dir
-			}
-			disc_ReadSector (firstSector + wrkDirSector, globalBuffer);
-		}
-		dir = ((DIR_ENT*) globalBuffer)[wrkDirOffset];
-		if ((dir.name[0] != FILE_FREE) && (dir.name[0] > 0x20) && ((dir.attrib & ATTRIB_VOL) != ATTRIB_VOL))
-		{
-			entry--;
-			if (lfnExists)
-			{
-				// Calculate file checksum
-				chkSum = 0;
-				for (aliasPos=0; aliasPos < 11; aliasPos++)
-				{
-					// NOTE: The operation is an unsigned char rotate right
-					chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + (aliasPos < 8 ? dir.name[aliasPos] : dir.ext[aliasPos - 8]);
-				}
-				if (chkSum != lfnChkSum)
-				{
-					lfnExists = false;
-					lfnName[0] = '\0';
-				}
-			}
-			if (entry == 0)
-			{
-				if (!lfnExists)
-				{
-					FAT_GetFilename (dir, lfnName);
-				}
-				found = true;
-			}
-		}
-		else if (dir.name[0] == FILE_LAST)
-		{
-			if (origin == SEEK_END)
-			{
-				found = true;
-			}
-			else
-			{
-				notFound = true;
-			}
-		}
-		else if (dir.attrib == ATTRIB_LFN)
-		{
-			lfn = ((DIR_ENT_LFN*) globalBuffer)[wrkDirOffset];
-			if (lfn.ordinal & LFN_DEL)
-			{
-				lfnExists = false;
-			}
-			else if (lfn.ordinal & LFN_END)	// Last part of LFN, make sure it isn't deleted (Thanks MoonLight)
-			{
-				lfnExists = true;
-				lfnName[(lfn.ordinal & ~LFN_END) * 13] = '\0';	// Set end of lfn to null character
-				lfnChkSum = lfn.checkSum;
-			}
-			if (lfnChkSum != lfn.checkSum)
-			{
-				lfnExists = false;
-			}
-			if (lfnExists)
-			{
-				lfnPos = ((lfn.ordinal & ~LFN_END) - 1) * 13;
-				for (i = 0; i < 13; i++) {
-					lfnName[lfnPos + i] = ((u8*)&lfn)[(int)(lfn_offset_table[i])] /* | ((u8*)&lfn)[(int)(lfn_offset_table[i]) + 1]  include this for unicode support*/;
-				}
-			}
-		}
-	} while (!found && !notFound);
-
-	// If no file is found, return FILE_FREE
-	if (notFound)
-	{
-		dir.name[0] = FILE_FREE;
-	}
-
-	return (dir);
-}
-
-
-/*-----------------------------------------------------------------
-FAT_GetLongFilename
-Get the long name of the last file or directory retrived with
-	GetDirEntry. Also works for FindFirstFile and FindNextFile.
-	If a long name doesn't exist, it returns the short name
-	instead.
-char* filename: OUT will be filled with the filename, should be at
-	least 256 bytes long
-bool return OUT: return true if successful
------------------------------------------------------------------*/
-bool FAT_GetLongFilename (char* filename)
-{
-	if (filename == NULL)
-		return false;
-
-	strncpy (filename, lfnName, MAX_FILENAME_LENGTH - 1);
-	filename[MAX_FILENAME_LENGTH - 1] = '\0';
-
-	return true;
-}
-
-
-/*-----------------------------------------------------------------
-FAT_GetFilename
-Get the alias (short name) of the file or directory stored in
-	dirEntry
-DIR_ENT dirEntry: IN a valid directory table entry
-char* alias OUT: will be filled with the alias (short filename),
-	should be at least 13 bytes long
-bool return OUT: return true if successful
------------------------------------------------------------------*/
-bool FAT_GetFilename (DIR_ENT dirEntry, char* alias)
-{
-	int i=0;
-	int j=0;
-
-	alias[0] = '\0';
-	if (dirEntry.name[0] != FILE_FREE)
-	{
-		if (dirEntry.name[0] == '.')
-		{
-			alias[0] = '.';
-			if (dirEntry.name[1] == '.')
-			{
-				alias[1] = '.';
-				alias[2] = '\0';
-			}
-			else
-			{
-				alias[1] = '\0';
-			}
-		}
-		else
-		{
-			// Copy the filename from the dirEntry to the string
-			for (i = 0; (i < 8) && (dirEntry.name[i] != ' '); i++)
-			{
-				alias[i] = dirEntry.name[i];
-			}
-			// Copy the extension from the dirEntry to the string
-			if (dirEntry.ext[0] != ' ')
-			{
-				alias[i++] = '.';
-				for ( j = 0; (j < 3) && (dirEntry.ext[j] != ' '); j++)
-				{
-					alias[i++] = dirEntry.ext[j];
-				}
-			}
-			alias[i] = '\0';
-		}
-	}
-
-	return (alias[0] != '\0');
-}
-
-/*-----------------------------------------------------------------
-FAT_GetAlias
-Get the alias (short name) of the last file or directory entry read
-	using GetDirEntry. Works for FindFirstFile and FindNextFile
-char* alias OUT: will be filled with the alias (short filename),
-	should be at least 13 bytes long
-bool return OUT: return true if successful
------------------------------------------------------------------*/
-bool FAT_GetAlias (char* alias)
-{
-	if (alias == NULL)
-	{
-		return false;
-	}
-	// Read in the last accessed directory entry
-	disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
-
-	return 	FAT_GetFilename (((DIR_ENT*)globalBuffer)[wrkDirOffset], alias);
-}
-
-/*-----------------------------------------------------------------
-FAT_GetFileSize
-Get the file size of the last file found or openned.
-This idea is based on a modification by MoonLight
-u32 return OUT: the file size
------------------------------------------------------------------*/
-u32 FAT_GetFileSize (void)
-{
-	// Read in the last accessed directory entry
-	disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
-
-	return 	((DIR_ENT*)globalBuffer)[wrkDirOffset].fileSize;
-}
-
-/*-----------------------------------------------------------------
-FAT_GetFileCluster
-Get the first cluster of the last file found or openned.
-u32 return OUT: the file start cluster
------------------------------------------------------------------*/
-u32 FAT_GetFileCluster (void)
-{
-	// Read in the last accessed directory entry
-	disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
-
-	return 	(((DIR_ENT*)globalBuffer)[wrkDirOffset].startCluster) | (((DIR_ENT*)globalBuffer)[wrkDirOffset].startClusterHigh << 16);
-}
-
-/*-----------------------------------------------------------------
-FAT_GetFileAttributes
-Get the attributes of the last file found or openned.
-u8 return OUT: the file's attributes
------------------------------------------------------------------*/
-u8 FAT_GetFileAttributes (void)
-{
-	// Read in the last accessed directory entry
-	disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
-
-	return 	((DIR_ENT*)globalBuffer)[wrkDirOffset].attrib;
-}
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_SetFileAttributes
-Set the attributes of a file.
-const char* filename IN: The name and path of the file to modify
-u8 attributes IN: The attribute values to assign
-u8 mask IN: Detemines which attributes are changed
-u8 return OUT: the file's new attributes
------------------------------------------------------------------*/
-u8 FAT_SetFileAttributes (const char* filename, u8 attributes, u8 mask)
-{
-	// Get the file
-	if (!FAT_FileExists(filename)) {
-		return 0xff;
-	}
-
-	// Read in the last accessed directory entry
-	disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
-
-	((DIR_ENT*)globalBuffer)[wrkDirOffset].attrib = (((DIR_ENT*)globalBuffer)[wrkDirOffset].attrib & ~(mask & 0x27)) | (attributes & 0x27);	// 0x27 is he settable attributes
-
-	disc_WriteSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
-
-	return 	((DIR_ENT*)globalBuffer)[wrkDirOffset].attrib;
-}
-#endif
-
-#ifdef FILE_TIME_SUPPORT
-time_t FAT_FileTimeToCTime (u16 fileTime, u16 fileDate)
-{
-	struct tm timeInfo;
-
-	timeInfo.tm_year = (fileDate >> 9) + 80;		// years since midnight January 1970
-	timeInfo.tm_mon = ((fileDate >> 5) & 0xf) - 1;	// Months since january
-	timeInfo.tm_mday = fileDate & 0x1f;				// Day of the month
-
-	timeInfo.tm_hour = fileTime >> 11;				// hours past midnight
-	timeInfo.tm_min = (fileTime >> 5) & 0x3f;		// minutes past the hour
-	timeInfo.tm_sec = (fileTime & 0x1f) * 2;		// seconds past the minute
-
-	return mktime(&timeInfo);
-}
-
-/*-----------------------------------------------------------------
-FAT_GetFileCreationTime
-Get the creation time of the last file found or openned.
-time_t return OUT: the file's creation time
------------------------------------------------------------------*/
-time_t FAT_GetFileCreationTime (void)
-{
-	// Read in the last accessed directory entry
-	disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
-
-	return 	FAT_FileTimeToCTime(((DIR_ENT*)globalBuffer)[wrkDirOffset].cTime, ((DIR_ENT*)globalBuffer)[wrkDirOffset].cDate);
-}
-
-/*-----------------------------------------------------------------
-FAT_GetFileLastWriteTime
-Get the creation time of the last file found or openned.
-time_t return OUT: the file's creation time
------------------------------------------------------------------*/
-time_t FAT_GetFileLastWriteTime (void)
-{
-	// Read in the last accessed directory entry
-	disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
-
-	return 	FAT_FileTimeToCTime(((DIR_ENT*)globalBuffer)[wrkDirOffset].mTime, ((DIR_ENT*)globalBuffer)[wrkDirOffset].mDate);
-}
-#endif
-
-/*-----------------------------------------------------------------
-FAT_DirEntFromPath
-Finds the directory entry for a file or directory from a path
-Path separator is a forward slash /
-const char* path: IN null terminated string of path.
-DIR_ENT return OUT: dirEntry of found file. First char will be FILE_FREE
-	if the file was not found
------------------------------------------------------------------*/
-DIR_ENT FAT_DirEntFromPath (const char* path)
-{
-	int pathPos;
-	char name[MAX_FILENAME_LENGTH];
-	char alias[13];
-	int namePos;
-	bool found, notFound;
-	DIR_ENT dirEntry;
-	u32 dirCluster;
-	bool flagLFN, dotSeen;
-	// Start at beginning of path
-	pathPos = 0;
-
-#ifdef DS_BUILD_F
-	// Problems with Kyrandia doing a load of path lookups are reduced by this hack.
-	if (strstr(path, ".voc") || strstr(path, ".voc"))
-	{
-		dirEntry.name[0] = FILE_FREE;
-		dirEntry.attrib = 0x00;
-		return dirEntry;
-	}
-#endif
-
-	if (path[pathPos] == '/')
-	{
-		dirCluster = filesysRootDirClus;	// Start at root directory
-	}
-	else
-	{
-		dirCluster = curWorkDirCluster;	// Start at current working dir
-	}
-
-	// Eat any slash /
-	while ((path[pathPos] == '/') && (path[pathPos] != '\0'))
-	{
-		pathPos++;
-	}
-
-	// Search until can't continue
-	found = false;
-	notFound = false;
-	while (!notFound && !found)
-	{
-		flagLFN = false;
-		// Copy name from path
-		namePos = 0;
-		if ((path[pathPos] == '.') && ((path[pathPos + 1] == '\0') || (path[pathPos + 1] == '/'))) {
-			// Dot entry
-			name[namePos++] = '.';
-			pathPos++;
-		} else if ((path[pathPos] == '.') && (path[pathPos + 1] == '.') && ((path[pathPos + 2] == '\0') || (path[pathPos + 2] == '/'))){
-			// Double dot entry
-			name[namePos++] = '.';
-			pathPos++;
-			name[namePos++] = '.';
-			pathPos++;
-		} else {
-			// Copy name from path
-			if (path[pathPos] == '.') {
-				flagLFN = true;
-			}
-			dotSeen = false;
-			while ((namePos < MAX_FILENAME_LENGTH - 1) && (path[pathPos] != '\0') && (path[pathPos] != '/'))
-			{
-				name[namePos] = ucase(path[pathPos]);
-				if ((name[namePos] <= ' ') || ((name[namePos] >= ':') && (name[namePos] <= '?'))) // Invalid character
-				{
-					flagLFN = true;
-				}
-				if (name[namePos] == '.') {
-					if (!dotSeen) {
-						dotSeen = true;
-					} else {
-						flagLFN = true;
-					}
-				}
-				namePos++;
-				pathPos++;
-			}
-			// Check if a long filename was specified
-			if (namePos > 12)
-			{
-				flagLFN = true;
-			}
-		}
-
-		// Add end of string char
-		name[namePos] = '\0';
-
-		// Move through path to correct place
-		while ((path[pathPos] != '/') && (path[pathPos] != '\0'))
-			pathPos++;
-		// Eat any slash /
-		while ((path[pathPos] == '/') && (path[pathPos] != '\0'))
-		{
-			pathPos++;
-		}
-
-		// Search current Dir for correct entry
-		dirEntry = FAT_GetDirEntry (dirCluster, 1, SEEK_SET);
-		while ( !found && !notFound)
-		{
-			// Match filename
-			found = true;
-			for (namePos = 0; (namePos < MAX_FILENAME_LENGTH-1) && found && (name[namePos] != '\0') && (lfnName[namePos] != '\0'); namePos++)
-			{
-				if (name[namePos] != ucase(lfnName[namePos]))
-				{
-					found = false;
-				}
-			}
-			if ((name[namePos] == '\0') != (lfnName[namePos] == '\0'))
-			{
-				found = false;
-			}
-
-			// Check against alias as well.
-			if (!found)
-			{
-				FAT_GetFilename(dirEntry, alias);
-				found = true;
-				for (namePos = 0; (namePos < (sizeof(alias)/sizeof(alias[0]))-1) && found && (name[namePos] != '\0') && (alias[namePos] != '\0'); namePos++)
-				{
-					if (name[namePos] != ucase(alias[namePos]))
-					{
-						found = false;
-					}
-				}
-				if ((name[namePos] == '\0') != (alias[namePos] == '\0'))
-				{
-					found = false;
-				}
-			}
-
-			if (dirEntry.name[0] == FILE_FREE)
-				// Couldn't find specified file
-			{
-				found = false;
-				notFound = true;
-			}
-			if (!found && !notFound)
-			{
-				dirEntry = FAT_GetDirEntry (dirCluster, 1, SEEK_CUR);
-			}
-		}
-
-		if (found && ((dirEntry.attrib & ATTRIB_DIR) == ATTRIB_DIR) && (path[pathPos] != '\0'))
-			// It has found a directory from within the path that needs to be followed
-		{
-			found = false;
-			dirCluster = dirEntry.startCluster | (dirEntry.startClusterHigh << 16);
-		}
-	}
-
-	if (notFound)
-	{
-		dirEntry.name[0] = FILE_FREE;
-		dirEntry.attrib = 0x00;
-	}
-
-	return (dirEntry);
-}
-
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_AddDirEntry
-Creates a new dir entry for a file
-Path separator is a forward slash /
-const char* path: IN null terminated string of path to file.
-DIR_ENT newDirEntry IN: The directory entry to use.
-int file IN: The file being added (optional, use -1 if not used)
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool FAT_AddDirEntry (const char* path, DIR_ENT newDirEntry)
-{
-	char filename[MAX_FILENAME_LENGTH];
-	int filePos, pathPos, aliasPos;
-	char tempChar;
-	bool flagLFN, dotSeen;
-	char fileAlias[13] = {0};
-	int tailNum;
-
-	unsigned char chkSum = 0;
-
-	u32 oldWorkDirCluster;
-
-	DIR_ENT* dirEntries = (DIR_ENT*)globalBuffer;
-	u32 dirCluster;
-	int secOffset;
-	int entryOffset;
-	int maxSectors;
-	u32 firstSector;
-
-	DIR_ENT_LFN lfnEntry;
-	int lfnPos = 0;
-
-	int dirEntryLength = 0;
-	int dirEntryRemain = 0;
-	u32 tempDirCluster;
-	int tempSecOffset;
-	int tempEntryOffset;
-	bool dirEndFlag = false;
-
-	int i;
-
-	// Store current working directory
-	oldWorkDirCluster = curWorkDirCluster;
-
-	// Find filename within path and change to correct directory
-	if (path[0] == '/')
-	{
-		curWorkDirCluster = filesysRootDirClus;
-	}
-
-	pathPos = 0;
-	filePos = 0;
-	flagLFN = false;
-
-	while (path[pathPos + filePos] != '\0')
-	{
-		if (path[pathPos + filePos] == '/')
-		{
-			filename[filePos] = '\0';
-			if (FAT_chdir(filename) == false)
-			{
-				curWorkDirCluster = oldWorkDirCluster;
-				return false; // Couldn't change directory
-			}
-			pathPos += filePos + 1;
-			filePos = 0;
-		}
-		filename[filePos] = path[pathPos + filePos];
-		filePos++;
-	}
-
-	// Skip over last slashes
-	while (path[pathPos] == '/')
-		pathPos++;
-
-	// Check if the filename has a leading "."
-	// If so, it is an LFN
-	if (path[pathPos] == '.') {
-		flagLFN = true;
-	}
-
-	// Copy name from path
-	filePos = 0;
-	dotSeen = false;
-
-	while ((filePos < MAX_FILENAME_LENGTH - 1) && (path[pathPos] != '\0'))
-	{
-		filename[filePos] = path[pathPos];
-		if ((filename[filePos] <= ' ') || ((filename[filePos] >= ':') && (filename[filePos] <= '?'))) // Invalid character
-		{
-			flagLFN = true;
-		}
-		if (filename[filePos] == '.') {
-			if (!dotSeen) {
-				dotSeen = true;
-			} else {
-				flagLFN = true;
-			}
-		}
-		filePos++;
-		pathPos++;
-		if ((filePos > 8) && !dotSeen) {
-			flagLFN = true;
-		}
-	}
-
-	if (filePos == 0)	// No filename
-	{
-		return false;
-	}
-
-	// Check if a long filename was specified
-	if (filePos > 12)
-	{
-		flagLFN = true;
-	}
-
-	// Check if extension is > 3 characters long
-	if (!flagLFN && (strrchr (filename, '.') != NULL) && (strlen(strrchr(filename, '.')) > 4)) {
-		flagLFN = true;
-	}
-
-	lfnPos = (filePos - 1) / 13;
-
-	// Add end of string char
-	filename[filePos++] = '\0';
-	// Clear remaining chars
-	while (filePos < MAX_FILENAME_LENGTH)
-		filename[filePos++] = 0x01;	// Set for LFN compatibility
-
-
-	if (flagLFN)
-	{
-		// Generate short filename - always a 2 digit number for tail
-		// Get first 5 chars of alias from LFN
-		aliasPos = 0;
-		filePos = 0;
-		if (filename[filePos] == '.') {
-			filePos++;
-		}
-		for ( ; (aliasPos < 5) && (filename[filePos] != '\0') && (filename[filePos] != '.') ; filePos++)
-		{
-			tempChar = ucase(filename[filePos]);
-			if (((tempChar > ' ' && tempChar < ':') || tempChar > '?') && tempChar != '.')
-				fileAlias[aliasPos++] = tempChar;
-		}
-		// Pad Alias with underscores
-		while (aliasPos < 5)
-			fileAlias[aliasPos++] = '_';
-
-		fileAlias[5] = '~';
-		fileAlias[8] = '.';
-		fileAlias[9] = ' ';
-		fileAlias[10] = ' ';
-		fileAlias[11] = ' ';
-		if (strchr (filename, '.') != NULL) {
-			while(filename[filePos] != '\0')
-			{
-				filePos++;
-				if (filename[filePos] == '.')
-				{
-					pathPos = filePos;
-				}
-			}
-			filePos = pathPos + 1;	//pathPos is used as a temporary variable
-			// Copy first 3 characters of extension
-			for (aliasPos = 9; (aliasPos < 12) && (filename[filePos] != '\0'); filePos++)
-			{
-				tempChar = ucase(filename[filePos]);
-				if ((tempChar > ' ' && tempChar < ':') || tempChar > '?')
-					fileAlias[aliasPos++] = tempChar;
-			}
-		} else {
-			aliasPos = 9;
-		}
-
-		// Pad Alias extension with spaces
-		while (aliasPos < 12)
-			fileAlias[aliasPos++] = ' ';
-
-		fileAlias[12] = '\0';
-
-
-		// Get a valid tail number
-		tailNum = 0;
-		do {
-			tailNum++;
-			fileAlias[6] = 0x30 + ((tailNum / 10) % 10);	// 10's digit
-			fileAlias[7] = 0x30 + (tailNum % 10);	// 1's digit
-		} while ((FAT_DirEntFromPath(fileAlias).name[0] != FILE_FREE) && (tailNum < 100));
-
-		if (tailNum < 100)	// Found an alias not being used
-		{
-			// Calculate file checksum
-			chkSum = 0;
-			for (aliasPos=0; aliasPos < 12; aliasPos++)
-			{
-				// Skip '.'
-				if (fileAlias[aliasPos] == '.')
-					aliasPos++;
-				// NOTE: The operation is an unsigned char rotate right
-				chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + fileAlias[aliasPos];
-			}
-		}
-		else	// Couldn't find a valid alias
-		{
-			return false;
-		}
-
-		dirEntryLength = lfnPos + 2;
-	}
-	else	// Its not a long file name
-	{
-		// Just copy alias straight from filename
-		for (aliasPos = 0; aliasPos < 13; aliasPos++)
-		{
-			tempChar = ucase(filename[aliasPos]);
-			if ((tempChar > ' ' && tempChar < ':') || tempChar > '?')
-				fileAlias[aliasPos] = tempChar;
-		}
-		fileAlias[12] = '\0';
-
-		lfnPos = -1;
-
-		dirEntryLength = 1;
-	}
-
-	// Change dirEntry name to match alias
-	for (aliasPos = 0; ((fileAlias[aliasPos] != '.') && (fileAlias[aliasPos] != '\0') && (aliasPos < 8)); aliasPos++)
-	{
-		newDirEntry.name[aliasPos] = fileAlias[aliasPos];
-	}
-	while (aliasPos < 8)
-	{
-		newDirEntry.name[aliasPos++] = ' ';
-	}
-	aliasPos = 0;
-	while ((fileAlias[aliasPos] != '.') && (fileAlias[aliasPos] != '\0'))
-		aliasPos++;
-	filePos = 0;
-	while (( filePos < 3 ) && (fileAlias[aliasPos] != '\0'))
-	{
-		tempChar = fileAlias[aliasPos++];
-		if ((tempChar > ' ' && tempChar < ':' && tempChar!='.') || tempChar > '?')
-			newDirEntry.ext[filePos++] = tempChar;
-	}
-	while (filePos < 3)
-	{
-		newDirEntry.ext[filePos++] = ' ';
-	}
-
-	// Scan Dir for free entry
-	dirCluster = curWorkDirCluster;
-	secOffset = 0;
-	entryOffset = 0;
-	maxSectors = (dirCluster == FAT16_ROOT_DIR_CLUSTER ? (filesysData - filesysRootDir) : filesysSecPerClus);
-	firstSector = (dirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(dirCluster));
-	disc_ReadSector (firstSector + secOffset, dirEntries);
-
-	dirEntryRemain = dirEntryLength;
-	tempDirCluster = dirCluster;
-	tempSecOffset = secOffset;
-	tempEntryOffset = entryOffset;
-
-	// Search for a large enough space to fit in new directory entry
-	while ((dirEntries[entryOffset].name[0] != FILE_LAST) && (dirEntryRemain > 0))
-	{
-
-		entryOffset++;
-
-		if (entryOffset == BYTE_PER_READ / sizeof (DIR_ENT))
-		{
-			entryOffset = 0;
-			secOffset++;
-			if ((secOffset == filesysSecPerClus) && (dirCluster != FAT16_ROOT_DIR_CLUSTER))
-			{
-				secOffset = 0;
-				if (FAT_NextCluster(dirCluster) == CLUSTER_EOF)
-				{
-					dirCluster = FAT_LinkFreeCluster(dirCluster);
-					dirEntries[0].name[0] = FILE_LAST;
-				}
-				else
-				{
-					dirCluster = FAT_NextCluster(dirCluster);
-				}
-				firstSector = FAT_ClustToSect(dirCluster);
-			}
-			else if ((dirCluster == FAT16_ROOT_DIR_CLUSTER) && (secOffset == (filesysData - filesysRootDir)))
-			{
-				return false;	// Got to end of root dir - can't fit in more files
-			}
-			disc_ReadSector (firstSector + secOffset, dirEntries);
-		}
-
-		if ((dirEntries[entryOffset].name[0] == FILE_FREE) || (dirEntries[entryOffset].name[0] == FILE_LAST) )
-		{
-			dirEntryRemain--;
-		} else {
-			dirEntryRemain = dirEntryLength;
-			tempDirCluster = dirCluster;
-			tempSecOffset = secOffset;
-			tempEntryOffset = entryOffset;
-		}
-	}
-
-	// Modifying the last directory is a special case - have to erase following entries
-	if (dirEntries[entryOffset].name[0] == FILE_LAST)
-	{
-		dirEndFlag = true;
-	}
-
-	// Recall last used entry
-	dirCluster = tempDirCluster;
-	secOffset = tempSecOffset;
-	entryOffset = tempEntryOffset;
-	dirEntryRemain = dirEntryLength;
-
-	// Re-read in first sector that will be written to
-	if (dirEndFlag && (entryOffset == 0))	{
-		memset (dirEntries, FILE_LAST, BYTE_PER_READ);
-	} else {
-		disc_ReadSector (firstSector + secOffset, dirEntries);
-	}
-
-	// Add new directory entry
-	while (dirEntryRemain > 0)
-	{
-		// Move to next entry, first pass advances from last used entry
-		entryOffset++;
-		if (entryOffset == BYTE_PER_READ / sizeof (DIR_ENT))
-		{
-			// Write out the current sector if we need to
-			entryOffset = 0;
-			if (dirEntryRemain < dirEntryLength) // Don't write out sector on first pass
-			{
-				disc_WriteSector (firstSector + secOffset, dirEntries);
-			}
-			secOffset++;
-			if ((secOffset == filesysSecPerClus) && (dirCluster != FAT16_ROOT_DIR_CLUSTER))
-			{
-				secOffset = 0;
-				if (FAT_NextCluster(dirCluster) == CLUSTER_EOF)
-				{
-					dirCluster = FAT_LinkFreeCluster(dirCluster);
-					dirEntries[0].name[0] = FILE_LAST;
-				}
-				else
-				{
-					dirCluster = FAT_NextCluster(dirCluster);
-				}
-				firstSector = FAT_ClustToSect(dirCluster);
-			}
-			else if ((dirCluster == FAT16_ROOT_DIR_CLUSTER) && (secOffset == (filesysData - filesysRootDir)))
-			{
-				return false;	// Got to end of root dir - can't fit in more files
-			}
-			if (dirEndFlag)
-			{
-				memset (dirEntries, FILE_LAST, BYTE_PER_READ);
-			} else {
-				disc_ReadSector (firstSector + secOffset, dirEntries);
-			}
-		}
-
-		// Generate LFN entries
-		if (lfnPos >= 0)
-		{
-			lfnEntry.ordinal = (lfnPos + 1) | (dirEntryRemain == dirEntryLength ? LFN_END : 0);
-			for (i = 0; i < 13; i++) {
-				if (filename [lfnPos * 13 + i] == 0x01) {
-					((u8*)&lfnEntry)[(int)lfn_offset_table[i]] = 0xff;
-					((u8*)&lfnEntry)[(int)(lfn_offset_table[i]) + 1] = 0xff;
-				} else {
-					((u8*)&lfnEntry)[(int)lfn_offset_table[i]] = filename [lfnPos * 13 + i];
-					((u8*)&lfnEntry)[(int)(lfn_offset_table[i]) + 1] = 0x00;
-				}
-			}
-
-			lfnEntry.checkSum = chkSum;
-			lfnEntry.flag = ATTRIB_LFN;
-			lfnEntry.reserved1 = 0;
-			lfnEntry.reserved2 = 0;
-
-			*((DIR_ENT_LFN*)&dirEntries[entryOffset]) = lfnEntry;
-			lfnPos --;
-			lfnEntry.ordinal = 0;
-		}	// end writing long filename entries
-		else
-		{
-			dirEntries[entryOffset] = newDirEntry;
-			if (dirEndFlag && (entryOffset < (BYTE_PER_READ / sizeof (DIR_ENT))) )
-				dirEntries[entryOffset+1].name[0] = FILE_LAST;
-		}
-
-		dirEntryRemain--;
-	}
-
-	// Write directory back to disk
-	disc_WriteSector (firstSector + secOffset, dirEntries);
-
-	// Change back to Working DIR
-	curWorkDirCluster = oldWorkDirCluster;
-
-	return true;
-}
-#endif
-
-/*-----------------------------------------------------------------
-FAT_FindNextFile
-Gets the name of the next directory entry
-	(can be a file or subdirectory)
-char* filename: OUT filename, must be at least 13 chars long
-FILE_TYPE return: OUT returns FT_NONE if failed,
-	FT_FILE if it found a file and FT_DIR if it found a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FindNextFile(char* filename)
-{
-	// Get the next directory entry
-	DIR_ENT file;
-	file = FAT_GetDirEntry (curWorkDirCluster, 1, SEEK_CUR);
-
-	if (file.name[0] == FILE_FREE)
-	{
-		return FT_NONE;	// Did not find a file
-	}
-
-	// Get the filename
-	if (filename != NULL)
-		FAT_GetFilename (file, filename);
-
-	if ((file.attrib & ATTRIB_DIR) != 0)
-	{
-		return FT_DIR;	// Found a directory
-	}
-	else
-	{
-		return FT_FILE;	// Found a file
-	}
-}
-
-/*-----------------------------------------------------------------
-FAT_FindFirstFile
-Gets the name of the first directory entry and resets the count
-	(can be a file or subdirectory)
-char* filename: OUT filename, must be at least 13 chars long
-FILE_TYPE return: OUT returns FT_NONE if failed,
-	FT_FILE if it found a file and FT_DIR if it found a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FindFirstFile(char* filename)
-{
-	// Get the first directory entry
-	DIR_ENT file;
-	file = FAT_GetDirEntry (curWorkDirCluster, 1, SEEK_SET);
-
-	if (file.name[0] == FILE_FREE)
-	{
-		return FT_NONE;	// Did not find a file
-	}
-
-	// Get the filename
-	if (filename != NULL)
-		FAT_GetFilename (file, filename);
-
-	if ((file.attrib & ATTRIB_DIR) != 0)
-	{
-		return FT_DIR;	// Found a directory
-	}
-	else
-	{
-		return FT_FILE;	// Found a file
-	}
-}
-
-/*-----------------------------------------------------------------
-FAT_FindFirstFileLFN
-Gets the long file name of the first directory entry and resets
-	the count (can be a file or subdirectory)
-char* lfn: OUT long file name, must be at least 256 chars long
-FILE_TYPE return: OUT returns FT_NONE if failed,
-	FT_FILE if it found a file and FT_DIR if it found a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FindFirstFileLFN(char* lfn)
-{
-	FILE_TYPE type;
-	type = FAT_FindFirstFile(NULL);
-	FAT_GetLongFilename (lfn);
-	return type;
-}
-
-/*-----------------------------------------------------------------
-FAT_FindNextFileLFN
-Gets the long file name of the next directory entry
-	(can be a file or subdirectory)
-char* lfn: OUT long file name, must be at least 256 chars long
-FILE_TYPE return: OUT returns FT_NONE if failed,
-	FT_FILE if it found a file and FT_DIR if it found a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FindNextFileLFN(char* lfn)
-{
-	FILE_TYPE type;
-	type = FAT_FindNextFile(NULL);
-	FAT_GetLongFilename (lfn);
-	return type;
-}
-
-
-/*-----------------------------------------------------------------
-FAT_FileExists
-Returns the type of file
-char* filename: IN filename of the file to look for
-FILE_TYPE return: OUT returns FT_NONE if there is now file with
-	that name, FT_FILE if it is a file and FT_DIR if it is a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FileExists(const char* filename)
-{
-    DIR_ENT dirEntry;
-    // Get the dirEntry for the path specified
-    dirEntry = FAT_DirEntFromPath (filename);
-
-    if (dirEntry.name[0] == FILE_FREE)
-    {
-        return FT_NONE;
-    }
-    else if (dirEntry.attrib & ATTRIB_DIR)
-    {
-        return FT_DIR;
-    }
-    else
-    {
-         return FT_FILE;
-    }
-}
-
-/*-----------------------------------------------------------------
-FAT_GetFileSystemType
-FS_TYPE return: OUT returns the current file system type
------------------------------------------------------------------*/
-FS_TYPE FAT_GetFileSystemType (void)
-{
-	return filesysType;
-}
-
-/*-----------------------------------------------------------------
-FAT_GetFileSystemTotalSize
-u32 return: OUT returns the total disk space (used + free)
------------------------------------------------------------------*/
-u32 FAT_GetFileSystemTotalSize (void)
-{
-	return filesysTotalSize;
-}
-
-
-
-/*-----------------------------------------------------------------
-FAT_chdir
-Changes the current working directory
-const char* path: IN null terminated string of directory separated by
-	forward slashes, / is root
-bool return: OUT returns true if successful
------------------------------------------------------------------*/
-bool FAT_chdir (const char* path)
-{
-	DIR_ENT dir;
-	if (path[0] == '/' && path[1] == '\0')
-	{
-		curWorkDirCluster = filesysRootDirClus;
-		return true;
-	}
-	if (path[0] == '\0')	// Return true if changing relative to nothing
-	{
-		return true;
-	}
-
-	dir = FAT_DirEntFromPath (path);
-
-	if (((dir.attrib & ATTRIB_DIR) == ATTRIB_DIR) && (dir.name[0] != FILE_FREE))
-	{
-		// Change directory
-		curWorkDirCluster = dir.startCluster | (dir.startClusterHigh << 16);
-
-		// Move to correct cluster for root directory
-		if (curWorkDirCluster == FAT16_ROOT_DIR_CLUSTER)
-		{
-			curWorkDirCluster = filesysRootDirClus;
-		}
-
-		// Reset file position in directory
-		wrkDirCluster = curWorkDirCluster;
-		wrkDirSector = 0;
-		wrkDirOffset = -1;
-		return true;
-	}
-	else
-	{
-		// Couldn't change directory - wrong path specified
-		return false;
-	}
-}
-
-/*-----------------------------------------------------------------
-FAT_fopen(filename, mode)
-Opens a file
-const char* path: IN null terminated string of filename and path
-	separated by forward slashes, / is root
-const char* mode: IN mode to open file in
-	Supported modes: "r", "r+", "w", "w+", "a", "a+", don't use
-	"b" or "t" in any mode, as all files are openned in binary mode
-FAT_FILE* return: OUT handle to open file, returns NULL if the file
-	couldn't be openned
------------------------------------------------------------------*/
-FAT_FILE* FAT_fopen(const char* path, const char* mode)
-{
-	int fileNum;
-	FAT_FILE* file;
-	DIR_ENT dirEntry;
-#ifdef CAN_WRITE_TO_DISC
-	u32 startCluster;
-	int clusCount;
-#endif
-
-	char* pchTemp;
-	// Check that a valid mode was specified
-	pchTemp = strpbrk ( mode, "rRwWaA" );
-	if (pchTemp == NULL)
-	{
-		return NULL;
-	}
-	if (strpbrk ( pchTemp+1, "rRwWaA" ) != NULL)
-	{
-		return NULL;
-	}
-
-	// Get the dirEntry for the path specified
-	dirEntry = FAT_DirEntFromPath (path);
-
-	// Check that it is not a directory
-	if (dirEntry.attrib & ATTRIB_DIR)
-	{
-		return NULL;
-	}
-
-#ifdef CAN_WRITE_TO_DISC
-	// Check that it is not a read only file being openned in a writing mode
-	if ( (strpbrk(mode, "wWaA+") != NULL) && (dirEntry.attrib & ATTRIB_RO))
-	{
-		return NULL;
-	}
-#else
-	if ( (strpbrk(mode, "wWaA+") != NULL))
-	{
-		return NULL;
-	}
-#endif
-
-	// Find a free file buffer
-	for (fileNum = 0; (fileNum < MAX_FILES_OPEN) && (openFiles[fileNum].inUse == true); fileNum++);
-
-	if (fileNum == MAX_FILES_OPEN) // No free files
-	{
-		return NULL;
-	}
-
-	file = &openFiles[fileNum];
-	// Remember where directory entry was
-	file->dirEntSector = (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector;
-	file->dirEntOffset = wrkDirOffset;
-
-	if ( strpbrk(mode, "rR") != NULL )  //(ucase(mode[0]) == 'R')
-	{
-		if (dirEntry.name[0] == FILE_FREE)	// File must exist
-		{
-			return NULL;
-		}
-
-		file->read = true;
-#ifdef CAN_WRITE_TO_DISC
-		file->write = ( strchr(mode, '+') != NULL ); //(mode[1] == '+');
-#else
-		file->write = false;
-#endif
-		file->append = false;
-
-		// Store information about position within the file, for use
-		// by FAT_fread, FAT_fseek, etc.
-		file->firstCluster = dirEntry.startCluster | (dirEntry.startClusterHigh << 16);
-
-#ifdef CAN_WRITE_TO_DISC
-		// Check if file is openned for random. If it is, and currently has no cluster, one must be
-		// assigned to it.
-		if (file->write && file->firstCluster == CLUSTER_FREE)
-		{
-			file->firstCluster = FAT_LinkFreeCluster (CLUSTER_FREE);
-			if (file->firstCluster == CLUSTER_FREE)	// Couldn't get a free cluster
-			{
-				return NULL;
-			}
-
-			// Store cluster position into the directory entry
-			dirEntry.startCluster = (file->firstCluster & 0xFFFF);
-			dirEntry.startClusterHigh = ((file->firstCluster >> 16) & 0xFFFF);
-			disc_ReadSector (file->dirEntSector, globalBuffer);
-			((DIR_ENT*) globalBuffer)[file->dirEntOffset] = dirEntry;
-			disc_WriteSector (file->dirEntSector, globalBuffer);
-		}
-#endif
-
-		file->length = dirEntry.fileSize;
-		file->curPos = 0;
-		file->curClus = dirEntry.startCluster | (dirEntry.startClusterHigh << 16);
-		file->curSect = 0;
-		file->curByte = 0;
-
-		// Not appending
-		file->appByte = 0;
-		file->appClus = 0;
-		file->appSect = 0;
-
-		disc_ReadSector( FAT_ClustToSect( file->curClus), file->readBuffer);
-		file->inUse = true;	// We're using this file now
-
-		return file;
-	}	// mode "r"
-
-#ifdef CAN_WRITE_TO_DISC
-	if ( strpbrk(mode, "wW") != NULL ) // (ucase(mode[0]) == 'W')
-	{
-		if (dirEntry.name[0] == FILE_FREE)	// Create file if it doesn't exist
-		{
-			dirEntry.attrib = ATTRIB_ARCH;
-			dirEntry.reserved = 0;
-
-			// Time and date set to system time and date
-			dirEntry.cTime_ms = 0;
-			dirEntry.cTime = getRTCtoFileTime();
-			dirEntry.cDate = getRTCtoFileDate();
-			dirEntry.aDate = getRTCtoFileDate();
-			dirEntry.mTime = getRTCtoFileTime();
-			dirEntry.mDate = getRTCtoFileDate();
-		}
-		else	// Already a file entry
-		{
-			// Free any clusters used
-			FAT_ClearLinks (dirEntry.startCluster | (dirEntry.startClusterHigh << 16));
-		}
-
-		// Get a cluster to use
-		startCluster = FAT_LinkFreeCluster (CLUSTER_FREE);
-		if (startCluster == CLUSTER_FREE)	// Couldn't get a free cluster
-		{
-			return NULL;
-		}
-
-		// Store cluster position into the directory entry
-		dirEntry.startCluster = (startCluster & 0xFFFF);
-		dirEntry.startClusterHigh = ((startCluster >> 16) & 0xFFFF);
-
-		// The file has no data in it - its over written so should be empty
-		dirEntry.fileSize = 0;
-
-		if (dirEntry.name[0] == FILE_FREE)	// No file
-		{
-			// Have to create a new entry
-			if(!FAT_AddDirEntry (path, dirEntry))
-			{
-				return NULL;
-			}
-			// Get the newly created dirEntry
-			dirEntry = FAT_DirEntFromPath (path);
-
-			// Remember where directory entry was
-			file->dirEntSector = (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector;
-			file->dirEntOffset = wrkDirOffset;
-		}
-		else	// Already a file
-		{
-			// Just modify the old entry
-			disc_ReadSector (file->dirEntSector, globalBuffer);
-			((DIR_ENT*) globalBuffer)[file->dirEntOffset] = dirEntry;
-			disc_WriteSector (file->dirEntSector, globalBuffer);
-		}
-
-
-		// Now that file is created, open it
-		file->read = ( strchr(mode, '+') != NULL ); //(mode[1] == '+');
-		file->write = true;
-		file->append = false;
-
-		// Store information about position within the file, for use
-		// by FAT_fread, FAT_fseek, etc.
-		file->firstCluster = startCluster;
-		file->length = 0;	// Should always have 0 bytes if openning in "w" mode
-		file->curPos = 0;
-		file->curClus = startCluster;
-		file->curSect = 0;
-		file->curByte = 0;
-
-		// Not appending
-		file->appByte = 0;
-		file->appClus = 0;
-		file->appSect = 0;
-
-		// Empty file, so empty read buffer
-		memset (file->readBuffer, 0, BYTE_PER_READ);
-		file->inUse = true;	// We're using this file now
-
-		return file;
-	}
-
-	if ( strpbrk(mode, "aA") != NULL ) // (ucase(mode[0]) == 'A')
-	{
-		if (dirEntry.name[0] == FILE_FREE)	// Create file if it doesn't exist
-		{
-			dirEntry.attrib = ATTRIB_ARCH;
-			dirEntry.reserved = 0;
-
-			// Time and date set to system time and date
-			dirEntry.cTime_ms = 0;
-			dirEntry.cTime = getRTCtoFileTime();
-			dirEntry.cDate = getRTCtoFileDate();
-			dirEntry.aDate = getRTCtoFileDate();
-			dirEntry.mTime = getRTCtoFileTime();
-			dirEntry.mDate = getRTCtoFileDate();
-
-			// The file has no data in it
-			dirEntry.fileSize = 0;
-
-			// Get a cluster to use
-			startCluster = FAT_LinkFreeCluster (CLUSTER_FREE);
-			if (startCluster == CLUSTER_FREE)	// Couldn't get a free cluster
-			{
-				return NULL;
-			}
-			dirEntry.startCluster = (startCluster & 0xFFFF);
-			dirEntry.startClusterHigh = ((startCluster >> 16) & 0xFFFF);
-
-			if(!FAT_AddDirEntry (path, dirEntry))
-				return NULL;
-
-			// Get the newly created dirEntry
-			dirEntry = FAT_DirEntFromPath (path);
-
-			// Store append cluster
-			file->appClus = startCluster;
-
-			// Remember where directory entry was
-			file->dirEntSector = (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector;
-			file->dirEntOffset = wrkDirOffset;
-		}
-		else	// File already exists - reuse the old directory entry
-		{
-			startCluster = dirEntry.startCluster | (dirEntry.startClusterHigh << 16);
-			// If it currently has no cluster, one must be assigned to it.
-			if (startCluster == CLUSTER_FREE)
-			{
-				file->firstCluster = FAT_LinkFreeCluster (CLUSTER_FREE);
-				if (file->firstCluster == CLUSTER_FREE)	// Couldn't get a free cluster
-				{
-					return NULL;
-				}
-
-				// Store cluster position into the directory entry
-				dirEntry.startCluster = (file->firstCluster & 0xFFFF);
-				dirEntry.startClusterHigh = ((file->firstCluster >> 16) & 0xFFFF);
-				disc_ReadSector (file->dirEntSector, globalBuffer);
-				((DIR_ENT*) globalBuffer)[file->dirEntOffset] = dirEntry;
-				disc_WriteSector (file->dirEntSector, globalBuffer);
-
-				// Store append cluster
-				file->appClus = startCluster;
-
-			} else {
-
-				// Follow cluster list until last one is found
-				clusCount = dirEntry.fileSize / filesysBytePerClus;
-				file->appClus = startCluster;
-				while ((clusCount--) && (FAT_NextCluster (file->appClus) != CLUSTER_FREE) && (FAT_NextCluster (file->appClus) != CLUSTER_EOF))
-				{
-					file->appClus = FAT_NextCluster (file->appClus);
-				}
-				if (clusCount >= 0) // Check if ran out of clusters
-				{
-					// Set flag to allocate new cluster when needed
-					file->appSect = filesysSecPerClus;
-					file->appByte = 0;
-				}
-			}
-		}
-
-		// Now that file is created, open it
-		file->read = ( strchr(mode, '+') != NULL );
-		file->write = false;
-		file->append = true;
-
-		// Calculate the sector and byte of the current position,
-		// and store them
-		file->appSect = (dirEntry.fileSize % filesysBytePerClus) / BYTE_PER_READ;
-		file->appByte = dirEntry.fileSize % BYTE_PER_READ;
-
-		// Store information about position within the file, for use
-		// by FAT_fread, FAT_fseek, etc.
-		file->firstCluster = startCluster;
-		file->length = dirEntry.fileSize;
-		file->curPos = dirEntry.fileSize;
-		file->curClus = file->appClus;
-		file->curSect = file->appSect;
-		file->curByte = file->appByte;
-
-		// Read into buffer
-		disc_ReadSector( FAT_ClustToSect(file->curClus) + file->curSect, file->readBuffer);
-		file->inUse = true;	// We're using this file now
-		return file;
-	}
-#endif
-
-	// Can only reach here if a bad mode was specified
-	return NULL;
-}
-
-/*-----------------------------------------------------------------
-FAT_fclose(file)
-Closes a file
-FAT_FILE* file: IN handle of the file to close
-bool return OUT: true if successful, false if not
------------------------------------------------------------------*/
-bool FAT_fclose (FAT_FILE* file)
-{
-	// Clear memory used by file information
-	if ((file != NULL) && (file->inUse == true))
-	{
-#ifdef CAN_WRITE_TO_DISC
-		if (file->write || file->append)
-		{
-			// Write new length, time and date back to directory entry
-			disc_ReadSector (file->dirEntSector, globalBuffer);
-
-			((DIR_ENT*)globalBuffer)[file->dirEntOffset].fileSize = file->length;
-			((DIR_ENT*)globalBuffer)[file->dirEntOffset].mTime = getRTCtoFileTime();
-			((DIR_ENT*)globalBuffer)[file->dirEntOffset].mDate = getRTCtoFileDate();
-			((DIR_ENT*)globalBuffer)[file->dirEntOffset].aDate = getRTCtoFileDate();
-
-			disc_WriteSector (file->dirEntSector, globalBuffer);
-
-			// Flush any sectors in disc cache
-			disc_CacheFlush();
-		}
-#endif
-		file->inUse = false;
-		return true;
-	}
-	else
-	{
-		return false;
-	}
-}
-
-/*-----------------------------------------------------------------
-FAT_ftell(file)
-Returns the current position in a file
-FAT_FILE* file: IN handle of an open file
-u32 OUT: Current position
------------------------------------------------------------------*/
-u32 FAT_ftell (FAT_FILE* file)
-{
-	// Return the position as specified in the FAT_FILE structure
-	if ((file != NULL) && (file->inUse == true))
-	{
-		return file->curPos;
-	}
-	else
-	{
-		// Return -1 if no file was given
-		return -1;
-	}
-}
-
-/*-----------------------------------------------------------------
-FAT_fseek(file, offset, origin)
-Seeks to specified byte position in file
-FAT_FILE* file: IN handle of an open file
-s32 offset IN: position to seek to, relative to origin
-int origin IN: origin to seek from
-int OUT: Returns 0 if successful, -1 if not
------------------------------------------------------------------*/
-int FAT_fseek(FAT_FILE* file, s32 offset, int origin)
-{
-	u32 cluster, nextCluster;
-	int clusCount;
-	u32 position;
-	u32 curPos;
-
-
-	if ((file == NULL) || (file->inUse == false))	// invalid file
-	{
-		return -1;
-	}
-
-	// Can't seek in append only mode
-	if (!file->read && !file->write)
-	{
-		return -1;
-	}
-
-	curPos = file->curPos;
-
-	switch (origin)
-	{
-	case SEEK_SET:
-		if (offset >= 0)
-		{
-			position = offset;
-		} else {
-			// Tried to seek before start of file
-			position = 0;
-		}
-		break;
-	case SEEK_CUR:
-		if (offset >= 0)
-		{
-			position = curPos + offset;
-		}
-		else if ( (u32)(offset * -1) >= curPos )
-		{
-			// Tried to seek before start of file
-			position = 0;
-		}
-		else
-		{
-			// Using u32 to maintain 32 bits of accuracy
-			position = curPos - (u32)(offset * -1);
-		}
-		break;
-	case SEEK_END:
-		if (offset >= 0)
-		{
-			// Seeking to end of file
-			position = file->length;	// Fixed thanks to MoonLight
-		}
-		else if ( (u32)(offset * -1) >= file->length )
-		{
-			// Tried to seek before start of file
-			position = 0;
-		}
-		else
-		{
-			// Using u32 to maintain 32 bits of accuracy
-			position = file->length - (u32)(offset * -1);
-		}
-		break;
-	default:
-		return -1;
-	}
-
-	if (position > file->length)
-	{
-		// Tried to go past end of file
-		position = file->length;
-	}
-
-	// Save position
-	file->curPos = position;
-
-
-	// Calculate where the correct cluster is
-	if (position > curPos)
-	{
-		clusCount = (position - curPos + (file->curSect * filesysBytePerSec) + file->curByte) / filesysBytePerClus;	// Fixed thanks to AgentQ
-		cluster = file->curClus;
-	} else {
-		clusCount = position / filesysBytePerClus;
-		cluster = file->firstCluster;
-	}
-
-	// Calculate the sector and byte of the current position,
-	// and store them
-	file->curSect = (position % filesysBytePerClus) / BYTE_PER_READ;
-	file->curByte = position % BYTE_PER_READ;
-
-	// Follow cluster list until desired one is found
-	if (clusCount > 0)	// Only look at next cluster if need to
-	{
-		nextCluster = FAT_NextCluster (cluster);
-	} else {
-		nextCluster = cluster;
-	}
-	while ((clusCount--) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF))
-	{
-		cluster = nextCluster;
-		nextCluster = FAT_NextCluster (cluster);
-	}
-	// Check if ran out of clusters, and the file is being written to
-	if ((clusCount >= 0) && (file->write || file->append))
-	{
-		// Set flag to allocate a new cluster
-		file->curSect = filesysSecPerClus;
-		file->curByte = 0;
-	}
-	file->curClus = cluster;
-
-	// Reload sector buffer for new position in file, if it is a different sector
-	if ((curPos ^ position) >= BYTE_PER_READ)
-	{
-		disc_ReadSector( file->curSect + FAT_ClustToSect(file->curClus), file->readBuffer);
-	}
-
-	return 0;
-
-}
-
-/*-----------------------------------------------------------------
-FAT_fread(buffer, size, count, file)
-Reads in size * count bytes into buffer from file, starting
-	from current position. It then sets the current position to the
-	byte after the last byte read. If it reaches the end of file
-	before filling the buffer then it stops reading.
-void* buffer OUT: Pointer to buffer to fill. Should be at least as
-	big as the number of bytes required
-u32 size IN: size of each item to read
-u32 count IN: number of items to read
-FAT_FILE* file IN: Handle of an open file
-u32 OUT: returns the actual number of bytes read
------------------------------------------------------------------*/
-u32 FAT_fread (void* buffer, u32 size, u32 count, FAT_FILE* file)
-{
-	int curByte;
-	int curSect;
-	u32 curClus;
-	u32 tempNextCluster;
-
-	int tempVar;
-
-	char* data = (char*)buffer;
-
-	u32 length = size * count;
-	u32 remain;
-
-	bool flagNoError = true;
-
-	// Can't read non-existant files
-	if ((file == NULL) || (file->inUse == false) || size == 0 || count == 0 || buffer == NULL)
-		return 0;
-
-	// Can only read files openned for reading
-	if (!file->read)
-		return 0;
-
-	// Don't read past end of file
-	if (length + file->curPos > file->length)
-		length = file->length - file->curPos;
-
-	remain = length;
-
-	curByte = file->curByte;
-	curSect = file->curSect;
-	curClus = file->curClus;
-
-	// Align to sector
-	tempVar = BYTE_PER_READ - curByte;
-	if (tempVar > remain)
-		tempVar = remain;
-
-	if ((tempVar < BYTE_PER_READ) && flagNoError)
-	{
-		memcpy(data, &(file->readBuffer[curByte]), tempVar);
-		remain -= tempVar;
-		data += tempVar;
-
-		curByte += tempVar;
-		if (curByte >= BYTE_PER_READ)
-		{
-			curByte = 0;
-			curSect++;
-		}
-	}
-
-	// align to cluster
-	// tempVar is number of sectors to read
-	if (remain > (filesysSecPerClus - curSect) * BYTE_PER_READ)
-	{
-		tempVar = filesysSecPerClus - curSect;
-	} else {
-		tempVar = remain / BYTE_PER_READ;
-	}
-
-	if ((tempVar > 0) && flagNoError)
-	{
-		disc_ReadSectors ( curSect + FAT_ClustToSect(curClus), tempVar, data);
-		data += tempVar * BYTE_PER_READ;
-		remain -= tempVar * BYTE_PER_READ;
-
-		curSect += tempVar;
-	}
-
-	// Move onto next cluster
-	// It should get to here without reading anything if a cluster is due to be allocated
-	if (curSect >= filesysSecPerClus)
-	{
-		tempNextCluster = FAT_NextCluster(curClus);
-		if ((remain == 0) && (tempNextCluster == CLUSTER_EOF))
-		{
-			curSect = filesysSecPerClus;
-		} else {
-			curSect = 0;
-			curClus = tempNextCluster;
-			if (curClus == CLUSTER_FREE)
-			{
-				flagNoError = false;
-			}
-		}
-	}
-
-	// Read in whole clusters
-	while ((remain >= filesysBytePerClus) && flagNoError)
-	{
-		disc_ReadSectors (FAT_ClustToSect(curClus), filesysSecPerClus, data);
-		data += filesysBytePerClus;
-		remain -= filesysBytePerClus;
-
-		// Advance to next cluster
-		tempNextCluster = FAT_NextCluster(curClus);
-		if ((remain == 0) && (tempNextCluster == CLUSTER_EOF))
-		{
-			curSect = filesysSecPerClus;
-		} else {
-			curSect = 0;
-			curClus = tempNextCluster;
-			if (curClus == CLUSTER_FREE)
-			{
-				flagNoError = false;
-			}
-		}
-	}
-
-	// Read remaining sectors
-	tempVar = remain / BYTE_PER_READ; // Number of sectors left
-	if ((tempVar > 0) && flagNoError)
-	{
-		disc_ReadSectors (FAT_ClustToSect(curClus), tempVar, data);
-		data += tempVar * BYTE_PER_READ;
-		remain -= tempVar * BYTE_PER_READ;
-		curSect += tempVar;
-	}
-
-	// Last remaining sector
-	// Check if sector wanted is different to the one started with
-	if ( ((file->curByte + length) >= BYTE_PER_READ) && flagNoError)
-	{
-		disc_ReadSector( curSect + FAT_ClustToSect( curClus), file->readBuffer);
-		if (remain > 0)
-		{
-			memcpy(data, file->readBuffer, remain);
-			curByte += remain;
-			remain = 0;
-		}
-	}
-
-	// Length read is the wanted length minus the stuff not read
-	length = length - remain;
-
-	// Update file information
-	file->curByte = curByte;
-	file->curSect = curSect;
-	file->curClus = curClus;
-	file->curPos = file->curPos + length;
-	return length;
-}
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_fwrite(buffer, size, count, file)
-Writes size * count bytes into file from buffer, starting
-	from current position. It then sets the current position to the
-	byte after the last byte written. If the file was openned in
-	append mode it always writes to the end of the file.
-const void* buffer IN: Pointer to buffer containing data. Should be
-	at least as big as the number of bytes to be written.
-u32 size IN: size of each item to write
-u32 count IN: number of items to write
-FAT_FILE* file IN: Handle of an open file
-u32 OUT: returns the actual number of bytes written
------------------------------------------------------------------*/
-u32 FAT_fwrite (const void* buffer, u32 size, u32 count, FAT_FILE* file)
-{
-	int curByte;
-	int curSect;
-	u32 curClus;
-
-	u32 tempNextCluster;
-	int tempVar;
-	u32 length = size * count;
-	u32 remain = length;
-	char* data = (char*)buffer;
-
-	char* writeBuffer;
-
-	bool flagNoError = true;
-	bool flagAppending = false;
-
-	if ((file == NULL) || (file->inUse == false) || length == 0 || buffer == NULL)
-		return 0;
-
-	if (file->write)
-	{
-		// Write at current read pointer
-		curByte = file->curByte;
-		curSect = file->curSect;
-		curClus = file->curClus;
-
-		// Use read buffer as write buffer
-		writeBuffer = file->readBuffer;
-
-		// If it is writing past the current end of file, set appending flag
-		if (length + file->curPos > file->length)
-		{
-			flagAppending = true;
-		}
-	}
-	else if (file->append)
-	{
-		// Write at end of file
-		curByte = file->appByte;
-		curSect = file->appSect;
-		curClus = file->appClus;
-		flagAppending = true;
-
-		// Use global buffer as write buffer, don't touch read buffer
-		writeBuffer = (char*)globalBuffer;
-		disc_ReadSector(curSect + FAT_ClustToSect(curClus), writeBuffer);
-	}
-	else
-	{
-		return 0;
-	}
-
-	// Move onto next cluster if needed
-	if (curSect >= filesysSecPerClus)
-	{
-		curSect = 0;
-		tempNextCluster = FAT_NextCluster(curClus);
-		if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE))
-		{
-			// Ran out of clusters so get a new one
-			curClus = FAT_LinkFreeCluster(curClus);
-			if (curClus == CLUSTER_FREE) // Couldn't get a cluster, so abort
-			{
-				flagNoError = false;
-			}
-			memset(writeBuffer, 0, BYTE_PER_READ);
-		} else {
-			curClus = tempNextCluster;
-			disc_ReadSector( FAT_ClustToSect( curClus), writeBuffer);
-		}
-	}
-
-	// Align to sector
-	tempVar = BYTE_PER_READ - curByte;
-	if (tempVar > remain)
-		tempVar = remain;
-
-	if ((tempVar < BYTE_PER_READ) && flagNoError)
-	{
-		memcpy(&(writeBuffer[curByte]), data, tempVar);
-		remain -= tempVar;
-		data += tempVar;
-		curByte += tempVar;
-
-		// Write buffer back to disk
-		disc_WriteSector (curSect + FAT_ClustToSect(curClus), writeBuffer);
-
-		// Move onto next sector
-		if (curByte >= BYTE_PER_READ)
-		{
-			curByte = 0;
-			curSect++;
-		}
-	}
-
-	// Align to cluster
-	// tempVar is number of sectors to write
-	if (remain > (filesysSecPerClus - curSect) * BYTE_PER_READ)
-	{
-		tempVar = filesysSecPerClus - curSect;
-	} else {
-		tempVar = remain / BYTE_PER_READ;
-	}
-
-	if ((tempVar > 0) && flagNoError)
-	{
-		disc_WriteSectors ( curSect + FAT_ClustToSect(curClus), tempVar, data);
-		data += tempVar * BYTE_PER_READ;
-		remain -= tempVar * BYTE_PER_READ;
-		curSect += tempVar;
-	}
-
-	if (((curSect >= filesysSecPerClus) && flagNoError) && (remain > 0))
-	{
-		curSect = 0;
-		tempNextCluster = FAT_NextCluster(curClus);
-		if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE))
-		{
-			// Ran out of clusters so get a new one
-			curClus = FAT_LinkFreeCluster(curClus);
-			if (curClus == CLUSTER_FREE) // Couldn't get a cluster, so abort
-			{
-				flagNoError = false;
-			}
-		} else {
-			curClus = tempNextCluster;
-		}
-	}
-
-	// Write whole clusters
-	while ((remain >= filesysBytePerClus) && flagNoError)
-	{
-		disc_WriteSectors (FAT_ClustToSect(curClus), filesysSecPerClus, data);
-		data += filesysBytePerClus;
-		remain -= filesysBytePerClus;
-		if (remain > 0)
-		{
-			tempNextCluster = FAT_NextCluster(curClus);
-			if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE))
-			{
-				// Ran out of clusters so get a new one
-				curClus = FAT_LinkFreeCluster(curClus);
-				if (curClus == CLUSTER_FREE) // Couldn't get a cluster, so abort
-				{
-					flagNoError = false;
-					break;
-				}
-			} else {
-				curClus = tempNextCluster;
-			}
-		} else {
-			// Allocate a new cluster when next writing the file
-			curSect = filesysSecPerClus;
-		}
-	}
-
-	// Write remaining sectors
-	tempVar = remain / BYTE_PER_READ; // Number of sectors left
-	if ((tempVar > 0) && flagNoError)
-	{
-		disc_WriteSectors (FAT_ClustToSect(curClus), tempVar, data);
-		data += tempVar * BYTE_PER_READ;
-		remain -= tempVar * BYTE_PER_READ;
-		curSect += tempVar;
-	}
-
-	// Last remaining sector
-	// Check if sector wanted is different to the one started with
-	if ( (( (file->append ? file->appByte : file->curByte) + length) >= BYTE_PER_READ) && flagNoError)
-	{
-		if (flagAppending)
-		{
-			// Zero sector before using it
-			memset (writeBuffer, 0, BYTE_PER_READ);
-		} else {
-			// Modify existing sector
-			disc_ReadSector( curSect + FAT_ClustToSect( curClus), writeBuffer);
-		}
-		if (remain > 0) {
-			memcpy(writeBuffer, data, remain);
-			curByte += remain;
-			remain = 0;
-			disc_WriteSector( curSect + FAT_ClustToSect( curClus), writeBuffer);
-		}
-	}
-
-	// Amount read is the originally requested amount minus stuff remaining
-	length = length - remain;
-
-	// Update file information
-	if (file->write)	// Writing also shifts the read pointer
-	{
-		file->curByte = curByte;
-		file->curSect = curSect;
-		file->curClus = curClus;
-		file->curPos = file->curPos + length;
-		if (file->length < file->curPos)
-		{
-			file->length = file->curPos;
-		}
-	}
-	else if (file->append)	// Appending doesn't affect the read pointer
-	{
-		file->appByte = curByte;
-		file->appSect = curSect;
-		file->appClus = curClus;
-		file->length = file->length + length;
-	}
-
-	return length;
-}
-#endif
-
-
-/*-----------------------------------------------------------------
-FAT_feof(file)
-Returns true if the end of file has been reached
-FAT_FILE* file IN: Handle of an open file
-bool return OUT: true if EOF, false if not
------------------------------------------------------------------*/
-bool FAT_feof(FAT_FILE* file)
-{
-	if ((file == NULL) || (file->inUse == false))
-		return true;	// Return eof on invalid files
-
-	return (file->length == file->curPos);
-}
-
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_remove (path)
-Deletes the file or empty directory sepecified in path
-const char* path IN: Path of item to delete
-int return OUT: zero if successful, non-zero if not
------------------------------------------------------------------*/
-int FAT_remove (const char* path)
-{
-	DIR_ENT dirEntry;
-	u32 oldWorkDirCluster;
-	char checkFilename[13];
-	FILE_TYPE checkFiletype;
-
-	dirEntry = FAT_DirEntFromPath (path);
-
-	if (dirEntry.name[0] == FILE_FREE)
-	{
-		return -1;
-	}
-
-	// Only delete directories if the directory is entry
-	if (dirEntry.attrib & ATTRIB_DIR)
-	{
-		// Change to the directory temporarily
-		oldWorkDirCluster = curWorkDirCluster;
-		FAT_chdir(path);
-
-		// Search for files or directories, excluding the . and .. entries
-		checkFiletype = FAT_FindFirstFile (checkFilename);
-		while ((checkFilename[0] == '.')  && (checkFiletype != FT_NONE))
-		{
-			checkFiletype = FAT_FindNextFile (checkFilename);
-		}
-
-		// Change back to working directory
-		curWorkDirCluster = oldWorkDirCluster;
-
-		// Check that the directory is empty
-		if (checkFiletype != FT_NONE)
-		{
-			// Directory isn't empty
-			return -1;
-		}
-	}
-
-	// Refresh directory information
-	dirEntry = FAT_DirEntFromPath (path);
-
-	// Free any clusters used
-	FAT_ClearLinks (dirEntry.startCluster | (dirEntry.startClusterHigh << 16));
-
-	// Remove Directory entry
-	disc_ReadSector ( (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector , globalBuffer);
-	((DIR_ENT*)globalBuffer)[wrkDirOffset].name[0] = FILE_FREE;
-	disc_WriteSector ( (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector , globalBuffer);
-
-	// Flush any sectors in disc cache
-	disc_CacheFlush();
-
-	return 0;
-}
-#endif
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_mkdir (path)
-Makes a new directory, so long as no other directory or file has
-	the same name.
-const char* path IN: Path and filename of directory to make
-int return OUT: zero if successful, non-zero if not
------------------------------------------------------------------*/
-int FAT_mkdir (const char* path)
-{
-	u32 newDirCluster;
-	u32 parentDirCluster;
-	DIR_ENT dirEntry;
-	DIR_ENT* entries = (DIR_ENT*)globalBuffer;
-	int i;
-
-	int pathPos, filePos;
-	char pathname[MAX_FILENAME_LENGTH];
-	u32 oldDirCluster;
-
-	if (FAT_FileExists(path) != FT_NONE)
-	{
-		return -1;	// File or directory exists with that name
-	}
-
-	// Find filename within path and change to that directory
-	oldDirCluster = curWorkDirCluster;
-	if (path[0] == '/')
-	{
-		curWorkDirCluster = filesysRootDirClus;
-	}
-
-	pathPos = 0;
-	filePos = 0;
-
-	while (path[pathPos + filePos] != '\0')
-	{
-		if (path[pathPos + filePos] == '/')
-		{
-			pathname[filePos] = '\0';
-			if (FAT_chdir(pathname) == false)
-			{
-				curWorkDirCluster = oldDirCluster;
-				return -1; // Couldn't change directory
-			}
-			pathPos += filePos + 1;
-			filePos = 0;
-		}
-		pathname[filePos] = path[pathPos + filePos];
-		filePos++;
-	}
-
-	// Now grab the parent directory's cluster
-	parentDirCluster = curWorkDirCluster;
-	curWorkDirCluster = oldDirCluster;
-
-	// Get a new cluster for the file
-	newDirCluster = FAT_LinkFreeCluster(CLUSTER_FREE);
-
-	if (newDirCluster == CLUSTER_FREE)
-	{
-		return -1;	// Couldn't get a new cluster for the directory
-	}
-	// Fill in directory entry's information
-	dirEntry.attrib = ATTRIB_DIR;
-	dirEntry.reserved = 0;
-	// Time and date set to system time and date
-	dirEntry.cTime_ms = 0;
-	dirEntry.cTime = getRTCtoFileTime();
-	dirEntry.cDate = getRTCtoFileDate();
-	dirEntry.aDate = getRTCtoFileDate();
-	dirEntry.mTime = getRTCtoFileTime();
-	dirEntry.mDate = getRTCtoFileDate();
-	// Store cluster position into the directory entry
-	dirEntry.startCluster = (newDirCluster & 0xFFFF);
-	dirEntry.startClusterHigh = ((newDirCluster >> 16) & 0xFFFF);
-	// The file has no data in it - its over written so should be empty
-	dirEntry.fileSize = 0;
-
-	if (FAT_AddDirEntry (path, dirEntry) == false)
-	{
-		return -1;	// Couldn't add the directory entry
-	}
-
-	// Create the new directory itself
-	memset(entries, FILE_LAST, BYTE_PER_READ);
-
-	// Create . directory entry
-	dirEntry.name[0] = '.';
-	// Fill name and extension with spaces
-	for (i = 1; i < (sizeof(dirEntry.name)/sizeof(dirEntry.name[0])); i++)
-	{
-		dirEntry.name[i] = ' ';
-	}
-
-	memcpy(entries, &dirEntry, sizeof(dirEntry));
-
-	// Create .. directory entry
-	dirEntry.name[1] = '.';
-	dirEntry.startCluster = (parentDirCluster & 0xFFFF);
-	dirEntry.startClusterHigh = ((parentDirCluster >> 16) & 0xFFFF);
-
-	memcpy(&entries[1], &dirEntry, sizeof(dirEntry));
-
-	// Write entry to disc
-	disc_WriteSector(FAT_ClustToSect(newDirCluster), entries);
-
-	// Flush any sectors in disc cache
-	disc_CacheFlush();
-	return 0;
-}
-#endif
-
-/*-----------------------------------------------------------------
-FAT_fgetc (handle)
-Gets the next character in the file
-FAT_FILE* file IN: Handle of open file
-bool return OUT: character if successful, EOF if not
------------------------------------------------------------------*/
-char FAT_fgetc (FAT_FILE* file)
-{
-	char c;
-	return (FAT_fread(&c, 1, 1, file) == 1) ? c : EOF;
-}
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_fputc (character, handle)
-Writes the given character into the file
-char c IN: Character to be written
-FAT_FILE* file IN: Handle of open file
-bool return OUT: character if successful, EOF if not
------------------------------------------------------------------*/
-char FAT_fputc (char c, FAT_FILE* file)
-{
-	return (FAT_fwrite(&c, 1, 1, file) == 1) ? c : EOF;
-}
-#endif
-
-/*-----------------------------------------------------------------
-FAT_fgets (char *tgtBuffer, int num, FAT_FILE* file)
-Gets a up to num bytes from file, stopping at the first
- newline.
-
-CAUTION: does not do strictly streaming. I.e. it's
- reading more then needed bytes and seeking back.
- shouldn't matter for random access
-
-char *tgtBuffer OUT: buffer to write to
-int num IN: size of target buffer
-FAT_FILE* file IN: Handle of open file
-bool return OUT: character if successful, EOF if not
-
-  Written by MightyMax
-  Modified by Chishm - 2005-11-17
-	* Added check for unix style text files
-	* Removed seek when no newline is found, since it isn't necessary
--------------------------------------------------------------------*/
-char *FAT_fgets(char *tgtBuffer, int num, FAT_FILE* file)
-{
-	u32 curPos;
-	u32 readLength;
-	char *returnChar;
-
-	// invalid filehandle
-	if (file == NULL)
-	{
-		return NULL ;
-	}
-
-	// end of file
-	if (FAT_feof(file)==true)
-	{
-		return NULL ;
-	}
-
-	// save current position
-	curPos = FAT_ftell(file);
-
-	// read the full buffer (max string chars is num-1 and one end of string \0
-	readLength = FAT_fread(tgtBuffer,1,num-1,file) ;
-
-	// mark least possible end of string
-	tgtBuffer[readLength] = '\0' ;
-
-	if (readLength==0) {
-		// return error
-		return NULL ;
-	}
-
-	// get position of first return '\r'
-	returnChar = strchr(tgtBuffer,'\r');
-
-	// if no return is found, search for a newline
-	if (returnChar == NULL)
-	{
-		returnChar = strchr(tgtBuffer,'\n');
-	}
-
-	// Mark the return, if existant, as end of line/string
-	if (returnChar!=NULL) {
-		*returnChar++ = 0 ;
-		if (*returnChar=='\n') { // catch newline too when jumping over the end
-			// return to location after \r\n (strlen+2)
-			FAT_fseek(file,curPos+strlen(tgtBuffer)+2,SEEK_SET) ;
-			return tgtBuffer ;
-		} else {
-			// return to location after \r (strlen+1)
-			FAT_fseek(file,curPos+strlen(tgtBuffer)+1,SEEK_SET) ;
-			return tgtBuffer ;
-		}
-	}
-
-	return tgtBuffer ;
-}
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_fputs (const char *string, FAT_FILE* file)
-Writes string to file, excluding end of string character
-const char *string IN: string to write
-FAT_FILE* file IN: Handle of open file
-bool return OUT: number of characters written if successful,
-	EOF if not
-
-  Written by MightyMax
-  Modified by Chishm - 2005-11-17
-	* Uses FAT_FILE instead of int
-	* writtenBytes is now u32 instead of int
--------------------------------------------------------------------*/
-int FAT_fputs (const char *string, FAT_FILE* file)
-{
-   u32 writtenBytes;
-	// save string except end of string '\0'
-   writtenBytes = FAT_fwrite((void *)string, 1, strlen(string), file);
-
-   // check if we had an error
-   if (writtenBytes != strlen(string))
-   {
-      // return EOF error
-      return EOF;
-   }
-
-   // return the charcount written
-   return writtenBytes ;
-}
-#endif
diff --git a/backends/platform/ds/arm9/source/fat/gba_nds_fat.h b/backends/platform/ds/arm9/source/fat/gba_nds_fat.h
deleted file mode 100644
index dd5c8ba85f..0000000000
--- a/backends/platform/ds/arm9/source/fat/gba_nds_fat.h
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
-	gba_nds_fat.h
-	By chishm (Michael Chisholm)
-
-	Routines for reading a compact flash card
-	using the GBA Movie Player or M3.
-
-	Some FAT routines are based on those in fat.c, which
-	is part of avrlib by Pascal Stang.
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-//---------------------------------------------------------------
-
-#ifndef _GBA_NDS_FAT_INCLUDED
-#define _GBA_NDS_FAT_INCLUDED
-
-//---------------------------------------------------------------
-// Customisable features
-
-// Maximum number of files open at once
-// Increase this to open more files, decrease to save memory
-#define MAX_FILES_OPEN	16
-
-// Allow file writing
-// Disable this to remove file writing support
-#define CAN_WRITE_TO_DISC
-
-// Allow file time functions
-// This adds ~ 14KB to the compiled size
-// Uncomment to enable
-// #define FILE_TIME_SUPPORT
-
-//---------------------------------------------------------------
-// Platform specific includes
-
-// When compiling for NDS, make sure NDS is defined
-#ifndef NDS
- #if defined ARM9 || defined ARM7
-  #define NDS
- #endif
-#endif
-
-#ifdef NDS
- #include <nds/ndstypes.h>
-#else
- #include "gba_types.h"
-#endif
-
-#ifdef FILE_TIME_SUPPORT
- #include <time.h>
-#endif
-
-//---------------------------------------------------------------
-#ifdef __cplusplus
-extern "C" {
-#endif
-//---------------------------------------------------------------
-
-//---------------------------------------------------------------
-// Important constants
-
-
-enum {
-	MAX_FILENAME_LENGTH = 256	// Maximum LFN length. Don't change this one
-};
-
-// File Constants
-#ifndef EOF
-#define EOF -1
-#define SEEK_SET	0
-#define SEEK_CUR	1
-#define SEEK_END	2
-#endif
-
-// File attributes
-#define ATTRIB_ARCH	0x20			// Archive
-#define ATTRIB_DIR	0x10			// Directory
-#define ATTRIB_LFN	0x0F			// Long file name
-#define ATTRIB_VOL	0x08			// Volume
-#define ATTRIB_SYS	0x04			// System
-#define ATTRIB_HID	0x02			// Hidden
-#define ATTRIB_RO	0x01			// Read only
-
-
-// Directory Constants
-typedef enum {FT_NONE, FT_FILE, FT_DIR} FILE_TYPE;
-
-// Filesystem type
-typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
-
-// Open file information structure
-typedef struct
-{
-	u32 firstCluster;
-	u32 length;
-	u32 curPos;
-	u32 curClus;			// Current cluster to read from
-	int curSect;			// Current sector within cluster
-	int curByte;			// Current byte within sector
-	char readBuffer[512];	// Buffer used for unaligned reads
-	u32 appClus;			// Cluster to append to
-	int appSect;			// Sector within cluster for appending
-	int appByte;			// Byte within sector for appending
-	bool read;	// Can read from file
-	bool write;	// Can write to file
-	bool append;// Can append to file
-	bool inUse;	// This file is open
-	u32 dirEntSector;	// The sector where the directory entry is stored
-	int dirEntOffset;	// The offset within the directory sector
-}	FAT_FILE;
-
-
-//-----------------------------------------------------------------
-// CF Card functions
-
-/*-----------------------------------------------------------------
-FAT_InitFiles
-Reads the FAT information from the CF card.
-You need to call this before reading any files.
-bool return OUT: true if successful.
------------------------------------------------------------------*/
-bool FAT_InitFiles (void);
-
-/*-----------------------------------------------------------------
-FAT_FreeFiles
-Closes all open files then resets the CF card.
-Call this before exiting back to the GBAMP
-bool return OUT: true if successful.
------------------------------------------------------------------*/
-bool FAT_FreeFiles (void);
-
-/*-----------------------------------------------------------------
-FAT_GetAlias
-Get the alias (short name) of the last file or directory entry read
-	using GetDirEntry. Works for FindFirstFile and FindNextFile
-char* alias OUT: will be filled with the alias (short filename),
-	should be at least 13 bytes long
-bool return OUT: return true if successful
------------------------------------------------------------------*/
-bool FAT_GetAlias (char* alias);
-
-/*-----------------------------------------------------------------
-FAT_GetLongFilename
-Get the long name of the last file or directory retrived with
-	GetDirEntry. Also works for FindFirstFile and FindNextFile
-char* filename: OUT will be filled with the filename, should be at
-	least 256 bytes long
-bool return OUT: return true if successful
------------------------------------------------------------------*/
-bool FAT_GetLongFilename (char* filename);
-
-/*-----------------------------------------------------------------
-FAT_GetFileSize
-Get the file size of the last file found or openned.
-This idea is based on a modification by MoonShine
-u32 return OUT: the file size
------------------------------------------------------------------*/
-u32 FAT_GetFileSize (void);
-
-/*-----------------------------------------------------------------
-FAT_GetFileCluster
-Get the first cluster of the last file found or openned.
-u32 return OUT: the file start cluster
------------------------------------------------------------------*/
-u32 FAT_GetFileCluster (void);
-
-/*-----------------------------------------------------------------
-FAT_GetFileAttributes
-Get the attributes of the last file found or openned.
-u8 return OUT: the file's attributes
------------------------------------------------------------------*/
-u8 FAT_GetFileAttributes (void);
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_FAT_SetFileAttributes
-Set the attributes of a file.
-const char* filename IN: The name and path of the file to modify
-u8 attributes IN: The attribute values to assign
-u8 mask IN: Detemines which attributes are changed
-u8 return OUT: the file's new attributes
------------------------------------------------------------------*/
-u8 FAT_SetFileAttributes (const char* filename, u8 attributes, u8 mask);
-#endif
-
-#ifdef FILE_TIME_SUPPORT
-/*-----------------------------------------------------------------
-FAT_GetFileCreationTime
-Get the creation time of the last file found or openned.
-time_t return OUT: the file's creation time
------------------------------------------------------------------*/
-time_t FAT_GetFileCreationTime (void);
-
-/*-----------------------------------------------------------------
-FAT_GetFileLastWriteTime
-Get the creation time of the last file found or openned.
-time_t return OUT: the file's creation time
------------------------------------------------------------------*/
-time_t FAT_GetFileLastWriteTime (void);
-#endif
-
-/*-----------------------------------------------------------------
-FAT_FindNextFile
-Gets the name of the next directory entry
-	(can be a file or subdirectory)
-char* filename: OUT filename, must be at least 13 chars long
-FILE_TYPE return: OUT returns FT_NONE if failed,
-	FT_FILE if it found a file and FT_DIR if it found a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FindNextFile (char* filename);
-
-/*-----------------------------------------------------------------
-FAT_FindFirstFile
-Gets the name of the first directory entry and resets the count
-	(can be a file or subdirectory)
-char* filename: OUT filename, must be at least 13 chars long
-FILE_TYPE return: OUT returns FT_NONE if failed,
-	FT_FILE if it found a file and FT_DIR if it found a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FindFirstFile (char* filename);
-
-/*-----------------------------------------------------------------
-FAT_FindFirstFileLFN
-Gets the long file name of the first directory entry and resets
-	the count (can be a file or subdirectory)
-char* lfn: OUT long file name, must be at least 256 chars long
-FILE_TYPE return: OUT returns FT_NONE if failed,
-	FT_FILE if it found a file and FT_DIR if it found a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FindFirstFileLFN(char* lfn);
-
-/*-----------------------------------------------------------------
-FAT_FindNextFileLFN
-Gets the long file name of the next directory entry
-	(can be a file or subdirectory)
-char* lfn: OUT long file name, must be at least 256 chars long
-FILE_TYPE return: OUT returns FT_NONE if failed,
-	FT_FILE if it found a file and FT_DIR if it found a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FindNextFileLFN(char* lfn);
-
-/*-----------------------------------------------------------------
-FAT_FileExists
-Returns the type of file
-char* filename: IN filename of the file to look for
-FILE_TYPE return: OUT returns FT_NONE if there is now file with
-	that name, FT_FILE if it is a file and FT_DIR if it is a directory
------------------------------------------------------------------*/
-FILE_TYPE FAT_FileExists (const char* filename);
-
-/*-----------------------------------------------------------------
-FAT_GetFileSystemType
-FS_TYPE return: OUT returns the current file system type
------------------------------------------------------------------*/
-FS_TYPE FAT_GetFileSystemType (void);
-
-/*-----------------------------------------------------------------
-FAT_GetFileSystemTotalSize
-u32 return: OUT returns the total disk space (used + free)
------------------------------------------------------------------*/
-u32 FAT_GetFileSystemTotalSize (void);
-
-/*-----------------------------------------------------------------
-FAT_chdir
-Changes the current working directory
-const char* path: IN null terminated string of directory separated by
-	forward slashes, / is root
-bool return: OUT returns true if successful
------------------------------------------------------------------*/
-bool FAT_chdir (const char* path);
-
-
-//-----------------------------------------------------------------
-// File functions
-
-/*-----------------------------------------------------------------
-FAT_fopen(filename, mode)
-Opens a file
-const char* path: IN null terminated string of filename and path
-	separated by forward slashes, / is root
-const char* mode: IN mode to open file in
-	Supported modes: "r", "r+", "w", "w+", "a", "a+", don't use
-	"b" or "t" in any mode, as all files are openned in binary mode
-FAT_FILE* return: OUT handle to open file, returns -1 if the file
-	couldn't be openned
------------------------------------------------------------------*/
-FAT_FILE* FAT_fopen(const char* path, const char* mode);
-
-/*-----------------------------------------------------------------
-FAT_fclose(file)
-Closes a file
-FAT_FILE* file: IN handle of the file to close
-bool return OUT: true if successful, false if not
------------------------------------------------------------------*/
-bool FAT_fclose (FAT_FILE* file);
-
-/*-----------------------------------------------------------------
-FAT_ftell(file)
-Returns the current position in a file
-FAT_FILE* file: IN handle of an open file
-u32 OUT: Current position
------------------------------------------------------------------*/
-u32 FAT_ftell (FAT_FILE* file);
-
-/*-----------------------------------------------------------------
-FAT_fseek(file, offset, origin)
-Seeks to specified byte position in file
-int file: IN handle of an open file
-u32 offset IN: position to seek to, relative to origin
-int origin IN: origin to seek from
-int OUT: Returns 0 if successful, -1 if not
------------------------------------------------------------------*/
-int FAT_fseek(FAT_FILE* file, s32 offset, int origin);
-
-/*-----------------------------------------------------------------
-FAT_fread(buffer, size, count, file)
-Reads in length number of bytes into buffer from file, starting
-	from current position. It then sets the current position to the
-	byte after the last byte read. If it reaches the end of file
-	before filling the buffer then it stops reading.
-void* buffer OUT: Pointer to buffer to fill. Should be at least as
-	big as the number of bytes required
-u32 size IN: size of each item to read
-u32 count IN: number of items to read
-FAT_FILE* file IN: Handle of an open file
-u32 OUT: returns the actual number of bytes read
------------------------------------------------------------------*/
-u32 FAT_fread (void* buffer, u32 size, u32 count, FAT_FILE* file);
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_fwrite(buffer, size, count, file)
-Writes size * count bytes into file from buffer, starting
-	from current position. It then sets the current position to the
-	byte after the last byte written. If the file was openned in
-	append mode it always writes to the end of the file.
-const void* buffer IN: Pointer to buffer containing data. Should be
-	at least as big as the number of bytes to be written.
-u32 size IN: size of each item to write
-u32 count IN: number of items to write
-FAT_FILE* file IN: Handle of an open file
-u32 OUT: returns the actual number of bytes written
------------------------------------------------------------------*/
-u32 FAT_fwrite (const void* buffer, u32 size, u32 count, FAT_FILE* file);
-#endif
-
-/*-----------------------------------------------------------------
-FAT_feof(file)
-Returns true if the end of file has been reached
-FAT_FILE* file IN: Handle of an open file
-bool return OUT: true if EOF, false if not
------------------------------------------------------------------*/
-bool FAT_feof(FAT_FILE* file);
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_remove (path)
-Deletes the file or empty directory sepecified in path
-const char* path IN: Path of item to delete
-int return OUT: zero if successful, non-zero if not
------------------------------------------------------------------*/
-int FAT_remove (const char* path);
-#endif
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_mkdir (path)
-Makes a new directory, so long as no other directory or file has
-	the same name.
-const char* path IN: Path and filename of directory to make
-int return OUT: zero if successful, non-zero if not
------------------------------------------------------------------*/
-int FAT_mkdir (const char* path);
-#endif
-
-/*-----------------------------------------------------------------
-FAT_fgetc (handle)
-Gets the next character in the file
-FAT_FILE* file IN: Handle of open file
-bool return OUT: character if successful, EOF if not
------------------------------------------------------------------*/
-char FAT_fgetc (FAT_FILE* file);
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_fputc (character, handle)
-Writes the given character into the file
-char c IN: Character to be written
-FAT_FILE* handle IN: Handle of open file
-bool return OUT: character if successful, EOF if not
------------------------------------------------------------------*/
-char FAT_fputc (char c, FAT_FILE* file);
-#endif
-
-/*-----------------------------------------------------------------
-FAT_fgets (char *tgtBuffer, int num, FAT_FILE* file)
-Gets a up to num bytes from file, stopping at the first
- newline.
-
-CAUTION: does not do strictly streaming. I.e. it's
- reading more then needed bytes and seeking back.
- shouldn't matter for random access
-
-char *tgtBuffer OUT: buffer to write to
-int num IN: size of target buffer
-FAT_FILE* file IN: Handle of open file
-bool return OUT: character if successful, EOF if not
-
-  Written by MightyMax
-  Modified by Chishm - 2005-11-17
-	* Added check for unix style text files
-	* Removed seek when no newline is found, since it isn't necessary
--------------------------------------------------------------------*/
-char *FAT_fgets(char *tgtBuffer, int num, FAT_FILE* file) ;
-
-#ifdef CAN_WRITE_TO_DISC
-/*-----------------------------------------------------------------
-FAT_fputs (const char *string, FAT_FILE* file)
-Writes string to file, excluding end of string character
-const char *string IN: string to write
-FAT_FILE* file IN: Handle of open file
-bool return OUT: number of characters written if successful,
-	EOF if not
-
-  Written by MightyMax
-  Modified by Chishm - 2005-11-17
-	* Uses FAT_FILE instead of int
-	* writtenBytes is now u32 instead of int
--------------------------------------------------------------------*/
-int FAT_fputs (const char *string, FAT_FILE* file);
-#endif
-
-//------------------------------------------------------------------
-#ifdef __cplusplus
-}	   // extern "C"
-#endif
-//------------------------------------------------------------------
-
-#endif	// ifndef _GBA_NDS_FAT
diff --git a/backends/platform/ds/arm9/source/fat/io_dldi.h b/backends/platform/ds/arm9/source/fat/io_dldi.h
deleted file mode 100644
index 034c6aace3..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_dldi.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-	io_dldi.h
-
-	Reserved space for new drivers
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_DLDI_H
-#define IO_DLDI_H
-
-// 'DLDI'
-#define DEVICE_TYPE_DLDD 0x49444C44
-
-#include "disc_io.h"
-#ifdef NDS
-#include <nds/memory.h>
-#include <nds.h>
-#endif
-
-extern IO_INTERFACE _io_dldi;
-
-extern u8 _dldi_driver_name;
-
-// export interface
-static inline LPIO_INTERFACE DLDI_GetInterface(void) {
-#ifdef NDS
-	// NDM: I'm really not sure about this change ARM9 - ARM7
-	REG_EXEMEMCNT &= ~(ARM7_OWNS_ROM | ARM7_OWNS_CARD);
-#endif // defined NDS
-	return &_io_dldi;
-}
-
-#endif	// define IO_DLDI_H
diff --git a/backends/platform/ds/arm9/source/fat/io_dldi.s b/backends/platform/ds/arm9/source/fat/io_dldi.s
deleted file mode 100644
index 311d43f3ff..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_dldi.s
+++ /dev/null
@@ -1,72 +0,0 @@
- at ---------------------------------------------------------------------------------
-	.align	4
-	.arm
-	.global _io_dldi
-	.global _dldi_driver_name
- at ---------------------------------------------------------------------------------
-.equ FEATURE_MEDIUM_CANREAD,		0x00000001
-.equ FEATURE_MEDIUM_CANWRITE,		0x00000002
-.equ FEATURE_SLOT_GBA,				0x00000010
-.equ FEATURE_SLOT_NDS,				0x00000020
-
-
- at ---------------------------------------------------------------------------------
-@ Driver patch file standard header -- 16 bytes
-	.word	0xBF8DA5ED		@ Magic number to identify this region
-	.asciz	" Chishm"		@ Identifying Magic string (8 bytes with null terminator)
-	.byte	0x01			@ Version number
-	.byte	0x0F	@32KiB	@ Log [base-2] of the size of this driver in bytes.
-	.byte	0x00			@ Sections to fix
-	.byte 	0x0F	@32KiB	@ Log [base-2] of the allocated space in bytes.
-
- at ---------------------------------------------------------------------------------
-@ Text identifier - can be anything up to 47 chars + terminating null -- 16 bytes
-	.align	4
-_dldi_driver_name:
-	.asciz "Default (No interface)"
-
- at ---------------------------------------------------------------------------------
-@ Offsets to important sections within the data	-- 32 bytes
-	.align	6
-	.word   0x00000000		@ data start
-	.word   0x00000000		@ data end
-	.word	0x00000000		@ Interworking glue start	-- Needs address fixing
-	.word	0x00000000		@ Interworking glue end
-	.word   0x00000000		@ GOT start					-- Needs address fixing
-	.word   0x00000000		@ GOT end
-	.word   0x00000000		@ bss start					-- Needs setting to zero
-	.word   0x00000000		@ bss end
-
- at ---------------------------------------------------------------------------------
-@ IO_INTERFACE data -- 32 bytes
-_io_dldi:
-	.ascii	"DLDI"					@ ioType
-	.word	0x00000000				@ Features
-	.word	_DLDI_startup			@
-	.word	_DLDI_isInserted		@
-	.word	_DLDI_readSectors		@   Function pointers to standard device driver functions
-	.word	_DLDI_writeSectors		@
-	.word	_DLDI_clearStatus		@
-	.word	_DLDI_shutdown			@
-
- at ---------------------------------------------------------------------------------
-
-_DLDI_startup:
-_DLDI_isInserted:
-_DLDI_readSectors:
-_DLDI_writeSectors:
-_DLDI_clearStatus:
-_DLDI_shutdown:
-	mov		r0, #0x00				@ Return false for every function
-	bx		lr
-
-
-
- at ---------------------------------------------------------------------------------
-	.align
-	.pool
-
-.space 32632						@ Fill to 32KiB
-
-	.end
- at ---------------------------------------------------------------------------------
diff --git a/backends/platform/ds/arm9/source/fat/io_efa2.c b/backends/platform/ds/arm9/source/fat/io_efa2.c
deleted file mode 100644
index 468361969e..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_efa2.c
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
-io_efa2.c by CyteX
-
-Based on io_mpfc.c by chishm (Michael Chisholm)
-
-Hardware Routines for reading the NAND flash located on
-EFA2 flash carts
-
-This software is completely free. No warranty is provided.
-If you use it, please give me credit and email me about your
-project at cytex <at> gmx <dot> de and do not forget to also
-drop chishm <at> hotmail <dot> com a line
-
-See gba_nds_fat.txt for help and license details.
-*/
-
-#include "io_efa2.h"
-
-#ifdef SUPPORT_EFA2
-
-//
-// EFA2 register addresses
-//
-
-// RTC registers
-#define REG_RTC_CLK        *(vu16*)0x080000c4
-#define REG_RTC_EN         *(vu16*)0x080000c8
-
-// "Magic" registers used for unlock/lock sequences
-#define REG_EFA2_MAGIC_A   *(vu16*)0x09fe0000
-#define REG_EFA2_MAGIC_B   *(vu16*)0x08000000
-#define REG_EFA2_MAGIC_C   *(vu16*)0x08020000
-#define REG_EFA2_MAGIC_D   *(vu16*)0x08040000
-#define REG_EFA2_MAGIC_E   *(vu16*)0x09fc0000
-
-// NAND flash lock/unlock register
-#define REG_EFA2_NAND_LOCK *(vu16*)0x09c40000
-// NAND flash enable register
-#define REG_EFA2_NAND_EN   *(vu16*)0x09400000
-// NAND flash command write register
-#define REG_EFA2_NAND_CMD   *(vu8*)0x09ffffe2
-// NAND flash address/data write register
-#define REG_EFA2_NAND_WR    *(vu8*)0x09ffffe0
-// NAND flash data read register
-#define REG_EFA2_NAND_RD    *(vu8*)0x09ffc000
-
-// ID of Samsung K9K1G NAND flash chip
-#define EFA2_NAND_ID 0xEC79A5C0
-
-// first sector of udisk
-#define EFA2_UDSK_START 0x40
-
-//
-// EFA2 access functions
-//
-
-// deactivate RTC ports
-inline void efa2_rtc_deactivate(void) {
-	REG_RTC_EN = 0;
-}
-
-// unlock register access
-void efa2_reg_unlock(void) {
-	REG_EFA2_MAGIC_A = 0x0d200;
-	REG_EFA2_MAGIC_B = 0x01500;
-	REG_EFA2_MAGIC_C = 0x0d200;
-	REG_EFA2_MAGIC_D = 0x01500;
-}
-
-// finish/lock register access
-inline void efa2_reg_lock(void) {
-	REG_EFA2_MAGIC_E = 0x1500;
-}
-
-// global reset/init/enable/unlock ?
-void efa2_global_unlock(void) {
-	efa2_reg_unlock();
-	*(vu16*)0x09880000 = 0x08000;
-	efa2_reg_lock();
-}
-
-// global lock, stealth mode
-void efa2_global_lock(void) {
-	// quite sure there is such a sequence, but haven't had
-	// a look for it upto now
-}
-
-// unlock NAND Flash
-void efa2_nand_unlock(void) {
-	efa2_reg_unlock();
-	REG_EFA2_NAND_LOCK = 0x01500;
-	efa2_reg_lock();
-}
-
-// lock NAND Flash
-void efa2_nand_lock(void) {
-	efa2_reg_unlock();
-	REG_EFA2_NAND_LOCK = 0x0d200;
-	efa2_reg_lock();
-}
-
-//
-// Set NAND Flash chip enable and write protection bits ?
-//
-//   val | ~CE | ~WP |
-//  -----+-----+-----+
-//     0 |  0  |  0  |
-//     1 |  1  |  0  |
-//     3 |  1  |  1  |
-//  -----+-----+-----+
-//
-void efa2_nand_enable(u16 val) {
-	efa2_reg_unlock();
-	REG_EFA2_NAND_EN = val;
-	efa2_reg_lock();
-}
-
-//
-// Perform NAND reset
-// NAND has to be unlocked and enabled when called
-//
-inline void efa2_nand_reset(void) {
-	REG_EFA2_NAND_CMD = 0xff; // write reset command
-}
-
-//
-// Read out NAND ID information, could be used for card detection
-//
-//                    | EFA2 1GBit |
-//  ------------------+------------+
-//         maker code |    0xEC    |
-//        device code |    0x79    |
-//         don't care |    0xA5    |
-//   multi plane code |    0xC0    |
-//  ------------------+------------+
-//
-u32 efa2_nand_id(void) {
-	u8 byte;
-	u32 id;
-
-	efa2_nand_unlock();
-	efa2_nand_enable(1);
-
-	REG_EFA2_NAND_CMD = 0x90;  // write id command
-	REG_EFA2_NAND_WR  = 0x00;  // (dummy) address cycle
-	byte = REG_EFA2_NAND_RD;   // read maker code
-	id   = byte;
-	byte = REG_EFA2_NAND_RD;   // read device code
-	id   = (id << 8) | byte;
-	byte = REG_EFA2_NAND_RD;   // read don't care
-	id   = (id << 8) | byte;
-	byte = REG_EFA2_NAND_RD;   // read multi plane code
-	id   = (id << 8) | byte;
-
-	efa2_nand_enable(0);
-	efa2_nand_lock();
-	return (id);
-}
-
-//
-// Start of gba_nds_fat block device description
-//
-
-/*-----------------------------------------------------------------
-EFA2_ClearStatus
-Reads and checks NAND status information
-bool return OUT:  true if NAND is idle
------------------------------------------------------------------*/
-bool EFA2_ClearStatus (void)
-{
-	// tbd: currently there is no write support, so always return
-	// true, there is no possibility for pending operations
-	return true;
-}
-
-/*-----------------------------------------------------------------
-EFA2_IsInserted
-Checks to see if the NAND chip used by the EFA2 is present
-bool return OUT:  true if the correct NAND chip is found
------------------------------------------------------------------*/
-bool EFA2_IsInserted (void)
-{
-	EFA2_ClearStatus();
-	return (efa2_nand_id() == EFA2_NAND_ID);
-}
-
-/*-----------------------------------------------------------------
-EFA2_ReadSectors
-Read "numSecs" 512 byte sectors starting from "sector" into "buffer"
-No error correction, no use of spare cells, no use of R/~B signal
-u32 sector IN: number of first 512 byte sector to be read
-u8 numSecs IN: number of 512 byte sectors to read,
-1 to 256 sectors can be read, 0 = 256
-void* buffer OUT: pointer to 512 byte buffer to store data in
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool EFA2_ReadSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int  i;
-	int  j = (numSecs > 0 ? numSecs : 256);
-
-#ifndef _CF_ALLOW_UNALIGNED
-	u8  byte;
-	u16  word;
-#endif
-
-	// NAND page 0x40 (EFA2_UDSK_START) contains the MBR of the
-	// udisk and thus is sector 0. The original EFA2 firmware
-	// does never look at this, it only watches page 0x60, which
-	// contains the boot block of the FAT16 partition. That is
-	// fixed, so the EFA2 udisk must not be reformated, else
-	// the ARK Octopus and also the original Firmware won't be
-	// able to access the udisk anymore and I have to write a
-	// recovery tool.
-	u32 page = EFA2_UDSK_START + sector;
-
-	// future enhancement: wait for possible write operations to
-	// be finisched
-	if (!EFA2_ClearStatus()) return false;
-
-	efa2_nand_unlock();
-	efa2_nand_enable(1);
-	efa2_nand_reset();
-
-	// set NAND to READ1 operation mode and transfer page address
-	REG_EFA2_NAND_CMD = 0x00;                // write READ1 command
-	REG_EFA2_NAND_WR  = 0x00;                // write address  [7:0]
-	REG_EFA2_NAND_WR  = (page      ) & 0xff; // write address [15:8]
-	REG_EFA2_NAND_WR  = (page >> 8 ) & 0xff; // write address[23:16]
-	REG_EFA2_NAND_WR  = (page >> 16) & 0xff; // write address[26:24]
-
-	// Due to a bug in EFA2 design there is need to waste some cycles
-	// "by hand" instead the possibility to check the R/~B port of
-	// the NAND flash via a register. The RTC deactivation is only
-	// there to make sure the loop won't be optimized by the compiler
-	for (i=0 ; i < 3 ; i++) efa2_rtc_deactivate();
-
-	while (j--)
-	{
-		// read page data
-#ifdef _CF_ALLOW_UNALIGNED
-		// slow byte access to RAM, but works in principle
-		for (i=0 ; i < 512 ; i++)
-			((u8*)buffer)[i] = REG_EFA2_NAND_RD;
-#else
-		// a bit faster, but DMA is not possible
-		for (i=0 ; i < 256 ; i++) {
-			byte = REG_EFA2_NAND_RD;   // read lo-byte
-			word = byte;
-			byte = REG_EFA2_NAND_RD;   // read hi-byte
-			word = word | (byte << 8);
-			((u16*)buffer)[i] = word;
-		}
-#endif
-	}
-
-	efa2_nand_enable(0);
-	efa2_nand_lock();
-	return true;
-}
-
-
-/*-----------------------------------------------------------------
-EFA2_WriteSectors
-Write "numSecs" 512 byte sectors starting at "sector" from "buffer"
-u32 sector IN: address of 512 byte sector on card to write
-u8 numSecs IN: number of 512 byte sectors to write
-1 to 256 sectors can be written, 0 = 256
-void* buffer IN: pointer to 512 byte buffer to read data from
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool EFA2_WriteSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	// Upto now I focused on reading NAND, write operations
-	// will follow
-	return false;
-}
-
-/*-----------------------------------------------------------------
-EFA2_Shutdown
-unload the EFA2 interface
------------------------------------------------------------------*/
-bool EFA2_Shutdown(void)
-{
-	return EFA2_ClearStatus();
-}
-
-/*-----------------------------------------------------------------
-EFA2_StartUp
-initializes the EFA2 card, returns true if successful,
-otherwise returns false
------------------------------------------------------------------*/
-bool EFA2_StartUp(void)
-{
-	efa2_global_unlock();
-	return (efa2_nand_id() == EFA2_NAND_ID);
-}
-
-/*-----------------------------------------------------------------
-the actual interface structure
------------------------------------------------------------------*/
-IO_INTERFACE io_efa2 = {
-	DEVICE_TYPE_EFA2,
-	FEATURE_MEDIUM_CANREAD | FEATURE_SLOT_GBA,
-	(FN_MEDIUM_STARTUP)&EFA2_StartUp,
-	(FN_MEDIUM_ISINSERTED)&EFA2_IsInserted,
-	(FN_MEDIUM_READSECTORS)&EFA2_ReadSectors,
-	(FN_MEDIUM_WRITESECTORS)&EFA2_WriteSectors,
-	(FN_MEDIUM_CLEARSTATUS)&EFA2_ClearStatus,
-	(FN_MEDIUM_SHUTDOWN)&EFA2_Shutdown
-};
-
-/*-----------------------------------------------------------------
-EFA2_GetInterface
-returns the interface structure to host
------------------------------------------------------------------*/
-LPIO_INTERFACE EFA2_GetInterface(void) {
-	return &io_efa2;
-}
-
-#endif // SUPPORT_EFA2
-/*
-io_efa2.c by CyteX
-
-Based on io_mpfc.c by chishm (Michael Chisholm)
-
-Hardware Routines for reading the NAND flash located on
-EFA2 flash carts
-
-This software is completely free. No warranty is provided.
-If you use it, please give me credit and email me about your
-project at cytex <at> gmx <dot> de and do not forget to also
-drop chishm <at> hotmail <dot> com a line
-
-See gba_nds_fat.txt for help and license details.
-*/
-
-#include "io_efa2.h"
-
-#ifdef SUPPORT_EFA2
-
-//
-// EFA2 register addresses
-//
-
-// RTC registers
-#define REG_RTC_CLK        *(vu16*)0x080000c4
-#define REG_RTC_EN         *(vu16*)0x080000c8
-
-// "Magic" registers used for unlock/lock sequences
-#define REG_EFA2_MAGIC_A   *(vu16*)0x09fe0000
-#define REG_EFA2_MAGIC_B   *(vu16*)0x08000000
-#define REG_EFA2_MAGIC_C   *(vu16*)0x08020000
-#define REG_EFA2_MAGIC_D   *(vu16*)0x08040000
-#define REG_EFA2_MAGIC_E   *(vu16*)0x09fc0000
-
-// NAND flash lock/unlock register
-#define REG_EFA2_NAND_LOCK *(vu16*)0x09c40000
-// NAND flash enable register
-#define REG_EFA2_NAND_EN   *(vu16*)0x09400000
-// NAND flash command write register
-#define REG_EFA2_NAND_CMD   *(vu8*)0x09ffffe2
-// NAND flash address/data write register
-#define REG_EFA2_NAND_WR    *(vu8*)0x09ffffe0
-// NAND flash data read register
-#define REG_EFA2_NAND_RD    *(vu8*)0x09ffc000
-
-// ID of Samsung K9K1G NAND flash chip
-#define EFA2_NAND_ID 0xEC79A5C0
-
-// first sector of udisk
-#define EFA2_UDSK_START 0x40
-
-//
-// EFA2 access functions
-//
-
-// deactivate RTC ports
-inline void efa2_rtc_deactivate(void) {
-	REG_RTC_EN = 0;
-}
-
-// unlock register access
-void efa2_reg_unlock(void) {
-	REG_EFA2_MAGIC_A = 0x0d200;
-	REG_EFA2_MAGIC_B = 0x01500;
-	REG_EFA2_MAGIC_C = 0x0d200;
-	REG_EFA2_MAGIC_D = 0x01500;
-}
-
-// finish/lock register access
-inline void efa2_reg_lock(void) {
-	REG_EFA2_MAGIC_E = 0x1500;
-}
-
-// global reset/init/enable/unlock ?
-void efa2_global_unlock(void) {
-	efa2_reg_unlock();
-	*(vu16*)0x09880000 = 0x08000;
-	efa2_reg_lock();
-}
-
-// global lock, stealth mode
-void efa2_global_lock(void) {
-	// quite sure there is such a sequence, but haven't had
-	// a look for it upto now
-}
-
-// unlock NAND Flash
-void efa2_nand_unlock(void) {
-	efa2_reg_unlock();
-	REG_EFA2_NAND_LOCK = 0x01500;
-	efa2_reg_lock();
-}
-
-// lock NAND Flash
-void efa2_nand_lock(void) {
-	efa2_reg_unlock();
-	REG_EFA2_NAND_LOCK = 0x0d200;
-	efa2_reg_lock();
-}
-
-//
-// Set NAND Flash chip enable and write protection bits ?
-//
-//   val | ~CE | ~WP |
-//  -----+-----+-----+
-//     0 |  0  |  0  |
-//     1 |  1  |  0  |
-//     3 |  1  |  1  |
-//  -----+-----+-----+
-//
-void efa2_nand_enable(u16 val) {
-	efa2_reg_unlock();
-	REG_EFA2_NAND_EN = val;
-	efa2_reg_lock();
-}
-
-//
-// Perform NAND reset
-// NAND has to be unlocked and enabled when called
-//
-inline void efa2_nand_reset(void) {
-	REG_EFA2_NAND_CMD = 0xff; // write reset command
-}
-
-//
-// Read out NAND ID information, could be used for card detection
-//
-//                    | EFA2 1GBit |
-//  ------------------+------------+
-//         maker code |    0xEC    |
-//        device code |    0x79    |
-//         don't care |    0xA5    |
-//   multi plane code |    0xC0    |
-//  ------------------+------------+
-//
-u32 efa2_nand_id(void) {
-	u8 byte;
-	u32 id;
-
-	efa2_nand_unlock();
-	efa2_nand_enable(1);
-
-	REG_EFA2_NAND_CMD = 0x90;  // write id command
-	REG_EFA2_NAND_WR  = 0x00;  // (dummy) address cycle
-	byte = REG_EFA2_NAND_RD;   // read maker code
-	id   = byte;
-	byte = REG_EFA2_NAND_RD;   // read device code
-	id   = (id << 8) | byte;
-	byte = REG_EFA2_NAND_RD;   // read don't care
-	id   = (id << 8) | byte;
-	byte = REG_EFA2_NAND_RD;   // read multi plane code
-	id   = (id << 8) | byte;
-
-	efa2_nand_enable(0);
-	efa2_nand_lock();
-	return (id);
-}
-
-//
-// Start of gba_nds_fat block device description
-//
-
-/*-----------------------------------------------------------------
-EFA2_ClearStatus
-Reads and checks NAND status information
-bool return OUT:  true if NAND is idle
------------------------------------------------------------------*/
-bool EFA2_ClearStatus (void)
-{
-	// tbd: currently there is no write support, so always return
-	// true, there is no possibility for pending operations
-	return true;
-}
-
-/*-----------------------------------------------------------------
-EFA2_IsInserted
-Checks to see if the NAND chip used by the EFA2 is present
-bool return OUT:  true if the correct NAND chip is found
------------------------------------------------------------------*/
-bool EFA2_IsInserted (void)
-{
-	EFA2_ClearStatus();
-	return (efa2_nand_id() == EFA2_NAND_ID);
-}
-
-/*-----------------------------------------------------------------
-EFA2_ReadSectors
-Read "numSecs" 512 byte sectors starting from "sector" into "buffer"
-No error correction, no use of spare cells, no use of R/~B signal
-u32 sector IN: number of first 512 byte sector to be read
-u8 numSecs IN: number of 512 byte sectors to read,
-1 to 256 sectors can be read, 0 = 256
-void* buffer OUT: pointer to 512 byte buffer to store data in
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool EFA2_ReadSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int  i;
-	int  j = (numSecs > 0 ? numSecs : 256);
-
-#ifndef _CF_ALLOW_UNALIGNED
-	u8  byte;
-	u16  word;
-#endif
-
-	// NAND page 0x40 (EFA2_UDSK_START) contains the MBR of the
-	// udisk and thus is sector 0. The original EFA2 firmware
-	// does never look at this, it only watches page 0x60, which
-	// contains the boot block of the FAT16 partition. That is
-	// fixed, so the EFA2 udisk must not be reformated, else
-	// the ARK Octopus and also the original Firmware won't be
-	// able to access the udisk anymore and I have to write a
-	// recovery tool.
-	u32 page = EFA2_UDSK_START + sector;
-
-	// future enhancement: wait for possible write operations to
-	// be finisched
-	if (!EFA2_ClearStatus()) return false;
-
-	efa2_nand_unlock();
-	efa2_nand_enable(1);
-	efa2_nand_reset();
-
-	// set NAND to READ1 operation mode and transfer page address
-	REG_EFA2_NAND_CMD = 0x00;                // write READ1 command
-	REG_EFA2_NAND_WR  = 0x00;                // write address  [7:0]
-	REG_EFA2_NAND_WR  = (page      ) & 0xff; // write address [15:8]
-	REG_EFA2_NAND_WR  = (page >> 8 ) & 0xff; // write address[23:16]
-	REG_EFA2_NAND_WR  = (page >> 16) & 0xff; // write address[26:24]
-
-	// Due to a bug in EFA2 design there is need to waste some cycles
-	// "by hand" instead the possibility to check the R/~B port of
-	// the NAND flash via a register. The RTC deactivation is only
-	// there to make sure the loop won't be optimized by the compiler
-	for (i=0 ; i < 3 ; i++) efa2_rtc_deactivate();
-
-	while (j--)
-	{
-		// read page data
-#ifdef _CF_ALLOW_UNALIGNED
-		// slow byte access to RAM, but works in principle
-		for (i=0 ; i < 512 ; i++)
-			((u8*)buffer)[i] = REG_EFA2_NAND_RD;
-#else
-		// a bit faster, but DMA is not possible
-		for (i=0 ; i < 256 ; i++) {
-			byte = REG_EFA2_NAND_RD;   // read lo-byte
-			word = byte;
-			byte = REG_EFA2_NAND_RD;   // read hi-byte
-			word = word | (byte << 8);
-			((u16*)buffer)[i] = word;
-		}
-#endif
-	}
-
-	efa2_nand_enable(0);
-	efa2_nand_lock();
-	return true;
-}
-
-
-/*-----------------------------------------------------------------
-EFA2_WriteSectors
-Write "numSecs" 512 byte sectors starting at "sector" from "buffer"
-u32 sector IN: address of 512 byte sector on card to write
-u8 numSecs IN: number of 512 byte sectors to write
-1 to 256 sectors can be written, 0 = 256
-void* buffer IN: pointer to 512 byte buffer to read data from
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool EFA2_WriteSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	// Upto now I focused on reading NAND, write operations
-	// will follow
-	return false;
-}
-
-/*-----------------------------------------------------------------
-EFA2_Shutdown
-unload the EFA2 interface
------------------------------------------------------------------*/
-bool EFA2_Shutdown(void)
-{
-	return EFA2_ClearStatus();
-}
-
-/*-----------------------------------------------------------------
-EFA2_StartUp
-initializes the EFA2 card, returns true if successful,
-otherwise returns false
------------------------------------------------------------------*/
-bool EFA2_StartUp(void)
-{
-	efa2_global_unlock();
-	return (efa2_nand_id() == EFA2_NAND_ID);
-}
-
-/*-----------------------------------------------------------------
-the actual interface structure
------------------------------------------------------------------*/
-IO_INTERFACE io_efa2 = {
-	DEVICE_TYPE_EFA2,
-	FEATURE_MEDIUM_CANREAD | FEATURE_SLOT_GBA,
-	(FN_MEDIUM_STARTUP)&EFA2_StartUp,
-	(FN_MEDIUM_ISINSERTED)&EFA2_IsInserted,
-	(FN_MEDIUM_READSECTORS)&EFA2_ReadSectors,
-	(FN_MEDIUM_WRITESECTORS)&EFA2_WriteSectors,
-	(FN_MEDIUM_CLEARSTATUS)&EFA2_ClearStatus,
-	(FN_MEDIUM_SHUTDOWN)&EFA2_Shutdown
-};
-
-/*-----------------------------------------------------------------
-EFA2_GetInterface
-returns the interface structure to host
------------------------------------------------------------------*/
-LPIO_INTERFACE EFA2_GetInterface(void) {
-	return &io_efa2;
-}
-
-#endif // SUPPORT_EFA2
diff --git a/backends/platform/ds/arm9/source/fat/io_efa2.h b/backends/platform/ds/arm9/source/fat/io_efa2.h
deleted file mode 100644
index 840c6b83ac..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_efa2.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-  io_efa2.h by CyteX
-
-  Based on io_mpfc.h by chishm (Michael Chisholm)
-
-  Hardware Routines for reading the NAND flash located on
-  EFA2 flash carts
-
-  This software is completely free. No warranty is provided.
-  If you use it, please give me credit and email me about your
-  project at cytex <at> gmx <dot> de and do not forget to also
-  drop chishm <at> hotmail <dot> com a line
-
-  See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_EFA2_H
-#define IO_EFA2_H
-
-// 'EFA2'
-#define DEVICE_TYPE_EFA2 0x32414645
-
-#include "disc_io.h"
-
-// export interface
-extern LPIO_INTERFACE EFA2_GetInterface(void);
-
-#endif	// define IO_EFA2_H
diff --git a/backends/platform/ds/arm9/source/fat/io_fcsr.c b/backends/platform/ds/arm9/source/fat/io_fcsr.c
deleted file mode 100644
index d6fa4ff292..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_fcsr.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
-	io_fcsr.c based on
-
-	compact_flash.c
-	By chishm (Michael Chisholm)
-
-	Hardware Routines for using a GBA Flash Cart and SRAM as a
-	block device.
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-
-	The file system must be 512 byte aligned, in cart address space.
-	SRAM is supported.
-*/
-
-
-#include "io_fcsr.h"
-
-#ifdef SUPPORT_FCSR
-#include <string.h>
-
-//---------------------------------------------------------------
-// DMA
-#ifdef _CF_USE_DMA
- #ifndef NDS
-  #include "gba_dma.h"
- #else
-  #include <nds/dma.h>
-  #ifdef ARM9
-   #include <nds/arm9/cache.h>
-  #endif
- #endif
-#endif
-
-#ifdef NDS
- #define SRAM_START 0x0A000000
-#else
- #define SRAM_START 0x0E000000
-#endif
-
-#define NO_SRAM 0xFFFFFFFF
-
-#define FCSR 0x52534346
-const char FCSR_LabelString[] = " Chishm FAT";
-
-u8* FCSR_FileSysPointer = 0;
-u8* FCSR_SramSectorPointer[4] = {0,0,0,0};
-u32 FCSR_SramSectorStart[4] = {0,0,0,0};
-u32 FCSR_SramSectorEnd[4] = {0,0,0,0};
-
-/*-----------------------------------------------------------------
-FCSR_IsInserted
-Is a GBA Flash Cart with a valid file system inserted?
-bool return OUT:  true if a GBA FC card is inserted
------------------------------------------------------------------*/
-bool FCSR_IsInserted (void)
-{
-	bool flagFoundFileSys = false;
-
-	u32* fileSysPointer = (u32*)0x08000100;		// Start at beginning of cart address space, offset by expected location of string
-
-	// Search for file system
-	while ((fileSysPointer < (u32*)0x0A000000) && !flagFoundFileSys)	// Only search while not at end of cart address space
-	{
-		while ((*fileSysPointer != FCSR) && (fileSysPointer < (u32*)0x0A000000))
-			fileSysPointer += 0x40;
-		if ((strncmp(FCSR_LabelString, (char*)(fileSysPointer + 1), 12) == 0) && (fileSysPointer < (u32*)0x0A000000))
-		{
-			flagFoundFileSys = true;
-		} else {
-			fileSysPointer += 0x80;
-		}
-	}
-
-	return flagFoundFileSys;
-}
-
-
-/*-----------------------------------------------------------------
-FCSR_ClearStatus
-Finish any pending operations
-bool return OUT:  always true for GBA FC
------------------------------------------------------------------*/
-bool FCSR_ClearStatus (void)
-{
-	return true;
-}
-
-
-/*-----------------------------------------------------------------
-FCSR_ReadSectors
-Read 512 byte sector numbered "sector" into "buffer"
-u32 sector IN: address of first 512 byte sector on Flash Cart to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer OUT: pointer to 512 byte buffer to store data in
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool FCSR_ReadSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int i;
-	bool flagSramSector = false;
-	int numSectors = (numSecs > 0 ? numSecs : 256);
-	int readLength = numSectors * BYTE_PER_READ;
-	u8* src;
-	u8* dst;
-
-	// Find which region this read is in
-	for (i = 0; (i < 4) && !flagSramSector; i++)
-	{
-		if ((sector >= FCSR_SramSectorStart[i]) && (sector < FCSR_SramSectorEnd[i]))
-		{
-			flagSramSector = true;
-			break;
-		}
-	}
-
-	// Make sure read will be completely in SRAM range if it is partially there
-	if ( flagSramSector && ((sector + numSectors) > FCSR_SramSectorEnd[i]))
-		return false;
-
-	// Copy data to buffer
-	if (flagSramSector)
-	{
-		src = FCSR_SramSectorPointer[i] + (sector - FCSR_SramSectorStart[i]) * BYTE_PER_READ;
-	} else {
-		src = FCSR_FileSysPointer + sector * BYTE_PER_READ;
-	}
-	dst = (u8*)buffer;
-
-	if (flagSramSector)
-	{
-		while (readLength--)
-		{
-			*dst++ = *src++;
-		}
-	} else {	// Reading from Cart ROM
-
-#ifdef _CF_USE_DMA
- #ifdef NDS
-  #ifdef ARM9
-		DC_FlushRange( buffer, readLength);
-  #endif	// ARM9
-		DMA3_SRC = (u32)src;
-		DMA3_DEST = (u32)buffer;
-		DMA3_CR = (readLength >> 1) | DMA_COPY_HALFWORDS;
- #else	// ! NDS
-		DMA3COPY ( src, buffer, (readLength >> 1) | DMA16 | DMA_ENABLE);
- #endif	// NDS
-#else	// !_CF_USE_DMA
-		memcpy (buffer, src, readLength);
-#endif	// _CF_USE_DMA
-
-	}	// if (flagSramSector)
-
-	return true;
-}
-
-/*-----------------------------------------------------------------
-FCSR_WriteSectors
-Write 512 byte sector numbered "sector" from "buffer"
-u32 sector IN: address of 512 byte sector on Flash Cart to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer IN: pointer to 512 byte buffer to read data from
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool FCSR_WriteSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int i;
-	bool flagSramSector = false;
-	int writeLength = (numSecs > 0 ? numSecs : 256) * BYTE_PER_READ;
-	u8* src = (u8*) buffer;
-	u8* dst;
-
-	// Find which region this sector belongs in
-	for (i = 0; (i < 4) && !flagSramSector; i++)
-	{
-		if ((sector >= FCSR_SramSectorStart[i]) && (sector < FCSR_SramSectorEnd[i]))
-		{
-			flagSramSector = true;
-			break;
-		}
-	}
-
-	if (!flagSramSector)
-		return false;
-
-	// Entire write must be within an SRAM region
-	if ((sector + (numSecs > 0 ? numSecs : 256)) > FCSR_SramSectorEnd[i])
-		return false;
-
-	// Copy data to SRAM
-	dst = FCSR_SramSectorPointer[i] + (sector - FCSR_SramSectorStart[i]) * BYTE_PER_READ;
-	while (writeLength--)
-	{
-		*dst++ = *src++;
-	}
-
-	return true;
-}
-
-/*-----------------------------------------------------------------
-FCSR_Shutdown
-unload the Flash Cart interface
------------------------------------------------------------------*/
-bool FCSR_Shutdown(void)
-{
-	int i;
-	if (FCSR_ClearStatus() == false)
-		return false;
-
-	FCSR_FileSysPointer = 0;
-
-	for (i=0; i < 4; i++)
-	{
-		FCSR_SramSectorPointer[i] = 0;
-		FCSR_SramSectorStart[i] = 0;
-		FCSR_SramSectorEnd[i] = 0;
-	}
-	return true;
-}
-
-/*-----------------------------------------------------------------
-FCSR_StartUp
-initializes the Flash Cart interface, returns true if successful,
-otherwise returns false
------------------------------------------------------------------*/
-bool FCSR_StartUp(void)
-{
-	bool flagFoundFileSys = false;
-	int i;
-	int SramRegionSize[4];
-	u8* srcByte;
-	u8* destByte;
-
-	u32* fileSysPointer = (u32*)0x08000100;		// Start at beginning of cart address space, offset by expected location of string
-
-	// Search for file system
-	while ((fileSysPointer < (u32*)0x0A000000) && !flagFoundFileSys)	// Only search while not at end of cart address space
-	{
-		while ((*fileSysPointer != FCSR) && (fileSysPointer < (u32*)0x0A000000))
-			fileSysPointer += 0x40;
-		if ((strncmp(FCSR_LabelString, (char*)(fileSysPointer + 1), 12) == 0) && (fileSysPointer < (u32*)0x0A000000))
-		{
-			flagFoundFileSys = true;
-		} else {
-			fileSysPointer += 0x80;
-		}
-	}
-
-	if (!flagFoundFileSys)
-		return false;
-
-	// Flash cart file system pointer has been found
-	FCSR_FileSysPointer = (u8*)(fileSysPointer - 0x40);
-
-	// Get SRAM sector regions from header block
-	for (i = 0; i < 4; i++)
-	{
-		FCSR_SramSectorStart[i] = fileSysPointer[i+4];
-		SramRegionSize[i] = fileSysPointer[i+8];
-		FCSR_SramSectorEnd[i] = FCSR_SramSectorStart[i] + SramRegionSize[i];
-	}
-
-	// Calculate SRAM region pointers
-	FCSR_SramSectorPointer[0] = (u8*)(SRAM_START + 4);
-	for (i = 1; i < 4; i++)
-	{
-		FCSR_SramSectorPointer[i] = FCSR_SramSectorPointer[i-1] + (SramRegionSize[i-1] * BYTE_PER_READ);
-	}
-
-	// Initialise SRAM with overlay if it hasn't been done so
-	if ( (*((u8*)SRAM_START) != 'F')  || (*((u8*)(SRAM_START+1)) != 'C') || (*((u8*)(SRAM_START+2)) != 'S') || (*((u8*)(SRAM_START+3)) != 'R') )
-	{
-		*((u8*)SRAM_START) = 'F';
-		*((u8*)(SRAM_START+1)) = 'C';
-		*((u8*)(SRAM_START+2)) = 'S';
-		*((u8*)(SRAM_START+3)) = 'R';
-
-		for (i = 0; i < 4; i++)
-		{
-			srcByte = FCSR_FileSysPointer + (FCSR_SramSectorStart[i] * BYTE_PER_READ);
-			destByte = FCSR_SramSectorPointer[i];
-			while (srcByte < FCSR_FileSysPointer + (FCSR_SramSectorEnd[i] * BYTE_PER_READ) )
-				*destByte++ = *srcByte++;
-		}
-	}
-
-		// Get SRAM sector regions from header block
-	for (i = 0; i < 4; i++)
-	{
-		if (SramRegionSize[i] == 0)
-		{
-			FCSR_SramSectorStart[i] = NO_SRAM;
-			FCSR_SramSectorEnd[i] = NO_SRAM;
-		}
-	}
-
-	return true;
-}
-
-/*-----------------------------------------------------------------
-the actual interface structure
------------------------------------------------------------------*/
-IO_INTERFACE io_fcsr = {
-	DEVICE_TYPE_FCSR,	// 'FCSR'
-	FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA,
-	(FN_MEDIUM_STARTUP)&FCSR_StartUp,
-	(FN_MEDIUM_ISINSERTED)&FCSR_IsInserted,
-	(FN_MEDIUM_READSECTORS)&FCSR_ReadSectors,
-	(FN_MEDIUM_WRITESECTORS)&FCSR_WriteSectors,
-	(FN_MEDIUM_CLEARSTATUS)&FCSR_ClearStatus,
-	(FN_MEDIUM_SHUTDOWN)&FCSR_Shutdown
-} ;
-
-/*-----------------------------------------------------------------
-FCSR_GetInterface
-returns the interface structure to host
------------------------------------------------------------------*/
-LPIO_INTERFACE FCSR_GetInterface(void) {
-	return &io_fcsr ;
-} ;
-
-#endif // SUPPORT_FCSR
diff --git a/backends/platform/ds/arm9/source/fat/io_fcsr.h b/backends/platform/ds/arm9/source/fat/io_fcsr.h
deleted file mode 100644
index ef390a8ad6..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_fcsr.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-	io_fcsr.h
-
-	Hardware Routines for using a GBA Flash Cart with SRAM
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_FCSR_H
-#define IO_FCSR_H
-
-// 'FCSR'
-#define DEVICE_TYPE_FCSR 0x52534346
-
-#include "disc_io.h"
-
-// export interface
-extern LPIO_INTERFACE FCSR_GetInterface(void) ;
-
-#endif	// define IO_FCSR_H
-/*
-	io_fcsr.h
-
-	Hardware Routines for using a GBA Flash Cart with SRAM
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_FCSR_H
-#define IO_FCSR_H
-
-// 'FCSR'
-#define DEVICE_TYPE_FCSR 0x52534346
-
-#include "disc_io.h"
-
-// export interface
-extern LPIO_INTERFACE FCSR_GetInterface(void) ;
-
-#endif	// define IO_FCSR_H
diff --git a/backends/platform/ds/arm9/source/fat/io_m3_common.c b/backends/platform/ds/arm9/source/fat/io_m3_common.c
deleted file mode 100644
index e3232a4df6..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_m3_common.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-	io_m3_common.c
-
-	Routines common to all version of the M3
-
-	Some code based on M3 SD drivers supplied by M3Adapter.
-	Some code written by SaTa may have been unknowingly used.
-
- 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.
-*/
-
-#include "io_m3_common.h"
-
-static u16 _M3_readHalfword (u32 addr) {
-	return *((vu16*)addr);
-}
-
-void _M3_changeMode (u32 mode) {
-	_M3_readHalfword (0x08e00002);
-	_M3_readHalfword (0x0800000e);
-	_M3_readHalfword (0x08801ffc);
-	_M3_readHalfword (0x0800104a);
-	_M3_readHalfword (0x08800612);
-	_M3_readHalfword (0x08000000);
-	_M3_readHalfword (0x08801b66);
-	_M3_readHalfword (0x08000000 + (mode << 1));
-	_M3_readHalfword (0x0800080e);
-	_M3_readHalfword (0x08000000);
-
-	if ((mode & 0x0f) != 4) {
-		_M3_readHalfword (0x09000000);
-	} else {
-		_M3_readHalfword (0x080001e4);
-		_M3_readHalfword (0x080001e4);
-		_M3_readHalfword (0x08000188);
-		_M3_readHalfword (0x08000188);
-	}
-}
diff --git a/backends/platform/ds/arm9/source/fat/io_m3_common.h b/backends/platform/ds/arm9/source/fat/io_m3_common.h
deleted file mode 100644
index 6a0cc03c2e..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_m3_common.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- io_m3_common.h
-
- Routines common to all version of the M3
-
- Some code based on M3 SD drivers supplied by M3Adapter.
- Some code written by SaTa may have been unknowingly used.
-
- 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.
-
-	2006-07-11 - Chishm
-		* Original release
-*/
-
-#ifndef IO_M3_COMMON_H
-#define IO_M3_COMMON_H
-
-#include "disc_io.h"
-
-// Values for changing mode
-#define M3_MODE_ROM 0x00400004
-#define M3_MODE_MEDIA 0x00400003
-
-extern void _M3_changeMode (u32 mode);
-
-#endif // IO_M3_COMMON_H
diff --git a/backends/platform/ds/arm9/source/fat/io_m3cf.c b/backends/platform/ds/arm9/source/fat/io_m3cf.c
deleted file mode 100644
index 968d83ae33..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_m3cf.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
-	io_m3cf.c based on
-
-	compact_flash.c
-	By chishm (Michael Chisholm)
-
-	Hardware Routines for reading a compact flash card
-	using the M3 Perfect CF Adapter
-
-	CF routines modified with help from Darkfader
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-
-#include "io_m3cf.h"
-
-#ifdef SUPPORT_M3CF
-
-//---------------------------------------------------------------
-// DMA
-#ifdef _CF_USE_DMA
- #ifndef NDS
-  #include "gba_dma.h"
- #else
-  #include <nds/dma.h>
-  #ifdef ARM9
-   #include <nds/arm9/cache.h>
-  #endif
- #endif
-#endif
-
-//---------------------------------------------------------------
-// CF Addresses & Commands
-
-#define GAME_PAK		0x08000000			// Game pack start address
-
-// GBAMP CF Addresses
-#define M3_REG_STS		*(vu16*)(GAME_PAK + 0x000C0000)	// Status of the CF Card / Device control
-#define M3_REG_CMD		*(vu16*)(GAME_PAK + 0x008E0000)	// Commands sent to control chip and status return
-#define M3_REG_ERR		*(vu16*)(GAME_PAK + 0x00820000)	// Errors / Features
-
-#define M3_REG_SEC		*(vu16*)(GAME_PAK + 0x00840000)	// Number of sector to transfer
-#define M3_REG_LBA1		*(vu16*)(GAME_PAK + 0x00860000)	// 1st byte of sector address
-#define M3_REG_LBA2		*(vu16*)(GAME_PAK + 0x00880000)	// 2nd byte of sector address
-#define M3_REG_LBA3		*(vu16*)(GAME_PAK + 0x008A0000)	// 3rd byte of sector address
-#define M3_REG_LBA4		*(vu16*)(GAME_PAK + 0x008C0000)	// last nibble of sector address | 0xE0
-
-#define M3_DATA			(vu16*)(GAME_PAK + 0x00800000)		// Pointer to buffer of CF data transered from card
-
-// CF Card status
-#define CF_STS_INSERTED		0x50
-#define CF_STS_REMOVED		0x00
-#define CF_STS_READY		0x58
-
-#define CF_STS_DRQ			0x08
-#define CF_STS_BUSY			0x80
-
-// CF Card commands
-#define CF_CMD_LBA			0xE0
-#define CF_CMD_READ			0x20
-#define CF_CMD_WRITE		0x30
-
-#define CARD_TIMEOUT	10000000		// Updated due to suggestion from SaTa, otherwise card will timeout sometimes on a write
-
-
-/*-----------------------------------------------------------------
-M3CF_IsInserted
-Is a compact flash card inserted?
-bool return OUT:  true if a CF card is inserted
------------------------------------------------------------------*/
-bool M3CF_IsInserted (void)
-{
-	// Change register, then check if value did change
-	M3_REG_STS = CF_STS_INSERTED;
-	return ((M3_REG_STS & 0xff) == CF_STS_INSERTED);
-}
-
-
-/*-----------------------------------------------------------------
-M3CF_ClearStatus
-Tries to make the CF card go back to idle mode
-bool return OUT:  true if a CF card is idle
------------------------------------------------------------------*/
-bool M3CF_ClearStatus (void)
-{
-	int i;
-
-	// Wait until CF card is finished previous commands
-	i=0;
-	while ((M3_REG_CMD & CF_STS_BUSY) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-
-	// Wait until card is ready for commands
-	i = 0;
-	while ((!(M3_REG_STS & CF_STS_INSERTED)) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-	if (i >= CARD_TIMEOUT)
-		return false;
-
-	return true;
-}
-
-
-/*-----------------------------------------------------------------
-M3CF_ReadSectors
-Read 512 byte sector numbered "sector" into "buffer"
-u32 sector IN: address of first 512 byte sector on CF card to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer OUT: pointer to 512 byte buffer to store data in
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool M3CF_ReadSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int i;
-	int j = (numSecs > 0 ? numSecs : 256);
-	u16 *buff = (u16*)buffer;
-#ifdef _CF_ALLOW_UNALIGNED
-	u8 *buff_u8 = (u8*)buffer;
-	int temp;
-#endif
-
-#if defined _CF_USE_DMA && defined NDS && defined ARM9
-	DC_FlushRange( buffer, j * BYTE_PER_READ);
-#endif
-
-	// Wait until CF card is finished previous commands
-	i=0;
-	while ((M3_REG_CMD & CF_STS_BUSY) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-
-	// Wait until card is ready for commands
-	i = 0;
-	while ((!(M3_REG_STS & CF_STS_INSERTED)) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-	if (i >= CARD_TIMEOUT)
-		return false;
-
-	// Set number of sectors to read
-	M3_REG_SEC = numSecs;
-
-	// Set read sector
-	M3_REG_LBA1 = sector & 0xFF;						// 1st byte of sector number
-	M3_REG_LBA2 = (sector >> 8) & 0xFF;					// 2nd byte of sector number
-	M3_REG_LBA3 = (sector >> 16) & 0xFF;				// 3rd byte of sector number
-	M3_REG_LBA4 = ((sector >> 24) & 0x0F )| CF_CMD_LBA;	// last nibble of sector number
-
-	// Set command to read
-	M3_REG_CMD = CF_CMD_READ;
-
-
-	while (j--)
-	{
-		// Wait until card is ready for reading
-		i = 0;
-		while (((M3_REG_STS & 0xff) != CF_STS_READY) && (i < CARD_TIMEOUT))
-		{
-			i++;
-		}
-		if (i >= CARD_TIMEOUT)
-			return false;
-
-		// Read data
-#ifdef _CF_USE_DMA
- #ifdef NDS
-		DMA3_SRC = (u32)M3_DATA;
-		DMA3_DEST = (u32)buff;
-		DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_SRC_FIX;
- #else
-		DMA3COPY ( M3_DATA, buff, 256 | DMA16 | DMA_ENABLE | DMA_SRC_FIXED);
- #endif
-		buff += BYTE_PER_READ / 2;
-#elif defined _CF_ALLOW_UNALIGNED
-		i=256;
-		if ((u32)buff_u8 & 0x01) {
-			while(i--)
-			{
-				temp = *M3_DATA;
-				*buff_u8++ = temp & 0xFF;
-				*buff_u8++ = temp >> 8;
-			}
-		} else {
-		while(i--)
-			*buff++ = *M3_DATA;
-		}
-#else
-		i=256;
-		while(i--)
-			*buff++ = *M3_DATA;
-#endif
-	}
-#if defined _CF_USE_DMA && defined NDS
-	// Wait for end of transfer before returning
-	while(DMA3_CR & DMA_BUSY);
-#endif
-
-	return true;
-}
-
-
-
-/*-----------------------------------------------------------------
-M3CF_WriteSectors
-Write 512 byte sector numbered "sector" from "buffer"
-u32 sector IN: address of 512 byte sector on CF card to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer IN: pointer to 512 byte buffer to read data from
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool M3CF_WriteSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int i;
-	int j = (numSecs > 0 ? numSecs : 256);
-	u16 *buff = (u16*)buffer;
-#ifdef _CF_ALLOW_UNALIGNED
-	u8 *buff_u8 = (u8*)buffer;
-	int temp;
-#endif
-
-#if defined _CF_USE_DMA && defined NDS && defined ARM9
-	DC_FlushRange( buffer, j * BYTE_PER_READ);
-#endif
-
-	// Wait until CF card is finished previous commands
-	i=0;
-	while ((M3_REG_CMD & CF_STS_BUSY) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-
-	// Wait until card is ready for commands
-	i = 0;
-	while ((!(M3_REG_STS & CF_STS_INSERTED)) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-	if (i >= CARD_TIMEOUT)
-		return false;
-
-	// Set number of sectors to write
-	M3_REG_SEC = numSecs;
-
-	// Set write sector
-	M3_REG_LBA1 = sector & 0xFF;						// 1st byte of sector number
-	M3_REG_LBA2 = (sector >> 8) & 0xFF;					// 2nd byte of sector number
-	M3_REG_LBA3 = (sector >> 16) & 0xFF;				// 3rd byte of sector number
-	M3_REG_LBA4 = ((sector >> 24) & 0x0F )| CF_CMD_LBA;	// last nibble of sector number
-
-	// Set command to write
-	M3_REG_CMD = CF_CMD_WRITE;
-
-	while (j--)
-	{
-		// Wait until card is ready for writing
-		i = 0;
-		while (((M3_REG_STS & 0xff) != CF_STS_READY) && (i < CARD_TIMEOUT))
-		{
-			i++;
-		}
-		if (i >= CARD_TIMEOUT)
-			return false;
-
-		// Write data
-#ifdef _CF_USE_DMA
- #ifdef NDS
-		DMA3_SRC = (u32)buff;
-		DMA3_DEST = (u32)M3_DATA;
-		DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_DST_FIX;
- #else
-		DMA3COPY( buff, M3_DATA, 256 | DMA16 | DMA_ENABLE | DMA_DST_FIXED);
- #endif
-		buff += BYTE_PER_READ / 2;
-#elif defined _CF_ALLOW_UNALIGNED
-		i=256;
-		if ((u32)buff_u8 & 0x01) {
-			while(i--)
-			{
-				temp = *buff_u8++;
-				temp |= *buff_u8++ << 8;
-				*M3_DATA = temp;
-			}
-		} else {
-		while(i--)
-			*M3_DATA = *buff++;
-		}
-#else
-		i=256;
-		while(i--)
-			*M3_DATA = *buff++;
-#endif
-	}
-#if defined _CF_USE_DMA && defined NDS
-	// Wait for end of transfer before returning
-	while(DMA3_CR & DMA_BUSY);
-#endif
-
-	return true;
-}
-
-
-/*-----------------------------------------------------------------
-M3_Unlock
-Returns true if M3 was unlocked, false if failed
-Added by MightyMax
------------------------------------------------------------------*/
-bool M3_Unlock(void)
-{
-	// run unlock sequence
-	volatile unsigned short tmp ;
-	tmp = *(volatile unsigned short *)0x08000000 ;
-	tmp = *(volatile unsigned short *)0x08E00002 ;
-	tmp = *(volatile unsigned short *)0x0800000E ;
-	tmp = *(volatile unsigned short *)0x08801FFC ;
-	tmp = *(volatile unsigned short *)0x0800104A ;
-	tmp = *(volatile unsigned short *)0x08800612 ;
-	tmp = *(volatile unsigned short *)0x08000000 ;
-	tmp = *(volatile unsigned short *)0x08801B66 ;
-	tmp = *(volatile unsigned short *)0x08800006 ;
-	tmp = *(volatile unsigned short *)0x08000000 ;
-	// test that we have register access
-	tmp = M3_REG_LBA1;
-	M3_REG_LBA1 = (~tmp & 0xFF);
-	tmp = (~tmp & 0xFF);
-	// did it change?
-	return (M3_REG_LBA1 == tmp) ;
-}
-
-bool M3CF_Shutdown(void) {
-	return M3CF_ClearStatus() ;
-} ;
-
-bool M3CF_StartUp(void) {
-	return M3_Unlock() ;
-} ;
-
-
-IO_INTERFACE io_m3cf = {
-	DEVICE_TYPE_M3CF,
-	FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA,
-	(FN_MEDIUM_STARTUP)&M3CF_StartUp,
-	(FN_MEDIUM_ISINSERTED)&M3CF_IsInserted,
-	(FN_MEDIUM_READSECTORS)&M3CF_ReadSectors,
-	(FN_MEDIUM_WRITESECTORS)&M3CF_WriteSectors,
-	(FN_MEDIUM_CLEARSTATUS)&M3CF_ClearStatus,
-	(FN_MEDIUM_SHUTDOWN)&M3CF_Shutdown
-} ;
-
-
-LPIO_INTERFACE M3CF_GetInterface(void) {
-	return &io_m3cf ;
-} ;
-
-#endif // SUPPORT_M3CF
diff --git a/backends/platform/ds/arm9/source/fat/io_m3cf.h b/backends/platform/ds/arm9/source/fat/io_m3cf.h
deleted file mode 100644
index 006c283adc..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_m3cf.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-	io_m3cf.h
-
-	Hardware Routines for reading a compact flash card
-	using the M3 CF
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_M3CF_H
-#define IO_M3CF_H
-
-// 'M3CF'
-#define DEVICE_TYPE_M3CF 0x4643334D
-
-#include "disc_io.h"
-
-// export interface
-extern LPIO_INTERFACE M3CF_GetInterface(void) ;
-
-#endif	// define IO_M3CF_H
-/*
-	io_m3cf.h
-
-	Hardware Routines for reading a compact flash card
-	using the M3 CF
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_M3CF_H
-#define IO_M3CF_H
-
-// 'M3CF'
-#define DEVICE_TYPE_M3CF 0x4643334D
-
-#include "disc_io.h"
-
-// export interface
-extern LPIO_INTERFACE M3CF_GetInterface(void) ;
-
-#endif	// define IO_M3CF_H
diff --git a/backends/platform/ds/arm9/source/fat/io_m3sd.c b/backends/platform/ds/arm9/source/fat/io_m3sd.c
deleted file mode 100644
index 2bbda37a5a..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_m3sd.c
+++ /dev/null
@@ -1,383 +0,0 @@
-
-#define io_M3SD_c
-#include "io_m3sd.h"
-#ifdef SUPPORT_M3SD
-//M3-SD interface SD card.
-
-#define DMA3SAD      *(volatile u32*)0x040000D4
-#define DMA3DAD      *(volatile u32*)0x040000D8
-#define DMA3CNT      *(volatile u32*)0x040000DC
-#define DMA3CR       *(volatile u16*)0x040000DE
-
-//SD dir control bit cmddir=bit0 clken=bit1
-//output
-#define SDDIR			(*(volatile u16*)0x8800000)
-
-//SD send get control bit send=bit0 get=bit1
-//output
-#define SDCON			(*(volatile u16*)0x9800000)
-
-//SD output data obyte[7:0]=AD[7:0]
-//output
-#define SDODA			(*(volatile u16*)0x9000000)
-
-//SD input data AD[7:0]=ibyte[7:0]
-//input
-#define SDIDA			(*(volatile u16*)0x9000000)
-
-//readsector data1
-#define SDIDA1			(*(volatile u16*)0x9200000)
-
-//readsector data2
-#define SDIDA2			(*(volatile u16*)0x9400000)
-
-//readsector data3
-#define SDIDA3			(*(volatile u16*)0x9600000)
-
-//SD stutas cmdneg=bit0 cmdpos=bit1 issend=bit2 isget=bit3
-//input
-#define SDSTA			(*(volatile u16*)0x9800000)
-
-#define M3_REG_STS		*(vu16*)(0x09800000)	// Status of the CF Card / Device control
-#define M3_DATA			(vu16*)(0x08800000)		// Pointer to buffer of CF data transered from card
-
-// CF Card status
-#define CF_STS_INSERTED1		0x20
-#define CF_STS_INSERTED2		0x30
-#define CF_STS_INSERTED3		0x22
-#define CF_STS_INSERTED4		0x32
-#define isM3ins(sta)	((sta==CF_STS_INSERTED1) || (sta==CF_STS_INSERTED2) || (sta==CF_STS_INSERTED3) || (sta==CF_STS_INSERTED4))
-
-
-#define CARD_TIMEOUT	400000		// Updated due to suggestion from SaTa, otherwise card will timeout sometimes on a write
-//#define CARD_TIMEOUT	(500*100)	// M3SD timeout nomal:500
-
-void SendCommand(u16 command, u32 sectorn);
-void PassRespond(u32 num);
-void SD_crc16(u16* buff,u16 num,u16* crc16buff);
-void SD_data_write(u16 *buff,u16* crc16buff);
-u16 M3_SetChipReg(u32 Data);
-
-//=========================================================
-u16 M3_SetChipReg(u32 Data)
-{
-	u16 i,j;
-
-	i = *(volatile u16*)(0x700001*2+0x8000000);
-
-	i = *(volatile u16*)(0x000007*2+0x8000000);
-	i = *(volatile u16*)(0x400ffe*2+0x8000000);
-	i = *(volatile u16*)(0x000825*2+0x8000000);
-
-	i = *(volatile u16*)(0x400309*2+0x8000000);
-	i = *(volatile u16*)(0x000000*2+0x8000000);
-	i = *(volatile u16*)(0x400db3*2+0x8000000);
-
-	i = *(volatile u16*)((Data*2)+0x8000000);
-
-	j = *(volatile u16*)(0x000407*2+0x8000000);
-	i = *(volatile u16*)(0x000000*2+0x8000000);
-
-	return j;
-}
-
-void M3_SelectSaver(u8 Bank)
-{
-	u16 i;
-
-	i = *(volatile u16*)(0x700001*2+0x8000000);
-
-	i = *(volatile u16*)(0x000007*2+0x8000000);
-	i = *(volatile u16*)(0x400FFE*2+0x8000000);
-	i = *(volatile u16*)(0x000825*2+0x8000000);
-
-	i = *(volatile u16*)(0x400309*2+0x8000000);
-	i = *(volatile u16*)(0x000000*2+0x8000000);
-	i = *(volatile u16*)(0x400db3*2+0x8000000);
-
-	i = *(volatile u16*)((Bank<<4)*2+0x8000000);
-
-	i = *(volatile u16*)(0x000407*2+0x8000000);
-	i = *(volatile u16*)(0x000000*2+0x8000000);
-}
-
-void DMA3(u32 src, u32 dst, u32 cnt)
-{
-	u16 i,j,cnttmp;
-
-	cnttmp = (cnt&0xffff);
-	if( ((dst&0x03) == 0)
-		&&((cnttmp&0x0f) == 0)
-		&&(cnttmp>0))
-	{
-		DC_FlushRange(dst,cnttmp*2);
-		DMA3CR &= (~0x3a00);
-		DMA3CR &= (~0x8000);
-		i = DMA3CR;
-		j = DMA3CR;
-
-		DMA3SAD=src;
-		DMA3DAD=dst;
-		DMA3CNT=cnt;
-	}
-	else
-	{
-		for(j=0;j<cnttmp;j++)
-		{
-			*(u16*)(dst+j*2) = *(u16*)(src+j*2);
-		}
-	}
-}
-
-void SendCommand(u16 command, u32 sectorn)
-{
-	SDCON=0x8;
-	SDIDA1=0x40+command;
-	SDIDA2=(sectorn>>7);
-	SDIDA3=(sectorn<<9);
-
-	SDDIR=0x29;
-	while ((SDSTA&0x01) != 0x01);
-	SDDIR=0x09;
-}
-
-void PassRespond(u32 num)
-{
-	u32 i,j,dmanum;
-
-	dmanum=(64+(num<<3))>>2;
-	SDDIR=0x8;
-	SDCON=0x4;
-
-	for(j=0;j<dmanum;j++)
-	{
-		i = SDDIR;
-	}
-}
-
-//read multi sectors function
-void readsectors(u16 * p,u32 sectorn,u16 number)
-{
-	u32 i,j;
-
-	SendCommand(18,sectorn);
-	for(i=0;i<number;i++,p+=0x100)
-	{
-		SDDIR=0x49;
-		while ( (SDSTA&0x40) !=0x40);
-		SDDIR=0x09;
-
-		SDDIR=0x8;
-		SDCON=0x4;
-		j = *(volatile u16*)0x8800000;
-		DMA3(0x8800000,(u32)p,0x80000100);
-		j = *(volatile u16*)0x8800000;
-		j = *(volatile u16*)0x8800000;
-		j = *(volatile u16*)0x8800000;
-		j = *(volatile u16*)0x8800000;
-
-		SDCON=0x8;
-	}
-
-	SendCommand(12,sectorn);
-	PassRespond(6);
-}
-
-//write one sector function
-void M3SD_writesector(u16 * p,u32 sectorn)
-{
-	u16 crc[4];
-	u16* check = (u16 *) malloc(512);
-	u16* data = (u16 *) malloc(512);
-	memcpy(data, p, 512);
-
-	int verify = 0;
-	int tries = 0;
-	do {
-		SendCommand(24,sectorn);
-		PassRespond(6);
-
-		SDDIR=0x4;
-		SDCON=0x0;
-
-		SD_crc16(data,512,crc);
-		SD_data_write(data,crc);
-
-		readsectors(check, sectorn, 1);
-
-		int r;
-		verify = 0;
-		for (r = 0; r < 256; r++) {
-			if (check[r] != data[r]) {
-				verify++;
-			}
-		}
-
-		if (verify > 0) {
-			tries++;
-		}
-
-	} while ((verify > 0) && (tries < 16));
-
-	free(data);
-	free(check);
-}	// */
-
-/*-----------------------------------------------------------------
-M3SD_IsInserted
-Is a compact flash card inserted?
-bool return OUT:  true if a CF card is inserted
------------------------------------------------------------------*/
-bool M3SD_IsInserted (void)
-{
-	u16 sta;
-	bool i;
-
-	M3_SetChipReg(0x400003);
-	M3_REG_STS = CF_STS_INSERTED1;
-	sta=M3_REG_STS;
-	i = ( isM3ins(sta) );
-
-	M3_SetChipReg(0x400002);
-	return i;
-}
-
-/*-----------------------------------------------------------------
-M3SD_ClearStatus
-Tries to make the CF card go back to idle mode
-bool return OUT:  true if a CF card is idle
------------------------------------------------------------------*/
-bool M3SD_ClearStatus (void)
-{
-	int i;
-	u16 sta;
-
-	M3_SetChipReg(0x400003);
-	i = 0;
-	M3_REG_STS = CF_STS_INSERTED1;
-	while (i < CARD_TIMEOUT)
-	{
-		sta=M3_REG_STS;
-		if(  isM3ins(sta)  )break;
-		i++;
-	}
-
-	M3_SetChipReg(0x400002);
-	if (i >= CARD_TIMEOUT) return false;
-
-	return true;
-}
-
-/*-----------------------------------------------------------------
-M3SD_ReadSectors
-Read 512 byte sector numbered "sector" into "buffer"
-u32 sector IN: address of first 512 byte sector on CF card to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer OUT: pointer to 512 byte buffer to store data in
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool M3SD_ReadSectors(u32 sector, u8 numSecs, void* buffer)
-{
-	//read multi sectors function
-	M3_SetChipReg(0x400003);
-	readsectors((u16*)buffer,sector,numSecs);
-	M3_SetChipReg(0x400002);
-	return true;	// */
-}
-/*-----------------------------------------------------------------
-M3SD_WriteSectors
-Write 512 byte sector numbered "sector" from "buffer"
-u32 sector IN: address of 512 byte sector on CF card to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer IN: pointer to 512 byte buffer to read data from
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool M3SD_WriteSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	bool r=true;
-	int i;
-	M3_SetChipReg(0x400003);
-	for(i=0;i<numSecs;i++)
-	{
-		M3SD_writesector((u16*)((u32)buffer+512*i),sector+i);
-	}
-	M3_SetChipReg(0x400002);
-	return r;
-}
-
-/*-----------------------------------------------------------------
-M3_Unlock
-Returns true if M3 was unlocked, false if failed
-Added by MightyMax
------------------------------------------------------------------*/
-bool M3SD_Unlock(void)
-{
-	vu16 sta;
-	bool i;
-
-	// run unlock sequence
-	volatile unsigned short tmp;
-
-	M3_SetChipReg(0x400003);
-	tmp = *(volatile unsigned short *)0x08000000 ;
-	tmp = *(volatile unsigned short *)0x08E00002 ;
-	tmp = *(volatile unsigned short *)0x0800000E ;
-	tmp = *(volatile unsigned short *)0x08801FFC ;
-	tmp = *(volatile unsigned short *)0x0800104A ;
-	tmp = *(volatile unsigned short *)0x08800612 ;
-	tmp = *(volatile unsigned short *)0x08000000 ;
-	tmp = *(volatile unsigned short *)0x08801B66 ;
-	tmp = *(volatile unsigned short *)0x08800006 ;
-	tmp = *(volatile unsigned short *)0x08000000 ;
-
-	// test that we have register access
-	sta=M3_REG_STS;
-	sta=M3_REG_STS;
-	if(  isM3ins(sta)  )
-	{
-		i = true;
-	}
-	else
-	{
-		i = false;
-	}
-
-	M3_SetChipReg(0x400002);
-	return i;
-}
-
-bool M3SD_Shutdown(void)
-{
-	return M3SD_ClearStatus() ;
-}
-
-bool M3SD_StartUp(void)
-{
-	vu16* waitCr = (vu16*)0x4000204;
-
-	*waitCr |= 0x6000;
-//	*(vu16*)0x4000204=0x6000;
-	// Try unlocking 3 times, because occationally it fails to detect the reader.
-	return M3SD_Unlock() | M3SD_Unlock() | M3SD_Unlock();
-}
-
-IO_INTERFACE io_m3sd =
-{
-	0x4453334D,	// 'M3SD'
-	FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE,
-	(FN_MEDIUM_STARTUP)&M3SD_StartUp,
-	(FN_MEDIUM_ISINSERTED)&M3SD_IsInserted,
-	(FN_MEDIUM_READSECTORS)&M3SD_ReadSectors,
-	(FN_MEDIUM_WRITESECTORS)&M3SD_WriteSectors,
-	(FN_MEDIUM_CLEARSTATUS)&M3SD_ClearStatus,
-	(FN_MEDIUM_SHUTDOWN)&M3SD_Shutdown
-};
-
-LPIO_INTERFACE M3SD_GetInterface(void)
-{
-	return &io_m3sd ;
-}
-
-#endif
diff --git a/backends/platform/ds/arm9/source/fat/io_m3sd.h b/backends/platform/ds/arm9/source/fat/io_m3sd.h
deleted file mode 100644
index 0723a2f468..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_m3sd.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-	io_m3sd.h  by SaTa.
-
-	Hardware Routines for reading a compact flash card
-	using the GBA Movie Player
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_M3SD_H
-#define IO_M3SD_H
-
-#include "disc_io.h"
-
-u16 M3_SetChipReg(u32 Data);
-void M3_SelectSaver(u8 Bank);
-
-// export interface
-extern LPIO_INTERFACE M3SD_GetInterface(void) ;
-
-#endif
diff --git a/backends/platform/ds/arm9/source/fat/io_m3sd_asm.s b/backends/platform/ds/arm9/source/fat/io_m3sd_asm.s
deleted file mode 100644
index f2bcce7da9..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_m3sd_asm.s
+++ /dev/null
@@ -1,195 +0,0 @@
-	.TEXT
-@	AREA M3SD, CODE, READONLY
-@	ENTRY
- at -----------------------------------
-@	EXPORT SD_crc16
-@	EXPORT SD_data_write
-
- at CSYNC	EQU	0x9800000
- at SDDIR	EQU 0x8800000
- at SDCON	EQU	0x9800000
- at SDODA	EQU 0x9000000
-.equ CSYNC,0x9800000
-.equ SDDIR,0x8800000
-.equ SDCON,0x9800000
-.equ SDODA,0x9000000
-
-	.ALIGN
-	.CODE 32
-
-clkout:
-	stmfd   r13!,{r0-r1}
-	ldr     r1,=SDDIR
-	mov     r0,#0x4
-	strh    r0,[r1]
-	mov     r0,r0
-	mov     r0,r0
-	mov     r0,#0xc
-	strh    r0,[r1]
-	ldmfd	r13!,{r0-r1}
-	bx      r14
-
-clkin:
-	stmfd   r13!,{r0-r1}
-	ldr     r1,=SDDIR
-	mov     r0,#0x0
-	strh    r0,[r1]
-	mov     r0,r0
-	mov     r0,r0
-	mov     r0,#0x8
-	strh    r0,[r1]
-	ldmfd	r13!,{r0-r1}
-	bx      r14
-
-wait_ready:
-	stmfd   r13!,{r0-r2}
-	mov     r2,#32
-	mov	    r1,#SDODA
-sd_write_loop2:
-	mov	    r0,#0xff @end bit
-	strh    r0,[r1]
-	bl      clkout
-	subs    r2, r2, #1
-	bne     sd_write_loop2
-
-sd_write_busy:
-	bl      clkin
-	ldrh    r0,[r1]
-	tst	    r0,#0x100
-	beq	    sd_write_busy
-	ldmfd	r13!,{r0-r1}
-	bx      r14
-
- at ------void SD_crc16(u16* buff,u16 num,u16* crc16buff)
-
-    .GLOBAL SD_crc16
-
-SD_crc16:
-	stmfd   r13!,{r4-r9}
-	mov	    r9,r2
-
-	mov	    r3,#0
-	mov	    r4,#0
-	mov	    r5,#0
-	mov	    r6,#0
-
-	ldr	    r7,=0x80808080
-	ldr	    r8,=0x1021
-	mov	    r1,r1,lsl #3
-sd_crc16_loop:
-
-	tst	    r7,#0x80
-	ldrneb	r2,[r0],#1
-
-	mov	    r3,r3,lsl #1
-	tst	    r3,#0x10000
-	eorne	r3,r3,r8
-	tst	    r2,r7,lsr #24
-	eorne	r3,r3,r8
-
-	mov	    r4,r4,lsl #1
-	tst	    r4,#0x10000
-	eorne	r4,r4,r8
-	tst	    r2,r7,lsr #25
-	eorne	r4,r4,r8
-
-	mov	    r5,r5,lsl #1
-	tst	    r5,#0x10000
-	eorne	r5,r5,r8
-	tst	    r2,r7,lsr #26
-	eorne	r5,r5,r8
-
-	mov	    r6,r6,lsl #1
-	tst	    r6,#0x10000
-	eorne	r6,r6,r8
-	tst	    r2,r7,lsr #27
-	eorne	r6,r6,r8
-
-	mov	    r7,r7,ror #4
-	subs	r1,r1,#4
-	bne     sd_crc16_loop
-
-	mov	    r2,r9
-	mov	    r8,#16
-sd_crc16_write_data:
-	mov	    r7,r7,lsl #4
-	tst	    r3,#0x8000
-	orrne   r7,r7,#8
-	tst	    r4,#0x8000
-	orrne   r7,r7,#4
-	tst	    r5,#0x8000
-	orrne   r7,r7,#2
-	tst	    r6,#0x8000
-	orrne   r7,r7,#1
-
-	mov	    r3,r3,lsl #1
-	mov	    r4,r4,lsl #1
-	mov	    r5,r5,lsl #1
-	mov	    r6,r6,lsl #1
-
-	sub	    r8,r8,#1
-	tst	    r8,#1
-	streqb  r7,[r2],#1
-	cmp	    r8,#0
-	bne	    sd_crc16_write_data
-
-	ldmfd   r13!,{r4-r9}
-	bx      r14
- at ------end-----------------------------------
-
- at -----------------viod SD_data_write(u16 *buff,u16* crc16buff)-------------------
-    .GLOBAL SD_data_write
-SD_data_write:
-	stmfd   r13!,{r4-r5,r14}
-	mov     r5,#512
-	mov	    r2,#SDODA
-sd_data_write_busy:
-	bl      clkin
-	ldrh    r3,[r2]
-	tst	    r3,#0x100
-	beq	    sd_data_write_busy
-
-	mov	    r3,#0 @star bit
-	strh    r3,[r2]
-	bl      clkout
-
-sd_data_write_loop:
-	ldrh    r4,[r0],#2
-	mov     r3,r4,lsr#4
-	strh    r3,[r2]
-	bl      clkout
-	mov     r3,r4
-	strh    r3,[r2]
-	bl      clkout
-	mov     r3,r4,lsr#12
-	strh    r3,[r2]
-	bl      clkout
-	mov     r3,r4,lsr#8
-	strh    r3,[r2]
-	bl      clkout
-
-	subs    r5, r5, #2
-	bne     sd_data_write_loop
-
-	cmp	    r1,#0
-	movne   r0,r1
-	movne   r1,#0
-	movne   r5,#8
-	bne	    sd_data_write_loop
-
-	mov     r5,#32
-sd_data_write_loop2:
-	mov	    r3,#0xff @end bit
-	strh    r3,[r2]
-	bl      clkout
-	subs    r5, r5, #1
-	bne     sd_data_write_loop2
-
-sd_data_write_busy2:
-	bl      clkin
-	ldrh    r3,[r2]
-	tst	    r3,#0x100
-	beq	    sd_data_write_busy2
-
-	ldmfd   r13!,{r4-r5,r15}
- at -----------------end-------------------
diff --git a/backends/platform/ds/arm9/source/fat/io_mmcf.c b/backends/platform/ds/arm9/source/fat/io_mmcf.c
deleted file mode 100644
index 5ccb3122e4..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_mmcf.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
-  io_mmcf.c based on
-
-	io_mpcf.c based on
-
-	compact_flash.c
-	By chishm (Michael Chisholm)
-
-	Hardware Routines for reading a compact flash card
-	using the GBA Movie Player
-
-	CF routines modified with help from Darkfader
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-
-#include "io_mmcf.h"
-
-#ifdef SUPPORT_MMCF
-
-//---------------------------------------------------------------
-// DMA
-#ifdef _CF_USE_DMA
- #ifndef NDS
-  #include "gba_dma.h"
- #else
-  #include <nds/dma.h>
-  #ifdef ARM9
-   #include <nds/arm9/cache.h>
-  #endif
- #endif
-#endif
-
-//---------------------------------------------------------------
-// CF Addresses & Commands
-
-#define CF_RD_DATA          (*(volatile u16*)(0x08000000 + 0x00000))
-#define CF_RD_ERROR         (*(volatile u16*)(0x08000000 + 0x20000))
-#define CF_RD_SECTOR_COUNT  (*(volatile u16*)(0x08000000 + 0x40000))
-#define CF_RD_SECTOR_NO     (*(volatile u16*)(0x08000000 + 0x60000))
-#define CF_RD_CYLINDER_LOW  (*(volatile u16*)(0x08000000 + 0x80000))
-#define CF_RD_CYLINDER_HIGH (*(volatile u16*)(0x08000000 + 0xA0000))
-#define CF_RD_SEL_HEAD      (*(volatile u16*)(0x08000000 + 0xC0000))
-#define CF_RD_STATUS        (*(volatile u16*)(0x08000000 + 0xE0000))
-
-#define CF_WR_DATA          (*(volatile u16*)(0x08000000 + 0x00000))
-#define CF_WR_FEATURES      (*(volatile u16*)(0x08000000 + 0x20000))
-#define CF_WR_SECTOR_COUNT  (*(volatile u16*)(0x08000000 + 0x40000))
-#define CF_WR_SECTOR_NO     (*(volatile u16*)(0x08000000 + 0x60000))
-#define CF_WR_CYLINDER_LOW  (*(volatile u16*)(0x08000000 + 0x80000))
-#define CF_WR_CYLINDER_HIGH (*(volatile u16*)(0x08000000 + 0xA0000))
-#define CF_WR_SEL_HEAD      (*(volatile u16*)(0x08000000 + 0xC0000))
-#define CF_WR_COMMAND       (*(volatile u16*)(0x08000000 + 0xE0000))
-
-
-#define GAME_PAK		0x08000000			// Game pack start address
-#define MP_DATA			(vu16*)(GAME_PAK + 0x01000000)		// Pointer to buffer of CF data transered from card
-#define MP_REG_LBA1		*(vu16*)(GAME_PAK + 0x01060000)	// 1st byte of sector address
-#define CARD_TIMEOUT	10000000		// Updated due to suggestion from SaTa, otherwise card will timeout sometimes on a write
-
-
-static bool cf_block_ready(void)
-{
-  int i;
-
-  i = 0;
-
-  /*
-  do
-  {
-    while (!(CF_RD_STATUS & 0x40));
-  } while (CF_RD_STATUS & 0x80);
-  */
-
-  do
-  {
-    i++;
-    while ( (!(CF_RD_STATUS & 0x40)) && (i < CARD_TIMEOUT) ) i++;
-  } while ( (CF_RD_STATUS & 0x80) && (i < CARD_TIMEOUT) );
-
-  if (i >= CARD_TIMEOUT) {
-	return false;
-  }
-
-  return true;
-}
-
-
-static bool cf_set_features(u32 feature)
-{
-  if ( !cf_block_ready() ) return false;
-
-  CF_WR_FEATURES = feature;
-  CF_WR_SECTOR_COUNT = 0x00;  // config???
-  CF_WR_SEL_HEAD = 0x00;
-  CF_WR_COMMAND = 0xEF;
-
-  return true;
-}
-
-
-
-/*-----------------------------------------------------------------
-MMCF_IsInserted
-Is a compact flash card inserted?
-bool return OUT:  true if a CF card is inserted
------------------------------------------------------------------*/
-bool MMCF_IsInserted (void)
-{
-  if ( !cf_set_features(0xAA) ) return false;
-
-  return true;
-}
-
-
-/*-----------------------------------------------------------------
-MMCF_ClearStatus
-Tries to make the CF card go back to idle mode
-bool return OUT:  true if a CF card is idle
------------------------------------------------------------------*/
-bool MMCF_ClearStatus (void)
-{
-	return true;
-}
-
-
-/*-----------------------------------------------------------------
-MMCF_ReadSectors
-Read 512 byte sector numbered "sector" into "buffer"
-u32 sector IN: address of first 512 byte sector on CF card to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer OUT: pointer to 512 byte buffer to store data in
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool MMCF_ReadSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int i;
-	int j = (numSecs > 0 ? numSecs : 256);
-	u16 *buff = (u16*)buffer;
-#ifdef _CF_ALLOW_UNALIGNED
-	u8 *buff_u8 = (u8*)buffer;
-	int temp;
-#endif
-
-#if (defined _CF_USE_DMA) && (defined NDS) && (defined ARM9)
-	DC_FlushRange( buffer, j * BYTE_PER_READ);
-#endif
-
-  if ( !cf_block_ready() ) return false;
-
-  CF_WR_SECTOR_COUNT = numSecs;
-  CF_WR_SECTOR_NO = sector;
-  CF_WR_CYLINDER_LOW = sector >> 8;
-  CF_WR_CYLINDER_HIGH = sector >> 16;
-  CF_WR_SEL_HEAD = ((sector >> 24) & 0x0F) | 0xE0;
-  CF_WR_COMMAND = 0x20; // read sectors
-
-  while (j--)
-  {
-    if ( !cf_block_ready() ) return false;
-
-#ifdef _CF_USE_DMA
- #ifdef NDS
-		DMA3_SRC = (u32)MP_DATA;
-		DMA3_DEST = (u32)buff;
-		DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_SRC_FIX;
- #else
-		DMA3COPY ( MP_DATA, buff, 256 | DMA16 | DMA_ENABLE | DMA_SRC_FIXED);
- #endif
-		buff += BYTE_PER_READ / 2;
-#elif defined _CF_ALLOW_UNALIGNED
-		i=256;
-		if ((u32)buff_u8 & 0x01) {
-			while(i--)
-			{
-				temp = *MP_DATA;
-				*buff_u8++ = temp & 0xFF;
-				*buff_u8++ = temp >> 8;
-			}
-		} else {
-		while(i--)
-			*buff++ = *MP_DATA;
-		}
-#else
-		i=256;
-		while(i--)
-			*buff++ = *MP_DATA;
-#endif
-  }
-
-#if (defined _CF_USE_DMA) && (defined NDS)
-	// Wait for end of transfer before returning
-	while(DMA3_CR & DMA_BUSY);
-#endif
-
-	return true;
-}
-
-
-
-/*-----------------------------------------------------------------
-MMCF_WriteSectors
-Write 512 byte sector numbered "sector" from "buffer"
-u32 sector IN: address of 512 byte sector on CF card to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer IN: pointer to 512 byte buffer to read data from
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool MMCF_WriteSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int i;
-	int j = (numSecs > 0 ? numSecs : 256);
-	u16 *buff = (u16*)buffer;
-#ifdef _CF_ALLOW_UNALIGNED
-	u8 *buff_u8 = (u8*)buffer;
-	int temp;
-#endif
-
-#if defined _CF_USE_DMA && defined NDS && defined ARM9
-	DC_FlushRange( buffer, j * BYTE_PER_READ);
-#endif
-
-	if (numSecs > 1)
-	{
-		int r = 0;
-
-		for (r = 0; r < numSecs; r++)
-		{
-			MMCF_WriteSectors(sector + r, 1, ((unsigned char *) (buffer)) + 512);
-		}
-  }
-
-  if ( !cf_block_ready() ) return false;
-
-  CF_WR_SECTOR_COUNT = numSecs;
-  CF_WR_SECTOR_NO = sector;
-  CF_WR_CYLINDER_LOW = sector >> 8;
-  CF_WR_CYLINDER_HIGH = sector >> 16;
-  CF_WR_SEL_HEAD = ((sector >> 24) & 0x0F) | 0xE0;
-  CF_WR_COMMAND = 0x30; // write sectors
-
-  while (j--)
-  {
-    if ( !cf_block_ready() ) return false;
-
-#ifdef _CF_USE_DMA
- #ifdef NDS
-		DMA3_SRC = (u32)buff;
-		DMA3_DEST = (u32)MP_DATA;
-		DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_DST_FIX;
- #else
-		DMA3COPY( buff, MP_DATA, 256 | DMA16 | DMA_ENABLE | DMA_DST_FIXED);
- #endif
-		buff += BYTE_PER_READ / 2;
-#elif defined _CF_ALLOW_UNALIGNED
-		i=256;
-		if ((u32)buff_u8 & 0x01) {
-			while(i--)
-			{
-				temp = *buff_u8++;
-				temp |= *buff_u8++ << 8;
-				*MP_DATA = temp;
-			}
-		} else {
-		while(i--)
-			*MP_DATA = *buff++;
-		}
-#else
-		i=256;
-		while(i--)
-			*MP_DATA = *buff++;
-#endif
-
-  }
-
-#if defined _CF_USE_DMA && defined NDS
-	// Wait for end of transfer before returning
-	while(DMA3_CR & DMA_BUSY);
-#endif
-
-//#define _CF_VERIFY
-
-#ifdef _CF_VERIFY
-	char* tmp = malloc(512);
-	int r;
-
-	for (r = 0; r < numSecs; r++)
-	{
-		MMCF_ReadSectors(sector + r, 1, tmp);
-		while (memcmp(temp, ((unsigned char *) (buffer)) + 512 * r, 512) != 0)
-		{
-			consolePrintf("Rewriting sector %d\n", r);
-			MMCF_WriteSectors(sector + r, 1, ((unsigned char *) (buffer)) + 512 * r);
-			MMCF_ReadSectors(sector + r, 1, tmp);
-		}
-	}
-
-	free(temp);
-#endif
-
-	return true;
-}
-
-/*-----------------------------------------------------------------
-MMCF_Shutdown
-unload the GBAMP CF interface
------------------------------------------------------------------*/
-bool MMCF_Shutdown(void)
-{
-	return MMCF_ClearStatus() ;
-}
-
-/*-----------------------------------------------------------------
-MMCF_StartUp
-initializes the CF interface, returns true if successful,
-otherwise returns false
------------------------------------------------------------------*/
-bool MMCF_StartUp(void)
-{
-  /*
-	u8 temp = MP_REG_LBA1;
-	MP_REG_LBA1 = (~temp & 0xFF);
-	temp = (~temp & 0xFF);
-	return (MP_REG_LBA1 == temp);
-  */
-  if ( (CF_RD_STATUS != 0x0050) || ( *((u8 *) (0x080000B2)) == 0x96) )
-  {
-	return false;
-  }
-
-  return true;
-}
-
-/*-----------------------------------------------------------------
-the actual interface structure
------------------------------------------------------------------*/
-IO_INTERFACE io_mmcf = {
-	DEVICE_TYPE_MMCF,
-	FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA,
-	(FN_MEDIUM_STARTUP)&MMCF_StartUp,
-	(FN_MEDIUM_ISINSERTED)&MMCF_IsInserted,
-	(FN_MEDIUM_READSECTORS)&MMCF_ReadSectors,
-	(FN_MEDIUM_WRITESECTORS)&MMCF_WriteSectors,
-	(FN_MEDIUM_CLEARSTATUS)&MMCF_ClearStatus,
-	(FN_MEDIUM_SHUTDOWN)&MMCF_Shutdown
-} ;
-
-/*-----------------------------------------------------------------
-MPCF_GetInterface
-returns the interface structure to host
------------------------------------------------------------------*/
-LPIO_INTERFACE MMCF_GetInterface(void) {
-	return &io_mmcf ;
-} ;
-
-#endif // SUPPORT_MMCF
diff --git a/backends/platform/ds/arm9/source/fat/io_mmcf.h b/backends/platform/ds/arm9/source/fat/io_mmcf.h
deleted file mode 100644
index fa9e6536ee..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_mmcf.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-	io_mmcf.h
-
-	Hardware Routines for reading a compact flash card
-	using the GBA Movie Player
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_MMCF_H
-#define IO_MMCF_H
-
-// 'MMCF'
-#define DEVICE_TYPE_MMCF 0x4646504D
-
-#include "disc_io.h"
-
-// export interface
-extern LPIO_INTERFACE MMCF_GetInterface(void) ;
-
-#endif	// define IO_MMCF_H
diff --git a/backends/platform/ds/arm9/source/fat/io_mpcf.c b/backends/platform/ds/arm9/source/fat/io_mpcf.c
deleted file mode 100644
index 6b56e29291..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_mpcf.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
-	io_mpcf.c based on
-
-	compact_flash.c
-	By chishm (Michael Chisholm)
-
-	Hardware Routines for reading a compact flash card
-	using the GBA Movie Player
-
-	CF routines modified with help from Darkfader
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-
-#include "io_mpcf.h"
-
-#ifdef SUPPORT_MPCF
-
-//---------------------------------------------------------------
-// DMA
-#ifdef _CF_USE_DMA
- #ifndef NDS
-  #include "gba_dma.h"
- #else
-  #include <nds/dma.h>
-  #ifdef ARM9
-   #include <nds/arm9/cache.h>
-  #endif
- #endif
-#endif
-
-//---------------------------------------------------------------
-// CF Addresses & Commands
-
-#define GAME_PAK		0x08000000			// Game pack start address
-
-// GBAMP CF Addresses
-#define MP_REG_STS		*(vu16*)(GAME_PAK + 0x018C0000)	// Status of the CF Card / Device control
-#define MP_REG_CMD		*(vu16*)(GAME_PAK + 0x010E0000)	// Commands sent to control chip and status return
-#define MP_REG_ERR		*(vu16*)(GAME_PAK + 0x01020000)	// Errors / Features
-
-#define MP_REG_SEC		*(vu16*)(GAME_PAK + 0x01040000)	// Number of sector to transfer
-#define MP_REG_LBA1		*(vu16*)(GAME_PAK + 0x01060000)	// 1st byte of sector address
-#define MP_REG_LBA2		*(vu16*)(GAME_PAK + 0x01080000)	// 2nd byte of sector address
-#define MP_REG_LBA3		*(vu16*)(GAME_PAK + 0x010A0000)	// 3rd byte of sector address
-#define MP_REG_LBA4		*(vu16*)(GAME_PAK + 0x010C0000)	// last nibble of sector address | 0xE0
-
-#define MP_DATA			(vu16*)(GAME_PAK + 0x01000000)		// Pointer to buffer of CF data transered from card
-
-// CF Card status
-#define CF_STS_INSERTED		0x50
-#define CF_STS_REMOVED		0x00
-#define CF_STS_READY		0x58
-
-#define CF_STS_DRQ			0x08
-#define CF_STS_BUSY			0x80
-
-// CF Card commands
-#define CF_CMD_LBA			0xE0
-#define CF_CMD_READ			0x20
-#define CF_CMD_WRITE		0x30
-
-#define CARD_TIMEOUT	10000000		// Updated due to suggestion from SaTa, otherwise card will timeout sometimes on a write
-
-
-/*-----------------------------------------------------------------
-MPCF_IsInserted
-Is a compact flash card inserted?
-bool return OUT:  true if a CF card is inserted
------------------------------------------------------------------*/
-bool MPCF_IsInserted (void)
-{
-	// Change register, then check if value did change
-	MP_REG_STS = CF_STS_INSERTED;
-	return ((MP_REG_STS & 0xff) == CF_STS_INSERTED);
-}
-
-
-/*-----------------------------------------------------------------
-MPCF_ClearStatus
-Tries to make the CF card go back to idle mode
-bool return OUT:  true if a CF card is idle
------------------------------------------------------------------*/
-bool MPCF_ClearStatus (void)
-{
-	int i;
-
-	// Wait until CF card is finished previous commands
-	i=0;
-	while ((MP_REG_CMD & CF_STS_BUSY) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-
-	// Wait until card is ready for commands
-	i = 0;
-	while ((!(MP_REG_STS & CF_STS_INSERTED)) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-	if (i >= CARD_TIMEOUT)
-		return false;
-
-	return true;
-}
-
-
-/*-----------------------------------------------------------------
-MPCF_ReadSectors
-Read 512 byte sector numbered "sector" into "buffer"
-u32 sector IN: address of first 512 byte sector on CF card to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer OUT: pointer to 512 byte buffer to store data in
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool MPCF_ReadSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int i;
-	int j = (numSecs > 0 ? numSecs : 256);
-	u16 *buff = (u16*)buffer;
-#ifdef _CF_ALLOW_UNALIGNED
-	u8 *buff_u8 = (u8*)buffer;
-	int temp;
-#endif
-
-#if (defined _CF_USE_DMA) && (defined NDS) && (defined ARM9)
-	DC_FlushRange( buffer, j * BYTE_PER_READ);
-#endif
-
-	// Wait until CF card is finished previous commands
-	i=0;
-	while ((MP_REG_CMD & CF_STS_BUSY) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-
-	// Wait until card is ready for commands
-	i = 0;
-	while ((!(MP_REG_STS & CF_STS_INSERTED)) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-	if (i >= CARD_TIMEOUT)
-		return false;
-
-	// Set number of sectors to read
-	MP_REG_SEC = numSecs;
-
-	// Set read sector
-	MP_REG_LBA1 = sector & 0xFF;						// 1st byte of sector number
-	MP_REG_LBA2 = (sector >> 8) & 0xFF;					// 2nd byte of sector number
-	MP_REG_LBA3 = (sector >> 16) & 0xFF;				// 3rd byte of sector number
-	MP_REG_LBA4 = ((sector >> 24) & 0x0F )| CF_CMD_LBA;	// last nibble of sector number
-
-	// Set command to read
-	MP_REG_CMD = CF_CMD_READ;
-
-
-	while (j--)
-	{
-		// Wait until card is ready for reading
-		i = 0;
-		while (((MP_REG_STS & 0xff)!= CF_STS_READY) && (i < CARD_TIMEOUT))
-		{
-			i++;
-		}
-		if (i >= CARD_TIMEOUT)
-			return false;
-
-		// Read data
-#ifdef _CF_USE_DMA
- #ifdef NDS
-		DMA3_SRC = (u32)MP_DATA;
-		DMA3_DEST = (u32)buff;
-		DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_SRC_FIX;
- #else
-		DMA3COPY ( MP_DATA, buff, 256 | DMA16 | DMA_ENABLE | DMA_SRC_FIXED);
- #endif
-		buff += BYTE_PER_READ / 2;
-#elif defined _CF_ALLOW_UNALIGNED
-		i=256;
-		if ((u32)buff_u8 & 0x01) {
-			while(i--)
-			{
-				temp = *MP_DATA;
-				*buff_u8++ = temp & 0xFF;
-				*buff_u8++ = temp >> 8;
-			}
-		} else {
-		while(i--)
-			*buff++ = *MP_DATA;
-		}
-#else
-		i=256;
-		while(i--)
-			*buff++ = *MP_DATA;
-#endif
-	}
-#if (defined _CF_USE_DMA) && (defined NDS)
-	// Wait for end of transfer before returning
-	while(DMA3_CR & DMA_BUSY);
-#endif
-	return true;
-}
-
-
-
-/*-----------------------------------------------------------------
-MPCF_WriteSectors
-Write 512 byte sector numbered "sector" from "buffer"
-u32 sector IN: address of 512 byte sector on CF card to read
-u8 numSecs IN: number of 512 byte sectors to read,
- 1 to 256 sectors can be read, 0 = 256
-void* buffer IN: pointer to 512 byte buffer to read data from
-bool return OUT: true if successful
------------------------------------------------------------------*/
-bool MPCF_WriteSectors (u32 sector, u8 numSecs, void* buffer)
-{
-	int i;
-	int j = (numSecs > 0 ? numSecs : 256);
-	u16 *buff = (u16*)buffer;
-#ifdef _CF_ALLOW_UNALIGNED
-	u8 *buff_u8 = (u8*)buffer;
-	int temp;
-#endif
-
-#if defined _CF_USE_DMA && defined NDS && defined ARM9
-	DC_FlushRange( buffer, j * BYTE_PER_READ);
-#endif
-
-	// Wait until CF card is finished previous commands
-	i=0;
-	while ((MP_REG_CMD & CF_STS_BUSY) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-
-	// Wait until card is ready for commands
-	i = 0;
-	while ((!(MP_REG_STS & CF_STS_INSERTED)) && (i < CARD_TIMEOUT))
-	{
-		i++;
-	}
-	if (i >= CARD_TIMEOUT)
-		return false;
-
-	// Set number of sectors to write
-	MP_REG_SEC = numSecs;
-
-	// Set write sector
-	MP_REG_LBA1 = sector & 0xFF;						// 1st byte of sector number
-	MP_REG_LBA2 = (sector >> 8) & 0xFF;					// 2nd byte of sector number
-	MP_REG_LBA3 = (sector >> 16) & 0xFF;				// 3rd byte of sector number
-	MP_REG_LBA4 = ((sector >> 24) & 0x0F )| CF_CMD_LBA;	// last nibble of sector number
-
-	// Set command to write
-	MP_REG_CMD = CF_CMD_WRITE;
-
-	while (j--)
-	{
-		// Wait until card is ready for writing
-		i = 0;
-		while (((MP_REG_STS & 0xff) != CF_STS_READY) && (i < CARD_TIMEOUT))
-		{
-			i++;
-		}
-		if (i >= CARD_TIMEOUT)
-			return false;
-
-		// Write data
-#ifdef _CF_USE_DMA
- #ifdef NDS
-		DMA3_SRC = (u32)buff;
-		DMA3_DEST = (u32)MP_DATA;
-		DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_DST_FIX;
- #else
-		DMA3COPY( buff, MP_DATA, 256 | DMA16 | DMA_ENABLE | DMA_DST_FIXED);
- #endif
-		buff += BYTE_PER_READ / 2;
-#elif defined _CF_ALLOW_UNALIGNED
-		i=256;
-		if ((u32)buff_u8 & 0x01) {
-			while(i--)
-			{
-				temp = *buff_u8++;
-				temp |= *buff_u8++ << 8;
-				*MP_DATA = temp;
-			}
-		} else {
-		while(i--)
-			*MP_DATA = *buff++;
-		}
-#else
-		i=256;
-		while(i--)
-			*MP_DATA = *buff++;
-#endif
-	}
-#if defined _CF_USE_DMA && defined NDS
-	// Wait for end of transfer before returning
-	while(DMA3_CR & DMA_BUSY);
-#endif
-
-	return true;
-}
-
-/*-----------------------------------------------------------------
-MPCF_Shutdown
-unload the GBAMP CF interface
------------------------------------------------------------------*/
-bool MPCF_Shutdown(void)
-{
-	return MPCF_ClearStatus() ;
-}
-
-/*-----------------------------------------------------------------
-MPCF_StartUp
-initializes the CF interface, returns true if successful,
-otherwise returns false
------------------------------------------------------------------*/
-bool MPCF_StartUp(void)
-{
-	u8 temp = MP_REG_LBA1;
-	MP_REG_LBA1 = (~temp & 0xFF);
-	temp = (~temp & 0xFF);
-	// NDM: Added GBA ROM header check so that this doesn't detect a Max Media Dock!
-	return (MP_REG_LBA1 == temp) && ( *((u8 *) (0x080000B2)) == 0x96);
-}
-
-/*-----------------------------------------------------------------
-the actual interface structure
------------------------------------------------------------------*/
-IO_INTERFACE io_mpcf = {
-	DEVICE_TYPE_MPCF,
-	FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA,
-	(FN_MEDIUM_STARTUP)&MPCF_StartUp,
-	(FN_MEDIUM_ISINSERTED)&MPCF_IsInserted,
-	(FN_MEDIUM_READSECTORS)&MPCF_ReadSectors,
-	(FN_MEDIUM_WRITESECTORS)&MPCF_WriteSectors,
-	(FN_MEDIUM_CLEARSTATUS)&MPCF_ClearStatus,
-	(FN_MEDIUM_SHUTDOWN)&MPCF_Shutdown
-} ;
-
-/*-----------------------------------------------------------------
-MPCF_GetInterface
-returns the interface structure to host
------------------------------------------------------------------*/
-LPIO_INTERFACE MPCF_GetInterface(void) {
-	return &io_mpcf ;
-} ;
-
-#endif // SUPPORT_MPCF
diff --git a/backends/platform/ds/arm9/source/fat/io_mpcf.h b/backends/platform/ds/arm9/source/fat/io_mpcf.h
deleted file mode 100644
index 8ec8859097..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_mpcf.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-	io_mpcf.h
-
-	Hardware Routines for reading a compact flash card
-	using the GBA Movie Player
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_MPCF_H
-#define IO_MPCF_H
-
-// 'MPCF'
-#define DEVICE_TYPE_MPCF 0x4643504D
-
-#include "disc_io.h"
-
-// export interface
-extern LPIO_INTERFACE MPCF_GetInterface(void) ;
-
-#endif	// define IO_MPCF_H
-/*
-	io_mpcf.h
-
-	Hardware Routines for reading a compact flash card
-	using the GBA Movie Player
-
-	This software is completely free. No warranty is provided.
-	If you use it, please give me credit and email me about your
-	project at chishm at hotmail.com
-
-	See gba_nds_fat.txt for help and license details.
-*/
-
-#ifndef IO_MPCF_H
-#define IO_MPCF_H
-
-// 'MPCF'
-#define DEVICE_TYPE_MPCF 0x4643504D
-
-#include "disc_io.h"
-
-// export interface
-extern LPIO_INTERFACE MPCF_GetInterface(void) ;
-
-#endif	// define IO_MPCF_H
diff --git a/backends/platform/ds/arm9/source/fat/io_njsd.c b/backends/platform/ds/arm9/source/fat/io_njsd.c
deleted file mode 100644
index 12388da8e9..0000000000
--- a/backends/platform/ds/arm9/source/fat/io_njsd.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
-	io_njsd.c
-
-	Hardware Routines for reading an SD card using
-	a NinjaDS SD adapter.
-
-	Original code supplied by NinjaMod
-
- 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.
-
-	2006-08-05 - Chishm
-		* First release
-*/
-
-#include "io_njsd.h"
-
-#ifdef SUPPORT_NJSD
-#ifdef NDS
-
-#include <nds.h>
-#include <string.h>
-#include "io_sd_common.h"
-
-#define BYTES_PER_READ 512
-//#define _NJSD_SYNC
-// #define _NJSD_DEBUG
-
-//---------------------------------------------------------------
-// Card communication speeds
-#define SD_CLK_200KHz		00
-#define SD_CLK_5MHz		01
-#define SD_CLK_8MHz			02
-#define SD_CLK_12MHz		03
-
-//---------------------------------------------------------------
-// Response types
-#define SD_RSP_48		0
-#define SD_RSP_136		1
-#define SD_RSP_DATA		2
-#define SD_RSP_STREAM	3
-
-//---------------------------------------------------------------
-// Send / receive timeouts, to stop infinite wait loops
-#define IRQ_TIMEOUT 1000000
-#define RESET_TIMEOUT 1000
-#define COMMAND_TIMEOUT 10000
-#define MAX_STARTUP_TRIES 2000	// Arbitrary value, check if the card is ready 20 times before giving up
-#define WRITE_TIMEOUT	300	// Time to wait for the card to finish writing
-
-
-static const u8 _NJSD_read_cmd[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40};
-static const u8 _NJSD_read_end_cmd[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x41};
-
-static int _NJSD_speed = SD_CLK_8MHz;		// Default speed;
-
-static u32 _NJSD_cardFlags;
-
-static u32 _NJSD_relativeCardAddress = 0;
-
-#define _NJSD_irqFlag		(*(volatile unsigned long*)(0x027FFEB0))
-
-
-static inline bool _NJSD_waitIRQ(void) {
-/*#ifdef _NJSD_SYNC
-	int i = IRQ_TIMEOUT;
-	while (!(REG_IF & 0x100000) && --i);
-	REG_IF = 0x100000;
-	if (i <= 0) {
-		return false;
-	} else {
-		return true;
-	}
-#else*/
-	int i = IRQ_TIMEOUT;
-	//if (!(REG_IME & 1))
-	//{
-		// irq's disabled...
-		while (!(REG_IF & 0x100000) && (!(_NJSD_irqFlag)) && --i);
-		_NJSD_irqFlag = 0;
-		REG_IF = 0x100000;
-		if (i <= 0) {
-			return false;
-		} else {
-			return true;
-		}
-	//} else {
-		// irq's enabled
-	//	while (!(_NJSD_irqFlag) && --i);
-	//	_NJSD_irqFlag = 0;
-	//	REG_IF = 0x100000;
-	//	if (i <= 0) {
-	//		return false;
-	//	} else {
-	//		return true;
-	//	}
-	//}
-//#endif
-}
-
-static inline void _NJSD_writeCardCommand
-	(u8 cmd0, u8 cmd1, u8 cmd2, u8 cmd3, u8 cmd4, u8 cmd5, u8 cmd6, u8 cmd7)
-{
-	CARD_COMMAND[0] = cmd0;
-	CARD_COMMAND[1] = cmd1;
-	CARD_COMMAND[2] = cmd2;
-	CARD_COMMAND[3] = cmd3;
-	CARD_COMMAND[4] = cmd4;
-	CARD_COMMAND[5] = cmd5;
-	CARD_COMMAND[6] = cmd6;
-	CARD_COMMAND[7] = cmd7;
-}
-
-
-static bool _NJSD_reset (void) {
-	int i;
-	CARD_CR1H = CARD_CR1_ENABLE;
-	_NJSD_writeCardCommand (0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
-	CARD_CR2 = 0xA0406000;
-	i = RESET_TIMEOUT;
-	while ((CARD_CR2 & CARD_BUSY) && --i);
-	if (i <= 0) {
-		return false;
-	}
-
-	return true;
-}
-
-static void _NJSD_irqHandler (void) {
-	_NJSD_irqFlag = 1;
-}
-
-static bool _NJSD_init (u32 flags) {
-	_NJSD_cardFlags = flags;
-
-	REG_IF = 0x100000; // Clear cart IRQ.
-
-	_NJSD_irqFlag = 0;
-#ifdef _NJSD_SYNC
-    irqDisable (IRQ_CARD_LINE);
-#else
-    irqSet(IRQ_CARD_LINE, _NJSD_irqHandler);
-    irqEnable (IRQ_CARD_LINE);
-#endif
-
-	if (! _NJSD_reset() ) {
-		return false;
-	}
-	return true;
-}
-
-static bool _NJSD_sendCMDR (int speed, u8 *rsp_buf, int type, u8 cmd, u32 param) {
-	int i;
-	u32 data;
-
-#ifdef _NJSD_SYNC
-	u32 old_REG_IME;
-	old_REG_IME = REG_IME;
-	REG_IME = 0;
-#endif
-
-	REG_IE &= ~0x100000;
-	REG_IF =   0x100000;
-
-	CARD_CR1H = CARD_CR1_ENABLE;
-
-	if ((type & 3) < 2) {
-		CARD_COMMAND[0] = 0xF0 | (speed << 2) | 1 | (type << 1);
-	} else if ((type & 3) == 2) {
-		CARD_COMMAND[0] = 0xE0 | (speed << 2) | 0 | (1 << 1);
-	} else {
-		CARD_COMMAND[0] = 0xF0 | (speed << 2) | 0 | (1 << 1);
-	}
-
-	CARD_COMMAND[1] = (type & 0x40) | ((( type >> 2) & 7) << 3);
-	CARD_COMMAND[2] = 0x40 | cmd;
-	CARD_COMMAND[3] = (param>>24) & 0xFF;
-	CARD_COMMAND[4] = (param>>16) & 0xFF;
-	CARD_COMMAND[5] = (param>>8) & 0xFF;
-	CARD_COMMAND[6] = (param>>0) & 0xFF;
-	CARD_COMMAND[7] = 0; // offset = 0
-
-	if ((type & 3) < 2) {
-		CARD_CR2 = _NJSD_cardFlags | 0x01000000;
-
-		// wait for ninja DS to be done!
-		if (!_NJSD_waitIRQ ()) {
-#ifdef _NJSD_SYNC
-			REG_IME = old_REG_IME;
-#endif
-			return false;
-		}
-
-		i = 0;
-		do {
-			// Read data if available
-			if (CARD_CR2 & CARD_DATA_READY) {
-				data=CARD_DATA_RD;
-				if (rsp_buf != NULL) {
-					if (i == 4) {
-						rsp_buf[0] = (data>>0)&0xFF;
-						rsp_buf[1] = (data>>8)&0xFF;
-						rsp_buf[2] = (data>>16)&0xFF;
-						rsp_buf[3] = (data>>24)&0xFF;
-					} else if (i == 5) {
-						rsp_buf[4] = (data>>0)&0xFF;
-						rsp_buf[5] = (data>>8)&0xFF;
-					}
-				}
-				i++;
-			}
-		} while (CARD_CR2 & CARD_BUSY);
-
-#ifdef _NJSD_DEBUG
-		iprintf ("r: ");
-		for (i = 0; i < 6; i++)
-			iprintf ("%02X ", rsp_buf[i]);
-		iprintf ("\n");
-#endif
-	} else {
-		CARD_CR2 = _NJSD_cardFlags;
-		while (CARD_CR2 & CARD_BUSY);


Commit: ab577c793032ea4f8cd1d0a6dc64c68a6aa6e5e2
    https://github.com/scummvm/scummvm/commit/ab577c793032ea4f8cd1d0a6dc64c68a6aa6e5e2
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Bundle the engine data files in romfs

Changed paths:
    backends/platform/ds/ds.mk
    configure


diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk
index 16cffeabde..d9682f8dce 100644
--- a/backends/platform/ds/ds.mk
+++ b/backends/platform/ds/ds.mk
@@ -135,18 +135,37 @@ clean: dsclean
 
 dsclean:
 	$(RM) $(addprefix $(ndsdir)/, $(ARM7_MODULE_OBJS)) scummvm.nds scummvm.ds.gba
+	$(RM_REC) romfs
 
 .PHONY: dsclean
 
 # TODO: Add a 'dsdist' target ?
 
-%.nds: %.elf $(ndsdir)/arm7/arm7.elf
-	ndstool -c $@ -9 $< -7 $(ndsdir)/arm7/arm7.elf -b $(srcdir)/$(ndsdir)/logo.bmp "$(@F);ScummVM $(VERSION);DS Port"
+%.nds: %.elf $(ndsdir)/arm7/arm7.elf romfs
+	ndstool -c $@ -9 $< -7 $(ndsdir)/arm7/arm7.elf -b $(srcdir)/$(ndsdir)/logo.bmp "$(@F);ScummVM $(VERSION);DS Port" -d romfs
 
 %.ds.gba: %.nds
 	dsbuild $< -o $@ -l $(srcdir)/$(ndsdir)/arm9/ndsloader.bin
 	padbin 16 $@
 
+romfs: $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(PLUGINS)
+	@rm -rf romfs
+	@mkdir -p romfs
+	@cp $(DIST_FILES_THEMES) romfs/
+ifdef DIST_FILES_ENGINEDATA
+	@cp $(DIST_FILES_ENGINEDATA) romfs/
+endif
+ifdef DIST_FILES_NETWORKING
+	@cp $(DIST_FILES_NETWORKING) romfs/
+endif
+ifdef DIST_FILES_VKEYBD
+	@cp $(DIST_FILES_VKEYBD) romfs/
+endif
+ifeq ($(DYNAMIC_MODULES),1)
+	@mkdir -p romfs/plugins
+	@for i in $(PLUGINS); do $(STRIP) --strip-debug $$i -o romfs/plugins/`basename $$i`; done
+endif
+
 #############################################################################
 #############################################################################
 #############################################################################
diff --git a/configure b/configure
index d7d31aa009..d6ba618cbd 100755
--- a/configure
+++ b/configure
@@ -1724,6 +1724,12 @@ ds)
 	_host_os=ds
 	_host_cpu=arm
 	_host_alias=arm-none-eabi
+
+	test "x$prefix" = xNONE && prefix=nitro:
+
+	datarootdir='${prefix}'
+	datadir='${datarootdir}'
+	docdir='${prefix}/doc'
 	;;
 gamecube)
 	_host_os=gamecube
@@ -5881,7 +5887,7 @@ case $_host_os in
 esac
 
 case $_backend in
-	3ds)
+	3ds | ds)
 		append_var DEFINES "-DPLUGIN_DIRECTORY=\\\"$datadir/plugins\\\""
 		;;
 	openpandora)


Commit: 8c9eb8edc807cc6edfe22477d411c118195192cb
    https://github.com/scummvm/scummvm/commit/8c9eb8edc807cc6edfe22477d411c118195192cb
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: List all available devices in the file browser

Changed paths:
  A backends/fs/devoptab/devoptab-fs-factory.cpp
  A backends/fs/devoptab/devoptab-fs-factory.h
    backends/fs/posix-drives/posix-drives-fs-factory.cpp
    backends/fs/posix-drives/posix-drives-fs.cpp
    backends/module.mk
    backends/platform/ds/arm9/source/osystem_ds.cpp


diff --git a/backends/fs/devoptab/devoptab-fs-factory.cpp b/backends/fs/devoptab/devoptab-fs-factory.cpp
new file mode 100644
index 0000000000..13e36655ae
--- /dev/null
+++ b/backends/fs/devoptab/devoptab-fs-factory.cpp
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(__DS__)
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/fs/devoptab/devoptab-fs-factory.h"
+
+#include <sys/iosupport.h>
+
+DevoptabFilesystemFactory::DevoptabFilesystemFactory() {
+	// skip in, out and err
+	for (uint8 i = 3; i < STD_MAX; ++i) {
+		const devoptab_t *dt = devoptab_list[i];
+
+		if (!dt || !dt->name || !dt->open_r || !dt->diropen_r)
+			continue;
+
+		addDrive(Common::String(dt->name) + ":/");
+	}
+
+}
+
+#endif
diff --git a/backends/fs/devoptab/devoptab-fs-factory.h b/backends/fs/devoptab/devoptab-fs-factory.h
new file mode 100644
index 0000000000..d65801bd9a
--- /dev/null
+++ b/backends/fs/devoptab/devoptab-fs-factory.h
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DEVOPTAB_FILESYSTEM_FACTORY_H
+#define DEVOPTAB_FILESYSTEM_FACTORY_H
+
+#include "backends/fs/posix-drives/posix-drives-fs-factory.h"
+
+/**
+ * A FilesystemFactory implementation for filesystems with a special
+ * top-level directory listing all registered devoptab devices but
+ * that otherwise implement the POSIX APIs.
+ */
+class DevoptabFilesystemFactory : public DrivesPOSIXFilesystemFactory {
+public:
+	DevoptabFilesystemFactory();
+};
+
+#endif
diff --git a/backends/fs/posix-drives/posix-drives-fs-factory.cpp b/backends/fs/posix-drives/posix-drives-fs-factory.cpp
index 371d3b87e3..7d8692266a 100644
--- a/backends/fs/posix-drives/posix-drives-fs-factory.cpp
+++ b/backends/fs/posix-drives/posix-drives-fs-factory.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#if defined(POSIX) || defined(PSP2)
+#if defined(POSIX) || defined(PSP2) || defined(__DS__)
 
 #define FORBIDDEN_SYMBOL_ALLOW_ALL
 
diff --git a/backends/fs/posix-drives/posix-drives-fs.cpp b/backends/fs/posix-drives/posix-drives-fs.cpp
index 4ad5a3bbf6..63776a2fd8 100644
--- a/backends/fs/posix-drives/posix-drives-fs.cpp
+++ b/backends/fs/posix-drives/posix-drives-fs.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#if defined(POSIX) || defined(PSP2)
+#if defined(POSIX) || defined(PSP2) || defined(__DS__)
 
 #define FORBIDDEN_SYMBOL_ALLOW_ALL
 
diff --git a/backends/module.mk b/backends/module.mk
index dbd4d524fa..2476ff3b98 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -287,6 +287,9 @@ MODULE_OBJS += \
 	fs/posix/posix-fs.o \
 	fs/posix/posix-fs-factory.o \
 	fs/posix/posix-iostream.o \
+	fs/posix-drives/posix-drives-fs.o \
+	fs/posix-drives/posix-drives-fs-factory.o \
+	fs/devoptab/devoptab-fs-factory.o \
 	plugins/ds/ds-provider.o
 endif
 
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 130feee0e7..69d3c932f9 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -42,7 +42,7 @@
 #include "common/str.h"
 #include "graphics/surface.h"
 #include "touchkeyboard.h"
-#include "backends/fs/posix/posix-fs-factory.h"
+#include "backends/fs/devoptab/devoptab-fs-factory.h"
 
 #include "backends/audiocd/default/default-audiocd.h"
 #include "backends/saves/default/default-saves.h"
@@ -95,7 +95,7 @@ OSystem_DS::OSystem_DS()
 	_instance = this;
 //	_mixer = NULL;
 	//_frameBufferExists = false;
-	_fsFactory = new POSIXFilesystemFactory();
+	_fsFactory = new DevoptabFilesystemFactory();
 }
 
 OSystem_DS::~OSystem_DS() {


Commit: e23e809086eecda63e25302cffc114ee1f8d5c8c
    https://github.com/scummvm/scummvm/commit/e23e809086eecda63e25302cffc114ee1f8d5c8c
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Update compile flags

Changed paths:
    configure


diff --git a/configure b/configure
index d6ba618cbd..52c09f0ac5 100755
--- a/configure
+++ b/configure
@@ -2999,8 +2999,8 @@ EOF
 		append_var CXXFLAGS "-isystem $DEVKITPRO/libnds/include"
 		append_var CXXFLAGS "-isystem $DEVKITPRO/portlibs/nds/include"
 		append_var CXXFLAGS "-isystem $DEVKITPRO/portlibs/armv5te/include"
-		append_var CXXFLAGS "-mcpu=arm9tdmi"
-		append_var CXXFLAGS "-mtune=arm9tdmi"
+		append_var CXXFLAGS "-march=armv5te"
+		append_var CXXFLAGS "-mtune=arm946e-s"
 		append_var CXXFLAGS "-fomit-frame-pointer"
 		append_var CXXFLAGS "-mthumb-interwork"
 		append_var CXXFLAGS "-ffunction-sections"
@@ -3010,13 +3010,6 @@ EOF
 		append_var LDFLAGS "-mthumb-interwork"
 		append_var LDFLAGS "-mfloat-abi=soft"
 		append_var LDFLAGS "-Wl,-Map,map.txt"
-		if test "$_dynamic_modules" = no ; then
-			append_var LDFLAGS "-Wl,--gc-sections"
-		else
-			append_var LDFLAGS "-Wl,--no-gc-sections"
-			# TODO automate this required 2 step linking phase
-			# append_var LDFLAGS "-Wl,--retain-symbols-file,ds.syms"
-		fi
 		append_var LDFLAGS "-L$DEVKITPRO/libnds/lib"
 		append_var LDFLAGS "-L$DEVKITPRO/portlibs/nds/lib"
 		append_var LDFLAGS "-L$DEVKITPRO/portlibs/armv5te/lib"
@@ -6051,6 +6044,16 @@ case $_host_os in
 		# than pick up anything unhygenic from the Android libs.
 		LIBS="-Wl,-Bstatic $static_libs -Wl,-Bdynamic -lgcc $system_libs -llog -landroid -lGLESv1_CM"
 		;;
+	ds)
+		# Moved -Wl,--gc-sections here to avoid it interfering with the library checks
+		if test "$_dynamic_modules" = no ; then
+			append_var LDFLAGS "-Wl,--gc-sections"
+		else
+			append_var LDFLAGS "-Wl,--no-gc-sections"
+			# TODO automate this required 2 step linking phase
+			# append_var LDFLAGS "-Wl,--retain-symbols-file,ds.syms"
+		fi
+		;;
 	riscos)
 		append_var CXXFLAGS "-mno-poke-function-name"
 		append_var CXXFLAGS "-ffunction-sections"


Commit: bfba7f3e415cdc6d55b7f3021d0e7d0f89108d4c
    https://github.com/scummvm/scummvm/commit/bfba7f3e415cdc6d55b7f3021d0e7d0f89108d4c
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Use libnds functionality for reading the touchscreen and buttons

Changed paths:
  R backends/platform/ds/arm9/source/interrupt.s
  R backends/platform/ds/arm9/source/keys.cpp
  R backends/platform/ds/arm9/source/keys.h
    backends/platform/ds/arm7/source/main.cpp
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsmain.h
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/touchkeyboard.cpp
    backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
    backends/platform/ds/module.mk


diff --git a/backends/platform/ds/arm7/source/main.cpp b/backends/platform/ds/arm7/source/main.cpp
index 617a1edc87..95ae813ee0 100644
--- a/backends/platform/ds/arm7/source/main.cpp
+++ b/backends/platform/ds/arm7/source/main.cpp
@@ -46,17 +46,6 @@
 
 #include "cartreset_nolibfat.h"
 
-#define TOUCH_CAL_X1 (*(vs16 *)0x027FFCD8)
-#define TOUCH_CAL_Y1 (*(vs16 *)0x027FFCDA)
-#define TOUCH_CAL_X2 (*(vs16 *)0x027FFCDE)
-#define TOUCH_CAL_Y2 (*(vs16 *)0x027FFCE0)
-#define SCREEN_WIDTH    256
-#define SCREEN_HEIGHT   192
-s32 TOUCH_WIDTH  = TOUCH_CAL_X2 - TOUCH_CAL_X1;
-s32 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
-s32 TOUCH_OFFSET_X = ( ((SCREEN_WIDTH  - 60) * TOUCH_CAL_X1) / TOUCH_WIDTH  ) - 28;
-s32 TOUCH_OFFSET_Y = ( ((SCREEN_HEIGHT - 60) * TOUCH_CAL_Y1) / TOUCH_HEIGHT ) - 28;
-
 vu8 *soundData;
 
 vu8 *soundBuffer;
@@ -65,17 +54,10 @@ bool soundFilled[4];
 
 int playingSection;
 
-bool needSleep = false;
 int temp;
 
 int adpcmBufferNum = 0;
 
-// those are pixel positions of the two points you click when calibrating
-#define TOUCH_CNTRL_X1 (*(vu8 *)0x027FFCDC)
-#define TOUCH_CNTRL_Y1 (*(vu8 *)0x027FFCDD)
-#define TOUCH_CNTRL_X2 (*(vu8 *)0x027FFCE2)
-#define TOUCH_CNTRL_Y2 (*(vu8 *)0x027FFCE3)
-
 /*
 void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0, u8 vol = 0x7F, u8 pan = 63, u8 format = 0) {
 	SCHANNEL_TIMER(channel)  = SOUND_FREQ(sampleRate);
@@ -224,119 +206,6 @@ void stopSound(int chan) {
 	SCHANNEL_CR(chan) = 0;
 }
 
-void DummyHandler() {
-	REG_IF = REG_IF;
-}
-
-void powerManagerWrite(uint32 command, u32 data, bool enable) {
-	uint16 result;
-	SerialWaitBusy();
-
-	// Write the command and wait for it to complete
-	REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
-	REG_SPIDATA = command | 0x80;
-	SerialWaitBusy();
-
-	// Write the second command and clock in the data
-	REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
-	REG_SPIDATA = 0;
-	SerialWaitBusy();
-
-	result = REG_SPIDATA & 0xFF;
-
-	// Write the command and wait for it to complete
-	REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
-	REG_SPIDATA = command;
-	SerialWaitBusy();
-
-	// Write the second command and clock in the data
-	REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
-	REG_SPIDATA = enable ? (result | data) : (result & ~data);
-	SerialWaitBusy();
-}
-
-/*
-void performSleep() {
-	powerManagerWrite(0, 0x30, true);
-
-	// Here, I set up a dummy interrupt handler, then trigger all interrupts.
-	// These are just aknowledged by the handler without doing anything else.
-	// Why?  Because without it the sleep mode will only happen once, and then
-	// never again.  I got the idea from reading the MoonShell source.
-	IME = 0;
-	u32 irq = (u32)IRQ_HANDLER;
-	IRQ_HANDLER = DummyHandler;
-	IF = ~0;
-	IME = 1;
-
-	// Now save which interrupts are enabled, then set only the screens unfolding
-	// interrupt to be enabled, so that the first interrupt that happens is the
-	// one I want.
-	int saveInts = IE;
-
-	IE = IRQ_TIMER0; // Screens unfolding interrupt
-
-	// Now call the sleep function in the bios
-	bool b;
-	do {
-		TIMER0_CR = 0;
-		TIMER0_DATA = TIMER_FREQ(20);
-		TIMER0_CR = TIMER_ENABLE | TIMER_DIV_64;
-
-		swiDelay(100);
-
-		swiSleep();
-
-		swiDelay(100);
-
-		powerManagerWrite(0, 0x30, b = !b);
-	} while (!(TIMER0_CR & TIMER_ENABLE));
-
-	TIMER0_CR = 0;
-
-	// We're back from sleep, now restore the interrupt state and IRQ handler
-	IRQ_HANDLER = (void (*)())irq;
-	IE = saveInts;
-	IF = ~0;
-	IME = 1;
-
-	powerManagerWrite(0, 0x30, false);
-}
-*/
-
-void performSleep() {
-	powerManagerWrite(0, 0x30, true);
-
-	IPC->performArm9SleepMode = true; // Tell ARM9 to sleep
-
-	// u32 irq = (u32)IRQ_HANDLER;
-	// IRQ_HANDLER = DummyHandler;
-	// POWER_CR &= ~POWER_SOUND;
-
-	// int saveInts = REG_IE;
-	// REG_IE = (1 << 22) | IRQ_VBLANK; // Lid open
-	// *((u32 *)(0x0380FFF8)) = *((u32 *)(0x0380FFF8)) | (REG_IE & REG_IF);
-	// VBLANK_INTR_WAIT_FLAGS = IRQ_VBLANK;
-
-	int r = 0;
-	while ((REG_KEYXY & (1 << 7))) { // Wait for lid to open
-		swiDelay(1000000);
-		r++;
-	}
-
-	// IRQ_HANDLER = (void (*)())irq;
-	IPC->performArm9SleepMode = false; // Tell ARM9 to wake up
-	// REG_IE = saveInts;
-
-	// POWER_CR |= POWER_SOUND;
-
-	powerManagerWrite(0, 0x30, false);
-}
-
-void powerOff() {
-	powerManagerWrite(0, 0x40, true);
-}
-
 void InterruptTimer1() {
 	IPC->fillNeeded[playingSection] = true;
 	soundFilled[playingSection] = false;
@@ -389,84 +258,7 @@ void InterruptTimer3() {
 	IPC->adpcm.semaphore = false;
 }
 
-// IPC->performArm9SleepMode = false;
-
-// precalculate some values
-// static int16 TOUCH_WIDTH  = TOUCH_CAL_X2 - TOUCH_CAL_X1;
-// static int16 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
-// static int16 CNTRL_WIDTH  = TOUCH_CNTRL_X2 - (TOUCH_CNTRL_X1 - 8);
-// static int16 CNTRL_HEIGHT = TOUCH_CNTRL_Y2 - (TOUCH_CNTRL_Y1 - 8);
-
- void InterruptVBlank() {
-	uint16 but = 0, x = 0, y = 0, xpx = 0, ypx = 0, z1 = 0, z2 = 0, batt = 0, aux = 0;
-	int t1 = 0, t2 = 0;
-	uint32 temp = 0;
-	uint8 ct[sizeof(IPC->curtime)];
-	static int heartbeat = 0;
-	// Update the heartbeat
-	heartbeat++;
-
-	// Read the X/Y buttons and the /PENIRQ line
-	but = REG_KEYXY;
-	if (!(but & 0x40)) {
-		// Read the touch screen
-		touchPosition p;
-		touchReadXY(&p);
-
-		// x = touchRead(TSC_MEASURE_X);
-		// y = touchRead(TSC_MEASURE_Y);
-
-		x = p.rawx;
-		y = p.rawy;
-
-		// xpx = p.px;
-		// ypx = p.py;
-
-		xpx = ( ((SCREEN_WIDTH  - 60) * x) / TOUCH_WIDTH  ) - TOUCH_OFFSET_X;
-		ypx = ( ((SCREEN_HEIGHT - 60) * y) / TOUCH_HEIGHT ) - TOUCH_OFFSET_Y;
-
-		// xpx = (IPC->touchX - (int16) TOUCH_CAL_X1) * CNTRL_WIDTH  / TOUCH_WIDTH  + (int16) (TOUCH_CNTRL_X1 - 8);
-		// ypx = (IPC->touchY - (int16) TOUCH_CAL_Y1) * CNTRL_HEIGHT / TOUCH_HEIGHT + (int16) (TOUCH_CNTRL_Y1 - 8);
-
-		z1 = touchRead(TSC_MEASURE_Z1);
-		z2 = touchRead(TSC_MEASURE_Z2);
-	}
-
-	// Check if screen is folded
-	if (but & (1 << 7)) {
-		needSleep = true;
-	}
-
-	batt = touchRead(TSC_MEASURE_BATTERY);
-	aux  = touchRead(TSC_MEASURE_AUX);
-
-	// Read the time
-	rtcGetTime((uint8 *)ct);
-	BCDToInteger((uint8 *)&(ct[1]), 7);
-
-	// Read the temperature
-	temp = touchReadTemperature(&t1, &t2);
-
-	// Update the IPC struct
-	IPC->heartbeat = heartbeat;
-	IPC->buttons   = but;
-	IPC->touchX    = x;
-	IPC->touchY    = y;
-	IPC->touchXpx  = xpx;
-	IPC->touchYpx  = ypx;
-	IPC->touchZ1   = z1;
-	IPC->touchZ2   = z2;
-	IPC->battery   = batt;
-	IPC->aux       = aux;
-
-	for (u32 i = 0; i < sizeof(ct); i++) {
-		IPC->curtime[i] = ct[i];
-	}
-
-	IPC->temperature = temp;
-	IPC->tdiode1 = t1;
-	IPC->tdiode2 = t2;
-
+void VblankHandler() {
 	// sound code  :)
 	TransferSound *snd = IPC->soundData;
 	IPC->soundData = 0;
@@ -488,6 +280,20 @@ void InterruptTimer3() {
 #endif
 }
 
+//---------------------------------------------------------------------------------
+void VcountHandler() {
+//---------------------------------------------------------------------------------
+	inputGetAndSend();
+}
+
+volatile bool exitflag = false;
+
+//---------------------------------------------------------------------------------
+void powerButtonCB() {
+//---------------------------------------------------------------------------------
+	exitflag = true;
+}
+
 #ifdef USE_DEBUGGER
 // callback to allow wifi library to notify arm9
 void arm7_synctoarm9() { // send fifo message
@@ -547,16 +353,10 @@ int main(int argc, char ** argv) {
 	REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR;
 #endif
 
-	// Reset the clock if needed
-	rtcReset();
-
 	// enable sound
 	// powerOn(POWER_SOUND);
 	SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
 	IPC->soundData = 0;
-	IPC->reset = false;
-
-	// fifoInit();
 
 	for (int r = 0; r < 8; r++) {
 		IPC->adpcm.arm7Buffer[r] = (u8 *)malloc(512);
@@ -566,12 +366,28 @@ int main(int argc, char ** argv) {
 		soundFilled[r] = false;
 	}
 
-	// Set up the interrupt handler
+	readUserSettings();
+	ledBlink(0);
 
 	irqInit();
+	// Start the RTC tracking IRQ
+	initClockIRQ();
+	fifoInit();
+	touchInit();
+
+//	mmInstall(FIFO_MAXMOD);
 
-	irqSet(IRQ_VBLANK, InterruptVBlank);
-	irqEnable(IRQ_VBLANK);
+	SetYtrigger(80);
+
+//	installWifiFIFO();
+//	installSoundFIFO();
+
+	installSystemFIFO();
+
+	irqSet(IRQ_VCOUNT, VcountHandler);
+	irqSet(IRQ_VBLANK, VblankHandler);
+
+	irqEnable(IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK);
 
 	irqSet(IRQ_TIMER1, InterruptTimer1);
 	irqEnable(IRQ_TIMER1);
@@ -592,23 +408,19 @@ int main(int argc, char ** argv) {
 	initDebugger();
 #endif
 
-	// Keep the ARM7 out of main RAM
-	while ((1)) {
-		if (needSleep) {
-			performSleep();
-			needSleep = false;
-		}
+	setPowerButtonCB(powerButtonCB);
 
+	// Keep the ARM7 mostly idle
+	while (!exitflag) {
+		if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) {
+			exitflag = true;
+		}
 #ifdef USE_LIBCARTRESET
 		if (passmeloopQuery()) {
 			reboot();
 		}
 #endif
 
-		if (IPC->reset) {
-			powerOff();
-		}
-
 		swiWaitForVBlank();
 	}
 
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 45323467d1..7abfe30b41 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -96,7 +96,6 @@
 #include "user_debugger.h"
 #endif
 #include "blitters.h"
-#include "keys.h"
 #ifdef USE_PROFILER
 #include "profiler/cyg-profile.h"
 #endif
@@ -736,37 +735,6 @@ void setGameID(int id) {
 	gameID = id;
 }
 
-void dummyHandler() {
-	REG_IF = IRQ_VBLANK;
-}
-
-void checkSleepMode() {
-	if (IPC->performArm9SleepMode) {
-
-		consolePrintf("ARM9 Entering sleep mode\n");
-
-		int intSave = REG_IE;
-		irqSet(IRQ_VBLANK, dummyHandler);
-//		int irqHandlerSave = (int) IRQ_HANDLER;
-		REG_IE = IRQ_VBLANK;
-		//IRQ_HANDLER = dummyHandler;
-
-		int powerSave = POWER_CR;
-		POWER_CR &= ~POWER_ALL;
-
-		while (IPC->performArm9SleepMode) {
-			swiWaitForVBlank();
-		}
-
-		POWER_CR = powerSave;
-//		IRQ_HANDLER = (void (*)()) irqHandlerSave;
-		irqSet(IRQ_VBLANK, VBlankHandler);
-		REG_IE = intSave;
-
-		consolePrintf("ARM9 Waking from sleep mode\n");
-	}
-}
-
 void setShowCursor(bool enable) {
 	if ((s_currentGame) && (s_currentGame->control == CONT_SCUMM_SAMNMAX)) {
 		if (cursorEnable) {
@@ -1091,7 +1059,6 @@ void soundUpdate() {
 	if ((bufferFrame == 0)) {
 //		playSound(soundBuffer, (bufferSamples * 2), true);
 	}
-//	consolePrintf("%x\n", IPC->test);
 
 
 	if (bufferFrame == 0) {
@@ -1513,20 +1480,6 @@ void addEventsToQueue() {
 
 	if (system->isEventQueueEmpty()) {
 
-/*
-		if (getKeysDown() & KEY_L) {
-			tweak--;
-			consolePrintf("Tweak: %d\n", tweak);
-			IPC->tweakChanged = true;
-		}
-
-
-		if (getKeysDown() & KEY_R) {
-			tweak++;
-			consolePrintf("Tweak: %d\n", tweak);
-			IPC->tweakChanged = true;
-		}
-	*/
 		if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
 			memoryReport();
 		}
@@ -2005,7 +1958,6 @@ void VBlankHandler(void) {
 	}
 */
 
-	IPC->tweak = tweak;
 	soundUpdate();
 
 
@@ -2410,8 +2362,6 @@ void initHardware() {
 	//consolePrintSet(0, 6);
 
 	//irqs are nice
-	irqInit();
-	irqInitHandler(OurIntrMain);
 	irqSet(IRQ_VBLANK, VBlankHandler);
 	irqSet(IRQ_TIMER0, timerTickHandler);
 	irqSet(IRQ_TIMER2, soundBufferEmptyHandler);
@@ -2489,9 +2439,10 @@ void penInit() {
 
 void penUpdate() {
 
-//	if (getKeysHeld() & KEY_L) consolePrintf("%d, %d   penX=%d, penY=%d tz=%d\n", IPC->touchXpx, IPC->touchYpx, penX, penY, IPC->touchZ1);
+	touchPosition touchPos;
+	touchRead(&touchPos);
 
-	bool penDownThisFrame = (!(IPC->buttons & 0x40)) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0);
+	bool penDownThisFrame = (keysCurrent() & KEY_TOUCH) && (touchPos.px > 0) && (touchPos.py > 0);
 	static bool moved = false;
 
 	if (( (tapScreenClicks) || getKeyboardEnable() ) && (getIsDisplayMode8Bit())) {
@@ -2533,9 +2484,10 @@ void penUpdate() {
 				if (penDownThisFrame) {
 					if (penDownFrames >= 2) {
 
-						if ((!keyboardEnable) || (!isInsideKeyboard(IPC->touchXpx, IPC->touchYpx))) {
-							int diffX = IPC->touchXpx - penDownX;
-							int diffY = IPC->touchYpx - penDownY;
+						touchRead(&touchPos);
+						if ((!keyboardEnable) || (!isInsideKeyboard(touchPos.px, touchPos.py))) {
+							int diffX = touchPos.px - penDownX;
+							int diffY = touchPos.py - penDownY;
 
 							int speed = ABS(diffX) + ABS(diffY);
 
@@ -2569,11 +2521,9 @@ void penUpdate() {
 									penY = 0;
 								}
 							}
-
-	//						consolePrintf("x: %d y: %d\n", IPC->touchYpx - penDownY, IPC->touchYpx - penDownY);
 						}
-						penDownX = IPC->touchXpx;
-						penDownY = IPC->touchYpx;
+						penDownX = touchPos.px;
+						penDownY = touchPos.py;
 
 					}
 				}
@@ -2585,8 +2535,9 @@ void penUpdate() {
 
 				// First frame, so save pen positions
 				if (penDownThisFrame) {
-					penDownX = IPC->touchXpx;
-					penDownY = IPC->touchYpx;
+					touchRead(&touchPos);
+					penDownX = touchPos.px;
+					penDownY = touchPos.py;
 				}
 			}
 		} else {
@@ -2610,17 +2561,19 @@ void penUpdate() {
 				penDown = false;
 			} else {
 				if (penDownFrames == 2) {
-					penDownX = IPC->touchXpx;
-					penDownY = IPC->touchYpx;
+					touchRead(&touchPos);
+					penDownX = touchPos.px;
+					penDownY = touchPos.py;
 				}
 				penDown = true;
 				penHeld = true;
 				penDownSaved = true;
 			}
 
-			if ((!(IPC->buttons & 0x40)) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
-				penX = IPC->touchXpx + touchXOffset;
-				penY = IPC->touchYpx + touchYOffset;
+			touchRead(&touchPos);
+			if ((keysCurrent() & KEY_TOUCH) && (touchPos.px > 0) && (touchPos.py > 0)) {
+				penX = touchPos.px + touchXOffset;
+				penY = touchPos.py + touchYOffset;
 				moved = true;
 			}
 
@@ -2640,7 +2593,7 @@ void penUpdate() {
 
 
 
-	if ((!(IPC->buttons & 0x40)) || ((penDownFrames == 2)) ) {
+	if ((keysCurrent() & KEY_TOUCH) || ((penDownFrames == 2)) ) {
 		penDownLastFrame = true;
 		penDownFrames++;
 	} else {
@@ -2822,26 +2775,6 @@ void debug_print_stub(char *string) {
 #endif
 
 
-void powerOff() {
-	while (keysHeld() != 0) {		// Wait for all keys to be released.
-		swiWaitForVBlank();			// Allow you to read error before the power
-	}								// is turned off.
-
-	for (int r = 0; r < 60; r++) {
-		swiWaitForVBlank();
-	}
-
-	if (ConfMan.hasKey("disablepoweroff", "ds") && ConfMan.getBool("disablepoweroff", "ds")) {
-		while (true);
-	} else {
-
-		IPC->reset = true;				// Send message to ARM7 to turn power off
-		while (true) {
-			// Stop the program from continuing beyond this point
-		}
-	}
-}
-
 /////////////////
 // Main
 /////////////////
@@ -3103,11 +3036,7 @@ int main(void) {
 	PluginManager::instance().addPluginProvider(new DSPluginProvider());
 #endif
 
-	while (1) {
-		scummvm_main(ARRAYSIZE(argv), (char **) &argv);
-		powerOff();
-	}
-
+	scummvm_main(ARRAYSIZE(argv), (char **) &argv);
 
 	return 0;
 }
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index 151b88d671..f562e42280 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -117,9 +117,6 @@ void 	setShakePos(int shakeXOffset, int shakeYOffset);
 // Reports
 void 	memoryReport();
 
-// Sleep (I'd like some of that right now)
-void 	checkSleepMode();
-
 // Virtual keyboard
 void 	setKeyboardIcon(bool enable);
 bool 	getKeyboardIcon();
diff --git a/backends/platform/ds/arm9/source/interrupt.s b/backends/platform/ds/arm9/source/interrupt.s
deleted file mode 100644
index a45675d3df..0000000000
--- a/backends/platform/ds/arm9/source/interrupt.s
+++ /dev/null
@@ -1,154 +0,0 @@
-/*---------------------------------------------------------------------------------
-	$Id$
-
-	Copyright (C) 2005
-		Dave Murphy (WinterMute)
-
-	This software is provided 'as-is', without any express or implied
-	warranty.  In no event will the authors be held liable for any
-	damages arising from the use of this software.
-
-	Permission is granted to anyone to use this software for any
-	purpose, including commercial applications, and to alter it and
-	redistribute it freely, subject to the following restrictions:
-
-	1.	The origin of this software must not be misrepresented; you
-		must not claim that you wrote the original software. If you use
-		this software in a product, an acknowledgment in the product
-		documentation would be appreciated but is not required.
-	2.	Altered source versions must be plainly marked as such, and
-		must not be misrepresented as being the original software.
-	3.	This notice may not be removed or altered from any source
-		distribution.
-
-	$Log: interruptDispatcher.s,v $
-	Revision 1.10  2007/08/11 06:00:23  wntrmute
-	make nesting really work
-
-	Revision 1.9  2007/01/10 15:48:27  wntrmute
-	remove unused code
-
-	Revision 1.8  2006/12/16 09:10:02  wntrmute
-	acknowledge interrupt before calling handler
-
-	Revision 1.7  2006/04/26 05:11:31  wntrmute
-	rebase dtcm, take __irq_flags and __irq_vector from linker script
-	move arm7 irq vector & irq flags to actual locations
-
-	Revision 1.6  2006/04/23 18:19:15  wntrmute
-	reworked interrupt code to allow dtcm moving
-
-	Revision 1.5  2005/12/12 13:01:55  wntrmute
-	disable interrupts on return from user handler
-
-	Revision 1.4  2005/10/21 22:43:42  wntrmute
-	restore REG_IME on exit from null handler
-
-	Revision 1.3  2005/09/27 18:21:53  wntrmute
-	safer nested interrupt support
-
-	Revision 1.2  2005/09/04 16:37:01  wntrmute
-	check for NULL handler
-
-	Revision 1.1  2005/09/03 17:09:35  wntrmute
-	added interworking aware interrupt dispatcher
-
-
----------------------------------------------------------------------------------*/
-
-#ifdef ARM7
-	.text
-#endif
-
-#ifdef ARM9
-	.section	.itcm,"ax",%progbits
-#endif
-
-	.extern	irqTable
-	.code 32
-
-	.global	OurIntrMain
- at ---------------------------------------------------------------------------------
-OurIntrMain:
- at ---------------------------------------------------------------------------------
-	mov	r3, #0x4000000		@ REG_BASE
-
-	ldr	r1, [r3, #0x208]	@ r1 = IME
-	str	r3, [r3, #0x208]	@ disable IME
-	mrs	r0, spsr
-	stmfd	sp!, {r0-r1,r3,lr}	@ {spsr, IME, REG_BASE, lr_irq}
-
-	ldr	r1, [r3,#0x210]		@ REG_IE
-	ldr	r2, [r3,#0x214]		@ REG_IF
-	and	r1,r1,r2
-
-	ldr	r0,=__irq_flags		@ defined by linker script
-
-	ldr	r2,[r0]
-	orr	r2,r2,r1
-	str	r2,[r0]
-
-	ldr	r2,=irqTable
- at ---------------------------------------------------------------------------------
-findIRQ:
- at ---------------------------------------------------------------------------------
-	ldr r0, [r2, #4]
-	cmp	r0,#0
-	beq	no_handler
-	ands	r0, r0, r1
-	bne	jump_intr
-	add	r2, r2, #8
-	b	findIRQ
-
- at ---------------------------------------------------------------------------------
-no_handler:
- at ---------------------------------------------------------------------------------
-	str	r1, [r3, #0x0214]	@ IF Clear
-	ldmfd   sp!, {r0-r1,r3,lr}	@ {spsr, IME, REG_BASE, lr_irq}
-	str	r1, [r3, #0x208]	@ restore REG_IME
-	mov	pc,lr
-
- at ---------------------------------------------------------------------------------
-jump_intr:
- at ---------------------------------------------------------------------------------
-	ldr	r1, [r2]		@ user IRQ handler address
-	cmp	r1, #0
-	bne	got_handler
-	mov	r1, r0
-	b	no_handler
- at ---------------------------------------------------------------------------------
-got_handler:
- at ---------------------------------------------------------------------------------
-
-	mrs	r2, cpsr
-	bic	r2, r2, #0xdf		@ \__
-	orr	r2, r2, #0x1f		@ /  --> Enable IRQ & FIQ. Set CPU mode to System.
-	msr	cpsr,r2
-
-	str	r0, [r3, #0x0214]	@ IF Clear
-
-	sub	r13,r13,#256
-	push	{lr}
-	adr	lr, IntrRet
-	bx	r1
-
- at ---------------------------------------------------------------------------------
-IntrRet:
- at ---------------------------------------------------------------------------------
-	mov	r3, #0x4000000		@ REG_BASE
-	str	r3, [r3, #0x208]	@ disable IME
-	pop	{lr}
-	add	r13,r13,#256
-
-	mrs	r3, cpsr
-	bic	r3, r3, #0xdf		@ \__
-	orr	r3, r3, #0x92		@ /  --> Disable IRQ. Enable FIQ. Set CPU mode to IRQ.
-	msr	cpsr, r3
-
-	ldmfd   sp!, {r0-r1,r3,lr}	@ {spsr, IME, REG_BASE, lr_irq}
-	msr	spsr, r0		@ restore spsr
-	str	r1, [r3, #0x208]	@ restore REG_IME
-	mov	pc,lr
-
-	.pool
-	.end
diff --git a/backends/platform/ds/arm9/source/keys.cpp b/backends/platform/ds/arm9/source/keys.cpp
deleted file mode 100644
index fdb981dfe5..0000000000
--- a/backends/platform/ds/arm9/source/keys.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*------------------------------------------------------------------------------
-	$Id$
-
-	key input code -- provides slightly higher level input forming
-
-	Copyright (C) 2005
-			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.
-
-	$Log: keys.c,v $
-	Revision 1.13  2006/01/12 09:10:47  wntrmute
-	Added key repeat as suggested by pepsiman
-
-	Revision 1.12  2005/11/27 12:30:25  wntrmute
-	reverted to correct hardware REGisters
-
-	Revision 1.11  2005/11/27 07:48:45  joatski
-	Renamed REG_KEYINPUT and REG_KEYCNT back to KEYS and KEYS_CR, as the alternatives are defined in registers_alt.h.
-	Changed function returns to uint32
-
-	Revision 1.10  2005/11/03 23:38:49  wntrmute
-	don't use enum for key function returns
-
-	Revision 1.9  2005/10/13 16:30:11  dovoto
-	Changed KEYPAD_BITS to a typedef enum, this resolved some issues with multiple redefinition of KEYPAD_BITS (although this error did not allways occur).
-
-	Revision 1.8  2005/10/03 21:21:59  wntrmute
-	use enum types
-
-	Revision 1.7  2005/09/07 18:06:27  wntrmute
-	use new register names
-
-	Revision 1.6  2005/08/23 17:06:10  wntrmute
-	converted all endings to unix
-
-	Revision 1.5  2005/08/03 18:07:55  wntrmute
-	don't use nds.h
-
-	Revision 1.4  2005/07/25 02:31:07  wntrmute
-	made local variables static
-	added proper header to keys.h
-
-	Revision 1.3  2005/07/25 02:19:01  desktopman
-	Added support for KEY_LID in keys.c.
-	Moved KEYS_CUR from header to source file.
-	Changed from the custom abs() to stdlib.h's abs().
-
-	Revision 1.2  2005/07/14 08:00:57  wntrmute
-	resynchronise with ndslib
-
-
-------------------------------------------------------------------------------*/
-
-#include <stdlib.h>
-
-#include <NDS/scummvm_ipc.h>
-#include <nds/system.h>
-#include <nds/arm9/input.h>
-
-
-#define KEYS_CUR (( ((~REG_KEYINPUT)&0x3ff) | (((~IPC->buttons)&3)<<10) | (((~IPC->buttons)<<6) & (KEY_TOUCH|KEY_LID) ))^KEY_LID)
-
-namespace DS {
-
-static uint16 keys = 0;
-static uint16 keysold = 0;
-static uint16 keysrepeat = 0;
-
-static u8 delay = 60, repeat = 30, count = 60;
-
-static uint16 oldx = 0;
-static uint16 oldy = 0;
-
-void scanKeys(void) {
-	keysold = keys;
-	keys = KEYS_CUR;
-
-	oldx = IPC->touchXpx;
-	oldy = IPC->touchYpx;
-    if (delay != 0) {
-        if (keys != keysold) {
-            count = delay;
-            keysrepeat = keysDown();
-        }
-        count--;
-        if (count == 0) {
-            count = repeat;
-            keysrepeat = keys;
-        }
-    }
-}
-
-uint32 keysHeld(void) {
-	return keys;
-}
-
-uint32 keysDown(void) {
-	return (keys ^ keysold) & keys;
-}
-
-uint32 keysDownRepeat(void) {
-	uint32 tmp = keysrepeat;
-    keysrepeat = 0;
-    return tmp;
-}
-
-void keysSetRepeat( u8 setDelay, u8 setRepeat ) {
-    delay = setDelay;
-    repeat = setRepeat;
-    count = delay;
-    keysrepeat = 0;
-}
-
-uint32 keysUp(void) {
-	return (keys ^ keysold) & (~keys);
-}
-
-
-} // End of namespace DS
diff --git a/backends/platform/ds/arm9/source/keys.h b/backends/platform/ds/arm9/source/keys.h
deleted file mode 100644
index d118b37f28..0000000000
--- a/backends/platform/ds/arm9/source/keys.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-
-namespace DS {
-
-void scanKeys(void);
-uint32 keysHeld(void);
-uint32 keysDown(void);
-uint32 keysDownRepeat(void);
-void keysSetRepeat(u8 setDelay, u8 setRepeat);
-uint32 keysUp(void);
-
-} // End of namespace DS
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 69d3c932f9..0ac93bf728 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -644,7 +644,6 @@ void OSystem_DS::delayMillis(uint msecs) {
 	}
 
 	DS::doTimerCallback();
-	DS::checkSleepMode();
 	DS::addEventsToQueue();
 }
 
@@ -680,12 +679,6 @@ void OSystem_DS::deleteMutex(MutexRef mutex) {
 }
 
 void OSystem_DS::quit() {
-/*	consolePrintf("Soft resetting...");
-	IPC->reset = 1;
-	REG_IE = 0;
-
-	asm("swi 0x26\n");
-	swiSoftReset();*/
 }
 
 Graphics::Surface *OSystem_DS::createTempFrameBuffer() {
diff --git a/backends/platform/ds/arm9/source/touchkeyboard.cpp b/backends/platform/ds/arm9/source/touchkeyboard.cpp
index 30c46dbf06..fa5af909d2 100644
--- a/backends/platform/ds/arm9/source/touchkeyboard.cpp
+++ b/backends/platform/ds/arm9/source/touchkeyboard.cpp
@@ -21,7 +21,6 @@
  */
 
 #include <nds.h>
-#include "NDS/scummvm_ipc.h"
 #include "touchkeyboard.h"
 #include "keyboard_raw.h"
 #include "keyboard_pal_raw.h"
@@ -468,11 +467,11 @@ void addKeyboardEvents() {
 	}
 
 	if (DS::getPenDown()) {
-		int x = IPC->touchXpx;
-		int y = IPC->touchYpx;
+		touchPosition touchPos;
+		touchRead(&touchPos);
 
-		int tx = (x >> 3);
-		int ty = (y >> 3);
+		int tx = (touchPos.px >> 3);
+		int ty = (touchPos.py >> 3);
 
 		if (ty >= 12) {
 			int current = -1;
diff --git a/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h b/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
index 540348ca0b..6a75872da0 100644
--- a/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
+++ b/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
@@ -64,62 +64,14 @@ typedef struct {
 //////////////////////////////////////////////////////////////////////
 
 typedef struct scummvmTransferRegion {
-  uint32 heartbeat;          // counts frames
-
-   int16 touchX,   touchY;   // TSC X, Y
-   int16 touchXpx, touchYpx; // TSC X, Y pixel values
-   int16 touchZ1,  touchZ2;  // TSC x-panel measurements
-  uint16 tdiode1,  tdiode2;  // TSC temperature diodes
-  uint32 temperature;        // TSC computed temperature
-
-  uint16 buttons;            // X, Y, /PENIRQ buttons
-
-  union {
-    uint8 curtime[8];        // current time response from RTC
-
-    struct {
-      u8 command;
-      u8 year;           //add 2000 to get 4 digit year
-      u8 month;          //1 to 12
-      u8 day;            //1 to (days in month)
-
-      u8 incr;
-      u8 hours;          //0 to 11 for AM, 52 to 63 for PM
-      u8 minutes;        //0 to 59
-      u8 seconds;        //0 to 59
-    } rtc;
-  };
-
-  uint16 battery;            // battery life ??  hopefully.  :)
-  uint16 aux;                // i have no idea...
-
   TransferSound *soundData;
 
   adpcmBuffer adpcm;
 
-
-  // Don't rely on these below, will change or be removed in the future
-  vuint32 mailAddr;
-  vuint32 mailData;
-  vuint8 mailRead;
-  vuint8 mailBusy;
-  vuint32 mailSize;
-
-  bool performArm9SleepMode;
-
-  u32 test;
-  int tweak;
-  bool tweakChanged;
-
-//  bool fillSoundFirstHalf;
-//  bool fillSoundSecondHalf;
-
   // These are used for ScummVMs sound output
   bool fillNeeded[4];
   int playingSection;
 
-  bool reset;
-
   // Streaming sound
   bool streamFillNeeded[4];
   int streamPlayingSection;
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
index b0b6157c4a..901effd8dd 100644
--- a/backends/platform/ds/module.mk
+++ b/backends/platform/ds/module.mk
@@ -11,9 +11,7 @@ PORT_OBJS := \
 	arm9/source/osystem_ds.o \
 	arm9/source/touchkeyboard.o \
 	arm9/source/dsoptions.o \
-	arm9/source/keys.o \
-	arm9/source/wordcompletion.o \
-	arm9/source/interrupt.o
+	arm9/source/wordcompletion.o
 
 DATA_OBJS := \
 	arm9/data/icons.o \


Commit: 95ec2667956f0e7182ed63e417b134315d484adc
    https://github.com/scummvm/scummvm/commit/95ec2667956f0e7182ed63e417b134315d484adc
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Remove dead code

Changed paths:
  R backends/platform/ds/arm7/Makefile
  R backends/platform/ds/arm7/source/libcartreset/cartreset.c
  R backends/platform/ds/arm7/source/libcartreset/cartreset_nolibfat.h
  R backends/platform/ds/arm9/buildkeyboard.bat
  R backends/platform/ds/arm9/lib/readme.txt
  R backends/platform/ds/arm9/makefile
  R backends/platform/ds/arm9/ndsloader.bin
  R backends/platform/ds/arm9/source/mad/readme.txt
  R backends/platform/ds/makefile
    backends/platform/ds/arm7/source/main.cpp
    backends/platform/ds/arm9/source/blitters.cpp
    backends/platform/ds/arm9/source/blitters_arm.s
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsoptions.cpp
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/touchkeyboard.cpp
    backends/platform/ds/arm9/source/touchkeyboard.h
    backends/platform/ds/arm9/source/wordcompletion.cpp
    backends/platform/ds/ds.mk
    backends/platform/ds/module.mk


diff --git a/backends/platform/ds/arm7/Makefile b/backends/platform/ds/arm7/Makefile
deleted file mode 100644
index 2c75019aed..0000000000
--- a/backends/platform/ds/arm7/Makefile
+++ /dev/null
@@ -1,241 +0,0 @@
-#---------------------------------------------------------------------------------
-.SUFFIXES:
-#---------------------------------------------------------------------------------
-
-#---------------------------------------------------------------------------------
-# TARGET is the name of the output, if this ends with _mb generates a multiboot image
-# 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
-#---------------------------------------------------------------------------------
-TARGET	:=	arm7
-BUILD		:=	build
-SOURCES	:=	gfx source source/libcartreset data
-INCLUDES	:=	include build
-
-
-# Enable support for debugger (must be the same as in the arm9 makefile)
-#USE_DEBUGGER = 1
-
-#---------------------------------------------------------------------------------
-# options for code generation
-#---------------------------------------------------------------------------------
-ARCH	:=	-mthumb-interwork
-
-# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
-# *insists* it has a FPU or VFP, and it won't take no for an answer!
-CFLAGS	:=	-g -Wall -O2\
-		-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
-		-ffast-math \
-		$(ARCH)
-
-CFLAGS	+=	$(INCLUDE) -DARM7
-
-ifdef USE_DEBUGGER
-	CFLAGS += -DUSE_DEBUGGER
-endif
-
-
-CXXFLAGS	:=	$(CFLAGS) -fno-exceptions -fno-rtti
-ASFLAGS	:=	-g $(ARCH)
-LDFLAGS	:=	-g $(ARCH) -mno-fpu
-
-#---------------------------------------------------------------------------------
-# path to tools - this can be deleted if you set the path in windows
-#---------------------------------------------------------------------------------
-# export PATH		:=	/d/dev/ds/devkitARM_r11/bin:/bin
-
-#---------------------------------------------------------------------------------
-# PATH to ndslib - just make a system variable called NDSLIBPATH and be done with it
-#---------------------------------------------------------------------------------
-# NDSLIBPATH	:=	/d/dev/ds/ndslib/
-
-#---------------------------------------------------------------------------------
-# the prefix on the compiler executables
-#---------------------------------------------------------------------------------
-PREFIX			:=	arm-eabi-
-#---------------------------------------------------------------------------------
-# any extra libraries we wish to link with the project
-#---------------------------------------------------------------------------------
-LIBS	:= -lnds7
-
-ifdef USE_DEBUGGER
-	LIBS += -ldswifi7
-endif
-
-
-#---------------------------------------------------------------------------------
-# list of directories containing libraries, this must be the top level containing
-# include and lib
-#---------------------------------------------------------------------------------
-#LIBDIRS	:=	/home/neil/devkitpror21/libnds home/neil/devkitpror21/libnds/nds
-LIBDIRS	:=	$(DEVKITPRO)/libnds
-
-
-#---------------------------------------------------------------------------------
-# 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 OUTPUT	:=	$(CURDIR)/$(TARGET)
-
-export VPATH	:=	$(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
-
-export CC		:=	$(PREFIX)gcc
-export CXX		:=	$(PREFIX)g++
-export AR		:=	$(PREFIX)ar
-export OBJCOPY	:=	$(PREFIX)objcopy
-#---------------------------------------------------------------------------------
-# use CXX for linking C++ projects, CC for standard C
-#---------------------------------------------------------------------------------
-export LD		:=	$(CXX)
-#export LD		:=	$(CC)
-
-CFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
-CPPFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
-SFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
-PCXFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcx)))
-BINFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.bin)))
-PALFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pal)))
-RAWFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.raw)))
-MAPFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.map)))
-
-
-
-export OFILES	:=	$(MAPFILES:.map=.o) $(RAWFILES:.raw=.o) $(PALFILES:.pal=.o) $(BINFILES:.bin=.o) $(PCXFILES:.pcx=.o)\
-					$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
-
-export INCLUDE	:=	$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) -Iquote -I$(CURDIR)/../commoninclude\
-					$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-					$(foreach dir,$(LIBDIRS),-I$(dir)/include/nds)\
-					-I$(CURDIR)/$(BUILD) -I$(CURDIR)/source/libcartreset
-
-export LIBPATHS	:=	$(foreach dir,$(LIBDIRS),-L$(dir)/lib)
-
-.PHONY: $(BUILD) clean
-
-#---------------------------------------------------------------------------------
-$(BUILD):
-	@[ -d $@ ] || mkdir -p $@
-	@echo $(OFILES)
-	@echo $(CFILES)
-	@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
-
-#---------------------------------------------------------------------------------
-clean:
-	@echo clean ...$(TARGET)
-	@rm -fr $(BUILD) *.bin
-
-#---------------------------------------------------------------------------------
-semiclean:
-	@echo semiclean ...$(TARGET)
-
-
-#---------------------------------------------------------------------------------
-else
-
-DEPENDS	:=	$(OFILES:.o=.d)
-
-#---------------------------------------------------------------------------------
-# main targets
-#---------------------------------------------------------------------------------
-
-$(OUTPUT).bin	:	$(OUTPUT).elf
-
-$(OUTPUT).elf	:	$(OFILES)
-
-
-
-#---------------------------------------------------------------------------------
-%.bin: %.elf
-	@echo built ... $(notdir $@)
-	$(OBJCOPY) -O binary  $(TARGET).elf $@
-
-#---------------------------------------------------------------------------------
-%.elf:
-	echo ELF
-	+$(LD)  $(LDFLAGS) -specs=ds_arm7.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $(TARGET).elf
-
-
-
-#---------------------------------------------------------------------------------
-# Compile Targets for C/C++
-#---------------------------------------------------------------------------------
-
-#---------------------------------------------------------------------------------
-%.o : %.cpp
-	@echo $(notdir $<)
-	@echo $(CXX) -MM $(CXXFLAGS) -o $*.d $<
-	@$(CXX) -MM $(CXXFLAGS) -o $*.d $<
-	@$(CXX) $(CXXFLAGS) -c $< -o$@
-
-#---------------------------------------------------------------------------------
-%.o : %.c
-	@echo $(notdir $<)
-	@echo $(CC)  $(CFLAGS) -c $< -o$@
-	@$(CC) -MM $(CFLAGS) -o $*.d $<
-	@$(CC)  $(CFLAGS) -c $< -o$@
-
-#---------------------------------------------------------------------------------
-%.o : %.s
-	@echo $(notdir $<)
-	@$(CC) -MM $(CFLAGS) -o $*.d $<
-	@$(CC)  $(ASFLAGS) -c $< -o$@
-
-define bin2o
-	cp $(<) $(*).tmp
-	$(OBJCOPY) -I binary -O elf32-littlearm -B arm \
-	--rename-section .data=.rodata \
-	--redefine-sym _binary_$*_tmp_start=$*\
-	--redefine-sym _binary_$*_tmp_end=$*_end\
-	--redefine-sym _binary_$*_tmp_size=$*_size\
-	$(*).tmp $(@)
-	echo "extern const u8" $(*)"[];" > $(*).h
-	echo "extern const u32" $(*)_size[]";" >> $(*).h
-	rm $(*).tmp
-endef
-
-#---------------------------------------------------------------------------------
-%.o	:	%.pcx
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-#---------------------------------------------------------------------------------
-%.o	:	%.bin
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-#---------------------------------------------------------------------------------
-%.o	:	%.raw
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-#---------------------------------------------------------------------------------
-%.o	:	%.pal
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-#---------------------------------------------------------------------------------
-%.o	:	%.map
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-#---------------------------------------------------------------------------------
-%.o	:	%.mdl
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-
--include $(DEPENDS)
-
-#---------------------------------------------------------------------------------------
-endif
-#---------------------------------------------------------------------------------------
diff --git a/backends/platform/ds/arm7/source/libcartreset/cartreset.c b/backends/platform/ds/arm7/source/libcartreset/cartreset.c
deleted file mode 100644
index 85be823b71..0000000000
--- a/backends/platform/ds/arm7/source/libcartreset/cartreset.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/**********************************
-  Copyright (C) Rick Wong (Lick)
-  http://licklick.wordpress.com/
-***********************************/
-#include <cartreset_nolibfat.h>
-
-
-#ifdef ARM9
-
-bool cartSetMenuMode(u32 _deviceType)
-{
-    *(vu16*)(0x04000204) &= ~0x0880;    //sysSetBusOwners(true, true);
-    u32 deviceType = _deviceType;
-
-    *((vu32*)0x027FFFF8) = 0x080000C0; // ARM7 reset address
-
-    if(deviceType == DEVICE_TYPE_EFA2)
-    {
-        *(u16 *)0x9FE0000 = 0xD200;
-        *(u16 *)0x8000000 = 0x1500;
-        *(u16 *)0x8020000 = 0xD200;
-        *(u16 *)0x8040000 = 0x1500;
-        *(u16 *)0x9880000 = 1 << 15;
-        *(u16 *)0x9FC0000 = 0x1500;
-        return true;
-    }
-    else if(deviceType == DEVICE_TYPE_MPCF)
-    {
-        return true;
-    }
-    else if(deviceType == DEVICE_TYPE_EZSD)
-    {
-        return true;
-    }
-    else if(deviceType == DEVICE_TYPE_M3CF || deviceType == DEVICE_TYPE_M3SD)
-    {
-        u32 mode = 0x00400004;
-	    vu16 tmp;
-        tmp = *(vu16*)(0x08E00002);
-        tmp = *(vu16*)(0x0800000E);
-        tmp = *(vu16*)(0x08801FFC);
-        tmp = *(vu16*)(0x0800104A);
-        tmp = *(vu16*)(0x08800612);
-        tmp = *(vu16*)(0x08000000);
-        tmp = *(vu16*)(0x08801B66);
-        tmp = *(vu16*)(0x08000000 + (mode << 1));
-        tmp = *(vu16*)(0x0800080E);
-        tmp = *(vu16*)(0x08000000);
-
-        tmp = *(vu16*)(0x080001E4);
-        tmp = *(vu16*)(0x080001E4);
-        tmp = *(vu16*)(0x08000188);
-        tmp = *(vu16*)(0x08000188);
-        return true;
-    }
-    else if(deviceType == DEVICE_TYPE_SCCF || deviceType == DEVICE_TYPE_SCSD)
-    {
-        *(vu16*)0x09FFFFFE = 0xA55A;
-        *(vu16*)0x09FFFFFE = 0xA55A;
-        *(vu16*)0x09FFFFFE = 0;
-        *(vu16*)0x09FFFFFE = 0;
-        *((vu32*)0x027FFFF8) = 0x08000000; // Special ARM7 reset address
-        return true;
-    }
-
-    return false;
-}
-
-
-
-void passmeloopEnter()
-{
-    *(vu16*)(0x04000208) = 0;           //REG_IME = IME_DISABLE;
-    *(vu16*)(0x04000204) |= 0x0880;     //sysSetBusOwners(false, false);
-    *((vu32*)0x027FFFFC) = 0;
-    *((vu32*)0x027FFE04) = (u32)0xE59FF018;
-    *((vu32*)0x027FFE24) = (u32)0x027FFE04;
-    asm("swi 0x00");                    //swiSoftReset();
-    asm("bx lr");
-}
-
-#endif
-
-
-#ifdef ARM7
-
-//#include <nds.h>
-
-bool passmeloopQuery()
-{
-    if(*((vu32*)0x027FFE24) == (u32)0x027FFE04)
-        return true;
-    return false;
-}
-
-
-
-void cartExecute()
-{
-    *(vu16*)(0x04000208) = 0;       //REG_IME = IME_DISABLE;
-    *((vu32*)0x027FFE34) = *((vu32*)0x027FFFF8);
-    asm("swi 0x00");                //swiSoftReset();
-    asm("bx lr");
-}
-
-#endif
diff --git a/backends/platform/ds/arm7/source/libcartreset/cartreset_nolibfat.h b/backends/platform/ds/arm7/source/libcartreset/cartreset_nolibfat.h
deleted file mode 100644
index 98808f79c5..0000000000
--- a/backends/platform/ds/arm7/source/libcartreset/cartreset_nolibfat.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**********************************
-  Copyright (C) Rick Wong (Lick)
-  http://licklick.wordpress.com/
-***********************************/
-#ifndef CARTRESET_H
-#define CARTRESET_H
-
-#include <nds.h>
-//#include <fat.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef ARM9
-// Auto detect:
-#define DEVICE_TYPE_AUTO        0x00000000 // doesn't work in libcartreset "nolibfat" version
-
-// Not supported:
-#define DEVICE_TYPE_FCSR        0x52534346
-#define DEVICE_TYPE_MMCF        0x46434D4D
-#define DEVICE_TYPE_NJSD        0x44534A4E
-#define DEVICE_TYPE_NMMC        0x434D4D4E
-
-// Supported:
-#define DEVICE_TYPE_EFA2        0x32414645
-#define DEVICE_TYPE_MPCF        0x4643504D
-#define DEVICE_TYPE_M3CF        0x4643334D
-#define DEVICE_TYPE_M3SD        0x4453334D
-#define DEVICE_TYPE_SCCF        0x46434353
-#define DEVICE_TYPE_SCSD        0x44534353
-
-// Supported, but libfat doesn't detect the device:
-#define DEVICE_TYPE_EZSD        0x44535A45
-
-
-bool cartSetMenuMode(u32 _deviceType);
-void passmeloopEnter();
-
-#endif
-
-
-#ifdef ARM7
-
-bool passmeloopQuery();
-void cartExecute();
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/backends/platform/ds/arm7/source/main.cpp b/backends/platform/ds/arm7/source/main.cpp
index 95ae813ee0..355f0b09df 100644
--- a/backends/platform/ds/arm7/source/main.cpp
+++ b/backends/platform/ds/arm7/source/main.cpp
@@ -26,8 +26,6 @@
 // -- modified by Darkain and others
 //////////////////////////////////////////////////////////////////////
 
-// #define USE_LIBCARTRESET
-
 #include <nds.h>
 
 #include <bios.h>
@@ -44,8 +42,6 @@
 #include <dswifi7.h>
 #endif
 
-#include "cartreset_nolibfat.h"
-
 vu8 *soundData;
 
 vu8 *soundBuffer;
@@ -58,25 +54,7 @@ int temp;
 
 int adpcmBufferNum = 0;
 
-/*
-void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0, u8 vol = 0x7F, u8 pan = 63, u8 format = 0) {
-	SCHANNEL_TIMER(channel)  = SOUND_FREQ(sampleRate);
-	SCHANNEL_SOURCE(channel) = (uint32)data;
-	SCHANNEL_LENGTH(channel) = bytes;
-	SCHANNEL_CR(channel)     = SOUND_ENABLE | SOUND_ONE_SHOT | SOUND_VOL(vol) | SOUND_PAN(pan) | (format==1?SOUND_8BIT:SOUND_16BIT);
-}
-
 s8 getFreeSoundChannel() {
-	for (int i = 0; i < 16; i++) {
-		if ( (SCHANNEL_CR(i) & SOUND_ENABLE) == 0 )
-			return i;
-	}
-	return -1;
-}
-*/
-
-s8 getFreeSoundChannel() {
-	// return 0;
 	for (int i = 0; i < 16; i++) {
 		if ( (SCHANNEL_CR(i) & SCHANNEL_ENABLE) == 0 )
 			return i;
@@ -85,22 +63,12 @@ s8 getFreeSoundChannel() {
 }
 
 void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0, u8 vol = 0x7F, u8 pan = 63, u8 format = 0) {
-	// REG_IME = IME_DISABLE;
-
 	channel = getFreeSoundChannel();
-	/*
-	if (format == 2) {
-		channel = 1;
-	} else {
-		channel = 0;
-	}
-	*/
 
 	if (channel > 1)
 		channel = 1;
 
 	bytes &= ~7; // Multiple of 4 bytes!
-	// bytes += 4;
 
 	SCHANNEL_CR(channel) = 0;
 	SCHANNEL_TIMER(channel)  = SOUND_FREQ(sampleRate);
@@ -119,22 +87,21 @@ void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0,
 	switch (format) {
 	case 1: {
 		flags |= SOUND_FORMAT_8BIT;
-		flags |= SOUND_REPEAT; // | (1 << 15);
+		flags |= SOUND_REPEAT;
 		break;
 	}
 
 	case 0: {
 		flags |= SOUND_FORMAT_16BIT;
-		flags |= SOUND_REPEAT; // | (1 << 15);
+		flags |= SOUND_REPEAT;
 		break;
 	}
 
 	case 2: {
 		flags |= SOUND_FORMAT_ADPCM;
-		flags |= SOUND_ONE_SHOT; // | (1 << 15);
+		flags |= SOUND_ONE_SHOT;
 
 		SCHANNEL_SOURCE(channel) = (unsigned int)IPC->adpcm.buffer[0];
-		// bytes += 32;
 		SCHANNEL_LENGTH(channel) = ((bytes + 4) & 0x7FFFFFFF) >> 2;
 
 		SCHANNEL_CR(channel + 1) = 0;
@@ -149,13 +116,6 @@ void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0,
 	}
 	}
 
-	/*
-	if (bytes & 0x80000000) {
-		flags |= SOUND_REPEAT;
-	} else {
-	}
-	*/
-
 	soundData = (vu8 *)data;
 
 	SCHANNEL_CR(channel)     = flags;
@@ -188,18 +148,8 @@ void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0,
 		TIMER3_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
 		TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
 
-		for (int r = 0; r < 4; r++) {
-			// IPC->streamFillNeeded[r] = true;
-		}
-
 		IPC->streamPlayingSection = 0;
 	}
-
-	// IPC->fillSoundFirstHalf = true;
-	// IPC->fillSoundSecondHalf = true;
-	// soundFirstHalf = true;
-
-	// REG_IME = IME_ENABLE;
 }
 
 void stopSound(int chan) {
@@ -211,36 +161,12 @@ void InterruptTimer1() {
 	soundFilled[playingSection] = false;
 
 	if (playingSection == 3) {
-		// IME = IME_DISABLED;
-
-		// while (SCHANNEL_CR(0) & SCHANNEL_ENABLE) {
-		// }
-		// SCHANNEL_CR(0) &= ~SCHANNEL_ENABLE;
-
-		// SCHANNEL_CR(0) |= SCHANNEL_ENABLE;
-		// TIMER1_CR = 0;
-		// TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
-
 		playingSection = 0;
-
-		// IME = IME_ENABLED;
 	} else {
 		playingSection++;
 	}
 
 	IPC->playingSection = playingSection;
-
-/*	for (int r = 0; r < 4; r++) {
-		//if ((!soundFilled[r]) && (!IPC->fillNeeded[playingSection])) {
-			memcpy((void *) (soundBuffer + (r * 1024)), (void *) (arm9Buffer + (r * 1024)), 1024);
-
-			vu16 *p = (vu16 *) (soundBuffer);
-			//for (int t = 0; t < 2048; t++) {
-		//		*(p + t) = (t & 1)? 0xF000: 0x0000;
-			//}
-			soundFilled[r] = true;
-		//}
-	}*/
 }
 
 void InterruptTimer3() {
@@ -274,10 +200,6 @@ void VblankHandler() {
 			}
 		}
 	}
-
-#ifdef USE_DEBUGGER
-	Wifi_Update(); // update wireless in vblank
-#endif
 }
 
 //---------------------------------------------------------------------------------
@@ -294,67 +216,8 @@ void powerButtonCB() {
 	exitflag = true;
 }
 
-#ifdef USE_DEBUGGER
-// callback to allow wifi library to notify arm9
-void arm7_synctoarm9() { // send fifo message
-	REG_IPC_FIFO_TX = 0x87654321;
-}
-
-// interrupt handler to allow incoming notifications from arm9
-void arm7_fifo() { // check incoming fifo messages
-	u32 msg = REG_IPC_FIFO_RX;
-	if (msg == 0x87654321)
-		Wifi_Sync();
-}
-
-void initDebugger() {
-	// set up the wifi irq
-	irqSet(IRQ_WIFI, Wifi_Interrupt); // set up wifi interrupt
-	irqEnable(IRQ_WIFI);
-
-	// get them talking together
-
-	// sync with arm9 and init wifi
-	u32 fifo_temp;
-
-	while (1) { // wait for magic number
-		while (REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY)
-			swiWaitForVBlank();
-
-		fifo_temp = REG_IPC_FIFO_RX;
-
-		if (fifo_temp == 0x12345678)
-			break;
-	}
-
-	while (REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY)
-		swiWaitForVBlank();
-
-	fifo_temp = REG_IPC_FIFO_RX; // give next value to wifi_init
-	Wifi_Init(fifo_temp);
-
-	irqSet(IRQ_FIFO_NOT_EMPTY,arm7_fifo); // set up fifo irq
-	irqEnable(IRQ_FIFO_NOT_EMPTY);
-	REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ;
-
-	Wifi_SetSyncHandler(arm7_synctoarm9); // allow wifi lib to notify arm9
-	// arm7 wifi init complete
-}
-#endif
-
-#ifdef USE_LIBCARTRESET
-void reboot() {
-	cartExecute();
-}
-#endif
-
 int main(int argc, char ** argv) {
-#ifdef USE_DEBUGGER
-	REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR;
-#endif
-
 	// enable sound
-	// powerOn(POWER_SOUND);
 	SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
 	IPC->soundData = 0;
 
@@ -395,19 +258,6 @@ int main(int argc, char ** argv) {
 	irqSet(IRQ_TIMER3, InterruptTimer3);
 	irqEnable(IRQ_TIMER3);
 
-	/*
-	REG_IME = 0;
-	IRQ_HANDLER = &InterruptHandler;
-	REG_IE = IRQ_VBLANK | IRQ_TIMER1 | IRQ_TIMER3;
-	REG_IF = ~0;
-	DISP_SR = DISP_VBLANK_IRQ;
-	REG_IME = 1;
-	*/
-
-#ifdef USE_DEBUGGER
-	initDebugger();
-#endif
-
 	setPowerButtonCB(powerButtonCB);
 
 	// Keep the ARM7 mostly idle
@@ -415,11 +265,6 @@ int main(int argc, char ** argv) {
 		if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) {
 			exitflag = true;
 		}
-#ifdef USE_LIBCARTRESET
-		if (passmeloopQuery()) {
-			reboot();
-		}
-#endif
 
 		swiWaitForVBlank();
 	}
diff --git a/backends/platform/ds/arm9/buildkeyboard.bat b/backends/platform/ds/arm9/buildkeyboard.bat
deleted file mode 100644
index ae3398d24d..0000000000
--- a/backends/platform/ds/arm9/buildkeyboard.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-cd data
-..\tools\gfx2gba -c16 -t8 -M -pkeyboard_pal.raw ..\keyboard.bmp
-del keyboard.map
-pause
diff --git a/backends/platform/ds/arm9/lib/readme.txt b/backends/platform/ds/arm9/lib/readme.txt
deleted file mode 100644
index 2469e38cd0..0000000000
--- a/backends/platform/ds/arm9/lib/readme.txt
+++ /dev/null
@@ -1 +0,0 @@
-If building with MAD enabled, put libmad.a in here.
diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile
deleted file mode 100644
index 88af796607..0000000000
--- a/backends/platform/ds/arm9/makefile
+++ /dev/null
@@ -1,409 +0,0 @@
-srcdir      ?= .
-DEPDIR      := .deps
-
-#DYNAMIC_MODULES = 1
-libndsdir = $(DEVKITPRO)/libnds
-#libndsdir = /home/neil/devkitpror21/libnds
-
-# Select the build by setting SCUMM_BUILD to a,b,c,d,e,f or g.
-# Anything else gets build a.
-
-ifeq ($(SCUMM_BUILD),k)
-	DS_BUILD_K = 1
-else
- ifeq ($(SCUMM_BUILD),j)
- 	DS_BUILD_J = 1
- else
-  ifeq ($(SCUMM_BUILD),i)
-        DS_BUILD_I = 1
-  else
-   ifeq ($(SCUMM_BUILD),h)
-          DS_BUILD_H = 1
-   else
-    ifeq ($(SCUMM_BUILD),g)
-         DS_BUILD_G = 1
-    else
-     ifeq ($(SCUMM_BUILD),f)
-         DS_BUILD_F = 1
-     else
-      ifeq ($(SCUMM_BUILD),e)
-         DS_BUILD_E = 1
-      else
-       ifeq ($(SCUMM_BUILD),d)
-         DS_BUILD_D = 1
-       else
-        ifeq ($(SCUMM_BUILD),c)
-         DS_BUILD_C = 1
-        else
-         ifeq ($(SCUMM_BUILD),b)
-         DS_BUILD_B = 1
-         else
-          DS_BUILD_A = 1
-         endif
-        endif
-       endif
-      endif
-     endif
-    endif
-   endif
-  endif
- endif
-endif
-# To do:
-# - FAT cache?
-
-
-
-# Uncomment the following line to build in support for MP3 audio
-# using libmad:
-
-ifdef DS_BUILD_F
-	# TODO: Fix this.  When libmad is compiled in, the Kyrandia resource loading
-	# searches through it's entire index to find an mp3 each time a voice sample is requested
-	# this causes a nasty pause.
-else
-	ifdef DS_BUILD_E
-	# TODO: Inherit the earth uses so much RAM that I have removed libmad in order to
-	# claw some back.
-
-
-
-	else
-		ifdef DS_BUILD_I
-
-		else
-			ifdef DS_BUILD_K
-
-			else
-				USE_MAD = 1
-			endif
-		endif
-	endif
-endif
-
-# Uncomment the following line to enable support for the
-# ace DS Debugger (remembering to make the same change in the arm7 makefile):
-#USE_DEBUGGER = 1
-
-# Uncomment the following line to enable the profiler
-#USE_PROFILER = 1
-
-# NOTE: The header and libs for the debugger is assumed to be in the libnds
-# folder.
-
-vpath %.h $(srcdir)
-vpath %.cpp $(srcdir)
-vpath %.c $(srcdir)
-vpath %.m $(srcdir)
-vpath %.asm $(srcdir)
-vpath %.s $(srcdir)
-
-# Command to build libmad is:
-# ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork'
-#
-# I actually had to use
-# ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork' LDFLAGS='C:/Progra~1/devkitpro/libnds/lib/libnds9.a' --disable-shared --disable-debugging
-
-
-# handy command to find where the big symbols are in the ELF:
-# arm-eabi-nm -S --radix=d --demangle scummvm.elf |sort -n -r --key=2 |less
-
-ARM = 1
-USE_ARM_SOUND_ASM = 1
-USE_ARM_COSTUME_ASM = 1
-#WRAP_MALLOC = 1
-
-ifdef DS_BUILD_A
-	DEFINES = -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM
-	ENABLE_SCUMM = STATIC_PLUGIN
-	USE_ARM_GFX_ASM = 1
-	BUILD=scummvm-A
-endif
-
-ifdef DS_BUILD_B
-	DEFINES = -DDS_BUILD_B
-	ENABLE_SKY = STATIC_PLUGIN
-	ENABLE_QUEEN = STATIC_PLUGIN
-	BUILD=scummvm-B
-endif
-
-ifdef DS_BUILD_C
-	DEFINES = -DDS_BUILD_C
-	ENABLE_AGOS = STATIC_PLUGIN
-	BUILD=scummvm-C
-endif
-
-ifdef DS_BUILD_D
-	DEFINES = -DDS_BUILD_D
-	ENABLE_GOB = STATIC_PLUGIN
-	ENABLE_CINE = STATIC_PLUGIN
-	ENABLE_AGI = STATIC_PLUGIN
-	BUILD=scummvm-D
-endif
-
-ifdef DS_BUILD_E
-	DEFINES = -DDS_BUILD_E
-	ENABLE_SAGA = STATIC_PLUGIN
-	BUILD=scummvm-E
-endif
-
-ifdef DS_BUILD_F
-	DEFINES = -DDS_BUILD_F
-	ENABLE_KYRA = STATIC_PLUGIN
-	BUILD=scummvm-F
-endif
-
-ifdef DS_BUILD_G
-	DEFINES = -DDS_BUILD_G
-	ENABLE_LURE = STATIC_PLUGIN
-	BUILD=scummvm-G
-endif
-
-ifdef DS_BUILD_H
-	DEFINES = -DDS_BUILD_H
-	ENABLE_PARALLACTION = STATIC_PLUGIN
-	BUILD=scummvm-H
-endif
-
-ifdef DS_BUILD_I
-	DEFINES = -DDS_BUILD_I
-	ENABLE_MADE = STATIC_PLUGIN
-	BUILD=scummvm-I
-endif
-
-ifdef DS_BUILD_K
-	DEFINES = -DDS_BUILD_K
-	ENABLE_CRUISE = STATIC_PLUGIN
-	BUILD=scummvm-K
-endif
-
-
-#ifdef DS_BUILD_L
-#	DEFINES = -DDS_BUILD_L
-#	ENABLE_DRASCULA = STATIC_PLUGIN
-#	BUILD=scummvm-K
-#endif
-
-#ifdef DS_BUILD_M
-#	DEFINES = -DDS_BUILD_M
-#	ENABLE_TUCKER = STATIC_PLUGIN
-#	BUILD=scummvm-K
-#endif
-
-ARM7BIN	:= -7 $(CURDIR)/../../arm7/arm7.bin
-
-CC      = arm-eabi-gcc
-CXX     = arm-eabi-g++
-LD	= arm-eabi-g++
-
-CFLAGS	=	-Wno-multichar -Wall\
-		-mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer\
-		-mthumb-interwork -DUSE_ARM_COSTUME_ASM=1 -DDISABLE_SID
-
-
-# -ffast-math
-
-ifdef USE_DEBUGGER
-	DEFINES += -DUSE_DEBUGGER
-	CFLAGS += -g
-endif
-
-ifdef USE_PROFILER
-	CFLAGS += -mpoke-function-name -finstrument-functions -g
-	DEFINES += -DUSE_PROFILER
-endif
-
-CXXFLAGS=	$(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder  \
-		-fno-exceptions -fno-rtti -mthumb-interwork -ffunction-sections -fdata-sections -fno-strict-aliasing
-
-#		-mthumb
-
-#		-fno-gcse\
-#		-fno-schedule-insns2
-
-#		-fno-inline-functions-called-once\
-#		-fno-gcse-lm\
-#		-fno-rerun-cse-after-loop\
-#		-fno-cse-follow-jumps -fno-cse-skip-blocks\
-
-
-ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork
-DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DARM
-ifdef USE_MAD
-	DEFINES += -DUSE_MAD
-endif
-
-DEFINES += -DREDUCE_MEMORY_USAGE -DDISABLE_DEBUGGER -DUSE_TEXT_CONSOLE_FOR_DEBUGGER -DDISABLE_MASS_ADD -DDISABLE_NES_APU
-# for release builds:
-#DEFINES +=  -DNDEBUG
-
-LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt -Wl,--gc-sections
-
-ifdef WRAP_MALLOC
-	LDFLAGS += -Wl,--wrap,malloc
-	DEFINES += -DWRAP_MALLOC
-endif
-
-BACKEND := ds
-
-INCLUDES= -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/engines \
-			-I$(portdir)/data -I$(portdir)/../commoninclude \
-			-I$(portdir)/source -I$(portdir)/source/mad \
-			-I$(libndsdir)/include -include $(portdir)/source/portdefs.h
-
-
-LIBS	= -lm -L$(libndsdir)/lib -L$(portdir)/lib -lnds9
-ifdef USE_MAD
-	LIBS += -lmad
-endif
-ifdef USE_DEBUGGER
-	LIBS += -ldsdebugger -ldswifi9
-endif
-
-EXECUTABLE = scummvm.elf
-MKDIR = mkdir -p
-RM = rm -f
-RM_REC = rm -rf
-AR = arm-eabi-ar cru
-RANLIB = arm-eabi-ranlib
-OBJCOPY = arm-eabi-objcopy
-AS = arm-eabi-as
-HAVE_GCC3 = true
-
-PORT_OBJS := \
-	$(portdir)/source/blitters_arm.o \
-	$(portdir)/source/cdaudio.o \
-	$(portdir)/source/dsmain.o \
-	$(portdir)/source/gbampsave.o \
-	$(portdir)/source/scummhelp.o \
-	$(portdir)/source/osystem_ds.o \
-	$(portdir)/source/touchkeyboard.o \
-	$(portdir)/source/zipreader.o \
-	$(portdir)/source/dsoptions.o \
-	$(portdir)/source/keys.o \
-	$(portdir)/source/wordcompletion.o \
-	$(portdir)/source/interrupt.o
-
-ifdef USE_PROFILER
-	PORT_OBJS += $(portdir)/source/profiler/cyg-profile.o
-endif
-
-
-DATA_OBJS := \
-	$(portdir)/data/icons.o \
-	$(portdir)/data/keyboard.o \
-	$(portdir)/data/keyboard_pal.o \
-	$(portdir)/data/default_font.o \
-	$(portdir)/data/8x8font_tga.o
-
-FAT_OBJS := \
-	$(portdir)/source/fat/disc_io.o \
-	$(portdir)/source/fat/gba_nds_fat.o \
-	$(portdir)/source/fat/io_fcsr.o \
-	$(portdir)/source/fat/io_m3cf.o \
-	$(portdir)/source/fat/io_mpcf.o \
-	$(portdir)/source/fat/io_sccf.o \
-	$(portdir)/source/fat/io_m3sd.o \
-	$(portdir)/source/fat/io_nmmc.o \
-	$(portdir)/source/fat/io_scsd.o \
-	$(portdir)/source/fat/io_scsd_asm.o \
-	$(portdir)/source/fat/io_njsd.o \
-	$(portdir)/source/fat/io_mmcf.o \
-	$(portdir)/source/fat/io_sd_common.o \
-	$(portdir)/source/fat/io_m3_common.o \
-	$(portdir)/source/fat/io_dldi.o \
-	$(portdir)/source/fat/m3sd.o
-
-
-# Files in this list will be optimisied for speed, otherwise they will be optimised for space
-OPTLIST := actor.cpp dsmain.cpp osystem_ds.cpp blitters.cpp mame.cpp rate.cpp isomap.cpp image.cpp gfx.cpp sprite.cpp actor_path.cpp actor_walk.cpp script.cpp
-#OPTLIST :=
-
-# Compiler options for files which should be optimised for speed
-ifdef DS_BUILD_E
-  # Another attempt to save some RAM in ITE
-  OPT_SPEED := -O3 -mthumb
-else
-  OPT_SPEED := -O3
-endif
-
-# Compiler options for files which should be optimised for space
-OPT_SIZE := -Os -mthumb
-
-
-OBJS := $(DATA_OBJS) $(PORT_OBJS) $(FAT_OBJS)
-
-
-
-MODULE_DIRS += .
-
-ndsall:
-	@[ -d $(BUILD) ] || mkdir -p $(BUILD)
-	$(MAKE) -C ./$(BUILD) -f ../makefile scummvm.nds scummvm.ds.gba
-
-include $(srcdir)/Makefile.common
-
-semiclean:
-	$(RM) $(portdir)/source/dsoptions.o $(portdir)/source/dsmain.o $(FAT_OBJS) $(DATA_OBJS) $(portdir)/source/wordcompletion.o $(portdir)/source/dsoptions.o
-
-clean:
-	$(RM) $(OBJS) $(EXECUTABLE)
-	rm -fr $(BUILD)
-
-dist : SCUMMVM.BIN plugins plugin_dist
-
-
-#---------------------------------------------------------------------------------
-# canned command sequence for binary data
-#---------------------------------------------------------------------------------
-define bin2o
-	bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@)
-	echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(<F) | tr . _)`.h
-	echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(<F) | tr . _)`.h
-	echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(<F) | tr . _)`.h
-endef
-
-
-##############
-# Replacement rule for the one in makefile.common
-##############
-%.o: %.cpp
-	$(MKDIR) $(*D)/$(DEPDIR)
-	$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(if $(findstring $(notdir $<), $(OPTLIST)), $(OPT_SPEED), $(OPT_SIZE)) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
-
-
-#---------------------------------------------------------------------------------
-
-#---------------------------------------------------------------------------------
-%.o	:	%.bin
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-#---------------------------------------------------------------------------------
-%.o	:	%.raw
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-#---------------------------------------------------------------------------------
-%.o	:	%.pal
-#---------------------------------------------------------------------------------
-	@echo $(notdir $<)
-	@$(bin2o)
-
-#---------------------------------------------------------------------------------
-%.nds: %.bin
-	ndstool -c $@ -9 $< $(ARM7BIN) -b ../../logo.bmp "$(@F);ScummVM $(VERSION);DS Port"
-
-%.ds.gba: %.nds
-	dsbuild $< -o $@ -l $(portdir)/ndsloader.bin
-	padbin 16 $@
-
-#---------------------------------------------------------------------------------
-%.bin: %.elf
-	$(OBJCOPY) -S -O binary $< $@
-
-#%.o: %.s
-#	$(MKDIR) $(*D)/$(DEPDIR)
-#	$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
diff --git a/backends/platform/ds/arm9/ndsloader.bin b/backends/platform/ds/arm9/ndsloader.bin
deleted file mode 100644
index 05abb01b2a..0000000000
Binary files a/backends/platform/ds/arm9/ndsloader.bin and /dev/null differ
diff --git a/backends/platform/ds/arm9/source/blitters.cpp b/backends/platform/ds/arm9/source/blitters.cpp
index 44de0ed0f6..c58c1f292a 100644
--- a/backends/platform/ds/arm9/source/blitters.cpp
+++ b/backends/platform/ds/arm9/source/blitters.cpp
@@ -36,9 +36,6 @@ void asmDrawStripToScreen(int height, int width, byte const *text, byte const *s
 		return;
 
 	width &= ~4;
-//	src = (const byte *) (((int) (src)) & (~4));
-//	dst = (byte *) (((int) (dst)) & (~4));
-//	text = (const byte *) (((int) (text)) & (~4));
 
 	asm (	"mov r5, %0\n"				// Height
 			"yLoop:\n"
diff --git a/backends/platform/ds/arm9/source/blitters_arm.s b/backends/platform/ds/arm9/source/blitters_arm.s
index a5e071f7dd..c97c2e2b32 100644
--- a/backends/platform/ds/arm9/source/blitters_arm.s
+++ b/backends/platform/ds/arm9/source/blitters_arm.s
@@ -20,14 +20,6 @@
 @
 @ @author Robin Watts (robin at wss.co.uk)
 
-@	.global timerTickHandler
-@	.align 2
-@	.code 32
-
- at timerTickHandler:
-@	bx lr
-
-
 	.global	Rescale_320x256xPAL8_To_256x256x1555
 	.global	Rescale_320x256x1555_To_256x256x1555
 @	.section .itcm,"ax", %progbits
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 7abfe30b41..25d31c1889 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -77,8 +77,6 @@
 #include <nds/arm9/console.h>
 #include <filesystem.h>
 
-//#include <ARM9/console.h> //basic print funcionality
-
 #include <stdlib.h>
 #include <string.h>
 
@@ -90,15 +88,8 @@
 #include "keyboard_pal_raw.h"
 #define V16(a, b) ((a << 12) | b)
 #include "touchkeyboard.h"
-//#include "compact_flash.h"
 #include "dsoptions.h"
-#ifdef USE_DEBUGGER
-#include "user_debugger.h"
-#endif
 #include "blitters.h"
-#ifdef USE_PROFILER
-#include "profiler/cyg-profile.h"
-#endif
 #include "engines/engine.h"
 
 #include "backends/plugins/ds/ds-provider.h"
@@ -113,64 +104,6 @@ static const char *registerNames[] =
 	{	"r0","r1","r2","r3","r4","r5","r6","r7",
 		"r8 ","r9 ","r10","r11","r12","sp ","lr ","pc" };
 
-#ifdef WRAP_MALLOC
-
-extern "C" void *__real_malloc(size_t size);
-
-static int s_total_malloc = 0;
-
-void *operator new (size_t size) {
-	register unsigned int reg asm("lr");
-	volatile unsigned int poo = reg;
-
-	void *res = __real_malloc(size);
-	s_total_malloc += size;
-
-	if (!res) {
-//		*((u8 *) NULL) = 0;
-		consolePrintf("Failed alloc (new) %d (%d)\n", size, s_total_malloc);
-		return NULL;
-	}
-
-	return res;
-}
-
-
-extern "C" void *__wrap_malloc(size_t size) {
-/*	u32 addr;
-
-	asm("mov %0, lr"
-		: "=r" (addr)
-		:
-		: );*/
-
-	register unsigned int reg asm("lr");
-	volatile unsigned int poo = reg;
-
-
-	if (size == 0) {
-		static int zeroSize = 0;
-		consolePrintf("0 size malloc (%d)", zeroSize++);
-	}
-
-	void *res = __real_malloc(size);
-	if (res) {
-		if (size > 50 * 1024) {
-			consolePrintf("Allocated %d (%x)\n", size, poo);
-		}
-		s_total_malloc += size;
-		return res;
-	} else {
-
-//		*((u8 *) NULL) = 0;
-		consolePrintf("Failed alloc %d (%d)\n", size, s_total_malloc);
-		return NULL;
-	}
-}
-
-
-#endif
-
 namespace DS {
 
 // From console.c in NDSLib
@@ -294,18 +227,6 @@ static int gameHeight = 200;
 static bool twoHundredPercentFixedScale = false;
 static bool cpuScalerEnable = false;
 
-		// 100    256
-		// 150	  192
-		// 200	  128
-
-		// (256 << 8) / scale
-
-
-
-#ifdef USE_PROFILER
-static int hBlankCount = 0;
-#endif
-
 static u8 *scalerBackBuffer = NULL;
 
 #define NUM_SUPPORTED_GAMES 21
@@ -410,20 +331,10 @@ void setGamma(int gamma) {
 }
 
 void setTopScreenZoom(int percentage) {
-		// 100    256
-		// 150	  192
-		// 200	  128
-
-		// (256 << 8) / scale
-
 	s32 scale = (percentage << 8) / 100;
 	subScreenScale = (256 * 256) / scale;
-
-//	consolePrintf("Scale is %d %%\n", percentage);
 }
 
-//	return (ConfMan.hasKey("cpu_scaler", "ds") && ConfMan.getBool("cpu_scaler", "ds"));
-
 controlType getControlType() {
 	return s_currentGame->control;
 }
@@ -557,32 +468,21 @@ void initGame() {
 	consolePrintf("initing game...");
 	#endif
 
-//	static bool firstTime = true;
-
 	setOptions();
 
-	//strcpy(gameName, ConfMan.getActiveDomain().c_str());
 	if (s_currentGame == NULL) {
 
 		strcpy(gameName, ConfMan.get("gameid").c_str());
-	//	consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]);
 
 		s_currentGame = &gameList[0];		// Default game
 
 		for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) {
 			if (!scumm_stricmp(gameName, gameList[r].gameId)) {
 				s_currentGame = &gameList[r];
-	//			consolePrintf("Game list num: %d\n", r);
 			}
 		}
 	}
 
-/*	if (firstTime) {
-		firstTime = false;
-
-
-	}
-*/
 	#ifdef HEAVY_LOGGING
 	consolePrintf("done\n");
 	#endif
@@ -695,7 +595,6 @@ void displayMode8Bit() {
 
 	for (int r = 0; r < 32 * 32; r++) {
 		((u16 *) SCREEN_BASE_BLOCK(2))[r] = buffer[r];
-//		dmaCopyHalfWords(3, (u16 *) SCREEN_BASE_BLOCK(0), buffer, 32 * 32 * 2);
 	}
 
 	// ConsoleInit destroys the hardware palette :-(
@@ -703,18 +602,6 @@ void displayMode8Bit() {
 		OSystem_DS::instance()->restoreHardwarePalette();
 	}
 
-//	BG_PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
-
-	// Do text stuff
-	// console chars at 1C000 (7), map at 1D000 (74)
-
-//	BG0_CR = BG_MAP_BASE(2) | BG_TILE_BASE(0);
-//	BG0_Y0 = 0;
-
-	// Restore palette entry used by text in the front-end
-//	PALETTE_SUB[255] = savedPalEntry255;
-
-
 	#ifdef HEAVY_LOGGING
 	consolePrintf("done\n");
 	#endif
@@ -759,8 +646,6 @@ void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX,
 	mouseHotspotX = hotspotX;
 	mouseHotspotY = hotspotY;
 
-	//consolePrintf("Set cursor icon %d, %d\n", w, h);
-
 	off = 128*64;
 
 
@@ -772,8 +657,6 @@ void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX,
 		for (uint x=0; x<w; x++) {
 			int color = icon[y*w+x];
 
-			//consolePrintf("%d:%d ", color, OSystem_DS::instance()->getDSPaletteEntry(color));
-
 			if (color == keycolor) {
 				SPRITE_GFX[off+(y)*32+x] = 0x0000; // black background
 				SPRITE_GFX_SUB[off+(y)*32+x] = 0x0000; // black background
@@ -892,20 +775,15 @@ void displayMode16Bit() {
 	SUB_BG0_Y0 = 0;
 
 	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 4, 0, false, true);
-//	consoleInitDefault((u16 *)SCREEN_BASE_BLOCK_SUB(4), (u16 *)CHAR_BASE_BLOCK_SUB(0), 16);
 
 	for (int r = 0; r < 32 * 32; r++) {
 		((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r] = buffer[r];
 	}
 
 	consoleSetWindow(NULL, 0, 0, 32, 24);
-//	consolePrintSet(0, 23);
-//	consolePrintf("Hello world!\n\n");
-//	consolePrintf("\n");
 
 	// Show keyboard
 	SUB_BG1_CR = BG_TILE_BASE(1) | BG_MAP_BASE(12);
-	//drawKeyboard(1, 12);
 
 	POWER_CR &= ~POWER_SWAP_LCDS;
 
@@ -935,9 +813,6 @@ void displayMode16BitFlipBuffer() {
 	if (!displayModeIs8Bit) {
 		u16 *back = get16BitBackBuffer();
 
-//		highBuffer = !highBuffer;
-//		BG3_CR = BG_BMP16_512x256 |	BG_BMP_RAM(highBuffer ? 1 : 0);
-
 		if (isCpuScalerEnabled()) {
 			Rescale_320x256x1555_To_256x256x1555(BG_GFX, back, 512, 512);
 		} else {
@@ -1056,18 +931,6 @@ void doTimerCallback() {
 }
 
 void soundUpdate() {
-	if ((bufferFrame == 0)) {
-//		playSound(soundBuffer, (bufferSamples * 2), true);
-	}
-
-
-	if (bufferFrame == 0) {
-//		bufferFirstHalf = true;
-	}
-	if (bufferFrame == bufferSize >> 1) {
-	//bufferSecondHalf = true;
-	}
-
 	bufferFrame++;
 	if (bufferFrame == bufferSize) {
 		bufferFrame = 0;
@@ -1105,8 +968,6 @@ void addIndyFightingKeys() {
 	event.type = Common::EVENT_KEYDOWN;
 	event.kbd.flags = 0;
 
-//	consolePrintf("Fight keys\n");
-
 	if ((getKeysDown() & KEY_L)) {
 		indyFightRight = false;
 	}
@@ -1115,8 +976,6 @@ void addIndyFightingKeys() {
 		indyFightRight = true;
 	}
 
-//	consolePrintf("ifr:%d\n", indyFightRight);
-
 	if ((getKeysChanged() & KEY_UP)) {
 		event.type = getKeyEvent(KEY_UP);
 		event.kbd.keycode = Common::KEYCODE_8;
@@ -1229,9 +1088,6 @@ void setKeyboardEnable(bool en) {
 			BG_PALETTE_SUB[r] = BG_PALETTE[r];
 		}
 
-
-		//restoreVRAM(1, 12, backupBank);
-
 		if (displayModeIs8Bit) {
 			// Copy the sub screen VRAM from the top screen - they should always be
 			// the same.
@@ -1243,10 +1099,7 @@ void setKeyboardEnable(bool en) {
 					BG_GFX_SUB[y * 256 + x] = buffer[(y * (stride / 2)) + x];
 				}
 			}
-/*
-			for (int r = 0; r < (512 * 256) >> 1; r++)
-				BG_GFX_SUB[r] = buffer[r];
-*/
+
 			SUB_DISPLAY_CR &= ~DISPLAY_BG1_ACTIVE;	// Turn off keyboard layer
 			SUB_DISPLAY_CR |= DISPLAY_BG3_ACTIVE;	// Turn on game layer
 		} else {
@@ -1345,7 +1198,6 @@ void doButtonSelectMode(OSystem_DS *system) {
 		event.type = Common::EVENT_MOUSEMOVE;
 		event.mouse = Common::Point(getPenX(), getPenY());
 		system->addEvent(event);
-		//consolePrintf("x=%d   y=%d  \n", getPenX(), getPenY());
 	}
 
 	if (getPenReleased() && (leftButtonDown || rightButtonDown)) {
@@ -1441,9 +1293,6 @@ void doButtonSelectMode(OSystem_DS *system) {
 
 					event.type = Common::EVENT_RBUTTONDOWN;
 					system->addEvent(event);
-
-					//event.type = Common::EVENT_RBUTTONUP;
-					//system->addEvent(event);
 				}
 			}
 
@@ -1463,21 +1312,6 @@ void addEventsToQueue() {
 	OSystem_DS *system = OSystem_DS::instance();
 	Common::Event event;
 
-#ifdef USE_PROFILER
-/*
-	if (keysDown() & KEY_R) {
-		cygprofile_begin();
-		cygprofile_enable();
-	}
-	if (keysDown() & KEY_L) {
-		cygprofile_disable();
-		cygprofile_end();
-	}
-*/
-#endif
-
-
-
 	if (system->isEventQueueEmpty()) {
 
 		if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
@@ -1633,8 +1467,7 @@ void addEventsToQueue() {
 
 				if (s_currentGame->control == CONT_AGI) {
 					// Extra controls for Leisure Suit Larry and KQ4
-					if ((getKeysHeld() & KEY_UP) && (getKeysHeld() & KEY_START)
-						/*&& (!strcmp(gameName, "LLLLL"))*/) {
+					if ((getKeysHeld() & KEY_UP) && (getKeysHeld() & KEY_START)) {
 						consolePrintf("Cheat key!\n");
 						event.type = Common::EVENT_KEYDOWN;
 						event.kbd.keycode = (Common::KeyCode)'X';		// Skip age test in LSL
@@ -1655,7 +1488,6 @@ void addEventsToQueue() {
 						event.kbd.ascii = Common::ASCII_F10;
 						event.kbd.flags = 0;
 						system->addEvent(event);
-//						consolePrintf("F10\n");
 
 						event.type = Common::EVENT_KEYUP;
 						system->addEvent(event);
@@ -1726,14 +1558,12 @@ void addEventsToQueue() {
 			} else if (s_currentGame->control == CONT_GOBLINS) {
 				event.kbd.keycode = Common::KEYCODE_F1;
 				event.kbd.ascii = Common::ASCII_F1;
-//				consolePrintf("!!!!!F1!!!!!");
 			} else if (s_currentGame->control == CONT_AGI) {
 				event.kbd.keycode = Common::KEYCODE_ESCAPE;
 				event.kbd.ascii = 27;
 			} else {
 				event.kbd.keycode = Common::KEYCODE_F5;		// F5
 				event.kbd.ascii = Common::ASCII_F5;
-//				consolePrintf("!!!!!F5!!!!!");
 			}
 			system->addEvent(event);
 		}
@@ -1794,9 +1624,6 @@ void updateStatus() {
 
 		if (indyFightState) {
 			setIcon(1, (190 - 32), 150, 3, (indyFightRight ? 0 : ATTR1_FLIP_X), true);
-//			consolePrintf("%d\n", indyFightRight);
-		} else {
-//			setIcon(1, 0, 0, 0, 0, false);
 		}
 
 		if (triggeredIconTimeout > 0) {
@@ -1815,15 +1642,8 @@ void updateStatus() {
 	}
 
 	if ((keyboardIcon) && (!keyboardEnable) && (!displayModeIs8Bit)) {
-//		spritesMain[0].attribute[0] = ATTR0_BMP | 160;
-//		spritesMain[0].attribute[1] = ATTR1_SIZE_32 | 0;
-//		spritesMain[0].attribute[2] = ATTR2_ALPHA(1) | 64;
 		setIconMain(0, 0, 160, 4, 0, true);
 	} else {
-//		spritesMain[0].attribute[0] = ATTR0_DISABLED;
-//		spritesMain[0].attribute[1] = 0;
-//		spritesMain[0].attribute[2] = 0;
-//		spritesMain[0].filler = 0;
 		setIconMain(0, 0, 0, 0, 0, false);
 	}
 
@@ -1832,12 +1652,6 @@ void updateStatus() {
 void soundBufferEmptyHandler() {
 	REG_IF = IRQ_TIMER2;
 
-	if (soundHiPart) {
-//		bufferSecondHalf = true;
-	} else {
-//		bufferFirstHalf = true;
-	}
-
 // TIMER0
 	if ((callback) && (callbackTimer > 0)) {
 		callbackTimer--;
@@ -1849,10 +1663,6 @@ void soundBufferEmptyHandler() {
 }
 
 void setMainScreenScroll(int x, int y) {
-/*	if (gameScreenSwap) {
-		SUB_BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
-		SUB_BG3_CY = y;
-	} else */{
 		BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
 		BG3_CY = y;
 
@@ -1860,16 +1670,9 @@ void setMainScreenScroll(int x, int y) {
 			touchX = x >> 8;
 			touchY = y >> 8;
 		}
-	}
 }
 
 void setMainScreenScale(int x, int y) {
-/*	if (gameScreenSwap) {
-		SUB_BG3_XDX = x;
-		SUB_BG3_XDY = 0;
-		SUB_BG3_YDX = 0;
-		SUB_BG3_YDY = y;
-	} else*/ {
 		if (isCpuScalerEnabled() && (x==320)) {
 			BG3_XDX = 256;
 			BG3_XDY = 0;
@@ -1886,18 +1689,9 @@ void setMainScreenScale(int x, int y) {
 			touchScX = x;
 			touchScY = y;
 		}
-	}
 }
 
 void setZoomedScreenScroll(int x, int y, bool shake) {
-/*	if (gameScreenSwap) {
-		BG3_CX = x + ((shake && ((frameCount & 1) == 0))? 64: 0);
-		BG3_CY = y;
-
-		touchX = x >> 8;
-		touchY = y >> 8;
-	} else */{
-
 		if ((gameScreenSwap) && (!touchPadStyle)) {
 			touchX = x >> 8;
 			touchY = y >> 8;
@@ -1906,18 +1700,9 @@ void setZoomedScreenScroll(int x, int y, bool shake) {
 
 		SUB_BG3_CX = x + ((shake && (frameCount & 1) == 0)? 64: 0);
 		SUB_BG3_CY = y;
-	}
 }
 
 void setZoomedScreenScale(int x, int y) {
-/*	if (gameScreenSwap) {
-		BG3_XDX = x;
-		BG3_XDY = 0;
-		BG3_YDX = 0;
-		BG3_YDY = y;
-
-	} else */{
-
 		if ((gameScreenSwap) && (!touchPadStyle)) {
 			touchScX = x;
 			touchScY = y;
@@ -1927,37 +1712,9 @@ void setZoomedScreenScale(int x, int y) {
 		SUB_BG3_XDY = 0;
 		SUB_BG3_YDX = 0;
 		SUB_BG3_YDY = y;
-	}
 }
 
-#ifdef USE_PROFILER
-void VBlankHandler(void) __attribute__ ((no_instrument_function));
-#endif
-
 void VBlankHandler(void) {
-//	BG_PALETTE[0] = RGB15(31, 31, 31);
-//	if (*((int *) (0x023FFF00)) != 0xBEEFCAFE) {
-	//	consolePrintf("Guard band overwritten!");
-//  }
-
-	//consolePrintf("X:%d Y:%d\n", getPenX(), getPenY());
-/*
-	if ((callback) && (callbackTimer > 0)) {
-		callbackTimer--;
-	}
-	currentTimeMillis++;
-*/
-/*	static int firstTime = 1;
-
-	// This is to ensure that the ARM7 vblank handler runs before this one.
-	// Fixes the problem with the MMD when the screens swap over on load.
-	if (firstTime > 0) {
-		REG_IF = IRQ_VBLANK;
-		firstTime--;
-		return;
-	}
-*/
-
 	soundUpdate();
 
 
@@ -2034,26 +1791,9 @@ void VBlankHandler(void) {
 				scX = dragScX + ((dragStartX - penX));
 				scY = dragScY + ((dragStartY - penY));
 			}
-
-//			consolePrintf("X:%d Y:%d\n", dragStartX - penX, dragStartY - penY);
 		}
 	}
 
-
-/*	if ((frameCount & 1) == 0) {
-		SUB_BG3_CX = subScX;
-	} else {
-		SUB_BG3_CX = subScX + 64;
-	}
-	SUB_BG3_CX += (s_shakeXOffset << 8)
-
-	SUB_BG3_CY = subScY + (s_shakeYOffset << 8);*/
-
-	/*SUB_BG3_XDX = (int) (subScreenWidth / 256.0f * 256);
-	SUB_BG3_XDY = 0;
-	SUB_BG3_YDX = 0;
-	SUB_BG3_YDY = (int) (subScreenHeight / 192.0f * 256);*/
-
 	static int ratio = (320 << 8) / SCUMM_GAME_WIDTH;
 
 	bool zooming = false;
@@ -2079,10 +1819,6 @@ void VBlankHandler(void) {
 		subScreenWidth = 256 >> 1;
 		subScreenHeight = 192 >> 1;
 	} else {
-//		subScreenWidth = (((SCUMM_GAME_HEIGHT * 256) / 192) * subScreenScale) >> 8;
-//		subScreenHeight = SCUMM_GAME_HEIGHT * subScreenScale >> 8;
-
-
 		subScreenWidth = (256 * subScreenScale) >> 8;
 		subScreenHeight = (192 * subScreenScale) >> 8;
 
@@ -2110,8 +1846,6 @@ void VBlankHandler(void) {
 				subScY = subScTargetY;
 				triggerIcon(7);
 			}
-		} else {
-			//triggerIcon(-1);
 		}
 	}
 
@@ -2219,25 +1953,19 @@ void VBlankHandler(void) {
 	}
 
 	updateOAM();
-
-	//PALETTE[0] = RGB15(0, 0, 0);
-	//REG_IF = IRQ_VBLANK;
 }
 
 int getMillis(bool skipRecord) {
 	return currentTimeMillis;
-//	return frameCount * FRAME_TIME;
 }
 
 void setTimerCallback(OSystem_DS::TimerProc proc, int interval) {
-//	consolePrintf("Set timer proc %x, int %d\n", proc, interval);
 	callback = proc;
 	callbackInterval = interval;
 	callbackTimer = interval;
 }
 
 void timerTickHandler() {
-//	REG_IF = IRQ_TIMER0;
 	if ((callback) && (callbackTimer > 0)) {
 		callbackTimer--;
 	}
@@ -2249,11 +1977,7 @@ void timerTickHandler() {
 
 
 void setTalkPos(int x, int y) {
-//	if (gameID != Scumm::GID_SAMNMAX) {
-//		setTopScreenTarget(x, 0);
-//	} else {
-		setTopScreenTarget(x, y);
-//	}
+	setTopScreenTarget(x, y);
 }
 
 void setTopScreenTarget(int x, int y) {
@@ -2270,14 +1994,6 @@ void setTopScreenTarget(int x, int y) {
 	subScTargetY <<=8;
 }
 
-#ifdef USE_PROFILER
-void hBlankHanlder() __attribute__ ((no_instrument_function));
-
-void hBlankHandler() {
-	hBlankCount++;
-}
-#endif
-
 void uploadSpriteGfx() {
 	vramSetBankD(VRAM_D_SUB_SPRITE);
 	vramSetBankE(VRAM_E_MAIN_SPRITE);
@@ -2292,30 +2008,14 @@ void uploadSpriteGfx() {
 }
 
 void initHardware() {
-	// Guard band
-//((int *) (0x023FFF00)) = 0xBEEFCAFE;
-
-
 	penInit();
 
 	powerOn(POWER_ALL);
-/*	vramSetBankA(VRAM_A_MAIN_BG);
-	vramSetBankB(VRAM_B_MAIN_BG);
-	vramSetBankC(VRAM_C_SUB_BG); */
 	vramSetBankD(VRAM_D_SUB_SPRITE);
 	vramSetBankE(VRAM_E_MAIN_SPRITE);
 
 	currentTimeMillis = 0;
 
-
-/*
-	// Set up a millisecond counter
-	TIMER0_CR = 0;
-	TIMER0_DATA = 0xFFFF;
-	TIMER0_CR = TIMER_ENABLE | TIMER_CASCADE;
-*/
-
-
 	for (int r = 0; r < 255; r++) {
 		BG_PALETTE[r] = 0;
 	}
@@ -2330,7 +2030,6 @@ void initHardware() {
 	BG_PALETTE_SUB[255] = RGB15(0,31,0);
 
 	// Allocate save buffer for game screen
-//	savedBuffer = new u8[320 * 200];
 	displayMode16Bit();
 
 	memset(BG_GFX, 0, 512 * 256 * 2);
@@ -2342,25 +2041,13 @@ void initHardware() {
 	subScTargetX = 0;
 	subScTargetY = 0;
 
-	//lcdSwap();
 	POWER_CR &= ~POWER_SWAP_LCDS;
 
 	frameCount = 0;
 	callback = NULL;
 
-//	vramSetBankH(VRAM_H_SUB_BG);
-
-
-//	// Do text stuff
-	//BG0_CR = BG_MAP_BASE(0) | BG_TILE_BASE(1);
-//	BG0_Y0 = 48;
-
 	BG_PALETTE[255] = RGB15(31,31,31);//by default font will be rendered with color 255
 
-	//consoleInit() is a lot more flexible but this gets you up and running quick
-//	consoleInitDefault((u16 *)SCREEN_BASE_BLOCK(0), (u16 *)CHAR_BASE_BLOCK(1), 16);
-	//consolePrintSet(0, 6);
-
 	//irqs are nice
 	irqSet(IRQ_VBLANK, VBlankHandler);
 	irqSet(IRQ_TIMER0, timerTickHandler);
@@ -2368,13 +2055,6 @@ void initHardware() {
 
 	irqEnable(IRQ_VBLANK);
 	irqEnable(IRQ_TIMER0);
-//	irqEnable(IRQ_TIMER2);
-
-#ifdef USE_PROFILER
-	irqSet(IRQ_HBLANK, hBlankHandler);
-	irqEnable(IRQ_HBLANK);
-#endif
-
 
 	// Set up a millisecond timer
 	#ifdef HEAVY_LOGGING
@@ -2392,14 +2072,11 @@ void initHardware() {
 
 	initSprites();
 
-//	videoSetModeSub(MODE_3_2D | DISPLAY_BG0_ACTIVE | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
-
 	// If the software scaler's back buffer has not been allocated, do it now
 	scalerBackBuffer = (u8 *) malloc(320 * 256);
 
 
 	WAIT_CR &= ~(0x0080);
-//	REG_WRAM_CNT = 0;
 
 	uploadSpriteGfx();
 
@@ -2454,7 +2131,6 @@ void penUpdate() {
 			if (((tapTimeout > 15) || (tapCount == 2)) && (tapCount > 0)) {
 				tapComplete = tapCount;
 				tapCount = 0;
-//				consolePrintf("Taps: %d\n", tapComplete);
 			}
 		}
 
@@ -2465,7 +2141,6 @@ void penUpdate() {
 				if ((penDownFrames > 0) && (penDownFrames < 6) && ((tapTimeout == -1) || (tapTimeout > 2))) {
 					tapCount++;
 					tapTimeout = 0;
-//					consolePrintf("Tap! %d\n", penDownFrames);
 					moved = false;
 				}
 			}
@@ -2749,32 +2424,6 @@ void fastRamReset() {
 }
 
 
-
-#ifdef USE_DEBUGGER
-void initDebugger() {
-	set_verbosity(VERBOSE_INFO | VERBOSE_ERROR);
-	wireless_init(0);
-	wireless_connect();
-
-	// This is where the address of the computer running the Java
-	// stub goes.
-	debugger_connect_tcp(192, 168, 0, 1);
-	debugger_init();
-
-	// Update function - should really call every frame
-	user_debugger_update();
-}
-
-
-// Ensure the function is processed with C linkage
-extern "C" void debug_print_stub(char *string);
-
-void debug_print_stub(char *string) {
-	consolePrintf(string);
-}
-#endif
-
-
 /////////////////
 // Main
 /////////////////
@@ -2847,16 +2496,6 @@ int main(void) {
 
 	setExceptionHandler(dsExceptionHandler);
 
-#ifdef USE_DEBUGGER
-	for (int r = 0; r < 150; r++) {
-		swiWaitForVBlank();
-	}
-	if (!(keysHeld() & KEY_Y)) {
-		initDebugger();
-	}
-#endif
-
-
 	// Let arm9 read cartridge
 	*((u16 *) (0x04000204)) &= ~0x0080;
 
@@ -2867,65 +2506,9 @@ int main(void) {
 	indyFightRight = true;
 
 
-	// CPU speed = 67108864
-	// 8 frames = 2946   368.5 bytes per fr
-
-//	playSound(stretch, 47619, false);
-//	playSound(twang, 11010, true);   // 18640
-
-//	bufferSize = 10;
-
-
-	/*bufferRate = 44100;
-	bufferFrame = 0;
-	bufferSamples = 8192;
-
-	bufferFirstHalf = false;
-	bufferSecondHalf = true;
-
-	int bytes = (2 * (bufferSamples)) + 100;
-
-	soundBuffer = (s16 *) malloc(bytes * 2);
-
-
-	soundHiPart = true;
-
-	for (int r = 0; r < bytes; r++) {
-		soundBuffer[r] = 0;
-	}
-
-
-	swiWaitForVBlank();
-	swiWaitForVBlank();
-	playSound(soundBuffer, (bufferSamples * 2), true);
-	swiWaitForVBlank();
-	swiWaitForVBlank();
-	swiWaitForVBlank();
-*/
-
-
 	lastEventFrame = 0;
 	mouseMode = MOUSE_LEFT;
 
-
-/*
-	TIMER1_CR = 0;
-	TIMER1_DATA = TIMER_FREQ(bufferRate);
-	TIMER1_CR = TIMER_ENABLE | TIMER_DIV_1;
-
-	TIMER2_CR = 0;
-	TIMER2_DATA = 0xFFFF - (bufferSamples / 2);
-	TIMER2_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
-	*/
-	// 2945 - 2947
-
-
-
-//	for (int r = 2946; r < 3000; r++) {
-//		soundBuffer[r] = 30000;
-//	}
-
-
 	//2372
 	consolePrintf("-------------------------------\n");
 	consolePrintf("ScummVM DS\n");
@@ -2992,17 +2575,11 @@ int main(void) {
 
 	updateStatus();
 
-
-//	OSystem_DS::instance();
-
 	g_system = new OSystem_DS();
 	assert(g_system);
 
 	IPC->adpcm.semaphore = false;
 
-//	printf("'%s'", Common::ConfigManager::kTransientDomain.c_str());
-	//printf("'%s'", Common::ConfigManager::kApplicationDomain.c_str());
-
 #if defined(DS_BUILD_A)
 	const char *argv[] = {"/scummvmds"};
 #elif defined(DS_BUILD_B)
@@ -3053,19 +2630,6 @@ int main() {
 }
 
 
-#ifdef USE_PROFILER
-int cygprofile_getHBlanks() __attribute__ ((no_instrument_function));
-
-
-int cygprofile_getHBlanks() {
-	return DS::hBlankCount;
-}
-
-
-extern "C" void consolePrintf(char * format, ...) __attribute__ ((no_instrument_function));
-#endif
-
-
 extern "C" void consolePrintf(const char * format, ...) {
 	va_list args;
 	va_start(args, format);
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp
index c28ffb86f1..cd76d22dd5 100644
--- a/backends/platform/ds/arm9/source/dsoptions.cpp
+++ b/backends/platform/ds/arm9/source/dsoptions.cpp
@@ -125,14 +125,6 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 
 	_radioButtonMode = false;
 
-//	new GUI::StaticTextWidget(this, 90, 10, 130, 15, "ScummVM DS Options", Graphics::kTextAlignCenter);
-
-
-//#ifdef ALLOW_CPU_SCALER
-//	_cpuScaler = new GUI::CheckboxWidget(this, 160, 115, 90, 20, "CPU scaler", 0, 0, 'T');
-//#endif
-
-
 #ifdef DS_BUILD_D
 	_snapToBorderCheckbox->setState(confGetBool("snaptoborder", true));
 #else
@@ -216,7 +208,6 @@ DSOptionsDialog::~DSOptionsDialog() {
 void DSOptionsDialog::updateConfigManager() {
 	ConfMan.setBool("lefthanded", _leftHandedCheckbox->getState(), "ds");
 	ConfMan.setBool("unscaled", _unscaledCheckbox->getState(), "ds");
-//	ConfMan.setBool("twohundredpercent", _twoHundredPercentCheckbox->getState(), "ds");
 	ConfMan.setBool("22khzaudio", _highQualityAudioCheckbox->getState(), "ds");
 	ConfMan.setBool("disablepoweroff", _disablePowerOff->getState(), "ds");
 #ifdef ALLOW_CPU_SCALER
diff --git a/backends/platform/ds/arm9/source/mad/readme.txt b/backends/platform/ds/arm9/source/mad/readme.txt
deleted file mode 100644
index c911ab9271..0000000000
--- a/backends/platform/ds/arm9/source/mad/readme.txt
+++ /dev/null
@@ -1 +0,0 @@
-Put mad.h here if you are compiling with Madlib support enabled.
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 0ac93bf728..2240456a54 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -37,7 +37,6 @@
 #include "osystem_ds.h"
 #include "nds.h"
 #include "dsmain.h"
-#include "nds/registers_alt.h"
 #include "common/config-manager.h"
 #include "common/str.h"
 #include "graphics/surface.h"
@@ -89,12 +88,7 @@ OSystem_DS::OSystem_DS()
 	: eventNum(0), lastPenFrame(0), queuePos(0), _mixer(NULL), _frameBufferExists(false),
 	_disableCursorPalette(true), _graphicsEnable(true), _gammaValue(0)
 {
-//	eventNum = 0;
-//	lastPenFrame = 0;
-//	queuePos = 0;
 	_instance = this;
-//	_mixer = NULL;
-	//_frameBufferExists = false;
 	_fsFactory = new DevoptabFilesystemFactory();
 }
 
@@ -171,8 +165,6 @@ int16 OSystem_DS::getWidth() {
 }
 
 void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
-//	consolePrintf("Setpal %d, %d\n", start, num);
-
 	for (unsigned int r = start; r < start + num; r++) {
 		int red = *colors;
 		int green = *(colors + 1);
@@ -182,7 +174,6 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 		green >>= 3;
 		blue >>= 3;
 
-//		if (r != 255)
 		{
 			u16 paletteValue = red | (green << 5) | (blue << 10);
 
@@ -197,7 +188,6 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 
 			_palette[r] = paletteValue;
 		}
-	//	if (num == 255) consolePrintf("pal:%d r:%d g:%d b:%d\n", r, red, green, blue);
 
 		colors += 3;
 	}
@@ -217,7 +207,6 @@ void OSystem_DS::restoreHardwarePalette() {
 
 void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
 
-//	consolePrintf("Cursor palette set: start: %d, cols: %d\n", start, num);
 	for (unsigned int r = start; r < start + num; r++) {
 		int red = *colors;
 		int green = *(colors + 1);
@@ -238,8 +227,6 @@ void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
 }
 
 void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) const {
-//	consolePrintf("Grabpalette");
-
 	for (unsigned int r = start; r < start + num; r++) {
 		*colors++ = (BG_PALETTE[r] & 0x001F) << 3;
 		*colors++ = (BG_PALETTE[r] & 0x03E0) >> 5 << 3;
@@ -256,8 +243,6 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 	if (h < 0) return;
 	if (!DS::getIsDisplayMode8Bit()) return;
 
-//	consolePrintf("CopyRectToScreen %d\n", w * h);
-
 	u16 *bg;
 	s32 stride;
 	u16 *bgSub = (u16 *)BG_GFX_SUB;
@@ -391,9 +376,6 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 			}
 		}
 
-//		consolePrintf("Slow method used!\n");
-
-
 	} else {
 
 		// Stuff is aligned to 16-bit boundaries, so it's safe to do DMA.
@@ -435,13 +417,9 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 			}
 		}
 	}
-//	consolePrintf("Done\n");
 }
 
 void OSystem_DS::updateScreen() {
-//	static int cnt = 0;
-//	consolePrintf("updatescr %d\n", cnt++);
-
 	if ((_frameBufferExists) && (DS::getIsDisplayMode8Bit())) {
 		_frameBufferExists = false;
 
@@ -451,7 +429,6 @@ void OSystem_DS::updateScreen() {
 
 	DS::displayMode16BitFlipBuffer();
 	DS::doSoundCallback();
-//	DS::doTimerCallback();
 	DS::addEventsToQueue();
 
 	// FIXME: Evil game specific hack.
@@ -466,7 +443,6 @@ void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
 }
 
 void OSystem_DS::showOverlay() {
-//	consolePrintf("showovl\n");
 	DS::displayMode16Bit();
 }
 
@@ -480,11 +456,9 @@ bool OSystem_DS::isOverlayVisible() const {
 
 void OSystem_DS::clearOverlay() {
 	memset((u16 *) DS::get16BitBackBuffer(), 0, 512 * 256 * 2);
-//	consolePrintf("clearovl\n");
 }
 
 void OSystem_DS::grabOverlay(void *buf, int pitch) {
-//	consolePrintf("grabovl\n")
 	u16 *start = DS::get16BitBackBuffer();
 
 	for (int y = 0; y < 200; y++) {
@@ -502,46 +476,22 @@ void OSystem_DS::copyRectToOverlay(const void *buf, int pitch, int x, int y, int
 	u16 *bg = (u16 *) DS::get16BitBackBuffer();
 	const u8 *source = (const u8 *)buf;
 
-//	if (x + w > 256) w = 256 - x;
-	//if (x + h > 256) h = 256 - y;
-
-//	consolePrintf("Copy rect ovl %d, %d   %d, %d  %d\n", x, y, w, h, pitch);
-
-
-
 	for (int dy = y; dy < y + h; dy++) {
 		const u16 *src = (const u16 *)source;
 
-		// Slow but save copy:
 		for (int dx = x; dx < x + w; dx++) {
-
 			*(bg + (dy * 512) + dx) = *src;
-			//if ((*src) != 0) consolePrintf("%d,%d: %d   ", dx, dy, *src);
-			//consolePrintf("%d,", *src);
 			src++;
 		}
 		source += pitch;
-
-		// Fast but broken copy: (why?)
-		/*
-		REG_IME = 0;
-		dmaCopy(src, bg + (dy << 9) + x, w * 2);
-		REG_IME = 1;
-
-		src += pitch;*/
 	}
-
-//	consolePrintf("Copy rect ovl done");
-
 }
 
 int16 OSystem_DS::getOverlayHeight() {
-//	consolePrintf("getovlheight\n");
 	return getHeight();
 }
 
 int16 OSystem_DS::getOverlayWidth() {
-//	consolePrintf("getovlwid\n");
 	return getWidth();
 }
 
@@ -590,43 +540,13 @@ bool OSystem_DS::pollEvent(Common::Event &event) {
 			event.kbd.ascii = 0;
 			event.kbd.keycode = Common::KEYCODE_INVALID;
 			event.kbd.flags = 0;
-//			consolePrintf("type: %d\n", event.type);
 			return false;
 		} else {
 			event = eventQueue[eventNum++];
-//			consolePrintf("type: %d\n", event.type);
 			return true;
 		}
 	}
 
-	return false;
-
-/*	if (lastPenFrame != DS::getMillis()) {
-		if ((eventNum == 0)) {
-			event.type = Common::EVENT_MOUSEMOVE;
-			event.mouse = Common::Point(DS::getPenX(), DS::getPenY());
-			eventNum = 1;
-			return true;
-		}
-		if (eventNum == 1) {
-			eventNum = 0;
-			lastPenFrame = DS::getMillis();
-			if (DS::getPenDown()) {
-				event.type = Common::EVENT_LBUTTONDOWN;
-				event.mouse = Common::Point(DS::getPenX(), DS::getPenY());
-				consolePrintf("Down %d, %d  ", event.mouse.x, event.mouse.y);
-				return true;
-			} else if (DS::getPenReleased()) {
-				event.type = Common::EVENT_LBUTTONUP;
-				event.mouse = Common::Point(DS::getPenX(), DS::getPenY());
-				consolePrintf("Up %d, %d ", event.mouse.x, event.mouse.y);
-				return true;
-			} else {
-				return false;
-			}
-		}
-	}*/
-
 	return false;
 }
 
@@ -722,19 +642,6 @@ Graphics::Surface *OSystem_DS::createTempFrameBuffer() {
 
 	_frameBufferExists = true;
 
-/*
-	size_t imageStrideInBytes = DS::get8BitBackBufferStride();
-	size_t imageStrideInWords = imageStrideInBytes / 2;
-
-	u16 *image = (u16 *) DS::get8BitBackBuffer();
-	for (int y = 0; y <  DS::getGameHeight(); y++) {
-		DC_FlushRange(image + (y * imageStrideInWords), DS::getGameWidth());
-		for (int x = 0; x < DS::getGameWidth() >> 1; x++) {
-			*(((u16 *) (_framebuffer.getPixels())) + y * (DS::getGameWidth() >> 1) + x) = image[(y * imageStrideInWords) + x];
-//			*(((u16 *) (surf->getPixels())) + y * (DS::getGameWidth() >> 1) + x) = image[y * imageStrideInWords + x];
-		}
-	}*/
-
 	return &_framebuffer;
 }
 
@@ -779,8 +686,8 @@ Common::String OSystem_DS::getDefaultConfigFileName() {
 void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
 #ifndef DISABLE_TEXT_CONSOLE
 	nocashMessage((char *)message);
-//	consolePrintf((char *)message);
 #endif
+	printf("%s", message);
 }
 
 u16 OSystem_DS::applyGamma(u16 color) {
diff --git a/backends/platform/ds/arm9/source/touchkeyboard.cpp b/backends/platform/ds/arm9/source/touchkeyboard.cpp
index fa5af909d2..27d27ef142 100644
--- a/backends/platform/ds/arm9/source/touchkeyboard.cpp
+++ b/backends/platform/ds/arm9/source/touchkeyboard.cpp
@@ -180,28 +180,12 @@ void drawText(int tx, int ty, const char *string, bool highlight) {
 
 }
 
-
-
-void restoreVRAM(int tileBase, int mapBase, u16 *saveSpace) {
-/*	for (int r = 0; r < 32 * 32; r++) {
-		((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase))[r] = *saveSpace++;
-	}
-
-	for (int r = 0; r < 4096; r++) {
-		((u16 *) CHAR_BASE_BLOCK_SUB(tileBase))[r]	= *saveSpace++;
-	}*/
-}
-
 void drawKeyboard(int tileBase, int mapBase, u16 *saveSpace) {
- 	/* int keyboardDataSize = 4736 * 2; */
-
 	for (int r = 0; r < 32 * 32; r++) {
-//		*saveSpace++ = ((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase))[r];
 		((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase))[r] = 0;
 	}
 
 	for (int r = 0; r < KEYBOARD_DATA_SIZE / 2; r++) {
-//		*saveSpace++ = ((u16 *) CHAR_BASE_BLOCK_SUB(tileBase))[r];
 		((u16 *) CHAR_BASE_BLOCK_SUB(tileBase))[r] = ((u16 *) (::keyboard_raw))[r];
 	}
 
@@ -354,32 +338,9 @@ void clearAutoComplete() {
 
 void typeCompletion(int current) {
 	Common::Event event;
-	/* OSystem_DS *system = OSystem_DS::instance(); */
 
 	strcat(autoCompleteBuffer, &autoCompleteWord[current][charactersEntered]);
 	strcat(autoCompleteBuffer, " ");
-
-/*	consolePrintf("Typing word: %s\n", autoCompleteWord[current]);
-
-	for (int r = charactersEntered; r < strlen(autoCompleteWord[current]); r++) {
-		event.kbd.keycode = autoCompleteWord[current][r];
-		event.kbd.ascii = autoCompleteWord[current][r];
-		event.type = Common::EVENT_KEYDOWN;
-		event.kbd.flags = 0;
-		system->addEvent(event);
-
-		event.type = Common::EVENT_KEYUP;
-		system->addEvent(event);
-	}
-
-	event.kbd.keycode = ' ';
-	event.kbd.ascii = ' ';
-
-	event.type = Common::EVENT_KEYDOWN;
-	system->addEvent(event);
-
-	event.type = Common::EVENT_KEYUP;
-	system->addEvent(event);*/
 }
 
 void updateTypeEvents() {
@@ -411,7 +372,7 @@ void createKeyEvent(int keyNum, Common::Event& event) {
 
 		if (!DS::shiftState) {
 			event.kbd.ascii = keys[keyNum].character;
-			event.kbd.keycode = (Common::KeyCode) keys[keyNum].character; //Common::KEYCODE_INVALID;
+			event.kbd.keycode = (Common::KeyCode) keys[keyNum].character;
 		} else {
 			event.kbd.keycode = (Common::KeyCode) (Common::KEYCODE_F1 - (keys[keyNum].character - '1'));
 			event.kbd.ascii = 0;
@@ -496,30 +457,19 @@ void addKeyboardEvents() {
 		tx -= keyboardX;
 		ty -= keyboardY;
 
-//		consolePrintf("x=%d y=%d\n", tx, ty);
-
 		for (int r = 0; r < DS_NUM_KEYS; r++) {
 			if (( (tx >= keys[r].x) && (tx <= keys[r].x + 1)) &&
 				   (ty >= keys[r].y) && (ty <= keys[r].y + 1)) {
 				OSystem_DS *system = OSystem_DS::instance();
 				Common::Event event;
 
-//				consolePrintf("Key: %d\n", r);
-				if ((keys[r].character == Common::KEYCODE_INVALID)) {
-					// Close button
-					//DS::closed = true;
-				} else {
+				if ((keys[r].character != Common::KEYCODE_INVALID)) {
 					createKeyEvent(r, event);
 				}
 
-				//event.kbd.keycode = keys[r].character;
-				//event.kbd.ascii = keys[r].character;
 				event.type = Common::EVENT_KEYDOWN;
 				system->addEvent(event);
 
-//				event.type = Common::EVENT_KEYUP;
-//				system->addEvent(event);
-
 				switch (keys[r].character) {
 					case DS_SHIFT: {
 						DS::shiftState = !DS::shiftState;
diff --git a/backends/platform/ds/arm9/source/touchkeyboard.h b/backends/platform/ds/arm9/source/touchkeyboard.h
index f64d531b82..cac602b090 100644
--- a/backends/platform/ds/arm9/source/touchkeyboard.h
+++ b/backends/platform/ds/arm9/source/touchkeyboard.h
@@ -36,7 +36,6 @@ enum {
 void createKeyEvent(int keyNum, Common::Event& event);
 
 void drawKeyboard(int tileBase, int mapBase, u16 *saveSpace);
-void restoreVRAM(int tileBase, int mapBase, u16 *saveSpace);
 void addKeyboardEvents();
 bool getKeyboardClosed();
 bool isInsideKeyboard(int x, int y);
diff --git a/backends/platform/ds/arm9/source/wordcompletion.cpp b/backends/platform/ds/arm9/source/wordcompletion.cpp
index eb0d5d7914..c89640bf10 100644
--- a/backends/platform/ds/arm9/source/wordcompletion.cpp
+++ b/backends/platform/ds/arm9/source/wordcompletion.cpp
@@ -139,16 +139,10 @@ bool findWordCompletions(const char *input) {
 			// We're too early, so change the maximum position
 			max = position - 1;
 		}
-
-//		consolePrintf("Word: %s, (%d, %d) result: %d\n", word, min, max, result);
-
 	} while (max - min > 0);
 
 	position = min;
 	word = wordBufferPtr[position];
-	//consolePrintf("Final word: %s\n", word);
-
-
 
 	system->setCharactersEntered(strlen(partialWord));
 
@@ -168,7 +162,6 @@ bool findWordCompletions(const char *input) {
 		if (position == wordBufferPtrPos)
 			return false;
 		word = wordBufferPtr[position];
-//		consolePrintf("Final word: %s\n", word);
 	}
 
 
diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk
index d9682f8dce..2b1b38cded 100644
--- a/backends/platform/ds/ds.mk
+++ b/backends/platform/ds/ds.mk
@@ -24,50 +24,10 @@
 #   DEFAULT_CONFIG_FILE).
 #   There are a few game specific hacks which are currently controlled by this,
 #   too; we need to investigate those.
-# * No support for USE_DEBUGGER and USE_PROFILER yet. I envision that we would
-#  integrate them with the --enable-debug and --enable-profiling configure options,
-#  I simply haven't gotten around to do that yet.
-# * ...
 
 # Set location of ndsdir so that we can easily refer to files in it
 ndsdir = backends/platform/ds
 
-# Uncomment the following line to enable support for the
-# ace DS Debugger (remembering to make the same change in the arm7 makefile):
-#USE_DEBUGGER = 1
-# TODO: Need to reimplement this (for arm9 and arm7).
-#ifdef USE_DEBUGGER
-#	DEFINES += -DUSE_DEBUGGER
-#	CFLAGS += -g
-#endif
-
-# Uncomment the following line to enable the profiler
-#USE_PROFILER = 1
-# TODO: Need to reimplement this; and maybe replace it by the --enable-profiling
-#       configure directive. Below is USE_PROFILER related code from the old NDS
-#       build system:
-#ifdef USE_PROFILER
-#	CFLAGS += -mpoke-function-name -finstrument-functions -g
-#	DEFINES += -DUSE_PROFILER
-#endif
-# And this for module.mk:
-#ifdef USE_PROFILER
-#	PORT_OBJS += arm9/source/profiler/cyg-profile.o
-#endif
-
-
-
-# NOTE: The header and libs for the debugger is assumed to be in the libnds
-# folder.
-
-
-ifdef WRAP_MALLOC
-	LDFLAGS += -Wl,--wrap,malloc
-	DEFINES += -DWRAP_MALLOC
-endif
-
-
-
 # Compiler options for files which should be optimised for speed
 OPT_SPEED := -O3 -marm
 
@@ -128,13 +88,12 @@ engines/teenagent/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
 #
 #############################################################################
 
-# FIXME: Newer versions of devkitARM don't include dsbuild, which is needed to create scummvm.ds.gba
-all: scummvm.nds # scummvm.ds.gba
+all: scummvm.nds
 
 clean: dsclean
 
 dsclean:
-	$(RM) $(addprefix $(ndsdir)/, $(ARM7_MODULE_OBJS)) scummvm.nds scummvm.ds.gba
+	$(RM) $(addprefix $(ndsdir)/, $(ARM7_MODULE_OBJS)) scummvm.nds
 	$(RM_REC) romfs
 
 .PHONY: dsclean
@@ -144,10 +103,6 @@ dsclean:
 %.nds: %.elf $(ndsdir)/arm7/arm7.elf romfs
 	ndstool -c $@ -9 $< -7 $(ndsdir)/arm7/arm7.elf -b $(srcdir)/$(ndsdir)/logo.bmp "$(@F);ScummVM $(VERSION);DS Port" -d romfs
 
-%.ds.gba: %.nds
-	dsbuild $< -o $@ -l $(srcdir)/$(ndsdir)/arm9/ndsloader.bin
-	padbin 16 $@
-
 romfs: $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(PLUGINS)
 	@rm -rf romfs
 	@mkdir -p romfs
@@ -179,10 +134,6 @@ endif
 #
 #############################################################################
 
-# HACK/FIXME: C compiler, for cartreset.c -- we should switch this to use CXX
-# as soon as possible.
-CC := $(DEVKITPRO)/devkitARM/bin/arm-none-eabi-gcc
-
 #
 # Set various flags
 #
@@ -194,7 +145,6 @@ ARM7_CFLAGS	:=	-g -Wall -O2\
 		-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
 		-ffast-math \
 		$(ARM7_ARCH) \
-		-I$(srcdir)/$(ndsdir)/arm7/source/libcartreset \
 		-I$(srcdir)/$(ndsdir)/commoninclude \
 		-I$(DEVKITPRO)/libnds/include \
 		-I$(DEVKITPRO)/libnds/include/nds \
@@ -204,36 +154,16 @@ ARM7_CXXFLAGS	:= $(ARM7_CFLAGS) -fno-exceptions -fno-rtti
 
 ARM7_LDFLAGS	:= -g $(ARM7_ARCH) -mfloat-abi=soft
 
-# HACK/FIXME: Define a custom build rule for cartreset.c.
-# We do this because it is a .c file, not a .cpp file and so is outside our
-# regular build system anyway. But this is *bad*. It should be changed into a
-# .cpp file and this rule be removed.
-# Redefining -std there as we are using CXXFLAGS which specifies -ansi or -std=c++11
-# Using gnu90 as library code doesn't conform to standards
-%.o: %.c
-	$(MKDIR) $(*D)/$(DEPDIR)
-	$(CC) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -std=gnu90 -c $(<) -o $*.o
-
-# Set custom build flags for cartreset.o
-$(ndsdir)/arm7/source/libcartreset/cartreset.o: CXXFLAGS=$(ARM7_CFLAGS)
-$(ndsdir)/arm7/source/libcartreset/cartreset.o: CPPFLAGS=
-
 # Set custom build flags for main.o
 $(ndsdir)/arm7/source/main.o: CXXFLAGS=$(ARM7_CXXFLAGS)
 $(ndsdir)/arm7/source/main.o: CPPFLAGS=
 
 # Rule for creating ARM7 .elf files by linking .o files together with a special linker script
 $(ndsdir)/arm7/arm7.elf: \
-	$(ndsdir)/arm7/source/libcartreset/cartreset.o \
 	$(ndsdir)/arm7/source/main.o
 	+$(LD) $(ARM7_LDFLAGS) -specs=ds_arm7.specs $+ -L$(DEVKITPRO)/libnds/lib -lnds7  -o $@
 
 
-
-
-
-
-
 # Command to build libmad is:
 # ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork'
 #
diff --git a/backends/platform/ds/makefile b/backends/platform/ds/makefile
deleted file mode 100644
index e24a36ef81..0000000000
--- a/backends/platform/ds/makefile
+++ /dev/null
@@ -1,66 +0,0 @@
-#SUBDIRS:= `ls | egrep -v '^(CVS|tools)$$'`
-
-
-
-
-export PATH	:=	$(DEVKITPRO)/devkitARM/bin:$(PATH)
-
-export portdir = $(CURDIR)/arm9
-export srcdir = $(CURDIR)/../../..
-
-
-SUBDIRS := arm7 arm9
-
-all:
-	@for i in $(SUBDIRS); do if test -d $$i; then $(MAKE) -C $$i; fi; done;
-clean:
-	@for i in $(SUBDIRS); do if test -d $$i; then $(MAKE) -C $$i clean; fi; done;
-semiclean:
-	@for i in $(SUBDIRS); do if test -d $$i; then $(MAKE) -C $$i semiclean; fi; done;
-
-export:
-	@for i in $(SUBDIRS); do if test -d $$i; then $(MAKE) -C $$i export; fi; done;
-
-allbuilds:
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=a
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=b
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=c
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=d
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=e
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=f
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=g
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=h
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=i
-	$(MAKE) semiclean
-	$(MAKE) all       SCUMM_BUILD=k
-
-allbuildssafe:
-	$(MAKE) clean     SCUMM_BUILD=a
-	$(MAKE) all       SCUMM_BUILD=a
-	$(MAKE) clean     SCUMM_BUILD=b
-	$(MAKE) all       SCUMM_BUILD=b
-	$(MAKE) clean     SCUMM_BUILD=c
-	$(MAKE) all       SCUMM_BUILD=c
-	$(MAKE) clean     SCUMM_BUILD=d
-	$(MAKE) all       SCUMM_BUILD=d
-	$(MAKE) clean     SCUMM_BUILD=e
-	$(MAKE) all       SCUMM_BUILD=e
-	$(MAKE) clean     SCUMM_BUILD=f
-	$(MAKE) all       SCUMM_BUILD=f
-	$(MAKE) clean     SCUMM_BUILD=g
-	$(MAKE) all       SCUMM_BUILD=g
-	$(MAKE) clean     SCUMM_BUILD=h
-	$(MAKE) all       SCUMM_BUILD=h
-	$(MAKE) clean     SCUMM_BUILD=i
-	$(MAKE) all       SCUMM_BUILD=i
-	$(MAKE) clean     SCUMM_BUILD=k
-	$(MAKE) all       SCUMM_BUILD=k
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
index 901effd8dd..9190091372 100644
--- a/backends/platform/ds/module.mk
+++ b/backends/platform/ds/module.mk
@@ -1,8 +1,7 @@
 MODULE := backends/platform/ds
 
 ARM7_MODULE_OBJS := \
-	arm7/source/main.o \
-	arm7/source/libcartreset/cartreset.o \
+	arm7/source/main.o
 
 PORT_OBJS := \
 	arm9/source/blitters_arm.o \
@@ -75,8 +74,7 @@ $(MODULE)/arm9/source/touchkeyboard.o: \
 
 
 MODULE_DIRS += \
-	backends/platform/ds/arm7/source/ \
-	backends/platform/ds/arm7/source/libcartreset/ \
+	backends/platform/ds/arm7/source/
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))


Commit: aa3b16e88e40c70604d33d4ad41a0f61dae284c4
    https://github.com/scummvm/scummvm/commit/aa3b16e88e40c70604d33d4ad41a0f61dae284c4
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Remove old audio code

Changed paths:
  R backends/platform/ds/arm7/source/main.cpp
  R backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
    .gitignore
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsmain.h
    backends/platform/ds/arm9/source/dsoptions.cpp
    backends/platform/ds/arm9/source/dsoptions.h
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/osystem_ds.h
    backends/platform/ds/ds.mk
    backends/platform/ds/module.mk


diff --git a/.gitignore b/.gitignore
index c2a43cce2a..761df9293b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,12 +69,7 @@ lib*.a
 /backends/platform/dc/SCUMMVM.BIN
 /backends/platform/dc/*.PLG
 
-/backends/platform/ds/arm7/arm7.bin
-/backends/platform/ds/arm7/build
-/backends/platform/ds/arm7/source/libcartreset/*.bak
-/backends/platform/ds/arm7/source/libcartreset/*.d
 /backends/platform/ds/arm9/data/*.h
-/backends/platform/ds/arm9/scummvm-?
 
 /backends/platform/maemo/scummvm
 
diff --git a/backends/platform/ds/arm7/source/main.cpp b/backends/platform/ds/arm7/source/main.cpp
deleted file mode 100644
index 355f0b09df..0000000000
--- a/backends/platform/ds/arm7/source/main.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-//////////////////////////////////////////////////////////////////////
-// Simple ARM7 stub (sends RTC, TSC, and X/Y data to the ARM 9)
-// -- joat
-// -- modified by Darkain and others
-//////////////////////////////////////////////////////////////////////
-
-#include <nds.h>
-
-#include <bios.h>
-#include <arm7/touch.h>
-#include <arm7/clock.h>
-#include <arm7/audio.h>
-#include <system.h>
-#include <stdlib.h>
-#include <string.h>
-#include <registers_alt.h> // Needed for SOUND_CR
-#include <NDS/scummvm_ipc.h>
-//////////////////////////////////////////////////////////////////////
-#ifdef USE_DEBUGGER
-#include <dswifi7.h>
-#endif
-
-vu8 *soundData;
-
-vu8 *soundBuffer;
-vu8 *arm9Buffer;
-bool soundFilled[4];
-
-int playingSection;
-
-int temp;
-
-int adpcmBufferNum = 0;
-
-s8 getFreeSoundChannel() {
-	for (int i = 0; i < 16; i++) {
-		if ( (SCHANNEL_CR(i) & SCHANNEL_ENABLE) == 0 )
-			return i;
-	}
-	return -1;
-}
-
-void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0, u8 vol = 0x7F, u8 pan = 63, u8 format = 0) {
-	channel = getFreeSoundChannel();
-
-	if (channel > 1)
-		channel = 1;
-
-	bytes &= ~7; // Multiple of 4 bytes!
-
-	SCHANNEL_CR(channel) = 0;
-	SCHANNEL_TIMER(channel)  = SOUND_FREQ(sampleRate);
-	SCHANNEL_SOURCE(channel) = (uint32)data;
-	SCHANNEL_LENGTH(channel) = (bytes & 0x7FFFFFFF) >> 2;
-	SCHANNEL_REPEAT_POINT(channel) = 0;
-
-	SCHANNEL_CR(channel + 2) = 0;
-	SCHANNEL_TIMER(channel + 2)  = SOUND_FREQ(sampleRate);
-	SCHANNEL_SOURCE(channel + 2) = (uint32)data;
-	SCHANNEL_LENGTH(channel + 2) = (bytes & 0x7FFFFFFF) >> 2;
-	SCHANNEL_REPEAT_POINT(channel + 2) = 0;
-
-	uint32 flags = SCHANNEL_ENABLE | SOUND_VOL(vol) | SOUND_PAN(pan);
-
-	switch (format) {
-	case 1: {
-		flags |= SOUND_FORMAT_8BIT;
-		flags |= SOUND_REPEAT;
-		break;
-	}
-
-	case 0: {
-		flags |= SOUND_FORMAT_16BIT;
-		flags |= SOUND_REPEAT;
-		break;
-	}
-
-	case 2: {
-		flags |= SOUND_FORMAT_ADPCM;
-		flags |= SOUND_ONE_SHOT;
-
-		SCHANNEL_SOURCE(channel) = (unsigned int)IPC->adpcm.buffer[0];
-		SCHANNEL_LENGTH(channel) = ((bytes + 4) & 0x7FFFFFFF) >> 2;
-
-		SCHANNEL_CR(channel + 1) = 0;
-		SCHANNEL_SOURCE(channel + 1) = (unsigned int)IPC->adpcm.buffer[0];
-		SCHANNEL_LENGTH(channel + 1) = ((bytes + 4) & 0x7FFFFFFF) >> 2;
-		SCHANNEL_TIMER(channel + 1)  = SOUND_FREQ(sampleRate);
-		SCHANNEL_REPEAT_POINT(channel + 1) = 0;
-		SCHANNEL_CR(channel + 1) = flags;
-		temp = bytes;
-		adpcmBufferNum = 0;
-		break;
-	}
-	}
-
-	soundData = (vu8 *)data;
-
-	SCHANNEL_CR(channel)     = flags;
-	SCHANNEL_CR(channel + 2) = flags;
-
-	if (channel == 0) {
-		for (volatile int i = 0; i < 16384 * 2; i++) {
-			// Delay loop - this makes everything stay in sync!
-		}
-
-		TIMER0_CR = 0;
-		TIMER0_DATA = SOUND_FREQ(sampleRate) * 2;
-		TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1;
-
-		TIMER1_CR = 0;
-		TIMER1_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
-		TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
-
-		playingSection = 0;
-	} else {
-		for (volatile int i = 0; i < 16384 * 2; i++) {
-			// Delay loop - this makes everything stay in sync!
-		}
-
-		TIMER2_CR = 0;
-		TIMER2_DATA = SOUND_FREQ(sampleRate) * 2;
-		TIMER2_CR = TIMER_ENABLE | TIMER_DIV_1;
-
-		TIMER3_CR = 0;
-		TIMER3_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
-		TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
-
-		IPC->streamPlayingSection = 0;
-	}
-}
-
-void stopSound(int chan) {
-	SCHANNEL_CR(chan) = 0;
-}
-
-void InterruptTimer1() {
-	IPC->fillNeeded[playingSection] = true;
-	soundFilled[playingSection] = false;
-
-	if (playingSection == 3) {
-		playingSection = 0;
-	} else {
-		playingSection++;
-	}
-
-	IPC->playingSection = playingSection;
-}
-
-void InterruptTimer3() {
-	while (IPC->adpcm.semaphore); // Wait for buffer to become free if needed
-	IPC->adpcm.semaphore = true; // Lock the buffer structure to prevent clashing with the ARM7
-
-	IPC->streamFillNeeded[IPC->streamPlayingSection] = true;
-
-	if (IPC->streamPlayingSection == 3) {
-		IPC->streamPlayingSection = 0;
-	} else {
-		IPC->streamPlayingSection++;
-	}
-
-	IPC->adpcm.semaphore = false;
-}
-
-void VblankHandler() {
-	// sound code  :)
-	TransferSound *snd = IPC->soundData;
-	IPC->soundData = 0;
-	if (snd) {
-		for (int i = 0; i < snd->count; i++) {
-			s8 chan = getFreeSoundChannel();
-			if (snd->data[i].rate > 0) {
-				if (chan >= 0) {
-					startSound(snd->data[i].rate, snd->data[i].data, snd->data[i].len, chan, snd->data[i].vol, snd->data[i].pan, snd->data[i].format);
-				}
-			} else {
-				stopSound(-snd->data[i].rate);
-			}
-		}
-	}
-}
-
-//---------------------------------------------------------------------------------
-void VcountHandler() {
-//---------------------------------------------------------------------------------
-	inputGetAndSend();
-}
-
-volatile bool exitflag = false;
-
-//---------------------------------------------------------------------------------
-void powerButtonCB() {
-//---------------------------------------------------------------------------------
-	exitflag = true;
-}
-
-int main(int argc, char ** argv) {
-	// enable sound
-	SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
-	IPC->soundData = 0;
-
-	for (int r = 0; r < 8; r++) {
-		IPC->adpcm.arm7Buffer[r] = (u8 *)malloc(512);
-	}
-
-	for (int r = 0; r < 4; r++) {
-		soundFilled[r] = false;
-	}
-
-	readUserSettings();
-	ledBlink(0);
-
-	irqInit();
-	// Start the RTC tracking IRQ
-	initClockIRQ();
-	fifoInit();
-	touchInit();
-
-//	mmInstall(FIFO_MAXMOD);
-
-	SetYtrigger(80);
-
-//	installWifiFIFO();
-//	installSoundFIFO();
-
-	installSystemFIFO();
-
-	irqSet(IRQ_VCOUNT, VcountHandler);
-	irqSet(IRQ_VBLANK, VblankHandler);
-
-	irqEnable(IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK);
-
-	irqSet(IRQ_TIMER1, InterruptTimer1);
-	irqEnable(IRQ_TIMER1);
-
-	irqSet(IRQ_TIMER3, InterruptTimer3);
-	irqEnable(IRQ_TIMER3);
-
-	setPowerButtonCB(powerButtonCB);
-
-	// Keep the ARM7 mostly idle
-	while (!exitflag) {
-		if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) {
-			exitflag = true;
-		}
-
-		swiWaitForVBlank();
-	}
-
-	return 0;
-}
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 25d31c1889..dc20c332c4 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -80,7 +80,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "NDS/scummvm_ipc.h"
 #include "dsmain.h"
 #include "osystem_ds.h"
 #include "icons_raw.h"
@@ -144,26 +143,11 @@ static int subScreenHeight = SCUMM_GAME_HEIGHT;
 static int subScreenScale = 256;
 
 
-
-// Sound
-static int bufferSize;
-static s16 *soundBuffer;
-static int bufferFrame;
-static int bufferRate;
-static int bufferSamples;
-static bool soundHiPart;
-static int soundFrequency;
-
 // Events
 static int lastEventFrame;
 static bool indyFightState;
 static bool indyFightRight;
 
-static OSystem_DS::SoundProc soundCallback;
-static int lastCallbackFrame;
-static bool bufferFirstHalf;
-static bool bufferSecondHalf;
-
 // Saved buffers
 static bool highBuffer;
 static bool displayModeIs8Bit = false;
@@ -185,7 +169,6 @@ static int storedMouseY = 0;
 // Sprites
 static SpriteEntry sprites[128];
 static SpriteEntry spritesMain[128];
-static int tweak;
 
 // Shake
 static int s_shakeXOffset = 0;
@@ -295,8 +278,6 @@ void setIcon(int num, int x, int y, int imageNum, int flags, bool enable);
 void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable);
 void uploadSpriteGfx();
 
-static TransferSound soundControl;
-
 static bool isScrollingWithDPad() {
 	return (getKeysHeld() & (KEY_L | KEY_R)) != 0;
 }
@@ -339,31 +320,6 @@ controlType getControlType() {
 	return s_currentGame->control;
 }
 
-
-//plays an 8 bit mono sample at 11025Hz
-void playSound(const void *data, u32 length, bool loop, bool adpcm, int rate) {
-
-	if (!IPC->soundData) {
-		soundControl.count = 0;
-	}
-
-	soundControl.data[soundControl.count].data   = data;
-	soundControl.data[soundControl.count].len    = length | (loop ? 0x80000000 : 0x00000000);
-	soundControl.data[soundControl.count].rate   = rate; // 367 samples per frame
-	soundControl.data[soundControl.count].pan    = 64;
-	soundControl.data[soundControl.count].vol    = 127;
-	soundControl.data[soundControl.count].format = adpcm ? 2 : 0;
-
-	soundControl.count++;
-
-	DC_FlushAll();
-	IPC->soundData = &soundControl;
-}
-
-void stopSound(int channel) {
-	playSound(NULL, 0, false, false, -channel);
-}
-
 void updateOAM() {
 	DC_FlushAll();
 
@@ -419,44 +375,6 @@ void saveGameBackBuffer() {
 	OSystem_DS::instance()->unlockScreen();
 }
 
-
-
-void startSound(int freq, int buffer) {
-	bufferRate = freq * 2;
-	bufferFrame = 0;
-	bufferSamples = 4096;
-
-	bufferFirstHalf = false;
-	bufferSecondHalf = true;
-
-	int bytes = (2 * (bufferSamples)) + 100;
-
-	soundBuffer = (s16 *) malloc(bytes * 2);
-	if (!soundBuffer)
-		consolePrintf("Sound buffer alloc failed\n");
-
-
-	soundHiPart = true;
-
-	for (int r = 0; r < bytes; r++) {
-		soundBuffer[r] = 0;
-	}
-
-	soundFrequency = freq;
-
-
-	swiWaitForVBlank();
-	swiWaitForVBlank();
-	playSound(soundBuffer, (bufferSamples * 2), true, false, freq * 2);
-	swiWaitForVBlank();
-	swiWaitForVBlank();
-	swiWaitForVBlank();
-}
-
-int getSoundFrequency() {
-	return soundFrequency;
-}
-
 void exitGame() {
 	s_currentGame = NULL;
 }
@@ -889,38 +807,6 @@ u16 *get8BitBackBuffer() {
 		return BG_GFX + 0x10000;		// 16bit qty!
 }
 
-// The sound system in ScummVM seems to always return stereo interleaved samples.
-// Here, I'm treating an 11Khz stereo stream as a 22Khz mono stream, which works sorta ok, but is
-// a horrible bodge.  Any advice on how to change the engine to output mono would be greatly
-// appreciated.
-void doSoundCallback() {
-	#ifdef HEAVY_LOGGING
-	consolePrintf("doSoundCallback...");
-	#endif
-
-	if (OSystem_DS::instance())
-	if (OSystem_DS::instance()->getMixerImpl()) {
-		lastCallbackFrame = frameCount;
-
-		for (int r = IPC->playingSection; r < IPC->playingSection + 4; r++) {
-			int chunk = r & 3;
-
-			if (IPC->fillNeeded[chunk]) {
-				IPC->fillNeeded[chunk] = false;
-				DC_FlushAll();
-				OSystem_DS::instance()->getMixerImpl()->mixCallback((byte *) (soundBuffer + ((bufferSamples >> 2) * chunk)), bufferSamples >> 1);
-				IPC->fillNeeded[chunk] = false;
-				DC_FlushAll();
-			}
-
-		}
-
-	}
-	#ifdef HEAVY_LOGGING
-	consolePrintf("done\n");
-	#endif
-}
-
 void doTimerCallback() {
 	if (callback) {
 		if (callbackTimer <= 0) {
@@ -930,13 +816,6 @@ void doTimerCallback() {
 	}
 }
 
-void soundUpdate() {
-	bufferFrame++;
-	if (bufferFrame == bufferSize) {
-		bufferFrame = 0;
-	}
-}
-
 void memoryReport() {
 	int r = 0;
 	int *p;
@@ -1649,19 +1528,6 @@ void updateStatus() {
 
 }
 
-void soundBufferEmptyHandler() {
-	REG_IF = IRQ_TIMER2;
-
-// TIMER0
-	if ((callback) && (callbackTimer > 0)) {
-		callbackTimer--;
-	}
-	currentTimeMillis++;
-// TIMER0 end
-
-	soundHiPart = !soundHiPart;
-}
-
 void setMainScreenScroll(int x, int y) {
 		BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
 		BG3_CY = y;
@@ -1715,9 +1581,6 @@ void setZoomedScreenScale(int x, int y) {
 }
 
 void VBlankHandler(void) {
-	soundUpdate();
-
-
 	if ((!gameScreenSwap) && !isScrollingWithDPad()) {
 		if (s_currentGame) {
 			if (s_currentGame->control != CONT_SCUMM_SAMNMAX) {
@@ -2051,7 +1914,6 @@ void initHardware() {
 	//irqs are nice
 	irqSet(IRQ_VBLANK, VBlankHandler);
 	irqSet(IRQ_TIMER0, timerTickHandler);
-	irqSet(IRQ_TIMER2, soundBufferEmptyHandler);
 
 	irqEnable(IRQ_VBLANK);
 	irqEnable(IRQ_TIMER0);
@@ -2490,8 +2352,6 @@ void dsExceptionHandler() {
 
 int main(void) {
 
-	soundCallback = NULL;
-
 	initHardware();
 
 	setExceptionHandler(dsExceptionHandler);
@@ -2499,9 +2359,6 @@ int main(void) {
 	// Let arm9 read cartridge
 	*((u16 *) (0x04000204)) &= ~0x0080;
 
-	lastCallbackFrame = 0;
-	tweak = 0;
-
 	indyFightState = false;
 	indyFightRight = true;
 
@@ -2578,8 +2435,6 @@ int main(void) {
 	g_system = new OSystem_DS();
 	assert(g_system);
 
-	IPC->adpcm.semaphore = false;
-
 #if defined(DS_BUILD_A)
 	const char *argv[] = {"/scummvmds"};
 #elif defined(DS_BUILD_B)
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index f562e42280..9c8e1e664b 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -93,14 +93,6 @@ void 	setTimerCallback(OSystem_DS::TimerProc proc, int interval);		// Setup a ca
 int 	getMillis(bool skipRecord = false);								// Return the current runtime in milliseconds
 void 	doTimerCallback();												// Call callback function if required
 
-// Sound
-void 	doSoundCallback();
-void 	startSound(int freq, int buffer);	// Start sound hardware
-// Call function if sound buffers need more data
-void 	playSound(const void *data, u32 length, bool loop, bool adpcm = false, int rate = 22050);		// Start a sound
-void 	stopSound(int channel);
-int		getSoundFrequency();
-
 // Event queue
 void 	addEventsToQueue();
 void 	VBlankHandler();
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp
index cd76d22dd5..59ec2334f7 100644
--- a/backends/platform/ds/arm9/source/dsoptions.cpp
+++ b/backends/platform/ds/arm9/source/dsoptions.cpp
@@ -118,7 +118,6 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 
 	_tab->addTab(_("General"), "");
 
-	_highQualityAudioCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 250, 20, _("High quality audio (slower) (reboot)"), U32String(), 0, 'T');
 	_disablePowerOff = new GUI::CheckboxWidget(_tab, 5, 20, 200, 20, _("Disable power off"), U32String(), 0, 'T');
 
 	_tab->setActiveTab(0);
@@ -172,7 +171,6 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 		_gammaCorrection->setValue(0);
 	}
 
-	_highQualityAudioCheckbox->setState(confGetBool("22khzaudio", false));
 	_disablePowerOff->setState(confGetBool("disablepoweroff", false));
 
     #ifdef ALLOW_CPU_SCALER
@@ -208,7 +206,6 @@ DSOptionsDialog::~DSOptionsDialog() {
 void DSOptionsDialog::updateConfigManager() {
 	ConfMan.setBool("lefthanded", _leftHandedCheckbox->getState(), "ds");
 	ConfMan.setBool("unscaled", _unscaledCheckbox->getState(), "ds");
-	ConfMan.setBool("22khzaudio", _highQualityAudioCheckbox->getState(), "ds");
 	ConfMan.setBool("disablepoweroff", _disablePowerOff->getState(), "ds");
 #ifdef ALLOW_CPU_SCALER
 	ConfMan.setBool("cpu_scaler", _cpuScaler->getState(), "ds");
diff --git a/backends/platform/ds/arm9/source/dsoptions.h b/backends/platform/ds/arm9/source/dsoptions.h
index 2ba07dd7c0..0bc61adda0 100644
--- a/backends/platform/ds/arm9/source/dsoptions.h
+++ b/backends/platform/ds/arm9/source/dsoptions.h
@@ -63,7 +63,6 @@ protected:
 	GUI::CheckboxWidget *_150PercentCheckbox;
 	GUI::CheckboxWidget *_200PercentCheckbox;
 	GUI::CheckboxWidget *_indyFightCheckbox;
-	GUI::CheckboxWidget *_highQualityAudioCheckbox;
 	GUI::CheckboxWidget *_disablePowerOff;
 	GUI::CheckboxWidget *_showCursorCheckbox;
 	GUI::CheckboxWidget *_snapToBorderCheckbox;
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 2240456a54..c9303c1cdb 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -111,13 +111,7 @@ void OSystem_DS::initBackend() {
 	_timerManager = new DefaultTimerManager();
     DS::setTimerCallback(&OSystem_DS::timerHandler, 10);
 
-	if (ConfMan.hasKey("22khzaudio", "ds") && ConfMan.getBool("22khzaudio", "ds")) {
-		DS::startSound(22050, 8192);
-	} else {
-		DS::startSound(11025, 4096);
-	}
-
-	_mixer = new Audio::MixerImpl(DS::getSoundFrequency());
+	_mixer = new Audio::MixerImpl(11025);
 	_mixer->setReady(true);
 
 	EventsBaseBackend::initBackend();
@@ -428,7 +422,6 @@ void OSystem_DS::updateScreen() {
 	}
 
 	DS::displayMode16BitFlipBuffer();
-	DS::doSoundCallback();
 	DS::addEventsToQueue();
 
 	// FIXME: Evil game specific hack.
@@ -558,10 +551,7 @@ void OSystem_DS::delayMillis(uint msecs) {
 	int st = getMillis();
 	DS::addEventsToQueue();
 
-	DS::doSoundCallback();
-	while (st + msecs >= getMillis()) {
-		DS::doSoundCallback();
-	}
+	while (st + msecs >= getMillis());
 
 	DS::doTimerCallback();
 	DS::addEventsToQueue();
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index 50f7d1f4df..6c438f917b 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -69,7 +69,6 @@ protected:
 	int _gammaValue;
 
 public:
-	typedef void (*SoundProc)(byte *buf, int len);
 	typedef int  (*TimerProc)(int interval);
 
 	OSystem_DS();
@@ -137,7 +136,6 @@ public:
 	virtual void unlockScreen();
 
 	virtual Audio::Mixer *getMixer() { return _mixer; }
-	Audio::MixerImpl *getMixerImpl() { return _mixer; }
 
 	static int timerHandler(int t);
 
diff --git a/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h b/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
deleted file mode 100644
index 6a75872da0..0000000000
--- a/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef SCUMMVM_IPC_INCLUDE
-#define SCUMMVM_IPC_INCLUDE
-
-//////////////////////////////////////////////////////////////////////
-
-#include <nds/ndstypes.h>
-#include <nds/ipc.h>
-
-//////////////////////////////////////////////////////////////////////
-
-
-typedef struct {
-	const void *data;
-	u32 len;
-	u32 rate;
-	u8 vol;
-	u8 pan;
-	u8 format;
-	u8 PADDING;
-} TransferSoundData;
-
-
-
-
-//---------------------------------------------------------------------------------
-typedef struct {
-	TransferSoundData data[16];
-	u8 count;
-	u8 PADDING[3];
-} TransferSound;
-
-
-
-typedef struct {
-	u8 *buffer[8];
-	bool filled[8];
-	u8 *arm7Buffer[8];
-	bool arm7Dirty[8];
-	bool semaphore;
-} adpcmBuffer;
-
-//////////////////////////////////////////////////////////////////////
-
-typedef struct scummvmTransferRegion {
-  TransferSound *soundData;
-
-  adpcmBuffer adpcm;
-
-  // These are used for ScummVMs sound output
-  bool fillNeeded[4];
-  int playingSection;
-
-  // Streaming sound
-  bool streamFillNeeded[4];
-  int streamPlayingSection;
-} scummTransferRegion;
-
-//////////////////////////////////////////////////////////////////////
-
-#undef IPC
-#define IPC ((scummTransferRegion volatile *)(0x027FF000))
-
-
-#endif
diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk
index 2b1b38cded..0fe97e39ab 100644
--- a/backends/platform/ds/ds.mk
+++ b/backends/platform/ds/ds.mk
@@ -93,15 +93,15 @@ all: scummvm.nds
 clean: dsclean
 
 dsclean:
-	$(RM) $(addprefix $(ndsdir)/, $(ARM7_MODULE_OBJS)) scummvm.nds
+	$(RM) scummvm.nds
 	$(RM_REC) romfs
 
 .PHONY: dsclean
 
 # TODO: Add a 'dsdist' target ?
 
-%.nds: %.elf $(ndsdir)/arm7/arm7.elf romfs
-	ndstool -c $@ -9 $< -7 $(ndsdir)/arm7/arm7.elf -b $(srcdir)/$(ndsdir)/logo.bmp "$(@F);ScummVM $(VERSION);DS Port" -d romfs
+%.nds: %.elf romfs
+	ndstool -c $@ -9 $< -b $(srcdir)/$(ndsdir)/logo.bmp "$(@F);ScummVM $(VERSION);DS Port" -d romfs
 
 romfs: $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(PLUGINS)
 	@rm -rf romfs
@@ -121,48 +121,6 @@ ifeq ($(DYNAMIC_MODULES),1)
 	@for i in $(PLUGINS); do $(STRIP) --strip-debug $$i -o romfs/plugins/`basename $$i`; done
 endif
 
-#############################################################################
-#############################################################################
-#############################################################################
-
-
-#############################################################################
-#
-# ARM7 rules.
-# For ARM7 files, we need different compiler flags, which leads to the
-# extra rules for .o files below
-#
-#############################################################################
-
-#
-# Set various flags
-#
-ARM7_ARCH	:=	-mthumb-interwork
-
-# note: arm7tdmi isn't the correct CPU arch, but anything newer and LD
-# *insists* it has a FPU or VFP, and it won't take no for an answer!
-ARM7_CFLAGS	:=	-g -Wall -O2\
-		-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
-		-ffast-math \
-		$(ARM7_ARCH) \
-		-I$(srcdir)/$(ndsdir)/commoninclude \
-		-I$(DEVKITPRO)/libnds/include \
-		-I$(DEVKITPRO)/libnds/include/nds \
-		-DARM7
-
-ARM7_CXXFLAGS	:= $(ARM7_CFLAGS) -fno-exceptions -fno-rtti
-
-ARM7_LDFLAGS	:= -g $(ARM7_ARCH) -mfloat-abi=soft
-
-# Set custom build flags for main.o
-$(ndsdir)/arm7/source/main.o: CXXFLAGS=$(ARM7_CXXFLAGS)
-$(ndsdir)/arm7/source/main.o: CPPFLAGS=
-
-# Rule for creating ARM7 .elf files by linking .o files together with a special linker script
-$(ndsdir)/arm7/arm7.elf: \
-	$(ndsdir)/arm7/source/main.o
-	+$(LD) $(ARM7_LDFLAGS) -specs=ds_arm7.specs $+ -L$(DEVKITPRO)/libnds/lib -lnds7  -o $@
-
 
 # Command to build libmad is:
 # ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork'
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
index 9190091372..9636173542 100644
--- a/backends/platform/ds/module.mk
+++ b/backends/platform/ds/module.mk
@@ -1,8 +1,5 @@
 MODULE := backends/platform/ds
 
-ARM7_MODULE_OBJS := \
-	arm7/source/main.o
-
 PORT_OBJS := \
 	arm9/source/blitters_arm.o \
 	arm9/source/dsmain.o \
@@ -73,9 +70,6 @@ $(MODULE)/arm9/source/touchkeyboard.o: \
 	$(MODULE)/arm9/data/8x8font_tga_raw.h
 
 
-MODULE_DIRS += \
-	backends/platform/ds/arm7/source/
-
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
 OBJS := $(MODULE_OBJS) $(OBJS)


Commit: bf63cd76ea512228656030f4d7bda4ec28443b0c
    https://github.com/scummvm/scummvm/commit/bf63cd76ea512228656030f4d7bda4ec28443b0c
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Get rid of consolePrintf

Changed paths:
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsoptions.cpp
    backends/platform/ds/arm9/source/portdefs.h
    backends/platform/ds/arm9/source/touchkeyboard.cpp


diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index dc20c332c4..96d97a5b5c 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -383,7 +383,7 @@ void initGame() {
 	// This is a good time to check for left handed mode since the mode change is done as the game starts.
 	// There's probably a better way, but hey.
 	#ifdef HEAVY_LOGGING
-	consolePrintf("initing game...");
+	printf("initing game...");
 	#endif
 
 	setOptions();
@@ -402,7 +402,7 @@ void initGame() {
 	}
 
 	#ifdef HEAVY_LOGGING
-	consolePrintf("done\n");
+	printf("done\n");
 	#endif
 
 }
@@ -434,7 +434,7 @@ void setUnscaledMode(bool enable) {
 void displayMode8Bit() {
 
 #ifdef HEAVY_LOGGING
-	consolePrintf("displayMode8Bit...");
+	printf("displayMode8Bit...");
 #endif
 	u16 buffer[32 * 32];
 
@@ -508,7 +508,7 @@ void displayMode8Bit() {
 	videoSetMode(MODE_5_2D | (consoleEnable ? DISPLAY_BG0_ACTIVE : 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
 
 	// Move the cursor to the bottom of the screen using ANSI escape code
-	consolePrintf("\033[23;0f");
+	printf("\033[23;0f");
 
 
 	for (int r = 0; r < 32 * 32; r++) {
@@ -521,7 +521,7 @@ void displayMode8Bit() {
 	}
 
 	#ifdef HEAVY_LOGGING
-	consolePrintf("done\n");
+	printf("done\n");
 	#endif
 
 	if (gameScreenSwap) {
@@ -649,7 +649,7 @@ void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX,
 
 void displayMode16Bit() {
 	#ifdef HEAVY_LOGGING
-	consolePrintf("displayMode16Bit...");
+	printf("displayMode16Bit...");
 	#endif
 
 	u16 buffer[32 * 32 * 2];
@@ -716,7 +716,7 @@ void displayMode16Bit() {
 	BG3_YDY = (int) ((200.0f / 192.0f) * 256);
 
 	#ifdef HEAVY_LOGGING
-	consolePrintf("done\n");
+	printf("done\n");
 	#endif
 
 	BG_PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
@@ -726,7 +726,7 @@ void displayMode16Bit() {
 
 void displayMode16BitFlipBuffer() {
 	#ifdef HEAVY_LOGGING
-	consolePrintf("Flip %s...", displayModeIs8Bit ? "8bpp" : "16bpp");
+	printf("Flip %s...", displayModeIs8Bit ? "8bpp" : "16bpp");
 	#endif
 	if (!displayModeIs8Bit) {
 		u16 *back = get16BitBackBuffer();
@@ -770,7 +770,7 @@ void displayMode16BitFlipBuffer() {
 		#endif
 	}
 	#ifdef HEAVY_LOGGING
-	consolePrintf("done\n");
+	printf("done\n");
 	#endif
 }
 
@@ -836,7 +836,7 @@ void memoryReport() {
 		free(block[q]);
 	}
 
-	consolePrintf("Free: %dK, Largest: %dK\n", t * 4, r * 8);
+	printf("Free: %dK, Largest: %dK\n", t * 4, r * 8);
 }
 
 
@@ -1186,7 +1186,7 @@ void doButtonSelectMode(OSystem_DS *system) {
 
 void addEventsToQueue() {
 	#ifdef HEAVY_LOGGING
-	consolePrintf("addEventsToQueue\n");
+	printf("addEventsToQueue\n");
 	#endif
 	OSystem_DS *system = OSystem_DS::instance();
 	Common::Event event;
@@ -1225,7 +1225,7 @@ void addEventsToQueue() {
 
 			if ((!getIndyFightState()) && (getKeysDown() & KEY_Y)) {
 				consoleEnable = !consoleEnable;
-				consolePrintf("Console enable: %d\n", consoleEnable);
+				printf("Console enable: %d\n", consoleEnable);
 				if (displayModeIs8Bit) {
 					displayMode8Bit();
 				} else {
@@ -1347,7 +1347,7 @@ void addEventsToQueue() {
 				if (s_currentGame->control == CONT_AGI) {
 					// Extra controls for Leisure Suit Larry and KQ4
 					if ((getKeysHeld() & KEY_UP) && (getKeysHeld() & KEY_START)) {
-						consolePrintf("Cheat key!\n");
+						printf("Cheat key!\n");
 						event.type = Common::EVENT_KEYDOWN;
 						event.kbd.keycode = (Common::KeyCode)'X';		// Skip age test in LSL
 						event.kbd.ascii = 'X';
@@ -1920,14 +1920,14 @@ void initHardware() {
 
 	// Set up a millisecond timer
 	#ifdef HEAVY_LOGGING
-	consolePrintf("Setting up timer...");
+	printf("Setting up timer...");
 	#endif
 	TIMER0_CR = 0;
 	TIMER0_DATA = (u32) TIMER_FREQ(1000);
 	TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1 | TIMER_IRQ_REQ;
 	REG_IME = 1;
 	#ifdef HEAVY_LOGGING
-	consolePrintf("done\n");
+	printf("done\n");
 	#endif
 
 	BG_PALETTE[255] = RGB15(0,0,31);
@@ -2275,7 +2275,7 @@ void *fastRamAlloc(int size) {
 	void *result = (void *) fastRamPointer;
 	fastRamPointer += size;
 	if(fastRamPointer > fastRamData + FAST_RAM_SIZE) {
-		consolePrintf("FastRam (ITCM) allocation failed!\n");
+		printf("FastRam (ITCM) allocation failed!\n");
 		return malloc(size);
 	}
 	return result;
@@ -2293,7 +2293,7 @@ void fastRamReset() {
 
 
 void dsExceptionHandler() {
-	consolePrintf("Blue screen of death");
+	printf("Blue screen of death");
 	setExceptionHandler(NULL);
 
 	u32	currentMode = getCPSR() & 0x1f;
@@ -2304,7 +2304,7 @@ void dsExceptionHandler() {
 	int offset = 8;
 
 	if (currentMode == 0x17) {
-		consolePrintf("\x1b[10Cdata abort!\n\n");
+		printf("\x1b[10Cdata abort!\n\n");
 		codeAddress = exceptionRegisters[15] - offset;
 		if (	(codeAddress > 0x02000000 && codeAddress < 0x02400000) ||
 				(codeAddress > (u32)__itcm_start && codeAddress < (u32)(__itcm_start + 32768)) )
@@ -2317,17 +2317,17 @@ void dsExceptionHandler() {
 			offset = 2;
 		else
 			offset = 4;
-		consolePrintf("\x1b[5Cundefined instruction!\n\n");
+		printf("\x1b[5Cundefined instruction!\n\n");
 		codeAddress = exceptionRegisters[15] - offset;
 		exceptionAddress = codeAddress;
 	}
 
-	consolePrintf("  pc: %08X addr: %08X\n\n",codeAddress,exceptionAddress);
+	printf("  pc: %08X addr: %08X\n\n",codeAddress,exceptionAddress);
 
 
 	int i;
 	for (i = 0; i < 8; i++) {
-		consolePrintf("  %s: %08X   %s: %08X\n",
+		printf("  %s: %08X   %s: %08X\n",
 					registerNames[i], exceptionRegisters[i],
 					registerNames[i+8],exceptionRegisters[i+8]);
 	}
@@ -2339,7 +2339,7 @@ void dsExceptionHandler() {
 
 
 	for (i = 0; i < 10; i++) {
-		consolePrintf("%08X %08X %08X\n", stack[i*3], stack[i*3+1], stack[(i*3)+2] );
+		printf("%08X %08X %08X\n", stack[i*3], stack[i*3+1], stack[(i*3)+2] );
 	}
 
 	memoryReport();
@@ -2367,65 +2367,65 @@ int main(void) {
 	mouseMode = MOUSE_LEFT;
 
 	//2372
-	consolePrintf("-------------------------------\n");
-	consolePrintf("ScummVM DS\n");
-	consolePrintf("Ported by Neil Millstone\n");
-	consolePrintf("Version %s ", gScummVMVersion);
+	printf("-------------------------------\n");
+	printf("ScummVM DS\n");
+	printf("Ported by Neil Millstone\n");
+	printf("Version %s ", gScummVMVersion);
 #if defined(DS_BUILD_A)
-	consolePrintf("build A\n");
-	consolePrintf("Lucasarts SCUMM games (SCUMM)\n");
+	printf("build A\n");
+	printf("Lucasarts SCUMM games (SCUMM)\n");
 #elif defined(DS_BUILD_B)
-	consolePrintf("build B\n");
-	consolePrintf("BASS, QUEEN\n");
+	printf("build B\n");
+	printf("BASS, QUEEN\n");
 #elif defined(DS_BUILD_C)
-	consolePrintf("build C\n");
-	consolePrintf("Simon/Elvira/Waxworks (AGOS)\n");
+	printf("build C\n");
+	printf("Simon/Elvira/Waxworks (AGOS)\n");
 #elif defined(DS_BUILD_D)
-	consolePrintf("build D\n");
-	consolePrintf("AGI, CINE, GOB\n");
+	printf("build D\n");
+	printf("AGI, CINE, GOB\n");
 #elif defined(DS_BUILD_E)
-	consolePrintf("build E\n");
-	consolePrintf("Inherit the Earth (SAGA)\n");
+	printf("build E\n");
+	printf("Inherit the Earth (SAGA)\n");
 #elif defined(DS_BUILD_F)
-	consolePrintf("build F\n");
-	consolePrintf("The Legend of Kyrandia (KYRA)\n");
+	printf("build F\n");
+	printf("The Legend of Kyrandia (KYRA)\n");
 #elif defined(DS_BUILD_G)
-	consolePrintf("build G\n");
-	consolePrintf("Lure of the Tempress (LURE)\n");
+	printf("build G\n");
+	printf("Lure of the Tempress (LURE)\n");
 #elif defined(DS_BUILD_H)
-	consolePrintf("build H\n");
-	consolePrintf("Nippon Safes (PARALLATION)\n");
+	printf("build H\n");
+	printf("Nippon Safes (PARALLATION)\n");
 #elif defined(DS_BUILD_I)
-	consolePrintf("build I\n");
-	consolePrintf("Activision Games (MADE)\n");
+	printf("build I\n");
+	printf("Activision Games (MADE)\n");
 #elif defined(DS_BUILD_K)
-	consolePrintf("build K\n");
-	consolePrintf("Cruise for a Corpse (Cruise)\n");
+	printf("build K\n");
+	printf("Cruise for a Corpse (Cruise)\n");
 #endif
-	consolePrintf("-------------------------------\n");
-	consolePrintf("L/R + D-pad/pen:    Scroll view\n");
-	consolePrintf("D-pad left:   Left mouse button\n");
-	consolePrintf("D-pad right: Right mouse button\n");
-	consolePrintf("D-pad up:           Hover mouse\n");
-	consolePrintf("B button:        Skip cutscenes\n");
-	consolePrintf("Select:         DS Options menu\n");
-	consolePrintf("Start:   Game menu (some games)\n");
-	consolePrintf("Y (in game):     Toggle console\n");
-	consolePrintf("X:              Toggle keyboard\n");
-	consolePrintf("A:                 Swap screens\n");
-	consolePrintf("L+R (on start):      Clear SRAM\n");
+	printf("-------------------------------\n");
+	printf("L/R + D-pad/pen:    Scroll view\n");
+	printf("D-pad left:   Left mouse button\n");
+	printf("D-pad right: Right mouse button\n");
+	printf("D-pad up:           Hover mouse\n");
+	printf("B button:        Skip cutscenes\n");
+	printf("Select:         DS Options menu\n");
+	printf("Start:   Game menu (some games)\n");
+	printf("Y (in game):     Toggle console\n");
+	printf("X:              Toggle keyboard\n");
+	printf("A:                 Swap screens\n");
+	printf("L+R (on start):      Clear SRAM\n");
 
 
 #if defined(DS_BUILD_A)
-	consolePrintf("For a complete key list see the\n");
-	consolePrintf("help screen.\n\n");
+	printf("For a complete key list see the\n");
+	printf("help screen.\n\n");
 #else
-	consolePrintf("\n");
+	printf("\n");
 #endif
 
 
 	if (!nitroFSInit(NULL)) {
-		consolePrintf("nitroFSInit failure: terminating\n");
+		printf("nitroFSInit failure: terminating\n");
 		return(1);
 	}
 
@@ -2483,11 +2483,3 @@ int main() {
 #endif
 	DS::main();
 }
-
-
-extern "C" void consolePrintf(const char * format, ...) {
-	va_list args;
-	va_start(args, format);
-	vprintf(format, args);
-	va_end(args);
-}
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp
index 59ec2334f7..5cac863736 100644
--- a/backends/platform/ds/arm9/source/dsoptions.cpp
+++ b/backends/platform/ds/arm9/source/dsoptions.cpp
@@ -229,7 +229,7 @@ void DSOptionsDialog::updateConfigManager() {
 		zoomLevel = 200;
 	}
 
-	consolePrintf("Saved zoom: %d\n", zoomLevel);
+	printf("Saved zoom: %d\n", zoomLevel);
 
 	ConfMan.setInt("topscreenzoom", zoomLevel, "ds");
 
diff --git a/backends/platform/ds/arm9/source/portdefs.h b/backends/platform/ds/arm9/source/portdefs.h
index 0325732208..148e3dc0f2 100644
--- a/backends/platform/ds/arm9/source/portdefs.h
+++ b/backends/platform/ds/arm9/source/portdefs.h
@@ -33,6 +33,7 @@ typedef unsigned int uint;
 #define SCUMMVM_DONT_DEFINE_TYPES
 
 // Include required headers
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,40 +52,6 @@ typedef unsigned int uint;
 #define STREAM_AUDIO_FROM_DISK
 #endif
 
-// FIXME: What is "NO_DEBUG_MSGS" good for?
-#define NO_DEBUG_MSGS
-
-// This is defined in dsmain.cpp
-#ifdef __cplusplus
-extern "C" {
-#endif
-void consolePrintf(const char *format, ...);
-#ifdef __cplusplus
-}
-#endif
-
-
-#ifdef assert
-#undef assert
-#endif
-
-#ifdef NDEBUG
-
-#define	assert(e)	((void)0)
-
-#else
-
-// FIXME: Shouldn't assert() also bail out / exit / halt the program? Right now we just
-// print an error message...
-#define assert(s) \
-	do { \
-		if (!(s)) { \
-			consolePrintf("Assertion failed: '##s##' at file %s, line %d\n", __FILE__, __LINE__); \
-		} \
-	} while (0)
-
-#endif
-
 // FIXME: Since I can't change the engine at the moment (post lockdown) this define can go here.
 // This define changes the mouse-relative motion which doesn't make sense on a touch screen to
 // a more conventional form of input where the menus can be clicked on.
diff --git a/backends/platform/ds/arm9/source/touchkeyboard.cpp b/backends/platform/ds/arm9/source/touchkeyboard.cpp
index 27d27ef142..622ed8215b 100644
--- a/backends/platform/ds/arm9/source/touchkeyboard.cpp
+++ b/backends/platform/ds/arm9/source/touchkeyboard.cpp
@@ -280,7 +280,7 @@ void drawAutoComplete() {
 
 	} else {
 
-		consolePrintf("time: %d\n", typingTimeout);
+		printf("time: %d\n", typingTimeout);
 
 		// Otherwise, draw autocompletions if one isn't being entered and there are
 		// some available.


Commit: f405be230eb02a1a14bd5a93d7fa520b5374b084
    https://github.com/scummvm/scummvm/commit/f405be230eb02a1a14bd5a93d7fa520b5374b084
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Clean up the main() function

Changed paths:
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/osystem_ds.h


diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 96d97a5b5c..899092439e 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -73,8 +73,6 @@
 
 #include <nds.h>
 #include <nds/registers_alt.h>
-#include <nds/arm9/exceptions.h>
-#include <nds/arm9/console.h>
 #include <filesystem.h>
 
 #include <stdlib.h>
@@ -92,17 +90,10 @@
 #include "engines/engine.h"
 
 #include "backends/plugins/ds/ds-provider.h"
+#include "base/main.h"
 #include "base/version.h"
 #include "common/util.h"
 
-extern "C" void OurIntrMain(void);
-extern "C" u32 getExceptionAddress(u32 opcodeAddress, u32 thumbState);
-
-extern const char __itcm_start[];
-static const char *registerNames[] =
-	{	"r0","r1","r2","r3","r4","r5","r6","r7",
-		"r8 ","r9 ","r10","r11","r12","sp ","lr ","pc" };
-
 namespace DS {
 
 // From console.c in NDSLib
@@ -267,8 +258,6 @@ static int triggeredIconTimeout = 0;
 
 static u16 savedPalEntry255 = RGB15(31, 31, 31);
 
-
-extern "C" int scummvm_main(int argc, char *argv[]);
 Common::EventType getKeyEvent(int key);
 int getKeysChanged();
 
@@ -1872,6 +1861,11 @@ void uploadSpriteGfx() {
 
 void initHardware() {
 	penInit();
+	indyFightState = false;
+	indyFightRight = true;
+
+	lastEventFrame = 0;
+	mouseMode = MOUSE_LEFT;
 
 	powerOn(POWER_ALL);
 	vramSetBankD(VRAM_D_SUB_SPRITE);
@@ -2285,123 +2279,26 @@ void fastRamReset() {
 	fastRamPointer = &fastRamData[0];
 }
 
+} // End of namespace DS
 
 /////////////////
 // Main
 /////////////////
 
+int main(int argc, char **argv) {
+#ifndef DISABLE_TEXT_CONSOLE
+	consoleDebugInit(DebugDevice_NOCASH);
+	nocashMessage("startup\n");
+#endif
 
+	DS::initHardware();
 
-void dsExceptionHandler() {
-	printf("Blue screen of death");
-	setExceptionHandler(NULL);
-
-	u32	currentMode = getCPSR() & 0x1f;
-	u32 thumbState = ((*(u32 *)0x027FFD90) & 0x20);
-
-	u32 codeAddress, exceptionAddress = 0;
-
-	int offset = 8;
-
-	if (currentMode == 0x17) {
-		printf("\x1b[10Cdata abort!\n\n");
-		codeAddress = exceptionRegisters[15] - offset;
-		if (	(codeAddress > 0x02000000 && codeAddress < 0x02400000) ||
-				(codeAddress > (u32)__itcm_start && codeAddress < (u32)(__itcm_start + 32768)) )
-			exceptionAddress = getExceptionAddress( codeAddress, thumbState);
-		else
-			exceptionAddress = codeAddress;
-
-	} else {
-		if (thumbState)
-			offset = 2;
-		else
-			offset = 4;
-		printf("\x1b[5Cundefined instruction!\n\n");
-		codeAddress = exceptionRegisters[15] - offset;
-		exceptionAddress = codeAddress;
-	}
-
-	printf("  pc: %08X addr: %08X\n\n",codeAddress,exceptionAddress);
-
-
-	int i;
-	for (i = 0; i < 8; i++) {
-		printf("  %s: %08X   %s: %08X\n",
-					registerNames[i], exceptionRegisters[i],
-					registerNames[i+8],exceptionRegisters[i+8]);
-	}
-
-	while(1)
-		;	// endles loop
-
-	u32 *stack = (u32 *)exceptionRegisters[13];
-
-
-	for (i = 0; i < 10; i++) {
-		printf("%08X %08X %08X\n", stack[i*3], stack[i*3+1], stack[(i*3)+2] );
-	}
-
-	memoryReport();
-
-	while(1);
-}
-
-
-
-
-int main(void) {
-
-	initHardware();
-
-	setExceptionHandler(dsExceptionHandler);
-
-	// Let arm9 read cartridge
-	*((u16 *) (0x04000204)) &= ~0x0080;
-
-	indyFightState = false;
-	indyFightRight = true;
-
-
-	lastEventFrame = 0;
-	mouseMode = MOUSE_LEFT;
+	defaultExceptionHandler();
 
-	//2372
 	printf("-------------------------------\n");
 	printf("ScummVM DS\n");
 	printf("Ported by Neil Millstone\n");
 	printf("Version %s ", gScummVMVersion);
-#if defined(DS_BUILD_A)
-	printf("build A\n");
-	printf("Lucasarts SCUMM games (SCUMM)\n");
-#elif defined(DS_BUILD_B)
-	printf("build B\n");
-	printf("BASS, QUEEN\n");
-#elif defined(DS_BUILD_C)
-	printf("build C\n");
-	printf("Simon/Elvira/Waxworks (AGOS)\n");
-#elif defined(DS_BUILD_D)
-	printf("build D\n");
-	printf("AGI, CINE, GOB\n");
-#elif defined(DS_BUILD_E)
-	printf("build E\n");
-	printf("Inherit the Earth (SAGA)\n");
-#elif defined(DS_BUILD_F)
-	printf("build F\n");
-	printf("The Legend of Kyrandia (KYRA)\n");
-#elif defined(DS_BUILD_G)
-	printf("build G\n");
-	printf("Lure of the Tempress (LURE)\n");
-#elif defined(DS_BUILD_H)
-	printf("build H\n");
-	printf("Nippon Safes (PARALLATION)\n");
-#elif defined(DS_BUILD_I)
-	printf("build I\n");
-	printf("Activision Games (MADE)\n");
-#elif defined(DS_BUILD_K)
-	printf("build K\n");
-	printf("Cruise for a Corpse (Cruise)\n");
-#endif
 	printf("-------------------------------\n");
 	printf("L/R + D-pad/pen:    Scroll view\n");
 	printf("D-pad left:   Left mouse button\n");
@@ -2414,72 +2311,27 @@ int main(void) {
 	printf("X:              Toggle keyboard\n");
 	printf("A:                 Swap screens\n");
 	printf("L+R (on start):      Clear SRAM\n");
-
-
-#if defined(DS_BUILD_A)
-	printf("For a complete key list see the\n");
-	printf("help screen.\n\n");
-#else
 	printf("\n");
-#endif
-
 
 	if (!nitroFSInit(NULL)) {
 		printf("nitroFSInit failure: terminating\n");
 		return(1);
 	}
 
-
-	updateStatus();
+	DS::updateStatus();
 
 	g_system = new OSystem_DS();
 	assert(g_system);
 
-#if defined(DS_BUILD_A)
-	const char *argv[] = {"/scummvmds"};
-#elif defined(DS_BUILD_B)
-	const char *argv[] = {"/scummvmds", "--config=scummvmb.ini"};
-#elif defined(DS_BUILD_C)
-	const char *argv[] = {"/scummvmds", "--config=scummvmc.ini"};
-#elif defined(DS_BUILD_D)
-	const char *argv[] = {"/scummvmds", "--config=scummvmd.ini"};
-#elif defined(DS_BUILD_E)
-	const char *argv[] = {"/scummvmds", "--config=scummvme.ini"};
-#elif defined(DS_BUILD_F)
-	const char *argv[] = {"/scummvmds", "--config=scummvmf.ini"};
-#elif defined(DS_BUILD_G)
-	const char *argv[] = {"/scummvmds", "--config=scummvmg.ini"};
-#elif defined(DS_BUILD_H)
-	const char *argv[] = {"/scummvmds", "--config=scummvmh.ini"};
-#elif defined(DS_BUILD_I)
-	const char *argv[] = {"/scummvmds", "--config=scummvmi.ini"};
-#elif defined(DS_BUILD_J)
-	const char *argv[] = {"/scummvmds", "--config=scummvmj.ini"};
-#elif defined(DS_BUILD_K)
-	const char *argv[] = {"/scummvmds", "--config=scummvmk.ini"};
-#else
-	// Use the default config file if no build was specified. This currently
-	// only happens with builds made using the regular ScummVM build system (as
-	// opposed to the nds specific build system).
-	const char *argv[] = {"/scummvmds"};
-#endif
-
 #ifdef DYNAMIC_MODULES
 	PluginManager::instance().addPluginProvider(new DSPluginProvider());
 #endif
 
-	scummvm_main(ARRAYSIZE(argv), (char **) &argv);
+	// Invoke the actual ScummVM main entry point:
+	int res = scummvm_main(argc, argv);
 
-	return 0;
-}
+	// Free OSystem
+	g_system->destroy();
 
-} // End of namespace DS
-
-
-int main() {
-#ifndef DISABLE_TEXT_CONSOLE
-	consoleDebugInit(DebugDevice_NOCASH);
-	nocashMessage("startup\n");
-#endif
-	DS::main();
+	return res;
 }
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index c9303c1cdb..098e14cd0f 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -53,35 +53,6 @@
 
 #include <time.h>
 
-#if defined(DS_BUILD_A)
-#define DEFAULT_CONFIG_FILE "scummvm.ini"
-#elif defined(DS_BUILD_B)
-#define DEFAULT_CONFIG_FILE "scummvmb.ini"
-#elif defined(DS_BUILD_C)
-#define DEFAULT_CONFIG_FILE "scummvmc.ini"
-#elif defined(DS_BUILD_D)
-#define DEFAULT_CONFIG_FILE "scummvmd.ini"
-#elif defined(DS_BUILD_E)
-#define DEFAULT_CONFIG_FILE "scummvme.ini"
-#elif defined(DS_BUILD_F)
-#define DEFAULT_CONFIG_FILE "scummvmf.ini"
-#elif defined(DS_BUILD_G)
-#define DEFAULT_CONFIG_FILE "scummvmg.ini"
-#elif defined(DS_BUILD_H)
-#define DEFAULT_CONFIG_FILE "scummvmh.ini"
-#elif defined(DS_BUILD_I)
-#define DEFAULT_CONFIG_FILE "scummvmi.ini"
-#elif defined(DS_BUILD_J)
-#define DEFAULT_CONFIG_FILE "scummvmj.ini"
-#elif defined(DS_BUILD_K)
-#define DEFAULT_CONFIG_FILE "scummvmk.ini"
-#else
-	// Use the "scummvm.ini" as config file if no build was specified. This
-	// currently only happens with builds made using the regular ScummVM build
-	// system (as opposed to the nds specific build system).
-#define DEFAULT_CONFIG_FILE "scummvm.ini"
-#endif
-
 OSystem_DS *OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
@@ -669,10 +640,6 @@ void OSystem_DS::setCharactersEntered(int count) {
 	DS::setCharactersEntered(count);
 }
 
-Common::String OSystem_DS::getDefaultConfigFileName() {
-	return DEFAULT_CONFIG_FILE;
-}
-
 void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
 #ifndef DISABLE_TEXT_CONSOLE
 	nocashMessage((char *)message);
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index 6c438f917b..d3519c30c1 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -151,8 +151,6 @@ public:
 
 	void refreshCursor();
 
-	virtual Common::String getDefaultConfigFileName();
-
 	virtual void logMessage(LogMessageType::Type type, const char *message);
 
 	u16 applyGamma(u16 color);


Commit: 1f8dc4d2048c5f6e6dc3092ab1d7834803ea0f65
    https://github.com/scummvm/scummvm/commit/1f8dc4d2048c5f6e6dc3092ab1d7834803ea0f65
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Replace some deprecated APIs

Changed paths:
    backends/platform/ds/arm9/source/dsmain.cpp


diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 899092439e..9500a27205 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -72,7 +72,6 @@
 
 
 #include <nds.h>
-#include <nds/registers_alt.h>
 #include <filesystem.h>
 
 #include <stdlib.h>
@@ -455,12 +454,12 @@ void displayMode8Bit() {
 
 		vramSetBankH(VRAM_H_LCD);
 
-		BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(8);
+		REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
 
-		BG3_XDX = 256;
-		BG3_XDY = 0;
-		BG3_YDX = 0;
-		BG3_YDY = (int) ((200.0f / 192.0f) * 256);
+		REG_BG3PA = 256;
+		REG_BG3PB = 0;
+		REG_BG3PC = 0;
+		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
 
 	} else {
 		videoSetMode(MODE_5_2D | (consoleEnable ? DISPLAY_BG0_ACTIVE : 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
@@ -474,20 +473,20 @@ void displayMode8Bit() {
 
 		vramSetBankH(VRAM_H_LCD);
 
-		BG3_CR = BG_BMP8_512x256 | BG_BMP_BASE(8);
+		REG_BG3CNT = BG_BMP8_512x256 | BG_BMP_BASE(8);
 
-		BG3_XDX = (int) (((float) (gameWidth) / 256.0f) * 256);
-		BG3_XDY = 0;
-		BG3_YDX = 0;
-		BG3_YDY = (int) ((200.0f / 192.0f) * 256);
+		REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
+		REG_BG3PB = 0;
+		REG_BG3PC = 0;
+		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
 	}
 
-	SUB_BG3_CR = BG_BMP8_512x256;
+	REG_BG3CNT_SUB = BG_BMP8_512x256;
 
-	SUB_BG3_XDX = (int) (subScreenWidth / 256.0f * 256);
-	SUB_BG3_XDY = 0;
-	SUB_BG3_YDX = 0;
-	SUB_BG3_YDY = (int) (subScreenHeight / 192.0f * 256);
+	REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
+	REG_BG3PB_SUB = 0;
+	REG_BG3PC_SUB = 0;
+	REG_BG3PD_SUB = (int) (subScreenHeight / 192.0f * 256);
 
 
 
@@ -514,9 +513,9 @@ void displayMode8Bit() {
 	#endif
 
 	if (gameScreenSwap) {
-		POWER_CR |= POWER_SWAP_LCDS;
+		lcdMainOnTop();
 	} else {
-		POWER_CR &= ~POWER_SWAP_LCDS;
+		lcdMainOnBottom();
 	}
 
 	uploadSpriteGfx();
@@ -668,7 +667,7 @@ void displayMode16Bit() {
 	vramSetBankD(VRAM_D_MAIN_BG);
 	vramSetBankH(VRAM_H_SUB_BG);
 
-	BG3_CR = BG_BMP16_512x256;
+	REG_BG3CNT = BG_BMP16_512x256;
 	highBuffer = false;
 
 
@@ -678,8 +677,8 @@ void displayMode16Bit() {
 	BG_PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
 
 	// Do text stuff
-	SUB_BG0_CR = BG_MAP_BASE(4) | BG_TILE_BASE(0);
-	SUB_BG0_Y0 = 0;
+	REG_BG0CNT_SUB = BG_MAP_BASE(4) | BG_TILE_BASE(0);
+	REG_BG0VOFS_SUB = 0;
 
 	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 4, 0, false, true);
 
@@ -690,19 +689,19 @@ void displayMode16Bit() {
 	consoleSetWindow(NULL, 0, 0, 32, 24);
 
 	// Show keyboard
-	SUB_BG1_CR = BG_TILE_BASE(1) | BG_MAP_BASE(12);
+	REG_BG1CNT_SUB = BG_TILE_BASE(1) | BG_MAP_BASE(12);
 
-	POWER_CR &= ~POWER_SWAP_LCDS;
+	lcdMainOnBottom();
 
 	displayModeIs8Bit = false;
 
 	// ConsoleInit destroys the hardware palette :-(
 	OSystem_DS::instance()->restoreHardwarePalette();
 
-	BG3_XDX = isCpuScalerEnabled() ? 256 : (int) (1.25f * 256);
-	BG3_XDY = 0;
-	BG3_YDX = 0;
-	BG3_YDY = (int) ((200.0f / 192.0f) * 256);
+	REG_BG3PA = isCpuScalerEnabled() ? 256 : (int) (1.25f * 256);
+	REG_BG3PB = 0;
+	REG_BG3PC = 0;
+	REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
 
 	#ifdef HEAVY_LOGGING
 	printf("done\n");
@@ -728,12 +727,6 @@ void displayMode16BitFlipBuffer() {
 			}
 		}
 	} else if (isCpuScalerEnabled()) {
-		//#define SCALER_PROFILE
-
-		#ifdef SCALER_PROFILE
-		TIMER1_CR = TIMER_ENABLE | TIMER_DIV_1024;
-		u16 t0 = TIMER1_DATA;
-		#endif
 		const u8 *back = (const u8*)get8BitBackBuffer();
 		u16 *base = BG_GFX + 0x10000;
 		Rescale_320x256xPAL8_To_256x256x1555(
@@ -743,20 +736,6 @@ void displayMode16BitFlipBuffer() {
 			get8BitBackBufferStride(),
 			BG_PALETTE,
 			getGameHeight() );
-
-		#ifdef SCALER_PROFILE
-		// 10 pixels : 1ms
-		u16 t1 = TIMER1_DATA;
-		TIMER1_CR &= ~TIMER_ENABLE;
-		u32 dt = t1 - t0;
-		u32 dt_us = (dt * 10240) / 334;
-		u32 dt_10ms = dt_us / 100;
-		int i;
-		for(i=0; i<dt_10ms; ++i)
-			base[i] = ((i/10)&1) ? 0xFFFF : 0x801F;
-		for(; i<256; ++i)
-			base[i] = 0x8000;
-		#endif
 	}
 	#ifdef HEAVY_LOGGING
 	printf("done\n");
@@ -934,18 +913,18 @@ void setKeyboardEnable(bool en) {
 		DS::drawKeyboard(1, 15, backupBank);
 
 
-		SUB_BG1_CR = BG_TILE_BASE(1) | BG_MAP_BASE(15);
+		REG_BG1CNT_SUB = BG_TILE_BASE(1) | BG_MAP_BASE(15);
 
 		if (displayModeIs8Bit) {
-			SUB_DISPLAY_CR |= DISPLAY_BG1_ACTIVE;	// Turn on keyboard layer
-			SUB_DISPLAY_CR &= ~DISPLAY_BG3_ACTIVE;	// Turn off game layer
+			REG_DISPCNT_SUB |= DISPLAY_BG1_ACTIVE;	// Turn on keyboard layer
+			REG_DISPCNT_SUB &= ~DISPLAY_BG3_ACTIVE;	// Turn off game layer
 		} else {
-			SUB_DISPLAY_CR |= DISPLAY_BG1_ACTIVE;	// Turn on keyboard layer
-			SUB_DISPLAY_CR &= ~DISPLAY_BG0_ACTIVE;	// Turn off console layer
+			REG_DISPCNT_SUB |= DISPLAY_BG1_ACTIVE;	// Turn on keyboard layer
+			REG_DISPCNT_SUB &= ~DISPLAY_BG0_ACTIVE;	// Turn off console layer
 		}
 
 		// Ensure the keyboard is on the lower screen
-		POWER_CR |= POWER_SWAP_LCDS;
+		lcdMainOnTop();
 
 
 	} else {
@@ -968,18 +947,18 @@ void setKeyboardEnable(bool en) {
 				}
 			}
 
-			SUB_DISPLAY_CR &= ~DISPLAY_BG1_ACTIVE;	// Turn off keyboard layer
-			SUB_DISPLAY_CR |= DISPLAY_BG3_ACTIVE;	// Turn on game layer
+			REG_DISPCNT_SUB &= ~DISPLAY_BG1_ACTIVE;	// Turn off keyboard layer
+			REG_DISPCNT_SUB |= DISPLAY_BG3_ACTIVE;	// Turn on game layer
 		} else {
-			SUB_DISPLAY_CR &= ~DISPLAY_BG1_ACTIVE;	// Turn off keyboard layer
-			SUB_DISPLAY_CR |= DISPLAY_BG0_ACTIVE;	// Turn on console layer
+			REG_DISPCNT_SUB &= ~DISPLAY_BG1_ACTIVE;	// Turn off keyboard layer
+			REG_DISPCNT_SUB |= DISPLAY_BG0_ACTIVE;	// Turn on console layer
 		}
 
 		// Restore the screens so they're the right way round
 		if (gameScreenSwap) {
-			POWER_CR |= POWER_SWAP_LCDS;
+			lcdMainOnTop();
 		} else {
-			POWER_CR &= ~POWER_SWAP_LCDS;
+			lcdMainOnBottom();
 		}
 	}
 }
@@ -1268,9 +1247,9 @@ void addEventsToQueue() {
 					gameScreenSwap = !gameScreenSwap;
 
 					if (gameScreenSwap) {
-						POWER_CR |= POWER_SWAP_LCDS;
+						lcdMainOnTop();
 					} else {
-						POWER_CR &= ~POWER_SWAP_LCDS;
+						lcdMainOnBottom();
 					}
 
 				}
@@ -1518,8 +1497,8 @@ void updateStatus() {
 }
 
 void setMainScreenScroll(int x, int y) {
-		BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
-		BG3_CY = y;
+		REG_BG3X = x + (((frameCount & 1) == 0)? 64: 0);
+		REG_BG3Y = y;
 
 		if ((!gameScreenSwap) || (touchPadStyle)) {
 			touchX = x >> 8;
@@ -1529,15 +1508,15 @@ void setMainScreenScroll(int x, int y) {
 
 void setMainScreenScale(int x, int y) {
 		if (isCpuScalerEnabled() && (x==320)) {
-			BG3_XDX = 256;
-			BG3_XDY = 0;
-			BG3_YDX = 0;
-			BG3_YDY = y;
+			REG_BG3PA = 256;
+			REG_BG3PB = 0;
+			REG_BG3PC = 0;
+			REG_BG3PD = y;
 		} else {
-			BG3_XDX = x;
-			BG3_XDY = 0;
-			BG3_YDX = 0;
-			BG3_YDY = y;
+			REG_BG3PA = x;
+			REG_BG3PB = 0;
+			REG_BG3PC = 0;
+			REG_BG3PD = y;
 		}
 
 		if ((!gameScreenSwap) || (touchPadStyle)) {
@@ -1553,8 +1532,8 @@ void setZoomedScreenScroll(int x, int y, bool shake) {
 		}
 
 
-		SUB_BG3_CX = x + ((shake && (frameCount & 1) == 0)? 64: 0);
-		SUB_BG3_CY = y;
+		REG_BG3X_SUB = x + ((shake && (frameCount & 1) == 0)? 64: 0);
+		REG_BG3Y_SUB = y;
 }
 
 void setZoomedScreenScale(int x, int y) {
@@ -1563,10 +1542,10 @@ void setZoomedScreenScale(int x, int y) {
 			touchScY = y;
 		}
 
-		SUB_BG3_XDX = x;
-		SUB_BG3_XDY = 0;
-		SUB_BG3_YDX = 0;
-		SUB_BG3_YDY = y;
+		REG_BG3PA_SUB = x;
+		REG_BG3PB_SUB = 0;
+		REG_BG3PC_SUB = 0;
+		REG_BG3PD_SUB = y;
 }
 
 void VBlankHandler(void) {
@@ -1871,8 +1850,6 @@ void initHardware() {
 	vramSetBankD(VRAM_D_SUB_SPRITE);
 	vramSetBankE(VRAM_E_MAIN_SPRITE);
 
-	currentTimeMillis = 0;
-
 	for (int r = 0; r < 255; r++) {
 		BG_PALETTE[r] = 0;
 	}
@@ -1898,7 +1875,7 @@ void initHardware() {
 	subScTargetX = 0;
 	subScTargetY = 0;
 
-	POWER_CR &= ~POWER_SWAP_LCDS;
+	lcdMainOnBottom();
 
 	frameCount = 0;
 	callback = NULL;
@@ -1907,22 +1884,12 @@ void initHardware() {
 
 	//irqs are nice
 	irqSet(IRQ_VBLANK, VBlankHandler);
-	irqSet(IRQ_TIMER0, timerTickHandler);
-
 	irqEnable(IRQ_VBLANK);
-	irqEnable(IRQ_TIMER0);
 
 	// Set up a millisecond timer
-	#ifdef HEAVY_LOGGING
-	printf("Setting up timer...");
-	#endif
-	TIMER0_CR = 0;
-	TIMER0_DATA = (u32) TIMER_FREQ(1000);
-	TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1 | TIMER_IRQ_REQ;
+	currentTimeMillis = 0;
+	timerStart(0, ClockDivider_1, (u16)TIMER_FREQ(1000), timerTickHandler);
 	REG_IME = 1;
-	#ifdef HEAVY_LOGGING
-	printf("done\n");
-	#endif
 
 	BG_PALETTE[255] = RGB15(0,0,31);
 
@@ -1931,9 +1898,6 @@ void initHardware() {
 	// If the software scaler's back buffer has not been allocated, do it now
 	scalerBackBuffer = (u8 *) malloc(320 * 256);
 
-
-	WAIT_CR &= ~(0x0080);
-
 	uploadSpriteGfx();
 
 	// This is a bodge to get around the fact that the cursor is turned on before it's image is set


Commit: 438c2d87147e4f7cc9158432cdc38dcd53f5869f
    https://github.com/scummvm/scummvm/commit/438c2d87147e4f7cc9158432cdc38dcd53f5869f
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Rewrite event handling

Changed paths:
  A backends/events/ds/ds-events.cpp
  A backends/events/ds/ds-events.h
  R backends/platform/ds/arm9/data/8x8font.tga
  R backends/platform/ds/arm9/data/8x8font_tga.raw
  R backends/platform/ds/arm9/data/default_font.bin
  R backends/platform/ds/arm9/data/keyboard.raw
  R backends/platform/ds/arm9/data/keyboard_pal.raw
  R backends/platform/ds/arm9/data/master.pal
  R backends/platform/ds/arm9/source/scummhelp.cpp
  R backends/platform/ds/arm9/source/scummhelp.h
  R backends/platform/ds/arm9/source/touchkeyboard.cpp
  R backends/platform/ds/arm9/source/touchkeyboard.h
  R backends/platform/ds/arm9/source/wordcompletion.cpp
  R backends/platform/ds/arm9/source/wordcompletion.h
    backends/module.mk
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsmain.h
    backends/platform/ds/arm9/source/dsoptions.cpp
    backends/platform/ds/arm9/source/dsoptions.h
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/osystem_ds.h
    backends/platform/ds/module.mk
    engines/agi/agi.cpp
    engines/agi/text.cpp
    engines/scumm/dialogs.cpp
    gui/predictivedialog.cpp


diff --git a/backends/events/ds/ds-events.cpp b/backends/events/ds/ds-events.cpp
new file mode 100644
index 0000000000..807a65884e
--- /dev/null
+++ b/backends/events/ds/ds-events.cpp
@@ -0,0 +1,102 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <nds.h>
+
+#include "dsmain.h"
+#include "backends/events/ds/ds-events.h"
+
+bool DSEventSource::pollEvent(Common::Event &event) {
+	if (_eventQueue.empty()) {
+		if (!_firstPoll) {
+			_firstPoll = true;
+			return false;
+		}
+
+
+		addEventsToQueue();
+		if (_eventQueue.empty())
+			return false;
+
+		_firstPoll = false;
+	}
+
+	event = _eventQueue.pop();
+
+	if (Common::isMouseEvent(event)) {
+		g_system->warpMouse(event.mouse.x, event.mouse.y);
+	}
+
+	return true;
+}
+
+void DSEventSource::addJoyButtonEvent(u32 keysPressed, u32 keysReleased, u32 ndsKey, uint8 svmButton) {
+	if (keysPressed & ndsKey || keysReleased & ndsKey) {
+		Common::Event event;
+		event.type = (keysPressed & ndsKey) ? Common::EVENT_JOYBUTTON_DOWN : Common::EVENT_JOYBUTTON_UP;
+		event.joystick.button = svmButton;
+
+		_eventQueue.push(event);
+	}
+}
+
+void DSEventSource::addEventsToQueue() {
+	Common::Event event;
+
+	scanKeys();
+	uint32 held = keysHeld(), keysPressed = keysDown(), keysReleased = keysUp();
+
+	// Touch screen events
+	if (held & KEY_TOUCH) {
+		touchPosition touchPos;
+		touchRead(&touchPos);
+		event.mouse = DS::transformPoint(touchPos.px, touchPos.py);
+
+		if (keysPressed & KEY_TOUCH) {
+			event.type = Common::EVENT_LBUTTONDOWN;
+			_eventQueue.push(event);
+		} else if (event.mouse.x != _lastTouch.x || event.mouse.y != _lastTouch.y) {
+			event.type = Common::EVENT_MOUSEMOVE;
+			_eventQueue.push(event);
+		}
+
+		_lastTouch = event.mouse;
+	} else if (keysReleased & KEY_TOUCH) {
+		event.mouse = _lastTouch;
+		event.type = Common::EVENT_LBUTTONUP;
+		_eventQueue.push(event);
+	}
+
+	// Button events
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_L,      Common::JOYSTICK_BUTTON_LEFT_SHOULDER);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_R,      Common::JOYSTICK_BUTTON_RIGHT_SHOULDER);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_A,      Common::JOYSTICK_BUTTON_A);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_B,      Common::JOYSTICK_BUTTON_B);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_X,      Common::JOYSTICK_BUTTON_X);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_Y,      Common::JOYSTICK_BUTTON_Y);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_UP,     Common::JOYSTICK_BUTTON_DPAD_UP);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_DOWN,   Common::JOYSTICK_BUTTON_DPAD_DOWN);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_LEFT,   Common::JOYSTICK_BUTTON_DPAD_LEFT);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_RIGHT,  Common::JOYSTICK_BUTTON_DPAD_RIGHT);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_START,  Common::JOYSTICK_BUTTON_START);
+	addJoyButtonEvent(keysPressed, keysReleased, KEY_SELECT, Common::JOYSTICK_BUTTON_BACK);
+}
diff --git a/backends/platform/ds/arm9/source/scummhelp.h b/backends/events/ds/ds-events.h
similarity index 64%
rename from backends/platform/ds/arm9/source/scummhelp.h
rename to backends/events/ds/ds-events.h
index a14890db48..d3fa3e46ee 100644
--- a/backends/platform/ds/arm9/source/scummhelp.h
+++ b/backends/events/ds/ds-events.h
@@ -20,18 +20,30 @@
  *
  */
 
-#ifndef _SCUMMHELP_H_
-#define _SCUMMHELP_H_
+#ifndef BACKEND_EVENTS_DS_H
+#define BACKEND_EVENTS_DS_H
 
-#include "common/ustr.h"
-#include "common/platform.h"
+#include "common/events.h"
 
-namespace DS {
+/**
+ * The Nintendo DS event source.
+ */
+class DSEventSource : public Common::EventSource {
+public:
+	DSEventSource() : _firstPoll(true) {}
 
-void updateStrings(byte gameId, byte version, Common::Platform platform,
-			int page, Common::U32String &title, Common::U32String *&key, Common::U32String *&dsc);
+	/**
+	 * Gets and processes events.
+	 */
+	virtual bool pollEvent(Common::Event &event);
 
-} // End of namespace DS
+protected:
+	Common::Queue<Common::Event> _eventQueue;
+	Common::Point _lastTouch;
+	bool _firstPoll;
 
+	void addEventsToQueue();
+	void addJoyButtonEvent(u32 keysPressed, u32 keysReleased, u32 ndsKey, uint8 svmButton);
+};
 
 #endif
diff --git a/backends/module.mk b/backends/module.mk
index 2476ff3b98..fac688fedb 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -284,6 +284,7 @@ endif
 
 ifeq ($(BACKEND),ds)
 MODULE_OBJS += \
+	events/ds/ds-events.o \
 	fs/posix/posix-fs.o \
 	fs/posix/posix-fs-factory.o \
 	fs/posix/posix-iostream.o \
diff --git a/backends/platform/ds/arm9/data/8x8font.tga b/backends/platform/ds/arm9/data/8x8font.tga
deleted file mode 100644
index 3a5c5397f2..0000000000
Binary files a/backends/platform/ds/arm9/data/8x8font.tga and /dev/null differ
diff --git a/backends/platform/ds/arm9/data/8x8font_tga.raw b/backends/platform/ds/arm9/data/8x8font_tga.raw
deleted file mode 100644
index 3a5c5397f2..0000000000
Binary files a/backends/platform/ds/arm9/data/8x8font_tga.raw and /dev/null differ
diff --git a/backends/platform/ds/arm9/data/default_font.bin b/backends/platform/ds/arm9/data/default_font.bin
deleted file mode 100644
index 112e78b336..0000000000
Binary files a/backends/platform/ds/arm9/data/default_font.bin and /dev/null differ
diff --git a/backends/platform/ds/arm9/data/keyboard.raw b/backends/platform/ds/arm9/data/keyboard.raw
deleted file mode 100644
index e8779f81ea..0000000000
Binary files a/backends/platform/ds/arm9/data/keyboard.raw and /dev/null differ
diff --git a/backends/platform/ds/arm9/data/keyboard_pal.raw b/backends/platform/ds/arm9/data/keyboard_pal.raw
deleted file mode 100644
index 31ef32c04e..0000000000
Binary files a/backends/platform/ds/arm9/data/keyboard_pal.raw and /dev/null differ
diff --git a/backends/platform/ds/arm9/data/master.pal b/backends/platform/ds/arm9/data/master.pal
deleted file mode 100644
index 9535668238..0000000000
Binary files a/backends/platform/ds/arm9/data/master.pal and /dev/null differ
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 9500a27205..529056a75a 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -79,11 +79,6 @@
 
 #include "dsmain.h"
 #include "osystem_ds.h"
-#include "icons_raw.h"
-#include "keyboard_raw.h"
-#include "keyboard_pal_raw.h"
-#define V16(a, b) ((a << 12) | b)
-#include "touchkeyboard.h"
 #include "dsoptions.h"
 #include "blitters.h"
 #include "engines/engine.h"
@@ -97,15 +92,6 @@ namespace DS {
 
 // From console.c in NDSLib
 
-//location of cursor
-extern u8 row;
-extern u8 col;
-
-// Mouse mode
-enum MouseMode {
-	MOUSE_LEFT, MOUSE_RIGHT, MOUSE_HOVER, MOUSE_NUM_MODES
-};
-
 // Defines
 #define FRAME_TIME 17
 #define SCUMM_GAME_HEIGHT 142
@@ -133,26 +119,15 @@ static int subScreenHeight = SCUMM_GAME_HEIGHT;
 static int subScreenScale = 256;
 
 
-// Events
-static int lastEventFrame;
-static bool indyFightState;
-static bool indyFightRight;
-
 // Saved buffers
 static bool highBuffer;
 static bool displayModeIs8Bit = false;
 
-// Game id
-static u8 gameID;
-
-static bool snapToBorder = false;
 static bool consoleEnable = false;
 static bool gameScreenSwap = false;
 bool isCpuScalerEnabled();
 //#define HEAVY_LOGGING
 
-static MouseMode mouseMode = MOUSE_LEFT;
-
 static int storedMouseX = 0;
 static int storedMouseY = 0;
 
@@ -164,33 +139,12 @@ static SpriteEntry spritesMain[128];
 static int s_shakeXOffset = 0;
 static int s_shakeYOffset = 0;
 
-// Keyboard
-static bool keyboardEnable = false;
-static bool leftHandedMode = false;
-static bool keyboardIcon = false;
-
 // Touch
 static int touchScX, touchScY, touchX, touchY;
 static int mouseHotspotX, mouseHotspotY;
 static bool cursorEnable = false;
 static bool mouseCursorVisible = true;
-static bool leftButtonDown = false;
-static bool rightButtonDown = false;
 static bool touchPadStyle = false;
-static int touchPadSensitivity = 8;
-static bool tapScreenClicks = true;
-
-static int tapCount = 0;
-static int tapTimeout = 0;
-static int tapComplete = 0;
-
-// Dragging
-static int dragStartX, dragStartY;
-static bool dragging = false;
-static int dragScX, dragScY;
-
-// Interface styles
-static char gameName[32];
 
 // 8-bit surface size
 static int gameWidth = 320;
@@ -202,73 +156,10 @@ static bool cpuScalerEnable = false;
 
 static u8 *scalerBackBuffer = NULL;
 
-#define NUM_SUPPORTED_GAMES 21
-
-static const gameListType gameList[NUM_SUPPORTED_GAMES] = {
-	// Unknown game - use normal SCUMM controls
-	{"unknown", 	CONT_SCUMM_ORIGINAL},
-
-	// SCUMM games
-	{"maniac",		CONT_SCUMM_ORIGINAL},
-	{"zak",			CONT_SCUMM_ORIGINAL},
-	{"loom",		CONT_SCUMM_ORIGINAL},
-	{"indy3",		CONT_SCUMM_ORIGINAL},
-	{"atlantis",		CONT_SCUMM_ORIGINAL},
-	{"monkey",		CONT_SCUMM_ORIGINAL},
-	{"monkey2",		CONT_SCUMM_ORIGINAL},
-	{"tentacle",		CONT_SCUMM_ORIGINAL},
-	{"samnmax",		CONT_SCUMM_SAMNMAX},
-
-	// Non-SCUMM games
-	{"sky",			CONT_SKY},
-	{"simon1",		CONT_SIMON},
-	{"simon2",		CONT_SIMON},
-	{"gob",			CONT_GOBLINS},
-	{"queen",		CONT_SCUMM_ORIGINAL},
-	{"cine",		CONT_FUTURE_WARS},
-	{"agi",			CONT_AGI},
-	{"elvira2",		CONT_SIMON},
-	{"elvira1",		CONT_SIMON},
-	{"waxworks",		CONT_SIMON},
-	{"parallaction",	CONT_NIPPON},
-};
-
-static const gameListType *s_currentGame = NULL;
-
-// Stylus
-static bool penDown = FALSE;
-static bool penHeld = FALSE;
-static bool penReleased = FALSE;
-static bool penDownLastFrame = FALSE;
-static s32 penX = 0, penY = 0;
-static s32 penDownX = 0, penDownY = 0;
-static int keysDownSaved = 0;
-static int keysReleasedSaved = 0;
-static int keysChangedSaved = 0;
-
-static bool penDownSaved = FALSE;
-static bool penReleasedSaved = FALSE;
-static int penDownFrames = 0;
-static int touchXOffset = 0;
-static int touchYOffset = 0;
-
-static int triggeredIcon = 0;
-static int triggeredIconTimeout = 0;
-
 static u16 savedPalEntry255 = RGB15(31, 31, 31);
 
-Common::EventType getKeyEvent(int key);
-int getKeysChanged();
-
-void updateStatus();
-void triggerIcon(int imageNum);
 void setIcon(int num, int x, int y, int imageNum, int flags, bool enable);
 void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable);
-void uploadSpriteGfx();
-
-static bool isScrollingWithDPad() {
-	return (getKeysHeld() & (KEY_L | KEY_R)) != 0;
-}
 
 bool isCpuScalerEnabled() {
 	return cpuScalerEnable || !displayModeIs8Bit;
@@ -283,18 +174,10 @@ void setTrackPadStyleEnable(bool enable) {
 	touchPadStyle = enable;
 }
 
-void setTapScreenClicksEnable(bool enable) {
-	tapScreenClicks = enable;
-}
-
 void setGameScreenSwap(bool enable) {
 	gameScreenSwap = enable;
 }
 
-void setSensitivity(int sensitivity) {
-	touchPadSensitivity = sensitivity;
-}
-
 void setGamma(int gamma) {
 	OSystem_DS::instance()->setGammaValue(gamma);
 }
@@ -304,10 +187,6 @@ void setTopScreenZoom(int percentage) {
 	subScreenScale = (256 * 256) / scale;
 }
 
-controlType getControlType() {
-	return s_currentGame->control;
-}
-
 void updateOAM() {
 	DC_FlushAll();
 
@@ -363,54 +242,6 @@ void saveGameBackBuffer() {
 	OSystem_DS::instance()->unlockScreen();
 }
 
-void exitGame() {
-	s_currentGame = NULL;
-}
-
-void initGame() {
-	// This is a good time to check for left handed mode since the mode change is done as the game starts.
-	// There's probably a better way, but hey.
-	#ifdef HEAVY_LOGGING
-	printf("initing game...");
-	#endif
-
-	setOptions();
-
-	if (s_currentGame == NULL) {
-
-		strcpy(gameName, ConfMan.get("gameid").c_str());
-
-		s_currentGame = &gameList[0];		// Default game
-
-		for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) {
-			if (!scumm_stricmp(gameName, gameList[r].gameId)) {
-				s_currentGame = &gameList[r];
-			}
-		}
-	}
-
-	#ifdef HEAVY_LOGGING
-	printf("done\n");
-	#endif
-
-}
-
-void setLeftHanded(bool enable) {
-	leftHandedMode = enable;
-}
-
-void setSnapToBorder(bool enable) {
-	snapToBorder = enable;
-}
-
-void setTouchXOffset(int x) {
-	touchXOffset = x;
-}
-
-void setTouchYOffset(int y) {
-	touchYOffset = y;
-}
-
 void set200PercentFixedScale(bool on) {
 	twoHundredPercentFixedScale = on;
 }
@@ -426,9 +257,7 @@ void displayMode8Bit() {
 #endif
 	u16 buffer[32 * 32];
 
-	initGame();
-
-	setKeyboardEnable(false);
+	setOptions();
 
 	if (!displayModeIs8Bit) {
 		for (int r = 0; r < 32 * 32; r++) {
@@ -517,32 +346,16 @@ void displayMode8Bit() {
 	} else {
 		lcdMainOnBottom();
 	}
-
-	uploadSpriteGfx();
-
-	keyboardEnable = false;
-
-}
-
-void setGameID(int id) {
-	gameID = id;
 }
 
 void setShowCursor(bool enable) {
-	if ((s_currentGame) && (s_currentGame->control == CONT_SCUMM_SAMNMAX)) {
-		if (cursorEnable) {
-			sprites[1].attribute[0] = ATTR0_BMP | 150;
-		} else {
-			sprites[1].attribute[0] = ATTR0_DISABLED;
-		}
-
-	}
-
 	cursorEnable = enable;
+	updateMouse();
 }
 
 void setMouseCursorVisible(bool enable) {
 	mouseCursorVisible = enable;
+	updateMouse();
 }
 
 void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX, int hotspotY) {
@@ -572,64 +385,6 @@ void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX,
 			}
 		}
 	}
-
-	if (s_currentGame->control != CONT_SCUMM_SAMNMAX)
-		return;
-
-	uint16 border = RGB15(24,24,24) | 0x8000;
-
-
-	off = 176*64;
-	memset(SPRITE_GFX_SUB+off, 0, 64*64*2);
-	memset(SPRITE_GFX+off, 0, 64*64*2);
-
-	int pos = 190 - (w+2);
-
-
-
-	// make border
-	for (uint i=0; i<w+2; i++) {
-		SPRITE_GFX[off+i] = border;
-		SPRITE_GFX[off+(31)*64+i] = border;
-
-		SPRITE_GFX_SUB[off+i] = border;
-		SPRITE_GFX_SUB[off+(31)*64+i] = border;
-	}
-	for (uint i=1; i<31; i++) {
-		SPRITE_GFX[off+(i*64)] = border;
-		SPRITE_GFX[off+(i*64)+(w+1)] = border;
-
-		SPRITE_GFX_SUB[off+(i*64)] = border;
-		SPRITE_GFX_SUB[off+(i*64)+(w+1)] = border;
-	}
-
-	int offset = (32 - h) >> 1;
-
-	for (uint y=0; y<h; y++) {
-		for (uint x=0; x<w; x++) {
-			int color = icon[y*w+x];
-
-			if (color == keycolor) {
-				SPRITE_GFX[off+(y+1+offset)*64+(x+1)] = 0x8000; // black background
-				SPRITE_GFX_SUB[off+(y+1+offset)*64+(x+1)] = 0x8000; // black background
-			} else {
-				SPRITE_GFX[off+(y+1+offset)*64+(x+1)] = BG_PALETTE[color] | 0x8000;
-				SPRITE_GFX_SUB[off+(y+1+offset)*64+(x+1)] = BG_PALETTE[color] | 0x8000;
-			}
-		}
-	}
-
-
-	if (cursorEnable) {
-		sprites[1].attribute[0] = ATTR0_BMP | 150;
-		sprites[1].attribute[1] = ATTR1_SIZE_64 | pos;
-		sprites[1].attribute[2] = ATTR2_ALPHA(1) | 176;
-	} else {
-		sprites[1].attribute[0] = ATTR0_DISABLED | 150;
-		sprites[1].attribute[1] = ATTR1_SIZE_64 | pos;
-		sprites[1].attribute[2] = ATTR2_ALPHA(1) | 176;
-	}
-
 }
 
 
@@ -642,10 +397,6 @@ void displayMode16Bit() {
 
 	u16 buffer[32 * 32 * 2];
 
-	releaseAllKeys();
-
-	setKeyboardEnable(false);
-
 	if (!displayModeIs8Bit) {
 		for (int r = 0; r < 32 * 32; r++) {
 			buffer[r] = ((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r];
@@ -659,7 +410,7 @@ void displayMode16Bit() {
 
 
 	videoSetMode(MODE_5_2D | /*DISPLAY_BG0_ACTIVE |*/ DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE |/* DISPLAY_BG1_ACTIVE |*/ DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
+	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
 
 	vramSetBankA(VRAM_A_MAIN_BG);
 	vramSetBankB(VRAM_B_MAIN_BG);
@@ -688,9 +439,6 @@ void displayMode16Bit() {
 
 	consoleSetWindow(NULL, 0, 0, 32, 24);
 
-	// Show keyboard
-	REG_BG1CNT_SUB = BG_TILE_BASE(1) | BG_MAP_BASE(12);
-
 	lcdMainOnBottom();
 
 	displayModeIs8Bit = false;
@@ -784,964 +532,167 @@ void doTimerCallback() {
 	}
 }
 
-void memoryReport() {
-	int r = 0;
-	int *p;
-	do {
-		p = (int *) malloc(r * 8192);
-		free(p);
-		r++;
-	} while ((p) && (r < 512));
-
-	int t = -1;
-	void *block[1024];
-	do {
-		t++;
-		block[t] = (int *) malloc(4096);
-	} while ((t < 1024) && (block[t]));
-
-	for (int q = 0; q < t; q++) {
-		free(block[q]);
-	}
-
-	printf("Free: %dK, Largest: %dK\n", t * 4, r * 8);
+bool getIsDisplayMode8Bit() {
+	return displayModeIs8Bit;
 }
 
+void setIcon(int num, int x, int y, int imageNum, int flags, bool enable) {
+	sprites[num].attribute[0] = ATTR0_BMP | (enable ? (y & 0xFF) : 192) | (!enable ? ATTR0_DISABLED : 0);
+	sprites[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
+	sprites[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
+}
 
-void addIndyFightingKeys() {
-	OSystem_DS *system = OSystem_DS::instance();
-	Common::Event event;
-
-	event.type = Common::EVENT_KEYDOWN;
-	event.kbd.flags = 0;
-
-	if ((getKeysDown() & KEY_L)) {
-		indyFightRight = false;
-	}
-
-	if ((getKeysDown() & KEY_R)) {
-		indyFightRight = true;
-	}
-
-	if ((getKeysChanged() & KEY_UP)) {
-		event.type = getKeyEvent(KEY_UP);
-		event.kbd.keycode = Common::KEYCODE_8;
-		event.kbd.ascii = '8';
-		system->addEvent(event);
-	}
-	if ((getKeysChanged() & KEY_LEFT)) {
-		event.type = getKeyEvent(KEY_LEFT);
-		event.kbd.keycode = Common::KEYCODE_4;
-		event.kbd.ascii = '4';
-		system->addEvent(event);
-	}
-	if ((getKeysChanged() & KEY_RIGHT)) {
-		event.type = getKeyEvent(KEY_RIGHT);
-		event.kbd.keycode = Common::KEYCODE_6;
-		event.kbd.ascii = '6';
-		system->addEvent(event);
-	}
-	if ((getKeysChanged() & KEY_DOWN)) {
-		event.type = getKeyEvent(KEY_DOWN);
-		event.kbd.keycode = Common::KEYCODE_2;
-		event.kbd.ascii = '2';
-		system->addEvent(event);
-	}
-
-	if (indyFightRight) {
+void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable) {
+	spritesMain[num].attribute[0] = ATTR0_BMP | (y & 0xFF) | (!enable ? ATTR0_DISABLED : 0);
+	spritesMain[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
+	spritesMain[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
+}
 
-		if ((getKeysChanged() & KEY_X)) {
-			event.type = getKeyEvent(KEY_X);
-			event.kbd.keycode = Common::KEYCODE_9;
-			event.kbd.ascii = '9';
-			system->addEvent(event);
-		}
-		if ((getKeysChanged() & KEY_A)) {
-			event.type = getKeyEvent(KEY_A);
-			event.kbd.keycode = Common::KEYCODE_6;
-			event.kbd.ascii = '6';
-			system->addEvent(event);
-		}
-		if ((getKeysChanged() & KEY_B)) {
-			event.type = getKeyEvent(KEY_B);
-			event.kbd.keycode = Common::KEYCODE_3;
-			event.kbd.ascii = '3';
-			system->addEvent(event);
+void updateMouse() {
+	if ((cursorEnable) && (mouseCursorVisible)) {
+		if (gameScreenSwap && touchPadStyle) {
+			setIcon(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
+			setIconMain(3, 0, 0, 0, 0, false);
+		} else {
+			setIconMain(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
+			setIcon(3, 0, 0, 0, 0, false);
 		}
-
 	} else {
-
-		if ((getKeysChanged() & KEY_X)) {
-			event.type = getKeyEvent(KEY_X);
-			event.kbd.keycode = Common::KEYCODE_7;
-			event.kbd.ascii = '7';
-			system->addEvent(event);
-		}
-		if ((getKeysChanged() & KEY_A)) {
-			event.type = getKeyEvent(KEY_A);
-			event.kbd.keycode = Common::KEYCODE_4;
-			event.kbd.ascii = '4';
-			system->addEvent(event);
-		}
-		if ((getKeysChanged() & KEY_B)) {
-			event.type = getKeyEvent(KEY_B);
-			event.kbd.keycode = Common::KEYCODE_1;
-			event.kbd.ascii = '1';
-			system->addEvent(event);
-		}
-
-	}
-
-
-	if ((getKeysChanged() & KEY_Y)) {
-		event.type = getKeyEvent(KEY_Y);
-		event.kbd.keycode = Common::KEYCODE_5;
-		event.kbd.ascii = '5';
-		system->addEvent(event);
+		setIconMain(3, 0, 0, 0, 0, false);
+		setIcon(3, 0, 0, 0, 0, false);
 	}
 }
 
+void warpMouse(int penX, int penY) {
+	storedMouseX = ((penX - touchX) << 8) / touchScX;
+	storedMouseY = ((penY - touchY) << 8) / touchScY;
+	updateMouse();
+}
 
-void setKeyboardEnable(bool en) {
-	if (en == keyboardEnable) return;
-	keyboardEnable = en;
-	u16 *backupBank = (u16 *) 0x6040000;
-
-	if (keyboardEnable) {
-
-
-		DS::drawKeyboard(1, 15, backupBank);
-
+void setMainScreenScroll(int x, int y) {
+		REG_BG3X = x + (((frameCount & 1) == 0)? 64: 0);
+		REG_BG3Y = y;
 
-		REG_BG1CNT_SUB = BG_TILE_BASE(1) | BG_MAP_BASE(15);
+		if ((!gameScreenSwap) || (touchPadStyle)) {
+			touchX = x >> 8;
+			touchY = y >> 8;
+		}
+}
 
-		if (displayModeIs8Bit) {
-			REG_DISPCNT_SUB |= DISPLAY_BG1_ACTIVE;	// Turn on keyboard layer
-			REG_DISPCNT_SUB &= ~DISPLAY_BG3_ACTIVE;	// Turn off game layer
+void setMainScreenScale(int x, int y) {
+		if (isCpuScalerEnabled() && (x==320)) {
+			REG_BG3PA = 256;
+			REG_BG3PB = 0;
+			REG_BG3PC = 0;
+			REG_BG3PD = y;
 		} else {
-			REG_DISPCNT_SUB |= DISPLAY_BG1_ACTIVE;	// Turn on keyboard layer
-			REG_DISPCNT_SUB &= ~DISPLAY_BG0_ACTIVE;	// Turn off console layer
+			REG_BG3PA = x;
+			REG_BG3PB = 0;
+			REG_BG3PC = 0;
+			REG_BG3PD = y;
 		}
 
-		// Ensure the keyboard is on the lower screen
-		lcdMainOnTop();
-
-
-	} else {
-
-		DS::releaseAllKeys();
-		// Restore the palette that the keyboard has used
-		for (int r = 0; r < 256; r++) {
-			BG_PALETTE_SUB[r] = BG_PALETTE[r];
+		if ((!gameScreenSwap) || (touchPadStyle)) {
+			touchScX = x;
+			touchScY = y;
 		}
+}
 
-		if (displayModeIs8Bit) {
-			// Copy the sub screen VRAM from the top screen - they should always be
-			// the same.
-			u16 *buffer = get8BitBackBuffer();
-			s32 stride = get8BitBackBufferStride();
-
-			for (int y = 0; y < gameHeight; y++) {
-				for (int x = 0; x < gameWidth; x++) {
-					BG_GFX_SUB[y * 256 + x] = buffer[(y * (stride / 2)) + x];
-				}
-			}
-
-			REG_DISPCNT_SUB &= ~DISPLAY_BG1_ACTIVE;	// Turn off keyboard layer
-			REG_DISPCNT_SUB |= DISPLAY_BG3_ACTIVE;	// Turn on game layer
-		} else {
-			REG_DISPCNT_SUB &= ~DISPLAY_BG1_ACTIVE;	// Turn off keyboard layer
-			REG_DISPCNT_SUB |= DISPLAY_BG0_ACTIVE;	// Turn on console layer
+void setZoomedScreenScroll(int x, int y, bool shake) {
+		if ((gameScreenSwap) && (!touchPadStyle)) {
+			touchX = x >> 8;
+			touchY = y >> 8;
 		}
 
-		// Restore the screens so they're the right way round
-		if (gameScreenSwap) {
-			lcdMainOnTop();
-		} else {
-			lcdMainOnBottom();
-		}
-	}
-}
 
-bool getKeyboardEnable() {
-	return keyboardEnable;
+		REG_BG3X_SUB = x + ((shake && (frameCount & 1) == 0)? 64: 0);
+		REG_BG3Y_SUB = y;
 }
 
-bool getIsDisplayMode8Bit() {
-	return displayModeIs8Bit;
+void setZoomedScreenScale(int x, int y) {
+		if ((gameScreenSwap) && (!touchPadStyle)) {
+			touchScX = x;
+			touchScY = y;
+		}
+
+		REG_BG3PA_SUB = x;
+		REG_BG3PB_SUB = 0;
+		REG_BG3PC_SUB = 0;
+		REG_BG3PD_SUB = y;
 }
 
-void doScreenTapMode(OSystem_DS *system) {
-	Common::Event event;
-	static bool left = false, right = false;
+Common::Point transformPoint(uint16 x, uint16 y) {
+	x = ((x * touchScX) >> 8) + touchX;
+	x = CLIP<uint16>(x, 0, gameWidth  - 1);
 
-	if (left) {
-		event.type = Common::EVENT_LBUTTONUP;
-		event.mouse = Common::Point(getPenX(), getPenY());
-		system->addEvent(event);
-		left = false;
-	}
+	y = ((y * touchScY) >> 8) + touchY;
+	y = CLIP<uint16>(y, 0, gameHeight - 1);
 
-	if (right) {
-		event.type = Common::EVENT_RBUTTONUP;
-		event.mouse = Common::Point(getPenX(), getPenY());
-		system->addEvent(event);
-		right = false;
-	}
+	return Common::Point(x, y);
+}
 
+void VBlankHandler(void) {
+	frameCount++;
 
-	if (tapComplete == 1) {
-		event.type = Common::EVENT_LBUTTONDOWN;
-		event.mouse = Common::Point(getPenX(), getPenY());
-		system->addEvent(event);
-		tapComplete = 0;
-		left = true;
-	} else if (tapComplete == 2) {
-		event.type = Common::EVENT_RBUTTONDOWN;
-		event.mouse = Common::Point(getPenX(), getPenY());
-		system->addEvent(event);
-		tapComplete = 0;
-		right = true;
+	if (callback) {
+		callbackTimer -= FRAME_TIME;
 	}
 
-	if (!isScrollingWithDPad()) {
-
-		if (getKeysDown() & KEY_LEFT) {
-			event.type = Common::EVENT_LBUTTONDOWN;
-			event.mouse = Common::Point(getPenX(), getPenY());
-			system->addEvent(event);
-		}
-
-		if (getKeysReleased() & KEY_LEFT) {
-			event.type = Common::EVENT_LBUTTONUP;
-			event.mouse = Common::Point(getPenX(), getPenY());
-			system->addEvent(event);
-		}
+	int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
+	int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
 
 
-		if (getKeysDown() & KEY_RIGHT) {
-			event.type = Common::EVENT_RBUTTONDOWN;
-			event.mouse = Common::Point(getPenX(), getPenY());
-			system->addEvent(event);
-		}
+	if (twoHundredPercentFixedScale) {
+		subScreenWidth = 256 >> 1;
+		subScreenHeight = 192 >> 1;
+	} else {
+		subScreenWidth = (256 * subScreenScale) >> 8;
+		subScreenHeight = (192 * subScreenScale) >> 8;
 
-		if (getKeysReleased() & KEY_RIGHT) {
-			event.type = Common::EVENT_RBUTTONUP;
-			event.mouse = Common::Point(getPenX(), getPenY());
-			system->addEvent(event);
+		if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
+			subScreenWidth = 256;
+			subScreenHeight = 192;
+		} else if ( ((subScreenWidth) > 128 - 8) && ((subScreenWidth) < 128 + 8) ) {
+			subScreenWidth = 128;
+			subScreenHeight = 96;
+		} else if (subScreenWidth > 256) {
+			subScreenWidth = 320;
+			subScreenHeight = 200;
 		}
 	}
 
-	event.type = Common::EVENT_MOUSEMOVE;
-	event.mouse = Common::Point(getPenX(), getPenY());
-	system->addEvent(event);
-}
 
-void doButtonSelectMode(OSystem_DS *system) {
-	Common::Event event;
+	subScTargetX = xCenter - ((subScreenWidth  >> 1) << 8);
+	subScTargetY = yCenter - ((subScreenHeight >> 1) << 8);
 
+	subScTargetX = CLIP(subScTargetX, 0, (gameWidth  - subScreenWidth)  << 8);
+	subScTargetY = CLIP(subScTargetY, 0, (gameHeight - subScreenHeight) << 8);
 
-	if (!isScrollingWithDPad()) {
-		event.type = Common::EVENT_MOUSEMOVE;
-		event.mouse = Common::Point(getPenX(), getPenY());
-		system->addEvent(event);
-	}
+	subScX += (subScTargetX - subScX) >> 2;
+	subScY += (subScTargetY - subScY) >> 2;
 
-	if (getPenReleased() && (leftButtonDown || rightButtonDown)) {
-		if (leftButtonDown) {
-			event.type = Common::EVENT_LBUTTONUP;
-			leftButtonDown = false;
-			event.mouse = Common::Point(getPenX(), getPenY());
-			system->addEvent(event);
-		} else if (rightButtonDown) {
-			event.type = Common::EVENT_RBUTTONUP;
-			rightButtonDown = false;
-			event.mouse = Common::Point(getPenX(), getPenY());
-			system->addEvent(event);
-		}
-	}
+	if (displayModeIs8Bit) {
 
+		if (!scaledMode) {
 
-	if ((mouseMode != MOUSE_HOVER) || (!displayModeIs8Bit)) {
-		if (getPenDown() && !isScrollingWithDPad()) {
-			if (mouseMode == MOUSE_LEFT) {
-				event.type = Common::EVENT_LBUTTONDOWN;
-				leftButtonDown = true;
-			} else {
-				event.type = Common::EVENT_RBUTTONDOWN;
-				rightButtonDown = true;
+			if (scX + 256 > gameWidth - 1) {
+				scX = gameWidth - 1 - 256;
 			}
 
-			event.mouse = Common::Point(getPenX(), getPenY());
-			system->addEvent(event);
-		}
-
-	} else {
-		// In hover mode, D-pad left and right click the mouse when the pen is on the screen
-
-		if (getPenHeld()) {
-			if (getKeysDown() & KEY_LEFT) {
-				event.type = Common::EVENT_LBUTTONDOWN;
-				event.mouse = Common::Point(getPenX(), getPenY());
-				system->addEvent(event);
-			}
-			if (getKeysReleased() & KEY_LEFT) {
-				event.type = Common::EVENT_LBUTTONUP;
-				event.mouse = Common::Point(getPenX(), getPenY());
-				system->addEvent(event);
+			if (scX < 0) {
+				scX = 0;
 			}
 
-
-			if (getKeysDown() & KEY_RIGHT) {
-				event.type = Common::EVENT_RBUTTONDOWN;
-				event.mouse = Common::Point(getPenX(), getPenY());
-				system->addEvent(event);
-			}
-			if (getKeysReleased() & KEY_RIGHT) {
-				event.type = Common::EVENT_RBUTTONUP;
-				event.mouse = Common::Point(getPenX(), getPenY());
-				system->addEvent(event);
+			if (scY + 192 > gameHeight - 1) {
+				scY = gameHeight - 1 - 192;
 			}
-		}
-	}
 
-	if (!isScrollingWithDPad() && !getIndyFightState() && !getKeyboardEnable()) {
-
-		if (!getPenHeld() || (mouseMode != MOUSE_HOVER)) {
-			if (getKeysDown() & KEY_LEFT) {
-				mouseMode = MOUSE_LEFT;
+			if (scY < 0) {
+				scY = 0;
 			}
 
-			if (rightButtonDown) {
-				event.mouse = Common::Point(getPenX(), getPenY());
-				event.type = Common::EVENT_RBUTTONUP;
-				system->addEvent(event);
-				rightButtonDown = false;
-			}
-
-
-			if (getKeysDown() & KEY_RIGHT) {
-				if ((s_currentGame->control != CONT_SCUMM_SAMNMAX) && (s_currentGame->control != CONT_FUTURE_WARS) && (s_currentGame->control != CONT_GOBLINS)) {
-					mouseMode = MOUSE_RIGHT;
-				} else {
-					// If we're playing sam and max, click and release the right mouse
-					// button to change verb
-
-					if (s_currentGame->control == CONT_FUTURE_WARS) {
-						event.mouse = Common::Point(320 - 128, 200 - 128);
-						event.type = Common::EVENT_MOUSEMOVE;
-						system->addEvent(event);
-					} else {
-						event.mouse = Common::Point(getPenX(), getPenY());
-					}
-
-					rightButtonDown = true;
-
-
-					event.type = Common::EVENT_RBUTTONDOWN;
-					system->addEvent(event);
-				}
-			}
-
-
-
-			if (getKeysDown() & KEY_UP) {
-				mouseMode = MOUSE_HOVER;
-			}
-		}
-	}
-}
-
-void addEventsToQueue() {
-	#ifdef HEAVY_LOGGING
-	printf("addEventsToQueue\n");
-	#endif
-	OSystem_DS *system = OSystem_DS::instance();
-	Common::Event event;
-
-	if (system->isEventQueueEmpty()) {
-
-		if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
-			memoryReport();
-		}
-
-		if (displayModeIs8Bit) {
-
-			if (!indyFightState) {
-
-				if (!isScrollingWithDPad() && (getKeysDown() & KEY_B)) {
-					if (s_currentGame->control == CONT_AGI) {
-						event.kbd.keycode = Common::KEYCODE_RETURN;
-						event.kbd.ascii = 13;
-						event.kbd.flags = 0;
-					} else {
-						event.kbd.keycode = Common::KEYCODE_ESCAPE;
-						event.kbd.ascii = 27;
-						event.kbd.flags = 0;
-					}
-
-					event.type = Common::EVENT_KEYDOWN;
-					system->addEvent(event);
-
-					event.type = Common::EVENT_KEYUP;
-					system->addEvent(event);
-				}
-
-			}
-
-
-
-			if ((!getIndyFightState()) && (getKeysDown() & KEY_Y)) {
-				consoleEnable = !consoleEnable;
-				printf("Console enable: %d\n", consoleEnable);
-				if (displayModeIs8Bit) {
-					displayMode8Bit();
-				} else {
-					displayMode16Bit();
-				}
-			}
-
-			if ((getKeyboardEnable())) {
-				event.kbd.flags = 0;
-
-				bool down = getKeysDown() & (KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN);
-				bool release = getKeysReleased() & (KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN);
-				bool shoulders = getKeysHeld() & (KEY_L | KEY_R);
-
-				if ( (down && (!shoulders)) || release) {
-
-					if (getKeysChanged() & KEY_LEFT) {
-						event.kbd.keycode = Common::KEYCODE_LEFT;
-						event.kbd.ascii = 0;
-						event.type = getKeyEvent(KEY_LEFT);
-						system->addEvent(event);
-					}
-
-					if (getKeysChanged() & KEY_RIGHT) {
-						event.kbd.keycode = Common::KEYCODE_RIGHT;
-						event.kbd.ascii = 0;
-						event.type = getKeyEvent(KEY_RIGHT);
-						system->addEvent(event);
-					}
-
-					if (getKeysChanged() & KEY_UP) {
-						event.kbd.keycode = Common::KEYCODE_UP;
-						event.kbd.ascii = 0;
-						event.type = getKeyEvent(KEY_UP);
-						system->addEvent(event);
-					}
-
-					if (getKeysChanged() & KEY_DOWN) {
-						event.kbd.keycode = Common::KEYCODE_DOWN;
-						event.kbd.ascii = 0;
-						event.type = getKeyEvent(KEY_DOWN);
-						system->addEvent(event);
-					}
-				}
-
-			}
-
-			if (!isScrollingWithDPad() && !getIndyFightState() && !getKeyboardEnable()) {
-
-				if ((getKeysDown() & KEY_A) && (!indyFightState)) {
-					gameScreenSwap = !gameScreenSwap;
-
-					if (gameScreenSwap) {
-						lcdMainOnTop();
-					} else {
-						lcdMainOnBottom();
-					}
-
-				}
-			}
-
-
-			static int selectTimeDown = -1;
-			static const int SELECT_HOLD_TIME = 1000;
-
-			if (getKeysDown() & KEY_SELECT) {
-				selectTimeDown = getMillis();
-			}
-
-			if (selectTimeDown != -1) {
-				if (getKeysHeld() & KEY_SELECT) {
-					if (getMillis() - selectTimeDown >= SELECT_HOLD_TIME) {
-						// Hold select down for one second - show GMM
-						g_engine->openMainMenuDialog();
-					}
-				}
-
-				if (getKeysReleased() & KEY_SELECT) {
-					if (getMillis() - selectTimeDown < SELECT_HOLD_TIME) {
-						// Just pressed select - show DS options screen
-						showOptionsDialog();
-					}
-				}
-			}
-		}
-
-		if (!getIndyFightState() && !isScrollingWithDPad() && (getKeysDown() & KEY_X)) {
-			setKeyboardEnable(!keyboardEnable);
-		}
-
-		updateStatus();
-
-
-		if ((tapScreenClicks) && (getIsDisplayMode8Bit())) {
-			if ((!keyboardEnable) || (!isInsideKeyboard(penDownX, penDownY))) {
-				doScreenTapMode(system);
-			}
-		} else {
-			if (!keyboardEnable) {
-				doButtonSelectMode(system);
-			} else if ((!keyboardEnable) || (!isInsideKeyboard(penDownX, penDownY))) {
-				doScreenTapMode(system);
-			}
-		}
-
-
-		if (!keyboardEnable) {
-			if ((!isScrollingWithDPad() || (indyFightState)) && (displayModeIs8Bit)) {
-				// Controls specific to the control method
-
-				if (s_currentGame->control == CONT_SKY) {
-					// Extra controls for Beneath a Steel Sky
-					if ((getKeysDown() & KEY_DOWN)) {
-						penY = 0;
-						penX = 160;		// Show inventory by moving mouse onto top line
-					}
-				}
-
-				if (s_currentGame->control == CONT_AGI) {
-					// Extra controls for Leisure Suit Larry and KQ4
-					if ((getKeysHeld() & KEY_UP) && (getKeysHeld() & KEY_START)) {
-						printf("Cheat key!\n");
-						event.type = Common::EVENT_KEYDOWN;
-						event.kbd.keycode = (Common::KeyCode)'X';		// Skip age test in LSL
-						event.kbd.ascii = 'X';
-						event.kbd.flags = Common::KBD_ALT;
-						system->addEvent(event);
-
-						event.type = Common::EVENT_KEYUP;
-						system->addEvent(event);
-					}
-				}
-
-				if (s_currentGame->control == CONT_SIMON) {
-					// Extra controls for Simon the Sorcerer
-					if ((getKeysDown() & KEY_DOWN)) {
-						event.type = Common::EVENT_KEYDOWN;
-						event.kbd.keycode = Common::KEYCODE_F10;		// F10 or # - show hotspots
-						event.kbd.ascii = Common::ASCII_F10;
-						event.kbd.flags = 0;
-						system->addEvent(event);
-
-						event.type = Common::EVENT_KEYUP;
-						system->addEvent(event);
-					}
-				}
-
-				if (s_currentGame->control == CONT_SCUMM_ORIGINAL) {
-					// Extra controls for Scumm v1-5 games
-					if ((getKeysDown() & KEY_DOWN)) {
-						event.type = Common::EVENT_KEYDOWN;
-						event.kbd.keycode = Common::KEYCODE_PERIOD;		// Full stop - skips current dialogue line
-						event.kbd.ascii = '.';
-						event.kbd.flags = 0;
-						system->addEvent(event);
-
-						event.type = Common::EVENT_KEYUP;
-						system->addEvent(event);
-					}
-
-					if (indyFightState) {
-						addIndyFightingKeys();
-					}
-
-				}
-
-			}
-		}
-
-		if (!displayModeIs8Bit) {
-			// Front end controls
-
-			if (leftHandedSwap(getKeysChanged()) & KEY_UP) {
-				event.type = getKeyEvent(leftHandedSwap(KEY_UP));
-				event.kbd.keycode = Common::KEYCODE_UP;
-				event.kbd.ascii = 0;
-				event.kbd.flags = 0;
-				system->addEvent(event);
-			}
-
-			if (leftHandedSwap(getKeysChanged()) & KEY_DOWN) {
-				event.type = getKeyEvent(leftHandedSwap(KEY_DOWN));
-				event.kbd.keycode = Common::KEYCODE_DOWN;
-				event.kbd.ascii = 0;
-				event.kbd.flags = 0;
-				system->addEvent(event);
-			}
-
-			if (leftHandedSwap(getKeysDown()) & KEY_A) {
-				event.type = Common::EVENT_KEYDOWN;
-				event.kbd.keycode = Common::KEYCODE_RETURN;
-				event.kbd.ascii = 0;
-				event.kbd.flags = 0;
-				system->addEvent(event);
-
-				event.type = Common::EVENT_KEYUP;
-				system->addEvent(event);
-			}
-
-		}
-
-
-		if ((getKeysChanged() & KEY_START)) {
-			event.kbd.flags = 0;
-			event.type = getKeyEvent(KEY_START);
-			if (s_currentGame->control == CONT_FUTURE_WARS) {
-				event.kbd.keycode = Common::KEYCODE_F10;
-				event.kbd.ascii = Common::ASCII_F10;
-			} else if (s_currentGame->control == CONT_GOBLINS) {
-				event.kbd.keycode = Common::KEYCODE_F1;
-				event.kbd.ascii = Common::ASCII_F1;
-			} else if (s_currentGame->control == CONT_AGI) {
-				event.kbd.keycode = Common::KEYCODE_ESCAPE;
-				event.kbd.ascii = 27;
-			} else {
-				event.kbd.keycode = Common::KEYCODE_F5;		// F5
-				event.kbd.ascii = Common::ASCII_F5;
-			}
-			system->addEvent(event);
-		}
-
-
-		if (keyboardEnable) {
-			DS::addKeyboardEvents();
-		}
-
-		consumeKeys();
-		consumePenEvents();
-	}
-}
-
-
-
-void triggerIcon(int imageNum) {
-	triggeredIcon = imageNum;
-	triggeredIconTimeout = 120;
-}
-
-
-void setIcon(int num, int x, int y, int imageNum, int flags, bool enable) {
-	sprites[num].attribute[0] = ATTR0_BMP | (enable ? (y & 0xFF) : 192) | (!enable ? ATTR0_DISABLED : 0);
-	sprites[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
-	sprites[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
-}
-
-void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable) {
-	spritesMain[num].attribute[0] = ATTR0_BMP | (y & 0xFF) | (!enable ? ATTR0_DISABLED : 0);
-	spritesMain[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
-	spritesMain[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
-}
-
-void updateStatus() {
-	int offs;
-
-	if (displayModeIs8Bit) {
-		if (!tapScreenClicks) {
-			switch (mouseMode) {
-			case MOUSE_LEFT:
-				offs = 1;
-				break;
-			case MOUSE_RIGHT:
-				offs = 2;
-				break;
-			case MOUSE_HOVER:
-				offs = 0;
-				break;
-			default:
-				// Nothing!
-				offs = 0;
-				break;
-			}
-
-			setIcon(0, 208, 150, offs, 0, true);
-		}
-
-		if (indyFightState) {
-			setIcon(1, (190 - 32), 150, 3, (indyFightRight ? 0 : ATTR1_FLIP_X), true);
-		}
-
-		if (triggeredIconTimeout > 0) {
-			triggeredIconTimeout--;
-			setIcon(4, 16, 150, triggeredIcon, 0, true);
-		} else {
-			setIcon(4, 0, 0, 0, 0, false);
-		}
-
-	} else {
-		setIcon(0, 0, 0, 0, 0, false);
-		setIcon(1, 0, 0, 0, 0, false);
-		setIcon(2, 0, 0, 0, 0, false);
-		setIcon(3, 0, 0, 0, 0, false);
-		setIcon(4, 0, 0, 0, 0, false);
-	}
-
-	if ((keyboardIcon) && (!keyboardEnable) && (!displayModeIs8Bit)) {
-		setIconMain(0, 0, 160, 4, 0, true);
-	} else {
-		setIconMain(0, 0, 0, 0, 0, false);
-	}
-
-}
-
-void setMainScreenScroll(int x, int y) {
-		REG_BG3X = x + (((frameCount & 1) == 0)? 64: 0);
-		REG_BG3Y = y;
-
-		if ((!gameScreenSwap) || (touchPadStyle)) {
-			touchX = x >> 8;
-			touchY = y >> 8;
-		}
-}
-
-void setMainScreenScale(int x, int y) {
-		if (isCpuScalerEnabled() && (x==320)) {
-			REG_BG3PA = 256;
-			REG_BG3PB = 0;
-			REG_BG3PC = 0;
-			REG_BG3PD = y;
-		} else {
-			REG_BG3PA = x;
-			REG_BG3PB = 0;
-			REG_BG3PC = 0;
-			REG_BG3PD = y;
-		}
-
-		if ((!gameScreenSwap) || (touchPadStyle)) {
-			touchScX = x;
-			touchScY = y;
-		}
-}
-
-void setZoomedScreenScroll(int x, int y, bool shake) {
-		if ((gameScreenSwap) && (!touchPadStyle)) {
-			touchX = x >> 8;
-			touchY = y >> 8;
-		}
-
-
-		REG_BG3X_SUB = x + ((shake && (frameCount & 1) == 0)? 64: 0);
-		REG_BG3Y_SUB = y;
-}
-
-void setZoomedScreenScale(int x, int y) {
-		if ((gameScreenSwap) && (!touchPadStyle)) {
-			touchScX = x;
-			touchScY = y;
-		}
-
-		REG_BG3PA_SUB = x;
-		REG_BG3PB_SUB = 0;
-		REG_BG3PC_SUB = 0;
-		REG_BG3PD_SUB = y;
-}
-
-void VBlankHandler(void) {
-	if ((!gameScreenSwap) && !isScrollingWithDPad()) {
-		if (s_currentGame) {
-			if (s_currentGame->control != CONT_SCUMM_SAMNMAX) {
-				if (getPenHeld() && (getPenY() < SCUMM_GAME_HEIGHT)) {
-					setTopScreenTarget(getPenX(), getPenY());
-				}
-			} else {
-				if (getPenHeld()) {
-					setTopScreenTarget(getPenX(), getPenY());
-				}
-			}
-		}
-	}
-
-
-	penUpdate();
-	keysUpdate();
-
-
-	frameCount++;
-
-	if ((cursorEnable) && (mouseCursorVisible)) {
-		storedMouseX = penX;
-		storedMouseY = penY;
-
-		if (gameScreenSwap && touchPadStyle) {
-			setIcon(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
-			setIconMain(3, 0, 0, 0, 0, false);
-		} else {
-			setIconMain(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
-			setIcon(3, 0, 0, 0, 0, false);
-		}
-	} else {
-		setIconMain(3, 0, 0, 0, 0, false);
-		setIcon(3, 0, 0, 0, 0, false);
-	}
-
-
-	if (callback) {
-		callbackTimer -= FRAME_TIME;
-	}
-
-	if (isScrollingWithDPad()) {
-
-		if ((!dragging) && (getPenHeld()) && (penDownFrames > 5)) {
-			dragging = true;
-			dragStartX = penX;
-			dragStartY = penY;
-
-			if (gameScreenSwap) {
-				dragScX = subScTargetX;
-				dragScY = subScTargetY;
-			} else {
-				dragScX = scX;
-				dragScY = scY;
-			}
-
-
-		}
-
-		if ((dragging) && (!getPenHeld())) {
-			dragging = false;
-		}
-
-		if (dragging) {
-
-			if (gameScreenSwap) {
-				subScTargetX = dragScX + ((dragStartX - penX) << 8);
-				subScTargetY = dragScY + ((dragStartY - penY) << 8);
-			} else {
-				scX = dragScX + ((dragStartX - penX));
-				scY = dragScY + ((dragStartY - penY));
-			}
-		}
-	}
-
-	static int ratio = (320 << 8) / SCUMM_GAME_WIDTH;
-
-	bool zooming = false;
-
-	if (isScrollingWithDPad()) {
-		if ((getKeysHeld() & KEY_A) && (subScreenScale < ratio)) {
-			subScreenScale += 1;
-			zooming = true;
-		}
-
-		if ((getKeysHeld() & KEY_B) && (subScreenScale > 128)) {
-			subScreenScale -=1;
-			zooming = true;
-		}
-	}
-
-
-	int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
-	int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
-
-
-	if (twoHundredPercentFixedScale) {
-		subScreenWidth = 256 >> 1;
-		subScreenHeight = 192 >> 1;
-	} else {
-		subScreenWidth = (256 * subScreenScale) >> 8;
-		subScreenHeight = (192 * subScreenScale) >> 8;
-
-		if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
-			subScreenWidth = 256;
-			subScreenHeight = 192;
-			if (zooming) {
-				subScX = subScTargetX;
-				subScY = subScTargetY;
-			 	triggerIcon(5);
-			}
-		} else if ( ((subScreenWidth) > 128 - 8) && ((subScreenWidth) < 128 + 8) ) {
-			subScreenWidth = 128;
-			subScreenHeight = 96;
-			if (zooming) {
-				subScX = subScTargetX;
-				subScY = subScTargetY;
-				triggerIcon(6);
-			}
-		} else if (subScreenWidth > 256) {
-			subScreenWidth = 320;
-			subScreenHeight = 200;
-			if (zooming) {
-				subScX = subScTargetX;
-				subScY = subScTargetY;
-				triggerIcon(7);
-			}
-		}
-	}
-
-
-	subScTargetX = xCenter - ((subScreenWidth  >> 1) << 8);
-	subScTargetY = yCenter - ((subScreenHeight >> 1) << 8);
-
-	subScTargetX = CLIP(subScTargetX, 0, (gameWidth  - subScreenWidth)  << 8);
-	subScTargetY = CLIP(subScTargetY, 0, (gameHeight - subScreenHeight) << 8);
-
-	subScX += (subScTargetX - subScX) >> 2;
-	subScY += (subScTargetY - subScY) >> 2;
-
-	if (displayModeIs8Bit) {
-
-		if (isScrollingWithDPad()) {
-
-			int offsX = 0, offsY = 0;
-
-
-			if ((getKeysHeld() & KEY_LEFT)) {
-				offsX -= 2;
-			}
-
-			if ((getKeysHeld() & KEY_RIGHT)) {
-				offsX += 2;
-			}
-
-			if ((getKeysHeld() & KEY_UP)) {
-				offsY -= 2;
-			}
-
-			if ((getKeysHeld() & KEY_DOWN)) {
-				offsY += 2;
-			}
-
-			if (((gameScreenSwap) && (getKeysHeld() & KEY_L)) || ((!gameScreenSwap) && (getKeysHeld() & KEY_R))) {
-				subScTargetX += offsX << 8;
-				subScTargetY += offsY << 8;
-			} else {
-				scX += offsX;
-				scY += offsY;
-			}
-		}
-
-		if (!scaledMode) {
-
-			if (scX + 256 > gameWidth - 1) {
-				scX = gameWidth - 1 - 256;
-			}
-
-			if (scX < 0) {
-				scX = 0;
-			}
-
-			if (scY + 192 > gameHeight - 1) {
-				scY = gameHeight - 1 - 192;
-			}
-
-			if (scY < 0) {
-				scY = 0;
-			}
-
-			setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
-			setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
+			setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
+			setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
 
 
 			setMainScreenScroll((scX << 8) + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
@@ -1772,17 +723,6 @@ void VBlankHandler(void) {
 		setMainScreenScale(320, 256);		// 1:1 scale
 	}
 
-	// Enable on screen keyboard when pen taps icon
-	if ((keyboardIcon) && (penX < 32) && (penY > 160) && (penHeld)) {
-		setKeyboardEnable(true);
-	}
-
-	if (keyboardEnable) {
-		if (DS::getKeyboardClosed()) {
-			setKeyboardEnable(false);
-		}
-	}
-
 	updateOAM();
 }
 
@@ -1825,27 +765,7 @@ void setTopScreenTarget(int x, int y) {
 	subScTargetY <<=8;
 }
 
-void uploadSpriteGfx() {
-	vramSetBankD(VRAM_D_SUB_SPRITE);
-	vramSetBankE(VRAM_E_MAIN_SPRITE);
-
-	// Convert texture from 24bit 888 to 16bit 1555, remembering to set top bit!
-	const u8 *srcTex = (const u8 *) ::icons_raw;
-	for (int r = 32 * 256 ; r >= 0; r--) {
-		SPRITE_GFX_SUB[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10);
-		SPRITE_GFX[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10);
-	}
-
-}
-
 void initHardware() {
-	penInit();
-	indyFightState = false;
-	indyFightRight = true;
-
-	lastEventFrame = 0;
-	mouseMode = MOUSE_LEFT;
-
 	powerOn(POWER_ALL);
 	vramSetBankD(VRAM_D_SUB_SPRITE);
 	vramSetBankE(VRAM_E_MAIN_SPRITE);
@@ -1898,327 +818,12 @@ void initHardware() {
 	// If the software scaler's back buffer has not been allocated, do it now
 	scalerBackBuffer = (u8 *) malloc(320 * 256);
 
-	uploadSpriteGfx();
-
 	// This is a bodge to get around the fact that the cursor is turned on before it's image is set
 	// during startup in Sam & Max.  This bodge moves the cursor offscreen so it is not seen.
 	sprites[1].attribute[1] = ATTR1_SIZE_64 | 192;
 
 }
 
-
-
-
-void setKeyboardIcon(bool enable) {
-	keyboardIcon = enable;
-}
-
-bool getKeyboardIcon() {
-	return keyboardIcon;
-}
-
-
-////////////////////
-// Pen stuff
-////////////////////
-
-
-void penInit() {
-	penDown = false;
-	penHeld = false;
-	penReleased = false;
-	penDownLastFrame = false;
-	penDownSaved = false;
-	penReleasedSaved = false;
-	penDownFrames = 0;
-	consumeKeys();
-}
-
-void penUpdate() {
-
-	touchPosition touchPos;
-	touchRead(&touchPos);
-
-	bool penDownThisFrame = (keysCurrent() & KEY_TOUCH) && (touchPos.px > 0) && (touchPos.py > 0);
-	static bool moved = false;
-
-	if (( (tapScreenClicks) || getKeyboardEnable() ) && (getIsDisplayMode8Bit())) {
-
-
-		if ((tapTimeout >= 0)) {
-			tapTimeout++;
-
-			if (((tapTimeout > 15) || (tapCount == 2)) && (tapCount > 0)) {
-				tapComplete = tapCount;
-				tapCount = 0;
-			}
-		}
-
-
-
-		if ((penHeld) && (!penDownThisFrame)) {
-			if ((touchPadStyle) || (getKeyboardEnable() && (!isInsideKeyboard(penDownX, penDownY))) || (moved) || (tapCount == 1)) {
-				if ((penDownFrames > 0) && (penDownFrames < 6) && ((tapTimeout == -1) || (tapTimeout > 2))) {
-					tapCount++;
-					tapTimeout = 0;
-					moved = false;
-				}
-			}
-		}
-	}
-
-
-	if ( ((keyboardEnable) || (touchPadStyle)) && (getIsDisplayMode8Bit()) ) {
-		// Relative positioning mode
-
-
-		if ((penDownFrames > 0) ) {
-
-			if ((penHeld)) {
-
-				if (penDownThisFrame) {
-					if (penDownFrames >= 2) {
-
-						touchRead(&touchPos);
-						if ((!keyboardEnable) || (!isInsideKeyboard(touchPos.px, touchPos.py))) {
-							int diffX = touchPos.px - penDownX;
-							int diffY = touchPos.py - penDownY;
-
-							int speed = ABS(diffX) + ABS(diffY);
-
-							if ((ABS(diffX) < 35) && (ABS(diffY) < 35)) {
-
-								if (speed >= 8)	{
-									diffX *= ((speed >> 3) * touchPadSensitivity) >> 3;
-									diffY *= ((speed >> 3) * touchPadSensitivity) >> 3;
-								}
-
-								penX += diffX;
-								penY += diffY;
-
-								if (penX > 255) {
-									scX -= 255 - penX;
-									penX = 255;
-								}
-
-								if (penX < 0) {
-									scX -= -penX;
-									penX = 0;
-								}
-
-								if (penY > 191) {
-									scY += penY - 191;
-									penY = 191;
-								}
-
-								if (penY < 0) {
-									scY -= -penY;
-									penY = 0;
-								}
-							}
-						}
-						penDownX = touchPos.px;
-						penDownY = touchPos.py;
-
-					}
-				}
-
-			} else {
-				penDown = true;
-				penHeld = true;
-				penDownSaved = true;
-
-				// First frame, so save pen positions
-				if (penDownThisFrame) {
-					touchRead(&touchPos);
-					penDownX = touchPos.px;
-					penDownY = touchPos.py;
-				}
-			}
-		} else {
-			if (penHeld) {
-				penReleased = true;
-				penReleasedSaved = true;
-			} else {
-				penReleased = false;
-			}
-
-			penDown = false;
-			penHeld = false;
-		}
-
-
-	} else {	// Absolute positioning mode
-		if ((penDownFrames > 1)) {			// Is this right?  Dunno, but it works for me.
-
-			if ((penHeld)) {
-				penHeld = true;
-				penDown = false;
-			} else {
-				if (penDownFrames == 2) {
-					touchRead(&touchPos);
-					penDownX = touchPos.px;
-					penDownY = touchPos.py;
-				}
-				penDown = true;
-				penHeld = true;
-				penDownSaved = true;
-			}
-
-			touchRead(&touchPos);
-			if ((keysCurrent() & KEY_TOUCH) && (touchPos.px > 0) && (touchPos.py > 0)) {
-				penX = touchPos.px + touchXOffset;
-				penY = touchPos.py + touchYOffset;
-				moved = true;
-			}
-
-
-		} else {
-			if (penHeld) {
-				penReleased = true;
-				penReleasedSaved = true;
-			} else {
-				penReleased = false;
-			}
-
-			penDown = false;
-			penHeld = false;
-		}
-	}
-
-
-
-	if ((keysCurrent() & KEY_TOUCH) || ((penDownFrames == 2)) ) {
-		penDownLastFrame = true;
-		penDownFrames++;
-	} else {
-		penDownLastFrame = false;
-		penDownFrames = 0;
-	}
-}
-
-int leftHandedSwap(int keys) {
-	// Start and select are unchanged
-	if (leftHandedMode) {
-		int result = keys & (~(KEY_R | KEY_L | KEY_Y | KEY_A | KEY_B | KEY_X | KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN));
-
-		if (keys & KEY_L) result |= KEY_R;
-		if (keys & KEY_R) result |= KEY_L;
-
-		if (keys & KEY_LEFT) result |= KEY_Y;
-		if (keys & KEY_RIGHT) result |= KEY_A;
-		if (keys & KEY_DOWN) result |= KEY_B;
-		if (keys & KEY_UP) result |= KEY_X;
-
-		if (keys & KEY_Y) result |= KEY_LEFT;
-		if (keys & KEY_A) result |= KEY_RIGHT;
-		if (keys & KEY_B) result |= KEY_DOWN;
-		if (keys & KEY_X) result |= KEY_UP;
-
-		return result;
-	} else {
-		return keys;
-	}
-}
-
-void keysUpdate() {
-	scanKeys();
-	keysDownSaved |= leftHandedSwap(keysDown());
-	keysReleasedSaved |= leftHandedSwap(keysUp());
-	keysChangedSaved = keysDownSaved | keysReleasedSaved;
-}
-
-int getKeysDown() {
-	return keysDownSaved;
-}
-
-int getKeysHeld() {
-	return leftHandedSwap(keysHeld());
-}
-
-int getKeysReleased() {
-	return keysReleasedSaved;
-}
-
-int getKeysChanged() {
-	return keysChangedSaved;
-}
-
-Common::EventType getKeyEvent(int key) {
-	if (getKeysDown() & key) {
-		return Common::EVENT_KEYDOWN;
-	} else if (getKeysReleased() & key) {
-		return Common::EVENT_KEYUP;
-	} else {
-		return (Common::EventType) 0;
-	}
-}
-
-void consumeKeys() {
-	keysDownSaved = 0;
-	keysReleasedSaved = 0;
-	keysChangedSaved = 0;
-}
-
-bool getPenDown() {
-	return penDownSaved;
-}
-
-bool getPenHeld() {
-	return penHeld;
-}
-
-bool getPenReleased() {
-	return penReleasedSaved;
-}
-
-void consumePenEvents() {
-	penDownSaved = false;
-	penReleasedSaved = false;
-}
-
-int getPenX() {
-	int x = ((penX * touchScX) >> 8) + touchX;
-	x = x < 0? 0: (x > gameWidth - 1? gameWidth - 1: x);
-
-	if (snapToBorder) {
-		if (x < 8) x = 0;
-		if (x > gameWidth - 8) x = gameWidth - 1;
-	}
-
-	return x;
-}
-
-int getPenY() {
-	int y = ((penY * touchScY) >> 8) + touchY;
-	y = y < 0? 0: (y > gameHeight - 1? gameHeight - 1: y);
-
-	if (snapToBorder) {
-		if (y < 8) y = 0;
-		if (y > gameHeight - 8) y = gameHeight - 1;
-	}
-
-	return y;
-}
-
-GLvector getPenPos() {
-	GLvector v;
-
-	v.x = (penX * inttof32(1)) / SCREEN_WIDTH;
-	v.y = (penY * inttof32(1)) / SCREEN_HEIGHT;
-
-	return v;
-}
-
-void setIndyFightState(bool st) {
-	indyFightState = st;
-	indyFightRight = true;
-}
-
-bool getIndyFightState() {
-	return indyFightState;
-}
-
 ///////////////////
 // Fast Ram
 ///////////////////
@@ -2259,31 +864,11 @@ int main(int argc, char **argv) {
 
 	defaultExceptionHandler();
 
-	printf("-------------------------------\n");
-	printf("ScummVM DS\n");
-	printf("Ported by Neil Millstone\n");
-	printf("Version %s ", gScummVMVersion);
-	printf("-------------------------------\n");
-	printf("L/R + D-pad/pen:    Scroll view\n");
-	printf("D-pad left:   Left mouse button\n");
-	printf("D-pad right: Right mouse button\n");
-	printf("D-pad up:           Hover mouse\n");
-	printf("B button:        Skip cutscenes\n");
-	printf("Select:         DS Options menu\n");
-	printf("Start:   Game menu (some games)\n");
-	printf("Y (in game):     Toggle console\n");
-	printf("X:              Toggle keyboard\n");
-	printf("A:                 Swap screens\n");
-	printf("L+R (on start):      Clear SRAM\n");
-	printf("\n");
-
 	if (!nitroFSInit(NULL)) {
 		printf("nitroFSInit failure: terminating\n");
 		return(1);
 	}
 
-	DS::updateStatus();
-
 	g_system = new OSystem_DS();
 	assert(g_system);
 
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index 9c8e1e664b..2fca93500d 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -30,45 +30,6 @@
 
 namespace DS {
 
-
-enum controlType {
-	CONT_SCUMM_ORIGINAL,
-	CONT_SCUMM_SAMNMAX,
-	CONT_SKY,
-	CONT_SIMON,
-	CONT_FUTURE_WARS,
-	CONT_AGI,
-	CONT_GOBLINS,
-	CONT_NIPPON
-};
-
-struct gameListType {
-	char 			gameId[16];
-	controlType 	control;
-};
-
-// Pen reading functions
-void 	penInit();
-void 	penUpdate();
-bool 	getPenDown();
-bool 	getPenHeld();
-bool 	getPenReleased();
-int 	getPenX();
-int 	getPenY();
-GLvector getPenPos();
-void 	consumePenEvents();
-controlType getControlType();
-
-// Pad reading
-int 	getKeysHeld();
-void 	keysUpdate();
-int 	getKeysDown();
-int 	getKeysReleased();
-void 	consumeKeys();
-int 	leftHandedSwap(int keys);
-void	setGameScreenSwap(bool enable);
-void	setSensitivity(int sensitivity);
-
 // Video
 void 	displayMode8Bit();											// Switch to 8-bit mode5
 void 	displayMode16Bit();										// Switch to 16-bit mode5
@@ -93,40 +54,25 @@ void 	setTimerCallback(OSystem_DS::TimerProc proc, int interval);		// Setup a ca
 int 	getMillis(bool skipRecord = false);								// Return the current runtime in milliseconds
 void 	doTimerCallback();												// Call callback function if required
 
-// Event queue
-void 	addEventsToQueue();
+// Events
 void 	VBlankHandler();
+Common::Point transformPoint(uint16 x, uint16 y);
 
 // Sam and Max Stuff
-void 	setGameID(int id);
 void 	setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX, int hotspotY);
 void	setShowCursor(bool enable);
 void	setMouseCursorVisible(bool visible);
+void	warpMouse(int penX, int penY);
+void	updateMouse();
 
 // Shake
 void 	setShakePos(int shakeXOffset, int shakeYOffset);
 
-// Reports
-void 	memoryReport();
-
-// Virtual keyboard
-void 	setKeyboardIcon(bool enable);
-bool 	getKeyboardIcon();
-void 	setKeyboardEnable(bool en);
-bool 	getKeyboardEnable();
-
 // Options
-void 	setLeftHanded(bool enable);
-void 	setTouchXOffset(int x);
-void 	setTouchYOffset(int y);
+void	setGameScreenSwap(bool enable);
 void 	setUnscaledMode(bool enable);
-void	setSnapToBorder(bool enable);
-void 	setIndyFightState(bool st);
-bool 	getIndyFightState();
 bool    isCpuScalerEnabled();
 void	setCpuScalerEnable(bool enable);
-void	setTrackPadStyleEnable(bool enable);
-void	setTapScreenClicksEnable(bool enable);
 
 // Display
 bool 	getIsDisplayMode8Bit();
@@ -138,8 +84,6 @@ int		getGameHeight();
 void	fastRamReset();
 void*	fastRamAlloc(int size);
 
-void 	exitGame();
-
 
 } // End of namespace DS
 
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp
index 5cac863736..8703330093 100644
--- a/backends/platform/ds/arm9/source/dsoptions.cpp
+++ b/backends/platform/ds/arm9/source/dsoptions.cpp
@@ -28,7 +28,6 @@
 #include "gui/widgets/tab.h"
 #include "osystem_ds.h"
 #include "engines/scumm/scumm.h"
-#include "touchkeyboard.h"
 #include "gui/widgets/popup.h"
 
 #include "common/translation.h"
@@ -58,43 +57,9 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 
 	_tab = new GUI::TabWidget(this, 10, 5, 300, 230 - 20 - 40 - 20);
 
-	_tab->addTab(_("Controls"), "");
+	_tab->addTab(_("Graphics"), "");
 
-	_leftHandedCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 130, 20, _("~L~eft handed mode"));
-	_indyFightCheckbox = new GUI::CheckboxWidget(_tab, 5, 20, 140, 20, _("~I~ndy fight controls"));
 	_showCursorCheckbox = new GUI::CheckboxWidget(_tab, 150, 5, 130, 20, _("Show mouse cursor"), U32String(), 0, 'T');
-	_snapToBorderCheckbox = new GUI::CheckboxWidget(_tab, 150, 20, 130, 20, _("Snap to edges"), U32String(), 0, 'T');
-
-	new GUI::StaticTextWidget(_tab, 20, 35, 100, 15, _("Touch X Offset"), Graphics::kTextAlignLeft);
-	_touchX = new GUI::SliderWidget(_tab, 130, 35, 130, 12, U32String("TODO: Add tooltip"), 1);
-	_touchX->setMinValue(-8);
-	_touchX->setMaxValue(+8);
-	_touchX->setValue(0);
-	_touchX->setFlags(GUI::WIDGET_CLEARBG);
-
-	new GUI::StaticTextWidget(_tab, 20, 50, 100, 15, _("Touch Y Offset"), Graphics::kTextAlignLeft);
-	_touchY = new GUI::SliderWidget(_tab, 130, 50, 130, 12, U32String("TODO: Add tooltip"), 2);
-	_touchY->setMinValue(-8);
-	_touchY->setMaxValue(+8);
-	_touchY->setValue(0);
-	_touchY->setFlags(GUI::WIDGET_CLEARBG);
-
-	new GUI::StaticTextWidget(_tab, 130 + 65 - 10, 65, 20, 15, U32String("0"), Graphics::kTextAlignCenter);
-	new GUI::StaticTextWidget(_tab, 130 + 130 - 10, 65, 20, 15, U32String("8"), Graphics::kTextAlignCenter);
-	new GUI::StaticTextWidget(_tab, 130 - 20, 65, 20, 15, U32String("-8"), Graphics::kTextAlignCenter);
-
-
-	_touchPadStyle = new GUI::CheckboxWidget(_tab, 5, 80, 270, 20, _("Use laptop trackpad-style cursor control"), U32String(), 0x20000001, 'T');
-	_screenTaps = new GUI::CheckboxWidget(_tab, 5, 95, 285, 20, _("Tap for left click, double tap right click"), U32String(), 0x20000002, 'T');
-
-	_sensitivityLabel = new GUI::StaticTextWidget(_tab, 20, 110, 110, 15, _("Sensitivity"), Graphics::kTextAlignLeft);
-	_sensitivity = new GUI::SliderWidget(_tab, 130, 110, 130, 12, U32String("TODO: Add tooltip"), 1);
-	_sensitivity->setMinValue(4);
-	_sensitivity->setMaxValue(16);
-	_sensitivity->setValue(8);
-	_sensitivity->setFlags(GUI::WIDGET_CLEARBG);
-
-	_tab->addTab(_("Graphics"), "");
 
 	new GUI::StaticTextWidget(_tab, 5, 67, 180, 15, _("Initial top screen scale:"), Graphics::kTextAlignLeft);
 
@@ -115,23 +80,11 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 	_gammaCorrection->setValue(0);
 
 
-
-	_tab->addTab(_("General"), "");
-
-	_disablePowerOff = new GUI::CheckboxWidget(_tab, 5, 20, 200, 20, _("Disable power off"), U32String(), 0, 'T');
-
 	_tab->setActiveTab(0);
 
 	_radioButtonMode = false;
 
-#ifdef DS_BUILD_D
-	_snapToBorderCheckbox->setState(confGetBool("snaptoborder", true));
-#else
-	_snapToBorderCheckbox->setState(confGetBool("snaptoborder", false));
-#endif
-
 	_showCursorCheckbox->setState(confGetBool("showcursor", true));
-	_leftHandedCheckbox->setState(confGetBool("lefthanded", false));
 	_unscaledCheckbox->setState(confGetBool("unscaled", false));
 
 
@@ -171,26 +124,10 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 		_gammaCorrection->setValue(0);
 	}
 
-	_disablePowerOff->setState(confGetBool("disablepoweroff", false));
-
     #ifdef ALLOW_CPU_SCALER
 	_cpuScaler->setState(confGetBool("cpu_scaler", false));
     #endif
 
-	_indyFightCheckbox->setState(DS::getIndyFightState());
-
-	_touchX->setValue(confGetInt("xoffset", 0));
-	_touchY->setValue(confGetInt("yoffset", 0));
-	_sensitivity->setValue(confGetInt("sensitivity", 8));
-
-	_touchPadStyle->setState(confGetBool("touchpad", false));
-	_screenTaps->setState(confGetBool("screentaps", false));
-
-	_screenTaps->setEnabled(!_touchPadStyle->getState());
-	_sensitivity->setEnabled(_touchPadStyle->getState());
-	_sensitivityLabel->setEnabled(_touchPadStyle->getState());
-	_sensitivityLabel->draw();
-
 	if (!_cpuScaler->getState() && !_unscaledCheckbox->getState()) {
 		_hardScaler->setState(true);
 	}
@@ -199,27 +136,18 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 }
 
 DSOptionsDialog::~DSOptionsDialog() {
-	DS::setIndyFightState(_indyFightCheckbox->getState());
 	ConfMan.flushToDisk();
 }
 
 void DSOptionsDialog::updateConfigManager() {
-	ConfMan.setBool("lefthanded", _leftHandedCheckbox->getState(), "ds");
 	ConfMan.setBool("unscaled", _unscaledCheckbox->getState(), "ds");
-	ConfMan.setBool("disablepoweroff", _disablePowerOff->getState(), "ds");
 #ifdef ALLOW_CPU_SCALER
 	ConfMan.setBool("cpu_scaler", _cpuScaler->getState(), "ds");
 #endif
-	ConfMan.setInt("xoffset", _touchX->getValue(), "ds");
-	ConfMan.setInt("yoffset", _touchY->getValue(), "ds");
 	ConfMan.setBool("showcursor", _showCursorCheckbox->getState(), "ds");
-	ConfMan.setBool("snaptoborder", _snapToBorderCheckbox->getState(), "ds");
-	ConfMan.setBool("touchpad", _touchPadStyle->getState(), "ds");
-	ConfMan.setBool("screentaps", _screenTaps->getState(), "ds");
-	ConfMan.setInt("sensitivity", _sensitivity->getValue(), "ds");
 	ConfMan.setInt("gamma", _gammaCorrection->getValue(), "ds");
 
-	u32 zoomLevel = 150;
+	int zoomLevel = 150;
 
 	if (_100PercentCheckbox->getState()) {
 		zoomLevel = 100;
@@ -266,39 +194,6 @@ void DSOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint
 	}
 
 
-	if ((!guard) && (_radioButtonMode)) {
-		guard = true;
-
-		if ((sender == _touchPadStyle) && (cmd == 0x20000001)) {
-
-			if (_touchPadStyle->getState()) {
-				// Swap screens when turning on trackpad style, it feels
-				// much more natural!
-				DS::setGameScreenSwap(true);
-
-				_screenTaps->setState(true);
-				_screenTaps->setEnabled(false);
-				_screenTaps->draw();
-				_sensitivity->setEnabled(true);
-				_sensitivityLabel->setEnabled(true);
-				_sensitivityLabel->draw();
-				_sensitivity->draw();
-			} else {
-				DS::setGameScreenSwap(false);
-
-				_screenTaps->setEnabled(true);
-				_screenTaps->setState(false);
-				_screenTaps->draw();
-				_sensitivity->setEnabled(false);
-				_sensitivityLabel->setEnabled(false);
-				_sensitivityLabel->draw();
-				_sensitivity->draw();
-			}
-		}
-
-		guard = false;
-	}
-
 	if ((!guard) && (_radioButtonMode)) {
 
 		guard = true;
@@ -361,15 +256,8 @@ void setOptions() {
 
 	ConfMan.addGameDomain("ds");
 
-	DS::setLeftHanded(confGetBool("lefthanded", false));
 	DS::setMouseCursorVisible(confGetBool("showcursor", true));
 
-#ifdef DS_BUILD_D
-	DS::setSnapToBorder(confGetBool("snaptoborder", true));
-#else
-	DS::setSnapToBorder(confGetBool("snaptoborder", false));
-#endif
-
 	DS::setUnscaledMode(confGetBool("unscaled", false));
 
 	if (firstLoad) {
@@ -384,39 +272,12 @@ void setOptions() {
 		}
 	}
 
-	DS::setTouchXOffset(confGetInt("xoffset", 0));
-	DS::setTouchYOffset(confGetInt("yoffset", 0));
-	DS::setSensitivity(confGetInt("sensitivity", 8));
-
 #ifdef ALLOW_CPU_SCALER
 	DS::setCpuScalerEnable(confGetBool("cpu_scaler", false));
 #endif
 
-	DS::setTapScreenClicksEnable(confGetBool("screentaps", false));
-
 	DS::setGamma(confGetInt("gamma", 0));
 
-
-	if (ConfMan.hasKey("touchpad", "ds")) {
-		bool enable = ConfMan.getBool("touchpad", "ds");
-
-		DS::setTrackPadStyleEnable(enable);
-
-		if (enable && firstLoad) {
-			// If we've just booted up, want to swap screens when trackpad mode is in use
-			// but not every time we enter the options dialog.
-			DS::setGameScreenSwap(true);
-		}
-
-		if (enable) {
-			DS::setTapScreenClicksEnable(true);
-		}
-
-	} else {
-		DS::setTrackPadStyleEnable(false);
-	}
-
-
 	firstLoad = false;
 }
 
diff --git a/backends/platform/ds/arm9/source/dsoptions.h b/backends/platform/ds/arm9/source/dsoptions.h
index 0bc61adda0..2afa628166 100644
--- a/backends/platform/ds/arm9/source/dsoptions.h
+++ b/backends/platform/ds/arm9/source/dsoptions.h
@@ -51,28 +51,16 @@ protected:
 
 	GUI::TabWidget *_tab;
 
-	GUI::StaticTextWidget *_sensitivityLabel;
-
-	GUI::SliderWidget *_touchX;
-	GUI::SliderWidget *_touchY;
-	GUI::SliderWidget *_sensitivity;
 	GUI::SliderWidget *_gammaCorrection;
-	GUI::CheckboxWidget *_leftHandedCheckbox;
 	GUI::CheckboxWidget *_unscaledCheckbox;
 	GUI::CheckboxWidget *_100PercentCheckbox;
 	GUI::CheckboxWidget *_150PercentCheckbox;
 	GUI::CheckboxWidget *_200PercentCheckbox;
-	GUI::CheckboxWidget *_indyFightCheckbox;
-	GUI::CheckboxWidget *_disablePowerOff;
 	GUI::CheckboxWidget *_showCursorCheckbox;
-	GUI::CheckboxWidget *_snapToBorderCheckbox;
 
 	GUI::CheckboxWidget *_hardScaler;
 	GUI::CheckboxWidget *_cpuScaler;
 
-	GUI::CheckboxWidget *_touchPadStyle;
-	GUI::CheckboxWidget *_screenTaps;
-
 	bool	_radioButtonMode;
 
 };
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 098e14cd0f..4d4a25f14e 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -33,6 +33,7 @@
 #include "common/util.h"
 #include "common/rect.h"
 #include "common/savefile.h"
+#include "common/translation.h"
 
 #include "osystem_ds.h"
 #include "nds.h"
@@ -40,23 +41,20 @@
 #include "common/config-manager.h"
 #include "common/str.h"
 #include "graphics/surface.h"
-#include "touchkeyboard.h"
 #include "backends/fs/devoptab/devoptab-fs-factory.h"
+#include "backends/keymapper/hardware-input.h"
 
 #include "backends/audiocd/default/default-audiocd.h"
+#include "backends/events/default/default-events.h"
 #include "backends/saves/default/default-saves.h"
 #include "backends/timer/default/default-timer.h"
 
-#ifdef ENABLE_AGI
-#include "wordcompletion.h"
-#endif
-
 #include <time.h>
 
 OSystem_DS *OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
-	: eventNum(0), lastPenFrame(0), queuePos(0), _mixer(NULL), _frameBufferExists(false),
+	: _eventSource(NULL), _mixer(NULL), _frameBufferExists(false),
 	_disableCursorPalette(true), _graphicsEnable(true), _gammaValue(0)
 {
 	_instance = this;
@@ -78,6 +76,9 @@ void OSystem_DS::initBackend() {
 	ConfMan.setInt("autosave_period", 0);
 	ConfMan.setBool("FM_medium_quality", true);
 
+	_eventSource = new DSEventSource();
+	_eventManager = new DefaultEventManager(_eventSource);
+
 	_savefileManager = new DefaultSaveFileManager();
 	_timerManager = new DefaultTimerManager();
     DS::setTimerCallback(&OSystem_DS::timerHandler, 10);
@@ -85,25 +86,21 @@ void OSystem_DS::initBackend() {
 	_mixer = new Audio::MixerImpl(11025);
 	_mixer->setReady(true);
 
-	EventsBaseBackend::initBackend();
+	BaseBackend::initBackend();
 }
 
 bool OSystem_DS::hasFeature(Feature f) {
-	return (f == kFeatureVirtualKeyboard) || (f == kFeatureCursorPalette);
+	return (f == kFeatureCursorPalette);
 }
 
 void OSystem_DS::setFeatureState(Feature f, bool enable) {
-	if (f == kFeatureVirtualKeyboard)
-		DS::setKeyboardIcon(enable);
-	else if (f == kFeatureCursorPalette) {
+	if (f == kFeatureCursorPalette) {
 		_disableCursorPalette = !enable;
 		refreshCursor();
 	}
 }
 
 bool OSystem_DS::getFeatureState(Feature f) {
-	if (f == kFeatureVirtualKeyboard)
-		return DS::getKeyboardIcon();
 	if (f == kFeatureCursorPalette)
 		return !_disableCursorPalette;
 	return false;
@@ -145,10 +142,7 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 			if (DS::getIsDisplayMode8Bit()) {
 				int col = applyGamma(paletteValue);
 				BG_PALETTE[r] = col;
-
-				if (!DS::getKeyboardEnable()) {
-					BG_PALETTE_SUB[r] = col;
-				}
+				BG_PALETTE_SUB[r] = col;
 			}
 
 			_palette[r] = paletteValue;
@@ -164,9 +158,7 @@ void OSystem_DS::restoreHardwarePalette() {
 	for (int r = 0; r < 255; r++) {
 		int col = applyGamma(_palette[r]);
 		BG_PALETTE[r] = col;
-		if (!DS::getKeyboardEnable()) {
-			BG_PALETTE_SUB[r] = col;
-		}
+		BG_PALETTE_SUB[r] = col;
 	}
 }
 
@@ -230,115 +222,59 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 
 		int by = 0;
 
-		if (DS::getKeyboardEnable()) {
-			// When they keyboard is on screen, we don't update the subscreen because
-			// the keyboard image uses the same VRAM addresses.
-
-			for (int dy = y; dy < y + h; dy++) {
-				u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
-				const u8 *src = (const u8 *) buf + (pitch * by);
-
-				u32 dx;
-
-				u32 pixelsLeft = w;
-
-				if (MISALIGNED16(dest)) {
-					// Read modify write
-
-					dest--;
-					u16 mix = *((u16 *) dest);
-
-					mix = (mix & 0x00FF) | (*src++ << 8);
-
-					*dest = mix;
-
-					dest += 2;
-					pixelsLeft--;
-				}
-
-				// We can now assume dest is aligned
-				u16 *dest16 = (u16 *) dest;
+		for (int dy = y; dy < y + h; dy++) {
+			u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
+			u8 *destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
+			const u8 *src = (const u8 *) buf + (pitch * by);
 
-				for (dx = 0; dx < pixelsLeft; dx+=2) {
-					u16 mix;
+			u32 dx;
 
-					mix = *src + (*(src + 1) << 8);
-					*dest16++ = mix;
-					src += 2;
-				}
+			u32 pixelsLeft = w;
 
-				pixelsLeft -= dx;
+			if (MISALIGNED16(dest)) {
+				// Read modify write
 
-				// At the end we may have one pixel left over
+				dest--;
+				u16 mix = *((u16 *) dest);
 
-				if (pixelsLeft != 0) {
-					u16 mix = *dest16;
+				mix = (mix & 0x00FF) | (*src++ << 8);
 
-					mix = (mix & 0x00FF) | ((*src++) << 8);
+				*dest = mix;
+				*destSub = mix;
 
-					*dest16 = mix;
-				}
-
-				by++;
+				dest += 2;
+				destSub += 2;
+				pixelsLeft--;
 			}
 
-		} else {
-			// When they keyboard is not on screen, update both vram copies
-
-			for (int dy = y; dy < y + h; dy++) {
-				u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
-				u8 *destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
-				const u8 *src = (const u8 *) buf + (pitch * by);
-
-				u32 dx;
-
-				u32 pixelsLeft = w;
-
-				if (MISALIGNED16(dest)) {
-					// Read modify write
-
-					dest--;
-					u16 mix = *((u16 *) dest);
-
-					mix = (mix & 0x00FF) | (*src++ << 8);
+			// We can now assume dest is aligned
+			u16 *dest16 = (u16 *) dest;
+			u16 *destSub16 = (u16 *) destSub;
 
-					*dest = mix;
-					*destSub = mix;
+			for (dx = 0; dx < pixelsLeft; dx+=2) {
+				u16 mix;
 
-					dest += 2;
-					destSub += 2;
-					pixelsLeft--;
-				}
-
-				// We can now assume dest is aligned
-				u16 *dest16 = (u16 *) dest;
-				u16 *destSub16 = (u16 *) destSub;
-
-				for (dx = 0; dx < pixelsLeft; dx+=2) {
-					u16 mix;
-
-					mix = *src + (*(src + 1) << 8);
-					*dest16++ = mix;
-					*destSub16++ = mix;
-					src += 2;
-				}
+				mix = *src + (*(src + 1) << 8);
+				*dest16++ = mix;
+				*destSub16++ = mix;
+				src += 2;
+			}
 
-				pixelsLeft -= dx;
+			pixelsLeft -= dx;
 
-				// At the end we may have one pixel left over
+			// At the end we may have one pixel left over
 
-				if (pixelsLeft != 0) {
-					u16 mix = *dest16;
+			if (pixelsLeft != 0) {
+				u16 mix = *dest16;
 
-					mix = (mix & 0x00FF) | ((*src++) << 8);
+				mix = (mix & 0x00FF) | ((*src++) << 8);
 
-					*dest16 = mix;
-					*destSub16 = mix;
-				}
+				*dest16 = mix;
+				*destSub16 = mix;
+			}
 
-				by++;
+			by++;
 
-			}
 		}
 
 	} else {
@@ -347,39 +283,23 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 
 		u16 *src = (u16 *) buf;
 
-		if (DS::getKeyboardEnable()) {
+		for (int dy = y; dy < y + h; dy++) {
+			u16 *dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
+			u16 *dest2 = bgSub + (dy << 8) + (x >> 1);
 
-			for (int dy = y; dy < y + h; dy++) {
-				u16 *dest = bg + (dy * (stride >> 1)) + (x >> 1);
+			DC_FlushRange(src, w << 1);
+			DC_FlushRange(dest1, w << 1);
+			DC_FlushRange(dest2, w << 1);
 
-				DC_FlushRange(src, w << 1);
-				DC_FlushRange(dest, w << 1);
-				dmaCopyHalfWords(3, src, dest, w);
+			dmaCopyHalfWords(3, src, dest1, w);
 
-				while (dmaBusy(3));
-
-				src += pitch >> 1;
+			if ((!_frameBufferExists) || (buf == _framebuffer.getPixels())) {
+				dmaCopyHalfWords(2, src, dest2, w);
 			}
 
-		} else {
-			for (int dy = y; dy < y + h; dy++) {
-				u16 *dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
-				u16 *dest2 = bgSub + (dy << 8) + (x >> 1);
-
-				DC_FlushRange(src, w << 1);
-				DC_FlushRange(dest1, w << 1);
-				DC_FlushRange(dest2, w << 1);
-
-				dmaCopyHalfWords(3, src, dest1, w);
-
-				if ((!_frameBufferExists) || (buf == _framebuffer.getPixels())) {
-					dmaCopyHalfWords(2, src, dest2, w);
-				}
+			while (dmaBusy(2) || dmaBusy(3));
 
-				while (dmaBusy(2) || dmaBusy(3));
-
-				src += pitch >> 1;
-			}
+			src += pitch >> 1;
 		}
 	}
 }
@@ -393,13 +313,12 @@ void OSystem_DS::updateScreen() {
 	}
 
 	DS::displayMode16BitFlipBuffer();
-	DS::addEventsToQueue();
 
 	// FIXME: Evil game specific hack.
 	// Force back buffer usage for Nippon Safes, as it doesn't double buffer it's output
-	if (DS::getControlType() == DS::CONT_NIPPON) {
-		lockScreen();
-	}
+	// if (DS::getControlType() == DS::CONT_NIPPON) {
+	//	lockScreen();
+	// }
 }
 
 void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
@@ -466,6 +385,7 @@ bool OSystem_DS::showMouse(bool visible) {
 }
 
 void OSystem_DS::warpMouse(int x, int y) {
+	DS::warpMouse(x, y);
 }
 
 void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
@@ -487,45 +407,16 @@ void OSystem_DS::refreshCursor() {
 	DS::setCursorIcon(_cursorImage, _cursorW, _cursorH, _cursorKey, _cursorHotX, _cursorHotY);
 }
 
-void OSystem_DS::addEvent(const Common::Event& e) {
-	eventQueue[queuePos++] = e;
-}
-
-bool OSystem_DS::pollEvent(Common::Event &event) {
-
-	if (lastPenFrame != DS::getMillis()) {
-
-		if (eventNum == queuePos) {
-			eventNum = 0;
-			queuePos = 0;
-			// Bodge - this last event seems to be processed sometimes and not others.
-			// So we make it something harmless which won't cause any adverse effects.
-			event.type = Common::EVENT_KEYUP;
-			event.kbd.ascii = 0;
-			event.kbd.keycode = Common::KEYCODE_INVALID;
-			event.kbd.flags = 0;
-			return false;
-		} else {
-			event = eventQueue[eventNum++];
-			return true;
-		}
-	}
-
-	return false;
-}
-
 uint32 OSystem_DS::getMillis(bool skipRecord) {
 	return DS::getMillis();
 }
 
 void OSystem_DS::delayMillis(uint msecs) {
 	int st = getMillis();
-	DS::addEventsToQueue();
 
 	while (st + msecs >= getMillis());
 
 	DS::doTimerCallback();
-	DS::addEventsToQueue();
 }
 
 
@@ -627,19 +518,6 @@ void OSystem_DS::clearFocusRectangle() {
 
 }
 
-
-void OSystem_DS::addAutoComplete(const char *word) {
-	DS::addAutoComplete(word);
-}
-
-void OSystem_DS::clearAutoComplete() {
-	DS::clearAutoComplete();
-}
-
-void OSystem_DS::setCharactersEntered(int count) {
-	DS::setCharactersEntered(count);
-}
-
 void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
 #ifndef DISABLE_TEXT_CONSOLE
 	nocashMessage((char *)message);
@@ -673,11 +551,38 @@ u16 OSystem_DS::applyGamma(u16 color) {
 	return 0x8000 | r | (g << 5) | (b << 10);
 }
 
-void OSystem_DS::engineDone() {
-	DS::exitGame();
-
-#ifdef ENABLE_AGI
-	DS::clearAutoCompleteWordList();
-#endif
-
+static const Common::HardwareInputTableEntry ndsJoystickButtons[] = {
+    { "JOY_A",              Common::JOYSTICK_BUTTON_A,              _s("A")           },
+    { "JOY_B",              Common::JOYSTICK_BUTTON_B,              _s("B")           },
+    { "JOY_X",              Common::JOYSTICK_BUTTON_X,              _s("X")           },
+    { "JOY_Y",              Common::JOYSTICK_BUTTON_Y,              _s("Y")           },
+    { "JOY_BACK",           Common::JOYSTICK_BUTTON_BACK,           _s("Select")      },
+    { "JOY_START",          Common::JOYSTICK_BUTTON_START,          _s("Start")       },
+    { "JOY_LEFT_SHOULDER",  Common::JOYSTICK_BUTTON_LEFT_SHOULDER,  _s("L")           },
+    { "JOY_RIGHT_SHOULDER", Common::JOYSTICK_BUTTON_RIGHT_SHOULDER, _s("R")           },
+    { "JOY_UP",             Common::JOYSTICK_BUTTON_DPAD_UP,        _s("D-pad Up")    },
+    { "JOY_DOWN",           Common::JOYSTICK_BUTTON_DPAD_DOWN,      _s("D-pad Down")  },
+    { "JOY_LEFT",           Common::JOYSTICK_BUTTON_DPAD_LEFT,      _s("D-pad Left")  },
+    { "JOY_RIGHT",          Common::JOYSTICK_BUTTON_DPAD_RIGHT,     _s("D-pad Right") },
+    { nullptr,              0,                                      nullptr           }
+};
+
+static const Common::AxisTableEntry ndsJoystickAxes[] = {
+    { nullptr, 0, Common::kAxisTypeFull, nullptr }
+};
+
+const Common::HardwareInputTableEntry ndsMouseButtons[] = {
+    { "MOUSE_LEFT", Common::MOUSE_BUTTON_LEFT, _s("Touch") },
+    { nullptr,      0,                         nullptr     }
+};
+
+Common::HardwareInputSet *OSystem_DS::getHardwareInputSet() {
+	using namespace Common;
+
+	CompositeHardwareInputSet *inputSet = new CompositeHardwareInputSet();
+	// Touch input sends mouse events for now, so we need to declare we have a mouse...
+	inputSet->addHardwareInputSet(new MouseHardwareInputSet(ndsMouseButtons));
+	inputSet->addHardwareInputSet(new JoystickHardwareInputSet(ndsJoystickButtons, ndsJoystickAxes));
+
+	return inputSet;
 }
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index d3519c30c1..da42454f23 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -29,21 +29,14 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
 
 #include "backends/base-backend.h"
-#include "common/events.h"
+#include "backends/events/ds/ds-events.h"
 #include "nds.h"
 #include "audio/mixer_intern.h"
 #include "graphics/surface.h"
 #include "graphics/palette.h"
 
-class OSystem_DS : public EventsBaseBackend, public PaletteManager {
+class OSystem_DS : public BaseBackend, public PaletteManager {
 protected:
-
-	int eventNum;
-	int lastPenFrame;
-
-	Common::Event eventQueue[96];
-	int queuePos;
-
 	Audio::MixerImpl *_mixer;
 	Graphics::Surface _framebuffer;
 	bool _frameBufferExists;
@@ -62,6 +55,7 @@ protected:
 	byte _cursorKey;
 	int _cursorScale;
 
+	DSEventSource *_eventSource;
 
 	Graphics::Surface *createTempFrameBuffer();
 	bool _disableCursorPalette;
@@ -111,11 +105,13 @@ public:
 	virtual void warpMouse(int x, int y);
 	virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
 
-	virtual bool pollEvent(Common::Event &event);
 	virtual uint32 getMillis(bool skipRecord = false);
 	virtual void delayMillis(uint msecs);
 	virtual void getTimeAndDate(TimeDate &t) const;
 
+	virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }
+	virtual Common::HardwareInputSet *getHardwareInputSet();
+
 	virtual MutexRef createMutex(void);
 	virtual void lockMutex(MutexRef mutex);
 	virtual void unlockMutex(MutexRef mutex);
@@ -123,9 +119,6 @@ public:
 
 	virtual void quit();
 
-	void addEvent(const Common::Event& e);
-	bool isEventQueueEmpty() const { return queuePos == 0; }
-
 	virtual void setFocusRectangle(const Common::Rect& rect);
 
 	virtual void clearFocusRectangle();
@@ -139,11 +132,6 @@ public:
 
 	static int timerHandler(int t);
 
-
-	virtual void addAutoComplete(const char *word);
-	virtual void clearAutoComplete();
-	virtual void setCharactersEntered(int count);
-
 	u16 getDSPaletteEntry(u32 entry) const { return _palette[entry]; }
 	u16 getDSCursorPaletteEntry(u32 entry) const { return !_disableCursorPalette? _cursorPalette[entry]: _palette[entry]; }
 
@@ -155,8 +143,6 @@ public:
 
 	u16 applyGamma(u16 color);
 	void setGammaValue(int gamma) { _gammaValue = gamma; }
-
-	void engineDone();
 };
 
 #endif
diff --git a/backends/platform/ds/arm9/source/scummhelp.cpp b/backends/platform/ds/arm9/source/scummhelp.cpp
deleted file mode 100644
index 7f379e3abe..0000000000
--- a/backends/platform/ds/arm9/source/scummhelp.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "scummhelp.h"
-#include "common/translation.h"
-
-#define ADD_BIND(k,d) do { key[i] = k; dsc[i] = d; i++; } while (0)
-#define ADD_TEXT(d) ADD_BIND("",d)
-#define ADD_LINE ADD_BIND("","")
-
-#define HELP_NUM_LINES 15
-
-namespace DS {
-
-void updateStrings(byte gameId, byte version, Common::Platform platform,
-			int page, Common::U32String &title, Common::U32String *&key, Common::U32String *&dsc) {
-	key = new Common::U32String[HELP_NUM_LINES];
-	dsc = new Common::U32String[HELP_NUM_LINES];
-	int i = 0;
-	switch (page) {
-	case 1: {
-		title = _("DS Controls (right handed):");
-		ADD_BIND(_("Pad Left"), _("Left mouse button"));
-		ADD_BIND(_("Pad Right"), _("Right mouse button"));
-		ADD_BIND(_("Pad Up"), _("Mouse hover mode (no click)"));
-		ADD_BIND(_("Pad Down"), _("Skip dialog line (some games)"));
-		ADD_BIND(_("Start"), _("Pause/Game menu"));
-		ADD_BIND(_("Select"), _("DS Options menu"));
-		ADD_BIND("B", _("Skip cutscenes"));
-		ADD_BIND("A", _("Switch screens"));
-		ADD_BIND("Y", _("Show/hide debug console"));
-		ADD_BIND("X", _("Show/hide keyboard"));
-		ADD_BIND("L+Pad/Pen", _("Scroll current touch screen view"));
-		ADD_BIND("L+B/A", _("Zoom in/out"));
-		break;
-	}
-
-	case 2: {
-		title = _("DS Controls (left handed):");
-		ADD_BIND("Y", _("Left mouse button"));
-		ADD_BIND("A", _("Right mouse button"));
-		ADD_BIND("X", _("Mouse hover mode (no click)"));
-		ADD_BIND("B", _("Skip dialog line (some games)"));
-		ADD_BIND(_("Start"), _("Pause/Game menu"));
-		ADD_BIND(_("Select"), _("DS Options menu"));
-		ADD_BIND(_("Pad Down"), _("Skip cutscenes"));
-		ADD_BIND(_("Pad Up"), _("Show/hide keyboard"));
-		ADD_BIND(_("Pad Left"), _("Show/hide debug console"));
-		ADD_BIND(_("Pad Right"), _("Swap screens"));
-		ADD_BIND("R+Pad/Pen", _("Scroll current touch screen view"));
-		ADD_BIND("R+dwn/rgt", _("Zoom in/out"));
-		break;
-	}
-
-	case 3: {
-		title = _("Indiana Jones Fight controls:");
-		ADD_BIND(_("Pad Left"), _("Move left"));
-		ADD_BIND(_("Pad Right"), _("Move right"));
-		ADD_BIND(_("Pad Up"), _("High guard"));
-		ADD_BIND(_("Pad Down"), _("Guard down"));
-		ADD_BIND("Y", _("Guard middle"));
-		ADD_BIND("X", _("Punch high"));
-		ADD_BIND("A", _("Punch middle"));
-		ADD_BIND("B", _("Punch low"));
-		break;
-	}
-	}
-
-
-	while (i < HELP_NUM_LINES) {
-		ADD_LINE;
-	}
-
-}
-
-} // End of namespace DS
-
-
-
-#undef ADD_BIND
-#undef ADD_TEXT
-#undef ADD_LINE
diff --git a/backends/platform/ds/arm9/source/touchkeyboard.cpp b/backends/platform/ds/arm9/source/touchkeyboard.cpp
deleted file mode 100644
index 622ed8215b..0000000000
--- a/backends/platform/ds/arm9/source/touchkeyboard.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include <nds.h>
-#include "touchkeyboard.h"
-#include "keyboard_raw.h"
-#include "keyboard_pal_raw.h"
-#include "8x8font_tga_raw.h"
-#include "dsmain.h"
-#include "osystem_ds.h"
-
-namespace DS {
-
-struct key_data {
-	char keyNum;
-	signed char x, y;
-	int character;
-	bool pressed;
-};
-
-#define DS_NUM_KEYS 72
-#define DS_SHIFT 2
-#define DS_BACKSPACE 8
-#define DS_RETURN 13
-#define DS_CAPSLOCK 1
-
-
-static key_data keys[DS_NUM_KEYS] = {
-	// Key number		x		y		character
-
-	// Numbers
-	{28,				3,		0,		'1', false},
-	{29,				5,		0,		'2', false},
-	{30,				7,		0,		'3', false},
-	{31,				9,		0,		'4', false},
-	{32,				11,		0,		'5', false},
-	{33,				13,		0,		'6', false},
-	{34,				15,		0,		'7', false},
-	{35,				17,		0,		'8', false},
-	{36,				19,		0,		'9', false},
-	{27,				21,		0,		'0', false},
-	{45,				23,		0,		Common::KEYCODE_MINUS, false},
-	{50,				25,		0,		Common::KEYCODE_EQUALS, false},
-	{52,				27,		0,		Common::KEYCODE_BACKSPACE, false},
-
-	// Top row
-	{'Q'-'A' + 1,		4,		2,		'Q', false},
-	{'W'-'A' + 1,		6,		2,		'W', false},
-	{'E'-'A' + 1,		8,		2,		'E', false},
-	{'R'-'A' + 1,		10,		2,		'R', false},
-	{'T'-'A' + 1,		12,		2,		'T', false},
-	{'Y'-'A' + 1,		14,		2,		'Y', false},
-	{'U'-'A' + 1,		16,		2,		'U', false},
-	{'I'-'A' + 1,		18,		2,		'I', false},
-	{'O'-'A' + 1,		20,		2,		'O', false},
-	{'P'-'A' + 1,		22,		2,		'P', false},
-	{43,				24,		2,		Common::KEYCODE_LEFTBRACKET, false},
-	{44,				26,		2,		Common::KEYCODE_RIGHTBRACKET, false},
-
-	// Middle row
-	{55,				3,		4,		DS_CAPSLOCK, false},
-	{'A'-'A' + 1,		5,		4,		'A', false},
-	{'S'-'A' + 1,		7,		4,		'S', false},
-	{'D'-'A' + 1,		9,		4,		'D', false},
-	{'F'-'A' + 1,		11,		4,		'F', false},
-	{'G'-'A' + 1,		13,		4,		'G', false},
-	{'H'-'A' + 1,		15,		4,		'H', false},
-	{'J'-'A' + 1,		17,		4,		'J', false},
-	{'K'-'A' + 1,		19,		4,		'K', false},
-	{'L'-'A' + 1,		21,		4,		'L', false},
-	{42,				23,		4,		Common::KEYCODE_SEMICOLON, false},
-	{41,				25,		4,		Common::KEYCODE_QUOTE, false},
-	{46,				27,		4,		Common::KEYCODE_RETURN, false},
-
-	// Bottom row
-	{51,				4,		6,		DS_SHIFT, false},
-	{'Z'-'A' + 1,		6,		6,		'Z', false},
-	{'X'-'A' + 1,		8,		6,		'X', false},
-	{'C'-'A' + 1,		10,		6,		'C', false},
-	{'V'-'A' + 1,		12,		6,		'V', false},
-	{'B'-'A' + 1,		14,		6,		'B', false},
-	{'N'-'A' + 1,		16,		6,		'N', false},
-	{'M'-'A' + 1,		18,		6,		'M', false},
-	{38,				20,		6,		Common::KEYCODE_COMMA, false},
-	{39,				22,		6,		Common::KEYCODE_PERIOD, false},
-	{40,				24,		6,		Common::KEYCODE_SLASH, false},
-
-	// Space bar
-	{47,				9,		8,		Common::KEYCODE_SPACE, false},
-	{48,				11,		8,		Common::KEYCODE_SPACE, false},
-	{48,				13,		8,		Common::KEYCODE_SPACE, false},
-	{48,				15,		8,		Common::KEYCODE_SPACE, false},
-	{48,				17,		8,		Common::KEYCODE_SPACE, false},
-	{49,				19,		8,		Common::KEYCODE_SPACE, false},
-
-	// Cursor arrows
-	{52,				27,		8,		Common::KEYCODE_LEFT, false},
-	{54,				29,		8,		Common::KEYCODE_DOWN, false},
-	{53,				31,		8,		Common::KEYCODE_RIGHT, false},
-	{51,				29,		6,		Common::KEYCODE_UP, false},
-
-	// Close button
-	{56,				30,		0,		Common::KEYCODE_INVALID, false},
-
-	// Function keys (needed for AGI)
-	{57,				4,		-2,		Common::KEYCODE_F1, false},
-	{58,				6,		-2,		Common::KEYCODE_F2, false},
-	{59,				8,		-2,		Common::KEYCODE_F3, false},
-	{60,				10,		-2,		Common::KEYCODE_F4, false},
-	{61,				14,		-2,		Common::KEYCODE_F5, false},
-	{62,				16,		-2,		Common::KEYCODE_F6, false},
-	{63,				18,		-2,		Common::KEYCODE_F7, false},
-	{64,				20,		-2,		Common::KEYCODE_F8, false},
-	{65,				24,		-2,		Common::KEYCODE_F9, false},
-	{66,				26,		-2,		Common::KEYCODE_F10, false},
-	{67,				28,		-2,		Common::KEYCODE_F11, false},
-	{68,				30,		-2,		Common::KEYCODE_F12, false},
-
-};
-
-static int keyboardX;
-static int keyboardY;
-
-static int s_mapBase;
-static int s_tileBase;
-
-static u16 *baseAddress;
-
-static bool shiftState;
-static bool capsLockState;
-
-static bool closed;
-
-static char autoCompleteWord[NUM_WORDS][32];
-static int autoCompleteCount;
-
-static char autoCompleteBuffer[128];
-
-static int selectedCompletion = -1;
-static int charactersEntered = 0;
-static int typingTimeout = 0;
-
-// Render text onto the tiled screen
-
-void drawText(int tx, int ty, const char *string, bool highlight) {
-
-	u16 baseValue = 0;
-
-	if (highlight) {
-		baseValue |= 0x1000;
-	}
-
-	for (int p = 0; *string; string++, p++) {
-		char c = *string;
-
-		if (c != ' ') {
-			int tile = c - 33 + (KEYBOARD_DATA_SIZE / 32);
-			baseAddress[ty * 32 + tx + p] = baseValue | tile;
-		}
-	}
-
-}
-
-void drawKeyboard(int tileBase, int mapBase, u16 *saveSpace) {
-	for (int r = 0; r < 32 * 32; r++) {
-		((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase))[r] = 0;
-	}
-
-	for (int r = 0; r < KEYBOARD_DATA_SIZE / 2; r++) {
-		((u16 *) CHAR_BASE_BLOCK_SUB(tileBase))[r] = ((u16 *) (::keyboard_raw))[r];
-	}
-
-	for (int r = 0; r < 16; r++) {
-		BG_PALETTE_SUB[r] = ((u16 *) (keyboard_pal_raw))[r];
-	}
-
-	// this is the font
-	for (int tile = 0; tile < 94; tile++) {
-
-		u16 *tileAddr = (u16 *) (CHAR_BASE_BLOCK_SUB(tileBase) + ((KEYBOARD_DATA_SIZE) + (tile * 32)));
-		const u8 *src = ((const u8 *) (::_8x8font_tga_raw)) + 18 + tile * 8;
-
-		for (int y = 0 ; y < 8; y++) {
-			for (int x = 0; x < 2; x++) {
-				 *(tileAddr + (y * 2) + x) =(*(src + (y * 752) + (x * 4) + 0) & 0x0F)
-									 	 | ((*(src + (y * 752) + (x * 4) + 1) & 0x0F) << 4)
-										 | ((*(src + (y * 752) + (x * 4) + 2) & 0x0F) << 8)
-										 | ((*(src + (y * 752) + (x * 4) + 3) & 0x0F) << 12);
-
-			}
-		}
-	}
-
-
-
-
-	for (int r = 0; r < 16; r++) {
-		int col = ((u16 *) (keyboard_pal_raw))[r];
-
-		int red = col & 0x001F;
-		int green = (col & 0x03E0) >> 5;
-		int blue = (col & 0x7C00) >> 10;
-
-		red = (red * 8) / 16;
-		green = (green * 24) / 16;
-		blue = (blue * 8) / 16;
-
-		if (green > 31) green = 31;
-
-		BG_PALETTE_SUB[16 + r] = red | (green << 5) | (blue << 10);
-	}
-
-	keyboardX = -2;
-	keyboardY = 2;
-
-	DS::s_mapBase = mapBase;
-	DS::s_tileBase = tileBase;
-
-	shiftState = false;
-	capsLockState = false;
-
-	int x = keyboardX;
-	int y = keyboardY;
-
-	u16 *base = ((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase));
-	baseAddress = base;
-
-	for (int r = 0; r < DS_NUM_KEYS; r++) {
-		base[(y + keys[r].y) * 32 + x + keys[r].x] = 10 + keys[r].keyNum * 2;
-		base[(y + keys[r].y) * 32 + x + keys[r].x + 1] = 10 + keys[r].keyNum * 2 + 1;
-
-		base[(y + keys[r].y + 1) * 32 + x + keys[r].x] = 10 + 148 + keys[r].keyNum * 2;
-		base[(y + keys[r].y + 1) * 32 + x + keys[r].x + 1] = 10 + 148 + keys[r].keyNum * 2 + 1;
-
-		keys[r].pressed = false;
-	}
-
-
-	closed = false;
-	clearAutoComplete();
-
-}
-
-
-void drawAutoComplete() {
-
-	// Clear the auto complete area at the bottom of the screen.
-	for (int y = 12; y < 24; y++) {
-		for (int x = 0; x < 32; x++) {
-			baseAddress[y * 32 + x] = 0;
-		}
-	}
-
-
-	if ((autoCompleteCount == 0) || (typingTimeout > 0)) {
-
-		// When there's no completions on the bottom of the screen, it acts like a mouse pad
-		// so this text indicates that
-		drawText(11, 18, "MOUSE AREA", true);
-
-
-	} else {
-
-		printf("time: %d\n", typingTimeout);
-
-		// Otherwise, draw autocompletions if one isn't being entered and there are
-		// some available.
-		for (int r = 0; r < autoCompleteCount; r++) {
-			int y = 12 + (r % 6) * 2;
-			int x = 0 + ((r / 6) * 16);
-
-			drawText(x, y, autoCompleteWord[r], selectedCompletion == r);
-		}
-
-	}
-}
-
-bool getKeyboardClosed() {
-	return closed;
-}
-
-void setKeyHighlight(int key, bool highlight) {
-	u16 *base = ((u16 *) SCREEN_BASE_BLOCK_SUB(DS::s_mapBase));
-
-	if (highlight) {
-		base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x] |= 0x1000;
-		base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x + 1] |= 0x1000;
-		base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x] |= 0x1000;
-		base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x + 1] |= 0x1000;
-	} else {
-		base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x] &= ~0x1000;
-		base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x + 1] &= ~0x1000;
-		base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x] &= ~0x1000;
-		base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x + 1] &= ~0x1000;
-	}
-}
-
-void addAutoComplete(const char *word) {
-	if (autoCompleteCount == NUM_WORDS) return;
-	strcpy(&autoCompleteWord[autoCompleteCount++][0], word);
-	drawAutoComplete();
-}
-
-void setCharactersEntered(int count) {
-	charactersEntered = count;
-}
-
-bool isInsideKeyboard(int x, int y) {
-	// When completions are available, keyboard covers the whole screen.
-	// otherwise, it only covers the area above KEYBOARD_BOTTOM_Y
-	return (autoCompleteCount > 0) || (y < KEYBOARD_BOTTOM_Y);
-}
-
-void clearAutoComplete() {
-	autoCompleteCount = 0;
-	selectedCompletion = -1;
-	drawAutoComplete();
-}
-
-void typeCompletion(int current) {
-	Common::Event event;
-
-	strcat(autoCompleteBuffer, &autoCompleteWord[current][charactersEntered]);
-	strcat(autoCompleteBuffer, " ");
-}
-
-void updateTypeEvents() {
-	if (autoCompleteBuffer[0] != '\0') {
-		Common::Event event;
-		OSystem_DS *system = OSystem_DS::instance();
-
-		event.kbd.keycode = (Common::KeyCode) autoCompleteBuffer[0];
-		event.kbd.ascii = autoCompleteBuffer[0];
-		event.type = Common::EVENT_KEYDOWN;
-		event.kbd.flags = 0;
-		system->addEvent(event);
-
-		event.type = Common::EVENT_KEYUP;
-		system->addEvent(event);
-
-		for (int r = 0; r < (int)strlen(autoCompleteBuffer); r++) {
-			autoCompleteBuffer[r] = autoCompleteBuffer[r + 1];
-		}
-
-		typingTimeout = 100;
-	}
-}
-
-void createKeyEvent(int keyNum, Common::Event& event) {
-	event.kbd.flags = 0;
-
-	if ((keys[keyNum].character >= '0') && (keys[keyNum].character <= '9')) {
-
-		if (!DS::shiftState) {
-			event.kbd.ascii = keys[keyNum].character;
-			event.kbd.keycode = (Common::KeyCode) keys[keyNum].character;
-		} else {
-			event.kbd.keycode = (Common::KeyCode) (Common::KEYCODE_F1 - (keys[keyNum].character - '1'));
-			event.kbd.ascii = 0;
-		}
-
-	} else if ((keys[keyNum].character >= 'A') && (keys[keyNum].character <= 'Z')) {
-
-		if ((!DS::shiftState) && (!DS::capsLockState)) {
-			event.kbd.ascii = keys[keyNum].character + 32; // Make key lowercase.
-		} else {
-			event.kbd.ascii = keys[keyNum].character;
-		}
-
-		event.kbd.keycode = (Common::KeyCode) event.kbd.ascii;
-	} else {
-		if ((keys[keyNum].character >= Common::KEYCODE_F1) && (keys[keyNum].character >= Common::KEYCODE_F12))	{
-			event.kbd.keycode = (Common::KeyCode) keys[keyNum].character;
-			event.kbd.ascii = keys[keyNum].character - Common::KEYCODE_F1 + Common::ASCII_F1;
-		} else {
-			event.kbd.ascii = keys[keyNum].character;
-			event.kbd.keycode = (Common::KeyCode) keys[keyNum].character;
-		}
-	}
-}
-
-void releaseAllKeys() {
-	for (int r = 0; r < DS_NUM_KEYS; r++) {
-		if (keys[r].pressed) {
-			DS::setKeyHighlight(r, false);
-
-			OSystem_DS *system = OSystem_DS::instance();
-
-			Common::Event event;
-			createKeyEvent(r, event);
-			event.type = Common::EVENT_KEYUP;
-			system->addEvent(event);
-
-			keys[r].pressed = false;
-		}
-	}
-}
-
-void addKeyboardEvents() {
-	bool resetShift = false;
-
-	updateTypeEvents();
-
-	if (typingTimeout > 0) {
-		typingTimeout--;
-		if (typingTimeout == 0) {
-			drawAutoComplete();
-		}
-	}
-
-	if (DS::getPenDown()) {
-		touchPosition touchPos;
-		touchRead(&touchPos);
-
-		int tx = (touchPos.px >> 3);
-		int ty = (touchPos.py >> 3);
-
-		if (ty >= 12) {
-			int current = -1;
-
-			if (tx < 12) {
-				current = (ty - 12) / 2;
-			} else {
-				current = 6 + (ty - 12) / 2;
-			}
-
-			if (selectedCompletion == current) {
-				typeCompletion(current);
-			} else {
-				if (current < autoCompleteCount) {
-					selectedCompletion = current;
-				}
-			}
-
-			drawAutoComplete();
-		}
-
-		tx -= keyboardX;
-		ty -= keyboardY;
-
-		for (int r = 0; r < DS_NUM_KEYS; r++) {
-			if (( (tx >= keys[r].x) && (tx <= keys[r].x + 1)) &&
-				   (ty >= keys[r].y) && (ty <= keys[r].y + 1)) {
-				OSystem_DS *system = OSystem_DS::instance();
-				Common::Event event;
-
-				if ((keys[r].character != Common::KEYCODE_INVALID)) {
-					createKeyEvent(r, event);
-				}
-
-				event.type = Common::EVENT_KEYDOWN;
-				system->addEvent(event);
-
-				switch (keys[r].character) {
-					case DS_SHIFT: {
-						DS::shiftState = !DS::shiftState;
-						DS::setKeyHighlight(r, DS::shiftState);
-						break;
-					}
-
-					case DS_CAPSLOCK: {
-						DS::capsLockState = !DS::capsLockState;
-						DS::setKeyHighlight(r, DS::capsLockState);
-						break;
-					}
-
-					default: {
-						DS::setKeyHighlight(r, true);
-						keys[r].pressed = true;
-						break;
-					}
-				}
-
-			}
-		}
-	}
-
-	if (DS::getPenReleased()) {
-
-		for (int r = 0; r < DS_NUM_KEYS; r++) {
-			if (keys[r].pressed) {
-				DS::setKeyHighlight(r, false);
-
-				OSystem_DS *system = OSystem_DS::instance();
-
-				Common::Event event;
-				if ((keys[r].character == Common::KEYCODE_INVALID)) {
-					// Close button
-					DS::closed = true;
-				} else {
-					createKeyEvent(r, event);
-					event.type = Common::EVENT_KEYUP;
-					system->addEvent(event);
-				}
-
-				keys[r].pressed = false;
-
-				if (keys[r].character != DS_SHIFT) {
-					resetShift = true;
-				}
-			}
-		}
-
-	}
-
-
-	if ((resetShift) && (DS::shiftState)) {
-		DS::shiftState = false;
-		resetShift = false;
-		for (int t = 0; t < DS_NUM_KEYS; t++) {
-			if (keys[t].character == DS_SHIFT) {
-				DS::setKeyHighlight(t, false);
-			}
-		}
-	}
-
-}
-
-} // End of namespace DS
diff --git a/backends/platform/ds/arm9/source/touchkeyboard.h b/backends/platform/ds/arm9/source/touchkeyboard.h
deleted file mode 100644
index cac602b090..0000000000
--- a/backends/platform/ds/arm9/source/touchkeyboard.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef _TOUCHKEYBOARD_H_
-#define _TOUCHKEYBOARD_H_
-
-#include "osystem_ds.h"
-
-namespace DS {
-
-enum {
-	NUM_WORDS = 12,
-	KEYBOARD_DATA_SIZE = 4736 * 2,
-	KEYBOARD_BOTTOM_Y = 105
-};
-
-void createKeyEvent(int keyNum, Common::Event& event);
-
-void drawKeyboard(int tileBase, int mapBase, u16 *saveSpace);
-void addKeyboardEvents();
-bool getKeyboardClosed();
-bool isInsideKeyboard(int x, int y);
-
-void addAutoComplete(const char *word);
-void clearAutoComplete();
-void setCharactersEntered(int count);
-void releaseAllKeys();
-
-} // End of namespace DS
-
-#endif
diff --git a/backends/platform/ds/arm9/source/wordcompletion.cpp b/backends/platform/ds/arm9/source/wordcompletion.cpp
deleted file mode 100644
index c89640bf10..0000000000
--- a/backends/platform/ds/arm9/source/wordcompletion.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "osystem_ds.h"
-#include "wordcompletion.h"
-#include "engines/agi/agi.h"	// Caution for #define for NUM_CHANNELS, causes problems in mixer_intern.h
-
-#ifdef ENABLE_AGI
-
-namespace DS {
-// Default dictionary is about 64Kb, so 96Kb should be enough for future expansion
-#define WORD_BUFFER_SIZE (96 * 1024)
-
-// Default dictionary has ~8000 words
-#define MAX_WORD_COUNT 12000
-
-char wordBuffer[WORD_BUFFER_SIZE];
-int wordBufferPos = 0;
-
-char *wordBufferPtr[MAX_WORD_COUNT];
-int wordBufferPtrPos = 0;
-
-void addAutoCompleteLine(const char *line) {
-
-	while (*line != 0) {
-		char word[32];
-		int length;
-
-		// Skip the T9-style numbers
-		while (*line != ' ') {
-			line++;
-		}
-		line++;
-
-		do {
-			length = 0;
-
-			if (*line == ' ') line++;
-
-
-			// Copy the new word
-			do {
-				word[length++] = *line++;
-			} while ((*line != '\0') && (*line != ' ') && (*line != '\n'));
-
-			word[length] = '\0';
-
-
-			// Store a pointer to the start of the word
-			wordBufferPtr[wordBufferPtrPos++] = &wordBuffer[wordBufferPos];
-
-			// copy the new word into the buffer
-			strcpy(&wordBuffer[wordBufferPos], word);
-			wordBufferPos += strlen(word) + 1;
-		} while (*line == ' ');
-	}
-}
-
-int stringCompare(const void *a, const void *b) {
-	const char** as = (const char **) a;
-	const char** bs = (const char **) b;
-
-	return scumm_stricmp(*as, *bs);
-}
-
-void clearAutoCompleteWordList() {
-	wordBufferPtrPos = 0;
-	wordBufferPos = 0;
-}
-
-void sortAutoCompleteWordList() {
-	// Sort the whole word list into alphabetical order
-	qsort((void *)wordBufferPtr, wordBufferPtrPos, 4, stringCompare);
-}
-
-// Sends the current available words to the virtual keyboard code for display
-bool findWordCompletions(const char *input) {
-	int min = 0;
-	int max = wordBufferPtrPos - 1;
-	char *word;
-	int position;
-	char partialWord[32];
-
-	// Early out if dictionary not loaded
-	if (wordBufferPtrPos == 0)
-		return false;
-
-	OSystem_DS *system = dynamic_cast<OSystem_DS *>(g_system);
-	system->clearAutoComplete();
-
-	int start = 0;
-	for (int r = strlen(input) - 1; r>0; r--) {
-		if (input[r] == ' ') {
-			start = r + 1;
-			break;
-		}
-	}
-	strcpy(partialWord, &input[start]);
-
-	if (*partialWord == 0) {
-		return false;
-	}
-
-	do {
-		position = min + ((max - min) / 2);
-
-		// Get the word from the dictonary line
-		word = wordBufferPtr[position];
-
-		// Now check to see if the word is before or after the stub we're after
-		int result = scumm_stricmp(partialWord, word);
-
-		if (result == 0) {
-			// We've found the whole word.  Aren't we good.
-			break;
-		} else if (result > 0) {
-			// We're too early, so change the minimum position
-			min = position + 1;
-		} else if (result < 0) {
-			// We're too early, so change the maximum position
-			max = position - 1;
-		}
-	} while (max - min > 0);
-
-	position = min;
-	word = wordBufferPtr[position];
-
-	system->setCharactersEntered(strlen(partialWord));
-
-
-	bool match = true;
-
-
-	for (int r = 0; partialWord[r] != 0; r++) {
-		if (word[r] != partialWord[r]) {
-			match = false;
-			break;
-		}
-	}
-
-	if (!match) {
-		position++;
-		if (position == wordBufferPtrPos)
-			return false;
-		word = wordBufferPtr[position];
-	}
-
-
-	match = true;
-
-	do {
-
-		for (int r = 0; partialWord[r] != 0; r++) {
-			if (word[r] != partialWord[r]) {
-				match = false;
-				break;
-			}
-		}
-
-		if (match) {
-			system->addAutoComplete(word);
-		}
-
-		position++;
-		if (position < wordBufferPtrPos) {
-			word = wordBufferPtr[position];
-		}
-
-	} while ((match) && (position < wordBufferPtrPos));
-
-	return true;
-
-}
-
-} // End of namespace DS
-
-#endif
diff --git a/backends/platform/ds/arm9/source/wordcompletion.h b/backends/platform/ds/arm9/source/wordcompletion.h
deleted file mode 100644
index d6e7224186..0000000000
--- a/backends/platform/ds/arm9/source/wordcompletion.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-namespace DS {
-
-extern void clearAutoCompleteWordList();
-extern bool findWordCompletions(const char *input);
-extern void addAutoCompleteLine(const char *line);
-extern void sortAutoCompleteWordList();
-
-} // End of namespace DS
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
index 9636173542..d08af9b0ca 100644
--- a/backends/platform/ds/module.mk
+++ b/backends/platform/ds/module.mk
@@ -1,74 +1,10 @@
 MODULE := backends/platform/ds
 
-PORT_OBJS := \
+MODULE_OBJS := \
 	arm9/source/blitters_arm.o \
 	arm9/source/dsmain.o \
-	arm9/source/scummhelp.o \
 	arm9/source/osystem_ds.o \
-	arm9/source/touchkeyboard.o \
-	arm9/source/dsoptions.o \
-	arm9/source/wordcompletion.o
-
-DATA_OBJS := \
-	arm9/data/icons.o \
-	arm9/data/keyboard.o \
-	arm9/data/keyboard_pal.o \
-	arm9/data/default_font.o \
-	arm9/data/8x8font_tga.o
-
-
-MODULE_OBJS := $(DATA_OBJS) $(PORT_OBJS)
-
-
-#---------------------------------------------------------------------------------
-# canned command sequence for binary data
-#---------------------------------------------------------------------------------
-define bin2o
-	$(MKDIR) $(*D)
-	bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@)
-endef
-
-define bin2h
-	$(MKDIR) $(*D)
-	echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > $@
-	echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> $@
-	echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> $@
-endef
-
-vpath %.raw $(srcdir)
-vpath %.pal $(srcdir)
-vpath %.bin $(srcdir)
-
-%.o: %.raw
-	$(bin2o)
-
-%_raw.h: %.raw
-	$(bin2h)
-
-%.o: %.pal
-	$(bin2o)
-
-%_raw.h: %.pal
-	$(bin2h)
-
-%.o: %.bin
-	$(bin2o)
-
-%_raw.h: %.bin
-	$(bin2h)
-
-
-# Mark files which require the *_raw.h files manually (for now, at least)
-$(MODULE)/arm9/source/dsmain.o: \
-	$(MODULE)/arm9/data/icons_raw.h \
-	$(MODULE)/arm9/data/keyboard_raw.h \
-	$(MODULE)/arm9/data/keyboard_pal_raw.h
-
-$(MODULE)/arm9/source/touchkeyboard.o: \
-	$(MODULE)/arm9/data/keyboard_raw.h \
-	$(MODULE)/arm9/data/keyboard_pal_raw.h \
-	$(MODULE)/arm9/data/8x8font_tga_raw.h
-
+	arm9/source/dsoptions.o
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index d1f9d46d41..644394ae60 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -167,14 +167,6 @@ int AgiEngine::agiInit() {
 	if (ec == errOK)
 		ec = _loader->loadResource(RESOURCETYPE_LOGIC, 0);
 
-#ifdef __DS__
-	// Normally, the engine loads the predictive text dictionary when the predictive dialog
-	// is shown.  On the DS version, the word completion feature needs the dictionary too.
-
-	// FIXME - loadDict() no long exists in AGI as this has been moved to within the
-	// GUI Predictive Dialog, but DS Word Completion is probably broken due to this...
-#endif
-
 	_keyHoldMode = false;
 	_keyHoldModeLastKey = Common::KEYCODE_INVALID;
 
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index f9518b3849..bfc4ff4519 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -28,9 +28,6 @@
 #include "agi/text.h"
 #include "agi/systemui.h"
 #include "agi/words.h"
-#ifdef __DS__
-#include "wordcompletion.h"
-#endif
 
 namespace Agi {
 
@@ -829,9 +826,6 @@ void TextMgr::promptClear() {
 }
 
 void TextMgr::promptRememberForAutoComplete(bool entered) {
-#ifdef __DS__
-	DS::findWordCompletions((char *)_prompt);
-#endif
 }
 
 void TextMgr::promptCommandWindow(bool recallLastCommand, uint16 newKey) {
@@ -1000,9 +994,6 @@ void TextMgr::stringKeyPress(uint16 newKey) {
 }
 
 void TextMgr::stringRememberForAutoComplete(bool entered) {
-#ifdef __DS__
-	DS::findWordCompletions((char *)_inputString);
-#endif
 }
 
 /**
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index e7dbd717c1..ae919399e9 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -30,10 +30,6 @@
 
 #include "graphics/scaler.h"
 
-#ifdef __DS__
-#include "scummhelp.h"
-#endif
-
 #include "gui/gui-manager.h"
 #include "gui/widget.h"
 #include "gui/ThemeEval.h"
@@ -329,12 +325,7 @@ void HelpDialog::reflowLayout() {
 void HelpDialog::displayKeyBindings() {
 	U32String titleStr, *keyStr, *dscStr;
 
-#ifndef __DS__
 	ScummHelp::updateStrings(_game.id, _game.version, _game.platform, _page, titleStr, keyStr, dscStr);
-#else
-	// DS version has a different help screen
-	DS::updateStrings(_game.id, _game.version, _game.platform, _page, titleStr, keyStr, dscStr);
-#endif
 
 	_title->setLabel(titleStr);
 	for (int i = 0; i < _numLines; i++) {
diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp
index 4928d299bf..d82bcf6254 100644
--- a/gui/predictivedialog.cpp
+++ b/gui/predictivedialog.cpp
@@ -35,10 +35,6 @@
 #include "common/file.h"
 #include "common/savefile.h"
 
-#if defined(__DS__) && defined(ENABLE_AGI)
-#include "backends/platform/ds/arm9/source/wordcompletion.h"
-#endif
-
 namespace GUI {
 
 enum {
@@ -976,10 +972,6 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict
 	while ((ptr = strchr(ptr, '\n'))) {
 		*ptr = 0;
 		ptr++;
-#if defined(__DS__) && defined(ENABLE_AGI)
-		// Pass the line on to the DS word list
-		DS::addAutoCompleteLine(dict.dictLine[i - 1]);
-#endif
 		dict.dictLine[i++] = ptr;
 	}
 	if (dict.dictLine[lines - 1][0] == 0)
@@ -989,12 +981,7 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict
 	debug(5, "Predictive Dialog: Loaded %d lines", dict.dictLineCount);
 
 	// FIXME: We use binary search on _predictiveDict.dictLine, yet we make no at_tempt
-	// to ever sort this array (except for the DS port). That seems risky, doesn't it?
-
-#if defined(__DS__) && defined(ENABLE_AGI)
-	// Sort the DS word completion list, to allow for a binary chop later (in the ds backend)
-	DS::sortAutoCompleteWordList();
-#endif
+	// to ever sort this array. That seems risky, doesn't it?
 
 	uint32 time3 = g_system->getMillis();
 	debug(5, "Predictive Dialog: Time to parse %s: %d, total: %d", ConfMan.get(dict.nameDict).c_str(), time3 - time2, time3 - time1);


Commit: 704deec03102d450eac650605eb4655c3d670cd3
    https://github.com/scummvm/scummvm/commit/704deec03102d450eac650605eb4655c3d670cd3
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Improve text console support

Changed paths:
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/osystem_ds.h
    configure


diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 529056a75a..93ba6b815e 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -123,10 +123,8 @@ static int subScreenScale = 256;
 static bool highBuffer;
 static bool displayModeIs8Bit = false;
 
-static bool consoleEnable = false;
 static bool gameScreenSwap = false;
 bool isCpuScalerEnabled();
-//#define HEAVY_LOGGING
 
 static int storedMouseX = 0;
 static int storedMouseY = 0;
@@ -156,8 +154,6 @@ static bool cpuScalerEnable = false;
 
 static u8 *scalerBackBuffer = NULL;
 
-static u16 savedPalEntry255 = RGB15(31, 31, 31);
-
 void setIcon(int num, int x, int y, int imageNum, int flags, bool enable);
 void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable);
 
@@ -251,38 +247,15 @@ void setUnscaledMode(bool enable) {
 }
 
 void displayMode8Bit() {
-
-#ifdef HEAVY_LOGGING
-	printf("displayMode8Bit...");
-#endif
-	u16 buffer[32 * 32];
-
 	setOptions();
 
-	if (!displayModeIs8Bit) {
-		for (int r = 0; r < 32 * 32; r++) {
-			buffer[r] = ((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r];
-		}
-	} else {
-		for (int r = 0; r < 32 * 32; r++) {
-			buffer[r] = ((u16 *) SCREEN_BASE_BLOCK(2))[r];
-		}
-	}
-
 	displayModeIs8Bit = true;
 
-	if (isCpuScalerEnabled()) {
-		videoSetMode(MODE_5_2D | (consoleEnable ? DISPLAY_BG0_ACTIVE : 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-		videoSetModeSub(MODE_3_2D /*| DISPLAY_BG0_ACTIVE*/ | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
-
-		vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
-		vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
-
-		vramSetBankC(VRAM_C_SUB_BG_0x06200000);
-		vramSetBankD(VRAM_D_SUB_SPRITE);
-
-		vramSetBankH(VRAM_H_LCD);
+	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
+	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
 
+	if (isCpuScalerEnabled()) {
 		REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
 
 		REG_BG3PA = 256;
@@ -291,17 +264,6 @@ void displayMode8Bit() {
 		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
 
 	} else {
-		videoSetMode(MODE_5_2D | (consoleEnable ? DISPLAY_BG0_ACTIVE : 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-		videoSetModeSub(MODE_3_2D /*| DISPLAY_BG0_ACTIVE*/ | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
-
-		vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
-		vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
-
-		vramSetBankC(VRAM_C_SUB_BG_0x06200000);
-		vramSetBankD(VRAM_D_SUB_SPRITE);
-
-		vramSetBankH(VRAM_H_LCD);
-
 		REG_BG3CNT = BG_BMP8_512x256 | BG_BMP_BASE(8);
 
 		REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
@@ -310,36 +272,17 @@ void displayMode8Bit() {
 		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
 	}
 
+#ifdef DISABLE_TEXT_CONSOLE
+	videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
+	vramSetBankD(VRAM_D_SUB_SPRITE);
 	REG_BG3CNT_SUB = BG_BMP8_512x256;
 
 	REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
 	REG_BG3PB_SUB = 0;
 	REG_BG3PC_SUB = 0;
 	REG_BG3PD_SUB = (int) (subScreenHeight / 192.0f * 256);
-
-
-
-	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 2, 0, true, true);
-
-	// Set this again because consoleinit resets it
-	videoSetMode(MODE_5_2D | (consoleEnable ? DISPLAY_BG0_ACTIVE : 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-
-	// Move the cursor to the bottom of the screen using ANSI escape code
-	printf("\033[23;0f");
-
-
-	for (int r = 0; r < 32 * 32; r++) {
-		((u16 *) SCREEN_BASE_BLOCK(2))[r] = buffer[r];
-	}
-
-	// ConsoleInit destroys the hardware palette :-(
-	if (OSystem_DS::instance()) {
-		OSystem_DS::instance()->restoreHardwarePalette();
-	}
-
-	#ifdef HEAVY_LOGGING
-	printf("done\n");
-	#endif
+#endif
 
 	if (gameScreenSwap) {
 		lcdMainOnTop();
@@ -391,79 +334,34 @@ void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX,
 
 
 void displayMode16Bit() {
-	#ifdef HEAVY_LOGGING
-	printf("displayMode16Bit...");
-	#endif
-
-	u16 buffer[32 * 32 * 2];
-
-	if (!displayModeIs8Bit) {
-		for (int r = 0; r < 32 * 32; r++) {
-			buffer[r] = ((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r];
-		}
-	} else {
+	if (displayModeIs8Bit) {
 		saveGameBackBuffer();
-		for (int r = 0; r < 32 * 32; r++) {
-			buffer[r] = ((u16 *) SCREEN_BASE_BLOCK(2))[r];
-		}
 	}
 
-
-	videoSetMode(MODE_5_2D | /*DISPLAY_BG0_ACTIVE |*/ DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
+	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
 
 	vramSetBankA(VRAM_A_MAIN_BG);
 	vramSetBankB(VRAM_B_MAIN_BG);
 	vramSetBankC(VRAM_C_MAIN_BG);
 	vramSetBankD(VRAM_D_MAIN_BG);
-	vramSetBankH(VRAM_H_SUB_BG);
 
 	REG_BG3CNT = BG_BMP16_512x256;
 	highBuffer = false;
 
-
 	memset(BG_GFX, 0, 512 * 256 * 2);
 
-	savedPalEntry255 = BG_PALETTE_SUB[255];
-	BG_PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
-
-	// Do text stuff
-	REG_BG0CNT_SUB = BG_MAP_BASE(4) | BG_TILE_BASE(0);
-	REG_BG0VOFS_SUB = 0;
-
-	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 4, 0, false, true);
-
-	for (int r = 0; r < 32 * 32; r++) {
-		((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r] = buffer[r];
-	}
-
-	consoleSetWindow(NULL, 0, 0, 32, 24);
-
 	lcdMainOnBottom();
 
 	displayModeIs8Bit = false;
 
-	// ConsoleInit destroys the hardware palette :-(
-	OSystem_DS::instance()->restoreHardwarePalette();
-
 	REG_BG3PA = isCpuScalerEnabled() ? 256 : (int) (1.25f * 256);
 	REG_BG3PB = 0;
 	REG_BG3PC = 0;
 	REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
-
-	#ifdef HEAVY_LOGGING
-	printf("done\n");
-	#endif
-
-	BG_PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
-
 }
 
 
 void displayMode16BitFlipBuffer() {
-	#ifdef HEAVY_LOGGING
-	printf("Flip %s...", displayModeIs8Bit ? "8bpp" : "16bpp");
-	#endif
 	if (!displayModeIs8Bit) {
 		u16 *back = get16BitBackBuffer();
 
@@ -485,9 +383,6 @@ void displayMode16BitFlipBuffer() {
 			BG_PALETTE,
 			getGameHeight() );
 	}
-	#ifdef HEAVY_LOGGING
-	printf("done\n");
-	#endif
 }
 
 void setShakePos(int shakeXOffset, int shakeYOffset) {
@@ -604,9 +499,10 @@ void setZoomedScreenScroll(int x, int y, bool shake) {
 			touchY = y >> 8;
 		}
 
-
+#ifdef DISABLE_TEXT_CONSOLE
 		REG_BG3X_SUB = x + ((shake && (frameCount & 1) == 0)? 64: 0);
 		REG_BG3Y_SUB = y;
+#endif
 }
 
 void setZoomedScreenScale(int x, int y) {
@@ -615,10 +511,12 @@ void setZoomedScreenScale(int x, int y) {
 			touchScY = y;
 		}
 
+#ifdef DISABLE_TEXT_CONSOLE
 		REG_BG3PA_SUB = x;
 		REG_BG3PB_SUB = 0;
 		REG_BG3PC_SUB = 0;
 		REG_BG3PD_SUB = y;
+#endif
 }
 
 Common::Point transformPoint(uint16 x, uint16 y) {
@@ -767,22 +665,11 @@ void setTopScreenTarget(int x, int y) {
 
 void initHardware() {
 	powerOn(POWER_ALL);
-	vramSetBankD(VRAM_D_SUB_SPRITE);
-	vramSetBankE(VRAM_E_MAIN_SPRITE);
 
 	for (int r = 0; r < 255; r++) {
 		BG_PALETTE[r] = 0;
 	}
 
-	BG_PALETTE[255] = RGB15(0,31,0);
-
-
-	for (int r = 0; r < 255; r++) {
-		BG_PALETTE_SUB[r] = 0;
-	}
-
-	BG_PALETTE_SUB[255] = RGB15(0,31,0);
-
 	// Allocate save buffer for game screen
 	displayMode16Bit();
 
@@ -800,8 +687,6 @@ void initHardware() {
 	frameCount = 0;
 	callback = NULL;
 
-	BG_PALETTE[255] = RGB15(31,31,31);//by default font will be rendered with color 255
-
 	//irqs are nice
 	irqSet(IRQ_VBLANK, VBlankHandler);
 	irqEnable(IRQ_VBLANK);
@@ -811,7 +696,16 @@ void initHardware() {
 	timerStart(0, ClockDivider_1, (u16)TIMER_FREQ(1000), timerTickHandler);
 	REG_IME = 1;
 
-	BG_PALETTE[255] = RGB15(0,0,31);
+	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+	vramSetBankD(VRAM_D_SUB_SPRITE);
+	vramSetBankE(VRAM_E_MAIN_SPRITE);
+
+#ifndef DISABLE_TEXT_CONSOLE
+	vramSetBankH(VRAM_H_SUB_BG);
+	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 15, 0, false, true);
+
+	printf("Testing the console\n");
+#endif
 
 	initSprites();
 
@@ -838,7 +732,7 @@ void *fastRamAlloc(int size) {
 	void *result = (void *) fastRamPointer;
 	fastRamPointer += size;
 	if(fastRamPointer > fastRamData + FAST_RAM_SIZE) {
-		printf("FastRam (ITCM) allocation failed!\n");
+		warning("FastRam (ITCM) allocation failed");
 		return malloc(size);
 	}
 	return result;
@@ -855,20 +749,10 @@ void fastRamReset() {
 /////////////////
 
 int main(int argc, char **argv) {
-#ifndef DISABLE_TEXT_CONSOLE
-	consoleDebugInit(DebugDevice_NOCASH);
-	nocashMessage("startup\n");
-#endif
-
 	DS::initHardware();
 
 	defaultExceptionHandler();
 
-	if (!nitroFSInit(NULL)) {
-		printf("nitroFSInit failure: terminating\n");
-		return(1);
-	}
-
 	g_system = new OSystem_DS();
 	assert(g_system);
 
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 4d4a25f14e..f258cbf06e 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -27,6 +27,9 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
 #define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
 
+#include <nds.h>
+#include <filesystem.h>
+
 #include "common/scummsys.h"
 #include "common/system.h"
 
@@ -36,7 +39,6 @@
 #include "common/translation.h"
 
 #include "osystem_ds.h"
-#include "nds.h"
 #include "dsmain.h"
 #include "common/config-manager.h"
 #include "common/str.h"
@@ -58,6 +60,8 @@ OSystem_DS::OSystem_DS()
 	_disableCursorPalette(true), _graphicsEnable(true), _gammaValue(0)
 {
 	_instance = this;
+
+	nitroFSInit(NULL);
 	_fsFactory = new DevoptabFilesystemFactory();
 }
 
@@ -142,7 +146,9 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 			if (DS::getIsDisplayMode8Bit()) {
 				int col = applyGamma(paletteValue);
 				BG_PALETTE[r] = col;
+#ifdef DISABLE_TEXT_CONSOLE
 				BG_PALETTE_SUB[r] = col;
+#endif
 			}
 
 			_palette[r] = paletteValue;
@@ -152,16 +158,6 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 	}
 }
 
-void OSystem_DS::restoreHardwarePalette() {
-	// Set the hardware palette up based on the stored palette
-
-	for (int r = 0; r < 255; r++) {
-		int col = applyGamma(_palette[r]);
-		BG_PALETTE[r] = col;
-		BG_PALETTE_SUB[r] = col;
-	}
-}
-
 void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
 
 	for (unsigned int r = start; r < start + num; r++) {
@@ -202,7 +198,9 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 
 	u16 *bg;
 	s32 stride;
+#ifdef DISABLE_TEXT_CONSOLE
 	u16 *bgSub = (u16 *)BG_GFX_SUB;
+#endif
 
 	// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
 	// to save a few pennies/euro cents on the hardware.
@@ -224,7 +222,9 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 
 		for (int dy = y; dy < y + h; dy++) {
 			u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
+#ifdef DISABLE_TEXT_CONSOLE
 			u8 *destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
+#endif
 			const u8 *src = (const u8 *) buf + (pitch * by);
 
 			u32 dx;
@@ -240,23 +240,32 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 				mix = (mix & 0x00FF) | (*src++ << 8);
 
 				*dest = mix;
+#ifdef DISABLE_TEXT_CONSOLE
 				*destSub = mix;
+#endif
 
 				dest += 2;
+#ifdef DISABLE_TEXT_CONSOLE
 				destSub += 2;
+#endif
+
 				pixelsLeft--;
 			}
 
 			// We can now assume dest is aligned
 			u16 *dest16 = (u16 *) dest;
+#ifdef DISABLE_TEXT_CONSOLE
 			u16 *destSub16 = (u16 *) destSub;
+#endif
 
 			for (dx = 0; dx < pixelsLeft; dx+=2) {
 				u16 mix;
 
 				mix = *src + (*(src + 1) << 8);
 				*dest16++ = mix;
+#ifdef DISABLE_TEXT_CONSOLE
 				*destSub16++ = mix;
+#endif
 				src += 2;
 			}
 
@@ -270,7 +279,9 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 				mix = (mix & 0x00FF) | ((*src++) << 8);
 
 				*dest16 = mix;
+#ifdef DISABLE_TEXT_CONSOLE
 				*destSub16 = mix;
+#endif
 			}
 
 			by++;
@@ -285,17 +296,23 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 
 		for (int dy = y; dy < y + h; dy++) {
 			u16 *dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
+#ifdef DISABLE_TEXT_CONSOLE
 			u16 *dest2 = bgSub + (dy << 8) + (x >> 1);
+#endif
 
 			DC_FlushRange(src, w << 1);
 			DC_FlushRange(dest1, w << 1);
+#ifdef DISABLE_TEXT_CONSOLE
 			DC_FlushRange(dest2, w << 1);
+#endif
 
 			dmaCopyHalfWords(3, src, dest1, w);
 
+#ifdef DISABLE_TEXT_CONSOLE
 			if ((!_frameBufferExists) || (buf == _framebuffer.getPixels())) {
 				dmaCopyHalfWords(2, src, dest2, w);
 			}
+#endif
 
 			while (dmaBusy(2) || dmaBusy(3));
 
@@ -520,9 +537,8 @@ void OSystem_DS::clearFocusRectangle() {
 
 void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
 #ifndef DISABLE_TEXT_CONSOLE
-	nocashMessage((char *)message);
-#endif
 	printf("%s", message);
+#endif
 }
 
 u16 OSystem_DS::applyGamma(u16 color) {
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index da42454f23..dbdcb52f99 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -84,8 +84,6 @@ protected:
 	virtual void grabPalette(byte *colors, uint start, uint num) const;
 
 public:
-	void restoreHardwarePalette();
-
 	virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
 	virtual void updateScreen();
 	virtual void setShakePos(int shakeXOffset, int shakeYOffset);
diff --git a/configure b/configure
index 52c09f0ac5..bbac28ed05 100755
--- a/configure
+++ b/configure
@@ -1881,7 +1881,7 @@ else
 fi
 
 case $_host in
-arm-*riscos | caanoo | gp2x | gp2xwiz | openpandora | psp | psp2 | switch)
+arm-*riscos | caanoo | ds | gp2x | gp2xwiz | openpandora | psp | psp2 | switch)
 	if test "$_debug_build" = auto; then
 		# If you want to debug one of these platforms, use '--disable-optimizations --enable-debug'
 		_debug_build=no
@@ -3401,12 +3401,14 @@ if test -n "$_host"; then
 			_port_mk="backends/platform/dc/dreamcast.mk"
 			;;
 		ds)
+			if test "$_debug_build" != yes; then
+				append_var DEFINES "-DDISABLE_TEXT_CONSOLE"
+			fi
 			append_var DEFINES "-DDISABLE_COMMAND_LINE"
 			append_var DEFINES "-DDISABLE_DOSBOX_OPL"
 			append_var DEFINES "-DDISABLE_FANCY_THEMES"
 			append_var DEFINES "-DDISABLE_SID"
 			append_var DEFINES "-DDISABLE_NES_APU"
-			append_var DEFINES "-DDISABLE_TEXT_CONSOLE"
 			append_var DEFINES "-DREDUCE_MEMORY_USAGE"
 			append_var DEFINES "-DSTREAM_AUDIO_FROM_DISK"
 			append_var DEFINES "-DVECTOR_RENDERER_FORMAT=1555"


Commit: 926ec07532a2099beb7a1aeef533ae6588962509
    https://github.com/scummvm/scummvm/commit/926ec07532a2099beb7a1aeef533ae6588962509
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Simplify the framebuffer code

Changed paths:
  R backends/platform/ds/arm9/source/blitters.cpp
    backends/platform/ds/arm9/source/blitters.h
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsmain.h
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/osystem_ds.h


diff --git a/backends/platform/ds/arm9/source/blitters.cpp b/backends/platform/ds/arm9/source/blitters.cpp
deleted file mode 100644
index c58c1f292a..0000000000
--- a/backends/platform/ds/arm9/source/blitters.cpp
+++ /dev/null
@@ -1,391 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "blitters.h"
-#define CHARSET_MASK_TRANSPARENCY 253
-
-//#define PERFECT_5_TO_4_RESCALING
-
-namespace DS {
-
-void asmDrawStripToScreen(int height, int width, byte const *text, byte const *src, byte *dst,
-	int vsPitch, int vmScreenWidth, int textSurfacePitch) {
-
-	if (height <= 0)
-		height = 1;
-	if (width < 4)
-		return;
-
-	width &= ~4;
-
-	asm (	"mov r5, %0\n"				// Height
-			"yLoop:\n"
-			"mov r3, #0\n"				// X pos
-
-			"xLoop:\n"
-
-			"ldr r4, [%2, r3]\n"		// Load text layer word
-			"cmp r4, %5\n"
-			"bne singleByteCompare\n"
-			"ldr r4, [%3, r3]\n"
-			"str r4, [%4, r3]\n"
-			"add r3, r3, #4\n"
-			"cmp r3, %1\n"				// x == width?
-			"blt xLoop\n"
-
-			"add %2, %2, %8\n"			// src += vs->pitch
-			"add %3, %3, %6\n"			// dst += _vm->_screenWidth
-			"add %4, %4, %7\n"			// text += _textSurface.pitch
-			"sub r5, r5, #1\n"			// y -= 1
-			"cmp r5, #0\n"				// y == 0?
-			"bne yLoop\n"
-			"b end\n"
-
-
-			"singleByteCompare:\n"
-			"ldrb r4, [%2, r3]\n"		// Load text byte
-			"cmps r4, %5, lsr #24\n"	// Compare with mask
-			"strneb r4, [%4, r3]\n"		// Store if not equal
-			"ldreqb r4, [%3, r3]\n"		// Otherwise Load src byte
-			"streqb r4, [%4, r3]\n"		// Store it
-			"add r3, r3, #1\n"
-
-			"ldrb r4, [%2, r3]\n"		// Load text byte
-			"cmps r4, %5, lsr #24\n"	// Compare with mask
-			"strneb r4, [%4, r3]\n"		// Store if not equal
-			"ldreqb r4, [%3, r3]\n"		// Otherwise Load src byte
-			"streqb r4, [%4, r3]\n"		// Store it
-			"add r3, r3, #1\n"
-
-			"ldrb r4, [%2, r3]\n"		// Load text byte
-			"cmps r4, %5, lsr #24\n"	// Compare with mask
-			"strneb r4, [%4, r3]\n"		// Store if not equal
-			"ldreqb r4, [%3, r3]\n"		// Otherwise Load src byte
-			"streqb r4, [%4, r3]\n"		// Store it
-			"add r3, r3, #1\n"
-
-			"ldrb r4, [%2, r3]\n"		// Load text byte
-			"cmps r4, %5, lsr #24\n"	// Compare with mask
-			"strneb r4, [%4, r3]\n"		// Store if not equal
-			"ldreqb r4, [%3, r3]\n"		// Otherwise Load src byte
-			"streqb r4, [%4, r3]\n"		// Store it
-			"add r3, r3, #1\n"
-
-			"cmps r3, %1\n"				// x == width?
-			"blt xLoop\n"				// Repeat
-			"add %2, %2, %8\n"			// src += vs->pitch
-			"add %3, %3, %6\n"			// dst += _vm->_screenWidth
-			"add %4, %4, %7\n"			// text += _textSurface.pitch
-			"sub r5, r5, #1\n"			// y -= 1
-			"cmp r5, #0\n"				// y == 0?
-			"bne yLoop\n"
-
-			"end:\n"
-		: /* no output registers */
-		: "r" (height), "r" (width), "r" (text), "r" (src), "r" (dst), "r" (CHARSET_MASK_TRANSPARENCY | (CHARSET_MASK_TRANSPARENCY << 8) | (CHARSET_MASK_TRANSPARENCY << 16) | (CHARSET_MASK_TRANSPARENCY << 24)),
-			"r" (vsPitch), "r" (vmScreenWidth), "r" (textSurfacePitch)
-		: "r5", "r3", "r4", "%2", "%3", "%4", "memory");
-}
-
-
-
-void asmCopy8Col(byte *dst, int dstPitch, const byte *src, int height) {
-	asm("ands r0, %3, #1\n"
-		 "addne %3, %3, #1\n"
-		 "bne roll2\n"
-
-		 "yLoop2:\n"
-		 "ldr r0, [%2, #0]\n"
-		 "str r0, [%0, #0]\n"
-		 "ldr r0, [%2, #4]\n"
-		 "str r0, [%0, #4]\n"
-		 "add %0, %0, %1\n"
-		 "add %2, %2, %1\n"
-		 "roll2:\n"
-		 "ldr r0, [%2, #0]\n"
-		 "str r0, [%0, #0]\n"
-		 "ldr r0, [%2, #4]\n"
-		 "str r0, [%0, #4]\n"
-		 "add %0, %0, %1\n"
-		 "add %2, %2, %1\n"
-		 "subs %3, %3, #2\n"
-		 "bne yLoop2\n"
-
-		: /* no output registers */
-		: "r" (dst), "r" (dstPitch), "r" (src), "r" (height)
-		: "r0", "%0", "%2", "%3");
-}
-
-static bool isDivBy5Ready = false;
-static u32  DIV_BY_5[160];
-
-void ComputeDivBy5TableIFN() {
-    if (isDivBy5Ready)
-        return;
-    isDivBy5Ready = true;
-
-    for (int i = 0; i < 160; ++i) {
-        DIV_BY_5[i] = (2*i+5)/10;
-    }
-}
-
-#ifdef PERFECT_5_TO_4_RESCALING
-static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3, u16 s4,
-                                                    u16 *dest) {
-    u32 bs0 = s0 & 0x1F;
-    u32 bs1 = s1 & 0x1F;
-    u32 bs2 = s2 & 0x1F;
-    u32 bs3 = s3 & 0x1F;
-    u32 bs4 = s4 & 0x1F;
-
-#if 0
-    u32 gs0 = (s0 >> 5) & 0x1F;
-    u32 gs1 = (s1 >> 5) & 0x1F;
-    u32 gs2 = (s2 >> 5) & 0x1F;
-    u32 gs3 = (s3 >> 5) & 0x1F;
-    u32 gs4 = (s4 >> 5) & 0x1F;
-
-    u32 rs0 = (s0 >> 10) & 0x1F;
-    u32 rs1 = (s1 >> 10) & 0x1F;
-    u32 rs2 = (s2 >> 10) & 0x1F;
-    u32 rs3 = (s3 >> 10) & 0x1F;
-    u32 rs4 = (s4 >> 10) & 0x1F;
-#else
-    // The compiler absolutely wants to use 0x1F as an immediate, which makes it unable to fold the shift during the and
-    u32 mask = 0x1F;
-    u32 gs0, gs1, gs2, gs3, gs4;
-    asm("and %0, %2, %1, lsr #5" : "=r"(gs0) : "r"(s0), "r"(mask) : );
-    asm("and %0, %2, %1, lsr #5" : "=r"(gs1) : "r"(s1), "r"(mask) : );
-    asm("and %0, %2, %1, lsr #5" : "=r"(gs2) : "r"(s2), "r"(mask) : );
-    asm("and %0, %2, %1, lsr #5" : "=r"(gs3) : "r"(s3), "r"(mask) : );
-    asm("and %0, %2, %1, lsr #5" : "=r"(gs4) : "r"(s4), "r"(mask) : );
-    u32 rs0, rs1, rs2, rs3, rs4;
-    asm("and %0, %2, %1, lsr #10" : "=r"(rs0) : "r"(s0), "r"(mask) : );
-    asm("and %0, %2, %1, lsr #10" : "=r"(rs1) : "r"(s1), "r"(mask) : );
-    asm("and %0, %2, %1, lsr #10" : "=r"(rs2) : "r"(s2), "r"(mask) : );
-    asm("and %0, %2, %1, lsr #10" : "=r"(rs3) : "r"(s3), "r"(mask) : );
-    asm("and %0, %2, %1, lsr #10" : "=r"(rs4) : "r"(s4), "r"(mask) : );
-#endif
-
-    u32 rd0 = 4*rs0 +   rs1;
-    u32 rd1 = 2*rs1 + rs1 + 2*rs2;
-    u32 rd2 = 2*rs2 + 2*rs3 + rs3;
-    u32 rd3 =   rs3 + 4*rs4;
-
-    u32 gd0 = 4*gs0 +   gs1;
-    u32 gd1 = 2*gs1 + gs1 + 2*gs2;
-    u32 gd2 = 2*gs2 + 2*gs3 + gs3;
-    u32 gd3 =   gs3 + 4*gs4;
-
-    u32 bd0 = 4*bs0 +   bs1;
-    u32 bd1 = 2*bs1 + bs1 + 2*bs2;
-    u32 bd2 = 2*bs2 + 2*bs3 + bs3;
-    u32 bd3 =   bs3 + 4*bs4;
-
-#if 0
-    // Offsetting for correct rounding
-    rd0 = rd0*2+5; rd1 = rd1*2+5; rd2 = rd2*2+5; rd3 = rd3*2+5;
-    gd0 = gd0*2+5; gd1 = gd1*2+5; gd2 = gd2*2+5; gd3 = gd3*2+5;
-    bd0 = bd0*2+5; bd1 = bd1*2+5; bd2 = bd2*2+5; bd3 = bd3*2+5;
-
-	rd0 = (rd0 * 51) >> 9; rd1 = (rd1 * 51) >> 9; rd2 = (rd2 * 51) >> 9; rd3 = (rd3 * 51) >> 9;
-	gd0 = (gd0 * 51) >> 9; gd1 = (gd1 * 51) >> 9; gd2 = (gd2 * 51) >> 9; gd3 = (gd3 * 51) >> 9;
-	bd0 = (bd0 * 51) >> 9; bd1 = (bd1 * 51) >> 9; bd2 = (bd2 * 51) >> 9; bd3 = (bd3 * 51) >> 9;
-#else
-	rd0 = DIV_BY_5[rd0]; rd1 = DIV_BY_5[rd1]; rd2 = DIV_BY_5[rd2]; rd3 = DIV_BY_5[rd3];
-	gd0 = DIV_BY_5[gd0]; gd1 = DIV_BY_5[gd1]; gd2 = DIV_BY_5[gd2]; gd3 = DIV_BY_5[gd3];
-	bd0 = DIV_BY_5[bd0]; bd1 = DIV_BY_5[bd1]; bd2 = DIV_BY_5[bd2]; bd3 = DIV_BY_5[bd3];
-#endif
-
-    u32 d10 = 0x80008000 | (rd1 << 26) | (gd1 << 21) | (bd1 << 16) | (rd0 << 10) | (gd0 << 5) | bd0;
-    u32 d32 = 0x80008000 | (rd3 << 26) | (gd3 << 21) | (bd3 << 16) | (rd2 << 10) | (gd2 << 5) | bd2;
-
-    ((u32 *)dest)[0] = d10;
-    ((u32 *)dest)[1] = d32;
-}
-#else
-static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3, u16 s4,
-                                                    u16 *dest) {
-    static const u32 MASK = 0x03E07C1F;
-
-    u32 argbargbs0 = u32(s0) | (u32(s0) << 16);
-    u32 argbargbs1 = u32(s1) | (u32(s1) << 16);
-    u32 argbargbs2 = u32(s2) | (u32(s2) << 16);
-    u32 argbargbs3 = u32(s3) | (u32(s3) << 16);
-    u32 argbargbs4 = u32(s4) | (u32(s4) << 16);
-
-    u32 grbs0 = argbargbs0 & MASK;
-    u32 grbs1 = argbargbs1 & MASK;
-    u32 grbs2 = argbargbs2 & MASK;
-    u32 grbs3 = argbargbs3 & MASK;
-    u32 grbs4 = argbargbs4 & MASK;
-
-    u32 grbd0 = (3*grbs0 +   grbs1) >> 2;
-    u32 grbd1 = (  grbs1 +   grbs2) >> 1;
-    u32 grbd2 = (  grbs2 +   grbs3) >> 1;
-    u32 grbd3 = (  grbs3 + 3*grbs4) >> 2;
-
-    grbd0 &= MASK;
-    grbd1 &= MASK;
-    grbd2 &= MASK;
-    grbd3 &= MASK;
-
-    u32 d0 = grbd0 | (grbd0 >> 16);
-    u32 d1 = grbd1 | (grbd1 >> 16);
-    u32 d2 = grbd2 | (grbd2 >> 16);
-    u32 d3 = grbd3 | (grbd3 >> 16);
-
-    d0 &= 0xFFFF;
-    d1 &= 0xFFFF;
-    d2 &= 0xFFFF;
-    d3 &= 0xFFFF;
-
-    d0 |= 0x8000;
-    d1 |= 0x8000;
-    d2 |= 0x8000;
-    d3 |= 0x8000;
-
-    dest[0] = d0;
-    dest[1] = d1;
-    dest[2] = d2;
-    dest[3] = d3;
-}
-#endif
-
-static inline void RescaleBlock_5x8888_To_4x1555( u32 s0, u32 s1, u32 s2, u32 s3, u32 s4,
-                                                    u16 *dest) {
-    u32 d0 = 4*s0 +   s1;
-    u32 d1 = 2*s1 +   s1 + 2*s2;
-
-    u32 bd0 = (d0 << 24) >> 24;
-    u32 bd1 = (d1 << 24) >> 24;
-    u32 gd0 = (d0 << 16) >> 24;
-    u32 gd1 = (d1 << 16) >> 24;
-    u32 rd0 = (d0 >> 16);
-    u32 rd1 = (d1 >> 16);
-
-	rd0 = DIV_BY_5[rd0]; rd1 = DIV_BY_5[rd1];
-	gd0 = DIV_BY_5[gd0]; gd1 = DIV_BY_5[gd1];
-	bd0 = DIV_BY_5[bd0]; bd1 = DIV_BY_5[bd1];
-    u32 d10 = 0x80008000 | (rd1 << 26) | (gd1 << 21) | (bd1 << 16) | (rd0 << 10) | (gd0 << 5) | bd0;
-    ((u32 *)dest)[0] = d10;
-
-    u32 d2 = 2*s2 + 2*s3 +   s3;
-    u32 d3 =   s3 + 4*s4;
-
-    u32 bd2 = (d2 << 24) >> 24;
-    u32 bd3 = (d3 << 24) >> 24;
-    u32 gd2 = (d2 << 16) >> 24;
-    u32 gd3 = (d3 << 16) >> 24;
-    u32 rd2 = (d2 >> 16);
-    u32 rd3 = (d3 >> 16);
-
-    rd2 = DIV_BY_5[rd2]; rd3 = DIV_BY_5[rd3];
-    gd2 = DIV_BY_5[gd2]; gd3 = DIV_BY_5[gd3];
-    bd2 = DIV_BY_5[bd2]; bd3 = DIV_BY_5[bd3];
-    u32 d32 = 0x80008000 | (rd3 << 26) | (gd3 << 21) | (bd3 << 16) | (rd2 << 10) | (gd2 << 5) | bd2;
-
-    ((u32 *)dest)[1] = d32;
-}
-
-// Can't work in place
-#ifdef PERFECT_5_TO_4_RESCALING
-static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16 *dest, const u8 *src, const u32 *palette) {
-    ComputeDivBy5TableIFN();
-
-    for (size_t i = 0; i < 64; ++i) {
-        u32 s0 = palette[src[5*i+0]];
-        u32 s1 = palette[src[5*i+1]];
-        u32 s2 = palette[src[5*i+2]];
-        u32 s3 = palette[src[5*i+3]];
-        u32 s4 = palette[src[5*i+4]];
-
-        RescaleBlock_5x8888_To_4x1555(s0, s1, s2, s3, s4, dest+4*i);
-    }
-}
-#else
-static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16 *dest, const u8 *src, const u16 *palette) {
-    for (size_t i = 0; i < 64; ++i) {
-        u16 s0 = palette[src[5*i+0]];
-        u16 s1 = palette[src[5*i+1]];
-        u16 s2 = palette[src[5*i+2]];
-        u16 s3 = palette[src[5*i+3]];
-        u16 s4 = palette[src[5*i+4]];
-
-        RescaleBlock_5x1555_To_4x1555(s0, s1, s2, s3, s4, dest+4*i);
-    }
-}
-#endif
-
-
-// Can work in place, because it's a contraction
-static inline void Rescale_320x1555Scanline_To_256x1555Scanline(u16 *dest, const u16 *src) {
-    ComputeDivBy5TableIFN();
-
-    for (size_t i = 0; i < 64; ++i) {
-        u16 s0 = src[5*i+0];
-        u16 s1 = src[5*i+1];
-        u16 s2 = src[5*i+2];
-        u16 s3 = src[5*i+3];
-        u16 s4 = src[5*i+4];
-
-        RescaleBlock_5x1555_To_4x1555(s0, s1, s2, s3, s4, dest+4*i);
-    }
-}
-
-#ifdef PERFECT_5_TO_4_RESCALING
-void Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette) {
-	u32 fastRam[768];
-
-    // Palette lookup -> 0_888
-    for (size_t i = 0; i < 256; ++i) {
-        u32 col = palette[i];
-        u32 result = col & 0x0000001F;
-        result |= (col << 3) & 0x00001F00;
-        result |= (col << 6) & 0x001F0000;
-
-        fastRam[i] = result;
-    }
-
-	for (size_t i = 0; i < 200; ++i) {
-		Rescale_320xPAL8Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride, fastRam);
-	}
-}
-#else
-void Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette) {
-	u16 fastRam[256];
-    for (size_t i = 0; i < 128; ++i)
-        ((u32 *)fastRam)[i] = ((const u32*)palette)[i];
-
-	for (size_t i = 0; i < 200; ++i) {
-		Rescale_320xPAL8Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride, fastRam);
-	}
-}
-#endif
-
-void Rescale_320x256x1555_To_256x256x1555(u16 *dest, const u16 *src, int destStride, int srcStride) {
-	for (size_t i = 0; i < 200; ++i) {
-		Rescale_320x1555Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride);
-	}
-}
-
-} // End of namespace DS
diff --git a/backends/platform/ds/arm9/source/blitters.h b/backends/platform/ds/arm9/source/blitters.h
index 602cde4755..05c9141e8c 100644
--- a/backends/platform/ds/arm9/source/blitters.h
+++ b/backends/platform/ds/arm9/source/blitters.h
@@ -20,35 +20,14 @@
  *
  */
 
- #ifndef _BLITTERS_H_
- #define _BLITTERS_H_
-
-#define USING_ARM_BLITTERS
-
-#ifndef USING_ARM_BLITTERS
-
-namespace DS {
-
-void asmDrawStripToScreen(int height, int width, byte const *text, byte const *src, byte *dst,
-	int vsPitch, int vmScreenWidth, int textSurfacePitch);
-void asmCopy8Col(byte *dst, int dstPitch, const byte *src, int height);
-void Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette);
-void Rescale_320x256x1555_To_256x256x1555(u16 *dest, const u16 *src, int destStride, int srcStride);
-
-} // End of namespace DS
-
-#else
+#ifndef _BLITTERS_H_
+#define _BLITTERS_H_
 
 extern "C" {
 
-void ITCM_CODE asmDrawStripToScreen(int height, int width, byte const *text, byte const *src, byte *dst,
-	int vsPitch, int vmScreenWidth, int textSurfacePitch);
-void ITCM_CODE asmCopy8Col(byte *dst, int dstPitch, const byte *src, int height);
 void ITCM_CODE Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette, u32 numLines);
 void ITCM_CODE Rescale_320x256x1555_To_256x256x1555(u16 *dest, const u16 *src, int destStride, int srcStride);
 
 }
 
 #endif
-
-#endif
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 93ba6b815e..eed96bc7c0 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -80,7 +80,6 @@
 #include "dsmain.h"
 #include "osystem_ds.h"
 #include "dsoptions.h"
-#include "blitters.h"
 #include "engines/engine.h"
 
 #include "backends/plugins/ds/ds-provider.h"
@@ -120,7 +119,6 @@ static int subScreenScale = 256;
 
 
 // Saved buffers
-static bool highBuffer;
 static bool displayModeIs8Bit = false;
 
 static bool gameScreenSwap = false;
@@ -152,8 +150,6 @@ static int gameHeight = 200;
 static bool twoHundredPercentFixedScale = false;
 static bool cpuScalerEnable = false;
 
-static u8 *scalerBackBuffer = NULL;
-
 void setIcon(int num, int x, int y, int imageNum, int flags, bool enable);
 void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable);
 
@@ -226,18 +222,6 @@ void initSprites() {
 	updateOAM();
 }
 
-
-void saveGameBackBuffer() {
-
-	// Sometimes the only copy of the game screen is in video memory.
-	// So, I lock the video memory here, as if I'm going to modify it.  This
-	// forces OSystem_DS to create a system memory copy if one doesn't exist.
-	// This will be automatially restored by OSystem_DS::updateScreen().
-
-	OSystem_DS::instance()->lockScreen();
-	OSystem_DS::instance()->unlockScreen();
-}
-
 void set200PercentFixedScale(bool on) {
 	twoHundredPercentFixedScale = on;
 }
@@ -334,10 +318,6 @@ void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX,
 
 
 void displayMode16Bit() {
-	if (displayModeIs8Bit) {
-		saveGameBackBuffer();
-	}
-
 	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
 
 	vramSetBankA(VRAM_A_MAIN_BG);
@@ -346,7 +326,6 @@ void displayMode16Bit() {
 	vramSetBankD(VRAM_D_MAIN_BG);
 
 	REG_BG3CNT = BG_BMP16_512x256;
-	highBuffer = false;
 
 	memset(BG_GFX, 0, 512 * 256 * 2);
 
@@ -361,30 +340,6 @@ void displayMode16Bit() {
 }
 
 
-void displayMode16BitFlipBuffer() {
-	if (!displayModeIs8Bit) {
-		u16 *back = get16BitBackBuffer();
-
-		if (isCpuScalerEnabled()) {
-			Rescale_320x256x1555_To_256x256x1555(BG_GFX, back, 512, 512);
-		} else {
-			for (int r = 0; r < 512 * 256; r++) {
-				*(BG_GFX + r) = *(back + r);
-			}
-		}
-	} else if (isCpuScalerEnabled()) {
-		const u8 *back = (const u8*)get8BitBackBuffer();
-		u16 *base = BG_GFX + 0x10000;
-		Rescale_320x256xPAL8_To_256x256x1555(
-			base,
-			back,
-			256,
-			get8BitBackBufferStride(),
-			BG_PALETTE,
-			getGameHeight() );
-	}
-}
-
 void setShakePos(int shakeXOffset, int shakeYOffset) {
 	s_shakeXOffset = shakeXOffset;
 	s_shakeYOffset = shakeYOffset;
@@ -395,29 +350,6 @@ u16 *get16BitBackBuffer() {
 	return BG_GFX + 0x20000;
 }
 
-s32 get8BitBackBufferStride() {
-	// When the CPU scaler is enabled, the back buffer is in system RAM and is
-	// 320 pixels wide. When the CPU scaler is disabled, the back buffer is in
-	// video memory and therefore must have a 512 pixel stride.
-
-	if (isCpuScalerEnabled()){
-		return 320;
-	} else {
-		return 512;
-	}
-}
-
-u16 *getScalerBuffer() {
-	return (u16 *) scalerBackBuffer;
-}
-
-u16 *get8BitBackBuffer() {
-	if (isCpuScalerEnabled())
-		return (u16 *) scalerBackBuffer;
-	else
-		return BG_GFX + 0x10000;		// 16bit qty!
-}
-
 void doTimerCallback() {
 	if (callback) {
 		if (callbackTimer <= 0) {
@@ -673,7 +605,6 @@ void initHardware() {
 	// Allocate save buffer for game screen
 	displayMode16Bit();
 
-	memset(BG_GFX, 0, 512 * 256 * 2);
 	scaledMode = true;
 	scX = 0;
 	scY = 0;
@@ -709,9 +640,6 @@ void initHardware() {
 
 	initSprites();
 
-	// If the software scaler's back buffer has not been allocated, do it now
-	scalerBackBuffer = (u8 *) malloc(320 * 256);
-
 	// This is a bodge to get around the fact that the cursor is turned on before it's image is set
 	// during startup in Sam & Max.  This bodge moves the cursor offscreen so it is not seen.
 	sprites[1].attribute[1] = ATTR1_SIZE_64 | 192;
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index 2fca93500d..b8d7342052 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -34,14 +34,8 @@ namespace DS {
 void 	displayMode8Bit();											// Switch to 8-bit mode5
 void 	displayMode16Bit();										// Switch to 16-bit mode5
 
-// Flip double buffer
-void 	displayMode16BitFlipBuffer();
-
 // Get address of current back buffer
 u16 *	get16BitBackBuffer();
-u16 *	get8BitBackBuffer();
-s32 	get8BitBackBufferStride();
-u16*	getScalerBuffer();
 
 void 	setTalkPos(int x, int y);
 void 	setTopScreenTarget(int x, int y);
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index f258cbf06e..0e07a5689e 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -40,6 +40,7 @@
 
 #include "osystem_ds.h"
 #include "dsmain.h"
+#include "blitters.h"
 #include "common/config-manager.h"
 #include "common/str.h"
 #include "graphics/surface.h"
@@ -56,7 +57,7 @@
 OSystem_DS *OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
-	: _eventSource(NULL), _mixer(NULL), _frameBufferExists(false),
+	: _eventSource(NULL), _mixer(NULL),
 	_disableCursorPalette(true), _graphicsEnable(true), _gammaValue(0)
 {
 	_instance = this;
@@ -111,6 +112,8 @@ bool OSystem_DS::getFeatureState(Feature f) {
 }
 
 void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
+	_framebuffer.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
 	// For Lost in Time, the title screen is displayed in 640x400.
 	// In order to support this game, the screen mode is set, but
 	// all draw calls are ignored until the game switches to 320x200.
@@ -123,11 +126,11 @@ void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *
 }
 
 int16 OSystem_DS::getHeight() {
-	return 200;
+	return _framebuffer.h;
 }
 
 int16 OSystem_DS::getWidth() {
-	return 320;
+	return _framebuffer.w;
 }
 
 void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
@@ -187,157 +190,62 @@ void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) const
 	}
 }
 
-
-#define MISALIGNED16(ptr) (((u32) (ptr) & 1) != 0)
-
 void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
-	if (!_graphicsEnable) return;
-	if (w <= 1) return;
-	if (h < 0) return;
-	if (!DS::getIsDisplayMode8Bit()) return;
-
-	u16 *bg;
-	s32 stride;
-#ifdef DISABLE_TEXT_CONSOLE
-	u16 *bgSub = (u16 *)BG_GFX_SUB;
-#endif
-
-	// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
-	// to save a few pennies/euro cents on the hardware.
-
-	if (_frameBufferExists) {
-		bg = (u16 *)_framebuffer.getPixels();
-		stride = _framebuffer.pitch;
-	} else {
-		bg = (u16 *)DS::get8BitBackBuffer();
-		stride = DS::get8BitBackBufferStride();
-	}
-
-
-	if (((pitch & 1) != 0) || ((w & 1) != 0) || (((int) (buf) & 1) != 0)) {
-
-		// Something is misaligned, so we have to use the slow but sure method
-
-		int by = 0;
-
-		for (int dy = y; dy < y + h; dy++) {
-			u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
-#ifdef DISABLE_TEXT_CONSOLE
-			u8 *destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
-#endif
-			const u8 *src = (const u8 *) buf + (pitch * by);
-
-			u32 dx;
-
-			u32 pixelsLeft = w;
-
-			if (MISALIGNED16(dest)) {
-				// Read modify write
-
-				dest--;
-				u16 mix = *((u16 *) dest);
-
-				mix = (mix & 0x00FF) | (*src++ << 8);
-
-				*dest = mix;
-#ifdef DISABLE_TEXT_CONSOLE
-				*destSub = mix;
-#endif
-
-				dest += 2;
-#ifdef DISABLE_TEXT_CONSOLE
-				destSub += 2;
-#endif
-
-				pixelsLeft--;
-			}
-
-			// We can now assume dest is aligned
-			u16 *dest16 = (u16 *) dest;
-#ifdef DISABLE_TEXT_CONSOLE
-			u16 *destSub16 = (u16 *) destSub;
-#endif
-
-			for (dx = 0; dx < pixelsLeft; dx+=2) {
-				u16 mix;
-
-				mix = *src + (*(src + 1) << 8);
-				*dest16++ = mix;
-#ifdef DISABLE_TEXT_CONSOLE
-				*destSub16++ = mix;
-#endif
-				src += 2;
-			}
-
-			pixelsLeft -= dx;
-
-			// At the end we may have one pixel left over
-
-			if (pixelsLeft != 0) {
-				u16 mix = *dest16;
-
-				mix = (mix & 0x00FF) | ((*src++) << 8);
+	_framebuffer.copyRectToSurface(buf, pitch, x, y, w, h);
+}
 
-				*dest16 = mix;
-#ifdef DISABLE_TEXT_CONSOLE
-				*destSub16 = mix;
-#endif
+void OSystem_DS::updateScreen() {
+	if (!DS::getIsDisplayMode8Bit()) {
+		u16 *back = DS::get16BitBackBuffer();
+
+		if (DS::isCpuScalerEnabled()) {
+			Rescale_320x256x1555_To_256x256x1555(BG_GFX, back, 512, 512);
+		} else {
+			for (int r = 0; r < 512 * 256; r++) {
+				*(BG_GFX + r) = *(back + r);
 			}
-
-			by++;
-
 		}
-
+	} else if (!_graphicsEnable) {
+		return;
+	} else if (DS::isCpuScalerEnabled()) {
+		u16 *base = BG_GFX + 0x10000;
+		Rescale_320x256xPAL8_To_256x256x1555(
+			base,
+			(const u8 *)_framebuffer.getPixels(),
+			256,
+			_framebuffer.pitch,
+			BG_PALETTE,
+			_framebuffer.h );
 	} else {
+		// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
+		// to save a few pennies/euro cents on the hardware.
 
-		// Stuff is aligned to 16-bit boundaries, so it's safe to do DMA.
+		u16 *bg = BG_GFX + 0x10000;
+		s32 stride = 512;
 
-		u16 *src = (u16 *) buf;
+		u16 *src = (u16 *)_framebuffer.getPixels();
 
-		for (int dy = y; dy < y + h; dy++) {
-			u16 *dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
-#ifdef DISABLE_TEXT_CONSOLE
-			u16 *dest2 = bgSub + (dy << 8) + (x >> 1);
-#endif
+		for (int dy = 0; dy < _framebuffer.h; dy++) {
+			DC_FlushRange(src, _framebuffer.w << 1);
 
-			DC_FlushRange(src, w << 1);
-			DC_FlushRange(dest1, w << 1);
-#ifdef DISABLE_TEXT_CONSOLE
-			DC_FlushRange(dest2, w << 1);
-#endif
-
-			dmaCopyHalfWords(3, src, dest1, w);
+			u16 *dest1 = bg + (dy * (stride >> 1));
+			DC_FlushRange(dest1, _framebuffer.w << 1);
 
 #ifdef DISABLE_TEXT_CONSOLE
-			if ((!_frameBufferExists) || (buf == _framebuffer.getPixels())) {
-				dmaCopyHalfWords(2, src, dest2, w);
-			}
+			u16 *dest2 = (u16 *)BG_GFX_SUB + (dy << 8);
+			DC_FlushRange(dest2, _framebuffer.w << 1);
+
+			dmaCopyHalfWords(2, src, dest2, _framebuffer.w);
 #endif
+			dmaCopyHalfWords(3, src, dest1, _framebuffer.w);
 
 			while (dmaBusy(2) || dmaBusy(3));
 
-			src += pitch >> 1;
+			src += _framebuffer.pitch >> 1;
 		}
 	}
 }
 
-void OSystem_DS::updateScreen() {
-	if ((_frameBufferExists) && (DS::getIsDisplayMode8Bit())) {
-		_frameBufferExists = false;
-
-		// Copy temp framebuffer back to screen
-		copyRectToScreen((byte *)_framebuffer.getPixels(), _framebuffer.pitch, 0, 0, _framebuffer.w, _framebuffer.h);
-	}
-
-	DS::displayMode16BitFlipBuffer();
-
-	// FIXME: Evil game specific hack.
-	// Force back buffer usage for Nippon Safes, as it doesn't double buffer it's output
-	// if (DS::getControlType() == DS::CONT_NIPPON) {
-	//	lockScreen();
-	// }
-}
-
 void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
 	DS::setShakePos(shakeXOffset, shakeYOffset);
 }
@@ -470,56 +378,7 @@ void OSystem_DS::deleteMutex(MutexRef mutex) {
 void OSystem_DS::quit() {
 }
 
-Graphics::Surface *OSystem_DS::createTempFrameBuffer() {
-
-	// Ensure we copy using 16 bit quantities due to limitation of VRAM addressing
-
-	// If the scaler is enabled, we can just return the 8 bit back buffer,
-	// since it's in system memory anyway.  Otherwise, we need to copy the back
-	// buffer into the memory normally used by the scaler buffer and then
-	// return it.
-	// We also must ensure that once the frame buffer is created, future calls
-	// to copyRectToScreen() copy to this buffer.
-
-	if (DS::isCpuScalerEnabled()) {
-
-		_framebuffer.init(DS::getGameWidth(), DS::getGameHeight(), DS::getGameWidth(),
-		                  DS::getScalerBuffer(), Graphics::PixelFormat::createFormatCLUT8());
-
-	} else {
-
-		s32 height = DS::getGameHeight();
-		s32 width = DS::getGameWidth();
-		s32 stride = DS::get8BitBackBufferStride();
-
-		u16 *src = DS::get8BitBackBuffer();
-		u16 *dest = DS::getScalerBuffer();
-
-		for (int y = 0; y < height; y++) {
-
-			u16 *destLine = dest + (y * (width / 2));
-			u16 *srcLine = src + (y * (stride / 2));
-
-			DC_FlushRange(srcLine, width);
-
-			dmaCopyHalfWords(3, srcLine, destLine, width);
-		}
-
-		_framebuffer.init(width, height, width, dest, Graphics::PixelFormat::createFormatCLUT8());
-
-	}
-
-	_frameBufferExists = true;
-
-	return &_framebuffer;
-}
-
-
 Graphics::Surface *OSystem_DS::lockScreen() {
-	if (!_frameBufferExists) {
-		createTempFrameBuffer();
-	}
-
 	return &_framebuffer;
 }
 
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index dbdcb52f99..984c099551 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -39,7 +39,6 @@ class OSystem_DS : public BaseBackend, public PaletteManager {
 protected:
 	Audio::MixerImpl *_mixer;
 	Graphics::Surface _framebuffer;
-	bool _frameBufferExists;
 	bool _graphicsEnable;
 
 	static OSystem_DS *_instance;


Commit: 37774cd57829e1d5762fb488fdaad70c4115a60b
    https://github.com/scummvm/scummvm/commit/37774cd57829e1d5762fb488fdaad70c4115a60b
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Allow the game screen and the overlay to be shown at the same time

Changed paths:
    backends/events/ds/ds-events.cpp
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsmain.h
    backends/platform/ds/arm9/source/dsoptions.cpp
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/osystem_ds.h


diff --git a/backends/events/ds/ds-events.cpp b/backends/events/ds/ds-events.cpp
index 807a65884e..f7652dc215 100644
--- a/backends/events/ds/ds-events.cpp
+++ b/backends/events/ds/ds-events.cpp
@@ -22,8 +22,8 @@
 
 #include <nds.h>
 
-#include "dsmain.h"
 #include "backends/events/ds/ds-events.h"
+#include "osystem_ds.h"
 
 bool DSEventSource::pollEvent(Common::Event &event) {
 	if (_eventQueue.empty()) {
@@ -69,7 +69,7 @@ void DSEventSource::addEventsToQueue() {
 	if (held & KEY_TOUCH) {
 		touchPosition touchPos;
 		touchRead(&touchPos);
-		event.mouse = DS::transformPoint(touchPos.px, touchPos.py);
+		event.mouse = dynamic_cast<OSystem_DS *>(g_system)->transformPoint(touchPos.px, touchPos.py);
 
 		if (keysPressed & KEY_TOUCH) {
 			event.type = Common::EVENT_LBUTTONDOWN;
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index eed96bc7c0..880ca22abc 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -117,10 +117,6 @@ static int subScreenWidth = SCUMM_GAME_WIDTH;
 static int subScreenHeight = SCUMM_GAME_HEIGHT;
 static int subScreenScale = 256;
 
-
-// Saved buffers
-static bool displayModeIs8Bit = false;
-
 static bool gameScreenSwap = false;
 bool isCpuScalerEnabled();
 
@@ -154,7 +150,7 @@ void setIcon(int num, int x, int y, int imageNum, int flags, bool enable);
 void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable);
 
 bool isCpuScalerEnabled() {
-	return cpuScalerEnable || !displayModeIs8Bit;
+	return cpuScalerEnable;
 }
 
 
@@ -231,12 +227,6 @@ void setUnscaledMode(bool enable) {
 }
 
 void displayMode8Bit() {
-	setOptions();
-
-	displayModeIs8Bit = true;
-
-	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
 	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
 
 	if (isCpuScalerEnabled()) {
@@ -257,9 +247,6 @@ void displayMode8Bit() {
 	}
 
 #ifdef DISABLE_TEXT_CONSOLE
-	videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
-	vramSetBankD(VRAM_D_SUB_SPRITE);
 	REG_BG3CNT_SUB = BG_BMP8_512x256;
 
 	REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
@@ -314,42 +301,11 @@ void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX,
 	}
 }
 
-
-
-
-void displayMode16Bit() {
-	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-
-	vramSetBankA(VRAM_A_MAIN_BG);
-	vramSetBankB(VRAM_B_MAIN_BG);
-	vramSetBankC(VRAM_C_MAIN_BG);
-	vramSetBankD(VRAM_D_MAIN_BG);
-
-	REG_BG3CNT = BG_BMP16_512x256;
-
-	memset(BG_GFX, 0, 512 * 256 * 2);
-
-	lcdMainOnBottom();
-
-	displayModeIs8Bit = false;
-
-	REG_BG3PA = isCpuScalerEnabled() ? 256 : (int) (1.25f * 256);
-	REG_BG3PB = 0;
-	REG_BG3PC = 0;
-	REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
-}
-
-
 void setShakePos(int shakeXOffset, int shakeYOffset) {
 	s_shakeXOffset = shakeXOffset;
 	s_shakeYOffset = shakeYOffset;
 }
 
-
-u16 *get16BitBackBuffer() {
-	return BG_GFX + 0x20000;
-}
-
 void doTimerCallback() {
 	if (callback) {
 		if (callbackTimer <= 0) {
@@ -359,10 +315,6 @@ void doTimerCallback() {
 	}
 }
 
-bool getIsDisplayMode8Bit() {
-	return displayModeIs8Bit;
-}
-
 void setIcon(int num, int x, int y, int imageNum, int flags, bool enable) {
 	sprites[num].attribute[0] = ATTR0_BMP | (enable ? (y & 0xFF) : 192) | (!enable ? ATTR0_DISABLED : 0);
 	sprites[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
@@ -390,9 +342,15 @@ void updateMouse() {
 	}
 }
 
-void warpMouse(int penX, int penY) {
-	storedMouseX = ((penX - touchX) << 8) / touchScX;
-	storedMouseY = ((penY - touchY) << 8) / touchScY;
+void warpMouse(int penX, int penY, bool isOverlayShown) {
+	if (!isOverlayShown) {
+		storedMouseX = ((penX - touchX) << 8) / touchScX;
+		storedMouseY = ((penY - touchY) << 8) / touchScY;
+	} else {
+		storedMouseX = penX;
+		storedMouseY = penY;
+	}
+
 	updateMouse();
 }
 
@@ -451,12 +409,14 @@ void setZoomedScreenScale(int x, int y) {
 #endif
 }
 
-Common::Point transformPoint(uint16 x, uint16 y) {
-	x = ((x * touchScX) >> 8) + touchX;
-	x = CLIP<uint16>(x, 0, gameWidth  - 1);
+Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown) {
+	if (!isOverlayShown) {
+		x = ((x * touchScX) >> 8) + touchX;
+		x = CLIP<uint16>(x, 0, gameWidth  - 1);
 
-	y = ((y * touchScY) >> 8) + touchY;
-	y = CLIP<uint16>(y, 0, gameHeight - 1);
+		y = ((y * touchScY) >> 8) + touchY;
+		y = CLIP<uint16>(y, 0, gameHeight - 1);
+	}
 
 	return Common::Point(x, y);
 }
@@ -501,55 +461,41 @@ void VBlankHandler(void) {
 	subScX += (subScTargetX - subScX) >> 2;
 	subScY += (subScTargetY - subScY) >> 2;
 
-	if (displayModeIs8Bit) {
-
-		if (!scaledMode) {
-
-			if (scX + 256 > gameWidth - 1) {
-				scX = gameWidth - 1 - 256;
-			}
-
-			if (scX < 0) {
-				scX = 0;
-			}
-
-			if (scY + 192 > gameHeight - 1) {
-				scY = gameHeight - 1 - 192;
-			}
-
-			if (scY < 0) {
-				scY = 0;
-			}
-
-			setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
-			setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
-
-
-			setMainScreenScroll((scX << 8) + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
-			setMainScreenScale(256, 256);		// 1:1 scale
+	if (!scaledMode) {
+		if (scX + 256 > gameWidth - 1) {
+			scX = gameWidth - 1 - 256;
+		}
 
-		} else {
+		if (scX < 0) {
+			scX = 0;
+		}
 
-			if (scY > gameHeight - 192 - 1) {
-				scY = gameHeight - 192 - 1;
-			}
+		if (scY + 192 > gameHeight - 1) {
+			scY = gameHeight - 1 - 192;
+		}
 
-			if (scY < 0) {
-				scY = 0;
-			}
+		if (scY < 0) {
+			scY = 0;
+		}
 
-			setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
-			setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
+		setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
+		setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
 
-			setMainScreenScroll(64 + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
-			setMainScreenScale(320, 256);		// 1:1 scale
+		setMainScreenScroll((scX << 8) + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
+		setMainScreenScale(256, 256);		// 1:1 scale
+	} else {
+		if (scY > gameHeight - 192 - 1) {
+			scY = gameHeight - 192 - 1;
+		}
 
+		if (scY < 0) {
+			scY = 0;
 		}
-	} else {
-		setZoomedScreenScroll(0, 0, true);
-		setZoomedScreenScale(320, 256);
 
-		setMainScreenScroll(0, 0);
+		setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
+		setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
+
+		setMainScreenScroll(64 + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
 		setMainScreenScale(320, 256);		// 1:1 scale
 	}
 
@@ -602,8 +548,15 @@ void initHardware() {
 		BG_PALETTE[r] = 0;
 	}
 
-	// Allocate save buffer for game screen
-	displayMode16Bit();
+	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
+	vramSetBankE(VRAM_E_MAIN_SPRITE);
+
+	REG_BG2CNT = BG_BMP16_256x256;
+	REG_BG2PA = 256;
+	REG_BG2PB = 0;
+	REG_BG2PC = 0;
+	REG_BG2PD = 256;
 
 	scaledMode = true;
 	scX = 0;
@@ -627,15 +580,14 @@ void initHardware() {
 	timerStart(0, ClockDivider_1, (u16)TIMER_FREQ(1000), timerTickHandler);
 	REG_IME = 1;
 
-	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
-	vramSetBankD(VRAM_D_SUB_SPRITE);
-	vramSetBankE(VRAM_E_MAIN_SPRITE);
-
 #ifndef DISABLE_TEXT_CONSOLE
+	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
 	vramSetBankH(VRAM_H_SUB_BG);
 	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 15, 0, false, true);
-
-	printf("Testing the console\n");
+#else
+	videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
+	vramSetBankI(VRAM_I_SUB_SPRITE);
 #endif
 
 	initSprites();
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index b8d7342052..7dd5f276da 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -50,13 +50,13 @@ void 	doTimerCallback();												// Call callback function if required
 
 // Events
 void 	VBlankHandler();
-Common::Point transformPoint(uint16 x, uint16 y);
+Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown);
 
 // Sam and Max Stuff
 void 	setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX, int hotspotY);
 void	setShowCursor(bool enable);
 void	setMouseCursorVisible(bool visible);
-void	warpMouse(int penX, int penY);
+void	warpMouse(int penX, int penY, bool isOverlayShown);
 void	updateMouse();
 
 // Shake
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp
index 8703330093..05541f9eb0 100644
--- a/backends/platform/ds/arm9/source/dsoptions.cpp
+++ b/backends/platform/ds/arm9/source/dsoptions.cpp
@@ -238,17 +238,9 @@ void DSOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint
 
 
 void showOptionsDialog() {
-
-
-	DS::displayMode16Bit();
-
-
 	DSOptionsDialog *d = new DSOptionsDialog();
 	d->runModal();
 	delete d;
-
-	DS::displayMode8Bit();
-
 }
 
 void setOptions() {
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 0e07a5689e..6f86c6cdb9 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -57,7 +57,7 @@
 OSystem_DS *OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
-	: _eventSource(NULL), _mixer(NULL),
+	: _eventSource(NULL), _mixer(NULL), _isOverlayShown(true),
 	_disableCursorPalette(true), _graphicsEnable(true), _gammaValue(0)
 {
 	_instance = this;
@@ -91,6 +91,8 @@ void OSystem_DS::initBackend() {
 	_mixer = new Audio::MixerImpl(11025);
 	_mixer->setReady(true);
 
+	_overlay.create(256, 192, Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15));
+
 	BaseBackend::initBackend();
 }
 
@@ -146,7 +148,7 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 		{
 			u16 paletteValue = red | (green << 5) | (blue << 10);
 
-			if (DS::getIsDisplayMode8Bit()) {
+			if (!_isOverlayShown) {
 				int col = applyGamma(paletteValue);
 				BG_PALETTE[r] = col;
 #ifdef DISABLE_TEXT_CONSOLE
@@ -195,16 +197,9 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 }
 
 void OSystem_DS::updateScreen() {
-	if (!DS::getIsDisplayMode8Bit()) {
-		u16 *back = DS::get16BitBackBuffer();
-
-		if (DS::isCpuScalerEnabled()) {
-			Rescale_320x256x1555_To_256x256x1555(BG_GFX, back, 512, 512);
-		} else {
-			for (int r = 0; r < 512 * 256; r++) {
-				*(BG_GFX + r) = *(back + r);
-			}
-		}
+	if (_isOverlayShown) {
+		u16 *back = (u16 *)_overlay.getPixels();
+		dmaCopyHalfWords(3, back, BG_GFX, 256 * 192 * 2);
 	} else if (!_graphicsEnable) {
 		return;
 	} else if (DS::isCpuScalerEnabled()) {
@@ -235,9 +230,9 @@ void OSystem_DS::updateScreen() {
 			u16 *dest2 = (u16 *)BG_GFX_SUB + (dy << 8);
 			DC_FlushRange(dest2, _framebuffer.w << 1);
 
-			dmaCopyHalfWords(2, src, dest2, _framebuffer.w);
+			dmaCopyHalfWordsAsynch(2, src, dest2, _framebuffer.w);
 #endif
-			dmaCopyHalfWords(3, src, dest1, _framebuffer.w);
+			dmaCopyHalfWordsAsynch(3, src, dest1, _framebuffer.w);
 
 			while (dmaBusy(2) || dmaBusy(3));
 
@@ -251,58 +246,54 @@ void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
 }
 
 void OSystem_DS::showOverlay() {
-	DS::displayMode16Bit();
+	dmaFillHalfWords(0, BG_GFX, 256 * 192 * 2);
+	videoBgEnable(2);
+	lcdMainOnBottom();
+	_isOverlayShown = true;
 }
 
 void OSystem_DS::hideOverlay() {
+	videoBgDisable(2);
 	DS::displayMode8Bit();
+	_isOverlayShown = false;
 }
 
 bool OSystem_DS::isOverlayVisible() const {
-	return !DS::getIsDisplayMode8Bit();
+	return _isOverlayShown;
 }
 
 void OSystem_DS::clearOverlay() {
-	memset((u16 *) DS::get16BitBackBuffer(), 0, 512 * 256 * 2);
+	memset(_overlay.getPixels(), 0, _overlay.pitch * _overlay.h);
 }
 
 void OSystem_DS::grabOverlay(void *buf, int pitch) {
-	u16 *start = DS::get16BitBackBuffer();
+	byte *dst = (byte *)buf;
 
-	for (int y = 0; y < 200; y++) {
-		u16 *src = start + (y * 320);
-		u16 *dest = (u16 *)((u8 *)buf + (y * pitch));
-
-		for (int x = 0; x < 320; x++) {
-			*dest++ =  *src++;
-		}
+	for (int y = 0; y < _overlay.h; ++y) {
+		memcpy(dst, _overlay.getBasePtr(0, y), _overlay.w * _overlay.format.bytesPerPixel);
+		dst += pitch;
 	}
-
 }
 
 void OSystem_DS::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
-	u16 *bg = (u16 *) DS::get16BitBackBuffer();
-	const u8 *source = (const u8 *)buf;
-
-	for (int dy = y; dy < y + h; dy++) {
-		const u16 *src = (const u16 *)source;
-
-		for (int dx = x; dx < x + w; dx++) {
-			*(bg + (dy * 512) + dx) = *src;
-			src++;
-		}
-		source += pitch;
-	}
+	_overlay.copyRectToSurface(buf, pitch, x, y, w, h);
 }
 
 int16 OSystem_DS::getOverlayHeight() {
-	return getHeight();
+	return _overlay.h;
 }
 
 int16 OSystem_DS::getOverlayWidth() {
-	return getWidth();
+	return _overlay.w;
 }
 
+Graphics::PixelFormat OSystem_DS::getOverlayFormat() const {
+	return _overlay.format;
+}
+
+Common::Point OSystem_DS::transformPoint(uint16 x, uint16 y) {
+	return DS::transformPoint(x, y, _isOverlayShown);
+}
 
 bool OSystem_DS::showMouse(bool visible) {
 	DS::setShowCursor(visible);
@@ -310,7 +301,7 @@ bool OSystem_DS::showMouse(bool visible) {
 }
 
 void OSystem_DS::warpMouse(int x, int y) {
-	DS::warpMouse(x, y);
+	DS::warpMouse(x, y, _isOverlayShown);
 }
 
 void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
@@ -394,6 +385,18 @@ void OSystem_DS::clearFocusRectangle() {
 
 }
 
+void OSystem_DS::engineInit() {
+#ifdef DISABLE_TEXT_CONSOLE
+	videoBgEnableSub(3);
+#endif
+}
+
+void OSystem_DS::engineDone() {
+#ifdef DISABLE_TEXT_CONSOLE
+	videoBgDisableSub(3);
+#endif
+}
+
 void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
 #ifndef DISABLE_TEXT_CONSOLE
 	printf("%s", message);
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index 984c099551..2fd0ccd974 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -38,8 +38,8 @@
 class OSystem_DS : public BaseBackend, public PaletteManager {
 protected:
 	Audio::MixerImpl *_mixer;
-	Graphics::Surface _framebuffer;
-	bool _graphicsEnable;
+	Graphics::Surface _framebuffer, _overlay;
+	bool _graphicsEnable, _isOverlayShown;
 
 	static OSystem_DS *_instance;
 
@@ -95,8 +95,9 @@ public:
 	virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
 	virtual int16 getOverlayHeight();
 	virtual int16 getOverlayWidth();
-	virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15); }
+	virtual Graphics::PixelFormat getOverlayFormat() const;
 
+	Common::Point transformPoint(uint16 x, uint16 y);
 	virtual bool showMouse(bool visible);
 
 	virtual void warpMouse(int x, int y);
@@ -117,9 +118,11 @@ public:
 	virtual void quit();
 
 	virtual void setFocusRectangle(const Common::Rect& rect);
-
 	virtual void clearFocusRectangle();
 
+	virtual void engineInit();
+	virtual void engineDone();
+
 	virtual void initBackend();
 
 	virtual Graphics::Surface *lockScreen();


Commit: 266e21de10dded8e6958d5937d1d70635209bb09
    https://github.com/scummvm/scummvm/commit/266e21de10dded8e6958d5937d1d70635209bb09
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Clean up the sprite code

Changed paths:
  R backends/platform/ds/arm9/data/icons.raw
  R backends/platform/ds/arm9/data/icons.tga
    backends/platform/ds/arm9/source/dsmain.cpp
    backends/platform/ds/arm9/source/dsmain.h
    backends/platform/ds/arm9/source/dsoptions.cpp
    backends/platform/ds/arm9/source/dsoptions.h
    backends/platform/ds/arm9/source/osystem_ds.cpp
    backends/platform/ds/arm9/source/osystem_ds.h


diff --git a/backends/platform/ds/arm9/data/icons.raw b/backends/platform/ds/arm9/data/icons.raw
deleted file mode 100644
index c8fbfd6e9a..0000000000
Binary files a/backends/platform/ds/arm9/data/icons.raw and /dev/null differ
diff --git a/backends/platform/ds/arm9/data/icons.tga b/backends/platform/ds/arm9/data/icons.tga
deleted file mode 100644
index f3b922d817..0000000000
Binary files a/backends/platform/ds/arm9/data/icons.tga and /dev/null differ
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index 880ca22abc..dd3254e85f 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -120,23 +120,12 @@ static int subScreenScale = 256;
 static bool gameScreenSwap = false;
 bool isCpuScalerEnabled();
 
-static int storedMouseX = 0;
-static int storedMouseY = 0;
-
-// Sprites
-static SpriteEntry sprites[128];
-static SpriteEntry spritesMain[128];
-
 // Shake
 static int s_shakeXOffset = 0;
 static int s_shakeYOffset = 0;
 
 // Touch
 static int touchScX, touchScY, touchX, touchY;
-static int mouseHotspotX, mouseHotspotY;
-static bool cursorEnable = false;
-static bool mouseCursorVisible = true;
-static bool touchPadStyle = false;
 
 // 8-bit surface size
 static int gameWidth = 320;
@@ -146,9 +135,6 @@ static int gameHeight = 200;
 static bool twoHundredPercentFixedScale = false;
 static bool cpuScalerEnable = false;
 
-void setIcon(int num, int x, int y, int imageNum, int flags, bool enable);
-void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable);
-
 bool isCpuScalerEnabled() {
 	return cpuScalerEnable;
 }
@@ -158,10 +144,6 @@ void setCpuScalerEnable(bool enable) {
 	cpuScalerEnable = enable;
 }
 
-void setTrackPadStyleEnable(bool enable) {
-	touchPadStyle = enable;
-}
-
 void setGameScreenSwap(bool enable) {
 	gameScreenSwap = enable;
 }
@@ -175,18 +157,6 @@ void setTopScreenZoom(int percentage) {
 	subScreenScale = (256 * 256) / scale;
 }
 
-void updateOAM() {
-	DC_FlushAll();
-
-	if (gameScreenSwap) {
-		dmaCopy(sprites, OAM, 128 * sizeof(SpriteEntry));
-		dmaCopy(spritesMain, OAM_SUB, 128 * sizeof(SpriteEntry));
-	} else {
-		dmaCopy(sprites, OAM_SUB, 128 * sizeof(SpriteEntry));
-		dmaCopy(spritesMain, OAM, 128 * sizeof(SpriteEntry));
-	}
-}
-
 void setGameSize(int width, int height) {
 	gameWidth = width;
 	gameHeight = height;
@@ -200,24 +170,6 @@ int getGameHeight() {
 	return gameHeight;
 }
 
-void initSprites() {
-	for (int i = 0; i < 128; i++) {
-		sprites[i].attribute[0] = ATTR0_DISABLED;
-		sprites[i].attribute[1] = 0;
-		sprites[i].attribute[2] = 0;
-		sprites[i].filler = 0;
-	}
-
-	for (int i = 0; i < 128; i++) {
-		spritesMain[i].attribute[0] = ATTR0_DISABLED;
-		spritesMain[i].attribute[1] = 0;
-		spritesMain[i].attribute[2] = 0;
-		spritesMain[i].filler = 0;
-	}
-
-	updateOAM();
-}
-
 void set200PercentFixedScale(bool on) {
 	twoHundredPercentFixedScale = on;
 }
@@ -262,45 +214,6 @@ void displayMode8Bit() {
 	}
 }
 
-void setShowCursor(bool enable) {
-	cursorEnable = enable;
-	updateMouse();
-}
-
-void setMouseCursorVisible(bool enable) {
-	mouseCursorVisible = enable;
-	updateMouse();
-}
-
-void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX, int hotspotY) {
-
-	int off;
-
-	mouseHotspotX = hotspotX;
-	mouseHotspotY = hotspotY;
-
-	off = 128*64;
-
-
-	memset(SPRITE_GFX + off, 0, 32 * 32 * 2);
-	memset(SPRITE_GFX_SUB + off, 0, 32 * 32 * 2);
-
-
-	for (uint y=0; y<h; y++) {
-		for (uint x=0; x<w; x++) {
-			int color = icon[y*w+x];
-
-			if (color == keycolor) {
-				SPRITE_GFX[off+(y)*32+x] = 0x0000; // black background
-				SPRITE_GFX_SUB[off+(y)*32+x] = 0x0000; // black background
-			} else {
-				SPRITE_GFX[off+(y)*32+x] = OSystem_DS::instance()->getDSCursorPaletteEntry(color) | 0x8000;
-				SPRITE_GFX_SUB[off+(y)*32+x] = OSystem_DS::instance()->getDSCursorPaletteEntry(color) | 0x8000;
-			}
-		}
-	}
-}
-
 void setShakePos(int shakeXOffset, int shakeYOffset) {
 	s_shakeXOffset = shakeXOffset;
 	s_shakeYOffset = shakeYOffset;
@@ -315,34 +228,8 @@ void doTimerCallback() {
 	}
 }
 
-void setIcon(int num, int x, int y, int imageNum, int flags, bool enable) {
-	sprites[num].attribute[0] = ATTR0_BMP | (enable ? (y & 0xFF) : 192) | (!enable ? ATTR0_DISABLED : 0);
-	sprites[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
-	sprites[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
-}
-
-void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable) {
-	spritesMain[num].attribute[0] = ATTR0_BMP | (y & 0xFF) | (!enable ? ATTR0_DISABLED : 0);
-	spritesMain[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
-	spritesMain[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
-}
-
-void updateMouse() {
-	if ((cursorEnable) && (mouseCursorVisible)) {
-		if (gameScreenSwap && touchPadStyle) {
-			setIcon(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
-			setIconMain(3, 0, 0, 0, 0, false);
-		} else {
-			setIconMain(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
-			setIcon(3, 0, 0, 0, 0, false);
-		}
-	} else {
-		setIconMain(3, 0, 0, 0, 0, false);
-		setIcon(3, 0, 0, 0, 0, false);
-	}
-}
-
-void warpMouse(int penX, int penY, bool isOverlayShown) {
+Common::Point warpMouse(int penX, int penY, bool isOverlayShown) {
+	int storedMouseX, storedMouseY;
 	if (!isOverlayShown) {
 		storedMouseX = ((penX - touchX) << 8) / touchScX;
 		storedMouseY = ((penY - touchY) << 8) / touchScY;
@@ -351,14 +238,14 @@ void warpMouse(int penX, int penY, bool isOverlayShown) {
 		storedMouseY = penY;
 	}
 
-	updateMouse();
+	return Common::Point(storedMouseX, storedMouseY);
 }
 
 void setMainScreenScroll(int x, int y) {
 		REG_BG3X = x + (((frameCount & 1) == 0)? 64: 0);
 		REG_BG3Y = y;
 
-		if ((!gameScreenSwap) || (touchPadStyle)) {
+		if (!gameScreenSwap) {
 			touchX = x >> 8;
 			touchY = y >> 8;
 		}
@@ -377,14 +264,14 @@ void setMainScreenScale(int x, int y) {
 			REG_BG3PD = y;
 		}
 
-		if ((!gameScreenSwap) || (touchPadStyle)) {
+		if (!gameScreenSwap) {
 			touchScX = x;
 			touchScY = y;
 		}
 }
 
 void setZoomedScreenScroll(int x, int y, bool shake) {
-		if ((gameScreenSwap) && (!touchPadStyle)) {
+		if (gameScreenSwap) {
 			touchX = x >> 8;
 			touchY = y >> 8;
 		}
@@ -396,7 +283,7 @@ void setZoomedScreenScroll(int x, int y, bool shake) {
 }
 
 void setZoomedScreenScale(int x, int y) {
-		if ((gameScreenSwap) && (!touchPadStyle)) {
+		if (gameScreenSwap) {
 			touchScX = x;
 			touchScY = y;
 		}
@@ -498,8 +385,6 @@ void VBlankHandler(void) {
 		setMainScreenScroll(64 + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
 		setMainScreenScale(320, 256);		// 1:1 scale
 	}
-
-	updateOAM();
 }
 
 int getMillis(bool skipRecord) {
@@ -548,7 +433,7 @@ void initHardware() {
 		BG_PALETTE[r] = 0;
 	}
 
-	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
 	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
 	vramSetBankE(VRAM_E_MAIN_SPRITE);
 
@@ -581,21 +466,13 @@ void initHardware() {
 	REG_IME = 1;
 
 #ifndef DISABLE_TEXT_CONSOLE
-	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
 	vramSetBankH(VRAM_H_SUB_BG);
 	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 15, 0, false, true);
 #else
-	videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+	videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE);
 	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
-	vramSetBankI(VRAM_I_SUB_SPRITE);
 #endif
-
-	initSprites();
-
-	// This is a bodge to get around the fact that the cursor is turned on before it's image is set
-	// during startup in Sam & Max.  This bodge moves the cursor offscreen so it is not seen.
-	sprites[1].attribute[1] = ATTR1_SIZE_64 | 192;
-
 }
 
 ///////////////////
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index 7dd5f276da..b7c3e49001 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -51,13 +51,7 @@ void 	doTimerCallback();												// Call callback function if required
 // Events
 void 	VBlankHandler();
 Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown);
-
-// Sam and Max Stuff
-void 	setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX, int hotspotY);
-void	setShowCursor(bool enable);
-void	setMouseCursorVisible(bool visible);
-void	warpMouse(int penX, int penY, bool isOverlayShown);
-void	updateMouse();
+Common::Point warpMouse(int penX, int penY, bool isOverlayShown);
 
 // Shake
 void 	setShakePos(int shakeXOffset, int shakeYOffset);
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp
index 05541f9eb0..56f496c4cd 100644
--- a/backends/platform/ds/arm9/source/dsoptions.cpp
+++ b/backends/platform/ds/arm9/source/dsoptions.cpp
@@ -59,8 +59,6 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 
 	_tab->addTab(_("Graphics"), "");
 
-	_showCursorCheckbox = new GUI::CheckboxWidget(_tab, 150, 5, 130, 20, _("Show mouse cursor"), U32String(), 0, 'T');
-
 	new GUI::StaticTextWidget(_tab, 5, 67, 180, 15, _("Initial top screen scale:"), Graphics::kTextAlignLeft);
 
 	_100PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 82, 80, 20, U32String("100%"), U32String("TODO: Add tooltip"), 0x30000001, 'T');
@@ -84,7 +82,6 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 
 	_radioButtonMode = false;
 
-	_showCursorCheckbox->setState(confGetBool("showcursor", true));
 	_unscaledCheckbox->setState(confGetBool("unscaled", false));
 
 
@@ -144,7 +141,6 @@ void DSOptionsDialog::updateConfigManager() {
 #ifdef ALLOW_CPU_SCALER
 	ConfMan.setBool("cpu_scaler", _cpuScaler->getState(), "ds");
 #endif
-	ConfMan.setBool("showcursor", _showCursorCheckbox->getState(), "ds");
 	ConfMan.setInt("gamma", _gammaCorrection->getValue(), "ds");
 
 	int zoomLevel = 150;
@@ -248,8 +244,6 @@ void setOptions() {
 
 	ConfMan.addGameDomain("ds");
 
-	DS::setMouseCursorVisible(confGetBool("showcursor", true));
-
 	DS::setUnscaledMode(confGetBool("unscaled", false));
 
 	if (firstLoad) {
diff --git a/backends/platform/ds/arm9/source/dsoptions.h b/backends/platform/ds/arm9/source/dsoptions.h
index 2afa628166..4be07c93c2 100644
--- a/backends/platform/ds/arm9/source/dsoptions.h
+++ b/backends/platform/ds/arm9/source/dsoptions.h
@@ -56,7 +56,6 @@ protected:
 	GUI::CheckboxWidget *_100PercentCheckbox;
 	GUI::CheckboxWidget *_150PercentCheckbox;
 	GUI::CheckboxWidget *_200PercentCheckbox;
-	GUI::CheckboxWidget *_showCursorCheckbox;
 
 	GUI::CheckboxWidget *_hardScaler;
 	GUI::CheckboxWidget *_cpuScaler;
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 6f86c6cdb9..9f2bfb842c 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -91,6 +91,9 @@ void OSystem_DS::initBackend() {
 	_mixer = new Audio::MixerImpl(11025);
 	_mixer->setReady(true);
 
+	oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
+	_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
+
 	_overlay.create(256, 192, Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15));
 
 	BaseBackend::initBackend();
@@ -103,7 +106,7 @@ bool OSystem_DS::hasFeature(Feature f) {
 void OSystem_DS::setFeatureState(Feature f, bool enable) {
 	if (f == kFeatureCursorPalette) {
 		_disableCursorPalette = !enable;
-		refreshCursor();
+		refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
 	}
 }
 
@@ -181,7 +184,7 @@ void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
 	}
 
 	_disableCursorPalette = false;
-	refreshCursor();
+	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
 }
 
 void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) const {
@@ -197,6 +200,10 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 }
 
 void OSystem_DS::updateScreen() {
+	oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
+	       SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
+	oamUpdate(&oamMain);
+
 	if (_isOverlayShown) {
 		u16 *back = (u16 *)_overlay.getPixels();
 		dmaCopyHalfWords(3, back, BG_GFX, 256 * 192 * 2);
@@ -296,31 +303,43 @@ Common::Point OSystem_DS::transformPoint(uint16 x, uint16 y) {
 }
 
 bool OSystem_DS::showMouse(bool visible) {
-	DS::setShowCursor(visible);
-	return true;
+	const bool last = _cursorVisible;
+	_cursorVisible = visible;
+	return last;
 }
 
 void OSystem_DS::warpMouse(int x, int y) {
-	DS::warpMouse(x, y, _isOverlayShown);
+	_cursorPos = DS::warpMouse(x, y, _isOverlayShown);
 }
 
 void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
-	if ((w > 0) && (w < 64) && (h > 0) && (h < 64)) {
-		memcpy(_cursorImage, buf, w * h);
-		_cursorW = w;
-		_cursorH = h;
-		_cursorHotX = hotspotX;
-		_cursorHotY = hotspotY;
-		_cursorKey = keycolor;
-		// TODO: The old target scales was saved, but never used. Should the
-		// new "do not scale" logic be implemented?
-		//_cursorScale = targetCursorScale;
-		refreshCursor();
-	}
+	if (!buf || w == 0 || h == 0 || (format && *format != Graphics::PixelFormat::createFormatCLUT8()))
+		return;
+
+	if (_cursor.w != w || _cursor.h != h)
+		_cursor.create(w, h, Graphics::PixelFormat::createFormatCLUT8());
+	_cursor.copyRectToSurface(buf, w, 0, 0, w, h);
+	_cursorHotX = hotspotX;
+	_cursorHotY = hotspotY;
+	_cursorKey = keycolor;
+	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
 }
 
-void OSystem_DS::refreshCursor() {
-	DS::setCursorIcon(_cursorImage, _cursorW, _cursorH, _cursorKey, _cursorHotX, _cursorHotY);
+void OSystem_DS::refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette) {
+	uint w = MIN<uint>(src.w, 64);
+	uint h = MIN<uint>(src.h, 64);
+
+	dmaFillHalfWords(0, dst, 64 * 64 * 2);
+
+	for (uint y = 0; y < h; y++) {
+		const uint8 *row = (const uint8 *)src.getBasePtr(0, y);
+		for (uint x = 0; x < w; x++) {
+			uint8 color = *row++;
+
+			if (color != _cursorKey)
+				dst[y * 64 + x] = palette[color] | 0x8000;
+		}
+	}
 }
 
 uint32 OSystem_DS::getMillis(bool skipRecord) {
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index 2fd0ccd974..9e742f9840 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -38,7 +38,7 @@
 class OSystem_DS : public BaseBackend, public PaletteManager {
 protected:
 	Audio::MixerImpl *_mixer;
-	Graphics::Surface _framebuffer, _overlay;
+	Graphics::Surface _framebuffer, _overlay, _cursor;
 	bool _graphicsEnable, _isOverlayShown;
 
 	static OSystem_DS *_instance;
@@ -46,13 +46,12 @@ protected:
 	u16 _palette[256];
 	u16 _cursorPalette[256];
 
-	u8 _cursorImage[64 * 64];
-	uint _cursorW;
-	uint _cursorH;
+	u16 *_cursorSprite;
+	Common::Point _cursorPos;
 	int _cursorHotX;
 	int _cursorHotY;
 	byte _cursorKey;
-	int _cursorScale;
+	bool _cursorVisible;
 
 	DSEventSource *_eventSource;
 
@@ -132,12 +131,9 @@ public:
 
 	static int timerHandler(int t);
 
-	u16 getDSPaletteEntry(u32 entry) const { return _palette[entry]; }
-	u16 getDSCursorPaletteEntry(u32 entry) const { return !_disableCursorPalette? _cursorPalette[entry]: _palette[entry]; }
-
 	virtual void setCursorPalette(const byte *colors, uint start, uint num);
 
-	void refreshCursor();
+	void refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette);
 
 	virtual void logMessage(LogMessageType::Type type, const char *message);
 


Commit: 3c306f33ed8c31c9136a0b1c186470af917b6b5a
    https://github.com/scummvm/scummvm/commit/3c306f33ed8c31c9136a0b1c186470af917b6b5a
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Simplify the directory structure

Changed paths:
  A backends/platform/ds/blitters.h
  A backends/platform/ds/blitters_arm.s
  A backends/platform/ds/dsmain.cpp
  A backends/platform/ds/dsmain.h
  A backends/platform/ds/dsoptions.cpp
  A backends/platform/ds/dsoptions.h
  A backends/platform/ds/osystem_ds.cpp
  A backends/platform/ds/osystem_ds.h
  A backends/platform/ds/portdefs.h
  A backends/platform/ds/readme_ds.txt
  R backends/platform/ds/arm9/dist/readme_ds.txt
  R backends/platform/ds/arm9/source/blitters.h
  R backends/platform/ds/arm9/source/blitters_arm.s
  R backends/platform/ds/arm9/source/dsmain.cpp
  R backends/platform/ds/arm9/source/dsmain.h
  R backends/platform/ds/arm9/source/dsoptions.cpp
  R backends/platform/ds/arm9/source/dsoptions.h
  R backends/platform/ds/arm9/source/osystem_ds.cpp
  R backends/platform/ds/arm9/source/osystem_ds.h
  R backends/platform/ds/arm9/source/portdefs.h
    backends/platform/ds/ds.mk
    backends/platform/ds/module.mk
    configure


diff --git a/backends/platform/ds/arm9/source/blitters.h b/backends/platform/ds/blitters.h
similarity index 100%
rename from backends/platform/ds/arm9/source/blitters.h
rename to backends/platform/ds/blitters.h
diff --git a/backends/platform/ds/arm9/source/blitters_arm.s b/backends/platform/ds/blitters_arm.s
similarity index 100%
rename from backends/platform/ds/arm9/source/blitters_arm.s
rename to backends/platform/ds/blitters_arm.s
diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk
index 0fe97e39ab..9e4e1c6275 100644
--- a/backends/platform/ds/ds.mk
+++ b/backends/platform/ds/ds.mk
@@ -41,9 +41,9 @@ CXXFLAGS += $(OPT_SIZE)
 # TODO: Several of these files probably should not be optimized for speed, but for now
 # we replicate the *precise* list from the old DS makefile, to ensure full compatibility.
 # Eventually, we should tune this list.
-$(ndsdir)/arm9/source/blitters.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-$(ndsdir)/arm9/source/dsmain.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-$(ndsdir)/arm9/source/osystem_ds.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+$(ndsdir)/blitters.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+$(ndsdir)/dsmain.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+$(ndsdir)/osystem_ds.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
 base/main.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
 sound/rate.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
 sound/softsynth/opl/mame.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/dsmain.cpp
similarity index 100%
rename from backends/platform/ds/arm9/source/dsmain.cpp
rename to backends/platform/ds/dsmain.cpp
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/dsmain.h
similarity index 100%
rename from backends/platform/ds/arm9/source/dsmain.h
rename to backends/platform/ds/dsmain.h
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/dsoptions.cpp
similarity index 100%
rename from backends/platform/ds/arm9/source/dsoptions.cpp
rename to backends/platform/ds/dsoptions.cpp
diff --git a/backends/platform/ds/arm9/source/dsoptions.h b/backends/platform/ds/dsoptions.h
similarity index 100%
rename from backends/platform/ds/arm9/source/dsoptions.h
rename to backends/platform/ds/dsoptions.h
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
index d08af9b0ca..891ef685ec 100644
--- a/backends/platform/ds/module.mk
+++ b/backends/platform/ds/module.mk
@@ -1,10 +1,10 @@
 MODULE := backends/platform/ds
 
 MODULE_OBJS := \
-	arm9/source/blitters_arm.o \
-	arm9/source/dsmain.o \
-	arm9/source/osystem_ds.o \
-	arm9/source/dsoptions.o
+	blitters_arm.o \
+	dsmain.o \
+	osystem_ds.o \
+	dsoptions.o
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
similarity index 100%
rename from backends/platform/ds/arm9/source/osystem_ds.cpp
rename to backends/platform/ds/osystem_ds.cpp
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/osystem_ds.h
similarity index 100%
rename from backends/platform/ds/arm9/source/osystem_ds.h
rename to backends/platform/ds/osystem_ds.h
diff --git a/backends/platform/ds/arm9/source/portdefs.h b/backends/platform/ds/portdefs.h
similarity index 100%
rename from backends/platform/ds/arm9/source/portdefs.h
rename to backends/platform/ds/portdefs.h
diff --git a/backends/platform/ds/arm9/dist/readme_ds.txt b/backends/platform/ds/readme_ds.txt
similarity index 100%
rename from backends/platform/ds/arm9/dist/readme_ds.txt
rename to backends/platform/ds/readme_ds.txt
diff --git a/configure b/configure
index bbac28ed05..d1349450b9 100755
--- a/configure
+++ b/configure
@@ -3709,9 +3709,7 @@ case $_backend in
 		_sdl=auto
 		;;
 	ds)
-		append_var INCLUDES '-I$(srcdir)/backends/platform/ds/arm9/source'
-		append_var INCLUDES '-I$(srcdir)/backends/platform/ds/commoninclude'
-		append_var INCLUDES '-Ibackends/platform/ds/arm9/data'
+		append_var INCLUDES '-I$(srcdir)/backends/platform/ds'
 		;;
 	gph)
 		# On the GPH devices we want fancy themes but do not want the load/save thumbnail grid.


Commit: 9ca78455900696549a843b0ad323570dbe6b1567
    https://github.com/scummvm/scummvm/commit/9ca78455900696549a843b0ad323570dbe6b1567
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Replace the options dialog

Changed paths:
  R backends/platform/ds/dsoptions.cpp
  R backends/platform/ds/dsoptions.h
    backends/platform/ds/dsmain.cpp
    backends/platform/ds/dsmain.h
    backends/platform/ds/module.mk
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h
    gui/launcher.cpp
    gui/massadd.cpp


diff --git a/backends/platform/ds/dsmain.cpp b/backends/platform/ds/dsmain.cpp
index dd3254e85f..887ba3a632 100644
--- a/backends/platform/ds/dsmain.cpp
+++ b/backends/platform/ds/dsmain.cpp
@@ -79,7 +79,6 @@
 
 #include "dsmain.h"
 #include "osystem_ds.h"
-#include "dsoptions.h"
 #include "engines/engine.h"
 
 #include "backends/plugins/ds/ds-provider.h"
@@ -105,7 +104,6 @@ static int callbackTimer;
 static OSystem_DS::TimerProc callback;
 
 // Scaled
-static bool scaledMode;
 static int scX;
 static int scY;
 
@@ -118,7 +116,6 @@ static int subScreenHeight = SCUMM_GAME_HEIGHT;
 static int subScreenScale = 256;
 
 static bool gameScreenSwap = false;
-bool isCpuScalerEnabled();
 
 // Shake
 static int s_shakeXOffset = 0;
@@ -131,27 +128,10 @@ static int touchScX, touchScY, touchX, touchY;
 static int gameWidth = 320;
 static int gameHeight = 200;
 
-// Scale
-static bool twoHundredPercentFixedScale = false;
-static bool cpuScalerEnable = false;
-
-bool isCpuScalerEnabled() {
-	return cpuScalerEnable;
-}
-
-
-void setCpuScalerEnable(bool enable) {
-	cpuScalerEnable = enable;
-}
-
 void setGameScreenSwap(bool enable) {
 	gameScreenSwap = enable;
 }
 
-void setGamma(int gamma) {
-	OSystem_DS::instance()->setGammaValue(gamma);
-}
-
 void setTopScreenZoom(int percentage) {
 	s32 scale = (percentage << 8) / 100;
 	subScreenScale = (256 * 256) / scale;
@@ -170,18 +150,10 @@ int getGameHeight() {
 	return gameHeight;
 }
 
-void set200PercentFixedScale(bool on) {
-	twoHundredPercentFixedScale = on;
-}
-
-void setUnscaledMode(bool enable) {
-	scaledMode = !enable;
-}
-
 void displayMode8Bit() {
 	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
 
-	if (isCpuScalerEnabled()) {
+	if (g_system->getGraphicsMode() == GFX_SWSCALE) {
 		REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
 
 		REG_BG3PA = 256;
@@ -252,7 +224,7 @@ void setMainScreenScroll(int x, int y) {
 }
 
 void setMainScreenScale(int x, int y) {
-		if (isCpuScalerEnabled() && (x==320)) {
+		if ((g_system->getGraphicsMode() == GFX_SWSCALE) && (x==320)) {
 			REG_BG3PA = 256;
 			REG_BG3PB = 0;
 			REG_BG3PC = 0;
@@ -318,27 +290,20 @@ void VBlankHandler(void) {
 	int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
 	int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
 
-
-	if (twoHundredPercentFixedScale) {
-		subScreenWidth = 256 >> 1;
-		subScreenHeight = 192 >> 1;
-	} else {
-		subScreenWidth = (256 * subScreenScale) >> 8;
-		subScreenHeight = (192 * subScreenScale) >> 8;
-
-		if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
-			subScreenWidth = 256;
-			subScreenHeight = 192;
-		} else if ( ((subScreenWidth) > 128 - 8) && ((subScreenWidth) < 128 + 8) ) {
-			subScreenWidth = 128;
-			subScreenHeight = 96;
-		} else if (subScreenWidth > 256) {
-			subScreenWidth = 320;
-			subScreenHeight = 200;
-		}
+	subScreenWidth = (256 * subScreenScale) >> 8;
+	subScreenHeight = (192 * subScreenScale) >> 8;
+
+	if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
+		subScreenWidth = 256;
+		subScreenHeight = 192;
+	} else if ( ((subScreenWidth) > 128 - 8) && ((subScreenWidth) < 128 + 8) ) {
+		subScreenWidth = 128;
+		subScreenHeight = 96;
+	} else if (subScreenWidth > 256) {
+		subScreenWidth = 320;
+		subScreenHeight = 200;
 	}
 
-
 	subScTargetX = xCenter - ((subScreenWidth  >> 1) << 8);
 	subScTargetY = yCenter - ((subScreenHeight >> 1) << 8);
 
@@ -348,7 +313,7 @@ void VBlankHandler(void) {
 	subScX += (subScTargetX - subScX) >> 2;
 	subScY += (subScTargetY - subScY) >> 2;
 
-	if (!scaledMode) {
+	if (g_system->getGraphicsMode() == GFX_NOSCALE) {
 		if (scX + 256 > gameWidth - 1) {
 			scX = gameWidth - 1 - 256;
 		}
@@ -443,7 +408,6 @@ void initHardware() {
 	REG_BG2PC = 0;
 	REG_BG2PD = 256;
 
-	scaledMode = true;
 	scX = 0;
 	scY = 0;
 	subScX = 0;
@@ -506,10 +470,6 @@ void fastRamReset() {
 /////////////////
 
 int main(int argc, char **argv) {
-	DS::initHardware();
-
-	defaultExceptionHandler();
-
 	g_system = new OSystem_DS();
 	assert(g_system);
 
diff --git a/backends/platform/ds/dsmain.h b/backends/platform/ds/dsmain.h
index b7c3e49001..7a492fb219 100644
--- a/backends/platform/ds/dsmain.h
+++ b/backends/platform/ds/dsmain.h
@@ -39,9 +39,7 @@ u16 *	get16BitBackBuffer();
 
 void 	setTalkPos(int x, int y);
 void 	setTopScreenTarget(int x, int y);
-void	set200PercentFixedScale(bool on);
 void	setTopScreenZoom(int percentage);
-void	setGamma(int gamma);
 
 // Timers
 void 	setTimerCallback(OSystem_DS::TimerProc proc, int interval);		// Setup a callback function at a regular interval
@@ -58,15 +56,13 @@ void 	setShakePos(int shakeXOffset, int shakeYOffset);
 
 // Options
 void	setGameScreenSwap(bool enable);
-void 	setUnscaledMode(bool enable);
-bool    isCpuScalerEnabled();
-void	setCpuScalerEnable(bool enable);
 
 // Display
 bool 	getIsDisplayMode8Bit();
 void 	setGameSize(int width, int height);
 int		getGameWidth();
 int		getGameHeight();
+void 	initHardware();
 
 // Fast RAM allocation (ITCM)
 void	fastRamReset();
diff --git a/backends/platform/ds/dsoptions.cpp b/backends/platform/ds/dsoptions.cpp
deleted file mode 100644
index 56f496c4cd..0000000000
--- a/backends/platform/ds/dsoptions.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "dsmain.h"
-#include "dsoptions.h"
-#include "gui/dialog.h"
-#include "gui/gui-manager.h"
-#include "gui/widgets/list.h"
-#include "gui/widgets/tab.h"
-#include "osystem_ds.h"
-#include "engines/scumm/scumm.h"
-#include "gui/widgets/popup.h"
-
-#include "common/translation.h"
-
-#define ALLOW_CPU_SCALER
-
-namespace DS {
-
-static bool confGetBool(Common::String key, bool defaultVal) {
-	if (ConfMan.hasKey(key, "ds"))
-		return ConfMan.getBool(key, "ds");
-	return defaultVal;
-}
-
-static int confGetInt(Common::String key, int defaultVal) {
-	if (ConfMan.hasKey(key, "ds"))
-		return ConfMan.getInt(key, "ds");
-	return defaultVal;
-}
-
-
-
-DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
-
-	new GUI::ButtonWidget(this, 10, 170, 72, 16, _("~C~lose"), U32String(), GUI::kCloseCmd);
-	new GUI::ButtonWidget(this, 320 - 10 - 130, 170, 120, 16, _("ScummVM Main Menu"), U32String(), 0x40000000, 'M');
-
-	_tab = new GUI::TabWidget(this, 10, 5, 300, 230 - 20 - 40 - 20);
-
-	_tab->addTab(_("Graphics"), "");
-
-	new GUI::StaticTextWidget(_tab, 5, 67, 180, 15, _("Initial top screen scale:"), Graphics::kTextAlignLeft);
-
-	_100PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 82, 80, 20, U32String("100%"), U32String("TODO: Add tooltip"), 0x30000001, 'T');
-	_150PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 97, 80, 20, U32String("150%"), U32String("TODO: Add tooltip"), 0x30000002, 'T');
-	_200PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 112, 80, 20, U32String("200%"), U32String("TODO: Add tooltip"), 0x30000003, 'T');
-
-	new GUI::StaticTextWidget(_tab, 5, 5, 180, 15, _("Main screen scaling:"), Graphics::kTextAlignLeft);
-
-	_hardScaler = new GUI::CheckboxWidget(_tab, 5, 20, 270, 20, _("Hardware scale (fast, but low quality)"), U32String(), 0x10000001, 'T');
-	_cpuScaler = new GUI::CheckboxWidget(_tab, 5, 35, 270, 20, _("Software scale (good quality, but slower)"), U32String(), 0x10000002, 'S');
-	_unscaledCheckbox = new GUI::CheckboxWidget(_tab, 5, 50, 270, 20, _("Unscaled (you must scroll left and right)"), U32String(), 0x10000003, 'S');
-
-	new GUI::StaticTextWidget(_tab, 5, 125, 110, 15, _("Brightness:"), Graphics::kTextAlignLeft);
-	_gammaCorrection = new GUI::SliderWidget(_tab, 130, 120, 130, 12, U32String("TODO: Add tooltip"), 1);
-	_gammaCorrection->setMinValue(0);
-	_gammaCorrection->setMaxValue(8);
-	_gammaCorrection->setValue(0);
-
-
-	_tab->setActiveTab(0);
-
-	_radioButtonMode = false;
-
-	_unscaledCheckbox->setState(confGetBool("unscaled", false));
-
-
-	if (ConfMan.hasKey("topscreenzoom", "ds")) {
-
-		_100PercentCheckbox->setState(false);
-		_150PercentCheckbox->setState(false);
-		_200PercentCheckbox->setState(false);
-
-		switch (ConfMan.getInt("topscreenzoom", "ds")) {
-			case 100: {
-				_100PercentCheckbox->setState(true);
-				break;
-			}
-
-			case 150: {
-				_150PercentCheckbox->setState(true);
-				break;
-			}
-
-			case 200: {
-				_200PercentCheckbox->setState(true);
-				break;
-			}
-		}
-
-	} else if (ConfMan.hasKey("twohundredpercent", "ds")) {
-		_200PercentCheckbox->setState(ConfMan.getBool("twohundredpercent", "ds"));
-	} else {
-		// No setting
-		_150PercentCheckbox->setState(true);
-	}
-
-	if (ConfMan.hasKey("gamma", "ds")) {
-		_gammaCorrection->setValue(ConfMan.getInt("gamma", "ds"));
-	} else {
-		_gammaCorrection->setValue(0);
-	}
-
-    #ifdef ALLOW_CPU_SCALER
-	_cpuScaler->setState(confGetBool("cpu_scaler", false));
-    #endif
-
-	if (!_cpuScaler->getState() && !_unscaledCheckbox->getState()) {
-		_hardScaler->setState(true);
-	}
-
-	_radioButtonMode = true;
-}
-
-DSOptionsDialog::~DSOptionsDialog() {
-	ConfMan.flushToDisk();
-}
-
-void DSOptionsDialog::updateConfigManager() {
-	ConfMan.setBool("unscaled", _unscaledCheckbox->getState(), "ds");
-#ifdef ALLOW_CPU_SCALER
-	ConfMan.setBool("cpu_scaler", _cpuScaler->getState(), "ds");
-#endif
-	ConfMan.setInt("gamma", _gammaCorrection->getValue(), "ds");
-
-	int zoomLevel = 150;
-
-	if (_100PercentCheckbox->getState()) {
-		zoomLevel = 100;
-	} else if (_150PercentCheckbox->getState()) {
-		zoomLevel = 150;
-	} else if (_200PercentCheckbox->getState()) {
-		zoomLevel = 200;
-	}
-
-	printf("Saved zoom: %d\n", zoomLevel);
-
-	ConfMan.setInt("topscreenzoom", zoomLevel, "ds");
-
-	DS::setOptions();
-}
-
-void DSOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
-
-	static bool guard = false;
-
-	if ((!guard) && (_radioButtonMode)) {
-		guard = true;
-
-		if ((cmd & 0xFF000000) == 0x10000000) {
-			_cpuScaler->setState(false);
-			_hardScaler->setState(false);
-			_unscaledCheckbox->setState(false);
-
-			if ((sender == _cpuScaler) && (cmd == 0x10000002)) {
-				_cpuScaler->setState(true);
-			}
-
-			if ((sender == _hardScaler) && (cmd == 0x10000001)) {
-				_hardScaler->setState(true);
-			}
-
-			if ((sender == _unscaledCheckbox) && (cmd == 0x10000003)) {
-				_unscaledCheckbox->setState(true);
-			}
-		}
-
-		guard = false;
-
-	}
-
-
-	if ((!guard) && (_radioButtonMode)) {
-
-		guard = true;
-
-		if (cmd == 0x30000001) {
-			_100PercentCheckbox->setState(true);
-			_150PercentCheckbox->setState(false);
-			_200PercentCheckbox->setState(false);
-			DS::setTopScreenZoom(100);
-		}
-
-		if (cmd == 0x30000002) {
-			_100PercentCheckbox->setState(false);
-			_150PercentCheckbox->setState(true);
-			_200PercentCheckbox->setState(false);
-			DS::setTopScreenZoom(150);
-		}
-
-		if (cmd == 0x30000003) {
-			_100PercentCheckbox->setState(false);
-			_150PercentCheckbox->setState(false);
-			_200PercentCheckbox->setState(true);
-			DS::setTopScreenZoom(200);
-		}
-
-		guard = false;
-
-	}
-
-
-	if (cmd == GUI::kCloseCmd) {
-		updateConfigManager();
-		close();
-	}
-
-
-	if ((!guard) && (cmd == 0x40000000)) {
-		close();
-		g_engine->openMainMenuDialog();
-	}
-}
-
-
-void showOptionsDialog() {
-	DSOptionsDialog *d = new DSOptionsDialog();
-	d->runModal();
-	delete d;
-}
-
-void setOptions() {
-	static bool firstLoad = true;
-
-	ConfMan.addGameDomain("ds");
-
-	DS::setUnscaledMode(confGetBool("unscaled", false));
-
-	if (firstLoad) {
-		if (ConfMan.hasKey("topscreenzoom", "ds")) {
-			DS::setTopScreenZoom(ConfMan.getInt("topscreenzoom", "ds"));
-		} else {
-			if (ConfMan.hasKey("twohundredpercent", "ds")) {
-				DS::setTopScreenZoom(200);
-			} else {
-				DS::setTopScreenZoom(150);
-			}
-		}
-	}
-
-#ifdef ALLOW_CPU_SCALER
-	DS::setCpuScalerEnable(confGetBool("cpu_scaler", false));
-#endif
-
-	DS::setGamma(confGetInt("gamma", 0));
-
-	firstLoad = false;
-}
-
-} // End of namespace DS
diff --git a/backends/platform/ds/dsoptions.h b/backends/platform/ds/dsoptions.h
deleted file mode 100644
index 4be07c93c2..0000000000
--- a/backends/platform/ds/dsoptions.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef _DSOPTIONS_H_
-#define _DSOPTIONS_H_
-
-
-#include "common/scummsys.h"
-#include "common/str.h"
-#include "common/config-manager.h"
-#include "common/ustr.h"
-
-#include "gui/object.h"
-#include "gui/widget.h"
-#include "gui/dialog.h"
-#include "gui/widgets/tab.h"
-#include "scumm/dialogs.h"
-
-namespace DS {
-
-class DSOptionsDialog : public GUI::Dialog {
-
-typedef Common::U32String U32String;
-
-public:
-	DSOptionsDialog();
-	~DSOptionsDialog();
-
-protected:
-	virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
-	void updateConfigManager();
-
-	GUI::TabWidget *_tab;
-
-	GUI::SliderWidget *_gammaCorrection;
-	GUI::CheckboxWidget *_unscaledCheckbox;
-	GUI::CheckboxWidget *_100PercentCheckbox;
-	GUI::CheckboxWidget *_150PercentCheckbox;
-	GUI::CheckboxWidget *_200PercentCheckbox;
-
-	GUI::CheckboxWidget *_hardScaler;
-	GUI::CheckboxWidget *_cpuScaler;
-
-	bool	_radioButtonMode;
-
-};
-
-extern void showOptionsDialog();
-extern void setOptions();
-
-} // End of namespace DS
-
-#endif
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
index 891ef685ec..3541b46a12 100644
--- a/backends/platform/ds/module.mk
+++ b/backends/platform/ds/module.mk
@@ -3,8 +3,7 @@ MODULE := backends/platform/ds
 MODULE_OBJS := \
 	blitters_arm.o \
 	dsmain.o \
-	osystem_ds.o \
-	dsoptions.o
+	osystem_ds.o
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index 9f2bfb842c..5f2c3a45d3 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -58,7 +58,8 @@ OSystem_DS *OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
 	: _eventSource(NULL), _mixer(NULL), _isOverlayShown(true),
-	_disableCursorPalette(true), _graphicsEnable(true), _gammaValue(0)
+	_graphicsMode(GFX_HWSCALE), _stretchMode(100),
+	_disableCursorPalette(true), _graphicsEnable(true)
 {
 	_instance = this;
 
@@ -78,6 +79,10 @@ int OSystem_DS::timerHandler(int t) {
 }
 
 void OSystem_DS::initBackend() {
+	DS::initHardware();
+
+	defaultExceptionHandler();
+
 	ConfMan.setInt("autosave_period", 0);
 	ConfMan.setBool("FM_medium_quality", true);
 
@@ -100,7 +105,7 @@ void OSystem_DS::initBackend() {
 }
 
 bool OSystem_DS::hasFeature(Feature f) {
-	return (f == kFeatureCursorPalette);
+	return (f == kFeatureCursorPalette) || (f == kFeatureStretchMode);
 }
 
 void OSystem_DS::setFeatureState(Feature f, bool enable) {
@@ -116,6 +121,62 @@ bool OSystem_DS::getFeatureState(Feature f) {
 	return false;
 }
 
+static const OSystem::GraphicsMode graphicsModes[] = {
+	{ "NONE",  _s("Unscaled"),                                  GFX_NOSCALE },
+	{ "HW",    _s("Hardware scale (fast, but low quality)"),    GFX_HWSCALE },
+	{ "SW",    _s("Software scale (good quality, but slower)"), GFX_SWSCALE },
+	{ nullptr, nullptr,                                         0           }
+};
+
+const OSystem::GraphicsMode *OSystem_DS::getSupportedGraphicsModes() const {
+	return graphicsModes;
+}
+
+int OSystem_DS::getDefaultGraphicsMode() const {
+	return GFX_HWSCALE;
+}
+
+bool OSystem_DS::setGraphicsMode(int mode) {
+	switch (mode) {
+	case GFX_NOSCALE:
+	case GFX_HWSCALE:
+	case GFX_SWSCALE:
+		_graphicsMode = mode;
+		return true;
+	default:
+		return false;
+	}
+}
+
+int OSystem_DS::getGraphicsMode() const {
+	return _graphicsMode;
+}
+
+static const OSystem::GraphicsMode stretchModes[] = {
+	{ "100",   "100%",  100 },
+	{ "150",   "150%",  150 },
+	{ "200",   "200%",  200 },
+	{ nullptr, nullptr, 0   }
+};
+
+const OSystem::GraphicsMode *OSystem_DS::getSupportedStretchModes() const {
+	return stretchModes;
+}
+
+int OSystem_DS::getDefaultStretchMode() const {
+	return 100;
+}
+
+bool OSystem_DS::setStretchMode(int mode) {
+	_stretchMode = mode;
+	DS::setTopScreenZoom(mode);
+	return true;
+}
+
+int OSystem_DS::getStretchMode() const {
+	return _stretchMode;
+}
+
 void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
 	_framebuffer.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
 
@@ -152,10 +213,9 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 			u16 paletteValue = red | (green << 5) | (blue << 10);
 
 			if (!_isOverlayShown) {
-				int col = applyGamma(paletteValue);
-				BG_PALETTE[r] = col;
+				BG_PALETTE[r] = paletteValue;
 #ifdef DISABLE_TEXT_CONSOLE
-				BG_PALETTE_SUB[r] = col;
+				BG_PALETTE_SUB[r] = paletteValue;
 #endif
 			}
 
@@ -209,7 +269,7 @@ void OSystem_DS::updateScreen() {
 		dmaCopyHalfWords(3, back, BG_GFX, 256 * 192 * 2);
 	} else if (!_graphicsEnable) {
 		return;
-	} else if (DS::isCpuScalerEnabled()) {
+	} else if (_graphicsMode == GFX_SWSCALE) {
 		u16 *base = BG_GFX + 0x10000;
 		Rescale_320x256xPAL8_To_256x256x1555(
 			base,
@@ -422,32 +482,6 @@ void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
 #endif
 }
 
-u16 OSystem_DS::applyGamma(u16 color) {
-	// Attempt to do gamma correction (or something like it) to palette entries
-	// to improve the contrast of the image on the original DS screen.
-
-	// Split the color into it's component channels
-	int r = color & 0x001F;
-	int g = (color & 0x03E0) >> 5;
-	int b = (color & 0x7C00) >> 10;
-
-	// Caluclate the scaling factor for this color based on it's brightness
-	int scale = ((23 - ((r + g + b) >> 2)) * _gammaValue) >> 3;
-
-	// Scale the three components by the scaling factor, with clamping
-	r = r + ((r * scale) >> 4);
-	if (r > 31) r = 31;
-
-	g = g + ((g * scale) >> 4);
-	if (g > 31) g = 31;
-
-	b = b + ((b * scale) >> 4);
-	if (b > 31) b = 31;
-
-	// Stick them back together into a 555 color value
-	return 0x8000 | r | (g << 5) | (b << 10);
-}
-
 static const Common::HardwareInputTableEntry ndsJoystickButtons[] = {
     { "JOY_A",              Common::JOYSTICK_BUTTON_A,              _s("A")           },
     { "JOY_B",              Common::JOYSTICK_BUTTON_B,              _s("B")           },
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index 9e742f9840..7b7caa191e 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -35,11 +35,18 @@
 #include "graphics/surface.h"
 #include "graphics/palette.h"
 
+enum {
+	GFX_NOSCALE = 0,
+	GFX_HWSCALE = 1,
+	GFX_SWSCALE = 2
+};
+
 class OSystem_DS : public BaseBackend, public PaletteManager {
 protected:
 	Audio::MixerImpl *_mixer;
 	Graphics::Surface _framebuffer, _overlay, _cursor;
 	bool _graphicsEnable, _isOverlayShown;
+	int _graphicsMode, _stretchMode;
 
 	static OSystem_DS *_instance;
 
@@ -58,8 +65,6 @@ protected:
 	Graphics::Surface *createTempFrameBuffer();
 	bool _disableCursorPalette;
 
-	int _gammaValue;
-
 public:
 	typedef int  (*TimerProc)(int interval);
 
@@ -71,6 +76,17 @@ public:
 	virtual bool hasFeature(Feature f);
 	virtual void setFeatureState(Feature f, bool enable);
 	virtual bool getFeatureState(Feature f);
+
+	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
+	virtual int getDefaultGraphicsMode() const;
+	virtual bool setGraphicsMode(int mode);
+	virtual int getGraphicsMode() const;
+
+	virtual const GraphicsMode *getSupportedStretchModes() const;
+	virtual int getDefaultStretchMode() const;
+	virtual bool setStretchMode(int mode);
+	virtual int getStretchMode() const;
+
 	virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
 	virtual int16 getHeight();
 	virtual int16 getWidth();
@@ -136,9 +152,6 @@ public:
 	void refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette);
 
 	virtual void logMessage(LogMessageType::Type type, const char *message);
-
-	u16 applyGamma(u16 color);
-	void setGammaValue(int gamma) { _gammaValue = gamma; }
 };
 
 #endif
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 41a16b160f..5d3448f6b8 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -283,14 +283,6 @@ void LauncherDialog::updateListing() {
 	// Turn it into a list of pointers
 	Common::List<LauncherEntry> domainList;
 	for (ConfigManager::DomainMap::const_iterator iter = domains.begin(); iter != domains.end(); ++iter) {
-#ifdef __DS__
-		// DS port uses an extra section called 'ds'.  This prevents the section from being
-		// detected as a game.
-		if (iter->_key == "ds") {
-			continue;
-		}
-#endif
-
 		String description(iter->_value.getVal("description"));
 
 		if (description.empty()) {
diff --git a/gui/massadd.cpp b/gui/massadd.cpp
index b071c02ac2..c7e3966047 100644
--- a/gui/massadd.cpp
+++ b/gui/massadd.cpp
@@ -95,15 +95,6 @@ MassAddDialog::MassAddDialog(const Common::FSNode &startDir)
 	const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
 	Common::ConfigManager::DomainMap::const_iterator iter;
 	for (iter = domains.begin(); iter != domains.end(); ++iter) {
-
-#ifdef __DS__
-		// DS port uses an extra section called 'ds'.  This prevents the section from being
-		// detected as a game.
-		if (iter->_key == "ds") {
-			continue;
-		}
-#endif
-
 		Common::String path(iter->_value.getVal("path"));
 		// Remove trailing slash, so that "/foo" and "/foo/" match.
 		// This works around a bug in the POSIX FS code (and others?)


Commit: 66472abf1ac92eb5febab05f2724536e3043232c
    https://github.com/scummvm/scummvm/commit/66472abf1ac92eb5febab05f2724536e3043232c
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Move timer code into OSystem_DS

Changed paths:
    backends/platform/ds/dsmain.cpp
    backends/platform/ds/dsmain.h
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/dsmain.cpp b/backends/platform/ds/dsmain.cpp
index 887ba3a632..916a3b0267 100644
--- a/backends/platform/ds/dsmain.cpp
+++ b/backends/platform/ds/dsmain.cpp
@@ -91,18 +91,9 @@ namespace DS {
 // From console.c in NDSLib
 
 // Defines
-#define FRAME_TIME 17
 #define SCUMM_GAME_HEIGHT 142
 #define SCUMM_GAME_WIDTH 227
 
-static int frameCount;
-static int currentTimeMillis;
-
-// Timer Callback
-static int callbackInterval;
-static int callbackTimer;
-static OSystem_DS::TimerProc callback;
-
 // Scaled
 static int scX;
 static int scY;
@@ -191,15 +182,6 @@ void setShakePos(int shakeXOffset, int shakeYOffset) {
 	s_shakeYOffset = shakeYOffset;
 }
 
-void doTimerCallback() {
-	if (callback) {
-		if (callbackTimer <= 0) {
-			callbackTimer += callbackInterval;
-			callback(callbackInterval);
-		}
-	}
-}
-
 Common::Point warpMouse(int penX, int penY, bool isOverlayShown) {
 	int storedMouseX, storedMouseY;
 	if (!isOverlayShown) {
@@ -214,7 +196,7 @@ Common::Point warpMouse(int penX, int penY, bool isOverlayShown) {
 }
 
 void setMainScreenScroll(int x, int y) {
-		REG_BG3X = x + (((frameCount & 1) == 0)? 64: 0);
+		REG_BG3X = x;
 		REG_BG3Y = y;
 
 		if (!gameScreenSwap) {
@@ -249,7 +231,7 @@ void setZoomedScreenScroll(int x, int y, bool shake) {
 		}
 
 #ifdef DISABLE_TEXT_CONSOLE
-		REG_BG3X_SUB = x + ((shake && (frameCount & 1) == 0)? 64: 0);
+		REG_BG3X_SUB = x;
 		REG_BG3Y_SUB = y;
 #endif
 }
@@ -281,12 +263,6 @@ Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown) {
 }
 
 void VBlankHandler(void) {
-	frameCount++;
-
-	if (callback) {
-		callbackTimer -= FRAME_TIME;
-	}
-
 	int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
 	int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
 
@@ -352,27 +328,6 @@ void VBlankHandler(void) {
 	}
 }
 
-int getMillis(bool skipRecord) {
-	return currentTimeMillis;
-}
-
-void setTimerCallback(OSystem_DS::TimerProc proc, int interval) {
-	callback = proc;
-	callbackInterval = interval;
-	callbackTimer = interval;
-}
-
-void timerTickHandler() {
-	if ((callback) && (callbackTimer > 0)) {
-		callbackTimer--;
-	}
-	currentTimeMillis++;
-}
-
-
-
-
-
 void setTalkPos(int x, int y) {
 	setTopScreenTarget(x, y);
 }
@@ -417,18 +372,10 @@ void initHardware() {
 
 	lcdMainOnBottom();
 
-	frameCount = 0;
-	callback = NULL;
-
 	//irqs are nice
 	irqSet(IRQ_VBLANK, VBlankHandler);
 	irqEnable(IRQ_VBLANK);
 
-	// Set up a millisecond timer
-	currentTimeMillis = 0;
-	timerStart(0, ClockDivider_1, (u16)TIMER_FREQ(1000), timerTickHandler);
-	REG_IME = 1;
-
 #ifndef DISABLE_TEXT_CONSOLE
 	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
 	vramSetBankH(VRAM_H_SUB_BG);
diff --git a/backends/platform/ds/dsmain.h b/backends/platform/ds/dsmain.h
index 7a492fb219..be41e54c1a 100644
--- a/backends/platform/ds/dsmain.h
+++ b/backends/platform/ds/dsmain.h
@@ -41,11 +41,6 @@ void 	setTalkPos(int x, int y);
 void 	setTopScreenTarget(int x, int y);
 void	setTopScreenZoom(int percentage);
 
-// Timers
-void 	setTimerCallback(OSystem_DS::TimerProc proc, int interval);		// Setup a callback function at a regular interval
-int 	getMillis(bool skipRecord = false);								// Return the current runtime in milliseconds
-void 	doTimerCallback();												// Call callback function if required
-
 // Events
 void 	VBlankHandler();
 Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown);
diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index 5f2c3a45d3..c2295b12c0 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -59,7 +59,8 @@ OSystem_DS *OSystem_DS::_instance = NULL;
 OSystem_DS::OSystem_DS()
 	: _eventSource(NULL), _mixer(NULL), _isOverlayShown(true),
 	_graphicsMode(GFX_HWSCALE), _stretchMode(100),
-	_disableCursorPalette(true), _graphicsEnable(true)
+	_disableCursorPalette(true), _graphicsEnable(true),
+	_callbackTimer(10), _currentTimeMillis(0)
 {
 	_instance = this;
 
@@ -72,10 +73,12 @@ OSystem_DS::~OSystem_DS() {
 	_mixer = 0;
 }
 
-int OSystem_DS::timerHandler(int t) {
-	DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager();
-	tm->handler();
-	return t;
+void timerTickHandler() {
+	OSystem_DS *system = OSystem_DS::instance();
+	if (system->_callbackTimer > 0) {
+		system->_callbackTimer--;
+	}
+	system->_currentTimeMillis++;
 }
 
 void OSystem_DS::initBackend() {
@@ -91,7 +94,8 @@ void OSystem_DS::initBackend() {
 
 	_savefileManager = new DefaultSaveFileManager();
 	_timerManager = new DefaultTimerManager();
-    DS::setTimerCallback(&OSystem_DS::timerHandler, 10);
+	timerStart(0, ClockDivider_1, (u16)TIMER_FREQ(1000), timerTickHandler);
+	REG_IME = 1;
 
 	_mixer = new Audio::MixerImpl(11025);
 	_mixer->setReady(true);
@@ -403,7 +407,7 @@ void OSystem_DS::refreshCursor(u16 *dst, const Graphics::Surface &src, const uin
 }
 
 uint32 OSystem_DS::getMillis(bool skipRecord) {
-	return DS::getMillis();
+	return _currentTimeMillis;
 }
 
 void OSystem_DS::delayMillis(uint msecs) {
@@ -411,17 +415,19 @@ void OSystem_DS::delayMillis(uint msecs) {
 
 	while (st + msecs >= getMillis());
 
-	DS::doTimerCallback();
+	doTimerCallback();
 }
 
+void OSystem_DS::doTimerCallback(int interval) {
+	DefaultTimerManager *tm = (DefaultTimerManager *)getTimerManager();
+	if (_callbackTimer <= 0) {
+		_callbackTimer += interval;
+		tm->handler();
+	}
+}
 
 void OSystem_DS::getTimeAndDate(TimeDate &td) const {
-	time_t curTime;
-#if 0
-	curTime = time(0);
-#else
-	curTime = 0xABCD1234 + DS::getMillis() / 1000;
-#endif
+	time_t curTime = time(0);
 	struct tm t = *localtime(&curTime);
 	td.tm_sec = t.tm_sec;
 	td.tm_min = t.tm_min;
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index 7b7caa191e..e3ac19416f 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -66,8 +66,6 @@ protected:
 	bool _disableCursorPalette;
 
 public:
-	typedef int  (*TimerProc)(int interval);
-
 	OSystem_DS();
 	virtual ~OSystem_DS();
 
@@ -121,6 +119,7 @@ public:
 	virtual uint32 getMillis(bool skipRecord = false);
 	virtual void delayMillis(uint msecs);
 	virtual void getTimeAndDate(TimeDate &t) const;
+	void doTimerCallback(int interval = 10);
 
 	virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }
 	virtual Common::HardwareInputSet *getHardwareInputSet();
@@ -145,13 +144,13 @@ public:
 
 	virtual Audio::Mixer *getMixer() { return _mixer; }
 
-	static int timerHandler(int t);
-
 	virtual void setCursorPalette(const byte *colors, uint start, uint num);
 
 	void refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette);
 
 	virtual void logMessage(LogMessageType::Type type, const char *message);
+
+	int _currentTimeMillis, _callbackTimer;
 };
 
 #endif


Commit: fe05ae75cdac28d44777fc6073ae2a1c76b75499
    https://github.com/scummvm/scummvm/commit/fe05ae75cdac28d44777fc6073ae2a1c76b75499
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Support detecting the system language

Changed paths:
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index c2295b12c0..0c49e990b8 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -523,3 +523,16 @@ Common::HardwareInputSet *OSystem_DS::getHardwareInputSet() {
 
 	return inputSet;
 }
+
+Common::String OSystem_DS::getSystemLanguage() const {
+	switch (PersonalData->language) {
+		case 0: return "ja_JP";
+		case 1: return "en_US";
+		case 2: return "fr_FR";
+		case 3: return "de_DE";
+		case 4: return "it_IT";
+		case 5: return "es_ES";
+		case 6: return "zh_CN";
+		default: return "en_US";
+	}
+}
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index e3ac19416f..d24a5bafee 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -124,6 +124,8 @@ public:
 	virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }
 	virtual Common::HardwareInputSet *getHardwareInputSet();
 
+	virtual Common::String getSystemLanguage() const;
+
 	virtual MutexRef createMutex(void);
 	virtual void lockMutex(MutexRef mutex);
 	virtual void unlockMutex(MutexRef mutex);


Commit: 8b551345471907a423a5bc3122c230c672ed8f70
    https://github.com/scummvm/scummvm/commit/8b551345471907a423a5bc3122c230c672ed8f70
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Re-add audio support using MaxMod

Changed paths:
  A backends/mixer/maxmod/maxmod-mixer.cpp
  A backends/mixer/maxmod/maxmod-mixer.h
    backends/module.mk
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h
    configure


diff --git a/backends/mixer/maxmod/maxmod-mixer.cpp b/backends/mixer/maxmod/maxmod-mixer.cpp
new file mode 100644
index 0000000000..b252d78b7c
--- /dev/null
+++ b/backends/mixer/maxmod/maxmod-mixer.cpp
@@ -0,0 +1,82 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Allow use of stuff in <nds.h>
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
+
+#include "common/scummsys.h"
+
+#if defined(__DS__)
+
+#include "backends/mixer/maxmod/maxmod-mixer.h"
+#include "common/system.h"
+
+#include <nds.h>
+#include <maxmod9.h>
+
+MaxModMixerManager::MaxModMixerManager(int freq, int bufSize)
+	:
+	_mixer(0),
+	_freq(freq),
+	_bufSize(bufSize) {
+
+}
+
+MaxModMixerManager::~MaxModMixerManager() {
+	_mixer->setReady(false);
+	mmStreamClose();
+	delete _mixer;
+}
+
+mm_word on_stream_request( mm_word length, mm_addr dest, mm_stream_formats format ) {
+	Audio::MixerImpl *mixer = (Audio::MixerImpl *)g_system->getMixer();
+	assert(mixer);
+	mixer->mixCallback((byte *)dest, length * 4);
+	return length;
+}
+
+void MaxModMixerManager::init() {
+	_mixer = new Audio::MixerImpl(_freq);
+	assert(_mixer);
+
+	mm_ds_system sys;
+	sys.mod_count 			= 0;
+	sys.samp_count			= 0;
+	sys.mem_bank			= 0;
+	sys.fifo_channel		= FIFO_MAXMOD;
+	mmInit( &sys );
+
+	mm_stream mystream;
+	mystream.sampling_rate = _freq;
+	mystream.buffer_length = _bufSize / 4;
+	mystream.callback = on_stream_request;
+	mystream.format = MM_STREAM_16BIT_STEREO;
+	mystream.timer = MM_TIMER2;
+	mystream.manual = 0;
+
+	mmStreamOpen( &mystream );
+
+	_mixer->setReady(true);
+}
+
+#endif
diff --git a/backends/mixer/maxmod/maxmod-mixer.h b/backends/mixer/maxmod/maxmod-mixer.h
new file mode 100644
index 0000000000..45d4e95f55
--- /dev/null
+++ b/backends/mixer/maxmod/maxmod-mixer.h
@@ -0,0 +1,55 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_MIXER_MAXMOD_H
+#define BACKENDS_MIXER_MAXMOD_H
+
+#include "audio/mixer_intern.h"
+
+/**
+ * MaxMod mixer manager. It wraps the actual implementation
+ * of the Audio:Mixer used by the engine, and sets up
+ * MaxMod and the callback for the audio mixer implementation.
+ */
+class MaxModMixerManager {
+public:
+	MaxModMixerManager(int freq, int bufSize);
+	virtual ~MaxModMixerManager();
+
+	/**
+	 * Initialize and setups the mixer
+	 */
+	virtual void init();
+
+	/**
+	 * Get the audio mixer implementation
+	 */
+	Audio::Mixer *getMixer() { return (Audio::Mixer *)_mixer; }
+
+protected:
+	/** The mixer implementation */
+	Audio::MixerImpl *_mixer;
+
+	int _freq, _bufSize;
+};
+
+#endif
diff --git a/backends/module.mk b/backends/module.mk
index fac688fedb..83760aae1e 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -291,6 +291,7 @@ MODULE_OBJS += \
 	fs/posix-drives/posix-drives-fs.o \
 	fs/posix-drives/posix-drives-fs-factory.o \
 	fs/devoptab/devoptab-fs-factory.o \
+	mixer/maxmod/maxmod-mixer.o \
 	plugins/ds/ds-provider.o
 endif
 
diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index 0c49e990b8..2766238aec 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -57,7 +57,7 @@
 OSystem_DS *OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
-	: _eventSource(NULL), _mixer(NULL), _isOverlayShown(true),
+	: _eventSource(NULL), _mixerManager(NULL), _isOverlayShown(true),
 	_graphicsMode(GFX_HWSCALE), _stretchMode(100),
 	_disableCursorPalette(true), _graphicsEnable(true),
 	_callbackTimer(10), _currentTimeMillis(0)
@@ -69,8 +69,8 @@ OSystem_DS::OSystem_DS()
 }
 
 OSystem_DS::~OSystem_DS() {
-	delete _mixer;
-	_mixer = 0;
+	delete _mixerManager;
+	_mixerManager = 0;
 }
 
 void timerTickHandler() {
@@ -95,10 +95,9 @@ void OSystem_DS::initBackend() {
 	_savefileManager = new DefaultSaveFileManager();
 	_timerManager = new DefaultTimerManager();
 	timerStart(0, ClockDivider_1, (u16)TIMER_FREQ(1000), timerTickHandler);
-	REG_IME = 1;
 
-	_mixer = new Audio::MixerImpl(11025);
-	_mixer->setReady(true);
+	_mixerManager = new MaxModMixerManager(11025, 4096);
+	_mixerManager->init();
 
 	oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
 	_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index d24a5bafee..c755df2c5c 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -24,14 +24,9 @@
 #ifndef _OSYSTEM_DS_H_
 #define _OSYSTEM_DS_H_
 
-// Allow use of stuff in <nds.h>
-#define FORBIDDEN_SYMBOL_EXCEPTION_printf
-#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
-
 #include "backends/base-backend.h"
 #include "backends/events/ds/ds-events.h"
-#include "nds.h"
-#include "audio/mixer_intern.h"
+#include "backends/mixer/maxmod/maxmod-mixer.h"
 #include "graphics/surface.h"
 #include "graphics/palette.h"
 
@@ -43,7 +38,7 @@ enum {
 
 class OSystem_DS : public BaseBackend, public PaletteManager {
 protected:
-	Audio::MixerImpl *_mixer;
+	MaxModMixerManager *_mixerManager;
 	Graphics::Surface _framebuffer, _overlay, _cursor;
 	bool _graphicsEnable, _isOverlayShown;
 	int _graphicsMode, _stretchMode;
@@ -144,7 +139,7 @@ public:
 	virtual Graphics::Surface *lockScreen();
 	virtual void unlockScreen();
 
-	virtual Audio::Mixer *getMixer() { return _mixer; }
+	virtual Audio::Mixer *getMixer() { return _mixerManager->getMixer(); }
 
 	virtual void setCursorPalette(const byte *colors, uint start, uint num);
 
diff --git a/configure b/configure
index d1349450b9..21af29f1ba 100755
--- a/configure
+++ b/configure
@@ -3016,6 +3016,7 @@ EOF
 		append_var LIBS "-specs=ds_arm9.specs"
 		append_var LIBS "-lfilesystem"
 		append_var LIBS "-lfat"
+		append_var LIBS "-lmm9"
 		append_var LIBS "-lnds9"
 		;;
 	freebsd* | openbsd*)


Commit: a900337952dbc7608c21f9b602bbfb32bec371d4
    https://github.com/scummvm/scummvm/commit/a900337952dbc7608c21f9b602bbfb32bec371d4
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Fix default search paths

Changed paths:
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h
    backends/plugins/ds/ds-provider.cpp
    backends/plugins/ds/ds-provider.h
    configure


diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index 2766238aec..b6a56aa32c 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -405,6 +405,10 @@ void OSystem_DS::refreshCursor(u16 *dst, const Graphics::Surface &src, const uin
 	}
 }
 
+void OSystem_DS::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
+	s.add("nitro:/", new Common::FSDirectory("nitro:/"), priority);
+}
+
 uint32 OSystem_DS::getMillis(bool skipRecord) {
 	return _currentTimeMillis;
 }
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index c755df2c5c..47c5b0e757 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -111,6 +111,8 @@ public:
 	virtual void warpMouse(int x, int y);
 	virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
 
+	virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
+
 	virtual uint32 getMillis(bool skipRecord = false);
 	virtual void delayMillis(uint msecs);
 	virtual void getTimeAndDate(TimeDate &t) const;
diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp
index c5419a989a..8353cbbfa1 100644
--- a/backends/plugins/ds/ds-provider.cpp
+++ b/backends/plugins/ds/ds-provider.cpp
@@ -46,4 +46,8 @@ Plugin *DSPluginProvider::createPlugin(const Common::FSNode &node) const {
 	return new TemplatedELFPlugin<DSDLObject>(node.getPath());
 }
 
+void DSPluginProvider::addCustomDirectories(Common::FSList &dirs) const {
+	dirs.push_back(Common::FSNode("nitro:/plugins"));
+}
+
 #endif // defined(DYNAMIC_MODULES) && defined(__DS__)
diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h
index 4eae89383b..c77cd9667e 100644
--- a/backends/plugins/ds/ds-provider.h
+++ b/backends/plugins/ds/ds-provider.h
@@ -30,6 +30,7 @@
 class DSPluginProvider : public ELFPluginProvider {
 public:
 	Plugin *createPlugin(const Common::FSNode &node) const;
+	void addCustomDirectories(Common::FSList &dirs) const;
 };
 
 #endif // BACKENDS_PLUGINS_DS_PROVIDER_H
diff --git a/configure b/configure
index 21af29f1ba..62421d6728 100755
--- a/configure
+++ b/configure
@@ -1724,12 +1724,6 @@ ds)
 	_host_os=ds
 	_host_cpu=arm
 	_host_alias=arm-none-eabi
-
-	test "x$prefix" = xNONE && prefix=nitro:
-
-	datarootdir='${prefix}'
-	datadir='${datarootdir}'
-	docdir='${prefix}/doc'
 	;;
 gamecube)
 	_host_os=gamecube
@@ -5872,7 +5866,7 @@ test "x$prefix" = xNONE && prefix=/usr/local
 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
 case $_host_os in
-	mingw*)
+	ds | mingw*)
 		# Windows stores all the external data files in executable file.
 		;;
 	*)
@@ -5881,9 +5875,11 @@ case $_host_os in
 esac
 
 case $_backend in
-	3ds | ds)
+	3ds)
 		append_var DEFINES "-DPLUGIN_DIRECTORY=\\\"$datadir/plugins\\\""
 		;;
+	ds)
+		;;
 	openpandora)
 		# Add ../plugins as a path so plugins can be found when running from a .PND.
 		append_var DEFINES "-DPLUGIN_DIRECTORY=\\\"../plugins\\\""


Commit: d614f3ce2c06e300e0e6a9c0335021c550d0678d
    https://github.com/scummvm/scummvm/commit/d614f3ce2c06e300e0e6a9c0335021c550d0678d
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
AUDIO: Disable Paula filtering on the DS

It's too slow with it enabled.

Changed paths:
    audio/mods/paula.h
    audio/mods/soundfx.cpp


diff --git a/audio/mods/paula.h b/audio/mods/paula.h
index 07a8793f27..941cbdca81 100644
--- a/audio/mods/paula.h
+++ b/audio/mods/paula.h
@@ -49,7 +49,13 @@ public:
 	enum FilterMode {
 		kFilterModeNone = 0,
 		kFilterModeA500,
-		kFilterModeA1200
+		kFilterModeA1200,
+
+#if defined(__DS__)
+		kFilterModeDefault = kFilterModeNone
+#else
+		kFilterModeDefault = kFilterModeA1200
+#endif
 	};
 
 	/* TODO: Document this */
@@ -69,10 +75,9 @@ public:
 	};
 
 	Paula(bool stereo = false, int rate = 44100, uint interruptFreq = 0,
-	      FilterMode filterMode = Paula::defaultFilterMode(), int periodScaleDivisor = 1);
+	      FilterMode filterMode = kFilterModeDefault, int periodScaleDivisor = 1);
 	~Paula();
 
-	static FilterMode defaultFilterMode() { return kFilterModeA1200; }
 	bool playing() const { return _playing; }
 	void setTimerBaseValue( uint32 ticksPerSecond ) { _timerBase = ticksPerSecond; }
 	uint32 getTimerBaseValue() { return _timerBase; }
diff --git a/audio/mods/soundfx.cpp b/audio/mods/soundfx.cpp
index 3462e55fd0..5469a18b5a 100644
--- a/audio/mods/soundfx.cpp
+++ b/audio/mods/soundfx.cpp
@@ -77,7 +77,7 @@ protected:
 };
 
 SoundFx::SoundFx(int rate, bool stereo, bool repeat, int periodScaleDivisor)
-	: Paula(stereo, rate, 0, Paula::defaultFilterMode(), periodScaleDivisor) {
+	: Paula(stereo, rate, 0, kFilterModeDefault, periodScaleDivisor) {
 	setTimerBaseValue(kPalCiaClock);
 	_ticks = 0;
 	_delay = 0;


Commit: 6fa77b342919c38b56c8ed161342c59c29cdce7b
    https://github.com/scummvm/scummvm/commit/6fa77b342919c38b56c8ed161342c59c29cdce7b
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Remove optimization of individual files for speed

Mixing ARM and THUMB code in dynamic plugins causes relocation issues.

Changed paths:
    backends/platform/ds/ds.mk
    configure


diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk
index 9e4e1c6275..04a63bb0b4 100644
--- a/backends/platform/ds/ds.mk
+++ b/backends/platform/ds/ds.mk
@@ -25,69 +25,6 @@
 #   There are a few game specific hacks which are currently controlled by this,
 #   too; we need to investigate those.
 
-# Set location of ndsdir so that we can easily refer to files in it
-ndsdir = backends/platform/ds
-
-# Compiler options for files which should be optimised for speed
-OPT_SPEED := -O3 -marm
-
-# Compiler options for files which should be optimised for space
-OPT_SIZE := -Os -mthumb
-
-# By default optimize for size
-CXXFLAGS += $(OPT_SIZE)
-
-# Files listed below will be optimisied for speed, otherwise they will be optimised for space.
-# TODO: Several of these files probably should not be optimized for speed, but for now
-# we replicate the *precise* list from the old DS makefile, to ensure full compatibility.
-# Eventually, we should tune this list.
-$(ndsdir)/blitters.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-$(ndsdir)/dsmain.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-$(ndsdir)/osystem_ds.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-base/main.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-sound/rate.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-sound/softsynth/opl/mame.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/agi/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/agos/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/agos/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/cine/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/cruise/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/cruise/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/draci/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/draci/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/gob/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/groovie/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/kyra/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/m4/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/m4/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/m4/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/made/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/actor_path.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/actor_walk.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/image.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/isomap.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/sci/engine/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/scumm/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/scumm/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/scumm/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/sword2/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/teenagent/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-# TODO: Fingolfin says: optimizing kyra/staticres.o for size would
-# save about 30k, so maybe consider that?
-#engines/kyra/staticres.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-
-
-
-#############################################################################
-#
-# ARM9 rules.
-#
-#############################################################################
-
 all: scummvm.nds
 
 clean: dsclean
@@ -101,7 +38,7 @@ dsclean:
 # TODO: Add a 'dsdist' target ?
 
 %.nds: %.elf romfs
-	ndstool -c $@ -9 $< -b $(srcdir)/$(ndsdir)/logo.bmp "$(@F);ScummVM $(VERSION);DS Port" -d romfs
+	ndstool -c $@ -9 $< -b $(srcdir)/backends/platform/ds/logo.bmp "$(@F);ScummVM $(VERSION);DS Port" -d romfs
 
 romfs: $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(PLUGINS)
 	@rm -rf romfs
diff --git a/configure b/configure
index 62421d6728..2b7251293e 100755
--- a/configure
+++ b/configure
@@ -2985,6 +2985,7 @@ EOF
 		append_var DEFINES "-DNONSTANDARD_PORT"
 		;;
 	ds)
+		_optimization_level=-Os
 		append_var DEFINES "-D__DS__"
 		append_var DEFINES "-DNDS"
 		append_var DEFINES "-DARM9"
@@ -2996,6 +2997,7 @@ EOF
 		append_var CXXFLAGS "-march=armv5te"
 		append_var CXXFLAGS "-mtune=arm946e-s"
 		append_var CXXFLAGS "-fomit-frame-pointer"
+		append_var CXXFLAGS "-mthumb"
 		append_var CXXFLAGS "-mthumb-interwork"
 		append_var CXXFLAGS "-ffunction-sections"
 		append_var CXXFLAGS "-fdata-sections"


Commit: 1c40d79732dbb1f2eb35f11540433292bc102bc6
    https://github.com/scummvm/scummvm/commit/1c40d79732dbb1f2eb35f11540433292bc102bc6
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Begin modularizing the DS backend

Changed paths:
    backends/mixer/maxmod/maxmod-mixer.cpp
    backends/mixer/maxmod/maxmod-mixer.h
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/mixer/maxmod/maxmod-mixer.cpp b/backends/mixer/maxmod/maxmod-mixer.cpp
index b252d78b7c..161274c75a 100644
--- a/backends/mixer/maxmod/maxmod-mixer.cpp
+++ b/backends/mixer/maxmod/maxmod-mixer.cpp
@@ -36,7 +36,6 @@
 
 MaxModMixerManager::MaxModMixerManager(int freq, int bufSize)
 	:
-	_mixer(0),
 	_freq(freq),
 	_bufSize(bufSize) {
 
@@ -66,17 +65,30 @@ void MaxModMixerManager::init() {
 	sys.fifo_channel		= FIFO_MAXMOD;
 	mmInit( &sys );
 
-	mm_stream mystream;
-	mystream.sampling_rate = _freq;
-	mystream.buffer_length = _bufSize / 4;
-	mystream.callback = on_stream_request;
-	mystream.format = MM_STREAM_16BIT_STEREO;
-	mystream.timer = MM_TIMER2;
-	mystream.manual = 0;
+	_stream.sampling_rate = _freq;
+	_stream.buffer_length = _bufSize / 4;
+	_stream.callback = on_stream_request;
+	_stream.format = MM_STREAM_16BIT_STEREO;
+	_stream.timer = MM_TIMER2;
+	_stream.manual = 0;
 
-	mmStreamOpen( &mystream );
+	mmStreamOpen( &_stream );
 
 	_mixer->setReady(true);
 }
 
+void MaxModMixerManager::suspendAudio() {
+	mmStreamClose();
+	_audioSuspended = true;
+}
+
+int MaxModMixerManager::resumeAudio() {
+	if (!_audioSuspended)
+		return -2;
+
+	mmStreamOpen( &_stream );
+	_audioSuspended = false;
+	return 0;
+}
+
 #endif
diff --git a/backends/mixer/maxmod/maxmod-mixer.h b/backends/mixer/maxmod/maxmod-mixer.h
index 45d4e95f55..774a007a01 100644
--- a/backends/mixer/maxmod/maxmod-mixer.h
+++ b/backends/mixer/maxmod/maxmod-mixer.h
@@ -23,14 +23,16 @@
 #ifndef BACKENDS_MIXER_MAXMOD_H
 #define BACKENDS_MIXER_MAXMOD_H
 
-#include "audio/mixer_intern.h"
+#include "backends/mixer/mixer.h"
+
+#include <mm_types.h>
 
 /**
  * MaxMod mixer manager. It wraps the actual implementation
  * of the Audio:Mixer used by the engine, and sets up
  * MaxMod and the callback for the audio mixer implementation.
  */
-class MaxModMixerManager {
+class MaxModMixerManager : public MixerManager {
 public:
 	MaxModMixerManager(int freq, int bufSize);
 	virtual ~MaxModMixerManager();
@@ -41,14 +43,17 @@ public:
 	virtual void init();
 
 	/**
-	 * Get the audio mixer implementation
+	 * Pauses the audio system
 	 */
-	Audio::Mixer *getMixer() { return (Audio::Mixer *)_mixer; }
+	virtual void suspendAudio();
 
-protected:
-	/** The mixer implementation */
-	Audio::MixerImpl *_mixer;
+	/**
+	 * Resumes the audio system
+	 */
+	virtual int resumeAudio();
 
+protected:
+	mm_stream _stream;
 	int _freq, _bufSize;
 };
 
diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index b6a56aa32c..92b98c4575 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -49,6 +49,8 @@
 
 #include "backends/audiocd/default/default-audiocd.h"
 #include "backends/events/default/default-events.h"
+#include "backends/mixer/maxmod/maxmod-mixer.h"
+#include "backends/mutex/null/null-mutex.h"
 #include "backends/saves/default/default-saves.h"
 #include "backends/timer/default/default-timer.h"
 
@@ -57,7 +59,7 @@
 OSystem_DS *OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
-	: _eventSource(NULL), _mixerManager(NULL), _isOverlayShown(true),
+	: _eventSource(NULL), _isOverlayShown(true),
 	_graphicsMode(GFX_HWSCALE), _stretchMode(100),
 	_disableCursorPalette(true), _graphicsEnable(true),
 	_callbackTimer(10), _currentTimeMillis(0)
@@ -66,11 +68,10 @@ OSystem_DS::OSystem_DS()
 
 	nitroFSInit(NULL);
 	_fsFactory = new DevoptabFilesystemFactory();
+	_mutexManager = new NullMutexManager();
 }
 
 OSystem_DS::~OSystem_DS() {
-	delete _mixerManager;
-	_mixerManager = 0;
 }
 
 void timerTickHandler() {
@@ -441,19 +442,6 @@ void OSystem_DS::getTimeAndDate(TimeDate &td) const {
 	td.tm_wday = t.tm_wday;
 }
 
-OSystem::MutexRef OSystem_DS::createMutex(void) {
-	return NULL;
-}
-
-void OSystem_DS::lockMutex(MutexRef mutex) {
-}
-
-void OSystem_DS::unlockMutex(MutexRef mutex) {
-}
-
-void OSystem_DS::deleteMutex(MutexRef mutex) {
-}
-
 void OSystem_DS::quit() {
 }
 
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index 47c5b0e757..af24f3fb51 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -24,9 +24,9 @@
 #ifndef _OSYSTEM_DS_H_
 #define _OSYSTEM_DS_H_
 
-#include "backends/base-backend.h"
+#include "backends/modular-backend.h"
 #include "backends/events/ds/ds-events.h"
-#include "backends/mixer/maxmod/maxmod-mixer.h"
+#include "backends/mixer/mixer.h"
 #include "graphics/surface.h"
 #include "graphics/palette.h"
 
@@ -36,9 +36,8 @@ enum {
 	GFX_SWSCALE = 2
 };
 
-class OSystem_DS : public BaseBackend, public PaletteManager {
+class OSystem_DS : public ModularMutexBackend, public ModularMixerBackend, public PaletteManager {
 protected:
-	MaxModMixerManager *_mixerManager;
 	Graphics::Surface _framebuffer, _overlay, _cursor;
 	bool _graphicsEnable, _isOverlayShown;
 	int _graphicsMode, _stretchMode;
@@ -123,11 +122,6 @@ public:
 
 	virtual Common::String getSystemLanguage() const;
 
-	virtual MutexRef createMutex(void);
-	virtual void lockMutex(MutexRef mutex);
-	virtual void unlockMutex(MutexRef mutex);
-	virtual void deleteMutex(MutexRef mutex);
-
 	virtual void quit();
 
 	virtual void setFocusRectangle(const Common::Rect& rect);
@@ -141,8 +135,6 @@ public:
 	virtual Graphics::Surface *lockScreen();
 	virtual void unlockScreen();
 
-	virtual Audio::Mixer *getMixer() { return _mixerManager->getMixer(); }
-
 	virtual void setCursorPalette(const byte *colors, uint start, uint num);
 
 	void refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette);


Commit: 626b6ac4e9442cca423fa8d78e5a5b59278a9247
    https://github.com/scummvm/scummvm/commit/626b6ac4e9442cca423fa8d78e5a5b59278a9247
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Move graphics code into a separate file

Changed paths:
  A backends/platform/ds/ds-graphics.cpp
    backends/events/ds/ds-events.cpp
    backends/platform/ds/dsmain.cpp
    backends/platform/ds/dsmain.h
    backends/platform/ds/module.mk
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/events/ds/ds-events.cpp b/backends/events/ds/ds-events.cpp
index f7652dc215..d1ec31aa04 100644
--- a/backends/events/ds/ds-events.cpp
+++ b/backends/events/ds/ds-events.cpp
@@ -23,7 +23,7 @@
 #include <nds.h>
 
 #include "backends/events/ds/ds-events.h"
-#include "osystem_ds.h"
+#include "backends/platform/ds/osystem_ds.h"
 
 bool DSEventSource::pollEvent(Common::Event &event) {
 	if (_eventQueue.empty()) {
diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
new file mode 100644
index 0000000000..39737722fe
--- /dev/null
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -0,0 +1,653 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <nds.h>
+
+#include "backends/platform/ds/osystem_ds.h"
+#include "backends/platform/ds/blitters.h"
+
+#include "common/translation.h"
+
+namespace DS {
+
+// From console.c in NDSLib
+
+// Defines
+#define SCUMM_GAME_HEIGHT 142
+#define SCUMM_GAME_WIDTH 227
+
+// Scaled
+static int scX;
+static int scY;
+
+static int subScX;
+static int subScY;
+static int subScTargetX;
+static int subScTargetY;
+static int subScreenWidth = SCUMM_GAME_WIDTH;
+static int subScreenHeight = SCUMM_GAME_HEIGHT;
+static int subScreenScale = 256;
+
+static bool gameScreenSwap = false;
+
+// Shake
+static int s_shakeXOffset = 0;
+static int s_shakeYOffset = 0;
+
+// Touch
+static int touchScX, touchScY, touchX, touchY;
+
+// 8-bit surface size
+static int gameWidth = 320;
+static int gameHeight = 200;
+
+void setGameScreenSwap(bool enable) {
+	gameScreenSwap = enable;
+}
+
+void setTopScreenZoom(int percentage) {
+	s32 scale = (percentage << 8) / 100;
+	subScreenScale = (256 * 256) / scale;
+}
+
+void setTopScreenTarget(int x, int y) {
+	subScTargetX = (x - (subScreenWidth >> 1));
+	subScTargetY = (y - (subScreenHeight >> 1));
+
+	if (subScTargetX < 0) subScTargetX = 0;
+	if (subScTargetX > gameWidth - subScreenWidth) subScTargetX = gameWidth - subScreenWidth;
+
+	if (subScTargetY < 0) subScTargetY = 0;
+	if (subScTargetY > gameHeight - subScreenHeight) subScTargetY = gameHeight - subScreenHeight;
+
+	subScTargetX <<=8;
+	subScTargetY <<=8;
+}
+
+void setGameSize(int width, int height) {
+	gameWidth = width;
+	gameHeight = height;
+}
+
+int getGameWidth() {
+	return gameWidth;
+}
+
+int getGameHeight() {
+	return gameHeight;
+}
+
+void displayMode8Bit() {
+	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
+
+	if (g_system->getGraphicsMode() == GFX_SWSCALE) {
+		REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
+
+		REG_BG3PA = 256;
+		REG_BG3PB = 0;
+		REG_BG3PC = 0;
+		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
+
+	} else {
+		REG_BG3CNT = BG_BMP8_512x256 | BG_BMP_BASE(8);
+
+		REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
+		REG_BG3PB = 0;
+		REG_BG3PC = 0;
+		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
+	}
+
+#ifdef DISABLE_TEXT_CONSOLE
+	REG_BG3CNT_SUB = BG_BMP8_512x256;
+
+	REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
+	REG_BG3PB_SUB = 0;
+	REG_BG3PC_SUB = 0;
+	REG_BG3PD_SUB = (int) (subScreenHeight / 192.0f * 256);
+#endif
+
+	if (gameScreenSwap) {
+		lcdMainOnTop();
+	} else {
+		lcdMainOnBottom();
+	}
+}
+
+void setShakePos(int shakeXOffset, int shakeYOffset) {
+	s_shakeXOffset = shakeXOffset;
+	s_shakeYOffset = shakeYOffset;
+}
+
+Common::Point warpMouse(int penX, int penY, bool isOverlayShown) {
+	int storedMouseX, storedMouseY;
+	if (!isOverlayShown) {
+		storedMouseX = ((penX - touchX) << 8) / touchScX;
+		storedMouseY = ((penY - touchY) << 8) / touchScY;
+	} else {
+		storedMouseX = penX;
+		storedMouseY = penY;
+	}
+
+	return Common::Point(storedMouseX, storedMouseY);
+}
+
+void setMainScreenScroll(int x, int y) {
+		REG_BG3X = x;
+		REG_BG3Y = y;
+
+		if (!gameScreenSwap) {
+			touchX = x >> 8;
+			touchY = y >> 8;
+		}
+}
+
+void setMainScreenScale(int x, int y) {
+		if ((g_system->getGraphicsMode() == GFX_SWSCALE) && (x==320)) {
+			REG_BG3PA = 256;
+			REG_BG3PB = 0;
+			REG_BG3PC = 0;
+			REG_BG3PD = y;
+		} else {
+			REG_BG3PA = x;
+			REG_BG3PB = 0;
+			REG_BG3PC = 0;
+			REG_BG3PD = y;
+		}
+
+		if (!gameScreenSwap) {
+			touchScX = x;
+			touchScY = y;
+		}
+}
+
+void setZoomedScreenScroll(int x, int y, bool shake) {
+		if (gameScreenSwap) {
+			touchX = x >> 8;
+			touchY = y >> 8;
+		}
+
+#ifdef DISABLE_TEXT_CONSOLE
+		REG_BG3X_SUB = x;
+		REG_BG3Y_SUB = y;
+#endif
+}
+
+void setZoomedScreenScale(int x, int y) {
+		if (gameScreenSwap) {
+			touchScX = x;
+			touchScY = y;
+		}
+
+#ifdef DISABLE_TEXT_CONSOLE
+		REG_BG3PA_SUB = x;
+		REG_BG3PB_SUB = 0;
+		REG_BG3PC_SUB = 0;
+		REG_BG3PD_SUB = y;
+#endif
+}
+
+Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown) {
+	if (!isOverlayShown) {
+		x = ((x * touchScX) >> 8) + touchX;
+		x = CLIP<uint16>(x, 0, gameWidth  - 1);
+
+		y = ((y * touchScY) >> 8) + touchY;
+		y = CLIP<uint16>(y, 0, gameHeight - 1);
+	}
+
+	return Common::Point(x, y);
+}
+
+void VBlankHandler(void) {
+	int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
+	int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
+
+	subScreenWidth = (256 * subScreenScale) >> 8;
+	subScreenHeight = (192 * subScreenScale) >> 8;
+
+	if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
+		subScreenWidth = 256;
+		subScreenHeight = 192;
+	} else if ( ((subScreenWidth) > 128 - 8) && ((subScreenWidth) < 128 + 8) ) {
+		subScreenWidth = 128;
+		subScreenHeight = 96;
+	} else if (subScreenWidth > 256) {
+		subScreenWidth = 320;
+		subScreenHeight = 200;
+	}
+
+	subScTargetX = xCenter - ((subScreenWidth  >> 1) << 8);
+	subScTargetY = yCenter - ((subScreenHeight >> 1) << 8);
+
+	subScTargetX = CLIP(subScTargetX, 0, (gameWidth  - subScreenWidth)  << 8);
+	subScTargetY = CLIP(subScTargetY, 0, (gameHeight - subScreenHeight) << 8);
+
+	subScX += (subScTargetX - subScX) >> 2;
+	subScY += (subScTargetY - subScY) >> 2;
+
+	if (g_system->getGraphicsMode() == GFX_NOSCALE) {
+		if (scX + 256 > gameWidth - 1) {
+			scX = gameWidth - 1 - 256;
+		}
+
+		if (scX < 0) {
+			scX = 0;
+		}
+
+		if (scY + 192 > gameHeight - 1) {
+			scY = gameHeight - 1 - 192;
+		}
+
+		if (scY < 0) {
+			scY = 0;
+		}
+
+		setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
+		setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
+
+		setMainScreenScroll((scX << 8) + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
+		setMainScreenScale(256, 256);		// 1:1 scale
+	} else {
+		if (scY > gameHeight - 192 - 1) {
+			scY = gameHeight - 192 - 1;
+		}
+
+		if (scY < 0) {
+			scY = 0;
+		}
+
+		setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
+		setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
+
+		setMainScreenScroll(64 + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
+		setMainScreenScale(320, 256);		// 1:1 scale
+	}
+}
+
+void setTalkPos(int x, int y) {
+	setTopScreenTarget(x, y);
+}
+
+void initHardware() {
+	powerOn(POWER_ALL);
+
+	for (int r = 0; r < 255; r++) {
+		BG_PALETTE[r] = 0;
+	}
+
+	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
+	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
+	vramSetBankE(VRAM_E_MAIN_SPRITE);
+
+	REG_BG2CNT = BG_BMP16_256x256;
+	REG_BG2PA = 256;
+	REG_BG2PB = 0;
+	REG_BG2PC = 0;
+	REG_BG2PD = 256;
+
+	scX = 0;
+	scY = 0;
+	subScX = 0;
+	subScY = 0;
+	subScTargetX = 0;
+	subScTargetY = 0;
+
+	lcdMainOnBottom();
+
+	//irqs are nice
+	irqSet(IRQ_VBLANK, VBlankHandler);
+	irqEnable(IRQ_VBLANK);
+
+#ifndef DISABLE_TEXT_CONSOLE
+	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
+	vramSetBankH(VRAM_H_SUB_BG);
+	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 15, 0, false, true);
+#else
+	videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE);
+	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
+#endif
+}
+
+}
+
+void OSystem_DS::initGraphics() {
+	DS::initHardware();
+
+	oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
+	_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
+
+	_overlay.create(256, 192, Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15));
+}
+
+bool OSystem_DS::hasFeature(Feature f) {
+	return (f == kFeatureCursorPalette) || (f == kFeatureStretchMode);
+}
+
+void OSystem_DS::setFeatureState(Feature f, bool enable) {
+	if (f == kFeatureCursorPalette) {
+		_disableCursorPalette = !enable;
+		refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
+	}
+}
+
+bool OSystem_DS::getFeatureState(Feature f) {
+	if (f == kFeatureCursorPalette)
+		return !_disableCursorPalette;
+	return false;
+}
+
+static const OSystem::GraphicsMode graphicsModes[] = {
+	{ "NONE",  _s("Unscaled"),                                  GFX_NOSCALE },
+	{ "HW",    _s("Hardware scale (fast, but low quality)"),    GFX_HWSCALE },
+	{ "SW",    _s("Software scale (good quality, but slower)"), GFX_SWSCALE },
+	{ nullptr, nullptr,                                         0           }
+};
+
+const OSystem::GraphicsMode *OSystem_DS::getSupportedGraphicsModes() const {
+	return graphicsModes;
+}
+
+int OSystem_DS::getDefaultGraphicsMode() const {
+	return GFX_HWSCALE;
+}
+
+bool OSystem_DS::setGraphicsMode(int mode) {
+	switch (mode) {
+	case GFX_NOSCALE:
+	case GFX_HWSCALE:
+	case GFX_SWSCALE:
+		_graphicsMode = mode;
+		return true;
+	default:
+		return false;
+	}
+}
+
+int OSystem_DS::getGraphicsMode() const {
+	return _graphicsMode;
+}
+
+static const OSystem::GraphicsMode stretchModes[] = {
+	{ "100",   "100%",  100 },
+	{ "150",   "150%",  150 },
+	{ "200",   "200%",  200 },
+	{ nullptr, nullptr, 0   }
+};
+
+const OSystem::GraphicsMode *OSystem_DS::getSupportedStretchModes() const {
+	return stretchModes;
+}
+
+int OSystem_DS::getDefaultStretchMode() const {
+	return 100;
+}
+
+bool OSystem_DS::setStretchMode(int mode) {
+	_stretchMode = mode;
+	DS::setTopScreenZoom(mode);
+	return true;
+}
+
+int OSystem_DS::getStretchMode() const {
+	return _stretchMode;
+}
+
+void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
+	_framebuffer.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+	// For Lost in Time, the title screen is displayed in 640x400.
+	// In order to support this game, the screen mode is set, but
+	// all draw calls are ignored until the game switches to 320x200.
+	if ((width == 640) && (height == 400)) {
+		_graphicsEnable = false;
+	} else {
+		_graphicsEnable = true;
+		DS::setGameSize(width, height);
+	}
+}
+
+int16 OSystem_DS::getHeight() {
+	return _framebuffer.h;
+}
+
+int16 OSystem_DS::getWidth() {
+	return _framebuffer.w;
+}
+
+void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
+	for (unsigned int r = start; r < start + num; r++) {
+		int red = *colors;
+		int green = *(colors + 1);
+		int blue = *(colors + 2);
+
+		red >>= 3;
+		green >>= 3;
+		blue >>= 3;
+
+		{
+			u16 paletteValue = red | (green << 5) | (blue << 10);
+
+			if (!_isOverlayShown) {
+				BG_PALETTE[r] = paletteValue;
+#ifdef DISABLE_TEXT_CONSOLE
+				BG_PALETTE_SUB[r] = paletteValue;
+#endif
+			}
+
+			_palette[r] = paletteValue;
+		}
+
+		colors += 3;
+	}
+}
+
+void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
+
+	for (unsigned int r = start; r < start + num; r++) {
+		int red = *colors;
+		int green = *(colors + 1);
+		int blue = *(colors + 2);
+
+		red >>= 3;
+		green >>= 3;
+		blue >>= 3;
+
+		u16 paletteValue = red | (green << 5) | (blue << 10);
+		_cursorPalette[r] = paletteValue;
+
+		colors += 3;
+	}
+
+	_disableCursorPalette = false;
+	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
+}
+
+void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) const {
+	for (unsigned int r = start; r < start + num; r++) {
+		*colors++ = (BG_PALETTE[r] & 0x001F) << 3;
+		*colors++ = (BG_PALETTE[r] & 0x03E0) >> 5 << 3;
+		*colors++ = (BG_PALETTE[r] & 0x7C00) >> 10 << 3;
+	}
+}
+
+void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
+	_framebuffer.copyRectToSurface(buf, pitch, x, y, w, h);
+}
+
+void OSystem_DS::updateScreen() {
+	oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
+	       SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
+	oamUpdate(&oamMain);
+
+	if (_isOverlayShown) {
+		u16 *back = (u16 *)_overlay.getPixels();
+		dmaCopyHalfWords(3, back, BG_GFX, 256 * 192 * 2);
+	} else if (!_graphicsEnable) {
+		return;
+	} else if (_graphicsMode == GFX_SWSCALE) {
+		u16 *base = BG_GFX + 0x10000;
+		Rescale_320x256xPAL8_To_256x256x1555(
+			base,
+			(const u8 *)_framebuffer.getPixels(),
+			256,
+			_framebuffer.pitch,
+			BG_PALETTE,
+			_framebuffer.h );
+	} else {
+		// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
+		// to save a few pennies/euro cents on the hardware.
+
+		u16 *bg = BG_GFX + 0x10000;
+		s32 stride = 512;
+
+		u16 *src = (u16 *)_framebuffer.getPixels();
+
+		for (int dy = 0; dy < _framebuffer.h; dy++) {
+			DC_FlushRange(src, _framebuffer.w << 1);
+
+			u16 *dest1 = bg + (dy * (stride >> 1));
+			DC_FlushRange(dest1, _framebuffer.w << 1);
+
+#ifdef DISABLE_TEXT_CONSOLE
+			u16 *dest2 = (u16 *)BG_GFX_SUB + (dy << 8);
+			DC_FlushRange(dest2, _framebuffer.w << 1);
+
+			dmaCopyHalfWordsAsynch(2, src, dest2, _framebuffer.w);
+#endif
+			dmaCopyHalfWordsAsynch(3, src, dest1, _framebuffer.w);
+
+			while (dmaBusy(2) || dmaBusy(3));
+
+			src += _framebuffer.pitch >> 1;
+		}
+	}
+}
+
+void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
+	DS::setShakePos(shakeXOffset, shakeYOffset);
+}
+
+void OSystem_DS::showOverlay() {
+	dmaFillHalfWords(0, BG_GFX, 256 * 192 * 2);
+	videoBgEnable(2);
+	lcdMainOnBottom();
+	_isOverlayShown = true;
+}
+
+void OSystem_DS::hideOverlay() {
+	videoBgDisable(2);
+	DS::displayMode8Bit();
+	_isOverlayShown = false;
+}
+
+bool OSystem_DS::isOverlayVisible() const {
+	return _isOverlayShown;
+}
+
+void OSystem_DS::clearOverlay() {
+	memset(_overlay.getPixels(), 0, _overlay.pitch * _overlay.h);
+}
+
+void OSystem_DS::grabOverlay(void *buf, int pitch) {
+	byte *dst = (byte *)buf;
+
+	for (int y = 0; y < _overlay.h; ++y) {
+		memcpy(dst, _overlay.getBasePtr(0, y), _overlay.w * _overlay.format.bytesPerPixel);
+		dst += pitch;
+	}
+}
+
+void OSystem_DS::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
+	_overlay.copyRectToSurface(buf, pitch, x, y, w, h);
+}
+
+int16 OSystem_DS::getOverlayHeight() {
+	return _overlay.h;
+}
+
+int16 OSystem_DS::getOverlayWidth() {
+	return _overlay.w;
+}
+
+Graphics::PixelFormat OSystem_DS::getOverlayFormat() const {
+	return _overlay.format;
+}
+
+Common::Point OSystem_DS::transformPoint(uint16 x, uint16 y) {
+	return DS::transformPoint(x, y, _isOverlayShown);
+}
+
+bool OSystem_DS::showMouse(bool visible) {
+	const bool last = _cursorVisible;
+	_cursorVisible = visible;
+	return last;
+}
+
+void OSystem_DS::warpMouse(int x, int y) {
+	_cursorPos = DS::warpMouse(x, y, _isOverlayShown);
+}
+
+void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
+	if (!buf || w == 0 || h == 0 || (format && *format != Graphics::PixelFormat::createFormatCLUT8()))
+		return;
+
+	if (_cursor.w != w || _cursor.h != h)
+		_cursor.create(w, h, Graphics::PixelFormat::createFormatCLUT8());
+	_cursor.copyRectToSurface(buf, w, 0, 0, w, h);
+	_cursorHotX = hotspotX;
+	_cursorHotY = hotspotY;
+	_cursorKey = keycolor;
+	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
+}
+
+void OSystem_DS::refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette) {
+	uint w = MIN<uint>(src.w, 64);
+	uint h = MIN<uint>(src.h, 64);
+
+	dmaFillHalfWords(0, dst, 64 * 64 * 2);
+
+	for (uint y = 0; y < h; y++) {
+		const uint8 *row = (const uint8 *)src.getBasePtr(0, y);
+		for (uint x = 0; x < w; x++) {
+			uint8 color = *row++;
+
+			if (color != _cursorKey)
+				dst[y * 64 + x] = palette[color] | 0x8000;
+		}
+	}
+}
+
+Graphics::Surface *OSystem_DS::lockScreen() {
+	return &_framebuffer;
+}
+
+void OSystem_DS::unlockScreen() {
+	// No need to do anything here.  The screen will be updated in updateScreen().
+}
+
+void OSystem_DS::setFocusRectangle(const Common::Rect& rect) {
+	DS::setTalkPos(rect.left + rect.width() / 2, rect.top + rect.height() / 2);
+}
+
+void OSystem_DS::clearFocusRectangle() {
+
+}
diff --git a/backends/platform/ds/dsmain.cpp b/backends/platform/ds/dsmain.cpp
index 916a3b0267..98fd519d03 100644
--- a/backends/platform/ds/dsmain.cpp
+++ b/backends/platform/ds/dsmain.cpp
@@ -65,327 +65,12 @@
 // - Memory size for ite
 // - Try discworld?
 
-
-// Allow use of stuff in <nds.h>
-#define FORBIDDEN_SYMBOL_EXCEPTION_printf
-#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
-
-
-#include <nds.h>
-#include <filesystem.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "dsmain.h"
-#include "osystem_ds.h"
-#include "engines/engine.h"
-
+#include "backends/platform/ds/osystem_ds.h"
 #include "backends/plugins/ds/ds-provider.h"
 #include "base/main.h"
-#include "base/version.h"
-#include "common/util.h"
 
 namespace DS {
 
-// From console.c in NDSLib
-
-// Defines
-#define SCUMM_GAME_HEIGHT 142
-#define SCUMM_GAME_WIDTH 227
-
-// Scaled
-static int scX;
-static int scY;
-
-static int subScX;
-static int subScY;
-static int subScTargetX;
-static int subScTargetY;
-static int subScreenWidth = SCUMM_GAME_WIDTH;
-static int subScreenHeight = SCUMM_GAME_HEIGHT;
-static int subScreenScale = 256;
-
-static bool gameScreenSwap = false;
-
-// Shake
-static int s_shakeXOffset = 0;
-static int s_shakeYOffset = 0;
-
-// Touch
-static int touchScX, touchScY, touchX, touchY;
-
-// 8-bit surface size
-static int gameWidth = 320;
-static int gameHeight = 200;
-
-void setGameScreenSwap(bool enable) {
-	gameScreenSwap = enable;
-}
-
-void setTopScreenZoom(int percentage) {
-	s32 scale = (percentage << 8) / 100;
-	subScreenScale = (256 * 256) / scale;
-}
-
-void setGameSize(int width, int height) {
-	gameWidth = width;
-	gameHeight = height;
-}
-
-int getGameWidth() {
-	return gameWidth;
-}
-
-int getGameHeight() {
-	return gameHeight;
-}
-
-void displayMode8Bit() {
-	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
-
-	if (g_system->getGraphicsMode() == GFX_SWSCALE) {
-		REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
-
-		REG_BG3PA = 256;
-		REG_BG3PB = 0;
-		REG_BG3PC = 0;
-		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
-
-	} else {
-		REG_BG3CNT = BG_BMP8_512x256 | BG_BMP_BASE(8);
-
-		REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
-		REG_BG3PB = 0;
-		REG_BG3PC = 0;
-		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
-	}
-
-#ifdef DISABLE_TEXT_CONSOLE
-	REG_BG3CNT_SUB = BG_BMP8_512x256;
-
-	REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
-	REG_BG3PB_SUB = 0;
-	REG_BG3PC_SUB = 0;
-	REG_BG3PD_SUB = (int) (subScreenHeight / 192.0f * 256);
-#endif
-
-	if (gameScreenSwap) {
-		lcdMainOnTop();
-	} else {
-		lcdMainOnBottom();
-	}
-}
-
-void setShakePos(int shakeXOffset, int shakeYOffset) {
-	s_shakeXOffset = shakeXOffset;
-	s_shakeYOffset = shakeYOffset;
-}
-
-Common::Point warpMouse(int penX, int penY, bool isOverlayShown) {
-	int storedMouseX, storedMouseY;
-	if (!isOverlayShown) {
-		storedMouseX = ((penX - touchX) << 8) / touchScX;
-		storedMouseY = ((penY - touchY) << 8) / touchScY;
-	} else {
-		storedMouseX = penX;
-		storedMouseY = penY;
-	}
-
-	return Common::Point(storedMouseX, storedMouseY);
-}
-
-void setMainScreenScroll(int x, int y) {
-		REG_BG3X = x;
-		REG_BG3Y = y;
-
-		if (!gameScreenSwap) {
-			touchX = x >> 8;
-			touchY = y >> 8;
-		}
-}
-
-void setMainScreenScale(int x, int y) {
-		if ((g_system->getGraphicsMode() == GFX_SWSCALE) && (x==320)) {
-			REG_BG3PA = 256;
-			REG_BG3PB = 0;
-			REG_BG3PC = 0;
-			REG_BG3PD = y;
-		} else {
-			REG_BG3PA = x;
-			REG_BG3PB = 0;
-			REG_BG3PC = 0;
-			REG_BG3PD = y;
-		}
-
-		if (!gameScreenSwap) {
-			touchScX = x;
-			touchScY = y;
-		}
-}
-
-void setZoomedScreenScroll(int x, int y, bool shake) {
-		if (gameScreenSwap) {
-			touchX = x >> 8;
-			touchY = y >> 8;
-		}
-
-#ifdef DISABLE_TEXT_CONSOLE
-		REG_BG3X_SUB = x;
-		REG_BG3Y_SUB = y;
-#endif
-}
-
-void setZoomedScreenScale(int x, int y) {
-		if (gameScreenSwap) {
-			touchScX = x;
-			touchScY = y;
-		}
-
-#ifdef DISABLE_TEXT_CONSOLE
-		REG_BG3PA_SUB = x;
-		REG_BG3PB_SUB = 0;
-		REG_BG3PC_SUB = 0;
-		REG_BG3PD_SUB = y;
-#endif
-}
-
-Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown) {
-	if (!isOverlayShown) {
-		x = ((x * touchScX) >> 8) + touchX;
-		x = CLIP<uint16>(x, 0, gameWidth  - 1);
-
-		y = ((y * touchScY) >> 8) + touchY;
-		y = CLIP<uint16>(y, 0, gameHeight - 1);
-	}
-
-	return Common::Point(x, y);
-}
-
-void VBlankHandler(void) {
-	int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
-	int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
-
-	subScreenWidth = (256 * subScreenScale) >> 8;
-	subScreenHeight = (192 * subScreenScale) >> 8;
-
-	if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
-		subScreenWidth = 256;
-		subScreenHeight = 192;
-	} else if ( ((subScreenWidth) > 128 - 8) && ((subScreenWidth) < 128 + 8) ) {
-		subScreenWidth = 128;
-		subScreenHeight = 96;
-	} else if (subScreenWidth > 256) {
-		subScreenWidth = 320;
-		subScreenHeight = 200;
-	}
-
-	subScTargetX = xCenter - ((subScreenWidth  >> 1) << 8);
-	subScTargetY = yCenter - ((subScreenHeight >> 1) << 8);
-
-	subScTargetX = CLIP(subScTargetX, 0, (gameWidth  - subScreenWidth)  << 8);
-	subScTargetY = CLIP(subScTargetY, 0, (gameHeight - subScreenHeight) << 8);
-
-	subScX += (subScTargetX - subScX) >> 2;
-	subScY += (subScTargetY - subScY) >> 2;
-
-	if (g_system->getGraphicsMode() == GFX_NOSCALE) {
-		if (scX + 256 > gameWidth - 1) {
-			scX = gameWidth - 1 - 256;
-		}
-
-		if (scX < 0) {
-			scX = 0;
-		}
-
-		if (scY + 192 > gameHeight - 1) {
-			scY = gameHeight - 1 - 192;
-		}
-
-		if (scY < 0) {
-			scY = 0;
-		}
-
-		setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
-		setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
-
-		setMainScreenScroll((scX << 8) + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
-		setMainScreenScale(256, 256);		// 1:1 scale
-	} else {
-		if (scY > gameHeight - 192 - 1) {
-			scY = gameHeight - 192 - 1;
-		}
-
-		if (scY < 0) {
-			scY = 0;
-		}
-
-		setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
-		setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
-
-		setMainScreenScroll(64 + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
-		setMainScreenScale(320, 256);		// 1:1 scale
-	}
-}
-
-void setTalkPos(int x, int y) {
-	setTopScreenTarget(x, y);
-}
-
-void setTopScreenTarget(int x, int y) {
-	subScTargetX = (x - (subScreenWidth >> 1));
-	subScTargetY = (y - (subScreenHeight >> 1));
-
-	if (subScTargetX < 0) subScTargetX = 0;
-	if (subScTargetX > gameWidth - subScreenWidth) subScTargetX = gameWidth - subScreenWidth;
-
-	if (subScTargetY < 0) subScTargetY = 0;
-	if (subScTargetY > gameHeight - subScreenHeight) subScTargetY = gameHeight - subScreenHeight;
-
-	subScTargetX <<=8;
-	subScTargetY <<=8;
-}
-
-void initHardware() {
-	powerOn(POWER_ALL);
-
-	for (int r = 0; r < 255; r++) {
-		BG_PALETTE[r] = 0;
-	}
-
-	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
-	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
-	vramSetBankE(VRAM_E_MAIN_SPRITE);
-
-	REG_BG2CNT = BG_BMP16_256x256;
-	REG_BG2PA = 256;
-	REG_BG2PB = 0;
-	REG_BG2PC = 0;
-	REG_BG2PD = 256;
-
-	scX = 0;
-	scY = 0;
-	subScX = 0;
-	subScY = 0;
-	subScTargetX = 0;
-	subScTargetY = 0;
-
-	lcdMainOnBottom();
-
-	//irqs are nice
-	irqSet(IRQ_VBLANK, VBlankHandler);
-	irqEnable(IRQ_VBLANK);
-
-#ifndef DISABLE_TEXT_CONSOLE
-	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
-	vramSetBankH(VRAM_H_SUB_BG);
-	consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 15, 0, false, true);
-#else
-	videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE);
-	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
-#endif
-}
-
 ///////////////////
 // Fast Ram
 ///////////////////
diff --git a/backends/platform/ds/dsmain.h b/backends/platform/ds/dsmain.h
index be41e54c1a..a4f7637952 100644
--- a/backends/platform/ds/dsmain.h
+++ b/backends/platform/ds/dsmain.h
@@ -23,51 +23,14 @@
 #ifndef _DSMAIN_H
 #define _DSMAIN_H
 
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
-#include <nds.h>
-#include "osystem_ds.h"
+#include "common/scummsys.h"
 
 namespace DS {
 
-// Video
-void 	displayMode8Bit();											// Switch to 8-bit mode5
-void 	displayMode16Bit();										// Switch to 16-bit mode5
-
-// Get address of current back buffer
-u16 *	get16BitBackBuffer();
-
-void 	setTalkPos(int x, int y);
-void 	setTopScreenTarget(int x, int y);
-void	setTopScreenZoom(int percentage);
-
-// Events
-void 	VBlankHandler();
-Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown);
-Common::Point warpMouse(int penX, int penY, bool isOverlayShown);
-
-// Shake
-void 	setShakePos(int shakeXOffset, int shakeYOffset);
-
-// Options
-void	setGameScreenSwap(bool enable);
-
-// Display
-bool 	getIsDisplayMode8Bit();
-void 	setGameSize(int width, int height);
-int		getGameWidth();
-int		getGameHeight();
-void 	initHardware();
-
 // Fast RAM allocation (ITCM)
 void	fastRamReset();
 void*	fastRamAlloc(int size);
 
-
 } // End of namespace DS
 
-
-
-int cygprofile_getHBlanks();
-
 #endif
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
index 3541b46a12..3592afbfa4 100644
--- a/backends/platform/ds/module.mk
+++ b/backends/platform/ds/module.mk
@@ -2,6 +2,7 @@ MODULE := backends/platform/ds
 
 MODULE_OBJS := \
 	blitters_arm.o \
+	ds-graphics.o \
 	dsmain.o \
 	osystem_ds.o
 
diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index 92b98c4575..6bca105510 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -20,35 +20,21 @@
  *
  */
 
-
-// Allow use of stuff in <time.h>
 #define FORBIDDEN_SYMBOL_EXCEPTION_time_h
-// Allow use of stuff in <nds.h>
 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
-#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
 
 #include <nds.h>
 #include <filesystem.h>
 
-#include "common/scummsys.h"
-#include "common/system.h"
-
-#include "common/util.h"
-#include "common/rect.h"
-#include "common/savefile.h"
-#include "common/translation.h"
+#include "backends/platform/ds/osystem_ds.h"
 
-#include "osystem_ds.h"
-#include "dsmain.h"
-#include "blitters.h"
 #include "common/config-manager.h"
-#include "common/str.h"
-#include "graphics/surface.h"
-#include "backends/fs/devoptab/devoptab-fs-factory.h"
-#include "backends/keymapper/hardware-input.h"
+#include "common/translation.h"
 
 #include "backends/audiocd/default/default-audiocd.h"
 #include "backends/events/default/default-events.h"
+#include "backends/fs/devoptab/devoptab-fs-factory.h"
+#include "backends/keymapper/hardware-input.h"
 #include "backends/mixer/maxmod/maxmod-mixer.h"
 #include "backends/mutex/null/null-mutex.h"
 #include "backends/saves/default/default-saves.h"
@@ -83,7 +69,7 @@ void timerTickHandler() {
 }
 
 void OSystem_DS::initBackend() {
-	DS::initHardware();
+	initGraphics();
 
 	defaultExceptionHandler();
 
@@ -100,312 +86,9 @@ void OSystem_DS::initBackend() {
 	_mixerManager = new MaxModMixerManager(11025, 4096);
 	_mixerManager->init();
 
-	oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
-	_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
-
-	_overlay.create(256, 192, Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15));
-
 	BaseBackend::initBackend();
 }
 
-bool OSystem_DS::hasFeature(Feature f) {
-	return (f == kFeatureCursorPalette) || (f == kFeatureStretchMode);
-}
-
-void OSystem_DS::setFeatureState(Feature f, bool enable) {
-	if (f == kFeatureCursorPalette) {
-		_disableCursorPalette = !enable;
-		refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
-	}
-}
-
-bool OSystem_DS::getFeatureState(Feature f) {
-	if (f == kFeatureCursorPalette)
-		return !_disableCursorPalette;
-	return false;
-}
-
-static const OSystem::GraphicsMode graphicsModes[] = {
-	{ "NONE",  _s("Unscaled"),                                  GFX_NOSCALE },
-	{ "HW",    _s("Hardware scale (fast, but low quality)"),    GFX_HWSCALE },
-	{ "SW",    _s("Software scale (good quality, but slower)"), GFX_SWSCALE },
-	{ nullptr, nullptr,                                         0           }
-};
-
-const OSystem::GraphicsMode *OSystem_DS::getSupportedGraphicsModes() const {
-	return graphicsModes;
-}
-
-int OSystem_DS::getDefaultGraphicsMode() const {
-	return GFX_HWSCALE;
-}
-
-bool OSystem_DS::setGraphicsMode(int mode) {
-	switch (mode) {
-	case GFX_NOSCALE:
-	case GFX_HWSCALE:
-	case GFX_SWSCALE:
-		_graphicsMode = mode;
-		return true;
-	default:
-		return false;
-	}
-}
-
-int OSystem_DS::getGraphicsMode() const {
-	return _graphicsMode;
-}
-
-static const OSystem::GraphicsMode stretchModes[] = {
-	{ "100",   "100%",  100 },
-	{ "150",   "150%",  150 },
-	{ "200",   "200%",  200 },
-	{ nullptr, nullptr, 0   }
-};
-
-const OSystem::GraphicsMode *OSystem_DS::getSupportedStretchModes() const {
-	return stretchModes;
-}
-
-int OSystem_DS::getDefaultStretchMode() const {
-	return 100;
-}
-
-bool OSystem_DS::setStretchMode(int mode) {
-	_stretchMode = mode;
-	DS::setTopScreenZoom(mode);
-	return true;
-}
-
-int OSystem_DS::getStretchMode() const {
-	return _stretchMode;
-}
-
-void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
-	_framebuffer.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
-
-	// For Lost in Time, the title screen is displayed in 640x400.
-	// In order to support this game, the screen mode is set, but
-	// all draw calls are ignored until the game switches to 320x200.
-	if ((width == 640) && (height == 400)) {
-		_graphicsEnable = false;
-	} else {
-		_graphicsEnable = true;
-		DS::setGameSize(width, height);
-	}
-}
-
-int16 OSystem_DS::getHeight() {
-	return _framebuffer.h;
-}
-
-int16 OSystem_DS::getWidth() {
-	return _framebuffer.w;
-}
-
-void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
-	for (unsigned int r = start; r < start + num; r++) {
-		int red = *colors;
-		int green = *(colors + 1);
-		int blue = *(colors + 2);
-
-		red >>= 3;
-		green >>= 3;
-		blue >>= 3;
-
-		{
-			u16 paletteValue = red | (green << 5) | (blue << 10);
-
-			if (!_isOverlayShown) {
-				BG_PALETTE[r] = paletteValue;
-#ifdef DISABLE_TEXT_CONSOLE
-				BG_PALETTE_SUB[r] = paletteValue;
-#endif
-			}
-
-			_palette[r] = paletteValue;
-		}
-
-		colors += 3;
-	}
-}
-
-void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
-
-	for (unsigned int r = start; r < start + num; r++) {
-		int red = *colors;
-		int green = *(colors + 1);
-		int blue = *(colors + 2);
-
-		red >>= 3;
-		green >>= 3;
-		blue >>= 3;
-
-		u16 paletteValue = red | (green << 5) | (blue << 10);
-		_cursorPalette[r] = paletteValue;
-
-		colors += 3;
-	}
-
-	_disableCursorPalette = false;
-	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
-}
-
-void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) const {
-	for (unsigned int r = start; r < start + num; r++) {
-		*colors++ = (BG_PALETTE[r] & 0x001F) << 3;
-		*colors++ = (BG_PALETTE[r] & 0x03E0) >> 5 << 3;
-		*colors++ = (BG_PALETTE[r] & 0x7C00) >> 10 << 3;
-	}
-}
-
-void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
-	_framebuffer.copyRectToSurface(buf, pitch, x, y, w, h);
-}
-
-void OSystem_DS::updateScreen() {
-	oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
-	       SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
-	oamUpdate(&oamMain);
-
-	if (_isOverlayShown) {
-		u16 *back = (u16 *)_overlay.getPixels();
-		dmaCopyHalfWords(3, back, BG_GFX, 256 * 192 * 2);
-	} else if (!_graphicsEnable) {
-		return;
-	} else if (_graphicsMode == GFX_SWSCALE) {
-		u16 *base = BG_GFX + 0x10000;
-		Rescale_320x256xPAL8_To_256x256x1555(
-			base,
-			(const u8 *)_framebuffer.getPixels(),
-			256,
-			_framebuffer.pitch,
-			BG_PALETTE,
-			_framebuffer.h );
-	} else {
-		// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
-		// to save a few pennies/euro cents on the hardware.
-
-		u16 *bg = BG_GFX + 0x10000;
-		s32 stride = 512;
-
-		u16 *src = (u16 *)_framebuffer.getPixels();
-
-		for (int dy = 0; dy < _framebuffer.h; dy++) {
-			DC_FlushRange(src, _framebuffer.w << 1);
-
-			u16 *dest1 = bg + (dy * (stride >> 1));
-			DC_FlushRange(dest1, _framebuffer.w << 1);
-
-#ifdef DISABLE_TEXT_CONSOLE
-			u16 *dest2 = (u16 *)BG_GFX_SUB + (dy << 8);
-			DC_FlushRange(dest2, _framebuffer.w << 1);
-
-			dmaCopyHalfWordsAsynch(2, src, dest2, _framebuffer.w);
-#endif
-			dmaCopyHalfWordsAsynch(3, src, dest1, _framebuffer.w);
-
-			while (dmaBusy(2) || dmaBusy(3));
-
-			src += _framebuffer.pitch >> 1;
-		}
-	}
-}
-
-void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
-	DS::setShakePos(shakeXOffset, shakeYOffset);
-}
-
-void OSystem_DS::showOverlay() {
-	dmaFillHalfWords(0, BG_GFX, 256 * 192 * 2);
-	videoBgEnable(2);
-	lcdMainOnBottom();
-	_isOverlayShown = true;
-}
-
-void OSystem_DS::hideOverlay() {
-	videoBgDisable(2);
-	DS::displayMode8Bit();
-	_isOverlayShown = false;
-}
-
-bool OSystem_DS::isOverlayVisible() const {
-	return _isOverlayShown;
-}
-
-void OSystem_DS::clearOverlay() {
-	memset(_overlay.getPixels(), 0, _overlay.pitch * _overlay.h);
-}
-
-void OSystem_DS::grabOverlay(void *buf, int pitch) {
-	byte *dst = (byte *)buf;
-
-	for (int y = 0; y < _overlay.h; ++y) {
-		memcpy(dst, _overlay.getBasePtr(0, y), _overlay.w * _overlay.format.bytesPerPixel);
-		dst += pitch;
-	}
-}
-
-void OSystem_DS::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
-	_overlay.copyRectToSurface(buf, pitch, x, y, w, h);
-}
-
-int16 OSystem_DS::getOverlayHeight() {
-	return _overlay.h;
-}
-
-int16 OSystem_DS::getOverlayWidth() {
-	return _overlay.w;
-}
-
-Graphics::PixelFormat OSystem_DS::getOverlayFormat() const {
-	return _overlay.format;
-}
-
-Common::Point OSystem_DS::transformPoint(uint16 x, uint16 y) {
-	return DS::transformPoint(x, y, _isOverlayShown);
-}
-
-bool OSystem_DS::showMouse(bool visible) {
-	const bool last = _cursorVisible;
-	_cursorVisible = visible;
-	return last;
-}
-
-void OSystem_DS::warpMouse(int x, int y) {
-	_cursorPos = DS::warpMouse(x, y, _isOverlayShown);
-}
-
-void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
-	if (!buf || w == 0 || h == 0 || (format && *format != Graphics::PixelFormat::createFormatCLUT8()))
-		return;
-
-	if (_cursor.w != w || _cursor.h != h)
-		_cursor.create(w, h, Graphics::PixelFormat::createFormatCLUT8());
-	_cursor.copyRectToSurface(buf, w, 0, 0, w, h);
-	_cursorHotX = hotspotX;
-	_cursorHotY = hotspotY;
-	_cursorKey = keycolor;
-	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
-}
-
-void OSystem_DS::refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette) {
-	uint w = MIN<uint>(src.w, 64);
-	uint h = MIN<uint>(src.h, 64);
-
-	dmaFillHalfWords(0, dst, 64 * 64 * 2);
-
-	for (uint y = 0; y < h; y++) {
-		const uint8 *row = (const uint8 *)src.getBasePtr(0, y);
-		for (uint x = 0; x < w; x++) {
-			uint8 color = *row++;
-
-			if (color != _cursorKey)
-				dst[y * 64 + x] = palette[color] | 0x8000;
-		}
-	}
-}
-
 void OSystem_DS::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
 	s.add("nitro:/", new Common::FSDirectory("nitro:/"), priority);
 }
@@ -445,22 +128,6 @@ void OSystem_DS::getTimeAndDate(TimeDate &td) const {
 void OSystem_DS::quit() {
 }
 
-Graphics::Surface *OSystem_DS::lockScreen() {
-	return &_framebuffer;
-}
-
-void OSystem_DS::unlockScreen() {
-	// No need to do anything here.  The screen will be updated in updateScreen().
-}
-
-void OSystem_DS::setFocusRectangle(const Common::Rect& rect) {
-	DS::setTalkPos(rect.left + rect.width() / 2, rect.top + rect.height() / 2);
-}
-
-void OSystem_DS::clearFocusRectangle() {
-
-}
-
 void OSystem_DS::engineInit() {
 #ifdef DISABLE_TEXT_CONSOLE
 	videoBgEnableSub(3);
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index af24f3fb51..d0ae0a316a 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -56,6 +56,8 @@ protected:
 
 	DSEventSource *_eventSource;
 
+	void initGraphics();
+
 	Graphics::Surface *createTempFrameBuffer();
 	bool _disableCursorPalette;
 


Commit: f802c2e88a83ea9efa0fbbed778362721d661c42
    https://github.com/scummvm/scummvm/commit/f802c2e88a83ea9efa0fbbed778362721d661c42
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Add support for RGB cursors

Changed paths:
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index 39737722fe..ef2d209f8e 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -335,7 +335,7 @@ void OSystem_DS::initGraphics() {
 	oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
 	_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
 
-	_overlay.create(256, 192, Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15));
+	_overlay.create(256, 192, _pfABGR1555);
 }
 
 bool OSystem_DS::hasFeature(Feature f) {
@@ -607,31 +607,52 @@ void OSystem_DS::warpMouse(int x, int y) {
 }
 
 void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
-	if (!buf || w == 0 || h == 0 || (format && *format != Graphics::PixelFormat::createFormatCLUT8()))
+	if (!buf || w == 0 || h == 0)
 		return;
 
-	if (_cursor.w != w || _cursor.h != h)
-		_cursor.create(w, h, Graphics::PixelFormat::createFormatCLUT8());
-	_cursor.copyRectToSurface(buf, w, 0, 0, w, h);
+	Graphics::PixelFormat actualFormat = format ? *format : _pfCLUT8;
+	if (_cursor.w != w || _cursor.h != h || _cursor.format != actualFormat)
+		_cursor.create(w, h, actualFormat);
+	_cursor.copyRectToSurface(buf, w * actualFormat.bytesPerPixel, 0, 0, w, h);
 	_cursorHotX = hotspotX;
 	_cursorHotY = hotspotY;
 	_cursorKey = keycolor;
+
+	if (actualFormat != _pfCLUT8 && actualFormat != _pfABGR1555) {
+		uint8 a, r, g, b;
+		actualFormat.colorToARGB(_cursorKey, a, r, g, b);
+		_cursorKey = _pfABGR1555.ARGBToColor(a, r, g, b);
+		_cursor.convertToInPlace(_pfABGR1555);
+	}
+
 	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
 }
 
 void OSystem_DS::refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette) {
-	uint w = MIN<uint>(src.w, 64);
-	uint h = MIN<uint>(src.h, 64);
+	const uint w = MIN<uint>(src.w, 64);
+	const uint h = MIN<uint>(src.h, 64);
 
 	dmaFillHalfWords(0, dst, 64 * 64 * 2);
 
-	for (uint y = 0; y < h; y++) {
-		const uint8 *row = (const uint8 *)src.getBasePtr(0, y);
-		for (uint x = 0; x < w; x++) {
-			uint8 color = *row++;
+	if (src.format == _pfCLUT8) {
+		for (uint y = 0; y < h; y++) {
+			const uint8 *row = (const uint8 *)src.getBasePtr(0, y);
+			for (uint x = 0; x < w; x++) {
+				uint8 color = *row++;
+
+				if (color != _cursorKey)
+					dst[y * 64 + x] = palette[color] | 0x8000;
+			}
+		}
+	} else {
+		for (uint y = 0; y < h; y++) {
+			const uint16 *row = (const uint16 *)src.getBasePtr(0, y);
+			for (uint x = 0; x < w; x++) {
+				uint16 color = *row++;
 
-			if (color != _cursorKey)
-				dst[y * 64 + x] = palette[color] | 0x8000;
+				if (color != _cursorKey)
+					dst[y * 64 + x] = color;
+			}
 		}
 	}
 }
diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index 6bca105510..0473971704 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -48,6 +48,8 @@ OSystem_DS::OSystem_DS()
 	: _eventSource(NULL), _isOverlayShown(true),
 	_graphicsMode(GFX_HWSCALE), _stretchMode(100),
 	_disableCursorPalette(true), _graphicsEnable(true),
+	_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
+	_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)),
 	_callbackTimer(10), _currentTimeMillis(0)
 {
 	_instance = this;
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index d0ae0a316a..c3995c9771 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -51,7 +51,7 @@ protected:
 	Common::Point _cursorPos;
 	int _cursorHotX;
 	int _cursorHotY;
-	byte _cursorKey;
+	uint32 _cursorKey;
 	bool _cursorVisible;
 
 	DSEventSource *_eventSource;
@@ -61,6 +61,8 @@ protected:
 	Graphics::Surface *createTempFrameBuffer();
 	bool _disableCursorPalette;
 
+	const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
+
 public:
 	OSystem_DS();
 	virtual ~OSystem_DS();


Commit: 2ca80f8c86a1be447999a7a47411b4b07f28fb50
    https://github.com/scummvm/scummvm/commit/2ca80f8c86a1be447999a7a47411b4b07f28fb50
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Add -mthumb to the linker flags

Changed paths:
    configure


diff --git a/configure b/configure
index 2b7251293e..fb0822603a 100755
--- a/configure
+++ b/configure
@@ -3003,6 +3003,7 @@ EOF
 		append_var CXXFLAGS "-fdata-sections"
 		append_var CXXFLAGS "-fno-strict-aliasing"
 		append_var CXXFLAGS "-fuse-cxa-atexit"
+		append_var LDFLAGS "-mthumb"
 		append_var LDFLAGS "-mthumb-interwork"
 		append_var LDFLAGS "-mfloat-abi=soft"
 		append_var LDFLAGS "-Wl,-Map,map.txt"
@@ -4158,7 +4159,7 @@ POST_OBJS_FLAGS		:= -Wl,--no-whole-archive
 		append_var DEFINES "-DUNCACHED_PLUGINS"
 		append_var DEFINES "-DELF_NO_MEM_MANAGER"
 _mak_plugins='
-PLUGIN_LDFLAGS		+= -Wl,-T$(srcdir)/backends/plugins/ds/plugin.ld -mthumb-interwork -mfloat-abi=soft
+PLUGIN_LDFLAGS		+= -Wl,-T$(srcdir)/backends/plugins/ds/plugin.ld -mthumb -mthumb-interwork -mfloat-abi=soft
 '
 		;;
 	freebsd* | openbsd*)


Commit: 4ac5421c6d2f0d3001b9cad9f37b9e23ed9453e3
    https://github.com/scummvm/scummvm/commit/4ac5421c6d2f0d3001b9cad9f37b9e23ed9453e3
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Add a generic dmaBlit function and use it in updateScreen

Changed paths:
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index ef2d209f8e..be210524df 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -493,6 +493,35 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 	_framebuffer.copyRectToSurface(buf, pitch, x, y, w, h);
 }
 
+void OSystem_DS::dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
+                         const uint w, const uint h) {
+	// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
+	// to save a few pennies/euro cents on the hardware.
+
+	for (uint dy = 0; dy < h; dy += 2) {
+		const u16 *src1 = src;
+		src += (srcPitch >> 1);
+		DC_FlushRange(src1, w << 1);
+
+		const u16 *src2 = src;
+		src += (srcPitch >> 1);
+		DC_FlushRange(src2, w << 1);
+
+		u16 *dest1 = dst;
+		dst += (dstPitch >> 1);
+		DC_FlushRange(dest1, w << 1);
+
+		u16 *dest2 = dst;
+		dst += (dstPitch >> 1);
+		DC_FlushRange(dest2, w << 1);
+
+		dmaCopyHalfWordsAsynch(2, src1, dest1, w);
+		dmaCopyHalfWordsAsynch(3, src2, dest2, w);
+
+		while (dmaBusy(2) || dmaBusy(3));
+	}
+}
+
 void OSystem_DS::updateScreen() {
 	oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
 	       SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
@@ -500,44 +529,24 @@ void OSystem_DS::updateScreen() {
 
 	if (_isOverlayShown) {
 		u16 *back = (u16 *)_overlay.getPixels();
-		dmaCopyHalfWords(3, back, BG_GFX, 256 * 192 * 2);
-	} else if (!_graphicsEnable) {
-		return;
-	} else if (_graphicsMode == GFX_SWSCALE) {
+		dmaCopy(back, BG_GFX, 256 * 192 * 2);
+	} else if (_graphicsEnable) {
 		u16 *base = BG_GFX + 0x10000;
-		Rescale_320x256xPAL8_To_256x256x1555(
-			base,
-			(const u8 *)_framebuffer.getPixels(),
-			256,
-			_framebuffer.pitch,
-			BG_PALETTE,
-			_framebuffer.h );
-	} else {
-		// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
-		// to save a few pennies/euro cents on the hardware.
-
-		u16 *bg = BG_GFX + 0x10000;
-		s32 stride = 512;
-
-		u16 *src = (u16 *)_framebuffer.getPixels();
-
-		for (int dy = 0; dy < _framebuffer.h; dy++) {
-			DC_FlushRange(src, _framebuffer.w << 1);
-
-			u16 *dest1 = bg + (dy * (stride >> 1));
-			DC_FlushRange(dest1, _framebuffer.w << 1);
+		if (_graphicsMode == GFX_SWSCALE) {
+			Rescale_320x256xPAL8_To_256x256x1555(
+				base,
+				(const u8 *)_framebuffer.getPixels(),
+				256,
+				_framebuffer.pitch,
+				BG_PALETTE,
+				_framebuffer.h );
+		} else {
+			dmaBlit(base, 512, (const u16 *)_framebuffer.getPixels(), _framebuffer.pitch,
+				_framebuffer.w, _framebuffer.h);
 
 #ifdef DISABLE_TEXT_CONSOLE
-			u16 *dest2 = (u16 *)BG_GFX_SUB + (dy << 8);
-			DC_FlushRange(dest2, _framebuffer.w << 1);
-
-			dmaCopyHalfWordsAsynch(2, src, dest2, _framebuffer.w);
+			dmaCopy(base, BG_GFX_SUB, 512 * 256);
 #endif
-			dmaCopyHalfWordsAsynch(3, src, dest1, _framebuffer.w);
-
-			while (dmaBusy(2) || dmaBusy(3));
-
-			src += _framebuffer.pitch >> 1;
 		}
 	}
 }
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index c3995c9771..3572a7a964 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -58,7 +58,9 @@ protected:
 
 	void initGraphics();
 
-	Graphics::Surface *createTempFrameBuffer();
+	void dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
+	             const uint w, const uint h);
+
 	bool _disableCursorPalette;
 
 	const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;


Commit: 0c776013f716617abd90d0a66d8b39101e4f137a
    https://github.com/scummvm/scummvm/commit/0c776013f716617abd90d0a66d8b39101e4f137a
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Add RGB colour support

Changed paths:
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ds/osystem_ds.h
    configure


diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index be210524df..ec3154bf2b 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -83,21 +83,12 @@ void setTopScreenTarget(int x, int y) {
 	subScTargetY <<=8;
 }
 
-void setGameSize(int width, int height) {
+void setGameSize(int width, int height, bool isRGB) {
 	gameWidth = width;
 	gameHeight = height;
-}
-
-int getGameWidth() {
-	return gameWidth;
-}
 
-int getGameHeight() {
-	return gameHeight;
-}
-
-void displayMode8Bit() {
 	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
+	vramSetBankD(VRAM_D_MAIN_BG_0x06040000);
 
 	if (g_system->getGraphicsMode() == GFX_SWSCALE) {
 		REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
@@ -108,7 +99,7 @@ void displayMode8Bit() {
 		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
 
 	} else {
-		REG_BG3CNT = BG_BMP8_512x256 | BG_BMP_BASE(8);
+		REG_BG3CNT = (isRGB ? BG_BMP16_512x256 :BG_BMP8_512x256) | BG_BMP_BASE(8);
 
 		REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
 		REG_BG3PB = 0;
@@ -124,12 +115,6 @@ void displayMode8Bit() {
 	REG_BG3PC_SUB = 0;
 	REG_BG3PD_SUB = (int) (subScreenHeight / 192.0f * 256);
 #endif
-
-	if (gameScreenSwap) {
-		lcdMainOnTop();
-	} else {
-		lcdMainOnBottom();
-	}
 }
 
 void setShakePos(int shakeXOffset, int shakeYOffset) {
@@ -411,8 +396,21 @@ int OSystem_DS::getStretchMode() const {
 	return _stretchMode;
 }
 
+Graphics::PixelFormat OSystem_DS::getScreenFormat() const {
+	return _framebuffer.format;
+}
+
+Common::List<Graphics::PixelFormat> OSystem_DS::getSupportedFormats() const {
+	Common::List<Graphics::PixelFormat> res;
+	res.push_back(_pfABGR1555);
+	res.push_back(_pfCLUT8);
+
+	return res;
+}
+
 void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
-	_framebuffer.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+	Graphics::PixelFormat actualFormat = format ? *format : _pfCLUT8;
+	_framebuffer.create(width, height, actualFormat);
 
 	// For Lost in Time, the title screen is displayed in 640x400.
 	// In order to support this game, the screen mode is set, but
@@ -421,7 +419,7 @@ void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *
 		_graphicsEnable = false;
 	} else {
 		_graphicsEnable = true;
-		DS::setGameSize(width, height);
+		DS::setGameSize(width, height, (actualFormat != _pfCLUT8));
 	}
 }
 
@@ -494,29 +492,31 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 }
 
 void OSystem_DS::dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
-                         const uint w, const uint h) {
+                         const uint w, const uint h, const uint bytesPerPixel) {
 	// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
 	// to save a few pennies/euro cents on the hardware.
 
+	uint row = w * bytesPerPixel;
+
 	for (uint dy = 0; dy < h; dy += 2) {
 		const u16 *src1 = src;
 		src += (srcPitch >> 1);
-		DC_FlushRange(src1, w << 1);
+		DC_FlushRange(src1, row << 1);
 
 		const u16 *src2 = src;
 		src += (srcPitch >> 1);
-		DC_FlushRange(src2, w << 1);
+		DC_FlushRange(src2, row << 1);
 
 		u16 *dest1 = dst;
 		dst += (dstPitch >> 1);
-		DC_FlushRange(dest1, w << 1);
+		DC_FlushRange(dest1, row << 1);
 
 		u16 *dest2 = dst;
 		dst += (dstPitch >> 1);
-		DC_FlushRange(dest2, w << 1);
+		DC_FlushRange(dest2, row << 1);
 
-		dmaCopyHalfWordsAsynch(2, src1, dest1, w);
-		dmaCopyHalfWordsAsynch(3, src2, dest2, w);
+		dmaCopyHalfWordsAsynch(2, src1, dest1, row);
+		dmaCopyHalfWordsAsynch(3, src2, dest2, row);
 
 		while (dmaBusy(2) || dmaBusy(3));
 	}
@@ -533,19 +533,29 @@ void OSystem_DS::updateScreen() {
 	} else if (_graphicsEnable) {
 		u16 *base = BG_GFX + 0x10000;
 		if (_graphicsMode == GFX_SWSCALE) {
-			Rescale_320x256xPAL8_To_256x256x1555(
-				base,
-				(const u8 *)_framebuffer.getPixels(),
-				256,
-				_framebuffer.pitch,
-				BG_PALETTE,
-				_framebuffer.h );
+			if (_framebuffer.format == _pfCLUT8) {
+				Rescale_320x256xPAL8_To_256x256x1555(
+					base,
+					(const u8 *)_framebuffer.getPixels(),
+					256,
+					_framebuffer.pitch,
+					BG_PALETTE,
+					_framebuffer.h );
+			} else {
+				Rescale_320x256x1555_To_256x256x1555(
+					base,
+					(const u16 *)_framebuffer.getPixels(),
+					256,
+					_framebuffer.pitch / 2 );
+			}
 		} else {
-			dmaBlit(base, 512, (const u16 *)_framebuffer.getPixels(), _framebuffer.pitch,
-				_framebuffer.w, _framebuffer.h);
+			dmaBlit(base, 512 * _framebuffer.format.bytesPerPixel,
+				(const u16 *)_framebuffer.getPixels(), _framebuffer.pitch,
+				_framebuffer.w, _framebuffer.h, _framebuffer.format.bytesPerPixel);
 
 #ifdef DISABLE_TEXT_CONSOLE
-			dmaCopy(base, BG_GFX_SUB, 512 * 256);
+			if (_framebuffer.format == _pfCLUT8)
+				dmaCopy(base, BG_GFX_SUB, 512 * 256);
 #endif
 		}
 	}
@@ -564,8 +574,13 @@ void OSystem_DS::showOverlay() {
 
 void OSystem_DS::hideOverlay() {
 	videoBgDisable(2);
-	DS::displayMode8Bit();
 	_isOverlayShown = false;
+
+	if (DS::gameScreenSwap) {
+		lcdMainOnTop();
+	} else {
+		lcdMainOnBottom();
+	}
 }
 
 bool OSystem_DS::isOverlayVisible() const {
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index 3572a7a964..5ddc2f8914 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -59,7 +59,7 @@ protected:
 	void initGraphics();
 
 	void dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
-	             const uint w, const uint h);
+	             const uint w, const uint h, const uint bytesPerPixel);
 
 	bool _disableCursorPalette;
 
@@ -85,6 +85,9 @@ public:
 	virtual bool setStretchMode(int mode);
 	virtual int getStretchMode() const;
 
+	virtual Graphics::PixelFormat getScreenFormat() const;
+	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
+
 	virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
 	virtual int16 getHeight();
 	virtual int16 getWidth();
diff --git a/configure b/configure
index fb0822603a..cb80821756 100755
--- a/configure
+++ b/configure
@@ -3944,7 +3944,7 @@ fi
 # Enable 16bit support only for backends which support it
 #
 case $_backend in
-	3ds | android | android3d | androidsdl | dingux | dc | gph | iphone | ios7 | maemo | null | openpandora | psp | psp2 | samsungtv | sdl | switch | wii)
+	3ds | android | android3d | androidsdl | dingux | dc | ds | gph | iphone | ios7 | maemo | null | openpandora | psp | psp2 | samsungtv | sdl | switch | wii)
 		if test "$_16bit" = auto ; then
 			_16bit=yes
 		else


Commit: cd7ae99f0b4b660248170572e96f24dcf96c1857
    https://github.com/scummvm/scummvm/commit/cd7ae99f0b4b660248170572e96f24dcf96c1857
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
GIT: Ignore the romfs directory

Changed paths:
    .gitignore


diff --git a/.gitignore b/.gitignore
index 761df9293b..15a2020b5f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ lib*.a
 /map.txt
 *.elf
 /*.nds
+/romfs
 /.project
 /.cproject
 /.settings


Commit: a642279e5d15eea9a5ffcbb2da93f7c46958d611
    https://github.com/scummvm/scummvm/commit/a642279e5d15eea9a5ffcbb2da93f7c46958d611
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Add a Background class for the overlay

Changed paths:
  A backends/platform/ds/background.cpp
  A backends/platform/ds/background.h
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ds/module.mk
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/background.cpp b/backends/platform/ds/background.cpp
new file mode 100644
index 0000000000..fafe4dab74
--- /dev/null
+++ b/backends/platform/ds/background.cpp
@@ -0,0 +1,108 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <nds.h>
+
+#include "backends/platform/ds/background.h"
+
+namespace DS {
+
+BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
+	BgSize size;
+	if (width > 512 && !isRGB) {
+		size = BgSize_B8_1024x512;
+		realPitch = 1024;
+	} else if (height > 512 && !isRGB) {
+		size = BgSize_B8_512x1024;
+		realPitch = 512;
+	} else if (height > 256) {
+		if (isRGB) {
+			size = BgSize_B16_512x512;
+			realPitch = 1024;
+		} else {
+			size = BgSize_B8_512x512;
+			realPitch = 512;
+		}
+	} else if (width > 256) {
+		if (isRGB) {
+			size = BgSize_B16_512x256;
+			realPitch = 1024;
+		} else {
+			size = BgSize_B8_512x256;
+			realPitch = 512;
+		}
+	} else if (width > 128 || height > 128) {
+		if (isRGB) {
+			size = BgSize_B16_256x256;
+			realPitch = 512;
+		} else {
+			size = BgSize_B8_256x256;
+			realPitch = 256;
+		}
+	} else {
+		if (isRGB) {
+			size = BgSize_B16_128x128;
+			realPitch = 256;
+		} else {
+			size = BgSize_B8_128x128;
+			realPitch = 128;
+		}
+	}
+	return size;
+}
+
+void Background::create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase) {
+	const Graphics::PixelFormat f = isRGB ? Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15) : Graphics::PixelFormat::createFormatCLUT8();
+	Surface::create(width, height, f);
+
+	BgType type = isRGB ? BgType_Bmp16 : BgType_Bmp8;
+	BgSize size = getBgSize(width, height, isRGB, _realPitch);
+
+	if (isSub) {
+		_bg = bgInitSub(layer, type, size, mapBase, 0);
+	} else {
+		_bg = bgInit(layer, type, size, mapBase, 0);
+	}
+}
+
+void Background::update() {
+	u16 *src = (u16 *)getPixels();
+	u16 *dst = bgGetGfxPtr(_bg);
+	dmaCopy(src, dst, _realPitch * h);
+}
+
+void Background::reset() {
+	u16 *dst = bgGetGfxPtr(_bg);
+	dmaFillHalfWords(0, dst, _realPitch * h);
+}
+
+void Background::show() {
+	bgShow(_bg);
+	_visible = true;
+}
+
+void Background::hide() {
+	bgHide(_bg);
+	_visible = false;
+}
+
+} // End of namespace DS
diff --git a/backends/platform/ds/background.h b/backends/platform/ds/background.h
new file mode 100644
index 0000000000..4bce40ca14
--- /dev/null
+++ b/backends/platform/ds/background.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DS_BACKGROUND_H
+#define DS_BACKGROUND_H
+
+#include "graphics/surface.h"
+
+namespace DS {
+
+class Background : public Graphics::Surface {
+public:
+	void create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase);
+
+	void update();
+	void reset();
+
+	void show();
+	void hide();
+	inline bool isVisible() const { return _visible; }
+
+	inline void clear() {
+		memset(getPixels(), 0, pitch * h);
+	}
+
+	inline void grab(byte *dst, int dstPitch) {
+		for (int y = 0; y < h; ++y) {
+			memcpy(dst, getBasePtr(0, y), w * format.bytesPerPixel);
+			dst += dstPitch;
+		}
+	}
+
+protected:
+	int _bg;
+	bool _visible;
+	int _realPitch;
+};
+
+} // End of namespace DS
+
+#endif // #ifndef DS_BACKGROUND_H
diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index ec3154bf2b..4b526e05d0 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -283,12 +283,6 @@ void initHardware() {
 	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
 	vramSetBankE(VRAM_E_MAIN_SPRITE);
 
-	REG_BG2CNT = BG_BMP16_256x256;
-	REG_BG2PA = 256;
-	REG_BG2PB = 0;
-	REG_BG2PC = 0;
-	REG_BG2PD = 256;
-
 	scX = 0;
 	scY = 0;
 	subScX = 0;
@@ -320,7 +314,7 @@ void OSystem_DS::initGraphics() {
 	oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
 	_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
 
-	_overlay.create(256, 192, _pfABGR1555);
+	_overlay.create(256, 192, true, 2, false, 0);
 }
 
 bool OSystem_DS::hasFeature(Feature f) {
@@ -444,7 +438,7 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 		{
 			u16 paletteValue = red | (green << 5) | (blue << 10);
 
-			if (!_isOverlayShown) {
+			if (!_overlay.isVisible()) {
 				BG_PALETTE[r] = paletteValue;
 #ifdef DISABLE_TEXT_CONSOLE
 				BG_PALETTE_SUB[r] = paletteValue;
@@ -527,9 +521,8 @@ void OSystem_DS::updateScreen() {
 	       SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
 	oamUpdate(&oamMain);
 
-	if (_isOverlayShown) {
-		u16 *back = (u16 *)_overlay.getPixels();
-		dmaCopy(back, BG_GFX, 256 * 192 * 2);
+	if (_overlay.isVisible()) {
+		_overlay.update();
 	} else if (_graphicsEnable) {
 		u16 *base = BG_GFX + 0x10000;
 		if (_graphicsMode == GFX_SWSCALE) {
@@ -566,15 +559,13 @@ void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
 }
 
 void OSystem_DS::showOverlay() {
-	dmaFillHalfWords(0, BG_GFX, 256 * 192 * 2);
-	videoBgEnable(2);
+	_overlay.reset();
+	_overlay.show();
 	lcdMainOnBottom();
-	_isOverlayShown = true;
 }
 
 void OSystem_DS::hideOverlay() {
-	videoBgDisable(2);
-	_isOverlayShown = false;
+	_overlay.hide();
 
 	if (DS::gameScreenSwap) {
 		lcdMainOnTop();
@@ -584,20 +575,15 @@ void OSystem_DS::hideOverlay() {
 }
 
 bool OSystem_DS::isOverlayVisible() const {
-	return _isOverlayShown;
+	return _overlay.isVisible();
 }
 
 void OSystem_DS::clearOverlay() {
-	memset(_overlay.getPixels(), 0, _overlay.pitch * _overlay.h);
+	_overlay.clear();
 }
 
 void OSystem_DS::grabOverlay(void *buf, int pitch) {
-	byte *dst = (byte *)buf;
-
-	for (int y = 0; y < _overlay.h; ++y) {
-		memcpy(dst, _overlay.getBasePtr(0, y), _overlay.w * _overlay.format.bytesPerPixel);
-		dst += pitch;
-	}
+	_overlay.grab((byte *)buf, pitch);
 }
 
 void OSystem_DS::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
@@ -617,7 +603,7 @@ Graphics::PixelFormat OSystem_DS::getOverlayFormat() const {
 }
 
 Common::Point OSystem_DS::transformPoint(uint16 x, uint16 y) {
-	return DS::transformPoint(x, y, _isOverlayShown);
+	return DS::transformPoint(x, y, _overlay.isVisible());
 }
 
 bool OSystem_DS::showMouse(bool visible) {
@@ -627,7 +613,7 @@ bool OSystem_DS::showMouse(bool visible) {
 }
 
 void OSystem_DS::warpMouse(int x, int y) {
-	_cursorPos = DS::warpMouse(x, y, _isOverlayShown);
+	_cursorPos = DS::warpMouse(x, y, _overlay.isVisible());
 }
 
 void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk
index 3592afbfa4..27204b9413 100644
--- a/backends/platform/ds/module.mk
+++ b/backends/platform/ds/module.mk
@@ -1,6 +1,7 @@
 MODULE := backends/platform/ds
 
 MODULE_OBJS := \
+	background.o \
 	blitters_arm.o \
 	ds-graphics.o \
 	dsmain.o \
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index 5ddc2f8914..3fdcb4aa0e 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -27,6 +27,7 @@
 #include "backends/modular-backend.h"
 #include "backends/events/ds/ds-events.h"
 #include "backends/mixer/mixer.h"
+#include "backends/platform/ds/background.h"
 #include "graphics/surface.h"
 #include "graphics/palette.h"
 
@@ -38,7 +39,8 @@ enum {
 
 class OSystem_DS : public ModularMutexBackend, public ModularMixerBackend, public PaletteManager {
 protected:
-	Graphics::Surface _framebuffer, _overlay, _cursor;
+	DS::Background _overlay;
+	Graphics::Surface _framebuffer, _cursor;
 	bool _graphicsEnable, _isOverlayShown;
 	int _graphicsMode, _stretchMode;
 


Commit: b37843f10d68b464a738b68e436113a8d9a14201
    https://github.com/scummvm/scummvm/commit/b37843f10d68b464a738b68e436113a8d9a14201
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Fix setGraphicsMode signature

Changed paths:
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index 4b526e05d0..33f13686c6 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -349,7 +349,7 @@ int OSystem_DS::getDefaultGraphicsMode() const {
 	return GFX_HWSCALE;
 }
 
-bool OSystem_DS::setGraphicsMode(int mode) {
+bool OSystem_DS::setGraphicsMode(int mode, uint flags) {
 	switch (mode) {
 	case GFX_NOSCALE:
 	case GFX_HWSCALE:
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index 3fdcb4aa0e..f257545cda 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -79,7 +79,7 @@ public:
 
 	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
 	virtual int getDefaultGraphicsMode() const;
-	virtual bool setGraphicsMode(int mode);
+	virtual bool setGraphicsMode(int mode, uint flags);
 	virtual int getGraphicsMode() const;
 
 	virtual const GraphicsMode *getSupportedStretchModes() const;


Commit: 7ddd7e49317b52cd62777112ddcb4a80fce4accc
    https://github.com/scummvm/scummvm/commit/7ddd7e49317b52cd62777112ddcb4a80fce4accc
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Use the Background class for the game screen

Changed paths:
    backends/platform/ds/background.cpp
    backends/platform/ds/background.h
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/background.cpp b/backends/platform/ds/background.cpp
index fafe4dab74..606aaf4549 100644
--- a/backends/platform/ds/background.cpp
+++ b/backends/platform/ds/background.cpp
@@ -23,17 +23,32 @@
 #include <nds.h>
 
 #include "backends/platform/ds/background.h"
+#include "backends/platform/ds/blitters.h"
 
 namespace DS {
 
-BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
+Background::Background() :
+	_bg(-1), _visible(true), _swScale(false),
+	_realPitch(0), _realHeight(0),
+	_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
+	_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)) {
+}
+
+static BgSize getBgSize(uint16 width, uint16 height, bool isRGB, bool swScale, uint16 &realPitch, uint16 &realHeight) {
+	if (swScale) {
+		isRGB = true;
+		width = (width * 4) / 5;
+	}
+
 	BgSize size;
 	if (width > 512 && !isRGB) {
 		size = BgSize_B8_1024x512;
 		realPitch = 1024;
+		realHeight = 512;
 	} else if (height > 512 && !isRGB) {
 		size = BgSize_B8_512x1024;
 		realPitch = 512;
+		realHeight = 1024;
 	} else if (height > 256) {
 		if (isRGB) {
 			size = BgSize_B16_512x512;
@@ -42,6 +57,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
 			size = BgSize_B8_512x512;
 			realPitch = 512;
 		}
+		realHeight = 512;
 	} else if (width > 256) {
 		if (isRGB) {
 			size = BgSize_B16_512x256;
@@ -50,6 +66,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
 			size = BgSize_B8_512x256;
 			realPitch = 512;
 		}
+		realHeight = 256;
 	} else if (width > 128 || height > 128) {
 		if (isRGB) {
 			size = BgSize_B16_256x256;
@@ -58,6 +75,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
 			size = BgSize_B8_256x256;
 			realPitch = 256;
 		}
+		realHeight = 256;
 	} else {
 		if (isRGB) {
 			size = BgSize_B16_128x128;
@@ -66,42 +84,133 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
 			size = BgSize_B8_128x128;
 			realPitch = 128;
 		}
+		realHeight = 128;
 	}
 	return size;
 }
 
-void Background::create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase) {
-	const Graphics::PixelFormat f = isRGB ? Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15) : Graphics::PixelFormat::createFormatCLUT8();
+size_t Background::getRequiredVRAM(uint16 width, uint16 height, bool isRGB, bool swScale) {
+	uint16 realPitch, realHeight;
+	/* BgSize size = */ getBgSize(width, height, isRGB, swScale, realPitch, realHeight);
+	return realPitch * realHeight;
+}
+
+void Background::create(uint16 width, uint16 height, bool isRGB) {
+	const Graphics::PixelFormat f = isRGB ? _pfABGR1555 : _pfCLUT8;
 	Surface::create(width, height, f);
+	_bg = -1;
+	_swScale = false;
+}
+
+void Background::create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase, bool swScale) {
+	const Graphics::PixelFormat f = isRGB ? _pfABGR1555 : _pfCLUT8;
+	Surface::create(width, height, f);
+
+	BgType type = (isRGB || swScale) ? BgType_Bmp16 : BgType_Bmp8;
+	BgSize size = getBgSize(width, height, isRGB, swScale, _realPitch, _realHeight);
+
+	if (isSub) {
+		_bg = bgInitSub(layer, type, size, mapBase, 0);
+	} else {
+		_bg = bgInit(layer, type, size, mapBase, 0);
+	}
+
+	_swScale = swScale;
+}
+
+void Background::init(Background *surface) {
+	Surface::init(surface->w, surface->h, surface->pitch, surface->pixels, surface->format);
+	_bg = -1;
+	_swScale = false;
+}
 
-	BgType type = isRGB ? BgType_Bmp16 : BgType_Bmp8;
-	BgSize size = getBgSize(width, height, isRGB, _realPitch);
+void Background::init(Background *surface, int layer, bool isSub, int mapBase, bool swScale) {
+	Surface::init(surface->w, surface->h, surface->pitch, surface->pixels, surface->format);
+
+	bool isRGB = (format != _pfCLUT8);
+	BgType type = (isRGB || swScale) ? BgType_Bmp16 : BgType_Bmp8;
+	BgSize size = getBgSize(w, h, isRGB, swScale, _realPitch, _realHeight);
 
 	if (isSub) {
 		_bg = bgInitSub(layer, type, size, mapBase, 0);
 	} else {
 		_bg = bgInit(layer, type, size, mapBase, 0);
 	}
+
+	_swScale = swScale;
+}
+
+static void dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
+                    const uint w, const uint h, const uint bytesPerPixel) {
+	if (dstPitch == srcPitch && ((w * bytesPerPixel) == dstPitch)) {
+		dmaCopy(src, dst, dstPitch * h);
+		return;
+	}
+
+	// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
+	// to save a few pennies/euro cents on the hardware.
+
+	uint row = w * bytesPerPixel;
+
+	for (uint dy = 0; dy < h; dy += 2) {
+		const u16 *src1 = src;
+		src += (srcPitch >> 1);
+		DC_FlushRange(src1, row << 1);
+
+		const u16 *src2 = src;
+		src += (srcPitch >> 1);
+		DC_FlushRange(src2, row << 1);
+
+		u16 *dest1 = dst;
+		dst += (dstPitch >> 1);
+		DC_FlushRange(dest1, row << 1);
+
+		u16 *dest2 = dst;
+		dst += (dstPitch >> 1);
+		DC_FlushRange(dest2, row << 1);
+
+		dmaCopyHalfWordsAsynch(2, src1, dest1, row);
+		dmaCopyHalfWordsAsynch(3, src2, dest2, row);
+
+		while (dmaBusy(2) || dmaBusy(3));
+	}
 }
 
 void Background::update() {
-	u16 *src = (u16 *)getPixels();
+	if (_bg < 0)
+		return;
+
 	u16 *dst = bgGetGfxPtr(_bg);
-	dmaCopy(src, dst, _realPitch * h);
+	if (_swScale) {
+		if (format == _pfCLUT8) {
+			Rescale_320x256xPAL8_To_256x256x1555(
+				dst, (const u8 *)getPixels(), _realPitch / 2, pitch, BG_PALETTE, h);
+		} else {
+			Rescale_320x256x1555_To_256x256x1555(
+				dst, (const u16 *)getPixels(), _realPitch / 2, pitch / 2);
+		}
+	} else {
+		dmaBlit(dst, _realPitch, (const u16 *)getPixels(), pitch, w, h, format.bytesPerPixel);
+	}
 }
 
 void Background::reset() {
+	if (_bg < 0)
+		return;
+
 	u16 *dst = bgGetGfxPtr(_bg);
 	dmaFillHalfWords(0, dst, _realPitch * h);
 }
 
 void Background::show() {
-	bgShow(_bg);
+	if (_bg >= 0)
+		bgShow(_bg);
 	_visible = true;
 }
 
 void Background::hide() {
-	bgHide(_bg);
+	if (_bg >= 0)
+		bgHide(_bg);
 	_visible = false;
 }
 
diff --git a/backends/platform/ds/background.h b/backends/platform/ds/background.h
index 4bce40ca14..c64e0f89a9 100644
--- a/backends/platform/ds/background.h
+++ b/backends/platform/ds/background.h
@@ -29,7 +29,13 @@ namespace DS {
 
 class Background : public Graphics::Surface {
 public:
-	void create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase);
+	Background();
+
+	size_t getRequiredVRAM(uint16 width, uint16 height, bool isRGB, bool swScale);
+	void create(uint16 width, uint16 height, bool isRGB);
+	void create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase, bool swScale);
+	void init(Background *surface);
+	void init(Background *surface, int layer, bool isSub, int mapBase, bool swScale);
 
 	void update();
 	void reset();
@@ -51,8 +57,9 @@ public:
 
 protected:
 	int _bg;
-	bool _visible;
-	int _realPitch;
+	bool _visible, _swScale;
+	uint16 _realPitch, _realHeight;
+	const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
 };
 
 } // End of namespace DS
diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index 33f13686c6..1404882cd2 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -23,7 +23,6 @@
 #include <nds.h>
 
 #include "backends/platform/ds/osystem_ds.h"
-#include "backends/platform/ds/blitters.h"
 
 #include "common/translation.h"
 
@@ -83,24 +82,17 @@ void setTopScreenTarget(int x, int y) {
 	subScTargetY <<=8;
 }
 
-void setGameSize(int width, int height, bool isRGB) {
+void setGameSize(int width, int height) {
 	gameWidth = width;
 	gameHeight = height;
 
-	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
-	vramSetBankD(VRAM_D_MAIN_BG_0x06040000);
-
 	if (g_system->getGraphicsMode() == GFX_SWSCALE) {
-		REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
-
 		REG_BG3PA = 256;
 		REG_BG3PB = 0;
 		REG_BG3PC = 0;
 		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
 
 	} else {
-		REG_BG3CNT = (isRGB ? BG_BMP16_512x256 :BG_BMP8_512x256) | BG_BMP_BASE(8);
-
 		REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
 		REG_BG3PB = 0;
 		REG_BG3PC = 0;
@@ -108,8 +100,6 @@ void setGameSize(int width, int height, bool isRGB) {
 	}
 
 #ifdef DISABLE_TEXT_CONSOLE
-	REG_BG3CNT_SUB = BG_BMP8_512x256;
-
 	REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
 	REG_BG3PB_SUB = 0;
 	REG_BG3PC_SUB = 0;
@@ -281,6 +271,8 @@ void initHardware() {
 
 	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
 	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
+	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
+	vramSetBankD(VRAM_D_MAIN_BG_0x06040000);
 	vramSetBankE(VRAM_E_MAIN_SPRITE);
 
 	scX = 0;
@@ -314,7 +306,7 @@ void OSystem_DS::initGraphics() {
 	oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
 	_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
 
-	_overlay.create(256, 192, true, 2, false, 0);
+	_overlay.create(256, 192, true, 2, false, 0, false);
 }
 
 bool OSystem_DS::hasFeature(Feature f) {
@@ -404,17 +396,27 @@ Common::List<Graphics::PixelFormat> OSystem_DS::getSupportedFormats() const {
 
 void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
 	Graphics::PixelFormat actualFormat = format ? *format : _pfCLUT8;
-	_framebuffer.create(width, height, actualFormat);
+	bool isRGB = (actualFormat != _pfCLUT8), swScale = ((_graphicsMode == GFX_SWSCALE) && (width == 320));
 
 	// For Lost in Time, the title screen is displayed in 640x400.
 	// In order to support this game, the screen mode is set, but
 	// all draw calls are ignored until the game switches to 320x200.
-	if ((width == 640) && (height == 400)) {
-		_graphicsEnable = false;
+	if (_framebuffer.getRequiredVRAM(width, height, isRGB, swScale) > 0x40000) {
+		_framebuffer.create(width, height, isRGB);
 	} else {
-		_graphicsEnable = true;
-		DS::setGameSize(width, height, (actualFormat != _pfCLUT8));
+		_framebuffer.reset();
+		_framebuffer.create(width, height, isRGB, 3, false, 8, swScale);
+		DS::setGameSize(width, height);
 	}
+
+#ifdef DISABLE_TEXT_CONSOLE
+	if (_framebuffer.getRequiredVRAM(width, height, isRGB, false) > 0x20000) {
+		_subScreen.init(&_framebuffer);
+	} else {
+		_subScreen.reset();
+		_subScreen.init(&_framebuffer, 3, true, 0, false);
+	}
+#endif
 }
 
 int16 OSystem_DS::getHeight() {
@@ -485,37 +487,6 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 	_framebuffer.copyRectToSurface(buf, pitch, x, y, w, h);
 }
 
-void OSystem_DS::dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
-                         const uint w, const uint h, const uint bytesPerPixel) {
-	// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
-	// to save a few pennies/euro cents on the hardware.
-
-	uint row = w * bytesPerPixel;
-
-	for (uint dy = 0; dy < h; dy += 2) {
-		const u16 *src1 = src;
-		src += (srcPitch >> 1);
-		DC_FlushRange(src1, row << 1);
-
-		const u16 *src2 = src;
-		src += (srcPitch >> 1);
-		DC_FlushRange(src2, row << 1);
-
-		u16 *dest1 = dst;
-		dst += (dstPitch >> 1);
-		DC_FlushRange(dest1, row << 1);
-
-		u16 *dest2 = dst;
-		dst += (dstPitch >> 1);
-		DC_FlushRange(dest2, row << 1);
-
-		dmaCopyHalfWordsAsynch(2, src1, dest1, row);
-		dmaCopyHalfWordsAsynch(3, src2, dest2, row);
-
-		while (dmaBusy(2) || dmaBusy(3));
-	}
-}
-
 void OSystem_DS::updateScreen() {
 	oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
 	       SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
@@ -523,34 +494,11 @@ void OSystem_DS::updateScreen() {
 
 	if (_overlay.isVisible()) {
 		_overlay.update();
-	} else if (_graphicsEnable) {
-		u16 *base = BG_GFX + 0x10000;
-		if (_graphicsMode == GFX_SWSCALE) {
-			if (_framebuffer.format == _pfCLUT8) {
-				Rescale_320x256xPAL8_To_256x256x1555(
-					base,
-					(const u8 *)_framebuffer.getPixels(),
-					256,
-					_framebuffer.pitch,
-					BG_PALETTE,
-					_framebuffer.h );
-			} else {
-				Rescale_320x256x1555_To_256x256x1555(
-					base,
-					(const u16 *)_framebuffer.getPixels(),
-					256,
-					_framebuffer.pitch / 2 );
-			}
-		} else {
-			dmaBlit(base, 512 * _framebuffer.format.bytesPerPixel,
-				(const u16 *)_framebuffer.getPixels(), _framebuffer.pitch,
-				_framebuffer.w, _framebuffer.h, _framebuffer.format.bytesPerPixel);
-
+	} else {
+		_framebuffer.update();
 #ifdef DISABLE_TEXT_CONSOLE
-			if (_framebuffer.format == _pfCLUT8)
-				dmaCopy(base, BG_GFX_SUB, 512 * 256);
+		_subScreen.update();
 #endif
-		}
 	}
 }
 
diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index 0473971704..2c6b265c14 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -45,9 +45,8 @@
 OSystem_DS *OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
-	: _eventSource(NULL), _isOverlayShown(true),
+	: _eventSource(NULL), _disableCursorPalette(true),
 	_graphicsMode(GFX_HWSCALE), _stretchMode(100),
-	_disableCursorPalette(true), _graphicsEnable(true),
 	_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
 	_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)),
 	_callbackTimer(10), _currentTimeMillis(0)
@@ -130,18 +129,6 @@ void OSystem_DS::getTimeAndDate(TimeDate &td) const {
 void OSystem_DS::quit() {
 }
 
-void OSystem_DS::engineInit() {
-#ifdef DISABLE_TEXT_CONSOLE
-	videoBgEnableSub(3);
-#endif
-}
-
-void OSystem_DS::engineDone() {
-#ifdef DISABLE_TEXT_CONSOLE
-	videoBgDisableSub(3);
-#endif
-}
-
 void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
 #ifndef DISABLE_TEXT_CONSOLE
 	printf("%s", message);
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index f257545cda..cc3351fcbc 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -39,9 +39,11 @@ enum {
 
 class OSystem_DS : public ModularMutexBackend, public ModularMixerBackend, public PaletteManager {
 protected:
-	DS::Background _overlay;
-	Graphics::Surface _framebuffer, _cursor;
-	bool _graphicsEnable, _isOverlayShown;
+	DS::Background _framebuffer, _overlay;
+#ifdef DISABLE_TEXT_CONSOLE
+	DS::Background _subScreen;
+#endif
+	Graphics::Surface _cursor;
 	int _graphicsMode, _stretchMode;
 
 	static OSystem_DS *_instance;
@@ -60,9 +62,6 @@ protected:
 
 	void initGraphics();
 
-	void dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
-	             const uint w, const uint h, const uint bytesPerPixel);
-
 	bool _disableCursorPalette;
 
 	const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
@@ -138,9 +137,6 @@ public:
 	virtual void setFocusRectangle(const Common::Rect& rect);
 	virtual void clearFocusRectangle();
 
-	virtual void engineInit();
-	virtual void engineDone();
-
 	virtual void initBackend();
 
 	virtual Graphics::Surface *lockScreen();


Commit: e3fabc803b2a456e9b5f8f89c1e982b1f6ead949
    https://github.com/scummvm/scummvm/commit/e3fabc803b2a456e9b5f8f89c1e982b1f6ead949
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Only update the palette and cursor when updateScreen() is called

Changed paths:
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ds/osystem_ds.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index 1404882cd2..3298606c00 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -265,10 +265,6 @@ void setTalkPos(int x, int y) {
 void initHardware() {
 	powerOn(POWER_ALL);
 
-	for (int r = 0; r < 255; r++) {
-		BG_PALETTE[r] = 0;
-	}
-
 	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
 	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
 	vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
@@ -316,7 +312,7 @@ bool OSystem_DS::hasFeature(Feature f) {
 void OSystem_DS::setFeatureState(Feature f, bool enable) {
 	if (f == kFeatureCursorPalette) {
 		_disableCursorPalette = !enable;
-		refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
+		_cursorDirty = true;
 	}
 }
 
@@ -433,25 +429,13 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
 		int green = *(colors + 1);
 		int blue = *(colors + 2);
 
-		red >>= 3;
-		green >>= 3;
-		blue >>= 3;
-
-		{
-			u16 paletteValue = red | (green << 5) | (blue << 10);
-
-			if (!_overlay.isVisible()) {
-				BG_PALETTE[r] = paletteValue;
-#ifdef DISABLE_TEXT_CONSOLE
-				BG_PALETTE_SUB[r] = paletteValue;
-#endif
-			}
-
-			_palette[r] = paletteValue;
-		}
-
+		_palette[r] = RGB8(red, green, blue);
 		colors += 3;
 	}
+
+	_paletteDirty = true;
+	if (_disableCursorPalette)
+		_cursorDirty = true;
 }
 
 void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
@@ -461,25 +445,19 @@ void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
 		int green = *(colors + 1);
 		int blue = *(colors + 2);
 
-		red >>= 3;
-		green >>= 3;
-		blue >>= 3;
-
-		u16 paletteValue = red | (green << 5) | (blue << 10);
-		_cursorPalette[r] = paletteValue;
-
+		_cursorPalette[r] = RGB8(red, green, blue);
 		colors += 3;
 	}
 
 	_disableCursorPalette = false;
-	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
+	_cursorDirty = true;
 }
 
 void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) const {
 	for (unsigned int r = start; r < start + num; r++) {
-		*colors++ = (BG_PALETTE[r] & 0x001F) << 3;
-		*colors++ = (BG_PALETTE[r] & 0x03E0) >> 5 << 3;
-		*colors++ = (BG_PALETTE[r] & 0x7C00) >> 10 << 3;
+		*colors++ = (_palette[r] & 0x001F) << 3;
+		*colors++ = (_palette[r] & 0x03E0) >> 5 << 3;
+		*colors++ = (_palette[r] & 0x7C00) >> 10 << 3;
 	}
 }
 
@@ -488,6 +466,10 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 }
 
 void OSystem_DS::updateScreen() {
+	if (_cursorDirty) {
+		refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
+		_cursorDirty = false;
+	}
 	oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
 	       SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
 	oamUpdate(&oamMain);
@@ -495,6 +477,14 @@ void OSystem_DS::updateScreen() {
 	if (_overlay.isVisible()) {
 		_overlay.update();
 	} else {
+		if (_paletteDirty) {
+			dmaCopyHalfWords(3, _palette, BG_PALETTE, 256 * 2);
+#ifdef DISABLE_TEXT_CONSOLE
+			dmaCopyHalfWords(3, _palette, BG_PALETTE_SUB, 256 * 2);
+#endif
+			_paletteDirty = false;
+		}
+
 		_framebuffer.update();
 #ifdef DISABLE_TEXT_CONSOLE
 		_subScreen.update();
@@ -583,7 +573,7 @@ void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, i
 		_cursor.convertToInPlace(_pfABGR1555);
 	}
 
-	refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
+	_cursorDirty = true;
 }
 
 void OSystem_DS::refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette) {
diff --git a/backends/platform/ds/osystem_ds.cpp b/backends/platform/ds/osystem_ds.cpp
index 2c6b265c14..4a958e4b32 100644
--- a/backends/platform/ds/osystem_ds.cpp
+++ b/backends/platform/ds/osystem_ds.cpp
@@ -47,6 +47,7 @@ OSystem_DS *OSystem_DS::_instance = NULL;
 OSystem_DS::OSystem_DS()
 	: _eventSource(NULL), _disableCursorPalette(true),
 	_graphicsMode(GFX_HWSCALE), _stretchMode(100),
+	_paletteDirty(false), _cursorDirty(false),
 	_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
 	_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)),
 	_callbackTimer(10), _currentTimeMillis(0)
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index cc3351fcbc..77f6c83a1d 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -45,6 +45,7 @@ protected:
 #endif
 	Graphics::Surface _cursor;
 	int _graphicsMode, _stretchMode;
+	bool _paletteDirty, _cursorDirty;
 
 	static OSystem_DS *_instance;
 


Commit: 521303b2efe8171d09096e9649d080789258b6c7
    https://github.com/scummvm/scummvm/commit/521303b2efe8171d09096e9649d080789258b6c7
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Handle scaling and scrolling in the Background class

Changed paths:
    backends/platform/ds/background.cpp
    backends/platform/ds/background.h
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ds/osystem_ds.h


diff --git a/backends/platform/ds/background.cpp b/backends/platform/ds/background.cpp
index 606aaf4549..155a21ac41 100644
--- a/backends/platform/ds/background.cpp
+++ b/backends/platform/ds/background.cpp
@@ -29,6 +29,7 @@ namespace DS {
 
 Background::Background() :
 	_bg(-1), _visible(true), _swScale(false),
+	_scaleX(1 << 8), _scaleY(1 << 8), _scrollX(0), _scrollY(0),
 	_realPitch(0), _realHeight(0),
 	_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
 	_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)) {
@@ -100,6 +101,10 @@ void Background::create(uint16 width, uint16 height, bool isRGB) {
 	Surface::create(width, height, f);
 	_bg = -1;
 	_swScale = false;
+	_scaleX = 1 << 8;
+	_scaleY = 1 << 8;
+	_scrollX = 0;
+	_scrollY = 0;
 }
 
 void Background::create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase, bool swScale) {
@@ -116,12 +121,20 @@ void Background::create(uint16 width, uint16 height, bool isRGB, int layer, bool
 	}
 
 	_swScale = swScale;
+	_scaleX = 1 << 8;
+	_scaleY = 1 << 8;
+	_scrollX = 0;
+	_scrollY = 0;
 }
 
 void Background::init(Background *surface) {
 	Surface::init(surface->w, surface->h, surface->pitch, surface->pixels, surface->format);
 	_bg = -1;
 	_swScale = false;
+	_scaleX = 1 << 8;
+	_scaleY = 1 << 8;
+	_scrollX = 0;
+	_scrollY = 0;
 }
 
 void Background::init(Background *surface, int layer, bool isSub, int mapBase, bool swScale) {
@@ -138,6 +151,10 @@ void Background::init(Background *surface, int layer, bool isSub, int mapBase, b
 	}
 
 	_swScale = swScale;
+	_scaleX = 1 << 8;
+	_scaleY = 1 << 8;
+	_scrollX = 0;
+	_scrollY = 0;
 }
 
 static void dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
@@ -214,4 +231,34 @@ void Background::hide() {
 	_visible = false;
 }
 
+void Background::setScalef(int32 sx, int32 sy) {
+	if (_bg < 0 || (_scaleX == sx && _scaleY == sy))
+			return;
+
+	bgSetScale(_bg, _swScale ? 256 : sx, sy);
+	_scaleX = sx;
+	_scaleY = sy;
+}
+
+void Background::setScrollf(int32 x, int32 y) {
+	if (_bg < 0 || (_scrollX == x && _scrollY == y))
+			return;
+
+	bgSetScrollf(_bg, x, y);
+	_scrollX = x;
+	_scrollY = y;
+}
+
+Common::Point Background::realToScaled(int16 x, int16 y) {
+	x = CLIP<int16>(((x * _scaleX) + _scrollX) >> 8, 0, w  - 1);
+	y = CLIP<int16>(((y * _scaleY) + _scrollY) >> 8, 0, h - 1);
+	return Common::Point(x, y);
+}
+
+Common::Point Background::scaledToReal(int16 x, int16 y) {
+	x = ((x << 8) - _scrollX) / _scaleX;
+	y = ((y << 8) - _scrollY) / _scaleY;
+	return Common::Point(x, y);
+}
+
 } // End of namespace DS
diff --git a/backends/platform/ds/background.h b/backends/platform/ds/background.h
index c64e0f89a9..18b12d3ab7 100644
--- a/backends/platform/ds/background.h
+++ b/backends/platform/ds/background.h
@@ -24,6 +24,7 @@
 #define DS_BACKGROUND_H
 
 #include "graphics/surface.h"
+#include "common/rect.h"
 
 namespace DS {
 
@@ -44,6 +45,14 @@ public:
 	void hide();
 	inline bool isVisible() const { return _visible; }
 
+	void setScalef(int32 sx, int32 sy);
+	inline void setScale(int sx, int sy) { setScalef(sx << 8, sy << 8); }
+	void setScrollf(int32 x, int32 y);
+	inline void setScroll(int x, int y) { setScrollf(x << 8, y << 8); }
+
+	Common::Point realToScaled(int16 x, int16 y);
+	Common::Point scaledToReal(int16 x, int16 y);
+
 	inline void clear() {
 		memset(getPixels(), 0, pitch * h);
 	}
@@ -60,6 +69,7 @@ protected:
 	bool _visible, _swScale;
 	uint16 _realPitch, _realHeight;
 	const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
+	int32 _scrollX, _scrollY, _scaleX, _scaleY;
 };
 
 } // End of namespace DS
diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index 3298606c00..4a54f75ec8 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -46,23 +46,14 @@ static int subScreenWidth = SCUMM_GAME_WIDTH;
 static int subScreenHeight = SCUMM_GAME_HEIGHT;
 static int subScreenScale = 256;
 
-static bool gameScreenSwap = false;
-
 // Shake
 static int s_shakeXOffset = 0;
 static int s_shakeYOffset = 0;
 
-// Touch
-static int touchScX, touchScY, touchX, touchY;
-
 // 8-bit surface size
 static int gameWidth = 320;
 static int gameHeight = 200;
 
-void setGameScreenSwap(bool enable) {
-	gameScreenSwap = enable;
-}
-
 void setTopScreenZoom(int percentage) {
 	s32 scale = (percentage << 8) / 100;
 	subScreenScale = (256 * 256) / scale;
@@ -85,26 +76,7 @@ void setTopScreenTarget(int x, int y) {
 void setGameSize(int width, int height) {
 	gameWidth = width;
 	gameHeight = height;
-
-	if (g_system->getGraphicsMode() == GFX_SWSCALE) {
-		REG_BG3PA = 256;
-		REG_BG3PB = 0;
-		REG_BG3PC = 0;
-		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
-
-	} else {
-		REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
-		REG_BG3PB = 0;
-		REG_BG3PC = 0;
-		REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
-	}
-
-#ifdef DISABLE_TEXT_CONSOLE
-	REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
-	REG_BG3PB_SUB = 0;
-	REG_BG3PC_SUB = 0;
-	REG_BG3PD_SUB = (int) (subScreenHeight / 192.0f * 256);
-#endif
+	setTopScreenTarget(width / 2, height / 2);
 }
 
 void setShakePos(int shakeXOffset, int shakeYOffset) {
@@ -112,86 +84,6 @@ void setShakePos(int shakeXOffset, int shakeYOffset) {
 	s_shakeYOffset = shakeYOffset;
 }
 
-Common::Point warpMouse(int penX, int penY, bool isOverlayShown) {
-	int storedMouseX, storedMouseY;
-	if (!isOverlayShown) {
-		storedMouseX = ((penX - touchX) << 8) / touchScX;
-		storedMouseY = ((penY - touchY) << 8) / touchScY;
-	} else {
-		storedMouseX = penX;
-		storedMouseY = penY;
-	}
-
-	return Common::Point(storedMouseX, storedMouseY);
-}
-
-void setMainScreenScroll(int x, int y) {
-		REG_BG3X = x;
-		REG_BG3Y = y;
-
-		if (!gameScreenSwap) {
-			touchX = x >> 8;
-			touchY = y >> 8;
-		}
-}
-
-void setMainScreenScale(int x, int y) {
-		if ((g_system->getGraphicsMode() == GFX_SWSCALE) && (x==320)) {
-			REG_BG3PA = 256;
-			REG_BG3PB = 0;
-			REG_BG3PC = 0;
-			REG_BG3PD = y;
-		} else {
-			REG_BG3PA = x;
-			REG_BG3PB = 0;
-			REG_BG3PC = 0;
-			REG_BG3PD = y;
-		}
-
-		if (!gameScreenSwap) {
-			touchScX = x;
-			touchScY = y;
-		}
-}
-
-void setZoomedScreenScroll(int x, int y, bool shake) {
-		if (gameScreenSwap) {
-			touchX = x >> 8;
-			touchY = y >> 8;
-		}
-
-#ifdef DISABLE_TEXT_CONSOLE
-		REG_BG3X_SUB = x;
-		REG_BG3Y_SUB = y;
-#endif
-}
-
-void setZoomedScreenScale(int x, int y) {
-		if (gameScreenSwap) {
-			touchScX = x;
-			touchScY = y;
-		}
-
-#ifdef DISABLE_TEXT_CONSOLE
-		REG_BG3PA_SUB = x;
-		REG_BG3PB_SUB = 0;
-		REG_BG3PC_SUB = 0;
-		REG_BG3PD_SUB = y;
-#endif
-}
-
-Common::Point transformPoint(uint16 x, uint16 y, bool isOverlayShown) {
-	if (!isOverlayShown) {
-		x = ((x * touchScX) >> 8) + touchX;
-		x = CLIP<uint16>(x, 0, gameWidth  - 1);
-
-		y = ((y * touchScY) >> 8) + touchY;
-		y = CLIP<uint16>(y, 0, gameHeight - 1);
-	}
-
-	return Common::Point(x, y);
-}
-
 void VBlankHandler(void) {
 	int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
 	int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
@@ -218,6 +110,7 @@ void VBlankHandler(void) {
 
 	subScX += (subScTargetX - subScX) >> 2;
 	subScY += (subScTargetY - subScY) >> 2;
+	OSystem_DS::instance()->setSubScreen(subScX, subScY, subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
 
 	if (g_system->getGraphicsMode() == GFX_NOSCALE) {
 		if (scX + 256 > gameWidth - 1) {
@@ -236,11 +129,7 @@ void VBlankHandler(void) {
 			scY = 0;
 		}
 
-		setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
-		setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
-
-		setMainScreenScroll((scX << 8) + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
-		setMainScreenScale(256, 256);		// 1:1 scale
+		OSystem_DS::instance()->setMainScreen((scX << 8) + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8), 256, 256);
 	} else {
 		if (scY > gameHeight - 192 - 1) {
 			scY = gameHeight - 192 - 1;
@@ -250,18 +139,10 @@ void VBlankHandler(void) {
 			scY = 0;
 		}
 
-		setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
-		setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
-
-		setMainScreenScroll(64 + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8));
-		setMainScreenScale(320, 256);		// 1:1 scale
+		OSystem_DS::instance()->setMainScreen(64 + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8), gameWidth, ((gameHeight * (256 << 8)) / 192) >> 8);
 	}
 }
 
-void setTalkPos(int x, int y) {
-	setTopScreenTarget(x, y);
-}
-
 void initHardware() {
 	powerOn(POWER_ALL);
 
@@ -305,6 +186,18 @@ void OSystem_DS::initGraphics() {
 	_overlay.create(256, 192, true, 2, false, 0, false);
 }
 
+void OSystem_DS::setMainScreen(int32 x, int32 y, int32 sx, int32 sy) {
+	_framebuffer.setScalef(sx, sy);
+	_framebuffer.setScrollf(x, y);
+}
+
+void OSystem_DS::setSubScreen(int32 x, int32 y, int32 sx, int32 sy) {
+#ifdef DISABLE_TEXT_CONSOLE
+	_subScreen.setScalef(sx, sy);
+	_subScreen.setScrollf(x, y);
+#endif
+}
+
 bool OSystem_DS::hasFeature(Feature f) {
 	return (f == kFeatureCursorPalette) || (f == kFeatureStretchMode);
 }
@@ -402,7 +295,6 @@ void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *
 	} else {
 		_framebuffer.reset();
 		_framebuffer.create(width, height, isRGB, 3, false, 8, swScale);
-		DS::setGameSize(width, height);
 	}
 
 #ifdef DISABLE_TEXT_CONSOLE
@@ -413,6 +305,8 @@ void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *
 		_subScreen.init(&_framebuffer, 3, true, 0, false);
 	}
 #endif
+
+	DS::setGameSize(width, height);
 }
 
 int16 OSystem_DS::getHeight() {
@@ -466,6 +360,9 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
 }
 
 void OSystem_DS::updateScreen() {
+	swiWaitForVBlank();
+	bgUpdate();
+
 	if (_cursorDirty) {
 		refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
 		_cursorDirty = false;
@@ -499,17 +396,10 @@ void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
 void OSystem_DS::showOverlay() {
 	_overlay.reset();
 	_overlay.show();
-	lcdMainOnBottom();
 }
 
 void OSystem_DS::hideOverlay() {
 	_overlay.hide();
-
-	if (DS::gameScreenSwap) {
-		lcdMainOnTop();
-	} else {
-		lcdMainOnBottom();
-	}
 }
 
 bool OSystem_DS::isOverlayVisible() const {
@@ -540,8 +430,11 @@ Graphics::PixelFormat OSystem_DS::getOverlayFormat() const {
 	return _overlay.format;
 }
 
-Common::Point OSystem_DS::transformPoint(uint16 x, uint16 y) {
-	return DS::transformPoint(x, y, _overlay.isVisible());
+Common::Point OSystem_DS::transformPoint(int16 x, int16 y) {
+	if (_overlay.isVisible())
+		return Common::Point(x, y);
+	else
+		return _framebuffer.realToScaled(x, y);
 }
 
 bool OSystem_DS::showMouse(bool visible) {
@@ -551,7 +444,10 @@ bool OSystem_DS::showMouse(bool visible) {
 }
 
 void OSystem_DS::warpMouse(int x, int y) {
-	_cursorPos = DS::warpMouse(x, y, _overlay.isVisible());
+	if (_overlay.isVisible())
+		_cursorPos = Common::Point(x, y);
+	else
+		_cursorPos = _framebuffer.scaledToReal(x, y);
 }
 
 void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
@@ -614,7 +510,7 @@ void OSystem_DS::unlockScreen() {
 }
 
 void OSystem_DS::setFocusRectangle(const Common::Rect& rect) {
-	DS::setTalkPos(rect.left + rect.width() / 2, rect.top + rect.height() / 2);
+	DS::setTopScreenTarget(rect.left + rect.width() / 2, rect.top + rect.height() / 2);
 }
 
 void OSystem_DS::clearFocusRectangle() {
diff --git a/backends/platform/ds/osystem_ds.h b/backends/platform/ds/osystem_ds.h
index 77f6c83a1d..c0672a379d 100644
--- a/backends/platform/ds/osystem_ds.h
+++ b/backends/platform/ds/osystem_ds.h
@@ -115,7 +115,7 @@ public:
 	virtual int16 getOverlayWidth();
 	virtual Graphics::PixelFormat getOverlayFormat() const;
 
-	Common::Point transformPoint(uint16 x, uint16 y);
+	Common::Point transformPoint(int16 x, int16 y);
 	virtual bool showMouse(bool visible);
 
 	virtual void warpMouse(int x, int y);
@@ -149,6 +149,9 @@ public:
 
 	virtual void logMessage(LogMessageType::Type type, const char *message);
 
+	void setMainScreen(int32 x, int32 y, int32 sx, int32 sy);
+	void setSubScreen(int32 x, int32 y, int32 sx, int32 sy);
+
 	int _currentTimeMillis, _callbackTimer;
 };
 


Commit: f50b472840c7af7baf2242bbf40471d8d458afcb
    https://github.com/scummvm/scummvm/commit/f50b472840c7af7baf2242bbf40471d8d458afcb
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Load the selected theme on startup

Changed paths:
    gui/gui-manager.cpp


diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index dc6ad96e77..751a72dc48 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -93,14 +93,6 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), _stateIsSaved(false),
 	ConfMan.registerDefault("gui_renderer", ThemeEngine::findModeConfigName(ThemeEngine::_defaultRendererMode));
 	ThemeEngine::GraphicsMode gfxMode = (ThemeEngine::GraphicsMode)ThemeEngine::findMode(ConfMan.get("gui_renderer"));
 
-#ifdef __DS__
-	// Searching for the theme file takes ~10 seconds on the DS.
-	// Disable this search here because external themes are not supported.
-	if (!loadNewTheme("builtin", gfxMode)) {
-		// Loading the built-in theme failed as well. Bail out
-		error("Failed to load any GUI theme, aborting");
-	}
-#else
 	// Try to load the theme
 	if (!loadNewTheme(themefile, gfxMode)) {
 		// Loading the theme failed, try to load the built-in theme
@@ -109,7 +101,6 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), _stateIsSaved(false),
 			error("Failed to load any GUI theme, aborting");
 		}
 	}
-#endif
 }
 
 GuiManager::~GuiManager() {


Commit: 2c1148791fd73132f78074520d2faaaecafbfdb7
    https://github.com/scummvm/scummvm/commit/2c1148791fd73132f78074520d2faaaecafbfdb7
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Replace the default assert function with sassert

Changed paths:
    backends/platform/ds/portdefs.h


diff --git a/backends/platform/ds/portdefs.h b/backends/platform/ds/portdefs.h
index 148e3dc0f2..aac647cf63 100644
--- a/backends/platform/ds/portdefs.h
+++ b/backends/platform/ds/portdefs.h
@@ -42,6 +42,10 @@ typedef unsigned int uint;
 #include <math.h>
 #include <new>
 
+#include <nds/arm9/sassert.h>
+#undef assert
+#define assert(e) sassert(e, " ")
+
 #define double float
 
 #ifndef DISABLE_COMMAND_LINE


Commit: ebb13066309924010290f910baa1c30721c1f781
    https://github.com/scummvm/scummvm/commit/ebb13066309924010290f910baa1c30721c1f781
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Update configure

Changed paths:
    configure


diff --git a/configure b/configure
index cb80821756..7459c26bf5 100755
--- a/configure
+++ b/configure
@@ -3399,6 +3399,12 @@ if test -n "$_host"; then
 			_port_mk="backends/platform/dc/dreamcast.mk"
 			;;
 		ds)
+			if test "$_dynamic_modules" = yes ; then
+				_detection_features_static=no
+				_plugins_default=dynamic
+			else
+				_detection_features_full=no
+			fi
 			if test "$_debug_build" != yes; then
 				append_var DEFINES "-DDISABLE_TEXT_CONSOLE"
 			fi
@@ -3417,6 +3423,8 @@ if test -n "$_host"; then
 			_tinygl=no
 			_bink=no
 			_lua=no
+			_png=no
+			_freetype2=no
 			_port_mk="backends/platform/ds/ds.mk"
 			;;
 		gamecube)


Commit: 78015cbd04f095203ae0fa697cf76396ab6e1774
    https://github.com/scummvm/scummvm/commit/78015cbd04f095203ae0fa697cf76396ab6e1774
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
TESTBED: Centre the rectangle on screen in the overlay test

This fixes an assert in the DS port due to the rectangle being drawn out of bounds.

Changed paths:
    engines/testbed/graphics.cpp


diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp
index 6690c87067..13cf59bb64 100644
--- a/engines/testbed/graphics.cpp
+++ b/engines/testbed/graphics.cpp
@@ -1082,6 +1082,8 @@ TestExitStatus GFXtests::overlayGraphics() {
 		return kTestSkipped;
 	}
 
+	int16 w = g_system->getOverlayWidth();
+	int16 h = g_system->getOverlayHeight();
 	Graphics::PixelFormat pf = g_system->getOverlayFormat();
 
 	byte *buffer = new byte[50 * 100 * pf.bytesPerPixel];
@@ -1102,7 +1104,7 @@ TestExitStatus GFXtests::overlayGraphics() {
 	}
 
 	g_system->showOverlay();
-	g_system->copyRectToOverlay(buffer, 100 * pf.bytesPerPixel, 270, 175, 100, 50);
+	g_system->copyRectToOverlay(buffer, 100 * pf.bytesPerPixel, (w - 100) / 2, (h - 50) / 2, 100, 50);
 	g_system->updateScreen();
 
 	delete[] buffer;


Commit: 2ea22a451c84f173c07b730958ab31f33913cbb6
    https://github.com/scummvm/scummvm/commit/2ea22a451c84f173c07b730958ab31f33913cbb6
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Ensure that a mouse move event is sent before a mouse down event

Changed paths:
    backends/events/ds/ds-events.cpp


diff --git a/backends/events/ds/ds-events.cpp b/backends/events/ds/ds-events.cpp
index d1ec31aa04..4f2ee92f68 100644
--- a/backends/events/ds/ds-events.cpp
+++ b/backends/events/ds/ds-events.cpp
@@ -71,12 +71,13 @@ void DSEventSource::addEventsToQueue() {
 		touchRead(&touchPos);
 		event.mouse = dynamic_cast<OSystem_DS *>(g_system)->transformPoint(touchPos.px, touchPos.py);
 
+		if (event.mouse.x != _lastTouch.x || event.mouse.y != _lastTouch.y) {
+			event.type = Common::EVENT_MOUSEMOVE;
+			_eventQueue.push(event);
+		}
 		if (keysPressed & KEY_TOUCH) {
 			event.type = Common::EVENT_LBUTTONDOWN;
 			_eventQueue.push(event);
-		} else if (event.mouse.x != _lastTouch.x || event.mouse.y != _lastTouch.y) {
-			event.type = Common::EVENT_MOUSEMOVE;
-			_eventQueue.push(event);
 		}
 
 		_lastTouch = event.mouse;


Commit: 72703a8d0a496f46bbc8d13a507df483cb0c8049
    https://github.com/scummvm/scummvm/commit/72703a8d0a496f46bbc8d13a507df483cb0c8049
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DS: Disable the ARM assembler code for now

Changed paths:
    configure


diff --git a/configure b/configure
index 7459c26bf5..a94dc80826 100755
--- a/configure
+++ b/configure
@@ -2638,7 +2638,7 @@ case $_host_cpu in
 			openpandora)
 				define_in_config_if_yes yes 'USE_ARM_NEON_ASPECT_CORRECTOR'
 				;;
-			androidsdl-armeabi | arm-*riscos | caanoo | ds | gp2x | gp2xwiz | maemo )
+			androidsdl-armeabi | arm-*riscos | caanoo | gp2x | gp2xwiz | maemo )
 				define_in_config_if_yes yes 'USE_ARM_SCALER_ASM'
 				# FIXME: The following feature exhibits a bug. It produces distorted
 				# sound since 9003ce517ff9906b0288f9f7c02197fd091d4554. The ARM


Commit: 4300571cf8f8a6d66237f7a24240e227ca1fe264
    https://github.com/scummvm/scummvm/commit/4300571cf8f8a6d66237f7a24240e227ca1fe264
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2021-02-04T01:59:14+01:00

Commit Message:
DOCS: First draft DS page

This replaces the old port-specific README file.

Changed paths:
  A doc/docportal/other_platforms/nintendo_ds.rst
  R backends/platform/ds/readme_ds.txt


diff --git a/backends/platform/ds/readme_ds.txt b/backends/platform/ds/readme_ds.txt
deleted file mode 100644
index 48242e7b84..0000000000
--- a/backends/platform/ds/readme_ds.txt
+++ /dev/null
@@ -1,862 +0,0 @@
-
-
-
-                    The official port of ScummVM
-                 to the Nintendo DS handheld console
-                     by Neil Millstone (agentq)
-                   http://scummvm.drunkencoders.com
-------------------------------------------------------------------------
-Visit the main ScummVM website <https://www.scummvm.org>
-
-
-
-
-     Contents
-     ------------------------------------------------------------------------
-
-
-
-    * What's New?
-    * What is ScummVM DS?
-    * Features
-    * Screenshots
-    * How to Get ScummVM DS Onto Your DS - Simple Explanation
-          o Using a CF/SD/Mini SD/Micro SD card reader and a DLDI driver
-          o Instructions for specific card readers
-    * How to use ScummVM DS
-    * Game Specific Controls
-    * DS Options Screen
-    * Which games are compatible with ScummVM DS
-    * Predictive dictionary for Sierra AGI games
-    * Converting your CD audio
-    * Converting speech to MP3 format
-    * Frequently Asked Questions
-    * Downloads
-    * Contributors
-    * Donations and Getting Help
-    * Building from Sources
-
-
-
-      What's New?
-      ------------------------------------------------------------------------
-
-ScummVM DS 1.2.0
-
- * New game supported: Fascination
-
-ScummVM DS 1.1.1
-
- * Bugfix release: no new features
-
-ScummVM DS 1.1.0
-
- * New games are supported in this stable build: Return to Zork, Rodney's
-   Funscreen, Manhole, Leather Goddess of Phobos 2, Cruise for a Corpse.
-
-ScummVM DS 1.0.0
-
- * No changes!
-
-ScummVM DS 1.0.0 RC1
-
- * Gamma correction feature to improve brightness level of game on the
-   original DS.
- * The usual round of bugfixes
-
-
-ScummVM DS 0.13.1
-
- * Support for the ScummVM Global Main Menu (hold select during the game)
- * The usual round of bugfixes
-
-
-ScummVM DS 0.12.0
-
- * New games supported: Lure of the Temptress, Nippon Safes, Lost in Time.
- * New laptop-style trackpad input method.  Uses relative movement when you
-   drag on the touch screen.
- * New option which allows you to drag to hover, tap the touch screen to
-   click, and double tap the screen to right click.
- * Reorganised DS Options screen into three tabs for clearer navigation
- * New top screen scaling options let you choose the scaling factor used
-   on startup.
- * The usual round of bug fixes.
-
-
-ScummVM DS 0.11.1
-
- * Bugfix release - No new DS port features
-
-
-ScummVM DS 0.11.0
-
- * New games supported: Elvira 1 and 2, Waxworks (Amiga version)
- * Software scaler for improved image quality. Turn it on using the DS options
-   screen (press select during the game). Thanks to Tramboi and Robin Watts for
-   this feature!
- * Function keys added to virtual keyboard (used in AGI games)
- * Plenty of bug fixes
-
-      What is ScummVM DS?
-      ------------------------------------------------------------------------
-
-ScummVM DS is a part of the ScummVM project.  The ScummVM project is an
-attempt to re-engineer many classic point and click adventure games of the
-80s and 90s to run on modern computer hardware.  Technology has changed a
-lot since these games were written, and so ScummVM attempts to replicate the
-gameplay of the original games in exacting details, without any of the original
-code that the game ran on.  ScummVM needs a copy of the original game, in order
-to take the graphics, sound, and scripts that made the game work.
-
-ScummVM is written in such a way that it can be 'ported' from one type of
-machine to another, and ScummVM DS is a port of ScummVM to the Nintendo DS
-handheld games console.
-
-
-      Features
-      ------------------------------------------------------------------------
-
-    * Runs nearly all of Lucasarts' SCUMM games up to and including Sam
-      & Max Hit the Road
-    * Runs many non-Lucasarts point-and-click adventures too
-    * Supports sound
-    * Provides a GUI to change settings and choose games
-    * Supports using the DS touch screen for controls
-    * Suports saving games to compatible flash cards
-    * All games run at pretty much full speed
-
-
-
-
-
-      How to Get ScummVM DS Onto Your DS - Simple Explanation
-      ------------------------------------------------------------------------
-
-Nintendo don't want you to run ScummVM on your DS.  They control
-which companies can make games on the DS, and there is an expensive
-process to go through in order to be licenced.  Having to pay for
-this would prevent me from giving away ScummVM for free.
-
-So, the result is that to run ScummVM on your DS you'll need an
-unofficial card reader.  There are many of these, and all are different.
-Popular models at the time of writing are the R4DS and the M3DS Real,
-but many different models work.  You need to buy one of these, and at
-MicroSD card to go with it.
-
-There are also slot-2 card readers which fit into the bottom slot on
-your DS, usually used for Game Boy Advance games.  These are less common
-these days, and although they have certain advantages, the details of
-these are beyond the scope of this website.  Information on these is
-quite easy to find by searching.
-
-Once you have your card reader and a MicroSD card, you will also need
-a copy of the game you want to run.  ScummVM can run a large variety
-of games, but you must own a real boxed copy of the game.  These games
-are still under copyright, and it is illegal to copy them from a friend
-or download them from the Internet without paying.  The exception to
-this are the three Revolution Software games.  These are 'Beneath a
-Steel Sky', 'Lure of the Temptress' and 'Flight of the Amazon Queen'.
-Revolution have kindly allowed us to give these games away for free.
-You can download them from the main ScummVM site at
-<https://www.scummvm.org/games/>
-
-If you have a modern card reader, like an M3 Real or R4DS, getting
-ScummVM to run on your card is as simple as:
- 1) Copy the scummvm NDS files on your MicroSD card using your
-    PC card reader
- 2) Copy the games you want to play onto your MicroSD card in any
-    location, one per folder
- 3) Boot the DS with the MicroSD card and card reader inserted
- 4) Run the relevent build for the game you want to play (see
-    'Which games are compatible with ScummVM DS' below.
- 5) Click 'Add Game'.  Select the folder where your game is stored.
-    Click 'OK'.  Click 'OK' in the settings dialog.
- 6) Click 'Start'.
-
-NOTE: Previous version of ScummVM DS supported a method which used a
-zip file to run games on unsupported flash card readers.  This method
-is no longer supported.
-
-
-
-      How to Get ScummVM DS Onto Your DS - Using a CF/SD/Mini SD/Micro
-      SD card reader and a DLDI driver
-      ------------------------------------------------------------------------
-
-ScummVM DS needs something called a DLDI driver to run on each make
-and model of card reader.  Many modern card readers (R4DS, M3 DS Real)
-handle this autmatically and for those, you don't have to do anything.
-Just running ScummVM on the card will handle this step for you.
-For others, you will need to follow the steps in this section before
-ScummVM DS will work.
-
-All DS card readers are different in the way that they work. In order to
-support many different card readers, ScummVM DS uses a DLDI driver installed
-into the ScummVM DS code. This is done using a program called DLDITool
-which you can download and run on your computer. Each DLDI driver is
-designed to tell ScummVM DS how to use a specific type of card reader.
-These drivers can be used with any homebrew program which supports the
-DLDI interface.
-
-While each card reader should work with these instructions, there are
-some exceptions. Please read the card reader notes
-section to see if there is any specific information about your card reader.
-
-Here is what you need to do:
-
-    * Visit the DLDI page <http://dldi.drunkencoders.com/> and
-      download the executable for DLDITool for your operating system
-      (versions are available for Windows, Linux, and MacOS)
-    * Download the DLDI for your card reader. This is the big table at
-      the top of the page. The first column marked DLDI is the one you
-      want. You should get a single file with a .dldi extension.
-    * Extract DLDITool into a folder, and put the DLDI of your choice in
-      the same folder.
-    * If you're using the command line version of DLDITool enter the
-      following at a command prompt:
-
-          dlditool <dldiname> <scummvm nds name>
-
-
-      If you're using the Windows GUI version, double click on
-      dlditool32.exe, select your card reader from the box, drag your
-      ScummVM binaries (either the .nds, or the .ds.gba version
-      depending on your card reader. I think only Supercards use the
-      .ds.gba files) into the lower box, then click patch.
-
-      Either way, you should see 'Patched Successfully'. If you don't,
-      you're doing something wrong.
-
-      You need to patch one of the builds labeled A - H depending on
-      which game you want to run. See the table on the ScummVM DS
-      website to see which games are supported by which build.
-
-    * Put the patched .nds or .ds.gba files on your flash card. If
-      you're using the Supercard, you will need to use the .ds.gba
-      files, but rename them to .nds.
-    * Put your game data in any folder on the card. Do NOT use a zip file.
-    * Boot up your DS and run ScummVM.
-    * Click 'Add Game', browse to the folder with your game data, click
-      'Choose', then 'OK'. Click 'Start' to run the game.
-
-If your copy of ScummVM DS has been successfully patched, you will get a
-message on the top screen that looks like this:
-
-        DLDI Device:
-        GBA Movie Player (Compact Flash)
-
-The message should show the name of your card reader. If it is wrong,
-you have used the wrong DLDI file.
-
-If you haven't patched your .nds file, you will get the following message
-
-        DLDI Driver not patched!
-        DLDI Initialise failed.
-
-In this case, you've made a mistake following the above instructions, or
-have patched the wrong file.
-
-You may also see the following message:
-
-        DLDI Device:
-        GBA Movie Player (Compact Flash)
-        DLDI Initialise failed.
-
-In this case, the driver did not start up correctly. The driver is
-probably broken, or you've used the wrong one for your card reader.
-
-In the case of the Supercard, M3 Lite and DS Link, there are several
-drivers available. You might want to try one of the others.
-
-This version of ScummVM DS will run on any card reader that has a DLDI
-driver available. If yours doesn't, you need to pressure your card
-reader manufacturer to release one.
-
-DO NOT EMAIL ME TO ASK ME TO CREATE A DRIVER FOR YOUR CARD READER, I
-CANNOT DO THIS.
-
-
-      How to Get ScummVM DS Onto Your DS - Instructions for specific
-      card readers
-      ------------------------------------------------------------------------
-
-    * *GBAMP CF:* You need to upload replacement firmware to your card
-      reader before it will work. You can download the firmware program
-      here <http://chishm.drunkencoders.com/NDSMP/index.html>. Name your
-      .nds file _BOOT_MP.nds.
-    * *M3 CF/SD:* Copy the .nds file to your card with the M3 Game
-      Manager in order to avoid an annoying message when you boot your
-      M3. Use the default options to copy the file. Be sure to press 'A'
-      in the M3 browser to start the .nds file, and not 'Start', or it
-      won't work.
-    * *M3 CF/SD:* Copy the .nds file to your card with the M3 Game
-      Manager in order to avoid an annoying message when you boot your
-      M3. Use the default options to copy the file. Be sure to press 'A'
-      in the M3 browser to start the .nds file, and not 'Start', or it
-      won't work.
-    * *Supercard CF/SD (slot-2):* Use the .ds.gba files to run ScummVM
-      on the Supercard. Other than that, just follow the instructions as
-      normal.
-    * *Supercard Lite (slot-2):* It has been reported that only the
-      standard Supercard driver and the Moonshell version work with
-      ScummVM DS.
-    * *Datel Max Media Dock: * If you haven't already, upgrade your
-      firmware to the latest version. The firmware that came with my Max
-      Media Dock was unable to run ScummVM DS at all. Click here to
-      visit Datel's support page and download the latest firmware
-      <http://us.codejunkies.com/mpds/support.htm>
-    * *NinjaDS*: There are firmware upgrades for this device, but for
-      me, ScummVM DS ran straight out of the box. Visit this page
-      <http://www.ninjads.com/news.html> to download the latest firmware
-      if you want. If you have installed FlashMe on your DS, it will
-      make your DS crash on boot when the NinjaDS is inserted. You can
-      hold the 'select' button during boot to disable FlashMe, which
-      will allow the NinjaDS to work. Due to this, it is not recommended
-      to install FlashMe if you use a NinjaDS.
-    * *R4DS*: If you upgrade the firmware for your R4DS to version 1.10
-      or later, the card will autmatically DLDI patch the game, meaning
-      you don't have to use dlditool to patch the .NDS file. This makes
-      things a lot easier!
-    * *M3DS Real*: This card autmatically DLDI patches the game, meaning
-      that you do not need to do this yourself.
-
-
-
-      Which games are compatible with ScummVM DS?
-      ------------------------------------------------------------------------
-
-I'm glad you asked. Here is a list of the compatible games in version
-1.2.0. Demo versions of the games listed should work too.
-
-Flight of the Amazon Queen, Beneath a Steel Sky, and Lure of the
-Temptress have generously been released as freeware by the original
-authors, Revolution Software <http://www.revolution.co.uk/>. This is a
-great thing and we should support Revolution for being so kind to us.
-You can download the game data from the official ScummVM download page
-<https://www.scummvm.org/games/>.
-
-The other games on this list are commercial, and still under copyright,
-which means downloading them without paying for it is illegal. You can
-probably find a second-hand copy on eBay. Please don't email me to ask
-for a copy, as I am unable to send it to you.
-
-Game                                      Build   Notes
-
-Manic Mansion                             A
-
-Zak McKracken and the Alien Mindbenders   A
-
-Indiana Jones and the Last Crusade        A
-
-Loom                                      A
-
-Passport to Adventure                     A
-
-The Secret of Monkey Island               A
-
-Monkey Island 2: LeChuck's Revenge        A
-
-Indiana Jones and the Fate of Atlantis    A
-
-Day of the Tentacle                       A
-
-Sam & Max Hit the Road                    A     Some slowdown in a few scenes
-                                                when MP3 audio is enabled
-
-Bear Stormin' (DOS)                       A
-
-Fatty Bear's Birthday Surprise (DOS)      A
-
-Fatty Bear's Fun Pack (DOS)               A
-
-Putt-Putt's Fun Pack (DOS)                A
-
-Putt-Putt Goes to the Moon (DOS)          A
-
-Putt-Putt Joins the Parade (DOS)          A     Can sometimes crash due to low memory
-
-Beneath a Steel Sky                       B
-
-Flight of the Amazon Queen                B
-
-Simon the Sorcerer 1                      C     Zoomed view does not follow the
-                                                speaking character
-Simon the Sorcerer 2                      C     Zoomed view does not follow the
-                                                speaking character
-Elvira 1                                  C
-
-Elvira 2                                  C
-
-Waxworks (Amiga version)                  C
-
-Gobliiins                                 D
-
-Gobliins 2                                D
-
-Goblins 3                                 D
-
-Fascination 				  D     This game is untested on the DS
-
-Ween: The Prophecy                        D
-
-Bargon Attack                             D
-
-Lost in Time                              D
-
-Future Wars                               D
-
-All Sierra AGI games.
-For a complete list, see this page
-<https://wiki.scummvm.org/index.php/AGI>  D
-
-Inherit the Earth                         E
-
-The Legend of Kyrandia                    F     Zoomed view does not follow the
-                                                speaking character
-
-Lure of the Temptress                     G
-
-Nippon Safes                              G
-
-Return to Zork                            I
-
-Leather Goddess of Phobos 2               I
-
-Manhole                                   I
-
-Rodney's Funscreen                        I
-
-Cruise for a Corpse                       K
-
-
-Full Throttle and The Dig can run on the DS using an external RAM pack
-plugged into slot-2 (the GBA slot).  To do this, download the special
-build of ScummVM DS from here: https://forums.scummvm.org/viewtopic.php?t=7044
-
-There is no support for Windows Humongous Entertainment games, Broken Sword,
-and all other games that run at 640x480 resolution.  The DS cannot cope with
-scaling these games down to 256x192, the resolution of the DS screens.
-
-
-      How to Use ScummVM
-      ------------------------------------------------------------------------
-
-Once you've booted up ScummVM, you'll see the start up screen.
-
- 1. Tap the 'Add' button with the pen, then browse to the folder
-    containing your game data. Once you have clicked on your folder, you will
-    not see any files inside.  This is normal, as the folder selector only shows
-    folders!
-
- 2. Click the 'Choose' button.
-
- 3. You will get some options for the game. You can usually just click 'Ok' to
-    this.
-
- 4. Now click on the name of the game you want to play from the list and
-    click 'Start'. Your game will start!
-
-You can use the B button to skip cutscenes, and the select button to
-show an options menu which will let you tweak the DS contols, including
-switch between scaled and unscaled video modes. The text is clearer in
-the unscaled mode, but the whole game doesn't fit on the screen. To
-scroll around, hold either shoulder button and use the D-pad or drag the
-screen around with the stylus. Even in scaled mode, a small amount is
-missing from the top and bottom of the screen. You can scroll around to
-see those areas. The top screen shows a zoomed-in view. This scrolls
-around to focus on the character who's speaking, and also follows where
-the pen touches the screen. You can change the zoom level by holding one
-of the shoulder buttons and pressing B to zoom in and A to zoom out.
-
-Press the start button for the in-game menu where you can load or save
-your game (this works in Lucasarts games, other games vary). Saves will
-write directly to your flash card. You can choose the folder where they
-are stored using the GUI that appears when you boot up. If you're using
-a GBA Flash Cartridge, or an unsupported flash card adaptor, you will be
-using GBA SRAM to save your game. Four or five save game will fit in
-save RAM. If you save more games than will fit, a warning will appear on
-the top screen. When you turn your DS off, the new save will be lost,
-and only the first ones you saved will be present.
-
-Many of the games use both mouse buttons. Usually the right button often
-performs the default action on any object you click on. To simulate this
-with the DS pen, you can switch the input into one of three modes. Press
-left on the D-pad to enable the left mouse button. Press right on the
-D-pad to enable the right mouse button. Press up on the D-pad to enable
-hover mode. In this mode, you won't click on anything, just hover the
-mouse cursor over it. This lets you pick out active objects in the
-scene.
-
-An icon on the top screen will show you which mode you're in.
-
-In hover mode, there are some additional controls. While holding the pen
-on the screen, tapping D-pad left or D-pad right (or A/Y in left handed
-mode) will click the left or right mouse button.
-
-There is an alternative method of control which doesn't require you to
-change modes with the D-pad.  Press 'Select' to bring up the DS options,
-and choose 'Tap for left click, double tap for right click'.  In this
-mode, you can quickly tap the screen to left click the mouse, and tap
-twice to right click the mouse.
-
-
-Here is a complete list of controls in right-handed mode (the default
-setting):
-Key                    Usage
-Pad Left               Left mouse button
-Pad Right              Right mouse button
-Pad Up                 Hover mouse (no mouse button)
-Pad Down               Skip dialogue line (for some Lucasarts games),
-                       Show inventory (for Beneath a Steel Sky), Show
-                       active objects (for Simon the Sorceror)
-Start                  Pause/game menu (works in some games)
-Select                 DS Options
-B                      Skip cutscenes
-A                      Swap main screen and zoomed screen
-Y                      Show/Hide debug console
-X                      Show/Hide on-screen keyboard
-L + D-pad or L + Pen   Scroll touch screen view
-L + B                  Zoom in
-L + A                  Zoom out
-
-
-
-And here's left-handed mode:
-Key                    Usage
-Y                      Left mouse button
-A                      Right mouse button
-X                      Hover mouse (no mouse button)
-B                      Skip dialogue line (for some Lucasarts games),
-                       Show inventory (for Beneath a Steel Sky), Show
-                       active objects (for Simon the Sorceror)
-Start                  Pause/game menu (works in some games)
-Select                 DS Options
-D-pad down             Skip cutscenes
-D-pad up               Swap main screen and zoomed screen
-D-pad left             Show/Hide debug console
-D-pad right            Show/Hide on-screen keyboard
-R + D-pad or R + Pen   Scroll touch screen view
-R + D-pad down         Zoom in
-R + d-pad right        Zoom out
-
-
-
-      Game-specific controls
-      ------------------------------------------------------------------------
-
-    * Sam and Max Hit the Road: The current cursor mode is displayed on
-      the top screen. Use d-pad right to switch mode.
-    * Indiana Jones games: If you get into a fight, press Select, and
-      check the box marked 'Use Indy Fighting Controls'.
-      Return to the game, then use the following controls to fight:
-
-      D-pad left: move left
-      D-pad right: move right
-      D-pad up: guard up
-      D-pad down: guard down
-      Y: guard middle
-      X: Punch high
-      A: Punch middle
-      B: Punch low
-      Left shoulder: Fight towards the left
-      Right shoulder: Fight towards the right
-
-      The icon on the top screen shows which way you're currently
-      facing. Remember to turn the option off when the fight ends, or
-      the normal controls won't work!
-    * Beneath a Steel Sky: Press D-pad down to show your inventory.
-    * Simon the Sorcerer 1/2: Press D-pad down to show active objects.
-    * AGI games: Press Start to show the menu bar.
-    * Bargon Attack: Press Start to hit F1 when you need to start the
-      game. Use the on-screen keyboard (hit X) to press other function keys.
-
-
-      DS Options Screen
-      ------------------------------------------------------------------------
-
-Pressing the 'select' button during any game to show the DS options
-screen.  This screen shows options specific to the Nintendo DS version
-of ScummVM.
-
-Controls tab
-
-Indy Fight Controls - Enable fighting controls for the Indiana Jones
-games.  See 'Game Specific Controls' for more information.
-
-Left handed Mode - Switch the controls on the D-pad with the controls
-on the A/B/X/Y buttons.
-
-Show mouse cursor - Shows the game's mouse cursor on the bottom screen.
-
-Snap to edges - makes it easier for the mouse controls to reach the edges
-of the screen.  Useful for Beneath a Steel Sky and Goblins 3.
-
-Touch X offset - if your screen doesn't perform properly, this setting
-allows you to adjust when the cursor appears left or right relative to
-the screen's measured touch position.
-
-Touch Y offset - if your screen doesn't perform properly, this setting
-allows you to adjust when the cursor appears higher or lower relative to
-the screen's measured touch position.
-
-Use Laptop Trackpad-style cursor control - In this mode, use the lower
-screen to drag the cursor around, a bit like using a trackpad on a laptop.
-When this option is enabled, the following option is also enabled.
-
-Tap for left click, double tap for right click - In this mode, you can
-quickly tap on the screen to left click the mouse, or quickly
-double tap on the screen to right click the mouse.  If you find clicking
-or double-clicking difficult, try and make a firmer touch on the screen,
-and keep the pen down for longer.
-
-Sensitivity - this bar adjusts the speed of cursor movement when laptop
-trackpad-style cursor control is enabled (see above).
-
-Graphics Tab
-
-Scaling options:
-
-Three scaling options are available for the main screen.
-
-Harware Scale - Scales using the DS hardware scaler using a flicker method.
-Produces lower quality graphics but doesn't slow the game down.
-
-Software Scale - Scales using the CPU.  A much higher quality image is
-produced, but at the expense of speed in some games.
-
-Unscaled - Allows you to see the graphics as originaly displayed.  This
-doesn't fit on the DS screen, but you can scroll the screen around by holding
-the left shoulder button and using the D-pad or touch screen.
-
-Top screen zoom - These three options control the zoom level of the top
-screen when ScummVM is started up.  Changing this option will set the zoom
-to the specified level immediately.
-
-Initial top screen scale:
-
-This option controls the scaling level of the zoomed screen.  In ScummVM
-DS, one screen shows a zoomed-in view of the action, and this option controls
-how zoomed in it is.  You can also adjust this in the game by holding L and
-pressing A/B.
-
-General Tab
-
-High Quality Audio - Enhance the sound quality, at the expense of some
-slowdown during some games.
-
-Disable power off - ScummVM DS turns the power off when the game quits.
-This option disables that feature.
-
-
-
-
-
-
-      Auto completion dictionary for Sierra AGI games
-      ------------------------------------------------------------------------
-
-If you are playing a Sierra AGI game, you will be using the on-screen
-keyboard quite a lot (press X to show it). To reduce the amount you have
-to type, the game can automatically complete long words for you. To use
-this feature, simply copy the PRED.DIC file from the ScummVM DS archive
-into your game folder on your card. Now, when you use the keyboard,
-possible words will be shown underneith it. To type one of those words,
-simply double click on it with your stylus.
-
-
-      Converting your CD audio
-      ------------------------------------------------------------------------
-
-ScummVM supports playing CD audio for specific games which came with
-music stored as standard music CD tracks. To use this music in ScummVM
-DS, they need to be ripped from the CD and stored in a specific format.
-This can only be done for the CD versions of certain games, such as
-Monkey Island 1, Loom, and Gobliiins. All the floppy games and CD games
-that didn't have CD audio tracks for music don't require any conversion,
-and will work unmodified on ScummVM DS. MP3 audio files for CD music are
-not supported.
-
-Cdex can do the conversion very well and I recommend using it to convert
-your audio files, although any CD ripping software can be used, so feel
-free to use your favorite program. The format you need to use is
-IMA-ADPCM 4-bit Mono. You may use any sample rate. All other formats
-will be rejected, including uncompressed WAV files.
-
-Since this sound format is a standard, you should be able to create it
-in a variety of software.
-Now I will to describe how to rip your CD tracks with Cdex, which can be
-found here: Cdex Homepage <http://sourceforge.net/projects/cdexos/>.
-If you're using MacOS or Linux, I suggest using Audacity
-<http://audacity.sourceforge.net>.
-
-To encode audio in Cdex, select Settings from the Options menu. On the
-Encoder tab, select 'WAV Output Encoder'. Under 'Encoder Options',
-choose the following:
-
-      Format: WAV
-      Compression: IMA ADPCM
-      Samplerate: 22050 Hz
-      Channels: Mono
-      On the fly encoding: On
-
-Next, go to the 'Filenames' tab and select the folder you want to save
-your Wav files to. Under 'Filename format', enter 'track%3'. This should
-name your WAV files in the correct way. Click OK.
-
-Now select all the tracks on your CD, and click 'Extract CD tracks to a
-compressed audio file'. Cdex should rip all the audio off your CD.
-
-Now all you have to do is copy the newly created WAV files into the same
-directory that your other game data is stored on your CompactFlash card.
-Next time your run ScummVM DS, it should play with music!
-
-*Important Note:* Do not select 'Extract CD tracks to a WAV file'. This
-creates uncompressed WAVs only. You want 'Extract CD tracks to a
-compressed audio file'.
-
-
-      Converting Speech files to MP3 format
-      ------------------------------------------------------------------------
-
-ScummVM supports playing back speech for talkie games in MP3 format.
-Unfortunately, the DS CPU is not quite up to the task, and MP3 audio
-will sometimes cause slowdown in your game. However, if your flash card
-isn't big enough to fit the audio files on, you will have no choice!
-
-To convert your audio you will need a copy of the ScummVM Tools package
-<https://www.scummvm.org/downloads/#tools>. You will also need a copy of
-the LAME MP3 encoder <http://www.free-codecs.com/Lame_Encoder_download.htm>.
-
-Once this is all installed and set up, the process to encode your audio
-varies from game to game, but the Lucasarts games can all be compressed
-using the following command line:
-
-compress_scumm_sou --mp3 monster.sou
-
-This produces a monster.so3 file which you can copy to your flash card
-and replaces the original monster.sou. Ogg format (monster.sog) and flac
-format files are not currently supported by ScummVM DS, and it is
-unlikely they will ever be supported. There is no way to convert .sog or
-.so3 files back to .sou files. Just dig out your original CD and copy
-the file from that.
-
-
-      Frequently Asked Questions
-      ------------------------------------------------------------------------
-
-I get a lot of email about ScummVM DS. Nearly all of them are exactly
-the same. Here I'm going to try and answer the questions that everybody
-asks me in the hope that I will spend less time answering questions that
-are clearly in the documentation and more time helping people who have a
-real problem or have discovered a real bug.
-
-*Q:* I can't see the bottom line of inventory items in Day of the
-Tentacle, Monkey Island 2, or a few other games! What do I do?
-*A:* Hold down the left shoulder button and use D-pad (or the touch
-screen) to scroll the screen around.
-
-*Q:* I don't get speech or sound effects in my Lucasarts games.  What's
-wrong?
-*A:* Do you have a monster.sog file?  If so, this is the wrong kind of
-speech file for ScummVM DS.  Copy the monster.sou file present on your
-original CD or floppies, and you will have speech.
-
-*Q:* Can ScummVM take advantage of the DSi?
-*A:* At the moment, no.  While some homebrew does run on the DSi, at
-the time of writing, it cannot access any of the DSi's new features.
-When it does, a version of ScummVM for the DSi may be possible.
-
-*Q:* I dont see a menu when I press Start in Flight of the Amazon Queen
-or Simon the Sorcerer. Is ScummVM broken?
-*A:* No. To save in Simon the Sorcerer, click 'use', then click on the
-postcard in your inventory. In Flight of the Amazon Queen, click 'use',
-then click on the journal in your inventory.
-
-*Q:* Why does ScummVM crash when I play Monkey Island 1?
-*A:* This happens when MP3 audio tracks are present from the PC version
-of ScummVM. Delete the MP3 tracks and reencode them to ADPCM WAV files
-as described in the CD audio section.
-
-*Q:* Can't you use the extra RAM in the M3/Supercard or the official
-Opera Expansion Pack to support more games like The Dig and Full
-Throttle? DS Linux has done it, so why can't you?
-*A:* Yes!  The Dig and Full Throttle are playable with some limitations.
-See the forum thread here for a download:
-https://forums.scummvm.org/viewtopic.php?t=7044
-
-*Q:* ScummVM DS turns off my DS when I hit 'Quit' in the game or quit
-from the frontend. Why doesn't it return to the menu?
-*A:* To return to the game launcher, hold 'Select' during the game
-to access the main ScummVM menu, then click 'Return to Launcher'
-
-
-
-      Contributors
-      ------------------------------------------------------------------------
-
-ScummVM DS uses chishm's GBA Movie Player FAT driver.
-The CPU scaler is by Tramboi and Robin Watts
-The ARM code was optimised by Robin Watts
-Thanks to highpass for the ScummVM DS icons.
-Thanks to zhevon for the Sam & Max cursor code.
-Thanks to theNinjaBunny for the M3 Adaptor guide on this site.
-Thanks also to everyone on the GBADev Forums.
-
-This program was brought to you by caffiene, sugar, and late nights.
-
-
-      Donations and Getting Help
-      ------------------------------------------------------------------------
-
-If you have problems getting ScummVM to work on your hardware, please
-read the FAQ first. /Please/ don't ask me questions which are answered
-in the FAQ, I get many emails about this program each day, and I can't
-help the people who really need help if I'm answering the same question
-all the time which is already answered on this page. Other than that,
-feel free to post on the ScummVM DS forum <https://forums.scummvm.org>
-for help. Please do your research first though. There is no way of
-running this on an out-of-the box DS without extra hardware. Most of
-these things are fairly inexpensive though.
-
-If you want to contact me, please email me on scummvm at millstone dot
-demon dot co dot uk.
-
-If you want to help with the development of ScummVM DS, great! Download
-the source code and get building. There are plenty of things left to do.
-
-You can also help by making a donation if you've particularly enjoyed
-ScummVM DS. This uses Paypal, and is completely secure. There's no
-pressure though, ScummVM DS is completely free. This is just for those
-who would like to make a contribution to further development.
-
-
-
-      Building from Sources
-      ------------------------------------------------------------------------
-
-ScummVM is an open source project.  This means that anyone is free to
-take the source code to the project and make their own additions and fixes,
-contributing them back to the authors for consideration for the next version.
-
-To build ScummVM DS from source, it's probably better to checkout the
-latest version of the code from the ScummVM Git repository. The ScummVM
-Wiki <https://wiki.scummvm.org/index.php?title=Compiling_ScummVM/Nintendo_DS>
-has all the information about how to do this.
-
-By default, ScummVM DS expects to find libmad, an MP3 compressor library
-targeted for the ARM platform.  If you don't have this, you must disable
-libmad support by opening 'backends/platform/ds/arm9/makefile' and
-commenting out the line which says USE_MAD = 1.
-
-Then, enter the 'backends/platform/ds' folder and type:
-
-  make SCUMM_BUILD=a
-
-The executable nds file will build inside 'backends/platform/ds/arm9/SCUMMVM-A'.
-
-For other builds, substitute the letters b - g in the above line.
-
-To build everything, type:
-
-  make allbuildssafe
diff --git a/doc/docportal/other_platforms/nintendo_ds.rst b/doc/docportal/other_platforms/nintendo_ds.rst
new file mode 100644
index 0000000000..a229d95bb8
--- /dev/null
+++ b/doc/docportal/other_platforms/nintendo_ds.rst
@@ -0,0 +1,56 @@
+=============================
+Nintendo DS
+=============================
+
+This page contains all the information you need to get ScummVM up and running on a Nintendo DS.
+
+What you'll need
+===================
+
+- A homebrew-enabled Nintendo DSi or an unofficial card reader. How to enable homebrew is outside the scope of this documentation.
+
+Installing ScummVM
+======================================
+
+Download the Nintendo DS package from the `ScummVM Downloads page <https://www.scummvm.org/downloads/>`_. Extract the archive and copy the extracted ``scummvm.nds`` file onto the SD card. The exact location is not important.
+
+Transferring game files
+========================
+
+Transfer game folders onto the SD card. The exact location is not important.
+
+See :doc:`../use_scummvm/game_files` for more information about game file requirements.
+
+Controls
+=============
+
+Controls can also be manually configured in the :doc:`Keymaps tab <../settings/keymaps>`. See the :doc:`../use_scummvm/keyboard_shortcuts` page for common keyboard shortcuts.
+
+Paths
+=======
+
+Saved games and the configuration file are found in the ScummVM installation directory.
+
+Settings
+==========
+
+For more information about Settings, see the Settings section of the documentation. Only platform-specific differences are listed here.
+
+Audio
+******
+
+Supported audio file formats:
+
+- MP3
+- Uncompressed audio
+
+.. tip::
+
+   Games run faster if audio files are uncompressed.
+
+
+Known issues
+==============
+
+- Games requiring a resolution of 512x512 or higher are not supported on the DS due to hardware limitations.
+- Some games are not playable due to the slow CPU speed and limited RAM on the DS. If there are any games that run really slowly, this is considered a hardware limitation, not a bug.




More information about the Scummvm-git-logs mailing list