ks0164: CPU refinements

- Force source register to be the same as destination register for max/min instructions. Fixes missing instruments and eventually disappearing music in elfin attract.
- Write "tst" instead of "zero |=" in disassembly
This commit is contained in:
AJR 2023-10-28 20:15:48 -04:00
parent 461916276f
commit 78857ddc5f
2 changed files with 22 additions and 10 deletions

View File

@ -335,16 +335,16 @@ void ks0164_cpu_device::execute_run()
case 1: {
// Min/max with immediate
// 1101 Mrrr Ssss 1000
u16 v1 = m_r[(opcode >> 4) & 7];
// 1101 Mrrr S000 1000
u16 v1 = m_r[(opcode >> 8) & 7];
u16 v2 = m_program_cache.read_word(m_r[R_PC]);
m_r[R_PC] += 2;
u16 res;
switch(bitswap<2>(opcode, 11, 7)) {
case 0: res = v1 > v2 ? v1 : v2; break;
case 1: res = s16(v1) > s16(v2) ? v1 : v2; break;
case 2: res = v1 < v2 ? v1 : v2; break;
case 3: default: res = s16(v1) < s16(v2) ? v1 : v2; break;
case 0: res = std::max<u16>(v1, v2); break;
case 1: res = std::max<s16>(v1, v2); break;
case 2: res = std::min<u16>(v1, v2); break;
case 3: default: res = std::min<s16>(v1, v2); break;
}
m_r[(opcode >> 8) & 7] = res;
break;

View File

@ -65,6 +65,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] {
{ 0x9804, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= %s.bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0x9884, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= %s.bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0x980c, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= %s", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa704, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst %s.bu", regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa784, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst %s.bs", regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa70c, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst %s", regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa004, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= %s.bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa084, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= %s.bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa00c, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= %s", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
@ -108,6 +111,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] {
{ 0x9806, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= (%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0x9886, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= (%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0x980e, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= (%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa706, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst (%s).bu", regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa786, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst (%s).bs", regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa70e, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst (%s).w", regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa006, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa086, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
{ 0xa00e, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } },
@ -133,6 +139,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] {
{ 0x9877, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s &= (%04x).bu", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0x98f7, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s &= (%04x).bs", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0x987f, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s &= (%04x).w", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xa777, 0xffff, [](P) -> u32 { util::stream_format(stream, "tst (%04x).bu", opcodes.r16(pc+2)); return 4; } },
{ 0xa7f7, 0xffff, [](P) -> u32 { util::stream_format(stream, "tst (%04x).bs", opcodes.r16(pc+2)); return 4; } },
{ 0xa77f, 0xffff, [](P) -> u32 { util::stream_format(stream, "tst (%04x).w", opcodes.r16(pc+2)); return 4; } },
{ 0xa077, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s |= (%04x).bu", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xa0f7, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s |= (%04x).bs", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xa07f, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s |= (%04x).w", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
@ -158,6 +167,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] {
{ 0x9807, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= (%s%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
{ 0x9887, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= (%s%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
{ 0x980f, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s &= (%s%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
{ 0xa707, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst (%s%s).bu", regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
{ 0xa787, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst (%s%s).bs", regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
{ 0xa70f, 0xff8f, [](P) -> u32 { util::stream_format(stream, "tst (%s%s).w", regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
{ 0xa007, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
{ 0xa087, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
{ 0xa00f, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } },
@ -186,10 +198,10 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] {
{ 0xc007, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s <<c= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } },
{ 0xc807, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s >>c= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } },
{ 0xd008, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = maxu(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xd808, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = minu(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xd088, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = maxs(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xd888, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = mins(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xd008, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = maxu(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xd808, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = minu(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xd088, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = maxs(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xd888, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = mins(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } },
{ 0xd001, 0xffff, [](P) -> u32 { util::stream_format(stream, "jmp %04x", opcodes.r16(pc+2)); return 4; } },
{ 0xd002, 0xffff, [](P) -> u32 { util::stream_format(stream, "jsr %04x", opcodes.r16(pc+2)); return 4 | STEP_OVER; } },
{ 0xd003, 0xffff, [](P) -> u32 { util::stream_format(stream, "rts"); return 2 | STEP_OUT; } },