mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-27 00:30:26 +00:00
Adds further costs.
This commit is contained in:
parent
05c3f2a30d
commit
fcb8bd00b6
@ -15,16 +15,16 @@ float ConfidenceCounter::get_confidence() {
|
||||
}
|
||||
|
||||
void ConfidenceCounter::add_hit() {
|
||||
hits_++;
|
||||
++hits_;
|
||||
}
|
||||
|
||||
void ConfidenceCounter::add_miss() {
|
||||
misses_++;
|
||||
++misses_;
|
||||
}
|
||||
|
||||
void ConfidenceCounter::add_equivocal() {
|
||||
if(hits_ > misses_) {
|
||||
hits_++;
|
||||
misses_++;
|
||||
++hits_;
|
||||
++misses_;
|
||||
}
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ class ConfidenceSummary: public ConfidenceSource {
|
||||
float get_confidence() final;
|
||||
|
||||
private:
|
||||
std::vector<ConfidenceSource *> sources_;
|
||||
std::vector<float> weights_;
|
||||
const std::vector<ConfidenceSource *> sources_;
|
||||
const std::vector<float> weights_;
|
||||
float weight_sum_;
|
||||
};
|
||||
|
||||
|
@ -21,8 +21,8 @@ std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetDFSCatalogue(const std::s
|
||||
auto catalogue = std::make_unique<Catalogue>();
|
||||
Storage::Encodings::MFM::Parser parser(false, disk);
|
||||
|
||||
Storage::Encodings::MFM::Sector *names = parser.get_sector(0, 0, 0);
|
||||
Storage::Encodings::MFM::Sector *details = parser.get_sector(0, 0, 1);
|
||||
const Storage::Encodings::MFM::Sector *const names = parser.get_sector(0, 0, 0);
|
||||
const Storage::Encodings::MFM::Sector *const details = parser.get_sector(0, 0, 1);
|
||||
|
||||
if(!names || !details) return nullptr;
|
||||
if(names->samples.empty() || details->samples.empty()) return nullptr;
|
||||
@ -84,7 +84,7 @@ std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetADFSCatalogue(const std::
|
||||
std::vector<uint8_t> root_directory;
|
||||
root_directory.reserve(5 * 256);
|
||||
for(uint8_t c = 2; c < 7; c++) {
|
||||
Storage::Encodings::MFM::Sector *sector = parser.get_sector(0, 0, c);
|
||||
const Storage::Encodings::MFM::Sector *const sector = parser.get_sector(0, 0, c);
|
||||
if(!sector) return nullptr;
|
||||
root_directory.insert(root_directory.end(), sector->samples[0].begin(), sector->samples[0].end());
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
||||
if(segment.data.size() != 0x4000 && segment.data.size() != 0x2000) continue;
|
||||
|
||||
// is a copyright string present?
|
||||
uint8_t copyright_offset = segment.data[7];
|
||||
const uint8_t copyright_offset = segment.data[7];
|
||||
if(
|
||||
segment.data[copyright_offset] != 0x00 ||
|
||||
segment.data[copyright_offset+1] != 0x28 ||
|
||||
@ -83,8 +83,8 @@ Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets(const Media &me
|
||||
// check also for a continuous threading of BASIC lines; if none then this probably isn't BASIC code,
|
||||
// so that's also justification to *RUN
|
||||
std::size_t pointer = 0;
|
||||
uint8_t *data = &files.front().data[0];
|
||||
std::size_t data_size = files.front().data.size();
|
||||
uint8_t *const data = &files.front().data[0];
|
||||
const std::size_t data_size = files.front().data.size();
|
||||
while(1) {
|
||||
if(pointer >= data_size-1 || data[pointer] != 13) {
|
||||
is_basic = false;
|
||||
|
@ -43,7 +43,7 @@ static std::unique_ptr<File::Chunk> GetNextChunk(const std::shared_ptr<Storage::
|
||||
while(!tape->is_at_end() && name_ptr < sizeof(name)) {
|
||||
name[name_ptr] = char(parser.get_next_byte(tape));
|
||||
if(!name[name_ptr]) break;
|
||||
name_ptr++;
|
||||
++name_ptr;
|
||||
}
|
||||
name[sizeof(name)-1] = '\0';
|
||||
new_chunk->name = name;
|
||||
|
@ -16,13 +16,11 @@ using namespace Analyser::Static::Atari2600;
|
||||
using Target = Analyser::Static::Atari2600::Target;
|
||||
|
||||
static void DeterminePagingFor2kCartridge(Target &target, const Storage::Cartridge::Cartridge::Segment &segment) {
|
||||
// if this is a 2kb cartridge then it's definitely either unpaged or a CommaVid
|
||||
uint16_t entry_address, break_address;
|
||||
// If this is a 2kb cartridge then it's definitely either unpaged or a CommaVid.
|
||||
const uint16_t entry_address = uint16_t(segment.data[0x7fc] | (segment.data[0x7fd] << 8)) & 0x1fff;
|
||||
const uint16_t break_address = uint16_t(segment.data[0x7fe] | (segment.data[0x7ff] << 8)) & 0x1fff;
|
||||
|
||||
entry_address = uint16_t(segment.data[0x7fc] | (segment.data[0x7fd] << 8)) & 0x1fff;
|
||||
break_address = uint16_t(segment.data[0x7fe] | (segment.data[0x7ff] << 8)) & 0x1fff;
|
||||
|
||||
// a CommaVid start address needs to be outside of its RAM
|
||||
// A CommaVid start address needs to be outside of its RAM.
|
||||
if(entry_address < 0x1800 || break_address < 0x1800) return;
|
||||
|
||||
std::function<std::size_t(uint16_t address)> high_location_mapper = [](uint16_t address) {
|
||||
@ -32,8 +30,8 @@ static void DeterminePagingFor2kCartridge(Target &target, const Storage::Cartrid
|
||||
Analyser::Static::MOS6502::Disassembly high_location_disassembly =
|
||||
Analyser::Static::MOS6502::Disassemble(segment.data, high_location_mapper, {entry_address, break_address});
|
||||
|
||||
// assume that any kind of store that looks likely to be intended for large amounts of memory implies
|
||||
// large amounts of memory
|
||||
// Assume that any kind of store that looks likely to be intended for large amounts of memory implies
|
||||
// large amounts of memory.
|
||||
bool has_wide_area_store = false;
|
||||
for(std::map<uint16_t, Analyser::Static::MOS6502::Instruction>::value_type &entry : high_location_disassembly.instructions_by_address) {
|
||||
if(entry.second.operation == Analyser::Static::MOS6502::Instruction::STA) {
|
||||
@ -45,17 +43,17 @@ static void DeterminePagingFor2kCartridge(Target &target, const Storage::Cartrid
|
||||
}
|
||||
}
|
||||
|
||||
// conclude that this is a CommaVid if it attempted to write something to the CommaVid RAM locations;
|
||||
// Conclude that this is a CommaVid if it attempted to write something to the CommaVid RAM locations;
|
||||
// caveat: false positives aren't likely to be problematic; a false positive is a 2KB ROM that always addresses
|
||||
// itself so as to land in ROM even if mapped as a CommaVid and this code is on the fence as to whether it
|
||||
// attempts to modify itself but it probably doesn't
|
||||
// attempts to modify itself but it probably doesn't.
|
||||
if(has_wide_area_store) target.paging_model = Target::PagingModel::CommaVid;
|
||||
}
|
||||
|
||||
static void DeterminePagingFor8kCartridge(Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
||||
// Activision stack titles have their vectors at the top of the low 4k, not the top, and
|
||||
// always list 0xf000 as both vectors; they do not repeat them, and, inexplicably, they all
|
||||
// issue an SEI as their first instruction (maybe some sort of relic of the development environment?)
|
||||
// issue an SEI as their first instruction (maybe some sort of relic of the development environment?).
|
||||
if(
|
||||
segment.data[4095] == 0xf0 && segment.data[4093] == 0xf0 && segment.data[4094] == 0x00 && segment.data[4092] == 0x00 &&
|
||||
(segment.data[8191] != 0xf0 || segment.data[8189] != 0xf0 || segment.data[8190] != 0x00 || segment.data[8188] != 0x00) &&
|
||||
@ -65,7 +63,7 @@ static void DeterminePagingFor8kCartridge(Target &target, const Storage::Cartrid
|
||||
return;
|
||||
}
|
||||
|
||||
// make an assumption that this is the Atari paging model
|
||||
// Make an assumption that this is the Atari paging model.
|
||||
target.paging_model = Target::PagingModel::Atari8k;
|
||||
|
||||
std::set<uint16_t> internal_accesses;
|
||||
@ -91,7 +89,7 @@ static void DeterminePagingFor8kCartridge(Target &target, const Storage::Cartrid
|
||||
}
|
||||
|
||||
static void DeterminePagingFor16kCartridge(Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
||||
// make an assumption that this is the Atari paging model
|
||||
// Make an assumption that this is the Atari paging model.
|
||||
target.paging_model = Target::PagingModel::Atari16k;
|
||||
|
||||
std::set<uint16_t> internal_accesses;
|
||||
@ -111,7 +109,7 @@ static void DeterminePagingFor16kCartridge(Target &target, const Storage::Cartri
|
||||
}
|
||||
|
||||
static void DeterminePagingFor64kCartridge(Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
||||
// make an assumption that this is a Tigervision if there is a write to 3F
|
||||
// Make an assumption that this is a Tigervision if there is a write to 3F.
|
||||
target.paging_model =
|
||||
(disassembly.external_stores.find(0x3f) != disassembly.external_stores.end()) ?
|
||||
Target::PagingModel::Tigervision : Target::PagingModel::MegaBoy;
|
||||
@ -123,17 +121,15 @@ static void DeterminePagingForCartridge(Target &target, const Storage::Cartridge
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t entry_address, break_address;
|
||||
|
||||
entry_address = uint16_t(segment.data[segment.data.size() - 4] | (segment.data[segment.data.size() - 3] << 8));
|
||||
break_address = uint16_t(segment.data[segment.data.size() - 2] | (segment.data[segment.data.size() - 1] << 8));
|
||||
const uint16_t entry_address = uint16_t(segment.data[segment.data.size() - 4] | (segment.data[segment.data.size() - 3] << 8));
|
||||
const uint16_t break_address = uint16_t(segment.data[segment.data.size() - 2] | (segment.data[segment.data.size() - 1] << 8));
|
||||
|
||||
std::function<std::size_t(uint16_t address)> address_mapper = [](uint16_t address) {
|
||||
if(!(address & 0x1000)) return size_t(-1);
|
||||
return size_t(address & 0xfff);
|
||||
};
|
||||
|
||||
std::vector<uint8_t> final_4k(segment.data.end() - 4096, segment.data.end());
|
||||
const std::vector<uint8_t> final_4k(segment.data.end() - 4096, segment.data.end());
|
||||
Analyser::Static::MOS6502::Disassembly disassembly = Analyser::Static::MOS6502::Disassemble(final_4k, address_mapper, {entry_address, break_address});
|
||||
|
||||
switch(segment.data.size()) {
|
||||
@ -159,7 +155,7 @@ static void DeterminePagingForCartridge(Target &target, const Storage::Cartridge
|
||||
break;
|
||||
}
|
||||
|
||||
// check for a Super Chip. Atari ROM images [almost] always have the same value stored over RAM
|
||||
// Check for a Super Chip. Atari ROM images [almost] always have the same value stored over RAM
|
||||
// regions; when they don't they at least seem to have the first 128 bytes be the same as the
|
||||
// next 128 bytes. So check for that.
|
||||
if( target.paging_model != Target::PagingModel::CBSRamPlus &&
|
||||
@ -174,7 +170,7 @@ static void DeterminePagingForCartridge(Target &target, const Storage::Cartridge
|
||||
target.uses_superchip = has_superchip;
|
||||
}
|
||||
|
||||
// check for a Tigervision or Tigervision-esque scheme
|
||||
// Check for a Tigervision or Tigervision-esque scheme
|
||||
if(target.paging_model == Target::PagingModel::None && segment.data.size() > 4096) {
|
||||
bool looks_like_tigervision = disassembly.external_stores.find(0x3f) != disassembly.external_stores.end();
|
||||
if(looks_like_tigervision) target.paging_model = Target::PagingModel::Tigervision;
|
||||
|
@ -17,7 +17,7 @@ Analyser::Static::TargetList Analyser::Static::AtariST::GetTargets(const Media &
|
||||
Analyser::Static::TargetList targets;
|
||||
|
||||
using Target = Analyser::Static::AtariST::Target;
|
||||
auto *target = new Target();
|
||||
auto *const target = new Target();
|
||||
target->media = media;
|
||||
targets.push_back(std::unique_ptr<Analyser::Static::Target>(target));
|
||||
|
||||
|
@ -26,12 +26,12 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
|
||||
|
||||
Instruction instruction;
|
||||
instruction.address = address;
|
||||
address++;
|
||||
++address;
|
||||
|
||||
// get operation
|
||||
uint8_t operation = memory[local_address];
|
||||
// Get operation.
|
||||
const uint8_t operation = memory[local_address];
|
||||
|
||||
// decode addressing mode
|
||||
// Decode addressing mode.
|
||||
switch(operation&0x1f) {
|
||||
case 0x00:
|
||||
if(operation >= 0x80) instruction.addressing_mode = Instruction::Immediate;
|
||||
@ -74,7 +74,7 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
|
||||
break;
|
||||
}
|
||||
|
||||
// decode operation
|
||||
// Decode operation.
|
||||
#define RM_INSTRUCTION(base, op) \
|
||||
case base+0x09: case base+0x05: case base+0x15: case base+0x01: case base+0x11: case base+0x0d: case base+0x1d: case base+0x19: \
|
||||
instruction.operation = op; \
|
||||
@ -222,14 +222,14 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
|
||||
#undef M_INSTRUCTION
|
||||
#undef IM_INSTRUCTION
|
||||
|
||||
// get operand
|
||||
// Get operand.
|
||||
switch(instruction.addressing_mode) {
|
||||
// zero-byte operands
|
||||
// Zero-byte operands.
|
||||
case Instruction::Implied:
|
||||
instruction.operand = 0;
|
||||
break;
|
||||
|
||||
// one-byte operands
|
||||
// One-byte operands.
|
||||
case Instruction::Immediate:
|
||||
case Instruction::ZeroPage: case Instruction::ZeroPageX: case Instruction::ZeroPageY:
|
||||
case Instruction::IndexedIndirectX: case Instruction::IndirectIndexedY:
|
||||
@ -242,7 +242,7 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
|
||||
}
|
||||
break;
|
||||
|
||||
// two-byte operands
|
||||
// Two-byte operands.
|
||||
case Instruction::Absolute: case Instruction::AbsoluteX: case Instruction::AbsoluteY:
|
||||
case Instruction::Indirect: {
|
||||
std::size_t low_operand_address = address_mapper(address);
|
||||
@ -255,13 +255,13 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
|
||||
break;
|
||||
}
|
||||
|
||||
// store the instruction away
|
||||
// Store the instruction.
|
||||
disassembly.disassembly.instructions_by_address[instruction.address] = instruction;
|
||||
|
||||
// TODO: something wider-ranging than this
|
||||
if(instruction.addressing_mode == Instruction::Absolute || instruction.addressing_mode == Instruction::ZeroPage) {
|
||||
std::size_t mapped_address = address_mapper(instruction.operand);
|
||||
bool is_external = mapped_address >= memory.size();
|
||||
const size_t mapped_address = address_mapper(instruction.operand);
|
||||
const bool is_external = mapped_address >= memory.size();
|
||||
|
||||
switch(instruction.operation) {
|
||||
default: break;
|
||||
@ -290,7 +290,7 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
|
||||
}
|
||||
}
|
||||
|
||||
// decide on overall flow control
|
||||
// Decide on overall flow control.
|
||||
if(instruction.operation == Instruction::RTS || instruction.operation == Instruction::RTI) return;
|
||||
if(instruction.operation == Instruction::BRK) return; // TODO: check whether IRQ vector is within memory range
|
||||
if(instruction.operation == Instruction::JSR) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user