Coding Questions and other Quandaries
#21
So I was looking at your code and was wondering if the part !!!_!!! is a typo?

Celia and enemies have infinite health:

F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 38000500 #Example unique string to look for ----------------------> !!!(shouldn’t this be: 907D0014 887D0020)!!!
D2000000 00000002 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
386000C8 907D0014 #ASM code (li r3, 0xC8; stw r3, 0x0014 (r29)
60000000 00000000 #End of ASM code
E0000000 80008000 #End if (final terminator)


Here's my take on the changing health address thing:

Only Celia should have infinite health:

28###### 00001000 #Control line activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000004 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
39600004 7FAB5838 #ASM code: li r11, 0x4; and r11, r29, r11
2C0B0004 41820000 #ASM code: cmpwi r11, 0x4; beq some_label
386000C8 907D0014 #ASM code: some_label: li r3, 0xC8; stw r3, 0x0014 (r29)
60000000 00000000 #End of ASM code
E0000000 80008000 #End if (final terminator)

Being that Celia’s health address ends with 0x4, possibly this could do the trick.

li r11, 0x4
and r11, r29, r11
cmpwi r11, 0x4
beq some_label
Some_label:
li r3, 0xC8
stw r3, 0x14 (r29)
Reply
#22
Yes you can run multiple F6 Codetypes. Just be sure each one has it own End-If.

No that wasn't a typo. I don't own the Celia game, so I was just supplying a random instruction in the unique string as an example.

(12-09-2021, 01:58 PM)Hackwiz Wrote: 28###### 00001000 #Control line activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000004 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
39600004 7FAB5838 #ASM code: li r11, 0x4; and r11, r29, r11
2C0B0004 41820000 #ASM code: cmpwi r11, 0x4; beq some_label
386000C8 907D0014 #ASM code: some_label: li r3, 0xC8; stw r3, 0x0014 (r29)
60000000 00000000 #End of ASM code
E0000000 80008000 #End if (final terminator)

Everything looks fine here as far as the F6 structure is concerned.

(12-09-2021, 01:58 PM)Hackwiz Wrote: Being that Celia’s health address ends with 0x4, possibly this could do the trick.

li r11, 0x4 
and r11, r29, r11
cmpwi r11, 0x4
beq some_label
Some_label:
li r3, 0xC8
stw r3, 0x14 (r29)

There's a better way to check if that address ends in 4 plus I see a mistake in your branching. Try this..

Code:
andi. r12, r29, 0x000F #This will AND with a value of 0x0000000F. All binary values in the final Hex digit are preserved. The dot in the instruction operand is required in the andi instruction because the Broadway CPU developers never made a version of the andi instruction without the dot. The dot isn't applicable to us in this situation but it's a free use of cmpwi rD, 0.

cmpwi r12, 4 #Check if Address ends in the digit 4.
bne- default_instruction #If not, it's not an address for Celia, don't execute

li r3, 0xC8 #Update Celia's health

default_instruction:
stw r3, 0x0014 (r29) #Store health to dynamic memory

r12 is usually more safe than r11 as an fyi. And be sure this string of "907D0014 887D0020" is truly unique in memory. Take a Memory dump of your game. Open up Dolphin's own Memory tab/window (NOT the Aldelaro memory engine), and choose the top option for dumping RAM. Go to where you Mem dumps are exported in your computer depending on your Dolphin config (this varies widely so there's no way I can know this). Open up the Mem/RAM Dump in a Hex editor (i.e. HxD). And do a search of that string in Hex Mode. If it only pops up once in the dump, you're good to go.
Reply
#23
(12-09-2021, 02:30 PM)Vega Wrote: Yes you can run multiple F6 Codetypes. Just be sure each one has it own End-If.

No that wasn't a typo. I don't own the Celia game, so I was just supplying a random instruction in the unique string as an example.

(12-09-2021, 01:58 PM)Hackwiz Wrote: 28###### 00001000 #Control line activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000004 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
39600004 7FAB5838 #ASM code: li r11, 0x4; and r11, r29, r11
2C0B0004 41820000 #ASM code: cmpwi r11, 0x4; beq some_label
386000C8 907D0014 #ASM code: some_label: li r3, 0xC8; stw r3, 0x0014 (r29)
60000000 00000000 #End of ASM code
E0000000 80008000 #End if (final terminator)

