You've already forked pico-loader
mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-01-09 16:28:35 -08:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9a8c09a35 | ||
|
|
8e98796be2 | ||
|
|
a8f5d880b2 | ||
|
|
7aba420201 | ||
|
|
8761081c73 | ||
|
|
0dd41f4220 | ||
|
|
485598ab79 | ||
|
|
b2fabe5d97 | ||
|
|
4701b9d1b7 | ||
|
|
5c37a57560 |
16
.github/workflows/nightly.yml
vendored
16
.github/workflows/nightly.yml
vendored
@@ -21,6 +21,7 @@ jobs:
|
||||
"AKRPG",
|
||||
"DSPICO",
|
||||
"DSTT",
|
||||
"EZP",
|
||||
"G003",
|
||||
"M3DS",
|
||||
"R4",
|
||||
@@ -46,14 +47,15 @@ jobs:
|
||||
- name: Run build script
|
||||
run: |
|
||||
make PICO_PLATFORM=${{ matrix.platform }}
|
||||
mv picoLoader7.bin data/picoLoader7.bin
|
||||
mv picoLoader9_${{ matrix.platform }}.bin data/picoLoader9.bin
|
||||
- name: Package artifact
|
||||
run: |
|
||||
mkdir Pico_Loader_${{ matrix.platform }}
|
||||
mv picoLoader7.bin data/aplist.bin data/savelist.bin Pico_Loader_${{ matrix.platform }}
|
||||
mv picoLoader9_${{ matrix.platform }}.bin Pico_Loader_${{ matrix.platform }}/picoLoader9.bin
|
||||
- name: Publish build to GH Actions
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: |
|
||||
data/aplist.bin
|
||||
data/savelist.bin
|
||||
data/picoLoader7.bin
|
||||
data/picoLoader9.bin
|
||||
name: Pico Loader for ${{ matrix.platform }}
|
||||
Pico_Loader_${{ matrix.platform }}
|
||||
# For some reason without explicitly setting a name there is some odd conflicts
|
||||
name: Pico_Loader_${{ matrix.platform }}
|
||||
|
||||
65
.github/workflows/release.yml
vendored
Normal file
65
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: Build Pico Loader release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
pico_loader:
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [
|
||||
"ACE3DS",
|
||||
"AK2",
|
||||
"AKRPG",
|
||||
"DSPICO",
|
||||
"DSTT",
|
||||
"EZP",
|
||||
"G003",
|
||||
"M3DS",
|
||||
"R4",
|
||||
"R4iDSN",
|
||||
"SUPERCARD"
|
||||
]
|
||||
runs-on: ubuntu-latest
|
||||
container: skylyrac/blocksds:slim-v1.13.1
|
||||
name: Build Pico Loader
|
||||
env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1
|
||||
DOTNET_NOLOGO: true
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 9.x
|
||||
- name: Install zip
|
||||
run:
|
||||
apt-get update && apt-get -y install zip
|
||||
- name: Run build script
|
||||
run: |
|
||||
make PICO_PLATFORM=${{ matrix.platform }}
|
||||
- name: Package artifact
|
||||
run: |
|
||||
mkdir Pico_Loader_${{ matrix.platform }}
|
||||
mv picoLoader7.bin data/aplist.bin data/savelist.bin Pico_Loader_${{ matrix.platform }}
|
||||
mv picoLoader9_${{ matrix.platform }}.bin Pico_Loader_${{ matrix.platform }}/picoLoader9.bin
|
||||
- name: Publish build to GH Actions
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: |
|
||||
Pico_Loader_${{ matrix.platform }}
|
||||
# For some reason without explicitly setting a name there is some odd conflicts
|
||||
name: Pico_Loader_${{ matrix.platform }}
|
||||
- name: Package for release
|
||||
run: |
|
||||
cd Pico_Loader_${{ matrix.platform }} && zip -r $PWD.zip *
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
Pico_Loader_${{ matrix.platform }}.zip
|
||||
@@ -27,6 +27,7 @@ Note that there can be some game compatibility differences between different pla
|
||||
| AKRPG | Acekard RPG SD card | ❌ |
|
||||
| DSPICO | DSpico | âś… |
|
||||
| DSTT | DSTT, SuperCard DSONE SDHC, r4isdhc.com carts 2014+, r4i-sdhc.com carts, various derivatives | ❌ |
|
||||
| EZP | EZ-Flash Parallel | ❌ |
|
||||
| G003 | M3i Zero (GMP-Z003) | âś… |
|
||||
| ISNITRO | Supports the IS-NITRO-EMULATOR through agb semihosting. | ❌ |
|
||||
| M3DS | M3 DS Real, M3i Zero, iTouchDS, r4rts.com, r4isdhc.com RTS (black) | ❌ |
|
||||
|
||||
@@ -534,13 +534,19 @@ void NdsLoader::LoadFirmwareUserSettings()
|
||||
|
||||
bool NdsLoader::ShouldAttemptDldiPatch()
|
||||
{
|
||||
// Some games contain a fake dldi header to trick flashcards
|
||||
// See also: https://shutterbug2000.github.io/very-clever/
|
||||
switch (_romHeader.ntrHeader.gameCode)
|
||||
{
|
||||
// Final Fantasy IV contains a fake dldi header to trick flashcards
|
||||
// See also: https://shutterbug2000.github.io/very-clever/
|
||||
// Final Fantasy IV
|
||||
case GAMECODE("YF4P"):
|
||||
case GAMECODE("YF4E"):
|
||||
case GAMECODE("YF4J"):
|
||||
// Final Fantasy Crystal Chronicles - Ring of Fates
|
||||
case GAMECODE("AFXE"):
|
||||
case GAMECODE("AFXP"):
|
||||
// Nanashi no Geemu
|
||||
case GAMECODE("YFQJ"):
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
5
arm9/source/jumpToArm9EntryPoint.h
Normal file
5
arm9/source/jumpToArm9EntryPoint.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
/// @brief Clears all cpu registers and jumps to the specified \p arm9EntryPoint.
|
||||
/// @param arm9EntryPoint The arm9 entry point to jump to.
|
||||
extern "C" void jumpToArm9EntryPoint(void* arm9EntryPoint);
|
||||
29
arm9/source/jumpToArm9EntryPoint.s
Normal file
29
arm9/source/jumpToArm9EntryPoint.s
Normal file
@@ -0,0 +1,29 @@
|
||||
.section ".itcm", "ax"
|
||||
.arm
|
||||
|
||||
// r0: arm9EntryPoint
|
||||
.global jumpToArm9EntryPoint
|
||||
.type jumpToArm9EntryPoint, %function
|
||||
jumpToArm9EntryPoint:
|
||||
str r0, entry_point
|
||||
// Clear all registers
|
||||
mov r0, #0
|
||||
mov r1, #0
|
||||
mov r2, #0
|
||||
mov r3, #0
|
||||
mov r4, #0
|
||||
mov r5, #0
|
||||
mov r6, #0
|
||||
mov r7, #0
|
||||
mov r8, #0
|
||||
mov r9, #0
|
||||
mov r10, #0
|
||||
mov r11, #0
|
||||
mov r12, #0
|
||||
mov sp, #0
|
||||
mov lr, #0
|
||||
// Jump to the arm9 entry point
|
||||
ldr pc, entry_point
|
||||
|
||||
entry_point:
|
||||
.word 0
|
||||
@@ -26,8 +26,7 @@
|
||||
#include "arm9Clock.h"
|
||||
#include "errorDisplay/ErrorDisplay.h"
|
||||
#include "LoaderInfo.h"
|
||||
|
||||
typedef void (*entrypoint_t)(void);
|
||||
#include "jumpToArm9EntryPoint.h"
|
||||
|
||||
#define HANDSHAKE_PART0 0xA
|
||||
#define HANDSHAKE_PART1 0xB
|
||||
@@ -109,7 +108,7 @@ static void bootArm9()
|
||||
while (gfx_getVCount() == 191);
|
||||
REG_IF = ~0u; // final clear of REG_IF bits
|
||||
auto romHeader = (const nds_header_ntr_t*)TWL_SHARED_MEMORY->ntrSharedMem.romHeader;
|
||||
((entrypoint_t)romHeader->arm9EntryAddress)();
|
||||
jumpToArm9EntryPoint((void*)romHeader->arm9EntryAddress);
|
||||
}
|
||||
|
||||
static void handleInitializeSdCardCommand()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,8 +17,5 @@ private:
|
||||
DSProtectVersion _version;
|
||||
u32 _functionMask;
|
||||
|
||||
void SetOldV1Offsets(const u16* offsets) const;
|
||||
const void* InsertPatchV1(PatchContext& patchContext) const;
|
||||
const void* InsertPatchV2(PatchContext& patchContext) const;
|
||||
const void* InsertPatchV2s(PatchContext& patchContext) const;
|
||||
void ConfigurePatch(PatchContext& patchContext) const;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "sections.h"
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(dsprotectpatch);
|
||||
|
||||
extern "C" void dsprotectpatch_entry();
|
||||
|
||||
extern u32 dsprotectpatch_patchType; // 0=write dsprotectpatch_writeWord, 1=copy subsequent word
|
||||
extern u32 dsprotectpatch_writeWord; // Word to write if dsprotectpatch_patchType=0
|
||||
extern u32 dsprotectpatch_offsetA1; // Target offset for A1 (0xFFFFFFFF=invalid)
|
||||
extern u32 dsprotectpatch_offsetNotA1; // Target offset for NotA1 (0xFFFFFFFF=invalid)
|
||||
|
||||
extern u32 dsprotectpatch_overlayId; // Target overlay ID
|
||||
extern const void* dsprotectpatch_nextAddress; // Next patch address
|
||||
@@ -0,0 +1,89 @@
|
||||
.cpu arm946e-s
|
||||
.syntax unified
|
||||
.section "dsprotectpatch", "ax"
|
||||
.thumb
|
||||
|
||||
.global dsprotectpatch_entry
|
||||
.type dsprotectpatch_entry, %function
|
||||
dsprotectpatch_entry:
|
||||
push {r4-r7, lr}
|
||||
|
||||
// r5 is overlay table entry-- load { ovy_id, ram_start }
|
||||
ldmia r5!, {r6, r7}
|
||||
|
||||
// Bail if this is the wrong overlay
|
||||
ldr r4, dsprotectpatch_overlayId
|
||||
cmp r4, r6
|
||||
bne continue_to_next
|
||||
|
||||
// Try to patch A1
|
||||
ldr r0, dsprotectpatch_offsetA1
|
||||
adds r0, r7
|
||||
bl try_apply_patch
|
||||
|
||||
// Try to patch NotA1
|
||||
ldr r0, dsprotectpatch_offsetNotA1
|
||||
adds r0, r7
|
||||
bl try_apply_patch
|
||||
|
||||
continue_to_next:
|
||||
// Return next patch address
|
||||
ldr r0, dsprotectpatch_nextAddress
|
||||
pop {r4-r7, pc}
|
||||
|
||||
.local try_apply_patch
|
||||
.type try_apply_patch, %function
|
||||
try_apply_patch:
|
||||
// If the high bit is set, this is invalid and we skip it
|
||||
cmp r0, #0x0
|
||||
blt offset_invalid
|
||||
|
||||
// Check what patch type to use
|
||||
ldr r1, dsprotectpatch_patchType
|
||||
cmp r1, #0x0
|
||||
beq load_literal
|
||||
|
||||
// Load next word (+4)
|
||||
ldr r2, [r0, #0x4]
|
||||
b load_done
|
||||
|
||||
load_literal:
|
||||
// Load literal value
|
||||
ldr r2, dsprotectpatch_writeWord
|
||||
|
||||
load_done:
|
||||
// Write to patch location
|
||||
str r2, [r0]
|
||||
|
||||
offset_invalid:
|
||||
bx lr
|
||||
|
||||
.balign 4
|
||||
|
||||
.global dsprotectpatch_writeWord
|
||||
dsprotectpatch_writeWord:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatch_patchType
|
||||
dsprotectpatch_patchType:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatch_offsetA1
|
||||
dsprotectpatch_offsetA1:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatch_offsetNotA1
|
||||
dsprotectpatch_offsetNotA1:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatch_overlayId
|
||||
dsprotectpatch_overlayId:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatch_nextAddress
|
||||
dsprotectpatch_nextAddress:
|
||||
.word 0
|
||||
|
||||
.pool
|
||||
|
||||
.end
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include "sections.h"
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(dsprotectpatchv1_part1);
|
||||
extern "C" void dsprotectpatchv1_entry1();
|
||||
extern u16 dsprotectpatchv1_stub_protectb1_offset;
|
||||
extern u16 dsprotectpatchv1_stub_protectb2_offset;
|
||||
extern u16 dsprotectpatchv1_stub_protectb3_offset;
|
||||
extern u16 dsprotectpatchv1_nitro_static_init_offset;
|
||||
extern u16 dsprotectpatchv1_overlay_id;
|
||||
extern u32 dsprotectpatchv1_base_offset;
|
||||
extern u32 dsprotectpatchv1_part2_address;
|
||||
extern u32 dsprotectpatchv1_protectb1_return_value;
|
||||
extern u32 dsprotectpatchv1_protectb2_return_value;
|
||||
extern u32 dsprotectpatchv1_protectb3_return_value;
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(dsprotectpatchv1_part2);
|
||||
extern "C" void dsprotectpatchv1_entry2();
|
||||
extern u16 dsprotectpatchv1_stub_notprotectb1_offset;
|
||||
extern u16 dsprotectpatchv1_stub_notprotectb2_offset;
|
||||
extern u16 dsprotectpatchv1_stub_notprotectb3_offset;
|
||||
extern u32 dsprotectpatchv1_nextAddress;
|
||||
extern u32 dsprotectpatchv1_notprotectb1_return_value;
|
||||
extern u32 dsprotectpatchv1_notprotectb2_return_value;
|
||||
extern u32 dsprotectpatchv1_notprotectb3_return_value;
|
||||
extern u32 dsprotectpatchv1_loadReturnValue;
|
||||
extern u32 dsprotectpatchv1_moveCallback;
|
||||
@@ -1,168 +0,0 @@
|
||||
.cpu arm946e-s
|
||||
.syntax unified
|
||||
.section "dsprotectpatchv1_part1", "ax"
|
||||
|
||||
.thumb
|
||||
|
||||
.global dsprotectpatchv1_entry1
|
||||
.type dsprotectpatchv1_entry1, %function
|
||||
dsprotectpatchv1_entry1:
|
||||
push {r4-r7,lr}
|
||||
adr r0, dsprotectpatchv1_stub_protectb1_offset
|
||||
ldrh r4, [r0, #(dsprotectpatchv1_overlay_id - dsprotectpatchv1_stub_protectb1_offset)]
|
||||
ldmia r5!, {r1, r2} // id, ram address
|
||||
cmp r1, r4
|
||||
bne continue_to_next
|
||||
|
||||
ldr r4, dsprotectpatchv1_base_offset
|
||||
adds r2, r4 // add base offset to overlay address
|
||||
|
||||
ldrh r4, [r0, #(dsprotectpatchv1_nitro_static_init_offset - dsprotectpatchv1_stub_protectb1_offset)]
|
||||
ldr r3,= 0xE12FFF1E // bx lr
|
||||
str r3, [r4, r2]
|
||||
|
||||
adr r4, protectbX_patch
|
||||
ldmia r4!, {r5,r6}
|
||||
|
||||
adds r3, r0, #(dsprotectpatchv1_nitro_static_init_offset - dsprotectpatchv1_stub_protectb1_offset)
|
||||
1:
|
||||
ldmia r4!, {r7}
|
||||
ldrh r1, [r0]
|
||||
adds r1, r2
|
||||
stmia r1!, {r5,r6,r7}
|
||||
adds r0, #2
|
||||
cmp r0, r3
|
||||
bne 1b
|
||||
|
||||
ldr r7, dsprotectpatchv1_part2_address
|
||||
bx r7
|
||||
|
||||
continue_to_next:
|
||||
ldr r7, dsprotectpatchv1_part2_address
|
||||
adds r7, #(dsprotectpatchv1_continue_to_next - dsprotectpatchv1_entry2)
|
||||
bx r7
|
||||
|
||||
.global dsprotectpatchv1_stub_protectb1_offset
|
||||
dsprotectpatchv1_stub_protectb1_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv1_stub_protectb2_offset
|
||||
dsprotectpatchv1_stub_protectb2_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv1_stub_protectb3_offset
|
||||
dsprotectpatchv1_stub_protectb3_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv1_nitro_static_init_offset
|
||||
dsprotectpatchv1_nitro_static_init_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv1_overlay_id
|
||||
dsprotectpatchv1_overlay_id:
|
||||
.short 0
|
||||
|
||||
.balign 4
|
||||
|
||||
.global dsprotectpatchv1_base_offset
|
||||
dsprotectpatchv1_base_offset:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatchv1_part2_address
|
||||
dsprotectpatchv1_part2_address:
|
||||
.word 0
|
||||
|
||||
.pool
|
||||
|
||||
.arm
|
||||
protectbX_patch:
|
||||
ldr r0, dsprotectpatchv1_protectb1_return_value
|
||||
bx lr
|
||||
.global dsprotectpatchv1_protectb1_return_value
|
||||
dsprotectpatchv1_protectb1_return_value:
|
||||
.word 1830601
|
||||
.global dsprotectpatchv1_protectb2_return_value
|
||||
dsprotectpatchv1_protectb2_return_value:
|
||||
.word 1830203
|
||||
.global dsprotectpatchv1_protectb3_return_value
|
||||
dsprotectpatchv1_protectb3_return_value:
|
||||
.word 1828014
|
||||
|
||||
.section "dsprotectpatchv1_part2", "ax"
|
||||
|
||||
.thumb
|
||||
|
||||
.global dsprotectpatchv1_entry2
|
||||
.type dsprotectpatchv1_entry2, %function
|
||||
dsprotectpatchv1_entry2:
|
||||
adr r0, dsprotectpatchv1_stub_notprotectb1_offset
|
||||
adds r1, r0, #(dsprotectpatchv1_stub_notprotectb3_offset - dsprotectpatchv1_stub_notprotectb1_offset + 2)
|
||||
mov lr, r1
|
||||
2:
|
||||
ldrh r1, [r0]
|
||||
adds r1, r2
|
||||
adr r3, notprotectbX_patch
|
||||
ldmia r3!, {r4,r5,r6,r7}
|
||||
stmia r1!, {r4,r5,r6,r7}
|
||||
ldmia r3!, {r4,r5,r6}
|
||||
stmia r1!, {r4,r5,r6}
|
||||
adds r0, #2
|
||||
cmp r0, lr
|
||||
bne 2b
|
||||
|
||||
ldmia r3!, {r6,r7}
|
||||
|
||||
adds r2, #0x18
|
||||
adr r0, dsprotectpatchv1_stub_notprotectb1_offset
|
||||
ldrh r1, [r0, #(dsprotectpatchv1_stub_notprotectb2_offset - dsprotectpatchv1_stub_notprotectb1_offset)]
|
||||
str r6, [r1, r2]
|
||||
ldrh r1, [r0, #(dsprotectpatchv1_stub_notprotectb3_offset - dsprotectpatchv1_stub_notprotectb1_offset)]
|
||||
str r7, [r1, r2]
|
||||
|
||||
dsprotectpatchv1_continue_to_next:
|
||||
ldr r0, dsprotectpatchv1_nextAddress
|
||||
pop {r4-r7,pc}
|
||||
|
||||
.global dsprotectpatchv1_stub_notprotectb1_offset
|
||||
dsprotectpatchv1_stub_notprotectb1_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv1_stub_notprotectb2_offset
|
||||
dsprotectpatchv1_stub_notprotectb2_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv1_stub_notprotectb3_offset
|
||||
dsprotectpatchv1_stub_notprotectb3_offset:
|
||||
.short 0
|
||||
|
||||
.balign 4
|
||||
|
||||
.global dsprotectpatchv1_nextAddress
|
||||
dsprotectpatchv1_nextAddress:
|
||||
.word 0
|
||||
|
||||
.pool
|
||||
|
||||
.arm
|
||||
notprotectbX_patch:
|
||||
push {lr}
|
||||
.global dsprotectpatchv1_moveCallback
|
||||
dsprotectpatchv1_moveCallback:
|
||||
movs lr, r0
|
||||
movne r0, r1
|
||||
blxne lr
|
||||
.global dsprotectpatchv1_loadReturnValue
|
||||
dsprotectpatchv1_loadReturnValue:
|
||||
ldr r0, dsprotectpatchv1_notprotectb1_return_value
|
||||
pop {pc}
|
||||
.global dsprotectpatchv1_notprotectb1_return_value
|
||||
dsprotectpatchv1_notprotectb1_return_value:
|
||||
.word 1831551
|
||||
.global dsprotectpatchv1_notprotectb2_return_value
|
||||
dsprotectpatchv1_notprotectb2_return_value:
|
||||
.word 1830859
|
||||
.global dsprotectpatchv1_notprotectb3_return_value
|
||||
dsprotectpatchv1_notprotectb3_return_value:
|
||||
.word 1829648
|
||||
|
||||
.end
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
#include "sections.h"
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(dsprotectpatchv2);
|
||||
|
||||
extern "C" void dsprotectpatchv2_entry();
|
||||
extern u16 dsprotectpatchv2_stub_protectb1_offset;
|
||||
extern u16 dsprotectpatchv2_stub_protectb2_offset;
|
||||
extern u16 dsprotectpatchv2_stub_protectb3_offset;
|
||||
extern u16 dsprotectpatchv2_stub_protectb4_offset;
|
||||
extern u16 dsprotectpatchv2_am_init_offset;
|
||||
extern u16 dsprotectpatchv2_overlay_id;
|
||||
extern u32 dsprotectpatchv2_nextAddress;
|
||||
extern u32 dsprotectpatchv2_checksum_fix;
|
||||
extern u32 dsprotectpatchv2_base_offset;
|
||||
|
||||
extern u16 dsprotectpatchv2_store_checksum_fix;
|
||||
@@ -1,93 +0,0 @@
|
||||
.cpu arm946e-s
|
||||
.section "dsprotectpatchv2", "ax"
|
||||
.syntax unified
|
||||
.thumb
|
||||
|
||||
.global dsprotectpatchv2_entry
|
||||
.type dsprotectpatchv2_entry, %function
|
||||
dsprotectpatchv2_entry:
|
||||
push {r4-r7,lr}
|
||||
|
||||
ldmia r5!, {r0,r1,r2}
|
||||
adds r3, r2, r1 // bss address
|
||||
|
||||
adr r2, dsprotectpatchv2_stub_protectb1_offset
|
||||
ldrh r7, [r2, #(dsprotectpatchv2_overlay_id - dsprotectpatchv2_stub_protectb1_offset)]
|
||||
cmp r0, r7
|
||||
bne continue_to_next
|
||||
|
||||
ldr r7, [r2, #(dsprotectpatchv2_base_offset - dsprotectpatchv2_stub_protectb1_offset)]
|
||||
adds r1, r7 // add base offset to overlay address
|
||||
|
||||
ldrh r0, [r2, #(dsprotectpatchv2_am_init_offset - dsprotectpatchv2_stub_protectb1_offset)]
|
||||
ldr r7,= 0xE12FFF1E // bx lr
|
||||
str r7, [r1, r0]
|
||||
|
||||
adr r0, stub_patch_code
|
||||
ldmia r0!, {r4,r5,r6,r7}
|
||||
|
||||
subs r1, #4 // write from 4 bytes before the actual function address
|
||||
adds r0, r2, #(dsprotectpatchv2_stub_protectb4_offset - dsprotectpatchv2_stub_protectb1_offset)
|
||||
mov lr, r0
|
||||
patch_loop:
|
||||
ldrh r0, [r2]
|
||||
adds r2, #2
|
||||
adds r0, r1
|
||||
stmia r0!, {r3,r4,r5,r6} // bss address + code
|
||||
.global dsprotectpatchv2_store_checksum_fix
|
||||
dsprotectpatchv2_store_checksum_fix:
|
||||
str r7, [r0, #0] // checksum fix
|
||||
cmp r2, lr
|
||||
ble patch_loop
|
||||
|
||||
continue_to_next:
|
||||
ldr r0, dsprotectpatchv2_nextAddress
|
||||
pop {r4-r7,pc}
|
||||
|
||||
.balign 4
|
||||
|
||||
.global dsprotectpatchv2_stub_protectb1_offset
|
||||
dsprotectpatchv2_stub_protectb1_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv2_stub_protectb2_offset
|
||||
dsprotectpatchv2_stub_protectb2_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv2_stub_protectb3_offset
|
||||
dsprotectpatchv2_stub_protectb3_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv2_stub_protectb4_offset
|
||||
dsprotectpatchv2_stub_protectb4_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv2_am_init_offset
|
||||
dsprotectpatchv2_am_init_offset:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv2_overlay_id
|
||||
dsprotectpatchv2_overlay_id:
|
||||
.short 0
|
||||
|
||||
.global dsprotectpatchv2_base_offset
|
||||
dsprotectpatchv2_base_offset:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatchv2_nextAddress
|
||||
dsprotectpatchv2_nextAddress:
|
||||
.word 0
|
||||
|
||||
.pool
|
||||
|
||||
.arm
|
||||
stub_patch_code:
|
||||
ldr r12, (. - 4)
|
||||
ldr r2, [r12], #4
|
||||
ldr pc, [r12, r2, lsl #2]
|
||||
|
||||
.global dsprotectpatchv2_checksum_fix
|
||||
dsprotectpatchv2_checksum_fix:
|
||||
.word 0
|
||||
|
||||
.end
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
#include "sections.h"
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(dsprotectpatchv2s);
|
||||
|
||||
extern "C" void dsprotectpatchv2s_entry();
|
||||
extern u32 dsprotectpatchv2s_stub_instantdetect_offset;
|
||||
extern u32 dsprotectpatchv2s_overlay_id;
|
||||
extern u32 dsprotectpatchv2s_nextAddress;
|
||||
extern u32 dsprotectpatchv2s_checksum_fix;
|
||||
|
||||
extern u16 dsprotectpatchv2s_store_checksum_fix;
|
||||
@@ -1,64 +0,0 @@
|
||||
.cpu arm946e-s
|
||||
.section "dsprotectpatchv2s", "ax"
|
||||
.syntax unified
|
||||
.thumb
|
||||
|
||||
.global dsprotectpatchv2s_entry
|
||||
.type dsprotectpatchv2s_entry, %function
|
||||
dsprotectpatchv2s_entry:
|
||||
push {r4-r7,lr}
|
||||
|
||||
ldmia r5!, {r0,r1,r2,r3,r4}
|
||||
|
||||
ldr r7, dsprotectpatchv2s_overlay_id
|
||||
cmp r0, r7
|
||||
bne continue_to_next
|
||||
|
||||
movs r3, #0
|
||||
movs r7, #0
|
||||
stmia r4!, {r3,r7}
|
||||
stmia r4!, {r3,r7}
|
||||
str r3, [r4]
|
||||
|
||||
adr r0, stub_patch_code
|
||||
ldmia r0!, {r3,r4,r5,r6,r7}
|
||||
|
||||
ldr r0, dsprotectpatchv2s_stub_instantdetect_offset
|
||||
adds r0, r1
|
||||
stmia r0!, {r3,r4,r5,r6} // code
|
||||
.global dsprotectpatchv2s_store_checksum_fix
|
||||
dsprotectpatchv2s_store_checksum_fix:
|
||||
str r7, [r0, #0] // checksum fix
|
||||
|
||||
continue_to_next:
|
||||
ldr r0, dsprotectpatchv2s_nextAddress
|
||||
pop {r4-r7,pc}
|
||||
|
||||
.balign 4
|
||||
|
||||
.global dsprotectpatchv2s_stub_instantdetect_offset
|
||||
dsprotectpatchv2s_stub_instantdetect_offset:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatchv2s_overlay_id
|
||||
dsprotectpatchv2s_overlay_id:
|
||||
.word 0
|
||||
|
||||
.global dsprotectpatchv2s_nextAddress
|
||||
dsprotectpatchv2s_nextAddress:
|
||||
.word 0
|
||||
|
||||
.pool
|
||||
|
||||
.arm
|
||||
stub_patch_code:
|
||||
movs r3, r0
|
||||
pusheq {r0,r1,lr}
|
||||
pushne {r1,r2,r3}
|
||||
pop {r0,r1,pc}
|
||||
|
||||
.global dsprotectpatchv2s_checksum_fix
|
||||
dsprotectpatchv2s_checksum_fix:
|
||||
.word 0
|
||||
|
||||
.end
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "patches/platform/akrpg/AKRPGLoaderPlatform.h"
|
||||
#include "patches/platform/r4idsn/R4iDSNLoaderPlatform.h"
|
||||
#include "patches/platform/supercard/SuperCardLoaderPlatform.h"
|
||||
#include "patches/platform/ezp/EZPLoaderPlatform.h"
|
||||
#include "LoaderPlatformFactory.h"
|
||||
|
||||
LoaderPlatform* LoaderPlatformFactory::CreateLoaderPlatform() const
|
||||
@@ -40,6 +41,8 @@ LoaderPlatform* LoaderPlatformFactory::CreateLoaderPlatform() const
|
||||
return new R4iDSNLoaderPlatform();
|
||||
#elif defined(PICO_LOADER_TARGET_SUPERCARD)
|
||||
return new SuperCardLoaderPlatform();
|
||||
#elif defined(PICO_LOADER_TARGET_EZP)
|
||||
return new EZPLoaderPlatform();
|
||||
#else
|
||||
#error "No loader platform defined"
|
||||
return nullptr;
|
||||
|
||||
33
arm9/source/patches/platform/ezp/EZPLoaderPlatform.h
Normal file
33
arm9/source/patches/platform/ezp/EZPLoaderPlatform.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
#include "../LoaderPlatform.h"
|
||||
#include "ezpReadSectorsAsm.h"
|
||||
#include "ezpReadSdDataAsm.h"
|
||||
#include "ezpWriteSectorsAsm.h"
|
||||
|
||||
/// @brief Implementation of LoaderPlatform for the EZ-Flash Parallel flashcard
|
||||
class EZPLoaderPlatform : public LoaderPlatform
|
||||
{
|
||||
public:
|
||||
const SdReadPatchCode* CreateSdReadPatchCode(
|
||||
PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override
|
||||
{
|
||||
return patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||
{
|
||||
return new EZPReadSectorsPatchCode(patchHeap,
|
||||
patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||
{
|
||||
return new EZPReadSDDataPatchCode(patchHeap);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
const SdWritePatchCode* CreateSdWritePatchCode(
|
||||
PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override
|
||||
{
|
||||
return patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||
{
|
||||
return new EZPWriteSectorsPatchCode(patchHeap);
|
||||
});
|
||||
}
|
||||
};
|
||||
19
arm9/source/patches/platform/ezp/ezpReadSdDataAsm.h
Normal file
19
arm9/source/patches/platform/ezp/ezpReadSdDataAsm.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "sections.h"
|
||||
#include "thumbInstructions.h"
|
||||
|
||||
DEFINE_SECTION_SYMBOLS(ezp_readsddata);
|
||||
|
||||
extern "C" void ezp_readSdData(u32 srcSector, void* dst, u32 sectorCount, u32 sectorCountThisRead);
|
||||
|
||||
class EZPReadSDDataPatchCode : public PatchCode
|
||||
{
|
||||
public:
|
||||
explicit EZPReadSDDataPatchCode(PatchHeap& patchHeap)
|
||||
: PatchCode(SECTION_START(ezp_readsddata), SECTION_SIZE(ezp_readsddata), patchHeap) { }
|
||||
|
||||
const void* GetReadSDDataFunction() const
|
||||
{
|
||||
return GetAddressAtTarget((void*)ezp_readSdData);
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user