mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +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);
|
||||
data_address_ = 0xfffc;
|
||||
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) {
|
||||
pending_exceptions_ &= ~NMI;
|
||||
data_address_ = registers_.emulation_flag ? 0xfffa : 0xffea;
|
||||
|
@ -70,11 +70,16 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
||||
++opcode;
|
||||
}
|
||||
|
||||
void set_exception_generator(Generator generator) {
|
||||
void set_exception_generator(Generator generator, Generator reset_tail_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[1] = uint16_t(map_entry->second.first);
|
||||
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() {
|
||||
@ -597,8 +602,9 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
||||
target(CycleFetchPCThrowaway); // IO.
|
||||
target(CycleFetchPCThrowaway); // IO.
|
||||
|
||||
target(OperationPrepareException); // Populates the data buffer; this skips a micro-op if
|
||||
// in emulation mode.
|
||||
target(OperationPrepareException); // Populates the data buffer; if the exception is a
|
||||
// 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); // PCH.
|
||||
@ -611,6 +617,20 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
||||
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.
|
||||
static void stack_pull(AccessType, bool is8bit, const std::function<void(MicroOp)> &target) {
|
||||
target(CycleFetchPCThrowaway); // IO.
|
||||
@ -1027,7 +1047,7 @@ ProcessorStorage::ProcessorStorage() {
|
||||
/* 0xff SBC al, x */ op(absolute_long_x, SBC);
|
||||
#undef op
|
||||
|
||||
constructor.set_exception_generator(&ProcessorStorageConstructor::stack_exception);
|
||||
constructor.set_exception_generator(&ProcessorStorageConstructor::stack_exception, &ProcessorStorageConstructor::reset_tail);
|
||||
constructor.install_fetch_decode_execute();
|
||||
|
||||
// Find any OperationMoveToNextProgram.
|
||||
|
@ -241,14 +241,16 @@ struct ProcessorStorage {
|
||||
/// So the program to perform is that at @c program_offsets[mx_flags[size_field]]
|
||||
uint8_t size_field = 0;
|
||||
};
|
||||
Instruction instructions[256 + 2]; // Arranged as:
|
||||
Instruction instructions[256 + 3]; // Arranged as:
|
||||
// 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.
|
||||
|
||||
enum class OperationSlot {
|
||||
Exception = 256,
|
||||
FetchDecodeExecute
|
||||
ResetTail,
|
||||
FetchDecodeExecute,
|
||||
};
|
||||
|
||||
// A helper for testing.
|
||||
|
Loading…
Reference in New Issue
Block a user