1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-27 18:55:48 +00:00

Avoid ranges entirely in favour of implicit entries.

This commit is contained in:
Thomas Harte 2023-09-10 14:25:28 -04:00
parent 2f5d710441
commit 34c631ed3b
2 changed files with 23 additions and 35 deletions

View File

@ -14,7 +14,7 @@ namespace Analyser::Static::Disassembly {
template <typename D, typename S> struct PartialDisassembly {
D disassembly;
std::vector<S> remaining_entry_points;
std::map<S, S> touched; // Maps from start of range to end.
std::vector<S> implicit_entry_points;
};
template <typename D, typename S, typename Disassembler> D Disassemble(
@ -50,18 +50,15 @@ template <typename D, typename S, typename Disassembler> D Disassemble(
break;
}
// Otherwise, find the first area between or just beyond a disassembled range
// that isn't yet disassembled and chuck it onto the list.
for(const auto &pair: partial_disassembly.touched) {
const auto end = pair.second;
if(partial_disassembly.touched.find(end) == partial_disassembly.touched.end()) {
if(address_mapper(end) < memory.size()) {
partial_disassembly.remaining_entry_points.push_back(end);
}
break;
}
}
// Otherwise, copy in the new 'implicit entry points' (i.e. all locations that are one after
// a disassembled region). There's a test above that'll ignore any which have already been
// disassembled from.
std::move(
partial_disassembly.implicit_entry_points.begin(),
partial_disassembly.implicit_entry_points.end(),
std::back_inserter(partial_disassembly.remaining_entry_points)
);
partial_disassembly.implicit_entry_points.clear();
}
return partial_disassembly.disassembly;

View File

@ -546,18 +546,6 @@ struct Z80Disassembler {
disassembly.disassembly.internal_calls.insert(entry_point);
Accessor accessor(memory, address_mapper, entry_point);
uint16_t *touched = nullptr;
auto lower_bound = disassembly.touched.lower_bound(entry_point);
if(lower_bound != disassembly.touched.begin()) {
--lower_bound;
if(lower_bound->second == entry_point) {
touched = &lower_bound->second;
}
} else {
touched = &disassembly.touched[entry_point];
*touched = entry_point;
}
while(!accessor.at_end()) {
Instruction instruction;
instruction.address = accessor.address();
@ -570,9 +558,6 @@ struct Z80Disassembler {
// Store the instruction away.
disassembly.disassembly.instructions_by_address[instruction.address] = instruction;
// Apply all touches.
*touched = accessor.address();
// Update access tables.
int access_type =
((instruction.source == Instruction::Location::Operand_Indirect) ? 1 : 0) |
@ -604,7 +589,7 @@ struct Z80Disassembler {
break;
}
// Add any (potentially) newly discovered entry point.
// Add any (potentially) newly-discovered entry point.
if( instruction.operation == Instruction::Operation::JP ||
instruction.operation == Instruction::Operation::JR ||
instruction.operation == Instruction::Operation::CALL ||
@ -613,13 +598,19 @@ struct Z80Disassembler {
}
// This is it if: an unconditional RET, RETI, RETN, JP or JR is found.
if(instruction.condition != Instruction::Condition::None) continue;
switch(instruction.operation) {
default: break;
if(instruction.operation == Instruction::Operation::RET) return;
if(instruction.operation == Instruction::Operation::RETI) return;
if(instruction.operation == Instruction::Operation::RETN) return;
if(instruction.operation == Instruction::Operation::JP) return;
if(instruction.operation == Instruction::Operation::JR) return;
case Instruction::Operation::RET:
case Instruction::Operation::RETI:
case Instruction::Operation::RETN:
case Instruction::Operation::JP:
case Instruction::Operation::JR:
if(instruction.condition == Instruction::Condition::None) {
disassembly.implicit_entry_points.push_back(accessor.address());
return;
}
}
}
}
};