mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 16:31:31 +00:00
Implements STP and WAI.
Albeit still without fully-implemented reactions to exceptions in general.
This commit is contained in:
parent
8eaf1303a3
commit
a0885ab7d0
@ -170,6 +170,19 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
||||
|
||||
#undef stack_access
|
||||
|
||||
//
|
||||
// STP and WAI.
|
||||
//
|
||||
|
||||
case CycleRepeatingNone:
|
||||
if(pending_exceptions_ & required_exceptions_) {
|
||||
continue;
|
||||
} else {
|
||||
--next_op_;
|
||||
perform_bus(0xffffff, nullptr, MOS6502Esque::None);
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Data movement.
|
||||
//
|
||||
@ -822,11 +835,17 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
||||
LD(a_, result, m_masks_);
|
||||
} break;
|
||||
|
||||
// TODO:
|
||||
// STP, WAI,
|
||||
//
|
||||
// STP and WAI
|
||||
//
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
case STP:
|
||||
required_exceptions_ = Reset;
|
||||
break;
|
||||
|
||||
case WAI:
|
||||
required_exceptions_ = Reset | IRQ | NMI;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -539,18 +539,15 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
||||
target(OperationPerform);
|
||||
}
|
||||
|
||||
// 19c. Stop the Clock.
|
||||
static void stp(AccessType, bool, const std::function<void(MicroOp)> &target) {
|
||||
target(CycleFetchPCThrowaway); // IO
|
||||
target(CycleFetchPCThrowaway); // IO
|
||||
target(OperationPerform);
|
||||
}
|
||||
|
||||
// 19c. Stop the Clock; also
|
||||
// 19d. Wait for interrupt.
|
||||
static void wai(AccessType, bool, const std::function<void(MicroOp)> &target) {
|
||||
static void stp_wai(AccessType, bool, const std::function<void(MicroOp)> &target) {
|
||||
target(OperationPerform); // Establishes the termination condition.
|
||||
target(CycleFetchPCThrowaway); // IO
|
||||
target(CycleFetchPCThrowaway); // IO
|
||||
target(OperationPerform);
|
||||
target(CycleRepeatingNone); // This will first check whether the STP/WAI exit
|
||||
// condition has occurred; if not then it'll issue
|
||||
// a BusOperation::None and then reschedule itself.
|
||||
}
|
||||
|
||||
// 20. Relative; r.
|
||||
@ -955,7 +952,7 @@ ProcessorStorage::ProcessorStorage() {
|
||||
/* 0xc8 INY i */ op(implied, INY);
|
||||
/* 0xc9 CMP # */ op(immediate, CMP);
|
||||
/* 0xca DEX i */ op(implied, DEX);
|
||||
/* 0xcb WAI i */ op(wai, WAI);
|
||||
/* 0xcb WAI i */ op(stp_wai, WAI);
|
||||
/* 0xcc CPY a */ op(absolute, CPY);
|
||||
/* 0xcd CMP a */ op(absolute, CMP);
|
||||
/* 0xce DEC a */ op(absolute_rmw, DEC);
|
||||
@ -972,7 +969,7 @@ ProcessorStorage::ProcessorStorage() {
|
||||
/* 0xd8 CLD i */ op(implied, CLD);
|
||||
/* 0xd9 CMP a, y */ op(absolute_y, CMP);
|
||||
/* 0xda PHX s */ op(stack_push, STX);
|
||||
/* 0xdb STP i */ op(stp, STP);
|
||||
/* 0xdb STP i */ op(stp_wai, STP);
|
||||
/* 0xdc JML (a) */ op(absolute_indirect_jml, JML);
|
||||
/* 0xdd CMP a, x */ op(absolute_x, CMP);
|
||||
/* 0xde DEC a, x */ op(absolute_x_rmw, DEC);
|
||||
|
@ -47,6 +47,10 @@ enum MicroOp: uint8_t {
|
||||
/// Performs as CyclePull if the 65816 is not in emulation mode; otherwise skips itself.
|
||||
CyclePullIfNotEmulation,
|
||||
|
||||
/// Issues a BusOperation::None and regresses the micro-op counter until an established
|
||||
/// STP or WAI condition is satisfied.
|
||||
CycleRepeatingNone,
|
||||
|
||||
/// Sets the data address by copying the final two bytes of the instruction buffer and
|
||||
/// using the data register as a high byte.
|
||||
OperationConstructAbsolute,
|
||||
@ -261,6 +265,9 @@ struct ProcessorStorage {
|
||||
static constexpr int NMI = 1 << 3;
|
||||
int pending_exceptions_ = PowerOn; // By default.
|
||||
|
||||
/// Sets the required exception flags necessary to exit a STP or WAI.
|
||||
int required_exceptions_ = 0;
|
||||
|
||||
/// Defines a four-byte buffer which can be cleared or filled in single-byte increments from least significant byte
|
||||
/// to most significant.
|
||||
struct Buffer {
|
||||
|
Loading…
Reference in New Issue
Block a user