Refactoring RawDiskImage out of Dos33DiskImage

This commit is contained in:
mlong 2021-02-15 16:30:02 -06:00
parent 20165005c2
commit 14301d7083
40 changed files with 938 additions and 293 deletions

View File

@ -36,6 +36,8 @@ INCLUDEPATH += src/ui/central
DEFINES += WS_VIDEO
SOURCES += \
src/diskfiles/dos33/dos33disktreeview.cpp \
src/diskfiles/rawdiskimage.cpp \
src/intbasic/IntBasicFile.cxx \
src/main.cpp \
src/diskfiles/dos33/dos33diskimage.cxx \
@ -45,7 +47,7 @@ SOURCES += \
src/diskfiles/dos33/tracksectorlist.cxx \
src/diskfiles/dos33/filedescriptiveentry.cxx \
src/diskfiles/dos33/genericfile.cxx \
src/diskfiles/dos33/tspair.cpp \
src/diskfiles/tspair.cpp \
src/diskfiles/dos33/dos33imagemodel.cpp \
src/diskfiles/dos33/dos33treeitem.cpp \
src/memory/attributedmemory.cpp \
@ -101,20 +103,23 @@ SOURCES += \
src/applesoftfile/ApplesoftRetokenizer.cpp \
src/internals/JumpLineManager.cpp \
src/ui/widgets/FlowLineTextBrowser.cpp \
src/util/chunkbytelist.cpp \
src/util/opcodes.cpp
HEADERS += \
src/diskfiles/dos33/dos33diskimage.h \
src/diskfiles/dos33/dos33disktreeview.h \
src/diskfiles/dos33/sector.h \
src/diskfiles/dos33/vtoc.h \
src/diskfiles/dos33/catalogsector.h \
src/diskfiles/dos33/tracksectorlist.h \
src/diskfiles/dos33/filedescriptiveentry.h \
src/diskfiles/dos33/genericfile.h \
src/diskfiles/dos33/tspair.h \
src/diskfiles/tspair.h \
src/diskfiles/dos33/dos33imagemodel.h\
src/diskfiles/dos33/dos33treeitem.h\
src/diskfiles/rawdiskimage.h \
src/intbasic/IntBasicFile.h \
src/memory/attributedmemory.h \
src/memory/memorycell.h \
@ -134,6 +139,7 @@ HEADERS += \
src/ui/startupdialog.h \
src/ui/viewers/intbasicfileviewer.h \
src/ui/widgets/notesdialog.h \
src/util/chunkbytelist.h \
src/util/opcodes.h \
src/util/util.h \
src/util/applestring.h \

View File

