コード例 #1
0
ファイル: DisassemblerForm.cs プロジェクト: guillemsola/C8POC
 /// <summary>
 /// Sets the button status
 /// </summary>
 /// <param name="machineState">
 /// The machine state.
 /// </param>
 private void SetButtonStatus(IMachineState machineState)
 {
     for (int i = 0; i < this.buttonList.Count(); i++)
     {
         this.buttonList.ElementAt(i).BackColor = machineState.Keys[i] ? Color.Green : Color.Transparent;
     }
 }
コード例 #2
0
ファイル: InternalState.cs プロジェクト: DespotBob/Herstamac
        public void GivenANewlyInitialisedSM()
        {
            MachineBuilder = new InitialMachineBuilder();

            MachineDefinition = MachineBuilder.GetMachineDefinition();
            MachineState      = MachineDefinition.NewMachineInstance(new State());
        }
コード例 #3
0
        private static void Dispatch <TInternalState, TEvent>(TEvent evnt
                                                              , IMachineState <TInternalState> internalState
                                                              , InternalState <TInternalState> currentState
                                                              , IReadOnlyDictionary <InternalState <TInternalState>, InternalState <TInternalState> > relations
                                                              , IEnumerable <Func <object, object> > eventInterceptors
                                                              , MachineConfiguration <TInternalState> config
                                                              , bool outerTransitionsTakePrecedence
                                                              , Func <string, InternalState <TInternalState> > lookup)
        {
            var currentStates = Misc <TInternalState> .FindAllStates(relations, currentState);

            if (!outerTransitionsTakePrecedence)
            {
                currentStates.Reverse();
            }

            var nextState = DispatchToStates(evnt, internalState, currentStates, eventInterceptors, config, lookup);

            if (nextState != null && nextState != currentStates.Last())
            {
                nextState = TransitionTo((object)evnt, internalState, relations, nextState, eventInterceptors, false, config, lookup);
            }

            if (nextState != null)
            {
                UpdateStateHistories(internalState, relations, nextState);
            }
        }
コード例 #4
0
        public void GivenANewlyInitialisedSM()
        {
            machine.AddEventInterceptor((evnt) =>
            {
                Console.WriteLine("Rx'd Event: {0}", evnt.GetType().Name);
                return(evnt);
            });

            machine.AddEventInterceptor((evnt) =>
            {
                Console.WriteLine("Rx'd Event2: {0}", evnt.GetType().Name);
                return(evnt);
            });

            MachineDefinition = machine.GetMachineDefinition(config =>
            {
                /* Name the Statemachine */
                config.Name("FastSlow");

                /* Define where the logging information is going! */
                config.Logger(x => Console.WriteLine(x));

                /* Define a function that will be used to serialise an event to a string */
                config.LogEventWith(x => x.ToString());

                /* Hmmm - Every state machine needs a unique Id - Get this one from here, otherwise it's a GUID! */
                config.UniqueId.FromProperty(p => p.Id);
            });

            MachineState = MachineDefinition.NewMachineInstance(new SlowFastStoppedInternalState());
        }
コード例 #5
0
        /// <summary>
        /// Loads a ROM, from a given path, in memory
        /// </summary>
        /// <param name="romPath">
        /// The rom path.
        /// </param>
        /// <param name="machineState">
        /// The machine state.
        /// </param>
        public void LoadRom(string romPath, IMachineState machineState)
        {
            if (File.Exists(romPath))
            {
                var rom = new FileStream(romPath, FileMode.Open);

                if (rom.Length == 0)
                {
                    throw new Exception(string.Format("File '{0}' empty or damaged", romPath));
                }

                int index;

                // Load rom starting at 0x200
                for (index = 0; index < rom.Length; index++)
                {
                    machineState.Memory[C8Constants.StartRomAddress + index] = (byte)rom.ReadByte();
                }

                machineState.NumberOfOpcodeBytes = index;

                rom.Close();
            }
            else
            {
                throw new FileNotFoundException(string.Format("The file '{0}' does not exist", romPath));
            }
        }
コード例 #6
0
ファイル: Lifts.cs プロジェクト: DespotBob/Herstamac
 public static IDisposable AsObservable <TInternalState, TEvent>(
     this IObservable <TEvent> t
     , MachineDefinition <TInternalState> machineDefinition
     , IMachineState <TInternalState> internalState)
 {
     return(t.Subscribe(x => MachineRunner.Dispatch(machineDefinition, internalState, x)));
 }
