/// <summary>
        /// Instruction Decoder for Disassembly
        /// </summary>
        private static Operation InstructionDecode(uint MemoryLocation)
        {
            ushort memoryOpCode = Functions.BytesToWord(Memory.Data[MemoryLocation], Memory.Data[MemoryLocation + 1]);
            // a new operation does not interfere with the executing
            Operation instruction = null;

            if (InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)] != null)
            {
                instruction = new Operation()
                {
                    AddressingModeDestination = InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)].AddressingModeDestination,
                    AddressingModeSource      = InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)].AddressingModeSource,
                    Context     = InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)].Context,
                    Length      = InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)].Length,
                    Mnemonic    = InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)].Mnemonic,
                    OpCode      = InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)].OpCode,
                    OpCodeValue = memoryOpCode,
                    Type        = InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)].Type,
                    Width       = InstructionSet.OperationsList[(ushort)(memoryOpCode & 0x0fe03)].Width,
                };
            }

            if (MemoryLocation < 0x020 || instruction == null)
            {
                return(new Operation()
                {
                    OpCode = memoryOpCode,
                    OpCodeValue = memoryOpCode,
                    Type = OperationType.Undefined,
                    Width = OperationWidth.Word,
                    Mnemonic = "DW",
                    Cycles = 0,
                    Length = 2,
                    Operands = new List <Operand>()
                    {
                        new Operand()
                        {
                            AddressingMode = AddressingMode.Immediate,
                            Notation = OperandNotation.Destination,
                            Symbol = string.Format("${0}", Convert.ToString(memoryOpCode, 16).ToUpper().PadLeft(4, '0')),
                            Value = memoryOpCode
                        }
                    }
                });
            }
            //else if (instruction == null)
            //    throw new Exception("oh no no no no...");

            ushort opcode = (ushort)(instruction.OpCodeValue & 0x0fe00);

            if (instruction.Type == OperationType.Implicit)
            {
                // specific with bwb, correct mnemonic else passed as is
                if ((instruction.OpCodeValue & 0x020) > 0)
                {
                    switch (opcode)
                    {
                    case 0x08600:
                        instruction.Mnemonic = "CLI";
                        break;
                    }
                }
                return(instruction);
            }
            else
            {
                // specific with bwb, correct mnemonic
                if ((instruction.OpCodeValue & 0x020) > 0)
                {
                    switch (opcode)
                    {
                    case 0x04e00:
                        instruction.Mnemonic = "JZ";
                        break;

                    case 0x05200:
                        instruction.Mnemonic = "JO";
                        break;

                    case 0x05600:
                        instruction.Mnemonic = "JC";
                        break;

                    case 0x05a00:
                        instruction.Mnemonic = "JN";
                        break;

                    case 0x0f200:
                        instruction.Mnemonic = "JRZ";
                        break;

                    case 0x04c00:
                        instruction.Mnemonic = "SRSET";
                        break;
                    }
                }

                // operands with addressing modes
                // destination addressing
                switch (instruction.AddressingModeDestination)
                {
                case AddressingMode.MemoryReference:
                case AddressingMode.Immediate:
                    instruction.Operands.Add(DispatchOperand(Functions.BytesToWord(Memory.Data[MemoryLocation + 2], Memory.Data[MemoryLocation + 3]), instruction.AddressingModeDestination, OperandNotation.Destination, (ushort)(instruction.Context == OperationContext.Relative ? MemoryLocation + instruction.Length : 0)));
                    break;

                case AddressingMode.RegisterDirect:
                case AddressingMode.RegisterReference:
                    instruction.Operands.Add(DispatchOperand(memoryOpCode, instruction.AddressingModeDestination, OperandNotation.Destination, (ushort)(instruction.Context == OperationContext.Relative ? MemoryLocation + instruction.Length : 0)));
                    break;

                case AddressingMode.StackPointer:
                    instruction.Operands.Add(new Operand()
                    {
                        AddressingMode = AddressingMode.StackPointer,
                        Notation       = OperandNotation.Destination,
                        Symbol         = "SP",
                        Value          = 0,
                    });
                    break;

                case AddressingMode.ProgramCounter:
                    instruction.Operands.Add(new Operand()
                    {
                        AddressingMode = AddressingMode.ProgramCounter,
                        Notation       = OperandNotation.Destination,
                        Symbol         = "PC",
                        Value          = 0,
                    });
                    break;

                case AddressingMode.StatusRegister:
                    instruction.Operands.Add(new Operand()
                    {
                        AddressingMode = AddressingMode.StatusRegister,
                        Notation       = OperandNotation.Destination,
                        Symbol         = "SR",
                        Value          = 0,
                    });
                    break;
                }

                // source addressing
                switch (instruction.AddressingModeSource)
                {
                case AddressingMode.Immediate:
                case AddressingMode.MemoryReference:
                    if (instruction.AddressingModeDestination == AddressingMode.MemoryReference || instruction.AddressingModeDestination == AddressingMode.Immediate)
                    {
                        instruction.Operands.Add(DispatchOperand(Functions.BytesToWord(Memory.Data[MemoryLocation + 4], Memory.Data[MemoryLocation + 5]), instruction.AddressingModeSource, OperandNotation.Source, (ushort)(instruction.Context == OperationContext.Relative ? MemoryLocation + instruction.Length : 0)));
                    }
                    else
                    {
                        // register reference
                        instruction.Operands.Add(DispatchOperand(Functions.BytesToWord(Memory.Data[MemoryLocation + 2], Memory.Data[MemoryLocation + 3]), instruction.AddressingModeSource, OperandNotation.Source, (ushort)(instruction.Context == OperationContext.Relative ? MemoryLocation + instruction.Length : 0)));
                    }
                    break;

                case AddressingMode.ImmediateQuick:
                case AddressingMode.RegisterDirect:
                case AddressingMode.RegisterReference:
                    if (instruction.AddressingModeDestination == AddressingMode.Internal)
                    {
                        instruction.Operands.Add(DispatchOperand(memoryOpCode, instruction.AddressingModeSource, OperandNotation.Destination, 0));
                    }
                    else
                    {
                        instruction.Operands.Add(DispatchOperand(memoryOpCode, instruction.AddressingModeSource, OperandNotation.Source, 0));
                    }
                    break;

                case AddressingMode.StackPointer:
                    instruction.Operands.Add(new Operand()
                    {
                        AddressingMode = AddressingMode.StackPointer,
                        Notation       = OperandNotation.Source,
                        Symbol         = "SP",
                        Value          = 0,
                    });
                    break;

                case AddressingMode.ProgramCounter:
                    instruction.Operands.Add(new Operand()
                    {
                        AddressingMode = AddressingMode.ProgramCounter,
                        Notation       = OperandNotation.Source,
                        Symbol         = "PC",
                        Value          = 0,
                    });
                    break;

                case AddressingMode.StatusRegister:
                    instruction.Operands.Add(new Operand()
                    {
                        AddressingMode = AddressingMode.StatusRegister,
                        Notation       = OperandNotation.Source,
                        Symbol         = "SR",
                        Value          = 0,
                    });
                    break;
                }
            }

            return(instruction);
        }
        // debug helper
        public static Operation Disassembly(uint memIndex)
        {
            DasmSymbol symbol      = BinFileDasmRecord.SymbolsList.Where(w => w.DecimalValue == memIndex).FirstOrDefault();
            Operation  instruction = InstructionDecode(memIndex);

            if (symbol != null)
            {
                if (!symbol.isLabel)
                {
                    // make variable
                    ushort     dataWordValue = Functions.BytesToWord(Memory.Data[memIndex], Memory.Data[memIndex + 1]);
                    DasmSymbol valueSymbol   = BinFileDasmRecord.SymbolsList.Where(w => w.isLabel == true && w.DecimalValue == dataWordValue).FirstOrDefault();

                    instruction = new Operation()
                    {
                        OpCode      = dataWordValue,
                        OpCodeValue = dataWordValue,
                        Length      = 2,
                        Mnemonic    = "DW",
                        Type        = OperationType.Undefined,
                        Operands    = new List <Operand>()
                        {
                            new Operand()
                            {
                                Value  = dataWordValue,
                                Symbol = valueSymbol == null?
                                         string.Format("${0}", Convert.ToString(dataWordValue, 16).ToUpper().PadLeft(4, '0')) :
                                             valueSymbol.Name
                            }
                        }
                    };
                }
            }

            // undefined mnemonic passed as is
            if (instruction.Type != OperationType.Undefined)
            {
                if (instruction.Width == OperationWidth.Mixed)
                {
                    instruction.Mnemonic += (instruction.OpCodeValue & 0x020) != 0 ? ".B" : string.Empty;
                }

                foreach (Operand op in instruction.Operands)
                {
                    DasmSymbol valueSymbol = BinFileDasmRecord.SymbolsList.Where(w => w.DecimalValue == op.Value).FirstOrDefault();

                    // jumps see labels
                    if (instruction.Type != OperationType.Branch && valueSymbol != null)
                    {
                        // not jumps see vars reference
                        if (valueSymbol.isLabel && instruction.Context != OperationContext.Relative)
                        {
                            valueSymbol = null;
                        }
                    }

                    // lovely operands values to dump if doMonitor
                    switch (op.AddressingMode)
                    {
                    case AddressingMode.RegisterDirect:
                        op.DebugText = string.Format("{0}={1}", op.Symbol, Convert.ToString(State.A[op.Value], 16).PadLeft(4, '0'));
                        break;

                    case AddressingMode.RegisterReference:
                        op.DebugText = string.Format("{0}={1}", op.Symbol, Convert.ToString(Functions.BytesToWord(Memory.Data[State.A[op.Value]], Memory.Data[State.A[op.Value] + 1]), 16).PadLeft(4, '0'));
                        break;

                    case AddressingMode.ImmediateQuick:
                        op.DebugText = string.Format("{0}={1}", op.Symbol, op.Value);
                        break;

                    case AddressingMode.Immediate:
                        if (valueSymbol != null)    // && instruction.Type == OperationType.Branch)
                        {
                            op.Symbol = valueSymbol.Name;
                        }
                        op.DebugText = string.Format("{0}={1}", op.Symbol, Convert.ToString(op.Value, 16).PadLeft(4, '0'));
                        break;

                    case AddressingMode.MemoryReference:
                        if (valueSymbol != null)
                        {
                            op.Symbol = string.Format("({0})", valueSymbol.Name);
                        }
                        op.DebugText = string.Format("{0}={1}", op.Symbol, Convert.ToString(Functions.BytesToWord(Memory.Data[op.Value], Memory.Data[op.Value + 1]), 16).PadLeft(4, '0'));
                        break;

                    case AddressingMode.StackPointer:
                        op.DebugText = string.Format("{0}={1}", "SP", Convert.ToString(State.SP, 16).PadLeft(4, '0'));
                        break;

                    case AddressingMode.StatusRegister:
                        op.DebugText = string.Format("{0}={1}", "SR", StatusRegisterValue());
                        break;

                    case AddressingMode.ProgramCounter:
                        op.DebugText = string.Format("{0}={1}", "PC", Convert.ToString(State.PC, 16).PadLeft(4, '0'));;
                        break;
                    }
                }
            }

            instruction.DebugText = instruction.Mnemonic;
            if (instruction.Type == OperationType.Undefined || instruction.AddressingModeSource == AddressingMode.Internal || instruction.AddressingModeDestination == AddressingMode.Internal)
            {
                instruction.DebugText += " " + instruction.Operands[0].Symbol;
            }
            else if (instruction.Type == OperationType.Memory && instruction.AddressingModeDestination == AddressingMode.StackPointer)
            {
                instruction.DebugText += instruction.Operands[0].Symbol + " ";
            }
            else if (instruction.Type == OperationType.Memory && instruction.AddressingModeSource == AddressingMode.Internal)
            {
                instruction.DebugText += " " + instruction.Operands[0].Symbol + " ";
            }
            else
            {
                instruction.DebugText += instruction.Operands.Count() > 0 ? " " + instruction.Operands[0].Symbol + "," : string.Empty;
            }
            // GETSP
            if (instruction.Type == OperationType.Memory && instruction.AddressingModeSource == AddressingMode.StackPointer)
            {
                instruction.DebugText = "GETSP" + " " + instruction.Operands[0].Symbol;
            }
            else
            {
                instruction.DebugText += instruction.Operands.Count() > 1 ? instruction.Operands[1].Symbol : string.Empty;
            }

            return(instruction);
        }