1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-21 21:33:54 +00:00

Correct 6502 JAM behaviour.

This commit is contained in:
Thomas Harte 2024-07-26 21:43:54 -04:00
parent 94058d498c
commit 59e1a5e5f6
3 changed files with 18 additions and 11 deletions

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) { const auto throwaway_read = [&](uint16_t address) {
next_bus_operation_ = BusOperation::Read; read_mem(bus_throwaway_, address);
bus_address_ = address;
bus_value_ = &bus_throwaway_;
bus_throwaway_ = 0xff;
}; };
const auto write_mem = [&](uint8_t &val, uint16_t 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 // MARK: - JAM, WAI, STP
case OperationScheduleJam: { case OperationSetJAMmed:
is_jammed_ = true; is_jammed_ = true;
scheduled_program_counter_ = operations_[CPU::MOS6502::JamOpcode]; scheduled_program_counter_ -= 2;
} continue; continue;
case CycleFetchFFFE: read_mem(bus_throwaway_, 0xfffe); break;
case CycleFetchFFFF: read_mem(bus_throwaway_, 0xffff); break;
case OperationScheduleStop: case OperationScheduleStop:
stop_is_active_ = true; 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) { void ProcessorBase::set_reset_line(bool active) {
interrupt_requests_ = (interrupt_requests_ & ~InterruptRequestFlags::Reset) | (active ? InterruptRequestFlags::Reset : 0); interrupt_requests_ = (interrupt_requests_ & ~InterruptRequestFlags::Reset) | (active ? InterruptRequestFlags::Reset : 0);
if(is_jammed_) {
restart_operation_fetch();
}
} }
bool ProcessorBase::get_is_resetting() const { 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() { void ProcessorBase::restart_operation_fetch() {
is_jammed_ = false;
scheduled_program_counter_ = nullptr; scheduled_program_counter_ = nullptr;
next_bus_operation_ = BusOperation::None; next_bus_operation_ = BusOperation::None;
} }

View File

@ -73,7 +73,7 @@ using namespace CPU::MOS6502;
#define ImpliedNop() {OperationMoveToNextProgram} #define ImpliedNop() {OperationMoveToNextProgram}
#define ImmediateNop() Program(OperationIncrementPC) #define ImmediateNop() Program(OperationIncrementPC)
#define JAM {CycleFetchOperand, OperationScheduleJam} #define JAM {CycleFetchFFFF, CycleFetchFFFE, CycleFetchFFFE, CycleFetchFFFF, OperationSetJAMmed}
ProcessorStorage::ProcessorStorage(Personality personality) { ProcessorStorage::ProcessorStorage(Personality personality) {
const InstructionList operations_6502[] = { 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 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 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) 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) 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]; using InstructionList = MicroOp[12];