public TestMemory(int capacityBytes, int waitCycles)
            : base(capacityBytes)
        {
            this.waitCycles = waitCycles;

            _wait = SignalState.HIGH;
        }
示例#2
0
        public void DiDevice_WhenConnected_IsCorrect()
        {
            // Arrange
            SignalState actual   = SignalState.Complete;
            SignalState expected = DateTime.Now.Second / 30 == 0 ?
                                   SignalState.Start : SignalState.Complete;

            _manager.Initial();
            _manager.DigitalInputReceived += (object sender, DaqControlEventArgs e) =>
            {
                if (e.Name == "DemoTemperature")    // only TemperatureDemo
                {
                    actual = e.State;
                }
                else
                {
                    SignalState temp = e.State;
                }
            };

            // Act
            _manager.Connect();
            System.Threading.Thread.Sleep(1200);

            // Assert
            Assert.Equal(expected, actual);
        }
示例#3
0
 public EventData(SignalState state, int mouseX, int mouseY, int scroll)
 {
     this.State            = state;
     this.MouseX           = mouseX;
     this.MouseY           = mouseY;
     this.ScrollWheelValue = scroll;
 }
示例#4
0
 private void EnterState(SignalState newState)
 {
     if (newState == state)
         return;
     state = newState;
     Invalidate();
 }
示例#5
0
        private void DrawSignal(ICanvas canvas, SignalState state)
        {
            const int HousingY = SignalHeight / 2 - SignalLightHousingHeight / 2;

            using (canvas.Scope())
            {
                canvas.Translate(-2 * SignalLightHousingWidth, 0);

                // Light
                using (canvas.Scope())
                {
                    canvas.Translate(SignalLightHousingWidth, SignalHeight / 2);

                    var signalColor = state switch
                    {
                        SignalState.Stop => s_signalLightRed,
                        SignalState.TemporaryStop => s_signalLightAmber,
                        _ => s_signalLightGreen
                    };

                    canvas.DrawPath(_lightPath, signalColor);
                }

                // Housing
                canvas.DrawRect(0, HousingY, SignalLightHousingWidth, SignalLightHousingHeight, s_signalBodyPaint);

                // Body
                canvas.DrawRect(SignalLightHousingWidth, 0, SignalWidth, SignalHeight, s_signalBodyPaint);
            }
        }
    }
示例#6
0
        public SignalState Read(DateTime time)
        {
            SignalState signal = SignalState.NoSignal;

            if (signalIndex.ContainsKey(time))
            {
                int signalPosition = signalIndex[time];

                //Check if position is Closed
                if (dataFrameItems[signalPosition].Position == PositionMode.Closed)
                {
                    //Check for reversal
                    int nextPosition = signalPosition + 1;
                    if (nextPosition < dataFrameItems.Length && dataFrameItems[nextPosition].ClosingBarTime == time)
                    {
                        if (dataFrameItems[nextPosition].Position == PositionMode.Long)
                        {
                            signal = SignalState.LongReversal;
                        }
                        else if (dataFrameItems[nextPosition].Position == PositionMode.Short)
                        {
                            signal = SignalState.ShortReversal;
                        }
                    }
                }
                else
                {
                    signal = dataFrameItems[signalPosition].Position == PositionMode.Long ? SignalState.Long : SignalState.Short;
                }
            }
            return(signal);
        }
示例#7
0
        /// <summary>
        /// Power On
        /// </summary>
        public ULA()
        {
            _cpuCLK = SignalState.LOW;
            _cpuINT = SignalState.HIGH;

            Address = new BusConnector <ushort>();
            Data    = new BusConnector <byte>();

            VideoAddress = new BusConnector <ushort>();
            VideoData    = new BusConnector <byte>();

            _videoMREQ = SignalState.HIGH;
            _videoRD   = SignalState.HIGH;

            ColorSignal = new AnalogOutputPin <byte>(0);
            _hSync      = SignalState.HIGH;
            _vSync      = SignalState.HIGH;

            KeyboardData = new BusConnector <byte>();
            _keyboardRD  = SignalState.HIGH;

            SpeakerSoundSignal = new AnalogOutputPin <byte>(0);
            _soundSampleCLK    = SignalState.HIGH;

            TapeInputSignal = new AnalogInputPin <byte>();
            TapeOuputSignal = new AnalogOutputPin <byte>(0);
        }
        public TestMemory(int capacityBytes, int waitCycles)
            : base(capacityBytes)
        {
            this.waitCycles = waitCycles;

            _wait = SignalState.HIGH;
        }
 public void DistributeSignal(SignalState state)
 {
     foreach (var comp in Owner.GetAllComponents <ISignalReceiver>())
     {
         comp.TriggerSignal(state);
     }
 }
