
#include "pch.h"
#include "AZBKDumpView.h"
#include "Config.h"
#include "Platform.h"
#include "Screen_Sizes.h"
#include "AZBK\AZBK_const.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif

constexpr auto COLUMN_WIDTH_ACS = 30;

constexpr auto COLNUM_MAP = 3;
constexpr auto ROWNUM_DMA = 5;
constexpr auto ROWNUM_COVOX = 5;
constexpr auto ROWNUM_AZBK = 4;
constexpr auto ROWNUM_SCR = 10;
constexpr auto ROWNUM_PAL = 2;
constexpr auto ROWNUM_BLT = 2;
constexpr auto ROWNUM_MAP = 16;
constexpr auto ROWNUM_MCR = 6;
constexpr auto ROWNUM_UART = 4;
constexpr auto ROWNUM_AY = 4;

static const CRegDumpDocPaneDlgViewHelper::ColParam_t arLSTMAPCols[COLNUM_MAP] =
{
	{COL_WIDTH | COL_COLOR, COLUMN_WIDTH, BG_COLOR},
	{COL_WIDTH | COL_EDITABLE, COLUMN_WIDTH, 0},
	{COL_WIDTH | COL_COLOR, COLUMN_WIDTH_ACS, BG_COLOR}
};

static const CRegDumpDocPaneDlgViewHelper::CellParam_t arDMARows[ROWNUM_DMA][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_DMA_177160, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_DMA_177162, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_DMA_177164, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_DMA_177166, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_DMA_177170, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};
static const uint16_t arDMARegs[ROWNUM_DMA] =
{ REG_DMA_CSR, REG_DMA_MEM, REG_DMA_LEN_HI, REG_DMA_LEN_LO, REG_DMA_PGNUM };


static const CRegDumpDocPaneDlgViewHelper::CellParam_t arCOVOXRows[ROWNUM_COVOX][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CVX_177200, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CVX_177202, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CVX_177204, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CVX_177206, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CVX_177212, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};
static const uint16_t arCOVOXRegs[ROWNUM_COVOX] =
{ REG_CVX_L16, REG_CVX_R16, REG_CVX_M16, REG_CVX_LR8, REG_CVX_CSR };


static const CRegDumpDocPaneDlgViewHelper::CellParam_t arAZBKRows[ROWNUM_AZBK][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CTR_177220, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CTR_177222, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CTR_177224, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_CTR_177226, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};
static const uint16_t arAZBKRegs[ROWNUM_AZBK] =
{ REG_CSR, REG_DR, REG_BR1, REG_BR2 };


static const CRegDumpDocPaneDlgViewHelper::CellParam_t arSCRRows[ROWNUM_SCR][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177230, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177232, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177240, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177242, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177244, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177246, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177250, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177252, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177254, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_SCR_177256, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};
static const uint16_t arSCRRegs[ROWNUM_SCR] =
{ REG_SCR_CSR, REG_SCR_PGNUM_L0, REG_SCR_PGNUM_L1, REG_SCR_PGNUM_L2,
			   REG_SCR_VSCRL_L2, REG_SCR_VSCRL_L1, REG_SCR_VSCRL_L0,
			   REG_SCR_HSCRL_L0, REG_SCR_HSCRL_L1, REG_SCR_HSCRL_L2 };


static const CRegDumpDocPaneDlgViewHelper::CellParam_t arPALRows[ROWNUM_PAL][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_PAL_177234, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_PAL_177236, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};
static const uint16_t arPALRegs[ROWNUM_PAL] =
{ REG_PAL_CELL, REG_PAL_VAL };

static const CRegDumpDocPaneDlgViewHelper::CellParam_t arBLTRows[ROWNUM_BLT][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_BLT_177270, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_BLT_177272, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};
static const uint16_t arBLTRegs[ROWNUM_BLT] =
{ REG_BLT_CMD, REG_BLT_PGN };



