#pragma once

#include "BKMPIDevice.h"
#include <thread>
#include <mutex>
#include "LockVarType.h"
#include "BKSound.h"


// для работы с контроллером взят код товарища form

/////////////////////////////////////////////////////////////////////////////////
// область определений

/////////////////////////////////////////////////////////////////////////////////
// перечисление всех регистров

// регистры DMA
constexpr auto REG_DMA_CSR      = 0177160; // регистр управления DMA
constexpr auto REG_DMA_MEM      = 0177162; // регистр адреса страницы с которой будем читать с дискретностью 10000 (4кБ)
constexpr auto REG_DMA_LEN_HI   = 0177164; // старшая часть длины - 8бит
constexpr auto REG_DMA_LEN_LO   = 0177166; // младшая часть длины - 16бит
constexpr auto REG_DMA_PGNUM    = 0177170; // номер текущей страницы воспроизведения
// регистры AY
constexpr auto REG_AY_ADR1      = 0177172; // адрес AY1
constexpr auto REG_AY_DAT1      = 0177173; // данные AY1
constexpr auto REG_AY_ADR2      = 0177174; // адрес AY2
constexpr auto REG_AY_DAT2      = 0177175; // данные AY2
// регистры COVOX
constexpr auto REG_CVX_L16      = 0177200; // 16bit левый канал COVOX
constexpr auto REG_CVX_R16      = 0177202; // 16bit правый канал COVOX
constexpr auto REG_CVX_M16      = 0177204; // 16bit моно COVOX, иначе говоря, запись в этот регистр приводит к фактической одновременной записи в регистры 177200 и 177202
constexpr auto REG_CVX_LR8      = 0177206; // 8bit стерео / mono COVOX, иначе говоря, запись в этот регистр приводит к фактической одновременной записи в регистры 177200 и 177202 - в старший байт
constexpr auto REG_CVX_CSR      = 0177212; // регистр управления звуком COVOX
// регистры STM, управление контроллером
constexpr auto REG_CSR          = 0177220;
constexpr auto REG_DR           = 0177222;
constexpr auto REG_BR1          = 0177224;
constexpr auto REG_BR2          = 0177226;
// регистры экрана
constexpr auto REG_SCR_CSR      = 0177230; // регистр управления режимами экрана
constexpr auto REG_SCR_PGNUM    = 0177232; // регистр номера страницы начала отображения экрана (верхний слой)
constexpr auto REG_SCR_SPR_PGNUM= 0177240; // регистр номера страницы начала отображения экрана (средний слой)
constexpr auto REG_SCR_BGF_PGNUM= 0177242; // регистр номера страницы начала отображения экрана (нижний слой)
// регистры палитры
constexpr auto REG_PAL_CELL     = 0177234; // адрес ячейки палитры [9бит]
constexpr auto REG_PAL_VAL      = 0177236; // значение палитры [15бит]
// регистр рулона
constexpr auto REG_SCROLL       = 0177250; // регистр рулона. дублирует 177664
// регистры маппера памяти
constexpr auto REG_MMU_PG00     = 0177300; // 000000     16 регистров маппера.На каждый сегмент по 4 Кб
constexpr auto REG_MMU_PG01     = 0177302; // 010000
constexpr auto REG_MMU_PG02     = 0177304; // 020000
constexpr auto REG_MMU_PG03     = 0177306; // 030000
constexpr auto REG_MMU_PG04     = 0177310; // 040000
constexpr auto REG_MMU_PG05     = 0177312; // 050000
constexpr auto REG_MMU_PG06     = 0177314; // 060000
constexpr auto REG_MMU_PG07     = 0177316; // 070000
constexpr auto REG_MMU_PG08     = 0177320; // 100000
constexpr auto REG_MMU_PG09     = 0177322; // 110000
constexpr auto REG_MMU_PG10     = 0177324; // 120000
constexpr auto REG_MMU_PG11     = 0177326; // 130000
constexpr auto REG_MMU_PG12     = 0177330; // 140000
constexpr auto REG_MMU_PG13     = 0177332; // 150000
constexpr auto REG_MMU_PG14     = 0177334; // 160000
constexpr auto REG_MMU_PG15     = 0177336; // 170000
constexpr auto REG_MMU_MNT      = 0177340; // регистр маски окон маппера(вкл. / выкл.).
constexpr auto REG_MMU_ACS      = 0177342; // регистр - маска режима доступа к окну(1 - ro / 0 - rw).
constexpr auto REG_MMU_DISA     = 0177344; // регистр с битовой маской запрета подключения окон(1 аппаратный запрет на подключение окна)
constexpr auto REG_MMU_CSR      = 0177346; // регистр управления контроллером памяти
// непонятный регистр
constexpr auto REG_VERS         = 0177370; // регистр версии контроллера / прошивки контроллера
// регистр RND
constexpr auto REG_RND          = 0177550; // регистр RND
// регистры UART
constexpr auto REG_TKS          = 0177560; // UART : регистр статуса приёмника
constexpr auto REG_TKB          = 0177562; // UART : регистр управления + регистр принятых данных
constexpr auto REG_TPS          = 0177564; // UART : регистр статуса передатчика
constexpr auto REG_TPB          = 0177566; // UART : регистр данных на передачу