示例#10
0
        public Clock(long frequencyHerz)
        {
            SimulatedFrequencyHerz = frequencyHerz;
            SimulatedPeriodNanoseconds = 1000000000L/frequencyHerz;

            SignalState beforeInitialState = SignalState.LOW;
            _clk = beforeInitialState;
        }
示例#11
0
        public TestDevice(byte portAddress, byte initialValue, int waitCycles) : base(portAddress)
        {
            this.waitCycles = waitCycles;

            _wait = SignalState.HIGH;

            internalValue = initialValue;
        }
        public TestInterruptingDevice(byte portAddress, byte initialValue, int waitCycles, int[][] startInterruptAfterTStatesAndDuringTStates, byte valueForDataBusAfterInterrupt)
            : base(portAddress, initialValue, waitCycles)
        {
            _int = SignalState.HIGH;

            this.startInterruptAfterTStatesAndDuringTStates = startInterruptAfterTStatesAndDuringTStates;
            this.valueForDataBusAfterInterrupt = valueForDataBusAfterInterrupt;
        }
示例#13
0
 public WaitForSignalsEvent(HistoryEvent @event, IEnumerable <HistoryEvent> allEvents)
     : base(@event)
 {
     _data        = @event.MarkerRecordedEventAttributes.Details.As <WaitForSignalData>();
     ScheduleId   = ScheduleId.Raw(_data.ScheduleId);
     _signalState = new WaitingForSignalState(this);
     PopulateResumedSignals(allEvents);
 }
示例#14
0
        protected void SignalOne(SignalState signalStateIfNoWaiters)
        {
            // Single a waiting thread and put it in the deferredWakeupQueue
            ThreadQueueStruct deferredWakeupQueue = SignalOneWithNoWakeup(signalStateIfNoWaiters);

            // Wakeup a waiter if we need to
            WakeupOneWaiter(deferredWakeupQueue);
        }
        public TestInterruptingDevice(byte portAddress, byte initialValue, int waitCycles, int[][] startInterruptAfterTStatesAndDuringTStates, byte valueForDataBusAfterInterrupt)
            : base(portAddress, initialValue, waitCycles)
        {
            _int = SignalState.HIGH;

            this.startInterruptAfterTStatesAndDuringTStates = startInterruptAfterTStatesAndDuringTStates;
            this.valueForDataBusAfterInterrupt = valueForDataBusAfterInterrupt;
        }
        public TestDevice(byte portAddress, byte initialValue, int waitCycles)
            : base(portAddress)
        {
            this.waitCycles = waitCycles;

            _wait = SignalState.HIGH;

            internalValue = initialValue;
        }
示例#17
0
        public Clock(long frequencyHerz)
        {
            SimulatedFrequencyHerz     = frequencyHerz;
            SimulatedPeriodNanoseconds = 1000000000L / frequencyHerz;

            SignalState beforeInitialState = SignalState.LOW;

            _clk = beforeInitialState;
        }
示例#18
0
 public void Reset()
 {
     InputBuffer.Clear();
     state = SignalState.NotDetected;
     fadeCount = 0;
     firstDetectedFrame = false;
     Invalidate();
     sw.Close();
     sw = new StreamWriter("signal_detector.txt");
 }
 public void Push()
 {
     if (releasedState == SignalState.HIGH)
     {
         Output = SignalState.LOW;
     }
     else
     {
         Output = SignalState.HIGH;
     }
 }
示例#20
0
 ///
 /// <summary>
 /// Constructor
 /// </summary>
 ///
 /// <param name="initialState">Initial state of an handle </param>
 /// <param name="signalStateAfterImediateWait">
 ///    Value represents a state of a handle when wait satisfied right a way
 /// </param>
 ///
 protected WaitHandleBase(
     SignalState initialState,
     SignalState signalStateAfterImediateWait)
 {
     this.id            = ++idGenerator;
     this.owner         = null;
     this.signaledQueue = new ThreadQueue(this);
     this.waitingQueue  = new ThreadQueue(this);
     this.signaled      = initialState;
     this.signalStateAfterImediateWait = signalStateAfterImediateWait;
 }
