956 lines
26 KiB
Plaintext
956 lines
26 KiB
Plaintext
|
|
||
|
--------------------------------
|
||
|
GCN AR CODES TYPES EXPLANATION
|
||
|
--------------------------------
|
||
|
|
||
|
v1.1 by kenobi
|
||
|
|
||
|
History :
|
||
|
|
||
|
v1.1 : Removed the 'NCT' codes types.
|
||
|
Added 'Byte Copy', 'Pointer Mod' and 'AND/OR' codes type.
|
||
|
Added some notes about the (m) codes, the 'write to CCxxxxxx' code.
|
||
|
Fixed some typos.
|
||
|
|
||
|
v1.0 : Initial release.
|
||
|
|
||
|
Special thanks to Parasyte for his help/informations about some codes types.
|
||
|
|
||
|
This document has been written for educational purpose.
|
||
|
It may help you create codes for the GCN AR, or they might be useless
|
||
|
junk... Your call !
|
||
|
If you know the GBA's ARv3 codes types, you'll find the GCN AR codes types
|
||
|
quite similar...
|
||
|
Also note that the PS2's AR MAX codes types are very close to the GCN ones.
|
||
|
|
||
|
|
||
|
Warning : This document is meant for advanced codes creators, NOT FOR
|
||
|
NEWBIES OR WANNABES. Sorry.
|
||
|
*************** If you are an experienced, known (by me or gscentral
|
||
|
admins) code hacker, and you don't
|
||
|
understand this document, you may try to ask help using the
|
||
|
www.gscentral.com forums
|
||
|
(or PM me there).
|
||
|
|
||
|
|
||
|
Special Note 1 : All adresses MUST be compatible with the data size you want
|
||
|
the codes are using.
|
||
|
*************** That means : -ANY address can be used for BYTE
|
||
|
reading/writing.
|
||
|
|
||
|
-Address MUST be a multiple of 2 for HALFWORD
|
||
|
reading/writing.
|
||
|
(Last hex number of the address must be either
|
||
|
:0,2,4,6,8,A,C,E)
|
||
|
|
||
|
-Address MUST be a multiple of 4 for WORD
|
||
|
reading/writing.
|
||
|
(Last hex number of the address must be either
|
||
|
:0,4,8,C)
|
||
|
|
||
|
If you don't follow this rule, the codes won't work (or the
|
||
|
AR might crash)...!
|
||
|
|
||
|
|
||
|
Special Note 2 : All codes are formatted like that : XXXXXXXX YYYYYYYY.
|
||
|
I called ADDRESS (in caps) the XXXXXXXX, and VALUE (in
|
||
|
caps) the YYYYYYYY.
|
||
|
|
||
|
|
||
|
Special Note 3 : GCN memory range is 0x80000000 - 0x817FFFFF cached, and
|
||
|
0xC0000000 - 0xC17FFFFF uncached.
|
||
|
(don't ask what it means, I don't get it either :P).
|
||
|
The codes will usualy write to the cached area.
|
||
|
|
||
|
|
||
|
Special Note 4 : The codes type numbers I give after a code name is a number
|
||
|
created like this:
|
||
|
For "Type zX" codes , the number X is :
|
||
|
AAA (3 most significant bits of the code's "VALUE")
|
||
|
|
||
|
For normal codes, the number in parenthesis after the name
|
||
|
of the code is :
|
||
|
AAABBCC (7 most significant bits of the code's
|
||
|
"ADDRESS")
|
||
|
AAA : type bits.
|
||
|
BB : subtype bits.
|
||
|
CC : value bits.
|
||
|
|
||
|
You can use them as reference, or just ignore them...
|
||
|
|
||
|
|
||
|
Special Note 5 : Any "unused" data could be filled with random numbers to
|
||
|
create a "unique encryption",
|
||
|
which could "sign" your codes. I randomly explained how it
|
||
|
works. It might not work
|
||
|
with every code. This feature isn't really interessing, but
|
||
|
I felt like it should be
|
||
|
noticed.
|
||
|
|
||
|
Special Note 6 : "Register 1BB4" is one of the register (= a given place in
|
||
|
the NGC memory) that the AR
|
||
|
uses to store some data while executing codes.
|
||
|
|
||
|
|
||
|
Special Note 7 : The addresses, values, and all the numbers starting by
|
||
|
"0x", or having the letter(s)
|
||
|
A, B, C, D, E and/or F in them are Hexadecimal numbers. If
|
||
|
you don't know what hexadecimal
|
||
|
is, make a search in Google.
|
||
|
|
||
|
|
||
|
Special Note 8 : If you don't know C/C++, be aware that "<<" means "Shift
|
||
|
left", and ">>" "Shift right".
|
||
|
"Shift left" is the "Lsh" button of the Windows calculator
|
||
|
(in "Scientific" mode).
|
||
|
"Shift right" is gotten by clicking the "Inv" checkbox,
|
||
|
then the "Lsh" button of the
|
||
|
Windows calculator (in "Scientific" mode).
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
________________
|
||
|
----------------
|
||
|
| Type z Codes |
|
||
|
----------------
|
||
|
|
||
|
|
||
|
|
||
|
"Type z" are codes which have an ADDRESS eqal to 00000000 ("z" stands for
|
||
|
"zero").
|
||
|
|
||
|
For any "Type zX" codes : X = code type = (VALUE >> 29) AND 0x07.
|
||
|
(If X>4, the code will be skipped)
|
||
|
|
||
|
|
||
|
-------------------------------
|
||
|
// Type "z0" : END OF CODES //
|
||
|
-------------------------------
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
00000000 00000000
|
||
|
|
||
|
It means "end of the code" (or "no more codes are executed").
|
||
|
|
||
|
The AR will "give" back the hand to the game, and then will start execute
|
||
|
codes
|
||
|
from the very 1st of the list.
|
||
|
|
||
|
|
||
|
|
||
|
--------------------------------------------
|
||
|
// Type "z2" : Normal execution of codes //
|
||
|
--------------------------------------------
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
00000000 40000000
|
||
|
|
||
|
Set register 1BB4 to 0.
|
||
|
It means that the AR goes back to the normal execution of codes.
|
||
|
(And it should break a "stop executing codes", set when register 1BB4 is =
|
||
|
2).
|
||
|
|
||
|
|
||
|
-----------------------------------------------------
|
||
|
// Type "z3" : Executes all codes in the same row //
|
||
|
-----------------------------------------------------
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
00000000 60000000
|
||
|
|
||
|
Set register 1BB4 to 1.
|
||
|
It means the AR will execute all the codes, without giving back the hand to
|
||
|
the
|
||
|
game, unless register 1BB4 changes value (with a "z2" code for exemple).
|
||
|
|
||
|
|
||
|
-------------------------------
|
||
|
// Type "z4" : Fill & Slide //
|
||
|
-------------------------------
|
||
|
|
||
|
2 lines code.
|
||
|
|
||
|
00000000 8XXXXXXX
|
||
|
Y1Y2Y3Y4 Z1Z2Z3Z4
|
||
|
|
||
|
|
||
|
Address = 8XXXXXXX AND 0x81FFFFFF.
|
||
|
|
||
|
Size = (address >> 25) AND 0x03.
|
||
|
(Size 0 = 8bits, Size 1 = 16 bits, Size 2 = 32 bits. Size 3 = Unused)
|
||
|
|
||
|
Value = Y1Y2Y3Y4.
|
||
|
|
||
|
Address increment = 0000Z3Z4 if (Z1 >> 3 = 0).
|
||
|
= FFFFZ3Z4 if (Z1 >> 3 = 1).
|
||
|
|
||
|
NOTE : When using halfword (or word), make address increment >> 1 (or >> 2)
|
||
|
when
|
||
|
computing the code.
|
||
|
|
||
|
Value increment = 00000000Z1 if (Z1 >> 3 = 0).
|
||
|
= FFFFFFFFZ1 if (Z1 >> 3 = 1).
|
||
|
|
||
|
Number of values to write = Z2.
|
||
|
|
||
|
NOTE : If Z2 = 0, nothing will be written (it'll be like the code isn't
|
||
|
executed).
|
||
|
|
||
|
|
||
|
Small note :
|
||
|
------------
|
||
|
As the sign of the address increment and the value increment are shared, you
|
||
|
MUST start
|
||
|
from the 1st address when using a positive value increment, and start from
|
||
|
the last address
|
||
|
when using a negative value increment.
|
||
|
|
||
|
|
||
|
------------------------------------------
|
||
|
// Type "z4 - Size 3" : Memory Copy //
|
||
|
------------------------------------------
|
||
|
|
||
|
These codes were 'created' by me (kenobi).
|
||
|
The only way to use them is to enter and enable the 'Enablers' codes.
|
||
|
You also HAVE TO add the Master Code flag to these Enabler codes'
|
||
|
indentifier
|
||
|
(or to include it into the (m) code), else they won't work properly.
|
||
|
Finally, the 'Enabler' codes and the actual codes must be entered
|
||
|
separately.
|
||
|
They should work on ANY AR (at least up to version 1.14b).
|
||
|
|
||
|
|
||
|
A - Memory Copy Without Pointer Support :
|
||
|
-----------------------------------------
|
||
|
|
||
|
Enabler (must be on!) :
|
||
|
04001E48 48000769
|
||
|
040025B0 5525043E
|
||
|
040025B4 4BFFF644
|
||
|
|
||
|
|
||
|
Exemple of byte copy :
|
||
|
00000000 86393FA8
|
||
|
80393FA0 00000001
|
||
|
|
||
|
|
||
|
Here is how it works :
|
||
|
00000000 8XXXXXXX
|
||
|
YYYYYYYY 0000ZZZZ
|
||
|
|
||
|
8XXXXXXX = [Destination address] OR 0x06000000.
|
||
|
YYYYYYYY = [Source address].
|
||
|
ZZZZ = number of bytes to copy (0x0000 will copy 0 byte, 0xFFFF will copy
|
||
|
65535 bytes).
|
||
|
|
||
|
Important : the 16-bits number before ZZZZ MUST BE '0000', else it'll create
|
||
|
errors !!!
|
||
|
|
||
|
So, if you follow what I explained, you can see that my code exemple will
|
||
|
copy 2 bytes,
|
||
|
from 80393FA0 to 80393FA8.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
B - Memory Copy With Pointers Support :
|
||
|
---------------------------------------
|
||
|
|
||
|
Enabler (must be on!) :
|
||
|
04001E48 48000769
|
||
|
040025B0 5525043E
|
||
|
040025B4 2C060000
|
||
|
040025B8 4182000C
|
||
|
040025BC 80630000
|
||
|
040025C0 80840000
|
||
|
040025C4 4BFFF634
|
||
|
|
||
|
|
||
|
With this code, if you put any data in the 8 upper bits of the value, the AR
|
||
|
will use
|
||
|
the addresses in the code as pointers addresses
|
||
|
|
||
|
Exemple :
|
||
|
|
||
|
00000000 86002F04
|
||
|
80002F00 01000138
|
||
|
|
||
|
Important : the 8-bits number before ZZZZ MUST BE '00', else it'll create
|
||
|
errors !!!
|
||
|
|
||
|
As the value start with '01' (could have been anything, but '00'), the AR
|
||
|
will load
|
||
|
the 32bits value at 80002F00 and use it as the source address, then load the
|
||
|
32bits
|
||
|
value at 80002F04 and use it as the destination address, and finally will
|
||
|
copy 138 bytes
|
||
|
from the source address to the destination address.
|
||
|
|
||
|
Note that if you put '00' in the start of the value, the code will work just
|
||
|
like
|
||
|
the 'Memory Copy Without Pointer Support' code.
|
||
|
|
||
|
If you need to add an offset to the pointer addresses, you'll have to do
|
||
|
this trick :
|
||
|
copy the source pointer address to 80002F00, the destination pointer address
|
||
|
to 80002F04,
|
||
|
add the offset values to theses pointer addresses (using the 'Add' code
|
||
|
type), and finally
|
||
|
use the 'Memory Copy with Pointers Support' to copy the bytes.
|
||
|
|
||
|
|
||
|
Exemple :
|
||
|
00000000 86002F00 <- Copy the 32bits (=4 bytes) source pointer address
|
||
|
804C8268 00000004 from 804C8268 to 80002F00.
|
||
|
|
||
|
00000000 86002F04 <- Copy the 32bits (=4 bytes) destination pointer address
|
||
|
804C8268 00000004 from 804C8268 to 80002F04.
|
||
|
|
||
|
84002F00 00000098 <- Add the offset 0x98 to the source pointer address at
|
||
|
80002F00.
|
||
|
|
||
|
84002F04 000001D0 <- Add the offset 0x1D0 to the source pointer address at
|
||
|
80002F04.
|
||
|
|
||
|
4A44F0A8 00000030 <- (if the user press R+Z...).
|
||
|
|
||
|
00000000 86002F04 <- Copy 0x138 bytes from the address stored at 80002F00
|
||
|
(=pointer address+0x98)
|
||
|
80002F00 01000138 to the address stored at 80002F04 (=pointer address +
|
||
|
0x1D0).
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
________________
|
||
|
----------------
|
||
|
| Normal Codes |
|
||
|
----------------
|
||
|
|
||
|
|
||
|
|
||
|
For any "Normal Codes", you have :
|
||
|
|
||
|
SubType = (ADDRESS >> 30) AND 0x03.
|
||
|
|
||
|
Type = (ADDRESS >> 27) AND 0x07.
|
||
|
|
||
|
Size = (ADDRESS >> 25) AND 0x03.
|
||
|
|
||
|
(usually, Size 0 = 8bits, Size 1 = 16 bits, Size 2 = 32 bits.
|
||
|
For some codes, Size 3 = Floating point single precision)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
------------
|
||
|
// Type 0 //
|
||
|
------------
|
||
|
|
||
|
--------------------------------------
|
||
|
// SubType 0 : Ram write (and fill) // (can be called "00", "01" and "02")
|
||
|
--------------------------------------
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
0.0.x
|
||
|
-----
|
||
|
|
||
|
0wXXXXXX Y1Y2Y3Y4
|
||
|
|
||
|
(w < 8!)
|
||
|
|
||
|
Address = ((0x0wXXXXXXX) AND 0x01FFFFFF) OR 0x80000000).
|
||
|
|
||
|
Size = (address >> 25) AND 0x03.
|
||
|
|
||
|
If Size = 0 [00] :
|
||
|
fills area [Address ; Address + Y1Y2Y3] with value Y4.
|
||
|
|
||
|
If Size = 1 [02] :
|
||
|
fills area [Address ; Address + (Y1Y2 << 1)] with value Y3Y4.
|
||
|
|
||
|
If Size = 2 [04] :
|
||
|
writes word Y1Y2Y3Y4 to Address.
|
||
|
|
||
|
|
||
|
Examples :
|
||
|
|
||
|
00023000 00000312
|
||
|
will write byte 0x12 to 80023000, 80023001, 80023002, 80023003.
|
||
|
|
||
|
02023000 00011234
|
||
|
will write halfword 0x1234 to 80023000, 80023002.
|
||
|
|
||
|
05023000 12345678
|
||
|
will write halfword 0x12345678 to 81023000.
|
||
|
|
||
|
|
||
|
|
||
|
-------------------------------
|
||
|
// SubType 1 : Write to pointer (can be called "04", "05" and "06")
|
||
|
-------------------------------
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
0.1.x
|
||
|
-----
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
4wXXXXXX Y1Y2Y3Y4
|
||
|
|
||
|
(w < 8!)
|
||
|
|
||
|
Address = ((0x4wXXXXXX) AND 0x01FFFFFF) OR 0x80000000.
|
||
|
|
||
|
Size = (Address >> 25) AND 0x03.
|
||
|
|
||
|
Pointer Address = [Word stored at Address].
|
||
|
|
||
|
This code will make the AR load the word stored at the address provided in
|
||
|
the code,
|
||
|
(also called the "Pointer Address"), and check if it's a valid address (ie.
|
||
|
if it's in
|
||
|
the [80000000~81800000[ range). It it is one, it will add an offset to it,
|
||
|
and it will
|
||
|
write the data provided in the code to this new address.
|
||
|
|
||
|
|
||
|
If Size = 0 [40] :
|
||
|
AR will write the byte Y4 at [Pointer Address + Y1Y2Y3].
|
||
|
|
||
|
If Size = 1 [42] :
|
||
|
AR will write the halfword Y3Y4 at [Pointer Address + (Y1Y2 << 1)].
|
||
|
|
||
|
If Size = 2 [44] :
|
||
|
AR will write the word Y1Y2Y3Y4 at [Pointer Address].
|
||
|
|
||
|
|
||
|
|
||
|
REMOVE THE 'VALID ADDRESS' CHECK, AKA 'POINTER MOD' :
|
||
|
-----------------------------------------------------
|
||
|
|
||
|
This code was 'created' by me (kenobi).
|
||
|
The only way to use it is to enter and enable the 'Enabler' code.
|
||
|
You also HAVE TO add the Master Code flag to these Enabler codes'
|
||
|
indentifier
|
||
|
(or to include it into the (m) code), else they won't work properly.
|
||
|
Finally, the 'Enabler' codes and the actual codes must be entered
|
||
|
separately.
|
||
|
It should work on ANY AR (at least up to version 1.14b).
|
||
|
|
||
|
|
||
|
Enabler (must be on) :
|
||
|
04001FA4 48000014
|
||
|
|
||
|
Once you use this code, the 'Write to Pointer' code will stop checking if
|
||
|
the address you
|
||
|
point to is a valid address.
|
||
|
That means that you can write to virtual memory without a TLB (m) code, but
|
||
|
you have to make
|
||
|
sure that the address the pointer code reads is a valid address (else, it'll
|
||
|
crash).
|
||
|
|
||
|
Exemple (courtesy of donny2112) :
|
||
|
04002F0C 7FC39C9C
|
||
|
42002F0C 00010000
|
||
|
42002F0C 03ED0000
|
||
|
42002F0C 04F70000
|
||
|
42002F0C 05BB0000
|
||
|
|
||
|
The first line will write '7FC39C9C' to 80002F0C.
|
||
|
Then, the other lines will write 0x0000 to 0x7FC39C9C+2*1,
|
||
|
0x7FC39C9C+2*0x3ED, 0x7FC39C9C+2*0x4F7,
|
||
|
and finally 0x7FC39C9C+2*0x5BB.
|
||
|
|
||
|
The advantage of this code, over a TLB (m) code, is that it only needs a 1
|
||
|
lines enabler, it is
|
||
|
compatible with all games and all ARs, and it allows you to use 8/16/32bits
|
||
|
ram write.
|
||
|
|
||
|
The downside is that if you point to an invalid address, the GC will just
|
||
|
crash.
|
||
|
If you're not sure that you'll point to a valid address, you can use this
|
||
|
combinaison of code to check
|
||
|
it manually (in this exemple, I make sure that the address is in the
|
||
|
0x80000000~817F0000 range) :
|
||
|
|
||
|
74XXXXXX 80000000 <- If value > 0x80000000
|
||
|
2CXXXXXX 81800000 <- and If value < 0x81800000
|
||
|
44XXXXXX Y1Y2Y3Y4 <- then execute this pointer code.
|
||
|
|
||
|
XXXXXXXX being the address where the Pointer Address is stored.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
-----------------------
|
||
|
// SubType 2 : Add code (can be called "08", "09" and "0A")
|
||
|
-----------------------
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
0.2.x
|
||
|
-----
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
8wXXXXXX Y1Y2Y3Y4
|
||
|
|
||
|
(w < 8!)
|
||
|
|
||
|
Address = (0x8wXXXXXX AND 0x81FFFFFF).
|
||
|
|
||
|
Size = (Address >> 25) AND 0x03.
|
||
|
|
||
|
if Size = 0 [80] :
|
||
|
Loads byte stored at [Address], adds Y1Y2Y3Y4 to it, and stores the
|
||
|
resulting byte
|
||
|
(= result AND 0xFF) at [Address].
|
||
|
|
||
|
if Size = 1 [82] :
|
||
|
Loads halfword stored at [Address], adds Y1Y2Y3Y4 to it, and stores the
|
||
|
resulting halfword
|
||
|
(= result AND 0xFFFF) at [Address].
|
||
|
|
||
|
if Size = 2 [84] :
|
||
|
Loads word stored at [Address], adds Y1Y2Y3Y4 to it, and stores the result
|
||
|
at [Address].
|
||
|
|
||
|
if Size = 3 [86] :
|
||
|
Loads floating value stored at [Address], adds Y1Y2Y3Y4 (must be a
|
||
|
floating point single precision value)
|
||
|
to it, and stores the result at [Address].
|
||
|
|
||
|
|
||
|
Change ADD to AND :
|
||
|
------------------
|
||
|
This code was 'created' by me (kenobi).
|
||
|
The only way to use it is to enter and enable the 'Enabler' code.
|
||
|
You also HAVE TO add the Master Code flag to these Enabler codes'
|
||
|
indentifier
|
||
|
(or to include it into the (m) code), else they won't work properly.
|
||
|
Finally, the 'Enabler' codes and the actual codes must be entered
|
||
|
separately.
|
||
|
This change is definitive (until you reboot the Game) :
|
||
|
|
||
|
Enable 8-bits AND :
|
||
|
0400200C 7C002038
|
||
|
|
||
|
|
||
|
Enable 16-bits AND :
|
||
|
0400201C 7C002038
|
||
|
|
||
|
|
||
|
Enable 32-bits AND :
|
||
|
0400202C 7C002038
|
||
|
|
||
|
Enable 8~32bits AND :
|
||
|
00000000 8400200C
|
||
|
7C002038 00030004
|
||
|
|
||
|
|
||
|
Change ADD to OR :
|
||
|
------------------
|
||
|
This code was 'created' by me (kenobi).
|
||
|
The only way to use it is to enter and enable the 'Enabler' code.
|
||
|
You also HAVE TO add the Master Code flag to these Enabler codes'
|
||
|
indentifier
|
||
|
(or to include it into the (m) code), else they won't work properly.
|
||
|
Finally, the 'Enabler' codes and the actual codes must be entered
|
||
|
separately.
|
||
|
This change is definitive (until you reboot the Game) :
|
||
|
|
||
|
Enable 8-bits OR :
|
||
|
0400200C 7C002378
|
||
|
|
||
|
Enable 16-bits OR :
|
||
|
0400201C 7C002378
|
||
|
|
||
|
Enable 32-bits OR :
|
||
|
0400202C 7C002378
|
||
|
|
||
|
Enable 8~32bits OR :
|
||
|
00000000 8400200C
|
||
|
7C002378 00030004
|
||
|
|
||
|
Note : you can't mix 'ADD', 'AND' and 'OR' codes for the same code type
|
||
|
(8/16/32bits).
|
||
|
|
||
|
|
||
|
|
||
|
----------------------------------------------
|
||
|
// SubType 3 : Master Code & Write to CCXXXXXX (can be called "0E" and "0F")
|
||
|
----------------------------------------------
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
0.3.x
|
||
|
-----
|
||
|
|
||
|
1 line code.
|
||
|
|
||
|
CwXXXXXX Y1Y2Y3Y4
|
||
|
|
||
|
(w < 8!)
|
||
|
|
||
|
Address = ((0x6wXXXXXX) AND 0x01FFFFFF) OR 0x80000000).
|
||
|
|
||
|
Size = (Address >> 25) AND 0x03.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
If Size = 2 (0.3.2) : Master Code (C4XXXXXX Y1Y2Y3Y4)
|
||
|
-----------------------------------------------------
|
||
|
|
||
|
Y4 = Master Code Number.
|
||
|
0x00 : executed only once, just before the game bootup.
|
||
|
Only one (m) code can have the '00' number (the others will be
|
||
|
skipped),
|
||
|
and it must be the very one in the (m) code list (else it'll be
|
||
|
skipped).
|
||
|
|
||
|
0x01~0x0F : executed continuously during the game execution.
|
||
|
(2 (or more) master codes that have the same Master Code
|
||
|
Number can't
|
||
|
be executed correctly if they are put one just after
|
||
|
another.
|
||
|
Only the first one will be executed, the other(s) will be
|
||
|
skipped).
|
||
|
|
||
|
Y3 = number of codes to execute each time the AR "has the hand".
|
||
|
|
||
|
Y2 AND 0x03 = Master Code Type :
|
||
|
|
||
|
Type 0 : create a branch to SUBROUTINE 1.
|
||
|
(Save : R0 R3 R28 R29 R30 R31)
|
||
|
|
||
|
Type 1 : backup 4 asm lines from the game, and write a Branch to MAIN
|
||
|
ROUTINE.
|
||
|
(Save : R3 R28 R29 R30 R31, Destroys : R0?)
|
||
|
|
||
|
Type 2 : create a branch to 1 copy of SUBROUTINE 1.
|
||
|
(Save : R0 R3 R28 R29 R30 R31)
|
||
|
|
||
|
Type 3 : create a branch to MAIN ROUTINE START (will execute the 4 asm lines
|
||
|
backed up
|
||
|
in Type 1, if any).
|
||
|
(Save : R0 R3 R28 R29 R30 R31)
|
||
|
|
||
|
|
||
|
Note : Putting random numbers in Y1 should change the encryption, thus
|
||
|
"signing" your
|
||
|
code (untested).
|
||
|
|
||
|
Note : Don't use the Type 1 alone with a Master Code Number >0, else the AR
|
||
|
will backup its own
|
||
|
hook, and enter an infinite loop. So put a conditional code type make
|
||
|
that this code isn't
|
||
|
executed more than once.
|
||
|
|
||
|
|
||
|
|
||
|
If (Size = 3) AND ((address AND 0x01FFFFFF ) < 0x01000000) (0.3.3):
|
||
|
-------------------------------------------------------------------
|
||
|
|
||
|
Write halfword to CCXXXXXX (C6XXXXXX Y1Y2Y3Y4)
|
||
|
----------------------------------------------
|
||
|
|
||
|
Address = 0xCCXXXXXX
|
||
|
Stores the halfword Y3Y4 at Address.
|
||
|
|
||
|
Note : Putting random numbers in Y1Y2 should change the encryption, thus
|
||
|
"signing" your
|
||
|
code (untested).
|
||
|
|
||
|
|
||
|
If (Size = 3) AND ((address AND 0x01FFFFFF ) >= 0x01000000) (0.3.3):
|
||
|
--------------------------------------------------------------------
|
||
|
|
||
|
Write word to CDXXXXXX (C7XXXXXX Y1Y2Y3Y4)
|
||
|
------------------------------------------
|
||
|
|
||
|
Address = 0xCDXXXXXX
|
||
|
Stores the word Y1Y2Y3Y4 at Address.
|
||
|
|
||
|
Note : Parasyte informed me that writing to 0xCDXXXXXX doesn't makes any
|
||
|
sense, and he thinks
|
||
|
it might be some kind of AR bug...
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
**************************************************
|
||
|
* NOTES FOR ALL CONDITIONAL CODES (TYPE 1 TO 7). *
|
||
|
**************************************************
|
||
|
|
||
|
All the Conditional Codes are 1 line code, but you "need" to add another
|
||
|
line to make them work.
|
||
|
Conditional Code are used to trigger the next code(s) when an event happens,
|
||
|
for exemple give the
|
||
|
player 99 lifes when buttons L+R are pushed, or make the life becomes full
|
||
|
when it reaches 50%
|
||
|
of its value...
|
||
|
|
||
|
|
||
|
They all come in 3 "flavors" : 8, 16 and 32 bits. You select it by changing
|
||
|
the size data in the code.
|
||
|
Reminder : Size = (Address >> 25) AND 0x03
|
||
|
|
||
|
For all the Conditional Codes, you first take the value of the IN GAME data,
|
||
|
and compare it to
|
||
|
the value provided in the CODE data. The result, which should be read as
|
||
|
'True' (or 'False'), will
|
||
|
tell if the Conditional Code will activate the next codes.
|
||
|
|
||
|
Anyway, Conditional Codes should be used by advanced code makers.
|
||
|
And don't ask for the "paddle" values, they seem to change for every game...
|
||
|
So find them yourself :-)
|
||
|
|
||
|
The number I give as exemples has been made using BYTE size :
|
||
|
|
||
|
08XXXXXX YYYYYY is the "If equal execute next code" generic value for a BYTE
|
||
|
comparison.
|
||
|
For halfwords, it'll be 0AXXXXXX YYYYYYYY, and for words 0CXXXXXX
|
||
|
YYYYYYYY...
|
||
|
|
||
|
|
||
|
|
||
|
--------------------------
|
||
|
// Type 1 : If equal... // (can be called "10", "11" and "12")
|
||
|
--------------------------
|
||
|
|
||
|
1.y.x
|
||
|
-----
|
||
|
|
||
|
08XXXXXX YYYYYYYY
|
||
|
|
||
|
(w >= 8!)
|
||
|
|
||
|
Subtype 0 [08] : If equal, execute next line (else skip next line).
|
||
|
Subtype 1 [48] : If equal, execute next 2 lines (else skip next 2 lines).
|
||
|
Sybtype 2 [88] : If equal, execute all the codes below this one in the same
|
||
|
row (else execute
|
||
|
none of the codes below).
|
||
|
Subtype 3 [C8] : While NOT EQUAL,turn off all codes (infinite loop on the
|
||
|
code).
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
------------------------------
|
||
|
// Type 2 : If NOT equal... // (can be called "20", "21" and "22")
|
||
|
------------------------------
|
||
|
|
||
|
2.y.x
|
||
|
-----
|
||
|
|
||
|
10XXXXXX YYYYYYYY
|
||
|
|
||
|
|
||
|
Subtype 0 [10] : If NOT equal, execute next line (else skip next line).
|
||
|
Subtype 1 [50] : If NOT equal, execute next 2 lines (else skip next 2
|
||
|
lines).
|
||
|
Sybtype 2 [90] : If NOT equal, execute all the codes below this one in the
|
||
|
same row (else execute
|
||
|
none of the codes below).
|
||
|
Subtype 3 [D0] : While EQUAL, turn off all codes (infinite loop on the
|
||
|
code).
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
------------------------------------
|
||
|
// Type 3 : If lower... (signed) // (can be called "30", "31" and "32")
|
||
|
------------------------------------
|
||
|
|
||
|
Signed means :
|
||
|
For Bytes : values go from -128 to +127.
|
||
|
For Halfword : values go from -32768/+32767.
|
||
|
For Words : values go from -2147483648 to 2147483647.
|
||
|
For exemple, for the Byte comparison, 7F (127) will be > to FFFFFFFF (-1).
|
||
|
You HAVE to enter a 32bits signed number as value, even if you just want to
|
||
|
make an halfword
|
||
|
comparison. That's because 0000FFFF = 65535, and FFFFFFFF = -1).
|
||
|
You could choose any value (for exemple, +65536 for halfword code, but the
|
||
|
result will be always True
|
||
|
(or always False if you choose -65537...).
|
||
|
|
||
|
3.y.x
|
||
|
-----
|
||
|
|
||
|
18XXXXXX YYYYYYYY
|
||
|
|
||
|
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
|
||
|
WARNING * WARNING *
|
||
|
|
||
|
If you used a "byte" size, this Type 3 code will actually be a "If lower...
|
||
|
(UNSIGNED)" !
|
||
|
That means, no signed comparison for byte values !!! (AR bug?)
|
||
|
|
||
|
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
|
||
|
WARNING * WARNING *
|
||
|
|
||
|
Subtype 0 [18] : If lower, execute next line (else skip next line).
|
||
|
Subtype 1 [58] : If lower, execute next 2 lines (else skip next 2 lines).
|
||
|
Sybtype 2 [98] : If lower, execute all the codes below this one in the same
|
||
|
row (else execute
|
||
|
none of the codes below).
|
||
|
Subtype 3 [D8] : While higher, turn off all codes (infinite loop on the
|
||
|
code).
|
||
|
|
||
|
|
||
|
|
||
|
Note 1 : For 8 and 16 bits codes, you *could* fill the unused numbers in the
|
||
|
Value to change
|
||
|
the encrypted code, and "sign" them (unverified).
|
||
|
|
||
|
|
||
|
|
||
|
------------------------------------
|
||
|
// Type 4 : If higher... (signed) // (can be called "40", "41" and "42")
|
||
|
------------------------------------
|
||
|
|
||
|
Signed means :
|
||
|
For Bytes : values go from -128 to +127.
|
||
|
For Halfword : values go from -32768/+32767.
|
||
|
For Words : values go from -2147483648 to 2147483647.
|
||
|
For exemple, for the Byte comparison, 7F (127) will be > to FFFFFFFF (-1).
|
||
|
You HAVE to enter a 32bits signed number as value, even if you just want to
|
||
|
make an halfword
|
||
|
comparison. That's because 0000FFFF = 65535, and FFFFFFFF = -1).
|
||
|
You could choose any value (for exemple, +65536 for halfword code, but the
|
||
|
result will be always True
|
||
|
(or always False if you choose -65537...).
|
||
|
|
||
|
|
||
|
4.y.x
|
||
|
-----
|
||
|
|
||
|
20XXXXXX YYYYYYYY
|
||
|
|
||
|
|
||
|
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
|
||
|
WARNING * WARNING *
|
||
|
|
||
|
If you used a "byte" size, this Type 4 code will actually be a "If lower...
|
||
|
(UNSIGNED)" !
|
||
|
That means, no signed comparison for byte values !!! (AR bug?)
|
||
|
|
||
|
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
|
||
|
WARNING * WARNING *
|
||
|
|
||
|
Subtype 0 [20] : If higher, execute next line (else skip next line).
|
||
|
Subtype 1 [60] : If higher, execute next 2 lines (else skip next 2 lines).
|
||
|
Sybtype 2 [A0] : If higher, execute all the codes below this one in the same
|
||
|
row (else execute
|
||
|
none of the codes below).
|
||
|
Subtype 3 [E0] : While lower, turn off all codes (infinite loop on the
|
||
|
code).
|
||
|
|
||
|
|
||
|
Note 1 : For 8 and 16 bits codes, you *could* fill the unused numbers in the
|
||
|
Value to change
|
||
|
the encrypted code, and "sign" them (unverified).
|
||
|
|
||
|
|
||
|
|
||
|
-------------------------------------
|
||
|
// Type 5 : If lower... (unsigned) // (can be called "50", "51" and "52")
|
||
|
-------------------------------------
|
||
|
|
||
|
Unsigned means :
|
||
|
For Bytes : values go from 0 to +255.
|
||
|
For Halfword : values go from 0 to +65535.
|
||
|
For Words : values go from 0 to 4294967295.
|
||
|
For exemple, for the Byte comparison, 7F (127) will be < to FF (255).
|
||
|
|
||
|
5.y.x
|
||
|
-----
|
||
|
|
||
|
28XXXXXX YYYYYYYY
|
||
|
|
||
|
|
||
|
Subtype 0 [28] : If lower, execute next line (else skip next line).
|
||
|
Subtype 1 [68] : If lower, execute next 2 lines (else skip next 2 lines).
|
||
|
Sybtype 2 [A8] : If lower, execute all the codes below this one in the same
|
||
|
row (else execute
|
||
|
none of the codes below).
|
||
|
Subtype 3 [E8] : While higher, turn off all codes (infinite loop on the
|
||
|
code).
|
||
|
|
||
|
|
||
|
|
||
|
--------------------------------------
|
||
|
// Type 6 : If higher... (unsigned) // (can be called "60", "61" and "62")
|
||
|
--------------------------------------
|
||
|
|
||
|
Unsigned means :
|
||
|
For Bytes : values go from 0 to +255.
|
||
|
For Halfword : values go from 0 to +65535.
|
||
|
For Words : values go from 0 to 4294967295.
|
||
|
For exemple, for the Byte comparison, 7F (127) will be < to FF (255).
|
||
|
|
||
|
|
||
|
6.y.x
|
||
|
-----
|
||
|
|
||
|
30XXXXXX YYYYYYYY
|
||
|
|
||
|
|
||
|
Subtype 0 [30] : If higher, execute next line (else skip next line).
|
||
|
Subtype 1 [70] : If higher, execute next 2 lines (else skip next 2 lines).
|
||
|
Sybtype 2 [B0] : If higher, execute all the codes below this one in the same
|
||
|
row (else execute
|
||
|
none of the codes below).
|
||
|
Subtype 3 [F0] : While lower, turn off all codes (infinite loop on the
|
||
|
code).
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
------------------------
|
||
|
// Type 7 : If AND... // (can be called "70", "71" and "72")
|
||
|
------------------------
|
||
|
|
||
|
(if the result of ANDing the IN GAME and IN CODE values is <>0)
|
||
|
|
||
|
7.y.x
|
||
|
-----
|
||
|
|
||
|
38XXXXXX YYYYYYYY
|
||
|
|
||
|
|
||
|
Subtype 0 [38] : If AND, execute next line (else skip next line).
|
||
|
Subtype 1 [78] : If AND, execute next 2 lines (else skip next 2 lines).
|
||
|
Sybtype 2 [B8] : If AND, execute all the codes below this one in the same
|
||
|
row (else execute
|
||
|
none of the codes below).
|
||
|
Subtype 3 [F8] : While NOT AND, turn off all codes (infinite loop on the
|
||
|
code).
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
* THE END *
|
||
|
|