Merge more commits from Chishm's NitroHax..

Includes the latest commits from Chishm:

74c22febe9

4f56f7df62

6024a87a44

e3b086e313

85e33b00ac

abbc8329ab

451929891a
This commit is contained in:
ApacheThunder 2018-04-15 15:26:28 -05:00
parent c33318186e
commit 18121ee763
7 changed files with 341 additions and 163 deletions

View File

@ -41,28 +41,5 @@ BEGIN_ASM_FUNC arm9_clearCache
mcr p15, 0, r3, c7, c6, 0 @ Flush DCache
mcr p15, 0, r3, c7, c10, 4 @ empty write buffer
mcr p15, 0, r3, c3, c0, 0 @ disable write buffer (def = 0)
mcr p15, 0, r3, c2, c0, 0 @ disable DTCM and protection unit
mcr p15, 0, r3, c6, c0, 0 @ disable protection unit 0 (def = 0)
mcr p15, 0, r3, c6, c1, 0 @ disable protection unit 1 (def = 0)
mcr p15, 0, r3, c6, c2, 0 @ disable protection unit 2 (def = 0)
mcr p15, 0, r3, c6, c3, 0 @ disable protection unit 3 (def = 0)
mcr p15, 0, r3, c6, c4, 0 @ disable protection unit 4 (def = ?)
mcr p15, 0, r3, c6, c5, 0 @ disable protection unit 5 (def = ?)
mcr p15, 0, r3, c6, c6, 0 @ disable protection unit 6 (def = ?)
mcr p15, 0, r3, c6, c7, 0 @ disable protection unit 7 (def = ?)
mcr p15, 0, r3, c5, c0, 3 @ IAccess
mcr p15, 0, r3, c5, c0, 2 @ DAccess
mov r3, #0x00800000
add r3, r3, #0x00A
mcr p15, 0, r3, c9, c1, 0 @ DTCM base (def = 0x0080000A) ???
mov r3, #0x0000000C
mcr p15, 0, r3, c9, c1, 1 @ ITCM base (def = 0x0000000C) ???
bx lr

View File

@ -20,6 +20,7 @@
#define _COMMON_H
#include <nds/dma.h>
#include <nds/ipc.h>
#include <stdlib.h>
#define resetCpu() \
@ -32,10 +33,28 @@ enum { ERR_NONE=0x00, ERR_STS_CLR_MEM=0x01, ERR_STS_LOAD_BIN=0x02, ERR_STS_HOOK_
ERR_NOCHEAT=0x21, ERR_HOOK=0x22,
} ERROR_CODES;
enum {ARM9_BOOT, ARM9_START, ARM9_MEMCLR, ARM9_READY, ARM9_BOOTBIN, ARM9_DISPERR} ARM9_STATE;
extern volatile int arm9_stateFlag;
// Values fixed so they can be shared with ASM code
enum {
ARM9_BOOT = 0,
ARM9_START = 1,
ARM9_RESET = 2,
ARM9_READY = 3,
ARM9_MEMCLR = 4
} ARM9_STATE;
enum {
ARM7_BOOT = 0,
ARM7_START = 1,
ARM7_RESET = 2,
ARM7_READY = 3,
ARM7_MEMCLR = 4,
ARM7_LOADBIN = 5,
ARM7_HOOKBIN = 6,
ARM7_BOOTBIN = 7,
ARM7_ERR = 8
} ARM7_STATE;
extern volatile u32 arm9_errorCode;
extern volatile bool arm9_errorClearBG;
static inline void dmaFill(const void* src, void* dest, uint32 size) {
DMA_SRC(3) = (uint32)src;
@ -50,5 +69,13 @@ static inline void copyLoop (u32* dest, const u32* src, size_t size) {
} while (size -= 4);
}
static inline void ipcSendState(uint8_t state) {
REG_IPC_SYNC = (state & 0x0f) << 8;
}
static inline uint8_t ipcRecvState(void) {
return (uint8_t)(REG_IPC_SYNC & 0x0f);
}
#endif // _COMMON_H

View File

