ASM explanations...

Started by Stuff, August 24, 2011, 02:19:59 AM

Previous topic - Next topic

Stuff

This one goes back to masks in the if codetypes. I want to add a mask to button activators, but in asm. I think this is the way to do it:

lis r12,0x8066
lhz r12, 0xffff93DC(r12)
andi. r12, r12, 0x800
cmplwi r12, 0x800

not(MMMM) = XXXX normally and I think this is what ifs do. That they AND the stuff from the address and then compare it to your button digits. Which would be XXXX if at least that's being pressed. But maybe I think this works because I used such a simple number as an example(0b100000000000).

This isn't very efficient considering if codetypes can handle this with 1 line, but I'm seeing these not needing a terminator and by adding this to a C2 code, I can make it run the original instructions or my instruction depending on if the button is pressed.

I was gonna say something about CR0, but I do a cmplwi right after andi.. Safe to assume it's safe? I have seen cmp's followed by a few instructions before branching.
.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

Bully@Wiiplaza

#46
Quote from: Stuff on September 30, 2011, 07:36:10 AM
lis r12,0x8066
lhz r12, 0xffff93DC(r12) # lhz only loads a 16bit value (93DC). Is the ffff part needed/accepted by the assembler program?
andi. r12, r12, 0x800 # doesn´t andi. replace a cmpwi?
cmplwi r12, 0x800 # why do we need two compare instructions? :confused:
beq- or bne- now?
and what´s the difference in usage of a cmpwi and cmplwi?
As far as I know, andi. is for masked buttons and cmpwi for non-masked ones.
Btw. button activators in asm can e.g. be used as rollers or just to pack everything into a C2 without multiple "code parts".
And it´s always shorter than using a 28 codestype + C2 + End if + Default line + Terminator.
Execution will then be decided inside the C2 :P
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

Quote from: Stuff on September 30, 2011, 07:36:10 AM
lis r12,0x8066
lhz r12, 0xffff93DC(r12)
andi. r12, r12, 0x800
cmplwi r12, 0x800

First thing I noticed is that your displacement operand is negative.  So this will be reading from 806593DC.

Second thing I noticed is that you don't need a cmp.  The . at the end of andi. is a cmpwi r12, 0.  If your button is pressed, then the result of andi. will be Not Equal.  If the button is not pressed, the result will be Equal.  It's kinda the opposite of cmpwi/cmplwi.  andi. can't be used to test for multiple simultaneous buttons, that requires a cmp.  But it can test for a single button easily.

The safety of CR0 inside a C2 code is determined by what lies around the hook.  If your hook is between a cmp or . instruction and its associated branch, you will get weird side effects.  In that case, I usually hook the cmp or . instruction, and place it at the end so CR0 is correct when we branch back to the game.

Stuff

Awesome. Many thanks guys. I can now shorten my max heal all monsters 1 more line even with a mask maybe. I didn't realize andi. does a cmpwi.

The reason I use cmplwi instead of cmpwi is because I ran into a signed issue here. CC right is 8000 and for some reason, cmpwi wasn't accepting 8000+ as 8000+. probably because it was looking for FFFF8000 and not 8000. And it makes sense now sort of. that's why I had to do lhz r12, 0xffff93DC(r12). I was experimenting with using hex instead of decimal in pyiiasmh and it was working fine until I did lhz r12, 0x93DC(r12). "Error: operand out of range (0x000093dc is not between 0xffff8000 and 0x00007fff)". Thank you captain obvious. When was the last time you interpreted A18C93DC as lhz r12,+27684(r12)?

806593DC is the classic controller address.

Quote from: dcx2 on September 30, 2011, 02:52:34 PMandi. can't be used to test for multiple simultaneous buttons, that requires a cmp.  But it can test for a single button easily.
D: I can for multiple simultaneous buttons, but only by using more code space.
"." is always cmpwi rA, 0? I wish it was cmpwi rA, UIMM just for andi.. >.<
.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

.set CC_ADDR, 0x806593DC

lis r12,CC_ADDR@ha
lhz r12,CC_ADDR@l(r12)
andi. r12,r12,0x800
# cmpwi here if you mask multiple buttons to make sure they are all held
beq- _NO_HACK

# do hack stuff here

_NO_HACK:

---

That will circumvent the sign extension problem in PyiiASMH.

