emumem: Fix delegates on delay methods

m68000: Fix the vpa timings
mac128: Use vpa for the via
This commit is contained in:
Olivier Galibert 2023-01-29 19:22:07 +01:00
parent fbf2c3fe95
commit dda0926481
5 changed files with 37 additions and 63 deletions

View File

@ -51,14 +51,21 @@ void m68000_device::do_post_run()
m_post_run = 0;
}
u64 m68000_device::vpa_sync(offs_t address, u64 current_time)
u64 m68000_device::vpa_sync(offs_t, u64 current_time)
{
u64 delta = current_time % 10;
if(delta)
current_time += 10-delta;
u64 mod = current_time % 10;
if(mod < 7)
current_time = current_time - mod + 10;
else
current_time = current_time - mod + 20;
return current_time;
}
u32 m68000_device::vpa_after(offs_t)
{
return 1;
}
void m68000_device::trigger_bus_error()
{
abort_access(PR_BERR);
@ -141,13 +148,13 @@ void m68000_device::default_autovectors_map(address_map &map)
{
if(m_cpu_space_id == AS_CPU_SPACE && !has_configured_map(AS_CPU_SPACE)) {
offs_t mask = make_bitmask<offs_t>(24) - 0xf;
map(mask + 0x3, mask + 0x3).before_time(*this, FUNC(m68000_device::vpa_sync)).lr8(NAME([] () -> u8 { return autovector(1); }));
map(mask + 0x5, mask + 0x5).before_time(*this, FUNC(m68000_device::vpa_sync)).lr8(NAME([] () -> u8 { return autovector(2); }));
map(mask + 0x7, mask + 0x7).before_time(*this, FUNC(m68000_device::vpa_sync)).lr8(NAME([] () -> u8 { return autovector(3); }));
map(mask + 0x9, mask + 0x9).before_time(*this, FUNC(m68000_device::vpa_sync)).lr8(NAME([] () -> u8 { return autovector(4); }));
map(mask + 0xb, mask + 0xb).before_time(*this, FUNC(m68000_device::vpa_sync)).lr8(NAME([] () -> u8 { return autovector(5); }));
map(mask + 0xd, mask + 0xd).before_time(*this, FUNC(m68000_device::vpa_sync)).lr8(NAME([] () -> u8 { return autovector(6); }));
map(mask + 0xf, mask + 0xf).before_time(*this, FUNC(m68000_device::vpa_sync)).lr8(NAME([] () -> u8 { return autovector(7); }));
map(mask + 0x3, mask + 0x3).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(1); }));
map(mask + 0x5, mask + 0x5).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(2); }));
map(mask + 0x7, mask + 0x7).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(3); }));
map(mask + 0x9, mask + 0x9).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(4); }));
map(mask + 0xb, mask + 0xb).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(5); }));
map(mask + 0xd, mask + 0xd).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(6); }));
map(mask + 0xf, mask + 0xf).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(7); }));
}
}

View File

@ -50,6 +50,7 @@ public:
template <typename... T> void set_rte_callback(T &&... args) { m_rte_instr_callback.set(std::forward<T>(args)...); }
u64 vpa_sync(offs_t address, u64 current_time);
u32 vpa_after(offs_t address);
protected:
// Processor special states

View File

@ -242,15 +242,15 @@ public:
// wait-states, device reference -> delegate converter
template <typename T, typename U>
address_map_entry &before_time(T &obj, u64 (U::*ws)(offs_t, u64), const char *name)
{ m_before_time = ws_time_delegate(*make_pointer<U>(obj), ws, name); return *this; }
{ m_before_time = ws_time_delegate(obj, ws, name); return *this; }
template <typename T, typename U>
address_map_entry &before_delay(T &obj, u32 (U::*ws)(offs_t), const char *name)
{ m_before_delay = ws_delay_delegate(*make_pointer<U>(obj), ws, name); return *this; }
{ m_before_delay = ws_delay_delegate(obj, ws, name); return *this; }
template <typename T, typename U>
address_map_entry &after_delay(T &obj, u32 (U::*ws)(offs_t), const char *name)
{ m_after_delay = ws_delay_delegate(*make_pointer<U>(obj), ws, name); return *this; }
{ m_after_delay = ws_delay_delegate(obj, ws, name); return *this; }
// wait-states, lambda -> delegate converter
template <typename T>

View File

@ -868,24 +868,30 @@ void address_space_installer::populate_map_entry(const address_map_entry &entry,
offs_t lowbits_mask = (m_config.data_width() >> (3 - m_config.addr_shift())) - 1;
if (!entry.m_before_time.isnull()) {
auto d = entry.m_before_time;
d.resolve();
if (readorwrite == read_or_write::READ)
install_read_before_time(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, entry.m_before_time);
install_read_before_time(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, d);
else
install_write_before_time(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, entry.m_before_time);
install_write_before_time(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, d);
}
if (!entry.m_before_delay.isnull()) {
auto d = entry.m_before_delay;
d.resolve();
if (readorwrite == read_or_write::READ)
install_read_before_delay(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, entry.m_before_delay);
install_read_before_delay(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, d);
else
install_write_before_delay(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, entry.m_before_delay);
install_write_before_delay(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, d);
}
if (!entry.m_after_delay.isnull()) {
auto d = entry.m_after_delay;
d.resolve();
if (readorwrite == read_or_write::READ)
install_read_after_delay(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, entry.m_after_delay);
install_read_after_delay(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, d);
else
install_write_after_delay(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, entry.m_after_delay);
install_write_after_delay(entry.m_addrstart & ~lowbits_mask, entry.m_addrend | lowbits_mask, entry.m_addrmirror, d);
}
}

