public override int Execute(C6502 cpu, byte operand) { int result = (cpu.State.RegA - operand - (1 - (cpu.State.ProcessorStatus & (byte)StatusFlags.Carry))); SetOverflow(cpu, () => ((cpu.State.RegA ^ operand) & 0x80) != 0 && ((cpu.State.RegA ^ result) & 0x80) != 0); cpu.State.RegA = (byte)(result & 0xFF); SetNegative(cpu, () => Helper.IsSigned(cpu.State.RegA)); SetZero(cpu, () => cpu.State.RegA == 0); SetCarry(cpu, () => (result & 0x100) == 0); return(2); }
public override int Execute(C6502 cpu, byte operand) { byte b1 = cpu.Pop(); byte b2 = cpu.Pop(); // low byte first, b1 is low byte ushort address = (ushort)((b2 << 8) | b1); cpu.State.ProgramCounter = (ushort)(address + 1); return(6); }
public override int Execute(C6502 cpu, byte operand) { // Relative to PC, therefore we need to emulate an immediate addressing mode to just use the parameter int address = (cpu.State.ProgramCounter + operand); if (!cpu.State.IsFlagSet((byte)StatusFlags.Negative)) { // TODO: page boundary shit. cpu.State.ProgramCounter = (ushort)(address & 0xFFFF); } return(2); }
public override int Execute(C6502 cpu, byte operand) { var state = cpu.State as ExecutionState; ushort toPush = (ushort)(cpu.State.ProgramCounter - 1); // TODO: check if this is the correct order. I guess so (DS) cpu.Push((byte)((toPush >> 8) & 0xFF)); cpu.Push((byte)(toPush & 0xFF)); cpu.State.ProgramCounter = AddressingType.GetAddress(cpu, state.Parameter); return(6); }
public override int Execute(C6502 cpu, byte operand) { ExecutionState state = cpu.State as ExecutionState; if (state == null) { throw new Exception("Something BAAAADD happened"); } cpu.Memory[AddressingType.GetAddress(cpu, state.Parameter)] = state.RegX; // I don't know what the f**k this is but it is 2 everywhere (DS). return(2); }
public override int Execute(C6502 cpu, byte operand) { var state = cpu.State as ExecutionState; int result = operand << 1; SetCarry(cpu, () => (result & 0x100) != 0); result &= 0xFF; SetNegative(cpu, () => Helper.IsSigned((byte)result)); SetZero(cpu, () => result == 0); // Hacky but it will do the trick. Accumulator Addressing is an outcast. if (AddressingType is AccumulatorAddressing) { cpu.State.RegA = (byte)result; } else { cpu.Memory[AddressingType.GetAddress(cpu, state.Parameter)] = (byte)result; } return(2); }
public override int Execute(C6502 cpu, byte operand) { var state = cpu.State as ExecutionState; SetCarry(cpu, () => (operand & 0x01) != 0); int result = operand >> 1; result &= 0xFF; // Negative is always set in this opcode SetNegative(cpu, () => true); SetZero(cpu, () => result == 0); // Hacky but it will do the trick. Accumulator Addressing is an outcast. if (AddressingType is AccumulatorAddressing) { cpu.State.RegA = (byte)result; } else { cpu.Memory[AddressingType.GetAddress(cpu, state.Parameter)] = (byte)result; } return(2); }
public override int Execute(C6502 cpu, byte operand) { cpu.State.StackPointer = cpu.State.RegX; return(2); }
public ushort GetAddress(C6502 cpu, ushort parameter) { return((ushort)(cpu.State.RegX + (parameter & 0xFF))); }
public override int Execute(C6502 cpu, byte operand) { cpu.Push(cpu.State.ProcessorStatus); return(3); }
public ushort GetAddress(C6502 cpu, ushort parameter) { // Basically not implemented... todo, check if should throw exception return((byte)(parameter & 0xFF)); }
public byte GetOperand(C6502 cpu, ushort parameter) { return((byte)(parameter & 0xFF)); }
public ushort GetAddress(C6502 cpu, ushort parameter) { return((UInt16)(parameter & 0xFF)); }
public override int Execute(C6502 cpu, byte operand) { cpu.State.ClearFlag((byte)StatusFlags.Overflow); return(2); }
public ushort GetAddress(C6502 cpu, ushort parameter) { return((ushort)(cpu.State.RegY + parameter)); }
static void Main(string[] args) { C6502 c = new C6502(); // immediate: c.Memory[0x00] = 0xA9; c.Memory[0x01] = 0xFF; // absolute (load value from memory @ address 0x16A0) c.Memory[0x16A0] = 0x13; c.Memory[0x02] = 0xAD; c.Memory[0x03] = 0xA0; c.Memory[0x04] = 0x16; // zero page c.Memory[0xFC] = 0x14; c.Memory[0x05] = 0xA5; c.Memory[0x06] = 0xFC; // Load X immediate c.Memory[0x07] = 0xA2; c.Memory[0x08] = 0x06; // Pre-Indexed Indirect Addressing c.Memory[0x46] = 0x05; c.Memory[0x47] = 0x20; c.Memory[0x2005] = 0xFF; c.Memory[0x09] = 0xA1; c.Memory[0x0A] = 0x46; // Load Y immediate c.Memory[0x0B] = 0xA0; c.Memory[0x0C] = 0x04; // Post-Indexed Indirect Addressing c.Memory[0x48] = 0x19; c.Memory[0x49] = 0x32; c.Memory[0x3219] = 0xCF; c.Memory[0x0D] = 0xB1; c.Memory[0x0E] = 0x48; // Zero Page Indexed Addressing c.Memory[0x0F] = 0xA2; c.Memory[0x10] = 0xDF; c.Memory[0xDF] = 0xFE; c.Memory[0x11] = 0xB5; c.Memory[0x12] = 0x00; // Absolute X addresing c.Memory[0x13] = 0xA2; c.Memory[0x14] = 0xFF; c.Memory[0x10FF] = 0xFB; c.Memory[0x15] = 0xBD; c.Memory[0x16] = 0x00; c.Memory[0x17] = 0x10; // Absolute Y addressing c.Memory[0x18] = 0xA0; c.Memory[0x19] = 0xFF; c.Memory[0x11FF] = 0xFD; c.Memory[0x1A] = 0xB9; c.Memory[0x1B] = 0x00; c.Memory[0x1C] = 0x11; Console.WriteLine("Loading FF into A using Immediate Addressing"); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading 13 into A using absolute addressing"); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading 14 into A using Zero Page Addressing"); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading 06 into X using Immediate Addressing"); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading FF into A using Pre-Indexed Indirect Addressing"); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading 04 into Y using Immediate Addressing"); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading CF into A using Post-Indexed Indirect Addressing"); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading FE into A using Zero-Page Indexed Addressing"); c.Step(); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading FB into A using Absolute X Addressing"); c.Step(); c.Step(); Console.Write(c.ToString()); Console.WriteLine("Loading FD into A using Absolute Y Addressing"); c.Step(); c.Step(); Console.Write(c.ToString()); Console.ReadKey(); }
public override int Execute(C6502 cpu, byte operand) { cpu.Push(cpu.State.RegA); return(3); }
public override int Execute(C6502 cpu, byte operand) { cpu.State.ClearFlag((byte)StatusFlags.DecimalMode); return(2); }
public byte GetOperand(C6502 cpu, ushort parameter) { return(0); }
public override int Execute(C6502 cpu, byte operand) { cpu.State.SetFlag((byte)StatusFlags.InterruptDisable); return(2); }
public ushort GetAddress(C6502 cpu, ushort parameter) { // TODO: maybe NotSupportedException() ? return(cpu.State.RegA); }
public abstract int Execute(C6502 cpu, byte operand);
public override int Execute(C6502 cpu, byte operand) { cpu.State.SetFlag((byte)StatusFlags.Carry); return(2); }
public ushort GetAddress(C6502 cpu, ushort parameter) { return(parameter); }
public byte GetOperand(C6502 cpu, ushort parameter) { return(cpu.State.RegA); }
public byte GetOperand(C6502 cpu, ushort parameter) { return(cpu.Memory[GetAddress(cpu, parameter)]); }
public override int Execute(C6502 cpu, byte operand) { cpu.State.ProcessorStatus = cpu.Pop(); return(4); }