/////////////////////////////////////////////////////////////////////////////////
// данные для эмуляции контроллера AZBK

constexpr uint16_t CS_CMD_MASK  = 0000077;
constexpr uint16_t CS_IE        = 0000100;
constexpr uint16_t CS_DONE      = 0000200;
constexpr uint16_t CS_BIG       = 0040000;
constexpr uint16_t CS_ERR       = 0100000;
constexpr uint16_t CS_VECTOR    = 0000174; // адрес вектора прерываний контроллера

constexpr uint16_t CS_RD_MASK   = (CS_ERR | CS_BIG | CS_DONE | CS_IE);
constexpr uint16_t CS_WR_MASK   = (CS_IE | CS_CMD_MASK);

template<typename T>
constexpr T AZ_CMD(T v)
{
	return ((v)&CS_CMD_MASK);
};

constexpr auto CMD_RESET        = 000;
constexpr auto CMD_SETUNI       = 001;
constexpr auto CMD_SETBLK       = 002;
constexpr auto CMD_SETBLKX      = 012;
constexpr auto CMD_READ         = 005;
constexpr auto CMD_READ_BUF     = 015;
constexpr auto CMD_WRITE        = 006;
constexpr auto CMD_WRITE_BUF    = 016;
constexpr auto CMD_GET_SIZE     = 007;
constexpr auto CMD_GET_SIZEX    = 017;
constexpr auto CMD_NET          = 010;
constexpr auto CMD_NOP          = 030;

#define CMD_GET_FEAT        027
#define CMD_HFS_GET_AZUNITS 011
#define CMD_HFS_OPEN_CAT    003
#define CMD_HFS_READ_CATREC 013
#define CMD_HFS_MOUNT_UNIT  004
#define CMD_HFS_UMOUNT_UNIT 014
#define CMD_GET_DIAGCODEEX  020

constexpr auto AZ_UNIT_MASK = 0000377;
constexpr auto AZ_LSB_MASK  = 0177777;

#define UF_CFG          0x01
#define UF_BOT          0x02
#define UF_MTD          0x04
#define UF_ERR          0x80

constexpr auto AZ_BUF_SIZE = 256;       // размер буфера ввода-вывода AZBK в словах

/////////////////////////////////////////////////////////////////////////////////

struct AZ_UNIT
{
	CFile       fFile;
	CString     strFileName;    // имя файла образа
	CString     strOrigPathName; // путь к файлу из ини файла
	bool        bRO;            // Флаг защиты от записи
	uint32_t    nSize;          // размер образа в байтах
	uint32_t    nBlkSize;       // размер образа в блоках
	uint32_t	nAttr;			// атрибуты файла
	uint16_t	nDate, nTime;	// дата/время в формате МС-ДОС
	AZ_UNIT() : bRO(true), nSize(0), nBlkSize(0), nAttr(0), nDate(0), nTime(0) {}
};

