• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Guide to AR and Gecko Code writing for complete noobs

ResidentWaffle

Smash Lord
Joined
Jan 22, 2006
Messages
1,125
Location
UCLA
Guide to AR and Gecko Code writing

NOTE: This guide is UNCOMPLETED, I wrote only on AR codes and I will finish later. For now this is mainly a guide on how to get started writing codes so take it for what you will. Also please point out errors in the guide if you see them.

If you don't know anything about programming don't fear! I'll explain the basics so you can get an idea of how codes are written.

1. Basic Hexadecimal and Programming logic.(Read if you know nothing about programming).

a. Hexadecimal

You've all probably heard of computer programming and thought about the 1s and 0s but most of that is used for very low level computer language. What is low level computer language? Basically the more low level a computer language is the easier it is for a computer to understand the code, the higher the level the more easy(it should be)for a human to understand. The trade-off is that if you understand low level language you are usually able to do more optimization but a higher level language is much, much, much easier to write. I'd say Action replay and Gecko OS codes are slightly more low level than common computer languages like C++ and Java but more more higher level than any type of assembly language. What is an assembly language? Any type of computer operates by a bunch of reads and writes to its memory addresses. Assembly language is basically a series of instructions for the computer to read and write to memory addresses. Action replay and Gecko codes operate by using simple programming logic to modify these memory address much like assembly language but they are much simpler(Any type of programming language modifies memory addresses but higher level ones often do so in much more indirect ways). Like most assembly code Action Replay and Gecko codes are written using a hexadecimals. While the numbering system you were taught in elementary school(the decimal system) is a base 10 numbering system, Hexadecimal is a base 16 numbering system. This means that hexadecimal cycles 0 to 16 before it cycles around whereas the decimal number system operates from 0 to 10 before it cycles. Another way you can think of this is that the hexadecimal numbering system is a clock that operates from 0 to 16 while the decimal number system is a 0 to 10 clock(Note we include 0 and do not start at 1 like conventional clocks). Why is this numbering system used? First, its just the normal convention and second many computer memory addresses operate in factors of 8 so a number system based on 16(8 x 2) makes it much easier to write code.

The digits in a hexadecimal writing system are:

0 1 2 3 4 5 6 7 8 9 A B C D E F

So in a full cycle after F you return to 0. So what happens if you have 0xF + 0x9 and you want to express the bigger number?(The 0x is just a common convention to represent the hexadecimal writing system, 0b is used to represent the binary writing system i.e. 0b011100). You can actually test this by typing that exact equation into a a Google search(which I use frequently). If you do so you get 0x18, remember this is not the regular decimal number 18, it is the hexadecimal 18, which is why I called it 0x18, which corresponds to the decimal number 24, you can also check this by Google searching "0x18 in decimal". Now that you get the basics of hexadecimal we can move on to programming logic.

b. Programming Logic

Every type of programming language has its own type of logic, however, there is basic logic used by almost every programming language. The first if the if statement. Essentially the if statement works by executing a series of code if the if statement condition is met. For instance, if memory address 0x198912 is equal to 0x10 then change the value it stores to 0x11. This can be written as:

if (0x198912 is equal to 0x10)
{
0x198912 = 0x11
}

for easy readability, where the parenthesis () contain the condition and the curly brackets {} contain the code to be executed. Note this use of indentation, while doesn't seem to do much, it is common type of indentation that greatly improves readability and can very useful when your code gets more complicated and you want to see quickly and easily how your code operates. Now that you can write your code, it is important to understand how it works. Here we use an if statement, if statements operate only once unless there is a loop that returns to it. A statement that operates more than once is a while statement. For instance:

while (0x198912 > 0x0)
{
0x198912 = *0x198912 - 0x1
}

First note the use of *. I use * to denote the value stored at the address specified. Therefore function means that while the value at 0x198912 is greater than zero subtract one. Now unlike the if statement above this function will essentially operate not just once but until 0x198912 equals 0. Now while this sounds safe sometimes something unexpected can go wrong so we include safeguards.

while (0x198912 > 0)
{
0xA = 0x198912
if (*0xA == 0x0)
{
End Loop
}
0x198912 = *0xA - 0x1
}

Note that this safeguard will end the loop if 0xA is equal to 0x0 so that we do not get negative numbers. Also note that we use a value 0xA to store the address which stores our modified value for easy reference and readability. These type of memory addresses are called pointers. In other words they point to other memory addresses and not values. Note, pointers are just terms for memory addresses meant to store values that correspond to other memory addresses and they are not usually any different than any other memory address. I would explain more but since pointers are a mildly difficult subject I'll leave it up to you to find out more about it if you're curious. Also note the use of == and not =, this is not a mistake. == is often used to denote check if a memory address is equal something to while = is used to assign a value. For example the set of statements:

{
0x5 = 0xC
0x5 == 0x1
0x6 = 0x1
}

Makes 0x5 equal to 0xC(or decimal 12) and 0x6 equal to 0x1. The second statement does nothing it just checks to see if 0x5 is equal to 0x1.

Now what if you want mulitple conditions for one statement? You could just write multi-tiered statements like this:

