Guides:Fast 0x1500 ACE: Difference between revisions
m
no edit summary
mNo edit summary |
|||
(25 intermediate revisions by 2 users not shown) | |||
Line 7:
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].
'''When playing on cartridge or emulator, it is
The contents of this guide are demonstrated in the following video:
{{youtube|iJRb3PwUrkg|TimoVM}}
=Setting up initial ACE=
Line 73 ⟶ 77:
Finally, in order to execute ACE, do the following actions:
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
|
[[File:EN Fast ACE PokeSen.png]]
||
[[File:EN Fast ACE Spearow.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.'''
Line 95 ⟶ 106:
# Sell TMs in specific quantities so that the amount of TMs in the TM/HM pocket spell out a small mail writer program.
==Step 4:
* Rename box names to form the following language dependent codes. '''Please mind the differences between uppercase X ([[File:Character UCX.png]]), lowercase x ([[File:Character lcx.png]]) and multiplication symbol ([[File:Character mul.png]]).'''
Line 112 ⟶ 123:
|}
* Then, execute 0x1500 control code ACE using the method described in
* If the code was successfully executed, the TM/HM pocket should now be completely filled with 255 copies of every TM. Additionally, the first item in the main item pocket will have changed into a TM15. Using it will execute code in the TM/HM pocket. Make sure to save after verifying that the code worked.
Line 123 ⟶ 134:
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
! English
|-
|
[[File:TM English C.png]]
||
[[File:TM Italian C.png]]
Line 246 ⟶ 253:
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
! rowspan="2" | TM !! colspan="2" | English
|-
|-
| TM08 ROCK SMASH || x117 ||69000
|-
| TM35 SLEEP TALK ||x204 ||25500
|-
| TM39 SWIFT ||x75 ||180000
|}
Line 294 ⟶ 301:
In case something happens with the TM15 bootstrap that causes it to no longer function, you can repair bootstrap without having to reset TM quantities using the following procedure:
* Enter the following language-specific box names. '''Please mind the differences between uppercase X ([[File:Character UCX.png]]), lowercase x ([[File:Character lcx.png]]) and multiplication symbol ([[File:Character mul.png]])'''. For English, boxes 8 through 13 are irrelevant for the setup and do not need to be renamed. For Italian & Spanish, boxes 7 through 13 are irrelevant for the setup and do not need to be renamed.
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
! English
|-
|
[[File:Box English C Reset V2.png]]
||
[[File:Box
||
[[File:Box
|}
* Then, execute 0x1500 control code ACE using the method described in section 1.4.1
* If the code executes succesfully without crashing the game, the bootstrap has now been repaired.
=Appendix
==
===Test box name===
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
! Language !! Box name content !! Language !! Box name content !! Language !! Box name content
|-
! scope="row"| English
|| <pre>Box 14: Pk Pk h 'd</pre>
! scope="row" | Italian
|| <pre>Box 14: Pk Pk Í</pre>
! scope="row"| Spanish
|| <pre>Box 14: Pk Pk Í</pre>
|}
Note: "..." refers to one ellipsis character, “pk” refers to the one pk character, "$" refers to the pokédollar sign, "*" refers to the multiplication symbol. Make sure to pay careful attention to upper/lowercase letters.
===Setup box name===
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
! Language !! Box name content !! Language !! Box name content !! Language !! Box name content
|-
! scope="row"| English
|| <pre>Box 1: 0 ♀ ♀ Pk ? ♂ E Pk
Box 2: ♀ Pk 'd 'v z é B 5
Box 3: 'v 9 é [SPACE] 5 'v , F
Box 4: 's [SPACE] 5 ? E 's [SPACE] 5
Box 5: 'v 's é J 5 'v 8 5
Box 6: é F 5 'v * é I 5
Box 7: 0 C 's [SPACE] 5 é H 5
Box 8: p é G 5 ♀ 'v h h
Box 9: 's [SPACE] 5 é C 5 'v B
Box 10: h 's [SPACE] 5 é D 5 *
Box 11: 'v 9 é E 5 Pk 0 9
Box 12: 's B 5 é C 5 Pk 'v
Box 13: 'v Pk é T 2 p F 1
Box 14: p 0 5 ♀ Pk 'v G 1</pre>
! scope="row" | Italian
|| <pre>Box 1: 0 ♀ ♀ Pk ? ¡ E Pk
Box 2: ♀ Pk ì ° z é B 5
Box 3: ° 9 é [SPACE] 5 ° , F
Box 4: ó [SPACE] 5 ? E ó [SPACE] 5
Box 5: ° ú é I 5 ° 9 5
Box 6: é J 5 ° 8 é F 5
Box 7: È R ó [SPACE] 5 é H 5
Box 8: p é G 5 ♀ ° h h
Box 9: ó [SPACE] 5 é C 5 ° B
Box 10: h ó [SPACE] 5 é D 5 *
Box 11: ° 9 é E 5 Pk 0 9
Box 12: ó B 5 é C 5 Pk °
Box 13: ° Pk é T 2 p F 1
Box 14: p 0 5 ♀ Pk ° G 1</pre>
! scope="row"| Spanish
|| <pre>Box 1: 0 ♀ ♀ Pk ? ¡ E Pk
Box 2: ♀ Pk ì ° z é B 5
Box 3: ° 9 é [SPACE] 5 ° , F
Box 4: ó [SPACE] 5 ? E ó [SPACE] 5
Box 5: ° ó é J 5 È 5 5
Box 6: é I 5 ° 3 é F 5
Box 7: È R ó [SPACE] 5 é H 5
Box 8: p é G 5 ♀ ° h h
Box 9: ó [SPACE] 5 é C 5 ° B
Box 10: h ó [SPACE] 5 é D 5 *
Box 11: ° 9 é E 5 Pk 0 9
Box 12: ó B 5 é C 5 Pk °
Box 13: ° Pk é T 2 p F 1
Box 14: p 0 5 ♀ Pk ° G 1</pre>
|}
Note: "..." refers to one ellipsis character, “pk” refers to the one pk character, "$" refers to the pokédollar sign, "*" refers to the multiplication symbol. Make sure to pay careful attention to upper/lowercase letters.
===Reset box name===
{| class="wikitable" style="margin-left: auto; margin-right: auto; border: none;"
! Language !! Box name content !! Language !! Box name content !! Language !! Box name content
|-
! scope="row"| English
|| <pre>Box 1: p 0 Mn ♀ Pk p 0 2
Box 2: E ♀ Pk 'v y é h 5
Box 3: F 'v , h 's h 5 p
Box 4: 'v 6 h 's h 5 p p
Box 5: 0 'm 's h 5 'v M F
Box 6: 's h 5 'v B A 'd Pk
Box 7: Pk Pk p F 1
Box 14: p 0 5 ♀ Pk 'v G 1</pre>
! scope="row" | Italian
|| <pre>Box 1: p 0 Mn È 2 ♀ Pk 5
Box 2: ° y é i 5 F ° ,
Box 3: Ù i 5 È È Ù i 5
Box 4: È Á Ù i 5 5 È W
Box 5: Ù i 5 È [SPACE] Ù i 5
Box 6: Pk Pk Pk p F 1 Í Í
Box 14: p 0 5 ♀ Pk ° G 1 </pre>
! scope="row"| Spanish
|| <pre>Box 1: p 0 Mn È 2 ♀ Pk 5
Box 2: ° y é i 5 F ° ,
Box 3: Ù i 5 È È Ù i 5
Box 4: È Á Ù i 5 5 È W
Box 5: Ù i 5 È [SPACE] Ù i 5
Box 6: Pk Pk Pk p F 1 Í Í
Box 14: p 0 5 ♀ Pk ° G 1 </pre>
|}
Note: "..." refers to one ellipsis character, “pk” refers to the one pk character, "$" refers to the pokédollar sign, "*" refers to the multiplication symbol. Make sure to pay careful attention to upper/lowercase letters.
==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
|-
| $C4A0 || Starting address of wTilemap
|-
| $C4BE || Address of the tilemap where the name of the current active box will be printed when viewing the withdraw screen.
|-
| $CD70 || Starting address of wBGMapBufferPointers
|-
| $D073 || Address where the names of pokémon are buffered.
|-
| $D086 || Address where the names of used items are buffered.
|-
| $D108 || Address where the current selected party pokémon’s species is buffered.
|-
| $D109 || Address where the current selected party pokémon’s party slot is buffered.
|}
* The specific movement pattern used will buffer C2 9B C4 (jp nz $C49B) at $CD70.
* Selecting Spearow in the party screen will buffer 15 00 at $D108.
* Viewing the unterminated name pokémon in the withdraw screen will cause the game to attempt to print its name. Since the name doesn't contain a terminator, the game will continue printing text until it find and executes the $15 control character at $D108.
* The presence of the $00 at $D109 will erroneously cause the game to call $CD52. Due to the specific movement pattern and location used, the area between $CD52 and $CD70 is filled with $00 values, allowing safe passage.
* Thanks to the jump buffered at $CD70, the game will jump to $C49B. Since we're in the withdraw screen, the area between $C49B and $C4A0 is filled with $00 values, allowing safe passage. The jump will always pass, since both the carry and zero flags are reset when the game calls $CD52.
* Between $C4A0 and $C4BE are a bunch of screen tiles that are either blank ($7F) or edges of text boxes ($79, $7A, $7B and $7C). These opcodes are all harmless and simply load register values to other registers, allowing safe passage.
* $C4BE holds the text characters of the current active box, allowing us to form arbitrary jumps to other locations in memory.
===Effect of the
The
====English====
<pre>
E1 pop hl
E1 pop hl ; popping hl twice then returning will cause the game to continue printing from de to hl. The second pop ensures hl will point to the $7000 region, allowing safe exit.
A7 and a ; reset carry flag
D0 ret nc ; Safely return to normal game operation
</pre>
====
<pre>
E1 pop hl
E1 pop hl ; popping hl twice then returning will cause the game to continue printing from de to hl. The second pop ensures hl will point to the $7000 region, allowing safe exit.
C9 ret ; Safely return to normal game operation
</pre>
===Effect of the setup box name code===
Converting the characters from box names to assembly results in the following code. Please note that the box name code overwrites part of itself, the translated assembly assumes the code was already used once.
The code overwrites part of itself to call the byteFill function. This will fill the area between $D859 and $D88A with $FF values, setting all 50 TM quantities to 255. Separately, this code writes five bytes from $DA10 onward, the effect pointer of TM15, installing a TM15 bootstrap that redirects execution to the Mail Writer. Lastly, when combined with the mail code, it will convert the first item in the main item pocket to a TM15.
====English====
<pre>
Box 1: $DB75
F6 F5 or $F5 ; a = $F5
F5 push af
E1 pop hl ; hl = $F500
E6 EF and $EF ; a = $E5
84 add a, h ; af = $DA10
E1 pop hl
50 ld d, b
Box 2: $DB7E
F5 push af
E1 pop hl ; hl = $DA10, overwritten to $22, ldi (hl), a
D0 ret nc ; On first pass, ignored. Taken whenever $DB7F is called
D6 B9 sub $B9 ; a = $21
EA 81 FB ld ($FB81), a
50 ld d, b
Box 3: $DB87
D6 FF sub $FF ; a = $22
EA
85 add a, l ; a = $3E, reset carry flag
50 ld d, b
Box 4: $DB90
D4 7F FB call nc, $FB7F
E6 84 and $84 ; a = $04
D4 7F FB call nc, $FB7F
50 ld d, b
Box 5: $DB99
D6 D4 sub $D4 ; a = $30
EA 89 FB ld ($FB89), a
D6 FE sub $FE ; a = $32
FB ei
50 ld d, b
Box 6: $DBA2
EA 85 FB ld ($FB85), a
D6 F1 sub $F1 ; a = $41
EA 88 FB ld ($FB88), a
50 ld d, b
Box 7: $DBAB
F6 82 or $82 ; a = $C3, reset carry flag
D4 7F FB call nc, $FB7F
EA 87 FB ld ($FB87), a
50 ld d, b
Box 8: $DBB4
AF xor a ; a = $00
EA 86 FB ld ($FB86), a
F5 push af
D6 A7 sub $A7 ; a = $59
A7 and a ; Reset carry flag
50 ld d, b
Box 9: $DBBD
D4 7F FB call nc, $FB7F
EA 82 FB ld ($FB82), a
D6 81 sub $81 ; a = $D8
50 ld d, b
Box 10: $DBC6
A7 and a ; Reset carry flag
D4 7F FB call nc, $FB7F
EA 83 FB ld ($FB83), a
F1 pop af ; a = $00
50 ld d, b
Box 11: $DBCF
D6 FF sub $FF ; a = $01
EA 84 FB ld ($FB84), a
E1 pop hl
F6 FF or $FF ; a = $FF
50 ld d, b
Box 12: $DBD8
D4 81 FB call nc, $FB81 ; $FB81 was rewritten to 21 59 D8 01 32 00 C3 41 30
EA 82 FB ld ($FB82), a ; Replace $59 by $FF to prevent possible crash when viewing $59 as text
E1 pop hl
D6 50 sub $50 ; a = $AF
Box 13: $DBE1
D6 E1 sub $E1 ; a = $CE
EA 93 F8 ld (wItems), a ; Replace first item in item pocket with TM15
AF xor a ; a = $00
85 add a, l
F7 rst30h ; Resume text function, immediately hit terminator
50 ld d, b
Box 14: displayed as screen tiles at $C4BE
AF xor a ; a = $00
F6 FB or $FB ; a = $FB
F5 push af
E1 pop hl ; h = $FB
D6 86 sub $86 ; a = $75
F7 rst30h ; hl = $FB75, de = $C4C5, jump to hl
Bootstrap: $DA10
3E 04 ld a, $04
C3 59 D8 jp wTMsHMs
</pre>
====
<pre>
Box 1: $DB75
F5 push af
E1 pop hl ; hl = $F500
84 add a, h ; af = $DA10
E1 pop hl
50 ld d, b
Box 2: $DB7E
F5 push af
E1 pop hl ; hl = $DA10, overwritten to $22, ldi (hl), a
D0 ret nc ; On first pass, ignored. Taken whenever $DB7F is called
D6 B9 sub $B9 ; a = $21
EA 81 FB ld ($FB81), a
50 ld d, b
Box 3: $DB87
D6 FF sub $FF ; a = $22
EA 7F FB ld ($FB7F), a
D6 F4 sub $F4 ; a = $2E
85 add a, l ; a = $3E, reset carry flag
50 ld d, b
Box 4: $DB90
D4 7F FB call nc, $FB7F
E6 84 and $84 ; a = $04
D4 7F FB call nc, $FB7F
50 ld d, b
Box 5: $DB99
D6 D5 sub $D5 ; a = $2F
EA 88 FB ld ($FB88), a
D6 FF sub $FF ; a = $30
FB ei
50 ld d, b
Box 6: $DBA2
EA 89 FB ld ($FB89), a
D6 FE sub $FE ; a = $32
EA 85 FB ld ($FB85), a
50 ld d, b
Box 7: $DBAB
C6 91 add $91 ; a = $C3, reset carry flag
D4 7F FB call nc, $FB7F
EA 87 FB ld ($FB87), a
50 ld d, b
Box 8: $DBB4
AF xor a ; a = $00
F5 push af
D6 A7 sub $A7 ; a = $59
50 ld d, b
Box 9: $DBBD
D4 7F FB call nc, $FB7F
EA 82 FB ld ($FB82), a
D6 81 sub $81 ; a = $D8
50 ld d, b
Box 10: $DBC6
A7 and a ; Reset carry flag
D4 7F FB call nc, $FB7F
EA 83 FB ld ($FB83), a
F1 pop af ; a = $00
50 ld d, b
Box 11: $DBCF
D6 FF sub $FF ; a = $01
EA 84 FB ld ($FB84), a
E1 pop hl
F6 FF or $FF ; a = $FF
50 ld d, b
Box 12: $DBD8
D4 81 FB call nc, $FB81 ; $FB81 was rewritten to 21 59 D8 01 32 00 C3 2F 30
EA 82 FB ld ($FB82), a ; Replace $59 by $FF to prevent possible crash when viewing $59 as text
E1 pop hl
D6 50 sub $50 ; a = $AF
Box 13: $DBE1
D6 E1 sub $E1 ; a = $CE
EA 93 F8 ld (wItems), a ; Replace first item in item pocket with TM15
AF xor a ; a = $00
85 add a, l
F7 rst30h ; Resume text function, immediately hit terminator
50 ld d, b
Box 14: displayed as screen tiles at $C4BE
AF xor a ; a = $00
F6 FB or $FB ; a = $FB
F5 push af
E1 pop hl ; h = $FB
D6 86 sub $86 ; a = $75
F7 rst30h ; hl = $FB75, de = $C4C5, jump to hl
Bootstrap: $DA10
3E 04 ld a, $04
C3 59 D8 jp wTMsHMs
</pre>
====
<pre>
Box 1: $DB75
F5 push af
E1 pop hl ; hl = $F500
E6 E5 and $E5 ; a = $E5
84 add a, h ; af = $DA10
E1 pop hl
50 ld d, b
Box 2: $DB7E
F5 push af
E1 pop hl ; hl = $DA10, overwritten to $22, ldi (hl), a
D0 ret nc ; On first pass, ignored. Taken whenever $DB7F is called
D6 B9 sub $B9 ; a = $21
EA 81 FB ld ($FB81), a
50 ld d, b
Box 3: $DB87
D6 FF sub $FF ; a = $22
EA 7F FB ld ($FB7F), a
D6 F4 sub $F4 ; a = $2E
85 add a, l ; a = $3E, reset carry flag
50 ld d, b
Box 4: $DB90
D4 7F FB call nc, $FB7F
E6 84 and $84 ; a = $04
D4 7F FB call nc, $FB7F
50 ld d, b
Box 5: $DB99
D6 D4 sub $D4 ; a = $30
EA 89 FB ld ($FB89), a
C6 FB add $FB ; a = $2B
FB ei
50 ld d, b
Box 6: $DBA2
EA 88 FB ld ($FB88), a
D6 F9 sub $F9 ; a = $32
EA 85 FB ld ($FB85), a
50 ld d, b
Box 7: $DBAB
C6 91 add $91 ; a = $C3, reset carry flag
D4 7F FB call nc, $FB7F
EA 87 FB ld ($FB87), a
50 ld d, b
Box 8: $DBB4
AF xor a ; a = $00
F5 push af
50 ld d, b
Box 9: $DBBD
D4 7F FB call nc, $FB7F
EA 82 FB ld ($FB82), a
D6 81 sub $81 ; a = $D8
50 ld d, b
Box 10: $DBC6
A7 and a ; Reset carry flag
D4 7F FB call nc, $FB7F
EA 83 FB ld ($FB83), a
F1 pop af ; a = $00
50 ld d, b
Box 11: $DBCF
D6 FF sub $FF ; a = $01
EA 84 FB ld ($FB84), a
E1 pop hl
F6 FF or $FF ; a = $FF
50 ld d, b
Box 12: $DBD8
D4 81 FB call nc, $FB81 ; $FB81 was rewritten to 21 59 D8 01 32 00 C3 2B 30
EA 82 FB ld ($FB82), a ; Replace $59 by $FF to prevent possible crash when viewing $59 as text
E1 pop hl
D6 50 sub $50 ; a = $AF
Box 13: $DBE1
D6 E1 sub $E1 ; a = $CE
EA 93 F8 ld (wItems), a ; Replace first item in item pocket with TM15
AF xor a ; a = $00
85 add a, l
F7 rst30h ; Resume text function, immediately hit terminator
50 ld d, b
Box 14: displayed as screen tiles at $C4BE
AF xor a ; a = $00
F6 FB or $FB ; a = $FB
F5 push af
E1 pop hl ; h = $FB
D6 86 sub $86 ; a = $75
F7 rst30h ; hl = $FB75, de = $C4C5, jump to hl
Bootstrap: $DA10
3E 04 ld a, $04
C3 59 D8 jp wTMsHMs
</pre>
===Effect of the
Converting the TM quantities to assembly results in the following code. Please note that this code requires a value of $04 in register a in order to properly work.
====English====
<pre>
11 80 D2 ld de, $D280
D5 push de
D5 push de ; .nextMail
D5 push de
21 75 5E ld hl, _ComposeMailMessage
CF rst08h, FarCall a:hl
E1 pop hl
D1 pop de
2A ldi a, (hl) ; .continue
FE 50 cp $50
38 FB jr c, .continue
28 0A jr z, .terminator
87 add a, a
86 add a, (hl)
12 ld (de), a
13 inc de
23 inc hl
81 add a, c
4F ld c, a
12 ld (de), a
18 EF jr .continue
21 01 C5 ld hl, $C501 ; .screenLoop
4D ld c, l
CD CC 38 call PrintBCDNumber.loop - 1
1B dec de ; .goBack
CD 4B 35 call JoyTextDelay_ForcehJoyDown
BD cp a, l ; l = $04
28 D9 jr z, .nextMail
38 F0 jr c, .displayLoop
FE 08 cp $08
C8 ret z
18 F2 jr .goBack
</pre>
====
<pre>
D5 push de
D5 push de ; .nextMail
D5 push de
21 C5 5E ld hl, _ComposeMailMessage
CF rst08h, FarCall a:hl
E1 pop hl
D1 pop de
2A ldi a, (hl) ; .continue
FE 50 cp $50
38 FB jr c, .continue
28 0A jr z, .terminator
87 add a, a
86 add a, (hl)
12 ld (de), a
13 inc de
23 inc hl
81 add a, c
4F ld c, a
12 ld (de), a
18 EF jr .continue
21 01 C5 ld hl, $C501 ; .screenLoop
4D ld c, l
CD BA 38 call PrintBCDNumber.loop
1B dec de ; .goBack
CD 39 35 call JoyTextDelay_ForcehJoyDown
BD cp a, l ; l = $04
28 D9 jr z, .nextMail
38 F0 jr c, .displayLoop
FE 08 cp $08
C8 ret z
18 F2 jr .goBack
</pre>
====
<pre>
D5 push de
D5 push de ; .nextMail
D5 push de
21 E8 5E ld hl, _ComposeMailMessage
CF rst08h, FarCall a:hl
E1 pop hl
D1 pop de
2A ldi a, (hl) ; .continue
FE 50 cp $50
38 FB jr c, .continue
28 0A jr z, .terminator
87 add a, a
86 add a, (hl)
12 ld (de), a
13 inc de
23 inc hl
81 add a, c
4F ld c, a
12 ld (de), a
18 EF jr .continue
21 01 C5 ld hl, $C501 ; .screenLoop
4D ld c, l
CD AC 38 call PrintBCDNumber.loop - 1
1B dec de ; .goBack
CD 35 35 call JoyTextDelay_ForcehJoyDown
BD cp a, l ; l = $04
28 D9 jr z, .nextMail
38 F0 jr c, .displayLoop
FE 08 cp $08
C8 ret z
18 F2 jr .goBack
</pre>
===Effect of the reset box name code===
Converting the characters from box names to assembly results in the following code. This code writes the required bootstrap to $DA10, the entrance point of Wrong Pocket TM15. This area of memory is unused but is preserved during saves.
====English====
<pre>
Box 1: $DB75
AF xor a ; a = $00, reset carry flag
F6 E2 or $E2 ; a = $E2
F5 push af
E1 pop hl
AF xor a ; a = $00, reset carry flag
F6 F8 or $F8 ; a = $F8
50 ld d, b
Box 2: $DB7E
84 add a, h ; af = $DA10
F5 push hl
E1 pop hl ; hl = $DA10
D6 B8 sub $B8 ; a = $22
EA A7 FB ld (.write), a
50 ld d, b
Box 3: $DB87
85 add a, l ; a = $33
D6 F4 sub $F4 ; a = $3E
A7 and a ; Reset carry flag
D4 A7 FB call nc, .write
AF xor a ; a = $00
50 ld d, b
Box 4: $DB90
D6 FC sub $FC ; a = $04
A7 and a ; Reset carry flag
D4 A7 FB call nc, .write
AF xor a ; a = $00
AF xor a
50 ld d, b
Box 5: $DB99
F6 D2 or $D2 ; a = $D2
D4 A7 FB call nc, .write
D6 8C sub $8C ; a = $46
85 add a, l ; a = $59
50 ld d, b
Box 6: $D8A2
D4 A7 FB call nc, .write
D6 81 sub $81 ; a = $D8, carry flag set
22 ldi (hl), a ; .write
D0 ret nc ; Skip on last pass
E1 pop hl
50 ld d, b
Box 7: $D8AC
E1 pop hl
E1 pop hl
AF xor a ; a = $00
85 add a, l
F7 rst30h ; Resume text function, immediately hit terminator
Box 14: displayed as screen tiles at $C4BE
AF xor a ; a = $00
F6 FB or $FB ; a = $FB
F5 push af
E1 pop hl ; h = $FB
D6 86 sub $86 ; a = $75
F7 rst30h ; hl = $FB75, de = $C4C5, jump to hl
</pre>
====Italian & Spanish====
<pre>
Box 1: $DB75
AF xor a ; a = $00
F6 E2 or $E2 ; a = $E2
C6 F8 add $F8 ; af = $DA10
F5 push af
E1 pop hl ; hl = $DA10
FB ei
50 ld d, b
Box 2: $DB7E
D6 B8 sub $B8 ; a = $22
EA A8 FB ld (.write), a
85 add a, l ; a = $32
D6 F4 sub $F4 ; a = $3E
50 ld d, b
Box 3: $DB87
CD A8 FB call .write
C6 C6 add $C6 ; a = $04
CD A8 FB call .write
50 ld d, b
Box 4: $DB90
C6 BF add $BF ; a = $C3
CD A8 FB call .write
FB ei
C6 96 add $96 ; a = $59
50 ld d, b
Box 5: $DB99
CD A8 FB call .write
C6 7F add $7F ; a = $D8
CD A8 FB call .write
50 ld d, b
Box 6: $DBA2
E1 pop hl
E1 pop hl ; Prevent side effects when returning to text printer
E1 pop hl
AF xor a ; a = $00
85 add a, l
F7 rst30h ; Resume text function, immediately hit terminator
22 ldi (hl), a ; .write
C9 ret
Box 14: displayed as screen tiles at $C4BE
AF xor a ; a = $00
F6 FB or $FB ; a = $FB
F5 push af
E1 pop hl ; h = $FB
D6 86 sub $86 ; a = $75
F7 rst30h ; hl = $FB75, de = $C4C5, jump to hl
</pre>
[[Category:Guides]]
|