the cutting room mirror

Whirlo

This article has a talk page!
view on tcrf.net

This page contains notes for the game Whirlo.

Map List#

7E003F Area (Save)
7E0060 Area (Current)

7E085E Invincible (00)
7E0470 Lives (09)

Room List

00  0-? Test Map (Unused)
01  1-1 Sandros
02  1-2 Haunted Forest, Lake
03  1-3 Haunted Forest, Ashes
04  1-5 Haunted Forest, Chasm
05  1-6 Valley of Sizus
06  2-1 Mt. Alsandra, Cage
07  2-2 Mt. Alsandra, Quarkman Village
08  2-3 Mt. Alsandra, Volcano
09  2-4 Mt. Alsandra, Crescent King
0A  3-1 Cauldra Castle, Flooded City
0B  3-4 Gramps Dock, Ascent
0C  3-5 The Princess
0D  3-6 Catacomb (Event)
0E  3-7 Catacomb
0F  3-9 Catacomb, Flood Escape
10  3-8 Catacomb, Nick Clan
11  4-1 Dragon Forest
12  4-2 Toadstool Cave, Area 1
13  4-3 Toadstool Cave, Area 2
14  4-4 Toadstool Cave, Ascent
15  4-5 Toadstool Cave, Area 4
16  4-6 Toadstool Cave, Nick
17  4-7 The Anconda
18  5-1 Sea of Sirrah
19  5-3 Pirate Ship, Whale
1A  5-4 Pirate Ship (Event)
1B  5-6 Pirate Ship, Area 1
1C  5-7 Pirate Ship, Area 2
1D  5-8 Pirate Ship, Grady & Andy
1E  5-9 Pirate Ship, Area 4
1F  5-10 Pirate Ship, Area 5
20  5-11 Pirate Ship, Rest Room
21  5-12 Pirate Ship, Boss
22  6-9 Sea of Sirrah, Peppy Route
23  6-10 Pirate Ship, Finding Buck, Peppy Route
24  6-14 Tree Island, Light Crystal 6
25  6-4 Tree Island, Underground 1
26  6-6 Tree Island, Underground 2
27  7-? Store (Unused)
28  7-2 Neverland, Ferry
29  7-5 Neverland, Decision
2A  7-6 Neverland, Auto-scroll
2B  7-7 The Monument
2C  7-8 Goblin Valley, Light Crystal 7
2D  8-1 Endless Desert
2E  8-2 Endless Desert
2F  8-3 Endless Desert
30  8-5 The Tower, Trial 1: Knowledge
31  8-6 The Tower, Trial 2: Heart
32  8-7 The Tower, Trial 3: Courage (V0)
33  Cutscene (1-4 Elders House)
34  Cutscene (3-3 Gramps Dock)
35  Cutscene (3-8 Nicks rooms)
36  Cutscene (4-1 Pixies House)
37  Cutscene (6-2 Tree House)
38  Cutscene (7-1 Neverland, Walter)
39  Cutscene (6-12 Store)
3A  Cutscene (3-10 Catacombs, Thief Bad Ending)
3B  Cutscene (5-5 Pirate Ship, Helping Buck)
3C
3D  5-7 Duplicate
3E  5-8 Duplicate
3F  5-8 Duplicate
40  Cutscene (6-10 The Princess, Bringing Nick to Nubs)
41  Cutscene (6-10 Catacomb, Bringing Nick to Nubs)
42  6-1 Tree Island
43  Cutscene (6-3 Tree Island)
44  Cutscene (6-5 Tree Island)
45  6-7 Tree Island
46  6-8 Tree Island, Decision
47  6-11 Tree Island, Decision
48  6-11 Tree Island, Decision
49
4A  7-4 Neverland, Conclusion
4B  7-3 Neverland, Conclusion
4C  Cutscene (5-2 Sea of Sirrah)
4D  Cutscene (3-2 Cauldra Castle)
4E  4-1 Duplicate
4F  8-9 The Tower, Final Boss
50  8-7 The Tower, Trial 3: Courage (V1)
51  8-7 The Tower, Trial 3: Courage (V2)
52  8-7 The Tower, Trial 3: Courage (V3)
53  8-7 The Tower, Trial 3: Courage (V4)
54  8-7 The Tower, Trial 3: Courage (V5)
55  8-7 The Tower, Trial 3: Courage (V6)
56  8-7 The Tower, Trial 3: Courage (V7)
57  8-7 The Tower, Trial 3: Courage (V8)
58  8-7 The Tower, Trial 3: Courage (V9)
59  8-7 The Tower, Trial 3: Courage (V10)
5A  8-7 The Tower, Trial 3: Courage (V11)
5B  8-7 The Tower, Trial 3: Courage (V12)
5C  8-7 The Tower, Trial 3: Courage (V13)
5D  8-7 The Tower, Trial 3: Courage (V14)
5E  8-7 The Tower, Trial 3: Courage (V15)
5F  8-7 The Tower, Trial 3: Courage (V16)
60  UI/Demo (Chapter 1)
61  UI/Demo (Chapter 1)
62  UI/Demo (Chapter 1)
63  UI/Demo (Chapter 2)
64  UI/Demo (Chapter 3)
65  UI/Demo (Chapter 3)
66  UI/Demo (Chapter 3)
67  UI/Demo (Chapter 4)
68  UI/Demo (Chapter 5)
69  UI/Demo (Chapter 5)
6A  UI/Demo (Chapter 5)
6B  UI/Demo (Chapter 6)
6C  UI/Demo (Chapter 6)
6D  UI/Demo (Chapter 7)
6E  UI/Demo (Chapter 7)
6F  
70  UI/Demo (Chapter 8)
71  UI/Demo (Chapter 8)
72  UI/Demo (Chapter 8)
73  UI/Demo (Chapter 8)
74  UI/Demo (Chapter 8)
75  UI/Demo (Chapter 8)
76  UI/Demo (Credits)
77  UI/Demo (Credits)
78  UI/Demo (Credits)
79  UI/Demo (Credits)
7A  UI/Demo (Credits)
7B  UI/Demo (Credits)
7C  UI/Demo (Credits)
7D  UI/Demo (Credits)
7E  UI/Demo (Credits)
7F
80
81
82
83
84
85
86
87  UI/Demo (Chapter 8, Sun Cure)
88  UI/Demo (Password Input)
89  UI/Demo (Password, Game Over)
8A  UI/Demo (Password, Round Clear)
8B  UI/Demo (Bad Ending, Game Over)
8C  UI/Demo (Bad Ending, Game Over)
8D  UI/Demo (Bad Ending, Coward)
8E  UI/Demo (Bad Ending, Coward)
8F  UI/Demo (Bad Ending, Coward)
90  UI/Demo (Bad Ending, Coward)
91  UI/Demo (Bad Ending, Thief)
92  UI/Demo (Bad Ending, Thief)
93  UI/Demo (Bad Ending, Thief)
94  UI/Demo (Bad Ending, Harem)
95  UI/Demo (Bad Ending, Harem)
96  UI/Demo (Bad Ending, Harem)
97  UI/Demo (Bad Ending, Harem)
98  UI/Demo (Bad Ending, Harem)
99  UI/Demo (Bad Ending, Pirate)
9A  UI/Demo (Bad Ending, Pirate)
9B  UI/Demo (Bad Ending, Pirate)
9C  UI/Demo (Bad Ending, Nubs)
9D  UI/Demo (Bad Ending, Nubs)
9E  UI/Demo (Bad Ending, Nubs)
9F
A0
A1
A2
A3
A4  UI/Demo (Bad Ending, Zona Pact 1)
A5  UI/Demo (Bad Ending, Zona Pact 1)
A6  UI/Demo (Bad Ending, Zona Pact 1)
A7  UI/Demo (Bad Ending, Zona Pact 1)
A8  UI/Demo (Bad Ending, Zona Pact 1)
A9  UI/Demo (Bad Ending, Zona Pact 2)
AA  UI/Demo (Bad Ending, Zona Pact 2)
AB  UI/Demo (Bad Ending, Zona Pact 2)
AC  UI/Demo (Bad Ending, Zona Pact 3)
AD  UI/Demo (Bad Ending, Zona Pact 3)
AE  UI/Demo (Bad Ending, Zona Pact 3)
AF  UI/Demo (Bad Ending, Zona Pact 3)
B0
B1
B2  UI/Demo (Good Ending)
B3  UI/Demo (Good Ending)
B4  UI/Demo (Good Ending)
B5
B6  UI/Demo (Good Ending)
B7  UI/Demo (Good Ending)
B8  UI/Demo (Good Ending)
B9  UI/Demo (Good Ending)
BA  UI/Demo (Good Ending)
BB  UI/Demo (Good Ending)
BC  UI/Demo (Bad Ending, Game Over)
BD  UI/Demo (Bad Ending, Coward)
BE  UI/Demo (Bad Ending, Thief)
BF  UI/Demo (Bad Ending, Harem)
C0  UI/Demo (Bad Ending, Pirate)
C1  UI/Demo (Bad Ending, Nubs)
C2
C3  UI/Demo (Bad Ending, Zona Pact 1)
C4  UI/Demo (Bad Ending, Zona Pact 2)
C5  UI/Demo (Bad Ending, Zona Pact 3)
C6  UI/Demo (Good Ending)