{
if (0xA == 0x3)
{
0xA = 0x0
}
if (0xA == 0x5)
{
0xA = 0x0
}
}

As you can see now indentation becomes very important to demonstate how your code works! However, this way of writing code is tedious and uncesscary. Instead write:

if (0xA == 0x3 | 0xA == 0x5)
{
0xA = 0x0
}

The | symbol represents an Or statement. In other words, if 0xA is equal to 0x3 or is equal to 0x5 than set it equal to 0x0.

Now what if you want to be more expressive? You can include conditionals such less than, greater than, less than or equal to, greater than or equal to, is not equal to(labeled, <, >, <=, >=, !=, respectively) and actually be quite expressive( or as expressive as we need to be to write codes).

Now that you get the basics of hexadecimal and programming logic you can understand how most of AR and Gecko Codes operate. On the explanation of how to write those codes.

2. AR Codes

a.Writing an AR code

AR codes can be written using basic programming logic and be converted into an AR code using a simple conversion program like GCncrypt. Essentially AR codes are statement that are 16 hexadecimals long that preform reads and writes to memory addresses.

The code

00000001 00000002

Will write 0x2 to memory address 0x80000001.

Now I know what you're saying how did we get address 0x80000001 and not 0x1? Well the GameCube operates with memory addresses starting from 0x80000000 all the way until 0x81FFFFFF. Only 6 hexadecimals (The third through eighth ones) are used to provide a memory address. The first two hexadecimals are used to issue an instruction. 00 is the write instruction and assumes the first two digits of the memory address are 80. But what if we want to write to an address starting with 81? If simply add one to the first to hexadecimals that is, 01 is the write instruction to an address starting with the first two digits 81.

So the instruction

01000001 00000002

Will write 0x2 to memory address 0x81000001 and not 0x80000001. Actually 00 and 01 are 8-bit write and not just write that means the code:

01000001 11111112

Does not write 0x11111112 to memory address 0x81000001. In 8-bit write only the last two hexadecimals are written, the previous six are the number of times additional times the command is issued to consecutive memory addresses starting at the memory address after the one you specified. So

01000001 11111112

Writes 0x12 to memory address 0x81000001, memory address 0x81000002, memory address 0x81000003, etc, for a total of 0x111111(or 1118481) + 1 writes. So this means this AR code is actually written in the format:

IIAAAAAA TTTTTTVV

Where I = Instruction, A is memory address to start from, T equals number of additional time to execute, and V equals the value to use. Note that this is an 8-bit AR code. A 16-bit AR code would actually be in the format IIAAAAAA TTTTVVVV and a 32-bit AR code in the format IIAAAAAA VVVVVVVV So something like:

04000001 11111112

would actually write 0x11111112 to memory address 0x80000001 as would 05000001 11111112 write 0x11111112 to memory address 0x81000001 because 04 is the 32 bit write instruction. These are the basics, I will expand upon this later, but for now here are a the list of instructions AR contains.
B. Instructions (The last numbers follow the instruction name)

Commands:

Write 8-bit 00
Write 16-bit 02
Write 32-bit 04
Struct Write 8-bit 40
Struct Write 16-bit 42
Struct Write 32-bit 44
*RAM Fill and Slide 8-bit 00xxxxxx 80xxxxxx
*RAM Fill and Slide 16-bit 00xxxxxx 80xxxxxx
*RAM Fill and Slide 32-bit 00xxxxxx 80xxxxxx
Signed Increment/Decrement 8-bit 80
Signed Increment/Decrement 16-bit 82
Signed Increment/Decrement 32-bit 84
*Signed Increment/Decrement Extended 86

Conditionals:

