示例#1
0
        public BaseAddressingModeTests()
        {
            addressingMode = new T();

            cpuMemory    = new CPUMemory();
            cpuRegisters = new CPURegisters();
        }
示例#2
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var operationValue = memory.Stack.Span[++registers.SP];

            registers.PS = (byte)((registers.PS & 0x30) | (operationValue & 0xCF));

            return(opCodeDefinition.ExecutionCycles);
        }
示例#3
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var operationAddress = addressingMode.GetAddress(memory, registers, operand1, operand2, out bool pageBoundaryCrossed);

            registers.PC = operationAddress;

            return((byte)(opCodeDefinition.ExecutionCycles + (opCodeDefinition.AddExecutionCycleOnPageBoundaryCross && pageBoundaryCrossed ? 1 : 0)));
        }
示例#4
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var pcLow  = (byte)(memory.Stack.Span[++registers.SP] + 1);
            var pcHigh = memory.Stack.Span[++registers.SP];

            registers.PC = (ushort)(pcLow | pcHigh << 0x08);

            return(opCodeDefinition.ExecutionCycles);
        }
示例#5
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            registers.N_NegativeFlag = (byte)((registers.X & 0x80) >> 7);
            registers.Z_ZeroFlag     = (byte)(registers.X == 0 ? 1 : 0);

            registers.A = registers.X;

            return(opCodeDefinition.ExecutionCycles);
        }
示例#6
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var operationValue = addressingMode.GetValue(memory, registers, operand1, operand2, out bool pageBoundaryCrossed);

            registers.N_NegativeFlag = (byte)((operationValue & 0x80) >> 7);
            registers.Z_ZeroFlag     = (byte)(operationValue == 0 ? 1 : 0);

            registers.X = operationValue;

            return((byte)(opCodeDefinition.ExecutionCycles + (opCodeDefinition.AddExecutionCycleOnPageBoundaryCross && pageBoundaryCrossed ? 1 : 0)));
        }
示例#7
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var pageBoundaryCrossed = false;

            if (opCodeDefinition.AddExecutionCycleOnPageBoundaryCross)
            {
                addressingMode.GetAddress(memory, registers, operand1, operand2, out pageBoundaryCrossed);
            }

            return((byte)(opCodeDefinition.ExecutionCycles + (opCodeDefinition.AddExecutionCycleOnPageBoundaryCross && pageBoundaryCrossed ? 1 : 0)));
        }
示例#8
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var operationValue = memory.Stack.Span[++registers.SP];

            registers.N_NegativeFlag = (byte)((operationValue & 0x80) >> 7);
            registers.Z_ZeroFlag     = (byte)(operationValue == 0 ? 1 : 0);

            registers.A = operationValue;

            return(opCodeDefinition.ExecutionCycles);
        }
示例#9
0
        public string GetSyntax(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            if (opCodeDefinition.AddressingMode == AddressingMode.IMM)
            {
                return(string.Empty);
            }
            else
            {
                var operationValue = addressingMode.GetValue(memory, registers, operand1, operand2, out _);

                return($"= {operationValue:X02}");
            }
        }
示例#10
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var operationAddress = addressingMode.GetAddress(memory, registers, operand1, operand2, out _);
            var operationValue   = addressingMode.GetValue(memory, registers, operationAddress);

            var result = operationValue + 1;

            registers.N_NegativeFlag = (byte)((result & 0x80) >> 7);
            registers.Z_ZeroFlag     = (byte)((byte)result == 0 ? 1 : 0);

            addressingMode.SetValue(memory, registers, operationAddress, (byte)result);

            return(opCodeDefinition.ExecutionCycles);
        }
示例#11
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var operationAddress = addressingMode.GetAddress(memory, registers, operand1, operand2, out bool pageBoundaryCrossed);
            var operationValue   = addressingMode.GetValue(memory, registers, operationAddress);

            var result = operationValue << 1 | registers.C_CarryFlag;

            registers.N_NegativeFlag = (byte)((result & 0x80) >> 7);
            registers.C_CarryFlag    = (byte)((operationValue & 0x80) >> 7);
            registers.Z_ZeroFlag     = (byte)((byte)result == 0x00 ? 1 : 0);

            addressingMode.SetValue(memory, registers, operationAddress, (byte)result);

            return((byte)(opCodeDefinition.ExecutionCycles + (opCodeDefinition.AddExecutionCycleOnPageBoundaryCross && pageBoundaryCrossed ? 1 : 0)));
        }
示例#12
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var operationAddress = addressingMode.GetAddress(memory, registers, operand1, operand2, out bool pageBoundaryCrossed);

            var branchTaken = false;

            if (registers.N_NegativeFlag == 0)
            {
                registers.PC = operationAddress;

                branchTaken = true;
            }

            return((byte)(opCodeDefinition.ExecutionCycles + (opCodeDefinition.AddExecutionCycleOnPageBoundaryCross && pageBoundaryCrossed && branchTaken ? 1 : 0) + (branchTaken ? 1 : 0)));
        }
