Codes
WiiRd forum
April 28, 2024, 07:03:32 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Welcome on the new server

Update 4.3 - do NOT update!
Gecko 1.9.3.1
Should I get a USB Gecko, I wanna hack?
How do I use my USB Gecko
Where can I get WiiRd?
 
   Home   CODE DATABASE GAMEHACKING Help Search Login Register  
Pages: 1 [2]
  Print  
Author Topic: 32bit if code type  (Read 4481 times)
Dude
Full Member
***

Karma: 4
Posts: 117


« Reply #15 on: March 08, 2010, 10:30:42 AM »

Sorry, there is just one more things that I'm curios about.

There only seems to be an option for 32bit or 16bit "if" code types.  What if I was wanting to use an 8bit value (with values occupying 8bits on either side) to read from, or even write to?

Is it possible to perform this function on an 8bit value?

Many thanks in advance  Grin
Logged
dcx2
Computer Engineer
Moderator
Legendary Member
*****

Karma: 165
Posts: 3468


WWW
« Reply #16 on: March 08, 2010, 01:15:26 PM »

There are 8-bit writes.  There are no 8-bit ifs.  The reason is that the least significant bit of the first code-word is used to specify end-if, and so is not available to use for resolving 8-bit addresses.

28543210 0000wxyz

Would read address 80543210 and compare equal to wxyz

28543211 0000wxyz

Would end-if, then read address 80543210 and compare equal to wxyz

---

Note how they both read the same address.  That last bit can't be used for the address, so no 8-bit ifs.

...however...

Those 0's before wxyz can otherwise be used to mask off the 8 bits you don't care about.  For address 80543210, I think* an 8-bit if would look like

28543210 00FFxy00

The bits set to 1 are bits we don't care about (i.e. we don't care about byte 80543211 if we want to know what byte 80543210 is)

And for address 80543211, you would use

28543210 FF0000xy

We don't care about byte 80543210, so we mask it by using 1s.

You can also use this with button activators, too.  When moon jumping, for instance, you want to keep moon jumping even if the player presses other buttons like Z or C or B, so you mask off those buttons when doing your test.

* I haven't tried this so I might have the FF's backwards
Logged

Dude
Full Member
***

Karma: 4
Posts: 117


« Reply #17 on: March 08, 2010, 01:33:48 PM »

once again, THANK YOU  Cheesy

I was hoping that there would be a method to it but I just couldn't figure it out lol

I'll test this to see what order the bit mask needs to be and to test if this would work for my needs Smiley  I'll report back what order the bit mask needs to be.

EDIT: Ok, I've checked.

For an 8bit "if equal" at address 80543211 it should be 28543211 FF00wxyz.

I have built a "multi-if" code using 8bit "if" and it works.  Example using a 16bit to check an 8bit value:

28XXXXX 00008008     IF Home + DPad-UP buttons pressed THEN
28543212 FF000001     IF 8bit value at 80543211 = 01 (note 2 instead of 1) THEN
00AABBCC 0000000A     8bit write to address 80AABBCC with value of 10
28543211 FF000002     IF 8bit value at 80543211 = 02 (note 1) THEN
00AABBCC 00000014     8bit write to address 80AABBCC with value of 20
28543211 FF000003     IF 8bit value at 80543211 = 03 (note 1) THEN
00AABBCC 0000001E     8bit write to address 80AABBCC with value of 30
E0000000 80008000     Terminator

I have found that all "if" statements after the initial "endif" don't require the last significant bit increased for the logic to work.  It will write all correct values based on the "if" comparison without just writing the final value.

Thanks again to everyone that has helped me (and everyone else that checks how these IF code-types work)   Grin
« Last Edit: March 08, 2010, 02:39:49 PM by Dude » Logged
dcx2
Computer Engineer
Moderator
Legendary Member
*****

Karma: 165
Posts: 3468


WWW
« Reply #18 on: March 08, 2010, 03:51:30 PM »

Quote
28543211 FF00wxyz
That is an end-if;if on address 80543210, actually.

28543210 FF0000yz    # if 80543211 is yz

