Jump to content

Ideka's ASM hacks


Ideka
 Share

Recommended Posts

So, I've devoted a few weeks to it, and I think that I'm finally starting to get a grasp around the basics of ASM hacking. Here's where I'll post any future major hacks I'll eventually make.

 

OoT Magic Armor:

 

Source:

 

  Reveal hidden contents

 

 

Thanks for reading, and keep a look out for any future updates!

  • Like 11
Link to comment
Share on other sites

Nice one, for a second I thought it was a remake of TP's magic armor but then I realized that your hack takes its name seriously. Do you have the hack patched to the ROM?

 

EDIT: You should look into using bitwise operations. Usage of ANDI would have greatly reduced your code for checking if the Zora Tunic was equipped by simply checking if ((*(u8*)(0x8015E6D0)) & 0x03) was equal to 3. Also, I see that you handle the case where subtracting from the current magic amount avoids overflowing the byte value by just setting the magic value to 0 if it was less than or equal to 4; one instruction which would help you greatly would be the SLTI (Set on Less Than Immediate) opcode.

 

I know that you realize you code could be shorter, I'm just offering what I think to be helpful tips (I don't mean to come off as a nitpicker). :)

  • Like 3
Link to comment
Share on other sites

Wow, thanks a lot Jason, I'm impressed by how easily you analyzed my hack! Those are definitely really useful advice, I think my opcode list is quite outdated (circa 98) so I'll look into that to avoid future mistakes. And yes, I have it patched to ROM. I would release a patch, but there's a possibility that this is going to be used in a major hack, so I'll wait until that's decided.

Link to comment
Share on other sites

  On 4/9/2015 at 7:43 PM, Jason777 said:

Nice one, for a second I thought it was a remake of TP's magic armor but then I realized that your hack takes its name seriously. Do you have the hack patched to the ROM?

 

EDIT: You should look into using bitwise operations. Usage of ANDI would have greatly reduced your code for checking if the Zora Tunic was equipped by simply checking if ((*(u8*)(0x8015E6D0)) & 0x03) was nonzero. Also, I see that you handle the case where subtracting from the current magic amount avoids overflowing the byte value by just setting the magic value to 0 if it was less than or equal to 4; one instruction which would help you greatly would be the SLTI (Set on Less Than Immediate) opcode.

 

I know that you realize you code could be shorter, I'm just offering what I think to be helpful tips (I don't mean to come off as a nitpicker).

 

God Jason, must you be such a nitpicker?!?!?

 

Kidding haha. I also liked that he used the actual magic instead of rupees. I thought it was a twist that folks would also enjoy.

Link to comment
Share on other sites

  On 4/10/2015 at 1:37 PM, haddockd said:

God Jason, must you be such a nitpicker?!?!?

 

Kidding haha. I also liked that he used the actual magic instead of rupees. I thought it was a twist that folks would also enjoy.

 

To be honest, magic armour using actual magic already exists, it's in The Wind Waker.

 

That said, I like this version better, because it only uses magic upon Link actually being attacked.  That's a cool twist, especially if it was edited so Link would take damage or immediately drop down dead if hit when his magic was at zero.

Link to comment
Share on other sites

Hmm... Using ANDI doesn't seem to work very well, it always makes the effect present with multiple other tunics. Perhaps I'm using it the wrong way? Here's the most recent source (haven't looked into the SLTI opcode yet):

 

  Reveal hidden contents

 

Thanks for any help!

Link to comment
Share on other sites

Ahh, no I made a mistake when advising how to check for it. What you should be doing is checking if ((*(u8*)(0x8015E6D0)) & 0x03) is equal to 0x03.

 

So you would change this...

 

andi k1, k1, 0003
bnel k1, r0, magic
lb k1, e693(k0)

To this...

 

andi k1, k1, 0003
ori t2, r0, 0003
bnel k1, t2, magic
lb k1, e693(k0)
Link to comment
Share on other sites

  • 2 weeks later...
  • 4 weeks later...

