/*

 *      Interactive disassembler (IDA).
 *      Version 3.05
 *      Copyright (c) 1990-95 by Ilfak Guilfanov.
 *      ALL RIGHTS RESERVED.
 *                              FIDO:   2:5020/209
 *                              E-mail: ig@estar.msk.su
 *
 */

#include "78k_0.hpp"


//Прочитать 2 байта  с указанного адресса
const ulong Get_Addr_Call(uchar Addr )
{
   ulong low = get_byte( Addr+1 );
   ulong high  = get_byte(Addr );
   ulong res = high | (low<<8);

   return res;
}


//Прочитать 2 байта, поменять байты местами и получить слово
const ulong Get_Data_16bits( )
{
   ulong high = ua_next_byte();
   ulong low  = ua_next_byte();
   ulong res = high | (low<<8);

   return res;
}


// Определяем oпреранд BIT
// Заполняем структуру op_t, описывая операнд типа - bit
//     TypeOrd - тип операнда
//            TBO_SADDR 
//            TBO_SFR      
//            TBO_A        
//            TBO_PSW      
//            TBO_HL       
//
//     NumBit- номер бита
//
inline void Operand_Bit( op_t &x , uchar TypeOrd, int NumBit)
{
   x.type = o_bit;
   x.TypeOperand = TypeOrd;
   x.value  = NumBit;
   x.offb = cmd.size;
}

// Определяем oпреранд IMM 8 байтовый
// Заполняем структуру op_t, описывая операнд типа - imm
//      Данные( 00 - FF)
inline void Operand_Data_8bits( op_t &x , uchar Data)
{
   x.type = o_imm;
   x.value = Data;
   x.dtyp  = dt_byte;
   x.offb = cmd.size;
}


// Определяем oпреранд IMM 16 байтовый
// Заполняем структуру op_t, описывая операнд типа - imm
//      Данные( 00 - FFFF)
inline void Operand_Data_16bits( op_t &x , ulong Data)
{
   x.type = o_imm;
   x.value = Data;
   x.dtyp  = dt_word;
   x.offb = cmd.size;
}


// Определяем oпреранд SFR
// Заполняем структуру op_t, описывая операнд типа - mem
//     addr - младшая часть адресса
inline void Operand_Sfr(op_t &x, uchar addr)
{
   x.type = o_mem;
   x.offb = cmd.size - 1;

   if( (0xFF00+addr)>0xFFFF)
     x.addr = addr ;
   else
     x.addr = 0xFF00+addr ; 
}


// Определяем oпреранд SADDR
// Заполняем структуру op_t, описывая операнд типа - mem
//     addr - младшая часть адресса
inline void Operand_Saddr( op_t &x , uchar addr)
{
   if(addr<0x20)
   {
     Operand_Sfr(x, addr);
     return;
   }

   x.type = o_mem;
   x.offb = cmd.size - 1;

   if( (0xFE00+addr)>0xFF1F)
      x.addr = addr ;
   else
      x.addr = 0xFE00+addr ;  
}


// Определяем oпреранд !ADDR16
// Заполняем структуру op_t, описывая операнд типа - imm
//     Res - 16 разрядное значение
inline void Operand_XAddr16( op_t &x, ulong Res)
{
   x.type = o_imm;
   x.value = Res;
   x.dtyp  = dt_word;
   x.offb =  cmd.size;  
   x.Form = 0x1;
}

//      reg - регистр 
//      Flags- дополнительные флаги необходимые при выводе
//
//            FTR_SCOBKI  - при выводе добавлять квадратные скобки
//            FTR_PLUS    - после регистра HL добавить +
//            FTR_VALUE   - нужно вывести значение
//            FTR_REGISTR - нужно вывести регистр
//
inline void Operand_Registr( op_t &x, int rReg, uchar Flags )
{
   x.type = o_reg;
   x.reg = rReg;       
   x.Prepost = Flags;
}

// Определяем oпреранд REG
// Заполняем структуру op_t, описывая операнд типа - reg
//  [HL+XXX]
//    ХХХ - значение
inline void Operand_Registr_Value( op_t &x, uchar Value )
{
   Operand_Registr(x, rHL, FTR_SCOBKI | FTR_PLUS | FTR_VALUE);
   x.value = Value;
}


// Определяем oпреранд REG
// Заполняем структуру op_t, описывая операнд типа - reg
//  [HL+XXX]
//   XXX-регистр
inline void Operand_Registr_Registr( op_t &x, int rReg )
{
   Operand_Registr(x, rHL, FTR_SCOBKI | FTR_PLUS | FTR_REGISTR);
   x.Registr = rReg;
}

// Определяем oпреранд CALL
// Заполняем структуру op_t, описывая операнд типа - near
//     Addr - адресс функции
inline void Operand_Call( op_t &x, ulong Addr)
{                     
   x.type = o_near;
   x.addr = Addr;
   x.offb = cmd.size;
}

// Определяем oпреранд CALL
// Заполняем структуру op_t, описывая операнд типа - near
//     Addr - смещение относительно 0х40
//      0x40 - 0x3E
inline void Operand_Call5( op_t &x, ulong Addr)
{                     
   x.type = o_near;
   x.addr = Get_Addr_Call( 0x40+ Addr );
//   x.offb = cmd.size;
   x.Form = 0x1;
}


// Определяем oпреранд CALL
// Заполняем структуру op_t, описывая операнд типа - near
//     Addr - смещение относительно 0х0800
//   x0800 - 0xFFF
inline void Operand_Call11( op_t &x, ulong Addr)
{               
   x.type = o_near;
   x.addr = Addr;
//   x.offb = cmd.size;
   x.Form = 0x2;
}

// Определяем oпреранд NEAR
//Запоняем структуру op_t, описывая операнд типа - near
//      addr - адресс в памяти
//      del - дополнительное
inline void Operand_Near(op_t &x, uchar addr, int del)
{
    x.type = o_near;
    x.addr = cmd.ip + (signed char)addr + del;
    x.offb = cmd.size;
}

// Определяем oпреранд SADDRP
// Заполняем структуру op_t, описывая операнд типа - mem
//     addr - младшая часть адресса

inline void Operand_Saddrp(op_t &x, uchar addr)
{
   if(addr<0x20)
   {
     Operand_Sfr(x, addr);
     return;
   }

   x.type = o_mem;
   x.offb = cmd.size - 1;

   if( (0xFE00+addr)>0xFF1E)
     x.addr = addr ;
   else
      x.addr = 0xFE00+addr ; 
 
}

//--------------------------------------------------------
static int GETBIT(uchar Data, int bit)
{
   uchar TempByte;
   TempByte = Data;
   return (((TempByte >> bit) & 0x01));
}