static const CRegDumpDocPaneDlgViewHelper::CellParam_t arMAPRows[ROWNUM_MAP][COLNUM_MAP] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177300, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177302, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177304, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177306, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177310, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177312, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177314, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177316, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177320, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177322, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177324, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177326, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177330, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177332, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177334, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPW_177336, BG_COLOR}, {COL_EDITABLE, 0, 0}, {COL_COLOR, 0, BG_COLOR} },
};
static const uint16_t arMAPRegs[ROWNUM_MAP] =
{
	REG_MMU_PG00, REG_MMU_PG01, REG_MMU_PG02, REG_MMU_PG03,
	REG_MMU_PG04, REG_MMU_PG05, REG_MMU_PG06, REG_MMU_PG07,
	REG_MMU_PG08, REG_MMU_PG09, REG_MMU_PG10, REG_MMU_PG11,
	REG_MMU_PG12, REG_MMU_PG13, REG_MMU_PG14, REG_MMU_PG15
};


static const CRegDumpDocPaneDlgViewHelper::CellParam_t arMCRRows[ROWNUM_MCR][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPC_177340, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPC_177342, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPC_177344, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPC_177346, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPC_177350, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_MPC_177352, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};
static const uint16_t arMCRRegs[ROWNUM_MCR] =
{ REG_MMU_MNT, REG_MMU_ACS, REG_MMU_SHADOW, REG_MMU_CSR, REG_MMU_AZ_130, REG_MMU_AZ_716 };


static const CRegDumpDocPaneDlgViewHelper::CellParam_t arUARTRows[ROWNUM_UART][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_UAR_177560, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_UAR_177562, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_UAR_177564, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_UAR_177566, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};

static const uint16_t arUARTRegs[ROWNUM_UART] =
{ REG_TKS, REG_TKB, REG_TPS, REG_TPB };

static const CRegDumpDocPaneDlgViewHelper::CellParam_t arAYRows[ROWNUM_AY][COLNUM_STD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_AZ_AY_177172, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_AY_177173, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_AY_177174, BG_COLOR}, {COL_EDITABLE, 0, 0} },
	{ {COL_VALUE | COL_COLOR, IDS_AZ_AY_177175, BG_COLOR}, {COL_EDITABLE, 0, 0} }
};

static const uint16_t arAYRegs[ROWNUM_AY] =
{ REG_AY_ADR1, REG_AY_DAT1, REG_AY_ADR2, REG_AY_DAT2 };



/////////////////////////////////////////////////////////////////////////////
// CAZBKDumpView
IMPLEMENT_DYNAMIC(CAZBKDumpView, CRegDumpDocPaneDlgViewHelper)

CAZBKDumpView::CAZBKDumpView()
    = default;

CAZBKDumpView::~CAZBKDumpView()
    = default;

void CAZBKDumpView::DoDataExchange(CDataExchange *pDX)
{
	CRegDumpDocPaneDlgViewHelper::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_AZBK_DMAREG, m_listDMA);
	DDX_Control(pDX, IDC_LIST_AZBK_COVOX, m_listCOVOX);
	DDX_Control(pDX, IDC_LIST_AZBK_MAIN, m_listAZBK);
	DDX_Control(pDX, IDC_LIST_AZBK_SCRREG, m_listScr);
	DDX_Control(pDX, IDC_LIST_AZBK_PALREG, m_listPalette);
	DDX_Control(pDX, IDC_LIST_AZBK_MAPPERREG, m_listMapper);
	DDX_Control(pDX, IDC_LIST_AZBK_MAPCTRLREG, m_listMapCtrl);
	DDX_Control(pDX, IDC_LIST_AZBK_UARTREG, m_listUART);
	DDX_Control(pDX, IDC_LIST_AZBK_AYREG, m_listAY);
	DDX_Control(pDX, IDC_LIST_AZBK_BLTREG, m_listBlitter);
}

BEGIN_MESSAGE_MAP(CAZBKDumpView, CRegDumpDocPaneDlgViewHelper)
	ON_MESSAGE(WM_INITDIALOG, &CAZBKDumpView::HandleInitDialog)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_MAPPERREG, &CAZBKDumpView::OnLvnItemchangedListAzbkMapperreg)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_MAPCTRLREG, &CAZBKDumpView::OnLvnItemchangedListAzbkMapctrlreg)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_DMAREG, &CAZBKDumpView::OnLvnItemchangedListAzbkDmareg)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_COVOX, &CAZBKDumpView::OnLvnItemchangedListAzbkCovox)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_MAIN, &CAZBKDumpView::OnLvnItemchangedListAzbkMain)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_UARTREG, &CAZBKDumpView::OnLvnItemchangedListAzbkUartreg)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_SCRREG, &CAZBKDumpView::OnLvnItemchangedListAzbkScrreg)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_PALREG, &CAZBKDumpView::OnLvnItemchangedListAzbkPalreg)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_AZBK_AYREG, &CAZBKDumpView::OnLvnItemchangedListAzbkAyreg)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// обработчики сообщений CAZBKDumpView

