From e502d76371b92bf63c5b354ff1fe957f654b5860 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Tue, 19 Jan 2021 22:12:18 -0500
Subject: [PATCH] Corrects immediate instruction length, muddles through to
 having to parse a second program segment.

Albeit with JSR not yet properly implemented.
---
 InstructionSets/M50740/Decoder.cpp     |  2 +-
 InstructionSets/M50740/Executor.cpp    | 30 ++++++++++++++++++++++++--
 InstructionSets/M50740/Executor.hpp    |  2 +-
 InstructionSets/M50740/Instruction.hpp | 10 ++++-----
 4 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/InstructionSets/M50740/Decoder.cpp b/InstructionSets/M50740/Decoder.cpp
index 8293bd465..fe0e2fc18 100644
--- a/InstructionSets/M50740/Decoder.cpp
+++ b/InstructionSets/M50740/Decoder.cpp
@@ -144,7 +144,7 @@ Instruction Decoder::instrucion_for_opcode(uint8_t opcode) {
 		Map(0x96, STX, ZeroPageX);					Map(0x97, BBC4, ZeroPageRelative);
 
 		Map(0x98, TYA, Implied);					Map(0x99, STA, AbsoluteY);
-		Map(0x9a, TXS, AbsoluteY);					Map(0x9b, CLB4, Accumulator);
+		Map(0x9a, TXS, Implied);					Map(0x9b, CLB4, Accumulator);
 
 													Map(0x9d, ADC, AbsoluteX);
 													Map(0x9f, CLB4, ZeroPage);
diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp
index 5b73a939e..5dcb5d5af 100644
--- a/InstructionSets/M50740/Executor.cpp
+++ b/InstructionSets/M50740/Executor.cpp
@@ -42,7 +42,7 @@ void Executor::set_rom(const std::vector<uint8_t> &rom) {
 
 void Executor::reset() {
 	// Just jump to the reset vector.
-	set_program_counter(uint16_t(memory_[0x1ffe] | (memory_[0x1fff] << 8)) & 0x1fff);
+	set_program_counter(uint16_t(memory_[0x1ffe] | (memory_[0x1fff] << 8)));
 }
 
 template <Operation operation, AddressingMode addressing_mode> void Executor::perform() {
@@ -55,6 +55,8 @@ template <Operation operation, AddressingMode addressing_mode> void Executor::pe
 #define next8()		memory_[(program_counter_ + 1) & 0x1fff]
 #define next16()	(memory_[(program_counter_ + 1) & 0x1fff] | (memory_[(program_counter_ + 2) & 0x1fff] << 8))
 
+	printf("%d %d\n", int(operation), int(addressing_mode));
+
 	// Underlying assumption below: the instruction stream will never
 	// overlap with IO ports.
 	switch(addressing_mode) {
@@ -130,8 +132,25 @@ template <Operation operation, AddressingMode addressing_mode> void Executor::pe
 
 #undef next16
 #undef next8
-
 	program_counter_ += 1 + size(addressing_mode);
+
+	// Check for a branch; those don't go through the memory accesses below.
+	switch(operation) {
+		case Operation::JMP:
+			set_program_counter(uint16_t(address));
+		return;
+
+		case Operation::JSR:
+			// TODO: push!
+			set_program_counter(uint16_t(address));
+		return;
+
+		/* TODO: all other types of branches and calls. */
+
+		default: break;
+	}
+
+
 	assert(access_type(operation) != AccessType::None);
 
 	// TODO: full reading/writing logic here; only the first 96 bytes are RAM,
@@ -159,6 +178,13 @@ template <Operation operation> void Executor::perform(uint8_t *operand [[maybe_u
 		case Operation::STX:	*operand = x_;	break;
 		case Operation::STY:	*operand = y_;	break;
 
+		case Operation::TXA:	set_nz(a_ = x_);	break;
+		case Operation::TYA:	set_nz(a_ = y_);	break;
+		case Operation::TXS:	s_ = x_;			break;
+		case Operation::TAX:	set_nz(x_ = a_);	break;
+		case Operation::TAY:	set_nz(y_ = a_);	break;
+		case Operation::TSX:	set_nz(x_ = s_);	break;
+
 		case Operation::SEB0:	case Operation::SEB1:	case Operation::SEB2:	case Operation::SEB3:
 		case Operation::SEB4:	case Operation::SEB5:	case Operation::SEB6:	case Operation::SEB7:
 			*operand |= 1 << (int(operation) - int(Operation::SEB0));
diff --git a/InstructionSets/M50740/Executor.hpp b/InstructionSets/M50740/Executor.hpp
index 9f3b71fcc..2433c5573 100644
--- a/InstructionSets/M50740/Executor.hpp
+++ b/InstructionSets/M50740/Executor.hpp
@@ -46,7 +46,7 @@ class Executor: public CachingExecutor {
 		*/
 		inline void parse(uint16_t start, uint16_t closing_bound) {
 			Parser<Executor, false> parser;
-			parser.parse(*this, memory_, start, closing_bound);
+			parser.parse(*this, memory_, start & 0x1fff, closing_bound);
 		}
 
 	private:
diff --git a/InstructionSets/M50740/Instruction.hpp b/InstructionSets/M50740/Instruction.hpp
index 803f3ed80..bbb69ef3f 100644
--- a/InstructionSets/M50740/Instruction.hpp
+++ b/InstructionSets/M50740/Instruction.hpp
@@ -16,10 +16,10 @@ namespace InstructionSet {
 namespace M50740 {
 
 enum class AddressingMode {
-	Implied,			Accumulator,			Immediate,
-	Absolute,			AbsoluteX,				AbsoluteY,
-	ZeroPage,			ZeroPageX,				ZeroPageY,
-	XIndirect,			IndirectY,
+	Implied,				Accumulator,			Immediate,
+	Absolute,				AbsoluteX,				AbsoluteY,
+	ZeroPage,				ZeroPageX,				ZeroPageY,
+	XIndirect,				IndirectY,
 	Relative,
 	AbsoluteIndirect,		ZeroPageIndirect,
 	SpecialPage,
@@ -33,7 +33,7 @@ static constexpr auto MinAddressingMode = int(AddressingMode::Implied);
 constexpr int size(AddressingMode mode) {
 	// This is coupled to the AddressingMode list above; be careful!
 	constexpr int sizes[] = {
-		0, 0, 0,
+		0, 0, 1,
 		2, 2, 2,
 		1, 1, 1,
 		1, 1,