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
10namespace openmsx {
11
12class SectorAccessibleDisk;
13
15 DOS1,
16 DOS2,
17 NEXTOR
18};
19
21 std::array<uint8_t, 3> jumpCode; // + 0 0xE5 to boot program
22 std::array<uint8_t, 8> name; // + 3
23 Endian::UA_L16 bpSector; // +11 bytes per sector (always 512)
24 uint8_t spCluster; // +13 sectors per cluster
25 Endian::L16 resvSectors; // +14 nb of non-data sectors (incl boot sector)
26 uint8_t nrFats; // +16 nb of fats
27 Endian::UA_L16 dirEntries; // +17 max nb of files in root directory
28 Endian::UA_L16 nrSectors; // +19 nb of sectors on this disk (< 65536)
29 uint8_t descriptor; // +21 media descriptor
30 Endian::L16 sectorsFat; // +22 sectors per FAT
31 Endian::L16 sectorsTrack; // +24 sectors per track (0 for LBA volumes)
32 Endian::L16 nrSides; // +26 number of sides (heads) (0 for LBA volumes)
33 union {
34 struct {
35 Endian::L16 hiddenSectors; // +28 not used
36 std::array<uint8_t, 512-30> pad; // +30
38 struct {
39 Endian::L16 hiddenSectors; // +28 not used
40 std::array<uint8_t, 9> pad1; // +30
42 std::array<uint8_t, 512-43> pad2; // +43
44 struct {
45 Endian::L32 hiddenSectors; // +28 not used
46 Endian::L32 nrSectors; // +32 nb of sectors on this disk (>= 65536)
47 uint8_t physicalDriveNum; // +36
48 uint8_t reserved; // +37
49 uint8_t extendedBootSignature; // +38
51 std::array<uint8_t, 11> volumeLabel; // +43
52 std::array<uint8_t, 8> fileSystemType; // +54
53 std::array<uint8_t, 512-62> padding; // +62
56};
57static_assert(sizeof(MSXBootSector) == 512);
58
60 static constexpr uint8_t ATT_REGULAR = 0x00; // Normal file
61 static constexpr uint8_t ATT_READONLY = 0x01; // Read-Only file
62 static constexpr uint8_t ATT_HIDDEN = 0x02; // Hidden file
63 static constexpr uint8_t ATT_SYSTEM = 0x04; // System file
64 static constexpr uint8_t ATT_VOLUME = 0x08; // filename is Volume Label
65 static constexpr uint8_t ATT_DIRECTORY = 0x10; // entry is a subdir
66 static constexpr uint8_t ATT_ARCHIVE = 0x20; // Archive bit
67
68 std::array<char, 8 + 3> filename; // + 0
69 uint8_t attrib; // +11
70 std::array<uint8_t, 10> reserved; // +12 unused
75
76 [[nodiscard]] auto base() const { return subspan<8>(filename, 0); }
77 [[nodiscard]] auto ext () const { return subspan<3>(filename, 8); }
78
79 bool operator==(const MSXDirEntry& other) const = default;
80};
81static_assert(sizeof(MSXDirEntry) == 32);
82
83// Note: can't use Endian::L32 for 'start' and 'size' because the Partition
84// struct itself is not 4-bytes aligned.
85struct Partition {
86 uint8_t boot_ind; // + 0 0x80 - active
87 uint8_t head; // + 1 starting head
88 uint8_t sector; // + 2 starting sector
89 uint8_t cyl; // + 3 starting cylinder
90 uint8_t sys_ind; // + 4 what partition type
91 uint8_t end_head; // + 5 end head
92 uint8_t end_sector; // + 6 end sector
93 uint8_t end_cyl; // + 7 end cylinder
94 Endian::UA_L32 start; // + 8 starting sector counting from 0
95 Endian::UA_L32 size; // +12 nr of sectors in partition
96};
97static_assert(sizeof(Partition) == 16);
98static_assert(alignof(Partition) == 1, "must not have alignment requirements");
99
101 std::array<char, 11> header; // + 0
102 std::array<char, 3> pad; // + 3
103 std::array<Partition, 31> part; // + 14,+30,..,+494 Not 4-byte aligned!!
105};
106static_assert(sizeof(PartitionTableSunrise) == 512);
107
109 std::array<char, 11> header; // + 0
110 std::array<char, 435> pad; // + 3
111 std::array<Partition, 4> part; // +446,+462,+478,+494 Not 4-byte aligned!!
113};
114static_assert(sizeof(PartitionTableNextor) == 512);
115
116
117// Buffer that can hold a (512-byte) disk sector.
118// The main advantages of this type over something like 'byte buf[512]' are:
119// - No need for reinterpret_cast<> when interpreting the data in a
120// specific way (this could in theory cause alignment problems).
121// - This type has a stricter alignment, so memcpy() and memset() can work
122// faster compared to using a raw byte array.
124 std::array<uint8_t, 512> raw; // raw byte data
125 MSXBootSector bootSector; // interpreted as bootSector
126 std::array<MSXDirEntry, 16> dirEntry; // interpreted as 16 dir entries
127 PartitionTableSunrise ptSunrise; // interpreted as Sunrise-IDE partition table
128 PartitionTableNextor ptNextor; // interpreted as Nextor partition table
129 AlignedBuffer aligned; // force big alignment (for faster memcpy)
130};
131static_assert(sizeof(SectorBuffer) == 512);
132
133
134namespace DiskImageUtils {
135
146
150
153 [[nodiscard]] bool hasPartitionTable(SectorAccessibleDisk& disk);
154
160 void format(SectorAccessibleDisk& disk, MSXBootSectorType bootType);
161 void format(SectorAccessibleDisk& disk, MSXBootSectorType bootType, size_t nbSectors);
162
168 unsigned partition(SectorAccessibleDisk& disk,
169 std::span<const unsigned> sizes, MSXBootSectorType bootType);
170};
171
172} // namespace openmsx
173
174#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.
void format(SectorAccessibleDisk &disk, MSXBootSectorType bootType)
Format the given disk (= a single partition).
unsigned partition(SectorAccessibleDisk &disk, std::span< const unsigned > sizes, MSXBootSectorType bootType)
Write a partition table to the given disk and format each partition.
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
Endian::UA_L16 bpSector
union openmsx::MSXBootSector::@1 params
Endian::UA_L16 nrSectors
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
static constexpr uint8_t ATT_READONLY
static constexpr uint8_t ATT_SYSTEM
static constexpr uint8_t ATT_VOLUME
Endian::L16 startCluster
bool operator==(const MSXDirEntry &other) const =default
static constexpr uint8_t ATT_ARCHIVE
static constexpr uint8_t ATT_REGULAR
static constexpr uint8_t ATT_DIRECTORY
std::array< char, 8+3 > filename
static constexpr uint8_t ATT_HIDDEN
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
MSXBootSector bootSector
std::array< MSXDirEntry, 16 > dirEntry
PartitionTableNextor ptNextor