68000: more flags fixes, especially N flag calculation. derp. :|

This commit is contained in:
beirich 2011-10-07 05:13:15 +00:00
parent 575a8940cb
commit 18a3f3f87a
4 changed files with 97 additions and 76 deletions

View File

@ -22,7 +22,7 @@ namespace BizHawk.Emulation.CPUs.M68K
sbyte result = (sbyte) (imm & arg);
WriteValueB(dstMode, dstReg, result);
PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesBW[dstMode, dstReg];
N = (result < 0);
N = (result & 0x80) != 0;
Z = (result == 0);
return;
}
@ -33,7 +33,7 @@ namespace BizHawk.Emulation.CPUs.M68K
short result = (short) (imm & arg);
WriteValueW(dstMode, dstReg, result);
PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesBW[dstMode, dstReg];
N = (result < 0);
N = (result & 0x8000) != 0;
Z = (result == 0);
return;
}
@ -44,7 +44,7 @@ namespace BizHawk.Emulation.CPUs.M68K
int result = imm & arg;
WriteValueL(dstMode, dstReg, result);
PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg];
N = (result < 0);
N = (result & 0x80000000) != 0;
Z = (result == 0);
return;
}
@ -105,7 +105,7 @@ namespace BizHawk.Emulation.CPUs.M68K
sbyte immed = (sbyte) ReadWord(PC); PC += 2;
sbyte value = (sbyte) (PeekValueB(mode, reg) | immed);
WriteValueB(mode, reg, value);
N = value < 0;
N = (value & 0x80) != 0;
Z = value == 0;
PendingCycles -= mode == 0 ? 8 : 12 + EACyclesBW[mode, reg];
return;
@ -115,7 +115,7 @@ namespace BizHawk.Emulation.CPUs.M68K
short immed = ReadWord(PC); PC += 2;
short value = (short)(PeekValueW(mode, reg) | immed);
WriteValueW(mode, reg, value);
N = value < 0;
N = (value & 0x8000) != 0;
Z = value == 0;
PendingCycles -= mode == 0 ? 8 : 12 + EACyclesBW[mode, reg];
return;
@ -125,7 +125,7 @@ namespace BizHawk.Emulation.CPUs.M68K
int immed = ReadLong(PC); PC += 4;
int value = PeekValueL(mode, reg) | immed;
WriteValueL(mode, reg, value);
N = value < 0;
N = (value & 0x80000000) != 0;
Z = value == 0;
PendingCycles -= mode == 0 ? 16 : 20 + EACyclesL[mode, reg];
return;
@ -184,7 +184,7 @@ namespace BizHawk.Emulation.CPUs.M68K
sbyte immed = (sbyte)ReadWord(PC); PC += 2;
sbyte value = (sbyte)(PeekValueB(mode, reg) | immed);
WriteValueB(mode, reg, value);
N = value < 0;
N = (value & 0x80) != 0;
Z = value == 0;
PendingCycles -= mode == 0 ? 8 : 12 + EACyclesBW[mode, reg];
return;
@ -194,7 +194,7 @@ namespace BizHawk.Emulation.CPUs.M68K
short immed = ReadWord(PC); PC += 2;
short value = (short)(PeekValueW(mode, reg) | immed);
WriteValueW(mode, reg, value);
N = value < 0;
N = (value & 0x8000) != 0;
Z = value == 0;
PendingCycles -= mode == 0 ? 8 : 12 + EACyclesBW[mode, reg];
return;
@ -204,7 +204,7 @@ namespace BizHawk.Emulation.CPUs.M68K
int immed = ReadLong(PC); PC += 4;
int value = PeekValueL(mode, reg) | immed;
WriteValueL(mode, reg, value);
N = value < 0;
N = (value & 0x80000000) != 0;
Z = value == 0;
PendingCycles -= mode == 0 ? 17 : 20 + EACyclesL[mode, reg];
return;
@ -271,7 +271,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u8 & 0x80) != 0;
D[reg].u8 <<= 1;
}
N = D[reg].s8 < 0;
N = (D[reg].s8 & 0x80) != 0;
Z = D[reg].u8 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -281,7 +281,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u16 & 0x8000) != 0;
D[reg].u16 <<= 1;
}
N = D[reg].s16 < 0;
N = (D[reg].s16 & 0x8000) != 0;
Z = D[reg].u16 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -291,7 +291,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u32 & 0x80000000) != 0;
D[reg].u32 <<= 1;
}
N = D[reg].s32 < 0;
N = (D[reg].s32 & 0x80000000) != 0;
Z = D[reg].u32 == 0;
PendingCycles -= 8 + (rot * 2);
return;
@ -341,7 +341,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u8 & 1) != 0;
D[reg].u8 >>= 1;
}
N = D[reg].s8 < 0;
N = (D[reg].s8 & 0x80) != 0;
Z = D[reg].u8 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -351,7 +351,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u16 & 1) != 0;
D[reg].u16 >>= 1;
}
N = D[reg].s16 < 0;
N = (D[reg].s16 & 0x8000) != 0;
Z = D[reg].u16 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -361,7 +361,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u32 & 1) != 0;
D[reg].u32 >>= 1;
}
N = D[reg].s32 < 0;
N = (D[reg].s32 & 0x80000000) != 0;
Z = D[reg].u32 == 0;
PendingCycles -= 8 + (rot * 2);
return;
@ -411,7 +411,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u8 & 0x80) != 0;
D[reg].s8 <<= 1;
}
N = D[reg].s8 < 0;
N = (D[reg].s8 & 0x80) != 0;
Z = D[reg].u8 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -421,7 +421,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u16 & 0x8000) != 0;
D[reg].s16 <<= 1;
}
N = D[reg].s16 < 0;
N = (D[reg].s16 & 0x8000) != 0;
Z = D[reg].u16 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -431,7 +431,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u32 & 0x80000000) != 0;
D[reg].s32 <<= 1;
}
N = D[reg].s32 < 0;
N = (D[reg].s32 & 0x80000000) != 0;
Z = D[reg].u32 == 0;
PendingCycles -= 8 + (rot * 2);
return;
@ -481,7 +481,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u8 & 1) != 0;
D[reg].s8 >>= 1;
}
N = D[reg].s8 < 0;
N = (D[reg].s8 & 0x80) != 0;
Z = D[reg].u8 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -491,7 +491,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u16 & 1) != 0;
D[reg].s16 >>= 1;
}
N = D[reg].s16 < 0;
N = (D[reg].s16 & 0x8000) != 0;
Z = D[reg].u16 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -501,7 +501,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = X = (D[reg].u32 & 1) != 0;
D[reg].s32 >>= 1;
}
N = D[reg].s32 < 0;
N = (D[reg].s32 & 0x80000000) != 0;
Z = D[reg].u32 == 0;
PendingCycles -= 8 + (rot * 2);
return;
@ -551,7 +551,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = (D[reg].u8 & 0x80) != 0;
D[reg].u8 = (byte) ((D[reg].u8 << 1) | (D[reg].u8 >> 7));
}
N = D[reg].s8 < 0;
N = (D[reg].s8 & 0x80) != 0;
Z = D[reg].u8 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -561,7 +561,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = (D[reg].u16 & 0x8000) != 0;
D[reg].u16 = (ushort) ((D[reg].u16 << 1) | (D[reg].u16 >> 15));
}
N = D[reg].s16 < 0;
N = (D[reg].s16 & 0x8000) != 0;
Z = D[reg].u16 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -571,7 +571,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = (D[reg].u32 & 0x80000000) != 0;
D[reg].u32 = ((D[reg].u32 << 1) | (D[reg].u32 >> 31));
}
N = D[reg].s32 < 0;
N = (D[reg].s32 & 0x80000000) != 0;
Z = D[reg].u32 == 0;
PendingCycles -= 8 + (rot * 2);
return;
@ -621,7 +621,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = (D[reg].u8 & 1) != 0;
D[reg].u8 = (byte)((D[reg].u8 >> 1) | (D[reg].u8 << 7));
}
N = D[reg].s8 < 0;
N = (D[reg].s8 & 0x80) != 0;
Z = D[reg].u8 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -631,7 +631,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = (D[reg].u16 & 1) != 0;
D[reg].u16 = (ushort)((D[reg].u16 >> 1) | (D[reg].u16 << 15));
}
N = D[reg].s16 < 0;
N = (D[reg].s16 & 0x8000) != 0;
Z = D[reg].u16 == 0;
PendingCycles -= 6 + (rot * 2);
return;
@ -641,7 +641,7 @@ namespace BizHawk.Emulation.CPUs.M68K
C = (D[reg].u32 & 1) != 0;
D[reg].u32 = ((D[reg].u32 >> 1) | (D[reg].u32 << 31));
}
N = D[reg].s32 < 0;
N = (D[reg].s32 & 0x80000000) != 0;
Z = D[reg].u32 == 0;
PendingCycles -= 8 + (rot * 2);
return;
@ -676,7 +676,7 @@ namespace BizHawk.Emulation.CPUs.M68K
D[reg].u32 = (D[reg].u32 << 16) | (D[reg].u32 >> 16);
V = C = false;
Z = D[reg].u32 == 0;
N = D[reg].s32 < 0;
N = (D[reg].s32 & 0x80000000) != 0;
PendingCycles -= 4;
}

