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:
@@ -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};
|
||||
|
||||
Reference in New Issue
Block a user