Viewing Issue Advanced Details
ID Category [?] Severity [?] Reproducibility Date Submitted Last Update
00429 Gameplay Minor Have not tried Jan 29, 2008, 11:37 Aug 20, 2008, 15:47
Tester Kale View Status Public Platform
Assigned To andrewga Resolution Fixed OS
Status [?] Resolved Driver fastlane.cpp
Version 0.61 Fixed in Version 0.127u1 Build
Summary 00429: fastlane: the random function of this doesn't work well and always gives a "no bonus"...
Description In Fast Lane there is a square bonus that sometimes appears and give a variable bonus. In MAME, the random function of this doesn't work well and always gives a "no bonus"...
Steps To Reproduce
Additional Information
Regression Version 0.36b13
Affected Sets / Systems fastlane
Attached Files
There are no relationship linked to this issue.
User avatar
Aug 20, 2008, 15:43
ShimaPong's notes from Mameworld:

The above bug has been reported in fastlane. This is protection problem.
The contents of the panel is decided by the value on $3856.

value panel bonus
0 "B" No Bonus
1 "B" No Bonus
2 "B" 500 pts
3 "B" 1000 pts
4 "B" 5000 pts
5 "B" 10000 pts
6 "W" Warp (finish current stage soon)
7 "1UP" extra player car

This value is stored the following routine. It is called during panel carrier in the screen many times over and value is fixed when you collide with it.

9DEC: B6 0F 06 LDA $0F06 // ! read K051733 (protection) !
9DEF: 84 0F ANDA #$0F // A register & 0x0F
9DF1: 44 LSRA // right-shift the value in A register
9DF2: A7 88 16 STA $16,X // set the value into $3856

See K051733 read handler in video/konamiic.c.

READ8_HANDLER( K051733_r )
int op1 = (K051733_ram[0x00] << 8 ) | K051733_ram[0x01];
int op2 = (K051733_ram[0x02] << 8 ) | K051733_ram[0x03];
int op3 = (K051733_ram[0x04] << 8 ) | K051733_ram[0x05];

int rad = (K051733_ram[0x06] << 8 ) | K051733_ram[0x07];
int yobj1c = (K051733_ram[0x08] << 8 ) | K051733_ram[0x09];
int xobj1c = (K051733_ram[0x0a] << 8 ) | K051733_ram[0x0b];
int yobj2c = (K051733_ram[0x0c] << 8 ) | K051733_ram[0x0d];
int xobj2c = (K051733_ram[0x0e] << 8 ) | K051733_ram[0x0f];
case 0x05:
return int_sqrt(op3<<16) & 0xff;

case 0x07:{
if (xobj1c + rad < xobj2c)
return 0x80;

if (xobj2c + rad < xobj1c)
return 0x80;

if (yobj1c + rad < yobj2c)
return 0x80;

if (yobj2c + rad < yobj1c)
return 0x80;

return 0;
return K051733_ram[offset];

In case of offset = 0x06 (NOTE : in fastlane, 0xf00 - 0xf1f are for K051733) this handler returns the value in K051733_ram[0x06] directly. But...

The following is the memory map for K051733 in konamiic.c.

Memory map(preliminary):
00-01 W operand 1
02-03 W operand 2
04-05 W operand 3

00-01 R operand 1 / operand 2
02-03 R operand 1 % operand 2?
04-05 R sqrt(operand 3<<16)

06-07 W distance for collision check
08-09 W Y pos of obj1
0a-0b W X pos of obj1
0c-0d W Y pos of obj2
0e-0f W X pos of obj2
13 W unknown

07 R collision (0x80 = no, 0x00 = yes)

06-07 is distance for collision check and in this game 0x0006 (vs Enemy) or 0x000A (vs Item) is stored in this location.
Yes, 06 is ALWAYS 0x00. Therefore ALWAYS 0x00 is return and it means that the panel is ALWAYS "B" panel with no point.
So you need to add special value return into this handler in case of reading 0x06.

But what value do you return...?

The following routine is collision check.

AA52: 10 BF 0F 06 STY $0F06 // set distance for collision check
AA57: E6 88 2E LDB $2E,X
AA5A: FD 0F 08 STD $0F08 // set Y pos of obj1
AA5D: E6 88 2F LDB $2F,X
AA60: FD 0F 0A STD $0F0A // set X pos of obj1
AA63: E6 C8 2E LDB $2E,U
AA66: FD 0F 0C STD $0F0C // set Y pos of obj2
AA69: E6 C8 2F LDB $2F,U
AA6C: FD 0F 0E STD $0F0E // set Y pos of obj2
AA6F: F7 0F 13 STB $0F13 // ? set Y pos of obj2 ?
AA72: 12 NOP
AA73: 12 NOP
AA74: 12 NOP
AA75: B6 0F 07 LDA $0F07 // do collision check
AA78: 10 2B 00 75 LBMI $AAF1 // go to $AAF1 if NO HIT
AA7C: B6 33 27 LDA $3327 // HIT!

See $AA6f. The value of Y pos of obj2 is stored into $0F0E and $0F13.
But the above memory map says 0x13 is "UNKNOWN" (it's WRITE ONLY and NO READ).
I notice it. Because this value is enough as "random" (obj2 is an enemy or item in this case). So I guess this handler returns the value on K051733_ram[0x13] directly.

case 0x05:
return int_sqrt(op3<<16) & 0xff;

case 0x06:
return K051733_ram[0x13];

case 0x07:{
if (xobj1c + rad < xobj2c)
return 0x80;

BTW, in other games which uses K051733...

The following is Devastators/Garuka (K051733 is $1FA0-$1FBF)

7004: 1F 98 TFR B,A
7006: FD 1F A6 STD $1FA6 // offset = 0x06
7009: B7 1F B3 STA $1FB3 // offset = 0x13
700C: EC 22 LDD $2,Y

0x06 and 0x13 seems to be pair.

The following is Blades of Steel (K051733 is $2F80-$2F9F)

79D4: E6 47 LDB $7,U
79D6: FD 2F 8E STD $2F8E // set Y pos of obj2
79D9: B7 2F 93 STA $2F93 // ? set Y pos of obj2 ?
79DC: 12 NOP
79DD: B6 2F 87 LDA $2F87 // do collilsion check
79E0: 2B B7 BMI $7999

It's very similar to Fast Lane.