LRESULT CAZBKDumpView::HandleInitDialog(WPARAM wp, LPARAM lp)
{
	CRegDumpDocPaneDlgViewHelper::HandleInitDialog(wp, lp);
	std::vector <ListParam_t> vList;    // приходится делать так, т.к. нельзя в статическом массиве делать
	// ссылки на нестатические объекты
	// создаём группу маппера
	vList.push_back({ &m_listMapper, &arLSTMAPCols[0], &arMAPRows[0][0], COLNUM_MAP, ROWNUM_MAP, IDC_STATIC_AZBK_MAPPERTTL, true });
	vList.push_back({ &m_listMapCtrl, &arLSTCols[0], &arMCRRows[0][0], COLNUM_STD, ROWNUM_MCR, 0, true });

	for (auto &i : vList)
	{
		CreateList(i);
	}

	int nGrp1Width = 0;
	CPoint ptLT1{ 0, 0 }; // это верхняя левая точка списка (не совпадает с rect1)
	ResizeList(vList[0], ptLT1, nGrp1Width);  // двигаем список маппера
	CRect rect1; // это реальный размер подготовленного списка регистров окон маппера
	vList[0].pList->GetWindowRect(&rect1);
	ScreenToClient(&rect1);
	CPoint ptLT2{ ptLT1.x + nGrp1Width, rect1.top }; // это для списка регистров управления маппера
	ResizeList(vList[1], ptLT2, nGrp1Width); //  разместим второй список - управление маппера
	CRect rect2; // это реальный размер подготовленного списка регистров управления маппера
	vList[1].pList->GetWindowRect(&rect2);
	ScreenToClient(&rect2);
	nGrp1Width += rect2.Width() + m_padX * 2; // сформируем ширину группы, охватывающую оба списка
	SetGrpWidth(GetDlgItem(vList[0].nGrpId), nGrp1Width); // по этой ширине будем корректировать ширину всего диалога
	vList.clear(); //всё, больше этот вектор не нужен
	int nMaxGrpWidth = 0;
	// теперь первую порцию списков
	vList.push_back({ &m_listDMA, &arLSTCols[0], &arDMARows[0][0],   COLNUM_STD, ROWNUM_DMA, IDC_STATIC_AZBK_DMATITLE, true });
	vList.push_back({ &m_listAZBK, &arLSTCols[0], &arAZBKRows[0][0], COLNUM_STD, ROWNUM_AZBK, IDC_STATIC_AZBK_MAINTTL, true });
	vList.push_back({ &m_listScr, &arLSTCols[0], &arSCRRows[0][0],   COLNUM_STD, ROWNUM_SCR, IDC_STATIC_AZBK_SCRTITLE, true });
	ptLT2 = ptLT1; // сохраним точку

	// Создаём списки регистров
	for (auto &i : vList)
	{
		CreateList(i);
		ResizeList(i, ptLT1, nMaxGrpWidth);  // и сразу подвинем
	}

	// теперь сделаем группы все одной ширины
	for (auto &i : vList)
	{
		SetGrpWidth(GetDlgItem(i.nGrpId), nMaxGrpWidth);
	}

	vList.clear(); //всё, больше этот вектор не нужен
	ptLT2.x += nMaxGrpWidth + m_padX * 2; // это координаты начала для второй группы
	nMaxGrpWidth = 0;
	// теперь вторая порция списков
	vList.push_back({ &m_listCOVOX, &arLSTCols[0], &arCOVOXRows[0][0], COLNUM_STD, ROWNUM_COVOX, IDC_STATIC_AZBK_COVOXTTL, true });
	vList.push_back({ &m_listAY, &arLSTCols[0], &arAYRows[0][0],       COLNUM_STD, ROWNUM_AY, IDC_STATIC_AZBK_AYTITLE,     true });
	vList.push_back({ &m_listPalette, &arLSTCols[0], &arPALRows[0][0], COLNUM_STD, ROWNUM_PAL, IDC_STATIC_AZBK_PALTITLE,   true });
	vList.push_back({ &m_listBlitter, &arLSTCols[0], &arBLTRows[0][0], COLNUM_STD, ROWNUM_BLT, IDC_STATIC_AZBK_BLTTITLE,   true });
	vList.push_back({ &m_listUART, &arLSTCols[0], &arUARTRows[0][0],   COLNUM_STD, ROWNUM_UART, IDC_STATIC_AZBK_UARTTITLE, true });

	for (auto &i : vList)
	{
		CreateList(i);
		ResizeList(i, ptLT2, nMaxGrpWidth);  // и сразу подвинем
	}

	// теперь сделаем группы все одной ширины
	for (auto &i : vList)
	{
		SetGrpWidth(GetDlgItem(i.nGrpId), nMaxGrpWidth);
	}

	vList.clear(); //всё,
	//и под конец изменим размеры самого окна
	GetWindowRect(&rect1);
	ScreenToClient(&rect1);
	rect1.bottom = max(ptLT1.y, ptLT2.y) - ::GetSystemMetrics(SM_CYCAPTION) / 2;
	rect1.right = nGrp1Width + m_padX * 4;
	m_sizeDefault = rect1.Size();
	return TRUE;  // return TRUE unless you set the focus to a control
	// Исключение: страница свойств OCX должна возвращать значение FALSE
}


