From 97649fedb7865d889dab2e20139bc887d871ed00 Mon Sep 17 00:00:00 2001
From: Joshua Wise <joshua@rebirth.joshuawise.com>
Date: Sat, 29 Mar 2008 04:12:10 -0400
Subject: [PATCH] PUSH and POP work

---
 FPGABoy.ise | Bin 162780 -> 162762 bytes
 GBZ80Core.v | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 rom.hex     |   7 ++--
 3 files changed, 105 insertions(+), 6 deletions(-)

diff --git a/FPGABoy.ise b/FPGABoy.ise
index 5a47155ec16ce79f541ac5154e5b64947b0b0e51..7770eb008676e674792cd2feea4e53b9fad09ccc 100644
GIT binary patch
delta 3072
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
Rd55O)95{AK>vu^g{r?%&qRRjP

delta 3066
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

diff --git a/GBZ80Core.v b/GBZ80Core.v
index fa9ed0b..cb80cb8 100644
--- a/GBZ80Core.v
+++ b/GBZ80Core.v
@@ -28,6 +28,8 @@
 `define INSN_LD_reg_reg		8'b01xxxxxx
 `define INSN_LD_reg_imm16	8'b00xx0001
 `define INSN_LD_SP_HL		8'b11111001
+`define INSN_PUSH_reg		8'b11xx0101
+`define INSN_POP_reg		8'b11xx0001
 `define INSN_reg_A		3'b111
 `define INSN_reg_B		3'b000
 `define INSN_reg_C		3'b001
@@ -40,6 +42,10 @@
 `define INSN_reg16_DE	2'b01
 `define INSN_reg16_HL	2'b10
 `define INSN_reg16_SP	2'b11
+`define INSN_stack_AF	2'b11
+`define INSN_stack_BC	2'b00
+`define INSN_stack_DE	2'b01
+`define INSN_stack_HL	2'b10
 module GBZ80Core(
 	input clk,
 	output reg [15:0] busaddress,	/* BUS_* is latched on STATE_FETCH. */
@@ -101,6 +107,10 @@ module GBZ80Core(
 				if (rd) rdata <= busdata;
 			buswr <= 0;
 			busrd <= 0;
+			wr <= 0;
+			rd <= 0;
+			address <= 16'bxxxxxxxxxxxxxxxx;	// Make it obvious if something of type has happened.
+			wdata <= 8'bxxxxxxxx;
 			state <= `STATE_EXECUTE;
 		end
 		`STATE_EXECUTE: begin
@@ -163,7 +173,7 @@ module GBZ80Core(
 				case(cycle)
 				0: begin
 						address <= {registers[`REG_H], registers[`REG_L]};
-						wr <= 0; rd <= 1;
+						rd <= 1;
 					end
 				1: begin
 						tmp <= rdata;
@@ -202,8 +212,6 @@ module GBZ80Core(
 			`INSN_LD_SP_HL: begin
 				case (cycle)
 				0:	begin
-						rd <= 0;
-						address <= 16'bxxxxxxxxxxxxxxxx;
 						tmp <= registers[`REG_H];
 					end
 				1:	begin
@@ -213,6 +221,51 @@ module GBZ80Core(
 					end
 				endcase
 			end
+			`INSN_PUSH_reg: begin	/* PUSH is 16 cycles! */
+				case (cycle)
+				0: begin
+						wr <= 1;
+						address <= {registers[`REG_SPH],registers[`REG_SPL]}-1;
+						case (opcode[5:4])
+						`INSN_stack_AF:	wdata <= registers[`REG_A];
+						`INSN_stack_BC:	wdata <= registers[`REG_B];
+						`INSN_stack_DE:	wdata <= registers[`REG_D];
+						`INSN_stack_HL:	wdata <= registers[`REG_H];
+						endcase
+					end
+				1: begin
+						wr <= 1;
+						address <= {registers[`REG_SPH],registers[`REG_SPL]}-1;
+						case (opcode[5:4])
+						`INSN_stack_AF:	wdata <= registers[`REG_F];
+						`INSN_stack_BC:	wdata <= registers[`REG_C];
+						`INSN_stack_DE:	wdata <= registers[`REG_E];
+						`INSN_stack_HL:	wdata <= registers[`REG_L];
+						endcase
+					end
+				2:	begin /* TWIDDLE OUR FUCKING THUMBS! */ end
+				3: begin
+						`EXEC_NEWCYCLE;
+						`EXEC_INC_PC;
+					end
+				endcase
+			end
+			`INSN_POP_reg: begin	/* POP is 12 cycles! */
+				case (cycle)
+				0: begin
+						rd <= 1;
+						address <= {registers[`REG_SPH],registers[`REG_SPL]};
+					end
+				1: begin
+						rd <= 1;
+						address <= {registers[`REG_SPH],registers[`REG_SPL]};
+					end
+				2: begin
+						`EXEC_NEWCYCLE;
+						`EXEC_INC_PC;
+					end
+				endcase
+			end
 			default:
 				$stop;
 			endcase
@@ -308,6 +361,51 @@ module GBZ80Core(
 					end
 				endcase
 			end
+			`INSN_PUSH_reg: begin	/* PUSH is 16 cycles! */
+				case (cycle)
+				0: begin
+						{registers[`REG_SPH],registers[`REG_SPL]} =
+							{registers[`REG_SPH],registers[`REG_SPL]} - 1;
+						cycle <= 1;
+					end
+				1:	begin
+						{registers[`REG_SPH],registers[`REG_SPL]} =
+							{registers[`REG_SPH],registers[`REG_SPL]} - 1;
+						cycle <= 2;
+					end
+				2:	cycle <= 3;
+				3:	cycle <= 0;
+				endcase
+			end
+			`INSN_POP_reg: begin	/* POP is 12 cycles! */
+				case (cycle)
+				0:	begin
+						cycle <= 1;
+						{registers[`REG_SPH],registers[`REG_SPL]} =
+							{registers[`REG_SPH],registers[`REG_SPL]} + 1;
+					end
+				1:	begin
+						case (opcode[5:4])
+						`INSN_stack_AF:	registers[`REG_F] <= rdata;
+						`INSN_stack_BC:	registers[`REG_C] <= rdata;
+						`INSN_stack_DE:	registers[`REG_E] <= rdata;
+						`INSN_stack_HL:	registers[`REG_L] <= rdata;
+						endcase
+						{registers[`REG_SPH],registers[`REG_SPL]} =
+							{registers[`REG_SPH],registers[`REG_SPL]} + 1;
+						cycle <= 2;
+					end
+				2:	begin
+						case (opcode[5:4])
+						`INSN_stack_AF:	registers[`REG_A] <= rdata;
+						`INSN_stack_BC:	registers[`REG_B] <= rdata;
+						`INSN_stack_DE:	registers[`REG_D] <= rdata;
+						`INSN_stack_HL:	registers[`REG_H] <= rdata;
+						endcase
+						cycle <= 0;
+					end
+				endcase
+			end	
 			endcase
 			state <= `STATE_FETCH;
 		end
diff --git a/rom.hex b/rom.hex
index a90b962..00214cd 100644
--- a/rom.hex
+++ b/rom.hex
@@ -4,8 +4,8 @@
 01
 // LD SP, HL
 F9
-// LD B, (HL)
-46
+// POP BC
+C1
 // LD A, 12h
 3E
 12
@@ -20,4 +20,5 @@ F9
 76
 
 @100
-56
\ No newline at end of file
+00
+56
-- 
2.43.0