openMSX
DiskImageUtils.hh
Go to the documentation of this file.
1#ifndef DISK_IMAGE_UTILS_HH
2#define DISK_IMAGE_UTILS_HH
3
4#include "AlignedBuffer.hh"
5#include "endian.hh"
6#include "ranges.hh"
7#include <array>
8#include <span>
9#include <string>
10
11namespace openmsx {
12
13class SectorAccessibleDisk;
14
15enum class MSXBootSectorType : int {
16 DOS1 = 0,
17 DOS2 = 1,
18 NEXTOR = 2,
19};
20
22 std::array<uint8_t, 3> jumpCode; // + 0 0xE5 to boot program
23 std::array<uint8_t, 8> name; // + 3
24 Endian::UA_L16 bpSector; // +11 bytes per sector (always 512)
25 uint8_t spCluster; // +13 sectors per cluster
26 Endian::L16 resvSectors; // +14 nb of non-data sectors (incl boot sector)
27 uint8_t nrFats; // +16 nb of fats
28 Endian::UA_L16 dirEntries; // +17 max nb of files in root directory
29 Endian::UA_L16 nrSectors; // +19 nb of sectors on this disk (< 65536)
30 uint8_t descriptor; // +21 media descriptor
31 Endian::L16 sectorsFat; // +22 sectors per FAT
32 Endian::L16 sectorsTrack; // +24 sectors per track (0 for LBA volumes)
33 Endian::L16 nrSides; // +26 number of sides (heads) (0 for LBA volumes)
34 union {
35 struct {
36 Endian::L16 hiddenSectors; // +28 not used
37 std::array<uint8_t, 512-30> pad; // +30
39 struct {
40 Endian::L16 hiddenSectors; // +28 not used
41 std::array<uint8_t, 9> pad1; // +30
43 std::array<uint8_t, 512-43> pad2; // +43
45 struct {
46 Endian::L32 hiddenSectors; // +28 not used
47 Endian::L32 nrSectors; // +32 nb of sectors on this disk (>= 65536)
48 uint8_t physicalDriveNum; // +36
49 uint8_t reserved; // +37
50 uint8_t extendedBootSignature; // +38
52 std::array<uint8_t, 11> volumeLabel; // +43
53 std::array<uint8_t, 8> fileSystemType; // +54
54 std::array<uint8_t, 512-62> padding; // +62
57};
58static_assert(sizeof(MSXBootSector) == 512);
59
61 enum Attrib : uint8_t {
62 REGULAR = 0x00, // Normal file
63 READONLY = 0x01, // Read-Only file
64 HIDDEN = 0x02, // Hidden file
65 SYSTEM = 0x04, // System file
66 VOLUME = 0x08, // filename is Volume Label
67 DIRECTORY = 0x10, // entry is a subdir
68 ARCHIVE = 0x20, // Archive bit
69 };
70
71 std::array<char, 8 + 3> filename; // + 0
72 uint8_t attrib; // +11
73 std::array<uint8_t, 10> reserved; // +12 unused
78
79 [[nodiscard]] auto base() const { return subspan<8>(filename, 0); }
80 [[nodiscard]] auto ext () const { return subspan<3>(filename, 8); }
81
82 bool operator==(const MSXDirEntry& other) const = default;
83};
84static_assert(sizeof(MSXDirEntry) == 32);
85
86// Note: can't use Endian::L32 for 'start' and 'size' because the Partition
87// struct itself is not 4-bytes aligned.
88struct Partition {
89 uint8_t boot_ind; // + 0 0x80 - active
90 uint8_t head; // + 1 starting head
91 uint8_t sector; // + 2 starting sector
92 uint8_t cyl; // + 3 starting cylinder
93 uint8_t sys_ind; // + 4 what partition type
94 uint8_t end_head; // + 5 end head
95 uint8_t end_sector; // + 6 end sector
96 uint8_t end_cyl; // + 7 end cylinder
97 Endian::UA_L32 start; // + 8 starting sector counting from 0
98 Endian::UA_L32 size; // +12 nr of sectors in partition
99};
100static_assert(sizeof(Partition) == 16);
101static_assert(alignof(Partition) == 1, "must not have alignment requirements");
102
104 std::array<char, 11> header; // + 0
105 std::array<char, 3> pad; // + 3
106 std::array<Partition, 31> part; // + 14,+30,..,+494 Not 4-byte aligned!!
108};
109static_assert(sizeof(PartitionTableSunrise) == 512);
110
112 std::array<char, 11> header; // + 0
113 std::array<char, 435> pad; // + 3
114 std::array<Partition, 4> part; // +446,+462,+478,+494 Not 4-byte aligned!!
116};
117static_assert(sizeof(PartitionTableNextor) == 512);
118
119
120// Buffer that can hold a (512-byte) disk sector.
121// The main advantages of this type over something like 'byte buf[512]' are:
122// - No need for reinterpret_cast<> when interpreting the data in a
123// specific way (this could in theory cause alignment problems).
124// - This type has a stricter alignment, so memcpy() and memset() can work
125// faster compared to using a raw byte array.
127 std::array<uint8_t, 512> raw; // raw byte data
128 MSXBootSector bootSector; // interpreted as bootSector
129 std::array<MSXDirEntry, 16> dirEntry; // interpreted as 16 dir entries
130 PartitionTableSunrise ptSunrise; // interpreted as Sunrise-IDE partition table
131 PartitionTableNextor ptNextor; // interpreted as Nextor partition table
132 AlignedBuffer aligned; // force big alignment (for faster memcpy)
133};
134static_assert(sizeof(SectorBuffer) == 512);
135
136
137namespace DiskImageUtils {
138
149
153
156 [[nodiscard]] bool hasPartitionTable(SectorAccessibleDisk& disk);
157
163 void format(SectorAccessibleDisk& disk, MSXBootSectorType bootType);
164 void format(SectorAccessibleDisk& disk, MSXBootSectorType bootType, size_t nbSectors);
165
171 unsigned partition(SectorAccessibleDisk& disk,
172 std::span<const unsigned> sizes, MSXBootSectorType bootType);
173
174 struct FatTimeDate {
175 uint16_t time, date;
176 };
177 FatTimeDate toTimeDate(time_t totalSeconds);
178 time_t fromTimeDate(FatTimeDate timeDate);
179
180 [[nodiscard]] std::string formatAttrib(uint8_t attrib);
181};
182
183} // namespace openmsx
184
185#endif
bool hasPartitionTable(SectorAccessibleDisk &disk)
Check whether the given disk is partitioned.
void checkSupportedPartition(SectorAccessibleDisk &disk, unsigned partition)
Check whether partition is of type FAT12 or FAT16.
Partition & getPartition(SectorAccessibleDisk &disk, unsigned partition, SectorBuffer &buf)
Gets the requested partition.
std::string formatAttrib(uint8_t attrib)
void format(SectorAccessibleDisk &disk, MSXBootSectorType bootType)
Format the given disk (= a single partition).
time_t fromTimeDate(FatTimeDate timeDate)
unsigned partition(SectorAccessibleDisk &disk, std::span< const unsigned > sizes, MSXBootSectorType bootType)
Write a partition table to the given disk and format each partition.
FatTimeDate toTimeDate(time_t totalSeconds)
This file implemented 3 utility functions:
Definition Autofire.cc:9
std::array< uint8_t, 512-30 > pad
struct openmsx::MSXBootSector::@1::@2 dos1
struct openmsx::MSXBootSector::@1::@4 extended
struct openmsx::MSXBootSector::@1::@3 dos2
std::array< uint8_t, 3 > jumpCode
std::array< uint8_t, 8 > fileSystemType
std::array< uint8_t, 8 > name
std::array< uint8_t, 11 > volumeLabel
Endian::UA_L16 dirEntries
union openmsx::MSXBootSector::@1 params
std::array< uint8_t, 512-62 > padding
std::array< uint8_t, 512-43 > pad2
std::array< uint8_t, 9 > pad1
std::array< uint8_t, 10 > reserved
bool operator==(const MSXDirEntry &other) const =default
std::array< char, 8+3 > filename
std::array< char, 435 > pad
std::array< Partition, 4 > part
std::array< char, 11 > header
std::array< Partition, 31 > part
std::array< char, 11 > header
Endian::UA_L32 size
Endian::UA_L32 start
PartitionTableSunrise ptSunrise
std::array< uint8_t, 512 > raw
std::array< MSXDirEntry, 16 > dirEntry
PartitionTableNextor ptNextor