13 namespace DiskImageUtils {
17 static const char PARTAB_HEADER[11] = {
18 '\353',
'\376',
'\220',
'M',
'S',
'X',
'_',
'I',
'D',
'E',
' '
22 return memcmp(pt.
header, PARTAB_HEADER,
sizeof(PARTAB_HEADER)) == 0;
28 disk.
readSector(0, reinterpret_cast<byte*>(&pt));
29 return isPartitionTableSector(pt);
37 if (partition < 1 || partition > 31) {
39 "Invalid partition number specified (must be 1-31).");
42 disk.
readSector(0, reinterpret_cast<byte*>(&pt));
43 if (!isPartitionTableSector(pt)) {
44 throw CommandException(
45 "No (or invalid) partition table.");
51 "No partition number " << partition);
59 checkImpl(disk, partition, pt);
65 Partition& p = checkImpl(disk, partition, pt);
75 static void setBootSector(
MSXBootSector& boot,
size_t nbSectors,
76 unsigned& firstDataSector,
byte& descriptor)
80 memcpy(&boot, defaultBootBlock, SECTOR_SIZE);
84 byte nbReservedSectors = 1;
85 byte nbHiddenSectors = 1;
91 byte nbSectorsPerCluster;
96 if (nbSectors > 32732) {
101 nbSectorsPerFat = 12;
102 nbSectorsPerCluster = 16;
105 nbHiddenSectors = 16;
106 }
else if (nbSectors > 16388) {
110 nbSectorsPerFat = 12;
111 nbSectorsPerCluster = 8;
114 }
else if (nbSectors > 8212) {
118 nbSectorsPerFat = 12;
119 nbSectorsPerCluster = 4;
122 }
else if (nbSectors > 4126) {
126 nbSectorsPerFat = 12;
127 nbSectorsPerCluster = 2;
130 }
else if (nbSectors > 2880) {
135 nbSectorsPerCluster = 2;
138 }
else if (nbSectors > 1440) {
143 nbSectorsPerCluster = 2;
146 }
else if (nbSectors > 720) {
152 nbSectorsPerCluster = 2;
162 nbSectorsPerCluster = 2;
179 static bool init =
false;
182 srand(
unsigned(time(
nullptr)));
184 auto raw =
reinterpret_cast<byte*
>(&boot);
185 for (
int i = 0x27; i < 0x2B; ++i) {
186 raw[i] = rand() & 0x7F;
189 unsigned nbRootDirSectors = nbDirEntry / 16;
190 unsigned rootDirStart = 1 + nbFats * nbSectorsPerFat;
191 firstDataSector = rootDirStart + nbRootDirSectors;
199 unsigned firstDataSector;
201 setBootSector(boot, nbSectors, firstDataSector, descriptor);
202 disk.
writeSector(0, reinterpret_cast<byte*>(&boot));
205 byte buf[SECTOR_SIZE];
206 memset(buf, 0x00,
sizeof(buf));
207 for (
unsigned i = 2; i < firstDataSector; ++i) {
219 memset(buf, 0xE5,
sizeof(buf));
220 for (
size_t i = firstDataSector; i < nbSectors; ++i) {
225 static void logicalToCHS(
unsigned logical,
unsigned& cylinder,
226 unsigned& head,
unsigned& sector)
230 unsigned tmp = logical + 1;
232 if (sector == 0) sector = 32;
233 tmp = (tmp - sector) / 32;
240 assert(sizes.size() <= 31);
243 memset(&pt, 0,
sizeof(pt));
244 memcpy(pt.header, PARTAB_HEADER,
sizeof(PARTAB_HEADER));
248 unsigned partitionOffset = 1;
249 for (
unsigned i = 0; i < sizes.size(); ++i) {
250 unsigned partitionNbSectors = sizes[i];
251 auto& p = pt.part[30 - i];
252 unsigned startCylinder, startHead, startSector;
253 logicalToCHS(partitionOffset,
254 startCylinder, startHead, startSector);
255 unsigned endCylinder, endHead, endSector;
256 logicalToCHS(partitionOffset + partitionNbSectors - 1,
257 endCylinder, endHead, endSector);
258 p.boot_ind = (i == 0) ? 0x80 : 0x00;
260 p.sector = startSector;
261 p.cyl = startCylinder;
263 p.end_head = endHead;
264 p.end_sector = endSector;
265 p.end_cyl = endCylinder;
266 p.start = partitionOffset;
268 DiskPartition diskPartition(disk, partitionOffset, partitionNbSectors);
270 partitionOffset += partitionNbSectors;