From 1bcbfe173abb9650c8ae13677d4dca4f0222ab7e Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Mon, 18 Nov 2013 01:53:58 +0200
Subject: [PATCH 2/9] Expose CPU registers

---
 libgambatte/include/gambatte.h | 22 +++++++++++++++++++
 libgambatte/src/cpu.h          |  4 ++--
 libgambatte/src/gambatte.cpp   | 48 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h
index 2901fdf..5094906 100644
--- a/libgambatte/include/gambatte.h
+++ b/libgambatte/include/gambatte.h
@@ -237,6 +237,28 @@ public:
 
 	/** Get version. */
 	static std::string version();
+
+	/** CPU registers. */
+	enum cpu_register
+	{
+		REG_CYCLECOUNTER,
+		REG_PC,
+		REG_SP,
+		REG_HF1,
+		REG_HF2,
+		REG_ZF,
+		REG_CF,
+		REG_A,
+		REG_B,
+		REG_C,
+		REG_D,
+		REG_E,
+		REG_F,
+		REG_H,
+		REG_L
+	};
+	uint32_t get_cpureg(enum cpu_register reg);
+	void set_cpureg(enum cpu_register reg, uint32_t val);
 private:
 	void preload_common();
 	void postload_common(const unsigned flags);
diff --git a/libgambatte/src/cpu.h b/libgambatte/src/cpu.h
index 9f9a11e..224ba0b 100644
--- a/libgambatte/src/cpu.h
+++ b/libgambatte/src/cpu.h
@@ -88,13 +88,13 @@ public:
 	std::pair<unsigned char*, size_t> getIoRam() { return mem_.getIoRam(); }
 	std::pair<unsigned char*, size_t> getVideoRam() { return mem_.getVideoRam(); };
 
-private:
-	Memory mem_;
 	unsigned cycleCounter_;
 	unsigned short pc_;
 	unsigned short sp;
 	unsigned hf1, hf2, zf, cf;
 	unsigned char a_, b, c, d, e, /*f,*/ h, l;
+private:
+	Memory mem_;
 	bool skip_;
 
 	void process(unsigned cycles);
diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp
index 0204557..a61e177 100644
--- a/libgambatte/src/gambatte.cpp
+++ b/libgambatte/src/gambatte.cpp
@@ -298,4 +298,52 @@ std::string GB::version()
 	return "r537";
 }
 
+uint32_t GB::get_cpureg(enum cpu_register _reg)
+{
+	switch(_reg) {
+		case REG_CYCLECOUNTER:	return p_->cpu.cycleCounter_;
+		case REG_PC:		return p_->cpu.pc_;
+		case REG_SP:		return p_->cpu.sp;
+		case REG_HF1:		return p_->cpu.hf1;
+		case REG_HF2:		return p_->cpu.hf2;
+		case REG_ZF:		return p_->cpu.zf;
+		case REG_CF:		return p_->cpu.cf;
+		case REG_A:		return p_->cpu.a_;
+		case REG_B:		return p_->cpu.b;
+		case REG_C:		return p_->cpu.c;
+		case REG_D:		return p_->cpu.d;
+		case REG_E:		return p_->cpu.e;
+		case REG_F:
+			return ((p_->cpu.hf2 & 0x600 | (p_->cpu.cf & 0x100)) >> 4)
+				| (p_->cpu.zf & 0xFF ? 0 : 0x80);
+		case REG_H:		return p_->cpu.h;
+		case REG_L:		return p_->cpu.l;
+		default:		return 0;
+	}
+}
+
+void GB::set_cpureg(enum cpu_register _reg, uint32_t val)
+{
+	switch(_reg) {
+		case REG_PC:		p_->cpu.pc_ = val; break;
+		case REG_SP:		p_->cpu.sp = val; break;
+		case REG_HF1:		p_->cpu.hf1 = val; break;
+		case REG_HF2:		p_->cpu.hf2 = val; break;
+		case REG_ZF:		p_->cpu.zf = val; break;
+		case REG_CF:		p_->cpu.cf = val; break;
+		case REG_A:		p_->cpu.a_ = val; break;
+		case REG_B:		p_->cpu.b = val; break;
+		case REG_C:		p_->cpu.c = val; break;
+		case REG_D:		p_->cpu.d = val; break;
+		case REG_E:		p_->cpu.e = val; break;
+		case REG_F:
+			p_->cpu.hf2 = (val << 4) & 0x600;
+			p_->cpu.cf = (val << 4) & 0x100;
+			p_->cpu.zf = val & 0x80;
+			break;
+		case REG_H:		p_->cpu.h = val; break;
+		case REG_L:		p_->cpu.l = val; break;
+		default:		break;
+	}
+}
 }
-- 
2.1.3

