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;
} 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("<null>");
+ 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;
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;
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 *, ...);
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:
{
}
}
+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;
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;
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) {