示例#13
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            var operationValue = addressingMode.GetValue(memory, registers, operand1, operand2, out bool pageBoundaryCrossed);

            var result = registers.A - operationValue - (1 - registers.C_CarryFlag);

            registers.N_NegativeFlag = (byte)((result & 0x80) >> 7);
            registers.Z_ZeroFlag     = (byte)((byte)result == 0 ? 1 : 0);
            registers.C_CarryFlag    = (byte)(result >= 0x00 ? 1 : 0);
            registers.V_OverflowFlag =
                (byte)((result < 0x80 && registers.A >= 0x80) ||
                       (result >= 0x80 && registers.A < 0x80) ? 1 : 0);

            registers.A = (byte)result;

            return((byte)(opCodeDefinition.ExecutionCycles + (opCodeDefinition.AddExecutionCycleOnPageBoundaryCross && pageBoundaryCrossed ? 1 : 0)));
        }
示例#14
0
        public BaseOperationTests()
        {
            operation = new T();

            absoluteAddressingMode    = new AbsoluteAddressingMode();
            absoluteXAddressingMode   = new AbsoluteXAddressingMode();
            absoluteYAddressingMode   = new AbsoluteYAddressingMode();
            accumulatorAddressingMode = new AccumulatorAddressingMode();
            immediateAddressingMode   = new ImmediateAddressingMode();
            impliedAddressingMode     = new ImpliedAddressingMode();
            indirectAddressingMode    = new IndirectAddressingMode();
            indirectXAddressingMode   = new IndirectXAddressingMode();
            indirectYAddressingMode   = new IndirectYAddressingMode();
            relativeAddressingMode    = new RelativeAddressingMode();
            zeroPageAddressingMode    = new ZeroPageAddressingMode();
            zeroPageXAddressingMode   = new ZeroPageXAddressingMode();
            zeroPageYAddressingMode   = new ZeroPageYAddressingMode();

            cpuMemory    = new CPUMemory();
            cpuRegisters = new CPURegisters();
        }
