Problem for Set/Clear Bit on Relative Address

If you are having problems finding or using cheats for an Emulator (particularly MAME/MESS) or have found a trick that you wish to share this is the place to do it. But please read the Cheat FAQ first.
Post Reply
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Problem for Set/Clear Bit on Relative Address

Post by ShimaPong »

Neo Bomberman needs Relative Address mode to enable several codes. But Set/Clear Bit prevents from working correctly, for example the following code.

Code: Select all

:neobombe:83000018:10449E:00000001:00000047:Always Have Bomb Kick PL1 (Incomplete):Can't use Bomb Catch at the same time
:neobombe:83000018:10449E:00000004:00000047:Always Have Bomb Catch PL1 (Incomplete):Can't use Bomb Kick at the same time
You can't get Bomb Kick and Bomb Catch at the same time. An address is the same and the management for these items is based on a bit. Bit 1 is for Bomb Kick and Bit 2 is for Bomb Catch. But if you set both codes, the value becomes 0x04 instead of 0x05 and Bomb Kick is disabled.

Normal bit mask works fine though. This address in the 1st stage is always $101647.

Code: Select all

:neobombe:00000000:101647:00000001:00000001:Always Have Bomb Kick PL1
:neobombe:00000000:101647:00000004:00000004:Always Have Bomb Catch PL1
You can get both items at the same time in this case. I made sure that the value is changed to 0x05.

Why does Set/Clear Bit on Relative Address work incompletely ?
Kriptokapi
DISABLED ACCOUNT
Posts: 135
Joined: Sat May 06, 2006 9:03 am
Location: Italy (Sardinia, OR / CA)

ShimaP is a smart guy (too much?)

Post by Kriptokapi »

Hm. I guess you must be nearly a genie to reply to this question!

:wink:
DISABLED ACCOUNT
User avatar
ianpatt
Posts: 336
Joined: Sat Sep 22, 2001 1:00 am
Location: San Francisco, CA

Post by ianpatt »

Both the relative offset and the bitmask use the extend data field (the last numeric field in the cheat), so only one can work at a time.
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Post by ShimaPong »

ianpatt wrote:Both the relative offset and the bitmask use the extend data field (the last numeric field in the cheat), so only one can work at a time.
What a strange it is ! According to "Extended Data Field - Relative Address" info in cheat.c, "Use the special set/clear bits operations instead of a masked write". I think that Set/Clear Bit is not influenced by the value in the extended data field. Is it wrong ?

And the same code on danceyes works without this problem.

Code: Select all

:danceyes:82800018:002157E8:00000001:000000E2:Always Have Speed Up
:danceyes:82000018:002157E8:00000002:000000E2:Always Have Invincibility Attack
:danceyes:82110000:002157E8:00000003:000000DC:Always Have Invincibility Attack (2/2)
:danceyes:82800018:002157E8:00000008:000000E2:Always Have Paralyze
:danceyes:82000018:002157E8:00000020:000000E2:Always Have Time Stop
:danceyes:82110000:002157E8:00000002:000000F2:Always Have Time Stop (2/2)
:danceyes:82800018:002157E8:00000040:000000E2:Always Have X-Attack
:danceyes:82800018:002157E8:00000080:000000E2:Always Have Y-Attack
Setting Speed Up and X-Attack at the same time, you can surely get both items and confirm that the value is changed to 0x41.

It's too mysterious...
User avatar
ianpatt
Posts: 336
Joined: Sat Sep 22, 2001 1:00 am
Location: San Francisco, CA

Post by ianpatt »

Heh, sorry about that. Was posting from work and couldn't check the code. There's a typo in ReadData that makes it applies random byte-swapping when reading an indirect value. To fix, replace:

Code: Select all

		case kLocation_IndirectIndexed:
		{
			UINT32	address;
			INT32	offset = action->extendData;
			UINT8	cpu = (parameter >> 2) & 0x7;
			UINT8	addressBytes = (parameter & 0x3) + 1;
			CPUInfo	* info = GetCPUInfo(cpu);

			address = DoCPURead(cpu, action->address, addressBytes, CPUNeedsSwap(parameter) ^ swapBytes);
			if(info)
				address = DoShift(address, info->addressShift);
			address += offset;

			return DoCPURead(cpu, address, bytes, CPUNeedsSwap(parameter) ^ swapBytes);
		}
		break;
with

Code: Select all

		case kLocation_IndirectIndexed:
		{
			UINT32	address;
			INT32	offset = action->extendData;
			UINT8	cpu = (parameter >> 2) & 0x7;
			UINT8	addressBytes = (parameter & 0x3) + 1;
			CPUInfo	* info = GetCPUInfo(cpu);

			address = DoCPURead(cpu, action->address, addressBytes, CPUNeedsSwap(cpu) ^ swapBytes);
			if(info)
				address = DoShift(address, info->addressShift);
			address += offset;

			return DoCPURead(cpu, address, bytes, CPUNeedsSwap(cpu) ^ swapBytes);
		}
		break;
in the ReadData function. (lines 9674-9689 in this copy of the code)

EDIT: fixed reference to incorrect function (oops)
Last edited by ianpatt on Thu Jun 22, 2006 8:03 pm, edited 1 time in total.
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Post by ShimaPong »

Thanks a lot ! I have confirmed that Set/Clear Bit problem has been fixed.

But sorry your information is incorrect a bit. Because not WriteData (9769-9784) but ReadData (9674-9689). "CPUNeedsSwap(parameter)" is found in ReadData section instead of WriteData.

Also fixed Rapid Fire problem on androdun.

Code: Select all

:androdun:81040018:105542:00000008:00100046:Rapid Fire PL1 (Buggy):Can't move and crash the game when you get the UNIT
:androdun:81040018:105546:00000008:00100046:Rapid Fire PL2 (Buggy):Can't move and crash the game when you get the UNIT
The above code used Clear Bit causes the game crash when you get a Unit item before the modification. Now it works fine !
User avatar
ianpatt
Posts: 336
Joined: Sat Sep 22, 2001 1:00 am
Location: San Francisco, CA

Post by ianpatt »

Gah, sorry about that again. Edited original post.
Post Reply