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); }