示例#21
0
 public void Push()
 {
     if (releasedState == SignalState.HIGH)
     {
         Output = SignalState.LOW;
     }
     else
     {
         Output = SignalState.HIGH;
     }
 }
示例#22
0
 ///
 /// <summary>
 /// Constructor
 /// </summary>
 ///
 /// <param name="initialState">Initial state of an handle </param>
 /// <param name="signalStateAfterImediateWait">
 ///  Value represents a state of a handle when wait satisfied right a way
 /// </param>
 /// <param name="spinLockType">The spin lock type of the wait handle</param>
 ///
 protected WaitHandle(
     SignalState initialState,
     SignalState signalStateAfterImediateWait,
     SpinLock.Types spinLockType)
     : base(initialState, signalStateAfterImediateWait)
 {
     this.singleHandle = new WaitHandle[1] {
         this
     };
     // Initialize waithandle spinlock
     this.myLock = new SpinLock(spinLockType);
 }
示例#23
0
        protected void SignalAll(
            SignalState signalStateIfNoWaiters,
            SignalState signalStateIfWaiters)
        {
            // Single the waiting threads and put them in the deferredWakeupQueue
            ThreadQueueStruct deferredWakeupQueue = SignalAllWithNoWakeup(
                signalStateIfNoWaiters,
                signalStateIfWaiters);

            // Wakeup a waiter if we need to
            WakeupAllWaiters(deferredWakeupQueue);
        }
示例#24
0
        private void AddOneTStateToCurrentMachineCycleIfSignalLow(SignalState signalState, string signalName)
        {
            if (signalState == SignalState.LOW)
            {
                // Add one more TState to the machine cycle by decreasing the halfTState counter
                this.halfTStateIndex -= 2;
            }

            if (TraceMicroInstructions)
            {
                TraceMicroInstruction(new MicroInstruction(Z80MicroInstructionTypes.CPUControlAddOneTStateIfSignalLow, signalName));
            }
        }
示例#25
0
        protected void InterruptAwareSignalOne(SignalState signalStateIfNoWaiters)
        {
            // Disable interrupt
            bool interruptFlag = Processor.DisableInterrupts();

            // Single a waiting thread and put it in the deferredWakeupQueue
            ThreadQueueStruct deferredWakeupQueue = SignalOneWithNoWakeup(signalStateIfNoWaiters);

            // Restore interrupt if necessary
            Processor.RestoreInterrupts(interruptFlag);

            // Wakeup a waiter if we need to
            WakeupOneWaiter(deferredWakeupQueue);
        }
    public void Initialise(GameObject _trafficLight)
    {
        trafficLights = new List <TrafficLight>();

        roadSection = GetComponent <RoadSection>();

        SetupIntersection(_trafficLight);

        currentLight = 0;

        signalState = SignalState.Alternate;

        delayTime   = delayTimeAlternate;
        sectionTime = sectionTimeAlternate;
    }
    private void UpdateState()
    {
        foreach (TrafficLight light in trafficLights)
        {
            if (light.IsTrafficWaiting())
            {
                signalState = SignalState.AllowTraffic;
                sectionTime = sectionTimeAllowTraffic;
                return;
            }
        }

        signalState = SignalState.Alternate;
        sectionTime = sectionTimeAlternate;
    }
