diff --git a/src/emu/machine/mm58274c.c b/src/emu/machine/mm58274c.c index 0b4d270e411..0bbefe91095 100644 --- a/src/emu/machine/mm58274c.c +++ b/src/emu/machine/mm58274c.c @@ -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(device)->token(); +const device_type MM58274C = &device_creator; + + +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(static_config()); + if (intf != NULL) + *static_cast(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(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); -} diff --git a/src/emu/machine/mm58274c.h b/src/emu/machine/mm58274c.h index 983d501dc59..02d24c4b726 100644 --- a/src/emu/machine/mm58274c.h +++ b/src/emu/machine/mm58274c.h @@ -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 diff --git a/src/mess/drivers/compis.c b/src/mess/drivers/compis.c index abdaee1b759..4309b95302e 100644 --- a/src/mess/drivers/compis.c +++ b/src/mess/drivers/compis.c @@ -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 */ diff --git a/src/mess/includes/concept.h b/src/mess/includes/concept.h index d4a0171b3c1..7f79c18887f 100644 --- a/src/mess/includes/concept.h +++ b/src/mess/includes/concept.h @@ -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 m_maincpu; required_device m_acia0; required_device m_acia1; + required_device m_mm58274; required_shared_ptr m_videoram; - device_t *m_mm58274; concept_exp_port_device *m_exp[4]; ioport_port *m_key[6]; diff --git a/src/mess/machine/concept.c b/src/mess/machine/concept.c index 8b3161307a4..b4272e4277c 100644 --- a/src/mess/machine/concept.c +++ b/src/mess/machine/concept.c @@ -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("exp1"); m_exp[1] = machine().device("exp2"); m_exp[2] = machine().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: diff --git a/src/mess/machine/ti99/bwg.c b/src/mess/machine/ti99/bwg.c index a3c6fea0aaf..7f70686fd0e 100644 --- a/src/mess/machine/ti99/bwg.c +++ b/src/mess/machine/ti99/bwg.c @@ -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; } diff --git a/src/mess/machine/ti99/bwg.h b/src/mess/machine/ti99/bwg.h index 995e0f05687..87a9fd22cfa 100644 --- a/src/mess/machine/ti99/bwg.h +++ b/src/mess/machine/ti99/bwg.h @@ -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 m_clock; // count 4.23s from rising edge of motor_on emu_timer* m_motor_on_timer; diff --git a/src/mess/machine/ti99/genboard.c b/src/mess/machine/ti99/genboard.c index 6f39179d9f0..26842cf94ce 100644 --- a/src/mess/machine/ti99/genboard.c +++ b/src/mess/machine/ti99/genboard.c @@ -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(GKEYBOARD_TAG); m_video = machine().device(VIDEO_SYSTEM_TAG); m_sound = machine().device(TISOUND_TAG); - m_clock = machine().device(GCLOCK_TAG); + m_clock = machine().device(GCLOCK_TAG); m_ready.resolve(conf->ready, *this); diff --git a/src/mess/machine/ti99/genboard.h b/src/mess/machine/ti99/genboard.h index e486dc18d7c..3186fa99682 100644 --- a/src/mess/machine/ti99/genboard.h +++ b/src/mess/machine/ti99/genboard.h @@ -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; diff --git a/src/mess/machine/ti99/hfdc.c b/src/mess/machine/ti99/hfdc.c index 52291b3a0f0..f37c54fb7b7 100644 --- a/src/mess/machine/ti99/hfdc.c +++ b/src/mess/machine/ti99/hfdc.c @@ -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(subdevice(FDC_TAG)); - m_clock = subdevice(CLOCK_TAG); m_dsrrom = memregion(DSRROM)->base(); m_buffer_ram = memregion(BUFFER)->base(); diff --git a/src/mess/machine/ti99/hfdc.h b/src/mess/machine/ti99/hfdc.h index 14a8d381af3..545d4199de7 100644 --- a/src/mess/machine/ti99/hfdc.h +++ b/src/mess/machine/ti99/hfdc.h @@ -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 m_hdc9234; /* Link to the clock chip on the board. */ - device_t* m_clock; + required_device m_clock; /* Determines whether we have access to the CRU bits. */ bool m_cru_select;