summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/ds9_dsk.cpp
blob: c0cbf0dccbccdcaed08234e075d29c9c9d15fdc0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// license:BSD-3-Clause
// copyright-holders:Sergey Svishchev
/**********************************************************************

    formats/ds9_dsk.cpp

    Floppies used by Agat-9 840KB controller

    http://agatcomp.ru/Reading/docs/es5323.txt

    https://github.com/sintech/AGAT/blob/master/docs/agat-840k-format.txt

    http://www.torlus.com/floppy/forum/viewtopic.php?f=19&t=1385

************************************************************************/

#include "formats/ds9_dsk.h"

#include "ioprocs.h"

#include <cstring>


// exactly 6500 bytes
const floppy_image_format_t::desc_e ds9_format::ds9_desc[] = {
	/* 01 */ { MFM, 0xaa, 32 },             // GAP1
	/* 02 */ { SECTOR_LOOP_START, 0, 20 },  // 21 sectors
	/* 03 */ {   RAWBITS, 0x8924, 16 },     // sync mark: xA4, 2 us zero level interval, 0xFF
	/* 04 */ {   RAWBITS, 0x5555, 16 },
	/* 05 */ {   MFM, 0x95, 1 },            // address field prologue
	/* 06 */ {   MFM, 0x6a, 1 },
	/* 07 */ {   MFM, 0xfe, 1 },            // volume number
	/* 08 */ {   OFFSET_ID },
	/* 09 */ {   SECTOR_ID },
	/* 10 */ {   MFM, 0x5a, 1 },            // address field epilogue
	/* 11 */ {   MFM, 0xaa, 5 },            // GAP2 (min 4 bytes)
	/* 12 */ {   RAWBITS, 0x8924, 16 },     // sync mark
	/* 13 */ {   RAWBITS, 0x5555, 16 },
	/* 14 */ {   MFM, 0x6a, 1 },            // data field prologue
	/* 15 */ {   MFM, 0x95, 1 },
	/* 16 */ {   SECTOR_DATA_DS9, -1 },
	/* 17 */ {   MFM, 0x5a, 1 },            // data field epilogue
	/* 18 */ {   MFM, 0xaa, 33 },           // GAP3
	/* 19 */ { SECTOR_LOOP_END },
	/* 20 */ { END }
};

ds9_format::ds9_format()
{
}

const char *ds9_format::name() const noexcept
{
	return "a9dsk";
}

const char *ds9_format::description() const noexcept
{
	return "Agat-9 840K floppy image";
}

const char *ds9_format::extensions() const noexcept
{
	return "ds9";
}

void ds9_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
	head_count = 2;
	track_count = 80;
	sector_count = 21;
	uint32_t const expected_size = 256 * track_count * head_count * sector_count;

	uint64_t size;
	if (!io.length(size) && (size >= expected_size)) // standard format has 860160 bytes
		return;

	track_count = head_count = sector_count = 0;
}

int ds9_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const
{
	uint8_t track_count, head_count, sector_count;
	find_size(io, track_count, head_count, sector_count);

	if (track_count)
		return FIFID_SIZE;

	return 0;
}

bool ds9_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const
{
	uint8_t track_count, head_count, sector_count;
	find_size(io, track_count, head_count, sector_count);
	if (track_count == 0) return false;

	uint8_t sectdata[21 * 256];
	desc_s sectors[21];
	for (int i = 0; i < sector_count; i++)
	{
		sectors[i].data = sectdata + 256 * i;
		sectors[i].size = 256;
		sectors[i].sector_id = i;
	}

	int track_size = sector_count * 256;
	for (int track = 0; track < track_count; track++)
	{
		for (int head = 0; head < head_count; head++)
		{
			/*auto const [err, actual] =*/ read_at(io, (track * head_count + head) * track_size, sectdata, track_size); // FIXME: check for errors and premature EOF
			generate_track(ds9_desc, track, head, sectors, sector_count, 104000, image);
		}
	}

	image.set_variant(floppy_image::DSQD);

	return true;
}

const ds9_format FLOPPY_DS9_FORMAT;