1
0
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:
Gyorgy Szombathelyi
2020-02-20 11:48:29 +01:00
parent 002b091ddb
commit 8b0c06f838
2 changed files with 11 additions and 19 deletions

View File

@@ -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),

View File

@@ -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