MAMEWorld >> Programming
View all threads Index   Threaded Mode Threaded  

Pages: 1

ole
MAME Porter
Reged: 02/09/14
Posts: 19
Send PM


mame 0.163 on ARM32 - raiden2 issue
#343400 - 08/04/15 12:38 AM


I've compiled mame 0.163 on my Arm linux box (Arm Cortex A17 RK3288 running Ubuntu 14.04)
and I've noticed raiden2 behaves weirdly (compared to my Ubuntu 14.04 on Intel processor where raiden2 runs fine).

What is the issue:
- tanks on the left side of the screen shoot only in vertical direction - straight down
- level 1 bosses have incorrect legs. See screenshot here: http://mujweb.cz/molej/r2/0002.png
- bonusses and tanks occasionally disappear for a split of a second then reappear somewhere else on the screen

Generally it looks just the sprites are affected. Anybody seen this or have an idea how to fix it?

BTW. I had to disable -Wcast-align as it threw a loads of errors on Arm box during compilation. Could it be related?



Haze
Reged: 09/23/03
Posts: 5242
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: ole]
#343406 - 08/04/15 01:11 AM


> I've compiled mame 0.163 on my Arm linux box (Arm Cortex A17 RK3288 running Ubuntu
> 14.04)
> and I've noticed raiden2 behaves weirdly (compared to my Ubuntu 14.04 on Intel
> processor where raiden2 runs fine).
>
> What is the issue:
> - tanks on the left side of the screen shoot only in vertical direction - straight
> down
> - level 1 bosses have incorrect legs. See screenshot here:
> http://mujweb.cz/molej/r2/0002.png
> - bonusses and tanks occasionally disappear for a split of a second then reappear
> somewhere else on the screen
>
> Generally it looks just the sprites are affected. Anybody seen this or have an idea
> how to fix it?
>
> BTW. I had to disable -Wcast-align as it threw a loads of errors on Arm box during
> compilation. Could it be related?

sounds like the protection simulation isn't behaving properly when compiled on ARM, it is responsible for the things you mention amongst others.



R. Belmont
Cuckoo for IGAvania
Reged: 09/21/03
Posts: 9713
Loc: ECV-197 The Orville
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: ole]
#343443 - 08/04/15 04:47 PM


> BTW. I had to disable -Wcast-align as it threw a loads of errors on Arm box during
> compilation. Could it be related?

Nope. What you're seeing is the protection simulation not working properly and the game returning to it's old pre-last-year emulation status. I'm not quite sure why that would be since ARM is little-endian though.



ole
MAME Porter
Reged: 02/09/14
Posts: 19
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: R. Belmont]
#343449 - 08/04/15 11:08 PM


Thanks both of you for the ideas.
I've saved the
UINT32 *data = (UINT32 *)machine.root_device().memregion("gfx3")->base();

contentof the 'data' memregion after decryption (r2crypt.c, raiden2_decrypt_sprites) to a file both on Intel and Arm and the file content is identical. I assume the sprite decryption works fine then on ARM. Besides, sprite graphics seem to be correct, only some of the sprite coordinates and rotation is wrong.

Any other idea what to check (raiden2cop.c I guess)?



Haze
Reged: 09/23/03
Posts: 5242
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: ole]
#343450 - 08/04/15 11:30 PM


it's not the encryption, it's the protection

raiden2cop.c etc.

although you might want to check that everything else using the same CPU works, could be the way you compile it has completely screwed up the core / cpu.



ole
MAME Porter
Reged: 02/09/14
Posts: 19
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: Haze]
#343499 - 08/05/15 11:18 PM


I tested 3 other V30 cpu based machines on my ARM box and they seem to be OK (bomblord, rtype2, dynduke).

I briefely looked to raiden2cop.c and tried to dump some info from
raiden2cop_device::execute_8100
During the raiden2 attract mode while the movie-like intro is being played there is almost no difference between the Arm and Intel (still the function is called many times). When the attract mode reaches gameplay section (the ship and shooting is on screen) the amount of differences is much bigger - probably because there's more sprites doing interesting stuff.
Here is the shortened log of the differences:
Movie-intro:
INT call 2912:execute_8100 addr=0x00007300 val=0x00038000 [ra=40 ang=1.570796 amp=114688.000000 cs=1]
ARM call 2912:execute_8100 addr=0x00007300 val=0x00000000 [ra=80 ang=3.141593 amp=114688.000000 cs=1]

INT call 2937:execute_8100 addr=0x00003780 val=0x00000c8e [ra=7e ang=3.092505 amp=32768.000000 cs=1]
ARM call 2937:execute_8100 addr=0x00003780 val=0x00000000 [ra=80 ang=3.141593 amp=32768.000000 cs=1]

