/*
 *  Interactive disassembler (IDA).
 *  Zilog Z8 module
 *
 */

#include "z8.hpp"

// ig: emuFlg вообще-то не нужен, т.к. ядро уже в переменную uFlag
//     положило флаги перед вызовом emu()
//static long emuFlg;
static int  flow;

//----------------------------------------------------------------------

static void TouchArg( op_t &x, int isload )
{
  switch( x.type )
  {
    case o_imm:
    case o_displ:
      if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dr_O);
      break;

    case o_mem:
    case o_ind_mem:
      {
        ulong dea = intmem + x.addr;
        ua_dodata( dea, x.dtyp );
        if( !isload )   doVar( dea );
        ua_add_dref( x.offb, dea, isload ? dr_R : dr_W );
      }
      break;

    case o_near:
      ulong ea = toEA( cmd.cs, x.addr );
      int iscall = InstrIsSet( cmd.itype, CF_CALL );
      ua_add_cref( x.offb, ea, iscall ? fl_CN : fl_JN );
      if( flow && iscall )
      {
        func_t *pfn = get_func( ea );
        if( pfn != NULL && (pfn->flags & FUNC_NORET) )  flow = 0;
      }
  }
}

//----------------------------------------------------------------------

int emu( void )
{
  int Feature = Instructions[cmd.itype].feature;

  flow = ((Feature & CF_STOP) == 0);

  if( Feature & CF_USE1 )   TouchArg( cmd.Op1, 1 );
  if( Feature & CF_USE2 )   TouchArg( cmd.Op2, 1 );
  if( Feature & CF_JUMP )   QueueMark( Q_jumps, cmd.ea );

  if( Feature & CF_CHG1 )   TouchArg( cmd.Op1, 0 );
  if( Feature & CF_CHG2 )   TouchArg( cmd.Op2, 0 );

  if( flow )                ua_add_cref( 0, cmd.ea+cmd.size, fl_F );

  return 1;
}
