Example #1
0
 private static ushort GetOperandRawValue(SimulationContext context, Operand operand)
 {
     if (operand is Operand <Register8> )
     {
         return(context.GetRegister8(((Operand <Register8>)operand).Value));
     }
     else if (operand is Operand <Register16> )
     {
         return(context.GetRegister16(((Operand <Register16>)operand).Value));
     }
     else if (operand is Operand <byte> )
     {
         return(((Operand <byte>)operand).Value);
     }
     else if (operand is Operand <ushort> )
     {
         return(((Operand <ushort>)operand).Value);
     }
     else if (operand is Operand <sbyte> )
     {
         if (operand.IsDirect)
         {
             return((ushort)(context.SP + ((Operand <sbyte>)operand).Value));
         }
         else
         {
             return((ushort)(short)((Operand <sbyte>)operand).Value);
         }
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
Example #2
0
		public SimulationContext(SimulationContext source)
		{
			a = source.a;
			b = source.b;
			c = source.c;
			d = source.d;
			e = source.e;
			f = source.f;
			h = source.h;
			l = source.l;
			sp = source.sp;
			pc = source.pc;
			romBank = source.romBank;
		}
Example #3
0
 public SimulationContext(SimulationContext source)
 {
     a       = source.a;
     b       = source.b;
     c       = source.c;
     d       = source.d;
     e       = source.e;
     f       = source.f;
     h       = source.h;
     l       = source.l;
     sp      = source.sp;
     pc      = source.pc;
     romBank = source.romBank;
 }
Example #4
0
		private static ushort GetOperandRawValue(SimulationContext context, Operand operand)
		{
			if (operand is Operand<Register8>)
				return context.GetRegister8(((Operand<Register8>)operand).Value);
			else if (operand is Operand<Register16>)
				return context.GetRegister16(((Operand<Register16>)operand).Value);
			else if (operand is Operand<byte>)
				return ((Operand<byte>)operand).Value;
			else if (operand is Operand<ushort>)
				return ((Operand<ushort>)operand).Value;
			else if (operand is Operand<sbyte>)
			{
				if (operand.IsDirect)
					return (ushort)(context.SP + ((Operand<sbyte>)operand).Value);
				else
					return (ushort)(short)((Operand<sbyte>)operand).Value;
			}
			else
				throw new InvalidOperationException();
		}
Example #5
0
		/// <summary>
		/// Runs a dynamic analyzis.
		/// This is currently implemented as a dumb simulation process
		/// Every memory operations are ignored except for ROM and HRAM
		/// Reads on ROM will work as expected
		/// Memory bank switching will work as expected, and unresolved ROM calls will be resolved when possible
		/// Memory copies between ROM and HRAM will be tracked, and thus HRAM calls will be remapped to ROM calls
		/// </summary>
		/// <remarks>The analyzis ends once all jumps are resolved</remarks>
		/// <param name="functionPointerStack">Stack containing the entry points to analyze</param>
		private void DynamicAnalyze(Stack<Label> entryPointStack)
		{
			Stack<SimulationContext> contextStack = new Stack<SimulationContext>();

			while (entryPointStack.Count > 0)
			{
				SimulationContext currentContext = new SimulationContext();
				Label entryPointLabel = entryPointStack.Pop();
				int instructionIndex = -1;

				currentContext.PC = entryPointLabel.Offset;

				contextStack.Push(currentContext);

				while (contextStack.Count > 0)
				{
					Instruction instruction;
					Operand operand1, operand2;
					ushort rawValue1, rawValue2;
					ushort value1, value2;
					bool byteOperation;

					currentContext = contextStack.Peek();
					if (instructionIndex < 0)
						instructionIndex = instructionList.FindIndex(i => i.Offset == currentContext.PC);

					instruction = instructionList[instructionIndex];
					currentContext.PC = instruction.Offset;

					if (instruction is FlowControlInstruction)
					{
						Condition condition = ((FlowControlInstruction)instruction).Condition;

						// Skips conditional instructions when the condition is false
						if (condition == Condition.Never
							|| condition == Condition.NotZero && currentContext.ZeroFlag
							|| condition == Condition.Zero && !currentContext.ZeroFlag
							|| condition == Condition.CarryClear && currentContext.CarryFlag
							|| condition == Condition.CarrySet && !currentContext.CarryFlag)
							goto NextInstruction;
					}
					else if (instruction is BinaryInstruction)
					{
						operand1 = ((BinaryInstruction)instruction).Destination;
						operand2 = ((BinaryInstruction)instruction).Source;
						rawValue1 = GetOperandRawValue(currentContext, operand1);
						rawValue2 = GetOperandRawValue(currentContext, operand1);
						byteOperation = Operand.IsByteOperand(operand1) && Operand.IsByteOperand(operand2);
					}
					else if (instruction is UnaryInstruction)
					{
						operand1 = ((BinaryInstruction)instruction).Destination;
						byteOperation = Operand.IsByteOperand(operand1);
					}

					if (instruction is LoadInstruction)
					{
					}
					else if (instruction is JumpInstruction)
					{
					}
					else if (instruction is ReturnInstruction)
					{
						if (((ReturnInstruction)instruction).Condition == Condition.Always)
							contextStack.Pop();
					}
				NextInstruction:
					if (instructionIndex > 0)
					{
						instructionIndex++;
						if (instructionIndex >= instructionList.Count)
							throw new InvalidOperationException();
					}
				}
			}
		}
Example #6
0
        /// <summary>
        /// Runs a dynamic analyzis.
        /// This is currently implemented as a dumb simulation process
        /// Every memory operations are ignored except for ROM and HRAM
        /// Reads on ROM will work as expected
        /// Memory bank switching will work as expected, and unresolved ROM calls will be resolved when possible
        /// Memory copies between ROM and HRAM will be tracked, and thus HRAM calls will be remapped to ROM calls
        /// </summary>
        /// <remarks>The analyzis ends once all jumps are resolved</remarks>
        /// <param name="functionPointerStack">Stack containing the entry points to analyze</param>
        private void DynamicAnalyze(Stack <Label> entryPointStack)
        {
            Stack <SimulationContext> contextStack = new Stack <SimulationContext>();

            while (entryPointStack.Count > 0)
            {
                SimulationContext currentContext  = new SimulationContext();
                Label             entryPointLabel = entryPointStack.Pop();
                int instructionIndex = -1;

                currentContext.PC = entryPointLabel.Offset;

                contextStack.Push(currentContext);

                while (contextStack.Count > 0)
                {
                    Instruction instruction;
                    Operand     operand1, operand2;
                    ushort      rawValue1, rawValue2;
                    ushort      value1, value2;
                    bool        byteOperation;

                    currentContext = contextStack.Peek();
                    if (instructionIndex < 0)
                    {
                        instructionIndex = instructionList.FindIndex(i => i.Offset == currentContext.PC);
                    }

                    instruction       = instructionList[instructionIndex];
                    currentContext.PC = instruction.Offset;

                    if (instruction is FlowControlInstruction)
                    {
                        Condition condition = ((FlowControlInstruction)instruction).Condition;

                        // Skips conditional instructions when the condition is false
                        if (condition == Condition.Never ||
                            condition == Condition.NotZero && currentContext.ZeroFlag ||
                            condition == Condition.Zero && !currentContext.ZeroFlag ||
                            condition == Condition.CarryClear && currentContext.CarryFlag ||
                            condition == Condition.CarrySet && !currentContext.CarryFlag)
                        {
                            goto NextInstruction;
                        }
                    }
                    else if (instruction is BinaryInstruction)
                    {
                        operand1      = ((BinaryInstruction)instruction).Destination;
                        operand2      = ((BinaryInstruction)instruction).Source;
                        rawValue1     = GetOperandRawValue(currentContext, operand1);
                        rawValue2     = GetOperandRawValue(currentContext, operand1);
                        byteOperation = Operand.IsByteOperand(operand1) && Operand.IsByteOperand(operand2);
                    }
                    else if (instruction is UnaryInstruction)
                    {
                        operand1      = ((BinaryInstruction)instruction).Destination;
                        byteOperation = Operand.IsByteOperand(operand1);
                    }

                    if (instruction is LoadInstruction)
                    {
                    }
                    else if (instruction is JumpInstruction)
                    {
                    }
                    else if (instruction is ReturnInstruction)
                    {
                        if (((ReturnInstruction)instruction).Condition == Condition.Always)
                        {
                            contextStack.Pop();
                        }
                    }
NextInstruction:
                    if (instructionIndex > 0)
                    {
                        instructionIndex++;
                        if (instructionIndex >= instructionList.Count)
                        {
                            throw new InvalidOperationException();
                        }
                    }
                }
            }
        }