INT call 5357:execute_8100 addr=0x00003860 val=0x00006d74 [ra=6e ang=2.699806 amp=32768.000000 cs=1]
ARM call 5357:execute_8100 addr=0x00003860 val=0x00000000 [ra=80 ang=3.141593 amp=32768.000000 cs=1]


It looks on Intel the raw angle varies (0x40, 0x7e, 0x6e) but the same call on ARM fetches raw angle 0x80.

Gameplay-intro:
INT call 7998:execute_8100 addr=0x00003780 val=0xffff4252 [ra=de ang=5.448700 amp=32768.000000 cs=1]
ARM call 7998:execute_8100 addr=0x00003780 val=0xffff4afc [ra=e0 ang=5.497787 amp=32768.000000 cs=1]

INT call 8021:execute_8100 addr=0x00003780 val=0xffff6782 [ra=e6 ang=5.645049 amp=32768.000000 cs=1]
ARM call 8021:execute_8100 addr=0x00003780 val=0xffff71c8 [ra=e8 ang=5.694137 amp=32768.000000 cs=1]

INT call 8211:execute_8100 addr=0x00003780 val=0x0000abea [ra=1e ang=0.736311 amp=32768.000000 cs=1]
ARM call 8211:execute_8100 addr=0x00003780 val=0x0000b504 [ra=20 ang=0.785398 amp=32768.000000 cs=1]

Now the raw angle still differs, but at least they are not stuck on value 0x80. On ARM they are always bigger than Intel by value of 2.
Also these differences only occurr on address from the first RAM region (AM_RANGE(0x00800, 0x0bfff)). Raw angle values from the second ram region (AM_RANGE(0x10000, 0x1efff)) etc. are correct - ie they match the Intel value.
If you'd like (by any chance) to reproduce the log, put the following printout at the end of the function:
printf("execute_8100 addr=0x%08x val=0x%08x [ra=%02x ang=%f amp=%f cs=%i]\n", cop_regs[0] + 16, res, raw_angle, (float) angle, (float) amp, cop_scale );

I don't know whether this is usefull at all. So far it seems to me the lower part of the emulated ram on my ARM box contains incorrect data.

Related to compilation options, I've removed all compilation options specific to ARM while compiling the CPU, but found no difference in the behaviour. I also disabled optimisation to see whether I get different results, but apart from much slower execution of the game's code the result is completely the same as previously (ie. the issue still remains).



Haze
Reged: 09/23/03
Posts: 5242
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: ole]
#343573 - 08/07/15 03:44 AM


does the r2dx_v33_r2 set work properly? it has entirely different protection.

you're probably on your own for debugging the main set tho.. it really sounds like an endian issue, but like RB said, I thought the endian on the ARM chips was the same as a PC.



AWJ
Reged: 03/08/05
Posts: 936
Loc: Ottawa, Ontario
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: Haze]
#343595 - 08/07/15 02:56 PM


> does the r2dx_v33_r2 set work properly? it has entirely different protection.
>
> you're probably on your own for debugging the main set tho.. it really sounds like an
> endian issue, but like RB said, I thought the endian on the ARM chips was the same as
> a PC.

Adding to that, I'm quite sure raiden2.c does work on PowerPC, which is opposite-endian to Intel. I distinctly remember fixing it for MacBox360 (and the problems were in the ROM loading and sprite decryption, the protection code was just fine)

Maybe the ARM compiler does int-float casting in a different way and it's causing an integer overflow to occur somewhere that doesn't occur on Intel (e.g. by doing a float conversion after a multiplication instead of before it) Remember that signed integer overflow is undefined behaviour in C/C++; it's quite legal for one compiler to do the conversion before multiplication and another to do the conversion after, depending on which is faster on a given architecture.

On a related note one of the Yamaha FM chips doesn't work properly on PowerPC builds, and it's probably not endian-related per se because the code never casts between different integer sizes. It does, however, cast back and forth between ints and doubles all over the place just like raiden2cop.c does.



ole
MAME Porter
Reged: 02/09/14
Posts: 19
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: Haze]
#343627 - 08/07/15 10:32 PM


> does the r2dx_v33_r2 set work properly? it has entirely different protection.

Surprisingly it does work OK on ARM! No targeting or bullet issues or incorrectly rotated sprites. Interesting.

> you're probably on your own for debugging the main set tho..

That's fine. I'm now convinced it's the protection code that's the peretrator on ARM :-). I'll investigate more...

> it really sounds like an endian issue, but like RB said, I thought the endian on the ARM chips was the same as a PC.

I doublechecked and my ARM box is little-endian.

Thanks for the tips!



