1
0
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:
Thomas Harte 2024-07-26 22:07:40 -04:00 committed by GitHub
commit 6c33177548
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 29 additions and 11 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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[] = {

View File

@ -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];