227 lines
6.3 KiB
C++
227 lines
6.3 KiB
C++
/*****************************************************************************
|
|
* AppleSAWS - The Apple Software Analysis WorkShop *
|
|
* Copyright (C) 2015-2021 Mark D. Long *
|
|
* *
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
|
*****************************************************************************/
|
|
|
|
#include "dos33diskimage.h"
|
|
|
|
#include "tracksectorlist.h"
|
|
#include "genericfile.h"
|
|
#include "applesoftfile.h"
|
|
#include "binaryfile.h"
|
|
#include "intbasicfile.h"
|
|
#include "relocatablefile.h"
|
|
#include "textfile.h"
|
|
#include "sector.h"
|
|
|
|
#include <QFile>
|
|
#include <QDataStream>
|
|
#include <QFileInfo>
|
|
#include <QDebug>
|
|
#include <QDir>
|
|
|
|
Dos33DiskImage::Dos33DiskImage(QString filename)
|
|
{
|
|
m_disk_image = new ASDiskData();
|
|
if (!filename.isEmpty())
|
|
{
|
|
read(filename);
|
|
}
|
|
}
|
|
|
|
Dos33DiskImage::~Dos33DiskImage()
|
|
{
|
|
delete m_disk_image;
|
|
}
|
|
|
|
bool Dos33DiskImage::read(QString filename)
|
|
{
|
|
ASDiskImporter importer;
|
|
bool retval = importer.importImage(filename, *m_disk_image);
|
|
|
|
// TODO: Cache sectors!!
|
|
|
|
return retval;
|
|
}
|
|
|
|
pSector Dos33DiskImage::getSector(TSPair ts) const {
|
|
return getSector(ts.track(),ts.sector());
|
|
}
|
|
|
|
pSector Dos33DiskImage::getSector(int track, int sector) const {
|
|
auto sectorData
|
|
= m_disk_image->getSector(track,sector);
|
|
qDebug() << "Dos33DiskImage::getSector("<<track<<","<<sector<<"); [SIZE = " << sectorData.size() << "]";
|
|
auto val = QSharedPointer<Sector>(new Sector(sectorData, track, sector));
|
|
val->dump();
|
|
return val;
|
|
}
|
|
|
|
VTOC Dos33DiskImage::getVTOC() const
|
|
{
|
|
return getSector(17,0)->promoteToVTOC();
|
|
}
|
|
|
|
QList<CatalogSector> Dos33DiskImage::getCatalogSectors()
|
|
{
|
|
QList<CatalogSector> retval;
|
|
VTOC vtoc = getVTOC();
|
|
TSPair ts = vtoc.firstCatalogSector();
|
|
qDebug() << "First TSPair for catalogsectors is " << ts.track() << "," << ts.sector();
|
|
|
|
CatalogSector cs = getSector(ts)->asCatalogSector();
|
|
retval.append(cs);
|
|
while (cs.nextCatalogSector() != TSPair(0,0)) {
|
|
ts = cs.nextCatalogSector();
|
|
qDebug() << "Next TSPair for catalogsectors is " << ts.track() << "," << ts.sector();
|
|
|
|
cs = getSector(ts)->asCatalogSector();
|
|
retval.append(cs);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
GenericFile *Dos33DiskImage::getFile(FileDescriptiveEntry fde)
|
|
{
|
|
GenericFile *retval = 0;
|
|
if (m_files.contains(fde))
|
|
{
|
|
retval = m_files[fde];
|
|
}
|
|
else
|
|
{
|
|
if (!fde.firstTSListSector().isValid())
|
|
{
|
|
qWarning(" Not returning a file from invalid TSList!");
|
|
return nullptr;
|
|
}
|
|
|
|
TrackSectorList tsl = getSector(fde.firstTSListSector())->asTrackSectorList();
|
|
if (!fde.firstTSListSector().isValid())
|
|
{
|
|
qWarning(" Not returning a file from invalid TSList!");
|
|
return nullptr;
|
|
}
|
|
|
|
auto type = fde.fileTypeIdentifier();
|
|
|
|
if (type == "A")
|
|
{
|
|
retval = new ApplesoftFile(this,fde);
|
|
}
|
|
else if (type == "B")
|
|
{
|
|
retval = new BinaryFile(this,fde);
|
|
}
|
|
else if (type == "R")
|
|
{
|
|
retval = new RelocatableFile(this,fde);
|
|
}
|
|
else if ((type == "T"))
|
|
{
|
|
retval = new TextFile(this,fde);
|
|
}
|
|
else if ((type == "I"))
|
|
{
|
|
retval = new IntBasicFile(this,fde);
|
|
}
|
|
else
|
|
{
|
|
retval = new GenericFile(this,fde);
|
|
}
|
|
retval->updateFromFDE(fde);
|
|
m_files[fde] = retval;
|
|
}
|
|
if (retval) { retval->setDiskFile(this); }
|
|
return retval;
|
|
}
|
|
|
|
|
|
QByteArray Dos33DiskImage::getDataFromTrackSectorList(TrackSectorList tsl)
|
|
{
|
|
QByteArray retval;
|
|
|
|
|
|
foreach(TSPair pair, tsl.getDataTSPairs())
|
|
{
|
|
if (pair.isValid())
|
|
{
|
|
pSector sec = getSector(pair);
|
|
retval.append(sec->rawData());
|
|
}
|
|
else
|
|
{
|
|
qWarning("Not adding data from invalid TSList");
|
|
}
|
|
}
|
|
|
|
auto next = tsl.getNextTSList();
|
|
if (next.isValid() && next != TSPair(0,0)) {
|
|
TrackSectorList nextTsl = getSector(tsl.getNextTSList())->asTrackSectorList();
|
|
retval.append(getDataFromTrackSectorList(nextTsl));
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
QByteArray Dos33DiskImage::getDataFromTSPairList(TSPairList list)
|
|
{
|
|
QByteArray retval;
|
|
foreach(TSPair pair, list)
|
|
{
|
|
if (pair.isValid())
|
|
{
|
|
pSector sec = getSector(pair);
|
|
retval.append(sec->rawData());
|
|
}
|
|
else
|
|
{
|
|
qWarning("Not adding data from invalid TSPairList");
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
QList<FileDescriptiveEntry> Dos33DiskImage::getAllFDEs()
|
|
{
|
|
QList<FileDescriptiveEntry> retval;
|
|
|
|
QList<CatalogSector> sectors = getCatalogSectors();
|
|
|
|
foreach (CatalogSector cs, sectors)
|
|
{
|
|
QList<FileDescriptiveEntry> fdes = cs.getFDEs();
|
|
retval.append(fdes);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
QString Dos33DiskImage::getMetaDataPath() const {
|
|
QString path = QString("%1.metadata/").arg(getFullDiskImageName());
|
|
|
|
QDir dir(path);
|
|
dir.mkpath(".");
|
|
|
|
return path;
|
|
}
|
|
|
|
FileList Dos33DiskImage::fileList()
|
|
{
|
|
return { };
|
|
}
|
|
|