mirror of
https://github.com/holub/mame
synced 2025-07-02 00:29:37 +03:00
emumem: Fix delegates on delay methods
m68000: Fix the vpa timings mac128: Use vpa for the via
This commit is contained in:
parent
fbf2c3fe95
commit
dda0926481
@ -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); }));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user