mc88000: allow for multiple cmmus

This commit is contained in:
Patrick Mackinlay 2024-07-08 11:22:25 +07:00
parent e84673d932
commit 91ef419166
8 changed files with 48 additions and 64 deletions

View File

@ -67,14 +67,11 @@ void vme_mvme180_card_device::device_add_mconfig(machine_config &config)
{
MC88100(config, m_cpu, 40_MHz_XTAL / 2);
m_cpu->set_addrmap(AS_PROGRAM, &vme_mvme180_card_device::cpu_mem);
m_cpu->set_cmmu_code([this](u32 const address) -> mc88200_device & { return *m_mmu[0]; });
m_cpu->set_cmmu_data([this](u32 const address) -> mc88200_device & { return *m_mmu[1]; });
MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x7e);
m_mmu[0]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_i(m_mmu[0]);
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x7f);
m_mmu[1]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_d(m_mmu[1]);
MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x7e).set_mbus(m_cpu, AS_PROGRAM);
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x7f).set_mbus(m_cpu, AS_PROGRAM);
SCN2681(config, m_duart, 3.6864_MHz_XTAL);
m_duart->irq_cb().set(FUNC(vme_mvme180_card_device::irq_w<6>));

View File

@ -96,14 +96,11 @@ void vme_mvme181_card_device::device_add_mconfig(machine_config &config)
{
MC88100(config, m_cpu, 40_MHz_XTAL / 2);
m_cpu->set_addrmap(AS_PROGRAM, &vme_mvme181_card_device::cpu_mem);
m_cpu->set_cmmu_code([this](u32 const address) -> mc88200_device & { return *m_mmu[0]; });
m_cpu->set_cmmu_data([this](u32 const address) -> mc88200_device & { return *m_mmu[1]; });
MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x7e);
m_mmu[0]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_i(m_mmu[0]);
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x7f);
m_mmu[1]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_d(m_mmu[1]);
MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x7e).set_mbus(m_cpu, AS_PROGRAM);
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x7f).set_mbus(m_cpu, AS_PROGRAM);
DS1315(config, m_rtc, 0); // DS1216

View File

@ -106,14 +106,11 @@ void vme_mvme187_card_device::device_add_mconfig(machine_config &config)
{
MC88100(config, m_cpu, 50_MHz_XTAL / 2);
m_cpu->set_addrmap(AS_PROGRAM, &vme_mvme187_card_device::cpu_mem);
m_cpu->set_cmmu_code([this](u32 const address) -> mc88200_device & { return *m_mmu[0]; });
m_cpu->set_cmmu_data([this](u32 const address) -> mc88200_device & { return *m_mmu[1]; });
MC88200(config, m_mmu[0], 50_MHz_XTAL / 2, 0x77);
m_mmu[0]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_i(m_mmu[0]);
MC88200(config, m_mmu[1], 50_MHz_XTAL / 2, 0x7f);
m_mmu[1]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_d(m_mmu[1]);
MC88200(config, m_mmu[0], 50_MHz_XTAL / 2, 0x77).set_mbus(m_cpu, AS_PROGRAM);
MC88200(config, m_mmu[1], 50_MHz_XTAL / 2, 0x7f).set_mbus(m_cpu, AS_PROGRAM);
DS1643(config, m_rtc);

View File

@ -86,14 +86,11 @@ void vme_tp881v_card_device::device_add_mconfig(machine_config &config)
{
MC88100(config, m_cpu, 40_MHz_XTAL / 2);
m_cpu->set_addrmap(AS_PROGRAM, &vme_tp881v_card_device::cpu_mem);
m_cpu->set_cmmu_code([this](u32 const address) -> mc88200_device & { return *m_mmu[0]; });
m_cpu->set_cmmu_data([this](u32 const address) -> mc88200_device & { return *m_mmu[1]; });
MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x00);
m_mmu[0]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_i(m_mmu[0]);
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x01);
m_mmu[1]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_d(m_mmu[1]);
MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x00).set_mbus(m_cpu, AS_PROGRAM);
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x01).set_mbus(m_cpu, AS_PROGRAM);
// per-jp interrupt controllers
// 4MHz input clock, ct3 gives 100Hz clock, ct2 counts at 10kHz

View File

