mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-05-17 03:03:43 +00:00
Add MBC6 & HuC3 mappers (#170)
This commit is contained in:
@@ -425,7 +425,8 @@ wire [9:0] mbc_bank;
|
||||
wire [7:0] ram_mask_file, cart_ram_size;
|
||||
wire isGBC_game, isSGB_game;
|
||||
wire cart_has_save;
|
||||
wire [31:0] RTC_timestampOut, RTC_savedtimeOut;
|
||||
wire [31:0] RTC_timestampOut;
|
||||
wire [47:0] RTC_savedtimeOut;
|
||||
wire RTC_inuse;
|
||||
|
||||
cart_top cart (
|
||||
@@ -969,6 +970,7 @@ assign sd_buff_din = (sd_lba[7:0] <= ram_mask_file) ? bk_q : // normal saveram
|
||||
(sd_buff_addr == 8'd1) ? RTC_timestampOut[31:16] :
|
||||
(sd_buff_addr == 8'd2) ? RTC_savedtimeOut[15:0] :
|
||||
(sd_buff_addr == 8'd3) ? RTC_savedtimeOut[31:16] :
|
||||
(sd_buff_addr == 8'd4) ? RTC_savedtimeOut[47:32] :
|
||||
16'hFFFF;
|
||||
|
||||
|
||||
|
||||
@@ -25,9 +25,11 @@ set_global_assignment -name VERILOG_FILE rtl/mappers/mbc1.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/mbc2.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/mbc3.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/mbc5.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/mbc6.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/mbc7.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/mmm01.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/huc1.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/huc3.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/gb_camera.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mappers/tama.v
|
||||
set_global_assignment -name SDC_FILE Gameboy.sdc
|
||||
|
||||
@@ -47,7 +47,7 @@ module cart_top (
|
||||
|
||||
input [32:0] RTC_time,
|
||||
output [31:0] RTC_timestampOut,
|
||||
output [31:0] RTC_savedtimeOut,
|
||||
output [47:0] RTC_savedtimeOut,
|
||||
output RTC_inuse,
|
||||
|
||||
input [63:0] SaveStateExt_Din,
|
||||
@@ -106,9 +106,11 @@ mappers mappers (
|
||||
.mbc3 ( mbc3 ),
|
||||
.mbc30( mbc30 ),
|
||||
.mbc5 ( mbc5 ),
|
||||
.mbc6 ( mbc6 ),
|
||||
.mbc7 ( mbc7 ),
|
||||
.mmm01 ( mmm01 ),
|
||||
.huc1 ( HuC1 ),
|
||||
.huc3 ( HuC3 ),
|
||||
.gb_camera ( gb_camera ),
|
||||
.tama ( tama ),
|
||||
|
||||
@@ -196,11 +198,12 @@ wire mbc3 = (cart_mbc_type == 15) || (cart_mbc_type == 16) || (cart_mbc_type ==
|
||||
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);
|
||||
wire mbc6 = (cart_mbc_type == 32);
|
||||
wire mbc7 = (cart_mbc_type == 34);
|
||||
wire gb_camera = (cart_mbc_type == 252);
|
||||
wire tama = (cart_mbc_type == 253);
|
||||
|
||||
//wire HuC3 = (cart_mbc_type == 254);
|
||||
wire HuC3 = (cart_mbc_type == 254);
|
||||
wire HuC1 = (cart_mbc_type == 255);
|
||||
|
||||
|
||||
|
||||
239
rtl/mappers/huc3.v
Normal file
239
rtl/mappers/huc3.v
Normal file
@@ -0,0 +1,239 @@
|
||||
module huc3 (
|
||||
input enable,
|
||||
|
||||
input clk_sys,
|
||||
input ce_cpu,
|
||||
|
||||
input savestate_load,
|
||||
input [63:0] savestate_data,
|
||||
inout [63:0] savestate_back_b,
|
||||
|
||||
input [32:0] RTC_time,
|
||||
inout [31:0] RTC_timestampOut_b,
|
||||
inout [47:0] RTC_savedtimeOut_b,
|
||||
inout RTC_inuse_b,
|
||||
|
||||
input bk_rtc_wr,
|
||||
input [16:0] bk_addr,
|
||||
input [15:0] bk_data,
|
||||
|
||||
input has_ram,
|
||||
input [3:0] ram_mask,
|
||||
input [8:0] rom_mask,
|
||||
|
||||
input [15:0] cart_addr,
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
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 [9:0] mbc_bank_b,
|
||||
inout ram_enabled_b,
|
||||
inout has_battery_b
|
||||
);
|
||||
|
||||
wire [9:0] mbc_bank;
|
||||
wire ram_enabled;
|
||||
wire [7:0] cram_do;
|
||||
wire [16:0] cram_addr;
|
||||
wire has_battery;
|
||||
wire [63:0] savestate_back;
|
||||
|
||||
reg [31:0] RTC_timestampOut;
|
||||
reg [47:0] RTC_savedtimeOut;
|
||||
wire RTC_inuse = 1;
|
||||
|
||||
assign mbc_bank_b = enable ? mbc_bank : 10'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 : 64'hZ;
|
||||
assign RTC_timestampOut_b = enable ? RTC_timestampOut : 32'hZ;
|
||||
assign RTC_savedtimeOut_b = enable ? RTC_savedtimeOut : 48'hZ;
|
||||
assign RTC_inuse_b = enable ? RTC_inuse : 1'hZ;
|
||||
|
||||
// --------------------- CPU register interface ------------------
|
||||
|
||||
reg [6:0] rom_bank_reg;
|
||||
reg [1:0] ram_bank_reg;
|
||||
reg [3:0] mode;
|
||||
|
||||
assign savestate_back[ 6: 0] = rom_bank_reg;
|
||||
assign savestate_back[ 8: 7] = ram_bank_reg;
|
||||
assign savestate_back[12: 9] = mode;
|
||||
assign savestate_back[63:13] = 0;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(savestate_load & enable) begin
|
||||
rom_bank_reg <= savestate_data[ 6: 0]; // 7'd0;
|
||||
ram_bank_reg <= savestate_data[ 8: 7]; // 2'd0;
|
||||
mode <= savestate_data[12: 9]; // 4'd0;
|
||||
end else if(~enable) begin
|
||||
rom_bank_reg <= 7'd0;
|
||||
ram_bank_reg <= 2'd0;
|
||||
mode <= 4'd0;
|
||||
end else if(ce_cpu) begin
|
||||
if (cart_wr) begin
|
||||
if (~cart_addr[15]) begin
|
||||
case(cart_addr[14:13])
|
||||
2'b00: mode <= cart_di[3:0];
|
||||
2'b01: rom_bank_reg <= cart_di[6:0]; // ROM bank register
|
||||
2'b10: ram_bank_reg <= cart_di[1:0]; // RAM bank register
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [ 7:0] rtc_index;
|
||||
reg [ 3:0] rtc_flags;
|
||||
reg [ 3:0] rtc_out;
|
||||
reg [ 5:0] rtc_seconds;
|
||||
reg [24:0] rtc_subseconds;
|
||||
reg [11:0] rtc_minutes; // Minutes of the day 0-1439
|
||||
reg [15:0] rtc_days;
|
||||
|
||||
reg [31:0] RTC_timestampSaved;
|
||||
reg [47:0] RTC_savedtimeIn;
|
||||
reg RTC_timestampNew_1;
|
||||
reg RTC_saveLoaded;
|
||||
|
||||
wire rtc_subseconds_end = &rtc_subseconds;
|
||||
reg [31:0] diffSeconds;
|
||||
wire diffSeconds_fast_count = (diffSeconds > 0);
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
rtc_subseconds <= rtc_subseconds + 1'b1;
|
||||
|
||||
if (rtc_subseconds_end) begin
|
||||
RTC_timestampOut <= RTC_timestampOut + 1'd1;
|
||||
end else if (diffSeconds_fast_count) begin // fast counting loaded seconds
|
||||
diffSeconds <= diffSeconds - 1'd1;
|
||||
end
|
||||
|
||||
if (rtc_subseconds_end | diffSeconds_fast_count) begin
|
||||
rtc_seconds <= rtc_seconds + 1'b1;
|
||||
if (rtc_seconds == 59) begin
|
||||
rtc_seconds <= 0;
|
||||
rtc_minutes <= rtc_minutes + 1'b1;
|
||||
if (rtc_minutes == 1439) begin
|
||||
rtc_minutes <= 0;
|
||||
rtc_days <= rtc_days + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RTC_saveLoaded <= 1'b0;
|
||||
if (bk_rtc_wr) begin // load data from savefile to intermediate register
|
||||
case (bk_addr[7:0])
|
||||
0: RTC_timestampSaved[15:0] <= bk_data;
|
||||
1: RTC_timestampSaved[31:16] <= bk_data;
|
||||
2: RTC_savedtimeIn[15:0] <= bk_data;
|
||||
3: RTC_savedtimeIn[31:16] <= bk_data;
|
||||
4: RTC_savedtimeIn[47:32] <= bk_data;
|
||||
5: RTC_saveLoaded <= 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
||||
if (RTC_saveLoaded) begin // load data from intermediate register to RTC registers
|
||||
|
||||
if (RTC_timestampOut > RTC_timestampSaved) begin
|
||||
diffSeconds <= RTC_timestampOut - RTC_timestampSaved;
|
||||
end
|
||||
|
||||
rtc_seconds <= RTC_savedtimeIn[ 5: 0];
|
||||
rtc_minutes <= RTC_savedtimeIn[17: 6];
|
||||
rtc_days <= RTC_savedtimeIn[33:18];
|
||||
end
|
||||
|
||||
RTC_savedtimeOut[33: 0] <= { rtc_days, rtc_minutes, rtc_seconds };
|
||||
RTC_savedtimeOut[47:34] <= 0;
|
||||
|
||||
if (~enable) begin
|
||||
rtc_index <= 8'd0;
|
||||
rtc_flags <= 4'd0;
|
||||
rtc_out <= 4'd0;
|
||||
end else if(ce_cpu & cart_wr & (cart_addr[15:13] == 3'b101)) begin // $A000-BFFF
|
||||
if (mode == 4'hB) begin
|
||||
if (cart_di[7:4] == 4'd1) begin
|
||||
case(rtc_index)
|
||||
8'h00: rtc_out <= rtc_minutes[ 3: 0];
|
||||
8'h01: rtc_out <= rtc_minutes[ 7: 4];
|
||||
8'h02: rtc_out <= rtc_minutes[11: 8];
|
||||
8'h03: rtc_out <= rtc_days[ 3: 0];
|
||||
8'h04: rtc_out <= rtc_days[ 7: 4];
|
||||
8'h05: rtc_out <= rtc_days[11: 8];
|
||||
8'h06: rtc_out <= rtc_days[15:12];
|
||||
endcase
|
||||
rtc_index <= rtc_index + 1'b1;
|
||||
end
|
||||
|
||||
if (cart_di[7:4] == 4'd2 || cart_di[7:4] == 4'd3) begin
|
||||
case(rtc_index)
|
||||
8'h00: begin
|
||||
rtc_minutes[ 3: 0] <= cart_di[3:0];
|
||||
rtc_seconds <= 0;
|
||||
rtc_subseconds <= 0;
|
||||
end
|
||||
8'h01: rtc_minutes[ 7: 4] <= cart_di[3:0];
|
||||
8'h02: rtc_minutes[11: 8] <= cart_di[3:0];
|
||||
8'h03: rtc_days[ 3: 0] <= cart_di[3:0];
|
||||
8'h04: rtc_days[ 7: 4] <= cart_di[3:0];
|
||||
8'h05: rtc_days[11: 8] <= cart_di[3:0];
|
||||
8'h06: rtc_days[15:12] <= cart_di[3:0];
|
||||
endcase
|
||||
if (cart_di[4]) rtc_index <= rtc_index + 1'b1;
|
||||
end
|
||||
|
||||
case(cart_di[7:4])
|
||||
4'd4: rtc_index[3:0] <= cart_di[3:0];
|
||||
4'd5: rtc_index[7:4] <= cart_di[3:0];
|
||||
4'd6: rtc_flags <= cart_di[3:0];
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
RTC_timestampNew_1 <= RTC_time[32]; // saving timestamp from HPS
|
||||
if (RTC_timestampNew_1 != RTC_time[32]) begin
|
||||
RTC_timestampOut <= RTC_time[31:0];
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
wire [1:0] ram_bank = ram_bank_reg & ram_mask[1:0];
|
||||
|
||||
// 0x0000-0x3FFF = Bank 0
|
||||
wire [6:0] rom_bank = (cart_addr[15:14] == 2'b00) ? 7'd0 : rom_bank_reg;
|
||||
|
||||
// mask address lines to enable proper mirroring
|
||||
wire [6:0] rom_bank_m = rom_bank & rom_mask[6:0]; //64
|
||||
|
||||
reg [7:0] cram_do_r;
|
||||
always @* begin
|
||||
cram_do_r = 8'hFF;
|
||||
case(mode)
|
||||
// 0: RAM read, A: RAM read/write. Robopon reads from RAM with mode 0.
|
||||
4'h0, 4'hA: if (has_ram) cram_do_r = cram_di; // RAM
|
||||
4'hC: cram_do_r[3:0] = (rtc_flags == 4'd2) ? 4'h1 : rtc_out; // RTC
|
||||
4'hD: cram_do_r[3:0] = 4'h1; //RTC
|
||||
4'hE: cram_do_r[0] = 1'b0; // Light detected
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign mbc_bank = { 2'b00, rom_bank_m, cart_addr[13] }; // 16k ROM Bank 0-127
|
||||
assign ram_enabled = (mode == 4'hA) & has_ram; // RAM write enable
|
||||
|
||||
assign cram_do = cram_do_r;
|
||||
assign cram_addr = { 2'b00, ram_bank, cart_addr[12:0] };
|
||||
assign has_battery = has_ram;
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -12,9 +12,11 @@ module mappers(
|
||||
input mbc3,
|
||||
input mbc30,
|
||||
input mbc5,
|
||||
input mbc6,
|
||||
input mbc7,
|
||||
input mmm01,
|
||||
input huc1,
|
||||
input huc3,
|
||||
input gb_camera,
|
||||
input tama,
|
||||
|
||||
@@ -22,7 +24,7 @@ module mappers(
|
||||
|
||||
input [32:0] RTC_time,
|
||||
output [31:0] RTC_timestampOut,
|
||||
output [31:0] RTC_savedtimeOut,
|
||||
output [47:0] RTC_savedtimeOut,
|
||||
output RTC_inuse,
|
||||
|
||||
input bk_wr,
|
||||
@@ -69,10 +71,13 @@ tri0 [15:0] savestate_back_b;
|
||||
tri0 [63:0] savestate_back2_b;
|
||||
tri0 [7:0] cram_wr_do_b;
|
||||
tri0 cram_wr_b;
|
||||
tri0 [31:0] RTC_timestampOut_b;
|
||||
tri0 [47:0] RTC_savedtimeOut_b;
|
||||
tri0 RTC_inuse_b;
|
||||
|
||||
|
||||
wire ce = speed ? ce_cpu2x : ce_cpu;
|
||||
wire no_mapper = ~(mbc1 | mbc2 | mbc3 | mbc5 | mbc7 | mmm01 | huc1 | gb_camera | tama);
|
||||
wire no_mapper = ~(mbc1 | mbc2 | mbc3 | mbc5 | mbc6 | mbc7 | mmm01 | huc1 | huc3 | gb_camera | tama);
|
||||
|
||||
mbc1 map_mbc1 (
|
||||
.enable ( mbc1 ),
|
||||
@@ -145,9 +150,9 @@ mbc3 map_mbc3 (
|
||||
.savestate_back_b ( savestate_back_b ),
|
||||
|
||||
.RTC_time ( RTC_time ),
|
||||
.RTC_timestampOut ( RTC_timestampOut ),
|
||||
.RTC_savedtimeOut ( RTC_savedtimeOut ),
|
||||
.RTC_inuse ( RTC_inuse ),
|
||||
.RTC_timestampOut_b( RTC_timestampOut_b ),
|
||||
.RTC_savedtimeOut_b( RTC_savedtimeOut_b ),
|
||||
.RTC_inuse_b ( RTC_inuse_b ),
|
||||
|
||||
.bk_wr ( bk_wr ),
|
||||
.bk_rtc_wr ( bk_rtc_wr ),
|
||||
@@ -203,6 +208,35 @@ mbc5 map_mbc5 (
|
||||
.has_battery_b ( has_battery_b )
|
||||
);
|
||||
|
||||
mbc6 map_mbc6 (
|
||||
.enable ( mbc6 ),
|
||||
|
||||
.clk_sys ( clk_sys ),
|
||||
.ce_cpu ( ce ),
|
||||
|
||||
.savestate_load ( savestate_load ),
|
||||
.savestate_data ( savestate_data2 ),
|
||||
.savestate_back_b ( savestate_back2_b ),
|
||||
|
||||
.has_ram ( has_ram ),
|
||||
.ram_mask ( ram_mask ),
|
||||
.rom_mask ( rom_mask ),
|
||||
|
||||
.cart_addr ( cart_addr ),
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.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_bank_b ( mbc_bank_b ),
|
||||
.ram_enabled_b ( ram_enabled_b ),
|
||||
.has_battery_b ( has_battery_b )
|
||||
);
|
||||
|
||||
mbc7 map_mbc7 (
|
||||
.enable ( mbc7 ),
|
||||
|
||||
@@ -299,6 +333,45 @@ huc1 map_huc1 (
|
||||
.has_battery_b ( has_battery_b )
|
||||
);
|
||||
|
||||
huc3 map_huc3 (
|
||||
.enable ( huc3 ),
|
||||
|
||||
.clk_sys ( clk_sys ),
|
||||
.ce_cpu ( ce ),
|
||||
|
||||
.savestate_load ( savestate_load ),
|
||||
.savestate_data ( savestate_data2 ),
|
||||
.savestate_back_b ( savestate_back2_b ),
|
||||
|
||||
.RTC_time ( RTC_time ),
|
||||
.RTC_timestampOut_b( RTC_timestampOut_b ),
|
||||
.RTC_savedtimeOut_b( RTC_savedtimeOut_b ),
|
||||
.RTC_inuse_b ( RTC_inuse_b ),
|
||||
|
||||
.bk_rtc_wr ( bk_rtc_wr ),
|
||||
.bk_addr ( bk_addr ),
|
||||
.bk_data ( bk_data ),
|
||||
|
||||
.has_ram ( has_ram ),
|
||||
.ram_mask ( ram_mask ),
|
||||
.rom_mask ( rom_mask ),
|
||||
|
||||
.cart_addr ( cart_addr ),
|
||||
.cart_mbc_type ( cart_mbc_type ),
|
||||
|
||||
.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_bank_b ( mbc_bank_b ),
|
||||
.ram_enabled_b ( ram_enabled_b ),
|
||||
.has_battery_b ( has_battery_b )
|
||||
);
|
||||
|
||||
|
||||
gb_camera map_gb_camera (
|
||||
.enable ( gb_camera ),
|
||||
|
||||
@@ -362,8 +435,11 @@ tama map_tama (
|
||||
.has_battery_b ( has_battery_b )
|
||||
);
|
||||
|
||||
assign { cram_do, ram_enabled, savestate_back, savestate_back2 } = { cram_do_b, ram_enabled_b, savestate_back_b, savestate_back2_b };
|
||||
assign { cram_do, ram_enabled } = { cram_do_b, ram_enabled_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_bank = no_mapper ? {8'd0, cart_addr[14:13]} : mbc_bank_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;
|
||||
|
||||
@@ -11,9 +11,9 @@ module mbc3 (
|
||||
inout [15:0] savestate_back_b,
|
||||
|
||||
input [32:0] RTC_time,
|
||||
output reg [31:0] RTC_timestampOut,
|
||||
output reg [31:0] RTC_savedtimeOut,
|
||||
output reg RTC_inuse,
|
||||
inout [31:0] RTC_timestampOut_b,
|
||||
inout [47:0] RTC_savedtimeOut_b,
|
||||
inout RTC_inuse_b,
|
||||
|
||||
input bk_wr,
|
||||
input bk_rtc_wr,
|
||||
@@ -47,12 +47,19 @@ wire ram_enabled;
|
||||
wire has_battery;
|
||||
wire [15:0] savestate_back;
|
||||
|
||||
assign mbc_bank_b = enable ? mbc_bank : 10'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;
|
||||
reg [31:0] RTC_timestampOut;
|
||||
reg [47:0] RTC_savedtimeOut;
|
||||
reg RTC_inuse;
|
||||
|
||||
assign mbc_bank_b = enable ? mbc_bank : 10'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;
|
||||
assign RTC_timestampOut_b = enable ? RTC_timestampOut : 32'hZ;
|
||||
assign RTC_savedtimeOut_b = enable ? RTC_savedtimeOut : 48'hZ;
|
||||
assign RTC_inuse_b = enable ? RTC_inuse : 1'hZ;
|
||||
|
||||
// --------------------- CPU register interface ------------------
|
||||
|
||||
@@ -165,9 +172,9 @@ always @(posedge clk_sys) begin
|
||||
RTC_inuse <= 1'b0;
|
||||
rtc_latch <= 1'b0;
|
||||
end else begin
|
||||
|
||||
RTC_savedtimeOut[47:29] <= 0;
|
||||
if (rtc_change == 1'b0) begin // when RTC hasn't changed recently, update the register which will be written after savegame
|
||||
RTC_savedtimeOut <= {3'd0, rtc_halt, rtc_overflow, rtc_days, rtc_hours, rtc_minutes, rtc_seconds};
|
||||
RTC_savedtimeOut[28:0] <= {rtc_halt, rtc_overflow, rtc_days, rtc_hours, rtc_minutes, rtc_seconds};
|
||||
end
|
||||
|
||||
rtc_change <= 1'b0;
|
||||
|
||||
128
rtl/mappers/mbc6.v
Normal file
128
rtl/mappers/mbc6.v
Normal file
@@ -0,0 +1,128 @@
|
||||
module mbc6 (
|
||||
input enable,
|
||||
|
||||
input clk_sys,
|
||||
input ce_cpu,
|
||||
|
||||
input savestate_load,
|
||||
input [63:0] savestate_data,
|
||||
inout [63:0] savestate_back_b,
|
||||
|
||||
input has_ram,
|
||||
input [1:0] ram_mask,
|
||||
input [5:0] rom_mask,
|
||||
|
||||
input [15:0] cart_addr,
|
||||
input [7:0] cart_mbc_type,
|
||||
|
||||
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 [9:0] mbc_bank_b,
|
||||
inout ram_enabled_b,
|
||||
inout has_battery_b
|
||||
);
|
||||
|
||||
wire [9:0] mbc_bank;
|
||||
wire [7:0] cram_do;
|
||||
wire [16:0] cram_addr;
|
||||
wire ram_enabled;
|
||||
wire has_battery;
|
||||
wire [63:0] savestate_back;
|
||||
|
||||
assign mbc_bank_b = enable ? mbc_bank : 10'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 : 64'hZ;
|
||||
|
||||
// --------------------- CPU register interface ------------------
|
||||
|
||||
reg [6:0] rom_bank_reg_a;
|
||||
reg [6:0] rom_bank_reg_b;
|
||||
reg [2:0] ram_bank_reg_a;
|
||||
reg [2:0] ram_bank_reg_b;
|
||||
reg ram_enable;
|
||||
|
||||
assign savestate_back[ 6: 0] = rom_bank_reg_a;
|
||||
assign savestate_back[13: 7] = rom_bank_reg_b;
|
||||
assign savestate_back[16:14] = ram_bank_reg_a;
|
||||
assign savestate_back[19:17] = ram_bank_reg_b;
|
||||
assign savestate_back[ 20] = ram_enable;
|
||||
assign savestate_back[63:21] = 0;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(savestate_load & enable) begin
|
||||
rom_bank_reg_a <= savestate_data[ 6: 0]; // 7'd0;
|
||||
rom_bank_reg_b <= savestate_data[13: 7]; // 7'd0;
|
||||
ram_bank_reg_a <= savestate_data[16:14]; // 3'd0;
|
||||
ram_bank_reg_b <= savestate_data[19:17]; // 3'd0;
|
||||
ram_enable <= savestate_data[ 20]; // 1'b0;
|
||||
end else if(~enable) begin
|
||||
rom_bank_reg_a <= 7'd0;
|
||||
rom_bank_reg_b <= 7'd0;
|
||||
ram_bank_reg_a <= 3'd0;
|
||||
ram_bank_reg_b <= 3'd0;
|
||||
ram_enable <= 1'b0;
|
||||
end else if(ce_cpu) begin
|
||||
if (cart_wr) begin
|
||||
if (!cart_addr[15:13]) begin // $0000-1FFF
|
||||
case(cart_addr[12:10])
|
||||
3'd0: ram_enable <= (cart_di[3:0] == 4'hA); //RAM enable/disable
|
||||
3'd1: ram_bank_reg_a <= cart_di[2:0]; // 4KB RAM bank A ($A000-AFFF)
|
||||
3'd2: ram_bank_reg_b <= cart_di[2:0]; // 4KB RAM bank B ($B000-BFFF)
|
||||
3'd3: ; // Flash enable
|
||||
3'd4: ; // Flash write enable
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
if (cart_addr[15:13] == 3'b001) begin // $2000-3FFF
|
||||
case(cart_addr[12:11])
|
||||
2'd0: rom_bank_reg_a <= cart_di[6:0]; // 8KB ROM bank A ($4000-5FFF)
|
||||
2'd1: ; //rom_flash_sel_a <= (cart_di[3:0] == 4'h8); // ROM/Flash A select
|
||||
2'd2: rom_bank_reg_b <= cart_di[6:0]; // 8KB ROM bank B ($6000-7FFF)
|
||||
2'd3: ; //rom_flash_sel_b <= (cart_di[3:0] == 4'h8); // ROM/Flash B select
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [6:0] rom_bank;
|
||||
always @* begin
|
||||
if (~cart_addr[14]) begin // $0000-3FFF
|
||||
rom_bank = { 6'd0, cart_addr[13] };
|
||||
end else if (~cart_addr[13]) begin // $4000-5FFF
|
||||
rom_bank = rom_bank_reg_a;
|
||||
end else begin // $6000-7FFF
|
||||
rom_bank = rom_bank_reg_b;
|
||||
end
|
||||
end
|
||||
|
||||
reg [2:0] ram_bank;
|
||||
always @* begin
|
||||
if (~cart_addr[12]) begin // $A000-AFFF
|
||||
ram_bank = ram_bank_reg_a;
|
||||
end else begin // $B000-BFFF
|
||||
ram_bank = ram_bank_reg_b;
|
||||
end
|
||||
end
|
||||
|
||||
// mask address lines to enable proper mirroring
|
||||
wire [6:0] rom_bank_m = rom_bank & { rom_mask[5:0], 1'b1 }; // 64x16KB Mask
|
||||
wire [2:0] ram_bank_m = ram_bank & { ram_mask[1:0], 1'b1 }; // 4x8KB Mask
|
||||
|
||||
assign mbc_bank = { 3'd0, rom_bank_m }; // 8KB ROM Bank 0-127
|
||||
|
||||
assign cram_do = ram_enabled ? cram_di : 8'hFF;
|
||||
assign cram_addr = { 2'd0, ram_bank_m, cart_addr[11:0] }; // 4KB RAM Bank 0-7
|
||||
|
||||
assign has_battery = has_ram;
|
||||
assign ram_enabled = ram_enable & has_ram;
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user