Files
2021-10-31 21:20:46 +02:00

136 lines
3.0 KiB
C++

#include "m740.hpp"
static void handle_imm(const insn_t &insn, const op_t &op, flags_t F)
{
set_immd(insn.ea);
if ( is_defarg(F, op.n) )
return;
bool in_hex = false;
switch ( insn.itype )
{
case m740_and:
case m740_ora:
in_hex = true;
break;
}
if ( in_hex )
op_hex(insn.ea, op.n);
}
void m740_t::handle_operand(const insn_t &insn, const op_t &op)
{
flags_t F = get_flags(insn.ea);
switch ( op.type )
{
// code address
case o_near:
{
ea_t ea = to_ea(insn.cs, op.addr);
cref_t mode = fl_JN;
if ( insn.itype == m740_jsr )
{
if ( !func_does_return(ea) )
flow = false;
mode = fl_CN;
}
insn.add_cref(ea, op.offb, mode);
}
break;
// data address
case o_mem:
{
enum dref_t mode = dr_U;
if ( is_addr_ind(op) )
mode = dr_R; /* NOT dr_O */
else if ( is_addr_read(op) )
mode = dr_R;
else if ( is_addr_write(op) )
mode = dr_W;
insn.add_dref(to_ea(insn.cs, op.addr), op.offb, mode);
insn.create_op_data(op.addr, op);
}
break;
// immediate
case o_imm:
handle_imm(insn, op, F);
// if the value was converted to an offset, then create a data xref:
if ( op_adds_xrefs(F, op.n) )
insn.add_off_drefs(op, dr_O, 0);
break;
// displ
case o_displ:
if ( op_adds_xrefs(F, op.n) )
{
ea_t ea = insn.add_off_drefs(op, dr_O, OOF_ADDR);
insn.create_op_data(ea, op);
}
break;
// reg - do nothing
case o_reg:
case o_void:
break;
default:
INTERR(10022);
}
}
// emulate an instruction
int m740_t::emu(const insn_t &insn)
{
uint32 feature = insn.get_canon_feature(ph);
flow = ((feature & CF_STOP) == 0);
if ( insn.Op1.type != o_void ) handle_operand(insn, insn.Op1);
if ( insn.Op2.type != o_void ) handle_operand(insn, insn.Op2);
if ( insn.Op3.type != o_void ) handle_operand(insn, insn.Op3);
/*
we can't use this code
if ( feature & CF_USE1) handle_operand(insn, insn.Op1, 1 );
if ( feature & CF_USE2) handle_operand(insn, insn.Op2, 1 );
if ( feature & CF_USE3) handle_operand(insn, insn.Op3, 1 );
*/
// we don't use CF_JUMP
// if ( feature & CF_JUMP )
switch ( insn.itype )
{
case m740_jmp:
case m740_jsr:
if ( insn.Op1.type != o_void && is_addr_ind(insn.Op1) )
remember_problem(PR_JUMP, insn.ea);
break;
}
/*
if ( feature & CF_CHG1) handle_operand(insn, insn.Op1, 0 );
if ( feature & CF_CHG2) handle_operand(insn, insn.Op2, 0 );
if ( feature & CF_CHG3) handle_operand(insn, insn.Op3, 0 );
*/
if ( flow )
{
// skip the next byte if the current insn is brk
if ( insn.itype == m740_brk )
{
add_cref(insn.ea, insn.ea + insn.size + 1, fl_JN);
create_byte(insn.ea + insn.size, 1);
}
else
{
add_cref(insn.ea, insn.ea + insn.size, fl_F);
}
}
return 1;
}