1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Attempts implementations of both ready and abort.

Which I think concludes the inputs?
This commit is contained in:
Thomas Harte 2020-10-15 20:46:18 -04:00
parent c0a1c34012
commit dfda2adf0d
2 changed files with 789 additions and 753 deletions

View File

@ -35,6 +35,7 @@ class ProcessorBase: protected ProcessorStorage {
inline void set_nmi_line(bool);
inline void set_reset_line(bool);
inline void set_abort_line(bool);
inline bool get_is_resetting() const;
void set_value_of_register(Register r, uint16_t value);
inline bool is_jammed() const;

View File

@ -25,6 +25,13 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
Cycles number_of_cycles = cycles + cycles_left_to_run_;
while(number_of_cycles > Cycles(0)) {
// Wait for ready to be inactive before proceeding.
while(uses_ready_line && ready_line_ && number_of_cycles > Cycles(0)) {
number_of_cycles -= bus_handler_.perform_bus_operation(BusOperation::Ready, bus_address_, &bus_throwaway_);
}
// Process for as much time is left and/or until ready is signalled.
while((!uses_ready_line || !ready_line_) && number_of_cycles > Cycles(0)) {
const MicroOp operation = *next_op_;
++next_op_;
@ -374,6 +381,8 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
// to a 6502 but may not have the exact details correct. E.g. if IRQ has
// become inactive since the decision was made to start an interrupt, should
// that turn into a BRK?
//
// Also: priority here is a guess.
bool is_brk = false;
@ -383,17 +392,23 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
set_reset_state();
} else if(pending_exceptions_ & NMI) {
pending_exceptions_ &= ~NMI;
data_address_ = 0xfffa;
data_address_ = registers_.emulation_flag ? 0xfffa : 0xffea;
} else if(pending_exceptions_ & IRQ & registers_.flags.inverse_interrupt) {
pending_exceptions_ &= ~IRQ;
data_address_ = 0xfffe;
data_address_ = registers_.emulation_flag ? 0xfffe : 0xffee;
} else if(pending_exceptions_ & Abort) {
// Special case: restore registers from start of instruction.
registers_ = abort_registers_copy_;
pending_exceptions_ &= ~Abort;
data_address_ = registers_.emulation_flag ? 0xfff8 : 0xffe8;;
} else {
is_brk = active_instruction_ == instructions; // Given that BRK has opcode 00.
if(is_brk) {
data_address_ = registers_.emulation_flag ? 0xfffe : 0xfff6;
data_address_ = registers_.emulation_flag ? 0xfffe : 0xffe6;
} else {
// Implicitly: COP.
data_address_ = 0xfff4;
data_address_ = registers_.emulation_flag ? 0xfff4 : 0xffe8;
}
}
@ -900,8 +915,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
// next thing is a MoveToNextProgram.
selected_exceptions_ = pending_exceptions_ & (registers_.flags.inverse_interrupt | PowerOn | Reset | NMI);
number_of_cycles -= bus_handler_.perform_bus_operation(bus_operation_, bus_address_, bus_value_);
// TODO: RDY line.
}
}
#undef read
@ -947,5 +961,26 @@ void ProcessorBase::set_nmi_line(bool active) {
}
}
void ProcessorBase::set_abort_line(bool active) {
// Take a copy of register state now to restore at the beginning of the exception
// if abort has gone active, preparing to regress the program counter.
if(active) {
pending_exceptions_ |= Abort;
abort_registers_copy_ = registers_;
abort_registers_copy_.pc = last_operation_pc_;
} else {
pending_exceptions_ &= ~Abort;
}
}
template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler, uses_ready_line>::set_ready_line(bool active) {
assert(uses_ready_line);
ready_line_ = active;
}
// The 65816 can't jam.
bool ProcessorBase::is_jammed() const { return false; }
bool ProcessorBase::get_is_resetting() const {
return pending_exceptions_ & (Reset | PowerOn);
}