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

Add -rtcdate option to set initial date and/or time for RTCs #12915

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
17 changes: 17 additions & 0 deletions docs/source/commandline/commandline-all.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4068,6 +4068,23 @@ Core Misc Options

mame galaga88 -nonvram_save

.. _mame-commandline-rtcdate:

**-rtcdate** *<string>*

Specify a date and/or time to initialize real-time clock devices to (for
systems that have one) at the start of machine emulation. The full format is
``YYYY-MM-DD hh:mm:ss``, though either the date or time may be omitted
altogether (in which case the system date or time will be used), the seconds
may be omitted (defaulting to zero), or the year may be specified alone.

Note that four-digit years must be specified here, even though RTC devices
in emulated systems might not keep track of the century.

Example:
.. code-block:: bash

mame a1010 -rtcdate 23:59:50

.. _mame-commandline-scripting:

Expand Down
5 changes: 4 additions & 1 deletion scripts/src/emu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ files {
MAME_DIR .. "src/emu/emuopts.h",
MAME_DIR .. "src/emu/emupal.cpp",
MAME_DIR .. "src/emu/emupal.h",
MAME_DIR .. "src/emu/emutime.cpp",
MAME_DIR .. "src/emu/emutime.h",
MAME_DIR .. "src/emu/fileio.cpp",
MAME_DIR .. "src/emu/fileio.h",
MAME_DIR .. "src/emu/http.h",
Expand Down Expand Up @@ -273,8 +275,9 @@ files {
}

pchsource(MAME_DIR .. "src/emu/main.cpp")
-- 2 files do not include emu.h
-- 3 files do not include emu.h
nopch(MAME_DIR .. "src/emu/attotime.cpp")
nopch(MAME_DIR .. "src/emu/emutime.cpp")
nopch(MAME_DIR .. "src/emu/debug/textbuf.cpp")

dependency {
Expand Down
1 change: 1 addition & 0 deletions src/devices/bus/gameboy/huc3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
#include "gbxfile.h"

#include "dirtc.h"
#include "emutime.h"

#include <algorithm>
#include <cassert>
Expand Down
1 change: 1 addition & 0 deletions src/devices/bus/gameboy/mbc3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
#include "gbxfile.h"

#include "dirtc.h"
#include "emutime.h"

#include "corestr.h"

Expand Down
8 changes: 5 additions & 3 deletions src/devices/bus/gba/rom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "emu.h"
#include "rom.h"

#include "emutime.h"


//-------------------------------------------------
// gba_rom_device - constructor
Expand Down Expand Up @@ -820,9 +822,9 @@ void gba_s3511_device::update_time(int len)
if (len == 7)
{
m_data[0] = convert_to_bcd(curtime.local_time.year);
m_data[1] = convert_to_bcd(curtime.local_time.month + 1);
m_data[2] = convert_to_bcd(curtime.local_time.mday);
m_data[3] = convert_to_bcd(curtime.local_time.weekday);
m_data[1] = convert_to_bcd(curtime.local_time.month);
m_data[2] = convert_to_bcd(curtime.local_time.day_of_month);
m_data[3] = curtime.local_time.day_of_week();
m_data[4] = convert_to_bcd(curtime.local_time.hour);
m_data[5] = convert_to_bcd(curtime.local_time.minute);
m_data[6] = convert_to_bcd(curtime.local_time.second);
Expand Down
2 changes: 2 additions & 0 deletions src/devices/bus/snes/bsx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "emu.h"
#include "bsx.h"

#include "emutime.h"


//-------------------------------------------------
// sns_rom_bsx_device - constructor
Expand Down
8 changes: 5 additions & 3 deletions src/devices/bus/snes/rom21.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "emu.h"
#include "rom21.h"

#include "emutime.h"


//-------------------------------------------------
// sns_rom_device - constructor
Expand Down Expand Up @@ -110,13 +112,13 @@ void sns_rom21_srtc_device::update_time()
m_rtc_ram[3] = systime->local_time.minute / 10;
m_rtc_ram[4] = systime->local_time.hour % 10;
m_rtc_ram[5] = systime->local_time.hour / 10;
m_rtc_ram[6] = systime->local_time.mday % 10;
m_rtc_ram[7] = systime->local_time.mday / 10;
m_rtc_ram[6] = systime->local_time.day_of_month % 10;
m_rtc_ram[7] = systime->local_time.day_of_month / 10;
m_rtc_ram[8] = systime->local_time.month;
m_rtc_ram[9] = (systime->local_time.year - 1000) % 10;
m_rtc_ram[10] = ((systime->local_time.year - 1000) / 10) % 10;
m_rtc_ram[11] = (systime->local_time.year - 1000) / 100;
m_rtc_ram[12] = systime->local_time.weekday % 7;
m_rtc_ram[12] = systime->local_time.day_of_week();
}

// Returns day-of-week for specified date
Expand Down
2 changes: 2 additions & 0 deletions src/devices/bus/snes/spc7110.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "snes_slot.h"
#include "rom21.h"

#include "emutime.h"


// ======================> sns_rom_spc7110_device

Expand Down
10 changes: 7 additions & 3 deletions src/devices/machine/ds1315.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

#include "emu.h"
#include "ds1315.h"

#include "emutime.h"

#include "coreutil.h"


Expand Down Expand Up @@ -204,9 +207,10 @@ void ds1315_device::fill_raw_data()
raw[2] = dec_2_bcd(systime.local_time.minute);
raw[3] = dec_2_bcd(systime.local_time.hour);

raw[4] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
raw[5] = dec_2_bcd(systime.local_time.mday);
raw[6] = dec_2_bcd(systime.local_time.month + 1);
int weekday = systime.local_time.day_of_week();
raw[4] = (weekday != 0) ? weekday : 7;
raw[5] = dec_2_bcd(systime.local_time.day_of_month);
raw[6] = dec_2_bcd(systime.local_time.month);
raw[7] = dec_2_bcd(systime.local_time.year - 1900); /* Epoch is 1900 */

/* Ok now we have the raw bcd bytes. Now we need to push them into our bit array */
Expand Down
2 changes: 2 additions & 0 deletions src/devices/machine/mccs1850.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "emu.h"
#include "mccs1850.h"

#include "emutime.h"

#include "multibyte.h"

//#define VERBOSE 0
Expand Down
2 changes: 2 additions & 0 deletions src/devices/machine/spg2xx_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "emu.h"
#include "spg2xx_io.h"

#include "emutime.h"

DEFINE_DEVICE_TYPE(SPG24X_IO, spg24x_io_device, "spg24x_io", "SPG240-series System-on-a-Chip I/O")
DEFINE_DEVICE_TYPE(SPG28X_IO, spg28x_io_device, "spg28x_io", "SPG280-series System-on-a-Chip I/O")

Expand Down
6 changes: 4 additions & 2 deletions src/emu/dirtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "emu.h"
#include "dirtc.h"

#include "emutime.h"


//**************************************************************************
// MACROS / CONSTANTS
Expand Down Expand Up @@ -79,8 +81,8 @@ void device_rtc_interface::set_time(bool update, int year, int month, int day, i

void device_rtc_interface::set_current_time(const system_time &systime)
{
const system_time::full_time &time = m_use_utc ? systime.utc_time : systime.local_time;
set_time(true, time.year, time.month + 1, time.mday, time.weekday + 1,
const util::arbitrary_datetime &time = m_use_utc ? systime.utc_time : systime.local_time;
set_time(true, time.year, time.month, time.day_of_month, time.day_of_week() + 1,
time.hour, time.minute, time.second);
}

Expand Down
3 changes: 3 additions & 0 deletions src/emu/emufwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ class memory_view;
// declared in emuopts.h
class emu_options;

// declared in emutime.h
class system_time;

// declared in fileio.h
class emu_file;

Expand Down
1 change: 1 addition & 0 deletions src/emu/emuopts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ const options_entry emu_options::s_option_entries[] =
{ OPTION_UI_MOUSE, "1", core_options::option_type::BOOLEAN, "display UI mouse cursor" },
{ OPTION_LANGUAGE ";lang", "", core_options::option_type::STRING, "set UI display language" },
{ OPTION_NVRAM_SAVE ";nvwrite", "1", core_options::option_type::BOOLEAN, "save NVRAM data on exit" },
{ OPTION_RTCDATE, "", core_options::option_type::STRING, "set RTC to a given date and/or time at start" },

{ nullptr, nullptr, core_options::option_type::HEADER, "SCRIPTING OPTIONS" },
{ OPTION_AUTOBOOT_COMMAND ";ab", nullptr, core_options::option_type::STRING, "command to execute after machine boot" },
Expand Down
2 changes: 2 additions & 0 deletions src/emu/emuopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
#define OPTION_UI "ui"
#define OPTION_RAMSIZE "ramsize"
#define OPTION_NVRAM_SAVE "nvram_save"
#define OPTION_RTCDATE "rtcdate"

// core comm options
#define OPTION_COMM_LOCAL_HOST "comm_localhost"
Expand Down Expand Up @@ -456,6 +457,7 @@ class emu_options : public core_options
ui_option ui() const { return m_ui; }
const char *ram_size() const { return value(OPTION_RAMSIZE); }
bool nvram_save() const { return bool_value(OPTION_NVRAM_SAVE); }
const char *rtcdate() const { return value(OPTION_RTCDATE); }

// core comm options
const char *comm_localhost() const { return value(OPTION_COMM_LOCAL_HOST); }
Expand Down
134 changes: 134 additions & 0 deletions src/emu/emutime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

emutime.cpp

System time utilities for MAME.

***************************************************************************/

#include "emutime.h"
#include "osdcore.h"


//**************************************************************************
// SYSTEM TIME
//**************************************************************************

//-------------------------------------------------
// system_time - constructor
//-------------------------------------------------

system_time::system_time()
{
set(0);
}

system_time::system_time(time_t t)
{
set(t);
}


//-------------------------------------------------
// set - fills out a system_time structure
//-------------------------------------------------

void system_time::set(time_t t)
{
// FIXME: this crashes if localtime or gmtime returns nullptr
time = t;
local_time = util::arbitrary_datetime(*localtime(&t));
utc_time = util::arbitrary_datetime(*gmtime(&t));
}


//-------------------------------------------------
// customize - check whether string conforms to
// YYYY-MM-DD hh:mm:ss format and modify date
// and/or time if it does
//-------------------------------------------------

bool system_time::customize(std::string_view str)
{
int yr = -1, mo = -1, dy = -1, hh = -1, mm = -1, ss = -1;
if (str.length() >= 4 && str.find_first_not_of("0123456789") >= 4)
{
yr = (str[0] - '0') * 1000 + (str[1] - '0') * 100 + (str[2] - '0') * 10 + (str[3] - '0');
if (str.length() == 4)
str = std::string_view();
else
{
if (str.length() < 10 || str[4] != str[7] || str[4] != '-')
return false;
if (str[5] < '0' || str[5] > '1' || str[6] < (str[5] == '0' ? '1' : '0') || str[6] > (str[5] == '1' ? '2' : '9'))
return false;
if (str[8] < '0' || str[8] > '3' || str[9] < (str[8] == '0' ? '1' : '0') || str[9] > (str[8] == '3' ? '1' : '9'))
return false;
mo = (str[5] - '0') * 10 + (str[6] - '0');
dy = (str[8] - '0') * 10 + (str[9] - '0');
if (str.length() == 10)
str = std::string_view();
else
{
auto pos = str.find_first_not_of(' ', 10);
if (pos > 10 && pos != std::string_view::npos)
str.remove_prefix(pos);
else
return false;
}
}
}
if (!str.empty())
{
if (str.length() < 5 || str[2] != ':')
return false;
if (str[0] < '0' || str[0] > '2' || str[1] < '0' || (str[1] > (str[0] == '2' ? '3' : '9')))
return false;
if (str[3] < '0' || str[3] > '5' || str[4] < '0' || str[4] > '9')
return false;
hh = (str[0] - '0') * 10 + (str[1] - '0');
mm = (str[3] - '0') * 10 + (str[4] - '0');
ss = 0;
if (str.length() != 5)
{
if (str.length() != 8 || str[5] != ':')
return false;
if (str[6] < '0' || str[6] > '5' || str[7] < '0' || str[7] > '9')
return false;
ss = (str[6] - '0') * 10 + (str[7] - '0');
}
}

if (yr != -1)
{
local_time.year = utc_time.year = yr;
if (mo != -1)
{
local_time.month = utc_time.month = mo;
local_time.day_of_month = utc_time.day_of_month = dy;
}
else if (!gregorian_is_leap_year(yr))
{
// Mitigate potential problems of having Leap Day in a non-leap year
if (local_time.month == 2 && local_time.day_of_month == 29)
{
local_time.month = 3;
local_time.day_of_month = 1;
}
if (utc_time.month == 2 && utc_time.day_of_month == 29)
{
utc_time.month = 3;
utc_time.day_of_month = 1;
}
}
}
if (hh != -1)
{
local_time.hour = utc_time.hour = hh;
local_time.minute = utc_time.minute = mm;
local_time.second = utc_time.second = ss;
}
return true;
}
Loading
Loading