@ -11,42 +11,29 @@ ApplesoftFile::ApplesoftFile(QByteArray data) : GenericFile(data)
m_retokenizer = Q_NULLPTR;
m_data_end = data.length();
if (!data.isEmpty())
{
setData(data);
}
setAddress(0x801);
}
void ApplesoftFile::setData(QByteArray data)
void ApplesoftFile::processData()
{
if (!m_retokenizer)
{
m_retokenizer = new ApplesoftRetokenizer();
}
GenericFile::setData(data);
m_length = dataWordAt(0);
setIgnoreOffset(2);
quint8 addlo = m_data.at(0);
quint8 addhi = m_data.at(1);
m_length = makeWord(addlo,addhi);
m_data.remove(0,2);
m_retokenizer->setData(m_data);
m_retokenizer->setData(data());
m_retokenizer->parse();
m_data_end = m_retokenizer->getEndOfDataOffset();
m_lines = m_retokenizer->getRetokenizedLines();
m_flowTargets = m_retokenizer->getFlowTargets();
}
QByteArray ApplesoftFile::rawData() {
QByteArray retval;
retval.append(m_length % 255);
retval.append(m_length / 255);
retval.append(m_data);
return retval;
}
QStringList ApplesoftFile::extraDataHexValues() {
QStringList retval;
@ -72,7 +59,7 @@ QStringList ApplesoftFile::extraDataHexValues() {
QByteArray ApplesoftFile::extraData()
{
return m_data.mid(m_data_end);
return data().mid(m_data_end);
}

View File

@ -14,20 +14,22 @@
class ApplesoftFile : public GenericFile
{
friend class Dos33DiskImage;
public:
ApplesoftFile(QByteArray data = QByteArray());
void setData(QByteArray data);
QByteArray extraData();
QStringList extraDataHexValues();
QVector<ApplesoftLine> getLines() const { return m_lines; }
quint16 length() const { return m_length; }
int length() const override { return m_length; }
QByteArray rawData();
protected:
void processData();
private:
ApplesoftFile(QByteArray data = QByteArray());
QVector<ApplesoftLine> m_lines;
int m_data_end;
quint16 m_length;

View File

@ -4,8 +4,6 @@
BinaryFile::BinaryFile(QByteArray data) : GenericFile(data)
{
m_length = 0;
if (!data.isEmpty()) {
setData(data);
}
@ -15,17 +13,15 @@ void BinaryFile::setData(QByteArray data)
{
if (data.length() >= 4) {
QByteArray metadata = data.left(4);
m_data = data.mid(4);
GenericFile::setData(data.mid(4));
setAddress(makeWord(metadata[0],metadata[1]));
m_length = makeWord(metadata[2],metadata[3]);
}
setLength(makeWord(metadata[2],metadata[3]));
}
}
void BinaryFile::dump()
{
qDebug() << QString("Address: %1 Length: %2")
.arg((quint16) address(),4,16,QChar('0'))
.arg(m_length,4,16,QChar('0')).toUpper();
qDebug() << QString("Data Length Recorded: %1")
.arg(m_data.length(),4,16,QChar('0')).toUpper();
.arg(length(),4,16,QChar('0')).toUpper();
}

View File

@ -5,15 +5,15 @@
class BinaryFile : public GenericFile
{
public:
BinaryFile(QByteArray data = QByteArray());
void setData(QByteArray data) override;
friend class Dos33DiskImage;
virtual quint16 length() const override { return m_length; }
public:
void dump();
protected:
BinaryFile(QByteArray data = QByteArray());
void setData(QByteArray data) override;
};
#endif // BINARYFILE_H

View File

@ -7,7 +7,7 @@ CatalogSector::CatalogSector(Sector *data)
m_next = TSPair(0,0);
TSPair next(m_data->rawData()[0x01],m_data->rawData()[0x02]);
TSPair next(m_data->at(0x01),m_data->at(0x02));
if (next.isValid() && next.track() == 17)
{
@ -48,13 +48,13 @@ void CatalogSector::dumpFDEs() {
FileDescriptiveEntry CatalogSector::makeFDE(int offset)
{
FileDescriptiveEntry fde;
TSPair first(m_data->rawData()[offset + 0x00],m_data->rawData()[offset + 0x01]);
TSPair first(m_data->at(offset + 0x00),m_data->at(offset + 0x01));
fde.setFirstTSListSector(first);
fde.lengthInSectors = makeWord( m_data->rawData()[offset + 0x21],
m_data->rawData()[offset + 0x22]);
fde.lengthInSectors = makeWord(m_data->at(offset + 0x21),
m_data->at(offset + 0x22));
fde.fileTypeFlags = m_data->rawData()[offset + 0x02];
fde.fileTypeFlags = m_data->at(offset + 0x02);
if (fde.lengthInSectors > 16*35)
{
@ -62,7 +62,7 @@ FileDescriptiveEntry CatalogSector::makeFDE(int offset)
}
for (int idx = 0x03; idx <= 0x20; idx++) {
fde.filename.append(m_data->rawData()[idx+offset]);
fde.filename.append(m_data->at(idx+offset));
}
if (fde.firstTSListSector().track() == 0xFF)
@ -71,7 +71,7 @@ FileDescriptiveEntry CatalogSector::makeFDE(int offset)
fde.deleted = true;
qDebug() << fde.filename;
TSPair first = fde.firstTSListSector();
first.setTrack(m_data->rawData()[offset + 0x20]);
first.setTrack(m_data->at(offset + 0x20));
fde.setFirstTSListSector(first);
qDebug() << " New track: " << (quint8) fde.firstTSListSector().track();
qDebug() << " Sector: " << fde.firstTSListSector().sector();

View File

@ -16,80 +16,104 @@
Dos33DiskImage::Dos33DiskImage(QString filename)
{
m_disk_image = new RawDiskImage(filename);
if (!filename.isEmpty())
{
read(filename);
}
}
Dos33DiskImage::Dos33DiskImage(RawDiskImage *rawImage)
{
m_disk_image = rawImage;
}
Dos33DiskImage::~Dos33DiskImage()
{
foreach (GenericFile *file, m_files)
{
delete file;
}
// foreach (GenericFile *file, m_files)
// {
// delete file;
// }
}
bool Dos33DiskImage::read(QString filename)
{
m_fullImageName = filename;
m_imageName = QFileInfo(filename).fileName();
if (m_imageName.toUpper().contains(".D13"))
{
m_sectors_per_track = 13;
}
else
{
m_sectors_per_track = 16;
}
bool retval = m_disk_image->read(filename);
QFile infile(filename);
QCryptographicHash hash(QCryptographicHash::Md5);
if (infile.open(QIODevice::ReadOnly))
if (retval)
{
QByteArray contents = infile.readAll();
int expectedsize = sectorsPerTrack() * tracks() * 256;
if (contents.size() != expectedsize)
for (auto tracknum = 0; tracknum < m_disk_image->numTracks(); tracknum++)
{
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++)
{
for (int sector = 0; sector < m_sectors_per_track; sector++)
for (auto secnum = 0; secnum < m_disk_image->sectorsPerTrack(); secnum++)
{
char buffer[256];
if (qds.readRawData(buffer,256) == 256)
{
TSPair tmpts(track,sector);
Sector newSec;
newSec.setTrackSector(tmpts);
newSec.setData(QByteArray(buffer,256));
m_contents[tmpts] = newSec;
}
else
{
qDebug() << "Invalid sector read!";
return false;
}
TSPair tmpts(tracknum,secnum);
Sector newSec;
SectorData * data = m_disk_image->sectorAt(tmpts);
newSec.setData(data);
newSec.setTrackSector(tmpts);
m_contents[tmpts] = newSec;
}
}
hash.addData(contents);
m_hash = hash.result();
// qDebug() << "Hash: " << m_hash;
return true;
}
else
qDebug() << "Could not open file " << filename;
return false;
return retval;
// m_fullImageName = filename;
// m_imageName = QFileInfo(filename).fileName();
// QFile infile(filename);
// QCryptographicHash hash(QCryptographicHash::Md5);
// 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++)
// {
// for (int sector = 0; sector < m_sectors_per_track; sector++)
// {
// char buffer[256];
// if (qds.readRawData(buffer,256) == 256)
// {
// TSPair tmpts(track,sector);
// Sector newSec;
// newSec.setTrackSector(tmpts);
// newSec.setData(QByteArray(buffer,256));
// m_contents[tmpts] = newSec;
// }
// else
// {
// qDebug() << "Invalid sector read!";
// return false;
// }
// }
// }
// hash.addData(contents);
// m_hash = hash.result();
// // qDebug() << "Hash: " << m_hash;
// return true;
// }
// else
// qDebug() << "Could not open file " << filename;
// return false;
}
Sector &Dos33DiskImage::getSector(TSPair ts) { return m_contents[ts]; }
Sector &Dos33DiskImage::getSector(int track, int sector) {
return getSector(TSPair(track,sector));
}
VTOC Dos33DiskImage::getVTOC()
@ -99,8 +123,6 @@ VTOC Dos33DiskImage::getVTOC()
QList<CatalogSector> Dos33DiskImage::getCatalogSectors()
{
// qDebug() << "### Start getCatalogSector";
QList<CatalogSector> retval;
VTOC vtoc = getVTOC();
TSPair ts = vtoc.firstCatalogSector();
@ -112,7 +134,6 @@ QList<CatalogSector> Dos33DiskImage::getCatalogSectors()
cs = getSector(ts).asCatalogSector();
retval.append(cs);
}
// qDebug() << "### End getCatalogSector";
return retval;
}
@ -138,30 +159,31 @@ GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde)
qWarning(" Not returning a file from invalid TSList!");
return nullptr;
}
QByteArray data = getDataFromTrackSectorList(tsl);
setFileType(fde.fileType());
if (fileType() == "A")
{
retval = new ApplesoftFile(data);
}
else if (fileType() == "B")
{
retval = new BinaryFile(data);
}
else if (fileType() == "R")
{
retval = new RelocatableFile(data);
}
else if ((fileType() == "T"))
{
retval = new TextFile(data);
}
else if ((fileType() == "I"))
{
retval = new IntBasicFile(data);
}
else
ChunkByteList data = getDataFromTrackSectorList(tsl);
setFileType(fde.fileTypeIdentifier());
// if (fileType() == "A")
// {
// retval = new ApplesoftFile(data);
// }
// else if (fileType() == "B")
// {
// retval = new BinaryFile(data);
// }
// else if (fileType() == "R")
// {
// retval = new RelocatableFile(data);
// }
// else if ((fileType() == "T"))
// {
// retval = new TextFile(data);
// }
// else if ((fileType() == "I"))
// {
// retval = new IntBasicFile(data);
// }
// else
{
retval = new GenericFile(data);
}
@ -173,16 +195,16 @@ GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde)
}
QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl)
ChunkByteList Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl)
{
QByteArray retval;
ChunkByteList retval;
foreach(TSPair pair, tsl.getDataTSPairs())
{
if (pair.isValid())
{
Sector sec = getSector(pair);
retval.append(sec.rawData());
retval.appendChunk(sec.rawData());
}
else
{
@ -193,7 +215,7 @@ QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl)
auto next = tsl.getNextTSList();
if (next.isValid() && next != TSPair(0,0)) {
TrackSectorList nextTsl = getSector(tsl.getNextTSList()).asTrackSectorList();
retval.append(getDataFromTrackSectorList(nextTsl));
retval.appendChunkList(getDataFromTrackSectorList(nextTsl));
}
return retval;
@ -201,7 +223,6 @@ QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl)
QList<FileDescriptiveEntry> Dos33DiskImage::getAllFDEs()
{
// qDebug() << "### Start getAllFDEs";
QList<FileDescriptiveEntry> retval;
QList<CatalogSector> sectors = getCatalogSectors();
@ -211,7 +232,6 @@ QList<FileDescriptiveEntry> Dos33DiskImage::getAllFDEs()
QList<FileDescriptiveEntry> fdes = cs.getFDEs();
retval.append(fdes);
}
// qDebug() << "### End getAllFDEs";
return retval;
}
@ -224,3 +244,8 @@ QString Dos33DiskImage::getMetaDataPath() const {
return path;
}
FileList Dos33DiskImage::fileList()
{
return { };
}

View File

