openMSX
DirAsDSK.hh
Go to the documentation of this file.
1 #ifndef DIRASDSK_HH
2 #define DIRASDSK_HH
3 
4 #include "SectorBasedDisk.hh"
5 #include "DiskImageUtils.hh"
6 #include "FileOperations.hh"
7 #include "EmuTime.hh"
8 #include "hash_map.hh"
9 
10 namespace openmsx {
11 
12 class DiskChanger;
13 class CliComm;
14 
15 class DirAsDSK final : public SectorBasedDisk
16 {
17 public:
20 
21 public:
22  DirAsDSK(DiskChanger& diskChanger, CliComm& cliComm,
23  const Filename& hostDir, SyncMode syncMode,
24  BootSectorType bootSectorType);
25 
26  // SectorBasedDisk
27  void readSectorImpl (size_t sector, SectorBuffer& buf) override;
28  void writeSectorImpl(size_t sector, const SectorBuffer& buf) override;
29  bool isWriteProtectedImpl() const override;
30  void checkCaches() override;
31 
32 private:
33  struct DirIndex {
34  DirIndex() = default;
35  DirIndex(unsigned sector_, unsigned idx_)
36  : sector(sector_), idx(idx_) {}
37  friend bool operator==(const DirIndex& x, const DirIndex& y) {
38  return (x.sector == y.sector) &&
39  (x.idx == y.idx);
40  }
41  unsigned sector;
42  unsigned idx;
43  };
44  struct HashDirIndex {
45  auto operator()(const DirIndex& d) const {
46  std::hash<unsigned> subHasher;
47  return 31 * subHasher(d.sector)
48  + subHasher(d.idx);
49  }
50  };
51  struct MapDir {
52  std::string hostName; // path relative to 'hostDir'
53  // The following two are used to detect changes in the host
54  // file compared to the last host->virtual-disk sync.
55  time_t mtime; // Modification time of host file at the time of
56  // the last sync.
57  size_t filesize; // Host file size, normally the same as msx
58  // filesize, except when the host file was
59  // truncated.
60  };
61 
62  SectorBuffer* fat();
63  SectorBuffer* fat2();
64  MSXDirEntry& msxDir(DirIndex dirIndex);
65  void writeFATSector (unsigned sector, const SectorBuffer& buf);
66  void writeDIRSector (unsigned sector, DirIndex dirDirIndex,
67  const SectorBuffer& buf);
68  void writeDataSector(unsigned sector, const SectorBuffer& buf);
69  void writeDIREntry(DirIndex dirIndex, DirIndex dirDirIndex,
70  const MSXDirEntry& newEntry);
71  void syncWithHost();
72  void checkDeletedHostFiles();
73  void deleteMSXFile(DirIndex dirIndex);
74  void deleteMSXFilesInDir(unsigned msxDirSector);
75  void freeFATChain(unsigned cluster);
76  void addNewHostFiles(const std::string& hostSubDir, unsigned msxDirSector);
77  void addNewDirectory(const std::string& hostSubDir, const std::string& hostName,
78  unsigned msxDirSector, FileOperations::Stat& fst);
79  void addNewHostFile(const std::string& hostSubDir, const std::string& hostName,
80  unsigned msxDirSector, FileOperations::Stat& fst);
81  DirIndex fillMSXDirEntry(
82  const std::string& hostSubDir, const std::string& hostName,
83  unsigned msxDirSector);
84  DirIndex getFreeDirEntry(unsigned msxDirSector);
85  DirIndex findHostFileInDSK(const std::string& hostName);
86  bool checkFileUsedInDSK(const std::string& hostName);
87  unsigned nextMsxDirSector(unsigned sector);
88  bool checkMSXFileExists(const std::string& msxfilename,
89  unsigned msxDirSector);
90  void checkModifiedHostFiles();
91  void setMSXTimeStamp(DirIndex dirIndex, FileOperations::Stat& fst);
92  void importHostFile(DirIndex dirIndex, FileOperations::Stat& fst);
93  void exportToHost(DirIndex dirIndex, DirIndex dirDirIndex);
94  void exportToHostDir (DirIndex dirIndex, const std::string& hostName);
95  void exportToHostFile(DirIndex dirIndex, const std::string& hostName);
96  unsigned findNextFreeCluster(unsigned cluster);
97  unsigned findFirstFreeCluster();
98  unsigned getFreeCluster();
99  unsigned readFAT(unsigned cluster);
100  void writeFAT12(unsigned cluster, unsigned val);
101  void exportFileFromFATChange(unsigned cluster, SectorBuffer* oldFAT);
102  unsigned getChainStart(unsigned cluster, unsigned& chainLength);
103  bool isDirSector(unsigned sector, DirIndex& dirDirIndex);
104  bool getDirEntryForCluster(unsigned cluster,
105  DirIndex& dirIndex, DirIndex& dirDirIndex);
106  DirIndex getDirEntryForCluster(unsigned cluster);
107  void unmapHostFiles(unsigned msxDirSector);
108  template<typename FUNC> bool scanMsxDirs(
109  FUNC func, unsigned msxDirSector);
110  friend struct NullScanner;
111  friend struct DirScanner;
112  friend struct IsDirSector;
113  friend struct DirEntryForCluster;
114  friend struct UnmapHostFiles;
115 
116  // internal helper functions
117  unsigned readFATHelper(const SectorBuffer* fat, unsigned cluster) const;
118  void writeFATHelper(SectorBuffer* fat, unsigned cluster, unsigned val) const;
119  unsigned clusterToSector(unsigned cluster) const;
120  void sectorToCluster(unsigned sector, unsigned& cluster, unsigned& offset) const;
121  unsigned sectorToCluster(unsigned sector) const;
122 
123 private:
124  DiskChanger& diskChanger; // used to query time / report disk change
125  CliComm& cliComm; // TODO don't use CliComm to report errors/warnings
126  const std::string hostDir;
127  const SyncMode syncMode;
128 
129  EmuTime lastAccess; // last time there was a sector read/write
130 
131  // For each directory entry that has a mapped host file/directory we
132  // store the name, last modification time and size of the corresponding
133  // host file/dir.
135  MapDirs mapDirs;
136 
137  // format parameters which depend on single/double sided
138  // varying root parameters
139  const unsigned nofSectors;
140  const unsigned nofSectorsPerFat;
141  // parameters that depend on these and thus also vary
142  const unsigned firstSector2ndFAT;
143  const unsigned firstDirSector;
144  const unsigned firstDataSector;
145  const unsigned maxCluster; // First cluster number that can NOT be used anymore.
146 
147  // Storage for the whole virtual disk.
148  std::vector<SectorBuffer> sectors;
149 };
150 
151 } // namespace openmsx
152 
153 #endif
constexpr bool operator==(const optional< T > &x, const optional< T > &y)
Definition: optional.hh:503
Abstract class for disk images that only represent the logical sector information (so not the raw tra...
DirAsDSK(DiskChanger &diskChanger, CliComm &cliComm, const Filename &hostDir, SyncMode syncMode, BootSectorType bootSectorType)
Definition: DirAsDSK.cc:260
void writeSectorImpl(size_t sector, const SectorBuffer &buf) override
Definition: DirAsDSK.cc:890
This class represents a filename.
Definition: Filename.hh:17
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void checkCaches() override
Definition: DirAsDSK.cc:332
void readSectorImpl(size_t sector, SectorBuffer &buf) override
Definition: DirAsDSK.cc:350
bool isWriteProtectedImpl() const override
Definition: DirAsDSK.cc:327