#include "pch.h"
#include "BKMemory.h"
#include "Globals.h"
#include "Object.h"

// сюда выделим функции, нужные BKBin2Obj

#pragma warning(disable:4996)

bool ObjManger::SaveIDBlk(FILE *f)
{
	//long fp = ftell(f);
	const OBJBlockHeader hdr
	{
		OBJTags::OBJ_HDRTAG, // nHdrTag
		OBJTags::OBJ_ID,    // nBlockTag
		sizeof(OBJIDBlock), // nBlkLen
		1,                  // nEntryCount
		0                   // nCheckSum
	};
	const OBJIDBlock data
	{
		OBJVERSION, // nVersion
		static_cast<int16_t>(g_Globals.GetStartAddress()), // nStartAddress - адрес запуска
		static_cast<int16_t>(g_Globals.GetLinkMode())   // nMode - режим компоновки
	};
	fwrite(&hdr, 1, sizeof(hdr), f);
	fwrite(&data, 1, sizeof(data), f);
	return true;
}

bool ObjManger::SaveData(FILE *f)
{
	const int dataLen = g_Globals.GetProgramLength();
	const OBJBlockHeader hdr
	{
		OBJTags::OBJ_HDRTAG, // nHdrTag
		OBJTags::OBJ_DATA,  // nBlockTag
		static_cast<uint32_t>(dataLen), // nBlkLen
		1,                  // nEntryCount
		0                   // nCheckSum
	};
	fwrite(&hdr, 1, sizeof(hdr), f);

	if (dataLen)
	{
		fwrite(&g_Memory.b[BASE_ADDRESS], 1, dataLen, f);
	}

	return true;
}

bool ObjManger::SaveLabelTable(FILE *f, CLabelTable *lbltbl, OBJTags nTag)
{
	const size_t sz = lbltbl->getSize();

	if (sz > 0)
	{
		const long fp = ftell(f);
		OBJBlockHeader hdr
		{
			OBJTags::OBJ_HDRTAG,        // nHdrTag
			nTag,                       // nBlockTag
			0,                          // nBlkLen
			static_cast<uint32_t>(sz),  // nEntryCount
			0                           // nCheckSum
		};
		fwrite(&hdr, 1, sizeof(hdr), f);

		for (size_t i = 0; i < sz; ++i)
		{
			const Label &l = lbltbl->GetElement(i);
			l.Store(f);
		}

		// как посчитать контрольную сумму пока неясно.
		const long efp = ftell(f);
		hdr.nBlkLen = efp - fp - static_cast<long>(sizeof(hdr));
		fseek(f, fp, SEEK_SET);
		fwrite(&hdr, 1, sizeof(hdr), f); // скорректируем размер блока
		fseek(f, efp, SEEK_SET);
	}

	return true;
}