You are also correct, cmplwi = compare logical word immediate.  http://pds.twi.tudelft.nl/vakken/in101/labcourse/instruction-set/cmpli.html  See how it says UIMM?  Unsigned IMMediate.  So it will not sign extend the immediate.

http://pds.twi.tudelft.nl/vakken/in101/labcourse/instruction-set/cmpi.html  SIMM = Signed IMMediate.  So it will extend the sign bit, which explains all the additional f's.

---

In your link, you used lhz (which does not sign extend the halfword) with cmplwi (which does).  If you had used lha instead, then the halfword that was loaded would be sign-extended and cmplwi would work.

. will always do cmpwi 0 (NOT cmplwi).  That is true for ANY instruction with a dot.  subic. rlwinm. etc.  Some instructions have an optional dot (rlwinm), others don't (andi.)

---

For multi-button activators, I often use an "enable" button (e.g. hold Z to enable hax), and then combine this with other buttons (press left or right arrow to roll value up or down).

First, you need both the delta activators and the typical activators loaded.  Then andi. the delta activators to see if e.g. left or right was just pressed.  If they weren't just pressed, beq- _END.  If they were pressed, use cmpwi's with the delta'd button and the enable button.

Here's my shop roller for ToS.  It's a GC game so the button masks are different, and the delta activators are +0x30 from buttons for GC instead of +4 for Wii.  But this is a good example to examine because it's a straight forward roller.

[spoiler]hook  800C70D8:  A8030016   lha   r0,22(r3)

z up or z down to roll shop

limits are 0 to 51

shop roller



# =========================================

.set BTN_ADDR,0x802CAED8

.set BTN_Z,0x0010
.set BTN_DUP,0x0008
.set BTN_DDOWN,0x0004


lha r10,22(r3)         # original instruction

lis r12,BTN_ADDR@ha      # r12 = button pointer
lhz r11,BTN_ADDR@l+0x30(r12)   # r11 = deltas
andi. r11,r11,BTN_DUP|BTN_DDOWN   # check for up or down changing
beq- _END

lhz r11,BTN_ADDR@l(r12)      # r11 = buttons

cmpwi r11,BTN_Z|BTN_DUP      # z dup incs
bne- 0f

addi r10,r10,1         # inc
cmpwi r10,51         # wrap
ble- 0f

li r10,0         # from 52 to 0

0:

cmpwi r11,BTN_Z|BTN_DDOWN   # z ddown decs
bne- 0f

subic. r10,r10,1      # dec
bge- 0f

li r10,51         # from 0 to 52

0:

_END:

sth r10, 22(r3)         # store rolled value
mr r0,r10         # finish original instruction[/spoiler]

Stuff

Quote from: dcx2 on September 30, 2011, 05:35:11 PMIn your link, you used lhz (which does not sign extend the halfword) with cmplwi (which does).  If you had used lha instead, then the halfword that was loaded would be sign-extended and cmplwi would work.
lhz worked though. Should I still change it to lha? I thought cmpwi was the problem since cmplwi fixed it.

I should start using these variable XD. In your spoiler, you used a different kind of branch label. 0f which points to 0:. Is it something special or is that just a regular label?

Your example showed me that there's still hope >.<. I wanted to see if my problem with Bully's speedhack could be fixed if I put the activators in the asm instead. The code works by itself, but as soon as I put activator buttons, it stopped working in some places. idk why. But I just didn't want to always be super running. I could check for 1 button that I would press along with R, and then it would work from there since you have to be pressing R to run anyway.
.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

You can use lhz with cmpwi or lha with cmplwi.  Doesn't matter, they're both functionally the same.  lhz/cmpwi is probably more intuitive because it's not doing implicit sign extensions.

Labels which are a single digit can be re-used.  0f will go to the next 0: label, 0b will go to the previous 0: label.  They're nice when you don't want to come up with five billion label names.

Stuff

I want to multiply. I'm assuming low word is fine, cuz we don't have 64 bits to work with >.>. And I just want to use mulli(high word has no immediate). I am thinking of this correctly, right? There isn't some kind of funky split going on here where it'll only multiply the lower 16 bits of the word.
.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

#53
mulli will multiply the two 32-bit values (EDIT: the 32-bit value in rS, and the sign-extended 16-bit immediate in the mulli), and truncate the upper 32-bits in the event that they aren't already 0.

