Codestype explanation

Started by Bully@Wiiplaza, August 04, 2011, 06:24:44 PM

Previous topic - Next topic

dcx2

Yeah, they're functionally equivalent.

---

So I was looking at the source code for the C6 code in the code handler.  And I saw this interesting line.

   rlwimi   r5,r3,0,31,31      #restore lr bit

r3 has the first code word.  So if the LSB of the first code word is set, the branch created will be a bl instead of a b.

So I believe C6012344 800018A8 will create a b 0x800018A8, while C6012345 800018A8 will create a bl 0x800018A8.

We might want to update http://www.geckocodes.org/index.php?arsenal=1#C6 to note this.

Unfortunately, the C2 code type does not have such a feature.

---

Another important detail about sending codes.   The 00000000 at the end is where the back-branch will go.  The back-branch is only written when the C2/D2/F2 code is actually executed.

This means that if you send a code more than once, without undo, and your hook was run conditionally (either an F2 code, or a C2 after an if), then executing codes after sending them will not cause the back-branch to be written, and therefore a dangling hook can still cause the code to executed with the 00000000, causing a crash.

Stuff

Gecko Register / Direct Value Operations. And the other one too. Is XXXXXXXX signed or is it impossible to -1?
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

Technically it doesn't matter if X is signed or not because it's a whole word.  There is no "extsw" instruction because a 32-bit word is already full-size so there's nothing to extend.  Therefore, if you add 0xFFFFFFFF to an unsigned number, it still goes down by 1.  The overflow bit would be lost.

This gets trickier with 16- and 8-bit adds, on account of sign extension.  (extsh and extsb instructions, which copy the sign bit over all of the bits to the left, thus making 0x7F into 0x0000007F, and 0x80 into 0xFFFFFF80).

Stuff

ah. Well for now it was for 32-bits. I did FFFFFFFF and it minused. I was making a C2 change the addi amount by +/-1 on the fly. It works. So I'll know I can do that later...I'll have to find something 16/8-bit to -1 so I can see what your saying. I think the player hp would work.

So with the C6, that's just used if you want it to branch to some other asm? I was trying to think of how it could be useful...but C2 kind of just works.

And what about C0. I don't understand that one at all.

"Executes the NNNNNNNN lines of instruction placed under the code.
The instructions MUST end with a blr (0x4E800020)"

But what's gonna be in the LR? From the description, I'm assuming that the asm runs every time the code handler executes, like every other codetype. But then if it must end with a blr, then that's probably not the case.
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

#19
extsh and extsb are only for ASM.  If you're doing Gecko Register ops you should just use 16-bit and 8-bit loads.  Although a 16-bit Gecko Reg load isn't going to sign-extend.  You could fake it by left-shifting (T=5) 16 bits and then arithmetic-shift-right (T=8) by 16 bits.  8-bit loads would need a 24-bit left-shift followed by a 24-bit arithmetic-shift-right.  Once sign-extended you still use 0xFFFFFFFF = -1.  Sign extension isn't necessary if you know your value will never be negative.  Sign extension is bad if the original 8- or 16-bit value was supposed to be unsigned!

---

C6 can be used to create branches from one address to another.  It is one-line.

C2 is used to create branches to and from a patch of ASM that lives in the code handler.  It is multi-line.

The reason you need a code type to create branches is that a relative branch requires you to know the address of the branch instruction and how many bytes away the destination is (i.e. how far away it is relative to the branch instruction).  This isn't so useful for the ba on account of being able to calculate the branch ahead of time, but it's extremely useful for the po.

Assume you F6 to find some code and you just want to turn one instruction into a branch.  You don't know where your branch will be, but you know the destination; this means you can't calculate the branch offset without copying the po into a Gecko Reg and doing some Gecko ops on it.

EDIT: here's an example code that used an F6 and a D6 to add the OSSleepThread hook, courtesy of Y.S.

OSSleepThread hook
F6000002 80008180
90A402E0 806502E4
908502E4 2C030000
D600005C 800018A8
E0000000 80008000

This is especially important because you can't use a branch in a C2 code, because the address of the branch inside the C2 is determined by the order codes were sent in (AND what version of the code handler you're using!), so again you don't know enough information to calculate the branch offset.

---

When the code handler executes a C2 code, all it does is write some branches.  The code handler does not execute the ASM inside the C2.  Later on, the game actually executes the ASM inside the C2.

