mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-06 22:04:10 +08:00
初步完成patch的代码,开始测试
This commit is contained in:
parent
29f57a58d1
commit
2091380ada
@ -21,10 +21,13 @@ typedef int cheat_error_t;
|
||||
#define CHEAT_MODE_SIZE 3
|
||||
|
||||
#define MAKE_ENTID(hole, key) ((key+1)<<16|(hole+1))
|
||||
#define ENT_USING(entid) ((entid) > 0xffff)
|
||||
|
||||
cheat_error_t init_current_cheat( u32 id, u16 len );
|
||||
cheat_error_t put_current_cheat( acl_entryid_t entry_id );
|
||||
cheat_error_t get_current_cheat( u32 *id, u32 *len, void **entry_array );
|
||||
cheat_error_t info_current_cheat( u32 *id, u32 *len );
|
||||
cheat_error_t get_current_cheat( u32 index, acl_entryid_t *id );
|
||||
cheat_error_t include_current_cheat( acl_entryid_t entry_id );
|
||||
cheat_error_t fini_current_cheat();
|
||||
|
||||
cheat_error_t push_current_cheat( const char *filename, int is_using );
|
||||
@ -32,6 +35,6 @@ cheat_error_t pop_current_cheat( const char *filename, u32 chtid );
|
||||
cheat_error_t chtid_current_cheat( const char *filename, u32 *pointer_id );
|
||||
cheat_error_t chtlst_current_cheat( const char *filename, u8 pointer_data[256] );
|
||||
|
||||
cheat_error_t apply_cheat( int mode, int szrom );
|
||||
cheat_error_t apply_cheat( int mode, u32 szrom, u16 bindkey, u32 varaddr, u32 *outsize );
|
||||
|
||||
#endif//_CHEAT_H_
|
||||
|
@ -1,8 +1,14 @@
|
||||
#include "arm11/acl.h"
|
||||
#include "arm11/cheat.h"
|
||||
#include "util.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ROM_LOC (0x20000000u)
|
||||
|
||||
#define MAKE_ENT(hole,key) ((key<<16) | hole)
|
||||
#define ROM_LOC (0x20000000u)
|
||||
#define GBA_KEYCODE(k) (0x3ff & (~(k)))
|
||||
|
||||
#define SIZE_32M (32*1024*1024)
|
||||
#define MAX_HOOKPOINT 10
|
||||
@ -48,15 +54,41 @@ cheat_error_t put_current_cheat( acl_entryid_t entid )
|
||||
else return CCHT_INVALID;
|
||||
}
|
||||
|
||||
cheat_error_t get_current_cheat( u32 *id, u32 *len, void **entry_array )
|
||||
cheat_error_t info_current_cheat( u32 *id, u32 *len )
|
||||
{
|
||||
if( setting.chtId == 0 ) return CCHT_NOT_INIT;
|
||||
*id = setting.chtId;
|
||||
*len = setting.entLen;
|
||||
*entry_array = setting.entArr;
|
||||
if( id != NULL ) *id = setting.chtId;
|
||||
if( len != NULL ) *len = setting.entLen;
|
||||
return CCHT_OK;
|
||||
}
|
||||
|
||||
cheat_error_t get_current_cheat( u32 index, acl_entryid_t *id )
|
||||
{
|
||||
if( setting.chtId == 0 ) return CCHT_NOT_INIT;
|
||||
if( index < setting.entLen )
|
||||
{
|
||||
acl_index_t val = setting.entArr[index];
|
||||
if( id != NULL ) *id = MAKE_ENT( index+1, val );
|
||||
return CCHT_OK;
|
||||
}
|
||||
else return CCHT_INVALID;
|
||||
}
|
||||
|
||||
cheat_error_t include_current_cheat( acl_entryid_t id )
|
||||
{
|
||||
if( setting.chtId == 0 ) return CCHT_NOT_INIT;
|
||||
|
||||
int index = id & 0xffff;
|
||||
if( index == 0 ) return CCHT_OK;
|
||||
else if( index < setting.entLen )
|
||||
{
|
||||
acl_index_t val = setting.entArr[index-1];
|
||||
if( val != 0 ) return CCHT_OK;
|
||||
else return CCHT_INVALID;
|
||||
}
|
||||
else return CCHT_INVALID;
|
||||
}
|
||||
|
||||
cheat_error_t fini_current_cheat()
|
||||
{
|
||||
if( setting.entArr ) free( setting.entArr );
|
||||
@ -67,7 +99,7 @@ cheat_error_t fini_current_cheat()
|
||||
}
|
||||
|
||||
typedef instruction_t* CodeLocation;
|
||||
#define CodeAtLocation(p) (*p)
|
||||
#define CodeAtLocation(p) (*(p))
|
||||
|
||||
// *******************************************
|
||||
// code for patch rom with cheat instruction
|
||||
@ -75,7 +107,6 @@ typedef instruction_t* CodeLocation;
|
||||
|
||||
#define GBACPU_PREFETCH 2
|
||||
#define GBACPU_PREFETCH_BYTE (sizeof(instruction_t)*GBACPU_PREFETCH)
|
||||
#define MAKE_ENT(hole,key) ((key<<16) | hole)
|
||||
|
||||
const instruction_t HOOKPOINT_INSTR[] = {
|
||||
0xe92d8000, // STMDB sp!, {pc}
|
||||
@ -116,7 +147,7 @@ const instruction_t KEY_ONOFF_INSTR[] = {
|
||||
0xe1df12b4, // ldrh r1, [pc, #36] ; 0x34
|
||||
0xe1df22b2, // ldrh r2, [pc, #34] ; 0x36
|
||||
0xe0000002, // and r0, r0, r2
|
||||
0xe59f2010, // ldr r2, [pc, #16] ; 0x2c
|
||||
0xe59f201c, // ldr r2, [pc, #28] ; 0x38
|
||||
0xe5d23000, // ldrb r3, [r2]
|
||||
0xe1500001, // cmp r0, r1
|
||||
0x02233001, // eoreq r3, r3, #1 ; 0x1
|
||||
@ -177,16 +208,16 @@ static int end_of_rom( CodeLocation addr, u32 size )
|
||||
return sizeof(instruction_t) * (prom + 2 - addr); // consider the first 0x00000000/0xffffffff as in-using
|
||||
}
|
||||
|
||||
#define MASK_PC0( m ) (pc[0]&mask)
|
||||
#define MASK_PC1( m ) (pc[1]&mask)
|
||||
#define MASK_PC2( m ) (pc[2]&mask)
|
||||
#define MASK_PC3( m ) (pc[3]&mask)
|
||||
#define MASK_PC4( m ) (pc[4]&mask)
|
||||
#define MASK_PC5( m ) (pc[5]&mask)
|
||||
#define MASK_PC6( m ) (pc[6]&mask)
|
||||
#define MASK_PC7( m ) (pc[7]&mask)
|
||||
#define MASK_PC8( m ) (pc[8]&mask)
|
||||
#define MASK_PC9( m ) (pc[9]&mask)
|
||||
#define MASK_PC0( m ) (pc[0]&m)
|
||||
#define MASK_PC1( m ) (pc[1]&m)
|
||||
#define MASK_PC2( m ) (pc[2]&m)
|
||||
#define MASK_PC3( m ) (pc[3]&m)
|
||||
#define MASK_PC4( m ) (pc[4]&m)
|
||||
#define MASK_PC5( m ) (pc[5]&m)
|
||||
#define MASK_PC6( m ) (pc[6]&m)
|
||||
#define MASK_PC7( m ) (pc[7]&m)
|
||||
#define MASK_PC8( m ) (pc[8]&m)
|
||||
#define MASK_PC9( m ) (pc[9]&m)
|
||||
|
||||
static int rom_search_hookpoint( CodeLocation addr, int addrlen, CodeLocation hookpoint[MAX_HOOKPOINT] )
|
||||
{
|
||||
@ -270,7 +301,7 @@ static int cht_calc_needsize( int mode, int numirq )
|
||||
return total + 1;
|
||||
}
|
||||
|
||||
static CodeLocation rom_fit_newsize( CodeLocation *rom, int realend, int totalsize )
|
||||
static CodeLocation rom_fit_newsize( CodeLocation rom, int realend, int totalsize, u32 *newsize )
|
||||
{
|
||||
u32 size = realend + totalsize;
|
||||
if( size > SIZE_32M )
|
||||
@ -306,6 +337,7 @@ static CodeLocation rom_fit_newsize( CodeLocation *rom, int realend, int totalsi
|
||||
else if( nextPow2(size) != nextPow2(realend) )
|
||||
{
|
||||
// 似乎没什么要动的
|
||||
*newsize = size + 1; // reserve a word for padding
|
||||
return rom + realend / sizeof(instruction_t);
|
||||
}
|
||||
|
||||
@ -319,7 +351,7 @@ static void rom_patch_hookpoint( CodeLocation start, CodeLocation hookpoint[MAX_
|
||||
{
|
||||
CodeLocation hook_point = hookpoint[i];
|
||||
memcpy( hook_point, HOOKPOINT_INSTR, HP_INSTR_SIZE );
|
||||
CodeAtLocation(hook_point[HP_WRAPPER_ADDR]) = addr + IW_INSTR_SIZE * i;
|
||||
hook_point[HP_WRAPPER_ADDR] = addr + IW_INSTR_SIZE * i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,7 +393,7 @@ static void rom_append_cheatproc( int mode, CodeLocation start, u16 bindkey, u32
|
||||
if( val != 0 )
|
||||
{
|
||||
acl_elemlen_t len;
|
||||
acl_select_entry( MAKE_ENT(i, val), &len );
|
||||
acl_select_entry( MAKE_ENT(i+1, val), &len );
|
||||
for( int j=0; j < len; ++j )
|
||||
{
|
||||
acl_entry_get_armcode(j, start++);
|
||||
@ -371,7 +403,7 @@ static void rom_append_cheatproc( int mode, CodeLocation start, u16 bindkey, u32
|
||||
*start++ = 0;
|
||||
}
|
||||
|
||||
cheat_error_t apply_cheat( int mode, u32 szrom, u16 bindkey, u32 storagemem )
|
||||
cheat_error_t apply_cheat( int mode, u32 szrom, u16 bindkey, u32 storagemem, u32 *outsize )
|
||||
{
|
||||
// try ignore patch
|
||||
if( mode == CHEAT_MODE_DISABLED ) return CCHT_OK;
|
||||
@ -379,7 +411,7 @@ cheat_error_t apply_cheat( int mode, u32 szrom, u16 bindkey, u32 storagemem )
|
||||
if( ACHTLIB_SUCCESS != acl_select_cheat_set( setting.chtId ) )
|
||||
return CCHT_NO_CHEAT;
|
||||
|
||||
u32 romdata = (u32*)ROM_LOC;
|
||||
CodeLocation romdata = ROM_LOC;
|
||||
int realend = end_of_rom(romdata, szrom);
|
||||
|
||||
// find hook point
|
||||
@ -390,12 +422,12 @@ cheat_error_t apply_cheat( int mode, u32 szrom, u16 bindkey, u32 storagemem )
|
||||
|
||||
// find free space to put new code
|
||||
int total_size = cht_calc_needsize( mode, n_hookpoint );
|
||||
CodeLocation page = rom_fit_newsize( romdata, realend, total_size );
|
||||
CodeLocation page = rom_fit_newsize( romdata, realend, total_size, outsize );
|
||||
if( page == NULL ) return CCHT_NO_SPACE;
|
||||
|
||||
// patching the rom
|
||||
rom_append_newirq( page, hookpoint, n_hookpoint );
|
||||
rom_patch_hookpoint( page, hookpoint, n_hookpoint );
|
||||
rom_append_cheatproc( mode, page + n_hookpoint * IW_INSTR_LEN, bindkey, storagemem );
|
||||
rom_append_cheatproc( mode, page + n_hookpoint * IW_INSTR_LEN, GBA_KEYCODE(bindkey), storagemem );
|
||||
return CCHT_OK;
|
||||
}
|
@ -234,17 +234,13 @@ static atp_error_t disp_str( atp_callerdata_t data, atp_counter_t, atp_linecfg_t
|
||||
cfg->text = (atp_text_t)data;
|
||||
return ATP_SUCCESS;
|
||||
}
|
||||
#define DEBUG( str ) atp_show(1, disp_str, str)
|
||||
|
||||
static atp_error_t select_region( atp_callerdata_t *dat, atp_counter_t index, atp_itemcfg_t *config )
|
||||
static atp_error_t select_region( atp_callerdata_t, atp_counter_t index, atp_itemcfg_t *config )
|
||||
{
|
||||
typedef u8 trunk[256];
|
||||
static char text[16];
|
||||
trunk data = (trunk)dat;
|
||||
u32 id = *(u32*)&data[sizeof(trunk) - sizeof(u32)];
|
||||
u32 *list = (u32*)&data[0];
|
||||
|
||||
acl_region_t sreg;
|
||||
acl_chtid_t sid;
|
||||
acl_chtid_t sid, id;
|
||||
if( ACHTLIB_SUCCESS != acl_query_cheat_set(index, &sid, &sreg) )
|
||||
{
|
||||
config->text = "无效数据";
|
||||
@ -266,20 +262,19 @@ static atp_error_t select_region( atp_callerdata_t *dat, atp_counter_t index, at
|
||||
default: t = "其他语种"; break;
|
||||
}
|
||||
ee_sprintf(text, "%c-%s", 'A'+(char)index, t);
|
||||
u8 inlist = 0;
|
||||
for( int i=0; i+1 < sizeof(trunk)/sizeof(u32); ++i )
|
||||
{
|
||||
u32 t = list[i];
|
||||
if( t==0 ) break;
|
||||
if( t == sid ){
|
||||
inlist = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( CCHT_NOT_INIT == info_current_cheat( &id, NULL ) )
|
||||
id = 0;
|
||||
|
||||
config->text = text;
|
||||
config->value = index;
|
||||
config->extra_text = sid == id ? "已启用" : (inlist ? "未启用" : "未设置");
|
||||
config->extra_text_color = sid == id ? ATP_COLOR_GREEN : ATP_COLOR_LIGHT;
|
||||
|
||||
// show saved information
|
||||
if( sid == id )
|
||||
{
|
||||
config->extra_text = "已启用";
|
||||
config->extra_text_color = ATP_COLOR_GREEN;
|
||||
}
|
||||
return ATP_SUCCESS;
|
||||
}
|
||||
|
||||
@ -291,6 +286,15 @@ static atp_error_t select_holes( atp_callerdata_t, atp_counter_t index, atp_item
|
||||
cfg->text = text;
|
||||
else cfg->text = "无效数据";
|
||||
cfg->value = 1+index;
|
||||
|
||||
// show saved information
|
||||
acl_entryid_t id;
|
||||
if( CCHT_OK == get_current_cheat( index, &id ) && ENT_USING(id) )
|
||||
{
|
||||
cfg->extra_text = "开";
|
||||
cfg->extra_text_color = ATP_COLOR_GREEN;
|
||||
}
|
||||
|
||||
return ATP_SUCCESS;
|
||||
}
|
||||
|
||||
@ -299,6 +303,13 @@ static atp_error_t select_onoff( atp_callerdata_t data, atp_counter_t index, atp
|
||||
acl_entryid_t eid = (acl_entryid_t)data;
|
||||
cfg->text = index == 0 ? "不开启" : "开启";
|
||||
cfg->value = index << 16 | eid;
|
||||
|
||||
// show saved information
|
||||
if( CCHT_OK == include_current_cheat((acl_entryid_t)cfg->value) )
|
||||
{
|
||||
cfg->extra_text = "选中";
|
||||
cfg->extra_text_color = ATP_COLOR_GREEN;
|
||||
}
|
||||
return ATP_SUCCESS;
|
||||
}
|
||||
|
||||
@ -318,6 +329,12 @@ static atp_error_t select_keys( atp_callerdata_t data, atp_counter_t index, atp_
|
||||
}
|
||||
acl_entryid_t eid = (acl_entryid_t)data;
|
||||
cfg->value = index<<16 | eid;
|
||||
|
||||
if( CCHT_OK == include_current_cheat((acl_entryid_t)cfg->value) )
|
||||
{
|
||||
cfg->extra_text = "选中";
|
||||
cfg->extra_text_color = ATP_COLOR_GREEN;
|
||||
}
|
||||
return ATP_SUCCESS;
|
||||
}
|
||||
|
||||
@ -399,25 +416,27 @@ static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, a
|
||||
uint8_t status = DISP_REGION;
|
||||
atp_counter_t defi = 0;
|
||||
acl_entryid_t eid = 0;
|
||||
char cheat_cfg_file[9];
|
||||
strncpy(cheat_cfg_file, serial, 4);
|
||||
strcpy(cheat_cfg_file+4, ".cht");
|
||||
cheat_cfg_file[8] = '\0';
|
||||
|
||||
while( status != DISP_DONE )
|
||||
{
|
||||
if( status == DISP_REGION )
|
||||
{
|
||||
u8 all_cheat_ids[256];
|
||||
chtlst_current_cheat( cheat_cfg_file, all_cheat_ids );
|
||||
chtid_current_cheat( cheat_cfg_file, all_cheat_ids + sizeof(all_cheat_ids)-sizeof(u32) );
|
||||
res = atp_select("选择一个金手指配置", len, select_region, NULL, all_cheat_ids, defi, 0, &item );
|
||||
res = atp_select("选择一个金手指配置", len, select_region, NULL, NULL, defi, 0, &item );
|
||||
if( res == ATP_SUCCESS )
|
||||
{
|
||||
defi = item;
|
||||
acl_chtid_t sid;
|
||||
acl_chtid_t sid, ccid;
|
||||
acl_elemlen_t len, cclen;
|
||||
acl_query_cheat_set((acl_index_t)item, &sid, NULL );
|
||||
acl_select_cheat_set( sid );
|
||||
pop_current_cheat( cheat_cfg_file, sid );
|
||||
acl_select_entry(0, len);
|
||||
if( CCHT_OK == info_current_cheat(&ccid, &cclen) )
|
||||
{
|
||||
// SKIP the init process when id and len is the same
|
||||
if( ccid != sid || cclen != len )
|
||||
init_current_cheat( sid, len );
|
||||
}
|
||||
else init_current_cheat( sid, len );
|
||||
eid = 0;
|
||||
status = DISP_HOLES;
|
||||
}
|
||||
@ -430,7 +449,7 @@ static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, a
|
||||
else if( status == DISP_HOLES )
|
||||
{
|
||||
acl_select_entry(0, &cnt);
|
||||
res = atp_select("选择一个金手指项目", cnt, select_holes, NULL, NULL, eid > 0 ? (eid&0xff)-1 : 0, 0, &item);
|
||||
res = atp_select("选择一个金手指项目", cnt, select_holes, NULL, NULL, eid > 0 ? (eid&0xffff)-1 : 0, 0, &item);
|
||||
if( res == ATP_SUCCESS )
|
||||
{
|
||||
eid = (acl_entryid_t)item;
|
||||
@ -448,9 +467,7 @@ static atp_pageopt_t serve_on_key( atp_callerdata_t data, atp_counter_t index, a
|
||||
res = atp_select("选择此项目对应的设置", cnt==0 ? 2:cnt, cnt==0 ? select_onoff : select_keys, NULL, (atp_callerdata_t)eid, 0, 0, &item);
|
||||
if( res == ATP_SUCCESS )
|
||||
{
|
||||
char tmp[20];
|
||||
ee_sprintf(tmp, "sel %08lx", item);
|
||||
DEBUG(tmp);
|
||||
put_current_cheat( (acl_entryid_t)item );
|
||||
status = DISP_HOLES;
|
||||
}
|
||||
else if( res == ATP_NO_ACTION )
|
||||
|
@ -66,6 +66,7 @@
|
||||
#define SAVE_POLICY_SRAM 2
|
||||
#define SAVE_POLICY_POPUP 3
|
||||
#define SAVE_POLICY_SIZE 4
|
||||
#define CHEAT_INUSE_ADDR (0x3007FE0u)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -128,7 +129,7 @@ static OafConfig g_oafConfig =
|
||||
// [by-anod]
|
||||
, SAVE_POLICY_GBADB // savePolicy
|
||||
, 0 // cheatMode
|
||||
, KEY_L|KEY_R|KEY_DOWN|KEY_SELECT
|
||||
, KEY_L|KEY_R|KEY_DDOWN|KEY_SELECT
|
||||
};
|
||||
static KHandle g_frameReadyEvent = 0;
|
||||
|
||||
@ -389,6 +390,10 @@ static Result loadGbaRom(const char *const path, u32 *const romSizeOut)
|
||||
while((res = fRead(f, ptr, 0x100000u, &read)) == RES_OK && read == 0x100000u)
|
||||
ptr += 0x100000u;
|
||||
|
||||
if( g_oafConfig.cheatMode != CHEAT_MODE_DISABLED )
|
||||
{
|
||||
apply_cheat( g_oafConfig.cheatMode, fileSize, g_oafConfig.cheatKeys, CHEAT_INUSE_ADDR, &filesize );
|
||||
}
|
||||
*romSizeOut = fixRomPadding(fileSize);
|
||||
}
|
||||
else res = RES_ROM_TOO_BIG;
|
||||
|
Loading…
x
Reference in New Issue
Block a user