static int GETNUMBIT( uchar Data )
{
  return (Data & 0x7);
}


//----------------------------------------------------------------------
const int Opcode_61( )             
{                              
   //получить один байт
   uchar code = ua_next_byte();

   //получаем старшую часть байта
   uchar nib  = (code >> 4) & 0xF;
   //получаем младшую часть байта       
   uchar cd = code & 0xF;

   uchar icode[]={ NEC_78K_0_add,  NEC_78K_0_sub,  NEC_78K_0_addc,
                   NEC_78K_0_subc, NEC_78K_0_cmp,  NEC_78K_0_and,
                   NEC_78K_0_or,   NEC_78K_0_xor };

   uchar bcode[]={ NEC_78K_0_mov1, NEC_78K_0_set1, NEC_78K_0_clr1,
                   NEC_78K_0_and1, NEC_78K_0_or1,  NEC_78K_0_xor1};


   if( ((nib & 0xD)==0xD && ( cd == 0 || cd == 8)) )//sel BRx
   {
     cmd.itype = NEC_78K_0_sel;
     cmd.Op1.type = o_phrase;
     cmd.Op1.Prepost =   ((code >>4) & 0x2) | (( code>>3 ) & 0x1);
   }

   switch(nib)
   {                              
      case 0x0://add  A,r      ( 0000 1RRR )
               //add  r,A      ( 0000 0RRR )
      case 0x1://sub  A,r      ( 0001 1RRR )
               //sub  r,A      ( 0001 0RRR )
      case 0x2://addc A,r      ( 0010 1RRR )
               //addc r,A      ( 0010 0RRR )
      case 0x3://subc A,r      ( 0011 1RRR )
               //subc r,A      ( 0011 0RRR )
      case 0x4://cmp  A,r      ( 0100 1RRR )
               //cmp  r,A      ( 0100 0RRR )
      case 0x5://and  A,r      ( 0101 1RRR )
               //and  r,A      ( 0101 0RRR )
      case 0x6://or   A,r      ( 0110 1RRR )
               //or   r,A      ( 0110 0RRR )
      case 0x7://xor  A,r      ( 0111 1RRR )
               //xor  r,A      ( 0111 0RRR )

           cmd.itype = icode[ nib ];

           if(GETBIT(code, 3) == 1)
           {
             Operand_Registr( cmd.Op1, rA, 0);
             Operand_Registr( cmd.Op2, GETNUMBIT(cd), 0 );
           }
           else
           {
             Operand_Registr( cmd.Op1, GETNUMBIT(cd), 0 );
             Operand_Registr( cmd.Op2, rA, 0);
           }          

         return( cmd.size );                              
   }

   switch(code)
   {
      case 0x80://adjba                ( 0110 0001 1000 0000 )
           cmd.itype = NEC_78K_0_adjba;
         break;

      case 0x90://adjbs                ( 0110 0001 1000 0000 )
           cmd.itype = NEC_78K_0_adjbs;
         break;

      default:
        {
         switch(cd)
         {
            case 0x9://mov1 A.bit,CY
                 cmd.itype = NEC_78K_0_mov1;
                 Operand_Bit( cmd.Op1, TBO_A, GETNUMBIT(nib & 0x7 ));
                 Operand_Registr( cmd.Op2, bCY, 0);
               break;

            case 0xA://set1
            case 0xB://clr1
                 cmd.itype = bcode[ cd -9 ];
                 Operand_Bit( cmd.Op1, TBO_A, GETNUMBIT(nib & 0x7 ));
               break;

            case 0xD://and1
            case 0xE://or1
            case 0xF://xor1
                 cmd.itype = bcode[ cd -10 ];                     
                 Operand_Registr( cmd.Op1, bCY, 0);
                 Operand_Bit( cmd.Op2, TBO_A, GETNUMBIT(nib & 0x7 ));
               break;

           case 0xC://mov1 CY,A.bit
                cmd.itype = NEC_78K_0_mov1;
                Operand_Registr( cmd.Op1, bCY, 0);
                Operand_Bit( cmd.Op2, TBO_A, GETNUMBIT(nib) );
              break;


         }//end switch

         break;
        }//end default
         
    }//end switch


   return( cmd.size );
}