We are not adding one to the address.  Remember, 16-bit if must always be hword-aligned, so any address we use the if on must be a multiple of 2, and so we can never if on an odd address directly.  We are setting the least significant bit - when the address *looks* odd, it's actually an end-if on the even address.

28XXXXX 00008008     IF Home + DPad-UP buttons pressed THEN
28543210 FF000001     IF 8bit value at 80543211 = 01 (note 0 instead of 1 - this is not an end-if) THEN
00AABBCC 0000000A     8bit write to address 80AABBCC with value of 10
28543211 FF000002     END-IF; IF 8bit value at 80543211 = 02 (note 1 - this is an end-if) THEN
00AABBCC 00000014     8bit write to address 80AABBCC with value of 20
28543211 FF000003     IF 8bit value at 80543211 = 03 (note 1 - this is an end-if) THEN
00AABBCC 0000001E     8bit write to address 80AABBCC with value of 30
E0000000 80008000     Terminator (this ends two ifs; the first line, and the sixth line)
Logged

Dude
Full Member
***

Karma: 4
Posts: 117


« Reply #19 on: March 08, 2010, 05:38:58 PM »

This is just odd  Huh?

I'm not sure if it's just the addresses that I'm using but it doesn't seem to be working in the way that it's supposed to be, based on the ways that have been mentioned.

I used this as an example:
28XXXXX 00008008     IF Home + DPad-UP buttons pressed THEN
28543212 FF000001     IF 8bit value at 80543211 = 01 (note 2 instead of 1) THEN
00AABBCC 0000000A     8bit write to address 80AABBCC with value of 10
28543211 FF000002     IF 8bit value at 80543211 = 02 (note 1) THEN
00AABBCC 00000014     8bit write to address 80AABBCC with value of 20
28543211 FF000003     IF 8bit value at 80543211 = 03 (note 1) THEN
00AABBCC 0000001E     8bit write to address 80AABBCC with value of 30
E0000000 80008000     Terminator

Because this code is identical to how I did it, only with example addresses...
The ifs and endifs are in all the same places.  It have confirmed that it works in THIS way, but not the if, endif, endif way.

Also, I tried to make another code this way but with the IF addresses on the next byte, one address up, and NOTHING is getting it to work.  It will do the first write after the if, but none of the rest.

I am using Geckos v1.9.3, a USB Gecko and the final codes tested independent of each other  Cry

I've tried turning ifs into endifs, etc, etc, etc but it just won't work how it SHOULD work.  could it be the addresses I am using?
Logged
dcx2
Computer Engineer
Moderator
Legendary Member
*****

Karma: 165
Posts: 3468


WWW
« Reply #20 on: March 08, 2010, 07:44:12 PM »

You're going to need to copy and paste your code and the appropriate addresses.
Logged

Dude
Full Member
***

Karma: 4
Posts: 117


« Reply #21 on: March 08, 2010, 08:33:11 PM »

This is the code that works perfectly:

2817D6E0 00008008     Check if Home + DPad-UP is pressed
28907B72 FF000003     Check if value is 3 (endif)
00908923 0000000A     Write 10
28907B71 FF000006     Check if value is 6 (not endif)
00908923 00000014     Write 20
28907B71 FF000009     Check if value is 9 (not endif)
00908923 0000001E     Write 30
E0000000 80008000     Terminator
It writes all the correct values to address 80908923 based on the value at address 80907B71.

This is the code that just refuses to work as it should (note, the read address is just 1 byte away and the write address is just 4 bytes from the code above):

2817D6E0 00008008     Check if Home and DPad-UP is pressed
28907B72 FF000002     Check if value is 2 (Not endif)
00908927 00000018     Write 24
28907B73 FF000004     Check if value is 4 (endif)
00908927 00000031     Write 49
28907B73 FF000006     Check if value is 6 (endif)
00908927 00000063     Write 99
E0000000 80008000     Terminator
I've tried turning ifs to endifs, without button activator, etc, but at best all that it does is the first write  Huh?

I have tested both codes independently so that they don't interfere.  I did the top code first and tested that it works perfectly.  I altered the read address to test and it always wrote the correct values.  But it doesn't work if the if/endifs are the same as the bottom code (if, if, endif, endif, terminator)  I then copied it and modified it to the new addresses, editing the read address again during testing, but it doesn't work correctly.
Logged
Link
that dev there
Moderator
Hero Member
*****

