mirror of
https://github.com/ApacheThunder/GBA-Exploader.git
synced 2025-06-18 11:35:38 -04:00
Resolved SuperCard save issues ...
* Fixed remaining save issues for most SuperCards. * Patching system from SCFW implemented for SuperCards. Prepatched roms no longer required for use with GBA-Exploader for SuperCards! * Initial EZ Flash Omega/Omega DE support! Note that there are still save issues right now. DE has partial saves working with just 128KB saves not working. (so Pokemon games do not hold saves currently)
This commit is contained in:
parent
99ed31e3e7
commit
8aa7cfdefa
@ -38,18 +38,19 @@ typedef bool BOOL ;
|
||||
//---------------------------------------------------
|
||||
//DS 卡 基本操作
|
||||
//Arm9 方面基本操作容许ARM7访问slot1
|
||||
void Enable_Arm7DS(void);
|
||||
// void Enable_Arm7DS(void);
|
||||
|
||||
//Arm9 方面基本操作容许ARM9访问slot1
|
||||
void Enable_Arm9DS(void);
|
||||
// void Enable_Arm9DS(void);
|
||||
|
||||
|
||||
//下面是访问震动卡的函数
|
||||
#define FlashBase 0x08000000
|
||||
#define PSRAMBase_S98 0x08800000
|
||||
#define PSRAMBase_S98 0x08800000 // EZ Flash Omega PSRAM location while in Kernal mode. (only writable in Kernal mode)
|
||||
#define FlashBase_S98 0x09000000
|
||||
#define _Ez5PsRAM 0x08000000
|
||||
#define SAVE_sram_base 0x0E000000
|
||||
#define SRAM_ADDR 0x0A000000
|
||||
#define SRAM_ADDR_OMEGA 0x0E000000
|
||||
#define RTC_ENABLE ((vu16*)0x080000C8)
|
||||
void OpenNorWrite();
|
||||
void CloseNorWrite();
|
||||
void SetRompage(u16 page);
|
||||
@ -58,9 +59,13 @@ typedef bool BOOL ;
|
||||
void Set_AUTO_save(u16 mode);
|
||||
u16 Read_S71NOR_ID(); // For Reading EZFlash Omega ID
|
||||
u16 Read_S98NOR_ID(); // For Reading EZFlash Omega ID
|
||||
void SetPSRampage(u16 page); // EZFlash Omega uses this instead of regular SetRamPage
|
||||
void SetPSRampage(u16 page); // EZFlash Omega uses this to change what 8MB of 32MB PSRAM is accessible at 0x08800000
|
||||
void Set_RTC_status(u16 status); // EZFlash Omega RTC thingy
|
||||
u16 Read_SET_info(u32 offset);
|
||||
void rtc_toggle(bool enable);
|
||||
void SetbufferControl(u16 control);
|
||||
void Omega_Bank_Switching(u8 bank);
|
||||
void Omega_InitFatBuffer(BYTE saveMODE);
|
||||
void OpenRamWrite();
|
||||
void CloseRamWrite();
|
||||
void SetSerialMode();
|
||||
@ -68,13 +73,12 @@ typedef bool BOOL ;
|
||||
void chip_reset();
|
||||
void Block_EraseIntel(u32 blockAdd);
|
||||
void Block_Erase(u32 blockAdd);
|
||||
// void ReadNorFlash(u8* pBuf,u32 address,u16 len);
|
||||
// void ReadNorFlash(u8* pBuf,u32 address,u16 len); // Not used anywhere right now. Disabled out for now.
|
||||
void WriteNorFlashINTEL(u32 address,u8 *buffer,u32 size);
|
||||
void WriteNorFlash(u32 address,u8 *buffer,u32 size);
|
||||
void WriteSram(uint32 address, u8* data , uint32 size );
|
||||
void ReadSram(uint32 address, u8* data , uint32 size );
|
||||
void SetShake(u16 data);
|
||||
void Omega_Bank_Switching(u8 bank);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "dscard.h"
|
||||
#include "string.h"
|
||||
#include "io_sc_common.h"
|
||||
|
||||
#include "tonccpy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -133,6 +133,43 @@ void Set_RTC_status(u16 status) {
|
||||
*(u16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void rtc_toggle(bool enable) {
|
||||
if (enable) { *RTC_ENABLE = 1; } else { *RTC_ENABLE = 0; }
|
||||
}
|
||||
|
||||
void Omega_Bank_Switching(u8 bank) {
|
||||
*((vu8*)(SRAM_ADDR_OMEGA+0x5555)) = 0xAA;
|
||||
*((vu8*)(SRAM_ADDR_OMEGA+0x2AAA)) = 0x55;
|
||||
*((vu8*)(SRAM_ADDR_OMEGA+0x5555)) = 0xB0;
|
||||
*((vu8*)SRAM_ADDR_OMEGA) = bank;
|
||||
}
|
||||
|
||||
void SetbufferControl(u16 control) {
|
||||
*(u16*)0x9fe0000 = 0xd200;
|
||||
*(u16*)0x8000000 = 0x1500;
|
||||
*(u16*)0x8020000 = 0xd200;
|
||||
*(u16*)0x8040000 = 0x1500;
|
||||
*(u16*)0x9420000 = control; //A1
|
||||
*(u16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
static u32 FAT_table_buffer[0x400/4];
|
||||
|
||||
void Omega_InitFatBuffer(BYTE saveMODE) {
|
||||
toncset((void*)FAT_table_buffer, 0, (0x400/4));
|
||||
FAT_table_buffer[2] = 0xFFFFFFFF;
|
||||
// FAT_table_buffer[0x1F0/4] = 0; //size
|
||||
FAT_table_buffer[0x1F4/4] = 0x2; // 0x1 == rom copy to psram // 0x2 == copy mode
|
||||
// FAT_table_buffer[0x1F8/4] = 0; // secort of cluster
|
||||
// FAT_table_buffer[0x1FC/4] = (0x31<<24) | 0x20000; // save mode and save file size
|
||||
FAT_table_buffer[0x1FC/4] = (saveMODE<<24) | 0x10000; // save mode and save file size
|
||||
SetbufferControl(1);
|
||||
// tonccpy((void*)0x9E00000, FAT_table_buffer, 0x400);
|
||||
// dmaCopy(FAT_table_buffer, (void*)0x9E00000, 0x400);
|
||||
tonccpy((void*)0x9E00000, FAT_table_buffer, 0x400);
|
||||
SetbufferControl(3);
|
||||
SetbufferControl(0);
|
||||
}
|
||||
|
||||
void SetRampage(u16 page) {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
@ -188,15 +225,14 @@ u32 ReadNorFlashID() {
|
||||
fwrite((void*)(FlashBase+0x2002), 2, 1, testFile);
|
||||
fclose(testFile);
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
if ((id1 != 0x227E) || (id2 != 0x227E)) {
|
||||
if (checkForSuperCard()) {
|
||||
ID = 0x227E2202;
|
||||
return 0x227E0000;
|
||||
}
|
||||
// Check For EZ Flash Omega
|
||||
SetRompage(0x8002);
|
||||
SetRompage(0x8000);
|
||||
id1 = Read_S98NOR_ID();
|
||||
if ((id1 == 0x223D)) {
|
||||
ID = 0x227EEA00;
|
||||
@ -507,7 +543,7 @@ void WriteNorFlashINTEL(u32 address,u8 *buffer,u32 size) {
|
||||
v1 = *((vu16*)(FlashBase+mapaddress+(loopwrite>>1)));
|
||||
v2 = *((vu16*)(FlashBase+mapaddress+(loopwrite>>1)+0x2000));
|
||||
if((v1==0x90) || (v2==0x90)) { // error response, hopefully this never actually happens?
|
||||
WriteSram(0xA000000,(u8 *)buf,0x8000);
|
||||
WriteSram(SRAM_ADDR,(u8 *)buf,0x8000);
|
||||
while(1);
|
||||
break;
|
||||
}
|
||||
@ -571,21 +607,14 @@ void WriteNorFlash(u32 address,u8 *buffer,u32 size) {
|
||||
}
|
||||
}
|
||||
|
||||
void Omega_Bank_Switching(u8 bank) {
|
||||
*((vu8 *)(SAVE_sram_base+0x5555)) = 0xAA ;
|
||||
*((vu8 *)(SAVE_sram_base+0x2AAA)) = 0x55 ;
|
||||
*((vu8 *)(SAVE_sram_base+0x5555)) = 0xB0 ;
|
||||
*((vu8 *)(SAVE_sram_base+0x0000)) = bank ;
|
||||
}
|
||||
|
||||
void WriteSram(uint32 address, u8* data , uint32 size ) {
|
||||
uint32 i ;
|
||||
for(i=0;i<size;i++)*(u8*)(address+i)=data[i];
|
||||
}
|
||||
|
||||
void ReadSram(uint32 address, u8* data , uint32 size ) {
|
||||
void WriteSram(uint32 address, u8* data, uint32 size) {
|
||||
uint32 i;
|
||||
for(i=0;i<size;i++)data[i] = *(u8*)(address+i);
|
||||
for(i = 0; i < size; i++)*(u8*)(address+i) = data[i];
|
||||
}
|
||||
|
||||
void ReadSram(uint32 address, u8* data, uint32 size) {
|
||||
uint32 i;
|
||||
for(i = 0; i < size; i++)data[i] = *(u8*)(address + i);
|
||||
}
|
||||
|
||||
void OpenRamWrite() {
|
||||
|
72
arm9/include/find.c
Normal file
72
arm9/include/find.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include <nds.h>
|
||||
#include <stddef.h> // NULL
|
||||
//#include <string.h> // memcmp
|
||||
//#include <limits.h>
|
||||
|
||||
// (memcmp is slower)
|
||||
//#define memcmp __builtin_memcmp
|
||||
|
||||
//#define TABLE_SIZE (UCHAR_MAX + 1) // 256
|
||||
|
||||
/*
|
||||
* Look for @find and return the position of it.
|
||||
* Brute Force algorithm
|
||||
*/
|
||||
u32* memsearch32(const u32* start, u32 dataSize, const u32* find, u32 findSize, bool forward) {
|
||||
u32 dataLen = dataSize/sizeof(u32);
|
||||
u32 findLen = findSize/sizeof(u32);
|
||||
|
||||
const u32* end = forward ? (start + dataLen) : (start - dataLen);
|
||||
for (u32* addr = (u32*)start; addr != end; forward ? ++addr : --addr) {
|
||||
bool found = true;
|
||||
for (u32 j = 0; j < findLen; ++j) {
|
||||
if (addr[j] != find[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return (u32*)addr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
u16* memsearch16(const u16* start, u32 dataSize, const u16* find, u32 findSize, bool forward) {
|
||||
u32 dataLen = dataSize/sizeof(u16);
|
||||
u32 findLen = findSize/sizeof(u16);
|
||||
|
||||
const u16* end = forward ? (start + dataLen) : (start - dataLen);
|
||||
for (u16* addr = (u16*)start; addr != end; forward ? ++addr : --addr) {
|
||||
bool found = true;
|
||||
for (u32 j = 0; j < findLen; ++j) {
|
||||
if (addr[j] != find[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return (u16*)addr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
u8* memsearch8(const u8* start, u32 dataSize, const u8* find, u32 findSize, bool forward) {
|
||||
u32 dataLen = dataSize/sizeof(u8);
|
||||
u32 findLen = findSize/sizeof(u8);
|
||||
|
||||
const u8* end = forward ? (start + dataLen) : (start - dataLen);
|
||||
for (u8* addr = (u8*)start; addr != end; forward ? ++addr : --addr) {
|
||||
bool found = true;
|
||||
for (u32 j = 0; j < findLen; ++j) {
|
||||
if (addr[j] != find[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return (u8*)addr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
21
arm9/include/find.h
Normal file
21
arm9/include/find.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef FIND_H
|
||||
#define FIND_H
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// COMMON
|
||||
//u8* memsearch(const u8* start, u32 dataSize, const u8* find, u32 findSize);
|
||||
extern u32* memsearch32(const u32* start, u32 dataSize, const u32* find, u32 findSize, bool forward);
|
||||
extern u16* memsearch16(const u16* start, u32 dataSize, const u16* find, u32 findSize, bool forward);
|
||||
extern u8* memsearch8(const u8* start, u32 dataSize, const u8* find, u32 findSize, bool forward);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FIND_H
|
||||
|
@ -29,6 +29,10 @@
|
||||
|
||||
#include "io_sc_common.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
_SC_changeMode (was SC_Unlock)
|
||||
Added by MightyMax
|
||||
@ -52,3 +56,58 @@ void _SC_changeMode16(u16 mode) {
|
||||
*unlockAddress = mode;
|
||||
}
|
||||
|
||||
void twoByteCpy(u16 *dst, const u16 *src, u32 size) {
|
||||
if (size == 0 || dst == NULL || src == NULL)return;
|
||||
|
||||
u32 count;
|
||||
u16 *dst16; // hword destination
|
||||
u8 *src8; // byte source
|
||||
|
||||
// Ideal case: copy by 4x words. Leaves tail for later.
|
||||
if (((u32)src|(u32)dst) %4 == 0 && size >= 4) {
|
||||
u32 *src32= (u32*)src, *dst32= (u32*)dst;
|
||||
|
||||
count = size/4;
|
||||
u32 tmp = count&3;
|
||||
count /= 4;
|
||||
|
||||
// Duff's Device, good friend!
|
||||
switch(tmp) {
|
||||
do { *dst32++ = *src32++;
|
||||
case 3: *dst32++ = *src32++;
|
||||
case 2: *dst32++ = *src32++;
|
||||
case 1: *dst32++ = *src32++;
|
||||
case 0: ; } while (count--);
|
||||
}
|
||||
|
||||
// Check for tail
|
||||
size &= 3;
|
||||
if (size == 0)return;
|
||||
|
||||
src8 = (u8*)src32;
|
||||
dst16 = (u16*)dst32;
|
||||
} else {
|
||||
// Unaligned
|
||||
|
||||
u32 dstOfs = (u32)dst&1;
|
||||
src8 = (u8*)src;
|
||||
dst16 = (u16*)(dst-dstOfs);
|
||||
|
||||
// Head: 1 byte.
|
||||
if (dstOfs != 0) {
|
||||
*dst16 = (*dst16 & 0xFF) | *src8++<<8;
|
||||
dst16++;
|
||||
if (--size == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unaligned main: copy by 2x byte.
|
||||
count = size/2;
|
||||
while (count--) {
|
||||
*dst16++ = src8[0] | src8[1]<<8;
|
||||
src8 += 2;
|
||||
}
|
||||
|
||||
// Tail: 1 byte.
|
||||
if (size & 1)*dst16 = (*dst16 &~ 0xFF) | *src8;
|
||||
}
|
@ -48,6 +48,7 @@ extern "C" {
|
||||
|
||||
extern void _SC_changeMode(u8 mode);
|
||||
extern void _SC_changeMode16(u16 mode);
|
||||
extern void twoByteCpy(u16 *dst, const u16 *src, u32 size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
348
arm9/include/sc_patches.c
Normal file
348
arm9/include/sc_patches.c
Normal file
@ -0,0 +1,348 @@
|
||||
#include <nds.h>
|
||||
|
||||
#include "io_sc_common.h"
|
||||
|
||||
u32 prefetchPatch[8] = {
|
||||
0xE59F000C, // LDR R0, =0x4000204
|
||||
0xE59F100C, // LDR R1, =0x4000
|
||||
0xE4A01000, // STRT R1, [R0]
|
||||
0xE59F0008, // LDR R0, =0x80000C0 (this changes, depending on the ROM)
|
||||
0xE1A0F000, // MOV PC, R0
|
||||
0x04000204,
|
||||
0x00004000,
|
||||
0x080000C0
|
||||
};
|
||||
|
||||
static const u8 sDbzLoGUPatch1[0x24] = {
|
||||
0x0A, 0x1C, 0x40, 0x0B, 0xE0, 0x21, 0x09, 0x05, 0x41, 0x18, 0x07, 0x31, 0x00, 0x23, 0x08, 0x78,
|
||||
0x10, 0x70, 0x01, 0x33, 0x01, 0x32, 0x01, 0x39, 0x07, 0x2B, 0xF8, 0xD9, 0x00, 0x20, 0x70, 0xBC,
|
||||
0x02, 0xBC, 0x08, 0x47
|
||||
};
|
||||
|
||||
static const u8 sDbzLoGUPatch2[0x28] = {
|
||||
0x70, 0xB5, 0x00, 0x04, 0x0A, 0x1C, 0x40, 0x0B, 0xE0, 0x21, 0x09, 0x05, 0x41, 0x18, 0x07, 0x31,
|
||||
0x00, 0x23, 0x10, 0x78, 0x08, 0x70, 0x01, 0x33, 0x01, 0x32, 0x01, 0x39, 0x07, 0x2B, 0xF8, 0xD9,
|
||||
0x00, 0x20, 0x70, 0xBC, 0x02, 0xBC, 0x08, 0x47
|
||||
};
|
||||
|
||||
static const u8 wwTwistedPatch[0xF0] = {
|
||||
0x1F, 0x24, 0x1F, 0xB4, 0x33, 0x48, 0x01, 0x21, 0x01, 0x60, 0x33, 0x48, 0x01, 0x21, 0x01, 0x60,
|
||||
0x32, 0x49, 0x0A, 0x68, 0x10, 0x23, 0x1A, 0x40, 0x1E, 0xD1, 0x30, 0x49, 0x0A, 0x68, 0x02, 0x23,
|
||||
0x1A, 0x40, 0x0D, 0xD0, 0x2E, 0x48, 0x01, 0x68, 0x01, 0x22, 0x91, 0x42, 0x02, 0xDB, 0x09, 0x19,
|
||||
0x01, 0x60, 0x38, 0xE0, 0x2A, 0x48, 0x01, 0x22, 0x02, 0x60, 0x12, 0x19, 0x02, 0x60, 0x32, 0xE0,
|
||||
0x27, 0x48, 0x01, 0x68, 0x01, 0x22, 0x91, 0x42, 0x00, 0xDB, 0x01, 0xE0, 0x02, 0x60, 0x11, 0x1C,
|
||||
0x24, 0x4B, 0xC9, 0x18, 0x01, 0x60, 0x26, 0xE0, 0x20, 0x49, 0x0A, 0x68, 0x20, 0x23, 0x1A, 0x40,
|
||||
0x1E, 0xD1, 0x1E, 0x49, 0x0A, 0x68, 0x02, 0x23, 0x1A, 0x40, 0x0D, 0xD0, 0x1C, 0x48, 0x01, 0x68,
|
||||
0x1D, 0x4A, 0x91, 0x42, 0x02, 0xDC, 0x09, 0x1B, 0x01, 0x60, 0x14, 0xE0, 0x18, 0x48, 0x1A, 0x4A,
|
||||
0x02, 0x60, 0x12, 0x1B, 0x02, 0x60, 0x0E, 0xE0, 0x15, 0x48, 0x01, 0x68, 0x16, 0x4A, 0x91, 0x42,
|
||||
0x00, 0xDC, 0x01, 0xE0, 0x02, 0x60, 0x11, 0x1C, 0x12, 0x4B, 0xC9, 0x1A, 0x01, 0x60, 0x02, 0xE0,
|
||||
0x0F, 0x48, 0x01, 0x21, 0x01, 0x60, 0x1F, 0xBC, 0x0C, 0x48, 0x00, 0x88, 0x0F, 0x4A, 0x10, 0x47,
|
||||
0x00, 0x7F, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0x03, 0x30, 0x01, 0x00, 0x04, 0x4B, 0x13, 0x00, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x03, 0x98, 0x0F, 0x00, 0x03, 0x30, 0x01, 0x00, 0x04,
|
||||
0x30, 0x10, 0x00, 0x03, 0x20, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4B, 0x13, 0x00, 0x08
|
||||
};
|
||||
|
||||
static const u8 yoshiTopsyTurvyPatch[0x18C] = {
|
||||
0x0C, 0x20, 0x9F, 0xE5, 0x80, 0x30, 0xA0, 0xE3, 0x00, 0x30, 0xE2, 0xE4, 0x04, 0x30, 0x9F, 0xE5,
|
||||
0x13, 0xFF, 0x2F, 0xE1, 0xE0, 0x7F, 0x00, 0x03, 0x69, 0x51, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xB5, 0x01, 0x4F, 0x00, 0x00, 0x09, 0xE0, 0xE0, 0x7F, 0x00, 0x03, 0x02, 0x49, 0x09, 0x88,
|
||||
0x01, 0x23, 0x08, 0x40, 0x70, 0x47, 0x00, 0x00, 0x30, 0x01, 0x00, 0x04, 0x3D, 0x78, 0x7F, 0x1C,
|
||||
0x80, 0x26, 0x35, 0x42, 0x24, 0xD0, 0x33, 0x48, 0x00, 0x21, 0x00, 0x88, 0x88, 0x42, 0x04, 0xD1,
|
||||
0x31, 0x49, 0x20, 0x20, 0x00, 0x02, 0x02, 0x30, 0x08, 0x80, 0x30, 0x48, 0x03, 0x21, 0x00, 0x88,
|
||||
0x88, 0x42, 0x04, 0xD1, 0x2E, 0x49, 0x20, 0x20, 0x00, 0x02, 0x02, 0x30, 0x08, 0x80, 0x02, 0x20,
|
||||
0x00, 0x02, 0x00, 0x30, 0xFF, 0xF7, 0xDA, 0xFF, 0x02, 0xD1, 0x2A, 0x49, 0x00, 0x20, 0x08, 0x80,
|
||||
0x01, 0x20, 0xFF, 0x30, 0xFF, 0xF7, 0xD2, 0xFF, 0x02, 0xD1, 0x27, 0x49, 0x03, 0x20, 0x08, 0x80,
|
||||
0x76, 0x08, 0x35, 0x42, 0x02, 0xD0, 0x25, 0x49, 0x63, 0x20, 0x08, 0x70, 0x76, 0x08, 0x35, 0x42,
|
||||
0x04, 0xD0, 0x23, 0x49, 0x27, 0x20, 0x00, 0x02, 0x0F, 0x30, 0x08, 0x80, 0x76, 0x08, 0x35, 0x42,
|
||||
0x02, 0xD0, 0x20, 0x49, 0x03, 0x20, 0x08, 0x80, 0x76, 0x08, 0x35, 0x42, 0x22, 0xD0, 0x1E, 0x49,
|
||||
0xAA, 0x20, 0x00, 0x02, 0xAA, 0x30, 0x08, 0x80, 0x1C, 0x49, 0xAA, 0x20, 0x00, 0x02, 0xAA, 0x30,
|
||||
0x08, 0x80, 0x1B, 0x49, 0xAA, 0x20, 0x00, 0x02, 0xAA, 0x30, 0x08, 0x80, 0x19, 0x49, 0xAA, 0x20,
|
||||
0x00, 0x02, 0xAA, 0x30, 0x08, 0x80, 0x18, 0x49, 0xAA, 0x20, 0x00, 0x02, 0xAA, 0x30, 0x08, 0x80,
|
||||
0x16, 0x49, 0xAA, 0x20, 0x00, 0x02, 0xAA, 0x30, 0x08, 0x80, 0x15, 0x49, 0xAA, 0x20, 0x00, 0x02,
|
||||
0xAA, 0x30, 0x08, 0x80, 0x76, 0x08, 0x35, 0x42, 0x02, 0xD0, 0x12, 0x49, 0x0A, 0x20, 0x08, 0x80,
|
||||
0x00, 0x00, 0x21, 0xE0, 0xE0, 0x1D, 0x00, 0x03, 0xE0, 0x1D, 0x00, 0x03, 0xE0, 0x1D, 0x00, 0x03,
|
||||
0xE0, 0x1D, 0x00, 0x03, 0xE0, 0x1D, 0x00, 0x03, 0xE0, 0x1D, 0x00, 0x03, 0xD8, 0x03, 0x00, 0x03,
|
||||
0xF8, 0x03, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0xDA, 0x03, 0x00, 0x03, 0xDC, 0x03, 0x00, 0x03,
|
||||
0xDE, 0x03, 0x00, 0x03, 0xE0, 0x03, 0x00, 0x03, 0xE2, 0x03, 0x00, 0x03, 0xE4, 0x03, 0x00, 0x03,
|
||||
0xE6, 0x03, 0x00, 0x03, 0x48, 0x29, 0x00, 0x02, 0xFF, 0xBD, 0x00, 0x00, 0x00, 0xB5, 0x03, 0x48,
|
||||
0xFE, 0x46, 0x00, 0x47, 0x01, 0xBC, 0x86, 0x46, 0x01, 0xBC, 0x01, 0xE0, 0x01, 0x9C, 0x7B, 0x08,
|
||||
0x02, 0x48, 0x00, 0x88, 0xC0, 0x43, 0x80, 0x05, 0x81, 0x0D, 0x01, 0xE0, 0x30, 0x01, 0x00, 0x04,
|
||||
0x03, 0xB4, 0x01, 0x48, 0x01, 0x90, 0x01, 0xBD, 0x18, 0x1A, 0x00, 0x08
|
||||
};
|
||||
|
||||
void patchGeneralWhiteScreen(u32 romSize) {
|
||||
u32 entryPoint = *(u32*)0x08000000;
|
||||
entryPoint -= 0xEA000000;
|
||||
entryPoint += 2;
|
||||
prefetchPatch[7] = 0x08000000+(entryPoint*4);
|
||||
|
||||
u32 patchOffset = 0x01FFFFDC;
|
||||
|
||||
vu32 *patchAddr = (vu32*)(0x08000000+patchOffset);
|
||||
for(int i=0;i<8;i++)patchAddr[i] = prefetchPatch[i];
|
||||
|
||||
|
||||
u32 branchCode = 0xEA000000+(patchOffset/sizeof(u32))-2;
|
||||
*(vu32*)0x08000000 = branchCode;
|
||||
|
||||
u32 searchRange = 0x08000000+romSize;
|
||||
if (romSize > 0x01FFFFDC) searchRange = 0x09FFFFDC;
|
||||
|
||||
// General fix for white screen crash
|
||||
// Patch out wait states
|
||||
for (u32 addr = 0x080000C0; addr < searchRange; addr+=4) {
|
||||
if (*(u32*)addr == 0x04000204 &&
|
||||
(*(u8*)(addr-1) == 0x00 || *(u8*)(addr-1) == 0x03 || *(u8*)(addr-1) == 0x04 || *(u8*)(addr+7) == 0x04
|
||||
|| *(u8*)(addr-1) == 0x08 || *(u8*)(addr-1) == 0x09
|
||||
|| *(u8*)(addr-1) == 0x47 || *(u8*)(addr-1) == 0x81 || *(u8*)(addr-1) == 0x85
|
||||
|| *(u8*)(addr-1) == 0xE0 || *(u8*)(addr-1) == 0xE7 || *(u16*)(addr-2) == 0xFFFE))
|
||||
{
|
||||
*(vu32*)addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Also check at 0x410
|
||||
if (*(u32*)0x08000410 == 0x04000204)*(vu32*)0x08000410 = 0;
|
||||
}
|
||||
|
||||
bool patchSpecificGame() {
|
||||
u32 nop = 0xE1A00000;
|
||||
|
||||
u32 gameCode = *(u32*)(0x080000AC);
|
||||
|
||||
if (gameCode == 0x50584C42) {
|
||||
//Astreix & Obelix XXL (Europe)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x50118) == 0x4014)*(u16*)(0x08000000 + 0x50118) = 0x4000;
|
||||
} else if (gameCode == 0x454D4441) {
|
||||
//Doom (USA)
|
||||
//Fix black screen crash
|
||||
if (*(u16*)(0x08000000 + 0x51C) == 0x45B6)*(u16*)(0x08000000 + 0x51C) = 0x4002;
|
||||
} else if (gameCode == 0x45443941 || gameCode == 0x50443941) {
|
||||
//Doom II (USA/Europe)
|
||||
//Fix black screen crash
|
||||
if (*(u16*)(0x08000000 + 0x2856) == 0x5281)*(u16*)(0x08000000 + 0x2856) = 0x46C0;
|
||||
} else if (gameCode == 0x45474C41) {
|
||||
//Dragon Ball Z - The Legacy of Goku (USA)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x96E8) == 0x80A8) *(u16*)(0x08000000 + 0x96E8) = 0x46C0;
|
||||
|
||||
//Fix "game cannot be played on hardware found" error
|
||||
if (*(u16*)(0x08000000 + 0x356) == 0x7002)*(u16*)(0x08000000 + 0x356) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x35E) == 0x7043)*(u16*)(0x08000000 + 0x35E) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x37E) == 0x7001)*(u16*)(0x08000000 + 0x37E) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x382) == 0x7041)*(u16*)(0x08000000 + 0x382) = 0;
|
||||
|
||||
if (*(u16*)(0x08000000 + 0xE27E) == 0xB0A2) {
|
||||
*(u16*)(0x08000000 + 0xE27E) = 0x400;
|
||||
for (int i = 0; i < (int)sizeof(sDbzLoGUPatch1); i += 2)*(u16*)(0x08000000 + 0xE280 + i) = *(u16*)&sDbzLoGUPatch1[i];
|
||||
for (int i = 0; i < (int)sizeof(sDbzLoGUPatch2); i += 2)*(u16*)(0x08000000 + 0xE32C + i) = *(u16*)&sDbzLoGUPatch2[i];
|
||||
}
|
||||
} else if (gameCode == 0x50474C41) {
|
||||
//Dragon Ball Z - The Legacy of Goku (Europe)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x9948) == 0x80B0)*(u16*)(0x08000000 + 0x9948) = 0x46C0;
|
||||
|
||||
//Fix "game cannot be played on hardware found" error
|
||||
if (*(u16*)(0x08000000 + 0x33C) == 0x7119)*(u16*)(0x08000000 + 0x33C) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x340) == 0x7159)*(u16*)(0x08000000 + 0x340) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x356) == 0x705A)*(u16*)(0x08000000 + 0x356) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x35A) == 0x7002)*(u16*)(0x08000000 + 0x35A) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x35E) == 0x7042)*(u16*)(0x08000000 + 0x35E) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x384) == 0x7001)*(u16*)(0x08000000 + 0x384) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x388) == 0x7041)*(u16*)(0x08000000 + 0x388) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x494C) == 0x7002)*(u16*)(0x08000000 + 0x494C) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x4950) == 0x7042)*(u16*)(0x08000000 + 0x4950) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x4978) == 0x7001)*(u16*)(0x08000000 + 0x4978) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x497C) == 0x7041)*(u16*)(0x08000000 + 0x497C) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x988E) == 0x7028)*(u16*)(0x08000000 + 0x988E) = 0x46C0;
|
||||
if (*(u16*)(0x08000000 + 0x9992) == 0x7068)*(u16*)(0x08000000 + 0x9992) = 0x46C0;
|
||||
} else if (gameCode == 0x45464C41) {
|
||||
//Dragon Ball Z - The Legacy of Goku II (USA)
|
||||
*((u32*)0x080000E0) = nop;
|
||||
//tonccpy((u16*)0x080000E0, &nop, sizeof(u32)); // Fix white screen crash
|
||||
|
||||
//Fix "game will not run on the hardware found" error
|
||||
if (*(u16*)(0x08000000 + 0x3B8E9E) == 0x1102)*(u16*)(0x08000000 + 0x3B8E9E) = 0x1001;
|
||||
if (*(u16*)(0x08000000 + 0x3B8EAE) == 0x0003)*(u16*)(0x08000000 + 0x3B8EAE) = 0;
|
||||
} else if (gameCode == 0x4A464C41) {
|
||||
//Dragon Ball Z - The Legacy of Goku II International (Japan)
|
||||
*((u32*)0x080000E0) = nop;
|
||||
//tonccpy((u16*)0x080000E0, &nop, sizeof(u32)); // Fix white screen crash
|
||||
|
||||
//Fix "game will not run on the hardware found" error
|
||||
if (*(u16*)(0x08000000 + 0x3FC8F6) == 0x1102)*(u16*)(0x08000000 + 0x3FC8F6) = 0x1001;
|
||||
if (*(u16*)(0x08000000 + 0x3FC906) == 0x0003)*(u16*)(0x08000000 + 0x3FC906) = 0;
|
||||
} else if (gameCode == 0x50464C41) {
|
||||
//Dragon Ball Z - The Legacy of Goku II (Europe)
|
||||
*((u32*)0x080000E0) = nop;
|
||||
//tonccpy((u16*)0x080000E0, &nop, sizeof(u32)); // Fix white screen crash
|
||||
|
||||
//Fix "game will not run on the hardware found" error
|
||||
if (*(u16*)(0x08000000 + 0x6F42B2) == 0x1102)*(u16*)(0x08000000 + 0x6F42B2) = 0x1001;
|
||||
if (*(u16*)(0x08000000 + 0x6F42C2) == 0x0003)*(u16*)(0x08000000 + 0x6F42C2) = 0;
|
||||
} else if (gameCode == 0x45464C42) {
|
||||
//2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA)
|
||||
*((u32*)0x080000E0) = nop;
|
||||
//tonccpy((u16*)0x080000E0, &nop, sizeof(u32)); // Fix white screen crash
|
||||
|
||||
if (*(u16*)(0x08000000 + 0x49840) == 0x80A8)*(u16*)(0x08000000 + 0x49840) = 0x46C0;
|
||||
|
||||
// tonccpy((u16*)0x088000E0, &nop, sizeof(u32));
|
||||
*((u32*)0x080000E0) = nop;
|
||||
|
||||
//LoG1: Fix "game cannot be played on hardware found" error
|
||||
if (*(u16*)(0x08000000 + 0x40356) == 0x7002)*(u16*)(0x08000000 + 0x40356) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x4035E) == 0x7043)*(u16*)(0x08000000 + 0x4035E) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x4037E) == 0x7001)*(u16*)(0x08000000 + 0x4037E) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x40382) == 0x7041)*(u16*)(0x08000000 + 0x40382) = 0;
|
||||
|
||||
//Do we need this?
|
||||
/*if (*(u16*)(0x08000000 + 0x4E316) == 0xB0A2) {
|
||||
*(u16*)(0x08000000 + 0x4E316) = 0x400;
|
||||
for (int i = 0; i < sizeof(sDbzLoGUPatch1); i += 2)*(u16*)(0x08000000 + 0x4E318 + i) = *(u16*)&sDbzLoGUPatch1[i];
|
||||
for (int i = 0; i < sizeof(sDbzLoGUPatch2); i += 2)*(u16*)(0x08000000 + 0x????? + i) = *(u16*)&sDbzLoGUPatch2[i];
|
||||
}*/
|
||||
|
||||
//LoG2: Fix "game will not run on the hardware found" error
|
||||
if (*(u16*)(0x08000000 + 0xBB9016) == 0x1102)*(u16*)(0x08000000 + 0xBB9016) = 0x1001;
|
||||
if (*(u16*)(0x08000000 + 0xBB9026) == 0x0003)*(u16*)(0x08000000 + 0xBB9026) = 0;
|
||||
} else if (gameCode == 0x45424442) {
|
||||
//Dragon Ball Z - Taiketsu (USA)
|
||||
//Fix "game cannot be played on this hardware" error
|
||||
if (*(u16*)(0x08000000 + 0x2BD54) == 0x7818)*(u16*)(0x08000000 + 0x2BD54) = 0x2000;
|
||||
if (*(u16*)(0x08000000 + 0x2BD60) == 0x7810)*(u16*)(0x08000000 + 0x2BD60) = 0x2000;
|
||||
if (*(u16*)(0x08000000 + 0x2BD80) == 0x703A)*(u16*)(0x08000000 + 0x2BD80) = 0x1C00;
|
||||
if (*(u16*)(0x08000000 + 0x2BD82) == 0x7839)*(u16*)(0x08000000 + 0x2BD82) = 0x2100;
|
||||
if (*(u16*)(0x08000000 + 0x2BD8C) == 0x7030)*(u16*)(0x08000000 + 0x2BD8C) = 0x1C00;
|
||||
if (*(u16*)(0x08000000 + 0x2BD8E) == 0x7830)*(u16*)(0x08000000 + 0x2BD8E) = 0x2000;
|
||||
if (*(u16*)(0x08000000 + 0x2BDAC) == 0x7008)*(u16*)(0x08000000 + 0x2BDAC) = 0x1C00;
|
||||
if (*(u16*)(0x08000000 + 0x2BDB2) == 0x7008)*(u16*)(0x08000000 + 0x2BDB2) = 0x1C00;
|
||||
} else if (gameCode == 0x50424442) {
|
||||
//Dragon Ball Z - Taiketsu (Europe)
|
||||
//Fix "game cannot be played on this hardware" error
|
||||
if (*(u16*)(0x08000000 + 0x3FE08) == 0x7818)*(u16*)(0x08000000 + 0x3FE08) = 0x2000;
|
||||
if (*(u16*)(0x08000000 + 0x3FE14) == 0x7810)*(u16*)(0x08000000 + 0x3FE14) = 0x2000;
|
||||
if (*(u16*)(0x08000000 + 0x3FE34) == 0x703A)*(u16*)(0x08000000 + 0x3FE34) = 0x1C00;
|
||||
if (*(u16*)(0x08000000 + 0x3FE36) == 0x7839)*(u16*)(0x08000000 + 0x3FE36) = 0x2100;
|
||||
if (*(u16*)(0x08000000 + 0x3FE40) == 0x7030)*(u16*)(0x08000000 + 0x3FE40) = 0x1C00;
|
||||
if (*(u16*)(0x08000000 + 0x3FE42) == 0x7830)*(u16*)(0x08000000 + 0x3FE42) = 0x2000;
|
||||
if (*(u16*)(0x08000000 + 0x3FE58) == 0x7008)*(u16*)(0x08000000 + 0x3FE58) = 0x1C00;
|
||||
if (*(u16*)(0x08000000 + 0x3FE66) == 0x7008)*(u16*)(0x08000000 + 0x3FE66) = 0x1C00;
|
||||
} else if (gameCode == 0x45334742) {
|
||||
//Dragon Ball Z - Buu's Fury (USA)
|
||||
*((u32*)0x080000E0) = nop;
|
||||
//tonccpy((u16*)0x080000E0, &nop, sizeof(u32)); // Fix white screen crash
|
||||
|
||||
//Fix "game will not run on this hardware" error
|
||||
if (*(u16*)(0x08000000 + 0x8B66) == 0x7032)*(u16*)(0x08000000 + 0x8B66) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x8B6A) == 0x7072)*(u16*)(0x08000000 + 0x8B6A) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x8B86) == 0x7008)*(u16*)(0x08000000 + 0x8B86) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x8B8C) == 0x7031)*(u16*)(0x08000000 + 0x8B8C) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x8B90) == 0x7071)*(u16*)(0x08000000 + 0x8B90) = 0;
|
||||
} else if (gameCode == 0x45345442) {
|
||||
//Dragon Ball GT - Transformation (USA)
|
||||
*((u32*)0x080000E0) = nop;
|
||||
//tonccpy((u16*)0x080000E0, &nop, sizeof(u32)); // Fix white screen crash
|
||||
} else if (gameCode == 0x45465542) {
|
||||
//2 Games in 1 - Dragon Ball Z - Buu's Fury & Dragon Ball GT - Transformation (USA)
|
||||
*((u32*)0x080000E0) = nop;
|
||||
//tonccpy((u16*)0x080000E0, &nop, sizeof(u32)); // Fix white screen crash
|
||||
*((u32*)0x080300E0) = nop;
|
||||
*((u32*)0x088000E0) = nop;
|
||||
// tonccpy((u16*)0x080300E0, &nop, sizeof(u32));
|
||||
// tonccpy((u16*)0x088000E0, &nop, sizeof(u32));
|
||||
|
||||
//DBZ BF: Fix "game will not run on this hardware" error
|
||||
if (*(u16*)(0x08000000 + 0x38B66) == 0x7032)*(u16*)(0x08000000 + 0x38B66) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x38B6A) == 0x7072)*(u16*)(0x08000000 + 0x38B6A) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x38B86) == 0x7008)*(u16*)(0x08000000 + 0x38B86) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x38B8C) == 0x7031)*(u16*)(0x08000000 + 0x38B8C) = 0;
|
||||
if (*(u16*)(0x08000000 + 0x38B90) == 0x7071)*(u16*)(0x08000000 + 0x38B90) = 0;
|
||||
} else if (gameCode == 0x45564442) {
|
||||
//Dragon Ball - Advanced Adventure (USA)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x10C240) == 0x8008)*(u16*)(0x08000000 + 0x10C240) = 0x46C0;
|
||||
} else if (gameCode == 0x50564442) {
|
||||
//Dragon Ball - Advanced Adventure (Europe)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x10CE3C) == 0x8008)*(u16*)(0x08000000 + 0x10CE3C) = 0x46C0;
|
||||
} else if (gameCode == 0x4A564442) {
|
||||
//Dragon Ball - Advanced Adventure (Japan)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x10B078) == 0x8008)*(u16*)(0x08000000 + 0x10B078) = 0x46C0;
|
||||
} else if (gameCode == 0x454B3842) {
|
||||
//Kirby and the Amazing Mirror (USA)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x1515A4) == 0x8008)*(u16*)(0x08000000 + 0x1515A4) = 0x46C0;
|
||||
} else if (gameCode == 0x504B3842) {
|
||||
//Kirby and the Amazing Mirror (Europe)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x151EE0) == 0x8008)*(u16*)(0x08000000 + 0x151EE0) = 0x46C0;
|
||||
} else if (gameCode == 0x4A4B3842) {
|
||||
//Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (V1.1)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x151564) == 0x8008)*(u16*)(0x08000000 + 0x151564) = 0x46C0;
|
||||
} else if (gameCode == 0x45533342) {
|
||||
//Sonic Advance 3 (USA)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0xBB67C) == 0x8008)*(u16*)(0x08000000 + 0xBB67C) = 0x46C0;
|
||||
} else if (gameCode == 0x50533342) {
|
||||
//Sonic Advance 3 (Europe)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0xBBA04) == 0x8008)*(u16*)(0x08000000 + 0xBBA04) = 0x46C0;
|
||||
} else if (gameCode == 0x4A533342) {
|
||||
//Sonic Advance 3 (Japan)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0xBB9F8) == 0x8008)*(u16*)(0x08000000 + 0xBB9F8) = 0x46C0;
|
||||
} else if (gameCode == 0x45593241) {
|
||||
//Top Gun - Combat Zones (USA)
|
||||
//Fix softlock when attempting to save (original cartridge does not have a save chip)
|
||||
if (*(u16*)(0x08000000 + 0x88816) == 0x3501)*(u16*)(0x08000000 + 0x88816) = 0x3401;
|
||||
|
||||
// savingAllowed = false;
|
||||
return false;
|
||||
} else if (gameCode == 0x45415741 || gameCode == 0x4A415741) {
|
||||
//Wario Land 4/Advance (USA/Europe/Japan)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x726) == 0x8008)*(u16*)(0x08000000 + 0x726) = 0x46C0;
|
||||
} else if (gameCode == 0x43415741) {
|
||||
//Wario Land Advance (iQue)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0xE92) == 0x8008)*(u16*)(0x08000000 + 0xE92) = 0x46C0;
|
||||
} else if (gameCode == 0x45575A52) {
|
||||
//WarioWare: Twisted! (USA)
|
||||
//Patch out tilt controls
|
||||
if (*(u16*)(0x08000000 + 0x1348) == 0x8800)*(u16*)(0x08000000 + 0x1348) = 0x4700;
|
||||
|
||||
if (*(u16*)(0x08000000 + 0x1376) == 0x0400 && *(u16*)(0x08000000 + 0x1374) == 0x0130) {
|
||||
*(u16*)(0x08000000 + 0x1376) = 0x08E9;
|
||||
*(u16*)(0x08000000 + 0x1374) = 0x3C6D;
|
||||
|
||||
// tonccpy((u8*)0x08E93C6C, &wwTwistedPatch, 0xF0);
|
||||
twoByteCpy((u16*)0x08E93C6C,(const u16*)wwTwistedPatch,0xF0);
|
||||
}
|
||||
} else if (gameCode == 0x4547594B) {
|
||||
//Yoshi Topsy-Turvy (USA)
|
||||
//Fix white screen crash
|
||||
if (*(u16*)(0x08000000 + 0x16E4) == 0x8008)*(u16*)(0x08000000 + 0x16E4) = 0x46C0;
|
||||
|
||||
//Patch out tilt controls
|
||||
if (*(u16*)(0x08000000 + 0x1F2) == 0x0802 && *(u16*)(0x08000000 + 0x1F0) == 0x5169) {
|
||||
*(u16*)(0x08000000 + 0x1F2) = 0x087B;
|
||||
*(u16*)(0x08000000 + 0x1F0) = 0x9BE0;
|
||||
|
||||
// tonccpy((u8*)0x087B9BE0, &yoshiTopsyTurvyPatch, 0x18C);
|
||||
twoByteCpy((u16*)0x087B9BE0,(const u16*)yoshiTopsyTurvyPatch,0x18C);
|
||||
}
|
||||
|
||||
if (*(u16*)(0x08000000 + 0x1A0E) == 0x4808)*(u16*)(0x08000000 + 0x1A0E) = 0xB401;
|
||||
if (*(u16*)(0x08000000 + 0x1A10) == 0x8800)*(u16*)(0x08000000 + 0x1A10) = 0x4800;
|
||||
if (*(u16*)(0x08000000 + 0x1A12) == 0x43C0)*(u16*)(0x08000000 + 0x1A12) = 0x4700;
|
||||
if (*(u16*)(0x08000000 + 0x1A14) == 0x0580)*(u16*)(0x08000000 + 0x1A14) = 0x9D3D;
|
||||
if (*(u16*)(0x08000000 + 0x1A16) == 0x0D81)*(u16*)(0x08000000 + 0x1A16) = 0x087B;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
67
arm9/include/sc_patches.h
Normal file
67
arm9/include/sc_patches.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef SC_PATCHES_H
|
||||
#define SC_PATCHES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
void patchGeneralWhiteScreen(u32 romSize);
|
||||
bool patchSpecificGame();
|
||||
|
||||
enum SaveType {
|
||||
SAVE_TYPE_NONE = 0,
|
||||
|
||||
SAVE_TYPE_EEPROM = (1 << 14),
|
||||
SAVE_TYPE_EEPROM_V111,
|
||||
SAVE_TYPE_EEPROM_V120,
|
||||
SAVE_TYPE_EEPROM_V121,
|
||||
SAVE_TYPE_EEPROM_V122,
|
||||
SAVE_TYPE_EEPROM_V124,
|
||||
SAVE_TYPE_EEPROM_V125,
|
||||
SAVE_TYPE_EEPROM_V126,
|
||||
|
||||
SAVE_TYPE_FLASH = (2 << 14),
|
||||
SAVE_TYPE_FLASH512 = SAVE_TYPE_FLASH | (0 << 13),
|
||||
SAVE_TYPE_FLASH_V120,
|
||||
SAVE_TYPE_FLASH_V121,
|
||||
SAVE_TYPE_FLASH_V123,
|
||||
SAVE_TYPE_FLASH_V124,
|
||||
SAVE_TYPE_FLASH_V125,
|
||||
SAVE_TYPE_FLASH_V126,
|
||||
SAVE_TYPE_FLASH512_V130,
|
||||
SAVE_TYPE_FLASH512_V131,
|
||||
SAVE_TYPE_FLASH512_V133,
|
||||
|
||||
SAVE_TYPE_FLASH1M = SAVE_TYPE_FLASH | (1 << 13),
|
||||
SAVE_TYPE_FLASH1M_V102,
|
||||
SAVE_TYPE_FLASH1M_V103,
|
||||
|
||||
SAVE_TYPE_SRAM = (3 << 14),
|
||||
SAVE_TYPE_SRAM_F_V100,
|
||||
SAVE_TYPE_SRAM_F_V102,
|
||||
SAVE_TYPE_SRAM_F_V103,
|
||||
SAVE_TYPE_SRAM_V110,
|
||||
SAVE_TYPE_SRAM_V111,
|
||||
SAVE_TYPE_SRAM_V112,
|
||||
SAVE_TYPE_SRAM_V113,
|
||||
|
||||
SAVE_TYPE_TYPE_MASK = (3 << 14)
|
||||
};
|
||||
|
||||
struct save_type {
|
||||
char tag[16];
|
||||
u16 tagLength;
|
||||
u16 type;
|
||||
u32 size;
|
||||
bool (*patchFunc)(const struct save_type* type);
|
||||
};
|
||||
|
||||
const struct save_type* save_findTag();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
601
arm9/include/sc_sram.c
Normal file
601
arm9/include/sc_sram.c
Normal file
@ -0,0 +1,601 @@
|
||||
#include <nds.h>
|
||||
#include "find.h"
|
||||
#include "sc_patches.h"
|
||||
|
||||
#include "io_sc_common.h"
|
||||
|
||||
#define SAVE_TYPE_COUNT 25
|
||||
|
||||
u32 romSize;
|
||||
|
||||
// SRAM Patches
|
||||
|
||||
static const u8 flash1M_V102_find1[48] = {
|
||||
0xaa,0x21,0x19,0x70,0x05,0x4a,0x55,0x21,0x11,0x70,0xb0,0x21,0x19,0x70,0xe0,0x21,
|
||||
0x09,0x05,0x08,0x70,0x70,0x47,0x55,0x55,0x00,0x0e,0xaa,0x2a,0x00,0x0e,0x30,0xb5,
|
||||
0x91,0xb0,0x68,0x46,0x00,0xf0,0xf3,0xf8,0x6d,0x46,0x01,0x35,0x06,0x4a,0xaa,0x20
|
||||
};
|
||||
static const u8 flash1M_V102_replace1[136] = {
|
||||
0x80,0x21,0x09,0x02,0x09,0x22,0x12,0x06,0x9f,0x44,0x11,0x80,0x03,0x49,0xc3,0x02,
|
||||
0xc9,0x18,0x11,0x80,0x70,0x47,0xfe,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x30,0xb5,
|
||||
0x91,0xb0,0x68,0x46,0x00,0xf0,0xf3,0xf8,0x6d,0x46,0x01,0x35,0x06,0x4a,0xaa,0x20,
|
||||
0x00,0x00,0x05,0x49,0x55,0x20,0x00,0x00,0x90,0x20,0x00,0x00,0x10,0xa9,0x03,0x4a,
|
||||
0x10,0x1c,0x08,0xe0,0x00,0x00,0x55,0x55,0x00,0x0e,0xaa,0x2a,0x00,0x0e,0x20,0x4e,
|
||||
0x00,0x00,0x08,0x88,0x01,0x38,0x08,0x80,0x08,0x88,0x00,0x28,0xf9,0xd1,0x0c,0x48,
|
||||
0x13,0x20,0x13,0x20,0x00,0x06,0x04,0x0c,0xe0,0x20,0x00,0x05,0x62,0x20,0x62,0x20,
|
||||
0x00,0x06,0x00,0x0e,0x04,0x43,0x07,0x49,0xaa,0x20,0x00,0x00,0x07,0x4a,0x55,0x20,
|
||||
0x00,0x00,0xf0,0x20,0x00,0x00,0x00,0x00
|
||||
};
|
||||
static const u8 flash1M_V102_find2[24] = {
|
||||
0x14,0x49,0xaa,0x24,0x0c,0x70,0x13,0x4b,0x55,0x22,0x1a,0x70,0x80,0x20,0x08,0x70,
|
||||
0x0c,0x70,0x1a,0x70,0x10,0x20,0x08,0x70
|
||||
};
|
||||
static const u8 flash1M_V102_replace2[24] = {
|
||||
0x0e,0x21,0x09,0x06,0xff,0x24,0x80,0x22,0x13,0x4b,0x52,0x02,0x01,0x3a,0x8c,0x54,
|
||||
0xfc,0xd1,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
static const u8 flash1M_V102_find3[22] = {
|
||||
0xaa,0x25,0x0d,0x70,0x13,0x4b,0x55,0x22,0x1a,0x70,0x80,0x20,0x08,0x70,0x0d,0x70,
|
||||
0x1a,0x70,0x30,0x20,0x20,0x70
|
||||
};
|
||||
static const u8 flash1M_V102_replace3[22] = {
|
||||
0xff,0x25,0x08,0x22,0x00,0x00,0x52,0x02,0x01,0x3a,0xa5,0x54,0xfc,0xd1,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
static const u8 flash1M_V102_find4[12] = {
|
||||
0x22,0x70,0x09,0x4b,0x55,0x22,0x1a,0x70,0xa0,0x22,0x22,0x70
|
||||
};
|
||||
static const u8 flash1M_V102_replace4[12] = {
|
||||
0x00,0x00,0x09,0x4b,0x55,0x22,0x00,0x00,0xa0,0x22,0x00,0x00
|
||||
};
|
||||
|
||||
|
||||
static const u8 flash1M_V103_find1[98] = {
|
||||
0x05,0x4b,0xaa,0x21,0x19,0x70,0x05,0x4a,0x55,0x21,0x11,0x70,0xb0,0x21,0x19,0x70,
|
||||
0xe0,0x21,0x09,0x05,0x08,0x70,0x70,0x47,0x55,0x55,0x00,0x0e,0xaa,0x2a,0x00,0x0e,
|
||||
0x30,0xb5,0x91,0xb0,0x68,0x46,0x00,0xf0,0xf3,0xf8,0x6d,0x46,0x01,0x35,0x06,0x4a,
|
||||
0xaa,0x20,0x10,0x70,0x05,0x49,0x55,0x20,0x08,0x70,0x90,0x20,0x10,0x70,0x10,0xa9,
|
||||
0x03,0x4a,0x10,0x1c,0x08,0xe0,0x00,0x00,0x55,0x55,0x00,0x0e,0xaa,0x2a,0x00,0x0e,
|
||||
0x20,0x4e,0x00,0x00,0x08,0x88,0x01,0x38,0x08,0x80,0x08,0x88,0x00,0x28,0xf9,0xd1,
|
||||
0x0c,0x48
|
||||
};
|
||||
static const u8 flash1M_V103_replace1[138] = {
|
||||
0x05,0x4b,0x80,0x21,0x09,0x02,0x09,0x22,0x12,0x06,0x9f,0x44,0x11,0x80,0x03,0x49,
|
||||
0xc3,0x02,0xc9,0x18,0x11,0x80,0x70,0x47,0xfe,0xff,0xff,0x01,0x00,0x00,0x00,0x00,
|
||||
0x30,0xb5,0x91,0xb0,0x68,0x46,0x00,0xf0,0xf3,0xf8,0x6d,0x46,0x01,0x35,0x06,0x4a,
|
||||
0xaa,0x20,0x00,0x00,0x05,0x49,0x55,0x20,0x00,0x00,0x90,0x20,0x00,0x00,0x10,0xa9,
|
||||
0x03,0x4a,0x10,0x1c,0x08,0xe0,0x00,0x00,0x55,0x55,0x00,0x0e,0xaa,0x2a,0x00,0x0e,
|
||||
0x20,0x4e,0x00,0x00,0x08,0x88,0x01,0x38,0x08,0x80,0x08,0x88,0x00,0x28,0xf9,0xd1,
|
||||
0x0c,0x48,0x13,0x20,0x13,0x20,0x00,0x06,0x04,0x0c,0xe0,0x20,0x00,0x05,0x62,0x20,
|
||||
0x62,0x20,0x00,0x06,0x00,0x0e,0x04,0x43,0x07,0x49,0xaa,0x20,0x00,0x00,0x07,0x4a,
|
||||
0x55,0x20,0x00,0x00,0xf0,0x20,0x00,0x00,0x00,0x00
|
||||
};
|
||||
static const u8 flash1M_V103_find2[24] = {
|
||||
0x14,0x49,0xaa,0x24,0x0c,0x70,0x13,0x4b,0x55,0x22,0x1a,0x70,0x80,0x20,0x08,0x70,
|
||||
0x0c,0x70,0x1a,0x70,0x10,0x20,0x08,0x70
|
||||
};
|
||||
static const u8 flash1M_V103_replace2[24] = {
|
||||
0x0e,0x21,0x09,0x06,0xff,0x24,0x80,0x22,0x13,0x4b,0x52,0x02,0x01,0x3a,0x8c,0x54,
|
||||
0xfc,0xd1,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
static const u8 flash1M_V103_find3[22] = {
|
||||
0xaa,0x25,0x0d,0x70,0x14,0x4b,0x55,0x22,0x1a,0x70,0x80,0x20,0x08,0x70,0x0d,0x70,
|
||||
0x1a,0x70,0x30,0x20,0x20,0x70
|
||||
};
|
||||
static const u8 flash1M_V103_replace3[22] = {
|
||||
0xff,0x25,0x08,0x22,0x00,0x00,0x52,0x02,0x01,0x3a,0xa5,0x54,0xfc,0xd1,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
static const u8 flash1M_V103_find4[12] = {
|
||||
0x10,0x70,0x0b,0x49,0x55,0x20,0x08,0x70,0xa0,0x20,0x10,0x70
|
||||
};
|
||||
static const u8 flash1M_V103_replace4[12] = {
|
||||
0x00,0x00,0x0b,0x49,0x55,0x20,0x00,0x00,0xa0,0x20,0x00,0x00
|
||||
};
|
||||
static const u8 flash1M_V103_find5[12] = {
|
||||
0x22,0x70,0x09,0x4b,0x55,0x22,0x1a,0x70,0xa0,0x22,0x22,0x70
|
||||
};
|
||||
static const u8 flash1M_V103_replace5[12] = {
|
||||
0x00,0x00,0x09,0x4b,0x55,0x22,0x00,0x00,0xa0,0x22,0x00,0x00
|
||||
};
|
||||
|
||||
|
||||
// FLASH512_V130, V131, and V133 have all the same patches.
|
||||
// Patches are from gbatemp thread, but gbata doesn't actually support V133.
|
||||
static const u8 flash512_V13X_find1[38] = {
|
||||
0xf0,0xb5,0xa0,0xb0,0x0d,0x1c,0x16,0x1c,0x1f,0x1c,0x03,0x04,0x1c,0x0c,0x0f,0x4a,
|
||||
0x10,0x88,0x0f,0x49,0x08,0x40,0x03,0x21,0x08,0x43,0x10,0x80,0x0d,0x48,0x00,0x68,
|
||||
0x01,0x68,0x80,0x20,0x80,0x02
|
||||
};
|
||||
static const u8 flash512_V13X_replace1[38] = {
|
||||
0x70,0xb5,0xa0,0xb0,0x00,0x03,0x40,0x18,0xe0,0x21,0x09,0x05,0x09,0x18,0x08,0x78,
|
||||
0x10,0x70,0x01,0x3b,0x01,0x32,0x01,0x31,0x00,0x2b,0xf8,0xd1,0x00,0x20,0x20,0xb0,
|
||||
0x70,0xbc,0x02,0xbc,0x08,0x47
|
||||
};
|
||||
static const u8 flash512_V13X_find2[8] = {
|
||||
0xff,0xf7,0x88,0xfd,0x00,0x04,0x03,0x0c
|
||||
};
|
||||
static const u8 flash512_V13X_replace2[8] = {
|
||||
0x1b,0x23,0x1b,0x02,0x32,0x20,0x03,0x43
|
||||
};
|
||||
static const u8 flash512_V13X_find3[8] = {
|
||||
0x70,0xb5,0x90,0xb0,0x15,0x4d,0x29,0x88
|
||||
};
|
||||
static const u8 flash512_V13X_find4[8] = {
|
||||
0x70,0xb5,0x46,0x46,0x40,0xb4,0x90,0xb0
|
||||
};
|
||||
static const u8 flash512_V13X_replace3_4[8] = {
|
||||
0x00,0xb5,0x00,0x20,0x02,0xbc,0x08,0x47
|
||||
};
|
||||
static const u8 flash512_V13X_find5[24] = {
|
||||
0xf0,0xb5,0x90,0xb0,0x0f,0x1c,0x00,0x04,0x04,0x0c,0x03,0x48,0x00,0x68,0x40,0x89,
|
||||
0x84,0x42,0x05,0xd3,0x01,0x48,0x41,0xe0
|
||||
};
|
||||
static const u8 flash512_V13X_replace5[42] = {
|
||||
0x7c,0xb5,0x90,0xb0,0x00,0x03,0x0a,0x1c,0xe0,0x21,0x09,0x05,0x09,0x18,0x01,0x23,
|
||||
0x1b,0x03,0x10,0x78,0x08,0x70,0x01,0x3b,0x01,0x32,0x01,0x31,0x00,0x2b,0xf8,0xd1,
|
||||
0x00,0x20,0x10,0xb0,0x7c,0xbc,0x02,0xbc,0x08,0x47
|
||||
};
|
||||
|
||||
|
||||
// Encompasses FLASH_V120 and V121.
|
||||
static const u8 flash_V12X_find1[12] = {
|
||||
0x90,0xb5,0x93,0xb0,0x6f,0x46,0x39,0x1d,0x08,0x1c,0x00,0xf0
|
||||
};
|
||||
static const u8 flash_V12X_replace1[14] = {
|
||||
0x00,0xb5,0x3d,0x20,0x00,0x02,0x1f,0x21,0x08,0x43,0x02,0xbc,0x08,0x47
|
||||
};
|
||||
static const u8 flash_V12X_find2[35] = {
|
||||
0x80,0xb5,0x94,0xb0,0x6f,0x46,0x39,0x1c,0x08,0x80,0x38,0x1c,0x01,0x88,0x0f,0x29,
|
||||
0x04,0xd9,0x01,0x48,0x56,0xe0,0x00,0x00,0xff,0x80,0x00,0x00,0x23,0x48,0x23,0x49,
|
||||
0x0a,0x88,0x23
|
||||
};
|
||||
static const u8 flash_V12X_replace2[36] = {
|
||||
0x7c,0xb5,0x00,0x07,0x00,0x0c,0xe0,0x21,0x09,0x05,0x09,0x18,0x01,0x23,0x1b,0x03,
|
||||
0xff,0x20,0x08,0x70,0x01,0x3b,0x01,0x31,0x00,0x2b,0xfa,0xd1,0x00,0x20,0x7c,0xbc,
|
||||
0x02,0xbc,0x08,0x47
|
||||
};
|
||||
static const u8 flash_V12X_find3[42] = {
|
||||
0x80,0xb5,0x94,0xb0,0x6f,0x46,0x79,0x60,0x39,0x1c,0x08,0x80,0x38,0x1c,0x01,0x88,
|
||||
0x0f,0x29,0x03,0xd9,0x00,0x48,0x73,0xe0,0xff,0x80,0x00,0x00,0x38,0x1c,0x01,0x88,
|
||||
0x08,0x1c,0xff,0xf7,0x21,0xfe,0x39,0x1c,0x0c,0x31
|
||||
};
|
||||
static const u8 flash_V12X_replace3[42] = {
|
||||
0x7c,0xb5,0x90,0xb0,0x00,0x03,0x0a,0x1c,0xe0,0x21,0x09,0x05,0x09,0x18,0x01,0x23,
|
||||
0x1b,0x03,0x10,0x78,0x08,0x70,0x01,0x3b,0x01,0x32,0x01,0x31,0x00,0x2b,0xf8,0xd1,
|
||||
0x00,0x20,0x10,0xb0,0x7c,0xbc,0x08,0xbc,0x08,0x47
|
||||
};
|
||||
|
||||
// Encompasses FLASH_V123, V124, V125, and V126.
|
||||
// FIXME for FLASH_V125 and FLASH_V126: Medabots/Metarot and Super Monkey Ball Jr. (U) don't patch 1:1 with gbata.
|
||||
static const u8 flash_V12Y_find1[8] = {
|
||||
0xff,0xf7,0xaa,0xff,0x00,0x04,0x03,0x0c
|
||||
};
|
||||
static const u8 flash_V12Y_replace1[8] = {
|
||||
0x1b,0x23,0x1b,0x02,0x32,0x20,0x03,0x43
|
||||
};
|
||||
static const u8 flash_V12Y_find2[6] = {
|
||||
0x70,0xb5,0x90,0xb0,0x15,0x4d
|
||||
};
|
||||
static const u8 flash_V12Y_replace2[4] = {
|
||||
0x00,0x20,0x70,0x47/*,0x15,0x4d*/
|
||||
};
|
||||
// Patch 3 differs from GBATemp tutorial.
|
||||
// The added bytes at the end have significance.
|
||||
static const u8 flash_V12Y_find3[9] = {
|
||||
0x70,0xb5,0x46,0x46,0x40,0xb4,0x90,0xb0,0x00
|
||||
};
|
||||
static const u8 flash_V12Y_replace3[4] = {
|
||||
0x00,0x20,0x70,0x47/*,0x40,0xb4,0x90,0xb0,0x00*/
|
||||
};
|
||||
static const u8 flash_V12Y_find4[38] = {
|
||||
0xf0,0xb5,0x90,0xb0,0x0f,0x1c,0x00,0x04,0x04,0x0c,0x0f,0x2c,0x04,0xd9,0x01,0x48,
|
||||
0x40,0xe0,0x00,0x00,0xff,0x80,0x00,0x00,0x20,0x1c,0xff,0xf7,0xd7,0xfe,0x00,0x04,
|
||||
0x05,0x0c,0x00,0x2d,0x35,0xd1
|
||||
};
|
||||
static const u8 flash_V12Y_replace4[38] = {
|
||||
0x70,0xb5,0x00,0x03,0x0a,0x1c,0xe0,0x21,0x09,0x05,0x41,0x18,0x01,0x23,0x1b,0x03,
|
||||
0x10,0x78,0x08,0x70,0x01,0x3b,0x01,0x32,0x01,0x31,0x00,0x2b,0xf8,0xd1,0x00,0x20,
|
||||
0x70,0xbc,0x02,0xbc,0x08,0x47
|
||||
};
|
||||
|
||||
|
||||
bool flash_patchV120(const struct save_type* type) {
|
||||
u8* func1 = memsearch8((u8*)0x08000000, romSize, flash_V12X_find1, sizeof(flash_V12X_find1), true);
|
||||
if (!func1)
|
||||
return false;
|
||||
twoByteCpy((u16*)func1, (const u16*)flash_V12X_replace1, sizeof(flash_V12X_replace1));
|
||||
|
||||
u8* func2 = memsearch8((u8*)0x08000000, romSize, flash_V12X_find2, sizeof(flash_V12X_find2), true);
|
||||
if (!func2)
|
||||
return false;
|
||||
twoByteCpy((u16*)func2, (const u16*)flash_V12X_replace2, sizeof(flash_V12X_replace2));
|
||||
|
||||
u8* func3 = memsearch8((u8*)0x08000000, romSize, flash_V12X_find3, sizeof(flash_V12X_find3), true);
|
||||
if (!func3)
|
||||
return false;
|
||||
twoByteCpy((u16*)func3, (const u16*)flash_V12X_replace3, sizeof(flash_V12X_replace3));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool flash_patchV123(const struct save_type* type) {
|
||||
u8* func1 = memsearch8((u8*)0x08000000, romSize, flash_V12Y_find1, sizeof(flash_V12Y_find1), true);
|
||||
if (!func1)
|
||||
return false;
|
||||
twoByteCpy((u16*)func1, (const u16*)flash_V12Y_replace1, sizeof(flash_V12Y_replace1));
|
||||
|
||||
u8* func2 = memsearch8((u8*)0x08000000, romSize, flash_V12Y_find2, sizeof(flash_V12Y_find2), true);
|
||||
if (!func2)
|
||||
return false;
|
||||
twoByteCpy((u16*)func2, (const u16*)flash_V12Y_replace2, sizeof(flash_V12Y_replace2));
|
||||
|
||||
u8* func3 = memsearch8((u8*)0x08000000, romSize, flash_V12Y_find3, sizeof(flash_V12Y_find3), true);
|
||||
if (!func3)
|
||||
return false;
|
||||
twoByteCpy((u16*)func3, (const u16*)flash_V12Y_replace3, sizeof(flash_V12Y_replace3));
|
||||
|
||||
u8* func4 = memsearch8((u8*)0x08000000, romSize, flash_V12Y_find4, sizeof(flash_V12Y_find4), true);
|
||||
if (!func4)
|
||||
return false;
|
||||
twoByteCpy((u16*)func4, (const u16*)flash_V12Y_replace4, sizeof(flash_V12Y_replace4));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*bool flash_patchV126(const struct save_type* type)
|
||||
{
|
||||
}*/
|
||||
|
||||
bool flash_patch512V130(const struct save_type* type) {
|
||||
u32* romPos = (u32*)0x08000000;
|
||||
u32 curRomSize = romSize;
|
||||
u32 startSig[4] = {0};
|
||||
startSig[0] = *(u32*)0x08000000;
|
||||
startSig[1] = *(u32*)0x08000004;
|
||||
startSig[2] = *(u32*)0x08000008;
|
||||
startSig[3] = *(u32*)0x0800000C;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
if (i != 0) {
|
||||
while (romPos < romPos+romSize) {
|
||||
// Look for another ROM in 2 in 1 game packs
|
||||
romPos += 0x100000;
|
||||
curRomSize -= 0x100000;
|
||||
if (curRomSize <= 0) break;
|
||||
if (romPos[0] == startSig[0]
|
||||
&& romPos[1] == startSig[1]
|
||||
&& romPos[2] == startSig[2]
|
||||
&& romPos[3] == startSig[3]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (romPos >= romPos+romSize) break;
|
||||
}
|
||||
|
||||
u8* func1 = memsearch8((u8*)romPos, curRomSize, flash512_V13X_find1, sizeof(flash512_V13X_find1), true);
|
||||
if (!func1)
|
||||
return false;
|
||||
twoByteCpy((u16*)func1, (const u16*)flash512_V13X_replace1, sizeof(flash512_V13X_replace1));
|
||||
|
||||
u8* func2 = memsearch8((u8*)romPos, curRomSize, flash512_V13X_find2, sizeof(flash512_V13X_find2), true);
|
||||
if (!func2)
|
||||
return false;
|
||||
twoByteCpy((u16*)func2, (const u16*)flash512_V13X_replace2, sizeof(flash512_V13X_replace2));
|
||||
|
||||
u8* func3 = memsearch8((u8*)romPos, curRomSize, flash512_V13X_find3, sizeof(flash512_V13X_find3), true);
|
||||
if (!func3)
|
||||
return false;
|
||||
twoByteCpy((u16*)func3, (const u16*)flash512_V13X_replace3_4, sizeof(flash512_V13X_replace3_4));
|
||||
|
||||
u8* func4 = memsearch8((u8*)romPos, curRomSize, flash512_V13X_find4, sizeof(flash512_V13X_find4), true);
|
||||
if (!func4)
|
||||
return false;
|
||||
twoByteCpy((u16*)func4, (const u16*)flash512_V13X_replace3_4, sizeof(flash512_V13X_replace3_4));
|
||||
|
||||
u8* func5 = memsearch8((u8*)romPos, curRomSize, flash512_V13X_find5, sizeof(flash512_V13X_find5), true);
|
||||
if (!func5)
|
||||
return false;
|
||||
twoByteCpy((u16*)func5, (const u16*)flash512_V13X_replace5, sizeof(flash512_V13X_replace5));
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool flash_patch1MV102(const struct save_type* type) {
|
||||
u8* func1 = memsearch8((u8*)0x08000000, romSize, flash1M_V102_find1, sizeof(flash1M_V102_find1), true);
|
||||
if (!func1)
|
||||
return false;
|
||||
twoByteCpy((u16*)func1, (const u16*)flash1M_V102_replace1, sizeof(flash1M_V102_replace1));
|
||||
|
||||
u8* func2 = memsearch8((u8*)0x08000000, romSize, flash1M_V102_find2, sizeof(flash1M_V102_find2), true);
|
||||
if (!func2)
|
||||
return false;
|
||||
twoByteCpy((u16*)func2, (const u16*)flash1M_V102_replace2, sizeof(flash1M_V102_replace2));
|
||||
|
||||
u8* func3 = memsearch8((u8*)0x08000000, romSize, flash1M_V102_find3, sizeof(flash1M_V102_find3), true);
|
||||
if (!func3)
|
||||
return false;
|
||||
twoByteCpy((u16*)func3, (const u16*)flash1M_V102_replace3, sizeof(flash1M_V102_replace3));
|
||||
|
||||
u8* func4 = memsearch8((u8*)0x08000000, romSize, flash1M_V102_find4, sizeof(flash1M_V102_find4), true);
|
||||
if (!func4)
|
||||
return false;
|
||||
twoByteCpy((u16*)func4, (const u16*)flash1M_V102_replace4, sizeof(flash1M_V102_replace4));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool flash_patch1MV103(const struct save_type* type) {
|
||||
u8* func1 = memsearch8((u8*)0x08000000, romSize, flash1M_V103_find1, sizeof(flash1M_V103_find1), true);
|
||||
if (!func1)
|
||||
return false;
|
||||
twoByteCpy((u16*)func1, (const u16*)flash1M_V103_replace1, sizeof(flash1M_V103_replace1));
|
||||
|
||||
u8* func2 = memsearch8((u8*)0x08000000, romSize, flash1M_V103_find2, sizeof(flash1M_V103_find2), true);
|
||||
if (!func2)
|
||||
return false;
|
||||
twoByteCpy((u16*)func2, (const u16*)flash1M_V103_replace2, sizeof(flash1M_V103_replace2));
|
||||
|
||||
u8* func3 = memsearch8((u8*)0x08000000, romSize, flash1M_V103_find3, sizeof(flash1M_V103_find3), true);
|
||||
if (!func3)
|
||||
return false;
|
||||
twoByteCpy((u16*)func3, (const u16*)flash1M_V103_replace3, sizeof(flash1M_V103_replace3));
|
||||
|
||||
u8* func4 = memsearch8((u8*)0x08000000, romSize, flash1M_V103_find4, sizeof(flash1M_V103_find4), true);
|
||||
if (!func4)
|
||||
return false;
|
||||
twoByteCpy((u16*)func4, (const u16*)flash1M_V103_replace4, sizeof(flash1M_V103_replace4));
|
||||
|
||||
u8* func5 = memsearch8((u8*)0x08000000, romSize, flash1M_V103_find5, sizeof(flash1M_V103_find5), true);
|
||||
if (!func5)
|
||||
return false;
|
||||
twoByteCpy((u16*)func5, (const u16*)flash1M_V103_replace5, sizeof(flash1M_V103_replace5));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//todo: Moero!! Jaleco Collection (Japan) reports EEPROM_V124, but the signatures below don't work!
|
||||
|
||||
static const u8 sReadEepromDwordV111Sig[0x10] = { 0xB0, 0xB5, 0xAA, 0xB0, 0x6F, 0x46, 0x79, 0x60, 0x39, 0x1C, 0x08, 0x80, 0x38, 0x1C, 0x01, 0x88 };
|
||||
|
||||
static const u8 sReadEepromDwordV120Sig[0x10] = { 0x70, 0xB5, 0xA2, 0xB0, 0x0D, 0x1C, 0x00, 0x04, 0x03, 0x0C, 0x03, 0x48, 0x00, 0x68, 0x80, 0x88 };
|
||||
|
||||
static const u8 sProgramEepromDwordV111Sig[0x10] = { 0x80, 0xB5, 0xAA, 0xB0, 0x6F, 0x46, 0x79, 0x60, 0x39, 0x1C, 0x08, 0x80, 0x38, 0x1C, 0x01, 0x88 };
|
||||
|
||||
//changed in EEPROM_V124
|
||||
static const u8 sProgramEepromDwordV120Sig[0x10] = { 0x30, 0xB5, 0xA9, 0xB0, 0x0D, 0x1C, 0x00, 0x04, 0x04, 0x0C, 0x03, 0x48, 0x00, 0x68, 0x80, 0x88 };
|
||||
|
||||
//changed in EEPROM_V126
|
||||
static const u8 sProgramEepromDwordV124Sig[0x10] = { 0xF0, 0xB5, 0xAC, 0xB0, 0x0D, 0x1C, 0x00, 0x04, 0x01, 0x0C, 0x12, 0x06, 0x17, 0x0E, 0x03, 0x48 };
|
||||
|
||||
static const u8 sProgramEepromDwordV126Sig[0x10] = { 0xF0, 0xB5, 0x47, 0x46, 0x80, 0xB4, 0xAC, 0xB0, 0x0E, 0x1C, 0x00, 0x04, 0x05, 0x0C, 0x12, 0x06 };
|
||||
|
||||
//not in EEPROM_V111
|
||||
//could be used to identify the eeprom size, but not strictly needed
|
||||
/*static u16 identifyEeprom(u16 kbitSize)
|
||||
{
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
const u8 patch_eeprom_1[] = {
|
||||
0x00,0x04, // LSL R0, R0, #0x10
|
||||
0x0a,0x1c, // ADD R2, R1, #0
|
||||
0x40,0x0b, // LSR R0, R0, #0xD
|
||||
0xe0,0x21,0x09,0x05, // MOVL R1, 0xE000000
|
||||
0x41,0x18, // ADD R1, R0, R1
|
||||
0x07,0x31, // ADD R1, #7
|
||||
0x00,0x23, // MOV R3, #0
|
||||
//l1:
|
||||
0x08,0x78, // LDRB R0, [R1]
|
||||
0x10,0x70, // STRB R0, [R2]
|
||||
0x01,0x33, // ADD R3, #1
|
||||
0x01,0x32, // ADD R2, #1
|
||||
0x01,0x39, // SUB R1, #1
|
||||
0x07,0x2b, // CMP R3, #7
|
||||
0xf8,0xd9, // BLS l1
|
||||
0x00,0x20, // MOV R0, #0
|
||||
0x70,0x47 // BX LR
|
||||
};
|
||||
|
||||
const u8 patch_eeprom_2[] = {
|
||||
0x00,0x04, // LSL R0, R0, #0x10
|
||||
0x0a,0x1c, // ADD R2, R1, #0
|
||||
0x40,0x0b, // LSR R0, R0, #0xD
|
||||
0xe0,0x21,0x09,0x05, // MOVL R1, 0xE000000
|
||||
0x41,0x18, // ADD R1, R0, R1
|
||||
0x07,0x31, // ADD R1, #7
|
||||
0x00,0x23, // MOV R3, #0
|
||||
//l1:
|
||||
0x10,0x78, // LDRB R0, [R2]
|
||||
0x08,0x70, // STRB R0, [R1]
|
||||
0x01,0x33, // ADD R3, #1
|
||||
0x01,0x32, // ADD R2, #1
|
||||
0x01,0x39, // SUB R1, #1
|
||||
0x07,0x2b, // CMP R3, #7
|
||||
0xf8,0xd9, // BLS l1
|
||||
0x00,0x20, // MOV R0, #0
|
||||
0x70,0x47 // BX LR
|
||||
};
|
||||
|
||||
bool eeprom_patchV111(const struct save_type* type) {
|
||||
u8* readFunc = memsearch8((u8*)0x08000000, romSize, sReadEepromDwordV111Sig, 0x10, true);
|
||||
if (!readFunc)
|
||||
return false;
|
||||
twoByteCpy((u16*)readFunc, (const u16*)patch_eeprom_1, sizeof(patch_eeprom_1));
|
||||
|
||||
u8* progFunc = memsearch8((u8*)0x08000000, romSize, sProgramEepromDwordV111Sig, 0x10, true);
|
||||
if (!progFunc)
|
||||
return false;
|
||||
twoByteCpy((u16*)progFunc, (const u16*)patch_eeprom_2, sizeof(patch_eeprom_2));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eeprom_patchV120(const struct save_type* type) {
|
||||
u32* romPos = (u32*)0x08000000;
|
||||
u32 curRomSize = romSize;
|
||||
u32 startSig[4] = {0};
|
||||
startSig[0] = *(u32*)0x08000000;
|
||||
startSig[1] = *(u32*)0x08000004;
|
||||
startSig[2] = *(u32*)0x08000008;
|
||||
startSig[3] = *(u32*)0x0800000C;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
||||
if (i != 0) {
|
||||
while (romPos < romPos+romSize) {
|
||||
// Look for another ROM in 2-3 in 1 game packs
|
||||
romPos += 0x100000;
|
||||
curRomSize -= 0x100000;
|
||||
if (curRomSize <= 0) break;
|
||||
if (romPos[0] == startSig[0]
|
||||
&& romPos[1] == startSig[1]
|
||||
&& romPos[2] == startSig[2]
|
||||
&& romPos[3] == startSig[3]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (romPos >= romPos+romSize) break;
|
||||
}
|
||||
|
||||
u8* readFunc = memsearch8((u8*)romPos, curRomSize, sReadEepromDwordV120Sig, 0x10, true);
|
||||
if (!readFunc)
|
||||
return false;
|
||||
twoByteCpy((u16*)readFunc, (const u16*)patch_eeprom_1, sizeof(patch_eeprom_1));
|
||||
|
||||
u8* progFunc = memsearch8((u8*)romPos, curRomSize, sProgramEepromDwordV120Sig, 0x10, true);
|
||||
if (!progFunc)
|
||||
return false;
|
||||
twoByteCpy((u16*)progFunc, (const u16*)patch_eeprom_2, sizeof(patch_eeprom_2));
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eeprom_patchV124(const struct save_type* type) {
|
||||
u32* romPos = (u32*)0x08000000;
|
||||
u32 curRomSize = romSize;
|
||||
u32 startSig[4] = {0};
|
||||
startSig[0] = *(u32*)0x08000000;
|
||||
startSig[1] = *(u32*)0x08000004;
|
||||
startSig[2] = *(u32*)0x08000008;
|
||||
startSig[3] = *(u32*)0x0800000C;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
if (i != 0) {
|
||||
while (romPos < romPos+romSize) {
|
||||
// Look for another ROM in 2 in 1 game packs
|
||||
romPos += 0x100000;
|
||||
curRomSize -= 0x100000;
|
||||
if (curRomSize <= 0) break;
|
||||
if (romPos[0] == startSig[0]
|
||||
&& romPos[1] == startSig[1]
|
||||
&& romPos[2] == startSig[2]
|
||||
&& romPos[3] == startSig[3]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (romPos >= romPos+romSize) break;
|
||||
}
|
||||
|
||||
u8* readFunc = memsearch8((u8*)romPos, curRomSize, sReadEepromDwordV120Sig, 0x10, true);
|
||||
if (!readFunc)
|
||||
return false;
|
||||
twoByteCpy((u16*)readFunc, (const u16*)patch_eeprom_1, sizeof(patch_eeprom_1));
|
||||
|
||||
u8* progFunc = memsearch8((u8*)romPos, curRomSize, sProgramEepromDwordV124Sig, 0x10, true);
|
||||
if (!progFunc)
|
||||
return false;
|
||||
twoByteCpy((u16*)progFunc, (const u16*)patch_eeprom_2, sizeof(patch_eeprom_2));
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eeprom_patchV126(const struct save_type* type) {
|
||||
u8* readFunc = memsearch8((u8*)0x08000000, romSize, sReadEepromDwordV120Sig, 0x10, true);
|
||||
if (!readFunc)
|
||||
return false;
|
||||
twoByteCpy((u16*)readFunc, (const u16*)patch_eeprom_1, sizeof(patch_eeprom_1));
|
||||
|
||||
u8* progFunc = memsearch8((u8*)0x08000000, romSize, sProgramEepromDwordV126Sig, 0x10, true);
|
||||
if (!progFunc)
|
||||
return false;
|
||||
twoByteCpy((u16*)progFunc, (const u16*)patch_eeprom_2, sizeof(patch_eeprom_2));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static const struct save_type sSaveTypes[SAVE_TYPE_COUNT] = {
|
||||
{"EEPROM_V111", 12, SAVE_TYPE_EEPROM_V111, 512, eeprom_patchV111},
|
||||
{"EEPROM_V120", 12, SAVE_TYPE_EEPROM_V120, 8 * 1024, eeprom_patchV120},
|
||||
{"EEPROM_V121", 12, SAVE_TYPE_EEPROM_V121, 8 * 1024, eeprom_patchV120},
|
||||
{"EEPROM_V122", 12, SAVE_TYPE_EEPROM_V122, 8 * 1024, eeprom_patchV120},
|
||||
{"EEPROM_V124", 12, SAVE_TYPE_EEPROM_V124, 8 * 1024, eeprom_patchV124},
|
||||
{"EEPROM_V125", 12, SAVE_TYPE_EEPROM_V125, 8 * 1024, eeprom_patchV124},
|
||||
{"EEPROM_V126", 12, SAVE_TYPE_EEPROM_V126, 8 * 1024, eeprom_patchV126},
|
||||
|
||||
{"FLASH_V120", 11, SAVE_TYPE_FLASH_V120, 64 * 1024, flash_patchV120},
|
||||
{"FLASH_V121", 11, SAVE_TYPE_FLASH_V121, 64 * 1024, flash_patchV120},
|
||||
{"FLASH_V123", 11, SAVE_TYPE_FLASH_V123, 64 * 1024, flash_patchV123},
|
||||
{"FLASH_V124", 11, SAVE_TYPE_FLASH_V124, 64 * 1024, flash_patchV123},
|
||||
{"FLASH_V125", 11, SAVE_TYPE_FLASH_V125, 64 * 1024, flash_patchV123},
|
||||
{"FLASH_V126", 11, SAVE_TYPE_FLASH_V126, 64 * 1024, /*flash_patchV126*/ flash_patchV123},
|
||||
{"FLASH512_V130", 14, SAVE_TYPE_FLASH512_V130, 64 * 1024, flash_patch512V130},
|
||||
{"FLASH512_V131", 14, SAVE_TYPE_FLASH512_V131, 64 * 1024, flash_patch512V130},
|
||||
{"FLASH512_V133", 14, SAVE_TYPE_FLASH512_V133, 64 * 1024, flash_patch512V130},
|
||||
{"FLASH1M_V102", 13, SAVE_TYPE_FLASH1M_V102, 128 * 1024, flash_patch1MV102},
|
||||
{"FLASH1M_V103", 13, SAVE_TYPE_FLASH1M_V103, 128 * 1024, flash_patch1MV103},
|
||||
|
||||
//sram does not require patching
|
||||
{"SRAM_F_V100", 12, SAVE_TYPE_SRAM_F_V100, 32 * 1024, NULL},
|
||||
{"SRAM_F_V102", 12, SAVE_TYPE_SRAM_F_V102, 32 * 1024, NULL},
|
||||
{"SRAM_F_V103", 12, SAVE_TYPE_SRAM_F_V103, 32 * 1024, NULL},
|
||||
|
||||
{"SRAM_V110", 10, SAVE_TYPE_SRAM_V110, 32 * 1024, NULL},
|
||||
{"SRAM_V111", 10, SAVE_TYPE_SRAM_V111, 32 * 1024, NULL},
|
||||
{"SRAM_V112", 10, SAVE_TYPE_SRAM_V112, 32 * 1024, NULL},
|
||||
{"SRAM_V113", 10, SAVE_TYPE_SRAM_V113, 32 * 1024, NULL},
|
||||
};
|
||||
|
||||
const struct save_type* save_findTag() {
|
||||
u32 curAddr = 0x080000C0;
|
||||
char saveTag[16];
|
||||
while (curAddr < 0x08000000+romSize) {
|
||||
u32 fst = *(u32*)curAddr;
|
||||
// tonccpy(&saveTag, (u8*)curAddr, 16);
|
||||
((u32*)saveTag)[0] = ((u32*)curAddr)[0];
|
||||
((u32*)saveTag)[1] = ((u32*)curAddr)[1];
|
||||
((u32*)saveTag)[2] = ((u32*)curAddr)[2];
|
||||
((u32*)saveTag)[3] = ((u32*)curAddr)[3];
|
||||
enum SaveType type = SAVE_TYPE_NONE;
|
||||
if (fst == 0x53414C46 && (saveTag[5] == '_' || saveTag[5] == '5' || saveTag[5] == '1')) {
|
||||
//FLAS
|
||||
type = SAVE_TYPE_FLASH;
|
||||
} else if (fst == 0x4D415253) {
|
||||
//SRAM
|
||||
type = SAVE_TYPE_SRAM;
|
||||
} else if (fst == 0x52504545 && saveTag[6] == '_') {
|
||||
//EEPR
|
||||
type = SAVE_TYPE_EEPROM;
|
||||
}
|
||||
|
||||
if (type != SAVE_TYPE_NONE) {
|
||||
for (int i = 0; i < SAVE_TYPE_COUNT; i++) {
|
||||
if (strncmp(saveTag, sSaveTypes[i].tag, sSaveTypes[i].tagLength) != 0)continue;
|
||||
return &sSaveTypes[i];
|
||||
}
|
||||
}
|
||||
curAddr += 4;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
31
arm9/include/sc_sram.h
Normal file
31
arm9/include/sc_sram.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef SC_SRAM_H
|
||||
#define SC_SRAM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
extern u32 romSize;
|
||||
|
||||
bool flash_patchV120(const struct save_type* type);
|
||||
bool flash_patchV123(const struct save_type* type);
|
||||
bool flash_patchV126(const struct save_type* type);
|
||||
bool flash_patch512V130(const struct save_type* type);
|
||||
bool flash_patch1MV102(const struct save_type* type);
|
||||
bool flash_patch1MV103(const struct save_type* type);
|
||||
|
||||
bool eeprom_patchV111(const struct save_type* type);
|
||||
bool eeprom_patchV120(const struct save_type* type);
|
||||
bool eeprom_patchV124(const struct save_type* type);
|
||||
bool eeprom_patchV126(const struct save_type* type);
|
||||
|
||||
const struct save_type* save_findTag();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
136
arm9/include/tonccpy.c
Normal file
136
arm9/include/tonccpy.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include "tonccpy.h"
|
||||
//# tonccpy.c
|
||||
|
||||
//! VRAM-safe cpy.
|
||||
/*! This version mimics memcpy in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memcpy, but faster
|
||||
implementations can be made.
|
||||
\param dst Destination pointer.
|
||||
\param src Source pointer.
|
||||
\param size Fill-length in bytes.
|
||||
\note The pointers and size need not be word-aligned.
|
||||
*/
|
||||
void tonccpy(void *dst, const void *src, uint size)
|
||||
{
|
||||
if(size==0 || dst==0 || src==0)
|
||||
return;
|
||||
|
||||
uint count;
|
||||
u16 *dst16; // hword destination
|
||||
u8 *src8; // byte source
|
||||
|
||||
// Ideal case: copy by 4x words. Leaves tail for later.
|
||||
if( ((u32)src|(u32)dst)%4==0 && size>=4)
|
||||
{
|
||||
u32 *src32= (u32*)src, *dst32= (u32*)dst;
|
||||
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
// Duff's Device, good friend!
|
||||
switch(tmp) {
|
||||
do { *dst32++ = *src32++;
|
||||
case 3: *dst32++ = *src32++;
|
||||
case 2: *dst32++ = *src32++;
|
||||
case 1: *dst32++ = *src32++;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Check for tail
|
||||
size &= 3;
|
||||
if(size == 0)
|
||||
return;
|
||||
|
||||
src8= (u8*)src32;
|
||||
dst16= (u16*)dst32;
|
||||
}
|
||||
else // Unaligned.
|
||||
{
|
||||
uint dstOfs= (u32)dst&1;
|
||||
src8= (u8*)src;
|
||||
dst16= (u16*)(dst-dstOfs);
|
||||
|
||||
// Head: 1 byte.
|
||||
if(dstOfs != 0)
|
||||
{
|
||||
*dst16= (*dst16 & 0xFF) | *src8++<<8;
|
||||
dst16++;
|
||||
if(--size==0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unaligned main: copy by 2x byte.
|
||||
count= size/2;
|
||||
while(count--)
|
||||
{
|
||||
*dst16++ = src8[0] | src8[1]<<8;
|
||||
src8 += 2;
|
||||
}
|
||||
|
||||
// Tail: 1 byte.
|
||||
if(size&1)
|
||||
*dst16= (*dst16 &~ 0xFF) | *src8;
|
||||
}
|
||||
//# toncset.c
|
||||
|
||||
//! VRAM-safe memset, internal routine.
|
||||
/*! This version mimics memset in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memset.
|
||||
\param dst Destination pointer.
|
||||
\param fill Word to fill with.
|
||||
\param size Fill-length in bytes.
|
||||
\note The \a dst pointer and \a size need not be
|
||||
word-aligned. In the case of unaligned fills, \a fill
|
||||
will be masked off to match the situation.
|
||||
*/
|
||||
void __toncset(void *dst, u32 fill, uint size)
|
||||
{
|
||||
if(size==0 || dst==0)
|
||||
return;
|
||||
|
||||
uint left= (u32)dst&3;
|
||||
u32 *dst32= (u32*)(dst-left);
|
||||
u32 count, mask;
|
||||
|
||||
// Unaligned head.
|
||||
if(left != 0)
|
||||
{
|
||||
// Adjust for very small stint.
|
||||
if(left+size<4)
|
||||
{
|
||||
mask= BIT_MASK(size*8)<<(left*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
return;
|
||||
}
|
||||
|
||||
mask= BIT_MASK(left*8);
|
||||
*dst32= (*dst32 & mask) | (fill&~mask);
|
||||
dst32++;
|
||||
size -= 4-left;
|
||||
}
|
||||
|
||||
// Main stint.
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
switch(tmp) {
|
||||
do { *dst32++ = fill;
|
||||
case 3: *dst32++ = fill;
|
||||
case 2: *dst32++ = fill;
|
||||
case 1: *dst32++ = fill;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Tail
|
||||
size &= 3;
|
||||
if(size)
|
||||
{
|
||||
mask= BIT_MASK(size*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
}
|
||||
}
|
43
arm9/include/tonccpy.h
Normal file
43
arm9/include/tonccpy.h
Normal file
@ -0,0 +1,43 @@
|
||||
//# Stuff you may not have yet.
|
||||
|
||||
#ifndef TONCCPY_H
|
||||
#define TONCCPY_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
typedef unsigned int uint;
|
||||
#define BIT_MASK(len) ( (1<<(len))-1 )
|
||||
static inline u32 quad8(u16 x) { x |= x<<8; return x | x<<16; }
|
||||
|
||||
|
||||
//# Declarations and inlines.
|
||||
|
||||
void tonccpy(void *dst, const void *src, uint size);
|
||||
|
||||
void __toncset(void *dst, u32 fill, uint size);
|
||||
static inline void toncset(void *dst, u8 src, uint size);
|
||||
static inline void toncset16(void *dst, u16 src, uint size);
|
||||
static inline void toncset32(void *dst, u32 src, uint size);
|
||||
|
||||
|
||||
//! VRAM-safe memset, byte version. Size in bytes.
|
||||
static inline void toncset(void *dst, u8 src, uint size)
|
||||
{ __toncset(dst, quad8(src), size); }
|
||||
|
||||
//! VRAM-safe memset, halfword version. Size in hwords.
|
||||
static inline void toncset16(void *dst, u16 src, uint size)
|
||||
{ __toncset(dst, src|src<<16, size*2); }
|
||||
|
||||
//! VRAM-safe memset, word version. Size in words.
|
||||
static inline void toncset32(void *dst, u32 src, uint size)
|
||||
{ __toncset(dst, src, size*4); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -12,9 +12,6 @@
|
||||
|
||||
struct ctrl_tbl ctrl;
|
||||
|
||||
#define SRAM_ADDR 0x0A000000
|
||||
|
||||
|
||||
extern int carttype;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -23,6 +20,8 @@ extern "C" {
|
||||
|
||||
extern void _RamPG(void);
|
||||
extern void _RamSave(int bnk);
|
||||
extern bool isOmega;
|
||||
extern bool isSuperCard;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@ -35,14 +34,20 @@ void ctrl_get() {
|
||||
|
||||
memset((u8*)&ctrl, 0, sizeof(struct ctrl_tbl));
|
||||
|
||||
if(carttype != 5) {
|
||||
if(carttype != 5 && !isSuperCard && !isOmega) {
|
||||
_RamPG();
|
||||
ReadSram(SRAM_ADDR, (u8*)&ctrl, sizeof(struct ctrl_tbl));
|
||||
_RamSave(0);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(expfile, "%s/EXP128K.dat", ini.sign_dir);
|
||||
if (isSuperCard) {
|
||||
sprintf(expfile, "%s/SUPERCRD.dat", ini.sign_dir);
|
||||
} else if (isOmega) {
|
||||
sprintf(expfile, "%s/OMEGA.dat", ini.sign_dir);
|
||||
} else {
|
||||
sprintf(expfile, "%s/EXP128K.dat", ini.sign_dir);
|
||||
}
|
||||
exp = fopen(expfile, "rb");
|
||||
if(exp != NULL) {
|
||||
fread(&ctrl, 1, sizeof(struct ctrl_tbl), exp);
|
||||
@ -53,15 +58,21 @@ void ctrl_get() {
|
||||
void ctrl_set() {
|
||||
FILE *exp;
|
||||
char expfile[64];
|
||||
|
||||
if(carttype != 5) {
|
||||
|
||||
if(carttype != 5 && !isSuperCard && !isOmega) {
|
||||
_RamPG();
|
||||
WriteSram(SRAM_ADDR, (u8*)&ctrl, sizeof(struct ctrl_tbl));
|
||||
_RamSave(0);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(expfile, "%s/EXP128K.dat", ini.sign_dir);
|
||||
|
||||
if (isSuperCard) {
|
||||
sprintf(expfile, "%s/SUPERCRD.dat", ini.sign_dir);
|
||||
} else if (isOmega) {
|
||||
sprintf(expfile, "%s/OMEGA.dat", ini.sign_dir);
|
||||
} else {
|
||||
sprintf(expfile, "%s/EXP128K.dat", ini.sign_dir);
|
||||
}
|
||||
exp = fopen(expfile, "wb");
|
||||
if(exp != NULL) {
|
||||
fwrite(&ctrl, 1, sizeof(struct ctrl_tbl), exp);
|
||||
|
@ -780,108 +780,13 @@ void gba_check_int(char *name) {
|
||||
}
|
||||
}
|
||||
|
||||
u32 gba_check_Ram1(u8 *buf, u32 bufsize, u32 size, u32 ofs) {
|
||||
u32 i, ii;
|
||||
u32 *pbuf;
|
||||
u32 oldtype;
|
||||
|
||||
|
||||
// if(SaveType != 0)
|
||||
// return(SaveSize);
|
||||
if(PatchVer == PATCH_VER)return(SaveSize);
|
||||
|
||||
pbuf = (u32*)buf;
|
||||
if(PatchCnt > 1) { oldtype = PatchType[PatchCnt-1]/0x10; } else { oldtype = 0; }
|
||||
|
||||
i = ofs;
|
||||
for(ii = 0; ii < bufsize / 4; ii++) {
|
||||
ii = _type_chk(pbuf, ii, i);
|
||||
if(SaveType == 8)break;
|
||||
|
||||
if(oldtype == 0 || oldtype == 2) {
|
||||
ii = _eeprom_chk(pbuf, ii, i, size);
|
||||
if(oldtype == 0)
|
||||
oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
|
||||
if(oldtype == 0 || oldtype == 3) {
|
||||
ii = _flash512_chk(pbuf, ii, i);
|
||||
if(oldtype == 0)
|
||||
oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
|
||||
if(oldtype == 0 || oldtype == 4) {
|
||||
ii = _flash_chk(pbuf, ii, i);
|
||||
if(oldtype == 0)
|
||||
oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
|
||||
if(oldtype == 0 || oldtype == 5) {
|
||||
ii = _flash1M_chk(pbuf, ii, i);
|
||||
if(oldtype == 0)
|
||||
oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
|
||||
if(oldtype == 0 || oldtype == 8) {
|
||||
ii = _fmini_chk(pbuf, ii, i);
|
||||
if(oldtype == 0)
|
||||
oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
}
|
||||
return(SaveSize);
|
||||
}
|
||||
|
||||
|
||||
static void _ReadPSram(uint32 address, u8* data , uint32 size ) {
|
||||
static void _ReadPSram(uint32 address, u8* data, uint32 size) {
|
||||
u32 i;
|
||||
u16* pData = (u16*)data;
|
||||
u16* sData = (u16*)address;
|
||||
|
||||
for(i = 0; i < size / 2; i++)pData[i] = sData[i];
|
||||
}
|
||||
|
||||
void gba_check_Ram2(u32 exp, u8 *buf, u32 bufsize, u32 size) {
|
||||
u32 i, ii;
|
||||
u32 *pbuf;
|
||||
// int cnt;
|
||||
|
||||
switch (SaveType) {
|
||||
case 0: // UNKNOWN Famicom Mini
|
||||
if(PatchCnt > 2 && PatchType[1] == 0x81 && PatchType[2] == 0x84) {
|
||||
SaveType = 8;
|
||||
PatchCnt = 3;
|
||||
strcpy((char*)SaveVer, "FaMini");
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
PatchType[PatchCnt] = 0x86; // Patch
|
||||
PatchAddr[PatchCnt] = 0x100000 - 0x800;
|
||||
PatchCnt++;
|
||||
break;
|
||||
}
|
||||
|
||||
if(SaveType < 2 || PatchCnt <= 1 || SaveType == PatchType[1]/0x10)return;
|
||||
|
||||
pbuf = (u32*)buf;
|
||||
PatchCnt = 1;
|
||||
for(i = 0; i < size; i += bufsize, exp += bufsize) {
|
||||
_ReadPSram(exp, buf, bufsize+0x400);
|
||||
// dmaCopy((void *)exp, buf, bufsize);
|
||||
// dmaCopyWords(3, buf, (void *)exp, 0x100000);
|
||||
// cnt = PatchCnt;
|
||||
for(ii = 0; ii < bufsize / 4; ii++) {
|
||||
switch (SaveType) {
|
||||
case 2: ii = _eeprom_chk(pbuf, ii, i, size); break;
|
||||
case 3: ii = _flash512_chk(pbuf, ii, i); break;
|
||||
case 4: ii = _flash_chk(pbuf, ii, i); break;
|
||||
case 5: ii = _flash1M_chk(pbuf, ii, i); break;
|
||||
}
|
||||
}
|
||||
// if(PatchCnt > 1 && cnt == PatchCnt)
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 gba_check(FILE *gbaFile, u32 size, u8 *buf, u32 bufsize) {
|
||||
u32 i, ii;
|
||||
u32 *pbuf;
|
||||
@ -1706,7 +1611,6 @@ static void _patch_write(char *name) {
|
||||
|
||||
fwrite(buf, 1, 256, sign);
|
||||
fclose(sign);
|
||||
|
||||
}
|
||||
|
||||
void gba_patch_Ram(u32 exp, char *name, int cart) {
|
||||
@ -1728,21 +1632,32 @@ void gba_patch_Ram(u32 exp, char *name, int cart) {
|
||||
|
||||
fmini = 124;
|
||||
|
||||
u8 _OmegaPage = 0;
|
||||
|
||||
for(i = 1; i < PatchCnt; i++) {
|
||||
|
||||
buf = (u8*)(exp + PatchAddr[i]);
|
||||
|
||||
|
||||
|
||||
// EZ Flash Omega and it's silly mapping schemes.... :P
|
||||
if (isOmega) {
|
||||
if ((exp + PatchAddr[i]) > 0x09000000 && (exp + PatchAddr[i]) < 0x09800000) {
|
||||
if ((exp + PatchAddr[i]) >= 0x08800000 && (exp + PatchAddr[i]) < 0x09000000) {
|
||||
SetPSRampage(0);
|
||||
_OmegaPage = 0;
|
||||
} else if ((exp + PatchAddr[i]) >= 0x09000000 && (exp + PatchAddr[i]) < 0x09800000) {
|
||||
SetPSRampage(0x1000);
|
||||
} else if ((exp + PatchAddr[i]) > 0x0A000000 && (exp + PatchAddr[i]) < 0x0A800000) {
|
||||
_OmegaPage = 0x01;
|
||||
} else if ((exp + PatchAddr[i]) >= 0x09800000 && (exp + PatchAddr[i]) < 0x0A000000) {
|
||||
SetPSRampage(0x2000);
|
||||
} else if ((exp + PatchAddr[i]) > 0x0B000000 && (exp + PatchAddr[i]) < 0x0B800000) {
|
||||
_OmegaPage = 0x02;
|
||||
} else if ((exp + PatchAddr[i]) >= 0x0A000000 && (exp + PatchAddr[i]) < 0x0A800000) {
|
||||
SetPSRampage(0x3000);
|
||||
_OmegaPage = 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
if (isOmega) {
|
||||
buf = (u8*)((exp + PatchAddr[i]) - (_OmegaPage * 0x00800000));
|
||||
} else {
|
||||
buf = (u8*)(exp + PatchAddr[i]);
|
||||
}
|
||||
|
||||
switch(SaveType) {
|
||||
case 2: // EEPROM
|
||||
@ -1796,8 +1711,7 @@ void gba_patch_Ram(u32 exp, char *name, int cart) {
|
||||
case 5: // FLASH1M_V
|
||||
if(PatchType[i] == 0x51) {
|
||||
for(j = i + 1; j < PatchCnt; j++) {
|
||||
// if(PatchType[j] == 0x56)
|
||||
// savel = PatchAddr[j];
|
||||
// if(PatchType[j] == 0x56)savel = PatchAddr[j];
|
||||
if(PatchType[j] == 0x58)break;
|
||||
}
|
||||
if (j < PatchCnt)V102 = false;
|
||||
@ -1957,6 +1871,115 @@ void gba_patch_Ram(u32 exp, char *name, int cart) {
|
||||
if (isOmega)SetPSRampage(0);
|
||||
}
|
||||
|
||||
u32 gba_check_Ram1(u8 *buf, u32 bufsize, u32 size, u32 ofs) {
|
||||
u32 i, ii;
|
||||
u32 *pbuf;
|
||||
u32 oldtype;
|
||||
|
||||
|
||||
// if(SaveType != 0)return(SaveSize);
|
||||
if(PatchVer == PATCH_VER)return(SaveSize);
|
||||
|
||||
pbuf = (u32*)buf;
|
||||
if(PatchCnt > 1) { oldtype = PatchType[PatchCnt-1]/0x10; } else { oldtype = 0; }
|
||||
|
||||
i = ofs;
|
||||
for(ii = 0; ii < bufsize / 4; ii++) {
|
||||
ii = _type_chk(pbuf, ii, i);
|
||||
if(SaveType == 8)break;
|
||||
|
||||
if(oldtype == 0 || oldtype == 2) {
|
||||
ii = _eeprom_chk(pbuf, ii, i, size);
|
||||
if(oldtype == 0)oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
|
||||
if(oldtype == 0 || oldtype == 3) {
|
||||
ii = _flash512_chk(pbuf, ii, i);
|
||||
if(oldtype == 0)oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
|
||||
if(oldtype == 0 || oldtype == 4) {
|
||||
ii = _flash_chk(pbuf, ii, i);
|
||||
if(oldtype == 0)oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
|
||||
if(oldtype == 0 || oldtype == 5) {
|
||||
ii = _flash1M_chk(pbuf, ii, i);
|
||||
if(oldtype == 0)oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
|
||||
if(oldtype == 0 || oldtype == 8) {
|
||||
ii = _fmini_chk(pbuf, ii, i);
|
||||
if(oldtype == 0)oldtype = PatchType[PatchCnt-1]/0x10;
|
||||
}
|
||||
}
|
||||
return(SaveSize);
|
||||
}
|
||||
|
||||
void gba_check_Ram2(u32 exp, u8 *buf, u32 bufsize, u32 size) {
|
||||
u32 i, ii;
|
||||
u32 *pbuf;
|
||||
// int cnt;
|
||||
|
||||
switch (SaveType) {
|
||||
case 0: // UNKNOWN Famicom Mini
|
||||
if(PatchCnt > 2 && PatchType[1] == 0x81 && PatchType[2] == 0x84) {
|
||||
SaveType = 8;
|
||||
PatchCnt = 3;
|
||||
strcpy((char*)SaveVer, "FaMini");
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
PatchType[PatchCnt] = 0x86; // Patch
|
||||
PatchAddr[PatchCnt] = 0x100000 - 0x800;
|
||||
PatchCnt++;
|
||||
break;
|
||||
}
|
||||
|
||||
if(SaveType < 2 || PatchCnt <= 1 || SaveType == PatchType[1]/0x10)return;
|
||||
|
||||
pbuf = (u32*)buf;
|
||||
PatchCnt = 1;
|
||||
|
||||
u16 OmegaPage = 0;
|
||||
|
||||
for(i = 0; i < size; i += bufsize, exp += bufsize) {
|
||||
if (isOmega) {
|
||||
if (exp >= 0x09000000) {
|
||||
OmegaPage += 0x1000;
|
||||
SetPSRampage(OmegaPage);
|
||||
exp = PSRAMBase_S98;
|
||||
}
|
||||
/*if (exp >= 0x08800000 && exp < 0x09000000) {
|
||||
SetPSRampage(0);
|
||||
} else if (exp >= 0x09000000 && exp < 0x09800000) {
|
||||
SetPSRampage(0x1000);
|
||||
} else if (exp >= 0x0A000000 && exp < 0x0A800000) {
|
||||
SetPSRampage(0x2000);
|
||||
} else if (exp >= 0x0B000000 && exp < 0x0B800000) {
|
||||
SetPSRampage(0x3000);
|
||||
}*/
|
||||
}
|
||||
// u32 currentAddress = exp;
|
||||
// if (isOmega && currentAddress >= 0x08800000 && _OmegaPage != 0)currentAddress = (currentAddress - (_OmegaPage * 0x00800000));
|
||||
_ReadPSram(exp, buf, bufsize+0x400);
|
||||
// dmaCopy((void *)exp, buf, bufsize);
|
||||
// dmaCopyWords(3, buf, (void *)exp, 0x100000);
|
||||
// cnt = PatchCnt;
|
||||
for(ii = 0; ii < bufsize / 4; ii++) {
|
||||
switch (SaveType) {
|
||||
case 2: ii = _eeprom_chk(pbuf, ii, i, size); break;
|
||||
case 3: ii = _flash512_chk(pbuf, ii, i); break;
|
||||
case 4: ii = _flash_chk(pbuf, ii, i); break;
|
||||
case 5: ii = _flash1M_chk(pbuf, ii, i); break;
|
||||
}
|
||||
}
|
||||
// if(PatchCnt > 1 && cnt == PatchCnt)
|
||||
// break;
|
||||
if (isOmega)SetPSRampage(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void gba_patch(u8 *buf, u32 add, u32 bufsize, int GBAmode, char *name) {
|
||||
int i, j;
|
||||
|
@ -3,12 +3,13 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern void gba_check_int(char *name);
|
||||
extern u32 gba_check_Ram1(u8 *buf, u32 bufsize, u32 size, u32 ofs);
|
||||
extern void gba_check_Ram2(u32 exp, u8 *buf, u32 bufsize, u32 size);
|
||||
extern u32 gba_check(FILE *gbaFile, u32 size, u8 *buf, u32 bufsize);
|
||||
extern void gba_patch_Ram(u32 exp, char *name, int cart);
|
||||
extern u32 gba_check(FILE *gbaFile, u32 size, u8 *buf, u32 bufsize);
|
||||
extern u32 gba_check_Ram1(u8 *buf, u32 bufsize, u32 size, u32 ofs);
|
||||
extern void gba_check_Ram2(u32 exp, u8 *buf, u32 bufsize, u32 size);
|
||||
extern void gba_patch(u8 *buf, u32 add, u32 bufsize, int GBAmode, char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
//#include <nds/arm9/rumble.h>
|
||||
|
||||
#include "dsCard.h"
|
||||
#include "sc_patches.h"
|
||||
#include "sc_sram.h"
|
||||
|
||||
//#include <nds/arm9/console.h> //basic print funcionality
|
||||
|
||||
@ -34,7 +36,6 @@
|
||||
#define SRAM_PAGE_SIZE 0x1000 // SRAM Page Size
|
||||
#define MAX_SRAM 0x80000 // 4MBit/512KByte total SRAM
|
||||
|
||||
#define SRAM_ADDR 0x0A000000
|
||||
#define USE_SRAM 0x20000 // 128KByte
|
||||
#define USE_SRAM_PG 48 // 0x0A030000-0A031FFF
|
||||
#define USE_SRAM_PG_EZ4 11 // 0x0A008000-0A00FFFF
|
||||
@ -45,7 +46,6 @@
|
||||
|
||||
#define USE_SRAM_NOR 16 // 0x0A010000-0A02FFFF
|
||||
|
||||
#define USE_SRAM_PSR_Omega 160
|
||||
#define USE_SRAM_PSR 50 // 0x0A032000-0A051FFF
|
||||
#define USE_SRAM_PSR_EZ4 16 // 0x0A010000-0A02FFFF
|
||||
#define USE_SRAM_PSR_EWN 8 // 0x0A000000-0A01FFFF
|
||||
@ -60,6 +60,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void turn_off(int cmd);
|
||||
extern void dsp_bar(int mod, int per);
|
||||
|
||||
extern char curpath[];
|
||||
extern int sortfile[];
|
||||
@ -404,13 +406,22 @@ void _RamPG() {
|
||||
SetM3Ram(USE_SRAM_PG_M3);
|
||||
return;
|
||||
}
|
||||
SetRampage(USE_SRAM_PG);
|
||||
if (isOmega) {
|
||||
// Omega_Bank_Switching(0);
|
||||
// SetRampage(0x20);
|
||||
SetRampage(0x40);
|
||||
// SetRampage(USE_SRAM_PG);
|
||||
|
||||
} else {
|
||||
SetRampage(USE_SRAM_PG);
|
||||
}
|
||||
// SetRampage(USE_SRAM_PG);
|
||||
return;
|
||||
}
|
||||
|
||||
void _RamSave(int bnk) {
|
||||
if (isSuperCard)return;
|
||||
if (isOmega)return;
|
||||
// if (isOmega)return;
|
||||
switch (carttype) {
|
||||
case 3:
|
||||
SetRampage(USE_SRAM_PSR_EZ4 + bnk * 16);
|
||||
@ -427,11 +438,17 @@ void _RamSave(int bnk) {
|
||||
|
||||
if(GBAmode == 0) {
|
||||
if (isOmega) {
|
||||
SetRampage(bnk * 16);
|
||||
SetRampage(bnk * 0x10);
|
||||
/*switch (bnk) {
|
||||
case 0: SetRampage(0); break;
|
||||
case 1: SetRampage(0x10); break;
|
||||
default: return;
|
||||
}*/
|
||||
} else {
|
||||
SetRampage(USE_SRAM_PSR + bnk * 16);
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
if (isOmega)return;
|
||||
SetRampage(USE_SRAM_NOR + bnk * 16);
|
||||
}
|
||||
return;
|
||||
@ -484,9 +501,9 @@ int checkFlashID() {
|
||||
SetSDControl(0);
|
||||
Set_RTC_status(1);
|
||||
gl_ingame_RTC_open_status = Read_SET_info(13);
|
||||
if( (gl_ingame_RTC_open_status != 0x0) && (gl_ingame_RTC_open_status != 0x1))gl_ingame_RTC_open_status = 0x1;
|
||||
Omega_Bank_Switching(0);
|
||||
Set_AUTO_save(0);
|
||||
if ((gl_ingame_RTC_open_status != 0x0) && (gl_ingame_RTC_open_status != 0x1))gl_ingame_RTC_open_status = 0x1;
|
||||
// Set_AUTO_save(0);
|
||||
// Omega_Bank_Switching(0);
|
||||
return carttype;
|
||||
case 0x227E0000: // SuperCard
|
||||
carttype = 6;
|
||||
@ -641,13 +658,12 @@ bool checkBackup() {
|
||||
|
||||
|
||||
void writeSramToFile(char *savename) {
|
||||
FILE *saver;
|
||||
FILE *saver;
|
||||
u32 len;
|
||||
|
||||
if(savename[0] == 0) return;
|
||||
|
||||
// if((GBAmode == 0) && (checkBackup() == false))
|
||||
// return;
|
||||
// if((GBAmode == 0) && (checkBackup() == false))return;
|
||||
|
||||
// getSaveFilename(filename, tbuf);
|
||||
sprintf(tbuf, "%s/%s", ini.save_dir, savename);
|
||||
@ -656,16 +672,17 @@ void writeSramToFile(char *savename) {
|
||||
// OpenNorWrite();
|
||||
|
||||
_RamSave(0);
|
||||
|
||||
ReadSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
|
||||
if (isOmega) { ReadSram(SRAM_ADDR_OMEGA, rwbuf, USE_SRAM / 2); } else { ReadSram(SRAM_ADDR, rwbuf, USE_SRAM / 2); }
|
||||
|
||||
if(saver != NULL) {
|
||||
len = USE_SRAM / 2;
|
||||
if(len > savesize)len = savesize;
|
||||
fwrite(rwbuf, 1, len, saver);
|
||||
}
|
||||
if(savesize > USE_SRAM / 2) {
|
||||
if((savesize > (USE_SRAM / 2)) && !isSuperCard) {
|
||||
_RamSave(1);
|
||||
ReadSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
if (isOmega) { ReadSram(SRAM_ADDR_OMEGA, rwbuf, USE_SRAM / 2); } else { ReadSram(SRAM_ADDR, rwbuf, USE_SRAM / 2); }
|
||||
if(saver != NULL)fwrite(rwbuf, 1, USE_SRAM / 2, saver);
|
||||
}
|
||||
fclose(saver);
|
||||
@ -688,32 +705,63 @@ void SRAMdump(int cmd) {
|
||||
mx = 8;
|
||||
|
||||
switch (carttype) {
|
||||
case 1:
|
||||
if (isOmega)mx = 2;
|
||||
break;
|
||||
case 4: mx = 4; break;
|
||||
case 5: mx = 2; break;
|
||||
case 6: mx = 16; break;
|
||||
}
|
||||
case 6:
|
||||
if (isSuperCard) { mx = 1; } else { mx = 16; }
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(name, "%s/SRAM.BIN", ini.save_dir);
|
||||
|
||||
if(cmd == 0) {
|
||||
dsp_bar(4, -1);
|
||||
dmp = fopen(name, "wb");
|
||||
for(i = 0; i < mx; i++) {
|
||||
if(carttype == 6) {
|
||||
if(carttype == 6 && !isSuperCard) {
|
||||
SetM3Ram(i);
|
||||
} else {
|
||||
if((carttype >= 4) && !isSuperCard) {
|
||||
} else if (!isSuperCard) {
|
||||
if((carttype >= 4)) {
|
||||
SetEWINRam(8 + i);
|
||||
} else {
|
||||
if (isOmega && (i > 4))Omega_Bank_Switching(0x01);
|
||||
// if (isOmega && (i > 4))Omega_Bank_Switching(1);
|
||||
SetRampage(i * 16);
|
||||
}
|
||||
}
|
||||
ReadSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
|
||||
if (isOmega) { ReadSram(SRAM_ADDR_OMEGA, rwbuf, USE_SRAM / 2); } else { ReadSram(SRAM_ADDR, rwbuf, USE_SRAM / 2); }
|
||||
|
||||
if(dmp != NULL)fwrite(rwbuf, 1, USE_SRAM / 2, dmp);
|
||||
|
||||
if (i == 0) {
|
||||
dsp_bar(4, 0);
|
||||
} else {
|
||||
switch (mx) {
|
||||
case 2:
|
||||
if (i == 1) { dsp_bar(4, 50); } else if (i == 2) { dsp_bar(4, 100); }
|
||||
break;
|
||||
case 4:
|
||||
if (i == 1) { dsp_bar(4, 25); } else if (i == 2) { dsp_bar(4, 50); } else if (i == 3) { dsp_bar(4, 75); } else if (i == 4) { dsp_bar(4, 100); }
|
||||
break;
|
||||
case 8:
|
||||
if (i == 2) { dsp_bar(4, 25); } else if (i == 4) { dsp_bar(4, 50); } else if (i == 6) { dsp_bar(4, 75); } else if (i == 8) { dsp_bar(4, 100); }
|
||||
break;
|
||||
case 16:
|
||||
if (i == 4) { dsp_bar(4, 25); } else if (i == 8) { dsp_bar(4, 50); } else if (i == 12) { dsp_bar(6, 75); } else if (i == 16) { dsp_bar(8, 100); }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dsp_bar(5, -1);
|
||||
dmp = fopen(name, "rb");
|
||||
if((carttype < 4) && !isSuperCard && !isOmega && !is3in1Plus)OpenNorWrite();
|
||||
|
||||
if (isOmega)Omega_Bank_Switching(0);
|
||||
|
||||
for(i = 0; i < mx; i++) {
|
||||
memset(rwbuf, 0, USE_SRAM / 2);
|
||||
if(dmp != NULL)
|
||||
@ -724,18 +772,36 @@ void SRAMdump(int cmd) {
|
||||
if((carttype >= 4) && !isSuperCard) {
|
||||
SetEWINRam(8 + i);
|
||||
} else {
|
||||
if (isOmega && (i > 4))Omega_Bank_Switching(0x01);
|
||||
// if (isOmega && (i > 4))Omega_Bank_Switching(1);
|
||||
SetRampage(i * 16);
|
||||
}
|
||||
}
|
||||
WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
if (isOmega) { WriteSram(SRAM_ADDR_OMEGA, rwbuf, USE_SRAM / 2); } else { WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2); }
|
||||
if (i == 0) {
|
||||
dsp_bar(5, 0);
|
||||
} else {
|
||||
switch (mx) {
|
||||
case 2:
|
||||
if (i == 1) { dsp_bar(5, 50); } else if (i == 2) { dsp_bar(5, 100); }
|
||||
break;
|
||||
case 4:
|
||||
if (i == 1) { dsp_bar(5, 25); } else if (i == 2) { dsp_bar(5, 50); } else if (i == 3) { dsp_bar(5, 75); } else if (i == 4) { dsp_bar(5, 100); }
|
||||
break;
|
||||
case 8:
|
||||
if (i == 2) { dsp_bar(5, 25); } else if (i == 4) { dsp_bar(5, 50); } else if (i == 6) { dsp_bar(5, 75); } else if (i == 8) { dsp_bar(5, 100); }
|
||||
break;
|
||||
case 16:
|
||||
if (i == 4) { dsp_bar(5, 25); } else if (i == 8) { dsp_bar(5, 50); } else if (i == 12) { dsp_bar(5, 75); } else if (i == 16) { dsp_bar(5, 100); }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((carttype < 4) && !isSuperCard && !isOmega && !is3in1Plus)CloseNorWrite();
|
||||
}
|
||||
fclose(dmp);
|
||||
if (isOmega)Omega_Bank_Switching(0);
|
||||
// if (isOmega)Omega_Bank_Switching(0);
|
||||
_RamSave(0);
|
||||
dsp_bar(-1, 100);
|
||||
}
|
||||
|
||||
void blankSRAM(char *savename) {
|
||||
@ -745,11 +811,16 @@ void blankSRAM(char *savename) {
|
||||
if((carttype < 4) && !isSuperCard && !isOmega && !is3in1Plus)OpenNorWrite();
|
||||
|
||||
_RamSave(0);
|
||||
WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
|
||||
if (isOmega)Omega_Bank_Switching(0);
|
||||
|
||||
if (isOmega) { WriteSram(SRAM_ADDR_OMEGA, rwbuf, USE_SRAM / 2); } else { WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2); }
|
||||
|
||||
// if(carttype != 5) {
|
||||
_RamSave(1);
|
||||
WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
if (!isSuperCard) {
|
||||
_RamSave(1);
|
||||
if (isOmega) { WriteSram(SRAM_ADDR_OMEGA, rwbuf, USE_SRAM / 2); } else { WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2); }
|
||||
}
|
||||
// }
|
||||
|
||||
ctrl.save_siz[GBAmode] = savesize;
|
||||
@ -776,7 +847,6 @@ void writeSramFromFile(char *savename) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if((carttype < 4) && !isSuperCard && !isOmega && !is3in1Plus)OpenNorWrite();
|
||||
|
||||
ctrl.save_siz[GBAmode] = savesize;
|
||||
@ -791,14 +861,17 @@ void writeSramFromFile(char *savename) {
|
||||
|
||||
memset(rwbuf, 0xFF, USE_SRAM / 2);
|
||||
fread(rwbuf, 1, USE_SRAM / 2, saver);
|
||||
WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
|
||||
if (isOmega)Omega_Bank_Switching(0);
|
||||
|
||||
if (isOmega) { WriteSram(SRAM_ADDR_OMEGA, rwbuf, USE_SRAM / 2); } else { WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2); }
|
||||
|
||||
// if(carttype != 5) {
|
||||
if(savesize > USE_SRAM / 2) {
|
||||
if((savesize > (USE_SRAM / 2)) && !isSuperCard) {
|
||||
_RamSave(1);
|
||||
memset(rwbuf, 0xFF, USE_SRAM / 2);
|
||||
fread(rwbuf, 1, USE_SRAM / 2, saver);
|
||||
WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
if (isOmega) { WriteSram(SRAM_ADDR_OMEGA, rwbuf, USE_SRAM / 2); } else { WriteSram(SRAM_ADDR, rwbuf, USE_SRAM / 2); }
|
||||
_RamSave(0);
|
||||
}
|
||||
// }
|
||||
@ -809,7 +882,7 @@ void writeSramFromFile(char *savename) {
|
||||
}
|
||||
|
||||
|
||||
void _ReadPSram(uint32 address, u8* data , uint32 size) {
|
||||
/*void _ReadPSram(uint32 address, u8* data , uint32 size) {
|
||||
u32 i;
|
||||
u16* pData = (u16*)data;
|
||||
u16* sData = (u16*)address;
|
||||
@ -817,7 +890,7 @@ void _ReadPSram(uint32 address, u8* data , uint32 size) {
|
||||
for(i = 0; i < size / 2; i++)pData[i] = sData[i];
|
||||
}
|
||||
|
||||
/*void _WritePSram(uint32 address, u8* data , uint32 size) {
|
||||
void _WritePSram(uint32 address, u8* data , uint32 size) {
|
||||
u32 i;
|
||||
u16* sData = (u16*)data;
|
||||
u16* pData = (u16*)address;
|
||||
@ -826,10 +899,6 @@ void _ReadPSram(uint32 address, u8* data , uint32 size) {
|
||||
}*/
|
||||
|
||||
|
||||
extern void turn_off(int cmd);
|
||||
extern void dsp_bar(int mod, int per);
|
||||
|
||||
|
||||
int writeFileToNor(int sel) {
|
||||
FILE *gbaFile;
|
||||
char savName[512];
|
||||
@ -912,9 +981,14 @@ int writeFileToNor(int sel) {
|
||||
|
||||
CloseNorWrite();
|
||||
|
||||
dsp_bar(5, -1);
|
||||
// getSaveFilename(sel, savName);
|
||||
if(cmd >= 0) { writeSramFromFile(savName); } else { blankSRAM(savName); }
|
||||
|
||||
dsp_bar(5, 100);
|
||||
|
||||
for (int i = 0; i < 30; i++)swiWaitForVBlank();
|
||||
|
||||
dsp_bar(-1, 100);
|
||||
// SetRampage(USE_SRAM_NOR);
|
||||
return(0);
|
||||
@ -934,7 +1008,7 @@ int writeFileToRam(int sel) {
|
||||
|
||||
if (carttype >= 3) { fsz = MAX_NOR; } else if (isOmega) { fsz = MAX_NOR; } else { fsz = MAX_PSRAM; }
|
||||
|
||||
if (carttype >= 4) { exp = 0x08000000; } else if (isOmega) { exp = 0x08800000; } else { exp = 0x08060000; }
|
||||
if (carttype >= 4) { exp = FlashBase; } else if (isOmega) { exp = PSRAMBase_S98; } else { exp = 0x08060000; }
|
||||
|
||||
exps = exp;
|
||||
|
||||
@ -949,7 +1023,7 @@ int writeFileToRam(int sel) {
|
||||
sprintf(tbuf, "%s%s", curpath, fs[sel].filename);
|
||||
|
||||
gbaFile = fopen(tbuf, "rb");
|
||||
if(gbaFile == NULL) return(0);
|
||||
if (gbaFile == NULL)return 0;
|
||||
|
||||
strcpy(savName, fs[sel].filename);
|
||||
cmd = save_sel(0, savName);
|
||||
@ -977,18 +1051,18 @@ int writeFileToRam(int sel) {
|
||||
|
||||
if(siz == 0 && gba)header_rep(rwbuf);
|
||||
|
||||
savesize = gba_check_Ram1(rwbuf, 0x100000, fs[sel].filesize, siz);
|
||||
|
||||
if (!isOmega)savesize = gba_check_Ram1(rwbuf, 0x100000, fs[sel].filesize, siz);
|
||||
|
||||
// EZ Flash Omega and it's silly mapping schemes.... :P
|
||||
if (isOmega) {
|
||||
if (exp >= 0x09000000) {
|
||||
PSRamPage += 0x1000;
|
||||
SetPSRampage(PSRamPage);
|
||||
exp = 0x08800000;
|
||||
exp = PSRAMBase_S98;
|
||||
}
|
||||
}
|
||||
|
||||
// _WritePSram(exp, rwbuf, 0x100000);
|
||||
|
||||
dmaCopy((void*)rwbuf, (void*)exp, 0x100000);
|
||||
// dmaCopyWords(3, rwbuf, (void *)exp, 0x100000);
|
||||
}
|
||||
@ -998,9 +1072,32 @@ int writeFileToRam(int sel) {
|
||||
if (isOmega)SetPSRampage(0);
|
||||
|
||||
dsp_bar(2, 100);
|
||||
gba_check_Ram2(exps, rwbuf, 0x100000, fs[sel].filesize);
|
||||
gba_patch_Ram(exps, fs[sel].filename, carttype);
|
||||
|
||||
|
||||
bool allowPatches = true;
|
||||
|
||||
if (isSuperCard) {
|
||||
dsp_bar(-1, 100);
|
||||
dsp_bar(3, -1);
|
||||
dsp_bar(3, 25);
|
||||
patchGeneralWhiteScreen(fs[sel].filesize);
|
||||
allowPatches = patchSpecificGame();
|
||||
dsp_bar(3, 50);
|
||||
romSize = fs[sel].filesize;
|
||||
const struct save_type* saveType = allowPatches ? save_findTag() : NULL;
|
||||
dsp_bar(3, 75);
|
||||
if (saveType != NULL && saveType->patchFunc != NULL)saveType->patchFunc(saveType);
|
||||
dsp_bar(3, 100);
|
||||
for (int I = 0; I < 50; I++)swiWaitForVBlank();
|
||||
dsp_bar(-1, 100);
|
||||
} else {
|
||||
gba_check_Ram2(exps, rwbuf, 0x100000, fs[sel].filesize);
|
||||
dsp_bar(-1, 100);
|
||||
}
|
||||
|
||||
dsp_bar(5, -1);
|
||||
|
||||
if (!isSuperCard)gba_patch_Ram(exps, fs[sel].filename, carttype);
|
||||
|
||||
fclose(gbaFile);
|
||||
|
||||
|
||||
@ -1010,10 +1107,11 @@ int writeFileToRam(int sel) {
|
||||
// }
|
||||
|
||||
// getSaveFilename(sel, savName);
|
||||
|
||||
dsp_bar(5, 50);
|
||||
|
||||
if(cmd >= 0) { writeSramFromFile(savName); } else { blankSRAM(savName); }
|
||||
|
||||
dsp_bar(-1, 100);
|
||||
|
||||
|
||||
if((carttype < 4) && !isSuperCard && !isOmega)CloseNorWrite();
|
||||
|
||||
_RamSave(0);
|
||||
@ -1022,19 +1120,24 @@ int writeFileToRam(int sel) {
|
||||
if(carttype == 6) { Close_M3(); } else { Close_EWIN(); }
|
||||
}
|
||||
|
||||
dsp_bar(5, 100);
|
||||
|
||||
for (int i = 0; i < 30; i++)swiWaitForVBlank();
|
||||
|
||||
dsp_bar(-1, 100);
|
||||
|
||||
if (isSuperCard)return 0;
|
||||
|
||||
if (isOmega) {
|
||||
Set_RTC_status(gl_ingame_RTC_open_status);
|
||||
rtc_toggle(true);
|
||||
// Omega_InitFatBuffer(0x10);
|
||||
SetRompage(0x200);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(carttype == 3) {
|
||||
SetRompage(0x300);
|
||||
} else if(carttype <= 2) {
|
||||
SetRompage(384);
|
||||
}
|
||||
if (carttype == 3) { SetRompage(0x300); } else if (carttype <= 2) { SetRompage(384); }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -882,9 +882,19 @@ int gba_sel() {
|
||||
if(GBAmode == 1) {
|
||||
if(checkSRAM(filename)) {
|
||||
// if(cnf_inp(3, 4) & KEY_A)
|
||||
if(save_sel(0, filename) >= 0)writeSramFromFile(filename);
|
||||
if(save_sel(0, filename) >= 0) {
|
||||
dsp_bar(5, -1);
|
||||
swiWaitForVBlank();
|
||||
dsp_bar(5, 50);
|
||||
writeSramFromFile(filename);
|
||||
dsp_bar(5, 100);
|
||||
for (int I = 0; I < 50; I++)swiWaitForVBlank();
|
||||
dsp_bar(-1, 100);
|
||||
}
|
||||
_gba_sel_dsp(sel, yc, 0);
|
||||
} else err_cnf(4, 5);
|
||||
} else {
|
||||
err_cnf(4, 5);
|
||||
}
|
||||
} else {
|
||||
if(cnf_inp(5, 6) & KEY_A) {
|
||||
SRAMdump(1);
|
||||
@ -930,7 +940,15 @@ int gba_sel() {
|
||||
if(ky & KEY_B) {
|
||||
if(checkSRAM(filename)) {
|
||||
// if(cnf_inp(1, 2) & KEY_A) {
|
||||
if(save_sel(1, filename) >= 0)writeSramToFile(filename);
|
||||
if(save_sel(1, filename) >= 0) {
|
||||
dsp_bar(4, -1);
|
||||
swiWaitForVBlank();
|
||||
dsp_bar(4, 50);
|
||||
writeSramToFile(filename);
|
||||
dsp_bar(4, 100);
|
||||
for (int I = 0; I < 50; I++)swiWaitForVBlank();
|
||||
dsp_bar(-1, 100);
|
||||
}
|
||||
_gba_sel_dsp(sel, yc, 0);
|
||||
} else {
|
||||
err_cnf(4, 5);
|
||||
@ -1096,7 +1114,15 @@ inp_key();
|
||||
|
||||
GBAmode = 0;
|
||||
if(checkSRAM(filename) && checkBackup()) {
|
||||
dsp_bar(4, -1);
|
||||
dsp_bar(4, 0);
|
||||
for (int I = 0; I < 30; I++)swiWaitForVBlank();
|
||||
if(save_sel(1, filename) >= 0)writeSramToFile(filename);
|
||||
dsp_bar(4, 50);
|
||||
for (int I = 0; I < 30; I++)swiWaitForVBlank();
|
||||
dsp_bar(4, 100);
|
||||
for (int I = 0; I < 30; I++)swiWaitForVBlank();
|
||||
dsp_bar(-1, 100);
|
||||
}
|
||||
|
||||
getGBAmode();
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
char *errmsg[16];
|
||||
char *cnfmsg[11];
|
||||
char *barmsg[4];
|
||||
char *barmsg[6];
|
||||
char *cmd_m[4];
|
||||
char *t_msg[22];
|
||||
char *savmsg[6];
|
||||
@ -78,18 +78,22 @@ static const char *cnfmsg_e[11] = {
|
||||
};
|
||||
|
||||
|
||||
static const char *barmsg_j[4] = {
|
||||
static const char *barmsg_j[6] = {
|
||||
" NORを消去中... ", // 0
|
||||
" NORにコピー中... ", // 1
|
||||
" RAMにロード中... ", // 2
|
||||
" ROMを解析中... " // 3
|
||||
" ROMを解析中... ", // 3
|
||||
" SRAMの読み取り ", // 4
|
||||
" SRAMへの書き込み " // 5
|
||||
};
|
||||
|
||||
static const char *barmsg_e[4] = {
|
||||
static const char *barmsg_e[6] = {
|
||||
" Erasing NOR... ", // 0
|
||||
" Copying to NOR... ", // 1
|
||||
" Loading to RAM... ", // 2
|
||||
" Analyzing ROM... " // 3
|
||||
" Analyzing ROM... ", // 3
|
||||
" Reading SRAM... ", // 4
|
||||
" Writing SRAM... " // 5
|
||||
};
|
||||
|
||||
|
||||
@ -187,7 +191,7 @@ void setLangMsg() {
|
||||
if(UserLang != 0) {
|
||||
for(i = 0; i < 16; i++)errmsg[i] = (char*)errmsg_e[i];
|
||||
for(i = 0; i < 11; i++)cnfmsg[i] = (char*)cnfmsg_e[i];
|
||||
for(i = 0; i < 4; i++)barmsg[i] = (char*)barmsg_e[i];
|
||||
for(i = 0; i < 6; i++)barmsg[i] = (char*)barmsg_e[i];
|
||||
for(i = 0; i < 4; i++)cmd_m[i] = (char*)cmd_m_e[i];
|
||||
for(i = 0; i < 22; i++)t_msg[i] = (char*)t_msg_e[i];
|
||||
for(i = 0; i < 6; i++)savmsg[i] = (char*)savmsg_e[i];
|
||||
@ -196,7 +200,7 @@ void setLangMsg() {
|
||||
|
||||
for(i = 0; i < 16; i++)errmsg[i] = (char*)errmsg_j[i];
|
||||
for(i = 0; i < 11; i++)cnfmsg[i] = (char*)cnfmsg_j[i];
|
||||
for(i = 0; i < 4; i++)barmsg[i] = (char*)barmsg_j[i];
|
||||
for(i = 0; i < 6; i++)barmsg[i] = (char*)barmsg_j[i];
|
||||
for(i = 0; i < 4; i++)cmd_m[i] = (char*)cmd_m_j[i];
|
||||
for(i = 0; i < 22; i++)t_msg[i] = (char*)t_msg_j[i];
|
||||
for(i = 0; i < 6; i++)savmsg[i] = (char*)savmsg_j[i];
|
||||
|
Loading…
Reference in New Issue
Block a user