Everything looks fine here as far as the F6 structure is concerned.

(12-09-2021, 01:58 PM)Hackwiz Wrote: Being that Celia’s health address ends with 0x4, possibly this could do the trick.

li r11, 0x4 
and r11, r29, r11
cmpwi r11, 0x4
beq some_label
Some_label:
li r3, 0xC8
stw r3, 0x14 (r29)

There's a better way to check if that address ends in 4 plus I see a mistake in your branching. Try this..

Code:
andi. r12, r29, 0x000F #This will AND with a value of 0x0000000F. All binary values in the final Hex digit are preserved. The dot in the instruction operand is required in the andi instruction because the Broadway CPU developers never made a version of the andi instruction without the dot. The dot isn't applicable to us in this situation but it's a free use of cmpwi rD, 0.

cmpwi r12, 4 #Check if Address ends in the digit 4.
bne- default_instruction #If not, it's not an address for Celia, don't execute

li r3, 0xC8 #Update Celia's health

default_instruction:
stw r3, 0x0014 (r29) #Store health to dynamic memory

r12 is usually more safe than r11 as an fyi. And be sure this string of "907D0014 887D0020" is truly unique in memory. Take a Memory dump of your game. Open up Dolphin's own Memory tab/window (NOT the Aldelaro memory engine), and choose the top option for dumping RAM. Go to where you Mem dumps are exported in your computer depending on your Dolphin config (this varies widely so there's no way I can know this). Open up the Mem/RAM Dump in a Hex editor (i.e. HxD). And do a search of that string in Hex Mode. If it only pops up once in the dump, you're good to go.

Brilliant!!!!
I see the mistake I made with the branch.
I'll give it a try later.
Reply
#24
Ok, so this worked great. Booted up 5 times and it worked like a champ.
Waited to activate until I took control of Celia.

Celia and enemies have infinite health:

285F036A 00001000 #Button activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000002 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
386000C8 907D0014 #ASM code (li r3, 0xC8; stw r3, 0x0014 (r29)
60000000 00000000 #End of ASM code
E0000000 80008000 #End if (final terminator)

This didn't work:

Only Celia should have infinite health:

285F036A 00001000 #Control line activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000004 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
39800004 73AC000F #ASM code: li r12, 0x4; andI. r12, r29, 0X000F
2C0C0004 40820008 #ASM code: cmpwi r12, 0x4; Bne- default_instruction
386000C8 907D0014 #ASM code: li r3, 0xC8; default_instruction: stw r3, 0x0014 (r29)
60000000 00000000 #End of ASM code
E0000000 80008000 #End if (final terminator)

So I did a bp on her health, and was looking at r29.
It dawned on me we hadn't taken into account the 0x0014, so I changed the compare value to 0x0.
And it worked Smile Smile Smile

However, I found that when I got into an area where multiple enemies spawned I could only kill 3 out of the
four, because apparently enemies addresses can end with 0x0 also.

