public static byte doArithmeticByte(CpuContext ctx, byte a1, byte a2, bool withCarry, bool isSub) { ushort res; /* To detect carry */ if (isSub) { ctx.SETFLAG(Z80Flags.F_N); ctx.VALFLAG(Z80Flags.F_H, (((a1 & 0x0F) - (a2 & 0x0F)) & 0x10) != 0); res = (ushort)(a1 - a2); if (withCarry && ctx.GETFLAG(Z80Flags.F_C)) res--; } else { ctx.RESFLAG(Z80Flags.F_N); ctx.VALFLAG(Z80Flags.F_H, (((a1 & 0x0F) + (a2 & 0x0F)) & 0x10) != 0); res = (ushort)(a1 + a2); if (withCarry && ctx.GETFLAG(Z80Flags.F_C)) res++; } ctx.VALFLAG(Z80Flags.F_S, ((res & 0x80) != 0)); ctx.VALFLAG(Z80Flags.F_C, ((res & 0x100) != 0)); ctx.VALFLAG(Z80Flags.F_Z, ((res & 0xff) == 0)); int minuend_sign = a1 & 0x80; int subtrahend_sign = a2 & 0x80; int result_sign = res & 0x80; bool overflow; if (isSub) { overflow = minuend_sign != subtrahend_sign && result_sign != minuend_sign; } else { overflow = minuend_sign == subtrahend_sign && result_sign != minuend_sign; } ctx.VALFLAG(Z80Flags.F_PV, overflow); adjustFlags(ctx, (byte)res); return (byte)(res & 0xFF); }
public static void doCPL(CpuContext ctx) { ctx.A = (byte)(~ctx.A); ctx.SETFLAG(Z80Flags.F_H | Z80Flags.F_N); adjustFlags(ctx, ctx.A); }
public static void doSCF(CpuContext ctx) { ctx.SETFLAG(Z80Flags.F_C); ctx.RESFLAG(Z80Flags.F_N | Z80Flags.F_H); adjustFlags(ctx, ctx.A); }
public static void doBIT(CpuContext ctx, int Bit, byte Value) { if ((Value & (1 << Bit)) != 0) { ctx.RESFLAG(Z80Flags.F_Z | Z80Flags.F_PV); } else { ctx.SETFLAG(Z80Flags.F_Z | Z80Flags.F_PV); } ctx.SETFLAG(Z80Flags.F_H); ctx.RESFLAG(Z80Flags.F_N); ctx.RESFLAG(Z80Flags.F_S); if ((Bit == 7) && !ctx.GETFLAG(Z80Flags.F_Z)) { ctx.SETFLAG(Z80Flags.F_S); } }