public InstructionInfo[] BuildInstructionInfo(Type type) { var instructions = new List<InstructionInfo>(); foreach (var property in type.GetProperties()) { foreach (var att in property.GetCustomAttributes(typeof(InstructionAttribute), false).Cast<InstructionAttribute>()) { Object instructionObject = BuildInstructionObject(type); var info = new InstructionInfo() { Mnemonic = att.Mnemonic, Opcode = att.Opcode }; if (att.Cycles == 0) info.Cycles = null; else info.Cycles = att.Cycles; info.Body = (Expression)property.GetValue(instructionObject, null); if (info.Body == null) throw new NullExpressionException(String.Format("The instruction {0} on {1} was null.", property.Name, type)); info.ParameterMode = att.ParameterMode; info.InstructionObject = instructionObject; info.Prefix = att.Prefix; instructions.Add(info); } } return instructions.ToArray(); }
public Expression BuildExpression(InstructionInfo info) { if (info.Body == null) throw new NullExpressionException(); var expressions = new List<Expression>(); switch (info.ParameterMode) { case InstructionParameterMode.None: break; case InstructionParameterMode.Byte: expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte1, _programControlExpressionLibrary.ReadAndIncrementProgramCounter)); break; case InstructionParameterMode.Index: // index - (index & 0x80) << 1 - Handles negative indexes. expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte2, _programControlExpressionLibrary.ReadAndIncrementProgramCounter)); expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte1, Expression.Subtract( _programControlExpressionLibrary.ParameterByte2, Expression.LeftShift( Expression.And(_programControlExpressionLibrary.ParameterByte2, Expression.Constant(0x80)), Expression.Constant(0x01) ) ) ) ); break; case InstructionParameterMode.IndexAndByte: // index - (index & 0x80) << 1 - Handles negative indexes. expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte2, _programControlExpressionLibrary.ReadAndIncrementProgramCounter)); expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte1, Expression.Subtract( _programControlExpressionLibrary.ParameterByte2, Expression.LeftShift( Expression.And(_programControlExpressionLibrary.ParameterByte2, Expression.Constant(0x80)), Expression.Constant(0x01) ) ) ) ); expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte2, _programControlExpressionLibrary.ReadAndIncrementProgramCounter)); break; case InstructionParameterMode.Word: case InstructionParameterMode.Address: expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte2, _programControlExpressionLibrary.ReadAndIncrementProgramCounter)); expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte1, _programControlExpressionLibrary.ReadAndIncrementProgramCounter)); break; default: break; } foreach (var advice in _preInstructionAdvice) { var a = advice.GetExpression(info, _expressionLibrary); if (a != null) expressions.Add(a); } expressions.Add(info.Body); foreach (var advice in _postInstructionAdvice) { var a = advice.GetExpression(info, _expressionLibrary); if (a != null) expressions.Add(a); } if (_postInstructionAdvice.Count > 0) { expressions.Add(Expression.Assign(_programControlExpressionLibrary.CycleCounter, _programControlExpressionLibrary.CycleCounter)); } if (info.Cycles.HasValue) { expressions.Add( Expression.SubtractAssign( _programControlExpressionLibrary.CycleCounter, Expression.Constant(info.Cycles) ) ); } return Expression.Block(expressions.ToArray()); }