add example of toggle code
This commit is contained in:
parent
1c3935d040
commit
4e73bcf5c9
11 changed files with 187 additions and 4 deletions
|
@ -42,15 +42,15 @@ int onReadOptionBlock(TCardManager *this, CARDFileInfo *fileInfo) {
|
|||
if ((rc = CARDRead(fileInfo, dst, size, 0))) {
|
||||
// should not fail if (dst, size) is properly set
|
||||
} else {
|
||||
// everything is good
|
||||
// TODO apply gecko code
|
||||
*(char*)0x817effff = 1; // ready (temporary solution)
|
||||
// everything is good => apply gecko code
|
||||
// TODO entry
|
||||
((void(*)())0x817f0000)();
|
||||
}
|
||||
|
||||
// close file
|
||||
CARDClose(fileInfo);
|
||||
|
||||
orig:
|
||||
// original function call
|
||||
// original function call
|
||||
return open_(this, fileInfo);
|
||||
}
|
||||
|
|
5
example/.gitignore
vendored
Normal file
5
example/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
*.o
|
||||
*.out
|
||||
*.bin
|
||||
*.gci
|
||||
*.map
|
31
example/Makefile
Normal file
31
example/Makefile
Normal file
|
@ -0,0 +1,31 @@
|
|||
CC = powerpc-eabi-gcc
|
||||
AS = powerpc-eabi-as
|
||||
LD = powerpc-eabi-ld
|
||||
OBJCOPY = powerpc-eabi-objcopy
|
||||
CFLAGS = -Os -I. -Wa,-mregnames,-mgekko -Wall -fno-asynchronous-unwind-tables -fno-unwind-tables
|
||||
ASFLAGS = -mregnames -mgekko
|
||||
PYTHON = python3
|
||||
|
||||
OBJS = _start.o gameLoop.o qfsync.o
|
||||
LDFILE = sms.ld
|
||||
MAPOUT = gci.map
|
||||
|
||||
GCI = 01-GMSJ-gct.gci
|
||||
OBJOUT = a.out
|
||||
OBJBIN = a.bin
|
||||
blockCount = 7
|
||||
|
||||
all: $(GCI)
|
||||
|
||||
$(GCI): $(OBJBIN)
|
||||
$(PYTHON) make-gci.py $(blockCount) $< $@
|
||||
|
||||
$(OBJOUT): $(OBJS) | $(LDFILE)
|
||||
$(LD) -o $@ -T $(LDFILE) -Map $(MAPOUT) $^
|
||||
$(OBJBIN): $(OBJOUT)
|
||||
$(OBJCOPY) -O binary $^ $@
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *.gci*.out *.bin *.o *.map
|
8
example/QFSync.s
Normal file
8
example/QFSync.s
Normal file
|
@ -0,0 +1,8 @@
|
|||
.globl _getQFSync
|
||||
_getQFSync:
|
||||
lis r12, 0x8180
|
||||
lwz r12, -0x4000(r12)
|
||||
rlwinm. r12, r12, 2, 0x3
|
||||
li r3, 600
|
||||
slw r3, r3, r12
|
||||
blr
|
38
example/_start.s
Normal file
38
example/_start.s
Normal file
|
@ -0,0 +1,38 @@
|
|||
.include "./macros.s"
|
||||
|
||||
.macro .rwbl src dst
|
||||
li32 r3, \src
|
||||
li32 r4, \dst
|
||||
bl replace_with_bl
|
||||
.endm
|
||||
|
||||
.globl _start
|
||||
_start: # right after gci loaded into RAM
|
||||
mflr r11 # need to make sure r11 is not destroyed
|
||||
|
||||
## replace original instruction @src with `bl dst`
|
||||
## TODO version
|
||||
.rwbl 0x800f9a10, _gameLoop
|
||||
.rwbl 0x800ecde0, _getQFSync
|
||||
|
||||
## return
|
||||
mtlr r11
|
||||
blr
|
||||
|
||||
/**
|
||||
* r3 = address of original code
|
||||
* r4 = address of practice code function
|
||||
*/
|
||||
replace_with_bl:
|
||||
## bl from r3 to r4
|
||||
sub r4, r4, r3
|
||||
rlwinm r4, r4, 0, 6, 29
|
||||
oris r4, r4, 0x4800
|
||||
ori r4, r4, 0x1
|
||||
stw r4, 0(r3)
|
||||
## invalidate cache
|
||||
dcbst 0, r3
|
||||
sync
|
||||
icbi 0, r3
|
||||
isync
|
||||
blr
|
18
example/gameLoop.c
Normal file
18
example/gameLoop.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <sms.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t qfsync : 2;
|
||||
} CodeConfig;
|
||||
extern CodeConfig config;
|
||||
|
||||
void _gameLoop(void *gamePad) {
|
||||
// original function
|
||||
TMarioGamePad_read(gamePad);
|
||||
|
||||
// check the controller input
|
||||
uint16_t btn = JUTGamePad_mPadStatus.button;
|
||||
config.qfsync =
|
||||
btn == (PRESS_B | PRESS_DL) ? 2 : // 4x
|
||||
btn == (PRESS_B | PRESS_DR) ? 3 : // 8x
|
||||
0; // 1x
|
||||
}
|
4
example/macros.s
Normal file
4
example/macros.s
Normal file
|
@ -0,0 +1,4 @@
|
|||
.macro li32 reg val
|
||||
lis \reg, \val@h
|
||||
ori \reg, \reg, \val@l
|
||||
.endm
|
3
example/main.c
Normal file
3
example/main.c
Normal file
|
@ -0,0 +1,3 @@
|
|||
int f(int x) {
|
||||
return x*x;
|
||||
}
|
28
example/make-gci.py
Normal file
28
example/make-gci.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
import sys
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
print('Usage: %s {block-count} {content.bin} {out.gci}'%sys.argv[0], file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
blockCount = int(sys.argv[1])
|
||||
contentPath = sys.argv[2]
|
||||
outPath = sys.argv[3]
|
||||
|
||||
gameId = b'GMSJ01\xff\x00' # TODO other version
|
||||
fileName = b'gct'
|
||||
|
||||
pad = lambda buf, size: buf+b'\x00'*(size-len(buf))
|
||||
with open(contentPath, 'rb') as fr, open(outPath, 'wb') as fw:
|
||||
content = fr.read()
|
||||
bodySize = 0x2000*blockCount
|
||||
assert len(content)<=bodySize, f'{contentPath} is too big: expect at most {bodySize} bytes, got {len(content)}'
|
||||
fw.write(b''.join((
|
||||
# header
|
||||
gameId,
|
||||
pad(fileName, 0x20),
|
||||
b'\x00'*16,
|
||||
blockCount.to_bytes(2, 'big'),
|
||||
b'\xff'*6,
|
||||
# body
|
||||
pad(content, bodySize),
|
||||
)))
|
34
example/sms.h
Normal file
34
example/sms.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef SMS_H
|
||||
#define SMS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void TMarioGamePad_read(void*);
|
||||
|
||||
typedef struct {
|
||||
uint16_t button;
|
||||
int8_t stickX;
|
||||
int8_t stickY;
|
||||
int8_t substickX;
|
||||
int8_t substickY;
|
||||
uint8_t triggerLeft;
|
||||
uint8_t triggerRight;
|
||||
uint8_t analogA;
|
||||
uint8_t analogB;
|
||||
int8_t err;
|
||||
} PADStatus;
|
||||
extern PADStatus JUTGamePad_mPadStatus;
|
||||
#define PRESS_START 0x1000
|
||||
#define PRESS_Y 0x0800
|
||||
#define PRESS_X 0x0400
|
||||
#define PRESS_B 0x0200
|
||||
#define PRESS_A 0x0100
|
||||
#define PRESS_L 0x0040
|
||||
#define PRESS_R 0x0020
|
||||
#define PRESS_Z 0x0010
|
||||
#define PRESS_DU 0x0008
|
||||
#define PRESS_DD 0x0004
|
||||
#define PRESS_DR 0x0002
|
||||
#define PRESS_DL 0x0001
|
||||
|
||||
#endif
|
14
example/sms.ld
Normal file
14
example/sms.ld
Normal file
|
@ -0,0 +1,14 @@
|
|||
SECTIONS {
|
||||
. = 0x817F0000;
|
||||
.init : { _start.o }
|
||||
.text : { *(.text) }
|
||||
.rodata : { *(.rodata) }
|
||||
.data : { *(.data) }
|
||||
.bss : { *(.bss) }
|
||||
}
|
||||
|
||||
/** TODO version */
|
||||
TMarioGamePad_read = 0x800fba58;
|
||||
JUTGamePad_mPadStatus = 0x80400d50;
|
||||
|
||||
config = 0x817fc000;
|
Loading…
Reference in a new issue