Karma: 76
Posts: 1254

I hate everyone in this community. Except for you!


WWW
« Reply #22 on: March 08, 2010, 08:44:20 PM »

This is the code that works perfectly:

2817D6E0 00008008     Check if Home + DPad-UP is pressed
28907B72 FF000003     Check if value is 3 (endif)
00908923 0000000A     Write 10
28907B71 FF000006     Check if value is 6 (not endif)
00908923 00000014     Write 20
28907B71 FF000009     Check if value is 9 (not endif)
00908923 0000001E     Write 30
E0000000 80008000     Terminator
It writes all the correct values to address 80908923 based on the value at address 80907B71.

This is the code that just refuses to work as it should (note, the read address is just 1 byte away and the write address is just 4 bytes from the code above):

2817D6E0 00008008     Check if Home and DPad-UP is pressed
28907B72 FF000002     Check if value is 2 (Not endif)
00908927 00000018     Write 24
28907B73 FF000004     Check if value is 4 (endif)
00908927 00000031     Write 49
28907B73 FF000006     Check if value is 6 (endif)
00908927 00000063     Write 99
E0000000 80008000     Terminator
I've tried turning ifs to endifs, without button activator, etc, but at best all that it does is the first write  Huh?

I have tested both codes independently so that they don't interfere.  I did the top code first and tested that it works perfectly.  I altered the read address to test and it always wrote the correct values.  But it doesn't work if the if/endifs are the same as the bottom code (if, if, endif, endif, terminator)  I then copied it and modified it to the new addresses, editing the read address again during testing, but it doesn't work correctly.

Um.. without criticising you: both codes have the same endif/if structure just the addresses differ. Let me point out:

2817D6E0 00008008     Perform a 16 bit comparison on 8017D6E0 - read the value - and AND it with FFFF ( FFFF = NOT 0000 ) and check whether the result of that logic calculation is 8008
28907B72 FF000003     Perform a 16 bit comparison on 80907B72 - read the value - and AND it with 00FF ( 00FF = NOT FF00 ) (basically make the first byte 00) ands check whether the result if 0003
28907B71 FF000006     Endif first - then perform a 16 bit comparison on 80907B70 - read the value - and AND it with 00FF ( 00FF = NOT FF00 ) (basically make the first byte 00) ands check whether the result if 0003
28907B71 FF000009     Endif first - then perform a 16 bit comparison on 80907B70 - read the value - and AND it with 00FF ( 00FF = NOT FF00 ) (basically make the first byte 00) ands check whether the result if 0003

Um.. so you say it would write everything correctly based on the value at address 80907B71 - hm.. hard to beleve.. you only check 80907B71 in the second and third line.. the first line should be 28907B70
Logged

dcx2
Computer Engineer
Moderator
Legendary Member
*****

Karma: 165
Posts: 3468


WWW
« Reply #23 on: March 08, 2010, 08:55:16 PM »

You're not getting your alignment correctly.  Remember, these are 16-bit ifs, and we need to mask the upper or lower byte off.

28907B72 FF000003     Check if 80907B73 is 3 (not endif)

28907B72 00FF0300     Check if 80907B72 is 3 (not endif)

28907B71 FF000006     Check if 80907B71 is 6 (endif)

28907B71 00FF0600     Check if 80907B70 is 6 (endif)

I'm surprised your first code would ever write 10.  I believe these are the codes you actually want.

2817D6E0 00008008     Check if Home + DPad-UP is pressed
28907B70 FF000003     Check if 80907B71 is 3 (not endif)
00908923 0000000A     Write 10
28907B71 FF000006     Check if 80907B71 is 6 (endif)
00908923 00000014     Write 20
28907B71 FF000009     Check if 80907B71 is 9 (endif)
00908923 0000001E     Write 30
E0000000 80008000     Terminator


2817D6E0 00008008     Check if Home and DPad-UP is pressed
28907B72 00FF0200     Check if 80907B72 is 2 (Not endif)
00908927 00000018     Write 24
28907B73 00FF0400     Check if 80907B72 is 4 (endif)
00908927 00000031     Write 49
28907B73 00FF0600     Check if 80907B72 is 6 (endif)
00908927 00000063     Write 99
E0000000 80008000     Terminator
Logged