@ -148,8 +148,8 @@ mc88100_device::mc88100_device(const machine_config &mconfig, const char *tag, d
: cpu_device(mconfig, MC88100, tag, owner, clock)
, m_code_config("code", ENDIANNESS_BIG, 32, 32, 0)
, m_data_config("data", ENDIANNESS_BIG, 32, 32, 0)
, m_cmmu_d(*this, finder_base::DUMMY_TAG)
, m_cmmu_i(*this, finder_base::DUMMY_TAG)
, m_cmmu_code(nullptr)
, m_cmmu_data(nullptr)
, m_sb(0)
, m_r{ 0 }
, m_cr{ 0 }
@ -183,13 +183,13 @@ bool mc88100_device::memory_translate(int spacenum, int intention, offs_t &addre
{
case TR_READ:
case TR_WRITE:
if (m_cmmu_d)
return m_cmmu_d->translate(intention, address, m_cr[PSR] & PSR_MODE);
if (m_cmmu_data)
return m_cmmu_data(address).translate(intention, address, m_cr[PSR] & PSR_MODE);
break;
case TR_FETCH:
if (m_cmmu_i)
return m_cmmu_i->translate(intention, address, m_cr[PSR] & PSR_MODE);
if (m_cmmu_code)
return m_cmmu_code(address).translate(intention, address, m_cr[PSR] & PSR_MODE);
break;
}
@ -198,7 +198,7 @@ bool mc88100_device::memory_translate(int spacenum, int intention, offs_t &addre
void mc88100_device::device_start()
{
space(AS_PROGRAM).specific(m_inst_space);
space(AS_PROGRAM).specific(m_code_space);
if (has_configured_map(AS_DATA))
space(AS_DATA).specific(m_data_space);
@ -1525,16 +1525,16 @@ void mc88100_device::fset(unsigned const td, unsigned const d, float64_t const d
void mc88100_device::fetch(u32 &address, u32 &inst)
{
if (m_cmmu_i)
if (m_cmmu_code)
{
std::optional<u32> data = m_cmmu_i->read<u32>(address & IP_A, m_cr[PSR] & PSR_MODE);
std::optional<u32> data = m_cmmu_code(address & IP_A).read<u32>(address & IP_A, m_cr[PSR] & PSR_MODE);
if (data.has_value())
inst = data.value();
else
address |= IP_E;
}
else
inst = m_inst_space.read_dword(address & IP_A);
inst = m_code_space.read_dword(address & IP_A);
}
template <typename T, bool Usr> void mc88100_device::ld(u32 address, unsigned const reg)
@ -1552,11 +1552,11 @@ template <typename T, bool Usr> void mc88100_device::ld(u32 address, unsigned co
address &= ~(sizeof(T) - 1);
}
if (m_cmmu_d)
if (m_cmmu_data)
{
if constexpr (sizeof(T) < 8)
{
std::optional<T> const data = m_cmmu_d->read<typename std::make_unsigned<T>::type>(address, (m_cr[PSR] & PSR_MODE) && !Usr);
std::optional<T> const data = m_cmmu_data(address).read<typename std::make_unsigned<T>::type>(address, (m_cr[PSR] & PSR_MODE) && !Usr);
if (data.has_value() && reg)
m_r[reg] = std::is_signed<T>() ? s32(data.value()) : data.value();
@ -1585,8 +1585,8 @@ template <typename T, bool Usr> void mc88100_device::ld(u32 address, unsigned co
}
else
{
std::optional<u32> const hi = m_cmmu_d->read<u32>(address + 0, (m_cr[PSR] & PSR_MODE) && !Usr);
std::optional<u32> const lo = m_cmmu_d->read<u32>(address + 4, (m_cr[PSR] & PSR_MODE) && !Usr);
std::optional<u32> const hi = m_cmmu_data(address + 0).read<u32>(address + 0, (m_cr[PSR] & PSR_MODE) && !Usr);
std::optional<u32> const lo = m_cmmu_data(address + 4).read<u32>(address + 4, (m_cr[PSR] & PSR_MODE) && !Usr);
if (lo.has_value() && hi.has_value())
{
if (reg != 0)
@ -1673,11 +1673,11 @@ template <typename T, bool Usr> void mc88100_device::st(u32 address, unsigned co
address &= ~(sizeof(T) - 1);
}
if (m_cmmu_d)
if (m_cmmu_data)
{
if constexpr (sizeof(T) < 8)
{
if (!m_cmmu_d->write(address, T(m_r[reg]), (m_cr[PSR] & PSR_MODE) && !Usr))
if (!m_cmmu_data(address).write(address, T(m_r[reg]), (m_cr[PSR] & PSR_MODE) && !Usr))
{
m_cr[DMT0] = DMT_EN<T>(address) | DMT_WRITE | DMT_VALID;
m_cr[DMT1] = 0;
@ -1701,8 +1701,8 @@ template <typename T, bool Usr> void mc88100_device::st(u32 address, unsigned co
else
{
bool result = true;
result &= m_cmmu_d->write(address + 0, m_r[(reg + 0) & 31], (m_cr[PSR] & PSR_MODE) && !Usr);
result &= m_cmmu_d->write(address + 4, m_r[(reg + 1) & 31], (m_cr[PSR] & PSR_MODE) && !Usr);
result &= m_cmmu_data(address + 0).write(address + 0, m_r[(reg + 0) & 31], (m_cr[PSR] & PSR_MODE) && !Usr);
result &= m_cmmu_data(address + 4).write(address + 4, m_r[(reg + 1) & 31], (m_cr[PSR] & PSR_MODE) && !Usr);
if (!result)
{
@ -1762,10 +1762,10 @@ template <typename T, bool Usr> void mc88100_device::xmem(u32 address, unsigned
// save source value
T const src = m_r[reg];
if (m_cmmu_d)
if (m_cmmu_data)
{
// read destination
std::optional<T> const dst = m_cmmu_d->read<T>(address, (m_cr[PSR] & PSR_MODE) && !Usr);
std::optional<T> const dst = m_cmmu_data(address).read<T>(address, (m_cr[PSR] & PSR_MODE) && !Usr);
if (dst.has_value())
{
// update register
@ -1773,7 +1773,7 @@ template <typename T, bool Usr> void mc88100_device::xmem(u32 address, unsigned
m_r[reg] = dst.value();
// write destination
if (m_cmmu_d->write<T>(address, src, (m_cr[PSR] & PSR_MODE) && !Usr))
if (m_cmmu_data(address).write<T>(address, src, (m_cr[PSR] & PSR_MODE) && !Usr))
return;
}

View File

@ -20,8 +20,8 @@ public:
// construction/destruction
mc88100_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
template <typename T> void set_cmmu_d(T &&tag) { m_cmmu_d.set_tag(std::forward<T>(tag)); }
template <typename T> void set_cmmu_i(T &&tag) { m_cmmu_i.set_tag(std::forward<T>(tag)); }
void set_cmmu_code(std::function<mc88200_device &(u32 const address)> f) { m_cmmu_code = f; }
void set_cmmu_data(std::function<mc88200_device &(u32 const address)> f) { m_cmmu_data = f; }
protected:
// device_t implementation
@ -64,11 +64,11 @@ private:
// address spaces
address_space_config m_code_config;
address_space_config m_data_config;
memory_access<32, 2, 0, ENDIANNESS_BIG>::specific m_inst_space;
memory_access<32, 2, 0, ENDIANNESS_BIG>::specific m_code_space;
memory_access<32, 2, 0, ENDIANNESS_BIG>::specific m_data_space;
optional_device<mc88200_device> m_cmmu_d;
optional_device<mc88200_device> m_cmmu_i;
std::function<mc88200_device &(u32 const address)> m_cmmu_code;
std::function<mc88200_device &(u32 const address)> m_cmmu_data;
// register storage
u32 m_xip; // execute instruction pointer

View File

@ -386,13 +386,11 @@ void luna_88k_state_base::common_config(machine_config &config, XTAL clock)
{
MC88100(config, m_cpu, clock.value());
m_cpu->set_addrmap(AS_PROGRAM, &luna_88k_state_base::cpu_map);
m_cpu->set_cmmu_code([this](u32 const address) -> mc88200_device & { return *m_cmmu[0]; });
m_cpu->set_cmmu_data([this](u32 const address) -> mc88200_device & { return *m_cmmu[1]; });
MC88200(config, m_cmmu[0], clock.value(), 0x07); // cpu0 cmmu i0
m_cmmu[0]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_i(m_cmmu[0]);
MC88200(config, m_cmmu[1], clock.value(), 0x06); // cpu0 cmmu d0
m_cmmu[1]->set_mbus(m_cpu, AS_PROGRAM);
m_cpu->set_cmmu_d(m_cmmu[1]);
MC88200(config, m_cmmu[0], clock.value(), 0x07).set_mbus(m_cpu, AS_PROGRAM); // cpu0 cmmu i0
MC88200(config, m_cmmu[1], clock.value(), 0x06).set_mbus(m_cpu, AS_PROGRAM); // cpu0 cmmu d0
// 6 SIMMs for RAM arranged as three groups of 2?
RAM(config, m_ram);

View File

@ -72,13 +72,11 @@ void xd88_state::xd88_01(machine_config &config)
{
MC88100(config, m_cpu, 20'000'000);
m_cpu->set_addrmap(AS_PROGRAM, &xd88_state::cpu_map);
m_cpu->set_cmmu_code([this](u32 const address) -> mc88200_device & { return *m_cmmu[4]; });
m_cpu->set_cmmu_data([this](u32 const address) -> mc88200_device & { return *m_cmmu[0]; });
for (unsigned i = 0; i < std::size(m_cmmu); i++)
MC88200(config, m_cmmu[i], 20'000'000, i).set_mbus(m_cpu, AS_PROGRAM);
// TODO: multiple i&d cmmu's
m_cpu->set_cmmu_d(m_cmmu[0]);
m_cpu->set_cmmu_i(m_cmmu[4]);
}
ROM_START(xd88_01)