Blood Shot issue
Moderator: BigEvilCorporation
Blood Shot issue
Hi,
we have found a weird bug in this game. As soon as you enter the room, turn right and get the player just in the corner. Then, turn the player left slowly, and you will eventually see some perspective errors and a blackish screen which locks up the emulator. Regen 0.972, Genesis Plus GX 1.4.0, Kega Fusion 3.64 and all the Gens versions I have tried so far (including Gens/GS) are affected by this issue.
Does anybody know what is causing this issue?
Thank you.
we have found a weird bug in this game. As soon as you enter the room, turn right and get the player just in the corner. Then, turn the player left slowly, and you will eventually see some perspective errors and a blackish screen which locks up the emulator. Regen 0.972, Genesis Plus GX 1.4.0, Kega Fusion 3.64 and all the Gens versions I have tried so far (including Gens/GS) are affected by this issue.
Does anybody know what is causing this issue?
Thank you.
This is strange indeed, only happens randomly when you turn VERY slowly (to the left or to the right) when the graphics are garbled, it does not crash if you just turn around rapidly...
Have you verified it does not happen similarely on real hardware ? The fact it crashes in every emulator the same way seems to indicate a game bug but you never know, could be bad documented cpu flag or instruction.
According to Gens KMOD, 68k is crashing because A2 got corrupted then apparently PC got loaded with the content of A2 (jump instruction ?)
Have you verified it does not happen similarely on real hardware ? The fact it crashes in every emulator the same way seems to indicate a game bug but you never know, could be bad documented cpu flag or instruction.
According to Gens KMOD, 68k is crashing because A2 got corrupted then apparently PC got loaded with the content of A2 (jump instruction ?)
I have verified it on real hardware (PAL MD-1) and it does work beautifully. No glitches or blackish screens whatsoever.Eke wrote:Have you verified it does not happen similarely on real hardware ? The fact it crashes in every emulator the same way seems to indicate a game bug but you never know, could be bad documented cpu flag or instruction.
As far as i could see, there is a jump to 0x8XXXXX, which is illegal. The address comes from an indexed RAM read, and the index is coming from a MULS (in the particular case i have debugged values are 0x3200 -setup at the beginning of gameplay- and 0x2c, IIRC).Eke wrote:According to Gens KMOD, 68k is crashing because A2 got corrupted then apparently PC got loaded with the content of A2 (jump instruction ?)
on a side note, exception and TRAP0 entry points have quite unexpected values in the ROM header , seems to point out of ROM area (above $200000)...
I have no way to test right now, but try to mirror ROM data above $200000 or change the exception vectors to fit in within ROM and see what happen ?
EDIT: i spotted a possible issue in Musashi regarding the following MULS instruction
with
it seems the src register is not properly masked, it should be:
otherwise,I think it can overflow when it shouldn't
I have no way to test right now, but try to mirror ROM data above $200000 or change the exception vectors to fit in within ROM and see what happen ?
EDIT: i spotted a possible issue in Musashi regarding the following MULS instruction
Code: Select all
static void m68k_op_muls_16_d(void)
{
uint* r_dst = &DX;
uint src = MAKE_INT_16(DY);
uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst)));
uint cyc = getMuls68kCycles(src);
USE_CYCLES(cyc);
*r_dst = res;
FLAG_Z = res;
FLAG_N = NFLAG_32(res);
FLAG_V = VFLAG_CLEAR;
FLAG_C = CFLAG_CLEAR;
}
Code: Select all
/* Allow for architectures that don't have 16-bit sizes */
#if USHRT_MAX == 0xffff
#define MAKE_INT_16(A) (sint16)(A)
#else
#undef sint16
#define sint16 signed int
#undef uint16
#define uint16 unsigned int
INLINE sint MAKE_INT_16(uint value)
{
return (value & 0x8000) ? value | ~0xffff : value & 0xffff;
}
#endif /* USHRT_MAX == 0xffff */
it seems the src register is not properly masked, it should be:
Code: Select all
uint src = MAKE_INT_16(MASK_OUT_ABOVE_16(DY));
Last edited by Eke on Wed Aug 04, 2010 3:34 pm, edited 1 time in total.
No, I have not. I can do when i get home.Eke wrote:on a side note, exception and TRAP0 entry points have quite unexpected values in the ROM header , seems to point out of ROM area (above $200000)...
I have no way to test right now, but try to mirror ROM data above $200000 or change the exception vectors to fit in within ROM and see what happen ?
It is unlikely this is caused by a buggy opcode implementation. That would mean different cores have the same bug. And I do not think that is the case.Eke wrote:EDIT: i spotted a possible issue in Musashi regarding the following MULS instruction
DIVU doesn't set the N flag correctly when there is an overflow. The manual doesn't tell how it should be set, so someone has to test it on a real Mega Drive.
I found that putting $6D00 at location $EDEA fixes the problem. I don't know what to do about the messed up textures in the first room, though.
I found that putting $6D00 at location $EDEA fixes the problem. I don't know what to do about the messed up textures in the first room, though.
Great find ! I see your patch changes a BMI instruction to BLT after a DIVU instruction, patching with BVS also fixes it so it is definitively related to undefined N flag behavior when overflow occurs.
According to this code(from Hatari emulator), the 68k on Atari ST sets N flag when overflow occurs on DIVU/DIVS
It seems to be also the case on Mega Drive.
http://www.youtube.com/watch?v=Lbj1OXv8xuo
EDIT: found another issue in Musashi regarding flags, C flag is not cleared when overflow or division by zero occur, while it should always be cleared everytime DIVU/DIVS is executed.
According to this code(from Hatari emulator), the 68k on Atari ST sets N flag when overflow occurs on DIVU/DIVS
It seems to be also the case on Mega Drive.
i think they are supposed to look like thatI don't know what to do about the messed up textures in the first room, though.
http://www.youtube.com/watch?v=Lbj1OXv8xuo
EDIT: found another issue in Musashi regarding flags, C flag is not cleared when overflow or division by zero occur, while it should always be cleared everytime DIVU/DIVS is executed.
Last edited by Eke on Thu Aug 05, 2010 9:17 am, edited 2 times in total.
So I was wrong. DIVU is buggy. Thanks for your help.Gigasoft wrote:DIVU doesn't set the N flag correctly when there is an overflow. The manual doesn't tell how it should be set, so someone has to test it on a real Mega Drive.
I found that putting $6D00 at location $EDEA fixes the problem. I don't know what to do about the messed up textures in the first room, though.
By the way, how did you figure out?
It was using a negative value as a function table index, so I found out, using Gens' instruction logging feature, that the value was coming from that DIVU instruction, and that it was overflowing, so that the old value in the register was used, without N being set. Since there was a BMI afterwards, it was obvious that N was supposed to be set for the faces that shouldn't be displayed.