//----------------------------------------------------------------------
const int Opcode_71()
{
   //получить один байт
   uchar code = ua_next_byte();

   //получаем старшую часть байта
   uchar nib  = (code >> 4) & 0xF;
   //получаем младшую часть байта       
   uchar cd = code & 0xF;

   //Анализируем старший бит на 0
   if( GETBIT(code, 7) == 0 )
   {
     switch(cd)
     {
       case 0x0:
            if(nib == 0x1)
              cmd.itype = NEC_78K_0_HALT;
            else
              cmd.itype = NEC_78K_0_STOP;
          break;

         //mov1 PSW.bit,CY
         //mov1 saddr.bit,CY
       case 0x1:
       {
            cmd.itype = NEC_78K_0_mov1;
            uchar bt = ua_next_byte();
            if( bt == 0x1E )
               Operand_Bit( cmd.Op1, TBO_PSW, GETNUMBIT(nib) );
            else
              {
               Operand_Saddr( cmd.Op1,  bt);
               Operand_Bit( cmd.Op1, TBO_SADDR, GETNUMBIT(nib) );
              }

            Operand_Registr( cmd.Op2, bCY, 0);
    
          break;
       }
         //mov1 CY,saddr.bit
         //mov1 CY,PSW.bit
       case 0x4:
       {
            cmd.itype = NEC_78K_0_mov1;
            Operand_Registr( cmd.Op1, bCY, 0);
            uchar bt = ua_next_byte();
            if( bt == 0x1E )
               Operand_Bit( cmd.Op2, TBO_PSW, GETNUMBIT(nib) );
            else
              {
               Operand_Saddr( cmd.Op2,  bt);
               Operand_Bit( cmd.Op2, TBO_SADDR, GETNUMBIT(nib) );
              }        
          break;
       }


       case 0x9://mov1 sfr.bit,CY
            cmd.itype = NEC_78K_0_mov1;
            Operand_Sfr( cmd.Op1,  ua_next_byte());
            Operand_Bit( cmd.Op1, TBO_SFR, GETNUMBIT(nib) );
            Operand_Registr( cmd.Op2, bCY, 0);
          break;


          //and1 CY,saddr.bit 
          //and1 CY,PSW.bit
       case 0x5:
           {
            cmd.itype = NEC_78K_0_and1;
            Operand_Registr( cmd.Op1, bCY, 0);
            uchar bt = ua_next_byte();
            if( bt == 0x1E )
               Operand_Bit( cmd.Op2, TBO_PSW, GETNUMBIT(nib) );
            else
              {
               Operand_Saddr( cmd.Op2,  bt);
               Operand_Bit( cmd.Op2, TBO_SADDR, GETNUMBIT(nib) );
              }
            }
          break;

       case 0xD://and1 CY,sfr.bit
            cmd.itype = NEC_78K_0_and1;
            Operand_Registr( cmd.Op1, bCY, 0);
            Operand_Sfr( cmd.Op1,  ua_next_byte());
            Operand_Bit( cmd.Op1, TBO_SFR, GETNUMBIT(nib) );
          break;

          //or1 CY,addr.bit
          //or1 CY,PSW.bit
       case 0x6:
           {
            cmd.itype = NEC_78K_0_or1;
            Operand_Registr( cmd.Op1, bCY, 0);
            uchar bt = ua_next_byte();
            if( bt == 0x1E )
               Operand_Bit( cmd.Op2, TBO_PSW, GETNUMBIT(nib) );
            else
              {
               Operand_Saddr( cmd.Op2,  bt);
               Operand_Bit( cmd.Op2, TBO_SADDR, GETNUMBIT(nib) );
              }
            }
          break;

          //xor1 CY,addr.bit
          //xor1 CY,PSW.bit
       case 0x7:
           {
            cmd.itype = NEC_78K_0_xor1;
            Operand_Registr( cmd.Op1, bCY, 0);
            uchar bt = ua_next_byte();
            if( bt == 0x1E )
               Operand_Bit( cmd.Op2, TBO_PSW, GETNUMBIT(nib) );
            else
              {
               Operand_Saddr( cmd.Op2,  bt);
               Operand_Bit( cmd.Op2, TBO_SADDR, GETNUMBIT(nib) );
              }
            }
          break;
                    
          //set1 sfr.bit
       case 0xA:
            cmd.itype = NEC_78K_0_set1;
            Operand_Sfr( cmd.Op1,  ua_next_byte());
            Operand_Bit( cmd.Op1, TBO_SFR, GETNUMBIT(nib) );
          break;

          //clr1 sfr.bit
       case 0xB:
            cmd.itype = NEC_78K_0_clr1;
            Operand_Sfr( cmd.Op1,  ua_next_byte());
            Operand_Bit( cmd.Op1, TBO_SFR, GETNUMBIT(nib) );
          break;


      case 0x8:
           cmd.itype = NEC_78K_0_EI;    
           ua_next_byte();
         break;

     }//end switch
   }//endif                
   else// старший бит равен 1
  {
     switch(cd)
     {
       case 0xC://mov1 CY,A.bit
            cmd.itype = NEC_78K_0_mov1;
            Operand_Registr( cmd.Op1, bCY, 0);
            Operand_Bit( cmd.Op2, TBO_A, GETNUMBIT(nib) );
          break;

       case 0x4://mov1 CY,[HL].bit
            cmd.itype = NEC_78K_0_mov1;
            Operand_Registr( cmd.Op1, bCY, 0);
            Operand_Bit( cmd.Op2, TBO_HL, GETNUMBIT(nib) );
          break;

       case 0x1://mov1 [HL].bit,CY
            cmd.itype = NEC_78K_0_mov1;
            Operand_Bit( cmd.Op1, TBO_HL, GETNUMBIT(nib) );
            Operand_Registr( cmd.Op2, bCY, 0);
          break;

       case 0x5://and1 CY,[HL].bit
            cmd.itype = NEC_78K_0_and1;
            Operand_Registr( cmd.Op1, bCY, 0);
            Operand_Bit( cmd.Op2, TBO_HL, GETNUMBIT(nib) );
          break;

       case 0x6://or1 CY,[HL].bit
            cmd.itype = NEC_78K_0_or1;
            Operand_Registr( cmd.Op1, bCY, 0);
            Operand_Bit( cmd.Op2, TBO_HL, GETNUMBIT(nib) );
          break;

       case 0x7://xor1 CY,[HL].bit
            cmd.itype = NEC_78K_0_xor1;
            Operand_Registr( cmd.Op1, bCY, 0);
            Operand_Bit( cmd.Op2, TBO_HL, GETNUMBIT(nib) );
          break;

       case 0x2://set1 [HL].bit
            cmd.itype = NEC_78K_0_set1;
            Operand_Bit( cmd.Op1, TBO_HL, GETNUMBIT(nib) );
          break;

       case 0x3://clr1 [HL].bit
            cmd.itype = NEC_78K_0_clr1;
            Operand_Bit( cmd.Op1, TBO_HL, GETNUMBIT(nib) );
          break;


     }//end switch

  }//end else

   return( cmd.size );
}
//----------------------------------------------------------------------
const int Opcode_31()
{
   //получить один байт
   uchar code = ua_next_byte();

   //получаем старшую часть байта
   uchar nib  = (code >> 4) & 0xF;

   uchar icode[]={ NEC_78K_0_add,  NEC_78K_0_sub,  NEC_78K_0_addc,
                   NEC_78K_0_subc, NEC_78K_0_cmp,  NEC_78K_0_and,
                   NEC_78K_0_or,   NEC_78K_0_xor,  NEC_78K_0_xch };

   switch( code )
   {
      case 0x0B://add  A,[HL+B]      ( 0000 1011 )
      case 0x1B://sub  A,[HL+B]      ( 0001 1011 )
      case 0x2B://addc A,[HL+B]      ( 0010 1011 )
      case 0x3B://subc A,[HL+B]      ( 0011 1011 )
      case 0x4B://cmp  A,[HL+B]      ( 0100 1011 )
      case 0x5B://and  A,[HL+B]      ( 0101 1011 )
      case 0x6B://or   A,[HL+B]      ( 0110 1011 )
      case 0x7B://xor  A,[HL+B]      ( 0111 1011 )
      case 0x8B://xch  A,[HL+B]      ( 1000 1011 )
           cmd.itype = icode[nib];     
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr_Registr(cmd.Op2, rB);
         break;

      case 0x0A://add  A,[HL+C]      ( 0000 1010 )
      case 0x1A://sub  A,[HL+C]      ( 0001 1010 )
      case 0x2A://addc A,[HL+C]      ( 0010 1010 )
      case 0x3A://subc A,[HL+C]      ( 0011 1010 )
      case 0x4A://cmp  A,[HL+C]      ( 0100 1010 )
      case 0x5A://and  A,[HL+C]      ( 0101 1010 )
      case 0x6A://or   A,[HL+C]      ( 0110 1010 )
      case 0x7A://xor  A,[HL+C]      ( 0111 1010 )
      case 0x8A://xch  A,[HL+C]      ( 1000 1010 )
           cmd.itype = icode[nib];
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr_Registr(cmd.Op2, rC);
         break;
                                                                                 
      case 0x98://br AX           (0011 0001 1001 1000)
           cmd.itype = NEC_78K_0_br;    
           Operand_Registr( cmd.Op1, rAX, 0 );
         break;

      case 0x88://mulu X          ( 0011 0001 1000 1000)
           cmd.itype = NEC_78K_0_mulu;    
           Operand_Registr( cmd.Op1, rX, 0 );
         break;

      case 0x82://divuw X          ( 0011 0001 1000 0010)
           cmd.itype = NEC_78K_0_divuw;    
           Operand_Registr( cmd.Op1, rC, 0 );
         break;

      case 0x90://ror4 [HL]          ( 0011 0001 1001 0000)
           cmd.itype = NEC_78K_0_ror4;    
           Operand_Registr( cmd.Op1, rHL, FTR_SCOBKI );
         break;

      case 0x80://rol4 [HL]          ( 0011 0001 1000 0000)
           cmd.itype = NEC_78K_0_rol4;    
           Operand_Registr( cmd.Op1, rHL, FTR_SCOBKI );
         break;
         
          //Оставшиеся 0x31(bt,bf,btclr)
      default:
         {
            //получаем старшую часть байта
            uchar nib  = (code >> 4) & 0xF;
            //получаем младшую часть байта
            uchar cd = code & 0xF;

            //Анализируем старший бит
            if( GETBIT(code, 7) == 0)
            {
              //sfr.bit, $addr16
              //A.bit, $addr16
              //PSW.bit,$addr16

              switch( cd )
              {
                case 0x1:
                     cmd.itype = NEC_78K_0_btclr;
                     Operand_Saddr( cmd.Op1, ua_next_byte() );
                     Operand_Bit(cmd.Op1, TBO_SADDR, GETNUMBIT( nib ) );
                     Operand_Near(cmd.Op2, ua_next_byte(), 4);
                   break;

                case 0x3:
                    {
                     cmd.itype = NEC_78K_0_bf;
                     uchar bt = ua_next_byte();
                     if(bt ==  0x1E)
                        Operand_Bit(cmd.Op1, TBO_PSW, GETNUMBIT( nib ) );
                     else
                     {
                       Operand_Saddr( cmd.Op1, bt );
                       Operand_Bit(cmd.Op1, TBO_SADDR, GETNUMBIT( nib ) );
                     }                   
                     Operand_Near(cmd.Op2, ua_next_byte(), 4); 
                    }
                   break;

                case 0x5:
                     cmd.itype = NEC_78K_0_btclr;
                     Operand_Sfr( cmd.Op1, ua_next_byte() );
                     Operand_Bit(cmd.Op1, TBO_SFR, GETNUMBIT( nib ) );
                     Operand_Near(cmd.Op2, ua_next_byte(), 4);
                   break;

                case 0x6:
                     cmd.itype = NEC_78K_0_bt;
                     Operand_Sfr( cmd.Op1, ua_next_byte() );
                     Operand_Bit(cmd.Op1, TBO_SFR, GETNUMBIT( nib ) );
                     Operand_Near(cmd.Op2, ua_next_byte(), 4);
                   break;


                case 0x7:
                     cmd.itype = NEC_78K_0_bf;
                     Operand_Sfr( cmd.Op1, ua_next_byte() );
                     Operand_Bit(cmd.Op1, TBO_SFR, GETNUMBIT( nib ) );
                     Operand_Near(cmd.Op2, ua_next_byte(), 4);
                   break;

                case 0xE:
                     cmd.itype = NEC_78K_0_bt;
                     Operand_Bit(cmd.Op1, TBO_A, GETNUMBIT( nib ) );
                     Operand_Near(cmd.Op2, ua_next_byte(), 3);
                   break;

                case 0xD:
                     cmd.itype = NEC_78K_0_btclr;
                     Operand_Bit(cmd.Op1, TBO_A, GETNUMBIT( nib ) );
                     Operand_Near(cmd.Op2, ua_next_byte(), 3);
                   break;

                case 0xF:
                     cmd.itype = NEC_78K_0_bf;
                     Operand_Bit(cmd.Op1, TBO_A, GETNUMBIT( nib ) );
                     Operand_Near(cmd.Op2, ua_next_byte(), 3);
                   break;
              }
            }
            else//если старший бит равен 1
            {       
              uchar dcode[] = { NEC_78K_0_btclr, NEC_78K_0_bt, NEC_78K_0_bf };
              switch(cd)
              {  
                 case 0x5://btclr 5
                 case 0x6://bt 6
                 case 0x7://bf 7
                      cmd.itype = dcode[cd - 5];
                      Operand_Registr( cmd.Op1, rA, FTR_SCOBKI);
                      Operand_Bit(cmd.Op1, TBO_HL, GETNUMBIT( nib ) );
                      Operand_Near(cmd.Op2, ua_next_byte(), 3);
                    break;  

              }
            }//else //если старший бит равен 1

         break; //default
         }//end default
   }//switch

   return( cmd.size );
}


