diff options
Diffstat (limited to 'src/devices/machine/mos6530n.cpp')
-rw-r--r-- | src/devices/machine/mos6530n.cpp | 831 |
1 files changed, 0 insertions, 831 deletions
diff --git a/src/devices/machine/mos6530n.cpp b/src/devices/machine/mos6530n.cpp deleted file mode 100644 index 23ec8c408fb..00000000000 --- a/src/devices/machine/mos6530n.cpp +++ /dev/null @@ -1,831 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -/********************************************************************** - - MOS Technology 6530 Memory, I/O, Timer Array emulation - MOS Technology 6532 RAM, I/O, Timer Array emulation - -**********************************************************************/ - -#include "emu.h" -#include "mos6530n.h" - -#define LOG_GENERAL (1U << 0) -#define LOG_TIMER (1U << 1) - -//#define VERBOSE (LOG_GENERAL | LOG_TIMER) -#include "logmacro.h" - -#define LOGTIMER(...) LOGMASKED(LOG_TIMER, __VA_ARGS__) - - - -//************************************************************************** -// DEVICE DEFINITIONS -//************************************************************************** - -DEFINE_DEVICE_TYPE(MOS6530_NEW, mos6530_new_device, "mos6530_new", "MOS 6530 (new)") -DEFINE_DEVICE_TYPE(MOS6532_NEW, mos6532_new_device, "mos6532_new", "MOS 6532 (new)") - - -void mos6530_new_device::rom_map(address_map &map) -{ - map.global_mask(0x3ff); - map(0x000, 0x3ff).r(FUNC(mos6530_new_device::rom_r)); -} - -void mos6530_new_device::ram_map(address_map &map) -{ - map.global_mask(0x3f); - map(0x00, 0x3f).rw(FUNC(mos6530_new_device::ram_r), FUNC(mos6530_new_device::ram_w)); -} - -void mos6530_new_device::io_map(address_map &map) -{ - map.global_mask(0xf); - map(0x00, 0x00).mirror(0x8).rw(FUNC(mos6530_new_device::pa_data_r), FUNC(mos6530_new_device::pa_data_w)); - map(0x01, 0x01).mirror(0x8).rw(FUNC(mos6530_new_device::pa_ddr_r), FUNC(mos6530_new_device::pa_ddr_w)); - map(0x02, 0x02).mirror(0x8).rw(FUNC(mos6530_new_device::pb_data_r), FUNC(mos6530_new_device::pb_data_w)); - map(0x03, 0x03).mirror(0x8).rw(FUNC(mos6530_new_device::pb_ddr_r), FUNC(mos6530_new_device::pb_ddr_w)); - map(0x04, 0x07).w(FUNC(mos6530_new_device::timer_off_w)); - map(0x0c, 0x0f).w(FUNC(mos6530_new_device::timer_on_w)); - map(0x04, 0x04).mirror(0x2).r(FUNC(mos6530_new_device::timer_off_r)); - map(0x0c, 0x0c).mirror(0x2).r(FUNC(mos6530_new_device::timer_on_r)); - map(0x05, 0x05).mirror(0xa).r(FUNC(mos6530_new_device::irq_r)); -} - -void mos6532_new_device::ram_map(address_map &map) -{ - map.global_mask(0x7f); - map(0x00, 0x7f).rw(FUNC(mos6532_new_device::ram_r), FUNC(mos6532_new_device::ram_w)); -} - -void mos6532_new_device::io_map(address_map &map) -{ - map.global_mask(0x1f); - map(0x00, 0x00).mirror(0x18).rw(FUNC(mos6532_new_device::pa_data_r), FUNC(mos6532_new_device::pa_data_w)); // SWCHA - map(0x01, 0x01).mirror(0x18).rw(FUNC(mos6532_new_device::pa_ddr_r), FUNC(mos6532_new_device::pa_ddr_w)); // SWACNT - map(0x02, 0x02).mirror(0x18).rw(FUNC(mos6532_new_device::pb_data_r), FUNC(mos6532_new_device::pb_data_w)); // SWCHB - map(0x03, 0x03).mirror(0x18).rw(FUNC(mos6532_new_device::pb_ddr_r), FUNC(mos6532_new_device::pb_ddr_w)); // SWBCNT - map(0x14, 0x17).w(FUNC(mos6532_new_device::timer_off_w)); - map(0x1c, 0x1f).w(FUNC(mos6532_new_device::timer_on_w)); - map(0x04, 0x04).mirror(0x12).r(FUNC(mos6532_new_device::timer_off_r)); - map(0x0c, 0x0c).mirror(0x12).r(FUNC(mos6532_new_device::timer_on_r)); - map(0x05, 0x05).mirror(0x1a).r(FUNC(mos6532_new_device::irq_r)); - map(0x04, 0x07).mirror(0x8).w(FUNC(mos6532_new_device::edge_w)); -} - -READ8_MEMBER(mos6532_new_device::io_r) -{ - offset &= 0x1f; - uint8_t ret = 0; - - if (offset == 0x00 || offset == 0x08 || offset == 0x10 || offset == 0x18) ret = pa_data_r(space, 0); - if (offset == 0x01 || offset == 0x09 || offset == 0x11 || offset == 0x19) ret = pa_ddr_r(space, 0); - if (offset == 0x02 || offset == 0x0a || offset == 0x12 || offset == 0x1a) ret = pb_data_r(space, 0); - if (offset == 0x03 || offset == 0x0b || offset == 0x13 || offset == 0x1b) ret = pb_ddr_r(space, 0); - - if (offset == 0x04 || offset == 0x06 || offset == 0x14 || offset == 0x16) ret = timer_off_r(space, 0); - if (offset == 0x0c || offset == 0x0e || offset == 0x1c || offset == 0x1e) ret = timer_on_r(space, 0); - - if (offset == 0x05 || offset == 0x07 || offset == 0x0d || offset == 0x0f) ret = irq_r(space, 0); - if (offset == 0x15 || offset == 0x17 || offset == 0x1d || offset == 0x1f) ret = irq_r(space, 0); - - return ret; -} - -WRITE8_MEMBER(mos6532_new_device::io_w) -{ - offset &= 0x1f; - - if (offset == 0x00 || offset == 0x08 || offset == 0x10 || offset == 0x18) pa_data_w(space, 0, data); - if (offset == 0x01 || offset == 0x09 || offset == 0x11 || offset == 0x19) pa_ddr_w(space, 0, data); - if (offset == 0x02 || offset == 0x0a || offset == 0x12 || offset == 0x1a) pb_data_w(space, 0, data); - if (offset == 0x03 || offset == 0x0b || offset == 0x13 || offset == 0x1b) pb_ddr_w(space, 0, data); - if (offset == 0x14 || offset == 0x15 || offset == 0x16 || offset == 0x17) timer_off_w(space, offset&3, data); - if (offset == 0x1c || offset == 0x1d || offset == 0x1e || offset == 0x1f) timer_on_w(space, offset&3, data); - - if (offset == 0x04 || offset == 0x05 || offset == 0x06 || offset == 0x07) edge_w(space, offset&3, data); - if (offset == 0x0c || offset == 0x0d || offset == 0xea || offset == 0x0f) edge_w(space, offset&3, data); -} - - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// mos6530_device_base - constructor -//------------------------------------------------- - -mos6530_device_base::mos6530_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, type, tag, owner, clock), - m_ram(*this, finder_base::DUMMY_TAG), - m_rom(*this, DEVICE_SELF), - m_irq_cb(*this), - m_in8_pa_cb(*this), - m_out8_pa_cb(*this), - m_in8_pb_cb(*this), - m_out8_pb_cb(*this), - m_in_pa_cb{ { *this }, { *this }, { *this }, { *this }, { *this }, { *this }, { *this }, { *this } }, - m_out_pa_cb{ { *this }, { *this }, { *this }, { *this }, { *this }, { *this }, { *this }, { *this } }, - m_in_pb_cb{ { *this }, { *this }, { *this }, { *this }, { *this }, { *this }, { *this }, { *this } }, - m_out_pb_cb{ { *this }, { *this }, { *this }, { *this }, { *this }, { *this }, { *this }, { *this } }, - m_pa_in(0xff), - m_pa_out(0), - m_pa_ddr(0), - m_pa7(0), - m_pa7_dir(0), - m_pb_in(0xff), - m_pb_out(0), - m_pb_ddr(0), - m_ie_timer(false), - m_irq_timer(true), - m_ie_edge(false), - m_irq_edge(false) -{ - cur_live.tm = attotime::never; - cur_live.state = IDLE; - cur_live.next_state = -1; -} - - -//------------------------------------------------- -// mos6530_new_device - constructor -//------------------------------------------------- - -mos6530_new_device::mos6530_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : mos6530_device_base(mconfig, MOS6530_NEW, tag, owner, clock) { } - - -//------------------------------------------------- -// mos6532_new_device - constructor -//------------------------------------------------- - -mos6532_new_device::mos6532_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : mos6530_device_base(mconfig, MOS6532_NEW, tag, owner, clock) { } - - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void mos6530_device_base::device_start() -{ - // resolve callbacks - m_irq_cb.resolve_safe(); - m_in8_pa_cb.resolve(); - m_out8_pa_cb.resolve(); - m_in8_pb_cb.resolve(); - m_out8_pb_cb.resolve(); - for (auto &cb : m_in_pa_cb) - cb.resolve(); - for (auto &cb : m_out_pa_cb) - cb.resolve_safe(); - for (auto &cb : m_in_pb_cb) - cb.resolve(); - for (auto &cb : m_out_pb_cb) - cb.resolve_safe(); - - // allocate timer - t_gen = timer_alloc(0); - - // state saving - save_item(NAME(m_pa_in)); - save_item(NAME(m_pa_out)); - save_item(NAME(m_pa_ddr)); - save_item(NAME(m_pa7)); - save_item(NAME(m_pa7_dir)); - save_item(NAME(m_pb_in)); - save_item(NAME(m_pb_out)); - save_item(NAME(m_pb_ddr)); - save_item(NAME(m_ie_timer)); - save_item(NAME(m_irq_timer)); - save_item(NAME(m_ie_edge)); - save_item(NAME(m_irq_edge)); - save_item(NAME(m_prescale)); - save_item(NAME(m_timer)); -} - -void mos6530_new_device::device_start() -{ - mos6530_device_base::device_start(); - - // allocate RAM - m_ram.allocate(0x40); -} - -void mos6532_new_device::device_start() -{ - mos6530_device_base::device_start(); - - // allocate RAM - m_ram.allocate(0x80); -} - - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void mos6530_device_base::device_reset() -{ - m_pa_out = 0xff; - m_pa_ddr = 0; - m_pb_out = 0xff; // a7800 One-On-One Basketball (1on1u) needs this or you can't start a game, it doesn't initialize it. (see MT6060) - m_pb_ddr = 0; - - m_ie_timer = false; - m_irq_timer = false; - m_ie_edge = false; - m_irq_edge = false; - m_pa7_dir = 0; - - update_pa(); - update_pb(); - update_irq(); - edge_detect(); - - m_timer = 0xff; - m_prescale = 1024; - - if (cur_live.state != IDLE) { - live_abort(); - } - - live_start(); - live_run(); -} - - -//------------------------------------------------- -// device_timer - handler timer events -//------------------------------------------------- - -void mos6530_device_base::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - live_sync(); - live_run(); -} - - -//------------------------------------------------- -// update_pa - -//------------------------------------------------- - -void mos6530_device_base::update_pa() -{ - uint8_t out = m_pa_out; - uint8_t ddr = m_pa_ddr; - uint8_t data = (out & ddr) | (ddr ^ 0xff); - - if (m_out8_pa_cb.isnull()) - { - m_out_pa_cb[0](BIT(data, 0)); - m_out_pa_cb[1](BIT(data, 1)); - m_out_pa_cb[2](BIT(data, 2)); - m_out_pa_cb[3](BIT(data, 3)); - m_out_pa_cb[4](BIT(data, 4)); - m_out_pa_cb[5](BIT(data, 5)); - m_out_pa_cb[6](BIT(data, 6)); - m_out_pa_cb[7](BIT(data, 7)); - } - else - { - m_out8_pa_cb(data); - } -} - - -//------------------------------------------------- -// update_pb - -//------------------------------------------------- - -void mos6530_device_base::update_pb() -{ - uint8_t out = m_pb_out; - uint8_t ddr = m_pb_ddr; - uint8_t data = (out & ddr) | (ddr ^ 0xff); - - if (m_out8_pb_cb.isnull()) - { - m_out_pb_cb[0](BIT(data, 0)); - m_out_pb_cb[1](BIT(data, 1)); - m_out_pb_cb[2](BIT(data, 2)); - m_out_pb_cb[3](BIT(data, 3)); - m_out_pb_cb[4](BIT(data, 4)); - m_out_pb_cb[5](BIT(data, 5)); - m_out_pb_cb[6](BIT(data, 6)); - m_out_pb_cb[7](BIT(data, 7)); - } - else - { - m_out8_pb_cb(data); - } -} - -void mos6530_new_device::update_pb() -{ - uint8_t out = m_pb_out; - uint8_t ddr = m_pb_ddr; - uint8_t data = (out & ddr) | (ddr ^ 0xff); - - if (m_ie_timer) - { - if (m_irq_timer) { - data |= IRQ_TIMER; - } else { - data &= ~IRQ_TIMER; - } - } - - if (m_out8_pb_cb.isnull()) - { - m_out_pb_cb[0](BIT(data, 0)); - m_out_pb_cb[1](BIT(data, 1)); - m_out_pb_cb[2](BIT(data, 2)); - m_out_pb_cb[3](BIT(data, 3)); - m_out_pb_cb[4](BIT(data, 4)); - m_out_pb_cb[5](BIT(data, 5)); - m_out_pb_cb[6](BIT(data, 6)); - m_out_pb_cb[7](BIT(data, 7)); - } - else - { - m_out8_pb_cb(data); - } -} - - -//------------------------------------------------- -// update_irq - -//------------------------------------------------- - -void mos6530_device_base::update_irq() -{ - int state = CLEAR_LINE; - - if (m_ie_timer && m_irq_timer) state = ASSERT_LINE; - if (m_ie_edge && m_irq_edge) state = ASSERT_LINE; - - m_irq_cb(state); -} - -void mos6530_new_device::update_irq() -{ - update_pb(); -} - - -//------------------------------------------------- -// get_irq_flags - -//------------------------------------------------- - -uint8_t mos6530_device_base::get_irq_flags() -{ - uint8_t data = 0; - - if (m_irq_timer) data |= IRQ_TIMER; - if (m_irq_edge) data |= IRQ_EDGE; - - return data; -} - -uint8_t mos6530_new_device::get_irq_flags() -{ - uint8_t data = 0; - - if (m_irq_timer) data |= IRQ_TIMER; - - return data; -} - - -//------------------------------------------------- -// edge_detect - -//------------------------------------------------- - -void mos6530_device_base::edge_detect() -{ - uint8_t ddr_out = m_pa_ddr; - uint8_t ddr_in = m_pa_ddr ^ 0xff; - uint8_t data = (m_pa_out & ddr_out) | (m_pa_in & ddr_in); - int state = BIT(data, 7); - - if ((m_pa7 ^ state) && (m_pa7_dir ^ state) == 0 && !m_irq_edge) - { - LOG("%s %s edge-detect IRQ\n", machine().time().as_string(), name()); - - m_irq_edge = true; - update_irq(); - } - - m_pa7 = state; -} - - -//------------------------------------------------- -// pa_w - -//------------------------------------------------- - -void mos6530_device_base::pa_w(int bit, int state) -{ - LOG("%s %s %s Port A Data Bit %u State %u\n", machine().time().as_string(), machine().describe_context(), name(), bit, state); - - m_pa_in &= ~(1 << bit); - m_pa_in |= (state << bit); - - edge_detect(); -} - - -//------------------------------------------------- -// pb_w - -//------------------------------------------------- - -void mos6530_device_base::pb_w(int bit, int state) -{ - LOG("%s %s %s Port B Data Bit %u State %u\n", machine().time().as_string(), machine().describe_context(), name(), bit, state); - - m_pb_in &= ~(1 << bit); - m_pb_in |= (state << bit); -} - - -//------------------------------------------------- -// pa_data_r - -//------------------------------------------------- - -READ8_MEMBER( mos6530_device_base::pa_data_r ) -{ - uint8_t in = 0; - - if (m_in8_pa_cb.isnull()) - { - in |= (m_in_pa_cb[0].isnull() ? BIT(m_pa_in, 0) : m_in_pa_cb[0]()); - in |= (m_in_pa_cb[1].isnull() ? BIT(m_pa_in, 1) : m_in_pa_cb[1]()) << 1; - in |= (m_in_pa_cb[2].isnull() ? BIT(m_pa_in, 2) : m_in_pa_cb[2]()) << 2; - in |= (m_in_pa_cb[3].isnull() ? BIT(m_pa_in, 3) : m_in_pa_cb[3]()) << 3; - in |= (m_in_pa_cb[4].isnull() ? BIT(m_pa_in, 4) : m_in_pa_cb[4]()) << 4; - in |= (m_in_pa_cb[5].isnull() ? BIT(m_pa_in, 5) : m_in_pa_cb[5]()) << 5; - in |= (m_in_pa_cb[6].isnull() ? BIT(m_pa_in, 6) : m_in_pa_cb[6]()) << 6; - in |= (m_in_pa_cb[7].isnull() ? BIT(m_pa_in, 7) : m_in_pa_cb[7]()) << 7; - } - else - { - in = m_in8_pa_cb(); - } - - uint8_t out = m_pa_out; - uint8_t ddr_out = m_pa_ddr; - uint8_t ddr_in = m_pa_ddr ^ 0xff; - uint8_t data = (out & ddr_out) | (in & ddr_in); - - LOG("%s %s %s Port A Data In %02x\n", machine().time().as_string(), machine().describe_context(), name(), data); - - return data; -} - - -//------------------------------------------------- -// pa_data_w - -//------------------------------------------------- - -WRITE8_MEMBER( mos6530_device_base::pa_data_w ) -{ - m_pa_out = data; - - LOG("%s %s %s Port A Data Out %02x\n", machine().time().as_string(), machine().describe_context(), name(), data); - - update_pa(); - edge_detect(); -} - - -//------------------------------------------------- -// pa_ddr_w - -//------------------------------------------------- - -WRITE8_MEMBER( mos6530_device_base::pa_ddr_w ) -{ - m_pa_ddr = data; - - LOG("%s %s %s Port A DDR %02x\n", machine().time().as_string(), machine().describe_context(), name(), data); - - update_pa(); - edge_detect(); -} - - -//------------------------------------------------- -// pb_data_r - -//------------------------------------------------- - -READ8_MEMBER( mos6530_device_base::pb_data_r ) -{ - uint8_t in = 0; - - if (m_in8_pb_cb.isnull()) - { - in |= (m_in_pb_cb[0].isnull() ? BIT(m_pb_in, 0) : m_in_pb_cb[0]()); - in |= (m_in_pb_cb[1].isnull() ? BIT(m_pb_in, 1) : m_in_pb_cb[1]()) << 1; - in |= (m_in_pb_cb[2].isnull() ? BIT(m_pb_in, 2) : m_in_pb_cb[2]()) << 2; - in |= (m_in_pb_cb[3].isnull() ? BIT(m_pb_in, 3) : m_in_pb_cb[3]()) << 3; - in |= (m_in_pb_cb[4].isnull() ? BIT(m_pb_in, 4) : m_in_pb_cb[4]()) << 4; - in |= (m_in_pb_cb[5].isnull() ? BIT(m_pb_in, 5) : m_in_pb_cb[5]()) << 5; - in |= (m_in_pb_cb[6].isnull() ? BIT(m_pb_in, 6) : m_in_pb_cb[6]()) << 6; - in |= (m_in_pb_cb[7].isnull() ? BIT(m_pb_in, 7) : m_in_pb_cb[7]()) << 7; - } - else - { - in = m_in8_pb_cb(); - } - - uint8_t out = m_pb_out; - uint8_t ddr_out = m_pb_ddr; - uint8_t ddr_in = m_pb_ddr ^ 0xff; - uint8_t data = (out & ddr_out) | (in & ddr_in); - - LOG("%s %s %s Port B Data In %02x\n", machine().time().as_string(), machine().describe_context(), name(), data); - - return data; -} - - -//------------------------------------------------- -// pb_data_w - -//------------------------------------------------- - -WRITE8_MEMBER( mos6530_device_base::pb_data_w ) -{ - m_pb_out = data; - - LOG("%s %s %s Port B Data Out %02x\n", machine().time().as_string(), machine().describe_context(), name(), data); - - update_pb(); -} - - -//------------------------------------------------- -// pb_ddr_w - -//------------------------------------------------- - -WRITE8_MEMBER( mos6530_device_base::pb_ddr_w ) -{ - m_pb_ddr = data; - - LOG("%s %s %s Port B DDR %02x\n", machine().time().as_string(), machine().describe_context(), name(), data); - - update_pb(); -} - - -//------------------------------------------------- -// timer_r - -//------------------------------------------------- - -READ8_MEMBER( mos6530_device_base::timer_off_r ) -{ - if (machine().side_effects_disabled()) - return 0; - - return timer_r(false); -} - -READ8_MEMBER( mos6530_device_base::timer_on_r ) -{ - if (machine().side_effects_disabled()) - return 0; - - return timer_r(true); -} - -uint8_t mos6530_device_base::timer_r(bool ie) -{ - uint8_t data; - - live_sync(); - - m_ie_timer = ie; - if (cur_live.tm_irq != machine().time()) { - m_irq_timer = false; - } - update_irq(); - - data = cur_live.value; - - LOGTIMER("%s %s %s Timer read %02x IE %u\n", machine().time().as_string(), machine().describe_context(), name(), data, m_ie_timer ? 1 : 0); - - checkpoint(); - live_run(); - - return data; -} - - -//------------------------------------------------- -// irq_r - -//------------------------------------------------- - -READ8_MEMBER( mos6530_device_base::irq_r ) -{ - uint8_t data = get_irq_flags(); - - if (!machine().side_effects_disabled()) { - if (m_irq_edge) { - m_irq_edge = false; - update_irq(); - } - } - - return data; -} - - -//------------------------------------------------- -// timer_w - -//------------------------------------------------- - -WRITE8_MEMBER( mos6530_device_base::timer_off_w ) -{ - timer_w(offset, data, false); -} - -WRITE8_MEMBER( mos6530_device_base::timer_on_w ) -{ - timer_w(offset, data, true); -} - -void mos6530_device_base::timer_w(offs_t offset, uint8_t data, bool ie) -{ - live_sync(); - - m_timer = data; - - switch (offset & 0x03) { - case 0: m_prescale = 1; break; - case 1: m_prescale = 8; break; - case 2: m_prescale = 64; break; - case 3: m_prescale = 1024; break; - } - - m_ie_timer = ie; - if (cur_live.tm_irq != machine().time()) { - m_irq_timer = false; - } - update_irq(); - - LOGTIMER("%s %s %s Timer value %02x prescale %u IE %u\n", machine().time().as_string(), machine().describe_context(), name(), data, m_prescale, m_ie_timer ? 1 : 0); - - checkpoint(); - - if (cur_live.state != IDLE) { - live_abort(); - } - - live_start(); - live_run(); -} - - -//------------------------------------------------- -// edge_w - -//------------------------------------------------- - -WRITE8_MEMBER( mos6530_device_base::edge_w ) -{ - m_pa7_dir = BIT(data, 0); - m_ie_edge = BIT(data, 1) ? false : true; - - LOG("%s %s %s %s edge-detect, %s interrupt\n", machine().time().as_string(), machine().describe_context(), name(), m_pa7_dir ? "positive" : "negative", m_ie_edge ? "enable" : "disable"); -} - - -//------------------------------------------------- -// live_start - -//------------------------------------------------- - -void mos6530_device_base::live_start() -{ - cur_live.period = attotime::from_ticks(m_prescale, clock()); - cur_live.tm = machine().time() + attotime::from_hz(clock()); - cur_live.state = RUNNING; - cur_live.next_state = -1; - - cur_live.value = m_timer; - - checkpoint(); - - live_run(); -} - -void mos6530_device_base::checkpoint() -{ - checkpoint_live = cur_live; -} - -void mos6530_device_base::rollback() -{ - cur_live = checkpoint_live; -} - -void mos6530_device_base::live_delay(int state) -{ - cur_live.next_state = state; - if(cur_live.tm != machine().time()) - t_gen->adjust(cur_live.tm - machine().time()); - else - live_sync(); -} - -void mos6530_device_base::live_sync() -{ - if(!cur_live.tm.is_never()) { - if(cur_live.tm > machine().time()) { - rollback(); - live_run(machine().time()); - } else { - if(cur_live.next_state != -1) { - cur_live.state = cur_live.next_state; - cur_live.next_state = -1; - } - if(cur_live.state == IDLE) { - cur_live.tm = attotime::never; - } - } - cur_live.next_state = -1; - checkpoint(); - } -} - -void mos6530_device_base::live_abort() -{ - if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) { - rollback(); - live_run(machine().time()); - } - - cur_live.tm = attotime::never; - cur_live.state = IDLE; - cur_live.next_state = -1; - cur_live.tm_irq = attotime::never; -} - -void mos6530_device_base::live_run(const attotime &limit) -{ - if(cur_live.state == IDLE || cur_live.next_state != -1) - return; - - for(;;) { - switch(cur_live.state) { - case RUNNING: { - if (cur_live.tm > limit) - return; - - cur_live.value--; - - if (cur_live.value == 0xff) { - live_delay(RUNNING_SYNCPOINT); - return; - } else { - LOGTIMER("%s %s timer %02x\n", cur_live.tm.as_string(), name(), cur_live.value); - - cur_live.tm += cur_live.period; - } - break; - } - - case RUNNING_SYNCPOINT: { - LOGTIMER("%s %s timer %02x interrupt\n", cur_live.tm.as_string(), name(), cur_live.value); - - cur_live.tm_irq = cur_live.tm; - m_irq_timer = true; - update_irq(); - - checkpoint(); - - cur_live.state = RUNNING_AFTER_INTERRUPT; - cur_live.period = attotime::from_hz(clock()); - cur_live.tm += cur_live.period; - break; - } - - case RUNNING_AFTER_INTERRUPT: { - if (cur_live.tm > limit) - return; - - cur_live.value--; - - LOGTIMER("%s %s timer %02x\n", cur_live.tm.as_string(), name(), cur_live.value); - - if (!cur_live.value) { - cur_live.state = IDLE; - return; - } - - cur_live.tm += cur_live.period; - break; - } - } - } -} |