From: <m97...@us...> - 2009-02-21 20:59:45
|
Revision: 8630 http://openmsx.svn.sourceforge.net/openmsx/?rev=8630&view=rev Author: m9710797 Date: 2009-02-21 20:59:32 +0000 (Sat, 21 Feb 2009) Log Message: ----------- Refactored Disk classes / support inserting disk partitions Modified Paths: -------------- openmsx/trunk/ChangeLog openmsx/trunk/src/fdc/DSKDiskImage.cc openmsx/trunk/src/fdc/DSKDiskImage.hh openmsx/trunk/src/fdc/DirAsDSK.cc openmsx/trunk/src/fdc/DirAsDSK.hh openmsx/trunk/src/fdc/Disk.cc openmsx/trunk/src/fdc/Disk.hh openmsx/trunk/src/fdc/DiskChanger.cc openmsx/trunk/src/fdc/DiskChanger.hh openmsx/trunk/src/fdc/DiskImageUtils.cc openmsx/trunk/src/fdc/DiskImageUtils.hh openmsx/trunk/src/fdc/DiskManipulator.cc openmsx/trunk/src/fdc/DummyDisk.cc openmsx/trunk/src/fdc/DummyDisk.hh openmsx/trunk/src/fdc/EmptyDiskPatch.cc openmsx/trunk/src/fdc/EmptyDiskPatch.hh openmsx/trunk/src/fdc/NowindInterface.cc openmsx/trunk/src/fdc/RamDSKDiskImage.cc openmsx/trunk/src/fdc/RamDSKDiskImage.hh openmsx/trunk/src/fdc/SectorAccessibleDisk.cc openmsx/trunk/src/fdc/SectorAccessibleDisk.hh openmsx/trunk/src/fdc/SectorBasedDisk.cc openmsx/trunk/src/fdc/SectorBasedDisk.hh openmsx/trunk/src/fdc/XSADiskImage.cc openmsx/trunk/src/fdc/XSADiskImage.hh openmsx/trunk/src/fdc/node.mk Added Paths: ----------- openmsx/trunk/src/fdc/DiskName.cc openmsx/trunk/src/fdc/DiskName.hh openmsx/trunk/src/fdc/DiskPartition.cc openmsx/trunk/src/fdc/DiskPartition.hh Removed Paths: ------------- openmsx/trunk/src/fdc/WriteProtectableDisk.hh Modified: openmsx/trunk/ChangeLog =================================================================== --- openmsx/trunk/ChangeLog 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/ChangeLog 2009-02-21 20:59:32 UTC (rev 8630) @@ -1,5 +1,21 @@ $Id$ +2009-02-21 Wouter Vermaelen <wou...@sc...> + * Refactored disk classes: + - simplified class hierarchy: + - removed virtual inheritance + - merged WriteProtectableDisk into SectorAccessibleDisk + - Disk now inherits from SectorAccessibleDisk, + ATM we don't support disk image formats that are lower level + than sector level. But even for those images it makes sense + to support reading/writing sectors. + - moved patch functionality up in the class hierarchy, + to SectorAccessibleDisk + * Added syntax to insert a partition of a hard disk image: + <hd-image>:<num> + This is a preparartion to support disk partitions in the nowind + interface. + 2009-02-11 Wouter Vermaelen <wou...@sc...> * Initial nowind implementation: still need to work on the nowind openmsx commands Modified: openmsx/trunk/src/fdc/DSKDiskImage.cc =================================================================== --- openmsx/trunk/src/fdc/DSKDiskImage.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DSKDiskImage.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -16,13 +16,13 @@ { } -void DSKDiskImage::readSectorSBD(unsigned sector, byte* buf) +void DSKDiskImage::readSectorImpl(unsigned sector, byte* buf) { file->seek(sector * SECTOR_SIZE); file->read(buf, SECTOR_SIZE); } -void DSKDiskImage::writeSectorSBD(unsigned sector, const byte* buf) +void DSKDiskImage::writeSectorImpl(unsigned sector, const byte* buf) { file->seek(sector * SECTOR_SIZE); file->write(buf, SECTOR_SIZE); Modified: openmsx/trunk/src/fdc/DSKDiskImage.hh =================================================================== --- openmsx/trunk/src/fdc/DSKDiskImage.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DSKDiskImage.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -17,8 +17,8 @@ virtual ~DSKDiskImage(); private: - virtual void readSectorSBD(unsigned sector, byte* buf); - virtual void writeSectorSBD(unsigned sector, const byte* buf); + virtual void readSectorImpl(unsigned sector, byte* buf); + virtual void writeSectorImpl(unsigned sector, const byte* buf); virtual bool isWriteProtectedImpl() const; const std::auto_ptr<File> file; Modified: openmsx/trunk/src/fdc/DirAsDSK.cc =================================================================== --- openmsx/trunk/src/fdc/DirAsDSK.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DirAsDSK.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -272,9 +272,9 @@ { } -void DirAsDSK::readSectorSBD(unsigned sector, byte* buf) +void DirAsDSK::readSectorImpl(unsigned sector, byte* buf) { - debug("DirAsDSK::readSectorSBD: %i ", sector); + debug("DirAsDSK::readSectorImpl: %i ", sector); switch (sector) { case 0: debug("boot sector\n"); break; @@ -602,12 +602,12 @@ } -void DirAsDSK::writeSectorSBD(unsigned sector, const byte* buf) +void DirAsDSK::writeSectorImpl(unsigned sector, const byte* buf) { // is this actually needed ? if (syncMode == GlobalSettings::SYNC_READONLY) return; - debug("DirAsDSK::writeSectorSBD: %i ", sector); + debug("DirAsDSK::writeSectorImpl: %i ", sector); switch (sector) { case 0: debug("boot sector\n"); break; Modified: openmsx/trunk/src/fdc/DirAsDSK.hh =================================================================== --- openmsx/trunk/src/fdc/DirAsDSK.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DirAsDSK.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -27,8 +27,8 @@ private: // SectorBasedDisk - virtual void readSectorSBD(unsigned sector, byte* buf); - virtual void writeSectorSBD(unsigned sector, const byte* buf); + virtual void readSectorImpl(unsigned sector, byte* buf); + virtual void writeSectorImpl(unsigned sector, const byte* buf); virtual bool isWriteProtectedImpl() const; struct MSXDirEntry { Modified: openmsx/trunk/src/fdc/Disk.cc =================================================================== --- openmsx/trunk/src/fdc/Disk.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/Disk.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -3,9 +3,11 @@ #include "Disk.hh" #include "DiskExceptions.hh" +using std::string; + namespace openmsx { -Disk::Disk(const Filename& name_) +Disk::Disk(const DiskName& name_) : name(name_), nbSides(0) { } @@ -14,7 +16,7 @@ { } -const Filename& Disk::getName() const +const DiskName& Disk::getName() const { return name; } @@ -64,16 +66,6 @@ return nbSides == 2; } -void Disk::applyPatch(const Filename& /*patchFile*/) -{ - throw MSXException("Patching of this disk image format not supported."); -} - -void Disk::getPatches(std::vector<Filename>& /*result*/) const -{ - // nothing -} - int Disk::physToLog(byte track, byte side, byte sector) { if ((track == 0) && (side == 0)) { @@ -112,10 +104,10 @@ void Disk::detectGeometryFallback() // if all else fails, use statistics { - // TODO maybe also check for 8*80*512 for 8 sectors per track + // TODO maybe also check for 8*80 for 8 sectors per track sectorsPerTrack = 9; // most of the time (sorry 5.25" disk users...) // 360k disks are likely to be single sided: - nbSides = (getImageSize() == (720 * 512)) ? 1 : 2; + nbSides = (getNbSectors() == 720) ? 1 : 2; } void Disk::detectGeometry() @@ -154,8 +146,8 @@ // ... try { - byte buf[512]; - read(0, 1, 0, 512, buf); + byte buf[SECTOR_SIZE]; + read(0, 1, 0, SECTOR_SIZE, buf); if ((buf[0] == 0xE9) || (buf[0] ==0xEB)) { // use values from bootsector sectorsPerTrack = buf[0x18] + 256 * buf[0x19]; @@ -166,7 +158,7 @@ detectGeometryFallback(); } } else { - read(0, 2, 0, 512, buf); + read(0, 2, 0, SECTOR_SIZE, buf); byte mediaDescriptor = buf[0]; if (mediaDescriptor >= 0xF8) { sectorsPerTrack = (mediaDescriptor & 2) ? 8 : 9; @@ -183,10 +175,5 @@ } } -int Disk::getImageSize() -{ - return 0; // by default we know nothing of the image size -} - } // namespace openmsx Modified: openmsx/trunk/src/fdc/Disk.hh =================================================================== --- openmsx/trunk/src/fdc/Disk.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/Disk.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -3,21 +3,20 @@ #ifndef DISK_HH #define DISK_HH -#include "WriteProtectableDisk.hh" -#include "Filename.hh" +#include "SectorAccessibleDisk.hh" +#include "DiskName.hh" #include "openmsx.hh" -#include <vector> namespace openmsx { -class Disk : public virtual WriteProtectableDisk +class Disk : public SectorAccessibleDisk { public: static const int RAWTRACK_SIZE = 6850; virtual ~Disk(); - const Filename& getName() const; + const DiskName& getName() const; virtual void read(byte track, byte sector, byte side, unsigned size, byte* buf) = 0; @@ -33,16 +32,12 @@ virtual bool isReady() const = 0; bool isDoubleSided() const; - virtual void applyPatch(const Filename& patchFile); - virtual void getPatches(std::vector<Filename>& result) const; - protected: - explicit Disk(const Filename& name); + explicit Disk(const DiskName& name); int physToLog(byte track, byte side, byte sector); void logToPhys(int log, byte& track, byte& side, byte& sector); virtual void detectGeometry(); - virtual int getImageSize(); void setSectorsPerTrack(unsigned num); void setNbSides(unsigned num); @@ -54,7 +49,7 @@ private: void detectGeometryFallback(); - const Filename name; + const DiskName name; unsigned sectorsPerTrack; unsigned nbSides; }; Modified: openmsx/trunk/src/fdc/DiskChanger.cc =================================================================== --- openmsx/trunk/src/fdc/DiskChanger.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DiskChanger.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -6,6 +6,7 @@ #include "XSADiskImage.hh" #include "DirAsDSK.hh" #include "DSKDiskImage.hh" +#include "DiskPartition.hh" #include "CommandController.hh" #include "Command.hh" #include "MSXEventDistributor.hh" @@ -98,7 +99,7 @@ return driveName; } -const Filename& DiskChanger::getDiskName() const +const DiskName& DiskChanger::getDiskName() const { return disk->getName(); } @@ -189,21 +190,46 @@ // first try XSA newDisk.reset(new XSADiskImage(filename)); } catch (MSXException& e) { + try { + // First try the fake disk, because a DSK will always + // succeed if diskImage can be resolved + // It is simply stat'ed, so even a directory name + // can be resolved and will be accepted as dsk name + // try to create fake DSK from a dir on host OS + newDisk.reset(new DirAsDSK( + controller.getCliComm(), + controller.getGlobalSettings(), + filename)); + } catch (MSXException& e) { + try { + // then try normal DSK + newDisk.reset(new DSKDiskImage(filename)); + } catch (MSXException& e1) { + // Finally try to interpret the filename as + // <filename>:<partition-number> + // Try this last because the ':' character could be + // part of the filename itself. So only try this if + // the name could not be interpreted as a valid + // filename. + string::size_type pos = diskImage.find_last_of(':'); + if (pos == string::npos) { + // does not contain ':', throw previous exception + throw; + } + shared_ptr<SectorAccessibleDisk> wholeDisk; try { - // First try the fake disk, because a DSK will always - // succeed if diskImage can be resolved - // It is simply stat'ed, so even a directory name - // can be resolved and will be accepted as dsk name - // try to create fake DSK from a dir on host OS - newDisk.reset(new DirAsDSK( - controller.getCliComm(), - controller.getGlobalSettings(), - filename)); + Filename file(diskImage.substr(0, pos)); + wholeDisk.reset(new DSKDiskImage(file)); } catch (MSXException& e) { - // then try normal DSK - newDisk.reset(new DSKDiskImage(filename)); + // If this fails we still prefer to show the + // previous error message, because it's most + // likely more descriptive. + throw e1; } - } + unsigned num = StringOp::stringToUint( + diskImage.substr(pos + 1)); + newDisk.reset(new DiskPartition(*wholeDisk, num, wholeDisk)); + }}} } for (unsigned i = 2; i < args.size(); ++i) { Filename filename(args[i]->getString(), controller); @@ -341,11 +367,25 @@ return disk ? disk->getSHA1Sum() : ""; } +// version 1: initial version +// version 2: replaced Filename with DiskName template<typename Archive> -void DiskChanger::serialize(Archive& ar, unsigned /*version*/) +void DiskChanger::serialize(Archive& ar, unsigned version) { - Filename diskname = disk->getName(); - ar.serializeNoID("disk", diskname); + DiskName diskname = disk->getName(); + if (version < 2) { + // there was no DiskName yet, just a plain Filename + assert(ar.isLoader()); + Filename filename; + ar.serializeNoID("disk", filename); + if (filename.getOriginal() == "ramdisk") { + diskname = DiskName(Filename(), "ramdisk"); + } else { + diskname = DiskName(filename, ""); + } + } else { + ar.serializeNoID("disk", diskname); + } vector<Filename> patches; if (!ar.isLoader()) { Modified: openmsx/trunk/src/fdc/DiskChanger.hh =================================================================== --- openmsx/trunk/src/fdc/DiskChanger.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DiskChanger.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -5,6 +5,7 @@ #include "DiskContainer.hh" #include "MSXEventListener.hh" +#include "serialize_meta.hh" #include "noncopyable.hh" #include <vector> #include <string> @@ -20,7 +21,7 @@ class Disk; class DiskCommand; class TclObject; -class Filename; +class DiskName; class DiskChanger : public DiskContainer, private MSXEventListener, private noncopyable @@ -37,7 +38,7 @@ void createCommand(); const std::string& getDriveName() const; - const Filename& getDiskName() const; + const DiskName& getDiskName() const; bool peekDiskChanged() const; Disk& getDisk(); @@ -74,6 +75,7 @@ bool diskChangedFlag; }; +SERIALIZE_CLASS_VERSION(DiskChanger, 2); } // namespace openmsx Modified: openmsx/trunk/src/fdc/DiskImageUtils.cc =================================================================== --- openmsx/trunk/src/fdc/DiskImageUtils.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DiskImageUtils.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -1,6 +1,7 @@ // $Id$ #include "DiskImageUtils.hh" +#include "DiskPartition.hh" #include "CommandException.hh" #include "StringOp.hh" #include "BootBlocks.hh" @@ -31,19 +32,6 @@ byte bootprogram[512-30];// actual bootprogram }; -struct Partition { - byte boot_ind; // 0x80 - active - byte head; // starting head - byte sector; // starting sector - byte cyl; // starting cylinder - byte sys_ind; // What partition type - byte end_head; // end head - byte end_sector; // end sector - byte end_cyl; // end cylinder - byte start4[4]; // starting sector counting from 0 - byte size4[4]; // nr of sectors in partition -}; - static inline void write16LE(byte* x, unsigned y) { x[0] = (y >> 0) & 0xFF; @@ -297,61 +285,5 @@ disk.writeSector(0, buf); } -std::auto_ptr<SectorAccessibleDisk> getPartition( - SectorAccessibleDisk& disk, unsigned partition) -{ - unsigned start, size; - if (partition == 0) { - start = 0; - size = disk.getNbSectors(); - } else { - #ifndef NDEBUG - try { - checkValidPartition(disk, partition); - } catch (MSXException& e) { - assert(false); - } - #endif - byte buf[SECTOR_SIZE]; - disk.readSector(0, buf); - Partition* p = reinterpret_cast<Partition*>( - &buf[14 + (31 - partition) * 16]); - start = read32LE(p->start4); - size = read32LE(p->size4); - } - return std::auto_ptr<SectorAccessibleDisk>( - new DiskPartition(disk, start, size)); -} - } // namespace DiskImageUtils - - -DiskPartition::DiskPartition(SectorAccessibleDisk& parent_, - unsigned start_, unsigned length_) - : parent(parent_) - , start(start_) - , length(length_) -{ -} - -void DiskPartition::readSectorImpl(unsigned sector, byte* buf) -{ - parent.readSector(start + sector, buf); -} - -void DiskPartition::writeSectorImpl(unsigned sector, const byte* buf) -{ - parent.writeSector(start + sector, buf); -} - -unsigned DiskPartition::getNbSectorsImpl() const -{ - return length; -} - -bool DiskPartition::isWriteProtectedImpl() const -{ - return parent.isWriteProtected(); -} - } // namespace openmsx Modified: openmsx/trunk/src/fdc/DiskImageUtils.hh =================================================================== --- openmsx/trunk/src/fdc/DiskImageUtils.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DiskImageUtils.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -3,14 +3,29 @@ #ifndef DISK_IMAGE_UTILS_HH #define DISK_IMAGE_UTILS_HH -#include "SectorAccessibleDisk.hh" +#include "openmsx.hh" #include <vector> #include <memory> namespace openmsx { +class SectorAccessibleDisk; + namespace DiskImageUtils { + struct Partition { + byte boot_ind; // 0x80 - active + byte head; // starting head + byte sector; // starting sector + byte cyl; // starting cylinder + byte sys_ind; // what partition type + byte end_head; // end head + byte end_sector; // end sector + byte end_cyl; // end cylinder + byte start4[4]; // starting sector counting from 0 + byte size4[4]; // nr of sectors in partition + }; + /** Checks whether * the disk is partitioned * the specified partition @@ -35,35 +50,8 @@ * @param sizes The number of sectors for each partition. */ void partition(SectorAccessibleDisk& disk, std::vector<unsigned> sizes); - - /** Return a partition (as a SectorAccessibleDisk) from another - * SectorAccessibleDisk. - * @param disk The whole disk. - * @param partition The partition number. - * 0 for the whole disk - * 1-31 for a specific partition, this must be a valid partition. - */ - std::auto_ptr<SectorAccessibleDisk> getPartition( - SectorAccessibleDisk& disk, unsigned partition); }; -class DiskPartition : public SectorAccessibleDisk -{ -public: - DiskPartition(SectorAccessibleDisk& parent, - unsigned start, unsigned length); - -private: - virtual void readSectorImpl(unsigned sector, byte* buf); - virtual void writeSectorImpl(unsigned sector, const byte* buf); - virtual unsigned getNbSectorsImpl() const; - virtual bool isWriteProtectedImpl() const; - - SectorAccessibleDisk& parent; - const unsigned start; - const unsigned length; -}; - } // namespace openmsx #endif Modified: openmsx/trunk/src/fdc/DiskManipulator.cc =================================================================== --- openmsx/trunk/src/fdc/DiskManipulator.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DiskManipulator.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -6,6 +6,7 @@ #include "MSXtar.hh" #include "DiskImageUtils.hh" #include "DSKDiskImage.hh" +#include "DiskPartition.hh" #include "CommandController.hh" #include "CommandException.hh" #include "MSXMotherBoard.hh" @@ -131,7 +132,8 @@ { SectorAccessibleDisk* disk = driveData.drive->getSectorAccessibleDisk(); assert(disk); - return DiskImageUtils::getPartition(*disk, driveData.partition); + return auto_ptr<SectorAccessibleDisk>( + new DiskPartition(*disk, driveData.partition)); } Added: openmsx/trunk/src/fdc/DiskName.cc =================================================================== --- openmsx/trunk/src/fdc/DiskName.cc (rev 0) +++ openmsx/trunk/src/fdc/DiskName.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -0,0 +1,52 @@ +// $Id$ + +#include "DiskName.hh" +#include "serialize.hh" + +using std::string; + +namespace openmsx { + +DiskName::DiskName(const Filename& name_, const string& extra_) + : name(name_) + , extra(extra_) +{ +} + +string DiskName::getOriginal() const +{ + return name.getOriginal() + extra; +} + +string DiskName::getResolved() const +{ + return name.getResolved() + extra; +} + +void DiskName::updateAfterLoadState(CommandController& controller) +{ + name.updateAfterLoadState(controller); +} + +bool DiskName::empty() const +{ + return name.empty() && extra.empty(); +} + +const Filename& DiskName::getFilename() const +{ + return name; +} + +template<typename Archive> +void DiskName::serialize(Archive& ar, unsigned /*version*/) +{ + // serializeNoID because we sometimes serialize DiskName objects that + // are allocated on the stack + ar.serializeNoID("filename", name); + ar.serializeNoID("extra", extra); +} +INSTANTIATE_SERIALIZE_METHODS(DiskName); + +} // namespace openmsx + Added: openmsx/trunk/src/fdc/DiskName.hh =================================================================== --- openmsx/trunk/src/fdc/DiskName.hh (rev 0) +++ openmsx/trunk/src/fdc/DiskName.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -0,0 +1,31 @@ +// $Id$ + +#ifndef DISKNAME_HH +#define DISKNAME_HH + +#include "Filename.hh" + +namespace openmsx { + +class DiskName +{ +public: + DiskName(const Filename& name, const std::string& extra = ""); + + std::string getOriginal() const; + std::string getResolved() const; + void updateAfterLoadState(CommandController& controller); + bool empty() const; + const Filename& getFilename() const; + + template<typename Archive> + void serialize(Archive& ar, unsigned version); + +private: + Filename name; + std::string extra; +}; + +} // namespace openmsx + +#endif Added: openmsx/trunk/src/fdc/DiskPartition.cc =================================================================== --- openmsx/trunk/src/fdc/DiskPartition.cc (rev 0) +++ openmsx/trunk/src/fdc/DiskPartition.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -0,0 +1,75 @@ +// $Id$ + +#include "DiskPartition.hh" +#include "DiskImageUtils.hh" +#include "Filename.hh" +#include "MSXException.hh" +#include "StringOp.hh" +#include <cassert> + +namespace openmsx { + +using namespace DiskImageUtils; + +static inline unsigned read32LE(const byte* x) +{ + return (x[0] << 0) + (x[1] << 8) + (x[2] << 16) + (x[3] << 24); +} + +static DiskName getDiskName(SectorAccessibleDisk* disk, unsigned partition) +{ + if (Disk* dsk = dynamic_cast<Disk*>(disk)) { + return DiskName(dsk->getName().getFilename(), + ':' + StringOp::toString(partition)); + } else { + return DiskName(Filename("dummy")); + } +} + +DiskPartition::DiskPartition(SectorAccessibleDisk& disk, unsigned partition, + shared_ptr<SectorAccessibleDisk> owned_) + : SectorBasedDisk(getDiskName(&disk, partition)) + , parent(disk) + , owned(owned_) +{ + assert(!owned.get() || (owned.get() == &disk)); + + if (partition == 0) { + start = 0; + setNbSectors(disk.getNbSectors()); + } else { + checkValidPartition(disk, partition); // throws + byte buf[SECTOR_SIZE]; + disk.readSector(0, buf); + Partition* p = reinterpret_cast<Partition*>( + &buf[14 + (31 - partition) * 16]); + start = read32LE(p->start4); + setNbSectors(read32LE(p->size4)); + } +} + +DiskPartition::DiskPartition(SectorAccessibleDisk& parent_, + unsigned start_, unsigned length) + : SectorBasedDisk(getDiskName(NULL, 0)) + , parent(parent_) + , start(start_) +{ + setNbSectors(length); +} + +void DiskPartition::readSectorImpl(unsigned sector, byte* buf) +{ + parent.readSector(start + sector, buf); +} + +void DiskPartition::writeSectorImpl(unsigned sector, const byte* buf) +{ + parent.writeSector(start + sector, buf); +} + +bool DiskPartition::isWriteProtectedImpl() const +{ + return parent.isWriteProtected(); +} + +} // namespace openmsx Added: openmsx/trunk/src/fdc/DiskPartition.hh =================================================================== --- openmsx/trunk/src/fdc/DiskPartition.hh (rev 0) +++ openmsx/trunk/src/fdc/DiskPartition.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -0,0 +1,42 @@ +// $Id$ + +#ifndef DISKPARTITION_HH +#define DISKPARTITION_HH + +#include "SectorBasedDisk.hh" +#include "shared_ptr.hh" + +namespace openmsx { + +class DiskPartition : public SectorBasedDisk +{ +public: + /** Return a partition (as a SectorbasedDisk) from another Disk. + * @param disk The whole disk. + * @param partition The partition number. + * 0 for the whole disk + * 1-31 for a specific partition, this must be a valid partition. + * @param owned If specified it should be a shared_ptr to the Disk + * object passed as first parameter. This DiskPartition + * will then take (shared) ownership of that Disk. + */ + DiskPartition(SectorAccessibleDisk& disk, unsigned partition, + shared_ptr<SectorAccessibleDisk> owned = + shared_ptr<SectorAccessibleDisk>()); + + DiskPartition(SectorAccessibleDisk& parent, + unsigned start, unsigned length); + +private: + virtual void readSectorImpl(unsigned sector, byte* buf); + virtual void writeSectorImpl(unsigned sector, const byte* buf); + virtual bool isWriteProtectedImpl() const; + + SectorAccessibleDisk& parent; + shared_ptr<SectorAccessibleDisk> owned; + unsigned start; +}; + +} // namespace openmsx + +#endif Modified: openmsx/trunk/src/fdc/DummyDisk.cc =================================================================== --- openmsx/trunk/src/fdc/DummyDisk.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DummyDisk.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -21,12 +21,12 @@ return true; // TODO check } -void DummyDisk::readSectorSBD(unsigned /*sector*/, byte* /*buf*/) +void DummyDisk::readSectorImpl(unsigned /*sector*/, byte* /*buf*/) { throw DriveEmptyException("No disk in drive"); } -void DummyDisk::writeSectorSBD(unsigned /*sector*/, const byte* /*buf*/) +void DummyDisk::writeSectorImpl(unsigned /*sector*/, const byte* /*buf*/) { throw DriveEmptyException("No disk in drive"); } Modified: openmsx/trunk/src/fdc/DummyDisk.hh =================================================================== --- openmsx/trunk/src/fdc/DummyDisk.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/DummyDisk.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -14,8 +14,8 @@ virtual bool isReady() const; private: - virtual void readSectorSBD(unsigned sector, byte* buf); - virtual void writeSectorSBD(unsigned sector, const byte* buf); + virtual void readSectorImpl(unsigned sector, byte* buf); + virtual void writeSectorImpl(unsigned sector, const byte* buf); virtual bool isWriteProtectedImpl() const; }; Modified: openmsx/trunk/src/fdc/EmptyDiskPatch.cc =================================================================== --- openmsx/trunk/src/fdc/EmptyDiskPatch.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/EmptyDiskPatch.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -1,12 +1,12 @@ // $Id$ #include "EmptyDiskPatch.hh" -#include "SectorBasedDisk.hh" +#include "SectorAccessibleDisk.hh" #include <cassert> namespace openmsx { -EmptyDiskPatch::EmptyDiskPatch(SectorBasedDisk& disk_) +EmptyDiskPatch::EmptyDiskPatch(SectorAccessibleDisk& disk_) : disk(disk_) { } @@ -14,13 +14,13 @@ void EmptyDiskPatch::copyBlock(unsigned src, byte* dst, unsigned num) const { (void)num; - assert(num == SectorBasedDisk::SECTOR_SIZE); - disk.readSectorSBD(src / SectorBasedDisk::SECTOR_SIZE, dst); + assert(num == SectorAccessibleDisk::SECTOR_SIZE); + disk.readSectorImpl(src / SectorAccessibleDisk::SECTOR_SIZE, dst); } unsigned EmptyDiskPatch::getSize() const { - return disk.getNbSectors() * SectorBasedDisk::SECTOR_SIZE; + return disk.getNbSectors() * SectorAccessibleDisk::SECTOR_SIZE; } void EmptyDiskPatch::getFilenames(std::vector<Filename>& /*result*/) const Modified: openmsx/trunk/src/fdc/EmptyDiskPatch.hh =================================================================== --- openmsx/trunk/src/fdc/EmptyDiskPatch.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/EmptyDiskPatch.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -7,19 +7,19 @@ namespace openmsx { -class SectorBasedDisk; +class SectorAccessibleDisk; class EmptyDiskPatch : public PatchInterface { public: - explicit EmptyDiskPatch(SectorBasedDisk& disk); + explicit EmptyDiskPatch(SectorAccessibleDisk& disk); virtual void copyBlock(unsigned src, byte* dst, unsigned num) const; virtual unsigned getSize() const; virtual void getFilenames(std::vector<Filename>& result) const; private: - SectorBasedDisk& disk; + SectorAccessibleDisk& disk; }; } // namespace openmsx Modified: openmsx/trunk/src/fdc/NowindInterface.cc =================================================================== --- openmsx/trunk/src/fdc/NowindInterface.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/NowindInterface.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -13,7 +13,7 @@ #include "MSXMotherBoard.hh" #include "FileContext.hh" #include "StringOp.hh" -#include "Filename.hh" +#include "DiskName.hh" #include "CommandException.hh" #include "serialize.hh" #include "serialize_stl.hh" Modified: openmsx/trunk/src/fdc/RamDSKDiskImage.cc =================================================================== --- openmsx/trunk/src/fdc/RamDSKDiskImage.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/RamDSKDiskImage.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -7,7 +7,7 @@ namespace openmsx { RamDSKDiskImage::RamDSKDiskImage(unsigned size) - : SectorBasedDisk(Filename("ramdsk")) + : SectorBasedDisk(DiskName(Filename(), "ramdsk")) { setNbSectors(size / SECTOR_SIZE); diskdata = new byte[size]; @@ -20,12 +20,12 @@ delete[] diskdata; } -void RamDSKDiskImage::readSectorSBD(unsigned sector, byte* buf) +void RamDSKDiskImage::readSectorImpl(unsigned sector, byte* buf) { memcpy(buf, &diskdata[sector * SECTOR_SIZE], SECTOR_SIZE); } -void RamDSKDiskImage::writeSectorSBD(unsigned sector, const byte* buf) +void RamDSKDiskImage::writeSectorImpl(unsigned sector, const byte* buf) { memcpy(&diskdata[sector * SECTOR_SIZE], buf, SECTOR_SIZE); } Modified: openmsx/trunk/src/fdc/RamDSKDiskImage.hh =================================================================== --- openmsx/trunk/src/fdc/RamDSKDiskImage.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/RamDSKDiskImage.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -15,8 +15,8 @@ private: // SectorBasedDisk - virtual void readSectorSBD(unsigned sector, byte* buf); - virtual void writeSectorSBD(unsigned sector, const byte* buf); + virtual void readSectorImpl(unsigned sector, byte* buf); + virtual void writeSectorImpl(unsigned sector, const byte* buf); virtual bool isWriteProtectedImpl() const; byte* diskdata; Modified: openmsx/trunk/src/fdc/SectorAccessibleDisk.cc =================================================================== --- openmsx/trunk/src/fdc/SectorAccessibleDisk.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/SectorAccessibleDisk.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -1,18 +1,36 @@ // $Id$ #include "SectorAccessibleDisk.hh" +#include "EmptyDiskPatch.hh" +#include "IPSPatch.hh" #include "DiskExceptions.hh" #include "sha1.hh" namespace openmsx { +SectorAccessibleDisk::SectorAccessibleDisk() + : patch(new EmptyDiskPatch(*this)) + , forcedWriteProtect(false) +{ +} + SectorAccessibleDisk::~SectorAccessibleDisk() { } void SectorAccessibleDisk::readSector(unsigned sector, byte* buf) { - readSectorImpl(sector, buf); + unsigned nbSectors = getNbSectors(); + if ((nbSectors != 0) && // in this case we want DriveEmptyException + (nbSectors <= sector)) { + throw NoSuchSectorException("No such sector"); + } + try { + // in the end this calls readSectorImpl() + patch->copyBlock(sector * SECTOR_SIZE, buf, SECTOR_SIZE); + } catch (MSXException& e) { + throw DiskIOErrorException("Disk I/O error: " + e.getMessage()); + } } void SectorAccessibleDisk::writeSector(unsigned sector, const byte* buf) @@ -20,8 +38,16 @@ if (isWriteProtected()) { throw WriteProtectedException(""); } + unsigned nbSectors = getNbSectors(); + if ((nbSectors != 0) && (nbSectors <= sector)) { + throw NoSuchSectorException("No such sector"); + } + try { + writeSectorImpl(sector, buf); + } catch (MSXException& e) { + throw DiskIOErrorException("Disk I/O error: " + e.getMessage()); + } sha1cache.clear(); - writeSectorImpl(sector, buf); } unsigned SectorAccessibleDisk::getNbSectors() const @@ -29,6 +55,16 @@ return getNbSectorsImpl(); } +void SectorAccessibleDisk::applyPatch(const Filename& patchFile) +{ + patch.reset(new IPSPatch(patchFile, patch)); +} + +void SectorAccessibleDisk::getPatches(std::vector<Filename>& result) const +{ + patch->getFilenames(result); +} + const std::string& SectorAccessibleDisk::getSHA1Sum() { if (sha1cache.empty()) { @@ -70,4 +106,15 @@ } } +bool SectorAccessibleDisk::isWriteProtected() const +{ + return forcedWriteProtect || isWriteProtectedImpl(); +} + +void SectorAccessibleDisk::forceWriteProtect() +{ + // can't be undone + forcedWriteProtect = true; +} + } // namespace openmsx Modified: openmsx/trunk/src/fdc/SectorAccessibleDisk.hh =================================================================== --- openmsx/trunk/src/fdc/SectorAccessibleDisk.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/SectorAccessibleDisk.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -3,23 +3,36 @@ #ifndef SECTORACCESSIBLEDISK_HH #define SECTORACCESSIBLEDISK_HH -#include "WriteProtectableDisk.hh" +#include "Filename.hh" #include "openmsx.hh" +#include <vector> #include <string> +#include <memory> namespace openmsx { -class SectorAccessibleDisk : public virtual WriteProtectableDisk +class PatchInterface; + +class SectorAccessibleDisk { public: static const unsigned SECTOR_SIZE = 512; virtual ~SectorAccessibleDisk(); + // sector stuff void readSector(unsigned sector, byte* buf); void writeSector(unsigned sector, const byte* buf); unsigned getNbSectors() const; + // write protected stuff + bool isWriteProtected() const; + void forceWriteProtect(); + + // patch stuff + void applyPatch(const Filename& patchFile); + void getPatches(std::vector<Filename>& result) const; + /** Calculate SHA1 of the content of this disk. * This value is cached (and flushed on writes). */ @@ -34,12 +47,20 @@ int writeSectors(const byte* buffer, unsigned startSector, unsigned nbSectors); +protected: + SectorAccessibleDisk(); + private: virtual void readSectorImpl(unsigned sector, byte* buf) = 0; virtual void writeSectorImpl(unsigned sector, const byte* buf) = 0; virtual unsigned getNbSectorsImpl() const = 0; + virtual bool isWriteProtectedImpl() const = 0; + std::auto_ptr<const PatchInterface> patch; std::string sha1cache; + bool forcedWriteProtect; + + friend class EmptyDiskPatch; }; } // namespace openmsx Modified: openmsx/trunk/src/fdc/SectorBasedDisk.cc =================================================================== --- openmsx/trunk/src/fdc/SectorBasedDisk.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/SectorBasedDisk.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -8,9 +8,8 @@ namespace openmsx { -SectorBasedDisk::SectorBasedDisk(const Filename& name) +SectorBasedDisk::SectorBasedDisk(const DiskName& name) : Disk(name) - , patch(new EmptyDiskPatch(*this)) , nbSectors(unsigned(-1)) // to detect misuse { } @@ -39,16 +38,6 @@ // because only the former flushes SHA1 cache } -void SectorBasedDisk::applyPatch(const Filename& patchFile) -{ - patch.reset(new IPSPatch(patchFile, patch)); -} - -void SectorBasedDisk::getPatches(std::vector<Filename>& result) const -{ - patch->getFilenames(result); -} - void SectorBasedDisk::writeTrackDataImpl(byte track, byte side, const byte* data) { unsigned sector = 1; @@ -139,36 +128,6 @@ return true; } -void SectorBasedDisk::readSectorImpl(unsigned sector, byte* buf) -{ - unsigned nbSectors = getNbSectors(); - if ((nbSectors != 0) && // in this case we want DriveEmptyException - (nbSectors <= sector)) { - throw NoSuchSectorException("No such sector"); - } - try { - patch->copyBlock(sector * SECTOR_SIZE, buf, SECTOR_SIZE); - } catch (MSXException& e) { - throw DiskIOErrorException("Disk I/O error: " + e.getMessage()); - } -} - -void SectorBasedDisk::writeSectorImpl(unsigned sector, const byte* buf) -{ - if (isWriteProtected()) { - throw WriteProtectedException(""); - } - unsigned nbSectors = getNbSectors(); - if ((nbSectors != 0) && (nbSectors <= sector)) { - throw NoSuchSectorException("No such sector"); - } - try { - writeSectorSBD(sector, buf); - } catch (MSXException& e) { - throw DiskIOErrorException("Disk I/O error: " + e.getMessage()); - } -} - unsigned SectorBasedDisk::getNbSectorsImpl() const { assert(nbSectors != unsigned(-1)); // must have been initialized Modified: openmsx/trunk/src/fdc/SectorBasedDisk.hh =================================================================== --- openmsx/trunk/src/fdc/SectorBasedDisk.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/SectorBasedDisk.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -4,36 +4,22 @@ #define SECTORBASEDDISK_HH #include "Disk.hh" -#include "SectorAccessibleDisk.hh" #include "noncopyable.hh" -#include <memory> namespace openmsx { -class PatchInterface; - -class SectorBasedDisk : public Disk, public SectorAccessibleDisk, - private noncopyable +class SectorBasedDisk : public Disk, private noncopyable { -public: - virtual void applyPatch(const Filename& patchFile); - virtual void getPatches(std::vector<Filename>& result) const; - protected: - explicit SectorBasedDisk(const Filename& name); + explicit SectorBasedDisk(const DiskName& name); virtual ~SectorBasedDisk(); virtual void detectGeometry(); void setNbSectors(unsigned num); private: - // SectorAccessibleDisk - // does apply IPS patches, does error checking - virtual void readSectorImpl(unsigned sector, byte* buf); - virtual void writeSectorImpl(unsigned sector, const byte* buf); - unsigned getNbSectorsImpl() const; - // Disk + virtual unsigned getNbSectorsImpl() const; virtual void read(byte track, byte sector, byte side, unsigned size, byte* buf); virtual void readTrackData(byte track, byte side, byte* output); @@ -42,13 +28,6 @@ unsigned size, const byte* buf); virtual void writeTrackDataImpl(byte track, byte side, const byte* data); - // low level sector routines - // doesn't apply IPS patches, doesn't do error checking - friend class EmptyDiskPatch; - virtual void readSectorSBD(unsigned sector, byte* buf) = 0; - virtual void writeSectorSBD(unsigned sector, const byte* buf) = 0; - - std::auto_ptr<const PatchInterface> patch; unsigned nbSectors; }; Deleted: openmsx/trunk/src/fdc/WriteProtectableDisk.hh =================================================================== --- openmsx/trunk/src/fdc/WriteProtectableDisk.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/WriteProtectableDisk.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -1,37 +0,0 @@ -// $Id$ - -#ifndef WRITEPROTECTABLEDISK_HH -#define WRITEPROTECTABLEDISK_HH - -#include "openmsx.hh" - -namespace openmsx { - -class WriteProtectableDisk -{ -public: - WriteProtectableDisk() - : forcedWriteProtect(false) - { - } - bool isWriteProtected() const - { - return forcedWriteProtect || isWriteProtectedImpl(); - } - void forceWriteProtect() - { - // can't be undone - forcedWriteProtect = true; - } - -protected: - virtual ~WriteProtectableDisk() {} - virtual bool isWriteProtectedImpl() const = 0; - -private: - bool forcedWriteProtect; -}; - -} // namespace openmsx - -#endif Modified: openmsx/trunk/src/fdc/XSADiskImage.cc =================================================================== --- openmsx/trunk/src/fdc/XSADiskImage.cc 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/XSADiskImage.cc 2009-02-21 20:59:32 UTC (rev 8630) @@ -63,12 +63,12 @@ setNbSectors(data.size() / 512); } -void XSADiskImage::readSectorSBD(unsigned sector, byte* buf) +void XSADiskImage::readSectorImpl(unsigned sector, byte* buf) { memcpy(buf, &data[sector * SECTOR_SIZE], SECTOR_SIZE); } -void XSADiskImage::writeSectorSBD(unsigned /*sector*/, const byte* /*buf*/) +void XSADiskImage::writeSectorImpl(unsigned /*sector*/, const byte* /*buf*/) { throw WriteProtectedException("Write protected"); } Modified: openmsx/trunk/src/fdc/XSADiskImage.hh =================================================================== --- openmsx/trunk/src/fdc/XSADiskImage.hh 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/XSADiskImage.hh 2009-02-21 20:59:32 UTC (rev 8630) @@ -22,8 +22,8 @@ private: // SectorBasedDisk - virtual void readSectorSBD(unsigned sector, byte* buf); - virtual void writeSectorSBD(unsigned sector, const byte* buf); + virtual void readSectorImpl(unsigned sector, byte* buf); + virtual void writeSectorImpl(unsigned sector, const byte* buf); virtual bool isWriteProtectedImpl() const; std::vector<byte> data; Modified: openmsx/trunk/src/fdc/node.mk =================================================================== --- openmsx/trunk/src/fdc/node.mk 2009-02-19 00:25:12 UTC (rev 8629) +++ openmsx/trunk/src/fdc/node.mk 2009-02-21 20:59:32 UTC (rev 8630) @@ -17,6 +17,7 @@ DiskChanger \ DriveMultiplexer \ Disk \ + DiskName \ SectorBasedDisk \ DummyDisk \ DSKDiskImage \ @@ -24,6 +25,7 @@ DirAsDSK \ EmptyDiskPatch \ RamDSKDiskImage \ + DiskPartition \ MSXtar \ DiskImageUtils \ DiskContainer \ @@ -34,7 +36,6 @@ HDR_ONLY:= \ DiskExceptions \ - WriteProtectableDisk include build/node-end.mk This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |