mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-05-17 03:03:43 +00:00
Add Wisdom Tree / Mani 161 mappers & mapper selection.
This commit is contained in:
23
Gameboy.sv
23
Gameboy.sv
@@ -194,13 +194,15 @@ assign AUDIO_MIX = status[8:7];
|
||||
// 0 1 2 3 4 5 6
|
||||
// 01234567890123456789012345678901 23456789012345678901234567890123
|
||||
// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV
|
||||
// XXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXX
|
||||
// XXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXX
|
||||
|
||||
`include "build_id.v"
|
||||
localparam CONF_STR = {
|
||||
"GAMEBOY;SS3E000000:40000;",
|
||||
"FS1,GBCGB BIN,Load ROM;",
|
||||
"OEF,System,Auto,Gameboy,Gameboy Color,MegaDuck;",
|
||||
"D7o79,Mapper,Auto,WisdomTree,Mani161,MBC1,MBC3;",
|
||||
"-;",
|
||||
"ONO,Super Game Boy,Off,Palette,On;",
|
||||
"d5FC2,SGB,Load SGB border;",
|
||||
"-;",
|
||||
@@ -322,6 +324,10 @@ wire [15:0] joy0_rumble;
|
||||
|
||||
wire [32:0] RTC_time;
|
||||
|
||||
wire sys_auto = (status[15:14] == 0);
|
||||
wire sys_gbc = (status[15:14] == 2);
|
||||
wire sys_megaduck = (status[15:14] == 3);
|
||||
|
||||
hps_io #(.CONF_STR(CONF_STR), .WIDE(1)) hps_io
|
||||
(
|
||||
.clk_sys(clk_sys),
|
||||
@@ -349,7 +355,7 @@ hps_io #(.CONF_STR(CONF_STR), .WIDE(1)) hps_io
|
||||
|
||||
.buttons(buttons),
|
||||
.status(status),
|
||||
.status_menumask({using_real_cgb_bios,sgb_border_en,isGBC,cart_ready,sav_supported,|tint,gg_available}),
|
||||
.status_menumask({sys_megaduck,using_real_cgb_bios,sgb_border_en,isGBC,cart_ready,sav_supported,|tint,gg_available}),
|
||||
.status_in({status[63:34],ss_slot,status[31:0]}),
|
||||
.status_set(statusUpdate),
|
||||
.direct_video(direct_video),
|
||||
@@ -445,6 +451,7 @@ wire [31:0] RTC_timestampOut;
|
||||
wire [47:0] RTC_savedtimeOut;
|
||||
wire RTC_inuse;
|
||||
wire rumbling;
|
||||
wire [2:0] mapper_sel = status[41:39];
|
||||
|
||||
assign joy0_rumble = {8'd0, ((rumbling & ~status[38]) ? 8'd128 : 8'd0)};
|
||||
|
||||
@@ -456,6 +463,7 @@ cart_top cart (
|
||||
.ce_cpu2x ( ce_cpu2x ),
|
||||
.speed ( speed ),
|
||||
.megaduck ( megaduck ),
|
||||
.mapper_sel ( mapper_sel ),
|
||||
|
||||
.cart_addr ( cart_addr ),
|
||||
.cart_a15 ( cart_a15 ),
|
||||
@@ -551,12 +559,15 @@ reg megaduck = 0;
|
||||
reg isGBC = 0;
|
||||
always @(posedge clk_sys) if(reset) begin
|
||||
if (cart_download)
|
||||
megaduck <= (status[15:14] == 3);
|
||||
megaduck <= sys_megaduck;
|
||||
if (md_download)
|
||||
megaduck <= (status[15:14] == 0) || (status[15:14] == 3);
|
||||
megaduck <= sys_auto || sys_megaduck;
|
||||
|
||||
if(status[15:14]) isGBC <= (status[15:14] == 2);
|
||||
else if(cart_download) isGBC <= (status[15:14] == 0) && !filetype[7:6];
|
||||
if(~sys_auto) isGBC <= sys_gbc;
|
||||
else if(cart_download) begin
|
||||
if (!filetype[5:0]) isGBC <= isGBC_game;
|
||||
else isGBC <= !filetype[7:6];
|
||||
end
|
||||
end
|
||||
|
||||
wire [15:0] GB_AUDIO_L;
|
||||
|
||||
@@ -36,5 +36,6 @@ set_global_assignment -name VERILOG_FILE rtl/mappers/tama.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/mappers/rocket.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/sachen.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/megaduck.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/misc.v
|
||||
set_global_assignment -name SDC_FILE Gameboy.sdc
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE Gameboy.sv
|
||||
|
||||
125
rtl/cart.v
125
rtl/cart.v
@@ -6,6 +6,7 @@ module cart_top (
|
||||
input ce_cpu2x,
|
||||
input speed,
|
||||
input megaduck,
|
||||
input [2:0] mapper_sel,
|
||||
|
||||
input [14:0] cart_addr,
|
||||
input cart_a15,
|
||||
@@ -123,6 +124,9 @@ mappers mappers (
|
||||
.tama ( tama ),
|
||||
.rocket ( rocket ),
|
||||
.sachen ( sachen),
|
||||
.wisdom_tree ( wisdom_tree ),
|
||||
.mani161 ( mani161 ),
|
||||
|
||||
.megaduck ( megaduck_en ),
|
||||
|
||||
.isGBC_game ( isGBC_game ),
|
||||
@@ -199,6 +203,7 @@ wire [3:0] ram_mask = // 0 - no ram
|
||||
4'b1111; // 4 - 128k 16 banks
|
||||
|
||||
// ROM size
|
||||
/*
|
||||
wire [8:0] rom_mask =
|
||||
(cart_rom_size == 0)? 9'b000000001: // 0 - 2 banks, 32k direct mapped
|
||||
(cart_rom_size == 1)? 9'b000000011: // 1 - 4 banks = 64k
|
||||
@@ -213,11 +218,14 @@ wire [8:0] rom_mask =
|
||||
(cart_rom_size == 83)?9'b001111111: //$53 - 80 banks = 1.2M
|
||||
(cart_rom_size == 84)?9'b001111111:
|
||||
9'b001111111; //$54 - 96 banks = 1.5M
|
||||
*/
|
||||
|
||||
wire mbc1 = (cart_mbc_type == 1) || (cart_mbc_type == 2) || (cart_mbc_type == 3);
|
||||
reg [8:0] rom_mask; // get mask from file size
|
||||
|
||||
wire mbc1 = (mapper_sel_r == 3'd3) || (cart_mbc_type == 1) || (cart_mbc_type == 2) || (cart_mbc_type == 3);
|
||||
wire mbc2 = (cart_mbc_type == 5) || (cart_mbc_type == 6);
|
||||
//wire mmm01 = (cart_mbc_type == 11) || (cart_mbc_type == 12) || (cart_mbc_type == 13) || (cart_mbc_type == 14);
|
||||
wire mbc3 = (cart_mbc_type == 15) || (cart_mbc_type == 16) || (cart_mbc_type == 17) || (cart_mbc_type == 18) || (cart_mbc_type == 19);
|
||||
wire mbc3 = (mapper_sel_r == 3'd4) || (cart_mbc_type == 15) || (cart_mbc_type == 16) || (cart_mbc_type == 17) || (cart_mbc_type == 18) || (cart_mbc_type == 19);
|
||||
wire mbc30 = mbc3 && ( (cart_rom_size == 7) || (cart_ram_size == 5) );
|
||||
//wire mbc4 = (cart_mbc_type == 21) || (cart_mbc_type == 22) || (cart_mbc_type == 23);
|
||||
wire mbc5 = (cart_mbc_type == 25) || (cart_mbc_type == 26) || (cart_mbc_type == 27) || (cart_mbc_type == 28) || (cart_mbc_type == 29) || (cart_mbc_type == 30);
|
||||
@@ -231,6 +239,9 @@ wire tama = (cart_mbc_type == 253);
|
||||
wire HuC3 = (cart_mbc_type == 254);
|
||||
wire HuC1 = (cart_mbc_type == 255);
|
||||
|
||||
wire wisdom_tree = (mapper_sel_r == 3'd1);
|
||||
wire mani161 = (mapper_sel_r == 3'd2);
|
||||
|
||||
wire has_rumble = (cart_mbc_type[7:2] == 6'b0001_11);
|
||||
wire cart_rumbling;
|
||||
assign rumbling = has_rumble & cart_rumbling;
|
||||
@@ -252,6 +263,7 @@ wire mmm01_bank = (ioctl_addr[18:12] == 7'h78); // $78000+
|
||||
wire cart_logo_match = &cart_logo_check;
|
||||
|
||||
reg old_cart_download;
|
||||
reg [2:0] mapper_sel_r;
|
||||
always @(posedge clk_sys) begin
|
||||
|
||||
old_cart_download <= cart_download;
|
||||
@@ -262,10 +274,20 @@ always @(posedge clk_sys) begin
|
||||
mbc1m <= 0;
|
||||
mmm01 <= 0;
|
||||
{ sachen, sachen_t1, sachen_t2 } <= 0;
|
||||
mapper_sel_r <= mapper_sel;
|
||||
end
|
||||
|
||||
if(cart_download & ioctl_wr) begin
|
||||
if (!megaduck) begin
|
||||
|
||||
rom_mask <= ioctl_addr[22:14];
|
||||
|
||||
if (megaduck) begin
|
||||
cart_cgb_flag <= 0;
|
||||
cart_sgb_flag <= 0;
|
||||
mapper_sel_r <= 0;
|
||||
if (ioctl_addr > 'h100) // Make sure there's time to reset the banks in the mapper
|
||||
cart_mbc_type <= 8'd250;
|
||||
end else begin
|
||||
if (~|ioctl_addr[24:12] || (mmm01_bank & mmm01) ) // MMM01 header is at the end of ROM
|
||||
case(ioctl_addr[11:0])
|
||||
12'h142: cart_cgb_flag <= ioctl_dout[15];
|
||||
@@ -278,62 +300,63 @@ always @(posedge clk_sys) begin
|
||||
12'h14a: { cart_old_licensee } <= ioctl_dout[15:8];
|
||||
endcase
|
||||
|
||||
// Sachen
|
||||
if (~|ioctl_addr[24:12]) begin
|
||||
case(ioctl_addr[11:0])
|
||||
12'h100: sachen_t1 <= (ioctl_dout[15:8] != 8'hC3);
|
||||
12'h140: sachen_t2 <= (ioctl_dout[ 7:0] == 8'hC3); // 0xC3 opcode is at $140 instead of $101
|
||||
12'h150: begin /// CGB flag
|
||||
if (sachen_t1 & sachen_t2) begin
|
||||
sachen <= 1'b1;
|
||||
cart_cgb_flag <= ioctl_dout[15];
|
||||
cart_mbc_type <= 0;
|
||||
cart_sgb_flag <= 0;
|
||||
cart_ram_size <= 0;
|
||||
cart_rom_size <= 0;
|
||||
cart_old_licensee <= 0;
|
||||
// Disable other mappers when a specific mapper has been selected
|
||||
if (|mapper_sel_r) begin
|
||||
cart_mbc_type <= 8'd0;
|
||||
mbc1m <= 0;
|
||||
mmm01 <= 0;
|
||||
sachen <= 0;
|
||||
end else begin
|
||||
// Sachen
|
||||
if (~|ioctl_addr[24:12]) begin
|
||||
case(ioctl_addr[11:0])
|
||||
12'h100: sachen_t1 <= (ioctl_dout[15:8] != 8'hC3);
|
||||
12'h140: sachen_t2 <= (ioctl_dout[ 7:0] == 8'hC3); // 0xC3 opcode is at $140 instead of $101
|
||||
12'h150: begin /// CGB flag
|
||||
if (sachen_t1 & sachen_t2) begin
|
||||
sachen <= 1'b1;
|
||||
cart_cgb_flag <= ioctl_dout[15];
|
||||
cart_mbc_type <= 0;
|
||||
cart_sgb_flag <= 0;
|
||||
cart_ram_size <= 0;
|
||||
cart_old_licensee <= 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
//Store cart logo data
|
||||
if (ioctl_addr >= 'h104 && ioctl_addr <= 'h112) begin
|
||||
cart_logo_data[cart_logo_idx] <= ioctl_dout;
|
||||
cart_logo_idx <= cart_logo_idx + 1'b1;
|
||||
end
|
||||
|
||||
// MBC1 Multicart detect: Compare 8 words of logo data at second 256KByte bank ($40000)
|
||||
// MMM01 detect: Compare the last bank every 512KByte ($78000+)
|
||||
if ( mbc1m_bank | mmm01_bank ) begin
|
||||
if (ioctl_addr[11:0] >= 12'h104 && ioctl_addr[11:0] <= 12'h112) begin
|
||||
cart_logo_check[cart_logo_idx] <= (ioctl_dout == cart_logo_data[cart_logo_idx]);
|
||||
cart_logo_idx <= cart_logo_idx + 1'b1;
|
||||
if (&cart_logo_idx) begin
|
||||
if (mbc1m_bank) mbc1m_check_end <= 1;
|
||||
if (mmm01_bank) mmm01_check_end <= 1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin // megaduck
|
||||
cart_cgb_flag <= 0;
|
||||
cart_sgb_flag <= 0;
|
||||
cart_rom_size <= ioctl_addr[17] ? 2'd3 : ioctl_addr[16] ? 2'd2 : ioctl_addr[15] ? 2'd1 : 2'd0;
|
||||
if (ioctl_addr > 'h100) // Make sure there's time to reset the banks in the mapper
|
||||
cart_mbc_type <= 8'd250;
|
||||
end
|
||||
end
|
||||
|
||||
//Store cart logo data
|
||||
if (ioctl_addr >= 'h104 && ioctl_addr <= 'h112) begin
|
||||
cart_logo_data[cart_logo_idx] <= ioctl_dout;
|
||||
cart_logo_idx <= cart_logo_idx + 1'b1;
|
||||
end
|
||||
if (mbc1m_check_end) begin
|
||||
mbc1m_check_end <= 0;
|
||||
mbc1m <= cart_logo_match;
|
||||
end
|
||||
|
||||
// MBC1 Multicart detect: Compare 8 words of logo data at second 256KByte bank ($40000)
|
||||
// MMM01 detect: Compare the last bank every 512KByte ($78000+)
|
||||
if ( mbc1m_bank | mmm01_bank ) begin
|
||||
if (ioctl_addr[11:0] >= 12'h104 && ioctl_addr[11:0] <= 12'h112) begin
|
||||
cart_logo_check[cart_logo_idx] <= (ioctl_dout == cart_logo_data[cart_logo_idx]);
|
||||
cart_logo_idx <= cart_logo_idx + 1'b1;
|
||||
if (&cart_logo_idx) begin
|
||||
if (mbc1m_bank) mbc1m_check_end <= 1;
|
||||
if (mmm01_bank) mmm01_check_end <= 1;
|
||||
if (mmm01_check_end) begin
|
||||
mmm01_check_end <= 0;
|
||||
mmm01 <= cart_logo_match;
|
||||
if (cart_logo_match) mbc1m <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (mbc1m_check_end) begin
|
||||
mbc1m_check_end <= 0;
|
||||
mbc1m <= cart_logo_match;
|
||||
end
|
||||
|
||||
if (mmm01_check_end) begin
|
||||
mmm01_check_end <= 0;
|
||||
mmm01 <= cart_logo_match;
|
||||
if (cart_logo_match) mbc1m <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
assign ram_size = cart_ram_size;
|
||||
|
||||
@@ -21,6 +21,9 @@ module mappers(
|
||||
input tama,
|
||||
input rocket,
|
||||
input sachen,
|
||||
input wisdom_tree,
|
||||
input mani161,
|
||||
|
||||
input megaduck,
|
||||
|
||||
input isGBC_game,
|
||||
@@ -94,12 +97,14 @@ tri0 RTC_inuse_b;
|
||||
|
||||
|
||||
wire ce = speed ? ce_cpu2x : ce_cpu;
|
||||
wire no_mapper = ~(mbc1 | mbc2 | mbc3 | mbc5 | mbc6 | mbc7 | mmm01 | huc1 | huc3 | gb_camera | tama | rocket | sachen | megaduck);
|
||||
wire no_mapper = ~(mbc1 | mbc2 | mbc3 | mbc5 | mbc6 | mbc7 | mmm01 | huc1 | huc3 | gb_camera | tama | rocket | sachen | wisdom_tree | mani161 | megaduck);
|
||||
wire no_mapper_single_bank = no_mapper & ~rom_mask[1];
|
||||
wire no_mapper_multi_bank = no_mapper & rom_mask[1]; // size > 32KB
|
||||
wire rom_override = (rocket);
|
||||
wire cart_oe_override = (mbc3 | mbc7 | huc1 | huc3 | gb_camera | tama);
|
||||
|
||||
mbc1 map_mbc1 (
|
||||
.enable ( mbc1 ),
|
||||
.enable ( mbc1 | no_mapper_multi_bank ),
|
||||
.mbc1m ( mbc1m ),
|
||||
|
||||
.clk_sys ( clk_sys ),
|
||||
@@ -590,15 +595,45 @@ megaduck map_megaduck (
|
||||
.has_battery_b ( has_battery_b )
|
||||
);
|
||||
|
||||
// Mani 4-in-1 DMG 601 & Wisdom Tree 32KB bank mappers
|
||||
misc_mapper map_misc (
|
||||
.enable ( ~reset & (wisdom_tree | mani161) ),
|
||||
|
||||
.clk_sys ( clk_sys ),
|
||||
.ce_cpu ( ce ),
|
||||
|
||||
.mapper_sel ( mani161 ),
|
||||
|
||||
.savestate_load ( savestate_load ),
|
||||
.savestate_data ( savestate_data ),
|
||||
.savestate_back_b ( savestate_back_b ),
|
||||
|
||||
.rom_mask ( rom_mask ),
|
||||
|
||||
.cart_addr ( cart_addr ),
|
||||
.cart_a15 ( cart_a15 ),
|
||||
|
||||
.cart_wr ( cart_wr ),
|
||||
.cart_di ( cart_di ),
|
||||
|
||||
.cram_di ( cram_di ),
|
||||
.cram_do_b ( cram_do_b ),
|
||||
.cram_addr_b ( cram_addr_b ),
|
||||
|
||||
.mbc_addr_b ( mbc_addr_b ),
|
||||
.ram_enabled_b ( ram_enabled_b ),
|
||||
.has_battery_b ( has_battery_b )
|
||||
);
|
||||
|
||||
assign { cram_do } = { cram_do_b };
|
||||
assign { savestate_back, savestate_back2 } = { savestate_back_b, savestate_back2_b };
|
||||
assign { RTC_timestampOut, RTC_savedtimeOut, RTC_inuse } = { RTC_timestampOut_b, RTC_savedtimeOut_b, RTC_inuse_b };
|
||||
assign { cram_wr_do, cram_wr } = { cram_wr_do_b, cram_wr_b };
|
||||
|
||||
assign mbc_addr = no_mapper ? {8'd0, cart_addr[14:0]} : mbc_addr_b;
|
||||
assign cram_addr = no_mapper ? {4'd0, cart_addr[12:0]} : cram_addr_b;
|
||||
assign has_battery = no_mapper ? (cart_mbc_type == 8'h09) : has_battery_b;
|
||||
assign ram_enabled = no_mapper ? has_ram : ram_enabled_b;
|
||||
assign mbc_addr = no_mapper_single_bank ? {8'd0, cart_addr[14:0]} : mbc_addr_b;
|
||||
assign cram_addr = no_mapper_single_bank ? {4'd0, cart_addr[12:0]} : cram_addr_b;
|
||||
assign has_battery = no_mapper_single_bank ? (cart_mbc_type == 8'h09) : has_battery_b;
|
||||
assign ram_enabled = no_mapper_single_bank ? has_ram : ram_enabled_b;
|
||||
assign rom_do = rom_override ? rom_do_b : rom_di;
|
||||
assign cart_oe = cart_oe_override ? cart_oe_b : ((cart_rd & ~cart_a15) | (cram_rd & ram_enabled));
|
||||
|
||||
|
||||
86
rtl/mappers/misc.v
Normal file
86
rtl/mappers/misc.v
Normal file
@@ -0,0 +1,86 @@
|
||||
module misc_mapper (
|
||||
input enable,
|
||||
|
||||
input clk_sys,
|
||||
input ce_cpu,
|
||||
|
||||
input mapper_sel, // 0: Wisdom Tree, 1: Mani DMG-601
|
||||
|
||||
input savestate_load,
|
||||
input [15:0] savestate_data,
|
||||
inout [15:0] savestate_back_b,
|
||||
|
||||
input [8:0] rom_mask,
|
||||
|
||||
input [14:0] cart_addr,
|
||||
input cart_a15,
|
||||
|
||||
input cart_wr,
|
||||
input [7:0] cart_di,
|
||||
|
||||
input [7:0] cram_di,
|
||||
inout [7:0] cram_do_b,
|
||||
inout [16:0] cram_addr_b,
|
||||
|
||||
inout [22:0] mbc_addr_b,
|
||||
inout ram_enabled_b,
|
||||
inout has_battery_b
|
||||
);
|
||||
|
||||
wire [22:0] mbc_addr;
|
||||
wire ram_enabled;
|
||||
wire [7:0] cram_do;
|
||||
wire [16:0] cram_addr;
|
||||
wire has_battery;
|
||||
wire [15:0] savestate_back;
|
||||
|
||||
assign mbc_addr_b = enable ? mbc_addr : 23'hZ;
|
||||
assign cram_do_b = enable ? cram_do : 8'hZ;
|
||||
assign cram_addr_b = enable ? cram_addr : 17'hZ;
|
||||
assign ram_enabled_b = enable ? ram_enabled : 1'hZ;
|
||||
assign has_battery_b = enable ? has_battery : 1'hZ;
|
||||
assign savestate_back_b = enable ? savestate_back : 16'hZ;
|
||||
|
||||
// --------------------- CPU register interface ------------------
|
||||
reg [7:0] rom_bank_reg;
|
||||
reg map_disable;
|
||||
|
||||
assign savestate_back[ 7: 0] = rom_bank_reg;
|
||||
assign savestate_back[ 8] = map_disable;
|
||||
assign savestate_back[15: 9] = 0;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(savestate_load & enable) begin
|
||||
rom_bank_reg <= savestate_data[ 7: 0]; //8'd0;
|
||||
map_disable <= savestate_data[ 8]; //1'b0;
|
||||
end else if(~enable) begin
|
||||
rom_bank_reg <= 8'd0;
|
||||
map_disable <= 1'b0;
|
||||
end else if(ce_cpu) begin
|
||||
if (cart_wr & ~cart_a15) begin
|
||||
if (mapper_sel) begin
|
||||
// Mani DMG-601
|
||||
if (~map_disable) begin
|
||||
rom_bank_reg <= { 5'd0, cart_di[2:0] };
|
||||
map_disable <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
// Wisdom Tree
|
||||
rom_bank_reg <= cart_addr[7:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// mask address lines to enable proper mirroring
|
||||
wire [7:0] rom_bank = rom_bank_reg & rom_mask[8:1];
|
||||
|
||||
assign mbc_addr = { rom_bank, cart_addr[14:0] };
|
||||
|
||||
assign cram_do = 8'hFF;
|
||||
assign cram_addr = { 4'b0000, cart_addr[12:0] };
|
||||
|
||||
assign ram_enabled = 0;
|
||||
assign has_battery = 0;
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user