diff options
author | 2011-10-08 23:02:59 +0000 | |
---|---|---|
committer | 2011-10-08 23:02:59 +0000 | |
commit | f8aba531d3c7c43c01bdb32161b00f71f634d8ce (patch) | |
tree | 4068b0b7c6038fd08fdab24654756a7033676c4c /src/emu | |
parent | ec6a340d1ddd5dafb9765d48e47aa99743959a55 (diff) |
m68k: preliminary 68040 MMU implementation [R. Belmont]
Diffstat (limited to 'src/emu')
-rw-r--r-- | src/emu/cpu/m68000/m68k_in.c | 25 | ||||
-rw-r--r-- | src/emu/cpu/m68000/m68kcpu.c | 14 | ||||
-rw-r--r-- | src/emu/cpu/m68000/m68kcpu.h | 2 | ||||
-rw-r--r-- | src/emu/cpu/m68000/m68kmmu.h | 337 |
4 files changed, 318 insertions, 60 deletions
diff --git a/src/emu/cpu/m68000/m68k_in.c b/src/emu/cpu/m68000/m68k_in.c index a960eb0e34d..2dff4c05b13 100644 --- a/src/emu/cpu/m68000/m68k_in.c +++ b/src/emu/cpu/m68000/m68k_in.c @@ -6586,7 +6586,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x003: /* TC */ if(CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type)) { - /* TODO */ + REG_DA(mc68kcpu)[(word2 >> 12) & 15] = mc68kcpu->mmu_tc; return; } m68ki_exception_illegal(mc68kcpu); @@ -6646,7 +6646,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x805: /* MMUSR */ if(CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type)) { - /* TODO */ + REG_DA(mc68kcpu)[(word2 >> 12) & 15] = mc68kcpu->mmu_sr_040; return; } m68ki_exception_illegal(mc68kcpu); @@ -6654,7 +6654,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x806: /* URP */ if(CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type)) { - /* TODO */ + REG_DA(mc68kcpu)[(word2 >> 12) & 15] = mc68kcpu->mmu_urp_aptr; return; } m68ki_exception_illegal(mc68kcpu); @@ -6662,7 +6662,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x807: /* SRP */ if(CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type)) { - /* TODO */ + REG_DA(mc68kcpu)[(word2 >> 12) & 15] = mc68kcpu->mmu_srp_aptr; return; } m68ki_exception_illegal(mc68kcpu); @@ -6831,7 +6831,16 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x003: /* TC */ if (CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type)) { - /* TODO */ + mc68kcpu->mmu_tc = REG_DA(mc68kcpu)[(word2 >> 12) & 15]; + + if (mc68kcpu->mmu_tc & 0x8000) + { + mc68kcpu->pmmu_enabled = 1; + } + else + { + mc68kcpu->pmmu_enabled = 0; + } return; } m68ki_exception_illegal(mc68kcpu); @@ -6891,7 +6900,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x805: /* MMUSR */ if (CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type)) { - /* TODO */ + mc68kcpu->mmu_sr_040 = REG_DA(mc68kcpu)[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(mc68kcpu); @@ -6899,7 +6908,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x806: /* URP */ if (CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type)) { - /* TODO */ + mc68kcpu->mmu_urp_aptr = REG_DA(mc68kcpu)[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(mc68kcpu); @@ -6907,7 +6916,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x807: /* SRP */ if (CPU_TYPE_IS_040_PLUS((mc68kcpu)->cpu_type)) { - /* TODO */ + mc68kcpu->mmu_srp_aptr = REG_DA(mc68kcpu)[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(mc68kcpu); diff --git a/src/emu/cpu/m68000/m68kcpu.c b/src/emu/cpu/m68000/m68kcpu.c index bd822edc02b..356ecb3c81b 100644 --- a/src/emu/cpu/m68000/m68kcpu.c +++ b/src/emu/cpu/m68000/m68kcpu.c @@ -735,20 +735,28 @@ static CPU_TRANSLATE( m68k ) /* only applies to the program address space and only does something if the MMU's enabled */ if (m68k) { - if ((space == AS_PROGRAM) && (m68k->pmmu_enabled)) + /* 68040 needs to call the MMU even when disabled so transparent translation works */ + if ((space == AS_PROGRAM) && ((m68k->pmmu_enabled) || (CPU_TYPE_IS_040_PLUS(m68k->cpu_type)))) { // FIXME: mmu_tmp_sr will be overwritten in pmmu_translate_addr_with_fc UINT16 mmu_tmp_sr = m68k->mmu_tmp_sr; // UINT32 va=*address; - *address = pmmu_translate_addr_with_fc(m68k, *address, 4, 1); + if (CPU_TYPE_IS_040_PLUS(m68k->cpu_type)) + { + *address = pmmu_translate_addr_with_fc_040(m68k, *address, FUNCTION_CODE_SUPERVISOR_PROGRAM, 1); + } + else + { + *address = pmmu_translate_addr_with_fc(m68k, *address, FUNCTION_CODE_SUPERVISOR_PROGRAM, 1); + } if ((m68k->mmu_tmp_sr & M68K_MMU_SR_INVALID) != 0) { // logerror("cpu_translate_m68k failed with mmu_sr=%04x va=%08x pa=%08x\n",m68k->mmu_tmp_sr,va ,*address); *address = 0; } - m68k->mmu_tmp_sr= mmu_tmp_sr; + m68k->mmu_tmp_sr = mmu_tmp_sr; } } return TRUE; diff --git a/src/emu/cpu/m68000/m68kcpu.h b/src/emu/cpu/m68000/m68kcpu.h index f1d1dde725d..bcb6fd38d27 100644 --- a/src/emu/cpu/m68000/m68kcpu.h +++ b/src/emu/cpu/m68000/m68kcpu.h @@ -692,8 +692,10 @@ public: /* PMMU registers */ UINT32 mmu_crp_aptr, mmu_crp_limit; UINT32 mmu_srp_aptr, mmu_srp_limit; + UINT32 mmu_urp_aptr; /* 040 only */ UINT32 mmu_tc; UINT16 mmu_sr; + UINT32 mmu_sr_040; UINT32 mmu_atc_tag[MMU_ATC_ENTRIES], mmu_atc_data[MMU_ATC_ENTRIES]; UINT32 mmu_atc_rr; UINT32 mmu_tt0, mmu_tt1; diff --git a/src/emu/cpu/m68000/m68kmmu.h b/src/emu/cpu/m68000/m68kmmu.h index d00f142e66d..7df23fd31dc 100644 --- a/src/emu/cpu/m68000/m68kmmu.h +++ b/src/emu/cpu/m68000/m68kmmu.h @@ -2,7 +2,7 @@ m68kmmu.h - PMMU implementation for 68851/68030/68040 HMMU implementation for 68020 (II and LC variants) - By R. Belmont + By R. Belmont and Hans Ostermeyer Copyright Nicola Salmoria and the MAME Team. Visit http://mamedev.org for licensing and usage restrictions. @@ -148,7 +148,7 @@ void pmmu_atc_add(m68ki_cpu_core *m68k, UINT32 logical, UINT32 physical, int fc) } // add the entry - // logerror("ATC[%2d] add: log %08x -> phys %08x (fc=%d)\n", found, (logical>>ps) << ps, (physical >> ps) << ps, fc); + // printf("ATC[%2d] add: log %08x -> phys %08x (fc=%d)\n", found, (logical>>ps) << ps, (physical >> ps) << ps, fc); m68k->mmu_atc_tag[found] = atc_tag; m68k->mmu_atc_data[found] = (physical >> ps) << (ps-8); @@ -166,7 +166,7 @@ void pmmu_atc_add(m68ki_cpu_core *m68k, UINT32 logical, UINT32 physical, int fc) void pmmu_atc_flush(m68ki_cpu_core *m68k) { int i; - // logerror("ATC flush: pc=%08x\n", REG_PPC(m68k)); + // printf("ATC flush: pc=%08x\n", REG_PPC(m68k)); for (i = 0; i < MMU_ATC_ENTRIES; i++) { @@ -255,13 +255,13 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U UINT32 address_mask = ((m68k->mmu_tt0 << 8) & 0xff000000) ^ 0xff000000; if ((addr_in & address_mask) == address_base) { -// logerror("PMMU: pc=%x TT0 fc=%x addr_in=%08x address_mask=%08x address_base=%08x\n", m68k->ppc, fc, addr_in, address_mask, address_base); +// printf("PMMU: pc=%x TT0 fc=%x addr_in=%08x address_mask=%08x address_base=%08x\n", m68k->ppc, fc, addr_in, address_mask, address_base); return addr_in; } } // if ((++pmmu_access_count % 10000000) == 0) { -// logerror("pmmu_translate_addr_with_fc: atc usage = %d%%\n", pmmu_atc_count*100/pmmu_access_count); +// printf("pmmu_translate_addr_with_fc: atc usage = %d%%\n", pmmu_atc_count*100/pmmu_access_count); // pmmu_atc_count = pmmu_access_count = 0; // } @@ -298,7 +298,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U m68k->mmu_tmp_sr = M68K_MMU_SR_MODIFIED; } addr_out = (m68k->mmu_atc_data[i] << 8) | (addr_in & ~(~0 << ps)); -// logerror("ATC[%2d] hit: log %08x -> phys %08x pc=%08x fc=%d\n", i, addr_in, addr_out, REG_PPC(m68k), fc); +// printf("ATC[%2d] hit: log %08x -> phys %08x pc=%08x fc=%d\n", i, addr_in, addr_out, REG_PPC(m68k), fc); // pmmu_atc_count++; return addr_out; } @@ -323,7 +323,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U bbits = (m68k->mmu_tc >> 8) & 0xf; cbits = (m68k->mmu_tc >> 4) & 0xf; -// logerror("PMMU: tcr %08x limit %08x aptr %08x is %x abits %d bbits %d cbits %d\n", m68k->mmu_tc, root_limit, root_aptr, is, abits, bbits, cbits); +// printf("PMMU: tcr %08x limit %08x aptr %08x is %x abits %d bbits %d cbits %d\n", m68k->mmu_tc, root_limit, root_aptr, is, abits, bbits, cbits); // get table A offset tofs = (addr_in<<is)>>(32-abits); @@ -338,23 +338,23 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U case M68K_MMU_DF_DT1: // page descriptor, will cause direct mapping addr_out = tptr + addr_in; -// logerror("PMMU: PC=%x root mode %d (addr_in %08x -> %08x)\n", m68k->ppc, M68K_MMU_DF_DT1, addr_in, addr_out); +// printf("PMMU: PC=%x root mode %d (addr_in %08x -> %08x)\n", m68k->ppc, M68K_MMU_DF_DT1, addr_in, addr_out); return addr_out; case M68K_MMU_DF_DT2: // valid 4 byte descriptors tofs *= 4; -// if (verbose) logerror("PMMU: reading table A entry at %08x\n", tofs + tptr); +// if (verbose) printf("PMMU: reading table A entry at %08x\n", tofs + tptr); tbl_entry = get_dt2_table_entry(m68k, tptr + tofs, ptest); tamode = tbl_entry & M68K_MMU_DF_DT; -// if (verbose) logerror("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tamode, tofs); +// if (verbose) printf("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tamode, tofs); break; case M68K_MMU_DF_DT3: // valid 8 byte descriptors tofs *= 8; -// if (verbose) logerror("PMMU: reading table A entries at %08x\n", tofs + tptr); +// if (verbose) printf("PMMU: reading table A entries at %08x\n", tofs + tptr); tbl_entry = get_dt3_table_entry(m68k, tofs + tptr, fc, ptest); tamode = tbl_entry & M68K_MMU_DF_DT; -// if (verbose) logerror("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs); +// if (verbose) printf("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs); break; } @@ -376,19 +376,19 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U case M68K_MMU_DF_DT2: // 4-byte table B descriptor tofs *= 4; -// if (verbose) logerror("PMMU: reading table B entry at %08x\n", tofs + tptr); +// if (verbose) printf("PMMU: reading table B entry at %08x\n", tofs + tptr); tbl_entry = get_dt2_table_entry(m68k, tptr + tofs, ptest); tbmode = tbl_entry & M68K_MMU_DF_DT; -// if (verbose) logerror("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); +// if (verbose) printf("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); break; case M68K_MMU_DF_DT3: // 8-byte table B descriptor tofs *= 8; -// if (verbose) logerror("PMMU: reading table B entries at %08x\n", tofs + tptr); +// if (verbose) printf("PMMU: reading table B entries at %08x\n", tofs + tptr); tbl_entry = get_dt3_table_entry(m68k, tptr + tofs, fc, ptest); tbmode = tbl_entry & M68K_MMU_DF_DT; tbl_entry &= ~M68K_MMU_DF_DT; -// if (verbose) logerror("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); +// if (verbose) printf("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs); break; case M68K_MMU_DF_DT1: // early termination descriptor @@ -420,18 +420,18 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U case M68K_MMU_DF_DT2: // 4-byte table C descriptor tofs *= 4; -// if (verbose) logerror("PMMU: reading table C entry at %08x\n", tofs + tptr); +// if (verbose) printf("PMMU: reading table C entry at %08x\n", tofs + tptr); tbl_entry = get_dt2_table_entry(m68k, tptr + tofs, ptest); tcmode = tbl_entry & M68K_MMU_DF_DT; -// if (verbose) logerror("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); +// if (verbose) printf("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs); break; case M68K_MMU_DF_DT3: // 8-byte table C descriptor tofs *= 8; -// if (verbose) logerror("PMMU: reading table C entries at %08x\n", tofs + tptr); +// if (verbose) printf("PMMU: reading table C entries at %08x\n", tofs + tptr); tbl_entry = get_dt3_table_entry(m68k, tptr+ tofs, fc, ptest); tcmode = tbl_entry & M68K_MMU_DF_DT; -// if (verbose) logerror("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tcmode, tofs); +// if (verbose) printf("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tcmode, tofs); break; case M68K_MMU_DF_DT1: // termination descriptor @@ -500,7 +500,224 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U } } - //logerror("PMMU: [%08x] => [%08x]\n", addr_in, addr_out); + //printf("PMMU: [%08x] => [%08x]\n", addr_in, addr_out); + + return addr_out; +} + + +// FC bits: 2 = supervisor, 1 = program, 0 = data +// the 68040 is a subset of the 68851 and 68030 PMMUs - the page table sizes are fixed, there is no early termination, etc, etc. +/*INLINE*/ static UINT32 pmmu_translate_addr_with_fc_040(m68ki_cpu_core *m68k, UINT32 addr_in, UINT8 fc, UINT8 ptest) +{ + UINT32 addr_out, tt0, tt1; + + addr_out = addr_in; + m68k->mmu_tmp_sr = 0; + + // transparent translation registers are always in force even if the PMMU itself is disabled + // they don't do much in emulation because we never write out of order, but the write-protect and cache control features + // are emulatable, and apparently transparent translation regions skip the page table lookup. + if (fc & 1) // data, use DTT0/DTT1 + { + tt0 = m68k->mmu_dtt0; + tt1 = m68k->mmu_dtt1; + } + else if (fc & 2) // program, use ITT0/ITT1 + { + tt0 = m68k->mmu_itt0; + tt1 = m68k->mmu_itt1; + } + else + { + fatalerror("68040: function code %d is neither data nor program!\n", fc&7); + } + + if (tt0 & 0x8000) + { + UINT32 mask = (tt0>>16) & 0xff; + mask ^= 0xff; + mask <<= 24; + + if ((addr_in & mask) == (tt0 & mask)) + { +// printf("TT0 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt0, mask); + if ((tt0 & 4) && !m68k->mmu_tmp_rw && !ptest) // write protect? + { + if (++m68k->mmu_tmp_buserror_occurred == 1) + { + m68k->mmu_tmp_buserror_address = addr_in; + } + } + + return addr_in; + } + } + + if (tt1 & 0x8000) + { + UINT32 mask = (tt1>>16) & 0xff; + mask ^= 0xff; + mask <<= 24; + + if ((addr_in & mask) == (tt1 & mask)) + { +// printf("TT1 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt1, mask); + if ((tt1 & 4) && !m68k->mmu_tmp_rw && !ptest) // write protect? + { + if (++m68k->mmu_tmp_buserror_occurred == 1) + { + m68k->mmu_tmp_buserror_address = addr_in; + } + } + + return addr_in; + } + } + + if (m68k->pmmu_enabled) + { + UINT32 root_idx = (addr_in>>25) & 0x7f; + UINT32 ptr_idx = (addr_in>>18) & 0x7f; + UINT32 page_idx, page; + UINT32 root_ptr, pointer_ptr, page_ptr; + UINT32 root_entry, pointer_entry, page_entry; + + // select supervisor or user root pointer + if (fc & 4) + { + root_ptr = m68k->mmu_srp_aptr + (root_idx<<2); + } + else + { + root_ptr = m68k->mmu_urp_aptr + (root_idx<<2); + } + + // get the root entry + root_entry = m68k->program->read_dword(root_ptr); +// printf("root entry = %08x\n", root_entry); + + // is UDT marked valid? + if (root_entry & 2) + { + pointer_ptr = (root_entry & ~0x1ff) + (ptr_idx<<2); + pointer_entry = m68k->program->read_dword(pointer_ptr); + +// printf("pointer entry = %08x\n", pointer_entry); + + // write protected by the root or pointer entries? + if ((((root_entry & 4) && !m68k->mmu_tmp_rw) || ((pointer_entry & 4) && !m68k->mmu_tmp_rw)) && !ptest) + { + if (++m68k->mmu_tmp_buserror_occurred == 1) + { + m68k->mmu_tmp_buserror_address = addr_in; + } + + return addr_in; + } + + // is UDT valid on the pointer entry? + if (!(pointer_entry & 2) && !ptest) + { +// printf("Invalid pointer entry! PC=%x, addr=%x\n", m68k->ppc, addr_in); + if (++m68k->mmu_tmp_buserror_occurred == 1) + { + m68k->mmu_tmp_buserror_address = addr_in; + } + + return addr_in; + } + + // (fall out of these ifs into the page lookup below) + } + else // throw an error + { +// printf("Invalid root entry! PC=%x, addr=%x\n", m68k->ppc, addr_in); + if (!ptest) + { + if (++m68k->mmu_tmp_buserror_occurred == 1) + { + m68k->mmu_tmp_buserror_address = addr_in; + } + } + + return addr_in; + } + + // now do the page lookup + if (m68k->mmu_tc & 0x4000) // 8k pages? + { + page_idx = (addr_in >> 13) & 0x1f; + page = addr_in & 0x1fff; + pointer_entry &= ~0x7f; + +// printf("8k pages: index %x page %x\n", page_idx, page); + } + else // 4k pages + { + page_idx = (addr_in >> 12) & 0x3f; + page = addr_in & 0xfff; + pointer_entry &= ~0xff; + +// printf("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); + +// printf("page_entry = %08x\n", page_entry); + + // resolve indirect page pointers + while ((page_entry & 3) == 2) + { + page_entry = m68k->program->read_dword(page_entry & ~0x3); + } + + // is the page write protected or supervisor protected? + if ((((page_entry & 4) && !m68k->mmu_tmp_rw) || ((page_entry & 0x80) && !(fc&4))) && !ptest) + { + if (++m68k->mmu_tmp_buserror_occurred == 1) + { + m68k->mmu_tmp_buserror_address = addr_in; + } + + return addr_in; + } + + switch (page_entry & 3) + { + case 0: // invalid +// printf("Invalid page entry! PC=%x, addr=%x\n", m68k->ppc, addr_in); + if (!ptest) + { + if (++m68k->mmu_tmp_buserror_occurred == 1) + { + m68k->mmu_tmp_buserror_address = addr_in; + } + } + + return addr_in; + + case 1: + case 3: // normal + if (m68k->mmu_tc & 0x4000) // 8k pages? + { + addr_out = (page_entry & ~0x1fff) | page; + } + else + { + addr_out = (page_entry & ~0xfff) | page; + } + + + break; + + case 2: // shouldn't happen + fatalerror("68040: got indirect final page pointer, shouldn't be possible\n"); + break; + } +// if (addr_in != addr_out) printf("040MMU: [%08x] => [%08x]\n", addr_in, addr_out); + } return addr_out; } @@ -510,10 +727,19 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U */ /*INLINE*/ static UINT32 pmmu_translate_addr(m68ki_cpu_core *m68k, UINT32 addr_in) { - UINT32 addr_out = pmmu_translate_addr_with_fc(m68k, addr_in, m68k->mmu_tmp_fc, 0); + UINT32 addr_out; + + if (CPU_TYPE_IS_040_PLUS(m68k->cpu_type)) + { + addr_out = pmmu_translate_addr_with_fc_040(m68k, addr_in, m68k->mmu_tmp_fc, 0); + } + else + { + addr_out = pmmu_translate_addr_with_fc(m68k, addr_in, m68k->mmu_tmp_fc, 0); + } // if (m68k->mmu_tmp_buserror_occurred > 0) { -// logerror("PMMU: pc=%08x sp=%08x va=%08x pa=%08x - invalid Table mode for level=%d (buserror %d)\n", +// printf("PMMU: pc=%08x sp=%08x va=%08x pa=%08x - invalid Table mode for level=%d (buserror %d)\n", // REG_PPC(m68k), REG_A(m68k)[7], addr_in, addr_out, m68k->mmu_tmp_sr & M68K_MMU_SR_LEVEL_3, // m68k->mmu_tmp_buserror_occurred); // } @@ -522,8 +748,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, U } /* - m68881_mmu_ops: COP 0 MMU opcode handling - + m68851_mmu_ops: COP 0 MMU opcode handling */ void m68881_mmu_ops(m68ki_cpu_core *m68k) @@ -536,12 +761,12 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) // catch the 2 "weird" encodings up front (PBcc) if ((m68k->ir & 0xffc0) == 0xf0c0) { - logerror("680x0: unhandled PBcc\n"); + printf("680x0: unhandled PBcc\n"); return; } else if ((m68k->ir & 0xffc0) == 0xf080) { - logerror("680x0: unhandled PBcc\n"); + printf("680x0: unhandled PBcc\n"); return; } else // the rest are 1111000xxxXXXXXX where xxx is the instruction family @@ -559,10 +784,17 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) ptmp = ltmp; if (m68k->pmmu_enabled) { - ptmp = pmmu_translate_addr_with_fc(m68k, ltmp, modes & 0x07, 0); + if (CPU_TYPE_IS_040_PLUS(m68k->cpu_type)) + { + ptmp = pmmu_translate_addr_with_fc_040(m68k, ltmp, modes & 0x07, 0); + } + else + { + ptmp = pmmu_translate_addr_with_fc(m68k, ltmp, modes & 0x07, 0); + } } - logerror("680x0: PLOADing ATC with logical %08x => phys %08x\n", ltmp, ptmp); + printf("680x0: PLOADing ATC with logical %08x => phys %08x\n", ltmp, ptmp); // FIXME: rw bit? pmmu_atc_add(m68k, ltmp, ptmp, modes & 0x07); return; @@ -579,12 +811,12 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) } else if (modes == 0x2800) // PVALID (FORMAT 1) { - logerror("680x0: unhandled PVALID1\n"); + printf("680x0: unhandled PVALID1\n"); return; } else if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) { - logerror("680x0: unhandled PVALID2\n"); + printf("680x0: unhandled PVALID2\n"); return; } else if ((modes & 0xe000) == 0x8000) // PTEST @@ -604,10 +836,17 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) break; } - p_addr = pmmu_translate_addr_with_fc(m68k, v_addr, fc, 1); + if (CPU_TYPE_IS_040_PLUS(m68k->cpu_type)) + { + p_addr = pmmu_translate_addr_with_fc_040(m68k, v_addr, fc, 1); + } + else + { + p_addr = pmmu_translate_addr_with_fc(m68k, v_addr, fc, 1); + } m68k->mmu_sr = m68k->mmu_tmp_sr; -// logerror("PMMU: pc=%08x sp=%08x va=%08x pa=%08x PTEST fc=%x level=%x mmu_sr=%04x\n", +// printf("PMMU: pc=%08x sp=%08x va=%08x pa=%08x PTEST fc=%x level=%x mmu_sr=%04x\n", // m68k->ppc, REG_A(m68k)[7], v_addr, p_addr, fc, (modes >> 10) & 0x07, m68k->mmu_sr); if (modes & 0x100) @@ -629,29 +868,29 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) { case 0x02: // transparent translation register 0 WRITE_EA_32(m68k, ea, m68k->mmu_tt0); -// logerror("PMMU: pc=%x PMOVE from mmu_tt0=%08x\n", m68k->ppc, m68k->mmu_tt0); +// printf("PMMU: pc=%x PMOVE from mmu_tt0=%08x\n", m68k->ppc, m68k->mmu_tt0); break; case 0x03: // transparent translation register 1 WRITE_EA_32(m68k, ea, m68k->mmu_tt1); -// logerror("PMMU: pc=%x PMOVE from mmu_tt1=%08x\n", m68k->ppc, m68k->mmu_tt1); +// printf("PMMU: pc=%x PMOVE from mmu_tt1=%08x\n", m68k->ppc, m68k->mmu_tt1); break; case 0x10: // translation control register WRITE_EA_32(m68k, ea, m68k->mmu_tc); -// logerror("PMMU: pc=%x PMOVE from mmu_tc=%08x\n", m68k->ppc, m68k->mmu_tc); +// printf("PMMU: pc=%x PMOVE from mmu_tc=%08x\n", m68k->ppc, m68k->mmu_tc); break; case 0x12: // supervisor root pointer WRITE_EA_64(m68k, ea, (UINT64)m68k->mmu_srp_limit<<32 | (UINT64)m68k->mmu_srp_aptr); -// logerror("PMMU: pc=%x PMOVE from SRP limit = %08x, aptr = %08x\n", REG_PPC(m68k), m68k->mmu_srp_limit, m68k->mmu_srp_aptr); +// printf("PMMU: pc=%x PMOVE from SRP limit = %08x, aptr = %08x\n", REG_PPC(m68k), m68k->mmu_srp_limit, m68k->mmu_srp_aptr); break; case 0x13: // CPU root pointer WRITE_EA_64(m68k, ea, (UINT64)m68k->mmu_crp_limit<<32 | (UINT64)m68k->mmu_crp_aptr); -// logerror("PMMU: pc=%x PMOVE from CRP limit = %08x, aptr = %08x\n", REG_PPC(m68k), m68k->mmu_crp_limit, m68k->mmu_crp_aptr); +// printf("PMMU: pc=%x PMOVE from CRP limit = %08x, aptr = %08x\n", REG_PPC(m68k), m68k->mmu_crp_limit, m68k->mmu_crp_aptr); break; default: - logerror("680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, m68k->pc); + printf("680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, m68k->pc); break; } @@ -676,7 +915,7 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) break; case 1: - logerror("680x0: unknown PMOVE case 1, PC %x\n", m68k->pc); + printf("680x0: unknown PMOVE case 1, PC %x\n", m68k->pc); break; case 2: @@ -684,17 +923,17 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) { case 0: // translation control register m68k->mmu_tc = READ_EA_32(m68k, ea); -// logerror("PMMU: TC = %08x\n", m68k->mmu_tc); +// printf("PMMU: TC = %08x\n", m68k->mmu_tc); if (m68k->mmu_tc & 0x80000000) { m68k->pmmu_enabled = 1; -// logerror("PMMU enabled\n"); +// printf("PMMU enabled\n"); } else { m68k->pmmu_enabled = 0; -// logerror("PMMU disabled\n"); +// printf("PMMU disabled\n"); } if (!(modes & 0x100)) // flush ATC on moves to TC, SRP, CRP with FD bit clear @@ -707,7 +946,7 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) temp64 = READ_EA_64(m68k, ea); m68k->mmu_srp_limit = (temp64>>32) & 0xffffffff; m68k->mmu_srp_aptr = temp64 & 0xffffffff; -// logerror("PMMU: SRP limit = %08x aptr = %08x\n", m68k->mmu_srp_limit, m68k->mmu_srp_aptr); +// printf("PMMU: SRP limit = %08x aptr = %08x\n", m68k->mmu_srp_limit, m68k->mmu_srp_aptr); if (!(modes & 0x100)) { pmmu_atc_flush(m68k); @@ -718,7 +957,7 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) temp64 = READ_EA_64(m68k, ea); m68k->mmu_crp_limit = (temp64>>32) & 0xffffffff; m68k->mmu_crp_aptr = temp64 & 0xffffffff; -// logerror("PMMU: CRP limit = %08x aptr = %08x\n", m68k->mmu_crp_limit, m68k->mmu_crp_aptr); +// printf("PMMU: CRP limit = %08x aptr = %08x\n", m68k->mmu_crp_limit, m68k->mmu_crp_aptr); if (!(modes & 0x100)) { pmmu_atc_flush(m68k); @@ -726,7 +965,7 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) break; default: - logerror("680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, m68k->pc); + printf("680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, m68k->pc); break; } break; @@ -734,7 +973,7 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) case 3: // MMU status { UINT32 temp = READ_EA_32(m68k, ea); - logerror("680x0: unsupported PMOVE %x to MMU status, PC %x\n", temp, m68k->pc); + printf("680x0: unsupported PMOVE %x to MMU status, PC %x\n", temp, m68k->pc); } break; } @@ -753,7 +992,7 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) break; default: - logerror("680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, m68k->pc); + printf("680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, m68k->pc); break; } @@ -761,7 +1000,7 @@ void m68881_mmu_ops(m68ki_cpu_core *m68k) break; default: - logerror("680x0: unknown PMMU instruction group %d\n", (m68k->ir>>9) & 0x7); + printf("680x0: unknown PMMU instruction group %d\n", (m68k->ir>>9) & 0x7); break; } } |