void CAZBKDumpView::DisplayRegDump()
{
	if (IsWindowVisible())
	{
		// выводим на экран данные
		if (g_Platform.GetPlatformStatus() & CONFPLATFORM_AZBK)
		{
			DisplayRegs();
		}
	}
}


void CAZBKDumpView::DisplayRegs()
{
	auto pDbg = g_Platform.GetDebuggerPtr();
	// выводим регистры управления маппером
	uint16_t mmucsr[ROWNUM_MCR];

	for (int n = 0; n < ROWNUM_MCR; ++n)
	{
		mmucsr[n] = pDbg->GetDebugAZBKRegsWord(arMCRRegs[n]);
		m_listMapCtrl.SetItemWithModified(mmucsr[n], n, LSTSTD_COL::VALUE);
	}

	// выводим регистры маппера
	for (int n = 0, bit = 1; n < ROWNUM_MAP; ++n, bit <<= 1)
	{
		const uint16_t nBank = pDbg->GetDebugAZBKRegsWord(arMAPRegs[n]);
		const bool bROBnk = (0100 <= nBank && nBank < 0200);
		COLORREF color = 0;
		CString str = _T("--");

		if (mmucsr[0] & bit) // если окно включено
		{
			// режим доступа
			str = (bROBnk || (mmucsr[1] & bit)) ? _T("RO") : _T("RW");
		}
		//если окно выключено
		else if (!bROBnk // и не диапазон эмуляции ПЗУ
				 && (mmucsr[2] & bit)) // и shadow включён
		{
			color = RGB(0, 0xcc, 0xcc); // показываем цветом
		}

		m_listMapper.SetItemColor(color, n, LSTSTD_COL::VALUE);
		m_listMapper.SetItemColor(color, n, 2);
		m_listMapper.SetItemWithModified(nBank, n, LSTSTD_COL::VALUE);
		m_listMapper.SetItemWithModifiedASCII(str, n, 2);
	}

	// выводим регистры dma
	for (int n = 0; n < ROWNUM_DMA; ++n)
	{
		m_listDMA.SetItemWithModified(pDbg->GetDebugAZBKRegsWord(arDMARegs[n]), n, LSTSTD_COL::VALUE);
	}

	// выводим регистры covox
	for (int n = 0; n < ROWNUM_COVOX; ++n)
	{
		m_listCOVOX.SetItemWithModified(pDbg->GetDebugAZBKRegsWord(arCOVOXRegs[n]), n, LSTSTD_COL::VALUE);
	}

	// выводим регистры контроллера
	for (int n = 0; n < ROWNUM_AZBK; ++n)
	{
		m_listAZBK.SetItemWithModified(pDbg->GetDebugAZBKRegsWord(arAZBKRegs[n]), n, LSTSTD_COL::VALUE);
	}

	// выводим регистры AY
	for (int n = 0; n < ROWNUM_AY; ++n)
	{
		m_listAY.SetItemWithModified(pDbg->GetDebugAZBKRegsByte(arAYRegs[n]), n, LSTSTD_COL::VALUE);
	}

	// выводим регистры экрана
	for (int n = 0; n < ROWNUM_SCR; ++n)
	{
		m_listScr.SetItemWithModified(pDbg->GetDebugAZBKRegsWord(arSCRRegs[n]), n, LSTSTD_COL::VALUE);
	}

	// выводим регистры палитры
	for (int n = 0; n < ROWNUM_PAL; ++n)
	{
		m_listPalette.SetItemWithModified(pDbg->GetDebugAZBKRegsWord(arPALRegs[n]), n, LSTSTD_COL::VALUE);
	}

	// выводим регистры блиттера
	for (int n = 0; n < ROWNUM_BLT; ++n)
	{
		m_listBlitter.SetItemWithModified(pDbg->GetDebugAZBKRegsWord(arBLTRegs[n]), n, LSTSTD_COL::VALUE);
	}

	// выводим регистры UART
	for (int n = 0; n < ROWNUM_UART; ++n)
	{
		m_listUART.SetItemWithModified(pDbg->GetDebugAZBKRegsWord(arUARTRegs[n]), n, LSTSTD_COL::VALUE);
	}
}



