예제 #1
0
        public bool execute()
        {
            // add address, instruction, and disassembled instruction strings to each list
            string addr = "0x" + currentInstAddress.ToString("X").PadLeft(8, '0');
            string inst = currentInstruction.ToString("x").PadLeft(8, '0');

            #region For testing purposes
            instAddressLst.Add(addr);
            instLst.Add(inst);
            #endregion

            // prepare string
            disassembledCombinedString = disassembledCombinedString + "\r\n" + addr + "\t" + inst + "\t";
            lastDisString = disassembledCombinedString;

            // will be used to collect strings to later concatenate with field string disassembledCombinedString
            string tempStr = "";

            // INJECT A NOP into execute if instruction is a NOP
            if (Extras.isNOPInstruction(currentInstruction, registers.getNFlag(), registers.getZFlag(), registers.getCFlag(), registers.getVFlag()))
            {
                writeInfoToTraceLogForSimI();
                #region For testing purposes
                instDisLst.Add("NOP");
                #endregion
                disassembledCombinedString += "NOP";
                lastDisString += "NOP";
                return(false);
            }

            /************************SPECIAL CASES ****************************/
            // SWI
            if (Extras.isSWIInstruction(currentInstruction))
            {
                //Debug.WriteLine("SWI in CPU.decode(). End of instructions");
                uint swi_imm = currentInstruction & 0x00ffffff;

                // add swi immediate to disassembled list
                tempStr = "svc 0x" + swi_imm.ToString("x").PadLeft(8, '0');

                #region For testing purposes
                instDisLst.Add(tempStr);
                #endregion

                disassembledCombinedString += tempStr;
                lastDisString += tempStr;

                writeInfoToTraceLogForSimI();
                switch (swi_imm.ToString("x").PadLeft(2, '0'))
                {
                case "00":
                    ArmSimFormRef.WriteCharToTerminal("Hello World!");
                    break;

                case "11":
                    return(true);

                case "6a":
                    while (!ArmSimFormRef.checkCharsQueueContainsReturn())
                    {
                        Thread.Sleep(2000);
                    }
                    bool gotReturnValue    = false;
                    uint memoryBufferPlace = 0;
                    while (!gotReturnValue)
                    {
                        char readValue = ArmSimFormRef.dequeCharsQueue();
                        if (readValue == (char)13)
                        {
                            gotReturnValue = true;
                            if (memoryBufferPlace < registers.getRegNValue(2))
                            {
                                memory.WriteByte(registers.getRegNValue(1) + memoryBufferPlace, 0x0);
                            }
                            else
                            {
                                memory.WriteByte(registers.getRegNValue(1) + (memoryBufferPlace - 1), 0x0);
                            }
                        }
                        if (memoryBufferPlace < registers.getRegNValue(2))
                        {
                            Console.WriteLine(readValue);
                            memory.WriteByte(registers.getRegNValue(1) + memoryBufferPlace, Convert.ToByte(readValue));
                            memoryBufferPlace++;
                        }
                    }

                    //memory.WriteByte(registers.getRegNValue(1), 0x35);
                    //memory.WriteByte(registers.getRegNValue(1) + 1, 0x0);
                    break;

                default:
                    break;
                }
                return(false); // true to stop executing more instructions
            }

            // MUL
            if (Extras.isMulInstruction(currentInstruction))
            {
                mul_instruct.executeMul();

                tempStr = mul_instruct.getInstructionString();

                #region For testing purposes
                instDisLst.Add(tempStr);
                #endregion

                disassembledCombinedString += tempStr;
                lastDisString += tempStr;

                writeInfoToTraceLogForSimI();
                return(false); // false to keep excuting more instructions
            }

            // BX CASE
            if (Extras.isBX(currentInstruction))
            {
                bx_instruct.executeBx();

                tempStr = bx_instruct.getInstructionString();

                #region For testing purposes
                instDisLst.Add(tempStr);
                #endregion

                disassembledCombinedString += tempStr;
                lastDisString += tempStr;

                writeInfoToTraceLogForSimI();
                return(false); // false to keep excuting more instructions
            }

            /************************NORMAL CASES ****************************/
            // execute the instruction according to its type
            switch (currentInstructionType)
            {
            case 0:     // if Data Processing (00x)
            case 1:     // if Data Processing (00x)
                data_processing_instruct.executeDP();

                tempStr = data_processing_instruct.getInstructionString();

                #region For testing purposes
                instDisLst.Add(tempStr);
                #endregion

                disassembledCombinedString += tempStr;
                lastDisString += tempStr;
                break;

            case 2:     // if Load/Store (01x)
            case 3:     // if Load/Store (01x)
                load_store_instruct.executeLaS();

                tempStr = load_store_instruct.getInstructionString();

                #region For testing purposes
                instDisLst.Add(tempStr);
                #endregion

                disassembledCombinedString += tempStr;
                lastDisString += tempStr;
                break;

            case 4:     // if Load/Store (100) Load/Store Multiple FD variant
                load_store_mul_instruct.executeLaSMul();

                tempStr = load_store_mul_instruct.getInstructionString();

                #region For testing purposes
                instDisLst.Add(tempStr);
                #endregion

                disassembledCombinedString += tempStr;
                lastDisString += tempStr;
                break;

            case 5:     // if Branch (101)
                branch_instruct.executeB();

                tempStr = branch_instruct.getInstructionString();

                #region For testing purposes
                instDisLst.Add(tempStr);
                #endregion

                disassembledCombinedString += tempStr;
                lastDisString += tempStr;
                break;

            // TODO: Check special cases
            default:
                Debug.WriteLine("ERROR in CPU.execute(): Type is Special or Non-valid instruction.");
                break;
            } // end switch

            writeInfoToTraceLogForSimI();

            //Thread.Sleep(5000);

            return(false);
        }