示例#28
0
 public Digital_WaveformGenerator(WaveformType type, IPAddress deviceAddress, string line, bool periodic)
 {
     waveformType                 = type;
     periodicWaveform             = periodic;
     waveform                     = new SignalState[2];
     waveform[0]                  = new SignalState();
     waveform[0].state            = true;
     waveform[0].durationMicroSec = onDuration;
     waveform[1]                  = new SignalState();
     waveform[1].state            = false;
     waveform[1].durationMicroSec = offDuration;
     transitionevent              = new WaveformEventArgs();
     stateevent                   = new WaveformEventArgs();
     lastStateIdx                 = 0;
     digitalLine                  = line;
     activeTransitionCounter      = 0;
     startCounter                 = 0;
     if (waveformType == WaveformType.DigitalIO)
     {
         try
         {
             DAQTask = new Task();
             DOChannel outputChannel = DAQTask.DOChannels.CreateChannel(digitalLine, "waveform", ChannelLineGrouping.OneChannelForAllLines);
             //outputChannel.OutputDriveType = DOOutputDriveType.ActiveDrive;
             DAQTask.Start();
             writer = new DigitalSingleChannelWriter(DAQTask.Stream);
         }
         catch (DaqException ex)
         {
             MessageBox.Show(ex.Message);
             if (DAQTask != null)
             {
                 DAQTask.Dispose();
                 DAQTask = null;
             }
         }
     }
     if (waveformType == WaveformType.TCP)
     {
         Int32 hostport;
         Int32.TryParse(line, out hostport);
         tcpClientGenerator       = new ClientConnection(deviceAddress.ToString(), hostport);
         tcpClientGeneratorThread = new Thread(new ThreadStart(DoTCPConnection));
     }
     if (waveformType == WaveformType.Serial)
     {
     }
 }
示例#29
0
        /// <summary>
        /// Update signal's state
        /// </summary>
        /// <param name="state">New state to set</param>
        /// <returns>True if succeeded</returns>
        public bool SetSignalState(SignalState state)
        {
            if (state == State)
            {
                return(true);
            }

            if (state == SignalState.Stopped)
            {
                Exit(null); //will set state to Stopped
                return(true);
            }

            var oldState = State;

            switch (state)
            {
            case SignalState.Running:
                if (State == SignalState.RunningSimulated)
                {
                    State = SignalState.Running;
                }
                break;

            case SignalState.RunningSimulated:
                if (State == SignalState.Running)
                {
                    State = SignalState.RunningSimulated;
                }
                break;

            case SignalState.Backtesting:
                if (State == SignalState.BacktestingPaused)
                {
                    State = SignalState.Backtesting;
                }
                break;

            case SignalState.BacktestingPaused:
                if (State == SignalState.Backtesting)
                {
                    State = SignalState.BacktestingPaused;
                }
                break;
            }

            return(State != oldState);
        }
        public void CPUClock_OnEdgeHigh()
        {
            if (waitCountdown >= 0)
            {
                if (waitCountdown == waitCycles)
                {
                    WAIT = SignalState.LOW;
                }
                else if (waitCountdown == 0)
                {
                    WAIT = SignalState.HIGH;
                }

                waitCountdown--;
            }
        }
示例#31
0
        public void CPUClock_OnEdgeHigh()
        {
            if (waitCountdown >= 0)
            {
                if (waitCountdown == waitCycles)
                {
                    WAIT = SignalState.LOW;
                }
                else if (waitCountdown == 0)
                {
                    WAIT = SignalState.HIGH;
                }

                waitCountdown--;
            }
        }
示例#32
0
        public void TriggerSignal(SignalState state)
        {
            switch (state)
            {
            case SignalState.On:
                _on = true;
                break;

            case SignalState.Off:
                _on = false;
                break;

            case SignalState.Toggle:
                _on = !_on;
                break;
            }
            UpdateLight();
        }
示例#33
0
        private void SetSignals(SignalState signal)
        {
            int signalsCount  = Enum.GetNames(typeof(SignalState)).Length;
            var currentSignal = signal;

            while (this.signals.Count != signalsCount)
            {
                this.signals.Enqueue(currentSignal);

                var nextSignal = (int)currentSignal + 1;
                if (nextSignal == signalsCount)
                {
                    nextSignal = 0;
                }

                currentSignal = (SignalState)nextSignal;
            }
        }
