mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-21 20:29:06 +00:00
Merge pull request #1389 from TomHarte/6502JAM
Correct 6502 JAM bus activity.
This commit is contained in:
commit
6c33177548
@ -29,6 +29,16 @@ struct BusHandler: public CPU::MOS6502Esque::BusHandlerT<type> {
|
||||
std::unordered_map<AddressType, uint8_t> inventions;
|
||||
|
||||
Cycles perform_bus_operation(CPU::MOS6502Esque::BusOperation operation, AddressType address, uint8_t *value) {
|
||||
// Check for a JAM; if one is found then record just five more bus cycles, arbitrarily.
|
||||
if(jam_count) {
|
||||
--jam_count;
|
||||
if(!jam_count) {
|
||||
throw StopException();
|
||||
}
|
||||
} else if(processor.is_jammed()) {
|
||||
jam_count = 5;
|
||||
}
|
||||
|
||||
// Record the basics of the operation.
|
||||
auto &cycle = cycles.emplace_back();
|
||||
cycle.operation = operation;
|
||||
@ -110,6 +120,7 @@ struct BusHandler: public CPU::MOS6502Esque::BusHandlerT<type> {
|
||||
int pc_overshoot = 0;
|
||||
std::optional<AddressType> initial_pc;
|
||||
bool allow_pc_repetition = false;
|
||||
int jam_count = 0;
|
||||
|
||||
struct Cycle {
|
||||
CPU::MOS6502Esque::BusOperation operation;
|
||||
|
@ -59,10 +59,7 @@ void Processor<personality, T, uses_ready_line>::run_for(const Cycles cycles) {
|
||||
};
|
||||
|
||||
const auto throwaway_read = [&](uint16_t address) {
|
||||
next_bus_operation_ = BusOperation::Read;
|
||||
bus_address_ = address;
|
||||
bus_value_ = &bus_throwaway_;
|
||||
bus_throwaway_ = 0xff;
|
||||
read_mem(bus_throwaway_, address);
|
||||
};
|
||||
|
||||
const auto write_mem = [&](uint8_t &val, uint16_t address) {
|
||||
@ -232,10 +229,13 @@ void Processor<personality, T, uses_ready_line>::run_for(const Cycles cycles) {
|
||||
|
||||
// MARK: - JAM, WAI, STP
|
||||
|
||||
case OperationScheduleJam: {
|
||||
case OperationSetJAMmed:
|
||||
is_jammed_ = true;
|
||||
scheduled_program_counter_ = operations_[CPU::MOS6502::JamOpcode];
|
||||
} continue;
|
||||
scheduled_program_counter_ -= 2;
|
||||
continue;
|
||||
|
||||
case CycleFetchFFFE: read_mem(bus_throwaway_, 0xfffe); break;
|
||||
case CycleFetchFFFF: read_mem(bus_throwaway_, 0xffff); break;
|
||||
|
||||
case OperationScheduleStop:
|
||||
stop_is_active_ = true;
|
||||
@ -804,6 +804,9 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
|
||||
|
||||
void ProcessorBase::set_reset_line(bool active) {
|
||||
interrupt_requests_ = (interrupt_requests_ & ~InterruptRequestFlags::Reset) | (active ? InterruptRequestFlags::Reset : 0);
|
||||
if(is_jammed_) {
|
||||
restart_operation_fetch();
|
||||
}
|
||||
}
|
||||
|
||||
bool ProcessorBase::get_is_resetting() const {
|
||||
@ -870,6 +873,7 @@ void ProcessorBase::set_value_of(Register r, uint16_t value) {
|
||||
}
|
||||
|
||||
void ProcessorBase::restart_operation_fetch() {
|
||||
is_jammed_ = false;
|
||||
scheduled_program_counter_ = nullptr;
|
||||
next_bus_operation_ = BusOperation::None;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ using namespace CPU::MOS6502;
|
||||
#define ImpliedNop() {OperationMoveToNextProgram}
|
||||
#define ImmediateNop() Program(OperationIncrementPC)
|
||||
|
||||
#define JAM {CycleFetchOperand, OperationScheduleJam}
|
||||
#define JAM {CycleFetchFFFF, CycleFetchFFFE, CycleFetchFFFE, CycleFetchFFFF, OperationSetJAMmed}
|
||||
|
||||
ProcessorStorage::ProcessorStorage(Personality personality) {
|
||||
const InstructionList operations_6502[] = {
|
||||
|
@ -198,9 +198,12 @@ class ProcessorStorage {
|
||||
OperationSetFlagsFromX, // sets the zero and negative flags based on the value of x
|
||||
OperationSetFlagsFromY, // sets the zero and negative flags based on the value of y
|
||||
|
||||
OperationScheduleJam, // schedules the program for operation F2
|
||||
OperationScheduleWait, // puts the processor into WAI mode (i.e. it'll do nothing until an interrupt is received)
|
||||
OperationScheduleStop, // puts the processor into STP mode (i.e. it'll do nothing until a reset is received)
|
||||
OperationScheduleWait, // puts the processor into WAI mode (i.e. it'll do nothing until an interrupt is received)
|
||||
OperationScheduleStop, // puts the processor into STP mode (i.e. it'll do nothing until a reset is received)
|
||||
|
||||
CycleFetchFFFE, // perform a throwaway read from $FFFE
|
||||
CycleFetchFFFF, // perform a throwaway read from $FFFF
|
||||
OperationSetJAMmed, // decrements the micro-operation program counter back to the operation before this one, marking the CPU as jammed
|
||||
};
|
||||
|
||||
using InstructionList = MicroOp[12];
|
||||
|
Loading…
x
Reference in New Issue
Block a user