mirror of
https://github.com/holub/mame
synced 2025-05-21 13:18:56 +03:00
m680x0 update:
- Added working PMMU address translation (not feature complete, but sufficient to boot several 68030 Macs in MESS) - Fixed up disassembly of some PMMU instructions - Added "68020 with 68851" CPU type
This commit is contained in:
parent
acf91ebdf7
commit
17fc4a4a78
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -241,6 +241,7 @@ src/emu/cpu/m68000/m68kcpu.h svneol=native#text/plain
|
||||
src/emu/cpu/m68000/m68kdasm.c svneol=native#text/plain
|
||||
src/emu/cpu/m68000/m68kfpu.c svneol=native#text/plain
|
||||
src/emu/cpu/m68000/m68kmake.c svneol=native#text/plain
|
||||
src/emu/cpu/m68000/m68kmmu.h svneol=native#text/plain
|
||||
src/emu/cpu/m6805/6805dasm.c svneol=native#text/plain
|
||||
src/emu/cpu/m6805/6805ops.c svneol=native#text/plain
|
||||
src/emu/cpu/m6805/m6805.c svneol=native#text/plain
|
||||
|
@ -76,6 +76,7 @@ CPU_GET_INFO( m68008 );
|
||||
CPU_GET_INFO( m68010 );
|
||||
CPU_GET_INFO( m68ec020 );
|
||||
CPU_GET_INFO( m68020 );
|
||||
CPU_GET_INFO( m68020pmmu );
|
||||
CPU_GET_INFO( m68ec030 );
|
||||
CPU_GET_INFO( m68030 );
|
||||
CPU_GET_INFO( m68ec040 );
|
||||
@ -88,6 +89,7 @@ CPU_GET_INFO( scc68070 );
|
||||
#define CPU_M68010 CPU_GET_INFO_NAME( m68010 )
|
||||
#define CPU_M68EC020 CPU_GET_INFO_NAME( m68ec020 )
|
||||
#define CPU_M68020 CPU_GET_INFO_NAME( m68020 )
|
||||
#define CPU_M68020_68851 CPU_GET_INFO_NAME( m68020pmmu )
|
||||
#define CPU_M68EC030 CPU_GET_INFO_NAME( m68ec030 )
|
||||
#define CPU_M68030 CPU_GET_INFO_NAME( m68030 )
|
||||
#define CPU_M68EC040 CPU_GET_INFO_NAME( m68ec040 )
|
||||
|
@ -8014,8 +8014,82 @@ M68KMAKE_OP(pmove, 32, ., .)
|
||||
{
|
||||
modes = m68ki_read_imm_16(m68k);
|
||||
ea = M68KMAKE_GET_EA_AY_32;
|
||||
|
||||
if ((modes & 0xfde0) == 0x2000) // PLOAD
|
||||
{
|
||||
logerror("680x0: unhandled PLOAD\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((modes & 0xe200) == 0x2000) // PFLUSHA
|
||||
{
|
||||
logerror("680x0: unhandled PFLUSHA\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((modes>>13) & 0x7)
|
||||
{
|
||||
case 0: // MC68030/040 form with FD bit
|
||||
case 2: // MC68881 form, FD never set
|
||||
if (modes & 0x200)
|
||||
{
|
||||
logerror("680x0: PMOVE from MMU not supported\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ((modes>>10) & 7)
|
||||
{
|
||||
case 0: // translation control register
|
||||
m68k->mmu_tc = memory_read_word_32be(m68k->program, ea)<<16;
|
||||
m68k->mmu_tc |= memory_read_word_32be(m68k->program, ea+2);
|
||||
|
||||
if (m68k->mmu_tc & 0x80000000)
|
||||
{
|
||||
m68k->pmmu_enabled = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m68k->pmmu_enabled = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // supervisor root pointer
|
||||
m68k->mmu_srp_limit = memory_read_word_32be(m68k->program, ea)<<16;
|
||||
m68k->mmu_srp_limit |= memory_read_word_32be(m68k->program, ea+2);
|
||||
m68k->mmu_srp_aptr = memory_read_word_32be(m68k->program, ea+4)<<16;
|
||||
m68k->mmu_srp_aptr |= memory_read_word_32be(m68k->program, ea+6);
|
||||
break;
|
||||
|
||||
case 3: // CPU root pointer
|
||||
m68k->mmu_crp_limit = memory_read_word_32be(m68k->program, ea)<<16;
|
||||
m68k->mmu_crp_limit |= memory_read_word_32be(m68k->program, ea+2);
|
||||
m68k->mmu_crp_aptr = memory_read_word_32be(m68k->program, ea+4)<<16;
|
||||
m68k->mmu_crp_aptr |= memory_read_word_32be(m68k->program, ea+6);
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("680x0: PMOVE to unknown MMU register %x\n", (modes>>10) & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // MC68030 to/from status reg
|
||||
if (modes & 0x200)
|
||||
{
|
||||
memory_write_word_32be(m68k->program, ea, m68k->mmu_sr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m68k->mmu_sr = memory_read_word_32be(m68k->program, ea);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, m68k->pc);
|
||||
break;
|
||||
}
|
||||
|
||||
logerror("680x0: unhandled PMOVE modes %x ea %x\n", modes, ea);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
#if 0
|
||||
static const char copyright_notice[] =
|
||||
"MUSASHI\n"
|
||||
"Version 4.10 (2009-09-27)\n"
|
||||
"Version 4.5 (2009-10-09)\n"
|
||||
"A portable Motorola M680x0 processor emulation engine.\n"
|
||||
"Copyright Karl Stenerud. All rights reserved.\n"
|
||||
"\n"
|
||||
@ -38,6 +38,8 @@ static const char copyright_notice[] =
|
||||
#include "m68kfpu.c"
|
||||
#include "debugger.h"
|
||||
|
||||
#include "m68kmmu.h"
|
||||
|
||||
extern void m68040_fpu_op0(m68ki_cpu_core *m68k);
|
||||
extern void m68040_fpu_op1(m68ki_cpu_core *m68k);
|
||||
|
||||
@ -611,6 +613,21 @@ static void m68k_postload(running_machine *machine, void *param)
|
||||
m68ki_jump(m68k, REG_PC);
|
||||
}
|
||||
|
||||
/* translate logical to physical addresses */
|
||||
static CPU_TRANSLATE( m68k )
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(device);
|
||||
|
||||
/* only applies to the program address space and only does something if the MMU's enabled */
|
||||
if (m68k)
|
||||
{
|
||||
if ((space == ADDRESS_SPACE_PROGRAM) && (m68k->pmmu_enabled))
|
||||
{
|
||||
*address = pmmu_translate_addr(m68k, *address);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Execute some instructions until we use up cycles clock cycles */
|
||||
static CPU_EXECUTE( m68k )
|
||||
@ -718,6 +735,9 @@ static CPU_RESET( m68k )
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(device);
|
||||
|
||||
/* Disable the PMMU on reset */
|
||||
m68k->pmmu_enabled = 0;
|
||||
|
||||
/* Clear all stop levels and eat up all remaining cycles */
|
||||
m68k->stopped = 0;
|
||||
if (m68k->remaining_cycles > 0)
|
||||
@ -890,6 +910,7 @@ static CPU_GET_INFO( m68k )
|
||||
case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(m68k); break;
|
||||
case CPUINFO_FCT_IMPORT_STATE: info->import_state = CPU_IMPORT_STATE_NAME(m68k); break;
|
||||
case CPUINFO_FCT_EXPORT_STATE: info->export_state = CPU_EXPORT_STATE_NAME(m68k); break;
|
||||
case CPUINFO_FCT_TRANSLATE: info->translate = CPU_TRANSLATE_NAME(m68k); break;
|
||||
|
||||
/* --- the following bits of info are returned as pointers --- */
|
||||
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &m68k->remaining_cycles; break;
|
||||
@ -898,7 +919,7 @@ static CPU_GET_INFO( m68k )
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case DEVINFO_STR_NAME: /* set per-core */ break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "Motorola 68K"); break;
|
||||
case DEVINFO_STR_VERSION: strcpy(info->s, "4.00"); break;
|
||||
case DEVINFO_STR_VERSION: strcpy(info->s, "4.50"); break;
|
||||
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
||||
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Karl Stenerud. All rights reserved. (2.1 fixes HJB)"); break;
|
||||
|
||||
@ -1062,7 +1083,139 @@ static const m68k_memory_interface interface_d32 =
|
||||
writelong_d32
|
||||
};
|
||||
|
||||
/* interface for 32-bit data bus with PMMU (68EC020, 68020) */
|
||||
static UINT8 read_byte_32_mmu(const address_space *space, offs_t address)
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(space->cpu);
|
||||
|
||||
if (m68k->pmmu_enabled)
|
||||
{
|
||||
address = pmmu_translate_addr(m68k, address);
|
||||
}
|
||||
|
||||
return memory_read_byte_32be(space, address);
|
||||
}
|
||||
|
||||
static void write_byte_32_mmu(const address_space *space, offs_t address, UINT8 data)
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(space->cpu);
|
||||
|
||||
if (m68k->pmmu_enabled)
|
||||
{
|
||||
address = pmmu_translate_addr(m68k, address);
|
||||
}
|
||||
|
||||
memory_write_byte_32be(space, address, data);
|
||||
}
|
||||
|
||||
static UINT16 read_immediate_16_mmu(const address_space *space, offs_t address)
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(space->cpu);
|
||||
|
||||
if (m68k->pmmu_enabled)
|
||||
{
|
||||
address = pmmu_translate_addr(m68k, address);
|
||||
}
|
||||
|
||||
return memory_decrypted_read_word(space, (address) ^ m68k->memory.opcode_xor);
|
||||
}
|
||||
|
||||
/* potentially misaligned 16-bit reads with a 32-bit data bus (and 24-bit address bus) */
|
||||
static UINT16 readword_d32_mmu(const address_space *space, offs_t address)
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(space->cpu);
|
||||
UINT16 result;
|
||||
|
||||
if (m68k->pmmu_enabled)
|
||||
{
|
||||
address = pmmu_translate_addr(m68k, address);
|
||||
}
|
||||
|
||||
if (!(address & 1))
|
||||
return memory_read_word_32be(space, address);
|
||||
result = memory_read_byte_32be(space, address) << 8;
|
||||
return result | memory_read_byte_32be(space, address + 1);
|
||||
}
|
||||
|
||||
/* potentially misaligned 16-bit writes with a 32-bit data bus (and 24-bit address bus) */
|
||||
static void writeword_d32_mmu(const address_space *space, offs_t address, UINT16 data)
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(space->cpu);
|
||||
|
||||
if (m68k->pmmu_enabled)
|
||||
{
|
||||
address = pmmu_translate_addr(m68k, address);
|
||||
}
|
||||
|
||||
if (!(address & 1))
|
||||
{
|
||||
memory_write_word_32be(space, address, data);
|
||||
return;
|
||||
}
|
||||
memory_write_byte_32be(space, address, data >> 8);
|
||||
memory_write_byte_32be(space, address + 1, data);
|
||||
}
|
||||
|
||||
/* potentially misaligned 32-bit reads with a 32-bit data bus (and 24-bit address bus) */
|
||||
static UINT32 readlong_d32_mmu(const address_space *space, offs_t address)
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(space->cpu);
|
||||
UINT32 result;
|
||||
|
||||
if (m68k->pmmu_enabled)
|
||||
{
|
||||
address = pmmu_translate_addr(m68k, address);
|
||||
}
|
||||
|
||||
if (!(address & 3))
|
||||
return memory_read_dword_32be(space, address);
|
||||
else if (!(address & 1))
|
||||
{
|
||||
result = memory_read_word_32be(space, address) << 16;
|
||||
return result | memory_read_word_32be(space, address + 2);
|
||||
}
|
||||
result = memory_read_byte_32be(space, address) << 24;
|
||||
result |= memory_read_word_32be(space, address + 1) << 8;
|
||||
return result | memory_read_byte_32be(space, address + 3);
|
||||
}
|
||||
|
||||
/* potentially misaligned 32-bit writes with a 32-bit data bus (and 24-bit address bus) */
|
||||
static void writelong_d32_mmu(const address_space *space, offs_t address, UINT32 data)
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(space->cpu);
|
||||
|
||||
if (m68k->pmmu_enabled)
|
||||
{
|
||||
address = pmmu_translate_addr(m68k, address);
|
||||
}
|
||||
|
||||
if (!(address & 3))
|
||||
{
|
||||
memory_write_dword_32be(space, address, data);
|
||||
return;
|
||||
}
|
||||
else if (!(address & 1))
|
||||
{
|
||||
memory_write_word_32be(space, address, data >> 16);
|
||||
memory_write_word_32be(space, address + 2, data);
|
||||
return;
|
||||
}
|
||||
memory_write_byte_32be(space, address, data >> 24);
|
||||
memory_write_word_32be(space, address + 1, data >> 8);
|
||||
memory_write_byte_32be(space, address + 3, data);
|
||||
}
|
||||
|
||||
static const m68k_memory_interface interface_d32_mmu =
|
||||
{
|
||||
WORD_XOR_BE(0),
|
||||
read_immediate_16_mmu,
|
||||
read_byte_32_mmu,
|
||||
readword_d32_mmu,
|
||||
readlong_d32_mmu,
|
||||
write_byte_32_mmu,
|
||||
writeword_d32_mmu,
|
||||
writelong_d32_mmu
|
||||
};
|
||||
|
||||
|
||||
void m68k_set_reset_callback(const device_config *device, m68k_reset_func callback)
|
||||
@ -1301,6 +1454,30 @@ CPU_GET_INFO( m68020 )
|
||||
}
|
||||
}
|
||||
|
||||
// 68020 with 68851 PMMU
|
||||
static CPU_INIT( m68020pmmu )
|
||||
{
|
||||
m68ki_cpu_core *m68k = get_safe_token(device);
|
||||
|
||||
CPU_INIT_CALL(m68020);
|
||||
|
||||
m68k->has_pmmu = 1;
|
||||
m68k->memory = interface_d32_mmu;
|
||||
}
|
||||
|
||||
CPU_GET_INFO( m68020pmmu )
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m68020pmmu); break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case DEVINFO_STR_NAME: strcpy(info->s, "68020, 68851"); break;
|
||||
|
||||
default: CPU_GET_INFO_CALL(m68020); break;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* M680EC20 section
|
||||
@ -1361,7 +1538,7 @@ static CPU_INIT( m68030 )
|
||||
m68k->cpu_type = CPU_TYPE_030;
|
||||
m68k->state.subtypemask = m68k->cpu_type;
|
||||
m68k->dasm_type = M68K_CPU_TYPE_68030;
|
||||
m68k->memory = interface_d32;
|
||||
m68k->memory = interface_d32_mmu;
|
||||
m68k->sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
m68k->cyc_instruction = m68ki_cycles[3];
|
||||
m68k->cyc_exception = m68ki_exception_cycle_table[3];
|
||||
@ -1480,7 +1657,7 @@ static CPU_INIT( m68040 )
|
||||
m68k->cpu_type = CPU_TYPE_040;
|
||||
m68k->state.subtypemask = m68k->cpu_type;
|
||||
m68k->dasm_type = M68K_CPU_TYPE_68040;
|
||||
m68k->memory = interface_d32;
|
||||
m68k->memory = interface_d32_mmu;
|
||||
m68k->sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
|
||||
m68k->cyc_instruction = m68ki_cycles[4];
|
||||
m68k->cyc_exception = m68ki_exception_cycle_table[4];
|
||||
@ -1568,7 +1745,7 @@ static CPU_INIT( m68ec040 )
|
||||
m68k->cyc_movem_l = 2;
|
||||
m68k->cyc_shift = 0;
|
||||
m68k->cyc_reset = 518;
|
||||
m68k->has_pmmu = 1;
|
||||
m68k->has_pmmu = 0;
|
||||
}
|
||||
|
||||
CPU_GET_INFO( m68ec040 )
|
||||
|
@ -3,7 +3,7 @@
|
||||
/* ======================================================================== */
|
||||
/*
|
||||
* MUSASHI
|
||||
* Version 4.00
|
||||
* Version 4.50
|
||||
*
|
||||
* A portable Motorola M680x0 processor emulation engine.
|
||||
* Copyright Karl Stenerud. All rights reserved.
|
||||
@ -581,6 +581,7 @@ struct _m68ki_cpu_core
|
||||
UINT32 instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */
|
||||
UINT32 run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */
|
||||
int has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */
|
||||
int pmmu_enabled; /* Indicates if the PMMU is enabled */
|
||||
|
||||
/* Clocks required for instructions / exceptions */
|
||||
UINT32 cyc_bcc_notake_b;
|
||||
@ -635,6 +636,12 @@ struct _m68ki_cpu_core
|
||||
UINT16 save_sr;
|
||||
UINT8 save_stopped;
|
||||
UINT8 save_halted;
|
||||
|
||||
/* PMMU registers */
|
||||
UINT32 mmu_crp_aptr, mmu_crp_limit;
|
||||
UINT32 mmu_srp_aptr, mmu_srp_limit;
|
||||
UINT32 mmu_tc;
|
||||
UINT16 mmu_sr;
|
||||
};
|
||||
|
||||
|
||||
|
@ -3027,6 +3027,32 @@ static void d68030_pmove(void)
|
||||
// do this after fetching the second PMOVE word so we properly get the 3rd if necessary
|
||||
str = get_ea_mode_str_32(g_cpu_ir);
|
||||
|
||||
if ((modes & 0xfde0) == 0x2000) // PLOAD
|
||||
{
|
||||
if (modes & 0x0200)
|
||||
{
|
||||
sprintf(g_dasm_str, "pload #%d, %s", (modes>>10)&7, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(g_dasm_str, "pload %s, #%d", str, (modes>>10)&7);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((modes & 0xe200) == 0x2000) // PFLUSHA
|
||||
{
|
||||
if (modes & 0x0200)
|
||||
{
|
||||
sprintf(g_dasm_str, "pflush %s, %s", g_mmuregs[(modes>>10)&7], str);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(g_dasm_str, "pflush %s, %s", str, g_mmuregs[(modes>>10)&7]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((modes>>13) & 0x7)
|
||||
{
|
||||
case 0: // MC68030/040 form with FD bit
|
||||
@ -3803,7 +3829,7 @@ CPU_DISASSEMBLE( m68040 )
|
||||
return m68k_disassemble_raw(buffer, pc, oprom, opram, M68K_CPU_TYPE_68040);
|
||||
}
|
||||
|
||||
|
||||
// f028 2215 0008
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
|
180
src/emu/cpu/m68000/m68kmmu.h
Normal file
180
src/emu/cpu/m68000/m68kmmu.h
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
m68kmmu.h - PMMU implementation for 68851/68030/68040
|
||||
|
||||
By R. Belmont
|
||||
|
||||
Copyright Nicola Salmoria and the MAME Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
*/
|
||||
|
||||
/*
|
||||
pmmu_translate_addr: perform 68851/68030-style PMMU address translation
|
||||
*/
|
||||
INLINE UINT32 pmmu_translate_addr(m68ki_cpu_core *m68k, UINT32 addr_in)
|
||||
{
|
||||
UINT32 addr_out, tbl_entry, tbl_entry2, tamode, tbmode;
|
||||
UINT32 root_aptr, root_limit, tofs, is, abits, bbits, cbits;
|
||||
UINT32 resolved, tptr, shift;
|
||||
|
||||
resolved = 0;
|
||||
addr_out = addr_in;
|
||||
|
||||
// if SRP is enabled and we're in supervisor mode, use it
|
||||
if ((m68k->mmu_tc & 0x02000000) && (m68ki_get_sr(m68k) & 0x2000))
|
||||
{
|
||||
root_aptr = m68k->mmu_srp_aptr;
|
||||
root_limit = m68k->mmu_srp_limit;
|
||||
}
|
||||
else // else use the CRP
|
||||
{
|
||||
root_aptr = m68k->mmu_crp_aptr;
|
||||
root_limit = m68k->mmu_crp_limit;
|
||||
}
|
||||
|
||||
// get initial shift (# of top bits to ignore)
|
||||
is = (m68k->mmu_tc>>16) & 0xf;
|
||||
abits = (m68k->mmu_tc>>12)&0xf;
|
||||
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);
|
||||
|
||||
// get table A offset
|
||||
tofs = (addr_in<<is)>>(32-abits);
|
||||
|
||||
// find out what format table A is
|
||||
switch (root_limit & 3)
|
||||
{
|
||||
case 0: // invalid, should cause MMU exception
|
||||
case 1: // page descriptor, should cause direct mapping
|
||||
fatalerror("680x0 PMMU: Unhandled root mode\n");
|
||||
break;
|
||||
|
||||
case 2: // valid 4 byte descriptors
|
||||
tofs *= 4;
|
||||
// logerror("PMMU: reading table A entry at %08x\n", tofs + (root_aptr & 0xfffffffc));
|
||||
tbl_entry = memory_read_dword_32be(m68k->program, tofs + (root_aptr & 0xfffffffc));
|
||||
tamode = tbl_entry & 3;
|
||||
// logerror("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tamode, tofs);
|
||||
break;
|
||||
|
||||
case 3: // valid 8 byte descriptors
|
||||
tofs *= 8;
|
||||
// logerror("PMMU: reading table A entries at %08x\n", tofs + (root_aptr & 0xfffffffc));
|
||||
tbl_entry2 = memory_read_dword_32be(m68k->program, tofs + (root_aptr & 0xfffffffc));
|
||||
tbl_entry = memory_read_dword_32be(m68k->program, tofs + (root_aptr & 0xfffffffc)+4);
|
||||
tamode = tbl_entry2 & 3;
|
||||
// logerror("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs);
|
||||
break;
|
||||
}
|
||||
|
||||
// get table B offset and pointer
|
||||
tofs = (addr_in<<(is+abits))>>(32-bbits);
|
||||
tptr = tbl_entry & 0xfffffff0;
|
||||
|
||||
// find out what format table B is, if any
|
||||
switch (tamode)
|
||||
{
|
||||
case 0: // invalid, should cause MMU exception
|
||||
fatalerror("680x0 PMMU: Unhandled Table A mode %d (addr_in %08x)\n", tamode, addr_in);
|
||||
break;
|
||||
|
||||
case 2: // 4-byte table B descriptor
|
||||
tofs *= 4;
|
||||
// logerror("PMMU: reading table B entry at %08x\n", tofs + tptr);
|
||||
tbl_entry = memory_read_dword_32be(m68k->program, tofs + tptr);
|
||||
tbmode = tbl_entry & 3;
|
||||
// logerror("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs);
|
||||
break;
|
||||
|
||||
case 3: // 8-byte table B descriptor
|
||||
tofs *= 8;
|
||||
// logerror("PMMU: reading table B entries at %08x\n", tofs + tptr);
|
||||
tbl_entry2 = memory_read_dword_32be(m68k->program, tofs + tptr);
|
||||
tbl_entry = memory_read_dword_32be(m68k->program, tofs + tptr + 4);
|
||||
tbmode = tbl_entry2 & 3;
|
||||
// logerror("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs);
|
||||
break;
|
||||
|
||||
case 1: // early termination descriptor
|
||||
tbl_entry &= 0xffffff00;
|
||||
|
||||
shift = is+abits;
|
||||
addr_out = ((addr_in<<shift)>>shift) + tbl_entry;
|
||||
resolved = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// if table A wasn't early-out, continue to process table B
|
||||
if (!resolved)
|
||||
{
|
||||
switch (tbmode)
|
||||
{
|
||||
case 0: // invalid, should cause MMU exception
|
||||
case 2: // 4-byte table C descriptor
|
||||
case 3: // 8-byte table C descriptor
|
||||
fatalerror("680x0 PMMU: Unhandled Table B mode %d (addr_in %08x)\n", tbmode, addr_in);
|
||||
break;
|
||||
|
||||
case 1: // early termination descriptor
|
||||
tbl_entry &= 0xffffff00;
|
||||
|
||||
shift = is+abits+bbits;
|
||||
addr_out = ((addr_in<<shift)>>shift) + tbl_entry;
|
||||
resolved = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if ((addr_in < 0x40000000) || (addr_in > 0x4fffffff)) printf("PMMU: [%08x] => [%08x]\n", addr_in, addr_out);
|
||||
|
||||
return addr_out;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
maincpu at 40804366: called unimplemented instruction f000 (cpgen)
|
||||
PMMU: tcr 80f05570 limit 7fff0003 aptr 043ffcc0 is 0
|
||||
PMMU: reading table A entries at 043ffce0
|
||||
PMMU: addr 4080438a entry 00000000 entry2 7ffffc18 mode 0 aofs 20
|
||||
680x0 PMMU: Unhandled Table A mode 0
|
||||
|
||||
enable, PS = f
|
||||
|
||||
tblA @ 043ffcc0:
|
||||
|
||||
043ffcc0 0001fc0a 043ffcb0 => 00000019 04000019
|
||||
043ffcc8 7ffffc18 00000000
|
||||
043ffcd0 7ffffc18 00000000
|
||||
043ffcd8 7ffffc18 00000000
|
||||
043ffce0 7ffffc18 00000000
|
||||
043ffce8 7ffffc18 00000000
|
||||
043ffcf0 7ffffc18 00000000
|
||||
043ffcf8 7ffffc18 00000000
|
||||
043ffd00 7ffffc19 40000000
|
||||
043ffd08 7ffffc19 48000000
|
||||
043ffd10 7ffffc59 50000000
|
||||
043ffd18 7ffffc59 58000000
|
||||
043ffd20 7ffffc59 60000000
|
||||
043ffd28 7ffffc59 68000000
|
||||
043ffd30 7ffffc59 70000000
|
||||
043ffd38 7ffffc59 78000000
|
||||
043ffd40 7ffffc59 80000000
|
||||
043ffd48 7ffffc59 88000000
|
||||
043ffd50 7ffffc59 90000000
|
||||
043ffd58 7ffffc59 98000000
|
||||
043ffd60 7ffffc59 a0000000
|
||||
043ffd68 7ffffc59 a8000000
|
||||
043ffd70 7ffffc59 b0000000
|
||||
043ffd78 7ffffc59 b8000000
|
||||
043ffd80 7ffffc59 c0000000
|
||||
043ffd88 7ffffc59 c8000000
|
||||
043ffd90 7ffffc59 d0000000
|
||||
043ffd98 7ffffc59 d8000000
|
||||
043ffda0 7ffffc59 e0000000
|
||||
043ffda8 7ffffc59 e8000000
|
||||
043ffdb0 7ffffc59 f0000000
|
||||
043ffdb8 7ffffc59 f8000000
|
||||
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user