/// <summary>
        /// test BITs
        /// </summary>
        private static void Bit(Cpu cpu, InstructionData data)
        {
            var value = cpu.ReadByte(data.ArgumentAddress);

            cpu.SetFlag(CpuFlags.Overflow, ((value >> 6) & 1) != 0);
            cpu.SetZero((byte)(value & cpu.accumulator));
            cpu.SetNegative(value);
        }
        /// <summary>
        /// Load Accumulator and X register
        /// </summary>
        private static void Lax(Cpu cpu, InstructionData data)
        {
            var value = cpu.ReadByte(data.ArgumentAddress);

            cpu.accumulator = value;
            cpu.x           = value;
            cpu.SetZeroNegative(value);
        }
        /// <summary>
        /// ADd with Carry
        /// </summary>
        private static void Adc(Cpu cpu, InstructionData data)
        {
            var a      = cpu.accumulator;
            var b      = cpu.ReadByte(data.ArgumentAddress);
            var c      = cpu.GetFlag(CpuFlags.Carry) ? 1 : 0;
            var result = a + b + c;

            cpu.accumulator = (byte)result;
            cpu.SetZeroNegative(cpu.accumulator);
            cpu.SetFlag(CpuFlags.Carry, result > 0xff);
            cpu.SetFlag(CpuFlags.Overflow, (((a ^ b) & 0x80) == 0) && (((a ^ cpu.accumulator) & 0x80) != 0));
        }
 /// <summary>
 /// ROtate Right
 /// </summary>
 private static void Ror(Cpu cpu, InstructionData data)
 {
     if (data.AddressingMode == AddressingMode.Accumulator)
     {
         cpu.RotateRight(ref cpu.accumulator);
     }
     else
     {
         var value = cpu.ReadByte(data.ArgumentAddress);
         cpu.RotateRight(ref value);
         cpu.WriteByte(data.ArgumentAddress, value);
     }
 }
        /// <summary>
        /// SuBtract with Carry
        /// </summary>
        private static void Sbc(Cpu cpu, InstructionData data)
        {
            var a      = cpu.accumulator;
            var b      = cpu.ReadByte(data.ArgumentAddress);
            var result = a - b;

            if (!cpu.GetFlag(CpuFlags.Carry))
            {
                result -= 1;
            }
            cpu.accumulator = (byte)result;
            cpu.SetZeroNegative(cpu.accumulator);
            cpu.SetFlag(CpuFlags.Carry, result >= 0);
            cpu.SetFlag(CpuFlags.Overflow, (((a ^ b) & 0x80) != 0) && (((a ^ cpu.accumulator) & 0x80) != 0));
        }
