Mail has been fixed; you should now be able to confirm your e-mail address, watch pages, and the like.
Please report any issues on Discord.

Notes:Alien Storm (Genesis)

From The Cutting Room Floor
Jump to navigation Jump to search

This page contains notes for the game Alien Storm (Genesis).


Credits Select

After entering a successful button sequence in Options (more on that in a moment), bit 0x01 is set in memory address $FFFF29. This bit is checked for when entering the Sound Test, and if it's set, bit 0x02 is set in $FFFF29, unlocking the credits select in Options.

Most games store their button cheats as a sequence of bytes (e.g., 0x01, 0x02, 0x04, 0x08 for up, down, left, right)

This game uses XOR and bit shifting operations instead and checks for word #$3929 in $FFFF1C.

The programming looks like this:

00:2DF8  B1 41  EOR.W   D0,D1
00:2DFA  E2 49  LSR.W   #1,D1
00:2DFC  64 00  BCC     #$0006 [00:2E04]
00:2E00  0A 41  EORI.W  #$8810,D1
00:2E04  31 C1  MOVE.w  D1,($FF1C)
00:2E08  B2 7A  CMP.W   $01FA(PC),D1

00003004 3929

  • First, XOR the controller button press (D0) with the word at memory address $FFFF1C (D1).
  • Next, shift right D1 once.
  • If bit 0x0001 is set at the time of the shift, XOR D1 with #$8810.
  • Repeat these steps until D1 is #$3929, then you're done.

A program, like the one at the bottom of this page, can be used to solve the problem.

Below is a detailed look at one possible button sequence that will work.

EXAMPLE:

button sequence: up, down, C, down, B, B, B, up, C
button sequence as byte values: 01, 02, 10, 02, 40, 40, 40, 01, 10

up   0001 ^ 0000 = 0001
     0001 >> 0001 = 0000
     0000 ^ 8810 = 8810

down 0002 ^ 8810 = 8812 
     8812 >> 0001 = 4409

C    0010 ^ 4409 = 4419
     4419 >> 0001 = 220C
     220C ^ 8810 = AA1C

down 0002 ^ AA1C = AA1E
     AA1E >> 0001 = 550F

B    0040 ^ 550F = 554F
     554F >> 0001 = 2AA7
     2AA7 ^ 8810 = A2B7

B    0040 ^ A2B7 = A2F7
     A2F7 >> 0001 = 517B
     517B ^ 8810 = D96B

B    0040 ^ D96B = D92B
     D92B >> 0001 = 6C95
     6C95 ^ 8810 = E485

up   0001 ^ E485 = E484
     E484 >> 0001 = 7242

C    0010 ^ 7242 = 7252
     7252 >> 0001 = 3929

No solution exists that uses less than 9 button presses.

There is no maximum limit on the number of presses, though. This opens the door for some creative ways to solve the problem, like using a controller with auto rapid-fire enabled on a single button to rack up tens of thousands of presses towards an eventual solution. The totals are 37,757 presses for button A, 63,671 for B, or 57,625 for C.

Some button sequences will inadvertently remap the control pad setup at the bottom of the options screen, resulting in a failed cheat. Any sequence that doesn't involve d-pad left or right is guaranteed to work.

Solve #$3929

Here is a small JavaScript program to generate a button sequence, save it as a .html file.

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function generatecode()
{
var ControllerArray = new Array(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40);
//controller buttons u, d, l, r, C, A, B

var Rand = Math.floor(Math.random()*7); //select a random button press from ControllerArray

var RecordedPresses = new Array(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
//used to store sequence of 9 random button presses

var Counter = 0x00;
var FF1C = 0x0000;
var CarryFlag = new Boolean();

while (FF1C != 0x3929)
{
if (Counter > 0x08) //if 9 button presses made and no solution, start over
{
Counter = 0x00;
FF1C = 0x0000;     
}

RecordedPresses[Counter] = ControllerArray[Rand];
FF1C = FF1C ^ ControllerArray[Rand];
Rand = Math.floor(Math.random()*7);
                
CarryFlag = (FF1C & 0x0001) == 0x0001;
FF1C = FF1C >> 1;

if (CarryFlag == true)
{
FF1C = FF1C ^ 0x8810;
}

Counter++;
}

var ButtonText = new Array();
ButtonText[0x01] = "up";
ButtonText[0x02] = "down";
ButtonText[0x04] = "left";
ButtonText[0x08] = "right";
ButtonText[0x10] = "C";
ButtonText[0x20] = "A";
ButtonText[0x40] = "B";

document.getElementById("RecordedPresses1").innerHTML=ButtonText[RecordedPresses[0x00]];
document.getElementById("RecordedPresses2").innerHTML=ButtonText[RecordedPresses[0x01]];
document.getElementById("RecordedPresses3").innerHTML=ButtonText[RecordedPresses[0x02]];
document.getElementById("RecordedPresses4").innerHTML=ButtonText[RecordedPresses[0x03]];
document.getElementById("RecordedPresses5").innerHTML=ButtonText[RecordedPresses[0x04]];
document.getElementById("RecordedPresses6").innerHTML=ButtonText[RecordedPresses[0x05]];
document.getElementById("RecordedPresses7").innerHTML=ButtonText[RecordedPresses[0x06]];
document.getElementById("RecordedPresses8").innerHTML=ButtonText[RecordedPresses[0x07]];
document.getElementById("RecordedPresses9").innerHTML=ButtonText[RecordedPresses[0x08]];
}
</script>
</head>
<body>

<h1>Solve #$3929</h1>

<button type="button" onclick="generatecode()">Generate</button>

<p>Click the button to begin.</p>

<p id="RecordedPresses1"> </p>
<p id="RecordedPresses2"> </p>
<p id="RecordedPresses3"> </p>
<p id="RecordedPresses4"> </p>
<p id="RecordedPresses5"> </p>
<p id="RecordedPresses6"> </p>
<p id="RecordedPresses7"> </p>
<p id="RecordedPresses8"> </p>
<p id="RecordedPresses9"> </p>

</body>
</html>