From 756cff8657b29d1b519f9a3b4816b14382d54127 Mon Sep 17 00:00:00 2001 From: Mark Long Date: Thu, 11 Feb 2021 10:12:30 -0600 Subject: [PATCH] Updated diskfile stuff --- src/diskfiles/dos33/catalogsector.cxx | 26 ++-- src/diskfiles/dos33/catalogsector.h | 1 + .../{diskfile.cxx => dos33diskimage.cxx} | 76 ++++++----- .../dos33/{diskfile.h => dos33diskimage.h} | 127 ++++++++++-------- src/diskfiles/dos33/dos33imagemodel.cpp | 95 +++++++++++++ src/diskfiles/dos33/dos33imagemodel.h | 42 ++++++ src/diskfiles/dos33/dos33treeitem.cpp | 18 +++ src/diskfiles/dos33/dos33treeitem.h | 20 +++ src/diskfiles/dos33/filedescriptiveentry.h | 26 ++-- src/diskfiles/dos33/genericfile.cxx | 14 ++ src/diskfiles/dos33/genericfile.h | 14 +- src/diskfiles/dos33/sector.cxx | 5 +- src/diskfiles/dos33/sector.h | 9 +- src/diskfiles/dos33/tracksectorlist.cxx | 22 +++ src/diskfiles/dos33/tracksectorlist.h | 12 +- src/diskfiles/dos33/tspair.cpp | 1 + src/diskfiles/dos33/tspair.h | 71 ++++++++++ src/diskfiles/dos33/vtoc.cxx | 38 +++++- src/diskfiles/dos33/vtoc.h | 7 +- src/util/applestring.cxx | 84 ++++++++---- src/util/applestring.h | 3 +- src/util/util.h | 73 +++------- 22 files changed, 565 insertions(+), 219 deletions(-) rename src/diskfiles/dos33/{diskfile.cxx => dos33diskimage.cxx} (63%) rename src/diskfiles/dos33/{diskfile.h => dos33diskimage.h} (57%) create mode 100644 src/diskfiles/dos33/dos33imagemodel.cpp create mode 100644 src/diskfiles/dos33/dos33imagemodel.h create mode 100644 src/diskfiles/dos33/dos33treeitem.cpp create mode 100644 src/diskfiles/dos33/dos33treeitem.h create mode 100644 src/diskfiles/dos33/tspair.cpp create mode 100644 src/diskfiles/dos33/tspair.h diff --git a/src/diskfiles/dos33/catalogsector.cxx b/src/diskfiles/dos33/catalogsector.cxx index 5b39c2b..f6dc9ab 100644 --- a/src/diskfiles/dos33/catalogsector.cxx +++ b/src/diskfiles/dos33/catalogsector.cxx @@ -3,7 +3,6 @@ CatalogSector::CatalogSector(Sector *data) { - // qDebug() << "### Start CatalogSector ctor"; m_data = data; m_next = TSPair(0,0); @@ -12,22 +11,19 @@ CatalogSector::CatalogSector(Sector *data) if (next.isValid() && next.track() == 17) { - next.dump(); - // qDebug("Next track sector is valid."); + // next.dump(); m_next = next; } else { - qWarning() << "Track sector " << next.track() << "," << next.sector() << "is invalid! Not adding to catalog."; - m_next.dump(); + // qWarning() << "Track sector " << next.track() << "," << next.sector() << "is invalid! Not adding to catalog."; + // m_next.dump(); } - //m_next.setTrack(m_data->rawData()[0x01]); - //m_next.setSector(m_data->rawData()[0x02]); for (int idx = 0; idx<7; idx++) { FileDescriptiveEntry fde = makeFDE(idx*0x23+0x0B); - if (fde.firstTSListSector() != TSPair(0,0)) { + if (fde.firstTSListSector() != TSPair(0,0)) { if (fde.firstTSListSector().isValid()) { m_fdes.append(fde); @@ -36,7 +32,6 @@ CatalogSector::CatalogSector(Sector *data) } // else { qWarning("fde.firstTSListSector() is 0,0"); } } - // qDebug() << "### End CatalogSector ctor"; } void CatalogSector::dumpFDEs() { @@ -53,12 +48,14 @@ void CatalogSector::dumpFDEs() { FileDescriptiveEntry CatalogSector::makeFDE(int offset) { FileDescriptiveEntry fde; - fde.firstTSListSector().setTrack(m_data->rawData()[offset + 0x00]); - fde.firstTSListSector().setSector(m_data->rawData()[offset + 0x01]); - fde.fileTypeAndFlags = m_data->rawData()[offset + 0x02]; + TSPair first(m_data->rawData()[offset + 0x00],m_data->rawData()[offset + 0x01]); + fde.setFirstTSListSector(first); + fde.lengthInSectors = makeWord( m_data->rawData()[offset + 0x21], m_data->rawData()[offset + 0x22]); + fde.fileTypeFlags = m_data->rawData()[offset + 0x02]; + if (fde.lengthInSectors > 16*35) { fde.lengthInSectors = -1; @@ -70,11 +67,12 @@ FileDescriptiveEntry CatalogSector::makeFDE(int offset) if (fde.firstTSListSector().track() == 0xFF) { - //TODO: Double check this stuff. applevision.dsk is a good example. qDebug() << "File" << fde.filename.printable() << "is deleted"; fde.deleted = true; qDebug() << fde.filename; - fde.firstTSListSector().setTrack(m_data->rawData()[offset + 0x20]); + TSPair first = fde.firstTSListSector(); + first.setTrack(m_data->rawData()[offset + 0x20]); + fde.setFirstTSListSector(first); qDebug() << " New track: " << (quint8) fde.firstTSListSector().track(); qDebug() << " Sector: " << fde.firstTSListSector().sector(); } diff --git a/src/diskfiles/dos33/catalogsector.h b/src/diskfiles/dos33/catalogsector.h index f845e5c..43af6b8 100644 --- a/src/diskfiles/dos33/catalogsector.h +++ b/src/diskfiles/dos33/catalogsector.h @@ -5,6 +5,7 @@ #include #include +#include "tspair.h" #include "util.h" #include "applestring.h" #include "filedescriptiveentry.h" diff --git a/src/diskfiles/dos33/diskfile.cxx b/src/diskfiles/dos33/dos33diskimage.cxx similarity index 63% rename from src/diskfiles/dos33/diskfile.cxx rename to src/diskfiles/dos33/dos33diskimage.cxx index a6e93d7..df3d75d 100644 --- a/src/diskfiles/dos33/diskfile.cxx +++ b/src/diskfiles/dos33/dos33diskimage.cxx @@ -1,4 +1,4 @@ -#include "diskfile.h" +#include "dos33diskimage.h" #include #include @@ -7,13 +7,14 @@ #include #include "tracksectorlist.h" +#include "genericfile.h" #include "applesoftfile.h" #include "binaryfile.h" #include "IntBasicFile.h" #include "relocatablefile.h" #include "textfile.h" -DiskFile::DiskFile(QString filename) +Dos33DiskImage::Dos33DiskImage(QString filename) { if (!filename.isEmpty()) { @@ -21,7 +22,7 @@ DiskFile::DiskFile(QString filename) } } -DiskFile::~DiskFile() +Dos33DiskImage::~Dos33DiskImage() { foreach (GenericFile *file, m_files) { @@ -29,7 +30,7 @@ DiskFile::~DiskFile() } } -bool DiskFile::read(QString filename) +bool Dos33DiskImage::read(QString filename) { m_fullImageName = filename; m_imageName = QFileInfo(filename).fileName(); @@ -48,6 +49,16 @@ bool DiskFile::read(QString filename) if (infile.open(QIODevice::ReadOnly)) { QByteArray contents = infile.readAll(); + int expectedsize = sectorsPerTrack() * tracks() * 256; + if (contents.size() != expectedsize) + { + if (contents.size() == 35*16*256) { m_sectors_per_track = 16; } + else if (contents.size() == 35*13*256) { m_sectors_per_track = 13; } + else qWarning() << QString("Size mismatch in file! Expected %1, got %2") + .arg(expectedsize) + .arg(contents.size()); + } + QDataStream qds(contents); for (int track = 0; track < 35; track++) { @@ -56,11 +67,11 @@ bool DiskFile::read(QString filename) char buffer[256]; if (qds.readRawData(buffer,256) == 256) { - // qDebug() << "Track " << track << " Sector " << sector; - Sector sec; - sec.setTrackSector(track,sector); - sec.setData(QByteArray(buffer,256)); - m_contents[track][sector] = sec; + TSPair tmpts(track,sector); + Sector newSec; + newSec.setTrackSector(tmpts); + newSec.setData(QByteArray(buffer,256)); + m_contents[tmpts] = newSec; } else { @@ -72,7 +83,7 @@ bool DiskFile::read(QString filename) hash.addData(contents); m_hash = hash.result(); - // qDebug() << "Hash: " << m_hash; + // qDebug() << "Hash: " << m_hash; return true; } @@ -81,32 +92,32 @@ bool DiskFile::read(QString filename) return false; } -VTOC DiskFile::getVTOC() +VTOC Dos33DiskImage::getVTOC() { return getSector(17,0).promoteToVTOC(); } -QList DiskFile::getCatalogSectors() +QList Dos33DiskImage::getCatalogSectors() { - // qDebug() << "### Start getCatalogSector"; + // qDebug() << "### Start getCatalogSector"; QList retval; VTOC vtoc = getVTOC(); TSPair ts = vtoc.firstCatalogSector(); - CatalogSector cs = getSector(ts).promoteToCatalogSector(); + CatalogSector cs = getSector(ts).asCatalogSector(); retval.append(cs); while (cs.nextCatalogSector() != TSPair(0,0)) { ts = cs.nextCatalogSector(); - cs = getSector(ts).promoteToCatalogSector(); + cs = getSector(ts).asCatalogSector(); retval.append(cs); } - // qDebug() << "### End getCatalogSector"; + // qDebug() << "### End getCatalogSector"; return retval; } -GenericFile *DiskFile::getFile(FileDescriptiveEntry fde) +GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde) { GenericFile *retval = 0; if (m_files.contains(fde)) @@ -115,38 +126,38 @@ GenericFile *DiskFile::getFile(FileDescriptiveEntry fde) } else { - if (!fde.firstTSListSector().isValid()) { qWarning(" Not returning a file from invalid TSList!"); return nullptr; } - TrackSectorList tsl = getSector(fde.firstTSListSector()).promoteToTrackSectorList(); + TrackSectorList tsl = getSector(fde.firstTSListSector()).asTrackSectorList(); if (!fde.firstTSListSector().isValid()) { qWarning(" Not returning a file from invalid TSList!"); return nullptr; } QByteArray data = getDataFromTrackSectorList(tsl); + setFileType(fde.fileType()); - if (fde.fileType() == "A") + if (fileType() == "A") { retval = new ApplesoftFile(data); } - else if (fde.fileType() == "B") + else if (fileType() == "B") { retval = new BinaryFile(data); } - else if (fde.fileType() == "R") + else if (fileType() == "R") { retval = new RelocatableFile(data); } - else if ((fde.fileType() == "T")) + else if ((fileType() == "T")) { retval = new TextFile(data); } - else if ((fde.fileType() == "I")) + else if ((fileType() == "I")) { retval = new IntBasicFile(data); } @@ -154,6 +165,7 @@ GenericFile *DiskFile::getFile(FileDescriptiveEntry fde) { retval = new GenericFile(data); } + m_files[fde] = retval; } if (retval) { retval->setDiskFile(this); } @@ -161,7 +173,7 @@ GenericFile *DiskFile::getFile(FileDescriptiveEntry fde) } -QByteArray DiskFile::getDataFromTrackSectorList(TrackSectorList tsl) +QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl) { QByteArray retval; @@ -169,8 +181,8 @@ QByteArray DiskFile::getDataFromTrackSectorList(TrackSectorList tsl) { if (pair.isValid()) { - Sector sec = getSector(pair); - retval.append(sec.rawData()); + Sector sec = getSector(pair); + retval.append(sec.rawData()); } else { @@ -180,16 +192,16 @@ QByteArray DiskFile::getDataFromTrackSectorList(TrackSectorList tsl) auto next = tsl.getNextTSList(); if (next.isValid() && next != TSPair(0,0)) { - TrackSectorList nextTsl = getSector(tsl.getNextTSList()).promoteToTrackSectorList(); + TrackSectorList nextTsl = getSector(tsl.getNextTSList()).asTrackSectorList(); retval.append(getDataFromTrackSectorList(nextTsl)); } return retval; } -QList DiskFile::getAllFDEs() +QList Dos33DiskImage::getAllFDEs() { - // qDebug() << "### Start getAllFDEs"; + // qDebug() << "### Start getAllFDEs"; QList retval; QList sectors = getCatalogSectors(); @@ -199,11 +211,11 @@ QList DiskFile::getAllFDEs() QList fdes = cs.getFDEs(); retval.append(fdes); } - // qDebug() << "### End getAllFDEs"; + // qDebug() << "### End getAllFDEs"; return retval; } -QString DiskFile::getMetaDataPath() const { +QString Dos33DiskImage::getMetaDataPath() const { QString path = QString("%1.metadata/").arg(getFullDiskImageName()); QDir dir(path); diff --git a/src/diskfiles/dos33/diskfile.h b/src/diskfiles/dos33/dos33diskimage.h similarity index 57% rename from src/diskfiles/dos33/diskfile.h rename to src/diskfiles/dos33/dos33diskimage.h index 54b441d..8d8a0e5 100644 --- a/src/diskfiles/dos33/diskfile.h +++ b/src/diskfiles/dos33/dos33diskimage.h @@ -1,59 +1,68 @@ -#ifndef DISKFILE_H -#define DISKFILE_H - -#include -#include -#include -#include -#include - -#include "util.h" -#include "sector.h" -#include "vtoc.h" - -class GenericFile; - -class DiskFile -{ -public: - DiskFile(QString filename = ""); - ~DiskFile(); - - bool read(QString filename); - - Sector &getSector(TSPair ts) { return getSector(ts.track(), ts.sector()); } - - Sector &getSector(int track, int sector) { - return m_contents[track][sector]; - } - - VTOC getVTOC(); - - QList getCatalogSectors(); - - GenericFile *getFile(FileDescriptiveEntry fde); - - QByteArray getDataFromTrackSectorList(TrackSectorList tsl); - - QList getAllFDEs(); - - QByteArray fileHash() const { return m_hash; } - - QString getDiskImageName() const { return m_imageName; } - QString getFullDiskImageName() const { return m_fullImageName; } - QString getMetaDataPath() const; - -private: - - QMap< int, QMap< int, Sector> > m_contents; - QMap m_files; - QByteArray m_hash; - - QString m_imageName; - QString m_fullImageName; - - quint8 m_sectors_per_track; - -}; - -#endif // DISKFILE_H +#ifndef DOS33DISKIMAGE_H +#define DOS33DISKIMAGE_H + +#include +#include +#include +#include +#include + +#include "util.h" +#include "sector.h" +#include "vtoc.h" + +class GenericFile; + +class Dos33DiskImage +{ +public: + Dos33DiskImage(QString filename = ""); + ~Dos33DiskImage(); + + bool read(QString filename); + + Sector &getSector(TSPair ts) { return m_contents[ts]; } + + Sector &getSector(int track, int sector) { + TSPair ts(track,sector); + return getSector(ts); + } + + VTOC getVTOC(); + + QList getCatalogSectors(); + + GenericFile *getFile(FileDescriptiveEntry fde); + + QByteArray getDataFromTrackSectorList(TrackSectorList tsl); + + QList getAllFDEs(); + + QByteArray fileHash() const { return m_hash; } + + QString getDiskImageName() const { return m_imageName; } + QString getFullDiskImageName() const { return m_fullImageName; } + QString getMetaDataPath() const; + + QString fileType() const { return m_fileType; } + void setFileType(QString type) { m_fileType = type; } + + quint8 sectorsPerTrack() const { return m_sectors_per_track; } + quint8 tracks() const { return 35; } + +private: + + QMap m_contents; + QMap m_files; + QByteArray m_hash; + + QString m_imageName; + QString m_fullImageName; + + QString m_fileType; + + quint8 m_sectors_per_track; + +}; + +#endif // DOS33DISKIMAGE_H diff --git a/src/diskfiles/dos33/dos33imagemodel.cpp b/src/diskfiles/dos33/dos33imagemodel.cpp new file mode 100644 index 0000000..ae57ae1 --- /dev/null +++ b/src/diskfiles/dos33/dos33imagemodel.cpp @@ -0,0 +1,95 @@ +#include "dos33imagemodel.h" + +#include + +#include "tspair.h" + +Dos33ImageModel::Dos33ImageModel(QObject *parent) : QStandardItemModel(parent) +{ + setHorizontalHeaderLabels({"Disk Images"}); + + m_icon_A = QIcon(":/A_YELLOW.png"); + m_icon_a = QIcon(":/A_GREY.png"); + m_icon_B = QIcon(":/B_GREEN.png"); + m_icon_b = QIcon(":/B_GREY.png"); + m_icon_R = QIcon(":/R_MAGENTA.png"); + m_icon_S = QIcon(":/S_ORANGE.png"); + m_icon_T = QIcon(":/T_CYAN.png"); + m_icon_I = QIcon(":/I_RED.png"); + m_icon_disk = QIcon(":/disk.png"); +} + +Dos33ImageModel::~Dos33ImageModel() +{ + +} + +bool Dos33ImageModel::addDiskImage(Dos33DiskImage *image, QString name) +{ + if (!image) { return false; } + + if (name.isEmpty()) { name = image->getDiskImageName(); } + + if (m_images.contains(name)) { return false; } + + auto diskImageItem = new Dos33TreeItem(name); + invisibleRootItem()->appendRow(diskImageItem); + + + foreach (auto sector, image->getCatalogSectors()) + { + foreach (auto fde, sector.getFDEs()) + { + if (!fde.deleted) + { + QString fn = AppleString(fde.filename).appleFontPrintable(); + QString type = fde.fileType(); + + QIcon icon; + if (type == "A") { icon = m_icon_A; } + else if (type == "B") { icon = m_icon_B; } + else if (type == "T") { icon = m_icon_T; } + else if (type == "R") { icon = m_icon_R; } + else if (type == "I") { icon = m_icon_I; } + else if (type == "a") { icon = m_icon_a; } + else if (type == "b") { icon = m_icon_b; } + else { icon = m_icon_S; } + + auto item = new Dos33TreeItem(icon,fn); + + + QVariant data; + data.setValue(fde.firstTSListSector()); + item->setData(data); + item->setToolTip(QString("%1 Block(s)").arg(fde.lengthInSectors)); + diskImageItem->appendRow(item); + } + } + } + + auto sectors = new Dos33TreeItem("Track/Sector"); + diskImageItem->appendRow(sectors); + + for (int track = 0; track < image->tracks(); track++) + { + auto trk = new Dos33TreeItem(m_icon_disk, QString("Track %1").arg(track)); + sectors->appendRow(trk); + for (int sector = 0; sector < image->sectorsPerTrack(); sector++) + { + auto sec = new Dos33TreeItem(m_icon_disk, QString("Sector %1").arg(sector)); + trk->appendRow(sec); + } + } + + return true; +} + +Dos33DiskImage *Dos33ImageModel::getDiskImage(QString name) +{ + return nullptr; +} + +Dos33DiskImage *Dos33ImageModel::removeDiskImage(QString name) +{ + return nullptr; +} diff --git a/src/diskfiles/dos33/dos33imagemodel.h b/src/diskfiles/dos33/dos33imagemodel.h new file mode 100644 index 0000000..c02efb6 --- /dev/null +++ b/src/diskfiles/dos33/dos33imagemodel.h @@ -0,0 +1,42 @@ +#ifndef DOS33IMAGEMODEL_H +#define DOS33IMAGEMODEL_H + +#include "dos33treeitem.h" +#include "dos33diskimage.h" + +#include +#include + +#include + +class Dos33ImageModel : public QStandardItemModel +{ + Q_OBJECT + + using ImageMap = QMap; + +public: + Dos33ImageModel(QObject *parent = nullptr); + ~Dos33ImageModel(); + + bool addDiskImage(Dos33DiskImage *image, QString name = ""); + Dos33DiskImage *getDiskImage(QString name); + Dos33DiskImage *removeDiskImage(QString name); + + + +private: + QIcon m_icon_A; + QIcon m_icon_a; + QIcon m_icon_B; + QIcon m_icon_b; + QIcon m_icon_I; + QIcon m_icon_R; + QIcon m_icon_S; + QIcon m_icon_T; + QIcon m_icon_disk; + + ImageMap m_images; +}; + +#endif // DOS33IMAGEMODEL_H diff --git a/src/diskfiles/dos33/dos33treeitem.cpp b/src/diskfiles/dos33/dos33treeitem.cpp new file mode 100644 index 0000000..04b4dcc --- /dev/null +++ b/src/diskfiles/dos33/dos33treeitem.cpp @@ -0,0 +1,18 @@ +#include "dos33treeitem.h" + + +Dos33TreeItem::Dos33TreeItem() : QStandardItem() +{ + setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); +} + +Dos33TreeItem::Dos33TreeItem(const QIcon &icon, const QString &text) + : QStandardItem(icon,text) +{ + setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); +} + +Dos33TreeItem::Dos33TreeItem(const QString &text) : QStandardItem(text) +{ + setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); +} diff --git a/src/diskfiles/dos33/dos33treeitem.h b/src/diskfiles/dos33/dos33treeitem.h new file mode 100644 index 0000000..c5a4fb0 --- /dev/null +++ b/src/diskfiles/dos33/dos33treeitem.h @@ -0,0 +1,20 @@ +#ifndef DOS33TREEITEM_H +#define DOS33TREEITEM_H + +#include + +class Dos33TreeItem : public QStandardItem +{ +public: + Dos33TreeItem(); + Dos33TreeItem(const QIcon &icon, const QString &text); + Dos33TreeItem(const QString &text); + + ~Dos33TreeItem() { } + +private: + Dos33TreeItem(int rows, int columns = 1) : QStandardItem(rows,columns) { } + +}; + +#endif // DOS33TREEITEM_H diff --git a/src/diskfiles/dos33/filedescriptiveentry.h b/src/diskfiles/dos33/filedescriptiveentry.h index 4fc7459..14cd3c0 100644 --- a/src/diskfiles/dos33/filedescriptiveentry.h +++ b/src/diskfiles/dos33/filedescriptiveentry.h @@ -1,18 +1,18 @@ #ifndef FILEDESCRIPTIVEENTRY_H #define FILEDESCRIPTIVEENTRY_H -#include "util.h" +#include "tspair.h" #include #include "applestring.h" struct FileDescriptiveEntry { - int fileTypeAndFlags; + quint8 fileTypeFlags; AppleString filename; quint16 lengthInSectors; bool deleted; FileDescriptiveEntry() { - fileTypeAndFlags = 0; + fileTypeFlags = 0; lengthInSectors = 0; deleted = false; } @@ -22,23 +22,23 @@ struct FileDescriptiveEntry { } QString fileType() { - if (fileTypeAndFlags & DOSIntegerBasicFile) { return "I"; } - if (fileTypeAndFlags & DOSApplesoftBasicFile) { return "A"; } - if (fileTypeAndFlags & DOSRelocatableFile) { return "R"; } - if (fileTypeAndFlags & DOSRawBinaryFile) { return "B"; } - if (fileTypeAndFlags & DOSTypeSFile) { return "S"; } - if (fileTypeAndFlags & DOSTypeAFile) { return "a"; } - if (fileTypeAndFlags & DOSTypeBFile) { return "b"; } + if (fileTypeFlags & (quint8) FileTypeFlag::Integer) { return "I"; } + if (fileTypeFlags & (quint8) FileTypeFlag::Applesoft) { return "A"; } + if (fileTypeFlags & (quint8) FileTypeFlag::Relocatable) { return "R"; } + if (fileTypeFlags & (quint8) FileTypeFlag::Binary) { return "B"; } + if (fileTypeFlags & (quint8) FileTypeFlag::TypeS) { return "S"; } + if (fileTypeFlags & (quint8) FileTypeFlag::TypeA) { return "a"; } + if (fileTypeFlags & (quint8) FileTypeFlag::TypeB) { return "b"; } return "T"; } - bool isLocked() { return (fileTypeAndFlags & DOSIsLocked); } + bool isLocked() { return (fileTypeFlags & (quint8) FileTypeFlag::IsLockedFlag); } void dump() { qDebug() << "First TS List Sector: Track: " << QString("%1").arg(firstTSListSector().track(),2,16,QChar('0')).toUpper() << " Sector: " << QString("%1").arg(firstTSListSector().sector(),2,16,QChar('0')).toUpper(); - qDebug() << "File Type and Flags: " << QString::number((quint8)fileTypeAndFlags) << "(" << fileType() << "," << (isLocked()?"Locked":"Unlocked") << ")"; + qDebug() << "File Type and Flags: " << QString::number((quint8) fileTypeFlags) << "(" << fileType() << "," << (isLocked()?"Locked":"Unlocked") << ")"; qDebug() << "Filename: " << filename.printable(); qDebug() << "Length in Sectors: " << lengthInSectors; } @@ -62,7 +62,7 @@ struct FileDescriptiveEntry { m_firstTSListSector = TSPair(0,0); } } - TSPair &firstTSListSector() { return m_firstTSListSector; } + TSPair firstTSListSector() const { return m_firstTSListSector; } private: TSPair m_firstTSListSector; diff --git a/src/diskfiles/dos33/genericfile.cxx b/src/diskfiles/dos33/genericfile.cxx index d4630fe..5c686fa 100644 --- a/src/diskfiles/dos33/genericfile.cxx +++ b/src/diskfiles/dos33/genericfile.cxx @@ -15,3 +15,17 @@ void GenericFile::setData(QByteArray data) m_data = data; m_length = data.size(); } + +QString GenericFile::getFileType() const +{ + if (m_file_type == "A" || m_file_type == "B" || m_file_type == "T" || + m_file_type == "I" || m_file_type == "R" || m_file_type == "S" || + m_file_type == "a" || m_file_type == "b") + { + return m_file_type; + } + else + { + return "?"; + } +} diff --git a/src/diskfiles/dos33/genericfile.h b/src/diskfiles/dos33/genericfile.h index 38da6d4..8ceb168 100644 --- a/src/diskfiles/dos33/genericfile.h +++ b/src/diskfiles/dos33/genericfile.h @@ -1,7 +1,7 @@ #ifndef GENERICFILE_H #define GENERICFILE_H -#include "diskfile.h" +#include "dos33diskimage.h" #include #include @@ -27,15 +27,21 @@ public: virtual void setLength(quint16 length) { m_length = length; } virtual quint16 length() const { return m_length; } - DiskFile *diskFile() const { return m_diskfile; } - void setDiskFile(DiskFile *diskfile) { m_diskfile = diskfile; } + Dos33DiskImage *diskFile() const { return m_diskfile; } + void setDiskFile(Dos33DiskImage *diskfile) { m_diskfile = diskfile; } + + void setFileType(QString type) { m_file_type = type; } + QString getFileType() const; protected: + QByteArray m_data; QString m_filename; quint16 m_address; qint16 m_length; - DiskFile * m_diskfile; + Dos33DiskImage * m_diskfile; + + QString m_file_type; }; diff --git a/src/diskfiles/dos33/sector.cxx b/src/diskfiles/dos33/sector.cxx index bfa0d13..808c7c7 100644 --- a/src/diskfiles/dos33/sector.cxx +++ b/src/diskfiles/dos33/sector.cxx @@ -22,12 +22,13 @@ void Sector::dump() { for (int jdx = 0; jdx < 16; jdx++) { QString line; - line += QString("%1 (%2): ").arg(jdx*16,2,16,QChar('0')).arg(jdx*16,3,10,QChar(' ')); + line += QString("%1 (%2): ") + .arg(uint16ToHex(jdx*16)).arg(jdx*16,3,10,QChar(' ')); for (int idx = 0; idx < 16; idx++) { int offset = (jdx*16) + idx; quint8 val = m_data[offset]; - line += QString("%1 ").arg(val,2,16,QChar('0')); + line += QString("%1 ").arg(uint16ToHex(val)); if (idx == 7) line += " "; } line = line.toUpper(); diff --git a/src/diskfiles/dos33/sector.h b/src/diskfiles/dos33/sector.h index 02e1b66..014133f 100644 --- a/src/diskfiles/dos33/sector.h +++ b/src/diskfiles/dos33/sector.h @@ -21,11 +21,11 @@ public: return VTOC(this); } - CatalogSector promoteToCatalogSector() { + CatalogSector asCatalogSector() { return CatalogSector(this); } - TrackSectorList promoteToTrackSectorList() { + TrackSectorList asTrackSectorList() { return TrackSectorList(this); } @@ -37,6 +37,11 @@ public: setSector(sector); } + void setTrackSector(TSPair ts) + { + setTrackSector(ts.track(),ts.sector()); + } + void setTrack(int track) { m_track = track; } void setSector(int sector) { m_sector = sector; } diff --git a/src/diskfiles/dos33/tracksectorlist.cxx b/src/diskfiles/dos33/tracksectorlist.cxx index 227ccce..014ef3f 100644 --- a/src/diskfiles/dos33/tracksectorlist.cxx +++ b/src/diskfiles/dos33/tracksectorlist.cxx @@ -22,3 +22,25 @@ TrackSectorList::TrackSectorList(Sector *data) } } } + +bool TrackSectorList::isNextTSListValid() const +{ + return getNextTSList().isValid(); +} + +bool TrackSectorList::isSectorOffsetValid() const +{ + return getSectorOffset().isValid(); +} + +QList TrackSectorList::getValidTSPairs() const +{ + QList retval; + + foreach (auto item, m_ts_pairs_for_data) + { + if (item.isValid()) { retval.append(item); } + } + + return retval; +} diff --git a/src/diskfiles/dos33/tracksectorlist.h b/src/diskfiles/dos33/tracksectorlist.h index 6c040d4..ea0f4f2 100644 --- a/src/diskfiles/dos33/tracksectorlist.h +++ b/src/diskfiles/dos33/tracksectorlist.h @@ -1,7 +1,7 @@ #ifndef TRACKSECTORLIST_H #define TRACKSECTORLIST_H -#include "util.h" +#include "tspair.h" class Sector; @@ -11,12 +11,16 @@ public: TrackSectorList(Sector *data); TSPair getNextTSList() const { return m_next_tslist; } - TSPair getSectorOffset() const { return m_sector_offset; } + bool isNextTSListValid() const; + + TSPair getSectorOffset() const { return m_sector_offset; } + bool isSectorOffsetValid() const; + + QList getDataTSPairs() const { return m_ts_pairs_for_data; } + QList getValidTSPairs() const; - QList getDataTSPairs() { return m_ts_pairs_for_data; } private: - TSPair m_next_tslist; TSPair m_sector_offset; QList m_ts_pairs_for_data; diff --git a/src/diskfiles/dos33/tspair.cpp b/src/diskfiles/dos33/tspair.cpp new file mode 100644 index 0000000..32bf0b4 --- /dev/null +++ b/src/diskfiles/dos33/tspair.cpp @@ -0,0 +1 @@ +#include "tspair.h" diff --git a/src/diskfiles/dos33/tspair.h b/src/diskfiles/dos33/tspair.h new file mode 100644 index 0000000..c8df5f8 --- /dev/null +++ b/src/diskfiles/dos33/tspair.h @@ -0,0 +1,71 @@ +#ifndef TSPAIR_H +#define TSPAIR_H + +#include +#include + +class TSPair +{ +public: + TSPair() { m_track = m_sector = 0; } + TSPair(quint8 trackval, quint8 secval) { m_track=trackval; m_sector = secval; } + TSPair(QPair pair) { m_track = pair.first; m_sector = pair.second;} + + void setTrack(quint8 tracknum) + { + if (tracknum > 34 && tracknum != 0xff) { + qWarning("Setting a track with value %d (> 34 and not 256).",tracknum); + } + m_track = tracknum; + } + + void setSector(quint8 secnum) + { + if (secnum > 15 && m_track != 0xff) { + qWarning("Setting a sector with value %d (> 15) on track %d.", + secnum, m_track); + } + m_sector = secnum; + } + + bool isValid() const + { + auto retval= (m_track != 0xff && m_track < 35) && m_sector < 16; + + return retval; } + + quint8 track() const { return m_track; } + quint8 sector() const { return m_sector; } + + bool operator==(const TSPair &other) const { + if (other.track() == track() && other.sector() == sector()) return true; + return false; + } + + bool operator!=(const TSPair &other) const { + return !(operator==(other)); + } + + bool operator<(const TSPair &other) const { + if (m_track == other.track()) + { + return (m_sector < other.sector()); + } + else + { + return (m_track < other.track()); + } + } + + QPair toQPair() { return QPair(track(),sector()); } + + void dump() const { + qDebug() << "TSPair: track: " << track() << " sector: " << sector(); + } +private: + quint8 m_track; + quint8 m_sector; +}; +Q_DECLARE_METATYPE(TSPair); + +#endif // TSPAIR_H diff --git a/src/diskfiles/dos33/vtoc.cxx b/src/diskfiles/dos33/vtoc.cxx index cefcb98..83fd95f 100644 --- a/src/diskfiles/dos33/vtoc.cxx +++ b/src/diskfiles/dos33/vtoc.cxx @@ -49,7 +49,7 @@ qint16 VTOC::bytesPerSector() { m_data->rawData()[0x37]); } -bool VTOC::isSectorInUse(TSPair ts) { +bool VTOC::isSectorInUse(TSPair ts) const { quint8 track = ts.track(); quint8 sec = ts.sector(); quint8 baseaddr = (track * 4) + 0x38; @@ -62,6 +62,42 @@ bool VTOC::isSectorInUse(TSPair ts) { return !(word & bitpos); } +QList VTOC::sectorsInUse() const +{ + QList retval; + + for (int track = 0; track < 35; track++) + { + for (int sector = 0; sector < 16; sector++) + { + TSPair ts(track,sector); + if (isSectorInUse(ts)) + { + retval.append(ts); + } + } + } + return retval; +} + +QList VTOC::sectorsNotInUse() const +{ + QList retval; + + for (int track = 0; track < 35; track++) + { + for (int sector = 0; sector < 16; sector++) + { + TSPair ts(track,sector); + if (!isSectorInUse(ts)) + { + retval.append(ts); + } + } + } + return retval; +} + void VTOC::dump() { /* diff --git a/src/diskfiles/dos33/vtoc.h b/src/diskfiles/dos33/vtoc.h index 9a882d0..c91fbbe 100644 --- a/src/diskfiles/dos33/vtoc.h +++ b/src/diskfiles/dos33/vtoc.h @@ -3,6 +3,8 @@ #include #include "util.h" +#include "tspair.h" + class Sector; class QString; @@ -22,7 +24,10 @@ public: quint8 tracksPerDisk(); quint8 sectorsPerDisk(); qint16 bytesPerSector(); - bool isSectorInUse(TSPair ts); + bool isSectorInUse(TSPair ts) const; + + QList sectorsInUse() const; + QList sectorsNotInUse() const; private: QString buildUseString(quint8 track); diff --git a/src/util/applestring.cxx b/src/util/applestring.cxx index 427ef6e..bbe1d97 100644 --- a/src/util/applestring.cxx +++ b/src/util/applestring.cxx @@ -7,10 +7,16 @@ QString AppleString::printable() const QString retval; foreach (quint8 ch, *this) { retval.append(AppleChar::printable(ch)); -// if (ch > 0x80) -// retval.append(QChar(ch-0x80)); -// else -// retval.append(QChar(ch)); + } + return retval; +} + +QString AppleString::appleFontPrintable() const +{ + QString retval; + foreach (quint8 ch, *this) { + + retval.append(AppleChar::getAppleFontChar(ch)); } return retval; } @@ -30,28 +36,28 @@ QChar AppleChar::printable(quint8 val) { quint8 newval; switch (getTextSet(val)) { - case SetInvUC: + case TextSet::SetInvUC: newval = val+0x40; break; - case SetInvSp: + case TextSet::SetInvSp: newval = val; break; - case SetFlUC: + case TextSet::SetFlUC: newval = val; break; - case SetFlSp: + case TextSet::SetFlSp: newval = val-0x40; break; - case SetNormUC: + case TextSet::SetNormUC: newval = val-0x40; break; - case SetNormSp: + case TextSet::SetNormSp: newval = val-0x80; break; - case SetNormAltUC: + case TextSet::SetNormAltUC: newval = val-0x80; break; - case SetNormLC: + case TextSet::SetNormLC: default: newval = val-0x80; break; @@ -61,22 +67,22 @@ QChar AppleChar::printable(quint8 val) TextAttribute AppleChar::getAttribute(quint8 val) { - if (val <= 0x3f) { return Inverse; } - if (val <= 0x7f) { return Flash; } - if (val <= 0xbf) { return NormalLow; } - if (val <= 0xdf) { return NormalHigh; } - return NormalHigh; + if (val <= 0x3f) { return TextAttribute::Inverse; } + if (val <= 0x7f) { return TextAttribute::Flash; } + if (val <= 0xbf) { return TextAttribute::NormalLow; } + if (val <= 0xdf) { return TextAttribute::NormalHigh; } + return TextAttribute::NormalHigh; } TextSet AppleChar::getTextSet(quint8 val) { - if (val < 0x20) { return SetInvUC; } - if (val < 0x40) { return SetInvSp; } - if (val < 0x60) { return SetFlUC; } - if (val < 0x80) { return SetFlSp; } - if (val < 0xA0) { return SetNormUC; } - if (val < 0xC0) { return SetNormSp; } - if (val < 0xE0) { return SetNormAltUC; } - return SetNormLC; + if (val < 0x20) { return TextSet::SetInvUC; } + if (val < 0x40) { return TextSet::SetInvSp; } + if (val < 0x60) { return TextSet::SetFlUC; } + if (val < 0x80) { return TextSet::SetFlSp; } + if (val < 0xA0) { return TextSet::SetNormUC; } + if (val < 0xC0) { return TextSet::SetNormSp; } + if (val < 0xE0) { return TextSet::SetNormAltUC; } + return TextSet::SetNormLC; } QString AppleChar::getHtmlString(quint8 val) @@ -86,11 +92,33 @@ QString AppleChar::getHtmlString(quint8 val) htmlstring = htmlstring.toHtmlEscaped(); QString retval; - if (attribute == Inverse) { retval = QString("%1").arg(htmlstring); } - else if (attribute == Flash) { retval = QString("%1").arg(htmlstring);} - else if (attribute == NormalLow) { retval = QString("%1").arg(htmlstring);} + if (attribute == TextAttribute::Inverse) { retval = QString("%1").arg(htmlstring); } + else if (attribute == TextAttribute::Flash) { retval = QString("%1").arg(htmlstring);} + else if (attribute == TextAttribute::NormalLow) { retval = QString("%1").arg(htmlstring);} else { retval = QString("%1").arg(htmlstring);} return retval; } +QChar AppleChar::getAppleFontChar(quint8 val) +{ + if (getAttribute(val) == TextAttribute::Inverse) + { + return QChar(printable(val).unicode() + 0xe100); + } + else if (getAttribute(val) == TextAttribute::Flash) + { + return QChar(printable(val).unicode() + 0xe100); + } + else if (val >= 0x80 && val < 0xA0) + { + return QChar(val - 0x80 + 0xe800); + } + else + { + return printable(val); + } +} + + + diff --git a/src/util/applestring.h b/src/util/applestring.h index dece303..59259fd 100644 --- a/src/util/applestring.h +++ b/src/util/applestring.h @@ -22,7 +22,7 @@ public: static TextSet getTextSet(quint8 val) ; static QChar printable(quint8 val) ; static QString getHtmlString(quint8 val); - + static QChar getAppleFontChar(quint8 val); private: quint8 m_val; @@ -32,6 +32,7 @@ class AppleString : public QByteArray { public: void setData(const QByteArray &data) { insert(0,data); } QString printable() const; + QString appleFontPrintable() const; QVector attributes() const; }; diff --git a/src/util/util.h b/src/util/util.h index 6147c5e..680ac1c 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -8,26 +8,26 @@ #include #include -typedef enum { - DOSTextFile = 0x00, - DOSIntegerBasicFile = 0x01, - DOSApplesoftBasicFile = 0x02, - DOSRawBinaryFile = 0x04, - DOSTypeSFile = 0x08, - DOSRelocatableFile = 0x10, - DOSTypeAFile = 0x20, - DOSTypeBFile= 0x40, - DOSIsLocked = 0x80 -} FileTypeFlag; +enum class FileTypeFlag : quint8 { + Text = 0x00, + Integer = 0x01, + Applesoft = 0x02, + Binary = 0x04, + TypeS = 0x08, + Relocatable = 0x10, + TypeA = 0x20, + TypeB= 0x40, + IsLockedFlag = 0x80 +}; -typedef enum { +enum class TextAttribute { Inverse = 0x00, // 0x00 -- 0x3F Flash = 0x01, // 0x40 -- 0x7F NormalLow = 0x02, // 0x80 -- 0xBF NormalHigh = 0x04 // 0xC0 -- 0xFF -} TextAttribute; +}; -typedef enum { +enum class TextSet { SetInvUC = 0x00, SetInvSp = 0x20, SetFlUC = 0x40, @@ -36,52 +36,9 @@ typedef enum { SetNormSp = 0xA0, SetNormAltUC = 0xC0, SetNormLC = 0xE0 -} TextSet; - -struct TSPair { - TSPair() { m_track = m_sector = 0; } - TSPair(quint8 trackval, quint8 secval) { m_track=trackval; m_sector = secval; } - - void setTrack(quint8 tracknum) - { - // Q_ASSERT(tracknum < 35); - if (tracknum > 34 && tracknum != 0xff) { qWarning("Setting a track with value %d (> 34 and not 256).",tracknum); } - m_track = tracknum; - } - - void setSector(quint8 secnum) - { - //Q_ASSERT(secnum < 16); - if (secnum > 15 && m_track != 0xff) { qWarning("Setting a sector with value %d (> 15) on track %d.",secnum, m_track); } - m_sector = secnum; - } - - bool isValid() - { - auto retval= (m_track != 0xff && m_track < 35) && m_sector < 16; - // qDebug() << "TSPair " << track() << "," << sector() << " is " << (retval?"":"not ") << "valid"; - return retval; } - - quint8 track() const { return m_track; } - quint8 sector() const { return m_sector; } - - bool operator==(const TSPair &other) { - if (other.track() == track() && other.sector() == sector()) return true; - return false; - } - - bool operator!=(const TSPair &other) { - return !(operator==(other)); - } - - void dump() const { - //qDebug() << "TSPair: track: " << track() << " sector: " << sector(); - } -private: - quint8 m_track; - quint8 m_sector; }; + inline QString uint8ToHex(quint8 val) { QString retval = QString("%1").arg(val,2,16,QChar('0')).toUpper(); return retval;