Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 82
» Latest member: saradk
» Forum threads: 1,023
» Forum posts: 1,707

Full Statistics

Online Users
There are currently 34 online users.
» 0 Member(s) | 32 Guest(s)
Bing, Google

Latest Threads
Automated Perfect License...
Forum: Cheat Codes
Last Post: zak
04-18-2019, 09:43 PM
» Replies: 2
» Views: 66
Timer Clock Display Modif...
Forum: DBZ BT3
Last Post: zak
04-18-2019, 01:03 PM
» Replies: 0
» Views: 18
480p Graphics Fix
Forum: Cheat Codes
Last Post: zak
04-16-2019, 05:51 PM
» Replies: 1
» Views: 121
Random Track Selection Fo...
Forum: Cheat Codes
Last Post: zak
04-14-2019, 02:37 PM
» Replies: 0
» Views: 80
Annoucements/Updates
Forum: Site Advancement
Last Post: zak
04-12-2019, 08:21 PM
» Replies: 36
» Views: 7,461
TAS BKT Sheet
Forum: TAS
Last Post: Cameron_MKW
04-07-2019, 12:13 PM
» Replies: 3
» Views: 1,029
List of Certain Functions...
Forum: Hacking General
Last Post: zak
04-05-2019, 06:23 PM
» Replies: 0
» Views: 106
Graphical In-Game Item Sp...
Forum: Cheat Codes
Last Post: zak
03-31-2019, 09:12 PM
» Replies: 0
» Views: 164
Graphical In-Game Item Sp...
Forum: Cheat Codes
Last Post: zak
03-31-2019, 09:10 PM
» Replies: 0
» Views: 76
Go From Complete Noob to ...
Forum: Guides/How-To's
Last Post: Cameron_MKW
03-31-2019, 02:29 PM
» Replies: 1
» Views: 165

 
  Graphical Speed-O-Meter
Posted by: zak - 03-23-2019, 02:11 PM - Forum: Cheat Codes - No Replies

Graphical Speed-O-Meter

Shout outs to Star & RiiDefi for Draw Text To Screen Code!

This code will display your vehicle speed as its own graphical image on the bottom left of your screen only during the race/battle. The image will not appear if you are not in a race/battle. Works everywhere.

NOTE: This code makes use of the following memory addresses...
0x80001660 thru 0x80001663
0x815F0000 thru 0x815F0003

Make sure no other codes in your GCT/Cheat-Manager are using those addresses.

NTSC-U
C200A3F0 00000007
9421FF80 BC610008
806DA358 80630044
80630000 3D808002
618C23E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009640 00000011
3D80815F 818C0000
2C0C0000 41820070
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
48000011 25332E30
66206B6D 2F680000
7CC802A6 38600009
388000DC 38A00001
3D808002 618C1DF0
7D8803A6 4E800021
3D808002 618C1DD0
7D8803A6 4E800021
B8610010 C8210008
38210090 81830000
60000000 00000000
C27E4C9C 00000007
3D80809C 818CD110
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807FEE20
60000000 00000000

PAL
C200A430 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C2480 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009680 00000011
3D80815F 818C0000
2C0C0000 41820070
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
48000011 25332E30
66206B6D 2F680000
7CC802A6 38600009
388000DC 38A00001
3D808002 618C1E90
7D8803A6 4E800021
3D808002 618C1E70
7D8803A6 4E800021
B8610010 C8210008
38210090 81830000
60000000 00000000
C27EEFAC 00000007
3D80809C 818C18F8
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F3618
60000000 00000000

NTSC-J
C200A38C 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C23A0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C20095DC 00000011
3D80815F 818C0000
2C0C0000 41820070
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
48000011 25332E30
66206B6D 2F680000
7CC802A6 38600009
388000DC 38A00001
3D808002 618C1DB0
7D8803A6 4E800021
3D808002 618C1D90
7D8803A6 4E800021
B8610010 C8210008
38210090 81830000
60000000 00000000
C27EE618 00000007
3D80809C 818C0958
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F2678
60000000 00000000

NTSC-K
C200A538 00000007
9421FF80 BC610008
806DA380 80630044
80630000 3D808002
618C24E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009788 00000011
3D80815F 818C0000
2C0C0000 41820070
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
48000011 25332E30
66206B6D 2F680000
7CC802A6 38600009
388000DC 38A00001
3D808002 618C1EF0
7D8803A6 4E800021
3D808002 618C1ED0
7D8803A6 4E800021
B8610010 C8210008
38210090 81830000
60000000 00000000
C27DD36C 00000007
3D80809B 818CFF38
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F1C58
60000000 00000000



List of Sources:
1st ASM (When Game loads StaticR.rel, Get Render Mode & Call Direct Print Setup Frame Buffer)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#       Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r0, 0x0014 (r1)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_SetupFB, 0x800223E0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_SetupFB, 0x80022480
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_SetupFB, 0x800223A0
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_SetupFB, 0x800224E0
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Get Render Mode (RKSystem->mpVideo()->pRenderMode) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

