mirror of
https://github.com/holub/mame
synced 2025-04-26 10:13:37 +03:00
Emulate MN18801A MMU
This commit is contained in:
parent
6a1747348d
commit
e43bc4bc3e
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user