Mail writer: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
No edit summary |
|||
Line 3: | Line 3: | ||
It is a 50 byte program, installed in the TM/HM pocket by having specific TM quantities, that allows the user to quickly and accurately write and execute arbitrary code payloads of up to a maximum size of 428 bytes. Payloads are written from wOtPartyCount onward, where enemy trainer's parties are usually buffered. '''Using the Mail writer requires an ACE setup that both redirects execution to the start of the TM/HM pocket and sets the value of register a to $04.''' |
It is a 50 byte program, installed in the TM/HM pocket by having specific TM quantities, that allows the user to quickly and accurately write and execute arbitrary code payloads of up to a maximum size of 428 bytes. Payloads are written from wOtPartyCount onward, where enemy trainer's parties are usually buffered. '''Using the Mail writer requires an ACE setup that both redirects execution to the start of the TM/HM pocket and sets the value of register a to $04.''' |
||
The Mail writer is currently supported for all language releases of Gold, Silver and Crystal, both VC and cartridge |
The Mail writer is currently supported for all language releases of Gold, Silver and Crystal, both VC and cartridge. |
||
=How the mail writer works= |
=How the mail writer works= |
||
Line 335: | Line 335: | ||
| TM50 || 241 || 14000 |
| TM50 || 241 || 14000 |
||
|} |
|} |
||
==Quantities for JP versions== |
|||
Unlike the others, the Japanese versions are able to use the Mail writer as a box code instead. Both are intended to be used with a wrong pocket TM ACE setup that redirects execution to the first box name ($D8B2 for Gold & Silver, $DB68 for Crystal). For Crystal, an additional setup using 0x1500 control code ACE is required to finish the box codes. |
|||
===Gold & Silver=== |
|||
Write the following box codes, then use the wrong pocket TM ACE: |
|||
<pre>Box 1: ヅ に わ ゆ ゆ ゾ ュ ぼ |
|||
Box 2: ゆ に ヂ ぺ な に ヨ プ |
|||
Box 3: ゅ ま む ゅ ご き き よ |
|||
Box 4: ぐ デ だ ガ ご き き よ |
|||
Box 5: キ デ ド ア ぺ デ ご ? |
|||
Box 6: だ ! ズ が と ぜ ォ ギ |
|||
Box 7: ビ ヘ ば で が ブ ブ ぜ |
|||
Box 8: げ ぜ ォ ま き ぐ ァ プ |
|||
Box 9: ダ れ か リ ダ リ だ ゥ</pre> |
|||
===Crystal=== |
|||
First, write the following box codes. |
|||
<pre>Box 1: ヅ に わ ゆ ゆ が ぜ xぜ |
|||
Box 2: ゆ げ ぜ ェ ぼ ガ べ プ |
|||
Box 3: き ま む ゅ ご き き よ |
|||
Box 4: ぐ デ だ ガ ご き き よ |
|||
Box 5: キ デ ド ア ぺ デ ご ? |
|||
Box 6: だ ! ズ が な ぜ ォ ギ |
|||
Box 7: ビ ヘ チ チ が ビ ブ ギ |
|||
Box 8: ぜ セ げ ま き ぐ ァ プ |
|||
Box 9: ダ ダ け パ ダ リ だ ゥ</pre> |
|||
Then, give a pokémon the following mail to hold. Execute 0x1500 control code ACE redirecting to $D000 (where the mail is buffered in memory). This code will modify two bytes from the above box code, along with replacing the first item in the main item pocket with TM15 and adding the required bootstrap to redirect execution to the start of box names. |
|||
<pre>ぼ ほ ほ セ ル が れ ぜ デ オ づ イ づ チ づ 0 |
|||
ゥ キ リ よ ヌ ゥ モ ろ ゥ あ ろ ゅ の</pre> |
|||
Afterwards, you can use TM15 anytime outside of battle to start up the mail writer. |
|||
=General assembly= |
=General assembly= |
||
Line 415: | Line 454: | ||
D0 ret nc |
D0 ret nc |
||
18 F1 jr .DownPressed</pre> |
18 F1 jr .DownPressed</pre> |
||
==JP Gold & Silver versions== |
|||
<pre>11 C6 DC ld de, DCC6 |
|||
D5 push de |
|||
.newMail |
|||
D5 push de |
|||
0E AE ld c, AE |
|||
3E 50 ld a, 50 |
|||
D5 push de |
|||
C6 10 sub A0 ; a = 60 |
|||
47 ld b, a ; bc = 60AE |
|||
C5 push bc |
|||
C6 A4 add a, A4 ; a = 04 |
|||
42 ld b, d |
|||
50 ld d, b |
|||
E1 pop hl ; hl = 60AE |
|||
CF rst08H ; Farcall _ComposeMailMessage (a:hl = 04:60AE) |
|||
D1 pop de |
|||
E1 pop hl ; set both hl and dc to the start of the newly written mail |
|||
.loop |
|||
2A ldi a, (hl) |
|||
B7 or a, a |
|||
B7 or a, a |
|||
D6 50 sub 50 |
|||
28 13 jr, .terminator |
|||
30 05 jr, .character |
|||
2A ldi a, (hl) ; if terminator, escape loop. if newline, get new value for a and continue |
|||
B7 or a, a |
|||
B7 or a, a |
|||
D6 50 sub 50 ; ensures that new character will result in the same value when combined with the next |
|||
.character |
|||
86 add (hl) |
|||
12 ld (de), a |
|||
13 inc de |
|||
80 add a, b |
|||
47 ld b, a ; responsible for generating checksum |
|||
12 ld (de), a |
|||
2A ldi a, (hl) ; inc hl is not available, so this will do |
|||
E6 50 or 50 ; ensures that carry flag is not set |
|||
30 E7 jr nc, .loop |
|||
.terminator |
|||
0C inc c ;_ComposeMailMessage sets bc to 0000, so c = 00 when we reach this part |
|||
26 C4 ld h, C4 |
|||
2E F4 ld l, F4 ; hl = C4F4, bottom left screen tile |
|||
06 50 and 50 ; Ensures that b is consistent for the next call |
|||
1A ld a, (de) |
|||
CD 3A 33 call PrintBCDNumber.loop + 01h ; PrintBCDNumber.loop itself can't be reached, so we skip forward one byte. |
|||
.errorCorrection |
|||
26 1B ld h, 1B |
|||
1B dec de ; calling PrintBCDNumber.loop with c = 01 advances de by 01. |
|||
2E 50 ld l, 50 ; hl = 1B50 |
|||
29 add hl, hl ; hl = 36A0 |
|||
2E F4 ld l, F4 ; hl = 36F4 (address of JoyTextDelay_ForcehJoyDown) |
|||
CF rst08H ; Farcall JoyTextDelay_ForcehJoyDown set a = current button state |
|||
B7 or a, a ; is no button pressed? if yes, ask for new button states |
|||
28 E9 jr z, .terminator |
|||
42 ld b, d |
|||
50 ld d, b |
|||
0F rlca ; is the a button pressed? If yes, start a new mail |
|||
DA B6 D8 jp c, .loop |
|||
0F rlca ; is the b button pressed? If yes, return and execute newly written program. if not, decrement de to allow user to correct errors |
|||
D8 ret c |
|||
30 EA jr nc, .errorCorrection |
|||
50 ld d, b</pre> |
|||
==JP Crystal versions== |
|||
<pre>mail |
|||
3E 01 ld a, 01 |
|||
01 8D A6 ld bc, A68D ; will be used for arithmetic operations |
|||
26 DA ld h, DA |
|||
2E 12 ld e, 12 |
|||
84 add a, h ; a = DB |
|||
32 ldd (hl), a ; hl = DA11 |
|||
81 add a, c ; a = 68 |
|||
32 ldd (hl), a ; hl = DA10 |
|||
90 sub a, b ; a = C2 |
|||
32 ldd (hl), a ; hl = DA0F |
|||
F6 4E or 4F ; a = CE (TM15 item ID) |
|||
EA 86 D8 ld (D886), a; Item pocket, item #1 ID |
|||
D6 96 sub a, 96 ; a = 38 |
|||
EA A1 DB ld (DBA1), a |
|||
EA B1 DB ld (DBB1), a |
|||
E1 pop hl ; required for proper exit out of 0x1500 |
|||
C9 ret |
|||
50 ld d, b |
|||
*Bytes 2 and 3 get overwritten when viewing the unterminated name pokémon in the box |
|||
Mail writer |
|||
11 B1 D2 ld de, D2B1 |
|||
D5 push de |
|||
.newMail |
|||
D5 push de |
|||
26 2E ld h, 2E |
|||
2E 50 ld l, 50 |
|||
D5 push de |
|||
29 add hl, hl ; hl = 5CA0 |
|||
2E EB ld l, EB ; hl = 5CEB |
|||
3E 05 ld a, 05 |
|||
3D dec a ; a = 04 |
|||
42 ld b, d |
|||
50 ld d, b |
|||
B7 or a, a |
|||
CF rst08H ; Farcall _ComposeMailMessage -01h (a:hl = 04:5CEB) |
|||
D1 pop de |
|||
E1 pop hl ; set both hl and dc to the start of the newly written mail |
|||
.loop |
|||
2A ldi a, (hl) |
|||
B7 or a, a |
|||
B7 or a, a |
|||
D6 50 sub 50 |
|||
28 13 jr, .terminator |
|||
30 05 jr, .character |
|||
2A ldi a, (hl) ; if terminator, escape loop. if newline, get new value for a and continue |
|||
B7 or a, a |
|||
B7 or a, a |
|||
D6 50 sub 50 ; ensures that new character will result in the same value when combined with the next |
|||
.character |
|||
86 add (hl) |
|||
12 ld (de), a |
|||
13 inc de |
|||
80 add a, b |
|||
47 ld b, a ; responsible for generating checksum |
|||
12 ld (de), a |
|||
2A ldi a, (hl) ; inc hl is not available, so this will do |
|||
E6 50 or 50 ; ensures that carry flag is not set |
|||
30 E7 jr nc, .loop |
|||
.terminator |
|||
0C inc c ;_ComposeMailMessage sets bc to 0000, so c = 00 when we reach this part |
|||
26 C5 ld h, C5 |
|||
2E F4 ld l, F4 ; hl = C4F4, bottom left screen tile |
|||
06 50 and 50 ; Ensures that b is consistent for the next call |
|||
1A ld a, (de) |
|||
CD 90(38) call PrintBCDNumber.loop |
|||
.errorCorrection |
|||
26 1A ld h, 1A |
|||
1B dec de ; calling PrintBCDNumber.loop with c = 01 advances de by 01. |
|||
06 50 ld b, 50 |
|||
2E 8D ld l, F4 ; hl = 1A8D |
|||
29 add hl, hl ; hl = 351A (address of JoyTextDelay_ForcehJoyDown -01h) |
|||
CF rst08H ; Farcall JoyTextDelay_ForcehJoyDown -01h set a = current button state |
|||
B7 or a, a ; is no button pressed? if yes, ask for new button states |
|||
28 E9 jr z, .terminator |
|||
42 ld b, d |
|||
50 ld d, b |
|||
0F rlca ; is the a button pressed? If yes, start a new mail |
|||
(38)B9 jr c, .loop |
|||
40 ld b, b |
|||
0F rlca ; is the b button pressed? If yes, return and execute newly written program. if not, decrement de to allow user to correct errors |
|||
D8 ret c |
|||
30 EA jr nc, .errorCorrection |
|||
50 ld d, b</pre> |