View File

@ -14,25 +14,25 @@ namespace BizHawk.Emulation.CPUs.M68K
int srcReg = (op & 0x07);
int value = 0;
switch(size)
switch (size)
{
case 1: // Byte
value = ReadValueB(srcMode, srcReg);
WriteValueB(dstMode, dstReg, (sbyte) value);
PendingCycles -= MoveCyclesBW[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)];
N = (value < 0);
N = (value & 0x80) != 0;
break;
case 3: // Word
value = ReadValueW(srcMode, srcReg);
WriteValueW(dstMode, dstReg, (short)value);
PendingCycles -= MoveCyclesBW[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)];
N = (value < 0);
N = (value & 0x8000) != 0;
break;
case 2: // Long
value = ReadValueL(srcMode, srcReg);
WriteValueL(dstMode, dstReg, value);
PendingCycles -= MoveCyclesL[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)];
N = (value < 0);
N = (value & 0x80000000) != 0;
break;
}
@ -146,7 +146,7 @@ namespace BizHawk.Emulation.CPUs.M68K
void MOVEQ()
{
int value = (sbyte) op; // 8-bit data payload is sign-extended to 32-bits.
N = (value < 0);
N = (value & 0x80) != 0;
Z = (value == 0);
V = false;
C = false;

View File

@ -244,8 +244,8 @@ namespace BizHawk.Emulation.CPUs.M68K
int uresult = (ushort)value + data;
if (mode != 1)
{
N = result < 0;
N = (result & 0x8000) != 0;
Z = result == 0;
V = result > short.MaxValue || result < short.MinValue;
C = X = (uresult & 0x10000) != 0;
}
@ -457,16 +457,18 @@ namespace BizHawk.Emulation.CPUs.M68K
int size = (op >> 6) & 3;
int mode = (op >> 3) & 7;
int reg = (op >> 0) & 7;
Log.Error("CPU", "SUBI, bad flag calculations, I = lame");
switch (size)
{
case 0: // byte
{
int immed = (sbyte) ReadWord(PC); PC += 2;
int result = PeekValueB(mode, reg) - immed;
X = C = (result & 0x100) != 0;
sbyte value = PeekValueB(mode, reg);
int result = value - immed;
int uresult = (byte)value - (byte)immed;
X = C = (uresult & 0x100) != 0;
V = result > sbyte.MaxValue || result < sbyte.MinValue;
N = result < 0;
N = (result & 0x80) != 0;
Z = result == 0;
WriteValueB(mode, reg, (sbyte)result);
if (mode == 0) PendingCycles -= 8;
@ -476,10 +478,12 @@ Log.Error("CPU", "SUBI, bad flag calculations, I = lame");
case 1: // word
{
int immed = ReadWord(PC); PC += 2;
int result = PeekValueW(mode, reg) - immed;
X = C = (result & 0x10000) != 0;
short value = PeekValueW(mode, reg);
int result = value - immed;
int uresult = (ushort)value - (ushort)immed;
X = C = (uresult & 0x10000) != 0;
V = result > short.MaxValue || result < short.MinValue;
N = result < 0;
N = (result & 0x8000) != 0;
Z = result == 0;
WriteValueW(mode, reg, (short)result);
if (mode == 0) PendingCycles -= 8;
@ -489,10 +493,12 @@ Log.Error("CPU", "SUBI, bad flag calculations, I = lame");
case 2: // long
{
int immed = ReadLong(PC); PC += 2;
long result = PeekValueL(mode, reg) - immed;
X = C = (result & 0x100000000) != 0;
int value = PeekValueL(mode, reg);
long result = value - immed;
long uresult = (uint)value - (uint)immed;
X = C = (uresult & 0x100000000) != 0;
V = result > int.MaxValue || result < int.MinValue;
N = result < 0;
N = (result & 0x80000000) != 0;
Z = result == 0;
WriteValueL(mode, reg, (int)result);
if (mode == 0) PendingCycles -= 16;
@ -650,38 +656,44 @@ Log.Error("CPU", "SUBI, bad flag calculations, I = lame");
int size = (op >> 6) & 3;
int mode = (op >> 3) & 7;
int reg = (op >> 0) & 7;
Log.Error("CPU", "CMP, very possibly bad flag calculations, I = lame");
switch (size)
{
case 0: // byte
{
int result = ReadValueB(mode, reg) - D[dReg].s8;
N = result < 0;
sbyte value = ReadValueB(mode, reg);
int result = value - D[dReg].s8;
int uresult = (byte)value - D[dReg].u8;
N = (result & 0x80) != 0;
Z = result == 0;
V = result > sbyte.MaxValue || result < sbyte.MinValue;
C = (result & 0x100) != 0;
C = (uresult & 0x100) != 0;
if (mode == 0) PendingCycles -= 8;
PendingCycles -= 4 + EACyclesBW[mode, reg];
return;
}
case 1: // word
{
int result = ReadValueW(mode, reg) - D[dReg].s16;
N = result < 0;
short value = ReadValueW(mode, reg);
int result = value - D[dReg].s16;
int uresult = (ushort)value - D[dReg].u16;
N = (result & 0x8000) != 0;
Z = result == 0;
V = result > short.MaxValue || result < short.MinValue;
C = (result & 0x10000) != 0;
C = (uresult & 0x10000) != 0;
if (mode == 0) PendingCycles -= 8;
PendingCycles -= 4 + EACyclesBW[mode, reg];
return;
}
case 2: // long
{
long result = ReadValueL(mode, reg) - D[dReg].s32;
N = result < 0;
int value = ReadValueL(mode, reg);
long result = value - D[dReg].s32;
long uresult = (uint)value - D[dReg].u32;
N = (result & 0x80000000) != 0;
Z = result == 0;
V = result > int.MaxValue || result < int.MinValue;
C = (result & 0x100000000) != 0;
C = (uresult & 0x100000000) != 0;
PendingCycles -= 6 + EACyclesL[mode, reg];
return;
}
@ -726,21 +738,25 @@ Log.Error("CPU", "CMP, very possibly bad flag calculations, I = lame");
{
case 0: // word
{
long result = A[aReg].s32 - ReadValueW(mode, reg);
N = result < 0;
short value = ReadValueW(mode, reg);
int result = A[aReg].s16 - value;
int uresult = A[aReg].u16 - (ushort)value;
N = (result & 0x8000) != 0;
Z = result == 0;
V = result > int.MaxValue || result < int.MinValue;
C = (result & 0x100000000) != 0;
V = result > short.MaxValue || result < short.MinValue;
C = (uresult & 0x10000) != 0;
PendingCycles -= 6 + EACyclesBW[mode, reg];
return;
}
case 1: // long
{
long result = A[aReg].s32 - ReadValueL(mode, reg);
N = result < 0;
int value = ReadValueL(mode, reg);
long result = A[aReg].s32 - value;
long uresult = A[aReg].u32 - (uint)value;
N = (result & 0x80000000) != 0;
Z = result == 0;
V = result > int.MaxValue || result < int.MinValue;
C = (result & 0x100000000) != 0;
C = (uresult & 0x100000000) != 0;
PendingCycles -= 6 + EACyclesL[mode, reg];
return;
}
@ -782,11 +798,13 @@ Log.Error("CPU", "CMP, very possibly bad flag calculations, I = lame");
case 0: // byte
{
int immed = (sbyte) ReadWord(PC); PC += 2;
int result = ReadValueB(mode, reg) - immed;
N = result < 0;
sbyte value = ReadValueB(mode, reg);
int result = value - immed;
int uresult = (byte)value - (byte)immed;
N = (result & 0x80) != 0;
Z = result == 0;
V = result > sbyte.MaxValue || result < sbyte.MinValue;
C = (result & 0x100) != 0;
C = (uresult & 0x100) != 0;
if (mode == 0) PendingCycles -= 8;
else PendingCycles -= 8 + EACyclesBW[mode, reg];
return;
@ -794,11 +812,13 @@ Log.Error("CPU", "CMP, very possibly bad flag calculations, I = lame");
case 1: // word
{
int immed = ReadWord(PC); PC += 2;
int result = ReadValueW(mode, reg) - immed;
N = result < 0;
short value = ReadValueW(mode, reg);
int result = value - immed;
int uresult = (ushort)value - (ushort)immed;
N = (result & 0x8000) != 0;
Z = result == 0;
V = result > short.MaxValue || result < short.MinValue;
C = (result & 0x10000) != 0;
C = (uresult & 0x10000) != 0;
if (mode == 0) PendingCycles -= 8;
else PendingCycles -= 8 + EACyclesBW[mode, reg];
return;
@ -806,11 +826,13 @@ Log.Error("CPU", "CMP, very possibly bad flag calculations, I = lame");
case 2: // long
{
int immed = ReadLong(PC); PC += 4;
long result = ReadValueL(mode, reg) - immed;
N = result < 0;
int value = ReadValueL(mode, reg);
long result = value - immed;
long uresult = (uint)value - (uint)immed;
N = (result & 0x80000000) != 0;
Z = result == 0;
V = result > int.MaxValue || result < int.MinValue;
C = (result & 0x100000000) != 0;
C = (uresult & 0x100000000) != 0;
if (mode == 0) PendingCycles -= 14;
else PendingCycles -= 12 + EACyclesL[mode, reg];
return;
@ -847,4 +869,4 @@ Log.Error("CPU", "CMP, very possibly bad flag calculations, I = lame");
info.Length = pc - info.PC;
}
}
}
}

View File

@ -214,13 +214,12 @@ namespace BizHawk.Emulation.CPUs.M68K
int value;
switch (size)
{
case 0: value = ReadValueB(mode, reg); PendingCycles -= 4 + EACyclesBW[mode, reg]; break;
case 1: value = ReadValueW(mode, reg); PendingCycles -= 4 + EACyclesBW[mode, reg]; break;
default: value = ReadValueL(mode, reg); PendingCycles -= 4 + EACyclesL[mode, reg]; break;
case 0: value = ReadValueB(mode, reg); PendingCycles -= 4 + EACyclesBW[mode, reg]; N = (value & 0x80) !=0; break;
case 1: value = ReadValueW(mode, reg); PendingCycles -= 4 + EACyclesBW[mode, reg]; N = (value & 0x8000) !=0; break;
default: value = ReadValueL(mode, reg); PendingCycles -= 4 + EACyclesL[mode, reg]; N = (value & 0x80000000) !=0; break;
}
V = false;
C = false;
N = (value < 0);
C = false;
Z = (value == 0);
}