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

#include "Platform.h"

IMPLEMENT_DYNAMIC(CFDDStd326Mem, CFDDStd326)

CFDDStd326Mem::CFDDStd326Mem()
    = default;


CFDDStd326Mem::~CFDDStd326Mem()
    = default;

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

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

bool CFDDStd326Mem::GetByteTInternal(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 & 077777];
		return true;
	}

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

bool CFDDStd326Mem::GetWordTInternal(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 & 077776]));
		return true;
	}

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


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