Dude
Full Member
***

Karma: 4
Posts: 117


« Reply #24 on: March 08, 2010, 09:50:29 PM »

I welcome all criticism.  As long as it's relevant to the topic, constructive and/or funny, then it's cool lol tongue  No worries.

@Link:
that is exactly why I'm confused...

The top code, as it is, works without a problem   huh  I tested it using various values, poking the read address with each target value to make sure that it reads and executes correctly...and it DOES.  It's reading from address 80907B71 and only has one endif (on the second line) and the terminator at the end.  It wouldn't work initially when I used the If, endif, endif, terminator format so I played around with the logic and found that this is what worked - if, endif, if, if, terminator.

I swear I'm not making this up and honestly cannot understand how or why this works, since it seems to go against the logic Sad  Typical that I end up with an illogical code that actually works.

@dcx2:
I didn't think to check the alignment tongue  I literally just copied the first code but modified the addresses.  I'll check with moving the mask and see how it goes.  I'm a little concerned with the fact that the first code works when I feel sure (and had it confirmed by two other people) that it shouldn't...

If I get the second code to work and have double-checked the first one that it also works then I will copy and paste them directly from the codes tab in Wiird - it's possible that I posted the "scratch" version that I made by accident.  I'm pretty tired and still learning Sad *fingers crossed*
Logged
dcx2
Computer Engineer
Moderator
Legendary Member
*****

Karma: 165
Posts: 3468


WWW
« Reply #25 on: March 08, 2010, 10:19:55 PM »

It is within the realm of possibility that the adjacent byte that you were reading just happens to be the right values at the right time.  These sorts of strange blue-moon phenomenon are quite common with technology, believe it or not.

If you know how to use breakpoints, you could set a breakpoint on your code or one of the destination addresses.  It will pause the game (hopefully when the code handler is running your code) and then you can step through line-by-line and see what addresses it's reading and writing to and what codes it is executing or not executing.

With exact checked, set a Write breakpoint on the address 80908923 or a Read breakpoint on the address 80907B70.  When you hit "Set Breakpoint", your game should pause instantly.  If you're staring at an instruction very low in memory (around 0x80001xxx), you're in the code handler, and if you aren't just keep hitting Set Breakpoint until you get there.  r3 and r4 should have the current line of the code being executed.

You can also use Memory Viewer to find your code and break when the code handler reads it, which is probably the most reliable since 1) only the code handler is reading the portion of memory where your code is, and 2) codes aren't always reading or writing to game memory if execution status is off.

To find your code in Memory Viewer, search for a unique-ish line of your code that will hopefully not be in many places in the game, like 2817D6E0 (C2 codes are usually pretty good too!).  Start searching from 80000000, result should be 80001xxxish, very low in memory again.  Right-click it -> breakpoint, change it to "Read", then Step away!

Hm...maybe I should do a tutorial on stepping through the code handler and watching it process your codes.
Logged

Dude
Full Member
***

Karma: 4
Posts: 117


« Reply #26 on: March 10, 2010, 06:37:58 AM »

Ok, I've really been looking at this...

Your modifications of the second code, dcx2, worked when everything I tried had failed (my attempt would only work up to a certain point).

I read the documentation closer to make sure I was understanding it correctly.  I understand the logic of how my code should go and the logic of how the code-type works...

I tried my first code again and found that it DID still work, so I checked in memory viewer to see what the adjacent values were.  All 8bit values in this memory area are similar.  I set ALL values, 2bytes on either side, to ZERO except for the address I wanted to read (28907B71).  I tried the code again and it still worked...

Also, I re-read through this thread to make sure I wasn't missing something before continuing with testing and found dcx2 saying:
Quote
The last bit of the address CANNOT be a 1, for two reasons.

1) The last bit of an if code-type's address is used to signify an end-if.
2) You would be doing an un-aligned read.  If you want to read a 16-bit half-word, your address MUST be a multiple of 2.  This requirement is why the least significant bit (LSbit) can be used for an end-if.

