diff options
Diffstat (limited to 'src/devices/cpu/mn1880/mn1880.cpp')
-rw-r--r-- | src/devices/cpu/mn1880/mn1880.cpp | 335 |
1 files changed, 201 insertions, 134 deletions
diff --git a/src/devices/cpu/mn1880/mn1880.cpp b/src/devices/cpu/mn1880/mn1880.cpp index 5c92d2b7b76..32b14a8a640 100644 --- a/src/devices/cpu/mn1880/mn1880.cpp +++ b/src/devices/cpu/mn1880/mn1880.cpp @@ -64,6 +64,20 @@ contents of locations about to be written to may show misleading values. Likewise, PCs at which watchpoint hits occur may be incorrectly reported for writes. + * Due to the pipelining of writes, an interrupt may be accepted during + an instruction which attempts to disable interrupts by setting the + IEMASK bit, which may be cleared instead when control reaches the next + sequential instruction from a RETI. This sequencing glitch is + documented in the MN187XX23 user's manual, along with a failsafe way + of setting IEMASK, and similar workarounds in extant program code + suggest it is likewise present in the MN1880 series. + * The optional MMU, which expands the memory spaces in certain models + which contain neither internal ROM nor RAM, has been emulated only + to the extent required by psr500, though it likely has a few other + features and quirks. + * In DF mode, MOV (da),(YP) and MOV (XP),(da) apparently need to take + the high byte of the direct address from the opposite pointer, + despite MN1870 documentation suggesting these use the same pointer. ***************************************************************************/ @@ -73,13 +87,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 +105,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 +154,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 +306,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 +338,25 @@ 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, address_space *&target_space) +{ + target_space = &space(spacenum); + 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] = @@ -363,6 +435,7 @@ u8 mn1880_device::cpu_registers::addcz(u8 data1, u8 data2, bool carry, bool hold return data1; } +// 4-bit decimal add with carry (without adjust) u8 mn1880_device::cpu_registers::adddcz(u8 data1, u8 data2, bool carry) { if (((data1 & 0x0f) + (data2 & 0x0f) + (carry ? 1 : 0)) >= 0x0a) @@ -391,6 +464,7 @@ u8 mn1880_device::cpu_registers::subcz(u8 data1, u8 data2, bool carry, bool hold return data1; } +// 4-bit decimal subtract with carry (without adjust) u8 mn1880_device::cpu_registers::subdcz(u8 data1, u8 data2, bool carry) { if ((data1 & 0x0f) < (data2 & 0x0f) + (carry ? 1 : 0)) @@ -439,18 +513,11 @@ u8 mn1880_device::cpu_registers::rorc(u8 data) u8 mn1880_device::cpu_registers::asrc(u8 data) { - if (BIT(data, 7)) - { - if (!BIT(data, 0)) - fs &= 0x7f; - return (data >> 1) | 0x80; - } + if (BIT(data, 0)) + fs |= 0x80; else - { - if (BIT(data, 0)) - fs |= 0x80; - return data >> 1; - } + fs &= 0x7f; + return (data >> 1) | (data & 0x80); } void mn1880_device::cpu_registers::branch(u16 label) @@ -507,7 +574,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: @@ -520,7 +587,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) @@ -551,7 +618,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 @@ -563,7 +630,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; @@ -589,21 +656,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; @@ -620,20 +687,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,12 +708,12 @@ void mn1880_device::execute_run() case microstate::MOV36_1: if (BIT(cpu.fs, 5)) - m_da |= cpu.xp & 0xff00; + m_da |= cpu.yp & 0xff00; m_ustate = microstate::MOV36_2; 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; @@ -657,10 +724,10 @@ 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; + m_da |= cpu.xp & 0xff00; m_ustate = microstate::MOV56_2; break; @@ -671,13 +738,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; @@ -695,7 +762,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(); @@ -714,7 +781,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(); @@ -733,7 +800,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; @@ -776,7 +843,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; @@ -799,7 +866,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; @@ -811,7 +878,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; @@ -825,7 +892,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; @@ -848,7 +915,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); @@ -904,7 +971,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; @@ -925,7 +992,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; @@ -936,19 +1003,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; @@ -983,7 +1050,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(); @@ -997,7 +1064,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; @@ -1017,7 +1084,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); @@ -1031,7 +1098,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)) @@ -1040,7 +1107,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; @@ -1062,7 +1129,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); @@ -1080,12 +1147,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(); @@ -1098,13 +1165,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; @@ -1128,7 +1195,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; @@ -1144,14 +1211,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; @@ -1160,14 +1227,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; @@ -1183,20 +1250,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); @@ -1213,7 +1280,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; @@ -1241,7 +1308,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; @@ -1261,7 +1328,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; @@ -1287,7 +1354,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; @@ -1305,7 +1372,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 @@ -1336,7 +1403,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; @@ -1354,7 +1421,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 @@ -1385,7 +1452,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; @@ -1403,7 +1470,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 @@ -1434,7 +1501,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; @@ -1452,7 +1519,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; @@ -1479,7 +1546,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; @@ -1497,7 +1564,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; @@ -1538,7 +1605,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; @@ -1556,7 +1623,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; @@ -1583,7 +1650,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; @@ -1601,7 +1668,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; @@ -1637,7 +1704,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)) { @@ -1654,14 +1721,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; @@ -1669,7 +1736,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...) @@ -1703,7 +1770,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)) { @@ -1718,19 +1785,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; @@ -1738,7 +1805,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(); @@ -1757,7 +1824,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)) { @@ -1772,19 +1839,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; @@ -1792,7 +1859,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(); @@ -1808,7 +1875,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; @@ -1825,7 +1892,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; @@ -1836,13 +1903,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; @@ -1857,7 +1924,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(); @@ -1885,13 +1952,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; @@ -1905,13 +1972,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; @@ -1948,13 +2015,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; @@ -1964,13 +2031,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; @@ -1982,7 +2049,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; @@ -1993,7 +2060,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; @@ -2008,7 +2075,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; @@ -2077,7 +2144,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 @@ -2104,24 +2171,24 @@ void mn1880_device::execute_run() case microstate::ADDRE8_1: ++cpu.ip; if (BIT(cpu.fs, 5)) - m_da |= cpu.yp & 0x00ff; + m_da |= cpu.yp & 0xff00; m_tmp2 = input; m_ustate = microstate::ADDRE8_2; 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; + m_da |= cpu.xp & 0xff00; m_ustate = microstate::ADDRE8_3; break; 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(m_tmp1, 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(m_tmp1, m_data.read_byte(mmu_data_translate(m_da)), false, false)); m_ustate = microstate::NOP_1; // TODO: output queue (XPl only?) break; @@ -2130,12 +2197,12 @@ void mn1880_device::execute_run() m_tmp2 = m_da & 0x00ff; m_da = input; if (BIT(cpu.fs, 5)) - m_da |= (BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) & 0x00ff; + m_da |= (BIT(cpu.ir, 1) ? cpu.yp : cpu.xp) & 0xff00; m_ustate = microstate::ADDRE9_2; 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; @@ -2158,7 +2225,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; @@ -2174,7 +2241,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; @@ -2196,7 +2263,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; @@ -2212,13 +2279,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; @@ -2240,13 +2307,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; @@ -2257,20 +2324,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; @@ -2284,7 +2351,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(); @@ -2308,14 +2375,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; @@ -2364,7 +2431,7 @@ void mn1880_device::execute_run() { // IRQ0 (first of four external edge inputs?) has the highest priority (after RESET) unsigned level = 32 - count_leading_zeros_32((m_irq - 1) & ~m_irq); - (void)standard_irq_callback(level); + (void)standard_irq_callback(level, cpu.ip); cpu.ie &= ~(1 << level); // No separate in-service lockout; handler must re-enable specific interrupt m_if &= ~(1 << level); cpu.iemask = true; @@ -2385,13 +2452,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; @@ -2399,7 +2466,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 |