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