예제 #1
0
        public Operand(Value value, AddressingModes addressingMode)
        {
            if (value == null)
            {
                if (_addressingMode != AddressingModes.Implied)
                {
                    throw new InvalidOperationException("invalid address mode for null value operand {" + Enum.GetName(typeof(AddressingModes), addressingMode) + "}");
                }
            }
            else
            {
                //Absolute = 4,
                //Indexed = 8,
                //Indirect = 16,
                //IndirectPreIndexed = 32,
                //IndirectPostIndexed = 64
                if (new[] { 4, 8, 16, 32, 64 }.ToList().Contains((int)addressingMode))
                {
                    if (value.Size != 2)
                    {
                        throw new InvalidOperationException("invalid address mode {" + Enum.GetName(typeof(AddressingModes), addressingMode) + "}");
                    }
                }
            }

            _addressingMode = addressingMode;
            _value          = value;
        }
예제 #2
0
 /// <summary>
 /// 发送信息
 /// </summary>
 /// <param name="mode"></param>
 /// <param name="msg"></param>
 /// <returns></returns>
 public bool CanTrans_TxMsg(AddressingModes mode, byte[] msg)
 {
     if (msg.Length == 0)
     {
         RrrorEvent("-->Error: Tx Msg Length Is Zero");
         return(false);
     }
     if (msg.Length > RX_MAX_TP_BYTES - 2)
     {
         RrrorEvent("-->Error: Tx Msg Length > RX_MAX_TP_BYTES");
         return(false);
     }
     if (tx_msg.Length != 0)
     {
         RrrorEvent("-->Error: Tx Msg ing");
         return(false);
     }
     if (mode == AddressingModes.Physical_Addressing)
     {
         id = tx_id;
     }
     else
     {
         id = 0x7DF;
     }
     tx_msg = msg;
     tx_msg = new byte[msg.Length];
     Array.Copy(msg, tx_msg, msg.Length);
     return(true);
 }
예제 #3
0
        public Operand(Value value)
        {
            if (value != null)
            {
                if (value.Size == 1)
                {
                    _addressingMode = AddressingModes.Immediate;
                }
                else if (value.Size == 2)
                {
                    if (value is Pointer)
                    {
                        _addressingMode = AddressingModes.Absolute;
                    }
                    else
                    {
                        _addressingMode = AddressingModes.BigImmediate;
                    }
                }
                else
                {
                    throw new NotSupportedException("operands of size {" + value.Size + "} not supported");
                }
            }
            else
            {
                _addressingMode = AddressingModes.Implied;
            }

            _value = value;
        }
예제 #4
0
      public Operand(Value value)
      {
         if (value!=null)
         {
            if (value.Size == 1)
            {
               _addressingMode = AddressingModes.Immediate;
            }
            else if (value.Size == 2)
            {
               if (value is Pointer)
               {
                  _addressingMode = AddressingModes.Absolute;
               }
               else
               {
                  _addressingMode = AddressingModes.BigImmediate;
               }
            }
            else
            {
               throw new NotSupportedException("operands of size {" + value.Size + "} not supported");
            }

         }
         else
         {
            _addressingMode = AddressingModes.Implied;
         }

         _value = value;
     }
예제 #5
0
        public int Process(ICpu cpu, byte instruction)
        {
            var ins = Instructions.Get(instruction);

            if (ins is null)
            {
                throw new UnknownInstructionException(instruction);
            }
            var(mode, insType, cycles) = ins.OpCodes[instruction];
            var addrMode = AddressingModes.Get(mode);

            var(address, pageCrossed) = addrMode.Addressing(cpu.CpuRegisters, cpu.Bus);
            var extraCycles     = ins.Invoke(cpu, instruction, address);
            var cyclesIncrement = insType switch
            {
                InstructionType.Common => extraCycles,
                InstructionType.CrossingPage => InstructionUtil.GetCrossingPageClockCycles(pageCrossed) + extraCycles,
                InstructionType.Branch => InstructionUtil.GetBranchClockCycle(Convert.ToBoolean(extraCycles),
                                                                              pageCrossed),
                _ => extraCycles
            };

            return(cycles + cyclesIncrement);
        }
    }
