Skip to content

Commit

Permalink
- Support read patches for Game Boy Player Start-up Disc.
Browse files Browse the repository at this point in the history
  • Loading branch information
Extrems committed Jan 24, 2019
1 parent 03d8d17 commit ca165f7
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 82 deletions.
44 changes: 10 additions & 34 deletions cube/patches/base/base.S
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ _start:
b stop_di_irq
b trigger_di_irq
b __DSPHandler
b patched_memcpy_dbg
b exit_to_pref # checks for a button combo and exits if true

.globl trigger_di_irq
Expand Down Expand Up @@ -113,39 +112,15 @@ process_read_queue:

.globl patched_memcpy
patched_memcpy:
mr r4, r24
cmpwi r3, 0x0500
beq customhandler
cmpwi r3, 0xF00
bgt redirecthandler
blr
customhandler:
lis r4, ext_handler_custom@h
ori r4, r4, ext_handler_custom@l
blr
redirecthandler:
li r3, 0xF00
blr

.globl patched_memcpy_dbg
patched_memcpy_dbg:
mr r4, r24
rlwinm r3, r3, 0, 16, 31
cmpwi r3, 0x0500
beq customhandlerdbg
cmpwi r3, 0xF00
bgt redirecthandlerdbg
addis r3, r3, 0x8000
blr
customhandlerdbg:
lis r4, ext_handler_custom@h
ori r4, r4, ext_handler_custom@l
addis r3, r3, 0x8000
blr
redirecthandlerdbg:
li r3, 0xF00
addis r3, r3, 0x8000
blr
subis r0, r3, 0x8000
cmplwi r0, 0x1000
bgelr
cmplwi r0, 0x0500
bne memcpy
lis r4, ext_handler_custom@ha
addi r4, r4, ext_handler_custom@l
li r5, ext_handler_custom_end-ext_handler_custom
b memcpy

.globl ext_handler_custom
ext_handler_custom:
Expand Down Expand Up @@ -181,3 +156,4 @@ ext_handler_custom:
ori r5, r5, process_read_queue@l
mtsrr0 r5
rfi
ext_handler_custom_end:
25 changes: 4 additions & 21 deletions cube/patches/wkf/base.S
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
.globl _start, __main
_start:
b patched_memcpy # void patched_memcpy(dst,src,size)
b patched_memcpy_dbg
b adjust_read
b exit_to_pref # checks for a button combo and exits if true

Expand All @@ -35,23 +34,7 @@ dcache_flush_icache_inv:

.globl patched_memcpy
patched_memcpy:
mr r4, r24
cmpwi r3, 0xF00
bgt redirecthandler
blr
redirecthandler:
li r3, 0xF00
blr

.globl patched_memcpy_dbg
patched_memcpy_dbg:
mr r4, r24
rlwinm r3, r3, 0, 16, 31
cmpwi r3, 0xF00
addis r3, r3, 0x8000
bgt redirecthandlerdbg
blr
redirecthandlerdbg:
li r3, 0xF00
blr

