// MSF.h: defines for the CMSFManager class.
//

#pragma once

constexpr uint32_t MSF_BLOCKTYPE_EXT_MASK = 0x10000;

enum class MSF_BLOCKTYPE : uint32_t
{
	UNKNOWN = uint32_t(-1),
	BASEMEMORY = 0,
	CPU_REGISTERS,
	PREVIEW,
	B10EXT16,			// deprecated
	B10EXT32,			// deprecated
	PLATFORM,
	PORT_REGS,
	MEMMAP,
	BASEMEMORY11M,	// deprecated
	MEMORY_SMK512,	// deprecated
	CONFIG,
	FRAMEDATA,
	WAVE = 200,
	// расширенные блоки с доп.полями
	BASEMEMORYEX = MSF_BLOCKTYPE_EXT_MASK,
	CPU_REGISTERSEX,
	PREVIEWEX,
	PLACEHOLDER1,
	PLACEHOLDER2,
	PLATFORMEX,
	PORT_REGSEX,
	MEMMAPEX,
	PLACEHOLDER3,
	PLACEHOLDER4,
	CONFIGEX,
	FRAMEDATAEX,
	CUSTOMEX,

};

#pragma pack(push)
#pragma pack(4)
// первый блок - заголовок файла
struct MSF_FILE_HEADER
{
	uint32_t	type;           // тип мсф файла. идентификатор, всегда 65536
	uint32_t	version;        // версия мсф файла.
	uint32_t	reserved;       // для обратной совместимости
};

// для обратной совместимости, нужно уметь читать старые tap файлы.
struct MSF_BLOCK_HEADER
{
	MSF_BLOCKTYPE type;		// тип блока (MSF_BLOCKTYPE)
	uint32_t	length;		// размер блока = размер заголовка + размер данных

	bool operator == (const MSF_BLOCK_HEADER &r)
	{
		return (memcmp(this, &r, sizeof(MSF_BLOCK_HEADER)) == 0);
	}
	bool operator != (const MSF_BLOCK_HEADER &r)
	{
		return (memcmp(this, &r, sizeof(MSF_BLOCK_HEADER)) != 0);
	}
	MSF_BLOCK_HEADER &operator = (const MSF_BLOCK_HEADER &src)
	{
		memcpy(this, &src, sizeof(MSF_BLOCK_HEADER));
		return *this;
	}
};

constexpr uint32_t MSF_EX_FLAG_COMPRESSED = 1; // флаг сжатых данных в блоке

// заголовок блока
struct MSF_BLOCK_HEADEREX
{
	MSF_BLOCK_HEADER hdr;
	uint32_t		id;			// идентификатор устройства, которому принадлежит блок
	uint32_t		flags;		// флаги
	uint32_t		unpSize;	// размер распакованного массива


	bool operator == (const MSF_BLOCK_HEADEREX &r)
	{
		return (memcmp(this, &r, sizeof(MSF_BLOCK_HEADEREX)) == 0);
	}
	bool operator != (const MSF_BLOCK_HEADEREX &r)
	{
		return (memcmp(this, &r, sizeof(MSF_BLOCK_HEADEREX)) != 0);
	}
	MSF_BLOCK_HEADEREX &operator = (const MSF_BLOCK_HEADEREX &src)
	{
		memcpy(this, &src, sizeof(MSF_BLOCK_HEADEREX));
		return *this;
	}
};



struct MSF_CPU_REGISTERS
{
	uint16_t    r0;
	uint16_t    r1;
	uint16_t    r2;
	uint16_t    r3;
	uint16_t    r4;
	uint16_t    r5;
	uint16_t    sp;
	uint16_t    pc;
	uint16_t    psw;
};

struct MSF_PORT_REGS
{
	uint16_t    p0177660;
	uint16_t    p0177662_in;
	uint16_t    p0177662_out;
	uint16_t    p0177664;
	uint16_t    p0177700;
	uint16_t    p0177702;
	uint16_t    p0177704;
	uint16_t    p0177706;
	uint16_t    p0177710;
	uint16_t    p0177712;
	uint16_t    p0177714_in;
	uint16_t    p0177714_out;
	uint16_t    p0177716_in;
	uint16_t    p0177716_out_tap;
	uint16_t    p0177716_out_mem;
};

struct MSF_FRAMEDATA
{
	// состояние ВЕ таймера
	int			nTimerSpeed;
	int			nTimerDiv;

	// состояние экрана
	int			nVideoAddress; // видео адрес, младшие 6 бит - счётчик строк внутри строки
	int			bHgate; // флаг отсчёта служебных видеоциклов в строке
	int			bVgate; // флаг отсчёта служебных строк
	int			nVGateCounter; // дополнительный счётчик служебных строк
	int			nLineCounter; // счётчик видео строк

	// состояние фрейма
	int			nCPUTicks;
	double		fMediaTicks;
	double		fMemoryTicks;
	double		fFDDTicks;
	double		fAZVideoTicks;
};

struct MSF_DEVICE_ID
{
	uint32_t	nBKBoardModel;          // модель устройства (см. enum BK_DEV_MPI)
	uint32_t	nUniqueID;              // уникальный идентификатор
	// на случай, если будет в списке несколько одинаковых BK_DEV_MPI.
};

struct MSF_PLATFORM_DATA
{
	uint32_t	nPlatformConfig;        // номер конфигурации (см enum CONF_BKMODEL)
	uint32_t	nDevNum;                // количество устройств в конфигурации
	std::vector<MSF_DEVICE_ID> pDevices; // список устройств размером nDevNum (фактически, с точки зрения физического хранения данных, - это обычный массив)
};

// описатель блока
struct MSF_BLOCK_INFO
{
	size_t				offset; // смещение до следующего блока.
	// заполняется при разборе файла
	// в самом файле не содержится.
	MSF_BLOCK_HEADEREX	header; // заголовок блока
};

#pragma pack(pop)