コード例 #7
0
        public DisassemblerControl(IMachineState state)
        {
            // TODO: maybe I don't need the ENTIRE state
            _state = state;

            _textArea = new RichTextArea
            {
                //BackgroundColor = Color.FromRgb(0),
                //TextColor = Color.FromGrayscale(1, 1),
                Font     = new Font("Monospace", 10),
                Width    = 300,
                ReadOnly = true,
            };

            //var stream = new MemoryStream();
            //var sw = new StreamWriter(stream);
            //sw.WriteLine("{\\rtf1 Hi {\\b Hi } \\line \\par asdf }");
            //sw.Flush();

            var stream = DisassembleAndFormat(100);

            _textArea.Buffer.Load(stream, RichTextAreaFormat.Rtf);

            Content = _textArea;
        }
コード例 #8
0
 /// <summary>
 /// Fx65 - LD Vx, [I]
 /// Read registers V0 through Vx from machineState.Memory starting at location I.
 /// The interpreter reads values from machineState.Memory starting at location I into registers V0 through Vx.
 /// </summary>
 /// <param name="machineState">
 /// The machine State.
 /// </param>
 public void LoadFromValueInRegisterIntoAllRegisters(IMachineState machineState)
 {
     for (int i = 0; i <= machineState.XRegisterFromCurrentOpcode; i++)
     {
         machineState.VRegisters[i] = machineState.Memory[machineState.IndexRegister + i];
     }
 }
コード例 #9
0
        /// <summary>
        /// Fx29 - LD F, Vx
        /// Set I = location of sprite for digit Vx.
        /// The value of I is set to the location for the hexadecimal sprite corresponding to the value of Vx.
        /// See section 2.4, Display, for more information on the Chip-8 hexadecimal font.
        /// </summary>
        /// <param name="machineState">
        /// The machine State.
        /// </param>
        public void LoadFontSpriteLocationFromValueInRegister(IMachineState machineState)
        {
            // Comments from NGEmu about this opcode

            /*Mmm... basically, set the machineState.Memory pointer I to the location of the character of the hexadecimal stored in register VX.
             * So... if it's FA29, you look in register VA and see what value it holds.
             * If it's F129, you look in register V1 and see what value it holds.
             * You can assume that the value stored in those registers only goes from 0x0 to 0xF.
             * Now... your emulator should have a table of sprite data already preset somewhere in the machineState.Memory (preferrably in the locations before 0x200).
             * These are sprite of characters from 0 to F, and they are 4x5 each in dimension.
             * Which means... mmm... the number 0 should be somewhat like this in binary data:
             *
             * 1111 0000
             * 1001 0000
             * 1001 0000
             * 1001 0000
             * 1111 0000
             *
             * If you have to ask, that's because the draw instruction draws 8 bits at a time.*/

            ushort character = machineState.VRegisters[machineState.XRegisterFromCurrentOpcode];

            // We assume that the value for character goes from 0x0 to 0xF and that each digit has size 5 (5 rows per digit)
            // Fonts are loaded starting at 0x0
            machineState.IndexRegister = (ushort)(5 * character);
        }
コード例 #10
0
ファイル: C8Engine.cs プロジェクト: guillemsola/C8POC
        /// <summary>
        /// Initializes a new instance of the <see cref="C8Engine"/> class.
        /// Engine constructor with an injected machine state
        /// </summary>
        /// <param name="machineState">
        /// An injected machine state
        /// </param>
        /// <param name="pluginService">
        /// The plugin Service.
        /// </param>
        /// <param name="configurationService">
        /// The configuration Service.
        /// </param>
        /// <param name="romService">
        /// The rom Service.
        /// </param>
        /// <param name="opcodeMapService">
        /// The opcode Map Service.
        /// </param>
        public C8Engine(
            IMachineState machineState,
            IPluginService pluginService,
            IConfigurationService configurationService,
            IRomService romService,
            IOpcodeMapService opcodeMapService)
        {
            // Injects the machine state
            this.machineState = machineState;

            // Inject the plugin service
            this.PluginService = pluginService;

            // Inject the configuration service
            this.ConfigurationService = configurationService;

            // Inject the ROM Service
            this.RomService = romService;

            // Inject the opcode map service
            this.OpcodeMapService = opcodeMapService;

            // Gets the instruction map
            this.instructionMap = this.OpcodeMapService.GetInstructionMap();

            // Loads the user saved configuration
            this.LoadSavedEngineSettings();

            // Loads the plugins
            this.LoadPlugins();
        }
