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 "openmsx.hh"
5 #include "AlignedBuffer.hh"
6 #include "endian.hh"
7 #include <vector>
8 
9 namespace openmsx {
10 
11 class SectorAccessibleDisk;
12 
13 struct MSXBootSector {
14  byte jumpCode[3]; // + 0 0xE5 to bootprogram
15  byte name[8]; // + 3
16  Endian::UA_L16 bpSector; // +11 bytes per sector (always 512)
17  byte spCluster; // +13 sectors per cluster (always 2)
18  Endian::L16 resvSectors; // +14 nb of non-data sectors (ex bootsector)
19  byte nrFats; // +16 nb of fats
20  Endian::UA_L16 dirEntries; // +17 max nb of files in root directory
21  Endian::UA_L16 nrSectors; // +19 nb of sectors on this disk
22  byte descriptor; // +21 media descriptor
23  Endian::L16 sectorsFat; // +22 sectors per FAT
24  Endian::L16 sectorsTrack; // +24 sectors per track
25  Endian::L16 nrSides; // +26 number of side
26  Endian::L16 hiddenSectors; // +28 not used
27  byte pad1[9]; // +30
29  byte pad2[512-43]; // +43
30 };
31 static_assert(sizeof(MSXBootSector) == 512, "must be size 512");
32 
33 struct MSXDirEntry {
34  static const byte ATT_REGULAR = 0x00; // Normal file
35  static const byte ATT_READONLY = 0x01; // Read-Only file
36  static const byte ATT_HIDDEN = 0x02; // Hidden file
37  static const byte ATT_SYSTEM = 0x04; // System file
38  static const byte ATT_VOLUME = 0x08; // filename is Volume Label
39  static const byte ATT_DIRECTORY = 0x10; // entry is a subdir
40  static const byte ATT_ARCHIVE = 0x20; // Archive bit
41 
42  union {
43  struct {
44  char base[8];// + 0
45  char ext [3];// + 8
46  } name;
47  char filename[8 + 3];// + 0
48  };
49  byte attrib; // +11
50  byte reserved[10]; // +12 unused
51  Endian::L16 time; // +22
52  Endian::L16 date; // +24
54  Endian::L32 size; // +28
55 };
56 static_assert(sizeof(MSXDirEntry) == 32, "must be size 32");
57 
58 // Note: can't use Endian::L32 for 'start' and 'size' because the Partition
59 // struct itself is not 4-bytes aligned.
60 struct Partition {
61  byte boot_ind; // + 0 0x80 - active
62  byte head; // + 1 starting head
63  byte sector; // + 2 tarting sector
64  byte cyl; // + 3 starting cylinder
65  byte sys_ind; // + 4 what partition type
66  byte end_head; // + 5 end head
67  byte end_sector; // + 6 end sector
68  byte end_cyl; // + 7 end cylinder
69  Endian::UA_L32 start; // + 8 starting sector counting from 0
70  Endian::UA_L32 size; // +12 nr of sectors in partition
71 };
72 static_assert(sizeof(Partition) == 16, "must be size 16");
73 static_assert(alignof(Partition) == 1, "must not have alignment requirements");
74 
76  char header[11]; // + 0
77  char pad[3]; // + 3
78  Partition part[31]; // + 14,+30,..,+494 Not 4-byte aligned!!
79  Endian::L16 end; // +510
80 };
81 static_assert(sizeof(PartitionTable) == 512, "must be size 512");
82 
83 
84 // Buffer that can hold a (512-byte) disk sector.
85 // The main advantages of this type over something like 'byte buf[512]' are:
86 // - No need for reinterpret_cast<> when interpreting the data in a
87 // specific way (this could in theory cause alignment problems).
88 // - This type has a stricter alignment, so memcpy() and memset() can work
89 // faster compared to using a raw byte array.
90 union SectorBuffer {
91  byte raw[512]; // raw byte data
92  MSXBootSector bootSector; // interpreted as bootSector
93  MSXDirEntry dirEntry[16]; // interpreted as 16 dir entries
94  PartitionTable pt; // interpreted as Sunrise-IDE partition table
95  AlignedBuffer aligned; // force big alignment (for faster memcpy)
96 };
97 static_assert(sizeof(SectorBuffer) == 512, "must be size 512");
98 
99 
100 namespace DiskImageUtils {
101 
109  void checkValidPartition(SectorAccessibleDisk& disk, unsigned partition);
110 
113  void checkFAT12Partition(SectorAccessibleDisk& disk, unsigned partition);
114 
118 
124  void format(SectorAccessibleDisk& disk, bool dos1 = false);
125 
130  void partition(SectorAccessibleDisk& disk,
131  const std::vector<unsigned>& sizes);
132 };
133 
134 } // namespace openmsx
135 
136 #endif
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
Endian::UA_L32 start
Endian::L16 startCluster
MSXBootSector bootSector
Endian::UA_L16 dirEntries
bool hasPartitionTable(SectorAccessibleDisk &disk)
Check whether the given disk is partitioned.
Endian::UA_L16 bpSector
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
Endian::UA_L16 nrSectors
void partition(SectorAccessibleDisk &disk, const std::vector< unsigned > &sizes)
Write a partition table to the given disk and format each partition.
Endian::UA_L32 size
void format(SectorAccessibleDisk &disk, bool dos1)
Format the given disk (= a single partition).
void checkValidPartition(SectorAccessibleDisk &disk, unsigned partition)
Checks whether the disk is partitioned the specified partition exists throws a CommandException if on...
void checkFAT12Partition(SectorAccessibleDisk &disk, unsigned partition)
Like above, but also check whether partition is of type FAT12.