/* Condition */
bool enabled;
uae_u16 status;
+
+ /* Last access cache */
+ uae_u32 mmu030_last_fc;
+ uae_u32 mmu030_last_physical_address;
+ uae_u32 mmu030_last_logical_address;
+
} mmu030;
#endif
}
}
+ mmu030.mmu030_last_fc = 0xffffffff;
}
/* This function flushes ATC entries depending on their logical address
#endif
}
}
+ mmu030.mmu030_last_fc = 0xffffffff;
}
/* This function flushes ATC entries depending on their logical address */
#endif
}
}
+ mmu030.mmu030_last_fc = 0xffffffff;
}
/* This function flushes all ATC entries */
for (i=0; i<ATC030_NUM_ENTRIES; i++) {
mmu030.atc[i].logical.valid = false;
}
+ mmu030.mmu030_last_fc = 0xffffffff;
}
bool mmu030_decode_tc(uae_u32 TC, bool check)
{
+ mmu030.mmu030_last_fc = 0xffffffff;
/* Set MMU condition */
if (TC & TC_ENABLE_TRANSLATION) {
if (!mmu030.enabled && check)
return;
}
- phys_put_long(physical_addr, val);
+ x_phys_put_long(physical_addr, val);
}
void mmu030_put_word_atc(uaecptr addr, uae_u16 val, int l, uae_u32 fc) {
return;
}
- phys_put_word(physical_addr, val);
+ x_phys_put_word(physical_addr, val);
}
void mmu030_put_byte_atc(uaecptr addr, uae_u8 val, int l, uae_u32 fc) {
return;
}
- phys_put_byte(physical_addr, val);
+ x_phys_put_byte(physical_addr, val);
}
uae_u32 mmu030_get_long_atc(uaecptr addr, int l, uae_u32 fc) {
return 0;
}
- return phys_get_long(physical_addr);
+ return x_phys_get_long(physical_addr);
}
-static uae_u32 mmu030_get_ilong_atc(uaecptr addr, int l, uae_u32 fc) {
+static uae_u32 mmu030_get_ilong_atc(uaecptr addr, int l, uae_u32 fc, uae_u32 *phys) {
uae_u32 page_index = addr & mmu030.translation.page.mask;
uae_u32 addr_mask = mmu030.translation.page.imask;
uae_u32 physical_addr = mmu030.atc[l].physical.addr&addr_mask;
+ *phys = physical_addr;
#if MMU030_ATC_DBG_MSG
write_log(_T("ATC match(%i): page addr = %08X, index = %08X (lget %08X)\n"), l,
physical_addr, page_index, phys_get_long(physical_addr + page_index));
return 0;
}
- return phys_get_word(physical_addr);
+ return x_phys_get_word(physical_addr);
}
-static uae_u16 mmu030_get_iword_atc(uaecptr addr, int l, uae_u32 fc) {
+static uae_u16 mmu030_get_iword_atc(uaecptr addr, int l, uae_u32 fc, uae_u32 *phys) {
uae_u32 page_index = addr & mmu030.translation.page.mask;
uae_u32 addr_mask = mmu030.translation.page.imask;
write_log(_T("ATC match(%i): page addr = %08X, index = %08X (wget %04X)\n"), l,
physical_addr, page_index, phys_get_word(physical_addr + page_index));
#endif
+ *phys = physical_addr;
physical_addr += page_index;
if (mmu030.atc[l].physical.bus_error) {
return 0;
}
- return phys_get_byte(physical_addr);
+ return x_phys_get_byte(physical_addr);
}
/* Generic versions of above */
return;
}
if (size == sz_byte)
- phys_put_byte(physical_addr, val);
+ x_phys_put_byte(physical_addr, val);
else if (size == sz_word)
- phys_put_word(physical_addr, val);
+ x_phys_put_word(physical_addr, val);
else
- phys_put_long(physical_addr, val);
+ x_phys_put_long(physical_addr, val);
}
return 0;
}
if (size == sz_byte)
- return phys_get_byte(physical_addr);
+ return x_phys_get_byte(physical_addr);
else if (size == sz_word)
- return phys_get_word(physical_addr);
- return phys_get_long(physical_addr);
+ return x_phys_get_word(physical_addr);
+ return x_phys_get_long(physical_addr);
}
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr,fc,true)) || (fc==7)) {
- phys_put_long(addr,val);
+ x_phys_put_long(addr,val);
return;
}
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr,fc,true)) || (fc==7)) {
- phys_put_word(addr,val);
+ x_phys_put_word(addr,val);
return;
}
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr, fc, true)) || (fc==7)) {
- phys_put_byte(addr,val);
+ x_phys_put_byte(addr,val);
return;
}
uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc) {
+ if (mmu030.mmu030_last_fc == fc && (addr & mmu030.translation.page.imask) == mmu030.mmu030_last_logical_address) {
+ return x_phys_get_ilong(mmu030.mmu030_last_physical_address + (addr & mmu030.translation.page.mask));
+ }
+
+ mmu030.mmu030_last_fc = 0xffffffff;
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr, fc, false)) || (fc == 7)) {
return x_phys_get_ilong(addr);
int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false);
if (atc_line_num >= 0) {
- return mmu030_get_ilong_atc(addr, atc_line_num, fc);
+ uae_u32 v = mmu030_get_ilong_atc(addr, atc_line_num, fc, &mmu030.mmu030_last_physical_address);
+ mmu030.mmu030_last_logical_address = addr & mmu030.translation.page.imask;
+ mmu030.mmu030_last_fc = fc;
+ return v;
}
else {
mmu030_table_search(addr, fc, false, 0);
- return mmu030_get_ilong_atc(addr, mmu030_logical_is_in_atc(addr, fc, false), fc);
+ uae_u32 v = mmu030_get_ilong_atc(addr, mmu030_logical_is_in_atc(addr, fc, false), fc, &mmu030.mmu030_last_physical_address);
+ mmu030.mmu030_last_logical_address = addr & mmu030.translation.page.imask;
+ mmu030.mmu030_last_fc = fc;
+ return v;
}
}
uae_u32 mmu030_get_long(uaecptr addr, uae_u32 fc) {
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr,fc,false)) || (fc==7)) {
- return phys_get_long(addr);
+ return x_phys_get_long(addr);
}
int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false);
uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) {
+ if (mmu030.mmu030_last_fc == fc && (addr & mmu030.translation.page.imask) == mmu030.mmu030_last_logical_address) {
+ return x_phys_get_iword(mmu030.mmu030_last_physical_address + (addr & mmu030.translation.page.mask));
+ }
+
+ mmu030.mmu030_last_fc = 0xffffffff;
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr, fc, false)) || (fc == 7)) {
return x_phys_get_iword(addr);
int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false);
if (atc_line_num >= 0) {
- return mmu030_get_iword_atc(addr, atc_line_num, fc);
+ uae_u16 v = mmu030_get_iword_atc(addr, atc_line_num, fc, &mmu030.mmu030_last_physical_address);
+ mmu030.mmu030_last_logical_address = addr & mmu030.translation.page.imask;
+ mmu030.mmu030_last_fc = fc;
+ return v;
} else {
mmu030_table_search(addr, fc, false, 0);
- return mmu030_get_iword_atc(addr, mmu030_logical_is_in_atc(addr, fc, false), fc);
+ uae_u16 v = mmu030_get_iword_atc(addr, mmu030_logical_is_in_atc(addr, fc, false), fc, &mmu030.mmu030_last_physical_address);
+ mmu030.mmu030_last_logical_address = addr & mmu030.translation.page.imask;
+ mmu030.mmu030_last_fc = fc;
+ return v;
}
}
uae_u16 mmu030_get_word(uaecptr addr, uae_u32 fc) {
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr,fc,false)) || (fc==7)) {
- return phys_get_word(addr);
+ return x_phys_get_word(addr);
}
int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false);
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr,fc,false)) || (fc==7)) {
- return phys_get_byte(addr);
+ return x_phys_get_byte(addr);
}
int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false);
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr, fc, true)) || (fc==7)) {
if (size == sz_byte)
- phys_put_byte(addr, val);
+ x_phys_put_byte(addr, val);
else if (size == sz_word)
- phys_put_word(addr, val);
+ x_phys_put_word(addr, val);
else
- phys_put_long(addr, val);
+ x_phys_put_long(addr, val);
return;
}
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_lrmw_ttr_access(addr,fc)) || (fc==7)) {
if (size == sz_byte)
- return phys_get_byte(addr);
+ return x_phys_get_byte(addr);
else if (size == sz_word)
- return phys_get_word(addr);
- return phys_get_long(addr);
+ return x_phys_get_word(addr);
+ return x_phys_get_long(addr);
}
int atc_line_num = mmu030_logical_is_in_atc(addr, fc, true);
// addr,super,write
if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr,fc,false)) || (fc==7)) {
if (size == sz_byte)
- return phys_get_byte(addr);
+ return x_phys_get_byte(addr);
else if (size == sz_word)
- return phys_get_word(addr);
- return phys_get_long(addr);
+ return x_phys_get_word(addr);
+ return x_phys_get_long(addr);
}
int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false);
{
/* A CPU reset causes the E-bits of TC and TT registers to be zeroed. */
mmu030.enabled = false;
+ mmu030.mmu030_last_fc = 0xffffffff;
regs.mmu_page_size = 0;
if (hardreset >= 0) {
tc_030 &= ~TC_ENABLE_TRANSLATION;
if (currprefs.cpu_memory_cycle_exact || currprefs.cpu_compatible) {
x_phys_get_iword = get_word_icache030;
x_phys_get_ilong = get_long_icache030;
+ x_phys_get_byte = get_dcache_byte;
+ x_phys_get_word = get_dcache_word;
+ x_phys_get_long = get_dcache_long;
+ x_phys_put_byte = put_dcache_byte;
+ x_phys_put_word = put_dcache_word;
+ x_phys_put_long = put_dcache_long;
} else {
x_phys_get_iword = phys_get_word;
x_phys_get_ilong = phys_get_long;
+ x_phys_get_byte = phys_get_byte;
+ x_phys_get_word = phys_get_word;
+ x_phys_get_long = phys_get_long;
+ x_phys_put_byte = phys_put_byte;
+ x_phys_put_word = phys_put_word;
+ x_phys_put_long = phys_put_long;
}
}