.if (region == 'E' || region == 'e') # RMCE
lwz r3, -0x5CA8(r13)
.elseif (region == 'P' || region == 'p') # RMCP
lwz r3, -0x5CA0(r13)
.elseif (region == 'J' || region == 'j') # RMCJ
lwz r3, -0x5CA0(r13)
.elseif (region == 'K' || region == 'k') # RMCK
lwz r3, -0x5C80(r13)
.endif

lwz r3, 0x0044(r3)
lwz r3, 0x0 (r3)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Call nw4r::db: DirectPrint_SetupFB #
#         r3 = Render Mode           #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

call_link nw4r_db_DirectPrint_SetupFB

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

pop_stack
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

2nd ASM (Take Float Speed, Convert It, Draw it to Screen)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#       Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                                  Mem Address Notes:                                        #
#                             0x80001660 Speed Float Word                                    #
# 0x815F0000 "Status Word" If not zero, Draw Code will execute, auto clears after every race #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x90 (r1)
stfd f1, 0x8 (r1)
stmw r3, 0x10 (r1)
.endm

.macro pop_stack
lmw r3, 0x10 (r1)
lfd f1, 0x8 (r1)
addi r1, r1, 0x90
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r12, 0x0 (r3)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_Printf, 0x80021DF0
.set nw4r_db_DirectPrint_StoreCache, 0x80021DD0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_Printf, 0x80021E90
.set nw4r_db_DirectPrint_StoreCache, 0x80021E70
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_Printf, 0x80021DB0
.set nw4r_db_DirectPrint_StoreCache, 0x80021D90
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_Printf, 0x80021EF0
.set nw4r_db_DirectPrint_StoreCache, 0x80021ED0
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#       Check to See if a Race is Active:       #
#         Load Status Word from Mem 81          #
# If not zero, we know to execute the Draw Code #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x815F
lwz r12, 0x0 (r12)
cmpwi r12, 0x0
beq- dont_execute

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Pointer Load; Float Load, Conversion, Storage #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x8000 #Set 1st Half Address of Exception Vector Area
lwz r11, 0x1660 (r12) #Load Pointer into r11
lfs f1, 0x0024 (r11) #Load the Speed Float from Pointer into Float Register 13
fabs f1, f1 #Handle negative values
crset 4*cr1+eq #Set the Condition Register before the Float Arg is used in DirectPrint Printf

#~~~~~~~~~~~~~~~~~~~~~#
# Create ASCII String #
#~~~~~~~~~~~~~~~~~~~~~#

bl the_string #Create the C++ string

.llong 0x25332E3066206B6D #Hex for "%3.0f km/h"
.long 0x2F680000

the_string:
mflr r6 #Set 4th Arg of DirectPrint Printf

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#              DirectPrint Printf & Store Cache               #
#                 Purpose: Draw on Screen                     #
#             r3 = X coordinate (starts far left)             #
#           r4 = Y coordinate (starts at very top)            #
#                 r5 = 0 No Wrap; 1 Wrap                      #
# r6 = Address Pointer to String that will be Drawn on Screen #
#               r7 thru r10 printf format args                #
#            f1 thru f13 printf float format args             #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

li r3, 0x9 
li r4, 0xDC
li r5, 0x1

call_link nw4r_db_DirectPrint_Printf
call_link nw4r_db_DirectPrint_StoreCache

#~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety #
#~~~~~~~~~~~~~~~~~~~~~#

pop_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# dont_execute label; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

dont_execute:
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

3rd ASM (Store Memory Pointer)
#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.macro default_instruction
lwz r3, -0x11E0 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0xFFFFD110 (r12)
.endm
.elseif (region == 'P' || region == 'p') # RMCP
.macro default_instruction
lwz r3, 0x3618 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0x18F8 (f12)
.endm
.elseif (region == 'J' || region == 'j') # RMCJ
.macro default_instruction
lwz r3, 0x2678 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0x0958 (r12)
.endm
.elseif (region == 'K' || region == 'k') # RMCK
.macro default_instruction
lwz r3, 0x1C58 (r31)
.endm
.macro set_playerbase
lis r12, 0x809B
lwz r12, 0xFFFFFF38 (r12)
.endm
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Region-Specific Player-Base #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

set_playerbase

#~~~~~~~~~~~~~~~~~~~~~~~#
# Pointer Level Loading #
#~~~~~~~~~~~~~~~~~~~~~~~#

lwz r12, 0x0020 (r12) #Load Word from 1st Level Pointer

slwi r11, r0, 2 #Shift the bits of r0 by 2 to the left, result in r11. This is the same as multiplying by 0x4. r0 is current player slot.

lwzx r12, r12, r11 #Load into 2nd Level Pointer
lwz r12, 0x0010(r12) #Load into 3rd Level Pointer
lwz r12, 0x0010(r12) #Load into 4th Level Pointer

#~~~~~~~~~~~~~~~~~~~~~#
# Store Final Pointer #
#~~~~~~~~~~~~~~~~~~~~~#

