1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-01-26 03:41:46 +00:00

[NES] Add Mapper165 (not fonctional)

This commit is contained in:
Sebastien Delestaing
2016-10-12 09:58:47 +02:00
parent 84d5cf3535
commit 22ec029324

View File

@@ -291,17 +291,13 @@ module MMC3(input clk, input ce, input reset,
// The alternative behavior has slightly different IRQ counter semantics.
wire mmc3_alt_behavior = 0;
// TQROM maps 8kB CHR RAM
wire TQROM = (flags[7:0] == 119);
wire TxSROM = (flags[7:0] == 118); // Connects CHR A17 to CIRAM A10
wire TQROM = (flags[7:0] == 119); // TQROM maps 8kB CHR RAM
wire TxSROM = (flags[7:0] == 118); // Connects CHR A17 to CIRAM A10
wire mapper47 = (flags[7:0] == 47); // Mapper 47 is a multicart that has 128k for each game. It has no RAM.
wire DxROM = (flags[7:0] == 206);
wire four_screen_mirroring = flags[16] | DxROM;
// Mapper 47 is a multicart that has 128k for each game. It has no RAM.
wire mapper47 = (flags[7:0] == 47);
reg mapper47_multicart;
wire [7:0] new_counter = (counter == 0 || irq_reload) ? irq_latch : counter - 1;
reg [3:0] a12_ctr;
@@ -1543,8 +1539,6 @@ module Mapper68(input clk, input ce, input reset,
endmodule
// 69 - Sunsoft FME-7
module Mapper69(input clk, input ce, input reset,
input [31:0] flags,
@@ -1771,6 +1765,135 @@ module NesEvent(input clk, input ce, input reset,
assign chr_aout = {9'b10_0000_000, chr_ain[12:0]};
endmodule
// mapper 165
module Mapper165(input clk, input ce, input reset,
input [31:0] flags,
input [15:0] prg_ain, output [21:0] prg_aout,
input prg_read, prg_write, // Read / write signals
input [7:0] prg_din,
output prg_allow, // Enable access to memory for the specified operation.
input chr_read, input [13:0] chr_ain, output [21:0] chr_aout,
output chr_allow, // Allow write
output vram_a10, // Value for A10 address line
output vram_ce, // True if the address should be routed to the internal 2kB VRAM.
output reg irq);
reg [2:0] bank_select; // Register to write to next
reg prg_rom_bank_mode; // Mode for PRG banking
reg chr_a12_invert; // Mode for CHR banking
reg mirroring; // 0 = vertical, 1 = horizontal
reg irq_enable, irq_reload; // IRQ enabled, and IRQ reload requested
reg [7:0] irq_latch, counter; // IRQ latch value and current counter
reg ram_enable, ram_protect; // RAM protection bits
reg [5:0] prg_bank_0, prg_bank_1; // Selected PRG banks
wire prg_is_ram;
reg [6:0] chr_bank_0, chr_bank_1; // Selected CHR banks
reg [7:0] chr_bank_2, chr_bank_3, chr_bank_4, chr_bank_5;
reg latch_0, latch_1;
wire [7:0] new_counter = (counter == 0 || irq_reload) ? irq_latch : counter - 1;
reg [3:0] a12_ctr;
always @(posedge clk) if (reset) begin
irq <= 0;
bank_select <= 0;
prg_rom_bank_mode <= 0;
chr_a12_invert <= 0;
mirroring <= flags[14];
{irq_enable, irq_reload} <= 0;
{irq_latch, counter} <= 0;
{ram_enable, ram_protect} <= 0;
{chr_bank_0, chr_bank_1, chr_bank_2, chr_bank_3, chr_bank_4, chr_bank_5} <= 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]; // Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF);
1: chr_bank_1 <= prg_din[7:1]; // 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[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
// 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[12] && a12_ctr == 0) begin
counter <= new_counter;
if ( (counter != 0 || irq_reload) && new_counter == 0 && irq_enable) begin
// $write("MMC3 SCANLINE IRQ!\n");
irq <= 1;
end
irq_reload <= 0;
end
a12_ctr <= chr_ain[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.
reg [5:0] prgsel;
always @* begin
casez({prg_ain[14:13], prg_rom_bank_mode})
3'b00_0: prgsel = prg_bank_0; // $8000 mode 0
3'b00_1: prgsel = 6'b111110; // $8000 fixed to second last bank
3'b01_?: prgsel = prg_bank_1; // $A000 mode 0,1
3'b10_0: prgsel = 6'b111110; // $C000 fixed to second last bank
3'b10_1: prgsel = prg_bank_0; // $C000 mode 1
3'b11_?: prgsel = 6'b111111; // $E000 fixed to last bank
endcase
end
wire [21:0] prg_aout_tmp = {3'b00_0, prgsel, prg_ain[12:0]};
// PPU reads $0FD0: latch 0 is set to $FD for subsequent reads
// PPU reads $0FE0: latch 0 is set to $FE for subsequent reads
// PPU reads $1FD0 through $1FDF: latch 1 is set to $FD for subsequent reads
// PPU reads $1FE0 through $1FEF: latch 1 is set to $FE for subsequent reads
always @(posedge clk) if (ce && chr_read) begin
latch_0 <= (chr_ain & 14'h3fff) == 14'h0fd0 ? 0 : (chr_ain & 14'h3fff) == 14'h0fe0 ? 1 : latch_0;
latch_1 <= (chr_ain & 14'h3ff0) == 14'h1fd0 ? 0 : (chr_ain & 14'h3ff0) == 14'h1fe0 ? 1 : latch_1;
end
// The CHR bank to load. Each increment here is 1kb. So valid values are 0..255.
reg [7:0] chrsel;
always @* begin
casez({chr_ain[12] ^ chr_a12_invert, latch_0, latch_1})
3'b0_0?: chrsel = {chr_bank_0, chr_ain[10]}; // 2Kb page
3'b0_1?: chrsel = {chr_bank_1, chr_ain[10]}; // 2Kb page
3'b1_?0: chrsel = chr_bank_2;
3'b1_?1: chrsel = chr_bank_4;
endcase
end
assign {chr_allow, chr_aout} = {flags[15] && (chrsel < 4), 4'b10_00, chrsel, chr_ain[9:0]};
assign prg_is_ram = prg_ain >= 'h6000 && prg_ain < 'h8000 && ram_enable && !(ram_protect && prg_write);
assign prg_allow = prg_ain[15] && !prg_write || prg_is_ram;
wire [21:0] prg_ram = {9'b11_1100_000, prg_ain[12:0]};
assign prg_aout = prg_is_ram ? prg_ram : prg_aout_tmp;
assign vram_a10 = mirroring ? chr_ain[11] : chr_ain[10];
assign vram_ce = chr_ain[13];
endmodule
// iNES Mapper 228 represents the board used by Active Enterprises for Action 52 and Cheetahmen II.
module Mapper228(input clk, input ce, input reset,
@@ -1957,6 +2080,10 @@ module MultiMapper(input clk, input ce, input ppu_ce, input reset,
Mapper79 map79(clk, ce, reset, flags, prg_ain, map79_prg_addr, prg_read, prg_write, prg_din, map79_prg_allow,
chr_ain, map79_chr_addr, map79_chr_allow, map79_vram_a10, map79_vram_ce);
wire map165_prg_allow, map165_vram_a10, map165_vram_ce, map165_chr_allow, map165_irq;
wire [21:0] map165_prg_addr, map165_chr_addr;
Mapper165 map165(clk, ppu_ce, reset, flags, prg_ain, map165_prg_addr, prg_read, prg_write, prg_din, map165_prg_allow,
chr_read, chr_ain, map165_chr_addr, map165_chr_allow, map165_vram_a10, map165_vram_ce, map165_irq);
wire map228_prg_allow, map228_vram_a10, map228_vram_ce, map228_chr_allow;
wire [21:0] map228_prg_addr, map228_chr_addr;
@@ -2020,7 +2147,7 @@ module MultiMapper(input clk, input ce, input ppu_ce, input reset,
// 11 = Working
// 13 = Working
// 15 = Working
// 16 = in progress
// 16 = Working minus EEPROM support
// 28 = Working
// 34 = Working
// 41 = Working
@@ -2037,6 +2164,7 @@ module MultiMapper(input clk, input ce, input ppu_ce, input reset,
// 118 = Working
// 119 = Working
// 158 = Tons of GFX bugs
// 165 = GFX corrupted
// 209 = Not Tested
// 228 = Working
// 234 = Not Tested
@@ -2085,6 +2213,8 @@ module MultiMapper(input clk, input ce, input ppu_ce, input reset,
105: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, irq}= {nesev_prg_addr, mmc1_prg_allow, nesev_chr_addr, mmc1_vram_a10, mmc1_vram_ce, mmc1_chr_allow, nesev_irq};
165: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow, irq} = {map165_prg_addr, map165_prg_allow, map165_chr_addr, map165_vram_a10, map165_vram_ce, map165_chr_allow, map165_irq};
228: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map228_prg_addr, map228_prg_allow, map228_chr_addr, map228_vram_a10, map228_vram_ce, map228_chr_allow};
234: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {map234_prg_addr, map234_prg_allow, map234_chr_addr, map234_vram_a10, map234_vram_ce, map234_chr_allow};
default: {prg_aout, prg_allow, chr_aout, vram_a10, vram_ce, chr_allow} = {mmc0_prg_addr, mmc0_prg_allow, mmc0_chr_addr, mmc0_vram_a10, mmc0_vram_ce, mmc0_chr_allow};