User:TimoVM/RAM Writer setups: Difference between revisions

From Glitch City Wiki
Jump to navigation Jump to search
Content added Content deleted
Line 897: Line 897:


===What to do in case you sell too much of a TM===
===What to do in case you sell too much of a TM===
If you accidentally sell too much any TM, you can use the following code to set that TM back to x255:
If you accidentally sell too much any TM, you can use the following box name code to set that TM back to x255:


{| class="wikitable"
{| class="wikitable"

Revision as of 17:12, 5 May 2023

This page serves as a repository for various RAM writer setups, written and developed by TimoVM, intended for gen 1 or gen 2. the RAM writers used are inspired by various pre-existing RAM writers, especially ZZAZZGlitch's memory writer.

Introduction: What is a RAM writer?

In simple terms, a RAM writer is a program that allows you to visualize and edit values that are stored in memory. In effect, this allows you to easily manipulate stuff like adding/modifying items, changing pokémon data such as making them shiny, triggering instant encounters etc.. This is usually combined with a graphical user interface (GUI) for better readability.

In a sense, you can regard RAM writers as a general tool to greatly expand what you can do with arbitrary code execution, due to granting the ability to easily modify any memory value in RAM at any time.

An unfortunate drawback of this approach is that RAM writers are quite large, memory-wise. For this reason, this guide was developed to document methods to install these RAM writers in a reasonably efficient way. Due to their size, you will always be required to start with building a smaller, more limited RAM writer. These will then be used to build the larger RAM writer.

The setups included in this guide work both for console and VC version, at the moment of writing, these setups are unfortunately only applicable for EN versions.

Red/Blue/Yellow

General installation overview:

  1. Assemble 7 items to form a text converter item code.
  2. Catch 15 pokémon (any species is fine), give 12 of them specific nicknames and store them in the currently loaded box. Use your ACE item.
  3. Use the nickname writer to write the large RAM writer in memory.
  4. Use the large RAM writer to finalize the setup.

Due to differences in memory layout, the nicknames and items used in Yellow will differ slightly from those in Red/Blue.

Requirements

In order to install the RAM writer, you need to have an ACE setup that redirects execution to the 3rd item slot ($D322) using a jp hl instruction. The ACE item has to be either 4F or 8F. -gm is not compatible with this guide.

Alongside this ACE setup, you will also need to set up inventory underflow to access item slots beyond the usual 20 slots available.

Install locations

This guides includes two possible install locations, each with advantages and disadvantages.

Installation at $DA96 (current box)

Advantage:

  • Able to view and edit all four sram banks.

Disadvantage:

  • Need to have the current box loaded in in order to be able to use the RAM writer

Installation at sram bank 03, $BA53 (unused save data)

Advantage:

  • Can freely swap out boxes

Disadvantage:

  • Only able to view and edit sram bank 03, other sram banks are inaccessible during execution.

Step 1: Assembling an 8-item code

Head to Celadon city and head to the following spot. Make sure to bring a pokémon with Fly/Teleport.

While standing on this spot, open your item bag and keep scrolling down until you find a Nugget x0 item stack, located at item slot #35. Around item slots #22 through #27 you'll likely encounter glitch items with garbled text. You can scroll past these items by pressing B occasionally while tapping DOWN. Do not select any of these items with the A button, otherwise your game will likely crash.

By walking left or right, you can increment or decrement the item ID in slot #35. By walking up and down we can alternate between an item quantity of x0 and x1. We can safely swap the contents of item slot #35 with other item slots, as long as we use Fly/Teleport afterwards to restore the map back to normal. We can use this to collect all the items we need for the item code.

For every item in the following table, head to the Nugget x0 spot, follow the instructions to obtain an item stack, then Fly back to Celadon and head back to the same spot to obtain the next item stack.

Item ID Item quantity How to acquire
Thunderstone x06/x05 From the Nugget spot, walk 16 steps to the left to get Thunderstone x0. Toss 250 from the stack if you're on Red/Blue or toss 251 if you're on Yellow, then swap with an item from your bag.
TM22 x229 At the Nugget spot, swap the Nugget with the TM23 x64 stack 4 slots below, then toss 63 TM23s. Walk one step left and one step down to get TM22 x0. Toss 27 from the stack, then swap with an item from your bag.
Helix Fossil (x135) At the Nugget spot, toss 121 from the stack to get Nugget x135. Walk 7 steps to the left, then swap with an item from your bag.
B2F x48 At the Nugget spot, swap the Nugget with the TM23 x64 stack 4 slots below, then toss 63 TM23s. Walk leftward (you can use the bicycle two slots above to speed this up) until you've looped through the map twice back to the Nugget spots, then walk 15 steps further to the left to get B2F x0. Toss 208 from the stack, then swap with an item from your bag.
Poké Ball x134 From the Nugget spot, walk 35 steps to the left, 4 steps down and 10 steps left to get Poké Ball x0. Toss 122 from the stack, then swap with an item from your bag.
Hyper Potion x28 From the Nugget spot, walk 30 steps to the left to get Hyper Potion x0. Toss 228 from the stack, then swap with an item from your bag.
HP UP x32 From the Nugget spot, walk 14 steps to the left to get HP UP x0. Toss 224 from the stack, then swap with an item from your bag.
TM45 x201 At the Nugget spot, swap the Nugget with the TM23 x64 stack 4 slots below, then toss 63 TM23s. Every step to the right will increment the TM number by 1. Keep walking rightward until you get TM45 x0. Toss 55 from the stack, then swap with an item from your bag.
Master Ball x00 (Optional for catching later) From the Nugget spot, walk 35 steps to the left, 8 steps down and 13 steps left to get Master Ball x0. Swap with an item from your bag,

Assemble the items you acquired according to the following list:

Item slot Item ID Item Quantity
Slot #1 ACE item (8F or 4F) any
Slot #2 Master Ball x0
Slot #3 Thunderstone x06/051
Slot #4 TM22 x229
Slot #5 Helix Fossil (x135)2
Slot #6 B2F x48
Slot #7 Poké Ball x134
Slot #8 Hyper Potion x28
Slot #9 HP UP x32
Slot #10 TM45 x201

1 x06 on Red/Blue, x05 on Yellow 2 The item quantity for Helix Fossil is invisible for the player.

This item code looks at the nicknames of the pokémon in the currently stored box, then uses pairs of text characters to write a new program. After it finishes, it immediately jumps to execute the newly written program.

Step 2: Catching and nicknaming 15 pokémon to build a nickname writer

The item code we have assembled converts nicknames into code, which means we'll have to catch pokémon with the right nicknames to do something useful. The pokémon we'll be catching will be stored in a storage box. Make sure the box you pick fulfils the following requirements:

  • The box needs to be set as the active box.
  • If on VC, do NOT pick box 1 since that's the box Poké Transporter connects to.

Once that is done, we will fill the box with nicknamed pokémon. We'll be making a list with nicknames using Scottey's nickname converter tool. Simply copy paste the entire code below into the converter, then press the "Run" button to display the list of nicknames. Ignore the checksums for now.

If you'll be manually depositing pokémon, follow the list from top to bottom. If you're catching pokémon and sending them to the PC through a full party, follow the list from bottom to top.

Codes to be used with Scotteh's mail code tool
Red/Blue Yellow
Nickname writer (15 codes) Nickname writer (15 codes)
00 00 00 00 00 11 96 DA D5 D5 06 01 21 5C 65 
CD D6 35 0E 80 21 4B 0A 74 65 77 26 CF D1 2A 
87 30 09 86 12 13 23 81 12 4F 18 F3 21 29 C4 
0E 01 D5 CD DF 15 CD 31 38 D1 F0 B5 A7 28 EE 
0F 38 CA 0F 38 06 0F D0 1B 1B 1B 1B 1B 18 DF
00 00 00 00 00 11 D1 DA D5 D5 06 01 21 CD 62 
CD 84 3E 0E 80 21 4A 0A 74 65 77 26 CF D1 2A 
87 30 09 86 12 13 23 81 12 4F 18 F3 21 00 C4 
0E 01 D5 CD BF 13 CD 1E 38 D1 F0 B5 A7 28 EE 
0F 38 CA 0F 38 06 0F D0 1B 1B 1B 1B 1B 18 DF 

After you've double checked everything, make sure to save. Once you activate the mail writer, you'll need to write up to 40 nicknames to form the full RAM writer. You will not be able to save during this time.

Step 3: Using the nickname writer

Once you activate your ACE item, you should be able to open the nickname writer. Make sure to only use the nickname writer inside a pokémon center to ensure that the checksums are correctly displayed.

The program works as follows:

  • The program opens the nickname screen and asks you to input a nickname.
  • This nickname then gets converted to a sequence of five bytes.
  • All five bytes are written starting from the starting location
  • The program displays a checksum (sum of all written byte values) to confirm that you correctly entered the code. If the printed checksum doesn't match the expected checksum, you made a mistake entering a code.
  • Afterwards, it waits for the user to decide what to do.

During the input phase, the controls are as follows:

  • Press B for the program to ask for a new nickname and convert that to the next five bytes to be written.
  • 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 (except A) to immediately start executing the newly written program. Only do this when you've finished writing everything.
Write mode Input mode
Press select to switch between uppercase/lowercase M and O of POKéMON replaced by the checksum

We will be installing the full RAM writer using a series of nickname codes. These nickname codes will be assembled using Scotteh's mail code tool. Simply copy paste the entire code below into the converter, then press the "Run" button to display the list of nicknames. Ensure you are entering the mail codes that are appropriate for the location you're installing the program to. The generated nicknames need to be entered from top to bottom.

Codes to be used with Scotteh's mail code tool
Red/Blue Yellow
Installation at $DA96 (40 codes) Installation at $BA53 (10 codes) Installation at $DAD1 (40 codes) Installation at $BA53 (10 codes)
3E 01 E0 B6 E0 B7 21 00 DA CD 
EA DA E5 11 F8 FF 19 54 5D 01 
0C 00 CD 53 DB 21 A9 C3 CD DB 
DA 3E 7C 22 7A CD DB DA 7B CD 
DB DA 3E E3 22 1A CD DB DA 36 
7C 09 13 7D FE 13 20 E5 26 00 
74 21 50 C4 36 ED E1 18 C4 F5 
CB 37 CD E2 DA F1 E6 0F C6 F6 
F6 60 22 C9 CD 34 DB CB 5F 20 
39 CB 57 28 0A 0F 30 01 E9 F0 
FE 83 E0 FE C9 0F 30 2A E5 CD 
53 DB 4E CD 34 DB 0F 38 12 0F 
30 01 4B 79 83 4F 21 50 C4 36 
EC 23 CD DB DA 18 E8 E1 71 E5 
06 1C 21 CE 77 CD D6 35 E1 C9 
0F 30 03 53 1E 00 19 C9 CD 31 
38 F0 B5 76 11 00 00 F5 07 30 
01 13 07 30 01 1B 07 30 03 11 
F0 FF 07 30 02 1E 10 F1 C9 E5 
F0 FE 26 0A 74 26 40 77 E1 C9
3E 01 E0 B6 E0 B7 21 00 DA CD 
9E BA E5 11 F8 FF 19 54 5D 01 
0C 00 21 AB C3 3E 7C 22 7A CD 
8F BA 7B CD 8F BA 3E E3 22 1A 
CD 8F BA 36 7C 09 13 7D FE 13 
20 E5 21 50 C4 36 ED E1 18 CD 
F5 CB 37 CD 96 BA F1 E6 0F C6 
F6 F6 60 22 C9 CD D4 BA CB 5F 
28 02 C1 C9 CB 57 28 01 E9 0F 
30 1D 4E E5 CD D4 BA 0F 38 12 
0F 30 01 4B 79 83 4F 21 50 C4 
36 EC 23 CD 8F BA 18 E8 E1 71 
C9 0F 30 03 53 1E 00 19 C9 CD 
31 38 F0 B5 76 11 00 00 F5 07 
30 01 13 07 30 01 1B 07 30 03 
11 F0 FF 07 30 02 1E 10 F1 C9 
3E 01 E0 B6 E0 B7 21 00 DA CD 
25 DB E5 11 F8 FF 19 54 5D 01 
0C 00 CD 8E DB 21 A9 C3 CD 16 
DB 3E 7C 22 7A CD 16 DB 7B CD 
16 DB 3E E3 22 1A CD 16 DB 36 
7C 09 13 7D FE 13 20 E5 26 00 
74 21 50 C4 36 ED E1 18 C4 F5 
CB 37 CD 1D DB F1 E6 0F C6 F6 
F6 60 22 C9 CD 6F DB CB 5F 20 
39 CB 57 28 0A 0F 30 01 E9 F0 
FE 83 E0 FE C9 0F 30 2A E5 CD 
8E DB 4E CD 6F DB 0F 38 12 0F 
30 01 4B 79 83 4F 21 50 C4 36 
EC 23 CD 16 DB 18 E8 E1 71 E5 
06 1C 21 46 7B CD 84 3E E1 C9 
0F 30 03 53 1E 00 19 C9 CD 1E 
38 F0 B5 76 11 00 00 F5 07 30 
01 13 07 30 01 1B 07 30 03 11 
F0 FF 07 30 02 1E 10 F1 C9 E5 
F0 FE 26 0A 74 26 40 77 E1 C9 
3E 01 E0 B6 E0 B7 21 00 DA CD 
9E BA E5 11 F8 FF 19 54 5D 01 
0C 00 21 AB C3 3E 7C 22 7A CD 
8F BA 7B CD 8F BA 3E E3 22 1A 
CD 8F BA 36 7C 09 13 7D FE 13 
20 E5 21 50 C4 36 ED E1 18 CD 
F5 CB 37 CD 96 BA F1 E6 0F C6 
F6 F6 60 22 C9 CD D4 BA CB 5F 
28 02 C1 C9 CB 57 28 01 E9 0F 
30 1D 4E E5 CD D4 BA 0F 38 12 
0F 30 01 4B 79 83 4F 21 50 C4 
36 EC 23 CD 8F BA 18 E8 E1 71 
C9 0F 30 03 53 1E 00 19 C9 CD 
1E 38 F0 B5 76 11 00 00 F5 07 
30 01 13 07 30 01 1B 07 30 03 
11 F0 FF 07 30 02 1E 10 F1 C9 

Once all codes have been entered and verified, you can press any button (with the exception of A, B and DOWN) during input mode to start up the full RAM writer.

Step 4: Using the full RAM writer and finalising the setup

Assuming the program was entered correctly, the game should open up one of the screens as seen in the below screenshots. The RAM writer will draw various values on the screen. The leftmost 4 columns describe the addresses that are currently in view. The rightmost two columns describe the values at each of these addresses. All values on screen are represented in hexadecimal format.

For example: DA01>05 means that the address $DA01 is currently holding the value of $05.

Full Writer Controls

The RAM writer uses two modes of operation. In Read mode you are able to navigate memory and view the values at specific addresses. in Write mode you'll lock in a single address and manipulate the value at that address. By default, the RAM writer will open in Read mode.

RAM writer installed at $DA96 in Read mode RAM writer installed at $DA96 in Write mode. Note the arrow pointing at the current address turning white. RAM writer installed at $BA53 in Read mode. Note the absence of sram bank number at the top of the screen. RAM writer installed at $BA53 in Write mode. Note the arrow pointing at the current address turning white.

Read mode controls

up: address -1
down: address +1
left: address -10
right: address +10
    
B + up: address -1
B + down: address +1
B + left: address -10
B + right: address +10
    
start: exit program    
A: toggle write mode

(When installed at B9E1)
select: start executing at current address

(When installed at DD55)
select + up: sram bank -1
select + down: sram bank +1
select + left: sram bank -10
select + right: sram bank +10
select + A: start executing code from current address onwards (use with caution!)

Write mode controls

up: value -1
down: value +1
left: value -10
right: value +10
B: set current value to 0
A: exit write mode and load final value into the address

Finalising the setup

Now that we have access to the full RAM writer, we'll be changing some values in order to ensure that our RAM writer is saved and properly accessible by using a specific ACE item. Once more, the details of this process will differ depending on the location you installed the writer at and the exact version

If you accidentally exit the RAM writer prematirely, use your ACE item to start the mail writer, enter an empty name by pressing start, then exit the mail writer to jump to the RAM writer.

Prior to following these next steps, make sure to have a useless item in slot #2 of the item pocket.

Red/Blue

  • First, we'll be adding 4F to your bag by adjusting the following value with the RAM writer. This part can be skipped if you already have 4F in your bag
Set the value at $D320 to $59
  • Next, from address $DA65 onward, add the following values depending on your install location:
RAM writer installed to $DA96 RAM writer installed to $BA53
C3 96 DA 21 43 0A 74 65 75 C3 53 BA

From now on, you can simply use 4F in your item pocket to start up the RAM writer.

Yellow

  • First, we'll be adding an ACE item to your bag by adjusting the following value with the RAM writer. This part can be skipped if you already have 4F in your bag
RAM writer installed to $DAD1 RAM writer installed to $BA53
Set the value at $D320 to $59 Set the value at $D320 to $59
  • Next, from address $DA64 onward, add the following values depending on your install location:
RAM writer installed to $DA96 RAM writer installed to $BA53
No writes needed 21 43 0A 74 65 75 C3 53 BA

From now on, you can simply use fm (if you installed to $DAD1) or 4F (if you installed to $BA53) in your item pocket to start up the RAM writer.

Asm translation of included programs/codes

7-item code nickname converter

Hex values Opcodes Labels/notes
26 DE ld h, $DE
2A ldi a, (hl) .loop
87 add a
44 ld b, h
30 04 jr nc, .notChar
86 add (hl)
02 ld (bc), a
2C inc l
03 inc bc
20 F5 jr nz, .loop .notChar
E9 jp hl
Transcript

26 DE 2A 87 44 30 04 86 02 2C 03 20 F5 E9

Nickname writer

Hex values Opcodes Labels/notes
11 96 DA / 11 53 BA ld de, $DA96 / ld de, $BA53 ;defines the address to write to
D5 push de
D5 push de .loop
AF xor a
47 ld b, a
21 5C 65 ld hl, DisplayNameRaterScreen
CD D6 35 Call BankSwitch
21 4B 0A ld hl, 0A4B
74 ld (hl), h
65 ld h, l
77 ld (hl), a
26 CF ld h, CF ; hl now holds the address of wStringBuffer
D1 pop de
2A ldi a, (hl) .not@
87 add a
30 09 jr nc, .@
86 add (hl)
12 ld (de), a
13 inc de
23 inc hl
81 add c
12 ld (de), a
4F ld c, a
18 F3 jr, .not@
21 00 C4 ld hl, $C400 .@
0E 01 ld c, $01
D5 push de
CD DF 15 Call PrintBCDNumber.loop
CD 31 38 Call JoypadLowSensitivity
D1 pop de
F0 B5 ld a, hJoy5
BD cp l
28 CF jr z, .loop
38 EC jr c, .@
07 rlca
D0 ret nc
1B dec de
18 E7 jr, .@
Transcript

11 96 DA D5 D5 AF 47 21 5C 65 CD D6 35 21 4B 0A 74 65 77 26 CF D1 2A 87 30 09 86 12 13 23 81 12 4F 18 F3 21 00 C4 0E 01 D5 CD DF 15 CD 31 38 D1 F0 B5 BD 28 CF 38 EC 07 D0 1B 18 E7

Full RAM writer (DA96)

setup
AF
3C
E0 B6
E0 B7
21 00 DA	ld hl, DA00

resolveDisplay
CD EA DA	call resolveInput
E5		push hl
11 F8 FF	ld de, FFF8
19		add hl, de
54		ld d, h
5D		ld e, l
01 0C 00	ld bc, 000C
CD 53 DB	call openSramBank
21 A9 C3	ld hl, C3A9
CD DB DA	call printHex
.displayLoop
3E 7C		ld a, 7C
22		ldi (hl), a
7A 		ld a, d
CD DB DA	call printHex
7B		ld a, e
CD DB DA	call printHex
3E E3		ld a, E3
22 		ldi (hl), a
1A 		ld a, (de)
CD DB DA	call printHex
36 7C		ld a, 7C
09		add hl, bc
13		inc de
7D		ld a, l
FE 13		cp 13
20 E5		jr nz, .displayLoop
26 00		ld h, 00
74		ld (hl), h
21 50 C4	ld hl, C450
36 ED		ld (hl), ED
E1		pop hl
18 C4		jr, resolveDisplay

printHex
F5		push af
CB 37		swap a
CD E2 DA	call .firstHex
F1		pop af
.firstHex	DAE2
E6 0F		and 0F
C6 F6		add a, F6
F6 60		or a, 60
22		ldi (hl), a
C9		ret

ResolveInput DAEA
CD 34 DB	call sampleDpad
CB 5F		bit 3, a
20 39		jr nz, .noStartButton
.noStartButton
CB 57		bit 2, a
28 0A		jr z, noSelectButton
0F		rrca
30 01		jr nc, .changeSramBank
E9		jp hl
.changeSramBank
F0 FE		ldh a, (FE)
83		add e
E0 FE		ldh (FE), a
C9		ret
.noSelectButton
0F		rrca		
30 2A		jr nc, .noAButton
CD 53 DB	call openSramBank
4E		ld c, (hl)
E5		push hl
.inputALoop
CD 34 DB	call sampleDpad
0F		rrca
38 12		jr c, .AButtonPressed
0F		rrca
30 01		jr nc , .BButtonNotPressed
4B		ld c, e
.BButtonNotPressed
79		ld a, c
83		add e
4F		ld c, a
21 50 C4	ld hl, C450
36 EC		ld (hl), EC
23		inc hl
CD DB DA	call printHex
18 E8		jr, .inputALoop
.AButtonPressed
E1		pop hl	
71		ld (hl), c
E5		push hl
3E 1C		ld a, 1C
21 CE 77	ld hl, 77CE
CD D6 35	Call Bankswitch
E1		pop hl
C9		ret
.noAButton
0F		rrca
30 03		jr nc, noBButton
53		ld d, e
1E 00		ld e, 00
19		add hl, de
C9		ret

sampleDpad
CD 31 38	call JoypadLowSensitivity
F0 B5		ldh a, (B5)
76		halt
11 00 00	ld de, 0000
F5		push af
07		rlca
30 01		jp nc, .noDown
13		inc de
.noDown
07		rlca
30 01		jr nc, .noUp	
1B		dec de
.noUp
07		rlca
30 03		jr nc, .noLeft
11 F0 FF	ld de, FFF0
.noLeft
07		rlca
30 02		jr nc, .noRight
1E 10		ld e, 10
.noRight
F1		pop af
c9		ret

opensrambank
E5		push hl
F0 FE		ldh a, (FE)
26 0A		ld h, 0A
74		ld (hl), h
26 40		ld h, 40
77		ld (hl), a
E1 		pop hl
c9		ret
Transcript

3E 01 E0 B6 E0 B7 21 00 DA CD EA DA E5 11 F8 FF 19 54 5D 01 0C 00 CD 53 DB 21 A9 C3 CD DB DA 3E 7C 22 7A CD DB DA 7B CD DB DA 3E E3 22 1A CD DB DA 36 7C 09 13 7D FE 13 20 E5 26 00 74 21 50 C4 36 ED E1 18 C4 F5 CB 37 CD E2 DA F1 E6 0F C6 F6 F6 60 22 C9 CD 34 DB CB 5F 20 39 CB 57 28 0A 0F 30 01 E9 F0 FE 83 E0 FE C9 0F 30 2A E5 CD 53 DB 4E CD 34 DB 0F 38 12 0F 30 01 4B 79 83 4F 21 50 C4 36 EC 23 CD DB DA 18 E8 E1 71 E5 06 1C 21 CE 77 CD D6 35 E1 C9 0F 30 03 53 1E 00 19 C9 CD 31 38 F0 B5 76 11 00 00 F5 07 30 01 13 07 30 01 1B 07 30 03 11 F0 FF 07 30 02 1E 10 F1 C9 E5 F0 FE 26 0A 74 26 40 77 E1 C9

Full RAM writer (BA53)

setup
3E 01		ld a, 01
E0 B6		ldh (B6), a
E0 B7		ldh (B7), a
21 00 DA	ld hl, DA00

resolveDisplay
CD 9E BA	call resolveInput
E5		push hl
11 F8 FF	ld de, FFF8
19		add hl, de
54		ld d, h
5D		ld e, l
01 0C 00	ld bc, 000C
21 AB C3	ld hl, C3AB
.displayLoop
3E 7C		ld a, 7C
22		ldi (hl), a
7A 		ld a, d
CD 8F BA	call printHex
7B		ld a, e
CD 8F BA	call printHex
3E E3		ld a, E3
22 		ldi (hl), a
1A 		ld a, (de)
CD 8F BA	call printHex
36 7C		ld a, 7C
09		add hl, bc
13		inc de
7D		ld a, l
FE 13		cp 13
20 E5		jr nz, .displayLoop
21 50 C4	ld hl, C450
36 ED		ld (hl), ED
E1		pop hl
18 CD		jr, resolveDisplay

printHex
F5		push af
CB 37		swap a
CD 94 ba	call .firstHex
F1		pop af
.firstHex	BA96
E6 0F		and 0F
C6 F6		add a, F6
F6 60		or a, 60
22		ldi (hl), a
C9		ret

ResolveInput
CD D4 BA	call sampleDpad
CB 5F		bit 3, a
28 02		jr z, .noStartButton
C1		pop bc
C9		ret
.noStartButton
CB 57		bit 2, a
28 01		jr z, noSelectButton
E9		jp hl
.noSelectButton
0F		rrca		
30 1D		jr nc, .noAButton
4E		ld c, (hl)
E5		push hl
.inputALoop
CD D4 BA	call sampleDpad
0F		rrca
38 12		jr c, .AButtonPressed
0F		rrca
30 01		jr nc , .BButtonNotPressed
4B		ld c, e
.BButtonNotPressed
79		ld a, c
83		add e
4F		ld c, a
21 50 C4	ld hl, C450
36 EC		ld (hl), EC
23		inc hl
CD 8F BA	call printHex
18 E8		jr, .inputALoop
.AButtonPressed
E1		pop hl	
71		ld (hl), c
C9		ret
.noAButton
0F		rrca
30 03		jr nc, noBButton
53		ld d, e
1E 00		ld e, 00
19		add hl, de
C9		ret

sampleDpad
CD 31 38	call JoypadLowSensitivity
F0 B5		ldh a, (B5)
76		halt
11 00 00	ld de, 0000
F5		push af
07		rlca
30 01		jp nc, .noDown
13		inc de
.noDown
07		rlca
30 01		jr nc, .noUp	
1B		dec de
.noUp
07		rlca
30 03		jr nc, .noLeft
11 F0 FF	ld de, FFF0
.noLeft
07		rlca
30 02		jr nc, .noRight
1E 10		ld e, 10
.noRight
F1		pop af
c9		ret
Transcript

3E 01 E0 B6 E0 B7 21 00 DA CD 9E BA E5 11 F8 FF 19 54 5D 01 0C 00 21 AB C3 3E 7C 22 7A CD 8F BA 7B CD 8F BA 3E E3 22 1A CD 8F BA 36 7C 09 13 7D FE 13 20 E5 21 50 C4 36 ED E1 18 CD F5 CB 37 CD 96 BA F1 E6 0F C6 F6 F6 60 22 C9 CD D4 BA CB 5F 28 02 C1 C9 CB 57 28 01 E9 0F 30 1D 4E E5 CD D4 BA 0F 38 12 0F 30 01 4B 79 83 4F 21 50 C4 36 EC 23 CD 8F BA 18 E8 E1 71 C9 0F 30 03 53 1E 00 19 C9 CD 31 38 F0 B5 76 11 00 00 F5 07 30 01 13 07 30 01 1B 07 30 03 11 F0 FF 07 30 02 1E 10 F1 C9

Gold/Silver

General installation overview:

  1. Use a box name code to set every TM quantity to 255.
  2. Write out a mail writer program by changing TM quantities. Use a box name code to use the mail writer.
  3. Enter a series of mail codes in order to write the full RAM writer.
  4. Use the full RAM writer to automatically it to the data of box 14.

Requirements

In order to install the RAM writer, you need to have an ACE setup that redirects execution to the 1st or 2nd character of box name 1. Available options are either:

  • Wrong Pocket TM17 ACE using a Quagsire holding TM01 and with Return as first move.
  • Coin Case ACE which uses a pokémon's EVs to redirect to the last read mail, which fixes the stack and then redirects to the start of box names.

Next, make sure to take care of the following:

  • Make sure to empty box 14 of any pokémon you wish to keep. We'll be installing the full RAM writer in the data for box 14, meaning everything inside it will have its data overwritten.
  • Put any item that you can afford to lose in the first slot of your item pack. This item will be changed to a TM33 at the end of the setup.

Step 1: Setting all TM quantities to 255

Edit the first eight box names until they form the following code.

Enter the following box names, then execute ACE.

Box 1: A p 'v C é 2 2 5
Box 2: 'v j 'v u é 1 2 5
Box 3: 'v ♂ é 5 2 p 'v 9
Box 4: é 4 2 p é 6 2 5
Box 5: 'v u é 8 2 'v {space} 5
Box 6: é 7 2 'v : é 9 2
Box 7: 0 9 ♀ 5 ♀ 5 5 5
Box 8: 5 5 5 5 5 5 x 'd

This will set the quantities of all 50 TMs to 255.

Step 2: Selling TMs to form a mail writer

Sell TMs such that you get the following quantities:

Sell or toss TMs until the quantities match the following amounts.
TM Final Quantity Amount to sell Sell value
TM01 DYNAMICPUNCH x17 x238 357000
TM02 HEADBUTT x85 x170 170000
TM03 CURSE x221 x34 51000
TM04 ROLLOUT x213 x42 42000
TM05 ROAR x213 x42 21000
TM06 TOXIC x213 x42 63000
TM07 ZAP CANNON x62 x193 193000
TM08 ROCK SMASH x04 x251 125500
TM09 PSYCH UP x33 x222 111000
TM10 HIDDEN POWER x66 x189 283500
TM11 SUNNY DAY x98 x157 157000
TM12 SWEET SCENT x207 x48 24000
TM13 SNORE x225 x30 15000
TM14 BLIZZARD x209 x46 69000
TM15 HYPER BEAM x42 x213 319500
TM16 ICY WIND x135 x120 180000
TM17 PROTECT x48 x207 310500
TM18 RAIN DANCE x07 x248 248000
TM19 GIGA DRAIN x134 x121 181500
TM20 ENDURE x18 x237 355500
TM21 FRUSTRATION x19 x236 118000
TM22 SOLARBEAM x129 x126 189000
TM23 IRON TAIL x79 x176 264000
TM24 DRAGONBREATH x18 x237 355500
TM25 THUNDER x42 x213 213000
TM26 EARTHQUAKE x39 x216 324000
TM27 RETURN x32 x223 111500
TM28 DIG x242 x13 13000
TM29 PSYCHIC x33 x222 222000
TM30 SHADOW BALL x1 x254 381000
TM31 MUD-SLAP x196 x59 88500
TM32 DOUBLE TEAM x77 x178 178000
TM33 ICE PUNCH x205 x50 75000
TM34 SWAGGER x240 x15 7500
TM35 SLEEP TALK x58 x197 98500
TM36 SLUDGE BOMB x27 x228 114000
TM37 SANDSTORM x205 x50 50000
TM38 FIRE BLAST x144 x111 111000
TM39 SWIFT x55 x200 200000
TM40 DEFENSE CURL x240 x15 7500
TM41 THUNDERPUNCH x171 x84 126000
TM42 DREAM EATER x189 x66 99000
TM43 DETECT x40 x215 107500
TM44 REST x216 x39 58500
TM45 ATTRACT x56 x199 298500
TM46 THIEF x238 x17 25500
TM47 STEEL WING x7 x248 372000
TM48 FIRE PUNCH x208 x47 70500
TM49 FURY CUTTER x24 x231 346500
TM50 NIGHTMARE x241 x14 14000

What to do in case you sell too much of a TM

If you accidentally sell too much any TM, you can use the following box name code to set that TM back to x255:

Box number Box name
Box 1 A p 0 9 é _ ♀ 'd
Other Can be left as they are

Replace _ with the character that corresponds to the TM you want to set to x255:

TM character
TM02 (space)
TM03 A
TM04 B
TM05 C
TM06 D
TM07 E
TM08 F
TM09 G
TM10 H
TM11 I
TM12 J
TM13 K
TM14 L
TM15 M
TM16 N
TM17 O
TM18 P
TM19 Q
TM20 R
TM21 S
TM22 T
TM23 U
TM24 V
TM25 W
TM26 X
TM27 Y
TM28 Z
TM29 (
TM30 )
TM31 :
TM32 ;
TM33 [
TM34 ]
TM35 a
TM36 b
TM37 c
TM38 d
TM39 e
TM40 f
TM41 g
TM42 h
TM43 i
TM44 j
TM45 k
TM46 l
TM47 m
TM48 n
TM49 o
TM50 p

Once you've finished selling TMs, set up box names according to the following codes.

Enter box names such that they match the above codes in-game.
Box number Box name
Box 1 A p 'v C é 'd 2 5
Box 2 5 5 5 5 5 5 h 'm
Box 3
Other Can be left as they are

Once everything has been double checked, you can use your ACE item in order to start up the mail writer. Make sure to save prior to this step. Once you start the mail writer you'll need to finish writing all mail codes before you have an opportunity to save again.

Step 3: Using the mail writer

Controls

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 screen just to the right of the lower row. This can be used to verify if a code was entered correctly.

Alongside these actions, the mail writer will now request user input:

  • Press A + B together to open a new mail and continue writing data.
  • 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 immediately jump to and start executing the newly written program. Only use this when you've finished every mail.
Enter your mail code, then press "END". It prints the checksum and waits for input.

Building the full RAM writer

We will be installing the full RAM writer using a series of mail codes. These mail codes will be assembled using Scotteh's mail code tool. Copy paste the entire code in the text box on the mail code tool's page, then press "Run".

Codes to be used with Scotteh's mail code tool
Installation at $DD55 (18 codes)
3E 03 CD E1 30 0E CE 11 E1 B9 21 74 DD CD 1A 31 
0E 2D 11 18 D4 D5 CD 1A 31 3E E1 EA B8 D5 C9 AF 
3C E0 D6 21 00 DA CD 21 DF E5 11 F8 FF 19 54 5D 
01 0C 00 F0 FE 21 A9 C3 CD E1 30 CD 65 CC 3E 7C 
22 7A CD 65 CC 7B CD 65 CC 3E E3 22 1A CD 65 CC 
36 7C 09 13 7D FE 13 20 E5 CD F1 30 21 50 C4 36 
ED E1 18 C2 F5 CB 37 CD 6C CC F1 E6 0F C6 F6 F6 
80 22 C9 CD 90 37 F0 AB 11 00 00 07 30 01 13 07 
30 01 1B 07 30 03 11 F0 FF 07 30 02 1E 10 07 C9 
CD 74 CC 38 41 07 30 0B 07 07 30 01 E9 F0 FE 83 
E0 FE C9 07 30 03 53 1E 00 19 07 30 2A E5 F0 FE 
CD E1 30 46 CD 74 CC 07 07 30 01 43 07 38 0E 78 
83 47 21 50 C4 36 EC 23 CD 65 CC 18 E7 E1 70 E5 
3E 05 21 FD 4D CF E1 C9 FA AB CE FE E1 C0 FA C2 
CE FE 90 C0 3E 0D EA E0 CE C9 C3 01 DF 3E 03 CD 
E1 30 0E 71 11 20 CC D5 21 E1 B9 CD 1A 31 0E 48 
11 21 DF CD 1A 31 0E 12 11 0F DF CD 1A 31 0E 03 
11 8A FF CD 1A 31 AF E0 89 C9 

After you press run, the tool will generate the mail codes that you need to enter in the mail writer. After you're finished entering all mail codes, you can press DOWN during the user input phase in order to start up the full RAM writer.

After entering every code, a new number will appear to the right of the bottom mail row. This is a checksum and is used to verify that you've correctly entered every mail. If a checksum doesn't match the one given by the tool, that means that a code was incorrectly entered, meaning you will need to redo your mail by pressing DOWN enough time to return to the starting byte of the last mail, then entering that same mail again.

Step 4: Activating the RAM writer

After you're finished and have verified that all checksums were valid, press any button outside of A, B or DOWN during the user input phase in order to start up the full RAM writer.

Doing this will activate the following effects:

  • Save the RAM writer to the contents of box 14.
  • Change the first item slot in your item pack to TM33.
  • Install setup to make sure that using TM33 from the item pack will start the RAM writer.
  • Automatically start the RAM writer.

Starting the RAM writer, either automatically or through using wrong pocket TM33, will activate the following effects:

  • Copy the necessary data to memory to activate the RAM writer.
  • Deploy setup that will enable the use of TM33 during battle.
  • Start the RAM writer.

After exiting the RAM writer, you can restart the RAM writer by using TM33 from the item pack. In battle, you can activate the RAM writer by using TM33 and selecting "QUIT". Please note that the setup to enable the use of TM33 during battle does not persist between resets, you can reenable this function by using the RAM writer outside of battle at least once.

As you can see in the screenshots below, the RAM writer will draw various values on the screen. The leftmost 4 columns describe the addresses that are currently in view. The rightmost two columns describe the values at each of these addresses. All values on screen are represented in hexadecimal format.

For example: DA01>05 means that the address $DA01 is currently holding the value of $05.

Let's go over the controls of the full RAM writer. By default, the RAM writer will open in Read mode.

Full Writer Controls

The RAM writer uses two modes of operation. In Read mode you are able to navigate memory and view the values at specific addresses. in Write mode you'll lock in a single address and manipulate the value at that address.

RAM writer in Read mode RAM writer in Write mode. Note the arrow pointing at the current address turning white.

Read mode controls

up: address -1
down: address +1
left: address -10
right: address +10
    
B + up: address -1
B + down: address +1
B + left: address -10
B + right: address +10
    
start: exit program    
A: toggle write mode

select + up: sram bank -1
select + down: sram bank +1
select + left: sram bank -10
select + right: sram bank +10
select + A: start executing code from current address onwards (use with caution!)

Write mode controls

up: value -1
down: value +1
left: value -10
right: value +10
B: set current value to 0
A: exit write mode and load final value into the address

Asm translation of included programs/codes

Set all TM quantities to x255

Before first execution After first execution
80		add b
AF		xor a
D6 82		sub $82
EA F8 F8	ld $f8f8, a
FB		ei
50		ld d, b
D6 A9		sub $A9
D6 B4		sub $B4
EA F7 F8	ld $F8F7, a
FB		ei
50		ld d, b
D6 EF		sub $EF
EA FB F8	ld $F8FB, a
AF		xor a
D6 FF		sub $FF
50		ld d, b
EA FA F8	ld $F8FA, a
AF		xor a
EA FC F8	ld $F8FC, a
FB		ei
50		ld d, b
D6 B4		sub $B4
EA FE F8	ld $F8FE, a
D6 7F		sub $7F
FB		ei
50		ld d, b
EA FD F8	ld $F8FD, a
D6 9C		sub $9C
EA FF F8	ld $F8FF, a
50		ld d, b
F6 FF		or $FF
F5		push af
FB		ei
F5		push af
FB		ei
FB		ei
FB		ei
50		ld d, b
FB		ei
FB		ei
FB		ei
FB		ei
FB		ei
B7		or a
D0		ret nc
80		add b
AF		xor a
D6 82		sub $82
EA F8 F8	ld $f8f8, a
FB		ei
50		ld d, b
D6 A9		sub $A9
D6 B4		sub $B4
EA F7 F8	ld $F8F7, a
FB		ei
50		ld d, b
D6 EF		sub $EF
EA FB F8	ld $F8FB, a
AF		xor a
D6 FF		sub $FF
50		ld d, b
EA FA F8	ld $F8FA, a
AF		xor a
EA FC F8	ld $F8FC, a
FB		ei
50		ld d, b
D6 B4		sub $B4
EA FE F8	ld $F8FE, a
D6 7F		sub $7F
FB		ei
50		ld d, b
EA FD F8	ld $F8FD, a
D6 9C		sub $9C
EA FF F8	ld $F8FF, a
50		ld d, b
F6 FF		or $FF
21 7E F5	ld hl, $F57E	
01 32 00	ld bc, $0032
CD 4C 31	call ByteFill
FB		ei
FB		ei
FB		ei
B7		or a
D0		ret nc

Redirect to TMs

Before first execution After first execution
80		add b
AF		xor a
D6 82		sub $82
EA D0 F8	ld $F8D0, a
FB		ei
50		ld d, b
FB		ei
FB		ei
FB		ei
FB		ei
FB		ei
FB		ei
A7		and a
D2 50 F5	jp nc, $F550
50		ld d, b
80		add b
AF		xor a
D6 82		sub $82
EA D0 F8	ld $F8D0, a
FB		ei
50		ld d, b
FB		ei
FB		ei
FB		ei
FB		ei
FB		ei
FB		ei
A7		and a
D2 7E F5	jp nc, $F57E
50		ld d, b

Open sram bank 3, then redirect to TMs

Before first execution After first execution
80		add b
AF		xor a
D6 D0		sub $D0
EA D0 F8	ld $F8D4, a
AF		xor a
50		ld d, b
D6 82		sub $82
EA D6 F8	ld $F8D6, a
AF		xor a
D6 FD		sub $FD
50		ld d, b
A7		and a
D4 E1 FB	call nc, $FBE1
D2 FB F5	jp nc, $F5FB
50		ld d, b
80		add b
AF		xor a
D6 D0		sub $D0
EA D0 F8	ld $F8D4, a
AF		xor a
50		ld d, b
D6 82		sub $82
EA D6 F8	ld $F8D6, a
AF		xor a
D6 FD		sub $FD
50		ld d, b
A7		and a
D4 E1 30	call nc, $30E1
D2 7E F5	jp nc, $F57E
50		ld d, b

Mail writer

11 55 DD	ld de, DD55
D5		push de
.continue
D5		push de
11 04 E2	ld de, E204
D5		push de
7B		ld a, e
21 42 62	ld hl, 6242
CF		rst08
E1		pop hl
D1		pop de
.terminator
2A		ldi a, (hl)
87		add a
30 08		jr nc, .notChar
86		add (hl)
12		ld (de), a
13		inc de
23		inc hl
81		add c
4F		ld c, a
12		ld (de), a
7C		ld a, h
.notChar
27		daa
20 F1		jr nc, .terminator
04		inc b
68		ld l, b
29		add hl, hl
48		ld c, b
CD F0 3A	call PrintBCDNumber.loop
1B		dec DE
.noButtonPressed 
F0 A5		ldh a, (hJoypadPressed)
B8		cp b
28 D8		jr z, .continue
38 F9		jr c, .noButtonPressed 
07		rlca
D8		ret c
E1		pop hl
C9		ret

Full RAM writer ($DD55)

setup
AF		xor a
3C		inc a
E0 D6   	ldh (D6),a
21 00 DA	ld hl, DA00

resolveDisplay
CD AB DD	call resolveInput
E5		push hl
11 F8 FF	ld de, FFF8
19		add hl, de
54		ld d, h4
5D		ld e, l
01 0C 00	ld bc, 000C
F0 FE		ldh a, (FE)
21 A9 C3	ld hl, C3A9
CD E1 30	call openSramBank
CD 9A DD	call printHex
.displayLoop
3E 7C		ld a, 7C
22		ldi (hl), a
7A 		ld a, d
CD 9A DD	call printHex
7B		ld a, e
CD 9A DD	call printHex
3E E3		ld a, E3
22 		ldi (hl), a
1A 		ld a, (de)
CD 9A DD	call printHex
36 7C		ld a, 7C
09		add hl, bc
13		inc de
7D		ld a, l
FE 13		cp 13
20 E5		jr nz, .displayLoop
CD F1 30	call closeSramBank
21 50 C4	ld hl, C450
36 ED		ld (hl), ED
E1		pop hl
18 C2		jr, resolveDisplay

printHex
F5		push af
CB 37		swap a
CD A1 DD	call .firstHex
F1		pop af
.firstHex
E6 0F		and 0F
C6 F6		add a, F6
30 02		jr nc, .hexIsNumber
C6 80		add a, 80
22		ldi (hl), a
C9		ret

ResolveInput
CD F7 DD	call sampleDpad
CB 5F		bit 3, a
28 02		jr z, .noStartButton
C1		pop bc
C9		ret
.noStartButton
CB 57		bit 2, a
28 0A		jr z, noSelectButton
0F		rrca
30 01		jr nc, .changeSramBank
E9		jp hl
.changeSramBank
F0 FE		ldh a, (FE)
83		add e
E0 FE		ldh (FE), a
C9		ret
.noSelectButton
0F		rrca		
30 2A		jr nc, .noAButton
E5		push hl
F0 FE		ldh a, (FE)
CD E1 30	call openSramBank
46		ld b, (hl)
.inputALoop
CD F7 DD	call sampleDpad
0F		rrca
38 12		jr c, .AButtonPressed
0F		rrca
30 01		jr nc , .BButtonNotPressed
43		ld b, e
.BButtonNotPressed
78		ld a, b
83		add e
47		ld b, a
21 50 C4	ld hl, C450
36 EC		ld (hl), EC
23		inc hl
CD 9A DD	call printHex
18 E8		jr, .inputALoop
.AButtonPressed
E1		pop hl	
70		ld (hl), b
E5		push hl
3E 05		ld a, 5
21 FD 4D	ld hl, 4DFD
CF		rst08h
E1		pop hl
C9		ret
.noAButton
0F		rrca
30 03		jr nc, noBButton
53		ld d, e
1E 00		ld e, 00
19		add hl, de
C9		ret

sampleDpad
CD 90 37	call JoyTextDelay_ForcehJoyDown
F0 AB		ldh a, (AB)
11 00 00	ld de, 0000
F5		push af
07		rlca
30 01		jp nc, .noDown
13		inc de
.noDown
07		rlca
30 01		jr nc, .noUp	
1B		dec de
.noUp
07		rlca
30 03		jr nc, .noLeft
11 F0 FF	ld de, FFF0
.noLeft
07		rlca
30 02		jr nc, .noRight
1E 10		ld e, 10
.noRight
F1		pop af
c9		ret

Full RAM writer ($03:B9E1)

db 14		//located at B9E0, ensures box 14 having 20 pokémon inside it.
setup
AF		xor a
3C		inc a
E0 D6   	ldh (D6),a
21 00 DA	ld hl, DA00

resolveDisplay
CD 2C BA	call resolveInput
E5		push hl
11 F8 FF	ld de, FFF8
19		add hl, de
54		ld d, h
5D		ld e, l
01 0C 00	ld bc, 000C
21 A9 C3	ld hl, C3AB
.displayLoop
3E 7C		ld a, 7C
22		ldi (hl), a
7A 		ld a, d
CD 1B BA	call printHex
7B		ld a, e
CD 1B BA	call printHex
3E E3		ld a, E3
22 		ldi (hl), a
1A 		ld a, (de)
CD 1B BA	call printHex
36 7C		ld a, 7C
09		add hl, bc
13		inc de
7D		ld a, l
FE 13		cp 13
20 E5		jr nz, .displayLoop
21 50 C4	ld hl, C450
36 ED		ld (hl), ED
E1		pop hl
18 CD		jr, resolveDisplay

printHex BA1B
F5		push af
CB 37		swap a
CD 22 BA	call .firstHex
F1		pop af
.firstHex
E6 0F		and 0F
C6 F6		add a, F6
30 02		jr nc, .hexIsNumber
C6 80		add a, 80
22		ldi (hl), a
C9		ret

ResolveInput BA2C
CD 62 BA	call sampleDpad
CB 5F		bit 3, a
28 02		jr z, .noStartButton
C1		pop bc
C9		ret
.noStartButton
CB 57		bit 2, a
28 01		jr z, noSelectButton
E9		jp hl
.noSelectButton
0F		rrca		
30 1D		jr nc, .noAButton
E5		push hl
46		ld b, (hl)
.inputALoop
CD 62 BA	call sampleDpad
0F		rrca
38 12		jr c, .AButtonPressed
0F		rrca
30 01		jr nc , .BButtonNotPressed
43		ld b, e
.BButtonNotPressed
78		ld a, b
83		add e
47		ld b, a
21 50 C4	ld hl, C450
36 EC		ld (hl), EC
23		inc hl
CD 1C BA	call printHex
18 E8		jr, .inputALoop
.AButtonPressed
E1		pop hl	
70		ld (hl), b
C9		ret
.noAButton
0F		rrca
30 03		jr nc, noBButton
53		ld d, e
1E 00		ld e, 00
19		add hl, de
C9		ret

sampleDpad BA62
CD 90 37	call JoyTextDelay_ForcehJoyDown
F0 AB		ldh a, (AB)
11 00 00	ld de, 0000
F5		push af
07		rlca
30 01		jp nc, .noDown
13		inc de
.noDown
07		rlca
30 01		jr nc, .noUp	
1B		dec de
.noUp
07		rlca
30 03		jr nc, .noLeft
11 F0 FF	ld de, FFF0
.noLeft
07		rlca
30 02		jr nc, .noRight
1E 10		ld e, 10
.noRight
F1		pop af
c9		ret

Codes that finalise the setup

backup RAM writer to $B9E0 recall RAM writer from $B9E0 Header text
3E 03		ld a, $03
CD E1 30	call OpenSRAM
01 C0 00	ld bc, $00C0
11 E0 B9	ld de, $B9E0
21 55 DD	ld hl, $DD55
C3 1A 31	jp CopyBytes
3E 03		ld a, $03
CD E1 30	call OpenSRAM
01 C0 00	ld bc, $00C0
11 55 DD	ld de, $DD55
21 E0 B9	ld hl, $B9E0
CD 1A 31	call CopyBytes
C3 55 DD	jp $DD55
3E 03		ld a, $03
CD E1 30	call OpenSRAM
C3 E1 B9	jp $B9E1

Crystal

Old methods for reference

Generation I

Setting up TheZZAZZGlitch's memory editor with coordinates

Main article: Player coordinates RAM writer


Use the player coordinates RAM writer to set up TheZZAZZGlitch's memory editor at DB01.


Setting up TheZZAZZGlitch's memory editor with an item set up

Main article: Reusable RAM writer

The reusable RAM writer can be use to write a byte one address at a time.

Fast sequential RAM writer

See https://archives.glitchcity.info/forums/board-115/thread-8725/page-0.html

Full Control: Real-time RAM writing with 8F

See https://archives.glitchcity.info/forums/board-115/thread-7744/page-0.html

Thanks to bbbbbbbbba and the larger GCRI community for suggesting improvements to the code initially written to determine mail codes.

Thanks to TheZZAZZGlitch and offgao, and k(ry for previous memory editors.

Generation II

Thanks to flag3833753 and Epsilon (Couldntthinkofaname) for previous work on RAM writers and inspiring various kinds of optimisations to be used in the RAM writers included in this guide.

Thanks to Scotteh for writing the mail code webapp.

Thanks to Crystal_ for their memory editor.

Thanks to Sanqui for discovering Coin Case arbitrary code execution.

Crystal

TheZZAZZGlitch's memory editor ported to Pokémon Crystal by Kai mirror (pokecrystal memory editor.sav)