// элемент внутренней таблицы назначений.
struct az_internal_table
{
	uint32_t    size;
	uint16_t    date;
	uint16_t    time;
	uint8_t     flag;
	uint8_t     attr;
	char        name[130];
};

constexpr auto AZ_BANKS_NUM = 16;   // количество банков памяти в карте памяти. размер банка - 4кб
constexpr auto AZBK_PORTSIO_AREA = 0177000; // адрес отсечки, выше которого нет ОЗУ в банке 15

template<typename T>
constexpr auto AZ_BANK_TO_OFFSET(T bnk)
{
	return (bnk << 12);
}

template<typename T>
constexpr auto AZ_ADDRESS_TO_BANK(T a)
{
	return ((a >> 12) & 0xf);
}

/////////////////////////////////////////////////////////////////////////////////
// данные для эмуляции палитр

constexpr auto AZ_PALETTE_SIZE = 338;   // размер массива палитр
constexpr auto AZ_256_COLOR_IDX = 0;    // начало блока палитр из 256 цветов в массиве
constexpr auto AZ_16_COLOR_IDX = 320;   // начало блока палитр из 16 цветов в массиве
constexpr auto AZ_4_COLOR_IDX = 256;    // начало блока палитр из 4 цветов в массиве (стандартная БКшная 16х4)
constexpr auto AZ_2_COLOR_IDX = 336;    // начало блока палитр из 2 цветов в массиве (монохром)

class CIni;

class CAZBK : public CBKMPIDevice
{
	DECLARE_DYNAMIC(CAZBK)

		CIni               *m_pAZIni;   // ини файл образа SD-Карты
		CString             m_strConfImgPath;   // путь к образу SD-Карты

		//регистры контроллера
		uint16_t			azcs;   // 177220
		uint16_t			azdr;   // 177222
		uint16_t			azbr1;  // 177224
		uint16_t			azbr2;  // 177226

		uint32_t			azunit;
		uint32_t			azblkn;
		int					azcmd;
		uint32_t			az_init_wcnt;
		uint32_t			az_version;

		uint16_t           *dr_rd_data;
		uint16_t           *dr_wr_data;
		uint16_t           *curr_rd_buf; //указатель на текущий читаемый буфер. В основном это azbuf
		int                 dr_wcnt;
		uint16_t            azbuf[AZ_BUF_SIZE];
		az_internal_table	az_assets[8]; // 8 строк всего. а приводов может быть гораздо больше

		// Контроллер поддерживает до восьми псевдодисков
		// мы же сделаем поддержку неограниченного количества.
		uint32_t            m_nMaxUnit;     // максимальный номер юнита
		AZ_UNIT            *m_pUnits;
		int                 m_nBootUnit;    // номер загрузочного юнита

		void                az_start_io();
		void                az_fill_table();
		void                az_set_done();
		uint16_t            az_read_data(uint16_t *reg, uint16_t **buff, int *wcnt);
		void                az_write_data(uint16_t *reg, uint16_t data, uint16_t **buff, int *wcnt);

		// регистры DMA
		mutable uint16_t	m_nDMACSR;
		uint16_t			m_nDMAStartPage;
		uint32_t			m_nDMAFileSize;
		mutable uint16_t	m_nDMACurrentPage;

		CBkSound		   *m_pAZBKSound;
		void				SetDMAWork();
		void                StopDMAThread();
		bool                StartDMAThread();
		void                DMAThreadFunc() const;	// собственно функция
		std::thread         m_DMAThread;
		mutable LockVarType m_lockDMAThr;   // мутекс потока. залочен пока поток живой
		mutable LockVarType m_lockDMA;      // мутекс для синхронизации

		// регистры AY
		uint8_t				m_nAY1Addr, m_nAY1Data, m_nAY2Addr, m_nAY2Data;
		// регистры COVOX
		uint16_t			m_nCVXLeft;
		uint16_t			m_nCVXRight;
		uint16_t			m_nCVXMono;
		uint16_t			m_nCVXCSR;

		// регистры Экрана
		uint16_t			m_nSCRCSR;
		uint16_t			m_nSCRPageNum;
		uint16_t			m_nSCRSprPageNum;
		uint16_t			m_nSCRBgfPageNum;
		static const int	m_arAZBPP[4];
		static const int	m_arAZLLEN[4];
		static const int	m_arAZXS[4];
		static const int	m_arAZYS[4];
		static const int	m_arAZLSCRL[12];

