From 8a83024962bf3ed8c606b52b3f0611257a09d8c3 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Sun, 4 Oct 2020 18:52:46 -0400
Subject: [PATCH] Starts a dash towards just completing the addressing modes
 for now.

This brings me up to the end of absolute long (i.e. 4a on the datasheet).
---
 .../Implementation/65816Implementation.hpp    | 74 +++++++++++++++++--
 .../65816/Implementation/65816Storage.hpp     |  2 +-
 2 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/Processors/65816/Implementation/65816Implementation.hpp b/Processors/65816/Implementation/65816Implementation.hpp
index e9ca6dee9..6cd2269cb 100644
--- a/Processors/65816/Implementation/65816Implementation.hpp
+++ b/Processors/65816/Implementation/65816Implementation.hpp
@@ -37,8 +37,8 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
 
 			case OperationDecode: {
 				// A VERY TEMPORARY piece of logging.
-				printf("%02x\n", instruction_buffer_.value);
-				active_instruction_ = &instructions[instruction_offset_ + instruction_buffer_.value];
+				printf("[%04x] %02x\n", pc_ - 1, instruction_buffer_.value);
+				active_instruction_ = &instructions[instruction_buffer_.value];
 
 				const auto size_flag = mx_flags_[active_instruction_->size_field];
 				next_op_ = &micro_ops_[active_instruction_->program_offsets[size_flag]];
@@ -69,6 +69,10 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
 			// Data fetches and stores.
 			//
 
+#define increment_data_address() data_address_ = (data_address_ & 0xff0000) + ((data_address_ + 1) & 0xffff)
+#define decrement_data_address() data_address_ = (data_address_ & 0xff0000) + ((data_address_ - 1) & 0xffff)
+
+
 			case CycleFetchData:
 				bus_address = data_address_;
 				bus_value = data_buffer_.next_input();
@@ -79,7 +83,7 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
 				bus_address = data_address_;
 				bus_value = data_buffer_.next_input();
 				bus_operation = MOS6502Esque::Read;
-				++data_address_;
+				increment_data_address();
 			break;
 
 			case CycleStoreData:
@@ -92,16 +96,48 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
 				bus_address = data_address_;
 				bus_value = data_buffer_.next_output();
 				bus_operation = MOS6502Esque::Read;
-				++data_address_;
+				increment_data_address();
 			break;
 
 			case CycleStoreDecrementData:
 				bus_address = data_address_;
 				bus_value = data_buffer_.next_output();
 				bus_operation = MOS6502Esque::Read;
-				--data_address_;
+				decrement_data_address();
 			break;
 
+#undef increment_data_address
+#undef decrement_data_address
+
+			//
+			// Stack accesses.
+			//
+
+#define stack_access(value, operation)	\
+	if(emulation_flag_) {	\
+		bus_address = s_.halves.low | 0x100;	\
+	} else {	\
+		bus_address = s_.full;	\
+	}	\
+	bus_value = value;	\
+	bus_operation = operation;
+
+			case CyclePush:
+				stack_access(data_buffer_.next_stack(), MOS6502Esque::Write);
+				--s_.full;
+			break;
+
+			case CyclePull:
+				++s_.full;
+				stack_access(data_buffer_.next_input(), MOS6502Esque::Read);
+			break;
+
+			case CycleAccessStack:
+				stack_access(&throwaway, MOS6502Esque::Read);
+			break;
+
+#undef stack_access
+
 			//
 			// Data movement.
 			//
@@ -123,6 +159,10 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
 				data_address_ = instruction_buffer_.value | data_bank_;
 			break;
 
+			case OperationConstructAbsoluteIndexedIndirect:
+				data_address_ = (instruction_buffer_.value + (x_.full & x_masks_[1])) & 0xffff;
+			break;
+
 			//
 			// Performance.
 			//
@@ -168,6 +208,30 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
 						data_buffer_.size = 2 - mx_flags_[0];
 					break;
 
+					//
+					// Jumps.
+					//
+
+					case JML:
+						program_bank_ = instruction_buffer_.value & 0xff0000;
+						pc_ = instruction_buffer_.value & 0xffff;
+					break;
+
+					case JSL:
+						program_bank_ = instruction_buffer_.value & 0xff0000;
+						instruction_buffer_.size = 2;
+					[[fallthrough]];
+
+					case JSR: {
+						const uint16_t old_pc = pc_;
+						pc_ = instruction_buffer_.value;
+						instruction_buffer_.value = old_pc;
+					} break;
+
+					case JSL: {
+
+					} break;
+
 					default:
 						assert(false);
 				}
diff --git a/Processors/65816/Implementation/65816Storage.hpp b/Processors/65816/Implementation/65816Storage.hpp
index 514447606..f184e8b9d 100644
--- a/Processors/65816/Implementation/65816Storage.hpp
+++ b/Processors/65816/Implementation/65816Storage.hpp
@@ -207,7 +207,7 @@ struct ProcessorStorage {
 	uint8_t mx_flags_[2] = {1, 1};				// [0] = m; [1] = x. In both cases either `0` or `1`; `1` => 8-bit.
 	uint16_t m_masks_[2] = {0xff00, 0x00ff};	// [0] = src mask; [1] = dst mask.
 	uint16_t x_masks_[2] = {0xff00, 0x00ff};	// [0] = src mask; [1] = dst mask.
-	int instruction_offset_ = 0;
+	bool emulation_flag_ = true;
 
 	// I.e. the offset for direct addressing (outside of emulation mode).
 	uint16_t direct_ = 0;