openMSX
Disk.cc
Go to the documentation of this file.
1 #include "Disk.hh"
2 #include "DiskExceptions.hh"
3 #include "one_of.hh"
4 
5 using std::string;
6 
7 namespace openmsx {
8 
10  : name(std::move(name_)), nbSides(0)
11 {
12 }
13 
14 void Disk::writeTrack(byte track, byte side, const RawTrack& input)
15 {
16  if (isWriteProtected()) {
18  }
19  writeTrackImpl(track, side, input);
20  flushCaches();
21 }
22 
24 {
25  if (!nbSides) {
27  }
28  return nbSides == 2;
29 }
30 
31 // Note: Special case to convert between logical/physical sector numbers
32 // for the boot sector and the 1st FAT sector (logical sector: 0/1,
33 // physical location: track 0, side 0, sector 1/2): perform this
34 // conversion without relying on the detected geometry parameters.
35 // Otherwise the detectGeometry() method (which itself reads these
36 // two sectors) would get in an infinite loop.
37 size_t Disk::physToLog(byte track, byte side, byte sector)
38 {
39  if ((track == 0) && (side == 0)) {
40  return sector - 1;
41  }
42  if (!nbSides) {
44  }
45  return sectorsPerTrack * (side + nbSides * track) + (sector - 1);
46 }
48 {
49  if (log <= 1) {
50  byte track = 0;
51  byte side = 0;
52  byte sector = byte(log + 1);
53  return {track, side, sector};
54  }
55  if (!nbSides) {
57  }
58  byte track = byte(log / (nbSides * sectorsPerTrack)); // TODO check for overflow
59  byte side = byte((log / sectorsPerTrack) % nbSides);
60  byte sector = byte((log % sectorsPerTrack) + 1);
61  return {track, side, sector};
62 }
63 
65 {
66  if (!nbSides) {
68  }
69  return sectorsPerTrack;
70 }
71 
72 void Disk::detectGeometryFallback() // if all else fails, use statistics
73 {
74  // TODO maybe also check for 8*80 for 8 sectors per track
75  sectorsPerTrack = 9; // most of the time (sorry 5.25" disk users...)
76  // 360k disks are likely to be single sided:
77  nbSides = (getNbSectors() == 720) ? 1 : 2;
78 }
79 
81 {
82  // From the MSX Red Book (p265):
83  //
84  // How to determine media types
85  //
86  // a) Read the boot sector (track 0, sector 1) of the target drive
87  //
88  // b) Check if the first byte is either 0E9H or 0EBH (the JMP
89  // instruction on 8086)
90  //
91  // c) If step b) fails, the disk is a version prior to MS-DOS 2.0;
92  // therefore, use the first byte of the FAT passed from the caller
93  // and make sure it is between 0F8h and 0FFh.
94  //
95  // If step c) is successful, use this as a media descriptor.
96  // If step c) fails, then this disk cannot be read.
97  //
98  // d) If step b) succeeds, read bytes # 0B to # 1D. This is the
99  // DPB for MS-DOS, Version 2.0 and above. The DPB for MSXDOS can
100  // be obtained as follows.
101  //
102  // ....
103  // +18 +19 Sectors per track
104  // +1A +1B Number of heads
105  // ...
106 
107  //
108  // Media Descriptor 0F8H 0F9H 0FAh 0FBH 0FCH 0FDH 0FEH 0FFH
109  // byte (FATID)
110  // Sectors/track 9 9 8 8 9 9 8 8
111  // No. of sides 1 2 1 2 1 2 1 2
112  // Tracks/side 80 80 80 80 40 40 40 40
113  // ...
114 
115  try {
116  SectorBuffer buf;
117  readSector(0, buf); // bootsector
118  if (buf.raw[0] == one_of(0xE9, 0xEB)) {
119  // use values from bootsector
120  sectorsPerTrack = buf.bootSector.sectorsTrack;
121  nbSides = buf.bootSector.nrSides;
122  if ((sectorsPerTrack == 0) || (sectorsPerTrack > 255) ||
123  (nbSides == 0) || (nbSides > 255)) {
124  // seems like bogus values, use defaults
126  }
127  } else {
128  readSector(1, buf); // 1st fat sector
129  byte mediaDescriptor = buf.raw[0];
130  if (mediaDescriptor >= 0xF8) {
131  sectorsPerTrack = (mediaDescriptor & 2) ? 8 : 9;
132  nbSides = (mediaDescriptor & 1) ? 2 : 1;
133  } else {
134  // invalid media descriptor, just assume it's a
135  // normal DS or SS DD disk
137  }
138  }
139  } catch (MSXException&) {
140  // read error, assume it's a 3.5" DS or SS DD disk
142  }
143 }
144 
145 } // namespace openmsx
one_of.hh
openmsx::SectorBuffer
Definition: DiskImageUtils.hh:90
openmsx::Disk::writeTrack
void writeTrack(byte track, byte side, const RawTrack &input)
Replace a full track in this image with the given track.
Definition: Disk.cc:14
Disk.hh
openmsx::MSXBootSector::sectorsTrack
Endian::L16 sectorsTrack
Definition: DiskImageUtils.hh:24
DiskExceptions.hh
openmsx::RawTrack
Definition: RawTrack.hh:62
openmsx::WriteProtectedException
Definition: DiskExceptions.hh:23
openmsx::SectorAccessibleDisk::isWriteProtected
bool isWriteProtected() const
Definition: SectorAccessibleDisk.cc:125
openmsx::SectorAccessibleDisk::readSector
void readSector(size_t sector, SectorBuffer &buf)
Definition: SectorAccessibleDisk.cc:18
openmsx::SectorAccessibleDisk::getNbSectors
size_t getNbSectors() const
Definition: SectorAccessibleDisk.cc:52
openmsx::Disk::isDoubleSided
bool isDoubleSided()
Definition: Disk.cc:23
openmsx::byte
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
openmsx::MSXBootSector::nrSides
Endian::L16 nrSides
Definition: DiskImageUtils.hh:25
openmsx::MSXException
Definition: MSXException.hh:10
openmsx::Disk::writeTrackImpl
virtual void writeTrackImpl(byte track, byte side, const RawTrack &input)=0
openmsx::Disk::logToPhys
TSS logToPhys(size_t log)
Definition: Disk.cc:47
openmsx::SectorBuffer::raw
byte raw[512]
Definition: DiskImageUtils.hh:91
openmsx::SectorBuffer::bootSector
MSXBootSector bootSector
Definition: DiskImageUtils.hh:92
openmsx::DiskName
Definition: DiskName.hh:9
openmsx::Disk::physToLog
size_t physToLog(byte track, byte side, byte sector)
Definition: Disk.cc:37
one_of
Definition: one_of.hh:7
openmsx::Disk::detectGeometryFallback
virtual void detectGeometryFallback()
Definition: Disk.cc:72
openmsx::SectorAccessibleDisk::flushCaches
virtual void flushCaches()
Definition: SectorAccessibleDisk.cc:146
openmsx::Disk::detectGeometry
virtual void detectGeometry()
Definition: Disk.cc:80
cstd::log
constexpr double log(double x)
Definition: cstd.hh:315
openmsx::Disk::getSectorsPerTrack
unsigned getSectorsPerTrack()
Definition: Disk.cc:64
openmsx::Disk::TSS
Definition: Disk.hh:30
openmsx::Disk::Disk
Disk(DiskName name)
Definition: Disk.cc:9
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5