示例#34
0
        public virtual void CPUClock_OnEdge()
        {
            if (waitCountdown >= 0)
            {
                if (CPUClock == SignalState.HIGH)
                {
                    if (waitCountdown == waitCycles)
                    {
                        WAIT = SignalState.LOW;
                    }
                    else if (waitCountdown == 0)
                    {
                        WAIT = SignalState.HIGH;
                    }

                    waitCountdown--;
                }
            }
        }
        public virtual void CPUClock_OnEdge()
        {
            if (waitCountdown >= 0)
            {
                if (CPUClock == SignalState.HIGH)
                {
                    if (waitCountdown == waitCycles)
                    {
                        WAIT = SignalState.LOW;
                    }
                    else if (waitCountdown == 0)
                    {
                        WAIT = SignalState.HIGH;
                    }

                    waitCountdown--;
                }
            }
        }
        public override void CPUClock_OnEdge()
        {
            base.CPUClock_OnEdge();

            foreach (int[] startAndDurationCouple in startInterruptAfterTStatesAndDuringTStates)
            {
                int startAfterTStates     = startAndDurationCouple[0];
                int activateDuringTStates = startAndDurationCouple[1];
                if (halfTStatesCounter == 2 * startAfterTStates)
                {
                    INT = SignalState.LOW;
                }
                if (halfTStatesCounter == 2 * (startAfterTStates + activateDuringTStates))
                {
                    INT = SignalState.HIGH;
                }
            }

            halfTStatesCounter++;
        }
