public override bool StepCycle()
        {
            if (IsHalted)
            {
                return(true);
            }

            string debugInfo;

            MessageManager.ShowLine($"-Cycle.{ this.CycleCount.ToString().PadLeft(8,' ') } -------------------------------------------", enumMessageLevel.ExecutionLog);
            {
                MessageManager.GoInnerTab();
                MessageManager.ShowLine($"PC: 0x{ (CircuitGroup.FS.PCOut_OFace.Value*2).ToString("X8") }", enumMessageLevel.ExecutionLog);

                Action showRAMHighPin = () =>
                {
                    MessageManager.Show("  (RAM-High) : ", enumMessageLevel.ExecutionLog);
                    MessageManager.GoInnerTab();
                    if (CircuitGroup.AS.MemoryStallRequest_OFace.Value)
                    { //MA
                        if (CircuitGroup.SyncMemoryHighRead.Value.Enabled)
                        {
                            uint readed = (uint)CircuitGroup.SyncMemoryHigh.Read_OFace.Value << 16 | CircuitGroup.SyncMemoryLow.Read_OFace.Value;
                            MessageManager.Show($"Memory read at 0x{(CircuitGroup.SyncMemoryHighRead.Value.Address * 4).ToString("X8")}", enumMessageLevel.ExecutionLog);
                            MessageManager.Show($" => {(int)readed} (0x{readed.ToString("X8")})", enumMessageLevel.ExecutionLog);

                            Memory.GetDebugInfo((uint)CircuitGroup.SyncMemoryHighRead.Value.Address, out debugInfo, 1, 0);
                            if (debugInfo != "")
                            {
                                MessageManager.Show($" ・・・ \"{ debugInfo }\"", enumMessageLevel.ExecutionLog);
                            }
                            MessageManager.ShowLine($"", enumMessageLevel.ExecutionLog);
                        }
                        else if (CircuitGroup.SyncMemoryHighWrite.Value.Enabled)
                        {
                            uint written = (uint)CircuitGroup.SyncMemoryHighWrite.Value.Value << 16 | CircuitGroup.SyncMemoryLowWrite.Value.Value;
                            MessageManager.Show($"Memory write to 0x{(CircuitGroup.SyncMemoryHighWrite.Value.Address * 4).ToString("X8")}", enumMessageLevel.ExecutionLog);
                            MessageManager.Show($" <= {(int)written} (0x{written.ToString("X8")})", enumMessageLevel.ExecutionLog);

                            Memory.GetDebugInfo((uint)CircuitGroup.SyncMemoryHighRead.Value.Address, out debugInfo, 1, 0);
                            if (debugInfo != "")
                            {
                                MessageManager.Show($" ・・・ \"{ debugInfo }\"", enumMessageLevel.ExecutionLog);
                            }
                            MessageManager.ShowLine($"", enumMessageLevel.ExecutionLog);
                        }
                    }
                    else
                    { //fetch
                        uint pc = (uint)CircuitGroup.SyncMemoryHighRead.Value.Address * 2;
                        MessageManager.Show($"Fetching at PC: 0x{ (pc*2).ToString("X8") }", enumMessageLevel.ExecutionLog);

                        Memory.GetDebugInfo(pc / 2, out debugInfo, 2, (int)pc % 2);
                        if (debugInfo != "")
                        {
                            MessageManager.ShowLine($" ・・・ \"{ debugInfo }\"", enumMessageLevel.ExecutionLog);
                        }
                        MessageManager.ShowLine($"", enumMessageLevel.ExecutionLog);
                    }
                    MessageManager.GoOuterTab();
                };
                Action showRAMLowPin = () =>
                {
                    if (CircuitGroup.AS.MemoryStallRequest_OFace.Value)
                    { //MA
                    }
                    else
                    { //fetch
                        MessageManager.Show("  (RAM-Low) : ", enumMessageLevel.ExecutionLog);
                        MessageManager.GoInnerTab();
                        uint pc = (uint)CircuitGroup.SyncMemoryLowRead.Value.Address * 2 + 1;
                        MessageManager.Show($"Fetching at PC: 0x{ (pc * 2).ToString("X8") }", enumMessageLevel.ExecutionLog);
                        Memory.GetDebugInfo(pc / 2, out debugInfo, 2, (int)pc % 2);
                        if (debugInfo != "")
                        {
                            MessageManager.ShowLine($" ・・・ \"{ debugInfo }\"", enumMessageLevel.ExecutionLog);
                        }
                        MessageManager.ShowLine($"", enumMessageLevel.ExecutionLog);
                        MessageManager.GoOuterTab();
                    }
                };
                if (!CircuitGroup.AS.MemoryStallRequest_OFace.Value)
                {
                    MessageManager.ShowLine("[Fetch Stage] ", enumMessageLevel.ExecutionLog);
                    if (CircuitGroup.SyncMemoryLowRead.Value.Address == CircuitGroup.SyncMemoryHighRead.Value.Address)
                    {
                        ushort intsr         = CircuitGroup.SyncMemoryHigh.Read_OFace.Value;
                        byte   instrOpcode   = (byte)((intsr >> 14) & 3);
                        bool   instrJumpFlag = ((intsr >> 13) & 1) != 0;

                        showRAMHighPin();
                        if ((instrOpcode & 2) == 0 && instrJumpFlag)
                        {
                            showRAMLowPin();
                        }
                    }
                    else
                    {
                        ushort intsr         = CircuitGroup.SyncMemoryLow.Read_OFace.Value;
                        byte   instrOpcode   = (byte)((intsr >> 14) & 3);
                        bool   instrJumpFlag = ((intsr >> 13) & 1) != 0;

                        showRAMLowPin();
                        if ((instrOpcode & 2) == 0 && instrJumpFlag)
                        {
                            showRAMHighPin();
                        }
                    }
                }
                else
                {
                    MessageManager.ShowLine($"**Stalling for Memory Access**", enumMessageLevel.ExecutionLog);
                    showRAMHighPin();
                    showRAMLowPin();
                }

                if (!CircuitGroup.AS.MemoryStallRequest_OFace.Value && CircuitGroup.CS.ValidCS_IFace)
                {
                    MessageManager.ShowLine("[Compute Stage]", enumMessageLevel.ExecutionLog);

                    MessageManager.GoInnerTab();
                    {
                        string opMode   = "";
                        string condMode = "";
                        switch (CircuitGroup.CS.Instruction_IFace.Get() >> 30)
                        {
                        case 0:
                            opMode = "SUB";
                            if (((CircuitGroup.CS.Instruction_IFace.Get() >> 29) & 1) != 0)
                            {
                                condMode = (CircuitGroup.CS.alu_condflag_OFace.Value == 1 ? "CAR" : CircuitGroup.CS.alu_condflag_OFace.Value == 4 ? "NEG" : "LSB");
                            }
                            break;

                        case 1:
                            opMode = "AND";
                            if (((CircuitGroup.CS.Instruction_IFace.Get() >> 29) & 1) != 0)
                            {
                                condMode = (CircuitGroup.CS.alu_condflag_OFace.Value == 1 ? "CAR" : CircuitGroup.CS.alu_condflag_OFace.Value == 4 ? "NEG" : "LSB");
                            }
                            break;

                        case 3:
                            opMode = "SHR";
                            break;

                        case 2:
                            opMode = (((CircuitGroup.CS.Instruction_IFace.Get() >> 29) & 1) == 0) ? "MR" : "MW";
                            break;
                        }
                        MessageManager.Show($" *OpMode = { opMode }", enumMessageLevel.ExecutionLog);
                        if (condMode != "")
                        {
                            MessageManager.Show($" -< J{ condMode }", enumMessageLevel.ExecutionLog);
                        }
                        MessageManager.ShowLine("", enumMessageLevel.ExecutionLog);
                        MessageManager.ShowLine(" *ALU", enumMessageLevel.ExecutionLog);
                        MessageManager.ShowLine($"   A = { (int)CircuitGroup.CS.alu_a_OFace.Value } (0x{CircuitGroup.CS.alu_a_OFace.Value.ToString("X8")})", enumMessageLevel.ExecutionLog);
                        MessageManager.ShowLine($"   B = { (int)CircuitGroup.CS.alu_b_OFace.Value } (0x{CircuitGroup.CS.alu_b_OFace.Value.ToString("X8")})", enumMessageLevel.ExecutionLog);
                        MessageManager.ShowLine($"   RES={ (int)CircuitGroup.CS.Alu.OpResult_OFace.Value } (0x{CircuitGroup.CS.Alu.OpResult_OFace.Value.ToString("X8")})", enumMessageLevel.ExecutionLog);
                        if (condMode != "")
                        {
                            MessageManager.ShowLine($"   CND={ CircuitGroup.CS.Alu.CondResult_OFace.Value }", enumMessageLevel.ExecutionLog);
                        }
                    }
                    MessageManager.GoOuterTab();
                }
                MessageManager.GoOuterTab();
            }


            if (CircuitGroup.AS.RegWen_OFace.Value && CircuitGroup.AS.RegWdata_OFace.Value == 0xFFFFFFFC)
            {
            }

            CircuitGroup.UpdateCycle();

            //System.IO.File.AppendAllText("PCLog.txt", "# " + (this.CircuitGroup.ProgramCounter * 2).ToString("X4") + "\n");

            if (this.CircuitGroup.ProgramCounter == this.PrevPrevProgramCounter && !PrevStalled)
            {
                MessageManager.ShowLine($"S Y S T E M  H A L T", enumMessageLevel.ExecutionLog);
                base.IsHalted = true;
            }
            this.PrevPrevProgramCounter = this.PrevProgramCounter;
            this.PrevProgramCounter     = this.CircuitGroup.ProgramCounter;
            this.PrevStalled            = this.CircuitGroup.AS.MemoryStallRequest_OFace.Value;

            this.CycleCount++;
            MarkExecutionTraceData((int)CircuitGroup.ProgramCounter, (long)CycleCount);
            StackPointerMin = Math.Min(StackPointerMin, CircuitGroup.CS.RegisterFile.Entries[1].Content);

            /*
             * StringBuilder sb = new StringBuilder();
             * for (int i = 0; i < 16; i++)
             * {
             *  sb.Append(this.CircuitGroup.CS.RegisterFile.Entries[i].Content.ToString("X8") + ",");
             * }
             * System.IO.File.AppendAllText(@"E:\cycle.txt", sb.ToString() + "\r\n");
             */
            return(true);
        }
        public override bool StepCycle()
        {
            if (IsHalted)
            {
                return(true);
            }

            string debugInfo;

            MessageManager.ShowLine($"-Cycle.{ this.CycleCount.ToString().PadLeft(8,' ') } -------------------------------------------", enumMessageLevel.ExecutionLog);
            MessageManager.GoInnerTab();
            MessageManager.Show($"PC: 0x{ ProgramCounter.ToString("X8") }", enumMessageLevel.ExecutionLog);
            Memory.GetDebugInfo(ProgramCounter / 4, out debugInfo, 4, (int)(ProgramCounter % 4));
            MessageManager.Show($" ・・・ \"{ debugInfo }\"", enumMessageLevel.ExecutionLog);
            MessageManager.ShowLine($"", enumMessageLevel.ExecutionLog);

            RegisterEntrys[RegisterNum_PC]    = ProgramCounter + 2;
            RegisterEntrys[RegisterNum_Z]     = 0;
            RegisterEntrys[RegisterNum_DEC]   = 1;
            RegisterEntrys[RegisterNum_INC]   = 0xFFFFFFFF;
            RegisterEntrys[RegisterNum_NFOUR] = 1u + ~4u;
            RegisterEntrys[RegisterNum_WIDTH] = 32;

            //Fetch
            uint instr;
            { //Left instruction
                if (!Memory.LoadWord(ProgramCounter / 4, out instr, EnumMemorymAccessType.Instruction, 2, ((int)ProgramCounter / 2) % 2))
                {
                    MessageManager.GoOuterTab();
                    return(false);
                }
                Memory.CountExecuteWord(ProgramCounter / 4, 2, ((int)ProgramCounter / 2) % 2);

                if (ProgramCounter % 4 == 0)
                {
                    instr = (instr >> 16) & 0xFFFF;
                }
                else
                {
                    instr = instr & 0xFFFF;
                }
            }

            //Decode
            byte opcode = (byte)((instr >> 14) & 0x3);
            bool jumpFlag = ((instr >> 13) & 0x1) != 0;
            uint op0, op1, op2;

            op0 = ((instr >> 9) & 0xF);
            op1 = ((instr >> 4) & 0x1F);
            op2 = (instr & 0xF);
            int offset0 = (int)(((op0 >> 3) & 1) != 0 ? (0xFFFFFFF0 | op0) : op0);

            op0 = (uint)OperandAIndexTable[op0];
            op1 = (uint)OperandBIndexTable[op1];
            op2 = (uint)OperandCIndexTable[op2];
            if ((int)op0 < 0 || (int)op1 < 0 || (int)op2 < 0)
            {
                MessageManager.ShowLine($"op0={(int)op0},op1={(int)op1},op2={(int)op2}", enumMessageLevel.ExecutionLog);

                MessageManager.GoOuterTab();
                return(false);
            }

            //Branch
            bool branchCond       = false;
            bool branchNotDelayed = false;
            uint branchAddress    = 0;

            if (opcode < 2 && jumpFlag)
            {
                uint jumpAttr;
                { //Fetch
                    uint jumpAttrByteAddr = ProgramCounter + 2;
                    if (!Memory.LoadWord(jumpAttrByteAddr / 4, out jumpAttr, EnumMemorymAccessType.Instruction, 2, ((int)jumpAttrByteAddr / 2) % 2))
                    {
                        MessageManager.GoOuterTab();
                        return(false);
                    }

                    if (jumpAttrByteAddr % 4 == 0)
                    {
                        jumpAttr = (jumpAttr >> 16) & 0xFFFF;
                    }
                    else
                    {
                        jumpAttr = jumpAttr & 0xFFFF;
                    }
                }

                byte condFlag   = (byte)((jumpAttr >> 12) & 0x7);
                byte regFlag    = (byte)((jumpAttr >> 15) & 0x1);
                uint targetAddr = (uint)(jumpAttr & 0x00000FFF) | ((jumpAttr & 0x000000800) != 0 ? 0xFFFFF000 : 0);
                branchAddress = ProgramCounter + 2 + targetAddr * 2; //((opcode < 2 && jumpFlag) ? 2u : 0u) +
                {                                                    //Determine
                    switch (condFlag)
                    {
                    case 1:     //carry
                        ulong brtmp1 = (ulong)RegisterEntrys[op1] - (ulong)RegisterEntrys[op0];
                        branchCond = (brtmp1 & 0x100000000) == 0;
                        break;

                    case 2:     //lsb
                        branchCond = ((RegisterEntrys[op1] & RegisterEntrys[op0]) & 0x1) == 0;
                        break;

                    case 4:     //neg
                        branchCond = (int)(RegisterEntrys[op1] - RegisterEntrys[op0]) < 0;
                        break;

                    default:

                        break;
                    }
                }
            }

            //Wriite
            switch (opcode)
            {
            case 0:     //Sub
            {
                uint writeValue = RegisterEntrys[op1] - RegisterEntrys[op0];
                MessageManager.ShowLine($"${ConvertRegisterNum(op2).PadRight(2)}  <=  {((int)RegisterEntrys[op1]).ToString()} (${ConvertRegisterNum(op1)})  -  {((int)RegisterEntrys[op0]).ToString()} (${ConvertRegisterNum(op0)})", enumMessageLevel.ExecutionLog);
                MessageManager.ShowLine($"      =  { ((int)writeValue).ToString() } = 0x{ writeValue.ToString("X8") }", enumMessageLevel.ExecutionLog);

                RegisterEntrys[op2] = writeValue;
            }
            break;

            case 1:     //Xan
            {
                uint writeValue = RegisterEntrys[op1] & RegisterEntrys[op0];

                /*
                 *                  (((RegisterEntrys[op1] & RegisterEntrys[op0]) >> 1) & 0x7FFFFFFF) |
                 *                    (RegisterEntrys[op1] < RegisterEntrys[op0] ? 0x80000000 : 0);
                 */
                MessageManager.ShowLine($"${ConvertRegisterNum(op2).PadRight(2)}  <=  [31]: {((int)RegisterEntrys[op1]).ToString()} (${ConvertRegisterNum(op1)})  <  {((int)RegisterEntrys[op0]).ToString() } (${ConvertRegisterNum(op0)})", enumMessageLevel.ExecutionLog);
                MessageManager.ShowLine($"        [30-0]: { RegisterEntrys[op1].ToString()} (${ConvertRegisterNum(op1)})  -  {RegisterEntrys[op0].ToString()} (${ConvertRegisterNum(op0)})", enumMessageLevel.ExecutionLog);
                MessageManager.ShowLine($"      =  { ((int)writeValue).ToString() } = 0x{ writeValue.ToString("X8") }", enumMessageLevel.ExecutionLog);

                RegisterEntrys[op2] = writeValue;
            }
            break;

            case 3:     //Shift
            {
                uint writeValue = (RegisterEntrys[op0]) >> 8;

                MessageManager.ShowLine($"${ConvertRegisterNum(op2).PadRight(2)}  <=  {((int)RegisterEntrys[op1]).ToString()} (${ConvertRegisterNum(op1)}) >> 8", enumMessageLevel.ExecutionLog);
                MessageManager.ShowLine($"      =  { ((int)writeValue).ToString() } = 0x{ writeValue.ToString("X8") }", enumMessageLevel.ExecutionLog);

                RegisterEntrys[op2] = writeValue;
            }
            break;

            case 2:     //Mr,Mw (by jump flag)
                branchCond       = false;
                branchNotDelayed = true;
                if (!jumpFlag)
                {     //Mr
                    uint mem;
                    if (!Memory.LoadWord((uint)(RegisterEntrys[op1] - offset0 * 2) / 4, out mem, EnumMemorymAccessType.Data, 1, 0))
                    {
                        MessageManager.GoOuterTab();
                        return(false);
                    }

                    MessageManager.ShowLine($"${ConvertRegisterNum(op2).PadRight(2)}  <=  MEM[0x{RegisterEntrys[op1].ToString("X8")}(${ConvertRegisterNum(op1)}) - ({offset0*2})]", enumMessageLevel.ExecutionLog);
                    MessageManager.ShowLine($"      =  MEM[0x{((RegisterEntrys[op1] - offset0 * 2)).ToString("X8")}]", enumMessageLevel.ExecutionLog);
                    MessageManager.ShowLine($"      = {mem} = 0x{mem.ToString("X8")}", enumMessageLevel.ExecutionLog);

                    RegisterEntrys[op2] = mem;

                    if (op1 == RegisterNum_PC)     //PC Relative
                    {
                        branchCond    = true;
                        branchAddress = (ProgramCounter & 0xFFFFFFFC) + 8;
                    }
                }
                else
                {     //Mw
                    /*if ((uint)(RegisterEntrys[op1] - offset0 * 2) / 4 >= 34 &&
                     *  (uint)(RegisterEntrys[op1] - offset0 * 2) / 4 <= 34 + 4)
                     * {
                     *  MessageManager.ShowLine($"-Cycle.{ this.CycleCount.ToString().PadLeft(8, ' ') } -------------------------------------------", enumMessageLevel.ProgressLog);
                     *  MessageManager.ShowLine($"MEM[0x{RegisterEntrys[op1].ToString("X8")}(${ConvertRegisterNum(op1)})-({offset0 * 2}) = 0x{(RegisterEntrys[op1] - offset0 * 2).ToString("X8")}]", enumMessageLevel.ProgressLog);
                     *  MessageManager.ShowLine($"                <= ${ConvertRegisterNum(op2)}", enumMessageLevel.ProgressLog);
                     *  MessageManager.ShowLine($"                 = {RegisterEntrys[op2]} (0x{RegisterEntrys[op2].ToString("X8")})", enumMessageLevel.ProgressLog);
                     * }*/
                    if (!Memory.StoreWord((uint)(RegisterEntrys[op1] - offset0 * 2) / 4, RegisterEntrys[op2], 1, 0))
                    {
                        MessageManager.GoOuterTab();
                        return(false);
                    }

                    MessageManager.ShowLine($"MEM[0x{RegisterEntrys[op1].ToString("X8")}(${ConvertRegisterNum(op1)})-({offset0 * 2}) = 0x{(RegisterEntrys[op1] - offset0 * 2).ToString("X8")}]", enumMessageLevel.ExecutionLog);
                    MessageManager.ShowLine($"                <= ${ConvertRegisterNum(op2)}", enumMessageLevel.ExecutionLog);
                    MessageManager.ShowLine($"                 = {RegisterEntrys[op2]} (0x{RegisterEntrys[op2].ToString("X8")})", enumMessageLevel.ExecutionLog);
                }
                break;
            }

            //Branch
            if (branchCond)
            {
                MessageManager.ShowLine($"Jump Happen to 0x{branchAddress.ToString("X8")}", enumMessageLevel.ExecutionLog);

                if (DelayBranchEnabled && !branchNotDelayed)
                {
                    BranchHappened  = DelayBranchEnabled;
                    BranchTarget    = branchAddress;
                    ProgramCounter += (opcode < 2 && jumpFlag) ? 4u : 2u;
                }
                else
                {
                    ProgramCounter = branchAddress;
                }
            }
            else
            {
                if (DelayBranchEnabled && BranchHappened)
                {
                    ProgramCounter = BranchTarget;
                    BranchHappened = false;
                }
                else
                {
                    ProgramCounter += (opcode < 2 && jumpFlag) ? 4u : 2u;
                }
            }
            MessageManager.GoOuterTab();

            if ((!DelayBranchEnabled && this.ProgramCounter == this.PrevProgramCounter) ||
                (DelayBranchEnabled && this.ProgramCounter == this.PrevPrevProgramCounter))
            {
                MessageManager.ShowLine($"S Y S T E M  H A L T", enumMessageLevel.ExecutionLog);
                base.IsHalted = true;
            }
            this.PrevPrevProgramCounter = this.PrevProgramCounter;
            this.PrevProgramCounter     = this.ProgramCounter;

            CycleCount++;
            MarkExecutionTraceData((int)ProgramCounter / 2, (long)CycleCount);
            StackPointerMin = Math.Min(StackPointerMin, RegisterEntrys[1]);

            /*
             * StringBuilder sb = new StringBuilder();
             * for (int i = 0; i < 16; i++)
             * {
             *  sb.Append(RegisterEntrys[i].ToString("X8") + ",");
             * }
             * System.IO.File.AppendAllText(@"E:\instr.txt", sb.ToString() + "\r\n");
             */
            return(true);
        }