示例#6
0
        public bool Advance()
        {
            if (waitCycles > 0)
            {
                waitCycles--;
                return(false);
            }
            var log = new StringBuilder();

            log.Append($"0x{programCounter:X4}");
            var opCode          = ReadByte(programCounter);
            var instruction     = Instructions[opCode];
            var adressingMode   = InstructionAdressingModes[opCode];
            var instructionData = new InstructionData
            {
                ArgumentAddress = GetInstructionArgumentAddress(adressingMode),
                ProgramCounter  = programCounter,
                AddressingMode  = adressingMode
            };
            var instructionSize = GetInstructionSize(adressingMode);

            for (int i = 0; i < 3; i++)
            {
                if (i <= instructionSize)
                {
                    log.Append($" {ReadByte((ushort) (programCounter + i)):X2}");
                }
                else
                {
                    log.Append("   ");
                }
            }
            programCounter += instructionSize;
            waitCycles      = InstructionCycles[opCode];
            if (IsPageCrossed(adressingMode, instructionData.ArgumentAddress))
            {
                waitCycles += InstructionPageCrossCycles[opCode];
            }
            log.Append($" {opCode:X2} {instruction.Method.Name.ToUpper()} {adressingMode} 0x{instructionData.ArgumentAddress:X4}");
            instruction(this, instructionData);
            System.Console.Out.WriteLine(log.ToString());
            return(true);
        }
 /// <summary>
 /// Jump to SubRoutine
 /// </summary>
 private static void Jsr(Cpu cpu, InstructionData data)
 {
     cpu.PushShort((ushort)(cpu.programCounter - 1));
     cpu.programCounter = data.ArgumentAddress;
 }
 /// <summary>
 /// PuLl Processor status
 /// </summary>
 private static void Plp(Cpu cpu, InstructionData data)
 {
     cpu.flags = (CpuFlags)(cpu.PullByte() & 0xEF | 0x20);
 }
 /// <summary>
 /// STore Y register
 /// </summary>
 private static void Sty(Cpu cpu, InstructionData data)
 {
     cpu.Store(data.ArgumentAddress, cpu.y);
 }
 /// <summary>
 /// Rotate Right, then Add memory to accumulator with carry
 /// </summary>
 private static void Rra(Cpu cpu, InstructionData data)
 {
     Ror(cpu, data);
     Adc(cpu, data);
 }
 /// <summary>
 /// Transfer Y to A
 /// </summary>
 private static void Tya(Cpu cpu, InstructionData data)
 {
     cpu.Transfer(cpu.y, out cpu.accumulator);
 }
 /// <summary>
 /// Increment memory and Subtract with Carry
 /// </summary>
 private static void Isb(Cpu cpu, InstructionData data)
 {
     Inc(cpu, data);
     Sbc(cpu, data);
 }
 /// <summary>
 /// Rotate Left then And accumulator with memory
 /// </summary>
 private static void Rla(Cpu cpu, InstructionData data)
 {
     Rol(cpu, data);
     And(cpu, data);
 }
 /// <summary>
 /// STore Accumulator
 /// </summary>
 private static void Sta(Cpu cpu, InstructionData data)
 {
     cpu.Store(data.ArgumentAddress, cpu.accumulator);
 }
 /// <summary>
 /// Transfer X to Stack ptr
 /// </summary>
 private static void Txs(Cpu cpu, InstructionData data)
 {
     cpu.stackPointer = cpu.x;
 }
 /// <summary>
 /// ReTurn from Subroutine
 /// </summary>
 private static void Rts(Cpu cpu, InstructionData data)
 {
     cpu.programCounter = (ushort)(cpu.PullShort() + 1);
 }
 /// <summary>
 /// LoaD Y register
 /// </summary>
 private static void Ldy(Cpu cpu, InstructionData data)
 {
     cpu.Load(out cpu.y, data.ArgumentAddress);
 }
 /// <summary>
 /// No OPeration
 /// </summary>
 private static void Nop(Cpu cpu, InstructionData data)
 {
 }
 /// <summary>
 /// INcrement Y
 /// </summary>
 private static void Iny(Cpu cpu, InstructionData data)
 {
     cpu.Increment(ref cpu.y);
 }
 /// <summary>
 /// DEcrement Y
 /// </summary>
 private static void Dey(Cpu cpu, InstructionData data)
 {
     cpu.Decrement(ref cpu.y);
 }
 /// <summary>
 /// Store Accumulator and X register
 /// </summary>
 private static void Sax(Cpu cpu, InstructionData data)
 {
     cpu.Store(data.ArgumentAddress, (byte)(cpu.accumulator & cpu.x));
 }
 /// <summary>
 /// LoaD Accumulator
 /// </summary>
 private static void Lda(Cpu cpu, InstructionData data)
 {
     cpu.Load(out cpu.accumulator, data.ArgumentAddress);
 }
 /// <summary>
 /// Decrease memory and ComPare with accumulator
 /// </summary>
 private static void Dcp(Cpu cpu, InstructionData data)
 {
     Dec(cpu, data);
     Cmp(cpu, data);
 }
 /// <summary>
 /// PusH Accumulator
 /// </summary>
 private static void Pha(Cpu cpu, InstructionData data)
 {
     cpu.PushByte(cpu.accumulator);
 }
 /// <summary>
 /// arithmetic Shift Left then Or accumulator with memory
 /// </summary>
 private static void Slo(Cpu cpu, InstructionData data)
 {
     Asl(cpu, data);
     Ora(cpu, data);
 }
 /// <summary>
 /// PuLl Accumulator
 /// </summary>
 private static void Pla(Cpu cpu, InstructionData data)
 {
     cpu.accumulator = cpu.PullByte();
     cpu.SetZeroNegative(cpu.accumulator);
 }
 /// <summary>
 /// logical Shift Right then Eor accumulator with memory
 /// </summary>
 private static void Sre(Cpu cpu, InstructionData data)
 {
     Lsr(cpu, data);
     Eor(cpu, data);
 }
 /// <summary>
 /// PusH Processor status
 /// </summary>
 private static void Php(Cpu cpu, InstructionData data)
 {
     cpu.PushByte((byte)((byte)cpu.flags | 0x10));
 }
 /// <summary>
 /// Transfer Stack ptr to X
 /// </summary>
 private static void Tsx(Cpu cpu, InstructionData data)
 {
     cpu.x = cpu.stackPointer;
     cpu.SetZeroNegative(cpu.x);
 }
 /// <summary>
 /// bitwise OR with Accumulator
 /// </summary>
 private static void Ora(Cpu cpu, InstructionData data)
 {
     cpu.accumulator = (byte)(cpu.accumulator | cpu.ReadByte(data.ArgumentAddress));
     cpu.SetZeroNegative(cpu.accumulator);
 }