If Equal Then Execute Next Line 8-bit 08
If Equal Then Execute Next Line 16-bit 0A
If Equal Then Execute Next Line 32-bit 0C
If Equal Then Execute Next 2 Lines 8-bit 48
If Equal Then Execute Next 2 Lines 16-bit 4A
If Equal Then Execute Next 2 Lines 32-bit 4C
*If Equal Then Execute All Until 8-bit 88
*If Equal Then Execute All Until 16-bit 8A
*If Equal Then Execute All Until 32-bit 8C
If Equal Then Execute Remaining Lines 8-bitC8
If Equal Then Execute Remaining Lines 16-bit CA
If Equal Then Execute Remaining Lines 32-bit CC
---
If Not Equal Then Execute Next Line 8-bit 10
If Not Equal Then Execute Next Line 16-bit 12
If Not Equal Then Execute Next Line 32-bit 14
If Not Equal Then Execute Next 2 Lines 8-bit 50
If Not Equal Then Execute Next 2 Lines 16-bit 52
If Not Equal Then Execute Next 2 Lines 32-bit 54
*If Not Equal Then Execute All Until 8-bit 90
*If Not Equal Then Execute All Until 16-bit 92
*If Not Equal Then Execute All Until 32-bit 94
If Not Equal Then Execute Remaining Lines 8-bit D0
If Not Equal Then Execute Remaining Lines 16-bit D2
If Not Equal Then Execute Remaining Lines 32-bit D4
---
If Less Then Execute Next Line 8-bit(signed) 18
If Less Then Execute Next Line 16-bit(signed) 1A
If Less Then Execute Next Line 32-bit(signed) 1C
If Less Then Execute Next 2 Lines 8-bit(signed) 58
If Less Then Execute Next 2 Lines 16-bit(signed) 5A
If Less Then Execute Next 2 Lines 32-bit(signed) 5C
*If Less Then Execute All Until 8-bit(signed) 98
*If Less Then Execute All Until 16-bit(signed) 9A
*If Less Then Execute All Until 32-bit(signed) 9C
If Less Then Execute Remaining Lines 8-bit(signed) D8
If Less Then Execute Remaining Lines 16-bit(signed) DA
If Less Then Execute Remaining Lines 32-bit(signed) DC
---
If Greater Then Execute Next Line 8-bit(signed) 20
If Greater Then Execute Next Line 16-bit(signed) 22
If Greater Then Execute Next Line 32-bit(signed) 24
If Greater Then Execute Next 2 Lines 8-bit(signed) 60
If Greater Then Execute Next 2 Lines 16-bit(signed) 62
If Greater Then Execute Next 2 Lines 32-bit(signed) 64
*If Greater Then Execute All Until 8-bit(signed) A0
*If Greater Then Execute All Until 16-bit(signed) A2
*If Greater Then Execute All Until 32-bit(signed) A4
If Greater Then Execute Remaining Lines 8-bit(signed) E0
If Greater Then Execute Remaining Lines 16-bit(signed) E2
If Greater Then Execute Remaining Lines 32-bit(signed) E4
---
If Less Then Execute Next Line 8-bit(unsigned) 28
If Less Then Execute Next Line 16-bit(unsigned) 2A
If Less Then Execute Next Line 32-bit(unsigned) 2C
If Less Then Execute Next 2 Lines 8-bit(unsigned) 68
If Less Then Execute Next 2 Lines 16-bit(unsigned) 6A
If Less Then Execute Next 2 Lines 32-bit(unsigned) 6C
*If Less Then Execute All Until 8-bit(unsigned) A8
*If Less Then Execute All Until 16-bit(unsigned) AA
*If Less Then Execute All Until 32-bit(unsigned) AC
If Less Then Execute Remaining Lines 8-bit(unsigned) E8
If Less Then Execute Remaining Lines 16-bit(unsigned) EA
If Less Then Execute Remaining Lines 32-bit(unsigned) EC
---
If Greater Then Execute Next Line 8-bit(unsigned) 30
If Greater Then Execute Next Line 16-bit(unsigned) 32
If Greater Then Execute Next Line 32-bit(unsigned) 34
If Greater Then Execute Next 2 Lines 8-bit(unsigned) 70
If Greater Then Execute Next 2 Lines 16-bit(unsigned) 72
If Greater Then Execute Next 2 Lines 32-bit(unsigned) 74
*If Greater Then Execute All Until 8-bit(unsigned) B0
*If Greater Then Execute All Until 16-bit(unsigned) B2
*If Greater Then Execute All Until 32-bit(unsigned) B4
If Greater Then Execute Remaining Lines 8-bit(unsigned) F0
If Greater Then Execute Remaining Lines 16-bit(unsigned) F2
If Greater Then Execute Remaining Lines 32-bit(unsigned) F4
---
If Bitwise AND Then Execute 8-bit 38
If Bitwise AND Then Execute Next Line 16-bit 3A
If Bitwise AND Then Execute Next Line 32-bit 3C
If Bitwise AND Then Execute Next 2 Lines 8-bit 78
If Bitwise AND Then Execute Next 2 Lines 16-bit 7A
If Bitwise AND Then Execute Next 2 Lines 32-bit 7C
*If Bitwise AND Then Execute All Until 8-bit B8
*If Bitwise AND Then Execute All Until 16-bit BA
*If Bitwise AND Then Execute All Until 32-bit BC
If Bitwise AND Then Execute Remaining Lines 8-bit F8
If Bitwise AND Then Execute Remaining Lines 16-bit FA
If Bitwise AND Then Execute Remaining Lines 32-bit FC
-----------------------------------------------------------------------------------------------------------------------------------------------
Notes:
*All until commands will execute all the following lines until a line 00000000 40000000 is reached.
*Signed/Unsigned - Sometimes values are meant to be stored as signed values which is a different numbering system than unsigned values. For instance, signed
0x00000000 to 0xFFFFFFFF includes the range of 0 to 4294967295 while unsigned 0x00000000 to 0xFFFFFFFF is the range of 0 to -1. Here 7FFFFFFF = 2147483647 while
0x80000000 equals -2147483648. This only applies to the instruction and not the memory address as the memory address cannot be negative.
*Bitwise AND checks to see if the bitwise and operation works and then executes. More explanation will be provided once I get around to it.
*RAM Fill and Slide is a two line code
*Will explain Extended later.
*I will go into detail soon how each command works such as Struct and RAM Fill and Slide work in another update.
-----------------------------------------------------------------------------------------------------------------------------------------------
3. Gecko Code
4. Where To Find Memory Addresses For Code
5. Using Your Code
 
Top Bottom