Emulate MN18801A MMU

This commit is contained in:
AJR 2022-09-16 23:24:58 -04:00
parent 6a1747348d
commit e43bc4bc3e
3 changed files with 214 additions and 127 deletions

View File

@ -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

View File

@ -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

View File

@ -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)