Added some debugging and some safeguards for not overrunning boundaries when loading corrupt disk images. Fixed default font size on sector viewer hexdump.

This commit is contained in:
mlong 2021-02-03 12:32:07 -06:00
parent 7002fc09ad
commit 659780d425
13 changed files with 161 additions and 78 deletions

View File

@ -3,13 +3,14 @@
CatalogSector::CatalogSector(Sector *data)
{
qDebug() << "### Start CatalogSector ctor";
m_data = data;
m_next = TSPair(0,0);
TSPair next(m_data->rawData()[0x01],m_data->rawData()[0x02]);
if (next.isValid())
if (next.isValid() && next.track() == 17)
{
next.dump();
qDebug("Next track sector is valid.");
@ -27,10 +28,15 @@ CatalogSector::CatalogSector(Sector *data)
{
FileDescriptiveEntry fde = makeFDE(idx*0x23+0x0B);
if (fde.firstTSListSector() != TSPair(0,0)) {
if (fde.firstTSListSector().isValid())
{
m_fdes.append(fde);
}
else qDebug() << "Not appending invalid TSPair.";
}
else { qWarning("fde.firstTSListSector() is 0,0"); }
}
qDebug() << "### End CatalogSector ctor";
}
void CatalogSector::dumpFDEs() {
@ -53,6 +59,11 @@ FileDescriptiveEntry CatalogSector::makeFDE(int offset)
fde.lengthInSectors = makeWord( m_data->rawData()[offset + 0x21],
m_data->rawData()[offset + 0x22]);
if (fde.lengthInSectors > 16*35)
{
fde.lengthInSectors = -1;
}
for (int idx = 0x03; idx <= 0x20; idx++) {
fde.filename.append(m_data->rawData()[idx+offset]);
}

View File

@ -88,6 +88,8 @@ VTOC DiskFile::getVTOC()
QList<CatalogSector> DiskFile::getCatalogSectors()
{
qDebug() << "### Start getCatalogSector";
QList<CatalogSector> retval;
VTOC vtoc = getVTOC();
TSPair ts = vtoc.firstCatalogSector();
@ -99,6 +101,8 @@ QList<CatalogSector> DiskFile::getCatalogSectors()
cs = getSector(ts).promoteToCatalogSector();
retval.append(cs);
}
qDebug() << "### End getCatalogSector";
return retval;
}
@ -111,8 +115,19 @@ GenericFile *DiskFile::getFile(FileDescriptiveEntry fde)
}
else
{
TrackSectorList tsl = getSector(fde.firstTSListSector()).promoteToTrackSectorList();
if (!fde.firstTSListSector().isValid())
{
qWarning(" Not returning a file from invalid TSList!");
return nullptr;
}
TrackSectorList tsl = getSector(fde.firstTSListSector()).promoteToTrackSectorList();
if (!fde.firstTSListSector().isValid())
{
qWarning(" Not returning a file from invalid TSList!");
return nullptr;
}
QByteArray data = getDataFromTrackSectorList(tsl);
if (fde.fileType() == "A")
@ -151,12 +166,20 @@ QByteArray DiskFile::getDataFromTrackSectorList(TrackSectorList tsl)
QByteArray retval;
foreach(TSPair pair, tsl.getDataTSPairs())
{
if (pair.isValid())
{
Sector sec = getSector(pair);
retval.append(sec.rawData());
}
else
{
qWarning("Not adding data from invalid TSList");
}
}
if (tsl.getNextTSList() != TSPair(0,0)) {
auto next = tsl.getNextTSList();
if (next.isValid() && next != TSPair(0,0)) {
TrackSectorList nextTsl = getSector(tsl.getNextTSList()).promoteToTrackSectorList();
retval.append(getDataFromTrackSectorList(nextTsl));
}
@ -164,7 +187,9 @@ QByteArray DiskFile::getDataFromTrackSectorList(TrackSectorList tsl)
return retval;
}
QList<FileDescriptiveEntry> DiskFile::getAllFDEs() {
QList<FileDescriptiveEntry> DiskFile::getAllFDEs()
{
qDebug() << "### Start getAllFDEs";
QList<FileDescriptiveEntry> retval;
QList<CatalogSector> sectors = getCatalogSectors();
@ -174,6 +199,7 @@ QList<FileDescriptiveEntry> DiskFile::getAllFDEs() {
QList<FileDescriptiveEntry> fdes = cs.getFDEs();
retval.append(fdes);
}
qDebug() << "### End getAllFDEs";
return retval;
}

View File

@ -15,7 +15,7 @@ TrackSectorList::TrackSectorList(Sector *data)
for (int idx = 0x0C; idx < 0xff; idx+=2)
{
TSPair ts(m_data->rawData()[idx],m_data->rawData()[idx+1]);
if (ts == TSPair(0,0)) {
if (ts == TSPair(0,0) && ts.isValid()) {
break;
} else {
m_ts_pairs_for_data.append(ts);

View File

@ -12,6 +12,7 @@ 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]);
}

View File

@ -39,22 +39,21 @@ void CatalogWidget::prepForNewDisk(QString filename, DiskFile *disk)
QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) {
QString retval;
retval += AppleString(fde.filename).printable().trimmed() + "\n";
retval += AppleString(fde.filename).printable().trimmed() +
(fde.deleted?"(Deleted)":"") + "\n";
retval += QString("Type: %1\n").arg(fde.fileType());
retval += QString("Sectors: %1 (%2 bytes)\n")
.arg(fde.lengthInSectors)
.arg(fde.lengthInSectors*256);
retval += QString("%1\n").arg(fde.isLocked()?"Locked":"Unlocked");
GenericFile *file = m_disk->getFile(fde);
if (!file) { return ""; }
quint16 address = file->address();
retval += QString("Address: $%1 (%2)\n").arg((quint16) (address),4,16,QChar('0'))
.arg(address);
if (dynamic_cast<BinaryFile*>(file)) {
BinaryFile *binfile = dynamic_cast<BinaryFile*>(file);
quint16 length = binfile->length();
retval += QString("Length: $%1 (%2)\n").arg((quint16) (length),4,16,QChar('0'))
.arg(length);
} else if (dynamic_cast<ApplesoftFile*>(file)) {
@ -71,12 +70,13 @@ QString CatalogWidget::createToolTip(FileDescriptiveEntry &fde) {
retval += QString("Data Length: $%1 (%2)\n").arg((quint16) (file->data().length()),4,16,QChar('0'))
.arg(file->data().length());
}
// delete file;
return retval;
}
void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, DiskFile *disk)
{
qDebug() << "### Start processNewlyLoadedDisk";
if (m_disk == disk) {
QUrl url = QUrl::fromLocalFile(diskfilename);
QString shortfilename = url.fileName();
@ -85,6 +85,7 @@ void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, DiskFile *disk)
ui->volume_label->setText(shortfilename);
int idx = 0;
foreach(FileDescriptiveEntry fde, m_disk->getAllFDEs()) {
qDebug() << " Processing FDE# " << idx;
QString filetype = fde.fileType();
QString filename = AppleString(fde.filename).printable().trimmed();
quint16 size = fde.lengthInSectors;
@ -92,7 +93,6 @@ void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, DiskFile *disk)
QString sizeStr = QString("%1").arg(size,5,10,QChar(' ')).toUpper();
QString text = QString("%1 %2 %3 %4").arg(locked?"*":" ").arg(sizeStr).arg(filetype).arg(filename);
QListWidgetItem *item = new QListWidgetItem(text);
if (filetype == "A") { item->setForeground(Qt::blue); }
else if (filetype == "I") { item->setForeground(Qt::darkYellow); }
else if (filetype == "B") { item->setForeground(Qt::darkGreen); }
@ -102,32 +102,35 @@ void CatalogWidget::processNewlyLoadedDisk(QString diskfilename, DiskFile *disk)
else if (filetype == "a") { item->setForeground(Qt::darkBlue); }
else if (filetype == "b") { item->setForeground(Qt::darkMagenta); }
else { item->setForeground(Qt::black); }
item->setToolTip(createToolTip(fde));
item->setData(0x0100,idx);
ui->catalog_list->addItem(item);
if (!fde.deleted) ui->catalog_list->addItem(item);
QRect rect = fm.boundingRect(text);
if (rect.width() > maxrect.width()) {
maxrect = rect;
}
idx++;
qDebug() << " Done Processing FDE# " << idx-1;
}
// QFont italfont = ui->catalog_list->font();
// italfont.setItalic(true);
// QListWidgetItem *item = new QListWidgetItem("Boot Sector");
// item->setForeground(Qt::black);
// item->setFont(italfont);
// item->setData(0x0100,-1);
// ui->catalog_list->addItem(item);
// QFont italfont = ui->catalog_list->font();
// italfont.setItalic(true);
// QListWidgetItem *item = new QListWidgetItem("Boot Sector");
// item->setForeground(Qt::black);
// item->setFont(italfont);
// item->setData(0x0100,-1);
// ui->catalog_list->addItem(item);
// item = new QListWidgetItem("DOS Image");
// item->setForeground(Qt::black);
// item->setFont(italfont);
// item->setData(0x0100,-2);
// ui->catalog_list->addItem(item);
// item = new QListWidgetItem("DOS Image");
// item->setForeground(Qt::black);
// item->setFont(italfont);
// item->setData(0x0100,-2);
// ui->catalog_list->addItem(item);
ui->catalog_list->resize(maxrect.width(),ui->catalog_list->size().height());
}
qDebug() << "### End processNewlyLoadedDisk";
}
void CatalogWidget::unloadDisk(DiskFile *disk)

