From d8c697eb85f46a7c5d44819022e78680e4bd4bdd Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Mon, 22 Feb 2021 18:34:17 +0100 Subject: [PATCH] mac: Correctly sync the main cpu to the via. Fixes the floppy writes, probably need to be propagated to other handlers --- src/mame/includes/mac.h | 1 + src/mame/machine/mac.cpp | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/mame/includes/mac.h b/src/mame/includes/mac.h index 2585fa8de49..9e1fcb28f54 100644 --- a/src/mame/includes/mac.h +++ b/src/mame/includes/mac.h @@ -307,6 +307,7 @@ private: void rbv_recalc_irqs(); void update_volume(); + void mac_via_sync(); uint16_t mac_via_r(offs_t offset); void mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); uint16_t mac_via2_r(offs_t offset); diff --git a/src/mame/machine/mac.cpp b/src/mame/machine/mac.cpp index 7c5ee1b61ec..9a3f1ebb14e 100644 --- a/src/mame/machine/mac.cpp +++ b/src/mame/machine/mac.cpp @@ -624,6 +624,9 @@ WRITE_LINE_MEMBER(mac_state::mac_scsi_irq) * *************************************************************************/ uint16_t mac_state::mac_scc_r(offs_t offset) { + if (!machine().side_effects_disabled()) + mac_via_sync(); + uint16_t result; result = m_scc->reg_r(offset); @@ -632,11 +635,13 @@ uint16_t mac_state::mac_scc_r(offs_t offset) void mac_state::mac_scc_w(offs_t offset, uint16_t data) { + mac_via_sync(); m_scc->reg_w(offset, data); } void mac_state::mac_scc_2_w(offs_t offset, uint16_t data) { + mac_via_sync(); m_scc->reg_w(offset, data >> 8); } @@ -925,8 +930,34 @@ WRITE_LINE_MEMBER(mac_state::mac_via_irq) set_via_interrupt(state); } +void mac_state::mac_via_sync() +{ + // The via runs at 783.36KHz while the main cpu runs at 15MHz or + // more, so we need to sync the access with the via clock. Plus + // the whole access takes half a (via) cycle and ends when synced + // with the main cpu again. + + // Get the main cpu time + u64 cycle = m_maincpu->total_cycles(); + + // Get the number of the cycle the via is in at that time + u64 via_cycle = cycle * m_via1->clock() / m_maincpu->clock(); + + // The access is going to start at via_cycle+1 and end at + // via_cycle+1.5, compute what that means in maincpu cycles (the + // +1 rounds up, since the clocks are too different to ever be + // synced). + u64 main_cycle = (via_cycle*2+3) * m_maincpu->clock() / (2*m_via1->clock()) + 1; + + // Finally adjust the main cpu icount as needed. + m_maincpu->adjust_icount(-int(main_cycle - cycle)); +} + uint16_t mac_state::mac_via_r(offs_t offset) { + if (!machine().side_effects_disabled()) + mac_via_sync(); + uint16_t data; offset >>= 8; @@ -936,14 +967,13 @@ uint16_t mac_state::mac_via_r(offs_t offset) logerror("mac_via_r: offset=0x%02x\n", offset); data = m_via1->read(offset); - if (!machine().side_effects_disabled()) - m_maincpu->adjust_icount(m_via_cycles); - return (data & 0xff) | (data << 8); } void mac_state::mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask) { + mac_via_sync(); + offset >>= 8; offset &= 0x0f; @@ -954,8 +984,6 @@ void mac_state::mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask) m_via1->write(offset, data & 0xff); if (ACCESSING_BITS_8_15) m_via1->write(offset, (data >> 8) & 0xff); - - m_maincpu->adjust_icount(m_via_cycles); } /* *************************************************************************