// регистры маппера
void CAZBKDumpView::OnLvnItemchangedListAzbkMapperreg(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = S_OK;
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	const int nItem = pNMLV->iItem;			// строка
	if (pNMLV->iSubItem == LSTSTD_COL::VALUE && (unsigned int)nItem < ROWNUM_MAP)
	{
		auto pDbg = g_Platform.GetDebuggerPtr();
		auto pStr = reinterpret_cast<CString *>(pNMLV->lParam);
		const uint16_t value = Global::OctStringToWord(*pStr);

		uint16_t bit = 1 << nItem;
		const bool bROBnk = (0100 <= value && value < 0200);
		COLORREF color = 0;
		CString str = _T("--");

		if ( pDbg->GetDebugAZBKRegsWord(REG_MMU_MNT) & bit) // если окно включено
		{
			// режим доступа
			str = (bROBnk || (pDbg->GetDebugAZBKRegsWord(REG_MMU_ACS) & bit)) ? _T("RO") : _T("RW");
		}
		//если окно выключено
		else if (!bROBnk // и не диапазон эмуляции ПЗУ
				 && (pDbg->GetDebugAZBKRegsWord(REG_MMU_SHADOW) & bit)) // и shadow включён
		{
			color = RGB(0, 0xcc, 0xcc); // показываем цветом
		}

		pDbg->SetDebugAZBKRegs(arMAPRegs[nItem], value);
		m_listMapper.SetItemColor(color, nItem, LSTSTD_COL::VALUE);
		m_listMapper.SetItemColor(color, nItem, 2);
		m_listMapper.SetItemWithModified(value, nItem, LSTSTD_COL::VALUE);
		m_listMapper.SetItemWithModifiedASCII(str, nItem, 2);
	}
}

// регистры управления маппером
void CAZBKDumpView::OnLvnItemchangedListAzbkMapctrlreg(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = S_OK;
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	const int nItem = pNMLV->iItem;			// строка
	if (pNMLV->iSubItem == LSTSTD_COL::VALUE && (unsigned int)nItem < ROWNUM_MCR)
	{
		auto pStr = reinterpret_cast<CString *>(pNMLV->lParam);
		const uint16_t value = Global::OctStringToWord(*pStr);
		g_Platform.GetDebuggerPtr()->SetDebugAZBKRegs(arMCRRegs[nItem], value);
		m_listMapCtrl.SetItemWithModified(value, nItem, LSTSTD_COL::VALUE);
	}
}

