From: Joshua Wise Date: Sun, 6 Apr 2008 06:14:45 +0000 (-0400) Subject: Start refactoring instructions. X-Git-Url: http://git.joshuawise.com/fpgaboy.git/commitdiff_plain/81358c71b258a72a2777bba0a0b4a82a7cae298a Start refactoring instructions. --- diff --git a/CPUDCM.v b/CPUDCM.v new file mode 100644 index 0000000..4e677a5 --- /dev/null +++ b/CPUDCM.v @@ -0,0 +1,78 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor: Xilinx +// \ \ \/ Version : 10.1 +// \ \ Application : xaw2verilog +// / / Filename : CPUDCM.v +// /___/ /\ Timestamp : 03/31/2008 23:51:44 +// \ \ / \ +// \___\/\___\ +// +//Command: xaw2verilog -intstyle /home/joshua/projects/fpga/FPGABoy/CPUDCM.xaw -st CPUDCM.v +//Design Name: CPUDCM +//Device: xc3s500e-5fg320 +// +// Module CPUDCM +// Generated by Xilinx Architecture Wizard +// Written for synthesis tool: XST +// Period Jitter (unit interval) for block DCM_SP_INST = 0.04 UI +// Period Jitter (Peak-to-Peak) for block DCM_SP_INST = 4.90 ns +`timescale 1ns / 1ps + +module CPUDCM(CLKIN_IN, + CLKFX_OUT, + CLKIN_IBUFG_OUT, + LOCKED_OUT); + + input CLKIN_IN; + output CLKFX_OUT; + output CLKIN_IBUFG_OUT; + output LOCKED_OUT; + + wire CLKFX_BUF; + wire CLKIN_IBUFG; + wire GND_BIT; + + assign GND_BIT = 0; + assign CLKIN_IBUFG_OUT = CLKIN_IBUFG; + BUFG CLKFX_BUFG_INST (.I(CLKFX_BUF), + .O(CLKFX_OUT)); + IBUFG CLKIN_IBUFG_INST (.I(CLKIN_IN), + .O(CLKIN_IBUFG)); + DCM_SP DCM_SP_INST (.CLKFB(GND_BIT), + .CLKIN(CLKIN_IBUFG), + .DSSEN(GND_BIT), + .PSCLK(GND_BIT), + .PSEN(GND_BIT), + .PSINCDEC(GND_BIT), + .RST(GND_BIT), + .CLKDV(), + .CLKFX(CLKFX_BUF), + .CLKFX180(), + .CLK0(), + .CLK2X(), + .CLK2X180(), + .CLK90(), + .CLK180(), + .CLK270(), + .LOCKED(LOCKED_OUT), + .PSDONE(), + .STATUS()); + defparam DCM_SP_INST.CLK_FEEDBACK = "NONE"; + defparam DCM_SP_INST.CLKDV_DIVIDE = 2.0; + defparam DCM_SP_INST.CLKFX_DIVIDE = 25; + defparam DCM_SP_INST.CLKFX_MULTIPLY = 4; + defparam DCM_SP_INST.CLKIN_DIVIDE_BY_2 = "FALSE"; + defparam DCM_SP_INST.CLKIN_PERIOD = 20.000; + defparam DCM_SP_INST.CLKOUT_PHASE_SHIFT = "NONE"; + defparam DCM_SP_INST.DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; + defparam DCM_SP_INST.DFS_FREQUENCY_MODE = "LOW"; + defparam DCM_SP_INST.DLL_FREQUENCY_MODE = "LOW"; + defparam DCM_SP_INST.DUTY_CYCLE_CORRECTION = "TRUE"; + defparam DCM_SP_INST.FACTORY_JF = 16'hC080; + defparam DCM_SP_INST.PHASE_SHIFT = 0; + defparam DCM_SP_INST.STARTUP_WAIT = "FALSE"; +endmodule diff --git a/GBZ80Core.v b/GBZ80Core.v index fef4de2..b53a6e2 100644 --- a/GBZ80Core.v +++ b/GBZ80Core.v @@ -191,151 +191,9 @@ module GBZ80Core( `define EXEC_NEWCYCLE \ newcycle <= 1; rd <= 1; wr <= 0 casex (opcode) - `INSN_LD_reg_imm8: begin - case (cycle) - 0: begin - `EXEC_INC_PC; - `EXEC_NEXTADDR_PCINC; - rd <= 1; - end - 1: begin - `EXEC_INC_PC; - if (opcode[5:3] == `INSN_reg_dHL) begin - address <= {registers[`REG_H], registers[`REG_L]}; - wdata <= rdata; - rd <= 0; - wr <= 1; - end else begin - `EXEC_NEWCYCLE; - end - end - 2: begin - `EXEC_NEWCYCLE; - end - endcase - end - `INSN_HALT: begin - `EXEC_NEWCYCLE; - /* XXX Interrupts needed for HALT. */ - end - `INSN_LD_HL_reg: begin - case (cycle) - 0: begin - case (opcode[2:0]) - `INSN_reg_A: wdata <= registers[`REG_A]; - `INSN_reg_B: wdata <= registers[`REG_B]; - `INSN_reg_C: wdata <= registers[`REG_C]; - `INSN_reg_D: wdata <= registers[`REG_D]; - `INSN_reg_E: wdata <= registers[`REG_E]; - `INSN_reg_H: wdata <= registers[`REG_H]; - `INSN_reg_L: wdata <= registers[`REG_L]; - endcase - address <= {registers[`REG_H], registers[`REG_L]}; - wr <= 1; rd <= 0; - end - 1: begin - `EXEC_INC_PC; - `EXEC_NEWCYCLE; - end - endcase - end - `INSN_LD_reg_HL: begin - case(cycle) - 0: begin - address <= {registers[`REG_H], registers[`REG_L]}; - rd <= 1; - end - 1: begin - tmp <= rdata; - `EXEC_INC_PC; - `EXEC_NEWCYCLE; - end - endcase - end - `INSN_LD_reg_reg: begin - `EXEC_INC_PC; - `EXEC_NEWCYCLE; - case (opcode[2:0]) - `INSN_reg_A: tmp <= registers[`REG_A]; - `INSN_reg_B: tmp <= registers[`REG_B]; - `INSN_reg_C: tmp <= registers[`REG_C]; - `INSN_reg_D: tmp <= registers[`REG_D]; - `INSN_reg_E: tmp <= registers[`REG_E]; - `INSN_reg_H: tmp <= registers[`REG_H]; - `INSN_reg_L: tmp <= registers[`REG_L]; - endcase - end - `INSN_LD_reg_imm16: begin - `EXEC_INC_PC; - case (cycle) - 0: begin - `EXEC_NEXTADDR_PCINC; - rd <= 1; - end - 1: begin - `EXEC_NEXTADDR_PCINC; - rd <= 1; - end - 2: begin `EXEC_NEWCYCLE; end - endcase - end - `INSN_LD_SP_HL: begin - case (cycle) - 0: begin - tmp <= registers[`REG_H]; - end - 1: begin - `EXEC_NEWCYCLE; - `EXEC_INC_PC; - tmp <= registers[`REG_L]; - 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]}-2; - 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 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]} + 1; - end - 2: begin - `EXEC_NEWCYCLE; - `EXEC_INC_PC; - end - endcase - end + `define EXECUTE + `include "allinsns.v" + `undef EXECUTE `INSN_LDH_AC: begin case (cycle) 0: begin @@ -602,114 +460,9 @@ module GBZ80Core( end `STATE_WRITEBACK: begin casex (opcode) - `INSN_LD_reg_imm8: - case (cycle) - 0: begin end - 1: case (opcode[5:3]) - `INSN_reg_A: begin registers[`REG_A] <= rdata; end - `INSN_reg_B: begin registers[`REG_B] <= rdata; end - `INSN_reg_C: begin registers[`REG_C] <= rdata; end - `INSN_reg_D: begin registers[`REG_D] <= rdata; end - `INSN_reg_E: begin registers[`REG_E] <= rdata; end - `INSN_reg_H: begin registers[`REG_H] <= rdata; end - `INSN_reg_L: begin registers[`REG_L] <= rdata; end - `INSN_reg_dHL: begin /* Go off to cycle 2 */ end - endcase - 2: begin end - endcase - `INSN_HALT: begin - /* Nothing needs happen here. */ - /* XXX Interrupts needed for HALT. */ - end - `INSN_LD_HL_reg: begin - /* Nothing of interest here */ - end - `INSN_LD_reg_HL: begin - case (cycle) - 0: begin end - 1: begin - case (opcode[5:3]) - `INSN_reg_A: registers[`REG_A] <= tmp; - `INSN_reg_B: registers[`REG_B] <= tmp; - `INSN_reg_C: registers[`REG_C] <= tmp; - `INSN_reg_D: registers[`REG_D] <= tmp; - `INSN_reg_E: registers[`REG_E] <= tmp; - `INSN_reg_H: registers[`REG_H] <= tmp; - `INSN_reg_L: registers[`REG_L] <= tmp; - endcase - end - endcase - end - `INSN_LD_reg_reg: begin - case (opcode[5:3]) - `INSN_reg_A: registers[`REG_A] <= tmp; - `INSN_reg_B: registers[`REG_B] <= tmp; - `INSN_reg_C: registers[`REG_C] <= tmp; - `INSN_reg_D: registers[`REG_D] <= tmp; - `INSN_reg_E: registers[`REG_E] <= tmp; - `INSN_reg_H: registers[`REG_H] <= tmp; - `INSN_reg_L: registers[`REG_L] <= tmp; - endcase - end - `INSN_LD_reg_imm16: begin - case (cycle) - 0: begin /* */ end - 1: begin - case (opcode[5:4]) - `INSN_reg16_BC: registers[`REG_C] <= rdata; - `INSN_reg16_DE: registers[`REG_E] <= rdata; - `INSN_reg16_HL: registers[`REG_L] <= rdata; - `INSN_reg16_SP: registers[`REG_SPL] <= rdata; - endcase - end - 2: begin - case (opcode[5:4]) - `INSN_reg16_BC: registers[`REG_B] <= rdata; - `INSN_reg16_DE: registers[`REG_D] <= rdata; - `INSN_reg16_HL: registers[`REG_H] <= rdata; - `INSN_reg16_SP: registers[`REG_SPH] <= rdata; - endcase - end - endcase - end - `INSN_LD_SP_HL: begin - case (cycle) - 0: registers[`REG_SPH] <= tmp; - 1: registers[`REG_SPL] <= tmp; - endcase - end - `INSN_PUSH_reg: begin /* PUSH is 16 cycles! */ - case (cycle) - 0: begin /* type F */ end - 1: begin /* type F */ end - 2: begin /* type F */ end - 3: {registers[`REG_SPH],registers[`REG_SPL]} <= - {registers[`REG_SPH],registers[`REG_SPL]} - 2; - endcase - end - `INSN_POP_reg: begin /* POP is 12 cycles! */ - case (cycle) - 0: begin 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 - 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 - {registers[`REG_SPH],registers[`REG_SPL]} <= - {registers[`REG_SPH],registers[`REG_SPL]} + 2; - end - endcase - end + `define WRITEBACK + `include "allinsns.v" + `undef WRITEBACK `INSN_LDH_AC: begin case (cycle) 0: begin /* Type F */ end diff --git a/Makefile b/Makefile index d89b586..0a4f411 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -VLOGS=Uart.v Timer.v Interrupt.v GBZ80Core.v CPUDCM.v 7seg.v System.v +VLOGS=Uart.v Timer.v Interrupt.v GBZ80Core.v CPUDCM.v 7seg.v System.v allinsns.v insn_ld_reg_imm8.v all: CoreTop.svf CoreTop.twr -CoreTyp.ngc: CoreTop.xst CoreTop.prj $(VLOGS) CoreTop.ucf +CoreTop.ngc: CoreTop.xst CoreTop.prj $(VLOGS) CoreTop.ucf xst -ifn CoreTop.xst -ofn CoreTop.syr CoreTop.ngd: CoreTop.ngc foo.bmm diff --git a/allinsns.v b/allinsns.v new file mode 100644 index 0000000..7e92cd3 --- /dev/null +++ b/allinsns.v @@ -0,0 +1,9 @@ +`include "insn_ld_reg_imm8.v" +`include "insn_halt.v" +`include "insn_ld_hl_reg.v" +`include "insn_ld_reg_hl.v" +`include "insn_ld_reg_reg.v" +`include "insn_ld_reg_imm16.v" +`include "insn_ld_sp_hl.v" +`include "insn_push_reg.v" +`include "insn_pop_reg.v" diff --git a/insn_halt.v b/insn_halt.v new file mode 100644 index 0000000..20340f8 --- /dev/null +++ b/insn_halt.v @@ -0,0 +1,13 @@ +`ifdef EXECUTE + `INSN_HALT: begin + `EXEC_NEWCYCLE; + /* XXX Interrupts needed for HALT. */ + end +`endif + +`ifdef WRITEBACK + `INSN_HALT: begin + /* Nothing needs happen here. */ + /* XXX Interrupts needed for HALT. */ + end +`endif diff --git a/insn_ld_hl_reg.v b/insn_ld_hl_reg.v new file mode 100644 index 0000000..0b98431 --- /dev/null +++ b/insn_ld_hl_reg.v @@ -0,0 +1,29 @@ +`ifdef EXECUTE + `INSN_LD_HL_reg: begin + case (cycle) + 0: begin + case (opcode[2:0]) + `INSN_reg_A: wdata <= registers[`REG_A]; + `INSN_reg_B: wdata <= registers[`REG_B]; + `INSN_reg_C: wdata <= registers[`REG_C]; + `INSN_reg_D: wdata <= registers[`REG_D]; + `INSN_reg_E: wdata <= registers[`REG_E]; + `INSN_reg_H: wdata <= registers[`REG_H]; + `INSN_reg_L: wdata <= registers[`REG_L]; + endcase + address <= {registers[`REG_H], registers[`REG_L]}; + wr <= 1; rd <= 0; + end + 1: begin + `EXEC_INC_PC; + `EXEC_NEWCYCLE; + end + endcase + end +`endif + +`ifdef WRITEBACK + `INSN_LD_HL_reg: begin + /* Nothing of interest here */ + end +`endif diff --git a/insn_ld_reg_hl.v b/insn_ld_reg_hl.v new file mode 100644 index 0000000..3fc7862 --- /dev/null +++ b/insn_ld_reg_hl.v @@ -0,0 +1,34 @@ +`ifdef EXECUTE + `INSN_LD_reg_HL: begin + case(cycle) + 0: begin + address <= {registers[`REG_H], registers[`REG_L]}; + rd <= 1; + end + 1: begin + tmp <= rdata; + `EXEC_INC_PC; + `EXEC_NEWCYCLE; + end + endcase + end +`endif + +`ifdef WRITEBACK + `INSN_LD_reg_HL: begin + case (cycle) + 0: begin end + 1: begin + case (opcode[5:3]) + `INSN_reg_A: registers[`REG_A] <= tmp; + `INSN_reg_B: registers[`REG_B] <= tmp; + `INSN_reg_C: registers[`REG_C] <= tmp; + `INSN_reg_D: registers[`REG_D] <= tmp; + `INSN_reg_E: registers[`REG_E] <= tmp; + `INSN_reg_H: registers[`REG_H] <= tmp; + `INSN_reg_L: registers[`REG_L] <= tmp; + endcase + end + endcase + end +`endif diff --git a/insn_ld_reg_imm16.v b/insn_ld_reg_imm16.v new file mode 100644 index 0000000..b9bd84e --- /dev/null +++ b/insn_ld_reg_imm16.v @@ -0,0 +1,40 @@ +`ifdef EXECUTE + `INSN_LD_reg_imm16: begin + `EXEC_INC_PC; + case (cycle) + 0: begin + `EXEC_NEXTADDR_PCINC; + rd <= 1; + end + 1: begin + `EXEC_NEXTADDR_PCINC; + rd <= 1; + end + 2: begin `EXEC_NEWCYCLE; end + endcase + end +`endif + +`ifdef WRITEBACK + `INSN_LD_reg_imm16: begin + case (cycle) + 0: begin /* */ end + 1: begin + case (opcode[5:4]) + `INSN_reg16_BC: registers[`REG_C] <= rdata; + `INSN_reg16_DE: registers[`REG_E] <= rdata; + `INSN_reg16_HL: registers[`REG_L] <= rdata; + `INSN_reg16_SP: registers[`REG_SPL] <= rdata; + endcase + end + 2: begin + case (opcode[5:4]) + `INSN_reg16_BC: registers[`REG_B] <= rdata; + `INSN_reg16_DE: registers[`REG_D] <= rdata; + `INSN_reg16_HL: registers[`REG_H] <= rdata; + `INSN_reg16_SP: registers[`REG_SPH] <= rdata; + endcase + end + endcase + end +`endif diff --git a/insn_ld_reg_imm8.v b/insn_ld_reg_imm8.v new file mode 100644 index 0000000..77768e0 --- /dev/null +++ b/insn_ld_reg_imm8.v @@ -0,0 +1,43 @@ +`ifdef EXECUTE + `INSN_LD_reg_imm8: begin + case (cycle) + 0: begin + `EXEC_INC_PC; + `EXEC_NEXTADDR_PCINC; + rd <= 1; + end + 1: begin + `EXEC_INC_PC; + if (opcode[5:3] == `INSN_reg_dHL) begin + address <= {registers[`REG_H], registers[`REG_L]}; + wdata <= rdata; + rd <= 0; + wr <= 1; + end else begin + `EXEC_NEWCYCLE; + end + end + 2: begin + `EXEC_NEWCYCLE; + end + endcase + end +`endif + +`ifdef WRITEBACK + `INSN_LD_reg_imm8: + case (cycle) + 0: begin end + 1: case (opcode[5:3]) + `INSN_reg_A: begin registers[`REG_A] <= rdata; end + `INSN_reg_B: begin registers[`REG_B] <= rdata; end + `INSN_reg_C: begin registers[`REG_C] <= rdata; end + `INSN_reg_D: begin registers[`REG_D] <= rdata; end + `INSN_reg_E: begin registers[`REG_E] <= rdata; end + `INSN_reg_H: begin registers[`REG_H] <= rdata; end + `INSN_reg_L: begin registers[`REG_L] <= rdata; end + `INSN_reg_dHL: begin /* Go off to cycle 2 */ end + endcase + 2: begin end + endcase +`endif diff --git a/insn_ld_reg_reg.v b/insn_ld_reg_reg.v new file mode 100644 index 0000000..4b5081e --- /dev/null +++ b/insn_ld_reg_reg.v @@ -0,0 +1,29 @@ +`ifdef EXECUTE + `INSN_LD_reg_reg: begin + `EXEC_INC_PC; + `EXEC_NEWCYCLE; + case (opcode[2:0]) + `INSN_reg_A: tmp <= registers[`REG_A]; + `INSN_reg_B: tmp <= registers[`REG_B]; + `INSN_reg_C: tmp <= registers[`REG_C]; + `INSN_reg_D: tmp <= registers[`REG_D]; + `INSN_reg_E: tmp <= registers[`REG_E]; + `INSN_reg_H: tmp <= registers[`REG_H]; + `INSN_reg_L: tmp <= registers[`REG_L]; + endcase + end +`endif + +`ifdef WRITEBACK + `INSN_LD_reg_reg: begin + case (opcode[5:3]) + `INSN_reg_A: registers[`REG_A] <= tmp; + `INSN_reg_B: registers[`REG_B] <= tmp; + `INSN_reg_C: registers[`REG_C] <= tmp; + `INSN_reg_D: registers[`REG_D] <= tmp; + `INSN_reg_E: registers[`REG_E] <= tmp; + `INSN_reg_H: registers[`REG_H] <= tmp; + `INSN_reg_L: registers[`REG_L] <= tmp; + endcase + end +`endif diff --git a/insn_ld_sp_hl.v b/insn_ld_sp_hl.v new file mode 100644 index 0000000..ba10d5a --- /dev/null +++ b/insn_ld_sp_hl.v @@ -0,0 +1,23 @@ +`ifdef EXECUTE + `INSN_LD_SP_HL: begin + case (cycle) + 0: begin + tmp <= registers[`REG_H]; + end + 1: begin + `EXEC_NEWCYCLE; + `EXEC_INC_PC; + tmp <= registers[`REG_L]; + end + endcase + end +`endif + +`ifdef WRITEBACK + `INSN_LD_SP_HL: begin + case (cycle) + 0: registers[`REG_SPH] <= tmp; + 1: registers[`REG_SPL] <= tmp; + endcase + end +`endif diff --git a/insn_pop_reg.v b/insn_pop_reg.v new file mode 100644 index 0000000..9d4acbd --- /dev/null +++ b/insn_pop_reg.v @@ -0,0 +1,44 @@ +`ifdef EXECUTE + `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]} + 1; + end + 2: begin + `EXEC_NEWCYCLE; + `EXEC_INC_PC; + end + endcase + end +`endif + +`ifdef WRITEBACK + `INSN_POP_reg: begin /* POP is 12 cycles! */ + case (cycle) + 0: begin 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 + 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 + {registers[`REG_SPH],registers[`REG_SPL]} <= + {registers[`REG_SPH],registers[`REG_SPL]} + 2; + end + endcase + end +`endif diff --git a/insn_push_reg.v b/insn_push_reg.v new file mode 100644 index 0000000..7a32301 --- /dev/null +++ b/insn_push_reg.v @@ -0,0 +1,43 @@ +`ifdef EXECUTE + `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]}-2; + 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 thumbs. */ end + 3: begin + `EXEC_NEWCYCLE; + `EXEC_INC_PC; + end + endcase + end +`endif + +`ifdef WRITEBACK + `INSN_PUSH_reg: begin /* PUSH is 16 cycles! */ + case (cycle) + 0: begin /* type F */ end + 1: begin /* type F */ end + 2: begin /* type F */ end + 3: {registers[`REG_SPH],registers[`REG_SPL]} <= + {registers[`REG_SPH],registers[`REG_SPL]} - 2; + endcase + end +`endif