mullw and mulhw can be used to get the lower and upper (respectively) 32-bits of a multiply.

mulhw can be useful if you know you're doing fixed point multiplies.  Put the 32-bit whole in one reg, 32-bit fraction in another, mulhw, and the destination reg will have the 32-bit whole result.

Stuff

#54
I made this up and pyiiasmh accepted it >.>
blrl.
Please tell me this branches to the link register and then stores the next address in the link register so I can come back to it later.Put it in a code. Yes it does. Unbelievable.
.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

Yup, that's what blrl does.  It's used in the code handler for C0 codes.

The "right" way to do such a thing is bctrl.  But if the ctr isn't safe, blrl is a nice substitute.

Stuff

So mtctr and then bctrl. Sounds gooder. So would it be safe if the next branch isn't a bctr? I mean, if your gonna bl, blrl would be safest imo, since your already gonna change the LR. But I'm willing to change to bctrl. Gotta do things the right way. XD
.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

Well, in general bctrl is the "right" way to do it because that's how compilers do it, that's how you'll see the game do it, etc.  You will never see blrl in the game's own ASM, except for maybe some kinda hack protection.

But you're right, if you are going to bl you know lr is safe.  So from a theoretical standpoint, it is an optimization to use lr for this purpose.  But if I had to look at it, it would make me twitch a bit.  o.<

ctr is volatile (except in the code handler; o.<) so it's pretty easy to determine whether it's safe.  Basically it can only be used in loops that don't call other functions.  If a loop will call a function, you'll see it use non-volatile, from r14-r31, to hold the loop counter.

daijoda

Quote from: dcx2 on September 30, 2011, 05:35:11 PM
[spoiler]hook  800C70D8:  A8030016   lha   r0,22(r3)

z up or z down to roll shop

limits are 0 to 51

shop roller



# =========================================

.set BTN_ADDR,0x802CAED8

.set BTN_Z,0x0010
.set BTN_DUP,0x0008
.set BTN_DDOWN,0x0004


lha r10,22(r3)         # original instruction

lis r12,BTN_ADDR@ha      # r12 = button pointer
lhz r11,BTN_ADDR@l+0x30(r12)   # r11 = deltas
andi. r11,r11,BTN_DUP|BTN_DDOWN   # check for up or down changing
beq- _END

lhz r11,BTN_ADDR@l(r12)      # r11 = buttons

cmpwi r11,BTN_Z|BTN_DUP      # z dup incs
bne- 0f

addi r10,r10,1         # inc
cmpwi r10,51         # wrap
ble- 0f

li r10,0         # from 52 to 0

0:

cmpwi r11,BTN_Z|BTN_DDOWN   # z ddown decs
bne- 0f

subic. r10,r10,1      # dec
bge- 0f

li r10,51         # from 0 to 52

0:

_END:

sth r10, 22(r3)         # store rolled value
mr r0,r10         # finish original instruction[/spoiler]
I'm shocked to find out sentences like ".set WHAT_EVER, 0x12345678" can be interpreted by the converter app and actually used in address calculations. I had no idea the app understood English! LOL. So slick. Is there a manual for the kind of lingo I could use in the app?

What do the "@ha" and "@l" parts mean? Whatever they mean, I've committed the effects of such usage to memory. Is this possible too?

lis r12,WHAT_EVER@ha
lwz r12,WHAT_EVER@l(r12)

And regarding your example, could you explain the reasoning behind doing two layers of tests (checking with andi. first, if passed, cmpwi), instead of just cmpwi always?

And dcx2, I can't thank you enough for your patience.

Stuff

@ha and such. That and the next 2 posts have dcx2 showing how @ha and such work. It's very handy. I have buttons saved in a txt (not all of them) and pyiiasm works it's magic from there.

.set is like a variable declaration afaik. you know variables can be named whatever. And even better is that you can use hex instead of decimal with displacement and immediates and whatnot. If you ask me, it's easier to look at hex than decimal when your working with hex. >.>

This thread is jam packed with stuff. And nice advice from dcx2. I learned the most here. (still think I'm newb with asm, but alot was learned. I'll be pro in no time ;p). Anything I learned elsewhere, sometimes I come back here to confirm that I'm right. You'll probably have to skip a few things, though cuz I asked some newb stuff.
.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