コード例 #11
0
 /// <summary>
 /// ExA1 - SKNP Vx
 /// Skip next instruction if key with the value of Vx is not pressed.
 /// Checks the keyboard, and if the key corresponding to the value of Vx is currently in the up position,
 /// PC is increased by 2.
 /// </summary>
 /// <param name="machineState">
 /// The machine State.
 /// </param>
 public void SkipNextInstructionIfRegisterNotEqualsKeyPressed(IMachineState machineState)
 {
     if (!machineState.Keys[machineState.VRegisters[machineState.XRegisterFromCurrentOpcode]])
     {
         machineState.IncreaseProgramCounter();
     }
 }
コード例 #12
0
        /// <summary>
        /// Dxyn - DRW Vx, Vy, nibble
        /// Display n-byte sprite starting at machineState.Memory location I at (Vx, Vy), set VF = collision.
        /// The interpreter reads n bytes from machineState.Memory, starting at the address stored in I.
        /// These bytes are then displayed as sprites on screen at coordinates (Vx, Vy).
        /// Sprites are XORed onto the existing screen.
        /// If this causes any pixels to be erased, VF is set to 1, otherwise it is set to 0.
        /// If the sprite is positioned so part of it is outside the coordinates of the display, it wraps around to the opposite side of the screen.
        /// See instruction 8xy3 for more information on XOR, and section 2.4, Display, for more information on the Chip-8 screen and sprites.
        /// </summary>
        /// <param name="machineState">
        /// The machine State.
        /// </param>
        public void DrawSprite(IMachineState machineState)
        {
            var numbytes  = (ushort)(machineState.CurrentOpcode & 0x000F);
            var positionX = machineState.VRegisters[machineState.XRegisterFromCurrentOpcode];
            var positionY = machineState.VRegisters[machineState.YRegisterFromCurrentOpcode];

            for (var rowNum = 0; rowNum < numbytes; rowNum++)
            {
                ushort currentpixel = machineState.Memory[machineState.IndexRegister + rowNum];

                // We assume sprites are always 8 pixels wide
                for (var colNum = 0; colNum < 8; colNum++)
                {
                    if ((currentpixel & (0x80 >> colNum)) != 0)
                    {
                        int positioninGraphics = (positionX + colNum
                                                  + ((positionY + rowNum) * C8Constants.ResolutionWidth))
                                                 % (C8Constants.ResolutionWidth * C8Constants.ResolutionHeight);

                        // Make sure we get a value inside boundaries
                        if (machineState.Graphics[positioninGraphics])
                        {
                            // Collision!
                            machineState.VRegisters[0xF] = 1;
                        }

                        machineState.Graphics[positioninGraphics] ^= true;
                    }
                }

                machineState.IsDrawFlagSet = true;
            }
        }
コード例 #13
0
        /// <summary>
        /// Cxkk - RND Vx, byte
        /// Set Vx = random byte AND kk.
        /// The interpreter generates a random number from 0 to 255, which is then ANDed with the value kk.
        /// The results are stored in Vx. See instruction 8xy2 for more information on AND.
        /// </summary>
        /// <param name="machineState">
        /// The machine State.
        /// </param>
        public void LoadRandomIntoRegister(IMachineState machineState)
        {
            var randomnumber = (ushort)new Random().Next(0, 255);

            machineState.VRegisters[machineState.XRegisterFromCurrentOpcode] =
                (ushort)(randomnumber & (machineState.CurrentOpcode & 0x00FF));
        }
コード例 #14
0
 public static bool IsInState <TInternalState>(IMachineState <TInternalState> internalState,
                                               MachineDefinition <TInternalState> machineDefinition,
                                               State state)
 {
     return(Misc <TInternalState> .FindAllStates(machineDefinition.ParentStates, internalState.CurrentState)
            .Any(currentState => currentState.Name == state.Name));
 }