View File

@ -207,8 +207,6 @@ private:
void ram_w_se(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint16_t ram_600000_r(offs_t offset);
void ram_600000_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~ 0);
void via_sync();
void via_sync_end();
uint16_t mac_via_r(offs_t offset);
void mac_via_w(offs_t offset, uint16_t data);
uint16_t mac_autovector_r(offs_t offset);
@ -722,36 +720,6 @@ WRITE_LINE_MEMBER(mac128_state::mac_via_irq)
set_via_interrupt(state);
}
void mac128_state::via_sync()
{
// The VIA runs from the E clock of the 68k and uses VPA.
// That means:
// - The 68000 starts the access cycle, with AS and the address bus. It's validated at cycle+1.
// - The glue chip sets VPA. The 68000 sees it and acts on it at cycle+2.
// - Between cycle+2 and cycle+11, the E clock goes up. The VIA
// is synced on that clock, so that's at a multiple of 10 in
// absolute time
// - 4 cycles later E goes down and that's the end of the access,
// We sync on the start of cycle (so that the via timings go ok)
// then on the end on via_sync_end()
uint64_t cur_cycle = m_maincpu->total_cycles();
uint64_t vpa_cycle = cur_cycle+2;
uint64_t via_start_cycle = (vpa_cycle + 9) / 10;
uint64_t m68k_start_cycle = via_start_cycle * 10;
m_maincpu->adjust_icount(cur_cycle - m68k_start_cycle); // 4 cycles already counted by the core
}
void mac128_state::via_sync_end()
{
m_maincpu->adjust_icount(-4);
}
uint16_t mac128_state::mac_via_r(offs_t offset)
{
uint16_t data;
@ -759,11 +727,7 @@ uint16_t mac128_state::mac_via_r(offs_t offset)
offset >>= 8;
offset &= 0x0f;
via_sync();
data = m_via->read(offset);
via_sync_end();
return (data & 0xff) | (data << 8);
}
@ -772,11 +736,7 @@ void mac128_state::mac_via_w(offs_t offset, uint16_t data)
offset >>= 8;
offset &= 0x0f;
via_sync();
m_via->write(offset, (data >> 8) & 0xff);
via_sync_end();
}
void mac128_state::mac_autovector_w(offs_t offset, uint16_t data)
@ -1078,7 +1038,7 @@ void mac128_state::mac512ke_map(address_map &map)
map(0x800000, 0x9fffff).r(m_scc, FUNC(z80scc_device::dc_ab_r)).umask16(0xff00);
map(0xa00000, 0xbfffff).w(m_scc, FUNC(z80scc_device::dc_ab_w)).umask16(0x00ff);
map(0xc00000, 0xdfffff).rw(FUNC(mac128_state::mac_iwm_r), FUNC(mac128_state::mac_iwm_w));
map(0xe80000, 0xefffff).rw(FUNC(mac128_state::mac_via_r), FUNC(mac128_state::mac_via_w));
map(0xe80000, 0xefffff).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).rw(FUNC(mac128_state::mac_via_r), FUNC(mac128_state::mac_via_w));
map(0xfffff0, 0xffffff).rw(FUNC(mac128_state::mac_autovector_r), FUNC(mac128_state::mac_autovector_w));
}
@ -1090,7 +1050,7 @@ void mac128_state::macplus_map(address_map &map)
map(0x800000, 0x9fffff).r(m_scc, FUNC(z80scc_device::dc_ab_r)).umask16(0xff00);
map(0xa00000, 0xbfffff).w(m_scc, FUNC(z80scc_device::dc_ab_w)).umask16(0x00ff);
map(0xc00000, 0xdfffff).rw(FUNC(mac128_state::mac_iwm_r), FUNC(mac128_state::mac_iwm_w));
map(0xe80000, 0xefffff).rw(FUNC(mac128_state::mac_via_r), FUNC(mac128_state::mac_via_w));
map(0xe80000, 0xefffff).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).rw(FUNC(mac128_state::mac_via_r), FUNC(mac128_state::mac_via_w));
map(0xfffff0, 0xffffff).rw(FUNC(mac128_state::mac_autovector_r), FUNC(mac128_state::mac_autovector_w));
}
@ -1102,7 +1062,7 @@ void mac128_state::macse_map(address_map &map)
map(0x900000, 0x9fffff).r(m_scc, FUNC(z80scc_device::dc_ab_r)).umask16(0xff00);
map(0xb00000, 0xbfffff).w(m_scc, FUNC(z80scc_device::dc_ab_w)).umask16(0x00ff);
map(0xd00000, 0xdfffff).rw(FUNC(mac128_state::mac_iwm_r), FUNC(mac128_state::mac_iwm_w));
map(0xe80000, 0xefffff).rw(FUNC(mac128_state::mac_via_r), FUNC(mac128_state::mac_via_w));
map(0xe80000, 0xefffff).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).rw(FUNC(mac128_state::mac_via_r), FUNC(mac128_state::mac_via_w));
map(0xfffff0, 0xffffff).rw(FUNC(mac128_state::mac_autovector_r), FUNC(mac128_state::mac_autovector_w));
}