subis r0, r3, 0x8000
cmplwi r0, 0x1000
bgelr
b memcpy
8 changes: 3 additions & 5 deletions cube/swiss/include/patcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ enum patchIds {
#define STOP_DI_IRQ (void*)(LO_RESERVE | 0x08)
#define READ_TRIGGER_INTERRUPT (void*)(LO_RESERVE | 0x0C)
#define DSP_HANDLER_HOOK (void*)(LO_RESERVE | 0x10)
#define PATCHED_MEMCPY_DBG (void*)(LO_RESERVE | 0x14)
#define IGR_CHECK (void*)(LO_RESERVE | 0x18)
#define IGR_CHECK (void*)(LO_RESERVE | 0x14)

/* Function jump locations for the DVD patch */
#define ENABLE_BACKUP_DISC (void*)(LO_RESERVE_DVD | 0x00)
Expand All @@ -155,9 +154,8 @@ enum patchIds {

/* Function jump locations for the WKF/WASP patch */
#define PATCHED_MEMCPY_WKF (void*)(LO_RESERVE)
#define PATCHED_MEMCPY_DBG_WKF (void*)(LO_RESERVE | 0x04)
#define ADJUST_LBA_OFFSET (void*)(LO_RESERVE | 0x08)
#define IGR_CHECK_WKF (void*)(LO_RESERVE | 0x0C)
#define ADJUST_LBA_OFFSET (void*)(LO_RESERVE | 0x04)
#define IGR_CHECK_WKF (void*)(LO_RESERVE | 0x08)

/* Function jump locations for the USBGecko patch */
#define PATCHED_MEMCPY_USB (void*)(LO_RESERVE)
Expand Down
85 changes: 63 additions & 22 deletions cube/swiss/source/patcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ static u32 top_addr = VAR_PATCHES_BASE;
FuncPattern ReadDebug = {56, 23, 18, 3, 2, 4, 0, 0, "Read (Debug)", 0};
FuncPattern ReadCommon = {68, 30, 18, 5, 2, 3, 0, 0, "Read (Common)", 0};
FuncPattern ReadUncommon = {66, 29, 17, 5, 2, 3, 0, 0, "Read (Uncommon)", 0};
FuncPattern ReadProDG = {67, 29, 17, 5, 2, 6, 0, 0, "Read (ProDG)", 0};

// OSExceptionInit
FuncPattern OSExceptionInitSig = {160, 39, 14, 14, 20, 7, 0, 0, "OSExceptionInit", 0};
FuncPattern OSExceptionInitSigDBG = {164, 61, 6, 18, 14, 14, 0, 0, "OSExceptionInitDBG", 0};
FuncPattern OSExceptionInitSigDebug = {164, 61, 6, 18, 14, 14, 0, 0, "OSExceptionInit (Debug)", 0};
FuncPattern OSExceptionInitSigProDG = {151, 45, 14, 16, 13, 9, 0, 0, "OSExceptionInit (ProDG)", 0};

// __DVDInterruptHandler
u16 _dvdinterrupthandler_part[3] = {
Expand Down Expand Up @@ -461,27 +463,40 @@ u32 Patch_DVDLowLevelReadForWKF(void *addr, u32 length, int dataType) {
if(patched == 0x11) break; // we're done

// Patch Read to adjust the offset for fragmented files
if( *(vu32*)(addr+i) != 0x7C0802A6 )
if( *(vu32*)(addr+i) != 0x7C0802A6 && *(vu32*)(addr+i+4) != 0x7C0802A6 )
continue;

FuncPattern fp;
make_pattern( addr, i / 4, length, &fp );

if(compare_pattern(&fp, &OSExceptionInitSig))
{
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 472)-(u32)(addr));
print_gecko("Found:[OSExceptionInit] @ %08X\r\n", properAddress);
*(vu32*)(addr + i + 472) = branchAndLink(PATCHED_MEMCPY_WKF, properAddress);
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 488)-(u32)(addr));
print_gecko("Found:[%s] @ %08X for WKF\r\n", OSExceptionInitSig.Name, properAddress);
*(vu32*)(addr + i + 488) = branchAndLink(PATCHED_MEMCPY_WKF, properAddress);
*(vu32*)(addr + i + 496) = 0x38800100;
*(vu32*)(addr + i + 512) = 0x38800100;
patched |= 0x10;
}
// Debug version of the above
if(compare_pattern(&fp, &OSExceptionInitSigDBG))
if(compare_pattern(&fp, &OSExceptionInitSigDebug))
{
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 512)-(u32)(addr));
print_gecko("Found:[OSExceptionInitDBG] @ %08X\r\n", properAddress);
*(vu32*)(addr + i + 512) = branchAndLink(PATCHED_MEMCPY_DBG_WKF, properAddress);
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 520)-(u32)(addr));
print_gecko("Found:[%s] @ %08X for WKF\r\n", OSExceptionInitSigDebug.Name, properAddress);
*(vu32*)(addr + i + 520) = branchAndLink(PATCHED_MEMCPY_WKF, properAddress);
*(vu32*)(addr + i + 528) = 0x38800100;
*(vu32*)(addr + i + 544) = 0x38800100;
patched |= 0x10;
}
if(compare_pattern(&fp, &OSExceptionInitSigProDG))
{
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 460)-(u32)(addr));
print_gecko("Found:[%s] @ %08X for WKF\r\n", OSExceptionInitSigProDG.Name, properAddress);
*(vu32*)(addr + i + 460) = branchAndLink(PATCHED_MEMCPY_WKF, properAddress);
*(vu32*)(addr + i + 468) = 0x38800100;
*(vu32*)(addr + i + 484) = 0x38800100;
patched |= 0x10;
}
}
if(compare_pattern(&fp, &ReadCommon)) {
// Overwrite the DI start to go to our code that will manipulate offsets for frag'd files.
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 0x84)-(u32)(addr));
Expand All @@ -501,6 +516,12 @@ u32 Patch_DVDLowLevelReadForWKF(void *addr, u32 length, int dataType) {
*(vu32*)(addr + i + 0x7C) = branchAndLink(ADJUST_LBA_OFFSET, properAddress);
patched |= 0x100;
}
if(compare_pattern(&fp, &ReadProDG)) {
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 0x74)-(u32)(addr));
print_gecko("Found:[%s] @ %08X for WKF\r\n", ReadProDG.Name, properAddress - 0x74);
*(vu32*)(addr + i + 0x74) = branchAndLink(ADJUST_LBA_OFFSET, properAddress);
patched |= 0x100;
}
}
return patched;
}
Expand All @@ -527,13 +548,13 @@ u32 Patch_DVDLowLevelReadForUSBGecko(void *addr, u32 length, int dataType) {
patched |= 0x10;
}
// Debug version of the above
if(compare_pattern(&fp, &OSExceptionInitSigDBG))
if(compare_pattern(&fp, &OSExceptionInitSigDebug))
{
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 512)-(u32)(addr));
print_gecko("Found:[OSExceptionInitDBG] @ %08X\r\n", properAddress);
print_gecko("Found:[OSExceptionInit] @ %08X\r\n", properAddress);
*(vu32*)(addr + i + 512) = branchAndLink(PATCHED_MEMCPY_DBG_USB, properAddress);
patched |= 0x10;
}
}
if(compare_pattern(&fp, &ReadCommon)) {
// Overwrite the DI start to go to our code that will manipulate offsets for frag'd files.
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 0x84)-(u32)(addr));
Expand Down Expand Up @@ -572,7 +593,7 @@ u32 Patch_DVDLowLevelReadForDVD(void *addr, u32 length, int dataType) {

for(i = 0; i < length; i+=4) {
// Patch Read (called from DVDLowLevelRead) to read data from SD if it has been patched.
if( *(vu32*)(addr+i) != 0x7C0802A6 )
if( *(vu32*)(addr+i) != 0x7C0802A6 && *(vu32*)(addr+i+4) != 0x7C0802A6 )
continue;

FuncPattern fp;
Expand All @@ -597,6 +618,12 @@ u32 Patch_DVDLowLevelReadForDVD(void *addr, u32 length, int dataType) {
*(vu32*)(addr + i + 0x7C) = branchAndLink(READ_REAL_OR_PATCHED, properAddress);
return 1;
}
if(compare_pattern(&fp, &ReadProDG)) {
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr + i + 0x74)-(u32)(addr));
print_gecko("Found:[%s] @ %08X for DVD\r\n", ReadProDG.Name, properAddress - 0x74);
*(vu32*)(addr + i + 0x74) = branchAndLink(READ_REAL_OR_PATCHED, properAddress);
return 1;
}
}
return 0;
}
Expand All @@ -608,21 +635,34 @@ u32 Patch_DVDLowLevelRead(void *addr, u32 length, int dataType) {
FuncPattern DSPHandler = {265, 103, 23, 34, 32, 9, 0, 0, "__DSPHandler", 0};
while(addr_start<addr_end) {
// Patch the memcpy call in OSExceptionInit to copy our code to 0x80000500 instead of anything else.
if(*(vu32*)(addr_start) == 0x7C0802A6)
if(*(vu32*)(addr_start) == 0x7C0802A6 || *(vu32*)(addr_start + 4) == 0x7C0802A6)
{
if( find_pattern( addr, (u32*)(addr_start)-(u32*)(addr), length, &OSExceptionInitSig ) )
{
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr_start + 472)-(u32)(addr));
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr_start + 488)-(u32)(addr));
print_gecko("Found:[OSExceptionInit] @ %08X\r\n", properAddress);
*(vu32*)(addr_start + 472) = branchAndLink(PATCHED_MEMCPY, properAddress);
*(vu32*)(addr_start + 488) = branchAndLink(PATCHED_MEMCPY, properAddress);
*(vu32*)(addr_start + 496) = 0x38800100;
*(vu32*)(addr_start + 512) = 0x38800100;
patched |= 0x100;
}
// Debug version of the above
else if( find_pattern( addr, (u32*)(addr_start)-(u32*)(addr), length, &OSExceptionInitSigDBG ) )
else if( find_pattern( addr, (u32*)(addr_start)-(u32*)(addr), length, &OSExceptionInitSigDebug ) )
{
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr_start + 512)-(u32)(addr));
print_gecko("Found:[OSExceptionInitDBG] @ %08X\r\n", properAddress);
*(vu32*)(addr_start + 512) = branchAndLink(PATCHED_MEMCPY_DBG, properAddress);
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr_start + 520)-(u32)(addr));
print_gecko("Found:[OSExceptionInit] @ %08X\r\n", properAddress);
*(vu32*)(addr_start + 520) = branchAndLink(PATCHED_MEMCPY, properAddress);
*(vu32*)(addr_start + 528) = 0x38800100;
*(vu32*)(addr_start + 544) = 0x38800100;
patched |= 0x100;
}
else if( find_pattern( addr, (u32*)(addr_start)-(u32*)(addr), length, &OSExceptionInitSigProDG ) )
{
void *properAddress = Calc_ProperAddress(addr, dataType, (u32)(addr_start + 460)-(u32)(addr));
print_gecko("Found:[OSExceptionInit] @ %08X\r\n", properAddress);
*(vu32*)(addr_start + 460) = branchAndLink(PATCHED_MEMCPY, properAddress);
*(vu32*)(addr_start + 468) = 0x38800100;
*(vu32*)(addr_start + 484) = 0x38800100;
patched |= 0x100;
}
// Audio Streaming Hook (only if required)
Expand All @@ -639,7 +679,8 @@ u32 Patch_DVDLowLevelRead(void *addr, u32 length, int dataType) {
make_pattern( addr, (u32*)(addr_start)-(u32*)(addr), length, &fp );
if(compare_pattern(&fp, &ReadCommon) // Common Read function
|| compare_pattern(&fp, &ReadDebug) // Debug Read function
|| compare_pattern(&fp, &ReadUncommon)) // Uncommon Read function
|| compare_pattern(&fp, &ReadUncommon) // Uncommon Read function
|| compare_pattern(&fp, &ReadProDG)) // ProDG Read function
{
u32 iEnd = 4;
while(*(vu32*)(addr_start + iEnd) != 0x4E800020) iEnd += 4; // branch relative from the end
Expand Down

0 comments on commit ca165f7

Please sign in to comment.