示例#15
0
 public string GetSyntax(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
 {
     return(string.Empty);
 }
示例#16
0
        private void InitializeOpCodeHandlers()
        {
            adcOperation = new ADCOperation();
            andOperation = new ANDOperation();
            aslOperation = new ASLOperation();
            bccOperation = new BCCOperation();
            bcsOperation = new BCSOperation();
            beqOperation = new BEQOperation();
            bitOperation = new BITOperation();
            bmiOperation = new BMIOperation();
            bneOperation = new BNEOperation();
            bplOperation = new BPLOperation();
            bvcOperation = new BVCOperation();
            bvsOperation = new BVSOperation();
            clcOperation = new CLCOperation();
            cldOperation = new CLDOperation();
            cliOperation = new CLIOperation();
            clvOperation = new CLVOperation();
            cmpOperation = new CMPOperation();
            cpxOperation = new CPXOperation();
            cpyOperation = new CPYOperation();
            decOperation = new DECOperation();
            dexOperation = new DEXOperation();
            deyOperation = new DEYOperation();
            eorOperation = new EOROperation();
            incOperation = new INCOperation();
            inxOperation = new INXOperation();
            inyOperation = new INYOperation();
            jmpOperation = new JMPOperation();
            jsrOperation = new JSROperation();
            laxOperation = new LAXOperation();
            ldaOperation = new LDAOperation();
            ldxOperation = new LDXOperation();
            ldyOperation = new LDYOperation();
            lsrOperation = new LSROperation();
            nopOperation = new NOPOperation();
            oraOperation = new ORAOperation();
            phaOperation = new PHAOperation();
            phpOperation = new PHPOperation();
            plaOperation = new PLAOperation();
            plpOperation = new PLPOperation();
            rolOperation = new ROLOperation();
            rorOperation = new ROROperation();
            rtiOperation = new RTIOperation();
            rtsOperation = new RTSOperation();
            sbcOperation = new SBCOperation();
            secOperation = new SECOperation();
            sedOperation = new SEDOperation();
            seiOperation = new SEIOperation();
            staOperation = new STAOperation();
            stxOperation = new STXOperation();
            styOperation = new STYOperation();
            taxOperation = new TAXOperation();
            tayOperation = new TAYOperation();
            tsxOperation = new TSXOperation();
            txaOperation = new TXAOperation();
            txsOperation = new TXSOperation();
            tyaOperation = new TYAOperation();

            noneAddressingMode        = new NoneAddressingMode();
            absoluteAddressingMode    = new AbsoluteAddressingMode();
            absoluteXAddressingMode   = new AbsoluteXAddressingMode();
            absoluteYAddressingMode   = new AbsoluteYAddressingMode();
            accumulatorAddressingMode = new AccumulatorAddressingMode();
            immediateAddressingMode   = new ImmediateAddressingMode();
            impliedAddressingMode     = new ImpliedAddressingMode();
            indirectAddressingMode    = new IndirectAddressingMode();
            indirectXAddressingMode   = new IndirectXAddressingMode();
            indirectYAddressingMode   = new IndirectYAddressingMode();
            relativeAddressingMode    = new RelativeAddressingMode();
            zeroPageAddressingMode    = new ZeroPageAddressingMode();
            zeroPageXAddressingMode   = new ZeroPageXAddressingMode();
            zeroPageYAddressingMode   = new ZeroPageYAddressingMode();

            OpCodeDefinitions.OpCodeList.ForEach(x =>
            {
                OpCodeHandlers.Add(x.OpCode, new OpCodeHandler
                {
                    OpCodeDefinition = x,
                    Operation        = x.Nemonic switch
                    {
                        OpCode.ADC => adcOperation,
                        OpCode.AND => andOperation,
                        OpCode.ASL => aslOperation,
                        OpCode.BCC => bccOperation,
                        OpCode.BCS => bcsOperation,
                        OpCode.BEQ => beqOperation,
                        OpCode.BIT => bitOperation,
                        OpCode.BMI => bmiOperation,
                        OpCode.BNE => bneOperation,
                        OpCode.BPL => bplOperation,
                        //OpCode.BRK => throw new NotImplementedException(),
                        OpCode.BVC => bvcOperation,
                        OpCode.BVS => bvsOperation,
                        OpCode.CLC => clcOperation,
                        OpCode.CLD => cldOperation,
                        OpCode.CLI => cliOperation,
                        OpCode.CLV => clvOperation,
                        OpCode.CMP => cmpOperation,
                        OpCode.CPX => cpxOperation,
                        OpCode.CPY => cpyOperation,
                        OpCode.DEC => decOperation,
                        OpCode.DEX => dexOperation,
                        OpCode.DEY => deyOperation,
                        OpCode.EOR => eorOperation,
                        OpCode.INC => incOperation,
                        OpCode.INX => inxOperation,
                        OpCode.INY => inyOperation,
                        OpCode.JMP => jmpOperation,
                        OpCode.JSR => jsrOperation,
                        OpCode.LDA => ldaOperation,
                        OpCode.LDX => ldxOperation,
                        OpCode.LDY => ldyOperation,
                        OpCode.LSR => lsrOperation,
                        OpCode.NOP => nopOperation,
                        OpCode.ORA => oraOperation,
                        OpCode.PHA => phaOperation,
                        OpCode.PHP => phpOperation,
                        OpCode.PLA => plaOperation,
                        OpCode.PLP => plpOperation,
                        OpCode.ROL => rolOperation,
                        OpCode.ROR => rorOperation,
                        OpCode.RTI => rtiOperation,
                        OpCode.RTS => rtsOperation,
                        OpCode.SBC => sbcOperation,
                        OpCode.SEC => secOperation,
                        OpCode.SED => sedOperation,
                        OpCode.SEI => seiOperation,
                        OpCode.STA => staOperation,
                        OpCode.STX => stxOperation,
                        OpCode.STY => styOperation,
                        OpCode.TAX => taxOperation,
                        OpCode.TAY => tayOperation,
                        OpCode.TSX => tsxOperation,
                        OpCode.TXA => txaOperation,
                        OpCode.TXS => txsOperation,
                        OpCode.TYA => tyaOperation,

                        OpCode.LAX => laxOperation,

                        _ => nopOperation,
                    },
                    AddressingMode = x.AddressingMode switch
                    {
                        AddressingMode.NON => noneAddressingMode,
                        AddressingMode.ZP0 => zeroPageAddressingMode,
                        AddressingMode.ZPX => zeroPageXAddressingMode,
                        AddressingMode.ZPY => zeroPageYAddressingMode,
                        AddressingMode.ABS => absoluteAddressingMode,
                        AddressingMode.ABX => absoluteXAddressingMode,
                        AddressingMode.ABY => absoluteYAddressingMode,
                        AddressingMode.IND => indirectAddressingMode,
                        AddressingMode.IDX => indirectXAddressingMode,
                        AddressingMode.IDY => indirectYAddressingMode,
                        AddressingMode.IMP => impliedAddressingMode,
                        AddressingMode.ACC => accumulatorAddressingMode,
                        AddressingMode.IMM => immediateAddressingMode,
                        AddressingMode.REL => relativeAddressingMode,
                        _ => throw new NotImplementedException(),
                    }
                });
示例#17
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            registers.C_CarryFlag = 0;

            return(opCodeDefinition.ExecutionCycles);
        }
示例#18
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            memory.Stack.Span[registers.SP--] = (byte)(registers.PS | (1 << 4) | (1 << 5));

            return(opCodeDefinition.ExecutionCycles);
        }
示例#19
0
        public byte Execute(OpCodeDefinition opCodeDefinition, IAddressingMode addressingMode, CPUMemory memory, CPURegisters registers, byte operand1, byte operand2)
        {
            registers.I_InterruptDisable = 1;

            return(opCodeDefinition.ExecutionCycles);
        }