Coding Questions and other Quandaries
#74
(12-28-2021, 08:10 PM)Hackwiz Wrote: I understand the 06 serial write. Pretty slick.
I'm assuming this would be a great way to replace in game text???

Ye you could write over some in-game ASCII using 06 codetype. 06 String Writes can also be used to write over a set of instructions in static memory, or create a lookup table for another code (like in our case with the C0 code using the contents of the 06 code as a lookup table for the Pin Configs)

(12-28-2021, 08:10 PM)Hackwiz Wrote: andi. r0, r0, 0x1000 #Your desired button(s)-------> (Here's where you start to lose me. At this point r0 should be holding 0x1000 if pressed)

lis r3, 0x8000 #Before taking the branch, set r3 to its new value, upper 16 bits of EVA---> (I understand)

bne- button_has_been_pressed ----> (If r0 is holding 0x1000, and we AND it with 0x1000 shouldn't this be a beq- button_has_been_pressed?)

???Because they are equal, your code as it's written brings it to the next line:
I understand what the rest of it is doing pretty much, it's just the andi. conditional part and the bne- button_has_been_pressed that has me puzzled???

To understand why we are using andi. and why we are AND'ing against the vallue 0x1000, you will need to visualize your button activators as binary values (which is what they actually are). Let's go over all the button activator values for Wii-Remote.

0x0001 = Left
0x0002 = Right
0x0004 = Down
0x0008 = Up
0x0010 = +
0x0100 = 2
0x0200 = 1
0x0400 = B
0x0800 = A
0x1000 = -
0x2000 = Z
0x4000 = C
0x8000 = Home

Each of these values represents a bit that is flipped high. No two buttons can use the same single bit, this is how every button activator can have a different hex value. Whenever you press a Button, its bit will be flipped high. If you press multiple Buttons, multiple bits will be flipped high thus creating a new unique Hex value that isn't on the list above.

So a word has 32 total bits. However, for controller activators (buttons) we are using Halfwords instead. Thus we are only working with 16 bits (bits 0 thru 15). Let's convert the Hex values to Binary and view the list now.

Bit 15 = Left
Bit 14 = Right
Bit 13 = Down
Bit 12 = Up
Bit 11 = +
Bit 10 = Not on list (unused)
Bit 9 = Not on list (unused)
Bit 8 = Not on list (unused)
Bit 7 = 2
Bit 6 = 1
Bit 5 = B
Bit 4 = A
Bit 3 = -
Bit 2 = Z
Bit 1 = C
Bit 0 = Home

Broadway uses what is called Big Endian mode. So if you are viewing any value, it's first bit (the most left) is bit 0.

Side note: Little Endian is a nightmare and I thank the overlords every day that Broadway is natively Big Endian  Shy

Anyway getting back on the topic, whenever you press the Minus Button in your Bowling game the Halfword value at address 0x80708D40 gets its Bit 3 flipped high. If you are viewing that Halfword in Dolphin-memory-engine, you will see the value 0x1000 appear. Now if you press 3 buttons at the same time. Let's say C, Minus, and Right. That means Bits 1, 3, and 14 of the Halfword will all be flipped high. This will produce a Hex value of 0x5002. That's because the binary form is 0101 0000 0000 0010. The 0100 converts to the Hex digit 5, and 0010 converts to 2. Any case of 0000 converts to 0 ofc.

What the andi. instruction is doing is checking if Bit 3 of that Halfword (minus button bit) is flipped high. It doesn't matter what else is flipped high (what other buttons are pressed) as we are only concerned with bit 3 (0x1000).

The dot in 'andi.' is a free use of cmpwi rD, 0. Which in this case is - cmpwi r0, 0.

If bit 3 was high, then the result (r0) of the andi. instruction will be a NON-zero value. If it is, we know for 100% fact, the minus button was AT LEAST pressed (we don't care about the other bits/buttons). If the andi. instruction resulted with r0 equaling zero, then we know for 100% fact bit 3 was not high.

(12-28-2021, 08:10 PM)Hackwiz Wrote: Now I think I understand what the blr's are doing. simply going to the next instruction in the LR, which is the next instruction after the C0 insert, which effectively ends the C0.

Is this correct?

Yes.

(12-28-2021, 08:10 PM)Hackwiz Wrote: Which btw, when you do a C0, where exactly in memory is it writing the code being inserted? Is this a static place where the code handler stores it?

This always varies. Depends on how many codes you have equipped, which version of the Code Handler you are using, where the C0 code(s) are in your GCT/Cheat-manager.

(12-28-2021, 08:10 PM)Hackwiz Wrote: Another question, right off the bat you begin using r3 and r5? Why those and not r12 and r11?

C0 Code Safety is much different than C2 Code Safety. Whenever the Gecko Code Handler is executing any C0 code at that moment in time, certain Registers are 100% safe due to how the source of the Handler was written. r0, r3, r5, and r9 thru r12 are all safe for the latest version of the Code Handler (which is what almost all applications use). I prefer to use the lower registers, just because of habit I guess. It may be best if you understood how the Code Handler actually runs. An HBC app (such as USB Loader GX) reads the Hooktype and Ocarina settings of the app. If Ocarina is turned On, then the Code Handler's source (as a binary file) is placed into Memory. It's usually 'injected' at address 0x800018A8. However you need a method to branch to the Code Handler for it to be executed, this is where the Hooktype comes into play.

For example, if you choose GXDraw, the HBC app will find the GXDraw function of the Wii game (every Wii game has one) and will 'hook' the Code Handler to a specific address of the GXDraw function. Think of the Code Handler like a giant C2 code per say. At a certain address in GXDraw a branch instruction is placed there and it will jump to 0x800018A8 to execute the Code handler. Whenever the Code Handler is done is will jump back to GXDraw. The HBC app will also take the GCT contents that are on your SD card (/codes/xxxxXX.gct) and place those into memory (the spot in Memory is 'hardcoded' by the HBC app to comply with what the Code Handler requires, it's usually at 0x80002338).

The Code Handler is first ran whenever the game runs GXDraw for the first time after boot. The Code Handler will look in memory for the GCT contents (that was placed there by the HBC app), it will check for a proper GCT header and format. It will attempt to decipher your codes based on their Gecko Codetypes. The codes are executed in a 'top to bottom' fashion. Whenever the Code Hanlder encounters C0 code(s) the Code Handler will execute those as a subroutine. The Code Handler will place the current C0 code's address into r15 and branch to it like so...

Code:
mtlr r15
blrl

Every time the game calls the GXDraw function, it will re-run the Code handler again. This is why basic  RAM Writes (without the use of any if-statements and terminators) will always rewrite themselves. GXDraw gets called by any Wii Game every frame. Thus GXDraw executes 60 times per second. Therefore the Code Handler executes 60 times per second.

Obviously with any C0 code if you need to use the Link Register, you will need to back it up and restore it at some point in your C0 code. Or else the execution of the CPU/Broadway will not re-route back to the Gecko Code Handler, and your game will crash.

More info on C0's - https://mariokartwii.com/showthread.php?tid=1156
Reply


Messages In This Thread
RE: Coding Questions and other Quandaries - by Vega - 12-28-2021, 10:51 PM

Forum Jump:


Users browsing this thread: 3 Guest(s)