X-Git-Url: http://git.joshuawise.com/fpgaboy.git/blobdiff_plain/decafd62efeba345e3ff285662021f36c9c3ae2f..49c326da841985a8aa48e8544173e5c045c6e0eb:/GBZ80Core.v diff --git a/GBZ80Core.v b/GBZ80Core.v index 45870d1..e1aa308 100644 --- a/GBZ80Core.v +++ b/GBZ80Core.v @@ -130,14 +130,28 @@ `define EXEC_NEXTADDR_PCINC address <= `_PC + 1; `define EXEC_NEWCYCLE begin newcycle <= 1; rd <= 1; wr <= 0; end `define EXEC_NEWCYCLE_TWOBYTE begin newcycle <= 1; rd <= 1; wr <= 0; twobyte <= 1; end -`define EXEC_WRITE(ad, da) begin address <= (ad); wdata <= (da); wr <= 1; end end -`define EXEC_READ(ad) begin address <= (ad); rd <= 1; end end +`ifdef verilator + `define EXEC_WRITE(ad, da) begin address <= (ad); wdata <= (da); wr <= 1; end + `define EXEC_READ(ad) begin address <= (ad); rd <= 1; end +`else + `ifdef isim + `define EXEC_WRITE(ad, da) begin address <= (ad); wdata <= (da); wr <= 1; end + `define EXEC_READ(ad) begin address <= (ad); rd <= 1; end + `else +/* Work around XST's retarded bugs :\ */ + `define EXEC_WRITE(ad, da) begin address <= (ad); wdata <= (da); wr <= 1; end end + `define EXEC_READ(ad) begin address <= (ad); rd <= 1; end end + `endif +`endif module GBZ80Core( input clk, - output reg [15:0] busaddress, /* BUS_* is latched on STATE_FETCH. */ - inout [7:0] busdata, - output reg buswr, output reg busrd, + inout [15:0] bus0address, /* BUS_* is latched on STATE_FETCH. */ + inout [7:0] bus0data, + inout bus0wr, bus0rd, + inout [15:0] bus1address, /* BUS_* is latched on STATE_FETCH. */ + inout [7:0] bus1data, + inout bus1wr, bus1rd, input irq, input [7:0] jaddr, output reg [1:0] state); @@ -156,7 +170,28 @@ module GBZ80Core( reg [7:0] tmp, tmp2; /* Generic temporary regs. */ reg [7:0] buswdata; - assign busdata = buswr ? buswdata : 8'bzzzzzzzz; + wire [7:0] busdata; + + reg [15:0] busaddress; + reg buswr, busrd; + + reg bootstrap_enb; + + wire bus = ((busaddress[15:8] == 8'h00) && bootstrap_enb) || ((busaddress[15:7] == 9'b111111111) && (busaddress != 16'hFFFF)) /* 0 or 1 depending on which bus */ + `ifdef isim + || (busaddress === 16'hxxxx) /* To avoid simulator glomulation. */ + `endif + ; + + assign bus0address = (bus == 0) ? busaddress : 16'bzzzzzzzzzzzzzzz; + assign bus1address = (bus == 1) ? busaddress : 16'bzzzzzzzzzzzzzzz; + assign bus0data = ((bus == 0) && buswr) ? buswdata : 8'bzzzzzzzz; + assign bus1data = ((bus == 1) && buswr) ? buswdata : 8'bzzzzzzzz; + assign busdata = (bus == 0) ? bus0data : bus1data; + assign bus0rd = (bus == 0) ? busrd : 1'b0; + assign bus1rd = (bus == 1) ? busrd : 1'b0; + assign bus0wr = (bus == 0) ? buswr : 1'b0; + assign bus1wr = (bus == 1) ? buswr : 1'b0; reg ie, iedelay; @@ -185,7 +220,7 @@ module GBZ80Core( 2'b0, tmp[0]}; - assign sla = {tmp[6:0],0}; + assign sla = {tmp[6:0],1'b0}; assign slaf = {(tmp[6:0] == 0 ? 1'b1 : 1'b0), 2'b0, tmp[7]}; @@ -194,10 +229,10 @@ module GBZ80Core( // assign sraf = {(tmp[7:1] == 0 ? 1'b1 : 1'b0),2'b0,tmp[0]}; now in assign srlf = assign swap = {tmp[3:0],tmp[7:4]}; - assign swapf = {(tmp == 0 ? 1'b1 : 1'b0), + assign swapf = {(tmp == 1'b0 ? 1'b1 : 1'b0), 3'b0}; - assign srl = {0,tmp[7:1]}; + assign srl = {1'b0,tmp[7:1]}; assign srlf = {(tmp[7:1] == 0 ? 1'b1 : 1'b0), 2'b0, tmp[0]}; @@ -220,18 +255,18 @@ module GBZ80Core( ); initial begin - registers[ 0] <= 0; - registers[ 1] <= 0; - registers[ 2] <= 0; - registers[ 3] <= 0; - registers[ 4] <= 0; - registers[ 5] <= 0; - registers[ 6] <= 0; - registers[ 7] <= 0; - registers[ 8] <= 0; - registers[ 9] <= 0; - registers[10] <= 0; - registers[11] <= 0; + `_A <= 0; + `_B <= 0; + `_C <= 0; + `_D <= 0; + `_E <= 0; + `_F <= 0; + `_H <= 0; + `_L <= 0; + `_PCH <= 0; + `_PCL <= 0; + `_SPH <= 0; + `_SPL <= 0; rd <= 1; wr <= 0; newcycle <= 1; @@ -246,9 +281,10 @@ module GBZ80Core( state <= `STATE_WRITEBACK; cycle <= 0; twobyte <= 0; + bootstrap_enb <= 1; end - always @(posedge clk) + always @(negedge clk) /* Set things up at the negedge to prepare for the posedge. */ case (state) `STATE_FETCH: begin if (newcycle) begin @@ -262,30 +298,39 @@ module GBZ80Core( if (wr) buswdata <= wdata; end + end + `STATE_DECODE: begin /* Make sure this only happens for one clock. */ + buswr <= 0; + busrd <= 0; + end + endcase + + always @(posedge clk) + case (state) + `STATE_FETCH: begin + /* Things are set up in negedge so that something looking on posedge will get his shit. */ state <= `STATE_DECODE; end `STATE_DECODE: begin if (newcycle) begin if (twobyte) begin - opcode <= {1,busdata}; + opcode <= {1'b1,busdata}; twobyte <= 0; end else if (ie && irq) opcode <= `INSN_VOP_INTR; else - opcode <= {0,busdata}; - rdata <= busdata; + opcode <= {1'b0,busdata}; newcycle <= 0; + rdata <= busdata; cycle <= 0; end else begin - if (rd) rdata <= busdata; + if (rd) rdata <= busdata; /* Still valid because peripherals are now expected to keep it held valid. */ cycle <= cycle + 1; end if (iedelay) begin ie <= 1; iedelay <= 0; end - buswr <= 0; - busrd <= 0; wr <= 0; rd <= 0; address <= 16'bxxxxxxxxxxxxxxxx; // Make it obvious if something of type has happened. @@ -293,6 +338,8 @@ module GBZ80Core( state <= `STATE_EXECUTE; end `STATE_EXECUTE: begin + if (opcode[7:0] === 8'bxxxxxxxx) + $stop; casex (opcode) `define EXECUTE `include "allinsns.v"