mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-02-07 00:17:07 +00:00
NES: [PPU] Timing fixes
This commit is contained in:
@@ -179,10 +179,10 @@ wire cpu_ce = (div_cpu == div_cpu_n);
|
||||
wire ppu_ce = (div_ppu == div_ppu_n);
|
||||
wire cart_ce = (cart_pre & ppu_ce); // First PPU cycle where cpu data is visible.
|
||||
|
||||
// Prefetch
|
||||
// Signals
|
||||
wire cart_pre = (ppu_tick == (cpu_tick_count[2] ? 1 : 0));
|
||||
wire ppu_fetch = (ppu_tick == (cpu_tick_count[2] ? 2 : 1));
|
||||
wire ppu_io = (ppu_tick == (cpu_tick_count[2] ? 2 : 1));
|
||||
wire ppu_read = (ppu_tick == (cpu_tick_count[2] ? 2 : 1));
|
||||
wire ppu_write = (ppu_tick == (cpu_tick_count[2] ? 1 : 0));
|
||||
|
||||
// The infamous NES jitter is important for accuracy, but wreks havok on modern devices and scalers,
|
||||
// so what I do here is pause the whole system for one PPU clock and insert a "fake" ppu clock to
|
||||
@@ -378,8 +378,8 @@ assign joypad_clock = {joypad2_cs && mr_int, joypad1_cs && mr_int};
|
||||
// 7 and 1/2 master cycles on NTSC. Therefore, the PPU should read or write once per cpu cycle, and
|
||||
// with our alignment, this should occur at PPU cycle 2 (the *third* cycle).
|
||||
|
||||
wire mr_ppu = mr_int && ppu_io; // Read *from* the PPU.
|
||||
wire mw_ppu = mw_int && ppu_io; // Write *to* the PPU.
|
||||
wire mr_ppu = mr_int && ppu_read; // Read *from* the PPU.
|
||||
wire mw_ppu = mw_int && ppu_write; // Write *to* the PPU.
|
||||
wire ppu_cs = addr >= 'h2000 && addr < 'h4000;
|
||||
wire [7:0] ppu_dout; // Data from PPU to CPU
|
||||
wire chr_read, chr_write; // If PPU reads/writes from VRAM
|
||||
@@ -402,8 +402,6 @@ PPU ppu(
|
||||
.read (ppu_cs && mr_ppu),
|
||||
.write (ppu_cs && mw_ppu),
|
||||
.nmi (nmi),
|
||||
.pre_read (ppu_fetch & mr_int & ppu_cs),
|
||||
.pre_write (ppu_fetch & mw_int & ppu_cs),
|
||||
.vram_r (chr_read),
|
||||
.vram_w (chr_write),
|
||||
.vram_a (chr_addr),
|
||||
|
||||
@@ -603,8 +603,6 @@ module PPU(
|
||||
input read, // read
|
||||
input write, // write
|
||||
output reg nmi, // one while inside vblank
|
||||
input pre_read,
|
||||
input pre_write,
|
||||
output vram_r, // read from vram active
|
||||
output vram_w, // write to vram active
|
||||
output [13:0] vram_a, // vram address
|
||||
@@ -829,12 +827,12 @@ assign vram_a =
|
||||
{1'b0, bg_patt, bg_name_table, cycle[1], loopy[14:12]}; // Pattern table bitmap #0, #1
|
||||
|
||||
// Read from VRAM, either when user requested a manual read, or when we're generating pixels.
|
||||
wire vram_r_ppudata = pre_read && (ain == 7);
|
||||
wire vram_r_ppudata = read && (ain == 7);
|
||||
|
||||
assign vram_r = vram_r_ppudata || is_rendering && cycle[0] == 0 && !end_of_line;
|
||||
|
||||
// Write to VRAM?
|
||||
assign vram_w = pre_write && (ain == 7) && !is_pal_address && !is_rendering;
|
||||
assign vram_w = write && (ain == 7) && !is_pal_address && !is_rendering;
|
||||
|
||||
wire [5:0] color2;
|
||||
wire [4:0] pram_addr = is_rendering ?
|
||||
@@ -855,6 +853,8 @@ wire pal_mask = ~|scanline || cycle < 2 || cycle > 253;
|
||||
assign color = (|sys_type && pal_mask) ? 6'h0E : (grayscale ? {color2[5:4], 4'b0} : color2);
|
||||
|
||||
reg enable_playfield, enable_objects;
|
||||
wire clear_nmi = (exiting_vblank | (read && ain == 2));
|
||||
wire set_nmi = entering_vblank & ~clear_nmi;
|
||||
|
||||
always @(posedge clk)
|
||||
if (ce) begin
|
||||
@@ -882,15 +882,9 @@ if (ce) begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
// https://wiki.nesdev.com/w/index.php/NMI
|
||||
// Reset frame specific counters upon exiting vblank
|
||||
if (exiting_vblank)
|
||||
nmi_occured <= 0;
|
||||
// Set the
|
||||
if (entering_vblank)
|
||||
if (set_nmi)
|
||||
nmi_occured <= 1;
|
||||
// Reset NMI register when reading from Status
|
||||
if (read && ain == 2)
|
||||
if (clear_nmi)
|
||||
nmi_occured <= 0;
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user