Fixed intermittent splash from CakeBrah, made splash last slightly longer, added shutdown on error, slimmed down FatFs, added error on missing emuNAND, changed folder to "aurei", changed the dat name to "AuReiNand.dat", propered the built-in screen init of the chainloader, remade the look of the 3dsx
(First luma-powered CFW!)
This commit is contained in:
parent
6dfb33191f
commit
9b9f784c26
32
Makefile
32
Makefile
@ -12,7 +12,7 @@ ifneq ($(PYTHON_VER_MAJOR), 3)
|
||||
PYTHON3 := py -3
|
||||
endif
|
||||
|
||||
name := ReiNand
|
||||
name := AuReiNand
|
||||
|
||||
dir_source := source
|
||||
dir_data := data
|
||||
@ -26,7 +26,7 @@ dir_loader := loader
|
||||
|
||||
ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te
|
||||
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -fshort-wchar -std=c11 -Wno-main -O2 -ffast-math
|
||||
FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) --no-print-directory
|
||||
FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) APP_DESCRIPTION="Noob-friendly 3DS CFW." APP_AUTHOR="Reisyukaku/Aurora Wright" --no-print-directory
|
||||
|
||||
objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
@ -43,29 +43,29 @@ launcher: $(dir_out)/$(name).dat
|
||||
a9lh: $(dir_out)/arm9loaderhax.bin
|
||||
|
||||
.PHONY: emunand
|
||||
emunand: $(dir_out)/rei/emunand/emunand.bin
|
||||
emunand: $(dir_out)/aurei/emunand/emunand.bin
|
||||
|
||||
.PHONY: reboot
|
||||
reboot: $(dir_out)/rei/reboot/reboot.bin
|
||||
reboot: $(dir_out)/aurei/reboot/reboot.bin
|
||||
|
||||
.PHONY: ninjhax
|
||||
ninjhax: $(dir_out)/3ds/$(name)
|
||||
|
||||
.PHONY: loader
|
||||
loader: $(dir_out)/rei/loader.bin
|
||||
loader: $(dir_out)/aurei/loader.bin
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@$(MAKE) $(FLAGS) -C $(dir_mset) clean
|
||||
@$(MAKE) $(FLAGS) -C $(dir_ninjhax) clean
|
||||
@rm -rf $(dir_out) $(dir_build)
|
||||
@cd $(dir_loader) && make clean
|
||||
@$(MAKE) -C $(dir_loader) clean
|
||||
|
||||
$(dir_out)/$(name).dat: $(dir_build)/main.bin $(dir_out)/rei
|
||||
$(dir_out)/$(name).dat: $(dir_build)/main.bin $(dir_out)/aurei
|
||||
@$(MAKE) $(FLAGS) -C $(dir_mset) launcher
|
||||
dd if=$(dir_build)/main.bin of=$@ bs=512 seek=144
|
||||
|
||||
$(dir_out)/arm9loaderhax.bin: $(dir_build)/main.bin $(dir_out)/rei
|
||||
$(dir_out)/arm9loaderhax.bin: $(dir_build)/main.bin $(dir_out)/aurei
|
||||
@cp -av $(dir_build)/main.bin $@
|
||||
|
||||
$(dir_out)/3ds/$(name):
|
||||
@ -74,21 +74,21 @@ $(dir_out)/3ds/$(name):
|
||||
@mv $(dir_out)/$(name).3dsx $@
|
||||
@mv $(dir_out)/$(name).smdh $@
|
||||
|
||||
$(dir_out)/rei:
|
||||
@mkdir -p "$(dir_out)/rei"
|
||||
$(dir_out)/aurei:
|
||||
@mkdir -p "$(dir_out)/aurei"
|
||||
|
||||
$(dir_out)/rei/emunand/emunand.bin: $(dir_emu)/emuCode.s
|
||||
$(dir_out)/aurei/emunand/emunand.bin: $(dir_emu)/emuCode.s
|
||||
@armips $<
|
||||
@mkdir -p "$(dir_out)/rei/emunand"
|
||||
@mkdir -p "$(dir_out)/aurei/emunand"
|
||||
@mv emunand.bin $@
|
||||
|
||||
$(dir_out)/rei/reboot/reboot.bin: $(dir_reboot)/rebootCode.s
|
||||
$(dir_out)/aurei/reboot/reboot.bin: $(dir_reboot)/rebootCode.s
|
||||
@armips $<
|
||||
@mkdir -p "$(dir_out)/rei/reboot"
|
||||
@mkdir -p "$(dir_out)/aurei/reboot"
|
||||
@mv reboot.bin $@
|
||||
|
||||
$(dir_out)/rei/loader.bin: $(dir_out)/rei $(dir_loader)/Makefile
|
||||
@cd $(dir_loader) && make
|
||||
$(dir_out)/aurei/loader.bin: $(dir_out)/aurei $(dir_loader)/Makefile
|
||||
@$(MAKE) -C $(dir_loader)
|
||||
@mv $(dir_loader)/loader.bin $@
|
||||
|
||||
$(dir_build)/main.bin: $(dir_build)/main.elf
|
||||
|
BIN
icon.png
BIN
icon.png
Binary file not shown.
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 3.1 KiB |
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../../types.h"
|
@ -10,11 +10,11 @@ static const struct { u8 bus_id, reg_addr; } dev_data[] = {
|
||||
{2, 0xA4}, {2, 0x9A}, {2, 0xA0},
|
||||
};
|
||||
|
||||
inline u8 i2cGetDeviceBusId(u8 device_id) {
|
||||
static inline u8 i2cGetDeviceBusId(u8 device_id) {
|
||||
return dev_data[device_id].bus_id;
|
||||
}
|
||||
|
||||
inline u8 i2cGetDeviceRegAddr(u8 device_id) {
|
||||
static inline u8 i2cGetDeviceRegAddr(u8 device_id) {
|
||||
return dev_data[device_id].reg_addr;
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ static vu8* reg_data_addrs[] = {
|
||||
(vu8*)(I2C3_REG_OFF + I2C_REG_DATA),
|
||||
};
|
||||
|
||||
inline vu8* i2cGetDataReg(u8 bus_id) {
|
||||
static inline vu8* i2cGetDataReg(u8 bus_id) {
|
||||
return reg_data_addrs[bus_id];
|
||||
}
|
||||
|
||||
@ -38,22 +38,22 @@ static vu8* reg_cnt_addrs[] = {
|
||||
(vu8*)(I2C3_REG_OFF + I2C_REG_CNT),
|
||||
};
|
||||
|
||||
inline vu8* i2cGetCntReg(u8 bus_id) {
|
||||
static inline vu8* i2cGetCntReg(u8 bus_id) {
|
||||
return reg_cnt_addrs[bus_id];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void i2cWaitBusy(u8 bus_id) {
|
||||
static inline void i2cWaitBusy(u8 bus_id) {
|
||||
while (*i2cGetCntReg(bus_id) & 0x80);
|
||||
}
|
||||
|
||||
inline bool i2cGetResult(u8 bus_id) {
|
||||
static inline u32 i2cGetResult(u8 bus_id) {
|
||||
i2cWaitBusy(bus_id);
|
||||
return (*i2cGetCntReg(bus_id) >> 4) & 1;
|
||||
}
|
||||
|
||||
void i2cStop(u8 bus_id, u8 arg0) {
|
||||
static void i2cStop(u8 bus_id, u8 arg0) {
|
||||
*i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0;
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetCntReg(bus_id) = 0xC5;
|
||||
@ -61,14 +61,14 @@ void i2cStop(u8 bus_id, u8 arg0) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool i2cSelectDevice(u8 bus_id, u8 dev_reg) {
|
||||
static u32 i2cSelectDevice(u8 bus_id, u8 dev_reg) {
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetDataReg(bus_id) = dev_reg;
|
||||
*i2cGetCntReg(bus_id) = 0xC2;
|
||||
return i2cGetResult(bus_id);
|
||||
}
|
||||
|
||||
bool i2cSelectRegister(u8 bus_id, u8 reg) {
|
||||
static u32 i2cSelectRegister(u8 bus_id, u8 reg) {
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetDataReg(bus_id) = reg;
|
||||
*i2cGetCntReg(bus_id) = 0xC0;
|
||||
@ -77,58 +77,7 @@ bool i2cSelectRegister(u8 bus_id, u8 reg) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
u8 i2cReadRegister(u8 dev_id, u8 reg) {
|
||||
u8 bus_id = i2cGetDeviceBusId(dev_id);
|
||||
u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
|
||||
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
if (i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg)) {
|
||||
if (i2cSelectDevice(bus_id, dev_addr | 1)) {
|
||||
i2cWaitBusy(bus_id);
|
||||
i2cStop(bus_id, 1);
|
||||
i2cWaitBusy(bus_id);
|
||||
return *i2cGetDataReg(bus_id);
|
||||
}
|
||||
}
|
||||
*i2cGetCntReg(bus_id) = 0xC5;
|
||||
i2cWaitBusy(bus_id);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
bool i2cReadRegisterBuffer(unsigned int dev_id, int reg, u8* buffer, size_t buf_size) {
|
||||
u8 bus_id = i2cGetDeviceBusId(dev_id);
|
||||
u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
|
||||
|
||||
size_t j = 0;
|
||||
while (!i2cSelectDevice(bus_id, dev_addr)
|
||||
|| !i2cSelectRegister(bus_id, reg)
|
||||
|| !i2cSelectDevice(bus_id, dev_addr | 1))
|
||||
{
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetCntReg(bus_id) = 0xC5;
|
||||
i2cWaitBusy(bus_id);
|
||||
if (++j >= 8)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buf_size != 1) {
|
||||
for (size_t i = 0; i < buf_size - 1; i++) {
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetCntReg(bus_id) = 0xF0;
|
||||
i2cWaitBusy(bus_id);
|
||||
buffer[i] = *i2cGetDataReg(bus_id);
|
||||
}
|
||||
}
|
||||
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetCntReg(bus_id) = 0xE1;
|
||||
i2cWaitBusy(bus_id);
|
||||
*buffer = *i2cGetDataReg(bus_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
|
||||
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
|
||||
u8 bus_id = i2cGetDeviceBusId(dev_id);
|
||||
u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
|
||||
|
||||
@ -139,11 +88,11 @@ bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
|
||||
*i2cGetCntReg(bus_id) = 0xC1;
|
||||
i2cStop(bus_id, 0);
|
||||
if (i2cGetResult(bus_id))
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
*i2cGetCntReg(bus_id) = 0xC5;
|
||||
i2cWaitBusy(bus_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
@ -15,21 +15,4 @@
|
||||
#define I2C_DEV_GYRO 10
|
||||
#define I2C_DEV_IR 13
|
||||
|
||||
u8 i2cGetDeviceBusId(u8 device_id);
|
||||
u8 i2cGetDeviceRegAddr(u8 device_id);
|
||||
|
||||
vu8* i2cGetDataReg(u8 bus_id);
|
||||
vu8* i2cGetCntReg(u8 bus_id);
|
||||
|
||||
void i2cWaitBusy(u8 bus_id);
|
||||
bool i2cGetResult(u8 bus_id);
|
||||
u8 i2cGetData(u8 bus_id);
|
||||
void i2cStop(u8 bus_id, u8 arg0);
|
||||
|
||||
bool i2cSelectDevice(u8 bus_id, u8 dev_reg);
|
||||
bool i2cSelectRegister(u8 bus_id, u8 reg);
|
||||
|
||||
u8 i2cReadRegister(u8 dev_id, u8 reg);
|
||||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
||||
|
||||
bool i2cReadRegisterBuffer(unsigned int dev_id, int reg, u8* buffer, size_t buf_size);
|
||||
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
@ -26,16 +26,16 @@ void main(void){
|
||||
//Get pressed buttons
|
||||
u16 pressed = HID_PAD;
|
||||
|
||||
if(((pressed & BUTTON_B) && loadPayload("/rei/payloads/b.bin")) ||
|
||||
((pressed & BUTTON_X) && loadPayload("/rei/payloads/x.bin")) ||
|
||||
((pressed & BUTTON_Y) && loadPayload("/rei/payloads/y.bin")) ||
|
||||
((pressed & BUTTON_SELECT) && loadPayload("/rei/payloads/select.bin")) ||
|
||||
((pressed & BUTTON_START) && loadPayload("/rei/payloads/start.bin")) ||
|
||||
((pressed & BUTTON_RIGHT) && loadPayload("/rei/payloads/right.bin")) ||
|
||||
((pressed & BUTTON_LEFT) && loadPayload("/rei/payloads/left.bin")) ||
|
||||
((pressed & BUTTON_UP) && loadPayload("/rei/payloads/up.bin")) ||
|
||||
((pressed & BUTTON_DOWN) && loadPayload("/rei/payloads/down.bin")) ||
|
||||
loadPayload("/rei/payloads/default.bin")){
|
||||
if(((pressed & BUTTON_B) && loadPayload("/aurei/payloads/b.bin")) ||
|
||||
((pressed & BUTTON_X) && loadPayload("/aurei/payloads/x.bin")) ||
|
||||
((pressed & BUTTON_Y) && loadPayload("/aurei/payloads/y.bin")) ||
|
||||
((pressed & BUTTON_SELECT) && loadPayload("/aurei/payloads/select.bin")) ||
|
||||
((pressed & BUTTON_START) && loadPayload("/aurei/payloads/start.bin")) ||
|
||||
((pressed & BUTTON_RIGHT) && loadPayload("/aurei/payloads/right.bin")) ||
|
||||
((pressed & BUTTON_LEFT) && loadPayload("/aurei/payloads/left.bin")) ||
|
||||
((pressed & BUTTON_UP) && loadPayload("/aurei/payloads/up.bin")) ||
|
||||
((pressed & BUTTON_DOWN) && loadPayload("/aurei/payloads/down.bin")) ||
|
||||
loadPayload("/aurei/payloads/default.bin")){
|
||||
//Determine if screen was already inited
|
||||
if(*(vu8 *)0x10141200 == 0x1) initLCD();
|
||||
((void (*)())PAYLOAD_ADDRESS)();
|
||||
|
@ -2,9 +2,10 @@
|
||||
#include "i2c.h"
|
||||
|
||||
void initLCD(void){
|
||||
vu32 *const arm11 = (u32 *)0x1FFFFFF8;
|
||||
vu32 *const arm11 = (vu32 *)0x1FFFFFF8;
|
||||
|
||||
void __attribute__((naked)) ARM11(void){
|
||||
__asm(".word 0xF10C01C0");
|
||||
*(vu32 *)0x10141200 = 0x1007F;
|
||||
*(vu32 *)0x10202014 = 0x00000001;
|
||||
*(vu32 *)0x1020200C &= 0xFFFEFFFE;
|
||||
@ -91,6 +92,11 @@ void initLCD(void){
|
||||
*(vu32 *)0x10400568 = 0x18346500;
|
||||
*(vu32 *)0x1040056c = 0x18346500;
|
||||
|
||||
//Set CakeBrah framebuffers
|
||||
*((vu32 *)0x23FFFE00) = 0x18300000;
|
||||
*((vu32 *)0x23FFFE04) = 0x18300000;
|
||||
*((vu32 *)0x23FFFE08) = 0x18346500;
|
||||
|
||||
//Clear ARM11 entry offset
|
||||
*arm11 = 0;
|
||||
|
||||
@ -100,14 +106,6 @@ void initLCD(void){
|
||||
((void (*)())*arm11)();
|
||||
}
|
||||
|
||||
//Set CakeBrah framebuffers
|
||||
*(vu32 *)0x23FFFE00 = 0x18300000;
|
||||
*(vu32 *)0x23FFFE04 = 0x18300000;
|
||||
*(vu32 *)0x23FFFE08 = 0x18346500;
|
||||
|
||||
*arm11 = (u32)ARM11;
|
||||
|
||||
//This delay is needed for some reason
|
||||
for(vu32 i = 0; i < 0x2000; ++i);
|
||||
while(*arm11);
|
||||
}
|
@ -6,7 +6,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -99,7 +99,7 @@ Memcpy:
|
||||
BX LR
|
||||
|
||||
FileName:
|
||||
.dcw "sdmc:/rei/patched_firmware_sys.bin"
|
||||
.dcw "sdmc:/aurei/patched_firmware_sys.bin"
|
||||
.word 0x0
|
||||
|
||||
.pool
|
||||
|
@ -32,17 +32,17 @@ void __attribute__((naked)) shutdownLCD(void){
|
||||
((void (*)())*arm11)();
|
||||
}
|
||||
|
||||
static void clearScreen(void){
|
||||
memset(fb->top_left, 0, 0x46500);
|
||||
memset(fb->top_right, 0, 0x46500);
|
||||
memset(fb->bottom, 0, 0x38400);
|
||||
static void clearScreens(void){
|
||||
memset32(fb->top_left, 0, 0x46500);
|
||||
memset32(fb->top_right, 0, 0x46500);
|
||||
memset32(fb->bottom, 0, 0x38400);
|
||||
}
|
||||
|
||||
void loadSplash(void){
|
||||
clearScreen();
|
||||
clearScreens();
|
||||
//Don't delay boot if no splash image is on the SD
|
||||
if(fileRead(fb->top_left, "/rei/splash.bin", 0x46500) +
|
||||
fileRead(fb->bottom, "/rei/splashbottom.bin", 0x38400)){
|
||||
u64 i = 0xFFFFFF; while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func
|
||||
if(fileRead(fb->top_left, "/aurei/splash.bin", 0x46500) +
|
||||
fileRead(fb->bottom, "/aurei/splashbottom.bin", 0x38400)){
|
||||
u64 i = 0x1300000; while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func
|
||||
}
|
||||
}
|
@ -22,6 +22,11 @@ void getEmunandSect(u32 *off, u32 *head, u32 emuNAND){
|
||||
}
|
||||
//Fallback to the first emuNAND if there's no second one
|
||||
else if(emuNAND == 2) getEmunandSect(off, head, 1);
|
||||
//Check if a RedNAND is present
|
||||
else if(sdmmc_sdcard_readsectors(1, 1, temp) == 0){
|
||||
if(*(u32 *)(temp + 0x100) != NCSD_MAGIC)
|
||||
*head = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
#define _FS_MINIMIZE 3
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
|
@ -32,7 +32,7 @@ void setupCFW(void){
|
||||
//Retrieve the last booted FIRM
|
||||
u8 previousFirm = CFG_BOOTENV;
|
||||
u32 overrideConfig = 0;
|
||||
const char lastConfigPath[] = "rei/lastbootcfg";
|
||||
const char lastConfigPath[] = "aurei/lastbootcfg";
|
||||
|
||||
//Detect the console being used
|
||||
if(PDN_MPCORE_CFG == 1) console = 0;
|
||||
@ -41,10 +41,10 @@ void setupCFW(void){
|
||||
pressed = HID_PAD;
|
||||
|
||||
//Determine if A9LH is installed
|
||||
if(a9lhBoot || fileExists("/rei/installeda9lh")){
|
||||
if(a9lhBoot || fileExists("/aurei/installeda9lh")){
|
||||
a9lhSetup = 1;
|
||||
//Check flag for > 9.2 SysNAND
|
||||
if(fileExists("/rei/updatedsysnand")) updatedSys = 1;
|
||||
if(fileExists("/aurei/updatedsysnand")) updatedSys = 1;
|
||||
}
|
||||
|
||||
//If booting with A9LH and it's a MCU reboot, try to force boot options
|
||||
@ -92,14 +92,14 @@ void setupCFW(void){
|
||||
}
|
||||
}
|
||||
|
||||
if(mode) firmPathPatched = emuNAND ? (emuNAND == 1 ? "/rei/patched_firmware_emu.bin" :
|
||||
"/rei/patched_firmware_em2.bin") :
|
||||
"/rei/patched_firmware_sys.bin";
|
||||
if(mode) firmPathPatched = emuNAND ? (emuNAND == 1 ? "/aurei/patched_firmware_emu.bin" :
|
||||
"/aurei/patched_firmware_em2.bin") :
|
||||
"/aurei/patched_firmware_sys.bin";
|
||||
|
||||
//Skip decrypting and patching FIRM
|
||||
if(fileExists("/rei/usepatchedfw")){
|
||||
if(fileExists("/aurei/usepatchedfw")){
|
||||
//Only needed with this flag
|
||||
if(!mode) firmPathPatched = "/rei/patched_firmware90.bin";
|
||||
if(!mode) firmPathPatched = "/aurei/patched_firmware90.bin";
|
||||
if(fileExists(firmPathPatched)) usePatchedFirm = 1;
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ u32 loadFirm(void){
|
||||
//Load FIRM from SD
|
||||
else{
|
||||
const char *path = usePatchedFirm ? firmPathPatched :
|
||||
(mode ? "/rei/firmware.bin" : "/rei/firmware90.bin");
|
||||
(mode ? "/aurei/firmware.bin" : "/aurei/firmware90.bin");
|
||||
firmSize = fileSize(path);
|
||||
if(!firmSize) return 0;
|
||||
fileRead((u8 *)firmLocation, path, firmSize);
|
||||
@ -147,7 +147,7 @@ static u32 loadEmu(void){
|
||||
emuCodeOffset;
|
||||
|
||||
//Read emunand code from SD
|
||||
const char path[] = "/rei/emunand/emunand.bin";
|
||||
const char path[] = "/aurei/emunand/emunand.bin";
|
||||
u32 size = fileSize(path);
|
||||
if(!size) return 0;
|
||||
if(!console || !mode) nandRedir[5] = 0xA4;
|
||||
@ -168,6 +168,9 @@ static u32 loadEmu(void){
|
||||
*pos_offset = emuOffset;
|
||||
*pos_header = emuHeader;
|
||||
|
||||
//No emuNAND detected
|
||||
if(!*pos_header) return 0;
|
||||
|
||||
//Patch emuNAND code in memory for O3DS and 9.0 N3DS
|
||||
if(!console || !mode){
|
||||
void *pos_instr = memsearch((void *)emuCodeOffset, "\xA6\x01\x08\x30", size, 4);
|
||||
@ -219,7 +222,7 @@ u32 patchFirm(void){
|
||||
fOpenOffset;
|
||||
|
||||
//Read reboot code from SD
|
||||
const char path[] = "/rei/reboot/reboot.bin";
|
||||
const char path[] = "/aurei/reboot/reboot.bin";
|
||||
u32 size = fileSize(path);
|
||||
if(!size) return 0;
|
||||
getReboot(firmLocation, firmSize, &rebootOffset);
|
||||
|
98
source/i2c.c
Normal file
98
source/i2c.c
Normal file
@ -0,0 +1,98 @@
|
||||
#include "i2c.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const struct { u8 bus_id, reg_addr; } dev_data[] = {
|
||||
{0, 0x4A}, {0, 0x7A}, {0, 0x78},
|
||||
{1, 0x4A}, {1, 0x78}, {1, 0x2C},
|
||||
{1, 0x2E}, {1, 0x40}, {1, 0x44},
|
||||
{2, 0xD6}, {2, 0xD0}, {2, 0xD2},
|
||||
{2, 0xA4}, {2, 0x9A}, {2, 0xA0},
|
||||
};
|
||||
|
||||
static inline u8 i2cGetDeviceBusId(u8 device_id) {
|
||||
return dev_data[device_id].bus_id;
|
||||
}
|
||||
|
||||
static inline u8 i2cGetDeviceRegAddr(u8 device_id) {
|
||||
return dev_data[device_id].reg_addr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static vu8* reg_data_addrs[] = {
|
||||
(vu8*)(I2C1_REG_OFF + I2C_REG_DATA),
|
||||
(vu8*)(I2C2_REG_OFF + I2C_REG_DATA),
|
||||
(vu8*)(I2C3_REG_OFF + I2C_REG_DATA),
|
||||
};
|
||||
|
||||
static inline vu8* i2cGetDataReg(u8 bus_id) {
|
||||
return reg_data_addrs[bus_id];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static vu8* reg_cnt_addrs[] = {
|
||||
(vu8*)(I2C1_REG_OFF + I2C_REG_CNT),
|
||||
(vu8*)(I2C2_REG_OFF + I2C_REG_CNT),
|
||||
(vu8*)(I2C3_REG_OFF + I2C_REG_CNT),
|
||||
};
|
||||
|
||||
static inline vu8* i2cGetCntReg(u8 bus_id) {
|
||||
return reg_cnt_addrs[bus_id];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static inline void i2cWaitBusy(u8 bus_id) {
|
||||
while (*i2cGetCntReg(bus_id) & 0x80);
|
||||
}
|
||||
|
||||
static inline u32 i2cGetResult(u8 bus_id) {
|
||||
i2cWaitBusy(bus_id);
|
||||
return (*i2cGetCntReg(bus_id) >> 4) & 1;
|
||||
}
|
||||
|
||||
static void i2cStop(u8 bus_id, u8 arg0) {
|
||||
*i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0;
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetCntReg(bus_id) = 0xC5;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static u32 i2cSelectDevice(u8 bus_id, u8 dev_reg) {
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetDataReg(bus_id) = dev_reg;
|
||||
*i2cGetCntReg(bus_id) = 0xC2;
|
||||
return i2cGetResult(bus_id);
|
||||
}
|
||||
|
||||
static u32 i2cSelectRegister(u8 bus_id, u8 reg) {
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetDataReg(bus_id) = reg;
|
||||
*i2cGetCntReg(bus_id) = 0xC0;
|
||||
return i2cGetResult(bus_id);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
|
||||
u8 bus_id = i2cGetDeviceBusId(dev_id);
|
||||
u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg)) {
|
||||
i2cWaitBusy(bus_id);
|
||||
*i2cGetDataReg(bus_id) = data;
|
||||
*i2cGetCntReg(bus_id) = 0xC1;
|
||||
i2cStop(bus_id, 0);
|
||||
if (i2cGetResult(bus_id))
|
||||
return 1;
|
||||
}
|
||||
*i2cGetCntReg(bus_id) = 0xC5;
|
||||
i2cWaitBusy(bus_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
18
source/i2c.h
Normal file
18
source/i2c.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define I2C1_REG_OFF 0x10161000
|
||||
#define I2C2_REG_OFF 0x10144000
|
||||
#define I2C3_REG_OFF 0x10148000
|
||||
|
||||
#define I2C_REG_DATA 0
|
||||
#define I2C_REG_CNT 1
|
||||
#define I2C_REG_CNTEX 2
|
||||
#define I2C_REG_SCL 4
|
||||
|
||||
#define I2C_DEV_MCU 3
|
||||
#define I2C_DEV_GYRO 10
|
||||
#define I2C_DEV_IR 13
|
||||
|
||||
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
@ -8,7 +8,7 @@
|
||||
#define PAYLOAD_ADDRESS 0x24F00000
|
||||
|
||||
void loadPayload(void){
|
||||
if(fileExists("rei/payloads/default.bin") &&
|
||||
fileRead((u8 *)PAYLOAD_ADDRESS, "rei/loader.bin", 0))
|
||||
if(fileExists("aurei/payloads/default.bin") &&
|
||||
fileRead((u8 *)PAYLOAD_ADDRESS, "aurei/loader.bin", 0))
|
||||
((void (*)())PAYLOAD_ADDRESS)();
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "fs.h"
|
||||
#include "firm.h"
|
||||
#include "i2c.h"
|
||||
|
||||
void main(void){
|
||||
mountSD();
|
||||
@ -18,4 +19,8 @@ void startCFW(void){
|
||||
if(!loadFirm()) return;
|
||||
if(!patchFirm()) return;
|
||||
launchFirm();
|
||||
}
|
||||
|
||||
void shutdown(void){
|
||||
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1);
|
||||
}
|
@ -19,6 +19,12 @@ void memset(void *dest, int filler, u32 size){
|
||||
destc[i] = (u8)filler;
|
||||
}
|
||||
|
||||
void memset32(void *dest, u32 filler, u32 size){
|
||||
u32 *dest32 = (u32 *)dest;
|
||||
for (u32 i = 0; i < size / 4; i++)
|
||||
dest32[i] = filler;
|
||||
}
|
||||
|
||||
int memcmp(const void *buf1, const void *buf2, u32 size){
|
||||
const u8 *buf1c = (const u8 *)buf1;
|
||||
const u8 *buf2c = (const u8 *)buf2;
|
||||
|
@ -10,5 +10,6 @@
|
||||
|
||||
void memcpy(void *dest, const void *src, u32 size);
|
||||
void memset(void *dest, int filler, u32 size);
|
||||
void memset32(void *dest, u32 filler, u32 size);
|
||||
int memcmp(const void *buf1, const void *buf2, u32 size);
|
||||
void *memsearch(void *start_pos, const void *search, u32 size, u32 size_search);
|
@ -10,7 +10,7 @@ _start:
|
||||
mcr p15, 0, r0, c5, c0, 2 @ write data access
|
||||
mcr p15, 0, r0, c5, c0, 3 @ write instruction access
|
||||
|
||||
@ Set MPU permissions
|
||||
@ Set MPU permissions and cache settings
|
||||
ldr r0, =0xFFFF001D @ ffff0000 32k
|
||||
ldr r1, =0x01FF801D @ 01ff8000 32k
|
||||
ldr r2, =0x08000027 @ 08000000 1M
|
||||
@ -27,6 +27,11 @@ _start:
|
||||
mcr p15, 0, r5, c6, c5, 0
|
||||
mcr p15, 0, r6, c6, c6, 0
|
||||
mcr p15, 0, r7, c6, c7, 0
|
||||
mov r4, #0x25
|
||||
mov r0, #0x5
|
||||
mcr p15, 0, r4, c2, c0, 0 @ data cacheable
|
||||
mcr p15, 0, r4, c2, c0, 1 @ instruction cacheable
|
||||
mcr p15, 0, r0, c3, c0, 0 @ data bufferable
|
||||
|
||||
@ Enable caches
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control register
|
||||
@ -48,13 +53,11 @@ _start:
|
||||
|
||||
bl main
|
||||
|
||||
@ Set cache settings
|
||||
mov r0, #0x25
|
||||
mcr p15, 0, r0, c3, c0, 0 @ Write bufferable 0, 2, 5
|
||||
mcr p15, 0, r0, c2, c0, 0 @ Data cacheable 0, 2, 5
|
||||
mcr p15, 0, r0, c2, c0, 1 @ Inst cacheable 0, 2, 5
|
||||
mcr p15, 0, r4, c3, c0, 0 @ data bufferable
|
||||
|
||||
bl startCFW
|
||||
|
||||
bl shutdown
|
||||
|
||||
.die:
|
||||
b .die
|
||||
|
Reference in New Issue
Block a user