コード例 #15
0
ファイル: DisassemblerForm.cs プロジェクト: guillemsola/C8POC
 /// <summary>
 /// Sets the registry Values
 /// </summary>
 /// <param name="machineState">
 /// The machine state
 /// </param>
 private void SetRegisterValues(IMachineState machineState)
 {
     for (int i = 0; i < this.registerList.Count(); i++)
     {
         this.registerList.ElementAt(i).Text = machineState.VRegisters[i].ToString("X");
     }
 }
コード例 #16
0
 /// <summary>
 /// 9xy0 - SNE Vx, Vy
 /// Skip next instruction if Vx != Vy.
 /// The values of Vx and Vy are compared, and if they are not equal, the program counter is increased by 2.
 /// </summary>
 /// <param name="machineState">
 /// The machine State.
 /// </param>
 public void SkipNextInstructionIfRegisterNotEqualsRegister(IMachineState machineState)
 {
     if (machineState.VRegisters[machineState.XRegisterFromCurrentOpcode]
         != machineState.VRegisters[machineState.YRegisterFromCurrentOpcode])
     {
         machineState.IncreaseProgramCounter();
     }
 }
コード例 #17
0
ファイル: DisassemblerForm.cs プロジェクト: guillemsola/C8POC
 /// <summary>
 /// Binds the list of opcodes to the data grid view
 /// </summary>
 /// <param name="machineState">
 /// The machine state
 /// </param>
 public void BindOpcodeList(IMachineState machineState)
 {
     this.opcodeList = this.GetDecodedInstructionsFromMemory(machineState);
     this.MemoryAddressColumn.DataPropertyName = "Item1";
     this.RawOpcodeColumn.DataPropertyName     = "Item2";
     this.MnemonicColumn.DataPropertyName      = "Item3";
     this.dataGridViewOpcodes.DataSource       = this.opcodeList;
 }
コード例 #18
0
        /// <summary>
        /// 2nnn - CALL addr
        /// Call subroutine at nnn.
        /// The interpreter increments the machineState.Stack pointer, then puts the current PC on the top of the machineState.Stack.
        /// The PC is then set to nnn.
        /// </summary>
        /// <param name="machineState">
        /// The machine State.
        /// </param>
        public void CallAtAdress(IMachineState machineState)
        {
            // Program counter will be increased right after the instruction fetch
            // So theres no need to increase the program counter before pushing
            machineState.Stack.Push(machineState.ProgramCounter);

            machineState.ProgramCounter = (ushort)(machineState.CurrentOpcode & 0x0FFF);
        }
コード例 #19
0
 /// <summary>
 /// 4xkk - SNE Vx, byte
 /// Skip next instruction if Vx != kk.
 /// The interpreter compares register Vx to kk, and if they are not equal, increments the program counter by 2.
 /// </summary>
 /// <param name="machineState">
 /// The machine State.
 /// </param>
 public void SkipNextInstructionIfRegisterNotEqualsImmediate(IMachineState machineState)
 {
     if (machineState.VRegisters[machineState.XRegisterFromCurrentOpcode]
         != (machineState.CurrentOpcode & 0x00FF))
     {
         machineState.IncreaseProgramCounter();
     }
 }
コード例 #20
0
        public static IEnumerator <byte> Passive(IMachineState state)
        {
            var pc = state.Registers.PC.Value;

            while (true)
            {
                yield return(state.Memory[pc++]);
            }
        }
コード例 #21
0
ファイル: HistoryTests.cs プロジェクト: DespotBob/Herstamac
        public void GivenANewlyInitialisedSM()
        {
            MachineBuilder    = new HistoryStateMachineBuilder();
            MachineDefinition = MachineBuilder.GetMachineDefinition();
            InternalState     = MachineDefinition.NewMachineInstance(new HistoryState());

            // Given - The Machine is started
            MachineRunner.Start(MachineDefinition, InternalState);
        }
コード例 #22
0
ファイル: DisassemblerForm.cs プロジェクト: guillemsola/C8POC
 /// <summary>
 /// The refresh disassembler status.
 /// </summary>
 /// <param name="machineState">
 /// The monitored machine state
 /// </param>
 public void RefreshDisassemblerStatus(IMachineState machineState)
 {
     this.SetButtonStatus(machineState);
     this.SetRegisterValues(machineState);
     this.SetStackValues(machineState);
     this.SetTimerValues(machineState);
     this.SetProgramCounter(machineState);
     this.SetDrawFlag(machineState);
 }