lis r11, 0x8000 #Set up 1st Half Address of Exception Vector Area
stw r12, 0x1660 (r11) #Store Pointer Address to 0x80001660

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Status Word in Mem81 for Draw Text ASM #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x815F #Set up 1st Half Address of dynmaic Mem81
stw r31, 0x0 (r12) #Store r31 to 0x815F0000, we simply need a value not zero to be stored here. This will make the Speed Bar ASM only trigger during races.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Default Instruction; Region-Specific #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#



Code creator: zak
Code credits: Star & RiiDefi (Draw Text To Screen Code); SwareJonge (Speed-O-Meter); Chadderz (source fixes to Mdmwii's OG Speed source); Mdmwii (original Speed-O-Meter)

Print this item

  Mini Turbo Charge Meter
Posted by: zak - 03-21-2019, 11:06 PM - Forum: Cheat Codes - No Replies

Mini Turbo Charge Meter 

Works everywhere except Battle.

This code will read the output value of your MT charge (including Orange MT for Karts) on the millisecond section of your timer. Works for all vehicles.

For Bike Usage: A reading of '270' indicates MT is fully charged ready for boost.
For Kart Usage: Once the first/initial reading reaches 270 (blue MT is fully charged), the milliseconds recycle. Then a reading of '300' indicates the Orange MT is fully charged ready for boost.

NTSC-U
C27E4C9C 00000008
3D80809C 818CD110
818C0020 540B103A
7D8C582E 818C0010
818C0010 A16C0100
2C0B0000 40820008
A16C00FE 3D808053
3D6B38A0 916C10A0
807FEE20 00000000

PAL
C27EEFAC 00000008
3D80809C 818C18F8
818C0020 540B103A
7D8C582E 818C0010
818C0010 A16C0100
2C0B0000 40820008
A16C00FE 3D808053
3D6B38A0 916C5BE8
807F3618 00000000

NTSC-J
C27EE618 00000008
3D80809C 818C0958
818C0020 540B103A
7D8C582E 818C0010
818C0010 A16C0100
2C0B0000 40820008
A16C00FE 3D808053
3D6B38A0 916C5568
807F2678 00000000

NTSC-K
C27DD36C 00000008
3D80809B 818CFF38
818C0020 540B103A
7D8C582E 818C0010
818C0010 A16C0100
2C0B0000 40820008
A16C00FE 3D808052
3D6B38A0 916C3C40
807F1C58 00000000



Source:

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.set region, ''

.if (region == 'E' || region == 'e') # RMCE
    .macro default_instruction
        lwz r3, -0x11E0 (r31)
    .endm
    .macro set_playerbase
        lis r12, 0x809C
    lwz r12, 0xFFFFD110 (r12)
    .endm
    .set _1sthalf, 0x8053
    .set _2ndhalf, 0x10A0
.elseif (region == 'P' || region == 'p') # RMCP
    .macro default_instruction
        lwz r3, 0x3618 (r31)
    .endm
    .macro set_playerbase
        lis r12, 0x809C
        lwz r12, 0x18F8 (f12)
    .endm
    .set _1sthalf, 0x8053
    .set _2ndhalf, 0x5BE8
.elseif (region == 'J' || region == 'j') # RMCJ
    .macro default_instruction
        lwz r3, 0x2678 (r31)
    .endm
    .macro set_playerbase
        lis r12, 0x809C
        lwz r12, 0x0958 (r12)
    .endm
    .set _1sthalf, 0x8053
    .set _2ndhalf, 0x5568
.elseif (region == 'K' || region == 'k') # RMCK
    .macro default_instruction
        lwz r3, 0x1C58 (r31)
    .endm
    .macro set_playerbase
        lis r12, 0x809B
        lwz r12, 0xFFFFFF38 (r12)
    .endm
    .set _1sthalf, 0x8052
    .set _2ndhalf, 0x3C40
.else # Invalid Region
    .abort
.endif

.set _mtc , 0xFE #MT Charge
.set _omtc, 0x100 #Kart Only Orange MT Charge
.set _mtb, 0x102 #Boost from MT Release
.set _ssmtb, 0x10C #Boost from both Stand Still Charge & MT's
.set _mushb, 0x110 #Mushroom/Zipper Boost
.set _trikb, 0x114 #Trick Boost
.set _ssc, 0x14C #Stand Still Charge
.set _air, 0x21A #Air Time

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Region-Specific Player-Base #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

set_playerbase

#~~~~~~~~~~~~~~~~~~~~~~~#
# Pointer Level Loading #
#~~~~~~~~~~~~~~~~~~~~~~~#

lwz r12, 0x0020 (r12) #Load Word from 1st Level Pointer

slwi r11, r0, 2 #Shift the bits of r0 by 2 to the left, result in r11. This is the same as multiplying by 0x4. r0 is current player slot.

lwzx r12, r12, r11 #Load into 2nd Level Pointer
lwz r12, 0x0010(r12) #Load into 3rd Level Pointer
lwz r12, 0x0010(r12) #Load into 4th Level Pointer

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load & Check Orange MT. If Zero, Load Blue MT Instead #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lhz r11, _omtc (r12) #Load Orange MT
cmpwi r11, 0x0
bne- skip_blue

lhz r11, _mtc (r12) #Load Blue MT

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Change Millisecond Display Code Instruction/Word #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

skip_blue:
lis r12, _1sthalf
addis r11, r11, 0x38A0 #Add 0x38A00000 to r11
stw r11, _2ndhalf (r12) #Store new instruction to Millisecond Display Address in Memory

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Default Instruction; Region-Specific #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#



Code creator: zak
Code credits: SwareJonge (universal meter code), Chadderz (fixes to pointer loading), mdmwii (subroutine founder for Millisecond Display), Bully (Millisecond Display Modifier Code creator)

Print this item

  About Stack Frames
Posted by: zak - 03-18-2019, 03:10 AM - Forum: Hacking General - No Replies

About Stack Frames

If you have been viewing sources of various ASM codes, you may have come across these set of instructions...

Code:
stwu r1, -0x50 (r1)
stmw r14, 0x8 (r1)

lmw r14, 0x8 (r1)
addi r1, r1, 0x50

You may have also seen something similar to the above, which is this...

Code:
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)