Password System#

Some of this research is based on prior work on this wiki who graciously took the time to collect passwords from either versions. The following applies to the European version, unless explicitly stated otherwise.

The password is a 6-byte long sequence (so 48 bits) stored to RAM at 7E0038-7E003D. It's initialized to zeroes, represented by the square icons.

Each icon is a 3 bit value.

01   0000 0001
08   0000 1000
40   0100 0000
...

00  square (8th)
01  orb (1st)
02  drop (3rd)
03  snake (4th)
04  skull (5th)
05  heart (6th)
06  leaf (7th)
07  crescent (2nd)

The password follows the following pattern (European version):

0038    Password Checksum (Adds 39-3D)
0039    Level ID
003A    Number of Game Overs (0-255)
003B    Event flags

The checksum calculation is handled by the following instruction:

 00FCCB  F0 1C          BEQ $00FCE9

By changing F0 to 80 at ROM address 7CCB in the European ROM (or 7C9A in the Japanese ROM), the checksum will be ignored, for ease of testing of various invalid passwords and flag combinations. You can either convert the data on your own, or type the password as a hexadecimal value in fields 39-3C (38 will be ignored) and the icon display will be updated in real time to reflect your changes. Use at your own risk. Do note that the default password (all squares) is technically a valid password that starts the player from a new game with 0 Game Overs, but the game is coded to reject it nevertheless.

