#include "stdafx.h"
#include "CommonBus.h"

#pragma warning(disable:4996)

CCommonBus::CCommonBus()
#if (OUT_CMNBUS_DBG_LOG)
	: m_pLog(nullptr)
#endif
{
#if (OUT_CMNBUS_DBG_LOG)
#define DBG_OUT_CMNBUS_LOG_NAME "_commonbus_log.txt"
	m_pLog = fopen(DBG_OUT_CMNBUS_LOG_NAME, "wt");
	fclose(m_pLog);
#endif
	initArrays();
}
CCommonBus::~CCommonBus()
{
	deinitArrays();
}

void CCommonBus::initArrays()
{
	for (auto &i : m_pCMNData)
	{
		i.nObjNumber = 0;
		i.nCurrValue = -1;

		for (auto &n : i.pObjVal)
		{
			n = -1;
		}
	}

	for (auto &i : m_pCMNLine)
	{
		i.nObjNumber = 0;
		i.bCurrValue = true;

		for (auto &n : i.pObjVal)
		{
			n = true;
		}
	}
}
void CCommonBus::deinitArrays()
{
}

bool CCommonBus::RegisterSignal(CMNB_DATASET *DataSet, CMNBUS_DATA nData)
{
	ASSERT(DataSet);
	DataSet->bSet = false;
	DataSet->nData = nData;
	int nIndex = m_pCMNData[nData].nObjNumber; //выдаём текущий индекс.

	if (nIndex >= CMNB_MAX_OBJECTS) //если индекс достиг максимума
	{
		return false;           //то ошибка
	}
	else
	{
		m_pCMNData[nData].nObjNumber++; //иначе увеличиваем значение
	}

	DataSet->nIndex = nIndex;
	return true;
}

void CCommonBus::SetSignal(CMNB_DATASET *DataSet, uint32_t nValue)
{
	ASSERT(DataSet);
	m_pCMNData[DataSet->nData].SetSignal(DataSet->nIndex, nValue);
}

void CCommonBus::SetSignalOE(CMNB_DATASET *DataSet, bool bEnable, uint32_t nValue)
{
	ASSERT(DataSet);
	if (bEnable)
	{
		if (!DataSet->bSet)
		{
			m_pCMNData[DataSet->nData].SetSignal(DataSet->nIndex, nValue);
			DataSet->bSet = true;
		}
	}
	else
	{
		if (DataSet->bSet)
		{
			m_pCMNData[DataSet->nData].SetSignal(DataSet->nIndex, -1);
			DataSet->bSet = false;
		}
	}
}

//выдача данных МПИ.
uint32_t CCommonBus::GetSignal(CMNBUS_DATA nData)
{
	return m_pCMNData[nData].GetSignal();
}

bool CCommonBus::RegisterSignal(CMNB_LINESET *LineSet, CMNBUS_LINES nLine)
{
	ASSERT(LineSet);
	LineSet->bSet = false;
	LineSet->nLine = nLine;
	int nIndex = m_pCMNLine[nLine].nObjNumber; //выдаём текущий индекс.

	if (nIndex >= CMNB_MAX_OBJECTS) //если индекс достиг максимума
	{
		false;          //то ошибка
	}
	else
	{
		m_pCMNLine[nLine].nObjNumber++; //иначе увеличиваем значение
	}

	LineSet->nIndex = nIndex;
	return true;
}

void CCommonBus::SetSignal(CMNB_LINESET *LineSet, bool bValue)
{
	ASSERT(LineSet);
	m_pCMNLine[LineSet->nLine].SetSignal(LineSet->nIndex, bValue);
}

void CCommonBus::SetSignalOE(CMNB_LINESET *LineSet, bool bEnable, bool bValue)
{
	ASSERT(LineSet);
	if (bEnable)
	{
		if (!LineSet->bSet)
		{
			m_pCMNLine[LineSet->nLine].SetSignal(LineSet->nIndex, bValue);
			LineSet->bSet = true;
		}
	}
	else
	{
		if (LineSet->bSet)
		{
			m_pCMNLine[LineSet->nLine].SetSignal(LineSet->nIndex, true);
			LineSet->bSet = false;
		}
	}
}


//выдача линии МПИ.
bool CCommonBus::GetSignal(CMNBUS_LINES nLine)
{
	return m_pCMNLine[nLine].GetSignal();
}

#if (OUT_CMNBUS_DBG_LOG)
void CCommonBus::OutLog(int nClk, const char *str)
{
	static int nCount = 20;
	m_pLog = fopen(DBG_OUT_CMNBUS_LOG_NAME, "a");

	if (++nCount >= 20)
	{
		nCount = 0;
		fprintf(m_pLog, "                    B W S D D R I D A I I I V D S D D I S S\n");
		fprintf(m_pLog, "     clk    ad      S T Y I O P N C C R R R I M A M M A L L\n");
		fprintf(m_pLog, "                    Y B N N U L I L L 1 2 3 R R C I O K 1 2\n");
	}

	fprintf(m_pLog, "%s %08d", str, nClk);
	//выводятся сигналы с мпи. Поэтому кто выставляет сигнал - нужно догадываться из контекста.
	fprintf(m_pLog, " %06o", (~GetSignal(CCommonBus::MPI_DATA_nAD) & 0xffff));
	fprintf(m_pLog, "  %d", (GetSignal(CCommonBus::CMN_LINE_nBSY) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nWTBT) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nSYNC) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nDIN)  ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nDOUT) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nRPLY) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nINIT) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nDCLO) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nACLO) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nIRQ1) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nIRQ2) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nIRQ3) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nIRQ0) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nDMR)  ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nSACK) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::CMN_LINE_nDMGI) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nDMGO) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::MPI_LINE_nIAK0) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::CMN_LINE_nSEL1) ? 0 : 1));
	fprintf(m_pLog, " %d", (GetSignal(CCommonBus::CMN_LINE_nSEL2) ? 0 : 1));
	fprintf(m_pLog, "\n");
	fclose(m_pLog);
}
#endif