lmw r3, 0x8 (r1)
addi r1, r1, 0x80

Let's go over the details of what these set of instructions do, plus some tips (if you are beginner coder) to customize your own 'type' of stack frame to create instead of using a 'generic 'version'.

It is first recommended you go to this thread HERE and read the examples plus notes/rules for the following instructions: stwu, stmw, lmw, addi, stfd, lfd, stswi, lswi



Chapter 1. The Purpose

The purpose of creating a stack frame is to backup certain registers that could/will lose their values during the execution of the ASM code. It's used because its a universal method that can work on any Wii game. Sure you could use the Exception Vector Area, but there isn't that much available space there and many other ASM codes already utilize that space for storing misc values. You could find some other place to store them, but then it may only work just for the Wii game you are using. The stack method will work for all Wii games as just mentioned.



Chapter 2. Details of Creating Frame, Storing Registers

Code:
stwu r1, -0x50 (r1)
stmw r14, 0x8 (r1)

lmw r14, 0x8 (r1)
addi r1, r1, 0x50

The above is a common list of instructions used in some MKWii ASM codes to store the non-volatile registers to the stack and load them back after a code is done. Usually, the default instruction of the code is placed before the stwu instruction or after the addi instruction. The contents of the ASM code itself is placed in the middle of the two sets of stack instructions.

Register 1 (named sp in Dolphin) is the register that holds the address to the current stack pointer.  The stack grows DOWNWARD. As in towards LOWER memory addresses. So if you were viewing memory addresses on something like a RAM viewer the stack is actually growing upward for your view. A little confusing, I know.

So since the stack grows downward, thus anything before r1's current value is free space (more on stack limits later). So first we need to backup r1's value. At the same time, let's store that value to the address we want to, and... update r1 to have the new address. This is all done via the first stwu instruction...

Code:
stwu r1, -0x50 (r1)

The old r1 value is store -0x50 in reference to its address value. So let's say r1's value is 0x80371550. With the above instruction, the value 0x80371550 is stored at 0x80371500. At this point, you are wondering why the offset amount of -0x50 for the stmw instruction is used. We will get to that in a second...

Code:
stmw r14, 0x8 (r1)

This instruction will store all registers starting at r14 going upward to r31; to the location of r1 plus offset 0x8. Thus, they are now all copied over to our new stack frame. Your code can use the registers now as the instructions lmw, and addi will retrieve the values and replace r1 with its original value. We use stmw over multiple-stw instructions for various reasons:

- Creates a code that's shorter in compiled length
- Reduces risk of loss of data during an interrupt

Interrupts are invisible, you won't see them and one could occur during your stack frame creation. Thus it's much better to use stwm instead of a bunch of consecutive stw instructions.



Chapter 3. Illustration

Now that you understand how a new stack frame is created with the registers' values being stored, let's take a look of an illustration to demonstrate what would memory look like after execution of the stwu and stmw instructions from above

Code:
#      ...       #  Lower Address (Stack grows in the direction towards lower addresses aka downward)
#~~~~~~~~~~~~~~~~#
#     New r1     #  0x80371500 (r1's old address value of 0x80371550 is here)
#~~~~~~~~~~~~~~~~#
# Padding of 0x4 #  0x80371504
#~~~~~~~~~~~~~~~~#
#      r14       #  0x80371508 (0x8)
#~~~~~~~~~~~~~~~~#
#      r15       #  0x8037150C (0xC)
#~~~~~~~~~~~~~~~~#
# r16 thru... 30 #  0x80371510  (0x10 thru 0x48)
#~~~~~~~~~~~~~~~~#
#      r31       #  0x8035154C (0x4C)
#~~~~~~~~~~~~~~~~#
#     Old r1     #  0x80371550
#~~~~~~~~~~~~~~~~#
#      ...       #  Higher Address

As you can see there is padding of 0x4 after new r1. This is ALWAYS done for any stack frame you create. Hence why the stmw instruction is done with an offset of 0x8. At offset 0x0 (or at new r1) is old r1's value. The padding is done so that if you do happen to call another function (more about function calls HERE), then once that new function is called, the game ALWAYS stores the LR to that spot in the padding. Yes, I know its not needed for most ASM codes as most ASM codes don't do function calls, but's this method of adding the padding is to for good habit and to keep consistency.

