From b6be4f59e7a6b485cf5903f66588a63d6220d27b Mon Sep 17 00:00:00 2001 From: paulb-nl Date: Mon, 12 Apr 2021 23:37:20 +0200 Subject: [PATCH 1/2] MBC3: pass test mbc3_rtc_prelim --- rtl/mappers/mbc3.v | 86 ++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/rtl/mappers/mbc3.v b/rtl/mappers/mbc3.v index 51aa10b..23dca77 100644 --- a/rtl/mappers/mbc3.v +++ b/rtl/mappers/mbc3.v @@ -101,7 +101,7 @@ always @(posedge clk_sys) begin mbc_ram_bank_reg <= cart_di[1:0]; //write to RAM bank register end end - 2'b11: ; // TODO: Latch RTC data + 2'b11: ; // Latch RTC data. Done below endcase end end @@ -130,14 +130,15 @@ assign ram_enabled = mbc_ram_enable & has_ram; reg [2:0] rtc_index; reg [25:0] rtc_subseconds; -reg [5:0] rtc_seconds; -reg [5:0] rtc_minutes; -reg [4:0] rtc_hours; -reg [9:0] rtc_days; -reg rtc_overflow; +reg [5:0] rtc_seconds, rtc_seconds_latch; +reg [5:0] rtc_minutes, rtc_minutes_latch; +reg [4:0] rtc_hours, rtc_hours_latch; +reg [9:0] rtc_days, rtc_days_latch; +reg rtc_overflow, rtc_overflow_latch; reg rtc_halt; wire [7:0] rtc_return; +wire rtc_subseconds_end = (rtc_subseconds >= 33554432); wire RTC_timestampNew = RTC_time[32]; wire [31:0] RTC_timestampIn = RTC_time[31:0]; @@ -147,9 +148,11 @@ reg [31:0] RTC_savedtimeIn = 0; reg RTC_saveLoaded = 0; reg rtc_change; +reg rtc_latch; reg RTC_saveLoaded_1; reg RTC_timestampNew_1; reg [31:0] diffSeconds; +wire diffSeconds_fast_count = (diffSeconds > 0 && ~rtc_change); reg reset_1; @@ -160,6 +163,7 @@ always @(posedge clk_sys) begin if(!reset_1 && reset) begin rtc_halt <= 1'b0; RTC_inuse <= 1'b0; + rtc_latch <= 1'b0; end else begin if (rtc_change == 1'b0) begin // when RTC hasn't changed recently, update the register which will be written after savegame @@ -199,10 +203,13 @@ always @(posedge clk_sys) begin RTC_inuse <= 1'b1; - end else if(cart_wr && (cart_addr[15:13] == 3'b101) && mbc3_mode == 1'b1) begin // setting RTC registers from game + end else if(ce_cpu && cart_wr && (cart_addr[15:13] == 3'b101) && mbc3_mode == 1'b1) begin // setting RTC registers from game case (rtc_index) - 0: rtc_seconds <= cart_di[5:0]; + 0: begin + rtc_seconds <= cart_di[5:0]; + rtc_subseconds <= 26'd0; + end 1: rtc_minutes <= cart_di[5:0]; 2: rtc_hours <= cart_di[4:0]; 3: rtc_days[7:0] <= cart_di; @@ -215,30 +222,49 @@ always @(posedge clk_sys) begin end else begin // normal counting - if (rtc_halt == 1'b0) begin - if (rtc_seconds >= 60) begin rtc_seconds <= 6'd0; rtc_minutes <= rtc_minutes + 1'd1; rtc_change <= 1'b1; end - if (rtc_minutes >= 60) begin rtc_minutes <= 6'd0; rtc_hours <= rtc_hours + 1'd1; rtc_change <= 1'b1; end - if (rtc_hours >= 24) begin rtc_hours <= 5'd0; rtc_days <= rtc_days + 1'd1; rtc_change <= 1'b1; end - if (rtc_days >= 512) begin rtc_days <= 10'd0; rtc_overflow <= 1'b1; rtc_change <= 1'b1; end + if (rtc_subseconds_end) begin + rtc_subseconds <= 26'd0; + 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 >= 33554432) begin - rtc_subseconds <= 26'd0; - RTC_timestampOut <= RTC_timestampOut + 1'd1; - if (rtc_halt == 1'b0) begin - rtc_seconds <= rtc_seconds + 1'd1; - rtc_change <= 1'b1; - end - end else if (diffSeconds > 0 && rtc_change == 1'b0) begin // fast counting loaded seconds - diffSeconds <= diffSeconds - 1'd1; - if (rtc_halt == 1'b0) begin - rtc_seconds <= rtc_seconds + 1'd1; - rtc_change <= 1'b1; + if (rtc_subseconds_end | diffSeconds_fast_count) begin + if (~rtc_halt) begin + rtc_change <= 1'b1; + rtc_seconds <= rtc_seconds + 1'd1; + if (rtc_seconds == 59) begin + rtc_seconds <= 6'd0; + rtc_minutes <= rtc_minutes + 1'd1; + if (rtc_minutes == 59) begin + rtc_minutes <= 6'd0; + rtc_hours <= rtc_hours + 1'd1; + if (rtc_hours == 23) begin + rtc_hours <= 5'd0; + rtc_days <= rtc_days + 1'd1; + if (rtc_days == 511) begin + rtc_days <= 10'd0; + rtc_overflow <= 1'b1; + end + end + end + end end end end + if(ce_cpu && cart_wr && (cart_addr[15:13] == 3'b011) && ~|cart_di[7:1]) begin // 6000-7FFF - Latch Clock Data + rtc_latch <= cart_di[0]; + if (~rtc_latch & cart_di[0]) begin + rtc_seconds_latch <= rtc_seconds; + rtc_minutes_latch <= rtc_minutes; + rtc_hours_latch <= rtc_hours; + rtc_days_latch <= rtc_days; + rtc_overflow_latch <= rtc_overflow; + end + end + RTC_timestampNew_1 <= RTC_timestampNew; // saving timestamp from HPS if (RTC_timestampNew != RTC_timestampNew_1) begin RTC_timestampOut <= RTC_timestampIn; @@ -248,11 +274,11 @@ always @(posedge clk_sys) begin end assign rtc_return = - (rtc_index == 0) ? rtc_seconds : - (rtc_index == 1) ? rtc_minutes : - (rtc_index == 2) ? rtc_hours : - (rtc_index == 3) ? rtc_days[7:0] : - (rtc_index == 4) ? {rtc_overflow, rtc_halt, 5'b00000, rtc_days[8]} : + (rtc_index == 0) ? rtc_seconds_latch : + (rtc_index == 1) ? rtc_minutes_latch : + (rtc_index == 2) ? rtc_hours_latch : + (rtc_index == 3) ? rtc_days_latch[7:0] : + (rtc_index == 4) ? {rtc_overflow_latch, rtc_halt, 5'b00000, rtc_days_latch[8]} : 8'hFF; endmodule \ No newline at end of file From 08e8724e63d12a0301ab9939f68ef0b8a9ce359b Mon Sep 17 00:00:00 2001 From: paulb-nl Date: Fri, 16 Apr 2021 19:16:13 +0200 Subject: [PATCH 2/2] Add MBC30 --- rtl/cart.v | 14 +++++++----- rtl/mappers/mappers.v | 2 ++ rtl/mappers/mbc3.v | 50 +++++++++++++++++++++---------------------- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/rtl/cart.v b/rtl/cart.v index 4898cb0..ab4da18 100644 --- a/rtl/cart.v +++ b/rtl/cart.v @@ -104,6 +104,7 @@ mappers mappers ( .mbc1m ( mbc1m ), .mbc2 ( mbc2 ), .mbc3 ( mbc3 ), + .mbc30( mbc30 ), .mbc5 ( mbc5 ), .mbc7 ( mbc7 ), .huc1 ( HuC1 ), @@ -162,11 +163,12 @@ reg [7:0] cart_old_licensee; reg [15:0] cart_logo_data[0:7]; // RAM size -wire [3:0] ram_mask = // 0 - no ram - (cart_ram_size == 1)?4'b0000: // 1 - 2k, 1 bank - (cart_ram_size == 2)?4'b0000: // 2 - 8k, 1 bank - (cart_ram_size == 3)?4'b0011: // 3 - 32k, 4 banks - 4'b1111; // 4 - 128k 16 banks +wire [3:0] ram_mask = // 0 - no ram + (cart_ram_size == 1)?4'b0000: // 1 - 2k, 1 bank + (cart_ram_size == 2)?4'b0000: // 2 - 8k, 1 bank + (cart_ram_size == 3)?4'b0011: // 3 - 32k, 4 banks + (cart_ram_size == 5)?4'b0111: // 5 - 64k, 8 banks + 4'b1111; // 4 - 128k 16 banks // ROM size wire [8:0] rom_mask = @@ -188,6 +190,7 @@ wire mbc1 = (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 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 mbc7 = (cart_mbc_type == 34); @@ -294,6 +297,7 @@ assign ram_mask_file = // 0 - no ram (cart_ram_size == 1)?8'h03: // 1 - 2k, 1 bank sd_lba[1:0] (cart_ram_size == 2)?8'h0F: // 2 - 8k, 1 bank sd_lba[3:0] (cart_ram_size == 3)?8'h3F: // 3 - 32k, 4 banks sd_lba[5:0] + (cart_ram_size == 5)?8'h7F: // 5 - 64k, 8 banks sd_lba[6:0] 8'hFF; // 4 - 128k 16 banks sd_lba[7:0] 1111 assign has_save = mbc_battery && (cart_ram_size > 0 || mbc2 || mbc7); diff --git a/rtl/mappers/mappers.v b/rtl/mappers/mappers.v index 3f6cf4c..369b7dd 100644 --- a/rtl/mappers/mappers.v +++ b/rtl/mappers/mappers.v @@ -10,6 +10,7 @@ module mappers( input mbc1m, input mbc2, input mbc3, + input mbc30, input mbc5, input mbc7, input huc1, @@ -131,6 +132,7 @@ mbc2 map_mbc2 ( mbc3 map_mbc3 ( .enable ( mbc3 ), .reset ( reset ), + .mbc30 ( mbc30 ), .clk_sys ( clk_sys ), .ce_cpu ( ce ), diff --git a/rtl/mappers/mbc3.v b/rtl/mappers/mbc3.v index 23dca77..1038f53 100644 --- a/rtl/mappers/mbc3.v +++ b/rtl/mappers/mbc3.v @@ -1,6 +1,7 @@ module mbc3 ( input enable, input reset, + input mbc30, input clk_sys, input ce_cpu, @@ -21,8 +22,8 @@ module mbc3 ( input [63:0] img_size, input has_ram, - input [1:0] ram_mask, - input [6:0] rom_mask, + input [2:0] ram_mask, + input [7:0] rom_mask, input [15:0] cart_addr, input [7:0] cart_mbc_type, @@ -53,52 +54,43 @@ 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; -wire [1:0] mbc3_ram_bank = mbc_ram_bank_reg[1:0] & ram_mask[1:0]; - -// 0x0000-0x3FFF = Bank 0 -wire [6:0] mbc_rom_bank = (cart_addr[15:14] == 2'b00) ? 7'd0 : mbc_rom_bank_reg; - -// mask address lines to enable proper mirroring -wire [6:0] mbc3_rom_bank = mbc_rom_bank[6:0] & rom_mask[6:0]; //128 - - // --------------------- CPU register interface ------------------ -reg [6:0] mbc_rom_bank_reg; -reg [1:0] mbc_ram_bank_reg; +reg [7:0] mbc_rom_bank_reg; +reg [2:0] mbc_ram_bank_reg; reg mbc_ram_enable; reg mbc3_mode; -assign savestate_back[ 6: 0] = mbc_rom_bank_reg; -assign savestate_back[ 8: 7] = 0; -assign savestate_back[10: 9] = mbc_ram_bank_reg; -assign savestate_back[13:11] = 0; +assign savestate_back[ 7: 0] = mbc_rom_bank_reg; +assign savestate_back[ 8] = 0; +assign savestate_back[11: 9] = mbc_ram_bank_reg; +assign savestate_back[13:12] = 0; assign savestate_back[ 14] = mbc3_mode; assign savestate_back[ 15] = mbc_ram_enable; always @(posedge clk_sys) begin if(savestate_load & enable) begin - mbc_rom_bank_reg <= savestate_data[ 6: 0]; //7'd1; - mbc_ram_bank_reg <= savestate_data[10: 9]; //2'd0; + mbc_rom_bank_reg <= savestate_data[ 7: 0]; //8'd1; + mbc_ram_bank_reg <= savestate_data[11: 9]; //3'd0; mbc3_mode <= savestate_data[ 14]; //1'b0; mbc_ram_enable <= savestate_data[ 15]; //1'b0; end else if(~enable) begin - mbc_rom_bank_reg <= 7'd1; - mbc_ram_bank_reg <= 2'd0; + mbc_rom_bank_reg <= 8'd1; + mbc_ram_bank_reg <= 3'd0; mbc3_mode <= 1'b0; mbc_ram_enable <= 1'b0; end else if(ce_cpu) begin if (cart_wr & ~cart_addr[15]) begin case(cart_addr[14:13]) 2'b00: mbc_ram_enable <= (cart_di[3:0] == 4'ha); //RAM enable/disable - 2'b01: mbc_rom_bank_reg <= (cart_di[6:0] == 7'd0) ? 7'd1 : cart_di[6:0]; //write to ROM bank register + 2'b01: mbc_rom_bank_reg <= ({cart_di[7] & mbc30, cart_di[6:0]} == 8'd0) ? 8'd1 : cart_di[7:0]; //write to ROM bank register 2'b10: begin if (cart_di[3]) begin mbc3_mode <= 1'b1; //enable RTC rtc_index <= cart_di[2:0]; end else begin mbc3_mode <= 1'b0; //enable RAM - mbc_ram_bank_reg <= cart_di[1:0]; //write to RAM bank register + mbc_ram_bank_reg <= cart_di[2:0]; //write to RAM bank register end end 2'b11: ; // Latch RTC data. Done below @@ -107,7 +99,15 @@ always @(posedge clk_sys) begin end end -assign mbc_bank = { 2'b00, mbc3_rom_bank, cart_addr[13] }; // 16k ROM Bank 0-127 +wire [2:0] mbc3_ram_bank = mbc_ram_bank_reg[2:0] & ram_mask[2:0]; + +// 0x0000-0x3FFF = Bank 0 +wire [7:0] mbc_rom_bank = (cart_addr[15:14] == 2'b00) ? 8'd0 : mbc_rom_bank_reg; + +// mask address lines to enable proper mirroring +wire [7:0] mbc3_rom_bank = mbc_rom_bank[7:0] & rom_mask[7:0]; // 16k ROM Bank 0-127, MBC30: 0-255 + +assign mbc_bank = { 1'b0, mbc3_rom_bank, cart_addr[13] }; reg [7:0] cram_do_r; always @* begin @@ -121,7 +121,7 @@ always @* begin end assign cram_do = cram_do_r; -assign cram_addr = { 2'b00, mbc3_ram_bank, cart_addr[12:0] }; +assign cram_addr = { 1'b0, mbc3_ram_bank, cart_addr[12:0] }; assign has_battery = (cart_mbc_type == 8'h0F || cart_mbc_type == 8'h10 || cart_mbc_type == 8'h13); assign ram_enabled = mbc_ram_enable & has_ram;