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
|
PYTHON3 := py -3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
name := ReiNand
|
name := AuReiNand
|
||||||
|
|
||||||
dir_source := source
|
dir_source := source
|
||||||
dir_data := data
|
dir_data := data
|
||||||
@ -26,7 +26,7 @@ dir_loader := loader
|
|||||||
|
|
||||||
ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te
|
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
|
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, \
|
objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||||
@ -43,29 +43,29 @@ launcher: $(dir_out)/$(name).dat
|
|||||||
a9lh: $(dir_out)/arm9loaderhax.bin
|
a9lh: $(dir_out)/arm9loaderhax.bin
|
||||||
|
|
||||||
.PHONY: emunand
|
.PHONY: emunand
|
||||||
emunand: $(dir_out)/rei/emunand/emunand.bin
|
emunand: $(dir_out)/aurei/emunand/emunand.bin
|
||||||
|
|
||||||
.PHONY: reboot
|
.PHONY: reboot
|
||||||
reboot: $(dir_out)/rei/reboot/reboot.bin
|
reboot: $(dir_out)/aurei/reboot/reboot.bin
|
||||||
|
|
||||||
.PHONY: ninjhax
|
.PHONY: ninjhax
|
||||||
ninjhax: $(dir_out)/3ds/$(name)
|
ninjhax: $(dir_out)/3ds/$(name)
|
||||||
|
|
||||||
.PHONY: loader
|
.PHONY: loader
|
||||||
loader: $(dir_out)/rei/loader.bin
|
loader: $(dir_out)/aurei/loader.bin
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@$(MAKE) $(FLAGS) -C $(dir_mset) clean
|
@$(MAKE) $(FLAGS) -C $(dir_mset) clean
|
||||||
@$(MAKE) $(FLAGS) -C $(dir_ninjhax) clean
|
@$(MAKE) $(FLAGS) -C $(dir_ninjhax) clean
|
||||||
@rm -rf $(dir_out) $(dir_build)
|
@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
|
@$(MAKE) $(FLAGS) -C $(dir_mset) launcher
|
||||||
dd if=$(dir_build)/main.bin of=$@ bs=512 seek=144
|
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 $@
|
@cp -av $(dir_build)/main.bin $@
|
||||||
|
|
||||||
$(dir_out)/3ds/$(name):
|
$(dir_out)/3ds/$(name):
|
||||||
@ -74,21 +74,21 @@ $(dir_out)/3ds/$(name):
|
|||||||
@mv $(dir_out)/$(name).3dsx $@
|
@mv $(dir_out)/$(name).3dsx $@
|
||||||
@mv $(dir_out)/$(name).smdh $@
|
@mv $(dir_out)/$(name).smdh $@
|
||||||
|
|
||||||
$(dir_out)/rei:
|
$(dir_out)/aurei:
|
||||||
@mkdir -p "$(dir_out)/rei"
|
@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 $<
|
@armips $<
|
||||||
@mkdir -p "$(dir_out)/rei/emunand"
|
@mkdir -p "$(dir_out)/aurei/emunand"
|
||||||
@mv emunand.bin $@
|
@mv emunand.bin $@
|
||||||
|
|
||||||
$(dir_out)/rei/reboot/reboot.bin: $(dir_reboot)/rebootCode.s
|
$(dir_out)/aurei/reboot/reboot.bin: $(dir_reboot)/rebootCode.s
|
||||||
@armips $<
|
@armips $<
|
||||||
@mkdir -p "$(dir_out)/rei/reboot"
|
@mkdir -p "$(dir_out)/aurei/reboot"
|
||||||
@mv reboot.bin $@
|
@mv reboot.bin $@
|
||||||
|
|
||||||
$(dir_out)/rei/loader.bin: $(dir_out)/rei $(dir_loader)/Makefile
|
$(dir_out)/aurei/loader.bin: $(dir_out)/aurei $(dir_loader)/Makefile
|
||||||
@cd $(dir_loader) && make
|
@$(MAKE) -C $(dir_loader)
|
||||||
@mv $(dir_loader)/loader.bin $@
|
@mv $(dir_loader)/loader.bin $@
|
||||||
|
|
||||||
$(dir_build)/main.bin: $(dir_build)/main.elf
|
$(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
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "../../types.h"
|
#include "../../types.h"
|
@ -10,11 +10,11 @@ static const struct { u8 bus_id, reg_addr; } dev_data[] = {
|
|||||||
{2, 0xA4}, {2, 0x9A}, {2, 0xA0},
|
{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;
|
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;
|
return dev_data[device_id].reg_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ static vu8* reg_data_addrs[] = {
|
|||||||
(vu8*)(I2C3_REG_OFF + I2C_REG_DATA),
|
(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];
|
return reg_data_addrs[bus_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,22 +38,22 @@ static vu8* reg_cnt_addrs[] = {
|
|||||||
(vu8*)(I2C3_REG_OFF + I2C_REG_CNT),
|
(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];
|
return reg_cnt_addrs[bus_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
inline void i2cWaitBusy(u8 bus_id) {
|
static inline void i2cWaitBusy(u8 bus_id) {
|
||||||
while (*i2cGetCntReg(bus_id) & 0x80);
|
while (*i2cGetCntReg(bus_id) & 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool i2cGetResult(u8 bus_id) {
|
static inline u32 i2cGetResult(u8 bus_id) {
|
||||||
i2cWaitBusy(bus_id);
|
i2cWaitBusy(bus_id);
|
||||||
return (*i2cGetCntReg(bus_id) >> 4) & 1;
|
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;
|
*i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0;
|
||||||
i2cWaitBusy(bus_id);
|
i2cWaitBusy(bus_id);
|
||||||
*i2cGetCntReg(bus_id) = 0xC5;
|
*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);
|
i2cWaitBusy(bus_id);
|
||||||
*i2cGetDataReg(bus_id) = dev_reg;
|
*i2cGetDataReg(bus_id) = dev_reg;
|
||||||
*i2cGetCntReg(bus_id) = 0xC2;
|
*i2cGetCntReg(bus_id) = 0xC2;
|
||||||
return i2cGetResult(bus_id);
|
return i2cGetResult(bus_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool i2cSelectRegister(u8 bus_id, u8 reg) {
|
static u32 i2cSelectRegister(u8 bus_id, u8 reg) {
|
||||||
i2cWaitBusy(bus_id);
|
i2cWaitBusy(bus_id);
|
||||||
*i2cGetDataReg(bus_id) = reg;
|
*i2cGetDataReg(bus_id) = reg;
|
||||||
*i2cGetCntReg(bus_id) = 0xC0;
|
*i2cGetCntReg(bus_id) = 0xC0;
|
||||||
@ -77,58 +77,7 @@ bool i2cSelectRegister(u8 bus_id, u8 reg) {
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
u8 i2cReadRegister(u8 dev_id, u8 reg) {
|
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data) {
|
||||||
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) {
|
|
||||||
u8 bus_id = i2cGetDeviceBusId(dev_id);
|
u8 bus_id = i2cGetDeviceBusId(dev_id);
|
||||||
u8 dev_addr = i2cGetDeviceRegAddr(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;
|
*i2cGetCntReg(bus_id) = 0xC1;
|
||||||
i2cStop(bus_id, 0);
|
i2cStop(bus_id, 0);
|
||||||
if (i2cGetResult(bus_id))
|
if (i2cGetResult(bus_id))
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
*i2cGetCntReg(bus_id) = 0xC5;
|
*i2cGetCntReg(bus_id) = 0xC5;
|
||||||
i2cWaitBusy(bus_id);
|
i2cWaitBusy(bus_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -15,21 +15,4 @@
|
|||||||
#define I2C_DEV_GYRO 10
|
#define I2C_DEV_GYRO 10
|
||||||
#define I2C_DEV_IR 13
|
#define I2C_DEV_IR 13
|
||||||
|
|
||||||
u8 i2cGetDeviceBusId(u8 device_id);
|
u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
||||||
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);
|
|
@ -26,16 +26,16 @@ void main(void){
|
|||||||
//Get pressed buttons
|
//Get pressed buttons
|
||||||
u16 pressed = HID_PAD;
|
u16 pressed = HID_PAD;
|
||||||
|
|
||||||
if(((pressed & BUTTON_B) && loadPayload("/rei/payloads/b.bin")) ||
|
if(((pressed & BUTTON_B) && loadPayload("/aurei/payloads/b.bin")) ||
|
||||||
((pressed & BUTTON_X) && loadPayload("/rei/payloads/x.bin")) ||
|
((pressed & BUTTON_X) && loadPayload("/aurei/payloads/x.bin")) ||
|
||||||
((pressed & BUTTON_Y) && loadPayload("/rei/payloads/y.bin")) ||
|
((pressed & BUTTON_Y) && loadPayload("/aurei/payloads/y.bin")) ||
|
||||||
((pressed & BUTTON_SELECT) && loadPayload("/rei/payloads/select.bin")) ||
|
((pressed & BUTTON_SELECT) && loadPayload("/aurei/payloads/select.bin")) ||
|
||||||
((pressed & BUTTON_START) && loadPayload("/rei/payloads/start.bin")) ||
|
((pressed & BUTTON_START) && loadPayload("/aurei/payloads/start.bin")) ||
|
||||||
((pressed & BUTTON_RIGHT) && loadPayload("/rei/payloads/right.bin")) ||
|
((pressed & BUTTON_RIGHT) && loadPayload("/aurei/payloads/right.bin")) ||
|
||||||
((pressed & BUTTON_LEFT) && loadPayload("/rei/payloads/left.bin")) ||
|
((pressed & BUTTON_LEFT) && loadPayload("/aurei/payloads/left.bin")) ||
|
||||||
((pressed & BUTTON_UP) && loadPayload("/rei/payloads/up.bin")) ||
|
((pressed & BUTTON_UP) && loadPayload("/aurei/payloads/up.bin")) ||
|
||||||
((pressed & BUTTON_DOWN) && loadPayload("/rei/payloads/down.bin")) ||
|
((pressed & BUTTON_DOWN) && loadPayload("/aurei/payloads/down.bin")) ||
|
||||||
loadPayload("/rei/payloads/default.bin")){
|
loadPayload("/aurei/payloads/default.bin")){
|
||||||
//Determine if screen was already inited
|
//Determine if screen was already inited
|
||||||
if(*(vu8 *)0x10141200 == 0x1) initLCD();
|
if(*(vu8 *)0x10141200 == 0x1) initLCD();
|
||||||
((void (*)())PAYLOAD_ADDRESS)();
|
((void (*)())PAYLOAD_ADDRESS)();
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
void initLCD(void){
|
void initLCD(void){
|
||||||
vu32 *const arm11 = (u32 *)0x1FFFFFF8;
|
vu32 *const arm11 = (vu32 *)0x1FFFFFF8;
|
||||||
|
|
||||||
void __attribute__((naked)) ARM11(void){
|
void __attribute__((naked)) ARM11(void){
|
||||||
|
__asm(".word 0xF10C01C0");
|
||||||
*(vu32 *)0x10141200 = 0x1007F;
|
*(vu32 *)0x10141200 = 0x1007F;
|
||||||
*(vu32 *)0x10202014 = 0x00000001;
|
*(vu32 *)0x10202014 = 0x00000001;
|
||||||
*(vu32 *)0x1020200C &= 0xFFFEFFFE;
|
*(vu32 *)0x1020200C &= 0xFFFEFFFE;
|
||||||
@ -91,6 +92,11 @@ void initLCD(void){
|
|||||||
*(vu32 *)0x10400568 = 0x18346500;
|
*(vu32 *)0x10400568 = 0x18346500;
|
||||||
*(vu32 *)0x1040056c = 0x18346500;
|
*(vu32 *)0x1040056c = 0x18346500;
|
||||||
|
|
||||||
|
//Set CakeBrah framebuffers
|
||||||
|
*((vu32 *)0x23FFFE00) = 0x18300000;
|
||||||
|
*((vu32 *)0x23FFFE04) = 0x18300000;
|
||||||
|
*((vu32 *)0x23FFFE08) = 0x18346500;
|
||||||
|
|
||||||
//Clear ARM11 entry offset
|
//Clear ARM11 entry offset
|
||||||
*arm11 = 0;
|
*arm11 = 0;
|
||||||
|
|
||||||
@ -100,14 +106,6 @@ void initLCD(void){
|
|||||||
((void (*)())*arm11)();
|
((void (*)())*arm11)();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set CakeBrah framebuffers
|
|
||||||
*(vu32 *)0x23FFFE00 = 0x18300000;
|
|
||||||
*(vu32 *)0x23FFFE04 = 0x18300000;
|
|
||||||
*(vu32 *)0x23FFFE08 = 0x18346500;
|
|
||||||
|
|
||||||
*arm11 = (u32)ARM11;
|
*arm11 = (u32)ARM11;
|
||||||
|
|
||||||
//This delay is needed for some reason
|
|
||||||
for(vu32 i = 0; i < 0x2000; ++i);
|
|
||||||
while(*arm11);
|
while(*arm11);
|
||||||
}
|
}
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ Memcpy:
|
|||||||
BX LR
|
BX LR
|
||||||
|
|
||||||
FileName:
|
FileName:
|
||||||
.dcw "sdmc:/rei/patched_firmware_sys.bin"
|
.dcw "sdmc:/aurei/patched_firmware_sys.bin"
|
||||||
.word 0x0
|
.word 0x0
|
||||||
|
|
||||||
.pool
|
.pool
|
||||||
|
@ -32,17 +32,17 @@ void __attribute__((naked)) shutdownLCD(void){
|
|||||||
((void (*)())*arm11)();
|
((void (*)())*arm11)();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearScreen(void){
|
static void clearScreens(void){
|
||||||
memset(fb->top_left, 0, 0x46500);
|
memset32(fb->top_left, 0, 0x46500);
|
||||||
memset(fb->top_right, 0, 0x46500);
|
memset32(fb->top_right, 0, 0x46500);
|
||||||
memset(fb->bottom, 0, 0x38400);
|
memset32(fb->bottom, 0, 0x38400);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadSplash(void){
|
void loadSplash(void){
|
||||||
clearScreen();
|
clearScreens();
|
||||||
//Don't delay boot if no splash image is on the SD
|
//Don't delay boot if no splash image is on the SD
|
||||||
if(fileRead(fb->top_left, "/rei/splash.bin", 0x46500) +
|
if(fileRead(fb->top_left, "/aurei/splash.bin", 0x46500) +
|
||||||
fileRead(fb->bottom, "/rei/splashbottom.bin", 0x38400)){
|
fileRead(fb->bottom, "/aurei/splashbottom.bin", 0x38400)){
|
||||||
u64 i = 0xFFFFFF; while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func
|
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
|
//Fallback to the first emuNAND if there's no second one
|
||||||
else if(emuNAND == 2) getEmunandSect(off, head, 1);
|
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. */
|
/ 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.
|
/* This option defines minimization level to remove some basic API functions.
|
||||||
/
|
/
|
||||||
/ 0: All basic functions are enabled.
|
/ 0: All basic functions are enabled.
|
||||||
|
@ -32,7 +32,7 @@ void setupCFW(void){
|
|||||||
//Retrieve the last booted FIRM
|
//Retrieve the last booted FIRM
|
||||||
u8 previousFirm = CFG_BOOTENV;
|
u8 previousFirm = CFG_BOOTENV;
|
||||||
u32 overrideConfig = 0;
|
u32 overrideConfig = 0;
|
||||||
const char lastConfigPath[] = "rei/lastbootcfg";
|
const char lastConfigPath[] = "aurei/lastbootcfg";
|
||||||
|
|
||||||
//Detect the console being used
|
//Detect the console being used
|
||||||
if(PDN_MPCORE_CFG == 1) console = 0;
|
if(PDN_MPCORE_CFG == 1) console = 0;
|
||||||
@ -41,10 +41,10 @@ void setupCFW(void){
|
|||||||
pressed = HID_PAD;
|
pressed = HID_PAD;
|
||||||
|
|
||||||
//Determine if A9LH is installed
|
//Determine if A9LH is installed
|
||||||
if(a9lhBoot || fileExists("/rei/installeda9lh")){
|
if(a9lhBoot || fileExists("/aurei/installeda9lh")){
|
||||||
a9lhSetup = 1;
|
a9lhSetup = 1;
|
||||||
//Check flag for > 9.2 SysNAND
|
//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
|
//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" :
|
if(mode) firmPathPatched = emuNAND ? (emuNAND == 1 ? "/aurei/patched_firmware_emu.bin" :
|
||||||
"/rei/patched_firmware_em2.bin") :
|
"/aurei/patched_firmware_em2.bin") :
|
||||||
"/rei/patched_firmware_sys.bin";
|
"/aurei/patched_firmware_sys.bin";
|
||||||
|
|
||||||
//Skip decrypting and patching FIRM
|
//Skip decrypting and patching FIRM
|
||||||
if(fileExists("/rei/usepatchedfw")){
|
if(fileExists("/aurei/usepatchedfw")){
|
||||||
//Only needed with this flag
|
//Only needed with this flag
|
||||||
if(!mode) firmPathPatched = "/rei/patched_firmware90.bin";
|
if(!mode) firmPathPatched = "/aurei/patched_firmware90.bin";
|
||||||
if(fileExists(firmPathPatched)) usePatchedFirm = 1;
|
if(fileExists(firmPathPatched)) usePatchedFirm = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ u32 loadFirm(void){
|
|||||||
//Load FIRM from SD
|
//Load FIRM from SD
|
||||||
else{
|
else{
|
||||||
const char *path = usePatchedFirm ? firmPathPatched :
|
const char *path = usePatchedFirm ? firmPathPatched :
|
||||||
(mode ? "/rei/firmware.bin" : "/rei/firmware90.bin");
|
(mode ? "/aurei/firmware.bin" : "/aurei/firmware90.bin");
|
||||||
firmSize = fileSize(path);
|
firmSize = fileSize(path);
|
||||||
if(!firmSize) return 0;
|
if(!firmSize) return 0;
|
||||||
fileRead((u8 *)firmLocation, path, firmSize);
|
fileRead((u8 *)firmLocation, path, firmSize);
|
||||||
@ -147,7 +147,7 @@ static u32 loadEmu(void){
|
|||||||
emuCodeOffset;
|
emuCodeOffset;
|
||||||
|
|
||||||
//Read emunand code from SD
|
//Read emunand code from SD
|
||||||
const char path[] = "/rei/emunand/emunand.bin";
|
const char path[] = "/aurei/emunand/emunand.bin";
|
||||||
u32 size = fileSize(path);
|
u32 size = fileSize(path);
|
||||||
if(!size) return 0;
|
if(!size) return 0;
|
||||||
if(!console || !mode) nandRedir[5] = 0xA4;
|
if(!console || !mode) nandRedir[5] = 0xA4;
|
||||||
@ -168,6 +168,9 @@ static u32 loadEmu(void){
|
|||||||
*pos_offset = emuOffset;
|
*pos_offset = emuOffset;
|
||||||
*pos_header = emuHeader;
|
*pos_header = emuHeader;
|
||||||
|
|
||||||
|
//No emuNAND detected
|
||||||
|
if(!*pos_header) return 0;
|
||||||
|
|
||||||
//Patch emuNAND code in memory for O3DS and 9.0 N3DS
|
//Patch emuNAND code in memory for O3DS and 9.0 N3DS
|
||||||
if(!console || !mode){
|
if(!console || !mode){
|
||||||
void *pos_instr = memsearch((void *)emuCodeOffset, "\xA6\x01\x08\x30", size, 4);
|
void *pos_instr = memsearch((void *)emuCodeOffset, "\xA6\x01\x08\x30", size, 4);
|
||||||
@ -219,7 +222,7 @@ u32 patchFirm(void){
|
|||||||
fOpenOffset;
|
fOpenOffset;
|
||||||
|
|
||||||
//Read reboot code from SD
|
//Read reboot code from SD
|
||||||
const char path[] = "/rei/reboot/reboot.bin";
|
const char path[] = "/aurei/reboot/reboot.bin";
|
||||||
u32 size = fileSize(path);
|
u32 size = fileSize(path);
|
||||||
if(!size) return 0;
|
if(!size) return 0;
|
||||||
getReboot(firmLocation, firmSize, &rebootOffset);
|
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
|
#define PAYLOAD_ADDRESS 0x24F00000
|
||||||
|
|
||||||
void loadPayload(void){
|
void loadPayload(void){
|
||||||
if(fileExists("rei/payloads/default.bin") &&
|
if(fileExists("aurei/payloads/default.bin") &&
|
||||||
fileRead((u8 *)PAYLOAD_ADDRESS, "rei/loader.bin", 0))
|
fileRead((u8 *)PAYLOAD_ADDRESS, "aurei/loader.bin", 0))
|
||||||
((void (*)())PAYLOAD_ADDRESS)();
|
((void (*)())PAYLOAD_ADDRESS)();
|
||||||
}
|
}
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "firm.h"
|
#include "firm.h"
|
||||||
|
#include "i2c.h"
|
||||||
|
|
||||||
void main(void){
|
void main(void){
|
||||||
mountSD();
|
mountSD();
|
||||||
@ -18,4 +19,8 @@ void startCFW(void){
|
|||||||
if(!loadFirm()) return;
|
if(!loadFirm()) return;
|
||||||
if(!patchFirm()) return;
|
if(!patchFirm()) return;
|
||||||
launchFirm();
|
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;
|
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){
|
int memcmp(const void *buf1, const void *buf2, u32 size){
|
||||||
const u8 *buf1c = (const u8 *)buf1;
|
const u8 *buf1c = (const u8 *)buf1;
|
||||||
const u8 *buf2c = (const u8 *)buf2;
|
const u8 *buf2c = (const u8 *)buf2;
|
||||||
|
@ -10,5 +10,6 @@
|
|||||||
|
|
||||||
void memcpy(void *dest, const void *src, u32 size);
|
void memcpy(void *dest, const void *src, u32 size);
|
||||||
void memset(void *dest, int filler, 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);
|
int memcmp(const void *buf1, const void *buf2, u32 size);
|
||||||
void *memsearch(void *start_pos, const void *search, u32 size, u32 size_search);
|
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, 2 @ write data access
|
||||||
mcr p15, 0, r0, c5, c0, 3 @ write instruction 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 r0, =0xFFFF001D @ ffff0000 32k
|
||||||
ldr r1, =0x01FF801D @ 01ff8000 32k
|
ldr r1, =0x01FF801D @ 01ff8000 32k
|
||||||
ldr r2, =0x08000027 @ 08000000 1M
|
ldr r2, =0x08000027 @ 08000000 1M
|
||||||
@ -27,6 +27,11 @@ _start:
|
|||||||
mcr p15, 0, r5, c6, c5, 0
|
mcr p15, 0, r5, c6, c5, 0
|
||||||
mcr p15, 0, r6, c6, c6, 0
|
mcr p15, 0, r6, c6, c6, 0
|
||||||
mcr p15, 0, r7, c6, c7, 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
|
@ Enable caches
|
||||||
mrc p15, 0, r0, c1, c0, 0 @ read control register
|
mrc p15, 0, r0, c1, c0, 0 @ read control register
|
||||||
@ -48,13 +53,11 @@ _start:
|
|||||||
|
|
||||||
bl main
|
bl main
|
||||||
|
|
||||||
@ Set cache settings
|
mcr p15, 0, r4, c3, c0, 0 @ data bufferable
|
||||||
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
|
|
||||||
|
|
||||||
bl startCFW
|
bl startCFW
|
||||||
|
|
||||||
|
bl shutdown
|
||||||
|
|
||||||
.die:
|
.die:
|
||||||
b .die
|
b .die
|
||||||
|
Reference in New Issue
Block a user