diff --git a/cores/nes/src/nes.v b/cores/nes/src/nes.v index ce9176d..9cfe50e 100644 --- a/cores/nes/src/nes.v +++ b/cores/nes/src/nes.v @@ -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), diff --git a/cores/nes/src/ppu.sv b/cores/nes/src/ppu.sv index 74b2fa7..70adbe1 100644 --- a/cores/nes/src/ppu.sv +++ b/cores/nes/src/ppu.sv @@ -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