Changed how the PowerPC MMU is enabled at compile time, to cut down on the

amount of unused functions in MAME.
This commit is contained in:
Nathan Woods 2008-03-10 13:10:44 +00:00
parent 2a8c73cc45
commit 43c2c2a002
2 changed files with 130 additions and 122 deletions

View File

@ -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); 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) INLINE void ppc_exception(int exception_type)
{ {
longjmp(ppc.exception_jmpbuf, exception_type); longjmp(ppc.exception_jmpbuf, exception_type);
} }
#endif
/***********************************************************************/ /***********************************************************************/

View File

@ -122,6 +122,14 @@ enum
}; };
#ifdef MESS #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) static int ppc_is_protected(UINT32 pp, int flags)
{ {
if (flags & PPC_TRANSLATE_WRITE) if (flags & PPC_TRANSLATE_WRITE)
@ -136,154 +144,156 @@ static int ppc_is_protected(UINT32 pp, int flags)
} }
return FALSE; return FALSE;
} }
#endif
static int ppc_translate_address(offs_t *addr_ptr, int flags) static int ppc_translate_address(offs_t *addr_ptr, int flags)
{ {
#ifdef MESS if (PPC_MMU_ENABLED)
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 (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; if (bat[i].u & ((MSR & MSR_PR) ? 0x00000001 : 0x00000002))
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++)
{ {
bl = bat[i].u & 0x00001FFC; bl = bat[i].u & 0x00001FFC;
mask = (~bl << 15) & 0xFFFE0000; 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++) 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]) if (pteg_ptr[hash_type])
{ {
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
pte = pteg_ptr[hash_type][i]; pte = pteg_ptr[hash_type][i];
mame_printf_debug(" PTE[%i%c]=%08X%08X\n",
i, /* is valid? */
hash_type ? '\'' : ' ', if (((pte >> 32) & 0xFFFFFFFF) == target_pte)
(unsigned) (pte >> 32), {
(unsigned) (pte >> 0)); 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: exception:
/* lookup failure - exception */ /* lookup failure - exception */
if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0) if ((flags & PPC_TRANSLATE_NOEXCEPTION) == 0)
{
if (flags & PPC_TRANSLATE_CODE)
{ {
ppc_exception(EXCEPTION_ISI); if (flags & PPC_TRANSLATE_CODE)
} {
else ppc_exception(EXCEPTION_ISI);
{ }
ppc.dar = address;
if (flags & PPC_TRANSLATE_WRITE)
ppc.dsisr = dsisr | DSISR_STORE;
else 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) #if (HAS_PPC602||HAS_PPC603)