diff --git a/src/devices/cpu/sm8500/sm8500d.cpp b/src/devices/cpu/sm8500/sm8500d.cpp index e3080d64cef..c509e2edd81 100644 --- a/src/devices/cpu/sm8500/sm8500d.cpp +++ b/src/devices/cpu/sm8500/sm8500d.cpp @@ -372,30 +372,35 @@ offs_t sm8500_disassembler::disassemble(std::ostream &stream, offs_t pc, const d ea += opcodes.r8(pos++); util::stream_format(stream, "$%04X", ea); break; - case AM_5A: + case AM_5A: // see issue #7451 ea = opcodes.r8(pos++); ea2 = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "CMP (rr%02Xh),$%02Xh", ea & 7, ea2); break; case 0x40: - util::stream_format(stream, "undef $%04X", ea); break; + util::stream_format(stream, "CMP (rr%02Xh)+,$%02Xh", ea & 7, ea2); break; case 0x80: ea3 = opcodes.r8(pos++); util::stream_format(stream, "CMP (rr%02Xh+%02Xh),$%02Xh", ea & 7, ea2, ea3); break; case 0xC0: - util::stream_format(stream, "undef $%04X", ea); break; + util::stream_format(stream, "CMP -(rr%02Xh)+,$%02Xh", ea & 7, ea2); break; } break; - case AM_5B: + case AM_5B: // see issue #7451 ea = opcodes.r8(pos++); ea2 = opcodes.r8(pos++); ea3 = (ea << 8) | ea2; switch( ea & 0xC0 ) { + case 0x00: + util::stream_format(stream, "MOV (rr%02Xh),$%02Xh", ea & 7, ea2); break; case 0x40: - util::stream_format(stream, "MOV (rr%02Xh)+,$%02Xh", ea & 7, ea2); break; // could be AND instead of MOV - default: - util::stream_format(stream, "undef $%04X", ea3); break; + util::stream_format(stream, "MOV (rr%02Xh)+,$%02Xh", ea & 7, ea2); break; + case 0x80: + ea3 = opcodes.r8(pos++); + util::stream_format(stream, "MOV (rr%02Xh+%02Xh),$%02Xh", ea & 7, ea2, ea3); break; + case 0xC0: + util::stream_format(stream, "MOV -(rr%02Xh),$%02Xh", ea & 7, ea2); break; } break; case AM_ss: diff --git a/src/devices/cpu/sm8500/sm85ops.h b/src/devices/cpu/sm8500/sm85ops.h index cd36b679263..2b4d4763bfe 100644 --- a/src/devices/cpu/sm8500/sm85ops.h +++ b/src/devices/cpu/sm8500/sm85ops.h @@ -1282,56 +1282,76 @@ case 0x59: /* Invalid - 2? cycles - Flags affected: --------? */ logerror( "%04X: unk%02x, unhandled\n", m_PC-1,op ); mycycles += 2; break; -case 0x5A: /* unk5A - 7,8,12,9,8 cycles */ -/* NOTE: This unknown command is used in the calculator, and in a number of carts. - It appears to be a compare, and the number of opcode bytes varies depending - on the 2nd byte. */ +case 0x5A: /* indirect CMP - 7,8,12,9,8 cycles */ ARG_iR; switch (r2 & 0xc0) { case 0x00: // 5A 02 09 (used in calculator @ 493A and 4941. Used in Defender II @ 6DC9). // Assuming it to be a compare of the literal last number against contents of (contents of r02). - logerror( "%04X: unk%02X %02X %02X\n", m_PC-3,op,r2,r1 ); + //logerror( "%04X: unk%02X %02X %02X\n", m_PC-3,op,r2,r1 ); s1 = mem_readbyte(r2 & 7); OP_CMP8( mem_readbyte(s1), r1 ); break; + case 0x40: + s1 = r2 & 7; // s1 = primary reg + res = mem_readbyte(s1); // res = secondary reg# + OP_CMP8( mem_readbyte(res), r1 ); + mem_writebyte(s1, res+1); // inc res + break; case 0x80: // 5A 86 C6 00 (used in Henry @ 495B, when you guess wrongly in practice mode). // 5A 87 C6 00 (used in Henry @ 7073, when you guess wrongly in competition mode). // Assuming it to be a compare of the literal last number against contents of (contents r06 + offset C6). s1 = r1; ARG_R; - logerror( "%04X: unk%02X %02X %02X %02X\n", m_PC-4,op,r2,s1,r1 ); + //logerror( "%04X: unk%02X %02X %02X %02X\n", m_PC-4,op,r2,s1,r1 ); s1 += mem_readbyte(r2 & 7); OP_CMP8( mem_readbyte(s1), r1 ); + mycycles += 4; break; - default: - logerror( "%04X: unk%02X %02X %02X, unhandled\n", m_PC-3,op,r2,r1 ); + case 0xC0: + s1 = r2 & 7; // s1 = primary reg + res = mem_readbyte(s1) - 1; // res = secondary reg# + mem_writebyte(s1, res); // dec res + OP_CMP8( mem_readbyte(res), r1 ); break; } mycycles += 7; break; -case 0x5B: /* unk5B - 6,7,11,8,7 cycles */ -/* NOTE: This unknown command appears to have several variants, but all the games that use it only - use one specific instruction. We code for that here, and log anything else that may turn up. - It appears to move a literal to a register pointed to by another register. +case 0x5B: /* indirect MOV - 6,7,11,8,7 cycles */ +/* Only one variant is used in gamecom: 5B 42 00 Example: move r02, E9 - unk 5b 42 00 (move 00 into register E9, then increment r02) -*/ + 5b 42 00 (move 00 into register E9, then increment r02) */ ARG_iR; - if (r2 == 0x42) // only code used is 5B 42 00. This code allows those games to boot. - { // MOV (Rr)+,i -- or maybe -- AND (Rr)+,i - logerror( "%04X: unk%02X %02X %02X\n", m_PC-3,op,r2,r1 ); - s1 = r2 & 7; - res = mem_readbyte( s1 ); - mem_writebyte( res, r1 ); - mem_writebyte( s1, res + 1 ); + switch (r2 & 0xc0) + { + case 0x00: + s1 = mem_readbyte(r2 & 7); + mem_writebyte( mem_readbyte(s1), r1 ); + break; + case 0x40: + //logerror( "%04X: unk%02X %02X %02X\n", m_PC-3,op,r2,r1 ); + s1 = r2 & 7; + res = mem_readbyte(s1); + mem_writebyte(res, r1); + mem_writebyte(s1, res + 1); + break; + case 0x80: + s1 = r1; + ARG_R; + s1 += mem_readbyte(r2 & 7); + mycycles += 4; + mem_writebyte(mem_readbyte(s1), r1); + break; + case 0xC0: + s1 = r2 & 7; + res = mem_readbyte(s1) - 1; + mem_writebyte(s1, res); + mem_writebyte(mem_readbyte(res), r1); + break; } - else - logerror( "%04X: unk%02X %02X %02X, unhandled\n", m_PC-3,op,r2,r1 ); - mycycles += 6; break; case 0x5C: /* DIV RRr,RRs - 47 cycles - Flags affected: -Z-V---- */