
                        --------------------------------
                         GCN AR CODES TYPES EXPLANATION
                        --------------------------------

					v1.0  by kenobi

History :

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 NOOBS OR WANNABES. Sorry.
***************


Special Note 0 : All the numbers in this text starting with "0x" are HEXADECIMAL numbers.
***************  If you don't know what hexadecimal is, make a search on google...


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 like that : XXXXXXXX YYYYYYYY.
                 I called ADDRESS (in cap) the XXXXXXXX, and VALUE (in cap) the YYYYYYYY.


Special Note 3 : GCN memory range is 80000000 - 817FFFFF cached, and C0000000 - C17FFFFF uncached.
                 (don't ask what it means, I don't get it either :P).


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 : bits of type.
                    BB : bits of subtype.
                    CC : bits of value.

                 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
                 use to store some data while executing codes.


Special Note 7 : The address, values, and all the numbers startinf 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 start with 00000000 ("z" has been choosen for "zero").

For any "Type zX" codes : X = (VALUE >> 29) AND 0x03.


-------------------------------
// 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 "normally",
from the very 1st of the list.



------------------------------
// Type "z1" : UNUSED !!! //
------------------------------

To make it work, create a new game, call it something like "AR" or "Action Replay".
Enter this master code :

(m)
M106-KTDA-715MR
DP16-4D99-B8ANX

Then create a new code, and enter this long code Kenobi NCT
TV5V-U6WF-UV8EH
M561-6JVG-EK7KH
AD0Z-8J9W-Z8J99
6PZT-JJ6W-ZP5WG
299T-VTCX-A3XWJ
HRFA-HMB0-M48K3
MNJE-XBYW-5ZRMZ
3UHD-6CBM-3TK13
C9CY-MDPU-Z54TF
YKU4-G3CC-XZ5VK
V8X3-W4TD-T0P6K
NHH4-3BFD-VFNQE
B3K0-HCH9-9YA2D
QZMN-TKA2-TEEUG
A312-YVAM-7KE64
8YZC-FEGV-1JTJC
9424-PB35-K9WT6
8GHC-Z6TY-EUVUB
C7XP-K5EP-RZ2AU
2DGJ-9EWA-J5WXJ
1TP7-KQXG-Y0048
7D14-UBH1-WF7G5
QRFJ-00ZH-NP1QJ
Y268-1Y5U-QPTDT

To "enable" the "z1" code type, follow these steps :

  -Put the AR in the NGC.
  -Turn off/on the NGC.
  -Once the AR is loaded, select the "Kenobi NCT" code, and press start.
  -Just open and close the lid, and the AR will reboot.

Now, the "memory copy" and "slowdown" codes are enabled. All codes starting by "00000000 2XXXXXXX" will be
recognized as "z1" codes, and will have a specific effect.

Note 1 : This hack will not create any conflict with any existing code. It uses an "unused" code type.
Note 2 : You'll have to redo these steps each time you boot the AR to enable the new code type
         (if you plan to use them).

What are these new code types :

- Memory Copy :

00000000 2XXXXXXX
YYYYYYYY NNNNNNNN

XXXXXXX  : source address AND $1FFFFFF (for exemple, 813C0000 becomes 13C0000, 80054123 becomes 0054123).

YYYYYYYY : destination address (must be the full address, with the starting 8. Like 813D0000).

