mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
m68k: Update used and modified bits in the page tables and greatly improved PTEST results on 68040. [R. Belmont]
nw: do a clean build after this or nothing using a 680x0 will work properly.
This commit is contained in:
parent
13a04d8822
commit
354873849d
@ -351,6 +351,7 @@ public:
|
||||
UINT32 mmu_tt0, mmu_tt1;
|
||||
UINT32 mmu_itt0, mmu_itt1, mmu_dtt0, mmu_dtt1;
|
||||
UINT32 mmu_acr0, mmu_acr1, mmu_acr2, mmu_acr3;
|
||||
UINT32 mmu_last_page_entry, mmu_last_page_entry_addr;
|
||||
|
||||
UINT16 mmu_tmp_sr; /* temporary hack: status code for ptest and to handle write protection */
|
||||
UINT16 mmu_tmp_fc; /* temporary hack: function code for the mmu (moves) */
|
||||
|
@ -1018,6 +1018,8 @@ void m68000_base_device::init_cpu_common(void)
|
||||
save_item(NAME(mmu_acr1));
|
||||
save_item(NAME(mmu_acr2));
|
||||
save_item(NAME(mmu_acr3));
|
||||
save_item(NAME(mmu_last_page_entry));
|
||||
save_item(NAME(mmu_last_page_entry_addr));
|
||||
|
||||
for (int i=0; i<MMU_ATC_ENTRIES;i++) {
|
||||
save_item(NAME(mmu_atc_tag[i]), i);
|
||||
|
@ -625,9 +625,35 @@ INLINE UINT32 get_dt3_table_entry(m68000_base_device *m68k, UINT32 tptr, UINT8 f
|
||||
// is UDT marked valid?
|
||||
if (root_entry & 2)
|
||||
{
|
||||
// we're accessing through this root entry, so set the U bit
|
||||
if ((!(root_entry & 0x8)) && (!ptest))
|
||||
{
|
||||
root_entry |= 0x8;
|
||||
m68k->program->write_dword(root_ptr, root_entry);
|
||||
}
|
||||
|
||||
// PTEST: any write protect bits set in the search tree will set W in SR
|
||||
if ((ptest) && (root_entry & 4))
|
||||
{
|
||||
m68k->mmu_tmp_sr |= 4;
|
||||
}
|
||||
|
||||
pointer_ptr = (root_entry & ~0x1ff) + (ptr_idx<<2);
|
||||
pointer_entry = m68k->program->read_dword(pointer_ptr);
|
||||
|
||||
// PTEST: any write protect bits set in the search tree will set W in SR
|
||||
if ((ptest) && (pointer_entry & 4))
|
||||
{
|
||||
m68k->mmu_tmp_sr |= 4;
|
||||
}
|
||||
|
||||
// update U bit on this pointer entry too
|
||||
if ((!(pointer_entry & 0x8)) && (!ptest))
|
||||
{
|
||||
pointer_entry |= 0x8;
|
||||
m68k->program->write_dword(pointer_ptr, pointer_entry);
|
||||
}
|
||||
|
||||
// logerror("pointer entry = %08x\n", pointer_entry);
|
||||
|
||||
// write protected by the root or pointer entries?
|
||||
@ -682,7 +708,6 @@ INLINE UINT32 get_dt3_table_entry(m68000_base_device *m68k, UINT32 tptr, UINT8 f
|
||||
page_idx = (addr_in >> 13) & 0x1f;
|
||||
page = addr_in & 0x1fff;
|
||||
pointer_entry &= ~0x7f;
|
||||
|
||||
// logerror("8k pages: index %x page %x\n", page_idx, page);
|
||||
}
|
||||
else // 4k pages
|
||||
@ -690,12 +715,12 @@ INLINE UINT32 get_dt3_table_entry(m68000_base_device *m68k, UINT32 tptr, UINT8 f
|
||||
page_idx = (addr_in >> 12) & 0x3f;
|
||||
page = addr_in & 0xfff;
|
||||
pointer_entry &= ~0xff;
|
||||
|
||||
// logerror("4k pages: index %x page %x\n", page_idx, page);
|
||||
}
|
||||
|
||||
page_ptr = pointer_entry + (page_idx<<2);
|
||||
page_entry = m68k->program->read_dword(page_ptr);
|
||||
m68k->mmu_last_page_entry_addr = page_ptr;
|
||||
|
||||
// logerror("page_entry = %08x\n", page_entry);
|
||||
|
||||
@ -703,7 +728,9 @@ INLINE UINT32 get_dt3_table_entry(m68000_base_device *m68k, UINT32 tptr, UINT8 f
|
||||
while ((page_entry & 3) == 2)
|
||||
{
|
||||
page_entry = m68k->program->read_dword(page_entry & ~0x3);
|
||||
m68k->mmu_last_page_entry_addr = (page_entry & ~0x3);
|
||||
}
|
||||
m68k->mmu_last_page_entry = page_entry;
|
||||
|
||||
// is the page write protected or supervisor protected?
|
||||
if ((((page_entry & 4) && !m68k->mmu_tmp_rw) || ((page_entry & 0x80) && !(fc&4))) && !ptest)
|
||||
@ -745,8 +772,30 @@ INLINE UINT32 get_dt3_table_entry(m68000_base_device *m68k, UINT32 tptr, UINT8 f
|
||||
addr_out = (page_entry & ~0xfff) | page;
|
||||
}
|
||||
|
||||
if (!(ptest))
|
||||
{
|
||||
page_entry |= 0x8; // always set the U bit
|
||||
|
||||
break;
|
||||
// if we're writing, the M bit comes into play
|
||||
if (!m68k->mmu_tmp_rw)
|
||||
{
|
||||
page_entry |= 0x10; // set Modified
|
||||
}
|
||||
|
||||
// if these updates resulted in a change, write the entry back where we found it
|
||||
if (page_entry != m68k->mmu_last_page_entry)
|
||||
{
|
||||
m68k->mmu_last_page_entry = page_entry;
|
||||
m68k->program->write_dword(m68k->mmu_last_page_entry_addr, m68k->mmu_last_page_entry);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// page entry: UR G U1 U0 S CM CM M U W PDT
|
||||
// SR: B G U1 U0 S CM CM M 0 W T R
|
||||
m68k->mmu_tmp_sr |= ((addr_out & ~0xfff) || (page_entry & 0x7f4));
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // shouldn't happen
|
||||
fatalerror("68040: got indirect final page pointer, shouldn't be possible\n");
|
||||
|
Loading…
Reference in New Issue
Block a user