<commit_before>// Copy-protected formats that require special support
//
// Contains detection and generation for each track format.
// Output will be in bitstream or flux format (or both),
// depending on the format requirements.

#include "SAMdisk.h"
#include "IBMPC.h"
#include "BitstreamTrackBuilder.h"
#include "FluxTrackBuilder.h"

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

bool IsEmptyTrack (const Track &track)
{
	return track.size() == 0;
}

TrackData GenerateEmptyTrack (const CylHead &cylhead, const Track &track)
{
	assert(IsEmptyTrack(track));
	(void)track;

	// Generate a DD track full of gap filler. It shouldn't really matter
	// which datarate and encoding as long as there are no sync marks.
	BitstreamTrackBuilder bitbuf(DataRate::_250K, Encoding::MFM);
	bitbuf.addBlock(0x4e, 6250);

	return TrackData(cylhead, std::move(bitbuf.buffer()));
}

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

// KBI-19 protection for CPC? (19 valid sectors)
bool IsKBI19Track (const Track &track)
{
	static const uint8_t ids[]{ 0,1,4,7,10,13,16,2,5,8,11,14,17,3,6,9,12,15,18 };

	if (track.size() != arraysize(ids))
		return false;

	int idx = 0;
	for (auto &s : track.sectors())
	{
		if (s.datarate != DataRate::_250K || s.encoding != Encoding::MFM ||
			s.header.sector != ids[idx++] || s.size() != 512 || !s.has_good_data())
			return false;
	}

	if (opt.debug) util::cout << "detected KBI-19 track\n";
	return true;
}

TrackData GenerateKBI19Track (const CylHead &cylhead, const Track &track)
{
	assert(IsKBI19Track(track));

	static const Data gap2_sig{ 0x20,0x4B,0x42,0x49,0x20 };	// " KBI "
	BitstreamTrackBuilder bitbuf(DataRate::_250K, Encoding::MFM);

	// Track start with slightly shorter gap4a.
	bitbuf.addGap(64);
	bitbuf.addIAM();
	bitbuf.addGap(50);<commit_msg>Extended KBI-19 to support 20-sector PC variant<commit_after>// Copy-protected formats that require special support
//
// Contains detection and generation for each track format.
// Output will be in bitstream or flux format (or both),
// depending on the format requirements.

#include "SAMdisk.h"
#include "IBMPC.h"
#include "BitstreamTrackBuilder.h"
#include "FluxTrackBuilder.h"

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

bool IsEmptyTrack (const Track &track)
{
	return track.size() == 0;
}

TrackData GenerateEmptyTrack (const CylHead &cylhead, const Track &track)
{
	assert(IsEmptyTrack(track));
	(void)track;

	// Generate a DD track full of gap filler. It shouldn't really matter
	// which datarate and encoding as long as there are no sync marks.
	BitstreamTrackBuilder bitbuf(DataRate::_250K, Encoding::MFM);
	bitbuf.addBlock(0x4e, 6250);

	return TrackData(cylhead, std::move(bitbuf.buffer()));
}

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

// KBI-19 protection (19 valid sectors on CPC+PC, plus 1 error sector on PC)
bool IsKBI19Track (const Track &track)
{
	static const uint8_t ids[]{ 0,1,4,7,10,13,16,2,5,8,11,14,17,3,6,9,12,15,18,19 };

	// CPC version has 19 sectors, PC version has 20 (with bad sector 19).
	if (track.size() != arraysize(ids) && track.size() != arraysize(ids) - 1)
		return false;

	int idx = 0;
	for (auto &s : track.sectors())
	{
		if (s.datarate != DataRate::_250K || s.encoding != Encoding::MFM ||
			s.header.sector != ids[idx++] || s.size() != 512 ||
			(!s.has_good_data() && s.header.sector != 19))
			return false;
	}

	if (opt.debug) util::cout << "detected KBI-19 track\n";
	return true;
}

TrackData GenerateKBI19Track (const CylHead &cylhead, const Track &track)
{
	assert(IsKBI19Track(track));

	static const Data gap2_sig{ 0x20,0x4B,0x42,0x49,0x20 };	// " KBI "
	BitstreamTrackBuilder bitbuf(DataRate::_250K, Encoding::MFM);

	// Track start with slightly shorter gap4a.
	bitbuf.addGap(64);
	bitbuf.addIAM();
	bitbuf.addGap(50);
{'fraction_non_alphanumeric': 0.21324469445154692, 'fraction_numerical': 0.045512656609562774, 'mean_word_length': 3.075, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1963512', 'n_tokens_mistral': 1424, 'n_tokens_neox': 1292, 'n_words': 357}