1 // license:BSD-3-Clause
2 // copyright-holders:Sergey Svishchev
3 /**********************************************************************
4
5 formats/ds9_dsk.cpp
6
7 Floppies used by Agat-9 840KB controller
8
9 http://agatcomp.ru/Reading/docs/es5323.txt
10
11 https://github.com/sintech/AGAT/blob/master/docs/agat-840k-format.txt
12
13 http://www.torlus.com/floppy/forum/viewtopic.php?f=19&t=1385
14
15 ************************************************************************/
16
17 #include <cassert>
18
19 #include "formats/ds9_dsk.h"
20
21
FLOPPY_IDENTIFY(ds9_dsk_identify)22 static FLOPPY_IDENTIFY(ds9_dsk_identify)
23 {
24 switch (floppy_image_size(floppy))
25 {
26 case (80 * 2 * 21 * 256):
27 case 860164:
28 case 860288:
29 *vote = 100;
30 break;
31
32 default:
33 *vote = 0;
34 break;
35 }
36
37 return FLOPPY_ERROR_SUCCESS;
38 }
39
FLOPPY_CONSTRUCT(ds9_dsk_construct)40 static FLOPPY_CONSTRUCT(ds9_dsk_construct)
41 {
42 struct basicdsk_geometry geometry;
43 memset(&geometry, 0, sizeof(geometry));
44 geometry.heads = 2;
45 geometry.first_sector_id = 0;
46 geometry.sector_length = 256;
47 geometry.tracks = 80;
48 geometry.sectors = 21;
49 return basicdsk_construct(floppy, &geometry);
50 }
51
52 LEGACY_FLOPPY_OPTIONS_START( ds9 )
53 LEGACY_FLOPPY_OPTION( ds9_dsk, "ds9,dsk,raw", "Agat 840K DSK image",
54 ds9_dsk_identify, ds9_dsk_construct, nullptr, nullptr)
55 LEGACY_FLOPPY_OPTIONS_END
56
57 // exactly 6500 bytes
58 const floppy_image_format_t::desc_e ds9_format::ds9_desc[] = {
59 /* 01 */ { MFM, 0xaa, 32 }, // GAP1
60 /* 02 */ { SECTOR_LOOP_START, 0, 20 }, // 21 sectors
61 /* 03 */ { RAWBITS, 0x8924, 16 }, // sync mark: xA4, 2 us zero level interval, 0xFF
62 /* 04 */ { RAWBITS, 0x5555, 16 },
63 /* 05 */ { MFM, 0x95, 1 }, // address field prologue
64 /* 06 */ { MFM, 0x6a, 1 },
65 /* 07 */ { MFM, 0xfe, 1 }, // volume number
66 /* 08 */ { OFFSET_ID },
67 /* 09 */ { SECTOR_ID },
68 /* 10 */ { MFM, 0x5a, 1 }, // address field epilogue
69 /* 11 */ { MFM, 0xaa, 5 }, // GAP2 (min 4 bytes)
70 /* 12 */ { RAWBITS, 0x8924, 16 }, // sync mark
71 /* 13 */ { RAWBITS, 0x5555, 16 },
72 /* 14 */ { MFM, 0x6a, 1 }, // data field prologue
73 /* 15 */ { MFM, 0x95, 1 },
74 /* 16 */ { SECTOR_DATA_DS9, -1 },
75 /* 17 */ { MFM, 0x5a, 1 }, // data field epilogue
76 /* 18 */ { MFM, 0xaa, 33 }, // GAP3
77 /* 19 */ { SECTOR_LOOP_END },
78 /* 20 */ { END }
79 };
80
ds9_format()81 ds9_format::ds9_format()
82 {
83 }
84
name() const85 const char *ds9_format::name() const
86 {
87 return "a9dsk";
88 }
89
description() const90 const char *ds9_format::description() const
91 {
92 return "Agat-9 840K floppy image";
93 }
94
extensions() const95 const char *ds9_format::extensions() const
96 {
97 return "ds9";
98 }
99
find_size(io_generic * io,uint8_t & track_count,uint8_t & head_count,uint8_t & sector_count)100 void ds9_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count)
101 {
102 uint32_t expected_size = 0;
103 uint64_t size = io_generic_size(io);
104
105 head_count = 2;
106 track_count = 80;
107 sector_count = 21;
108 expected_size = 256 * track_count * head_count * sector_count;
109
110 if (size >= expected_size) // standard format has 860160 bytes
111 return;
112
113 track_count = head_count = sector_count = 0;
114 }
115
identify(io_generic * io,uint32_t form_factor)116 int ds9_format::identify(io_generic *io, uint32_t form_factor)
117 {
118 uint8_t track_count, head_count, sector_count;
119 find_size(io, track_count, head_count, sector_count);
120
121 if (track_count) return 50;
122
123 return 0;
124 }
125
load(io_generic * io,uint32_t form_factor,floppy_image * image)126 bool ds9_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
127 {
128 uint8_t track_count, head_count, sector_count;
129 find_size(io, track_count, head_count, sector_count);
130 if (track_count == 0) return false;
131
132 uint8_t sectdata[21 * 256];
133 desc_s sectors[21];
134 for (int i = 0; i < sector_count; i++)
135 {
136 sectors[i].data = sectdata + 256 * i;
137 sectors[i].size = 256;
138 sectors[i].sector_id = i;
139 }
140
141 int track_size = sector_count * 256;
142 for (int track = 0; track < track_count; track++)
143 {
144 for (int head = 0; head < head_count; head++)
145 {
146 io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size);
147 generate_track(ds9_desc, track, head, sectors, sector_count, 104000, image);
148 }
149 }
150
151 image->set_variant(floppy_image::DSQD);
152
153 return true;
154 }
155
156 const floppy_format_type FLOPPY_DS9_FORMAT = &floppy_image_format_creator<ds9_format>;
157