		int                 m_nAZVideoMode; // номер видеорежима
		int                 m_nAZBpp;       // бит на точку
		int                 m_nAZLineLen;   // длина строки в байтах
		int                 m_nAZXStretch;  // число повторов точки по ширине
		int                 m_nAZYStretch;  // число повторов строки по высоте
		int                 m_nAZScrlSize;  // длина рулона в словах
		int                 m_nAZScrlLines; // размер рулона в строках.
		mutable uint32_t   *m_pTexture;     // указатель на текстуру экрана

		// регистры Палитры
		uint16_t			m_nPalCell;
		uint32_t			m_azPalette[AZ_PALETTE_SIZE];

		// регистр рулона
		uint16_t			m_nSCRL177250;

		// регистры UART
		uint16_t			m_nCOM177560;
		uint16_t			m_nCOM177562;
		uint16_t			m_nCOM177564;
		uint16_t			m_nCOM177566;

		//регистры маппера памяти
		uint16_t			m_nConnectMap;      // 0177340 карта подключенных страниц.
		uint16_t			m_nAccessMode;      // 0177342 режим доступа
		uint16_t			m_nDisableConnect;  // 0177344 аппаратный запрет подключения страниц в заданнео окно
		uint16_t			m_nMMUCSR;          // 0177346 регистр управления контроллером памяти

		// перехват некоторых данных
		int					m_nLegacyPalette;   // номер палитры
		int					m_nLegacyScrBuf;    // номер отображаемого экрана
		int					m_nLegacyPgNum0;    // номер страницы ОЗУ, подключенной в окно 0
		int					m_nLegacyPgNum1;    // номер страницы ОЗУ, подключенной в окно 1, если больше 7, то ПЗУ.

		bool				m_bSEL1;            // триггер, для подмены адреса запуска в 177716 на этапе старта/рестарта
		BK_DEV_MPI			m_devMainBoard;		// модель БКшки, к которой подключен AZBK

		void                VideoThreadFunc() const; // собственно функция
		std::thread         m_VideoThread;
		mutable LockVarType m_lockVidThr;   // мутекс потока. залочен пока поток живой
		mutable LockVarType m_lockVid;      // мутекс для синхронизации
		mutable std::mutex	m_mutScrParam;	// блокировка измениния параметров экрана

		AltProCustomData_t  m_sCustom;
		bool                m_bA16M_Trigger;
		uint16_t            m_nAltproMode;      // код режима работы контроллера Альтпро
		uint16_t            m_nAltProMemBank;   // номер банка памяти контроллера Альтпро
		BKMEMBank_t         m_IOSegment;    // тут будет задаваться статус участка памяти 177000-177777

	protected:
		virtual bool        InitMemory(uint16_t wHighLim) override;
		virtual void        MemoryManager() override;
		void                DropLegacyShadowMap(register const uint16_t addr, register uint16_t value, register UINT dwFlags = 0);
		void                MapToWindow(int nWnd, int nPage, bool bRW, bool bForce = false); // подключение страницы в окно

		uint32_t            R5G5B5toRGB(uint16_t c) const;
		uint16_t            RGBtoR5G5B5(uint32_t c) const;
		void                SetScreenParam(uint16_t v);
		void                FillTexture() const;

		void                Change_AltPro_Mode(uint16_t w);
		void				AltPro_MemoryManager();

	public:
		CAZBK();
		virtual ~CAZBK() override;
		virtual bool        InitialSetDevice() override;

		virtual BK_DEV_MPI GetBoardModel() const override
		{
			return BK_DEV_MPI::AZBK;
		}

		virtual bool        InitDevice(uint16_t addrStart) override;

		// Virtual method called after reset command
		virtual void        OnReset() override;
		// хак. неиспользуемая виртуальная функция, чтобы сбросить SEL1
		virtual void        NextTick() override;

