private void StartMachineCycle(MachineCycle machineCycle) { machineCycleCounter++; currentMachineCycle = machineCycle; DecodeMachineCycleExecutionMethod(); }
private void EndMachineCycle() { currentMachineCycle = null; executeMachineCycle = null; }
// Main entry point : logic executed on each edge of the clock signal public void CLK_OnEdge() { // Count T States if (halfTStateIndex % 2 == 0) { tStateCounter++; } // Debug interface : breakpoints management ExitConditionException pendingExitException = null; // Start a new instruction if no instruction is currently in progress if (currentInstruction == null) { // If RESET Pin is active, execute a special reset "instruction" if (RESET == SignalState.LOW) { ResetCPUControlState(); StartInstruction(Instruction.RESET); } // If a non maskable interrupt is pending, execute NMI instruction else if (nonMaskableInterruptPending) { nonMaskableInterruptPending = false; StartInstruction(Instruction.NMI); } // If a maskable interrupt is pending, execute INT instruction else if (maskableInterruptPending) { maskableInterruptPending = false; switch (IM) { case 0: StartInstruction(Instruction.INT0); break; case 1: StartInstruction(Instruction.INT1); break; case 2: StartInstruction(Instruction.INT2); break; } } // If no external CPU control Pin is active, read the next instruction opcode in memory else { StartInstruction(Instruction.FetchNewInstruction); } // Debug notification if (pendingExitException == null) { pendingExitException = NotifyLifecycleEvent(LifecycleEventType.InstructionStart); } } // Start a new machine cycle if no machine cycle is currently in progress if (currentMachineCycle == null) { // If a Bus Request is pending, start a special Bus Request Acknowledge machine cycle if (busRequestPending) { busRequestPending = false; StartMachineCycle(MachineCycle.BusRequestAcknowledge); } // The following machine cycles are defined by the documentation of the current instruction else { MachineCycle nextMachineCycle = currentInstruction.ExecutionTimings.MachineCycles[machineCycleIndex]; StartMachineCycle(nextMachineCycle); } // Debug notification if (pendingExitException == null) { pendingExitException = NotifyLifecycleEvent(LifecycleEventType.MachineCycleStart); } } // Execute the current machine cycle logic during one halfTState executeMachineCycle(halfTStateIndex); // Check if the current machine cycle was a bus request bool machineCycleWasBusRequest = currentMachineCycle.Type == MachineCycleType.BRQA; // Check if this halfTState is the rising edge of the last clock period of this machine cycle bool isRisingEdgeOfLastClockPeriodOfCurrentMachineCycle = (halfTStateIndex == currentMachineCycle.PenultimateHalfTStateIndex); // Check if this halfTState is the last one for the current machine cycle bool isLastHalfTStateOfCurrentMachineCycle = (halfTStateIndex == currentMachineCycle.LastHalfTStateIndex); // Check if the current machine cycle was the last machine cycle of the instruction bool isLastMachineCycleOfCurrentInstruction = !machineCycleWasBusRequest && (machineCycleIndex == currentInstruction.LastMachineCycleIndex); // Sample BUSREQ, NMI, and INT signals at the rising edge of the last clock period of any machine cycle if (isRisingEdgeOfLastClockPeriodOfCurrentMachineCycle) { SampleBusControlSignals(); if (isLastMachineCycleOfCurrentInstruction) { SampleInterruptControlSignals(); } } // Debug notification if (pendingExitException == null) { pendingExitException = NotifyLifecycleEvent(LifecycleEventType.HalfTState); } // If machine cycle is finished if (isLastHalfTStateOfCurrentMachineCycle) { // Execute one last time the machine cycle logic // to release buses and controls signals before the next machine cycle executeMachineCycle((byte)(halfTStateIndex + 1)); // Debug notification if (pendingExitException == null) { pendingExitException = NotifyLifecycleEvent(LifecycleEventType.MachineCycleEnd); } EndMachineCycle(); } // If instruction is finished if (isLastMachineCycleOfCurrentInstruction && isLastHalfTStateOfCurrentMachineCycle) { // Debug notification if (pendingExitException == null) { pendingExitException = NotifyLifecycleEvent(LifecycleEventType.InstructionEnd); } EndInstruction(); } // Count half T states whithin one machine cycle if (isLastHalfTStateOfCurrentMachineCycle) { halfTStateIndex = 0; } else { halfTStateIndex++; } // Count machine cycles within one instruction if (isLastHalfTStateOfCurrentMachineCycle) { if (isLastMachineCycleOfCurrentInstruction) { machineCycleIndex = 0; machineCycleCountAfterInstruction = 0; } else { if (!machineCycleWasBusRequest) // Bus request "steals" machine cycles from the instruction { machineCycleIndex++; if (currentInstruction != Instruction.FetchNewInstruction) // Incremented only after instruction decoding { machineCycleCountAfterInstruction++; } } } } // Debug : if a breakpoint was hit, notify the system clock via a specific exception if (pendingExitException != null) { throw pendingExitException; } }