The game stores the password bytes to the following active gameplay session variables (in RAM Bank $7Exxxx)

0039    0060    1   Level ID
003A    0474    1   Game Overs  
zero    047E    1   L6: Peppy marries Carpenter Grady (01) or Buck (00)
zero    047C    1   L6: Nubs is a viola player (00) or a cucumber farmer (01)
003B    0472    1   Light Orbs
zero    047A    1   L6: Look for Buck (01) or Nick (00)
zero    0476    1   L3: Princess is loved (00) or hated (01)
003C    0084    2   ?
        0086    2   ?
        0480    2   ?
        0482    2   ?
        042C    2   ?
        0852    2   ?
        0854    2   ?
        0856    2   ?
        0858    2   ?

Note: Normally, the Peppy and Nubs choices are mutually exclusive. They're initialized to 00 (Buck, viola player).

There is a possibly unused RAM value among the events at 0478, in between the flags for the third and sixth levels. The password routine seems to completely discard any bits associated with it, and never actually writes anything there. The password parser writes to a bunch of other unknown RAM values - those values might be tied to something meant to be unlockable by the passwords.

Here's a dump of the password parser for the password display, executed every single frame. This is from the European version, the Japanese version is stored at CPU address FB69 instead.

                     --------sub start--------
00FB9A  A2 08 00       LDX #$0008
00FB9D  A5 38          LDA $38
00FB9F  29 07 00       AND #$0007
00FBA2  20 88 FC       JSR $FC88

(Tilemap construction)

                     --------sub start--------
00FC88  0A             ASL
00FC89  A8             TAY
00FC8A  B9 28 F6       LDA $F628,Y
00FC8D  85 00          STA $00
00FC8F  A0 00 00       LDY #$0000
00FC92  B1 00          LDA ($00),Y
00FC94  9F 00 5E 7E    STA $7E5E00,X
00FC98  C8             INY
00FC99  C8             INY
00FC9A  B1 00          LDA ($00),Y
00FC9C  9F 02 5E 7E    STA $7E5E02,X
00FCA0  C8             INY
00FCA1  C8             INY
00FCA2  B1 00          LDA ($00),Y
00FCA4  9F 40 5E 7E    STA $7E5E40,X
00FCA8  C8             INY
00FCA9  C8             INY
00FCAA  B1 00          LDA ($00),Y
00FCAC  9F 42 5E 7E    STA $7E5E42,X
00FCB0  60             RTS
                     ----------------
The tilemap addresses:

$38
7E5E08, 7E5E0A, 7E5E48, 7E5E4A
7E5E0E, 7E5E10, 7E5E4E, 7E5E50
7E5E14, 7E5E16, 7E5E54, 7E5E56
$39
7E5E1A, 7E5E1C, 7E5E5A, 7E5E5C
7E5E20, 7E5E22, 7E5E60, 7E5E62
7E5E26, 7E5E28, 7E5E66, 7E5E68
$3A
7E5E2C, 7E5E2E, 7E5E6C, 7E5E6E
7E5E32, 7E5E34, 7E5E72, 7E5E74
$3B
7E5EC8, 7E5ECA, 7E5F08, 7E5F0A
7E5ECE, 7E5ED0, 7E5F0E, 7E5F10
7E5ED4, 7E5ED6, 7E5F14, 7E5F16
$3C
7E5EDA, 7E5EDC, 7E5F1A, 7E5F1C
7E5EE0, 7E5EE2, 7E5F20, 7E5F22
7E5EE6, 7E5EE8, 7E5F26, 7E5F28
7E5EEC, 7E5EEE, 7E5F2C, 7E5F2E
$3D
7E5EF2, 7E5EF4, 7E5F32, 7E5F34