		// Методы, эмулирующие поведение регистров
		virtual bool        GetSystemRegister(register const uint16_t addr, register void *pDst, register UINT dwFlags = 0) override;
		virtual bool        SetSystemRegister(register const uint16_t addr, register uint16_t value, register UINT dwFlags = 0) override;

		// Methods for Set/Get byte/word
		virtual bool        GetByteT(register const uint16_t addr, register uint8_t *pValue, int &nTC) override;
		virtual bool        GetWordT(register const uint16_t addr, register uint16_t *pValue, int &nTC) override;
		virtual bool        SetByteT(register const uint16_t addr, register uint8_t value, int &nTC) override;
		virtual bool        SetWordT(register const uint16_t addr, register uint16_t value, int &nTC) override;
		virtual bool        GetByteTInternal(register const uint16_t addr, register uint8_t *pValue, int &nTC) override;
		virtual bool        GetWordTInternal(register const uint16_t addr, register uint16_t *pValue, int &nTC) override;

		// Методы для загрузки и сохранения состояния эмулятора
		//virtual bool        RestoreRegisters(DWORD id, CMSFManager *pMsf) override; это для сохранения/восстановления регистров
		virtual bool        RestoreMemory(DWORD id, CMSFManager *pMsf) override;
		virtual bool        RestoreMemoryMap(DWORD id, CMSFManager *pMsf) override;
		//virtual bool        RestoreCustomData(DWORD id, CMSFManager *pMsf) override; это для сохранения/восстановления каких-нибудь своих данных

		void                StopVideoThread();
		bool                StartVideoThread();
};

