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
123
|
// 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
{
return "a9dsk";
}
const char *ds9_format::description() const
{
return "Agat-9 840K floppy image";
}
const char *ds9_format::extensions() const
{
return "ds9";
}
void ds9_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_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++)
{
size_t actual;
io.read_at((track * head_count + head) * track_size, sectdata, track_size, actual);
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;
|