예제 #6
0
      public Operand(Value value, AddressingModes addressingMode)
      {
         if (value == null)
         {
            if (_addressingMode != AddressingModes.Implied)
            {
               throw new InvalidOperationException("invalid address mode for null value operand {" + Enum.GetName(typeof(AddressingModes), addressingMode) + "}");
            }
         }
         else
         {
            //Absolute = 4,
            //Indexed = 8,
            //Indirect = 16,
            //IndirectPreIndexed = 32,
            //IndirectPostIndexed = 64
            if (new[] { 4, 8, 16, 32, 64 }.ToList().Contains((int)addressingMode))
            {
               if (value.Size != 2)
               {
                  throw new InvalidOperationException("invalid address mode {" + Enum.GetName(typeof(AddressingModes), addressingMode) + "}");
               }
            }
         }

         _addressingMode = addressingMode;
         _value = value;

      }
        /// <summary>
        /// 发送信息
        /// </summary>
        /// <paramname="mode"></param>
        /// <paramname="msg"></param>
        /// <returns></returns>
        public bool CanTrans_TxMsg(AddressingModes mode, byte[] msg)
        {
            if (msg.Length == 0)
            {
                RrrorEvent("-->Error:Tx Msg Length Is Zero");
                return(false);
            }

            if (msg.Length > RX_MAX_TP_BYTES - 2)  //RX_MAX_TP_BYTES 0xFFFF
            {
                RrrorEvent("-->Error:Tx Msg Length > RX_MAX_TP_BYTES");
                return(false);
            }

            if (tx_msg.Length != 0)
            {
                RrrorEvent("-->Error:Tx Msg ing");
                return(false);
            }

            if (mode == AddressingModes.Physical_Addressing)
            {
                id = tx_id;  //physical address
            }
            else
            {
                id = test_id;  //functional address
            }

            tx_msg = msg;
            tx_msg = new byte[msg.Length];
            Array.Copy(msg, tx_msg, msg.Length);  //similar with function memcpy() in C language

            return(true);
        }
예제 #8
0
        public static int Encode(AddressingMode addressingMode, Opcode opcode)
        {
            // Find out what possible combination of addressing mode and opcode can exist.
            var valuesByMode = AddressingModes
                               .Where(kv => kv.Value == addressingMode)
                               .Select(kv => kv.Key);
            var valuesByOpcode = Opcodes
                                 .Where(kv => kv.Value == opcode)
                                 .Select(kv => kv.Key);
            var possibleOpcodes = valuesByMode
                                  .Intersect(valuesByOpcode)
                                  .ToArray();

            // If there are none, fail.
            if (!possibleOpcodes.Any())
            {
                throw new Exception($"No possible opcodes for {opcode} {addressingMode}.");
            }

            // Prefer to use official opcodes if possible.
            var possiblePreferredOpcodes = PreferredOpcodes
                                           .Intersect(possibleOpcodes)
                                           .ToArray();

            if (possiblePreferredOpcodes.Any())
            {
                return(possiblePreferredOpcodes.First());
            }

            // It's an undocumented opcode, most times it doesn't matter which is used.
            return(possibleOpcodes.First());
        }
예제 #9
0
 public MOS6502OpcodeAttribute(int code, string name, AddressingModes addressingMode, int timing, int length, string description = "", bool verify = true, bool unofficial = false)
     : base(code, name, description)
 {
     this.AddressingMode = addressingMode;
     this.Cycles         = timing;
     this.PCDelta        = length;
     this.ShouldVerify   = verify;
     this.Unofficial     = unofficial;
 }
예제 #10
0
파일: Operation.cs 프로젝트: joebarn/rebop
        public static ushort GetWidth(AddressingModes addressingMode)
        {
            switch (addressingMode)
            {
            case AddressingModes.Implied:
                return(1);

            case AddressingModes.Immediate:
                return(2);

            default:
                return(3);
            }
        }
예제 #11
0
        public static byte ReadData(this IInstruction ins, ushort address, ICpu cpu, byte instruction)
        {
            if (!ins.OpCodes.TryGetValue(instruction, out var value))
            {
                throw new UnknownInstructionException(instruction);
            }

            var addressingMode = AddressingModes.Get(value.mode);

            if (addressingMode.AddressingType == AddressingType.Address)
            {
                return(cpu.Bus.ReadByte(address));
            }

            return((byte)address);
        }