示例#37
0
文件: Program.cs 项目: AndrewTheM/OOP
        static void Main(string[] args)
        {
            var trafficLights = new List <TrafficLight>();

            var signalNames = Console.ReadLine().Split(' ');
            int changeCount = int.Parse(Console.ReadLine());

            foreach (var name in signalNames)
            {
                try
                {
                    SignalState signal = name.ToLower() switch
                    {
                        "red" => new RedSignalState(),
                        "yellow" => new YellowSignalState(),
                        "green" => new GreenSignalState(),
                        _ => throw new Exception($"Invalid signal: {name}")
                    };

                    var trafficLight = new TrafficLight(signal);
                    trafficLights.Add(trafficLight);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }

            for (int i = 0; i < changeCount; ++i)
            {
                foreach (var tl in trafficLights)
                {
                    tl.Switch();
                    Console.Write($"{tl.State.SignalName} ");
                }

                Console.WriteLine();
            }

            Console.ReadKey();
        }
示例#38
0
        public void ExecuteHalfTState()
        {
            if (startAfterTStatesAndActivateDuringTStates != null)
            {
                foreach (int[] startAndDurationCouple in startAfterTStatesAndActivateDuringTStates)
                {
                    int startAfterTStates     = startAndDurationCouple[0];
                    int activateDuringTStates = startAndDurationCouple[1];
                    if (halfTStatesCounter == 2 * startAfterTStates)
                    {
                        CPUControlPIN = SignalState.LOW;
                    }
                    if (halfTStatesCounter == 2 * (startAfterTStates + activateDuringTStates))
                    {
                        CPUControlPIN = SignalState.HIGH;
                    }
                }

                halfTStatesCounter++;
            }
        }
示例#39
0
        /// <summary>
        /// Calls scripting inner parameters Initialization using cross-thread lock's
        /// </summary>
        /// <param name="broker">Data broker</param>
        /// <param name="selections">Data descriptions on which  code will be run</param>
        /// <param name="dataProvider">Object which provide access to historical and real time data</param>
        /// <returns>True if case of succeeded initialization</returns>
        public bool Init(IBroker broker, IDataProvider dataProvider, IEnumerable <Selection> selections,
                         SignalState state, StrategyParams strategyParameters, ISimulationBroker simulationBroker = null)
        {
            Broker           = broker;
            SimulationBroker = simulationBroker ?? new SimulationBroker(broker.AvailableAccounts, broker.Portfolios);
            DataProvider     = dataProvider;
            State            = state;
            SetStrategyParameters(strategyParameters);

            lock (_locker)
            {
                try
                {
                    return(InternalInit(selections));
                }
                catch
                {
                    return(false);
                }
            }
        }
        public void ExecuteHalfTState()
        {
            if (startAfterTStatesAndActivateDuringTStates != null)
            {
                foreach (int[] startAndDurationCouple in startAfterTStatesAndActivateDuringTStates)
                {
                    int startAfterTStates = startAndDurationCouple[0];
                    int activateDuringTStates = startAndDurationCouple[1];
                    if (halfTStatesCounter == 2 * startAfterTStates)
                    {
                        CPUControlPIN = SignalState.LOW;
                    }
                    if (halfTStatesCounter == 2 * (startAfterTStates + activateDuringTStates))
                    {
                        CPUControlPIN = SignalState.HIGH;
                    }
                }

                halfTStatesCounter++;
            }
        }
示例#41
0
        /// <summary>
        /// Power On
        /// </summary>
        public ULA()
        {
            _cpuCLK = SignalState.LOW;
            _cpuINT = SignalState.HIGH;

            Address = new BusConnector<ushort>();
            Data = new BusConnector<byte>();

            VideoAddress = new BusConnector<ushort>();
            VideoData = new BusConnector<byte>();

            _videoMREQ = SignalState.HIGH;
            _videoRD = SignalState.HIGH;

            ColorSignal = new AnalogOutputPin<byte>(0);
            _hSync = SignalState.HIGH;
            _vSync = SignalState.HIGH;

            KeyboardData = new BusConnector<byte>();
            _keyboardRD = SignalState.HIGH;

            SpeakerSoundSignal = new AnalogOutputPin<byte>(0);
            _soundSampleCLK = SignalState.HIGH;

            TapeInputSignal = new AnalogInputPin<byte>();
            TapeOuputSignal = new AnalogOutputPin<byte>(0);
        }
        private void AddOneTStateToCurrentMachineCycleIfSignalLow(SignalState signalState, string signalName)
        {
            if (signalState == SignalState.LOW)
            {
                // Add one more TState to the machine cycle by decreasing the halfTState counter
                this.halfTStateIndex -= 2;
            }

            if (TraceMicroInstructions)
            {
                TraceMicroInstruction(new MicroInstruction(Z80MicroInstructionTypes.CPUControlAddOneTStateIfSignalLow, signalName));
            }
        }
 public Button(SignalState releasedState)
 {
     this.releasedState = releasedState;
     _output = releasedState;
 }
        public TestSignal(int[][] startAfterTStatesAndActivateDuringTStates)
        {
            this.startAfterTStatesAndActivateDuringTStates = startAfterTStatesAndActivateDuringTStates;

            _cpuControlPin = SignalState.HIGH;
        }
 public void Release()
 {
     Output = releasedState;
 }
示例#46
0
        /// <summary>
        /// All ULA timing states are synchronized to this internal 7MHz clock.
        /// </summary>
        public void ExecuteOnPixelClock()
        {
            // Debug interface : breakpoints management
            ExitConditionException pendingExitException = null;

            // Video signals generation is aligned on a 16 pixels pattern
            int videoMem16StepsAccessPatternIndex = column % 16;

            // --- CPU/ULA video memory contention

            // The ULA accesses video memory from pixels 8 to 15
            // outside the border generation periods. To make sure
            // no CPU memory or IO access can overlap this period
            // we must stop any CPU memory or IO instruction starting
            // after pixel 4 and halt the CPU clock until next pixel 0.
            switch (videoMem16StepsAccessPatternIndex)
            {
                case 0:
                    videoMemAccessTimeFrame = false;
                    break;

                case 4:
                    if (!generateBorder)
                    {
                        videoMemAccessTimeFrame = true;
                    }
                    break;
            }

            if (videoMemAccessTimeFrame)
            {
                if (!haltCpuClock) // No need to check for CPU memory or IO requests while it is already halted
                {
                    if (// CPU is about to access the video memory
                        // CPU is about to access the ULA IO port
                        cpuMemoryOrIORequestHalfTState == 1)
                    {
                        haltCpuClock = true;
                    }
                }
            }
            else
            {
                if (haltCpuClock)
                {
                    haltCpuClock = false;
                }
            }

            // --- CPU interrupt
            if (line == 248)
            {
                if (column == 0 /* Offset : because of the time necessary to read the first pixels in video memory, color output begins only 13 cycles after the master counter */ + 13)
                {
                    CpuINT = SignalState.LOW;
                }
                else if (column == 32 /* Offset : because of the time necessary to read the first pixels in video memory, color output begins only 13 cycles after the master counter */ + 13)
                {
                    CpuINT = SignalState.HIGH;
                }
            }

            // Connect TapeInput and SoundOutput
            if (TapeInputSignal.Level == 1)
            {
                SpeakerSoundSignal.Level = 1;
            }
            else if (!soundOutputWasSetByTheCPU)
            {
                SpeakerSoundSignal.Level = 0;
            }

            if (!haltCpuClock)
            {
                // --- CPU clock
                CpuCLK = PixelCLK; // C0 is directly used to drive CPU clock, but CPU T state starts with High state while ULA counter should start with C0 low

                // Check for CPU memory or IO access that could interfere with ULA operations
                if (cpuMemoryOrIORequestHalfTState == 0)
                {
                    // CPU is about to access the video memory
                    bool cpuMemoryOrIORequestToVideoAddress = (Address.SampleValue() & A15A14) == VideoMem;
                    // CPU is about to access the ULA IO port
                    cpuIORequestToULA = (CpuIORQ == SignalState.LOW) && ((Address.SampleValue() & A0) == (ULAPort & A0));
                    if (cpuIORequestToULA)
                    {
                        // Check to see if it is a read operation
                        cpuIORequestToULAIsREAD = CpuWR == SignalState.HIGH;
                    }
                    if (cpuMemoryOrIORequestToVideoAddress || cpuIORequestToULA)
                    {
                        cpuMemoryOrIORequestHalfTState = 1;
                    }
                }
                else if (cpuMemoryOrIORequestHalfTState > 0)
                {
                    cpuMemoryOrIORequestHalfTState++;
                }

                // --- CPU IO requests to ULA port
                if (cpuIORequestToULA)
                {
                    if (cpuIORequestToULAIsREAD)
                    {
                        if (cpuMemoryOrIORequestHalfTState == 5)
                        {
                            byte inputData = 0;
                            // Read keyboard state
                            KeyboardRD = SignalState.LOW;
                            inputData = (byte)(KeyboardData.SampleValue() & ULAPort_Read_Keyboard);
                            KeyboardRD = SignalState.HIGH;
                            // Load cassette
                            inputData |= (byte)(TapeInputSignal.Level << ULAPort_Read_EAR);
                            // Bits 5 and 7 as read by INning from Port 0xfe are always one
                            inputData |= ULAPort_Read_Bits5And7;
                            Data.SetValue(inputData);
                        }
                        else if (cpuMemoryOrIORequestHalfTState == 6)
                        {
                            Data.ReleaseValue();
                        }
                    }
                    else
                    {
                        if (cpuMemoryOrIORequestHalfTState == 3)
                        {
                            byte writeData = Data.SampleValue();
                            // Write borderColor register
                            borderColorRegister = (byte)(writeData & ULAPort_Write_Border);
                            // Output sound
                            SpeakerSoundSignal.Level = (byte)((writeData & ULAPort_Write_Speaker) >> 4);
                            if (SpeakerSoundSignal.Level == 1)
                            {
                                soundOutputWasSetByTheCPU = true;
                            }
                            else { soundOutputWasSetByTheCPU = false; }
                            // Save cassette
                            TapeOuputSignal.Level = (byte)(writeData & ULAPort_Write_MIC);
                        }
                    }
                }
                else if (cpuMemoryOrIORequestHalfTState == 3)
                {
                    // CPU is about to access the ULA IO port
                    cpuIORequestToULA = (CpuIORQ == SignalState.LOW) && ((Address.SampleValue() & A0) == (ULAPort & A0));
                    if (cpuIORequestToULA)
                    {
                        // Check to see if it is a read operation
                        cpuIORequestToULAIsREAD = CpuWR == SignalState.HIGH;
                    }
                    if (cpuIORequestToULA)
                    {
                        cpuMemoryOrIORequestHalfTState = 1;
                    }
                }
            }

            if (cpuMemoryOrIORequestHalfTState == 6)
            {
                cpuMemoryOrIORequestHalfTState = 0;
            }

            // --- Compute pixel colors ---
            if (displayPixels) // First thing to do at the falling edge of the clock
            {
                switch (videoMem16StepsAccessPatternIndex)
                {
                    case 5:
                        displayRegister = displayLatch;
                        break;

                    case 13:
                        displayRegister = displayLatch;
                        break;
                }
            }
            switch (videoMem16StepsAccessPatternIndex)
            {
                case 5:
                    MultiplexAttributeLatchWithBorderColor();
                    break;

                case 13:
                    MultiplexAttributeLatchWithBorderColor();
                    break;
            }

            // --- Load two display and attribute bytes for 16 pixels from video memory ---
            if (!generateBorder)
            {
                switch (videoMem16StepsAccessPatternIndex)
                {
                    case 7:
                        ComputeVideoAddresses();
                        break;

                    case 8:
                        // display address -> address bus
                        VideoAddress.SetValue(displayAddress);
                        VideoMREQ = SignalState.LOW;
                        VideoRD = SignalState.LOW;
                        break;

                    case 9:
                        displayLatch = VideoData.SampleValue();
                        VideoRD = SignalState.HIGH;
                        VideoMREQ = SignalState.HIGH;
                        VideoAddress.ReleaseValue();
                        break;

                    case 10:
                        // attribute adress -> address bus
                        VideoAddress.SetValue(attributeAddress);
                        VideoMREQ = SignalState.LOW;
                        VideoRD = SignalState.LOW;
                        break;

                    case 11:
                        attributeLatch = VideoData.SampleValue();
                        VideoRD = SignalState.HIGH;
                        VideoMREQ = SignalState.HIGH;
                        VideoAddress.ReleaseValue();
                        ComputeVideoAddresses();
                        break;

                    case 12:
                        // display colum address -> address bus
                        VideoAddress.SetValue(displayAddress);
                        VideoMREQ = SignalState.LOW;
                        VideoRD = SignalState.LOW;
                        break;

                    case 13:
                        displayLatch = VideoData.SampleValue();
                        VideoRD = SignalState.HIGH;
                        VideoMREQ = SignalState.HIGH;
                        VideoAddress.ReleaseValue();
                        break;

                    case 14:
                        // attribute adress -> address bus
                        VideoAddress.SetValue(attributeAddress);
                        VideoMREQ = SignalState.LOW;
                        VideoRD = SignalState.LOW;
                        break;

                    case 15:
                        attributeLatch = VideoData.SampleValue();
                        VideoRD = SignalState.HIGH;
                        VideoMREQ = SignalState.HIGH;
                        VideoAddress.ReleaseValue();
                        break;
                }
            }

            // --- For each pixel : Video output signals ---

            // Generate horizontal and vertical synchronization signals
            if (column == 320 /* Offset : because of the time necessary to read the first pixels in video memory, color output begins only 13 cycles after the master counter */ + 13)
            {
                HSync = SignalState.LOW;
            }
            else if (column == 416 /* Offset : because of the time necessary to read the first pixels in video memory, color output begins only 13 cycles after the master counter */ + 13)
            {
                HSync = SignalState.HIGH;
                if (line == 247)
                {
                    VSync = SignalState.LOW;
                }
                else if (line == 255)
                {
                    VSync = SignalState.HIGH;
                }
            }

            // Compute pixel color for video output
            if (HSync == SignalState.LOW || VSync == SignalState.LOW)
            {
                // Blanking
                ColorSignal.Level = 0;
            }
            else
            {
                MultiplexDisplayRegisterWithAttributeRegisterAndFlashClock();
            }

            // Debug notification
            if (pendingExitException == null)
            {
                pendingExitException = NotifyLifecycleEvent(LifecycleEventType.ClockCycle);
            }

            // --- Increment master counters and prepare next iteration ---

            // Shift display register bits
            displayRegister = (byte)(displayRegister << 1);

            column++;
            if(column == 8)
            {
                if (!generateBorder)
                {
                    displayPixels = true;
                }
            }
            else if (column == 256)
            {
                generateBorder = true;
                videoMemAccessTimeFrame = false;
            }
            else if (column == 264)
            {
                if (displayPixels)
                {
                    displayPixels = false;
                }
            }
            else if (column == 448)
            {
                column = 0;
                line++;

                // At each end of line send sound sample signal to the speaker
                // => 7 Mhz pixel clock / 448 pixels per line = 15.6 Khz sound sampling frequency
                SoundSampleCLK = SoundSampleCLK == SignalState.LOW ? SignalState.HIGH : SignalState.LOW;

                if (line < 192)
                {
                    generateBorder = false;
                }

                if (line == 312)
                {
                    line = 0;
                    generateBorder = false;
                    frame++;

                    // Each 16 frames, invert flash clock
                    if (frame == 16)
                    {
                        frame = 0;
                        flashClock = !flashClock;
                    }
                }
            }

            // Debug : if a breakpoint was hit, notify the pixel clock via a specific exception
            if (pendingExitException != null)
            {
                throw pendingExitException;
            }
        }