View File

@ -112,7 +112,8 @@ void DiskExplorer::initUi()
m_frame->setMinimumSize(200,200);
QGridLayout *frameLayout = new QGridLayout(0);
m_frame->setLayout(frameLayout);
m_hdv = new HexDumpViewer(this);
m_hdv = new HexDumpViewer(this, 10);
frameLayout->addWidget(m_hdv);
m_gridLayout->setColumnStretch(0,4);
@ -196,7 +197,10 @@ void DiskExplorer::showLoadDialog(bool parentToThis)
void DiskExplorer::handleDiskItemSelectedDefaultOpen(DiskFile *disk, FileDescriptiveEntry fde)
{
if (fde.deleted) { return; }
GenericFile *file = disk->getFile(fde);
file->setFilename(AppleString(fde.filename).printable().trimmed());
ViewerBase *vb = new ViewerBase();

View File

@ -9,6 +9,7 @@
#include <QButtonGroup>
#include <QDebug>
#include <QHBoxLayout>
#include <QGuiApplication>
DiskExplorerMapWidget::DiskExplorerMapWidget(int numtracks, int numsectors, QWidget *parent) : QWidget(parent)
{
@ -242,6 +243,7 @@ QGroupBox *DiskExplorerMapWidget::makeKeyWidget()
DEButton *DiskExplorerMapWidget::buttonAt(int track, int sector)
{
qDebug() << "Button At:" << track << "," << sector;
if (track >= m_numtracks || sector >= m_numsectors)
{
if (track >= m_numtracks) { track = 0; }
@ -293,6 +295,7 @@ void DiskExplorerMapWidget::mapDiskToButtons()
int catseccount = 0;
foreach (CatalogSector cs, m_disk->getCatalogSectors())
{
// qDebug() << "LOOP 1";
Sector *sec = cs.getSector();
QString desc = QString("Catalog Sector #%1").arg(++catseccount);
@ -303,31 +306,48 @@ void DiskExplorerMapWidget::mapDiskToButtons()
foreach(FileDescriptiveEntry fde, cs.getFDEs())
{
// qDebug() << "LOOP 2";
Sector *s = &(m_disk->getSector(fde.firstTSListSector()));
TrackSectorList tsl(s);
int tsltr = fde.firstTSListSector().track();
int tslse = fde.firstTSListSector().sector();
int tslcount = 0;
while (tsltr != 0)
if (!fde.firstTSListSector().isValid())
{
qDebug() << "Invalid first tse entry. Skipping TSList.";
break;
}
int tslcount = 0;
while (tsltr != 0 /*&& tslcount < 1*/)
{
qDebug() << "LOOP 3";
tslcount++;
buttonAt(tsltr,tslse)->setBgColor(m_tsListColor);
buttonAt(tsltr,tslse)->setText(QString("%1").arg(idx));
//qDebug() << "Button" << idx << "=" << tsltr << "," << tslse << " " << fde.filename.printable() << "TSL";
// qDebug() << "Button" << idx << "=" << tsltr << "," << tslse << " " << fde.filename.printable() << "TSL";
QString description = QString("T/S List #%1 for %2").arg(tslcount).arg(fde.filename.printable());
m_sectorDescriptions.insert(DETSPair(tsltr,tslse),description);
idx++;
bool valid = true;
int sectorcount = 0;
foreach(TSPair tsp, tsl.getDataTSPairs())
auto pairs = tsl.getDataTSPairs();
// int jdx = 0;
/*if (false) */ foreach(TSPair tsp, pairs)
{
// qDebug() << "LOOP 4" << jdx++ << "of" << pairs.count() << "pairs";
//QCoreApplication::processEvents(QEventLoop::AllEvents);
int se = tsp.sector();
int tr = tsp.track();
if (valid && tsp.isValid() && (se != 0 && tr != 0)) {
QString description = QString("Sector #%1.%2 of %3")
.arg(tslcount)
.arg(++sectorcount)
@ -346,12 +366,16 @@ void DiskExplorerMapWidget::mapDiskToButtons()
else qDebug() << "Unknown file type: " << fde.fileType();
buttonAt(tr,se)->setBgColor(color);
setButtonText(tr,se,QString("%1").arg(idx));
//qDebug() << "Button" << idx << "=" << tr << "," << se << " " << fde.filename.printable();
// fde.dump();
qDebug() << "Button" << idx << "=" << tr << "," << se << " " << fde.filename.printable();
fde.dump();
}
idx++;
}
tsltr = tsl.getNextTSList().track();
tslse = tsl.getNextTSList().sector();
valid = tsl.getNextTSList().isValid();
tsl = m_disk->getSector(tsl.getNextTSList()).promoteToTrackSectorList();
}
}

View File

@ -18,8 +18,8 @@ ApplesoftFileViewer::ApplesoftFileViewer(QWidget *parent) :
m_afdv = Q_NULLPTR;
// QFont textAreaFont("PR Number 3");
QFont textAreaFont("Print Char 21");
QFont textAreaFont("PR Number 3");
// QFont textAreaFont("Print Char 21");
// textAreaFont.setStyleHint(QFont::Monospace);
textAreaFont.setPointSize(12);

View File

@ -10,18 +10,21 @@
#include "applestring.h"
#include <QChar>
HexDumpViewer::HexDumpViewer(QWidget *parent) :
HexDumpViewer::HexDumpViewer(QWidget *parent, int defaultFontSize) :
FileViewerInterface(parent),
ui(new Ui::HexDumpViewer)
{
m_defaultFontSize = defaultFontSize;
QFont textAreaFont;
textAreaFont.setStyleHint(QFont::Monospace);
if (defaultFontSize > 0) { textAreaFont.setPointSize(10); }
m_file = Q_NULLPTR;
ui->setupUi(this);
setTextFont(fontFromSettings("HexDumpViewer.textFont", textAreaFont));
setTextFont(fontFromSettings("HexDumpViewer.textFont", textAreaFont),
defaultFontSize);
m_offset = 0;
@ -184,9 +187,13 @@ bool HexDumpViewer::optionsMenuItems(QMenu *menu)
return true;
}
void HexDumpViewer::setTextFont(const QFont &font)
void HexDumpViewer::setTextFont(const QFont &font, int forcedFontSize)
{
ui->textArea->setFont(font);
QFont myfont = font;
if (forcedFontSize > 0) { myfont.setPointSize(forcedFontSize); }
qDebug() << "######################### Setting text font size " << myfont.pointSize();
ui->textArea->setFont(myfont);
}
void HexDumpViewer::setData(QByteArray data)

View File

@ -18,7 +18,7 @@ class HexDumpViewer : public FileViewerInterface
Q_OBJECT
public:
explicit HexDumpViewer(QWidget *parent = 0);
explicit HexDumpViewer(QWidget *parent = 0, int defaultFontSize = -1);
~HexDumpViewer();
void setFile(GenericFile *file) { setFile(file,0); }
@ -36,14 +36,14 @@ public slots:
void doExport();
protected:
void setTextFont(const QFont &font);
void setTextFont(const QFont &font, int forcedFontSize = -1);
private:
void setText(QString text);
void setData(QByteArray data);
QString valToAppleAscii(quint8 val);
QAction *m_setFontAction;
int m_defaultFontSize;
Ui::HexDumpViewer *ui;
quint16 m_offset;

View File

@ -24,7 +24,13 @@
<number>1</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="QTextBrowser" name="textArea"/>
<widget class="QTextBrowser" name="textArea">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>

View File

@ -6,10 +6,11 @@ QString AppleString::printable() const
{
QString retval;
foreach (quint8 ch, *this) {
if (ch > 0x80)
retval.append(QChar(ch-0x80));
else
retval.append(QChar(ch));
retval.append(AppleChar::printable(ch));
// if (ch > 0x80)
// retval.append(QChar(ch-0x80));
// else
// retval.append(QChar(ch));
}
return retval;
}