@ -11,22 +11,25 @@
#include "sector.h"
#include "vtoc.h"
#include "rawdiskimage.h"
#include "chunkbytelist.h"
class GenericFile;
using FileList = QList<GenericFile *>;
class Dos33DiskImage
{
public:
Dos33DiskImage(QString filename = "");
Dos33DiskImage(RawDiskImage *rawImage);
~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);
}
Sector &getSector(TSPair ts);
Sector &getSector(int track, int sector);
VTOC getVTOC();
@ -34,34 +37,36 @@ public:
GenericFile *getFile(FileDescriptiveEntry fde);
QByteArray getDataFromTrackSectorList(TrackSectorList tsl);
ChunkByteList getDataFromTrackSectorList(TrackSectorList tsl);
QList<FileDescriptiveEntry> getAllFDEs();
QByteArray fileHash() const { return m_hash; }
QString getDiskImageName() const { return m_imageName; }
QString getFullDiskImageName() const { return m_fullImageName; }
QString getDiskImageName() const { return m_disk_image->diskImageName(); }
QString getFullDiskImageName() const { return m_disk_image->fullDiskImageName(); }
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; }
int sectorsPerTrack() const { return m_disk_image->sectorsPerTrack(); }
int tracks() const { return m_disk_image->numTracks(); }
QList<GenericFile *> fileList();
private:
RawDiskImage *m_disk_image;
QMap<TSPair, Sector> m_contents;
QMap<FileDescriptiveEntry, GenericFile *> m_files;
QByteArray m_hash;
QString m_imageName;
QString m_fullImageName;
QString m_fileType;
quint8 m_sectors_per_track;
};

View File

@ -0,0 +1,32 @@
#include "dos33disktreeview.h"
#include <QGuiApplication>
Dos33DiskTreeView::Dos33DiskTreeView(QWidget *parent) : QTreeView(parent)
{
connect(this, &Dos33DiskTreeView::clicked,
this, &Dos33DiskTreeView::handleClick);
connect(this, &Dos33DiskTreeView::pressed,
this, &Dos33DiskTreeView::handlePress);
connect(this, &Dos33DiskTreeView::doubleClicked,
this, &Dos33DiskTreeView::handleDoubleClick);
}
void Dos33DiskTreeView::handleClick(const QModelIndex &/*index*/)
{
}
void Dos33DiskTreeView::handleDoubleClick(const QModelIndex &/*index*/)
{
}
void Dos33DiskTreeView::handlePress(const QModelIndex &/*index*/)
{
if (QGuiApplication::mouseButtons() & Qt::RightButton)
{
}
}

View File

@ -0,0 +1,38 @@
#ifndef DOS33DISKTREEVIEW_H
#define DOS33DISKTREEVIEW_H
#include <QTreeView>
#include <QWidget>
#include "filedescriptiveentry.h"
class Dos33DiskTreeView : public QTreeView
{
Q_OBJECT
public:
Dos33DiskTreeView(QWidget *parent = nullptr);
protected:
signals:
void fileClicked(const FileDescriptiveEntry &fde);
void fileRightClicked(const FileDescriptiveEntry &fde);
void fileDoubleClicked(const FileDescriptiveEntry &fde);
void diskClicked(QString name);
void diskRightClicked(QString name);
void sectorClicked(TSPair ts);
void sectorRightClicked(TSPair ts);
void sectorDoubleClicked(TSPair ts);
private slots:
void handleClick(const QModelIndex &index);
void handleDoubleClick(const QModelIndex &index);
void handlePress(const QModelIndex &index);
};
#endif // DOS33DISKTREEVIEW_H

View File

@ -43,7 +43,7 @@ bool Dos33ImageModel::addDiskImage(Dos33DiskImage *image, QString name)
if (!fde.deleted)
{
QString fn = AppleString(fde.filename).appleFontPrintable();
QString type = fde.fileType();
QString type = fde.fileTypeIdentifier();
QIcon icon;
if (type == "A") { icon = m_icon_A; }
@ -53,14 +53,23 @@ bool Dos33ImageModel::addDiskImage(Dos33DiskImage *image, QString name)
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; }
else if (type == "S") { icon = m_icon_S; }
auto item = new Dos33TreeItem(icon,fn);
QVariant data;
data.setValue(fde.firstTSListSector());
item->setData(data);
QVariant typevar = (int) Dos33ItemType::File;
item->setData(typevar, (int) Dos33TreeRole::ItemType);
QVariant datavar;
datavar.setValue(fde.firstTSListSector());
item->setData(datavar, (int) Dos33TreeRole::GetTSPair);
QVariant fdevar;
fdevar.setValue(fde);
item->setData(fdevar, (int) Dos33TreeRole::GetFDE);
item->setToolTip(QString("%1 Block(s)").arg(fde.lengthInSectors));
diskImageItem->appendRow(item);
}

View File

@ -9,6 +9,20 @@
#include <QIcon>
enum class Dos33TreeRole {
ItemType = Qt::UserRole,
GetTSPair,
GetFDE,
};
enum class Dos33ItemType {
Unknown,
Sector,
File,
DiskImage
};
class Dos33ImageModel : public QStandardItemModel
{
Q_OBJECT

View File

@ -21,15 +21,15 @@ struct FileDescriptiveEntry {
return f1.filename < filename;
}
QString fileType() {
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";
QString fileTypeIdentifier() {
if (fileTypeFlags & (quint8) FileTypeFlag::Integer) { return "I"; }
else if (fileTypeFlags & (quint8) FileTypeFlag::Applesoft) { return "A"; }
else if (fileTypeFlags & (quint8) FileTypeFlag::Relocatable) { return "R"; }
else if (fileTypeFlags & (quint8) FileTypeFlag::Binary) { return "B"; }
else if (fileTypeFlags & (quint8) FileTypeFlag::TypeS) { return "S"; }
else if (fileTypeFlags & (quint8) FileTypeFlag::TypeA) { return "a"; }
else if (fileTypeFlags & (quint8) FileTypeFlag::TypeB) { return "b"; }
else return "T";
}
bool isLocked() { return (fileTypeFlags & (quint8) FileTypeFlag::IsLockedFlag); }
@ -38,7 +38,7 @@ struct FileDescriptiveEntry {
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) fileTypeFlags) << "(" << fileType() << "," << (isLocked()?"Locked":"Unlocked") << ")";
qDebug() << "File Type and Flags: " << QString::number((quint8) fileTypeFlags) << "(" << fileTypeIdentifier() << "," << (isLocked()?"Locked":"Unlocked") << ")";
qDebug() << "Filename: " << filename.printable();
qDebug() << "Length in Sectors: " << lengthInSectors;
}
@ -46,7 +46,7 @@ struct FileDescriptiveEntry {
void catalog() {
QString output = QString("%1 %2 %3 %4").arg(QString(isLocked()?"*":" "))
.arg(lengthInSectors,3,10,QChar('0'))
.arg(fileType())
.arg(fileTypeIdentifier())
.arg(filename.printable().trimmed());
qDebug() << output;
}
@ -68,5 +68,5 @@ private:
TSPair m_firstTSListSector;
};
Q_DECLARE_METATYPE(FileDescriptiveEntry);
#endif // FILEDESCRIPTIVEENTRY_H

View File

@ -2,20 +2,40 @@
GenericFile::GenericFile(QByteArray data)
{
m_data_loaded = false;
m_diskfile = 0;
if (!data.isEmpty()) {
setData(data);
m_data_loaded = true;
}
m_address = 0x00;
m_length = 0x00;
m_ignore_offset = 0;
}
GenericFile::GenericFile(Dos33DiskImage *image, TSPairList pairs)
{
m_diskfile = image;
m_ts_pairs = pairs;
m_length = 0x00;
m_address = 0x00;
m_ignore_offset = 0;
m_data_loaded = false;
}
quint8 GenericFile::dataAt(int offset) const
{
return m_data[offset ];
}
void GenericFile::setData(QByteArray data)
{
m_data_loaded = true;
m_data = data;
m_length = data.size();
}
QString GenericFile::getFileType() const
{
if (m_file_type == "A" || m_file_type == "B" || m_file_type == "T" ||
@ -29,3 +49,10 @@ QString GenericFile::getFileType() const
return "?";
}
}
quint16 GenericFile::dataWordAt(int offset) const
{
return makeWord(dataAt(offset),dataAt(offset+1));
}

