Guides:TMless 0x1500 ACE (JP): Difference between revisions
Jump to navigation
Jump to search
no edit summary
No edit summary |
|||
(32 intermediate revisions by the same user not shown) | |||
Line 3:
This page serves as a repository on a 0x1500 ACE setup for the Japanese versions of Pokémon Crystal. It is part of the [[Guides:TimoVM's_gen_2_ACE_setups|TimoVM's Gen 2 ACE setups]] set of guides.
The setup requires catching a Spearow during day time.
If you encounter any issues when going through this guide or would like to provide feedback, please contact TimoVM on the [https://discord.gg/EA7jxJ6 Glitch City Research Institute Discord].
Line 11:
'''When playing on cartridge or emulator, it is required to have previously cleared an old save by pressing SELECT + UP + B simultaneously on the start screen at least once since obtaining the cart. Otherwise you will not be able to obtain a bad clone or an unterminated name pokémon.'''
=Setting up initial ACE=
Pokémon Crystal contains two important differences compared to its predecessors. Firstly, Crystal won't abort the text printing function when it encounters a $00 value,
By obtaining a pokémon whose name does not contain the usual text terminator, we can force the game into printing much larger amounts of texts than would otherwise be possible. By abusing an illegal Mobile Adapter function and setting up memory in a specific way with help of a Spearow, we can escape the text printing function and trigger arbitrary code execution based on
In practice, the initial ACE setup will be created using the following general process:
Line 26:
At the moment, this guide is incompatible with saves exported from PKHex. Upon exporting a save, PKHex will fill all currently unused data for the OT name and nickname of all boxes with text terminators, making it impossible to obtain an unterminated name pokémon.
Setting up initial ACE and installing the Mail Writer=
==Step 1:
* (optional) When starting from a new game, set the in-game time to either morning or midday. You are free to pick any starter, trainer name and/or rival name.
* Catch or obtain a Spearow.
** When using an existing save, either catch any Spearow or obtain the nicknamed Spearow from the gate guard between Goldenrod City and Route 35.
==Step 2: Preparing the bad clone and remaining items==
# Use the bad clone glitch to obtain a pokémon with an unterminated name.
## For this, use a box that has never been full at any point in time. It’s recommended to start with an empty box.
## Deposit a single pokémon. Attempt to save the game using "Move Pokémon w/o mail" but reset the game a bit just after the game has fully printed "SAVING... DON'T TURN OFF THE POWER".
## After rebooting the game, '''open and close the item pack''', then check the newly deposited pokémon.
## If the newly deposited pokémon’s nickname was changed to a bunch of question marks, you can continue with the next step. If the pokémon wasn't saved, that means the reset too early. If the pokémon was cloned, this means the reset was too late.
## If the
# Now that you have an unterminated name pokémon, '''put it in box
# Finally,
While we now have everything ready to execute box name codes using ACE, the setup will have a few drawbacks:
* Executing ACE requires performing various specific steps, preventing us from using ACE whenever we want.
* Box name codes have a limited size, due to only having access to 9 different boxes. Effectively meaning that it's impractical to set up more complicated ACE effects.
To resolve this issue, we're going to install the Mail Writer. This is a box name program that will allow us to quickly and efficiently write and execute any arbitrary code we want. Once we've set up the Mail Writer, we'll never have to swap bpx names again.
To do that, we're going to use a box name code that does the following:
- It will alter box #7's name so that the Mail Writer can be used afterwards.
- It will change the first item in the main item pocket to a TM15
- It will modify data to ensure that using this TM15 will allow us to use the mail writer
This will allow us to easily write and execute large amounts of arbitrary code, simply by using a TM15 at any time.
==Step 3: Setting up the Mail Writer==
We're going to both finish the setup and use it install a Mail Writer program. The Mail Writer is a small program that is written using box name codes and will allow you to easily write arbitrary data in order to achieve numerous effects.
Rename all boxes to the following names:
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
|
[[File:Box Japanese C
|}
Upon using 0x1500 ACE, this box code will be executed and will replace the first item of the main item pocket with a TM15. Alongside that, it will install a setup so that using this TM15 will execute box name codes. Finally, it will write a $38 value to box #7's name, to allow the Mail Writer to properly function.
Once that is done, you can use TM15 at any time to run the Mail Writer. More details on the Mail Writer can be found in the next guide.
==Step
Before executing ACE, arrange your party as follow:
* Slot 1 - Spearow
*
Make sure that box 3 is set as the current active box, make sure that the unterminated name pokémon is the only pokémon present in box 3.
In order to execute ACE, do the following actions:
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
|
[[File:JP ACE PokeSen Location.png]]
||
[[File:JP ACE Spearow menu.png]]
|}
# Stand in front of the PC on the second floor of any pokémon center. Take one step down, take one step left until you end up at the location indicated by the above screenshot on the left. '''Save the game here and reset.'''
# After reloading the save, take one step to the right and take one step up. You should now be standing right in front of the PC. (these steps need to be taken in the correct order, otherwise the setup will not work)
# Open the start menu, select Spearow so that you get the option to look at its summary and switch its party position as indicated by the above screenshot on the right, then exit and close the start menu.
# Open the PC. Open the withdraw screen so that the unterminated name pokémon's name would be displayed. Displaying this name will trigger ACE. If the screen stays white, press "A" a couple of times until the box view reappears.
If the game doesn't crash, the setup was a success. You should now have a TM15 in the main item pocket, the name of box 7 has now been changed.
==Step
Lastly, rename the names of boxes #3 through #6 so that all box names fit the following image. '''Make sure to not change the names of box #7.'''
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
|
[[File:Box Japanese C After Setup.png]]
|}
Once this is done, you have completed the setup and have installed the Mail Writer. '''You can now simply use TM15 at any time to start up the Mail Writer, regardless of your location or the pokémon in your party.'''
===How the mail writer works===
Upon execution, the Mail writer will open the mail character entry screen where the player can write up to 32 different characters. After the player has confirmed the mail, the following actions take place:
* The Mail writer will take pairs of characters and convert them into a single combined value. These values are then sequentially written, converting the 32 letter mail into a 16 byte long line of code.
* Next, the Mail writer will display a checksum calculated from the combined value of all written bytes for the player to verify. Then the program enters a waiting state where they can either choose to write another mail, go back and correct previously written values or stop the mail writer and execute the newly written payload.
* If the player has chosen to write a new mail, the Mail writer will open a new mail entry screen. The new mail is then also converted into a 16 byte lond line of code and placed right after the code written by the previous mail(s), allowing the player to write arbitrarily long payloads.
==Step 6: Using the Mail writer==
The mail writer will open a screen that asks you to write the contents of a mail. This is where you'll need to enter mail codes. Once done, use the "END" option to finish the mail.
This will cause the mail writer to convert the newly written code into assembly. It will also '''print a checksum''' (sum of all written values) on the lower left corner of the screen. This can be used to verify if a code was entered correctly.
Assembly can easily be converted to mail codes using [https://timovm.github.io/MailConverter/ TimoVM's MailConverter]. Simply paste the assembly of the code you wish to enter here, press "run" and the converter will automatically generate mail codes requiring the least amount of button presses to write. A list of ready-to-use codes will be provided at the end of the guide.
===Controls===
Between entering mail codes, the mail writer will ask for user input.
* '''Press B''' to immediately jump to and start executing the newly written program. '''Only use this when you've finished every mail.'''
* '''Press DOWN''' to go back one byte at a time to correct errors. '''If the printed checksum doesn't match the expected checksum, press DOWN 16 times to retry the last mail.''' This will also overwrite the printed checksum with the value at the currently selected address, giving you a method to check how far back you're going.
* '''Press any other button''' to open a new mail and continue writing data.
'''Due to space limitations, it is not possible to exit the Mail Writer without executing the newly written code. If you accidentally start the Mail Writer, you can safely exit by writing a mail with the contents "セス" and execute it.'''
=
The Mail writer allows you to easily write and execute arbitrary payloads. Aside from writing your own codes, we recommend the following:
* [[User:TimoVM/Mail Writer Codes|Mail codes]]: this page contains a collection of assembly for mail codes that can be used for a variety of common purposes such as editing pokémon, obtaining items, etc..
* [[User:TimoVM/RAM Writer|RAM writer]]: (recommended for more experienced users) this page contains the assembly for a large one-size-fits all program that allows you to edit any value in RAM with a user-friendly GUI. It will also fix the side effects of the ACE setup when you first run it.
=Appendix
==
* 0x1500 Control Code ACE box name code
<pre>ヅ あ め ゆ ゆ が ぜ ぜ
ゆ げ ぜ ェ ぼ オ ま ぜ
ョ に ろ て エ ろ
が れ ぜ デ づ に セ づ
ぼ て づ に ジ ゥ キ リ
よ ヌ ゥ モ ろ ゅ ゅ の
ビ ヘ チ チ が ビ ブ ギ
ぜ セ げ ま き ぐ ァ よ
め ヤ ろ ダ ダ リ だ え
</pre>
* Mail Writer
<pre>が ヅ あ め ゆ ゆ が ぜ ぜ
ゆ げ ぜ ェ ぼ オ ま ぜ
き き む ゅ ご き き よ
ぐ デ だ ガ ご き き よ
キ デ ド ア ぺ デ ご ?
だ ! ズ が な ぜ ォ ギ
ビ ヘ チ レ ッ ド が ビ ブ ギ
ぜ セ げ ま き ぐ ァ よ
め ヤ ろ ダ ダ リ だ え</pre>
==In-depth explanation of the setup==
===Explanation on the 0x1500 ACE setup===
This setup uses [[0x1500 control code arbitrary code execution|0x1500 control code ACE]]. Since the page already contains an explanation on how it works, this page will focus on what the setup does to achieve its effect.
Relevant addresses for this explanation:
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
! Address !! Function
|-
| $D05B || Address where the names of pokémon and items are buffered.
|-
| $D0C8 || Address where the current selected party pokémon’s species is buffered.
|-
| $D0C9 || Address where the current selected party pokémon’s party slot is buffered (zero indexed).
|}
* Resetting the game clears the contents of the text buffer, which would cause an undesired early termination of the unterminated pokémon's name
* Resetting the game also resets a bunch of nearby values that are related to selected item IDs, quantities and amounts to be tossed.
* Selecting Spearow in the party menu will buffer its species ID ($15) to $D0C8 and party slot ($00) to $D0C9.
* When the text printing function encounters a $15 value, it will attempt to execute a Mobile Adapter related function. The selected function depends on the next read value, but $00 is an invalid Mobile Adapter function and will instead call $CD46.
* By opening the start menu and moving one step right and one step up at a specified location, the game will load in a $C2 9B C4 (jp nz, $C49B) at $CD64. Due to the tile contents of the 2nd floor of the pokémon center, the area between $CD46 and $CD64 will be filled with $00 values, allowing safe passage.
* Viewing the unterminated clone through the withdraw screen will cause the game to attempt to do a lot of stuff at once.
*# The withdrawn screen is set up and the current active box's name is displayed.
*# The unterminated name pokémon's name will be drawn on screen, which leads to a buffer overflow.
*# After printing the name for a while, the game will attempt to print the $15 value that is buffered at $D0C8, which causes it to enter the mobile function mode.
*# Immediately after this, it will encounter a buffered $00 value at $D0C9, causing a call to $CD46 and activating ACE
* After arriving at $CD46, execution will nopslide to $CD64, where it will use the buffered data to jump to $C49B, which lies right before screen data.
===Effect of screen data===
Once execution arrives at $C49B, execution will nopslide until it encounters the following values at $C4A0:
<pre>
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7B ld a, e
79 ld a, c
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7A ld a, d
7B ld a, e
7C ld a, h
00 nop
07 rlca
0E 15 ld c, 15
1C inc e
23 inc hl
2A ldi a, (hl)
7C ld a, h
7C ld a, h
7F ld a, a
7F ld a, a
7F ld a, a
7F ld a, a
7F ld a, a
7F ld a, a
7F ld a, a
7F ld a, a
7F ld a, a
7C ld a, h
7C ld a, h
01 08 0F ld bc, $0F08
16 1D ld d, 1D
24 inc h
2B dec hl
7C ld a, h
7C ld a, h
AF xor a ; a = $00, name of the current active box is printed here
C6 DB add $DB ; a = $DB
C3 83 DB jp $DB83 ; 1st character of box name #4
</pre>
===Effect of the box name code===
In the context of 0x1500 Control Code ACE, only box name #3 through box name #6 are executed. Box name #1, #2 and #7 through #9 are part of the Mail Writer and will be discussed in the section after this section:
<pre>
Box 3: $DB7A ; Executed as part of screen data, see previous section
AF xor a ; a = $00
C6 DB add $DB ; a = $DB
C3 83 DB jp $DB83
26 DA ld h, $DA
2E 12 ld l, 12
3E DB ld a, $DB ; a = $DB
C6 50 add $50 ; a = $2B
Box 4: $DB83 ; Landing point after screen data
26 DA ld h, $DA
2E 12 ld l, 12
32 ldd (hl), a
32 ldd (hl), a
Box 5: $DB8C
3E C3 ld a, $C3 ; a = $C3
32 ldd (hl), a
EA 86 D8 ld(wItems), a
50 ld d, b
Box 6: $DB95
D6 96 sub $96 ; a = $38
EA A1 DB ld($DBA1), a
E1 pop hl
E1 pop hl
C9 ret
</pre>
===Effect of the
Converting the
<pre>
Line 233 ⟶ 311:
29 add hl, hl ; hl = $5CA0
2E EB ld l, $EB ; hl = $5CEB
3E
CF rst08h ; farCall _ComposeMailMessage (a:hl = 04:5CEB), most significant bit gets ignored when changing ROM banks
Box 3: $DB7A
B7 or a
B7 or a
D1 pop de
E1 pop hl ; Set both hl and de to the start of the newly written mail
Line 267 ⟶ 344:
Box 6: $DB95
30
0C inc c ; .terminator, _ComposeMailMessage sets bc to 0000, so c = 01 after this part
26 C5 ld h, $C5
Line 275 ⟶ 352:
Box 7: $DB9E
1A ld a, (de)
CD 90 38 call PrintBCDNumber.loop + 01h ; PrintBCDNumber.loop itself can't be reached, so we skip forward one byte. $38 is written by the previous box name code.
26 1A ld h, $1A ; .errorCorrection
1B dec de ; Calling PrintBCDNumber.loop with c = 01 advances de by 1.
06 50 ld b, $50
Box 8: $
2E 8D ld l, $F4 ; hl = $1A8D
29 add hl, hl ; hl = $351A (address of JoyTextDelay_ForcehJoyDown)
Line 286 ⟶ 363:
B7 or a, a ; Are any buttons pressed? if not, ask for new button states
28 E9 jr z, .terminator
D6 50 sub $50 ; if down is pressed, carry is reset if any other button is pressed, carry is set
Box 9: $
D2 A2 DB jp nc, .errorCorrection
0F rlca
0F rlca ; Is the b button pressed? If yes, carry is set
D8 ret c ; Exit and execute code if B is pressed. Else, start new mail
30 B4 jr nc, .loop
</pre>
[[Category:Guides]]
|