// rev 1.03
#pragma once
#include "qbus_device.h"

#include <mutex>
#include <condition_variable>
#include <thread>

class QBUS_IRPS : public QBUS_Device
{
		bool            m_bTTY_TXRdy;  // terminal transmitter ready
		bool            m_bTTY_RXRdy;  // terminal receiver ready
		bool            m_bTTY_TXIntrEna, m_bTTY_TXIntrEna_prev;       // terminal transmitter interrupt enable
		bool            m_bTTY_RXIntrEna, m_bTTY_RXIntrEna_prev;       // terminal receiver interrupt enable
		bool            m_bTTY_RXVirq;
		bool            m_bTTY_TXVirq;
		uint8_t         m_chRXData, m_chTXData;

		bool            m_bConsole;

	protected:

		enum QBUSDEV_VIRQ_STATE
		{
			VIRQSTATE_NONE = 0, //начальное состояние - прерывание не требуется
			VIRQSTATE_SETVIRQ,
			VIRQSTATE_WAIT_IAKO,
			VIRQSTATE_WAIT_ENDCYCLE,
			VIRQSTATE_SETRPLY,
			VIRQSTATE_CLRVIRQ,
			VIRQSTATE_WAIT_IAKOCLR,
			VIRQSTATE_FINAL

		};

		bool            m_bPinVirqEna;  //разрешение вывода запроса прерывания на шину
		bool            m_bIakiTranslate;

		QBUSDEV_VIRQ_STATE m_nVirqState;
		int             m_nVirqDelay;
		int             m_nRXRdyDelay;

		CCommonBus::CMNB_LINESET m_PIN_nVIRQ;
		CCommonBus::CMNB_LINESET m_PIN_nIAKO;

		virtual void    setMPI() override; //присваисваем значения Mem -> MPI
		virtual void    getMPI() override; //присваисваем значения MPI -> Mem
		virtual bool    DecodeAddr() override;
		virtual bool    WriteOp() override; //операция производимая при операции записи
		virtual bool    ReadOp() override; //операция производимая при операции чтения
		virtual bool    InitOp() override;

		void            VIRQ_FSM();    //конечный автомат выдачи вектора прерывания

		std::mutex      m_mutInputThreadWork; //событие, означающее, что поток работает
		bool            m_bStopInputThread;  //событие, что пора завершить работу потока
		bool            m_bInputNotify;
		std::condition_variable m_cvInput;
		std::mutex      m_mutInputMutex;

		std::mutex      m_mutOutputThreadWork; //событие, означающее, что поток работает
		bool            m_bStopOutputThread; //событие, что пора завершить работу потока
		bool            m_bOutputNotify;
		std::condition_variable m_cvOutput;
		std::mutex      m_mutOutputMutex;

		//потоки ввода-вывода
		void            InputThreadFunc();     //собственно функция
		std::thread     m_thrInput;
		void            OutputThreadFunc();        //собственно функция
		std::thread     m_thrOutput;
		bool            StartInputThread();
		void            StopInputThread();
		bool            StartOutputThread();
		void            StopOutputThread();

	public:
		QBUS_IRPS();
		virtual ~QBUS_IRPS() override;
		virtual void    RegisterDevice(CCommonBus *pMPI) override;
		virtual void    eval() override;
};