示例#3
0
        public override bool StepCycle()
        {
            if (IsHalted)
            {
                return(false);
            }

            string debugInfo;

            MessageManager.ShowLine($"-Cycle.{ this.CycleCount.ToString().PadLeft(8,' ') } -------------------------------------------", enumMessageLevel.ExecutionLog);
            MessageManager.GoInnerTab();
            MessageManager.Show($"PC: 0x{ ProgramCounter.ToString("X8") }", enumMessageLevel.ExecutionLog);
            Memory.GetDebugInfo(ProgramCounter, out debugInfo);
            MessageManager.Show($" ・・・ \"{ debugInfo }\"", enumMessageLevel.ExecutionLog);
            MessageManager.ShowLine($"", enumMessageLevel.ExecutionLog);

            //Fetch
            uint opA, opB, opC, opD;

            if (!Memory.LoadWord(ProgramCounter + 0, out opA, EnumMemorymAccessType.Instruction) ||
                !Memory.LoadWord(ProgramCounter + 1, out opB, EnumMemorymAccessType.Instruction) ||
                !Memory.LoadWord(ProgramCounter + 2, out opC, EnumMemorymAccessType.Instruction) ||
                !Memory.LoadWord(ProgramCounter + 3, out opD, EnumMemorymAccessType.Instruction))
            {
                MessageManager.GoOuterTab();
                return(false);
            }

            //Read
            uint memOpA, memOpB;

            if (!Memory.LoadWord(opA, out memOpA, EnumMemorymAccessType.Data) ||
                !Memory.LoadWord(opB, out memOpB, EnumMemorymAccessType.Data))
            {
                MessageManager.GoOuterTab();
                return(false);
            }

            //Alu
            bool opcode = (opD & 0x80000000) != 0;

            if (!opcode)
            {
                uint writeValue;
                bool branchCondition;
                Subneg4X.Alu.ComputeSubneg(memOpA, memOpB, out writeValue, out branchCondition);
                MessageManager.ShowLine($"Mem[0x{opC.ToString("X8")}]  <=  {((int)memOpB).ToString()} (Mem[0x{ opB.ToString("X8") }])  -  {((int)memOpA).ToString() } (Mem[0x{ opA.ToString("X8") }])", enumMessageLevel.ExecutionLog);
                MessageManager.ShowLine($"                  =  { ((int)writeValue).ToString() } = 0x{ writeValue.ToString("X8") }", enumMessageLevel.ExecutionLog);

                //Write
                if (!Memory.StoreWord(opC, writeValue))
                {
                    MessageManager.GoOuterTab();
                    return(false);
                }
                if (opC >= 261 && opC <= 261 + 4)
                {
                    MessageManager.ShowLine($"-Cycle.{ this.CycleCount.ToString().PadLeft(8, ' ') } -------------------------------------------", enumMessageLevel.ExecutionLog);
                    MessageManager.ShowLine($"Mem[0x{opC.ToString("X8")}]  <=  {((int)memOpB).ToString()} (Mem[0x{ opB.ToString("X8") }])  -  {((int)memOpA).ToString() } (Mem[0x{ opA.ToString("X8") }])", enumMessageLevel.ExecutionLog);
                    MessageManager.ShowLine($"                  =  { ((int)writeValue).ToString() } = 0x{ writeValue.ToString("X8") }", enumMessageLevel.ExecutionLog);
                }

                //Branch
                uint branchTarget = opD & 0x7FFFFFFF;
                if (branchCondition && branchTarget != this.ProgramCounter + 4)
                {
                    MessageManager.ShowLine($"Jump to 0x{ (opD & 0x7FFFFFFF).ToString("X8") }", enumMessageLevel.ExecutionLog);

                    this.ProgramCounter = branchTarget;
                }
                else
                {
                    this.ProgramCounter += 4;
                }
            }
            else
            {
                uint writeValue;
                bool branchCondition;
                Subneg4X.Alu.ComputeSubnegX(memOpA, memOpB, out writeValue, out branchCondition);
                MessageManager.ShowLine($"Mem[0x{opC.ToString("X8")}]  <=  [31]: {((int)memOpB).ToString()} (Mem[0x{ opB.ToString("X8") }]  <  {((int)memOpA).ToString() } (Mem[0x{ opA.ToString("X8") }])", enumMessageLevel.ExecutionLog);
                MessageManager.ShowLine($"                  [30-0]: { memOpB.ToString()} (Mem[0x{ opB.ToString("X8") }])  -  {memOpA.ToString() } (Mem[0x{ opA.ToString("X8") }])", enumMessageLevel.ExecutionLog);
                MessageManager.ShowLine($"                  =  { ((int)writeValue).ToString() } = 0x{ writeValue.ToString("X8") }", enumMessageLevel.ExecutionLog);


                //Write
                if (!Memory.StoreWord(opC, writeValue))
                {
                    MessageManager.GoOuterTab();
                    return(false);
                }

                //Branch
                uint branchTarget = opD & 0x7FFFFFFF;
                if (branchCondition && branchTarget != this.ProgramCounter + 4)
                {
                    MessageManager.ShowLine($"Jump to 0x{ (opD & 0x7FFFFFFF).ToString("X8") }", enumMessageLevel.ExecutionLog);

                    this.ProgramCounter = branchTarget;
                }
                else
                {
                    this.ProgramCounter += 4;
                }
            }

            MessageManager.GoOuterTab();

            if (this.ProgramCounter >= HaltAddress)
            {
                MessageManager.ShowLine($"S Y S T E M  H A L T", enumMessageLevel.ExecutionLog);
                base.IsHalted = true;
            }

            CycleCount++;
            MarkExecutionTraceData((int)ProgramCounter * 2, (long)CycleCount);

            return(true);
        }
        public override bool StepCycle()
        {
            if (IsHalted)
            {
                return(true);
            }

            string debugInfo;

            MessageManager.ShowLine($"-Cycle.{ this.CycleCount.ToString().PadLeft(8,' ') } -------------------------------------------", enumMessageLevel.ExecutionLog);
            MessageManager.GoInnerTab();
            MessageManager.Show($"PC: 0x{ CircuitGroup.ProgramCounter.Value.ToString("X8") }", enumMessageLevel.ExecutionLog);
            Memory.GetDebugInfo(CircuitGroup.ProgramCounter.Value, out debugInfo);
            MessageManager.Show($" ・・・ \"{ debugInfo }\"", enumMessageLevel.ExecutionLog);
            MessageManager.ShowLine($"", enumMessageLevel.ExecutionLog);
            {
                MessageManager.ShowLine("[Status]", enumMessageLevel.ExecutionLog);
                MessageManager.GoInnerTab();
                MessageManager.Show($"Stage = { CircuitGroup.State.Value.ToString() }", enumMessageLevel.ExecutionLog);
                switch (CircuitGroup.State.Value)
                {
                case -1:
                    MessageManager.ShowLine($" : RST,Issuing read PC+0 / PC+1 address", enumMessageLevel.ExecutionLog);
                    break;

                case 0:
                    MessageManager.ShowLine($" : Issuing read MEM[PC+0] / MEM[PC+1] address", enumMessageLevel.ExecutionLog);
                    break;

                case 1:
                    MessageManager.ShowLine($" : Saving to MemOpA / MemOpB,Issuing read PC+2 / PC+3 address", enumMessageLevel.ExecutionLog);
                    break;

                case 2:
                    MessageManager.ShowLine($" : Writing ALU to MEM[PC+2] address,Issuing read PC+3 address", enumMessageLevel.ExecutionLog);
                    break;

                case 3:
                    MessageManager.ShowLine($" : Branching,Issuing read NewPC+0 / NewPC+1 address", enumMessageLevel.ExecutionLog);
                    break;
                }
                MessageManager.ShowLine($"Mem[OperandA] = { ((int)CircuitGroup.MemOpA.Value).ToString() },Mem[OperandB] = { ((int)CircuitGroup.MemOpB.Value).ToString() }", enumMessageLevel.ExecutionDetailLog);
                MessageManager.GoOuterTab();

                MessageManager.ShowLine("[ALU]", enumMessageLevel.ExecutionDetailLog);
                MessageManager.GoInnerTab();
                MessageManager.ShowLine($"Result = { ((int)CircuitGroup.Alu.AluResult_OFace.Value).ToString() },BranchCond = { CircuitGroup.Alu.BranchCond_OFace.Value.ToString() }", enumMessageLevel.ExecutionDetailLog);
                MessageManager.GoOuterTab();

                MessageManager.ShowLine("[RAM]", enumMessageLevel.ExecutionLog);
                MessageManager.GoInnerTab();
                if (CircuitGroup.SyncMemory.ReadCmd1_IFace.SourceFace.Value.Enabled)
                {
                    MessageManager.ShowLine($"ReadCmd1.{{ Addr=0x{CircuitGroup.SyncMemory.ReadCmd1_IFace.SourceFace.Value.Address.ToString("X8")} }}", enumMessageLevel.ExecutionLog);
                }
                if (CircuitGroup.SyncMemory.ReadCmd2_IFace.SourceFace.Value.Enabled)
                {
                    MessageManager.ShowLine($"ReadCmd2.{{ Addr=0x{CircuitGroup.SyncMemory.ReadCmd2_IFace.SourceFace.Value.Address.ToString("X8")} }}", enumMessageLevel.ExecutionLog);
                }
                if (CircuitGroup.SyncMemory.WriteCmd_IFace.SourceFace.Value.Enabled)
                {
                    MessageManager.ShowLine($"WriteCmd.{{ Addr=0x{CircuitGroup.SyncMemory.WriteCmd_IFace.SourceFace.Value.Address.ToString("X8")},Value={(int)CircuitGroup.SyncMemory.WriteCmd_IFace.SourceFace.Value.Value} (0x{CircuitGroup.SyncMemory.WriteCmd_IFace.SourceFace.Value.Value.ToString("X8")}) }}", enumMessageLevel.ExecutionLog);
                }
                MessageManager.ShowLine($"ReadOut1 = {(int)CircuitGroup.SyncMemory.ReadValue1_OFace.Value} (0x{CircuitGroup.SyncMemory.ReadValue1_OFace.Value.ToString("X8")}),ReadOut2 = {(int)CircuitGroup.SyncMemory.ReadValue2_OFace.Value} (0x{CircuitGroup.SyncMemory.ReadValue2_OFace.Value.ToString("X8")})", enumMessageLevel.ExecutionLog);
                MessageManager.GoOuterTab();
            }
            MessageManager.GoOuterTab();

            CircuitGroup.UpdateCycle();

            if (this.CircuitGroup.ProgramCounterInput.Value == HaltAddress)
            {
                MessageManager.ShowLine($"S Y S T E M  H A L T", enumMessageLevel.ExecutionLog);
                IsHalted = true;
            }

            this.CycleCount++;
            MarkExecutionTraceData((int)CircuitGroup.ProgramCounter.Value * 2, (long)CycleCount);

            return(true);
        }