summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/ibm/rosetta.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/ibm/rosetta.cpp')
-rw-r--r--src/mame/ibm/rosetta.cpp74
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;