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> /// <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); }
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; }
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; }
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); } }
/// <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); }
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()); }
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; }
public static ushort GetWidth(AddressingModes addressingMode) { switch (addressingMode) { case AddressingModes.Implied: return(1); case AddressingModes.Immediate: return(2); default: return(3); } }
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); }
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}"); }
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; }
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()); }
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); } }
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()); }
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 ""; }
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()); } }
/// <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)); } } }
public InstructionSBC(CPU cpu, AddressingModes addressingMode) : base(cpu, OpCodes.SBC, addressingMode) { }
public HALT(Cpu cpu, AddressingModes addressingMode) : base(cpu, addressingMode) { }
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 }; }
public GenericInstruction(CPU cpu, OpCodes opCode, AddressingModes addrMode, bool haveArguments) : base(cpu, opCode, addrMode) { this.haveArguments = haveArguments; }
public NOP(Cpu cpu, AddressingModes addressingMode) : base(cpu, addressingMode) { }
public BLDX(Cpu cpu, AddressingModes addressingMode) : base(cpu, addressingMode) { }
public InstructionASL(CPU cpu, AddressingModes addressingMode) : base(cpu, OpCodes.ASL, addressingMode) { }
public static string GetOpcodeKey(string mnemonic, AddressingModes addressingMode) { return(mnemonic + "_" + Enum.GetName(typeof(AddressingModes), addressingMode)); }
public OpcodeAttribute(byte opcode, AddressingModes addresssingMode) { Opcode = opcode; AddressingMode = addresssingMode; }
public InstructionEOR(CPU cpu, AddressingModes addressingMode) : base(cpu, OpCodes.EOR, addressingMode) { }
public INCA(Cpu cpu, AddressingModes addressingMode) : base(cpu, addressingMode) { }
public InstructionORA(CPU cpu, AddressingModes addressingMode) : base(cpu, OpCodes.ORA, addressingMode) { }
/// <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())); }
public Operand() { _addressingMode = AddressingModes.Implied; _value = null; }
public InstructionJMP(CPU cpu, AddressingModes addressingMode) : base(cpu, OpCodes.JMP, addressingMode) { }
public Operation(Cpu cpu, AddressingModes addressingMode) { _cpu = cpu; _addressingMode = addressingMode; }