/*

/////////////////////////////////////////////////////////////////////////////////
распределение памяти.
0-128 - теневое ОЗУ БК
128-256 - резерв
256-512 - RO память для эмуляции ПЗУ - безусловное RO, значения регистра 177342 не применяются.
512-1024 - память для эмуляции СМК
1024-... - память AZBK

177220 - регистр команд и состояния (CSR)
  по записи
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
                             |  +------+-------+
                             |         +---------- код команды
                             +-------------------- разрешение прерывания
  по чтению
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
  |                       |
  |                       +----------------------- признак готовности
  +----------------------------------------------- признак ошибки


177300-177336 – 16 регистров маппера. На каждое окно по 4 Кб
177300 - окно  0: адр 000000...007777
177302 - окно  1: адр 010000...017777
177304 - окно  2: адр 020000...027777
177306 - окно  3: адр 030000...037777
177310 - окно  4: адр 040000...047777
177312 - окно  5: адр 050000...057777
177314 - окно  6: адр 060000...067777
177316 - окно  7: адр 070000...077777
177320 - окно  8: адр 100000...107777
177322 - окно  9: адр 110000...117777
177324 - окно 10: адр 120000...127777
177326 - окно 11: адр 130000...137777
177330 - окно 12: адр 140000...147777
177332 - окно 13: адр 150000...157777
177334 - окно 14: адр 160000...167777
177336 - окно 15: адр 170000...177777
формат данных регистров маппера
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|  |  |  |    номер сегмента памяти             |
биты 15-13 - зарезервированы

177340 - регистр маски окон маппера (вкл. / выкл.).
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
  |                                            +-- маска окна 0
  |                                                ......
  +----------------------------------------------- маска окна 15
1 в бите - в окно подключено заданное ОЗУ
0 - не подключено

177342 - регистр-маска режима доступа к окну (1-ro / 0-rw).
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
  |                                            +-- режим окна 0
  |                                                ......
  +----------------------------------------------- режим окна 15

177344 - регистр с битовой маской запрета подключения окон (1 аппаратный запрет на подключение окна)/
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
  |                                            +-- режим окна 0
  |                                                ......
  +----------------------------------------------- режим окна 15

Но поскольку в первых 32 кб ОЗУ БК всегда и не отключается, то использовать
окна 0..7 нельзя. т.е. если использовать, то будет наложение на ОЗУ БК.

/////////////////////////////////////////////////////////////////////////////////
Экран
177230 - регистр управления
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
 +----+----+    +-+-+    +-+-+    +-+-+    +-+-+
      |           |        |        |        +---- количество бит на цвет:
      |           |        |        |               0 - 1 бит на цвет - 2 цвета
      |           |        |        |               1 - 2 бита на цвет - 4 цвета
      |           |        |        |               2 - 4 бита на цвет - 16 цветов
      |           |        |        |               3 - 8 бит на цвет - 256 цветов
      |           |        |        +------------- длина строки в словах
      |           |        |                        0 - 32 слова
      |           |        |                        1 - 64
      |           |        |                        2 - 128
      |           |        |                        3 - 256
      |           |        +---------------------- растяжение по горизонтали - т.е. количество повторов у точки
      |           |                                 0 - х1 - те 1024 точки в строке
      |           |                                 1 - х2 - 512
      |           |                                 2 - х4 - 256
      |           |                                 3 - х8 - 128
      |           +------------------------------- количество повторов строк
      |                                             0 - х1 - 768 строк
      |                                             1 - х2 - 384
      |                                             2 - х3 - 256
      |                                             3 - х4 - 192
      +------------------------------------------- длина рулона в словах
                                                    0 - 6144        256 x 24
                                                    1 - 8192        256 x 32
                                                    2 - 12288       256 x 48
                                                    3 - 16384       256 x 64
                                                    4 - 24576       256 x 96
                                                    5 - 32768       256 x 128
                                                    6 - 49152       256 x 192
                                                    7 - 65536       256 x 256
                                                    8 - 98304       256 x 384
                                                    9 - 131072      256 x 512
                                                    10 - 196608     256 x 768
                                                    11 - 262144     256 x 1024

177232 - регистр номера страницы начала отображения
формат данных регистра
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|  |  |  |    номер сегмента памяти             |
биты 15-13 - зарезервированы

Палитры
177234 - адрес ячейки палитры [9бит]
177236 - значение палитры [15бит]


/////////////////////////////////////////////////////////////////////////////////
COVOX
177200 - 16bit левый канал
177202 - 16bit правый канал
177204 - 16bit моно ковокс
177206 - 8bit стерео/mono ковокс
            битность определяется режимом обращения. словный - стерео, байтовый - моно
177212 - регистр управления режимами ковокса
формат данных регистра
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
                                         |  |  +-- режим легаси перехвата 177714:
                                         |  |       0 - моно, 1 - стерео
                                         |  +----- легаси перехват 177714:
                                         |          0 - разрешён, 1 - запрещён
                                         +-------- перехват звука из 177716:
                                                    0 - разрешён, 1 - запрещён

/////////////////////////////////////////////////////////////////////////////////
DMA звук
177160 - регистр управления
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
             +---+--+  +--+--+     |  |  |  |  +-- старт:
                 |        |        |  |  |  |       1 - старт
                 |        |        |  |  |  +----- однократный запуск:
                 |        |        |  |  |          1 - однократный запуск, 0 - циклический
                 |        |        |  |  |          после окончания однократного запуска устанавливается
                 |        |        |  |  |          в 1 бит 3, для циклического запуска бит 3 тоже должен
                 |        |        |  |  |          быть обнулён.
                 |        |        |  |  +-------- принудительная остановка до завершения цикла
                 |        |        |  +----------- по чтению: 1 - конец однократного запуска, 0 - ещё нет
                 |        |        |               по записи: 0 - разрешён циклический запуск
                 |        |        +-------------- =1 - потоковое воспроизведение с подкачкой данных
                 |        +----------------------- скорость выдачи наружу:
                 |                                  0 - 44100
                 |                                  больше пока нет
                 +-------------------------------- режим интерпретации:
                                                    000 - PCM 16 mono
                                                    100 - IMA ADPCM DECODER mono
                                                    101 - IMA ADPCM DECODER stereo
177162 - регистр адреса страницы, с которой будем читать с дискретностью 10000 (4кБ)
формат данных регистра
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|  |  |  |    номер сегмента памяти             |
биты 15-13 - зарезервированы
177164 - старшая часть длины - 8бит
177166 - младшая часть длины - 16бит
177170 - номер текущей страницы воспроизведения
формат данных регистра
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|  |  |  |    номер сегмента памяти             |
биты 15-13 - зарезервированы







*/
