mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-06 15:00:05 +00:00
Ensure complete runs of each tested opcode.
This commit is contained in:
parent
586ef4810b
commit
f8e6954739
@ -15,9 +15,12 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
struct StopException {};
|
||||||
|
|
||||||
struct BusHandler: public CPU::MOS6502Esque::BusHandler<uint32_t> {
|
struct BusHandler: public CPU::MOS6502Esque::BusHandler<uint32_t> {
|
||||||
// Use a map to store RAM contents, in order to preserve initialised state.
|
// Use a map to store RAM contents, in order to preserve initialised state.
|
||||||
std::unordered_map<uint32_t, uint8_t> ram;
|
std::unordered_map<uint32_t, uint8_t> ram;
|
||||||
|
std::unordered_map<uint32_t, uint8_t> inventions;
|
||||||
|
|
||||||
Cycles perform_bus_operation(CPU::MOS6502Esque::BusOperation operation, uint32_t address, uint8_t *value) {
|
Cycles perform_bus_operation(CPU::MOS6502Esque::BusOperation operation, uint32_t address, uint8_t *value) {
|
||||||
// Record the basics of the operation.
|
// Record the basics of the operation.
|
||||||
@ -31,7 +34,11 @@ struct BusHandler: public CPU::MOS6502Esque::BusHandler<uint32_t> {
|
|||||||
auto ram_value = ram.find(address);
|
auto ram_value = ram.find(address);
|
||||||
switch(operation) {
|
switch(operation) {
|
||||||
case BusOperation::ReadOpcode:
|
case BusOperation::ReadOpcode:
|
||||||
++opcodes_fetched_;
|
--opcodes_remaining;
|
||||||
|
if(!opcodes_remaining) {
|
||||||
|
cycles.pop_back();
|
||||||
|
throw StopException();
|
||||||
|
}
|
||||||
case BusOperation::Read:
|
case BusOperation::Read:
|
||||||
case BusOperation::ReadProgram:
|
case BusOperation::ReadProgram:
|
||||||
case BusOperation::ReadVector:
|
case BusOperation::ReadVector:
|
||||||
@ -39,7 +46,7 @@ struct BusHandler: public CPU::MOS6502Esque::BusHandler<uint32_t> {
|
|||||||
cycle.value = *value = ram_value->second;
|
cycle.value = *value = ram_value->second;
|
||||||
} else {
|
} else {
|
||||||
cycle.value = *value = uint8_t(rand() >> 8);
|
cycle.value = *value = uint8_t(rand() >> 8);
|
||||||
ram[address] = cycle.value;
|
inventions[address] = ram[address] = cycle.value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -54,7 +61,19 @@ struct BusHandler: public CPU::MOS6502Esque::BusHandler<uint32_t> {
|
|||||||
return Cycles(1);
|
return Cycles(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int opcodes_fetched_ = 0;
|
template <typename Processor> void setup(Processor &processor, uint8_t opcode) {
|
||||||
|
ram.clear();
|
||||||
|
inventions.clear();
|
||||||
|
cycles.clear();
|
||||||
|
|
||||||
|
using Register = CPU::MOS6502Esque::Register;
|
||||||
|
const uint32_t pc =
|
||||||
|
processor.get_value_of_register(Register::ProgramCounter) |
|
||||||
|
(processor.get_value_of_register(Register::ProgramBank) << 8);
|
||||||
|
inventions[pc] = ram[pc] = opcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int opcodes_remaining = 0;
|
||||||
|
|
||||||
struct Cycle {
|
struct Cycle {
|
||||||
CPU::MOS6502Esque::BusOperation operation;
|
CPU::MOS6502Esque::BusOperation operation;
|
||||||
@ -77,17 +96,29 @@ struct BusHandler: public CPU::MOS6502Esque::BusHandler<uint32_t> {
|
|||||||
BusHandler handler;
|
BusHandler handler;
|
||||||
CPU::WDC65816::Processor<BusHandler, false> processor(handler);
|
CPU::WDC65816::Processor<BusHandler, false> processor(handler);
|
||||||
|
|
||||||
|
// Never run the official reset procedure.
|
||||||
|
processor.set_power_on(false);
|
||||||
|
|
||||||
for(int operation = 0; operation < 512; operation++) {
|
for(int operation = 0; operation < 512; operation++) {
|
||||||
const bool is_emulated = operation & 256;
|
const bool is_emulated = operation & 256;
|
||||||
const uint8_t opcode = operation & 255;
|
const uint8_t opcode = operation & 255;
|
||||||
|
|
||||||
// TODO: set up for opcode and emulation mode.
|
// Ensure processor's next action is an opcode fetch.
|
||||||
|
processor.restart_operation_fetch();
|
||||||
|
|
||||||
// TODO: run for a bit longer than this, of course.
|
// Randomise processor state.
|
||||||
processor.run_for(Cycles(1));
|
using Register = CPU::MOS6502Esque::Register;
|
||||||
|
processor.set_value_of_register(Register::EmulationFlag, is_emulated);
|
||||||
|
|
||||||
|
// Establish the opcode.
|
||||||
|
handler.setup(processor, opcode);
|
||||||
|
|
||||||
|
// Run to the second opcode fetch.
|
||||||
|
handler.opcodes_remaining = 2;
|
||||||
|
try {
|
||||||
|
processor.run_for(Cycles(100));
|
||||||
|
} catch (const StopException &) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
Loading…
Reference in New Issue
Block a user