Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Gameboy.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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 ),

Expand Down Expand Up @@ -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 ),
Expand Down
2 changes: 2 additions & 0 deletions rtl/cart.v
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 ),
Expand Down
9 changes: 5 additions & 4 deletions rtl/mappers/huc3.v
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion rtl/mappers/mappers.v
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 ),
Expand Down Expand Up @@ -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 ),
Expand Down Expand Up @@ -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 ),
Expand All @@ -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 ),
Expand Down
15 changes: 8 additions & 7 deletions rtl/mappers/mbc3.v
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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];
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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];
Expand All @@ -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;
Expand Down
98 changes: 50 additions & 48 deletions rtl/mappers/tama.v
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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 (|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 (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
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
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 else begin // RAM
cram_wr_r <= ~ram_read;
ram_io <= 1;
end
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
Expand Down