174 lines
4.6 KiB
C++
174 lines
4.6 KiB
C++
#include "JumpLineManager.h"
|
|
|
|
JumpLineManager::JumpLineManager(quint16 from, quint16 to)
|
|
: m_start(from),
|
|
m_end(to)
|
|
{
|
|
//qDebug() << "JumpLineManager(from:"<<uint16ToHex(m_start)<<", to:"<<uint16ToHex(m_end) << ")";
|
|
|
|
}
|
|
|
|
void JumpLineManager::addJump(quint16 src, quint16 dest, JumpType type, quint16 from, quint16 to)
|
|
{
|
|
TJump jump(src,dest);
|
|
if (src >= from && src <= to && dest >= from && dest <= to)
|
|
{
|
|
if (!m_jumpmap.contains(jump))
|
|
{
|
|
// qDebug() << "JumpLineManager::addJump: Added Jump from" << uint16ToHex(src) << "to" << uint16ToHex(dest) << ", Type:" << type;
|
|
m_jumpmap.insert(jump,type);
|
|
}
|
|
else
|
|
{
|
|
//qDebug() << "JumpLineManager::addJump: Not adding duplicate jump:" << uint16ToHex(src) << "," << uint16ToHex(dest);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// qDebug() << "JumpLineManager::addJump: Address range is out of bounds";
|
|
|
|
}
|
|
}
|
|
|
|
void JumpLineManager::dumpJumps() const {
|
|
dumpJumps(m_jumpmap);
|
|
}
|
|
|
|
void JumpLineManager::dumpJumps(JumpMap map) const
|
|
{
|
|
//qDebug() << "JumpLineManager::dumpJumps()\n JumpTable:";
|
|
QMapIterator<TJump,JumpType> it(map);
|
|
while (it.hasNext())
|
|
{
|
|
it.next();
|
|
QString jumptypelabel;
|
|
if (it.value() == IsUnknownJump) { jumptypelabel = "Unknown Jump"; }
|
|
if (it.value() == IsJMP) { jumptypelabel = "JMP"; }
|
|
if (it.value() == IsBranch) { jumptypelabel = "Branch"; }
|
|
if (it.value() == IsJSR) { jumptypelabel = "JSR"; }
|
|
if (it.value() == IsBRA) { jumptypelabel = "BRA"; }
|
|
//qDebug() << " Jump from" << uint16ToHex(it.key().first) << "to"
|
|
// << uint16ToHex(it.key().second) << jumptypelabel;
|
|
}
|
|
}
|
|
|
|
JumpLines JumpLineManager::buildJumpLines()
|
|
{
|
|
//qDebug() << "A";
|
|
|
|
m_channelsAtAddress.clear();
|
|
m_jumplines.m_maxChannel = 0;
|
|
QMapIterator<TJump, JumpType> it(m_jumpmap);
|
|
while (it.hasNext())
|
|
{
|
|
it.next();
|
|
TJump range = it.key();
|
|
|
|
JumpLine jl;
|
|
jl.type = it.value();
|
|
jl.from = range.first;
|
|
jl.to = range.second;
|
|
int channel = findBestChannel(jl);
|
|
setChannelForJumpLine(channel,jl);
|
|
|
|
m_jumplines.jumpLines.append(jl);
|
|
m_jumplines.m_maxChannel = qMax(m_jumplines.m_maxChannel, channel);
|
|
}
|
|
//qDebug() << "A";
|
|
|
|
|
|
return m_jumplines;
|
|
|
|
}
|
|
|
|
|
|
|
|
int JumpLineManager::findBestChannel(JumpLine &jl)
|
|
{
|
|
//qDebug() << "findBestChannel()";
|
|
if (m_jumplines.jumpLines.count() == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int potentialChannel = 0;
|
|
bool foundChannel = false;
|
|
while (!foundChannel)
|
|
{
|
|
//qDebug() << "Tryning potential channel" << potentialChannel;
|
|
bool matched = false;
|
|
for (quint16 addr = jl.min(); addr <= jl.max(); addr++)
|
|
{
|
|
// If any of these addresses contain the potential channel, move on
|
|
if (m_channelsAtAddress[addr].contains(potentialChannel))
|
|
{
|
|
matched = true;
|
|
}
|
|
}
|
|
if (matched)
|
|
{
|
|
potentialChannel++;
|
|
matched = false;
|
|
}
|
|
else
|
|
{
|
|
foundChannel = true;
|
|
}
|
|
}
|
|
return potentialChannel;
|
|
}
|
|
|
|
void JumpLineManager::setChannelForJumpLine(int channel, JumpLine &jl)
|
|
{
|
|
jl.channel = channel;
|
|
for (quint16 addr = jl.min(); addr <= jl.max(); addr++)
|
|
{
|
|
m_channelsAtAddress[addr].append(channel);
|
|
}
|
|
}
|
|
|
|
void JumpLineManager::dumpJumpLines() const
|
|
{
|
|
//foreach (JumpLine jl, m_jumplines.jumpLines)
|
|
// {
|
|
//qDebug() << " JumpLine from:" << uint16ToHex(jl.from)
|
|
// << " to:" << uint16ToHex(jl.to)
|
|
// << "channel: " << jl.channel << " type:" << jl.type;
|
|
// }
|
|
}
|
|
|
|
bool JumpLineManager::doJumpsIntersect(TJump &A, TJump &B) const
|
|
{
|
|
|
|
if (A == B) return false;
|
|
if (isLineWithinRange(A.first,B) || isLineWithinRange(A.second,B))
|
|
return true;
|
|
|
|
if (isLineWithinRange(B.first,A) || isLineWithinRange(B.second,A))
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool JumpLineManager::isLineWithinRange(quint16 line, TJump &jm) const
|
|
{
|
|
quint16 min = qMin(jm.first,jm.second);
|
|
quint16 max = qMax(jm.first,jm.second);
|
|
|
|
return (line > min && line < max);
|
|
}
|
|
|
|
QList<JumpLine> JumpLines::jumpLinesAtAddress(quint16 addrs)
|
|
{
|
|
QList<JumpLine> list;
|
|
foreach (JumpLine jl, jumpLines)
|
|
{
|
|
if (addrs >= jl.min() && addrs <= jl.max())
|
|
{
|
|
list.append(jl);
|
|
}
|
|
}
|
|
return list;
|
|
}
|