Kinda funny how the game is using this pseudo random number generator for a lot of things. Remember, the game always resets the number to 0x2472 on boot up, and then just constantly bit rotates it to the right. It uses it twice in the dizzy calculations.
Lets check out the dizzy code:
002EB4: move.b ($2d1,A5), D0 // Grab a value from the random number generator
002EB8: rts
07A636: andi.w #$1f, D0 // AND the value against 0x1F (Gives a result of 0-31)
07A63A: move.b (A0,D0.w), D0 // This gets a number from another table to randomize the dizzy @ A0+D0 and loads it into D0
07A63E: move.w D0, D6
07A640: lsl.w #6, D0 // Bit Shift D0 to the left 6 times
07A642: lea ($5a,PC), A0; ($7a69e) // Load effective address of 0x7A69E into register A0
07A646: lea (A0,D0.w), A0 //Load the sum of registers A0 + D0 into A0, A0 then becomes the base pointer
07A64A: jsr $2e96.w
002E96: move.w ($2d0,A5), D0
002E9A: andi.w #$202, D0
002E9E: move.w D0, D1
002EA0: lsr.w #8, D0
002EA2: eor.b D0, D1
002EA4: andi #$ee, CCR
002EA8: beq $2eae
002EAE: roxr.w ($2d0,A5) // Rotate the value at the random number generator, so the game won't get the same number twice
002EB2: moveq #$0, D0 // Reset D0 to zero
002EB4: move.b ($2d1,A5), D0 // Load the value at the random number generator into D0
002EB8: rts
07A64E: andi.w #$3e, D0 // Do a AND operation of D0 against 0x3E (Always results in 0--62, even numbers only)
07A652: move.w (A0,D0.w), ($60,A6) // Store the value located at A0 + D0 into the players dizzy value
Ok, now to break this down further.
So the first thing going on is the game grabs a value from the random number generator. This number is AND’d against and a result of 0-31 occurs. The game then takes this result of 0-31 and loads a value from a table at 0x7A65E. This table has the following values:
01: 01
02: 03
03: 02
04: 02
05: 02
06: 02
07: 01
08: 02
09: 02
10: 01
11: 02
12: 00
13: 02
14: 01
15: 02
16: 01
17: 02
18: 02
19: 01
20: 02
21: 01
22: 02
23: 01
24: 02
25: 02
26: 02
27: 02
28: 01
29: 02
30: 03
31: 02
0x00 = 01/32 = 3.125%
0x01 = 09/32 = 28.125%
0x02 = 19/32 = 59.375%
0x03 = 02/32 = 6.25%
Now then. Once the game grabs the value from this table, it takes that value and bit shifts it to the left by 6. This is the same thing as multiplying the value by 64. So now we have:
00 = 00 (Angel table)
01 = 0x40 (64) (Star table)
02 = 0x80 (128) (Bird table)
03 = 0xC0 (192) (Reaper table)
The game then takes this value and adds it to register A0. This gives us our base pointer where we shall start at the dizzy table.
So we know where the dizzy pointer could POSSIBLY begin at (0x7A69E + 0x00 = 0x7A69E) and we know where the dizzy could POSSIBLY end (0x7A69E + 0xC0 = 0x7A75E)
The final piece of the puzzle is the next random value it obtains from the random number generator after it rotates it again. This value is AND’d against 0x3E and gives us a result of 0-62 (even numbers only). The reason they are even, is because the dizzy values are type word, so they contain 2 bytes.
So with this information, we can pinpoint the beginning and the end of the dizzy table!
0x7A69E <— We know this address is the lowest possible base pointer, so this is the beginning of the dizzy table.
0x7A75E <— We know this address is the highest possible base pointer. So now we add the maximum offset possible from the random number generator, 62.
0x7A75E+ 0x3E = 0x7A79C
So the games dizzy table is located at:
Start: 0x7A69E
End: 0x7A79C
And here it is:
http://img839.imageshack.us/img839/3201/dizzytable.png
Ok so now, the possiblities:
We can have a possibility of 4 base pointers.
0x7A69E + 0x00 = 0x7A69E (Angels)
0x7A69E + 0x40 = 0x7A6DE (Stars)
0x7A69E + 0x80 = 0x7A71E (Birds)
0x7A69E + 0xC0 = 0x7A75E (Reapers)
We have 32 possible offsets. 0-62, even numbers only (e.g. 0,2,4,6,8 etc…)
Format: Offset: Dizzy value
Base pointer 1 0x7A69E:
00: 003C
02: 003C
04: 003C
06: 003C
08: 003C
10: 003C
12: 003C
14: 003C
16: 005A
18: 005A
20: 005A
22: 005A
24: 005A
26: 005A
28: 005A
30: 003C
32: 005A
34: 005A
36: 005A
38: 005A
40: 005A
42: 005A
44: 005A
46: 005A
48: 003C
50: 003C
52: 003C
54: 003C
56: 003C
58: 003C
60: 003C
62: 003C
Angels:
0x003C = 17/32 = 53.125%
0x005A = 15/32 = 46.875%
Base Pointer 2 0x7A6DE:
00: 0078
02: 0078
04: 0078
06: 0078
08: 0078
10: 0078
12: 0078
14: 0078
16: 0078
18: 0078
20: 005A
22: 005A
24: 005A
26: 0078
28: 0078
30: 0078
32: 0078
34: 0078
36: 005A
38: 005A
40: 005A
42: 0078
44: 0078
46: 0078
48: 0078
50: 0078
52: 0078
54: 0078
56: 0078
58: 0078
60: 0078
62: 0078
Stars:
0x005A = 06/32 = 18.75%
0x0078 = 26/32 = 81.25%
Base Pointer 3 0x7A71E:
00: 0096
02: 0096
04: 0096
06: 0096
08: 0096
10: 0096
12: 0096
14: 0096
16: 0096
18: 0096
20: 0096
22: 00B4
24: 00B4
26: 00B4
28: 0096
30: 0096
32: 0096
34: 0096
36: 0096
38: 00B4
40: 00B4
42: 00B4
44: 0096
46: 0096
48: 0096
50: 0096
52: 0096
54: 0096
56: 0096
58: 0096
60: 0096
62: 0096
Birds:
0x0096 = 26/32 = 8******1.25%
***0x00B4 = 06/32 = ***18.75%
Base Pointer 4 0x7A81E:
00: 0096
02: 0096
04: 0096
06: 0096
08: 0096
10: 0096
12: 0096
14: 00D2
16: 00D2
18: 00D2
20: 00D2
22: 00D2
24: 00D2
26: 00D2
28: 00D2
30: 00D2
32: 00D2
34: 00D2
36: 00D2
38: 00D2
40: 00D2
42: 00D2
44: 00D2
46: 00D2
48: 0096
50: 0096
52: 0096
54: 0096
56: 0096
58: 0096
60: 0096
62: 0096
Reapers:
0x0096 = 15/32 = 46.875%
0x00D2 = 17/32 = 53.125%
So, now we have all of our numbers in order lets make an example, assume the first random number is 22 (0x16) after the AND and 2nd roll is 44 (0x2C) after the AND.
Example:
0x7A65E + 0x16 (1st random number) = 0x7A674
The value located at 0x7A674 is 0x01.
0x01 * 0x40 = 0x40 (Bit shift it left 6 times)
0x7A69E** + 0x40 = 0x7A6DE (Stars table)**
**0x7A6DE **+ 0x2C (2nd random number) = 0x7A70A
The value located at 0x7A70A = 0x0078 (120)
We rolled a stars dizzy with a value of 120.
So there we have it. Given the numbers we can determine the percentage chance of each dizzy:
Angels: 3.125%
Stars: 28.125%
Birds: 59.375%
Reapers: 6.25%
You can then further break this down on what value you will get based on the type of dizzy you rolled:
Angels:
Dizzy value 60: 53.125%
Dizzy value 90: 46.875%
Stars:
Dizzy value 90: 18.75%
Dizzy value 120: 81.25%
Birds:
Dizzy value 150: 81.25%
Dizzy value 180: 18.75%
Reapers:
Dizzy value 150: 46.875%
Dizzy value 210: 53.125%
I haven’t taken statistics in ages, so if anyone wants to calculate actual roll percentages to get a reaper of 150 or 210, etc… feel free to post them.
I think it’s kinda funny how you can get birds and be worse off than if you got reapers since some of the birds dizzy value is 180, and reapers can be 150.
Another mystery solved.
I’m in yo ST, reversing yo shit!