MBC3: Pause RTC subsecond counter when halted. (rtc3test) (#214)

Also change to 32768Hz clock enable for RTC
This commit is contained in:
paulb-nl
2022-10-17 10:17:35 +02:00
committed by GitHub
parent 2ad3e08dd1
commit f1cd3472b0
6 changed files with 79 additions and 60 deletions

View File

@@ -457,6 +457,13 @@ wire [2:0] mapper_sel = status[41:39];
assign joy0_rumble = {8'd0, ((rumbling & ~status[38]) ? 8'd128 : 8'd0)};
reg ce_32k; // 32768Hz clock for RTC
reg [9:0] ce_32k_div;
always @(posedge clk_sys) begin
ce_32k_div <= ce_32k_div + 1'b1;
ce_32k <= !ce_32k_div;
end
cart_top cart (
.reset ( reset ),
@@ -511,6 +518,7 @@ cart_top cart (
.joystick_analog_0 ( joystick_analog_0 ),
.ce_32k ( ce_32k ),
.RTC_time ( RTC_time ),
.RTC_timestampOut ( RTC_timestampOut ),
.RTC_savedtimeOut ( RTC_savedtimeOut ),

View File

@@ -52,6 +52,7 @@ module cart_top (
input [15:0] joystick_analog_0,
input ce_32k,
input [32:0] RTC_time,
output [31:0] RTC_timestampOut,
output [47:0] RTC_savedtimeOut,
@@ -133,6 +134,7 @@ mappers mappers (
.joystick_analog_0 ( joystick_analog_0 ),
.ce_32k ( ce_32k ),
.RTC_time ( RTC_time ),
.RTC_timestampOut ( RTC_timestampOut ),
.RTC_savedtimeOut ( RTC_savedtimeOut ),

View File

@@ -8,6 +8,7 @@ module huc3 (
input [63:0] savestate_data,
inout [63:0] savestate_back_b,
input ce_32k,
input [32:0] RTC_time,
inout [31:0] RTC_timestampOut_b,
inout [47:0] RTC_savedtimeOut_b,
@@ -105,7 +106,7 @@ 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 [14:0] rtc_subseconds;
reg [11:0] rtc_minutes; // Minutes of the day 0-1439
reg [15:0] rtc_days;
@@ -119,15 +120,15 @@ reg [31:0] diffSeconds;
wire diffSeconds_fast_count = (diffSeconds > 0);
always @(posedge clk_sys) begin
rtc_subseconds <= rtc_subseconds + 1'b1;
if (ce_32k) rtc_subseconds <= rtc_subseconds + 1'b1;
if (rtc_subseconds_end) begin
if (ce_32k & 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
if ((ce_32k & rtc_subseconds_end) | diffSeconds_fast_count) begin
rtc_seconds <= rtc_seconds + 1'b1;
if (rtc_seconds == 59) begin
rtc_seconds <= 0;

View File

@@ -30,6 +30,7 @@ module mappers(
input [15:0] joystick_analog_0,
input ce_32k,
input [32:0] RTC_time,
output [31:0] RTC_timestampOut,
output [47:0] RTC_savedtimeOut,
@@ -177,6 +178,7 @@ mbc3 map_mbc3 (
.savestate_data ( savestate_data ),
.savestate_back_b ( savestate_back_b ),
.ce_32k ( ce_32k ),
.RTC_time ( RTC_time ),
.RTC_timestampOut_b( RTC_timestampOut_b ),
.RTC_savedtimeOut_b( RTC_savedtimeOut_b ),
@@ -394,6 +396,7 @@ huc3 map_huc3 (
.savestate_data ( savestate_data2 ),
.savestate_back_b ( savestate_back2_b ),
.ce_32k ( ce_32k ),
.RTC_time ( RTC_time ),
.RTC_timestampOut_b( RTC_timestampOut_b ),
.RTC_savedtimeOut_b( RTC_savedtimeOut_b ),
@@ -468,7 +471,7 @@ tama map_tama (
.clk_sys ( clk_sys ),
.ce_cpu ( ce ),
.ce_1x ( ce_cpu ),
.ce_32k ( ce_32k ),
.savestate_load ( savestate_load ),
.savestate_data ( savestate_data2 ),
@@ -488,6 +491,8 @@ tama map_tama (
.cart_di ( cart_di ),
.cart_oe_b ( cart_oe_b ),
.nCS ( nCS ),
.cram_rd ( cram_rd ),
.cram_di ( cram_di ),
.cram_do_b ( cram_do_b ),

View File

@@ -10,6 +10,7 @@ module mbc3 (
input [15:0] savestate_data,
inout [15:0] savestate_back_b,
input ce_32k,
input [32:0] RTC_time,
inout [31:0] RTC_timestampOut_b,
inout [47:0] RTC_savedtimeOut_b,
@@ -147,7 +148,7 @@ assign ram_enabled = mbc_ram_enable & ~mbc3_mode & has_ram;
///////////////////////////// RTC ///////////////////////////////
reg [2:0] rtc_index;
reg [25:0] rtc_subseconds;
reg [15:0] rtc_subseconds;
reg [5:0] rtc_seconds, rtc_seconds_latch;
reg [5:0] rtc_minutes, rtc_minutes_latch;
reg [4:0] rtc_hours, rtc_hours_latch;
@@ -156,7 +157,7 @@ reg rtc_overflow, rtc_overflow_latch;
reg rtc_halt;
wire [7:0] rtc_return;
wire rtc_subseconds_end = (rtc_subseconds >= 33554432);
wire rtc_subseconds_end = (rtc_subseconds >= 32768-1);
wire RTC_timestampNew = RTC_time[32];
wire [31:0] RTC_timestampIn = RTC_time[31:0];
@@ -189,7 +190,7 @@ always @(posedge clk_sys) begin
end
rtc_change <= 1'b0;
rtc_subseconds <= rtc_subseconds + 1'd1;
if (ce_32k & ~rtc_halt) rtc_subseconds <= rtc_subseconds + 1'd1;
if (mbc3_mode || (bk_wr && enable && img_size[9])) begin // RTC is either used by game or already used in savegame
RTC_inuse <= 1'b1;
@@ -226,7 +227,7 @@ always @(posedge clk_sys) begin
case (rtc_index)
0: begin
rtc_seconds <= cart_di[5:0];
rtc_subseconds <= 26'd0;
rtc_subseconds <= 0;
end
1: rtc_minutes <= cart_di[5:0];
2: rtc_hours <= cart_di[4:0];
@@ -240,14 +241,14 @@ always @(posedge clk_sys) begin
end else begin // normal counting
if (rtc_subseconds_end) begin
rtc_subseconds <= 26'd0;
if (ce_32k & rtc_subseconds_end) begin
rtc_subseconds <= 0;
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
if ((ce_32k & rtc_subseconds_end) | diffSeconds_fast_count) begin
if (~rtc_halt) begin
rtc_change <= 1'b1;
rtc_seconds <= rtc_seconds + 1'd1;

View File

@@ -3,7 +3,7 @@ module tama (
input clk_sys,
input ce_cpu,
input ce_1x,
input ce_32k,
input savestate_load,
input [63:0] savestate_data,
@@ -74,7 +74,7 @@ reg ram_io;
reg prev_cram_rd;
reg [6:0] rtc_seconds;
reg [21:0] rtc_subseconds;
reg [14:0] rtc_subseconds;
reg [6:0] rtc_minutes;
reg [5:0] rtc_hours;
reg [5:0] rtc_days;
@@ -84,7 +84,7 @@ reg rtc_24hours;
reg [3:0] rtc_index;
reg [1:0] rtc_leap_year;
wire sec_inc = &rtc_subseconds; // 4Mhz
wire sec_inc = &rtc_subseconds;
reg [5:0] days_in_month;
always @* begin
@@ -136,9 +136,9 @@ always @(posedge clk_sys) begin
cram_wr_r <= 1'd0;
ram_io <= 1'd0;
prev_cram_rd <= 1'd0;
end else if(ce_cpu) begin
end else begin
if (cart_wr & ~nCS & ~cart_addr[14]) begin // $A000-BFFF
if (ce_cpu & cart_wr & ~nCS & ~cart_addr[14]) begin // $A000-BFFF
if (cart_addr[0]) begin
reg_index <= cart_di[3:0]; // Register index
if (cart_di[3:0] == 4'hA) begin
@@ -163,7 +163,7 @@ always @(posedge clk_sys) begin
// TODO: Get RTC working. How does the game use the RTC?
// The in game timer runs at ~16x speed so 1 minute passes every 3.75 seconds.
// Does the RTC also run 16x speed or only when the Game Boy is on?
if (ce_1x) begin
if (ce_32k) begin
rtc_subseconds <= rtc_subseconds + 1'b1;
if (sec_inc) begin
rtc_seconds[3:0] <= rtc_seconds[3:0] + 1'b1;
@@ -226,53 +226,55 @@ always @(posedge clk_sys) begin
end
end
cram_wr_r <= 0;
ram_io <= 0;
if (reg_start) begin
reg_start <= 0;
if (ce_cpu) begin
cram_wr_r <= 0;
ram_io <= 0;
if (reg_start) begin
reg_start <= 0;
if (|rtc_sel) begin // RTC
if (rtc_sel == 2'd1) begin
case (reg_addr)
5'h04: begin
rtc_minutes <= reg_data_in[6:0];
rtc_seconds <= 0;
rtc_subseconds <= 0;
end
5'h05: rtc_hours <= reg_data_in[5:0];
5'h06: rtc_index <= 0;
default: ;
endcase
if (|rtc_sel) begin // RTC
if (rtc_sel == 2'd1) begin
case (reg_addr)
5'h04: begin
rtc_minutes <= reg_data_in[6:0];
rtc_seconds <= 0;
rtc_subseconds <= 0;
end
5'h05: rtc_hours <= reg_data_in[5:0];
5'h06: rtc_index <= 0;
default: ;
endcase
end
if (rtc_sel == 2'd2) begin
case ({reg_addr,reg_data_in[3:0]})
{2'd0, 4'h7}: rtc_days[3:0] <= reg_data_in[7:4];
{2'd0, 4'h8}: rtc_days[5:4] <= reg_data_in[5:4];
{2'd0, 4'h9}: rtc_month[3:0] <= reg_data_in[7:4];
{2'd0, 4'hA}: rtc_month[4] <= reg_data_in[4];
{2'd0, 4'hB}: rtc_year[3:0] <= reg_data_in[7:4];
{2'd0, 4'hC}: rtc_year[7:4] <= reg_data_in[7:4];
{2'd2, 4'hA}: rtc_24hours <= reg_data_in[4];
{2'd2, 4'hB}: rtc_leap_year <= reg_data_in[5:4];
default: ;
endcase
end
end else begin // RAM
cram_wr_r <= ~ram_read;
ram_io <= 1;
end
if (rtc_sel == 2'd2) begin
case ({reg_addr,reg_data_in[3:0]})
{2'd0, 4'h7}: rtc_days[3:0] <= reg_data_in[7:4];
{2'd0, 4'h8}: rtc_days[5:4] <= reg_data_in[5:4];
{2'd0, 4'h9}: rtc_month[3:0] <= reg_data_in[7:4];
{2'd0, 4'hA}: rtc_month[4] <= reg_data_in[4];
{2'd0, 4'hB}: rtc_year[3:0] <= reg_data_in[7:4];
{2'd0, 4'hC}: rtc_year[7:4] <= reg_data_in[7:4];
{2'd2, 4'hA}: rtc_24hours <= reg_data_in[4];
{2'd2, 4'hB}: rtc_leap_year <= reg_data_in[5:4];
default: ;
endcase
end
end else begin // RAM
cram_wr_r <= ~ram_read;
ram_io <= 1;
end
end
if (ram_io & ram_read) begin
reg_data_out <= cram_di;
end
if (ram_io & ram_read) begin
reg_data_out <= cram_di;
end
prev_cram_rd <= cram_rd;
if (prev_cram_rd & ~cram_rd & ~cart_addr[0] & |rtc_sel & reg_index[3:1] == 3'b110) begin
rtc_index <= rtc_index + 1'b1;
prev_cram_rd <= cram_rd;
if (prev_cram_rd & ~cram_rd & ~cart_addr[0] & |rtc_sel & reg_index[3:1] == 3'b110) begin
rtc_index <= rtc_index + 1'b1;
end
end
end
end