ole
MAME Porter
Reged: 02/09/14
Posts: 19
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue new [Re: AWJ]
#343628 - 08/07/15 10:36 PM


Thanks for the tip, I'll replace all doubles to floats and see whether it makes a difference. If not I'll try to use integer math, just out of curiosity.



ole
MAME Porter
Reged: 02/09/14
Posts: 19
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue FIXED! new [Re: ole]
#343640 - 08/08/15 01:33 AM


Ah... finally fixed !

the issue is indeed in raiden2cop.c, there's automatic casting from negative float to unsigned int when atan() function is used. On ARM the result is always 0 (not on Intel though), but explicit conversion to signed int fixes it.

so for example:
cop_angle = atan(double(dy) / double(dx)) * 128.0 / M_PI;
should be
cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI);

in order to make it work on ARM.

Later on I found some blog confirming the issue:
http://www.embeddeduse.com/2013/08/25/casting-a-negative-float-to-an-unsigned-int/

The guy in the blog above recommends using -Wconversion warning option so the issue is more obvious during compilation.



AWJ
Reged: 03/08/05
Posts: 936
Loc: Ottawa, Ontario
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue FIXED! new [Re: ole]
#343648 - 08/08/15 03:36 AM


> Ah... finally fixed !
>
> the issue is indeed in raiden2cop.c, there's automatic casting from negative float to
> unsigned int when atan() function is used. On ARM the result is always 0 (not on
> Intel though), but explicit conversion to signed int fixes it.
>
> so for example:
> cop_angle = atan(double(dy) / double(dx)) * 128.0 / M_PI;
> should be
> cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI);
>
> in order to make it work on ARM.
>
> Later on I found some blog confirming the issue:
> http://www.embeddeduse.com/2013/08/25/casting-a-negative-float-to-an-unsigned-int/
>
> The guy in the blog above recommends using -Wconversion warning option so the issue
> is more obvious during compilation.

Congratulations on finding the issue and fixing it! If you're able to, please submit a Github pull request with the fix.



ole
MAME Porter
Reged: 02/09/14
Posts: 19
Send PM


Re: mame 0.163 on ARM32 - raiden2 issue FIXED! new [Re: AWJ]
#343710 - 08/09/15 01:04 AM


> Congratulations on finding the issue and fixing it! If you're able to, please submit
> a Github pull request with the fix.

Thanks.
Github: I'm affraid I don't have a permission to push my branch to origin.

Anyway, here is the patch. Hope it helps.
------------------------ src/mame/machine/raiden2cop.c ------------------------
index 7194ca3..0190e69 100644
@@ -997,7 +997,7 @@ void raiden2cop_device::LEGACY_execute_130e(address_space &space, int offset, UI
cop_angle = 0;
}
else {
- cop_angle = atan(double(dy) / double(dx)) * 128.0 / M_PI;
+ cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI);
if (dx < 0)
cop_angle += 0x80;
}
@@ -1020,7 +1020,7 @@ void raiden2cop_device::LEGACY_execute_130e_cupsoc(address_space &space, int off
cop_angle = 0;
}
else {
- cop_angle = atan(double(dy) / double(dx)) * 128.0 / M_PI;
+ cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI);
if (dx < 0)
cop_angle += 0x80;
}
@@ -1057,7 +1057,7 @@ void raiden2cop_device::execute_2288(address_space &space, int offset, UINT16 da
cop_angle = 0;
}
else {
- cop_angle = atan(double(dx) / double(dy)) * 128 / M_PI;
+ cop_angle = (int)(atan(double(dx) / double(dy)) * 128 / M_PI);
if (dy < 0)
cop_angle += 0x80;
}
@@ -1095,7 +1095,7 @@ void raiden2cop_device::execute_338e(address_space &space, int offset, UINT16 da
cop_angle = 0;
}
else {
- cop_angle = atan(double(dx) / double(dy)) * 128 / M_PI;
+ cop_angle = (int)(atan(double(dx) / double(dy)) * 128 / M_PI);
if (dy < 0)
cop_angle += 0x80;
}
@@ -1553,7 +1553,7 @@ void raiden2cop_device::LEGACY_execute_e30e(address_space &space, int offset, UI
cop_angle = 0;
}
else {
- cop_angle = atan(double(dy) / double(dx)) * 128.0 / M_PI;
+ cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI);
if (dx < 0)
cop_angle += 0x80;
}


Pages: 1

MAMEWorld >> Programming
View all threads Index   Threaded Mode Threaded  

Extra information Permissions
Moderator:  Pi 
0 registered and 5 anonymous users are browsing this forum.
You cannot start new topics
You cannot reply to topics
HTML is enabled
UBBCode is enabled
Thread views: 2694