From f0d807a0fe5c849bbafd6ccb5909cd34d1484fac Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Sat, 21 Sep 2024 20:49:59 -0400
Subject: [PATCH 1/5] Fix `[d], y` page-wrapping behaviour.

---
 Processors/65816/Implementation/65816Storage.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Processors/65816/Implementation/65816Storage.cpp b/Processors/65816/Implementation/65816Storage.cpp
index fd89b8551..d539fe0b4 100644
--- a/Processors/65816/Implementation/65816Storage.cpp
+++ b/Processors/65816/Implementation/65816Storage.cpp
@@ -493,7 +493,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
 	static void direct_indirect_indexed_long(AccessType type, bool is8bit, const std::function<void(MicroOp)> &target) {
 		target(CycleFetchIncrementPC);					// DO.
 
-		target(OperationConstructDirect);
+		target(OperationConstructDirectLong);
 		target(CycleFetchPreviousPCThrowaway);			// IO.
 
 		target(CycleFetchIncrementData);				// AAL.

From a65551f652164a074ccb6980c278f93f09958cf0 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Sat, 21 Sep 2024 21:08:02 -0400
Subject: [PATCH 2/5] Give PLB the same stack behaviour as PLD.

---
 Processors/65816/Implementation/65816Storage.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Processors/65816/Implementation/65816Storage.cpp b/Processors/65816/Implementation/65816Storage.cpp
index d539fe0b4..c46effd21 100644
--- a/Processors/65816/Implementation/65816Storage.cpp
+++ b/Processors/65816/Implementation/65816Storage.cpp
@@ -667,8 +667,8 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
 		target(OperationPerform);
 	}
 
