diff --git a/rtl/cart.sv b/rtl/cart.sv index ec7ef0a..1796e8f 100644 --- a/rtl/cart.sv +++ b/rtl/cart.sv @@ -17,10 +17,10 @@ module cart_top ( input clk, - input ce, - input ppu_ce, + input ce, // M2 + input cpu_ce, // CPU Phi1 clock (several mappers use m2 inverted) + input paused, // This indicates the core is paused so anything using the master clock won't get messed up input reset, - input [19:0] ppuflags, // Misc flags from PPU for MMC5 cheating input [63:0] flags, // Misc flags from ines header {prg_size(3), chr_size(3), mapper(8)} input [15:0] prg_ain, // Better known as "CPU Address in" output reg [24:0] prg_aout, // PRG Input / Output Address Lines ([25:22] extended Lines [Misc ROM]) @@ -277,7 +277,7 @@ Mapper32 map32( //*****************************************************************************// MMC2 mmc2( .clk (clk), - .ce (ppu_ce), // PPU_CE + .ce (ce), .enable (me[9]), .flags (flags), .prg_ain (prg_ain), @@ -299,6 +299,7 @@ MMC2 mmc2( .audio_b (audio_out_b), // Special ports .chr_ain_o (chr_ain_orig), + .paused (paused), // savestates .SaveStateBus_Din (SaveStateBus_Din ), .SaveStateBus_Adr (SaveStateBus_Adr ), @@ -322,7 +323,7 @@ wire mmc3_en = me[118] | me[119] | me[47] | me[206] | me[112] | me[88] | me[154] MMC3 mmc3 ( .clk (clk), - .ce (ppu_ce), // PPU CE + .ce (ce), .enable (mmc3_en), .flags (flags), .prg_ain (prg_ain), @@ -344,6 +345,8 @@ MMC3 mmc3 ( .audio_b (audio_out_b), // Special ports .chr_ain_o (chr_ain_orig), + .m2_inv (cpu_ce), + .paused (paused), // savestates .SaveStateBus_Din (SaveStateBus_Din ), .SaveStateBus_Adr (SaveStateBus_Adr ), @@ -362,7 +365,7 @@ MMC3 mmc3 ( //*****************************************************************************// MMC4 mmc4( .clk (clk), - .ce (ppu_ce), // PPU_CE + .ce (ce), .enable (me[10]), .flags (flags), .prg_ain (prg_ain), @@ -384,6 +387,7 @@ MMC4 mmc4( .audio_b (audio_out_b), // Special ports .chr_ain_o (chr_ain_orig), + .paused (paused), // savestates .SaveStateBus_Din (SaveStateBus_Din ), .SaveStateBus_Adr (SaveStateBus_Adr ), @@ -428,7 +432,7 @@ MMC5 mmc5( .chr_din (chr_din), .chr_write (chr_write), .chr_dout_b (chr_dout_b), - .ppu_ce (ppu_ce), + .paused (paused), // savestates .SaveStateBus_Din (SaveStateBus_Din ), .SaveStateBus_Adr (SaveStateBus_Adr ), @@ -1221,7 +1225,7 @@ Mapper111 map111( //*****************************************************************************// Mapper165 map165( .clk (clk), - .ce (ppu_ce), // PPU_CE + .ce (ce), .enable (me[165]), .flags (flags), .prg_ain (prg_ain), @@ -1242,7 +1246,9 @@ Mapper165 map165( .audio_in (audio_in), .audio_b (audio_out_b), // Special ports - .chr_ain_o (chr_ain_orig) + .chr_ain_o (chr_ain_orig), + .m2_inv (cpu_ce), + .paused (paused) ); //*****************************************************************************// @@ -1623,7 +1629,7 @@ VRC5 vrc5( .chr_din (chr_din), .chr_write (chr_write), .chr_dout_b (chr_dout_b), - .ppu_ce (ppu_ce), + .paused (paused), // savestates .SaveStateBus_Din (SaveStateBus_Din ), .SaveStateBus_Adr (SaveStateBus_Adr ), @@ -1810,8 +1816,7 @@ Nanjing map163( .audio_in (audio_in), .audio_b (audio_out_b), // Special Ports - .ppu_ce (ppu_ce), - .ppuflags (ppuflags) + .paused (paused) ); @@ -1988,7 +1993,7 @@ JYCompany jycompany( .audio_in (audio_in), .audio_b (audio_out_b), // Special ports - .ppu_ce (ppu_ce), + .paused (paused), .chr_ain_o (chr_ain_orig), // savestates .SaveStateBus_Din (SaveStateBus_Din ), @@ -2075,7 +2080,7 @@ Mapper225 map225( //*****************************************************************************// Mapper413 map413 ( .clk (clk), - .ce (ppu_ce), // PPU CE + .ce (ce), .enable (me[413]), .flags (flags), .prg_ain (prg_ain), @@ -2097,7 +2102,9 @@ Mapper413 map413 ( .audio_b (audio_out_b), // Special ports .chr_ain_o (chr_ain_orig), - .prg_aoute (prg_aoute_m413) + .prg_aoute (prg_aoute_m413), + .m2_inv (cpu_ce), + .paused (paused) ); //*****************************************************************************// diff --git a/rtl/mappers/JYCompany.sv b/rtl/mappers/JYCompany.sv index 9b2ea68..ee90c55 100644 --- a/rtl/mappers/JYCompany.sv +++ b/rtl/mappers/JYCompany.sv @@ -76,7 +76,7 @@ module JYCompany( inout [15:0] audio_b, // Mixed audio output inout [15:0] flags_out_b, // flags {0, 0, 0, 0, has_savestate, prg_conflict, prg_bus_write, has_chr_dout} // Special ports - input ppu_ce, + input paused, input [13:0] chr_ain_o, // savestates input [63:0] SaveStateBus_Din, @@ -220,7 +220,7 @@ always @(posedge clk) begin endcase end - if (ppu_ce) old_a12 <= chr_ain_o[12]; + if (~paused) old_a12 <= chr_ain_o[12]; if (irq_source && irq_enable && (irq_mode[7] != irq_mode[6])) begin irq_prescalar <= irq_mode[6] ? (irq_prescalar + 8'd1) : (irq_prescalar - 8'd1); @@ -248,8 +248,8 @@ end always @* begin case(irq_mode[1:0]) 2'b00: irq_source = ce; - 2'b01: irq_source = ppu_ce && chr_ain_o[12] && !old_a12; - 2'b10: irq_source = ppu_ce && chr_read; + 2'b01: irq_source = ~paused && chr_ain_o[12] && !old_a12; + 2'b10: irq_source = ~paused && chr_read; 2'b11: irq_source = ce && prg_write; endcase end @@ -367,7 +367,7 @@ if (~enable) begin chr_latch <= 2'b00; end else if (SaveStateBus_load) begin chr_latch <= SS_MAP6[11:10]; -end else if (ppu_ce && chr_read) begin +end else if (~paused && chr_read) begin chr_latch[chr_ain_o[12]] <= outer_bank[7] && (((chr_ain_o & 14'h2ff8) == 14'h0fd8) ? 1'd0 : ((chr_ain_o & 14'h2ff8) == 14'h0fe8) ? 1'd1 : chr_latch[chr_ain_o[12]]); end wire [2:0] chr_reg; diff --git a/rtl/mappers/MMC2.sv b/rtl/mappers/MMC2.sv index f7323ca..70401e3 100644 --- a/rtl/mappers/MMC2.sv +++ b/rtl/mappers/MMC2.sv @@ -24,6 +24,7 @@ module MMC2( inout [15:0] audio_b, // Mixed audio output inout [15:0] flags_out_b, // flags {0, 0, 0, 0, has_savestate, prg_conflict, prg_bus_write, has_chr_dout} input [13:0] chr_ain_o, + input paused, // savestates input [63:0] SaveStateBus_Din, input [ 9:0] SaveStateBus_Adr, @@ -140,7 +141,7 @@ if (~enable) begin end else if (SaveStateBus_load) begin latch_0 <= SS_MAP1[ 25]; latch_1 <= SS_MAP1[ 26]; -end else if (ce && chr_read) begin +end else if (~paused && chr_read) begin latch_0 <= (chr_ain_o & 14'h3fff) == 14'h0fd8 ? 1'd0 : (chr_ain_o & 14'h3fff) == 14'h0fe8 ? 1'd1 : latch_0; latch_1 <= (chr_ain_o & 14'h3ff8) == 14'h1fd8 ? 1'd0 : (chr_ain_o & 14'h3ff8) == 14'h1fe8 ? 1'd1 : latch_1; end @@ -220,6 +221,7 @@ module MMC4( inout [15:0] audio_b, // Mixed audio output inout [15:0] flags_out_b, // flags {0, 0, 0, 0, has_savestate, prg_conflict, prg_bus_write, has_chr_dout} input [13:0] chr_ain_o, + input paused, // savestates input [63:0] SaveStateBus_Din, input [ 9:0] SaveStateBus_Adr, @@ -334,7 +336,7 @@ always @(posedge clk) if (SaveStateBus_load) begin latch_0 <= SS_MAP1[ 25]; latch_1 <= SS_MAP1[ 26]; -end else if (ce & chr_read) begin +end else if (~paused & chr_read) begin latch_0 <= (chr_ain_o & 14'h3ff8) == 14'h0fd8 ? 1'd0 : (chr_ain_o & 14'h3ff8) == 14'h0fe8 ? 1'd1 : latch_0; latch_1 <= (chr_ain_o & 14'h3ff8) == 14'h1fd8 ? 1'd0 : (chr_ain_o & 14'h3ff8) == 14'h1fe8 ? 1'd1 : latch_1; end diff --git a/rtl/mappers/MMC3.sv b/rtl/mappers/MMC3.sv index 159306e..6b63007 100644 --- a/rtl/mappers/MMC3.sv +++ b/rtl/mappers/MMC3.sv @@ -310,6 +310,8 @@ module MMC3 ( inout [15:0] audio_b, // Mixed audio output inout [15:0] flags_out_b, // flags {0, 0, 0, 0, has_savestate, prg_conflict, prg_bus_write, has_chr_dout} input [13:0] chr_ain_o, + input m2_inv, + input paused, // savestates input [63:0] SaveStateBus_Din, input [ 9:0] SaveStateBus_Adr, @@ -354,7 +356,7 @@ reg [7:0] prg_bank_0, prg_bank_1, prg_bank_2; // Selected PRG banks reg last_a12; wire prg_is_ram; reg [6:0] irq_reg; -assign irq = mapper48 ? irq_reg[6] & irq_enable : irq_reg[0]; +assign irq = mapper48 ? irq_reg[3] & irq_enable : irq_reg[0]; reg [7:0] m268_reg [5:0]; // The alternative behavior has slightly different IRQ counter semantics. @@ -466,151 +468,161 @@ end else if (SaveStateBus_load) begin m268_reg[5] <= SS_MAP3[47:40]; chr_bank_0_0 <= SS_MAP1[ 48]; chr_bank_1_0 <= SS_MAP1[ 49]; -end else if (ce) begin - irq_reg[6:1] <= irq_reg[5:0]; // 6 cycle delay - if (!regs_7e && prg_write && prg_ain[15]) begin - if (!mapper33 && !mapper48 && !mapper112) begin - casez({prg_ain[14:13], prg_reg_odd}) - 3'b00_0: {chr_a12_invert, prg_rom_bank_mode, ram6_enabled, bank_select} <= {prg_din[7:5], prg_din[2:0]}; // Bank select ($8000-$9FFE, even) - 3'b00_1: begin // Bank data ($8001-$9FFF, odd) - case (bank_select) - 0: {chr_bank_0,chr_bank_0_0} <= {1'b0,prg_din}; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF); - 1: {chr_bank_1,chr_bank_1_0} <= {1'b0,prg_din}; // Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF); - 2: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); - 3: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); - 4: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); - 5: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); - 6: prg_bank_0 <= prg_din; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); - 7: prg_bank_1 <= prg_din; // Select 8 KB PRG ROM bank at $A000-$BFFF - endcase - end - 3'b01_0: mirroring <= !prg_din[0]; // Mirroring ($A000-$BFFE, even) - 3'b01_1: {ram_enable, ram_protect, ram6_enable, ram6_protect} <= {{4{prg_din[7]}},{4{prg_din[6]}}, prg_din[5:4]}; // PRG RAM protect ($A001-$BFFF, odd) - 3'b10_0: irq_latch <= prg_din; // IRQ latch ($C000-$DFFE, even) - 3'b10_1: irq_reload <= 1; // IRQ reload ($C001-$DFFF, odd) - 3'b11_0: {irq_enable, irq_reg[0]} <= 2'b00; // IRQ disable ($E000-$FFFE, even) - 3'b11_1: irq_enable <= 1; // IRQ enable ($E001-$FFFF, odd) - endcase - end else if (!mapper112) begin - casez({prg_ain[14:13], prg_ain[1:0], mapper48}) - 5'b00_00_0: {mirroring, prg_bank_0[5:0]} <= prg_din[6:0] ^ 7'h40; // Select 8 KB PRG ROM bank at $8000-$9FFF - 5'b00_00_1: prg_bank_0[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF - 5'b00_01_?: prg_bank_1[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF - 5'b00_10_?: chr_bank_0 <= prg_din; // Select 2 KB CHR bank at PPU $0000-$07FF - 5'b00_11_?: chr_bank_1 <= prg_din; // Select 2 KB CHR bank at PPU $0800-$0FFF - 5'b01_00_?: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF - 5'b01_01_?: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF - 5'b01_10_?: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF - 5'b01_11_?: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF - - 5'b10_00_1: irq_latch <= prg_din ^ 8'hFF; // IRQ latch ($C000-$DFFC) - 5'b10_01_1: {irq_reload, irq_reg} <= 8'b10000000; // IRQ reload ($C001-$DFFD) - 5'b10_10_1: irq_enable <= 1; // IRQ enable ($C002-$DFFE) - 5'b10_11_1: irq_enable <= 0; // IRQ disable ($C003-$DFFF) - - 5'b11_00_1: mirroring <= !prg_din[6]; // Mirroring - endcase - end else begin - casez({prg_ain[14:13], prg_ain[0]}) - 3'b00_0: {bank_select} <= {prg_din[2:0]}; // Bank select ($8000-$9FFE) - - 3'b01_0: begin // Bank data ($A000-$BFFF) - case (bank_select) - 0: prg_bank_0 <= prg_din; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); - 1: prg_bank_1 <= prg_din; // Select 8 KB PRG ROM bank at $A000-$BFFF - 2: chr_bank_0 <= {1'b0,prg_din[7:1]}; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF); - 3: chr_bank_1 <= {1'b0,prg_din[7:1]}; // Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF); - 4: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); - 5: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); - 6: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); - 7: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); - endcase - end - - 3'b11_0: mirroring <= !prg_din[0]; // Mirroring ($E000-$FFFE) +end else begin + if (ce) begin // M2 + if (!regs_7e && prg_write && prg_ain[15]) begin + if (!mapper33 && !mapper48 && !mapper112) begin + casez({prg_ain[14:13], prg_reg_odd}) + 3'b00_0: {chr_a12_invert, prg_rom_bank_mode, ram6_enabled, bank_select} <= {prg_din[7:5], prg_din[2:0]}; // Bank select ($8000-$9FFE, even) + 3'b00_1: begin // Bank data ($8001-$9FFF, odd) + case (bank_select) + 0: {chr_bank_0,chr_bank_0_0} <= {1'b0,prg_din}; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF); + 1: {chr_bank_1,chr_bank_1_0} <= {1'b0,prg_din}; // Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF); + 2: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); + 3: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); + 4: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); + 5: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); + 6: prg_bank_0 <= prg_din; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); + 7: prg_bank_1 <= prg_din; // Select 8 KB PRG ROM bank at $A000-$BFFF + endcase + end + 3'b01_0: mirroring <= !prg_din[0]; // Mirroring ($A000-$BFFE, even) + 3'b01_1: {ram_enable, ram_protect, ram6_enable, ram6_protect} <= {{4{prg_din[7]}},{4{prg_din[6]}}, prg_din[5:4]}; // PRG RAM protect ($A001-$BFFF, odd) + 3'b10_0: irq_latch <= prg_din; // IRQ latch ($C000-$DFFE, even) + 3'b10_1: irq_reload <= 1; // IRQ reload ($C001-$DFFF, odd) + 3'b11_0: {irq_enable, irq_reg[0]} <= 2'b00; // IRQ disable ($E000-$FFFE, even) + 3'b11_1: irq_enable <= 1; // IRQ enable ($E001-$FFFF, odd) + endcase + end else if (!mapper112) begin + casez({prg_ain[14:13], prg_ain[1:0], mapper48}) + 5'b00_00_0: {mirroring, prg_bank_0[5:0]} <= prg_din[6:0] ^ 7'h40; // Select 8 KB PRG ROM bank at $8000-$9FFF + 5'b00_00_1: prg_bank_0[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF + 5'b00_01_?: prg_bank_1[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF + 5'b00_10_?: chr_bank_0 <= prg_din; // Select 2 KB CHR bank at PPU $0000-$07FF + 5'b00_11_?: chr_bank_1 <= prg_din; // Select 2 KB CHR bank at PPU $0800-$0FFF + 5'b01_00_?: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF + 5'b01_01_?: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF + 5'b01_10_?: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF + 5'b01_11_?: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF + + 5'b10_00_1: irq_latch <= prg_din ^ 8'hFF; // IRQ latch ($C000-$DFFC) + 5'b10_01_1: {irq_reload, irq_reg} <= 8'b10000000; // IRQ reload ($C001-$DFFD) + 5'b10_10_1: irq_enable <= 1; // IRQ enable ($C002-$DFFE) + 5'b10_11_1: irq_enable <= 0; // IRQ disable ($C003-$DFFF) + + 5'b11_00_1: mirroring <= !prg_din[6]; // Mirroring + endcase + end else begin + casez({prg_ain[14:13], prg_ain[0]}) + 3'b00_0: {bank_select} <= {prg_din[2:0]}; // Bank select ($8000-$9FFE) + + 3'b01_0: begin // Bank data ($A000-$BFFF) + case (bank_select) + 0: prg_bank_0 <= prg_din; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); + 1: prg_bank_1 <= prg_din; // Select 8 KB PRG ROM bank at $A000-$BFFF + 2: chr_bank_0 <= {1'b0,prg_din[7:1]}; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF); + 3: chr_bank_1 <= {1'b0,prg_din[7:1]}; // Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF); + 4: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); + 5: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); + 6: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); + 7: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); + endcase + end + + 3'b11_0: mirroring <= !prg_din[0]; // Mirroring ($E000-$FFFE) + endcase + end + + if (mapper154) + mirroring <= !prg_din[6]; + if (DxROM || mapper76 || mapper88) + mirroring <= flags[14]; // Hard-wired mirroring + end + else if (regs_7e && prg_write && prg_ain[15:4]==12'h7EF) begin + casez({prg_ain[3:0], mapper82}) + 5'b0000_?: chr_bank_0 <= {1'b0,prg_din[7:1]}; // Select 2 KB CHR bank at PPU $0000-$07FF + 5'b0001_?: chr_bank_1 <= {1'b0,prg_din[7:1]}; // Select 2 KB CHR bank at PPU $0800-$0FFF + 5'b0010_?: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF + 5'b0011_?: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF + 5'b0100_?: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF + 5'b0101_?: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF + 5'b011?_0: {mirroring} <= prg_din[0]; // Select Mirroing + 5'b100?_0: {ram_enable[3], ram_protect[3]} <= {(prg_din==8'hA3),!(prg_din==8'hA3)}; // Enable RAM at $7F00-$7FFF + 5'b0110_1: {chr_a12_invert,mirroring} <= prg_din[1:0]; // Select Mirroing + 5'b0111_1: {ram_enable[0], ram_protect[0]} <= {(prg_din==8'hCA),!(prg_din==8'hCA)}; // Enable RAM at $6000-$67FF + 5'b1000_1: {ram_enable[1], ram_protect[1]} <= {(prg_din==8'h69),!(prg_din==8'h69)}; // Enable RAM at $6F00-$6FFF + 5'b1001_1: {ram_enable[2], ram_protect[2]} <= {(prg_din==8'h84),!(prg_din==8'h84)}; // Enable RAM at $7000-$73FF //Using 6K; Require 5K instead? + 5'b101?_0: prg_bank_0[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF + 5'b110?_0: prg_bank_1[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF + 5'b111?_0: prg_bank_2[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $C000-$DFFF + 5'b1010_1: prg_bank_0[5:0] <= prg_din[7:2]; // Select 8 KB PRG ROM bank at $8000-$9FFF + 5'b1011_1: prg_bank_1[5:0] <= prg_din[7:2]; // Select 8 KB PRG ROM bank at $A000-$BFFF + 5'b1100_1: prg_bank_2[5:0] <= prg_din[7:2]; // Select 8 KB PRG ROM bank at $C000-$DFFF endcase end - - if (mapper154) - mirroring <= !prg_din[6]; - if (DxROM || mapper76 || mapper88) - mirroring <= flags[14]; // Hard-wired mirroring - end - else if (regs_7e && prg_write && prg_ain[15:4]==12'h7EF) begin - casez({prg_ain[3:0], mapper82}) - 5'b0000_?: chr_bank_0 <= {1'b0,prg_din[7:1]}; // Select 2 KB CHR bank at PPU $0000-$07FF - 5'b0001_?: chr_bank_1 <= {1'b0,prg_din[7:1]}; // Select 2 KB CHR bank at PPU $0800-$0FFF - 5'b0010_?: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF - 5'b0011_?: chr_bank_3 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF - 5'b0100_?: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF - 5'b0101_?: chr_bank_5 <= prg_din; // Select 1 KB CHR bank at PPU $1C00-$1FFF - 5'b011?_0: {mirroring} <= prg_din[0]; // Select Mirroing - 5'b100?_0: {ram_enable[3], ram_protect[3]} <= {(prg_din==8'hA3),!(prg_din==8'hA3)}; // Enable RAM at $7F00-$7FFF - 5'b0110_1: {chr_a12_invert,mirroring} <= prg_din[1:0]; // Select Mirroing - 5'b0111_1: {ram_enable[0], ram_protect[0]} <= {(prg_din==8'hCA),!(prg_din==8'hCA)}; // Enable RAM at $6000-$67FF - 5'b1000_1: {ram_enable[1], ram_protect[1]} <= {(prg_din==8'h69),!(prg_din==8'h69)}; // Enable RAM at $6F00-$6FFF - 5'b1001_1: {ram_enable[2], ram_protect[2]} <= {(prg_din==8'h84),!(prg_din==8'h84)}; // Enable RAM at $7000-$73FF //Using 6K; Require 5K instead? - 5'b101?_0: prg_bank_0[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF - 5'b110?_0: prg_bank_1[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF - 5'b111?_0: prg_bank_2[5:0] <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $C000-$DFFF - 5'b1010_1: prg_bank_0[5:0] <= prg_din[7:2]; // Select 8 KB PRG ROM bank at $8000-$9FFF - 5'b1011_1: prg_bank_1[5:0] <= prg_din[7:2]; // Select 8 KB PRG ROM bank at $A000-$BFFF - 5'b1100_1: prg_bank_2[5:0] <= prg_din[7:2]; // Select 8 KB PRG ROM bank at $C000-$DFFF - endcase + + if (mapper268 && prg_write && ({mapper268_5k,prg_ain[15:12]}==5'h6 || {mapper268_5k,prg_ain[15:12]}==5'h15)) begin + if (prg_ain[2:0]==3'h2) begin + m268_reg[2][3:0] <= prg_din[3:0]; + if (!gnrom_lock) + m268_reg[2][7:4] <= prg_din[7:4]; + end else if ((prg_ain[2:1]!=2'b11) && !lockout) begin + m268_reg[prg_ain[2:0]] <= prg_din; + end + end + + // For Mapper 47 + // $6000-7FFF: [.... ...B] Block select + if (prg_write && prg_is_ram) + mapper47_multicart <= prg_din[0]; + + // For Mapper 37 + // $6000-7FFF: [.... .QBB] Block select + if (prg_write && prg_is_ram) + mapper37_multicart <= prg_din[2:0]; + + // Mapper 189 + // $4120-7FFF: [AAAA BBBB] A,B: PRG Reg + if (prg_write && prg_ain[15:14] == 2'b01 && prg_ain[8]) + mapper189_prgsel <= (prg_din[7:4] | prg_din[3:0]); // Select 32 KB PRG ROM bank at $8000-$FFFF end - if (mapper268 && prg_write && ({mapper268_5k,prg_ain[15:12]}==5'h6 || {mapper268_5k,prg_ain[15:12]}==5'h15)) begin - if (prg_ain[2:0]==3'h2) begin - m268_reg[2][3:0] <= prg_din[3:0]; - if (!gnrom_lock) - m268_reg[2][7:4] <= prg_din[7:4]; - end else if ((prg_ain[2:1]!=2'b11) && !lockout) begin - m268_reg[prg_ain[2:0]] <= prg_din; + if (m2_inv) begin // Inverted M2 + irq_reg[6:1] <= irq_reg[5:0]; // 4 cpu cycle delay for mapper 48 + + if (!acclaim) begin // nintendo mapper 'cools down' for 3 inverted M2 cycles + a12_ctr <= (a12_ctr != 0) ? a12_ctr - 4'b0001 : a12_ctr; end end - // For Mapper 47 - // $6000-7FFF: [.... ...B] Block select - if (prg_write && prg_is_ram) - mapper47_multicart <= prg_din[0]; - - // For Mapper 37 - // $6000-7FFF: [.... .QBB] Block select - if (prg_write && prg_is_ram) - mapper37_multicart <= prg_din[2:0]; - - // Mapper 189 - // $4120-7FFF: [AAAA BBBB] A,B: PRG Reg - if (prg_write && prg_ain[15:14] == 2'b01 && prg_ain[8]) - mapper189_prgsel <= (prg_din[7:4] | prg_din[3:0]); // Select 32 KB PRG ROM bank at $8000-$FFFF - - // Trigger IRQ counter on rising edge of chr_ain[12] - // All MMC3A's and non-Sharp MMC3B's will generate only a single IRQ when $C000 is $00. - // This is because this version of the MMC3 generates IRQs when the scanline counter is decremented to 0. - // In addition, writing to $C001 with $C000 still at $00 will result in another single IRQ being generated. - // In the community, this is known as the "alternate" or "old" behavior. - // All MMC3C's and Sharp MMC3B's will generate an IRQ on each scanline while $C000 is $00. - // This is because this version of the MMC3 generates IRQs when the scanline counter is equal to 0. - // In the community, this is known as the "normal" or "new" behavior. - - last_a12 <= chr_ain_o[12]; - if ((acclaim && (!last_a12 && chr_ain_o[12]) && (a12_ctr == 6)) || - (~acclaim && chr_ain_o[12] && (a12_ctr == 0))) begin - counter <= new_counter; - - // MMC Scanline - if ( (!mmc3_alt_behavior || counter != 0 || irq_reload) && new_counter == 0 && irq_enable && irq_support) begin - irq_reg[0] <= 1; + if (~paused) begin + // Trigger IRQ counter on rising edge of chr_ain[12] + // All MMC3A's and non-Sharp MMC3B's will generate only a single IRQ when $C000 is $00. + // This is because this version of the MMC3 generates IRQs when the scanline counter is decremented to 0. + // In addition, writing to $C001 with $C000 still at $00 will result in another single IRQ being generated. + // In the community, this is known as the "alternate" or "old" behavior. + // All MMC3C's and Sharp MMC3B's will generate an IRQ on each scanline while $C000 is $00. + // This is because this version of the MMC3 generates IRQs when the scanline counter is equal to 0. + // In the community, this is known as the "normal" or "new" behavior. + + last_a12 <= chr_ain_o[12]; + if ((acclaim && (!last_a12 && chr_ain_o[12]) && (a12_ctr == 6)) || + (~acclaim && (!last_a12 && chr_ain_o[12]) && (a12_ctr == 0))) begin + counter <= new_counter; + + // MMC Scanline + if ( (!mmc3_alt_behavior || counter != 0 || irq_reload) && new_counter == 0 && irq_enable && irq_support) begin + irq_reg[0] <= 1; + end + irq_reload <= 0; end - irq_reload <= 0; - end - if (acclaim) begin - if (!last_a12 && chr_ain_o[12]) // acclaim mapper counts down 8 pulses, or 16 edges total - a12_ctr <= (a12_ctr != 0) ? a12_ctr - 4'b0001 : 4'b0111; - if (prg_ain == 16'hC001 && prg_write) a12_ctr <= 4'b0111; - end else begin // nintendo mapper 'cools down' for 16 low cycles - a12_ctr <= chr_ain_o[12] ? 4'b1111 : (a12_ctr != 0) ? a12_ctr - 4'b0001 : a12_ctr; + if (acclaim) begin + if (!last_a12 && chr_ain_o[12]) // acclaim mapper counts down 8 pulses, or 16 edges total + a12_ctr <= (a12_ctr != 0) ? a12_ctr - 4'b0001 : 4'b0111; + if (prg_ain == 16'hC001 && prg_write) a12_ctr <= 4'b0111; + end else if (chr_ain_o[12]) // Nintendo mapper cooldown resets on a12 + a12_ctr <= 4'b0011; end end @@ -820,7 +832,9 @@ module Mapper165( input [15:0] audio_in, // Inverted audio from APU inout [15:0] audio_b, // Mixed audio output inout [15:0] flags_out_b, // flags {0, 0, 0, 0, has_savestate, prg_conflict, prg_bus_write, has_chr_dout} - input [13:0] chr_ain_o + input [13:0] chr_ain_o, + input m2_inv, + input paused ); assign prg_aout_b = enable ? prg_aout : 22'hZ; @@ -859,6 +873,7 @@ reg latch_0, latch_1; wire [7:0] new_counter = (counter == 0 || irq_reload) ? irq_latch : counter - 1'd1; reg [3:0] a12_ctr; +reg last_a12 = 0; always @(posedge clk) if (~enable) begin @@ -873,50 +888,56 @@ if (~enable) begin {chr_bank_0, chr_bank_1, chr_bank_2, chr_bank_4} <= 0; {prg_bank_0, prg_bank_1} <= 0; a12_ctr <= 0; -end else if (ce) begin - if (prg_write && prg_ain[15]) begin - case({prg_ain[14], prg_ain[13], prg_ain[0]}) - 3'b00_0: {chr_a12_invert, prg_rom_bank_mode, bank_select} <= {prg_din[7], prg_din[6], prg_din[2:0]}; // Bank select ($8000-$9FFE, even) - 3'b00_1: begin // Bank data ($8001-$9FFF, odd) - case (bank_select) - 0: chr_bank_0 <= {prg_din[7:1], 1'b0}; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF); - 1: chr_bank_1 <= {prg_din[7:1], 1'b0}; // Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF); - 2: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); - 3: ; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); - 4: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); - 5: ; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); - 6: prg_bank_0 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); - 7: prg_bank_1 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF - endcase - end - 3'b01_0: mirroring <= prg_din[0]; // Mirroring ($A000-$BFFE, even) - 3'b01_1: {ram_enable, ram_protect} <= prg_din[7:6]; // PRG RAM protect ($A001-$BFFF, odd) - 3'b10_0: irq_latch <= prg_din; // IRQ latch ($C000-$DFFE, even) - 3'b10_1: irq_reload <= 1; // IRQ reload ($C001-$DFFF, odd) - 3'b11_0: begin irq_enable <= 0; irq <= 0; end // IRQ disable ($E000-$FFFE, even) - 3'b11_1: irq_enable <= 1; // IRQ enable ($E001-$FFFF, odd) - endcase + last_a12 <= 0; +end else begin + if (ce) begin + if (prg_write && prg_ain[15]) begin + case({prg_ain[14], prg_ain[13], prg_ain[0]}) + 3'b00_0: {chr_a12_invert, prg_rom_bank_mode, bank_select} <= {prg_din[7], prg_din[6], prg_din[2:0]}; // Bank select ($8000-$9FFE, even) + 3'b00_1: begin // Bank data ($8001-$9FFF, odd) + case (bank_select) + 0: chr_bank_0 <= {prg_din[7:1], 1'b0}; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF); + 1: chr_bank_1 <= {prg_din[7:1], 1'b0}; // Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF); + 2: chr_bank_2 <= prg_din; // Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); + 3: ; // Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); + 4: chr_bank_4 <= prg_din; // Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); + 5: ; // Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); + 6: prg_bank_0 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF); + 7: prg_bank_1 <= prg_din[5:0]; // Select 8 KB PRG ROM bank at $A000-$BFFF + endcase + end + 3'b01_0: mirroring <= prg_din[0]; // Mirroring ($A000-$BFFE, even) + 3'b01_1: {ram_enable, ram_protect} <= prg_din[7:6]; // PRG RAM protect ($A001-$BFFF, odd) + 3'b10_0: irq_latch <= prg_din; // IRQ latch ($C000-$DFFE, even) + 3'b10_1: irq_reload <= 1; // IRQ reload ($C001-$DFFF, odd) + 3'b11_0: begin irq_enable <= 0; irq <= 0; end // IRQ disable ($E000-$FFFE, even) + 3'b11_1: irq_enable <= 1; // IRQ enable ($E001-$FFFF, odd) + endcase + end end - // Trigger IRQ counter on rising edge of chr_ain[12] - // All MMC3A's and non-Sharp MMC3B's will generate only a single IRQ when $C000 is $00. - // This is because this version of the MMC3 generates IRQs when the scanline counter is decremented to 0. - // In addition, writing to $C001 with $C000 still at $00 will result in another single IRQ being generated. - // In the community, this is known as the "alternate" or "old" behavior. - // All MMC3C's and Sharp MMC3B's will generate an IRQ on each scanline while $C000 is $00. - // This is because this version of the MMC3 generates IRQs when the scanline counter is equal to 0. - // In the community, this is known as the "normal" or "new" behavior. - if (chr_ain_o[12] && a12_ctr == 0) begin - counter <= new_counter; - - if ((counter != 0 || irq_reload) && new_counter == 0 && irq_enable) begin - irq <= 1; + if (m2_inv) begin // Inverted M2 + // nintendo mapper 'cools down' for 3 inverted M2 cycles + a12_ctr <= (a12_ctr != 0) ? a12_ctr - 4'b0001 : a12_ctr; + end + + if (~paused) begin + // Trigger IRQ counter on rising edge of chr_ain[12] + + last_a12 <= chr_ain_o[12]; + if ((!last_a12 && chr_ain_o[12]) && (a12_ctr == 0)) begin + counter <= new_counter; + + // MMC Scanline + if ( (counter != 0 || irq_reload) && new_counter == 0 && irq_enable) begin + irq <= 1; + end + irq_reload <= 0; end - irq_reload <= 0; + if (chr_ain_o[12]) // Nintendo mapper cooldown resets on a12 + a12_ctr <= 4'b0011; end - - a12_ctr <= chr_ain_o[12] ? 4'b1111 : (a12_ctr != 0) ? a12_ctr - 4'b0001 : a12_ctr; end // The PRG bank to load. Each increment here is 8kb. So valid values are 0..63. @@ -993,6 +1014,8 @@ module Mapper413 ( inout [15:0] audio_b, // Mixed audio output inout [15:0] flags_out_b, // flags {0, 0, 0, 0, has_savestate, prg_conflict, prg_bus_write, has_chr_dout} input [13:0] chr_ain_o, + input m2_inv, + input paused, output [2:0] prg_aoute // Extended prg address out bits ); @@ -1023,6 +1046,7 @@ assign irq = irq_reg[0]; wire [7:0] new_counter = (counter == 0 || irq_reload) ? irq_latch : counter - 1'd1; reg [3:0] a12_ctr; +reg last_a12 = 0; reg misc_inc; reg old_misc_inc; @@ -1047,44 +1071,52 @@ if (~enable) begin misc_inc <= 0; old_misc_inc <= 0; a12_ctr <= 0; -end else if (ce) begin - irq_reg[4:1] <= irq_reg[3:0]; // 4 cycle delay - if (prg_write && prg_ain[15]) begin - casez(prg_ain[14:12]) - 3'b000: irq_latch <= prg_din; // IRQ latch $8000-8FFF (mmc3=$C000-$DFFE, even) - 3'b001: irq_reload <= 1; // IRQ reload $9000-9FFF (mmc3=$C001-$DFFF, odd) - 3'b010: begin irq_enable <= 0; irq_reg[0] <= 0; end// IRQ disable $A000-AFFF (mmc3=$E000-$FFFE, even) - 3'b011: irq_enable <= 1; // IRQ enable $B000-BFFF (mmc3=$E001-$FFFF, odd) - 3'b100: prg_amisc <= {prg_amisc[21:0], prg_din[7]};// Misc Address (shift left 1, insert MSB) - 3'b101: misc_ctrl <= prg_din[1]; // Misc Control (& 0x2) - 3'b11?: bank_reg[prg_din[7:6]] <= prg_din[5:0]; // Bank select din[7:6] ($E000-$EFFE) - endcase + last_a12 <= 0; +end else begin + if (ce) begin + if (prg_write && prg_ain[15]) begin + casez(prg_ain[14:12]) + 3'b000: irq_latch <= prg_din; // IRQ latch $8000-8FFF (mmc3=$C000-$DFFE, even) + 3'b001: irq_reload <= 1; // IRQ reload $9000-9FFF (mmc3=$C001-$DFFF, odd) + 3'b010: begin irq_enable <= 0; irq_reg[0] <= 0; end// IRQ disable $A000-AFFF (mmc3=$E000-$FFFE, even) + 3'b011: irq_enable <= 1; // IRQ enable $B000-BFFF (mmc3=$E001-$FFFF, odd) + 3'b100: prg_amisc <= {prg_amisc[21:0], prg_din[7]};// Misc Address (shift left 1, insert MSB) + 3'b101: misc_ctrl <= prg_din[1]; // Misc Control (& 0x2) + 3'b11?: bank_reg[prg_din[7:6]] <= prg_din[5:0]; // Bank select din[7:6] ($E000-$EFFE) + endcase + end + + misc_inc <= 0; + old_misc_inc <= misc_inc; + if (prg_read && prg_is_misc) + misc_inc <= 1; + if (old_misc_inc && !misc_inc && misc_ctrl) + prg_amisc <= prg_amisc + 23'd1; end - misc_inc <= 0; - old_misc_inc <= misc_inc; - if (prg_read && prg_is_misc) - misc_inc <= 1; - if (old_misc_inc && !misc_inc && misc_ctrl) - prg_amisc <= prg_amisc + 23'd1; - - // Trigger IRQ counter on rising edge of chr_ain[12] - // All MMC3C's and Sharp MMC3B's will generate an IRQ on each scanline while $C000 is $00. - // This is because this version of the MMC3 generates IRQs when the scanline counter is equal to 0. - // In the community, this is known as the "normal" or "new" behavior. - - if (chr_ain_o[12] && (a12_ctr == 0)) begin - counter <= new_counter; - - // MMC Scanline - if (new_counter == 0 && irq_enable) begin - irq_reg[0] <= 1; - end - irq_reload <= 0; + if (m2_inv) begin // Inverted M2 + // nintendo mapper 'cools down' for 3 inverted M2 cycles + a12_ctr <= (a12_ctr != 0) ? a12_ctr - 4'b0001 : a12_ctr; + irq_reg[4:1] <= irq_reg[3:0]; // 1 cpu cycle delay ??? what is this for end - // nintendo mapper 'cools down' for 16 low cycles - a12_ctr <= chr_ain_o[12] ? 4'b1111 : (a12_ctr != 0) ? a12_ctr - 4'b0001 : a12_ctr; + if (~paused) begin + // Trigger IRQ counter on rising edge of chr_ain[12] + + last_a12 <= chr_ain_o[12]; + if ((!last_a12 && chr_ain_o[12]) && (a12_ctr == 0)) begin + counter <= new_counter; + + // MMC Scanline + if ( (counter != 0 || irq_reload) && new_counter == 0 && irq_enable) begin + irq_reg[0] <= 1; + end + irq_reload <= 0; + end + + if (chr_ain_o[12]) // Nintendo mapper cooldown resets on a12 + a12_ctr <= 4'b0011; + end end reg [5:0] prgsel; diff --git a/rtl/mappers/MMC5.sv b/rtl/mappers/MMC5.sv index a649107..57dc786 100644 --- a/rtl/mappers/MMC5.sv +++ b/rtl/mappers/MMC5.sv @@ -28,7 +28,7 @@ module MMC5( input [7:0] chr_din, // CHR Data in input chr_write, // CHR Write inout [7:0] chr_dout_b, // chr data (non standard) - input ppu_ce, + input paused, // savestates input [63:0] SaveStateBus_Din, input [ 9:0] SaveStateBus_Adr, @@ -217,7 +217,7 @@ always @(posedge clk) begin // Mode 2 - Readable and writable // Mode 3 - Read-only if (extended_ram_mode != 3) begin - if (ppu_ce && !ppu_in_frame && !extended_ram_mode[1] && chr_write && (mirrbits == 2) && chr_ain[13]) begin + if (~paused && !ppu_in_frame && !extended_ram_mode[1] && chr_write && (mirrbits == 2) && chr_ain[13]) begin ram_addrA <= chr_ain[9:0]; ram_dataA <= chr_din; ram_wrenA <= 1'b1; diff --git a/rtl/mappers/VRC.sv b/rtl/mappers/VRC.sv index 1eb4ae5..b0a0ebc 100644 --- a/rtl/mappers/VRC.sv +++ b/rtl/mappers/VRC.sv @@ -1313,7 +1313,7 @@ module VRC5( input [7:0] chr_din, // CHR Data in input chr_write, // CHR Write inout [7:0] chr_dout_b, // chr data (non standard) - input ppu_ce, + input paused, // savestates input [63:0] SaveStateBus_Din, input [ 9:0] SaveStateBus_Adr, @@ -1439,7 +1439,7 @@ always @(posedge clk) begin end end - if (ppu_ce && chr_read && (chr_ain[13:12] == 2'b10) && (~&chr_ain[9:6])) begin + if (~paused && chr_read && (chr_ain[13:12] == 2'b10) && (~&chr_ain[9:6])) begin qtram_read_addr <= {vram_a10,chr_ain[9:0]}; end end diff --git a/rtl/mappers/misc.sv b/rtl/mappers/misc.sv index 23b75c5..71420ef 100644 --- a/rtl/mappers/misc.sv +++ b/rtl/mappers/misc.sv @@ -1755,8 +1755,7 @@ module Nanjing( input [15:0] audio_in, // Inverted audio from APU inout [15:0] audio_b, // Mixed audio output inout [15:0] flags_out_b, // flags {0, 0, 0, 0, has_savestate, prg_conflict, prg_bus_write, has_chr_dout} - input [19:0] ppuflags, - input ppu_ce + input paused ); assign prg_aout_b = enable ? prg_aout : 22'hZ; @@ -1787,8 +1786,7 @@ reg trig_comp; reg [7:0] security[4]; -wire [8:0] scanline = ppuflags[19:11]; -wire [8:0] cycle = ppuflags[10:2]; +reg old_a13; always @(posedge clk) begin if (~enable) begin @@ -1797,50 +1795,52 @@ always @(posedge clk) begin security <= '{8'h00, 8'h00, 8'h00, 8'h00}; chr_switch <= 0; trig_comp <= 1; // Initial value 1 - end else if (ce) begin - prg_dout <= prg_din; - prg_bus_write <= 0; - if (prg_write) begin - if (prg_ain == 16'h5101) begin - if (trig_comp && ~|prg_din) - trigger <= ~trigger; - trig_comp <= |prg_din; - end else begin - case (prg_ain & 16'h7300) - // If the most significant bit of this register is set, it does automatic CHR RAM switching - 'h5000: begin - prg_bank[3:0] <= prg_din[3:0]; - chr_switch <= prg_din[7]; - security[0] <= prg_din; - end - - 'h5100: begin - security[1] <= prg_din; - if (prg_din == 6) - prg_bank <= 8'h3; - end - - 'h5200: begin - prg_bank[7:4] <= prg_din[3:0]; - security[2] <= prg_din; + old_a13 <= 0; + end else begin + if (ce) begin + prg_dout <= prg_din; + prg_bus_write <= 0; + if (prg_write) begin + if (prg_ain == 16'h5101) begin + if (trig_comp && ~|prg_din) + trigger <= ~trigger; + trig_comp <= |prg_din; + end else begin + case (prg_ain & 16'h7300) + // If the most significant bit of this register is set, it does automatic CHR RAM switching + 'h5000: begin + prg_bank[3:0] <= prg_din[3:0]; + chr_switch <= prg_din[7]; + security[0] <= prg_din; + end + + 'h5100: begin + security[1] <= prg_din; + if (prg_din == 6) + prg_bank <= 8'h3; + end + + 'h5200: begin + prg_bank[7:4] <= prg_din[3:0]; + security[2] <= prg_din; + end + + 'h5300: security[3] <= prg_din; + endcase + end + end else if (prg_read) begin // Security stuff as Mesen does it + prg_bus_write <= 1'b1; + case (prg_ain & 16'h7700) + 'h5100: prg_dout <= security[0] | security[1] | security[3] | (security[2] ^ 8'hFF); + 'h5500: prg_dout <= trigger ? (security[3] | security[0]) : 8'h0; + default: begin + prg_dout <= 8'hFF; + prg_bus_write <= 0; end - - 'h5300: security[3] <= prg_din; endcase end - end else if (prg_read) begin // Security stuff as Mesen does it - prg_bus_write <= 1'b1; - case (prg_ain & 16'h7700) - 'h5100: prg_dout <= security[0] | security[1] | security[3] | (security[2] ^ 8'hFF); - 'h5500: prg_dout <= trigger ? (security[3] | security[0]) : 8'h0; - default: begin - prg_dout <= 8'hFF; - prg_bus_write <= 0; - end - endcase end end - // The exact way this works is unknown but is conjectured // to resemble iNES Mapper 096, latching PA9 at start of nametable reads. // When turned on, both 4K CHR RAM banks 0000-0FFF and 1000-1FFF map to 0000-0FFF @@ -1848,13 +1848,11 @@ always @(posedge clk) begin // point to 1000-1FFF. if(~enable) begin chr_bank <= 0; - end else if (ppu_ce) begin - if (cycle > 254) begin - if (scanline == 239) - chr_bank <= 0; - else if(scanline == 127) - chr_bank <= 1; - end + end else if (~paused) begin + + old_a13 <= chr_ain[13]; + if (~old_a13 && chr_ain[13]) + chr_bank <= chr_ain[9]; end end diff --git a/rtl/nes.v b/rtl/nes.v index c3479c2..31e151c 100644 --- a/rtl/nes.v +++ b/rtl/nes.v @@ -545,7 +545,6 @@ wire chr_read, chr_write, chr_read_ex; // If PPU reads/writes from VRAM wire [13:0] chr_addr, chr_addr_ex; // Address PPU accesses in VRAM wire [7:0] chr_from_ppu; // Data from PPU to VRAM wire [7:0] chr_to_ppu; -wire [19:0] mapper_ppu_flags; // PPU flags for mapper cheating wire [8:0] ppu_cycle; wire [8:0] scanline_ppu; assign cycle = use_fake_h ? 9'd340 : (corepause_active) ? cycle_paused : ppu_cycle; @@ -572,7 +571,6 @@ PPU ppu( .vram_dout (chr_from_ppu), .scanline (scanline_ppu), .cycle (ppu_cycle), - .mapper_ppu_flags (mapper_ppu_flags), .emphasis (emphasis), .short_frame (skip_pixel), .extra_sprites (ex_sprites), @@ -618,8 +616,10 @@ cart_top multi_mapper ( .clk (clk), .reset (reset_noSS), .flags (mapper_flags), // iNES header data (use 0 while loading) + .paused (freeze_clocks), // Cart pins (slightly abstracted) .ce (cart_ce & ~reset_noSS), // M2 (held in high impedance during reset) + .cpu_ce (cpu_ce), // Serves as M2 Inverted .prg_ain (prg_addr), // CPU Address in (a15 abstracted from ROMSEL) .prg_read (prg_read), // CPU RnW split .prg_write (prg_write), // CPU RnW split @@ -652,8 +652,6 @@ cart_top multi_mapper ( .mapper_ovr (bram_override), // Cheats .prg_from_ram (from_data_bus), // Hacky cpu din <= get rid of this! - .ppuflags (mapper_ppu_flags), // Cheat for MMC5 - .ppu_ce (ppu_ce), // PPU Clock (cheat for MMC5/2/4) // Behavior helper flags .has_chr_dout (has_chr_from_ppu_mapper), // Output specific data for CHR rather than from SDRAM .prg_bus_write (prg_bus_write), // PRG data driven to bus diff --git a/rtl/ppu.sv b/rtl/ppu.sv index ae7ca33..236a858 100644 --- a/rtl/ppu.sv +++ b/rtl/ppu.sv @@ -1084,7 +1084,6 @@ module PPU( output [7:0] vram_dout, output [8:0] scanline, output [8:0] cycle, - output [19:0] mapper_ppu_flags, output reg [2:0] emphasis, output short_frame, input extra_sprites, @@ -1392,8 +1391,9 @@ always_comb begin vram_r_ex = use_ex && extra_sprites; else vram_r_ex = 0; - - if (cycle[2:1] == 0 || at_last_cycle_group) + if (cycle == 340) + vram_a = {1'b0, bg_patt, bg_name_table, cycle[1], loopy[14:12]}; // Pattern table override + else if (cycle[2:1] == 0 || at_last_cycle_group) vram_a = {2'b10, loopy[11:0]}; // Name Table else if (cycle[2:1] == 1) vram_a = {2'b10, loopy[11:10], 4'b1111, loopy[9:7], loopy[4:2]}; // Attribute table @@ -1611,7 +1611,4 @@ end assign dout = latched_dout; - -assign mapper_ppu_flags = {scanline, cycle, obj_size, is_rendering}; - endmodule // PPU \ No newline at end of file