M680x0 updates [Hans Ostermeyer]
- Instruction cache emulated on '020 and later - Fixed interaction between MMU and bfextu/bfexts/bfins - Added fsgldiv, fsglmul, and fscc FPU instructions - Fixed fault address in stack frame - Fixed supervisor violation bit in MMU status register - Add fmovem modes 1 and 3 - Various other MMU fixes
This commit is contained in:
parent
18aca550f0
commit
1fcc151bc9
@ -2634,17 +2634,20 @@ M68KMAKE_OP(bfexts, 32, ., .)
|
||||
if(BIT_5(word2))
|
||||
width = REG_D[width&7];
|
||||
|
||||
/* Offset is signed so we have to use ugly math =( */
|
||||
ea += offset / 8;
|
||||
offset %= 8;
|
||||
if(offset < 0)
|
||||
if(BIT_B(word2))
|
||||
{
|
||||
offset += 8;
|
||||
ea--;
|
||||
/* Offset is signed so we have to use ugly math =( */
|
||||
ea += offset / 8;
|
||||
offset %= 8;
|
||||
if(offset < 0)
|
||||
{
|
||||
offset += 8;
|
||||
ea--;
|
||||
}
|
||||
}
|
||||
width = ((width-1) & 31) + 1;
|
||||
|
||||
data = m68ki_read_32(m68k, ea);
|
||||
data = (offset+width) < 16 ? (m68ki_read_16(m68k, ea) << 16) : m68ki_read_32(m68k, ea);
|
||||
|
||||
data = MASK_OUT_ABOVE_32(data<<offset);
|
||||
|
||||
@ -2716,17 +2719,20 @@ M68KMAKE_OP(bfextu, 32, ., .)
|
||||
if(BIT_5(word2))
|
||||
width = REG_D[width&7];
|
||||
|
||||
/* Offset is signed so we have to use ugly math =( */
|
||||
ea += offset / 8;
|
||||
offset %= 8;
|
||||
if(offset < 0)
|
||||
if(BIT_B(word2))
|
||||
{
|
||||
offset += 8;
|
||||
ea--;
|
||||
/* Offset is signed so we have to use ugly math =( */
|
||||
ea += offset / 8;
|
||||
offset %= 8;
|
||||
if(offset < 0)
|
||||
{
|
||||
offset += 8;
|
||||
ea--;
|
||||
}
|
||||
}
|
||||
width = ((width-1) & 31) + 1;
|
||||
|
||||
data = m68ki_read_32(m68k, ea);
|
||||
data = (offset+width) < 16 ? (m68ki_read_16(m68k, ea) << 16) : m68ki_read_32(m68k, ea);
|
||||
data = MASK_OUT_ABOVE_32(data<<offset);
|
||||
|
||||
if((offset+width) > 32)
|
||||
@ -2813,7 +2819,7 @@ M68KMAKE_OP(bfffo, 32, ., .)
|
||||
}
|
||||
width = ((width-1) & 31) + 1;
|
||||
|
||||
data = m68ki_read_32(m68k, ea);
|
||||
data = (offset+width) < 16 ? (m68ki_read_16(m68k, ea) << 16) : m68ki_read_32(m68k, ea);
|
||||
data = MASK_OUT_ABOVE_32(data<<local_offset);
|
||||
|
||||
if((local_offset+width) > 32)
|
||||
@ -2902,13 +2908,16 @@ M68KMAKE_OP(bfins, 32, ., .)
|
||||
if(BIT_5(word2))
|
||||
width = REG_D[width&7];
|
||||
|
||||
/* Offset is signed so we have to use ugly math =( */
|
||||
ea += offset / 8;
|
||||
offset %= 8;
|
||||
if(offset < 0)
|
||||
if(BIT_B(word2))
|
||||
{
|
||||
offset += 8;
|
||||
ea--;
|
||||
/* Offset is signed so we have to use ugly math =( */
|
||||
ea += offset / 8;
|
||||
offset %= 8;
|
||||
if(offset < 0)
|
||||
{
|
||||
offset += 8;
|
||||
ea--;
|
||||
}
|
||||
}
|
||||
width = ((width-1) & 31) + 1;
|
||||
|
||||
@ -2920,11 +2929,18 @@ M68KMAKE_OP(bfins, 32, ., .)
|
||||
m68k->not_z_flag = insert_base;
|
||||
insert_long = insert_base >> offset;
|
||||
|
||||
data_long = m68ki_read_32(m68k, ea);
|
||||
data_long = (offset+width) < 16 ? (m68ki_read_16(m68k, ea) << 16) : m68ki_read_32(m68k, ea);
|
||||
m68k->v_flag = VFLAG_CLEAR;
|
||||
m68k->c_flag = CFLAG_CLEAR;
|
||||
|
||||
m68ki_write_32(m68k, ea, (data_long & ~mask_long) | insert_long);
|
||||
if((width + offset) < 16)
|
||||
{
|
||||
m68ki_write_16(m68k, ea, ((data_long & ~mask_long) | insert_long) >> 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
m68ki_write_32(m68k, ea, (data_long & ~mask_long) | insert_long);
|
||||
}
|
||||
|
||||
if((width + offset) > 32)
|
||||
{
|
||||
@ -6684,6 +6700,12 @@ M68KMAKE_OP(movec, 32, rc, .)
|
||||
{
|
||||
m68k->cacr = REG_DA[(word2 >> 12) & 15] & 0x0f;
|
||||
}
|
||||
|
||||
// logerror("movec to cacr=%04x\n", m68k->cacr);
|
||||
if (m68k->cacr & (M68K_CACR_CI | M68K_CACR_CEI))
|
||||
{
|
||||
m68ki_ic_clear(m68k);
|
||||
}
|
||||
return;
|
||||
}
|
||||
m68ki_exception_illegal(m68k);
|
||||
|
@ -632,9 +632,9 @@ static CPU_EXECUTE( m68k )
|
||||
/* Call external hook to peek at CPU */
|
||||
debugger_instruction_hook(device, REG_PC);
|
||||
|
||||
// FIXME: remove this
|
||||
// void apollo_debug_instruction(device_t *device);
|
||||
// apollo_debug_instruction(device);
|
||||
/* call external instruction hook (independent of debug mode) */
|
||||
if (m68k->instruction_hook != NULL)
|
||||
m68k->instruction_hook(device, REG_PC);
|
||||
|
||||
/* Record previous program counter */
|
||||
REG_PPC = REG_PC;
|
||||
@ -672,13 +672,6 @@ static CPU_EXECUTE( m68k )
|
||||
{
|
||||
UINT32 sr;
|
||||
|
||||
// const char * disassemble(m68ki_cpu_core *m68k, offs_t pc);
|
||||
// logerror(
|
||||
// "PMMU: pc=%08x sp=%08x va=%08x bus error: %s\n",
|
||||
// REG_PPC, REG_A[7], m68k->mmu_tmp_buserror_address,
|
||||
// (m68k->mmu_tmp_buserror_address == REG_PPC) ? "-"
|
||||
// : disassemble(m68k, REG_PPC));
|
||||
|
||||
m68k->mmu_tmp_buserror_occurred = 0;
|
||||
|
||||
// restore cpu address registers to value at start of instruction
|
||||
@ -821,6 +814,15 @@ static CPU_RESET( m68k )
|
||||
|
||||
/* flush the MMU's cache */
|
||||
pmmu_atc_flush(m68k);
|
||||
|
||||
if(CPU_TYPE_IS_EC020_PLUS(m68k->cpu_type))
|
||||
{
|
||||
// clear instruction cache
|
||||
m68ki_ic_clear(m68k);
|
||||
}
|
||||
|
||||
// disable instruction hook
|
||||
m68k->instruction_hook = NULL;
|
||||
}
|
||||
|
||||
static CPU_DISASSEMBLE( m68k )
|
||||
|
@ -103,6 +103,15 @@ typedef struct _m68ki_cpu_core m68ki_cpu_core;
|
||||
/* MMU constants */
|
||||
#define MMU_ATC_ENTRIES (22) // 68851 has 64, 030 has 22
|
||||
|
||||
/* instruction cache constants */
|
||||
#define M68K_IC_SIZE 128
|
||||
|
||||
#define M68K_CACR_IBE 0x10 // Instruction Burst Enable
|
||||
#define M68K_CACR_CI 0x08 // Clear Instruction Cache
|
||||
#define M68K_CACR_CEI 0x04 // Clear Entry in Instruction Cache
|
||||
#define M68K_CACR_FI 0x02 // Freeze Instruction Cache
|
||||
#define M68K_CACR_EI 0x01 // Enable Instruction Cache
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================ MACROS ================================ */
|
||||
/* ======================================================================== */
|
||||
@ -706,6 +715,13 @@ struct _m68ki_cpu_core
|
||||
UINT16 mmu_tmp_rw; /* temporary hack: read/write (1/0) for the mmu */
|
||||
UINT32 mmu_tmp_buserror_address; /* temporary hack: (first) bus error address */
|
||||
UINT16 mmu_tmp_buserror_occurred; /* temporary hack: flag that bus error has occurred from mmu */
|
||||
|
||||
UINT32 ic_address[M68K_IC_SIZE]; /* instruction cache address data */
|
||||
UINT16 ic_data[M68K_IC_SIZE]; /* instruction cache content data */
|
||||
|
||||
/* external instruction hook (does not depend on debug mode) */
|
||||
typedef int (*instruction_hook_t)(device_t *device, offs_t curpc);
|
||||
instruction_hook_t instruction_hook;
|
||||
};
|
||||
|
||||
|
||||
@ -882,6 +898,43 @@ INLINE void m68kx_write_memory_32_pd(m68ki_cpu_core *m68k, unsigned int address,
|
||||
|
||||
/* ---------------------------- Read Immediate ---------------------------- */
|
||||
|
||||
// clear the instruction cache
|
||||
INLINE void m68ki_ic_clear(m68ki_cpu_core *m68k)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i< M68K_IC_SIZE; i++) {
|
||||
m68k->ic_address[i] = ~0;
|
||||
}
|
||||
}
|
||||
|
||||
// read immediate word using the instruction cache
|
||||
|
||||
INLINE UINT32 m68ki_ic_readimm16(m68ki_cpu_core *m68k, UINT32 address)
|
||||
{
|
||||
if(CPU_TYPE_IS_EC020_PLUS(m68k->cpu_type) && (m68k->cacr & M68K_CACR_EI))
|
||||
{
|
||||
UINT32 ic_offset = (address >> 1) % M68K_IC_SIZE;
|
||||
if (m68k->ic_address[ic_offset] == address)
|
||||
{
|
||||
return m68k->ic_data[ic_offset];
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 data = m68k->memory.readimm16(address);
|
||||
if (!m68k->mmu_tmp_buserror_occurred)
|
||||
{
|
||||
m68k->ic_data[ic_offset] = data;
|
||||
m68k->ic_address[ic_offset] = address;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return m68k->memory.readimm16(address);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handles all immediate reads, does address error check, function code setting,
|
||||
* and prefetching if they are enabled in m68kconf.h
|
||||
*/
|
||||
@ -896,14 +949,14 @@ INLINE UINT32 m68ki_read_imm_16(m68ki_cpu_core *m68k)
|
||||
|
||||
if(REG_PC != m68k->pref_addr)
|
||||
{
|
||||
m68k->pref_data = m68k->memory.readimm16(REG_PC);
|
||||
m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC);
|
||||
m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC;
|
||||
}
|
||||
result = MASK_OUT_ABOVE_16(m68k->pref_data);
|
||||
REG_PC += 2;
|
||||
if (!m68k->mmu_tmp_buserror_occurred) {
|
||||
// prefetch only if no bus error occurred in opcode fetch
|
||||
m68k->pref_data = m68k->memory.readimm16(REG_PC);
|
||||
m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC);
|
||||
m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC;
|
||||
// ignore bus error on prefetch
|
||||
m68k->mmu_tmp_buserror_occurred = 0;
|
||||
@ -924,16 +977,16 @@ INLINE UINT32 m68ki_read_imm_32(m68ki_cpu_core *m68k)
|
||||
if(REG_PC != m68k->pref_addr)
|
||||
{
|
||||
m68k->pref_addr = REG_PC;
|
||||
m68k->pref_data = m68k->memory.readimm16(m68k->pref_addr);
|
||||
m68k->pref_data = m68ki_ic_readimm16(m68k, m68k->pref_addr);
|
||||
}
|
||||
temp_val = MASK_OUT_ABOVE_16(m68k->pref_data);
|
||||
REG_PC += 2;
|
||||
m68k->pref_addr = REG_PC;
|
||||
m68k->pref_data = m68k->memory.readimm16(m68k->pref_addr);
|
||||
m68k->pref_data = m68ki_ic_readimm16(m68k, m68k->pref_addr);
|
||||
|
||||
temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | MASK_OUT_ABOVE_16(m68k->pref_data));
|
||||
REG_PC += 2;
|
||||
m68k->pref_data = m68k->memory.readimm16(REG_PC);
|
||||
m68k->pref_data = m68ki_ic_readimm16(m68k, REG_PC);
|
||||
m68k->pref_addr = m68k->mmu_tmp_buserror_occurred ? ~0 : REG_PC;
|
||||
|
||||
return temp_val;
|
||||
@ -1543,7 +1596,9 @@ void m68ki_stack_frame_1010(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT
|
||||
m68ki_push_16(m68k, 0);
|
||||
|
||||
/* SPECIAL STATUS REGISTER */
|
||||
m68ki_push_16(m68k, 0);
|
||||
// set bit for: Rerun Faulted bus Cycle, or run pending prefetch
|
||||
// set FC
|
||||
m68ki_push_16(m68k, 0x0100 | m68k->mmu_tmp_fc );
|
||||
|
||||
/* INTERNAL REGISTER */
|
||||
m68ki_push_16(m68k, 0);
|
||||
@ -1590,7 +1645,7 @@ void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT
|
||||
m68ki_push_32(m68k, 0);
|
||||
|
||||
/* STAGE B ADDRESS (2 words) */
|
||||
m68ki_push_32(m68k, fault_address);
|
||||
m68ki_push_32(m68k, 0);
|
||||
|
||||
/* INTERNAL REGISTER (4 words) */
|
||||
m68ki_push_32(m68k, 0);
|
||||
@ -1606,7 +1661,7 @@ void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT
|
||||
m68ki_push_16(m68k, 0);
|
||||
|
||||
/* DATA CYCLE FAULT ADDRESS (2 words) */
|
||||
m68ki_push_32(m68k, 0);
|
||||
m68ki_push_32(m68k, fault_address);
|
||||
|
||||
/* INSTRUCTION PIPE STAGE B */
|
||||
m68ki_push_16(m68k, 0);
|
||||
@ -1615,7 +1670,7 @@ void m68ki_stack_frame_1011(m68ki_cpu_core *m68k, UINT32 sr, UINT32 vector, UINT
|
||||
m68ki_push_16(m68k, 0);
|
||||
|
||||
/* SPECIAL STATUS REGISTER */
|
||||
m68ki_push_16(m68k, 0);
|
||||
m68ki_push_16(m68k, 0x0100 | m68k->mmu_tmp_fc);
|
||||
|
||||
/* INTERNAL REGISTER */
|
||||
m68ki_push_16(m68k, 0);
|
||||
|
@ -1318,6 +1318,11 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2)
|
||||
m68k->remaining_cycles -= 109;
|
||||
break;
|
||||
}
|
||||
// case 0x0e: // FSIN
|
||||
// {
|
||||
// // TODO
|
||||
// break;
|
||||
// }
|
||||
case 0x18: // FABS
|
||||
{
|
||||
REG_FP[dst] = source;
|
||||
@ -1365,6 +1370,12 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2)
|
||||
m68k->remaining_cycles -= 11;
|
||||
break;
|
||||
}
|
||||
case 0x24: // FSGLDIV
|
||||
{
|
||||
REG_FP[dst] = floatx80_div(REG_FP[dst], source);
|
||||
m68k->remaining_cycles -= 43; // // ? (value is from FDIV)
|
||||
break;
|
||||
}
|
||||
case 0x25: // FREM
|
||||
{
|
||||
REG_FP[dst] = floatx80_rem(REG_FP[dst], source);
|
||||
@ -1372,6 +1383,13 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2)
|
||||
m68k->remaining_cycles -= 43; // guess
|
||||
break;
|
||||
}
|
||||
case 0x27: // FSGLMUL
|
||||
{
|
||||
REG_FP[dst] = floatx80_mul(REG_FP[dst], source);
|
||||
SET_CONDITION_CODES(m68k, REG_FP[dst]);
|
||||
m68k->remaining_cycles -= 11; // ? (value is from FMUL)
|
||||
break;
|
||||
}
|
||||
case 0x28: // FSUB
|
||||
{
|
||||
REG_FP[dst] = floatx80_sub(REG_FP[dst], source);
|
||||
@ -1396,7 +1414,7 @@ static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2)
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
|
||||
default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PPC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1507,6 +1525,10 @@ static void fmovem(m68ki_cpu_core *m68k, UINT16 w2)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 1: // Dynamic register list, postincrement or control addressing mode.
|
||||
// FIXME: not really tested, but seems to work
|
||||
reglist = REG_D[(reglist >> 4) & 7];
|
||||
|
||||
case 0: // Static register list, predecrement or control addressing mode
|
||||
{
|
||||
for (i=0; i < 8; i++)
|
||||
@ -1531,13 +1553,41 @@ static void fmovem(m68ki_cpu_core *m68k, UINT16 w2)
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
|
||||
case 2: // Static register list, postdecrement or control addressing mode
|
||||
{
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
if (reglist & (1 << i))
|
||||
{
|
||||
switch (ea >> 3)
|
||||
{
|
||||
case 5: // (d16, An)
|
||||
case 6: // (An) + (Xn) + d8
|
||||
store_extended_float80(m68k, mem_addr, REG_FP[7-i]);
|
||||
mem_addr += 12;
|
||||
break;
|
||||
default:
|
||||
WRITE_EA_FPE(m68k, ea, REG_FP[7-i]);
|
||||
break;
|
||||
}
|
||||
|
||||
m68k->remaining_cycles -= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
|
||||
}
|
||||
}
|
||||
else // From mem to FP regs
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 3: // Dynamic register list, predecrement addressing mode.
|
||||
// FIXME: not really tested, but seems to work
|
||||
reglist = REG_D[(reglist >> 4) & 7];
|
||||
|
||||
case 2: // Static register list, postincrement or control addressing mode
|
||||
{
|
||||
for (i=0; i < 8; i++)
|
||||
@ -1561,11 +1611,20 @@ static void fmovem(m68ki_cpu_core *m68k, UINT16 w2)
|
||||
break;
|
||||
}
|
||||
|
||||
default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
|
||||
default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fscc(m68ki_cpu_core *m68k)
|
||||
{
|
||||
int ea = m68k->ir & 0x3f;
|
||||
int condition = (INT16)(OPER_I_16(m68k));
|
||||
|
||||
WRITE_EA_8(m68k, ea, TEST_CONDITION(m68k, condition) ? 0xff : 0);
|
||||
m68k->remaining_cycles -= 7; // ???
|
||||
}
|
||||
|
||||
static void fbcc16(m68ki_cpu_core *m68k)
|
||||
{
|
||||
INT32 offset;
|
||||
@ -1646,15 +1705,15 @@ void m68040_fpu_op0(m68ki_cpu_core *m68k)
|
||||
|
||||
case 1: // FBcc disp16
|
||||
{
|
||||
switch ((m68k->ir >> 3) & 0x3) {
|
||||
switch ((m68k->ir >> 3) & 0x7) {
|
||||
case 1: // FDBcc
|
||||
// TODO:
|
||||
break;
|
||||
default: // FScc (?)
|
||||
// TODO:
|
||||
break;
|
||||
fscc(m68k);
|
||||
return;
|
||||
}
|
||||
fatalerror("M68kFPU: unimplemented main op %d with mode %d\n", (m68k->ir >> 6) & 0x3, (m68k->ir >> 3) & 0x7);
|
||||
fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (m68k->ir >> 6) & 0x3, (m68k->ir >> 3) & 0x7, REG_PPC);
|
||||
}
|
||||
|
||||
case 2: // FBcc disp16
|
||||
|
@ -199,13 +199,13 @@ INLINE UINT32 get_dt2_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest
|
||||
return tbl_entry;
|
||||
}
|
||||
|
||||
INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest)
|
||||
INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 fc, UINT8 ptest)
|
||||
{
|
||||
UINT32 tbl_entry2 = m68k->program->read_dword(tptr);
|
||||
UINT32 tbl_entry = m68k->program->read_dword(tptr + 4);
|
||||
UINT32 dt = tbl_entry2 & M68K_MMU_DF_DT;
|
||||
|
||||
m68k->mmu_tmp_sr |= tbl_entry2 & 0x0100 ? M68K_MMU_SR_SUPERVISOR_ONLY : 0;
|
||||
m68k->mmu_tmp_sr |= ((tbl_entry2 & 0x0100) && !(fc & 4)) ? M68K_MMU_SR_SUPERVISOR_ONLY : 0;
|
||||
m68k->mmu_tmp_sr |= tbl_entry2 & 0x0004 ? M68K_MMU_SR_WRITE_PROTECT : 0;
|
||||
|
||||
if (!ptest)
|
||||
@ -272,27 +272,35 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest
|
||||
// first see if this is already in the ATC
|
||||
for (i = 0; i < MMU_ATC_ENTRIES; i++)
|
||||
{
|
||||
// if tag bits and function code match, we've got it
|
||||
if (m68k->mmu_atc_tag[i] == atc_tag)
|
||||
if (m68k->mmu_atc_tag[i] != atc_tag)
|
||||
{
|
||||
if (m68k->mmu_tmp_rw || !(m68k->mmu_atc_data[i] & M68K_MMU_ATC_WRITE_PR))
|
||||
{
|
||||
// read access or write access and not write protected
|
||||
if (!m68k->mmu_tmp_rw && !ptest)
|
||||
{
|
||||
// FIXME: must set modified in PMMU tables as well
|
||||
m68k->mmu_atc_data[i] |= M68K_MMU_ATC_MODIFIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: supervisor mode?
|
||||
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, fc);
|
||||
// pmmu_atc_count++;
|
||||
return addr_out;
|
||||
}
|
||||
// tag bits and function code don't match
|
||||
}
|
||||
else if (!m68k->mmu_tmp_rw && (m68k->mmu_atc_data[i] & M68K_MMU_ATC_WRITE_PR))
|
||||
{
|
||||
// write mode, but write protected
|
||||
}
|
||||
else if (!m68k->mmu_tmp_rw && !(m68k->mmu_atc_data[i] & M68K_MMU_ATC_MODIFIED))
|
||||
{
|
||||
// first write; must set modified in PMMU tables as well
|
||||
}
|
||||
else
|
||||
{
|
||||
// read access or write access and not write protected
|
||||
if (!m68k->mmu_tmp_rw && !ptest)
|
||||
{
|
||||
// FIXME: must set modified in PMMU tables as well
|
||||
m68k->mmu_atc_data[i] |= M68K_MMU_ATC_MODIFIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: supervisor mode?
|
||||
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, fc);
|
||||
// pmmu_atc_count++;
|
||||
return addr_out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,7 +352,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest
|
||||
case M68K_MMU_DF_DT3: // valid 8 byte descriptors
|
||||
tofs *= 8;
|
||||
// if (verbose) logerror("PMMU: reading table A entries at %08x\n", tofs + tptr);
|
||||
tbl_entry = get_dt3_table_entry(m68k, tofs + tptr, ptest);
|
||||
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);
|
||||
break;
|
||||
@ -377,7 +385,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest
|
||||
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);
|
||||
tbl_entry = get_dt3_table_entry(m68k, tptr + tofs, ptest);
|
||||
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);
|
||||
@ -421,7 +429,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest
|
||||
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);
|
||||
tbl_entry = get_dt3_table_entry(m68k, tptr+ tofs, ptest);
|
||||
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);
|
||||
break;
|
||||
@ -470,7 +478,7 @@ INLINE UINT32 get_dt3_table_entry(m68ki_cpu_core *m68k, UINT32 tptr, UINT8 ptest
|
||||
m68k->mmu_tmp_buserror_address = addr_in;
|
||||
}
|
||||
}
|
||||
else if ((m68k->mmu_tmp_sr & M68K_MMU_SR_SUPERVISOR_ONLY) && !(fc & 4))
|
||||
else if (m68k->mmu_tmp_sr & M68K_MMU_SR_SUPERVISOR_ONLY)
|
||||
{
|
||||
if (++m68k->mmu_tmp_buserror_occurred == 1)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user