-	// 22b(ii). Stack; s, PLx, ignoring emulation mode. I.e. PLD.
-	static void stack_pld(AccessType, bool, const std::function<void(MicroOp)> &target) {
+	// 22b(ii). Stack; s, PLx, ignoring emulation mode. I.e. PLD and PLB.
+	static void stack_pld_plb(AccessType, bool, const std::function<void(MicroOp)> &target) {
 		target(CycleFetchPCThrowaway);	// IO.
 		target(CycleFetchPCThrowaway);	// IO.
 
@@ -873,7 +873,7 @@ ProcessorStorage::ProcessorStorage() {
 	/* 0x28 PLP s */			op(stack_pull, PLP, AccessMode::Always8Bit);
 	/* 0x29 AND # */			op(immediate, AND);
 	/* 0x2a ROL A */			op(accumulator, ROL);
-	/* 0x2b PLD s */			op(stack_pld, PLD);
+	/* 0x2b PLD s */			op(stack_pld_plb, PLD);
 	/* 0x2c BIT a */			op(absolute, BIT);
 	/* 0x2d AND a */			op(absolute, AND);
 	/* 0x2e ROL a */			op(absolute_rmw, ROL);
@@ -1009,7 +1009,7 @@ ProcessorStorage::ProcessorStorage() {
 	/* 0xa8 TAY i */			op(implied, TAY);
 	/* 0xa9 LDA # */			op(immediate, LDA);
 	/* 0xaa TAX i */			op(implied, TAX);
-	/* 0xab PLB s */			op(stack_pull, PLB, AccessMode::Always8Bit);
+	/* 0xab PLB s */			op(stack_pld_plb, PLB, AccessMode::Always8Bit);
 	/* 0xac LDY a */			op(absolute, LDY);
 	/* 0xad LDA a */			op(absolute, LDA);
 	/* 0xae LDX a */			op(absolute, LDX);

From ff6753fcdff03bdee9f103305a732d8cd52c1c1d Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Sat, 21 Sep 2024 21:12:04 -0400
Subject: [PATCH 3/5] PEI: don't page wrap.

---
 Processors/65816/Implementation/65816Storage.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Processors/65816/Implementation/65816Storage.cpp b/Processors/65816/Implementation/65816Storage.cpp
index c46effd21..8c7b8bfb8 100644
--- a/Processors/65816/Implementation/65816Storage.cpp
+++ b/Processors/65816/Implementation/65816Storage.cpp
@@ -713,7 +713,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
 	static void stack_pei(AccessType, bool, const std::function<void(MicroOp)> &target) {
 		target(CycleFetchIncrementPC);			// DO.
 
-		target(OperationConstructDirect);
+		target(OperationConstructDirectLong);
 		target(CycleFetchPreviousPCThrowaway);	// IO.
 
 		target(CycleFetchIncrementData);		// AAL.

From 9abd653fb9c67fac0dbfdf088defd02c4a1e8e0b Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Sat, 21 Sep 2024 21:25:49 -0400
Subject: [PATCH 4/5] Avoid impossible clamps.

---
 ClockReceiver/ClockReceiver.hpp | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/ClockReceiver/ClockReceiver.hpp b/ClockReceiver/ClockReceiver.hpp
index 340341435..c6493499a 100644
--- a/ClockReceiver/ClockReceiver.hpp
+++ b/ClockReceiver/ClockReceiver.hpp
@@ -140,6 +140,19 @@ template <class T> class WrappedInt {
 
 		/// @returns The underlying int, converted to an integral type of your choosing, clamped to that int's range.
 		template<typename Type = IntType> forceinline constexpr Type as() const {
+			if constexpr (sizeof(Type) == sizeof(IntType)) {
+				if constexpr (std::is_same_v<Type, IntType>) {
+					return length_;
+				} else if constexpr (std::is_signed_v<Type>) {
+					// Both integers are the same size, but a signed result is being asked for
+					// from an unsigned original.
+					return length_ > Type(std::numeric_limits<Type>::max()) ? Type(std::numeric_limits<Type>::max()) : Type(length_);
+				} else {
+					// An unsigned result is being asked for from a signed original.
+					return length_ < 0 ? 0 : Type(length_);
+				}
+			}
+
 			const auto clamped = std::clamp(length_, IntType(std::numeric_limits<Type>::min()), IntType(std::numeric_limits<Type>::max()));
 			return Type(clamped);
 		}

From 17ff0c4f657c53ea1df0cf2a01f8413a9c2e0583 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Sat, 21 Sep 2024 21:28:38 -0400
Subject: [PATCH 5/5] Fix PLD/PLB sizes.

---
 Processors/65816/Implementation/65816Storage.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Processors/65816/Implementation/65816Storage.cpp b/Processors/65816/Implementation/65816Storage.cpp
index 8c7b8bfb8..5d7f43f31 100644
--- a/Processors/65816/Implementation/65816Storage.cpp
+++ b/Processors/65816/Implementation/65816Storage.cpp
@@ -668,12 +668,12 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
 	}
 
 	// 22b(ii). Stack; s, PLx, ignoring emulation mode. I.e. PLD and PLB.
-	static void stack_pld_plb(AccessType, bool, const std::function<void(MicroOp)> &target) {
+	static void stack_pld_plb(AccessType, bool is8bit, const std::function<void(MicroOp)> &target) {
 		target(CycleFetchPCThrowaway);	// IO.
 		target(CycleFetchPCThrowaway);	// IO.
 
-		target(CyclePullNotEmulation);	// REG low.
-		target(CyclePullNotEmulation);	// REG [high].
+		if(!is8bit) target(CyclePullNotEmulation);	// REG low.
+		target(CyclePullNotEmulation);				// REG [high].
 
 		target(OperationPerform);
 	}
@@ -873,7 +873,7 @@ ProcessorStorage::ProcessorStorage() {
 	/* 0x28 PLP s */			op(stack_pull, PLP, AccessMode::Always8Bit);
 	/* 0x29 AND # */			op(immediate, AND);
 	/* 0x2a ROL A */			op(accumulator, ROL);
-	/* 0x2b PLD s */			op(stack_pld_plb, PLD);
+	/* 0x2b PLD s */			op(stack_pld_plb, PLD, AccessMode::Always16Bit);
 	/* 0x2c BIT a */			op(absolute, BIT);
 	/* 0x2d AND a */			op(absolute, AND);
 	/* 0x2e ROL a */			op(absolute_rmw, ROL);