コード例 #1
0
        private void StartMachineCycle(MachineCycle machineCycle)
        {
            machineCycleCounter++;

            currentMachineCycle = machineCycle;
            DecodeMachineCycleExecutionMethod();
        }
コード例 #2
0
 private void EndMachineCycle()
 {
     currentMachineCycle = null;
     executeMachineCycle = null;
 }
コード例 #3
0
        // 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;
            }
        }