diff options
Diffstat (limited to 'src/mame/ibm/rosetta.cpp')
| -rw-r--r-- | src/mame/ibm/rosetta.cpp | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/src/mame/ibm/rosetta.cpp b/src/mame/ibm/rosetta.cpp index cc624d61e48..fa79917ac90 100644 --- a/src/mame/ibm/rosetta.cpp +++ b/src/mame/ibm/rosetta.cpp @@ -226,8 +226,6 @@ void rosetta_device::device_start() m_ecc = std::make_unique<u8[]>(m_ram_size); m_rca = std::make_unique<u8[]>(2048); - offs_t const mask = m_rom.bytes() - 1; - m_mem_space->install_rom(0, mask, 0xffffff & ~mask, m_rom); m_mem_space->cache(m_mem); } @@ -360,6 +358,78 @@ bool rosetta_device::iow(u32 address, u32 data) return true; } +// translate logical to physical address ignoring protection and without side effects +bool rosetta_device::translate(u32 &address) const +{ + unsigned const segment = address >> 28; + + // segment present + if (!(m_segment[segment] & SEGMENT_P)) + return false; + + // segment zero virtual equal to real + if ((m_control[TCR] & TCR_V) && !segment) + { + address &= 0x00ff'ffffU; + + return true; + } + + u64 const virtual_address = (u64(m_segment[segment] & SEGMENT_ID) << 26) | (address & 0x0fff'ffffU); + + // ignore tlb and directly search inverted page table + u32 page_address = 0; + { + // compute hat index + u16 hat_offset = (((virtual_address >> 26) & SEGMENT_ID) ^ (virtual_address >> (m_page_shift - 2))) & m_hat_mask; + + // fetch hat entry + u32 hat_entry = m_ram[m_hat_base + hat_offset + 1]; + + // page fault + if (hat_entry & HAT_E) + return false; + + // compute ipt entry pointer + hat_offset = ((hat_entry & HAT_HATP) >> 14); + u32 const address = (virtual_address >> 11) & m_atag_mask; + + // ipt search + for (unsigned count = 0; count < 1024; count++) + { + // fetch ipt entry + u32 const ipt_entry = m_ram[m_hat_base + hat_offset + 0]; + + if ((ipt_entry & m_atag_mask) == address) + { + // reload tlb + page_address = (hat_offset << 1) | TLB_V | (ipt_entry >> 30); + + // found + break; + } + + // fetch next hat entry + hat_entry = m_ram[m_hat_base + hat_offset + 1]; + if (hat_entry & HAT_L) + return false; + + // select next ipt entry + hat_offset = (hat_entry & HAT_IPTP) << 2; + } + + // search failed + if (!page_address) + return false; + } + + u32 const real_page = (page_address << 8) & m_page_mask; + + address = real_page | (address & ~m_page_mask); + + return true; +} + bool rosetta_device::translate(u32 &address, bool system_processor, bool store) { unsigned const segment = address >> 28; |
