mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-30 01:29:42 -06:00
an attempt to move docs to trunk. god tortoisesvn was an ass to do this with tortoisesvn and google code (core pdf was refused multiple times) NOTE: docs/WiiMote/Core V2.1 + EDR.pdf is still missing deu to googlecode hating me
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3491 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
955
docs/ActionReplay/GCNCodeTypes.txt
Normal file
955
docs/ActionReplay/GCNCodeTypes.txt
Normal file
@ -0,0 +1,955 @@
|
||||
|
||||
--------------------------------
|
||||
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 *
|
||||
|
Reference in New Issue
Block a user