diff --git a/src/emu/cpu/powerpc/ppc.c b/src/emu/cpu/powerpc/ppc.c index d13c901dcad..77650fa0c1f 100644 --- a/src/emu/cpu/powerpc/ppc.c +++ b/src/emu/cpu/powerpc/ppc.c @@ -817,12 +817,10 @@ INLINE UINT32 ppc_get_cr(void) return CR(0) << 28 | CR(1) << 24 | CR(2) << 20 | CR(3) << 16 | CR(4) << 12 | CR(5) << 8 | CR(6) << 4 | CR(7); } -#ifdef UNUSED_FUNCTION INLINE void ppc_exception(int exception_type) { longjmp(ppc.exception_jmpbuf, exception_type); } -#endif /***********************************************************************/ diff --git a/src/emu/cpu/powerpc/ppc_mem.c b/src/emu/cpu/powerpc/ppc_mem.c index e9aebed95b9..c96002751ab 100644 --- a/src/emu/cpu/powerpc/ppc_mem.c +++ b/src/emu/cpu/powerpc/ppc_mem.c @@ -122,6 +122,14 @@ enum }; #ifdef MESS +#define PPC_MMU_ENABLED 1 +#else /* !MESS */ +/* MMU not enabled in MAME; model3 drivers don't work properly */ +#define PPC_MMU_ENABLED 0 +#endif /* MESS */ + + + static int ppc_is_protected(UINT32 pp, int flags) { if (flags & PPC_TRANSLATE_WRITE) @@ -136,154 +144,156 @@ static int ppc_is_protected(UINT32 pp, int flags) } return FALSE; } -#endif static int ppc_translate_address(offs_t *addr_ptr, int flags) { -#ifdef MESS - const BATENT *bat; - UINT32 address; - UINT32 sr, vsid, hash; - UINT32 pteg_address; - UINT32 target_pte, bl, mask; - UINT64 pte; - UINT64 *pteg_ptr[2]; - int i, hash_type; - UINT32 dsisr = DSISR_PROT; - - bat = (flags & PPC_TRANSLATE_CODE) ? ppc.ibat : ppc.dbat; - - address = *addr_ptr; - - /* first check the block address translation table */ - for (i = 0; i < 4; i++) + if (PPC_MMU_ENABLED) { - if (bat[i].u & ((MSR & MSR_PR) ? 0x00000001 : 0x00000002)) + const BATENT *bat; + UINT32 address; + UINT32 sr, vsid, hash; + UINT32 pteg_address; + UINT32 target_pte, bl, mask; + UINT64 pte; + UINT64 *pteg_ptr[2]; + int i, hash_type; + UINT32 dsisr = DSISR_PROT; + + bat = (flags & PPC_TRANSLATE_CODE) ? ppc.ibat : ppc.dbat; + + address = *addr_ptr; + + /* first check the block address translation table */ + for (i = 0; i < 4; i++) { - bl = bat[i].u & 0x00001FFC; - mask = (~bl << 15) & 0xFFFE0000; - - if ((address & mask) == (bat[i].u & 0xFFFE0000)) - { - if (ppc_is_protected(bat[i].l, flags)) - goto exception; - - *addr_ptr = (bat[i].l & 0xFFFE0000) - | (address & ((bl << 15) | 0x0001FFFF)); - return 1; - } - } - } - - /* now try page address translation */ - sr = ppc.sr[(address >> 28) & 0x0F]; - if (sr & 0x80000000) - { - /* direct store translation */ - if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0) - fatalerror("ppc: direct store translation not yet implemented"); - return 0; - } - else - { - /* is no execute is set? */ - if ((flags & PPC_TRANSLATE_CODE) && (sr & 0x10000000)) - goto exception; - - vsid = sr & 0x00FFFFFF; - hash = (vsid & 0x0007FFFF) ^ ((address >> 12) & 0xFFFF); - target_pte = (vsid << 7) | ((address >> 22) & 0x3F) | 0x80000000; - - /* we have to try both types of hashes */ - for (hash_type = 0; hash_type <= 1; hash_type++) - { - pteg_address = (ppc.sdr1 & 0xFFFF0000) - | (((ppc.sdr1 & 0x01FF) & (hash >> 10)) << 16) - | ((hash & 0x03FF) << 6); - - pteg_ptr[hash_type] = memory_get_read_ptr(cpu_getactivecpu(), ADDRESS_SPACE_PROGRAM, pteg_address); - if (pteg_ptr[hash_type]) - { - for (i = 0; i < 8; i++) - { - pte = pteg_ptr[hash_type][i]; - - /* is valid? */ - if (((pte >> 32) & 0xFFFFFFFF) == target_pte) - { - if (ppc_is_protected((UINT32) pte, flags)) - goto exception; - - *addr_ptr = ((UINT32) (pte & 0xFFFFF000)) - | (address & 0x0FFF); - return 1; - } - } - } - - hash ^= 0x7FFFF; - target_pte ^= 0x40; - } - - if (DUMP_PAGEFAULTS) - { - mame_printf_debug("PAGE FAULT: address=%08X PC=%08X SDR1=%08X MSR=%08X\n", address, ppc.pc, ppc.sdr1, ppc.msr); - mame_printf_debug("\n"); - - for (i = 0; i < 4; i++) + if (bat[i].u & ((MSR & MSR_PR) ? 0x00000001 : 0x00000002)) { bl = bat[i].u & 0x00001FFC; mask = (~bl << 15) & 0xFFFE0000; - mame_printf_debug(" BAT[%d]=%08X%08X (A & %08X = %08X)\n", i, bat[i].u, bat[i].l, - mask, bat[i].u & 0xFFFE0000); - } - mame_printf_debug("\n"); - mame_printf_debug(" VSID=%06X HASH=%05X HASH\'=%05X\n", vsid, hash, hash ^ 0x7FFFF); + if ((address & mask) == (bat[i].u & 0xFFFE0000)) + { + if (ppc_is_protected(bat[i].l, flags)) + goto exception; + + *addr_ptr = (bat[i].l & 0xFFFE0000) + | (address & ((bl << 15) | 0x0001FFFF)); + return 1; + } + } + } + + /* now try page address translation */ + sr = ppc.sr[(address >> 28) & 0x0F]; + if (sr & 0x80000000) + { + /* direct store translation */ + if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0) + fatalerror("ppc: direct store translation not yet implemented"); + return 0; + } + else + { + /* is no execute is set? */ + if ((flags & PPC_TRANSLATE_CODE) && (sr & 0x10000000)) + goto exception; + + vsid = sr & 0x00FFFFFF; + hash = (vsid & 0x0007FFFF) ^ ((address >> 12) & 0xFFFF); + target_pte = (vsid << 7) | ((address >> 22) & 0x3F) | 0x80000000; + + /* we have to try both types of hashes */ for (hash_type = 0; hash_type <= 1; hash_type++) { + pteg_address = (ppc.sdr1 & 0xFFFF0000) + | (((ppc.sdr1 & 0x01FF) & (hash >> 10)) << 16) + | ((hash & 0x03FF) << 6); + + pteg_ptr[hash_type] = memory_get_read_ptr(cpu_getactivecpu(), ADDRESS_SPACE_PROGRAM, pteg_address); if (pteg_ptr[hash_type]) { for (i = 0; i < 8; i++) { pte = pteg_ptr[hash_type][i]; - mame_printf_debug(" PTE[%i%c]=%08X%08X\n", - i, - hash_type ? '\'' : ' ', - (unsigned) (pte >> 32), - (unsigned) (pte >> 0)); + + /* is valid? */ + if (((pte >> 32) & 0xFFFFFFFF) == target_pte) + { + if (ppc_is_protected((UINT32) pte, flags)) + goto exception; + + *addr_ptr = ((UINT32) (pte & 0xFFFFF000)) + | (address & 0x0FFF); + return 1; + } + } + } + + hash ^= 0x7FFFF; + target_pte ^= 0x40; + } + + if (DUMP_PAGEFAULTS) + { + mame_printf_debug("PAGE FAULT: address=%08X PC=%08X SDR1=%08X MSR=%08X\n", address, ppc.pc, ppc.sdr1, ppc.msr); + mame_printf_debug("\n"); + + for (i = 0; i < 4; i++) + { + bl = bat[i].u & 0x00001FFC; + mask = (~bl << 15) & 0xFFFE0000; + mame_printf_debug(" BAT[%d]=%08X%08X (A & %08X = %08X)\n", i, bat[i].u, bat[i].l, + mask, bat[i].u & 0xFFFE0000); + } + mame_printf_debug("\n"); + mame_printf_debug(" VSID=%06X HASH=%05X HASH\'=%05X\n", vsid, hash, hash ^ 0x7FFFF); + + for (hash_type = 0; hash_type <= 1; hash_type++) + { + if (pteg_ptr[hash_type]) + { + for (i = 0; i < 8; i++) + { + pte = pteg_ptr[hash_type][i]; + mame_printf_debug(" PTE[%i%c]=%08X%08X\n", + i, + hash_type ? '\'' : ' ', + (unsigned) (pte >> 32), + (unsigned) (pte >> 0)); + } } } } } - } - dsisr = DSISR_PAGE; + dsisr = DSISR_PAGE; exception: - /* lookup failure - exception */ - if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0) - { - if (flags & PPC_TRANSLATE_CODE) + /* lookup failure - exception */ + if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0) { - ppc_exception(EXCEPTION_ISI); - } - else - { - ppc.dar = address; - if (flags & PPC_TRANSLATE_WRITE) - ppc.dsisr = dsisr | DSISR_STORE; + if (flags & PPC_TRANSLATE_CODE) + { + ppc_exception(EXCEPTION_ISI); + } else - ppc.dsisr = dsisr; + { + ppc.dar = address; + if (flags & PPC_TRANSLATE_WRITE) + ppc.dsisr = dsisr | DSISR_STORE; + else + ppc.dsisr = dsisr; - ppc_exception(EXCEPTION_DSI); + ppc_exception(EXCEPTION_DSI); + } } + return 0; + } + else + { + /* MMU not enabled in MAME; model3 drivers don't work properly */ + return 1; } - return 0; -#else - /* MMU not enabled in MAME; model3 drivers don't work properly */ - return 1; -#endif } #if (HAS_PPC602||HAS_PPC603)