add example of toggle code

This commit is contained in:
sup39 2022-11-10 21:01:47 +09:00
parent 1c3935d040
commit 4e73bcf5c9
11 changed files with 187 additions and 4 deletions

View file

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

@ -0,0 +1,5 @@
*.o
*.out
*.bin
*.gci
*.map

31
example/Makefile Normal file
View 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
View 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
View 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
View 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
View 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
View file

@ -0,0 +1,3 @@
int f(int x) {
return x*x;
}

28
example/make-gci.py Normal file
View 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
View 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
View 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;