1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-05 07:34:41 +00:00

NES: Add mapper83, small fix for mapper 153

Author: Cray Elliott <MP2E@archlinux.us>
This commit is contained in:
Gyorgy Szombathelyi
2020-02-18 13:39:11 +01:00
parent 8fa561da55
commit 8a028f21e2

View File

@@ -285,7 +285,7 @@ wire [7:0] ram_addr;
wire ram_read;
assign mapper_addr[17:8] = 0;
assign mapper_addr[7:0] = ram_addr;
assign mapper_ovr = 1'b1;
assign mapper_ovr = mapper159 || submapper5;
EEPROM_24C0x eeprom(
.type_24C01(mapper159), //24C01 is 128 bytes, 24C02 is 256 bytes
@@ -1792,7 +1792,6 @@ wire [7:0] prg_dout;
wire prg_allow, chr_allow;
wire vram_ce, vram_a10;
wire [15:0] audio = audio_in;
wire [18:15] ramprgaout;
wire irq;
reg [15:0] flags_out = 0;
@@ -1824,3 +1823,215 @@ assign vram_ce = 1'b0;
assign irq = 1'b0;
endmodule
// 83 Cony/Yoko - Unlicensed fighting game bootlegs
// Street Fighter II Pro, Fatal Fury 2, World Heroes 2
module Mapper83(
input clk, // System clock
input ce, // M2 ~cpu_clk
input enable, // Mapper enabled
input [31:0] flags, // Cart flags
input [15:0] prg_ain, // prg address
inout [21:0] prg_aout_b, // prg address out
input prg_read, // prg read
input prg_write, // prg write
input [7:0] prg_din, // prg data in
inout [7:0] prg_dout_b, // prg data out
inout prg_allow_b, // Enable access to memory for the specified operation.
input [13:0] chr_ain, // chr address in
inout [21:0] chr_aout_b, // chr address out
input chr_read, // chr ram read
inout chr_allow_b, // chr allow write
inout vram_a10_b, // Value for A10 address line
inout vram_ce_b, // True if the address should be routed to the internal 2kB VRAM.
inout irq_b, // IRQ
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, 0, prg_conflict, prg_bus_write, has_chr_dout}
);
assign prg_aout_b = enable ? prg_aout : 22'hZ;
assign prg_dout_b = enable ? prg_dout : 8'hZ;
assign prg_allow_b = enable ? prg_allow : 1'hZ;
assign chr_aout_b = enable ? chr_aout : 22'hZ;
assign chr_allow_b = enable ? chr_allow : 1'hZ;
assign vram_a10_b = enable ? vram_a10 : 1'hZ;
assign vram_ce_b = enable ? vram_ce : 1'hZ;
assign irq_b = enable ? irq : 1'hZ;
assign flags_out_b = enable ? flags_out : 16'hZ;
assign audio_b = enable ? audio : 16'hZ;
wire [21:0] prg_aout, chr_aout;
reg [7:0] prg_dout;
wire prg_allow, chr_allow;
wire vram_ce, vram_a10;
wire [15:0] audio = audio_in;
wire [15:0] flags_out = {14'h0, prg_bus_write, 1'h0};
wire prg_bus_write;
wire submapper1 = flags[21];
wire submapper2 = flags[22];
// mode register bits
reg [1:0] prgbank_mode; // determines PRG banking mode
reg [1:0] mirroring;
reg prg_reg3_enable; // if 1, maps 8 KiB PRG bank to 0x6000-0x7FFF for submapper 0 and 1
reg irq_mode, irq_latch;
reg irq;
reg irq_enable;
reg [15:0] irq_counter;
reg [4:0] prgbank_reg[3:0];
reg [3:0] prgbank_reg4;
reg [7:0] chrbank_reg[7:0];
reg [1:0] dipswitch; // alters title screen, wrong dipswitch can result in garbled graphics
reg [7:0] scratch_ram[3:0];
// Submapper 2 only
// outer 256 KiB PRG/CHR-ROM bank
reg [1:0] outer_bank;
// select 8 KiB WRAM bank
reg [1:0] wrambank;
always@(posedge clk) begin
if (~enable) begin
{irq, irq_mode, irq_latch, irq_enable, irq_counter} <= 0;
{prg_reg3_enable, prgbank_mode, mirroring} <= 0;
outer_bank <= 0;
wrambank <= 0;
dipswitch <= 0;
chrbank_reg <= '{default:0};
prgbank_reg <= '{default:0};
prgbank_reg4 <= 0;
scratch_ram <= '{default:0};
end else if(ce) begin
if (prg_write) begin
casez(prg_ain[15:8])
8'b1???_??00 : begin
{wrambank, outer_bank} <= prg_din[7:4];
{prgbank_reg4} <= prg_din[3:0];
end
8'b1???_??01 : begin
{irq_latch, irq_mode, prg_reg3_enable, prgbank_mode} <= prg_din[7:3];
mirroring <= prg_din[1:0];
end
8'b1???_??10 : begin
if (prg_ain[0]) begin
irq_counter[15:8] <= prg_din;
irq_enable <= irq_latch;
end else begin
irq_counter[7:0] <= prg_din;
irq <= 1'b0; // IRQ ACK
end
end
8'b1???_??11 : begin
if (prg_ain[4]) begin
if (!prg_ain[3])
chrbank_reg[prg_ain[2:0]] <= prg_din;
end else
prgbank_reg[prg_ain[1:0]] <= prg_din[4:0];
end
8'b0101_???? : begin
if (|prg_ain[11:8])
scratch_ram[prg_ain[1:0]] <= prg_din;
end
endcase
end
if (irq_enable) begin
if (irq_mode)
irq_counter <= irq_counter - 16'd1;
else
irq_counter <= irq_counter + 16'd1;
end
if (irq_enable && (irq_counter == 16'h0000)) begin
irq <= 1'b1;
irq_enable <= 1'b0;
end
end
end
always_comb begin
// mirroring
casez(mirroring[1:0])
2'b00: vram_a10 = {chr_ain[10]}; // vertical
2'b01: vram_a10 = {chr_ain[11]}; // horizontal
2'b1?: vram_a10 = {mirroring[0]}; // single screen
endcase
end
// PRG address space mapping
reg [4:0] prgsel;
always_comb begin
casez ({prgbank_mode, prg_ain[15:13]})
// mode 0
5'b00_10? : prgsel = {prgbank_reg4, prg_ain[13]}; // 0x8000-0xBFFF
5'b00_11? : prgsel = {4'b1111, prg_ain[13]}; // 0xC000-0xFFFF
// mode 1
5'b01_1?? : prgsel = {prgbank_reg4[3:1], prg_ain[14:13]}; // 0x8000-0xFFFF
// mode 2 and 3
5'b1?_100 : prgsel = prgbank_reg[0]; // 0x8000-0x9FFF
5'b1?_101 : prgsel = prgbank_reg[1]; // 0xA000-0xBFFF
5'b1?_110 : prgsel = prgbank_reg[2]; // 0xC000-0xDFFF
5'b1?_111 : prgsel = 5'b11_111; // 0xE000-0xFFFF
// all modes
5'b??_011 : prgsel = prgbank_reg[3]; // 0x6000-0x7FFF
default : prgsel = {2'd0, prg_ain[15:13]};
endcase
end
// CHR address space mapping
reg [9:0] chrsel;
always_comb begin
chrsel = 0;
casez({submapper1, chr_ain[13:11]})
// submapper 1
4'b1_000 : chrsel = {1'b0, chrbank_reg[0], chr_ain[10]};
4'b1_001 : chrsel = {1'b0, chrbank_reg[1], chr_ain[10]};
4'b1_010 : chrsel = {1'b0, chrbank_reg[6], chr_ain[10]};
4'b1_011 : chrsel = {1'b0, chrbank_reg[7], chr_ain[10]};
// submapper 0 and 2
4'b0_0?? : chrsel = {submapper2 ? outer_bank : 2'b00, chrbank_reg[chr_ain[12:10]]};
// all submappers
default : chrsel = {6'd0, chr_ain[13:10]};
endcase
end
// handle reads from scratch RAM and dipswitch
always_comb begin
casez(prg_ain[15:12])
4'h5 : begin
if (|prg_ain[11:8]) begin
prg_dout = scratch_ram[prg_ain[1:0]];
end else
prg_dout = {6'b1111_11, dipswitch};
end
default : begin
prg_dout = 8'hFF;
end
endcase
end
wire prg_read_blocked = (prg_ain[15:13] == 3'b011) && !submapper2 && !prg_reg3_enable;
assign prg_bus_write = (prg_ain[15:12] == 4'h5) || prg_read_blocked;
wire is_wram = submapper2 && (prg_ain[15:13] == 3'b011);
assign chr_aout[21:20] = 2'b10;
assign chr_aout[19:10] = chrsel;
assign chr_aout[9:0] = chr_ain[9:0];
assign prg_aout[21:18] = is_wram ? 4'b11_11 : {2'b00, submapper2 ? outer_bank : 2'b00};
assign prg_aout[17:13] = is_wram ? {3'b00_0, wrambank} : prgsel;
assign prg_aout[12:0] = prg_ain[12:0];
assign prg_allow = (prg_ain[15] && !prg_write) || is_wram;
assign chr_allow = flags[15];
assign vram_ce = chr_ain[13];
endmodule