コード例 #23
0
ファイル: BreakpointAdlers.cs プロジェクト: zxmak/ZXMAK2
        public bool checkInfo(IMachineState state)
        {
            if (!Info.IsOn)
            {
                return(false);
            }
            var needWriteMemoryCheck = IsNeedWriteMemoryCheck;

            IsNeedWriteMemoryCheck = false; // reset flag for next cycle
            if (IsForceStop)
            {
                IsForceStop = false;    // reset stop flag for next cycle
                return(true);           // return true to force stop
            }
            if (needWriteMemoryCheck && checkInfoMemory(state))
            {
                return(true);
            }

            lock (lockingObj)
            {
                if (debuggerStop)
                {
                    debuggerStop = false;
                    return(true);
                }
            }

            switch (Info.AccessType)
            {
            //e.g.: fZ == 1
            case BreakPointConditionType.flagVsValue:
            //e.g.: PC == #9C40
            case BreakPointConditionType.registryVsValue:
            //e.g.: (PC) == #AFC9 - instruction breakpoint; must be here because the registry change must be taking into account, not memory change
            case BreakPointConditionType.registryMemoryReferenceVsValue:
                if (Info.CheckBreakpoint())
                {
                    if (Info.IsMulticonditional)
                    {
                        return(Info.CheckSecondCondition());
                    }
                    else
                    {
                        return(true);
                    }
                }
                else
                {
                    return(false);
                }

            default:
                return(false);
            }
        }
コード例 #24
0
ファイル: DebugUtils.cs プロジェクト: a10r/GameboyEmulator
        public static string Trace(IMachineState state)
        {
            var pc = state.Registers.PC.Value;
            var disassembledInstr = Disassembler.DisassembleInstruction(InstructionLookahead.Passive(state));
            var bytes             = string.Join(" ", Enumerable.Range(0, disassembledInstr.Length).Select(i => state.Memory[pc + i].ToString("X2")));

            var hl = state.Memory[state.Registers.HL.Value];

            return($"0x{pc:X4}: {bytes,-10} {disassembledInstr.Text,-15} {state.Registers.ToString()}; (HL)={hl:X2}");
        }
コード例 #25
0
ファイル: DisassemblerForm.cs プロジェクト: guillemsola/C8POC
        /// <summary>
        /// Sets the stack Values
        /// </summary>
        /// <param name="machineState">
        /// The machine state
        /// </param>
        private void SetStackValues(IMachineState machineState)
        {
            this.stackList.ForEach(x => x.Text = @"0");

            for (int i = 0; i < machineState.Stack.Count; i++)
            {
                this.stackList.ElementAt(i).Text =
                    machineState.Stack.ElementAtOrDefault(i).ToString("X");
            }
        }
コード例 #26
0
 /// <summary>
 /// Returns a list of of the Events that the state machine will currently perform an action on.
 /// </summary>
 /// <typeparam name="TInternalState"></typeparam>
 /// <param name="internalState"></param>
 /// <param name="machineDefinition"></param>
 /// <returns>Will not return Events.EntryEvents or exit Events.ExitEvent events</returns>
 public static IEnumerable <Type> CurrentlyActionableEvents <TInternalState>(IMachineState <TInternalState> internalState, MachineDefinition <TInternalState> machineDefinition)
 {
     return(Misc <TInternalState> .FindAllStates(machineDefinition.ParentStates, internalState.CurrentState)
            .SelectMany(x => x.Handlers)
            .Select(x => x.Key)
            .Where(x => x != typeof(Events.EntryEvent))
            .Where(x => x != typeof(Events.ExitEvent))
            .Distinct()
            .ToList());
 }
コード例 #27
0
 public void DispenseProduct()
 {
     vendingMachineState.DispenseProduct();
     // Product has been dispensed so vending Machine changed the
     // internal state to 'NoMoneyState'
     if (vendingMachineState is HasMoneyState)
     {
         vendingMachineState = new NoMoney();
         Console.WriteLine("VendingMachine internal state has been moved to : " + vendingMachineState.GetType().Name);
     }
 }
