MAME.Core/MAME.Core/cpu/m6502/Ops02.cs

590 lines
14 KiB
C#

using mame;
namespace cpu.m6502
{
public partial class M6502
{
public byte F_C = 0x01, F_Z = 0x02, F_I = 0x04, F_D = 0x08, F_B = 0x10, F_T = 0x20, F_V = 0x40, F_N = 0x80;
private void SET_NZ(byte n)
{
if (n == 0)
{
p = (byte)((p & ~F_N) | F_Z);
}
else
{
p = (byte)((p & ~(F_N | F_Z)) | (n & F_N));
}
}
private void SET_Z(byte n)
{
if ((n) == 0)
{
p |= F_Z;
}
else
{
p &= (byte)(~F_Z);
}
}
private byte RDOPARG()
{
byte b1;
b1 = ReadOpArg(pc.LowWord++);
pendingCycles -= 1;
return b1;
}
private byte RDMEM(ushort addr)
{
byte b1;
b1 = ReadMemory(addr);
pendingCycles -= 1;
return b1;
}
private void WRMEM(ushort addr, byte data)
{
WriteMemory(addr, data);
pendingCycles -= 1;
}
private void BRA(bool cond)
{
sbyte tmp2 = (sbyte)RDOPARG();
if (cond)
{
RDMEM(pc.LowWord);
ea.LowWord = (ushort)(pc.LowWord + (sbyte)tmp2);
if (ea.HighByte != pc.HighByte)
{
RDMEM((ushort)((pc.HighByte << 8) | ea.LowByte));
}
pc.d = ea.d;
}
}
private void EA_ZPG()
{
zp.LowByte = RDOPARG();
ea.d = zp.d;
}
private void EA_ZPX()
{
zp.LowByte = RDOPARG();
RDMEM((ushort)zp.d);
zp.LowByte = (byte)(x + zp.LowByte);
ea.d = zp.d;
}
private void EA_ZPY()
{
zp.LowByte = RDOPARG();
RDMEM((ushort)zp.d);
zp.LowByte = (byte)(y + zp.LowByte);
ea.d = zp.d;
}
private void EA_ABS()
{
ea.LowByte = RDOPARG();
ea.HighByte = RDOPARG();
}
private void EA_ABX_P()
{
EA_ABS();
if (ea.LowByte + x > 0xff)
{
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + x) & 0xff)));
}
ea.LowWord += x;
}
private void EA_ABX_NP()
{
EA_ABS();
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + x) & 0xff)));
ea.LowWord += x;
}
private void EA_ABY_P()
{
EA_ABS();
if (ea.LowByte + y > 0xff)
{
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + y) & 0xff)));
}
ea.LowWord += y;
}
private void EA_ABY_NP()
{
EA_ABS();
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + y) & 0xff)));
ea.LowWord += y;
}
private void EA_IDX()
{
zp.LowByte = RDOPARG();
RDMEM((ushort)zp.d);
zp.LowByte = (byte)(zp.LowByte + x);
ea.LowByte = RDMEM((ushort)zp.d);
zp.LowByte++;
ea.HighByte = RDMEM((ushort)zp.d);
}
private void EA_IDY_P()
{
zp.LowByte = RDOPARG();
ea.LowByte = RDMEM((ushort)zp.d);
zp.LowByte++;
ea.HighByte = RDMEM((ushort)zp.d);
if (ea.LowByte + y > 0xff)
{
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + y) & 0xff)));
}
ea.LowWord += y;
}
private void EA_IDY_NP()
{
zp.LowByte = RDOPARG();
ea.LowByte = RDMEM((ushort)zp.d);
zp.LowByte++;
ea.HighByte = RDMEM((ushort)zp.d);
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + y) & 0xff)));
ea.LowWord += y;
}
private void EA_ZPI()
{
zp.LowByte = RDOPARG();
ea.LowByte = RDMEM((ushort)zp.d);
zp.LowByte++;
ea.HighByte = RDMEM((ushort)zp.d);
}
private void EA_IND()
{
byte tmp;
EA_ABS();
tmp = RDMEM((ushort)ea.d);
ea.LowByte++;
ea.HighByte = RDMEM((ushort)ea.d);
ea.LowByte = tmp;
}
private void PUSH(byte Rg)
{
WRMEM((ushort)sp.d, Rg);
sp.LowByte--;
}
private void PULL(ref byte Rg)
{
sp.LowByte++;
Rg = RDMEM((ushort)sp.d);
}
private void ADC(int tmp)
{
if ((p & F_D) != 0)
{
int c = (p & F_C);
int lo = (a & 0x0f) + (tmp & 0x0f) + c;
int hi = (a & 0xf0) + (tmp & 0xf0);
p &= (byte)(~(F_V | F_C | F_N | F_Z));
if (((lo + hi) & 0xff) == 0)
{
p |= F_Z;
}
if (lo > 0x09)
{
hi += 0x10;
lo += 0x06;
}
if ((hi & 0x80) != 0)
{
p |= F_N;
}
if ((~(a ^ tmp) & (a ^ hi) & F_N) != 0)
{
p |= F_V;
}
if (hi > 0x90)
{
hi += 0x60;
}
if ((hi & 0xff00) != 0)
{
p |= F_C;
}
a = (byte)((lo & 0x0f) + (hi & 0xf0));
}
else
{
int c = (p & F_C);
int sum = a + tmp + c;
p &= (byte)(~(F_V | F_C));
if ((~(a ^ tmp) & (a ^ sum) & F_N) != 0)
{
p |= F_V;
}
if ((sum & 0xff00) != 0)
{
p |= F_C;
}
a = (byte)sum;
SET_NZ(a);
}
}
private void AND(int tmp)
{
a = (byte)(a & tmp);
SET_NZ(a);
}
private void ASL(ref int tmp)
{
p = (byte)((p & ~F_C) | ((tmp >> 7) & F_C));
tmp = (byte)(tmp << 1);
SET_NZ((byte)tmp);
}
private void BCC()
{
BRA((p & F_C) == 0);
}
private void BCS()
{
BRA((p & F_C) != 0);
}
private void BEQ()
{
BRA((p & F_Z) != 0);
}
private void BIT(int tmp)
{
p &= (byte)(~(F_N | F_V | F_Z));
p |= (byte)(tmp & (F_N | F_V));
if ((tmp & a) == 0)
{
p |= F_Z;
}
}
private void BMI()
{
BRA((p & F_N) != 0);
}
private void BNE()
{
BRA((p & F_Z) == 0);
}
private void BPL()
{
BRA((p & F_N) == 0);
}
private void BRK()
{
RDOPARG();
PUSH(pc.HighByte);
PUSH(pc.LowByte);
PUSH((byte)(p | F_B));
p = ((byte)(p | F_I));
pc.LowByte = RDMEM(M6502_IRQ_VEC);
pc.HighByte = RDMEM((ushort)(M6502_IRQ_VEC + 1));
}
private void BVC()
{
BRA((p & F_V) == 0);
}
private void BVS()
{
BRA((p & F_V) != 0);
}
private void CLC()
{
p &= (byte)~F_C;
}
private void CLD()
{
p &= (byte)~F_D;
}
private void CLI()
{
if ((irq_state != (byte)LineState.CLEAR_LINE) && ((p & F_I) != 0))
{
after_cli = 1;
}
p &= (byte)~F_I;
}
private void CLV()
{
p &= (byte)~F_V;
}
private void CMP(int tmp)
{
p &= (byte)~F_C;
if (a >= tmp)
{
p |= F_C;
}
SET_NZ((byte)(a - tmp));
}
private void CPX(int tmp)
{
p &= (byte)~F_C;
if (x >= tmp)
{
p |= F_C;
}
SET_NZ((byte)(x - tmp));
}
private void CPY(int tmp)
{
p &= (byte)~F_C;
if (y >= tmp)
{
p |= F_C;
}
SET_NZ((byte)(y - tmp));
}
private void DEC(ref int tmp)
{
tmp = (byte)(tmp - 1);
SET_NZ((byte)tmp);
}
private void DEX()
{
x = (byte)(x - 1);
SET_NZ(x);
}
private void DEY()
{
y = (byte)(y - 1);
SET_NZ(y);
}
private void EOR(int tmp)
{
a = (byte)(a ^ tmp);
SET_NZ(a);
}
private void INC(ref int tmp)
{
tmp = (byte)(tmp + 1);
SET_NZ((byte)tmp);
}
private void INX()
{
x = (byte)(x + 1);
SET_NZ(x);
}
private void INY()
{
y = (byte)(y + 1);
SET_NZ(y);
}
private void JMP()
{
if (ea.d == ppc.d && pending_irq == 0 && after_cli == 0)
{
if (pendingCycles > 0)
{
pendingCycles = 0;
}
}
pc.d = ea.d;
}
private void JSR()
{
ea.LowByte = RDOPARG();
RDMEM((ushort)sp.d);
PUSH(pc.HighByte);
PUSH(pc.LowByte);
ea.HighByte = RDOPARG();
pc.d = ea.d;
}
private void LDA(int tmp)
{
a = (byte)tmp;
SET_NZ(a);
}
private void LDX(int tmp)
{
x = (byte)tmp;
SET_NZ(x);
}
private void LDY(int tmp)
{
y = (byte)tmp;
SET_NZ(y);
}
private void LSR(ref int tmp)
{
p = (byte)((p & ~F_C) | (tmp & F_C));
tmp = (byte)tmp >> 1;
SET_NZ((byte)tmp);
}
private void ORA(int tmp)
{
a = (byte)(a | tmp);
SET_NZ(a);
}
private void PHA()
{
PUSH(a);
}
private void PHP()
{
PUSH(p);
}
private void PLA()
{
RDMEM((ushort)sp.d);
PULL(ref a);
SET_NZ(a);
}
private void PLP()
{
RDMEM((ushort)sp.d);
if ((p & F_I) != 0)
{
PULL(ref p);
if ((irq_state != (byte)LineState.CLEAR_LINE) && ((p & F_I) == 0))
{
after_cli = 1;
}
}
else
{
PULL(ref p);
}
p |= (byte)(F_T | F_B);
}
private void ROL(ref int tmp)
{
tmp = (tmp << 1) | (p & F_C);
p = (byte)((p & ~F_C) | ((tmp >> 8) & F_C));
tmp = (byte)tmp;
SET_NZ((byte)tmp);
}
private void ROR(ref int tmp)
{
tmp |= (p & F_C) << 8;
p = (byte)((p & ~F_C) | (tmp & F_C));
tmp = (byte)(tmp >> 1);
SET_NZ((byte)tmp);
}
private void RTI()
{
RDOPARG();
RDMEM((ushort)sp.d);
PULL(ref p);
PULL(ref pc.LowByte);
PULL(ref pc.HighByte);
p |= (byte)(F_T | F_B);
if ((irq_state != (byte)LineState.CLEAR_LINE) && ((p & F_I) == 0))
{
after_cli = 1;
}
}
private void RTS()
{
RDOPARG();
RDMEM((ushort)sp.d);
PULL(ref pc.LowByte);
PULL(ref pc.HighByte);
RDMEM(pc.LowWord);
pc.LowWord++;
}
private void SBC(int tmp)
{
if ((p & F_D) != 0)
{
int c = (p & F_C) ^ F_C;
int sum = a - tmp - c;
int lo = (a & 0x0f) - (tmp & 0x0f) - c;
int hi = (a & 0xf0) - (tmp & 0xf0);
if ((lo & 0x10) != 0)
{
lo -= 6;
hi--;
}
p &= (byte)~(F_V | F_C | F_Z | F_N);
if (((a ^ tmp) & (a ^ sum) & F_N) != 0)
{
p |= F_V;
}
if ((hi & 0x0100) != 0)
{
hi -= 0x60;
}
if ((sum & 0xff00) == 0)
{
p |= F_C;
}
if (((a - tmp - c) & 0xff) == 0)
{
p |= F_Z;
}
if (((a - tmp - c) & 0x80) != 0)
{
p |= F_N;
}
a = (byte)((lo & 0x0f) | (hi & 0xf0));
}
else
{
int c = (p & F_C) ^ F_C;
int sum = a - tmp - c;
p &= (byte)~(F_V | F_C);
if (((a ^ tmp) & (a ^ sum) & F_N) != 0)
{
p |= F_V;
}
if ((sum & 0xff00) == 0)
{
p |= F_C;
}
a = (byte)sum;
SET_NZ(a);
}
}
private void SEC()
{
p |= F_C;
}
private void SED()
{
p |= F_D;
}
private void SEI()
{
p |= F_I;
}
private void STA(ref int tmp)
{
tmp = a;
}
private void STX(ref int tmp)
{
tmp = x;
}
private void STY(ref int tmp)
{
tmp = y;
}
private void TAX()
{
x = a;
SET_NZ(x);
}
private void TAY()
{
y = a;
SET_NZ(y);
}
private void TSX()
{
x = sp.LowByte;
SET_NZ(x);
}
private void TXA()
{
a = x;
SET_NZ(a);
}
private void TXS()
{
sp.LowByte = x;
}
private void TYA()
{
a = y;
SET_NZ(a);
}
}
}