mirror of
https://github.com/ApacheThunder/GBA-Exploader.git
synced 2025-06-18 19:45:39 -04:00

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