mirror of
https://github.com/holub/mame
synced 2025-05-12 09:08:53 +03:00
Imported RP5C15 RTC from MESS. (no whatsnew)
This commit is contained in:
parent
62335e3a06
commit
c39297ce17
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -866,6 +866,8 @@ src/emu/machine/roc10937.c svneol=native#text/plain
|
|||||||
src/emu/machine/roc10937.h svneol=native#text/plain
|
src/emu/machine/roc10937.h svneol=native#text/plain
|
||||||
src/emu/machine/rp5c01.c svneol=native#text/plain
|
src/emu/machine/rp5c01.c svneol=native#text/plain
|
||||||
src/emu/machine/rp5c01.h svneol=native#text/plain
|
src/emu/machine/rp5c01.h svneol=native#text/plain
|
||||||
|
src/emu/machine/rp5c15.c svneol=native#text/plain
|
||||||
|
src/emu/machine/rp5c15.h svneol=native#text/plain
|
||||||
src/emu/machine/rp5h01.c svneol=native#text/plain
|
src/emu/machine/rp5h01.c svneol=native#text/plain
|
||||||
src/emu/machine/rp5h01.h svneol=native#text/plain
|
src/emu/machine/rp5h01.h svneol=native#text/plain
|
||||||
src/emu/machine/rtc65271.c svneol=native#text/plain
|
src/emu/machine/rtc65271.c svneol=native#text/plain
|
||||||
|
@ -208,6 +208,7 @@ EMUMACHINEOBJS = \
|
|||||||
$(EMUMACHINE)/ram.o \
|
$(EMUMACHINE)/ram.o \
|
||||||
$(EMUMACHINE)/roc10937.o \
|
$(EMUMACHINE)/roc10937.o \
|
||||||
$(EMUMACHINE)/rp5c01.o \
|
$(EMUMACHINE)/rp5c01.o \
|
||||||
|
$(EMUMACHINE)/rp5c15.o \
|
||||||
$(EMUMACHINE)/rp5h01.o \
|
$(EMUMACHINE)/rp5h01.o \
|
||||||
$(EMUMACHINE)/rtc65271.o \
|
$(EMUMACHINE)/rtc65271.o \
|
||||||
$(EMUMACHINE)/s3c2400.o \
|
$(EMUMACHINE)/s3c2400.o \
|
||||||
|
@ -293,6 +293,26 @@ inline void rp5c01_device::advance_minutes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// adjust_seconds -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline void rp5c01_device::adjust_seconds()
|
||||||
|
{
|
||||||
|
int seconds = read_counter(REGISTER_1_SECOND);
|
||||||
|
|
||||||
|
if (seconds < 30)
|
||||||
|
{
|
||||||
|
write_counter(REGISTER_1_SECOND, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
write_counter(REGISTER_1_SECOND, 0);
|
||||||
|
advance_minutes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// check_alarm -
|
// check_alarm -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
@ -427,17 +447,7 @@ WRITE_LINE_MEMBER( rp5c01_device::adj_w )
|
|||||||
{
|
{
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
int seconds = read_counter(REGISTER_1_SECOND);
|
adjust_seconds();
|
||||||
|
|
||||||
if (seconds < 30)
|
|
||||||
{
|
|
||||||
write_counter(REGISTER_1_SECOND, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write_counter(REGISTER_1_SECOND, 0);
|
|
||||||
advance_minutes();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +109,7 @@ private:
|
|||||||
inline void write_counter(int counter, int value);
|
inline void write_counter(int counter, int value);
|
||||||
inline void advance_seconds();
|
inline void advance_seconds();
|
||||||
inline void advance_minutes();
|
inline void advance_minutes();
|
||||||
|
inline void adjust_seconds();
|
||||||
inline void check_alarm();
|
inline void check_alarm();
|
||||||
|
|
||||||
static const device_timer_id TIMER_CLOCK = 0;
|
static const device_timer_id TIMER_CLOCK = 0;
|
||||||
|
571
src/emu/machine/rp5c15.c
Normal file
571
src/emu/machine/rp5c15.c
Normal file
@ -0,0 +1,571 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
|
||||||
|
Ricoh RP5C15 Real Time Clock emulation
|
||||||
|
|
||||||
|
Copyright MESS Team.
|
||||||
|
Visit http://mamedev.org for licensing and usage restrictions.
|
||||||
|
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
- 12 hour clock
|
||||||
|
- test register
|
||||||
|
- timer reset
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp5c15.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// MACROS / CONSTANTS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
#define LOG 0
|
||||||
|
|
||||||
|
|
||||||
|
// registers
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
REGISTER_1_SECOND = 0, REGISTER_CLOCK_OUTPUT = REGISTER_1_SECOND,
|
||||||
|
REGISTER_10_SECOND, REGISTER_ADJUST = REGISTER_10_SECOND,
|
||||||
|
REGISTER_1_MINUTE,
|
||||||
|
REGISTER_10_MINUTE,
|
||||||
|
REGISTER_1_HOUR,
|
||||||
|
REGISTER_10_HOUR,
|
||||||
|
REGISTER_DAY_OF_THE_WEEK,
|
||||||
|
REGISTER_1_DAY,
|
||||||
|
REGISTER_10_DAY,
|
||||||
|
REGISTER_1_MONTH,
|
||||||
|
REGISTER_10_MONTH, REGISTER_12_24_SELECT = REGISTER_10_MONTH,
|
||||||
|
REGISTER_1_YEAR, REGISTER_LEAP_YEAR = REGISTER_1_YEAR,
|
||||||
|
REGISTER_10_YEAR,
|
||||||
|
REGISTER_MODE,
|
||||||
|
REGISTER_TEST,
|
||||||
|
REGISTER_RESET
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// clock output select
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CLKOUT_Z = 0,
|
||||||
|
CLKOUT_16384_HZ,
|
||||||
|
CLKOUT_1024_HZ,
|
||||||
|
CLKOUT_128_HZ,
|
||||||
|
CLKOUT_16_HZ,
|
||||||
|
CLKOUT_1_HZ,
|
||||||
|
CLKOUT_1_DIV_60_HZ,
|
||||||
|
CLKOUT_L
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// register write mask
|
||||||
|
static const int REGISTER_WRITE_MASK[2][16] =
|
||||||
|
{
|
||||||
|
{ 0xf, 0x7, 0xf, 0x7, 0xf, 0x3, 0x7, 0xf, 0x3, 0xf, 0x1, 0xf, 0xf, 0xf, 0xf, 0xf },
|
||||||
|
{ 0x3, 0x1, 0xf, 0x7, 0xf, 0x3, 0x7, 0xf, 0x3, 0x0, 0x1, 0x3, 0x0, 0xf, 0xf, 0xf }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// days per month
|
||||||
|
static const int DAYS_PER_MONTH[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
|
|
||||||
|
|
||||||
|
// modes
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MODE00 = 0,
|
||||||
|
MODE01
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// mode register
|
||||||
|
#define MODE_TIMER_EN 0x08
|
||||||
|
#define MODE_ALARM_EN 0x04
|
||||||
|
#define MODE_MASK 0x01
|
||||||
|
|
||||||
|
|
||||||
|
// test register
|
||||||
|
#define TEST_3 0x08
|
||||||
|
#define TEST_2 0x04
|
||||||
|
#define TEST_1 0x02
|
||||||
|
#define TEST_0 0x01
|
||||||
|
|
||||||
|
|
||||||
|
// reset register
|
||||||
|
#define RESET_ALARM 0x08
|
||||||
|
#define RESET_TIMER 0x04
|
||||||
|
#define RESET_16_HZ 0x02
|
||||||
|
#define RESET_1_HZ 0x01
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// GLOBAL VARIABLES
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// devices
|
||||||
|
const device_type RP5C15 = rp5c15_device_config::static_alloc_device_config;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// DEVICE CONFIGURATION
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// rp5c15_device_config - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
rp5c15_device_config::rp5c15_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
|
||||||
|
: device_config(mconfig, static_alloc_device_config, "RP5C15", tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// static_alloc_device_config - allocate a new
|
||||||
|
// configuration object
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
device_config *rp5c15_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
|
||||||
|
{
|
||||||
|
return global_alloc(rp5c15_device_config(mconfig, tag, owner, clock));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// alloc_device - allocate a new device object
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
device_t *rp5c15_device_config::alloc_device(running_machine &machine) const
|
||||||
|
{
|
||||||
|
return auto_alloc(machine, rp5c15_device(machine, *this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_config_complete - perform any
|
||||||
|
// operations now that the configuration is
|
||||||
|
// complete
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void rp5c15_device_config::device_config_complete()
|
||||||
|
{
|
||||||
|
// inherit a copy of the static data
|
||||||
|
const rp5c15_interface *intf = reinterpret_cast<const rp5c15_interface *>(static_config());
|
||||||
|
if (intf != NULL)
|
||||||
|
*static_cast<rp5c15_interface *>(this) = *intf;
|
||||||
|
|
||||||
|
// or initialize to defaults if none provided
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(&m_out_alarm_func, 0, sizeof(m_out_alarm_func));
|
||||||
|
memset(&m_out_clkout_func, 0, sizeof(m_out_clkout_func));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// INLINE HELPERS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// set_alarm_line -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline void rp5c15_device::set_alarm_line()
|
||||||
|
{
|
||||||
|
int alarm = ((m_mode & MODE_ALARM_EN) ? m_alarm_on : 1) &
|
||||||
|
((m_reset & RESET_16_HZ) ? 1 : m_16hz) &
|
||||||
|
((m_reset & RESET_1_HZ) ? 1 : m_1hz);
|
||||||
|
|
||||||
|
if (m_alarm != alarm)
|
||||||
|
{
|
||||||
|
if (LOG) logerror("RP5C15 '%s' Alarm %u\n", tag(), alarm);
|
||||||
|
|
||||||
|
devcb_call_write_line(&m_out_alarm_func, alarm);
|
||||||
|
m_alarm = alarm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// read_counter -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline int rp5c15_device::read_counter(int counter)
|
||||||
|
{
|
||||||
|
return (m_reg[MODE00][counter + 1] * 10) + m_reg[MODE00][counter];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// write_counter -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline void rp5c15_device::write_counter(int counter, int value)
|
||||||
|
{
|
||||||
|
m_reg[MODE00][counter] = value % 10;
|
||||||
|
m_reg[MODE00][counter + 1] = value / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// advance_seconds -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline void rp5c15_device::advance_seconds()
|
||||||
|
{
|
||||||
|
int seconds = read_counter(REGISTER_1_SECOND);
|
||||||
|
|
||||||
|
seconds++;
|
||||||
|
|
||||||
|
if (seconds > 59)
|
||||||
|
{
|
||||||
|
seconds = 0;
|
||||||
|
|
||||||
|
advance_minutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
write_counter(REGISTER_1_SECOND, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// advance_minutes -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline void rp5c15_device::advance_minutes()
|
||||||
|
{
|
||||||
|
int minutes = read_counter(REGISTER_1_MINUTE);
|
||||||
|
int hours = read_counter(REGISTER_1_HOUR);
|
||||||
|
int days = read_counter(REGISTER_1_DAY);
|
||||||
|
int month = read_counter(REGISTER_1_MONTH);
|
||||||
|
int year = read_counter(REGISTER_1_YEAR);
|
||||||
|
int day_of_week = m_reg[MODE00][REGISTER_DAY_OF_THE_WEEK];
|
||||||
|
|
||||||
|
minutes++;
|
||||||
|
|
||||||
|
if (minutes > 59)
|
||||||
|
{
|
||||||
|
minutes = 0;
|
||||||
|
hours++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hours > 23)
|
||||||
|
{
|
||||||
|
hours = 0;
|
||||||
|
days++;
|
||||||
|
day_of_week++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (day_of_week > 6)
|
||||||
|
{
|
||||||
|
day_of_week++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (days > DAYS_PER_MONTH[month - 1])
|
||||||
|
{
|
||||||
|
days = 1;
|
||||||
|
month++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (month > 12)
|
||||||
|
{
|
||||||
|
month = 1;
|
||||||
|
year++;
|
||||||
|
m_reg[MODE01][REGISTER_LEAP_YEAR]++;
|
||||||
|
m_reg[MODE01][REGISTER_LEAP_YEAR] &= 0x03;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (year > 99)
|
||||||
|
{
|
||||||
|
year = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_counter(REGISTER_1_MINUTE, minutes);
|
||||||
|
write_counter(REGISTER_1_HOUR, hours);
|
||||||
|
write_counter(REGISTER_1_DAY, days);
|
||||||
|
write_counter(REGISTER_1_MONTH, month);
|
||||||
|
write_counter(REGISTER_1_YEAR, year);
|
||||||
|
m_reg[MODE00][REGISTER_DAY_OF_THE_WEEK] = day_of_week;
|
||||||
|
|
||||||
|
check_alarm();
|
||||||
|
set_alarm_line();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// adjust_seconds -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline void rp5c15_device::adjust_seconds()
|
||||||
|
{
|
||||||
|
int seconds = read_counter(REGISTER_1_SECOND);
|
||||||
|
|
||||||
|
if (seconds < 30)
|
||||||
|
{
|
||||||
|
write_counter(REGISTER_1_SECOND, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
write_counter(REGISTER_1_SECOND, 0);
|
||||||
|
advance_minutes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// check_alarm -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline void rp5c15_device::check_alarm()
|
||||||
|
{
|
||||||
|
bool all_match = true;
|
||||||
|
bool all_zeroes = true;
|
||||||
|
|
||||||
|
for (int i = REGISTER_1_MINUTE; i < REGISTER_1_MONTH; i++)
|
||||||
|
{
|
||||||
|
if (m_reg[MODE01][i] != 0) all_zeroes = false;
|
||||||
|
if (m_reg[MODE01][i] != m_reg[MODE00][i]) all_match = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_alarm_on = (all_match || (!m_alarm_on && all_zeroes)) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// LIVE DEVICE
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// rp5c15_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
rp5c15_device::rp5c15_device(running_machine &_machine, const rp5c15_device_config &config)
|
||||||
|
: device_t(_machine, config),
|
||||||
|
m_alarm(1),
|
||||||
|
m_alarm_on(1),
|
||||||
|
m_1hz(1),
|
||||||
|
m_16hz(1),
|
||||||
|
m_clkout(1),
|
||||||
|
m_config(config)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void rp5c15_device::device_start()
|
||||||
|
{
|
||||||
|
// resolve callbacks
|
||||||
|
devcb_resolve_write_line(&m_out_alarm_func, &m_config.m_out_alarm_func, this);
|
||||||
|
devcb_resolve_write_line(&m_out_clkout_func, &m_config.m_out_clkout_func, this);
|
||||||
|
|
||||||
|
// allocate timers
|
||||||
|
m_clock_timer = timer_alloc(TIMER_CLOCK);
|
||||||
|
m_clock_timer->adjust(attotime::from_hz(clock() / 16384), 0, attotime::from_hz(clock() / 16384));
|
||||||
|
|
||||||
|
m_16hz_timer = timer_alloc(TIMER_16HZ);
|
||||||
|
m_16hz_timer->adjust(attotime::from_hz(clock() / 1024), 0, attotime::from_hz(clock() / 1024));
|
||||||
|
|
||||||
|
m_clkout_timer = timer_alloc(TIMER_CLKOUT);
|
||||||
|
|
||||||
|
// state saving
|
||||||
|
save_item(NAME(m_reg[MODE00]));
|
||||||
|
save_item(NAME(m_reg[MODE01]));
|
||||||
|
save_item(NAME(m_mode));
|
||||||
|
save_item(NAME(m_reset));
|
||||||
|
save_item(NAME(m_alarm));
|
||||||
|
save_item(NAME(m_alarm_on));
|
||||||
|
save_item(NAME(m_1hz));
|
||||||
|
save_item(NAME(m_16hz));
|
||||||
|
save_item(NAME(m_clkout));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_timer - handler timer events
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void rp5c15_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
|
{
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case TIMER_CLOCK:
|
||||||
|
if (m_1hz && (m_mode & MODE_TIMER_EN))
|
||||||
|
{
|
||||||
|
advance_seconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_1hz = !m_1hz;
|
||||||
|
set_alarm_line();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TIMER_16HZ:
|
||||||
|
m_16hz = !m_16hz;
|
||||||
|
set_alarm_line();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TIMER_CLKOUT:
|
||||||
|
m_clkout = !m_clkout;
|
||||||
|
devcb_call_write_line(&m_out_clkout_func, m_clkout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// read -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
READ8_MEMBER( rp5c15_device::read )
|
||||||
|
{
|
||||||
|
UINT8 data = 0;
|
||||||
|
|
||||||
|
switch (offset & 0x0f)
|
||||||
|
{
|
||||||
|
case REGISTER_MODE:
|
||||||
|
data = m_mode;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGISTER_TEST:
|
||||||
|
case REGISTER_RESET:
|
||||||
|
// write only
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
data = m_reg[m_mode & MODE_MASK][offset];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG) logerror("RP5C15 '%s' Register %u Read %02x\n", tag(), offset & 0x0f, data);
|
||||||
|
|
||||||
|
return data & 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// write -
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
WRITE8_MEMBER( rp5c15_device::write )
|
||||||
|
{
|
||||||
|
int mode = m_mode & MODE_MASK;
|
||||||
|
|
||||||
|
switch (offset & 0x0f)
|
||||||
|
{
|
||||||
|
case REGISTER_MODE:
|
||||||
|
m_mode = data & 0x0f;
|
||||||
|
|
||||||
|
if (LOG)
|
||||||
|
{
|
||||||
|
logerror("RP5C15 '%s' Mode %u\n", tag(), data & MODE_MASK);
|
||||||
|
logerror("RP5C15 '%s' Timer %s\n", tag(), (data & MODE_TIMER_EN) ? "enabled" : "disabled");
|
||||||
|
logerror("RP5C15 '%s' Alarm %s\n", tag(), (data & MODE_ALARM_EN) ? "enabled" : "disabled");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGISTER_TEST:
|
||||||
|
if (LOG) logerror("RP5C15 '%s' Test %u not supported!\n", tag(), data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGISTER_RESET:
|
||||||
|
m_reset = data & 0x0f;
|
||||||
|
|
||||||
|
if (data & RESET_ALARM)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// reset alarm registers
|
||||||
|
for (i = REGISTER_1_MINUTE; i < REGISTER_1_MONTH; i++)
|
||||||
|
{
|
||||||
|
m_reg[MODE01][i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG)
|
||||||
|
{
|
||||||
|
if (data & RESET_ALARM) logerror("RP5C15 '%s' Alarm Reset\n", tag());
|
||||||
|
if (data & RESET_TIMER) logerror("RP5C15 '%s' Timer Reset not supported!\n", tag());
|
||||||
|
logerror("RP5C15 '%s' 16Hz Signal %s\n", tag(), (data & RESET_16_HZ) ? "disabled" : "enabled");
|
||||||
|
logerror("RP5C15 '%s' 1Hz Signal %s\n", tag(), (data & RESET_1_HZ) ? "disabled" : "enabled");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case MODE00:
|
||||||
|
m_reg[mode][offset & 0x0f] = data & REGISTER_WRITE_MASK[mode][offset & 0x0f];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE01:
|
||||||
|
switch (offset & 0x0f)
|
||||||
|
{
|
||||||
|
case REGISTER_CLOCK_OUTPUT:
|
||||||
|
switch (data & 0x07)
|
||||||
|
{
|
||||||
|
case CLKOUT_16384_HZ:
|
||||||
|
m_clkout_timer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLKOUT_1024_HZ:
|
||||||
|
m_clkout_timer->adjust(attotime::from_hz(clock() / 16), 0, attotime::from_hz(clock() / 16));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLKOUT_128_HZ:
|
||||||
|
m_clkout_timer->adjust(attotime::from_hz(clock() / 128), 0, attotime::from_hz(clock() / 128));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLKOUT_16_HZ:
|
||||||
|
m_clkout_timer->adjust(attotime::from_hz(clock() / 1024), 0, attotime::from_hz(clock() / 1024));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLKOUT_1_HZ:
|
||||||
|
m_clkout_timer->adjust(attotime::from_hz(clock() / 16384), 0, attotime::from_hz(clock() / 16384));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLKOUT_1_DIV_60_HZ:
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLKOUT_L:
|
||||||
|
case CLKOUT_Z:
|
||||||
|
m_clkout = 1;
|
||||||
|
m_clkout_timer->adjust(attotime::zero, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_reg[mode][offset & 0x0f] = data & REGISTER_WRITE_MASK[mode][offset & 0x0f];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGISTER_ADJUST:
|
||||||
|
if (BIT(data, 0))
|
||||||
|
{
|
||||||
|
adjust_seconds();
|
||||||
|
}
|
||||||
|
m_reg[mode][offset & 0x0f] = data & REGISTER_WRITE_MASK[mode][offset & 0x0f];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
m_reg[mode][offset & 0x0f] = data & REGISTER_WRITE_MASK[mode][offset & 0x0f];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG) logerror("RP5C15 '%s' Register %u Write %02x\n", tag(), offset & 0x0f, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
141
src/emu/machine/rp5c15.h
Normal file
141
src/emu/machine/rp5c15.h
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
|
||||||
|
Ricoh RP5C15 Real Time Clock emulation
|
||||||
|
|
||||||
|
Copyright MESS Team.
|
||||||
|
Visit http://mamedev.org for licensing and usage restrictions.
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
_____ _____
|
||||||
|
_CS 1 |* \_/ | 18 Vcc
|
||||||
|
CS 2 | | 17 OSCOUT
|
||||||
|
CLKOUT 3 | | 16 OSCIN
|
||||||
|
A0 4 | RP5C15 | 15 _ALARM
|
||||||
|
A1 5 | RF5C15 | 14 D3
|
||||||
|
A2 6 | RJ5C15 | 13 D2
|
||||||
|
A3 7 | | 12 D1
|
||||||
|
_RD 8 | | 11 D0
|
||||||
|
GND 9 |_____________| 10 _WR
|
||||||
|
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __RP5C15__
|
||||||
|
#define __RP5C15__
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// INTERFACE CONFIGURATION MACROS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
#define MCFG_RP5C15_ADD(_tag, _clock, _config) \
|
||||||
|
MCFG_DEVICE_ADD((_tag), RP5C15, _clock) \
|
||||||
|
MCFG_DEVICE_CONFIG(_config)
|
||||||
|
|
||||||
|
|
||||||
|
#define RP5C15_INTERFACE(name) \
|
||||||
|
const rp5c15_interface (name) =
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// ======================> rp5c15_interface
|
||||||
|
|
||||||
|
struct rp5c15_interface
|
||||||
|
{
|
||||||
|
devcb_write_line m_out_alarm_func;
|
||||||
|
devcb_write_line m_out_clkout_func;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> rp5c15_device_config
|
||||||
|
|
||||||
|
class rp5c15_device_config : public device_config,
|
||||||
|
public rp5c15_interface
|
||||||
|
{
|
||||||
|
friend class rp5c15_device;
|
||||||
|
|
||||||
|
// construction/destruction
|
||||||
|
rp5c15_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// allocators
|
||||||
|
static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||||
|
virtual device_t *alloc_device(running_machine &machine) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// device_config overrides
|
||||||
|
virtual void device_config_complete();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> rp5c15_device
|
||||||
|
|
||||||
|
class rp5c15_device : public device_t
|
||||||
|
{
|
||||||
|
friend class rp5c15_device_config;
|
||||||
|
|
||||||
|
// construction/destruction
|
||||||
|
rp5c15_device(running_machine &_machine, const rp5c15_device_config &_config);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DECLARE_READ8_MEMBER( read );
|
||||||
|
DECLARE_WRITE8_MEMBER( write );
|
||||||
|
DECLARE_WRITE_LINE_MEMBER( adj_w );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline void set_alarm_line();
|
||||||
|
inline int read_counter(int counter);
|
||||||
|
inline void write_counter(int counter, int value);
|
||||||
|
inline void advance_seconds();
|
||||||
|
inline void advance_minutes();
|
||||||
|
inline void adjust_seconds();
|
||||||
|
inline void check_alarm();
|
||||||
|
|
||||||
|
static const device_timer_id TIMER_CLOCK = 0;
|
||||||
|
static const device_timer_id TIMER_16HZ = 1;
|
||||||
|
static const device_timer_id TIMER_CLKOUT = 2;
|
||||||
|
|
||||||
|
devcb_resolved_write_line m_out_alarm_func;
|
||||||
|
devcb_resolved_write_line m_out_clkout_func;
|
||||||
|
|
||||||
|
UINT8 m_reg[2][13]; // clock registers
|
||||||
|
UINT8 m_ram[13]; // RAM
|
||||||
|
|
||||||
|
UINT8 m_mode; // mode register
|
||||||
|
UINT8 m_reset; // reset register
|
||||||
|
int m_alarm; // alarm output
|
||||||
|
int m_alarm_on; // alarm condition
|
||||||
|
int m_1hz; // 1 Hz condition
|
||||||
|
int m_16hz; // 16 Hz condition
|
||||||
|
int m_clkout; // clock output
|
||||||
|
|
||||||
|
// timers
|
||||||
|
emu_timer *m_clock_timer;
|
||||||
|
emu_timer *m_16hz_timer;
|
||||||
|
emu_timer *m_clkout_timer;
|
||||||
|
|
||||||
|
const rp5c15_device_config &m_config;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type RP5C15;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user