When confirming the password, this is the checksum routine. It also checks whether it is the default password among other things, but it wasn't investigated in depth. This is from the European version, the Japanese version is stored at CPU address FC9A instead.

                     --------sub start--------
00FCB1  A9 00 00       LDA #$0000
00FCB4  E2 20          SEP #$20
00FCB6  A5 39          LDA $39
00FCB8  18             CLC
00FCB9  65 3A          ADC $3A
00FCBB  18             CLC
00FCBC  65 3B          ADC $3B
00FCBE  18             CLC
00FCBF  65 3C          ADC $3C
00FCC1  18             CLC
00FCC2  65 3D          ADC $3D
00FCC4  AA             TAX
00FCC5  BF 57 9E 01    LDA $019E57,X
00FCC9  C5 38          CMP $38
00FCCB  F0 1C          BEQ $00FCE9

This is the parsing routine that loads the password from the 0038-003C password buffer into the gameplay state.

European Version
00FCE9  A5 39          LDA $39
00FCEB  85 60          STA $60
00FCED  A5 3A          LDA $3A
00FCEF  8D 74 04       STA $0474
00FCF2  9C 7E 04       STZ $047E
00FCF5  9C 7C 04       STZ $047C
00FCF8  A5 3B          LDA $3B
00FCFA  4A             LSR
00FCFB  4A             LSR
00FCFC  4A             LSR
00FCFD  4A             LSR
00FCFE  2E 7E 04       ROL $047E
00FD01  4A             LSR
00FD02  2E 7C 04       ROL $047C
00FD05  8D 72 04       STA $0472
00FD08  C2 20          REP #$20
00FD0A  9C 7A 04       STZ $047A
00FD0D  9C 76 04       STZ $0476
00FD10  A5 3C          LDA $3C
00FD12  4A             LSR
00FD13  2E 7A 04       ROL $047A
00FD16  4A             LSR
00FD17  2E 76 04       ROL $0476
00FD1A  0A             ASL
00FD1B  18             CLC
00FD1C  69 00 80       ADC #$8000
00FD1F  85 84          STA $84
00FD21  A9 02 00       LDA #$0002
00FD24  85 86          STA $86
00FD26  A9 00 80       LDA #$8000
00FD29  8D 80 04       STA $0480
00FD2C  A9 02 00       LDA #$0002
00FD2F  8D 82 04       STA $0482
00FD32  A9 04 00       LDA #$0004
00FD35  8D 2C 04       STA $042C
00FD38  A9 04 00       LDA #$0004
00FD3B  20 0D 8D       JSR $8D0D
00FD3E  A9 5E A0       LDA #$A05E
00FD41  8D 52 08       STA $0852
00FD44  A9 01 00       LDA #$0001
00FD47  8D 54 08       STA $0854
00FD4A  9C 56 08       STZ $0856
00FD4D  9C 58 08       STZ $0858
00FD50  18             CLC
00FD51  60             RTS
                     ----------------

The Japanese version has a mostly identical parser, outside of a very specific line that uses the value C05E (Japan) instead of A05E (Europe).

00FD0D  A9 5E C0       LDA #$C05E
00FD10  8D 52 08       STA $0852

This $0852 RAM offset isn't the game state address used for the level ID or the orb counter, which probably means it's part of the event flags setting up the scene or level. This would mean that the game loaded the player in the correct location all along, but regional differences meant that its scene data was filled with garbage data, usually leading to crashes. This tracks with the fact that the few passwords that are cross-compatible cover the Test Room and the first level up to the Elder's House cutscene, which is where the incompatiblities begin.

You could probably make the game accept the password from the wrong region by changing ROM address 7D0F from C0 to A0 (on a Japanese ROM, to make it accept European passwords) or ROM address 7D40 from A0 to C0 (on an European ROM, to make it accept Japanese passwords) albeit this might require further modifications to make the game generate passwords from game states.

Unkillable Enemies#

The Cualkman enemies from Level 2-1 can't be killed. They're not immune to damage, but their health is automatically set to FF (255) after a few frames. It seems that even with cheats to kill them, they simply continue their animations while no longer harming the player or reacting to any hits,