#pragma once

#include "BKDRT11Header.h"
#include "BKFloppyImage_Prototype.h"
#include <deque>

#pragma pack(push)
#pragma pack(1)
struct NCdosFileRecord
{
	uint8_t  name[12];  //имя файла, если начинается с "//", то это метка диска.
	uint8_t  ext[4];    //расширение, начинается всегда с точки, необязательное
	uint16_t address;   //стартовый адрес
	uint16_t length;    //длина
	uint16_t date;      //дата создания. совместима с RT11

	NCdosFileRecord()
	{
		memset(this, 0, sizeof(NCdosFileRecord));
	}
	NCdosFileRecord &operator = (const NCdosFileRecord &src)
	{
		memcpy(this, &src, sizeof(NCdosFileRecord));
		return *this;
	}
	NCdosFileRecord &operator = (const NCdosFileRecord *src)
	{
		memcpy(this, src, sizeof(NCdosFileRecord));
		return *this;
	}
};
#pragma pack(pop)

#define DISKMAP_OFFSET 01000
#define DISKMAP_SIZE 01440
#define CATALOG_OFFSET 02440
//официально заявлено, что размер каталога 100. файлов
//но физически влезает 0176
#define CATALOG_SIZE 0176

class CBKFloppyImage_HCDos : public CBKFloppyImage_Prototype
{
		uint8_t *m_pCatBuffer;  //буфер каталога
		int     m_nCatSize;     //размер буфера каталога, выровнено по секторам, включая служебную область
		int     m_nFilesNum;    //количество файлов в каталоге

		int GetFreeBlock(int blk);
		bool MarkBlock(int blk, int fn);
		int GetStartBlock(int fn);
		int GetNextBlock(int blk);

		/* поиск заданной записи в каталоге.
		делается поиск на полное бинарное соответствие
		выход: -1 если не найдено,
		если найдено - индекс в векторе
		*/
		int FindRecord(NCdosFileRecord *pHCrec, bool bFull = false);

		unsigned int EvenLengthToBlkLen(unsigned int fileLen);
		unsigned int ConvertLengthToBlkLen(unsigned int fileLen);

	protected:
		virtual void ConvertAbstractToRealRecord(AbstractFileRecord *pFR, bool bRenameOnly = false) override;
		virtual void ConvertRealToAbstractRecord(AbstractFileRecord *pFR) override;

	public:
		CBKFloppyImage_HCDos(const PARSE_RESULT &image);
		virtual ~CBKFloppyImage_HCDos() override;

		//виртуальные функции

		/* прочитать каталог образа */
		virtual bool ReadCurrentDir() override;
		/* записать каталог образа */
		virtual bool WriteCurrentDir() override;
		/* прочитать файл из образа
		 * Параметры.
		 * pFR - указатель на абстрактную запись о файле, внутри которой сохранена
		 *       и реальная запись о файле, где сохранены все необходимые данные,
		 *       даже с дублированием.
		 * pBuffer - указатель на заранее выделенный массив памяти, куда будем сохранять файл.
		 *   что мы будем делать потом с данными буфера, функцию не волнует. */
		virtual bool ReadFile(AbstractFileRecord *pFR, uint8_t *pBuffer) override;
		/* записать файл в образ
		 * Параметры.
		 * pFR - указатель на абстрактную запись о файле, внутри которой сформирована
		 *       реальная запись о файле, где по возможности сохранены все необходимые данные для записи,
		 *       даже с дублированием.
		 * pBuffer - указатель на заранее выделенный массив памяти, где заранее подготовлен массив сохраняемого файла. */
		virtual bool WriteFile(AbstractFileRecord *pFR, uint8_t *pBuffer) override;
		/* удалить файл в образе
		 * Параметры.
		 * pFR - указатель на абстрактную запись о файле, внутри которой сохранена
		 *       и реальная запись о файле, где сохранены все необходимые данные,
		 *       даже с дублированием. */
		virtual bool DeleteFile(AbstractFileRecord *pFR, bool bForce = false) override;

		virtual bool RenameRecord(AbstractFileRecord *pFR) override;
};

/*
0 сектор - загрузчик
со смещения 01000 (с первого сектора) начинается карта диска,
размером 01440 (800.) байтов.
каждый байт означает блок (2 сектора). значение - номер файла, который
занимает блок. В результате получаются цепочки блоков, которые занимают файлы.
фрагментация предусмотрена. файл может быть разбит на куски, но они должны идти последовательно
от начала диска к концу.

со смещения 02440 начинается каталог, директорий кажется нет.
со смещения 010000 начинаются данные.

размер записи каталога 22. байта, первой записью всегда идёт что-то
вроде метки диска, начинается с "//", затем файлы. они нумеруются по
порядку, начиная с 2, метка диска - 1, 0 -свободный блок.
и вот в соответствии с этими номерами, в карте диска, находятся блоки,
занимаемые файлами, системная область там помечается как 1, с установленным старшим битом

ещё, предположительно если старший бит установлен, то файл защищённый, или системный,
или это просто зарезервированная область, непонятно

смещ.   размер  значение
--------------------------------
0       16.     имя файла
16.     2       адрес загрузки файла
18.     2       длина файла, файл не может быть больше 64кб?
20.     2       непонятно, может дата, а может это 2 байта атрибутов

    nop
    mov #404,r0
    emt 12
    mov #177,r0
    emt 12
    mov #11,r0      ;номер блока на диске  10*
    mov #14000,r1   ;длина пересылаемого массива в словах 11000*
    mov #110000,r2  ;начальный адрес массива данных
    mov #2000,r3    ;базовый адрес рабочей области драйвера
    call @#160004   ;чтение-запись по номеру блока
    bcs 0x3e
    mov #33,r0      ; 32*
    mov #4000,r1    ; 5000*
    mov #60000,r2
    mov #2000,r3
    call @#160004   ;чтение-запись по номеру блока
    bcs 0x3e
    jmp @#110000
0x3e: mov pc,r0
    add #10,r0
    emt 65
    halt
    asciz "\r\n* Ошибка чтения системы *\r\n"

непонятно, как опознать систему. пока будем опознавать по первым командам.

ПРИЛОЖЕНИЕ. Формат хранения каталога.

   смещение (от адреса 132000)
   0-     карта диска; каждый байт определяет состояние
   1437   2-х блоков, т.е 1 Кбайт на дисковом пространстве.

   1440-  разбито на 26-байтные области для каждого файла;
   5670   файл с номером 0 занимает адреса 1440 - 1465.
   всего в каталог влазит 100. файлов, хотя физически может поместиться 0176

   Формат байта состояния 2-х блоков:
            0 - свободные блоки
            1-177 - номер файла, занимающий эти блоки.
            200  - плохие блоки.
            201  - системные блоки.

  Блок считается свободным, если соответствующий байт равно 0.
Таким образом обеспечивается оптимальное хранение файлов на
дисках.

  Формат блока параметров файла:
  смещение
  0-13 - имя
  14-17- расширение (14 байт - точка, расширение необязательно)
  20-21- адрес (если нечетный - файл защищен).
  22-23 -длина.
  24-25 -дата.


*/
