Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module ppu_if(rstn, clk, dot0, ack, wr, la, ld,
- ena, m2, rw, a, d, q, nmin, mdr,
- ca, cd, cq, cena, cm2, crw);
- input wire rstn, clk, dot0;
- output wire ack, wr;
- output wire [7:0] la;
- output wire [8:0] ld;
- input wire ena, m2, rw;
- input wire [2:0] a;
- input wire [7:0] d;
- output reg [7:0] q;
- output wire nmin;
- input wire [7:0] mdr;
- output wire [20:0] ca;
- output reg [7:0] cd;
- input wire [7:0] cq;
- output wire cena, cm2, crw;
- wire [3:0] phi;
- wire [8:0] hc, vc;
- wire sync;
- ppu_phasegen phase(.rstn(rstn), .clk(clk), .m2(m2), .phi(phi));
- ppu_counters hvcount(.rstn(rstn), .clk(clk), .phi(phi[2]), .dot0(dot0), .hc(hc), .vc(vc), .sync(sync));
- assign cm2 = phi[1];
- reg ff, vbl, hit, over, blank;
- reg [7:0] ctrl, mask, oamaddr, buf2007;
- reg [2:0] xfine;
- reg [14:0] t;
- reg [14:0] v;
- reg clrvbl, incv, inco, rstv, rd2007, wr2007;
- wire rendering = |mask[4:3] & ~blank;
- always @(posedge clk)
- if (~sync)
- ; // ignore everything until sync triggers
- else if (phi[0])
- begin
- // blank/vbl, set at start of vblank, cleared after
- if (~|hc)
- if (~|vc)
- blank <= 1'b0;
- else if (vc == 9'd242)
- begin
- blank <= 1'b1;
- if (clrvbl)
- vbl <= 1'b0;
- else
- vbl <= 1'b1;
- end
- end
- else if (phi[1])
- ;
- else if (phi[2])
- ;
- else if (phi[3])
- begin
- clrvbl <= 1'b0;
- rstv <= 1'b0;
- rd2007 <= 1'b0;
- wr2007 <= 1'b0;
- inco <= 1'b0;
- incv <= 1'b0;
- if (m2 & ena)
- if (rw)
- if (a == 3'h2)
- begin
- q <= { vbl, hit, over, mdr[4:0] };
- ff <= 1'b0;
- clrvbl <= 1'b1;
- end
- else if (a == 3'h4)
- ; // oamdat
- else if (a == 3'h7)
- begin
- q <= buf2007;
- rd2007 <= 1'b1;
- end
- else
- q <= mdr;
- else
- case (a)
- 3'h0: begin ctrl <= d; t[11:10] <= d[1:0]; end
- 3'h1: mask <= d;
- 3'h3: oamaddr <= d;
- 3'h4: inco <= 1'b1; // write to oam, inc
- 3'h5:
- begin
- if (ff) { t[9:5], t[14:12] } <= d;
- else { t[4:0], xfine } <= d;
- ff <= ~ff;
- end
- 3'h6:
- begin
- if (ff) begin t[7:0] <= d; rstv <= 1'b1; end
- else t[14:8] <= { 1'b0, d[5:0] };
- end
- 3'h7:
- begin
- wr2007 <= 1'b1;
- cd <= d;
- end
- endcase // case(a)
- else
- begin
- if (inco)
- oamaddr <= oamaddr + 1'b1;
- if (incv)
- ;
- end // else: !if(a == 3'h7)
- end // if (phi[3])
- always @(posedge clk)
- if (m2)
- begin
- clrvbl <= 1'b0;
- rstv <= 1'b0;
- if (ena & rw)
- begin
- if (a == 3'h2)
- begin
- q <= { vbl, hit, over, mdr[4:0] };
- clrvbl <= 1'b1;
- ff <= 1'b0;
- end
- else if (a == 3'h4)
- begin
- ; // q = oamdat
- inco <= 1'b1;
- end
- else if (a == 3'h7)
- begin
- q <= buf2007;
- rd2007 <= 1'b1;
- incv <= 1'b1;
- end
- else
- q <= mdr;
- end // if (rw)
- else if (ena & ~rw)
- begin
- case (a)
- 3'h0: begin ctrl <= d; t[11:10] <= d[1:0]; end
- 3'h1: mask <= d;
- 3'h3: oamaddr <= d;
- 3'h4: ; // write to oam, inc
- 3'h5:
- begin
- if (ff) { t[9:5], t[14:12] } <= d;
- else { t[4:0], xfine } <= d;
- ff <= ~ff;
- end
- 3'h6:
- begin
- if (ff) begin t[7:0] <= d; rstv <= 1'b1; end
- else t[14:8] <= { 1'b0, d[5:0] };
- end
- 3'h7: ; // write to vram, inc
- endcase
- end // if (ena & ~rw)
- end // if (m2)
- // ack tells the buffer manager to swap the PPU over to the other one, and that the
- // line is ready for scanout
- always @(posedge clk)
- if (~rstn)
- ack <= 1'b0;
- else if (phi[2] & hc == 9'd256)
- ack <= 1'b1;
- else
- ack <= 1'b0;
- always @(posedge clk)
- if (~rstn)
- begin
- la <= 8'h0;
- ld <= 9'h0;
- wr <= 1'b0;
- end
- else if (phi[2] & hc < 9'd256)
- begin
- la <= hc[7:0];
- ld <= hs; // output of shift regs
- wr <= 1'b1;
- end
- endmodule // ppu_if
Add Comment
Please, Sign In to add comment