NNNNNNNN : number of bytes to copy - 1. (you shouldn't go over 0xFFFF, unless you know exactly what
           you're doing).

This Memory Copy code could also be used to fill a memory area with any data.
For exemple, let's say you want to fill 80010000 to 8001FFFF with the word 000000FF...
The normal rom/fill code would not work (because we're writing a 32bits data), and the "z4" slide code
could work, but will eat up 8 lines (you'll need 4 slide codes to fill this area !).

With the Memory Copy code, you just have to do this :

04010000 000000FF
00000000 20010000
80010004 0000FFFB

FFFB is obtained by doing (last address to write) - (first address to write), 8001FFFF-80010004.

But you can also fill a memory area with anything, like 11223344 55667711 22334455 66771122 33445566 77112233...
which is 11223344556677 copied over and over, and which is impossible to do with another code type.


- Slow Down :

00000000 220000NN

The AR will "loop" NN*65536 times each time this code is executed.
A NN value of about 20 gives a "good" slowdown (not too slow).
A NN value of FF will slow down big time the game (2 or 3 frames per seconds).

And of course, you can use a Joker code to trigger the slow down on/off...

The Slow Down codes should be the perfect test code to find out working Master Codes, as it should (will) work
for every single game !

Please remember that if you use these codes WITHOUT loading the "Kenobi NCT" code on the AR before,
they won't work (the 1st line will be skipped, and the 2nd line of the Memory Copy code will be executed,
which could create some "bugs" during the game).



--------------------------------------------
// Type "z2" : Normal execution of codes //
--------------------------------------------

1 line code.

00000000 40000000

Set register 1BB4 to 0.

It should mean the AR goes back to the normal execution of codes.
(it should break a "stop executing codes" set when register 1BB4 is = 2).


-----------------------------------------------------
// Type "z3" : Executes all codes in the same row //
-----------------------------------------------------

1 lines code.

00000000 60000000

Set register 1BB4 to 1.

It should means the AR will execute all codes without giving back the hand to the
game, unless register 1BB4 changes value.


-------------------------------
// Type "z4" : Fill & Slide //
-------------------------------

2 lines code.

00000000 8XXXXXXX
Y1Y2Y3Y4 Z1Z2Z3Z4


Address = 8XXXXXXX AND 0x81FFFFFF

Size = (address >> 25) AND 0x03

Value = Y1Y2Y3Y4

Address increment = Z3Z4 (signed! : min=-65536, max=+65535, 0x8000 = -65536)

NOTE : When using halfword (or word), make address increment >> 1 (or >> 2) when computing
       the code.

Value increment = Z1 (signed! : min=-128, max=+127, 0x80 = -128)

Number of codes to write = Z2 (unsigned! : min=0, max=+255, 0x80 = 127)


---------------------------------
// Type "z5" to "z7" : Unused //
---------------------------------

I asked Parasyte what can of code could be nice, and he answered me the "String Code".
So, there you are : the NGC AR string code

Please note that you CAN'T use the "Memory Copy + Slow down" ("z1") and this "String" code at the same time.
You'll have to make a choice...

Just add this code below the "Kenobi NCT" Code :

Kenobi String Code
GHTP-U93K-8T42W
N7QC-J8C9-CFT0R
GU1H-4GAM-10PQG
ZHCG-3JD6-585FQ
299T-VTCX-A3XWJ
N3NE-J17U-VNMF4
MNJE-XBYW-5ZRMZ
3UHD-6CBM-3TK13
C9CY-MDPU-Z54TF
YKU4-G3CC-XZ5VK
V8X3-W4TD-T0P6K
NHH4-3BFD-VFNQE
Q20Y-8611-ZM0R8
M4J1-X153-WZV2C
E9FX-K7WE-EYPRD
7Y9Z-UU3T-EV9Q0
BERP-TPUR-C8K78
Y7GW-548T-AX56V
YT8C-YWTN-P861J
XX81-XDBJ-BDWF4
F8T9-AH6B-ZGEYY
YNKQ-CW2K-6N8CD
Y268-1Y5U-QPTDT

How does it work? Answer :

- String Code :

00000000 A1A2A3A4
X1X1X1X1 X2X2X2X2
X3X3X3X3 X4X4X4X4
...


A1A2A3A4 : It's the Destination Address, on which A1 isn't "80", but ["C0" OR (NN*2)].
NN is a number between 0 and 31 (0 and 0x1F).

X1X1X1X1, X2X2X2X2... are the data to write.

This code will write NN+1 words to the destination address (that means you can write up to 32 words,
using 17 lines instead of 32 with the normal ram write).

Exemple :
00000000 C8030000
01010101 02020202
03030303 04040404
05050505 00000000

The destination adress is 80030000, and NN is 4.
So the code will write 5 (NN+1) words to address 80030000.
More precisely, it'll write 01010101 at 80030000, 02020202 at 80030004, 03030303 at 80030008,
04040404 at 8003000C, 05050505 at 80030010.
And it'll skip the last word ("00000000"), which is only used to pad the data.









                                ________________
                                ----------------
                                | Normal Codes |
                                ----------------



For any "Normal Codes", you have :

Type = (ADDRESS >> 27) AND 0x07

Subtype = (ADDRESS >> 30) AND 0x03

Size = (ADDRESS >> 25) AND 0x03

(usually, Size 0 = 8bits, Size 1 = 16 bits, and Size 2 = 32 bits)

I give summary of each code type/subtype/size at the start of this description with the numbers "T.y.x"

T is the code Type (goes from 0 to 7)

y is the cude Subtype (goes from 0 to 3)

x is the code Size (0 = byte, 1 = halfword, 2 = word, 3 = special).



------------
// 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 (0.0.0) :
  fills area [Address to (Address + Y1Y2Y3)] with value Y4.

If Size = 1 (0.0.1) :
  fills area [Address to (Address + (Y1Y2 * 2))] with value Y3Y4.


If Size = 2 (0.0.2) :
  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 word 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 an address.
If it is one, it will add an offset to it, and will write the data provided within
the code to this new address.


If Size = 0 (0.1.0) (40XXXXXX or 41XXXXXX) :
AR will write byte Y4 at [Pointer Address + Y1Y2Y3].

If Size = 1 (0.1.1) (42XXXXXX or 43XXXXXX) :
AR will write halfword Y3Y4 at [Pointer Address + (Y1Y2 * 2)].

If Size = 2 (0.1.2) (44XXXXXX or 45XXXXXX) :
AR will write word Y1Y2Y3Y4 at [Pointer Address].



-----------------------
// 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 (0.2.0) (80XXXXXX or 81XXXXXX) :
  Load byte stored at [Address], add Y1Y2Y3Y4 to it, and store the resulting byte
  (= result AND 0xFF) at [Address].

if Size = 1 (0.2.1) (82XXXXXX or 83XXXXXX) :
  Load halfword stored at [Address], add Y1Y2Y3Y4 to it, and store the resulting halfword
  (= result AND 0xFFFF) at [Address].

if Size = 0 (0.2.2) (84XXXXXX or 85XXXXXX) :
  Load word stored at [Address], add Y1Y2Y3Y4 to it, and store the result at [Address].



----------------------------------------------
// 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 = ((0xCwXXXXXX) AND 0x01FFFFFF) OR 0x80000000)

Size = (Address >> 25) AND 0x03



If Size = 2 (0.3.2) : Master Code (C4XXXXXX Y1Y2Y3Y4) :
-------------------------------------------------------

Y4 = ? (an "order" number to make the master code execute only once...?)

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.
        (Save : R0 R3 R28 R29 R30 R31)


Note : Putting random numbers in Y1 should change the encryption, thus "signing" your
       code (untested).



If (Size = 3) AND (address < 0x01000000) (0.3.3): Write to CCXXXXXX (C6XXXXXX Y1Y2Y3Y4) :
-----------------------------------------------------------------------------------------

Address = 0xCCXXXXXX
Stores halfword Y3Y4 at Address.

Note : Putting random numbers in Y1Y2 should change the encryption, thus "signing" your
       code (untested). 







                                   * THE END *

