mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-05 10:28:58 +00:00
Ensures that reset doesn't push to the stack.
This commit is contained in:
parent
1e4679ae14
commit
1df2ce513a
@ -410,6 +410,13 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
pending_exceptions_ &= ~(Reset | PowerOn);
|
pending_exceptions_ &= ~(Reset | PowerOn);
|
||||||
data_address_ = 0xfffc;
|
data_address_ = 0xfffc;
|
||||||
set_reset_state();
|
set_reset_state();
|
||||||
|
|
||||||
|
// Also switch tracks to the reset program, and don't load up the
|
||||||
|
// data buffer. set_reset_state() will already have fixed the
|
||||||
|
// interrupt and decimal flags.
|
||||||
|
active_instruction_ = &instructions[size_t(OperationSlot::ResetTail)];
|
||||||
|
next_op_ = µ_ops_[active_instruction_->program_offsets[0]];
|
||||||
|
continue;
|
||||||
} else if(pending_exceptions_ & NMI) {
|
} else if(pending_exceptions_ & NMI) {
|
||||||
pending_exceptions_ &= ~NMI;
|
pending_exceptions_ &= ~NMI;
|
||||||
data_address_ = registers_.emulation_flag ? 0xfffa : 0xffea;
|
data_address_ = registers_.emulation_flag ? 0xfffa : 0xffea;
|
||||||
|
@ -70,11 +70,16 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
|||||||
++opcode;
|
++opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_exception_generator(Generator generator) {
|
void set_exception_generator(Generator generator, Generator reset_tail_generator) {
|
||||||
const auto map_entry = install(generator);
|
const auto map_entry = install(generator);
|
||||||
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].program_offsets[0] =
|
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].program_offsets[0] =
|
||||||
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].program_offsets[1] = uint16_t(map_entry->second.first);
|
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].program_offsets[1] = uint16_t(map_entry->second.first);
|
||||||
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].operation = JMPind;
|
storage_.instructions[size_t(ProcessorStorage::OperationSlot::Exception)].operation = JMPind;
|
||||||
|
|
||||||
|
const auto reset_tail_entry = install(reset_tail_generator);
|
||||||
|
storage_.instructions[size_t(ProcessorStorage::OperationSlot::ResetTail)].program_offsets[0] =
|
||||||
|
storage_.instructions[size_t(ProcessorStorage::OperationSlot::ResetTail)].program_offsets[1] = uint16_t(reset_tail_entry->second.first);
|
||||||
|
storage_.instructions[size_t(ProcessorStorage::OperationSlot::ResetTail)].operation = JMPind;
|
||||||
}
|
}
|
||||||
|
|
||||||
void install_fetch_decode_execute() {
|
void install_fetch_decode_execute() {
|
||||||
@ -597,8 +602,9 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
|||||||
target(CycleFetchPCThrowaway); // IO.
|
target(CycleFetchPCThrowaway); // IO.
|
||||||
target(CycleFetchPCThrowaway); // IO.
|
target(CycleFetchPCThrowaway); // IO.
|
||||||
|
|
||||||
target(OperationPrepareException); // Populates the data buffer; this skips a micro-op if
|
target(OperationPrepareException); // Populates the data buffer; if the exception is a
|
||||||
// in emulation mode.
|
// reset then switches to the reset tail program.
|
||||||
|
// Otherwise skips a micro-op if in emulation mode.
|
||||||
|
|
||||||
target(CyclePush); // PBR [skipped in emulation mode].
|
target(CyclePush); // PBR [skipped in emulation mode].
|
||||||
target(CyclePush); // PCH.
|
target(CyclePush); // PCH.
|
||||||
@ -611,6 +617,20 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
|||||||
target(OperationPerform); // Jumps to the vector address.
|
target(OperationPerform); // Jumps to the vector address.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reset_tail(AccessType, bool, const std::function<void(MicroOp)> &target) {
|
||||||
|
// The reset program still walks through three stack accesses as if it were doing
|
||||||
|
// the usual exception stack activity, but forces them to reads that don't modify
|
||||||
|
// the stack pointer. Here they are:
|
||||||
|
target(CycleAccessStack); // PCH.
|
||||||
|
target(CycleAccessStack); // PCL.
|
||||||
|
target(CycleAccessStack); // P.
|
||||||
|
|
||||||
|
target(CycleFetchIncrementVector); // AAVL.
|
||||||
|
target(CycleFetchVector); // AAVH.
|
||||||
|
|
||||||
|
target(OperationPerform); // Jumps to the vector address.
|
||||||
|
}
|
||||||
|
|
||||||
// 22b. Stack; s, PLx.
|
// 22b. Stack; s, PLx.
|
||||||
static void stack_pull(AccessType, bool is8bit, const std::function<void(MicroOp)> &target) {
|
static void stack_pull(AccessType, bool is8bit, const std::function<void(MicroOp)> &target) {
|
||||||
target(CycleFetchPCThrowaway); // IO.
|
target(CycleFetchPCThrowaway); // IO.
|
||||||
@ -1027,7 +1047,7 @@ ProcessorStorage::ProcessorStorage() {
|
|||||||
/* 0xff SBC al, x */ op(absolute_long_x, SBC);
|
/* 0xff SBC al, x */ op(absolute_long_x, SBC);
|
||||||
#undef op
|
#undef op
|
||||||
|
|
||||||
constructor.set_exception_generator(&ProcessorStorageConstructor::stack_exception);
|
constructor.set_exception_generator(&ProcessorStorageConstructor::stack_exception, &ProcessorStorageConstructor::reset_tail);
|
||||||
constructor.install_fetch_decode_execute();
|
constructor.install_fetch_decode_execute();
|
||||||
|
|
||||||
// Find any OperationMoveToNextProgram.
|
// Find any OperationMoveToNextProgram.
|
||||||
|
@ -241,14 +241,16 @@ struct ProcessorStorage {
|
|||||||
/// So the program to perform is that at @c program_offsets[mx_flags[size_field]]
|
/// So the program to perform is that at @c program_offsets[mx_flags[size_field]]
|
||||||
uint8_t size_field = 0;
|
uint8_t size_field = 0;
|
||||||
};
|
};
|
||||||
Instruction instructions[256 + 2]; // Arranged as:
|
Instruction instructions[256 + 3]; // Arranged as:
|
||||||
// 256 entries: instructions;
|
// 256 entries: instructions;
|
||||||
// the entry for 'exceptions' (i.e. reset, irq, nmi); and
|
// the entry for 'exceptions' (i.e. reset, irq, nmi);
|
||||||
|
// a duplicate entry for the final part of exceptions if the selected exception is a reset; and
|
||||||
// the entry for fetch-decode-execute.
|
// the entry for fetch-decode-execute.
|
||||||
|
|
||||||
enum class OperationSlot {
|
enum class OperationSlot {
|
||||||
Exception = 256,
|
Exception = 256,
|
||||||
FetchDecodeExecute
|
ResetTail,
|
||||||
|
FetchDecodeExecute,
|
||||||
};
|
};
|
||||||
|
|
||||||
// A helper for testing.
|
// A helper for testing.
|
||||||
|
Loading…
Reference in New Issue
Block a user