From fe7293d65cbd8ae600711982c2df82dd0b9d7b76 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 10 Sep 2017 18:36:12 +0300 Subject: [PATCH] Disassembler data cache check. --- debug.cpp | 104 +++++++++++++++++++------------- include/debug.h | 5 ++ newcpu.cpp | 156 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 220 insertions(+), 45 deletions(-) diff --git a/debug.cpp b/debug.cpp index 77935025..8ad21de1 100644 --- a/debug.cpp +++ b/debug.cpp @@ -2593,10 +2593,10 @@ static int debug_mem_off (uaecptr *addrp) if (!ba) return offset; if (ba->mask || ba->startmask) { - addr -= ba->start; + uae_u32 start = ba->startmask ? ba->startmask : ba->start; + addr -= start; addr &= ba->mask; - addr += ba->start; - addr |= ba->startmask; + addr += start; } *addrp = addr; return offset; @@ -4138,41 +4138,57 @@ static void show_exec_lists (TCHAR *t) } else if (c == 'e') { // expansion uaecptr expbase = get_base("expansion.library", 378); if (expbase) { - list = get_long_debug(expbase + 60); - while (list && get_long_debug(list)) { - uae_u32 addr = get_long_debug(list + 32); - uae_u16 rom_vector = get_word_debug(list + 16 + 10); - uae_u8 type = get_byte_debug(list + 16 + 0); - console_out_f(_T("%02x %02x %08x %08x %04x %02x %08x %04x (%u/%u)\n"), - type, get_byte_debug(list + 16 + 2), - addr, get_long_debug(list + 36), - get_word_debug(list + 16 + 4), get_byte_debug(list + 16 + 1), - get_long_debug(list + 16 + 6), rom_vector, - get_word_debug(list + 16 + 4), get_byte_debug(list + 16 + 1)); - if ((type & 0x10)) { - uae_u8 diagarea[256]; - uae_u16 nameoffset; - uaecptr rom = addr + rom_vector; - uae_u8 config = get_byte_debug(rom); - copyromdata(config, rom, 0, diagarea, 16); - nameoffset = (diagarea[8] << 8) | diagarea[9]; - console_out_f(_T(" %02x %02x Size %04x Diag %04x Boot %04x Name %04x %04x %04x\n"), - diagarea[0], diagarea[1], - (diagarea[2] << 8) | diagarea[3], - (diagarea[4] << 8) | diagarea[5], - (diagarea[6] << 8) | diagarea[7], - nameoffset, - (diagarea[10] << 8) | diagarea[11], - (diagarea[12] << 8) | diagarea[13]); - if (nameoffset != 0 && nameoffset != 0xffff) { - copyromdata(config, rom, nameoffset, diagarea, 256); - diagarea[sizeof diagarea - 1] = 0; - TCHAR *str = au((char*)diagarea); - console_out_f(_T(" '%s'\n"), str); - xfree(str); + if (t[1] == 'm') { + uaecptr list = get_long_debug(expbase + 74); + while (list && get_long_debug(list)) { + uaecptr name = get_long(list + 10); + uae_s8 pri = get_byte(list + 9); + uae_u16 flags = get_word_debug(list + 14); + uae_u32 dn = get_long_debug(list + 16); + uae_u8 *addr = get_real_address(name); + TCHAR *name1 = addr ? au((char*)addr) : au(""); + my_trim(name1); + console_out_f(_T("%08x %04x %08x %d %s\n"), list, flags, dn, pri, name1); + xfree(name1); + list = get_long_debug(list); + } + } else { + list = get_long_debug(expbase + 60); + while (list && get_long_debug(list)) { + uae_u32 addr = get_long_debug(list + 32); + uae_u16 rom_vector = get_word_debug(list + 16 + 10); + uae_u8 type = get_byte_debug(list + 16 + 0); + console_out_f(_T("%02x %02x %08x %08x %04x %02x %08x %04x (%u/%u)\n"), + type, get_byte_debug(list + 16 + 2), + addr, get_long_debug(list + 36), + get_word_debug(list + 16 + 4), get_byte_debug(list + 16 + 1), + get_long_debug(list + 16 + 6), rom_vector, + get_word_debug(list + 16 + 4), get_byte_debug(list + 16 + 1)); + if ((type & 0x10)) { + uae_u8 diagarea[256]; + uae_u16 nameoffset; + uaecptr rom = addr + rom_vector; + uae_u8 config = get_byte_debug(rom); + copyromdata(config, rom, 0, diagarea, 16); + nameoffset = (diagarea[8] << 8) | diagarea[9]; + console_out_f(_T(" %02x %02x Size %04x Diag %04x Boot %04x Name %04x %04x %04x\n"), + diagarea[0], diagarea[1], + (diagarea[2] << 8) | diagarea[3], + (diagarea[4] << 8) | diagarea[5], + (diagarea[6] << 8) | diagarea[7], + nameoffset, + (diagarea[10] << 8) | diagarea[11], + (diagarea[12] << 8) | diagarea[13]); + if (nameoffset != 0 && nameoffset != 0xffff) { + copyromdata(config, rom, nameoffset, diagarea, 256); + diagarea[sizeof diagarea - 1] = 0; + TCHAR *str = au((char*)diagarea); + console_out_f(_T(" '%s'\n"), str); + xfree(str); + } } + list = get_long_debug(list); } - list = get_long_debug(list); } } return; @@ -4333,17 +4349,21 @@ static int cycle_breakpoint(TCHAR **c) int count = readint(c); if (nc == 's') { if (more_params(c)) { + int mvp = maxvpos + lof_store; int hp = readint(c); - if (count >= vpos) { - count = vpos - count; + int chp = current_hpos(); + if (count == vpos && chp < hp) { + count += mvp - vpos; + } else if (count >= vpos) { + count = count - vpos; } else { - count += maxvpos - vpos; + count += mvp - vpos; } count *= maxhpos; - if (hp >= current_hpos()) { - count += hp - current_hpos(); + if (hp >= chp) { + count += hp - chp; } else { - count += maxhpos - current_hpos(); + count += maxhpos - chp; } } else { count *= maxhpos; diff --git a/include/debug.h b/include/debug.h index 846e512f..ebdff0dc 100644 --- a/include/debug.h +++ b/include/debug.h @@ -168,6 +168,11 @@ uae_u32 get_long_debug (uaecptr addr); uae_u32 get_ilong_debug (uaecptr addr); uae_u32 get_iword_debug (uaecptr addr); +uae_u32 get_byte_cache_debug(uaecptr addr, bool *cached); +uae_u32 get_word_cache_debug(uaecptr addr, bool *cached); +uae_u32 get_long_cache_debug(uaecptr addr, bool *cached); +uae_u32 get_iword_cache_debug(uaecptr addr, bool *cached); +uae_u32 get_ilong_cache_debug(uaecptr addr, bool *cached); enum debugtest_item { DEBUGTEST_BLITTER, DEBUGTEST_KEYBOARD, DEBUGTEST_FLOPPY, DEBUGTEST_MAX }; void debugtest (enum debugtest_item, const TCHAR *, ...); diff --git a/newcpu.cpp b/newcpu.cpp index 7af66c00..74ab9c2f 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -2132,16 +2132,47 @@ static void showea_val(TCHAR *buffer, uae_u16 opcode, uaecptr addr, int size) return; buffer += _tcslen(buffer); if (debug_safe_addr(addr, datasizes[size])) { + bool cached = false; switch (size) { case sz_byte: - _stprintf(buffer, _T(" [%02x]"), get_byte_debug(addr)); + { + uae_u8 v = get_byte_cache_debug(addr, &cached); + uae_u8 v2 = v; + if (cached) + v2 = get_byte_debug(addr); + if (v != v2) { + _stprintf(buffer, _T(" [%02x:%02x]"), v, v2); + } else { + _stprintf(buffer, _T(" [%s%02x]"), cached ? _T("*") : _T(""), v); + } + } break; case sz_word: - _stprintf(buffer, _T(" [%04x]"), get_word_debug(addr)); + { + uae_u16 v = get_word_cache_debug(addr, &cached); + uae_u16 v2 = v; + if (cached) + v2 = get_word_debug(addr); + if (v != v2) { + _stprintf(buffer, _T(" [%04x:%04x]"), v, v2); + } else { + _stprintf(buffer, _T(" [%s%04x]"), cached ? _T("*") : _T(""), v); + } + } break; case sz_long: - _stprintf(buffer, _T(" [%08x]"), get_long_debug(addr)); + { + uae_u32 v = get_long_cache_debug(addr, &cached); + uae_u32 v2 = v; + if (cached) + v2 = get_long_debug(addr); + if (v != v2) { + _stprintf(buffer, _T(" [%08x:%08x]"), v, v2); + } else { + _stprintf(buffer, _T(" [%s%08x]"), cached ? _T("*") : _T(""), v); + } + } break; case sz_single: { @@ -9393,6 +9424,60 @@ static void dcache030_maybe_burst(uaecptr addr, struct cache030 *c, int lws) } } +static uae_u32 read_dcache030_debug(uaecptr addr, uae_u32 size, uae_u32 fc, bool *cached) +{ + static const uae_u32 mask[3] = { 0x000000ff, 0x0000ffff, 0xffffffff }; + struct cache030 *c1, *c2; + int lws1, lws2; + uae_u32 tag1, tag2; + int aligned = addr & 3; + uae_u32 v1, v2; + int width = 8 << size; + int offset = 8 * aligned; + uae_u32 out; + + *cached = false; + if (!currprefs.cpu_data_cache) { + if (size == 0) + return get_byte_debug(addr); + if (size == 1) + return get_word_debug(addr); + return get_long_debug(addr); + } + + c1 = getdcache030(dcaches030, addr, &tag1, &lws1); + addr &= ~3; + if (!c1->valid[lws1] || c1->tag != tag1 || c1->fc != fc) { + v1 = get_long_debug(addr); + } else { + // Cache hit, inhibited caching do not prevent read hits. + v1 = c1->data[lws1]; + *cached = true; + } + + // only one long fetch needed? + if (width + offset <= 32) { + out = v1 >> (32 - (offset + width)); + out &= mask[size]; + return out; + } + + // no, need another one + addr += 4; + c2 = getdcache030(dcaches030, addr, &tag2, &lws2); + if (!c2->valid[lws2] || c2->tag != tag2 || c2->fc != fc) { + v2 = get_long_debug(addr); + } else { + v2 = c2->data[lws2]; + *cached = true; + } + + uae_u64 v64 = ((uae_u64)v1 << 32) | v2; + out = (uae_u32)(v64 >> (64 - (offset + width))); + out &= mask[size]; + return out; +} + uae_u32 read_dcache030 (uaecptr addr, uae_u32 size, uae_u32 fc) { uae_u32 addr_o = addr; @@ -10041,6 +10126,39 @@ static int dcache040_fill_line(int index, uae_u32 tag, uaecptr addr) return line; } +static uae_u32 read_dcache040_debug(uae_u32 addr, int size, bool *cached) +{ + int index; + uae_u32 tag; + struct cache040 *c; + int line; + uae_u32 addr_o = addr; + uae_u8 cs = mmu_cache_state; + + *cached = false; + if (!currprefs.cpu_data_cache) + goto nocache; + if (!(regs.cacr & 0x80000000)) + goto nocache; + + addr &= ~15; + index = (addr >> 4) & cachedsets04060mask; + tag = addr & cachedtag04060mask; + c = &dcaches040[index]; + for (line = 0; line < CACHELINES040; line++) { + if (c->valid[line] && c->tag[line] == tag) { + // cache hit + return dcache040_get_data(addr_o, c, line, size); + } + } +nocache: + if (size == 0) + return get_byte_debug(addr); + if (size == 1) + return get_word_debug(addr); + return get_long_debug(addr); +} + static uae_u32 read_dcache040(uae_u32 addr, int size, uae_u32 (*fetch)(uaecptr)) { int index; @@ -10242,6 +10360,38 @@ uae_u32 next_ilong_cache040(void) return r; } +uae_u32 get_byte_cache_debug(uaecptr addr, bool *cached) +{ + *cached = false; + if (currprefs.cpu_model == 68030) { + return read_dcache030_debug(addr, 0, regs.s ? 5 : 1, cached); + } else if (currprefs.cpu_model >= 68040) { + return read_dcache040_debug(addr, 0, cached); + } + return get_byte_debug(addr); +} +uae_u32 get_word_cache_debug(uaecptr addr, bool *cached) +{ + *cached = false; + if (currprefs.cpu_model == 68030) { + return read_dcache030_debug(addr, 1, regs.s ? 5 : 1, cached); + } else if (currprefs.cpu_model >= 68040) { + return read_dcache040_debug(addr, 1, cached); + } + return get_word_debug(addr); +} + +uae_u32 get_long_cache_debug(uaecptr addr, bool *cached) +{ + *cached = false; + if (currprefs.cpu_model == 68030) { + return read_dcache030_debug(addr, 2, regs.s ? 5 : 1, cached); + } else if (currprefs.cpu_model >= 68040) { + return read_dcache040_debug(addr, 2, cached); + } + return get_long_debug(addr); +} + void check_t0_trace(void) { if (regs.t0 && currprefs.cpu_model >= 68020) { -- 2.47.3