Okay. The last month(s?) I've been taking a break from the whole hacking thing, simply because I didn't have any time to spare for it. But now that Summer's coming up, I can gradually start picking up this hobby again! Here's a code I wrote quickly for a simple "marathon" mini-game where you gain 200 rupees if you win, or lose them if you don't:

 

  Reveal hidden contents

I obviously need to locate the adress of the Z coordinate of the opponent actor (which I plan to be the Running Man), but this is quite easy. My major problem is finding a good hook that runs every frame. If any of you guys have any tips or feedback on this hack, please tell me! Anything would be appreciated, really. Thanks.

Link to comment
Share on other sites

  • 6 months later...

Looking for a good hook, huh? http://doc.kodewerx.org/documents/r4300i_datasheet.pdf(Page 18)

The GameShark hooks in a similar location, as noted near the bottom of this excerpt. Let me give you a rundown pertaining to what's around said address where the GameShark hooks to:

 

 

 "0x80000400 (physical address 0x400) is by default the boot location. All R4xxx series processors uses the first 0x200 of RAM for exception handlers. The first 0x400 of physical memory contains the Interrupt Vector Table (and first 0x180 are the Processor Exception Vectors) and configuration parameters. The "interrupt vector table" is a data structure that associates a list of interrupt handlers with a list of interrupt requests. Put simply, an interrupt and exception handler both alter program flow. Interrupts handle external event, e.g. cartridge issue (peripheral interrupt), Pre-nmi (reset type), etc. Exceptions handle instruction faults, e.g. dividing by zero, etc. One thing to note about interrupts and exceptions with the Nintendo 64 that the R4300i architecture doesn't distinguish between them as there's essentially a single handler for them and the two merely have unique masks. However, in applications outside of this situation, they have individual handlers.
  Along with that, the CIC chip can relocate the boot location/entry point (which I linked to information relating to this initially at the top of this category). You can locate the start of the code segment by going to 0x8 (a word long) in any Nintendo 64 ROM, copying the address and breakpointing (linebreaking) it (as explained further down the page). The word found there is a pointer to the start of the real game code (Where memory officially starts). Everything before that is pretty much bootstrapping related and is for the most part, the same between games. For games that make use of the 64DD keep a copy of the original disk's disk header at 800001A0 for reference.

 

Exception Vectors

  Four exceptions are hardcoded to specific addresses: 0x80000000 is for TLB miss, 0x80000080 XTLB miss (64-bit), 0x80000100 for cache errors, and 0x80000180 for general exceptions (including caught interrupts). In addition to 0x80000180 the exception vector is here and can be used as a place to hook (to execute every frame) for Nintendo 64 GameShark codes ( made in assemby). However, a con to that is your code probably won't work on an actual GameShark as it hooks with a similar method (described below). In practice these are all just redirects to the general exception handler. Just a note about the exceptions: COP0 says why an exception occurs at a given point in time, but the vector table is the address where the CPU will jump to when said exception occurs/where the CPU goes to handle an exception. Speaking of which, the GameShark works by relocating the general exception handler to 0xA0000120 (uncached memory) and hooking GameShark utilities into the "regular" general exception handler at 0xA0000180 during which point in the execution path, a "code generator" gets executed. The code generator is basically an engine made up of instructions which act on behalf of GameShark codes, usually to make data at an address be written with a chosen value over and over again every time an interrupt occurs. Note, the GameShark writes to both cacheable and non-cachable memory (For a better understanding, read "CPU Addressing above")."

 

Those excerpts are taken from a Nintendo 64 hacking wiki that is currently in the works.

 

In conclusion, you can use 0x80000180, however your code probably won't work on an actual GS due to identical hooking methods (the GS overwriting your hook). I know Jason777 uses osWriteBackDCacheAll which seems to work great for him. For OoT 1.0 hooks, I shall direct you here: http://cloudmodding.com/zelda/oot

  • Like 1
Link to comment
Share on other sites

  • 1 year later...
  On 1/24/2017 at 7:13 PM, Ideka said:

Like stated in the video description (on Youtube though, so I get why you missed it) that's simply caused by my crappy computer. This was the best, least laggy footage I could manage to record, believe it or not.

Yeah I figured it was something like that but either way it's still a pretty awesome hack! Great job!

Link to comment
Share on other sites

 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.