Any other tricks up your sleeve???
Reply
#25
Your are right about forgetting the 0x0014, I missed that too, lul. Considering enemy addresses can end in 0x0 (like Celia's), that will be an issue. You will need to find another way to determine a discrepancy between Celia vs Enemies. Whatever happen to that Link Register thing you mentioned about before?

--

Oh by the way, that IABR concept related source will work. I made a mockup of it for an MKWii code. I didn't include was the address save in the EVA of the C0 code and the address checks in the IABR routine (address in EVA vs IABR), since I didn't need those parts in the source as MKWii doesn't have the relocatable elf issues.

Anyway for those who stumble upon this thread, here's a region free Shared Item Code (Item: Star) using C0 codetype and the Instruction Address Breakpoint Register. I doubt this will work on Dolphin, runs perfect on real hardware.

C0000000 00000008
3C60807A 38007FFF
7C0903A6 3CA0D877
60A512ED 81630000
85830004 7D606278
7C050000 4182000C
4200FFEC 4E800020
60630003 7C72FBA6
4E800020 00000000
06001300 0000001C
38600009 56EC007E
906C0020 7D9A02A6
398C0004 7D9A03A6
4C000064 00000000

C0 Code source:
Code:
#IABR compiler statement
.set IABR, 1010

#Set First Loop Load Address
lis r3, 0x807A

#Search will be from 0x807A0000 thru 0x807C0000
#Set amount of times to search (0x20000 bytes / 4 = 0x8000 words); so we'll set the amount to 0x7FFF to scrap the one search so we can save one insruction on the source, lul
li r0, 0x7FFF
mtctr r0

#Set the crude checksum
#480012CD (before default instruction) XOR'd with 90770020 (default insruction) = D87712ED
lis r5, 0xD877
ori r5, r5, 0x12ED

#Loop
loop:

#Load double word at r3, and then increment r3 by 4
lwz r11, 0 (r3)
lwzu r12, 0x4 (r3)

#Xor double word together; compare XOR checksums
xor r0, r11, r12
cmpw r5, r0
beq- found

#not yet found, keep trying
bdnz+ loop
blr #If no find, end C0. Do NOT update EVA nor IABR

#Found it!
found:
#Flip bits of 30 and 31 high, this is needed for IABR (BE and TE)
ori r3, r3, 0x0003
mtspr IABR, r3 #Broadway says we need a context-synchronizing instruction after this but considering there's a huge amount of time from when this instruction executes to when the IABR is taken, its not needed
#blr #End C0; uncomment if NOT using pyiiasmh and then adjust compiled code so it can be a proper C0

06 String Write Source (overwrite IABR exception call)
Code:
li r3, 9 #Set the shared item
clrlwi r12, r23, 1 #Change r23's address to physical
stw r3, 0x0020 (r12) #Update new item
mfsrr0 r12 #Grab address that IABR triggered on
addi r12, r12, 4 #We must increment to return back to shared item adress+4. Or else the IABR will be triggered again and we will be in a infinite loop
mtsrr0 r12 #Update new srr0 (address to go to when exception is over)
rfi #END EXCEPTION!
Reply
#26
Only using Celia’s health address ending in 0x4 as a check. (Buggy) Some enemies also end in 0x4.

285F036A 00001000 #Control line activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000004 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
39800004 73AC000F #ASM code: li r12, 0x0; andI. r12, r29, 0X000F
2C0C0004 40820008 #ASM code: cmpwi r12, 0x0; Bne- default_instruction
386000C8 907D0014 #ASM code: li r3, 0xC8; default_instruction: stw r3, 0x0014 (r29)
60000000 00000000 #End of ASM code
E0000000 80008000 #End if (final terminator)

I went in and checked out the health values of the three different enemies I've encountered so far, and found that none of them
shared the same value for health (0xC8), as Celia.

So:

Only using Celia’s health value (0xC8) as a check. (Buggy maybe?)

285F036A 00001000 #Control line activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000003 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
819D0014 2C0C00C8 #ASM code: lwz r12, 0x0014 (r29); cmpwi r12, 0x00c8
40820008 386000C8 #ASM code: Bne- default_instruction; li r3, 0x00c8
907D0014 00000000 #ASM code: default_instruction: stw r3, 0x0014 (r29)
E0000000 80008000 #End if (final terminator)


Or, use both the address check and health value check for redundancy:


Using both Celia’s health address ending in 0x4 and health value 0xc8 as a check

285F036A 00001000 #Control line activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000005 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
819d0014 2c0c00c8 #ASM code: lwz r12, 0x0014 (r29); cmpwi r12, 0x00c8
41820004 39800000 #ASM Beq celia_health; celia_health: li r12, 0x0
73AC000F 2C0C0000 #ASM code: andi. r12, r29, 0XF; cmpwi r12, 0x0
40820008 386000C8 #ASM code: Bne- default_instruction; li r3, 0xc8
907D0014 00000000 #ASM default_instruction: stw r3, 0x0014 (r29)
E0000000 80008000 #End if (final terminator)

I'm interested in how you would have written the branch commands.

In regards to adding the shortcut + or - to the branch command, what made you determine to use the Bne- as apposed to Bne or Bne+?
Will it work regardless of whether you add the + or -?

Also, can you use multiple "branch_label" for one "branch_label:"?

In other words, simplified:

bne some_label
ASM code
beq some_label
ASM code
ble some_lable
ASM code
some_label:
ASM code


No, I did not pursue the Link Register thing.
I briefly read up on the IABR thing. But:

Too many hands on my time ~ Rush

Thanks for all your help!!!
Reply
#27
In regards to your Assembly writes within your F6 Codes, I see a few problems. Here's the ASM source of your 3rd F6 code, I placed a comment next to any mistakes I found.

Code:
lwz r12, 0x0014 (r29)
cmpwi r12, 0xC8
beq- celia_health #You are branching literally to the next instruction, this is a useless branch

celia_health:
li r12, 0 #r12's value is going to be overwritten by the andi. instruction. So this li instruction has zero effect
andi. r12, r29, 0xF
cmpwi r12, 0
bne- default_instruction
li r3, 0xC8

default_instruction:
stw r3, 0x0014 (r29)

Here's a better way~

Code:
#First check the last digit of the Health Address
addi r12, r29, 0x0014 #increment r29's mem address by value of 0x0014
andi. r12, r12, 0xF
cmpwi r12, 0x4
bne- default_instruction

#Check if Health Value 0xC8 is initially present
lwz r12, 0x0014 (r29)
cmpwi r12, 0xC8
bne- default_instruction

#Keep Celia's health at 0xC8
mr r3, r12

#Default Instruction, update the Health
default_instruction:
stw r3, 0x0014 (r29)

Use that in your F6 code and see if it works. If not, try the F6 Code with using the following ASM source instead just in case....

Code:
addi r12, r29, 0x0014 #increment r29's mem address by value of 0x0014
andi. r12, r12, 0xF
cmpwi r12, 0x4
bne- default_instruction
li r3, 0xC8
default_instruction:
stw r3, 0x0014 (r29)

The + and - symbols are conditional branch hints. They give Broadway a hint of what the higher probability outcome of the conditional branch is. We're talking about saving nanoseconds here. It's pretty much useless for Wii Codes, I just do it out of habit and imo it makes the Assembly look much more clean.

+ = The branch is most likely to be taken
- = The branch is less likely to be taken

If no hint is supplied, the ASM compiler will default to - when compiling your Code
If you are unsure about the probabilities, use a -

Putting incorrect branch hints won't botch a code, but it will slow down the execution of said code by a super super small amount of time (measurement in nanoseconds lol). And, yes you can have multiple branches land/jump at the same spot/destination.

In regards to how I write out the branch commands:
Branches are basic jumps, that's it. Don't overthink it at all. A simple jump to your label name. There should never be any type of branch that jumps down to the very next instruction below. You could handwrite your ASM on a piece of paper and draw arrows of the branch jumps to help you out more visually.

Don't worry about the IABR thing, I'm just glad we have that as a backup and I personally just wanted to see if that nifty trick would even work.

You seem close to solving this. All that is needed is finding a reliable discrepancy.
Reply
#28
285F036A 00001000 #Control line activator. Press (-)
F6000001 80E080FF #Example unique string takes up 1 row/line. Search from 0x80E00000 thru 0x80FF0000
907D0014 887D0020 #Example unique string to look for
D2000000 00000005 #Insert ASM at pointer (zero offset); D2 = Codetype for Pointer ASM
399D0014 718C000F #ASM addi r12, r29, 0x14; andi. r12, r12, 0xF
2C0C0004 40820014 #ASM cmpwi r12, 0x4; bne- default_instruction
819D0014 2C0C00C8 # lwz r12, 0x0014 (r29); cmpwi r12, 0xC8
40820008 7D836378 #ASM bne- default_instruction; mr r3, r12
907D0014 00000000 #ASM default_instruction: stw r3, 0x0014 (r29)
E0000000 80008000 #End if (final terminator)

I haven't met an enemy I couldn't defeat yet. Have went way further into the game than ever.

At first I thought it wasn't working with continues, but with the first continue I chose, Celia's health was less than 0xC8.
You could barely tell by the gauge on the screen. So of course, it didn't work.
Started the same continue, but killed her off for the respawn/health refill.
Activated and it worked just fine.

Going to keep jamming on it to see if there are any more bugs.

Thanks for teaching me how to do this!!!!
Reply
#29
Do the register safety rules pertain to the Game Cube also?
Reply
#30
Yeah, pretty much everything on the PPC side is the same between GC and Wii
Reply


Forum Jump:


Users browsing this thread: 49 Guest(s)