For my first code the address I WANTED to read as an 8bit IF was 80907B71.  My first 8bit IF was 28907B72 FF000003.  The one dcx2 posted had 28907B70 FF000003.  I had all adjacent memory addresses set to ZERO and my version of the code STILL worked.  Was it because the address 80907B71 wasn't aligned and increasing (instead of decreasing) the last bit fixed this?  This would explain why I was getting so confused and messing up my second attempt using different addresses...


EDIT:
It must be the alignment.  Here are some examples of codes that I have just created.  They are all based from codes that I just made.  the codes work as expected...so these should be correct tongue

When reading an 8bit value at address 80907B71
28907B70 FF000001     if = 01
00123456 000000xy     8bit write xy to address 80123456
28907B71 FF000002     endif = 02
00123456 000000xy     8bit write xy to address 80123456
28907B71 FF000003     endif = 03
00123456 000000xy     8bit write xy to address 80123456
E0000000 80008000     terminator

When reading an 8bit value at address 80907B72
28907B72 00FF0100     if = 01
00123456 000000xy     8bit write xy to address 80123456
28907B73 00FF0200     endif = 02
00123456 000000xy     8bit write xy to address 80123456
28907B73 00FF0300     endif = 03
00123456 000000xy     8bit write xy to address 80123456
E0000000 80008000     terminator

When reading an 8bit value at address 80907B73
28907B72 FF000001     if = 01
00123456 000000xy     8bit write xy to address 80123456
28907B73 FF000002     endif = 02
00123456 000000xy     8bit write xy to address 80123456
28907B73 FF000003     endif = 03
00123456 000000xy     8bit write xy to address 80123456
E0000000 80008000     terminator

When reading an 8bit value at address 80907B74
28907B74 00FF0100     if = 01
00123456 000000xy     8bit write xy to address 80123456
28907B75 00FF0200     endif = 02
00123456 000000xy     8bit write xy to address 80123456
28907B75 00FF0300     endif = 03
00123456 000000xy     8bit write xy to address 80123456
E0000000 80008000     terminator
« Last Edit: March 10, 2010, 07:35:53 AM by Dude » Logged
dcx2
Computer Engineer
Moderator
Legendary Member
*****

Karma: 165
Posts: 3468


WWW
« Reply #27 on: March 10, 2010, 12:58:40 PM »

Congrats!  Your edit looks good to me.  You got the alignment correct, you got the end-ifs correct, and you got the read addresses correct.  (Alignment's a bitch, huh?)

I really don't understand how

28907B72 FF000003

worked for you.  It was reading 80907B73 and comparing it to 3.

When did you look in Memory Viewer?  There's a chance that when you paused the game, the values in Memory Viewer were changing.  You also said you set the values to 0, but when the code handler was reading your code, the game might have fixed your pokes.

If you were using that code, you could set an Exact Read Breakpoint on 80907B73 and it would probably pause in the code handler while it is executing your code (you might have to set the breakpoint a few times, because there's probably more people than just the code handler reading it).  That would be the best time to cruise the Memory Viewer.

Other than that...good job!
Logged

Dude
Full Member
***

Karma: 4
Posts: 117


« Reply #28 on: March 10, 2010, 02:03:31 PM »

Thanks  Grin

I gotta agree, alignments are are right up there with the dentist.  But I've found that it's just the same as finding the alignment for a binary digit in CheatEngine.  Once I understood and got the ruling for it nailed down it is actually pretty simple tongue

I can't understand why it worked either.  I had the memory viewer auto-refreshing to see if anything was modifying the address it should, in theory, have been pointing to and that nothing was modifying the address that the code said it SHOULD be reading from...  Every address near the byte was set to zero and there was nothing altering them.  I poked the address with the values needed to trigger the code with and it worked every time (I had a progress bar and decimal value in the game to confirm it worked).

I also tried the "correct" code and it gave the exact same results.  I also haven't tried investigating using breakpoints.  I've used them on many an occasion before but never with any depth.  That breakpoint tutorial you mentioned earlier would be fantastic though  Cheesy

I might just go ahead and investigate this later Smiley  Many, many thanks to all that helped!
Logged
Pages: 1 [2]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2013, Simple Machines Valid XHTML 1.0! Valid CSS!