예제 #12
0
        public static string Encode(string mnemonic, AddressingModes addressingMode)
        {
            mnemonic = mnemonic.ToUpper();
            string addressingPart;

            if (addressingMode == AddressingModes.Immediate)
            {
                addressingPart = "imm";
            }
            else if (addressingMode == AddressingModes.BigImmediate)
            {
                addressingPart = "imm-b";
            }
            else if (addressingMode == AddressingModes.Absolute)
            {
                addressingPart = "abs";
            }
            else if (addressingMode == AddressingModes.BigAbsolute)
            {
                addressingPart = "abs-b";
            }
            else if (addressingMode == AddressingModes.AbsoluteIndexed)
            {
                addressingPart = "abs-x";
            }
            else if (addressingMode == AddressingModes.Indirect)
            {
                addressingPart = "ind";
            }
            else if (addressingMode == AddressingModes.IndirectPreIndexed)
            {
                addressingPart = "x-ind";
            }
            else if (addressingMode == AddressingModes.IndirectPostIndexed)
            {
                addressingPart = "ind-x";
            }
            else
            {
                addressingPart = "imp";
            }

            return($"{mnemonic}-{addressingPart}");
        }
예제 #13
0
        public Instruction GenericInst(OpCodes code, AddressingModes addrMode, Action<GenericInstruction, int, int> exec, ArgumentType param1type = ArgumentType.None, ArgumentType param2type = ArgumentType.None)
        {
            var inst = new GenericInstruction(cpu, code, addrMode, param1type != ArgumentType.None) { runFunction = exec };

            if (param1type != ArgumentType.None)
            {
                inst.decodeArgumentsFunction = delegate(GenericInstruction sender, Memory.MemoryBin bin, ref InstructionDecodeContext context, ref int offset, ref int param1, ref int param2)
                {
                    switch (param1type)
                    {
                        case ArgumentType.None:
                            break;
                        default:
                        case ArgumentType.I1:
                            param1 = inst.DecodeInt1Argument(bin, ref offset);
                            break;
                        case ArgumentType.I2:
                            param1 = inst.DecodeInt2Argument(bin, ref offset);
                            break;
                        case ArgumentType.I3:
                            param1 = inst.DecodeInt3Argument(bin, ref offset);
                            break;
                    }

                    switch (param2type)
                    {
                        case ArgumentType.None:
                            break;
                        default:
                        case ArgumentType.I1:
                            param2 = inst.DecodeInt1Argument(bin, ref offset);
                            break;
                        case ArgumentType.I2:
                            param2 = inst.DecodeInt2Argument(bin, ref offset);
                            break;
                        case ArgumentType.I3:
                            param2 = inst.DecodeInt3Argument(bin, ref offset);
                            break;
                    }
                };
            }

            return inst;
        }
예제 #14
0
        public string ConvertToBinary(string instruction)
        {
            StringBuilder binary = new StringBuilder("1101");
            //binary.Append(ConvertInstructionToBinary(instruction));

            bool isSourceDataReigster = false;

            //SOurce is a data register
            //append register
            string[] instructionParts = instruction.Split(' ');
            if (instructionParts[SOURCE][0] == 'd')
            {
                isSourceDataReigster = true;
            }

            StringBuilder effectiveAddressAsBinary = new StringBuilder();
            StringBuilder dataRegisterAsBinary     = new StringBuilder();

            if (isSourceDataReigster)
            {
                EffectiveAddress dataRegister = AddressingModes.GetAddressingMode(instructionParts[SOURCE]);
                dataRegisterAsBinary.Append(dataRegister.GetRegister());

                EffectiveAddress effectiveAddress = AddressingModes.GetAddressingMode(instructionParts[DESTINATION]);
                effectiveAddressAsBinary.Append(effectiveAddress.GetRegister());
                effectiveAddressAsBinary.Append(effectiveAddress.GetMode());
            }
            else
            {
            }

            //if(isSourceDataReigster)
            //{
            //    binary.Append(ConvertDestinationEA());
            //}
            //else
            //{
            //    binary.Append(ConvertImmediateOrSourceEA(instructionParts));
            //}

            return(binary.ToString());
        }
