void IN(ref Register rDestination, int S2, bool bFlag, ref TableSet tables)
 {
     if (bFlag)
     {
         tables.setTableItem(MainForm.getRegister(RegisterType.INPUT_REGISTER).data,
                             MainForm.getRegister(RegisterType.INPUT_REGISTER).dataType, S2, TableType.DATA_TABLE);
     }
     else
     {
         rDestination.setData(MainForm.getRegister(RegisterType.INPUT_REGISTER).data, MainForm.getRegister(RegisterType.INPUT_REGISTER).dataType);
     }
 }
 void OUT(ref Register outRegister, ref Register rSource, int S2, bool bFlag, ref TableSet tables)
 {
     if (bFlag)
     {
         string content = tables.DataTable.values[S2];
         outRegister.setData(content, tables.DataTable.valueType);
     }
     else
     {
         outRegister.setData(rSource.data, rSource.dataType);
     }
 }
        void RET(ref Register stackPointer, ref Register programCounter, ref TableSet tables)
        {
            int newSP = stackPointer.convertDataToInt() - 1;

            if (newSP < 0)
            {
                MessageBox.Show("Stack Overflow!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else if (newSP == 0)
            {
                stackEmpty = true;
                stackFull  = false;
            }
            stackPointer.setData((stackPointer.convertDataToInt() - 1).ToString(), DataType.DECIMAL);
            programCounter.setData(tables.StackTable.values[stackPointer.convertDataToInt()], tables.StackTable.valueType);
            insTableLine = programCounter.convertDataToInt() - 1;
            Jump         = true;
        }
        void CALL(int BS2, ref Register programCounter, ref Register stackPointer, ref TableSet tables)
        {
            string pcData = programCounter.data;

            tables.setTableItem(pcData, programCounter.dataType, stackPointer.convertDataToInt(), TableType.STACK_TABLE);
            int newSP = stackPointer.convertDataToInt() + 1;

            if (newSP > tables.StackTable.values.Length)
            {
                MessageBox.Show("Stack Overflow!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else if (newSP == tables.StackTable.values.Length)
            {
                stackFull = true;
            }
            stackEmpty = false;
            stackPointer.setData(newSP.ToString(), DataType.DECIMAL);
            programCounter.setData(BS2.ToString(), DataType.DECIMAL);
            insTableLine = BS2 - 1;
            Jump         = true;
        }
        public bool decode(ref Register[] registers, ref TableSet tables)
        {
            EXECUTE_STRING = "\tExecute ";
            string   instruction     = MainForm.getRegister(RegisterType.INSTRUCTION_REGISTER).data;
            DataType insDataType     = MainForm.getRegister(RegisterType.INSTRUCTION_REGISTER).dataType;
            int      instructionBase = 2;

            instructionBase = insDataType == DataType.DECIMAL ? 10 : insDataType == DataType.HEXADECIMAL ? 16 : 2;
            if (instructionBase != 2)
            {
                instruction = Convert.ToString(Convert.ToInt32(instruction, instructionBase), 2).PadLeft(14, '0');
            }
            string insOpCode = instruction.Substring(0, 5);

            string destination = (Convert.ToInt32(instruction[5] + "" + instruction[6], 2) + 1).ToString();
            string source      = (Convert.ToInt32(instruction[7] + "" + instruction[8], 2) + 1).ToString();
            string dataBS2     = instruction[9] + "" + instruction[10] + "" + instruction[11] + "" + instruction[12] + "" + instruction[13];
            string dataString  = instruction[10] + "" + instruction[11] + "" + instruction[12] + "" + instruction[13];
            int    data        = Convert.ToInt32(dataString, 2);
            bool   bFlag       = false;

            //////////////////////////
            string showValue  = "";
            string showOpcode = "";

            switch (insOpCode)
            {
            case "00010":    //HLT
                showOpcode = "HLT";
                return(false);

            case "10000":    //ADD
                EXECUTE_STRING += "ADD:\t R";
                EXECUTE_STRING += destination;
                showOpcode      = "ADD";
                if (instruction[9] == '1')
                {
                    EXECUTE_STRING += " <- R" + source + " + AR, SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", AR";
                    bFlag           = true;
                }
                else
                {
                    EXECUTE_STRING += " <- R" + source + " + R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1) + ", SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1);
                }
                ADD(ref registers[Convert.ToInt16(destination) - 1], ref registers[Convert.ToInt16(source) - 1], data, bFlag);
                break;

            case "10001":    //SUB
                EXECUTE_STRING += "SUB:\t R";
                showOpcode      = "SUB";
                EXECUTE_STRING += destination;
                bFlag           = false;
                if (instruction[9] == '1')
                {
                    EXECUTE_STRING += " <- R" + source + " - AR, SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", AR";
                    bFlag           = true;
                }
                else
                {
                    EXECUTE_STRING += " <- R" + source + " - R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1) + ", SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1);
                }
                SUB(ref registers[Convert.ToInt16(destination) - 1], ref registers[Convert.ToInt16(source) - 1], data, bFlag);
                break;

            case "10100":    //AND
                EXECUTE_STRING += "AND:\t R";
                EXECUTE_STRING += destination;
                showOpcode      = "AND";
                if (instruction[9] == '1')
                {
                    EXECUTE_STRING += " <- R" + source + " ∧ AR, SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", AR";
                    bFlag           = true;
                }
                else
                {
                    EXECUTE_STRING += " <- R" + source + " ∧ R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1) + ", SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1);
                }
                And(ref registers[Convert.ToInt32(destination) - 1], ref registers[Convert.ToInt32(source) - 1], data, bFlag);
                break;

            case "10101":    //OR
                EXECUTE_STRING += "OR:\t R";
                showOpcode      = "OR";
                EXECUTE_STRING += destination;
                if (instruction[9] == '1')
                {
                    EXECUTE_STRING += " <- R" + source + " V AR, SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", AR";
                    bFlag           = true;
                }
                else
                {
                    EXECUTE_STRING += " <- R" + source + " V R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1) + ", SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1);
                }
                Or(ref registers[Convert.ToInt32(destination) - 1], ref registers[Convert.ToInt32(source) - 1], data, bFlag);
                break;

            case "10110":    //XOR
                EXECUTE_STRING += "XOR:\t R";
                EXECUTE_STRING += destination;
                showOpcode      = "XOR";
                if (instruction[9] == '1')
                {
                    EXECUTE_STRING += " <- R" + source + " ⊕ AR, SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", AR";
                    bFlag           = true;
                }
                else
                {
                    EXECUTE_STRING += " <- R" + source + " ⊕ R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1) + ", SC <- 0\n";
                    showValue       = "R" + destination + ", R" + source + ", R" + (MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt() + 1);
                }
                xOr(ref registers[Convert.ToInt32(destination) - 1], ref registers[Convert.ToInt32(source) - 1], data, bFlag);
                break;

            case "10010":    //SHL
                EXECUTE_STRING += "SHL:\t R";
                showOpcode      = "SHL";
                EXECUTE_STRING += destination;
                EXECUTE_STRING += " <- shiftL R" + source + ", SC <- 0\n";
                showValue       = "R" + destination + ", R" + source;
                shiftLeft(ref registers[Convert.ToInt32(destination) - 1], ref registers[Convert.ToInt32(source) - 1]);
                break;

            case "10011":    //SHR
                EXECUTE_STRING += "SHR:\t R";
                showOpcode      = "SHR";
                EXECUTE_STRING += destination;
                EXECUTE_STRING += " <- shiftR R" + source + ", SC <- 0\n";
                showValue       = "R" + destination + ", R" + source;
                shiftRight(ref registers[Convert.ToInt32(destination) - 1], ref registers[Convert.ToInt32(source) - 1]);
                break;

            case "11111":    //INC
                EXECUTE_STRING += "INC:\t R";
                showOpcode      = "INC";
                EXECUTE_STRING += destination;
                EXECUTE_STRING += " <- R" + source + " + 1, SC <- 0\n";
                showValue       = "R" + destination + ", R" + source;
                INC(ref registers[Convert.ToInt32(destination) - 1], ref registers[Convert.ToInt32(source) - 1]);
                break;

            case "10111":    //COMA
                EXECUTE_STRING += "COMA:\t R";
                showOpcode      = "COMA";
                EXECUTE_STRING += destination;
                EXECUTE_STRING += " <- ¬R" + source + ", SC <- 0\n";
                showValue       = "R" + destination + ", R" + source;
                COMA(ref registers[Convert.ToInt32(destination) - 1], ref registers[Convert.ToInt32(source) - 1]);
                break;

            case "01100":    //LD
                EXECUTE_STRING += "LD:\t R";
                showOpcode      = "LD";
                EXECUTE_STRING += destination;
                EXECUTE_STRING += " <- DM[AR], SC <- 0\n";
                showValue       = "R" + destination + ", DM[AR]";
                registers[Convert.ToInt16(destination) - 1].setData(tables.DataTable.values[MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt()], tables.DataTable.valueType);
                break;

            case "01101":    //ST
                EXECUTE_STRING += "ST:\t DM[AR] <- R";
                EXECUTE_STRING += source;
                showValue       = "DM[AR], R" + source;
                showOpcode      = "ST";
                EXECUTE_STRING += ", SC <- 0\n";

                tables.setTableItem(registers[Convert.ToInt32(source) - 1].data, registers[Convert.ToInt32(source) - 1].dataType, MainForm.getRegister(RegisterType.ADDRESS_REGISTER).convertDataToInt(), TableType.DATA_TABLE);
                break;

            case "01110":    //IN
                showOpcode = "IN";
                if (instruction[9] == '1')
                {
                    EXECUTE_STRING += "IN:\t DM[AR] <- InR, SC <- 0\n";
                    showValue       = "DM[AR], InR";
                    bFlag           = true;
                }
                else
                {
                    EXECUTE_STRING += "IN:\t R" + destination + " <- InR, SC <- 0\n";
                    showValue       = "R" + destination + ", InR";
                }
                IN(ref registers[Convert.ToInt32(destination) - 1], data, bFlag, ref tables);
                break;

            case "01111":    //OUT
                showOpcode = "OUT";
                if (instruction[9] == '1')
                {
                    EXECUTE_STRING += "OUT:\t OuR <- DM[AR], SC <- 0\n";
                    bFlag           = true;
                }
                else
                {
                    EXECUTE_STRING += "OUT:\t OuR <- R" + source + ", SC <- 0\n";
                    showValue       = "OuR, R" + source;
                }
                OUT(ref registers[6], ref registers[Convert.ToInt32(source) - 1], data, bFlag, ref tables);
                break;

            case "01001":    //JMP
                showOpcode = "JMP";
                bool jmpExecute = false;
                if ((Convert.ToInt16(destination) == 1 && carryOut) || (Convert.ToInt16(destination) == 2 && zero) ||
                    (Convert.ToInt16(destination) == 3 && overFlow))
                {
                    EXECUTE_STRING += "JMP:\t PC(4) <- B, PC(3-0) <- AR, SC <- 0\n";
                    jmpExecute      = true;
                }
                else
                {
                    EXECUTE_STRING += "JMP:\t Not Executed!!";
                }

                if (jmpExecute)
                {
                    JMP(ref registers[8], dataBS2);
                }

                break;

            case "01010":    //CALL
                showOpcode      = "CALL";
                EXECUTE_STRING += "CALL:\t --(T2)-- SM[SP] <- PC\n\t\t --(T3) -- SP <- SP + 1, PC <- BS2, SC <- 0\n";
                CALL(Convert.ToInt32(dataBS2, 2), ref registers[8], ref registers[9], ref tables);
                break;

            case "01011":    //RET
                showOpcode      = "RET";
                EXECUTE_STRING += "CALL:\t --(T2)-- SP <- SP - 1\n\t\t --(T3) -- PC <- SM[SP], SC <- 0\n";
                RET(ref registers[9], ref registers[8], ref tables);
                break;

            case "00110":    //EMPTY
                showOpcode = "EMPTY";
                break;

            case "00111":    //FULL
                showOpcode = "FULL";
                break;
            }
            txtShowOpcode.Text = showOpcode;
            txtShowValue.Text  = showValue;
            return(true);
        }