View File

@ -9,23 +9,22 @@
class GenericFile
{
friend class Dos33DiskImage;
public:
GenericFile(QByteArray data = QByteArray());
virtual ~GenericFile() { }
virtual void setData(QByteArray data);
virtual QByteArray data() { return m_data; }
void setFilename(QString filename) { m_filename = filename; }
virtual QByteArray data() { return m_data.mid(m_ignore_offset); }
quint8 dataAt(int offset) const;
quint16 dataWordAt(int offset) const;
virtual void setFilename(QString filename) { m_filename = filename; }
QString filename() const { return m_filename; }
virtual void setAddress(quint16 location) { m_address = location; }
virtual quint16 address() { return m_address; }
virtual QByteArray rawData() { return m_data; }
virtual void setLength(quint16 length) { m_length = length; }
virtual quint16 length() const { return m_length; }
virtual int length() const { return m_length; }
Dos33DiskImage *diskFile() const { return m_diskfile; }
void setDiskFile(Dos33DiskImage *diskfile) { m_diskfile = diskfile; }
@ -33,13 +32,27 @@ public:
void setFileType(QString type) { m_file_type = type; }
QString getFileType() const;
protected:
QByteArray rawData() const { return m_data; }
void setIgnoreOffset(int offset) { m_ignore_offset = offset; }
int ignoreOffset() const { return m_ignore_offset; }
protected:
GenericFile(Dos33DiskImage *image, QList<TSPair> pairs);
GenericFile(QByteArray data = QByteArray());
virtual void setLength(quint16 length) { m_length = length; }
virtual void setData(QByteArray data);
private:
int m_ignore_offset;
QByteArray m_data;
QString m_filename;
quint16 m_address;
qint16 m_length;
Dos33DiskImage * m_diskfile;
bool m_data_loaded;
TSPairList m_ts_pairs;
QString m_file_type;

View File

@ -3,19 +3,13 @@
#include <QString>
#include <QDebug>
QByteRef Sector::operator[](uint offset) {
quint8 Sector::operator[](uint offset) const {
if (offset > 255) {
offset = 255;
}
return m_data[offset];
return m_raw_data->at(offset);
}
bool Sector::setData(QByteArray data) {
if (data.length() != 256) return false;
m_data = data;
return true;
}
void Sector::dump() {
qDebug() << "Dumping Track " << track() << "Sector " << sector() << " ...";
@ -27,7 +21,7 @@ void Sector::dump() {
for (int idx = 0; idx < 16; idx++)
{
int offset = (jdx*16) + idx;
quint8 val = m_data[offset];
quint8 val = m_raw_data->at(offset);
line += QString("%1 ").arg(uint16ToHex(val));
if (idx == 7) line += " ";
}
@ -36,7 +30,7 @@ void Sector::dump() {
for (int idx = 0; idx < 16; idx++)
{
int offset = (jdx*16) + idx;
quint8 val = m_data[offset];
quint8 val = m_raw_data->at(offset);
if (val > 127) { val -= 128; }
QChar ch(val);
line += QString("%1").arg(ch.isPrint()?ch:'.');

View File

@ -3,6 +3,8 @@
#include <QByteArray>
#include "rawdiskimage.h"
#include "vtoc.h"
#include "catalogsector.h"
#include "tracksectorlist.h"
@ -11,12 +13,18 @@ class Sector
{
public:
Sector() {
m_data.resize(256);
Sector(SectorData *data = nullptr) {
// m_data.resize(256);
setData(data);
m_track = 255;
m_sector = 255;
}
void setData(SectorData *data)
{
m_raw_data = data;
}
VTOC promoteToVTOC() {
return VTOC(this);
}
@ -45,18 +53,19 @@ public:
void setTrack(int track) { m_track = track; }
void setSector(int sector) { m_sector = sector; }
QByteRef operator[](uint offset);
bool setData(QByteArray data);
quint8 operator[](uint offset) const;
quint8 at(int offset) { return m_raw_data->at(offset); }
void dump();
QByteArray rawData() { return m_data; }
SectorData *rawData() { return m_raw_data; }
private:
QByteArray m_data;
// QByteArray m_data;
int m_track;
int m_sector;
SectorData *m_raw_data;
};
#endif // SECTOR_H

View File

@ -6,15 +6,15 @@ TrackSectorList::TrackSectorList(Sector *data)
{
m_data = data;
m_next_tslist.setTrack(m_data->rawData()[0x01]);
m_next_tslist.setSector(m_data->rawData()[0x02]);
m_next_tslist.setTrack(m_data->at(0x01));
m_next_tslist.setSector(m_data->at(0x02));
m_sector_offset.setTrack(m_data->rawData()[0x05]);
m_sector_offset.setSector(m_data->rawData()[0x06]);
m_sector_offset.setTrack(m_data->at(0x05));
m_sector_offset.setSector(m_data->at(0x06));
for (int idx = 0x0C; idx < 0xff; idx+=2)
{
TSPair ts(m_data->rawData()[idx],m_data->rawData()[idx+1]);
TSPair ts(m_data->at(idx),m_data->at(idx+1));
if (ts == TSPair(0,0) && ts.isValid()) {
break;
} else {

View File

@ -5,6 +5,8 @@
class Sector;
using TSPairList = QList<TSPair>;
class TrackSectorList
{
public:
@ -16,14 +18,14 @@ public:
TSPair getSectorOffset() const { return m_sector_offset; }
bool isSectorOffsetValid() const;
QList<TSPair> getDataTSPairs() const { return m_ts_pairs_for_data; }
QList<TSPair> getValidTSPairs() const;
TSPairList getDataTSPairs() const { return m_ts_pairs_for_data; }
TSPairList getValidTSPairs() const;
private:
TSPair m_next_tslist;
TSPair m_sector_offset;
QList<TSPair> m_ts_pairs_for_data;
TSPairList m_ts_pairs_for_data;
Sector *m_data;
};

View File

@ -13,40 +13,40 @@ VTOC::VTOC(Sector *data)
TSPair VTOC::firstCatalogSector() {
// return TSPair(0x11,0x0f); // Force to look at the normal location
return TSPair(m_data->rawData()[0x01], m_data->rawData()[0x02]);
return TSPair(m_data->at(0x01), m_data->at(0x02));
}
quint8 VTOC::dosVersion() {
return m_data->rawData()[0x03];
return m_data->at(0x03);
}
quint8 VTOC::volumeNumber() {
return m_data->rawData()[0x06];
return m_data->at(0x06);
}
quint8 VTOC::maxTSPairs() {
return m_data->rawData()[0x27];
return m_data->at(0x27);
}
quint8 VTOC::lastTrackAllocated() {
return m_data->rawData()[0x30];
return m_data->at(0x30);
}
qint8 VTOC::directionOfAllocation() {
return m_data->rawData()[0x31];
return m_data->at(0x31);
}
quint8 VTOC::tracksPerDisk() {
return m_data->rawData()[0x34];
return m_data->at(0x34);
}
quint8 VTOC::sectorsPerDisk() {
return m_data->rawData()[0x35];
return m_data->at(0x35);
}
qint16 VTOC::bytesPerSector() {
return makeWord(m_data->rawData()[0x36],
m_data->rawData()[0x37]);
return makeWord(m_data->at(0x36),
m_data->at(0x37));
}
bool VTOC::isSectorInUse(TSPair ts) const {
@ -55,8 +55,8 @@ bool VTOC::isSectorInUse(TSPair ts) const {
quint8 baseaddr = (track * 4) + 0x38;
//quint16 word = (((quint16) m_data->rawData()[baseaddr]) *256) + (quint8) m_data->rawData()[baseaddr+1];
quint16 word = makeWord(m_data->rawData()[baseaddr+1],
m_data->rawData()[baseaddr]);
quint16 word = makeWord(m_data->at(baseaddr+1),
m_data->at(baseaddr));
quint16 bitpos = (quint16) 0x01 << (quint16) sec;
return !(word & bitpos);
@ -119,7 +119,7 @@ void VTOC::dump()
qDebug() << " Number sectors per disk: " << QString::number(sectorsPerDisk());
qDebug() << " Number bytes/sector: " << QString::number(bytesPerSector());
qDebug() << " Track Usage (.=free, 0-F=used):";
for (quint8 track = 0; track < m_data->rawData()[0x34];track++)
for (quint8 track = 0; track < m_data->at(0x34);track++)
{
qDebug() << " " << QString("Track %1:").arg((int) track,2,10,QChar('0')) << buildUseString(track);
}

View File

@ -14,17 +14,18 @@ class VTOC
public:
VTOC(Sector *data);
void dump();
void dump();
TSPair firstCatalogSector();
quint8 dosVersion();
quint8 volumeNumber();
quint8 maxTSPairs();
quint8 lastTrackAllocated();
qint8 directionOfAllocation();
qint8 directionOfAllocation();
quint8 tracksPerDisk();
quint8 sectorsPerDisk();
qint16 bytesPerSector();
bool isSectorInUse(TSPair ts) const;
bool isSectorInUse(TSPair ts) const;
QList<TSPair> sectorsInUse() const;
QList<TSPair> sectorsNotInUse() const;

View File

@ -0,0 +1,194 @@
#include "rawdiskimage.h"
#include <QFileInfo>
#include <QFile>
#include <QCryptographicHash>
#include <QDataStream>
RawDiskImage::RawDiskImage(QString name)
{
setCustomOrderMap0(dosOrderMap());
setCustomOrderMap1(prodosOrderMap());
// Set everything up assuming a 140k DOS image as a default for now
m_track_count = 35;
m_sector_size = 256;
m_sectors_per_track = 16;
m_sector_order = SectorOrder::Dos33;
m_empty_image = true;
if (!name.isEmpty())
{
read(name);
}
}
RawDiskImage::~RawDiskImage()
{
foreach (auto track, m_tracks)
{
while (track.count())
{
auto sectorblock = track.takeFirst();
delete sectorblock;
}
}
}
bool RawDiskImage::read(QString filename)
{
if (!isEmpty()) return false; // Don't reread a disk!
m_full_filename = filename;
m_filename = QFileInfo(filename).fileName();
if (m_filename.toUpper().contains(".D13"))
{
setSectorsPerTrack(13);
}
else
{
setSectorsPerTrack(16);
}
QFile infile(filename);
QCryptographicHash hash(QCryptographicHash::Md5);
if (infile.open(QIODevice::ReadOnly))
{
QByteArray contents = infile.readAll();
int expectedsize = sectorsPerTrack() * numTracks() * 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 < numTracks(); track++)
{
TrackData td;
for (int sector = 0; sector < m_sectors_per_track; sector++)
{
char buffer[256];
if (qds.readRawData(buffer,sectorSize()) == sectorSize())
{
TSPair tmpts(track,sector);
SectorData *newSec = new SectorData();
*newSec = QByteArray(buffer,sectorSize());
td.append(newSec);
}
else
{
qDebug() << "Invalid sector read!";
return false;
}
}
m_tracks.append(td);
}
hash.addData(contents);
m_hash = hash.result();
return true;
}
else
{
qDebug() << "Could not open file " << filename;
return false;
}
}
bool RawDiskImage::isEmpty() const { return m_empty_image; }
HashValue RawDiskImage::hash() const { return m_hash; }
QString RawDiskImage::diskImageName() const { return m_filename; }
QString RawDiskImage::fullDiskImageName() const { return m_full_filename; }
void RawDiskImage::setNumTracks(int count) { m_track_count = count; }
int RawDiskImage::numTracks() const { return m_track_count; }
bool RawDiskImage::hasSectors() const {return true; }
int RawDiskImage::sectorSize() const { return m_sector_size; }
void RawDiskImage::setSectorSize(int size) { m_sector_size = size; }
void RawDiskImage::setSectorsPerTrack(int spt) { m_sectors_per_track = spt; }
int RawDiskImage::sectorsPerTrack() const { return m_sectors_per_track; }
void RawDiskImage::setSectorOrder(SectorOrder order) { m_sector_order = order; }
SectorOrder RawDiskImage::sectorOrder() const { return m_sector_order; }
bool RawDiskImage::reorderSectorsTo(SectorOrder)
{
//TODO: Handle Reordering
return false;
}
SectorData *RawDiskImage::sectorAt(int track, int sector)
{
if (track >= numTracks() || sector >= sectorsPerTrack())
{
return nullptr;
}
return m_tracks[track][sector];
}
SectorData *RawDiskImage::sectorAt(TSPair ts)
{
return sectorAt(ts.track(),ts.sector());
}
SectorOrderMap RawDiskImage::dosOrderMap() const {
return QByteArrayLiteral("\x0\xD\xB\x9\x7\x5\x3\x1\xE\xC\xA\x8\x6\x4\x2\xF");
}
SectorOrderMap RawDiskImage::prodosOrderMap() const {
return QByteArrayLiteral("\x0\x8\x1\x9\x2\xA\x3\xB\x4\xC\x5\xD\x6\xE\x7\xF");
}
SectorOrderMap RawDiskImage::pascalOrderMap() const {
return QByteArrayLiteral("\x0\x2\x4\x6\x8\xA\xC\xE\x1\x3\x5\x7x9xBxDxF");
}
SectorOrderMap RawDiskImage::cpmOrderMap() const {
return QByteArrayLiteral("\x0\x3\x6\x9\xC\xF\x2\x5\x8\xB\xE\x1\x4\x7\xA\xD");
}
SectorOrderMap RawDiskImage::customOrderMap0() const { return m_custom_order_map_0; }
SectorOrderMap RawDiskImage::customOrderMap1() const { return m_custom_order_map_0; }
bool RawDiskImage::setCustomOrderMap0(SectorOrderMap map)
{
if (map.count() < m_sectors_per_track)
{
return false;
}
m_custom_order_map_0 = map.left(m_sectors_per_track);
return true;
}
bool RawDiskImage::setCustomOrderMap1(SectorOrderMap map)
{
if (map.count() < m_sectors_per_track)
{
return false;
}
m_custom_order_map_1 = map.left(m_sectors_per_track);
return true;
}

View File

@ -0,0 +1,103 @@
#ifndef RAWDISKIMAGE_H
#define RAWDISKIMAGE_H
#include "tspair.h"
#include <QString>
#include <QByteArray>
#include <QVector>
using SectorOrderMap = QByteArray;
using SectorData = QByteArray;
//PRODOS using BlockData = QByteArray;
//PRODOS using BlockPair = QPair<TSPair, TSPair>;
using TrackData = QList<SectorData*>;
using TrackList = QList<TrackData>;
using HashValue = QByteArray;
enum class SectorOrder
{
Unknown = 0,
Dos33 = 0,
ProDos,
Pascal,
CPM,
Custom1,
Custom2
};
class RawDiskImage
{
public:
RawDiskImage(QString filename = QString());
~RawDiskImage();
bool read(QString filename);
bool isEmpty() const;
HashValue hash() const;
QString diskImageName() const;
QString fullDiskImageName() const;
void setNumTracks(int count);
int numTracks() const;
bool hasSectors() const;
int sectorSize() const;
void setSectorSize(int size);
void setSectorsPerTrack(int spt);
int sectorsPerTrack() const;
//PRODOS bool hasBlocks();
//PRODOS int blockSize();
//PRODOS int blocksPerTrack();
void setSectorOrder(SectorOrder order);
SectorOrder sectorOrder() const;
bool reorderSectorsTo(SectorOrder newOrder);
SectorData *sectorAt(int track, int sector);
SectorData *sectorAt(TSPair ts);
inline SectorOrderMap dosOrderMap() const;;
inline SectorOrderMap prodosOrderMap() const;
inline SectorOrderMap pascalOrderMap() const;
inline SectorOrderMap cpmOrderMap() const;
SectorOrderMap customOrderMap0() const;
SectorOrderMap customOrderMap1() const;
bool setCustomOrderMap0(SectorOrderMap map);
bool setCustomOrderMap1(SectorOrderMap map);
private:
//PRODOS BlockPair mapBlockToTS(int blocknum);
private:
TrackList m_tracks;
bool m_empty_image;
int m_sector_size;
int m_sectors_per_track;
int m_track_count;
QString m_full_filename;
QString m_filename;
SectorOrder m_sector_order;
SectorOrderMap m_custom_order_map_0;
SectorOrderMap m_custom_order_map_1;
HashValue m_hash;
};
#endif // RAWDISKIMAGE_H

View File

@ -8,10 +8,10 @@ class TSPair
{
public:
TSPair() { m_track = m_sector = 0; }
TSPair(quint8 trackval, quint8 secval) { m_track=trackval; m_sector = secval; }
TSPair(QPair<quint8,quint8> pair) { m_track = pair.first; m_sector = pair.second;}
TSPair(int trackval, int secval) { m_track=trackval; m_sector = secval; }
TSPair(QPair<int,int> pair) { m_track = pair.first; m_sector = pair.second;}
void setTrack(quint8 tracknum)
void setTrack(int tracknum)
{
if (tracknum > 34 && tracknum != 0xff) {
qWarning("Setting a track with value %d (> 34 and not 256).",tracknum);
@ -34,8 +34,8 @@ public:
return retval; }
quint8 track() const { return m_track; }
quint8 sector() const { return m_sector; }
int track() const { return m_track; }
int sector() const { return m_sector; }
bool operator==(const TSPair &other) const {
if (other.track() == track() && other.sector() == sector()) return true;
@ -57,14 +57,14 @@ public:
}
}
QPair<quint8,quint8> toQPair() { return QPair<quint8,quint8>(track(),sector()); }
QPair<int,int> toQPair() { return QPair<quint8,quint8>(track(),sector()); }
void dump() const {
qDebug() << "TSPair: track: " << track() << " sector: " << sector();
}
private:
quint8 m_track;
quint8 m_sector;
int m_track;
int m_sector;
};
Q_DECLARE_METATYPE(TSPair);

View File

@ -6,11 +6,13 @@
class IntBasicFile : public GenericFile
{
public:
IntBasicFile(QByteArray data = QByteArray());
friend class Dos33DiskImage;
public:
QByteArray detokenize();
private:
IntBasicFile(QByteArray data = QByteArray());
quint16 get16(quint8 v1, quint8 v2);
QByteArray dumpBufferAsIntBasicFile(QByteArray origdata);
};

View File

@ -1,12 +1,4 @@
/* ---------------------------------------------------------------------------
Created by the qtsass compiler v0.1.1
The definitions are in the "qdarkstyle.qss._styles.scss" module
WARNING! All changes made in this file will be lost!
--------------------------------------------------------------------------- */
/* QDarkStyleSheet -----------------------------------------------------------
This is the main style sheet, the palette has nine colors.
@ -1010,7 +1002,7 @@ QPushButton {
padding: 3px;
outline: none;
/* Issue #194 - Special case of QPushButton inside dialogs, for better UI */
min-width: 80px;
min-width: 80px;
}
QPushButton:disabled {
@ -2187,3 +2179,13 @@ background-color: #32414B;
color: #aaa;
}
DEButton {
background-color: #505F69;
border: 1px solid #32414B;
color: #F0F0F0;
border-radius: 4px;
padding: 2px;
outline: none;
min-width: 10px;
}

View File

@ -10,18 +10,18 @@ RelocatableFile::RelocatableFile(QByteArray data) : GenericFile(data)
}
}
void RelocatableFile::setData(QByteArray data)
void RelocatableFile::setData(QByteArray /*data*/)
{
// qDebug() << "setData()";
if (data.length() >= 6) {
m_starting_ram_address = makeWord(m_data[0],m_data[1]);
m_ram_image_length = makeWord(m_data[2],m_data[3]);
m_code_image_length = makeWord(m_data[4],m_data[5]);
if (length() >= 6) {
m_starting_ram_address = dataWordAt(0);
m_ram_image_length = dataWordAt(2);
m_code_image_length = dataWordAt(4);
int offset = 0;
for (int idx = 6; idx < m_code_image_length+6; idx++) {
quint8 val = m_data[idx];
quint8 val = dataAt(idx);
m_binary_code_image.append(val);
}
@ -33,14 +33,12 @@ void RelocatableFile::setData(QByteArray data)
// << uint8ToHex(m_data[offset+2])
// << uint8ToHex(m_data[offset+3]);
RelocatableDictItem rdi = RelocatableDictItem(m_data[offset],m_data[offset+1],
m_data[offset+2],m_data[offset+3]);
RelocatableDictItem rdi = RelocatableDictItem(
dataAt(offset),dataAt(offset+1),
dataAt(offset+2),dataAt(offset+3));
m_relocatable_dict.append(rdi);
if (rdi.isEndOfRLD()) { break; }
}
}
}

View File

@ -77,12 +77,10 @@ private:
class RelocatableFile : public GenericFile
{
friend class Dos33DiskImage;
public:
RelocatableFile(QByteArray data = QByteArray());
void setData(QByteArray data);
virtual quint16 length() { return m_data.length(); }
void dump();
@ -95,6 +93,9 @@ public:
QStringList decodeRelocatableDict();
protected:
RelocatableFile(QByteArray data = QByteArray());
void setData(QByteArray data);
quint16 m_starting_ram_address;
quint16 m_ram_image_length;
quint16 m_code_image_length;

View File

@ -8,10 +8,6 @@ TextFile::TextFile(QByteArray data) : GenericFile(data)
}
}
void TextFile::setData(QByteArray data)
{
m_data = data;
}
void TextFile::dump()
{

View File

@ -5,13 +5,14 @@
class TextFile : public GenericFile
{
friend class Dos33DiskImage;
public:
TextFile(QByteArray data = QByteArray());
void setData(QByteArray data);
void dump();
protected:
TextFile(QByteArray data = QByteArray());
};
#endif // TEXTFILE_H

View File

@ -42,7 +42,7 @@ QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) {
QString retval;
retval += AppleString(fde.filename).printable().trimmed() +
(fde.deleted?"(Deleted)":"") + "\n";
retval += QString("Type: %1\n").arg(fde.fileType());
retval += QString("Type: %1\n").arg(fde.fileTypeIdentifier());
retval += QString("Sectors: %1 (%2 bytes)\n")
.arg(fde.lengthInSectors)
.arg(fde.lengthInSectors*256);
@ -54,12 +54,12 @@ QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) {
.arg(address);
if (dynamic_cast<BinaryFile*>(file)) {
BinaryFile *binfile = dynamic_cast<BinaryFile*>(file);
quint16 length = binfile->length();
auto length = binfile->length();
retval += QString("Length: $%1 (%2)\n").arg((quint16) (length),4,16,QChar('0'))
.arg(length);
} else if (dynamic_cast<ApplesoftFile*>(file)) {
ApplesoftFile *asfile = dynamic_cast<ApplesoftFile*>(file);
quint16 length = asfile->length();
auto length = asfile->length();
retval += QString("Length: $%1 (%2)\n").arg((quint16) (length),4,16,QChar('0'))
.arg(length);
quint16 uabytes = asfile->extraData().length();
@ -87,7 +87,7 @@ void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, Dos33DiskImage
int idx = 0;
foreach(FileDescriptiveEntry fde, m_disk->getAllFDEs()) {
// qDebug() << " Processing FDE# " << idx;
QString filetype = fde.fileType();
QString filetype = fde.fileTypeIdentifier();
QString filename = AppleString(fde.filename).printable().trimmed();
quint16 size = fde.lengthInSectors;
bool locked = fde.isLocked();

View File

@ -3,8 +3,9 @@
#include "dos33diskimage.h"
#include "dos33imagemodel.h"
#include "dos33disktreeview.h"
#include "sequencetoolbox.h"
#include "DiskExplorerMapWidget.h"
#include <QTreeView>
#include <QAction>
@ -15,6 +16,9 @@
#include <QDockWidget>
#include <QGridLayout>
#include <QStatusBar>
#include <QStackedWidget>
#include <QScrollArea>
#include <QFile>
@ -36,8 +40,8 @@ CentralAppWindow::CentralAppWindow(QWidget *parent) : QMainWindow(parent)
initToolBars();
initDockWidgets();
initStatusBar();
initCentralWidget();
setCentralWidget(new SequenceViewer());
}
void CentralAppWindow::createActions()
@ -74,14 +78,13 @@ void CentralAppWindow::initToolBars()
void CentralAppWindow::initDockWidgets()
{
QDockWidget *container = new QDockWidget(this);
// container->setLayout(new QGridLayout());
container->setMinimumWidth(200);
container->setFeatures(QDockWidget::DockWidgetMovable);
m_project_area = new QWidget(container);
m_project_area->setMinimumSize(300,200);
m_directory_area = new QTreeView(container);
m_directory_area = new Dos33DiskTreeView(container);
m_directory_area->setFont(QFont("Pr Number 3", 12));
m_directory_area->setMinimumSize(300,200);
@ -114,7 +117,7 @@ void CentralAppWindow::initDockWidgets()
QDockWidget *stb = new QDockWidget(this);
stb->setMinimumWidth(200);
stb->setFeatures(QDockWidget::DockWidgetMovable);
stb->setLayout(new QGridLayout());
// stb->setLayout(new QGridLayout());
m_toolbox = new SequenceToolBox(this);
@ -124,3 +127,20 @@ void CentralAppWindow::initDockWidgets()
}
void CentralAppWindow::initCentralWidget()
{
m_central_stack = new QStackedWidget(this);
QScrollArea *sa = new QScrollArea(m_central_stack);
sa->setWidgetResizable(true);
m_central_stack->addWidget(sa);
setCentralWidget(m_central_stack);
Dos33DiskImage *img = new Dos33DiskImage("c:/develop/git/AppleSAWS/disk-images/ApplesoftToolkit.dsk");
auto dew = new DiskExplorerMapWidget(img->tracks(),img->sectorsPerTrack());
dew->setDisk(img);
sa->setWidget(dew);
// m_central_stack->addWidget(dew);
//new SequenceViewer()
}

View File

@ -8,6 +8,7 @@ class QTreeView;
class QAction;
class QStatusBar;
class SequenceToolBox;
class QStackedWidget;
class CentralAppWindow : public QMainWindow
{
@ -22,6 +23,7 @@ private:
void initStatusBar();
void initToolBars();
void initDockWidgets();
void initCentralWidget();
private:
QAction *m_quitAction;
@ -32,6 +34,8 @@ private:
QStatusBar *m_status_bar;
SequenceToolBox *m_toolbox;
QStackedWidget *m_central_stack;
};
#endif // CENTRALAPPWINDOW_H

View File

@ -36,7 +36,7 @@ DiskExplorer::~DiskExplorer()
void DiskExplorer::initUi()
{
QMenuBar *menuBar = new QMenuBar(this);
setMenuBar(menuBar);
setMenuBar(menuBar);
QMenu *menu = new QMenu(tr("&File"),this);
menuBar->addMenu(menu);
@ -100,7 +100,7 @@ void DiskExplorer::initUi()
// if (!m_notesDialog) m_notesDialog = new NotesDialog(this);
// connect(action_Notes, &QAction::triggered, m_notesDialog, &NotesDialog::show);
QWidget *widget = new QWidget(0);
QWidget *widget = new QWidget(nullptr);
m_gridLayout = new QGridLayout();
m_gridLayout->setVerticalSpacing(4);
m_gridLayout->setHorizontalSpacing(4);
@ -125,7 +125,12 @@ void DiskExplorer::initUi()
m_key = m_demw->makeKeyWidget();
m_gridLayout->addWidget(m_key,1,1);
m_gridLayout->addWidget(m_frame,1,2);
this->setCentralWidget(widget);
// auto lo = new QGridLayout();
// this->setLayout(lo);
// lo->addWidget(widget);
connect(m_cw, &CatalogWidget::openWithDefaultViewer,
this, &DiskExplorer::handleDiskItemSelectedDefaultOpen);

View File

@ -25,8 +25,9 @@ DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWid
setWindowTitle("Disk Explorer");
QGridLayout *gridlayout = new QGridLayout(this);
gridlayout->setSizeConstraint(QLayout::SetFixedSize);
gridlayout->setHorizontalSpacing(2);
// gridlayout->setSizeConstraint(QLayout::SetFixedSize);
gridlayout->setSizeConstraint(QLayout::SetMinimumSize);
gridlayout->setHorizontalSpacing(1);
gridlayout->setVerticalSpacing(1);
initColors();
@ -37,7 +38,7 @@ DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWid
gridlayout->addWidget(tracklabel,0,0,1,m_numtracks+1,Qt::AlignHCenter);
for (int track= 0; track < numtracks; track++)
{
QLabel *label = new QLabel(QString("%1").arg(track));
QLabel *label = new QLabel(QString("%1").arg(track,2,10,QChar('0')));
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
gridlayout->addWidget(label,1,track+1);
}
@ -64,13 +65,16 @@ DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWid
gridlayout->addWidget(tb,sec+2,track+1);
}
}
gridlayout->addWidget(new QLabel("Stretchy Row"),18,0,1,5);
gridlayout->setRowStretch(18,900);
makeStatusWidget();
}
void DiskExplorerMapWidget::makeStatusWidget()
{
QWidget *statusWidget = new QWidget(this);
QWidget *statusWidget = new QWidget;
QHBoxLayout *hbl = new QHBoxLayout();
statusWidget->setLayout(hbl);
@ -125,8 +129,8 @@ void DiskExplorerMapWidget::handleButtonCheck(int track, int sector, bool checke
if (checked)
{
Sector sec = m_disk->getSector(track,sector);
QByteArray data = sec.rawData();
emit showSectorData(data,track,sector,QVariant());
QByteArray *data = sec.rawData();
emit showSectorData(*data,track,sector,QVariant());
m_trackSectorLabel->setText(
QString("Track: %1 Sector: %2 (%3)")
.arg(track)
@ -215,7 +219,7 @@ QLabel *DiskExplorerMapWidget::makeKeyLabel(QWidget *parent, QString name, QColo
QGroupBox *DiskExplorerMapWidget::makeKeyWidget()
{
int idx = 0;
QGroupBox *groupbox= new QGroupBox(this);
QGroupBox *groupbox= new QGroupBox();
groupbox->setTitle("Key");
QGridLayout *layout = new QGridLayout();
layout->setVerticalSpacing(0);
@ -354,15 +358,15 @@ void DiskExplorerMapWidget::mapDiskToButtons()
m_sectorDescriptions.insert(DETSPair(tr,se),description);
QColor color;
if (fde.fileType() == "I") color = m_intBasicFileColor;
else if (fde.fileType() == "A") color = m_applesoftFileColor;
else if (fde.fileType() == "R") color = m_reloFileColor;
else if (fde.fileType() == "B") color = m_binaryFileColor;
else if (fde.fileType() == "S") color = m_typeSFileColor;
else if (fde.fileType() == "T") color = m_textFileColor;
else if (fde.fileType() == "a") color = m_typeAFileColor;
else if (fde.fileType() == "b") color = m_typeBFileColor;
else qDebug() << "Unknown file type: " << fde.fileType();
if (fde.fileTypeIdentifier() == "I") color = m_intBasicFileColor;
else if (fde.fileTypeIdentifier() == "A") color = m_applesoftFileColor;
else if (fde.fileTypeIdentifier() == "R") color = m_reloFileColor;
else if (fde.fileTypeIdentifier() == "B") color = m_binaryFileColor;
else if (fde.fileTypeIdentifier() == "S") color = m_typeSFileColor;
else if (fde.fileTypeIdentifier() == "T") color = m_textFileColor;
else if (fde.fileTypeIdentifier() == "a") color = m_typeAFileColor;
else if (fde.fileTypeIdentifier() == "b") color = m_typeBFileColor;
else qDebug() << "Unknown file type: " << fde.fileTypeIdentifier();
buttonAt(tr,se)->setBgColor(color);
setButtonText(tr,se,QString("%1").arg(idx));
qDebug() << "Button" << idx << "=" << tr << "," << se << " " << fde.filename.printable();

View File

@ -8,29 +8,37 @@
#include <QColor>
#include <QGroupBox>
#include <QLabel>
#include <QToolButton>
#include "dos33diskimage.h"
class DEButton : public QPushButton
class DEButton : public QToolButton
{
Q_OBJECT
public:
DEButton(QWidget *parent,int track = -1, int sec = -1) : QPushButton(parent)
DEButton(QWidget *parent,int track = -1, int sec = -1) : QToolButton(parent)
{
setTrack(track);
setSector(sec);
connect(this, &DEButton::clicked, this, &DEButton::handleClick);
m_isHighlighted = false;
}
void setTrack(int track) { m_track = track; }
void setSector(int sector) { m_sector = sector; }
int track() const { return m_track; }
int sector() const { return m_sector; }
void clearBgColor() { m_backgroundColor = ""; setText(""); setStyleSheet(makeStyleSheet());}
void clearBgColor() {
m_backgroundColor = "";
setText("");
setStyleSheet(makeStyleSheet());
}
void setBgColor(QColor color) {
m_fgColor = determineFgColor(color).name();
@ -40,9 +48,18 @@ public:
}
bool highlighted() const { return m_isHighlighted; }
void setHighlighted(bool highlighted) { m_isHighlighted = highlighted;setStyleSheet(makeStyleSheet()); }
void reset() { setHighlighted(false); setChecked(false); makeStyleSheet(); qDebug() << "Reset";}
void setHighlighted(bool highlighted) {
m_isHighlighted = highlighted;
setStyleSheet(makeStyleSheet());
}
void reset() {
setHighlighted(false);
setChecked(false);
makeStyleSheet();
qDebug() << "Reset";
}
void resetToDefault() { clearBgColor(); reset(); }
@ -59,28 +76,41 @@ signals:
void checked(int track, int sec,bool );
private slots:
void handleClick(bool isChecked) { emit checked(m_track,m_sector,isChecked); }
void handleClick(bool isChecked) {
emit checked(m_track,m_sector,isChecked);
}
QSize minimumSizeHint() const Q_DECL_OVERRIDE { return QSize(24,24); }
QSize minimumSizeHint() const Q_DECL_OVERRIDE { return QSize(12,12); }
QSize sizeHint() const Q_DECL_OVERRIDE { return QSize(24,24); }
bool hasHeightForWidth() const Q_DECL_OVERRIDE { return true; }
int heightForWidth(int width) const Q_DECL_OVERRIDE { return width; }
private:
QString makeStyleSheet() const {
return QString(" QPushButton { font: 10px; border-width: 1px; color: %1; background-color: %2} "
" QPushButton:checked { font: bold italic 11px; } "
) .arg(m_fgColor)
return QString("DEButton { "
" font: 10px; "
" border-width: 1px; "
" color: %1; "
" background-color: %2 "
"} "
" "
"DEButton:checked { "
" font: bold italic 11px; "
"}"
).arg(m_fgColor)
.arg(m_backgroundColor);
}
int m_track;
int m_sector;
bool m_isHighlighted;
QString m_fgColor;
QString m_backgroundColor;
QString m_hlColor;
};

View File

@ -0,0 +1,80 @@
#include "chunkbytelist.h"
ChunkByteList::ChunkByteList() { }
ChunkByteList &ChunkByteList::appendChunk(QByteArray *chunk)
{
if (chunk)
{
m_chunk_list.append(chunk);
}
return *this;
}
ChunkByteList &ChunkByteList::appendChunkList(ChunkByteList other)
{
if (&other != this)
{
for (auto count = 0; count < other.numChunks(); count++)
{
m_chunk_list.append(other.getChunk(count));
}
}
return *this;
}
int ChunkByteList::count() const
{
int size = 0;
foreach (auto chunk, m_chunk_list)
{
size += chunk->size();
}
return size;
}
int ChunkByteList::size() const
{
return count();
}
int ChunkByteList::length() const
{
return count();
}
bool ChunkByteList::isEmpty() const
{
if (m_chunk_list.size() == 0) return true;
foreach (auto chunk, m_chunk_list)
{
if (!chunk->isEmpty()) return false;
}
return false;
}
char ChunkByteList::at(int i) const
{
int offset = 0;
foreach (auto chunk, m_chunk_list)
{
int upperbound = offset + chunk->size();
if (i < upperbound)
{
return chunk->at(i-offset);
}
else
{
offset += chunk->size();
}
}
return 0;
}
char ChunkByteList::operator[](int i) const
{
return at(i);
}

43
src/util/chunkbytelist.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef CHUNKBYTELIST_H
#define CHUNKBYTELIST_H
#include <QByteArray>
#include <QList>
class ChunkByteList
{
public:
ChunkByteList();
ChunkByteList &appendChunk(QByteArray *chunk);
ChunkByteList &appendChunkList(ChunkByteList other);
int count() const;
int size() const;
int length() const;
bool isEmpty() const;
char at(int i) const;
char operator[](int i) const;
int numChunks() const { return m_chunk_list.size(); }
QByteArray *getChunk(int chunk) const { return m_chunk_list[chunk]; }
QByteArray asQByteArray() const {
QByteArray retval;
foreach (auto chunk, m_chunk_list)
{
retval.append(*chunk);
}
return retval;
}
operator QByteArray() { return asQByteArray(); }
private:
QList<QByteArray *> m_chunk_list;
};
#endif // CHUNKBYTELIST_H

View File

@ -39,6 +39,8 @@ enum class TextSet {
};
inline QString uint8ToHex(quint8 val) {
QString retval = QString("%1").arg(val,2,16,QChar('0')).toUpper();
return retval;