コード例 #28
0
 public void SelectProductAndInsertMoney(int amount, string productName)
 {
     vendingMachineState.SelectProductAndInsertMoney(amount, productName);
     // Money has been inserted so vending Machine internal state
     // changed to 'hasMoneyState'
     if (vendingMachineState is NoMoney)
     {
         vendingMachineState = new HasMoneyState();
         Console.WriteLine("VendingMachine internal state has been moved to : " + vendingMachineState.GetType().Name);
     }
 }
コード例 #29
0
        /// <summary>
        /// Fx33 - LD B, Vx
        /// Store BCD representation of Vx in machineState.Memory locations I, I+1, and I+2.
        /// The interpreter takes the decimal value of Vx,
        /// and places the hundreds digit in machineState.Memory at location in I,
        /// the tens digit at location I+1,
        /// and the ones digit at location I+2.
        /// </summary>
        /// <param name="machineState">
        /// The machine State.
        /// </param>
        public void LoadBcdRepresentationFromRegister(IMachineState machineState)
        {
            machineState.Memory[machineState.IndexRegister] =
                (byte)(machineState.VRegisters[machineState.XRegisterFromCurrentOpcode] / 100); // Hundreds

            machineState.Memory[machineState.IndexRegister + 1] =
                (byte)((machineState.VRegisters[machineState.XRegisterFromCurrentOpcode] / 10) % 10); // Tens

            machineState.Memory[machineState.IndexRegister + 2] =
                (byte)(machineState.VRegisters[machineState.XRegisterFromCurrentOpcode] % 10); // Ones
        }
コード例 #30
0
ファイル: BreakpointAdlers.cs プロジェクト: zxmak/ZXMAK2
        private bool checkInfoMemory(IMachineState state)
        {
            if (!Info.IsOn)
            {
                return(false);
            }

            lock (lockingObj)
            {
                if (debuggerStop)
                {
                    debuggerStop = false;
                    return(true);
                }
            }

            ushort leftValue = 0;

            switch (Info.AccessType)
            {
            // e.g.: (#9C40) != #2222
            case BreakPointConditionType.memoryVsValue:
                if (Info.CheckBreakpoint())
                {
                    if (Info.IsMulticonditional)
                    {
                        return(Info.CheckSecondCondition());
                    }
                    else
                    {
                        return(true);
                    }
                }
                else
                {
                    return(false);
                }

            default:
                break;
            }

            //condition
            if (Info.IsConditionEquals) // is equal
            {
                return(leftValue == Info.RightValue);
            }
            else
            {
                return(leftValue != Info.RightValue);
            }
        }
コード例 #31
0
ファイル: FormCPU.cs プロジェクト: bobsummerwill/ZXMAK2
        private bool checkInfo(IMachineState state)
        {
            if (!Info.isOn)
                return false;

            ushort leftValue = 0;
            ushort rightValue = 0;

            switch (Info.accessType)
            {
                // e.g.: PC == #9C40
                case BreakPointConditionType.registryVsValue:
                    leftValue = DebuggerManager.getRegistryValueByName(state.CPU.regs, Info.leftCondition);
                    rightValue = Info.rightValue;
                    break;
                // e.g.: (#9C40) != #2222
                case BreakPointConditionType.memoryVsValue:
                    leftValue = state.ReadMemory(Info.leftValue);
                    rightValue = Info.rightValue;
                    break;
                // e.g.: (PC) == #D1 - instruction breakpoint
                case BreakPointConditionType.registryMemoryReferenceVsValue:
                    leftValue = state.ReadMemory(DebuggerManager.getRegistryValueByName(state.CPU.regs, DebuggerManager.getRegistryFromReference(Info.leftCondition)));
                    rightValue = Info.rightValue;
                    if (rightValue > 0xFF) //check on 2 bytes right condition, e.g.: (PC) == #5EED
                    {
                        int hiByte = DebuggerManager.getRegistryValueByName(state.CPU.regs, DebuggerManager.getRegistryFromReference(Info.leftCondition)) + 1;
                        if (hiByte > 0xFFFF)
                            hiByte = 0;
                        leftValue += Convert.ToUInt16(state.ReadMemory(Convert.ToUInt16(hiByte)) * 256);
                    }
                    break;
                default:
                    break;
            }

            //condition
            if (Info.conditionTypeSign == "==") // is equal
            {
                if (leftValue == rightValue)
                    return true;
            }
            else if (Info.conditionTypeSign == "!=") // is not equal
            {
                if (leftValue != rightValue)
                    return true;
            };
            return false;
        }