예제 #15
0
        public static void WriteData(this IInstruction ins, ushort address, byte data, ICpu cpu, byte instruction)
        {
            if (!ins.OpCodes.TryGetValue(instruction, out var value))
            {
                throw new UnknownInstructionException(instruction);
            }

            var addressingMode = AddressingModes.Get(value.mode);

            if (value.mode == AddressingMode.AccumulatorAddressingMode)
            {
                cpu.CpuRegisters.A = data;
                return;
            }

            if (addressingMode.AddressingType == AddressingType.Address)
            {
                cpu.Bus.WriteByte(address, data);
            }
        }
예제 #16
0
        public string ConvertImmediateOrSourceEA(string[] instructionParts)
        {
            StringBuilder binary = new StringBuilder();

            //If source is immediate
            if (instructionParts[2][0] == '#')
            {
                string immediateNumber = instructionParts[2].Substring(1);
                Int16  number          = Convert.ToInt16(immediateNumber);
                binary.Append(Convert.ToString(number, 2));
            }
            else
            {
                AddressingModes  addressingModes  = new AddressingModes();
                EffectiveAddress effectiveAddress = addressingModes.GetAddressingMode(instructionParts[2]);
            }



            return(binary.ToString());
        }
예제 #17
0
 public static string GetString(AddressingModes m)
 {
     switch (m)
     {
         case AddressingModes.at:
             return "@";
         case AddressingModes.close:
             return "}";
         case AddressingModes.dollar:
             return "$";
         case AddressingModes.higherThen:
             return ">";
         case AddressingModes.lowerThen:
             return "<";
         case AddressingModes.open:
             return "{";
         case AddressingModes.sharp:
             return "#";
         case AddressingModes.star:
             return "*";
     }
     return "";
 }
예제 #18
0
        public static Operand Parse(string text)
        {
            //v=LABEL | ($ff | 255 | %10101010) | ($ffff | 64000 | %1010101010101010

            //v
            //[v]
            //[[v]]
            //[v,X]
            //[[v,X]]
            //[[v],X]

            AddressingModes addressingMode = AddressingModes.Implied;

            string parsed = text;

            if (parsed != null)
            {
                bool isAddress     = false;
                bool isIndirect    = false;
                bool isIndexed     = false;
                bool isPreIndexed  = false;
                bool isPostIndexed = false;


                if (parsed[0] == '[')
                {
                    if (parsed[parsed.Length - 1] != ']')
                    {
                        throw new InvalidOperationException("can't parse {" + text + "}");
                    }

                    isAddress = true;
                    parsed    = parsed.Substring(1, parsed.Length - 2);

                    if (parsed[0] == '[')
                    {
                        isIndirect = true;

                        if (parsed.Substring(parsed.Length - 3, 3) == ",X]")
                        {
                            isPreIndexed = true;
                            parsed       = parsed.Substring(1, parsed.Length - 4);
                        }
                        else if (parsed.Substring(parsed.Length - 3, 3) == "],X")
                        {
                            isPostIndexed = true;
                            parsed        = parsed.Substring(1, parsed.Length - 4);
                        }
                        else if (parsed[parsed.Length - 1] == ']')
                        {
                            parsed = parsed.Substring(1, parsed.Length - 2);
                        }
                        else
                        {
                            throw new InvalidOperationException("can't parse {" + text + "}");
                        }
                    }

                    if (parsed.Substring(parsed.Length - 2, 2) == ",X")
                    {
                        isIndexed = true;
                        parsed    = parsed.Substring(0, parsed.Length - 2);
                    }
                }

                if (parsed.Length == 0)
                {
                    throw new InvalidOperationException("can't parse {" + text + "}");
                }

                //parse label or literal
                UInt   ui   = null;
                string name = null;

                if (char.IsLetter(parsed[0]) || parsed[0] == '_')
                {
                    if (!parsed.All(c => char.IsLetterOrDigit(c) || c == '_'))
                    {
                        throw new InvalidOperationException("can't parse {" + text + "}");
                    }
                    name = parsed;
                }
                else
                {
                    ui = UInt.Parse(parsed);

                    if (isAddress && ui is U8)
                    {
                        ui = new U16(((U8)ui).Read());
                    }
                }


                if (isAddress)
                {
                    //address literal or pointer (label)
                    if (isIndirect)
                    {
                        if (isPreIndexed)
                        {
                            addressingMode = AddressingModes.IndirectPreIndexed;
                        }
                        else if (isPostIndexed)
                        {
                            addressingMode = AddressingModes.IndirectPostIndexed;
                        }
                        else
                        {
                            addressingMode = AddressingModes.Indirect;
                        }
                    }
                    else
                    {
                        if (isIndexed)
                        {
                            addressingMode = AddressingModes.Indexed;
                        }
                        else
                        {
                            addressingMode = AddressingModes.Absolute;
                        }
                    }

                    Value value = null;

                    if (ui != null)
                    {
                        value = new Literal(ui);
                    }
                    else
                    {
                        value = new Pointer(name);
                    }

                    return(new Operand(value, addressingMode));
                }
                else
                {
                    //immediate literal or constant (label)
                    if (ui != null)
                    {
                        if (ui is U8)
                        {
                            addressingMode = AddressingModes.Immediate;
                        }
                        else if (ui is U16)
                        {
                            addressingMode = AddressingModes.BigImmediate;
                        }
                        else
                        {
                            throw new NotSupportedException("only U8 and U16 supported");
                        }

                        return(new Operand(new Literal(ui), addressingMode));
                    }
                    else
                    {
                        //how to tell if a constant label is 8 or 16?
                        //TODO: look up .EQU in symbol table
                        return(new Operand(new Constant(name, null), addressingMode));
                    }
                }
            }
            else
            {
                //implied
                return(new Operand());
            }
        }