The values in the parenthesis are the starting offset values for each item on the illustration. r31 starts at 0x4C offset. Ofc since r31 is 4 bytes long, it uses offsets 0x4C thru 0x4F

You can also see I didn't bother list every register of r14 thru r31 separately on the illustration. What's important is that you see r31 is exactly the the memory address before the old r1. So the amount of space we used for our stack frame was the BARE minimum. Ofc you could add more stack space to have padding in between r31 and old r1, but try to only allocate the amount you need.



Chapter 4. Stack Frame Size Rules/Limits

As mentioned moments ago, only allocate the amount of space you need. Personally the most stack space I have seen allocated was around 0x300 of bytes. But sometimes, a big stack allocation can cause a crash as the space might not be available.

Now at this you point, you have a good idea of how much space you need. You need 0x4 for old r1's value stored at new r1's location. You need 0x4 of padding afterwards. Then you need space for your registers. Each register takes up 4 bytes of data ofc...

So here's a simple equation to do to calculate stack space for your stack frame...

[4 x (# of Registers)] + 8 = Stack Space

Keep in mind we are using the stmw instruction for backing up registers. So if we want 3 free registers, the registers that would be backed up are r29, r30, and r31. Obviously with this instruction you need at least 2 registers (r30 and r31) or else trying to do a stmw instruction backing up just one register (r31) will output an error within the compiler.

So let's say we want 5 free registers (which would be r27 thru r31 due to stmw instruction) to use.. Let's do the calculation to figure out how much of a stack frame size to create

4 x 5 = 20

20 + 8 = 28

That is a value 0x1C in hex. Great so if we were to create a stack frame, we would start with this....

Code:
stwu r1, -0x1C (r1)
stmw r27, 0x8 (r1)

So are we good? No, we aren't. PowerPC has specific rules for creating stack frames. One of those rules is that all stack frames created must have a size that is 16 bytes (quadword) aligned. Thus because of this, the stack space your create (in hex value) must be divisible by 0x10 (aka the hex value ends in a zero). The value 0x1C does not end in zero, so we are breaking this rule.

We follow this rule as if an ASM Code has a function call in it, then the misalignment may cause a crash. Ofc, if the ASM code doesn't do any function calls at all, it doesn't matter. But once again, good habit and consistency is why.

Since our calculation for the stack frame size is 0x1C, we need to bump it up to next hex number that ends in zero. So the stack space we will allocate is 0x20. Here's the instructions..

Code:
stwu r1, -0x20 (r1)
stmw r27, 0x8 (r1)



Chapter 5. Overview of Recovering Values From Stack

Now we have a stack frame created, We put it in some code contents, and now we need to retrieve all the values back...

Code:
lmw r27, 0x8 (r1)

The lmw is simply the opposite of stmw. It loads all the values beginning at 0x8 offset of r1 and stores them in the source register all the way to r31 depending on which register is listed in the instruction. Ofc you can't do this with r31 as the source register (just like in the stmw instruction). Onto the final instruction..

Code:
addi r1, r1, 0x20 (r1)

The value you used in the addi instruction is simply the positive value of what was used in the stwu instruction. That's all you need to know. This makes r1 have its old value again. And that's it. You don't need to do any instruction to remove what values are left in memory, as the game will wipe/replace them the next time it creates a stack frame after the execution of your code's address.



Chapter 6. Using Store/Load String Word Immediate

All the stack-related instructions we have done so far are via stmw/and lmw. Obviously, if you wanted to backup registers 17 thru 20 only, then stmw/lmw would not be an option.

Let's see what the stack frame instructions would be if we wanted to backup only r17 thru r19. First calculate the stack space...

4 x 4 = 16
16 + 8 = 24 (0x18 hex)

Code:
stwu r1, -0x20 (r1) #0x18 bumped up to 0x20 for quadword alignment

Due to the stswi/lswi instructions not allowing offset values to be used with memory addresses of a register, you need we need an extra instruction that contains the exact address of new r1 + 8...Let's say r11 is available for use...

Code:
addi r11, r1, 0x8

Now we can do the store string word index....

Code:
stswi r17, r11, 12 #12 stands for 12 bytes starting at r17. 4 bytes r17, next 4 bytes of r18 then next 4 bytes of r19. Thus r17 thru r19 are stored.

And lets say our code is ending, time to retrieve the values from the stack and update r1 with its old value...

Code:
addi r11, r1, 0x8 #You will need to use this instruction again if r11's value was wiped/replaced during your code...
lswi r17, r11, r12
addi r1, r1, 0x20



Chapter 7. Storing Floats to a Stack Frame

When storing floats, you should always store them in their double precision form instead of single.

Since double precision values are used, this changes up the stack calculation as each double precision FPR takes up 0x8 per register. Let's say you wanna store 7 registers (via stmw/lmw so r25 thru r31)) and 2 floating point registers (f1 and f2)... Here's the calculation...

4 x 7 = 28 #for GPRs
8 x 2 = 16 #for FPRs

28 = 16 = 40

40 + 8 = 48 (0x30 in hex)

So our stack space already ends in 0x0 so we don't need to add any more space for quadword alignment. Now at this point, you are wondering which do I store first, the FPRs or the GPRs. It's always easier to store the items that take up less total stack space. Since our two FPRs take up less space than the 7 GPRs, we will store them first. There are no stwm/lmw type instructions that work for floats. Same with store/load string word type instructions for floats. Each FPR must be stored/loaded one at a time... So with all of this in mind, let's look at creating the stack frame and storing the FPRs....

Code:
stwu r1, -0x30 (r1)
stfd f1, 0x8 (r1)
stfd f2, 0xC (r1)

Alright now we store the GPRs....

Code:
stmw r25, 0x14 (r1)

Ofc, make sure all your offsets are correct so you don't wipe half of an FPR or a whole GPR when storing both floats and GPRs...

Alright let's say we are at the end of our code, lets recover the values and update r1 with it's old value..

Code:
lmw r25, 0x14 (r1)
lfd f2, 0xC (r1)
lfd f1, 0x8 (r1)
addi r1, r1, 0x30



Chapter 8. Conclusion

Alright, at this point you should know how to make your own stack frames 'from scratch'. Happy coding.

Print this item

  Using Mem81 to Auto-Clear Data for ASM Codes
Posted by: zak - 03-18-2019, 02:45 AM - Forum: Hacking General - No Replies

Using Mem81 to Auto-Clear Data for ASM Codes

NOTE: For intermediate level code creators that have already been utilizing the crash handler in previous codes.

Let's say you have an ASM code that originally stores data/values to the crash handler. You wanted these values to clear after every race. So you write another ASM code (that occurs only in between races) to zero/null out all the values.

Seems pretty silly to write another whole ASM code just to clear values. Instead of storing your data/values to the crash handler. You store them to Mem81. Mem81 auto-clears after every race/battle. The only time is doesn't auto clear is pressing restart in TT mode. I don't know the entire exact allowable region of Mem81 but here is a LARGE chunk used many various codes over time and I have seen no issues with any of those codes' functionality.

0x81400000 thru 0x81701000

As you can see this is a very large region of memory to have at your expense. And there you go, a great place to store values that need to be cleared per race. Happy coding!

Print this item

  Using the Exception Vector Area in ASM Codes
Posted by: zak - 03-18-2019, 02:31 AM - Forum: Hacking General - No Replies

Using the Exception Vector Area in ASM Codes

If you have started making ASM Codes recently and they are becoming less basic, you will eventually hit a point where you need to store values during one ASM code, to later utilize said values in another ASM Code. The simplest method to achieve that is to store the necessary data/values to what is known as the Exception Vector Area.

The Exception Vector Area is universal (same location within memory) for every Wii Game. Here are the address ranges:

0x80001490 thru 0x800016FF
0x80001798 thru 0x800017FF

This area is safe to store data/values to. Keep in mind that many many ASM codes utilize the Exception Vectors Area.

I would say that the most used region within this area is from High 0x800015XX to Mid 0x800016XX Range. So you might want to use the second portion (0x80001798 thru 0x800017FF) instead. Many users (noobs) of the game will use multiple ASM codes together in a GCT and not think twice to check them to see if a code happens to use the same Exception Vector region as another code. Thus causing both codes to malfunction and the 'noob' thinking there is something wrong with the code(s).

Now onto a demo code of how to utilize the Exception Vector Area. We have this code here...

https://mkwii.org/showthread.php?tid=889 (take a moment to thoroughly read thru the source)

The first ASM code has a register that holds the value of the in-race room size. We want to use this value for the next ASM Code (shared item code) to help determine whether or not the code should execute. The shared item code address has NO registers that hold the in-race room size value. 

So what the 1st instruction of the 1st ASM code does is establish the 1st half address of the Vector Area (lis r12, 0x8000). The next instruction stores the in-race room size value (byte) to the designated spot in the Vector Area at 0x8000164F. Now this allows the second ASM to load this byte value for use.

As you can see, pretty simple to do. Happy coding!

Print this item

  Distance Meter; DBZ BT3
Posted by: zak - 03-16-2019, 01:41 AM - Forum: DBZ BT3 - No Replies

DBZ BT3 Distance Meter

This code will display the current measured lateral distance between you and P2/COM via the match timer. The closer the opponent is to you, the more the number will decrease. The farther away the opponent is from you, the more the number will increase. The value 999 is the max, so if the distance measurement exceeds 999, the reading will still be 999. The actual timer of the match will still continue as normal. The distance values in this code only effect the display value of the match timer.

NTSC-U
C207B7A4 00000005
FDA0001C 3D808000
D9AC1600 816C1604
3D808012 3D6B3B80
916C1B44 D01E0044
60000000 00000000



Source:
fctiw f13, f0 #f0 contains distance float, convert it. Store result in FPR 13
lis r12, 0x8000 #Setup Exception Vector Area Address
stfd f13, 0x1600 (r12) #Store converted float double-word to 0x80001600
lwz r11, 0x1604 (r12) #Word at 0x80001604 contains our hex value, load it into r12
lis r12, 0x8012 #80121B44 is Timer Display Code's Memory Address
addis r11, r11, 0x3B80 #Add 3B800000 to r12
stw r11, 0x1B44 (r12) #Store 0x3B800XXXX (new instruction) to static memory address 0x80121B44
stfs f0, 0x0044 (r30) #Default Instruction



Code creator: zak

Print this item

  DWC_Authdata Spoofer; DBZ BT3
Posted by: zak - 03-14-2019, 10:23 PM - Forum: DBZ BT3 - No Replies

DBZ BT3 DWC_Authdata Spoofer

Also known as User ID Spoofer. This code allows a user to have a fully spoofed DWC_Authdata/User ID. Do not exceed the value of 000009184E729FFF (9999999999999 in decimal). Legit authdatas cannot exceed that limit. If you exceed that limit, a server mod/admin will instantly know you are using spoofing codes. Thus, if you follow this rule, your XXXX value will always be 0000.

Another thing to know, is that you this code on an existing Wifi Profile, you will get EC 60000. You will need to reset/initialize your Wifi Profile. When you make a Wifi Profile and get a new FC while using this code, you will need this code every time (with the same authdata value) to get on Wifi again on the same profile, or you will get EC 60000.

NTSC-U
C22D6190 00000004
3CE0WWWW 60E7XXXX
90E601B0 3CE0YYYY
60E7ZZZZ 90E601B4
80E601B0 00000000

WWWWXXXXYYYYZZZZ = Your desired DWC_Authdata in HEX



Source:
lis r7, 0xWWWW #Load the WWWW value into the upper 16 bits of Register 7, clear the lower 16 bits
ori r7, r7, 0xXXXX #Load the XXXX value into the lower 16 bits of Register 7
stw r7, 0x01B0 (r6) #Store the word (WWWWXXXX) of Register 7 at the address of Register 6 plus offset of 0x01B0
lis r7, 0xYYYY #Load the YYYY value into the upper 16 bits of Register 7, clear the lower 16 bits
ori r7, r7, 0xZZZZ #Load the ZZZZ value into the lower 16 bits of Register 7
stw r7, 0x01B4 (r6) #Store the word (YYYYZZZZ) of Register 7 at the address of Register 6 plus offset of 0x01B4
lwz r7, 0x01B0 (r6) #Load the word at address of Register 6 plus offset 0x01B0 into Register 7; Default Instruction



Code creator: zak

Print this item

  MAC Address Spoofer; DBZ BT3
Posted by: zak - 03-14-2019, 07:42 PM - Forum: DBZ BT3 - No Replies

DBZ BT3 MAC Address Spoofer

MAC Address = YY-YY-YY-ZZ-ZZ-ZZ

It is recommended you put the YY values that matches a prefix owned by Nintendo. A list of all Nintendo YY-YY-YY values are listed below. You can put any YY Values you want, but if you're using this to bypass a ban, stick with the list of Nintendo YY values.

The ZZ values can be anything in hex (A-F, 0-9).

NTSC-U
C22B0AA4 00000004
3D80YYYY 618CYYZZ
91840000 3D80ZZZZ
558C843E B1840004
38A00006 00000000

List of YY-YY-YY MAC Prefixes owned by Nintendo:
0009BF Nintendo Co., Ltd.
001656 Nintendo Co., Ltd.
0017AB Nintendo Co., Ltd.
00191D Nintendo Co., Ltd.
0019FD Nintendo Co., Ltd.
001AE9 Nintendo Co., Ltd.
001B7A Nintendo Co., Ltd.
001BEA Nintendo Co., Ltd.
001CBE Nintendo Co., Ltd.
001DBC Nintendo Co., Ltd.
001E35 Nintendo Co., Ltd.
001EA9 Nintendo Co., Ltd.
001F32 Nintendo Co., Ltd.
001FC5 Nintendo Co., Ltd.
002147 Nintendo Co., Ltd.
0021BD Nintendo Co., Ltd.
00224C Nintendo Co., Ltd.
0022AA Nintendo Co., Ltd.
0022D7 Nintendo Co., Ltd.
002331 Nintendo Co., Ltd.
0023CC Nintendo Co., Ltd.
00241E Nintendo Co., Ltd.
002444 Nintendo Co., Ltd.
0024F3 Nintendo Co., Ltd.
0025A0 Nintendo Co., Ltd.
002659 Nintendo Co., Ltd.
002709 Nintendo Co., Ltd.
182A7B Nintendo Co., Ltd.
2C10C1 Nintendo Co., Ltd.
34AF2C Nintendo Co., Ltd.
40F407 Nintendo Co., Ltd.
58BDA3 Nintendo Co., Ltd.
78A2A0 Nintendo Co., Ltd.
8C56C5 Nintendo Co., Ltd.
8CCDE8 Nintendo Co., Ltd.
9CE635 Nintendo Co., Ltd.
A45C27 Nintendo Co., Ltd.
A4C0E1 Nintendo Co., Ltd.
B8AE6E Nintendo Co., Ltd.
CC9E00 Nintendo Co., Ltd.
D86BF7 Nintendo Co., Ltd.
E00C7F Nintendo Co., Ltd.
E0E751 Nintendo Co., Ltd.
E84ECE Nintendo Co., Ltd.

Source:
lis r12, 0x0YYYY
ori r12, r12, 0xZZZZ
stw r12, 0 (r4)
lis r12, 0xZZZZ
srwi r12, r12, 16
sth r12, 0x4 (r4)
li r5, 6 #Default instruction

Code creator: NinArm
Code credits: mdmwii (mkw version source creator)

Print this item

  Serial Number Spoofer; DBZ BT3
Posted by: zak - 03-14-2019, 04:35 AM - Forum: DBZ BT3 - No Replies

DBZ BT3 Serial Number Spoofer

This code will allow you to spoof both parts of your serial number. Those are the Product Code and the 'SerNo'. The Product Code is the two or three digit letter code that comes right before your 9 digit number 'SerNo' that is on the outside sticker of the Wii. For example, on older American Wiis, this product Code is LU. On newer American Wiis (family model wiis, no GCN ports), the product code is KU. Another example is that some older European Wiis have the product code of LEH.

This code makes use of memory addresses 0x80001670 thru 0x80001673. Make sure no other codes in your GCT file are using those memory addresses.

NOTES (read this if you are intending to use this to bypass a ban):
Nintendo uses a certain order/range when applying serial numbers depending on when the Console was built. You simply can't put any Product Code + SerNo combination/setup you would like. Because if a server mod (who knows these certain orders/ranges like I do) sees an impossible Product Code + SerNo combo, then he/she knows you are using spoofer codes and you will get banned. View the Guide listed below to ensure your spoofed values are a legit 'combination' and within the legit range.

Guide:
List of legit Product Code (GGHHKK) values, then proper SerNo value range accordingly:
4C4546 = LEF (European); Serno must start with the values 3130, or 3230
4C4548 = LEH (European); Serno must start with the values 3130
4C454D = LEM (European); SerNo starting values unknown (maybe someone can get those...)
4C5500 = LU (American); SerNo must start with the value 31, 33, or 35
4B5500 = KU (American); SerNo must start with the values 3130, or 3430
4C4A46 = LJF (Japanese); SerNo must start with the value 3130
4C4A48 = LJH (Japanese); SerNo must start with the values 3132
4C4A4D = LJM (Japanese); SerNo must start with the values 3130
4C4148 = LAH (Australian); SerNo must start with the values 3130, 3131, or 3132
4C5446 = LTF (Taiwanese); SerNo must start with the values 3130, or 3230
4C5448 = LTH (Taiwanese); SerNo starting values unknown (maybe someone can get those...)
4C4B48 = LKH (Korean); SerNo starting values unknown (maybe someone can get those...)
4C4B4D = LKM (Korean; SerNo must start with the values 3130

SerNo (NNPPRRTTUUVVXXYYZZ) Values:
30 = 0
31 = 1
32 = 2
33 = 3
34 = 4
35 = 5
36 = 6
37 = 7
38 = 8
39 = 9

NTSC-U
C2256394 00000007
3D80GGHH 618CKK00
91960000 3D80NNPP
618CRRTT 9184FFF6
3D80UUVV 618CXXYY
9184FFFA 398000ZZ
9984FFFE 2C030000
60000000 00000000



Source:

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                                    Summary:                                   #
# The code's address is the first instruction after the function SCGetProductSN #
#     is completed. Thus certain registers hold key memory addresses that we    #
#     can use to edit the Product Code and SerNo before the Server reads it.    #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                    Register Notes:                   #
# r4 minus 0xA = Address that points to Start of SerNo #
#         r22 holds the Product Code Address           #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set & Store Product Code (LEH used as example) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x4C45
ori r12, r12, 0x4800
stw r12, 0 (r22)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set & Store SerNo (123456789 used as example) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x3132
ori r12, r12, 0x3334
stw r12, -0xA (r4)
lis r12, 0x3536
ori r12, r12, 0x3738
stw r12, -0x6 (r4)
li r12, 0x39
stb r12, -0x2 (r4)

#~~~~~~~~~~~~~~~~~~~~~#
# Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~#

cmpwi r3, 0

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#



Code creator: zak

Print this item

  Dragonball Z Budokai Tenkaichi Symbol Map
Posted by: zak - 03-14-2019, 04:19 AM - Forum: DBZ BT3 - No Replies

Dragonball Z Budokai Tenkaichi 3 Symbol Map

This is for the NTSC-U version of the game. Currently expanding this as time goes by. If you post this list anywhere else or expand it, please remember to credit me. Thanks!

memcpy = 0x80004338
memset = 0x8000443C
_OSShutdownToSBY = 0x80210E90
memmove = 0x80236A10
memcmp = 0x80236B34
sprintf = 0x802392B8
SCGetProductArea = 0x802562B0
SCGetProductCode = 0x80256334
SCGetProductSN = 0x80256370
SCGetProductGameRegion = 0x802563D8
NCDiGetWirelessMacAddress = 0x802B09C4

Original List Creator: zak
Credits: Megazig (MKW Symbol Map)

Print this item