//----------------------------------------------------------------------
int ana(void) {
  
   //получить один байт
   uchar code = ua_next_byte();

   uchar icode[]={ NEC_78K_0_add,  NEC_78K_0_sub,  NEC_78K_0_addc,
                   NEC_78K_0_subc, NEC_78K_0_cmp,  NEC_78K_0_and,
                   NEC_78K_0_or,   NEC_78K_0_xor };

  //проверяем на call5
  if( (code & 0xC1) == 0xC1)
  { 
    cmd.itype = NEC_78K_0_callt;
    Operand_Call5(cmd.Op1, code & 0x3E );
    return( cmd.size );
  }



   //add,addc,sub,subc,and,or,xor,cmp   
   switch( code )
   {
      case 0x0D://add  A,#byte      ( 0000 1101 DATA )
      case 0x1D://sub  A,#byte      ( 0001 1101 DATA )
      case 0x2D://addc A,#byte      ( 0010 1101 DATA )
      case 0x3D://subc A,#byte      ( 0011 1101 DATA )
      case 0x4D://cmp  A,#byte      ( 0100 1101 DATA )
      case 0x5D://and  A,#byte      ( 0101 1101 DATA )
      case 0x6D://or   A,#byte      ( 0110 1101 DATA )
      case 0x7D://xor  A,#byte      ( 0111 1101 DATA )

           cmd.itype = icode[ code>>4 ];

           Operand_Registr( cmd.Op1, rA, 0);
           Operand_Data_8bits( cmd.Op2, ua_next_byte() );
         break;


      case 0x88://add  saddr,data      ( 1000 1000 SADDR DATA )
      case 0x98://sub  saddr,data      ( 1001 1000 SADDR DATA )
      case 0xA8://addc saddr,data      ( 1010 1000 SADDR DATA )
      case 0xB8://subc saddr,data      ( 1011 1000 SADDR DATA )
      case 0xC8://cmp  saddr,data      ( 1100 1000 SADDR DATA )
      case 0xD8://and  saddr,data      ( 1101 1000 SADDR DATA )
      case 0xE8://or   saddr,data      ( 1110 1000 SADDR DATA )
      case 0xF8://xor  saddr,data      ( 1111 1000 SADDR DATA )

           cmd.itype = icode[ (code>>4)-8 ];

           Operand_Saddr( cmd.Op1, ua_next_byte() );           
           Operand_Data_8bits( cmd.Op2, ua_next_byte() );
         break;

      case 0x0E://add  A,saddr-offset      ( 0000 1110 SADDR )
      case 0x17://sub  A,saddr-offset      ( 0001 1110 SADDR )
      case 0x2E://addc A,saddr-offset      ( 0010 1110 SADDR )
      case 0x3E://subc A,saddr-offset      ( 0011 1110 SADDR )
      case 0x4E://cmp  A,saddr-offset      ( 0100 1110 SADDR )
      case 0x5E://and  A,saddr-offset      ( 0101 1110 SADDR )
      case 0x6E://or   A,saddr-offset      ( 0110 1110 SADDR )
      case 0x7E://xor  A,saddr-offset      ( 0111 1110 SADDR )

           cmd.itype = icode[ code>>4 ];

           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Saddr( cmd.Op2, ua_next_byte() );
         break;

      case 0x08://add  A,!addr      ( 0000 1000 LOW HIGH )
      case 0x18://sub  A,!addr      ( 0001 1000 LOW HIGH )
      case 0x28://addc A,!addr      ( 0010 1000 LOW HIGH )
      case 0x38://subc A,!addr      ( 0011 1000 LOW HIGH )
      case 0x48://cmp  A,!addr      ( 0100 1000 LOW HIGH )
      case 0x58://and  A,!addr      ( 0101 1000 LOW HIGH )
      case 0x68://or   A,!addr      ( 0110 1000 LOW HIGH )
      case 0x78://xor  A,!addr      ( 0111 1000 LOW HIGH )

           cmd.itype = icode[ code>>4 ];

           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_XAddr16( cmd.Op2, Get_Data_16bits() );
         break;


      case 0x0F://add  A,[HL]      ( 0000 1111 )
      case 0x1F://sub  A,[HL]      ( 0001 1111 )
      case 0x2F://addc A,[HL]      ( 0010 1111 )
      case 0x3F://subc A,[HL]      ( 0011 1111 )
      case 0x4F://cmp  A,[HL]      ( 0100 1111 )
      case 0x5F://and  A,[HL]      ( 0101 1111 )
      case 0x6F://or   A,[HL]      ( 0110 1111 )
      case 0x7F://xor  A,[HL]      ( 0111 1111 )

           cmd.itype = icode[ code>>4 ];

           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr( cmd.Op2, rHL, FTR_SCOBKI );
         break;

      case 0x09://add  A,[HL+byte]      ( 0000 1111  DATA)
      case 0x19://sub  A,[HL+byte]      ( 0001 1111  DATA)
      case 0x29://addc A,[HL+byte]      ( 0010 1111  DATA)
      case 0x39://subc A,[HL+byte]      ( 0011 1111  DATA)
      case 0x49://cmp  A,[HL+byte]      ( 0100 1111  DATA)
      case 0x59://and  A,[HL+byte]      ( 0101 1111  DATA)
      case 0x69://or   A,[HL+byte]      ( 0110 1111  DATA)
      case 0x79://xor  A,[HL+byte]      ( 0111 1111  DATA)

           cmd.itype = icode[ code>>4 ];
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr_Value( cmd.Op2,  ua_next_byte() );
         break;

      case 0x31://xxx A,[HL+B], xxx A,[HL+C]
            return Opcode_31( );

    ////////////////////////////////////////////////
    //
    //  Call Return
    //
    ////////////////////////////////////////////////

      case 0x9A://call !addr16         ( 1001 1010 LOW HIGH )
           cmd.itype = NEC_78K_0_call;
           cmd.Op1.Form = 0x2;//вывод знака - !
           Operand_Call(cmd.Op1, Get_Data_16bits() );
         break;

     case 0xBF://brk              ( 1011 1111 )
           cmd.itype = NEC_78K_0_brk;
           break;

      case 0xAF://ret              ( 1010 1111 )
           cmd.itype = NEC_78K_0_ret;
           break;

     case 0x9F://retb              ( 1001 1111 )
           cmd.itype = NEC_78K_0_retb;
           break;

     case 0x8F://ret              ( 1000 1111 )
           cmd.itype = NEC_78K_0_reti;
           break;



    ////////////////////////////////////////////////
    //
    //  8-Bit Data Transfer
    //  MOV
    //
    ////////////////////////////////////////////////

         //mov saddr,#byte              ( 0001 0001 SADDR DATA)
         //mov PSW,#byte              ( 0001 0001 SADDR DATA)
     case 0x11:
         {  
           cmd.itype = NEC_78K_0_mov;
           uchar bt = ua_next_byte();
           if(bt == 0x1E)
             Operand_Registr( cmd.Op1, rPSW, 0 );
           else
             Operand_Saddr( cmd.Op1, bt );
                                        
           Operand_Data_8bits( cmd.Op2, ua_next_byte() );
           break;
          }

     case 0x13://mov sfr,#byte              ( 0001 0011 SFR DATA)
           cmd.itype = NEC_78K_0_mov;
           Operand_Sfr( cmd.Op1, ua_next_byte() );
           Operand_Data_8bits( cmd.Op2, ua_next_byte() );
           break;

          //mov A,saddr              ( 1111 0000 A SADDRR )
          //mov A,PSW                ( 1111 0000 A PSW )
     case 0xF0:
          {
           cmd.itype = NEC_78K_0_mov;
           uchar bt = ua_next_byte();
           if( bt == 0x1E)
             Operand_Registr( cmd.Op2, rPSW, 0 );
           else
             Operand_Saddr( cmd.Op2, bt );
  
           Operand_Registr( cmd.Op1, rA, 0 );
           break;
          }

        //mov saddr,A              ( 1111 0010 SADDRR A)
        //mov PSW,A                ( 1111 0010 SADDRR A)
     case 0xF2:
          {
           uchar bt = ua_next_byte();
           cmd.itype = NEC_78K_0_mov;
           if( bt == 0x1E)
             Operand_Registr( cmd.Op1, rPSW, 0 );
           else
             Operand_Saddr( cmd.Op1, bt );

           Operand_Registr( cmd.Op2, rA, 0 );
           break;
          }

     case 0xF4://mov A,sfr              ( 1111 0100 A SFR )
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Sfr( cmd.Op2, ua_next_byte() );
           break;

     case 0xF6://mov saddr,A              ( 1111 0110 SFR A)
           cmd.itype = NEC_78K_0_mov;
           Operand_Sfr( cmd.Op1, ua_next_byte() );
           Operand_Registr( cmd.Op2, rA, 0 );
           break;

     case 0x8E://mov A,!addr16              ( 1000 1110 LOW HIGH)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_XAddr16(cmd.Op2, Get_Data_16bits() );
           break;

     case 0x9E://mov !addr16,A              ( 1001 1110 LOW HIGH)
           cmd.itype = NEC_78K_0_mov;
           Operand_XAddr16( cmd.Op1, Get_Data_16bits() );
           Operand_Registr( cmd.Op2, rA, 0 );
           break;

     case 0x85://mov A,[DE]              ( 1000 0101)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr( cmd.Op2, rDE, FTR_SCOBKI );
           break;
                                              
     case 0x95://mov [DE],A              ( 1001 0101)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rDE, FTR_SCOBKI );
           Operand_Registr( cmd.Op2, rA, 0 );
           break;

     case 0x87://mov A,[HL]              ( 1000 0111)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr( cmd.Op2, rHL, FTR_SCOBKI );
           break;
                                              
     case 0x97://mov A,[HL]              ( 1001 0111)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rHL, FTR_SCOBKI );
           Operand_Registr( cmd.Op2, rA, 0 );
           break;
                                              
     case 0xAE://mov A,[HL+byte]              ( 1010 1110)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr_Value( cmd.Op2,  ua_next_byte() );
           break;
                                              
     case 0xBE://mov [HL+byte],A              ( 1011 1110)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr_Value( cmd.Op1,  ua_next_byte() );
           Operand_Registr( cmd.Op2, rA, 0 );
           break;

     case 0xAB://mov A,[HL+B]              ( 1010 1011)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr_Registr(cmd.Op2, rB);
           break;
                                              
     case 0xBB://mov [HL+B],A              ( 1011 1011)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr_Registr(cmd.Op1, rB);
           Operand_Registr( cmd.Op2, rA, 0 );
           break;

     case 0xAA://mov A,[HL+C]              ( 1010 1010)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr_Registr(cmd.Op2, rC);
           break;
                                              
     case 0xBA://mov [HL+B],A              ( 1011 1010)
           cmd.itype = NEC_78K_0_mov;
           Operand_Registr_Registr(cmd.Op1, rC);
           Operand_Registr( cmd.Op2, rA, 0 );
           break;


    ////////////////////////////////////////////////
    //
    //  8-Bit Data Transfer
    //  XCH
    //
    ////////////////////////////////////////////////

     case 0x83://xch A,saddr              ( 1000 0011 SADDR )
           cmd.itype = NEC_78K_0_xch;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Saddr( cmd.Op2, ua_next_byte() );
           break;

     case 0x93://xch A,sfr              ( 1001 0011 SFR )
           cmd.itype = NEC_78K_0_xch;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Sfr( cmd.Op2, ua_next_byte() );
           break;

     case 0xCE://xch A,!addr              ( 1100 1110 LOW HIGH )
           cmd.itype = NEC_78K_0_xch;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_XAddr16( cmd.Op2, Get_Data_16bits() );
           break;

     case 0x05://xch A,[DE]              ( 0000 0101 )
           cmd.itype = NEC_78K_0_xch;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr( cmd.Op1, rDE, FTR_SCOBKI );
           break;

     case 0x07://xch A,[HL]              ( 0000 0111 )
           cmd.itype = NEC_78K_0_xch;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr( cmd.Op1, rHL, FTR_SCOBKI );
           break;

     case 0xDE://xch A,[HL+byte]              ( 1101 1110 DATA )
           cmd.itype = NEC_78K_0_xch;
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Registr_Value( cmd.Op2,  ua_next_byte() );
           break;

    ////////////////////////////////////////////////
    //
    //  Unconditional Branch
    //
    ////////////////////////////////////////////////

      case 0xFA://br $addr16           (1111 01010 JDISP)
           cmd.itype = NEC_78K_0_br;    
           Operand_Near( cmd.Op1, ua_next_byte(), 2);
         break;

      case 0x9B://br !addr16           (1111 1011 LOW HIGH)
           cmd.itype = NEC_78K_0_br;    
           Operand_XAddr16( cmd.Op1, Get_Data_16bits() );
         break;

    ////////////////////////////////////////////////
    //
    //  Conditional Branch
    //
    ////////////////////////////////////////////////

      case 0x8D://bc $addr16           (1000 1101 JDISP )
           cmd.itype = NEC_78K_0_bc;    
           Operand_Near( cmd.Op1, ua_next_byte(), 2);   
         break;

      case 0x9D://bnc $addr16           (1001 1101 JDISP )
           cmd.itype = NEC_78K_0_bnc;    
           Operand_Near( cmd.Op1, ua_next_byte(), 2);   
         break;

      case 0xAD://bz $addr16           (1010 1101 JDISP )
           cmd.itype = NEC_78K_0_bz;    
           Operand_Near( cmd.Op1, ua_next_byte(), 2);   
         break;

      case 0xBD://bnz $addr16           (1011 1101 JDISP )
           cmd.itype = NEC_78K_0_bnz;    
           Operand_Near( cmd.Op1, ua_next_byte(), 2);   
         break;


      case 0x8B://dbnz B,$addr16           (1000 1011 JDISP )
           cmd.itype = NEC_78K_0_dbnz;    
           Operand_Registr( cmd.Op1, rB, 0 );
           Operand_Near( cmd.Op2, ua_next_byte(), 2);   
         break;

      case 0x8A://dbnz C,$addr16           (1000 1010 JDISP )
           cmd.itype = NEC_78K_0_dbnz;    
           Operand_Registr( cmd.Op1, rC, 0 );
           Operand_Near( cmd.Op2, ua_next_byte(), 2);   
         break;

      case 0x04://dbnz saddr,$addr16           (0000 0100 SADDR JDISP )
           cmd.itype = NEC_78K_0_dbnz;    
           Operand_Saddr( cmd.Op1, ua_next_byte() );
           Operand_Near(  cmd.Op2, ua_next_byte(), 3);
         break;

    ////////////////////////////////////////////////
    //
    //  Rotate
    //
    ////////////////////////////////////////////////

      case 0x24://ror A,1           ( 0010 0100 )
           cmd.itype = NEC_78K_0_ror;    
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Data_8bits( cmd.Op2, 1 );
         break;

      case 0x26://rol A,1           ( 0010 0110 )
           cmd.itype = NEC_78K_0_rol;    
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Data_8bits( cmd.Op2, 1 );
         break;

      case 0x25://rorc A,1           ( 0010 0101 )
           cmd.itype = NEC_78K_0_rorc;    
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Data_8bits( cmd.Op2, 1 );
         break;

      case 0x27://rolc A,1           ( 0010 0111 )
           cmd.itype = NEC_78K_0_rolc;    
           Operand_Registr( cmd.Op1, rA, 0 );
           Operand_Data_8bits( cmd.Op2, 1 );
         break;

    ////////////////////////////////////////////////
    //
    //  16-Bit Operand
    //
    ////////////////////////////////////////////////

      case 0xCA://addw AX,#word           ( 1100 1010 LOW HIGH)
           cmd.itype = NEC_78K_0_addw;    
           Operand_Registr( cmd.Op1, rAX, 0 );
           Operand_Data_16bits( cmd.Op2, Get_Data_16bits() );
         break;

      case 0xDA://subw AX,#word           ( 1101 1010 LOW HIGH)
           cmd.itype = NEC_78K_0_subw;    
           Operand_Registr( cmd.Op1, rAX, 0 );
           Operand_Data_16bits( cmd.Op2, Get_Data_16bits() );
         break;

      case 0xEA://cmpw AX,#word           ( 1110 1010 LOW HIGH)
           cmd.itype = NEC_78K_0_cmpw;    
           Operand_Registr( cmd.Op1, rAX, 0 );
           Operand_Data_16bits( cmd.Op2, Get_Data_16bits() );
         break;

    ////////////////////////////////////////////////
    //
    //  Incriment/decriment
    //
    ////////////////////////////////////////////////

      case 0x81://inc saddr           ( 1000 0001 SADDR)
           cmd.itype = NEC_78K_0_inc;    
           Operand_Saddr( cmd.Op1, ua_next_byte() );
         break;

      case 0x91://inc saddr           ( 1001 0001 SADDR)
           cmd.itype = NEC_78K_0_dec;    
           Operand_Saddr( cmd.Op1, ua_next_byte() );
         break;


    ////////////////////////////////////////////////
    //
    //  Bit manipulation
    //
    ////////////////////////////////////////////////

      case 0x20://set1 CY            ( 0010 0000 )
           cmd.itype = NEC_78K_0_set1;    
           Operand_Registr( cmd.Op1, bCY, 0 );
         break;

      case 0x21://clr1 CY            ( 0010 0001 )
           cmd.itype = NEC_78K_0_clr1;    
           Operand_Registr( cmd.Op1, bCY, 0 );
         break;

      case 0x01://not1 CY            ( 0000 0001 )
           cmd.itype = NEC_78K_0_not1;    
           Operand_Registr( cmd.Op1, bCY, 0 );
         break;

    ////////////////////////////////////////////////
    //
    //  Stack Manipulation
    //
    ////////////////////////////////////////////////

      case 0x22://push PSW            ( 0010 0010 )
           cmd.itype = NEC_78K_0_push;    
           Operand_Registr( cmd.Op1, rPSW, 0 );
         break;

      case 0x23://pop PSW            ( 0010 0011 )
           cmd.itype = NEC_78K_0_pop;    
           Operand_Registr( cmd.Op1, rPSW, 0 );
         break;


       //movw SP,#word            ( 1110 1110 0001 1100 LOW HIGH)
       //movw saddrp,#word            ( 1110 1110 SADDR LOW HIGH)
      case 0xEE:
         {
           cmd.itype = NEC_78K_0_movw;  
           uchar bt = ua_next_byte();
           if(bt == 0x1C)
             Operand_Registr( cmd.Op1, rSP, 0 );
           else
             Operand_Saddrp( cmd.Op1,  bt);

           Operand_Data_16bits( cmd.Op2, Get_Data_16bits() );
         break;
         }

           //movw SP,AX                ( 1001 1001 0001 1100 )
           //movw SADDRP,AX            ( 1001 1001 SADDRP )
      case 0x99:
         {
           cmd.itype = NEC_78K_0_movw;  
           uchar bt = ua_next_byte();
           if( bt == 0x1C)
             Operand_Registr( cmd.Op1, rSP, 0 );
           else
             Operand_Saddrp( cmd.Op1,  bt );

           Operand_Registr( cmd.Op2, rAX, 0 );
         break;
         }
           //movw AX,SP                ( 1000 1001 0001 1100 )
           //movw AX,SADDRP            ( 1000 1001 SADDRP )
      case 0x89:
         {
           cmd.itype = NEC_78K_0_movw;  
           uchar bt = ua_next_byte();                
           Operand_Registr( cmd.Op1, rAX, 0 );

           if( bt == 0x1C)
             Operand_Registr( cmd.Op2, rSP, 0 );
           else
             Operand_Saddrp( cmd.Op2,  bt );
         break;
         }

    ////////////////////////////////////////////////
    //
    //  16-Bit Data Transfer
    //
    ////////////////////////////////////////////////

/*      case 0xEE://movw saddrp,#word            ( 1110 1110 SADDR LOW HIGH)
           cmd.itype = NEC_78K_0_movw;    
           Operand_Saddrp( cmd.Op1,  ua_next_byte());
           Operand_Data_16bits( cmd.Op2, Get_Data_16bits() );
         break;
 */
      case 0xFE://movw sfr,#word            ( 1111 1110 SFR LOW HIGH)
           cmd.itype = NEC_78K_0_movw;    
           Operand_Sfr( cmd.Op1,  ua_next_byte());
           Operand_Data_16bits( cmd.Op2, Get_Data_16bits() );
         break;

      case 0xA9://movw AX,SFR            ( 1010 1001 SFR )
           cmd.itype = NEC_78K_0_movw;    
           Operand_Registr( cmd.Op1, rAX, 0 );
           Operand_Sfr( cmd.Op2,  ua_next_byte());
         break;

      case 0xB9://movw SFR,AX            ( 1011 1001 SFR )
           cmd.itype = NEC_78K_0_movw;    
           Operand_Sfr( cmd.Op1,  ua_next_byte());
           Operand_Registr( cmd.Op2, rAX, 0 );
         break;

      case 0x02://movw AX,!addr16            ( 0000 0010 LOW HIGH )
           cmd.itype = NEC_78K_0_movw;    
           Operand_Registr( cmd.Op1, rAX, 0 );
           Operand_Data_16bits( cmd.Op2, Get_Data_16bits() );
         break;

      case 0x03://movw !addr16,AX            ( 0000 0011 LOW HIGH )
           cmd.itype = NEC_78K_0_movw;    
           Operand_Data_16bits( cmd.Op1, Get_Data_16bits() );
           Operand_Registr( cmd.Op2, rAX, 0 );
         break;

    ////////////////////////////////////////////////
    //
    //  CPU control
    //
    ////////////////////////////////////////////////

      case 0x00://nop            ( 0000 0000 )
           cmd.itype = NEC_78K_0_nop;    
         break;

    ////////////////////////////////////////////////
    //
    //
    ////////////////////////////////////////////////

      case 0x61:
           return Opcode_61(  );

      case 0x71:
           return Opcode_71();


      case 0x7A:
           cmd.itype = NEC_78K_0_EI;    
           ua_next_byte();
         break;

      case 0x7B:
           cmd.itype = NEC_78K_0_DI;
           ua_next_byte();
         break;


      default:
        {
          //получаем старшую часть байта
          uchar nib  = (code >> 4) & 0xF;
          //получаем младшую часть байта
          uchar cd = code & 0xF;

          if(GETBIT(code, 3) == 0)
          {
            switch(nib)
            { 
               case 0x1://movw rp,#word
                    cmd.itype = NEC_78K_0_movw;   
                    Operand_Registr( cmd.Op1, rAX+(GETNUMBIT(cd)>>1), 0 );
                    Operand_Data_16bits( cmd.Op2, Get_Data_16bits() );
                 break;

              case 0xC://movw AX,rp           (1100 0PP0)
                   cmd.itype = NEC_78K_0_movw;   
                   Operand_Registr( cmd.Op1, rAX, 0 );
                   Operand_Registr( cmd.Op2, rAX+(GETNUMBIT(cd)>>1), 0 );
               break;

              case 0xD://movw rp,AX           (1101 0PP0)
                   cmd.itype = NEC_78K_0_movw;   
                   Operand_Registr( cmd.Op1, rAX+(GETNUMBIT(cd)>>1), 0 );
                   Operand_Registr( cmd.Op2, rAX, 0 );
                 break;
  
              case 0xE://xchw AX,rp           (1101 0PP0)
                   cmd.itype = NEC_78K_0_xchw;   
                   Operand_Registr( cmd.Op1, rAX, 0 );
                   Operand_Registr( cmd.Op2, rAX+(GETNUMBIT(cd)>>1), 0 );
                 break;


            case 0x4://inc r              (0100 0RRR)
                 cmd.itype = NEC_78K_0_inc;   
                 Operand_Registr( cmd.Op1, GETNUMBIT(cd), 0 );
               break;

            case 0x5://dec r              (0101 0RRR)
                 cmd.itype = NEC_78K_0_dec;   
                 Operand_Registr( cmd.Op1, GETNUMBIT(cd), 0 );
               break;

            case 0x8://incw rp              (1000 0PP0)
                 cmd.itype = NEC_78K_0_incw;   
                 Operand_Registr( cmd.Op1, rAX+(GETNUMBIT(cd)>>1), 0 );
               break;


            case 0x9://decw rp              (1001 0PP0)
                 cmd.itype = NEC_78K_0_decw;   
                 Operand_Registr( cmd.Op1, rAX+(GETNUMBIT(cd)>>1), 0 );
               break;


               //push rp              (1011 0PP1)
               //pop  rp              (1011 0PP0)
            case 0x2:
            case 0xB:
                 if( GETBIT(cd, 0)==0)  cmd.itype = NEC_78K_0_pop;
                 else   cmd.itype = NEC_78K_0_push;   
                 Operand_Registr( cmd.Op1, rAX+(GETNUMBIT(cd)>>1), 0 );
               break;

            case 0xA://mov r,#byte              (1010 0RRR)
                 cmd.itype = NEC_78K_0_mov;   
                 Operand_Registr( cmd.Op1, GETNUMBIT(cd), 0 );
                 Operand_Data_8bits( cmd.Op2, ua_next_byte() );
               break;

            case 0x7://mov r,A              (0111 0RRR)
                 cmd.itype = NEC_78K_0_mov;   
                 Operand_Registr( cmd.Op1, GETNUMBIT(cd), 0 );
                 Operand_Registr( cmd.Op2, rA, 0 ); 
               break;

            case 0x6://mov A,r              (0110 0RRR)
                 cmd.itype = NEC_78K_0_mov;   
                 Operand_Registr( cmd.Op1, rA, 0 ); 
                 Operand_Registr( cmd.Op2, GETNUMBIT(cd), 0 );
               break;

            case 0x3://xch A,r              (0011 0RRR)
                 cmd.itype = NEC_78K_0_xch;   
                 Operand_Registr( cmd.Op1, rA, 0 ); 
                 Operand_Registr( cmd.Op2, GETNUMBIT(cd), 0 );
               break;

            }
          }
          else
          {
            switch(cd)
            { 
               //set1 saddr.bit              (0BBB 1010)
               //set1 PSW.bit              (0BBB 1010)
            case 0xA:
               {
                 cmd.itype = NEC_78K_0_set1;
                 uchar bt =  ua_next_byte();
                 if(bt == 0x1E)                                     
                   Operand_Bit( cmd.Op1, TBO_PSW, GETNUMBIT(nib & 0x7 ));
                 else
                  {
                   Operand_Saddr( cmd.Op1, bt );
                   Operand_Bit( cmd.Op1, TBO_SADDR, GETNUMBIT(nib & 0x7 ));
                  }
                break;
                }


               //clr1 saddr.bit              (0BBB 1011)
               //clr1 PSW.bit                (0BBB 1011)
            case 0xB:
               {
                 cmd.itype = NEC_78K_0_clr1;
                 uchar bt =  ua_next_byte();
                 if(bt == 0x1E)                                     
                   Operand_Bit( cmd.Op1, TBO_PSW, GETNUMBIT(nib & 0x7 ));
                 else
                  {
                   Operand_Saddr( cmd.Op1, bt );
                   Operand_Bit( cmd.Op1, TBO_SADDR, GETNUMBIT(nib & 0x7 ));
                  }
                break;
                }

              //bt saddr.bit,$saddr16
              //bt PSW.bit,$saddr16
            case 0xC:
               {
                 if( GETBIT(code, 7)== 1)//bt xxxxxxxx
                 {
                   cmd.itype = NEC_78K_0_bt;
                   uchar bt = ua_next_byte();
                   if(bt == 0x1E)
                     Operand_Bit(cmd.Op1, TBO_PSW, GETNUMBIT( nib ) );
                   else
                   {
                     Operand_Saddr( cmd.Op1, bt );
                     Operand_Bit(cmd.Op1, TBO_SADDR, GETNUMBIT( nib ) );
                   }

                    Operand_Near(cmd.Op2, ua_next_byte(), 3);
                  }
                  else//call11
                  {
                     cmd.itype = NEC_78K_0_callf;

                     ulong Addr = ((long)( code & 0xF0 )<<8) | (ulong)ua_next_byte();
                     Operand_Call11(cmd.Op1, Addr);
                  }
               break;
               }

            }
          }

          
          break;  

        } //end default 
   }

   return( cmd.size );

}
