Problem for Relative Address in dino

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 Relative Address in dino

Post by ShimaPong »

I have found the pointer address for Infinite Ammo in dino.

Code: Select all

:dino:81000000:FFB328:00000032:00FF006D:Infinite Ammo PL1 (Buggy)
But it causes the game crash when you don't have a weapon.

Stored address on pointer is based on 2 bytes (NOT 3 or 4 bytes). In case that $ff9961 is an address for an ammo, the value on pointer address is 0x98f4 (NOT 0xff98f4). Therefore 0xff9961 - 0x0098f4 = 0xff006d and set this value into the extend data field. It's without problem.
But when you lose a weapon, stored value on pointer is changed to 0x0000 then the game crash. I think the cause of the crash is that the cheat engine pokes a value on $ff006d in this time.

Can current cheat engine prevent from this problem ?
User avatar
ianpatt
Posts: 336
Joined: Sat Sep 22, 2001 1:00 am
Location: San Francisco, CA

Post by ianpatt »

Not currently.
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Post by ShimaPong »

I have tried to update cheat.c a bit.

In ReadData function

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);

			if(address)
			{
				address += offset;
				return DoCPURead(cpu, address, bytes, CPUNeedsSwap(cpu) ^ swapBytes);
			}
		}
		break;
In WriteData function

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);

			if(address)
			{
				address += offset;
				DoCPUWrite(data, cpu, address, bytes, CPUNeedsSwap(cpu) ^ swapBytes);
			}
		}
		break;
Simple improvement. If a pointer address has not an index (=0x00000000), doesn't execute DoCPUWrite/Read.

If you finish re-compiling, try to use the following codes.

Code: Select all

:dino:81000000:FFB328:00000032:00FF006D:Infinite Ammo PL1:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka
:dino:81000000:FFB4A8:00000032:00FF006D:Infinite Ammo PL2:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka
:dino:81000000:FFB628:00000032:00FF006D:Infinite Ammo PL3:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka

:dinou:81000000:FFB328:00000032:00FF006D:Infinite Ammo PL1:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka
:dinou:81000000:FFB4A8:00000032:00FF006D:Infinite Ammo PL2:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka
:dinou:81000000:FFB628:00000032:00FF006D:Infinite Ammo PL3:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka

:dinoj:81000000:FFB328:00000032:00FF006D:Infinite Ammo PL1:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka
:dinoj:81000000:FFB4A8:00000032:00FF006D:Infinite Ammo PL2:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka
:dinoj:81000000:FFB628:00000032:00FF006D:Infinite Ammo PL3:Works for Rifle, Gun, Uzi, M-16A1, Shotgun and Bazooka
OK, these codes work fine without a crash problem. RAM code is very simple and separate each players.

In several games, a pointer address is sometimes filled with 0x00.

- Xevious Arrangement in ncv1
If you start single play with 1P, the pointer address for 2P is 0x00.

Code: Select all

:ncv1:83200000:4066CC:00010000:00000071:Rapid Fire PL1
:ncv1:83000000:406A9A:00000003:0000004B:Invincibility PL1
:ncv1:83200000:404D00:00010000:00000071:Rapid Fire PL2
:ncv1:83000000:406A9E:00000003:0000004B:Invincibility PL2
In this case, the cheat engine tries to poke a value on $4B after you set Invincibility PL2. But it will be without problem because $4B is in ROM region.

- Kengo

Code: Select all

:kengo:81000018:E2CAC:00000010:000E0034:Invincibility PL1
:kengo:81010000:E2CAC:00000003:000E0021:Invincibility PL1 (2/2)
:kengo:81000018:E2D5A:00000010:000E0034:Invincibility PL2
:kengo:81010000:E2D5A:00000003:000E0021:Invincibility PL2 (2/2)
V30 (8086) CPU has a "segment" so that "partial" address is often stored into a pointer address. If you start single play with 2P then set Invincibility PL1, the cheat engine tries to poke a value on $E0021 and $E0034. Both addresses are in RAM region but fortunately it seems to be without problem.
Post Reply