Create a breakpoint for reading from the EXP value's memory address.
[02038E7C]!
ldr r1,=2038E7Ch
ldr r0,[r1]
adds r0,r0,4h
str r0,[r1]
EXP += 4;
ldr r1,=2038E00h
lsl r2,r0,8
adds r1,r1,r2
ldr r0,[r1,7Ch]
adds r0,r0,4
str r0,[r1,7Ch]
It is however fairly ambitious if you are going in completely cold/new, though within reason for a learning hack (any programming teacher, or indeed any teacher of practical skills, worth their salt will tell you a project that the student is motivated to stick with is 10 times better than an something abstract and boring that they have to breathe down their neck to complete).Yeah, that's a bit of a problem I have. I tend to go immediately ambitious when trying out new things. I thought this was gonna be a simple task, boy how wrong I was. I am learning some interesting facts about the inner workings of the game. Who knows, maybe within an extended period of time I can even work out how the speed-based not-quite-turn-based battle system works.
I should probably include more screenshots in general. Here (https://cdn.discordapp.com/attachments/461384755079020584/768820148533854208/unknown.png) is a screenshot of no$gba and the two values I added breakpoints to, those being the value for EXP and Gold handed out at the end of battle respectively. I can see some things of interest but I don't know how to read them, or where I should be looking for or at.
What I wanna know is what each of the columns that are displayed on no$gba's top left part mean, respectively.
Locate what writes into the address, I mean, for lack of a better terminology. Maybe I'm misusing terms, I don't freaking know the proper terms for this. Where do I click? What do I click? Sometimes I click on the breakpoint'd addresses and they boot me to a random part of the code. All this jumping around really isn't helpful and is more of a nuisance than anything.
Hmm, considering I've been going rather off-topic and all over the place with this thread, I figure I should create a new thread focusing specifically on discussing Lufia: The Ruins of Lore stuff and my journey to try and understand things. I'm not sure if this sort of thing is frowned upon in here, so I'll just wait for some "okay" on this front.
What we want is a "memory breakpoint". Memory breakpoints stop the CPU when *any* code accesses a certain memory address to load or store data. To use this sort of breakpoint, no$gba requires a different syntax: "[02038E7C]?". If you just put 02038E7C, you'll set an execution breakpoint, the wrong kind.Ah, no wonder I was having so much trouble, I didn't know about the existence of two different types of breakpoints! Maybe it's documented within no$gba's intruction manual, but considering the sheer size of it, can you blame me for not finding it?
ldr r1,=2038E7Ch ;load address of variable into r1
ldr r0,[r1] ;load what's at address r1, put it into r0
ldr r1,=6001036 ;load address of map spot for new tile into r1
str r0,[r1] ;store value from r0 to address in r1
cmp r1,r2
beq 8123456h
subs r0,r1,r2
beq 8123456h
"I doubt anyone nowadays would see much use in either of those."
That you can not assume, both in general (if nothing else I still get asked for the occasional multiplayer patch if a flash cart is acting up and existing ones still get downloads) and going into the future (oh no android based emulator got bluetooth support for the link cable setup).
Alright, I'm back. I actually forgot to do the whole breakpoint thing with the JP meter. I need to ask something before do so, and I can't believe I haven't asked this earlier: What is the second address mean at the bottom right screen? (https://cdn.discordapp.com/attachments/769286995779780689/771367803067432970/unknown.png) What is that bottom right screen? I may need to revise the way I document things if it turns out I've been misinterpreting what it means.
mov r0,b
mov r1,c
bl pow
mov a,r0
push r4-r7,r14
... code for pow(r0, positive r1) and pow(r0, negative r1) ...
pop r4-r7,r15
push r4-r7,r14
mov r4,r8
mov r5,r9
mov r6,r10
push r4-r6
sub sp,sp,16
Fair point, I just came to that conclusion because expanding the ROM itself didn't cross my mind, mostly because I have no clue how I would do that. It's probably really simple to expand it to 16 MB, but in order to make any proper use of the new space, I'd need to do a bunch of things that are beyond my current level of knowledge. A daunting task, indeed. No idea what you mean by "trimming" a ROM. Wouldn't that require recompiling the ROM, thus necessitating a disassembly of the game?
EWRAM 0203D20C = Eldin's current JP (4 bytes)
----> 08001AC6 = Jumps here upon killing the last enemy (adds r0,r0,r4)
\-> 03007C00 = Allocated
----> 08001AD4 = Then jumps here from 08001AC6 (ldr r3,=Lxx_5F5E0FFh)
----> 08001B2A = Then jumps here from 08001AD4 (mov r8,r2)
ldr r1,=5F5E0FFh ;load address of variable into r1
ldr r0,[r1] ;load what's at address r1, put it into r0
ldr r1,=6001036 ;load address of map spot for new tile into r1
str r0,[r1] ;store value from r0 to address in r1
.open "lufia.gba",08000000h ; Open ROM, map to 0x08000000 as per typical memory mapping for GBA
.gba ; Put armips in GBA mode/THUMB mode
.org 08001AC6h ; Move insert point to this address
; add r0,r4 ; Add r4 to r0 (original instruction)
mov r0,20h ; Set value to always be 0x20, instead of adding r0 and r4 together
.close
08069D14 B500 push r14 ;10
08069D16 4B0D ldr r3,=3001974h ;9
08069D18 7818 ldrb r0,[r3] ;4
08069D1A 28FF cmp r0,0FFh ;2
08069D1C D013 beq 8069D46h ;8
08069D1E 480C ldr r0,=3001973h ;9
08069D20 7800 ldrb r0,[r0] ;8
08069D22 2801 cmp r0,1h ;2
08069D24 D10F bne 8069D46h ;8
08069D26 4A0B ldr r2,=30018BCh ;9
08069D28 490B ldr r1,=3001948h ;9
08069D2A 7818 ldrb r0,[r3] ;4
08069D2C 3801 sub r0,1h ;2
08069D2E 0100 lsl r0,r0,4h ;2
08069D30 6809 ldr r1,[r1] ;4
08069D32 1809 add r1,r1,r0 ;2
08069D34 60D1 str r1,[r2,0Ch] ;5
08069D36 4809 ldr r0,=3001AD8h ;9
08069D38 6001 str r1,[r0] ;14
08069D3A 7B88 ldrb r0,[r1,0Eh] ;4
08069D3C 7110 strb r0,[r2,4h] ;5
08069D3E 7BC8 ldrb r0,[r1,0Fh] ;4
08069D40 7150 strb r0,[r2,5h] ;5
08069D42 F001F973 bl 806B02Ch ;10
08069D46 BC01 pop r0 ;9
08069D48 4700 bx r0 ;8
08069D4A 0000
08069D4C 1974
08069D4E 0300
08069D50 1973
08069D52 0300
08069D54 18BC
08069D56 0300
08069D58 1948
08069D5A 0300
08069D5C 1AD8
08069D5E 0300
08069D14 B500 push r14 ;10
<-- add new code here
08069D16 4B0D ldr r3,=3001974h ;9
08069D16 ldr r3,=0x087E8228 ; ldr = 2 bytes
08069D18 mov r15,r3 ; mov = 2 bytes
08069D1A dh 0x8228 ; first part of constant loaded by ldr above = 2 bytes
08069D1C dh 0x087E ; final part of constant loaded by ldr above = 2 bytes
08069D14 B500 push r14 ;10
=== We're replacing this part:
=== 08069D16 4B0D ldr r3,=3001974h ;9
=== 08069D18 7818 ldrb r0,[r3] ;4
=== 08069D1A 28FF cmp r0,0FFh ;2
=== 08069D1C D013 beq 8069D46h ;8
===
08069D1E 480C ldr r0,=3001973h ;9
ldr r3,=0x03001974
ldrb r0,[r3]
cmp r0,0xFF
bne @@dontbeq
ldr r0,0x08069D46
mov r15,r0
@@dontbeq:
ldr r0,0x08069D1E
mov r15,r0
.pool
ldr r3,=0x03001974
ldrb r0,[r3]
; INSERTED CODE:
push r1
mov r1,0x02012345
strb r0,[r1]
pop r1
; END OF INSERTED CODE
cmp r0,0xFF
bne @@dontbeq
ldr r0,0x08069D46
mov r15,r0
@@dontbeq:
ldr r0,0x08069D1E
mov r15,r0
.pool
Most GBA code is Thumb, because ARM code essentially runs at 50% speed on the GBA. It can be run at full speed by copying it into WRAM and running from there, but you only have so much WRAM, so games typically only do this with performance critical code.
(stuff before)
bl MyFunction ; overwrites either a different bl or 2 instructions
(stuff after)
MyFunction:
ldr r3,=MyFunctionForReal
bx r3
.pool
(this is more or less what you wrote, but now not in the middle of other code)MyFunctionForReal:
push lr
(replicate the code you overwrote in the hacked function)
(do your stuff)
pop lr
bx lr
MyFunction:
push r4
ldr r4,=MyFunctionForReal
mov r12,r4
pop r4
bx r12
.pool
There is certainly cause to learn both and expect to see both in any given game but most times I have gone to either hardcode a cheat, trace down, tweak a game just slightly so, fiddle with vblanks, or maybe have some fun function I encounter it as ARM mode. Thumb is great for injecting things into a game though where you have limited space/execution time.
I am not sure what the GBA duplicates list is at these days but that might actually make an interesting study if we are going to head towards whole ROM set analysis (I still want to see the results of a DS analysis for what uses SDAT sound). If we can figure out a way to differentiate between housekeeping and big boy code that might also be nice but that might be easier said than done (idle loops and housekeeping might well be predominantly thumb).