How to Make Codes Execute on Set Intervals - Printable Version +- Mario Kart Wii Gecko Codes, Cheats, & Hacks (https://mariokartwii.com) +-- Forum: Guides/Tutorials/How-To's (https://mariokartwii.com/forumdisplay.php?fid=45) +--- Forum: PowerPC Assembly (https://mariokartwii.com/forumdisplay.php?fid=50) +--- Thread: How to Make Codes Execute on Set Intervals (/showthread.php?tid=1385) |
How to Make Codes Execute on Set Intervals - Vega - 12-21-2019 How to make Codes Execute on Set Intervals
This has been a requested tutorial for quite some time, so here ya guys go.
Requirements: Already an intermediate-level (beyond pure beginner) ASM Coder This thread will teach you how to take a basic code and make the code execute on set timed intervals. This will imitate an automated off-on switch or vice versa. Method using the Race Timer: This is by far the easiest method for the beginner ASM Coder. For this method, we will want to use Hamster's Invisible Racing code (NTSC-U) located HERE. We will utilize the seconds value of the Race Timer to determine whether or not the Invisible Racing code will be off or on. We want the code to execute whenever the seconds of the race timer is an odd number. NTSC-U Invisible Racing 04559228 38000001 We will need to modify Hamster's code into a short ASM write. Two ASM Codes are required. One for the Invisible Racing Code and the other ASM will need to use an address that contains a register which tracks the race timer seconds. We will have the turn off for 1 full second, then turn on for 1 second, and repeat for the entirety of the race. Bully's Millisecond Modifier code https://mkwii.com/showthread.php?tid=102 is a good code for this. r28 at this address contains the seconds value of the race timer. Let's first write our ASM for Bully's Millisecond Modifier (NTSC-U). We will simply take r28's value and store it to the Exception Vectors. Before we write any ASM for this, launch Dolphin, set an Instruction BP on the address, and take a look at the code view. We do this just in case you have any weird scenario in regards to Register Safety. We see in the Code View this is our default instruction... Code: lhz r5, 0x0024 (sp) We can set the default instruction at the end of the source and use r5 safely. Let's write our ASM... Code: lis r5, 0x8000 #Setup upper bits of Exception Vector Address Our first ASM is completed. Now we need to make an ASM out of the Invisible Racing Code that will load this value and execute accordingly. You can go ahead and also set an Instruction BP on this address to check out the Register Safety. After a quick glance, it appears it will be easier just to use r12 instead of searching for safe registers to use. r0 cannot be used due to being read by the CPU as a pure 0 in certain instructions that we will be using for our ASM write. We will have the code only execute when the seconds value is an even number. Let's write it... Code: lbz r0, 0x0020 (r5) #Default Instruction Okay at this point, we have our seconds value in r12. Now we need a proper efficient way to know if the current seconds value is odd or even when being read. To do this, we need to go over binary just a quick bit. What is binary? Hex numbers are actually compiled readable form of binary numbers. Binary numbers are 0 or 1. As usual a word is 32 bits in length aka it has 32 binary numbers (0/1's). Thus each Hex number digit has 4 bits. When a Hex number is even, it's far-right most bit is 0. If it's odd that bit will be 1. So here's an easy instruction that will check if value in a register is even or odd. Code: clrlwi rX, rY, 31 The above instruction (Clear Left Word Immediate) will clear out all the bits except the last bit (which can referred to as the least significant bit). What's great about the clrlwi instruction is that you can use the 'record' feature for a free use of cmpwi rX, 0. Let's use the record feature and add in our branch instruction. Code: clrlwi. r12, r12, 31 Going back to Hamster's code, he was able to make the code by replacing the default instruction with li r0, 1. Thus we will have that Load Immediate instruction be executed if our seconds value is even. Let's write in the rest of the source and view it as completed. Code: lbz r0, 0x0020 (r5) #Default Instruction After compiling both of your own ASM's. Add them to your GCT/Cheat-Manager. If they fail, double check your work for errors and also remember to check Register Safety. Here are the two compiled ASMs of what we did wrote in this tutorial (NTSC-U). The code below has already been tested and works. C25310A0 00000002 3CA08000 93851398 A0A10024 00000000 C2559228 00000004 88050020 3D808000 818C1398 558C07FF 41820008 38000001 60000000 00000000 NOTE: For codes that you want to modify are 32 bit RAM Writes (that aren't replacing branch routes), you can actually do this with one ASM via just using Bully's Code. However, learning it the way explained in the tutorial is easier for the beginner. Conclusion: If the code you are wanting to utilize for set intervals is already an ASM code, then just simply add in the extra instructions for the seconds load-and-check. If you need to code to execute quicker, keep in mind that r5 in Bully's code contains the millisecond value. You can utilize that value to make codes go off/on in less than a second. For codes you need to execute off/on all the time regardless of whether or not you are in a live race, you will need to find an address that keeps track of some sort of timer value that can set an Instruction Breakpoint anywhere in game. RE: How to Make Codes Execute on Set Intervals - JoshuaMK - 12-22-2019 You can also create a simple C0 code to create the timer: Code: #~~~~~~~~~~~# This, as you know, will execute once per frame, meaning FRAMES is a value equaling XXXX/60 seconds. It's safer than trying to find a random hook address when running throughout the entire course too. r10's value is activated and then re-deactivated each time the timer loops. This is used as a flag for the main code. Just my input |