1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-29 00:29:34 +00:00

Support interrupts; documentation to come.

This commit is contained in:
Thomas Harte 2022-05-12 20:52:24 -04:00
parent 3d8f5d4302
commit 2e796f31d4
3 changed files with 25 additions and 1 deletions

View File

@ -32,6 +32,7 @@ struct BusHandler {
template <typename IntT> void write(uint32_t address, IntT value, FunctionCode function);
template <typename IntT> IntT read(uint32_t address, FunctionCode function);
void reset();
int acknowlege_interrupt(int);
};
/// Ties together the decoder, sequencer and performer to provide an executor for 680x0 instruction streams.
@ -52,6 +53,9 @@ template <Model model, typename BusHandler> class Executor: public NullFlowContr
/// this will raise a C++ exception, and therefore doesn't return.
[[noreturn]] void signal_bus_error(FunctionCode, uint32_t address);
/// Sets the current input interrupt level.
void set_interrupt_level(int);
// Flow control; Cf. Perform.hpp.
template <bool use_current_instruction_pc = true> void raise_exception(int);
@ -123,6 +127,9 @@ template <Model model, typename BusHandler> class Executor: public NullFlowContr
uint16_t instruction_opcode_;
int active_stack_pointer_ = 0;
// Bus state.
int interrupt_input_ = 0;
// A lookup table to ensure that A7 is adjusted by 2 rather than 1 in
// postincrement and predecrement mode.
static constexpr uint32_t byte_increments[] = {

View File

@ -227,6 +227,11 @@ void Executor<model, BusHandler>::signal_bus_error(FunctionCode code, uint32_t a
throw AccessException(code, address, Exception::AccessFault);
}
template <Model model, typename BusHandler>
void Executor<model, BusHandler>::set_interrupt_level(int level) {
interrupt_input_ = level;
}
template <Model model, typename BusHandler>
void Executor<model, BusHandler>::run_for_instructions(int count) {
while(count > 0) {
@ -267,7 +272,16 @@ void Executor<model, BusHandler>::run_for_instructions(int count) {
template <Model model, typename BusHandler>
void Executor<model, BusHandler>::run(int &count) {
while(count--) {
// TODO: interrupts.
// Check for a new interrupt.
if(interrupt_input_ > status_.interrupt_level) {
const int vector = bus_handler_.acknowlege_interrupt(interrupt_input_);
if(vector >= 0) {
raise_exception<false>(vector);
} else {
raise_exception<false>(Exception::InterruptAutovectorBase - 1 + interrupt_input_);
}
status_.interrupt_level = interrupt_input_;
}
// Capture the trace bit, indicating whether to trace
// after this instruction.

View File

@ -77,6 +77,9 @@ struct Test68000 {
}
void reset() {}
int acknowlege_interrupt(int) {
return -1;
}
};
}