summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2022-09-16 23:24:58 -0400
committer AJR <ajrhacker@users.noreply.github.com>2022-09-16 23:24:58 -0400
commite43bc4bc3e9d9872439bb474ab1db576a6312e4f (patch)
tree6dac90bf4062bb57d3838c91f6909965240a0f24
parent6a1747348d0fd5bea75b711286848eada9e9409e (diff)
Emulate MN18801A MMU
-rw-r--r--src/devices/cpu/mn1880/mn1880.cpp291
-rw-r--r--src/devices/cpu/mn1880/mn1880.h25
-rw-r--r--src/mame/yamaha/ympsr400.cpp25
3 files changed, 214 insertions, 127 deletions
diff --git a/src/devices/cpu/mn1880/mn1880.cpp b/src/devices/cpu/mn1880/mn1880.cpp
index 528c528430d..9ea47debcb0 100644
--- a/src/devices/cpu/mn1880/mn1880.cpp
+++ b/src/devices/cpu/mn1880/mn1880.cpp
@@ -73,13 +73,15 @@
// device type definitions
DEFINE_DEVICE_TYPE(MN1880, mn1880_device, "mn1880", "Panasonic MN1880")
+DEFINE_DEVICE_TYPE(MN18801A, mn18801a_device, "mn18801a", "Panasonic MN18801A")
ALLOW_SAVE_TYPE(mn1880_device::microstate)
-mn1880_device::mn1880_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor data_map)
+mn1880_device::mn1880_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool has_mmu, address_map_constructor data_map)
: cpu_device(mconfig, type, tag, owner, clock)
- , m_program_config("program", ENDIANNESS_BIG, 8, 16, 0)
- , m_data_config("data", ENDIANNESS_LITTLE, 8, 16, 0, data_map)
+ , m_program_config("program", ENDIANNESS_BIG, 8, has_mmu ? 21 : 16, 0, 16, 14)
+ , m_data_config("data", ENDIANNESS_LITTLE, 8, has_mmu ? 21 : 16, 0, 16, 14, data_map)
+ , m_has_mmu(has_mmu)
, m_cpum(0)
, m_ustate(microstate::UNKNOWN)
, m_da(0)
@@ -89,11 +91,18 @@ mn1880_device::mn1880_device(const machine_config &mconfig, device_type type, co
, m_icount(0)
, m_if(0)
, m_irq(0)
+ , m_mmu_bank{0, 0, 0, 0}
+ , m_mmu_enable(0)
{
}
mn1880_device::mn1880_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : mn1880_device(mconfig, MN1880, tag, owner, clock, address_map_constructor(FUNC(mn1880_device::internal_data_map), this))
+ : mn1880_device(mconfig, MN1880, tag, owner, clock, false, address_map_constructor(FUNC(mn1880_device::internal_data_map), this))
+{
+}
+
+mn18801a_device::mn18801a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : mn1880_device(mconfig, MN18801A, tag, owner, clock, true, address_map_constructor(FUNC(mn18801a_device::internal_data_map), this))
{
}
@@ -131,11 +140,36 @@ void mn1880_device::cpum_w(u8 data)
m_cpum = (data & 0xef) | (m_cpum & 0x10);
}
+u8 mn1880_device::mmu_bank_r(offs_t offset)
+{
+ return m_mmu_bank[offset];
+}
+
+void mn1880_device::mmu_bank_w(offs_t offset, u8 data)
+{
+ m_mmu_bank[offset] = data & 0x7f;
+}
+
+u8 mn1880_device::mmu_enable_r()
+{
+ return m_mmu_enable;
+}
+
+void mn1880_device::mmu_enable_w(u8 data)
+{
+ m_mmu_enable = data & 0xc0;
+}
+
void mn1880_device::internal_data_map(address_map &map)
{
map(0x0012, 0x0012).rw(FUNC(mn1880_device::ie0_r), FUNC(mn1880_device::ie0_w));
map(0x0015, 0x0015).rw(FUNC(mn1880_device::ie1_r), FUNC(mn1880_device::ie1_w));
map(0x0016, 0x0016).rw(FUNC(mn1880_device::cpum_r), FUNC(mn1880_device::cpum_w));
+ if (m_has_mmu)
+ {
+ map(0x0040, 0x0043).rw(FUNC(mn1880_device::mmu_bank_r), FUNC(mn1880_device::mmu_bank_w));
+ map(0x0044, 0x0044).rw(FUNC(mn1880_device::mmu_enable_r), FUNC(mn1880_device::mmu_enable_w));
+ }
}
std::unique_ptr<util::disasm_interface> mn1880_device::create_disassembler()
@@ -258,6 +292,11 @@ void mn1880_device::device_start()
save_item(NAME(m_tmp1));
save_item(NAME(m_tmp2));
save_item(NAME(m_output_queue_state));
+ if (m_has_mmu)
+ {
+ save_item(NAME(m_mmu_bank));
+ save_item(NAME(m_mmu_enable));
+ }
}
void mn1880_device::device_reset()
@@ -285,6 +324,24 @@ void mn1880_device::device_reset()
m_cpum = 0x0c;
m_ustate = microstate::NEXT;
m_output_queue_state = 0xff;
+
+ m_mmu_enable = 0;
+}
+
+bool mn1880_device::memory_translate(int spacenum, int intention, offs_t &address)
+{
+ switch (spacenum)
+ {
+ case AS_PROGRAM:
+ address = mmu_psen_translate(address);
+ break;
+
+ case AS_DATA:
+ address = mmu_data_translate(address);
+ break;
+ }
+
+ return true;
}
const mn1880_device::microstate mn1880_device::s_decode_map[256] =
@@ -502,7 +559,7 @@ void mn1880_device::execute_run()
}
}
- u8 input = m_cache.read_byte(cpu.ip);
+ u8 input = m_cache.read_byte(mmu_psen_translate(cpu.ip));
switch (m_ustate)
{
case microstate::NEXT:
@@ -515,7 +572,7 @@ void mn1880_device::execute_run()
{
if (output_queued())
{
- m_data.write_byte(m_da, m_tmp1 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1 & 0x00ff);
m_output_queue_state = 0xff;
}
if (m_irq != 0)
@@ -546,7 +603,7 @@ void mn1880_device::execute_run()
case microstate::CLRSET_1:
if (BIT(cpu.fs, 5))
m_da |= cpu.xp & 0xff00;
- m_tmp1 = m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
if (BIT(cpu.ir, 3))
m_tmp1 |= 1 << (cpu.ir & 0x07);
else
@@ -558,7 +615,7 @@ void mn1880_device::execute_run()
++cpu.ip;
if (BIT(cpu.fs, 5))
m_da |= cpu.xp & 0xff00;
- m_tmp1 = m_data.read_byte(m_da) & (1 << (cpu.ir & 0x07));
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da)) & (1 << (cpu.ir & 0x07));
m_tmp2 = cpu.ip + s8(input);
m_ustate = microstate::CMPBF1_3;
break;
@@ -584,21 +641,21 @@ void mn1880_device::execute_run()
break;
case microstate::MOVL34_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_tmp2 = m_da + 1;
m_da = cpu.xp;
m_ustate = microstate::MOVL34_3;
break;
case microstate::MOVL34_3:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
m_da = m_tmp2;
++cpu.xp;
m_ustate = microstate::MOVL34_4;
break;
case microstate::MOVL34_4:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = cpu.xp;
if ((cpu.fs & 0x1f) != 0)
++cpu.xp;
@@ -615,20 +672,20 @@ void mn1880_device::execute_run()
break;
case microstate::MOVL35_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = m_tmp2;
++cpu.yp;
m_ustate = microstate::MOVL35_3;
break;
case microstate::MOVL35_3:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
m_da = cpu.yp;
m_ustate = microstate::MOVL35_4;
break;
case microstate::MOVL35_4:
- m_tmp1 = m_data.read_byte(cpu.yp);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = m_tmp2 + 1;
set_output_queued();
next_instruction(input);
@@ -641,7 +698,7 @@ void mn1880_device::execute_run()
break;
case microstate::MOV36_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = cpu.xp;
if ((cpu.fs & 0x1f) != 0)
++cpu.xp;
@@ -652,7 +709,7 @@ void mn1880_device::execute_run()
case microstate::MOV37_1:
++cpu.ip;
m_da = cpu.yp;
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = input;
if (BIT(cpu.fs, 5))
m_da |= cpu.yp & 0xff00;
@@ -666,13 +723,13 @@ void mn1880_device::execute_run()
break;
case microstate::MOVL38_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
++m_da;
m_ustate = microstate::MOVL38_3;
break;
case microstate::MOVL38_3:
- m_tmp1 |= m_data.read_byte(m_da) << 8;
+ m_tmp1 |= m_data.read_byte(mmu_data_translate(m_da)) << 8;
m_ustate = microstate::MOVL31_2; // TODO: output queue
break;
@@ -690,7 +747,7 @@ void mn1880_device::execute_run()
break;
case microstate::MOVL39_3:
- m_data.write_byte(m_da, m_tmp1 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1 & 0x00ff);
++m_da;
m_tmp1 >>= 8;
set_output_queued();
@@ -709,7 +766,7 @@ void mn1880_device::execute_run()
break;
case microstate::ASL_2:
- m_tmp1 = m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
cpu.fs = (m_tmp1 & 0x80) | (cpu.fs & 0x7f);
m_tmp1 <<= 1;
set_output_queued();
@@ -728,7 +785,7 @@ void mn1880_device::execute_run()
break;
case microstate::ASR_2:
- m_tmp1 = cpu.asrc(m_data.read_byte(m_da)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.asrc(m_data.read_byte(mmu_data_translate(m_da))); // TODO: read latch instead of terminal
set_output_queued();
next_instruction(input);
break;
@@ -771,7 +828,7 @@ void mn1880_device::execute_run()
case microstate::CMPM44_2:
++cpu.ip;
- m_tmp1 &= m_data.read_byte(m_da);
+ m_tmp1 &= m_data.read_byte(mmu_data_translate(m_da));
m_tmp2 = input;
m_ustate = microstate::CMPM44_3;
break;
@@ -794,7 +851,7 @@ void mn1880_device::execute_run()
break;
case microstate::CMPM50_1:
- m_tmp2 = m_data.read_byte(cpu.yp);
+ m_tmp2 = m_data.read_byte(mmu_data_translate(cpu.yp));
m_tmp1 = m_da & 0x00ff;
m_da = cpu.xp;
m_ustate = microstate::CMPM50_2;
@@ -806,7 +863,7 @@ void mn1880_device::execute_run()
break;
case microstate::CMPM50_3:
- m_tmp1 &= m_data.read_byte(m_da);
+ m_tmp1 &= m_data.read_byte(mmu_data_translate(m_da));
m_ustate = microstate::CMPM44_3;
break;
@@ -820,7 +877,7 @@ void mn1880_device::execute_run()
case microstate::CMPM52_2:
++cpu.ip;
- m_tmp2 = m_data.read_byte(m_da);
+ m_tmp2 = m_data.read_byte(mmu_data_translate(m_da));
m_da = input;
if (BIT(cpu.fs, 5))
m_da |= cpu.xp & 0xff00;
@@ -843,7 +900,7 @@ void mn1880_device::execute_run()
break;
case microstate::XCH4_2:
- m_tmp1 = m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
m_tmp1 = (m_tmp1 << 4) | (m_tmp1 >> 4);
set_output_queued();
next_instruction(input);
@@ -899,7 +956,7 @@ void mn1880_device::execute_run()
break;
case microstate::ROL_2:
- m_tmp1 = cpu.rolc(m_data.read_byte(m_da)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.rolc(m_data.read_byte(mmu_data_translate(m_da))); // TODO: read latch instead of terminal
set_output_queued();
next_instruction(input);
break;
@@ -920,7 +977,7 @@ void mn1880_device::execute_run()
break;
case microstate::ROR_2:
- m_tmp1 = cpu.rorc(m_data.read_byte(m_da)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.rorc(m_data.read_byte(mmu_data_translate(m_da))); // TODO: read latch instead of terminal
set_output_queued();
next_instruction(input);
break;
@@ -931,19 +988,19 @@ void mn1880_device::execute_run()
break;
case microstate::DIV51_2:
- m_tmp2 = m_data.read_byte(m_da);
+ m_tmp2 = m_data.read_byte(mmu_data_translate(m_da));
m_da = cpu.xp;
m_ustate = microstate::DIV51_3;
break;
case microstate::DIV51_3:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
++m_da;
m_ustate = microstate::DIV51_4;
break;
case microstate::DIV51_4:
- m_tmp1 |= m_data.read_byte(m_da) << 8;
+ m_tmp1 |= m_data.read_byte(mmu_data_translate(m_da)) << 8;
--m_da;
m_ustate = microstate::DIV51_5;
break;
@@ -978,7 +1035,7 @@ void mn1880_device::execute_run()
break;
case microstate::DIV51_10:
- m_data.write_byte(m_da, m_tmp1 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1 & 0x00ff);
++m_da;
cpu.xp = m_da;
set_output_queued();
@@ -992,7 +1049,7 @@ void mn1880_device::execute_run()
break;
case microstate::MOVDA_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
++cpu.ip;
m_da = input;
m_ustate = microstate::MOVDA_3;
@@ -1012,7 +1069,7 @@ void mn1880_device::execute_run()
break;
case microstate::MOV55_1:
- m_data.write_byte(cpu.xp, m_da & 0x00ff);
+ m_data.write_byte(mmu_data_translate(cpu.xp), m_da & 0x00ff);
if ((cpu.fs & 0x1f) != 0)
++cpu.xp;
next_instruction(input);
@@ -1026,7 +1083,7 @@ void mn1880_device::execute_run()
{
if (BIT(cpu.fs, 5))
m_da |= cpu.yp & 0xff00;
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
}
m_da = input;
if (BIT(cpu.fs, 5))
@@ -1035,7 +1092,7 @@ void mn1880_device::execute_run()
break;
case microstate::MOV56_2:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
next_instruction(input);
break;
@@ -1057,7 +1114,7 @@ void mn1880_device::execute_run()
break;
case microstate::XCH58_2:
- m_tmp1 = m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
if (BIT(cpu.ir, 1))
{
std::swap(m_da, m_tmp2);
@@ -1075,12 +1132,12 @@ void mn1880_device::execute_run()
break;
case microstate::XCH58_3:
- m_tmp1 |= u16(m_data.read_byte(m_da)) << 8; // TODO: read latch instead of terminal
+ m_tmp1 |= u16(m_data.read_byte(mmu_data_translate(m_da))) << 8; // TODO: read latch instead of terminal
m_ustate = microstate::XCH58_4;
break;
case microstate::XCH58_4:
- m_data.write_byte(m_da, m_tmp1 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1 & 0x00ff);
m_tmp1 >>= 8;
m_da = m_tmp2;
set_output_queued();
@@ -1093,13 +1150,13 @@ void mn1880_device::execute_run()
break;
case microstate::MUL59_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
++m_da;
m_ustate = microstate::MUL59_3;
break;
case microstate::MUL59_3:
- m_tmp2 = m_data.read_byte(m_da);
+ m_tmp2 = m_data.read_byte(mmu_data_translate(m_da));
m_ustate = microstate::MUL59_4;
break;
@@ -1123,7 +1180,7 @@ void mn1880_device::execute_run()
break;
case microstate::MUL59_8:
- m_data.write_byte(m_da, m_tmp1 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1 & 0x00ff);
m_da = cpu.xp;
if ((cpu.fs & 0x1f) != 0)
++cpu.xp;
@@ -1139,14 +1196,14 @@ void mn1880_device::execute_run()
break;
case microstate::MOVL5C_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = cpu.xp;
++cpu.xp;
m_ustate = microstate::MOVL5C_3;
break;
case microstate::MOVL5C_3:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
m_da = cpu.yp;
if ((cpu.fs & 0x1f) != 0)
++cpu.yp;
@@ -1155,14 +1212,14 @@ void mn1880_device::execute_run()
case microstate::MOVL5D_1:
++cpu.ip;
- m_data.write_byte(cpu.xp, m_da & 0x00ff);
+ m_data.write_byte(mmu_data_translate(cpu.xp), m_da & 0x00ff);
++cpu.xp;
m_tmp1 = input;
m_ustate = microstate::MOVL5D_2;
break;
case microstate::MOVL5D_2:
- m_data.write_byte(cpu.xp, m_tmp1);
+ m_data.write_byte(mmu_data_translate(cpu.xp), m_tmp1);
++cpu.xp;
next_instruction(input);
break;
@@ -1178,20 +1235,20 @@ void mn1880_device::execute_run()
break;
case microstate::MOVL5E_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
std::swap(m_da, m_tmp2);
m_ustate = microstate::MOVL5E_3;
break;
case microstate::MOVL5E_3:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
std::swap(m_da, m_tmp2);
++m_da;
m_ustate = microstate::MOVL5E_4;
break;
case microstate::MOVL5E_4:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = m_tmp2 + 1;
set_output_queued();
next_instruction(input);
@@ -1208,7 +1265,7 @@ void mn1880_device::execute_run()
case microstate::MOVL5F_2:
++cpu.ip;
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
m_tmp1 = input;
++m_da;
m_ustate = microstate::MOV56_2;
@@ -1236,7 +1293,7 @@ void mn1880_device::execute_run()
case microstate::CMP_2:
if (!BIT(cpu.ir, 0))
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (BIT(cpu.ir, 1))
{
++cpu.ip;
@@ -1256,7 +1313,7 @@ void mn1880_device::execute_run()
break;
case microstate::CMP_3:
- (void)cpu.subcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4));
+ (void)cpu.subcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4));
m_ustate = microstate::NOP_1; // TODO: output queue (but just what is the output?)
break;
@@ -1282,7 +1339,7 @@ void mn1880_device::execute_run()
case microstate::AND_2:
if (!BIT(cpu.ir, 0))
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (BIT(cpu.ir, 1))
{
++cpu.ip;
@@ -1300,7 +1357,7 @@ void mn1880_device::execute_run()
break;
case microstate::AND_3:
- m_tmp1 &= m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 &= m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
if (u8(m_tmp1) == 0)
cpu.fs |= 0x40;
else
@@ -1331,7 +1388,7 @@ void mn1880_device::execute_run()
case microstate::XOR_2:
if (!BIT(cpu.ir, 0))
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (BIT(cpu.ir, 1))
{
++cpu.ip;
@@ -1349,7 +1406,7 @@ void mn1880_device::execute_run()
break;
case microstate::XOR_3:
- m_tmp1 ^= m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 ^= m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
if (u8(m_tmp1) == 0)
cpu.fs |= 0x40;
else
@@ -1380,7 +1437,7 @@ void mn1880_device::execute_run()
case microstate::OR_2:
if (!BIT(cpu.ir, 0))
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (BIT(cpu.ir, 1))
{
++cpu.ip;
@@ -1398,7 +1455,7 @@ void mn1880_device::execute_run()
break;
case microstate::OR_3:
- m_tmp1 |= m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 |= m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
if (u8(m_tmp1) == 0)
cpu.fs |= 0x40;
else
@@ -1429,7 +1486,7 @@ void mn1880_device::execute_run()
case microstate::SUBC_2:
if (!BIT(cpu.ir, 0))
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (BIT(cpu.ir, 1))
{
++cpu.ip;
@@ -1447,7 +1504,7 @@ void mn1880_device::execute_run()
break;
case microstate::SUBC_3:
- m_tmp1 = cpu.subcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.subcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4)); // TODO: read latch instead of terminal
set_output_queued();
next_instruction(input);
break;
@@ -1474,7 +1531,7 @@ void mn1880_device::execute_run()
case microstate::SUBD_2:
if (!BIT(cpu.ir, 0))
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (BIT(cpu.ir, 1))
{
++cpu.ip;
@@ -1492,7 +1549,7 @@ void mn1880_device::execute_run()
break;
case microstate::SUBD_3:
- m_tmp1 = cpu.subdcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.subdcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7)); // TODO: read latch instead of terminal
set_output_queued();
next_instruction(input);
break;
@@ -1533,7 +1590,7 @@ void mn1880_device::execute_run()
case microstate::ADDC_2:
if (!BIT(cpu.ir, 0))
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (BIT(cpu.ir, 1))
{
++cpu.ip;
@@ -1551,7 +1608,7 @@ void mn1880_device::execute_run()
break;
case microstate::ADDC_3:
- m_tmp1 = cpu.addcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.addcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4)); // TODO: read latch instead of terminal
set_output_queued();
next_instruction(input);
break;
@@ -1578,7 +1635,7 @@ void mn1880_device::execute_run()
case microstate::ADDD_2:
if (!BIT(cpu.ir, 0))
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (BIT(cpu.ir, 1))
{
++cpu.ip;
@@ -1596,7 +1653,7 @@ void mn1880_device::execute_run()
break;
case microstate::ADDD_3:
- m_tmp1 = cpu.adddcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.adddcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7)); // TODO: read latch instead of terminal
m_ustate = microstate::ADDD_4;
break;
@@ -1632,7 +1689,7 @@ void mn1880_device::execute_run()
break;
case microstate::CMPL_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_tmp2 = m_da;
if (BIT(cpu.ir, 1))
{
@@ -1649,14 +1706,14 @@ void mn1880_device::execute_run()
break;
case microstate::CMPL_3:
- (void)cpu.subcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4));
+ (void)cpu.subcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4));
std::swap(m_da, m_tmp2);
++m_da;
m_ustate = microstate::CMPL_4;
break;
case microstate::CMPL_4:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (!BIT(cpu.ir, 1))
cpu.yp = m_da + 1;
m_da = m_tmp2 + 1;
@@ -1664,7 +1721,7 @@ void mn1880_device::execute_run()
break;
case microstate::CMPL_5:
- (void)cpu.subcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), true);
+ (void)cpu.subcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), true);
if (!BIT(cpu.ir, 1))
cpu.xp = m_da + 1;
m_ustate = microstate::NOP_1; // TODO: output queue (if any...)
@@ -1698,7 +1755,7 @@ void mn1880_device::execute_run()
break;
case microstate::SUBCL_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_tmp2 = m_da;
if (BIT(cpu.ir, 1))
{
@@ -1713,19 +1770,19 @@ void mn1880_device::execute_run()
break;
case microstate::SUBCL_3:
- m_tmp1 = cpu.subcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.subcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4)); // TODO: read latch instead of terminal
++m_tmp2;
m_ustate = microstate::SUBCL_4;
break;
case microstate::SUBCL_4:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
std::swap(m_da, m_tmp2);
m_ustate = microstate::SUBCL_5;
break;
case microstate::SUBCL_5:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (!BIT(cpu.ir, 1))
cpu.yp = m_da + 1;
m_da = m_tmp2 + 1;
@@ -1733,7 +1790,7 @@ void mn1880_device::execute_run()
break;
case microstate::SUBCL_6:
- m_tmp1 = cpu.subcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), true); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.subcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), true); // TODO: read latch instead of terminal
if (!BIT(cpu.ir, 1))
cpu.xp = m_da + 1;
set_output_queued();
@@ -1752,7 +1809,7 @@ void mn1880_device::execute_run()
break;
case microstate::ADDCL_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_tmp2 = m_da;
if (BIT(cpu.ir, 1))
{
@@ -1767,19 +1824,19 @@ void mn1880_device::execute_run()
break;
case microstate::ADDCL_3:
- m_tmp1 = cpu.addcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4)); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.addcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), BIT(cpu.fs, 4)); // TODO: read latch instead of terminal
++m_tmp2;
m_ustate = microstate::ADDCL_4;
break;
case microstate::ADDCL_4:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
std::swap(m_da, m_tmp2);
m_ustate = microstate::ADDCL_5;
break;
case microstate::ADDCL_5:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
if (!BIT(cpu.ir, 1))
cpu.yp = m_da + 1;
m_da = m_tmp2 + 1;
@@ -1787,7 +1844,7 @@ void mn1880_device::execute_run()
break;
case microstate::ADDCL_6:
- m_tmp1 = cpu.addcz(m_data.read_byte(m_da), m_tmp1, BIT(cpu.fs, 7), true); // TODO: read latch instead of terminal
+ m_tmp1 = cpu.addcz(m_data.read_byte(mmu_data_translate(m_da)), m_tmp1, BIT(cpu.fs, 7), true); // TODO: read latch instead of terminal
if (!BIT(cpu.ir, 1))
cpu.xp = m_da + 1;
set_output_queued();
@@ -1803,7 +1860,7 @@ void mn1880_device::execute_run()
break;
case microstate::CALL90_2:
- m_data.write_byte(m_da, m_tmp2 >> 8);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp2 >> 8);
--m_da;
cpu.branch(m_tmp1);
m_ustate = microstate::CALL_3;
@@ -1820,7 +1877,7 @@ void mn1880_device::execute_run()
break;
case microstate::POPFS_2:
- cpu.fs = m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ cpu.fs = m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
cpu.sp = m_da + 1;
m_ustate = microstate::NOP_1; // TODO: output queue (only FS?)
break;
@@ -1831,13 +1888,13 @@ void mn1880_device::execute_run()
break;
case microstate::POPB4_2:
- (BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) = m_data.read_byte(m_da);
+ (BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) = m_data.read_byte(mmu_data_translate(m_da));
++m_da;
m_ustate = microstate::POPB4_3;
break;
case microstate::POPB4_3:
- (BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) |= m_data.read_byte(m_da) << 8;
+ (BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) |= m_data.read_byte(mmu_data_translate(m_da)) << 8;
cpu.sp = m_da + 1;
m_ustate = microstate::NOP_1; // TODO: output queue (only XP/YP?)
break;
@@ -1852,7 +1909,7 @@ void mn1880_device::execute_run()
break;
case microstate::POPB5_2:
- m_tmp1 = m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
cpu.sp = m_da + 1;
m_da = m_tmp2;
set_output_queued();
@@ -1880,13 +1937,13 @@ void mn1880_device::execute_run()
break;
case microstate::PUSHBC_2:
- m_data.write_byte(m_da, m_tmp1 >> 8);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1 >> 8);
--m_da;
m_ustate = microstate::PUSHBC_3;
break;
case microstate::PUSHBC_3:
- m_data.write_byte(m_da, m_tmp1 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1 & 0x00ff);
cpu.sp = m_da;
m_ustate = microstate::NOP_1; // TODO: output queue (only SP?)
break;
@@ -1900,13 +1957,13 @@ void mn1880_device::execute_run()
break;
case microstate::PUSHBD_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = cpu.sp - 1;
m_ustate = microstate::PUSHBD_3;
break;
case microstate::PUSHBD_3:
- m_data.write_byte(m_da, m_tmp1 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1 & 0x00ff);
cpu.sp = m_da;
m_ustate = microstate::NOP_1; // TODO: output queue (only SP?)
break;
@@ -1943,13 +2000,13 @@ void mn1880_device::execute_run()
case microstate::XCHC5_1:
if (BIT(cpu.fs, 5))
m_da |= (BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) & 0xff00;
- m_tmp2 = m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp2 = m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
m_tmp1 = (BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) & 0x00ff;
m_ustate = microstate::XCHC5_2;
break;
case microstate::XCHC5_2:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
setl(BIT(cpu.ir, 1) ? cpu.yp : cpu.xp, m_tmp2);
next_instruction(input);
break;
@@ -1959,13 +2016,13 @@ void mn1880_device::execute_run()
{
if (BIT(cpu.ir, 5))
m_da |= cpu.yp & 0xff00;
- setl(cpu.yp, m_data.read_byte(m_da));
+ setl(cpu.yp, m_data.read_byte(mmu_data_translate(m_da)));
}
else
{
if (BIT(cpu.ir, 5))
m_da |= cpu.xp & 0xff00;
- setl(cpu.xp, m_data.read_byte(m_da));
+ setl(cpu.xp, m_data.read_byte(mmu_data_translate(m_da)));
}
next_instruction(input);
break;
@@ -1977,7 +2034,7 @@ void mn1880_device::execute_run()
break;
case microstate::MOVCD_2:
- setl(BIT(cpu.ir, 1) ? cpu.yp : cpu.xp, m_data.read_byte(m_da));
+ setl(BIT(cpu.ir, 1) ? cpu.yp : cpu.xp, m_data.read_byte(mmu_data_translate(m_da)));
next_instruction(input); // TODO: output queue
break;
@@ -1988,7 +2045,7 @@ void mn1880_device::execute_run()
break;
case microstate::MULC9_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_ustate = microstate::MULC9_3;
break;
@@ -2003,7 +2060,7 @@ void mn1880_device::execute_run()
break;
case microstate::CMPD0_2:
- (void)cpu.subcz((BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) & 0x00ff, m_data.read_byte(m_da), false, false);
+ (void)cpu.subcz((BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) & 0x00ff, m_data.read_byte(mmu_data_translate(m_da)), false, false);
m_ustate = microstate::CMPD1_2;
break;
@@ -2072,7 +2129,7 @@ void mn1880_device::execute_run()
break;
case microstate::LOOP_2:
- m_tmp1 = m_data.read_byte(m_da) - 1; // TODO: read latch instead of terminal
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da)) - 1; // TODO: read latch instead of terminal
if (m_tmp1 != 0)
cpu.branch(m_tmp2);
else
@@ -2105,7 +2162,7 @@ void mn1880_device::execute_run()
break;
case microstate::ADDRE8_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_da = m_tmp2;
if (BIT(cpu.fs, 5))
m_da |= cpu.xp & 0x00ff;
@@ -2114,9 +2171,9 @@ void mn1880_device::execute_run()
case microstate::ADDRE8_3:
if (BIT(cpu.ir, 1))
- setl(cpu.yp, cpu.addcz(cpu.yp & 0x00ff, m_data.read_byte(m_da), false, false));
+ setl(cpu.yp, cpu.addcz(cpu.yp & 0x00ff, m_data.read_byte(mmu_data_translate(m_da)), false, false));
else
- setl(cpu.xp, cpu.addcz(cpu.xp & 0x00ff, m_data.read_byte(m_da), false, false));
+ setl(cpu.xp, cpu.addcz(cpu.xp & 0x00ff, m_data.read_byte(mmu_data_translate(m_da)), false, false));
m_ustate = microstate::NOP_1; // TODO: output queue (XPl only?)
break;
@@ -2130,7 +2187,7 @@ void mn1880_device::execute_run()
break;
case microstate::ADDRE9_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
m_ustate = microstate::ADDRE9_3;
break;
@@ -2153,7 +2210,7 @@ void mn1880_device::execute_run()
case microstate::CMPBF0_1:
++cpu.ip;
- m_tmp1 = m_data.read_byte(cpu.xp) ^ (m_da & 0x00ff);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(cpu.xp)) ^ (m_da & 0x00ff);
m_tmp2 = cpu.ip + s8(input);
m_ustate = microstate::CMPBF1_3;
break;
@@ -2169,7 +2226,7 @@ void mn1880_device::execute_run()
case microstate::CMPBF1_2:
++cpu.ip;
- m_tmp1 ^= m_data.read_byte(m_da);
+ m_tmp1 ^= m_data.read_byte(mmu_data_translate(m_da));
m_tmp2 = cpu.ip + s8(input);
m_ustate = microstate::CMPBF1_3;
break;
@@ -2191,7 +2248,7 @@ void mn1880_device::execute_run()
case microstate::MOV1_2:
++cpu.ip;
- m_tmp1 &= m_data.read_byte(m_da);
+ m_tmp1 &= m_data.read_byte(mmu_data_translate(m_da));
m_da = input;
if (BIT(cpu.fs, 5))
m_da |= cpu.xp & 0xff00;
@@ -2207,13 +2264,13 @@ void mn1880_device::execute_run()
break;
case microstate::MOV1_4:
- m_tmp1 |= m_data.read_byte(m_da); // TODO: read latch instead of terminal
+ m_tmp1 |= m_data.read_byte(mmu_data_translate(m_da)); // TODO: read latch instead of terminal
set_output_queued();
next_instruction(input);
break;
case microstate::MOV1N_4:
- m_tmp1 = m_data.read_byte(m_da) & ~m_tmp1; // TODO: read latch instead of terminal
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da)) & ~m_tmp1; // TODO: read latch instead of terminal
set_output_queued();
next_instruction(input);
break;
@@ -2235,13 +2292,13 @@ void mn1880_device::execute_run()
break;
case microstate::RET_2:
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
++m_da;
m_ustate = microstate::RET_3;
break;
case microstate::RET_3:
- cpu.branch(u16(m_data.read_byte(m_da)) << 8 | m_tmp1);
+ cpu.branch(u16(m_data.read_byte(mmu_data_translate(m_da))) << 8 | m_tmp1);
cpu.sp = m_da + 1;
m_ustate = microstate::BR_2;
break;
@@ -2252,20 +2309,20 @@ void mn1880_device::execute_run()
break;
case microstate::RETI_2:
- cpu.fs = m_data.read_byte(m_da);
+ cpu.fs = m_data.read_byte(mmu_data_translate(m_da));
++m_da;
m_ustate = microstate::RETI_3;
break;
case microstate::RETI_3:
cpu.iemask = false;
- m_tmp1 = m_data.read_byte(m_da);
+ m_tmp1 = m_data.read_byte(mmu_data_translate(m_da));
++m_da;
m_ustate = microstate::RETI_4;
break;
case microstate::RETI_4:
- cpu.ip = u16(m_data.read_byte(m_da)) << 8 | m_tmp1;
+ cpu.ip = u16(m_data.read_byte(mmu_data_translate(m_da))) << 8 | m_tmp1;
if ((cpu.fs & 0x1f) != 0)
{
++m_da;
@@ -2279,7 +2336,7 @@ void mn1880_device::execute_run()
break;
case microstate::RETI_5:
- cpu.ir = m_data.read_byte(m_da);
+ cpu.ir = m_data.read_byte(mmu_data_translate(m_da));
cpu.sp = m_da + 1;
m_ustate = microstate::NEXT;
swap_cpus();
@@ -2303,14 +2360,14 @@ void mn1880_device::execute_run()
break;
case microstate::CALL_2:
- m_data.write_byte(m_da, m_tmp2 >> 8);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp2 >> 8);
--m_da;
cpu.branch(m_tmp1 << 8 | input);
m_ustate = microstate::CALL_3;
break;
case microstate::CALL_3:
- m_data.write_byte(m_da, m_tmp2 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp2 & 0x00ff);
cpu.sp = m_da;
next_instruction(input);
break;
@@ -2380,13 +2437,13 @@ void mn1880_device::execute_run()
break;
case microstate::PI_2:
- m_data.write_byte(m_da, m_tmp1);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp1);
--m_da;
m_ustate = microstate::PI_3;
break;
case microstate::PI_3:
- m_data.write_byte(m_da, m_tmp2 >> 8);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp2 >> 8);
--m_da;
m_tmp1 = u16(input) << 8;
++cpu.ip;
@@ -2394,7 +2451,7 @@ void mn1880_device::execute_run()
break;
case microstate::PI_4:
- m_data.write_byte(m_da, m_tmp2 & 0x00ff);
+ m_data.write_byte(mmu_data_translate(m_da), m_tmp2 & 0x00ff);
--m_da;
m_tmp2 = cpu.fs;
cpu.branch(m_tmp1 | input); // FS repeat bits are cleared here
diff --git a/src/devices/cpu/mn1880/mn1880.h b/src/devices/cpu/mn1880/mn1880.h
index 95bf7151452..47f470c02a8 100644
--- a/src/devices/cpu/mn1880/mn1880.h
+++ b/src/devices/cpu/mn1880/mn1880.h
@@ -29,7 +29,7 @@ public:
};
protected:
- mn1880_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor data_map);
+ mn1880_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool has_mmu, address_map_constructor data_map);
// device-level overrides
virtual void device_start() override;
@@ -45,10 +45,13 @@ protected:
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
+ virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
// device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
+ void internal_data_map(address_map &map);
+
private:
struct cpu_registers
{
@@ -181,6 +184,9 @@ private:
bool output_queued() const { return m_output_queue_state != 0xff; }
void set_output_queued() { m_output_queue_state = BIT(m_cpum, 4); }
+ offs_t mmu_psen_translate(u16 addr) const { return BIT(m_mmu_enable, 6) && BIT(addr + 0x4000, 15) ? u32(m_mmu_bank[BIT(addr, 15)]) << 14 | (addr & 0x3fff) : addr; }
+ offs_t mmu_data_translate(u16 addr) const { return BIT(m_mmu_enable, 7) && BIT(addr + 0x4000, 15) ? u32(m_mmu_bank[BIT(addr, 15) + 2]) << 14 | (addr & 0x3fff) : addr; }
+
u8 ie0_r();
void ie0_w(u8 data);
u8 ie1_r();
@@ -188,7 +194,10 @@ private:
u8 cpum_r();
void cpum_w(u8 data);
- void internal_data_map(address_map &map);
+ u8 mmu_bank_r(offs_t offset);
+ void mmu_bank_w(offs_t offset, u8 data);
+ u8 mmu_enable_r();
+ void mmu_enable_w(u8 data);
void swap_cpus();
void next_instruction(u8 input);
@@ -202,6 +211,7 @@ private:
address_space_config m_data_config;
memory_access<16, 0, 0, ENDIANNESS_BIG>::cache m_cache;
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_data;
+ const bool m_has_mmu;
// execution state
cpu_registers m_cpu[2];
@@ -216,8 +226,19 @@ private:
// interrupt state
u16 m_if;
u16 m_irq;
+
+ // MMU state
+ u8 m_mmu_bank[4];
+ u8 m_mmu_enable;
+};
+
+class mn18801a_device : public mn1880_device
+{
+public:
+ mn18801a_device(const machine_config &config, const char *tag, device_t *owner, u32 clock);
};
DECLARE_DEVICE_TYPE(MN1880, mn1880_device)
+DECLARE_DEVICE_TYPE(MN18801A, mn18801a_device)
#endif // MAME_CPU_MN1880_MN1880_H
diff --git a/src/mame/yamaha/ympsr400.cpp b/src/mame/yamaha/ympsr400.cpp
index b6b07c05c50..b8928105989 100644
--- a/src/mame/yamaha/ympsr400.cpp
+++ b/src/mame/yamaha/ympsr400.cpp
@@ -9,6 +9,8 @@
#include "emu.h"
#include "cpu/m6805/m6805.h"
#include "cpu/mn1880/mn1880.h"
+#include "sound/multipcm.h"
+#include "speaker.h"
namespace {
@@ -37,14 +39,15 @@ private:
void psr400_state::program_map(address_map &map)
{
- // TODO: 2 MB external program memory space using MMU
- map(0x0000, 0xffff).rom().region("program", 0);
+ // 2 MB external program memory space using MMU
+ map(0x000000, 0x1fffff).rom().region("program", 0);
}
void psr400_state::data_map(address_map &map)
{
- // TODO: 2 MB external data memory space using MMU
- map(0x0100, 0x1fff).ram();
+ // 2 MB external data memory space using MMU
+ map(0x000080, 0x03ffff).mirror(0xc0000).ram(); // 2x 1M-bit PSRAM (only one on PSR-400)
+ map(0x100000, 0x10000f).mirror(0xffff0).rw("gew8", FUNC(multipcm_device::read), FUNC(multipcm_device::write));
}
static INPUT_PORTS_START(psr500)
@@ -52,14 +55,20 @@ INPUT_PORTS_END
void psr400_state::psr500(machine_config &config)
{
- MN1880(config, m_maincpu, 10_MHz_XTAL); // MN18801A (also has 500 kHz secondary resonator)
+ MN18801A(config, m_maincpu, 10_MHz_XTAL); // MN18801A (also has 500 kHz secondary resonator)
m_maincpu->set_addrmap(AS_PROGRAM, &psr400_state::program_map);
m_maincpu->set_addrmap(AS_DATA, &psr400_state::data_map);
HD63705(config, m_mpscpu, 8_MHz_XTAL).set_disable(); // HD63B05V0D73P (mislabeled HD63B50 on schematic)
- //YMW258F(config, "gew8", 9.4_MHz_XTAL);
- //YM3413(config, "ldsp");
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+
+ multipcm_device &gew8(MULTIPCM(config, "gew8", 9.4_MHz_XTAL)); // YMW-258-F
+ gew8.add_route(1, "lspeaker", 1.0);
+ gew8.add_route(0, "rspeaker", 1.0);
+
+ //YM3413(config, "ldsp"); // PSR-500 only (has its own 256K-bit PSRAM)
}
ROM_START(psr500)
@@ -70,7 +79,7 @@ ROM_START(psr500)
ROM_RELOAD(0x0c0000, 0x040000)
ROM_LOAD("xj921b0.ic5", 0x100000, 0x100000, CRC(dd1a8afc) SHA1(5d5b47577faeed165f0bd73283f148d112e4d1e9))
- ROM_REGION(0x100000, "waverom", 0)
+ ROM_REGION(0x100000, "gew8", 0)
ROM_LOAD("xj426b0.ic3", 0x000000, 0x100000, CRC(ef566734) SHA1(864f5689dbaa82bd8a1be4e53bdb21ec71be03cc))
ROM_REGION(0x1000, "mpscpu", 0)