10 Commits

Author SHA1 Message Date
Gericom
e9a8c09a35 Merge pull request #22 from lifehackerhansol/develop
workflow: add release pipeline
2025-12-04 13:29:20 +01:00
lifehackerhansol
8e98796be2 workflow: add release pipeline
- Minor change in push pipeline to remove spaces from artifact name
- Add artifact move step to add all files to a single folder before
  pushing to artifacts
- Create release pipeline with the same steps that will upload a zipped
  package to every published release automatically
2025-12-03 21:00:11 -08:00
Mow
a8f5d880b2 Improved DSProtect patches 2025-12-03 16:22:06 +01:00
Gericom
7aba420201 Merge pull request #15 from lifehackerhansol/ez5n
platform: add support for the EZ-Flash Parallel
2025-12-02 19:57:14 +01:00
Gericom
8761081c73 Added more game codes to DLDI blacklist. Fixes Final Fantasy Crystal Chronicles - Ring of Fates (EU and US) and Nanashi no Geemu. Fixes #17 2025-12-02 19:14:59 +01:00
lifehackerhansol
0dd41f4220 platform: add support for the EZ-Flash Parallel 2025-12-02 08:40:36 -08:00
Gericom
485598ab79 Removed unused entrypoint_t typedef 2025-11-30 13:03:13 +01:00
Gericom
b2fabe5d97 Clear all arm9 cpu registers before jumping to the arm9 entry point. Fixes Cake Ninja DSiWare titles. 2025-11-30 13:00:35 +01:00
Gericom
4701b9d1b7 Fixed the DSProtect v2.03 patch (thanks Mow). Fixes #13 2025-11-29 11:21:35 +01:00
IceKareemCheese
5c37a57560 Add V2GE Rev 2 to the aplist 2025-11-26 18:29:16 +00:00
30 changed files with 958 additions and 744 deletions

View File

@@ -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
View 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

View File

@@ -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) | ❌ |

View File

@@ -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;
}

View 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);

View 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

View File

@@ -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()

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View 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);
});
}
};

View 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