From: Joshua Wise Date: Sat, 5 Apr 2008 04:34:42 +0000 (-0400) Subject: Cut 1 at interrupt support for CPU X-Git-Url: http://git.joshuawise.com/fpgaboy.git/commitdiff_plain/f8db64484a25b6970acb75b35188efd7089e572a Cut 1 at interrupt support for CPU --- diff --git a/FPGABoy.ise b/FPGABoy.ise index 2278455..3562e29 100644 Binary files a/FPGABoy.ise and b/FPGABoy.ise differ diff --git a/GBZ80Core.v b/GBZ80Core.v index 095d9e8..57c22d2 100644 --- a/GBZ80Core.v +++ b/GBZ80Core.v @@ -46,6 +46,9 @@ `define INSN_JR_imm 8'b00011000 `define INSN_JRCC_imm 8'b001xx000 `define INSN_INCDEC16 8'b00xxx011 +`define INSN_VOP_INTR 8'b11111100 // 0xFC is grabbed by the fetch if there is an interrupt pending. +`define INSN_DI 8'b11110011 +`define INSN_EI 8'b11111011 `define INSN_cc_NZ 2'b00 `define INSN_cc_Z 2'b01 @@ -89,7 +92,8 @@ module GBZ80Core( input clk, output reg [15:0] busaddress = 0, /* BUS_* is latched on STATE_FETCH. */ inout [7:0] busdata, - output reg buswr = 0, output reg busrd = 0); + output reg buswr = 0, output reg busrd = 0, + input irq, input [7:0] jaddr); reg [1:0] state = 0; /* State within this bus cycle (see STATE_*). */ reg [2:0] cycle = 0; /* Cycle for instructions. */ @@ -108,7 +112,7 @@ module GBZ80Core( reg [7:0] buswdata; assign busdata = buswr ? buswdata : 8'bzzzzzzzz; - reg ie = 0; + reg ie = 0, iedelay = 0; initial begin registers[ 0] <= 0; @@ -129,6 +133,10 @@ module GBZ80Core( newcycle <= 1; state <= 0; cycle <= 0; + busrd <= 0; + buswr <= 0; + busaddress <= 0; + iedelay <= 0; end always @(posedge clk) @@ -149,7 +157,10 @@ module GBZ80Core( end `STATE_DECODE: begin if (newcycle) begin - opcode <= busdata; + if (ie && irq) + opcode <= `INSN_VOP_INTR; + else + opcode <= busdata; rdata <= busdata; newcycle <= 0; cycle <= 0; @@ -157,6 +168,10 @@ module GBZ80Core( if (rd) rdata <= busdata; cycle <= cycle + 1; end + if (iedelay) begin + ie <= 1; + iedelay <= 0; + end buswr <= 0; busrd <= 0; wr <= 0; @@ -552,6 +567,31 @@ module GBZ80Core( end endcase end + `INSN_VOP_INTR: begin + case (cycle) + 0: begin + address <= {registers[`REG_SPH],registers[`REG_SPL]} - 1; + wdata <= registers[`REG_PCH]; + wr <= 1; + end + 1: begin + address <= {registers[`REG_SPH],registers[`REG_SPL]} - 2; + wdata <= registers[`REG_PCL]; + wr <= 1; + end + 2: begin + `EXEC_NEWCYCLE; + end + endcase + end + `INSN_DI: begin + `EXEC_NEWCYCLE; + `EXEC_INC_PC; + end + `INSN_EI: begin + `EXEC_NEWCYCLE; + `EXEC_INC_PC; + end default: $stop; endcase @@ -896,6 +936,20 @@ module GBZ80Core( end endcase end + `INSN_VOP_INTR: begin + case (cycle) + 0: begin end + 1: {registers[`REG_SPH],registers[`REG_SPL]} + <= {registers[`REG_SPH],registers[`REG_SPL]} - 2; + 2: begin + ie <= 0; + {registers[`REG_PCH],registers[`REG_PCL]} <= + {8'b0,jaddr}; + end + endcase + end + `INSN_DI: ie <= 0; + `INSN_EI: iedelay <= 1; default: $stop; endcase diff --git a/System.v b/System.v index 8b8d613..7319ebf 100644 --- a/System.v +++ b/System.v @@ -76,13 +76,18 @@ module CoreTop( wire [15:0] addr; wire [7:0] data; wire wr, rd; + + wire irq, tmrirq; + wire [7:0] jaddr; GBZ80Core core( .clk(clk), .busaddress(addr), .busdata(data), .buswr(wr), - .busrd(rd)); + .busrd(rd), + .irq(irq), + .jaddr(jaddr)); ROM rom( .address(addr), @@ -125,8 +130,6 @@ module CoreTop( .wr(wr), .rd(rd)); - wire irq, tmrirq; - wire [7:0] jaddr; Timer tmr( .clk(clk), .wr(wr), @@ -156,6 +159,9 @@ module TestBench(); wire [7:0] data; wire wr, rd; + wire irq, tmrirq; + wire [7:0] jaddr; + // wire [7:0] leds; // wire [7:0] switches; @@ -165,7 +171,9 @@ module TestBench(); .busaddress(addr), .busdata(data), .buswr(wr), - .busrd(rd)); + .busrd(rd), + .irq(irq), + .jaddr(jaddr)); ROM rom( .clk(clk), @@ -190,8 +198,6 @@ module TestBench(); .rd(rd), .serial(serio)); - wire irq, tmrirq; - wire [7:0] jaddr; Timer tmr( .clk(clk), .wr(wr),