mirror of
https://github.com/markdavidlong/AppleSAWS.git
synced 2025-01-02 22:33:03 +00:00
Added text/hex viewer for hex files
This commit is contained in:
parent
846212fe98
commit
919cf5b6eb
@ -14,6 +14,7 @@ INCLUDEPATH += src/diskfiles/dos33
|
||||
INCLUDEPATH += src/util
|
||||
INCLUDEPATH += src/applesoftfile
|
||||
INCLUDEPATH += src/binaryfile
|
||||
INCLUDEPATH += src/textfile
|
||||
INCLUDEPATH += src/ui/viewers
|
||||
INCLUDEPATH += src/imported
|
||||
INCLUDEPATH += src/internals
|
||||
@ -35,6 +36,7 @@ SOURCES += \
|
||||
src/applesoftfile/applesofttoken.cxx \
|
||||
src/binaryfile/disassembler.cxx \
|
||||
src/binaryfile/binaryfile.cxx \
|
||||
src/textfile/textfile.cxx \
|
||||
src/ui/catalogwidget.cxx \
|
||||
src/ui/mainwindow.cxx \
|
||||
src/ui/viewers/hiresviewwidget.cxx \
|
||||
@ -44,6 +46,7 @@ SOURCES += \
|
||||
src/internals/memory.cxx \
|
||||
src/ui/viewers/disassemblerviewer.cpp \
|
||||
src/ui/viewers/hexdumpviewer.cpp \
|
||||
src/ui/viewers/texthexdumpviewer.cpp \
|
||||
src/relocatablefile/relocatablefile.cxx
|
||||
|
||||
HEADERS += \
|
||||
@ -60,6 +63,7 @@ HEADERS += \
|
||||
src/applesoftfile/applesofttoken.h \
|
||||
src/binaryfile/disassembler.h \
|
||||
src/binaryfile/binaryfile.h \
|
||||
src/textfile/textfile.h \
|
||||
src/ui/catalogwidget.h \
|
||||
src/ui/mainwindow.h \
|
||||
src/ui/viewers/hiresviewwidget.h \
|
||||
@ -69,6 +73,7 @@ HEADERS += \
|
||||
src/internals/memory.h \
|
||||
src/ui/viewers/disassemblerviewer.h \
|
||||
src/ui/viewers/hexdumpviewer.h \
|
||||
src/ui/viewers/texthexdumpviewer.h \
|
||||
src/relocatablefile/relocatablefile.h
|
||||
|
||||
FORMS += \
|
||||
@ -76,4 +81,5 @@ FORMS += \
|
||||
src/ui/mainwindow.ui \
|
||||
src/ui/viewers/applesoftfileviewer.ui \
|
||||
src/ui/viewers/disassemblerviewer.ui \
|
||||
src/ui/viewers/hexdumpviewer.ui
|
||||
src/ui/viewers/hexdumpviewer.ui \
|
||||
src/ui/viewers/texthexdumpviewer.ui
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "applesoftfile.h"
|
||||
#include "binaryfile.h"
|
||||
#include "relocatablefile.h"
|
||||
#include "textfile.h"
|
||||
|
||||
DiskFile::DiskFile(QString filename)
|
||||
{
|
||||
@ -91,18 +92,22 @@ GenericFile *DiskFile::getFile(FileDescriptiveEntry fde)
|
||||
TrackSectorList tsl = getSector(fde.firstTSListSector).promoteToTrackSectorList();
|
||||
QByteArray data = getDataFromTrackSectorList(tsl);
|
||||
|
||||
if (fde.fileTypeAndFlags & DOSApplesoftBasicFile)
|
||||
if (fde.fileType() == "A")
|
||||
{
|
||||
retval = new ApplesoftFile(data);
|
||||
}
|
||||
else if (fde.fileTypeAndFlags & DOSRawBinaryFile)
|
||||
else if (fde.fileType() == "B")
|
||||
{
|
||||
retval = new BinaryFile(data);
|
||||
}
|
||||
else if (fde.fileTypeAndFlags & DOSRelocatableFile)
|
||||
else if (fde.fileType() == "R")
|
||||
{
|
||||
retval = new RelocatableFile(data);
|
||||
}
|
||||
else if ((fde.fileType() == "T"))
|
||||
{
|
||||
retval = new TextFile(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = new GenericFile(data);
|
||||
|
71
src/relocatablefile/relocatablefile.cxx
Normal file
71
src/relocatablefile/relocatablefile.cxx
Normal file
@ -0,0 +1,71 @@
|
||||
#include <QDebug>
|
||||
#include "relocatablefile.h"
|
||||
#include "util.h"
|
||||
|
||||
RelocatableFile::RelocatableFile(QByteArray data) : GenericFile(data)
|
||||
{
|
||||
// qDebug() << "Relocatable file ctor";
|
||||
if (!data.isEmpty()) {
|
||||
setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
void RelocatableFile::setData(QByteArray data)
|
||||
{
|
||||
// qDebug() << "setData()";
|
||||
if (data.length() >= 6) {
|
||||
m_starting_ram_address = (quint8) m_data[0] + ((quint8) m_data[1] * 256);
|
||||
m_ram_image_length = (quint8) m_data[2] + ((quint8) m_data[3] * 256);
|
||||
m_code_image_length = (quint8) m_data[4] + ((quint8) m_data[5] * 256);
|
||||
|
||||
int offset = 0;
|
||||
|
||||
for (int idx = 6; idx < m_code_image_length+6; idx++) {
|
||||
quint8 val = m_data[idx];
|
||||
m_binary_code_image.append(val);
|
||||
}
|
||||
|
||||
for (int N = 0; N < (m_code_image_length/4); N++) {
|
||||
offset = m_code_image_length+ 6 +(N*4);
|
||||
|
||||
// qDebug() << "N: " << N << uint8ToHex(m_data[offset])
|
||||
// << uint8ToHex(m_data[offset+1])
|
||||
// << 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]);
|
||||
m_relocatable_dict.append(rdi);
|
||||
if (rdi.isEndOfRLD()) { break; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void RelocatableFile::dump()
|
||||
{
|
||||
qDebug() << "\nTotalLength: " << length();
|
||||
qDebug() << "Starting Ram Address: " << (quint16) m_starting_ram_address << uint16ToHex(m_starting_ram_address);
|
||||
qDebug() << "Length of Ram Image: " << (quint16) m_ram_image_length << uint16ToHex(m_ram_image_length);
|
||||
qDebug() << "Length of Code Image: " << (quint16) m_code_image_length << uint16ToHex(m_code_image_length);
|
||||
|
||||
int itemIdx = 0;
|
||||
foreach (RelocatableDictItem item, m_relocatable_dict) {
|
||||
Byte4ReturnType b4rt = item.getByte4();
|
||||
QString typestr;
|
||||
if (b4rt.first == ESDSymbol) { typestr = "ESDSymbol"; }
|
||||
else if (b4rt.first == ByteHi) { typestr = "Hi Byte"; }
|
||||
else { typestr = "Lo Byte"; }
|
||||
quint16 fo = item.getFieldOffset();
|
||||
qDebug() << " Item #" << itemIdx++
|
||||
<< "Field Offset: " << uint16ToHex(fo)
|
||||
<< "FieldSize: " << ((item.getFieldSize()==RFS2Byte)?"2-Byte":"1-Byte")
|
||||
<< typestr << uint8ToHex(b4rt.second)
|
||||
<< ((item.isNotEndOfRLD())?"NotEndOfRLD":"EndOfRLD")
|
||||
<< " " << ((item.isExtern())?"Extern":"Not Extern");
|
||||
}
|
||||
|
||||
|
||||
}
|
106
src/relocatablefile/relocatablefile.h
Normal file
106
src/relocatablefile/relocatablefile.h
Normal file
@ -0,0 +1,106 @@
|
||||
#ifndef RELOCATABLEFILE_H
|
||||
#define RELOCATABLEFILE_H
|
||||
|
||||
#include <QPair>
|
||||
#include <QByteArray>
|
||||
|
||||
#include "genericfile.h"
|
||||
|
||||
|
||||
typedef enum { RFS1Byte, RFS2Byte } FieldSize;
|
||||
typedef enum { ULIsHighByte, ULIsLowByte } WordUpperLower;
|
||||
typedef enum { LowHi, HiLow } Endianness;
|
||||
typedef enum { ByteLo, ByteHi, ESDSymbol } Byte4Type;
|
||||
|
||||
typedef QPair<Byte4Type, quint8> Byte4ReturnType;
|
||||
|
||||
class RelocatableDictItem {
|
||||
public:
|
||||
RelocatableDictItem() {init(0,0,0,0); }
|
||||
RelocatableDictItem(quint8 rld, quint8 fo_low, quint8 fo_hi, quint8 lbsym) {
|
||||
init(rld,fo_low, fo_hi,lbsym);
|
||||
}
|
||||
RelocatableDictItem(quint8 rld, quint16 fo, quint8 lbsym) {
|
||||
init(rld,fo,lbsym);
|
||||
}
|
||||
|
||||
void init(quint8 rld, quint8 fo_low, quint8 fo_hi, quint8 lbsym) {
|
||||
m_rld_flag = rld;
|
||||
m_halfword_or_sym_num = lbsym;
|
||||
m_field_offset = (quint8) fo_low + ((quint8) fo_hi * 256);
|
||||
}
|
||||
|
||||
void init(quint8 rld, quint16 fo, quint8 lbsym) {
|
||||
m_rld_flag = rld;
|
||||
m_halfword_or_sym_num = lbsym;
|
||||
m_field_offset = fo;
|
||||
}
|
||||
|
||||
FieldSize getFieldSize() { return (m_rld_flag & 0x80)?RFS2Byte:RFS1Byte; }
|
||||
WordUpperLower getWordBytePos() { return (m_rld_flag & 0x40)?ULIsHighByte:ULIsLowByte; }
|
||||
Endianness getEndianness() { return (m_rld_flag & 0x20)?HiLow:LowHi; }
|
||||
bool isExtern() { return (m_rld_flag & 0x10); }
|
||||
bool isNotEndOfRLD() { return (m_rld_flag & 0x01); }
|
||||
bool isEndOfRLD() { return !(m_rld_flag & 0x01); }
|
||||
|
||||
Byte4ReturnType getByte4() {
|
||||
Byte4ReturnType retval;
|
||||
|
||||
if (isExtern()) {
|
||||
retval.first = ESDSymbol;
|
||||
} else if (getWordBytePos() == ULIsHighByte) {
|
||||
retval.first = ByteHi;
|
||||
} else {
|
||||
retval.first = ByteLo;
|
||||
}
|
||||
|
||||
retval.second = m_halfword_or_sym_num;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
quint16 getFieldOffset() { return m_field_offset; }
|
||||
|
||||
quint8 getRLDFlag() { return m_rld_flag; }
|
||||
quint8 getRawHalfWordOrSymNum() { return m_halfword_or_sym_num; }
|
||||
|
||||
private:
|
||||
|
||||
quint8 m_rld_flag;
|
||||
quint16 m_field_offset;
|
||||
quint8 m_halfword_or_sym_num;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class RelocatableFile : public GenericFile
|
||||
{
|
||||
public:
|
||||
|
||||
RelocatableFile(QByteArray data = QByteArray());
|
||||
void setData(QByteArray data);
|
||||
|
||||
quint16 length() { return m_data.length(); }
|
||||
|
||||
void dump();
|
||||
|
||||
QByteArray getBinaryCodeImage() { return m_binary_code_image; }
|
||||
QList<RelocatableDictItem> getRelocatableDict() { return m_relocatable_dict; }
|
||||
|
||||
quint16 address() { return m_starting_ram_address; }
|
||||
quint16 codeImageLength() { return m_code_image_length; }
|
||||
|
||||
protected:
|
||||
quint16 m_starting_ram_address;
|
||||
quint16 m_ram_image_length;
|
||||
quint16 m_code_image_length;
|
||||
|
||||
QByteArray m_binary_code_image;
|
||||
|
||||
QList<RelocatableDictItem> m_relocatable_dict;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
18
src/textfile/textfile.cxx
Normal file
18
src/textfile/textfile.cxx
Normal file
@ -0,0 +1,18 @@
|
||||
#include <QDebug>
|
||||
#include "textfile.h"
|
||||
|
||||
TextFile::TextFile(QByteArray data) : GenericFile(data)
|
||||
{
|
||||
if (!data.isEmpty()) {
|
||||
setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
void TextFile::setData(QByteArray data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
void TextFile::dump()
|
||||
{
|
||||
}
|
17
src/textfile/textfile.h
Normal file
17
src/textfile/textfile.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef TEXTFILE_H
|
||||
#define TEXTFILE_H
|
||||
|
||||
#include "genericfile.h"
|
||||
|
||||
class TextFile : public GenericFile
|
||||
{
|
||||
public:
|
||||
TextFile(QByteArray data = QByteArray());
|
||||
void setData(QByteArray data);
|
||||
|
||||
void dump();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif // TEXTFILE_H
|
@ -4,10 +4,13 @@
|
||||
#include "hiresviewwidget.h"
|
||||
#include "applesoftfileviewer.h"
|
||||
#include "applesoftfile.h"
|
||||
#include "textfile.h"
|
||||
#include "memory.h"
|
||||
#include "disassembler.h"
|
||||
#include "disassemblerviewer.h"
|
||||
#include "hexdumpviewer.h"
|
||||
#include "texthexdumpviewer.h"
|
||||
|
||||
#include "relocatablefile.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
@ -142,6 +145,14 @@ void MainWindow::handleDiskItemSelectedDefaultOpen(DiskFile *disk, FileDescripti
|
||||
abf->setFilename(AppleString(fde.filename).printable().trimmed());
|
||||
openInApplesoftFileViewer(abf);
|
||||
}
|
||||
else if (dynamic_cast<TextFile *>(file))
|
||||
{
|
||||
TextFile *tf = dynamic_cast<TextFile *>(file);
|
||||
tf->setFilename(AppleString(fde.filename).printable().trimmed());
|
||||
TextHexDumpViewer *thdv = new TextHexDumpViewer();
|
||||
thdv->setFile(tf);
|
||||
thdv->show();
|
||||
}
|
||||
else if (dynamic_cast<RelocatableFile *>(file))
|
||||
{
|
||||
RelocatableFile *rf = dynamic_cast<RelocatableFile *>(file);
|
||||
|
@ -18,7 +18,7 @@
|
||||
<widget class="QTextBrowser" name="textArea">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier</family>
|
||||
<family>Courier 10 Pitch</family>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
|
95
src/ui/viewers/texthexdumpviewer.cpp
Normal file
95
src/ui/viewers/texthexdumpviewer.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
#include "texthexdumpviewer.h"
|
||||
#include "ui_texthexdumpviewer.h"
|
||||
#include "applestring.h"
|
||||
|
||||
#include <QVector>
|
||||
#include <QByteArray>
|
||||
|
||||
TextHexDumpViewer::TextHexDumpViewer(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::TextHexDumpViewer)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
m_offset = 0;
|
||||
|
||||
QString title = QString("Text/Hex File Viewer");
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
TextHexDumpViewer::~TextHexDumpViewer()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString TextHexDumpViewer::makeHexStr(QByteArray data)
|
||||
{
|
||||
QString retval;
|
||||
for (int idx = 0; idx < data.length(); idx++)
|
||||
{
|
||||
retval += QString(" %1").arg((quint8) data[idx],2,16,QChar('0'));
|
||||
}
|
||||
retval.remove(0,1);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
QString TextHexDumpViewer::makeTextStr(QByteArray data)
|
||||
{
|
||||
AppleString as;
|
||||
as.setData(data);
|
||||
|
||||
QString retval = as.printable();
|
||||
|
||||
retval.replace(QChar(0x7f),QChar(0x25a9));
|
||||
|
||||
for (int idx = 0; idx <= 0x1f; idx++) {
|
||||
retval.replace(QChar(idx),QChar(idx+0x2400));
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void TextHexDumpViewer::setFile(GenericFile *file, quint16 offset)
|
||||
{
|
||||
m_offset = offset;
|
||||
QByteArray data = file->data();
|
||||
|
||||
QString title = QString("Text/Hex File Viewer: %1").arg(file->filename());
|
||||
setWindowTitle(title);
|
||||
|
||||
QStringList outputlines;
|
||||
|
||||
|
||||
QVector<QByteArray> chunks;
|
||||
|
||||
QByteArray tmpval = data;
|
||||
|
||||
while (tmpval.count()) {
|
||||
QByteArray tmpchunk = tmpval.left(16);
|
||||
tmpval.remove(0,16);
|
||||
chunks.append(tmpchunk);
|
||||
}
|
||||
|
||||
quint16 addr = 0;
|
||||
foreach (QByteArray chunk, chunks) {
|
||||
QString hexstr = makeHexStr(chunk);
|
||||
// chunk.replace(0,'.');
|
||||
QString textstr = makeTextStr(chunk);
|
||||
QString line = QString("%1: %2 %3").arg(addr,4,16,QChar('0')).arg(hexstr).arg(textstr);
|
||||
|
||||
addr += 16;
|
||||
outputlines.append(line);
|
||||
}
|
||||
|
||||
setData(qPrintable(outputlines.join("\n").toUpper()));
|
||||
}
|
||||
|
||||
void TextHexDumpViewer::setData(QByteArray data)
|
||||
{
|
||||
ui->textArea->setText(data);
|
||||
}
|
||||
|
||||
void TextHexDumpViewer::setText(QString text)
|
||||
{
|
||||
ui->textArea->setHtml(text);
|
||||
}
|
36
src/ui/viewers/texthexdumpviewer.h
Normal file
36
src/ui/viewers/texthexdumpviewer.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef TEXTHEXDUMPVIEWER_H
|
||||
#define TEXTHEXDUMPVIEWER_H
|
||||
|
||||
#include "genericfile.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class TextHexDumpViewer;
|
||||
}
|
||||
|
||||
class TextHexDumpViewer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TextHexDumpViewer(QWidget *parent = 0);
|
||||
~TextHexDumpViewer();
|
||||
|
||||
void setFile(GenericFile *file, quint16 offset = 0);
|
||||
void setData(QByteArray data);
|
||||
void setText(QString text);
|
||||
|
||||
protected:
|
||||
QString makeTextStr(QByteArray data);
|
||||
QString makeHexStr(QByteArray data);
|
||||
private:
|
||||
Ui::TextHexDumpViewer *ui;
|
||||
|
||||
quint16 m_offset;
|
||||
};
|
||||
|
||||
#endif // TEXTHEXDUMPVIEWER_H
|
31
src/ui/viewers/texthexdumpviewer.ui
Normal file
31
src/ui/viewers/texthexdumpviewer.ui
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TextHexDumpViewer</class>
|
||||
<widget class="QWidget" name="TextHexDumpViewer">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>836</width>
|
||||
<height>540</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextBrowser" name="textArea">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier</family>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -6,7 +6,10 @@ QString AppleString::printable() const
|
||||
{
|
||||
QString retval;
|
||||
foreach (quint8 ch, *this) {
|
||||
retval.append(AppleChar(ch).printable());
|
||||
if (ch > 0x80)
|
||||
retval.append(QChar(ch-0x80));
|
||||
else
|
||||
retval.append(QChar(ch));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@ -22,7 +25,6 @@ QVector<TextAttribute> AppleString::attributes() const
|
||||
}
|
||||
|
||||
|
||||
|
||||
QChar AppleChar::printable() const
|
||||
{
|
||||
quint8 newval;
|
||||
|
@ -24,6 +24,7 @@ private:
|
||||
|
||||
class AppleString : public QByteArray {
|
||||
public:
|
||||
void setData(const QByteArray &data) { insert(0,data); }
|
||||
QString printable() const;
|
||||
QVector<TextAttribute> attributes() const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user