1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Took some provision steps towards paging type autodetection and communication. But I think this is a distraction.

This commit is contained in:
Thomas Harte 2017-02-20 17:44:36 -05:00
parent d19f26887d
commit 87afa9140e
4 changed files with 59 additions and 17 deletions

View File

@ -8,6 +8,8 @@
#include "StaticAnalyser.hpp" #include "StaticAnalyser.hpp"
#include "../Disassembler/Disassembler6502.hpp"
using namespace StaticAnalyser::Atari; using namespace StaticAnalyser::Atari;
void StaticAnalyser::Atari::AddTargets( void StaticAnalyser::Atari::AddTargets(
@ -24,5 +26,31 @@ void StaticAnalyser::Atari::AddTargets(
target.disks = disks; target.disks = disks;
target.tapes = tapes; target.tapes = tapes;
target.cartridges = cartridges; target.cartridges = cartridges;
target.atari.paging_model = Atari2600PagingModel::None;
// try to figure out the paging scheme
/* if(!cartridges.empty())
{
const std::list<Storage::Cartridge::Cartridge::Segment> &segments = cartridges.front()->get_segments();
if(segments.size() == 1)
{
uint16_t entry_address, break_address;
const Storage::Cartridge::Cartridge::Segment &segment = segments.front();
if(segment.data.size() < 4096)
{
entry_address = (uint16_t)(segment.data[0x7fc] | (segment.data[0x7fd] << 8));
break_address = (uint16_t)(segment.data[0x7fe] | (segment.data[0x7ff] << 8));
}
else
{
entry_address = (uint16_t)(segment.data[0xffc] | (segment.data[0xffd] << 8));
break_address = (uint16_t)(segment.data[0xffe] | (segment.data[0xfff] << 8));
}
StaticAnalyser::MOS6502::Disassembly disassembly =
StaticAnalyser::MOS6502::Disassemble(segment.data, 0x1000, {entry_address, break_address}, 0x1fff);
printf("%p", &disassembly);
}
}*/
destination.push_back(target); destination.push_back(target);
} }

View File

@ -16,9 +16,9 @@ struct PartialDisassembly {
std::vector<uint16_t> remaining_entry_points; std::vector<uint16_t> remaining_entry_points;
}; };
static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<uint8_t> &memory, uint16_t start_address, uint16_t entry_point) static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<uint8_t> &memory, uint16_t start_address, uint16_t entry_point, uint16_t address_mask)
{ {
uint16_t address = entry_point; uint16_t address = entry_point & address_mask;
while(1) while(1)
{ {
uint16_t local_address = address - start_address; uint16_t local_address = address - start_address;
@ -26,7 +26,7 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
struct Instruction instruction; struct Instruction instruction;
instruction.address = address; instruction.address = address;
address++; address = (address + 1) & address_mask;
// get operation // get operation
uint8_t operation = memory[local_address]; uint8_t operation = memory[local_address];
@ -250,7 +250,7 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
if(operand_address >= memory.size()-1) return; if(operand_address >= memory.size()-1) return;
address += 2; address += 2;
instruction.operand = memory[operand_address] | (uint16_t)(memory[operand_address+1] << 8); instruction.operand = memory[operand_address] | (uint16_t)(memory[operand_address + 1] << 8);
} }
break; break;
} }
@ -259,7 +259,7 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
disassembly.disassembly.instructions_by_address[instruction.address] = instruction; disassembly.disassembly.instructions_by_address[instruction.address] = instruction;
// TODO: something wider-ranging than this // TODO: something wider-ranging than this
if(instruction.addressing_mode == Instruction::Absolute && (instruction.operand < start_address || instruction.operand >= start_address + memory.size())) if((instruction.addressing_mode == Instruction::Absolute || instruction.addressing_mode == Instruction::ZeroPage) && (instruction.operand < start_address || instruction.operand >= start_address + memory.size()))
{ {
if( instruction.operation == Instruction::STY || if( instruction.operation == Instruction::STY ||
instruction.operation == Instruction::STX || instruction.operation == Instruction::STX ||
@ -276,23 +276,23 @@ static void AddToDisassembly(PartialDisassembly &disassembly, const std::vector<
if(instruction.operation == Instruction::BRK) return; // TODO: check whether IRQ vector is within memory range if(instruction.operation == Instruction::BRK) return; // TODO: check whether IRQ vector is within memory range
if(instruction.operation == Instruction::JSR) if(instruction.operation == Instruction::JSR)
{ {
disassembly.remaining_entry_points.push_back(instruction.operand); disassembly.remaining_entry_points.push_back(instruction.operand & address_mask);
} }
if(instruction.operation == Instruction::JMP) if(instruction.operation == Instruction::JMP)
{ {
if(instruction.addressing_mode == Instruction::Absolute) if(instruction.addressing_mode == Instruction::Absolute)
disassembly.remaining_entry_points.push_back(instruction.operand); disassembly.remaining_entry_points.push_back(instruction.operand & address_mask);
return; return;
} }
if(instruction.addressing_mode == Instruction::Relative) if(instruction.addressing_mode == Instruction::Relative)
{ {
uint16_t destination = (uint16_t)(address + (int8_t)instruction.operand); uint16_t destination = (uint16_t)(address + (int8_t)instruction.operand);
disassembly.remaining_entry_points.push_back(destination); disassembly.remaining_entry_points.push_back(destination & address_mask);
} }
} }
} }
Disassembly StaticAnalyser::MOS6502::Disassemble(const std::vector<uint8_t> &memory, uint16_t start_address, std::vector<uint16_t> entry_points) Disassembly StaticAnalyser::MOS6502::Disassemble(const std::vector<uint8_t> &memory, uint16_t start_address, std::vector<uint16_t> entry_points, uint16_t address_mask)
{ {
PartialDisassembly partialDisassembly; PartialDisassembly partialDisassembly;
partialDisassembly.remaining_entry_points = entry_points; partialDisassembly.remaining_entry_points = entry_points;
@ -300,7 +300,7 @@ Disassembly StaticAnalyser::MOS6502::Disassemble(const std::vector<uint8_t> &mem
while(!partialDisassembly.remaining_entry_points.empty()) while(!partialDisassembly.remaining_entry_points.empty())
{ {
// pull the next entry point from the back of the vector // pull the next entry point from the back of the vector
uint16_t next_entry_point = partialDisassembly.remaining_entry_points.back(); uint16_t next_entry_point = partialDisassembly.remaining_entry_points.back() & address_mask;
partialDisassembly.remaining_entry_points.pop_back(); partialDisassembly.remaining_entry_points.pop_back();
// if that address has already bene visited, forget about it // if that address has already bene visited, forget about it
@ -310,7 +310,7 @@ Disassembly StaticAnalyser::MOS6502::Disassemble(const std::vector<uint8_t> &mem
if(next_entry_point < start_address || next_entry_point >= start_address + memory.size()) if(next_entry_point < start_address || next_entry_point >= start_address + memory.size())
partialDisassembly.disassembly.outward_calls.insert(next_entry_point); partialDisassembly.disassembly.outward_calls.insert(next_entry_point);
else else
AddToDisassembly(partialDisassembly, memory, start_address, next_entry_point); AddToDisassembly(partialDisassembly, memory, start_address, next_entry_point, address_mask);
} }
return std::move(partialDisassembly.disassembly); return std::move(partialDisassembly.disassembly);

View File

@ -67,7 +67,7 @@ struct Disassembly {
std::set<uint16_t> external_stores, external_loads, external_modifies; std::set<uint16_t> external_stores, external_loads, external_modifies;
}; };
Disassembly Disassemble(const std::vector<uint8_t> &memory, uint16_t start_address, std::vector<uint16_t> entry_points); Disassembly Disassemble(const std::vector<uint8_t> &memory, uint16_t start_address, std::vector<uint16_t> entry_points, uint16_t address_mask = 0xffff);
} }
} }

View File

@ -25,6 +25,16 @@ enum class Vic20MemoryModel {
ThirtyTwoKB ThirtyTwoKB
}; };
enum class Atari2600PagingModel {
None,
Atari8k,
Atari16k,
Atari32k,
ActivisionStack,
ParkerBros,
Tigervision
};
/*! /*!
A list of disks, tapes and cartridges plus information about the machine to which to attach them and its configuration, A list of disks, tapes and cartridges plus information about the machine to which to attach them and its configuration,
and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness. and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness.
@ -39,21 +49,25 @@ struct Target {
float probability; float probability;
union { union {
struct {
Vic20MemoryModel memory_model;
bool has_c1540;
} vic20;
struct { struct {
bool has_adfs; bool has_adfs;
bool has_dfs; bool has_dfs;
bool should_shift_restart; bool should_shift_restart;
} acorn; } acorn;
struct {
Atari2600PagingModel paging_model;
} atari;
struct { struct {
bool use_atmos_rom; bool use_atmos_rom;
bool has_microdisc; bool has_microdisc;
} oric; } oric;
struct {
Vic20MemoryModel memory_model;
bool has_c1540;
} vic20;
}; };
std::string loadingCommand; std::string loadingCommand;