modernized the MM58274C RTC device. [Fabio Priuli]

This commit is contained in:
Fabio Priuli 2013-06-01 13:27:40 +00:00
parent 17cc34dc37
commit ef44a8dc38
11 changed files with 406 additions and 447 deletions

View File

@ -19,37 +19,7 @@
***************************************************************************/
#include "emu.h"
#include "mm58274c.h"
struct mm58274c_t
{
const mm58274c_interface *intf;
int status; /* status register (*read* from address 0 = control register) */
int control; /* control register (*write* to address 0) */
int clk_set; /* clock setting register */
int int_ctl; /* interrupt control register */
int wday; /* day of the week (1-7 (1=day1 as set in init)) */
int years1; /* years (BCD: 0-99) */
int years2;
int months1; /* months (BCD: 1-12) */
int months2;
int days1; /* days (BCD: 1-31) */
int days2;
int hours1; /* hours (BCD : 0-23) */
int hours2;
int minutes1; /* minutes (BCD : 0-59) */
int minutes2;
int seconds1; /* seconds (BCD : 0-59) */
int seconds2;
int tenths; /* tenths of second (BCD : 0-9) */
emu_timer *increment_rtc;
emu_timer *interrupt_timer;
};
#include "machine/mm58274c.h"
enum
{
@ -71,15 +41,113 @@ enum
};
INLINE mm58274c_t *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == MM58274C);
return (mm58274c_t *)downcast<mm58274c_device *>(device)->token();
const device_type MM58274C = &device_creator<mm58274c_device>;
mm58274c_device::mm58274c_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MM58274C, "National Semiconductor MM58274C", tag, owner, clock)
{
}
static attotime interrupt_period_table(int val)
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void mm58274c_device::device_config_complete()
{
// inherit a copy of the static data
const mm58274c_interface *intf = reinterpret_cast<const mm58274c_interface *>(static_config());
if (intf != NULL)
*static_cast<mm58274c_interface *>(this) = *intf;
// or initialize to defaults if none provided
else
{
m_mode24 = 0;
m_day1 = 0;
}
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void mm58274c_device::device_start()
{
m_increment_rtc = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mm58274c_device::rtc_increment_cb),this));
m_increment_rtc->adjust(attotime::zero, 0, attotime::from_msec(100));
m_interrupt_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mm58274c_device::rtc_interrupt_cb),this));
// register for state saving
save_item(NAME(m_status));
save_item(NAME(m_control));
save_item(NAME(m_clk_set));
save_item(NAME(m_int_ctl));
save_item(NAME(m_wday));
save_item(NAME(m_years1));
save_item(NAME(m_years2));
save_item(NAME(m_months1));
save_item(NAME(m_months2));
save_item(NAME(m_days1));
save_item(NAME(m_days2));
save_item(NAME(m_hours1));
save_item(NAME(m_hours2));
save_item(NAME(m_minutes1));
save_item(NAME(m_minutes2));
save_item(NAME(m_seconds1));
save_item(NAME(m_seconds2));
save_item(NAME(m_tenths));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void mm58274c_device::device_reset()
{
system_time systime;
/* get the current date/time from the core */
machine().current_datetime(systime);
m_clk_set = systime.local_time.year & 3 << 2;
if (m_mode24)
m_clk_set |= clk_set_24;
/* The clock count starts on 1st January 1900 */
m_wday = 1 + ((systime.local_time.weekday - m_day1) % 7);
m_years1 = (systime.local_time.year / 10) % 10;
m_years2 = systime.local_time.year % 10;
m_months1 = (systime.local_time.month + 1) / 10;
m_months2 = (systime.local_time.month + 1) % 10;
m_days1 = systime.local_time.mday / 10;
m_days2 = systime.local_time.mday % 10;
if (!m_mode24)
{
/* 12-hour mode */
if (systime.local_time.hour > 12)
{
systime.local_time.hour -= 12;
m_clk_set |= clk_set_pm;
}
if (systime.local_time.hour == 0)
systime.local_time.hour = 12;
}
m_hours1 = systime.local_time.hour / 10;
m_hours2 = systime.local_time.hour % 10;
m_minutes1 = systime.local_time.minute / 10;
m_minutes2 = systime.local_time.minute % 10;
m_seconds1 = systime.local_time.second / 10;
m_seconds2 = systime.local_time.second % 10;
m_tenths = 0;
}
attotime mm58274c_device::interrupt_period_table(int val)
{
switch(val)
{
@ -95,295 +163,273 @@ static attotime interrupt_period_table(int val)
}
};
READ8_DEVICE_HANDLER( mm58274c_r )
READ8_MEMBER( mm58274c_device::read )
{
mm58274c_t *mm58274c = get_safe_token(device);
int reply;
offset &= 0xf;
switch (offset)
{
case 0x0: /* Control Register */
reply = mm58274c->status;
mm58274c->status = 0;
break;
case 0x1: /* Tenths of Seconds */
reply = mm58274c->tenths;
break;
case 0x2: /* Units Seconds */
reply = mm58274c->seconds2;
break;
case 0x3: /* Tens Seconds */
reply = mm58274c->seconds1;
break;
case 0x04: /* Units Minutes */
reply = mm58274c->minutes2;
break;
case 0x5: /* Tens Minutes */
reply = mm58274c->minutes1;
break;
case 0x6: /* Units Hours */
reply = mm58274c->hours2;
break;
case 0x7: /* Tens Hours */
reply = mm58274c->hours1;
break;
case 0x8: /* Units Days */
reply = mm58274c->days2;
break;
case 0x9: /* Tens Days */
reply = mm58274c->days1;
break;
case 0xA: /* Units Months */
reply = mm58274c->months2;
break;
case 0xB: /* Tens Months */
reply = mm58274c->months1;
break;
case 0xC: /* Units Years */
reply = mm58274c->years2;
break;
case 0xD: /* Tens Years */
reply = mm58274c->years1;
break;
case 0xE: /* Day of Week */
reply = mm58274c->wday;
break;
case 0xF: /* Clock Setting & Interrupt Registers */
if (mm58274c->control & ctl_intsel)
/* interrupt register */
reply = mm58274c->int_ctl;
else
{ /* clock setting register */
if (mm58274c->clk_set & clk_set_24)
/* 24-hour mode */
reply = mm58274c->clk_set & ~clk_set_pm;
else
/* 12-hour mode */
reply = mm58274c->clk_set;
}
break;
default:
reply = 0;
break;
case 0x00: /* Control Register */
reply = m_status;
m_status = 0;
break;
case 0x01: /* Tenths of Seconds */
reply = m_tenths;
break;
case 0x02: /* Units Seconds */
reply = m_seconds2;
break;
case 0x03: /* Tens Seconds */
reply = m_seconds1;
break;
case 0x04: /* Units Minutes */
reply = m_minutes2;
break;
case 0x05: /* Tens Minutes */
reply = m_minutes1;
break;
case 0x06: /* Units Hours */
reply = m_hours2;
break;
case 0x07: /* Tens Hours */
reply = m_hours1;
break;
case 0x08: /* Units Days */
reply = m_days2;
break;
case 0x09: /* Tens Days */
reply = m_days1;
break;
case 0x0a: /* Units Months */
reply = m_months2;
break;
case 0x0b: /* Tens Months */
reply = m_months1;
break;
case 0x0c: /* Units Years */
reply = m_years2;
break;
case 0x0d: /* Tens Years */
reply = m_years1;
break;
case 0x0e: /* Day of Week */
reply = m_wday;
break;
case 0x0f: /* Clock Setting & Interrupt Registers */
if (m_control & ctl_intsel) /* interrupt register */
reply = m_int_ctl;
else /* clock setting register */
{
if (m_clk_set & clk_set_24) /* 24-hour mode */
reply = m_clk_set & ~clk_set_pm;
else /* 12-hour mode */
reply = m_clk_set;
}
break;
default:
reply = 0;
break;
}
return reply;
}
WRITE8_DEVICE_HANDLER (mm58274c_w)
WRITE8_MEMBER( mm58274c_device::write )
{
mm58274c_t *mm58274c = get_safe_token(device);
offset &= 0xf;
data &= 0xf;
switch (offset)
{
case 0x0: /* Control Register (test mode and interrupt not emulated) */
if ((! (mm58274c->control & ctl_intstop)) && (data & ctl_intstop))
/* interrupt stop */
mm58274c->interrupt_timer->enable(0);
else if ((mm58274c->control & ctl_intstop) && (! (data & ctl_intstop)))
{
/* interrupt run */
attotime period = interrupt_period_table(mm58274c->int_ctl & int_ctl_dly);
mm58274c->interrupt_timer->adjust(period, 0, mm58274c->int_ctl & int_ctl_rpt ? period : attotime::zero);
}
if (data & ctl_clkstop)
/* stopping the clock clears the tenth counter */
mm58274c->tenths = 0;
mm58274c->control = data;
break;
case 0x1: /* Tenths of Seconds: cannot be written */
break;
case 0x2: /* Units Seconds */
mm58274c->seconds2 = data;
break;
case 0x3: /* Tens Seconds */
mm58274c->seconds1 = data;
break;
case 0x4: /* Units Minutes */
mm58274c->minutes2 = data;
break;
case 0x5: /* Tens Minutes */
mm58274c->minutes1 = data;
break;
case 0x6: /* Units Hours */
mm58274c->hours2 = data;
break;
case 0x7: /* Tens Hours */
mm58274c->hours1 = data;
break;
case 0x8: /* Units Days */
mm58274c->days2 = data;
break;
case 0x9: /* Tens Days */
mm58274c->days1 = data;
break;
case 0xA: /* Units Months */
mm58274c->months2 = data;
break;
case 0xB: /* Tens Months */
mm58274c->months1 = data;
break;
case 0xC: /* Units Years */
mm58274c->years2 = data;
break;
case 0xD: /* Tens Years */
mm58274c->years1 = data;
break;
case 0xE: /* Day of Week */
mm58274c->wday = data;
break;
case 0xF: /* Clock Setting & Interrupt Registers */
if (mm58274c->control & ctl_intsel)
{
/* interrupt register (not emulated) */
mm58274c->int_ctl = data;
if (! (mm58274c->control & ctl_intstop))
case 0x00: /* Control Register (test mode and interrupt not emulated) */
if ((!(m_control & ctl_intstop)) && (data & ctl_intstop)) /* interrupt stop */
m_interrupt_timer->enable(0);
else if ((m_control & ctl_intstop) && (!(data & ctl_intstop))) /* interrupt run */
{
/* interrupt run */
attotime period = interrupt_period_table(mm58274c->int_ctl & int_ctl_dly);
mm58274c->interrupt_timer->adjust(period, 0, mm58274c->int_ctl & int_ctl_rpt ? period : attotime::zero);
attotime period = interrupt_period_table(m_int_ctl & int_ctl_dly);
m_interrupt_timer->adjust(period, 0, m_int_ctl & int_ctl_rpt ? period : attotime::zero);
}
}
else
{
/* clock setting register */
mm58274c->clk_set = data;
#if 0
if (mm58274c->clk_set & clk_set_24)
/* 24-hour mode */
mm58274c->clk_set &= ~clk_set_pm;
#endif
}
break;
if (data & ctl_clkstop) /* stopping the clock clears the tenth counter */
m_tenths = 0;
m_control = data;
break;
case 0x01: /* Tenths of Seconds: cannot be written */
break;
case 0x02: /* Units Seconds */
m_seconds2 = data;
break;
case 0x03: /* Tens Seconds */
m_seconds1 = data;
break;
case 0x04: /* Units Minutes */
m_minutes2 = data;
break;
case 0x05: /* Tens Minutes */
m_minutes1 = data;
break;
case 0x06: /* Units Hours */
m_hours2 = data;
break;
case 0x07: /* Tens Hours */
m_hours1 = data;
break;
case 0x08: /* Units Days */
m_days2 = data;
break;
case 0x09: /* Tens Days */
m_days1 = data;
break;
case 0x0a: /* Units Months */
m_months2 = data;
break;
case 0x0b: /* Tens Months */
m_months1 = data;
break;
case 0x0c: /* Units Years */
m_years2 = data;
break;
case 0x0d: /* Tens Years */
m_years1 = data;
break;
case 0x0e: /* Day of Week */
m_wday = data;
break;
case 0x0f: /* Clock Setting & Interrupt Registers */
if (m_control & ctl_intsel) /* interrupt register (not emulated) */
{
m_int_ctl = data;
if (!(m_control & ctl_intstop)) /* interrupt run */
{
attotime period = interrupt_period_table(m_int_ctl & int_ctl_dly);
m_interrupt_timer->adjust(period, 0, m_int_ctl & int_ctl_rpt ? period : attotime::zero);
}
}
else /* clock setting register */
{
m_clk_set = data;
#if 0
if (m_clk_set & clk_set_24) /* 24-hour mode */
m_clk_set &= ~clk_set_pm;
#endif
}
break;
}
}
/*
Set RTC interrupt flag
*/
static TIMER_CALLBACK(rtc_interrupt_callback)
// Set RTC interrupt flag
TIMER_CALLBACK_MEMBER(mm58274c_device::rtc_interrupt_cb)
{
device_t *device = (device_t *)ptr;
mm58274c_t *mm58274c = get_safe_token(device);
mm58274c->status |= st_if;
m_status |= st_if;
}
/*
Increment RTC clock (timed interrupt every 1/10s)
*/
static TIMER_CALLBACK(increment_rtc)
// Increment RTC clock (timed interrupt every 1/10s)
TIMER_CALLBACK_MEMBER(mm58274c_device::rtc_increment_cb)
{
device_t *device = (device_t *)ptr;
mm58274c_t *mm58274c = get_safe_token(device);
if (! (mm58274c->control & ctl_clkstop))
if (!(m_control & ctl_clkstop))
{
mm58274c->status |= st_dcf;
m_status |= st_dcf;
if ((++mm58274c->tenths) == 10)
if ((++m_tenths) == 10)
{
mm58274c->tenths = 0;
m_tenths = 0;
if ((++mm58274c->seconds2) == 10)
if ((++m_seconds2) == 10)
{
mm58274c->seconds2 = 0;
m_seconds2 = 0;
if ((++mm58274c->seconds1) == 6)
if ((++m_seconds1) == 6)
{
mm58274c->seconds1 = 0;
m_seconds1 = 0;
if ((++mm58274c->minutes2) == 10)
if ((++m_minutes2) == 10)
{
mm58274c->minutes2 = 0;
m_minutes2 = 0;
if ((++mm58274c->minutes1) == 6)
if ((++m_minutes1) == 6)
{
mm58274c->minutes1 = 0;
m_minutes1 = 0;
if ((++mm58274c->hours2) == 10)
if ((++m_hours2) == 10)
{
mm58274c->hours2 = 0;
m_hours2 = 0;
mm58274c->hours1++;
m_hours1++;
}
/* handle wrap-around */
if ((! (mm58274c->clk_set & clk_set_24))
&& ((mm58274c->hours1*10 + mm58274c->hours2) == 12))
if ((!(m_clk_set & clk_set_24))
&& ((m_hours1*10 + m_hours2) == 12))
{
mm58274c->clk_set ^= clk_set_pm;
m_clk_set ^= clk_set_pm;
}
if ((! (mm58274c->clk_set & clk_set_24))
&& ((mm58274c->hours1*10 + mm58274c->hours2) == 13))
if ((!(m_clk_set & clk_set_24))
&& ((m_hours1*10 + m_hours2) == 13))
{
mm58274c->hours1 = 0;
mm58274c->hours2 = 1;
m_hours1 = 0;
m_hours2 = 1;
}
if ((mm58274c->clk_set & clk_set_24)
&& ((mm58274c->hours1*10 + mm58274c->hours2) == 24))
if ((m_clk_set & clk_set_24)
&& ((m_hours1*10 + m_hours2) == 24))
{
mm58274c->hours1 = mm58274c->hours2 = 0;
m_hours1 = m_hours2 = 0;
}
/* increment day if needed */
if ((mm58274c->clk_set & clk_set_24)
? ((mm58274c->hours1*10 + mm58274c->hours2) == 0)
: (((mm58274c->hours1*10 + mm58274c->hours2) == 12)
&& (! (mm58274c->clk_set & clk_set_pm))))
if ((m_clk_set & clk_set_24)
? ((m_hours1*10 + m_hours2) == 0)
: (((m_hours1*10 + m_hours2) == 12)
&& (!(m_clk_set & clk_set_pm))))
{
int days_in_month;
if ((++mm58274c->days2) == 10)
if ((++m_days2) == 10)
{
mm58274c->days2 = 0;
m_days2 = 0;
mm58274c->days1++;
m_days1++;
}
if ((++mm58274c->wday) == 8)
mm58274c->wday = 1;
if ((++m_wday) == 8)
m_wday = 1;
{
static const int days_in_month_array[] =
@ -392,39 +438,39 @@ static TIMER_CALLBACK(increment_rtc)
31,31,30, 31,30,31
};
if (((mm58274c->months1*10 + mm58274c->months2) != 2) || (mm58274c->clk_set & clk_set_leap))
days_in_month = days_in_month_array[mm58274c->months1*10 + mm58274c->months2 - 1];
if (((m_months1*10 + m_months2) != 2) || (m_clk_set & clk_set_leap))
days_in_month = days_in_month_array[m_months1*10 + m_months2 - 1];
else
days_in_month = 29;
}
if ((mm58274c->days1*10 + mm58274c->days2) == days_in_month+1)
if ((m_days1*10 + m_days2) == days_in_month+1)
{
mm58274c->days1 = 0;
mm58274c->days2 = 1;
m_days1 = 0;
m_days2 = 1;
if ((++mm58274c->months2) == 10)
if ((++m_months2) == 10)
{
mm58274c->months2 = 0;
m_months2 = 0;
mm58274c->months1++;
m_months1++;
}
if ((mm58274c->months1*10 + mm58274c->months2) == 13)
if ((m_months1*10 + m_months2) == 13)
{
mm58274c->months1 = 0;
mm58274c->months2 = 1;
m_months1 = 0;
m_months2 = 1;
mm58274c->clk_set = (mm58274c->clk_set & ~clk_set_leap)
| ((mm58274c->clk_set + clk_set_leap_inc) & clk_set_leap);
m_clk_set = (m_clk_set & ~clk_set_leap)
| ((m_clk_set + clk_set_leap_inc) & clk_set_leap);
if ((++mm58274c->years2) == 10)
if ((++m_years2) == 10)
{
mm58274c->years2 = 0;
m_years2 = 0;
if ((++mm58274c->years1) == 10)
mm58274c->years1 = 0;
if ((++m_years1) == 10)
m_years1 = 0;
}
}
}
@ -437,116 +483,3 @@ static TIMER_CALLBACK(increment_rtc)
}
}
/* Device Interface */
static DEVICE_START( mm58274c )
{
mm58274c_t *mm58274c = get_safe_token(device);
// validate arguments
assert(device != NULL);
assert(device->tag() != NULL);
assert(device->static_config() != NULL);
mm58274c->intf = (const mm58274c_interface*)device->static_config();
// register for state saving
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->status);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->control);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->clk_set);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->int_ctl);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->wday);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->years1);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->years2);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->months1);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->months2);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->days1);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->days2);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->hours1);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->hours2);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->minutes1);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->minutes2);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->seconds1);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->seconds2);
state_save_register_item(device->machine(), "mm58274c", device->tag(), 0, mm58274c->tenths);
mm58274c->increment_rtc = device->machine().scheduler().timer_alloc(FUNC(increment_rtc), ((void*)device));
mm58274c->increment_rtc->adjust(attotime::zero, 0, attotime::from_msec(100));
mm58274c->interrupt_timer = device->machine().scheduler().timer_alloc(FUNC(rtc_interrupt_callback), ((void*)device));
}
static DEVICE_RESET( mm58274c )
{
mm58274c_t *mm58274c = get_safe_token(device);
system_time systime;
/* get the current date/time from the core */
device->machine().current_datetime(systime);
mm58274c->clk_set = systime.local_time.year & 3 << 2;
if (mm58274c->intf->mode24)
mm58274c->clk_set |= clk_set_24;
/* The clock count starts on 1st January 1900 */
mm58274c->wday = 1 + ((systime.local_time.weekday - mm58274c->intf->day1)%7);
mm58274c->years1 = (systime.local_time.year / 10) % 10;
mm58274c->years2 = systime.local_time.year % 10;
mm58274c->months1 = (systime.local_time.month + 1) / 10;
mm58274c->months2 = (systime.local_time.month + 1) % 10;
mm58274c->days1 = systime.local_time.mday / 10;
mm58274c->days2 = systime.local_time.mday % 10;
if (!mm58274c->intf->mode24)
{
/* 12-hour mode */
if (systime.local_time.hour > 12)
{
systime.local_time.hour -= 12;
mm58274c->clk_set |= clk_set_pm;
}
if (systime.local_time.hour == 0)
systime.local_time.hour = 12;
}
mm58274c->hours1 = systime.local_time.hour / 10;
mm58274c->hours2 = systime.local_time.hour % 10;
mm58274c->minutes1 = systime.local_time.minute / 10;
mm58274c->minutes2 = systime.local_time.minute % 10;
mm58274c->seconds1 = systime.local_time.second / 10;
mm58274c->seconds2 = systime.local_time.second % 10;
mm58274c->tenths = 0;
}
const device_type MM58274C = &device_creator<mm58274c_device>;
mm58274c_device::mm58274c_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MM58274C, "National Semiconductor MM58274C", tag, owner, clock)
{
m_token = global_alloc_clear(mm58274c_t);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void mm58274c_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void mm58274c_device::device_start()
{
DEVICE_START_NAME( mm58274c )(this);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void mm58274c_device::device_reset()
{
DEVICE_RESET_NAME( mm58274c )(this);
}

View File

@ -1,50 +1,77 @@
#ifndef MM58274C_H
#define MM58274C_H
#ifndef __MM58274C_H__
#define __MM58274C_H__
/*
Initializes the clock chip.
day1 must be set to a value from 0 (sunday), 1 (monday) ...
to 6 (saturday) and is needed to correctly retrieve the day-of-week
from the host system clock.
*/
struct mm58274c_interface
{
int m_mode24; /* 24/12 mode */
int m_day1; /* first day of week */
};
/***************************************************************************
MACROS
***************************************************************************/
class mm58274c_device : public device_t
class mm58274c_device : public device_t,
public mm58274c_interface
{
public:
mm58274c_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~mm58274c_device() { global_free(m_token); }
~mm58274c_device() {}
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
TIMER_CALLBACK_MEMBER(rtc_increment_cb);
TIMER_CALLBACK_MEMBER(rtc_interrupt_cb);
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
private:
// internal state
void *m_token;
attotime interrupt_period_table(int val);
int m_status; /* status register (*read* from address 0 = control register) */
int m_control; /* control register (*write* to address 0) */
int m_clk_set; /* clock setting register */
int m_int_ctl; /* interrupt control register */
int m_wday; /* day of the week (1-7 (1=day1 as set in init)) */
int m_years1; /* years (BCD: 0-99) */
int m_years2;
int m_months1; /* months (BCD: 1-12) */
int m_months2;
int m_days1; /* days (BCD: 1-31) */
int m_days2;
int m_hours1; /* hours (BCD : 0-23) */
int m_hours2;
int m_minutes1; /* minutes (BCD : 0-59) */
int m_minutes2;
int m_seconds1; /* seconds (BCD : 0-59) */
int m_seconds2;
int m_tenths; /* tenths of second (BCD : 0-9) */
emu_timer *m_increment_rtc;
emu_timer *m_interrupt_timer;
};
extern const device_type MM58274C;
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
/* interface */
/*
Initializes the clock chip.
day1 must be set to a value from 0 (sunday), 1 (monday) ...
to 6 (saturday) and is needed to correctly retrieve the day-of-week
from the host system clock.
*/
struct mm58274c_interface
{
int mode24; /* 24/12 mode */
int day1; /* first day of week */
};
DECLARE_READ8_DEVICE_HANDLER ( mm58274c_r );
DECLARE_WRITE8_DEVICE_HANDLER( mm58274c_w );
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/
@ -53,4 +80,4 @@ DECLARE_WRITE8_DEVICE_HANDLER( mm58274c_w );
MCFG_DEVICE_ADD(_tag, MM58274C, 0) \
MCFG_DEVICE_CONFIG(_intrf)
#endif /* MM58274C_H */
#endif

View File

@ -162,7 +162,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( compis_io, AS_IO, 16, compis_state )
AM_RANGE( 0x0000, 0x0007) AM_DEVREADWRITE8("ppi8255", i8255_device, read, write, 0xff00)
AM_RANGE( 0x0080, 0x0087) AM_DEVREADWRITE8_LEGACY("pit8253", pit8253_r, pit8253_w, 0xffff)
AM_RANGE( 0x0100, 0x011b) AM_DEVREADWRITE8_LEGACY("mm58274c", mm58274c_r, mm58274c_w, 0xffff)
AM_RANGE( 0x0100, 0x011b) AM_DEVREADWRITE8("mm58274c", mm58274c_device, read, write, 0xffff)
AM_RANGE( 0x0280, 0x0283) AM_DEVREADWRITE8("pic8259_master", pic8259_device, read, write, 0xffff) /* 80150/80130 */
//AM_RANGE( 0x0288, 0x028f) AM_DEVREADWRITE_LEGACY("pit8254", compis_osp_pit_r, compis_osp_pit_w ) /* PIT 8254 (80150/80130) */
AM_RANGE( 0x0310, 0x031f) AM_READWRITE( compis_usart_r, compis_usart_w ) /* USART 8251 Keyboard */

View File

@ -35,14 +35,15 @@ public:
m_maincpu(*this, "maincpu"),
m_acia0(*this, ACIA_0_TAG),
m_acia1(*this, ACIA_1_TAG),
m_mm58274(*this,"mm58274c"),
m_videoram(*this,"videoram") { }
required_device<cpu_device> m_maincpu;
required_device<mos6551_device> m_acia0;
required_device<mos6551_device> m_acia1;
required_device<mm58274c_device> m_mm58274;
required_shared_ptr<UINT16> m_videoram;
device_t *m_mm58274;
concept_exp_port_device *m_exp[4];
ioport_port *m_key[6];

View File

@ -59,8 +59,6 @@ void concept_state::machine_start()
m_KeyQueueHead = m_KeyQueueLen = 0;
memset(m_KeyStateSave, 0, sizeof(m_KeyStateSave));
m_mm58274 = machine().device("mm58274c");
m_exp[0] = machine().device<concept_exp_port_device>("exp1");
m_exp[1] = machine().device<concept_exp_port_device>("exp2");
m_exp[2] = machine().device<concept_exp_port_device>("exp3");
@ -280,7 +278,7 @@ READ16_MEMBER(concept_state::concept_io_r)
/* calendar R/W */
VLOG(("concept_io_r: Calendar read at address 0x03%4.4x\n", offset << 1));
if (!m_clock_enable)
return mm58274c_r(m_mm58274, space, m_clock_address);
return m_mm58274->read(space, m_clock_address);
break;
case 7:
@ -405,7 +403,7 @@ WRITE16_MEMBER(concept_state::concept_io_w)
/* calendar R/W */
LOG(("concept_io_w: Calendar written to at address 0x03%4.4x, data: 0x%4.4x\n", offset << 1, data));
if (!m_clock_enable)
mm58274c_w(m_mm58274, space, m_clock_address, data & 0xf);
m_mm58274->write(space, m_clock_address, data & 0xf);
break;
case 7:

View File

@ -33,7 +33,6 @@
#include "machine/wd17xx.h"
#include "formats/ti99_dsk.h"
#include "imagedev/flopdrv.h"
#include "machine/mm58274c.h"
#define LOG logerror
#define VERBOSE 1
@ -45,7 +44,8 @@
#define BUFFER "ram"
snug_bwg_device::snug_bwg_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ti_expansion_card_device(mconfig, TI99_BWG, "SNUG BwG Floppy Controller", tag, owner, clock, "ti99_bwg", __FILE__)
: ti_expansion_card_device(mconfig, TI99_BWG, "SNUG BwG Floppy Controller", tag, owner, clock, "ti99_bwg", __FILE__),
m_clock(*this, CLOCK_TAG)
{
}
@ -131,7 +131,7 @@ READ8Z_MEMBER(snug_bwg_device::readz)
if ((offset & 0x03e1)==0x03e0)
{
// .... ..11 111x xxx0
*value = mm58274c_r(m_clock, space, (offset & 0x001e) >> 1);
*value = m_clock->read(space, (offset & 0x001e) >> 1);
}
else
{
@ -210,7 +210,7 @@ WRITE8_MEMBER(snug_bwg_device::write)
if ((offset & 0x03e1)==0x03e0)
{
// .... ..11 111x xxx0
mm58274c_w(m_clock, space, (offset & 0x001e) >> 1, data);
m_clock->write(space, (offset & 0x001e) >> 1, data);
}
else
{
@ -386,7 +386,6 @@ void snug_bwg_device::device_start(void)
m_buffer_ram = memregion(BUFFER)->base();
m_motor_on_timer = timer_alloc(MOTOR_TIMER);
m_controller = subdevice(FDC_TAG);
m_clock = subdevice(CLOCK_TAG);
m_cru_base = 0x1100;
}

View File

@ -14,6 +14,7 @@
#include "ti99defs.h"
#include "imagedev/flopdrv.h"
#include "machine/mm58274c.h"
extern const device_type TI99_BWG;
@ -79,7 +80,7 @@ private:
device_t* m_controller;
// Link to the real-time clock on the board.
device_t* m_clock;
required_device<mm58274c_device> m_clock;
// count 4.23s from rising edge of motor_on
emu_timer* m_motor_on_timer;

View File

@ -141,7 +141,6 @@
***************************************************************************/
#include "genboard.h"
#include "machine/mm58274c.h"
#define VERBOSE 1
#define LOG logerror
@ -338,7 +337,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
// clock
// tests on the real machine showed that
// upper nibble is 0xf (probably because of the location at 0xf130?)
value = mm58274c_r(m_clock, space, offset & 0x000f) | 0xf0;
value = m_clock->read(space, offset & 0x000f) | 0xf0;
do_wait(1);
if (VERBOSE>7) LOG("genboard: Read clock %04x -> %02x\n", offset, value);
return value;
@ -372,7 +371,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
// Obscure, needs more investigation. We might as well ignore this,
// as the high nibble is obviously undefined and takes some past
// value floating around.
value = mm58274c_r(m_clock, space, offset & 0x000f);
value = m_clock->read(space, offset & 0x000f);
value |= ((offset & 0x000f)==0x000f)? 0x20 : 0x10;
do_wait(1);
@ -609,7 +608,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
{
// clock
// ++++ ++++ ++++ ----
mm58274c_w(m_clock, space, offset & 0x00f, data);
m_clock->write(space, offset & 0x00f, data);
do_wait(1);
if (VERBOSE>7) LOG("genboard: Write clock %04x <- %02x\n", offset, data);
return;
@ -630,7 +629,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
if ((offset & 0xfff0)==0x8010)
{
// clock
mm58274c_w(m_clock, space, offset & 0x00f, data);
m_clock->write(space, offset & 0x00f, data);
do_wait(1);
if (VERBOSE>7) LOG("genboard: Write clock %04x <- %02x\n", offset, data);
return;
@ -834,7 +833,7 @@ void geneve_mapper_device::device_start()
m_keyboard = machine().device<geneve_keyboard_device>(GKEYBOARD_TAG);
m_video = machine().device<bus8z_device>(VIDEO_SYSTEM_TAG);
m_sound = machine().device<bus8z_device>(TISOUND_TAG);
m_clock = machine().device(GCLOCK_TAG);
m_clock = machine().device<mm58274c_device>(GCLOCK_TAG);
m_ready.resolve(conf->ready, *this);

View File

@ -13,6 +13,7 @@
#include "emu.h"
#include "ti99defs.h"
#include "machine/mm58274c.h"
#include "video/v9938.h"
extern const device_type GENEVE_MOUSE;
@ -180,7 +181,7 @@ private:
int m_waitcount;
// Devices
device_t* m_clock;
mm58274c_device* m_clock;
geneve_keyboard_device* m_keyboard;
bus8z_device* m_video;
bus8z_device* m_peribox;

View File

@ -17,7 +17,6 @@
#include "hfdc.h"
#include "imagedev/flopdrv.h"
#include "machine/mm58274c.h"
#include "formats/ti99_dsk.h" // Format
#define BUFFER "ram"
@ -39,7 +38,9 @@
#define LOG logerror
myarc_hfdc_device::myarc_hfdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ti_expansion_card_device(mconfig, TI99_HFDC, "Myarc Hard and Floppy Disk Controller", tag, owner, clock, "ti99_hfdc", __FILE__)
: ti_expansion_card_device(mconfig, TI99_HFDC, "Myarc Hard and Floppy Disk Controller", tag, owner, clock, "ti99_hfdc", __FILE__),
m_hdc9234(*this, FDC_TAG),
m_clock(*this, CLOCK_TAG)
{
}
@ -85,7 +86,7 @@ READ8Z_MEMBER(myarc_hfdc_device::readz)
if ((offset & 0x1fe1)==CLK_ADDR)
{
*value = mm58274c_r(m_clock, space, (offset & 0x001e) >> 1);
*value = m_clock->read(space, (offset & 0x001e) >> 1);
if (VERBOSE>7) LOG("hfdc: read from clock address %04x: %02x\n", offset & 0xffff, *value);
return;
}
@ -139,7 +140,7 @@ WRITE8_MEMBER( myarc_hfdc_device::write )
if ((offset & 0x1fe1)==CLK_ADDR)
{
if (VERBOSE>7) LOG("hfdc: write to clock address %04x: %02x\n", offset & 0xffff, data);
mm58274c_w(m_clock, space, (offset & 0x001e) >> 1, data);
m_clock->write(space, (offset & 0x001e) >> 1, data);
return;
}
@ -495,8 +496,6 @@ INPUT_PORTS_END
void myarc_hfdc_device::device_start()
{
if (VERBOSE>5) LOG("hfdc: start\n");
m_hdc9234 = static_cast<smc92x4_device *>(subdevice(FDC_TAG));
m_clock = subdevice(CLOCK_TAG);
m_dsrrom = memregion(DSRROM)->base();
m_buffer_ram = memregion(BUFFER)->base();

View File

@ -17,6 +17,7 @@
#include "ti99defs.h"
#include "ti99_hd.h"
#include "machine/smc92x4.h"
#include "machine/mm58274c.h"
#define HFDC_MAX_FLOPPY 4
#define HFDC_MAX_HARD 4
@ -70,10 +71,10 @@ private:
// Link to the HDC9234 controller on the board. In fact, the proper name
// is HDC 9234, the manufacturer is Standard Microsystems Corp.
smc92x4_device* m_hdc9234;
required_device<smc92x4_device> m_hdc9234;
/* Link to the clock chip on the board. */
device_t* m_clock;
required_device<mm58274c_device> m_clock;
/* Determines whether we have access to the CRU bits. */
bool m_cru_select;