mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
mc146818: add square wave output
This commit is contained in:
parent
a35cd5698f
commit
481e06f3fe
@ -39,12 +39,14 @@ mc146818_device::mc146818_device(const machine_config &mconfig, device_type type
|
||||
m_index(0),
|
||||
m_last_refresh(attotime::zero), m_clock_timer(nullptr), m_periodic_timer(nullptr),
|
||||
m_write_irq(*this),
|
||||
m_write_sqw(*this),
|
||||
m_century_index(-1),
|
||||
m_epoch(0),
|
||||
m_use_utc(false),
|
||||
m_binary(false),
|
||||
m_hour(false),
|
||||
m_binyear(false)
|
||||
m_binyear(false),
|
||||
m_sqw_state(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -60,9 +62,11 @@ void mc146818_device::device_start()
|
||||
m_periodic_timer = timer_alloc(TIMER_PERIODIC);
|
||||
|
||||
m_write_irq.resolve_safe();
|
||||
m_write_sqw.resolve_safe();
|
||||
|
||||
save_pointer(NAME(m_data), data_size());
|
||||
save_item(NAME(m_index));
|
||||
save_item(NAME(m_sqw_state));
|
||||
}
|
||||
|
||||
|
||||
@ -75,6 +79,10 @@ void mc146818_device::device_reset()
|
||||
m_data[REG_B] &= ~(REG_B_UIE | REG_B_AIE | REG_B_PIE | REG_B_SQWE);
|
||||
m_data[REG_C] = 0;
|
||||
|
||||
// square wave output is disabled
|
||||
if (m_sqw_state)
|
||||
m_write_sqw(CLEAR_LINE);
|
||||
|
||||
update_irq();
|
||||
}
|
||||
|
||||
@ -87,8 +95,17 @@ void mc146818_device::device_timer(emu_timer &timer, device_timer_id id, int par
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_PERIODIC:
|
||||
m_data[REG_C] |= REG_C_PF;
|
||||
update_irq();
|
||||
m_sqw_state = !m_sqw_state;
|
||||
|
||||
if (m_data[REG_B] & REG_B_SQWE)
|
||||
m_write_sqw(m_sqw_state);
|
||||
|
||||
// periodic flag/interrupt on rising edge of periodic timer
|
||||
if (m_sqw_state)
|
||||
{
|
||||
m_data[REG_C] |= REG_C_PF;
|
||||
update_irq();
|
||||
}
|
||||
break;
|
||||
|
||||
case TIMER_CLOCK:
|
||||
@ -464,8 +481,9 @@ void mc146818_device::update_timer()
|
||||
double periodic_hz = (double) clock() / (1 << shift);
|
||||
|
||||
// TODO: take the time since last timer into account
|
||||
periodic_period = attotime::from_hz(periodic_hz * 2);
|
||||
periodic_interval = attotime::from_hz(periodic_hz);
|
||||
// periodic frequency is doubled to produce square wave output
|
||||
periodic_period = attotime::from_hz(periodic_hz * 4);
|
||||
periodic_interval = attotime::from_hz(periodic_hz * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,6 +680,9 @@ void mc146818_device::internal_write(offs_t offset, uint8_t data)
|
||||
if ((data & REG_B_SET) && !(m_data[REG_B] & REG_B_SET))
|
||||
data &= ~REG_B_UIE;
|
||||
|
||||
if (!(data & REG_B_SQWE) && (m_data[REG_B] & REG_B_SQWE) && m_sqw_state)
|
||||
m_write_sqw(CLEAR_LINE);
|
||||
|
||||
m_data[REG_B] = data;
|
||||
update_irq();
|
||||
break;
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
|
||||
// callbacks
|
||||
auto irq() { return m_write_irq.bind(); }
|
||||
auto sqw() { return m_write_sqw.bind(); }
|
||||
|
||||
// The MC146818 doesn't have century support (some variants do), but when syncing the date & time at startup we can optionally store the century.
|
||||
void set_century_index(int century_index) { assert(!century_count_enabled()); m_century_index = century_index; }
|
||||
@ -165,8 +166,10 @@ protected:
|
||||
emu_timer *m_periodic_timer;
|
||||
|
||||
devcb_write_line m_write_irq;
|
||||
devcb_write_line m_write_sqw;
|
||||
int m_century_index, m_epoch;
|
||||
bool m_use_utc, m_binary, m_hour, m_binyear;
|
||||
bool m_sqw_state;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user