Added text/hex viewer for hex files

This commit is contained in:
Mark Long 2016-02-26 15:06:48 -06:00
parent 846212fe98
commit 919cf5b6eb
13 changed files with 406 additions and 7 deletions

View File

@ -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

View File

@ -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);

View 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");
}
}

View 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
View 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
View 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

View File

@ -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);

View 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>

View 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);
}

View 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

View 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>

View File

@ -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;

View File

@ -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;