예제 #19
0
        /// <summary>
        /// Ecrit une instruction. C'est un peut chiant car il faut spécifier à la fois l'instruction, l'addrMode, le type des args et les args mais bon,
        /// pour l'instant ça devrait faire l'affaire
        /// </summary>
        /// <param name="bin"></param>
        /// <param name="offset"></param>
        /// <param name="opCode"></param>
        /// <param name="addrMode"></param>
        /// <param name="param1Type"></param>
        /// <param name="param1"></param>
        /// <param name="param2"></param>
        public void Write(MemoryBin bin, ref int offset, OpCodes opCode, AddressingModes addrMode = AddressingModes.Direct, ArgumentType param1Type = ArgumentType.I1, int param1 = 0, int param2 = 0)
        {
            var originalOffset = offset;

            /* d'abord, on cherche l'instruction */
            Instruction match_instruction = null;

            var match_code = from instruction in cpu.DecodeTable.KnownInstructions where instruction.Code == opCode select instruction;
            switch(match_code.Count())
            {
                case 0: throw new InvalidOperationException(String.Format("Instruction not found : {0}", opCode));
                case 1: {
                    /* on se prend pas la tête sur le mode d'addr */
                    match_instruction = match_code.First();
                    break;
                }
                default:
                    {
                        /* on cherche le bon mode */
                        match_instruction = (from code_item in match_code where code_item.AddrMode == addrMode select code_item).FirstOrDefault();

                        if(match_instruction== null)
                            throw new InvalidOperationException(String.Format("Instruction {0} was found, but the addrMode {1} has no binding", opCode, addrMode));

                        break;
                    }
            }

            /* on écrit le code */
            bin.WriteInt1(offset, match_instruction.AssociatedHexCode);
            offset++;

            /* s'il y a des arguments, on les écrit */
            if (match_instruction.HaveArgs)
            {
                WriteParameter(bin, ref offset, param1Type, param1);

                if (addrMode == AddressingModes.BlockMove)
                {
                    /* c'est le seul mode qui a deux arguments, et il a la même
                     * taille que le premier argument
                     * */
                    WriteParameter(bin, ref offset, param1Type, param2);
                }
            }

            if (enableInstructionValidation)
            {
                /* on vérifie l'instruction écrite */
                var instructionDecode = new InstructionReference();
                var context = cpu.BuildCurrentContext();

                cpu.Platform.Decoder.DecodeOnce(bin, ref originalOffset, ref context, ref instructionDecode);

                if (instructionDecode.instruction.Code != opCode ||
                    instructionDecode.param1 != param1 ||
                    instructionDecode.param2 != param2)
                {
                    throw new InvalidProgramException(String.Format("Instruction decode mismatch.\r\nEncoded:{0}({1},{2}) [{3}]\r\nDecoded:{4}({5},{6}) [{7}]",
                        opCode,
                        param1, param2,
                        addrMode,

                        instructionDecode.instruction.Code,
                        instructionDecode.param1, instructionDecode.param2,
                        instructionDecode.instruction.AddrMode));
                }
                else if (originalOffset != offset)
                {
                    throw new InvalidProgramException(String.Format("Instruction decode mismatch, Invalid offset. Difference : {0}", offset - originalOffset));
                }
            }
        }