@ -49,7 +49,11 @@
#include "common.h"
#include "read_card.h"
void arm7_clearmem (void* loc, size_t len);
/*-------------------------------------------------------------------------
External functions
--------------------------------------------------------------------------*/
extern void arm7_clearmem (void* loc, size_t len);
extern void arm7_reset (void);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Important things
@ -60,28 +64,14 @@ tNDSHeader* ndsHeader = (tNDSHeader*)NDS_HEAD;
// Used for debugging purposes
/* Disabled for now. Re-enable to debug problems
static void errorOutput (u32 code) {
// Wait until the ARM9 is ready
while (arm9_stateFlag != ARM9_READY);
// Set the error code, then tell ARM9 to display it
// Set the error code, then set our state to "error"
arm9_errorCode = code;
arm9_errorClearBG = true;
arm9_stateFlag = ARM9_DISPERR;
ipcSendState(ARM7_ERR);
// Stop
while(1);
}
*/
static void debugOutput (u32 code) {
// Wait until the ARM9 is ready
while (arm9_stateFlag != ARM9_READY);
// Set the error code, then tell ARM9 to display it
arm9_errorCode = code;
arm9_errorClearBG = false;
arm9_stateFlag = ARM9_DISPERR;
// Wait for completion
while (arm9_stateFlag != ARM9_READY);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Firmware stuff
@ -201,30 +191,6 @@ int arm7_loadBinary (void) {
}
/*-------------------------------------------------------------------------
arm7_startBinary
Jumps to the ARM7 NDS binary in sync with the display and ARM9
Written by Darkain, modified by Chishm.
--------------------------------------------------------------------------*/
void arm7_startBinary (void)
{
// Wait until the ARM9 is ready
while (arm9_stateFlag != ARM9_READY);
while(REG_VCOUNT!=191);
while(REG_VCOUNT==191);
// Get the ARM9 to boot
arm9_stateFlag = ARM9_BOOTBIN;
while(REG_VCOUNT!=191);
while(REG_VCOUNT==191);
// Start ARM7
((void (*)())(*(u32*)(0x27FFE34)))();
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Main function
@ -232,26 +198,28 @@ void arm7_main (void) {
int errorCode;
// Wait for ARM9 to at least start
while (arm9_stateFlag < ARM9_START);
// Synchronise start
while (ipcRecvState() != ARM9_START);
ipcSendState(ARM7_START);
debugOutput (ERR_STS_CLR_MEM);
// Wait until ARM9 is ready
while (ipcRecvState() != ARM9_READY);
ipcSendState(ARM7_MEMCLR);
// Get ARM7 to clear RAM
arm7_resetMemory();
debugOutput (ERR_STS_LOAD_BIN);
ipcSendState(ARM7_LOADBIN);
// Load the NDS file
errorCode = arm7_loadBinary();
if (errorCode) {
debugOutput(errorCode);
// errorOutput(errorCode);
}
debugOutput (ERR_STS_START);
ipcSendState(ARM7_BOOTBIN);
arm7_startBinary();
return;
arm7_reset();
}

View File

@ -51,14 +51,19 @@ volatile u32 arm9_BLANK_RAM = 0;
External functions
--------------------------------------------------------------------------*/
extern void arm9_clearCache(void);
extern void arm9_reset (void);
/*-------------------------------------------------------------------------
arm9_errorOutput
Displays an error code on screen.
Each box is 2 bits, and left-to-right is most-significant bits to least.
Red = 00, Yellow = 01, Green = 10, Blue = 11
Written by Chishm
--------------------------------------------------------------------------*/
/* Re-enable for debugging.
static void arm9_errorOutput (u32 code, bool clearBG) {
static void arm9_errorOutput (u32 code) {
int i, j, k;
u16 colour;
@ -66,12 +71,10 @@ static void arm9_errorOutput (u32 code, bool clearBG) {
REG_DISPCNT = MODE_FB0;
VRAM_A_CR = VRAM_ENABLE;
if (clearBG) {
// Clear display
for (i = 0; i < 256*192; i++) {
VRAM_A[i] = 0x0000;
}
}
// Draw boxes of colour, signifying error codes
@ -95,7 +98,6 @@ static void arm9_errorOutput (u32 code, bool clearBG) {
}
}
if ((code >> 8) != 0) {
// Low 16 bits
for (i = 0; i < 8; i++) { // Pair of bits to use
if (((code>>(14-2*i))&3) == 0) {
@ -113,33 +115,14 @@ static void arm9_errorOutput (u32 code, bool clearBG) {
}
}
}
} else {
// Low 8 bits
for (i = 0; i < 4; i++) { // Pair of bits to use
if (((code>>(6-2*i))&3) == 0) {
colour = 0x001F; // Red
} else if (((code>>(6-2*i))&3) == 1) {
colour = 0x03FF; // Yellow
} else if (((code>>(6-2*i))&3) == 2) {
colour = 0x03E0; // Green
} else {
colour = 0x7C00; // Blue
}
for (j = 87; j < 103; j++) { // Row
for (k = 32*i+72; k < 32*i+88; k++) { // Column
VRAM_A[j*256+k] = colour;
}
}
}
}
}
*/
/*-------------------------------------------------------------------------
arm9_main
Clears the ARM9's icahce and dcache
Clears the ARM9's DMA channels and resets video memory
Jumps to the ARM9 NDS binary in sync with the display and ARM7
Jumps to the ARM9 NDS binary in sync with the ARM7
Written by Darkain, modified by Chishm
--------------------------------------------------------------------------*/
void arm9_main (void) {
@ -150,12 +133,17 @@ void arm9_main (void) {
WRAM_CR = 0x03;
REG_EXMEMCNT = 0xE880;
arm9_stateFlag = ARM9_START;
// Disable interrupts
REG_IME = 0;
REG_IE = 0;
REG_IF = ~0;
// Synchronise start
ipcSendState(ARM9_START);
while (ipcRecvState() != ARM7_START);
ipcSendState(ARM9_MEMCLR);
arm9_clearCache();
for (i=0; i<16*1024; i+=4) { //first 16KB
@ -167,29 +155,19 @@ void arm9_main (void) {
(*(vu32*)(i+0x00000000)) = 0x00000000; //clear ITCM
}
arm9_stateFlag = ARM9_MEMCLR;
(*(vu32*)0x00803FFC) = 0; //IRQ_HANDLER ARM9 version
(*(vu32*)0x00803FF8) = ~0; //VBLANK_INTR_WAIT_FLAGS ARM9 version
//clear out ARM9 DMA channels
for (i=0; i<4; i++) {
DMA_CR(i) = 0;
DMA_SRC(i) = 0;
DMA_DEST(i) = 0;
TIMER_CR(i) = 0;
TIMER_DATA(i) = 0;
}
// Clear out FIFO
REG_IPC_SYNC = 0;
REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR;
REG_IPC_FIFO_CR = 0;
// Blank out VRAM
VRAM_A_CR = 0x80;
VRAM_B_CR = 0x80;
// Don't mess with the VRAM used for execution
// VRAM_C_CR = 0;
// Don't mess with the VRAM used for execution
// VRAM_C_CR = 0;
VRAM_D_CR = 0x80;
VRAM_E_CR = 0x80;
VRAM_F_CR = 0x80;
@ -199,11 +177,26 @@ void arm9_main (void) {
BG_PALETTE[0] = 0xFFFF;
dmaFill((void*)&arm9_BLANK_RAM, BG_PALETTE+1, (2*1024)-2);
dmaFill((void*)&arm9_BLANK_RAM, OAM, 2*1024);
dmaFill((void*)&arm9_BLANK_RAM, (void*)0x04000000, 0x56); //clear main display registers
dmaFill((void*)&arm9_BLANK_RAM, (void*)0x04001000, 0x56); //clear sub display registers
dmaFill((void*)&arm9_BLANK_RAM, VRAM_A, 256*1024); // Banks A, B
dmaFill((void*)&arm9_BLANK_RAM, VRAM_D, 272*1024); // Banks D, E, F, G, H, I
// Clear out display registers
vu16 *mainregs = (vu16*)0x04000000;
vu16 *subregs = (vu16*)0x04001000;
for (i=0; i<43; i++) {
mainregs[i] = 0;
subregs[i] = 0;
}
// Clear out ARM9 DMA channels
for (i=0; i<4; i++) {
DMA_CR(i) = 0;
DMA_SRC(i) = 0;
DMA_DEST(i) = 0;
TIMER_CR(i) = 0;
TIMER_DATA(i) = 0;
}
REG_DISPSTAT = 0;
videoSetMode(0);
videoSetModeSub(0);
@ -219,25 +212,21 @@ void arm9_main (void) {
VRAM_I_CR = 0;
REG_POWERCNT = 0x820F;
// set ARM9 state to ready and wait for it to change again
arm9_stateFlag = ARM9_READY;
while ( arm9_stateFlag != ARM9_BOOTBIN ) {
if (arm9_stateFlag == ARM9_DISPERR) {
// Re-enable for debugging
// arm9_errorOutput (arm9_errorCode, arm9_errorClearBG);
if ( arm9_stateFlag == ARM9_DISPERR) {
arm9_stateFlag = ARM9_READY;
}
}
}
// wait for vblank then boot
while(REG_VCOUNT!=191);
while(REG_VCOUNT==191);
// set ARM9 state to ready and wait for instructions from ARM7
ipcSendState(ARM9_READY);
while (ipcRecvState() != ARM7_BOOTBIN) {
if (ipcRecvState() == ARM7_ERR) {
// Re-enable for debugging
// arm9_errorOutput (arm9_errorCode);
// Halt after displaying error code
while(1);
}
}
// arm9_errorOutput (*(u32*)(first), true);
((void (*)())(*(u32*)(0x27FFE24)))();
// ((void (*)())(*(u32*)(0x27FFE24)))();
arm9_reset();
}

View File

@ -0,0 +1,81 @@
/*
Copyright 2015 Dave Murphy (WinterMute)
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, see <http://www.gnu.org/licenses/>.
*/
.text
.align 4
.arm
@---------------------------------------------------------------------------------
.global arm7_reset
.type arm7_reset STT_FUNC
@---------------------------------------------------------------------------------
arm7_reset:
@---------------------------------------------------------------------------------
mrs r0, cpsr @ cpu interrupt disable
orr r0, r0, #0x80 @ (set i flag)
msr cpsr, r0
ldr r0, =0x380FFFC @ irq vector
mov r1, #0
str r1, [r0]
sub r0, r0, #4 @ IRQ1 Check Bits
str r1, [r0]
sub r0, r0, #4 @ IRQ2 Check Bits
str r1, [r0]
bic r0, r0, #0x7f
msr cpsr_c, #0xd3 @ svc mode
mov sp, r0
sub r0, r0, #64
msr cpsr_c, #0xd2 @ irq mode
mov sp, r0
sub r0, r0, #512
msr cpsr_c, #0xdf @ system mode
mov sp, r0
mov r12, #0x04000000
add r12, r12, #0x180
@ while (ipcRecvState() != ARM9_RESET);
mov r0, #2
bl waitsync
@ ipcSendState(ARM7_RESET)
mov r0, #0x200
strh r0, [r12]
@ while(ipcRecvState() != ARM9_BOOT);
mov r0, #0
bl waitsync
@ ipcSendState(ARM7_BOOT)
strh r0, [r12]
ldr r0,=0x2FFFE34
ldr r0,[r0]
bx r0
.pool
@---------------------------------------------------------------------------------
waitsync:
@---------------------------------------------------------------------------------
ldrh r1, [r12]
and r1, r1, #0x000f
cmp r0, r1
bne waitsync
bx lr

View File

@ -0,0 +1,136 @@
/*
Copyright 2006 - 2015 Dave Murphy (WinterMute)
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, see <http://www.gnu.org/licenses/>.
*/
#include <nds/arm9/cache_asm.h>
.text
.align 4
.arm
.arch armv5te
.cpu arm946e-s
@---------------------------------------------------------------------------------
.global arm9_reset
.type arm9_reset STT_FUNC
@---------------------------------------------------------------------------------
arm9_reset:
@---------------------------------------------------------------------------------
mrs r0, cpsr @ cpu interrupt disable
orr r0, r0, #0x80 @ (set i flag)
msr cpsr, r0
@ Switch off MPU
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #PROTECT_ENABLE
mcr p15, 0, r0, c1, c0, 0
adr r12, mpu_initial_data
ldmia r12, {r0-r10}
mcr p15, 0, r0, c2, c0, 0
mcr p15, 0, r0, c2, c0, 1
mcr p15, 0, r1, c3, c0, 0
mcr p15, 0, r2, c5, c0, 2
mcr p15, 0, r3, c5, c0, 3
mcr p15, 0, r4, c6, c0, 0
mcr p15, 0, r5, c6, c1, 0
mcr p15, 0, r6, c6, c3, 0
mcr p15, 0, r7, c6, c4, 0
mcr p15, 0, r8, c6, c6, 0
mcr p15, 0, r9, c6, c7, 0
mcr p15, 0, r10, c9, c1, 0
mov r0, #0
mcr p15, 0, r0, c6, c2, 0 @ PU Protection Unit Data/Unified Region 2
mcr p15, 0, r0, c6, c5, 0 @ PU Protection Unit Data/Unified Region 5
mrc p15, 0, r0, c9, c1, 0 @ DTCM
mov r0, r0, lsr #12 @ base
mov r0, r0, lsl #12 @ size
add r0, r0, #0x4000 @ dtcm top
sub r0, r0, #4 @ irq vector
mov r1, #0
str r1, [r0]
sub r0, r0, #4 @ IRQ1 Check Bits
str r1, [r0]
bic r0, r0, #0x7f
msr cpsr_c, #0xd3 @ svc mode
mov sp, r0
sub r0, r0, #64
msr cpsr_c, #0xd2 @ irq mode
mov sp, r0
sub r0, r0, #4096
msr cpsr_c, #0xdf @ system mode
mov sp, r0
mov r12, #0x04000000
add r12, r12, #0x180
@ ipcSendState(ARM9_RESET)
mov r0, #0x200
strh r0, [r12]
@ while (ipcRecvState() != ARM7_RESET);
mov r0, #2
bl waitsync
@ ipcSendState(ARM9_BOOT)
mov r0, #0
strh r0, [r12]
@ while (ipcRecvState() != ARM7_BOOT);
bl waitsync
ldr r10, =0x2FFFE24
ldr r2, [r10]
@ Switch MPU to startup default
ldr r0, =0x00012078
mcr p15, 0, r0, c1, c0, 0
bx r2
.pool
@---------------------------------------------------------------------------------
waitsync:
@---------------------------------------------------------------------------------
ldrh r1, [r12]
and r1, r1, #0x000f
cmp r0, r1
bne waitsync
bx lr
mpu_initial_data:
.word 0x00000042 @ p15,0,c2,c0,0..1,r0 ;PU Cachability Bits for Data/Unified+Instruction Protection Region
.word 0x00000002 @ p15,0,c3,c0,0,r1 ;PU Write-Bufferability Bits for Data Protection Regions
.word 0x15111011 @ p15,0,c5,c0,2,r2 ;PU Extended Access Permission Data/Unified Protection Region
.word 0x05100011 @ p15,0,c5,c0,3,r3 ;PU Extended Access Permission Instruction Protection Region
.word 0x04000033 @ p15,0,c6,c0,0,r4 ;PU Protection Unit Data/Unified Region 0
.word 0x0200002b @ p15,0,c6,c1,0,r5 ;PU Protection Unit Data/Unified Region 1 4MB
.word 0x08000035 @ p15,0,c6,c3,0,r6 ;PU Protection Unit Data/Unified Region 3
.word 0x0300001b @ p15,0,c6,c4,0,r7 ;PU Protection Unit Data/Unified Region 4
.word 0xffff001d @ p15,0,c6,c6,0,r8 ;PU Protection Unit Data/Unified Region 6
.word 0x027ff017 @ p15,0,c6,c7,0,r9 ;PU Protection Unit Data/Unified Region 7 4KB
.word 0x0300000a @ p15,0,c9,c1,0,r10 ;TCM Data TCM Base and Virtual Size
itcm_reset_code_end:

View File

@ -6,4 +6,4 @@ Launcher side of NitroHax without the cheat engine. Nothing much else to say abo
The source to "Launch DS Cart" on FileTrip was never released. I rebuilt it after ahezard ported NitroHax to latest devkitarm. This project is GNU licensed so that original DS Launcher on File Trip should have included source anyways.
That has been corrected here. :D
Credits go to Chism for NitroHax which this source is based from.
Credits go to Chism for NitroHax which this source is based from and WinterMute for dslink source/reset code.