#include "pch.h"
#include "FDDStd326Mem.h"
#include "Platform.h"

IMPLEMENT_DYNAMIC(CFDDStd326Mem, CFDDStd326)

CFDDStd326Mem::~CFDDStd326Mem()
    = default;

bool CFDDStd326Mem::InitialSetDevice()
{
	if (CFDDStd326::InitialSetDevice())
	{
		// хак, чтобы не зацикливаться при старте
		*(reinterpret_cast<uint16_t *>(&m_pMemory[0120000])) = 0;
		g_Platform.GetWndVectorPtr()->push_back({ _T("EXTMEM"), 0120000, 040000, GetMainMemory() + 0120000 });
		return true;
	}

	return false;
}

bool CFDDStd326Mem::GetByteT(const uint16_t addr, uint8_t *pValue, int &nTC)
{
	if (0120000 <= addr && addr < 0160000)
	{
		nTC = m_pMemoryMap[KNGMD_RAM1_BNK].nTimingCorrection;
		*pValue = m_pMemory[addr];
		return true;
	}

	return CFDDStd326::GetByteT(addr, pValue, nTC);
}

bool CFDDStd326Mem::GetWordT(const uint16_t addr, uint16_t *pValue, int &nTC)
{
	if (0120000 <= addr && addr < 0160000)
	{
		nTC = m_pMemoryMap[KNGMD_RAM1_BNK].nTimingCorrection;
		*pValue = *(reinterpret_cast<uint16_t *>(&m_pMemory[addr & 0177776]));
		return true;
	}

	return CFDDStd326::GetWordT(addr, pValue, nTC);
}

bool CFDDStd326Mem::SetByteT(const uint16_t addr, uint8_t value, int &nTC)
{
	if (0120000 <= addr && addr < 0160000)
	{
		m_pMemory[addr] = value;
		nTC = m_pMemoryMap[KNGMD_RAM1_BNK].nTimingCorrection;
		return true;
	}

	return CFDDStd326::SetByteT(addr, value, nTC);
}

bool CFDDStd326Mem::SetWordT(const uint16_t addr, uint16_t value, int &nTC)
{
	if (0120000 <= addr && addr < 0160000)
	{
		*(reinterpret_cast<uint16_t *>(&m_pMemory[addr & 0177776])) = value;
		nTC = m_pMemoryMap[KNGMD_RAM1_BNK].nTimingCorrection;
		return true;
	}

	return CFDDStd326::SetWordT(addr, value, nTC);
}

bool CFDDStd326Mem::GetByteIndirect(const uint16_t addr, uint8_t *pValue)
{
	if (0120000 <= addr && addr < 0160000)
	{
		*pValue = m_pMemory[addr];
		return true;
	}

	return CFDDStd326::GetByteIndirect(addr, pValue);
}

bool CFDDStd326Mem::GetWordIndirect(const uint16_t addr, uint16_t *pValue)
{
	if (0120000 <= addr && addr < 0160000)
	{
		*pValue = *(reinterpret_cast<uint16_t *>(&m_pMemory[addr & 0177776]));
		return true;
	}

	return CFDDStd326::GetWordIndirect(addr, pValue);
}


bool CFDDStd326Mem::CheckReadWord(const uint16_t addr)
{
	if (0120000 <= addr && addr < 0160000)
	{
		return true;
	}

	return CFDDStd326::CheckReadWord(addr);
}

bool CFDDStd326Mem::CheckWriteWord(const uint16_t addr)
{
	if (0120000 <= addr && addr < 0160000)
	{
		return true;
	}

	return CFDDStd326::CheckWriteWord(addr);
}

void CFDDStd326Mem::MemoryManager()
{
	CFDDStd326::MemoryManager();
	// по адресам 120000-160000 ОЗУ
	BKMEMBank_t &m = m_pMemoryMap[KNGMD_RAM1_BNK];
	m.bReadable = TRUE;
	m.bWritable = TRUE;
	m.nTimingCorrection = RAM_TIMING_CORR_VALUE_S;
	BKMEMBank_t &m1 = m_pMemoryMap[KNGMD_RAM2_BNK];
	m1.bReadable = TRUE;
	m1.bWritable = TRUE;
	m1.nTimingCorrection = RAM_TIMING_CORR_VALUE_S;
	SetMemoryMapViewData(KNGMD_RAM1_BNK);
	SetMemoryMapViewData(KNGMD_RAM2_BNK);
}