예제 #20
0
 public InstructionSBC(CPU cpu, AddressingModes addressingMode)
     : base(cpu, OpCodes.SBC, addressingMode)
 {
 }
예제 #21
0
 public HALT(Cpu cpu, AddressingModes addressingMode) : base(cpu, addressingMode)
 {
 }
예제 #22
0
 public Instruction GenericInstCustom(OpCodes code, AddressingModes addrMode, Action<GenericInstruction, int, int> exec, GenericInstruction.DecodeArgumentsFunctionDelegate decodeDelegate = null)
 {
     return new GenericInstruction(cpu, code, addrMode, decodeDelegate != null) { runFunction = exec, decodeArgumentsFunction = decodeDelegate };
 }
예제 #23
0
 public GenericInstruction(CPU cpu, OpCodes opCode, AddressingModes addrMode, bool haveArguments)
     : base(cpu, opCode, addrMode)
 {
     this.haveArguments = haveArguments;
 }
예제 #24
0
파일: NOP.cs 프로젝트: joebarn/rebop
 public NOP(Cpu cpu, AddressingModes addressingMode) : base(cpu, addressingMode)
 {
 }
예제 #25
0
 public BLDX(Cpu cpu, AddressingModes addressingMode) : base(cpu, addressingMode)
 {
 }
예제 #26
0
 public InstructionASL(CPU cpu, AddressingModes addressingMode)
     : base(cpu, OpCodes.ASL, addressingMode)
 {
 }
예제 #27
0
 public static string GetOpcodeKey(string mnemonic, AddressingModes addressingMode)
 {
     return(mnemonic + "_" + Enum.GetName(typeof(AddressingModes), addressingMode));
 }
예제 #28
0
 public OpcodeAttribute(byte opcode, AddressingModes addresssingMode)
 {
    Opcode = opcode;
    AddressingMode = addresssingMode;
 }
예제 #29
0
 public InstructionEOR(CPU cpu, AddressingModes addressingMode)
     : base(cpu, OpCodes.EOR, addressingMode)
 {
 }
예제 #30
0
파일: INCA.cs 프로젝트: joebarn/rebop
 public INCA(Cpu cpu, AddressingModes addressingMode) : base(cpu, addressingMode)
 {
 }
예제 #31
0
 public InstructionORA(CPU cpu, AddressingModes addressingMode)
     : base(cpu, OpCodes.ORA, addressingMode)
 {
 }
예제 #32
0
 /// <summary>
 /// 发送信息
 /// </summary>
 /// <param name="mode"></param>
 /// <param name="strings"></param>
 /// <returns></returns>
 public bool CanTrans_TxMsg(AddressingModes mode, string strings)
 {
     return(CanTrans_TxMsg(mode, strings.StringToHex()));
 }
예제 #33
0
 public Operand()
 {
     _addressingMode = AddressingModes.Implied;
     _value          = null;
 }
예제 #34
0
 public OpcodeAttribute(byte opcode, AddressingModes addresssingMode)
 {
     Opcode         = opcode;
     AddressingMode = addresssingMode;
 }
예제 #35
0
 public InstructionJMP(CPU cpu, AddressingModes addressingMode)
     : base(cpu, OpCodes.JMP, addressingMode)
 {
 }
예제 #36
0
파일: Operation.cs 프로젝트: joebarn/rebop
 public Operation(Cpu cpu, AddressingModes addressingMode)
 {
     _cpu            = cpu;
     _addressingMode = addressingMode;
 }
예제 #37
0
  public Operand()
  {
     _addressingMode = AddressingModes.Implied;
     _value = null;
 }