diff options
author | 2016-06-27 15:20:38 +0200 | |
---|---|---|
committer | 2016-06-27 15:20:38 +0200 | |
commit | 047d5055926d57a905a9ff2c8c2fb264839d5da6 (patch) | |
tree | b51a135ce5634ae515827140eb7da58db9ac1e81 /src/devices/cpu/sparc | |
parent | 2d5e2fe9d1ee4636471a1b1198c4b5020ac82131 (diff) |
Fix spurious double-load in SPARC core
Diffstat (limited to 'src/devices/cpu/sparc')
-rw-r--r-- | src/devices/cpu/sparc/mb86901.cpp | 259 |
1 files changed, 258 insertions, 1 deletions
diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp index ee672632108..0a1bf03938b 100644 --- a/src/devices/cpu/sparc/mb86901.cpp +++ b/src/devices/cpu/sparc/mb86901.cpp @@ -1983,7 +1983,7 @@ void mb86901_device::execute_load(UINT32 op) else if (LDDC) { } // implementation-dependent actions } - if (!m_trap) + if (!m_trap && (LDD || LDDA || LDDF || LDDC)) { UINT32 word1 = read_sized_word(addr_space, address + 4, 4); if (MAE) @@ -2812,6 +2812,263 @@ void mb86901_device::execute_step() UINT32 addr_space = (IS_USER ? 8 : 9); UINT32 op = read_sized_word(addr_space, PC, 4); +#if 0 + if (PC == 0xffef0000) + { + UINT32 opcode = read_sized_word(11, REG(5), 2); + if (!(REG(5) & 2)) + { + opcode >>= 16; + } + UINT32 l1 = opcode << 2; + l1 += REG(2); + UINT32 handler_offset = read_sized_word(11, l1, 2); + if (!(l1 & 2)) + { + handler_offset >>= 16; + } + handler_offset <<= 2; + handler_offset += REG(2); + if (handler_offset == 0xffe87964) + { + printf("Opcode at %08x: %04x, handler is at %08x // call %08x\n", REG(5), opcode, handler_offset, l1 + 2); + } + else if (handler_offset == 0xffe8799c) + { + UINT32 address = REG(5) + 2; + UINT32 half = read_sized_word(11, address, 2); + if (!(address & 2)) half >>= 16; + + printf("Opcode at %08x: %04x, handler is at %08x // push_data current result (%08x) + load address %08x\n", REG(5), opcode, handler_offset, REG(4), REG(3) + half); + } + else if (handler_offset == 0xffe879e4) + { + UINT32 address = l1 + 2; + UINT32 half0 = read_sized_word(11, address, 2); + if (address & 2) half0 <<= 16; + + address = l1 + 4; + UINT32 half1 = read_sized_word(11, address, 2); + if (!(address & 2)) half1 >>= 16; + + UINT32 value = half0 | half1; + + printf("Opcode at %08x: %04x, handler is at %08x // push_data current result (%08x) + load immediate word from handler table (%08x)\n", REG(5), opcode, handler_offset, REG(4), value); + } + else if (handler_offset == 0xffe879c4) + { + UINT32 address = l1 + 2; + UINT32 l0 = read_sized_word(11, address, 2); + if (!(address & 2)) l0 >>= 16; + + address = REG(3) + l0; + UINT32 l1_2 = read_sized_word(11, address, 2); + if (!(address & 2)) l1_2 >>= 16; + + address = REG(2) + (l1_2 << 2); + UINT32 l0_2 = read_sized_word(11, address, 2); + if (!(address & 2)) l0_2 >>= 16; + + UINT32 dest = REG(2) + (l0_2 << 2); + + printf("Opcode at %08x: %04x, handler is at %08x // SPARC branch to %08x, calcs: g2(%08x) + halfword[g2(%04x) + (halfword[g3(%08x) + halfword[entry_point(%04x) + 2](%04x)](%04x) << 2)](%08x)\n", REG(5), opcode, handler_offset, dest, REG(2), REG(2), REG(3), l1, l0, l1_2, l0_2); + printf(" // Target func: %08x\n", l0_2 << 2); + switch (l0_2 << 2) + { + case 0x10: // call + printf(" // call %08x\n", (REG(2) + (l1_2 << 2)) + 2); + break; + default: + printf(" // unknown handler address: %08x\n", REG(2) + (l0_2 << 2)); + break; + } + } + else if (handler_offset == 0xffe8c838) + { + UINT32 address = l1 + 2; + UINT32 half0 = read_sized_word(11, address, 2); + if (address & 2) half0 <<= 16; + + address = l1 + 4; + UINT32 half1 = read_sized_word(11, address, 2); + if (!(address & 2)) half1 >>= 16; + + UINT32 value = half0 | half1; + + printf("Opcode at %08x: %04x, handler is at %08x // add 32-bit word (%08x) from handler table to result (%08x + %08x = %08x)\n", REG(5), opcode, handler_offset, value, REG(4), value, REG(4) + value); + } + else if (opcode == 0x003f || opcode == 0x0066 || opcode == 0x0099 || opcode == 0x0121 || opcode == 0x0136 || opcode == 0x014f || opcode == 0x0155 || opcode == 0x01c7 || opcode == 0x01cd || + opcode == 0x0217 || opcode == 0x0289 || opcode == 0x0296 || opcode == 0x029d || opcode == 0x02f2 || opcode == 0x0334 || opcode == 0x0381 || opcode == 0x3d38) + { + switch(opcode) + { + case 0x003f: + { + UINT32 address = REG(5) + 2; + UINT32 half0 = read_sized_word(11, address, 2); + if (address & 2) half0 <<= 16; + + address = REG(5) + 4; + UINT32 half1 = read_sized_word(11, address, 2); + if (!(address & 2)) half1 >>= 16; + + UINT32 value = half0 | half1; + + printf("Opcode at %08x: %04x, handler is at %08x // push_data current result (%08x) + load immediate word from instructions (%08x)\n", REG(5), opcode, handler_offset, REG(4), value); + break; + } + + case 0x0066: + { + UINT32 address = REG(5) + 2; + UINT32 offset = read_sized_word(11, address, 2); + if (!(address & 2)) offset >>= 16; + + UINT32 target = REG(5) + 2 + offset; + + printf("Opcode at %08x: %04x, handler is at %08x // if result (%08x) is zero, jump to %08x\n", REG(5), opcode, handler_offset, REG(4), target); + break; + } + + case 0x0099: + { + UINT32 l1_2 = REG(4); + + UINT32 address = REG(7); + UINT32 l0_2 = read_sized_word(11, address, 4); + + address = REG(7) + 4; + UINT32 popped_g4 = read_sized_word(11, address, 4); + + address = REG(5) + 2; + UINT32 offset = read_sized_word(11, address, 2); + if (!(address & 2)) offset >>= 16; + + UINT32 target = REG(5) + 2 + offset; + + printf("Opcode at %08x: %04x, handler is at %08x // branch relative to %08x if data stack pop/top (%08x) == result (%08x), pop_data result (%08x)\n", REG(5), opcode, handler_offset, target, l0_2, l1_2, popped_g4); + if (l1_2 == l0_2) + { + printf(" // branch will be taken\n"); + } + else + { + printf(" // branch will not be taken\n"); + printf(" // push pc (%08x) onto program stack\n", REG(5) + 2); + printf(" // push previous data stack top + 0x80000000 (%08x) onto program stack\n", l0_2 + 0x8000000); + printf(" // push diff of (result - stack top) (%08x - %08x = %08x)\n", popped_g4, l0_2 + 0x8000000, popped_g4 - (l0_2 + 0x80000000)); + } + + break; + } + + case 0x0121: + { + UINT32 address = REG(7); + UINT32 word = read_sized_word(11, address, 4); + printf("Opcode at %08x: %04x, handler is at %08x // logical-AND result with data stack pop, store in result: %08x = %08x & %08x\n", REG(5), opcode, handler_offset, word & REG(4), word, REG(4)); + break; + } + + case 0x0136: + printf("Opcode at %08x: %04x, handler is at %08x // invert result (%08x -> %08x)\n", REG(5), opcode, handler_offset, REG(4), REG(4) ^ 0xffffffff); + break; + + case 0x014f: + { + UINT32 address = REG(7); + UINT32 word = read_sized_word(11, address, 4); + printf("Opcode at %08x: %04x, handler is at %08x // add result to data stack pop, store in result: %08x = %08x + %08x\n", REG(5), opcode, handler_offset, word + REG(4), word, REG(4)); + break; + } + + case 0x0155: + { + UINT32 address = REG(7); + UINT32 word = read_sized_word(11, address, 4); + printf("Opcode at %08x: %04x, handler is at %08x // subtract result from data stack pop, store in result: %08x = %08x - %08x\n", REG(5), opcode, handler_offset, word - REG(4), word, REG(4)); + break; + } + + case 0x01c7: + { + UINT32 address = REG(6); + UINT32 half0 = read_sized_word(11, address, 2); + if (address & 2) half0 <<= 16; + + address = REG(6) + 2; + UINT32 half1 = read_sized_word(11, address, 2); + if (!(address & 2)) half1 >>= 16; + + UINT32 value = half0 | half1; + + printf("Opcode at %08x: %04x, handler is at %08x // return (%08x) (pops off program stack)\n", REG(5), opcode, handler_offset, value); + break; + } + + case 0x01cd: + printf("Opcode at %08x: %04x, handler is at %08x // insert result (%08x) between data stack top (%08x) and next data stack entry\n", REG(5), opcode, handler_offset, REG(4), read_sized_word(11, REG(7), 4)); + break; + + case 0x0217: + { + UINT32 value = read_sized_word(11, REG(7), 4); + printf("Opcode at %08x: %04x, handler is at %08x // if pop_data (%08x) >= result (%08x), set result to 0, otherwise -1 (%08x)\n", REG(5), opcode, handler_offset, value, REG(4), (value >= REG(4)) ? 0 : ~0); + break; + } + + case 0x0289: + printf("Opcode at %08x: %04x, handler is at %08x // push_data(g4 (%08x))\n", REG(5), opcode, handler_offset, REG(4)); + break; + + case 0x0296: + printf("Opcode at %08x: %04x, handler is at %08x // swap result (%08x) with top of data stack (%08x)\n", REG(5), opcode, handler_offset, REG(4), read_sized_word(11, REG(7), 4)); + break; + + case 0x029d: + { + UINT32 top = read_sized_word(11, REG(7), 4); + UINT32 next = read_sized_word(11, REG(7) + 4, 4); + printf("Opcode at %08x: %04x, handler is at %08x // swap the top two values of the data stack (%08x <-> %08x), exchange second value with result (%08x <-> %08x)\n", REG(5), opcode, handler_offset, top, next, REG(4), next); + break; + } + + case 0x02f2: + printf("Opcode at %08x: %04x, handler is at %08x // decrement g4 (%08x -> %08x)\n", REG(5), opcode, handler_offset, REG(4), REG(4) - 1); + break; + + case 0x0334: + { + UINT32 address = REG(4); + UINT32 half0 = read_sized_word(11, address, 2); + if (address & 2) half0 <<= 16; + + address = REG(4) + 2; + UINT32 half1 = read_sized_word(11, address, 2); + if (!(address & 2)) half1 >>= 16; + + UINT32 value = half0 | half1; + + printf("Opcode at %08x: %04x, handler is at %08x // load result with 32-bit word at result address (g4 = [%08x] (%08x)\n", REG(5), opcode, handler_offset, REG(4), value); + break; + } + + case 0x0381: + printf("Opcode at %08x: %04x, handler is at %08x // word[g4 (%08x)] = pop_data(g7), result = pop_data(g7), g7 = %08x\n", REG(5), opcode, handler_offset, REG(4), REG(7)); + break; + + case 0x3d38: + printf("Opcode at %08x: %04x, handler is at %08x // call ffe8fe90\n", REG(5), opcode, handler_offset); + break; + } + } + else + { + printf("Opcode at %08x: %04x, handler is at %08x\n", REG(5), opcode, handler_offset); + } + } +#endif + if (MAE && !m_annul) { m_trap = 1; |