// регистры ДМА
void CAZBKDumpView::OnLvnItemchangedListAzbkDmareg(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = S_OK;
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	const int nItem = pNMLV->iItem;			// строка
	if (pNMLV->iSubItem == LSTSTD_COL::VALUE && (unsigned int)nItem < ROWNUM_DMA)
	{
		auto pStr = reinterpret_cast<CString *>(pNMLV->lParam);
		const uint16_t value = Global::OctStringToWord(*pStr);
		g_Platform.GetDebuggerPtr()->SetDebugAZBKRegs(arDMARegs[nItem], value);
		m_listDMA.SetItemWithModified(value, nItem, LSTSTD_COL::VALUE);
	}
}

// регистры ковокса
void CAZBKDumpView::OnLvnItemchangedListAzbkCovox(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = S_OK;
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	const int nItem = pNMLV->iItem;			// строка
	if (pNMLV->iSubItem == LSTSTD_COL::VALUE && (unsigned int)nItem < ROWNUM_COVOX)
	{
		auto pStr = reinterpret_cast<CString *>(pNMLV->lParam);
		const uint16_t value = Global::OctStringToWord(*pStr);
		g_Platform.GetDebuggerPtr()->SetDebugAZBKRegs(arCOVOXRegs[nItem], value);
		m_listCOVOX.SetItemWithModified(value, nItem, LSTSTD_COL::VALUE);
	}
}

// регистры контроллера AZ
void CAZBKDumpView::OnLvnItemchangedListAzbkMain(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = S_OK;
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	const int nItem = pNMLV->iItem;			// строка
	if (pNMLV->iSubItem == LSTSTD_COL::VALUE && (unsigned int)nItem < ROWNUM_AZBK)
	{
		auto pStr = reinterpret_cast<CString *>(pNMLV->lParam);
		const uint16_t value = Global::OctStringToWord(*pStr);
		g_Platform.GetDebuggerPtr()->SetDebugAZBKRegs(arAZBKRegs[nItem], value);
		m_listAZBK.SetItemWithModified(value, nItem, LSTSTD_COL::VALUE);
	}
}

// регистры UART
void CAZBKDumpView::OnLvnItemchangedListAzbkUartreg(NMHDR *pNMHDR, LRESULT *pResult)
{
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	// TODO: добавьте свой код обработчика уведомлений
	*pResult = 0;
}

// регистры экрана
void CAZBKDumpView::OnLvnItemchangedListAzbkScrreg(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = S_OK;
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	const int nItem = pNMLV->iItem;			// строка
	if (pNMLV->iSubItem == LSTSTD_COL::VALUE && (unsigned int)nItem < ROWNUM_SCR)
	{
		auto pStr = reinterpret_cast<CString *>(pNMLV->lParam);
		const uint16_t value = Global::OctStringToWord(*pStr);
		g_Platform.GetDebuggerPtr()->SetDebugAZBKRegs(arSCRRegs[nItem], value);
		m_listScr.SetItemWithModified(value, nItem, LSTSTD_COL::VALUE);
	}
}

// регистры палитр
void CAZBKDumpView::OnLvnItemchangedListAzbkPalreg(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = S_OK;
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	const int nItem = pNMLV->iItem;			// строка
	if (pNMLV->iSubItem == LSTSTD_COL::VALUE && (unsigned int)nItem < ROWNUM_PAL)
	{
		auto pStr = reinterpret_cast<CString *>(pNMLV->lParam);
		const uint16_t value = Global::OctStringToWord(*pStr);
		g_Platform.GetDebuggerPtr()->SetDebugAZBKRegs(arPALRegs[nItem], value);
		m_listPalette.SetItemWithModified(value, nItem, LSTSTD_COL::VALUE);
	}
}

// регистры AY
void CAZBKDumpView::OnLvnItemchangedListAzbkAyreg(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = S_OK;
	auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	const int nItem = pNMLV->iItem;			// строка
	if (pNMLV->iSubItem == LSTSTD_COL::VALUE && (unsigned int)nItem < ROWNUM_AY)
	{
		auto pStr = reinterpret_cast<CString *>(pNMLV->lParam);
		const uint16_t value = Global::OctStringToWord(*pStr);
		g_Platform.GetDebuggerPtr()->SetDebugAZBKRegs(arAYRegs[nItem], value);
		m_listAY.SetItemWithModified(value, nItem, LSTSTD_COL::VALUE);
	}
}