C0 codes run in the context of the code handler.  So when the code handler runs, the ASM inside the C0 runs.  When the code handler "calls" a C0 code, it places the next instruction of the code handler into the LR.  This means a C0 code needs to end with a blr so that execution returns to the code handler after the ASM is done.  This allows the code handler to continue reading the code list and executing codes.

Stuff

So I did a XBP on this:
C0000000 00000001
4E800020 00000000

From there, I can see that r3 is safe. The next thing that happens is lwz r3,0(r15) and no conditional branches. But that's about it. I'll assume r12 is safe.. r9 looks safe too. andi. r9,r8,1 is the first time it gets used after the C0. Is there any more that would be definitely safe? Since it's probably always predictable, I wanted to know if there were some exceptions with C0, but that doesn't seem to be the case. It's probably always the same, so it'd be nice to know that there's a set of registers that don't need restoring. r10, r5, and r11 also look nice. This is the first time they're used after C0:

80001FB8:  546A1F7E   rlwinm   r10,r3,3,29,31
80001FBC:  54653F7E   rlwinm   r5,r3,7,29,31
80001FC0:  746B1000   andis.    r11,r3,4096

So from this I can say r3, r5, r9, r10, r11, and r12 are safe to use in C0 codes without having to restore them. That's a lot of flex. but is there more...:p. I was too scared to go further. Conditional branches that I wasn't gonna try to understand yet comes next.
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2


Stuff

Interesting. I don't really want to stack frame anything since that would be 2 extra lines of code, so I'll just start with r12 and work my way down, skipping those reserved registers. I haven't needed more than 3 registers so far, so I'll hope with future codehandlers, if there are future ones, nothing changes with r12-r9. After reading "On the safety of registers" a few times, I can see why r0 would be considered safe in this situation. I didn't see it being used yet, so I considered it to be unknown.

I was thinking about messing with C0 in a real code, but C2 is superior for most ideas. For example, if monster id wasn't constantly being read, C0 would've almost been an option, but then I have no way to make it work for all monsters with out unnecessary effort.
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

#23
C0 codes are for when normal WiiRD code types would take too much effort to use.  For instance, in this thread, I posted two ways to do a "Gecko Register Slider".  http://wiird.l0nk.org/forum/index.php/topic,8671.msg72146.html#msg72146  And then I posted a C0 conversion, which is one line shorter.  http://wiird.l0nk.org/forum/index.php/topic,8671.msg72154.html#msg72154

C2 codes have the benefit of access to game pointers.

And the code handler does not strictly follow the PowerPC EABI, so most of "On the Safety of Registers" does not apply to the code handler.

One very useful feature of the C0 is that you have access to the po via r16, the Gecko Registers and the Blocks via r7, and the address of the current code line via r15 ("current code line" in this case should be a pointer to the C0000000 00000001)

Stuff

#24
Here's a stupid question. Wasn't there a way to store the next code's address in a gecko register or block? Not jump to it. Just store it. Don't want to change the pointer in the process.60 doesn't need a terminator, right? I'll just work with that. But I do wish it would do next code's address +XXXX. :/

And a much better question. If I do that/\, followed by a C2 code, can I expect that grN/bP to be that when my asm executes, even if there's a line that modifies that grN/bP in the next or previous code.

load into gr3
C2
lwz r12, d(r12) ##EA == gr3
load into gr3

Has the grN and bP location ever moved in previous code handlers?
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm

dcx2

#25
Try 4E/4C.  Use 80001808 with 4C to write the pointer to gr0.

C2 codes execute in the context of the game, not the code handler.  Anything you write to a gr will probably still be there, although you should double-check to make sure it's a legit pointer first. (EDIT: The last code in the code list which writes to a gr will "win" when the C2 tries to read the gr)  The code handler usually runs first, but when sending codes that might not be true.

Old versions of the code handler used 8000180C as gr0 instead of 80001808.

Stuff

#26
:/ that almost sucks that grNs were different in older code handlers. I used 60. It works just fine. I was trying to avoid using using a terminator. And it worked out. I needed 1 more instruction to not have to end with a nop. And that 1 instruction was addi rA, rA, 0x10.  ;D

----
Wow. I could've just bl->mflr for the same result. It's already safe to modify the link register and the code started with a branch.
.make Stuff happen.
Dropbox. If you don't have one, get it NOW! +250MB free if you follow my link :p.

Mod code Generator ~50% complete but very usable:
http://dl.dropbox.com/u/24514984/modcodes/modcodes.htm