Blood Shot issue

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
fox68k
Interested
Posts: 13
Joined: Wed Apr 01, 2009 1:22 pm

Blood Shot issue

Post by fox68k » Tue Aug 03, 2010 9:49 pm

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.

Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Wed Aug 04, 2010 8:43 am

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

fox68k
Interested
Posts: 13
Joined: Wed Apr 01, 2009 1:22 pm

Post by fox68k » Wed Aug 04, 2010 9:37 am

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.
I have verified it on real hardware (PAL MD-1) and it does work beautifully. No glitches or blackish screens whatsoever.
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 ?)
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
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Wed Aug 04, 2010 10:45 am

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

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;
}
with

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));
otherwise,I think it can overflow when it shouldn't
Last edited by Eke on Wed Aug 04, 2010 3:34 pm, edited 1 time in total.

fox68k
Interested
Posts: 13
Joined: Wed Apr 01, 2009 1:22 pm

Post by fox68k » Wed Aug 04, 2010 2:52 pm

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 ?
No, I have not. I can do when i get home.
Eke wrote:EDIT: i spotted a possible issue in Musashi regarding the following MULS instruction
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
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Wed Aug 04, 2010 4:29 pm

yes, probably
and after some thought, seems like Musashi implementation is correct, I forgot it was signed multiplication so casting to signed short would extend the sign bit, it does not matter if MSB are masked or not :oops:

Gigasoft
Very interested
Posts: 95
Joined: Fri Jan 01, 2010 2:24 am

Post by Gigasoft » Wed Aug 04, 2010 8:19 pm

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.

Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Thu Aug 05, 2010 8:25 am

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.
I don't know what to do about the messed up textures in the first room, though.
i think they are supposed to look like that :?
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.

Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru » Thu Aug 05, 2010 9:04 am

The textures are messed on real HW. Long ago I've thought my cartridge is glitchy because of that, but later I've seen other cartridges, there the textures were messed as well.

fox68k
Interested
Posts: 13
Joined: Wed Apr 01, 2009 1:22 pm

Post by fox68k » Thu Aug 05, 2010 12:57 pm

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.
So I was wrong. DIVU is buggy. Thanks for your help.

By the way, how did you figure out?

Gigasoft
Very interested
Posts: 95
Joined: Fri Jan 01, 2010 2:24 am

Post by Gigasoft » Thu Aug 05, 2010 8:38 pm

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.

Post Reply