mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-04-19 03:04:09 +00:00
MBC3: Pause RTC subsecond counter when halted. (rtc3test) (#214)
Also change to 32768Hz clock enable for RTC
This commit is contained in:
@@ -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 ),
|
||||
|
||||
@@ -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 ),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user